From 435a566751e9f8bab39f95207e03aea4e37b03bf Mon Sep 17 00:00:00 2001 From: Klemens Friedl Date: Sat, 29 Sep 2007 08:39:35 +0000 Subject: [PATCH] SmartPDF - lightweight pdf viewer app for rosapps * sumatrapdf - vendor import * everything compiles (libjpeg, poppler, fitz, sumatrapdf) * does NOT link (remove the comment tags in the parent directory.rbuild file (rosapps dir) to build it) svn path=/trunk/; revision=29295 --- rosapps/directory.rbuild | 13 +- rosapps/lib/directory.rbuild | 8 + rosapps/lib/libjpeg/LibJPEG.dsp | 328 + rosapps/lib/libjpeg/LibJPEG.vcproj | 315 + rosapps/lib/libjpeg/ansi2knr.c | 693 ++ rosapps/lib/libjpeg/cderror.h | 132 + rosapps/lib/libjpeg/cdjpeg.c | 181 + rosapps/lib/libjpeg/cdjpeg.h | 184 + rosapps/lib/libjpeg/change.log | 217 + rosapps/lib/libjpeg/cjpeg.c | 606 ++ rosapps/lib/libjpeg/ckconfig.c | 402 + rosapps/lib/libjpeg/djpeg.c | 616 ++ rosapps/lib/libjpeg/example.c | 433 + rosapps/lib/libjpeg/jcapimin.c | 280 + rosapps/lib/libjpeg/jcapistd.c | 161 + rosapps/lib/libjpeg/jccoefct.c | 449 + rosapps/lib/libjpeg/jccolor.c | 459 + rosapps/lib/libjpeg/jcdctmgr.c | 387 + rosapps/lib/libjpeg/jchuff.c | 909 ++ rosapps/lib/libjpeg/jchuff.h | 47 + rosapps/lib/libjpeg/jcinit.c | 72 + rosapps/lib/libjpeg/jcmainct.c | 293 + rosapps/lib/libjpeg/jcmarker.c | 664 ++ rosapps/lib/libjpeg/jcmaster.c | 590 ++ rosapps/lib/libjpeg/jcomapi.c | 106 + rosapps/lib/libjpeg/jconfig.h | 47 + rosapps/lib/libjpeg/jcparam.c | 610 ++ rosapps/lib/libjpeg/jcphuff.c | 833 ++ rosapps/lib/libjpeg/jcprepct.c | 354 + rosapps/lib/libjpeg/jcsample.c | 519 + rosapps/lib/libjpeg/jctrans.c | 388 + rosapps/lib/libjpeg/jdapimin.c | 499 + rosapps/lib/libjpeg/jdapistd.c | 275 + rosapps/lib/libjpeg/jdatadst.c | 151 + rosapps/lib/libjpeg/jdatasrc.c | 213 + rosapps/lib/libjpeg/jdcoefct.c | 736 ++ rosapps/lib/libjpeg/jdcolor.c | 396 + rosapps/lib/libjpeg/jdct.h | 176 + rosapps/lib/libjpeg/jddctmgr.c | 305 + rosapps/lib/libjpeg/jdhuff.c | 651 ++ rosapps/lib/libjpeg/jdhuff.h | 201 + rosapps/lib/libjpeg/jdinput.c | 381 + rosapps/lib/libjpeg/jdmainct.c | 512 + rosapps/lib/libjpeg/jdmarker.c | 1360 +++ rosapps/lib/libjpeg/jdmaster.c | 557 ++ rosapps/lib/libjpeg/jdmerge.c | 1024 ++ rosapps/lib/libjpeg/jdphuff.c | 668 ++ rosapps/lib/libjpeg/jdpostct.c | 290 + rosapps/lib/libjpeg/jdsample.c | 478 + rosapps/lib/libjpeg/jdtrans.c | 143 + rosapps/lib/libjpeg/jerror.c | 248 + rosapps/lib/libjpeg/jerror.h | 292 + rosapps/lib/libjpeg/jfdctflt.c | 168 + rosapps/lib/libjpeg/jfdctfst.c | 224 + rosapps/lib/libjpeg/jfdctint.c | 283 + rosapps/lib/libjpeg/jidctflt.c | 242 + rosapps/lib/libjpeg/jidctfst.c | 1650 ++++ rosapps/lib/libjpeg/jidctint.c | 963 ++ rosapps/lib/libjpeg/jidctred.c | 398 + rosapps/lib/libjpeg/jinclude.h | 91 + rosapps/lib/libjpeg/jmemansi.c | 167 + rosapps/lib/libjpeg/jmemdos.c | 638 ++ rosapps/lib/libjpeg/jmemdosa.asm | 379 + rosapps/lib/libjpeg/jmemmac.c | 289 + rosapps/lib/libjpeg/jmemmgr.c | 1118 +++ rosapps/lib/libjpeg/jmemname.c | 276 + rosapps/lib/libjpeg/jmemnobs.c | 109 + rosapps/lib/libjpeg/jmemsys.h | 198 + rosapps/lib/libjpeg/jmorecfg.h | 384 + rosapps/lib/libjpeg/jpegint.h | 392 + rosapps/lib/libjpeg/jpeglib.h | 1107 +++ rosapps/lib/libjpeg/jpegtran.c | 546 ++ rosapps/lib/libjpeg/jquant1.c | 856 ++ rosapps/lib/libjpeg/jquant2.c | 1310 +++ rosapps/lib/libjpeg/jutils.c | 179 + rosapps/lib/libjpeg/jversion.h | 14 + rosapps/lib/libjpeg/libjpeg.rbuild | 62 + rosapps/lib/libjpeg/rdbmp.c | 439 + rosapps/lib/libjpeg/rdcolmap.c | 253 + rosapps/lib/libjpeg/rdgif.c | 38 + rosapps/lib/libjpeg/rdjpgcom.c | 496 + rosapps/lib/libjpeg/rdppm.c | 458 + rosapps/lib/libjpeg/rdrle.c | 387 + rosapps/lib/libjpeg/rdswitch.c | 332 + rosapps/lib/libjpeg/rdtarga.c | 500 + rosapps/lib/libjpeg/transupp.c | 1529 +++ rosapps/lib/libjpeg/transupp.h | 205 + rosapps/lib/libjpeg/wrbmp.c | 442 + rosapps/lib/libjpeg/wrgif.c | 399 + rosapps/lib/libjpeg/wrjpgcom.c | 583 ++ rosapps/lib/libjpeg/wrppm.c | 268 + rosapps/lib/libjpeg/wrrle.c | 305 + rosapps/lib/libjpeg/wrtarga.c | 253 + rosapps/smartpdf/COPYING | 340 + rosapps/smartpdf/baseutils/WinUtil.cpp | 112 + rosapps/smartpdf/baseutils/WinUtil.hpp | 15 + rosapps/smartpdf/baseutils/base_util.c | 138 + rosapps/smartpdf/baseutils/base_util.h | 160 + .../smartpdf/baseutils/common_unit_tests.sln | 20 + .../baseutils/common_unit_tests.vcproj | 246 + rosapps/smartpdf/baseutils/dstring.c | 319 + rosapps/smartpdf/baseutils/dstring.h | 73 + rosapps/smartpdf/baseutils/file_util.c | 483 + rosapps/smartpdf/baseutils/file_util.h | 61 + rosapps/smartpdf/baseutils/geom_util.c | 225 + rosapps/smartpdf/baseutils/geom_util.h | 73 + rosapps/smartpdf/baseutils/log_util.c | 160 + rosapps/smartpdf/baseutils/log_util.h | 23 + rosapps/smartpdf/baseutils/makefile.msvc | 76 + rosapps/smartpdf/baseutils/ms_ui_helper.c | 634 ++ rosapps/smartpdf/baseutils/ms_ui_helper.h | 348 + rosapps/smartpdf/baseutils/ms_ui_shguim.h | 96 + rosapps/smartpdf/baseutils/netstr.c | 271 + rosapps/smartpdf/baseutils/netstr.h | 28 + rosapps/smartpdf/baseutils/netstr_ut.c | 26 + rosapps/smartpdf/baseutils/pdiff.cc | 387 + rosapps/smartpdf/baseutils/pdiff.h | 81 + rosapps/smartpdf/baseutils/prefs_util.c | 256 + rosapps/smartpdf/baseutils/prefs_util.h | 38 + rosapps/smartpdf/baseutils/str_strsafe.h | 22 + rosapps/smartpdf/baseutils/str_util.c | 970 ++ rosapps/smartpdf/baseutils/str_util.h | 117 + rosapps/smartpdf/baseutils/str_util_test.c | 44 + rosapps/smartpdf/baseutils/strlist_util.c | 70 + rosapps/smartpdf/baseutils/strlist_util.h | 28 + rosapps/smartpdf/baseutils/test_file_util.cpp | 30 + rosapps/smartpdf/baseutils/test_win.bat | 23 + rosapps/smartpdf/baseutils/todo.txt | 3 + rosapps/smartpdf/baseutils/tstr_util.h | 44 + rosapps/smartpdf/baseutils/unit_tests_all.c | 13 + rosapps/smartpdf/baseutils/win-build.bat | 5 + rosapps/smartpdf/baseutils/win-rebuild.bat | 9 + rosapps/smartpdf/baseutils/win_dib.cpp | 1263 +++ rosapps/smartpdf/baseutils/win_dib.h | 219 + rosapps/smartpdf/baseutils/win_image.cpp | 139 + rosapps/smartpdf/baseutils/win_image.h | 23 + rosapps/smartpdf/baseutils/win_util.c | 463 + rosapps/smartpdf/baseutils/win_util.h | 128 + rosapps/smartpdf/baseutils/wstr_util.c | 285 + rosapps/smartpdf/baseutils/wstr_util.h | 35 + rosapps/smartpdf/fitz.rbuild | 167 + rosapps/smartpdf/fitz/COPYING | 339 + rosapps/smartpdf/fitz/DESIGN | 199 + rosapps/smartpdf/fitz/Makefile.vc | 257 + rosapps/smartpdf/fitz/README | 85 + rosapps/smartpdf/fitz/TODO | 177 + rosapps/smartpdf/fitz/apps/common/pdfapp.c | 685 ++ .../macosx/FzView.app/Contents/Info.plist | 44 + .../FzView.app/Contents/MacOS/.gitignore | 0 .../apps/macosx/FzView.app/Contents/PkgInfo | 1 + .../Resources/English.lproj/InfoPlist.strings | 7 + .../English.lproj/main.nib/classes.nib | 4 + .../Resources/English.lproj/main.nib/info.nib | 24 + .../English.lproj/main.nib/objects.xib | 516 + .../FzView.app/Contents/Resources/macpdf.icns | Bin 0 -> 31574 bytes rosapps/smartpdf/fitz/apps/macosx/macpdf.c | 438 + rosapps/smartpdf/fitz/apps/mozilla/jri.h | 5 + rosapps/smartpdf/fitz/apps/mozilla/moz_main.c | 889 ++ .../smartpdf/fitz/apps/mozilla/moz_winres.rc | 21 + rosapps/smartpdf/fitz/apps/mozilla/npapi.h | 469 + rosapps/smartpdf/fitz/apps/mozilla/npunix.c | 406 + rosapps/smartpdf/fitz/apps/mozilla/npupp.h | 1160 +++ rosapps/smartpdf/fitz/apps/mozilla/npwin.c | 327 + rosapps/smartpdf/fitz/apps/pdftool.c | 1017 ++ rosapps/smartpdf/fitz/apps/samshow.c | 188 + rosapps/smartpdf/fitz/apps/unix/gs_l.xbm | 29 + rosapps/smartpdf/fitz/apps/unix/x11pdf.c | 511 + rosapps/smartpdf/fitz/apps/unix/ximage.c | 672 ++ rosapps/smartpdf/fitz/apps/windows/gsapp.ico | Bin 0 -> 25214 bytes rosapps/smartpdf/fitz/apps/windows/gsdoc.ico | Bin 0 -> 2238 bytes rosapps/smartpdf/fitz/apps/windows/winmain.c | 821 ++ rosapps/smartpdf/fitz/apps/windows/winres.rc | 62 + rosapps/smartpdf/fitz/base/base_cleanname.c | 52 + rosapps/smartpdf/fitz/base/base_cpudep.c | 221 + rosapps/smartpdf/fitz/base/base_error.c | 74 + rosapps/smartpdf/fitz/base/base_hash.c | 274 + rosapps/smartpdf/fitz/base/base_matrix.c | 151 + rosapps/smartpdf/fitz/base/base_memory.c | 91 + rosapps/smartpdf/fitz/base/base_rect.c | 75 + rosapps/smartpdf/fitz/base/base_rune.c | 168 + rosapps/smartpdf/fitz/base/util_getopt.c | 116 + rosapps/smartpdf/fitz/base/util_strlcat.c | 35 + rosapps/smartpdf/fitz/base/util_strlcpy.c | 32 + rosapps/smartpdf/fitz/base/util_strsep.c | 11 + rosapps/smartpdf/fitz/build-debug.bat | 1 + rosapps/smartpdf/fitz/build.bat | 1 + rosapps/smartpdf/fitz/clean.bat | 1 + rosapps/smartpdf/fitz/fonts/Dingbats.cff.c | 2461 +++++ .../smartpdf/fitz/fonts/NimbusMonL-Bold.cff.c | 2742 ++++++ .../fitz/fonts/NimbusMonL-BoldObli.cff.c | 2802 ++++++ .../smartpdf/fitz/fonts/NimbusMonL-Regu.cff.c | 2138 +++++ .../fitz/fonts/NimbusMonL-ReguObli.cff.c | 2371 +++++ .../fitz/fonts/NimbusRomNo9L-Medi.cff.c | 2030 ++++ .../fitz/fonts/NimbusRomNo9L-MediItal.cff.c | 2263 +++++ .../fitz/fonts/NimbusRomNo9L-Regu.cff.c | 2109 ++++ .../fitz/fonts/NimbusRomNo9L-ReguItal.cff.c | 2306 +++++ .../smartpdf/fitz/fonts/NimbusSanL-Bold.cff.c | 1460 +++ .../fitz/fonts/NimbusSanL-BoldItal.cff.c | 1667 ++++ .../smartpdf/fitz/fonts/NimbusSanL-Regu.cff.c | 1387 +++ .../fitz/fonts/NimbusSanL-ReguItal.cff.c | 1683 ++++ .../smartpdf/fitz/fonts/StandardSymL.cff.c | 1582 +++ .../fitz/fonts/URWChanceryL-MediItal.cff.c | 2873 ++++++ rosapps/smartpdf/fitz/include/fitz-base.h | 22 + rosapps/smartpdf/fitz/include/fitz-draw.h | 27 + rosapps/smartpdf/fitz/include/fitz-stream.h | 26 + rosapps/smartpdf/fitz/include/fitz-world.h | 28 + rosapps/smartpdf/fitz/include/fitz.h | 10 + .../smartpdf/fitz/include/fitz/base_cpudep.h | 26 + .../smartpdf/fitz/include/fitz/base_geom.h | 65 + .../smartpdf/fitz/include/fitz/base_hash.h | 20 + .../smartpdf/fitz/include/fitz/base_math.h | 29 + .../smartpdf/fitz/include/fitz/base_pixmap.h | 26 + .../smartpdf/fitz/include/fitz/base_runtime.h | 79 + .../smartpdf/fitz/include/fitz/base_sysdep.h | 109 + .../smartpdf/fitz/include/fitz/draw_misc.h | 83 + .../smartpdf/fitz/include/fitz/draw_path.h | 46 + .../smartpdf/fitz/include/fitz/stm_buffer.h | 41 + .../smartpdf/fitz/include/fitz/stm_crypt.h | 43 + .../smartpdf/fitz/include/fitz/stm_filter.h | 95 + .../smartpdf/fitz/include/fitz/stm_object.h | 132 + .../smartpdf/fitz/include/fitz/stm_stream.h | 103 + .../smartpdf/fitz/include/fitz/wld_color.h | 40 + rosapps/smartpdf/fitz/include/fitz/wld_font.h | 68 + .../smartpdf/fitz/include/fitz/wld_image.h | 16 + rosapps/smartpdf/fitz/include/fitz/wld_path.h | 83 + .../smartpdf/fitz/include/fitz/wld_shade.h | 29 + rosapps/smartpdf/fitz/include/fitz/wld_text.h | 44 + rosapps/smartpdf/fitz/include/fitz/wld_tree.h | 183 + rosapps/smartpdf/fitz/include/mupdf.h | 39 + rosapps/smartpdf/fitz/include/mupdf/annot.h | 69 + rosapps/smartpdf/fitz/include/mupdf/base14.h | 30 + rosapps/smartpdf/fitz/include/mupdf/content.h | 110 + rosapps/smartpdf/fitz/include/mupdf/page.h | 58 + rosapps/smartpdf/fitz/include/mupdf/rsrc.h | 242 + rosapps/smartpdf/fitz/include/mupdf/syntax.h | 74 + rosapps/smartpdf/fitz/include/mupdf/xref.h | 76 + rosapps/smartpdf/fitz/include/pdfapp.h | 75 + rosapps/smartpdf/fitz/include/samus.h | 25 + rosapps/smartpdf/fitz/include/samus/fixdoc.h | 13 + rosapps/smartpdf/fitz/include/samus/misc.h | 7 + rosapps/smartpdf/fitz/include/samus/names.h | 96 + rosapps/smartpdf/fitz/include/samus/pack.h | 28 + rosapps/smartpdf/fitz/include/samus/xml.h | 20 + rosapps/smartpdf/fitz/include/samus/zip.h | 12 + rosapps/smartpdf/fitz/include/win_os.h | 12 + rosapps/smartpdf/fitz/mupdf/glyphlist.txt | 4291 +++++++++ rosapps/smartpdf/fitz/mupdf/pdf_annot.c | 210 + rosapps/smartpdf/fitz/mupdf/pdf_build.c | 803 ++ rosapps/smartpdf/fitz/mupdf/pdf_cmap.c | 1166 +++ rosapps/smartpdf/fitz/mupdf/pdf_colorspace1.c | 755 ++ rosapps/smartpdf/fitz/mupdf/pdf_colorspace2.c | 201 + rosapps/smartpdf/fitz/mupdf/pdf_crypt.c | 451 + rosapps/smartpdf/fitz/mupdf/pdf_debug.c | 92 + rosapps/smartpdf/fitz/mupdf/pdf_doctor.c | 267 + rosapps/smartpdf/fitz/mupdf/pdf_font.c | 1039 ++ rosapps/smartpdf/fitz/mupdf/pdf_fontagl.c | 4647 +++++++++ rosapps/smartpdf/fitz/mupdf/pdf_fontenc.c | 375 + rosapps/smartpdf/fitz/mupdf/pdf_fontfile.c | 420 + rosapps/smartpdf/fitz/mupdf/pdf_fontfilefc.c | 295 + rosapps/smartpdf/fitz/mupdf/pdf_fontfilems.c | 806 ++ rosapps/smartpdf/fitz/mupdf/pdf_function.c | 1556 +++ rosapps/smartpdf/fitz/mupdf/pdf_image.c | 538 ++ rosapps/smartpdf/fitz/mupdf/pdf_interpret.c | 1207 +++ rosapps/smartpdf/fitz/mupdf/pdf_lex.c | 350 + rosapps/smartpdf/fitz/mupdf/pdf_nametree.c | 134 + rosapps/smartpdf/fitz/mupdf/pdf_open.c | 595 ++ rosapps/smartpdf/fitz/mupdf/pdf_outline.c | 142 + rosapps/smartpdf/fitz/mupdf/pdf_page.c | 290 + rosapps/smartpdf/fitz/mupdf/pdf_pagetree.c | 224 + rosapps/smartpdf/fitz/mupdf/pdf_parse.c | 423 + rosapps/smartpdf/fitz/mupdf/pdf_pattern.c | 142 + rosapps/smartpdf/fitz/mupdf/pdf_repair.c | 304 + rosapps/smartpdf/fitz/mupdf/pdf_resources.c | 385 + rosapps/smartpdf/fitz/mupdf/pdf_save.c | 326 + rosapps/smartpdf/fitz/mupdf/pdf_shade.c | 230 + rosapps/smartpdf/fitz/mupdf/pdf_shade1.c | 369 + rosapps/smartpdf/fitz/mupdf/pdf_shade4.c | 795 ++ rosapps/smartpdf/fitz/mupdf/pdf_store.c | 183 + rosapps/smartpdf/fitz/mupdf/pdf_stream.c | 492 + rosapps/smartpdf/fitz/mupdf/pdf_type3.c | 311 + rosapps/smartpdf/fitz/mupdf/pdf_unicode.c | 318 + rosapps/smartpdf/fitz/mupdf/pdf_xobject.c | 102 + rosapps/smartpdf/fitz/mupdf/pdf_xref.c | 455 + rosapps/smartpdf/fitz/raster/archppc.c | 67 + rosapps/smartpdf/fitz/raster/archsparc.c | 23 + rosapps/smartpdf/fitz/raster/archx86.c | 229 + rosapps/smartpdf/fitz/raster/glyphcache.c | 390 + rosapps/smartpdf/fitz/raster/imagedraw.c | 240 + rosapps/smartpdf/fitz/raster/imagescale.c | 370 + rosapps/smartpdf/fitz/raster/imageunpack.c | 251 + rosapps/smartpdf/fitz/raster/meshdraw.c | 404 + rosapps/smartpdf/fitz/raster/pathfill.c | 134 + rosapps/smartpdf/fitz/raster/pathscan.c | 486 + rosapps/smartpdf/fitz/raster/pathstroke.c | 727 ++ rosapps/smartpdf/fitz/raster/pixmap.c | 127 + rosapps/smartpdf/fitz/raster/porterduff.c | 359 + rosapps/smartpdf/fitz/raster/render.c | 885 ++ rosapps/smartpdf/fitz/samus/sa_fixdoc.c | 327 + rosapps/smartpdf/fitz/samus/sa_misc.c | 55 + rosapps/smartpdf/fitz/samus/sa_pack.c | 387 + rosapps/smartpdf/fitz/samus/sa_tiff.c | 653 ++ rosapps/smartpdf/fitz/samus/sa_xml.c | 344 + rosapps/smartpdf/fitz/samus/sa_zip.c | 313 + rosapps/smartpdf/fitz/stream/crypt_arc4.c | 96 + rosapps/smartpdf/fitz/stream/crypt_crc32.c | 86 + rosapps/smartpdf/fitz/stream/crypt_md5.c | 270 + rosapps/smartpdf/fitz/stream/filt_a85d.c | 129 + rosapps/smartpdf/fitz/stream/filt_a85e.c | 128 + rosapps/smartpdf/fitz/stream/filt_ahxd.c | 113 + rosapps/smartpdf/fitz/stream/filt_ahxe.c | 65 + rosapps/smartpdf/fitz/stream/filt_arc4.c | 47 + rosapps/smartpdf/fitz/stream/filt_dctc.h | 39 + rosapps/smartpdf/fitz/stream/filt_dctd.c | 220 + rosapps/smartpdf/fitz/stream/filt_dcte.c | 253 + rosapps/smartpdf/fitz/stream/filt_faxc.h | 125 + rosapps/smartpdf/fitz/stream/filt_faxd.c | 442 + rosapps/smartpdf/fitz/stream/filt_faxd.h | 61 + rosapps/smartpdf/fitz/stream/filt_faxdtab.c | 931 ++ rosapps/smartpdf/fitz/stream/filt_faxe.c | 399 + rosapps/smartpdf/fitz/stream/filt_faxe.h | 37 + rosapps/smartpdf/fitz/stream/filt_faxetab.c | 131 + rosapps/smartpdf/fitz/stream/filt_flate.c | 211 + rosapps/smartpdf/fitz/stream/filt_jbig2d.c | 116 + rosapps/smartpdf/fitz/stream/filt_jpxd.c | 144 + rosapps/smartpdf/fitz/stream/filt_lzwd.c | 254 + rosapps/smartpdf/fitz/stream/filt_lzwe.c | 262 + rosapps/smartpdf/fitz/stream/filt_null.c | 53 + rosapps/smartpdf/fitz/stream/filt_pipeline.c | 129 + rosapps/smartpdf/fitz/stream/filt_predict.c | 239 + rosapps/smartpdf/fitz/stream/filt_rld.c | 74 + rosapps/smartpdf/fitz/stream/filt_rle.c | 238 + rosapps/smartpdf/fitz/stream/obj_array.c | 185 + rosapps/smartpdf/fitz/stream/obj_dict.c | 356 + rosapps/smartpdf/fitz/stream/obj_parse.c | 402 + rosapps/smartpdf/fitz/stream/obj_print.c | 337 + rosapps/smartpdf/fitz/stream/obj_simple.c | 374 + rosapps/smartpdf/fitz/stream/stm_buffer.c | 94 + rosapps/smartpdf/fitz/stream/stm_filter.c | 52 + rosapps/smartpdf/fitz/stream/stm_misc.c | 194 + rosapps/smartpdf/fitz/stream/stm_open.c | 223 + rosapps/smartpdf/fitz/stream/stm_read.c | 263 + rosapps/smartpdf/fitz/stream/stm_write.c | 280 + rosapps/smartpdf/fitz/world/node_misc1.c | 191 + rosapps/smartpdf/fitz/world/node_misc2.c | 332 + rosapps/smartpdf/fitz/world/node_optimize.c | 314 + rosapps/smartpdf/fitz/world/node_path.c | 306 + rosapps/smartpdf/fitz/world/node_text.c | 142 + rosapps/smartpdf/fitz/world/node_tolisp.c | 192 + rosapps/smartpdf/fitz/world/node_toxml.c | 200 + rosapps/smartpdf/fitz/world/node_tree.c | 110 + rosapps/smartpdf/fitz/world/res_colorspace.c | 92 + rosapps/smartpdf/fitz/world/res_font.c | 270 + rosapps/smartpdf/fitz/world/res_image.c | 23 + rosapps/smartpdf/fitz/world/res_shade.c | 29 + rosapps/smartpdf/fitzheadlib.vcproj | 810 ++ rosapps/smartpdf/fitzlib.cbp | 465 + rosapps/smartpdf/fitzlib.vcproj | 818 ++ rosapps/smartpdf/pdfbench.vcproj | 278 + rosapps/smartpdf/pdfbenchbase.vcproj | 276 + rosapps/smartpdf/poppler.rbuild | 117 + rosapps/smartpdf/poppler/AUTHORS | 3 + rosapps/smartpdf/poppler/COPYING | 340 + rosapps/smartpdf/poppler/ChangeLog | 3339 +++++++ rosapps/smartpdf/poppler/INSTALL | 236 + rosapps/smartpdf/poppler/NEWS | 110 + rosapps/smartpdf/poppler/README | 37 + rosapps/smartpdf/poppler/README-XPDF | 376 + rosapps/smartpdf/poppler/TODO | 51 + rosapps/smartpdf/poppler/fofi/FoFiBase.cc | 156 + rosapps/smartpdf/poppler/fofi/FoFiBase.h | 55 + .../smartpdf/poppler/fofi/FoFiEncodings.cc | 994 ++ rosapps/smartpdf/poppler/fofi/FoFiEncodings.h | 34 + rosapps/smartpdf/poppler/fofi/FoFiTrueType.cc | 1781 ++++ rosapps/smartpdf/poppler/fofi/FoFiTrueType.h | 139 + rosapps/smartpdf/poppler/fofi/FoFiType1.cc | 207 + rosapps/smartpdf/poppler/fofi/FoFiType1.h | 57 + rosapps/smartpdf/poppler/fofi/FoFiType1C.cc | 2481 +++++ rosapps/smartpdf/poppler/fofi/FoFiType1C.h | 230 + rosapps/smartpdf/poppler/fofi/Makefile.am | 16 + rosapps/smartpdf/poppler/goo/FastAlloc.cc | 321 + rosapps/smartpdf/poppler/goo/FastAlloc.h | 28 + .../poppler/goo/FastFixedAllocator.cc | 148 + .../smartpdf/poppler/goo/FastFixedAllocator.h | 162 + rosapps/smartpdf/poppler/goo/FixedPoint.cc | 95 + rosapps/smartpdf/poppler/goo/FixedPoint.h | 150 + rosapps/smartpdf/poppler/goo/GooHash.cc | 380 + rosapps/smartpdf/poppler/goo/GooHash.h | 76 + rosapps/smartpdf/poppler/goo/GooList.cc | 97 + rosapps/smartpdf/poppler/goo/GooList.h | 94 + rosapps/smartpdf/poppler/goo/GooMutex.h | 70 + rosapps/smartpdf/poppler/goo/GooString.cc | 327 + rosapps/smartpdf/poppler/goo/GooString.h | 230 + rosapps/smartpdf/poppler/goo/GooTimer.cc | 66 + rosapps/smartpdf/poppler/goo/GooTimer.h | 44 + rosapps/smartpdf/poppler/goo/GooVector.h | 101 + rosapps/smartpdf/poppler/goo/Makefile.am | 29 + rosapps/smartpdf/poppler/goo/gfile.cc | 709 ++ rosapps/smartpdf/poppler/goo/gfile.h | 142 + rosapps/smartpdf/poppler/goo/gmem.c | 275 + rosapps/smartpdf/poppler/goo/gmem.h | 62 + rosapps/smartpdf/poppler/goo/gmempp.cc | 32 + rosapps/smartpdf/poppler/goo/gtypes.h | 29 + rosapps/smartpdf/poppler/poppler/Annot.cc | 325 + rosapps/smartpdf/poppler/poppler/Annot.h | 72 + rosapps/smartpdf/poppler/poppler/Array.cc | 88 + rosapps/smartpdf/poppler/poppler/Array.h | 57 + .../poppler/poppler/ArthurOutputDev.cc | 743 ++ .../poppler/poppler/ArthurOutputDev.h | 144 + rosapps/smartpdf/poppler/poppler/BaseFile.h | 82 + .../smartpdf/poppler/poppler/BuiltinFont.cc | 65 + .../smartpdf/poppler/poppler/BuiltinFont.h | 55 + .../poppler/poppler/BuiltinFontTables.cc | 4284 +++++++++ .../poppler/poppler/BuiltinFontTables.h | 23 + rosapps/smartpdf/poppler/poppler/CMap.cc | 408 + rosapps/smartpdf/poppler/poppler/CMap.h | 101 + .../poppler/poppler/CairoFontEngine.cc | 364 + .../poppler/poppler/CairoFontEngine.h | 61 + .../poppler/poppler/CairoOutputDev.cc | 873 ++ .../smartpdf/poppler/poppler/CairoOutputDev.h | 171 + rosapps/smartpdf/poppler/poppler/Catalog.cc | 617 ++ rosapps/smartpdf/poppler/poppler/Catalog.h | 200 + .../poppler/poppler/CharCodeToUnicode.cc | 563 ++ .../poppler/poppler/CharCodeToUnicode.h | 116 + rosapps/smartpdf/poppler/poppler/CharTypes.h | 24 + .../poppler/poppler/CompactFontTables.h | 464 + rosapps/smartpdf/poppler/poppler/DCTStream.cc | 170 + rosapps/smartpdf/poppler/poppler/DCTStream.h | 73 + rosapps/smartpdf/poppler/poppler/Decrypt.cc | 411 + rosapps/smartpdf/poppler/poppler/Decrypt.h | 61 + rosapps/smartpdf/poppler/poppler/Dict.cc | 203 + rosapps/smartpdf/poppler/poppler/Dict.h | 89 + rosapps/smartpdf/poppler/poppler/Error.cc | 49 + rosapps/smartpdf/poppler/poppler/Error.h | 23 + rosapps/smartpdf/poppler/poppler/ErrorCodes.h | 36 + .../smartpdf/poppler/poppler/FlateStream.cc | 116 + .../smartpdf/poppler/poppler/FlateStream.h | 73 + .../poppler/poppler/FontEncodingTables.cc | 1824 ++++ .../poppler/poppler/FontEncodingTables.h | 20 + rosapps/smartpdf/poppler/poppler/FontInfo.cc | 212 + rosapps/smartpdf/poppler/poppler/FontInfo.h | 65 + rosapps/smartpdf/poppler/poppler/Function.cc | 1539 +++ rosapps/smartpdf/poppler/poppler/Function.h | 223 + rosapps/smartpdf/poppler/poppler/Gfx.cc | 3651 +++++++ rosapps/smartpdf/poppler/poppler/Gfx.h | 293 + rosapps/smartpdf/poppler/poppler/GfxFont.cc | 1649 ++++ rosapps/smartpdf/poppler/poppler/GfxFont.h | 355 + rosapps/smartpdf/poppler/poppler/GfxState.cc | 4187 ++++++++ rosapps/smartpdf/poppler/poppler/GfxState.h | 1228 +++ .../smartpdf/poppler/poppler/GlobalParams.cc | 2051 ++++ .../smartpdf/poppler/poppler/GlobalParams.h | 355 + .../poppler/poppler/GlobalParamsWin.cc | 287 + .../poppler/poppler/JArithmeticDecoder.cc | 322 + .../poppler/poppler/JArithmeticDecoder.h | 107 + .../smartpdf/poppler/poppler/JBIG2Stream.cc | 3468 +++++++ .../smartpdf/poppler/poppler/JBIG2Stream.h | 141 + rosapps/smartpdf/poppler/poppler/JPXStream.cc | 2967 ++++++ rosapps/smartpdf/poppler/poppler/JPXStream.h | 347 + rosapps/smartpdf/poppler/poppler/Lexer.cc | 566 ++ rosapps/smartpdf/poppler/poppler/Lexer.h | 130 + rosapps/smartpdf/poppler/poppler/Link.cc | 963 ++ rosapps/smartpdf/poppler/poppler/Link.h | 440 + rosapps/smartpdf/poppler/poppler/Makefile.am | 215 + .../poppler/poppler/NameToCharCode.cc | 116 + .../smartpdf/poppler/poppler/NameToCharCode.h | 40 + .../poppler/poppler/NameToUnicodeTable.h | 1097 +++ rosapps/smartpdf/poppler/poppler/Object.cc | 236 + rosapps/smartpdf/poppler/poppler/Object.h | 352 + rosapps/smartpdf/poppler/poppler/Outline.cc | 158 + rosapps/smartpdf/poppler/poppler/Outline.h | 75 + rosapps/smartpdf/poppler/poppler/OutputDev.cc | 162 + rosapps/smartpdf/poppler/poppler/OutputDev.h | 223 + rosapps/smartpdf/poppler/poppler/PDFDoc.cc | 486 + rosapps/smartpdf/poppler/poppler/PDFDoc.h | 196 + .../poppler/poppler/PDFDocEncoding.cc | 44 + .../smartpdf/poppler/poppler/PDFDocEncoding.h | 16 + .../smartpdf/poppler/poppler/PSOutputDev.cc | 4958 ++++++++++ .../smartpdf/poppler/poppler/PSOutputDev.h | 356 + .../smartpdf/poppler/poppler/PSTokenizer.cc | 144 + .../smartpdf/poppler/poppler/PSTokenizer.h | 40 + rosapps/smartpdf/poppler/poppler/Page.cc | 566 ++ rosapps/smartpdf/poppler/poppler/Page.h | 210 + .../smartpdf/poppler/poppler/PageLabelInfo.cc | 376 + .../smartpdf/poppler/poppler/PageLabelInfo.h | 39 + .../poppler/poppler/PageTransition.cc | 189 + rosapps/smartpdf/poppler/poppler/Parser.cc | 216 + rosapps/smartpdf/poppler/poppler/Parser.h | 52 + .../smartpdf/poppler/poppler/ProfileData.cc | 44 + .../smartpdf/poppler/poppler/ProfileData.h | 41 + .../poppler/poppler/SecurityHandler.cc | 360 + .../poppler/poppler/SecurityHandler.h | 174 + rosapps/smartpdf/poppler/poppler/Sound.cc | 140 + rosapps/smartpdf/poppler/poppler/Sound.h | 74 + .../poppler/poppler/SplashOutputDev.cc | 2511 +++++ .../poppler/poppler/SplashOutputDev.h | 217 + .../smartpdf/poppler/poppler/Stream-CCITT.h | 459 + rosapps/smartpdf/poppler/poppler/Stream.cc | 4731 +++++++++ rosapps/smartpdf/poppler/poppler/Stream.h | 883 ++ .../smartpdf/poppler/poppler/TextOutputDev.cc | 4247 ++++++++ .../smartpdf/poppler/poppler/TextOutputDev.h | 639 ++ .../smartpdf/poppler/poppler/UGooString.cc | 199 + rosapps/smartpdf/poppler/poppler/UGooString.h | 78 + rosapps/smartpdf/poppler/poppler/UTF8.h | 56 + .../poppler/poppler/UnicodeCClassTables.h | 1827 ++++ .../poppler/poppler/UnicodeCompTables.h | 665 ++ .../poppler/poppler/UnicodeDecompTables.h | 8526 +++++++++++++++++ .../smartpdf/poppler/poppler/UnicodeMap.cc | 293 + rosapps/smartpdf/poppler/poppler/UnicodeMap.h | 122 + .../poppler/poppler/UnicodeMapTables.h | 361 + .../poppler/poppler/UnicodeTypeTable.cc | 1184 +++ .../poppler/poppler/UnicodeTypeTable.h | 23 + rosapps/smartpdf/poppler/poppler/XRef.cc | 969 ++ rosapps/smartpdf/poppler/poppler/XRef.h | 138 + .../smartpdf/poppler/poppler/XpdfPluginAPI.cc | 262 + .../smartpdf/poppler/poppler/XpdfPluginAPI.h | 341 + .../poppler/poppler/poppler-config.h.in | 150 + rosapps/smartpdf/poppler/splash/Makefile.am | 57 + rosapps/smartpdf/poppler/splash/Splash.cc | 3365 +++++++ rosapps/smartpdf/poppler/splash/Splash.h | 202 + .../smartpdf/poppler/splash/SplashBitmap.cc | 268 + .../smartpdf/poppler/splash/SplashBitmap.h | 53 + rosapps/smartpdf/poppler/splash/SplashClip.cc | 270 + rosapps/smartpdf/poppler/splash/SplashClip.h | 95 + .../poppler/splash/SplashErrorCodes.h | 32 + .../smartpdf/poppler/splash/SplashFTFont.cc | 353 + .../smartpdf/poppler/splash/SplashFTFont.h | 53 + .../poppler/splash/SplashFTFontEngine.cc | 156 + .../poppler/splash/SplashFTFontEngine.h | 57 + .../poppler/splash/SplashFTFontFile.cc | 122 + .../poppler/splash/SplashFTFontFile.h | 68 + rosapps/smartpdf/poppler/splash/SplashFont.cc | 172 + rosapps/smartpdf/poppler/splash/SplashFont.h | 95 + .../poppler/splash/SplashFontEngine.cc | 247 + .../poppler/splash/SplashFontEngine.h | 81 + .../smartpdf/poppler/splash/SplashFontFile.cc | 109 + .../smartpdf/poppler/splash/SplashFontFile.h | 76 + .../poppler/splash/SplashFontFileID.cc | 23 + .../poppler/splash/SplashFontFileID.h | 28 + .../poppler/splash/SplashGlyphBitmap.h | 24 + rosapps/smartpdf/poppler/splash/SplashMath.h | 77 + rosapps/smartpdf/poppler/splash/SplashPath.cc | 178 + rosapps/smartpdf/poppler/splash/SplashPath.h | 112 + .../smartpdf/poppler/splash/SplashPattern.cc | 68 + .../smartpdf/poppler/splash/SplashPattern.h | 88 + .../smartpdf/poppler/splash/SplashScreen.cc | 141 + .../smartpdf/poppler/splash/SplashScreen.h | 48 + .../smartpdf/poppler/splash/SplashState.cc | 110 + rosapps/smartpdf/poppler/splash/SplashState.h | 89 + .../smartpdf/poppler/splash/SplashT1Font.cc | 264 + .../smartpdf/poppler/splash/SplashT1Font.h | 51 + .../poppler/splash/SplashT1FontEngine.cc | 123 + .../poppler/splash/SplashT1FontEngine.h | 51 + .../poppler/splash/SplashT1FontFile.cc | 116 + .../poppler/splash/SplashT1FontFile.h | 55 + rosapps/smartpdf/poppler/splash/SplashTypes.h | 140 + .../smartpdf/poppler/splash/SplashXPath.cc | 414 + rosapps/smartpdf/poppler/splash/SplashXPath.h | 90 + .../poppler/splash/SplashXPathScanner.cc | 285 + .../poppler/splash/SplashXPathScanner.h | 72 + rosapps/smartpdf/poppler/test/Makefile.am | 69 + .../smartpdf/poppler/test/gtk-cairo-test.cc | 202 + .../smartpdf/poppler/test/gtk-splash-test.cc | 309 + .../smartpdf/poppler/test/pdf-inspector.cc | 358 + .../smartpdf/poppler/test/pdf-inspector.glade | 434 + rosapps/smartpdf/poppler/test/pdf-operators.c | 81 + rosapps/smartpdf/poppler/test/pdfbench.cc | 1244 +++ rosapps/smartpdf/poppler/utils/HtmlFonts.cc | 326 + rosapps/smartpdf/poppler/utils/HtmlFonts.h | 85 + rosapps/smartpdf/poppler/utils/HtmlLinks.cc | 101 + rosapps/smartpdf/poppler/utils/HtmlLinks.h | 49 + .../smartpdf/poppler/utils/HtmlOutputDev.cc | 1572 +++ .../smartpdf/poppler/utils/HtmlOutputDev.h | 302 + .../smartpdf/poppler/utils/ImageOutputDev.cc | 197 + .../smartpdf/poppler/utils/ImageOutputDev.h | 76 + rosapps/smartpdf/poppler/utils/Makefile.am | 80 + rosapps/smartpdf/poppler/utils/parseargs.c | 190 + rosapps/smartpdf/poppler/utils/parseargs.h | 71 + rosapps/smartpdf/poppler/utils/pdf2xml.dtd | 28 + rosapps/smartpdf/poppler/utils/pdffonts.1 | 128 + rosapps/smartpdf/poppler/utils/pdffonts.cc | 304 + rosapps/smartpdf/poppler/utils/pdfimages.1 | 96 + rosapps/smartpdf/poppler/utils/pdfimages.cc | 159 + rosapps/smartpdf/poppler/utils/pdfinfo.1 | 157 + rosapps/smartpdf/poppler/utils/pdfinfo.cc | 386 + rosapps/smartpdf/poppler/utils/pdftohtml.1 | 85 + rosapps/smartpdf/poppler/utils/pdftohtml.cc | 428 + rosapps/smartpdf/poppler/utils/pdftoppm.1 | 113 + rosapps/smartpdf/poppler/utils/pdftoppm.cc | 190 + rosapps/smartpdf/poppler/utils/pdftops.1 | 224 + rosapps/smartpdf/poppler/utils/pdftops.cc | 339 + rosapps/smartpdf/poppler/utils/pdftotext.1 | 135 + rosapps/smartpdf/poppler/utils/pdftotext.cc | 347 + rosapps/smartpdf/popplerlib.cbp | 414 + rosapps/smartpdf/popplerlib.vcproj | 855 ++ rosapps/smartpdf/smartpdf.def | 2 + rosapps/smartpdf/smartpdf.rbuild | 134 + rosapps/smartpdf/src/AppPrefs.cc | 359 + rosapps/smartpdf/src/AppPrefs.h | 13 + rosapps/smartpdf/src/DisplayModel.cc | 1316 +++ rosapps/smartpdf/src/DisplayModel.h | 372 + rosapps/smartpdf/src/DisplayModelFitz.cc | 170 + rosapps/smartpdf/src/DisplayModelFitz.h | 30 + rosapps/smartpdf/src/DisplayModelSplash.cc | 869 ++ rosapps/smartpdf/src/DisplayModelSplash.h | 115 + rosapps/smartpdf/src/DisplayState.cc | 114 + rosapps/smartpdf/src/DisplayState.h | 77 + rosapps/smartpdf/src/FileHistory.cc | 210 + rosapps/smartpdf/src/FileHistory.h | 33 + rosapps/smartpdf/src/Kopie von SumatraPDF.cpp | 5103 ++++++++++ rosapps/smartpdf/src/PdfEngine.cc | 714 ++ rosapps/smartpdf/src/PdfEngine.h | 191 + rosapps/smartpdf/src/PdftestWinPreview.cc | 234 + rosapps/smartpdf/src/Resource.h | 117 + rosapps/smartpdf/src/SumatraDialogs.cc | 227 + rosapps/smartpdf/src/SumatraDialogs.h | 35 + rosapps/smartpdf/src/SumatraPDF.aps | Bin 0 -> 49724 bytes rosapps/smartpdf/src/SumatraPDF.cpp | 5116 ++++++++++ rosapps/smartpdf/src/SumatraPDF.h | 165 + rosapps/smartpdf/src/SumatraPDF.ico | Bin 0 -> 9158 bytes rosapps/smartpdf/src/SumatraPDF.rc | 187 + rosapps/smartpdf/src/build-release.bat | 52 + rosapps/smartpdf/src/config.h | 77 + rosapps/smartpdf/src/dragcursor.cur | Bin 0 -> 326 bytes rosapps/smartpdf/src/icons-silk/Thumbs.db | Bin 0 -> 15872 bytes rosapps/smartpdf/src/icons-silk/folder.bmp | Bin 0 -> 822 bytes rosapps/smartpdf/src/icons-silk/folder.png | Bin 0 -> 537 bytes rosapps/smartpdf/src/icons-silk/next.bmp | Bin 0 -> 822 bytes rosapps/smartpdf/src/icons-silk/next.png | Bin 0 -> 395 bytes rosapps/smartpdf/src/icons-silk/previous.bmp | Bin 0 -> 822 bytes rosapps/smartpdf/src/icons-silk/previous.png | Bin 0 -> 389 bytes rosapps/smartpdf/src/icons-silk/printer.png | Bin 0 -> 731 bytes .../src/icons-silk/rotate_anticlock.png | Bin 0 -> 608 bytes .../smartpdf/src/icons-silk/rotate_cloc.png | Bin 0 -> 602 bytes rosapps/smartpdf/src/icons-silk/zoom_in.bmp | Bin 0 -> 822 bytes rosapps/smartpdf/src/icons-silk/zoom_in.png | Bin 0 -> 725 bytes rosapps/smartpdf/src/icons-silk/zoom_out.bmp | Bin 0 -> 822 bytes rosapps/smartpdf/src/icons-silk/zoom_out.png | Bin 0 -> 708 bytes rosapps/smartpdf/src/pdfbench.cc | 1259 +++ rosapps/smartpdf/src/poppler-config.h | 150 + rosapps/smartpdf/src/strings.txt | 210 + rosapps/smartpdf/src/todo.txt | 21 + rosapps/smartpdf/src/toolbar-disabled.bmp | Bin 0 -> 20022 bytes rosapps/smartpdf/src/toolbar.bmp | Bin 0 -> 7734 bytes rosapps/smartpdf/src/translations.cpp | 235 + rosapps/smartpdf/src/translations.h | 15 + rosapps/smartpdf/src/translations_txt.c | 257 + rosapps/smartpdf/src/translations_txt.h | 18 + rosapps/smartpdf/sumatrapdf.cbp | 187 + rosapps/smartpdf/sumatrapdf.sln | 36 + rosapps/smartpdf/sumatrapdf.vcproj | 416 + rosapps/smartpdf/sumatrapdfdll.sln | 36 + rosapps/smartpdf/sumatrapdfdll.vcproj | 408 + 651 files changed, 270205 insertions(+), 3 deletions(-) create mode 100644 rosapps/lib/libjpeg/LibJPEG.dsp create mode 100644 rosapps/lib/libjpeg/LibJPEG.vcproj create mode 100644 rosapps/lib/libjpeg/ansi2knr.c create mode 100644 rosapps/lib/libjpeg/cderror.h create mode 100644 rosapps/lib/libjpeg/cdjpeg.c create mode 100644 rosapps/lib/libjpeg/cdjpeg.h create mode 100644 rosapps/lib/libjpeg/change.log create mode 100644 rosapps/lib/libjpeg/cjpeg.c create mode 100644 rosapps/lib/libjpeg/ckconfig.c create mode 100644 rosapps/lib/libjpeg/djpeg.c create mode 100644 rosapps/lib/libjpeg/example.c create mode 100644 rosapps/lib/libjpeg/jcapimin.c create mode 100644 rosapps/lib/libjpeg/jcapistd.c create mode 100644 rosapps/lib/libjpeg/jccoefct.c create mode 100644 rosapps/lib/libjpeg/jccolor.c create mode 100644 rosapps/lib/libjpeg/jcdctmgr.c create mode 100644 rosapps/lib/libjpeg/jchuff.c create mode 100644 rosapps/lib/libjpeg/jchuff.h create mode 100644 rosapps/lib/libjpeg/jcinit.c create mode 100644 rosapps/lib/libjpeg/jcmainct.c create mode 100644 rosapps/lib/libjpeg/jcmarker.c create mode 100644 rosapps/lib/libjpeg/jcmaster.c create mode 100644 rosapps/lib/libjpeg/jcomapi.c create mode 100644 rosapps/lib/libjpeg/jconfig.h create mode 100644 rosapps/lib/libjpeg/jcparam.c create mode 100644 rosapps/lib/libjpeg/jcphuff.c create mode 100644 rosapps/lib/libjpeg/jcprepct.c create mode 100644 rosapps/lib/libjpeg/jcsample.c create mode 100644 rosapps/lib/libjpeg/jctrans.c create mode 100644 rosapps/lib/libjpeg/jdapimin.c create mode 100644 rosapps/lib/libjpeg/jdapistd.c create mode 100644 rosapps/lib/libjpeg/jdatadst.c create mode 100644 rosapps/lib/libjpeg/jdatasrc.c create mode 100644 rosapps/lib/libjpeg/jdcoefct.c create mode 100644 rosapps/lib/libjpeg/jdcolor.c create mode 100644 rosapps/lib/libjpeg/jdct.h create mode 100644 rosapps/lib/libjpeg/jddctmgr.c create mode 100644 rosapps/lib/libjpeg/jdhuff.c create mode 100644 rosapps/lib/libjpeg/jdhuff.h create mode 100644 rosapps/lib/libjpeg/jdinput.c create mode 100644 rosapps/lib/libjpeg/jdmainct.c create mode 100644 rosapps/lib/libjpeg/jdmarker.c create mode 100644 rosapps/lib/libjpeg/jdmaster.c create mode 100644 rosapps/lib/libjpeg/jdmerge.c create mode 100644 rosapps/lib/libjpeg/jdphuff.c create mode 100644 rosapps/lib/libjpeg/jdpostct.c create mode 100644 rosapps/lib/libjpeg/jdsample.c create mode 100644 rosapps/lib/libjpeg/jdtrans.c create mode 100644 rosapps/lib/libjpeg/jerror.c create mode 100644 rosapps/lib/libjpeg/jerror.h create mode 100644 rosapps/lib/libjpeg/jfdctflt.c create mode 100644 rosapps/lib/libjpeg/jfdctfst.c create mode 100644 rosapps/lib/libjpeg/jfdctint.c create mode 100644 rosapps/lib/libjpeg/jidctflt.c create mode 100644 rosapps/lib/libjpeg/jidctfst.c create mode 100644 rosapps/lib/libjpeg/jidctint.c create mode 100644 rosapps/lib/libjpeg/jidctred.c create mode 100644 rosapps/lib/libjpeg/jinclude.h create mode 100644 rosapps/lib/libjpeg/jmemansi.c create mode 100644 rosapps/lib/libjpeg/jmemdos.c create mode 100644 rosapps/lib/libjpeg/jmemdosa.asm create mode 100644 rosapps/lib/libjpeg/jmemmac.c create mode 100644 rosapps/lib/libjpeg/jmemmgr.c create mode 100644 rosapps/lib/libjpeg/jmemname.c create mode 100644 rosapps/lib/libjpeg/jmemnobs.c create mode 100644 rosapps/lib/libjpeg/jmemsys.h create mode 100644 rosapps/lib/libjpeg/jmorecfg.h create mode 100644 rosapps/lib/libjpeg/jpegint.h create mode 100644 rosapps/lib/libjpeg/jpeglib.h create mode 100644 rosapps/lib/libjpeg/jpegtran.c create mode 100644 rosapps/lib/libjpeg/jquant1.c create mode 100644 rosapps/lib/libjpeg/jquant2.c create mode 100644 rosapps/lib/libjpeg/jutils.c create mode 100644 rosapps/lib/libjpeg/jversion.h create mode 100644 rosapps/lib/libjpeg/libjpeg.rbuild create mode 100644 rosapps/lib/libjpeg/rdbmp.c create mode 100644 rosapps/lib/libjpeg/rdcolmap.c create mode 100644 rosapps/lib/libjpeg/rdgif.c create mode 100644 rosapps/lib/libjpeg/rdjpgcom.c create mode 100644 rosapps/lib/libjpeg/rdppm.c create mode 100644 rosapps/lib/libjpeg/rdrle.c create mode 100644 rosapps/lib/libjpeg/rdswitch.c create mode 100644 rosapps/lib/libjpeg/rdtarga.c create mode 100644 rosapps/lib/libjpeg/transupp.c create mode 100644 rosapps/lib/libjpeg/transupp.h create mode 100644 rosapps/lib/libjpeg/wrbmp.c create mode 100644 rosapps/lib/libjpeg/wrgif.c create mode 100644 rosapps/lib/libjpeg/wrjpgcom.c create mode 100644 rosapps/lib/libjpeg/wrppm.c create mode 100644 rosapps/lib/libjpeg/wrrle.c create mode 100644 rosapps/lib/libjpeg/wrtarga.c create mode 100644 rosapps/smartpdf/COPYING create mode 100644 rosapps/smartpdf/baseutils/WinUtil.cpp create mode 100644 rosapps/smartpdf/baseutils/WinUtil.hpp create mode 100644 rosapps/smartpdf/baseutils/base_util.c create mode 100644 rosapps/smartpdf/baseutils/base_util.h create mode 100644 rosapps/smartpdf/baseutils/common_unit_tests.sln create mode 100644 rosapps/smartpdf/baseutils/common_unit_tests.vcproj create mode 100644 rosapps/smartpdf/baseutils/dstring.c create mode 100644 rosapps/smartpdf/baseutils/dstring.h create mode 100644 rosapps/smartpdf/baseutils/file_util.c create mode 100644 rosapps/smartpdf/baseutils/file_util.h create mode 100644 rosapps/smartpdf/baseutils/geom_util.c create mode 100644 rosapps/smartpdf/baseutils/geom_util.h create mode 100644 rosapps/smartpdf/baseutils/log_util.c create mode 100644 rosapps/smartpdf/baseutils/log_util.h create mode 100644 rosapps/smartpdf/baseutils/makefile.msvc create mode 100644 rosapps/smartpdf/baseutils/ms_ui_helper.c create mode 100644 rosapps/smartpdf/baseutils/ms_ui_helper.h create mode 100644 rosapps/smartpdf/baseutils/ms_ui_shguim.h create mode 100644 rosapps/smartpdf/baseutils/netstr.c create mode 100644 rosapps/smartpdf/baseutils/netstr.h create mode 100644 rosapps/smartpdf/baseutils/netstr_ut.c create mode 100644 rosapps/smartpdf/baseutils/pdiff.cc create mode 100644 rosapps/smartpdf/baseutils/pdiff.h create mode 100644 rosapps/smartpdf/baseutils/prefs_util.c create mode 100644 rosapps/smartpdf/baseutils/prefs_util.h create mode 100644 rosapps/smartpdf/baseutils/str_strsafe.h create mode 100644 rosapps/smartpdf/baseutils/str_util.c create mode 100644 rosapps/smartpdf/baseutils/str_util.h create mode 100644 rosapps/smartpdf/baseutils/str_util_test.c create mode 100644 rosapps/smartpdf/baseutils/strlist_util.c create mode 100644 rosapps/smartpdf/baseutils/strlist_util.h create mode 100644 rosapps/smartpdf/baseutils/test_file_util.cpp create mode 100644 rosapps/smartpdf/baseutils/test_win.bat create mode 100644 rosapps/smartpdf/baseutils/todo.txt create mode 100644 rosapps/smartpdf/baseutils/tstr_util.h create mode 100644 rosapps/smartpdf/baseutils/unit_tests_all.c create mode 100644 rosapps/smartpdf/baseutils/win-build.bat create mode 100644 rosapps/smartpdf/baseutils/win-rebuild.bat create mode 100644 rosapps/smartpdf/baseutils/win_dib.cpp create mode 100644 rosapps/smartpdf/baseutils/win_dib.h create mode 100644 rosapps/smartpdf/baseutils/win_image.cpp create mode 100644 rosapps/smartpdf/baseutils/win_image.h create mode 100644 rosapps/smartpdf/baseutils/win_util.c create mode 100644 rosapps/smartpdf/baseutils/win_util.h create mode 100644 rosapps/smartpdf/baseutils/wstr_util.c create mode 100644 rosapps/smartpdf/baseutils/wstr_util.h create mode 100644 rosapps/smartpdf/fitz.rbuild create mode 100644 rosapps/smartpdf/fitz/COPYING create mode 100644 rosapps/smartpdf/fitz/DESIGN create mode 100644 rosapps/smartpdf/fitz/Makefile.vc create mode 100644 rosapps/smartpdf/fitz/README create mode 100644 rosapps/smartpdf/fitz/TODO create mode 100644 rosapps/smartpdf/fitz/apps/common/pdfapp.c create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Info.plist create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/MacOS/.gitignore create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/PkgInfo create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/InfoPlist.strings create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/classes.nib create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/info.nib create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/objects.xib create mode 100644 rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/macpdf.icns create mode 100644 rosapps/smartpdf/fitz/apps/macosx/macpdf.c create mode 100644 rosapps/smartpdf/fitz/apps/mozilla/jri.h create mode 100644 rosapps/smartpdf/fitz/apps/mozilla/moz_main.c create mode 100644 rosapps/smartpdf/fitz/apps/mozilla/moz_winres.rc create mode 100644 rosapps/smartpdf/fitz/apps/mozilla/npapi.h create mode 100644 rosapps/smartpdf/fitz/apps/mozilla/npunix.c create mode 100644 rosapps/smartpdf/fitz/apps/mozilla/npupp.h create mode 100644 rosapps/smartpdf/fitz/apps/mozilla/npwin.c create mode 100644 rosapps/smartpdf/fitz/apps/pdftool.c create mode 100644 rosapps/smartpdf/fitz/apps/samshow.c create mode 100644 rosapps/smartpdf/fitz/apps/unix/gs_l.xbm create mode 100644 rosapps/smartpdf/fitz/apps/unix/x11pdf.c create mode 100644 rosapps/smartpdf/fitz/apps/unix/ximage.c create mode 100644 rosapps/smartpdf/fitz/apps/windows/gsapp.ico create mode 100644 rosapps/smartpdf/fitz/apps/windows/gsdoc.ico create mode 100644 rosapps/smartpdf/fitz/apps/windows/winmain.c create mode 100644 rosapps/smartpdf/fitz/apps/windows/winres.rc create mode 100644 rosapps/smartpdf/fitz/base/base_cleanname.c create mode 100644 rosapps/smartpdf/fitz/base/base_cpudep.c create mode 100644 rosapps/smartpdf/fitz/base/base_error.c create mode 100644 rosapps/smartpdf/fitz/base/base_hash.c create mode 100644 rosapps/smartpdf/fitz/base/base_matrix.c create mode 100644 rosapps/smartpdf/fitz/base/base_memory.c create mode 100644 rosapps/smartpdf/fitz/base/base_rect.c create mode 100644 rosapps/smartpdf/fitz/base/base_rune.c create mode 100644 rosapps/smartpdf/fitz/base/util_getopt.c create mode 100644 rosapps/smartpdf/fitz/base/util_strlcat.c create mode 100644 rosapps/smartpdf/fitz/base/util_strlcpy.c create mode 100644 rosapps/smartpdf/fitz/base/util_strsep.c create mode 100644 rosapps/smartpdf/fitz/build-debug.bat create mode 100644 rosapps/smartpdf/fitz/build.bat create mode 100644 rosapps/smartpdf/fitz/clean.bat create mode 100644 rosapps/smartpdf/fitz/fonts/Dingbats.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusMonL-Bold.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusMonL-BoldObli.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusMonL-Regu.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusMonL-ReguObli.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Medi.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-MediItal.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Regu.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-ReguItal.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusSanL-Bold.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusSanL-BoldItal.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusSanL-Regu.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/NimbusSanL-ReguItal.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/StandardSymL.cff.c create mode 100644 rosapps/smartpdf/fitz/fonts/URWChanceryL-MediItal.cff.c create mode 100644 rosapps/smartpdf/fitz/include/fitz-base.h create mode 100644 rosapps/smartpdf/fitz/include/fitz-draw.h create mode 100644 rosapps/smartpdf/fitz/include/fitz-stream.h create mode 100644 rosapps/smartpdf/fitz/include/fitz-world.h create mode 100644 rosapps/smartpdf/fitz/include/fitz.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/base_cpudep.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/base_geom.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/base_hash.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/base_math.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/base_pixmap.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/base_runtime.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/base_sysdep.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/draw_misc.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/draw_path.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/stm_buffer.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/stm_crypt.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/stm_filter.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/stm_object.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/stm_stream.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/wld_color.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/wld_font.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/wld_image.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/wld_path.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/wld_shade.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/wld_text.h create mode 100644 rosapps/smartpdf/fitz/include/fitz/wld_tree.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf/annot.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf/base14.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf/content.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf/page.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf/rsrc.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf/syntax.h create mode 100644 rosapps/smartpdf/fitz/include/mupdf/xref.h create mode 100644 rosapps/smartpdf/fitz/include/pdfapp.h create mode 100644 rosapps/smartpdf/fitz/include/samus.h create mode 100644 rosapps/smartpdf/fitz/include/samus/fixdoc.h create mode 100644 rosapps/smartpdf/fitz/include/samus/misc.h create mode 100644 rosapps/smartpdf/fitz/include/samus/names.h create mode 100644 rosapps/smartpdf/fitz/include/samus/pack.h create mode 100644 rosapps/smartpdf/fitz/include/samus/xml.h create mode 100644 rosapps/smartpdf/fitz/include/samus/zip.h create mode 100644 rosapps/smartpdf/fitz/include/win_os.h create mode 100644 rosapps/smartpdf/fitz/mupdf/glyphlist.txt create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_annot.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_build.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_cmap.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_colorspace1.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_colorspace2.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_crypt.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_debug.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_doctor.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_font.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_fontagl.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_fontenc.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_fontfile.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_fontfilefc.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_fontfilems.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_function.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_image.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_interpret.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_lex.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_nametree.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_open.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_outline.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_page.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_pagetree.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_parse.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_pattern.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_repair.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_resources.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_save.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_shade.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_shade1.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_shade4.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_store.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_stream.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_type3.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_unicode.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_xobject.c create mode 100644 rosapps/smartpdf/fitz/mupdf/pdf_xref.c create mode 100644 rosapps/smartpdf/fitz/raster/archppc.c create mode 100644 rosapps/smartpdf/fitz/raster/archsparc.c create mode 100644 rosapps/smartpdf/fitz/raster/archx86.c create mode 100644 rosapps/smartpdf/fitz/raster/glyphcache.c create mode 100644 rosapps/smartpdf/fitz/raster/imagedraw.c create mode 100644 rosapps/smartpdf/fitz/raster/imagescale.c create mode 100644 rosapps/smartpdf/fitz/raster/imageunpack.c create mode 100644 rosapps/smartpdf/fitz/raster/meshdraw.c create mode 100644 rosapps/smartpdf/fitz/raster/pathfill.c create mode 100644 rosapps/smartpdf/fitz/raster/pathscan.c create mode 100644 rosapps/smartpdf/fitz/raster/pathstroke.c create mode 100644 rosapps/smartpdf/fitz/raster/pixmap.c create mode 100644 rosapps/smartpdf/fitz/raster/porterduff.c create mode 100644 rosapps/smartpdf/fitz/raster/render.c create mode 100644 rosapps/smartpdf/fitz/samus/sa_fixdoc.c create mode 100644 rosapps/smartpdf/fitz/samus/sa_misc.c create mode 100644 rosapps/smartpdf/fitz/samus/sa_pack.c create mode 100644 rosapps/smartpdf/fitz/samus/sa_tiff.c create mode 100644 rosapps/smartpdf/fitz/samus/sa_xml.c create mode 100644 rosapps/smartpdf/fitz/samus/sa_zip.c create mode 100644 rosapps/smartpdf/fitz/stream/crypt_arc4.c create mode 100644 rosapps/smartpdf/fitz/stream/crypt_crc32.c create mode 100644 rosapps/smartpdf/fitz/stream/crypt_md5.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_a85d.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_a85e.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_ahxd.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_ahxe.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_arc4.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_dctc.h create mode 100644 rosapps/smartpdf/fitz/stream/filt_dctd.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_dcte.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_faxc.h create mode 100644 rosapps/smartpdf/fitz/stream/filt_faxd.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_faxd.h create mode 100644 rosapps/smartpdf/fitz/stream/filt_faxdtab.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_faxe.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_faxe.h create mode 100644 rosapps/smartpdf/fitz/stream/filt_faxetab.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_flate.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_jbig2d.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_jpxd.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_lzwd.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_lzwe.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_null.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_pipeline.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_predict.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_rld.c create mode 100644 rosapps/smartpdf/fitz/stream/filt_rle.c create mode 100644 rosapps/smartpdf/fitz/stream/obj_array.c create mode 100644 rosapps/smartpdf/fitz/stream/obj_dict.c create mode 100644 rosapps/smartpdf/fitz/stream/obj_parse.c create mode 100644 rosapps/smartpdf/fitz/stream/obj_print.c create mode 100644 rosapps/smartpdf/fitz/stream/obj_simple.c create mode 100644 rosapps/smartpdf/fitz/stream/stm_buffer.c create mode 100644 rosapps/smartpdf/fitz/stream/stm_filter.c create mode 100644 rosapps/smartpdf/fitz/stream/stm_misc.c create mode 100644 rosapps/smartpdf/fitz/stream/stm_open.c create mode 100644 rosapps/smartpdf/fitz/stream/stm_read.c create mode 100644 rosapps/smartpdf/fitz/stream/stm_write.c create mode 100644 rosapps/smartpdf/fitz/world/node_misc1.c create mode 100644 rosapps/smartpdf/fitz/world/node_misc2.c create mode 100644 rosapps/smartpdf/fitz/world/node_optimize.c create mode 100644 rosapps/smartpdf/fitz/world/node_path.c create mode 100644 rosapps/smartpdf/fitz/world/node_text.c create mode 100644 rosapps/smartpdf/fitz/world/node_tolisp.c create mode 100644 rosapps/smartpdf/fitz/world/node_toxml.c create mode 100644 rosapps/smartpdf/fitz/world/node_tree.c create mode 100644 rosapps/smartpdf/fitz/world/res_colorspace.c create mode 100644 rosapps/smartpdf/fitz/world/res_font.c create mode 100644 rosapps/smartpdf/fitz/world/res_image.c create mode 100644 rosapps/smartpdf/fitz/world/res_shade.c create mode 100644 rosapps/smartpdf/fitzheadlib.vcproj create mode 100644 rosapps/smartpdf/fitzlib.cbp create mode 100644 rosapps/smartpdf/fitzlib.vcproj create mode 100644 rosapps/smartpdf/pdfbench.vcproj create mode 100644 rosapps/smartpdf/pdfbenchbase.vcproj create mode 100644 rosapps/smartpdf/poppler.rbuild create mode 100644 rosapps/smartpdf/poppler/AUTHORS create mode 100644 rosapps/smartpdf/poppler/COPYING create mode 100644 rosapps/smartpdf/poppler/ChangeLog create mode 100644 rosapps/smartpdf/poppler/INSTALL create mode 100644 rosapps/smartpdf/poppler/NEWS create mode 100644 rosapps/smartpdf/poppler/README create mode 100644 rosapps/smartpdf/poppler/README-XPDF create mode 100644 rosapps/smartpdf/poppler/TODO create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiBase.cc create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiBase.h create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiEncodings.cc create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiEncodings.h create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiTrueType.cc create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiTrueType.h create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiType1.cc create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiType1.h create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiType1C.cc create mode 100644 rosapps/smartpdf/poppler/fofi/FoFiType1C.h create mode 100644 rosapps/smartpdf/poppler/fofi/Makefile.am create mode 100644 rosapps/smartpdf/poppler/goo/FastAlloc.cc create mode 100644 rosapps/smartpdf/poppler/goo/FastAlloc.h create mode 100644 rosapps/smartpdf/poppler/goo/FastFixedAllocator.cc create mode 100644 rosapps/smartpdf/poppler/goo/FastFixedAllocator.h create mode 100644 rosapps/smartpdf/poppler/goo/FixedPoint.cc create mode 100644 rosapps/smartpdf/poppler/goo/FixedPoint.h create mode 100644 rosapps/smartpdf/poppler/goo/GooHash.cc create mode 100644 rosapps/smartpdf/poppler/goo/GooHash.h create mode 100644 rosapps/smartpdf/poppler/goo/GooList.cc create mode 100644 rosapps/smartpdf/poppler/goo/GooList.h create mode 100644 rosapps/smartpdf/poppler/goo/GooMutex.h create mode 100644 rosapps/smartpdf/poppler/goo/GooString.cc create mode 100644 rosapps/smartpdf/poppler/goo/GooString.h create mode 100644 rosapps/smartpdf/poppler/goo/GooTimer.cc create mode 100644 rosapps/smartpdf/poppler/goo/GooTimer.h create mode 100644 rosapps/smartpdf/poppler/goo/GooVector.h create mode 100644 rosapps/smartpdf/poppler/goo/Makefile.am create mode 100644 rosapps/smartpdf/poppler/goo/gfile.cc create mode 100644 rosapps/smartpdf/poppler/goo/gfile.h create mode 100644 rosapps/smartpdf/poppler/goo/gmem.c create mode 100644 rosapps/smartpdf/poppler/goo/gmem.h create mode 100644 rosapps/smartpdf/poppler/goo/gmempp.cc create mode 100644 rosapps/smartpdf/poppler/goo/gtypes.h create mode 100644 rosapps/smartpdf/poppler/poppler/Annot.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Annot.h create mode 100644 rosapps/smartpdf/poppler/poppler/Array.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Array.h create mode 100644 rosapps/smartpdf/poppler/poppler/ArthurOutputDev.cc create mode 100644 rosapps/smartpdf/poppler/poppler/ArthurOutputDev.h create mode 100644 rosapps/smartpdf/poppler/poppler/BaseFile.h create mode 100644 rosapps/smartpdf/poppler/poppler/BuiltinFont.cc create mode 100644 rosapps/smartpdf/poppler/poppler/BuiltinFont.h create mode 100644 rosapps/smartpdf/poppler/poppler/BuiltinFontTables.cc create mode 100644 rosapps/smartpdf/poppler/poppler/BuiltinFontTables.h create mode 100644 rosapps/smartpdf/poppler/poppler/CMap.cc create mode 100644 rosapps/smartpdf/poppler/poppler/CMap.h create mode 100644 rosapps/smartpdf/poppler/poppler/CairoFontEngine.cc create mode 100644 rosapps/smartpdf/poppler/poppler/CairoFontEngine.h create mode 100644 rosapps/smartpdf/poppler/poppler/CairoOutputDev.cc create mode 100644 rosapps/smartpdf/poppler/poppler/CairoOutputDev.h create mode 100644 rosapps/smartpdf/poppler/poppler/Catalog.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Catalog.h create mode 100644 rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.cc create mode 100644 rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.h create mode 100644 rosapps/smartpdf/poppler/poppler/CharTypes.h create mode 100644 rosapps/smartpdf/poppler/poppler/CompactFontTables.h create mode 100644 rosapps/smartpdf/poppler/poppler/DCTStream.cc create mode 100644 rosapps/smartpdf/poppler/poppler/DCTStream.h create mode 100644 rosapps/smartpdf/poppler/poppler/Decrypt.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Decrypt.h create mode 100644 rosapps/smartpdf/poppler/poppler/Dict.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Dict.h create mode 100644 rosapps/smartpdf/poppler/poppler/Error.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Error.h create mode 100644 rosapps/smartpdf/poppler/poppler/ErrorCodes.h create mode 100644 rosapps/smartpdf/poppler/poppler/FlateStream.cc create mode 100644 rosapps/smartpdf/poppler/poppler/FlateStream.h create mode 100644 rosapps/smartpdf/poppler/poppler/FontEncodingTables.cc create mode 100644 rosapps/smartpdf/poppler/poppler/FontEncodingTables.h create mode 100644 rosapps/smartpdf/poppler/poppler/FontInfo.cc create mode 100644 rosapps/smartpdf/poppler/poppler/FontInfo.h create mode 100644 rosapps/smartpdf/poppler/poppler/Function.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Function.h create mode 100644 rosapps/smartpdf/poppler/poppler/Gfx.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Gfx.h create mode 100644 rosapps/smartpdf/poppler/poppler/GfxFont.cc create mode 100644 rosapps/smartpdf/poppler/poppler/GfxFont.h create mode 100644 rosapps/smartpdf/poppler/poppler/GfxState.cc create mode 100644 rosapps/smartpdf/poppler/poppler/GfxState.h create mode 100644 rosapps/smartpdf/poppler/poppler/GlobalParams.cc create mode 100644 rosapps/smartpdf/poppler/poppler/GlobalParams.h create mode 100644 rosapps/smartpdf/poppler/poppler/GlobalParamsWin.cc create mode 100644 rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.cc create mode 100644 rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.h create mode 100644 rosapps/smartpdf/poppler/poppler/JBIG2Stream.cc create mode 100644 rosapps/smartpdf/poppler/poppler/JBIG2Stream.h create mode 100644 rosapps/smartpdf/poppler/poppler/JPXStream.cc create mode 100644 rosapps/smartpdf/poppler/poppler/JPXStream.h create mode 100644 rosapps/smartpdf/poppler/poppler/Lexer.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Lexer.h create mode 100644 rosapps/smartpdf/poppler/poppler/Link.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Link.h create mode 100644 rosapps/smartpdf/poppler/poppler/Makefile.am create mode 100644 rosapps/smartpdf/poppler/poppler/NameToCharCode.cc create mode 100644 rosapps/smartpdf/poppler/poppler/NameToCharCode.h create mode 100644 rosapps/smartpdf/poppler/poppler/NameToUnicodeTable.h create mode 100644 rosapps/smartpdf/poppler/poppler/Object.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Object.h create mode 100644 rosapps/smartpdf/poppler/poppler/Outline.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Outline.h create mode 100644 rosapps/smartpdf/poppler/poppler/OutputDev.cc create mode 100644 rosapps/smartpdf/poppler/poppler/OutputDev.h create mode 100644 rosapps/smartpdf/poppler/poppler/PDFDoc.cc create mode 100644 rosapps/smartpdf/poppler/poppler/PDFDoc.h create mode 100644 rosapps/smartpdf/poppler/poppler/PDFDocEncoding.cc create mode 100644 rosapps/smartpdf/poppler/poppler/PDFDocEncoding.h create mode 100644 rosapps/smartpdf/poppler/poppler/PSOutputDev.cc create mode 100644 rosapps/smartpdf/poppler/poppler/PSOutputDev.h create mode 100644 rosapps/smartpdf/poppler/poppler/PSTokenizer.cc create mode 100644 rosapps/smartpdf/poppler/poppler/PSTokenizer.h create mode 100644 rosapps/smartpdf/poppler/poppler/Page.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Page.h create mode 100644 rosapps/smartpdf/poppler/poppler/PageLabelInfo.cc create mode 100644 rosapps/smartpdf/poppler/poppler/PageLabelInfo.h create mode 100644 rosapps/smartpdf/poppler/poppler/PageTransition.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Parser.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Parser.h create mode 100644 rosapps/smartpdf/poppler/poppler/ProfileData.cc create mode 100644 rosapps/smartpdf/poppler/poppler/ProfileData.h create mode 100644 rosapps/smartpdf/poppler/poppler/SecurityHandler.cc create mode 100644 rosapps/smartpdf/poppler/poppler/SecurityHandler.h create mode 100644 rosapps/smartpdf/poppler/poppler/Sound.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Sound.h create mode 100644 rosapps/smartpdf/poppler/poppler/SplashOutputDev.cc create mode 100644 rosapps/smartpdf/poppler/poppler/SplashOutputDev.h create mode 100644 rosapps/smartpdf/poppler/poppler/Stream-CCITT.h create mode 100644 rosapps/smartpdf/poppler/poppler/Stream.cc create mode 100644 rosapps/smartpdf/poppler/poppler/Stream.h create mode 100644 rosapps/smartpdf/poppler/poppler/TextOutputDev.cc create mode 100644 rosapps/smartpdf/poppler/poppler/TextOutputDev.h create mode 100644 rosapps/smartpdf/poppler/poppler/UGooString.cc create mode 100644 rosapps/smartpdf/poppler/poppler/UGooString.h create mode 100644 rosapps/smartpdf/poppler/poppler/UTF8.h create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeCClassTables.h create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeCompTables.h create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeDecompTables.h create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeMap.cc create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeMap.h create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeMapTables.h create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.cc create mode 100644 rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.h create mode 100644 rosapps/smartpdf/poppler/poppler/XRef.cc create mode 100644 rosapps/smartpdf/poppler/poppler/XRef.h create mode 100644 rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.cc create mode 100644 rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.h create mode 100644 rosapps/smartpdf/poppler/poppler/poppler-config.h.in create mode 100644 rosapps/smartpdf/poppler/splash/Makefile.am create mode 100644 rosapps/smartpdf/poppler/splash/Splash.cc create mode 100644 rosapps/smartpdf/poppler/splash/Splash.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashBitmap.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashBitmap.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashClip.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashClip.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashErrorCodes.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashFTFont.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashFTFont.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashFTFontEngine.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashFTFontEngine.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashFTFontFile.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashFTFontFile.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashFont.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashFont.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashFontEngine.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashFontEngine.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashFontFile.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashFontFile.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashFontFileID.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashFontFileID.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashGlyphBitmap.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashMath.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashPath.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashPath.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashPattern.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashPattern.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashScreen.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashScreen.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashState.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashState.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashT1Font.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashT1Font.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashT1FontEngine.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashT1FontEngine.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashT1FontFile.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashT1FontFile.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashTypes.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashXPath.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashXPath.h create mode 100644 rosapps/smartpdf/poppler/splash/SplashXPathScanner.cc create mode 100644 rosapps/smartpdf/poppler/splash/SplashXPathScanner.h create mode 100644 rosapps/smartpdf/poppler/test/Makefile.am create mode 100644 rosapps/smartpdf/poppler/test/gtk-cairo-test.cc create mode 100644 rosapps/smartpdf/poppler/test/gtk-splash-test.cc create mode 100644 rosapps/smartpdf/poppler/test/pdf-inspector.cc create mode 100644 rosapps/smartpdf/poppler/test/pdf-inspector.glade create mode 100644 rosapps/smartpdf/poppler/test/pdf-operators.c create mode 100644 rosapps/smartpdf/poppler/test/pdfbench.cc create mode 100644 rosapps/smartpdf/poppler/utils/HtmlFonts.cc create mode 100644 rosapps/smartpdf/poppler/utils/HtmlFonts.h create mode 100644 rosapps/smartpdf/poppler/utils/HtmlLinks.cc create mode 100644 rosapps/smartpdf/poppler/utils/HtmlLinks.h create mode 100644 rosapps/smartpdf/poppler/utils/HtmlOutputDev.cc create mode 100644 rosapps/smartpdf/poppler/utils/HtmlOutputDev.h create mode 100644 rosapps/smartpdf/poppler/utils/ImageOutputDev.cc create mode 100644 rosapps/smartpdf/poppler/utils/ImageOutputDev.h create mode 100644 rosapps/smartpdf/poppler/utils/Makefile.am create mode 100644 rosapps/smartpdf/poppler/utils/parseargs.c create mode 100644 rosapps/smartpdf/poppler/utils/parseargs.h create mode 100644 rosapps/smartpdf/poppler/utils/pdf2xml.dtd create mode 100644 rosapps/smartpdf/poppler/utils/pdffonts.1 create mode 100644 rosapps/smartpdf/poppler/utils/pdffonts.cc create mode 100644 rosapps/smartpdf/poppler/utils/pdfimages.1 create mode 100644 rosapps/smartpdf/poppler/utils/pdfimages.cc create mode 100644 rosapps/smartpdf/poppler/utils/pdfinfo.1 create mode 100644 rosapps/smartpdf/poppler/utils/pdfinfo.cc create mode 100644 rosapps/smartpdf/poppler/utils/pdftohtml.1 create mode 100644 rosapps/smartpdf/poppler/utils/pdftohtml.cc create mode 100644 rosapps/smartpdf/poppler/utils/pdftoppm.1 create mode 100644 rosapps/smartpdf/poppler/utils/pdftoppm.cc create mode 100644 rosapps/smartpdf/poppler/utils/pdftops.1 create mode 100644 rosapps/smartpdf/poppler/utils/pdftops.cc create mode 100644 rosapps/smartpdf/poppler/utils/pdftotext.1 create mode 100644 rosapps/smartpdf/poppler/utils/pdftotext.cc create mode 100644 rosapps/smartpdf/popplerlib.cbp create mode 100644 rosapps/smartpdf/popplerlib.vcproj create mode 100644 rosapps/smartpdf/smartpdf.def create mode 100644 rosapps/smartpdf/smartpdf.rbuild create mode 100644 rosapps/smartpdf/src/AppPrefs.cc create mode 100644 rosapps/smartpdf/src/AppPrefs.h create mode 100644 rosapps/smartpdf/src/DisplayModel.cc create mode 100644 rosapps/smartpdf/src/DisplayModel.h create mode 100644 rosapps/smartpdf/src/DisplayModelFitz.cc create mode 100644 rosapps/smartpdf/src/DisplayModelFitz.h create mode 100644 rosapps/smartpdf/src/DisplayModelSplash.cc create mode 100644 rosapps/smartpdf/src/DisplayModelSplash.h create mode 100644 rosapps/smartpdf/src/DisplayState.cc create mode 100644 rosapps/smartpdf/src/DisplayState.h create mode 100644 rosapps/smartpdf/src/FileHistory.cc create mode 100644 rosapps/smartpdf/src/FileHistory.h create mode 100644 rosapps/smartpdf/src/Kopie von SumatraPDF.cpp create mode 100644 rosapps/smartpdf/src/PdfEngine.cc create mode 100644 rosapps/smartpdf/src/PdfEngine.h create mode 100644 rosapps/smartpdf/src/PdftestWinPreview.cc create mode 100644 rosapps/smartpdf/src/Resource.h create mode 100644 rosapps/smartpdf/src/SumatraDialogs.cc create mode 100644 rosapps/smartpdf/src/SumatraDialogs.h create mode 100644 rosapps/smartpdf/src/SumatraPDF.aps create mode 100644 rosapps/smartpdf/src/SumatraPDF.cpp create mode 100644 rosapps/smartpdf/src/SumatraPDF.h create mode 100644 rosapps/smartpdf/src/SumatraPDF.ico create mode 100644 rosapps/smartpdf/src/SumatraPDF.rc create mode 100644 rosapps/smartpdf/src/build-release.bat create mode 100644 rosapps/smartpdf/src/config.h create mode 100644 rosapps/smartpdf/src/dragcursor.cur create mode 100644 rosapps/smartpdf/src/icons-silk/Thumbs.db create mode 100644 rosapps/smartpdf/src/icons-silk/folder.bmp create mode 100644 rosapps/smartpdf/src/icons-silk/folder.png create mode 100644 rosapps/smartpdf/src/icons-silk/next.bmp create mode 100644 rosapps/smartpdf/src/icons-silk/next.png create mode 100644 rosapps/smartpdf/src/icons-silk/previous.bmp create mode 100644 rosapps/smartpdf/src/icons-silk/previous.png create mode 100644 rosapps/smartpdf/src/icons-silk/printer.png create mode 100644 rosapps/smartpdf/src/icons-silk/rotate_anticlock.png create mode 100644 rosapps/smartpdf/src/icons-silk/rotate_cloc.png create mode 100644 rosapps/smartpdf/src/icons-silk/zoom_in.bmp create mode 100644 rosapps/smartpdf/src/icons-silk/zoom_in.png create mode 100644 rosapps/smartpdf/src/icons-silk/zoom_out.bmp create mode 100644 rosapps/smartpdf/src/icons-silk/zoom_out.png create mode 100644 rosapps/smartpdf/src/pdfbench.cc create mode 100644 rosapps/smartpdf/src/poppler-config.h create mode 100644 rosapps/smartpdf/src/strings.txt create mode 100644 rosapps/smartpdf/src/todo.txt create mode 100644 rosapps/smartpdf/src/toolbar-disabled.bmp create mode 100644 rosapps/smartpdf/src/toolbar.bmp create mode 100644 rosapps/smartpdf/src/translations.cpp create mode 100644 rosapps/smartpdf/src/translations.h create mode 100644 rosapps/smartpdf/src/translations_txt.c create mode 100644 rosapps/smartpdf/src/translations_txt.h create mode 100644 rosapps/smartpdf/sumatrapdf.cbp create mode 100644 rosapps/smartpdf/sumatrapdf.sln create mode 100644 rosapps/smartpdf/sumatrapdf.vcproj create mode 100644 rosapps/smartpdf/sumatrapdfdll.sln create mode 100644 rosapps/smartpdf/sumatrapdfdll.vcproj diff --git a/rosapps/directory.rbuild b/rosapps/directory.rbuild index ba7b0e29402..f4dd9e6a836 100644 --- a/rosapps/directory.rbuild +++ b/rosapps/directory.rbuild @@ -46,12 +46,10 @@ - - @@ -106,4 +104,13 @@ + + + diff --git a/rosapps/lib/directory.rbuild b/rosapps/lib/directory.rbuild index e8126388361..67aa5343360 100644 --- a/rosapps/lib/directory.rbuild +++ b/rosapps/lib/directory.rbuild @@ -1,6 +1,14 @@ + + + + + + + diff --git a/rosapps/lib/libjpeg/LibJPEG.dsp b/rosapps/lib/libjpeg/LibJPEG.dsp new file mode 100644 index 00000000000..a73f58be494 --- /dev/null +++ b/rosapps/lib/libjpeg/LibJPEG.dsp @@ -0,0 +1,328 @@ +# Microsoft Developer Studio Project File - Name="LibJPEG" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=LibJPEG - Win32 Debug +!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 "LibJPEG.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 "LibJPEG.mak" CFG="LibJPEG - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LibJPEG - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "LibJPEG - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName ""$/FreeImage/LibJPEG", IHAAAAAA" +# PROP Scc_LocalPath "." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LibJPEG - 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 Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O1 /I "..\zlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "LibJPEG - 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 "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "LibJPEG - Win32 Release" +# Name "LibJPEG - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\jcapimin.c +# End Source File +# Begin Source File + +SOURCE=.\jcapistd.c +# End Source File +# Begin Source File + +SOURCE=.\jccoefct.c +# End Source File +# Begin Source File + +SOURCE=.\jccolor.c +# End Source File +# Begin Source File + +SOURCE=.\jcdctmgr.c +# End Source File +# Begin Source File + +SOURCE=.\jchuff.c +# End Source File +# Begin Source File + +SOURCE=.\jcinit.c +# End Source File +# Begin Source File + +SOURCE=.\jcmainct.c +# End Source File +# Begin Source File + +SOURCE=.\jcmarker.c +# End Source File +# Begin Source File + +SOURCE=.\jcmaster.c +# End Source File +# Begin Source File + +SOURCE=.\jcomapi.c +# End Source File +# Begin Source File + +SOURCE=.\jcparam.c +# End Source File +# Begin Source File + +SOURCE=.\jcphuff.c +# End Source File +# Begin Source File + +SOURCE=.\jcprepct.c +# End Source File +# Begin Source File + +SOURCE=.\jcsample.c +# End Source File +# Begin Source File + +SOURCE=.\jctrans.c +# End Source File +# Begin Source File + +SOURCE=.\jdapimin.c +# End Source File +# Begin Source File + +SOURCE=.\jdapistd.c +# End Source File +# Begin Source File + +SOURCE=.\jdatadst.c +# End Source File +# Begin Source File + +SOURCE=.\jdatasrc.c +# End Source File +# Begin Source File + +SOURCE=.\jdcoefct.c +# End Source File +# Begin Source File + +SOURCE=.\jdcolor.c +# End Source File +# Begin Source File + +SOURCE=.\jddctmgr.c +# End Source File +# Begin Source File + +SOURCE=.\jdhuff.c +# End Source File +# Begin Source File + +SOURCE=.\jdinput.c +# End Source File +# Begin Source File + +SOURCE=.\jdmainct.c +# End Source File +# Begin Source File + +SOURCE=.\jdmarker.c +# End Source File +# Begin Source File + +SOURCE=.\jdmaster.c +# End Source File +# Begin Source File + +SOURCE=.\jdmerge.c +# End Source File +# Begin Source File + +SOURCE=.\jdphuff.c +# End Source File +# Begin Source File + +SOURCE=.\jdpostct.c +# End Source File +# Begin Source File + +SOURCE=.\jdsample.c +# End Source File +# Begin Source File + +SOURCE=.\jdtrans.c +# End Source File +# Begin Source File + +SOURCE=.\jerror.c +# End Source File +# Begin Source File + +SOURCE=.\jfdctflt.c +# End Source File +# Begin Source File + +SOURCE=.\jfdctfst.c +# End Source File +# Begin Source File + +SOURCE=.\jfdctint.c +# End Source File +# Begin Source File + +SOURCE=.\jidctflt.c +# End Source File +# Begin Source File + +SOURCE=.\jidctfst.c +# End Source File +# Begin Source File + +SOURCE=.\jidctint.c +# End Source File +# Begin Source File + +SOURCE=.\jidctred.c +# End Source File +# Begin Source File + +SOURCE=.\jmemmgr.c +# End Source File +# Begin Source File + +SOURCE=.\jmemnobs.c +# End Source File +# Begin Source File + +SOURCE=.\jquant1.c +# End Source File +# Begin Source File + +SOURCE=.\jquant2.c +# End Source File +# Begin Source File + +SOURCE=.\jutils.c +# End Source File +# Begin Source File + +SOURCE=.\transupp.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\jchuff.h +# End Source File +# Begin Source File + +SOURCE=.\jconfig.h +# End Source File +# Begin Source File + +SOURCE=.\jdct.h +# End Source File +# Begin Source File + +SOURCE=.\jdhuff.h +# End Source File +# Begin Source File + +SOURCE=.\jerror.h +# End Source File +# Begin Source File + +SOURCE=.\jinclude.h +# End Source File +# Begin Source File + +SOURCE=.\jmemsys.h +# End Source File +# Begin Source File + +SOURCE=.\jmorecfg.h +# End Source File +# Begin Source File + +SOURCE=.\jpegint.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib.h +# End Source File +# Begin Source File + +SOURCE=.\jversion.h +# End Source File +# Begin Source File + +SOURCE=.\transupp.h +# End Source File +# End Group +# End Target +# End Project diff --git a/rosapps/lib/libjpeg/LibJPEG.vcproj b/rosapps/lib/libjpeg/LibJPEG.vcproj new file mode 100644 index 00000000000..d1fd21959ee --- /dev/null +++ b/rosapps/lib/libjpeg/LibJPEG.vcproj @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/lib/libjpeg/ansi2knr.c b/rosapps/lib/libjpeg/ansi2knr.c new file mode 100644 index 00000000000..4e05fc2d321 --- /dev/null +++ b/rosapps/lib/libjpeg/ansi2knr.c @@ -0,0 +1,693 @@ +/* ansi2knr.c */ +/* Convert ANSI C function definitions to K&R ("traditional C") syntax */ + +/* +ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY. No author or distributor accepts responsibility to anyone for the +consequences of using it or for whether it serves any particular purpose or +works at all, unless he says so in writing. Refer to the GNU General Public +License (the "GPL") for full details. + +Everyone is granted permission to copy, modify and redistribute ansi2knr, +but only under the conditions described in the GPL. A copy of this license +is supposed to have been given to you along with ansi2knr so you can know +your rights and responsibilities. It should be in a file named COPYLEFT. +[In the IJG distribution, the GPL appears below, not in a separate file.] +Among other things, the copyright notice and this notice must be preserved +on all copies. + +We explicitly state here what we believe is already implied by the GPL: if +the ansi2knr program is distributed as a separate set of sources and a +separate executable file which are aggregated on a storage medium together +with another program, this in itself does not bring the other program under +the GPL, nor does the mere fact that such a program or the procedures for +constructing it invoke the ansi2knr executable bring any other part of the +program under the GPL. +*/ + +/* +---------- Here is the GNU GPL file COPYLEFT, referred to above ---------- +----- These terms do NOT apply to the JPEG software itself; see README ------ + + GHOSTSCRIPT GENERAL PUBLIC LICENSE + (Clarified 11 Feb 1988) + + Copyright (C) 1988 Richard M. Stallman + Everyone is permitted to copy and distribute verbatim copies of this + license, but changing it is not allowed. You can also use this wording + to make the terms for other programs. + + The license agreements of most software companies keep you at the +mercy of those companies. By contrast, our general public license is +intended to give everyone the right to share Ghostscript. To make sure +that you get the rights we want you to have, we need to make +restrictions that forbid anyone to deny you these rights or to ask you +to surrender the rights. Hence this license agreement. + + Specifically, we want to make sure that you have the right to give +away copies of Ghostscript, that you receive source code or else can get +it if you want it, that you can change Ghostscript or use pieces of it +in new free programs, and that you know you can do these things. + + To make sure that everyone has such rights, we have to forbid you to +deprive anyone else of these rights. For example, if you distribute +copies of Ghostscript, 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 tell them their rights. + + Also, for our own protection, we must make certain that everyone finds +out that there is no warranty for Ghostscript. If Ghostscript is +modified by someone else and passed on, we want its recipients to know +that what they have is not what we distributed, so that any problems +introduced by others will not reflect on our reputation. + + Therefore we (Richard M. Stallman and the Free Software Foundation, +Inc.) make the following terms which say what you must do to be allowed +to distribute or change Ghostscript. + + + COPYING POLICIES + + 1. You may copy and distribute verbatim copies of Ghostscript source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy a valid copyright and license +notice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved. +Distributed by Free Software Foundation, Inc." (or with whatever year is +appropriate); keep intact the notices on all files that refer to this +License Agreement and to the absence of any warranty; and give any other +recipients of the Ghostscript program a copy of this License Agreement +along with the program. You may charge a distribution fee for the +physical act of transferring a copy. + + 2. You may modify your copy or copies of Ghostscript or any portion of +it, and copy and distribute such modifications under the terms of +Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating + that you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, + that in whole or in part contains or is a derivative of Ghostscript + or any part thereof, to be licensed at no charge to all third + parties on terms identical to those contained in this License + Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty + protection in exchange for a fee. + +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute Ghostscript (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the +terms of Paragraphs 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 + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. + + 4. You may not copy, sublicense, distribute or transfer Ghostscript +except as expressly provided under this License Agreement. Any attempt +otherwise to copy, sublicense, distribute or transfer Ghostscript is +void and your rights to use the program under this License agreement +shall be automatically terminated. However, parties who have received +computer software programs from you with this License Agreement will not +have their licenses terminated so long as such parties remain in full +compliance. + + 5. If you wish to incorporate parts of Ghostscript into other free +programs whose distribution conditions are different, write to the Free +Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not +yet worked out a simple rule that can be stated here, but we will often +permit this. We 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. + +Your comments and suggestions about our licensing policies and our +software are welcome! Please contact the Free Software Foundation, +Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296. + + NO WARRANTY + + BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY +NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD +M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES +PROVIDE GHOSTSCRIPT "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 GHOSTSCRIPT IS WITH +YOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. +STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN +ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE +GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING +ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE +(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE +PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU +HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM +BY ANY OTHER PARTY. + +-------------------- End of file COPYLEFT ------------------------------ +*/ + +/* + * Usage: + ansi2knr input_file [output_file] + * If no output_file is supplied, output goes to stdout. + * There are no error messages. + * + * ansi2knr recognizes function definitions by seeing a non-keyword + * identifier at the left margin, followed by a left parenthesis, + * with a right parenthesis as the last character on the line, + * and with a left brace as the first token on the following line + * (ignoring possible intervening comments). + * It will recognize a multi-line header provided that no intervening + * line ends with a left or right brace or a semicolon. + * These algorithms ignore whitespace and comments, except that + * the function name must be the first thing on the line. + * The following constructs will confuse it: + * - Any other construct that starts at the left margin and + * follows the above syntax (such as a macro or function call). + * - Some macros that tinker with the syntax of the function header. + */ + +/* + * The original and principal author of ansi2knr is L. Peter Deutsch + * . Other authors are noted in the change history + * that follows (in reverse chronological order): + lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with + compilers that don't understand void, as suggested by + Tom Lane + lpd 96-01-15 changed to require that the first non-comment token + on the line following a function header be a left brace, + to reduce sensitivity to macros, as suggested by Tom Lane + + lpd 95-06-22 removed #ifndefs whose sole purpose was to define + undefined preprocessor symbols as 0; changed all #ifdefs + for configuration symbols to #ifs + lpd 95-04-05 changed copyright notice to make it clear that + including ansi2knr in a program does not bring the entire + program under the GPL + lpd 94-12-18 added conditionals for systems where ctype macros + don't handle 8-bit characters properly, suggested by + Francois Pinard ; + removed --varargs switch (this is now the default) + lpd 94-10-10 removed CONFIG_BROKETS conditional + lpd 94-07-16 added some conditionals to help GNU `configure', + suggested by Francois Pinard ; + properly erase prototype args in function parameters, + contributed by Jim Avera ; + correct error in writeblanks (it shouldn't erase EOLs) + lpd 89-xx-xx original version + */ + +/* Most of the conditionals here are to make ansi2knr work with */ +/* or without the GNU configure machinery. */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include + +#if HAVE_CONFIG_H + +/* + For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h). + This will define HAVE_CONFIG_H and so, activate the following lines. + */ + +# if STDC_HEADERS || HAVE_STRING_H +# include +# else +# include +# endif + +#else /* not HAVE_CONFIG_H */ + +/* Otherwise do it the hard way */ + +# ifdef BSD +# include +# else +# ifdef VMS + extern int strlen(), strncmp(); +# else +# include +# endif +# endif + +#endif /* not HAVE_CONFIG_H */ + +#if STDC_HEADERS +# include +#else +/* + malloc and free should be declared in stdlib.h, + but if you've got a K&R compiler, they probably aren't. + */ +# ifdef MSDOS +# include +# else +# ifdef VMS + extern char *malloc(); + extern void free(); +# else + extern char *malloc(); + extern int free(); +# endif +# endif + +#endif + +/* + * The ctype macros don't always handle 8-bit characters correctly. + * Compensate for this here. + */ +#ifdef isascii +# undef HAVE_ISASCII /* just in case */ +# define HAVE_ISASCII 1 +#else +#endif +#if STDC_HEADERS || !HAVE_ISASCII +# define is_ascii(c) 1 +#else +# define is_ascii(c) isascii(c) +#endif + +#define is_space(c) (is_ascii(c) && isspace(c)) +#define is_alpha(c) (is_ascii(c) && isalpha(c)) +#define is_alnum(c) (is_ascii(c) && isalnum(c)) + +/* Scanning macros */ +#define isidchar(ch) (is_alnum(ch) || (ch) == '_') +#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_') + +/* Forward references */ +char *skipspace(); +int writeblanks(); +int test1(); +int convert1(); + +/* The main program */ +int +main(argc, argv) + int argc; + char *argv[]; +{ FILE *in, *out; +#define bufsize 5000 /* arbitrary size */ + char *buf; + char *line; + char *more; + /* + * In previous versions, ansi2knr recognized a --varargs switch. + * If this switch was supplied, ansi2knr would attempt to convert + * a ... argument to va_alist and va_dcl; if this switch was not + * supplied, ansi2knr would simply drop any such arguments. + * Now, ansi2knr always does this conversion, and we only + * check for this switch for backward compatibility. + */ + int convert_varargs = 1; + + if ( argc > 1 && argv[1][0] == '-' ) + { if ( !strcmp(argv[1], "--varargs") ) + { convert_varargs = 1; + argc--; + argv++; + } + else + { fprintf(stderr, "Unrecognized switch: %s\n", argv[1]); + exit(1); + } + } + switch ( argc ) + { + default: + printf("Usage: ansi2knr input_file [output_file]\n"); + exit(0); + case 2: + out = stdout; + break; + case 3: + out = fopen(argv[2], "w"); + if ( out == NULL ) + { fprintf(stderr, "Cannot open output file %s\n", argv[2]); + exit(1); + } + } + in = fopen(argv[1], "r"); + if ( in == NULL ) + { fprintf(stderr, "Cannot open input file %s\n", argv[1]); + exit(1); + } + fprintf(out, "#line 1 \"%s\"\n", argv[1]); + buf = malloc(bufsize); + line = buf; + while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) + { +test: line += strlen(line); + switch ( test1(buf) ) + { + case 2: /* a function header */ + convert1(buf, out, 1, convert_varargs); + break; + case 1: /* a function */ + /* Check for a { at the start of the next line. */ + more = ++line; +f: if ( line >= buf + (bufsize - 1) ) /* overflow check */ + goto wl; + if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL ) + goto wl; + switch ( *skipspace(more, 1) ) + { + case '{': + /* Definitely a function header. */ + convert1(buf, out, 0, convert_varargs); + fputs(more, out); + break; + case 0: + /* The next line was blank or a comment: */ + /* keep scanning for a non-comment. */ + line += strlen(line); + goto f; + default: + /* buf isn't a function header, but */ + /* more might be. */ + fputs(buf, out); + strcpy(buf, more); + line = buf; + goto test; + } + break; + case -1: /* maybe the start of a function */ + if ( line != buf + (bufsize - 1) ) /* overflow check */ + continue; + /* falls through */ + default: /* not a function */ +wl: fputs(buf, out); + break; + } + line = buf; + } + if ( line != buf ) + fputs(buf, out); + free(buf); + fclose(out); + fclose(in); + return 0; +} + +/* Skip over space and comments, in either direction. */ +char * +skipspace(p, dir) + register char *p; + register int dir; /* 1 for forward, -1 for backward */ +{ for ( ; ; ) + { while ( is_space(*p) ) + p += dir; + if ( !(*p == '/' && p[dir] == '*') ) + break; + p += dir; p += dir; + while ( !(*p == '*' && p[dir] == '/') ) + { if ( *p == 0 ) + return p; /* multi-line comment?? */ + p += dir; + } + p += dir; p += dir; + } + return p; +} + +/* + * Write blanks over part of a string. + * Don't overwrite end-of-line characters. + */ +int +writeblanks(start, end) + char *start; + char *end; +{ char *p; + for ( p = start; p < end; p++ ) + if ( *p != '\r' && *p != '\n' ) + *p = ' '; + return 0; +} + +/* + * Test whether the string in buf is a function definition. + * The string may contain and/or end with a newline. + * Return as follows: + * 0 - definitely not a function definition; + * 1 - definitely a function definition; + * 2 - definitely a function prototype (NOT USED); + * -1 - may be the beginning of a function definition, + * append another line and look again. + * The reason we don't attempt to convert function prototypes is that + * Ghostscript's declaration-generating macros look too much like + * prototypes, and confuse the algorithms. + */ +int +test1(buf) + char *buf; +{ register char *p = buf; + char *bend; + char *endfn; + int contin; + + if ( !isidfirstchar(*p) ) + return 0; /* no name at left margin */ + bend = skipspace(buf + strlen(buf) - 1, -1); + switch ( *bend ) + { + case ';': contin = 0 /*2*/; break; + case ')': contin = 1; break; + case '{': return 0; /* not a function */ + case '}': return 0; /* not a function */ + default: contin = -1; + } + while ( isidchar(*p) ) + p++; + endfn = p; + p = skipspace(p, 1); + if ( *p++ != '(' ) + return 0; /* not a function */ + p = skipspace(p, 1); + if ( *p == ')' ) + return 0; /* no parameters */ + /* Check that the apparent function name isn't a keyword. */ + /* We only need to check for keywords that could be followed */ + /* by a left parenthesis (which, unfortunately, is most of them). */ + { static char *words[] = + { "asm", "auto", "case", "char", "const", "double", + "extern", "float", "for", "if", "int", "long", + "register", "return", "short", "signed", "sizeof", + "static", "switch", "typedef", "unsigned", + "void", "volatile", "while", 0 + }; + char **key = words; + char *kp; + int len = endfn - buf; + + while ( (kp = *key) != 0 ) + { if ( strlen(kp) == len && !strncmp(kp, buf, len) ) + return 0; /* name is a keyword */ + key++; + } + } + return contin; +} + +/* Convert a recognized function definition or header to K&R syntax. */ +int +convert1(buf, out, header, convert_varargs) + char *buf; + FILE *out; + int header; /* Boolean */ + int convert_varargs; /* Boolean */ +{ char *endfn; + register char *p; + char **breaks; + unsigned num_breaks = 2; /* for testing */ + char **btop; + char **bp; + char **ap; + char *vararg = 0; + + /* Pre-ANSI implementations don't agree on whether strchr */ + /* is called strchr or index, so we open-code it here. */ + for ( endfn = buf; *(endfn++) != '('; ) + ; +top: p = endfn; + breaks = (char **)malloc(sizeof(char *) * num_breaks * 2); + if ( breaks == 0 ) + { /* Couldn't allocate break table, give up */ + fprintf(stderr, "Unable to allocate break table!\n"); + fputs(buf, out); + return -1; + } + btop = breaks + num_breaks * 2 - 2; + bp = breaks; + /* Parse the argument list */ + do + { int level = 0; + char *lp = NULL; + char *rp; + char *end = NULL; + + if ( bp >= btop ) + { /* Filled up break table. */ + /* Allocate a bigger one and start over. */ + free((char *)breaks); + num_breaks <<= 1; + goto top; + } + *bp++ = p; + /* Find the end of the argument */ + for ( ; end == NULL; p++ ) + { switch(*p) + { + case ',': + if ( !level ) end = p; + break; + case '(': + if ( !level ) lp = p; + level++; + break; + case ')': + if ( --level < 0 ) end = p; + else rp = p; + break; + case '/': + p = skipspace(p, 1) - 1; + break; + default: + ; + } + } + /* Erase any embedded prototype parameters. */ + if ( lp ) + writeblanks(lp + 1, rp); + p--; /* back up over terminator */ + /* Find the name being declared. */ + /* This is complicated because of procedure and */ + /* array modifiers. */ + for ( ; ; ) + { p = skipspace(p - 1, -1); + switch ( *p ) + { + case ']': /* skip array dimension(s) */ + case ')': /* skip procedure args OR name */ + { int level = 1; + while ( level ) + switch ( *--p ) + { + case ']': case ')': level++; break; + case '[': case '(': level--; break; + case '/': p = skipspace(p, -1) + 1; break; + default: ; + } + } + if ( *p == '(' && *skipspace(p + 1, 1) == '*' ) + { /* We found the name being declared */ + while ( !isidfirstchar(*p) ) + p = skipspace(p, 1) + 1; + goto found; + } + break; + default: + goto found; + } + } +found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' ) + { if ( convert_varargs ) + { *bp++ = "va_alist"; + vararg = p-2; + } + else + { p++; + if ( bp == breaks + 1 ) /* sole argument */ + writeblanks(breaks[0], p); + else + writeblanks(bp[-1] - 1, p); + bp--; + } + } + else + { while ( isidchar(*p) ) p--; + *bp++ = p+1; + } + p = end; + } + while ( *p++ == ',' ); + *bp = p; + /* Make a special check for 'void' arglist */ + if ( bp == breaks+2 ) + { p = skipspace(breaks[0], 1); + if ( !strncmp(p, "void", 4) ) + { p = skipspace(p+4, 1); + if ( p == breaks[2] - 1 ) + { bp = breaks; /* yup, pretend arglist is empty */ + writeblanks(breaks[0], p + 1); + } + } + } + /* Put out the function name and left parenthesis. */ + p = buf; + while ( p != endfn ) putc(*p, out), p++; + /* Put out the declaration. */ + if ( header ) + { fputs(");", out); + for ( p = breaks[0]; *p; p++ ) + if ( *p == '\r' || *p == '\n' ) + putc(*p, out); + } + else + { for ( ap = breaks+1; ap < bp; ap += 2 ) + { p = *ap; + while ( isidchar(*p) ) + putc(*p, out), p++; + if ( ap < bp - 1 ) + fputs(", ", out); + } + fputs(") ", out); + /* Put out the argument declarations */ + for ( ap = breaks+2; ap <= bp; ap += 2 ) + (*ap)[-1] = ';'; + if ( vararg != 0 ) + { *vararg = 0; + fputs(breaks[0], out); /* any prior args */ + fputs("va_dcl", out); /* the final arg */ + fputs(bp[0], out); + } + else + fputs(breaks[0], out); + } + free((char *)breaks); + return 0; +} diff --git a/rosapps/lib/libjpeg/cderror.h b/rosapps/lib/libjpeg/cderror.h new file mode 100644 index 00000000000..70435e161c0 --- /dev/null +++ b/rosapps/lib/libjpeg/cderror.h @@ -0,0 +1,132 @@ +/* + * cderror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the cjpeg/djpeg + * applications. These strings are not needed as part of the JPEG library + * proper. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef CDERROR_H +#define CDERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* CDERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */ + +#ifdef BMP_SUPPORTED +JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format") +JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported") +JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length") +JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1") +JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB") +JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported") +JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM") +JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image") +JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image") +JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image") +JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image") +#endif /* BMP_SUPPORTED */ + +#ifdef GIF_SUPPORTED +JMESSAGE(JERR_GIF_BUG, "GIF output got confused") +JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d") +JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB") +JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file") +JMESSAGE(JERR_GIF_NOT, "Not a GIF file") +JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image") +JMESSAGE(JTRC_GIF_BADVERSION, + "Warning: unexpected GIF version number '%c%c%c'") +JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x") +JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input") +JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file") +JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring") +JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image") +JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits") +#endif /* GIF_SUPPORTED */ + +#ifdef PPM_SUPPORTED +JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB") +JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file") +JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file") +JMESSAGE(JTRC_PGM, "%ux%u PGM image") +JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image") +JMESSAGE(JTRC_PPM, "%ux%u PPM image") +JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image") +#endif /* PPM_SUPPORTED */ + +#ifdef RLE_SUPPORTED +JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library") +JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB") +JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE") +JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file") +JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header") +JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header") +JMESSAGE(JERR_RLE_NOT, "Not an RLE file") +JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE") +JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup") +JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file") +JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d") +JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file") +JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d") +JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d") +#endif /* RLE_SUPPORTED */ + +#ifdef TARGA_SUPPORTED +JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format") +JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file") +JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB") +JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image") +JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image") +JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image") +#else +JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled") +#endif /* TARGA_SUPPORTED */ + +JMESSAGE(JERR_BAD_CMAP_FILE, + "Color map file is invalid or of unsupported format") +JMESSAGE(JERR_TOO_MANY_COLORS, + "Output file format cannot handle %d colormap entries") +JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed") +#ifdef TARGA_SUPPORTED +JMESSAGE(JERR_UNKNOWN_FORMAT, + "Unrecognized input file format --- perhaps you need -targa") +#else +JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format") +#endif +JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTADDONCODE +} ADDON_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE diff --git a/rosapps/lib/libjpeg/cdjpeg.c b/rosapps/lib/libjpeg/cdjpeg.c new file mode 100644 index 00000000000..b6250ff97cb --- /dev/null +++ b/rosapps/lib/libjpeg/cdjpeg.c @@ -0,0 +1,181 @@ +/* + * cdjpeg.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains common support routines used by the IJG application + * programs (cjpeg, djpeg, jpegtran). + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include /* to declare isupper(), tolower() */ +#ifdef NEED_SIGNAL_CATCHER +#include /* to declare signal() */ +#endif +#ifdef USE_SETMODE +#include /* to declare setmode()'s parameter macros */ +/* If you have setmode() but not , just delete this line: */ +#include /* to declare setmode() */ +#endif + + +/* + * Signal catcher to ensure that temporary files are removed before aborting. + * NB: for Amiga Manx C this is actually a global routine named _abort(); + * we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus... + */ + +#ifdef NEED_SIGNAL_CATCHER + +static j_common_ptr sig_cinfo; + +void /* must be global for Manx C */ +signal_catcher (int signum) +{ + if (sig_cinfo != NULL) { + if (sig_cinfo->err != NULL) /* turn off trace output */ + sig_cinfo->err->trace_level = 0; + jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */ + } + exit(EXIT_FAILURE); +} + + +GLOBAL(void) +enable_signal_catcher (j_common_ptr cinfo) +{ + sig_cinfo = cinfo; +#ifdef SIGINT /* not all systems have SIGINT */ + signal(SIGINT, signal_catcher); +#endif +#ifdef SIGTERM /* not all systems have SIGTERM */ + signal(SIGTERM, signal_catcher); +#endif +} + +#endif + + +/* + * Optional progress monitor: display a percent-done figure on stderr. + */ + +#ifdef PROGRESS_REPORT + +METHODDEF(void) +progress_monitor (j_common_ptr cinfo) +{ + cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress; + int total_passes = prog->pub.total_passes + prog->total_extra_passes; + int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit); + + if (percent_done != prog->percent_done) { + prog->percent_done = percent_done; + if (total_passes > 1) { + fprintf(stderr, "\rPass %d/%d: %3d%% ", + prog->pub.completed_passes + prog->completed_extra_passes + 1, + total_passes, percent_done); + } else { + fprintf(stderr, "\r %3d%% ", percent_done); + } + fflush(stderr); + } +} + + +GLOBAL(void) +start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress) +{ + /* Enable progress display, unless trace output is on */ + if (cinfo->err->trace_level == 0) { + progress->pub.progress_monitor = progress_monitor; + progress->completed_extra_passes = 0; + progress->total_extra_passes = 0; + progress->percent_done = -1; + cinfo->progress = &progress->pub; + } +} + + +GLOBAL(void) +end_progress_monitor (j_common_ptr cinfo) +{ + /* Clear away progress display */ + if (cinfo->err->trace_level == 0) { + fprintf(stderr, "\r \r"); + fflush(stderr); + } +} + +#endif + + +/* + * Case-insensitive matching of possibly-abbreviated keyword switches. + * keyword is the constant keyword (must be lower case already), + * minchars is length of minimum legal abbreviation. + */ + +GLOBAL(boolean) +keymatch (char * arg, const char * keyword, int minchars) +{ + register int ca, ck; + register int nmatched = 0; + + while ((ca = *arg++) != '\0') { + if ((ck = *keyword++) == '\0') + return FALSE; /* arg longer than keyword, no good */ + if (isupper(ca)) /* force arg to lcase (assume ck is already) */ + ca = tolower(ca); + if (ca != ck) + return FALSE; /* no good */ + nmatched++; /* count matched characters */ + } + /* reached end of argument; fail if it's too short for unique abbrev */ + if (nmatched < minchars) + return FALSE; + return TRUE; /* A-OK */ +} + + +/* + * Routines to establish binary I/O mode for stdin and stdout. + * Non-Unix systems often require some hacking to get out of text mode. + */ + +GLOBAL(FILE *) +read_stdin (void) +{ + FILE * input_file = stdin; + +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdin), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) { + fprintf(stderr, "Cannot reopen stdin\n"); + exit(EXIT_FAILURE); + } +#endif + return input_file; +} + + +GLOBAL(FILE *) +write_stdout (void) +{ + FILE * output_file = stdout; + +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdout), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { + fprintf(stderr, "Cannot reopen stdout\n"); + exit(EXIT_FAILURE); + } +#endif + return output_file; +} diff --git a/rosapps/lib/libjpeg/cdjpeg.h b/rosapps/lib/libjpeg/cdjpeg.h new file mode 100644 index 00000000000..2b387b6e5fa --- /dev/null +++ b/rosapps/lib/libjpeg/cdjpeg.h @@ -0,0 +1,184 @@ +/* + * cdjpeg.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains common declarations for the sample applications + * cjpeg and djpeg. It is NOT used by the core JPEG library. + */ + +#define JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */ +#define JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" /* get library error codes too */ +#include "cderror.h" /* get application-specific error codes */ + + +/* + * Object interface for cjpeg's source file decoding modules + */ + +typedef struct cjpeg_source_struct * cjpeg_source_ptr; + +struct cjpeg_source_struct { + JMETHOD(void, start_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(void, finish_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + + FILE *input_file; + + JSAMPARRAY buffer; + JDIMENSION buffer_height; +}; + + +/* + * Object interface for djpeg's output file encoding modules + */ + +typedef struct djpeg_dest_struct * djpeg_dest_ptr; + +struct djpeg_dest_struct { + /* start_output is called after jpeg_start_decompress finishes. + * The color map will be ready at this time, if one is needed. + */ + JMETHOD(void, start_output, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo)); + /* Emit the specified number of pixel rows from the buffer. */ + JMETHOD(void, put_pixel_rows, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied)); + /* Finish up at the end of the image. */ + JMETHOD(void, finish_output, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo)); + + /* Target file spec; filled in by djpeg.c after object is created. */ + FILE * output_file; + + /* Output pixel-row buffer. Created by module init or start_output. + * Width is cinfo->output_width * cinfo->output_components; + * height is buffer_height. + */ + JSAMPARRAY buffer; + JDIMENSION buffer_height; +}; + + +/* + * cjpeg/djpeg may need to perform extra passes to convert to or from + * the source/destination file format. The JPEG library does not know + * about these passes, but we'd like them to be counted by the progress + * monitor. We use an expanded progress monitor object to hold the + * additional pass count. + */ + +struct cdjpeg_progress_mgr { + struct jpeg_progress_mgr pub; /* fields known to JPEG library */ + int completed_extra_passes; /* extra passes completed */ + int total_extra_passes; /* total extra */ + /* last printed percentage stored here to avoid multiple printouts */ + int percent_done; +}; + +typedef struct cdjpeg_progress_mgr * cd_progress_ptr; + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_read_bmp jIRdBMP +#define jinit_write_bmp jIWrBMP +#define jinit_read_gif jIRdGIF +#define jinit_write_gif jIWrGIF +#define jinit_read_ppm jIRdPPM +#define jinit_write_ppm jIWrPPM +#define jinit_read_rle jIRdRLE +#define jinit_write_rle jIWrRLE +#define jinit_read_targa jIRdTarga +#define jinit_write_targa jIWrTarga +#define read_quant_tables RdQTables +#define read_scan_script RdScnScript +#define set_quant_slots SetQSlots +#define set_sample_factors SetSFacts +#define read_color_map RdCMap +#define enable_signal_catcher EnSigCatcher +#define start_progress_monitor StProgMon +#define end_progress_monitor EnProgMon +#define read_stdin RdStdin +#define write_stdout WrStdout +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Module selection routines for I/O modules. */ + +EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo, + boolean is_os2)); +EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_targa JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo)); + +/* cjpeg support routines (in rdswitch.c) */ + +EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename, + int scale_factor, boolean force_baseline)); +EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename)); +EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg)); +EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg)); + +/* djpeg support routines (in rdcolmap.c) */ + +EXTERN(void) read_color_map JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* common support routines (in cdjpeg.c) */ + +EXTERN(void) enable_signal_catcher JPP((j_common_ptr cinfo)); +EXTERN(void) start_progress_monitor JPP((j_common_ptr cinfo, + cd_progress_ptr progress)); +EXTERN(void) end_progress_monitor JPP((j_common_ptr cinfo)); +EXTERN(boolean) keymatch JPP((char * arg, const char * keyword, int minchars)); +EXTERN(FILE *) read_stdin JPP((void)); +EXTERN(FILE *) write_stdout JPP((void)); + +/* miscellaneous useful macros */ + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define WRITE_BINARY "w" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define WRITE_BINARY "wb", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#define WRITE_BINARY "wb" +#endif +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#ifdef VMS +#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ +#else +#define EXIT_SUCCESS 0 +#endif +#endif +#ifndef EXIT_WARNING +#ifdef VMS +#define EXIT_WARNING 1 /* VMS is very nonstandard */ +#else +#define EXIT_WARNING 2 +#endif +#endif diff --git a/rosapps/lib/libjpeg/change.log b/rosapps/lib/libjpeg/change.log new file mode 100644 index 00000000000..74102c0db5a --- /dev/null +++ b/rosapps/lib/libjpeg/change.log @@ -0,0 +1,217 @@ +CHANGE LOG for Independent JPEG Group's JPEG software + + +Version 6b 27-Mar-1998 +----------------------- + +jpegtran has new features for lossless image transformations (rotation +and flipping) as well as "lossless" reduction to grayscale. + +jpegtran now copies comments by default; it has a -copy switch to enable +copying all APPn blocks as well, or to suppress comments. (Formerly it +always suppressed comments and APPn blocks.) jpegtran now also preserves +JFIF version and resolution information. + +New decompressor library feature: COM and APPn markers found in the input +file can be saved in memory for later use by the application. (Before, +you had to code this up yourself with a custom marker processor.) + +There is an unused field "void * client_data" now in compress and decompress +parameter structs; this may be useful in some applications. + +JFIF version number information is now saved by the decoder and accepted by +the encoder. jpegtran uses this to copy the source file's version number, +to ensure "jpegtran -copy all" won't create bogus files that contain JFXX +extensions but claim to be version 1.01. Applications that generate their +own JFXX extension markers also (finally) have a supported way to cause the +encoder to emit JFIF version number 1.02. + +djpeg's trace mode reports JFIF 1.02 thumbnail images as such, rather +than as unknown APP0 markers. + +In -verbose mode, djpeg and rdjpgcom will try to print the contents of +APP12 markers as text. Some digital cameras store useful text information +in APP12 markers. + +Handling of truncated data streams is more robust: blocks beyond the one in +which the error occurs will be output as uniform gray, or left unchanged +if decoding a progressive JPEG. The appearance no longer depends on the +Huffman tables being used. + +Huffman tables are checked for validity much more carefully than before. + +To avoid the Unisys LZW patent, djpeg's GIF output capability has been +changed to produce "uncompressed GIFs", and cjpeg's GIF input capability +has been removed altogether. We're not happy about it either, but there +seems to be no good alternative. + +The configure script now supports building libjpeg as a shared library +on many flavors of Unix (all the ones that GNU libtool knows how to +build shared libraries for). Use "./configure --enable-shared" to +try this out. + +New jconfig file and makefiles for Microsoft Visual C++ and Developer Studio. +Also, a jconfig file and a build script for Metrowerks CodeWarrior +on Apple Macintosh. makefile.dj has been updated for DJGPP v2, and there +are miscellaneous other minor improvements in the makefiles. + +jmemmac.c now knows how to create temporary files following Mac System 7 +conventions. + +djpeg's -map switch is now able to read raw-format PPM files reliably. + +cjpeg -progressive -restart no longer generates any unnecessary DRI markers. + +Multiple calls to jpeg_simple_progression for a single JPEG object +no longer leak memory. + + +Version 6a 7-Feb-96 +-------------------- + +Library initialization sequence modified to detect version mismatches +and struct field packing mismatches between library and calling application. +This change requires applications to be recompiled, but does not require +any application source code change. + +All routine declarations changed to the style "GLOBAL(type) name ...", +that is, GLOBAL, LOCAL, METHODDEF, EXTERN are now macros taking the +routine's return type as an argument. This makes it possible to add +Microsoft-style linkage keywords to all the routines by changing just +these macros. Note that any application code that was using these macros +will have to be changed. + +DCT coefficient quantization tables are now stored in normal array order +rather than zigzag order. Application code that calls jpeg_add_quant_table, +or otherwise manipulates quantization tables directly, will need to be +changed. If you need to make such code work with either older or newer +versions of the library, a test like "#if JPEG_LIB_VERSION >= 61" is +recommended. + +djpeg's trace capability now dumps DQT tables in natural order, not zigzag +order. This allows the trace output to be made into a "-qtables" file +more easily. + +New system-dependent memory manager module for use on Apple Macintosh. + +Fix bug in cjpeg's -smooth option: last one or two scanlines would be +duplicates of the prior line unless the image height mod 16 was 1 or 2. + +Repair minor problems in VMS, BCC, MC6 makefiles. + +New configure script based on latest GNU Autoconf. + +Correct the list of include files needed by MetroWerks C for ccommand(). + +Numerous small documentation updates. + + +Version 6 2-Aug-95 +------------------- + +Progressive JPEG support: library can read and write full progressive JPEG +files. A "buffered image" mode supports incremental decoding for on-the-fly +display of progressive images. Simply recompiling an existing IJG-v5-based +decoder with v6 should allow it to read progressive files, though of course +without any special progressive display. + +New "jpegtran" application performs lossless transcoding between different +JPEG formats; primarily, it can be used to convert baseline to progressive +JPEG and vice versa. In support of jpegtran, the library now allows lossless +reading and writing of JPEG files as DCT coefficient arrays. This ability +may be of use in other applications. + +Notes for programmers: +* We changed jpeg_start_decompress() to be able to suspend; this makes all +decoding modes available to suspending-input applications. However, +existing applications that use suspending input will need to be changed +to check the return value from jpeg_start_decompress(). You don't need to +do anything if you don't use a suspending data source. +* We changed the interface to the virtual array routines: access_virt_array +routines now take a count of the number of rows to access this time. The +last parameter to request_virt_array routines is now interpreted as the +maximum number of rows that may be accessed at once, but not necessarily +the height of every access. + + +Version 5b 15-Mar-95 +--------------------- + +Correct bugs with grayscale images having v_samp_factor > 1. + +jpeg_write_raw_data() now supports output suspension. + +Correct bugs in "configure" script for case of compiling in +a directory other than the one containing the source files. + +Repair bug in jquant1.c: sometimes didn't use as many colors as it could. + +Borland C makefile and jconfig file work under either MS-DOS or OS/2. + +Miscellaneous improvements to documentation. + + +Version 5a 7-Dec-94 +-------------------- + +Changed color conversion roundoff behavior so that grayscale values are +represented exactly. (This causes test image files to change.) + +Make ordered dither use 16x16 instead of 4x4 pattern for a small quality +improvement. + +New configure script based on latest GNU Autoconf. +Fix configure script to handle CFLAGS correctly. +Rename *.auto files to *.cfg, so that configure script still works if +file names have been truncated for DOS. + +Fix bug in rdbmp.c: didn't allow for extra data between header and image. + +Modify rdppm.c/wrppm.c to handle 2-byte raw PPM/PGM formats for 12-bit data. + +Fix several bugs in rdrle.c. + +NEED_SHORT_EXTERNAL_NAMES option was broken. + +Revise jerror.h/jerror.c for more flexibility in message table. + +Repair oversight in jmemname.c NO_MKTEMP case: file could be there +but unreadable. + + +Version 5 24-Sep-94 +-------------------- + +Version 5 represents a nearly complete redesign and rewrite of the IJG +software. Major user-visible changes include: + * Automatic configuration simplifies installation for most Unix systems. + * A range of speed vs. image quality tradeoffs are supported. + This includes resizing of an image during decompression: scaling down + by a factor of 1/2, 1/4, or 1/8 is handled very efficiently. + * New programs rdjpgcom and wrjpgcom allow insertion and extraction + of text comments in a JPEG file. + +The application programmer's interface to the library has changed completely. +Notable improvements include: + * We have eliminated the use of callback routines for handling the + uncompressed image data. The application now sees the library as a + set of routines that it calls to read or write image data on a + scanline-by-scanline basis. + * The application image data is represented in a conventional interleaved- + pixel format, rather than as a separate array for each color channel. + This can save a copying step in many programs. + * The handling of compressed data has been cleaned up: the application can + supply routines to source or sink the compressed data. It is possible to + suspend processing on source/sink buffer overrun, although this is not + supported in all operating modes. + * All static state has been eliminated from the library, so that multiple + instances of compression or decompression can be active concurrently. + * JPEG abbreviated datastream formats are supported, ie, quantization and + Huffman tables can be stored separately from the image data. + * And not only that, but the documentation of the library has improved + considerably! + + +The last widely used release before the version 5 rewrite was version 4A of +18-Feb-93. Change logs before that point have been discarded, since they +are not of much interest after the rewrite. diff --git a/rosapps/lib/libjpeg/cjpeg.c b/rosapps/lib/libjpeg/cjpeg.c new file mode 100644 index 00000000000..f2a929f0c9f --- /dev/null +++ b/rosapps/lib/libjpeg/cjpeg.c @@ -0,0 +1,606 @@ +/* + * cjpeg.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a command-line user interface for the JPEG compressor. + * It should work on any system with Unix- or MS-DOS-style command lines. + * + * Two different command line styles are permitted, depending on the + * compile-time switch TWO_FILE_COMMANDLINE: + * cjpeg [options] inputfile outputfile + * cjpeg [options] [inputfile] + * In the second style, output is always to standard output, which you'd + * normally redirect to a file or pipe to some other program. Input is + * either from a named file or from standard input (typically redirected). + * The second style is convenient on Unix but is unhelpful on systems that + * don't support pipes. Also, you MUST use the first style if your system + * doesn't do binary I/O to stdin/stdout. + * To simplify script writing, the "-outfile" switch is provided. The syntax + * cjpeg [options] -outfile outputfile inputfile + * works regardless of which command line style is used. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "jversion.h" /* for version message */ + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + + +/* Create the add-on message string table. */ + +#define JMESSAGE(code,string) string , + +static const char * const cdjpeg_message_table[] = { +#include "cderror.h" + NULL +}; + + +/* + * This routine determines what format the input file is, + * and selects the appropriate input-reading module. + * + * To determine which family of input formats the file belongs to, + * we may look only at the first byte of the file, since C does not + * guarantee that more than one character can be pushed back with ungetc. + * Looking at additional bytes would require one of these approaches: + * 1) assume we can fseek() the input file (fails for piped input); + * 2) assume we can push back more than one character (works in + * some C implementations, but unportable); + * 3) provide our own buffering (breaks input readers that want to use + * stdio directly, such as the RLE library); + * or 4) don't put back the data, and modify the input_init methods to assume + * they start reading after the start of file (also breaks RLE library). + * #1 is attractive for MS-DOS but is untenable on Unix. + * + * The most portable solution for file types that can't be identified by their + * first byte is to make the user tell us what they are. This is also the + * only approach for "raw" file types that contain only arbitrary values. + * We presently apply this method for Targa files. Most of the time Targa + * files start with 0x00, so we recognize that case. Potentially, however, + * a Targa file could start with any byte value (byte 0 is the length of the + * seldom-used ID field), so we provide a switch to force Targa input mode. + */ + +static boolean is_targa; /* records user -targa switch */ + + +LOCAL(cjpeg_source_ptr) +select_file_type (j_compress_ptr cinfo, FILE * infile) +{ + int c; + + if (is_targa) { +#ifdef TARGA_SUPPORTED + return jinit_read_targa(cinfo); +#else + ERREXIT(cinfo, JERR_TGA_NOTCOMP); +#endif + } + + if ((c = getc(infile)) == EOF) + ERREXIT(cinfo, JERR_INPUT_EMPTY); + if (ungetc(c, infile) == EOF) + ERREXIT(cinfo, JERR_UNGETC_FAILED); + + switch (c) { +#ifdef BMP_SUPPORTED + case 'B': + return jinit_read_bmp(cinfo); +#endif +#ifdef GIF_SUPPORTED + case 'G': + return jinit_read_gif(cinfo); +#endif +#ifdef PPM_SUPPORTED + case 'P': + return jinit_read_ppm(cinfo); +#endif +#ifdef RLE_SUPPORTED + case 'R': + return jinit_read_rle(cinfo); +#endif +#ifdef TARGA_SUPPORTED + case 0x00: + return jinit_read_targa(cinfo); +#endif + default: + ERREXIT(cinfo, JERR_UNKNOWN_FORMAT); + break; + } + + return NULL; /* suppress compiler warnings */ +} + + +/* + * Argument-parsing code. + * The switch parser is designed to be useful with DOS-style command line + * syntax, ie, intermixed switches and file names, where only the switches + * to the left of a given file name affect processing of that file. + * The main program in this file doesn't actually use this capability... + */ + + +static const char * progname; /* program name for error messages */ +static char * outfilename; /* for -outfile switch */ + + +LOCAL(void) +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -quality N Compression quality (0..100; 5-95 is useful range)\n"); + fprintf(stderr, " -grayscale Create monochrome JPEG file\n"); +#ifdef ENTROPY_OPT_SUPPORTED + fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); +#endif +#ifdef C_PROGRESSIVE_SUPPORTED + fprintf(stderr, " -progressive Create progressive JPEG file\n"); +#endif +#ifdef TARGA_SUPPORTED + fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n"); +#endif + fprintf(stderr, "Switches for advanced users:\n"); +#ifdef DCT_ISLOW_SUPPORTED + fprintf(stderr, " -dct int Use integer DCT method%s\n", + (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); +#endif +#ifdef DCT_IFAST_SUPPORTED + fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", + (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); +#endif +#ifdef DCT_FLOAT_SUPPORTED + fprintf(stderr, " -dct float Use floating-point DCT method%s\n", + (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); +#endif + fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); +#ifdef INPUT_SMOOTHING_SUPPORTED + fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n"); +#endif + fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); + fprintf(stderr, " -outfile name Specify name for output file\n"); + fprintf(stderr, " -verbose or -debug Emit debug output\n"); + fprintf(stderr, "Switches for wizards:\n"); +#ifdef C_ARITH_CODING_SUPPORTED + fprintf(stderr, " -arithmetic Use arithmetic coding\n"); +#endif + fprintf(stderr, " -baseline Force baseline quantization tables\n"); + fprintf(stderr, " -qtables file Use quantization tables given in file\n"); + fprintf(stderr, " -qslots N[,...] Set component quantization tables\n"); + fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n"); +#ifdef C_MULTISCAN_FILES_SUPPORTED + fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); +#endif + exit(EXIT_FAILURE); +} + + +LOCAL(int) +parse_switches (j_compress_ptr cinfo, int argc, char **argv, + int last_file_arg_seen, boolean for_real) +/* Parse optional switches. + * Returns argv[] index of first file-name argument (== argc if none). + * Any file names with indexes <= last_file_arg_seen are ignored; + * they have presumably been processed in a previous iteration. + * (Pass 0 for last_file_arg_seen on the first or only iteration.) + * for_real is FALSE on the first (dummy) pass; we may skip any expensive + * processing. + */ +{ + int argn; + char * arg; + int quality; /* -quality parameter */ + int q_scale_factor; /* scaling percentage for -qtables */ + boolean force_baseline; + boolean simple_progressive; + char * qtablefile = NULL; /* saves -qtables filename if any */ + char * qslotsarg = NULL; /* saves -qslots parm if any */ + char * samplearg = NULL; /* saves -sample parm if any */ + char * scansarg = NULL; /* saves -scans parm if any */ + + /* Set up default JPEG parameters. */ + /* Note that default -quality level need not, and does not, + * match the default scaling for an explicit -qtables argument. + */ + quality = 75; /* default -quality value */ + q_scale_factor = 100; /* default to no scaling for -qtables */ + force_baseline = FALSE; /* by default, allow 16-bit quantizers */ + simple_progressive = FALSE; + is_targa = FALSE; + outfilename = NULL; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ + + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (*arg != '-') { + /* Not a switch, must be a file name argument */ + if (argn <= last_file_arg_seen) { + outfilename = NULL; /* -outfile applies to just one input file */ + continue; /* ignore this name if previously processed */ + } + break; /* else done parsing switches */ + } + arg++; /* advance past switch marker character */ + + if (keymatch(arg, "arithmetic", 1)) { + /* Use arithmetic coding. */ +#ifdef C_ARITH_CODING_SUPPORTED + cinfo->arith_code = TRUE; +#else + fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "baseline", 1)) { + /* Force baseline-compatible output (8-bit quantizer values). */ + force_baseline = TRUE; + + } else if (keymatch(arg, "dct", 2)) { + /* Select DCT algorithm. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "int", 1)) { + cinfo->dct_method = JDCT_ISLOW; + } else if (keymatch(argv[argn], "fast", 2)) { + cinfo->dct_method = JDCT_IFAST; + } else if (keymatch(argv[argn], "float", 2)) { + cinfo->dct_method = JDCT_FLOAT; + } else + usage(); + + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ + static boolean printed_version = FALSE; + + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n", + JVERSION, JCOPYRIGHT); + printed_version = TRUE; + } + cinfo->err->trace_level++; + + } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { + /* Force a monochrome JPEG file to be generated. */ + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + + } else if (keymatch(arg, "maxmemory", 3)) { + /* Maximum memory in Kb (or Mb with 'm'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (ch == 'm' || ch == 'M') + lval *= 1000L; + cinfo->mem->max_memory_to_use = lval * 1000L; + + } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { + /* Enable entropy parm optimization. */ +#ifdef ENTROPY_OPT_SUPPORTED + cinfo->optimize_coding = TRUE; +#else + fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "outfile", 4)) { + /* Set output file name. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + outfilename = argv[argn]; /* save it away for later use */ + + } else if (keymatch(arg, "progressive", 1)) { + /* Select simple progressive mode. */ +#ifdef C_PROGRESSIVE_SUPPORTED + simple_progressive = TRUE; + /* We must postpone execution until num_components is known. */ +#else + fprintf(stderr, "%s: sorry, progressive output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "quality", 1)) { + /* Quality factor (quantization table scaling factor). */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d", &quality) != 1) + usage(); + /* Change scale factor in case -qtables is present. */ + q_scale_factor = jpeg_quality_scaling(quality); + + } else if (keymatch(arg, "qslots", 2)) { + /* Quantization table slot numbers. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + qslotsarg = argv[argn]; + /* Must delay setting qslots until after we have processed any + * colorspace-determining switches, since jpeg_set_colorspace sets + * default quant table numbers. + */ + + } else if (keymatch(arg, "qtables", 2)) { + /* Quantization tables fetched from file. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + qtablefile = argv[argn]; + /* We postpone actually reading the file in case -quality comes later. */ + + } else if (keymatch(arg, "restart", 1)) { + /* Restart interval in MCU rows (or in MCUs with 'b'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (lval < 0 || lval > 65535L) + usage(); + if (ch == 'b' || ch == 'B') { + cinfo->restart_interval = (unsigned int) lval; + cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ + } else { + cinfo->restart_in_rows = (int) lval; + /* restart_interval will be computed during startup */ + } + + } else if (keymatch(arg, "sample", 2)) { + /* Set sampling factors. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + samplearg = argv[argn]; + /* Must delay setting sample factors until after we have processed any + * colorspace-determining switches, since jpeg_set_colorspace sets + * default sampling factors. + */ + + } else if (keymatch(arg, "scans", 2)) { + /* Set scan script. */ +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (++argn >= argc) /* advance to next argument */ + usage(); + scansarg = argv[argn]; + /* We must postpone reading the file in case -progressive appears. */ +#else + fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "smooth", 2)) { + /* Set input smoothing factor. */ + int val; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d", &val) != 1) + usage(); + if (val < 0 || val > 100) + usage(); + cinfo->smoothing_factor = val; + + } else if (keymatch(arg, "targa", 1)) { + /* Input file is Targa format. */ + is_targa = TRUE; + + } else { + usage(); /* bogus switch */ + } + } + + /* Post-switch-scanning cleanup */ + + if (for_real) { + + /* Set quantization tables for selected quality. */ + /* Some or all may be overridden if -qtables is present. */ + jpeg_set_quality(cinfo, quality, force_baseline); + + if (qtablefile != NULL) /* process -qtables if it was present */ + if (! read_quant_tables(cinfo, qtablefile, + q_scale_factor, force_baseline)) + usage(); + + if (qslotsarg != NULL) /* process -qslots if it was present */ + if (! set_quant_slots(cinfo, qslotsarg)) + usage(); + + if (samplearg != NULL) /* process -sample if it was present */ + if (! set_sample_factors(cinfo, samplearg)) + usage(); + +#ifdef C_PROGRESSIVE_SUPPORTED + if (simple_progressive) /* process -progressive; -scans can override */ + jpeg_simple_progression(cinfo); +#endif + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (scansarg != NULL) /* process -scans if it was present */ + if (! read_scan_script(cinfo, scansarg)) + usage(); +#endif + } + + return argn; /* return index of next arg (file name) */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; +#ifdef PROGRESS_REPORT + struct cdjpeg_progress_mgr progress; +#endif + int file_index; + cjpeg_source_ptr src_mgr; + FILE * input_file; + FILE * output_file; + JDIMENSION num_scanlines; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "cjpeg"; /* in case C library doesn't provide it */ + + /* Initialize the JPEG compression object with default error handling. */ + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + /* Add some application-specific error messages (from cderror.h) */ + jerr.addon_message_table = cdjpeg_message_table; + jerr.first_addon_message = JMSG_FIRSTADDONCODE; + jerr.last_addon_message = JMSG_LASTADDONCODE; + + /* Now safe to enable signal catcher. */ +#ifdef NEED_SIGNAL_CATCHER + enable_signal_catcher((j_common_ptr) &cinfo); +#endif + + /* Initialize JPEG parameters. + * Much of this may be overridden later. + * In particular, we don't yet know the input file's color space, + * but we need to provide some value for jpeg_set_defaults() to work. + */ + + cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ + jpeg_set_defaults(&cinfo); + + /* Scan command line to find file names. + * It is convenient to use just one switch-parsing routine, but the switch + * values read here are ignored; we will rescan the switches after opening + * the input file. + */ + + file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); + +#ifdef TWO_FILE_COMMANDLINE + /* Must have either -outfile switch or explicit output file name */ + if (outfilename == NULL) { + if (file_index != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + outfilename = argv[file_index+1]; + } else { + if (file_index != argc-1) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + } +#else + /* Unix style: expect zero or one file name */ + if (file_index < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } +#endif /* TWO_FILE_COMMANDLINE */ + + /* Open the input file. */ + if (file_index < argc) { + if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ + input_file = read_stdin(); + } + + /* Open the output file. */ + if (outfilename != NULL) { + if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, outfilename); + exit(EXIT_FAILURE); + } + } else { + /* default output file is stdout */ + output_file = write_stdout(); + } + +#ifdef PROGRESS_REPORT + start_progress_monitor((j_common_ptr) &cinfo, &progress); +#endif + + /* Figure out the input file format, and set up to read it. */ + src_mgr = select_file_type(&cinfo, input_file); + src_mgr->input_file = input_file; + + /* Read the input file header to obtain file size & colorspace. */ + (*src_mgr->start_input) (&cinfo, src_mgr); + + /* Now that we know input colorspace, fix colorspace-dependent defaults */ + jpeg_default_colorspace(&cinfo); + + /* Adjust default compression parameters by re-parsing the options */ + file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); + + /* Specify data destination for compression */ + jpeg_stdio_dest(&cinfo, output_file); + + /* Start compressor */ + jpeg_start_compress(&cinfo, TRUE); + + /* Process data */ + while (cinfo.next_scanline < cinfo.image_height) { + num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); + (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); + } + + /* Finish compression and release memory */ + (*src_mgr->finish_input) (&cinfo, src_mgr); + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + /* Close files, if we opened them */ + if (input_file != stdin) + fclose(input_file); + if (output_file != stdout) + fclose(output_file); + +#ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &cinfo); +#endif + + /* All done. */ + exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/rosapps/lib/libjpeg/ckconfig.c b/rosapps/lib/libjpeg/ckconfig.c new file mode 100644 index 00000000000..34baf795b00 --- /dev/null +++ b/rosapps/lib/libjpeg/ckconfig.c @@ -0,0 +1,402 @@ +/* + * ckconfig.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + */ + +/* + * This program is intended to help you determine how to configure the JPEG + * software for installation on a particular system. The idea is to try to + * compile and execute this program. If your compiler fails to compile the + * program, make changes as indicated in the comments below. Once you can + * compile the program, run it, and it will produce a "jconfig.h" file for + * your system. + * + * As a general rule, each time you try to compile this program, + * pay attention only to the *first* error message you get from the compiler. + * Many C compilers will issue lots of spurious error messages once they + * have gotten confused. Go to the line indicated in the first error message, + * and read the comments preceding that line to see what to change. + * + * Almost all of the edits you may need to make to this program consist of + * changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL", + * or vice versa. This is called defining or undefining that symbol. + */ + + +/* First we must see if your system has the include files we need. + * We start out with the assumption that your system has all the ANSI-standard + * include files. If you get any error trying to include one of these files, + * undefine the corresponding HAVE_xxx symbol. + */ + +#define HAVE_STDDEF_H /* replace 'define' by 'undef' if error here */ +#ifdef HAVE_STDDEF_H /* next line will be skipped if you undef... */ +#include +#endif + +#define HAVE_STDLIB_H /* same thing for stdlib.h */ +#ifdef HAVE_STDLIB_H +#include +#endif + +#include /* If you ain't got this, you ain't got C. */ + +/* We have to see if your string functions are defined by + * strings.h (old BSD convention) or string.h (everybody else). + * We try the non-BSD convention first; define NEED_BSD_STRINGS + * if the compiler says it can't find string.h. + */ + +#undef NEED_BSD_STRINGS + +#ifdef NEED_BSD_STRINGS +#include +#else +#include +#endif + +/* On some systems (especially older Unix machines), type size_t is + * defined only in the include file . If you get a failure + * on the size_t test below, try defining NEED_SYS_TYPES_H. + */ + +#undef NEED_SYS_TYPES_H /* start by assuming we don't need it */ +#ifdef NEED_SYS_TYPES_H +#include +#endif + + +/* Usually type size_t is defined in one of the include files we've included + * above. If not, you'll get an error on the "typedef size_t my_size_t;" line. + * In that case, first try defining NEED_SYS_TYPES_H just above. + * If that doesn't work, you'll have to search through your system library + * to figure out which include file defines "size_t". Look for a line that + * says "typedef something-or-other size_t;". Then, change the line below + * that says "#include " to instead include the file + * you found size_t in, and define NEED_SPECIAL_INCLUDE. If you can't find + * type size_t anywhere, try replacing "#include " with + * "typedef unsigned int size_t;". + */ + +#undef NEED_SPECIAL_INCLUDE /* assume we DON'T need it, for starters */ + +#ifdef NEED_SPECIAL_INCLUDE +#include +#endif + +typedef size_t my_size_t; /* The payoff: do we have size_t now? */ + + +/* The next question is whether your compiler supports ANSI-style function + * prototypes. You need to know this in order to choose between using + * makefile.ansi and using makefile.unix. + * The #define line below is set to assume you have ANSI function prototypes. + * If you get an error in this group of lines, undefine HAVE_PROTOTYPES. + */ + +#define HAVE_PROTOTYPES + +#ifdef HAVE_PROTOTYPES +int testfunction (int arg1, int * arg2); /* check prototypes */ + +struct methods_struct { /* check method-pointer declarations */ + int (*error_exit) (char *msgtext); + int (*trace_message) (char *msgtext); + int (*another_method) (void); +}; + +int testfunction (int arg1, int * arg2) /* check definitions */ +{ + return arg2[arg1]; +} + +int test2function (void) /* check void arg list */ +{ + return 0; +} +#endif + + +/* Now we want to find out if your compiler knows what "unsigned char" means. + * If you get an error on the "unsigned char un_char;" line, + * then undefine HAVE_UNSIGNED_CHAR. + */ + +#define HAVE_UNSIGNED_CHAR + +#ifdef HAVE_UNSIGNED_CHAR +unsigned char un_char; +#endif + + +/* Now we want to find out if your compiler knows what "unsigned short" means. + * If you get an error on the "unsigned short un_short;" line, + * then undefine HAVE_UNSIGNED_SHORT. + */ + +#define HAVE_UNSIGNED_SHORT + +#ifdef HAVE_UNSIGNED_SHORT +unsigned short un_short; +#endif + + +/* Now we want to find out if your compiler understands type "void". + * If you get an error anywhere in here, undefine HAVE_VOID. + */ + +#define HAVE_VOID + +#ifdef HAVE_VOID +/* Caution: a C++ compiler will insist on complete prototypes */ +typedef void * void_ptr; /* check void * */ +#ifdef HAVE_PROTOTYPES /* check ptr to function returning void */ +typedef void (*void_func) (int a, int b); +#else +typedef void (*void_func) (); +#endif + +#ifdef HAVE_PROTOTYPES /* check void function result */ +void test3function (void_ptr arg1, void_func arg2) +#else +void test3function (arg1, arg2) + void_ptr arg1; + void_func arg2; +#endif +{ + char * locptr = (char *) arg1; /* check casting to and from void * */ + arg1 = (void *) locptr; + (*arg2) (1, 2); /* check call of fcn returning void */ +} +#endif + + +/* Now we want to find out if your compiler knows what "const" means. + * If you get an error here, undefine HAVE_CONST. + */ + +#define HAVE_CONST + +#ifdef HAVE_CONST +static const int carray[3] = {1, 2, 3}; + +#ifdef HAVE_PROTOTYPES +int test4function (const int arg1) +#else +int test4function (arg1) + const int arg1; +#endif +{ + return carray[arg1]; +} +#endif + + +/* If you get an error or warning about this structure definition, + * define INCOMPLETE_TYPES_BROKEN. + */ + +#undef INCOMPLETE_TYPES_BROKEN + +#ifndef INCOMPLETE_TYPES_BROKEN +typedef struct undefined_structure * undef_struct_ptr; +#endif + + +/* If you get an error about duplicate names, + * define NEED_SHORT_EXTERNAL_NAMES. + */ + +#undef NEED_SHORT_EXTERNAL_NAMES + +#ifndef NEED_SHORT_EXTERNAL_NAMES + +int possibly_duplicate_function () +{ + return 0; +} + +int possibly_dupli_function () +{ + return 1; +} + +#endif + + + +/************************************************************************ + * OK, that's it. You should not have to change anything beyond this + * point in order to compile and execute this program. (You might get + * some warnings, but you can ignore them.) + * When you run the program, it will make a couple more tests that it + * can do automatically, and then it will create jconfig.h and print out + * any additional suggestions it has. + ************************************************************************ + */ + + +#ifdef HAVE_PROTOTYPES +int is_char_signed (int arg) +#else +int is_char_signed (arg) + int arg; +#endif +{ + if (arg == 189) { /* expected result for unsigned char */ + return 0; /* type char is unsigned */ + } + else if (arg != -67) { /* expected result for signed char */ + printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n"); + printf("I fear the JPEG software will not work at all.\n\n"); + } + return 1; /* assume char is signed otherwise */ +} + + +#ifdef HAVE_PROTOTYPES +int is_shifting_signed (long arg) +#else +int is_shifting_signed (arg) + long arg; +#endif +/* See whether right-shift on a long is signed or not. */ +{ + long res = arg >> 4; + + if (res == -0x7F7E80CL) { /* expected result for signed shift */ + return 1; /* right shift is signed */ + } + /* see if unsigned-shift hack will fix it. */ + /* we can't just test exact value since it depends on width of long... */ + res |= (~0L) << (32-4); + if (res == -0x7F7E80CL) { /* expected result now? */ + return 0; /* right shift is unsigned */ + } + printf("Right shift isn't acting as I expect it to.\n"); + printf("I fear the JPEG software will not work at all.\n\n"); + return 0; /* try it with unsigned anyway */ +} + + +#ifdef HAVE_PROTOTYPES +int main (int argc, char ** argv) +#else +int main (argc, argv) + int argc; + char ** argv; +#endif +{ + char signed_char_check = (char) (-67); + FILE *outfile; + + /* Attempt to write jconfig.h */ + if ((outfile = fopen("jconfig.h", "w")) == NULL) { + printf("Failed to write jconfig.h\n"); + return 1; + } + + /* Write out all the info */ + fprintf(outfile, "/* jconfig.h --- generated by ckconfig.c */\n"); + fprintf(outfile, "/* see jconfig.doc for explanations */\n\n"); +#ifdef HAVE_PROTOTYPES + fprintf(outfile, "#define HAVE_PROTOTYPES\n"); +#else + fprintf(outfile, "#undef HAVE_PROTOTYPES\n"); +#endif +#ifdef HAVE_UNSIGNED_CHAR + fprintf(outfile, "#define HAVE_UNSIGNED_CHAR\n"); +#else + fprintf(outfile, "#undef HAVE_UNSIGNED_CHAR\n"); +#endif +#ifdef HAVE_UNSIGNED_SHORT + fprintf(outfile, "#define HAVE_UNSIGNED_SHORT\n"); +#else + fprintf(outfile, "#undef HAVE_UNSIGNED_SHORT\n"); +#endif +#ifdef HAVE_VOID + fprintf(outfile, "/* #define void char */\n"); +#else + fprintf(outfile, "#define void char\n"); +#endif +#ifdef HAVE_CONST + fprintf(outfile, "/* #define const */\n"); +#else + fprintf(outfile, "#define const\n"); +#endif + if (is_char_signed((int) signed_char_check)) + fprintf(outfile, "#undef CHAR_IS_UNSIGNED\n"); + else + fprintf(outfile, "#define CHAR_IS_UNSIGNED\n"); +#ifdef HAVE_STDDEF_H + fprintf(outfile, "#define HAVE_STDDEF_H\n"); +#else + fprintf(outfile, "#undef HAVE_STDDEF_H\n"); +#endif +#ifdef HAVE_STDLIB_H + fprintf(outfile, "#define HAVE_STDLIB_H\n"); +#else + fprintf(outfile, "#undef HAVE_STDLIB_H\n"); +#endif +#ifdef NEED_BSD_STRINGS + fprintf(outfile, "#define NEED_BSD_STRINGS\n"); +#else + fprintf(outfile, "#undef NEED_BSD_STRINGS\n"); +#endif +#ifdef NEED_SYS_TYPES_H + fprintf(outfile, "#define NEED_SYS_TYPES_H\n"); +#else + fprintf(outfile, "#undef NEED_SYS_TYPES_H\n"); +#endif + fprintf(outfile, "#undef NEED_FAR_POINTERS\n"); +#ifdef NEED_SHORT_EXTERNAL_NAMES + fprintf(outfile, "#define NEED_SHORT_EXTERNAL_NAMES\n"); +#else + fprintf(outfile, "#undef NEED_SHORT_EXTERNAL_NAMES\n"); +#endif +#ifdef INCOMPLETE_TYPES_BROKEN + fprintf(outfile, "#define INCOMPLETE_TYPES_BROKEN\n"); +#else + fprintf(outfile, "#undef INCOMPLETE_TYPES_BROKEN\n"); +#endif + fprintf(outfile, "\n#ifdef JPEG_INTERNALS\n\n"); + if (is_shifting_signed(-0x7F7E80B1L)) + fprintf(outfile, "#undef RIGHT_SHIFT_IS_UNSIGNED\n"); + else + fprintf(outfile, "#define RIGHT_SHIFT_IS_UNSIGNED\n"); + fprintf(outfile, "\n#endif /* JPEG_INTERNALS */\n"); + fprintf(outfile, "\n#ifdef JPEG_CJPEG_DJPEG\n\n"); + fprintf(outfile, "#define BMP_SUPPORTED /* BMP image file format */\n"); + fprintf(outfile, "#define GIF_SUPPORTED /* GIF image file format */\n"); + fprintf(outfile, "#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */\n"); + fprintf(outfile, "#undef RLE_SUPPORTED /* Utah RLE image file format */\n"); + fprintf(outfile, "#define TARGA_SUPPORTED /* Targa image file format */\n\n"); + fprintf(outfile, "#undef TWO_FILE_COMMANDLINE /* You may need this on non-Unix systems */\n"); + fprintf(outfile, "#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */\n"); + fprintf(outfile, "#undef DONT_USE_B_MODE\n"); + fprintf(outfile, "/* #define PROGRESS_REPORT */ /* optional */\n"); + fprintf(outfile, "\n#endif /* JPEG_CJPEG_DJPEG */\n"); + + /* Close the jconfig.h file */ + fclose(outfile); + + /* User report */ + printf("Configuration check for Independent JPEG Group's software done.\n"); + printf("\nI have written the jconfig.h file for you.\n\n"); +#ifdef HAVE_PROTOTYPES + printf("You should use makefile.ansi as the starting point for your Makefile.\n"); +#else + printf("You should use makefile.unix as the starting point for your Makefile.\n"); +#endif + +#ifdef NEED_SPECIAL_INCLUDE + printf("\nYou'll need to change jconfig.h to include the system include file\n"); + printf("that you found type size_t in, or add a direct definition of type\n"); + printf("size_t if that's what you used. Just add it to the end.\n"); +#endif + + return 0; +} diff --git a/rosapps/lib/libjpeg/djpeg.c b/rosapps/lib/libjpeg/djpeg.c new file mode 100644 index 00000000000..e099e90aee3 --- /dev/null +++ b/rosapps/lib/libjpeg/djpeg.c @@ -0,0 +1,616 @@ +/* + * djpeg.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a command-line user interface for the JPEG decompressor. + * It should work on any system with Unix- or MS-DOS-style command lines. + * + * Two different command line styles are permitted, depending on the + * compile-time switch TWO_FILE_COMMANDLINE: + * djpeg [options] inputfile outputfile + * djpeg [options] [inputfile] + * In the second style, output is always to standard output, which you'd + * normally redirect to a file or pipe to some other program. Input is + * either from a named file or from standard input (typically redirected). + * The second style is convenient on Unix but is unhelpful on systems that + * don't support pipes. Also, you MUST use the first style if your system + * doesn't do binary I/O to stdin/stdout. + * To simplify script writing, the "-outfile" switch is provided. The syntax + * djpeg [options] -outfile outputfile inputfile + * works regardless of which command line style is used. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "jversion.h" /* for version message */ + +#include /* to declare isprint() */ + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + + +/* Create the add-on message string table. */ + +#define JMESSAGE(code,string) string , + +static const char * const cdjpeg_message_table[] = { +#include "cderror.h" + NULL +}; + + +/* + * This list defines the known output image formats + * (not all of which need be supported by a given version). + * You can change the default output format by defining DEFAULT_FMT; + * indeed, you had better do so if you undefine PPM_SUPPORTED. + */ + +typedef enum { + FMT_BMP, /* BMP format (Windows flavor) */ + FMT_GIF, /* GIF format */ + FMT_OS2, /* BMP format (OS/2 flavor) */ + FMT_PPM, /* PPM/PGM (PBMPLUS formats) */ + FMT_RLE, /* RLE format */ + FMT_TARGA, /* Targa format */ + FMT_TIFF /* TIFF format */ +} IMAGE_FORMATS; + +#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */ +#define DEFAULT_FMT FMT_PPM +#endif + +static IMAGE_FORMATS requested_fmt; + + +/* + * Argument-parsing code. + * The switch parser is designed to be useful with DOS-style command line + * syntax, ie, intermixed switches and file names, where only the switches + * to the left of a given file name affect processing of that file. + * The main program in this file doesn't actually use this capability... + */ + + +static const char * progname; /* program name for error messages */ +static char * outfilename; /* for -outfile switch */ + + +LOCAL(void) +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); + fprintf(stderr, " -fast Fast, low-quality processing\n"); + fprintf(stderr, " -grayscale Force grayscale output\n"); +#ifdef IDCT_SCALING_SUPPORTED + fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n"); +#endif +#ifdef BMP_SUPPORTED + fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n", + (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); +#endif +#ifdef GIF_SUPPORTED + fprintf(stderr, " -gif Select GIF output format%s\n", + (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); +#endif +#ifdef BMP_SUPPORTED + fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", + (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); +#endif +#ifdef PPM_SUPPORTED + fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n", + (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); +#endif +#ifdef RLE_SUPPORTED + fprintf(stderr, " -rle Select Utah RLE output format%s\n", + (DEFAULT_FMT == FMT_RLE ? " (default)" : "")); +#endif +#ifdef TARGA_SUPPORTED + fprintf(stderr, " -targa Select Targa output format%s\n", + (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); +#endif + fprintf(stderr, "Switches for advanced users:\n"); +#ifdef DCT_ISLOW_SUPPORTED + fprintf(stderr, " -dct int Use integer DCT method%s\n", + (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); +#endif +#ifdef DCT_IFAST_SUPPORTED + fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", + (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); +#endif +#ifdef DCT_FLOAT_SUPPORTED + fprintf(stderr, " -dct float Use floating-point DCT method%s\n", + (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); +#endif + fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); + fprintf(stderr, " -dither none Don't use dithering in quantization\n"); + fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n"); +#ifdef QUANT_2PASS_SUPPORTED + fprintf(stderr, " -map FILE Map to colors used in named image file\n"); +#endif + fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); +#ifdef QUANT_1PASS_SUPPORTED + fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n"); +#endif + fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); + fprintf(stderr, " -outfile name Specify name for output file\n"); + fprintf(stderr, " -verbose or -debug Emit debug output\n"); + exit(EXIT_FAILURE); +} + + +LOCAL(int) +parse_switches (j_decompress_ptr cinfo, int argc, char **argv, + int last_file_arg_seen, boolean for_real) +/* Parse optional switches. + * Returns argv[] index of first file-name argument (== argc if none). + * Any file names with indexes <= last_file_arg_seen are ignored; + * they have presumably been processed in a previous iteration. + * (Pass 0 for last_file_arg_seen on the first or only iteration.) + * for_real is FALSE on the first (dummy) pass; we may skip any expensive + * processing. + */ +{ + int argn; + char * arg; + + /* Set up default JPEG parameters. */ + requested_fmt = DEFAULT_FMT; /* set default output file format */ + outfilename = NULL; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ + + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (*arg != '-') { + /* Not a switch, must be a file name argument */ + if (argn <= last_file_arg_seen) { + outfilename = NULL; /* -outfile applies to just one input file */ + continue; /* ignore this name if previously processed */ + } + break; /* else done parsing switches */ + } + arg++; /* advance past switch marker character */ + + if (keymatch(arg, "bmp", 1)) { + /* BMP output format. */ + requested_fmt = FMT_BMP; + + } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) || + keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) { + /* Do color quantization. */ + int val; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d", &val) != 1) + usage(); + cinfo->desired_number_of_colors = val; + cinfo->quantize_colors = TRUE; + + } else if (keymatch(arg, "dct", 2)) { + /* Select IDCT algorithm. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "int", 1)) { + cinfo->dct_method = JDCT_ISLOW; + } else if (keymatch(argv[argn], "fast", 2)) { + cinfo->dct_method = JDCT_IFAST; + } else if (keymatch(argv[argn], "float", 2)) { + cinfo->dct_method = JDCT_FLOAT; + } else + usage(); + + } else if (keymatch(arg, "dither", 2)) { + /* Select dithering algorithm. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "fs", 2)) { + cinfo->dither_mode = JDITHER_FS; + } else if (keymatch(argv[argn], "none", 2)) { + cinfo->dither_mode = JDITHER_NONE; + } else if (keymatch(argv[argn], "ordered", 2)) { + cinfo->dither_mode = JDITHER_ORDERED; + } else + usage(); + + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ + static boolean printed_version = FALSE; + + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n", + JVERSION, JCOPYRIGHT); + printed_version = TRUE; + } + cinfo->err->trace_level++; + + } else if (keymatch(arg, "fast", 1)) { + /* Select recommended processing options for quick-and-dirty output. */ + cinfo->two_pass_quantize = FALSE; + cinfo->dither_mode = JDITHER_ORDERED; + if (! cinfo->quantize_colors) /* don't override an earlier -colors */ + cinfo->desired_number_of_colors = 216; + cinfo->dct_method = JDCT_FASTEST; + cinfo->do_fancy_upsampling = FALSE; + + } else if (keymatch(arg, "gif", 1)) { + /* GIF output format. */ + requested_fmt = FMT_GIF; + + } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { + /* Force monochrome output. */ + cinfo->out_color_space = JCS_GRAYSCALE; + + } else if (keymatch(arg, "map", 3)) { + /* Quantize to a color map taken from an input file. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (for_real) { /* too expensive to do twice! */ +#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ + FILE * mapfile; + + if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + read_color_map(cinfo, mapfile); + fclose(mapfile); + cinfo->quantize_colors = TRUE; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + + } else if (keymatch(arg, "maxmemory", 3)) { + /* Maximum memory in Kb (or Mb with 'm'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (ch == 'm' || ch == 'M') + lval *= 1000L; + cinfo->mem->max_memory_to_use = lval * 1000L; + + } else if (keymatch(arg, "nosmooth", 3)) { + /* Suppress fancy upsampling */ + cinfo->do_fancy_upsampling = FALSE; + + } else if (keymatch(arg, "onepass", 3)) { + /* Use fast one-pass quantization. */ + cinfo->two_pass_quantize = FALSE; + + } else if (keymatch(arg, "os2", 3)) { + /* BMP output format (OS/2 flavor). */ + requested_fmt = FMT_OS2; + + } else if (keymatch(arg, "outfile", 4)) { + /* Set output file name. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + outfilename = argv[argn]; /* save it away for later use */ + + } else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) { + /* PPM/PGM output format. */ + requested_fmt = FMT_PPM; + + } else if (keymatch(arg, "rle", 1)) { + /* RLE output format. */ + requested_fmt = FMT_RLE; + + } else if (keymatch(arg, "scale", 1)) { + /* Scale the output image by a fraction M/N. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d/%d", + &cinfo->scale_num, &cinfo->scale_denom) != 2) + usage(); + + } else if (keymatch(arg, "targa", 1)) { + /* Targa output format. */ + requested_fmt = FMT_TARGA; + + } else { + usage(); /* bogus switch */ + } + } + + return argn; /* return index of next arg (file name) */ +} + + +/* + * Marker processor for COM and interesting APPn markers. + * This replaces the library's built-in processor, which just skips the marker. + * We want to print out the marker as text, to the extent possible. + * Note this code relies on a non-suspending data source. + */ + +LOCAL(unsigned int) +jpeg_getc (j_decompress_ptr cinfo) +/* Read next byte */ +{ + struct jpeg_source_mgr * datasrc = cinfo->src; + + if (datasrc->bytes_in_buffer == 0) { + if (! (*datasrc->fill_input_buffer) (cinfo)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } + datasrc->bytes_in_buffer--; + return GETJOCTET(*datasrc->next_input_byte++); +} + + +METHODDEF(boolean) +print_text_marker (j_decompress_ptr cinfo) +{ + boolean traceit = (cinfo->err->trace_level >= 1); + INT32 length; + unsigned int ch; + unsigned int lastch = 0; + + length = jpeg_getc(cinfo) << 8; + length += jpeg_getc(cinfo); + length -= 2; /* discount the length word itself */ + + if (traceit) { + if (cinfo->unread_marker == JPEG_COM) + fprintf(stderr, "Comment, length %ld:\n", (long) length); + else /* assume it is an APPn otherwise */ + fprintf(stderr, "APP%d, length %ld:\n", + cinfo->unread_marker - JPEG_APP0, (long) length); + } + + while (--length >= 0) { + ch = jpeg_getc(cinfo); + if (traceit) { + /* Emit the character in a readable form. + * Nonprintables are converted to \nnn form, + * while \ is converted to \\. + * Newlines in CR, CR/LF, or LF form will be printed as one newline. + */ + if (ch == '\r') { + fprintf(stderr, "\n"); + } else if (ch == '\n') { + if (lastch != '\r') + fprintf(stderr, "\n"); + } else if (ch == '\\') { + fprintf(stderr, "\\\\"); + } else if (isprint(ch)) { + putc(ch, stderr); + } else { + fprintf(stderr, "\\%03o", ch); + } + lastch = ch; + } + } + + if (traceit) + fprintf(stderr, "\n"); + + return TRUE; +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; +#ifdef PROGRESS_REPORT + struct cdjpeg_progress_mgr progress; +#endif + int file_index; + djpeg_dest_ptr dest_mgr = NULL; + FILE * input_file; + FILE * output_file; + JDIMENSION num_scanlines; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "djpeg"; /* in case C library doesn't provide it */ + + /* Initialize the JPEG decompression object with default error handling. */ + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + /* Add some application-specific error messages (from cderror.h) */ + jerr.addon_message_table = cdjpeg_message_table; + jerr.first_addon_message = JMSG_FIRSTADDONCODE; + jerr.last_addon_message = JMSG_LASTADDONCODE; + + /* Insert custom marker processor for COM and APP12. + * APP12 is used by some digital camera makers for textual info, + * so we provide the ability to display it as text. + * If you like, additional APPn marker types can be selected for display, + * but don't try to override APP0 or APP14 this way (see libjpeg.doc). + */ + jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); + jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); + + /* Now safe to enable signal catcher. */ +#ifdef NEED_SIGNAL_CATCHER + enable_signal_catcher((j_common_ptr) &cinfo); +#endif + + /* Scan command line to find file names. */ + /* It is convenient to use just one switch-parsing routine, but the switch + * values read here are ignored; we will rescan the switches after opening + * the input file. + * (Exception: tracing level set here controls verbosity for COM markers + * found during jpeg_read_header...) + */ + + file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); + +#ifdef TWO_FILE_COMMANDLINE + /* Must have either -outfile switch or explicit output file name */ + if (outfilename == NULL) { + if (file_index != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + outfilename = argv[file_index+1]; + } else { + if (file_index != argc-1) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + } +#else + /* Unix style: expect zero or one file name */ + if (file_index < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } +#endif /* TWO_FILE_COMMANDLINE */ + + /* Open the input file. */ + if (file_index < argc) { + if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ + input_file = read_stdin(); + } + + /* Open the output file. */ + if (outfilename != NULL) { + if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, outfilename); + exit(EXIT_FAILURE); + } + } else { + /* default output file is stdout */ + output_file = write_stdout(); + } + +#ifdef PROGRESS_REPORT + start_progress_monitor((j_common_ptr) &cinfo, &progress); +#endif + + /* Specify data source for decompression */ + jpeg_stdio_src(&cinfo, input_file); + + /* Read file header, set default decompression parameters */ + (void) jpeg_read_header(&cinfo, TRUE); + + /* Adjust default decompression parameters by re-parsing the options */ + file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); + + /* Initialize the output module now to let it override any crucial + * option settings (for instance, GIF wants to force color quantization). + */ + switch (requested_fmt) { +#ifdef BMP_SUPPORTED + case FMT_BMP: + dest_mgr = jinit_write_bmp(&cinfo, FALSE); + break; + case FMT_OS2: + dest_mgr = jinit_write_bmp(&cinfo, TRUE); + break; +#endif +#ifdef GIF_SUPPORTED + case FMT_GIF: + dest_mgr = jinit_write_gif(&cinfo); + break; +#endif +#ifdef PPM_SUPPORTED + case FMT_PPM: + dest_mgr = jinit_write_ppm(&cinfo); + break; +#endif +#ifdef RLE_SUPPORTED + case FMT_RLE: + dest_mgr = jinit_write_rle(&cinfo); + break; +#endif +#ifdef TARGA_SUPPORTED + case FMT_TARGA: + dest_mgr = jinit_write_targa(&cinfo); + break; +#endif + default: + ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT); + break; + } + dest_mgr->output_file = output_file; + + /* Start decompressor */ + (void) jpeg_start_decompress(&cinfo); + + /* Write output file header */ + (*dest_mgr->start_output) (&cinfo, dest_mgr); + + /* Process data */ + while (cinfo.output_scanline < cinfo.output_height) { + num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, + dest_mgr->buffer_height); + (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); + } + +#ifdef PROGRESS_REPORT + /* Hack: count final pass as done in case finish_output does an extra pass. + * The library won't have updated completed_passes. + */ + progress.pub.completed_passes = progress.pub.total_passes; +#endif + + /* Finish decompression and release memory. + * I must do it in this order because output module has allocated memory + * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory. + */ + (*dest_mgr->finish_output) (&cinfo, dest_mgr); + (void) jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + /* Close files, if we opened them */ + if (input_file != stdin) + fclose(input_file); + if (output_file != stdout) + fclose(output_file); + +#ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &cinfo); +#endif + + /* All done. */ + exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/rosapps/lib/libjpeg/example.c b/rosapps/lib/libjpeg/example.c new file mode 100644 index 00000000000..7fc354f04d9 --- /dev/null +++ b/rosapps/lib/libjpeg/example.c @@ -0,0 +1,433 @@ +/* + * example.c + * + * This file illustrates how to use the IJG code as a subroutine library + * to read or write JPEG image files. You should look at this code in + * conjunction with the documentation file libjpeg.doc. + * + * This code will not do anything useful as-is, but it may be helpful as a + * skeleton for constructing routines that call the JPEG library. + * + * We present these routines in the same coding style used in the JPEG code + * (ANSI function definitions, etc); but you are of course free to code your + * routines in a different style if you prefer. + */ + +#include + +/* + * Include file for users of JPEG library. + * You will need to have included system headers that define at least + * the typedefs FILE and size_t before you can include jpeglib.h. + * (stdio.h is sufficient on ANSI-conforming systems.) + * You may also wish to include "jerror.h". + */ + +#include "jpeglib.h" + +/* + * is used for the optional error recovery mechanism shown in + * the second part of the example. + */ + +#include + + + +/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/ + +/* This half of the example shows how to feed data into the JPEG compressor. + * We present a minimal version that does not worry about refinements such + * as error recovery (the JPEG code will just exit() if it gets an error). + */ + + +/* + * IMAGE DATA FORMATS: + * + * The standard input image format is a rectangular array of pixels, with + * each pixel having the same number of "component" values (color channels). + * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars). + * If you are working with color data, then the color values for each pixel + * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit + * RGB color. + * + * For this example, we'll assume that this data structure matches the way + * our application has stored the image in memory, so we can just pass a + * pointer to our image buffer. In particular, let's say that the image is + * RGB color and is described by: + */ + +extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */ +extern int image_height; /* Number of rows in image */ +extern int image_width; /* Number of columns in image */ + + +/* + * Sample routine for JPEG compression. We assume that the target file name + * and a compression quality factor are passed in. + */ + +GLOBAL(void) +write_JPEG_file (char * filename, int quality) +{ + /* This struct contains the JPEG compression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + * It is possible to have several such structures, representing multiple + * compression/decompression processes, in existence at once. We refer + * to any one struct (and its associated working data) as a "JPEG object". + */ + struct jpeg_compress_struct cinfo; + /* This struct represents a JPEG error handler. It is declared separately + * because applications often want to supply a specialized error handler + * (see the second half of this file for an example). But here we just + * take the easy way out and use the standard error handler, which will + * print a message on stderr and call exit() if compression fails. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct jpeg_error_mgr jerr; + /* More stuff */ + FILE * outfile; /* target file */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + + /* Step 1: allocate and initialize JPEG compression object */ + + /* We have to set up the error handler first, in case the initialization + * step fails. (Unlikely, but it could happen if you are out of memory.) + * This routine fills in the contents of struct jerr, and returns jerr's + * address which we place into the link field in cinfo. + */ + cinfo.err = jpeg_std_error(&jerr); + /* Now we can initialize the JPEG compression object. */ + jpeg_create_compress(&cinfo); + + /* Step 2: specify data destination (eg, a file) */ + /* Note: steps 2 and 3 can be done in either order. */ + + /* Here we use the library-supplied code to send compressed data to a + * stdio stream. You can also write your own code to do something else. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to write binary files. + */ + if ((outfile = fopen(filename, "wb")) == NULL) { + fprintf(stderr, "can't open %s\n", filename); + exit(1); + } + jpeg_stdio_dest(&cinfo, outfile); + + /* Step 3: set parameters for compression */ + + /* First we supply a description of the input image. + * Four fields of the cinfo struct must be filled in: + */ + cinfo.image_width = image_width; /* image width and height, in pixels */ + cinfo.image_height = image_height; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + /* Now use the library's routine to set default compression parameters. + * (You must set at least cinfo.in_color_space before calling this, + * since the defaults depend on the source color space.) + */ + jpeg_set_defaults(&cinfo); + /* Now you can set any non-default parameters you wish to. + * Here we just illustrate the use of quality (quantization table) scaling: + */ + jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); + + /* Step 4: Start compressor */ + + /* TRUE ensures that we will write a complete interchange-JPEG file. + * Pass TRUE unless you are very sure of what you're doing. + */ + jpeg_start_compress(&cinfo, TRUE); + + /* Step 5: while (scan lines remain to be written) */ + /* jpeg_write_scanlines(...); */ + + /* Here we use the library's state variable cinfo.next_scanline as the + * loop counter, so that we don't have to keep track ourselves. + * To keep things simple, we pass one scanline per call; you can pass + * more if you wish, though. + */ + row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */ + + while (cinfo.next_scanline < cinfo.image_height) { + /* jpeg_write_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could pass + * more than one scanline at a time if that's more convenient. + */ + row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + /* Step 6: Finish compression */ + + jpeg_finish_compress(&cinfo); + /* After finish_compress, we can close the output file. */ + fclose(outfile); + + /* Step 7: release JPEG compression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_compress(&cinfo); + + /* And we're done! */ +} + + +/* + * SOME FINE POINTS: + * + * In the above loop, we ignored the return value of jpeg_write_scanlines, + * which is the number of scanlines actually written. We could get away + * with this because we were only relying on the value of cinfo.next_scanline, + * which will be incremented correctly. If you maintain additional loop + * variables then you should be careful to increment them properly. + * Actually, for output to a stdio stream you needn't worry, because + * then jpeg_write_scanlines will write all the lines passed (or else exit + * with a fatal error). Partial writes can only occur if you use a data + * destination module that can demand suspension of the compressor. + * (If you don't know what that's for, you don't need it.) + * + * If the compressor requires full-image buffers (for entropy-coding + * optimization or a multi-scan JPEG file), it will create temporary + * files for anything that doesn't fit within the maximum-memory setting. + * (Note that temp files are NOT needed if you use the default parameters.) + * On some systems you may need to set up a signal handler to ensure that + * temporary files are deleted if the program is interrupted. See libjpeg.doc. + * + * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG + * files to be compatible with everyone else's. If you cannot readily read + * your data in that order, you'll need an intermediate array to hold the + * image. See rdtarga.c or rdbmp.c for examples of handling bottom-to-top + * source data using the JPEG code's internal virtual-array mechanisms. + */ + + + +/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/ + +/* This half of the example shows how to read data from the JPEG decompressor. + * It's a bit more refined than the above, in that we show: + * (a) how to modify the JPEG library's standard error-reporting behavior; + * (b) how to allocate workspace using the library's memory manager. + * + * Just to make this example a little different from the first one, we'll + * assume that we do not intend to put the whole image into an in-memory + * buffer, but to send it line-by-line someplace else. We need a one- + * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG + * memory manager allocate it for us. This approach is actually quite useful + * because we don't need to remember to deallocate the buffer separately: it + * will go away automatically when the JPEG object is cleaned up. + */ + + +/* + * ERROR HANDLING: + * + * The JPEG library's standard error handler (jerror.c) is divided into + * several "methods" which you can override individually. This lets you + * adjust the behavior without duplicating a lot of code, which you might + * have to update with each future release. + * + * Our example here shows how to override the "error_exit" method so that + * control is returned to the library's caller when a fatal error occurs, + * rather than calling exit() as the standard error_exit method does. + * + * We use C's setjmp/longjmp facility to return control. This means that the + * routine which calls the JPEG library must first execute a setjmp() call to + * establish the return point. We want the replacement error_exit to do a + * longjmp(). But we need to make the setjmp buffer accessible to the + * error_exit routine. To do this, we make a private extension of the + * standard JPEG error handler object. (If we were using C++, we'd say we + * were making a subclass of the regular error handler.) + * + * Here's the extended error handler struct: + */ + +struct my_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + + jmp_buf setjmp_buffer; /* for return to caller */ +}; + +typedef struct my_error_mgr * my_error_ptr; + +/* + * Here's the routine that will replace the standard error_exit method: + */ + +METHODDEF(void) +my_error_exit (j_common_ptr cinfo) +{ + /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ + my_error_ptr myerr = (my_error_ptr) cinfo->err; + + /* Always display the message. */ + /* We could postpone this until after returning, if we chose. */ + (*cinfo->err->output_message) (cinfo); + + /* Return control to the setjmp point */ + longjmp(myerr->setjmp_buffer, 1); +} + + +/* + * Sample routine for JPEG decompression. We assume that the source file name + * is passed in. We want to return 1 on success, 0 on error. + */ + + +GLOBAL(int) +read_JPEG_file (char * filename) +{ + /* This struct contains the JPEG decompression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + */ + struct jpeg_decompress_struct cinfo; + /* We use our private extension JPEG error handler. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct my_error_mgr jerr; + /* More stuff */ + FILE * infile; /* source file */ + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + + /* In this example we want to open the input file before doing anything else, + * so that the setjmp() error recovery below can assume the file is open. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to read binary files. + */ + + if ((infile = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "can't open %s\n", filename); + return 0; + } + + /* Step 1: allocate and initialize JPEG decompression object */ + + /* We set up the normal JPEG error routines, then override error_exit. */ + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + /* Establish the setjmp return context for my_error_exit to use. */ + if (setjmp(jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. + * We need to clean up the JPEG object, close the input file, and return. + */ + jpeg_destroy_decompress(&cinfo); + fclose(infile); + return 0; + } + /* Now we can initialize the JPEG decompression object. */ + jpeg_create_decompress(&cinfo); + + /* Step 2: specify data source (eg, a file) */ + + jpeg_stdio_src(&cinfo, infile); + + /* Step 3: read file parameters with jpeg_read_header() */ + + (void) jpeg_read_header(&cinfo, TRUE); + /* We can ignore the return value from jpeg_read_header since + * (a) suspension is not possible with the stdio data source, and + * (b) we passed TRUE to reject a tables-only JPEG file as an error. + * See libjpeg.doc for more info. + */ + + /* Step 4: set parameters for decompression */ + + /* In this example, we don't need to change any of the defaults set by + * jpeg_read_header(), so we do nothing here. + */ + + /* Step 5: Start decompressor */ + + (void) jpeg_start_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* We may need to do some setup of our own at this point before reading + * the data. After jpeg_start_decompress() we have the correct scaled + * output image dimensions available, as well as the output colormap + * if we asked for color quantization. + * In this example, we need to make an output work buffer of the right size. + */ + /* JSAMPLEs per row in output buffer */ + row_stride = cinfo.output_width * cinfo.output_components; + /* Make a one-row-high sample array that will go away when done with image */ + buffer = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + /* Step 6: while (scan lines remain to be read) */ + /* jpeg_read_scanlines(...); */ + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + while (cinfo.output_scanline < cinfo.output_height) { + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + (void) jpeg_read_scanlines(&cinfo, buffer, 1); + /* Assume put_scanline_someplace wants a pointer and sample count. */ + put_scanline_someplace(buffer[0], row_stride); + } + + /* Step 7: Finish decompression */ + + (void) jpeg_finish_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* Step 8: Release JPEG decompression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_decompress(&cinfo); + + /* After finish_decompress, we can close the input file. + * Here we postpone it until after no more JPEG errors are possible, + * so as to simplify the setjmp error logic above. (Actually, I don't + * think that jpeg_destroy can do an error exit, but why assume anything...) + */ + fclose(infile); + + /* At this point you may want to check to see whether any corrupt-data + * warnings occurred (test whether jerr.pub.num_warnings is nonzero). + */ + + /* And we're done! */ + return 1; +} + + +/* + * SOME FINE POINTS: + * + * In the above code, we ignored the return value of jpeg_read_scanlines, + * which is the number of scanlines actually read. We could get away with + * this because we asked for only one line at a time and we weren't using + * a suspending data source. See libjpeg.doc for more info. + * + * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress(); + * we should have done it beforehand to ensure that the space would be + * counted against the JPEG max_memory setting. In some systems the above + * code would risk an out-of-memory error. However, in general we don't + * know the output image dimensions before jpeg_start_decompress(), unless we + * call jpeg_calc_output_dimensions(). See libjpeg.doc for more about this. + * + * Scanlines are returned in the same order as they appear in the JPEG file, + * which is standardly top-to-bottom. If you must emit data bottom-to-top, + * you can use one of the virtual arrays provided by the JPEG memory manager + * to invert the data. See wrbmp.c for an example. + * + * As with compression, some operating modes may require temporary files. + * On some systems you may need to set up a signal handler to ensure that + * temporary files are deleted if the program is interrupted. See libjpeg.doc. + */ diff --git a/rosapps/lib/libjpeg/jcapimin.c b/rosapps/lib/libjpeg/jcapimin.c new file mode 100644 index 00000000000..54fb8c58c56 --- /dev/null +++ b/rosapps/lib/libjpeg/jcapimin.c @@ -0,0 +1,280 @@ +/* + * jcapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-compression case or the transcoding-only + * case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jcapistd.c. But also see jcparam.c for + * parameter-setup helper routines, jcomapi.c for routines shared by + * compression and decompression, and jctrans.c for the transcoding case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG compression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL(void) +jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize) +{ + int i; + + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_compress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_compress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ + MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct)); + cinfo->err = err; + cinfo->client_data = client_data; + } + cinfo->is_decompressor = FALSE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->dest = NULL; + + cinfo->comp_info = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + cinfo->script_space = NULL; + + cinfo->input_gamma = 1.0; /* in case application forgets */ + + /* OK, I'm ready */ + cinfo->global_state = CSTATE_START; +} + + +/* + * Destruction of a JPEG compression object + */ + +GLOBAL(void) +jpeg_destroy_compress (j_compress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG compression operation, + * but don't destroy the object itself. + */ + +GLOBAL(void) +jpeg_abort_compress (j_compress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Forcibly suppress or un-suppress all quantization and Huffman tables. + * Marks all currently defined tables as already written (if suppress) + * or not written (if !suppress). This will control whether they get emitted + * by a subsequent jpeg_start_compress call. + * + * This routine is exported for use by applications that want to produce + * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + * since it is called by jpeg_start_compress, we put it here --- otherwise + * jcparam.o would be linked whether the application used it or not. + */ + +GLOBAL(void) +jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) +{ + int i; + JQUANT_TBL * qtbl; + JHUFF_TBL * htbl; + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL) + qtbl->sent_table = suppress; + } + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + } +} + + +/* + * Finish JPEG compression. + * + * If a multipass operating mode was selected, this may do a great deal of + * work including most of the actual output. + */ + +GLOBAL(void) +jpeg_finish_compress (j_compress_ptr cinfo) +{ + JDIMENSION iMCU_row; + + if (cinfo->global_state == CSTATE_SCANNING || + cinfo->global_state == CSTATE_RAW_OK) { + /* Terminate first pass */ + if (cinfo->next_scanline < cinfo->image_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_pass) (cinfo); + } else if (cinfo->global_state != CSTATE_WRCOEFS) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any remaining passes */ + while (! cinfo->master->is_last_pass) { + (*cinfo->master->prepare_for_pass) (cinfo); + for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) { + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) iMCU_row; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* We bypass the main controller and invoke coef controller directly; + * all work is being done from the coefficient buffer. + */ + if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } + (*cinfo->master->finish_pass) (cinfo); + } + /* Write EOI, do final cleanup */ + (*cinfo->marker->write_file_trailer) (cinfo); + (*cinfo->dest->term_destination) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); +} + + +/* + * Write a special marker. + * This is only recommended for writing COM or APPn markers. + * Must be called after jpeg_start_compress() and before + * first call to jpeg_write_scanlines() or jpeg_write_raw_data(). + */ + +GLOBAL(void) +jpeg_write_marker (j_compress_ptr cinfo, int marker, + const JOCTET *dataptr, unsigned int datalen) +{ + JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val)); + + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); + write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */ + while (datalen--) { + (*write_marker_byte) (cinfo, *dataptr); + dataptr++; + } +} + +/* Same, but piecemeal. */ + +GLOBAL(void) +jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +{ + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); +} + +GLOBAL(void) +jpeg_write_m_byte (j_compress_ptr cinfo, int val) +{ + (*cinfo->marker->write_marker_byte) (cinfo, val); +} + + +/* + * Alternate compression function: just write an abbreviated table file. + * Before calling this, all parameters and a data destination must be set up. + * + * To produce a pair of files containing abbreviated tables and abbreviated + * image data, one would proceed as follows: + * + * initialize JPEG object + * set JPEG parameters + * set destination to table file + * jpeg_write_tables(cinfo); + * set destination to image file + * jpeg_start_compress(cinfo, FALSE); + * write data... + * jpeg_finish_compress(cinfo); + * + * jpeg_write_tables has the side effect of marking all tables written + * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + * will not re-emit the tables unless it is passed write_all_tables=TRUE. + */ + +GLOBAL(void) +jpeg_write_tables (j_compress_ptr cinfo) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Initialize the marker writer ... bit of a crock to do it here. */ + jinit_marker_writer(cinfo); + /* Write them tables! */ + (*cinfo->marker->write_tables_only) (cinfo); + /* And clean up. */ + (*cinfo->dest->term_destination) (cinfo); + /* + * In library releases up through v6a, we called jpeg_abort() here to free + * any working memory allocated by the destination manager and marker + * writer. Some applications had a problem with that: they allocated space + * of their own from the library memory manager, and didn't want it to go + * away during write_tables. So now we do nothing. This will cause a + * memory leak if an app calls write_tables repeatedly without doing a full + * compression cycle or otherwise resetting the JPEG object. However, that + * seems less bad than unexpectedly freeing memory in the normal case. + * An app that prefers the old behavior can call jpeg_abort for itself after + * each call to jpeg_write_tables(). + */ +} diff --git a/rosapps/lib/libjpeg/jcapistd.c b/rosapps/lib/libjpeg/jcapistd.c new file mode 100644 index 00000000000..c0320b1b190 --- /dev/null +++ b/rosapps/lib/libjpeg/jcapistd.c @@ -0,0 +1,161 @@ +/* + * jcapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-compression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_compress, it will end up linking in the entire compressor. + * We thus must separate this file from jcapimin.c to avoid linking the + * whole compression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Compression initialization. + * Before calling this, all parameters and a data destination must be set up. + * + * We require a write_all_tables parameter as a failsafe check when writing + * multiple datastreams from the same compression object. Since prior runs + * will have left all the tables marked sent_table=TRUE, a subsequent run + * would emit an abbreviated stream (no tables) by default. This may be what + * is wanted, but for safety's sake it should not be the default behavior: + * programmers should have to make a deliberate choice to emit abbreviated + * images. Therefore the documentation and examples should encourage people + * to pass write_all_tables=TRUE; then it will take active thought to do the + * wrong thing. + */ + +GLOBAL(void) +jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (write_all_tables) + jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + jinit_compress_master(cinfo); + /* Set up for the first pass */ + (*cinfo->master->prepare_for_pass) (cinfo); + /* Ready for application to drive first pass through jpeg_write_scanlines + * or jpeg_write_raw_data. + */ + cinfo->next_scanline = 0; + cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); +} + + +/* + * Write some scanlines of data to the JPEG compressor. + * + * The return value will be the number of lines actually written. + * This should be less than the supplied num_lines only in case that + * the data destination module has requested suspension of the compressor, + * or if more than image_height scanlines are passed in. + * + * Note: we warn about excess calls to jpeg_write_scanlines() since + * this likely signals an application programmer error. However, + * excess scanlines passed in the last valid call are *silently* ignored, + * so that the application need not adjust num_lines for end-of-image + * when using a multiple-scanline buffer. + */ + +GLOBAL(JDIMENSION) +jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION num_lines) +{ + JDIMENSION row_ctr, rows_left; + + if (cinfo->global_state != CSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_scanlines. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_scanlines. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Ignore any extra scanlines at bottom of image. */ + rows_left = cinfo->image_height - cinfo->next_scanline; + if (num_lines > rows_left) + num_lines = rows_left; + + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); + cinfo->next_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to write raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL(JDIMENSION) +jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION num_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != CSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_raw_data. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_raw_data. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Verify that at least one iMCU row has been passed. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; + if (num_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Directly compress the row. */ + if (! (*cinfo->coef->compress_data) (cinfo, data)) { + /* If compressor did not consume the whole row, suspend processing. */ + return 0; + } + + /* OK, we processed one iMCU row. */ + cinfo->next_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} diff --git a/rosapps/lib/libjpeg/jccoefct.c b/rosapps/lib/libjpeg/jccoefct.c new file mode 100644 index 00000000000..1963ddb61b1 --- /dev/null +++ b/rosapps/lib/libjpeg/jccoefct.c @@ -0,0 +1,449 @@ +/* + * jccoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for compression. + * This controller is the top level of the JPEG compressor proper. + * The coefficient buffer lies between forward-DCT and entropy encoding steps. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* We use a full-image coefficient buffer when doing Huffman optimization, + * and also for writing multiple-scan JPEG files. In all cases, the DCT + * step is run during the first pass, and subsequent passes need only read + * the buffered coefficients. + */ +#ifdef ENTROPY_OPT_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#else +#ifdef C_MULTISCAN_FILES_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#endif +#endif + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* For single-pass compression, it's sufficient to buffer just one MCU + * (although this may prove a bit slow in practice). We allocate a + * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each + * MCU constructed and sent. (On 80x86, the workspace is FAR even though + * it's not really very big; this is to keep the module interfaces unchanged + * when a large coefficient buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays. + */ + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +/* Forward declarations */ +METHODDEF(boolean) compress_data + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#ifdef FULL_COEF_BUFFER_SUPPORTED +METHODDEF(boolean) compress_first_pass + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +METHODDEF(boolean) compress_output + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (coef->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_data; + break; +#ifdef FULL_COEF_BUFFER_SUPPORTED + case JBUF_SAVE_AND_PASS: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_first_pass; + break; + case JBUF_CRANK_DEST: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_output; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data in the single-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(boolean) +compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, bi, ci, yindex, yoffset, blockcnt; + JDIMENSION ypos, xpos; + jpeg_component_info *compptr; + + /* Loop to write as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Determine where data comes from in input_buf and do the DCT thing. + * Each call on forward_DCT processes a horizontal row of DCT blocks + * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks + * sequentially. Dummy blocks at the right or bottom edge are filled in + * specially. The data in them does not matter for image reconstruction, + * so we fill them with values that will encode to the smallest amount of + * data, viz: all zeroes in the AC entries, DC entries equal to previous + * block's DC value. (Thanks to Thomas Kinsman for this idea.) + */ + blkn = 0; + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + xpos = MCU_col_num * compptr->MCU_sample_width; + ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */ + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[compptr->component_index], + coef->MCU_buffer[blkn], + ypos, xpos, (JDIMENSION) blockcnt); + if (blockcnt < compptr->MCU_width) { + /* Create some dummy blocks at the right edge of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], + (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); + for (bi = blockcnt; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; + } + } + } else { + /* Create a row of dummy blocks at the bottom of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn], + compptr->MCU_width * SIZEOF(JBLOCK)); + for (bi = 0; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; + } + } + blkn += compptr->MCU_width; + ypos += DCTSIZE; + } + } + /* Try to write the MCU. In event of a suspension failure, we will + * re-DCT the MCU on restart (a bit inefficient, could be fixed...) + */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +#ifdef FULL_COEF_BUFFER_SUPPORTED + +/* + * Process some data in the first pass of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * This amount of data is read from the source buffer, DCT'd and quantized, + * and saved into the virtual arrays. We also generate suitable dummy blocks + * as needed at the right and lower edges. (The dummy blocks are constructed + * in the virtual arrays, which have been padded appropriately.) This makes + * it possible for subsequent passes not to worry about real vs. dummy blocks. + * + * We must also emit the data to the entropy encoder. This is conveniently + * done by calling compress_output() after we've loaded the current strip + * of the virtual arrays. + * + * NB: input_buf contains a plane for each component in image. All + * components are DCT'd and loaded into the virtual arrays in this pass. + * However, it may be that only a subset of the components are emitted to + * the entropy encoder during this first pass; be careful about looking + * at the scan-dependent variables (MCU dimensions, etc). + */ + +METHODDEF(boolean) +compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION blocks_across, MCUs_across, MCUindex; + int bi, ci, h_samp_factor, block_row, block_rows, ndummy; + JCOEF lastDC; + jpeg_component_info *compptr; + JBLOCKARRAY buffer; + JBLOCKROW thisblockrow, lastblockrow; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (coef->iMCU_row_num < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here, since may not be set! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + blocks_across = compptr->width_in_blocks; + h_samp_factor = compptr->h_samp_factor; + /* Count number of dummy blocks to be added at the right margin. */ + ndummy = (int) (blocks_across % h_samp_factor); + if (ndummy > 0) + ndummy = h_samp_factor - ndummy; + /* Perform DCT for all non-dummy blocks in this iMCU row. Each call + * on forward_DCT processes a complete horizontal row of DCT blocks. + */ + for (block_row = 0; block_row < block_rows; block_row++) { + thisblockrow = buffer[block_row]; + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[ci], thisblockrow, + (JDIMENSION) (block_row * DCTSIZE), + (JDIMENSION) 0, blocks_across); + if (ndummy > 0) { + /* Create dummy blocks at the right edge of the image. */ + thisblockrow += blocks_across; /* => first dummy block */ + jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK)); + lastDC = thisblockrow[-1][0]; + for (bi = 0; bi < ndummy; bi++) { + thisblockrow[bi][0] = lastDC; + } + } + } + /* If at end of image, create dummy block rows as needed. + * The tricky part here is that within each MCU, we want the DC values + * of the dummy blocks to match the last real block's DC value. + * This squeezes a few more bytes out of the resulting file... + */ + if (coef->iMCU_row_num == last_iMCU_row) { + blocks_across += ndummy; /* include lower right corner */ + MCUs_across = blocks_across / h_samp_factor; + for (block_row = block_rows; block_row < compptr->v_samp_factor; + block_row++) { + thisblockrow = buffer[block_row]; + lastblockrow = buffer[block_row-1]; + jzero_far((void FAR *) thisblockrow, + (size_t) (blocks_across * SIZEOF(JBLOCK))); + for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { + lastDC = lastblockrow[h_samp_factor-1][0]; + for (bi = 0; bi < h_samp_factor; bi++) { + thisblockrow[bi][0] = lastDC; + } + thisblockrow += h_samp_factor; /* advance to next MCU in row */ + lastblockrow += h_samp_factor; + } + } + } + } + /* NB: compress_output will increment iMCU_row_num if successful. + * A suspension return will result in redoing all the work above next time. + */ + + /* Emit data to the entropy encoder, sharing code with subsequent passes */ + return compress_output(cinfo, input_buf); +} + + +/* + * Process some data in subsequent passes of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF(boolean) +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. + * NB: during first pass, this is safe only because the buffers will + * already be aligned properly, so jmemmgr.c won't need to do any I/O. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + +#endif /* FULL_COEF_BUFFER_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL(void) +jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef FULL_COEF_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + int ci; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->whole_image[0] = NULL; /* flag for no virtual arrays */ + } +} diff --git a/rosapps/lib/libjpeg/jccolor.c b/rosapps/lib/libjpeg/jccolor.c new file mode 100644 index 00000000000..0a8a4b5d13c --- /dev/null +++ b/rosapps/lib/libjpeg/jccolor.c @@ -0,0 +1,459 @@ +/* + * jccolor.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_converter pub; /* public fields */ + + /* Private state for RGB->YCC conversion */ + INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */ +} my_color_converter; + +typedef my_color_converter * my_cconvert_ptr; + + +/**************** RGB -> YCbCr conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B + * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE + * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2, + * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and + * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) + * were not represented exactly. Now we sacrifice exact representation of + * maximum red and maximum blue in order to get exact grayscales. + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times R,G,B for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included + * in the tables to save adding them separately in the inner loop. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS) +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L< Y section */ +#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ +#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ +#define R_CB_OFF (3*(MAXJSAMPLE+1)) +#define G_CB_OFF (4*(MAXJSAMPLE+1)) +#define B_CB_OFF (5*(MAXJSAMPLE+1)) +#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */ +#define G_CR_OFF (6*(MAXJSAMPLE+1)) +#define B_CR_OFF (7*(MAXJSAMPLE+1)) +#define TABLE_SIZE (8*(MAXJSAMPLE+1)) + + +/* + * Initialize for RGB->YCC colorspace conversion. + */ + +METHODDEF(void) +rgb_ycc_start (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + INT32 * rgb_ycc_tab; + INT32 i; + + /* Allocate and fill in the conversion tables. */ + cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (TABLE_SIZE * SIZEOF(INT32))); + + for (i = 0; i <= MAXJSAMPLE; i++) { + rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i; + rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i; + rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; + rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i; + rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i; + /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. + * This ensures that the maximum output will round to MAXJSAMPLE + * not MAXJSAMPLE+1, and thus that we don't have to range-limit. + */ + rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +/* B=>Cb and R=>Cr tables are the same + rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +*/ + rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i; + rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i; + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * + * Note that we change from the application's interleaved-pixel format + * to our internal noninterleaved, one-plane-per-component format. + * The input buffer is therefore three times as wide as the output buffer. + * + * A starting row offset is provided only for the output buffer. The caller + * can easily adjust the passed input_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF(void) +rgb_ycc_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/**************** Cases other than RGB -> YCbCr **************/ + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles RGB->grayscale conversion, which is the same + * as the RGB->Y portion of RGB->YCbCr. + * We assume rgb_ycc_start has been called (we only use the Y tables). + */ + +METHODDEF(void) +rgb_gray_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* Y */ + outptr[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles Adobe-style CMYK->YCCK conversion, + * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same + * conversion as above, while passing K (black) unchanged. + * We assume rgb_ycc_start has been called. + */ + +METHODDEF(void) +cmyk_ycck_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2, outptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + outptr3 = output_buf[3][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = MAXJSAMPLE - GETJSAMPLE(inptr[0]); + g = MAXJSAMPLE - GETJSAMPLE(inptr[1]); + b = MAXJSAMPLE - GETJSAMPLE(inptr[2]); + /* K passes through as-is */ + outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */ + inptr += 4; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles grayscale output with no conversion. + * The source can be either plain grayscale or YCbCr (since Y == gray). + */ + +METHODDEF(void) +grayscale_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + int instride = cinfo->input_components; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */ + inptr += instride; + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles multi-component colorspaces without conversion. + * We assume input_components == num_components. + */ + +METHODDEF(void) +null_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + register int ci; + int nc = cinfo->num_components; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + /* It seems fastest to make a separate pass for each component. */ + for (ci = 0; ci < nc; ci++) { + inptr = *input_buf; + outptr = output_buf[ci][output_row]; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */ + inptr += nc; + } + } + input_buf++; + output_row++; + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF(void) +null_method (j_compress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for input colorspace conversion. + */ + +GLOBAL(void) +jinit_color_converter (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_converter)); + cinfo->cconvert = (struct jpeg_color_converter *) cconvert; + /* set start_pass to null method until we find out differently */ + cconvert->pub.start_pass = null_method; + + /* Make sure input_components agrees with in_color_space */ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + if (cinfo->input_components != 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + if (cinfo->input_components != RGB_PIXELSIZE) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; +#endif /* else share code with YCbCr */ + + case JCS_YCbCr: + if (cinfo->input_components != 3) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->input_components != 4) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->input_components < 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + } + + /* Check num_components, set conversion method based on requested space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_GRAYSCALE) + cconvert->pub.color_convert = grayscale_convert; + else if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_gray_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = grayscale_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_ycc_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = cmyk_ycck_convert; + } else if (cinfo->in_color_space == JCS_YCCK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: /* allow null conversion of JCS_UNKNOWN */ + if (cinfo->jpeg_color_space != cinfo->in_color_space || + cinfo->num_components != cinfo->input_components) + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + cconvert->pub.color_convert = null_convert; + break; + } +} diff --git a/rosapps/lib/libjpeg/jcdctmgr.c b/rosapps/lib/libjpeg/jcdctmgr.c new file mode 100644 index 00000000000..61fa79b9e68 --- /dev/null +++ b/rosapps/lib/libjpeg/jcdctmgr.c @@ -0,0 +1,387 @@ +/* + * jcdctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the forward-DCT management logic. + * This code selects a particular DCT implementation to be used, + * and it performs related housekeeping chores including coefficient + * quantization. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_forward_dct pub; /* public fields */ + + /* Pointer to the DCT routine actually in use */ + forward_DCT_method_ptr do_dct; + + /* The actual post-DCT divisors --- not identical to the quant table + * entries, because of scaling (especially for an unnormalized DCT). + * Each table is given in normal array order. + */ + DCTELEM * divisors[NUM_QUANT_TBLS]; + +#ifdef DCT_FLOAT_SUPPORTED + /* Same as above for the floating-point case. */ + float_DCT_method_ptr do_float_dct; + FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]; +#endif +} my_fdct_controller; + +typedef my_fdct_controller * my_fdct_ptr; + + +/* + * Initialize for a processing pass. + * Verify that all referenced Q-tables are present, and set up + * the divisor table for each one. + * In the current implementation, DCT of all components is done during + * the first pass, even if only some components will be output in the + * first scan. Hence all components should be examined here. + */ + +METHODDEF(void) +start_pass_fdctmgr (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + int ci, qtblno, i; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + DCTELEM * dtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + qtblno = compptr->quant_tbl_no; + /* Make sure specified quantization table is present */ + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + qtbl = cinfo->quant_tbl_ptrs[qtblno]; + /* Compute divisors for this quant table */ + /* We may do this more than once for same table, but it's not a big deal */ + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + /* For LL&M IDCT method, divisors are equal to raw quantization + * coefficients multiplied by 8 (to counteract scaling). + */ + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3; + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + */ +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = (DCTELEM) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-3); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + * What's actually stored is 1/divisor so that the inner loop can + * use a multiplication rather than a division. + */ + FAST_FLOAT * fdtbl; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + if (fdct->float_divisors[qtblno] == NULL) { + fdct->float_divisors[qtblno] = (FAST_FLOAT *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(FAST_FLOAT)); + } + fdtbl = fdct->float_divisors[qtblno]; + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fdtbl[i] = (FAST_FLOAT) + (1.0 / (((double) qtbl->quantval[i] * + aanscalefactor[row] * aanscalefactor[col] * 8.0))); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Perform forward DCT on one or more blocks of a component. + * + * The input samples are taken from the sample_data[] array starting at + * position start_row/start_col, and moving to the right for any additional + * blocks. The quantized coefficients are returned in coef_blocks[]. + */ + +METHODDEF(void) +forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for integer DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + forward_DCT_method_ptr do_dct = fdct->do_dct; + DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no]; + DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register DCTELEM *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register DCTELEM temp, qval; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + qval = divisors[i]; + temp = workspace[i]; + /* Divide the coefficient value by qval, ensuring proper rounding. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * + * In most files, at least half of the output values will be zero + * (at default quantization settings, more like three-quarters...) + * so we should ensure that this case is fast. On many machines, + * a comparison is enough cheaper than a divide to make a special test + * a win. Since both inputs will be nonnegative, we need only test + * for a < b to discover whether a/b is 0. + * If your machine's division is fast enough, define FAST_DIVIDE. + */ +#ifdef FAST_DIVIDE +#define DIVIDE_BY(a,b) a /= b +#else +#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 +#endif + if (temp < 0) { + temp = -temp; + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + temp = -temp; + } else { + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + } + output_ptr[i] = (JCOEF) temp; + } + } + } +} + + +#ifdef DCT_FLOAT_SUPPORTED + +METHODDEF(void) +forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for floating-point DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + float_DCT_method_ptr do_dct = fdct->do_float_dct; + FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no]; + FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register FAST_FLOAT *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = (FAST_FLOAT) + (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register FAST_FLOAT temp; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + /* Apply the quantization and scaling factor */ + temp = workspace[i] * divisors[i]; + /* Round to nearest integer. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * The maximum coefficient size is +-16K (for 12-bit data), so this + * code should work for either 16-bit or 32-bit ints. + */ + output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384); + } + } + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ + + +/* + * Initialize FDCT manager. + */ + +GLOBAL(void) +jinit_forward_dct (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct; + int i; + + fdct = (my_fdct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_fdct_controller)); + cinfo->fdct = (struct jpeg_forward_dct *) fdct; + fdct->pub.start_pass = start_pass_fdctmgr; + + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_islow; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_ifast; + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + fdct->pub.forward_DCT = forward_DCT_float; + fdct->do_float_dct = jpeg_fdct_float; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + + /* Mark divisor tables unallocated */ + for (i = 0; i < NUM_QUANT_TBLS; i++) { + fdct->divisors[i] = NULL; +#ifdef DCT_FLOAT_SUPPORTED + fdct->float_divisors[i] = NULL; +#endif + } +} diff --git a/rosapps/lib/libjpeg/jchuff.c b/rosapps/lib/libjpeg/jchuff.c new file mode 100644 index 00000000000..f2352505486 --- /dev/null +++ b/rosapps/lib/libjpeg/jchuff.c @@ -0,0 +1,909 @@ +/* + * jchuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines. + * + * Much of the complexity here has to do with supporting output suspension. + * If the data destination module demands suspension, we want to be able to + * back up to the start of the current MCU. To do this, we copy state + * variables into local working storage, and update them back to the + * permanent JPEG objects only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jcphuff.c */ + + +/* Expanded entropy encoder object for Huffman encoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).put_buffer = (src).put_buffer, \ + (dest).put_bits = (src).put_bits, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + savable_state saved; /* Bit buffer & DC state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + +#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ + long * dc_count_ptrs[NUM_HUFF_TBLS]; + long * ac_count_ptrs[NUM_HUFF_TBLS]; +#endif +} huff_entropy_encoder; + +typedef huff_entropy_encoder * huff_entropy_ptr; + +/* Working state while writing an MCU. + * This struct contains all the fields that are needed by subroutines. + */ + +typedef struct { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + savable_state cur; /* Current bit buffer & DC state */ + j_compress_ptr cinfo; /* dump_buffer needs access to this */ +} working_state; + + +/* Forward declarations */ +METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo)); +#ifdef ENTROPY_OPT_SUPPORTED +METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo)); +#endif + + +/* + * Initialize for a Huffman-compressed scan. + * If gather_statistics is TRUE, we do not output anything during the scan, + * just count the Huffman symbols used and generate Huffman code tables. + */ + +METHODDEF(void) +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + entropy->pub.encode_mcu = encode_mcu_gather; + entropy->pub.finish_pass = finish_pass_gather; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + entropy->pub.encode_mcu = encode_mcu_huff; + entropy->pub.finish_pass = finish_pass_huff; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + /* Check for invalid table indexes */ + /* (make_c_derived_tbl does this in the other path) */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0 || actbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->dc_count_ptrs[dctbl] == NULL) + entropy->dc_count_ptrs[dctbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long)); + if (entropy->ac_count_ptrs[actbl] == NULL) + entropy->ac_count_ptrs[actbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long)); +#endif + } else { + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bit buffer to empty */ + entropy->saved.put_buffer = 0; + entropy->saved.put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* + * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * + * Note this is also used by jcphuff.c. + */ + +GLOBAL(void) +jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl) +{ + JHUFF_TBL *htbl; + c_derived_tbl *dtbl; + int p, i, l, lastp, si, maxsymbol; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (c_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(c_derived_tbl)); + dtbl = *pdtbl; + + /* Figure C.1: make table of Huffman code length for each symbol */ + + p = 0; + for (l = 1; l <= 16; l++) { + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + lastp = p; + + /* Figure C.2: generate the codes themselves */ + /* We also validate that the counts represent a legal Huffman code tree. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + code <<= 1; + si++; + } + + /* Figure C.3: generate encoding tables */ + /* These are code and size indexed by symbol value */ + + /* Set all codeless symbols to have code length 0; + * this lets us detect duplicate VAL entries here, and later + * allows emit_bits to detect any attempt to emit such symbols. + */ + MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi)); + + /* This is also a convenient place to check for out-of-range + * and duplicated VAL entries. We allow 0..255 for AC symbols + * but only 0..15 for DC. (We could constrain them further + * based on data depth and mode, but this seems enough.) + */ + maxsymbol = isDC ? 15 : 255; + + for (p = 0; p < lastp; p++) { + i = htbl->huffval[p]; + if (i < 0 || i > maxsymbol || dtbl->ehufsi[i]) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + dtbl->ehufco[i] = huffcode[p]; + dtbl->ehufsi[i] = huffsize[p]; + } +} + + +/* Outputting bytes to the file */ + +/* Emit a byte, taking 'action' if must suspend. */ +#define emit_byte(state,val,action) \ + { *(state)->next_output_byte++ = (JOCTET) (val); \ + if (--(state)->free_in_buffer == 0) \ + if (! dump_buffer(state)) \ + { action; } } + + +LOCAL(boolean) +dump_buffer (working_state * state) +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ +{ + struct jpeg_destination_mgr * dest = state->cinfo->dest; + + if (! (*dest->empty_output_buffer) (state->cinfo)) + return FALSE; + /* After a successful buffer dump, must reset buffer pointers */ + state->next_output_byte = dest->next_output_byte; + state->free_in_buffer = dest->free_in_buffer; + return TRUE; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(boolean) +emit_bits (working_state * state, unsigned int code, int size) +/* Emit some bits; return TRUE if successful, FALSE if must suspend */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = state->cur.put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); + + put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(state, c, return FALSE); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(state, 0, return FALSE); + } + put_buffer <<= 8; + put_bits -= 8; + } + + state->cur.put_buffer = put_buffer; /* update state variables */ + state->cur.put_bits = put_bits; + + return TRUE; +} + + +LOCAL(boolean) +flush_bits (working_state * state) +{ + if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ + return FALSE; + state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ + state->cur.put_bits = 0; + return TRUE; +} + + +/* Encode a single block's worth of coefficients */ + +LOCAL(boolean) +encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, + c_derived_tbl *dctbl, c_derived_tbl *actbl) +{ + register int temp, temp2; + register int nbits; + register int k, r, i; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = temp2 = block[0] - last_dc_val; + + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit Huffman symbol for run length / number of bits */ + i = (r << 4) + nbits; + if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) + return FALSE; + + return TRUE; +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(boolean) +emit_restart (working_state * state, int restart_num) +{ + int ci; + + if (! flush_bits(state)) + return FALSE; + + emit_byte(state, 0xFF, return FALSE); + emit_byte(state, JPEG_RST0 + restart_num, return FALSE); + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) + state->cur.last_dc_val[ci] = 0; + + /* The restart counter is not updated until we successfully write the MCU. */ + + return TRUE; +} + + +/* + * Encode and output one MCU's worth of Huffman-compressed coefficients. + */ + +METHODDEF(boolean) +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + int blkn, ci; + jpeg_component_info * compptr; + + /* Load up working state */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! emit_restart(&state, entropy->next_restart_num)) + return FALSE; + } + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + if (! encode_one_block(&state, + MCU_data[blkn][0], state.cur.last_dc_val[ci], + entropy->dc_derived_tbls[compptr->dc_tbl_no], + entropy->ac_derived_tbls[compptr->ac_tbl_no])) + return FALSE; + /* Update last_dc_val */ + state.cur.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + /* Completed MCU, so update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed scan. + */ + +METHODDEF(void) +finish_pass_huff (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + + /* Load up working state ... flush_bits needs it */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Flush out the last data */ + if (! flush_bits(&state)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + + /* Update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); +} + + +/* + * Huffman coding optimization. + * + * We first scan the supplied data and count the number of uses of each symbol + * that is to be Huffman-coded. (This process MUST agree with the code above.) + * Then we build a Huffman coding tree for the observed counts. + * Symbols which are not needed at all for the particular image are not + * assigned any code, which saves space in the DHT marker as well as in + * the compressed data. + */ + +#ifdef ENTROPY_OPT_SUPPORTED + + +/* Process a single block's worth of coefficients */ + +LOCAL(void) +htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, + long dc_counts[], long ac_counts[]) +{ + register int temp; + register int nbits; + register int k, r; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = block[0] - last_dc_val; + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + ac_counts[0]++; +} + + +/* + * Trial-encode one MCU's worth of Huffman-compressed coefficients. + * No data is actually output, so no suspension return is possible. + */ + +METHODDEF(boolean) +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn, ci; + jpeg_component_info * compptr; + + /* Take care of restart intervals if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Update restart state */ + entropy->restarts_to_go = cinfo->restart_interval; + } + entropy->restarts_to_go--; + } + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci], + entropy->dc_count_ptrs[compptr->dc_tbl_no], + entropy->ac_count_ptrs[compptr->ac_tbl_no]); + entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + return TRUE; +} + + +/* + * Generate the best Huffman code table for the given counts, fill htbl. + * Note this is also used by jcphuff.c. + * + * The JPEG standard requires that no symbol be assigned a codeword of all + * one bits (so that padding bits added at the end of a compressed segment + * can't look like a valid code). Because of the canonical ordering of + * codewords, this just means that there must be an unused slot in the + * longest codeword length category. Section K.2 of the JPEG spec suggests + * reserving such a slot by pretending that symbol 256 is a valid symbol + * with count 1. In theory that's not optimal; giving it count zero but + * including it in the symbol set anyway should give a better Huffman code. + * But the theoretically better code actually seems to come out worse in + * practice, because it produces more all-ones bytes (which incur stuffed + * zero bytes in the final file). In any case the difference is tiny. + * + * The JPEG standard requires Huffman codes to be no more than 16 bits long. + * If some symbols have a very small but nonzero probability, the Huffman tree + * must be adjusted to meet the code length restriction. We currently use + * the adjustment method suggested in JPEG section K.2. This method is *not* + * optimal; it may not choose the best possible limited-length code. But + * typically only very-low-frequency symbols will be given less-than-optimal + * lengths, so the code is almost optimal. Experimental comparisons against + * an optimal limited-length-code algorithm indicate that the difference is + * microscopic --- usually less than a hundredth of a percent of total size. + * So the extra complexity of an optimal algorithm doesn't seem worthwhile. + */ + +GLOBAL(void) +jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) +{ +#define MAX_CLEN 32 /* assumed maximum initial code length */ + UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ + int codesize[257]; /* codesize[k] = code length of symbol k */ + int others[257]; /* next symbol in current branch of tree */ + int c1, c2; + int p, i, j; + long v; + + /* This algorithm is explained in section K.2 of the JPEG standard */ + + MEMZERO(bits, SIZEOF(bits)); + MEMZERO(codesize, SIZEOF(codesize)); + for (i = 0; i < 257; i++) + others[i] = -1; /* init links to empty */ + + freq[256] = 1; /* make sure 256 has a nonzero count */ + /* Including the pseudo-symbol 256 in the Huffman procedure guarantees + * that no real symbol is given code-value of all ones, because 256 + * will be placed last in the largest codeword category. + */ + + /* Huffman's basic algorithm to assign optimal code lengths to symbols */ + + for (;;) { + /* Find the smallest nonzero frequency, set c1 = its symbol */ + /* In case of ties, take the larger symbol number */ + c1 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v) { + v = freq[i]; + c1 = i; + } + } + + /* Find the next smallest nonzero frequency, set c2 = its symbol */ + /* In case of ties, take the larger symbol number */ + c2 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v && i != c1) { + v = freq[i]; + c2 = i; + } + } + + /* Done if we've merged everything into one frequency */ + if (c2 < 0) + break; + + /* Else merge the two counts/trees */ + freq[c1] += freq[c2]; + freq[c2] = 0; + + /* Increment the codesize of everything in c1's tree branch */ + codesize[c1]++; + while (others[c1] >= 0) { + c1 = others[c1]; + codesize[c1]++; + } + + others[c1] = c2; /* chain c2 onto c1's tree branch */ + + /* Increment the codesize of everything in c2's tree branch */ + codesize[c2]++; + while (others[c2] >= 0) { + c2 = others[c2]; + codesize[c2]++; + } + } + + /* Now count the number of symbols of each code length */ + for (i = 0; i <= 256; i++) { + if (codesize[i]) { + /* The JPEG standard seems to think that this can't happen, */ + /* but I'm paranoid... */ + if (codesize[i] > MAX_CLEN) + ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW); + + bits[codesize[i]]++; + } + } + + /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure + * Huffman procedure assigned any such lengths, we must adjust the coding. + * Here is what the JPEG spec says about how this next bit works: + * Since symbols are paired for the longest Huffman code, the symbols are + * removed from this length category two at a time. The prefix for the pair + * (which is one bit shorter) is allocated to one of the pair; then, + * skipping the BITS entry for that prefix length, a code word from the next + * shortest nonzero BITS entry is converted into a prefix for two code words + * one bit longer. + */ + + for (i = MAX_CLEN; i > 16; i--) { + while (bits[i] > 0) { + j = i - 2; /* find length of new prefix to be used */ + while (bits[j] == 0) + j--; + + bits[i] -= 2; /* remove two symbols */ + bits[i-1]++; /* one goes in this length */ + bits[j+1] += 2; /* two new symbols in this length */ + bits[j]--; /* symbol of this length is now a prefix */ + } + } + + /* Remove the count for the pseudo-symbol 256 from the largest codelength */ + while (bits[i] == 0) /* find largest codelength still in use */ + i--; + bits[i]--; + + /* Return final symbol counts (only for lengths 0..16) */ + MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits)); + + /* Return a list of the symbols sorted by code length */ + /* It's not real clear to me why we don't need to consider the codelength + * changes made above, but the JPEG spec seems to think this works. + */ + p = 0; + for (i = 1; i <= MAX_CLEN; i++) { + for (j = 0; j <= 255; j++) { + if (codesize[j] == i) { + htbl->huffval[p] = (UINT8) j; + p++; + } + } + } + + /* Set sent_table FALSE so updated table will be written to JPEG file. */ + htbl->sent_table = FALSE; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did_dc[NUM_HUFF_TBLS]; + boolean did_ac[NUM_HUFF_TBLS]; + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did_dc, SIZEOF(did_dc)); + MEMZERO(did_ac, SIZEOF(did_ac)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (! did_dc[dctbl]) { + htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); + did_dc[dctbl] = TRUE; + } + if (! did_ac[actbl]) { + htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); + did_ac[actbl] = TRUE; + } + } +} + + +#endif /* ENTROPY_OPT_SUPPORTED */ + + +/* + * Module initialization routine for Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_huff_encoder (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_huff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; +#ifdef ENTROPY_OPT_SUPPORTED + entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; +#endif + } +} diff --git a/rosapps/lib/libjpeg/jchuff.h b/rosapps/lib/libjpeg/jchuff.h new file mode 100644 index 00000000000..a9599fc1e6f --- /dev/null +++ b/rosapps/lib/libjpeg/jchuff.h @@ -0,0 +1,47 @@ +/* + * jchuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy encoding routines + * that are shared between the sequential encoder (jchuff.c) and the + * progressive encoder (jcphuff.c). No other modules need to see these. + */ + +/* The legal range of a DCT coefficient is + * -1024 .. +1023 for 8-bit data; + * -16384 .. +16383 for 12-bit data. + * Hence the magnitude should always fit in 10 or 14 bits respectively. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MAX_COEF_BITS 10 +#else +#define MAX_COEF_BITS 14 +#endif + +/* Derived data constructed for each Huffman table */ + +typedef struct { + unsigned int ehufco[256]; /* code for each symbol */ + char ehufsi[256]; /* length of code for each symbol */ + /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ +} c_derived_tbl; + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_c_derived_tbl jMkCDerived +#define jpeg_gen_optimal_table jGenOptTbl +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Expand a Huffman table definition into the derived format */ +EXTERN(void) jpeg_make_c_derived_tbl + JPP((j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl)); + +/* Generate an optimal table definition given the specified counts */ +EXTERN(void) jpeg_gen_optimal_table + JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); diff --git a/rosapps/lib/libjpeg/jcinit.c b/rosapps/lib/libjpeg/jcinit.c new file mode 100644 index 00000000000..5efffe33166 --- /dev/null +++ b/rosapps/lib/libjpeg/jcinit.c @@ -0,0 +1,72 @@ +/* + * jcinit.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains initialization logic for the JPEG compressor. + * This routine is in charge of selecting the modules to be executed and + * making an initialization call to each one. + * + * Logically, this code belongs in jcmaster.c. It's split out because + * linking this routine implies linking the entire compression library. + * For a transcoding-only application, we want to be able to use jcmaster.c + * without linking in the whole library. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Master selection of compression modules. + * This is done once at the start of processing an image. We determine + * which modules will be used and give them appropriate initialization calls. + */ + +GLOBAL(void) +jinit_compress_master (j_compress_ptr cinfo) +{ + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, FALSE /* full compression */); + + /* Preprocessing */ + if (! cinfo->raw_data_in) { + jinit_color_converter(cinfo); + jinit_downsampler(cinfo); + jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */); + } + /* Forward DCT */ + jinit_forward_dct(cinfo); + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* Need a full-image coefficient buffer in any multi-pass mode. */ + jinit_c_coef_controller(cinfo, + (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding)); + jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} diff --git a/rosapps/lib/libjpeg/jcmainct.c b/rosapps/lib/libjpeg/jcmainct.c new file mode 100644 index 00000000000..e0279a7e017 --- /dev/null +++ b/rosapps/lib/libjpeg/jcmainct.c @@ -0,0 +1,293 @@ +/* + * jcmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for compression. + * The main buffer lies between the pre-processor and the JPEG + * compressor proper; it holds downsampled data in the JPEG colorspace. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Note: currently, there is no operating mode in which a full-image buffer + * is needed at this step. If there were, that mode could not be used with + * "raw data" input, since this module is bypassed in that case. However, + * we've left the code here for possible use in special applications. + */ +#undef FULL_MAIN_BUFFER_SUPPORTED + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_main_controller pub; /* public fields */ + + JDIMENSION cur_iMCU_row; /* number of current iMCU row */ + JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ + boolean suspended; /* remember if we suspended output */ + J_BUF_MODE pass_mode; /* current operating mode */ + + /* If using just a strip buffer, this points to the entire set of buffers + * (we allocate one for each component). In the full-image case, this + * points to the currently accessible strips of the virtual arrays. + */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* If using full-image storage, this array holds pointers to virtual-array + * control blocks for each component. Unused if not full-image storage. + */ + jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; +#endif +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + + +/* Forward declarations */ +METHODDEF(void) process_data_simple_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#ifdef FULL_MAIN_BUFFER_SUPPORTED +METHODDEF(void) process_data_buffer_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Do nothing in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + main->cur_iMCU_row = 0; /* initialize counters */ + main->rowgroup_ctr = 0; + main->suspended = FALSE; + main->pass_mode = pass_mode; /* save mode for use by process_data */ + + switch (pass_mode) { + case JBUF_PASS_THRU: +#ifdef FULL_MAIN_BUFFER_SUPPORTED + if (main->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + main->pub.process_data = process_data_simple_main; + break; +#ifdef FULL_MAIN_BUFFER_SUPPORTED + case JBUF_SAVE_SOURCE: + case JBUF_CRANK_DEST: + case JBUF_SAVE_AND_PASS: + if (main->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + main->pub.process_data = process_data_buffer_main; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This routine handles the simple pass-through mode, + * where we have only a strip buffer. + */ + +METHODDEF(void) +process_data_simple_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Read input data if we haven't filled the main buffer yet */ + if (main->rowgroup_ctr < DCTSIZE) + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + + /* If we don't have a full iMCU row buffered, return to application for + * more data. Note that preprocessor will always pad to fill the iMCU row + * at the bottom of the image. + */ + if (main->rowgroup_ctr != DCTSIZE) + return; + + /* Send the completed row to the compressor */ + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + +/* + * Process some data. + * This routine handles all of the modes that use a full-size buffer. + */ + +METHODDEF(void) +process_data_buffer_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci; + jpeg_component_info *compptr; + boolean writing = (main->pass_mode != JBUF_CRANK_DEST); + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Realign the virtual buffers if at the start of an iMCU row. */ + if (main->rowgroup_ctr == 0) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, main->whole_image[ci], + main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); + } + /* In a read pass, pretend we just read some source data. */ + if (! writing) { + *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; + main->rowgroup_ctr = DCTSIZE; + } + } + + /* If a write pass, read input data until the current iMCU row is full. */ + /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ + if (writing) { + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + /* Return to application if we need more data to fill the iMCU row. */ + if (main->rowgroup_ctr < DCTSIZE) + return; + } + + /* Emit data, unless this is a sink-only pass. */ + if (main->pass_mode != JBUF_SAVE_SOURCE) { + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + } + + /* If get here, we are done with this iMCU row. Mark buffer empty. */ + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + +#endif /* FULL_MAIN_BUFFER_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL(void) +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_c_main_controller *) main; + main->pub.start_pass = start_pass_main; + + /* We don't need to create a buffer in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + /* Create the buffer. It holds downsampled data, so each component + * may be of a different size. + */ + if (need_full_buffer) { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component */ + /* Note we pad the bottom to a multiple of the iMCU height */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor) * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + main->whole_image[0] = NULL; /* flag for no virtual arrays */ +#endif + /* Allocate a strip buffer for each component */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } + } +} diff --git a/rosapps/lib/libjpeg/jcmarker.c b/rosapps/lib/libjpeg/jcmarker.c new file mode 100644 index 00000000000..3d1e6c6d524 --- /dev/null +++ b/rosapps/lib/libjpeg/jcmarker.c @@ -0,0 +1,664 @@ +/* + * jcmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write JPEG datastream markers. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* Private state */ + +typedef struct { + struct jpeg_marker_writer pub; /* public fields */ + + unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */ +} my_marker_writer; + +typedef my_marker_writer * my_marker_ptr; + + +/* + * Basic output routines. + * + * Note that we do not support suspension while writing a marker. + * Therefore, an application using suspension must ensure that there is + * enough buffer space for the initial markers (typ. 600-700 bytes) before + * calling jpeg_start_compress, and enough space to write the trailing EOI + * (a few bytes) before calling jpeg_finish_compress. Multipass compression + * modes are not supported at all with suspension, so those two are the only + * points where markers will be written. + */ + +LOCAL(void) +emit_byte (j_compress_ptr cinfo, int val) +/* Emit a byte */ +{ + struct jpeg_destination_mgr * dest = cinfo->dest; + + *(dest->next_output_byte)++ = (JOCTET) val; + if (--dest->free_in_buffer == 0) { + if (! (*dest->empty_output_buffer) (cinfo)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } +} + + +LOCAL(void) +emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) +/* Emit a marker code */ +{ + emit_byte(cinfo, 0xFF); + emit_byte(cinfo, (int) mark); +} + + +LOCAL(void) +emit_2bytes (j_compress_ptr cinfo, int value) +/* Emit a 2-byte integer; these are always MSB first in JPEG files */ +{ + emit_byte(cinfo, (value >> 8) & 0xFF); + emit_byte(cinfo, value & 0xFF); +} + + +/* + * Routines to write specific marker types. + */ + +LOCAL(int) +emit_dqt (j_compress_ptr cinfo, int index) +/* Emit a DQT marker */ +/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ +{ + JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index]; + int prec; + int i; + + if (qtbl == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index); + + prec = 0; + for (i = 0; i < DCTSIZE2; i++) { + if (qtbl->quantval[i] > 255) + prec = 1; + } + + if (! qtbl->sent_table) { + emit_marker(cinfo, M_DQT); + + emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2); + + emit_byte(cinfo, index + (prec<<4)); + + for (i = 0; i < DCTSIZE2; i++) { + /* The table entries must be emitted in zigzag order. */ + unsigned int qval = qtbl->quantval[jpeg_natural_order[i]]; + if (prec) + emit_byte(cinfo, (int) (qval >> 8)); + emit_byte(cinfo, (int) (qval & 0xFF)); + } + + qtbl->sent_table = TRUE; + } + + return prec; +} + + +LOCAL(void) +emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) +/* Emit a DHT marker */ +{ + JHUFF_TBL * htbl; + int length, i; + + if (is_ac) { + htbl = cinfo->ac_huff_tbl_ptrs[index]; + index += 0x10; /* output index has AC bit set */ + } else { + htbl = cinfo->dc_huff_tbl_ptrs[index]; + } + + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index); + + if (! htbl->sent_table) { + emit_marker(cinfo, M_DHT); + + length = 0; + for (i = 1; i <= 16; i++) + length += htbl->bits[i]; + + emit_2bytes(cinfo, length + 2 + 1 + 16); + emit_byte(cinfo, index); + + for (i = 1; i <= 16; i++) + emit_byte(cinfo, htbl->bits[i]); + + for (i = 0; i < length; i++) + emit_byte(cinfo, htbl->huffval[i]); + + htbl->sent_table = TRUE; + } +} + + +LOCAL(void) +emit_dac (j_compress_ptr cinfo) +/* Emit a DAC marker */ +/* Since the useful info is so small, we want to emit all the tables in */ +/* one DAC marker. Therefore this routine does its own scan of the table. */ +{ +#ifdef C_ARITH_CODING_SUPPORTED + char dc_in_use[NUM_ARITH_TBLS]; + char ac_in_use[NUM_ARITH_TBLS]; + int length, i; + jpeg_component_info *compptr; + + for (i = 0; i < NUM_ARITH_TBLS; i++) + dc_in_use[i] = ac_in_use[i] = 0; + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + dc_in_use[compptr->dc_tbl_no] = 1; + ac_in_use[compptr->ac_tbl_no] = 1; + } + + length = 0; + for (i = 0; i < NUM_ARITH_TBLS; i++) + length += dc_in_use[i] + ac_in_use[i]; + + emit_marker(cinfo, M_DAC); + + emit_2bytes(cinfo, length*2 + 2); + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + if (dc_in_use[i]) { + emit_byte(cinfo, i); + emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4)); + } + if (ac_in_use[i]) { + emit_byte(cinfo, i + 0x10); + emit_byte(cinfo, cinfo->arith_ac_K[i]); + } + } +#endif /* C_ARITH_CODING_SUPPORTED */ +} + + +LOCAL(void) +emit_dri (j_compress_ptr cinfo) +/* Emit a DRI marker */ +{ + emit_marker(cinfo, M_DRI); + + emit_2bytes(cinfo, 4); /* fixed length */ + + emit_2bytes(cinfo, (int) cinfo->restart_interval); +} + + +LOCAL(void) +emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) +/* Emit a SOF marker */ +{ + int ci; + jpeg_component_info *compptr; + + emit_marker(cinfo, code); + + emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ + + /* Make sure image isn't bigger than SOF field can handle */ + if ((long) cinfo->image_height > 65535L || + (long) cinfo->image_width > 65535L) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535); + + emit_byte(cinfo, cinfo->data_precision); + emit_2bytes(cinfo, (int) cinfo->image_height); + emit_2bytes(cinfo, (int) cinfo->image_width); + + emit_byte(cinfo, cinfo->num_components); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + emit_byte(cinfo, compptr->component_id); + emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor); + emit_byte(cinfo, compptr->quant_tbl_no); + } +} + + +LOCAL(void) +emit_sos (j_compress_ptr cinfo) +/* Emit a SOS marker */ +{ + int i, td, ta; + jpeg_component_info *compptr; + + emit_marker(cinfo, M_SOS); + + emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */ + + emit_byte(cinfo, cinfo->comps_in_scan); + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + emit_byte(cinfo, compptr->component_id); + td = compptr->dc_tbl_no; + ta = compptr->ac_tbl_no; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan; + * furthermore, Huffman coding of DC refinement uses no table at all. + * We emit 0 for unused field(s); this is recommended by the P&M text + * but does not seem to be specified in the standard. + */ + if (cinfo->Ss == 0) { + ta = 0; /* DC scan */ + if (cinfo->Ah != 0 && !cinfo->arith_code) + td = 0; /* no DC table either */ + } else { + td = 0; /* AC scan */ + } + } + emit_byte(cinfo, (td << 4) + ta); + } + + emit_byte(cinfo, cinfo->Ss); + emit_byte(cinfo, cinfo->Se); + emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al); +} + + +LOCAL(void) +emit_jfif_app0 (j_compress_ptr cinfo) +/* Emit a JFIF-compliant APP0 marker */ +{ + /* + * Length of APP0 block (2 bytes) + * Block ID (4 bytes - ASCII "JFIF") + * Zero byte (1 byte to terminate the ID string) + * Version Major, Minor (2 bytes - major first) + * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm) + * Xdpu (2 bytes - dots per unit horizontal) + * Ydpu (2 bytes - dots per unit vertical) + * Thumbnail X size (1 byte) + * Thumbnail Y size (1 byte) + */ + + emit_marker(cinfo, M_APP0); + + emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */ + + emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */ + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0x49); + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0); + emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */ + emit_byte(cinfo, cinfo->JFIF_minor_version); + emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ + emit_2bytes(cinfo, (int) cinfo->X_density); + emit_2bytes(cinfo, (int) cinfo->Y_density); + emit_byte(cinfo, 0); /* No thumbnail image */ + emit_byte(cinfo, 0); +} + + +LOCAL(void) +emit_adobe_app14 (j_compress_ptr cinfo) +/* Emit an Adobe APP14 marker */ +{ + /* + * Length of APP14 block (2 bytes) + * Block ID (5 bytes - ASCII "Adobe") + * Version Number (2 bytes - currently 100) + * Flags0 (2 bytes - currently 0) + * Flags1 (2 bytes - currently 0) + * Color transform (1 byte) + * + * Although Adobe TN 5116 mentions Version = 101, all the Adobe files + * now in circulation seem to use Version = 100, so that's what we write. + * + * We write the color transform byte as 1 if the JPEG color space is + * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with + * whether the encoder performed a transformation, which is pretty useless. + */ + + emit_marker(cinfo, M_APP14); + + emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */ + + emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */ + emit_byte(cinfo, 0x64); + emit_byte(cinfo, 0x6F); + emit_byte(cinfo, 0x62); + emit_byte(cinfo, 0x65); + emit_2bytes(cinfo, 100); /* Version */ + emit_2bytes(cinfo, 0); /* Flags0 */ + emit_2bytes(cinfo, 0); /* Flags1 */ + switch (cinfo->jpeg_color_space) { + case JCS_YCbCr: + emit_byte(cinfo, 1); /* Color transform = 1 */ + break; + case JCS_YCCK: + emit_byte(cinfo, 2); /* Color transform = 2 */ + break; + default: + emit_byte(cinfo, 0); /* Color transform = 0 */ + break; + } +} + + +/* + * These routines allow writing an arbitrary marker with parameters. + * The only intended use is to emit COM or APPn markers after calling + * write_file_header and before calling write_frame_header. + * Other uses are not guaranteed to produce desirable results. + * Counting the parameter bytes properly is the caller's responsibility. + */ + +METHODDEF(void) +write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +/* Emit an arbitrary marker header */ +{ + if (datalen > (unsigned int) 65533) /* safety check */ + ERREXIT(cinfo, JERR_BAD_LENGTH); + + emit_marker(cinfo, (JPEG_MARKER) marker); + + emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ +} + +METHODDEF(void) +write_marker_byte (j_compress_ptr cinfo, int val) +/* Emit one byte of marker parameters following write_marker_header */ +{ + emit_byte(cinfo, val); +} + + +/* + * Write datastream header. + * This consists of an SOI and optional APPn markers. + * We recommend use of the JFIF marker, but not the Adobe marker, + * when using YCbCr or grayscale data. The JFIF marker should NOT + * be used for any other JPEG colorspace. The Adobe marker is helpful + * to distinguish RGB, CMYK, and YCCK colorspaces. + * Note that an application can write additional header markers after + * jpeg_start_compress returns. + */ + +METHODDEF(void) +write_file_header (j_compress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + emit_marker(cinfo, M_SOI); /* first the SOI */ + + /* SOI is defined to reset restart interval to 0 */ + marker->last_restart_interval = 0; + + if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */ + emit_jfif_app0(cinfo); + if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ + emit_adobe_app14(cinfo); +} + + +/* + * Write frame header. + * This consists of DQT and SOFn markers. + * Note that we do not emit the SOF until we have emitted the DQT(s). + * This avoids compatibility problems with incorrect implementations that + * try to error-check the quant table numbers as soon as they see the SOF. + */ + +METHODDEF(void) +write_frame_header (j_compress_ptr cinfo) +{ + int ci, prec; + boolean is_baseline; + jpeg_component_info *compptr; + + /* Emit DQT for each quantization table. + * Note that emit_dqt() suppresses any duplicate tables. + */ + prec = 0; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prec += emit_dqt(cinfo, compptr->quant_tbl_no); + } + /* now prec is nonzero iff there are any 16-bit quant tables. */ + + /* Check for a non-baseline specification. + * Note we assume that Huffman table numbers won't be changed later. + */ + if (cinfo->arith_code || cinfo->progressive_mode || + cinfo->data_precision != 8) { + is_baseline = FALSE; + } else { + is_baseline = TRUE; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1) + is_baseline = FALSE; + } + if (prec && is_baseline) { + is_baseline = FALSE; + /* If it's baseline except for quantizer size, warn the user */ + TRACEMS(cinfo, 0, JTRC_16BIT_TABLES); + } + } + + /* Emit the proper SOF marker */ + if (cinfo->arith_code) { + emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ + } else { + if (cinfo->progressive_mode) + emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ + else if (is_baseline) + emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */ + else + emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ + } +} + + +/* + * Write scan header. + * This consists of DHT or DAC markers, optional DRI, and SOS. + * Compressed data will be written following the SOS. + */ + +METHODDEF(void) +write_scan_header (j_compress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + int i; + jpeg_component_info *compptr; + + if (cinfo->arith_code) { + /* Emit arith conditioning info. We may have some duplication + * if the file has multiple scans, but it's so small it's hardly + * worth worrying about. + */ + emit_dac(cinfo); + } else { + /* Emit Huffman tables. + * Note that emit_dht() suppresses any duplicate tables. + */ + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan */ + if (cinfo->Ss == 0) { + if (cinfo->Ah == 0) /* DC needs no table for refinement scan */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + } else { + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } else { + /* Sequential mode: need both DC and AC tables */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } + } + + /* Emit DRI if required --- note that DRI value could change for each scan. + * We avoid wasting space with unnecessary DRIs, however. + */ + if (cinfo->restart_interval != marker->last_restart_interval) { + emit_dri(cinfo); + marker->last_restart_interval = cinfo->restart_interval; + } + + emit_sos(cinfo); +} + + +/* + * Write datastream trailer. + */ + +METHODDEF(void) +write_file_trailer (j_compress_ptr cinfo) +{ + emit_marker(cinfo, M_EOI); +} + + +/* + * Write an abbreviated table-specification datastream. + * This consists of SOI, DQT and DHT tables, and EOI. + * Any table that is defined and not marked sent_table = TRUE will be + * emitted. Note that all tables will be marked sent_table = TRUE at exit. + */ + +METHODDEF(void) +write_tables_only (j_compress_ptr cinfo) +{ + int i; + + emit_marker(cinfo, M_SOI); + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if (cinfo->quant_tbl_ptrs[i] != NULL) + (void) emit_dqt(cinfo, i); + } + + if (! cinfo->arith_code) { + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if (cinfo->dc_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, FALSE); + if (cinfo->ac_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, TRUE); + } + } + + emit_marker(cinfo, M_EOI); +} + + +/* + * Initialize the marker writer module. + */ + +GLOBAL(void) +jinit_marker_writer (j_compress_ptr cinfo) +{ + my_marker_ptr marker; + + /* Create the subobject */ + marker = (my_marker_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_marker_writer)); + cinfo->marker = (struct jpeg_marker_writer *) marker; + /* Initialize method pointers */ + marker->pub.write_file_header = write_file_header; + marker->pub.write_frame_header = write_frame_header; + marker->pub.write_scan_header = write_scan_header; + marker->pub.write_file_trailer = write_file_trailer; + marker->pub.write_tables_only = write_tables_only; + marker->pub.write_marker_header = write_marker_header; + marker->pub.write_marker_byte = write_marker_byte; + /* Initialize private state */ + marker->last_restart_interval = 0; +} diff --git a/rosapps/lib/libjpeg/jcmaster.c b/rosapps/lib/libjpeg/jcmaster.c new file mode 100644 index 00000000000..aab4020b879 --- /dev/null +++ b/rosapps/lib/libjpeg/jcmaster.c @@ -0,0 +1,590 @@ +/* + * jcmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG compressor. + * These routines are concerned with parameter validation, initial setup, + * and inter-pass control (determining the number of passes and the work + * to be done in each pass). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef enum { + main_pass, /* input data, also do first output step */ + huff_opt_pass, /* Huffman code optimization pass */ + output_pass /* data output pass */ +} c_pass_type; + +typedef struct { + struct jpeg_comp_master pub; /* public fields */ + + c_pass_type pass_type; /* the type of the current pass */ + + int pass_number; /* # of passes completed */ + int total_passes; /* total # of passes needed */ + + int scan_number; /* current index in scan_info[] */ +} my_comp_master; + +typedef my_comp_master * my_master_ptr; + + +/* + * Support routines that do various essential calculations. + */ + +LOCAL(void) +initial_setup (j_compress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ + int ci; + jpeg_component_info *compptr; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Sanity check on image dimensions */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0 || cinfo->input_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* Width of an input scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Fill in the correct component_index value; don't rely on application */ + compptr->component_index = ci; + /* For compression, we never do DCT scaling. */ + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed (this flag isn't actually used for compression) */ + compptr->component_needed = TRUE; + } + + /* Compute number of fully interleaved MCU rows (number of times that + * main controller will call coefficient controller). + */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); +} + + +#ifdef C_MULTISCAN_FILES_SUPPORTED + +LOCAL(void) +validate_script (j_compress_ptr cinfo) +/* Verify that the scan script in cinfo->scan_info[] is valid; also + * determine whether it uses progressive JPEG, and set cinfo->progressive_mode. + */ +{ + const jpeg_scan_info * scanptr; + int scanno, ncomps, ci, coefi, thisi; + int Ss, Se, Ah, Al; + boolean component_sent[MAX_COMPONENTS]; +#ifdef C_PROGRESSIVE_SUPPORTED + int * last_bitpos_ptr; + int last_bitpos[MAX_COMPONENTS][DCTSIZE2]; + /* -1 until that coefficient has been seen; then last Al for it */ +#endif + + if (cinfo->num_scans <= 0) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0); + + /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; + * for progressive JPEG, no scan can have this. + */ + scanptr = cinfo->scan_info; + if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) { +#ifdef C_PROGRESSIVE_SUPPORTED + cinfo->progressive_mode = TRUE; + last_bitpos_ptr = & last_bitpos[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (coefi = 0; coefi < DCTSIZE2; coefi++) + *last_bitpos_ptr++ = -1; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + for (ci = 0; ci < cinfo->num_components; ci++) + component_sent[ci] = FALSE; + } + + for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) { + /* Validate component indexes */ + ncomps = scanptr->comps_in_scan; + if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN); + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (thisi < 0 || thisi >= cinfo->num_components) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + /* Components must appear in SOF order within each scan */ + if (ci > 0 && thisi <= scanptr->component_index[ci-1]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + } + /* Validate progression parameters */ + Ss = scanptr->Ss; + Se = scanptr->Se; + Ah = scanptr->Ah; + Al = scanptr->Al; + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that + * seems wrong: the upper bound ought to depend on data precision. + * Perhaps they really meant 0..N+1 for N-bit precision. + * Here we allow 0..10 for 8-bit data; Al larger than 10 results in + * out-of-range reconstructed DC values during the first DC scan, + * which might cause problems for some decoders. + */ +#if BITS_IN_JSAMPLE == 8 +#define MAX_AH_AL 10 +#else +#define MAX_AH_AL 13 +#endif + if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 || + Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + if (Ss == 0) { + if (Se != 0) /* DC and AC together not OK */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + if (ncomps != 1) /* AC scans must be for only one component */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + for (ci = 0; ci < ncomps; ci++) { + last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0]; + if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + for (coefi = Ss; coefi <= Se; coefi++) { + if (last_bitpos_ptr[coefi] < 0) { + /* first scan of this coefficient */ + if (Ah != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + /* not first scan */ + if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + last_bitpos_ptr[coefi] = Al; + } + } +#endif + } else { + /* For sequential JPEG, all progression parameters must be these: */ + if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + /* Make sure components are not sent twice */ + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (component_sent[thisi]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + component_sent[thisi] = TRUE; + } + } + } + + /* Now verify that everything got sent. */ + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + /* For progressive mode, we only check that at least some DC data + * got sent for each component; the spec does not require that all bits + * of all coefficients be transmitted. Would it be wiser to enforce + * transmission of all coefficient bits?? + */ + for (ci = 0; ci < cinfo->num_components; ci++) { + if (last_bitpos[ci][0] < 0) + ERREXIT(cinfo, JERR_MISSING_DATA); + } +#endif + } else { + for (ci = 0; ci < cinfo->num_components; ci++) { + if (! component_sent[ci]) + ERREXIT(cinfo, JERR_MISSING_DATA); + } + } +} + +#endif /* C_MULTISCAN_FILES_SUPPORTED */ + + +LOCAL(void) +select_scan_parameters (j_compress_ptr cinfo) +/* Set up the scan parameters for the current scan */ +{ + int ci; + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (cinfo->scan_info != NULL) { + /* Prepare for current scan --- the script is already validated */ + my_master_ptr master = (my_master_ptr) cinfo->master; + const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number; + + cinfo->comps_in_scan = scanptr->comps_in_scan; + for (ci = 0; ci < scanptr->comps_in_scan; ci++) { + cinfo->cur_comp_info[ci] = + &cinfo->comp_info[scanptr->component_index[ci]]; + } + cinfo->Ss = scanptr->Ss; + cinfo->Se = scanptr->Se; + cinfo->Ah = scanptr->Ah; + cinfo->Al = scanptr->Al; + } + else +#endif + { + /* Prepare for single sequential-JPEG scan containing all components */ + if (cinfo->num_components > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPS_IN_SCAN); + cinfo->comps_in_scan = cinfo->num_components; + for (ci = 0; ci < cinfo->num_components; ci++) { + cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci]; + } + cinfo->Ss = 0; + cinfo->Se = DCTSIZE2-1; + cinfo->Ah = 0; + cinfo->Al = 0; + } +} + + +LOCAL(void) +per_scan_setup (j_compress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = DCTSIZE; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } + + /* Convert restart specified in rows to actual MCU count. */ + /* Note that count must fit in 16 bits, so we provide limiting. */ + if (cinfo->restart_in_rows > 0) { + long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row; + cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L); + } +} + + +/* + * Per-pass setup. + * This is called at the beginning of each pass. We determine which modules + * will be active during this pass and give them appropriate start_pass calls. + * We also set is_last_pass to indicate whether any more passes will be + * required. + */ + +METHODDEF(void) +prepare_for_pass (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + switch (master->pass_type) { + case main_pass: + /* Initial pass: will collect input data, and do either Huffman + * optimization or data output for the first scan. + */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (! cinfo->raw_data_in) { + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->downsample->start_pass) (cinfo); + (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU); + } + (*cinfo->fdct->start_pass) (cinfo); + (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding); + (*cinfo->coef->start_pass) (cinfo, + (master->total_passes > 1 ? + JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + if (cinfo->optimize_coding) { + /* No immediate data output; postpone writing frame/scan headers */ + master->pub.call_pass_startup = FALSE; + } else { + /* Will write frame/scan headers at first jpeg_write_scanlines call */ + master->pub.call_pass_startup = TRUE; + } + break; +#ifdef ENTROPY_OPT_SUPPORTED + case huff_opt_pass: + /* Do Huffman optimization for a scan after the first one. */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) { + (*cinfo->entropy->start_pass) (cinfo, TRUE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + master->pub.call_pass_startup = FALSE; + break; + } + /* Special case: Huffman DC refinement scans need no Huffman table + * and therefore we can skip the optimization pass for them. + */ + master->pass_type = output_pass; + master->pass_number++; + /*FALLTHROUGH*/ +#endif + case output_pass: + /* Do a data-output pass. */ + /* We need not repeat per-scan setup if prior optimization pass did it. */ + if (! cinfo->optimize_coding) { + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + } + (*cinfo->entropy->start_pass) (cinfo, FALSE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + /* We emit frame/scan headers now */ + if (master->scan_number == 0) + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); + master->pub.call_pass_startup = FALSE; + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + } + + master->pub.is_last_pass = (master->pass_number == master->total_passes-1); + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->total_passes; + } +} + + +/* + * Special start-of-pass hook. + * This is called by jpeg_write_scanlines if call_pass_startup is TRUE. + * In single-pass processing, we need this hook because we don't want to + * write frame/scan headers during jpeg_start_compress; we want to let the + * application write COM markers etc. between jpeg_start_compress and the + * jpeg_write_scanlines loop. + * In multi-pass processing, this routine is not used. + */ + +METHODDEF(void) +pass_startup (j_compress_ptr cinfo) +{ + cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */ + + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); +} + + +/* + * Finish up at end of pass. + */ + +METHODDEF(void) +finish_pass_master (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* The entropy coder always needs an end-of-pass call, + * either to analyze statistics or to flush its output buffer. + */ + (*cinfo->entropy->finish_pass) (cinfo); + + /* Update state for next pass */ + switch (master->pass_type) { + case main_pass: + /* next pass is either output of scan 0 (after optimization) + * or output of scan 1 (if no optimization). + */ + master->pass_type = output_pass; + if (! cinfo->optimize_coding) + master->scan_number++; + break; + case huff_opt_pass: + /* next pass is always output of current scan */ + master->pass_type = output_pass; + break; + case output_pass: + /* next pass is either optimization or output of next scan */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + master->scan_number++; + break; + } + + master->pass_number++; +} + + +/* + * Initialize master compression control. + */ + +GLOBAL(void) +jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_comp_master)); + cinfo->master = (struct jpeg_comp_master *) master; + master->pub.prepare_for_pass = prepare_for_pass; + master->pub.pass_startup = pass_startup; + master->pub.finish_pass = finish_pass_master; + master->pub.is_last_pass = FALSE; + + /* Validate parameters, determine derived values */ + initial_setup(cinfo); + + if (cinfo->scan_info != NULL) { +#ifdef C_MULTISCAN_FILES_SUPPORTED + validate_script(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + cinfo->num_scans = 1; + } + + if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */ + cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ + + /* Initialize my private state */ + if (transcode_only) { + /* no main pass in transcoding */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + else + master->pass_type = output_pass; + } else { + /* for normal compression, first pass is always this type: */ + master->pass_type = main_pass; + } + master->scan_number = 0; + master->pass_number = 0; + if (cinfo->optimize_coding) + master->total_passes = cinfo->num_scans * 2; + else + master->total_passes = cinfo->num_scans; +} diff --git a/rosapps/lib/libjpeg/jcomapi.c b/rosapps/lib/libjpeg/jcomapi.c new file mode 100644 index 00000000000..9b1fa7568a6 --- /dev/null +++ b/rosapps/lib/libjpeg/jcomapi.c @@ -0,0 +1,106 @@ +/* + * jcomapi.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface routines that are used for both + * compression and decompression. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Abort processing of a JPEG compression or decompression operation, + * but don't destroy the object itself. + * + * For this, we merely clean up all the nonpermanent memory pools. + * Note that temp files (virtual arrays) are not allowed to belong to + * the permanent pool, so we will be able to close all temp files here. + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL(void) +jpeg_abort (j_common_ptr cinfo) +{ + int pool; + + /* Do nothing if called on a not-initialized or destroyed JPEG object. */ + if (cinfo->mem == NULL) + return; + + /* Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) { + (*cinfo->mem->free_pool) (cinfo, pool); + } + + /* Reset overall state for possible reuse of object */ + if (cinfo->is_decompressor) { + cinfo->global_state = DSTATE_START; + /* Try to keep application from accessing now-deleted marker list. + * A bit kludgy to do it here, but this is the most central place. + */ + ((j_decompress_ptr) cinfo)->marker_list = NULL; + } else { + cinfo->global_state = CSTATE_START; + } +} + + +/* + * Destruction of a JPEG object. + * + * Everything gets deallocated except the master jpeg_compress_struct itself + * and the error manager struct. Both of these are supplied by the application + * and must be freed, if necessary, by the application. (Often they are on + * the stack and so don't need to be freed anyway.) + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL(void) +jpeg_destroy (j_common_ptr cinfo) +{ + /* We need only tell the memory manager to release everything. */ + /* NB: mem pointer is NULL if memory mgr failed to initialize. */ + if (cinfo->mem != NULL) + (*cinfo->mem->self_destruct) (cinfo); + cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ + cinfo->global_state = 0; /* mark it destroyed */ +} + + +/* + * Convenience routines for allocating quantization and Huffman tables. + * (Would jutils.c be a more reasonable place to put these?) + */ + +GLOBAL(JQUANT_TBL *) +jpeg_alloc_quant_table (j_common_ptr cinfo) +{ + JQUANT_TBL *tbl; + + tbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} + + +GLOBAL(JHUFF_TBL *) +jpeg_alloc_huff_table (j_common_ptr cinfo) +{ + JHUFF_TBL *tbl; + + tbl = (JHUFF_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} diff --git a/rosapps/lib/libjpeg/jconfig.h b/rosapps/lib/libjpeg/jconfig.h new file mode 100644 index 00000000000..44e5c52ee55 --- /dev/null +++ b/rosapps/lib/libjpeg/jconfig.h @@ -0,0 +1,47 @@ +/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#ifndef HAVE_STDLIB_H +#define HAVE_STDLIB_H +#endif +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +/* Define "boolean" as unsigned char, not int, per Windows custom */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ + + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE /* optional */ +#define USE_SETMODE /* Microsoft has setmode() */ +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/rosapps/lib/libjpeg/jcparam.c b/rosapps/lib/libjpeg/jcparam.c new file mode 100644 index 00000000000..6fc48f53653 --- /dev/null +++ b/rosapps/lib/libjpeg/jcparam.c @@ -0,0 +1,610 @@ +/* + * jcparam.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains optional default-setting code for the JPEG compressor. + * Applications do not have to use this file, but those that don't use it + * must know a lot more about the innards of the JPEG code. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Quantization table setup routines + */ + +GLOBAL(void) +jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, boolean force_baseline) +/* Define a quantization table equal to the basic_table times + * a scale factor (given as a percentage). + * If force_baseline is TRUE, the computed quantization table entries + * are limited to 1..255 for JPEG baseline compatibility. + */ +{ + JQUANT_TBL ** qtblptr; + int i; + long temp; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl); + + qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; + + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo); + + for (i = 0; i < DCTSIZE2; i++) { + temp = ((long) basic_table[i] * scale_factor + 50L) / 100L; + /* limit the values to the valid range */ + if (temp <= 0L) temp = 1L; + if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ + if (force_baseline && temp > 255L) + temp = 255L; /* limit to baseline range if requested */ + (*qtblptr)->quantval[i] = (UINT16) temp; + } + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*qtblptr)->sent_table = FALSE; +} + + +GLOBAL(void) +jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, + boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables + * and a straight percentage-scaling quality scale. In most cases it's better + * to use jpeg_set_quality (below); this entry point is provided for + * applications that insist on a linear percentage scaling. + */ +{ + /* These are the sample quantization tables given in JPEG spec section K.1. + * The spec says that the values given produce "good" quality, and + * when divided by 2, "very good" quality. + */ + static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 + }; + static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }; + + /* Set up two quantization tables using the specified scaling */ + jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, + scale_factor, force_baseline); + jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, + scale_factor, force_baseline); +} + + +GLOBAL(int) +jpeg_quality_scaling (int quality) +/* Convert a user-specified quality rating to a percentage scaling factor + * for an underlying quantization table, using our recommended scaling curve. + * The input 'quality' factor should be 0 (terrible) to 100 (very good). + */ +{ + /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */ + if (quality <= 0) quality = 1; + if (quality > 100) quality = 100; + + /* The basic table is used as-is (scaling 100) for a quality of 50. + * Qualities 50..100 are converted to scaling percentage 200 - 2*Q; + * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table + * to make all the table entries 1 (hence, minimum quantization loss). + * Qualities 1..50 are converted to scaling percentage 5000/Q. + */ + if (quality < 50) + quality = 5000 / quality; + else + quality = 200 - quality*2; + + return quality; +} + + +GLOBAL(void) +jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables. + * This is the standard quality-adjusting entry point for typical user + * interfaces; only those who want detailed control over quantization tables + * would use the preceding three routines directly. + */ +{ + /* Convert user 0-100 rating to percentage scaling */ + quality = jpeg_quality_scaling(quality); + + /* Set up standard quality tables */ + jpeg_set_linear_quality(cinfo, quality, force_baseline); +} + + +/* + * Huffman table setup routines + */ + +LOCAL(void) +add_huff_table (j_compress_ptr cinfo, + JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) +/* Define a Huffman table */ +{ + int nsymbols, len; + + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + /* Copy the number-of-symbols-of-each-code-length counts */ + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + + /* Validate the counts. We do this here mainly so we can copy the right + * number of symbols from the val[] array, without risking marching off + * the end of memory. jchuff.c will do a more thorough test later. + */ + nsymbols = 0; + for (len = 1; len <= 16; len++) + nsymbols += bits[len]; + if (nsymbols < 1 || nsymbols > 256) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + + MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8)); + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*htblptr)->sent_table = FALSE; +} + + +LOCAL(void) +std_huff_tables (j_compress_ptr cinfo) +/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ +/* IMPORTANT: these are only valid for 8-bit data precision! */ +{ + static const UINT8 bits_dc_luminance[17] = + { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_luminance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_dc_chrominance[17] = + { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_chrominance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_ac_luminance[17] = + { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; + static const UINT8 val_ac_luminance[] = + { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + static const UINT8 bits_ac_chrominance[17] = + { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; + static const UINT8 val_ac_chrominance[] = + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0], + bits_dc_luminance, val_dc_luminance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0], + bits_ac_luminance, val_ac_luminance); + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1], + bits_dc_chrominance, val_dc_chrominance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1], + bits_ac_chrominance, val_ac_chrominance); +} + + +/* + * Default parameter setup for compression. + * + * Applications that don't choose to use this routine must do their + * own setup of all these parameters. Alternately, you can call this + * to establish defaults and then alter parameters selectively. This + * is the recommended approach since, if we add any new parameters, + * your code will still work (they'll be set to reasonable defaults). + */ + +GLOBAL(void) +jpeg_set_defaults (j_compress_ptr cinfo) +{ + int i; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Allocate comp_info array large enough for maximum component count. + * Array is made permanent in case application wants to compress + * multiple images at same param settings. + */ + if (cinfo->comp_info == NULL) + cinfo->comp_info = (jpeg_component_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + MAX_COMPONENTS * SIZEOF(jpeg_component_info)); + + /* Initialize everything not dependent on the color space */ + + cinfo->data_precision = BITS_IN_JSAMPLE; + /* Set up two quantization tables using default quality of 75 */ + jpeg_set_quality(cinfo, 75, TRUE); + /* Set up two Huffman tables */ + std_huff_tables(cinfo); + + /* Initialize default arithmetic coding conditioning */ + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + + /* Default is no multiple-scan output */ + cinfo->scan_info = NULL; + cinfo->num_scans = 0; + + /* Expect normal source image, not raw downsampled data */ + cinfo->raw_data_in = FALSE; + + /* Use Huffman coding, not arithmetic coding, by default */ + cinfo->arith_code = FALSE; + + /* By default, don't do extra passes to optimize entropy coding */ + cinfo->optimize_coding = FALSE; + /* The standard Huffman tables are only valid for 8-bit data precision. + * If the precision is higher, force optimization on so that usable + * tables will be computed. This test can be removed if default tables + * are supplied that are valid for the desired precision. + */ + if (cinfo->data_precision > 8) + cinfo->optimize_coding = TRUE; + + /* By default, use the simpler non-cosited sampling alignment */ + cinfo->CCIR601_sampling = FALSE; + + /* No input smoothing */ + cinfo->smoothing_factor = 0; + + /* DCT algorithm preference */ + cinfo->dct_method = JDCT_DEFAULT; + + /* No restart markers */ + cinfo->restart_interval = 0; + cinfo->restart_in_rows = 0; + + /* Fill in default JFIF marker parameters. Note that whether the marker + * will actually be written is determined by jpeg_set_colorspace. + * + * By default, the library emits JFIF version code 1.01. + * An application that wants to emit JFIF 1.02 extension markers should set + * JFIF_minor_version to 2. We could probably get away with just defaulting + * to 1.02, but there may still be some decoders in use that will complain + * about that; saying 1.01 should minimize compatibility problems. + */ + cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */ + cinfo->JFIF_minor_version = 1; + cinfo->density_unit = 0; /* Pixel size is unknown by default */ + cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ + cinfo->Y_density = 1; + + /* Choose JPEG colorspace based on input space, set defaults accordingly */ + + jpeg_default_colorspace(cinfo); +} + + +/* + * Select an appropriate JPEG colorspace for in_color_space. + */ + +GLOBAL(void) +jpeg_default_colorspace (j_compress_ptr cinfo) +{ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + break; + case JCS_RGB: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_YCbCr: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_CMYK: + jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */ + break; + case JCS_YCCK: + jpeg_set_colorspace(cinfo, JCS_YCCK); + break; + case JCS_UNKNOWN: + jpeg_set_colorspace(cinfo, JCS_UNKNOWN); + break; + default: + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + } +} + + +/* + * Set the JPEG colorspace, and choose colorspace-dependent default values. + */ + +GLOBAL(void) +jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) +{ + jpeg_component_info * compptr; + int ci; + +#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \ + (compptr = &cinfo->comp_info[index], \ + compptr->component_id = (id), \ + compptr->h_samp_factor = (hsamp), \ + compptr->v_samp_factor = (vsamp), \ + compptr->quant_tbl_no = (quant), \ + compptr->dc_tbl_no = (dctbl), \ + compptr->ac_tbl_no = (actbl) ) + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* For all colorspaces, we use Q and Huff tables 0 for luminance components, + * tables 1 for chrominance components. + */ + + cinfo->jpeg_color_space = colorspace; + + cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */ + cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */ + + switch (colorspace) { + case JCS_GRAYSCALE: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 1; + /* JFIF specifies component ID 1 */ + SET_COMP(0, 1, 1,1, 0, 0,0); + break; + case JCS_RGB: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */ + cinfo->num_components = 3; + SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0); + SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0); + SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0); + break; + case JCS_YCbCr: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 3; + /* JFIF specifies component IDs 1,2,3 */ + /* We default to 2x2 subsamples of chrominance */ + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + break; + case JCS_CMYK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */ + cinfo->num_components = 4; + SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0); + SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0); + SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0); + SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0); + break; + case JCS_YCCK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */ + cinfo->num_components = 4; + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 2,2, 0, 0,0); + break; + case JCS_UNKNOWN: + cinfo->num_components = cinfo->input_components; + if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + for (ci = 0; ci < cinfo->num_components; ci++) { + SET_COMP(ci, ci, 1,1, 0, 0,0); + } + break; + default: + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + } +} + + +#ifdef C_PROGRESSIVE_SUPPORTED + +LOCAL(jpeg_scan_info *) +fill_a_scan (jpeg_scan_info * scanptr, int ci, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for specified component */ +{ + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + return scanptr; +} + +LOCAL(jpeg_scan_info *) +fill_scans (jpeg_scan_info * scanptr, int ncomps, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for each component */ +{ + int ci; + + for (ci = 0; ci < ncomps; ci++) { + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } + return scanptr; +} + +LOCAL(jpeg_scan_info *) +fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) +/* Support routine: generate interleaved DC scan if possible, else N scans */ +{ + int ci; + + if (ncomps <= MAX_COMPS_IN_SCAN) { + /* Single interleaved DC scan */ + scanptr->comps_in_scan = ncomps; + for (ci = 0; ci < ncomps; ci++) + scanptr->component_index[ci] = ci; + scanptr->Ss = scanptr->Se = 0; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } else { + /* Noninterleaved DC scan for each component */ + scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al); + } + return scanptr; +} + + +/* + * Create a recommended progressive-JPEG script. + * cinfo->num_components and cinfo->jpeg_color_space must be correct. + */ + +GLOBAL(void) +jpeg_simple_progression (j_compress_ptr cinfo) +{ + int ncomps = cinfo->num_components; + int nscans; + jpeg_scan_info * scanptr; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Figure space needed for script. Calculation must match code below! */ + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + nscans = 10; + } else { + /* All-purpose script for other color spaces. */ + if (ncomps > MAX_COMPS_IN_SCAN) + nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ + else + nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ + } + + /* Allocate space for script. + * We need to put it in the permanent pool in case the application performs + * multiple compressions without changing the settings. To avoid a memory + * leak if jpeg_simple_progression is called repeatedly for the same JPEG + * object, we try to re-use previously allocated space, and we allocate + * enough space to handle YCbCr even if initially asked for grayscale. + */ + if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) { + cinfo->script_space_size = MAX(nscans, 10); + cinfo->script_space = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + cinfo->script_space_size * SIZEOF(jpeg_scan_info)); + } + scanptr = cinfo->script_space; + cinfo->scan_info = scanptr; + cinfo->num_scans = nscans; + + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + /* Initial DC scan */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + /* Initial AC scan: get some luma data out in a hurry */ + scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2); + /* Chroma data is too small to be worth expending many scans on */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1); + /* Complete spectral selection for luma AC */ + scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2); + /* Refine next bit of luma AC */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1); + /* Finish DC successive approximation */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + /* Finish AC successive approximation */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0); + /* Luma bottom bit comes last since it's usually largest scan */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0); + } else { + /* All-purpose script for other color spaces. */ + /* Successive approximation first pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2); + scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2); + /* Successive approximation second pass */ + scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1); + /* Successive approximation final pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0); + } +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jcphuff.c b/rosapps/lib/libjpeg/jcphuff.c new file mode 100644 index 00000000000..07f9178b01c --- /dev/null +++ b/rosapps/lib/libjpeg/jcphuff.c @@ -0,0 +1,833 @@ +/* + * jcphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines for progressive JPEG. + * + * We do not support output suspension in this module, since the library + * currently does not allow multiple-scan files to be written with output + * suspension. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jchuff.c */ + +#ifdef C_PROGRESSIVE_SUPPORTED + +/* Expanded entropy encoder object for progressive Huffman encoding. */ + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + /* Mode flag: TRUE for optimization, FALSE for actual data output */ + boolean gather_statistics; + + /* Bit-level coding status. + * next_output_byte/free_in_buffer are local copies of cinfo->dest fields. + */ + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */ + + /* Coding status for DC components */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ + + /* Coding status for AC components */ + int ac_tbl_no; /* the table number of the single component */ + unsigned int EOBRUN; /* run length of EOBs */ + unsigned int BE; /* # of buffered correction bits before MCU */ + char * bit_buffer; /* buffer for correction bits (1 per char) */ + /* packing correction bits tightly would save some space but cost time... */ + + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan). + * Since any one scan codes only DC or only AC, we only need one set + * of tables, not one for DC and one for AC. + */ + c_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + /* Statistics tables for optimization; again, one set is enough */ + long * count_ptrs[NUM_HUFF_TBLS]; +} phuff_entropy_encoder; + +typedef phuff_entropy_encoder * phuff_entropy_ptr; + +/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit + * buffer can hold. Larger sizes may slightly improve compression, but + * 1000 is already well into the realm of overkill. + * The minimum safe size is 64 bits. + */ + +#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */ + +/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32. + * We assume that int right shift is unsigned if INT32 right shift is, + * which should be safe. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS int ishift_temp; +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +/* Forward declarations */ +METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo)); +METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); + + +/* + * Initialize for a Huffman-compressed scan using progressive JPEG. + */ + +METHODDEF(void) +start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + + entropy->cinfo = cinfo; + entropy->gather_statistics = gather_statistics; + + is_DC_band = (cinfo->Ss == 0); + + /* We assume jcmaster.c already validated the scan parameters. */ + + /* Select execution routines */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_first; + else + entropy->pub.encode_mcu = encode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_refine; + else { + entropy->pub.encode_mcu = encode_mcu_AC_refine; + /* AC refinement needs a correction bit buffer */ + if (entropy->bit_buffer == NULL) + entropy->bit_buffer = (char *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + MAX_CORR_BITS * SIZEOF(char)); + } + } + if (gather_statistics) + entropy->pub.finish_pass = finish_pass_gather_phuff; + else + entropy->pub.finish_pass = finish_pass_phuff; + + /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1 + * for AC coefficients. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Initialize DC predictions to 0 */ + entropy->last_dc_val[ci] = 0; + /* Get table index */ + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + } else { + entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; + } + if (gather_statistics) { + /* Check for invalid table index */ + /* (make_c_derived_tbl does this in the other path) */ + if (tbl < 0 || tbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->count_ptrs[tbl] == NULL) + entropy->count_ptrs[tbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); + } else { + /* Compute derived values for Huffman table */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, + & entropy->derived_tbls[tbl]); + } + } + + /* Initialize AC stuff */ + entropy->EOBRUN = 0; + entropy->BE = 0; + + /* Initialize bit buffer to empty */ + entropy->put_buffer = 0; + entropy->put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* Outputting bytes to the file. + * NB: these must be called only when actually outputting, + * that is, entropy->gather_statistics == FALSE. + */ + +/* Emit a byte */ +#define emit_byte(entropy,val) \ + { *(entropy)->next_output_byte++ = (JOCTET) (val); \ + if (--(entropy)->free_in_buffer == 0) \ + dump_buffer(entropy); } + + +LOCAL(void) +dump_buffer (phuff_entropy_ptr entropy) +/* Empty the output buffer; we do not support suspension in this module. */ +{ + struct jpeg_destination_mgr * dest = entropy->cinfo->dest; + + if (! (*dest->empty_output_buffer) (entropy->cinfo)) + ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND); + /* After a successful buffer dump, must reset buffer pointers */ + entropy->next_output_byte = dest->next_output_byte; + entropy->free_in_buffer = dest->free_in_buffer; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(void) +emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) +/* Emit some bits, unless we are in gather mode */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = entropy->put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); + + if (entropy->gather_statistics) + return; /* do nothing if we're only getting stats */ + + put_buffer &= (((INT32) 1)<put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(entropy, c); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(entropy, 0); + } + put_buffer <<= 8; + put_bits -= 8; + } + + entropy->put_buffer = put_buffer; /* update variables */ + entropy->put_bits = put_bits; +} + + +LOCAL(void) +flush_bits (phuff_entropy_ptr entropy) +{ + emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */ + entropy->put_buffer = 0; /* and reset bit-buffer to empty */ + entropy->put_bits = 0; +} + + +/* + * Emit (or just count) a Huffman symbol. + */ + +INLINE +LOCAL(void) +emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) +{ + if (entropy->gather_statistics) + entropy->count_ptrs[tbl_no][symbol]++; + else { + c_derived_tbl * tbl = entropy->derived_tbls[tbl_no]; + emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]); + } +} + + +/* + * Emit bits from a correction bit buffer. + */ + +LOCAL(void) +emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, + unsigned int nbits) +{ + if (entropy->gather_statistics) + return; /* no real work */ + + while (nbits > 0) { + emit_bits(entropy, (unsigned int) (*bufstart), 1); + bufstart++; + nbits--; + } +} + + +/* + * Emit any pending EOBRUN symbol. + */ + +LOCAL(void) +emit_eobrun (phuff_entropy_ptr entropy) +{ + register int temp, nbits; + + if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ + temp = entropy->EOBRUN; + nbits = 0; + while ((temp >>= 1)) + nbits++; + /* safety check: shouldn't happen given limited correction-bit buffer */ + if (nbits > 14) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); + + emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4); + if (nbits) + emit_bits(entropy, entropy->EOBRUN, nbits); + + entropy->EOBRUN = 0; + + /* Emit any buffered correction bits */ + emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE); + entropy->BE = 0; + } +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(void) +emit_restart (phuff_entropy_ptr entropy, int restart_num) +{ + int ci; + + emit_eobrun(entropy); + + if (! entropy->gather_statistics) { + flush_bits(entropy); + emit_byte(entropy, 0xFF); + emit_byte(entropy, JPEG_RST0 + restart_num); + } + + if (entropy->cinfo->Ss == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++) + entropy->last_dc_val[ci] = 0; + } else { + /* Re-initialize all AC-related fields to 0 */ + entropy->EOBRUN = 0; + entropy->BE = 0; + } +} + + +/* + * MCU encoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + int blkn, ci; + int Al = cinfo->Al; + JBLOCKROW block; + jpeg_component_info * compptr; + ISHIFT_TEMPS + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + + /* Compute the DC value after the required point transform by Al. + * This is simply an arithmetic right shift. + */ + temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al); + + /* DC differences are figured on the point-transformed values. */ + temp = temp2 - entropy->last_dc_val[ci]; + entropy->last_dc_val[ci] = temp2; + + /* Encode the DC coefficient difference per section G.1.2.1 */ + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count/emit the Huffman-coded symbol for the number of bits */ + emit_symbol(entropy, compptr->dc_tbl_no, nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + emit_bits(entropy, (unsigned int) temp2, nbits); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + register int r, k; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */ + + r = 0; /* r = run length of zeros */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = (*block)[jpeg_natural_order[k]]) == 0) { + r++; + continue; + } + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value; so the code is + * interwoven with finding the abs value (temp) and output bits (temp2). + */ + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ + temp2 = ~temp; + } else { + temp >>= Al; /* apply the point transform */ + temp2 = temp; + } + /* Watch out for case that nonzero coef is zero after point transform */ + if (temp == 0) { + r++; + continue; + } + + /* Emit any pending EOBRUN */ + if (entropy->EOBRUN > 0) + emit_eobrun(entropy); + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + emit_bits(entropy, (unsigned int) temp2, nbits); + + r = 0; /* reset zero run length */ + } + + if (r > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + if (entropy->EOBRUN == 0x7FFF) + emit_eobrun(entropy); /* force it out to avoid overflow */ + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF(boolean) +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + int blkn; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* We simply emit the Al'th bit of the DC coefficient value. */ + temp = (*block)[0]; + emit_bits(entropy, (unsigned int) (temp >> Al), 1); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC successive approximation refinement scan. + */ + +METHODDEF(boolean) +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + register int r, k; + int EOB; + char *BR_buffer; + unsigned int BR; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + int absvalues[DCTSIZE2]; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* It is convenient to make a pre-pass to determine the transformed + * coefficients' absolute values and the EOB position. + */ + EOB = 0; + for (k = cinfo->Ss; k <= Se; k++) { + temp = (*block)[jpeg_natural_order[k]]; + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value. + */ + if (temp < 0) + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + absvalues[k] = temp; /* save abs value for main pass */ + if (temp == 1) + EOB = k; /* EOB = index of last newly-nonzero coef */ + } + + /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */ + + r = 0; /* r = run length of zeros */ + BR = 0; /* BR = count of buffered bits added now */ + BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = absvalues[k]) == 0) { + r++; + continue; + } + + /* Emit any required ZRLs, but not if they can be folded into EOB */ + while (r > 15 && k <= EOB) { + /* emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + /* Emit ZRL */ + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + /* Emit buffered correction bits that must be associated with ZRL */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + } + + /* If the coef was previously nonzero, it only needs a correction bit. + * NOTE: a straight translation of the spec's figure G.7 would suggest + * that we also need to test r > 15. But if r > 15, we can only get here + * if k > EOB, which implies that this coefficient is not 1. + */ + if (temp > 1) { + /* The correction bit is the next bit of the absolute value. */ + BR_buffer[BR++] = (char) (temp & 1); + continue; + } + + /* Emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1); + + /* Emit output bit for newly-nonzero coef */ + temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1; + emit_bits(entropy, (unsigned int) temp, 1); + + /* Emit buffered correction bits that must be associated with this code */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + r = 0; /* reset zero run length */ + } + + if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + entropy->BE += BR; /* concat my correction bits to older ones */ + /* We force out the EOB if we risk either: + * 1. overflow of the EOB counter; + * 2. overflow of the correction bit buffer during the next MCU. + */ + if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1)) + emit_eobrun(entropy); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed progressive scan. + */ + +METHODDEF(void) +finish_pass_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Flush out any buffered data */ + emit_eobrun(entropy); + flush_bits(entropy); + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did[NUM_HUFF_TBLS]; + + /* Flush out buffered data (all we care about is counting the EOB symbol) */ + emit_eobrun(entropy); + + is_DC_band = (cinfo->Ss == 0); + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did, SIZEOF(did)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + } else { + tbl = compptr->ac_tbl_no; + } + if (! did[tbl]) { + if (is_DC_band) + htblptr = & cinfo->dc_huff_tbl_ptrs[tbl]; + else + htblptr = & cinfo->ac_huff_tbl_ptrs[tbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]); + did[tbl] = TRUE; + } + } +} + + +/* + * Module initialization routine for progressive Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_phuff_encoder (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_phuff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + entropy->count_ptrs[i] = NULL; + } + entropy->bit_buffer = NULL; /* needed only in AC refinement scan */ +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jcprepct.c b/rosapps/lib/libjpeg/jcprepct.c new file mode 100644 index 00000000000..fa93333db20 --- /dev/null +++ b/rosapps/lib/libjpeg/jcprepct.c @@ -0,0 +1,354 @@ +/* + * jcprepct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the compression preprocessing controller. + * This controller manages the color conversion, downsampling, + * and edge expansion steps. + * + * Most of the complexity here is associated with buffering input rows + * as required by the downsampler. See the comments at the head of + * jcsample.c for the downsampler's needs. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* At present, jcsample.c can request context rows only for smoothing. + * In the future, we might also need context rows for CCIR601 sampling + * or other more-complex downsampling procedures. The code to support + * context rows should be compiled only if needed. + */ +#ifdef INPUT_SMOOTHING_SUPPORTED +#define CONTEXT_ROWS_SUPPORTED +#endif + + +/* + * For the simple (no-context-row) case, we just need to buffer one + * row group's worth of pixels for the downsampling step. At the bottom of + * the image, we pad to a full row group by replicating the last pixel row. + * The downsampler's last output row is then replicated if needed to pad + * out to a full iMCU row. + * + * When providing context rows, we must buffer three row groups' worth of + * pixels. Three row groups are physically allocated, but the row pointer + * arrays are made five row groups high, with the extra pointers above and + * below "wrapping around" to point to the last and first real row groups. + * This allows the downsampler to access the proper context rows. + * At the top and bottom of the image, we create dummy context rows by + * copying the first or last real pixel row. This copying could be avoided + * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the + * trouble on the compression side. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_prep_controller pub; /* public fields */ + + /* Downsampling input buffer. This buffer holds color-converted data + * until we have enough to do a downsample step. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + JDIMENSION rows_to_go; /* counts rows remaining in source image */ + int next_buf_row; /* index of next row to store in color_buf */ + +#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ + int this_row_group; /* starting row index of group to process */ + int next_buf_stop; /* downsample when we reach this index */ +#endif +} my_prep_controller; + +typedef my_prep_controller * my_prep_ptr; + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + + if (pass_mode != JBUF_PASS_THRU) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Initialize total-height counter for detecting bottom of image */ + prep->rows_to_go = cinfo->image_height; + /* Mark the conversion buffer empty */ + prep->next_buf_row = 0; +#ifdef CONTEXT_ROWS_SUPPORTED + /* Preset additional state variables for context mode. + * These aren't used in non-context mode, so we needn't test which mode. + */ + prep->this_row_group = 0; + /* Set next_buf_stop to stop after two row groups have been read in. */ + prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; +#endif +} + + +/* + * Expand an image vertically from height input_rows to height output_rows, + * by duplicating the bottom row. + */ + +LOCAL(void) +expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, + int input_rows, int output_rows) +{ + register int row; + + for (row = input_rows; row < output_rows; row++) { + jcopy_sample_rows(image_data, input_rows-1, image_data, row, + 1, num_cols); + } +} + + +/* + * Process some data in the simple no-context case. + * + * Preprocessor output data is counted in "row groups". A row group + * is defined to be v_samp_factor sample rows of each component. + * Downsampling will produce this much data from each max_v_samp_factor + * input rows. + */ + +METHODDEF(void) +pre_process_data (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + JDIMENSION inrows; + jpeg_component_info * compptr; + + while (*in_row_ctr < in_rows_avail && + *out_row_group_ctr < out_row_groups_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = cinfo->max_v_samp_factor - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + /* If at bottom of image, pad to fill the conversion buffer. */ + if (prep->rows_to_go == 0 && + prep->next_buf_row < cinfo->max_v_samp_factor) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, cinfo->max_v_samp_factor); + } + prep->next_buf_row = cinfo->max_v_samp_factor; + } + /* If we've filled the conversion buffer, empty it. */ + if (prep->next_buf_row == cinfo->max_v_samp_factor) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, (JDIMENSION) 0, + output_buf, *out_row_group_ctr); + prep->next_buf_row = 0; + (*out_row_group_ctr)++; + } + /* If at bottom of image, pad the output to a full iMCU height. + * Note we assume the caller is providing a one-iMCU-height output buffer! + */ + if (prep->rows_to_go == 0 && + *out_row_group_ctr < out_row_groups_avail) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + expand_bottom_edge(output_buf[ci], + compptr->width_in_blocks * DCTSIZE, + (int) (*out_row_group_ctr * compptr->v_samp_factor), + (int) (out_row_groups_avail * compptr->v_samp_factor)); + } + *out_row_group_ctr = out_row_groups_avail; + break; /* can exit outer loop without test */ + } + } +} + + +#ifdef CONTEXT_ROWS_SUPPORTED + +/* + * Process some data in the context case. + */ + +METHODDEF(void) +pre_process_context (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + int buf_height = cinfo->max_v_samp_factor * 3; + JDIMENSION inrows; + + while (*out_row_group_ctr < out_row_groups_avail) { + if (*in_row_ctr < in_rows_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = prep->next_buf_stop - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + /* Pad at top of image, if first time through */ + if (prep->rows_to_go == cinfo->image_height) { + for (ci = 0; ci < cinfo->num_components; ci++) { + int row; + for (row = 1; row <= cinfo->max_v_samp_factor; row++) { + jcopy_sample_rows(prep->color_buf[ci], 0, + prep->color_buf[ci], -row, + 1, cinfo->image_width); + } + } + } + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + } else { + /* Return for more data, unless we are at the bottom of the image. */ + if (prep->rows_to_go != 0) + break; + /* When at bottom of image, pad to fill the conversion buffer. */ + if (prep->next_buf_row < prep->next_buf_stop) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, prep->next_buf_stop); + } + prep->next_buf_row = prep->next_buf_stop; + } + } + /* If we've gotten enough data, downsample a row group. */ + if (prep->next_buf_row == prep->next_buf_stop) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, + (JDIMENSION) prep->this_row_group, + output_buf, *out_row_group_ctr); + (*out_row_group_ctr)++; + /* Advance pointers with wraparound as necessary. */ + prep->this_row_group += cinfo->max_v_samp_factor; + if (prep->this_row_group >= buf_height) + prep->this_row_group = 0; + if (prep->next_buf_row >= buf_height) + prep->next_buf_row = 0; + prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; + } + } +} + + +/* + * Create the wrapped-around downsampling input buffer needed for context mode. + */ + +LOCAL(void) +create_context_buffer (j_compress_ptr cinfo) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int rgroup_height = cinfo->max_v_samp_factor; + int ci, i; + jpeg_component_info * compptr; + JSAMPARRAY true_buffer, fake_buffer; + + /* Grab enough space for fake row pointers for all the components; + * we need five row groups' worth of pointers for each component. + */ + fake_buffer = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (cinfo->num_components * 5 * rgroup_height) * + SIZEOF(JSAMPROW)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate the actual buffer space (3 row groups) for this component. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + true_buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) (3 * rgroup_height)); + /* Copy true buffer row pointers into the middle of the fake row array */ + MEMCOPY(fake_buffer + rgroup_height, true_buffer, + 3 * rgroup_height * SIZEOF(JSAMPROW)); + /* Fill in the above and below wraparound pointers */ + for (i = 0; i < rgroup_height; i++) { + fake_buffer[i] = true_buffer[2 * rgroup_height + i]; + fake_buffer[4 * rgroup_height + i] = true_buffer[i]; + } + prep->color_buf[ci] = fake_buffer + rgroup_height; + fake_buffer += 5 * rgroup_height; /* point to space for next component */ + } +} + +#endif /* CONTEXT_ROWS_SUPPORTED */ + + +/* + * Initialize preprocessing controller. + */ + +GLOBAL(void) +jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_prep_ptr prep; + int ci; + jpeg_component_info * compptr; + + if (need_full_buffer) /* safety check */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + prep = (my_prep_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_prep_controller)); + cinfo->prep = (struct jpeg_c_prep_controller *) prep; + prep->pub.start_pass = start_pass_prep; + + /* Allocate the color conversion buffer. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + if (cinfo->downsample->need_context_rows) { + /* Set up to provide context rows */ +#ifdef CONTEXT_ROWS_SUPPORTED + prep->pub.pre_process_data = pre_process_context; + create_context_buffer(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* No context, just make it tall enough for one row group */ + prep->pub.pre_process_data = pre_process_data; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/rosapps/lib/libjpeg/jcsample.c b/rosapps/lib/libjpeg/jcsample.c new file mode 100644 index 00000000000..212ec8757c4 --- /dev/null +++ b/rosapps/lib/libjpeg/jcsample.c @@ -0,0 +1,519 @@ +/* + * jcsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains downsampling routines. + * + * Downsampling input data is counted in "row groups". A row group + * is defined to be max_v_samp_factor pixel rows of each component, + * from which the downsampler produces v_samp_factor sample rows. + * A single row group is processed in each call to the downsampler module. + * + * The downsampler is responsible for edge-expansion of its output data + * to fill an integral number of DCT blocks horizontally. The source buffer + * may be modified if it is helpful for this purpose (the source buffer is + * allocated wide enough to correspond to the desired output width). + * The caller (the prep controller) is responsible for vertical padding. + * + * The downsampler may request "context rows" by setting need_context_rows + * during startup. In this case, the input arrays will contain at least + * one row group's worth of pixels above and below the passed-in data; + * the caller will create dummy rows at image top and bottom by replicating + * the first or last real pixel row. + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + * + * The downsampling algorithm used here is a simple average of the source + * pixels covered by the output pixel. The hi-falutin sampling literature + * refers to this as a "box filter". In general the characteristics of a box + * filter are not very good, but for the specific cases we normally use (1:1 + * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not + * nearly so bad. If you intend to use other sampling ratios, you'd be well + * advised to improve this code. + * + * A simple input-smoothing capability is provided. This is mainly intended + * for cleaning up color-dithered GIF input files (if you find it inadequate, + * we suggest using an external filtering program such as pnmconvol). When + * enabled, each input pixel P is replaced by a weighted sum of itself and its + * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, + * where SF = (smoothing_factor / 1024). + * Currently, smoothing is only supported for 2h2v sampling factors. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to downsample a single component */ +typedef JMETHOD(void, downsample1_ptr, + (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data)); + +/* Private subobject */ + +typedef struct { + struct jpeg_downsampler pub; /* public fields */ + + /* Downsampling method pointers, one per component */ + downsample1_ptr methods[MAX_COMPONENTS]; +} my_downsampler; + +typedef my_downsampler * my_downsample_ptr; + + +/* + * Initialize for a downsampling pass. + */ + +METHODDEF(void) +start_pass_downsample (j_compress_ptr cinfo) +{ + /* no work for now */ +} + + +/* + * Expand a component horizontally from width input_cols to width output_cols, + * by duplicating the rightmost samples. + */ + +LOCAL(void) +expand_right_edge (JSAMPARRAY image_data, int num_rows, + JDIMENSION input_cols, JDIMENSION output_cols) +{ + register JSAMPROW ptr; + register JSAMPLE pixval; + register int count; + int row; + int numcols = (int) (output_cols - input_cols); + + if (numcols > 0) { + for (row = 0; row < num_rows; row++) { + ptr = image_data[row] + input_cols; + pixval = ptr[-1]; /* don't need GETJSAMPLE() here */ + for (count = numcols; count > 0; count--) + *ptr++ = pixval; + } + } +} + + +/* + * Do downsampling for a whole row group (all components). + * + * In this version we simply downsample each component independently. + */ + +METHODDEF(void) +sep_downsample (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) +{ + my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample; + int ci; + jpeg_component_info * compptr; + JSAMPARRAY in_ptr, out_ptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + in_ptr = input_buf[ci] + in_row_index; + out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor); + (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr); + } +} + + +/* + * Downsample pixel values of a single component. + * One row group is processed per call. + * This version handles arbitrary integral sampling ratios, without smoothing. + * Note that this version is not actually used for customary sampling ratios. + */ + +METHODDEF(void) +int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v; + JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */ + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JSAMPROW inptr, outptr; + INT32 outvalue; + + h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor; + v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor; + numpix = h_expand * v_expand; + numpix2 = numpix/2; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * h_expand); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + for (outcol = 0, outcol_h = 0; outcol < output_cols; + outcol++, outcol_h += h_expand) { + outvalue = 0; + for (v = 0; v < v_expand; v++) { + inptr = input_data[inrow+v] + outcol_h; + for (h = 0; h < h_expand; h++) { + outvalue += (INT32) GETJSAMPLE(*inptr++); + } + } + *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix); + } + inrow += v_expand; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * without smoothing. + */ + +METHODDEF(void) +fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + /* Copy the data */ + jcopy_sample_rows(input_data, 0, output_data, 0, + cinfo->max_v_samp_factor, cinfo->image_width); + /* Edge-expand */ + expand_right_edge(output_data, cinfo->max_v_samp_factor, + cinfo->image_width, compptr->width_in_blocks * DCTSIZE); +} + + +/* + * Downsample pixel values of a single component. + * This version handles the common case of 2:1 horizontal and 1:1 vertical, + * without smoothing. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF(void) +h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + bias = 0; /* bias = 0,1,0,1,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + + bias) >> 1); + bias ^= 1; /* 0=>1, 1=>0 */ + inptr += 2; + } + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * without smoothing. + */ + +METHODDEF(void) +h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + bias = 1; /* bias = 1,2,1,2,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + + bias) >> 2); + bias ^= 3; /* 1=>2, 2=>1 */ + inptr0 += 2; inptr1 += 2; + } + inrow += 2; + } +} + + +#ifdef INPUT_SMOOTHING_SUPPORTED + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * with smoothing. One row of context is required. + */ + +METHODDEF(void) +h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols * 2); + + /* We don't bother to form the individual "smoothed" input pixel values; + * we can directly compute the output which is the average of the four + * smoothed values. Each of the four member pixels contributes a fraction + * (1-8*SF) to its own smoothed image and a fraction SF to each of the three + * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final + * output. The four corner-adjacent neighbor pixels contribute a fraction + * SF to just one smoothed pixel, or SF/4 to the final output; while the + * eight edge-adjacent neighbors contribute SF to each of two smoothed + * pixels, or SF/2 overall. In order to use integer arithmetic, these + * factors are scaled by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */ + neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */ + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + above_ptr = input_data[inrow-1]; + below_ptr = input_data[inrow+2]; + + /* Special case for first column: pretend column -1 is same as column 0 */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]); + neighsum += neighsum; + neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + /* sum of pixels directly mapped to this output element */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + /* sum of edge-neighbor pixels */ + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]); + /* The edge-neighbors count twice as much as corner-neighbors */ + neighsum += neighsum; + /* Add in the corner-neighbors */ + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]); + /* form final output scaled up by 2^16 */ + membersum = membersum * memberscale + neighsum * neighscale; + /* round, descale and output it */ + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]); + neighsum += neighsum; + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + inrow += 2; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * with smoothing. One row of context is required. + */ + +METHODDEF(void) +fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + int colsum, lastcolsum, nextcolsum; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols); + + /* Each of the eight neighbor pixels contributes a fraction SF to the + * smoothed pixel, while the main pixel contributes (1-8*SF). In order + * to use integer arithmetic, these factors are multiplied by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */ + neighscale = cinfo->smoothing_factor * 64; /* scaled SF */ + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + above_ptr = input_data[outrow-1]; + below_ptr = input_data[outrow+1]; + + /* Special case for first column */ + colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) + + GETJSAMPLE(*inptr); + membersum = GETJSAMPLE(*inptr++); + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = colsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + membersum = GETJSAMPLE(*inptr++); + above_ptr++; below_ptr++; + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + colsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + } +} + +#endif /* INPUT_SMOOTHING_SUPPORTED */ + + +/* + * Module initialization routine for downsampling. + * Note that we must select a routine for each component. + */ + +GLOBAL(void) +jinit_downsampler (j_compress_ptr cinfo) +{ + my_downsample_ptr downsample; + int ci; + jpeg_component_info * compptr; + boolean smoothok = TRUE; + + downsample = (my_downsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_downsampler)); + cinfo->downsample = (struct jpeg_downsampler *) downsample; + downsample->pub.start_pass = start_pass_downsample; + downsample->pub.downsample = sep_downsample; + downsample->pub.need_context_rows = FALSE; + + if (cinfo->CCIR601_sampling) + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* Verify we can handle the sampling factors, and set up method pointers */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = fullsize_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = fullsize_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { + smoothok = FALSE; + downsample->methods[ci] = h2v1_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = h2v2_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = h2v2_downsample; + } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 && + (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) { + smoothok = FALSE; + downsample->methods[ci] = int_downsample; + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + } + +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor && !smoothok) + TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL); +#endif +} diff --git a/rosapps/lib/libjpeg/jctrans.c b/rosapps/lib/libjpeg/jctrans.c new file mode 100644 index 00000000000..0e6d70769df --- /dev/null +++ b/rosapps/lib/libjpeg/jctrans.c @@ -0,0 +1,388 @@ +/* + * jctrans.c + * + * Copyright (C) 1995-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding compression, + * that is, writing raw DCT coefficient arrays to an output JPEG file. + * The routines in jcapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(void) transencode_master_selection + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); +LOCAL(void) transencode_coef_controller + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); + + +/* + * Compression initialization for writing raw-coefficient data. + * Before calling this, all parameters and a data destination must be set up. + * Call jpeg_finish_compress() to actually write the data. + * + * The number of passed virtual arrays must match cinfo->num_components. + * Note that the virtual arrays need not be filled or even realized at + * the time write_coefficients is called; indeed, if the virtual arrays + * were requested from this compression object's memory manager, they + * typically will be realized during this routine and filled afterwards. + */ + +GLOBAL(void) +jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Mark all tables to be written */ + jpeg_suppress_tables(cinfo, FALSE); + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + transencode_master_selection(cinfo, coef_arrays); + /* Wait for jpeg_finish_compress() call */ + cinfo->next_scanline = 0; /* so jpeg_write_marker works */ + cinfo->global_state = CSTATE_WRCOEFS; +} + + +/* + * Initialize the compression object with default parameters, + * then copy from the source object all parameters needed for lossless + * transcoding. Parameters that can be varied without loss (such as + * scan script and Huffman optimization) are left in their default states. + */ + +GLOBAL(void) +jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo) +{ + JQUANT_TBL ** qtblptr; + jpeg_component_info *incomp, *outcomp; + JQUANT_TBL *c_quant, *slot_quant; + int tblno, ci, coefi; + + /* Safety check to ensure start_compress not called yet. */ + if (dstinfo->global_state != CSTATE_START) + ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state); + /* Copy fundamental image dimensions */ + dstinfo->image_width = srcinfo->image_width; + dstinfo->image_height = srcinfo->image_height; + dstinfo->input_components = srcinfo->num_components; + dstinfo->in_color_space = srcinfo->jpeg_color_space; + /* Initialize all parameters to default values */ + jpeg_set_defaults(dstinfo); + /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. + * Fix it to get the right header markers for the image colorspace. + */ + jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); + dstinfo->data_precision = srcinfo->data_precision; + dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; + /* Copy the source's quantization tables. */ + for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { + if (srcinfo->quant_tbl_ptrs[tblno] != NULL) { + qtblptr = & dstinfo->quant_tbl_ptrs[tblno]; + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo); + MEMCOPY((*qtblptr)->quantval, + srcinfo->quant_tbl_ptrs[tblno]->quantval, + SIZEOF((*qtblptr)->quantval)); + (*qtblptr)->sent_table = FALSE; + } + } + /* Copy the source's per-component info. + * Note we assume jpeg_set_defaults has allocated the dest comp_info array. + */ + dstinfo->num_components = srcinfo->num_components; + if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS) + ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components, + MAX_COMPONENTS); + for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info; + ci < dstinfo->num_components; ci++, incomp++, outcomp++) { + outcomp->component_id = incomp->component_id; + outcomp->h_samp_factor = incomp->h_samp_factor; + outcomp->v_samp_factor = incomp->v_samp_factor; + outcomp->quant_tbl_no = incomp->quant_tbl_no; + /* Make sure saved quantization table for component matches the qtable + * slot. If not, the input file re-used this qtable slot. + * IJG encoder currently cannot duplicate this. + */ + tblno = outcomp->quant_tbl_no; + if (tblno < 0 || tblno >= NUM_QUANT_TBLS || + srcinfo->quant_tbl_ptrs[tblno] == NULL) + ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno); + slot_quant = srcinfo->quant_tbl_ptrs[tblno]; + c_quant = incomp->quant_table; + if (c_quant != NULL) { + for (coefi = 0; coefi < DCTSIZE2; coefi++) { + if (c_quant->quantval[coefi] != slot_quant->quantval[coefi]) + ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); + } + } + /* Note: we do not copy the source's Huffman table assignments; + * instead we rely on jpeg_set_colorspace to have made a suitable choice. + */ + } + /* Also copy JFIF version and resolution information, if available. + * Strictly speaking this isn't "critical" info, but it's nearly + * always appropriate to copy it if available. In particular, + * if the application chooses to copy JFIF 1.02 extension markers from + * the source file, we need to copy the version to make sure we don't + * emit a file that has 1.02 extensions but a claimed version of 1.01. + * We will *not*, however, copy version info from mislabeled "2.01" files. + */ + if (srcinfo->saw_JFIF_marker) { + if (srcinfo->JFIF_major_version == 1) { + dstinfo->JFIF_major_version = srcinfo->JFIF_major_version; + dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version; + } + dstinfo->density_unit = srcinfo->density_unit; + dstinfo->X_density = srcinfo->X_density; + dstinfo->Y_density = srcinfo->Y_density; + } +} + + +/* + * Master selection of compression modules for transcoding. + * This substitutes for jcinit.c's initialization of the full compressor. + */ + +LOCAL(void) +transencode_master_selection (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + /* Although we don't actually use input_components for transcoding, + * jcmaster.c's initial_setup will complain if input_components is 0. + */ + cinfo->input_components = 1; + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, TRUE /* transcode only */); + + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* We need a special coefficient buffer controller. */ + transencode_coef_controller(cinfo, coef_arrays); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI, JFIF) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} + + +/* + * The rest of this file is a special implementation of the coefficient + * buffer controller. This is similar to jccoefct.c, but it handles only + * output from presupplied virtual arrays. Furthermore, we generate any + * dummy padding blocks on-the-fly rather than expecting them to be present + * in the arrays. + */ + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* Virtual block array for each component. */ + jvirt_barray_ptr * whole_image; + + /* Workspace for constructing dummy blocks at right/bottom edges. */ + JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +LOCAL(void) +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + if (pass_mode != JBUF_CRANK_DEST) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); +} + + +/* + * Process some data. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF(boolean) +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, blockcnt; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yindex+yoffset < compptr->last_row_height) { + /* Fill in pointers to real blocks in this row */ + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < blockcnt; xindex++) + MCU_buffer[blkn++] = buffer_ptr++; + } else { + /* At bottom of image, need a whole row of dummy blocks */ + xindex = 0; + } + /* Fill in any dummy blocks needed in this row. + * Dummy blocks are filled in the same way as in jccoefct.c: + * all zeroes in the AC entries, DC entries equal to previous + * block's DC value. The init routine has already zeroed the + * AC entries, so we need only set the DC entries correctly. + */ + for (; xindex < compptr->MCU_width; xindex++) { + MCU_buffer[blkn] = coef->dummy_buffer[blkn]; + MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0]; + blkn++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +/* + * Initialize coefficient buffer controller. + * + * Each passed coefficient array must be the right size for that + * coefficient: width_in_blocks wide and height_in_blocks high, + * with unitheight at least v_samp_factor. + */ + +LOCAL(void) +transencode_coef_controller (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + my_coef_ptr coef; + JBLOCKROW buffer; + int i; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + coef->pub.compress_data = compress_output; + + /* Save pointer to virtual arrays */ + coef->whole_image = coef_arrays; + + /* Allocate and pre-zero space for dummy DCT blocks. */ + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->dummy_buffer[i] = buffer + i; + } +} diff --git a/rosapps/lib/libjpeg/jdapimin.c b/rosapps/lib/libjpeg/jdapimin.c new file mode 100644 index 00000000000..6d4a675883f --- /dev/null +++ b/rosapps/lib/libjpeg/jdapimin.c @@ -0,0 +1,499 @@ +/* + * jdapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-decompression case or the + * transcoding-only case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jdapistd.c. But also see jcomapi.c for routines + * shared by compression and decompression, and jdtrans.c for the transcoding + * case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef HAVE_MMX_INTEL_MNEMONICS +int MMXAvailable; +static int mmxsupport(); +#endif + +#ifdef HAVE_SSE2_INTEL_MNEMONICS +int SSE2Available = 0; +static int sse2support(); +#endif + + +/* + * Initialization of a JPEG decompression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL(void) +jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) +{ + int i; + +#ifdef HAVE_MMX_INTEL_MNEMONICS + static int cpuidDetected = 0; + + if(!cpuidDetected) + { + MMXAvailable = mmxsupport(); + +#ifdef HAVE_SSE2_INTEL_MNEMONICS + /* only do the sse2 support check if mmx is supported (so + we know the processor supports cpuid) */ + if (MMXAvailable) + SSE2Available = sse2support(); +#endif + + cpuidDetected = 1; + } +#endif + + /* For debugging purposes, zero the whole master structure. + * But error manager pointer is already there, so save and restore it. + */ + + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_decompress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ + MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); + cinfo->err = err; + cinfo->client_data = client_data; + } + cinfo->is_decompressor = TRUE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->src = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + /* Initialize marker processor so application can override methods + * for COM, APPn markers before calling jpeg_read_header. + */ + cinfo->marker_list = NULL; + jinit_marker_reader(cinfo); + + /* And initialize the overall input controller. */ + jinit_input_controller(cinfo); + + /* OK, I'm ready */ + cinfo->global_state = DSTATE_START; +} + + +/* + * Destruction of a JPEG decompression object + */ + +GLOBAL(void) +jpeg_destroy_decompress (j_decompress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG decompression operation, + * but don't destroy the object itself. + */ + +GLOBAL(void) +jpeg_abort_decompress (j_decompress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + +/* + * Set default decompression parameters. + */ + +LOCAL(void) +default_decompress_parms (j_decompress_ptr cinfo) +{ + /* Guess the input colorspace, and set output colorspace accordingly. */ + /* (Wish JPEG committee had provided a real way to specify this...) */ + /* Note application may override our guesses. */ + switch (cinfo->num_components) { + case 1: + cinfo->jpeg_color_space = JCS_GRAYSCALE; + cinfo->out_color_space = JCS_GRAYSCALE; + break; + + case 3: + if (cinfo->saw_JFIF_marker) { + cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */ + } else if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_RGB; + break; + case 1: + cinfo->jpeg_color_space = JCS_YCbCr; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + break; + } + } else { + /* Saw no special markers, try to guess from the component IDs */ + int cid0 = cinfo->comp_info[0].component_id; + int cid1 = cinfo->comp_info[1].component_id; + int cid2 = cinfo->comp_info[2].component_id; + + if (cid0 == 1 && cid1 == 2 && cid2 == 3) + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + else if (cid0 == 82 && cid1 == 71 && cid2 == 66) + cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ + else { + TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + } + } + /* Always guess RGB is proper output colorspace. */ + cinfo->out_color_space = JCS_RGB; + break; + + case 4: + if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_CMYK; + break; + case 2: + cinfo->jpeg_color_space = JCS_YCCK; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ + break; + } + } else { + /* No special markers, assume straight CMYK. */ + cinfo->jpeg_color_space = JCS_CMYK; + } + cinfo->out_color_space = JCS_CMYK; + break; + + default: + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->out_color_space = JCS_UNKNOWN; + break; + } + + /* Set defaults for other decompression parameters. */ + cinfo->scale_num = 1; /* 1:1 scaling */ + cinfo->scale_denom = 1; + cinfo->output_gamma = 1.0; + cinfo->buffered_image = FALSE; + cinfo->raw_data_out = FALSE; + cinfo->dct_method = JDCT_DEFAULT; + cinfo->do_fancy_upsampling = TRUE; + cinfo->do_block_smoothing = TRUE; + cinfo->quantize_colors = FALSE; + /* We set these in case application only sets quantize_colors. */ + cinfo->dither_mode = JDITHER_FS; +#ifdef QUANT_2PASS_SUPPORTED + cinfo->two_pass_quantize = TRUE; +#else + cinfo->two_pass_quantize = FALSE; +#endif + cinfo->desired_number_of_colors = 256; + cinfo->colormap = NULL; + /* Initialize for no mode change in buffered-image mode. */ + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; +} + + +/* + * Decompression startup: read start of JPEG datastream to see what's there. + * Need only initialize JPEG object and supply a data source before calling. + * + * This routine will read as far as the first SOS marker (ie, actual start of + * compressed data), and will save all tables and parameters in the JPEG + * object. It will also initialize the decompression parameters to default + * values, and finally return JPEG_HEADER_OK. On return, the application may + * adjust the decompression parameters and then call jpeg_start_decompress. + * (Or, if the application only wanted to determine the image parameters, + * the data need not be decompressed. In that case, call jpeg_abort or + * jpeg_destroy to release any temporary space.) + * If an abbreviated (tables only) datastream is presented, the routine will + * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + * re-use the JPEG object to read the abbreviated image datastream(s). + * It is unnecessary (but OK) to call jpeg_abort in this case. + * The JPEG_SUSPENDED return code only occurs if the data source module + * requests suspension of the decompressor. In this case the application + * should load more source data and then re-call jpeg_read_header to resume + * processing. + * If a non-suspending data source is used and require_image is TRUE, then the + * return code need not be inspected since only JPEG_HEADER_OK is possible. + * + * This routine is now just a front end to jpeg_consume_input, with some + * extra error checking. + */ + +GLOBAL(int) +jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) +{ + int retcode; + + if (cinfo->global_state != DSTATE_START && + cinfo->global_state != DSTATE_INHEADER) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + retcode = jpeg_consume_input(cinfo); + + switch (retcode) { + case JPEG_REACHED_SOS: + retcode = JPEG_HEADER_OK; + break; + case JPEG_REACHED_EOI: + if (require_image) /* Complain if application wanted an image */ + ERREXIT(cinfo, JERR_NO_IMAGE); + /* Reset to start state; it would be safer to require the application to + * call jpeg_abort, but we can't change it now for compatibility reasons. + * A side effect is to free any temporary memory (there shouldn't be any). + */ + jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */ + retcode = JPEG_HEADER_TABLES_ONLY; + break; + case JPEG_SUSPENDED: + /* no work */ + break; + } + + return retcode; +} + + +/* + * Consume data in advance of what the decompressor requires. + * This can be called at any time once the decompressor object has + * been created and a data source has been set up. + * + * This routine is essentially a state machine that handles a couple + * of critical state-transition actions, namely initial setup and + * transition from header scanning to ready-for-start_decompress. + * All the actual input is done via the input controller's consume_input + * method. + */ + +GLOBAL(int) +jpeg_consume_input (j_decompress_ptr cinfo) +{ + int retcode = JPEG_SUSPENDED; + + /* NB: every possible DSTATE value should be listed in this switch */ + switch (cinfo->global_state) { + case DSTATE_START: + /* Start-of-datastream actions: reset appropriate modules */ + (*cinfo->inputctl->reset_input_controller) (cinfo); + /* Initialize application's data source module */ + (*cinfo->src->init_source) (cinfo); + cinfo->global_state = DSTATE_INHEADER; + /*FALLTHROUGH*/ + case DSTATE_INHEADER: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */ + /* Set up default parameters based on header data */ + default_decompress_parms(cinfo); + /* Set global state: ready for start_decompress */ + cinfo->global_state = DSTATE_READY; + } + break; + case DSTATE_READY: + /* Can't advance past first SOS until start_decompress is called */ + retcode = JPEG_REACHED_SOS; + break; + case DSTATE_PRELOAD: + case DSTATE_PRESCAN: + case DSTATE_SCANNING: + case DSTATE_RAW_OK: + case DSTATE_BUFIMAGE: + case DSTATE_BUFPOST: + case DSTATE_STOPPING: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + break; + default: + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + return retcode; +} + + +/* + * Have we finished reading the input file? + */ + +GLOBAL(boolean) +jpeg_input_complete (j_decompress_ptr cinfo) +{ + /* Check for valid jpeg object */ + if (cinfo->global_state < DSTATE_START || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->eoi_reached; +} + + +/* + * Is there more than one scan? + */ + +GLOBAL(boolean) +jpeg_has_multiple_scans (j_decompress_ptr cinfo) +{ + /* Only valid after jpeg_read_header completes */ + if (cinfo->global_state < DSTATE_READY || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->has_multiple_scans; +} + + +/* + * Finish JPEG decompression. + * + * This will normally just verify the file trailer and release temp storage. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_finish_decompress (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) { + /* Terminate final pass of non-buffered mode */ + if (cinfo->output_scanline < cinfo->output_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state == DSTATE_BUFIMAGE) { + /* Finishing after a buffered-image operation */ + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state != DSTATE_STOPPING) { + /* STOPPING = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read until EOI */ + while (! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + /* Do final cleanup */ + (*cinfo->src->term_source) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); + return TRUE; +} + + +#ifdef HAVE_MMX_INTEL_MNEMONICS + + +static int mmxsupport() +{ + int mmx_supported = 0; + + _asm { + pushfd //Save Eflag to stack + pop eax //Get Eflag from stack into eax + mov ecx, eax //Make another copy of Eflag in ecx + xor eax, 0x200000 //Toggle ID bit in Eflag [i.e. bit(21)] + push eax //Save modified Eflag back to stack + + popfd //Restored modified value back to Eflag reg + pushfd //Save Eflag to stack + pop eax //Get Eflag from stack + xor eax, ecx //Compare the new Eflag with the original Eflag + jz NOT_SUPPORTED //If the same, CPUID instruction is not supported, + //skip following instructions and jump to + //NOT_SUPPORTED label + + xor eax, eax //Set eax to zero + + cpuid + + cmp eax, 1 //make sure eax return non-zero value + jl NOT_SUPPORTED //If eax is zero, mmx not supported + + xor eax, eax //set eax to zero + inc eax //Now increment eax to 1. This instruction is + //faster than the instruction "mov eax, 1" + + cpuid + + and edx, 0x00800000 //mask out all bits but mmx bit(24) + cmp edx, 0 // 0 = mmx not supported + jz NOT_SUPPORTED // non-zero = Yes, mmx IS supported + + mov mmx_supported, 1 //set return value to 1 + +NOT_SUPPORTED: + mov eax, mmx_supported //move return value to eax + + } + + return mmx_supported; +} +#endif + +#ifdef HAVE_SSE2_INTEL_MNEMONICS + +static int sse2support() +{ + int sse2available = 0; + int my_edx; + _asm + { + mov eax, 01 + cpuid + mov my_edx, edx + } + if (my_edx & (0x1 << 26)) + sse2available = 1; + else sse2available = 2; + + return sse2available; +} + +#endif + diff --git a/rosapps/lib/libjpeg/jdapistd.c b/rosapps/lib/libjpeg/jdapistd.c new file mode 100644 index 00000000000..c8e3fa0c35d --- /dev/null +++ b/rosapps/lib/libjpeg/jdapistd.c @@ -0,0 +1,275 @@ +/* + * jdapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-decompression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_decompress, it will end up linking in the entire decompressor. + * We thus must separate this file from jdapimin.c to avoid linking the + * whole decompression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo)); + + +/* + * Decompression initialization. + * jpeg_read_header must be completed before calling this. + * + * If a multipass operating mode was selected, this will do all but the + * last pass, and thus may take a great deal of time. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_start_decompress (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize master control, select active modules */ + jinit_master_decompress(cinfo); + if (cinfo->buffered_image) { + /* No more work here; expecting jpeg_start_output next */ + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; + } + cinfo->global_state = DSTATE_PRELOAD; + } + if (cinfo->global_state == DSTATE_PRELOAD) { + /* If file has multiple scans, absorb them all into the coef buffer */ + if (cinfo->inputctl->has_multiple_scans) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return FALSE; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* jdmaster underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + } + cinfo->output_scan_number = cinfo->input_scan_number; + } else if (cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any dummy output passes, and set up for the final pass */ + return output_pass_setup(cinfo); +} + + +/* + * Set up for an output pass, and perform any dummy pass(es) needed. + * Common subroutine for jpeg_start_decompress and jpeg_start_output. + * Entry: global_state = DSTATE_PRESCAN only if previously suspended. + * Exit: If done, returns TRUE and sets global_state for proper output mode. + * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. + */ + +LOCAL(boolean) +output_pass_setup (j_decompress_ptr cinfo) +{ + if (cinfo->global_state != DSTATE_PRESCAN) { + /* First call: do pass setup */ + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; + cinfo->global_state = DSTATE_PRESCAN; + } + /* Loop over any required dummy passes */ + while (cinfo->master->is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Crank through the dummy pass */ + while (cinfo->output_scanline < cinfo->output_height) { + JDIMENSION last_scanline; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* Process some data */ + last_scanline = cinfo->output_scanline; + (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, + &cinfo->output_scanline, (JDIMENSION) 0); + if (cinfo->output_scanline == last_scanline) + return FALSE; /* No progress made, must suspend */ + } + /* Finish up dummy pass, and set up for another one */ + (*cinfo->master->finish_output_pass) (cinfo); + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } + /* Ready for application to drive output pass through + * jpeg_read_scanlines or jpeg_read_raw_data. + */ + cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; + return TRUE; +} + + +/* + * Read some scanlines of data from the JPEG decompressor. + * + * The return value will be the number of lines actually read. + * This may be less than the number requested in several cases, + * including bottom of image, data source suspension, and operating + * modes that emit multiple scanlines at a time. + * + * Note: we warn about excess calls to jpeg_read_scanlines() since + * this likely signals an application programmer error. However, + * an oversize buffer (max_lines > scanlines remaining) is not an error. + */ + +GLOBAL(JDIMENSION) +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION max_lines) +{ + JDIMENSION row_ctr; + + if (cinfo->global_state != DSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Process some data */ + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); + cinfo->output_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to read raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL(JDIMENSION) +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION max_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != DSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Verify that at least one iMCU row can be returned. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; + if (max_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Decompress directly into user's buffer. */ + if (! (*cinfo->coef->decompress_data) (cinfo, data)) + return 0; /* suspension forced, can do nothing more */ + + /* OK, we processed one iMCU row. */ + cinfo->output_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} + + +/* Additional entry points for buffered-image mode. */ + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Initialize for an output pass in buffered-image mode. + */ + +GLOBAL(boolean) +jpeg_start_output (j_decompress_ptr cinfo, int scan_number) +{ + if (cinfo->global_state != DSTATE_BUFIMAGE && + cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Limit scan number to valid range */ + if (scan_number <= 0) + scan_number = 1; + if (cinfo->inputctl->eoi_reached && + scan_number > cinfo->input_scan_number) + scan_number = cinfo->input_scan_number; + cinfo->output_scan_number = scan_number; + /* Perform any dummy output passes, and set up for the real pass */ + return output_pass_setup(cinfo); +} + + +/* + * Finish up after an output pass in buffered-image mode. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_finish_output (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { + /* Terminate this pass. */ + /* We do not require the whole pass to have been completed. */ + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_BUFPOST; + } else if (cinfo->global_state != DSTATE_BUFPOST) { + /* BUFPOST = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read markers looking for SOS or EOI */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jdatadst.c b/rosapps/lib/libjpeg/jdatadst.c new file mode 100644 index 00000000000..a8f6fb0e025 --- /dev/null +++ b/rosapps/lib/libjpeg/jdatadst.c @@ -0,0 +1,151 @@ +/* + * jdatadst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains compression data destination routines for the case of + * emitting JPEG data to a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * destination manager. + * IMPORTANT: we assume that fwrite() will correctly transcribe an array of + * JOCTETs into 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data destination object for stdio output */ + +typedef struct { + struct jpeg_destination_mgr pub; /* public fields */ + + FILE * outfile; /* target stream */ + JOCTET * buffer; /* start of buffer */ +} my_destination_mgr; + +typedef my_destination_mgr * my_dest_ptr; + +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ + + +/* + * Initialize destination --- called by jpeg_start_compress + * before any data is actually written. + */ + +METHODDEF(void) +init_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + + +/* + * Empty the output buffer --- called whenever buffer fills up. + * + * In typical applications, this should write the entire output buffer + * (ignoring the current state of next_output_byte & free_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been dumped. + * + * In applications that need to be able to suspend compression due to output + * overrun, a FALSE return indicates that the buffer cannot be emptied now. + * In this situation, the compressor will return to its caller (possibly with + * an indication that it has not accepted all the supplied scanlines). The + * application should resume compression after it has made more room in the + * output buffer. Note that there are substantial restrictions on the use of + * suspension --- see the documentation. + * + * When suspending, the compressor will back up to a convenient restart point + * (typically the start of the current MCU). next_output_byte & free_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point will be regenerated after resumption, so do not + * write it out when emptying the buffer externally. + */ + +METHODDEF(boolean) +empty_output_buffer (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != + (size_t) OUTPUT_BUF_SIZE) + ERREXIT(cinfo, JERR_FILE_WRITE); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + + +/* + * Terminate destination --- called by jpeg_finish_compress + * after all data has been written. Usually needs to flush buffer. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +term_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) + ERREXIT(cinfo, JERR_FILE_WRITE); + } + fflush(dest->outfile); + /* Make sure we wrote the output file OK */ + if (ferror(dest->outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * Prepare for output to a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing compression. + */ + +GLOBAL(void) +jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) +{ + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_destination_mgr)); + } + + dest = (my_dest_ptr) cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outfile = outfile; +} diff --git a/rosapps/lib/libjpeg/jdatasrc.c b/rosapps/lib/libjpeg/jdatasrc.c new file mode 100644 index 00000000000..9a41b900c4b --- /dev/null +++ b/rosapps/lib/libjpeg/jdatasrc.c @@ -0,0 +1,213 @@ +/* + * jdatasrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ + +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data source object for stdio input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + FILE *infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) +init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes; + + nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); + + if (nbytes <= 0) { + if (src->start_of_file) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF(void) +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL(void) +jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + 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(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * SIZEOF(JOCTET)); + } + + src = (my_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; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} diff --git a/rosapps/lib/libjpeg/jdcoefct.c b/rosapps/lib/libjpeg/jdcoefct.c new file mode 100644 index 00000000000..4938d20fcb6 --- /dev/null +++ b/rosapps/lib/libjpeg/jdcoefct.c @@ -0,0 +1,736 @@ +/* + * jdcoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for decompression. + * This controller is the top level of the JPEG decompressor proper. + * The coefficient buffer lies between entropy decoding and inverse-DCT steps. + * + * In buffered-image mode, this controller is the interface between + * input-oriented processing and output-oriented processing. + * Also, the input side (only) is used when reading a file for transcoding. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +/* Block smoothing is only applicable for progressive JPEG, so: */ +#ifndef D_PROGRESSIVE_SUPPORTED +#undef BLOCK_SMOOTHING_SUPPORTED +#endif + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_coef_controller pub; /* public fields */ + + /* These variables keep track of the current location of the input side. */ + /* cinfo->input_iMCU_row is also used for this. */ + JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* The output side's location is represented by cinfo->output_iMCU_row. */ + + /* In single-pass modes, it's sufficient to buffer just one MCU. + * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + * and let the entropy decoder write into that workspace each time. + * (On 80x86, the workspace is FAR even though it's not really very big; + * this is to keep the module interfaces unchanged when a large coefficient + * buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays; it is used only by the input side. + */ + JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +#endif + +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* When doing block smoothing, we latch coefficient Al values here */ + int * coef_bits_latch; +#define SAVED_COEFS 6 /* we save coef_bits[0..5] */ +#endif +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + +/* Forward declarations */ +METHODDEF(int) decompress_onepass + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#ifdef D_MULTISCAN_FILES_SUPPORTED +METHODDEF(int) decompress_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif +#ifdef BLOCK_SMOOTHING_SUPPORTED +LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo)); +METHODDEF(int) decompress_smooth_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_decompress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row (input side) */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->MCU_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + cinfo->input_iMCU_row = 0; + start_iMCU_row(cinfo); +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF(void) +start_output_pass (j_decompress_ptr cinfo) +{ +#ifdef BLOCK_SMOOTHING_SUPPORTED + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* If multipass, check to see whether to use block smoothing on this pass */ + if (coef->pub.coef_arrays != NULL) { + if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) + coef->pub.decompress_data = decompress_smooth_data; + else + coef->pub.decompress_data = decompress_data; + } +#endif + cinfo->output_iMCU_row = 0; +} + + +/* + * Decompress and return some data in the single-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Input and output must run in lockstep since we have only a one-MCU buffer. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(int) +decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, useful_width; + JSAMPARRAY output_ptr; + JDIMENSION start_col, output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Loop to process as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ + jzero_far((void FAR *) coef->MCU_buffer[0], + (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + /* Determine where data should go in output_buf and do the IDCT thing. + * We skip dummy blocks at the right and bottom edges (but blkn gets + * incremented past them!). Note the inner loop relies on having + * allocated the MCU_buffer[] blocks sequentially. + */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) { + blkn += compptr->MCU_blocks; + continue; + } + inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; + useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + output_ptr = output_buf[compptr->component_index] + + yoffset * compptr->DCT_scaled_size; + start_col = MCU_col_num * compptr->MCU_sample_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (cinfo->input_iMCU_row < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + output_col = start_col; + for (xindex = 0; xindex < useful_width; xindex++) { + (*inverse_DCT) (cinfo, compptr, + (JCOEFPTR) coef->MCU_buffer[blkn+xindex], + output_ptr, output_col); + output_col += compptr->DCT_scaled_size; + } + } + blkn += compptr->MCU_width; + output_ptr += compptr->DCT_scaled_size; + } + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + cinfo->output_iMCU_row++; + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Dummy consume-input routine for single-pass operation. + */ + +METHODDEF(int) +dummy_consume_data (j_decompress_ptr cinfo) +{ + return JPEG_SUSPENDED; /* Always indicate nothing was done */ +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Consume input data and store it in the full-image coefficient buffer. + * We read as much as one fully interleaved MCU row ("iMCU" row) per call, + * ie, v_samp_factor block rows for each component in the scan. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + */ + +METHODDEF(int) +consume_data (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + cinfo->input_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Note: entropy decoder expects buffer to be zeroed, + * but this is handled automatically by the memory manager + * because we requested a pre-zeroed array. + */ + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to fetch the MCU. */ + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Decompress and return some data in the multi-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image. + */ + +METHODDEF(int) +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num; + int ci, block_row, block_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number < cinfo->output_scan_number || + (cinfo->input_scan_number == cinfo->output_scan_number && + cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + cinfo->output_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + output_col = 0; + for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { + (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, + output_ptr, output_col); + buffer_ptr++; + output_col += compptr->DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +#ifdef BLOCK_SMOOTHING_SUPPORTED + +/* + * This code applies interblock smoothing as described by section K.8 + * of the JPEG standard: the first 5 AC coefficients are estimated from + * the DC values of a DCT block and its 8 neighboring blocks. + * We apply smoothing only for progressive JPEG decoding, and only if + * the coefficients it can estimate are not yet known to full precision. + */ + +/* Natural-order array positions of the first 5 zigzag-order coefficients */ +#define Q01_POS 1 +#define Q10_POS 8 +#define Q20_POS 16 +#define Q11_POS 9 +#define Q02_POS 2 + +/* + * Determine whether block smoothing is applicable and safe. + * We also latch the current states of the coef_bits[] entries for the + * AC coefficients; otherwise, if the input side of the decompressor + * advances into a new scan, we might think the coefficients are known + * more accurately than they really are. + */ + +LOCAL(boolean) +smoothing_ok (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + boolean smoothing_useful = FALSE; + int ci, coefi; + jpeg_component_info *compptr; + JQUANT_TBL * qtable; + int * coef_bits; + int * coef_bits_latch; + + if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) + return FALSE; + + /* Allocate latch area if not already done */ + if (coef->coef_bits_latch == NULL) + coef->coef_bits_latch = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * + (SAVED_COEFS * SIZEOF(int))); + coef_bits_latch = coef->coef_bits_latch; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* All components' quantization values must already be latched. */ + if ((qtable = compptr->quant_table) == NULL) + return FALSE; + /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ + if (qtable->quantval[0] == 0 || + qtable->quantval[Q01_POS] == 0 || + qtable->quantval[Q10_POS] == 0 || + qtable->quantval[Q20_POS] == 0 || + qtable->quantval[Q11_POS] == 0 || + qtable->quantval[Q02_POS] == 0) + return FALSE; + /* DC values must be at least partly known for all components. */ + coef_bits = cinfo->coef_bits[ci]; + if (coef_bits[0] < 0) + return FALSE; + /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ + for (coefi = 1; coefi <= 5; coefi++) { + coef_bits_latch[coefi] = coef_bits[coefi]; + if (coef_bits[coefi] != 0) + smoothing_useful = TRUE; + } + coef_bits_latch += SAVED_COEFS; + } + + return smoothing_useful; +} + + +/* + * Variant of decompress_data for use when doing block smoothing. + */ + +METHODDEF(int) +decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num, last_block_column; + int ci, block_row, block_rows, access_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr, prev_block_row, next_block_row; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + boolean first_row, last_row; + JBLOCK workspace; + int *coef_bits; + JQUANT_TBL *quanttbl; + INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; + int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; + int Al, pred; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if (cinfo->input_scan_number == cinfo->output_scan_number) { + /* If input is working on current scan, we ordinarily want it to + * have completed the current row. But if input scan is DC, + * we want it to keep one row ahead so that next block row's DC + * values are up to date. + */ + JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; + if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta) + break; + } + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) { + block_rows = compptr->v_samp_factor; + access_rows = block_rows * 2; /* this and next iMCU row */ + last_row = FALSE; + } else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + access_rows = block_rows; /* this iMCU row only */ + last_row = TRUE; + } + /* Align the virtual buffer for this component. */ + if (cinfo->output_iMCU_row > 0) { + access_rows += compptr->v_samp_factor; /* prior iMCU row too */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, + (JDIMENSION) access_rows, FALSE); + buffer += compptr->v_samp_factor; /* point to current iMCU row */ + first_row = FALSE; + } else { + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE); + first_row = TRUE; + } + /* Fetch component-dependent info */ + coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); + quanttbl = compptr->quant_table; + Q00 = quanttbl->quantval[0]; + Q01 = quanttbl->quantval[Q01_POS]; + Q10 = quanttbl->quantval[Q10_POS]; + Q20 = quanttbl->quantval[Q20_POS]; + Q11 = quanttbl->quantval[Q11_POS]; + Q02 = quanttbl->quantval[Q02_POS]; + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + if (first_row && block_row == 0) + prev_block_row = buffer_ptr; + else + prev_block_row = buffer[block_row-1]; + if (last_row && block_row == block_rows-1) + next_block_row = buffer_ptr; + else + next_block_row = buffer[block_row+1]; + /* We fetch the surrounding DC values using a sliding-register approach. + * Initialize all nine here so as to do the right thing on narrow pics. + */ + DC1 = DC2 = DC3 = (int) prev_block_row[0][0]; + DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; + DC7 = DC8 = DC9 = (int) next_block_row[0][0]; + output_col = 0; + last_block_column = compptr->width_in_blocks - 1; + for (block_num = 0; block_num <= last_block_column; block_num++) { + /* Fetch current DCT block into workspace so we can modify it. */ + jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); + /* Update DC values */ + if (block_num < last_block_column) { + DC3 = (int) prev_block_row[1][0]; + DC6 = (int) buffer_ptr[1][0]; + DC9 = (int) next_block_row[1][0]; + } + /* Compute coefficient estimates per K.8. + * An estimate is applied only if coefficient is still zero, + * and is not known to be fully accurate. + */ + /* AC01 */ + if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) { + num = 36 * Q00 * (DC4 - DC6); + if (num >= 0) { + pred = (int) (((Q01<<7) + num) / (Q01<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q10<<7) + num) / (Q10<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q20<<7) + num) / (Q20<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q11<<7) + num) / (Q11<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q02<<7) + num) / (Q02<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* BLOCK_SMOOTHING_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL(void) +jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_d_coef_controller *) coef; + coef->pub.start_input_pass = start_input_pass; + coef->pub.start_output_pass = start_output_pass; +#ifdef BLOCK_SMOOTHING_SUPPORTED + coef->coef_bits_latch = NULL; +#endif + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + /* Note we ask for a pre-zeroed array. */ + int ci, access_rows; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + access_rows = compptr->v_samp_factor; +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* If block smoothing could be used, need a bigger window */ + if (cinfo->progressive_mode) + access_rows *= 3; +#endif + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) access_rows); + } + coef->pub.consume_data = consume_data; + coef->pub.decompress_data = decompress_data; + coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->pub.consume_data = dummy_consume_data; + coef->pub.decompress_data = decompress_onepass; + coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ + } +} diff --git a/rosapps/lib/libjpeg/jdcolor.c b/rosapps/lib/libjpeg/jdcolor.c new file mode 100644 index 00000000000..6c04dfe8aa1 --- /dev/null +++ b/rosapps/lib/libjpeg/jdcolor.c @@ -0,0 +1,396 @@ +/* + * jdcolor.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains output colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_deconverter pub; /* public fields */ + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ +} my_color_deconverter; + +typedef my_color_deconverter * my_cconvert_ptr; + + +/**************** YCbCr -> RGB conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * R = Y + 1.40200 * Cr + * G = Y - 0.34414 * Cb - 0.71414 * Cr + * B = Y + 1.77200 * Cb + * where Cb and Cr represent the incoming values less CENTERJSAMPLE. + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * Notice that Y, being an integral input, does not contribute any fraction + * so it need not participate in the rounding. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times Cb and Cr for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the + * values for the G calculation are left scaled up, since we must add them + * together before rounding. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. + */ + +LOCAL(void) +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + int i; + INT32 x; + SHIFT_TEMPS + + cconvert->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + cconvert->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + cconvert->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Convert some rows of samples to the output colorspace. + * + * Note that we change from noninterleaved, one-plane-per-component format + * to interleaved-pixel format. The output buffer is therefore three times + * as wide as the input buffer. + * A starting row offset is provided only for the input buffer. The caller + * can easily adjust the passed output_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF(void) +ycc_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; + outptr[RGB_GREEN] = range_limit[y + + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS))]; + outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/**************** Cases other than YCbCr -> RGB **************/ + + +/* + * Color conversion for no colorspace change: just copy the data, + * converting from separate-planes to interleaved representation. + */ + +METHODDEF(void) +null_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION count; + register int num_components = cinfo->num_components; + JDIMENSION num_cols = cinfo->output_width; + int ci; + + while (--num_rows >= 0) { + for (ci = 0; ci < num_components; ci++) { + inptr = input_buf[ci][input_row]; + outptr = output_buf[0] + ci; + for (count = num_cols; count > 0; count--) { + *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ + outptr += num_components; + } + } + input_row++; + output_buf++; + } +} + + +/* + * Color conversion for grayscale: just copy the data. + * This also works for YCbCr -> grayscale conversion, in which + * we just copy the Y (luminance) component and ignore chrominance. + */ + +METHODDEF(void) +grayscale_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, + num_rows, cinfo->output_width); +} + + +/* + * Convert grayscale to RGB: just duplicate the graylevel three times. + * This is provided to support applications that don't want to cope + * with grayscale as a separate case. + */ + +METHODDEF(void) +gray_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + + while (--num_rows >= 0) { + inptr = input_buf[0][input_row++]; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + /* We can dispense with GETJSAMPLE() here */ + outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/* + * Adobe-style YCCK->CMYK conversion. + * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same + * conversion as above, while passing K (black) unchanged. + * We assume build_ycc_rgb_table has been called. + */ + +METHODDEF(void) +ycck_cmyk_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2, inptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + inptr3 = input_buf[3][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ + outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS)))]; + outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ + /* K passes through unchanged */ + outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ + outptr += 4; + } + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF(void) +start_pass_dcolor (j_decompress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for output colorspace conversion. + */ + +GLOBAL(void) +jinit_color_deconverter (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + int ci; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_deconverter)); + cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; + cconvert->pub.start_pass = start_pass_dcolor; + + /* Make sure num_components agrees with jpeg_color_space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_RGB: + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->num_components < 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + } + + /* Set out_color_components and conversion method based on requested space. + * Also clear the component_needed flags for any unused components, + * so that earlier pipeline stages can avoid useless computation. + */ + + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + if (cinfo->jpeg_color_space == JCS_GRAYSCALE || + cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = grayscale_convert; + /* For color->grayscale conversion, only the Y (0) component is needed */ + for (ci = 1; ci < cinfo->num_components; ci++) + cinfo->comp_info[ci].component_needed = FALSE; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + cinfo->out_color_components = RGB_PIXELSIZE; + if (cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = ycc_rgb_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { + cconvert->pub.color_convert = gray_rgb_convert; + } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + cinfo->out_color_components = 4; + if (cinfo->jpeg_color_space == JCS_YCCK) { + cconvert->pub.color_convert = ycck_cmyk_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_CMYK) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: + /* Permit null conversion to same output space */ + if (cinfo->out_color_space == cinfo->jpeg_color_space) { + cinfo->out_color_components = cinfo->num_components; + cconvert->pub.color_convert = null_convert; + } else /* unsupported non-null conversion */ + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + } + + if (cinfo->quantize_colors) + cinfo->output_components = 1; /* single colormapped output component */ + else + cinfo->output_components = cinfo->out_color_components; +} diff --git a/rosapps/lib/libjpeg/jdct.h b/rosapps/lib/libjpeg/jdct.h new file mode 100644 index 00000000000..04192a266ae --- /dev/null +++ b/rosapps/lib/libjpeg/jdct.h @@ -0,0 +1,176 @@ +/* + * jdct.h + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the forward and + * inverse DCT modules. These declarations are private to the DCT managers + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + * The individual DCT algorithms are kept in separate files to ease + * machine-dependent tuning (e.g., assembly coding). + */ + + +/* + * A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + * the DCT is to be performed in-place in that buffer. Type DCTELEM is int + * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT + * implementations use an array of type FAST_FLOAT, instead.) + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + * The DCT outputs are returned scaled up by a factor of 8; they therefore + * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This + * convention improves accuracy in integer implementations and saves some + * work in floating-point ones. + * Quantization of the output coefficients is done by jcdctmgr.c. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef int DCTELEM; /* 16 or 32 bits is fine */ +#else +typedef INT32 DCTELEM; /* must have 32 bits */ +#endif + +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); + + +/* + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + * to an output sample array. The routine must dequantize the input data as + * well as perform the IDCT; for dequantization, it uses the multiplier table + * pointed to by compptr->dct_table. The output data is to be placed into the + * sample array starting at a specified column. (Any row offset needed will + * be applied to the array pointer before it is passed to the IDCT code.) + * Note that the number of samples emitted by the IDCT routine is + * DCT_scaled_size * DCT_scaled_size. + */ + +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ + +/* + * Each IDCT routine has its own ideas about the best dct_table element type. + */ + +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ +#if BITS_IN_JSAMPLE == 8 +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ +#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ +#else +typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ +#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ +#endif +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ + + +/* + * Each IDCT routine is responsible for range-limiting its results and + * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + * be quite far out of range if the input data is corrupt, so a bulletproof + * range-limiting step is required. We use a mask-and-table-lookup method + * to do the combined operations quickly. See the comments with + * prepare_range_limit_table (in jdmaster.c) for more info. + */ + +#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE) + +#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_fdct_islow jFDislow +#define jpeg_fdct_ifast jFDifast +#define jpeg_fdct_float jFDfloat +#define jpeg_idct_islow jRDislow +#define jpeg_idct_ifast jRDifast +#define jpeg_idct_float jRDfloat +#define jpeg_idct_4x4 jRD4x4 +#define jpeg_idct_2x2 jRD2x2 +#define jpeg_idct_1x1 jRD1x1 +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Extern declarations for the forward and inverse DCT routines. */ + +EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data)); + +EXTERN(void) jpeg_idct_islow + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_ifast + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_float + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_4x4 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_2x2 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_1x1 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + + +/* + * Macros for handling fixed-point arithmetic; these are used by many + * but not all of the DCT/IDCT modules. + * + * All values are expected to be of type INT32. + * Fractional constants are scaled left by CONST_BITS bits. + * CONST_BITS is defined within each module using these macros, + * and may differ from one module to the next. + */ + +#define ONE ((INT32) 1) +#define CONST_SCALE (ONE << CONST_BITS) + +/* Convert a positive real constant to an integer scaled by CONST_SCALE. + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, + * thus causing a lot of useless floating-point operations at run time. + */ + +#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) + +/* Descale and correctly round an INT32 value that's scaled by N bits. + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding + * the fudge factor is correct for either sign of X. + */ + +#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * This macro is used only when the two inputs will actually be no more than + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a + * full 32x32 multiply. This provides a useful speedup on many machines. + * Unfortunately there is no way to specify a 16x16->32 multiply portably + * in C, but some C compilers will do the right thing if you provide the + * correct combination of casts. + */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) +#endif +#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) +#endif + +#ifndef MULTIPLY16C16 /* default definition */ +#define MULTIPLY16C16(var,const) ((var) * (const)) +#endif + +/* Same except both inputs are variables. */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) +#endif + +#ifndef MULTIPLY16V16 /* default definition */ +#define MULTIPLY16V16(var1,var2) ((var1) * (var2)) +#endif diff --git a/rosapps/lib/libjpeg/jddctmgr.c b/rosapps/lib/libjpeg/jddctmgr.c new file mode 100644 index 00000000000..afdb180af13 --- /dev/null +++ b/rosapps/lib/libjpeg/jddctmgr.c @@ -0,0 +1,305 @@ +/* + * jddctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the inverse-DCT management logic. + * This code selects a particular IDCT implementation to be used, + * and it performs related housekeeping chores. No code in this file + * is executed per IDCT step, only during output pass setup. + * + * Note that the IDCT routines are responsible for performing coefficient + * dequantization as well as the IDCT proper. This module sets up the + * dequantization multiplier table needed by the IDCT routine. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ +extern int SSE2Available; + +/* + * The decompressor input side (jdinput.c) saves away the appropriate + * quantization table for each component at the start of the first scan + * involving that component. (This is necessary in order to correctly + * decode files that reuse Q-table slots.) + * When we are ready to make an output pass, the saved Q-table is converted + * to a multiplier table that will actually be used by the IDCT routine. + * The multiplier table contents are IDCT-method-dependent. To support + * application changes in IDCT method between scans, we can remake the + * multiplier tables if necessary. + * In buffered-image mode, the first output pass may occur before any data + * has been seen for some components, and thus before their Q-tables have + * been saved away. To handle this case, multiplier tables are preset + * to zeroes; the result of the IDCT will be a neutral gray level. + */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_inverse_dct pub; /* public fields */ + + /* This array contains the IDCT method code that each multiplier table + * is currently set up for, or -1 if it's not yet set up. + * The actual multiplier tables are pointed to by dct_table in the + * per-component comp_info structures. + */ + int cur_method[MAX_COMPONENTS]; +} my_idct_controller; + +typedef my_idct_controller * my_idct_ptr; + + +/* Allocated multiplier tables: big enough for any supported variant */ + +typedef union { + ISLOW_MULT_TYPE islow_array[DCTSIZE2]; +#ifdef DCT_IFAST_SUPPORTED + IFAST_MULT_TYPE ifast_array[DCTSIZE2]; +#endif +#ifdef DCT_FLOAT_SUPPORTED + FLOAT_MULT_TYPE float_array[DCTSIZE2]; +#endif +} multiplier_table; + + +/* The current scaled-IDCT routines require ISLOW-style multiplier tables, + * so be sure to compile that code if either ISLOW or SCALING is requested. + */ +#ifdef DCT_ISLOW_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#else +#ifdef IDCT_SCALING_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#endif +#endif + +GLOBAL(void) +jpeg_idct_islow_sse2 ( + j_decompress_ptr cinfo, + jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, + JDIMENSION output_col); + + +/* + * Prepare for an output pass. + * Here we select the proper IDCT routine for each component and build + * a matching multiplier table. + */ + +METHODDEF(void) +start_pass (j_decompress_ptr cinfo) +{ + my_idct_ptr idct = (my_idct_ptr) cinfo->idct; + int ci, i; + jpeg_component_info *compptr; + int method = 0; + inverse_DCT_method_ptr method_ptr = NULL; + JQUANT_TBL * qtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Select the proper IDCT routine for this component's scaling */ + switch (compptr->DCT_scaled_size) { +#ifdef IDCT_SCALING_SUPPORTED + case 1: + method_ptr = jpeg_idct_1x1; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 2: + method_ptr = jpeg_idct_2x2; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 4: + method_ptr = jpeg_idct_4x4; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; +#endif + case DCTSIZE: + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: +#ifdef HAVE_SSE2_INTEL_MNEMONICS + if(SSE2Available == 1) + { + method_ptr = jpeg_idct_islow_sse2; + method = JDCT_ISLOW; + } + else + { + method_ptr = jpeg_idct_islow; + method = JDCT_ISLOW; + } +#else + method_ptr = jpeg_idct_islow; + method = JDCT_ISLOW; + +#endif /* HAVE_SSE2_INTEL_MNEMONICS */ + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: +#ifdef HAVE_SSE2_INTEL_MNEMONICS + if (SSE2Available==1) + { + method_ptr = jpeg_idct_islow_sse2; + method = JDCT_ISLOW; + } + else + { + method_ptr = jpeg_idct_ifast; + method = JDCT_IFAST; + } +#else + method_ptr = jpeg_idct_ifast; + method = JDCT_IFAST; +#endif /* HAVE_SSE2_INTEL_MNEMONICS */ + break; + +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + method_ptr = jpeg_idct_float; + method = JDCT_FLOAT; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + break; + default: + ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size); + break; + } + idct->pub.inverse_DCT[ci] = method_ptr; + /* Create multiplier table from quant table. + * However, we can skip this if the component is uninteresting + * or if we already built the table. Also, if no quant table + * has yet been saved for the component, we leave the + * multiplier table all-zero; we'll be reading zeroes from the + * coefficient controller's buffer anyway. + */ + if (! compptr->component_needed || idct->cur_method[ci] == method) + continue; + qtbl = compptr->quant_table; + if (qtbl == NULL) /* happens if no data yet for component */ + continue; + idct->cur_method[ci] = method; + switch (method) { +#ifdef PROVIDE_ISLOW_TABLES + case JDCT_ISLOW: + { + /* For LL&M IDCT method, multipliers are equal to raw quantization + * coefficients, but are stored as ints to ensure access efficiency. + */ + ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; + for (i = 0; i < DCTSIZE2; i++) { + ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i]; + } + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * For integer operation, the multiplier table is to be scaled by + * IFAST_SCALE_BITS. + */ + IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + for (i = 0; i < DCTSIZE2; i++) { + ifmtbl[i] = (IFAST_MULT_TYPE) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-IFAST_SCALE_BITS); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + */ + FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fmtbl[i] = (FLOAT_MULT_TYPE) + ((double) qtbl->quantval[i] * + aanscalefactor[row] * aanscalefactor[col]); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Initialize IDCT manager. + */ + +GLOBAL(void) +jinit_inverse_dct (j_decompress_ptr cinfo) +{ + my_idct_ptr idct; + int ci; + jpeg_component_info *compptr; + + idct = (my_idct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_idct_controller)); + cinfo->idct = (struct jpeg_inverse_dct *) idct; + idct->pub.start_pass = start_pass; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate and pre-zero a multiplier table for each component */ + compptr->dct_table = + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(multiplier_table)); + MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); + /* Mark multiplier table not yet set up for any method */ + idct->cur_method[ci] = -1; + } +} diff --git a/rosapps/lib/libjpeg/jdhuff.c b/rosapps/lib/libjpeg/jdhuff.c new file mode 100644 index 00000000000..b5ba39f736a --- /dev/null +++ b/rosapps/lib/libjpeg/jdhuff.c @@ -0,0 +1,651 @@ +/* + * jdhuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdphuff.c */ + + +/* + * Expanded entropy decoder object for Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + + /* Precalculated info set up by start_pass for use in decode_mcu: */ + + /* Pointers to derived tables to be used for each block within an MCU */ + d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + /* Whether we care about the DC and AC coefficient values for each block */ + boolean dc_needed[D_MAX_BLOCKS_IN_MCU]; + boolean ac_needed[D_MAX_BLOCKS_IN_MCU]; +} huff_entropy_decoder; + +typedef huff_entropy_decoder * huff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, blkn, dctbl, actbl; + jpeg_component_info * compptr; + + /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. + * This ought to be an error condition, but we make it a warning because + * there are some baseline files out there with all zeroes in these bytes. + */ + if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || + cinfo->Ah != 0 || cinfo->Al != 0) + WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Precalculate decoding info for each block in an MCU of this scan */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + /* Precalculate which table to use for each block */ + entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no]; + entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + /* Decide whether we really care about the coefficient values */ + if (compptr->component_needed) { + entropy->dc_needed[blkn] = TRUE; + /* we don't need the ACs if producing a 1/8th-size image */ + entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1); + } else { + entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE; + } + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->pub.insufficient_data = FALSE; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * + * Note this is also used by jdphuff.c. + */ + +GLOBAL(void) +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, + d_derived_tbl ** pdtbl) +{ + JHUFF_TBL *htbl; + d_derived_tbl *dtbl; + int p, i, l, si, numsymbols; + int lookbits, ctr; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (d_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(d_derived_tbl)); + dtbl = *pdtbl; + dtbl->pub = htbl; /* fill in back link */ + + /* Figure C.1: make table of Huffman code length for each symbol */ + + p = 0; + for (l = 1; l <= 16; l++) { + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + numsymbols = p; + + /* Figure C.2: generate the codes themselves */ + /* We also validate that the counts represent a legal Huffman code tree. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + code <<= 1; + si++; + } + + /* Figure F.15: generate decoding tables for bit-sequential decoding */ + + p = 0; + for (l = 1; l <= 16; l++) { + if (htbl->bits[l]) { + /* valoffset[l] = huffval[] index of 1st symbol of code length l, + * minus the minimum code of length l + */ + dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p]; + p += htbl->bits[l]; + dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ + } else { + dtbl->maxcode[l] = -1; /* -1 if no codes of this length */ + } + } + dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */ + + /* Compute lookahead tables to speed up decoding. + * First we set all the table entries to 0, indicating "too long"; + * then we iterate through the Huffman codes that are short enough and + * fill in all the entries that correspond to bit sequences starting + * with that code. + */ + + MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits)); + + p = 0; + for (l = 1; l <= HUFF_LOOKAHEAD; l++) { + for (i = 1; i <= (int) htbl->bits[l]; i++, p++) { + /* l = current code's length, p = its index in huffcode[] & huffval[]. */ + /* Generate left-justified code followed by all possible bit sequences */ + lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); + for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { + dtbl->look_nbits[lookbits] = l; + dtbl->look_sym[lookbits] = htbl->huffval[p]; + lookbits++; + } + } + } + + /* Validate symbols as being reasonable. + * For AC tables, we make no check, but accept all byte values 0..255. + * For DC tables, we require the symbols to be in range 0..15. + * (Tighter bounds could be applied depending on the data depth and mode, + * but this is sufficient to ensure safe decoding.) + */ + if (isDC) { + for (i = 0; i < numsymbols; i++) { + int sym = htbl->huffval[i]; + if (sym < 0 || sym > 15) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + } + } +} + + +/* + * Out-of-line code for bit fetching (shared with jdphuff.c). + * See jdhuff.h for info about usage. + * Note: current values of get_buffer and bits_left are passed as parameters, + * but are returned in the corresponding fields of the state struct. + * + * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width + * of get_buffer to be used. (On machines with wider words, an even larger + * buffer could be used.) However, on some machines 32-bit shifts are + * quite slow and take time proportional to the number of places shifted. + * (This is true with most PC compilers, for instance.) In this case it may + * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the + * average shift distance at the cost of more calls to jpeg_fill_bit_buffer. + */ + +#ifdef SLOW_SHIFT_32 +#define MIN_GET_BITS 15 /* minimum allowable value */ +#else +#define MIN_GET_BITS (BIT_BUF_SIZE-7) +#endif + + +GLOBAL(boolean) +jpeg_fill_bit_buffer (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + int nbits) +/* Load up the bit buffer to a depth of at least nbits */ +{ + /* Copy heavily used state fields into locals (hopefully registers) */ + register const JOCTET * next_input_byte = state->next_input_byte; + register size_t bytes_in_buffer = state->bytes_in_buffer; + j_decompress_ptr cinfo = state->cinfo; + + /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ + /* (It is assumed that no request will be for more than that many bits.) */ + /* We fail to do so only if we hit a marker or are forced to suspend. */ + + if (cinfo->unread_marker == 0) { /* cannot advance past a marker */ + while (bits_left < MIN_GET_BITS) { + register int c; + + /* Attempt to read a byte */ + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + + /* If it's 0xFF, check and discard stuffed zero byte */ + if (c == 0xFF) { + /* Loop here to discard any padding FF's on terminating marker, + * so that we can save a valid unread_marker value. NOTE: we will + * accept multiple FF's followed by a 0 as meaning a single FF data + * byte. This data pattern is not valid according to the standard. + */ + do { + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + } while (c == 0xFF); + + if (c == 0) { + /* Found FF/00, which represents an FF data byte */ + c = 0xFF; + } else { + /* Oops, it's actually a marker indicating end of compressed data. + * Save the marker code for later use. + * Fine point: it might appear that we should save the marker into + * bitread working state, not straight into permanent state. But + * once we have hit a marker, we cannot need to suspend within the + * current MCU, because we will read no more bytes from the data + * source. So it is OK to update permanent state right away. + */ + cinfo->unread_marker = c; + /* See if we need to insert some fake zero bits. */ + goto no_more_bytes; + } + } + + /* OK, load c into get_buffer */ + get_buffer = (get_buffer << 8) | c; + bits_left += 8; + } /* end while */ + } else { + no_more_bytes: + /* We get here if we've read the marker that terminates the compressed + * data segment. There should be enough bits in the buffer register + * to satisfy the request; if so, no problem. + */ + if (nbits > bits_left) { + /* Uh-oh. Report corrupted data to user and stuff zeroes into + * the data stream, so that we can produce some kind of image. + * We use a nonvolatile flag to ensure that only one warning message + * appears per data segment. + */ + if (! cinfo->entropy->insufficient_data) { + WARNMS(cinfo, JWRN_HIT_MARKER); + cinfo->entropy->insufficient_data = TRUE; + } + /* Fill the buffer with zero bits */ + get_buffer <<= MIN_GET_BITS - bits_left; + bits_left = MIN_GET_BITS; + } + } + + /* Unload the local registers */ + state->next_input_byte = next_input_byte; + state->bytes_in_buffer = bytes_in_buffer; + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + return TRUE; +} + + +/* + * Out-of-line code for Huffman code decoding. + * See jdhuff.h for info about usage. + */ + +GLOBAL(int) +jpeg_huff_decode (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + d_derived_tbl * htbl, int min_bits) +{ + register int l = min_bits; + register INT32 code; + + /* HUFF_DECODE has determined that the code is at least min_bits */ + /* bits long, so fetch that many bits in one swoop. */ + + CHECK_BIT_BUFFER(*state, l, return -1); + code = GET_BITS(l); + + /* Collect the rest of the Huffman code one bit at a time. */ + /* This is per Figure F.16 in the JPEG spec. */ + + while (code > htbl->maxcode[l]) { + code <<= 1; + CHECK_BIT_BUFFER(*state, 1, return -1); + code |= GET_BITS(1); + l++; + } + + /* Unload the local registers */ + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + /* With garbage input we may reach the sentinel value l = 17. */ + + if (l > 16) { + WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE); + return 0; /* fake a zero as the safest result */ + } + + return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ]; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Decode and return one MCU's worth of Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + * (Wholesale zeroing is usually a little faster than retail...) + * + * Returns FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * this module, since we'll just re-assign them on the next call.) + */ + +METHODDEF(boolean) +decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn; + BITREAD_STATE_VARS; + savable_state state; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + JBLOCKROW block = MCU_data[blkn]; + d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn]; + d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn]; + register int s, k, r; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + if (entropy->dc_needed[blkn]) { + /* Convert DC difference to actual value, update last_dc_val */ + int ci = cinfo->MCU_membership[blkn]; + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ + (*block)[0] = (JCOEF) s; + } + + if (entropy->ac_needed[blkn]) { + + /* Section F.2.2.2: decode the AC coefficients */ + /* Since zeroes are skipped, output area must be cleared beforehand */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label2); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Output coefficient in natural (dezigzagged) order. + * Note: the extra entries in jpeg_natural_order[] will save us + * if k >= DCTSIZE2, which could happen if the data is corrupted. + */ + (*block)[jpeg_natural_order[k]] = (JCOEF) s; + } else { + if (r != 15) + break; + k += 15; + } + } + + } else { + + /* Section F.2.2.2: decode the AC coefficients */ + /* In this path we just discard the values */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label3); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + DROP_BITS(s); + } else { + if (r != 15) + break; + k += 15; + } + } + + } + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_huff_decoder; + entropy->pub.decode_mcu = decode_mcu; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; + } +} diff --git a/rosapps/lib/libjpeg/jdhuff.h b/rosapps/lib/libjpeg/jdhuff.h new file mode 100644 index 00000000000..ae19b6cafd7 --- /dev/null +++ b/rosapps/lib/libjpeg/jdhuff.h @@ -0,0 +1,201 @@ +/* + * jdhuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy decoding routines + * that are shared between the sequential decoder (jdhuff.c) and the + * progressive decoder (jdphuff.c). No other modules need to see these. + */ + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_d_derived_tbl jMkDDerived +#define jpeg_fill_bit_buffer jFilBitBuf +#define jpeg_huff_decode jHufDecode +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Derived data constructed for each Huffman table */ + +#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ + +typedef struct { + /* Basic tables: (element [0] of each array is unused) */ + INT32 maxcode[18]; /* largest code of length k (-1 if none) */ + /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ + INT32 valoffset[17]; /* huffval[] offset for codes of length k */ + /* valoffset[k] = huffval[] index of 1st symbol of code length k, less + * the smallest code of length k; so given a code of length k, the + * corresponding symbol is huffval[code + valoffset[k]] + */ + + /* Link to public Huffman table (needed only in jpeg_huff_decode) */ + JHUFF_TBL *pub; + + /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of + * the input data stream. If the next Huffman code is no more + * than HUFF_LOOKAHEAD bits long, we can obtain its length and + * the corresponding symbol directly from these tables. + */ + int look_nbits[1< 32 bits on your machine, and shifting/masking longs is + * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE + * appropriately should be a win. Unfortunately we can't define the size + * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + * because not all machines measure sizeof in 8-bit bytes. + */ + +typedef struct { /* Bitreading state saved across MCUs */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ +} bitread_perm_state; + +typedef struct { /* Bitreading working state within an MCU */ + /* Current data source location */ + /* We need a copy, rather than munging the original, in case of suspension */ + const JOCTET * next_input_byte; /* => next byte to read from source */ + size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ + /* Bit input buffer --- note these values are kept in register variables, + * not in this struct, inside the inner loops. + */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ + /* Pointer needed by jpeg_fill_bit_buffer. */ + j_decompress_ptr cinfo; /* back link to decompress master record */ +} bitread_working_state; + +/* Macros to declare and load/save bitread local variables. */ +#define BITREAD_STATE_VARS \ + register bit_buf_type get_buffer; \ + register int bits_left; \ + bitread_working_state br_state + +#define BITREAD_LOAD_STATE(cinfop,permstate) \ + br_state.cinfo = cinfop; \ + br_state.next_input_byte = cinfop->src->next_input_byte; \ + br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ + get_buffer = permstate.get_buffer; \ + bits_left = permstate.bits_left; + +#define BITREAD_SAVE_STATE(cinfop,permstate) \ + cinfop->src->next_input_byte = br_state.next_input_byte; \ + cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ + permstate.get_buffer = get_buffer; \ + permstate.bits_left = bits_left + +/* + * These macros provide the in-line portion of bit fetching. + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + * before using GET_BITS, PEEK_BITS, or DROP_BITS. + * The variables get_buffer and bits_left are assumed to be locals, + * but the state struct might not be (jpeg_huff_decode needs this). + * CHECK_BIT_BUFFER(state,n,action); + * Ensure there are N bits in get_buffer; if suspend, take action. + * val = GET_BITS(n); + * Fetch next N bits. + * val = PEEK_BITS(n); + * Fetch next N bits without removing them from the buffer. + * DROP_BITS(n); + * Discard next N bits. + * The value N should be a simple variable, not an expression, because it + * is evaluated multiple times. + */ + +#define CHECK_BIT_BUFFER(state,nbits,action) \ + { if (bits_left < (nbits)) { \ + if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ + { action; } \ + get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } + +#define GET_BITS(nbits) \ + (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) + +#define PEEK_BITS(nbits) \ + (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) + +#define DROP_BITS(nbits) \ + (bits_left -= (nbits)) + +/* Load up the bit buffer to a depth of at least nbits */ +EXTERN(boolean) jpeg_fill_bit_buffer + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, int nbits)); + + +/* + * Code for extracting next Huffman-coded symbol from input bit stream. + * Again, this is time-critical and we make the main paths be macros. + * + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + * without looping. Usually, more than 95% of the Huffman codes will be 8 + * or fewer bits long. The few overlength codes are handled with a loop, + * which need not be inline code. + * + * Notes about the HUFF_DECODE macro: + * 1. Near the end of the data segment, we may fail to get enough bits + * for a lookahead. In that case, we do it the hard way. + * 2. If the lookahead table contains no entry, the next code must be + * more than HUFF_LOOKAHEAD bits long. + * 3. jpeg_huff_decode returns -1 if forced to suspend. + */ + +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ +{ register int nb, look; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + nb = 1; goto slowlabel; \ + } \ + } \ + look = PEEK_BITS(HUFF_LOOKAHEAD); \ + if ((nb = htbl->look_nbits[look]) != 0) { \ + DROP_BITS(nb); \ + result = htbl->look_sym[look]; \ + } else { \ + nb = HUFF_LOOKAHEAD+1; \ +slowlabel: \ + if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ + { failaction; } \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + } \ +} + +/* Out-of-line case for Huffman code fetching */ +EXTERN(int) jpeg_huff_decode + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, d_derived_tbl * htbl, int min_bits)); diff --git a/rosapps/lib/libjpeg/jdinput.c b/rosapps/lib/libjpeg/jdinput.c new file mode 100644 index 00000000000..0c2ac8f120b --- /dev/null +++ b/rosapps/lib/libjpeg/jdinput.c @@ -0,0 +1,381 @@ +/* + * jdinput.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input control logic for the JPEG decompressor. + * These routines are concerned with controlling the decompressor's input + * processing (marker reading and coefficient decoding). The actual input + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_input_controller pub; /* public fields */ + + boolean inheaders; /* TRUE until first SOS is reached */ +} my_input_controller; + +typedef my_input_controller * my_inputctl_ptr; + + +/* Forward declarations */ +METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo)); + + +/* + * Routines to calculate various quantities related to the size of the image. + */ + +LOCAL(void) +initial_setup (j_decompress_ptr cinfo) +/* Called once, when first SOS marker is reached */ +{ + int ci; + jpeg_component_info *compptr; + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. + * In the full decompressor, this will be overridden by jdmaster.c; + * but in the transcoder, jdmaster.c is not used, so we must do it here. + */ + cinfo->min_DCT_scaled_size = DCTSIZE; + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* downsampled_width and downsampled_height will also be overridden by + * jdmaster.c if we are doing full decompression. The transcoder library + * doesn't use these values, but the calling application might. + */ + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed, until color conversion says otherwise */ + compptr->component_needed = TRUE; + /* Mark no quantization table yet saved for component */ + compptr->quant_table = NULL; + } + + /* Compute number of fully interleaved MCU rows. */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + /* Decide whether file contains multiple scans */ + if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) + cinfo->inputctl->has_multiple_scans = TRUE; + else + cinfo->inputctl->has_multiple_scans = FALSE; +} + + +LOCAL(void) +per_scan_setup (j_decompress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = compptr->DCT_scaled_size; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } +} + + +/* + * Save away a copy of the Q-table referenced by each component present + * in the current scan, unless already saved during a prior scan. + * + * In a multiple-scan JPEG file, the encoder could assign different components + * the same Q-table slot number, but change table definitions between scans + * so that each component uses a different Q-table. (The IJG encoder is not + * currently capable of doing this, but other encoders might.) Since we want + * to be able to dequantize all the components at the end of the file, this + * means that we have to save away the table actually used for each component. + * We do this by copying the table at the start of the first scan containing + * the component. + * The JPEG spec prohibits the encoder from changing the contents of a Q-table + * slot between scans of a component using that slot. If the encoder does so + * anyway, this decoder will simply use the Q-table values that were current + * at the start of the first scan for the component. + * + * The decompressor output side looks only at the saved quant tables, + * not at the current Q-table slots. + */ + +LOCAL(void) +latch_quant_tables (j_decompress_ptr cinfo) +{ + int ci, qtblno; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* No work if we already saved Q-table for this component */ + if (compptr->quant_table != NULL) + continue; + /* Make sure specified quantization table is present */ + qtblno = compptr->quant_tbl_no; + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + /* OK, save away the quantization table */ + qtbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(JQUANT_TBL)); + MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); + compptr->quant_table = qtbl; + } +} + + +/* + * Initialize the input modules to read a scan of compressed data. + * The first call to this is done by jdmaster.c after initializing + * the entire decompressor (during jpeg_start_decompress). + * Subsequent calls come from consume_markers, below. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + per_scan_setup(cinfo); + latch_quant_tables(cinfo); + (*cinfo->entropy->start_pass) (cinfo); + (*cinfo->coef->start_input_pass) (cinfo); + cinfo->inputctl->consume_input = cinfo->coef->consume_data; +} + + +/* + * Finish up after inputting a compressed-data scan. + * This is called by the coefficient controller after it's read all + * the expected data of the scan. + */ + +METHODDEF(void) +finish_input_pass (j_decompress_ptr cinfo) +{ + cinfo->inputctl->consume_input = consume_markers; +} + + +/* + * Read JPEG markers before, between, or after compressed-data scans. + * Change state as necessary when a new scan is reached. + * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + * + * The consume_input method pointer points either here or to the + * coefficient controller's consume_data routine, depending on whether + * we are reading a compressed data segment or inter-segment markers. + */ + +METHODDEF(int) +consume_markers (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + int val; + + if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */ + return JPEG_REACHED_EOI; + + val = (*cinfo->marker->read_markers) (cinfo); + + switch (val) { + case JPEG_REACHED_SOS: /* Found SOS */ + if (inputctl->inheaders) { /* 1st SOS */ + initial_setup(cinfo); + inputctl->inheaders = FALSE; + /* Note: start_input_pass must be called by jdmaster.c + * before any more input can be consumed. jdapimin.c is + * responsible for enforcing this sequencing. + */ + } else { /* 2nd or later SOS marker */ + if (! inputctl->pub.has_multiple_scans) + ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ + start_input_pass(cinfo); + } + break; + case JPEG_REACHED_EOI: /* Found EOI */ + inputctl->pub.eoi_reached = TRUE; + if (inputctl->inheaders) { /* Tables-only datastream, apparently */ + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_NO_SOS); + } else { + /* Prevent infinite loop in coef ctlr's decompress_data routine + * if user set output_scan_number larger than number of scans. + */ + if (cinfo->output_scan_number > cinfo->input_scan_number) + cinfo->output_scan_number = cinfo->input_scan_number; + } + break; + case JPEG_SUSPENDED: + break; + } + + return val; +} + + +/* + * Reset state to begin a fresh datastream. + */ + +METHODDEF(void) +reset_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + + inputctl->pub.consume_input = consume_markers; + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; + /* Reset other modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->marker->reset_marker_reader) (cinfo); + /* Reset progression state -- would be cleaner if entropy decoder did this */ + cinfo->coef_bits = NULL; +} + + +/* + * Initialize the input controller module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL(void) +jinit_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl; + + /* Create subobject in permanent pool */ + inputctl = (my_inputctl_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_input_controller)); + cinfo->inputctl = (struct jpeg_input_controller *) inputctl; + /* Initialize method pointers */ + inputctl->pub.consume_input = consume_markers; + inputctl->pub.reset_input_controller = reset_input_controller; + inputctl->pub.start_input_pass = start_input_pass; + inputctl->pub.finish_input_pass = finish_input_pass; + /* Initialize state: can't use reset_input_controller since we don't + * want to try to reset other modules yet. + */ + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; +} diff --git a/rosapps/lib/libjpeg/jdmainct.c b/rosapps/lib/libjpeg/jdmainct.c new file mode 100644 index 00000000000..13c956f5deb --- /dev/null +++ b/rosapps/lib/libjpeg/jdmainct.c @@ -0,0 +1,512 @@ +/* + * jdmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for decompression. + * The main buffer lies between the JPEG decompressor proper and the + * post-processor; it holds downsampled data in the JPEG colorspace. + * + * Note that this code is bypassed in raw-data mode, since the application + * supplies the equivalent of the main buffer in that case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * In the current system design, the main buffer need never be a full-image + * buffer; any full-height buffers will be found inside the coefficient or + * postprocessing controllers. Nonetheless, the main controller is not + * trivial. Its responsibility is to provide context rows for upsampling/ + * rescaling, and doing this in an efficient fashion is a bit tricky. + * + * Postprocessor input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. (We require DCT_scaled_size values to be + * chosen such that these numbers are integers. In practice DCT_scaled_size + * values will likely be powers of two, so we actually have the stronger + * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + * Upsampling will typically produce max_v_samp_factor pixel rows from each + * row group (times any additional scale factor that the upsampler is + * applying). + * + * The coefficient controller will deliver data to us one iMCU row at a time; + * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or + * exactly min_DCT_scaled_size row groups. (This amount of data corresponds + * to one row of MCUs when the image is fully interleaved.) Note that the + * number of sample rows varies across components, but the number of row + * groups does not. Some garbage sample rows may be included in the last iMCU + * row at the bottom of the image. + * + * Depending on the vertical scaling algorithm used, the upsampler may need + * access to the sample row(s) above and below its current input row group. + * The upsampler is required to set need_context_rows TRUE at global selection + * time if so. When need_context_rows is FALSE, this controller can simply + * obtain one iMCU row at a time from the coefficient controller and dole it + * out as row groups to the postprocessor. + * + * When need_context_rows is TRUE, this controller guarantees that the buffer + * passed to postprocessing contains at least one row group's worth of samples + * above and below the row group(s) being processed. Note that the context + * rows "above" the first passed row group appear at negative row offsets in + * the passed buffer. At the top and bottom of the image, the required + * context rows are manufactured by duplicating the first or last real sample + * row; this avoids having special cases in the upsampling inner loops. + * + * The amount of context is fixed at one row group just because that's a + * convenient number for this controller to work with. The existing + * upsamplers really only need one sample row of context. An upsampler + * supporting arbitrary output rescaling might wish for more than one row + * group of context when shrinking the image; tough, we don't handle that. + * (This is justified by the assumption that downsizing will be handled mostly + * by adjusting the DCT_scaled_size values, so that the actual scale factor at + * the upsample step needn't be much less than one.) + * + * To provide the desired context, we have to retain the last two row groups + * of one iMCU row while reading in the next iMCU row. (The last row group + * can't be processed until we have another row group for its below-context, + * and so we have to save the next-to-last group too for its above-context.) + * We could do this most simply by copying data around in our buffer, but + * that'd be very slow. We can avoid copying any data by creating a rather + * strange pointer structure. Here's how it works. We allocate a workspace + * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + * of row groups per iMCU row). We create two sets of redundant pointers to + * the workspace. Labeling the physical row groups 0 to M+1, the synthesized + * pointer lists look like this: + * M+1 M-1 + * master pointer --> 0 master pointer --> 0 + * 1 1 + * ... ... + * M-3 M-3 + * M-2 M + * M-1 M+1 + * M M-2 + * M+1 M-1 + * 0 0 + * We read alternate iMCU rows using each master pointer; thus the last two + * row groups of the previous iMCU row remain un-overwritten in the workspace. + * The pointer lists are set up so that the required context rows appear to + * be adjacent to the proper places when we pass the pointer lists to the + * upsampler. + * + * The above pictures describe the normal state of the pointer lists. + * At top and bottom of the image, we diddle the pointer lists to duplicate + * the first or last sample row as necessary (this is cheaper than copying + * sample rows around). + * + * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that + * situation each iMCU row provides only one row group so the buffering logic + * must be different (eg, we must read two iMCU rows before we can emit the + * first row group). For now, we simply do not support providing context + * rows when min_DCT_scaled_size is 1. That combination seems unlikely to + * be worth providing --- if someone wants a 1/8th-size preview, they probably + * want it quick and dirty, so a context-free upsampler is sufficient. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_main_controller pub; /* public fields */ + + /* Pointer to allocated workspace (M or M+2 row groups). */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + + boolean buffer_full; /* Have we gotten an iMCU row from decoder? */ + JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */ + + /* Remaining fields are only used in the context case. */ + + /* These are the master pointers to the funny-order pointer lists. */ + JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */ + + int whichptr; /* indicates which pointer set is now in use */ + int context_state; /* process_data state machine status */ + JDIMENSION rowgroups_avail; /* row groups available to postprocessor */ + JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */ +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + +/* context_state values: */ +#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */ +#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */ +#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */ + + +/* Forward declarations */ +METHODDEF(void) process_data_simple_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +METHODDEF(void) process_data_context_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF(void) process_data_crank_post + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#endif + + +LOCAL(void) +alloc_funny_pointers (j_decompress_ptr cinfo) +/* Allocate space for the funny pointer lists. + * This is done only once, not once per pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + /* Get top-level space for component array pointers. + * We alloc both arrays with one call to save a few cycles. + */ + main->xbuffer[0] = (JSAMPIMAGE) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); + main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + /* Get space for pointer lists --- M+4 row groups in each list. + * We alloc both pointer lists with one call to save a few cycles. + */ + xbuf = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); + xbuf += rgroup; /* want one row group at negative offsets */ + main->xbuffer[0][ci] = xbuf; + xbuf += rgroup * (M + 4); + main->xbuffer[1][ci] = xbuf; + } +} + + +LOCAL(void) +make_funny_pointers (j_decompress_ptr cinfo) +/* Create the funny pointer lists discussed in the comments above. + * The actual workspace is already allocated (in main->buffer), + * and the space for the pointer lists is allocated too. + * This routine just fills in the curiously ordered lists. + * This will be repeated at the beginning of each pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY buf, xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + /* First copy the workspace pointers as-is */ + buf = main->buffer[ci]; + for (i = 0; i < rgroup * (M + 2); i++) { + xbuf0[i] = xbuf1[i] = buf[i]; + } + /* In the second list, put the last four row groups in swapped order */ + for (i = 0; i < rgroup * 2; i++) { + xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; + xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; + } + /* The wraparound pointers at top and bottom will be filled later + * (see set_wraparound_pointers, below). Initially we want the "above" + * pointers to duplicate the first actual data line. This only needs + * to happen in xbuffer[0]. + */ + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[0]; + } + } +} + + +LOCAL(void) +set_wraparound_pointers (j_decompress_ptr cinfo) +/* Set up the "wraparound" pointers at top and bottom of the pointer lists. + * This changes the pointer list state from top-of-image to the normal state. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; + xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; + xbuf0[rgroup*(M+2) + i] = xbuf0[i]; + xbuf1[rgroup*(M+2) + i] = xbuf1[i]; + } + } +} + + +LOCAL(void) +set_bottom_pointers (j_decompress_ptr cinfo) +/* Change the pointer lists to duplicate the last sample row at the bottom + * of the image. whichptr indicates which xbuffer holds the final iMCU row. + * Also sets rowgroups_avail to indicate number of nondummy row groups in row. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup, iMCUheight, rows_left; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Count sample rows in one iMCU row and in one row group */ + iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size; + rgroup = iMCUheight / cinfo->min_DCT_scaled_size; + /* Count nondummy sample rows remaining for this component */ + rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); + if (rows_left == 0) rows_left = iMCUheight; + /* Count nondummy row groups. Should get same answer for each component, + * so we need only do it once. + */ + if (ci == 0) { + main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); + } + /* Duplicate the last real sample row rgroup*2 times; this pads out the + * last partial rowgroup and ensures at least one full rowgroup of context. + */ + xbuf = main->xbuffer[main->whichptr][ci]; + for (i = 0; i < rgroup * 2; i++) { + xbuf[rows_left + i] = xbuf[rows_left-1]; + } + } +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->upsample->need_context_rows) { + main->pub.process_data = process_data_context_main; + make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ + main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ + main->context_state = CTX_PREPARE_FOR_IMCU; + main->iMCU_row_ctr = 0; + } else { + /* Simple case with no context needed */ + main->pub.process_data = process_data_simple_main; + } + main->buffer_full = FALSE; /* Mark buffer empty */ + main->rowgroup_ctr = 0; + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_CRANK_DEST: + /* For last pass of 2-pass quantization, just crank the postprocessor */ + main->pub.process_data = process_data_crank_post; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This handles the simple case where no context is required. + */ + +METHODDEF(void) +process_data_simple_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + JDIMENSION rowgroups_avail; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer)) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + } + + /* There are always min_DCT_scaled_size row groups in an iMCU row. */ + rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size; + /* Note: at the bottom of the image, we may pass extra garbage row groups + * to the postprocessor. The postprocessor has to check for bottom + * of image anyway (at row resolution), so no point in us doing it too. + */ + + /* Feed the postprocessor */ + (*cinfo->post->post_process_data) (cinfo, main->buffer, + &main->rowgroup_ctr, rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + + /* Has postprocessor consumed all the data yet? If so, mark buffer empty */ + if (main->rowgroup_ctr >= rowgroups_avail) { + main->buffer_full = FALSE; + main->rowgroup_ctr = 0; + } +} + + +/* + * Process some data. + * This handles the case where context rows must be provided. + */ + +METHODDEF(void) +process_data_context_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, + main->xbuffer[main->whichptr])) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + main->iMCU_row_ctr++; /* count rows received */ + } + + /* Postprocessor typically will not swallow all the input data it is handed + * in one call (due to filling the output buffer first). Must be prepared + * to exit and restart. This switch lets us keep track of how far we got. + * Note that each case falls through to the next on successful completion. + */ + switch (main->context_state) { + case CTX_POSTPONED_ROW: + /* Call postprocessor using previously set pointers for postponed row */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + main->context_state = CTX_PREPARE_FOR_IMCU; + if (*out_row_ctr >= out_rows_avail) + return; /* Postprocessor exactly filled output buf */ + /*FALLTHROUGH*/ + case CTX_PREPARE_FOR_IMCU: + /* Prepare to process first M-1 row groups of this iMCU row */ + main->rowgroup_ctr = 0; + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); + /* Check for bottom of image: if so, tweak pointers to "duplicate" + * the last sample row, and adjust rowgroups_avail to ignore padding rows. + */ + if (main->iMCU_row_ctr == cinfo->total_iMCU_rows) + set_bottom_pointers(cinfo); + main->context_state = CTX_PROCESS_IMCU; + /*FALLTHROUGH*/ + case CTX_PROCESS_IMCU: + /* Call postprocessor using previously set pointers */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + /* After the first iMCU, change wraparound pointers to normal state */ + if (main->iMCU_row_ctr == 1) + set_wraparound_pointers(cinfo); + /* Prepare to load new iMCU row using other xbuffer list */ + main->whichptr ^= 1; /* 0=>1 or 1=>0 */ + main->buffer_full = FALSE; + /* Still need to process last row group of this iMCU row, */ + /* which is saved at index M+1 of the other xbuffer */ + main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); + main->context_state = CTX_POSTPONED_ROW; + } +} + + +/* + * Process some data. + * Final pass of two-pass quantization: just call the postprocessor. + * Source data will be the postprocessor controller's internal buffer. + */ + +#ifdef QUANT_2PASS_SUPPORTED + +METHODDEF(void) +process_data_crank_post (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, + (JDIMENSION *) NULL, (JDIMENSION) 0, + output_buf, out_row_ctr, out_rows_avail); +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL(void) +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci, rgroup, ngroups; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_d_main_controller *) main; + main->pub.start_pass = start_pass_main; + + if (need_full_buffer) /* shouldn't happen */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Allocate the workspace. + * ngroups is the number of row groups we need. + */ + if (cinfo->upsample->need_context_rows) { + if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */ + ERREXIT(cinfo, JERR_NOTIMPL); + alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ + ngroups = cinfo->min_DCT_scaled_size + 2; + } else { + ngroups = cinfo->min_DCT_scaled_size; + } + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * compptr->DCT_scaled_size, + (JDIMENSION) (rgroup * ngroups)); + } +} diff --git a/rosapps/lib/libjpeg/jdmarker.c b/rosapps/lib/libjpeg/jdmarker.c new file mode 100644 index 00000000000..f4cca8cc835 --- /dev/null +++ b/rosapps/lib/libjpeg/jdmarker.c @@ -0,0 +1,1360 @@ +/* + * jdmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to decode JPEG datastream markers. + * Most of the complexity arises from our desire to support input + * suspension: if not all of the data for a marker is available, + * we must exit back to the application. On resumption, we reprocess + * the marker. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* Private state */ + +typedef struct { + struct jpeg_marker_reader pub; /* public fields */ + + /* Application-overridable marker processing methods */ + jpeg_marker_parser_method process_COM; + jpeg_marker_parser_method process_APPn[16]; + + /* Limit on marker data length to save for each marker type */ + unsigned int length_limit_COM; + unsigned int length_limit_APPn[16]; + + /* Status of COM/APPn marker saving */ + jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */ + unsigned int bytes_read; /* data bytes read so far in marker */ + /* Note: cur_marker is not linked into marker_list until it's all read. */ +} my_marker_reader; + +typedef my_marker_reader * my_marker_ptr; + + +/* + * Macros for fetching data from the data source module. + * + * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect + * the current restart point; we update them only when we have reached a + * suitable place to restart if a suspension occurs. + */ + +/* Declare and initialize local copies of input pointer/count */ +#define INPUT_VARS(cinfo) \ + struct jpeg_source_mgr * datasrc = (cinfo)->src; \ + const JOCTET * next_input_byte = datasrc->next_input_byte; \ + size_t bytes_in_buffer = datasrc->bytes_in_buffer + +/* Unload the local copies --- do this only at a restart boundary */ +#define INPUT_SYNC(cinfo) \ + ( datasrc->next_input_byte = next_input_byte, \ + datasrc->bytes_in_buffer = bytes_in_buffer ) + +/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ +#define INPUT_RELOAD(cinfo) \ + ( next_input_byte = datasrc->next_input_byte, \ + bytes_in_buffer = datasrc->bytes_in_buffer ) + +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + * but we must reload the local copies after a successful fill. + */ +#define MAKE_BYTE_AVAIL(cinfo,action) \ + if (bytes_in_buffer == 0) { \ + if (! (*datasrc->fill_input_buffer) (cinfo)) \ + { action; } \ + INPUT_RELOAD(cinfo); \ + } + +/* Read a byte into variable V. + * If must suspend, take the specified action (typically "return FALSE"). + */ +#define INPUT_BYTE(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = GETJOCTET(*next_input_byte++); ) + +/* As above, but read two bytes interpreted as an unsigned 16-bit integer. + * V should be declared unsigned int or perhaps INT32. + */ +#define INPUT_2BYTES(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ + MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V += GETJOCTET(*next_input_byte++); ) + + +/* + * Routines to process JPEG markers. + * + * Entry condition: JPEG marker itself has been read and its code saved + * in cinfo->unread_marker; input restart point is just after the marker. + * + * Exit: if return TRUE, have read and processed any parameters, and have + * updated the restart point to point after the parameters. + * If return FALSE, was forced to suspend before reaching end of + * marker parameters; restart point has not been moved. Same routine + * will be called again after application supplies more input data. + * + * This approach to suspension assumes that all of a marker's parameters + * can fit into a single input bufferload. This should hold for "normal" + * markers. Some COM/APPn markers might have large parameter segments + * that might not fit. If we are simply dropping such a marker, we use + * skip_input_data to get past it, and thereby put the problem on the + * source manager's shoulders. If we are saving the marker's contents + * into memory, we use a slightly different convention: when forced to + * suspend, the marker processor updates the restart point to the end of + * what it's consumed (ie, the end of the buffer) before returning FALSE. + * On resumption, cinfo->unread_marker still contains the marker code, + * but the data source will point to the next chunk of marker data. + * The marker processor must retain internal state to deal with this. + * + * Note that we don't bother to avoid duplicate trace messages if a + * suspension occurs within marker parameters. Other side effects + * require more care. + */ + + +LOCAL(boolean) +get_soi (j_decompress_ptr cinfo) +/* Process an SOI marker */ +{ + int i; + + TRACEMS(cinfo, 1, JTRC_SOI); + + if (cinfo->marker->saw_SOI) + ERREXIT(cinfo, JERR_SOI_DUPLICATE); + + /* Reset all parameters that are defined to be reset by SOI */ + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + cinfo->restart_interval = 0; + + /* Set initial assumptions for colorspace etc */ + + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ + + cinfo->saw_JFIF_marker = FALSE; + cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */ + cinfo->JFIF_minor_version = 1; + cinfo->density_unit = 0; + cinfo->X_density = 1; + cinfo->Y_density = 1; + cinfo->saw_Adobe_marker = FALSE; + cinfo->Adobe_transform = 0; + + cinfo->marker->saw_SOI = TRUE; + + return TRUE; +} + + +LOCAL(boolean) +get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) +/* Process a SOFn marker */ +{ + INT32 length; + int c, ci; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + cinfo->progressive_mode = is_prog; + cinfo->arith_code = is_arith; + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); + INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); + + length -= 8; + + TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, + (int) cinfo->image_width, (int) cinfo->image_height, + cinfo->num_components); + + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_DUPLICATE); + + /* We don't support files in which the image height is initially specified */ + /* as 0 and is later redefined by DNL. As long as we have to check that, */ + /* might as well have a general sanity check. */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + if (length != (cinfo->num_components * 3)) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + if (cinfo->comp_info == NULL) /* do only once, even if suspend */ + cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * SIZEOF(jpeg_component_info)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->component_index = ci; + INPUT_BYTE(cinfo, compptr->component_id, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + compptr->h_samp_factor = (c >> 4) & 15; + compptr->v_samp_factor = (c ) & 15; + INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); + + TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, + compptr->component_id, compptr->h_samp_factor, + compptr->v_samp_factor, compptr->quant_tbl_no); + } + + cinfo->marker->saw_SOF = TRUE; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_sos (j_decompress_ptr cinfo) +/* Process a SOS marker */ +{ + INT32 length; + int i, ci, n, c, cc; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + if (! cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOS_NO_SOF); + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ + + TRACEMS1(cinfo, 1, JTRC_SOS, n); + + if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + cinfo->comps_in_scan = n; + + /* Collect the component-spec parameters */ + + for (i = 0; i < n; i++) { + INPUT_BYTE(cinfo, cc, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (cc == compptr->component_id) + goto id_found; + } + + ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); + + id_found: + + cinfo->cur_comp_info[i] = compptr; + compptr->dc_tbl_no = (c >> 4) & 15; + compptr->ac_tbl_no = (c ) & 15; + + TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, + compptr->dc_tbl_no, compptr->ac_tbl_no); + } + + /* Collect the additional scan parameters Ss, Se, Ah/Al. */ + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ss = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Se = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ah = (c >> 4) & 15; + cinfo->Al = (c ) & 15; + + TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, + cinfo->Ah, cinfo->Al); + + /* Prepare to scan data & restart markers */ + cinfo->marker->next_restart_num = 0; + + /* Count another SOS marker */ + cinfo->input_scan_number++; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +#ifdef D_ARITH_CODING_SUPPORTED + +LOCAL(boolean) +get_dac (j_decompress_ptr cinfo) +/* Process a DAC marker */ +{ + INT32 length; + int index, val; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, index, return FALSE); + INPUT_BYTE(cinfo, val, return FALSE); + + length -= 2; + + TRACEMS2(cinfo, 1, JTRC_DAC, index, val); + + if (index < 0 || index >= (2*NUM_ARITH_TBLS)) + ERREXIT1(cinfo, JERR_DAC_INDEX, index); + + if (index >= NUM_ARITH_TBLS) { /* define AC table */ + cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; + } else { /* define DC table */ + cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); + cinfo->arith_dc_U[index] = (UINT8) (val >> 4); + if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) + ERREXIT1(cinfo, JERR_DAC_VALUE, val); + } + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + +#else /* ! D_ARITH_CODING_SUPPORTED */ + +#define get_dac(cinfo) skip_variable(cinfo) + +#endif /* D_ARITH_CODING_SUPPORTED */ + + +LOCAL(boolean) +get_dht (j_decompress_ptr cinfo) +/* Process a DHT marker */ +{ + INT32 length; + UINT8 bits[17]; + UINT8 huffval[256]; + int i, index, count; + JHUFF_TBL **htblptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 16) { + INPUT_BYTE(cinfo, index, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DHT, index); + + bits[0] = 0; + count = 0; + for (i = 1; i <= 16; i++) { + INPUT_BYTE(cinfo, bits[i], return FALSE); + count += bits[i]; + } + + length -= 1 + 16; + + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[1], bits[2], bits[3], bits[4], + bits[5], bits[6], bits[7], bits[8]); + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[9], bits[10], bits[11], bits[12], + bits[13], bits[14], bits[15], bits[16]); + + /* Here we just do minimal validation of the counts to avoid walking + * off the end of our table space. jdhuff.c will check more carefully. + */ + if (count > 256 || ((INT32) count) > length) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + + for (i = 0; i < count; i++) + INPUT_BYTE(cinfo, huffval[i], return FALSE); + + length -= count; + + if (index & 0x10) { /* AC table definition */ + index -= 0x10; + htblptr = &cinfo->ac_huff_tbl_ptrs[index]; + } else { /* DC table definition */ + htblptr = &cinfo->dc_huff_tbl_ptrs[index]; + } + + if (index < 0 || index >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_DHT_INDEX, index); + + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_dqt (j_decompress_ptr cinfo) +/* Process a DQT marker */ +{ + INT32 length; + int n, i, prec; + unsigned int tmp; + JQUANT_TBL *quant_ptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, n, return FALSE); + prec = n >> 4; + n &= 0x0F; + + TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); + + if (n >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, n); + + if (cinfo->quant_tbl_ptrs[n] == NULL) + cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); + quant_ptr = cinfo->quant_tbl_ptrs[n]; + + for (i = 0; i < DCTSIZE2; i++) { + if (prec) + INPUT_2BYTES(cinfo, tmp, return FALSE); + else + INPUT_BYTE(cinfo, tmp, return FALSE); + /* We convert the zigzag-order table to natural array order. */ + quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp; + } + + if (cinfo->err->trace_level >= 2) { + for (i = 0; i < DCTSIZE2; i += 8) { + TRACEMS8(cinfo, 2, JTRC_QUANTVALS, + quant_ptr->quantval[i], quant_ptr->quantval[i+1], + quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], + quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], + quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); + } + } + + length -= DCTSIZE2+1; + if (prec) length -= DCTSIZE2; + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_dri (j_decompress_ptr cinfo) +/* Process a DRI marker */ +{ + INT32 length; + unsigned int tmp; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + + if (length != 4) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_2BYTES(cinfo, tmp, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DRI, tmp); + + cinfo->restart_interval = tmp; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +/* + * Routines for processing APPn and COM markers. + * These are either saved in memory or discarded, per application request. + * APP0 and APP14 are specially checked to see if they are + * JFIF and Adobe markers, respectively. + */ + +#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */ +#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */ +#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */ + + +LOCAL(void) +examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP0. + * Take appropriate action if it is a JFIF marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + INT32 totallen = (INT32) datalen + remaining; + + if (datalen >= APP0_DATA_LEN && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x49 && + GETJOCTET(data[3]) == 0x46 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF APP0 marker: save info */ + cinfo->saw_JFIF_marker = TRUE; + cinfo->JFIF_major_version = GETJOCTET(data[5]); + cinfo->JFIF_minor_version = GETJOCTET(data[6]); + cinfo->density_unit = GETJOCTET(data[7]); + cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); + cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); + /* Check version. + * Major version must be 1, anything else signals an incompatible change. + * (We used to treat this as an error, but now it's a nonfatal warning, + * because some bozo at Hijaak couldn't read the spec.) + * Minor version should be 0..2, but process anyway if newer. + */ + if (cinfo->JFIF_major_version != 1) + WARNMS2(cinfo, JWRN_JFIF_MAJOR, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version); + /* Generate trace messages */ + TRACEMS5(cinfo, 1, JTRC_JFIF, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version, + cinfo->X_density, cinfo->Y_density, cinfo->density_unit); + /* Validate thumbnail dimensions and issue appropriate messages */ + if (GETJOCTET(data[12]) | GETJOCTET(data[13])) + TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, + GETJOCTET(data[12]), GETJOCTET(data[13])); + totallen -= APP0_DATA_LEN; + if (totallen != + ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3)) + TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen); + } else if (datalen >= 6 && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x58 && + GETJOCTET(data[3]) == 0x58 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF "JFXX" extension APP0 marker */ + /* The library doesn't actually do anything with these, + * but we try to produce a helpful trace message. + */ + switch (GETJOCTET(data[5])) { + case 0x10: + TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen); + break; + case 0x11: + TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen); + break; + case 0x13: + TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen); + break; + default: + TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, + GETJOCTET(data[5]), (int) totallen); + break; + } + } else { + /* Start of APP0 does not match "JFIF" or "JFXX", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen); + } +} + + +LOCAL(void) +examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP14. + * Take appropriate action if it is an Adobe marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + unsigned int version, flags0, flags1, transform; + + if (datalen >= APP14_DATA_LEN && + GETJOCTET(data[0]) == 0x41 && + GETJOCTET(data[1]) == 0x64 && + GETJOCTET(data[2]) == 0x6F && + GETJOCTET(data[3]) == 0x62 && + GETJOCTET(data[4]) == 0x65) { + /* Found Adobe APP14 marker */ + version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]); + flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]); + flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]); + transform = GETJOCTET(data[11]); + TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); + cinfo->saw_Adobe_marker = TRUE; + cinfo->Adobe_transform = (UINT8) transform; + } else { + /* Start of APP14 does not match "Adobe", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining)); + } +} + + +METHODDEF(boolean) +get_interesting_appn (j_decompress_ptr cinfo) +/* Process an APP0 or APP14 marker without saving it */ +{ + INT32 length; + JOCTET b[APPN_DATA_LEN]; + unsigned int i, numtoread; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + /* get the interesting part of the marker data */ + if (length >= APPN_DATA_LEN) + numtoread = APPN_DATA_LEN; + else if (length > 0) + numtoread = (unsigned int) length; + else + numtoread = 0; + for (i = 0; i < numtoread; i++) + INPUT_BYTE(cinfo, b[i], return FALSE); + length -= numtoread; + + /* process it */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + case M_APP14: + examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + default: + /* can't get here unless jpeg_save_markers chooses wrong processor */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +#ifdef SAVE_MARKERS_SUPPORTED + +METHODDEF(boolean) +save_marker (j_decompress_ptr cinfo) +/* Save an APPn or COM marker into the marker list */ +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + jpeg_saved_marker_ptr cur_marker = marker->cur_marker; + unsigned int bytes_read, data_length; + JOCTET FAR * data; + INT32 length = 0; + INPUT_VARS(cinfo); + + if (cur_marker == NULL) { + /* begin reading a marker */ + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + if (length >= 0) { /* watch out for bogus length word */ + /* figure out how much we want to save */ + unsigned int limit; + if (cinfo->unread_marker == (int) M_COM) + limit = marker->length_limit_COM; + else + limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0]; + if ((unsigned int) length < limit) + limit = (unsigned int) length; + /* allocate and initialize the marker item */ + cur_marker = (jpeg_saved_marker_ptr) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(struct jpeg_marker_struct) + limit); + cur_marker->next = NULL; + cur_marker->marker = (UINT8) cinfo->unread_marker; + cur_marker->original_length = (unsigned int) length; + cur_marker->data_length = limit; + /* data area is just beyond the jpeg_marker_struct */ + data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1); + marker->cur_marker = cur_marker; + marker->bytes_read = 0; + bytes_read = 0; + data_length = limit; + } else { + /* deal with bogus length word */ + bytes_read = data_length = 0; + data = NULL; + } + } else { + /* resume reading a marker */ + bytes_read = marker->bytes_read; + data_length = cur_marker->data_length; + data = cur_marker->data + bytes_read; + } + + while (bytes_read < data_length) { + INPUT_SYNC(cinfo); /* move the restart point to here */ + marker->bytes_read = bytes_read; + /* If there's not at least one byte in buffer, suspend */ + MAKE_BYTE_AVAIL(cinfo, return FALSE); + /* Copy bytes with reasonable rapidity */ + while (bytes_read < data_length && bytes_in_buffer > 0) { + *data++ = *next_input_byte++; + bytes_in_buffer--; + bytes_read++; + } + } + + /* Done reading what we want to read */ + if (cur_marker != NULL) { /* will be NULL if bogus length word */ + /* Add new marker to end of list */ + if (cinfo->marker_list == NULL) { + cinfo->marker_list = cur_marker; + } else { + jpeg_saved_marker_ptr prev = cinfo->marker_list; + while (prev->next != NULL) + prev = prev->next; + prev->next = cur_marker; + } + /* Reset pointer & calc remaining data length */ + data = cur_marker->data; + length = cur_marker->original_length - data_length; + } + /* Reset to initial state for next marker */ + marker->cur_marker = NULL; + + /* Process the marker if interesting; else just make a generic trace msg */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, data, data_length, length); + break; + case M_APP14: + examine_app14(cinfo, data, data_length, length); + break; + default: + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, + (int) (data_length + length)); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +METHODDEF(boolean) +skip_variable (j_decompress_ptr cinfo) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + INT32 length; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); + + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +/* + * Find the next JPEG marker, save it in cinfo->unread_marker. + * Returns FALSE if had to suspend before reaching a marker; + * in that case cinfo->unread_marker is unchanged. + * + * Note that the result might not be a valid marker code, + * but it will never be 0 or FF. + */ + +LOCAL(boolean) +next_marker (j_decompress_ptr cinfo) +{ + int c; + INPUT_VARS(cinfo); + + for (;;) { + INPUT_BYTE(cinfo, c, return FALSE); + /* Skip any non-FF bytes. + * This may look a bit inefficient, but it will not occur in a valid file. + * We sync after each discarded byte so that a suspending data source + * can discard the byte from its buffer. + */ + while (c != 0xFF) { + cinfo->marker->discarded_bytes++; + INPUT_SYNC(cinfo); + INPUT_BYTE(cinfo, c, return FALSE); + } + /* This loop swallows any duplicate FF bytes. Extra FFs are legal as + * pad bytes, so don't count them in discarded_bytes. We assume there + * will not be so many consecutive FF bytes as to overflow a suspending + * data source's input buffer. + */ + do { + INPUT_BYTE(cinfo, c, return FALSE); + } while (c == 0xFF); + if (c != 0) + break; /* found a valid marker, exit loop */ + /* Reach here if we found a stuffed-zero data sequence (FF/00). + * Discard it and loop back to try again. + */ + cinfo->marker->discarded_bytes += 2; + INPUT_SYNC(cinfo); + } + + if (cinfo->marker->discarded_bytes != 0) { + WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); + cinfo->marker->discarded_bytes = 0; + } + + cinfo->unread_marker = c; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +first_marker (j_decompress_ptr cinfo) +/* Like next_marker, but used to obtain the initial SOI marker. */ +/* For this marker, we do not allow preceding garbage or fill; otherwise, + * we might well scan an entire input file before realizing it ain't JPEG. + * If an application wants to process non-JFIF files, it must seek to the + * SOI before calling the JPEG library. + */ +{ + int c, c2; + INPUT_VARS(cinfo); + + INPUT_BYTE(cinfo, c, return FALSE); + INPUT_BYTE(cinfo, c2, return FALSE); + if (c != 0xFF || c2 != (int) M_SOI) + ERREXIT2(cinfo, JERR_NO_SOI, c, c2); + + cinfo->unread_marker = c2; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +/* + * Read markers until SOS or EOI. + * + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + +METHODDEF(int) +read_markers (j_decompress_ptr cinfo) +{ + /* Outer loop repeats once for each marker. */ + for (;;) { + /* Collect the marker proper, unless we already did. */ + /* NB: first_marker() enforces the requirement that SOI appear first. */ + if (cinfo->unread_marker == 0) { + if (! cinfo->marker->saw_SOI) { + if (! first_marker(cinfo)) + return JPEG_SUSPENDED; + } else { + if (! next_marker(cinfo)) + return JPEG_SUSPENDED; + } + } + /* At this point cinfo->unread_marker contains the marker code and the + * input point is just past the marker proper, but before any parameters. + * A suspension will cause us to return with this state still true. + */ + switch (cinfo->unread_marker) { + case M_SOI: + if (! get_soi(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + if (! get_sof(cinfo, FALSE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF2: /* Progressive, Huffman */ + if (! get_sof(cinfo, TRUE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF9: /* Extended sequential, arithmetic */ + if (! get_sof(cinfo, FALSE, TRUE)) + return JPEG_SUSPENDED; + break; + + case M_SOF10: /* Progressive, arithmetic */ + if (! get_sof(cinfo, TRUE, TRUE)) + return JPEG_SUSPENDED; + break; + + /* Currently unsupported SOFn types */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_JPG: /* Reserved for JPEG extensions */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); + break; + + case M_SOS: + if (! get_sos(cinfo)) + return JPEG_SUSPENDED; + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_SOS; + + case M_EOI: + TRACEMS(cinfo, 1, JTRC_EOI); + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_EOI; + + case M_DAC: + if (! get_dac(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DHT: + if (! get_dht(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DQT: + if (! get_dqt(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DRI: + if (! get_dri(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_APP0: + case M_APP1: + case M_APP2: + case M_APP3: + case M_APP4: + case M_APP5: + case M_APP6: + case M_APP7: + case M_APP8: + case M_APP9: + case M_APP10: + case M_APP11: + case M_APP12: + case M_APP13: + case M_APP14: + case M_APP15: + if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[ + cinfo->unread_marker - (int) M_APP0]) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_COM: + if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_RST0: /* these are all parameterless */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); + break; + + case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ + if (! skip_variable(cinfo)) + return JPEG_SUSPENDED; + break; + + default: /* must be DHP, EXP, JPGn, or RESn */ + /* For now, we treat the reserved markers as fatal errors since they are + * likely to be used to signal incompatible JPEG Part 3 extensions. + * Once the JPEG 3 version-number marker is well defined, this code + * ought to change! + */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + /* Successfully processed marker, so reset state variable */ + cinfo->unread_marker = 0; + } /* end loop */ +} + + +/* + * Read a restart marker, which is expected to appear next in the datastream; + * if the marker is not there, take appropriate recovery action. + * Returns FALSE if suspension is required. + * + * This is called by the entropy decoder after it has read an appropriate + * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder + * has already read a marker from the data source. Under normal conditions + * cinfo->unread_marker will be reset to 0 before returning; if not reset, + * it holds a marker which the decoder will be unable to read past. + */ + +METHODDEF(boolean) +read_restart_marker (j_decompress_ptr cinfo) +{ + /* Obtain a marker unless we already did. */ + /* Note that next_marker will complain if it skips any data. */ + if (cinfo->unread_marker == 0) { + if (! next_marker(cinfo)) + return FALSE; + } + + if (cinfo->unread_marker == + ((int) M_RST0 + cinfo->marker->next_restart_num)) { + /* Normal case --- swallow the marker and let entropy decoder continue */ + TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num); + cinfo->unread_marker = 0; + } else { + /* Uh-oh, the restart markers have been messed up. */ + /* Let the data source manager determine how to resync. */ + if (! (*cinfo->src->resync_to_restart) (cinfo, + cinfo->marker->next_restart_num)) + return FALSE; + } + + /* Update next-restart state */ + cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; + + return TRUE; +} + + +/* + * This is the default resync_to_restart method for data source managers + * to use if they don't have any better approach. Some data source managers + * may be able to back up, or may have additional knowledge about the data + * which permits a more intelligent recovery strategy; such managers would + * presumably supply their own resync method. + * + * read_restart_marker calls resync_to_restart if it finds a marker other than + * the restart marker it was expecting. (This code is *not* used unless + * a nonzero restart interval has been declared.) cinfo->unread_marker is + * the marker code actually found (might be anything, except 0 or FF). + * The desired restart marker number (0..7) is passed as a parameter. + * This routine is supposed to apply whatever error recovery strategy seems + * appropriate in order to position the input stream to the next data segment. + * Note that cinfo->unread_marker is treated as a marker appearing before + * the current data-source input point; usually it should be reset to zero + * before returning. + * Returns FALSE if suspension is required. + * + * This implementation is substantially constrained by wanting to treat the + * input as a data stream; this means we can't back up. Therefore, we have + * only the following actions to work with: + * 1. Simply discard the marker and let the entropy decoder resume at next + * byte of file. + * 2. Read forward until we find another marker, discarding intervening + * data. (In theory we could look ahead within the current bufferload, + * without having to discard data if we don't find the desired marker. + * This idea is not implemented here, in part because it makes behavior + * dependent on buffer size and chance buffer-boundary positions.) + * 3. Leave the marker unread (by failing to zero cinfo->unread_marker). + * This will cause the entropy decoder to process an empty data segment, + * inserting dummy zeroes, and then we will reprocess the marker. + * + * #2 is appropriate if we think the desired marker lies ahead, while #3 is + * appropriate if the found marker is a future restart marker (indicating + * that we have missed the desired restart marker, probably because it got + * corrupted). + * We apply #2 or #3 if the found marker is a restart marker no more than + * two counts behind or ahead of the expected one. We also apply #2 if the + * found marker is not a legal JPEG marker code (it's certainly bogus data). + * If the found marker is a restart marker more than 2 counts away, we do #1 + * (too much risk that the marker is erroneous; with luck we will be able to + * resync at some future point). + * For any valid non-restart JPEG marker, we apply #3. This keeps us from + * overrunning the end of a scan. An implementation limited to single-scan + * files might find it better to apply #2 for markers other than EOI, since + * any other marker would have to be bogus data in that case. + */ + +GLOBAL(boolean) +jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) +{ + int marker = cinfo->unread_marker; + int action = 1; + + /* Always put up a warning. */ + WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); + + /* Outer loop handles repeated decision after scanning forward. */ + for (;;) { + if (marker < (int) M_SOF0) + action = 2; /* invalid marker */ + else if (marker < (int) M_RST0 || marker > (int) M_RST7) + action = 3; /* valid non-restart marker */ + else { + if (marker == ((int) M_RST0 + ((desired+1) & 7)) || + marker == ((int) M_RST0 + ((desired+2) & 7))) + action = 3; /* one of the next two expected restarts */ + else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || + marker == ((int) M_RST0 + ((desired-2) & 7))) + action = 2; /* a prior restart, so advance */ + else + action = 1; /* desired restart or too far away */ + } + TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); + switch (action) { + case 1: + /* Discard marker and let entropy decoder resume processing. */ + cinfo->unread_marker = 0; + return TRUE; + case 2: + /* Scan to the next marker, and repeat the decision loop. */ + if (! next_marker(cinfo)) + return FALSE; + marker = cinfo->unread_marker; + break; + case 3: + /* Return without advancing past this marker. */ + /* Entropy decoder will be forced to process an empty segment. */ + return TRUE; + } + } /* end loop */ +} + + +/* + * Reset marker processing state to begin a fresh datastream. + */ + +METHODDEF(void) +reset_marker_reader (j_decompress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + cinfo->comp_info = NULL; /* until allocated by get_sof */ + cinfo->input_scan_number = 0; /* no SOS seen yet */ + cinfo->unread_marker = 0; /* no pending marker */ + marker->pub.saw_SOI = FALSE; /* set internal state too */ + marker->pub.saw_SOF = FALSE; + marker->pub.discarded_bytes = 0; + marker->cur_marker = NULL; +} + + +/* + * Initialize the marker reader module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL(void) +jinit_marker_reader (j_decompress_ptr cinfo) +{ + my_marker_ptr marker; + int i; + + /* Create subobject in permanent pool */ + marker = (my_marker_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_marker_reader)); + cinfo->marker = (struct jpeg_marker_reader *) marker; + /* Initialize public method pointers */ + marker->pub.reset_marker_reader = reset_marker_reader; + marker->pub.read_markers = read_markers; + marker->pub.read_restart_marker = read_restart_marker; + /* Initialize COM/APPn processing. + * By default, we examine and then discard APP0 and APP14, + * but simply discard COM and all other APPn. + */ + marker->process_COM = skip_variable; + marker->length_limit_COM = 0; + for (i = 0; i < 16; i++) { + marker->process_APPn[i] = skip_variable; + marker->length_limit_APPn[i] = 0; + } + marker->process_APPn[0] = get_interesting_appn; + marker->process_APPn[14] = get_interesting_appn; + /* Reset marker processing state */ + reset_marker_reader(cinfo); +} + + +/* + * Control saving of COM and APPn markers into marker_list. + */ + +#ifdef SAVE_MARKERS_SUPPORTED + +GLOBAL(void) +jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + long maxlength; + jpeg_marker_parser_method processor; + + /* Length limit mustn't be larger than what we can allocate + * (should only be a concern in a 16-bit environment). + */ + maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct); + if (((long) length_limit) > maxlength) + length_limit = (unsigned int) maxlength; + + /* Choose processor routine to use. + * APP0/APP14 have special requirements. + */ + if (length_limit) { + processor = save_marker; + /* If saving APP0/APP14, save at least enough for our internal use. */ + if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN) + length_limit = APP0_DATA_LEN; + else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN) + length_limit = APP14_DATA_LEN; + } else { + processor = skip_variable; + /* If discarding APP0/APP14, use our regular on-the-fly processor. */ + if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14) + processor = get_interesting_appn; + } + + if (marker_code == (int) M_COM) { + marker->process_COM = processor; + marker->length_limit_COM = length_limit; + } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) { + marker->process_APPn[marker_code - (int) M_APP0] = processor; + marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit; + } else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +/* + * Install a special processing method for COM or APPn markers. + */ + +GLOBAL(void) +jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + if (marker_code == (int) M_COM) + marker->process_COM = routine; + else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) + marker->process_APPn[marker_code - (int) M_APP0] = routine; + else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} diff --git a/rosapps/lib/libjpeg/jdmaster.c b/rosapps/lib/libjpeg/jdmaster.c new file mode 100644 index 00000000000..2802c5b7b29 --- /dev/null +++ b/rosapps/lib/libjpeg/jdmaster.c @@ -0,0 +1,557 @@ +/* + * jdmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG decompressor. + * These routines are concerned with selecting the modules to be executed + * and with determining the number of passes and the work to be done in each + * pass. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_decomp_master pub; /* public fields */ + + int pass_number; /* # of passes completed */ + + boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ + + /* Saved references to initialized quantizer modules, + * in case we need to switch modes. + */ + struct jpeg_color_quantizer * quantizer_1pass; + struct jpeg_color_quantizer * quantizer_2pass; +} my_decomp_master; + +typedef my_decomp_master * my_master_ptr; + + +/* + * Determine whether merged upsample/color conversion should be used. + * CRUCIAL: this must match the actual capabilities of jdmerge.c! + */ + +LOCAL(boolean) +use_merged_upsample (j_decompress_ptr cinfo) +{ +#ifdef UPSAMPLE_MERGING_SUPPORTED + /* Merging is the equivalent of plain box-filter upsampling */ + if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling) + return FALSE; + /* jdmerge.c only supports YCC=>RGB color conversion */ + if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || + cinfo->out_color_space != JCS_RGB || + cinfo->out_color_components != RGB_PIXELSIZE) + return FALSE; + /* and it only handles 2h1v or 2h2v sampling ratios */ + if (cinfo->comp_info[0].h_samp_factor != 2 || + cinfo->comp_info[1].h_samp_factor != 1 || + cinfo->comp_info[2].h_samp_factor != 1 || + cinfo->comp_info[0].v_samp_factor > 2 || + cinfo->comp_info[1].v_samp_factor != 1 || + cinfo->comp_info[2].v_samp_factor != 1) + return FALSE; + /* furthermore, it doesn't work if we've scaled the IDCTs differently */ + if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size) + return FALSE; + /* ??? also need to test for upsample-time rescaling, when & if supported */ + return TRUE; /* by golly, it'll work... */ +#else + return FALSE; +#endif +} + + +/* + * Compute output image dimensions and related values. + * NOTE: this is exported for possible use by application. + * Hence it mustn't do anything that can't be done twice. + * Also note that it may be called before the master module is initialized! + */ + +GLOBAL(void) +jpeg_calc_output_dimensions (j_decompress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ +#ifdef IDCT_SCALING_SUPPORTED + int ci; + jpeg_component_info *compptr; +#endif + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_READY) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + +#ifdef IDCT_SCALING_SUPPORTED + + /* Compute actual output image dimensions and DCT scaling choices. */ + if (cinfo->scale_num * 8 <= cinfo->scale_denom) { + /* Provide 1/8 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 8L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 8L); + cinfo->min_DCT_scaled_size = 1; + } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { + /* Provide 1/4 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 4L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 4L); + cinfo->min_DCT_scaled_size = 2; + } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { + /* Provide 1/2 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 2L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 2L); + cinfo->min_DCT_scaled_size = 4; + } else { + /* Provide 1/1 scaling */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + cinfo->min_DCT_scaled_size = DCTSIZE; + } + /* In selecting the actual DCT scaling for each component, we try to + * scale up the chroma components via IDCT scaling rather than upsampling. + * This saves time if the upsampler gets to use 1:1 scaling. + * Note this code assumes that the supported DCT scalings are powers of 2. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + int ssize = cinfo->min_DCT_scaled_size; + while (ssize < DCTSIZE && + (compptr->h_samp_factor * ssize * 2 <= + cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) && + (compptr->v_samp_factor * ssize * 2 <= + cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) { + ssize = ssize * 2; + } + compptr->DCT_scaled_size = ssize; + } + + /* Recompute downsampled dimensions of components; + * application needs to know these if using raw downsampled data. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Size in samples, after IDCT scaling */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * + (long) (compptr->h_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * + (long) (compptr->v_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + } + +#else /* !IDCT_SCALING_SUPPORTED */ + + /* Hardwire it to "no scaling" */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, + * and has computed unscaled downsampled_width and downsampled_height. + */ + +#endif /* IDCT_SCALING_SUPPORTED */ + + /* Report number of components in selected colorspace. */ + /* Probably this should be in the color conversion module... */ + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + break; + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + cinfo->out_color_components = RGB_PIXELSIZE; + break; +#endif /* else share code with YCbCr */ + case JCS_YCbCr: + cinfo->out_color_components = 3; + break; + case JCS_CMYK: + case JCS_YCCK: + cinfo->out_color_components = 4; + break; + default: /* else must be same colorspace as in file */ + cinfo->out_color_components = cinfo->num_components; + break; + } + cinfo->output_components = (cinfo->quantize_colors ? 1 : + cinfo->out_color_components); + + /* See if upsampler will want to emit more than one row at a time */ + if (use_merged_upsample(cinfo)) + cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; + else + cinfo->rec_outbuf_height = 1; +} + + +/* + * Several decompression processes need to range-limit values to the range + * 0..MAXJSAMPLE; the input value may fall somewhat outside this range + * due to noise introduced by quantization, roundoff error, etc. These + * processes are inner loops and need to be as fast as possible. On most + * machines, particularly CPUs with pipelines or instruction prefetch, + * a (subscript-check-less) C table lookup + * x = sample_range_limit[x]; + * is faster than explicit tests + * if (x < 0) x = 0; + * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; + * These processes all use a common table prepared by the routine below. + * + * For most steps we can mathematically guarantee that the initial value + * of x is within MAXJSAMPLE+1 of the legal range, so a table running from + * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial + * limiting step (just after the IDCT), a wildly out-of-range value is + * possible if the input data is corrupt. To avoid any chance of indexing + * off the end of memory and getting a bad-pointer trap, we perform the + * post-IDCT limiting thus: + * x = range_limit[x & MASK]; + * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit + * samples. Under normal circumstances this is more than enough range and + * a correct output will be generated; with bogus input data the mask will + * cause wraparound, and we will safely generate a bogus-but-in-range output. + * For the post-IDCT step, we want to convert the data from signed to unsigned + * representation by adding CENTERJSAMPLE at the same time that we limit it. + * So the post-IDCT limiting table ends up looking like this: + * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, + * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0,1,...,CENTERJSAMPLE-1 + * Negative inputs select values from the upper half of the table after + * masking. + * + * We can save some space by overlapping the start of the post-IDCT table + * with the simpler range limiting table. The post-IDCT table begins at + * sample_range_limit + CENTERJSAMPLE. + * + * Note that the table is allocated in near data space on PCs; it's small + * enough and used often enough to justify this. + */ + +LOCAL(void) +prepare_range_limit_table (j_decompress_ptr cinfo) +/* Allocate and fill in the sample_range_limit table */ +{ + JSAMPLE * table; + int i; + + table = (JSAMPLE *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ + cinfo->sample_range_limit = table; + /* First segment of "simple" table: limit[x] = 0 for x < 0 */ + MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); + /* Main part of "simple" table: limit[x] = x */ + for (i = 0; i <= MAXJSAMPLE; i++) + table[i] = (JSAMPLE) i; + table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ + /* End of simple table, rest of first half of post-IDCT table */ + for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) + table[i] = MAXJSAMPLE; + /* Second half of post-IDCT table */ + MEMZERO(table + (2 * (MAXJSAMPLE+1)), + (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), + cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); +} + + +/* + * Master selection of decompression modules. + * This is done once at jpeg_start_decompress time. We determine + * which modules will be used and give them appropriate initialization calls. + * We also initialize the decompressor input side to begin consuming data. + * + * Since jpeg_read_header has finished, we know what is in the SOF + * and (first) SOS markers. We also have all the application parameter + * settings. + */ + +LOCAL(void) +master_selection (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + boolean use_c_buffer; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Initialize dimensions and other stuff */ + jpeg_calc_output_dimensions(cinfo); + prepare_range_limit_table(cinfo); + + /* Width of an output scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* Initialize my private state */ + master->pass_number = 0; + master->using_merged_upsample = use_merged_upsample(cinfo); + + /* Color quantizer selection */ + master->quantizer_1pass = NULL; + master->quantizer_2pass = NULL; + /* No mode changes if not using buffered-image mode. */ + if (! cinfo->quantize_colors || ! cinfo->buffered_image) { + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + } + if (cinfo->quantize_colors) { + if (cinfo->raw_data_out) + ERREXIT(cinfo, JERR_NOTIMPL); + /* 2-pass quantizer only works in 3-component color space. */ + if (cinfo->out_color_components != 3) { + cinfo->enable_1pass_quant = TRUE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + cinfo->colormap = NULL; + } else if (cinfo->colormap != NULL) { + cinfo->enable_external_quant = TRUE; + } else if (cinfo->two_pass_quantize) { + cinfo->enable_2pass_quant = TRUE; + } else { + cinfo->enable_1pass_quant = TRUE; + } + + if (cinfo->enable_1pass_quant) { +#ifdef QUANT_1PASS_SUPPORTED + jinit_1pass_quantizer(cinfo); + master->quantizer_1pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + + /* We use the 2-pass code to map to external colormaps. */ + if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { +#ifdef QUANT_2PASS_SUPPORTED + jinit_2pass_quantizer(cinfo); + master->quantizer_2pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + /* If both quantizers are initialized, the 2-pass one is left active; + * this is necessary for starting with quantization to an external map. + */ + } + + /* Post-processing: in particular, color conversion first */ + if (! cinfo->raw_data_out) { + if (master->using_merged_upsample) { +#ifdef UPSAMPLE_MERGING_SUPPORTED + jinit_merged_upsampler(cinfo); /* does color conversion too */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + jinit_color_deconverter(cinfo); + jinit_upsampler(cinfo); + } + jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); + } + /* Inverse DCT */ + jinit_inverse_dct(cinfo); + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Initialize principal buffer controllers. */ + use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; + jinit_d_coef_controller(cinfo, use_c_buffer); + + if (! cinfo->raw_data_out) + jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* If jpeg_start_decompress will read the whole file, initialize + * progress monitoring appropriately. The input step is counted + * as one pass. + */ + if (cinfo->progress != NULL && ! cinfo->buffered_image && + cinfo->inputctl->has_multiple_scans) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); + /* Count the input pass as done */ + master->pass_number++; + } +#endif /* D_MULTISCAN_FILES_SUPPORTED */ +} + + +/* + * Per-pass setup. + * This is called at the beginning of each output pass. We determine which + * modules will be active during this pass and give them appropriate + * start_pass calls. We also set is_dummy_pass to indicate whether this + * is a "real" output pass or a dummy pass for color quantization. + * (In the latter case, jdapistd.c will crank the pass to completion.) + */ + +METHODDEF(void) +prepare_for_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (master->pub.is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Final pass of 2-pass quantization */ + master->pub.is_dummy_pass = FALSE; + (*cinfo->cquantize->start_pass) (cinfo, FALSE); + (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); + (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + if (cinfo->quantize_colors && cinfo->colormap == NULL) { + /* Select new quantization method */ + if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { + cinfo->cquantize = master->quantizer_2pass; + master->pub.is_dummy_pass = TRUE; + } else if (cinfo->enable_1pass_quant) { + cinfo->cquantize = master->quantizer_1pass; + } else { + ERREXIT(cinfo, JERR_MODE_CHANGE); + } + } + (*cinfo->idct->start_pass) (cinfo); + (*cinfo->coef->start_output_pass) (cinfo); + if (! cinfo->raw_data_out) { + if (! master->using_merged_upsample) + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->upsample->start_pass) (cinfo); + if (cinfo->quantize_colors) + (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); + (*cinfo->post->start_pass) (cinfo, + (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + } + } + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->pass_number + + (master->pub.is_dummy_pass ? 2 : 1); + /* In buffered-image mode, we assume one more output pass if EOI not + * yet reached, but no more passes if EOI has been reached. + */ + if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { + cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); + } + } +} + + +/* + * Finish up at end of an output pass. + */ + +METHODDEF(void) +finish_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (cinfo->quantize_colors) + (*cinfo->cquantize->finish_pass) (cinfo); + master->pass_number++; +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Switch to a new external colormap between output passes. + */ + +GLOBAL(void) +jpeg_new_colormap (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_BUFIMAGE) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (cinfo->quantize_colors && cinfo->enable_external_quant && + cinfo->colormap != NULL) { + /* Select 2-pass quantizer for external colormap use */ + cinfo->cquantize = master->quantizer_2pass; + /* Notify quantizer of colormap change */ + (*cinfo->cquantize->new_color_map) (cinfo); + master->pub.is_dummy_pass = FALSE; /* just in case */ + } else + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +/* + * Initialize master decompression control and select active modules. + * This is performed at the start of jpeg_start_decompress. + */ + +GLOBAL(void) +jinit_master_decompress (j_decompress_ptr cinfo) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_decomp_master)); + cinfo->master = (struct jpeg_decomp_master *) master; + master->pub.prepare_for_output_pass = prepare_for_output_pass; + master->pub.finish_output_pass = finish_output_pass; + + master->pub.is_dummy_pass = FALSE; + + master_selection(cinfo); +} diff --git a/rosapps/lib/libjpeg/jdmerge.c b/rosapps/lib/libjpeg/jdmerge.c new file mode 100644 index 00000000000..3239ddbde82 --- /dev/null +++ b/rosapps/lib/libjpeg/jdmerge.c @@ -0,0 +1,1024 @@ +/* + * jdmerge.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains code for merged upsampling/color conversion. + * + * This file combines functions from jdsample.c and jdcolor.c; + * read those files first to understand what's going on. + * + * When the chroma components are to be upsampled by simple replication + * (ie, box filtering), we can save some work in color conversion by + * calculating all the output pixels corresponding to a pair of chroma + * samples at one time. In the conversion equations + * R = Y + K1 * Cr + * G = Y + K2 * Cb + K3 * Cr + * B = Y + K4 * Cb + * only the Y term varies among the group of pixels corresponding to a pair + * of chroma samples, so the rest of the terms can be calculated just once. + * At typical sampling ratios, this eliminates half or three-quarters of the + * multiplications needed for color conversion. + * + * This file currently provides implementations for the following cases: + * YCbCr => RGB color conversion only. + * Sampling ratios of 2h1v or 2h2v. + * No scaling needed at upsample time. + * Corner-aligned (non-CCIR601) sampling alignment. + * Other special cases could be added, but in most applications these are + * the only common cases. (For uncommon cases we fall back on the more + * general code in jdsample.c and jdcolor.c.) + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef UPSAMPLE_MERGING_SUPPORTED + +#ifdef HAVE_MMX_INTEL_MNEMONICS + __int64 const1 = 0x59BA0000D24B59BA; // Cr_r Cr_b Cr_g Cr_r + __int64 const2 = 0x00007168E9FA0000; // Cb-r Cb_b Cb_g Cb_r + __int64 const5 = 0x0000D24B59BA0000; // Cr_b Cr_g Cr_r Cr_b + __int64 const6 = 0x7168E9FA00007168; // Cb_b Cb_g Cb_r Cb_b + + // constants for factors (One_Half/fix(x)) << 2 + + __int64 const05 = 0x0001000000000001; // Cr_r Cr_b Cr_g Cr_r + __int64 const15 = 0x00000001FFFA0000; // Cb-r Cb_b Cb_g Cb_r + __int64 const45 = 0x0000000000010000; // Cr_b Cr_g Cr_r Cr_b + __int64 const55 = 0x0001FFFA00000001; // Cb_b Cb_g Cb_r Cb_b +#endif + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Pointer to routine to do actual upsampling/conversion of one row group */ + JMETHOD(void, upmethod, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf)); + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ + + /* For 2:1 vertical sampling, we produce two output rows at a time. + * We need a "spare" row buffer to hold the second output row if the + * application provides just a one-row buffer; we also use the spare + * to discard the dummy last row if the image height is odd. + */ + JSAMPROW spare_row; + boolean spare_full; /* T if spare buffer is occupied */ + + JDIMENSION out_row_width; /* samples per output row */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. + * This is taken directly from jdcolor.c; see that file for more info. + */ + +LOCAL(void) +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int i; + INT32 x; + SHIFT_TEMPS + + upsample->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + upsample->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + upsample->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + upsample->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF(void) +start_pass_merged_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the spare buffer empty */ + upsample->spare_full = FALSE; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * The control routine just handles the row buffering considerations. + */ + +METHODDEF(void) +merged_2v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 2:1 vertical sampling case: may need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPROW work_ptrs[2]; + JDIMENSION num_rows; /* number of rows returned to caller */ + + if (upsample->spare_full) { + /* If we have a spare row saved from a previous cycle, just return it. */ + jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, + 1, upsample->out_row_width); + num_rows = 1; + upsample->spare_full = FALSE; + } else { + /* Figure number of rows to return to caller. */ + num_rows = 2; + /* Not more than the distance to the end of the image. */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + /* Create output pointer array for upsampler. */ + work_ptrs[0] = output_buf[*out_row_ctr]; + if (num_rows > 1) { + work_ptrs[1] = output_buf[*out_row_ctr + 1]; + } else { + work_ptrs[1] = upsample->spare_row; + upsample->spare_full = TRUE; + } + /* Now do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs); + } + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (! upsample->spare_full) + (*in_row_group_ctr)++; +} + + +METHODDEF(void) +merged_1v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 1:1 vertical sampling case: much easier, never need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Just do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, + output_buf + *out_row_ctr); + /* Adjust counts */ + (*out_row_ctr)++; + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by the control routines to do + * the actual upsampling/conversion. One row group is processed per call. + * + * Note: since we may be writing directly into application-supplied buffers, + * we have to be honest about the output width; we can't assume the buffer + * has been rounded up to an even width. + */ + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. + */ + +METHODDEF(void) +h2v1_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + + + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr; + JSAMPROW inptr0, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr0 = input_buf[0][in_row_group_ctr]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr = output_buf[0]; + /* Loop for each pair of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 2 Y values and emit 2 pixels */ + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr0); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + } +} + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. + */ + +#ifdef HAVE_MMX_INTEL_MNEMONICS +__inline METHODDEF(void) +h2v2_merged_upsample_orig (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf); +__inline METHODDEF(void) +h2v2_merged_upsample_mmx (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf); +#endif + +METHODDEF(void) +h2v2_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf); + +#ifdef HAVE_MMX_INTEL_MNEMONICS +METHODDEF(void) +h2v2_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ +if (MMXAvailable && (cinfo->image_width >= 8)) + h2v2_merged_upsample_mmx (cinfo, input_buf, in_row_group_ctr, output_buf); +else + h2v2_merged_upsample_orig (cinfo, input_buf, in_row_group_ctr, output_buf); + +} + +__inline METHODDEF(void) +h2v2_merged_upsample_orig (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr0, outptr1; + JSAMPROW inptr00, inptr01, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr00 = input_buf[0][in_row_group_ctr*2]; + inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr0 = output_buf[0]; + outptr1 = output_buf[1]; + /* Loop for each group of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 4 Y values and emit 4 pixels */ + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr00); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + y = GETJSAMPLE(*inptr01); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + } +} + +/* + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. + */ +__inline METHODDEF(void) +h2v2_merged_upsample_mmx (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + // added for MMX + __int64 const128 = 0x0080008000800080; + __int64 empty = 0x0000000000000000; + __int64 davemask = 0x0000FFFFFFFF0000; + //////////////////////////////// + + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr0, outptr1; + JSAMPROW inptr00, inptr01, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + + // Added for MMX + register int width = cinfo->image_width; + int cols = cinfo->output_width; + int cols_asm = (cols >> 3); + int diff = cols - (cols_asm<<3); + int cols_asm_copy = cols_asm; + + /////////////////////////////////////// + + inptr00 = input_buf[0][in_row_group_ctr*2]; + inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr0 = output_buf[0]; + outptr1 = output_buf[1]; + /* Loop for each group of output pixels */ + + + _asm + { + mov esi, inptr00 + + mov eax, inptr01 + + mov ebx, inptr2 + + mov ecx, inptr1 + + mov edi, outptr0 + + mov edx, outptr1 + +do_next16: + + movd mm0, [ebx] ; Cr7 Cr6.....Cr1 Cr0 + + pxor mm6, mm6 + + punpcklbw mm0, mm0 ; Cr3 Cr3 Cr2 Cr2 Cr1 Cr1 Cr0 Cr0 + + movq mm7, const128 + + punpcklwd mm0, mm0 ; Cr1 Cr1 Cr1 Cr1 Cr0 Cr0 Cr0 Cr0 + + movq mm4, mm0 + + punpcklbw mm0, mm6 ; Cr0 Cr0 Cr0 Cr0 + + psubsw mm0, mm7 ; Cr0 - 128:Cr0-128:Cr0-128:Cr0 -128 + + movd mm1, [ecx] ; Cb7 Cb6...... Cb1 Cb0 + + psllw mm0, 2 ; left shift by 2 bits + + punpcklbw mm1, mm1 ; Cb3 Cb3 Cb2 Cb2 Cb1 Cb1 Cb0 Cb0 + + paddsw mm0, const05 ; add (one_half/fix(x)) << 2 + + punpcklwd mm1, mm1 ; Cb1 Cb1 Cb1 Cb1 Cb0 Cb0 Cb0 Cb0 + + movq mm5, mm1 + + pmulhw mm0, const1 ; multiply by (fix(x) >> 1) + + punpcklbw mm1, mm6 ; Cb0 Cb0 Cb0 Cb0 + + punpckhbw mm4, mm6 ; Cr1 Cr1 Cr1 Cr1 + + psubsw mm1, mm7 ; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128 + + punpckhbw mm5, mm6 ; Cb1 Cb1 Cb1 Cb1 + + psllw mm1, 2 ; left shift by 2 bits + + paddsw mm1, const15 ; add (one_half/fix(x)) << 2 + + psubsw mm4, mm7 ; Cr1 - 128:Cr1-128:Cr1-128:Cr1 -128 + + psubsw mm5, mm7 ; Cb1 - 128:Cb1-128:Cb1-128:Cb1 -128 + + pmulhw mm1, const2 ; multiply by (fix(x) >> 1) + + psllw mm4, 2 ; left shift by 2 bits + + psllw mm5, 2 ; left shift by 2 bits + + paddsw mm4, const45 ; add (one_half/fix(x)) << 2 + + movd mm7, [esi] ; Y13 Y12 Y9 Y8 Y5 Y4 Y1 Y0 + + pmulhw mm4, const5 ; multiply by (fix(x) >> 1) + + movq mm6, mm7 + + punpcklbw mm7, mm7 ; Y5 Y5 Y4 Y4 Y1 Y1 Y0 Y0 + + paddsw mm5, const55 ; add (one_half/fix(x)) << 2 + + paddsw mm0, mm1 ; cred0 cbl0 cgr0 cred0 + + movq mm1, mm7 + + pmulhw mm5, const6 ; multiply by (fix(x) >> 1) + + movq mm2, mm0 ; cred0 cbl0 cgr0 cred0 + + punpcklwd mm7, mm6 ; Y5 Y4 Y1 Y1 Y1 Y0 Y0 Y0 + + pand mm2, davemask ; 0 cbl0 cgr0 0 + + psrlq mm1, 16 ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1 + + psrlq mm2, 16 ; 0 0 cbl0 cgr0 + + punpcklbw mm7, empty ; Y1 Y0 Y0 Y0 + + paddsw mm4, mm5 ; cbl1 cgr1 cred1 cbl1 + + movq mm3, mm4 ; cbl1 cgr1 cred1 cbl1 + + pand mm3, davemask ; 0 cgr1 cred1 0 + + paddsw mm7, mm0 ; r1 b0 g0 r0 + + psllq mm3, 16 ; cgr1 cred1 0 0 + + movq mm6, mm1 ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1 + + por mm2, mm3 ; cgr1 cred1 cbl0 cgr0 + + punpcklbw mm6, empty ; Y4 Y4 Y1 Y1 + + movd mm3, [eax] ; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2 + + paddsw mm6, mm2 ; g4 r4 b1 g1 + + packuswb mm7, mm6 ; g4 r4 b1 g1 r1 b0 g0 r0 + + movq mm6, mm3 ; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2 + + punpcklbw mm3, mm3 ; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2 + + movq [edi], mm7 ; move to memory g4 r4 b1 g1 r1 b0 g0 r0 + + movq mm5, mm3 ; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2 + + punpcklwd mm3, mm6 ; X X X X Y3 Y2 Y2 Y2 + + punpcklbw mm3, empty ; Y3 Y2 Y2 Y2 + + psrlq mm5, 16 ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3 + + paddsw mm3, mm0 ; r3 b2 g2 r2 + + movq mm6, mm5 ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3 + + movq mm0, mm1 ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1 + + punpckldq mm6, mm6 ; X X X X Y6 Y6 Y3 Y3 + + punpcklbw mm6, empty ; Y6 Y6 Y3 Y3 + + psrlq mm1, 24 ; 0 0 0 0 0 Y5 Y5 Y4 + + paddsw mm6, mm2 ; g6 r6 b3 g3 + + packuswb mm3, mm6 ; g6 r6 b3 g3 r3 b2 g2 r2 + + movq mm2, mm5 ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3 + + psrlq mm0, 32 ; 0 0 0 0 0 0 Y5 Y5 + + movq [edx], mm3 ; move to memory g6 r6 b3 g3 r3 b2 g2 r2 + + punpcklwd mm1, mm0 ; X X X X Y5 Y5 Y5 Y4 + + psrlq mm5, 24 ; 0 0 0 0 0 Y7 Y7 Y6 + + movd mm0, [ebx] ; Cr9 Cr8.....Cr3 Cr2 + + psrlq mm2, 32 ; 0 0 0 0 0 0 Y7 Y7 + + psrlq mm0, 16 + + punpcklbw mm1, empty ; Y5 Y5 Y5 Y4 + + punpcklwd mm5, mm2 ; X X X X Y7 Y7 Y7 Y6 + + paddsw mm1, mm4 ; b5 g5 r5 b4 + + punpcklbw mm5, empty ; Y7 Y7 Y7 Y6 + + pxor mm6, mm6 ; clear mm6 registr + + punpcklbw mm0, mm0 ; X X X X Cr3 Cr3 Cr2 Cr2 + + paddsw mm5, mm4 ; b7 g7 r7 b6 + + punpcklwd mm0, mm0 ; Cr3 Cr3 Cr3 Cr3 Cr2 Cr2 Cr2 Cr2 + + movq mm4, mm0 + + movd mm3, [ecx] ; Cb9 Cb8...... Cb3 Cb2 + + punpcklbw mm0, mm6 ; Cr2 Cr2 Cr2 Cr2 + + psrlq mm3, 16 + + psubsw mm0, const128 ; Cr2 - 128:Cr2-128:Cr2-128:Cr2 -128 + + punpcklbw mm3, mm3 ; X X X X Cb3 Cb3 Cb2 Cb2 + + psllw mm0, 2 ; left shift by 2 bits + + paddsw mm0, const05 ; add (one_half/fix(x)) << 2 + + punpcklwd mm3, mm3 ; Cb3 Cb3 Cb3 Cb3 Cb2 Cb2 Cb2 Cb2 + + movq mm7, mm3 + + pmulhw mm0, const1 ; multiply by (fix(x) >> 1) + + punpcklbw mm3, mm6 ; Cb2 Cb2 Cb2 Cb2 + + psubsw mm3, const128 ; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128 + + punpckhbw mm4, mm6 ; Cr3 Cr3 Cr3 Cr3 + + psllw mm3, 2 ; left shift by 2 bits + + paddsw mm3, const15 ; add (one_half/fix(x)) << 2 + + punpckhbw mm7, mm6 ; Cb3 Cb3 Cb3 Cb3 + + pmulhw mm3, const2 ; multiply by (fix(x) >> 1) + + psubsw mm7, const128 ; Cb3 - 128:Cb3-128:Cb3-128:Cb3 -128 + + paddsw mm0, mm3 ; cred2 cbl2 cgr2 cred2 + + psllw mm7, 2 ; left shift by 2 bits + + psubsw mm4, const128 ; Cr3 - 128:Cr3-128:Cr3-128:Cr3 -128 + + movd mm3, [esi+4] ; Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8 + + psllw mm4, 2 ; left shift by 2 bits + + paddsw mm7, const55 ; add (one_half/fix(x)) << 2 + + movq mm6, mm3 ; Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8 + + movq mm2, mm0 + + pand mm2, davemask + + punpcklbw mm3, mm3 ; Y13 Y13 Y12 Y12 Y9 Y9 Y8 Y8 + + psrlq mm2, 16 + + paddsw mm4, const45 ; add (one_half/fix(x)) << 2 + + punpcklwd mm3, mm6 ; X X X X Y9 Y8 Y8 Y8 + + pmulhw mm4, const5 ; multiply by (fix(x) >> 1) + + pmulhw mm7, const6 ; multiply by (fix(x) >> 1) + + punpcklbw mm3, empty ; Y9 Y8 Y8 Y8 + + paddsw mm4, mm7 ; cbl3 cgr3 cred3 cbl3 + + paddsw mm3, mm0 ; r9 b8 g8 r8 + + movq mm7, mm4 + + packuswb mm1, mm3 ; r9 b8 g8 r8 b5 g5 r5 b4 + + movd mm3, [eax+4] ; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10 + + pand mm7, davemask + + psrlq mm6, 8 ; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9 + + psllq mm7, 16 + + movq [edi+8], mm1 ; move to memory r9 b8 g8 r8 b5 g5 r5 b4 + + por mm2, mm7 + + movq mm7, mm3 ; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10 + + punpcklbw mm3, mm3 ; X X X X Y11 Y11 Y10 Y10 + + pxor mm1, mm1 + + punpcklwd mm3, mm7 ; X X X X Y11 Y10 Y10 Y10 + + punpcklbw mm3, mm1 ; Y11 Y10 Y10 Y10 + + psrlq mm7, 8 ; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11 + + paddsw mm3, mm0 ; r11 b10 g10 r10 + + movq mm0, mm7 ; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11 + + packuswb mm5, mm3 ; r11 b10 g10 r10 b7 g7 r7 b6 + + punpcklbw mm7, mm7 ; X X X X Y14 Y14 Y11 Y11 + + movq [edx+8], mm5 ; move to memory r11 b10 g10 r10 b7 g7 r7 b6 + + movq mm3, mm6 ; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9 + + punpcklbw mm6, mm6 ; X X X X Y12 Y12 Y9 Y9 + + punpcklbw mm7, mm1 ; Y14 Y14 Y11 Y11 + + punpcklbw mm6, mm1 ; Y12 Y12 Y9 Y9 + + paddsw mm7, mm2 ; g14 r14 b11 g11 + + paddsw mm6, mm2 ; g12 r12 b9 g9 + + psrlq mm3, 8 ; 0 0 Y21 Y20 Y17 Y16 Y13 Y12 + + movq mm1, mm3 ; 0 0 Y21 Y20 Y17 Y16 Y13 Y12 + + punpcklbw mm3, mm3 ; X X X X Y13 Y13 Y12 Y12 + + add esi, 8 + + psrlq mm3, 16 ; X X X X X X Y13 Y13 modified on 09/24 + + punpcklwd mm1, mm3 ; X X X X Y13 Y13 Y13 Y12 + + add eax, 8 + + psrlq mm0, 8 ; 0 0 Y23 Y22 Y19 Y18 Y15 Y14 + + punpcklbw mm1, empty ; Y13 Y13 Y13 Y12 + + movq mm5, mm0 ; 0 0 Y23 Y22 Y19 Y18 Y15 Y14 + + punpcklbw mm0, mm0 ; X X X X Y15 Y15 Y14 Y14 + + paddsw mm1, mm4 ; b13 g13 r13 b12 + + psrlq mm0, 16 ; X X X X X X Y15 Y15 + + add edi, 24 + + punpcklwd mm5, mm0 ; X X X X Y15 Y15 Y15 Y14 + + packuswb mm6, mm1 ; b13 g13 r13 b12 g12 r12 b9 g9 + + add edx, 24 + + punpcklbw mm5, empty ; Y15 Y15 Y15 Y14 + + add ebx, 4 + + paddsw mm5, mm4 ; b15 g15 r15 b14 + + movq [edi-8], mm6 ; move to memory b13 g13 r13 b12 g12 r12 b9 g9 + + packuswb mm7, mm5 ; b15 g15 r15 b14 g14 r14 b11 g11 + + add ecx, 4 + + movq [edx-8], mm7 ; move to memory b15 g15 r15 b14 g14 r14 b11 g11 + + dec cols_asm + + jnz do_next16 + + EMMS + + } + + + inptr1 += (cols_asm_copy<<2); + + inptr2 += (cols_asm_copy<<2); + + inptr00 += (cols_asm_copy<<3); + + inptr01 += (cols_asm_copy<<3); + + outptr0 += cols_asm_copy*24; + + outptr1 += cols_asm_copy*24; + + //for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + /*cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb];*/ + /* Fetch 4 Y values and emit 4 pixels */ + /*y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + } */ + + + for (col = diff >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 4 Y values and emit 4 pixels */ + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + } + + + /* If image width is odd, do the last output column separately */ + //if (cinfo->output_width & 1) { + if (diff & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr00); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + y = GETJSAMPLE(*inptr01); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + } +} +#else + + +METHODDEF(void) +h2v2_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr0, outptr1; + JSAMPROW inptr00, inptr01, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr00 = input_buf[0][in_row_group_ctr*2]; + inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr0 = output_buf[0]; + outptr1 = output_buf[1]; + /* Loop for each group of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 4 Y values and emit 4 pixels */ + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr00); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + y = GETJSAMPLE(*inptr01); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + } +} +#endif + + +/* + * Module initialization routine for merged upsampling/color conversion. + * + * NB: this is called under the conditions determined by use_merged_upsample() + * in jdmaster.c. That routine MUST correspond to the actual capabilities + * of this module; no safety checks are made here. + */ + +GLOBAL(void) +jinit_merged_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_merged_upsample; + upsample->pub.need_context_rows = FALSE; + + upsample->out_row_width = cinfo->output_width * cinfo->out_color_components; + + if (cinfo->max_v_samp_factor == 2) { + upsample->pub.upsample = merged_2v_upsample; + upsample->upmethod = h2v2_merged_upsample; + /* Allocate a spare row buffer */ + upsample->spare_row = (JSAMPROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE))); + } else { + upsample->pub.upsample = merged_1v_upsample; + upsample->upmethod = h2v1_merged_upsample; + /* No spare row needed */ + upsample->spare_row = NULL; + } + + build_ycc_rgb_table(cinfo); +} + +#endif /* UPSAMPLE_MERGING_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jdphuff.c b/rosapps/lib/libjpeg/jdphuff.c new file mode 100644 index 00000000000..22678099451 --- /dev/null +++ b/rosapps/lib/libjpeg/jdphuff.c @@ -0,0 +1,668 @@ +/* + * jdphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines for progressive JPEG. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdhuff.c */ + + +#ifdef D_PROGRESSIVE_SUPPORTED + +/* + * Expanded entropy decoder object for progressive Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).EOBRUN = (src).EOBRUN, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */ +} phuff_entropy_decoder; + +typedef phuff_entropy_decoder * phuff_entropy_ptr; + +/* Forward declarations */ +METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band, bad; + int ci, coefi, tbl; + int *coef_bit_ptr; + jpeg_component_info * compptr; + + is_DC_band = (cinfo->Ss == 0); + + /* Validate scan parameters */ + bad = FALSE; + if (is_DC_band) { + if (cinfo->Se != 0) + bad = TRUE; + } else { + /* need not check Ss/Se < 0 since they came from unsigned bytes */ + if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2) + bad = TRUE; + /* AC scans may have only one component */ + if (cinfo->comps_in_scan != 1) + bad = TRUE; + } + if (cinfo->Ah != 0) { + /* Successive approximation refinement scan: must have Al = Ah-1. */ + if (cinfo->Al != cinfo->Ah-1) + bad = TRUE; + } + if (cinfo->Al > 13) /* need not check for < 0 */ + bad = TRUE; + /* Arguably the maximum Al value should be less than 13 for 8-bit precision, + * but the spec doesn't say so, and we try to be liberal about what we + * accept. Note: large Al values could result in out-of-range DC + * coefficients during early scans, leading to bizarre displays due to + * overflows in the IDCT math. But we won't crash. + */ + if (bad) + ERREXIT4(cinfo, JERR_BAD_PROGRESSION, + cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); + /* Update progression status, and verify that scan order is legal. + * Note that inter-scan inconsistencies are treated as warnings + * not fatal errors ... not clear if this is right way to behave. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + int cindex = cinfo->cur_comp_info[ci]->component_index; + coef_bit_ptr = & cinfo->coef_bits[cindex][0]; + if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); + for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { + int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; + if (cinfo->Ah != expected) + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); + coef_bit_ptr[coefi] = cinfo->Al; + } + } + + /* Select MCU decoding routine */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_first; + else + entropy->pub.decode_mcu = decode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_refine; + else + entropy->pub.decode_mcu = decode_mcu_AC_refine; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Make sure requested tables are present, and compute derived tables. + * We may build same derived table more than once, but it's not expensive. + */ + if (is_DC_band) { + if (cinfo->Ah == 0) { /* DC refinement needs no table */ + tbl = compptr->dc_tbl_no; + jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, + & entropy->derived_tbls[tbl]); + } + } else { + tbl = compptr->ac_tbl_no; + jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, + & entropy->derived_tbls[tbl]); + /* remember the single active table */ + entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->pub.insufficient_data = FALSE; + + /* Initialize private state variables */ + entropy->saved.EOBRUN = 0; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Re-init EOB run count, too */ + entropy->saved.EOBRUN = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Huffman MCU decoding. + * Each of these routines decodes and returns one MCU's worth of + * Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. + * + * We return FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * spectral selection, since we'll just re-assign them on the next call. + * Successive approximation AC refinement has to be more careful, however.) + */ + +/* + * MCU decoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Al = cinfo->Al; + register int s, r; + int blkn, ci; + JBLOCKROW block; + BITREAD_STATE_VARS; + savable_state state; + d_derived_tbl * tbl; + jpeg_component_info * compptr; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + tbl = entropy->derived_tbls[compptr->dc_tbl_no]; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, tbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + /* Convert DC difference to actual value, update last_dc_val */ + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */ + (*block)[0] = (JCOEF) (s << Al); + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int Al = cinfo->Al; + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state. + * We can avoid loading/saving bitread state if in an EOB run. + */ + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + + /* There is always only one block per MCU */ + + if (EOBRUN > 0) /* if it's a band of zeroes... */ + EOBRUN--; /* ...process it now (we do nothing) */ + else { + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + for (k = cinfo->Ss; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, return FALSE, label2); + r = s >> 4; + s &= 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Scale and output coefficient in natural (dezigzagged) order */ + (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); + } else { + if (r == 15) { /* ZRL */ + k += 15; /* skip 15 zeroes in band */ + } else { /* EOBr, run length is 2^r + appended bits */ + EOBRUN = 1 << r; + if (r) { /* EOBr, r > 0 */ + CHECK_BIT_BUFFER(br_state, r, return FALSE); + r = GET_BITS(r); + EOBRUN += r; + } + EOBRUN--; /* this band is processed at this moment */ + break; /* force end-of-band */ + } + } + } + + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + } + + /* Completed MCU, so update state */ + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF(boolean) +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int blkn; + JBLOCKROW block; + BITREAD_STATE_VARS; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Not worth the cycles to check insufficient_data here, + * since we will not change the data anyway if we read zeroes. + */ + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* Encoded data is simply the next bit of the two's-complement DC value */ + CHECK_BIT_BUFFER(br_state, 1, return FALSE); + if (GET_BITS(1)) + (*block)[0] |= p1; + /* Note: since we use |=, repeating the assignment later is safe */ + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC successive approximation refinement scan. + */ + +METHODDEF(boolean) +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + JCOEFPTR thiscoef; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + int num_newnz; + int newnz_pos[DCTSIZE2]; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, don't modify the MCU. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + + /* There is always only one block per MCU */ + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + /* If we are forced to suspend, we must undo the assignments to any newly + * nonzero coefficients in the block, because otherwise we'd get confused + * next time about which coefficients were already nonzero. + * But we need not undo addition of bits to already-nonzero coefficients; + * instead, we can test the current bit to see if we already did it. + */ + num_newnz = 0; + + /* initialize coefficient loop counter to start of band */ + k = cinfo->Ss; + + if (EOBRUN == 0) { + for (; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, goto undoit, label3); + r = s >> 4; + s &= 15; + if (s) { + if (s != 1) /* size of new coef should always be 1 */ + WARNMS(cinfo, JWRN_HUFF_BAD_CODE); + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) + s = p1; /* newly nonzero coef is positive */ + else + s = m1; /* newly nonzero coef is negative */ + } else { + if (r != 15) { + EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ + if (r) { + CHECK_BIT_BUFFER(br_state, r, goto undoit); + r = GET_BITS(r); + EOBRUN += r; + } + break; /* rest of block is handled by EOB logic */ + } + /* note s = 0 for processing ZRL */ + } + /* Advance over already-nonzero coefs and r still-zero coefs, + * appending correction bits to the nonzeroes. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + do { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } else { + if (--r < 0) + break; /* reached target zero coefficient */ + } + k++; + } while (k <= Se); + if (s) { + int pos = jpeg_natural_order[k]; + /* Output newly nonzero coefficient */ + (*block)[pos] = (JCOEF) s; + /* Remember its position in case we have to suspend */ + newnz_pos[num_newnz++] = pos; + } + } + } + + if (EOBRUN > 0) { + /* Scan any remaining coefficient positions after the end-of-band + * (the last newly nonzero coefficient, if any). Append a correction + * bit to each already-nonzero coefficient. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + for (; k <= Se; k++) { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } + } + /* Count one block completed in EOB run */ + EOBRUN--; + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; + +undoit: + /* Re-zero any output coefficients that we made newly nonzero */ + while (num_newnz > 0) + (*block)[newnz_pos[--num_newnz]] = 0; + + return FALSE; +} + + +/* + * Module initialization routine for progressive Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int *coef_bit_ptr; + int ci, i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_phuff_decoder; + + /* Mark derived tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + } + + /* Create progression status table */ + cinfo->coef_bits = (int (*)[DCTSIZE2]) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components*DCTSIZE2*SIZEOF(int)); + coef_bit_ptr = & cinfo->coef_bits[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (i = 0; i < DCTSIZE2; i++) + *coef_bit_ptr++ = -1; +} + +#endif /* D_PROGRESSIVE_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jdpostct.c b/rosapps/lib/libjpeg/jdpostct.c new file mode 100644 index 00000000000..571563d728e --- /dev/null +++ b/rosapps/lib/libjpeg/jdpostct.c @@ -0,0 +1,290 @@ +/* + * jdpostct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the decompression postprocessing controller. + * This controller manages the upsampling, color conversion, and color + * quantization/reduction steps; specifically, it controls the buffering + * between upsample/color conversion and color quantization/reduction. + * + * If no color quantization/reduction is required, then this module has no + * work to do, and it just hands off to the upsample/color conversion code. + * An integrated upsample/convert/quantize process would replace this module + * entirely. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_post_controller pub; /* public fields */ + + /* Color quantization source buffer: this holds output data from + * the upsample/color conversion step to be passed to the quantizer. + * For two-pass color quantization, we need a full-image buffer; + * for one-pass operation, a strip buffer is sufficient. + */ + jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ + JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ + JDIMENSION strip_height; /* buffer size in rows */ + /* for two-pass mode only: */ + JDIMENSION starting_row; /* row # of first row in current strip */ + JDIMENSION next_row; /* index of next row to fill/empty in strip */ +} my_post_controller; + +typedef my_post_controller * my_post_ptr; + + +/* Forward declarations */ +METHODDEF(void) post_process_1pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF(void) post_process_prepass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +METHODDEF(void) post_process_2pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->quantize_colors) { + /* Single-pass processing with color quantization. */ + post->pub.post_process_data = post_process_1pass; + /* We could be doing buffered-image output before starting a 2-pass + * color quantization; in that case, jinit_d_post_controller did not + * allocate a strip buffer. Use the virtual-array buffer as workspace. + */ + if (post->buffer == NULL) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + (JDIMENSION) 0, post->strip_height, TRUE); + } + } else { + /* For single-pass processing without color quantization, + * I have no work to do; just call the upsampler directly. + */ + post->pub.post_process_data = cinfo->upsample->upsample; + } + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_SAVE_AND_PASS: + /* First pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_prepass; + break; + case JBUF_CRANK_DEST: + /* Second pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_2pass; + break; +#endif /* QUANT_2PASS_SUPPORTED */ + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } + post->starting_row = post->next_row = 0; +} + + +/* + * Process some data in the one-pass (strip buffer) case. + * This is used for color precision reduction as well as one-pass quantization. + */ + +METHODDEF(void) +post_process_1pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Fill the buffer, but not more than what we can dump out in one go. */ + /* Note we rely on the upsampler to detect bottom of image. */ + max_rows = out_rows_avail - *out_row_ctr; + if (max_rows > post->strip_height) + max_rows = post->strip_height; + num_rows = 0; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &num_rows, max_rows); + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer, output_buf + *out_row_ctr, (int) num_rows); + *out_row_ctr += num_rows; +} + + +#ifdef QUANT_2PASS_SUPPORTED + +/* + * Process some data in the first pass of 2-pass quantization. + */ + +METHODDEF(void) +post_process_prepass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION old_next_row, num_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, TRUE); + } + + /* Upsample some data (up to a strip height's worth). */ + old_next_row = post->next_row; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &post->next_row, post->strip_height); + + /* Allow quantizer to scan new data. No data is emitted, */ + /* but we advance out_row_ctr so outer loop can tell when we're done. */ + if (post->next_row > old_next_row) { + num_rows = post->next_row - old_next_row; + (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, + (JSAMPARRAY) NULL, (int) num_rows); + *out_row_ctr += num_rows; + } + + /* Advance if we filled the strip. */ + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + + +/* + * Process some data in the second pass of 2-pass quantization. + */ + +METHODDEF(void) +post_process_2pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, FALSE); + } + + /* Determine number of rows to emit. */ + num_rows = post->strip_height - post->next_row; /* available in strip */ + max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ + if (num_rows > max_rows) + num_rows = max_rows; + /* We have to check bottom of image here, can't depend on upsampler. */ + max_rows = cinfo->output_height - post->starting_row; + if (num_rows > max_rows) + num_rows = max_rows; + + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer + post->next_row, output_buf + *out_row_ctr, + (int) num_rows); + *out_row_ctr += num_rows; + + /* Advance if we filled the strip. */ + post->next_row += num_rows; + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize postprocessing controller. + */ + +GLOBAL(void) +jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_post_ptr post; + + post = (my_post_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_post_controller)); + cinfo->post = (struct jpeg_d_post_controller *) post; + post->pub.start_pass = start_pass_dpost; + post->whole_image = NULL; /* flag for no virtual arrays */ + post->buffer = NULL; /* flag for no strip buffer */ + + /* Create the quantization buffer, if needed */ + if (cinfo->quantize_colors) { + /* The buffer strip height is max_v_samp_factor, which is typically + * an efficient number of rows for upsampling to return. + * (In the presence of output rescaling, we might want to be smarter?) + */ + post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; + if (need_full_buffer) { + /* Two-pass color quantization: need full-image storage. */ + /* We round up the number of rows to a multiple of the strip height. */ +#ifdef QUANT_2PASS_SUPPORTED + post->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + cinfo->output_width * cinfo->out_color_components, + (JDIMENSION) jround_up((long) cinfo->output_height, + (long) post->strip_height), + post->strip_height); +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + /* One-pass color quantization: just make a strip buffer. */ + post->buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width * cinfo->out_color_components, + post->strip_height); + } + } +} diff --git a/rosapps/lib/libjpeg/jdsample.c b/rosapps/lib/libjpeg/jdsample.c new file mode 100644 index 00000000000..80ffefb2a1c --- /dev/null +++ b/rosapps/lib/libjpeg/jdsample.c @@ -0,0 +1,478 @@ +/* + * jdsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains upsampling routines. + * + * Upsampling input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. Upsampling will normally produce + * max_v_samp_factor pixel rows from each row group (but this could vary + * if the upsampler is applying a scale factor of its own). + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to upsample a single component */ +typedef JMETHOD(void, upsample1_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Color conversion buffer. When using separate upsampling and color + * conversion steps, this buffer holds one upsampled row group until it + * has been color converted and output. + * Note: we do not allocate any storage for component(s) which are full-size, + * ie do not need rescaling. The corresponding entry of color_buf[] is + * simply set to point to the input data array, thereby avoiding copying. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + /* Per-component upsampling method pointers */ + upsample1_ptr methods[MAX_COMPONENTS]; + + int next_row_out; /* counts rows emitted from color_buf */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ + + /* Height of an input row group for each component. */ + int rowgroup_height[MAX_COMPONENTS]; + + /* These arrays save pixel expansion factors so that int_expand need not + * recompute them each time. They are unused for other upsampling methods. + */ + UINT8 h_expand[MAX_COMPONENTS]; + UINT8 v_expand[MAX_COMPONENTS]; +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF(void) +start_pass_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the conversion buffer empty */ + upsample->next_row_out = cinfo->max_v_samp_factor; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * In this version we upsample each component independently. + * We upsample one row group into the conversion buffer, then apply + * color conversion a row at a time. + */ + +METHODDEF(void) +sep_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int ci; + jpeg_component_info * compptr; + JDIMENSION num_rows; + + /* Fill the conversion buffer, if it's empty */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Invoke per-component upsample method. Notice we pass a POINTER + * to color_buf[ci], so that fullsize_upsample can change it. + */ + (*upsample->methods[ci]) (cinfo, compptr, + input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), + upsample->color_buf + ci); + } + upsample->next_row_out = 0; + } + + /* Color-convert and emit rows */ + + /* How many we have in the buffer: */ + num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); + /* Not more than the distance to the end of the image. Need this test + * in case the image height is not a multiple of max_v_samp_factor: + */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + + (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, + (JDIMENSION) upsample->next_row_out, + output_buf + *out_row_ctr, + (int) num_rows); + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + upsample->next_row_out += num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by sep_upsample to upsample pixel values + * of a single component. One row group is processed per call. + */ + + +/* + * For full-size components, we just make color_buf[ci] point at the + * input buffer, and thus avoid copying any data. Note that this is + * safe only because sep_upsample doesn't declare the input row group + * "consumed" until we are done color converting and emitting it. + */ + +METHODDEF(void) +fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = input_data; +} + + +/* + * This is a no-op version used for "uninteresting" components. + * These components will not be referenced by color conversion. + */ + +METHODDEF(void) +noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = NULL; /* safety check */ +} + + +/* + * This version handles any integral sampling ratios. + * This is not used for typical JPEG files, so it need not be fast. + * Nor, for that matter, is it particularly accurate: the algorithm is + * simple replication of the input pixel onto the corresponding output + * pixels. The hi-falutin sampling literature refers to this as a + * "box filter". A box filter tends to introduce visible artifacts, + * so if you are actually going to use 3:1 or 4:1 sampling ratios + * you would be well advised to improve this code. + */ + +METHODDEF(void) +int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + register int h; + JSAMPROW outend; + int h_expand, v_expand; + int inrow, outrow; + + h_expand = upsample->h_expand[compptr->component_index]; + v_expand = upsample->v_expand[compptr->component_index]; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + /* Generate one output row with proper horizontal expansion */ + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + for (h = h_expand; h > 0; h--) { + *outptr++ = invalue; + } + } + /* Generate any additional output rows by duplicating the first one */ + if (v_expand > 1) { + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + v_expand-1, cinfo->output_width); + } + inrow++; + outrow += v_expand; + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. + * It's still a box filter. + */ + +METHODDEF(void) +h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. + * It's still a box filter. + */ + +METHODDEF(void) +h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow, outrow; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + 1, cinfo->output_width); + inrow++; + outrow += 2; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. + * + * The upsampling algorithm is linear interpolation between pixel centers, + * also known as a "triangle filter". This is a good compromise between + * speed and visual quality. The centers of the output pixels are 1/4 and 3/4 + * of the way between input pixel centers. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF(void) +h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register int invalue; + register JDIMENSION colctr; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + /* Special case for first column */ + invalue = GETJSAMPLE(*inptr++); + *outptr++ = (JSAMPLE) invalue; + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ + invalue = GETJSAMPLE(*inptr++) * 3; + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); + } + + /* Special case for last column */ + invalue = GETJSAMPLE(*inptr); + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); + *outptr++ = (JSAMPLE) invalue; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. + * Again a triangle filter; see comments for h2v1 case, above. + * + * It is OK for us to reference the adjacent input rows because we demanded + * context from the main buffer controller (see initialization code). + */ + +METHODDEF(void) +h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr0, inptr1, outptr; +#if BITS_IN_JSAMPLE == 8 + register int thiscolsum, lastcolsum, nextcolsum; +#else + register INT32 thiscolsum, lastcolsum, nextcolsum; +#endif + register JDIMENSION colctr; + int inrow, outrow, v; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + for (v = 0; v < 2; v++) { + /* inptr0 points to nearest input row, inptr1 points to next nearest */ + inptr0 = input_data[inrow]; + if (v == 0) /* next nearest is row above */ + inptr1 = input_data[inrow-1]; + else /* next nearest is row below */ + inptr1 = input_data[inrow+1]; + outptr = output_data[outrow++]; + + /* Special case for first column */ + thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ + /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + } + + /* Special case for last column */ + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); + } + inrow++; + } +} + + +/* + * Module initialization routine for upsampling. + */ + +GLOBAL(void) +jinit_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + int ci; + jpeg_component_info * compptr; + boolean need_buffer, do_fancy; + int h_in_group, v_in_group, h_out_group, v_out_group; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_upsample; + upsample->pub.upsample = sep_upsample; + upsample->pub.need_context_rows = FALSE; /* until we find out differently */ + + if (cinfo->CCIR601_sampling) /* this isn't supported */ + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, + * so don't ask for it. + */ + do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; + + /* Verify we can handle the sampling factors, select per-component methods, + * and create storage as needed. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Compute size of an "input group" after IDCT scaling. This many samples + * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. + */ + h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + h_out_group = cinfo->max_h_samp_factor; + v_out_group = cinfo->max_v_samp_factor; + upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ + need_buffer = TRUE; + if (! compptr->component_needed) { + /* Don't bother to upsample an uninteresting component. */ + upsample->methods[ci] = noop_upsample; + need_buffer = FALSE; + } else if (h_in_group == h_out_group && v_in_group == v_out_group) { + /* Fullsize components can be processed without any work. */ + upsample->methods[ci] = fullsize_upsample; + need_buffer = FALSE; + } else if (h_in_group * 2 == h_out_group && + v_in_group == v_out_group) { + /* Special cases for 2h1v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) + upsample->methods[ci] = h2v1_fancy_upsample; + else + upsample->methods[ci] = h2v1_upsample; + } else if (h_in_group * 2 == h_out_group && + v_in_group * 2 == v_out_group) { + /* Special cases for 2h2v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) { + upsample->methods[ci] = h2v2_fancy_upsample; + upsample->pub.need_context_rows = TRUE; + } else + upsample->methods[ci] = h2v2_upsample; + } else if ((h_out_group % h_in_group) == 0 && + (v_out_group % v_in_group) == 0) { + /* Generic integral-factors upsampling method */ + upsample->methods[ci] = int_upsample; + upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); + upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + if (need_buffer) { + upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) cinfo->output_width, + (long) cinfo->max_h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/rosapps/lib/libjpeg/jdtrans.c b/rosapps/lib/libjpeg/jdtrans.c new file mode 100644 index 00000000000..6c0ab715d32 --- /dev/null +++ b/rosapps/lib/libjpeg/jdtrans.c @@ -0,0 +1,143 @@ +/* + * jdtrans.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding decompression, + * that is, reading raw DCT coefficient arrays from an input JPEG file. + * The routines in jdapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo)); + + +/* + * Read the coefficient arrays from a JPEG file. + * jpeg_read_header must be completed before calling this. + * + * The entire image is read into a set of virtual coefficient-block arrays, + * one per component. The return value is a pointer to the array of + * virtual-array descriptors. These can be manipulated directly via the + * JPEG memory manager, or handed off to jpeg_write_coefficients(). + * To release the memory occupied by the virtual arrays, call + * jpeg_finish_decompress() when done with the data. + * + * An alternative usage is to simply obtain access to the coefficient arrays + * during a buffered-image-mode decompression operation. This is allowed + * after any jpeg_finish_output() call. The arrays can be accessed until + * jpeg_finish_decompress() is called. (Note that any call to the library + * may reposition the arrays, so don't rely on access_virt_barray() results + * to stay valid across library calls.) + * + * Returns NULL if suspended. This case need be checked only if + * a suspending data source is used. + */ + +GLOBAL(jvirt_barray_ptr *) +jpeg_read_coefficients (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize active modules */ + transdecode_master_selection(cinfo); + cinfo->global_state = DSTATE_RDCOEFS; + } + if (cinfo->global_state == DSTATE_RDCOEFS) { + /* Absorb whole file into the coef buffer */ + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return NULL; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* startup underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } + /* Set state so that jpeg_finish_decompress does the right thing */ + cinfo->global_state = DSTATE_STOPPING; + } + /* At this point we should be in state DSTATE_STOPPING if being used + * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access + * to the coefficients during a full buffered-image-mode decompression. + */ + if ((cinfo->global_state == DSTATE_STOPPING || + cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) { + return cinfo->coef->coef_arrays; + } + /* Oops, improper usage */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return NULL; /* keep compiler happy */ +} + + +/* + * Master selection of decompression modules for transcoding. + * This substitutes for jdmaster.c's initialization of the full decompressor. + */ + +LOCAL(void) +transdecode_master_selection (j_decompress_ptr cinfo) +{ + /* This is effectively a buffered-image operation. */ + cinfo->buffered_image = TRUE; + + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Always get a full-image coefficient buffer. */ + jinit_d_coef_controller(cinfo, TRUE); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + + /* Initialize progress monitoring. */ + if (cinfo->progress != NULL) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else if (cinfo->inputctl->has_multiple_scans) { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } else { + nscans = 1; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = 1; + } +} diff --git a/rosapps/lib/libjpeg/jerror.c b/rosapps/lib/libjpeg/jerror.c new file mode 100644 index 00000000000..5802b9962f3 --- /dev/null +++ b/rosapps/lib/libjpeg/jerror.c @@ -0,0 +1,248 @@ +/* + * jerror.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains simple error-reporting and trace-message routines. + * These are suitable for Unix-like systems and others where writing to + * stderr is the right thing to do. Many applications will want to replace + * some or all of these routines. + * + * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile, + * you get a Windows-specific hack to display error messages in a dialog box. + * It ain't much, but it beats dropping error messages into the bit bucket, + * which is what happens to output to stderr under most Windows C compilers. + * + * These routines are used by both the compression and decompression code. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jversion.h" +#include "jerror.h" + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif + + +/* + * Create the message string table. + * We do this from the master message list in jerror.h by re-reading + * jerror.h with a suitable definition for macro JMESSAGE. + * The message table is made an external symbol just in case any applications + * want to refer to it directly. + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_message_table jMsgTable +#endif + +#define JMESSAGE(code,string) string , + +const char * const jpeg_std_message_table[] = { +#include "jerror.h" + NULL +}; + + +/* + * Error exit handler: must not return to caller. + * + * Applications may override this if they want to get control back after + * an error. Typically one would longjmp somewhere instead of exiting. + * The setjmp buffer can be made a private field within an expanded error + * handler object. Note that the info needed to generate an error message + * is stored in the error object, so you can generate the message now or + * later, at your convenience. + * You should make sure that the JPEG object is cleaned up (with jpeg_abort + * or jpeg_destroy) at some point. + */ + +METHODDEF(void) +error_exit (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + exit(EXIT_FAILURE); +} + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. + */ + +METHODDEF(void) +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else + /* Send it to stderr, adding a newline */ + fprintf(stderr, "%s\n", buffer); +#endif +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF(void) +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF(void) +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + boolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF(void) +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +/* + * Fill in the standard error-handling methods in a jpeg_error_mgr object. + * Typical call is: + * struct jpeg_compress_struct cinfo; + * struct jpeg_error_mgr err; + * + * cinfo.err = jpeg_std_error(&err); + * after which the application may override some of the methods. + */ + +GLOBAL(struct jpeg_error_mgr *) +jpeg_std_error (struct jpeg_error_mgr * err) +{ + err->error_exit = error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff --git a/rosapps/lib/libjpeg/jerror.h b/rosapps/lib/libjpeg/jerror.h new file mode 100644 index 00000000000..41a69d5e24a --- /dev/null +++ b/rosapps/lib/libjpeg/jerror.h @@ -0,0 +1,292 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/rosapps/lib/libjpeg/jfdctflt.c b/rosapps/lib/libjpeg/jfdctflt.c new file mode 100644 index 00000000000..79d7a007874 --- /dev/null +++ b/rosapps/lib/libjpeg/jfdctflt.c @@ -0,0 +1,168 @@ +/* + * jfdctflt.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * forward DCT (Discrete Cosine Transform). + * + * This implementation should be more accurate than either of the integer + * DCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_float (FAST_FLOAT * data) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z1, z2, z3, z4, z5, z11, z13; + FAST_FLOAT *dataptr; + int ctr; + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jfdctfst.c b/rosapps/lib/libjpeg/jfdctfst.c new file mode 100644 index 00000000000..ccb378a3b45 --- /dev/null +++ b/rosapps/lib/libjpeg/jfdctfst.c @@ -0,0 +1,224 @@ +/* + * jfdctfst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jfdctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * Again to save a few shifts, the intermediate results between pass 1 and + * pass 2 are not upscaled, but are represented only to integral precision. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#define CONST_BITS 8 + + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */ +#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */ +#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */ +#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */ +#else +#define FIX_0_382683433 FIX(0.382683433) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_707106781 FIX(0.707106781) +#define FIX_1_306562965 FIX(1.306562965) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_ifast (DCTELEM * data) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z1, z2, z3, z4, z5, z11, z13; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jfdctint.c b/rosapps/lib/libjpeg/jfdctint.c new file mode 100644 index 00000000000..0a78b64aee8 --- /dev/null +++ b/rosapps/lib/libjpeg/jfdctint.c @@ -0,0 +1,283 @@ +/* + * jfdctint.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D DCT step produces outputs which are a factor of sqrt(N) + * larger than the true DCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D DCT, + * because the y0 and y4 outputs need not be divided by sqrt(N). + * In the IJG code, this factor of 8 is removed by the quantization step + * (in jcdctmgr.c), NOT in this module. + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (For 12-bit sample data, the intermediate + * array is INT32 anyway.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_islow (DCTELEM * data) +{ + INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + /* Note results are scaled up by sqrt(8) compared to a true DCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); + dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS-PASS1_BITS); + dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS-PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); + dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); + dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); + dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. + * We remove the PASS1_BITS scaling, but leave the results scaled up + * by an overall factor of 8. + */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); + dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, + CONST_BITS+PASS1_BITS); + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jidctflt.c b/rosapps/lib/libjpeg/jidctflt.c new file mode 100644 index 00000000000..0188ce3dfcd --- /dev/null +++ b/rosapps/lib/libjpeg/jidctflt.c @@ -0,0 +1,242 @@ +/* + * jidctflt.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * This implementation should be more accurate than either of the integer + * IDCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a float result. + */ + +#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z5, z10, z11, z12, z13; + JCOEFPTR inptr; + FLOAT_MULT_TYPE * quantptr; + FAST_FLOAT * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = tmp0 + tmp7; + wsptr[DCTSIZE*7] = tmp0 - tmp7; + wsptr[DCTSIZE*1] = tmp1 + tmp6; + wsptr[DCTSIZE*6] = tmp1 - tmp6; + wsptr[DCTSIZE*2] = tmp2 + tmp5; + wsptr[DCTSIZE*5] = tmp2 - tmp5; + wsptr[DCTSIZE*4] = tmp3 + tmp4; + wsptr[DCTSIZE*3] = tmp3 - tmp4; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * And testing floats for zero is relatively expensive, so we don't bother. + */ + + /* Even part */ + + tmp10 = wsptr[0] + wsptr[4]; + tmp11 = wsptr[0] - wsptr[4]; + + tmp13 = wsptr[2] + wsptr[6]; + tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = wsptr[5] + wsptr[3]; + z10 = wsptr[5] - wsptr[3]; + z11 = wsptr[1] + wsptr[7]; + z12 = wsptr[1] - wsptr[7]; + + tmp7 = z11 + z13; + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jidctfst.c b/rosapps/lib/libjpeg/jidctfst.c new file mode 100644 index 00000000000..a94455a0e50 --- /dev/null +++ b/rosapps/lib/libjpeg/jidctfst.c @@ -0,0 +1,1650 @@ +/* + * jidctfst.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jidctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * The dequantized coefficients are not integers because the AA&N scaling + * factors have been incorporated. We represent them scaled up by PASS1_BITS, + * so that the first and second IDCT rounds have the same input scaling. + * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + * avoid a descaling shift; this compromises accuracy rather drastically + * for small quantization table entries, but it saves a lot of shifts. + * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + * so we use a much larger scaling factor to preserve accuracy. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 8 +#define PASS1_BITS 2 +#else +#define CONST_BITS 8 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ +#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ +#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ +#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ +#else +#define FIX_1_082392200 FIX(1.082392200) +#define FIX_1_414213562 FIX(1.414213562) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_613125930 FIX(2.613125930) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + * multiplication will do. For 12-bit data, the multiplier table is + * declared INT32, so a 32-bit multiply will be used. + */ + +#if BITS_IN_JSAMPLE == 8 +#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval)) +#else +#define DEQUANTIZE(coef,quantval) \ + DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) +#endif + + +/* Like DESCALE, but applies to a DCTELEM and produces an int. + * We assume that int right shift is unsigned if INT32 right shift is. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS DCTELEM ishift_temp; +#if BITS_IN_JSAMPLE == 8 +#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ +#else +#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ +#endif +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +#ifdef USE_ACCURATE_ROUNDING +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n)) +#else +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n)) +#endif + +#ifdef HAVE_MMX_INTEL_MNEMONICS +__inline GLOBAL(void) +jpeg_idct_ifast_mmx (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col); +__inline GLOBAL(void) +jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col); +#endif + +GLOBAL(void) +jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col); + + +#ifdef HAVE_MMX_INTEL_MNEMONICS +GLOBAL(void) +jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ +if (MMXAvailable) + jpeg_idct_ifast_mmx(cinfo, compptr, coef_block, output_buf, output_col); +else + jpeg_idct_ifast_orig(cinfo, compptr, coef_block, output_buf, output_col); +} +#else + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL (void) +jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z5, z10, z11, z12, z13; + JCOEFPTR inptr; + IFAST_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS /* for DESCALE */ + ISHIFT_TEMPS /* for IDESCALE */ + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (IFAST_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); + wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); + wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); + wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); + wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5); + wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); + wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); + wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); + tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); + + tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); + tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) + - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; + z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; + z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; + z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif + +#ifdef HAVE_MMX_INTEL_MNEMONICS + + +_inline GLOBAL(void) +jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z5, z10, z11, z12, z13; + JCOEFPTR inptr; + IFAST_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS /* for DESCALE */ + ISHIFT_TEMPS /* for IDESCALE */ + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (IFAST_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | + inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | + inptr[DCTSIZE*7]) == 0) { + /* AC terms all zero */ + int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); + wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); + wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); + wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); + wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5); + wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); + wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); + wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | + wsptr[7]) == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); + tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); + + tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); + tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) + - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; + z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; + z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; + z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + + static __int64 fix_141 = 0x5a825a825a825a82; + static __int64 fix_184n261 = 0xcf04cf04cf04cf04; + static __int64 fix_184 = 0x7641764176417641; + static __int64 fix_n184 = 0x896f896f896f896f; + static __int64 fix_108n184 = 0xcf04cf04cf04cf04; + static __int64 const_0x0080 = 0x0080008000800080; + + +__inline GLOBAL(void) +jpeg_idct_ifast_mmx (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR inptr, + JSAMPARRAY outptr, JDIMENSION output_col) +{ + + int16 workspace[DCTSIZE2 + 4]; /* buffers data between passes */ + int16 *wsptr=workspace; + int16 *quantptr=compptr->dct_table; + + __asm{ + + mov edi, quantptr + mov ebx, inptr + mov esi, wsptr + add esi, 0x07 ;align wsptr to qword + and esi, 0xfffffff8 ;align wsptr to qword + + mov eax, esi + + /* Odd part */ + + + movq mm1, [ebx + 8*10] ;load inptr[DCTSIZE*5] + + pmullw mm1, [edi + 8*10] ;tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + + movq mm0, [ebx + 8*6] ;load inptr[DCTSIZE*3] + + pmullw mm0, [edi + 8*6] ;tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + + movq mm3, [ebx + 8*2] ;load inptr[DCTSIZE*1] + movq mm2, mm1 ;copy tmp6 /* phase 6 */ + + pmullw mm3, [edi + 8*2] ;tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + movq mm4, [ebx + 8*14] ;load inptr[DCTSIZE*1] + paddw mm1, mm0 ;z13 = tmp6 + tmp5; + + pmullw mm4, [edi + 8*14] ;tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + psubw mm2, mm0 ;z10 = tmp6 - tmp5 + + psllw mm2, 2 ;shift z10 + movq mm0, mm2 ;copy z10 + + pmulhw mm2, fix_184n261 ;MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */ + movq mm5, mm3 ;copy tmp4 + + pmulhw mm0, fix_n184 ;MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */ + paddw mm3, mm4 ;z11 = tmp4 + tmp7; + + movq mm6, mm3 ;copy z11 /* phase 5 */ + psubw mm5, mm4 ;z12 = tmp4 - tmp7; + + psubw mm6, mm1 ;z11-z13 + psllw mm5, 2 ;shift z12 + + movq mm4, [ebx + 8*12] ;load inptr[DCTSIZE*6], even part + movq mm7, mm5 ;copy z12 + + pmulhw mm5, fix_108n184 ;MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part + paddw mm3, mm1 ;tmp7 = z11 + z13; + + + /* Even part */ + pmulhw mm7, fix_184 ;MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */ + psllw mm6, 2 + + movq mm1, [ebx + 8*4] ;load inptr[DCTSIZE*2] + + pmullw mm1, [edi + 8*4] ;tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + paddw mm0, mm5 ;tmp10 + + pmullw mm4, [edi + 8*12] ;tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + paddw mm2, mm7 ;tmp12 + + pmulhw mm6, fix_141 ;tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + psubw mm2, mm3 ;tmp6 = tmp12 - tmp7 + + movq mm5, mm1 ;copy tmp1 + paddw mm1, mm4 ;tmp13= tmp1 + tmp3; /* phases 5-3 */ + + psubw mm5, mm4 ;tmp1-tmp3 + psubw mm6, mm2 ;tmp5 = tmp11 - tmp6; + + movq [esi+8*0], mm1 ;save tmp13 in workspace + psllw mm5, 2 ;shift tmp1-tmp3 + + movq mm7, [ebx + 8*0] ;load inptr[DCTSIZE*0] + + pmulhw mm5, fix_141 ;MULTIPLY(tmp1 - tmp3, FIX_1_414213562) + paddw mm0, mm6 ;tmp4 = tmp10 + tmp5; + + pmullw mm7, [edi + 8*0] ;tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + movq mm4, [ebx + 8*8] ;load inptr[DCTSIZE*4] + + pmullw mm4, [edi + 8*8] ;tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + psubw mm5, mm1 ;tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ + + movq [esi+8*4], mm0 ;save tmp4 in workspace + movq mm1, mm7 ;copy tmp0 /* phase 3 */ + + movq [esi+8*2], mm5 ;save tmp12 in workspace + psubw mm1, mm4 ;tmp11 = tmp0 - tmp2; + + paddw mm7, mm4 ;tmp10 = tmp0 + tmp2; + movq mm5, mm1 ;copy tmp11 + + paddw mm1, [esi+8*2] ;tmp1 = tmp11 + tmp12; + movq mm4, mm7 ;copy tmp10 /* phase 2 */ + + paddw mm7, [esi+8*0] ;tmp0 = tmp10 + tmp13; + + psubw mm4, [esi+8*0] ;tmp3 = tmp10 - tmp13; + movq mm0, mm7 ;copy tmp0 + + psubw mm5, [esi+8*2] ;tmp2 = tmp11 - tmp12; + paddw mm7, mm3 ;wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); + + psubw mm0, mm3 ;wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); + + movq [esi + 8*0], mm7 ;wsptr[DCTSIZE*0] + movq mm3, mm1 ;copy tmp1 + + movq [esi + 8*14], mm0 ;wsptr[DCTSIZE*7] + paddw mm1, mm2 ;wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); + + psubw mm3, mm2 ;wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); + + movq [esi + 8*2], mm1 ;wsptr[DCTSIZE*1] + movq mm1, mm4 ;copy tmp3 + + movq [esi + 8*12], mm3 ;wsptr[DCTSIZE*6] + + paddw mm4, [esi+8*4] ;wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); + + psubw mm1, [esi+8*4] ;wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); + + movq [esi + 8*8], mm4 + movq mm7, mm5 ;copy tmp2 + + paddw mm5, mm6 ;wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5) + + movq [esi+8*6], mm1 ; + psubw mm7, mm6 ;wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); + + movq [esi + 8*4], mm5 + + movq [esi + 8*10], mm7 + + + +/*****************************************************************/ + add edi, 8 + add ebx, 8 + add esi, 8 + +/*****************************************************************/ + + + + + movq mm1, [ebx + 8*10] ;load inptr[DCTSIZE*5] + + pmullw mm1, [edi + 8*10] ;tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + + movq mm0, [ebx + 8*6] ;load inptr[DCTSIZE*3] + + pmullw mm0, [edi + 8*6] ;tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + + movq mm3, [ebx + 8*2] ;load inptr[DCTSIZE*1] + movq mm2, mm1 ;copy tmp6 /* phase 6 */ + + pmullw mm3, [edi + 8*2] ;tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + movq mm4, [ebx + 8*14] ;load inptr[DCTSIZE*1] + paddw mm1, mm0 ;z13 = tmp6 + tmp5; + + pmullw mm4, [edi + 8*14] ;tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + psubw mm2, mm0 ;z10 = tmp6 - tmp5 + + psllw mm2, 2 ;shift z10 + movq mm0, mm2 ;copy z10 + + pmulhw mm2, fix_184n261 ;MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */ + movq mm5, mm3 ;copy tmp4 + + pmulhw mm0, fix_n184 ;MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */ + paddw mm3, mm4 ;z11 = tmp4 + tmp7; + + movq mm6, mm3 ;copy z11 /* phase 5 */ + psubw mm5, mm4 ;z12 = tmp4 - tmp7; + + psubw mm6, mm1 ;z11-z13 + psllw mm5, 2 ;shift z12 + + movq mm4, [ebx + 8*12] ;load inptr[DCTSIZE*6], even part + movq mm7, mm5 ;copy z12 + + pmulhw mm5, fix_108n184 ;MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part + paddw mm3, mm1 ;tmp7 = z11 + z13; + + + /* Even part */ + pmulhw mm7, fix_184 ;MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */ + psllw mm6, 2 + + movq mm1, [ebx + 8*4] ;load inptr[DCTSIZE*2] + + pmullw mm1, [edi + 8*4] ;tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + paddw mm0, mm5 ;tmp10 + + pmullw mm4, [edi + 8*12] ;tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + paddw mm2, mm7 ;tmp12 + + pmulhw mm6, fix_141 ;tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + psubw mm2, mm3 ;tmp6 = tmp12 - tmp7 + + movq mm5, mm1 ;copy tmp1 + paddw mm1, mm4 ;tmp13= tmp1 + tmp3; /* phases 5-3 */ + + psubw mm5, mm4 ;tmp1-tmp3 + psubw mm6, mm2 ;tmp5 = tmp11 - tmp6; + + movq [esi+8*0], mm1 ;save tmp13 in workspace + psllw mm5, 2 ;shift tmp1-tmp3 + + movq mm7, [ebx + 8*0] ;load inptr[DCTSIZE*0] + paddw mm0, mm6 ;tmp4 = tmp10 + tmp5; + + pmulhw mm5, fix_141 ;MULTIPLY(tmp1 - tmp3, FIX_1_414213562) + + pmullw mm7, [edi + 8*0] ;tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + movq mm4, [ebx + 8*8] ;load inptr[DCTSIZE*4] + + pmullw mm4, [edi + 8*8] ;tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + psubw mm5, mm1 ;tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ + + movq [esi+8*4], mm0 ;save tmp4 in workspace + movq mm1, mm7 ;copy tmp0 /* phase 3 */ + + movq [esi+8*2], mm5 ;save tmp12 in workspace + psubw mm1, mm4 ;tmp11 = tmp0 - tmp2; + + paddw mm7, mm4 ;tmp10 = tmp0 + tmp2; + movq mm5, mm1 ;copy tmp11 + + paddw mm1, [esi+8*2] ;tmp1 = tmp11 + tmp12; + movq mm4, mm7 ;copy tmp10 /* phase 2 */ + + paddw mm7, [esi+8*0] ;tmp0 = tmp10 + tmp13; + + psubw mm4, [esi+8*0] ;tmp3 = tmp10 - tmp13; + movq mm0, mm7 ;copy tmp0 + + psubw mm5, [esi+8*2] ;tmp2 = tmp11 - tmp12; + paddw mm7, mm3 ;wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); + + psubw mm0, mm3 ;wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); + + movq [esi + 8*0], mm7 ;wsptr[DCTSIZE*0] + movq mm3, mm1 ;copy tmp1 + + movq [esi + 8*14], mm0 ;wsptr[DCTSIZE*7] + paddw mm1, mm2 ;wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); + + psubw mm3, mm2 ;wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); + + movq [esi + 8*2], mm1 ;wsptr[DCTSIZE*1] + movq mm1, mm4 ;copy tmp3 + + movq [esi + 8*12], mm3 ;wsptr[DCTSIZE*6] + + paddw mm4, [esi+8*4] ;wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); + + psubw mm1, [esi+8*4] ;wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); + + movq [esi + 8*8], mm4 + movq mm7, mm5 ;copy tmp2 + + paddw mm5, mm6 ;wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5) + + movq [esi+8*6], mm1 ; + psubw mm7, mm6 ;wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); + + movq [esi + 8*4], mm5 + + movq [esi + 8*10], mm7 + + + + +/*****************************************************************/ + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + +/*****************************************************************/ + /* Even part */ + + mov esi, eax + mov eax, outptr + +// tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); +// tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); +// tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); +// tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]); + movq mm0, [esi+8*0] ;wsptr[0,0],[0,1],[0,2],[0,3] + + movq mm1, [esi+8*1] ;wsptr[0,4],[0,5],[0,6],[0,7] + movq mm2, mm0 + + movq mm3, [esi+8*2] ;wsptr[1,0],[1,1],[1,2],[1,3] + paddw mm0, mm1 ;wsptr[0,tmp10],[xxx],[0,tmp13],[xxx] + + movq mm4, [esi+8*3] ;wsptr[1,4],[1,5],[1,6],[1,7] + psubw mm2, mm1 ;wsptr[0,tmp11],[xxx],[0,tmp14],[xxx] + + movq mm6, mm0 + movq mm5, mm3 + + paddw mm3, mm4 ;wsptr[1,tmp10],[xxx],[1,tmp13],[xxx] + movq mm1, mm2 + + psubw mm5, mm4 ;wsptr[1,tmp11],[xxx],[1,tmp14],[xxx] + punpcklwd mm0, mm3 ;wsptr[0,tmp10],[1,tmp10],[xxx],[xxx] + + movq mm7, [esi+8*7] ;wsptr[3,4],[3,5],[3,6],[3,7] + punpckhwd mm6, mm3 ;wsptr[0,tmp13],[1,tmp13],[xxx],[xxx] + + movq mm3, [esi+8*4] ;wsptr[2,0],[2,1],[2,2],[2,3] + punpckldq mm0, mm6 ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13] + + punpcklwd mm1, mm5 ;wsptr[0,tmp11],[1,tmp11],[xxx],[xxx] + movq mm4, mm3 + + movq mm6, [esi+8*6] ;wsptr[3,0],[3,1],[3,2],[3,3] + punpckhwd mm2, mm5 ;wsptr[0,tmp14],[1,tmp14],[xxx],[xxx] + + movq mm5, [esi+8*5] ;wsptr[2,4],[2,5],[2,6],[2,7] + punpckldq mm1, mm2 ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14] + + + paddw mm3, mm5 ;wsptr[2,tmp10],[xxx],[2,tmp13],[xxx] + movq mm2, mm6 + + psubw mm4, mm5 ;wsptr[2,tmp11],[xxx],[2,tmp14],[xxx] + paddw mm6, mm7 ;wsptr[3,tmp10],[xxx],[3,tmp13],[xxx] + + movq mm5, mm3 + punpcklwd mm3, mm6 ;wsptr[2,tmp10],[3,tmp10],[xxx],[xxx] + + psubw mm2, mm7 ;wsptr[3,tmp11],[xxx],[3,tmp14],[xxx] + punpckhwd mm5, mm6 ;wsptr[2,tmp13],[3,tmp13],[xxx],[xxx] + + movq mm7, mm4 + punpckldq mm3, mm5 ;wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13] + + punpcklwd mm4, mm2 ;wsptr[2,tmp11],[3,tmp11],[xxx],[xxx] + + punpckhwd mm7, mm2 ;wsptr[2,tmp14],[3,tmp14],[xxx],[xxx] + + punpckldq mm4, mm7 ;wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14] + movq mm6, mm1 + +// mm0 = ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13] +// mm1 = ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14] + + + movq mm2, mm0 + punpckhdq mm6, mm4 ;wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14] + + punpckldq mm1, mm4 ;wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11] + psllw mm6, 2 + + pmulhw mm6, fix_141 + punpckldq mm0, mm3 ;wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10] + + punpckhdq mm2, mm3 ;wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13] + movq mm7, mm0 + +// tmp0 = tmp10 + tmp13; +// tmp3 = tmp10 - tmp13; + paddw mm0, mm2 ;[0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0] + psubw mm7, mm2 ;[0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3] + +// tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13; + psubw mm6, mm2 ;wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12] +// tmp1 = tmp11 + tmp12; +// tmp2 = tmp11 - tmp12; + movq mm5, mm1 + + + + /* Odd part */ + +// z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; +// z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; +// z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; +// z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; + movq mm3, [esi+8*0] ;wsptr[0,0],[0,1],[0,2],[0,3] + paddw mm1, mm6 ;[0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1] + + movq mm4, [esi+8*1] ;wsptr[0,4],[0,5],[0,6],[0,7] + psubw mm5, mm6 ;[0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2] + + movq mm6, mm3 + punpckldq mm3, mm4 ;wsptr[0,0],[0,1],[0,4],[0,5] + + punpckhdq mm4, mm6 ;wsptr[0,6],[0,7],[0,2],[0,3] + movq mm2, mm3 + +//Save tmp0 and tmp1 in wsptr + movq [esi+8*0], mm0 ;save tmp0 + paddw mm2, mm4 ;wsptr[xxx],[0,z11],[xxx],[0,z13] + + +//Continue with z10 --- z13 + movq mm6, [esi+8*2] ;wsptr[1,0],[1,1],[1,2],[1,3] + psubw mm3, mm4 ;wsptr[xxx],[0,z12],[xxx],[0,z10] + + movq mm0, [esi+8*3] ;wsptr[1,4],[1,5],[1,6],[1,7] + movq mm4, mm6 + + movq [esi+8*1], mm1 ;save tmp1 + punpckldq mm6, mm0 ;wsptr[1,0],[1,1],[1,4],[1,5] + + punpckhdq mm0, mm4 ;wsptr[1,6],[1,7],[1,2],[1,3] + movq mm1, mm6 + +//Save tmp2 and tmp3 in wsptr + paddw mm6, mm0 ;wsptr[xxx],[1,z11],[xxx],[1,z13] + movq mm4, mm2 + +//Continue with z10 --- z13 + movq [esi+8*2], mm5 ;save tmp2 + punpcklwd mm2, mm6 ;wsptr[xxx],[xxx],[0,z11],[1,z11] + + psubw mm1, mm0 ;wsptr[xxx],[1,z12],[xxx],[1,z10] + punpckhwd mm4, mm6 ;wsptr[xxx],[xxx],[0,z13],[1,z13] + + movq mm0, mm3 + punpcklwd mm3, mm1 ;wsptr[xxx],[xxx],[0,z12],[1,z12] + + movq [esi+8*3], mm7 ;save tmp3 + punpckhwd mm0, mm1 ;wsptr[xxx],[xxx],[0,z10],[1,z10] + + movq mm6, [esi+8*4] ;wsptr[2,0],[2,1],[2,2],[2,3] + punpckhdq mm0, mm2 ;wsptr[0,z10],[1,z10],[0,z11],[1,z11] + + movq mm7, [esi+8*5] ;wsptr[2,4],[2,5],[2,6],[2,7] + punpckhdq mm3, mm4 ;wsptr[0,z12],[1,z12],[0,z13],[1,z13] + + movq mm1, [esi+8*6] ;wsptr[3,0],[3,1],[3,2],[3,3] + movq mm4, mm6 + + punpckldq mm6, mm7 ;wsptr[2,0],[2,1],[2,4],[2,5] + movq mm5, mm1 + + punpckhdq mm7, mm4 ;wsptr[2,6],[2,7],[2,2],[2,3] + movq mm2, mm6 + + movq mm4, [esi+8*7] ;wsptr[3,4],[3,5],[3,6],[3,7] + paddw mm6, mm7 ;wsptr[xxx],[2,z11],[xxx],[2,z13] + + psubw mm2, mm7 ;wsptr[xxx],[2,z12],[xxx],[2,z10] + punpckldq mm1, mm4 ;wsptr[3,0],[3,1],[3,4],[3,5] + + punpckhdq mm4, mm5 ;wsptr[3,6],[3,7],[3,2],[3,3] + movq mm7, mm1 + + paddw mm1, mm4 ;wsptr[xxx],[3,z11],[xxx],[3,z13] + psubw mm7, mm4 ;wsptr[xxx],[3,z12],[xxx],[3,z10] + + movq mm5, mm6 + punpcklwd mm6, mm1 ;wsptr[xxx],[xxx],[2,z11],[3,z11] + + punpckhwd mm5, mm1 ;wsptr[xxx],[xxx],[2,z13],[3,z13] + movq mm4, mm2 + + punpcklwd mm2, mm7 ;wsptr[xxx],[xxx],[2,z12],[3,z12] + + punpckhwd mm4, mm7 ;wsptr[xxx],[xxx],[2,z10],[3,z10] + + punpckhdq mm4, mm6 ;wsptr[2,z10],[3,z10],[2,z11],[3,z11] + + punpckhdq mm2, mm5 ;wsptr[2,z12],[3,z12],[2,z13],[3,z13] + movq mm5, mm0 + + punpckldq mm0, mm4 ;wsptr[0,z10],[1,z10],[2,z10],[3,z10] + + punpckhdq mm5, mm4 ;wsptr[0,z11],[1,z11],[2,z11],[3,z11] + movq mm4, mm3 + + punpckhdq mm4, mm2 ;wsptr[0,z13],[1,z13],[2,z13],[3,z13] + movq mm1, mm5 + + punpckldq mm3, mm2 ;wsptr[0,z12],[1,z12],[2,z12],[3,z12] +// tmp7 = z11 + z13; /* phase 5 */ +// tmp8 = z11 - z13; /* phase 5 */ + psubw mm1, mm4 ;tmp8 + + paddw mm5, mm4 ;tmp7 +// tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */ + psllw mm1, 2 + + psllw mm0, 2 + + pmulhw mm1, fix_141 ;tmp21 +// tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065)) /* 2*(c2-c6) */ +// + MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */ + psllw mm3, 2 + movq mm7, mm0 + + pmulhw mm7, fix_n184 + movq mm6, mm3 + + movq mm2, [esi+8*0] ;tmp0,final1 + + pmulhw mm6, fix_108n184 +// tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */ +// + MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */ + movq mm4, mm2 ;final1 + + pmulhw mm0, fix_184n261 + paddw mm2, mm5 ;tmp0+tmp7,final1 + + pmulhw mm3, fix_184 + psubw mm4, mm5 ;tmp0-tmp7,final1 + +// tmp6 = tmp22 - tmp7; /* phase 2 */ + psraw mm2, 5 ;outptr[0,0],[1,0],[2,0],[3,0],final1 + + paddsw mm2, const_0x0080 ;final1 + paddw mm7, mm6 ;tmp20 + psraw mm4, 5 ;outptr[0,7],[1,7],[2,7],[3,7],final1 + + paddsw mm4, const_0x0080 ;final1 + paddw mm3, mm0 ;tmp22 + +// tmp5 = tmp21 - tmp6; + psubw mm3, mm5 ;tmp6 + +// tmp4 = tmp20 + tmp5; + movq mm0, [esi+8*1] ;tmp1,final2 + psubw mm1, mm3 ;tmp5 + + movq mm6, mm0 ;final2 + paddw mm0, mm3 ;tmp1+tmp6,final2 + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + +// outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) +// & RANGE_MASK]; final1 + + +// outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) +// & RANGE_MASK]; final2 + psubw mm6, mm3 ;tmp1-tmp6,final2 + psraw mm0, 5 ;outptr[0,1],[1,1],[2,1],[3,1] + + paddsw mm0, const_0x0080 + psraw mm6, 5 ;outptr[0,6],[1,6],[2,6],[3,6] + + paddsw mm6, const_0x0080 ;need to check this value + packuswb mm0, mm4 ;out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7] + + movq mm5, [esi+8*2] ;tmp2,final3 + packuswb mm2, mm6 ;out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6] + +// outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) +// & RANGE_MASK]; final3 + paddw mm7, mm1 ;tmp4 + movq mm3, mm5 + + paddw mm5, mm1 ;tmp2+tmp5 + psubw mm3, mm1 ;tmp2-tmp5 + + psraw mm5, 5 ;outptr[0,2],[1,2],[2,2],[3,2] + + paddsw mm5, const_0x0080 + movq mm4, [esi+8*3] ;tmp3,final4 + psraw mm3, 5 ;outptr[0,5],[1,5],[2,5],[3,5] + + paddsw mm3, const_0x0080 + + +// outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) +// & RANGE_MASK]; final4 + movq mm6, mm4 + paddw mm4, mm7 ;tmp3+tmp4 + + psubw mm6, mm7 ;tmp3-tmp4 + psraw mm4, 5 ;outptr[0,4],[1,4],[2,4],[3,4] + mov ecx, [eax] + + paddsw mm4, const_0x0080 + psraw mm6, 5 ;outptr[0,3],[1,3],[2,3],[3,3] + + paddsw mm6, const_0x0080 + packuswb mm5, mm4 ;out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4] + + packuswb mm6, mm3 ;out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5] + movq mm4, mm2 + + movq mm7, mm5 + punpcklbw mm2, mm0 ;out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1] + + punpckhbw mm4, mm0 ;out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7] + movq mm1, mm2 + + punpcklbw mm5, mm6 ;out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3] + add eax, 4 + + punpckhbw mm7, mm6 ;out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5] + + punpcklwd mm2, mm5 ;out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3] + add ecx, output_col + + movq mm6, mm7 + punpckhwd mm1, mm5 ;out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3] + + movq mm0, mm2 + punpcklwd mm6, mm4 ;out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7] + + mov ebx, [eax] + punpckldq mm2, mm6 ;out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7] + + add eax, 4 + movq mm3, mm1 + + add ebx, output_col + punpckhwd mm7, mm4 ;out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7] + + movq [ecx], mm2 + punpckhdq mm0, mm6 ;out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7] + + mov ecx, [eax] + add eax, 4 + add ecx, output_col + + movq [ebx], mm0 + punpckldq mm1, mm7 ;out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7] + + mov ebx, [eax] + + add ebx, output_col + punpckhdq mm3, mm7 ;out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7] + movq [ecx], mm1 + + + movq [ebx], mm3 + + + +/*******************************************************************/ + + + add esi, 64 + add eax, 4 + +/*******************************************************************/ + +// tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); +// tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); +// tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); +// tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]); + movq mm0, [esi+8*0] ;wsptr[0,0],[0,1],[0,2],[0,3] + + movq mm1, [esi+8*1] ;wsptr[0,4],[0,5],[0,6],[0,7] + movq mm2, mm0 + + movq mm3, [esi+8*2] ;wsptr[1,0],[1,1],[1,2],[1,3] + paddw mm0, mm1 ;wsptr[0,tmp10],[xxx],[0,tmp13],[xxx] + + movq mm4, [esi+8*3] ;wsptr[1,4],[1,5],[1,6],[1,7] + psubw mm2, mm1 ;wsptr[0,tmp11],[xxx],[0,tmp14],[xxx] + + movq mm6, mm0 + movq mm5, mm3 + + paddw mm3, mm4 ;wsptr[1,tmp10],[xxx],[1,tmp13],[xxx] + movq mm1, mm2 + + psubw mm5, mm4 ;wsptr[1,tmp11],[xxx],[1,tmp14],[xxx] + punpcklwd mm0, mm3 ;wsptr[0,tmp10],[1,tmp10],[xxx],[xxx] + + movq mm7, [esi+8*7] ;wsptr[3,4],[3,5],[3,6],[3,7] + punpckhwd mm6, mm3 ;wsptr[0,tmp13],[1,tmp13],[xxx],[xxx] + + movq mm3, [esi+8*4] ;wsptr[2,0],[2,1],[2,2],[2,3] + punpckldq mm0, mm6 ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13] + + punpcklwd mm1, mm5 ;wsptr[0,tmp11],[1,tmp11],[xxx],[xxx] + movq mm4, mm3 + + movq mm6, [esi+8*6] ;wsptr[3,0],[3,1],[3,2],[3,3] + punpckhwd mm2, mm5 ;wsptr[0,tmp14],[1,tmp14],[xxx],[xxx] + + movq mm5, [esi+8*5] ;wsptr[2,4],[2,5],[2,6],[2,7] + punpckldq mm1, mm2 ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14] + + + paddw mm3, mm5 ;wsptr[2,tmp10],[xxx],[2,tmp13],[xxx] + movq mm2, mm6 + + psubw mm4, mm5 ;wsptr[2,tmp11],[xxx],[2,tmp14],[xxx] + paddw mm6, mm7 ;wsptr[3,tmp10],[xxx],[3,tmp13],[xxx] + + movq mm5, mm3 + punpcklwd mm3, mm6 ;wsptr[2,tmp10],[3,tmp10],[xxx],[xxx] + + psubw mm2, mm7 ;wsptr[3,tmp11],[xxx],[3,tmp14],[xxx] + punpckhwd mm5, mm6 ;wsptr[2,tmp13],[3,tmp13],[xxx],[xxx] + + movq mm7, mm4 + punpckldq mm3, mm5 ;wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13] + + punpcklwd mm4, mm2 ;wsptr[2,tmp11],[3,tmp11],[xxx],[xxx] + + punpckhwd mm7, mm2 ;wsptr[2,tmp14],[3,tmp14],[xxx],[xxx] + + punpckldq mm4, mm7 ;wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14] + movq mm6, mm1 + +// mm0 = ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13] +// mm1 = ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14] + + + movq mm2, mm0 + punpckhdq mm6, mm4 ;wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14] + + punpckldq mm1, mm4 ;wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11] + psllw mm6, 2 + + pmulhw mm6, fix_141 + punpckldq mm0, mm3 ;wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10] + + punpckhdq mm2, mm3 ;wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13] + movq mm7, mm0 + +// tmp0 = tmp10 + tmp13; +// tmp3 = tmp10 - tmp13; + paddw mm0, mm2 ;[0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0] + psubw mm7, mm2 ;[0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3] + +// tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13; + psubw mm6, mm2 ;wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12] +// tmp1 = tmp11 + tmp12; +// tmp2 = tmp11 - tmp12; + movq mm5, mm1 + + + + /* Odd part */ + +// z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; +// z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; +// z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; +// z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; + movq mm3, [esi+8*0] ;wsptr[0,0],[0,1],[0,2],[0,3] + paddw mm1, mm6 ;[0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1] + + movq mm4, [esi+8*1] ;wsptr[0,4],[0,5],[0,6],[0,7] + psubw mm5, mm6 ;[0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2] + + movq mm6, mm3 + punpckldq mm3, mm4 ;wsptr[0,0],[0,1],[0,4],[0,5] + + punpckhdq mm4, mm6 ;wsptr[0,6],[0,7],[0,2],[0,3] + movq mm2, mm3 + +//Save tmp0 and tmp1 in wsptr + movq [esi+8*0], mm0 ;save tmp0 + paddw mm2, mm4 ;wsptr[xxx],[0,z11],[xxx],[0,z13] + + +//Continue with z10 --- z13 + movq mm6, [esi+8*2] ;wsptr[1,0],[1,1],[1,2],[1,3] + psubw mm3, mm4 ;wsptr[xxx],[0,z12],[xxx],[0,z10] + + movq mm0, [esi+8*3] ;wsptr[1,4],[1,5],[1,6],[1,7] + movq mm4, mm6 + + movq [esi+8*1], mm1 ;save tmp1 + punpckldq mm6, mm0 ;wsptr[1,0],[1,1],[1,4],[1,5] + + punpckhdq mm0, mm4 ;wsptr[1,6],[1,7],[1,2],[1,3] + movq mm1, mm6 + +//Save tmp2 and tmp3 in wsptr + paddw mm6, mm0 ;wsptr[xxx],[1,z11],[xxx],[1,z13] + movq mm4, mm2 + +//Continue with z10 --- z13 + movq [esi+8*2], mm5 ;save tmp2 + punpcklwd mm2, mm6 ;wsptr[xxx],[xxx],[0,z11],[1,z11] + + psubw mm1, mm0 ;wsptr[xxx],[1,z12],[xxx],[1,z10] + punpckhwd mm4, mm6 ;wsptr[xxx],[xxx],[0,z13],[1,z13] + + movq mm0, mm3 + punpcklwd mm3, mm1 ;wsptr[xxx],[xxx],[0,z12],[1,z12] + + movq [esi+8*3], mm7 ;save tmp3 + punpckhwd mm0, mm1 ;wsptr[xxx],[xxx],[0,z10],[1,z10] + + movq mm6, [esi+8*4] ;wsptr[2,0],[2,1],[2,2],[2,3] + punpckhdq mm0, mm2 ;wsptr[0,z10],[1,z10],[0,z11],[1,z11] + + movq mm7, [esi+8*5] ;wsptr[2,4],[2,5],[2,6],[2,7] + punpckhdq mm3, mm4 ;wsptr[0,z12],[1,z12],[0,z13],[1,z13] + + movq mm1, [esi+8*6] ;wsptr[3,0],[3,1],[3,2],[3,3] + movq mm4, mm6 + + punpckldq mm6, mm7 ;wsptr[2,0],[2,1],[2,4],[2,5] + movq mm5, mm1 + + punpckhdq mm7, mm4 ;wsptr[2,6],[2,7],[2,2],[2,3] + movq mm2, mm6 + + movq mm4, [esi+8*7] ;wsptr[3,4],[3,5],[3,6],[3,7] + paddw mm6, mm7 ;wsptr[xxx],[2,z11],[xxx],[2,z13] + + psubw mm2, mm7 ;wsptr[xxx],[2,z12],[xxx],[2,z10] + punpckldq mm1, mm4 ;wsptr[3,0],[3,1],[3,4],[3,5] + + punpckhdq mm4, mm5 ;wsptr[3,6],[3,7],[3,2],[3,3] + movq mm7, mm1 + + paddw mm1, mm4 ;wsptr[xxx],[3,z11],[xxx],[3,z13] + psubw mm7, mm4 ;wsptr[xxx],[3,z12],[xxx],[3,z10] + + movq mm5, mm6 + punpcklwd mm6, mm1 ;wsptr[xxx],[xxx],[2,z11],[3,z11] + + punpckhwd mm5, mm1 ;wsptr[xxx],[xxx],[2,z13],[3,z13] + movq mm4, mm2 + + punpcklwd mm2, mm7 ;wsptr[xxx],[xxx],[2,z12],[3,z12] + + punpckhwd mm4, mm7 ;wsptr[xxx],[xxx],[2,z10],[3,z10] + + punpckhdq mm4, mm6 ;wsptr[2,z10],[3,z10],[2,z11],[3,z11] + + punpckhdq mm2, mm5 ;wsptr[2,z12],[3,z12],[2,z13],[3,z13] + movq mm5, mm0 + + punpckldq mm0, mm4 ;wsptr[0,z10],[1,z10],[2,z10],[3,z10] + + punpckhdq mm5, mm4 ;wsptr[0,z11],[1,z11],[2,z11],[3,z11] + movq mm4, mm3 + + punpckhdq mm4, mm2 ;wsptr[0,z13],[1,z13],[2,z13],[3,z13] + movq mm1, mm5 + + punpckldq mm3, mm2 ;wsptr[0,z12],[1,z12],[2,z12],[3,z12] +// tmp7 = z11 + z13; /* phase 5 */ +// tmp8 = z11 - z13; /* phase 5 */ + psubw mm1, mm4 ;tmp8 + + paddw mm5, mm4 ;tmp7 +// tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */ + psllw mm1, 2 + + psllw mm0, 2 + + pmulhw mm1, fix_141 ;tmp21 +// tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065)) /* 2*(c2-c6) */ +// + MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */ + psllw mm3, 2 + movq mm7, mm0 + + pmulhw mm7, fix_n184 + movq mm6, mm3 + + movq mm2, [esi+8*0] ;tmp0,final1 + + pmulhw mm6, fix_108n184 +// tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */ +// + MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */ + movq mm4, mm2 ;final1 + + pmulhw mm0, fix_184n261 + paddw mm2, mm5 ;tmp0+tmp7,final1 + + pmulhw mm3, fix_184 + psubw mm4, mm5 ;tmp0-tmp7,final1 + +// tmp6 = tmp22 - tmp7; /* phase 2 */ + psraw mm2, 5 ;outptr[0,0],[1,0],[2,0],[3,0],final1 + + paddsw mm2, const_0x0080 ;final1 + paddw mm7, mm6 ;tmp20 + psraw mm4, 5 ;outptr[0,7],[1,7],[2,7],[3,7],final1 + + paddsw mm4, const_0x0080 ;final1 + paddw mm3, mm0 ;tmp22 + +// tmp5 = tmp21 - tmp6; + psubw mm3, mm5 ;tmp6 + +// tmp4 = tmp20 + tmp5; + movq mm0, [esi+8*1] ;tmp1,final2 + psubw mm1, mm3 ;tmp5 + + movq mm6, mm0 ;final2 + paddw mm0, mm3 ;tmp1+tmp6,final2 + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + +// outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) +// & RANGE_MASK]; final1 + + +// outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) +// & RANGE_MASK]; final2 + psubw mm6, mm3 ;tmp1-tmp6,final2 + psraw mm0, 5 ;outptr[0,1],[1,1],[2,1],[3,1] + + paddsw mm0, const_0x0080 + psraw mm6, 5 ;outptr[0,6],[1,6],[2,6],[3,6] + + paddsw mm6, const_0x0080 ;need to check this value + packuswb mm0, mm4 ;out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7] + + movq mm5, [esi+8*2] ;tmp2,final3 + packuswb mm2, mm6 ;out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6] + +// outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) +// & RANGE_MASK]; final3 + paddw mm7, mm1 ;tmp4 + movq mm3, mm5 + + paddw mm5, mm1 ;tmp2+tmp5 + psubw mm3, mm1 ;tmp2-tmp5 + + psraw mm5, 5 ;outptr[0,2],[1,2],[2,2],[3,2] + + paddsw mm5, const_0x0080 + movq mm4, [esi+8*3] ;tmp3,final4 + psraw mm3, 5 ;outptr[0,5],[1,5],[2,5],[3,5] + + paddsw mm3, const_0x0080 + + +// outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) +// & RANGE_MASK]; +// outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) +// & RANGE_MASK]; final4 + movq mm6, mm4 + paddw mm4, mm7 ;tmp3+tmp4 + + psubw mm6, mm7 ;tmp3-tmp4 + psraw mm4, 5 ;outptr[0,4],[1,4],[2,4],[3,4] + mov ecx, [eax] + + paddsw mm4, const_0x0080 + psraw mm6, 5 ;outptr[0,3],[1,3],[2,3],[3,3] + + paddsw mm6, const_0x0080 + packuswb mm5, mm4 ;out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4] + + packuswb mm6, mm3 ;out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5] + movq mm4, mm2 + + movq mm7, mm5 + punpcklbw mm2, mm0 ;out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1] + + punpckhbw mm4, mm0 ;out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7] + movq mm1, mm2 + + punpcklbw mm5, mm6 ;out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3] + add eax, 4 + + punpckhbw mm7, mm6 ;out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5] + + punpcklwd mm2, mm5 ;out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3] + add ecx, output_col + + movq mm6, mm7 + punpckhwd mm1, mm5 ;out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3] + + movq mm0, mm2 + punpcklwd mm6, mm4 ;out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7] + + mov ebx, [eax] + punpckldq mm2, mm6 ;out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7] + + add eax, 4 + movq mm3, mm1 + + add ebx, output_col + punpckhwd mm7, mm4 ;out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7] + + movq [ecx], mm2 + punpckhdq mm0, mm6 ;out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7] + + mov ecx, [eax] + add eax, 4 + add ecx, output_col + + movq [ebx], mm0 + punpckldq mm1, mm7 ;out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7] + + mov ebx, [eax] + + add ebx, output_col + punpckhdq mm3, mm7 ;out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7] + movq [ecx], mm1 + + movq [ebx], mm3 + + emms + } +} +#endif + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jidctint.c b/rosapps/lib/libjpeg/jidctint.c new file mode 100644 index 00000000000..df1041ed024 --- /dev/null +++ b/rosapps/lib/libjpeg/jidctint.c @@ -0,0 +1,963 @@ +/* + * jidctint.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + * larger than the true IDCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D IDCT, + * because the y0 and y4 inputs need not be divided by sqrt(N). + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (To scale up 12-bit sample data further, an + * intermediate INT32 array would be needed.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp1, tmp2, tmp3; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + + tmp0 = (z2 + z3) << CONST_BITS; + tmp1 = (z2 - z3) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = (INT32) wsptr[2]; + z3 = (INT32) wsptr[6]; + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS; + tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = (INT32) wsptr[7]; + tmp1 = (INT32) wsptr[5]; + tmp2 = (INT32) wsptr[3]; + tmp3 = (INT32) wsptr[1]; + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +#ifdef HAVE_SSE2_INTEL_MNEMONICS + +/* +* Intel SSE2 optimized Inverse Discrete Cosine Transform +* +* +* Copyright (c) 2001-2002 Intel Corporation +* All Rights Reserved +* +* +* Authors: +* Danilov G. +* +* +*----------------------------------------------------------------------------- +* +* References: +* K.R. Rao and P. Yip +* Discrete Cosine Transform. +* Algorithms, Advantages, Applications. +* Academic Press, Inc, London, 1990. +* JPEG Group's software. +* This implementation is based on Appendix A.2 of the book (R&Y) ... +* +*----------------------------------------------------------------------------- +*/ + +typedef unsigned char Ipp8u; +typedef unsigned short Ipp16u; +typedef unsigned int Ipp32u; + +typedef signed char Ipp8s; +typedef signed short Ipp16s; +typedef signed int Ipp32s; + +#define BITS_INV_ACC 4 +#define SHIFT_INV_ROW 16 - BITS_INV_ACC +#define SHIFT_INV_COL 1 + BITS_INV_ACC + +#define RND_INV_ROW 1024 * (6 - BITS_INV_ACC) /* 1 << (SHIFT_INV_ROW-1) */ +#define RND_INV_COL = 16 * (BITS_INV_ACC - 3) /* 1 << (SHIFT_INV_COL-1) */ +#define RND_INV_CORR = RND_INV_COL - 1 /* correction -1.0 and round */ + +#define c_inv_corr_0 -1024 * (6 - BITS_INV_ACC) + 65536 /* -0.5 + (16.0 or 32.0) */ +#define c_inv_corr_1 1877 * (6 - BITS_INV_ACC) /* 0.9167 */ +#define c_inv_corr_2 1236 * (6 - BITS_INV_ACC) /* 0.6035 */ +#define c_inv_corr_3 680 * (6 - BITS_INV_ACC) /* 0.3322 */ +#define c_inv_corr_4 0 * (6 - BITS_INV_ACC) /* 0.0 */ +#define c_inv_corr_5 -569 * (6 - BITS_INV_ACC) /* -0.278 */ +#define c_inv_corr_6 -512 * (6 - BITS_INV_ACC) /* -0.25 */ +#define c_inv_corr_7 -651 * (6 - BITS_INV_ACC) /* -0.3176 */ + +#define RND_INV_ROW_0 RND_INV_ROW + c_inv_corr_0 +#define RND_INV_ROW_1 RND_INV_ROW + c_inv_corr_1 +#define RND_INV_ROW_2 RND_INV_ROW + c_inv_corr_2 +#define RND_INV_ROW_3 RND_INV_ROW + c_inv_corr_3 +#define RND_INV_ROW_4 RND_INV_ROW + c_inv_corr_4 +#define RND_INV_ROW_5 RND_INV_ROW + c_inv_corr_5 +#define RND_INV_ROW_6 RND_INV_ROW + c_inv_corr_6 +#define RND_INV_ROW_7 RND_INV_ROW + c_inv_corr_7 + +/* Table for rows 0,4 - constants are multiplied on cos_4_16 */ + +__declspec(align(16)) short tab_i_04[] = { + 16384, 21407, 16384, 8867, + -16384, 21407, 16384, -8867, + 16384, -8867, 16384, -21407, + 16384, 8867, -16384, -21407, + 22725, 19266, 19266, -4520, + 4520, 19266, 19266, -22725, + 12873, -22725, 4520, -12873, + 12873, 4520, -22725, -12873}; + +/* Table for rows 1,7 - constants are multiplied on cos_1_16 */ + +__declspec(align(16)) short tab_i_17[] = { + 22725, 29692, 22725, 12299, + -22725, 29692, 22725, -12299, + 22725, -12299, 22725, -29692, + 22725, 12299, -22725, -29692, + 31521, 26722, 26722, -6270, + 6270, 26722, 26722, -31521, + 17855, -31521, 6270, -17855, + 17855, 6270, -31521, -17855}; + +/* Table for rows 2,6 - constants are multiplied on cos_2_16 */ + +__declspec(align(16)) short tab_i_26[] = { + 21407, 27969, 21407, 11585, + -21407, 27969, 21407, -11585, + 21407, -11585, 21407, -27969, + 21407, 11585, -21407, -27969, + 29692, 25172, 25172, -5906, + 5906, 25172, 25172, -29692, + 16819, -29692, 5906, -16819, + 16819, 5906, -29692, -16819}; + +/* Table for rows 3,5 - constants are multiplied on cos_3_16 */ + +__declspec(align(16)) short tab_i_35[] = { + 19266, 25172, 19266, 10426, + -19266, 25172, 19266, -10426, + 19266, -10426, 19266, -25172, + 19266, 10426, -19266, -25172, + 26722, 22654, 22654, -5315, + 5315, 22654, 22654, -26722, + 15137, -26722, 5315, -15137, + 15137, 5315, -26722, -15137}; + +__declspec(align(16)) long round_i_0[] = {RND_INV_ROW_0,RND_INV_ROW_0, + RND_INV_ROW_0,RND_INV_ROW_0}; +__declspec(align(16)) long round_i_1[] = {RND_INV_ROW_1,RND_INV_ROW_1, + RND_INV_ROW_1,RND_INV_ROW_1}; +__declspec(align(16)) long round_i_2[] = {RND_INV_ROW_2,RND_INV_ROW_2, + RND_INV_ROW_2,RND_INV_ROW_2}; +__declspec(align(16)) long round_i_3[] = {RND_INV_ROW_3,RND_INV_ROW_3, + RND_INV_ROW_3,RND_INV_ROW_3}; +__declspec(align(16)) long round_i_4[] = {RND_INV_ROW_4,RND_INV_ROW_4, + RND_INV_ROW_4,RND_INV_ROW_4}; +__declspec(align(16)) long round_i_5[] = {RND_INV_ROW_5,RND_INV_ROW_5, + RND_INV_ROW_5,RND_INV_ROW_5}; +__declspec(align(16)) long round_i_6[] = {RND_INV_ROW_6,RND_INV_ROW_6, + RND_INV_ROW_6,RND_INV_ROW_6}; +__declspec(align(16)) long round_i_7[] = {RND_INV_ROW_7,RND_INV_ROW_7, + RND_INV_ROW_7,RND_INV_ROW_7}; + +__declspec(align(16)) short tg_1_16[] = { + 13036, 13036, 13036, 13036, /* tg * (2<<16) + 0.5 */ + 13036, 13036, 13036, 13036}; +__declspec(align(16)) short tg_2_16[] = { + 27146, 27146, 27146, 27146, /* tg * (2<<16) + 0.5 */ + 27146, 27146, 27146, 27146}; +__declspec(align(16)) short tg_3_16[] = { + -21746, -21746, -21746, -21746, /* tg * (2<<16) + 0.5 */ + -21746, -21746, -21746, -21746}; +__declspec(align(16)) short cos_4_16[] = { + -19195, -19195, -19195, -19195, /* cos * (2<<16) + 0.5 */ + -19195, -19195, -19195, -19195}; + +/* +* In this implementation the outputs of the iDCT-1D are multiplied +* for rows 0,4 - on cos_4_16, +* for rows 1,7 - on cos_1_16, +* for rows 2,6 - on cos_2_16, +* for rows 3,5 - on cos_3_16 +* and are shifted to the left for rise of accuracy +* +* For used constants +* FIX(float_const) = (short) (float_const * (1<<15) + 0.5) +* +*----------------------------------------------------------------------------- +* +* On the first stage the calculation is executed at once for two rows. +* The permutation for each output row is done on second stage +* t7 t6 t5 t4 t3 t2 t1 t0 -> t4 t5 t6 t7 t3 t2 t1 t0 +* +*----------------------------------------------------------------------------- +*/ + +#define DCT_8_INV_ROW_2R(TABLE, ROUND1, ROUND2) __asm { \ + __asm pshuflw xmm1, xmm0, 10001000b \ + __asm pshuflw xmm0, xmm0, 11011101b \ + __asm pshufhw xmm1, xmm1, 10001000b \ + __asm pshufhw xmm0, xmm0, 11011101b \ + __asm movdqa xmm2, XMMWORD PTR [TABLE] \ + __asm pmaddwd xmm2, xmm1 \ + __asm movdqa xmm3, XMMWORD PTR [TABLE + 32] \ + __asm pmaddwd xmm3, xmm0 \ + __asm pmaddwd xmm1, XMMWORD PTR [TABLE + 16] \ + __asm pmaddwd xmm0, XMMWORD PTR [TABLE + 48] \ + __asm pshuflw xmm5, xmm4, 10001000b \ + __asm pshuflw xmm4, xmm4, 11011101b \ + __asm pshufhw xmm5, xmm5, 10001000b \ + __asm pshufhw xmm4, xmm4, 11011101b \ + __asm movdqa xmm6, XMMWORD PTR [TABLE] \ + __asm pmaddwd xmm6, xmm5 \ + __asm movdqa xmm7, XMMWORD PTR [TABLE + 32] \ + __asm pmaddwd xmm7, xmm4 \ + __asm pmaddwd xmm5, XMMWORD PTR [TABLE + 16] \ + __asm pmaddwd xmm4, XMMWORD PTR [TABLE + 48] \ + __asm pshufd xmm1, xmm1, 01001110b \ + __asm pshufd xmm0, xmm0, 01001110b \ + __asm paddd xmm2, XMMWORD PTR [ROUND1] \ + __asm paddd xmm3, xmm0 \ + __asm paddd xmm1, xmm2 \ + __asm pshufd xmm5, xmm5, 01001110b \ + __asm pshufd xmm4, xmm4, 01001110b \ + __asm movdqa xmm2, xmm1 \ + __asm psubd xmm2, xmm3 \ + __asm psrad xmm2, SHIFT_INV_ROW \ + __asm paddd xmm1, xmm3 \ + __asm psrad xmm1, SHIFT_INV_ROW \ + __asm packssdw xmm1, xmm2 \ + __asm paddd xmm6, XMMWORD PTR [ROUND2] \ + __asm paddd xmm7, xmm4 \ + __asm paddd xmm5, xmm6 \ + __asm movdqa xmm6, xmm5 \ + __asm psubd xmm6, xmm7 \ + __asm psrad xmm6, SHIFT_INV_ROW \ + __asm paddd xmm5, xmm7 \ + __asm psrad xmm5, SHIFT_INV_ROW \ + __asm packssdw xmm5, xmm6 \ + } + +/* +* +* The second stage - inverse DCTs of columns +* +* The inputs are multiplied +* for rows 0,4 - on cos_4_16, +* for rows 1,7 - on cos_1_16, +* for rows 2,6 - on cos_2_16, +* for rows 3,5 - on cos_3_16 +* and are shifted to the left for rise of accuracy +*/ + +#define DCT_8_INV_COL_8R(INP, OUTP) __asm { \ + __asm movdqa xmm0, [INP + 5*16] \ + __asm movdqa xmm1, XMMWORD PTR tg_3_16 \ + __asm movdqa xmm2, xmm0 \ + __asm movdqa xmm3, [INP + 3*16] \ + __asm pmulhw xmm0, xmm1 \ + __asm movdqa xmm4, [INP + 7*16] \ + __asm pmulhw xmm1, xmm3 \ + __asm movdqa xmm5, XMMWORD PTR tg_1_16 \ + __asm movdqa xmm6, xmm4 \ + __asm pmulhw xmm4, xmm5 \ + __asm paddsw xmm0, xmm2 \ + __asm pmulhw xmm5, [INP + 1*16] \ + __asm paddsw xmm1, xmm3 \ + __asm movdqa xmm7, [INP + 6*16] \ + __asm paddsw xmm0, xmm3 \ + __asm movdqa xmm3, XMMWORD PTR tg_2_16 \ + __asm psubsw xmm2, xmm1 \ + __asm pmulhw xmm7, xmm3 \ + __asm movdqa xmm1, xmm0 \ + __asm pmulhw xmm3, [INP + 2*16] \ + __asm psubsw xmm5, xmm6 \ + __asm paddsw xmm4, [INP + 1*16] \ + __asm paddsw xmm0, xmm4 \ + __asm psubsw xmm4, xmm1 \ + __asm pshufhw xmm0, xmm0, 00011011b \ + __asm paddsw xmm7, [INP + 2*16] \ + __asm movdqa xmm6, xmm5 \ + __asm psubsw xmm3, [INP + 6*16] \ + __asm psubsw xmm5, xmm2 \ + __asm paddsw xmm6, xmm2 \ + __asm movdqa [OUTP + 7*16], xmm0 \ + __asm movdqa xmm1, xmm4 \ + __asm movdqa xmm2, XMMWORD PTR cos_4_16 \ + __asm paddsw xmm4, xmm5 \ + __asm movdqa xmm0, XMMWORD PTR cos_4_16 \ + __asm pmulhw xmm2, xmm4 \ + __asm pshufhw xmm6, xmm6, 00011011b \ + __asm movdqa [OUTP + 3*16], xmm6 \ + __asm psubsw xmm1, xmm5 \ + __asm movdqa xmm6, [INP + 0*16] \ + __asm pmulhw xmm0, xmm1 \ + __asm movdqa xmm5, [INP + 4*16] \ + __asm paddsw xmm4, xmm2 \ + __asm paddsw xmm5, xmm6 \ + __asm psubsw xmm6, [INP + 4*16] \ + __asm paddsw xmm0, xmm1 \ + __asm pshufhw xmm4, xmm4, 00011011b \ + __asm movdqa xmm2, xmm5 \ + __asm paddsw xmm5, xmm7 \ + __asm movdqa xmm1, xmm6 \ + __asm psubsw xmm2, xmm7 \ + __asm movdqa xmm7, [OUTP + 7*16] \ + __asm paddsw xmm6, xmm3 \ + __asm pshufhw xmm5, xmm5, 00011011b \ + __asm paddsw xmm7, xmm5 \ + __asm psubsw xmm1, xmm3 \ + __asm pshufhw xmm6, xmm6, 00011011b \ + __asm movdqa xmm3, xmm6 \ + __asm paddsw xmm6, xmm4 \ + __asm pshufhw xmm2, xmm2, 00011011b \ + __asm psraw xmm7, SHIFT_INV_COL \ + __asm movdqa [OUTP + 0*16], xmm7 \ + __asm movdqa xmm7, xmm1 \ + __asm paddsw xmm1, xmm0 \ + __asm psraw xmm6, SHIFT_INV_COL \ + __asm movdqa [OUTP + 1*16], xmm6 \ + __asm pshufhw xmm1, xmm1, 00011011b \ + __asm movdqa xmm6, [OUTP + 3*16] \ + __asm psubsw xmm7, xmm0 \ + __asm psraw xmm1, SHIFT_INV_COL \ + __asm movdqa [OUTP + 2*16], xmm1 \ + __asm psubsw xmm5, [OUTP + 7*16] \ + __asm paddsw xmm6, xmm2 \ + __asm psubsw xmm2, [OUTP + 3*16] \ + __asm psubsw xmm3, xmm4 \ + __asm psraw xmm7, SHIFT_INV_COL \ + __asm pshufhw xmm7, xmm7, 00011011b \ + __asm movdqa [OUTP + 5*16], xmm7 \ + __asm psraw xmm5, SHIFT_INV_COL \ + __asm movdqa [OUTP + 7*16], xmm5 \ + __asm psraw xmm6, SHIFT_INV_COL \ + __asm movdqa [OUTP + 3*16], xmm6 \ + __asm psraw xmm2, SHIFT_INV_COL \ + __asm movdqa [OUTP + 4*16], xmm2 \ + __asm psraw xmm3, SHIFT_INV_COL \ + __asm movdqa [OUTP + 6*16], xmm3 \ + } + +/* +* +* Name: dct_8x8_inv_16s +* Purpose: Inverse Discrete Cosine Transform 8x8 with +* 2D buffer of short int data +* Context: +* void dct_8x8_inv_16s ( short *src, short *dst ) +* Parameters: +* src - Pointer to the source buffer +* dst - Pointer to the destination buffer +* +*/ + +GLOBAL(void) +dct_8x8_inv_16s ( short *src, short *dst ) { + + __asm { + + mov ecx, src + mov edx, dst + + movdqa xmm0, [ecx+0*16] + movdqa xmm4, [ecx+4*16] + DCT_8_INV_ROW_2R(tab_i_04, round_i_0, round_i_4) + movdqa [edx+0*16], xmm1 + movdqa [edx+4*16], xmm5 + + movdqa xmm0, [ecx+1*16] + movdqa xmm4, [ecx+7*16] + DCT_8_INV_ROW_2R(tab_i_17, round_i_1, round_i_7) + movdqa [edx+1*16], xmm1 + movdqa [edx+7*16], xmm5 + + movdqa xmm0, [ecx+3*16] + movdqa xmm4, [ecx+5*16] + DCT_8_INV_ROW_2R(tab_i_35, round_i_3, round_i_5); + movdqa [edx+3*16], xmm1 + movdqa [edx+5*16], xmm5 + + movdqa xmm0, [ecx+2*16] + movdqa xmm4, [ecx+6*16] + DCT_8_INV_ROW_2R(tab_i_26, round_i_2, round_i_6); + movdqa [edx+2*16], xmm1 + movdqa [edx+6*16], xmm5 + + DCT_8_INV_COL_8R(edx+0, edx+0); + } +} + + +/* +* Name: +* ownpj_QuantInv_8x8_16s +* +* Purpose: +* Dequantize 8x8 block of DCT coefficients +* +* Context: +* void ownpj_QuantInv_8x8_16s +* Ipp16s* pSrc, +* Ipp16s* pDst, +* const Ipp16u* pQTbl)* +* +*/ + +GLOBAL(void) +ownpj_QuantInv_8x8_16s(short * pSrc, short * pDst, const unsigned short * pQTbl) +{ + __asm { + + push ebx + push ecx + push edx + push esi + push edi + + mov esi, pSrc + mov edi, pDst + mov edx, pQTbl + mov ecx, 4 + mov ebx, 32 + + again: + + movq mm0, QWORD PTR [esi+0] + movq mm1, QWORD PTR [esi+8] + movq mm2, QWORD PTR [esi+16] + movq mm3, QWORD PTR [esi+24] + + prefetcht0 [esi+ebx] ; fetch next cache line + + pmullw mm0, QWORD PTR [edx+0] + pmullw mm1, QWORD PTR [edx+8] + pmullw mm2, QWORD PTR [edx+16] + pmullw mm3, QWORD PTR [edx+24] + + movq QWORD PTR [edi+0], mm0 + movq QWORD PTR [edi+8], mm1 + movq QWORD PTR [edi+16], mm2 + movq QWORD PTR [edi+24], mm3 + + add esi, ebx + add edi, ebx + add edx, ebx + dec ecx + jnz again + + emms + + pop edi + pop esi + pop edx + pop ecx + pop ebx + } +} + + +/* +* Name: +* ownpj_Add128_8x8_16s8u +* +* Purpose: +* signed to unsigned conversion (level shift) +* for 8x8 block of DCT coefficients +* +* Context: +* void ownpj_Add128_8x8_16s8u +* const Ipp16s* pSrc, +* Ipp8u* pDst, +* int DstStep); +* +*/ + +__declspec(align(16)) long const_128[]= {0x00800080, 0x00800080, 0x00800080, 0x00800080}; + +GLOBAL(void) +ownpj_Add128_8x8_16s8u(const short * pSrc, unsigned char * pDst, int DstStep) +{ + __asm { + push eax + push ebx + push ecx + push edx + push esi + push edi + + mov esi, pSrc + mov edi, pDst + mov edx, DstStep + mov ecx, 2 + mov ebx, edx + mov eax, edx + sal ebx, 1 + add eax, ebx + movdqa xmm7, XMMWORD PTR const_128 + + again: + + movdqa xmm0, XMMWORD PTR [esi+0] ; line 0 + movdqa xmm1, XMMWORD PTR [esi+16] ; line 1 + movdqa xmm2, XMMWORD PTR [esi+32] ; line 2 + movdqa xmm3, XMMWORD PTR [esi+48] ; line 3 + + paddw xmm0, xmm7 + paddw xmm1, xmm7 + paddw xmm2, xmm7 + paddw xmm3, xmm7 + + packuswb xmm0, xmm1 + packuswb xmm2, xmm3 + + movq QWORD PTR [edi], xmm0 ;0*DstStep + movq QWORD PTR [edi+ebx], xmm2 ;2*DstStep + + psrldq xmm0, 8 + psrldq xmm2, 8 + + movq QWORD PTR [edi+edx], xmm0 ;1*DstStep + movq QWORD PTR [edi+eax], xmm2 ;3*DstStep + + add edi, ebx + add esi, 64 + add edi, ebx + dec ecx + jnz again + + pop edi + pop esi + pop edx + pop ecx + pop ebx + pop eax + } +} + + +/* +* Name: +* ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R +* +* Purpose: +* Inverse DCT transform, de-quantization and level shift +* +* Parameters: +* pSrc - pointer to source +* pDst - pointer to output array +* DstStep - line offset for output data +* pEncoderQuantTable - pointer to Quantization table +* +*/ + +GLOBAL(void) +ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R( + short * pSrc, + unsigned char * pDst, + int DstStep, + const unsigned short * pQuantInvTable) +{ + + __declspec(align(16)) Ipp8u buf[DCTSIZE2*sizeof(Ipp16s)]; + Ipp16s * workbuf = (Ipp16s *)buf; + + ownpj_QuantInv_8x8_16s(pSrc,workbuf,pQuantInvTable); + dct_8x8_inv_16s(workbuf,workbuf); + ownpj_Add128_8x8_16s8u(workbuf,pDst,DstStep); + +} + +GLOBAL(void) +jpeg_idct_islow_sse2 ( + j_decompress_ptr cinfo, + jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, + JDIMENSION output_col) +{ + int ctr; + JCOEFPTR inptr; + Ipp16u* quantptr; + Ipp8u* wsptr; + __declspec(align(16)) Ipp8u workspace[DCTSIZE2]; + JSAMPROW outptr; + + inptr = coef_block; + quantptr = (Ipp16u*)compptr->dct_table; + wsptr = workspace; + + ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R(inptr, workspace, 8, quantptr); + + for(ctr = 0; ctr < DCTSIZE; ctr++) + { + outptr = output_buf[ctr] + output_col; + + outptr[0] = wsptr[0]; + outptr[1] = wsptr[1]; + outptr[2] = wsptr[2]; + outptr[3] = wsptr[3]; + outptr[4] = wsptr[4]; + outptr[5] = wsptr[5]; + outptr[6] = wsptr[6]; + outptr[7] = wsptr[7]; + + wsptr += DCTSIZE; + } +} +#endif /* HAVE_SSE2_INTEL_MNEMONICS */ + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jidctred.c b/rosapps/lib/libjpeg/jidctred.c new file mode 100644 index 00000000000..421f3c7ca1e --- /dev/null +++ b/rosapps/lib/libjpeg/jidctred.c @@ -0,0 +1,398 @@ +/* + * jidctred.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains inverse-DCT routines that produce reduced-size output: + * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. + * + * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) + * algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step + * with an 8-to-4 step that produces the four averages of two adjacent outputs + * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). + * These steps were derived by computing the corresponding values at the end + * of the normal LL&M code, then simplifying as much as possible. + * + * 1x1 is trivial: just take the DC coefficient divided by 8. + * + * See jidctint.c for additional comments. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef IDCT_SCALING_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling is the same as in jidctint.c. */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */ +#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */ +#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */ +#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */ +#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */ +#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */ +#else +#define FIX_0_211164243 FIX(0.211164243) +#define FIX_0_509795579 FIX(0.509795579) +#define FIX_0_601344887 FIX(0.601344887) +#define FIX_0_720959822 FIX(0.720959822) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_850430095 FIX(0.850430095) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_061594337 FIX(1.061594337) +#define FIX_1_272758580 FIX(1.272758580) +#define FIX_1_451774981 FIX(1.451774981) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_172734803 FIX(2.172734803) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_624509785 FIX(3.624509785) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 4x4 output block. + */ + +GLOBAL(void) +jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp2, tmp10, tmp12; + INT32 z1, z2, z3, z4; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*4]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process column 4, because second pass won't use it */ + if (ctr == DCTSIZE-4) + continue; + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 && + inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) { + /* AC terms all zero; we need not examine term 4 for 4x4 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp0 <<= (CONST_BITS+1); + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1); + } + + /* Pass 2: process 4 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 4; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1); + + tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065) + + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = (INT32) wsptr[7]; + z2 = (INT32) wsptr[5]; + z3 = (INT32) wsptr[3]; + z4 = (INT32) wsptr[1]; + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 2x2 output block. + */ + +GLOBAL(void) +jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp10, z1; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process columns 2,4,6 */ + if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) + continue; + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) { + /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + + continue; + } + + /* Even part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp10 = z1 << (CONST_BITS+2); + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2); + } + + /* Pass 2: process 2 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 2; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2); + + /* Odd part */ + + tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */ + + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */ + + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ + + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 1x1 output block. + */ + +GLOBAL(void) +jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + int dcval; + ISLOW_MULT_TYPE * quantptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + SHIFT_TEMPS + + /* We hardly need an inverse DCT routine for this: just take the + * average pixel value, which is one-eighth of the DC coefficient. + */ + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + dcval = DEQUANTIZE(coef_block[0], quantptr[0]); + dcval = (int) DESCALE((INT32) dcval, 3); + + output_buf[0][output_col] = range_limit[dcval & RANGE_MASK]; +} + +#endif /* IDCT_SCALING_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jinclude.h b/rosapps/lib/libjpeg/jinclude.h new file mode 100644 index 00000000000..0a4f15146ae --- /dev/null +++ b/rosapps/lib/libjpeg/jinclude.h @@ -0,0 +1,91 @@ +/* + * jinclude.h + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file exists to provide a single place to fix any problems with + * including the wrong system include files. (Common problems are taken + * care of by the standard jconfig symbols, but on really weird systems + * you may have to edit this file.) + * + * NOTE: this file is NOT intended to be included by applications using the + * JPEG library. Most applications need only include jpeglib.h. + */ + + +/* Include auto-config file to find out which system include files we need. */ + +#include "jconfig.h" /* auto configuration options */ +#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ + +/* + * We need the NULL macro and size_t typedef. + * On an ANSI-conforming system it is sufficient to include . + * Otherwise, we get them from or ; we may have to + * pull in as well. + * Note that the core JPEG library does not require ; + * only the default error handler and data source/destination modules do. + * But we must pull it in because of the references to FILE in jpeglib.h. + * You can remove those references if you want to compile without . + */ + +#ifdef HAVE_STDDEF_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef NEED_SYS_TYPES_H +#include +#endif + +#include + +/* + * We need memory copying and zeroing functions, plus strncpy(). + * ANSI and System V implementations declare these in . + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + * Some systems may declare memset and memcpy in . + * + * NOTE: we assume the size parameters to these functions are of type size_t. + * Change the casts in these macros if not! + */ + +#ifdef NEED_BSD_STRINGS + +#include +#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) +#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) + +#else /* not BSD, assume ANSI/SysV string lib */ + +#include +#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) +#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) + +#endif + +/* + * In ANSI C, and indeed any rational implementation, size_t is also the + * type returned by sizeof(). However, it seems there are some irrational + * implementations out there, in which sizeof() returns an int even though + * size_t is defined as long or unsigned long. To ensure consistent results + * we always use this SIZEOF() macro in place of using sizeof() directly. + */ + +#define SIZEOF(object) ((size_t) sizeof(object)) + +/* + * The modules that use fread() and fwrite() always invoke them through + * these macros. On some systems you may need to twiddle the argument casts. + * CAUTION: argument order is different from underlying functions! + */ + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) diff --git a/rosapps/lib/libjpeg/jmemansi.c b/rosapps/lib/libjpeg/jmemansi.c new file mode 100644 index 00000000000..2d93e496251 --- /dev/null +++ b/rosapps/lib/libjpeg/jmemansi.c @@ -0,0 +1,167 @@ +/* + * jmemansi.c + * + * Copyright (C) 1992-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a simple generic implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that you have the ANSI-standard library routine tmpfile(). + * Also, the problem of determining the amount of memory available + * is shoved onto the user. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + +#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ +#define SEEK_SET 0 /* if not, assume 0 is correct */ +#endif + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ +#endif + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF(void) +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFREAD(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFWRITE(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + fclose(info->temp_file); + /* Since this implementation uses tmpfile() to create the file, + * no explicit file deletion is needed. + */ +} + + +/* + * Initial opening of a backing-store object. + * + * This version uses tmpfile(), which constructs a suitable file name + * behind the scenes. We don't have to use info->temp_name[] at all; + * indeed, we can't even find out the actual name of the temp file. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + if ((info->temp_file = tmpfile()) == NULL) + ERREXITS(cinfo, JERR_TFILE_CREATE, ""); + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/rosapps/lib/libjpeg/jmemdos.c b/rosapps/lib/libjpeg/jmemdos.c new file mode 100644 index 00000000000..60b45c69388 --- /dev/null +++ b/rosapps/lib/libjpeg/jmemdos.c @@ -0,0 +1,638 @@ +/* + * jmemdos.c + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides an MS-DOS-compatible implementation of the system- + * dependent portion of the JPEG memory manager. Temporary data can be + * stored in extended or expanded memory as well as in regular DOS files. + * + * If you use this file, you must be sure that NEED_FAR_POINTERS is defined + * if you compile in a small-data memory model; it should NOT be defined if + * you use a large-data memory model. This file is not recommended if you + * are using a flat-memory-space 386 environment such as DJGCC or Watcom C. + * Also, this code will NOT work if struct fields are aligned on greater than + * 2-byte boundaries. + * + * Based on code contributed by Ge' Weijers. + */ + +/* + * If you have both extended and expanded memory, you may want to change the + * order in which they are tried in jopen_backing_store. On a 286 machine + * expanded memory is usually faster, since extended memory access involves + * an expensive protected-mode-and-back switch. On 386 and better, extended + * memory is usually faster. As distributed, the code tries extended memory + * first (what? not everyone has a 386? :-). + * + * You can disable use of extended/expanded memory entirely by altering these + * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0). + */ + +#ifndef XMS_SUPPORTED +#define XMS_SUPPORTED 1 +#endif +#ifndef EMS_SUPPORTED +#define EMS_SUPPORTED 1 +#endif + + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare these */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +extern char * getenv JPP((const char * name)); +#endif + +#ifdef NEED_FAR_POINTERS + +#ifdef __TURBOC__ +/* These definitions work for Borland C (Turbo C) */ +#include /* need farmalloc(), farfree() */ +#define far_malloc(x) farmalloc(x) +#define far_free(x) farfree(x) +#else +/* These definitions work for Microsoft C and compatible compilers */ +#include /* need _fmalloc(), _ffree() */ +#define far_malloc(x) _fmalloc(x) +#define far_free(x) _ffree(x) +#endif + +#else /* not NEED_FAR_POINTERS */ + +#define far_malloc(x) malloc(x) +#define far_free(x) free(x) + +#endif /* NEED_FAR_POINTERS */ + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#else +#define READ_BINARY "rb" +#endif + +#ifndef USE_MSDOS_MEMMGR /* make sure user got configuration right */ + You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */ +#endif + +#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */ + MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */ +#endif + + +/* + * Declarations for assembly-language support routines (see jmemdosa.asm). + * + * The functions are declared "far" as are all their pointer arguments; + * this ensures the assembly source code will work regardless of the + * compiler memory model. We assume "short" is 16 bits, "long" is 32. + */ + +typedef void far * XMSDRIVER; /* actually a pointer to code */ +typedef struct { /* registers for calling XMS driver */ + unsigned short ax, dx, bx; + void far * ds_si; + } XMScontext; +typedef struct { /* registers for calling EMS driver */ + unsigned short ax, dx, bx; + void far * ds_si; + } EMScontext; + +extern short far jdos_open JPP((short far * handle, char far * filename)); +extern short far jdos_close JPP((short handle)); +extern short far jdos_seek JPP((short handle, long offset)); +extern short far jdos_read JPP((short handle, void far * buffer, + unsigned short count)); +extern short far jdos_write JPP((short handle, void far * buffer, + unsigned short count)); +extern void far jxms_getdriver JPP((XMSDRIVER far *)); +extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *)); +extern short far jems_available JPP((void)); +extern void far jems_calldriver JPP((EMScontext far *)); + + +/* + * Selection of a file name for a temporary file. + * This is highly system-dependent, and you may want to customize it. + */ + +static int next_file_num; /* to distinguish among several temp files */ + +LOCAL(void) +select_file_name (char * fname) +{ + const char * env; + char * ptr; + FILE * tfile; + + /* Keep generating file names till we find one that's not in use */ + for (;;) { + /* Get temp directory name from environment TMP or TEMP variable; + * if none, use "." + */ + if ((env = (const char *) getenv("TMP")) == NULL) + if ((env = (const char *) getenv("TEMP")) == NULL) + env = "."; + if (*env == '\0') /* null string means "." */ + env = "."; + ptr = fname; /* copy name to fname */ + while (*env != '\0') + *ptr++ = *env++; + if (ptr[-1] != '\\' && ptr[-1] != '/') + *ptr++ = '\\'; /* append backslash if not in env variable */ + /* Append a suitable file name */ + next_file_num++; /* advance counter */ + sprintf(ptr, "JPG%03d.TMP", next_file_num); + /* Probe to see if file name is already in use */ + if ((tfile = fopen(fname, READ_BINARY)) == NULL) + break; + fclose(tfile); /* oops, it's there; close tfile & try again */ + } +} + + +/* + * Near-memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are allocated in far memory, if possible + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) far_malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + far_free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */ +#endif + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + +/* + * For MS-DOS we support three types of backing storage: + * 1. Conventional DOS files. We access these by direct DOS calls rather + * than via the stdio package. This provides a bit better performance, + * but the real reason is that the buffers to be read or written are FAR. + * The stdio library for small-data memory models can't cope with that. + * 2. Extended memory, accessed per the XMS V2.0 specification. + * 3. Expanded memory, accessed per the LIM/EMS 4.0 specification. + * You'll need copies of those specs to make sense of the related code. + * The specs are available by Internet FTP from the SIMTEL archives + * (oak.oakland.edu and its various mirror sites). See files + * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip. + */ + + +/* + * Access methods for a DOS file. + */ + + +METHODDEF(void) +read_file_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (jdos_seek(info->handle.file_handle, file_offset)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ + if (byte_count > 65535L) /* safety check */ + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if (jdos_read(info->handle.file_handle, buffer_address, + (unsigned short) byte_count)) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_file_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (jdos_seek(info->handle.file_handle, file_offset)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ + if (byte_count > 65535L) /* safety check */ + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if (jdos_write(info->handle.file_handle, buffer_address, + (unsigned short) byte_count)) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_file_store (j_common_ptr cinfo, backing_store_ptr info) +{ + jdos_close(info->handle.file_handle); /* close the file */ + remove(info->temp_name); /* delete the file */ +/* If your system doesn't have remove(), try unlink() instead. + * remove() is the ANSI-standard name for this function, but + * unlink() was more common in pre-ANSI systems. + */ + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); +} + + +LOCAL(boolean) +open_file_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + short handle; + + select_file_name(info->temp_name); + if (jdos_open((short far *) & handle, (char far *) info->temp_name)) { + /* might as well exit since jpeg_open_backing_store will fail anyway */ + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + return FALSE; + } + info->handle.file_handle = handle; + info->read_backing_store = read_file_store; + info->write_backing_store = write_file_store; + info->close_backing_store = close_file_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); + return TRUE; /* succeeded */ +} + + +/* + * Access methods for extended memory. + */ + +#if XMS_SUPPORTED + +static XMSDRIVER xms_driver; /* saved address of XMS driver */ + +typedef union { /* either long offset or real-mode pointer */ + long offset; + void far * ptr; + } XMSPTR; + +typedef struct { /* XMS move specification structure */ + long length; + XMSH src_handle; + XMSPTR src; + XMSH dst_handle; + XMSPTR dst; + } XMSspec; + +#define ODD(X) (((X) & 1L) != 0) + + +METHODDEF(void) +read_xms_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + XMScontext ctx; + XMSspec spec; + char endbuffer[2]; + + /* The XMS driver can't cope with an odd length, so handle the last byte + * specially if byte_count is odd. We don't expect this to be common. + */ + + spec.length = byte_count & (~ 1L); + spec.src_handle = info->handle.xms_handle; + spec.src.offset = file_offset; + spec.dst_handle = 0; + spec.dst.ptr = buffer_address; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x0b00; /* EMB move */ + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + ERREXIT(cinfo, JERR_XMS_READ); + + if (ODD(byte_count)) { + read_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0]; + } +} + + +METHODDEF(void) +write_xms_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + XMScontext ctx; + XMSspec spec; + char endbuffer[2]; + + /* The XMS driver can't cope with an odd length, so handle the last byte + * specially if byte_count is odd. We don't expect this to be common. + */ + + spec.length = byte_count & (~ 1L); + spec.src_handle = 0; + spec.src.ptr = buffer_address; + spec.dst_handle = info->handle.xms_handle; + spec.dst.offset = file_offset; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x0b00; /* EMB move */ + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + ERREXIT(cinfo, JERR_XMS_WRITE); + + if (ODD(byte_count)) { + read_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L]; + write_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + } +} + + +METHODDEF(void) +close_xms_store (j_common_ptr cinfo, backing_store_ptr info) +{ + XMScontext ctx; + + ctx.dx = info->handle.xms_handle; + ctx.ax = 0x0a00; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle); + /* we ignore any error return from the driver */ +} + + +LOCAL(boolean) +open_xms_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + XMScontext ctx; + + /* Get address of XMS driver */ + jxms_getdriver((XMSDRIVER far *) & xms_driver); + if (xms_driver == NULL) + return FALSE; /* no driver to be had */ + + /* Get version number, must be >= 2.00 */ + ctx.ax = 0x0000; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax < (unsigned short) 0x0200) + return FALSE; + + /* Try to get space (expressed in kilobytes) */ + ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10); + ctx.ax = 0x0900; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + return FALSE; + + /* Succeeded, save the handle and away we go */ + info->handle.xms_handle = ctx.dx; + info->read_backing_store = read_xms_store; + info->write_backing_store = write_xms_store; + info->close_backing_store = close_xms_store; + TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx); + return TRUE; /* succeeded */ +} + +#endif /* XMS_SUPPORTED */ + + +/* + * Access methods for expanded memory. + */ + +#if EMS_SUPPORTED + +/* The EMS move specification structure requires word and long fields aligned + * at odd byte boundaries. Some compilers will align struct fields at even + * byte boundaries. While it's usually possible to force byte alignment, + * that causes an overall performance penalty and may pose problems in merging + * JPEG into a larger application. Instead we accept some rather dirty code + * here. Note this code would fail if the hardware did not allow odd-byte + * word & long accesses, but all 80x86 CPUs do. + */ + +typedef void far * EMSPTR; + +typedef union { /* EMS move specification structure */ + long length; /* It's easy to access first 4 bytes */ + char bytes[18]; /* Misaligned fields in here! */ + } EMSspec; + +/* Macros for accessing misaligned fields */ +#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset]))) +#define SRC_TYPE(spec) FIELD_AT(spec,4,char) +#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH) +#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short) +#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short) +#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR) +#define DST_TYPE(spec) FIELD_AT(spec,11,char) +#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH) +#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short) +#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short) +#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR) + +#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */ + +#define HIBYTE(W) (((W) >> 8) & 0xFF) +#define LOBYTE(W) ((W) & 0xFF) + + +METHODDEF(void) +read_ems_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + EMScontext ctx; + EMSspec spec; + + spec.length = byte_count; + SRC_TYPE(spec) = 1; + SRC_HANDLE(spec) = info->handle.ems_handle; + SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); + SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); + DST_TYPE(spec) = 0; + DST_HANDLE(spec) = 0; + DST_PTR(spec) = buffer_address; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x5700; /* move memory region */ + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + ERREXIT(cinfo, JERR_EMS_READ); +} + + +METHODDEF(void) +write_ems_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + EMScontext ctx; + EMSspec spec; + + spec.length = byte_count; + SRC_TYPE(spec) = 0; + SRC_HANDLE(spec) = 0; + SRC_PTR(spec) = buffer_address; + DST_TYPE(spec) = 1; + DST_HANDLE(spec) = info->handle.ems_handle; + DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); + DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x5700; /* move memory region */ + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + ERREXIT(cinfo, JERR_EMS_WRITE); +} + + +METHODDEF(void) +close_ems_store (j_common_ptr cinfo, backing_store_ptr info) +{ + EMScontext ctx; + + ctx.ax = 0x4500; + ctx.dx = info->handle.ems_handle; + jems_calldriver((EMScontext far *) & ctx); + TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle); + /* we ignore any error return from the driver */ +} + + +LOCAL(boolean) +open_ems_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + EMScontext ctx; + + /* Is EMS driver there? */ + if (! jems_available()) + return FALSE; + + /* Get status, make sure EMS is OK */ + ctx.ax = 0x4000; + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + return FALSE; + + /* Get version, must be >= 4.0 */ + ctx.ax = 0x4600; + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40) + return FALSE; + + /* Try to allocate requested space */ + ctx.ax = 0x4300; + ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE); + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + return FALSE; + + /* Succeeded, save the handle and away we go */ + info->handle.ems_handle = ctx.dx; + info->read_backing_store = read_ems_store; + info->write_backing_store = write_ems_store; + info->close_backing_store = close_ems_store; + TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx); + return TRUE; /* succeeded */ +} + +#endif /* EMS_SUPPORTED */ + + +/* + * Initial opening of a backing-store object. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + /* Try extended memory, then expanded memory, then regular file. */ +#if XMS_SUPPORTED + if (open_xms_store(cinfo, info, total_bytes_needed)) + return; +#endif +#if EMS_SUPPORTED + if (open_ems_store(cinfo, info, total_bytes_needed)) + return; +#endif + if (open_file_store(cinfo, info, total_bytes_needed)) + return; + ERREXITS(cinfo, JERR_TFILE_CREATE, ""); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; /* initialize temp file name generator */ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* Microsoft C, at least in v6.00A, will not successfully reclaim freed + * blocks of size > 32Kbytes unless we give it a kick in the rear, like so: + */ +#ifdef NEED_FHEAPMIN + _fheapmin(); +#endif +} diff --git a/rosapps/lib/libjpeg/jmemdosa.asm b/rosapps/lib/libjpeg/jmemdosa.asm new file mode 100644 index 00000000000..ecd43729fe5 --- /dev/null +++ b/rosapps/lib/libjpeg/jmemdosa.asm @@ -0,0 +1,379 @@ +; +; jmemdosa.asm +; +; Copyright (C) 1992, Thomas G. Lane. +; This file is part of the Independent JPEG Group's software. +; For conditions of distribution and use, see the accompanying README file. +; +; This file contains low-level interface routines to support the MS-DOS +; backing store manager (jmemdos.c). Routines are provided to access disk +; files through direct DOS calls, and to access XMS and EMS drivers. +; +; This file should assemble with Microsoft's MASM or any compatible +; assembler (including Borland's Turbo Assembler). If you haven't got +; a compatible assembler, better fall back to jmemansi.c or jmemname.c. +; +; To minimize dependence on the C compiler's register usage conventions, +; we save and restore all 8086 registers, even though most compilers only +; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return +; values, which everybody returns in AX. +; +; Based on code contributed by Ge' Weijers. +; + +JMEMDOSA_TXT segment byte public 'CODE' + + assume cs:JMEMDOSA_TXT + + public _jdos_open + public _jdos_close + public _jdos_seek + public _jdos_read + public _jdos_write + public _jxms_getdriver + public _jxms_calldriver + public _jems_available + public _jems_calldriver + +; +; short far jdos_open (short far * handle, char far * filename) +; +; Create and open a temporary file +; +_jdos_open proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov cx,0 ; normal file attributes + lds dx,dword ptr [bp+10] ; get filename pointer + mov ah,3ch ; create file + int 21h + jc open_err ; if failed, return error code + lds bx,dword ptr [bp+6] ; get handle pointer + mov word ptr [bx],ax ; save the handle + xor ax,ax ; return zero for OK +open_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_open endp + + +; +; short far jdos_close (short handle) +; +; Close the file handle +; +_jdos_close proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + mov ah,3eh ; close file + int 21h + jc close_err ; if failed, return error code + xor ax,ax ; return zero for OK +close_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_close endp + + +; +; short far jdos_seek (short handle, long offset) +; +; Set file position +; +_jdos_seek proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + mov dx,word ptr [bp+8] ; LS offset + mov cx,word ptr [bp+10] ; MS offset + mov ax,4200h ; absolute seek + int 21h + jc seek_err ; if failed, return error code + xor ax,ax ; return zero for OK +seek_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_seek endp + + +; +; short far jdos_read (short handle, void far * buffer, unsigned short count) +; +; Read from file +; +_jdos_read proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + lds dx,dword ptr [bp+8] ; buffer address + mov cx,word ptr [bp+12] ; number of bytes + mov ah,3fh ; read file + int 21h + jc read_err ; if failed, return error code + cmp ax,word ptr [bp+12] ; make sure all bytes were read + je read_ok + mov ax,1 ; else return 1 for not OK + jmp short read_err +read_ok: xor ax,ax ; return zero for OK +read_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_read endp + + +; +; short far jdos_write (short handle, void far * buffer, unsigned short count) +; +; Write to file +; +_jdos_write proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + lds dx,dword ptr [bp+8] ; buffer address + mov cx,word ptr [bp+12] ; number of bytes + mov ah,40h ; write file + int 21h + jc write_err ; if failed, return error code + cmp ax,word ptr [bp+12] ; make sure all bytes written + je write_ok + mov ax,1 ; else return 1 for not OK + jmp short write_err +write_ok: xor ax,ax ; return zero for OK +write_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_write endp + + +; +; void far jxms_getdriver (XMSDRIVER far *) +; +; Get the address of the XMS driver, or NULL if not available +; +_jxms_getdriver proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov ax,4300h ; call multiplex interrupt with + int 2fh ; a magic cookie, hex 4300 + cmp al,80h ; AL should contain hex 80 + je xmsavail + xor dx,dx ; no XMS driver available + xor ax,ax ; return a nil pointer + jmp short xmsavail_done +xmsavail: mov ax,4310h ; fetch driver address with + int 2fh ; another magic cookie + mov dx,es ; copy address to dx:ax + mov ax,bx +xmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value + mov word ptr es:[bx],ax + mov word ptr es:[bx+2],dx + pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jxms_getdriver endp + + +; +; void far jxms_calldriver (XMSDRIVER, XMScontext far *) +; +; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers. +; These are loaded, the XMS call is performed, and the new values of the +; AX,DX,BX registers are written back to the context structure. +; +_jxms_calldriver proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + les bx,dword ptr [bp+10] ; get XMScontext pointer + mov ax,word ptr es:[bx] ; load registers + mov dx,word ptr es:[bx+2] + mov si,word ptr es:[bx+6] + mov ds,word ptr es:[bx+8] + mov bx,word ptr es:[bx+4] + call dword ptr [bp+6] ; call the driver + mov cx,bx ; save returned BX for a sec + les bx,dword ptr [bp+10] ; get XMScontext pointer + mov word ptr es:[bx],ax ; put back ax,dx,bx + mov word ptr es:[bx+2],dx + mov word ptr es:[bx+4],cx + pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jxms_calldriver endp + + +; +; short far jems_available (void) +; +; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs) +; +_jems_available proc far + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov ax,3567h ; get interrupt vector 67h + int 21h + push cs + pop ds + mov di,000ah ; check offs 10 in returned seg + lea si,ASCII_device_name ; against literal string + mov cx,8 + cld + repe cmpsb + jne no_ems + mov ax,1 ; match, it's there + jmp short avail_done +no_ems: xor ax,ax ; it's not there +avail_done: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + ret + +ASCII_device_name db "EMMXXXX0" + +_jems_available endp + + +; +; void far jems_calldriver (EMScontext far *) +; +; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers. +; These are loaded, the EMS trap is performed, and the new values of the +; AX,DX,BX registers are written back to the context structure. +; +_jems_calldriver proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + les bx,dword ptr [bp+6] ; get EMScontext pointer + mov ax,word ptr es:[bx] ; load registers + mov dx,word ptr es:[bx+2] + mov si,word ptr es:[bx+6] + mov ds,word ptr es:[bx+8] + mov bx,word ptr es:[bx+4] + int 67h ; call the EMS driver + mov cx,bx ; save returned BX for a sec + les bx,dword ptr [bp+6] ; get EMScontext pointer + mov word ptr es:[bx],ax ; put back ax,dx,bx + mov word ptr es:[bx+2],dx + mov word ptr es:[bx+4],cx + pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jems_calldriver endp + +JMEMDOSA_TXT ends + + end diff --git a/rosapps/lib/libjpeg/jmemmac.c b/rosapps/lib/libjpeg/jmemmac.c new file mode 100644 index 00000000000..106f9bea05d --- /dev/null +++ b/rosapps/lib/libjpeg/jmemmac.c @@ -0,0 +1,289 @@ +/* + * jmemmac.c + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * jmemmac.c provides an Apple Macintosh implementation of the system- + * dependent portion of the JPEG memory manager. + * + * If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the + * JPEG_INTERNALS part of jconfig.h. + * + * jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr + * instead of malloc and free. It accurately determines the amount of + * memory available by using CompactMem. Notice that if left to its + * own devices, this code can chew up all available space in the + * application's zone, with the exception of the rather small "slop" + * factor computed in jpeg_mem_available(). The application can ensure + * that more space is left over by reducing max_memory_to_use. + * + * Large images are swapped to disk using temporary files and System 7.0+'s + * temporary folder functionality. + * + * Note that jmemmac.c depends on two features of MacOS that were first + * introduced in System 7: FindFolder and the FSSpec-based calls. + * If your application uses jmemmac.c and is run under System 6 or earlier, + * and the jpeg library decides it needs a temporary file, it will abort, + * printing error messages about requiring System 7. (If no temporary files + * are created, it will run fine.) + * + * If you want to use jmemmac.c in an application that might be used with + * System 6 or earlier, then you should remove dependencies on FindFolder + * and the FSSpec calls. You will need to replace FindFolder with some + * other mechanism for finding a place to put temporary files, and you + * should replace the FSSpec calls with their HFS equivalents: + * + * FSpDelete -> HDelete + * FSpGetFInfo -> HGetFInfo + * FSpCreate -> HCreate + * FSpOpenDF -> HOpen *** Note: not HOpenDF *** + * FSMakeFSSpec -> (fill in spec by hand.) + * + * (Use HOpen instead of HOpenDF. HOpen is just a glue-interface to PBHOpen, + * which is on all HFS macs. HOpenDF is a System 7 addition which avoids the + * ages-old problem of names starting with a period.) + * + * Contributed by Sam Bushell (jsam@iagu.on.net) and + * Dan Gildor (gyld@in-touch.com). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef USE_MAC_MEMMGR /* make sure user got configuration right */ + You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */ +#endif + +#include /* we use the MacOS memory manager */ +#include /* we use the MacOS File stuff */ +#include /* we use the MacOS HFS stuff */ +#include /* for smSystemScript */ +#include /* we use Gestalt to test for specific functionality */ + +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "JPG%03d.TMP" +#endif + +static int next_file_num; /* to distinguish among several temp files */ + + +/* + * Memory allocation and freeing are controlled by the MacOS library + * routines NewPtr() and DisposePtr(), which allocate fixed-address + * storage. Unfortunately, the IJG library isn't smart enough to cope + * with relocatable storage. + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) NewPtr(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + DisposePtr((Ptr) object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: we include FAR keywords in the routine declarations simply for + * consistency with the rest of the IJG code; FAR should expand to empty + * on rational architectures like the Mac. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) NewPtr(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + DisposePtr((Ptr) object); +} + + +/* + * This routine computes the total memory space available for allocation. + */ + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + long limit = cinfo->mem->max_memory_to_use - already_allocated; + long slop, mem; + + /* Don't ask for more than what application has told us we may use */ + if (max_bytes_needed > limit && limit > 0) + max_bytes_needed = limit; + /* Find whether there's a big enough free block in the heap. + * CompactMem tries to create a contiguous block of the requested size, + * and then returns the size of the largest free block (which could be + * much more or much less than we asked for). + * We add some slop to ensure we don't use up all available memory. + */ + slop = max_bytes_needed / 16 + 32768L; + mem = CompactMem(max_bytes_needed + slop) - slop; + if (mem < 0) + mem = 0; /* sigh, couldn't even get the slop */ + /* Don't take more than the application says we can have */ + if (mem > limit && limit > 0) + mem = limit; + return mem; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF(void) +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + long bytes = byte_count; + long retVal; + + if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr ) + ERREXIT(cinfo, JERR_TFILE_SEEK); + + retVal = FSRead ( info->temp_file, &bytes, + (unsigned char *) buffer_address ); + if ( retVal != noErr || bytes != byte_count ) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + long bytes = byte_count; + long retVal; + + if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr ) + ERREXIT(cinfo, JERR_TFILE_SEEK); + + retVal = FSWrite ( info->temp_file, &bytes, + (unsigned char *) buffer_address ); + if ( retVal != noErr || bytes != byte_count ) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + FSClose ( info->temp_file ); + FSpDelete ( &(info->tempSpec) ); +} + + +/* + * Initial opening of a backing-store object. + * + * This version uses FindFolder to find the Temporary Items folder, + * and puts the temporary file in there. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + short tmpRef, vRefNum; + long dirID; + FInfo finderInfo; + FSSpec theSpec; + Str255 fName; + OSErr osErr; + long gestaltResponse = 0; + + /* Check that FSSpec calls are available. */ + osErr = Gestalt( gestaltFSAttr, &gestaltResponse ); + if ( ( osErr != noErr ) + || !( gestaltResponse & (1<temp_name, TEMP_FILE_NAME, next_file_num); + strcpy ( (Ptr)fName+1, info->temp_name ); + *fName = strlen (info->temp_name); + osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec ); + + if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr ) + break; + } + + osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript ); + if ( osErr != noErr ) + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + + osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) ); + if ( osErr != noErr ) + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + + info->tempSpec = theSpec; + + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; + + /* max_memory_to_use will be initialized to FreeMem()'s result; + * the calling application might later reduce it, for example + * to leave room to invoke multiple JPEG objects. + * Note that FreeMem returns the total number of free bytes; + * it may not be possible to allocate a single block of this size. + */ + return FreeMem(); +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/rosapps/lib/libjpeg/jmemmgr.c b/rosapps/lib/libjpeg/jmemmgr.c new file mode 100644 index 00000000000..d801b322da0 --- /dev/null +++ b/rosapps/lib/libjpeg/jmemmgr.c @@ -0,0 +1,1118 @@ +/* + * jmemmgr.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the JPEG system-independent memory management + * routines. This code is usable across a wide variety of machines; most + * of the system dependencies have been isolated in a separate file. + * The major functions provided here are: + * * pool-based allocation and freeing of memory; + * * policy decisions about how to divide available memory among the + * virtual arrays; + * * control logic for swapping virtual arrays between main memory and + * backing storage. + * The separate system-dependent file provides the actual backing-storage + * access code, and it contains the policy decision about how much total + * main memory to use. + * This file is system-dependent in the sense that some of its functions + * are unnecessary in some systems. For example, if there is enough virtual + * memory so that backing storage will never be used, much of the virtual + * array control logic could be removed. (Of course, if you have that much + * memory then you shouldn't care about a little bit of unused code...) + */ + +#define JPEG_INTERNALS +#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef NO_GETENV +#ifndef HAVE_STDLIB_H /* should declare getenv() */ +extern char * getenv JPP((const char * name)); +#endif +#endif + + +/* + * Some important notes: + * The allocation routines provided here must never return NULL. + * They should exit to error_exit if unsuccessful. + * + * It's not a good idea to try to merge the sarray and barray routines, + * even though they are textually almost the same, because samples are + * usually stored as bytes while coefficients are shorts or ints. Thus, + * in machines where byte pointers have a different representation from + * word pointers, the resulting machine code could not be the same. + */ + + +/* + * Many machines require storage alignment: longs must start on 4-byte + * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() + * always returns pointers that are multiples of the worst-case alignment + * requirement, and we had better do so too. + * There isn't any really portable way to determine the worst-case alignment + * requirement. This module assumes that the alignment requirement is + * multiples of sizeof(ALIGN_TYPE). + * By default, we define ALIGN_TYPE as double. This is necessary on some + * workstations (where doubles really do need 8-byte alignment) and will work + * fine on nearly everything. If your machine has lesser alignment needs, + * you can save a few bytes by making ALIGN_TYPE smaller. + * The only place I know of where this will NOT work is certain Macintosh + * 680x0 compilers that define double as a 10-byte IEEE extended float. + * Doing 10-byte alignment is counterproductive because longwords won't be + * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have + * such a compiler. + */ + +#ifndef ALIGN_TYPE /* so can override from jconfig.h */ +#define ALIGN_TYPE double +#endif + + +/* + * We allocate objects from "pools", where each pool is gotten with a single + * request to jpeg_get_small() or jpeg_get_large(). There is no per-object + * overhead within a pool, except for alignment padding. Each pool has a + * header with a link to the next pool of the same class. + * Small and large pool headers are identical except that the latter's + * link pointer must be FAR on 80x86 machines. + * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE + * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple + * of the alignment requirement of ALIGN_TYPE. + */ + +typedef union small_pool_struct * small_pool_ptr; + +typedef union small_pool_struct { + struct { + small_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} small_pool_hdr; + +typedef union large_pool_struct FAR * large_pool_ptr; + +typedef union large_pool_struct { + struct { + large_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} large_pool_hdr; + + +/* + * Here is the full definition of a memory manager object. + */ + +typedef struct { + struct jpeg_memory_mgr pub; /* public fields */ + + /* Each pool identifier (lifetime class) names a linked list of pools. */ + small_pool_ptr small_list[JPOOL_NUMPOOLS]; + large_pool_ptr large_list[JPOOL_NUMPOOLS]; + + /* Since we only have one lifetime class of virtual arrays, only one + * linked list is necessary (for each datatype). Note that the virtual + * array control blocks being linked together are actually stored somewhere + * in the small-pool list. + */ + jvirt_sarray_ptr virt_sarray_list; + jvirt_barray_ptr virt_barray_list; + + /* This counts total space obtained from jpeg_get_small/large */ + long total_space_allocated; + + /* alloc_sarray and alloc_barray set this value for use by virtual + * array routines. + */ + JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ +} my_memory_mgr; + +typedef my_memory_mgr * my_mem_ptr; + + +/* + * The control blocks for virtual arrays. + * Note that these blocks are allocated in the "small" pool area. + * System-dependent info for the associated backing store (if any) is hidden + * inside the backing_store_info struct. + */ + +struct jvirt_sarray_control { + JSAMPARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_sarray_ptr next; /* link to next virtual sarray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + +struct jvirt_barray_control { + JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_barray_ptr next; /* link to next virtual barray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + + +#ifdef MEM_STATS /* optional extra stuff for statistics */ + +LOCAL(void) +print_mem_stats (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + + /* Since this is only a debugging stub, we can cheat a little by using + * fprintf directly rather than going through the trace message code. + * This is helpful because message parm array can't handle longs. + */ + fprintf(stderr, "Freeing pool %d, total space = %ld\n", + pool_id, mem->total_space_allocated); + + for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; + lhdr_ptr = lhdr_ptr->hdr.next) { + fprintf(stderr, " Large chunk used %ld\n", + (long) lhdr_ptr->hdr.bytes_used); + } + + for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; + shdr_ptr = shdr_ptr->hdr.next) { + fprintf(stderr, " Small chunk used %ld free %ld\n", + (long) shdr_ptr->hdr.bytes_used, + (long) shdr_ptr->hdr.bytes_left); + } +} + +#endif /* MEM_STATS */ + + +LOCAL(void) +out_of_memory (j_common_ptr cinfo, int which) +/* Report an out-of-memory error and stop execution */ +/* If we compiled MEM_STATS support, report alloc requests before dying */ +{ +#ifdef MEM_STATS + cinfo->err->trace_level = 2; /* force self_destruct to report stats */ +#endif + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); +} + + +/* + * Allocation of "small" objects. + * + * For these, we use pooled storage. When a new pool must be created, + * we try to get enough space for the current request plus a "slop" factor, + * where the slop will be the amount of leftover space in the new pool. + * The speed vs. space tradeoff is largely determined by the slop values. + * A different slop value is provided for each pool class (lifetime), + * and we also distinguish the first pool of a class from later ones. + * NOTE: the values given work fairly well on both 16- and 32-bit-int + * machines, but may be too small if longs are 64 bits or more. + */ + +static const size_t first_pool_slop[JPOOL_NUMPOOLS] = +{ + 1600, /* first PERMANENT pool */ + 16000 /* first IMAGE pool */ +}; + +static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = +{ + 0, /* additional PERMANENT pools */ + 5000 /* additional IMAGE pools */ +}; + +#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ + + +METHODDEF(void *) +alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "small" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr hdr_ptr, prev_hdr_ptr; + char * data_ptr; + size_t odd_bytes, min_request, slop; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) + out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* See if space is available in any existing pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + prev_hdr_ptr = NULL; + hdr_ptr = mem->small_list[pool_id]; + while (hdr_ptr != NULL) { + if (hdr_ptr->hdr.bytes_left >= sizeofobject) + break; /* found pool with enough space */ + prev_hdr_ptr = hdr_ptr; + hdr_ptr = hdr_ptr->hdr.next; + } + + /* Time to make a new pool? */ + if (hdr_ptr == NULL) { + /* min_request is what we need now, slop is what will be leftover */ + min_request = sizeofobject + SIZEOF(small_pool_hdr); + if (prev_hdr_ptr == NULL) /* first pool in class? */ + slop = first_pool_slop[pool_id]; + else + slop = extra_pool_slop[pool_id]; + /* Don't ask for more than MAX_ALLOC_CHUNK */ + if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request)) + slop = (size_t) (MAX_ALLOC_CHUNK-min_request); + /* Try to get space, if fail reduce slop and try again */ + for (;;) { + hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); + if (hdr_ptr != NULL) + break; + slop /= 2; + if (slop < MIN_SLOP) /* give up when it gets real small */ + out_of_memory(cinfo, 2); /* jpeg_get_small failed */ + } + mem->total_space_allocated += min_request + slop; + /* Success, initialize the new pool header and add to end of list */ + hdr_ptr->hdr.next = NULL; + hdr_ptr->hdr.bytes_used = 0; + hdr_ptr->hdr.bytes_left = sizeofobject + slop; + if (prev_hdr_ptr == NULL) /* first pool in class? */ + mem->small_list[pool_id] = hdr_ptr; + else + prev_hdr_ptr->hdr.next = hdr_ptr; + } + + /* OK, allocate the object from the current pool */ + data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ + data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ + hdr_ptr->hdr.bytes_used += sizeofobject; + hdr_ptr->hdr.bytes_left -= sizeofobject; + + return (void *) data_ptr; +} + + +/* + * Allocation of "large" objects. + * + * The external semantics of these are the same as "small" objects, + * except that FAR pointers are used on 80x86. However the pool + * management heuristics are quite different. We assume that each + * request is large enough that it may as well be passed directly to + * jpeg_get_large; the pool management just links everything together + * so that we can free it all on demand. + * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY + * structures. The routines that create these structures (see below) + * deliberately bunch rows together to ensure a large request size. + */ + +METHODDEF(void FAR *) +alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "large" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + large_pool_ptr hdr_ptr; + size_t odd_bytes; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) + out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* Always make a new pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + + SIZEOF(large_pool_hdr)); + if (hdr_ptr == NULL) + out_of_memory(cinfo, 4); /* jpeg_get_large failed */ + mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); + + /* Success, initialize the new pool header and add to list */ + hdr_ptr->hdr.next = mem->large_list[pool_id]; + /* We maintain space counts in each pool header for statistical purposes, + * even though they are not needed for allocation. + */ + hdr_ptr->hdr.bytes_used = sizeofobject; + hdr_ptr->hdr.bytes_left = 0; + mem->large_list[pool_id] = hdr_ptr; + + return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */ +} + + +/* + * Creation of 2-D sample arrays. + * The pointers are in near heap, the samples themselves in FAR heap. + * + * To minimize allocation overhead and to allow I/O of large contiguous + * blocks, we allocate the sample rows in groups of as many rows as possible + * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. + * NB: the virtual array control routines, later in this file, know about + * this chunking of rows. The rowsperchunk value is left in the mem manager + * object so that it can be saved away if this sarray is the workspace for + * a virtual array. + */ + +METHODDEF(JSAMPARRAY) +alloc_sarray (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, JDIMENSION numrows) +/* Allocate a 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JSAMPARRAY result; + JSAMPROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) samplesperrow * SIZEOF(JSAMPLE)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JSAMPARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JSAMPROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JSAMPROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow + * SIZEOF(JSAMPLE))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += samplesperrow; + } + } + + return result; +} + + +/* + * Creation of 2-D coefficient-block arrays. + * This is essentially the same as the code for sample arrays, above. + */ + +METHODDEF(JBLOCKARRAY) +alloc_barray (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, JDIMENSION numrows) +/* Allocate a 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JBLOCKARRAY result; + JBLOCKROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) blocksperrow * SIZEOF(JBLOCK)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JBLOCKROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow + * SIZEOF(JBLOCK))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += blocksperrow; + } + } + + return result; +} + + +/* + * About virtual array management: + * + * The above "normal" array routines are only used to allocate strip buffers + * (as wide as the image, but just a few rows high). Full-image-sized buffers + * are handled as "virtual" arrays. The array is still accessed a strip at a + * time, but the memory manager must save the whole array for repeated + * accesses. The intended implementation is that there is a strip buffer in + * memory (as high as is possible given the desired memory limit), plus a + * backing file that holds the rest of the array. + * + * The request_virt_array routines are told the total size of the image and + * the maximum number of rows that will be accessed at once. The in-memory + * buffer must be at least as large as the maxaccess value. + * + * The request routines create control blocks but not the in-memory buffers. + * That is postponed until realize_virt_arrays is called. At that time the + * total amount of space needed is known (approximately, anyway), so free + * memory can be divided up fairly. + * + * The access_virt_array routines are responsible for making a specific strip + * area accessible (after reading or writing the backing file, if necessary). + * Note that the access routines are told whether the caller intends to modify + * the accessed strip; during a read-only pass this saves having to rewrite + * data to disk. The access routines are also responsible for pre-zeroing + * any newly accessed rows, if pre-zeroing was requested. + * + * In current usage, the access requests are usually for nonoverlapping + * strips; that is, successive access start_row numbers differ by exactly + * num_rows = maxaccess. This means we can get good performance with simple + * buffer dump/reload logic, by making the in-memory buffer be a multiple + * of the access height; then there will never be accesses across bufferload + * boundaries. The code will still work with overlapping access requests, + * but it doesn't handle bufferload overlaps very efficiently. + */ + + +METHODDEF(jvirt_sarray_ptr) +request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION samplesperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_sarray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_sarray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->samplesperrow = samplesperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ + mem->virt_sarray_list = result; + + return result; +} + + +METHODDEF(jvirt_barray_ptr) +request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION blocksperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_barray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_barray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->blocksperrow = blocksperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_barray_list; /* add to list of virtual arrays */ + mem->virt_barray_list = result; + + return result; +} + + +METHODDEF(void) +realize_virt_arrays (j_common_ptr cinfo) +/* Allocate the in-memory buffers for any unrealized virtual arrays */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + long space_per_minheight, maximum_space, avail_mem; + long minheights, max_minheights; + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + /* Compute the minimum space needed (maxaccess rows in each buffer) + * and the maximum space needed (full image height in each buffer). + * These may be of use to the system-dependent jpeg_mem_available routine. + */ + space_per_minheight = 0; + maximum_space = 0; + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) sptr->maxaccess * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + maximum_space += (long) sptr->rows_in_array * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + } + } + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) bptr->maxaccess * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + maximum_space += (long) bptr->rows_in_array * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + } + } + + if (space_per_minheight <= 0) + return; /* no unrealized arrays, no work */ + + /* Determine amount of memory to actually use; this is system-dependent. */ + avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, + mem->total_space_allocated); + + /* If the maximum space needed is available, make all the buffers full + * height; otherwise parcel it out with the same number of minheights + * in each buffer. + */ + if (avail_mem >= maximum_space) + max_minheights = 1000000000L; + else { + max_minheights = avail_mem / space_per_minheight; + /* If there doesn't seem to be enough space, try to get the minimum + * anyway. This allows a "stub" implementation of jpeg_mem_available(). + */ + if (max_minheights <= 0) + max_minheights = 1; + } + + /* Allocate the in-memory buffers and initialize backing store as needed. */ + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + sptr->rows_in_mem = sptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); + jpeg_open_backing_store(cinfo, & sptr->b_s_info, + (long) sptr->rows_in_array * + (long) sptr->samplesperrow * + (long) SIZEOF(JSAMPLE)); + sptr->b_s_open = TRUE; + } + sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, + sptr->samplesperrow, sptr->rows_in_mem); + sptr->rowsperchunk = mem->last_rowsperchunk; + sptr->cur_start_row = 0; + sptr->first_undef_row = 0; + sptr->dirty = FALSE; + } + } + + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + bptr->rows_in_mem = bptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); + jpeg_open_backing_store(cinfo, & bptr->b_s_info, + (long) bptr->rows_in_array * + (long) bptr->blocksperrow * + (long) SIZEOF(JBLOCK)); + bptr->b_s_open = TRUE; + } + bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, + bptr->blocksperrow, bptr->rows_in_mem); + bptr->rowsperchunk = mem->last_rowsperchunk; + bptr->cur_start_row = 0; + bptr->first_undef_row = 0; + bptr->dirty = FALSE; + } + } +} + + +LOCAL(void) +do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual sample array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +LOCAL(void) +do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual coefficient-block array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +METHODDEF(JSAMPARRAY) +access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual sample array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_sarray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_sarray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +METHODDEF(JBLOCKARRAY) +access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual block array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_barray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_barray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +/* + * Release all objects belonging to a specified pool. + */ + +METHODDEF(void) +free_pool (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + size_t space_freed; + + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + +#ifdef MEM_STATS + if (cinfo->err->trace_level > 1) + print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */ +#endif + + /* If freeing IMAGE pool, close any virtual arrays first */ + if (pool_id == JPOOL_IMAGE) { + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->b_s_open) { /* there may be no backing store */ + sptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); + } + } + mem->virt_sarray_list = NULL; + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->b_s_open) { /* there may be no backing store */ + bptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); + } + } + mem->virt_barray_list = NULL; + } + + /* Release large objects */ + lhdr_ptr = mem->large_list[pool_id]; + mem->large_list[pool_id] = NULL; + + while (lhdr_ptr != NULL) { + large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; + space_freed = lhdr_ptr->hdr.bytes_used + + lhdr_ptr->hdr.bytes_left + + SIZEOF(large_pool_hdr); + jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + lhdr_ptr = next_lhdr_ptr; + } + + /* Release small objects */ + shdr_ptr = mem->small_list[pool_id]; + mem->small_list[pool_id] = NULL; + + while (shdr_ptr != NULL) { + small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; + space_freed = shdr_ptr->hdr.bytes_used + + shdr_ptr->hdr.bytes_left + + SIZEOF(small_pool_hdr); + jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + shdr_ptr = next_shdr_ptr; + } +} + + +/* + * Close up shop entirely. + * Note that this cannot be called unless cinfo->mem is non-NULL. + */ + +METHODDEF(void) +self_destruct (j_common_ptr cinfo) +{ + int pool; + + /* Close all backing store, release all memory. + * Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + free_pool(cinfo, pool); + } + + /* Release the memory manager control block too. */ + jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); + cinfo->mem = NULL; /* ensures I will be called only once */ + + jpeg_mem_term(cinfo); /* system-dependent cleanup */ +} + + +/* + * Memory manager initialization. + * When this is called, only the error manager pointer is valid in cinfo! + */ + +GLOBAL(void) +jinit_memory_mgr (j_common_ptr cinfo) +{ + my_mem_ptr mem; + long max_to_use; + int pool; + size_t test_mac; + + cinfo->mem = NULL; /* for safety if init fails */ + + /* Check for configuration errors. + * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably + * doesn't reflect any real hardware alignment requirement. + * The test is a little tricky: for X>0, X and X-1 have no one-bits + * in common if and only if X is a power of 2, ie has only one one-bit. + * Some compilers may give an "unreachable code" warning here; ignore it. + */ + if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0) + ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); + /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be + * a multiple of SIZEOF(ALIGN_TYPE). + * Again, an "unreachable code" warning may be ignored here. + * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. + */ + test_mac = (size_t) MAX_ALLOC_CHUNK; + if ((long) test_mac != MAX_ALLOC_CHUNK || + (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0) + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + + max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ + + /* Attempt to allocate memory manager's control block */ + mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); + + if (mem == NULL) { + jpeg_mem_term(cinfo); /* system-dependent cleanup */ + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); + } + + /* OK, fill in the method pointers */ + mem->pub.alloc_small = alloc_small; + mem->pub.alloc_large = alloc_large; + mem->pub.alloc_sarray = alloc_sarray; + mem->pub.alloc_barray = alloc_barray; + mem->pub.request_virt_sarray = request_virt_sarray; + mem->pub.request_virt_barray = request_virt_barray; + mem->pub.realize_virt_arrays = realize_virt_arrays; + mem->pub.access_virt_sarray = access_virt_sarray; + mem->pub.access_virt_barray = access_virt_barray; + mem->pub.free_pool = free_pool; + mem->pub.self_destruct = self_destruct; + + /* Make MAX_ALLOC_CHUNK accessible to other modules */ + mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK; + + /* Initialize working state */ + mem->pub.max_memory_to_use = max_to_use; + + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + mem->small_list[pool] = NULL; + mem->large_list[pool] = NULL; + } + mem->virt_sarray_list = NULL; + mem->virt_barray_list = NULL; + + mem->total_space_allocated = SIZEOF(my_memory_mgr); + + /* Declare ourselves open for business */ + cinfo->mem = & mem->pub; + + /* Check for an environment variable JPEGMEM; if found, override the + * default max_memory setting from jpeg_mem_init. Note that the + * surrounding application may again override this value. + * If your system doesn't support getenv(), define NO_GETENV to disable + * this feature. + */ +#ifndef NO_GETENV + { char * memenv; + + if ((memenv = getenv("JPEGMEM")) != NULL) { + char ch = 'x'; + + if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { + if (ch == 'm' || ch == 'M') + max_to_use *= 1000L; + mem->pub.max_memory_to_use = max_to_use * 1000L; + } + } + } +#endif + +} diff --git a/rosapps/lib/libjpeg/jmemname.c b/rosapps/lib/libjpeg/jmemname.c new file mode 100644 index 00000000000..ed96dee1bc8 --- /dev/null +++ b/rosapps/lib/libjpeg/jmemname.c @@ -0,0 +1,276 @@ +/* + * jmemname.c + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a generic implementation of the system-dependent + * portion of the JPEG memory manager. This implementation assumes that + * you must explicitly construct a name for each temp file. + * Also, the problem of determining the amount of memory available + * is shoved onto the user. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + +#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ +#define SEEK_SET 0 /* if not, assume 0 is correct */ +#endif + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define RW_BINARY "w+" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define RW_BINARY "w+b", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#define RW_BINARY "w+b" +#endif +#endif + + +/* + * Selection of a file name for a temporary file. + * This is system-dependent! + * + * The code as given is suitable for most Unix systems, and it is easily + * modified for most non-Unix systems. Some notes: + * 1. The temp file is created in the directory named by TEMP_DIRECTORY. + * The default value is /usr/tmp, which is the conventional place for + * creating large temp files on Unix. On other systems you'll probably + * want to change the file location. You can do this by editing the + * #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h. + * + * 2. If you need to change the file name as well as its location, + * you can override the TEMP_FILE_NAME macro. (Note that this is + * actually a printf format string; it must contain %s and %d.) + * Few people should need to do this. + * + * 3. mktemp() is used to ensure that multiple processes running + * simultaneously won't select the same file names. If your system + * doesn't have mktemp(), define NO_MKTEMP to do it the hard way. + * (If you don't have , also define NO_ERRNO_H.) + * + * 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c + * will cause the temp files to be removed if you stop the program early. + */ + +#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */ +#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */ +#endif + +static int next_file_num; /* to distinguish among several temp files */ + +#ifdef NO_MKTEMP + +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "%sJPG%03d.TMP" +#endif + +#ifndef NO_ERRNO_H +#include /* to define ENOENT */ +#endif + +/* ANSI C specifies that errno is a macro, but on older systems it's more + * likely to be a plain int variable. And not all versions of errno.h + * bother to declare it, so we have to in order to be most portable. Thus: + */ +#ifndef errno +extern int errno; +#endif + + +LOCAL(void) +select_file_name (char * fname) +{ + FILE * tfile; + + /* Keep generating file names till we find one that's not in use */ + for (;;) { + next_file_num++; /* advance counter */ + sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); + if ((tfile = fopen(fname, READ_BINARY)) == NULL) { + /* fopen could have failed for a reason other than the file not + * being there; for example, file there but unreadable. + * If isn't available, then we cannot test the cause. + */ +#ifdef ENOENT + if (errno != ENOENT) + continue; +#endif + break; + } + fclose(tfile); /* oops, it's there; close tfile & try again */ + } +} + +#else /* ! NO_MKTEMP */ + +/* Note that mktemp() requires the initial filename to end in six X's */ +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "%sJPG%dXXXXXX" +#endif + +LOCAL(void) +select_file_name (char * fname) +{ + next_file_num++; /* advance counter */ + sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); + mktemp(fname); /* make sure file name is unique */ + /* mktemp replaces the trailing XXXXXX with a unique string of characters */ +} + +#endif /* NO_MKTEMP */ + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ +#endif + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF(void) +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFREAD(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFWRITE(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + fclose(info->temp_file); /* close the file */ + unlink(info->temp_name); /* delete the file */ +/* If your system doesn't have unlink(), use remove() instead. + * remove() is the ANSI-standard name for this function, but if + * your system was ANSI you'd be using jmemansi.c, right? + */ + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); +} + + +/* + * Initial opening of a backing-store object. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + select_file_name(info->temp_name); + if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL) + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; /* initialize temp file name generator */ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/rosapps/lib/libjpeg/jmemnobs.c b/rosapps/lib/libjpeg/jmemnobs.c new file mode 100644 index 00000000000..eb8c337725f --- /dev/null +++ b/rosapps/lib/libjpeg/jmemnobs.c @@ -0,0 +1,109 @@ +/* + * jmemnobs.c + * + * Copyright (C) 1992-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a really simple implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that no backing-store files are needed: all required space + * can be obtained from malloc(). + * This is very portable in the sense that it'll compile on almost anything, + * but you'd better have lots of main memory (or virtual memory) if you want + * to process big images. + * Note that the max_memory_to_use option is ignored by this implementation. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * Here we always say, "we got all you want bud!" + */ + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return max_bytes_needed; +} + + +/* + * Backing store (temporary file) management. + * Since jpeg_mem_available always promised the moon, + * this should never be called and we can just error out. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. Here, there isn't any. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + return 0; /* just set max_memory_to_use to 0 */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/rosapps/lib/libjpeg/jmemsys.h b/rosapps/lib/libjpeg/jmemsys.h new file mode 100644 index 00000000000..6c3c6d348f2 --- /dev/null +++ b/rosapps/lib/libjpeg/jmemsys.h @@ -0,0 +1,198 @@ +/* + * jmemsys.h + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file defines the interface between the system-independent + * and system-dependent portions of the JPEG memory manager. No other + * modules need include it. (The system-independent portion is jmemmgr.c; + * there are several different versions of the system-dependent portion.) + * + * This file works as-is for the system-dependent memory managers supplied + * in the IJG distribution. You may need to modify it if you write a + * custom memory manager. If system-dependent changes are needed in + * this file, the best method is to #ifdef them based on a configuration + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR + * and USE_MAC_MEMMGR. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_get_small jGetSmall +#define jpeg_free_small jFreeSmall +#define jpeg_get_large jGetLarge +#define jpeg_free_large jFreeLarge +#define jpeg_mem_available jMemAvail +#define jpeg_open_backing_store jOpenBackStore +#define jpeg_mem_init jMemInit +#define jpeg_mem_term jMemTerm +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * These two functions are used to allocate and release small chunks of + * memory. (Typically the total amount requested through jpeg_get_small is + * no more than 20K or so; this will be requested in chunks of a few K each.) + * Behavior should be the same as for the standard library functions malloc + * and free; in particular, jpeg_get_small must return NULL on failure. + * On most systems, these ARE malloc and free. jpeg_free_small is passed the + * size of the object being freed, just in case it's needed. + * On an 80x86 machine using small-data memory model, these manage near heap. + */ + +EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); +EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, + size_t sizeofobject)); + +/* + * These two functions are used to allocate and release large chunks of + * memory (up to the total free space designated by jpeg_mem_available). + * The interface is the same as above, except that on an 80x86 machine, + * far pointers are used. On most other machines these are identical to + * the jpeg_get/free_small routines; but we keep them separate anyway, + * in case a different allocation strategy is desirable for large chunks. + */ + +EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo, + size_t sizeofobject)); +EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, + size_t sizeofobject)); + +/* + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that + * matter, but that case should never come into play). This macro is needed + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + * On those machines, we expect that jconfig.h will provide a proper value. + * On machines with 32-bit flat address spaces, any large constant may be used. + * + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + * size_t and will be a multiple of sizeof(align_type). + */ + +#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ +#define MAX_ALLOC_CHUNK 1000000000L +#endif + +/* + * This routine computes the total space still available for allocation by + * jpeg_get_large. If more space than this is needed, backing store will be + * used. NOTE: any memory already allocated must not be counted. + * + * There is a minimum space requirement, corresponding to the minimum + * feasible buffer sizes; jmemmgr.c will request that much space even if + * jpeg_mem_available returns zero. The maximum space needed, enough to hold + * all working storage in memory, is also passed in case it is useful. + * Finally, the total space already allocated is passed. If no better + * method is available, cinfo->mem->max_memory_to_use - already_allocated + * is often a suitable calculation. + * + * It is OK for jpeg_mem_available to underestimate the space available + * (that'll just lead to more backing-store access than is really necessary). + * However, an overestimate will lead to failure. Hence it's wise to subtract + * a slop factor from the true available space. 5% should be enough. + * + * On machines with lots of virtual memory, any large constant may be returned. + * Conversely, zero may be returned to always use the minimum amount of memory. + */ + +EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, + long min_bytes_needed, + long max_bytes_needed, + long already_allocated)); + + +/* + * This structure holds whatever state is needed to access a single + * backing-store object. The read/write/close method pointers are called + * by jmemmgr.c to manipulate the backing-store object; all other fields + * are private to the system-dependent backing store routines. + */ + +#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ + + +#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ + +typedef unsigned short XMSH; /* type of extended-memory handles */ +typedef unsigned short EMSH; /* type of expanded-memory handles */ + +typedef union { + short file_handle; /* DOS file handle if it's a temp file */ + XMSH xms_handle; /* handle if it's a chunk of XMS */ + EMSH ems_handle; /* handle if it's a chunk of EMS */ +} handle_union; + +#endif /* USE_MSDOS_MEMMGR */ + +#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ +#include +#endif /* USE_MAC_MEMMGR */ + + +typedef struct backing_store_struct * backing_store_ptr; + +typedef struct backing_store_struct { + /* Methods for reading/writing/closing this backing-store object */ + JMETHOD(void, read_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, write_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, close_backing_store, (j_common_ptr cinfo, + backing_store_ptr info)); + + /* Private fields for system-dependent backing-store management */ +#ifdef USE_MSDOS_MEMMGR + /* For the MS-DOS manager (jmemdos.c), we need: */ + handle_union handle; /* reference to backing-store storage object */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else +#ifdef USE_MAC_MEMMGR + /* For the Mac manager (jmemmac.c), we need: */ + short temp_file; /* file reference number to temp file */ + FSSpec tempSpec; /* the FSSpec for the temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else + /* For a typical implementation with temp files, we need: */ + FILE * temp_file; /* stdio reference to temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ +#endif +#endif +} backing_store_info; + + +/* + * Initial opening of a backing-store object. This must fill in the + * read/write/close pointers in the object. The read/write routines + * may take an error exit if the specified maximum file size is exceeded. + * (If jpeg_mem_available always returns a large value, this routine can + * just take an error exit.) + */ + +EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo, + backing_store_ptr info, + long total_bytes_needed)); + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. jpeg_mem_init will be called before anything is + * allocated (and, therefore, nothing in cinfo is of use except the error + * manager pointer). It should return a suitable default value for + * max_memory_to_use; this may subsequently be overridden by the surrounding + * application. (Note that max_memory_to_use is only important if + * jpeg_mem_available chooses to consult it ... no one else will.) + * jpeg_mem_term may assume that all requested memory has been freed and that + * all opened backing-store objects have been closed. + */ + +EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/rosapps/lib/libjpeg/jmorecfg.h b/rosapps/lib/libjpeg/jmorecfg.h new file mode 100644 index 00000000000..2c32cc66bf4 --- /dev/null +++ b/rosapps/lib/libjpeg/jmorecfg.h @@ -0,0 +1,384 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +#ifdef _MSC_VER +#pragma warning (disable : 4142) /* benign redefinition of type */ +#endif + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + +/* Defines for MMX/SSE2 support. */ +/* Disabled for AT&T and VC++ 6.0 */ +#if defined(_M_IX86) && !defined(__GNUC__) && !(defined(_MSC_VER) && (_MSC_VER<1300)) +#define HAVE_MMX_INTEL_MNEMONICS + +/* SSE2 code appears broken for some cpus (bug 247437) + my comment: I read the discussion about that bug and it was disabled + because one guy sent a bugreport - incorrectly decoded jpeg. + No one else seems to have this problem = probably a hardware problem. + (He had a P4 Celeron) + PS: This code comes from Mozilla/Firefox. -= BiShop =- +*/ +#define HAVE_SSE2_INTEL_MNEMONICS +#endif + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +/* typedef long INT32; */ +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#undef DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#undef IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#undef QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#undef QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#define int16 short + +#ifndef MULTIPLIER +#define MULTIPLIER int16 /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/rosapps/lib/libjpeg/jpegint.h b/rosapps/lib/libjpeg/jpegint.h new file mode 100644 index 00000000000..95b00d405ca --- /dev/null +++ b/rosapps/lib/libjpeg/jpegint.h @@ -0,0 +1,392 @@ +/* + * jpegint.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides common declarations for the various JPEG modules. + * These declarations are considered internal to the JPEG library; most + * applications using the library shouldn't need to include this file. + */ + + +/* Declarations for both compression & decompression */ + +typedef enum { /* Operating modes for buffer controllers */ + JBUF_PASS_THRU, /* Plain stripwise operation */ + /* Remaining modes require a full-image buffer to have been created */ + JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ + JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ + JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ +} J_BUF_MODE; + +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ +#define CSTATE_START 100 /* after create_compress */ +#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ +#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ +#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ +#define DSTATE_START 200 /* after create_decompress */ +#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ +#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ +#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ +#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ +#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ +#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ +#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ +#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ +#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ +#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ + + +/* Declarations for compression modules */ + +/* Master control module */ +struct jpeg_comp_master { + JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); + JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean call_pass_startup; /* True if pass_startup must be called */ + boolean is_last_pass; /* True during last pass */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_c_main_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail)); +}; + +/* Compression preprocessing (downsampling input buffer control) */ +struct jpeg_c_prep_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, + JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_c_coef_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf)); +}; + +/* Colorspace conversion */ +struct jpeg_color_converter { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, color_convert, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows)); +}; + +/* Downsampling */ +struct jpeg_downsampler { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, downsample, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, + JDIMENSION out_row_group_index)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Forward DCT (also controls coefficient quantization) */ +struct jpeg_forward_dct { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + /* perhaps this should be an array??? */ + JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, + jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks)); +}; + +/* Entropy encoding */ +struct jpeg_entropy_encoder { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); + JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); +}; + +/* Marker writing */ +struct jpeg_marker_writer { + JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); + JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); + /* These routines are exported to allow insertion of extra markers */ + /* Probably only COM and APPn markers should be written this way */ + JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, + unsigned int datalen)); + JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); +}; + + +/* Declarations for decompression modules */ + +/* Master control module */ +struct jpeg_decomp_master { + JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ +}; + +/* Input control module */ +struct jpeg_input_controller { + JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); + JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean has_multiple_scans; /* True if file has multiple scans */ + boolean eoi_reached; /* True when EOI has been consumed */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_d_main_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_d_coef_controller { + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); + JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, + JSAMPIMAGE output_buf)); + /* Pointer to array of coefficient virtual arrays, or NULL if none */ + jvirt_barray_ptr *coef_arrays; +}; + +/* Decompression postprocessing (color quantization buffer control) */ +struct jpeg_d_post_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Marker reading & parsing */ +struct jpeg_marker_reader { + JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); + /* Read markers until SOS or EOI. + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); + /* Read a restart marker --- exported for use by entropy decoder only */ + jpeg_marker_parser_method read_restart_marker; + + /* State of marker reader --- nominally internal, but applications + * supplying COM or APPn handlers might like to know the state. + */ + boolean saw_SOI; /* found SOI? */ + boolean saw_SOF; /* found SOF? */ + int next_restart_num; /* next restart number expected (0-7) */ + unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ +}; + +/* Entropy decoding */ +struct jpeg_entropy_decoder { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + /* This is here to share code between baseline and progressive decoders; */ + /* other modules probably should not use it */ + boolean insufficient_data; /* set TRUE after emitting warning */ +}; + +/* Inverse DCT (also performs dequantization) */ +typedef JMETHOD(void, inverse_DCT_method_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col)); + +struct jpeg_inverse_dct { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + /* It is useful to allow each component to have a separate IDCT method. */ + inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; +}; + +/* Upsampling (note that upsampler must also call color converter) */ +struct jpeg_upsampler { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, upsample, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Colorspace conversion */ +struct jpeg_color_deconverter { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, color_convert, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows)); +}; + +/* Color quantization or color precision reduction */ +struct jpeg_color_quantizer { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); + JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, + int num_rows)); + JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); +}; + + +/* Miscellaneous useful macros */ + +#undef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#undef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +/* We assume that right shift corresponds to signed division by 2 with + * rounding towards minus infinity. This is correct for typical "arithmetic + * shift" instructions that shift in copies of the sign bit. But some + * C compilers implement >> with an unsigned shift. For these machines you + * must define RIGHT_SHIFT_IS_UNSIGNED. + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. + * It is only applied with constant shift counts. SHIFT_TEMPS must be + * included in the variables of any routine using RIGHT_SHIFT. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define SHIFT_TEMPS INT32 shift_temp; +#define RIGHT_SHIFT(x,shft) \ + ((shift_temp = (x)) < 0 ? \ + (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ + (shift_temp >> (shft))) +#else +#define SHIFT_TEMPS +#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_compress_master jICompress +#define jinit_c_master_control jICMaster +#define jinit_c_main_controller jICMainC +#define jinit_c_prep_controller jICPrepC +#define jinit_c_coef_controller jICCoefC +#define jinit_color_converter jICColor +#define jinit_downsampler jIDownsampler +#define jinit_forward_dct jIFDCT +#define jinit_huff_encoder jIHEncoder +#define jinit_phuff_encoder jIPHEncoder +#define jinit_marker_writer jIMWriter +#define jinit_master_decompress jIDMaster +#define jinit_d_main_controller jIDMainC +#define jinit_d_coef_controller jIDCoefC +#define jinit_d_post_controller jIDPostC +#define jinit_input_controller jIInCtlr +#define jinit_marker_reader jIMReader +#define jinit_huff_decoder jIHDecoder +#define jinit_phuff_decoder jIPHDecoder +#define jinit_inverse_dct jIIDCT +#define jinit_upsampler jIUpsampler +#define jinit_color_deconverter jIDColor +#define jinit_1pass_quantizer jI1Quant +#define jinit_2pass_quantizer jI2Quant +#define jinit_merged_upsampler jIMUpsampler +#define jinit_memory_mgr jIMemMgr +#define jdiv_round_up jDivRound +#define jround_up jRound +#define jcopy_sample_rows jCopySamples +#define jcopy_block_row jCopyBlocks +#define jzero_far jZeroFar +#define jpeg_zigzag_order jZIGTable +#define jpeg_natural_order jZAGTable +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Compression module initialization routines */ +EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, + boolean transcode_only)); +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); +/* Decompression module initialization routines */ +EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); +/* Memory manager initialization */ +EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); + +/* Utility routines in jutils.c */ +EXTERN(long) jdiv_round_up JPP((long a, long b)); +EXTERN(long) jround_up JPP((long a, long b)); +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols)); +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks)); +EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); +/* Constant tables in jutils.c */ +#if 0 /* This table is not actually needed in v6a */ +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +#endif +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ + +/* Suppress undefined-structure complaints if necessary. */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +#endif +#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/rosapps/lib/libjpeg/jpeglib.h b/rosapps/lib/libjpeg/jpeglib.h new file mode 100644 index 00000000000..9f57edfc29d --- /dev/null +++ b/rosapps/lib/libjpeg/jpeglib.h @@ -0,0 +1,1107 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +#include +#include + + + + /* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +#ifdef HAVE_MMX_INTEL_MNEMONICS + extern int MMXAvailable; +#endif + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct +{ + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + unsigned short quantval[64]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + unsigned char sent_table; /* TRUE when table has been output */ +}JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + unsigned char sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + unsigned char component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + unsigned char is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + unsigned char raw_data_in; /* TRUE=caller supplies downsampled data */ + unsigned char arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + unsigned char optimize_coding; /* TRUE=optimize entropy encoding parms */ + unsigned char CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + unsigned char write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + unsigned char write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + unsigned char progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + unsigned char buffered_image; /* TRUE=multiple output passes */ + unsigned char raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + unsigned char do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + unsigned char do_block_smoothing; /* TRUE=apply interblock smoothing */ + + unsigned char quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + unsigned char two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + unsigned char enable_1pass_quant; /* enable future use of 1-pass quantizer */ + unsigned char enable_external_quant;/* enable future use of external colormap */ + unsigned char enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + unsigned char progressive_mode; /* TRUE if SOFn specifies progressive mode */ + unsigned char arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + unsigned char saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + unsigned char saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + unsigned char CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(unsigned char, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(unsigned char, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(unsigned char, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + unsigned char pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + unsigned char pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + unsigned char writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + unsigned char writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(unsigned char, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + unsigned char force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + unsigned char force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + unsigned char force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + unsigned char suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + unsigned char write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + unsigned char require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(unsigned char) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(unsigned char) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(unsigned char) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(unsigned char) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(unsigned char) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(unsigned char) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(unsigned char) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/rosapps/lib/libjpeg/jpegtran.c b/rosapps/lib/libjpeg/jpegtran.c new file mode 100644 index 00000000000..44c061a84b3 --- /dev/null +++ b/rosapps/lib/libjpeg/jpegtran.c @@ -0,0 +1,546 @@ +/* + * jpegtran.c + * + * Copyright (C) 1995-2001, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a command-line user interface for JPEG transcoding. + * It is very similar to cjpeg.c, but provides lossless transcoding between + * different JPEG file formats. It also provides some lossless and sort-of- + * lossless transformations of JPEG data. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "transupp.h" /* Support routines for jpegtran */ +#include "jversion.h" /* for version message */ + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + + +/* + * Argument-parsing code. + * The switch parser is designed to be useful with DOS-style command line + * syntax, ie, intermixed switches and file names, where only the switches + * to the left of a given file name affect processing of that file. + * The main program in this file doesn't actually use this capability... + */ + + +static const char * progname; /* program name for error messages */ +static char * outfilename; /* for -outfile switch */ +static JCOPY_OPTION copyoption; /* -copy switch */ +static jpeg_transform_info transformoption; /* image transformation options */ + + +LOCAL(void) +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -copy none Copy no extra markers from source file\n"); + fprintf(stderr, " -copy comments Copy only comment markers (default)\n"); + fprintf(stderr, " -copy all Copy all extra markers\n"); +#ifdef ENTROPY_OPT_SUPPORTED + fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); +#endif +#ifdef C_PROGRESSIVE_SUPPORTED + fprintf(stderr, " -progressive Create progressive JPEG file\n"); +#endif +#if TRANSFORMS_SUPPORTED + fprintf(stderr, "Switches for modifying the image:\n"); + fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n"); + fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n"); + fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n"); + fprintf(stderr, " -perfect Fail if there is non-transformable edge blocks\n"); + fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n"); + fprintf(stderr, " -transpose Transpose image\n"); + fprintf(stderr, " -transverse Transverse transpose image\n"); + fprintf(stderr, " -trim Drop non-transformable edge blocks\n"); +#endif /* TRANSFORMS_SUPPORTED */ + fprintf(stderr, "Switches for advanced users:\n"); + fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); + fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); + fprintf(stderr, " -outfile name Specify name for output file\n"); + fprintf(stderr, " -verbose or -debug Emit debug output\n"); + fprintf(stderr, "Switches for wizards:\n"); +#ifdef C_ARITH_CODING_SUPPORTED + fprintf(stderr, " -arithmetic Use arithmetic coding\n"); +#endif +#ifdef C_MULTISCAN_FILES_SUPPORTED + fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); +#endif + exit(EXIT_FAILURE); +} + + +LOCAL(void) +select_transform (JXFORM_CODE transform) +/* Silly little routine to detect multiple transform options, + * which we can't handle. + */ +{ +#if TRANSFORMS_SUPPORTED + if (transformoption.transform == JXFORM_NONE || + transformoption.transform == transform) { + transformoption.transform = transform; + } else { + fprintf(stderr, "%s: can only do one image transformation at a time\n", + progname); + usage(); + } +#else + fprintf(stderr, "%s: sorry, image transformation was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif +} + + +LOCAL(int) +parse_switches (j_compress_ptr cinfo, int argc, char **argv, + int last_file_arg_seen, boolean for_real) +/* Parse optional switches. + * Returns argv[] index of first file-name argument (== argc if none). + * Any file names with indexes <= last_file_arg_seen are ignored; + * they have presumably been processed in a previous iteration. + * (Pass 0 for last_file_arg_seen on the first or only iteration.) + * for_real is FALSE on the first (dummy) pass; we may skip any expensive + * processing. + */ +{ + int argn; + char * arg; + boolean simple_progressive; + char * scansarg = NULL; /* saves -scans parm if any */ + + /* Set up default JPEG parameters. */ + simple_progressive = FALSE; + outfilename = NULL; + copyoption = JCOPYOPT_DEFAULT; + transformoption.transform = JXFORM_NONE; + transformoption.trim = FALSE; + transformoption.perfect = FALSE; + transformoption.force_grayscale = FALSE; + transformoption.crop = FALSE; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ + + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (*arg != '-') { + /* Not a switch, must be a file name argument */ + if (argn <= last_file_arg_seen) { + outfilename = NULL; /* -outfile applies to just one input file */ + continue; /* ignore this name if previously processed */ + } + break; /* else done parsing switches */ + } + arg++; /* advance past switch marker character */ + + if (keymatch(arg, "arithmetic", 1)) { + /* Use arithmetic coding. */ +#ifdef C_ARITH_CODING_SUPPORTED + cinfo->arith_code = TRUE; +#else + fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "copy", 2)) { + /* Select which extra markers to copy. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "none", 1)) { + copyoption = JCOPYOPT_NONE; + } else if (keymatch(argv[argn], "comments", 1)) { + copyoption = JCOPYOPT_COMMENTS; + } else if (keymatch(argv[argn], "all", 1)) { + copyoption = JCOPYOPT_ALL; + } else + usage(); + + } else if (keymatch(arg, "crop", 2)) { + /* Perform lossless cropping. */ +#if TRANSFORMS_SUPPORTED + if (++argn >= argc) /* advance to next argument */ + usage(); + if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) { + fprintf(stderr, "%s: bogus -crop argument '%s'\n", + progname, argv[argn]); + exit(EXIT_FAILURE); + } +#else + select_transform(JXFORM_NONE); /* force an error */ +#endif + + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ + static boolean printed_version = FALSE; + + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n", + JVERSION, JCOPYRIGHT); + printed_version = TRUE; + } + cinfo->err->trace_level++; + + } else if (keymatch(arg, "flip", 1)) { + /* Mirror left-right or top-bottom. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "horizontal", 1)) + select_transform(JXFORM_FLIP_H); + else if (keymatch(argv[argn], "vertical", 1)) + select_transform(JXFORM_FLIP_V); + else + usage(); + + } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) { + /* Force to grayscale. */ +#if TRANSFORMS_SUPPORTED + transformoption.force_grayscale = TRUE; +#else + select_transform(JXFORM_NONE); /* force an error */ +#endif + + } else if (keymatch(arg, "maxmemory", 3)) { + /* Maximum memory in Kb (or Mb with 'm'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (ch == 'm' || ch == 'M') + lval *= 1000L; + cinfo->mem->max_memory_to_use = lval * 1000L; + + } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { + /* Enable entropy parm optimization. */ +#ifdef ENTROPY_OPT_SUPPORTED + cinfo->optimize_coding = TRUE; +#else + fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "outfile", 4)) { + /* Set output file name. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + outfilename = argv[argn]; /* save it away for later use */ + + } else if (keymatch(arg, "perfect", 2)) { + /* Fail if there is any partial edge MCUs that the transform can't + * handle. */ + transformoption.perfect = TRUE; + + } else if (keymatch(arg, "progressive", 2)) { + /* Select simple progressive mode. */ +#ifdef C_PROGRESSIVE_SUPPORTED + simple_progressive = TRUE; + /* We must postpone execution until num_components is known. */ +#else + fprintf(stderr, "%s: sorry, progressive output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "restart", 1)) { + /* Restart interval in MCU rows (or in MCUs with 'b'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (lval < 0 || lval > 65535L) + usage(); + if (ch == 'b' || ch == 'B') { + cinfo->restart_interval = (unsigned int) lval; + cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ + } else { + cinfo->restart_in_rows = (int) lval; + /* restart_interval will be computed during startup */ + } + + } else if (keymatch(arg, "rotate", 2)) { + /* Rotate 90, 180, or 270 degrees (measured clockwise). */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "90", 2)) + select_transform(JXFORM_ROT_90); + else if (keymatch(argv[argn], "180", 3)) + select_transform(JXFORM_ROT_180); + else if (keymatch(argv[argn], "270", 3)) + select_transform(JXFORM_ROT_270); + else + usage(); + + } else if (keymatch(arg, "scans", 1)) { + /* Set scan script. */ +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (++argn >= argc) /* advance to next argument */ + usage(); + scansarg = argv[argn]; + /* We must postpone reading the file in case -progressive appears. */ +#else + fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "transpose", 1)) { + /* Transpose (across UL-to-LR axis). */ + select_transform(JXFORM_TRANSPOSE); + + } else if (keymatch(arg, "transverse", 6)) { + /* Transverse transpose (across UR-to-LL axis). */ + select_transform(JXFORM_TRANSVERSE); + + } else if (keymatch(arg, "trim", 3)) { + /* Trim off any partial edge MCUs that the transform can't handle. */ + transformoption.trim = TRUE; + + } else { + usage(); /* bogus switch */ + } + } + + /* Post-switch-scanning cleanup */ + + if (for_real) { + +#ifdef C_PROGRESSIVE_SUPPORTED + if (simple_progressive) /* process -progressive; -scans can override */ + jpeg_simple_progression(cinfo); +#endif + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (scansarg != NULL) /* process -scans if it was present */ + if (! read_scan_script(cinfo, scansarg)) + usage(); +#endif + } + + return argn; /* return index of next arg (file name) */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + struct jpeg_decompress_struct srcinfo; + struct jpeg_compress_struct dstinfo; + struct jpeg_error_mgr jsrcerr, jdsterr; +#ifdef PROGRESS_REPORT + struct cdjpeg_progress_mgr progress; +#endif + jvirt_barray_ptr * src_coef_arrays; + jvirt_barray_ptr * dst_coef_arrays; + int file_index; + /* We assume all-in-memory processing and can therefore use only a + * single file pointer for sequential input and output operation. + */ + FILE * fp; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "jpegtran"; /* in case C library doesn't provide it */ + + /* Initialize the JPEG decompression object with default error handling. */ + srcinfo.err = jpeg_std_error(&jsrcerr); + jpeg_create_decompress(&srcinfo); + /* Initialize the JPEG compression object with default error handling. */ + dstinfo.err = jpeg_std_error(&jdsterr); + jpeg_create_compress(&dstinfo); + + /* Now safe to enable signal catcher. + * Note: we assume only the decompression object will have virtual arrays. + */ +#ifdef NEED_SIGNAL_CATCHER + enable_signal_catcher((j_common_ptr) &srcinfo); +#endif + + /* Scan command line to find file names. + * It is convenient to use just one switch-parsing routine, but the switch + * values read here are mostly ignored; we will rescan the switches after + * opening the input file. Also note that most of the switches affect the + * destination JPEG object, so we parse into that and then copy over what + * needs to affects the source too. + */ + + file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE); + jsrcerr.trace_level = jdsterr.trace_level; + srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use; + +#ifdef TWO_FILE_COMMANDLINE + /* Must have either -outfile switch or explicit output file name */ + if (outfilename == NULL) { + if (file_index != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + outfilename = argv[file_index+1]; + } else { + if (file_index != argc-1) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + } +#else + /* Unix style: expect zero or one file name */ + if (file_index < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } +#endif /* TWO_FILE_COMMANDLINE */ + + /* Open the input file. */ + if (file_index < argc) { + if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s for reading\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ + fp = read_stdin(); + } + +#ifdef PROGRESS_REPORT + start_progress_monitor((j_common_ptr) &dstinfo, &progress); +#endif + + /* Specify data source for decompression */ + jpeg_stdio_src(&srcinfo, fp); + + /* Enable saving of extra markers that we want to copy */ + jcopy_markers_setup(&srcinfo, copyoption); + + /* Read file header */ + (void) jpeg_read_header(&srcinfo, TRUE); + + /* Any space needed by a transform option must be requested before + * jpeg_read_coefficients so that memory allocation will be done right. + */ +#if TRANSFORMS_SUPPORTED + /* Fails right away if -perfect is given and transformation is not perfect. + */ + if (transformoption.perfect && + !jtransform_perfect_transform(srcinfo.image_width, srcinfo.image_height, + srcinfo.max_h_samp_factor * DCTSIZE, srcinfo.max_v_samp_factor * DCTSIZE, + transformoption.transform)) { + fprintf(stderr, "%s: transformation is not perfect\n", progname); + exit(EXIT_FAILURE); + } + jtransform_request_workspace(&srcinfo, &transformoption); +#endif + + /* Read source file as DCT coefficients */ + src_coef_arrays = jpeg_read_coefficients(&srcinfo); + + /* Initialize destination compression parameters from source values */ + jpeg_copy_critical_parameters(&srcinfo, &dstinfo); + + /* Adjust destination parameters if required by transform options; + * also find out which set of coefficient arrays will hold the output. + */ +#if TRANSFORMS_SUPPORTED + dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo, + src_coef_arrays, + &transformoption); +#else + dst_coef_arrays = src_coef_arrays; +#endif + + /* Close input file, if we opened it. + * Note: we assume that jpeg_read_coefficients consumed all input + * until JPEG_REACHED_EOI, and that jpeg_finish_decompress will + * only consume more while (! cinfo->inputctl->eoi_reached). + * We cannot call jpeg_finish_decompress here since we still need the + * virtual arrays allocated from the source object for processing. + */ + if (fp != stdin) + fclose(fp); + + /* Open the output file. */ + if (outfilename != NULL) { + if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s for writing\n", progname, outfilename); + exit(EXIT_FAILURE); + } + } else { + /* default output file is stdout */ + fp = write_stdout(); + } + + /* Adjust default compression parameters by re-parsing the options */ + file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); + + /* Specify data destination for compression */ + jpeg_stdio_dest(&dstinfo, fp); + + /* Start compressor (note no image data is actually written here) */ + jpeg_write_coefficients(&dstinfo, dst_coef_arrays); + + /* Copy to the output file any extra markers that we want to preserve */ + jcopy_markers_execute(&srcinfo, &dstinfo, copyoption); + + /* Execute image transformation, if any */ +#if TRANSFORMS_SUPPORTED + jtransform_execute_transformation(&srcinfo, &dstinfo, + src_coef_arrays, + &transformoption); +#endif + + /* Finish compression and release memory */ + jpeg_finish_compress(&dstinfo); + jpeg_destroy_compress(&dstinfo); + (void) jpeg_finish_decompress(&srcinfo); + jpeg_destroy_decompress(&srcinfo); + + /* Close output file, if we opened it */ + if (fp != stdout) + fclose(fp); + +#ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &dstinfo); +#endif + + /* All done. */ + exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/rosapps/lib/libjpeg/jquant1.c b/rosapps/lib/libjpeg/jquant1.c new file mode 100644 index 00000000000..b2f96aa15d2 --- /dev/null +++ b/rosapps/lib/libjpeg/jquant1.c @@ -0,0 +1,856 @@ +/* + * jquant1.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 1-pass color quantization (color mapping) routines. + * These routines provide mapping to a fixed color map using equally spaced + * color values. Optional Floyd-Steinberg or ordered dithering is available. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_1PASS_SUPPORTED + + +/* + * The main purpose of 1-pass quantization is to provide a fast, if not very + * high quality, colormapped output capability. A 2-pass quantizer usually + * gives better visual quality; however, for quantized grayscale output this + * quantizer is perfectly adequate. Dithering is highly recommended with this + * quantizer, though you can turn it off if you really want to. + * + * In 1-pass quantization the colormap must be chosen in advance of seeing the + * image. We use a map consisting of all combinations of Ncolors[i] color + * values for the i'th component. The Ncolors[] values are chosen so that + * their product, the total number of colors, is no more than that requested. + * (In most cases, the product will be somewhat less.) + * + * Since the colormap is orthogonal, the representative value for each color + * component can be determined without considering the other components; + * then these indexes can be combined into a colormap index by a standard + * N-dimensional-array-subscript calculation. Most of the arithmetic involved + * can be precalculated and stored in the lookup table colorindex[]. + * colorindex[i][j] maps pixel value j in component i to the nearest + * representative value (grid plane) for that component; this index is + * multiplied by the array stride for component i, so that the + * index of the colormap entry closest to a given pixel value is just + * sum( colorindex[component-number][pixel-component-value] ) + * Aside from being fast, this scheme allows for variable spacing between + * representative values with no additional lookup cost. + * + * If gamma correction has been applied in color conversion, it might be wise + * to adjust the color grid spacing so that the representative colors are + * equidistant in linear space. At this writing, gamma correction is not + * implemented by jdcolor, so nothing is done here. + */ + + +/* Declarations for ordered dithering. + * + * We use a standard 16x16 ordered dither array. The basic concept of ordered + * dithering is described in many references, for instance Dale Schumacher's + * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). + * In place of Schumacher's comparisons against a "threshold" value, we add a + * "dither" value to the input pixel and then round the result to the nearest + * output value. The dither value is equivalent to (0.5 - threshold) times + * the distance between output values. For ordered dithering, we assume that + * the output colors are equally spaced; if not, results will probably be + * worse, since the dither may be too much or too little at a given point. + * + * The normal calculation would be to form pixel value + dither, range-limit + * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. + * We can skip the separate range-limiting step by extending the colorindex + * table in both directions. + */ + +#define ODITHER_SIZE 16 /* dimension of dither matrix */ +/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ +#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ +#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ + +typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; +typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; + +static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { + /* Bayer's order-4 dither array. Generated by the code given in + * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. + * The values in this array must range from 0 to ODITHER_CELLS-1. + */ + { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, + { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, + { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, + { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, + { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, + { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, + { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, + { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, + { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, + { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, + { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, + { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, + { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, + { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, + { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, + { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } +}; + + +/* Declarations for Floyd-Steinberg dithering. + * + * Errors are accumulated into the array fserrors[], at a resolution of + * 1/16th of a pixel count. The error at a given pixel is propagated + * to its not-yet-processed neighbors using the standard F-S fractions, + * ... (here) 7/16 + * 3/16 5/16 1/16 + * We work left-to-right on even rows, right-to-left on odd rows. + * + * We can get away with a single array (holding one row's worth of errors) + * by using it to store the current row's errors at pixel columns not yet + * processed, but the next row's errors at columns already processed. We + * need only a few extra variables to hold the errors immediately around the + * current column. (If we are lucky, those variables are in registers, but + * even if not, they're probably cheaper to access than array elements are.) + * + * The fserrors[] array is indexed [component#][position]. + * We provide (#columns + 2) entries per component; the extra entry at each + * end saves us from special-casing the first and last pixels. + * + * Note: on a wide image, we might not have enough room in a PC's near data + * segment to hold the error array; so it is allocated with alloc_large. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef INT16 FSERROR; /* 16 bits should be enough */ +typedef int LOCFSERROR; /* use 'int' for calculation temps */ +#else +typedef INT32 FSERROR; /* may need more than 16 bits */ +typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ +#endif + +typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ + + +/* Private subobject */ + +#define MAX_Q_COMPS 4 /* max components I can handle */ + +typedef struct { + struct jpeg_color_quantizer pub; /* public fields */ + + /* Initially allocated colormap is saved here */ + JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ + int sv_actual; /* number of entries in use */ + + JSAMPARRAY colorindex; /* Precomputed mapping for speed */ + /* colorindex[i][j] = index of color closest to pixel value j in component i, + * premultiplied as described above. Since colormap indexes must fit into + * JSAMPLEs, the entries of this array will too. + */ + boolean is_padded; /* is the colorindex padded for odither? */ + + int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ + + /* Variables for ordered dithering */ + int row_index; /* cur row's vertical index in dither matrix */ + ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ + + /* Variables for Floyd-Steinberg dithering */ + FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ + boolean on_odd_row; /* flag to remember which row we are on */ +} my_cquantizer; + +typedef my_cquantizer * my_cquantize_ptr; + + +/* + * Policy-making subroutines for create_colormap and create_colorindex. + * These routines determine the colormap to be used. The rest of the module + * only assumes that the colormap is orthogonal. + * + * * select_ncolors decides how to divvy up the available colors + * among the components. + * * output_value defines the set of representative values for a component. + * * largest_input_value defines the mapping from input values to + * representative values for a component. + * Note that the latter two routines may impose different policies for + * different components, though this is not currently done. + */ + + +LOCAL(int) +select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) +/* Determine allocation of desired colors to components, */ +/* and fill in Ncolors[] array to indicate choice. */ +/* Return value is total number of colors (product of Ncolors[] values). */ +{ + int nc = cinfo->out_color_components; /* number of color components */ + int max_colors = cinfo->desired_number_of_colors; + int total_colors, iroot, i, j; + boolean changed; + long temp; + static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; + + /* We can allocate at least the nc'th root of max_colors per component. */ + /* Compute floor(nc'th root of max_colors). */ + iroot = 1; + do { + iroot++; + temp = iroot; /* set temp = iroot ** nc */ + for (i = 1; i < nc; i++) + temp *= iroot; + } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ + iroot--; /* now iroot = floor(root) */ + + /* Must have at least 2 color values per component */ + if (iroot < 2) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); + + /* Initialize to iroot color values for each component */ + total_colors = 1; + for (i = 0; i < nc; i++) { + Ncolors[i] = iroot; + total_colors *= iroot; + } + /* We may be able to increment the count for one or more components without + * exceeding max_colors, though we know not all can be incremented. + * Sometimes, the first component can be incremented more than once! + * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) + * In RGB colorspace, try to increment G first, then R, then B. + */ + do { + changed = FALSE; + for (i = 0; i < nc; i++) { + j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); + /* calculate new total_colors if Ncolors[j] is incremented */ + temp = total_colors / Ncolors[j]; + temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ + if (temp > (long) max_colors) + break; /* won't fit, done with this pass */ + Ncolors[j]++; /* OK, apply the increment */ + total_colors = (int) temp; + changed = TRUE; + } + } while (changed); + + return total_colors; +} + + +LOCAL(int) +output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return j'th output value, where j will range from 0 to maxj */ +/* The output values must fall in 0..MAXJSAMPLE in increasing order */ +{ + /* We always provide values 0 and MAXJSAMPLE for each component; + * any additional values are equally spaced between these limits. + * (Forcing the upper and lower values to the limits ensures that + * dithering can't produce a color outside the selected gamut.) + */ + return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); +} + + +LOCAL(int) +largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return largest input value that should map to j'th output value */ +/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ +{ + /* Breakpoints are halfway between values returned by output_value */ + return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); +} + + +/* + * Create the colormap. + */ + +LOCAL(void) +create_colormap (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colormap; /* Created colormap */ + int total_colors; /* Number of distinct output colors */ + int i,j,k, nci, blksize, blkdist, ptr, val; + + /* Select number of colors for each component */ + total_colors = select_ncolors(cinfo, cquantize->Ncolors); + + /* Report selected color counts */ + if (cinfo->out_color_components == 3) + TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, + total_colors, cquantize->Ncolors[0], + cquantize->Ncolors[1], cquantize->Ncolors[2]); + else + TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); + + /* Allocate and fill in the colormap. */ + /* The colors are ordered in the map in standard row-major order, */ + /* i.e. rightmost (highest-indexed) color changes most rapidly. */ + + colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + /* blkdist is distance between groups of identical entries for a component */ + blkdist = total_colors; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colormap entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blkdist / nci; + for (j = 0; j < nci; j++) { + /* Compute j'th output value (out of nci) for component */ + val = output_value(cinfo, i, j, nci-1); + /* Fill in all colormap entries that have this value of this component */ + for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { + /* fill in blksize entries beginning at ptr */ + for (k = 0; k < blksize; k++) + colormap[i][ptr+k] = (JSAMPLE) val; + } + } + blkdist = blksize; /* blksize of this color is blkdist of next */ + } + + /* Save the colormap in private storage, + * where it will survive color quantization mode changes. + */ + cquantize->sv_colormap = colormap; + cquantize->sv_actual = total_colors; +} + + +/* + * Create the color index table. + */ + +LOCAL(void) +create_colorindex (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPROW indexptr; + int i,j,k, nci, blksize, val, pad; + + /* For ordered dither, we pad the color index tables by MAXJSAMPLE in + * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). + * This is not necessary in the other dithering modes. However, we + * flag whether it was done in case user changes dithering mode. + */ + if (cinfo->dither_mode == JDITHER_ORDERED) { + pad = MAXJSAMPLE*2; + cquantize->is_padded = TRUE; + } else { + pad = 0; + cquantize->is_padded = FALSE; + } + + cquantize->colorindex = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (MAXJSAMPLE+1 + pad), + (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + blksize = cquantize->sv_actual; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colorindex entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blksize / nci; + + /* adjust colorindex pointers to provide padding at negative indexes. */ + if (pad) + cquantize->colorindex[i] += MAXJSAMPLE; + + /* in loop, val = index of current output value, */ + /* and k = largest j that maps to current val */ + indexptr = cquantize->colorindex[i]; + val = 0; + k = largest_input_value(cinfo, i, 0, nci-1); + for (j = 0; j <= MAXJSAMPLE; j++) { + while (j > k) /* advance val if past boundary */ + k = largest_input_value(cinfo, i, ++val, nci-1); + /* premultiply so that no multiplication needed in main processing */ + indexptr[j] = (JSAMPLE) (val * blksize); + } + /* Pad at both ends if necessary */ + if (pad) + for (j = 1; j <= MAXJSAMPLE; j++) { + indexptr[-j] = indexptr[0]; + indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; + } + } +} + + +/* + * Create an ordered-dither array for a component having ncolors + * distinct output values. + */ + +LOCAL(ODITHER_MATRIX_PTR) +make_odither_array (j_decompress_ptr cinfo, int ncolors) +{ + ODITHER_MATRIX_PTR odither; + int j,k; + INT32 num,den; + + odither = (ODITHER_MATRIX_PTR) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ODITHER_MATRIX)); + /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). + * Hence the dither value for the matrix cell with fill order f + * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). + * On 16-bit-int machine, be careful to avoid overflow. + */ + den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); + for (j = 0; j < ODITHER_SIZE; j++) { + for (k = 0; k < ODITHER_SIZE; k++) { + num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) + * MAXJSAMPLE; + /* Ensure round towards zero despite C's lack of consistency + * about rounding negative values in integer division... + */ + odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); + } + } + return odither; +} + + +/* + * Create the ordered-dither tables. + * Components having the same number of representative colors may + * share a dither table. + */ + +LOCAL(void) +create_odither_tables (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + ODITHER_MATRIX_PTR odither; + int i, j, nci; + + for (i = 0; i < cinfo->out_color_components; i++) { + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + odither = NULL; /* search for matching prior component */ + for (j = 0; j < i; j++) { + if (nci == cquantize->Ncolors[j]) { + odither = cquantize->odither[j]; + break; + } + } + if (odither == NULL) /* need a new table? */ + odither = make_odither_array(cinfo, nci); + cquantize->odither[i] = odither; + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF(void) +color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colorindex = cquantize->colorindex; + register int pixcode, ci; + register JSAMPROW ptrin, ptrout; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + register int nc = cinfo->out_color_components; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = 0; + for (ci = 0; ci < nc; ci++) { + pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); + } + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF(void) +color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW ptrin, ptrout; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF(void) +quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + int * dither; /* points to active row of dither matrix */ + int row_index, col_index; /* current indexes into dither matrix */ + int nc = cinfo->out_color_components; + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + row_index = cquantize->row_index; + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + colorindex_ci = cquantize->colorindex[ci]; + dither = cquantize->odither[ci][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, + * select output value, accumulate into output code for this pixel. + * Range-limiting need not be done explicitly, as we have extended + * the colorindex table to produce the right answers for out-of-range + * inputs. The maximum dither is +- MAXJSAMPLE; this sets the + * required amount of padding. + */ + *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; + input_ptr += nc; + output_ptr++; + col_index = (col_index + 1) & ODITHER_MASK; + } + } + /* Advance row index for next row */ + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF(void) +quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int * dither0; /* points to active row of dither matrix */ + int * dither1; + int * dither2; + int row_index, col_index; /* current indexes into dither matrix */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + row_index = cquantize->row_index; + input_ptr = input_buf[row]; + output_ptr = output_buf[row]; + dither0 = cquantize->odither[0][row_index]; + dither1 = cquantize->odither[1][row_index]; + dither2 = cquantize->odither[2][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + + dither0[col_index]]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + + dither1[col_index]]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + + dither2[col_index]]); + *output_ptr++ = (JSAMPLE) pixcode; + col_index = (col_index + 1) & ODITHER_MASK; + } + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF(void) +quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register LOCFSERROR cur; /* current error or pixel value */ + LOCFSERROR belowerr; /* error for pixel below cur */ + LOCFSERROR bpreverr; /* error for below/prev col */ + LOCFSERROR bnexterr; /* error for below/next col */ + LOCFSERROR delta; + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + JSAMPROW colormap_ci; + int pixcode; + int nc = cinfo->out_color_components; + int dir; /* 1 for left-to-right, -1 for right-to-left */ + int dirnc; /* dir * nc */ + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + input_ptr += (width-1) * nc; /* so point to rightmost pixel */ + output_ptr += width-1; + dir = -1; + dirnc = -nc; + errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ + } else { + /* work left to right in this row */ + dir = 1; + dirnc = nc; + errorptr = cquantize->fserrors[ci]; /* => entry before first column */ + } + colorindex_ci = cquantize->colorindex[ci]; + colormap_ci = cquantize->sv_colormap[ci]; + /* Preset error values: no error propagated to first pixel from left */ + cur = 0; + /* and no error propagated to row below yet */ + belowerr = bpreverr = 0; + + for (col = width; col > 0; col--) { + /* cur holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE; this sets the required size + * of the range_limit array. + */ + cur += GETJSAMPLE(*input_ptr); + cur = GETJSAMPLE(range_limit[cur]); + /* Select output value, accumulate into output code for this pixel */ + pixcode = GETJSAMPLE(colorindex_ci[cur]); + *output_ptr += (JSAMPLE) pixcode; + /* Compute actual representation error at this pixel */ + /* Note: we can do this even though we don't have the final */ + /* pixel code, because the colormap is orthogonal. */ + cur -= GETJSAMPLE(colormap_ci[pixcode]); + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + bnexterr = cur; + delta = cur * 2; + cur += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr + cur); + cur += delta; /* form error * 5 */ + bpreverr = belowerr + cur; + belowerr = bnexterr; + cur += delta; /* form error * 7 */ + /* At this point cur contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + input_ptr += dirnc; /* advance input ptr to next column */ + output_ptr += dir; /* advance output ptr to next column */ + errorptr += dir; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error value into the + * final fserrors[] entry. Note we need not unload belowerr because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ + } + cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); + } +} + + +/* + * Allocate workspace for Floyd-Steinberg errors. + */ + +LOCAL(void) +alloc_fs_workspace (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) { + cquantize->fserrors[i] = (FSERRPTR) + (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + } +} + + +/* + * Initialize for one-pass color quantization. + */ + +METHODDEF(void) +start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + /* Install my colormap. */ + cinfo->colormap = cquantize->sv_colormap; + cinfo->actual_number_of_colors = cquantize->sv_actual; + + /* Initialize for desired dithering mode. */ + switch (cinfo->dither_mode) { + case JDITHER_NONE: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = color_quantize3; + else + cquantize->pub.color_quantize = color_quantize; + break; + case JDITHER_ORDERED: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = quantize3_ord_dither; + else + cquantize->pub.color_quantize = quantize_ord_dither; + cquantize->row_index = 0; /* initialize state for ordered dither */ + /* If user changed to ordered dither from another mode, + * we must recreate the color index table with padding. + * This will cost extra space, but probably isn't very likely. + */ + if (! cquantize->is_padded) + create_colorindex(cinfo); + /* Create ordered-dither tables if we didn't already. */ + if (cquantize->odither[0] == NULL) + create_odither_tables(cinfo); + break; + case JDITHER_FS: + cquantize->pub.color_quantize = quantize_fs_dither; + cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ + /* Allocate Floyd-Steinberg workspace if didn't already. */ + if (cquantize->fserrors[0] == NULL) + alloc_fs_workspace(cinfo); + /* Initialize the propagated errors to zero. */ + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) + jzero_far((void FAR *) cquantize->fserrors[i], arraysize); + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } +} + + +/* + * Finish up at the end of the pass. + */ + +METHODDEF(void) +finish_pass_1_quant (j_decompress_ptr cinfo) +{ + /* no work in 1-pass case */ +} + + +/* + * Switch to a new external colormap between output passes. + * Shouldn't get to this module! + */ + +METHODDEF(void) +new_color_map_1_quant (j_decompress_ptr cinfo) +{ + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + + +/* + * Module initialization routine for 1-pass color quantization. + */ + +GLOBAL(void) +jinit_1pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_1_quant; + cquantize->pub.finish_pass = finish_pass_1_quant; + cquantize->pub.new_color_map = new_color_map_1_quant; + cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ + cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ + + /* Make sure my internal arrays won't overflow */ + if (cinfo->out_color_components > MAX_Q_COMPS) + ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); + + /* Create the colormap and color index table. */ + create_colormap(cinfo); + create_colorindex(cinfo); + + /* Allocate Floyd-Steinberg workspace now if requested. + * We do this now since it is FAR storage and may affect the memory + * manager's space calculations. If the user changes to FS dither + * mode in a later pass, we will allocate the space then, and will + * possibly overrun the max_memory_to_use setting. + */ + if (cinfo->dither_mode == JDITHER_FS) + alloc_fs_workspace(cinfo); +} + +#endif /* QUANT_1PASS_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jquant2.c b/rosapps/lib/libjpeg/jquant2.c new file mode 100644 index 00000000000..af601e334b2 --- /dev/null +++ b/rosapps/lib/libjpeg/jquant2.c @@ -0,0 +1,1310 @@ +/* + * jquant2.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 2-pass color quantization (color mapping) routines. + * These routines provide selection of a custom color map for an image, + * followed by mapping of the image to that color map, with optional + * Floyd-Steinberg dithering. + * It is also possible to use just the second pass to map to an arbitrary + * externally-given color map. + * + * Note: ordered dithering is not supported, since there isn't any fast + * way to compute intercolor distances; it's unclear that ordered dither's + * fundamental assumptions even hold with an irregularly spaced color map. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_2PASS_SUPPORTED + + +/* + * This module implements the well-known Heckbert paradigm for color + * quantization. Most of the ideas used here can be traced back to + * Heckbert's seminal paper + * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", + * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. + * + * In the first pass over the image, we accumulate a histogram showing the + * usage count of each possible color. To keep the histogram to a reasonable + * size, we reduce the precision of the input; typical practice is to retain + * 5 or 6 bits per color, so that 8 or 4 different input values are counted + * in the same histogram cell. + * + * Next, the color-selection step begins with a box representing the whole + * color space, and repeatedly splits the "largest" remaining box until we + * have as many boxes as desired colors. Then the mean color in each + * remaining box becomes one of the possible output colors. + * + * The second pass over the image maps each input pixel to the closest output + * color (optionally after applying a Floyd-Steinberg dithering correction). + * This mapping is logically trivial, but making it go fast enough requires + * considerable care. + * + * Heckbert-style quantizers vary a good deal in their policies for choosing + * the "largest" box and deciding where to cut it. The particular policies + * used here have proved out well in experimental comparisons, but better ones + * may yet be found. + * + * In earlier versions of the IJG code, this module quantized in YCbCr color + * space, processing the raw upsampled data without a color conversion step. + * This allowed the color conversion math to be done only once per colormap + * entry, not once per pixel. However, that optimization precluded other + * useful optimizations (such as merging color conversion with upsampling) + * and it also interfered with desired capabilities such as quantizing to an + * externally-supplied colormap. We have therefore abandoned that approach. + * The present code works in the post-conversion color space, typically RGB. + * + * To improve the visual quality of the results, we actually work in scaled + * RGB space, giving G distances more weight than R, and R in turn more than + * B. To do everything in integer math, we must use integer scale factors. + * The 2/3/1 scale factors used here correspond loosely to the relative + * weights of the colors in the NTSC grayscale equation. + * If you want to use this code to quantize a non-RGB color space, you'll + * probably need to change these scale factors. + */ + +#define R_SCALE 2 /* scale R distances by this much */ +#define G_SCALE 3 /* scale G distances by this much */ +#define B_SCALE 1 /* and B by this much */ + +/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined + * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B + * and B,G,R orders. If you define some other weird order in jmorecfg.h, + * you'll get compile errors until you extend this logic. In that case + * you'll probably want to tweak the histogram sizes too. + */ + +#if RGB_RED == 0 +#define C0_SCALE R_SCALE +#endif +#if RGB_BLUE == 0 +#define C0_SCALE B_SCALE +#endif +#if RGB_GREEN == 1 +#define C1_SCALE G_SCALE +#endif +#if RGB_RED == 2 +#define C2_SCALE R_SCALE +#endif +#if RGB_BLUE == 2 +#define C2_SCALE B_SCALE +#endif + + +/* + * First we have the histogram data structure and routines for creating it. + * + * The number of bits of precision can be adjusted by changing these symbols. + * We recommend keeping 6 bits for G and 5 each for R and B. + * If you have plenty of memory and cycles, 6 bits all around gives marginally + * better results; if you are short of memory, 5 bits all around will save + * some space but degrade the results. + * To maintain a fully accurate histogram, we'd need to allocate a "long" + * (preferably unsigned long) for each cell. In practice this is overkill; + * we can get by with 16 bits per cell. Few of the cell counts will overflow, + * and clamping those that do overflow to the maximum value will give close- + * enough results. This reduces the recommended histogram size from 256Kb + * to 128Kb, which is a useful savings on PC-class machines. + * (In the second pass the histogram space is re-used for pixel mapping data; + * in that capacity, each cell must be able to store zero to the number of + * desired colors. 16 bits/cell is plenty for that too.) + * Since the JPEG code is intended to run in small memory model on 80x86 + * machines, we can't just allocate the histogram in one chunk. Instead + * of a true 3-D array, we use a row of pointers to 2-D arrays. Each + * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and + * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that + * on 80x86 machines, the pointer row is in near memory but the actual + * arrays are in far memory (same arrangement as we use for image arrays). + */ + +#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ + +/* These will do the right thing for either R,G,B or B,G,R color order, + * but you may not like the results for other color orders. + */ +#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ +#define HIST_C1_BITS 6 /* bits of precision in G histogram */ +#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ + +/* Number of elements along histogram axes. */ +#define HIST_C0_ELEMS (1<cquantize; + register JSAMPROW ptr; + register histptr histp; + register hist3d histogram = cquantize->histogram; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptr = input_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the histogram */ + histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] + [GETJSAMPLE(ptr[1]) >> C1_SHIFT] + [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; + /* increment, check for overflow and undo increment if so. */ + if (++(*histp) <= 0) + (*histp)--; + ptr += 3; + } + } +} + + +/* + * Next we have the really interesting routines: selection of a colormap + * given the completed histogram. + * These routines work with a list of "boxes", each representing a rectangular + * subset of the input color space (to histogram precision). + */ + +typedef struct { + /* The bounds of the box (inclusive); expressed as histogram indexes */ + int c0min, c0max; + int c1min, c1max; + int c2min, c2max; + /* The volume (actually 2-norm) of the box */ + INT32 volume; + /* The number of nonzero histogram cells within this box */ + long colorcount; +} box; + +typedef box * boxptr; + + +LOCAL(boxptr) +find_biggest_color_pop (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest color population */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register long maxc = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->colorcount > maxc && boxp->volume > 0) { + which = boxp; + maxc = boxp->colorcount; + } + } + return which; +} + + +LOCAL(boxptr) +find_biggest_volume (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest (scaled) volume */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register INT32 maxv = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->volume > maxv) { + which = boxp; + maxv = boxp->volume; + } + } + return which; +} + + +LOCAL(void) +update_box (j_decompress_ptr cinfo, boxptr boxp) +/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ +/* and recompute its volume and population */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + INT32 dist0,dist1,dist2; + long ccount; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + if (c0max > c0min) + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0min = c0min = c0; + goto have_c0min; + } + } + have_c0min: + if (c0max > c0min) + for (c0 = c0max; c0 >= c0min; c0--) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0max = c0max = c0; + goto have_c0max; + } + } + have_c0max: + if (c1max > c1min) + for (c1 = c1min; c1 <= c1max; c1++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1min = c1min = c1; + goto have_c1min; + } + } + have_c1min: + if (c1max > c1min) + for (c1 = c1max; c1 >= c1min; c1--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1max = c1max = c1; + goto have_c1max; + } + } + have_c1max: + if (c2max > c2min) + for (c2 = c2min; c2 <= c2max; c2++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2min = c2min = c2; + goto have_c2min; + } + } + have_c2min: + if (c2max > c2min) + for (c2 = c2max; c2 >= c2min; c2--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2max = c2max = c2; + goto have_c2max; + } + } + have_c2max: + + /* Update box volume. + * We use 2-norm rather than real volume here; this biases the method + * against making long narrow boxes, and it has the side benefit that + * a box is splittable iff norm > 0. + * Since the differences are expressed in histogram-cell units, + * we have to shift back to JSAMPLE units to get consistent distances; + * after which, we scale according to the selected distance scale factors. + */ + dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; + dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; + dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; + boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2; + + /* Now scan remaining volume of box and compute population */ + ccount = 0; + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++, histp++) + if (*histp != 0) { + ccount++; + } + } + boxp->colorcount = ccount; +} + + +LOCAL(int) +median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, + int desired_colors) +/* Repeatedly select and split the largest box until we have enough boxes */ +{ + int n,lb; + int c0,c1,c2,cmax; + register boxptr b1,b2; + + while (numboxes < desired_colors) { + /* Select box to split. + * Current algorithm: by population for first half, then by volume. + */ + if (numboxes*2 <= desired_colors) { + b1 = find_biggest_color_pop(boxlist, numboxes); + } else { + b1 = find_biggest_volume(boxlist, numboxes); + } + if (b1 == NULL) /* no splittable boxes left! */ + break; + b2 = &boxlist[numboxes]; /* where new box will go */ + /* Copy the color bounds to the new box. */ + b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; + b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; + /* Choose which axis to split the box on. + * Current algorithm: longest scaled axis. + * See notes in update_box about scaling distances. + */ + c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; + c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; + c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; + /* We want to break any ties in favor of green, then red, blue last. + * This code does the right thing for R,G,B or B,G,R color orders only. + */ +#if RGB_RED == 0 + cmax = c1; n = 1; + if (c0 > cmax) { cmax = c0; n = 0; } + if (c2 > cmax) { n = 2; } +#else + cmax = c1; n = 1; + if (c2 > cmax) { cmax = c2; n = 2; } + if (c0 > cmax) { n = 0; } +#endif + /* Choose split point along selected axis, and update box bounds. + * Current algorithm: split at halfway point. + * (Since the box has been shrunk to minimum volume, + * any split will produce two nonempty subboxes.) + * Note that lb value is max for lower box, so must be < old max. + */ + switch (n) { + case 0: + lb = (b1->c0max + b1->c0min) / 2; + b1->c0max = lb; + b2->c0min = lb+1; + break; + case 1: + lb = (b1->c1max + b1->c1min) / 2; + b1->c1max = lb; + b2->c1min = lb+1; + break; + case 2: + lb = (b1->c2max + b1->c2min) / 2; + b1->c2max = lb; + b2->c2min = lb+1; + break; + } + /* Update stats for boxes */ + update_box(cinfo, b1); + update_box(cinfo, b2); + numboxes++; + } + return numboxes; +} + + +LOCAL(void) +compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) +/* Compute representative color for a box, put it in colormap[icolor] */ +{ + /* Current algorithm: mean weighted by pixels (not colors) */ + /* Note it is important to get the rounding correct! */ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + long count; + long total = 0; + long c0total = 0; + long c1total = 0; + long c2total = 0; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) { + if ((count = *histp++) != 0) { + total += count; + c0total += ((c0 << C0_SHIFT) + ((1<>1)) * count; + c1total += ((c1 << C1_SHIFT) + ((1<>1)) * count; + c2total += ((c2 << C2_SHIFT) + ((1<>1)) * count; + } + } + } + + cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total); + cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total); + cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total); +} + + +LOCAL(void) +select_colors (j_decompress_ptr cinfo, int desired_colors) +/* Master routine for color selection */ +{ + boxptr boxlist; + int numboxes; + int i; + + /* Allocate workspace for box list */ + boxlist = (boxptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box)); + /* Initialize one box containing whole space */ + numboxes = 1; + boxlist[0].c0min = 0; + boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; + boxlist[0].c1min = 0; + boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; + boxlist[0].c2min = 0; + boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; + /* Shrink it to actually-used volume and set its statistics */ + update_box(cinfo, & boxlist[0]); + /* Perform median-cut to produce final box list */ + numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); + /* Compute the representative color for each box, fill colormap */ + for (i = 0; i < numboxes; i++) + compute_color(cinfo, & boxlist[i], i); + cinfo->actual_number_of_colors = numboxes; + TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); +} + + +/* + * These routines are concerned with the time-critical task of mapping input + * colors to the nearest color in the selected colormap. + * + * We re-use the histogram space as an "inverse color map", essentially a + * cache for the results of nearest-color searches. All colors within a + * histogram cell will be mapped to the same colormap entry, namely the one + * closest to the cell's center. This may not be quite the closest entry to + * the actual input color, but it's almost as good. A zero in the cache + * indicates we haven't found the nearest color for that cell yet; the array + * is cleared to zeroes before starting the mapping pass. When we find the + * nearest color for a cell, its colormap index plus one is recorded in the + * cache for future use. The pass2 scanning routines call fill_inverse_cmap + * when they need to use an unfilled entry in the cache. + * + * Our method of efficiently finding nearest colors is based on the "locally + * sorted search" idea described by Heckbert and on the incremental distance + * calculation described by Spencer W. Thomas in chapter III.1 of Graphics + * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that + * the distances from a given colormap entry to each cell of the histogram can + * be computed quickly using an incremental method: the differences between + * distances to adjacent cells themselves differ by a constant. This allows a + * fairly fast implementation of the "brute force" approach of computing the + * distance from every colormap entry to every histogram cell. Unfortunately, + * it needs a work array to hold the best-distance-so-far for each histogram + * cell (because the inner loop has to be over cells, not colormap entries). + * The work array elements have to be INT32s, so the work array would need + * 256Kb at our recommended precision. This is not feasible in DOS machines. + * + * To get around these problems, we apply Thomas' method to compute the + * nearest colors for only the cells within a small subbox of the histogram. + * The work array need be only as big as the subbox, so the memory usage + * problem is solved. Furthermore, we need not fill subboxes that are never + * referenced in pass2; many images use only part of the color gamut, so a + * fair amount of work is saved. An additional advantage of this + * approach is that we can apply Heckbert's locality criterion to quickly + * eliminate colormap entries that are far away from the subbox; typically + * three-fourths of the colormap entries are rejected by Heckbert's criterion, + * and we need not compute their distances to individual cells in the subbox. + * The speed of this approach is heavily influenced by the subbox size: too + * small means too much overhead, too big loses because Heckbert's criterion + * can't eliminate as many colormap entries. Empirically the best subbox + * size seems to be about 1/512th of the histogram (1/8th in each direction). + * + * Thomas' article also describes a refined method which is asymptotically + * faster than the brute-force method, but it is also far more complex and + * cannot efficiently be applied to small subboxes. It is therefore not + * useful for programs intended to be portable to DOS machines. On machines + * with plenty of memory, filling the whole histogram in one shot with Thomas' + * refined method might be faster than the present code --- but then again, + * it might not be any faster, and it's certainly more complicated. + */ + + +/* log2(histogram cells in update box) for each axis; this can be adjusted */ +#define BOX_C0_LOG (HIST_C0_BITS-3) +#define BOX_C1_LOG (HIST_C1_BITS-3) +#define BOX_C2_LOG (HIST_C2_BITS-3) + +#define BOX_C0_ELEMS (1<actual_number_of_colors; + int maxc0, maxc1, maxc2; + int centerc0, centerc1, centerc2; + int i, x, ncolors; + INT32 minmaxdist, min_dist, max_dist, tdist; + INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ + + /* Compute true coordinates of update box's upper corner and center. + * Actually we compute the coordinates of the center of the upper-corner + * histogram cell, which are the upper bounds of the volume we care about. + * Note that since ">>" rounds down, the "center" values may be closer to + * min than to max; hence comparisons to them must be "<=", not "<". + */ + maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); + centerc0 = (minc0 + maxc0) >> 1; + maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); + centerc1 = (minc1 + maxc1) >> 1; + maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); + centerc2 = (minc2 + maxc2) >> 1; + + /* For each color in colormap, find: + * 1. its minimum squared-distance to any point in the update box + * (zero if color is within update box); + * 2. its maximum squared-distance to any point in the update box. + * Both of these can be found by considering only the corners of the box. + * We save the minimum distance for each color in mindist[]; + * only the smallest maximum distance is of interest. + */ + minmaxdist = 0x7FFFFFFFL; + + for (i = 0; i < numcolors; i++) { + /* We compute the squared-c0-distance term, then add in the other two. */ + x = GETJSAMPLE(cinfo->colormap[0][i]); + if (x < minc0) { + tdist = (x - minc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else if (x > maxc0) { + tdist = (x - maxc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + min_dist = 0; + if (x <= centerc0) { + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[1][i]); + if (x < minc1) { + tdist = (x - minc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc1) { + tdist = (x - maxc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc1) { + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[2][i]); + if (x < minc2) { + tdist = (x - minc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc2) { + tdist = (x - maxc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc2) { + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } + } + + mindist[i] = min_dist; /* save away the results */ + if (max_dist < minmaxdist) + minmaxdist = max_dist; + } + + /* Now we know that no cell in the update box is more than minmaxdist + * away from some colormap entry. Therefore, only colors that are + * within minmaxdist of some part of the box need be considered. + */ + ncolors = 0; + for (i = 0; i < numcolors; i++) { + if (mindist[i] <= minmaxdist) + colorlist[ncolors++] = (JSAMPLE) i; + } + return ncolors; +} + + +LOCAL(void) +find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, + int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) +/* Find the closest colormap entry for each cell in the update box, + * given the list of candidate colors prepared by find_nearby_colors. + * Return the indexes of the closest entries in the bestcolor[] array. + * This routine uses Thomas' incremental distance calculation method to + * find the distance from a colormap entry to successive cells in the box. + */ +{ + int ic0, ic1, ic2; + int i, icolor; + register INT32 * bptr; /* pointer into bestdist[] array */ + JSAMPLE * cptr; /* pointer into bestcolor[] array */ + INT32 dist0, dist1; /* initial distance values */ + register INT32 dist2; /* current distance in inner loop */ + INT32 xx0, xx1; /* distance increments */ + register INT32 xx2; + INT32 inc0, inc1, inc2; /* initial values for increments */ + /* This array holds the distance to the nearest-so-far color for each cell */ + INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Initialize best-distance for each cell of the update box */ + bptr = bestdist; + for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--) + *bptr++ = 0x7FFFFFFFL; + + /* For each color selected by find_nearby_colors, + * compute its distance to the center of each cell in the box. + * If that's less than best-so-far, update best distance and color number. + */ + + /* Nominal steps between cell centers ("x" in Thomas article) */ +#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) +#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) +#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) + + for (i = 0; i < numcolors; i++) { + icolor = GETJSAMPLE(colorlist[i]); + /* Compute (square of) distance from minc0/c1/c2 to this color */ + inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; + dist0 = inc0*inc0; + inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; + dist0 += inc1*inc1; + inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; + dist0 += inc2*inc2; + /* Form the initial difference increments */ + inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; + inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; + inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; + /* Now loop over all cells in box, updating distance per Thomas method */ + bptr = bestdist; + cptr = bestcolor; + xx0 = inc0; + for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) { + dist1 = dist0; + xx1 = inc1; + for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) { + dist2 = dist1; + xx2 = inc2; + for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) { + if (dist2 < *bptr) { + *bptr = dist2; + *cptr = (JSAMPLE) icolor; + } + dist2 += xx2; + xx2 += 2 * STEP_C2 * STEP_C2; + bptr++; + cptr++; + } + dist1 += xx1; + xx1 += 2 * STEP_C1 * STEP_C1; + } + dist0 += xx0; + xx0 += 2 * STEP_C0 * STEP_C0; + } + } +} + + +LOCAL(void) +fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) +/* Fill the inverse-colormap entries in the update box that contains */ +/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ +/* we can fill as many others as we wish.) */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int minc0, minc1, minc2; /* lower left corner of update box */ + int ic0, ic1, ic2; + register JSAMPLE * cptr; /* pointer into bestcolor[] array */ + register histptr cachep; /* pointer into main cache array */ + /* This array lists the candidate colormap indexes. */ + JSAMPLE colorlist[MAXNUMCOLORS]; + int numcolors; /* number of candidate colors */ + /* This array holds the actually closest colormap index for each cell. */ + JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Convert cell coordinates to update box ID */ + c0 >>= BOX_C0_LOG; + c1 >>= BOX_C1_LOG; + c2 >>= BOX_C2_LOG; + + /* Compute true coordinates of update box's origin corner. + * Actually we compute the coordinates of the center of the corner + * histogram cell, which are the lower bounds of the volume we care about. + */ + minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); + minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); + minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); + + /* Determine which colormap entries are close enough to be candidates + * for the nearest entry to some cell in the update box. + */ + numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); + + /* Determine the actually nearest colors. */ + find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, + bestcolor); + + /* Save the best color numbers (plus 1) in the main cache array */ + c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ + c1 <<= BOX_C1_LOG; + c2 <<= BOX_C2_LOG; + cptr = bestcolor; + for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { + for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { + cachep = & histogram[c0+ic0][c1+ic1][c2]; + for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { + *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1); + } + } + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF(void) +pass2_no_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register JSAMPROW inptr, outptr; + register histptr cachep; + register int c0, c1, c2; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the cache */ + c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; + c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; + c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; + cachep = & histogram[c0][c1][c2]; + /* If we have not seen this color before, find nearest colormap entry */ + /* and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, c0,c1,c2); + /* Now emit the colormap index for this cell */ + *outptr++ = (JSAMPLE) (*cachep - 1); + } + } +} + + +METHODDEF(void) +pass2_fs_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ + LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ + LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + JSAMPROW inptr; /* => current input pixel */ + JSAMPROW outptr; /* => current output pixel */ + histptr cachep; + int dir; /* +1 or -1 depending on direction */ + int dir3; /* 3*dir, for advancing inptr & errorptr */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + int *error_limit = cquantize->error_limiter; + JSAMPROW colormap0 = cinfo->colormap[0]; + JSAMPROW colormap1 = cinfo->colormap[1]; + JSAMPROW colormap2 = cinfo->colormap[2]; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + inptr += (width-1) * 3; /* so point to rightmost pixel */ + outptr += width-1; + dir = -1; + dir3 = -3; + errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */ + cquantize->on_odd_row = FALSE; /* flip for next time */ + } else { + /* work left to right in this row */ + dir = 1; + dir3 = 3; + errorptr = cquantize->fserrors; /* => entry before first real column */ + cquantize->on_odd_row = TRUE; /* flip for next time */ + } + /* Preset error values: no error propagated to first pixel from left */ + cur0 = cur1 = cur2 = 0; + /* and no error propagated to row below yet */ + belowerr0 = belowerr1 = belowerr2 = 0; + bpreverr0 = bpreverr1 = bpreverr2 = 0; + + for (col = width; col > 0; col--) { + /* curN holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4); + cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4); + cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4); + /* Limit the error using transfer function set by init_error_limit. + * See comments with init_error_limit for rationale. + */ + cur0 = error_limit[cur0]; + cur1 = error_limit[cur1]; + cur2 = error_limit[cur2]; + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE (or less with error limiting); + * this sets the required size of the range_limit array. + */ + cur0 += GETJSAMPLE(inptr[0]); + cur1 += GETJSAMPLE(inptr[1]); + cur2 += GETJSAMPLE(inptr[2]); + cur0 = GETJSAMPLE(range_limit[cur0]); + cur1 = GETJSAMPLE(range_limit[cur1]); + cur2 = GETJSAMPLE(range_limit[cur2]); + /* Index into the cache with adjusted pixel value */ + cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT]; + /* If we have not seen this color before, find nearest colormap */ + /* entry and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); + /* Now emit the colormap index for this cell */ + { register int pixcode = *cachep - 1; + *outptr = (JSAMPLE) pixcode; + /* Compute representation error for this pixel */ + cur0 -= GETJSAMPLE(colormap0[pixcode]); + cur1 -= GETJSAMPLE(colormap1[pixcode]); + cur2 -= GETJSAMPLE(colormap2[pixcode]); + } + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + { register LOCFSERROR bnexterr, delta; + + bnexterr = cur0; /* Process component 0 */ + delta = cur0 * 2; + cur0 += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr0 + cur0); + cur0 += delta; /* form error * 5 */ + bpreverr0 = belowerr0 + cur0; + belowerr0 = bnexterr; + cur0 += delta; /* form error * 7 */ + bnexterr = cur1; /* Process component 1 */ + delta = cur1 * 2; + cur1 += delta; /* form error * 3 */ + errorptr[1] = (FSERROR) (bpreverr1 + cur1); + cur1 += delta; /* form error * 5 */ + bpreverr1 = belowerr1 + cur1; + belowerr1 = bnexterr; + cur1 += delta; /* form error * 7 */ + bnexterr = cur2; /* Process component 2 */ + delta = cur2 * 2; + cur2 += delta; /* form error * 3 */ + errorptr[2] = (FSERROR) (bpreverr2 + cur2); + cur2 += delta; /* form error * 5 */ + bpreverr2 = belowerr2 + cur2; + belowerr2 = bnexterr; + cur2 += delta; /* form error * 7 */ + } + /* At this point curN contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + inptr += dir3; /* Advance pixel pointers to next column */ + outptr += dir; + errorptr += dir3; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error values into the + * final fserrors[] entry. Note we need not unload belowerrN because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ + errorptr[1] = (FSERROR) bpreverr1; + errorptr[2] = (FSERROR) bpreverr2; + } +} + + +/* + * Initialize the error-limiting transfer function (lookup table). + * The raw F-S error computation can potentially compute error values of up to + * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be + * much less, otherwise obviously wrong pixels will be created. (Typical + * effects include weird fringes at color-area boundaries, isolated bright + * pixels in a dark area, etc.) The standard advice for avoiding this problem + * is to ensure that the "corners" of the color cube are allocated as output + * colors; then repeated errors in the same direction cannot cause cascading + * error buildup. However, that only prevents the error from getting + * completely out of hand; Aaron Giles reports that error limiting improves + * the results even with corner colors allocated. + * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty + * well, but the smoother transfer function used below is even better. Thanks + * to Aaron Giles for this idea. + */ + +LOCAL(void) +init_error_limit (j_decompress_ptr cinfo) +/* Allocate and fill in the error_limiter table */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + int * table; + int in, out; + + table = (int *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int)); + table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ + cquantize->error_limiter = table; + +#define STEPSIZE ((MAXJSAMPLE+1)/16) + /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ + out = 0; + for (in = 0; in < STEPSIZE; in++, out++) { + table[in] = out; table[-in] = -out; + } + /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ + for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) { + table[in] = out; table[-in] = -out; + } + /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ + for (; in <= MAXJSAMPLE; in++) { + table[in] = out; table[-in] = -out; + } +#undef STEPSIZE +} + + +/* + * Finish up at the end of each pass. + */ + +METHODDEF(void) +finish_pass1 (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Select the representative colors and fill in cinfo->colormap */ + cinfo->colormap = cquantize->sv_colormap; + select_colors(cinfo, cquantize->desired); + /* Force next pass to zero the color index table */ + cquantize->needs_zeroed = TRUE; +} + + +METHODDEF(void) +finish_pass2 (j_decompress_ptr cinfo) +{ + /* no work */ +} + + +/* + * Initialize for each processing pass. + */ + +METHODDEF(void) +start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int i; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + if (is_pre_scan) { + /* Set up method pointers */ + cquantize->pub.color_quantize = prescan_quantize; + cquantize->pub.finish_pass = finish_pass1; + cquantize->needs_zeroed = TRUE; /* Always zero histogram */ + } else { + /* Set up method pointers */ + if (cinfo->dither_mode == JDITHER_FS) + cquantize->pub.color_quantize = pass2_fs_dither; + else + cquantize->pub.color_quantize = pass2_no_dither; + cquantize->pub.finish_pass = finish_pass2; + + /* Make sure color count is acceptable */ + i = cinfo->actual_number_of_colors; + if (i < 1) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); + if (i > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + + if (cinfo->dither_mode == JDITHER_FS) { + size_t arraysize = (size_t) ((cinfo->output_width + 2) * + (3 * SIZEOF(FSERROR))); + /* Allocate Floyd-Steinberg workspace if we didn't already. */ + if (cquantize->fserrors == NULL) + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + /* Initialize the propagated errors to zero. */ + jzero_far((void FAR *) cquantize->fserrors, arraysize); + /* Make the error-limit table if we didn't already. */ + if (cquantize->error_limiter == NULL) + init_error_limit(cinfo); + cquantize->on_odd_row = FALSE; + } + + } + /* Zero the histogram or inverse color map, if necessary */ + if (cquantize->needs_zeroed) { + for (i = 0; i < HIST_C0_ELEMS; i++) { + jzero_far((void FAR *) histogram[i], + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = FALSE; + } +} + + +/* + * Switch to a new external colormap between output passes. + */ + +METHODDEF(void) +new_color_map_2_quant (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Reset the inverse color map */ + cquantize->needs_zeroed = TRUE; +} + + +/* + * Module initialization routine for 2-pass color quantization. + */ + +GLOBAL(void) +jinit_2pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + int i; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_2_quant; + cquantize->pub.new_color_map = new_color_map_2_quant; + cquantize->fserrors = NULL; /* flag optional arrays not allocated */ + cquantize->error_limiter = NULL; + + /* Make sure jdmaster didn't give me a case I can't handle */ + if (cinfo->out_color_components != 3) + ERREXIT(cinfo, JERR_NOTIMPL); + + /* Allocate the histogram/inverse colormap storage */ + cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d)); + for (i = 0; i < HIST_C0_ELEMS; i++) { + cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ + + /* Allocate storage for the completed colormap, if required. + * We do this now since it is FAR storage and may affect + * the memory manager's space calculations. + */ + if (cinfo->enable_2pass_quant) { + /* Make sure color count is acceptable */ + int desired = cinfo->desired_number_of_colors; + /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ + if (desired < 8) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (desired > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); + cquantize->desired = desired; + } else + cquantize->sv_colormap = NULL; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + /* Allocate Floyd-Steinberg workspace if necessary. + * This isn't really needed until pass 2, but again it is FAR storage. + * Although we will cope with a later change in dither_mode, + * we do not promise to honor max_memory_to_use if dither_mode changes. + */ + if (cinfo->dither_mode == JDITHER_FS) { + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); + /* Might as well create the error-limiting table too. */ + init_error_limit(cinfo); + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/jutils.c b/rosapps/lib/libjpeg/jutils.c new file mode 100644 index 00000000000..d18a9555621 --- /dev/null +++ b/rosapps/lib/libjpeg/jutils.c @@ -0,0 +1,179 @@ +/* + * jutils.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains tables and miscellaneous utility routines needed + * for both compression and decompression. + * Note we prefix all global names with "j" to minimize conflicts with + * a surrounding application. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element + * of a DCT block read in natural order (left to right, top to bottom). + */ + +#if 0 /* This table is not actually needed in v6a */ + +const int jpeg_zigzag_order[DCTSIZE2] = { + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63 +}; + +#endif + +/* + * jpeg_natural_order[i] is the natural-order position of the i'th element + * of zigzag order. + * + * When reading corrupted data, the Huffman decoders could attempt + * to reference an entry beyond the end of this array (if the decoded + * zero run length reaches past the end of the block). To prevent + * wild stores without adding an inner-loop test, we put some extra + * "63"s after the real entries. This will cause the extra coefficient + * to be stored in location 63 of the block, not somewhere random. + * The worst case would be a run-length of 15, which means we need 16 + * fake entries. + */ + +const int jpeg_natural_order[DCTSIZE2+16] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 +}; + + +/* + * Arithmetic utilities + */ + +GLOBAL(long) +jdiv_round_up (long a, long b) +/* Compute a/b rounded up to next integer, ie, ceil(a/b) */ +/* Assumes a >= 0, b > 0 */ +{ + return (a + b - 1L) / b; +} + + +GLOBAL(long) +jround_up (long a, long b) +/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */ +/* Assumes a >= 0, b > 0 */ +{ + a += b - 1L; + return a - (a % b); +} + + +/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays + * and coefficient-block arrays. This won't work on 80x86 because the arrays + * are FAR and we're assuming a small-pointer memory model. However, some + * DOS compilers provide far-pointer versions of memcpy() and memset() even + * in the small-model libraries. These will be used if USE_FMEM is defined. + * Otherwise, the routines below do it the hard way. (The performance cost + * is not all that great, because these routines aren't very heavily used.) + */ + +#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ +#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) +#define FMEMZERO(target,size) MEMZERO(target,size) +#else /* 80x86 case, define if we can */ +#ifdef USE_FMEM +#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) +#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) +#endif +#endif + + +GLOBAL(void) +jcopy_sample_rows (JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols) +/* Copy some rows of samples from one place to another. + * num_rows rows are copied from input_array[source_row++] + * to output_array[dest_row++]; these areas may overlap for duplication. + * The source and destination arrays must be at least as wide as num_cols. + */ +{ + register JSAMPROW inptr, outptr; +#ifdef FMEMCOPY + register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); +#else + register JDIMENSION count; +#endif + register int row; + + input_array += source_row; + output_array += dest_row; + + for (row = num_rows; row > 0; row--) { + inptr = *input_array++; + outptr = *output_array++; +#ifdef FMEMCOPY + FMEMCOPY(outptr, inptr, count); +#else + for (count = num_cols; count > 0; count--) + *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ +#endif + } +} + + +GLOBAL(void) +jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks) +/* Copy a row of coefficient blocks from one place to another. */ +{ +#ifdef FMEMCOPY + FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); +#else + register JCOEFPTR inptr, outptr; + register long count; + + inptr = (JCOEFPTR) input_row; + outptr = (JCOEFPTR) output_row; + for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) { + *outptr++ = *inptr++; + } +#endif +} + + +GLOBAL(void) +jzero_far (void FAR * target, size_t bytestozero) +/* Zero out a chunk of FAR memory. */ +/* This might be sample-array data, block-array data, or alloc_large data. */ +{ +#ifdef FMEMZERO + FMEMZERO(target, bytestozero); +#else + register char FAR * ptr = (char FAR *) target; + register size_t count; + + for (count = bytestozero; count > 0; count--) { + *ptr++ = 0; + } +#endif +} diff --git a/rosapps/lib/libjpeg/jversion.h b/rosapps/lib/libjpeg/jversion.h new file mode 100644 index 00000000000..6472c58d351 --- /dev/null +++ b/rosapps/lib/libjpeg/jversion.h @@ -0,0 +1,14 @@ +/* + * jversion.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains software version identification. + */ + + +#define JVERSION "6b 27-Mar-1998" + +#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" diff --git a/rosapps/lib/libjpeg/libjpeg.rbuild b/rosapps/lib/libjpeg/libjpeg.rbuild new file mode 100644 index 00000000000..8de4f40bcf9 --- /dev/null +++ b/rosapps/lib/libjpeg/libjpeg.rbuild @@ -0,0 +1,62 @@ + + + + 0x600 + 0x501 + + + + + + + + + . + jcapimin.c + jcapistd.c + jccoefct.c + jccolor.c + jcdctmgr.c + jchuff.c + jcinit.c + jcmainct.c + jcmarker.c + jcmaster.c + jcomapi.c + jcparam.c + jcphuff.c + jcprepct.c + jcsample.c + jctrans.c + jdapimin.c + jdapistd.c + jdatadst.c + jdatasrc.c + jdcoefct.c + jdcolor.c + jddctmgr.c + jdhuff.c + jdinput.c + jdmainct.c + jdmarker.c + jdmaster.c + jdmerge.c + jdphuff.c + jdpostct.c + jdsample.c + jdtrans.c + jerror.c + jfdctflt.c + jfdctfst.c + jfdctint.c + jidctflt.c + jidctfst.c + jidctint.c + jidctred.c + jmemmgr.c + jmemnobs.c + jquant1.c + jquant2.c + jutils.c + transupp.c + \ No newline at end of file diff --git a/rosapps/lib/libjpeg/rdbmp.c b/rosapps/lib/libjpeg/rdbmp.c new file mode 100644 index 00000000000..b05fe2ac47c --- /dev/null +++ b/rosapps/lib/libjpeg/rdbmp.c @@ -0,0 +1,439 @@ +/* + * rdbmp.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in Microsoft "BMP" + * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors). + * Currently, only 8-bit and 24-bit images are supported, not 1-bit or + * 4-bit (feeding such low-depth images into JPEG would be silly anyway). + * Also, we don't support RLE-compressed files. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed BMP format). + * + * This code contributed by James Arthur Boucher. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef BMP_SUPPORTED + + +/* Macros to deal with unsigned chars as efficiently as compiler allows */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char U_CHAR; +#define UCH(x) ((int) (x)) +#else /* !HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char U_CHAR; +#define UCH(x) ((int) (x)) +#else +typedef char U_CHAR; +#define UCH(x) ((int) (x) & 0xFF) +#endif +#endif /* HAVE_UNSIGNED_CHAR */ + + +#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) + + +/* Private version of data source object */ + +typedef struct _bmp_source_struct * bmp_source_ptr; + +typedef struct _bmp_source_struct { + struct cjpeg_source_struct pub; /* public fields */ + + j_compress_ptr cinfo; /* back link saves passing separate parm */ + + JSAMPARRAY colormap; /* BMP colormap (converted to my format) */ + + jvirt_sarray_ptr whole_image; /* Needed to reverse row order */ + JDIMENSION source_row; /* Current source row number */ + JDIMENSION row_width; /* Physical width of scanlines in file */ + + int bits_per_pixel; /* remembers 8- or 24-bit format */ +} bmp_source_struct; + + +LOCAL(int) +read_byte (bmp_source_ptr sinfo) +/* Read next byte from BMP file */ +{ + register FILE *infile = sinfo->pub.input_file; + register int c; + + if ((c = getc(infile)) == EOF) + ERREXIT(sinfo->cinfo, JERR_INPUT_EOF); + return c; +} + + +LOCAL(void) +read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize) +/* Read the colormap from a BMP file */ +{ + int i; + + switch (mapentrysize) { + case 3: + /* BGR format (occurs in OS/2 files) */ + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + } + break; + case 4: + /* BGR0 format (occurs in MS Windows files) */ + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + (void) read_byte(sinfo); + } + break; + default: + ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP); + break; + } +} + + +/* + * Read one row of pixels. + * The image has been read into the whole_image array, but is otherwise + * unprocessed. We must read it out in top-to-bottom row order, and if + * it is an 8-bit image, we must expand colormapped pixels to 24bit format. + */ + +METHODDEF(JDIMENSION) +get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 8-bit colormap indexes */ +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + register JSAMPARRAY colormap = source->colormap; + JSAMPARRAY image_ptr; + register int t; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + + /* Expand the colormap indexes to real data */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + t = GETJSAMPLE(*inptr++); + *outptr++ = colormap[0][t]; /* can omit GETJSAMPLE() safely */ + *outptr++ = colormap[1][t]; + *outptr++ = colormap[2][t]; + } + + return 1; +} + + +METHODDEF(JDIMENSION) +get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 24-bit pixels */ +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + + /* Transfer data. Note source values are in BGR order + * (even though Microsoft's own documents say the opposite). + */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ + outptr[1] = *inptr++; + outptr[0] = *inptr++; + outptr += 3; + } + + return 1; +} + + +/* + * This method loads the image into whole_image during the first call on + * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call + * get_8bit_row or get_24bit_row on subsequent calls. + */ + +METHODDEF(JDIMENSION) +preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + register FILE *infile = source->pub.input_file; + register int c; + register JSAMPROW out_ptr; + JSAMPARRAY image_ptr; + JDIMENSION row, col; + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + + /* Read the data into a virtual array in input-file row order. */ + for (row = 0; row < cinfo->image_height; row++) { + if (progress != NULL) { + progress->pub.pass_counter = (long) row; + progress->pub.pass_limit = (long) cinfo->image_height; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + row, (JDIMENSION) 1, TRUE); + out_ptr = image_ptr[0]; + for (col = source->row_width; col > 0; col--) { + /* inline copy of read_byte() for speed */ + if ((c = getc(infile)) == EOF) + ERREXIT(cinfo, JERR_INPUT_EOF); + *out_ptr++ = (JSAMPLE) c; + } + } + if (progress != NULL) + progress->completed_extra_passes++; + + /* Set up to read from the virtual array in top-to-bottom order */ + switch (source->bits_per_pixel) { + case 8: + source->pub.get_pixel_rows = get_8bit_row; + break; + case 24: + source->pub.get_pixel_rows = get_24bit_row; + break; + default: + ERREXIT(cinfo, JERR_BMP_BADDEPTH); + } + source->source_row = cinfo->image_height; + + /* And read the first row */ + return (*source->pub.get_pixel_rows) (cinfo, sinfo); +} + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + U_CHAR bmpfileheader[14]; + U_CHAR bmpinfoheader[64]; +#define GET_2B(array,offset) ((unsigned int) UCH(array[offset]) + \ + (((unsigned int) UCH(array[offset+1])) << 8)) +#define GET_4B(array,offset) ((INT32) UCH(array[offset]) + \ + (((INT32) UCH(array[offset+1])) << 8) + \ + (((INT32) UCH(array[offset+2])) << 16) + \ + (((INT32) UCH(array[offset+3])) << 24)) + INT32 bfOffBits; + INT32 headerSize; + INT32 biWidth = 0; /* initialize to avoid compiler warning */ + INT32 biHeight = 0; + unsigned int biPlanes; + INT32 biCompression; + INT32 biXPelsPerMeter,biYPelsPerMeter; + INT32 biClrUsed = 0; + int mapentrysize = 0; /* 0 indicates no colormap */ + INT32 bPad; + JDIMENSION row_width; + + /* Read and verify the bitmap file header */ + if (! ReadOK(source->pub.input_file, bmpfileheader, 14)) + ERREXIT(cinfo, JERR_INPUT_EOF); + if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */ + ERREXIT(cinfo, JERR_BMP_NOT); + bfOffBits = (INT32) GET_4B(bmpfileheader,10); + /* We ignore the remaining fileheader fields */ + + /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows), + * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which. + */ + if (! ReadOK(source->pub.input_file, bmpinfoheader, 4)) + ERREXIT(cinfo, JERR_INPUT_EOF); + headerSize = (INT32) GET_4B(bmpinfoheader,0); + if (headerSize < 12 || headerSize > 64) + ERREXIT(cinfo, JERR_BMP_BADHEADER); + if (! ReadOK(source->pub.input_file, bmpinfoheader+4, headerSize-4)) + ERREXIT(cinfo, JERR_INPUT_EOF); + + switch ((int) headerSize) { + case 12: + /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */ + biWidth = (INT32) GET_2B(bmpinfoheader,4); + biHeight = (INT32) GET_2B(bmpinfoheader,6); + biPlanes = GET_2B(bmpinfoheader,8); + source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10); + + switch (source->bits_per_pixel) { + case 8: /* colormapped image */ + mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */ + TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, (int) biWidth, (int) biHeight); + break; + case 24: /* RGB image */ + TRACEMS2(cinfo, 1, JTRC_BMP_OS2, (int) biWidth, (int) biHeight); + break; + default: + ERREXIT(cinfo, JERR_BMP_BADDEPTH); + break; + } + if (biPlanes != 1) + ERREXIT(cinfo, JERR_BMP_BADPLANES); + break; + case 40: + case 64: + /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */ + /* or OS/2 2.x header, which has additional fields that we ignore */ + biWidth = GET_4B(bmpinfoheader,4); + biHeight = GET_4B(bmpinfoheader,8); + biPlanes = GET_2B(bmpinfoheader,12); + source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14); + biCompression = GET_4B(bmpinfoheader,16); + biXPelsPerMeter = GET_4B(bmpinfoheader,24); + biYPelsPerMeter = GET_4B(bmpinfoheader,28); + biClrUsed = GET_4B(bmpinfoheader,32); + /* biSizeImage, biClrImportant fields are ignored */ + + switch (source->bits_per_pixel) { + case 8: /* colormapped image */ + mapentrysize = 4; /* Windows uses RGBQUAD colormap */ + TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, (int) biWidth, (int) biHeight); + break; + case 24: /* RGB image */ + TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); + break; + default: + ERREXIT(cinfo, JERR_BMP_BADDEPTH); + break; + } + if (biPlanes != 1) + ERREXIT(cinfo, JERR_BMP_BADPLANES); + if (biCompression != 0) + ERREXIT(cinfo, JERR_BMP_COMPRESSED); + + if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) { + /* Set JFIF density parameters from the BMP data */ + cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */ + cinfo->Y_density = (UINT16) (biYPelsPerMeter/100); + cinfo->density_unit = 2; /* dots/cm */ + } + break; + default: + ERREXIT(cinfo, JERR_BMP_BADHEADER); + break; + } + + /* Compute distance to bitmap data --- will adjust for colormap below */ + bPad = bfOffBits - (headerSize + 14); + + /* Read the colormap, if any */ + if (mapentrysize > 0) { + if (biClrUsed <= 0) + biClrUsed = 256; /* assume it's 256 */ + else if (biClrUsed > 256) + ERREXIT(cinfo, JERR_BMP_BADCMAP); + /* Allocate space to store the colormap */ + source->colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) biClrUsed, (JDIMENSION) 3); + /* and read it from the file */ + read_colormap(source, (int) biClrUsed, mapentrysize); + /* account for size of colormap */ + bPad -= biClrUsed * mapentrysize; + } + + /* Skip any remaining pad bytes */ + if (bPad < 0) /* incorrect bfOffBits value? */ + ERREXIT(cinfo, JERR_BMP_BADHEADER); + while (--bPad >= 0) { + (void) read_byte(source); + } + + /* Compute row width in file, including padding to 4-byte boundary */ + if (source->bits_per_pixel == 24) + row_width = (JDIMENSION) (biWidth * 3); + else + row_width = (JDIMENSION) biWidth; + while ((row_width & 3) != 0) row_width++; + source->row_width = row_width; + + /* Allocate space for inversion array, prepare for preload pass */ + source->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + row_width, (JDIMENSION) biHeight, (JDIMENSION) 1); + source->pub.get_pixel_rows = preload_image; + if (cinfo->progress != NULL) { + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + progress->total_extra_passes++; /* count file input as separate pass */ + } + + /* Allocate one-row buffer for returned data */ + source->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (biWidth * 3), (JDIMENSION) 1); + source->pub.buffer_height = 1; + + cinfo->in_color_space = JCS_RGB; + cinfo->input_components = 3; + cinfo->data_precision = 8; + cinfo->image_width = (JDIMENSION) biWidth; + cinfo->image_height = (JDIMENSION) biHeight; +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for BMP format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_bmp (j_compress_ptr cinfo) +{ + bmp_source_ptr source; + + /* Create module interface object */ + source = (bmp_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(bmp_source_struct)); + source->cinfo = cinfo; /* make back link for subroutines */ + /* Fill in method ptrs, except get_pixel_rows which start_input sets */ + source->pub.start_input = start_input_bmp; + source->pub.finish_input = finish_input_bmp; + + return (cjpeg_source_ptr) source; +} + +#endif /* BMP_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/rdcolmap.c b/rosapps/lib/libjpeg/rdcolmap.c new file mode 100644 index 00000000000..42b343763b5 --- /dev/null +++ b/rosapps/lib/libjpeg/rdcolmap.c @@ -0,0 +1,253 @@ +/* + * rdcolmap.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file implements djpeg's "-map file" switch. It reads a source image + * and constructs a colormap to be supplied to the JPEG decompressor. + * + * Currently, these file formats are supported for the map file: + * GIF: the contents of the GIF's global colormap are used. + * PPM (either text or raw flavor): the entire file is read and + * each unique pixel value is entered in the map. + * Note that reading a large PPM file will be horrendously slow. + * Typically, a PPM-format map file should contain just one pixel + * of each desired color. Such a file can be extracted from an + * ordinary image PPM file with ppmtomap(1). + * + * Rescaling a PPM that has a maxval unequal to MAXJSAMPLE is not + * currently implemented. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ + +/* Portions of this code are based on the PBMPLUS library, which is: +** +** Copyright (C) 1988 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + + +/* + * Add a (potentially) new color to the color map. + */ + +LOCAL(void) +add_map_entry (j_decompress_ptr cinfo, int R, int G, int B) +{ + JSAMPROW colormap0 = cinfo->colormap[0]; + JSAMPROW colormap1 = cinfo->colormap[1]; + JSAMPROW colormap2 = cinfo->colormap[2]; + int ncolors = cinfo->actual_number_of_colors; + int index; + + /* Check for duplicate color. */ + for (index = 0; index < ncolors; index++) { + if (GETJSAMPLE(colormap0[index]) == R && + GETJSAMPLE(colormap1[index]) == G && + GETJSAMPLE(colormap2[index]) == B) + return; /* color is already in map */ + } + + /* Check for map overflow. */ + if (ncolors >= (MAXJSAMPLE+1)) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, (MAXJSAMPLE+1)); + + /* OK, add color to map. */ + colormap0[ncolors] = (JSAMPLE) R; + colormap1[ncolors] = (JSAMPLE) G; + colormap2[ncolors] = (JSAMPLE) B; + cinfo->actual_number_of_colors++; +} + + +/* + * Extract color map from a GIF file. + */ + +LOCAL(void) +read_gif_map (j_decompress_ptr cinfo, FILE * infile) +{ + int header[13]; + int i, colormaplen; + int R, G, B; + + /* Initial 'G' has already been read by read_color_map */ + /* Read the rest of the GIF header and logical screen descriptor */ + for (i = 1; i < 13; i++) { + if ((header[i] = getc(infile)) == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + } + + /* Verify GIF Header */ + if (header[1] != 'I' || header[2] != 'F') + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + /* There must be a global color map. */ + if ((header[10] & 0x80) == 0) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + /* OK, fetch it. */ + colormaplen = 2 << (header[10] & 0x07); + + for (i = 0; i < colormaplen; i++) { + R = getc(infile); + G = getc(infile); + B = getc(infile); + if (R == EOF || G == EOF || B == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + add_map_entry(cinfo, + R << (BITS_IN_JSAMPLE-8), + G << (BITS_IN_JSAMPLE-8), + B << (BITS_IN_JSAMPLE-8)); + } +} + + +/* Support routines for reading PPM */ + + +LOCAL(int) +pbm_getc (FILE * infile) +/* Read next char, skipping over any comments */ +/* A comment/newline sequence is returned as a newline */ +{ + register int ch; + + ch = getc(infile); + if (ch == '#') { + do { + ch = getc(infile); + } while (ch != '\n' && ch != EOF); + } + return ch; +} + + +LOCAL(unsigned int) +read_pbm_integer (j_decompress_ptr cinfo, FILE * infile) +/* Read an unsigned decimal integer from the PPM file */ +/* Swallows one trailing character after the integer */ +/* Note that on a 16-bit-int machine, only values up to 64k can be read. */ +/* This should not be a problem in practice. */ +{ + register int ch; + register unsigned int val; + + /* Skip any leading whitespace */ + do { + ch = pbm_getc(infile); + if (ch == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); + + if (ch < '0' || ch > '9') + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + val = ch - '0'; + while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') { + val *= 10; + val += ch - '0'; + } + return val; +} + + +/* + * Extract color map from a PPM file. + */ + +LOCAL(void) +read_ppm_map (j_decompress_ptr cinfo, FILE * infile) +{ + int c; + unsigned int w, h, maxval, row, col; + int R, G, B; + + /* Initial 'P' has already been read by read_color_map */ + c = getc(infile); /* save format discriminator for a sec */ + + /* while we fetch the remaining header info */ + w = read_pbm_integer(cinfo, infile); + h = read_pbm_integer(cinfo, infile); + maxval = read_pbm_integer(cinfo, infile); + + if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + /* For now, we don't support rescaling from an unusual maxval. */ + if (maxval != (unsigned int) MAXJSAMPLE) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + switch (c) { + case '3': /* it's a text-format PPM file */ + for (row = 0; row < h; row++) { + for (col = 0; col < w; col++) { + R = read_pbm_integer(cinfo, infile); + G = read_pbm_integer(cinfo, infile); + B = read_pbm_integer(cinfo, infile); + add_map_entry(cinfo, R, G, B); + } + } + break; + + case '6': /* it's a raw-format PPM file */ + for (row = 0; row < h; row++) { + for (col = 0; col < w; col++) { + R = getc(infile); + G = getc(infile); + B = getc(infile); + if (R == EOF || G == EOF || B == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + add_map_entry(cinfo, R, G, B); + } + } + break; + + default: + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + break; + } +} + + +/* + * Main entry point from djpeg.c. + * Input: opened input file (from file name argument on command line). + * Output: colormap and actual_number_of_colors fields are set in cinfo. + */ + +GLOBAL(void) +read_color_map (j_decompress_ptr cinfo, FILE * infile) +{ + /* Allocate space for a color map of maximum supported size. */ + cinfo->colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (MAXJSAMPLE+1), (JDIMENSION) 3); + cinfo->actual_number_of_colors = 0; /* initialize map to empty */ + + /* Read first byte to determine file format */ + switch (getc(infile)) { + case 'G': + read_gif_map(cinfo, infile); + break; + case 'P': + read_ppm_map(cinfo, infile); + break; + default: + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + break; + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/rdgif.c b/rosapps/lib/libjpeg/rdgif.c new file mode 100644 index 00000000000..b27c1675d76 --- /dev/null +++ b/rosapps/lib/libjpeg/rdgif.c @@ -0,0 +1,38 @@ +/* + * rdgif.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in GIF format. + * + ***************************************************************************** + * NOTE: to avoid entanglements with Unisys' patent on LZW compression, * + * the ability to read GIF files has been removed from the IJG distribution. * + * Sorry about that. * + ***************************************************************************** + * + * We are required to state that + * "The Graphics Interchange Format(c) is the Copyright property of + * CompuServe Incorporated. GIF(sm) is a Service Mark property of + * CompuServe Incorporated." + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef GIF_SUPPORTED + +/* + * The module selection routine for GIF format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_gif (j_compress_ptr cinfo) +{ + fprintf(stderr, "GIF input is unsupported for legal reasons. Sorry.\n"); + exit(EXIT_FAILURE); + return NULL; /* keep compiler happy */ +} + +#endif /* GIF_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/rdjpgcom.c b/rosapps/lib/libjpeg/rdjpgcom.c new file mode 100644 index 00000000000..ffe6fc6218d --- /dev/null +++ b/rosapps/lib/libjpeg/rdjpgcom.c @@ -0,0 +1,496 @@ +/* + * rdjpgcom.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a very simple stand-alone application that displays + * the text in COM (comment) markers in a JFIF file. + * This may be useful as an example of the minimum logic needed to parse + * JPEG markers. + */ + +#define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */ +#include "jinclude.h" /* get auto-config symbols, */ + +#include /* to declare isupper(), tolower() */ +#ifdef USE_SETMODE +#include /* to declare setmode()'s parameter macros */ +/* If you have setmode() but not , just delete this line: */ +#include /* to declare setmode() */ +#endif + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#endif +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#ifdef VMS +#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ +#else +#define EXIT_SUCCESS 0 +#endif +#endif + + +/* + * These macros are used to read the input file. + * To reuse this code in another application, you might need to change these. + */ + +static FILE * infile; /* input JPEG file */ + +/* Return next input byte, or EOF if no more */ +#define NEXTBYTE() getc(infile) + + +/* Error exit handler */ +#define ERREXIT(msg) (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE)) + + +/* Read one byte, testing for EOF */ +static int +read_1_byte (void) +{ + int c; + + c = NEXTBYTE(); + if (c == EOF) + ERREXIT("Premature EOF in JPEG file"); + return c; +} + +/* Read 2 bytes, convert to unsigned int */ +/* All 2-byte quantities in JPEG markers are MSB first */ +static unsigned int +read_2_bytes (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + if (c1 == EOF) + ERREXIT("Premature EOF in JPEG file"); + c2 = NEXTBYTE(); + if (c2 == EOF) + ERREXIT("Premature EOF in JPEG file"); + return (((unsigned int) c1) << 8) + ((unsigned int) c2); +} + + +/* + * JPEG markers consist of one or more 0xFF bytes, followed by a marker + * code byte (which is not an FF). Here are the marker codes of interest + * in this program. (See jdmarker.c for a more complete list.) + */ + +#define M_SOF0 0xC0 /* Start Of Frame N */ +#define M_SOF1 0xC1 /* N indicates which compression process */ +#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */ +#define M_EOI 0xD9 /* End Of Image (end of datastream) */ +#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ +#define M_APP0 0xE0 /* Application-specific marker, type N */ +#define M_APP12 0xEC /* (we don't bother to list all 16 APPn's) */ +#define M_COM 0xFE /* COMment */ + + +/* + * Find the next JPEG marker and return its marker code. + * We expect at least one FF byte, possibly more if the compressor used FFs + * to pad the file. + * There could also be non-FF garbage between markers. The treatment of such + * garbage is unspecified; we choose to skip over it but emit a warning msg. + * NB: this routine must not be used after seeing SOS marker, since it will + * not deal correctly with FF/00 sequences in the compressed image data... + */ + +static int +next_marker (void) +{ + int c; + int discarded_bytes = 0; + + /* Find 0xFF byte; count and skip any non-FFs. */ + c = read_1_byte(); + while (c != 0xFF) { + discarded_bytes++; + c = read_1_byte(); + } + /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs + * are legal as pad bytes, so don't count them in discarded_bytes. + */ + do { + c = read_1_byte(); + } while (c == 0xFF); + + if (discarded_bytes != 0) { + fprintf(stderr, "Warning: garbage data found in JPEG file\n"); + } + + return c; +} + + +/* + * Read the initial marker, which should be SOI. + * For a JFIF file, the first two bytes of the file should be literally + * 0xFF M_SOI. To be more general, we could use next_marker, but if the + * input file weren't actually JPEG at all, next_marker might read the whole + * file and then return a misleading error message... + */ + +static int +first_marker (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + c2 = NEXTBYTE(); + if (c1 != 0xFF || c2 != M_SOI) + ERREXIT("Not a JPEG file"); + return c2; +} + + +/* + * Most types of marker are followed by a variable-length parameter segment. + * This routine skips over the parameters for any marker we don't otherwise + * want to process. + * Note that we MUST skip the parameter segment explicitly in order not to + * be fooled by 0xFF bytes that might appear within the parameter segment; + * such bytes do NOT introduce new markers. + */ + +static void +skip_variable (void) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + unsigned int length; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + /* Skip over the remaining bytes */ + while (length > 0) { + (void) read_1_byte(); + length--; + } +} + + +/* + * Process a COM marker. + * We want to print out the marker contents as legible text; + * we must guard against non-text junk and varying newline representations. + */ + +static void +process_COM (void) +{ + unsigned int length; + int ch; + int lastch = 0; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + + while (length > 0) { + ch = read_1_byte(); + /* Emit the character in a readable form. + * Nonprintables are converted to \nnn form, + * while \ is converted to \\. + * Newlines in CR, CR/LF, or LF form will be printed as one newline. + */ + if (ch == '\r') { + printf("\n"); + } else if (ch == '\n') { + if (lastch != '\r') + printf("\n"); + } else if (ch == '\\') { + printf("\\\\"); + } else if (isprint(ch)) { + putc(ch, stdout); + } else { + printf("\\%03o", ch); + } + lastch = ch; + length--; + } + printf("\n"); +} + + +/* + * Process a SOFn marker. + * This code is only needed if you want to know the image dimensions... + */ + +static void +process_SOFn (int marker) +{ + unsigned int length; + unsigned int image_height, image_width; + int data_precision, num_components; + const char * process; + int ci; + + length = read_2_bytes(); /* usual parameter length count */ + + data_precision = read_1_byte(); + image_height = read_2_bytes(); + image_width = read_2_bytes(); + num_components = read_1_byte(); + + switch (marker) { + case M_SOF0: process = "Baseline"; break; + case M_SOF1: process = "Extended sequential"; break; + case M_SOF2: process = "Progressive"; break; + case M_SOF3: process = "Lossless"; break; + case M_SOF5: process = "Differential sequential"; break; + case M_SOF6: process = "Differential progressive"; break; + case M_SOF7: process = "Differential lossless"; break; + case M_SOF9: process = "Extended sequential, arithmetic coding"; break; + case M_SOF10: process = "Progressive, arithmetic coding"; break; + case M_SOF11: process = "Lossless, arithmetic coding"; break; + case M_SOF13: process = "Differential sequential, arithmetic coding"; break; + case M_SOF14: process = "Differential progressive, arithmetic coding"; break; + case M_SOF15: process = "Differential lossless, arithmetic coding"; break; + default: process = "Unknown"; break; + } + + printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n", + image_width, image_height, num_components, data_precision); + printf("JPEG process: %s\n", process); + + if (length != (unsigned int) (8 + num_components * 3)) + ERREXIT("Bogus SOF marker length"); + + for (ci = 0; ci < num_components; ci++) { + (void) read_1_byte(); /* Component ID code */ + (void) read_1_byte(); /* H, V sampling factors */ + (void) read_1_byte(); /* Quantization table number */ + } +} + + +/* + * Parse the marker stream until SOS or EOI is seen; + * display any COM markers. + * While the companion program wrjpgcom will always insert COM markers before + * SOFn, other implementations might not, so we scan to SOS before stopping. + * If we were only interested in the image dimensions, we would stop at SOFn. + * (Conversely, if we only cared about COM markers, there would be no need + * for special code to handle SOFn; we could treat it like other markers.) + */ + +static int +scan_JPEG_header (int verbose) +{ + int marker; + + /* Expect SOI at start of file */ + if (first_marker() != M_SOI) + ERREXIT("Expected SOI marker first"); + + /* Scan miscellaneous markers until we reach SOS. */ + for (;;) { + marker = next_marker(); + switch (marker) { + /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be, + * treated as SOFn. C4 in particular is actually DHT. + */ + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + case M_SOF2: /* Progressive, Huffman */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_SOF9: /* Extended sequential, arithmetic */ + case M_SOF10: /* Progressive, arithmetic */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + if (verbose) + process_SOFn(marker); + else + skip_variable(); + break; + + case M_SOS: /* stop before hitting compressed data */ + return marker; + + case M_EOI: /* in case it's a tables-only JPEG stream */ + return marker; + + case M_COM: + process_COM(); + break; + + case M_APP12: + /* Some digital camera makers put useful textual information into + * APP12 markers, so we print those out too when in -verbose mode. + */ + if (verbose) { + printf("APP12 contains:\n"); + process_COM(); + } else + skip_variable(); + break; + + default: /* Anything else just gets skipped */ + skip_variable(); /* we assume it has a parameter count... */ + break; + } + } /* end loop */ +} + + +/* Command line parsing code */ + +static const char * progname; /* program name for error messages */ + + +static void +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "rdjpgcom displays any textual comments in a JPEG file.\n"); + + fprintf(stderr, "Usage: %s [switches] [inputfile]\n", progname); + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -verbose Also display dimensions of JPEG image\n"); + + exit(EXIT_FAILURE); +} + + +static int +keymatch (char * arg, const char * keyword, int minchars) +/* Case-insensitive matching of (possibly abbreviated) keyword switches. */ +/* keyword is the constant keyword (must be lower case already), */ +/* minchars is length of minimum legal abbreviation. */ +{ + register int ca, ck; + register int nmatched = 0; + + while ((ca = *arg++) != '\0') { + if ((ck = *keyword++) == '\0') + return 0; /* arg longer than keyword, no good */ + if (isupper(ca)) /* force arg to lcase (assume ck is already) */ + ca = tolower(ca); + if (ca != ck) + return 0; /* no good */ + nmatched++; /* count matched characters */ + } + /* reached end of argument; fail if it's too short for unique abbrev */ + if (nmatched < minchars) + return 0; + return 1; /* A-OK */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + int argn; + char * arg; + int verbose = 0; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "rdjpgcom"; /* in case C library doesn't provide it */ + + /* Parse switches, if any */ + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (arg[0] != '-') + break; /* not switch, must be file name */ + arg++; /* advance over '-' */ + if (keymatch(arg, "verbose", 1)) { + verbose++; + } else + usage(); + } + + /* Open the input file. */ + /* Unix style: expect zero or one file name */ + if (argn < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } + if (argn < argc) { + if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdin), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open stdin\n", progname); + exit(EXIT_FAILURE); + } +#else + infile = stdin; +#endif + } + + /* Scan the JPEG headers. */ + (void) scan_JPEG_header(verbose); + + /* All done. */ + exit(EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/rosapps/lib/libjpeg/rdppm.c b/rosapps/lib/libjpeg/rdppm.c new file mode 100644 index 00000000000..1df35c1b3a4 --- /dev/null +++ b/rosapps/lib/libjpeg/rdppm.c @@ -0,0 +1,458 @@ +/* + * rdppm.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in PPM/PGM format. + * The extended 2-byte-per-sample raw PPM/PGM formats are supported. + * The PBMPLUS library is NOT required to compile this software + * (but it is highly useful as a set of PPM image manipulation programs). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed PPM format). + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef PPM_SUPPORTED + + +/* Portions of this code are based on the PBMPLUS library, which is: +** +** Copyright (C) 1988 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + + +/* Macros to deal with unsigned chars as efficiently as compiler allows */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char U_CHAR; +#define UCH(x) ((int) (x)) +#else /* !HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char U_CHAR; +#define UCH(x) ((int) (x)) +#else +typedef char U_CHAR; +#define UCH(x) ((int) (x) & 0xFF) +#endif +#endif /* HAVE_UNSIGNED_CHAR */ + + +#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) + + +/* + * On most systems, reading individual bytes with getc() is drastically less + * efficient than buffering a row at a time with fread(). On PCs, we must + * allocate the buffer in near data space, because we are assuming small-data + * memory model, wherein fread() can't reach far memory. If you need to + * process very wide images on a PC, you might have to compile in large-memory + * model, or else replace fread() with a getc() loop --- which will be much + * slower. + */ + + +/* Private version of data source object */ + +typedef struct { + struct cjpeg_source_struct pub; /* public fields */ + + U_CHAR *iobuffer; /* non-FAR pointer to I/O buffer */ + JSAMPROW pixrow; /* FAR pointer to same */ + size_t buffer_width; /* width of I/O buffer */ + JSAMPLE *rescale; /* => maxval-remapping array, or NULL */ +} ppm_source_struct; + +typedef ppm_source_struct * ppm_source_ptr; + + +LOCAL(int) +pbm_getc (FILE * infile) +/* Read next char, skipping over any comments */ +/* A comment/newline sequence is returned as a newline */ +{ + register int ch; + + ch = getc(infile); + if (ch == '#') { + do { + ch = getc(infile); + } while (ch != '\n' && ch != EOF); + } + return ch; +} + + +LOCAL(unsigned int) +read_pbm_integer (j_compress_ptr cinfo, FILE * infile) +/* Read an unsigned decimal integer from the PPM file */ +/* Swallows one trailing character after the integer */ +/* Note that on a 16-bit-int machine, only values up to 64k can be read. */ +/* This should not be a problem in practice. */ +{ + register int ch; + register unsigned int val; + + /* Skip any leading whitespace */ + do { + ch = pbm_getc(infile); + if (ch == EOF) + ERREXIT(cinfo, JERR_INPUT_EOF); + } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); + + if (ch < '0' || ch > '9') + ERREXIT(cinfo, JERR_PPM_NONNUMERIC); + + val = ch - '0'; + while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') { + val *= 10; + val += ch - '0'; + } + return val; +} + + +/* + * Read one row of pixels. + * + * We provide several different versions depending on input file format. + * In all cases, input is scaled to the size of JSAMPLE. + * + * A really fast path is provided for reading byte/sample raw files with + * maxval = MAXJSAMPLE, which is the normal case for 8-bit data. + */ + + +METHODDEF(JDIMENSION) +get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading text-format PGM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + FILE * infile = source->pub.input_file; + register JSAMPROW ptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading text-format PPM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + FILE * infile = source->pub.input_file; + register JSAMPROW ptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-byte-format PGM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[UCH(*bufferptr++)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-byte-format PPM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[UCH(*bufferptr++)]; + *ptr++ = rescale[UCH(*bufferptr++)]; + *ptr++ = rescale[UCH(*bufferptr++)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-byte-format files with maxval = MAXJSAMPLE. + * In this case we just read right into the JSAMPLE buffer! + * Note that same code works for PPM and PGM files. + */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + return 1; +} + + +METHODDEF(JDIMENSION) +get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-word-format PGM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + register int temp; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-word-format PPM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + register int temp; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + } + return 1; +} + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + int c; + unsigned int w, h, maxval; + boolean need_iobuffer, use_raw_buffer, need_rescale; + + if (getc(source->pub.input_file) != 'P') + ERREXIT(cinfo, JERR_PPM_NOT); + + c = getc(source->pub.input_file); /* subformat discriminator character */ + + /* detect unsupported variants (ie, PBM) before trying to read header */ + switch (c) { + case '2': /* it's a text-format PGM file */ + case '3': /* it's a text-format PPM file */ + case '5': /* it's a raw-format PGM file */ + case '6': /* it's a raw-format PPM file */ + break; + default: + ERREXIT(cinfo, JERR_PPM_NOT); + break; + } + + /* fetch the remaining header info */ + w = read_pbm_integer(cinfo, source->pub.input_file); + h = read_pbm_integer(cinfo, source->pub.input_file); + maxval = read_pbm_integer(cinfo, source->pub.input_file); + + if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ + ERREXIT(cinfo, JERR_PPM_NOT); + + cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ + cinfo->image_width = (JDIMENSION) w; + cinfo->image_height = (JDIMENSION) h; + + /* initialize flags to most common settings */ + need_iobuffer = TRUE; /* do we need an I/O buffer? */ + use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */ + need_rescale = TRUE; /* do we need a rescale array? */ + + switch (c) { + case '2': /* it's a text-format PGM file */ + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); + source->pub.get_pixel_rows = get_text_gray_row; + need_iobuffer = FALSE; + break; + + case '3': /* it's a text-format PPM file */ + cinfo->input_components = 3; + cinfo->in_color_space = JCS_RGB; + TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); + source->pub.get_pixel_rows = get_text_rgb_row; + need_iobuffer = FALSE; + break; + + case '5': /* it's a raw-format PGM file */ + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + TRACEMS2(cinfo, 1, JTRC_PGM, w, h); + if (maxval > 255) { + source->pub.get_pixel_rows = get_word_gray_row; + } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) { + source->pub.get_pixel_rows = get_raw_row; + use_raw_buffer = TRUE; + need_rescale = FALSE; + } else { + source->pub.get_pixel_rows = get_scaled_gray_row; + } + break; + + case '6': /* it's a raw-format PPM file */ + cinfo->input_components = 3; + cinfo->in_color_space = JCS_RGB; + TRACEMS2(cinfo, 1, JTRC_PPM, w, h); + if (maxval > 255) { + source->pub.get_pixel_rows = get_word_rgb_row; + } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) { + source->pub.get_pixel_rows = get_raw_row; + use_raw_buffer = TRUE; + need_rescale = FALSE; + } else { + source->pub.get_pixel_rows = get_scaled_rgb_row; + } + break; + } + + /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ + if (need_iobuffer) { + source->buffer_width = (size_t) w * cinfo->input_components * + ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR))); + source->iobuffer = (U_CHAR *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + source->buffer_width); + } + + /* Create compressor input buffer. */ + if (use_raw_buffer) { + /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ + /* Synthesize a JSAMPARRAY pointer structure */ + /* Cast here implies near->far pointer conversion on PCs */ + source->pixrow = (JSAMPROW) source->iobuffer; + source->pub.buffer = & source->pixrow; + source->pub.buffer_height = 1; + } else { + /* Need to translate anyway, so make a separate sample buffer. */ + source->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1); + source->pub.buffer_height = 1; + } + + /* Compute the rescaling array if required. */ + if (need_rescale) { + INT32 val, half_maxval; + + /* On 16-bit-int machines we have to be careful of maxval = 65535 */ + source->rescale = (JSAMPLE *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE))); + half_maxval = maxval / 2; + for (val = 0; val <= (INT32) maxval; val++) { + /* The multiplication here must be done in 32 bits to avoid overflow */ + source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval); + } + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for PPM format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_ppm (j_compress_ptr cinfo) +{ + ppm_source_ptr source; + + /* Create module interface object */ + source = (ppm_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ppm_source_struct)); + /* Fill in method ptrs, except get_pixel_rows which start_input sets */ + source->pub.start_input = start_input_ppm; + source->pub.finish_input = finish_input_ppm; + + return (cjpeg_source_ptr) source; +} + +#endif /* PPM_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/rdrle.c b/rosapps/lib/libjpeg/rdrle.c new file mode 100644 index 00000000000..542bc37490c --- /dev/null +++ b/rosapps/lib/libjpeg/rdrle.c @@ -0,0 +1,387 @@ +/* + * rdrle.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in Utah RLE format. + * The Utah Raster Toolkit library is required (version 3.1 or later). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed RLE format). + * + * Based on code contributed by Mike Lijewski, + * with updates from Robert Hutchinson. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef RLE_SUPPORTED + +/* rle.h is provided by the Utah Raster Toolkit. */ + +#include + +/* + * We assume that JSAMPLE has the same representation as rle_pixel, + * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + +/* + * We support the following types of RLE files: + * + * GRAYSCALE - 8 bits, no colormap + * MAPPEDGRAY - 8 bits, 1 channel colomap + * PSEUDOCOLOR - 8 bits, 3 channel colormap + * TRUECOLOR - 24 bits, 3 channel colormap + * DIRECTCOLOR - 24 bits, no colormap + * + * For now, we ignore any alpha channel in the image. + */ + +typedef enum + { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind; + + +/* + * Since RLE stores scanlines bottom-to-top, we have to invert the image + * to conform to JPEG's top-to-bottom order. To do this, we read the + * incoming image into a virtual array on the first get_pixel_rows call, + * then fetch the required row from the virtual array on subsequent calls. + */ + +typedef struct _rle_source_struct * rle_source_ptr; + +typedef struct _rle_source_struct { + struct cjpeg_source_struct pub; /* public fields */ + + rle_kind visual; /* actual type of input file */ + jvirt_sarray_ptr image; /* virtual array to hold the image */ + JDIMENSION row; /* current row # in the virtual array */ + rle_hdr header; /* Input file information */ + rle_pixel** rle_row; /* holds a row returned by rle_getrow() */ + +} rle_source_struct; + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + JDIMENSION width, height; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + /* Use RLE library routine to get the header info */ + source->header = *rle_hdr_init(NULL); + source->header.rle_file = source->pub.input_file; + switch (rle_get_setup(&(source->header))) { + case RLE_SUCCESS: + /* A-OK */ + break; + case RLE_NOT_RLE: + ERREXIT(cinfo, JERR_RLE_NOT); + break; + case RLE_NO_SPACE: + ERREXIT(cinfo, JERR_RLE_MEM); + break; + case RLE_EMPTY: + ERREXIT(cinfo, JERR_RLE_EMPTY); + break; + case RLE_EOF: + ERREXIT(cinfo, JERR_RLE_EOF); + break; + default: + ERREXIT(cinfo, JERR_RLE_BADERROR); + break; + } + + /* Figure out what we have, set private vars and return values accordingly */ + + width = source->header.xmax - source->header.xmin + 1; + height = source->header.ymax - source->header.ymin + 1; + source->header.xmin = 0; /* realign horizontally */ + source->header.xmax = width-1; + + cinfo->image_width = width; + cinfo->image_height = height; + cinfo->data_precision = 8; /* we can only handle 8 bit data */ + + if (source->header.ncolors == 1 && source->header.ncmap == 0) { + source->visual = GRAYSCALE; + TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height); + } else if (source->header.ncolors == 1 && source->header.ncmap == 1) { + source->visual = MAPPEDGRAY; + TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height, + 1 << source->header.cmaplen); + } else if (source->header.ncolors == 1 && source->header.ncmap == 3) { + source->visual = PSEUDOCOLOR; + TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height, + 1 << source->header.cmaplen); + } else if (source->header.ncolors == 3 && source->header.ncmap == 3) { + source->visual = TRUECOLOR; + TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height, + 1 << source->header.cmaplen); + } else if (source->header.ncolors == 3 && source->header.ncmap == 0) { + source->visual = DIRECTCOLOR; + TRACEMS2(cinfo, 1, JTRC_RLE, width, height); + } else + ERREXIT(cinfo, JERR_RLE_UNSUPPORTED); + + if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) { + cinfo->in_color_space = JCS_GRAYSCALE; + cinfo->input_components = 1; + } else { + cinfo->in_color_space = JCS_RGB; + cinfo->input_components = 3; + } + + /* + * A place to hold each scanline while it's converted. + * (GRAYSCALE scanlines don't need converting) + */ + if (source->visual != GRAYSCALE) { + source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) width, (JDIMENSION) cinfo->input_components); + } + + /* request a virtual array to hold the image */ + source->image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) (width * source->header.ncolors), + (JDIMENSION) height, (JDIMENSION) 1); + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + /* count file input as separate pass */ + progress->total_extra_passes++; + } +#endif + + source->pub.buffer_height = 1; +} + + +/* + * Read one row of pixels. + * Called only after load_image has read the image into the virtual array. + * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images. + */ + +METHODDEF(JDIMENSION) +get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + + source->row--; + source->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); + + return 1; +} + +/* + * Read one row of pixels. + * Called only after load_image has read the image into the virtual array. + * Used for PSEUDOCOLOR images. + */ + +METHODDEF(JDIMENSION) +get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + JSAMPROW src_row, dest_row; + JDIMENSION col; + rle_map *colormap; + int val; + + colormap = source->header.cmap; + dest_row = source->pub.buffer[0]; + source->row--; + src_row = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); + + for (col = cinfo->image_width; col > 0; col--) { + val = GETJSAMPLE(*src_row++); + *dest_row++ = (JSAMPLE) (colormap[val ] >> 8); + *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8); + *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8); + } + + return 1; +} + + +/* + * Load the image into a virtual array. We have to do this because RLE + * files start at the lower left while the JPEG standard has them starting + * in the upper left. This is called the first time we want to get a row + * of input. What we do is load the RLE data into the array and then call + * the appropriate routine to read one row from the array. Before returning, + * we set source->pub.get_pixel_rows so that subsequent calls go straight to + * the appropriate row-reading routine. + */ + +METHODDEF(JDIMENSION) +load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + JDIMENSION row, col; + JSAMPROW scanline, red_ptr, green_ptr, blue_ptr; + rle_pixel **rle_row; + rle_map *colormap; + char channel; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + colormap = source->header.cmap; + rle_row = source->rle_row; + + /* Read the RLE data into our virtual array. + * We assume here that (a) rle_pixel is represented the same as JSAMPLE, + * and (b) we are not on a machine where FAR pointers differ from regular. + */ + RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */ + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_limit = cinfo->image_height; + progress->pub.pass_counter = 0; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + + switch (source->visual) { + + case GRAYSCALE: + case PSEUDOCOLOR: + for (row = 0; row < cinfo->image_height; row++) { + rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); + rle_getrow(&source->header, rle_row); +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + break; + + case MAPPEDGRAY: + case TRUECOLOR: + for (row = 0; row < cinfo->image_height; row++) { + scanline = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); + rle_row = source->rle_row; + rle_getrow(&source->header, rle_row); + + for (col = 0; col < cinfo->image_width; col++) { + for (channel = 0; channel < source->header.ncolors; channel++) { + *scanline++ = (JSAMPLE) + (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8); + } + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + break; + + case DIRECTCOLOR: + for (row = 0; row < cinfo->image_height; row++) { + scanline = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); + rle_getrow(&source->header, rle_row); + + red_ptr = rle_row[0]; + green_ptr = rle_row[1]; + blue_ptr = rle_row[2]; + + for (col = cinfo->image_width; col > 0; col--) { + *scanline++ = *red_ptr++; + *scanline++ = *green_ptr++; + *scanline++ = *blue_ptr++; + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) + progress->completed_extra_passes++; +#endif + + /* Set up to call proper row-extraction routine in future */ + if (source->visual == PSEUDOCOLOR) { + source->pub.buffer = source->rle_row; + source->pub.get_pixel_rows = get_pseudocolor_row; + } else { + source->pub.get_pixel_rows = get_rle_row; + } + source->row = cinfo->image_height; + + /* And fetch the topmost (bottommost) row */ + return (*source->pub.get_pixel_rows) (cinfo, sinfo); +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for RLE format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_rle (j_compress_ptr cinfo) +{ + rle_source_ptr source; + + /* Create module interface object */ + source = (rle_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(rle_source_struct)); + /* Fill in method ptrs */ + source->pub.start_input = start_input_rle; + source->pub.finish_input = finish_input_rle; + source->pub.get_pixel_rows = load_image; + + return (cjpeg_source_ptr) source; +} + +#endif /* RLE_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/rdswitch.c b/rosapps/lib/libjpeg/rdswitch.c new file mode 100644 index 00000000000..4f4bb4f5899 --- /dev/null +++ b/rosapps/lib/libjpeg/rdswitch.c @@ -0,0 +1,332 @@ +/* + * rdswitch.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to process some of cjpeg's more complicated + * command-line switches. Switches processed here are: + * -qtables file Read quantization tables from text file + * -scans file Read scan script from text file + * -qslots N[,N,...] Set component quantization table selectors + * -sample HxV[,HxV,...] Set component sampling factors + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include /* to declare isdigit(), isspace() */ + + +LOCAL(int) +text_getc (FILE * file) +/* Read next char, skipping over any comments (# to end of line) */ +/* A comment/newline sequence is returned as a newline */ +{ + register int ch; + + ch = getc(file); + if (ch == '#') { + do { + ch = getc(file); + } while (ch != '\n' && ch != EOF); + } + return ch; +} + + +LOCAL(boolean) +read_text_integer (FILE * file, long * result, int * termchar) +/* Read an unsigned decimal integer from a file, store it in result */ +/* Reads one trailing character after the integer; returns it in termchar */ +{ + register int ch; + register long val; + + /* Skip any leading whitespace, detect EOF */ + do { + ch = text_getc(file); + if (ch == EOF) { + *termchar = ch; + return FALSE; + } + } while (isspace(ch)); + + if (! isdigit(ch)) { + *termchar = ch; + return FALSE; + } + + val = ch - '0'; + while ((ch = text_getc(file)) != EOF) { + if (! isdigit(ch)) + break; + val *= 10; + val += ch - '0'; + } + *result = val; + *termchar = ch; + return TRUE; +} + + +GLOBAL(boolean) +read_quant_tables (j_compress_ptr cinfo, char * filename, + int scale_factor, boolean force_baseline) +/* Read a set of quantization tables from the specified file. + * The file is plain ASCII text: decimal numbers with whitespace between. + * Comments preceded by '#' may be included in the file. + * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values. + * The tables are implicitly numbered 0,1,etc. + * NOTE: does not affect the qslots mapping, which will default to selecting + * table 0 for luminance (or primary) components, 1 for chrominance components. + * You must use -qslots if you want a different component->table mapping. + */ +{ + FILE * fp; + int tblno, i, termchar; + long val; + unsigned int table[DCTSIZE2]; + + if ((fp = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Can't open table file %s\n", filename); + return FALSE; + } + tblno = 0; + + while (read_text_integer(fp, &val, &termchar)) { /* read 1st element of table */ + if (tblno >= NUM_QUANT_TBLS) { + fprintf(stderr, "Too many tables in file %s\n", filename); + fclose(fp); + return FALSE; + } + table[0] = (unsigned int) val; + for (i = 1; i < DCTSIZE2; i++) { + if (! read_text_integer(fp, &val, &termchar)) { + fprintf(stderr, "Invalid table data in file %s\n", filename); + fclose(fp); + return FALSE; + } + table[i] = (unsigned int) val; + } + jpeg_add_quant_table(cinfo, tblno, table, scale_factor, force_baseline); + tblno++; + } + + if (termchar != EOF) { + fprintf(stderr, "Non-numeric data in file %s\n", filename); + fclose(fp); + return FALSE; + } + + fclose(fp); + return TRUE; +} + + +#ifdef C_MULTISCAN_FILES_SUPPORTED + +LOCAL(boolean) +read_scan_integer (FILE * file, long * result, int * termchar) +/* Variant of read_text_integer that always looks for a non-space termchar; + * this simplifies parsing of punctuation in scan scripts. + */ +{ + register int ch; + + if (! read_text_integer(file, result, termchar)) + return FALSE; + ch = *termchar; + while (ch != EOF && isspace(ch)) + ch = text_getc(file); + if (isdigit(ch)) { /* oops, put it back */ + if (ungetc(ch, file) == EOF) + return FALSE; + ch = ' '; + } else { + /* Any separators other than ';' and ':' are ignored; + * this allows user to insert commas, etc, if desired. + */ + if (ch != EOF && ch != ';' && ch != ':') + ch = ' '; + } + *termchar = ch; + return TRUE; +} + + +GLOBAL(boolean) +read_scan_script (j_compress_ptr cinfo, char * filename) +/* Read a scan script from the specified text file. + * Each entry in the file defines one scan to be emitted. + * Entries are separated by semicolons ';'. + * An entry contains one to four component indexes, + * optionally followed by a colon ':' and four progressive-JPEG parameters. + * The component indexes denote which component(s) are to be transmitted + * in the current scan. The first component has index 0. + * Sequential JPEG is used if the progressive-JPEG parameters are omitted. + * The file is free format text: any whitespace may appear between numbers + * and the ':' and ';' punctuation marks. Also, other punctuation (such + * as commas or dashes) can be placed between numbers if desired. + * Comments preceded by '#' may be included in the file. + * Note: we do very little validity checking here; + * jcmaster.c will validate the script parameters. + */ +{ + FILE * fp; + int scanno, ncomps, termchar; + long val; + jpeg_scan_info * scanptr; +#define MAX_SCANS 100 /* quite arbitrary limit */ + jpeg_scan_info scans[MAX_SCANS]; + + if ((fp = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Can't open scan definition file %s\n", filename); + return FALSE; + } + scanptr = scans; + scanno = 0; + + while (read_scan_integer(fp, &val, &termchar)) { + if (scanno >= MAX_SCANS) { + fprintf(stderr, "Too many scans defined in file %s\n", filename); + fclose(fp); + return FALSE; + } + scanptr->component_index[0] = (int) val; + ncomps = 1; + while (termchar == ' ') { + if (ncomps >= MAX_COMPS_IN_SCAN) { + fprintf(stderr, "Too many components in one scan in file %s\n", + filename); + fclose(fp); + return FALSE; + } + if (! read_scan_integer(fp, &val, &termchar)) + goto bogus; + scanptr->component_index[ncomps] = (int) val; + ncomps++; + } + scanptr->comps_in_scan = ncomps; + if (termchar == ':') { + if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + goto bogus; + scanptr->Ss = (int) val; + if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + goto bogus; + scanptr->Se = (int) val; + if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + goto bogus; + scanptr->Ah = (int) val; + if (! read_scan_integer(fp, &val, &termchar)) + goto bogus; + scanptr->Al = (int) val; + } else { + /* set non-progressive parameters */ + scanptr->Ss = 0; + scanptr->Se = DCTSIZE2-1; + scanptr->Ah = 0; + scanptr->Al = 0; + } + if (termchar != ';' && termchar != EOF) { +bogus: + fprintf(stderr, "Invalid scan entry format in file %s\n", filename); + fclose(fp); + return FALSE; + } + scanptr++, scanno++; + } + + if (termchar != EOF) { + fprintf(stderr, "Non-numeric data in file %s\n", filename); + fclose(fp); + return FALSE; + } + + if (scanno > 0) { + /* Stash completed scan list in cinfo structure. + * NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data, + * but if you want to compress multiple images you'd want JPOOL_PERMANENT. + */ + scanptr = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + scanno * SIZEOF(jpeg_scan_info)); + MEMCOPY(scanptr, scans, scanno * SIZEOF(jpeg_scan_info)); + cinfo->scan_info = scanptr; + cinfo->num_scans = scanno; + } + + fclose(fp); + return TRUE; +} + +#endif /* C_MULTISCAN_FILES_SUPPORTED */ + + +GLOBAL(boolean) +set_quant_slots (j_compress_ptr cinfo, char *arg) +/* Process a quantization-table-selectors parameter string, of the form + * N[,N,...] + * If there are more components than parameters, the last value is replicated. + */ +{ + int val = 0; /* default table # */ + int ci; + char ch; + + for (ci = 0; ci < MAX_COMPONENTS; ci++) { + if (*arg) { + ch = ','; /* if not set by sscanf, will be ',' */ + if (sscanf(arg, "%d%c", &val, &ch) < 1) + return FALSE; + if (ch != ',') /* syntax check */ + return FALSE; + if (val < 0 || val >= NUM_QUANT_TBLS) { + fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n", + NUM_QUANT_TBLS-1); + return FALSE; + } + cinfo->comp_info[ci].quant_tbl_no = val; + while (*arg && *arg++ != ',') /* advance to next segment of arg string */ + ; + } else { + /* reached end of parameter, set remaining components to last table */ + cinfo->comp_info[ci].quant_tbl_no = val; + } + } + return TRUE; +} + + +GLOBAL(boolean) +set_sample_factors (j_compress_ptr cinfo, char *arg) +/* Process a sample-factors parameter string, of the form + * HxV[,HxV,...] + * If there are more components than parameters, "1x1" is assumed for the rest. + */ +{ + int ci, val1, val2; + char ch1, ch2; + + for (ci = 0; ci < MAX_COMPONENTS; ci++) { + if (*arg) { + ch2 = ','; /* if not set by sscanf, will be ',' */ + if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3) + return FALSE; + if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */ + return FALSE; + if (val1 <= 0 || val1 > 4 || val2 <= 0 || val2 > 4) { + fprintf(stderr, "JPEG sampling factors must be 1..4\n"); + return FALSE; + } + cinfo->comp_info[ci].h_samp_factor = val1; + cinfo->comp_info[ci].v_samp_factor = val2; + while (*arg && *arg++ != ',') /* advance to next segment of arg string */ + ; + } else { + /* reached end of parameter, set remaining components to 1x1 sampling */ + cinfo->comp_info[ci].h_samp_factor = 1; + cinfo->comp_info[ci].v_samp_factor = 1; + } + } + return TRUE; +} diff --git a/rosapps/lib/libjpeg/rdtarga.c b/rosapps/lib/libjpeg/rdtarga.c new file mode 100644 index 00000000000..4c2cd26730a --- /dev/null +++ b/rosapps/lib/libjpeg/rdtarga.c @@ -0,0 +1,500 @@ +/* + * rdtarga.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in Targa format. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed Targa format). + * + * Based on code contributed by Lee Daniel Crocker. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef TARGA_SUPPORTED + + +/* Macros to deal with unsigned chars as efficiently as compiler allows */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char U_CHAR; +#define UCH(x) ((int) (x)) +#else /* !HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char U_CHAR; +#define UCH(x) ((int) (x)) +#else +typedef char U_CHAR; +#define UCH(x) ((int) (x) & 0xFF) +#endif +#endif /* HAVE_UNSIGNED_CHAR */ + + +#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) + + +/* Private version of data source object */ + +typedef struct _tga_source_struct * tga_source_ptr; + +typedef struct _tga_source_struct { + struct cjpeg_source_struct pub; /* public fields */ + + j_compress_ptr cinfo; /* back link saves passing separate parm */ + + JSAMPARRAY colormap; /* Targa colormap (converted to my format) */ + + jvirt_sarray_ptr whole_image; /* Needed if funny input row order */ + JDIMENSION current_row; /* Current logical row number to read */ + + /* Pointer to routine to extract next Targa pixel from input file */ + JMETHOD(void, read_pixel, (tga_source_ptr sinfo)); + + /* Result of read_pixel is delivered here: */ + U_CHAR tga_pixel[4]; + + int pixel_size; /* Bytes per Targa pixel (1 to 4) */ + + /* State info for reading RLE-coded pixels; both counts must be init to 0 */ + int block_count; /* # of pixels remaining in RLE block */ + int dup_pixel_count; /* # of times to duplicate previous pixel */ + + /* This saves the correct pixel-row-expansion method for preload_image */ + JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); +} tga_source_struct; + + +/* For expanding 5-bit pixel values to 8-bit with best rounding */ + +static const UINT8 c5to8bits[32] = { + 0, 8, 16, 25, 33, 41, 49, 58, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 197, 206, 214, 222, 230, 239, 247, 255 +}; + + + +LOCAL(int) +read_byte (tga_source_ptr sinfo) +/* Read next byte from Targa file */ +{ + register FILE *infile = sinfo->pub.input_file; + register int c; + + if ((c = getc(infile)) == EOF) + ERREXIT(sinfo->cinfo, JERR_INPUT_EOF); + return c; +} + + +LOCAL(void) +read_colormap (tga_source_ptr sinfo, int cmaplen, int mapentrysize) +/* Read the colormap from a Targa file */ +{ + int i; + + /* Presently only handles 24-bit BGR format */ + if (mapentrysize != 24) + ERREXIT(sinfo->cinfo, JERR_TGA_BADCMAP); + + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + } +} + + +/* + * read_pixel methods: get a single pixel from Targa file into tga_pixel[] + */ + +METHODDEF(void) +read_non_rle_pixel (tga_source_ptr sinfo) +/* Read one Targa pixel from the input file; no RLE expansion */ +{ + register FILE *infile = sinfo->pub.input_file; + register int i; + + for (i = 0; i < sinfo->pixel_size; i++) { + sinfo->tga_pixel[i] = (U_CHAR) getc(infile); + } +} + + +METHODDEF(void) +read_rle_pixel (tga_source_ptr sinfo) +/* Read one Targa pixel from the input file, expanding RLE data as needed */ +{ + register FILE *infile = sinfo->pub.input_file; + register int i; + + /* Duplicate previously read pixel? */ + if (sinfo->dup_pixel_count > 0) { + sinfo->dup_pixel_count--; + return; + } + + /* Time to read RLE block header? */ + if (--sinfo->block_count < 0) { /* decrement pixels remaining in block */ + i = read_byte(sinfo); + if (i & 0x80) { /* Start of duplicate-pixel block? */ + sinfo->dup_pixel_count = i & 0x7F; /* number of dups after this one */ + sinfo->block_count = 0; /* then read new block header */ + } else { + sinfo->block_count = i & 0x7F; /* number of pixels after this one */ + } + } + + /* Read next pixel */ + for (i = 0; i < sinfo->pixel_size; i++) { + sinfo->tga_pixel[i] = (U_CHAR) getc(infile); + } +} + + +/* + * Read one row of pixels. + * + * We provide several different versions depending on input file format. + */ + + +METHODDEF(JDIMENSION) +get_8bit_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 8-bit grayscale pixels */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]); + } + return 1; +} + +METHODDEF(JDIMENSION) +get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 8-bit colormap indexes */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register int t; + register JSAMPROW ptr; + register JDIMENSION col; + register JSAMPARRAY colormap = source->colormap; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + t = UCH(source->tga_pixel[0]); + *ptr++ = colormap[0][t]; + *ptr++ = colormap[1][t]; + *ptr++ = colormap[2][t]; + } + return 1; +} + +METHODDEF(JDIMENSION) +get_16bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 16-bit pixels */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register int t; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + t = UCH(source->tga_pixel[0]); + t += UCH(source->tga_pixel[1]) << 8; + /* We expand 5 bit data to 8 bit sample width. + * The format of the 16-bit (LSB first) input word is + * xRRRRRGGGGGBBBBB + */ + ptr[2] = (JSAMPLE) c5to8bits[t & 0x1F]; + t >>= 5; + ptr[1] = (JSAMPLE) c5to8bits[t & 0x1F]; + t >>= 5; + ptr[0] = (JSAMPLE) c5to8bits[t & 0x1F]; + ptr += 3; + } + return 1; +} + +METHODDEF(JDIMENSION) +get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 24-bit pixels */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[2]); /* change BGR to RGB order */ + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[1]); + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]); + } + return 1; +} + +/* + * Targa also defines a 32-bit pixel format with order B,G,R,A. + * We presently ignore the attribute byte, so the code for reading + * these pixels is identical to the 24-bit routine above. + * This works because the actual pixel length is only known to read_pixel. + */ + +#define get_32bit_row get_24bit_row + + +/* + * This method is for re-reading the input data in standard top-down + * row order. The entire image has already been read into whole_image + * with proper conversion of pixel format, but it's in a funny row order. + */ + +METHODDEF(JDIMENSION) +get_memory_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + JDIMENSION source_row; + + /* Compute row of source that maps to current_row of normal order */ + /* For now, assume image is bottom-up and not interlaced. */ + /* NEEDS WORK to support interlaced images! */ + source_row = cinfo->image_height - source->current_row - 1; + + /* Fetch that row from virtual array */ + source->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source_row, (JDIMENSION) 1, FALSE); + + source->current_row++; + return 1; +} + + +/* + * This method loads the image into whole_image during the first call on + * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call + * get_memory_row on subsequent calls. + */ + +METHODDEF(JDIMENSION) +preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + JDIMENSION row; + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + + /* Read the data into a virtual array in input-file row order. */ + for (row = 0; row < cinfo->image_height; row++) { + if (progress != NULL) { + progress->pub.pass_counter = (long) row; + progress->pub.pass_limit = (long) cinfo->image_height; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } + source->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, row, (JDIMENSION) 1, TRUE); + (*source->get_pixel_rows) (cinfo, sinfo); + } + if (progress != NULL) + progress->completed_extra_passes++; + + /* Set up to read from the virtual array in unscrambled order */ + source->pub.get_pixel_rows = get_memory_row; + source->current_row = 0; + /* And read the first row */ + return get_memory_row(cinfo, sinfo); +} + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + U_CHAR targaheader[18]; + int idlen, cmaptype, subtype, flags, interlace_type, components; + unsigned int width, height, maplen; + boolean is_bottom_up; + +#define GET_2B(offset) ((unsigned int) UCH(targaheader[offset]) + \ + (((unsigned int) UCH(targaheader[offset+1])) << 8)) + + if (! ReadOK(source->pub.input_file, targaheader, 18)) + ERREXIT(cinfo, JERR_INPUT_EOF); + + /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */ + if (targaheader[16] == 15) + targaheader[16] = 16; + + idlen = UCH(targaheader[0]); + cmaptype = UCH(targaheader[1]); + subtype = UCH(targaheader[2]); + maplen = GET_2B(5); + width = GET_2B(12); + height = GET_2B(14); + source->pixel_size = UCH(targaheader[16]) >> 3; + flags = UCH(targaheader[17]); /* Image Descriptor byte */ + + is_bottom_up = ((flags & 0x20) == 0); /* bit 5 set => top-down */ + interlace_type = flags >> 6; /* bits 6/7 are interlace code */ + + if (cmaptype > 1 || /* cmaptype must be 0 or 1 */ + source->pixel_size < 1 || source->pixel_size > 4 || + (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */ + interlace_type != 0) /* currently don't allow interlaced image */ + ERREXIT(cinfo, JERR_TGA_BADPARMS); + + if (subtype > 8) { + /* It's an RLE-coded file */ + source->read_pixel = read_rle_pixel; + source->block_count = source->dup_pixel_count = 0; + subtype -= 8; + } else { + /* Non-RLE file */ + source->read_pixel = read_non_rle_pixel; + } + + /* Now should have subtype 1, 2, or 3 */ + components = 3; /* until proven different */ + cinfo->in_color_space = JCS_RGB; + + switch (subtype) { + case 1: /* Colormapped image */ + if (source->pixel_size == 1 && cmaptype == 1) + source->get_pixel_rows = get_8bit_row; + else + ERREXIT(cinfo, JERR_TGA_BADPARMS); + TRACEMS2(cinfo, 1, JTRC_TGA_MAPPED, width, height); + break; + case 2: /* RGB image */ + switch (source->pixel_size) { + case 2: + source->get_pixel_rows = get_16bit_row; + break; + case 3: + source->get_pixel_rows = get_24bit_row; + break; + case 4: + source->get_pixel_rows = get_32bit_row; + break; + default: + ERREXIT(cinfo, JERR_TGA_BADPARMS); + break; + } + TRACEMS2(cinfo, 1, JTRC_TGA, width, height); + break; + case 3: /* Grayscale image */ + components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + if (source->pixel_size == 1) + source->get_pixel_rows = get_8bit_gray_row; + else + ERREXIT(cinfo, JERR_TGA_BADPARMS); + TRACEMS2(cinfo, 1, JTRC_TGA_GRAY, width, height); + break; + default: + ERREXIT(cinfo, JERR_TGA_BADPARMS); + break; + } + + if (is_bottom_up) { + /* Create a virtual array to buffer the upside-down image. */ + source->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) width * components, (JDIMENSION) height, (JDIMENSION) 1); + if (cinfo->progress != NULL) { + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + progress->total_extra_passes++; /* count file input as separate pass */ + } + /* source->pub.buffer will point to the virtual array. */ + source->pub.buffer_height = 1; /* in case anyone looks at it */ + source->pub.get_pixel_rows = preload_image; + } else { + /* Don't need a virtual array, but do need a one-row input buffer. */ + source->whole_image = NULL; + source->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) width * components, (JDIMENSION) 1); + source->pub.buffer_height = 1; + source->pub.get_pixel_rows = source->get_pixel_rows; + } + + while (idlen--) /* Throw away ID field */ + (void) read_byte(source); + + if (maplen > 0) { + if (maplen > 256 || GET_2B(3) != 0) + ERREXIT(cinfo, JERR_TGA_BADCMAP); + /* Allocate space to store the colormap */ + source->colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) maplen, (JDIMENSION) 3); + /* and read it from the file */ + read_colormap(source, (int) maplen, UCH(targaheader[7])); + } else { + if (cmaptype) /* but you promised a cmap! */ + ERREXIT(cinfo, JERR_TGA_BADPARMS); + source->colormap = NULL; + } + + cinfo->input_components = components; + cinfo->data_precision = 8; + cinfo->image_width = width; + cinfo->image_height = height; +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for Targa format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_targa (j_compress_ptr cinfo) +{ + tga_source_ptr source; + + /* Create module interface object */ + source = (tga_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(tga_source_struct)); + source->cinfo = cinfo; /* make back link for subroutines */ + /* Fill in method ptrs, except get_pixel_rows which start_input sets */ + source->pub.start_input = start_input_tga; + source->pub.finish_input = finish_input_tga; + + return (cjpeg_source_ptr) source; +} + +#endif /* TARGA_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/transupp.c b/rosapps/lib/libjpeg/transupp.c new file mode 100644 index 00000000000..ff0f275cfc6 --- /dev/null +++ b/rosapps/lib/libjpeg/transupp.c @@ -0,0 +1,1529 @@ +/* + * transupp.c + * + * Copyright (C) 1997-2001, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains image transformation routines and other utility code + * used by the jpegtran sample application. These are NOT part of the core + * JPEG library. But we keep these routines separate from jpegtran.c to + * ease the task of maintaining jpegtran-like programs that have other user + * interfaces. + */ + +/* Although this file really shouldn't have access to the library internals, + * it's helpful to let it call jround_up() and jcopy_block_row(). + */ +#define JPEG_INTERNALS + +#include "jinclude.h" +#include "jpeglib.h" +#include "transupp.h" /* My own external interface */ +#include /* to declare isdigit() */ + + +#if TRANSFORMS_SUPPORTED + +/* + * Lossless image transformation routines. These routines work on DCT + * coefficient arrays and thus do not require any lossy decompression + * or recompression of the image. + * Thanks to Guido Vollbeding for the initial design and code of this feature, + * and to Ben Jackson for introducing the cropping feature. + * + * Horizontal flipping is done in-place, using a single top-to-bottom + * pass through the virtual source array. It will thus be much the + * fastest option for images larger than main memory. + * + * The other routines require a set of destination virtual arrays, so they + * need twice as much memory as jpegtran normally does. The destination + * arrays are always written in normal scan order (top to bottom) because + * the virtual array manager expects this. The source arrays will be scanned + * in the corresponding order, which means multiple passes through the source + * arrays for most of the transforms. That could result in much thrashing + * if the image is larger than main memory. + * + * If cropping or trimming is involved, the destination arrays may be smaller + * than the source arrays. Note it is not possible to do horizontal flip + * in-place when a nonzero Y crop offset is specified, since we'd have to move + * data from one block row to another but the virtual array manager doesn't + * guarantee we can touch more than one row at a time. So in that case, + * we have to use a separate destination array. + * + * Some notes about the operating environment of the individual transform + * routines: + * 1. Both the source and destination virtual arrays are allocated from the + * source JPEG object, and therefore should be manipulated by calling the + * source's memory manager. + * 2. The destination's component count should be used. It may be smaller + * than the source's when forcing to grayscale. + * 3. Likewise the destination's sampling factors should be used. When + * forcing to grayscale the destination's sampling factors will be all 1, + * and we may as well take that as the effective iMCU size. + * 4. When "trim" is in effect, the destination's dimensions will be the + * trimmed values but the source's will be untrimmed. + * 5. When "crop" is in effect, the destination's dimensions will be the + * cropped values but the source's will be uncropped. Each transform + * routine is responsible for picking up source data starting at the + * correct X and Y offset for the crop region. (The X and Y offsets + * passed to the transform routines are measured in iMCU blocks of the + * destination.) + * 6. All the routines assume that the source and destination buffers are + * padded out to a full iMCU boundary. This is true, although for the + * source buffer it is an undocumented property of jdcoefct.c. + */ + + +LOCAL(void) +do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Crop. This is only used when no rotate/flip is requested with the crop. */ +{ + JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks; + int ci, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + jpeg_component_info *compptr; + + /* We simply have to copy the right amount of data (the destination's + * image size) starting at the given X and Y offsets in the source. + */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, + dst_buffer[offset_y], + compptr->width_in_blocks); + } + } + } +} + + +LOCAL(void) +do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, + jvirt_barray_ptr *src_coef_arrays) +/* Horizontal flip; done in-place, so no separate dest array is required. + * NB: this only works when y_crop_offset is zero. + */ +{ + JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks; + int ci, k, offset_y; + JBLOCKARRAY buffer; + JCOEFPTR ptr1, ptr2; + JCOEF temp1, temp2; + jpeg_component_info *compptr; + + /* Horizontal mirroring of DCT blocks is accomplished by swapping + * pairs of blocks in-place. Within a DCT block, we perform horizontal + * mirroring by changing the signs of odd-numbered columns. + * Partial iMCUs at the right edge are left untouched. + */ + MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + for (blk_y = 0; blk_y < compptr->height_in_blocks; + blk_y += compptr->v_samp_factor) { + buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + /* Do the mirroring */ + for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { + ptr1 = buffer[offset_y][blk_x]; + ptr2 = buffer[offset_y][comp_width - blk_x - 1]; + /* this unrolled loop doesn't need to know which row it's on... */ + for (k = 0; k < DCTSIZE2; k += 2) { + temp1 = *ptr1; /* swap even column */ + temp2 = *ptr2; + *ptr1++ = temp2; + *ptr2++ = temp1; + temp1 = *ptr1; /* swap odd column with sign change */ + temp2 = *ptr2; + *ptr1++ = -temp2; + *ptr2++ = -temp1; + } + } + if (x_crop_blocks > 0) { + /* Now left-justify the portion of the data to be kept. + * We can't use a single jcopy_block_row() call because that routine + * depends on memcpy(), whose behavior is unspecified for overlapping + * source and destination areas. Sigh. + */ + for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) { + jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks, + buffer[offset_y] + blk_x, + (JDIMENSION) 1); + } + } + } + } + } +} + + +LOCAL(void) +do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Horizontal flip in general cropping case */ +{ + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, k, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Here we must output into a separate array because we can't touch + * different rows of a single virtual array simultaneously. Otherwise, + * this is essentially the same as the routine above. + */ + MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[offset_y]; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Do the mirrorable blocks */ + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; + /* this unrolled loop doesn't need to know which row it's on... */ + for (k = 0; k < DCTSIZE2; k += 2) { + *dst_ptr++ = *src_ptr++; /* copy even column */ + *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */ + } + } else { + /* Copy last partial block(s) verbatim */ + jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, + dst_row_ptr + dst_blk_x, + (JDIMENSION) 1); + } + } + } + } + } +} + + +LOCAL(void) +do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Vertical flip */ +{ + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* We output into a separate array because we can't touch different + * rows of the source virtual array simultaneously. Otherwise, this + * is a pretty straightforward analog of horizontal flip. + * Within a DCT block, vertical mirroring is done by changing the signs + * of odd-numbered rows. + * Partial iMCUs at the bottom edge are copied verbatim. + */ + MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_height - y_crop_blocks - dst_blk_y - + (JDIMENSION) compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge blocks will be copied verbatim. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; + src_row_ptr += x_crop_blocks; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[dst_blk_x]; + for (i = 0; i < DCTSIZE; i += 2) { + /* copy even row */ + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = *src_ptr++; + /* copy odd row with sign change */ + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = - *src_ptr++; + } + } + } else { + /* Just copy row verbatim. */ + jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, + dst_buffer[offset_y], + compptr->width_in_blocks); + } + } + } + } +} + + +LOCAL(void) +do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Transpose source into destination */ +{ + JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Transposing pixels within a block just requires transposing the + * DCT coefficients. + * Partial iMCUs at the edges require no special treatment; we simply + * process all the available DCT blocks for every component. + */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_x + x_crop_blocks, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } +} + + +LOCAL(void) +do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* 90 degree rotation is equivalent to + * 1. Transposing the image; + * 2. Horizontal mirroring. + * These two steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Because of the horizontal mirror step, we can't process partial iMCUs + * at the (output) right edge properly. They just get transposed and + * not mirrored. + */ + MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_width - x_crop_blocks - dst_blk_x - + (JDIMENSION) compptr->h_samp_factor, + (JDIMENSION) compptr->h_samp_factor, FALSE); + } else { + /* Edge blocks are transposed but not mirrored. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_x + x_crop_blocks, + (JDIMENSION) compptr->h_samp_factor, FALSE); + } + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] + [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + i++; + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } else { + /* Edge blocks are transposed but not mirrored. */ + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } + } +} + + +LOCAL(void) +do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* 270 degree rotation is equivalent to + * 1. Horizontal mirroring; + * 2. Transposing the image. + * These two steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Because of the horizontal mirror step, we can't process partial iMCUs + * at the (output) bottom edge properly. They just get transposed and + * not mirrored. + */ + MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_x + x_crop_blocks, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + if (y_crop_blocks + dst_blk_y < comp_height) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[offset_x] + [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } + } else { + /* Edge blocks are transposed but not mirrored. */ + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } + } +} + + +LOCAL(void) +do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* 180 degree rotation is equivalent to + * 1. Vertical mirroring; + * 2. Horizontal mirroring. + * These two steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the vertically mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_height - y_crop_blocks - dst_blk_y - + (JDIMENSION) compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge rows are only mirrored horizontally. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + dst_row_ptr = dst_buffer[offset_y]; + if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Process the blocks that can be mirrored both ways. */ + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; + for (i = 0; i < DCTSIZE; i += 2) { + /* For even row, negate every odd column. */ + for (j = 0; j < DCTSIZE; j += 2) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + } + /* For odd row, negate every even column. */ + for (j = 0; j < DCTSIZE; j += 2) { + *dst_ptr++ = - *src_ptr++; + *dst_ptr++ = *src_ptr++; + } + } + } else { + /* Any remaining right-edge blocks are only mirrored vertically. */ + src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x]; + for (i = 0; i < DCTSIZE; i += 2) { + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = *src_ptr++; + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = - *src_ptr++; + } + } + } + } else { + /* Remaining rows are just mirrored horizontally. */ + src_row_ptr = src_buffer[offset_y]; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Process the blocks that can be mirrored. */ + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; + for (i = 0; i < DCTSIZE2; i += 2) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + } + } else { + /* Any remaining right-edge blocks are only copied. */ + jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, + dst_row_ptr + dst_blk_x, + (JDIMENSION) 1); + } + } + } + } + } + } +} + + +LOCAL(void) +do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Transverse transpose is equivalent to + * 1. 180 degree rotation; + * 2. Transposition; + * or + * 1. Horizontal mirroring; + * 2. Transposition; + * 3. Horizontal mirroring. + * These steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_width - x_crop_blocks - dst_blk_x - + (JDIMENSION) compptr->h_samp_factor, + (JDIMENSION) compptr->h_samp_factor, FALSE); + } else { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_x + x_crop_blocks, + (JDIMENSION) compptr->h_samp_factor, FALSE); + } + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + if (y_crop_blocks + dst_blk_y < comp_height) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] + [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + i++; + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } else { + /* Right-edge blocks are mirrored in y only */ + src_ptr = src_buffer[offset_x] + [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } + } + } else { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Bottom-edge blocks are mirrored in x only */ + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] + [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + i++; + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } else { + /* At lower right corner, just transpose, no mirroring */ + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } + } + } +} + + +/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec. + * Returns TRUE if valid integer found, FALSE if not. + * *strptr is advanced over the digit string, and *result is set to its value. + */ + +LOCAL(boolean) +jt_read_integer (const char ** strptr, JDIMENSION * result) +{ + const char * ptr = *strptr; + JDIMENSION val = 0; + + for (; isdigit(*ptr); ptr++) { + val = val * 10 + (JDIMENSION) (*ptr - '0'); + } + *result = val; + if (ptr == *strptr) + return FALSE; /* oops, no digits */ + *strptr = ptr; + return TRUE; +} + + +/* Parse a crop specification (written in X11 geometry style). + * The routine returns TRUE if the spec string is valid, FALSE if not. + * + * The crop spec string should have the format + * x{+-}{+-} + * where width, height, xoffset, and yoffset are unsigned integers. + * Each of the elements can be omitted to indicate a default value. + * (A weakness of this style is that it is not possible to omit xoffset + * while specifying yoffset, since they look alike.) + * + * This code is loosely based on XParseGeometry from the X11 distribution. + */ + +GLOBAL(boolean) +jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec) +{ + info->crop = FALSE; + info->crop_width_set = JCROP_UNSET; + info->crop_height_set = JCROP_UNSET; + info->crop_xoffset_set = JCROP_UNSET; + info->crop_yoffset_set = JCROP_UNSET; + + if (isdigit(*spec)) { + /* fetch width */ + if (! jt_read_integer(&spec, &info->crop_width)) + return FALSE; + info->crop_width_set = JCROP_POS; + } + if (*spec == 'x' || *spec == 'X') { + /* fetch height */ + spec++; + if (! jt_read_integer(&spec, &info->crop_height)) + return FALSE; + info->crop_height_set = JCROP_POS; + } + if (*spec == '+' || *spec == '-') { + /* fetch xoffset */ + info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; + spec++; + if (! jt_read_integer(&spec, &info->crop_xoffset)) + return FALSE; + } + if (*spec == '+' || *spec == '-') { + /* fetch yoffset */ + info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; + spec++; + if (! jt_read_integer(&spec, &info->crop_yoffset)) + return FALSE; + } + /* We had better have gotten to the end of the string. */ + if (*spec != '\0') + return FALSE; + info->crop = TRUE; + return TRUE; +} + + +/* Trim off any partial iMCUs on the indicated destination edge */ + +LOCAL(void) +trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width) +{ + JDIMENSION MCU_cols; + + MCU_cols = info->output_width / (info->max_h_samp_factor * DCTSIZE); + if (MCU_cols > 0 && info->x_crop_offset + MCU_cols == + full_width / (info->max_h_samp_factor * DCTSIZE)) + info->output_width = MCU_cols * (info->max_h_samp_factor * DCTSIZE); +} + +LOCAL(void) +trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height) +{ + JDIMENSION MCU_rows; + + MCU_rows = info->output_height / (info->max_v_samp_factor * DCTSIZE); + if (MCU_rows > 0 && info->y_crop_offset + MCU_rows == + full_height / (info->max_v_samp_factor * DCTSIZE)) + info->output_height = MCU_rows * (info->max_v_samp_factor * DCTSIZE); +} + + +/* Request any required workspace. + * + * This routine figures out the size that the output image will be + * (which implies that all the transform parameters must be set before + * it is called). + * + * We allocate the workspace virtual arrays from the source decompression + * object, so that all the arrays (both the original data and the workspace) + * will be taken into account while making memory management decisions. + * Hence, this routine must be called after jpeg_read_header (which reads + * the image dimensions) and before jpeg_read_coefficients (which realizes + * the source's virtual arrays). + */ + +GLOBAL(void) +jtransform_request_workspace (j_decompress_ptr srcinfo, + jpeg_transform_info *info) +{ + jvirt_barray_ptr *coef_arrays = NULL; + boolean need_workspace, transpose_it; + jpeg_component_info *compptr; + JDIMENSION xoffset, yoffset, width_in_iMCUs, height_in_iMCUs; + JDIMENSION width_in_blocks, height_in_blocks; + int ci, h_samp_factor, v_samp_factor; + + /* Determine number of components in output image */ + if (info->force_grayscale && + srcinfo->jpeg_color_space == JCS_YCbCr && + srcinfo->num_components == 3) { + /* We'll only process the first component */ + info->num_components = 1; + } else { + /* Process all the components */ + info->num_components = srcinfo->num_components; + } + /* If there is only one output component, force the iMCU size to be 1; + * else use the source iMCU size. (This allows us to do the right thing + * when reducing color to grayscale, and also provides a handy way of + * cleaning up "funny" grayscale images whose sampling factors are not 1x1.) + */ + + switch (info->transform) { + case JXFORM_TRANSPOSE: + case JXFORM_TRANSVERSE: + case JXFORM_ROT_90: + case JXFORM_ROT_270: + info->output_width = srcinfo->image_height; + info->output_height = srcinfo->image_width; + if (info->num_components == 1) { + info->max_h_samp_factor = 1; + info->max_v_samp_factor = 1; + } else { + info->max_h_samp_factor = srcinfo->max_v_samp_factor; + info->max_v_samp_factor = srcinfo->max_h_samp_factor; + } + break; + default: + info->output_width = srcinfo->image_width; + info->output_height = srcinfo->image_height; + if (info->num_components == 1) { + info->max_h_samp_factor = 1; + info->max_v_samp_factor = 1; + } else { + info->max_h_samp_factor = srcinfo->max_h_samp_factor; + info->max_v_samp_factor = srcinfo->max_v_samp_factor; + } + break; + } + + /* If cropping has been requested, compute the crop area's position and + * dimensions, ensuring that its upper left corner falls at an iMCU boundary. + */ + if (info->crop) { + /* Insert default values for unset crop parameters */ + if (info->crop_xoffset_set == JCROP_UNSET) + info->crop_xoffset = 0; /* default to +0 */ + if (info->crop_yoffset_set == JCROP_UNSET) + info->crop_yoffset = 0; /* default to +0 */ + if (info->crop_xoffset >= info->output_width || + info->crop_yoffset >= info->output_height) + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); + if (info->crop_width_set == JCROP_UNSET) + info->crop_width = info->output_width - info->crop_xoffset; + if (info->crop_height_set == JCROP_UNSET) + info->crop_height = info->output_height - info->crop_yoffset; + /* Ensure parameters are valid */ + if (info->crop_width <= 0 || info->crop_width > info->output_width || + info->crop_height <= 0 || info->crop_height > info->output_height || + info->crop_xoffset > info->output_width - info->crop_width || + info->crop_yoffset > info->output_height - info->crop_height) + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); + /* Convert negative crop offsets into regular offsets */ + if (info->crop_xoffset_set == JCROP_NEG) + xoffset = info->output_width - info->crop_width - info->crop_xoffset; + else + xoffset = info->crop_xoffset; + if (info->crop_yoffset_set == JCROP_NEG) + yoffset = info->output_height - info->crop_height - info->crop_yoffset; + else + yoffset = info->crop_yoffset; + /* Now adjust so that upper left corner falls at an iMCU boundary */ + info->output_width = + info->crop_width + (xoffset % (info->max_h_samp_factor * DCTSIZE)); + info->output_height = + info->crop_height + (yoffset % (info->max_v_samp_factor * DCTSIZE)); + /* Save x/y offsets measured in iMCUs */ + info->x_crop_offset = xoffset / (info->max_h_samp_factor * DCTSIZE); + info->y_crop_offset = yoffset / (info->max_v_samp_factor * DCTSIZE); + } else { + info->x_crop_offset = 0; + info->y_crop_offset = 0; + } + + /* Figure out whether we need workspace arrays, + * and if so whether they are transposed relative to the source. + */ + need_workspace = FALSE; + transpose_it = FALSE; + switch (info->transform) { + case JXFORM_NONE: + if (info->x_crop_offset != 0 || info->y_crop_offset != 0) + need_workspace = TRUE; + /* No workspace needed if neither cropping nor transforming */ + break; + case JXFORM_FLIP_H: + if (info->trim) + trim_right_edge(info, srcinfo->image_width); + if (info->y_crop_offset != 0) + need_workspace = TRUE; + /* do_flip_h_no_crop doesn't need a workspace array */ + break; + case JXFORM_FLIP_V: + if (info->trim) + trim_bottom_edge(info, srcinfo->image_height); + /* Need workspace arrays having same dimensions as source image. */ + need_workspace = TRUE; + break; + case JXFORM_TRANSPOSE: + /* transpose does NOT have to trim anything */ + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + case JXFORM_TRANSVERSE: + if (info->trim) { + trim_right_edge(info, srcinfo->image_height); + trim_bottom_edge(info, srcinfo->image_width); + } + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + case JXFORM_ROT_90: + if (info->trim) + trim_right_edge(info, srcinfo->image_height); + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + case JXFORM_ROT_180: + if (info->trim) { + trim_right_edge(info, srcinfo->image_width); + trim_bottom_edge(info, srcinfo->image_height); + } + /* Need workspace arrays having same dimensions as source image. */ + need_workspace = TRUE; + break; + case JXFORM_ROT_270: + if (info->trim) + trim_bottom_edge(info, srcinfo->image_width); + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + } + + /* Allocate workspace if needed. + * Note that we allocate arrays padded out to the next iMCU boundary, + * so that transform routines need not worry about missing edge blocks. + */ + if (need_workspace) { + coef_arrays = (jvirt_barray_ptr *) + (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, + SIZEOF(jvirt_barray_ptr) * info->num_components); + width_in_iMCUs = (JDIMENSION) + jdiv_round_up((long) info->output_width, + (long) (info->max_h_samp_factor * DCTSIZE)); + height_in_iMCUs = (JDIMENSION) + jdiv_round_up((long) info->output_height, + (long) (info->max_v_samp_factor * DCTSIZE)); + for (ci = 0; ci < info->num_components; ci++) { + compptr = srcinfo->comp_info + ci; + if (info->num_components == 1) { + /* we're going to force samp factors to 1x1 in this case */ + h_samp_factor = v_samp_factor = 1; + } else if (transpose_it) { + h_samp_factor = compptr->v_samp_factor; + v_samp_factor = compptr->h_samp_factor; + } else { + h_samp_factor = compptr->h_samp_factor; + v_samp_factor = compptr->v_samp_factor; + } + width_in_blocks = width_in_iMCUs * h_samp_factor; + height_in_blocks = height_in_iMCUs * v_samp_factor; + coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) + ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, + width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor); + } + } + + info->workspace_coef_arrays = coef_arrays; +} + + +/* Transpose destination image parameters */ + +LOCAL(void) +transpose_critical_parameters (j_compress_ptr dstinfo) +{ + int tblno, i, j, ci, itemp; + jpeg_component_info *compptr; + JQUANT_TBL *qtblptr; + UINT16 qtemp; + + /* Transpose sampling factors */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + itemp = compptr->h_samp_factor; + compptr->h_samp_factor = compptr->v_samp_factor; + compptr->v_samp_factor = itemp; + } + + /* Transpose quantization tables */ + for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { + qtblptr = dstinfo->quant_tbl_ptrs[tblno]; + if (qtblptr != NULL) { + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < i; j++) { + qtemp = qtblptr->quantval[i*DCTSIZE+j]; + qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i]; + qtblptr->quantval[j*DCTSIZE+i] = qtemp; + } + } + } + } +} + + +/* Adjust Exif image parameters. + * + * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible. + */ + +LOCAL(void) +adjust_exif_parameters (JOCTET FAR * data, unsigned int length, + JDIMENSION new_width, JDIMENSION new_height) +{ + boolean is_motorola; /* Flag for byte order */ + unsigned int number_of_tags, tagnum; + unsigned int firstoffset, offset; + JDIMENSION new_value; + + if (length < 12) return; /* Length of an IFD entry */ + + /* Discover byte order */ + if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) + is_motorola = FALSE; + else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) + is_motorola = TRUE; + else + return; + + /* Check Tag Mark */ + if (is_motorola) { + if (GETJOCTET(data[2]) != 0) return; + if (GETJOCTET(data[3]) != 0x2A) return; + } else { + if (GETJOCTET(data[3]) != 0) return; + if (GETJOCTET(data[2]) != 0x2A) return; + } + + /* Get first IFD offset (offset to IFD0) */ + if (is_motorola) { + if (GETJOCTET(data[4]) != 0) return; + if (GETJOCTET(data[5]) != 0) return; + firstoffset = GETJOCTET(data[6]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[7]); + } else { + if (GETJOCTET(data[7]) != 0) return; + if (GETJOCTET(data[6]) != 0) return; + firstoffset = GETJOCTET(data[5]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[4]); + } + if (firstoffset > length - 2) return; /* check end of data segment */ + + /* Get the number of directory entries contained in this IFD */ + if (is_motorola) { + number_of_tags = GETJOCTET(data[firstoffset]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset+1]); + } else { + number_of_tags = GETJOCTET(data[firstoffset+1]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset]); + } + if (number_of_tags == 0) return; + firstoffset += 2; + + /* Search for ExifSubIFD offset Tag in IFD0 */ + for (;;) { + if (firstoffset > length - 12) return; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = GETJOCTET(data[firstoffset]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset+1]); + } else { + tagnum = GETJOCTET(data[firstoffset+1]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset]); + } + if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */ + if (--number_of_tags == 0) return; + firstoffset += 12; + } + + /* Get the ExifSubIFD offset */ + if (is_motorola) { + if (GETJOCTET(data[firstoffset+8]) != 0) return; + if (GETJOCTET(data[firstoffset+9]) != 0) return; + offset = GETJOCTET(data[firstoffset+10]); + offset <<= 8; + offset += GETJOCTET(data[firstoffset+11]); + } else { + if (GETJOCTET(data[firstoffset+11]) != 0) return; + if (GETJOCTET(data[firstoffset+10]) != 0) return; + offset = GETJOCTET(data[firstoffset+9]); + offset <<= 8; + offset += GETJOCTET(data[firstoffset+8]); + } + if (offset > length - 2) return; /* check end of data segment */ + + /* Get the number of directory entries contained in this SubIFD */ + if (is_motorola) { + number_of_tags = GETJOCTET(data[offset]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[offset+1]); + } else { + number_of_tags = GETJOCTET(data[offset+1]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[offset]); + } + if (number_of_tags < 2) return; + offset += 2; + + /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ + do { + if (offset > length - 12) return; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = GETJOCTET(data[offset]); + tagnum <<= 8; + tagnum += GETJOCTET(data[offset+1]); + } else { + tagnum = GETJOCTET(data[offset+1]); + tagnum <<= 8; + tagnum += GETJOCTET(data[offset]); + } + if (tagnum == 0xA002 || tagnum == 0xA003) { + if (tagnum == 0xA002) + new_value = new_width; /* ExifImageWidth Tag */ + else + new_value = new_height; /* ExifImageHeight Tag */ + if (is_motorola) { + data[offset+2] = 0; /* Format = unsigned long (4 octets) */ + data[offset+3] = 4; + data[offset+4] = 0; /* Number Of Components = 1 */ + data[offset+5] = 0; + data[offset+6] = 0; + data[offset+7] = 1; + data[offset+8] = 0; + data[offset+9] = 0; + data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF); + data[offset+11] = (JOCTET)(new_value & 0xFF); + } else { + data[offset+2] = 4; /* Format = unsigned long (4 octets) */ + data[offset+3] = 0; + data[offset+4] = 1; /* Number Of Components = 1 */ + data[offset+5] = 0; + data[offset+6] = 0; + data[offset+7] = 0; + data[offset+8] = (JOCTET)(new_value & 0xFF); + data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF); + data[offset+10] = 0; + data[offset+11] = 0; + } + } + offset += 12; + } while (--number_of_tags); +} + + +/* Adjust output image parameters as needed. + * + * This must be called after jpeg_copy_critical_parameters() + * and before jpeg_write_coefficients(). + * + * The return value is the set of virtual coefficient arrays to be written + * (either the ones allocated by jtransform_request_workspace, or the + * original source data arrays). The caller will need to pass this value + * to jpeg_write_coefficients(). + */ + +GLOBAL(jvirt_barray_ptr *) +jtransform_adjust_parameters (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info) +{ + /* If force-to-grayscale is requested, adjust destination parameters */ + if (info->force_grayscale) { + /* First, ensure we have YCbCr or grayscale data, and that the source's + * Y channel is full resolution. (No reasonable person would make Y + * be less than full resolution, so actually coping with that case + * isn't worth extra code space. But we check it to avoid crashing.) + */ + if (((dstinfo->jpeg_color_space == JCS_YCbCr && + dstinfo->num_components == 3) || + (dstinfo->jpeg_color_space == JCS_GRAYSCALE && + dstinfo->num_components == 1)) && + srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor && + srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) { + /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed + * properly. Among other things, it sets the target h_samp_factor & + * v_samp_factor to 1, which typically won't match the source. + * We have to preserve the source's quantization table number, however. + */ + int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; + jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); + dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; + } else { + /* Sorry, can't do it */ + ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); + } + } else if (info->num_components == 1) { + /* For a single-component source, we force the destination sampling factors + * to 1x1, with or without force_grayscale. This is useful because some + * decoders choke on grayscale images with other sampling factors. + */ + dstinfo->comp_info[0].h_samp_factor = 1; + dstinfo->comp_info[0].v_samp_factor = 1; + } + + /* Correct the destination's image dimensions as necessary + * for crop and rotate/flip operations. + */ + dstinfo->image_width = info->output_width; + dstinfo->image_height = info->output_height; + + /* Transpose destination image parameters */ + switch (info->transform) { + case JXFORM_TRANSPOSE: + case JXFORM_TRANSVERSE: + case JXFORM_ROT_90: + case JXFORM_ROT_270: + transpose_critical_parameters(dstinfo); + break; + } + + /* Adjust Exif properties */ + if (srcinfo->marker_list != NULL && + srcinfo->marker_list->marker == JPEG_APP0+1 && + srcinfo->marker_list->data_length >= 6 && + GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 && + GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 && + GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 && + GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 && + GETJOCTET(srcinfo->marker_list->data[4]) == 0 && + GETJOCTET(srcinfo->marker_list->data[5]) == 0) { + /* Suppress output of JFIF marker */ + dstinfo->write_JFIF_header = FALSE; + /* Adjust Exif image parameters */ + if (dstinfo->image_width != srcinfo->image_width || + dstinfo->image_height != srcinfo->image_height) + /* Align data segment to start of TIFF structure for parsing */ + adjust_exif_parameters(srcinfo->marker_list->data + 6, + srcinfo->marker_list->data_length - 6, + dstinfo->image_width, dstinfo->image_height); + } + + /* Return the appropriate output data set */ + if (info->workspace_coef_arrays != NULL) + return info->workspace_coef_arrays; + return src_coef_arrays; +} + + +/* Execute the actual transformation, if any. + * + * This must be called *after* jpeg_write_coefficients, because it depends + * on jpeg_write_coefficients to have computed subsidiary values such as + * the per-component width and height fields in the destination object. + * + * Note that some transformations will modify the source data arrays! + */ + +GLOBAL(void) +jtransform_execute_transform (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info) +{ + jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; + + /* Note: conditions tested here should match those in switch statement + * in jtransform_request_workspace() + */ + switch (info->transform) { + case JXFORM_NONE: + if (info->x_crop_offset != 0 || info->y_crop_offset != 0) + do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_FLIP_H: + if (info->y_crop_offset != 0) + do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + else + do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset, + src_coef_arrays); + break; + case JXFORM_FLIP_V: + do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSPOSE: + do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSVERSE: + do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_90: + do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_180: + do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_270: + do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + } +} + +/* jtransform_perfect_transform + * + * Determine whether lossless transformation is perfectly + * possible for a specified image and transformation. + * + * Inputs: + * image_width, image_height: source image dimensions. + * MCU_width, MCU_height: pixel dimensions of MCU. + * transform: transformation identifier. + * Parameter sources from initialized jpeg_struct + * (after reading source header): + * image_width = cinfo.image_width + * image_height = cinfo.image_height + * MCU_width = cinfo.max_h_samp_factor * DCTSIZE + * MCU_height = cinfo.max_v_samp_factor * DCTSIZE + * Result: + * TRUE = perfect transformation possible + * FALSE = perfect transformation not possible + * (may use custom action then) + */ + +GLOBAL(boolean) +jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height, + int MCU_width, int MCU_height, + JXFORM_CODE transform) +{ + boolean result = TRUE; /* initialize TRUE */ + + switch (transform) { + case JXFORM_FLIP_H: + case JXFORM_ROT_270: + if (image_width % (JDIMENSION) MCU_width) + result = FALSE; + break; + case JXFORM_FLIP_V: + case JXFORM_ROT_90: + if (image_height % (JDIMENSION) MCU_height) + result = FALSE; + break; + case JXFORM_TRANSVERSE: + case JXFORM_ROT_180: + if (image_width % (JDIMENSION) MCU_width) + result = FALSE; + if (image_height % (JDIMENSION) MCU_height) + result = FALSE; + break; + } + + return result; +} + +#endif /* TRANSFORMS_SUPPORTED */ + + +/* Setup decompression object to save desired markers in memory. + * This must be called before jpeg_read_header() to have the desired effect. + */ + +GLOBAL(void) +jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) +{ +#ifdef SAVE_MARKERS_SUPPORTED + int m; + + /* Save comments except under NONE option */ + if (option != JCOPYOPT_NONE) { + jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); + } + /* Save all types of APPn markers iff ALL option */ + if (option == JCOPYOPT_ALL) { + for (m = 0; m < 16; m++) + jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); + } +#endif /* SAVE_MARKERS_SUPPORTED */ +} + +/* Copy markers saved in the given source object to the destination object. + * This should be called just after jpeg_start_compress() or + * jpeg_write_coefficients(). + * Note that those routines will have written the SOI, and also the + * JFIF APP0 or Adobe APP14 markers if selected. + */ + +GLOBAL(void) +jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JCOPY_OPTION option) +{ + jpeg_saved_marker_ptr marker; + + /* In the current implementation, we don't actually need to examine the + * option flag here; we just copy everything that got saved. + * But to avoid confusion, we do not output JFIF and Adobe APP14 markers + * if the encoder library already wrote one. + */ + for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { + if (dstinfo->write_JFIF_header && + marker->marker == JPEG_APP0 && + marker->data_length >= 5 && + GETJOCTET(marker->data[0]) == 0x4A && + GETJOCTET(marker->data[1]) == 0x46 && + GETJOCTET(marker->data[2]) == 0x49 && + GETJOCTET(marker->data[3]) == 0x46 && + GETJOCTET(marker->data[4]) == 0) + continue; /* reject duplicate JFIF */ + if (dstinfo->write_Adobe_marker && + marker->marker == JPEG_APP0+14 && + marker->data_length >= 5 && + GETJOCTET(marker->data[0]) == 0x41 && + GETJOCTET(marker->data[1]) == 0x64 && + GETJOCTET(marker->data[2]) == 0x6F && + GETJOCTET(marker->data[3]) == 0x62 && + GETJOCTET(marker->data[4]) == 0x65) + continue; /* reject duplicate Adobe */ +#ifdef NEED_FAR_POINTERS + /* We could use jpeg_write_marker if the data weren't FAR... */ + { + unsigned int i; + jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); + for (i = 0; i < marker->data_length; i++) + jpeg_write_m_byte(dstinfo, marker->data[i]); + } +#else + jpeg_write_marker(dstinfo, marker->marker, + marker->data, marker->data_length); +#endif + } +} diff --git a/rosapps/lib/libjpeg/transupp.h b/rosapps/lib/libjpeg/transupp.h new file mode 100644 index 00000000000..981b1cee7d6 --- /dev/null +++ b/rosapps/lib/libjpeg/transupp.h @@ -0,0 +1,205 @@ +/* + * transupp.h + * + * Copyright (C) 1997-2001, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for image transformation routines and + * other utility code used by the jpegtran sample application. These are + * NOT part of the core JPEG library. But we keep these routines separate + * from jpegtran.c to ease the task of maintaining jpegtran-like programs + * that have other user interfaces. + * + * NOTE: all the routines declared here have very specific requirements + * about when they are to be executed during the reading and writing of the + * source and destination files. See the comments in transupp.c, or see + * jpegtran.c for an example of correct usage. + */ + +/* If you happen not to want the image transform support, disable it here */ +#ifndef TRANSFORMS_SUPPORTED +#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ +#endif + +/* + * Although rotating and flipping data expressed as DCT coefficients is not + * hard, there is an asymmetry in the JPEG format specification for images + * whose dimensions aren't multiples of the iMCU size. The right and bottom + * image edges are padded out to the next iMCU boundary with junk data; but + * no padding is possible at the top and left edges. If we were to flip + * the whole image including the pad data, then pad garbage would become + * visible at the top and/or left, and real pixels would disappear into the + * pad margins --- perhaps permanently, since encoders & decoders may not + * bother to preserve DCT blocks that appear to be completely outside the + * nominal image area. So, we have to exclude any partial iMCUs from the + * basic transformation. + * + * Transpose is the only transformation that can handle partial iMCUs at the + * right and bottom edges completely cleanly. flip_h can flip partial iMCUs + * at the bottom, but leaves any partial iMCUs at the right edge untouched. + * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched. + * The other transforms are defined as combinations of these basic transforms + * and process edge blocks in a way that preserves the equivalence. + * + * The "trim" option causes untransformable partial iMCUs to be dropped; + * this is not strictly lossless, but it usually gives the best-looking + * result for odd-size images. Note that when this option is active, + * the expected mathematical equivalences between the transforms may not hold. + * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim + * followed by -rot 180 -trim trims both edges.) + * + * We also offer a lossless-crop option, which discards data outside a given + * image region but losslessly preserves what is inside. Like the rotate and + * flip transforms, lossless crop is restricted by the JPEG format: the upper + * left corner of the selected region must fall on an iMCU boundary. If this + * does not hold for the given crop parameters, we silently move the upper left + * corner up and/or left to make it so, simultaneously increasing the region + * dimensions to keep the lower right crop corner unchanged. (Thus, the + * output image covers at least the requested region, but may cover more.) + * + * If both crop and a rotate/flip transform are requested, the crop is applied + * last --- that is, the crop region is specified in terms of the destination + * image. + * + * We also offer a "force to grayscale" option, which simply discards the + * chrominance channels of a YCbCr image. This is lossless in the sense that + * the luminance channel is preserved exactly. It's not the same kind of + * thing as the rotate/flip transformations, but it's convenient to handle it + * as part of this package, mainly because the transformation routines have to + * be aware of the option to know how many components to work on. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jtransform_parse_crop_spec jTrParCrop +#define jtransform_request_workspace jTrRequest +#define jtransform_adjust_parameters jTrAdjust +#define jtransform_execute_transform jTrExec +#define jtransform_perfect_transform jTrPerfect +#define jcopy_markers_setup jCMrkSetup +#define jcopy_markers_execute jCMrkExec +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * Codes for supported types of image transformations. + */ + +typedef enum { + JXFORM_NONE, /* no transformation */ + JXFORM_FLIP_H, /* horizontal flip */ + JXFORM_FLIP_V, /* vertical flip */ + JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ + JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ + JXFORM_ROT_90, /* 90-degree clockwise rotation */ + JXFORM_ROT_180, /* 180-degree rotation */ + JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ +} JXFORM_CODE; + +/* + * Codes for crop parameters, which can individually be unspecified, + * positive, or negative. (Negative width or height makes no sense, though.) + */ + +typedef enum { + JCROP_UNSET, + JCROP_POS, + JCROP_NEG +} JCROP_CODE; + +/* + * Transform parameters struct. + * NB: application must not change any elements of this struct after + * calling jtransform_request_workspace. + */ + +typedef struct { + /* Options: set by caller */ + JXFORM_CODE transform; /* image transform operator */ + boolean perfect; /* if TRUE, fail if partial MCUs are requested */ + boolean trim; /* if TRUE, trim partial MCUs as needed */ + boolean force_grayscale; /* if TRUE, convert color image to grayscale */ + boolean crop; /* if TRUE, crop source image */ + + /* Crop parameters: application need not set these unless crop is TRUE. + * These can be filled in by jtransform_parse_crop_spec(). + */ + JDIMENSION crop_width; /* Width of selected region */ + JCROP_CODE crop_width_set; + JDIMENSION crop_height; /* Height of selected region */ + JCROP_CODE crop_height_set; + JDIMENSION crop_xoffset; /* X offset of selected region */ + JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */ + JDIMENSION crop_yoffset; /* Y offset of selected region */ + JCROP_CODE crop_yoffset_set; /* (negative measures from bottom edge) */ + + /* Internal workspace: caller should not touch these */ + int num_components; /* # of components in workspace */ + jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ + JDIMENSION output_width; /* cropped destination dimensions */ + JDIMENSION output_height; + JDIMENSION x_crop_offset; /* destination crop offsets measured in iMCUs */ + JDIMENSION y_crop_offset; + int max_h_samp_factor; /* destination iMCU size */ + int max_v_samp_factor; +} jpeg_transform_info; + + +#if TRANSFORMS_SUPPORTED + +/* Parse a crop specification (written in X11 geometry style) */ +EXTERN(boolean) jtransform_parse_crop_spec + JPP((jpeg_transform_info *info, const char *spec)); +/* Request any required workspace */ +EXTERN(void) jtransform_request_workspace + JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info)); +/* Adjust output image parameters */ +EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); +/* Execute the actual transformation, if any */ +EXTERN(void) jtransform_execute_transform + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); +/* Determine whether lossless transformation is perfectly + * possible for a specified image and transformation. + */ +EXTERN(boolean) jtransform_perfect_transform + JPP((JDIMENSION image_width, JDIMENSION image_height, + int MCU_width, int MCU_height, + JXFORM_CODE transform)); + +/* jtransform_execute_transform used to be called + * jtransform_execute_transformation, but some compilers complain about + * routine names that long. This macro is here to avoid breaking any + * old source code that uses the original name... + */ +#define jtransform_execute_transformation jtransform_execute_transform + +#endif /* TRANSFORMS_SUPPORTED */ + + +/* + * Support for copying optional markers from source to destination file. + */ + +typedef enum { + JCOPYOPT_NONE, /* copy no optional markers */ + JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ + JCOPYOPT_ALL /* copy all optional markers */ +} JCOPY_OPTION; + +#define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ + +/* Setup decompression object to save desired markers in memory */ +EXTERN(void) jcopy_markers_setup + JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); +/* Copy markers saved in the given source object to the destination object */ +EXTERN(void) jcopy_markers_execute + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JCOPY_OPTION option)); diff --git a/rosapps/lib/libjpeg/wrbmp.c b/rosapps/lib/libjpeg/wrbmp.c new file mode 100644 index 00000000000..3283b0f15c2 --- /dev/null +++ b/rosapps/lib/libjpeg/wrbmp.c @@ -0,0 +1,442 @@ +/* + * wrbmp.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in Microsoft "BMP" + * format (MS Windows 3.x and OS/2 1.x flavors). + * Either 8-bit colormapped or 24-bit full-color format can be written. + * No compression is supported. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + * + * This code contributed by James Arthur Boucher. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef BMP_SUPPORTED + + +/* + * To support 12-bit JPEG data, we'd have to scale output down to 8 bits. + * This is not yet implemented. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + +/* + * Since BMP stores scanlines bottom-to-top, we have to invert the image + * from JPEG's top-to-bottom order. To do this, we save the outgoing data + * in a virtual array during put_pixel_row calls, then actually emit the + * BMP file during finish_output. The virtual array contains one JSAMPLE per + * pixel if the output is grayscale or colormapped, three if it is full color. + */ + +/* Private version of data destination object */ + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + boolean is_os2; /* saves the OS2 format request flag */ + + jvirt_sarray_ptr whole_image; /* needed to reverse row order */ + JDIMENSION data_width; /* JSAMPLEs per row */ + JDIMENSION row_width; /* physical width of one row in the BMP file */ + int pad_bytes; /* number of padding bytes needed per row */ + JDIMENSION cur_output_row; /* next row# to write to virtual array */ +} bmp_dest_struct; + +typedef bmp_dest_struct * bmp_dest_ptr; + + +/* Forward declarations */ +LOCAL(void) write_colormap + JPP((j_decompress_ptr cinfo, bmp_dest_ptr dest, + int map_colors, int map_entry_size)); + + +/* + * Write some pixel data. + * In this module rows_supplied will always be 1. + */ + +METHODDEF(void) +put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* This version is for writing 24-bit pixels */ +{ + bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + int pad; + + /* Access next row in virtual array */ + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->whole_image, + dest->cur_output_row, (JDIMENSION) 1, TRUE); + dest->cur_output_row++; + + /* Transfer data. Note destination values must be in BGR order + * (even though Microsoft's own documents say the opposite). + */ + inptr = dest->pub.buffer[0]; + outptr = image_ptr[0]; + for (col = cinfo->output_width; col > 0; col--) { + outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ + outptr[1] = *inptr++; + outptr[0] = *inptr++; + outptr += 3; + } + + /* Zero out the pad bytes. */ + pad = dest->pad_bytes; + while (--pad >= 0) + *outptr++ = 0; +} + +METHODDEF(void) +put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* This version is for grayscale OR quantized color output */ +{ + bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + int pad; + + /* Access next row in virtual array */ + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->whole_image, + dest->cur_output_row, (JDIMENSION) 1, TRUE); + dest->cur_output_row++; + + /* Transfer data. */ + inptr = dest->pub.buffer[0]; + outptr = image_ptr[0]; + for (col = cinfo->output_width; col > 0; col--) { + *outptr++ = *inptr++; /* can omit GETJSAMPLE() safely */ + } + + /* Zero out the pad bytes. */ + pad = dest->pad_bytes; + while (--pad >= 0) + *outptr++ = 0; +} + + +/* + * Startup: normally writes the file header. + * In this module we may as well postpone everything until finish_output. + */ + +METHODDEF(void) +start_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + /* no work here */ +} + + +/* + * Finish up at the end of the file. + * + * Here is where we really output the BMP file. + * + * First, routines to write the Windows and OS/2 variants of the file header. + */ + +LOCAL(void) +write_bmp_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) +/* Write a Windows-style BMP file header, including colormap if needed */ +{ + char bmpfileheader[14]; + char bmpinfoheader[40]; +#define PUT_2B(array,offset,value) \ + (array[offset] = (char) ((value) & 0xFF), \ + array[offset+1] = (char) (((value) >> 8) & 0xFF)) +#define PUT_4B(array,offset,value) \ + (array[offset] = (char) ((value) & 0xFF), \ + array[offset+1] = (char) (((value) >> 8) & 0xFF), \ + array[offset+2] = (char) (((value) >> 16) & 0xFF), \ + array[offset+3] = (char) (((value) >> 24) & 0xFF)) + INT32 headersize, bfSize; + int bits_per_pixel, cmap_entries; + + /* Compute colormap size and total file size */ + if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) { + /* Colormapped RGB */ + bits_per_pixel = 8; + cmap_entries = 256; + } else { + /* Unquantized, full color RGB */ + bits_per_pixel = 24; + cmap_entries = 0; + } + } else { + /* Grayscale output. We need to fake a 256-entry colormap. */ + bits_per_pixel = 8; + cmap_entries = 256; + } + /* File size */ + headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */ + bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; + + /* Set unused fields of header to 0 */ + MEMZERO(bmpfileheader, SIZEOF(bmpfileheader)); + MEMZERO(bmpinfoheader, SIZEOF(bmpinfoheader)); + + /* Fill the file header */ + bmpfileheader[0] = 0x42; /* first 2 bytes are ASCII 'B', 'M' */ + bmpfileheader[1] = 0x4D; + PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ + /* we leave bfReserved1 & bfReserved2 = 0 */ + PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ + + /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */ + PUT_2B(bmpinfoheader, 0, 40); /* biSize */ + PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */ + PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */ + PUT_2B(bmpinfoheader, 12, 1); /* biPlanes - must be 1 */ + PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */ + /* we leave biCompression = 0, for none */ + /* we leave biSizeImage = 0; this is correct for uncompressed data */ + if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */ + PUT_4B(bmpinfoheader, 24, (INT32) (cinfo->X_density*100)); /* XPels/M */ + PUT_4B(bmpinfoheader, 28, (INT32) (cinfo->Y_density*100)); /* XPels/M */ + } + PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */ + /* we leave biClrImportant = 0 */ + + if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) + ERREXIT(cinfo, JERR_FILE_WRITE); + if (JFWRITE(dest->pub.output_file, bmpinfoheader, 40) != (size_t) 40) + ERREXIT(cinfo, JERR_FILE_WRITE); + + if (cmap_entries > 0) + write_colormap(cinfo, dest, cmap_entries, 4); +} + + +LOCAL(void) +write_os2_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) +/* Write an OS2-style BMP file header, including colormap if needed */ +{ + char bmpfileheader[14]; + char bmpcoreheader[12]; + INT32 headersize, bfSize; + int bits_per_pixel, cmap_entries; + + /* Compute colormap size and total file size */ + if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) { + /* Colormapped RGB */ + bits_per_pixel = 8; + cmap_entries = 256; + } else { + /* Unquantized, full color RGB */ + bits_per_pixel = 24; + cmap_entries = 0; + } + } else { + /* Grayscale output. We need to fake a 256-entry colormap. */ + bits_per_pixel = 8; + cmap_entries = 256; + } + /* File size */ + headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */ + bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; + + /* Set unused fields of header to 0 */ + MEMZERO(bmpfileheader, SIZEOF(bmpfileheader)); + MEMZERO(bmpcoreheader, SIZEOF(bmpcoreheader)); + + /* Fill the file header */ + bmpfileheader[0] = 0x42; /* first 2 bytes are ASCII 'B', 'M' */ + bmpfileheader[1] = 0x4D; + PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ + /* we leave bfReserved1 & bfReserved2 = 0 */ + PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ + + /* Fill the info header (Microsoft calls this a BITMAPCOREHEADER) */ + PUT_2B(bmpcoreheader, 0, 12); /* bcSize */ + PUT_2B(bmpcoreheader, 4, cinfo->output_width); /* bcWidth */ + PUT_2B(bmpcoreheader, 6, cinfo->output_height); /* bcHeight */ + PUT_2B(bmpcoreheader, 8, 1); /* bcPlanes - must be 1 */ + PUT_2B(bmpcoreheader, 10, bits_per_pixel); /* bcBitCount */ + + if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) + ERREXIT(cinfo, JERR_FILE_WRITE); + if (JFWRITE(dest->pub.output_file, bmpcoreheader, 12) != (size_t) 12) + ERREXIT(cinfo, JERR_FILE_WRITE); + + if (cmap_entries > 0) + write_colormap(cinfo, dest, cmap_entries, 3); +} + + +/* + * Write the colormap. + * Windows uses BGR0 map entries; OS/2 uses BGR entries. + */ + +LOCAL(void) +write_colormap (j_decompress_ptr cinfo, bmp_dest_ptr dest, + int map_colors, int map_entry_size) +{ + JSAMPARRAY colormap = cinfo->colormap; + int num_colors = cinfo->actual_number_of_colors; + FILE * outfile = dest->pub.output_file; + int i; + + if (colormap != NULL) { + if (cinfo->out_color_components == 3) { + /* Normal case with RGB colormap */ + for (i = 0; i < num_colors; i++) { + putc(GETJSAMPLE(colormap[2][i]), outfile); + putc(GETJSAMPLE(colormap[1][i]), outfile); + putc(GETJSAMPLE(colormap[0][i]), outfile); + if (map_entry_size == 4) + putc(0, outfile); + } + } else { + /* Grayscale colormap (only happens with grayscale quantization) */ + for (i = 0; i < num_colors; i++) { + putc(GETJSAMPLE(colormap[0][i]), outfile); + putc(GETJSAMPLE(colormap[0][i]), outfile); + putc(GETJSAMPLE(colormap[0][i]), outfile); + if (map_entry_size == 4) + putc(0, outfile); + } + } + } else { + /* If no colormap, must be grayscale data. Generate a linear "map". */ + for (i = 0; i < 256; i++) { + putc(i, outfile); + putc(i, outfile); + putc(i, outfile); + if (map_entry_size == 4) + putc(0, outfile); + } + } + /* Pad colormap with zeros to ensure specified number of colormap entries */ + if (i > map_colors) + ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i); + for (; i < map_colors; i++) { + putc(0, outfile); + putc(0, outfile); + putc(0, outfile); + if (map_entry_size == 4) + putc(0, outfile); + } +} + + +METHODDEF(void) +finish_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; + register FILE * outfile = dest->pub.output_file; + JSAMPARRAY image_ptr; + register JSAMPROW data_ptr; + JDIMENSION row; + register JDIMENSION col; + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + + /* Write the header and colormap */ + if (dest->is_os2) + write_os2_header(cinfo, dest); + else + write_bmp_header(cinfo, dest); + + /* Write the file body from our virtual array */ + for (row = cinfo->output_height; row > 0; row--) { + if (progress != NULL) { + progress->pub.pass_counter = (long) (cinfo->output_height - row); + progress->pub.pass_limit = (long) cinfo->output_height; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->whole_image, row-1, (JDIMENSION) 1, FALSE); + data_ptr = image_ptr[0]; + for (col = dest->row_width; col > 0; col--) { + putc(GETJSAMPLE(*data_ptr), outfile); + data_ptr++; + } + } + if (progress != NULL) + progress->completed_extra_passes++; + + /* Make sure we wrote the output file OK */ + fflush(outfile); + if (ferror(outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for BMP format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_bmp (j_decompress_ptr cinfo, boolean is_os2) +{ + bmp_dest_ptr dest; + JDIMENSION row_width; + + /* Create module interface object, fill in method pointers */ + dest = (bmp_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(bmp_dest_struct)); + dest->pub.start_output = start_output_bmp; + dest->pub.finish_output = finish_output_bmp; + dest->is_os2 = is_os2; + + if (cinfo->out_color_space == JCS_GRAYSCALE) { + dest->pub.put_pixel_rows = put_gray_rows; + } else if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) + dest->pub.put_pixel_rows = put_gray_rows; + else + dest->pub.put_pixel_rows = put_pixel_rows; + } else { + ERREXIT(cinfo, JERR_BMP_COLORSPACE); + } + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Determine width of rows in the BMP file (padded to 4-byte boundary). */ + row_width = cinfo->output_width * cinfo->output_components; + dest->data_width = row_width; + while ((row_width & 3) != 0) row_width++; + dest->row_width = row_width; + dest->pad_bytes = (int) (row_width - dest->data_width); + + /* Allocate space for inversion array, prepare for write pass */ + dest->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + row_width, cinfo->output_height, (JDIMENSION) 1); + dest->cur_output_row = 0; + if (cinfo->progress != NULL) { + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + progress->total_extra_passes++; /* count file input as separate pass */ + } + + /* Create decompressor output buffer. */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, row_width, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + + return (djpeg_dest_ptr) dest; +} + +#endif /* BMP_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/wrgif.c b/rosapps/lib/libjpeg/wrgif.c new file mode 100644 index 00000000000..5fe83283919 --- /dev/null +++ b/rosapps/lib/libjpeg/wrgif.c @@ -0,0 +1,399 @@ +/* + * wrgif.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in GIF format. + * + ************************************************************************** + * NOTE: to avoid entanglements with Unisys' patent on LZW compression, * + * this code has been modified to output "uncompressed GIF" files. * + * There is no trace of the LZW algorithm in this file. * + ************************************************************************** + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + */ + +/* + * This code is loosely based on ppmtogif from the PBMPLUS distribution + * of Feb. 1991. That file contains the following copyright notice: + * Based on GIFENCODE by David Rowley . + * Lempel-Ziv compression based on "compress" by Spencer W. Thomas et al. + * Copyright (C) 1989 by Jef Poskanzer. + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. This software is provided "as is" without express or + * implied warranty. + * + * We are also required to state that + * "The Graphics Interchange Format(c) is the Copyright property of + * CompuServe Incorporated. GIF(sm) is a Service Mark property of + * CompuServe Incorporated." + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef GIF_SUPPORTED + + +/* Private version of data destination object */ + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + j_decompress_ptr cinfo; /* back link saves passing separate parm */ + + /* State for packing variable-width codes into a bitstream */ + int n_bits; /* current number of bits/code */ + int maxcode; /* maximum code, given n_bits */ + INT32 cur_accum; /* holds bits not yet output */ + int cur_bits; /* # of bits in cur_accum */ + + /* State for GIF code assignment */ + int ClearCode; /* clear code (doesn't change) */ + int EOFCode; /* EOF code (ditto) */ + int code_counter; /* counts output symbols */ + + /* GIF data packet construction buffer */ + int bytesinpkt; /* # of bytes in current packet */ + char packetbuf[256]; /* workspace for accumulating packet */ + +} gif_dest_struct; + +typedef gif_dest_struct * gif_dest_ptr; + +/* Largest value that will fit in N bits */ +#define MAXCODE(n_bits) ((1 << (n_bits)) - 1) + + +/* + * Routines to package finished data bytes into GIF data blocks. + * A data block consists of a count byte (1..255) and that many data bytes. + */ + +LOCAL(void) +flush_packet (gif_dest_ptr dinfo) +/* flush any accumulated data */ +{ + if (dinfo->bytesinpkt > 0) { /* never write zero-length packet */ + dinfo->packetbuf[0] = (char) dinfo->bytesinpkt++; + if (JFWRITE(dinfo->pub.output_file, dinfo->packetbuf, dinfo->bytesinpkt) + != (size_t) dinfo->bytesinpkt) + ERREXIT(dinfo->cinfo, JERR_FILE_WRITE); + dinfo->bytesinpkt = 0; + } +} + + +/* Add a character to current packet; flush to disk if necessary */ +#define CHAR_OUT(dinfo,c) \ + { (dinfo)->packetbuf[++(dinfo)->bytesinpkt] = (char) (c); \ + if ((dinfo)->bytesinpkt >= 255) \ + flush_packet(dinfo); \ + } + + +/* Routine to convert variable-width codes into a byte stream */ + +LOCAL(void) +output (gif_dest_ptr dinfo, int code) +/* Emit a code of n_bits bits */ +/* Uses cur_accum and cur_bits to reblock into 8-bit bytes */ +{ + dinfo->cur_accum |= ((INT32) code) << dinfo->cur_bits; + dinfo->cur_bits += dinfo->n_bits; + + while (dinfo->cur_bits >= 8) { + CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF); + dinfo->cur_accum >>= 8; + dinfo->cur_bits -= 8; + } +} + + +/* The pseudo-compression algorithm. + * + * In this module we simply output each pixel value as a separate symbol; + * thus, no compression occurs. In fact, there is expansion of one bit per + * pixel, because we use a symbol width one bit wider than the pixel width. + * + * GIF ordinarily uses variable-width symbols, and the decoder will expect + * to ratchet up the symbol width after a fixed number of symbols. + * To simplify the logic and keep the expansion penalty down, we emit a + * GIF Clear code to reset the decoder just before the width would ratchet up. + * Thus, all the symbols in the output file will have the same bit width. + * Note that emitting the Clear codes at the right times is a mere matter of + * counting output symbols and is in no way dependent on the LZW patent. + * + * With a small basic pixel width (low color count), Clear codes will be + * needed very frequently, causing the file to expand even more. So this + * simplistic approach wouldn't work too well on bilevel images, for example. + * But for output of JPEG conversions the pixel width will usually be 8 bits + * (129 to 256 colors), so the overhead added by Clear symbols is only about + * one symbol in every 256. + */ + +LOCAL(void) +compress_init (gif_dest_ptr dinfo, int i_bits) +/* Initialize pseudo-compressor */ +{ + /* init all the state variables */ + dinfo->n_bits = i_bits; + dinfo->maxcode = MAXCODE(dinfo->n_bits); + dinfo->ClearCode = (1 << (i_bits - 1)); + dinfo->EOFCode = dinfo->ClearCode + 1; + dinfo->code_counter = dinfo->ClearCode + 2; + /* init output buffering vars */ + dinfo->bytesinpkt = 0; + dinfo->cur_accum = 0; + dinfo->cur_bits = 0; + /* GIF specifies an initial Clear code */ + output(dinfo, dinfo->ClearCode); +} + + +LOCAL(void) +compress_pixel (gif_dest_ptr dinfo, int c) +/* Accept and "compress" one pixel value. + * The given value must be less than n_bits wide. + */ +{ + /* Output the given pixel value as a symbol. */ + output(dinfo, c); + /* Issue Clear codes often enough to keep the reader from ratcheting up + * its symbol size. + */ + if (dinfo->code_counter < dinfo->maxcode) { + dinfo->code_counter++; + } else { + output(dinfo, dinfo->ClearCode); + dinfo->code_counter = dinfo->ClearCode + 2; /* reset the counter */ + } +} + + +LOCAL(void) +compress_term (gif_dest_ptr dinfo) +/* Clean up at end */ +{ + /* Send an EOF code */ + output(dinfo, dinfo->EOFCode); + /* Flush the bit-packing buffer */ + if (dinfo->cur_bits > 0) { + CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF); + } + /* Flush the packet buffer */ + flush_packet(dinfo); +} + + +/* GIF header construction */ + + +LOCAL(void) +put_word (gif_dest_ptr dinfo, unsigned int w) +/* Emit a 16-bit word, LSB first */ +{ + putc(w & 0xFF, dinfo->pub.output_file); + putc((w >> 8) & 0xFF, dinfo->pub.output_file); +} + + +LOCAL(void) +put_3bytes (gif_dest_ptr dinfo, int val) +/* Emit 3 copies of same byte value --- handy subr for colormap construction */ +{ + putc(val, dinfo->pub.output_file); + putc(val, dinfo->pub.output_file); + putc(val, dinfo->pub.output_file); +} + + +LOCAL(void) +emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap) +/* Output the GIF file header, including color map */ +/* If colormap==NULL, synthesize a gray-scale colormap */ +{ + int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte; + int cshift = dinfo->cinfo->data_precision - 8; + int i; + + if (num_colors > 256) + ERREXIT1(dinfo->cinfo, JERR_TOO_MANY_COLORS, num_colors); + /* Compute bits/pixel and related values */ + BitsPerPixel = 1; + while (num_colors > (1 << BitsPerPixel)) + BitsPerPixel++; + ColorMapSize = 1 << BitsPerPixel; + if (BitsPerPixel <= 1) + InitCodeSize = 2; + else + InitCodeSize = BitsPerPixel; + /* + * Write the GIF header. + * Note that we generate a plain GIF87 header for maximum compatibility. + */ + putc('G', dinfo->pub.output_file); + putc('I', dinfo->pub.output_file); + putc('F', dinfo->pub.output_file); + putc('8', dinfo->pub.output_file); + putc('7', dinfo->pub.output_file); + putc('a', dinfo->pub.output_file); + /* Write the Logical Screen Descriptor */ + put_word(dinfo, (unsigned int) dinfo->cinfo->output_width); + put_word(dinfo, (unsigned int) dinfo->cinfo->output_height); + FlagByte = 0x80; /* Yes, there is a global color table */ + FlagByte |= (BitsPerPixel-1) << 4; /* color resolution */ + FlagByte |= (BitsPerPixel-1); /* size of global color table */ + putc(FlagByte, dinfo->pub.output_file); + putc(0, dinfo->pub.output_file); /* Background color index */ + putc(0, dinfo->pub.output_file); /* Reserved (aspect ratio in GIF89) */ + /* Write the Global Color Map */ + /* If the color map is more than 8 bits precision, */ + /* we reduce it to 8 bits by shifting */ + for (i=0; i < ColorMapSize; i++) { + if (i < num_colors) { + if (colormap != NULL) { + if (dinfo->cinfo->out_color_space == JCS_RGB) { + /* Normal case: RGB color map */ + putc(GETJSAMPLE(colormap[0][i]) >> cshift, dinfo->pub.output_file); + putc(GETJSAMPLE(colormap[1][i]) >> cshift, dinfo->pub.output_file); + putc(GETJSAMPLE(colormap[2][i]) >> cshift, dinfo->pub.output_file); + } else { + /* Grayscale "color map": possible if quantizing grayscale image */ + put_3bytes(dinfo, GETJSAMPLE(colormap[0][i]) >> cshift); + } + } else { + /* Create a gray-scale map of num_colors values, range 0..255 */ + put_3bytes(dinfo, (i * 255 + (num_colors-1)/2) / (num_colors-1)); + } + } else { + /* fill out the map to a power of 2 */ + put_3bytes(dinfo, 0); + } + } + /* Write image separator and Image Descriptor */ + putc(',', dinfo->pub.output_file); /* separator */ + put_word(dinfo, 0); /* left/top offset */ + put_word(dinfo, 0); + put_word(dinfo, (unsigned int) dinfo->cinfo->output_width); /* image size */ + put_word(dinfo, (unsigned int) dinfo->cinfo->output_height); + /* flag byte: not interlaced, no local color map */ + putc(0x00, dinfo->pub.output_file); + /* Write Initial Code Size byte */ + putc(InitCodeSize, dinfo->pub.output_file); + + /* Initialize for "compression" of image data */ + compress_init(dinfo, InitCodeSize+1); +} + + +/* + * Startup: write the file header. + */ + +METHODDEF(void) +start_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + gif_dest_ptr dest = (gif_dest_ptr) dinfo; + + if (cinfo->quantize_colors) + emit_header(dest, cinfo->actual_number_of_colors, cinfo->colormap); + else + emit_header(dest, 256, (JSAMPARRAY) NULL); +} + + +/* + * Write some pixel data. + * In this module rows_supplied will always be 1. + */ + +METHODDEF(void) +put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + gif_dest_ptr dest = (gif_dest_ptr) dinfo; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + for (col = cinfo->output_width; col > 0; col--) { + compress_pixel(dest, GETJSAMPLE(*ptr++)); + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + gif_dest_ptr dest = (gif_dest_ptr) dinfo; + + /* Flush "compression" mechanism */ + compress_term(dest); + /* Write a zero-length data block to end the series */ + putc(0, dest->pub.output_file); + /* Write the GIF terminator mark */ + putc(';', dest->pub.output_file); + /* Make sure we wrote the output file OK */ + fflush(dest->pub.output_file); + if (ferror(dest->pub.output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for GIF format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_gif (j_decompress_ptr cinfo) +{ + gif_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (gif_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(gif_dest_struct)); + dest->cinfo = cinfo; /* make back link for subroutines */ + dest->pub.start_output = start_output_gif; + dest->pub.put_pixel_rows = put_pixel_rows; + dest->pub.finish_output = finish_output_gif; + + if (cinfo->out_color_space != JCS_GRAYSCALE && + cinfo->out_color_space != JCS_RGB) + ERREXIT(cinfo, JERR_GIF_COLORSPACE); + + /* Force quantization if color or if > 8 bits input */ + if (cinfo->out_color_space != JCS_GRAYSCALE || cinfo->data_precision > 8) { + /* Force quantization to at most 256 colors */ + cinfo->quantize_colors = TRUE; + if (cinfo->desired_number_of_colors > 256) + cinfo->desired_number_of_colors = 256; + } + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + if (cinfo->output_components != 1) /* safety check: just one component? */ + ERREXIT(cinfo, JERR_GIF_BUG); + + /* Create decompressor output buffer. */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->output_width, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + + return (djpeg_dest_ptr) dest; +} + +#endif /* GIF_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/wrjpgcom.c b/rosapps/lib/libjpeg/wrjpgcom.c new file mode 100644 index 00000000000..8c04b055120 --- /dev/null +++ b/rosapps/lib/libjpeg/wrjpgcom.c @@ -0,0 +1,583 @@ +/* + * wrjpgcom.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a very simple stand-alone application that inserts + * user-supplied text as a COM (comment) marker in a JFIF file. + * This may be useful as an example of the minimum logic needed to parse + * JPEG markers. + */ + +#define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */ +#include "jinclude.h" /* get auto-config symbols, */ + +#ifndef HAVE_STDLIB_H /* should declare malloc() */ +extern void * malloc (); +#endif +#include /* to declare isupper(), tolower() */ +#ifdef USE_SETMODE +#include /* to declare setmode()'s parameter macros */ +/* If you have setmode() but not , just delete this line: */ +#include /* to declare setmode() */ +#endif + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define WRITE_BINARY "w" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define WRITE_BINARY "wb", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#define WRITE_BINARY "wb" +#endif +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#ifdef VMS +#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ +#else +#define EXIT_SUCCESS 0 +#endif +#endif + +/* Reduce this value if your malloc() can't allocate blocks up to 64K. + * On DOS, compiling in large model is usually a better solution. + */ + +#ifndef MAX_COM_LENGTH +#define MAX_COM_LENGTH 65000L /* must be <= 65533 in any case */ +#endif + + +/* + * These macros are used to read the input file and write the output file. + * To reuse this code in another application, you might need to change these. + */ + +static FILE * infile; /* input JPEG file */ + +/* Return next input byte, or EOF if no more */ +#define NEXTBYTE() getc(infile) + +static FILE * outfile; /* output JPEG file */ + +/* Emit an output byte */ +#define PUTBYTE(x) putc((x), outfile) + + +/* Error exit handler */ +#define ERREXIT(msg) (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE)) + + +/* Read one byte, testing for EOF */ +static int +read_1_byte (void) +{ + int c; + + c = NEXTBYTE(); + if (c == EOF) + ERREXIT("Premature EOF in JPEG file"); + return c; +} + +/* Read 2 bytes, convert to unsigned int */ +/* All 2-byte quantities in JPEG markers are MSB first */ +static unsigned int +read_2_bytes (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + if (c1 == EOF) + ERREXIT("Premature EOF in JPEG file"); + c2 = NEXTBYTE(); + if (c2 == EOF) + ERREXIT("Premature EOF in JPEG file"); + return (((unsigned int) c1) << 8) + ((unsigned int) c2); +} + + +/* Routines to write data to output file */ + +static void +write_1_byte (int c) +{ + PUTBYTE(c); +} + +static void +write_2_bytes (unsigned int val) +{ + PUTBYTE((val >> 8) & 0xFF); + PUTBYTE(val & 0xFF); +} + +static void +write_marker (int marker) +{ + PUTBYTE(0xFF); + PUTBYTE(marker); +} + +static void +copy_rest_of_file (void) +{ + int c; + + while ((c = NEXTBYTE()) != EOF) + PUTBYTE(c); +} + + +/* + * JPEG markers consist of one or more 0xFF bytes, followed by a marker + * code byte (which is not an FF). Here are the marker codes of interest + * in this program. (See jdmarker.c for a more complete list.) + */ + +#define M_SOF0 0xC0 /* Start Of Frame N */ +#define M_SOF1 0xC1 /* N indicates which compression process */ +#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */ +#define M_EOI 0xD9 /* End Of Image (end of datastream) */ +#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ +#define M_COM 0xFE /* COMment */ + + +/* + * Find the next JPEG marker and return its marker code. + * We expect at least one FF byte, possibly more if the compressor used FFs + * to pad the file. (Padding FFs will NOT be replicated in the output file.) + * There could also be non-FF garbage between markers. The treatment of such + * garbage is unspecified; we choose to skip over it but emit a warning msg. + * NB: this routine must not be used after seeing SOS marker, since it will + * not deal correctly with FF/00 sequences in the compressed image data... + */ + +static int +next_marker (void) +{ + int c; + int discarded_bytes = 0; + + /* Find 0xFF byte; count and skip any non-FFs. */ + c = read_1_byte(); + while (c != 0xFF) { + discarded_bytes++; + c = read_1_byte(); + } + /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs + * are legal as pad bytes, so don't count them in discarded_bytes. + */ + do { + c = read_1_byte(); + } while (c == 0xFF); + + if (discarded_bytes != 0) { + fprintf(stderr, "Warning: garbage data found in JPEG file\n"); + } + + return c; +} + + +/* + * Read the initial marker, which should be SOI. + * For a JFIF file, the first two bytes of the file should be literally + * 0xFF M_SOI. To be more general, we could use next_marker, but if the + * input file weren't actually JPEG at all, next_marker might read the whole + * file and then return a misleading error message... + */ + +static int +first_marker (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + c2 = NEXTBYTE(); + if (c1 != 0xFF || c2 != M_SOI) + ERREXIT("Not a JPEG file"); + return c2; +} + + +/* + * Most types of marker are followed by a variable-length parameter segment. + * This routine skips over the parameters for any marker we don't otherwise + * want to process. + * Note that we MUST skip the parameter segment explicitly in order not to + * be fooled by 0xFF bytes that might appear within the parameter segment; + * such bytes do NOT introduce new markers. + */ + +static void +copy_variable (void) +/* Copy an unknown or uninteresting variable-length marker */ +{ + unsigned int length; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + write_2_bytes(length); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + /* Skip over the remaining bytes */ + while (length > 0) { + write_1_byte(read_1_byte()); + length--; + } +} + +static void +skip_variable (void) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + unsigned int length; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + /* Skip over the remaining bytes */ + while (length > 0) { + (void) read_1_byte(); + length--; + } +} + + +/* + * Parse the marker stream until SOFn or EOI is seen; + * copy data to output, but discard COM markers unless keep_COM is true. + */ + +static int +scan_JPEG_header (int keep_COM) +{ + int marker; + + /* Expect SOI at start of file */ + if (first_marker() != M_SOI) + ERREXIT("Expected SOI marker first"); + write_marker(M_SOI); + + /* Scan miscellaneous markers until we reach SOFn. */ + for (;;) { + marker = next_marker(); + switch (marker) { + /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be, + * treated as SOFn. C4 in particular is actually DHT. + */ + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + case M_SOF2: /* Progressive, Huffman */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_SOF9: /* Extended sequential, arithmetic */ + case M_SOF10: /* Progressive, arithmetic */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + return marker; + + case M_SOS: /* should not see compressed data before SOF */ + ERREXIT("SOS without prior SOFn"); + break; + + case M_EOI: /* in case it's a tables-only JPEG stream */ + return marker; + + case M_COM: /* Existing COM: conditionally discard */ + if (keep_COM) { + write_marker(marker); + copy_variable(); + } else { + skip_variable(); + } + break; + + default: /* Anything else just gets copied */ + write_marker(marker); + copy_variable(); /* we assume it has a parameter count... */ + break; + } + } /* end loop */ +} + + +/* Command line parsing code */ + +static const char * progname; /* program name for error messages */ + + +static void +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "wrjpgcom inserts a textual comment in a JPEG file.\n"); + fprintf(stderr, "You can add to or replace any existing comment(s).\n"); + + fprintf(stderr, "Usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -replace Delete any existing comments\n"); + fprintf(stderr, " -comment \"text\" Insert comment with given text\n"); + fprintf(stderr, " -cfile name Read comment from named file\n"); + fprintf(stderr, "Notice that you must put quotes around the comment text\n"); + fprintf(stderr, "when you use -comment.\n"); + fprintf(stderr, "If you do not give either -comment or -cfile on the command line,\n"); + fprintf(stderr, "then the comment text is read from standard input.\n"); + fprintf(stderr, "It can be multiple lines, up to %u characters total.\n", + (unsigned int) MAX_COM_LENGTH); +#ifndef TWO_FILE_COMMANDLINE + fprintf(stderr, "You must specify an input JPEG file name when supplying\n"); + fprintf(stderr, "comment text from standard input.\n"); +#endif + + exit(EXIT_FAILURE); +} + + +static int +keymatch (char * arg, const char * keyword, int minchars) +/* Case-insensitive matching of (possibly abbreviated) keyword switches. */ +/* keyword is the constant keyword (must be lower case already), */ +/* minchars is length of minimum legal abbreviation. */ +{ + register int ca, ck; + register int nmatched = 0; + + while ((ca = *arg++) != '\0') { + if ((ck = *keyword++) == '\0') + return 0; /* arg longer than keyword, no good */ + if (isupper(ca)) /* force arg to lcase (assume ck is already) */ + ca = tolower(ca); + if (ca != ck) + return 0; /* no good */ + nmatched++; /* count matched characters */ + } + /* reached end of argument; fail if it's too short for unique abbrev */ + if (nmatched < minchars) + return 0; + return 1; /* A-OK */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + int argn; + char * arg; + int keep_COM = 1; + char * comment_arg = NULL; + FILE * comment_file = NULL; + unsigned int comment_length = 0; + int marker; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "wrjpgcom"; /* in case C library doesn't provide it */ + + /* Parse switches, if any */ + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (arg[0] != '-') + break; /* not switch, must be file name */ + arg++; /* advance over '-' */ + if (keymatch(arg, "replace", 1)) { + keep_COM = 0; + } else if (keymatch(arg, "cfile", 2)) { + if (++argn >= argc) usage(); + if ((comment_file = fopen(argv[argn], "r")) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + } else if (keymatch(arg, "comment", 1)) { + if (++argn >= argc) usage(); + comment_arg = argv[argn]; + /* If the comment text starts with '"', then we are probably running + * under MS-DOG and must parse out the quoted string ourselves. Sigh. + */ + if (comment_arg[0] == '"') { + comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); + if (comment_arg == NULL) + ERREXIT("Insufficient memory"); + strcpy(comment_arg, argv[argn]+1); + for (;;) { + comment_length = (unsigned int) strlen(comment_arg); + if (comment_length > 0 && comment_arg[comment_length-1] == '"') { + comment_arg[comment_length-1] = '\0'; /* zap terminating quote */ + break; + } + if (++argn >= argc) + ERREXIT("Missing ending quote mark"); + strcat(comment_arg, " "); + strcat(comment_arg, argv[argn]); + } + } + comment_length = (unsigned int) strlen(comment_arg); + } else + usage(); + } + + /* Cannot use both -comment and -cfile. */ + if (comment_arg != NULL && comment_file != NULL) + usage(); + /* If there is neither -comment nor -cfile, we will read the comment text + * from stdin; in this case there MUST be an input JPEG file name. + */ + if (comment_arg == NULL && comment_file == NULL && argn >= argc) + usage(); + + /* Open the input file. */ + if (argn < argc) { + if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdin), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open stdin\n", progname); + exit(EXIT_FAILURE); + } +#else + infile = stdin; +#endif + } + + /* Open the output file. */ +#ifdef TWO_FILE_COMMANDLINE + /* Must have explicit output file name */ + if (argn != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + if ((outfile = fopen(argv[argn+1], WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn+1]); + exit(EXIT_FAILURE); + } +#else + /* Unix style: expect zero or one file name */ + if (argn < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } + /* default output file is stdout */ +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdout), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((outfile = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open stdout\n", progname); + exit(EXIT_FAILURE); + } +#else + outfile = stdout; +#endif +#endif /* TWO_FILE_COMMANDLINE */ + + /* Collect comment text from comment_file or stdin, if necessary */ + if (comment_arg == NULL) { + FILE * src_file; + int c; + + comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); + if (comment_arg == NULL) + ERREXIT("Insufficient memory"); + comment_length = 0; + src_file = (comment_file != NULL ? comment_file : stdin); + while ((c = getc(src_file)) != EOF) { + if (comment_length >= (unsigned int) MAX_COM_LENGTH) { + fprintf(stderr, "Comment text may not exceed %u bytes\n", + (unsigned int) MAX_COM_LENGTH); + exit(EXIT_FAILURE); + } + comment_arg[comment_length++] = (char) c; + } + if (comment_file != NULL) + fclose(comment_file); + } + + /* Copy JPEG headers until SOFn marker; + * we will insert the new comment marker just before SOFn. + * This (a) causes the new comment to appear after, rather than before, + * existing comments; and (b) ensures that comments come after any JFIF + * or JFXX markers, as required by the JFIF specification. + */ + marker = scan_JPEG_header(keep_COM); + /* Insert the new COM marker, but only if nonempty text has been supplied */ + if (comment_length > 0) { + write_marker(M_COM); + write_2_bytes(comment_length + 2); + while (comment_length > 0) { + write_1_byte(*comment_arg++); + comment_length--; + } + } + /* Duplicate the remainder of the source file. + * Note that any COM markers occuring after SOF will not be touched. + */ + write_marker(marker); + copy_rest_of_file(); + + /* All done. */ + exit(EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/rosapps/lib/libjpeg/wrppm.c b/rosapps/lib/libjpeg/wrppm.c new file mode 100644 index 00000000000..6c6d908817c --- /dev/null +++ b/rosapps/lib/libjpeg/wrppm.c @@ -0,0 +1,268 @@ +/* + * wrppm.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in PPM/PGM format. + * The extended 2-byte-per-sample raw PPM/PGM formats are supported. + * The PBMPLUS library is NOT required to compile this software + * (but it is highly useful as a set of PPM image manipulation programs). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef PPM_SUPPORTED + + +/* + * For 12-bit JPEG data, we either downscale the values to 8 bits + * (to write standard byte-per-sample PPM/PGM files), or output + * nonstandard word-per-sample PPM/PGM files. Downscaling is done + * if PPM_NORAWWORD is defined (this can be done in the Makefile + * or in jconfig.h). + * (When the core library supports data precision reduction, a cleaner + * implementation will be to ask for that instead.) + */ + +#if BITS_IN_JSAMPLE == 8 +#define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) (v) +#define BYTESPERSAMPLE 1 +#define PPM_MAXVAL 255 +#else +#ifdef PPM_NORAWWORD +#define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) ((v) >> (BITS_IN_JSAMPLE-8)) +#define BYTESPERSAMPLE 1 +#define PPM_MAXVAL 255 +#else +/* The word-per-sample format always puts the LSB first. */ +#define PUTPPMSAMPLE(ptr,v) \ + { register int val_ = v; \ + *ptr++ = (char) (val_ & 0xFF); \ + *ptr++ = (char) ((val_ >> 8) & 0xFF); \ + } +#define BYTESPERSAMPLE 2 +#define PPM_MAXVAL ((1<pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * This code is used when we have to copy the data and apply a pixel + * format translation. Typically this only happens in 12-bit mode. + */ + +METHODDEF(void) +copy_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + register char * bufferptr; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + bufferptr = dest->iobuffer; + for (col = dest->samples_per_row; col > 0; col--) { + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(*ptr++)); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Write some pixel data when color quantization is in effect. + * We have to demap the color index values to straight data. + */ + +METHODDEF(void) +put_demapped_rgb (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + register char * bufferptr; + register int pixval; + register JSAMPROW ptr; + register JSAMPROW color_map0 = cinfo->colormap[0]; + register JSAMPROW color_map1 = cinfo->colormap[1]; + register JSAMPROW color_map2 = cinfo->colormap[2]; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + bufferptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + pixval = GETJSAMPLE(*ptr++); + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[pixval])); + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map1[pixval])); + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map2[pixval])); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +METHODDEF(void) +put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + register char * bufferptr; + register JSAMPROW ptr; + register JSAMPROW color_map = cinfo->colormap[0]; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + bufferptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map[GETJSAMPLE(*ptr++)])); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Startup: write the file header. + */ + +METHODDEF(void) +start_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + + /* Emit file header */ + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + /* emit header for raw PGM format */ + fprintf(dest->pub.output_file, "P5\n%ld %ld\n%d\n", + (long) cinfo->output_width, (long) cinfo->output_height, + PPM_MAXVAL); + break; + case JCS_RGB: + /* emit header for raw PPM format */ + fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n", + (long) cinfo->output_width, (long) cinfo->output_height, + PPM_MAXVAL); + break; + default: + ERREXIT(cinfo, JERR_PPM_COLORSPACE); + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + /* Make sure we wrote the output file OK */ + fflush(dinfo->output_file); + if (ferror(dinfo->output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for PPM format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_ppm (j_decompress_ptr cinfo) +{ + ppm_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (ppm_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ppm_dest_struct)); + dest->pub.start_output = start_output_ppm; + dest->pub.finish_output = finish_output_ppm; + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Create physical I/O buffer. Note we make this near on a PC. */ + dest->samples_per_row = cinfo->output_width * cinfo->out_color_components; + dest->buffer_width = dest->samples_per_row * (BYTESPERSAMPLE * SIZEOF(char)); + dest->iobuffer = (char *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width); + + if (cinfo->quantize_colors || BITS_IN_JSAMPLE != 8 || + SIZEOF(JSAMPLE) != SIZEOF(char)) { + /* When quantizing, we need an output buffer for colormap indexes + * that's separate from the physical I/O buffer. We also need a + * separate buffer if pixel format translation must take place. + */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width * cinfo->output_components, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + if (! cinfo->quantize_colors) + dest->pub.put_pixel_rows = copy_pixel_rows; + else if (cinfo->out_color_space == JCS_GRAYSCALE) + dest->pub.put_pixel_rows = put_demapped_gray; + else + dest->pub.put_pixel_rows = put_demapped_rgb; + } else { + /* We will fwrite() directly from decompressor output buffer. */ + /* Synthesize a JSAMPARRAY pointer structure */ + /* Cast here implies near->far pointer conversion on PCs */ + dest->pixrow = (JSAMPROW) dest->iobuffer; + dest->pub.buffer = & dest->pixrow; + dest->pub.buffer_height = 1; + dest->pub.put_pixel_rows = put_pixel_rows; + } + + return (djpeg_dest_ptr) dest; +} + +#endif /* PPM_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/wrrle.c b/rosapps/lib/libjpeg/wrrle.c new file mode 100644 index 00000000000..a4e73372de6 --- /dev/null +++ b/rosapps/lib/libjpeg/wrrle.c @@ -0,0 +1,305 @@ +/* + * wrrle.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in RLE format. + * The Utah Raster Toolkit library is required (version 3.1 or later). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + * + * Based on code contributed by Mike Lijewski, + * with updates from Robert Hutchinson. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef RLE_SUPPORTED + +/* rle.h is provided by the Utah Raster Toolkit. */ + +#include + +/* + * We assume that JSAMPLE has the same representation as rle_pixel, + * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + + +/* + * Since RLE stores scanlines bottom-to-top, we have to invert the image + * from JPEG's top-to-bottom order. To do this, we save the outgoing data + * in a virtual array during put_pixel_row calls, then actually emit the + * RLE file during finish_output. + */ + + +/* + * For now, if we emit an RLE color map then it is always 256 entries long, + * though not all of the entries need be used. + */ + +#define CMAPBITS 8 +#define CMAPLENGTH (1<<(CMAPBITS)) + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + jvirt_sarray_ptr image; /* virtual array to store the output image */ + rle_map *colormap; /* RLE-style color map, or NULL if none */ + rle_pixel **rle_row; /* To pass rows to rle_putrow() */ + +} rle_dest_struct; + +typedef rle_dest_struct * rle_dest_ptr; + +/* Forward declarations */ +METHODDEF(void) rle_put_pixel_rows + JPP((j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied)); + + +/* + * Write the file header. + * + * In this module it's easier to wait till finish_output to write anything. + */ + +METHODDEF(void) +start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + rle_dest_ptr dest = (rle_dest_ptr) dinfo; + size_t cmapsize; + int i, ci; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + /* + * Make sure the image can be stored in RLE format. + * + * - RLE stores image dimensions as *signed* 16 bit integers. JPEG + * uses unsigned, so we have to check the width. + * + * - Colorspace is expected to be grayscale or RGB. + * + * - The number of channels (components) is expected to be 1 (grayscale/ + * pseudocolor) or 3 (truecolor/directcolor). + * (could be 2 or 4 if using an alpha channel, but we aren't) + */ + + if (cinfo->output_width > 32767 || cinfo->output_height > 32767) + ERREXIT2(cinfo, JERR_RLE_DIMENSIONS, cinfo->output_width, + cinfo->output_height); + + if (cinfo->out_color_space != JCS_GRAYSCALE && + cinfo->out_color_space != JCS_RGB) + ERREXIT(cinfo, JERR_RLE_COLORSPACE); + + if (cinfo->output_components != 1 && cinfo->output_components != 3) + ERREXIT1(cinfo, JERR_RLE_TOOMANYCHANNELS, cinfo->num_components); + + /* Convert colormap, if any, to RLE format. */ + + dest->colormap = NULL; + + if (cinfo->quantize_colors) { + /* Allocate storage for RLE-style cmap, zero any extra entries */ + cmapsize = cinfo->out_color_components * CMAPLENGTH * SIZEOF(rle_map); + dest->colormap = (rle_map *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, cmapsize); + MEMZERO(dest->colormap, cmapsize); + + /* Save away data in RLE format --- note 8-bit left shift! */ + /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */ + for (ci = 0; ci < cinfo->out_color_components; ci++) { + for (i = 0; i < cinfo->actual_number_of_colors; i++) { + dest->colormap[ci * CMAPLENGTH + i] = + GETJSAMPLE(cinfo->colormap[ci][i]) << 8; + } + } + } + + /* Set the output buffer to the first row */ + dest->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, (JDIMENSION) 0, (JDIMENSION) 1, TRUE); + dest->pub.buffer_height = 1; + + dest->pub.put_pixel_rows = rle_put_pixel_rows; + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->total_extra_passes++; /* count file writing as separate pass */ + } +#endif +} + + +/* + * Write some pixel data. + * + * This routine just saves the data away in a virtual array. + */ + +METHODDEF(void) +rle_put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + rle_dest_ptr dest = (rle_dest_ptr) dinfo; + + if (cinfo->output_scanline < cinfo->output_height) { + dest->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, + cinfo->output_scanline, (JDIMENSION) 1, TRUE); + } +} + +/* + * Finish up at the end of the file. + * + * Here is where we really output the RLE file. + */ + +METHODDEF(void) +finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + rle_dest_ptr dest = (rle_dest_ptr) dinfo; + rle_hdr header; /* Output file information */ + rle_pixel **rle_row, *red, *green, *blue; + JSAMPROW output_row; + char cmapcomment[80]; + int row, col; + int ci; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + /* Initialize the header info */ + header = *rle_hdr_init(NULL); + header.rle_file = dest->pub.output_file; + header.xmin = 0; + header.xmax = cinfo->output_width - 1; + header.ymin = 0; + header.ymax = cinfo->output_height - 1; + header.alpha = 0; + header.ncolors = cinfo->output_components; + for (ci = 0; ci < cinfo->output_components; ci++) { + RLE_SET_BIT(header, ci); + } + if (cinfo->quantize_colors) { + header.ncmap = cinfo->out_color_components; + header.cmaplen = CMAPBITS; + header.cmap = dest->colormap; + /* Add a comment to the output image with the true colormap length. */ + sprintf(cmapcomment, "color_map_length=%d", cinfo->actual_number_of_colors); + rle_putcom(cmapcomment, &header); + } + + /* Emit the RLE header and color map (if any) */ + rle_put_setup(&header); + + /* Now output the RLE data from our virtual array. + * We assume here that (a) rle_pixel is represented the same as JSAMPLE, + * and (b) we are not on a machine where FAR pointers differ from regular. + */ + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_limit = cinfo->output_height; + progress->pub.pass_counter = 0; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + + if (cinfo->output_components == 1) { + for (row = cinfo->output_height-1; row >= 0; row--) { + rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, + (JDIMENSION) row, (JDIMENSION) 1, FALSE); + rle_putrow(rle_row, (int) cinfo->output_width, &header); +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + } else { + for (row = cinfo->output_height-1; row >= 0; row--) { + rle_row = (rle_pixel **) dest->rle_row; + output_row = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, + (JDIMENSION) row, (JDIMENSION) 1, FALSE); + red = rle_row[0]; + green = rle_row[1]; + blue = rle_row[2]; + for (col = cinfo->output_width; col > 0; col--) { + *red++ = GETJSAMPLE(*output_row++); + *green++ = GETJSAMPLE(*output_row++); + *blue++ = GETJSAMPLE(*output_row++); + } + rle_putrow(rle_row, (int) cinfo->output_width, &header); +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) + progress->completed_extra_passes++; +#endif + + /* Emit file trailer */ + rle_puteof(&header); + fflush(dest->pub.output_file); + if (ferror(dest->pub.output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for RLE format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_rle (j_decompress_ptr cinfo) +{ + rle_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (rle_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(rle_dest_struct)); + dest->pub.start_output = start_output_rle; + dest->pub.finish_output = finish_output_rle; + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Allocate a work array for output to the RLE library. */ + dest->rle_row = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width, (JDIMENSION) cinfo->output_components); + + /* Allocate a virtual array to hold the image. */ + dest->image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) (cinfo->output_width * cinfo->output_components), + cinfo->output_height, (JDIMENSION) 1); + + return (djpeg_dest_ptr) dest; +} + +#endif /* RLE_SUPPORTED */ diff --git a/rosapps/lib/libjpeg/wrtarga.c b/rosapps/lib/libjpeg/wrtarga.c new file mode 100644 index 00000000000..cf104d2debd --- /dev/null +++ b/rosapps/lib/libjpeg/wrtarga.c @@ -0,0 +1,253 @@ +/* + * wrtarga.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in Targa format. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + * + * Based on code contributed by Lee Daniel Crocker. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef TARGA_SUPPORTED + + +/* + * To support 12-bit JPEG data, we'd have to scale output down to 8 bits. + * This is not yet implemented. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + +/* + * The output buffer needs to be writable by fwrite(). On PCs, we must + * allocate the buffer in near data space, because we are assuming small-data + * memory model, wherein fwrite() can't reach far memory. If you need to + * process very wide images on a PC, you might have to compile in large-memory + * model, or else replace fwrite() with a putc() loop --- which will be much + * slower. + */ + + +/* Private version of data destination object */ + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + char *iobuffer; /* physical I/O buffer */ + JDIMENSION buffer_width; /* width of one row */ +} tga_dest_struct; + +typedef tga_dest_struct * tga_dest_ptr; + + +LOCAL(void) +write_header (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, int num_colors) +/* Create and write a Targa header */ +{ + char targaheader[18]; + + /* Set unused fields of header to 0 */ + MEMZERO(targaheader, SIZEOF(targaheader)); + + if (num_colors > 0) { + targaheader[1] = 1; /* color map type 1 */ + targaheader[5] = (char) (num_colors & 0xFF); + targaheader[6] = (char) (num_colors >> 8); + targaheader[7] = 24; /* 24 bits per cmap entry */ + } + + targaheader[12] = (char) (cinfo->output_width & 0xFF); + targaheader[13] = (char) (cinfo->output_width >> 8); + targaheader[14] = (char) (cinfo->output_height & 0xFF); + targaheader[15] = (char) (cinfo->output_height >> 8); + targaheader[17] = 0x20; /* Top-down, non-interlaced */ + + if (cinfo->out_color_space == JCS_GRAYSCALE) { + targaheader[2] = 3; /* image type = uncompressed gray-scale */ + targaheader[16] = 8; /* bits per pixel */ + } else { /* must be RGB */ + if (num_colors > 0) { + targaheader[2] = 1; /* image type = colormapped RGB */ + targaheader[16] = 8; + } else { + targaheader[2] = 2; /* image type = uncompressed RGB */ + targaheader[16] = 24; + } + } + + if (JFWRITE(dinfo->output_file, targaheader, 18) != (size_t) 18) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * Write some pixel data. + * In this module rows_supplied will always be 1. + */ + +METHODDEF(void) +put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* used for unquantized full-color output */ +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + register JSAMPROW inptr; + register char * outptr; + register JDIMENSION col; + + inptr = dest->pub.buffer[0]; + outptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + outptr[0] = (char) GETJSAMPLE(inptr[2]); /* RGB to BGR order */ + outptr[1] = (char) GETJSAMPLE(inptr[1]); + outptr[2] = (char) GETJSAMPLE(inptr[0]); + inptr += 3, outptr += 3; + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + +METHODDEF(void) +put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* used for grayscale OR quantized color output */ +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + register JSAMPROW inptr; + register char * outptr; + register JDIMENSION col; + + inptr = dest->pub.buffer[0]; + outptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + *outptr++ = (char) GETJSAMPLE(*inptr++); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Write some demapped pixel data when color quantization is in effect. + * For Targa, this is only applied to grayscale data. + */ + +METHODDEF(void) +put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + register JSAMPROW inptr; + register char * outptr; + register JSAMPROW color_map0 = cinfo->colormap[0]; + register JDIMENSION col; + + inptr = dest->pub.buffer[0]; + outptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + *outptr++ = (char) GETJSAMPLE(color_map0[GETJSAMPLE(*inptr++)]); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Startup: write the file header. + */ + +METHODDEF(void) +start_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + int num_colors, i; + FILE *outfile; + + if (cinfo->out_color_space == JCS_GRAYSCALE) { + /* Targa doesn't have a mapped grayscale format, so we will */ + /* demap quantized gray output. Never emit a colormap. */ + write_header(cinfo, dinfo, 0); + if (cinfo->quantize_colors) + dest->pub.put_pixel_rows = put_demapped_gray; + else + dest->pub.put_pixel_rows = put_gray_rows; + } else if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) { + /* We only support 8-bit colormap indexes, so only 256 colors */ + num_colors = cinfo->actual_number_of_colors; + if (num_colors > 256) + ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, num_colors); + write_header(cinfo, dinfo, num_colors); + /* Write the colormap. Note Targa uses BGR byte order */ + outfile = dest->pub.output_file; + for (i = 0; i < num_colors; i++) { + putc(GETJSAMPLE(cinfo->colormap[2][i]), outfile); + putc(GETJSAMPLE(cinfo->colormap[1][i]), outfile); + putc(GETJSAMPLE(cinfo->colormap[0][i]), outfile); + } + dest->pub.put_pixel_rows = put_gray_rows; + } else { + write_header(cinfo, dinfo, 0); + dest->pub.put_pixel_rows = put_pixel_rows; + } + } else { + ERREXIT(cinfo, JERR_TGA_COLORSPACE); + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + /* Make sure we wrote the output file OK */ + fflush(dinfo->output_file); + if (ferror(dinfo->output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for Targa format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_targa (j_decompress_ptr cinfo) +{ + tga_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (tga_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(tga_dest_struct)); + dest->pub.start_output = start_output_tga; + dest->pub.finish_output = finish_output_tga; + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Create I/O buffer. Note we make this near on a PC. */ + dest->buffer_width = cinfo->output_width * cinfo->output_components; + dest->iobuffer = (char *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (dest->buffer_width * SIZEOF(char))); + + /* Create decompressor output buffer. */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + + return (djpeg_dest_ptr) dest; +} + +#endif /* TARGA_SUPPORTED */ diff --git a/rosapps/smartpdf/COPYING b/rosapps/smartpdf/COPYING new file mode 100644 index 00000000000..d60c31a97a5 --- /dev/null +++ b/rosapps/smartpdf/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/rosapps/smartpdf/baseutils/WinUtil.cpp b/rosapps/smartpdf/baseutils/WinUtil.cpp new file mode 100644 index 00000000000..5e6cbfdfef1 --- /dev/null +++ b/rosapps/smartpdf/baseutils/WinUtil.cpp @@ -0,0 +1,112 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ + +#include "base_util.h" + +#include "WinUtil.hpp" + +#include "str_util.h" + +// TODO: exe name might be unicode so to support everything cmd or args +// should be unicode or we can assume that cmd and args are utf8 and +// convert them to utf16 and call CreateProcessW +#define DONT_INHERIT_HANDLES FALSE + +// Given name of the command to exececute 'cmd', and its arguments 'args' +// return WinProcess object that makes it easier to handle the process +// Returns NULL if failed to create the process. Caller can use GetLastError() +// for detailed error information. +WinProcess * WinProcess::Create(const char* cmd, char* args) +{ + UINT res; + HANDLE stdOut = INVALID_HANDLE_VALUE; + HANDLE stdErr = INVALID_HANDLE_VALUE; + STARTUPINFOA siStartupInfo; + PROCESS_INFORMATION piProcessInfo; + SECURITY_ATTRIBUTES sa; + + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = 0; + sa.bInheritHandle = 1; + + memzero(&siStartupInfo, sizeof(siStartupInfo)); + memzero(&piProcessInfo, sizeof(piProcessInfo)); + siStartupInfo.cb = sizeof(siStartupInfo); + + char stdoutTempName[MAX_PATH] = {0}; + char stderrTempName[MAX_PATH] = {0}; + char *stdoutTempNameCopy = NULL; + char *stderrTempNameCopy = NULL; + + char buf[MAX_PATH] = {0}; + int len = GetTempPathA(sizeof(buf), buf); + assert(len < sizeof(buf)); + // create temporary files for capturing stdout and stderr or the command + res = GetTempFileNameA(buf, "stdout", 0, stdoutTempName); + if (0 == res) + goto Error; + + res = GetTempFileNameA(buf, "stderr", 0, stderrTempName); + if (0 == res) + goto Error; + + stdoutTempNameCopy = str_dup(stdoutTempName); + stderrTempNameCopy = str_dup(stderrTempName); + + stdOut = CreateFileA(stdoutTempNameCopy, + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_WRITE|FILE_SHARE_READ, + &sa, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, 0); + if (INVALID_HANDLE_VALUE == stdOut) + goto Error; + + stdErr = CreateFileA(stderrTempNameCopy, + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_WRITE|FILE_SHARE_READ, + &sa, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, 0); + if (INVALID_HANDLE_VALUE == stdErr) + goto Error; + + siStartupInfo.hStdOutput = stdOut; + siStartupInfo.hStdError = stdErr; + + BOOL ok = CreateProcessA(cmd, args, NULL, NULL, DONT_INHERIT_HANDLES, + CREATE_DEFAULT_ERROR_MODE, NULL /*env*/, NULL /*curr dir*/, + &siStartupInfo, &piProcessInfo); + + if (!ok) + goto Error; + + // TODO: pass stdoutTempNameCopy and stderrTempNameCopy so upon + // WinProcess destruction the files can be deleted and their memory freed + WinProcess *wp = new WinProcess(&piProcessInfo); + return wp; + +Error: + if (INVALID_HANDLE_VALUE != stdOut) { + CloseHandle(stdOut); + } + + if (INVALID_HANDLE_VALUE != stdErr) { + CloseHandle(stdErr); + } + + if (stdoutTempName[0]) { + // TODO: delete stdoutTempName + } + if (stderrTempName[0]) { + // TODO: delete stderrTempName + } + free(stdoutTempNameCopy); + free(stderrTempNameCopy); + return NULL; +} + +WinProcess::WinProcess(PROCESS_INFORMATION *pi) +{ + memcpy(&m_processInfo, pi, sizeof(PROCESS_INFORMATION)); +} + + diff --git a/rosapps/smartpdf/baseutils/WinUtil.hpp b/rosapps/smartpdf/baseutils/WinUtil.hpp new file mode 100644 index 00000000000..d4b5e2c11e4 --- /dev/null +++ b/rosapps/smartpdf/baseutils/WinUtil.hpp @@ -0,0 +1,15 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef WINUTIL_HPP__ +#define WINUTIL_HPP__ + +class WinProcess { +public: + static WinProcess* Create(const char *cmd, char *args=""); + +private: + WinProcess(PROCESS_INFORMATION *); // we don't want just anyone to make us + PROCESS_INFORMATION m_processInfo; +}; +#endif + diff --git a/rosapps/smartpdf/baseutils/base_util.c b/rosapps/smartpdf/baseutils/base_util.c new file mode 100644 index 00000000000..034d24dcb21 --- /dev/null +++ b/rosapps/smartpdf/baseutils/base_util.c @@ -0,0 +1,138 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" + +void swap_int(int *one, int *two) +{ + int tmp = *one; + *one = *two; + *two = tmp; +} + +void swap_double(double *one, double *two) +{ + double tmp = *one; + *one = *two; + *two = tmp; +} + +int MinInt(int one, int two) +{ + if (one < two) + return one; + else + return two; +} + +void memzero(void *data, size_t len) +{ + memset(data, 0, len); +} + +void *zmalloc(size_t len) +{ + void *data = malloc(len); + if (data) + memzero(data, len); + return data; +} + +/* TODO: probably should move to some other file and change name to + sleep_milliseconds */ +void sleep_milliseconds(int milliseconds) +{ +#ifdef WIN32 + Sleep((DWORD)milliseconds); +#else + struct timespec tv; + int secs, nanosecs; + secs = milliseconds / 1000; + nanosecs = (milliseconds - (secs * 1000)) * 1000; + tv.tv_sec = (time_t) secs; + tv.tv_nsec = (long) nanosecs; + while (1) + { + int rval = nanosleep(&tv, &tv); + if (rval == 0) + /* Completed the entire sleep time; all done. */ + return; + else if (errno == EINTR) + /* Interrupted by a signal. Try again. */ + continue; + else + /* Some other error; bail out. */ + return; + } + return; +#endif +} + +/* milli-second timer */ +#ifdef _WIN32 +void ms_timer_start(ms_timer *timer) +{ + assert(timer); + if (!timer) + return; + QueryPerformanceCounter(&timer->start); +} +void ms_timer_stop(ms_timer *timer) +{ + assert(timer); + if (!timer) + return; + QueryPerformanceCounter(&timer->end); +} + +double ms_timer_time_in_ms(ms_timer *timer) +{ + LARGE_INTEGER freq; + double time_in_secs; + QueryPerformanceFrequency(&freq); + time_in_secs = (double)(timer->end.QuadPart-timer->start.QuadPart)/(double)freq.QuadPart; + return time_in_secs * 1000.0; +} +#else +typedef struct ms_timer { + struct timeval start; + struct timeval end; +} ms_timer; + +void ms_timer_start(ms_timer *timer) +{ + assert(timer); + if (!timer) + return; + gettimeofday(&timer->start, NULL); +} + +void ms_timer_stop(ms_timer *timer) +{ + assert(timer); + if (!timer) + return; + gettimeofday(&timer->end, NULL); +} + +double ms_timer_time_in_ms(ms_timer *timer) +{ + double timeInMs; + time_t seconds; + int usecs; + + assert(timer); + if (!timer) + return 0.0; + /* TODO: this logic needs to be verified */ + seconds = timer->end.tv_sec - timer->start.tv_sec; + usecs = timer->end.tv_usec - timer->start.tv_usec; + if (usecs < 0) { + --seconds; + usecs += 1000000; + } + timeInMs = (double)seconds*(double)1000.0 + (double)usecs/(double)1000.0; + return timeInMs; +} +#endif + + diff --git a/rosapps/smartpdf/baseutils/base_util.h b/rosapps/smartpdf/baseutils/base_util.h new file mode 100644 index 00000000000..34654c2b257 --- /dev/null +++ b/rosapps/smartpdf/baseutils/base_util.h @@ -0,0 +1,160 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef BASE_UTIL_H_ +#define BASE_UTIL_H_ + +#ifdef _UNICODE +#ifndef UNICODE +#define UNICODE +#endif +#endif + +#ifdef UNICODE +#ifndef _UNICODE +#define _UNICODE +#endif +#endif + +/* It seems that Visual C defines WIN32 for Windows code but _WINDOWS for WINCE projects, + so I'll make sure to set WIN32 always*/ +#ifdef _WINDOWS + #ifndef WIN32 + #define WIN32 1 + #endif + #ifndef _WIN32 + #define _WIN32 1 + #endif +#endif + +#ifdef _WIN32 +#include +#include +#else +#include // for timeval +#endif + +/* Few most common includes for C stdlib */ +#include +#include + +#include +#include + +#include +#include + +// TODO: does it need to be __GNUC__ only? I think it was done for mingw +#ifdef __GNUC__ +#include +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifdef _WIN32 + #ifndef __GNUC__ + typedef unsigned int uint32_t; + #endif + #ifndef _T + #define _T TEXT + #endif +#else + #define _T(x) x + /* TODO: if _UNICODE, it should be different */ + #define TEXT(x) x +#endif + +/* compile-time assert */ +#ifndef CASSERT + #define CASSERT( exp, name ) typedef int dummy##name [ (exp ) ? 1 : -1 ]; +#endif + +/* Ugly name but the whole point is to make things shorter. */ +#define SA(struct_name) (struct_name *)malloc(sizeof(struct_name)) +#define SAZ(struct_name) (struct_name *)zmalloc(sizeof(struct_name)) + +typedef long long int64; + +CASSERT( sizeof(int64)==8, int64_is_8_bytes ) + +#define dimof(X) (sizeof(X)/sizeof((X)[0])) + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct ms_timer { +#ifdef _WIN32 + LARGE_INTEGER start; + LARGE_INTEGER end; +#else + struct timeval start; + struct timeval end; +#endif +} ms_timer; + +#ifdef _WIN32 + void win32_dbg_out(const char *format, ...); + void win32_dbg_out_hex(const char *dsc, const unsigned char *data, int dataLen); +#endif + +/* TODO: consider using standard C macros for SWAP and MIN */ +void swap_int(int *one, int *two); +void swap_double(double *one, double *two); +int MinInt(int one, int two); + +void memzero(void *data, size_t len); +void * zmalloc(size_t size); + +void sleep_milliseconds(int milliseconds); + +void ms_timer_start(ms_timer *timer); +void ms_timer_stop(ms_timer *timer); +double ms_timer_time_in_ms(ms_timer *timer); + +#define LIST_REVERSE_FUNC_PROTO(func_name, TYPE) \ +void func_name(TYPE **root) + +#define LIST_REVERSE_FUNC(func_name, TYPE) \ +void func_name(TYPE **root) \ +{ \ + TYPE * cur; \ + TYPE * next; \ + TYPE * new_first = NULL; \ +\ + if (!root) \ + return; \ +\ + cur = *root; \ + while (cur) { \ + next = cur->next; \ + cur->next = new_first; \ + new_first = cur; \ + cur = next; \ + } \ + *root = new_first; \ +} + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +class MsTimer { +public: + MsTimer() { ms_timer_start(&timer); } + void start(void) { ms_timer_start(&timer); } + void stop(void) { ms_timer_stop(&timer); } + double timeInMs(void) { return ms_timer_time_in_ms(&timer); } +private: + ms_timer timer; +}; +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/common_unit_tests.sln b/rosapps/smartpdf/baseutils/common_unit_tests.sln new file mode 100644 index 00000000000..3b1d07ac90b --- /dev/null +++ b/rosapps/smartpdf/baseutils/common_unit_tests.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common_unit_tests", "common_unit_tests.vcproj", "{35EC4096-521D-44D0-B693-2BF11B85B275}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {35EC4096-521D-44D0-B693-2BF11B85B275}.Debug|Win32.ActiveCfg = Debug|Win32 + {35EC4096-521D-44D0-B693-2BF11B85B275}.Debug|Win32.Build.0 = Debug|Win32 + {35EC4096-521D-44D0-B693-2BF11B85B275}.Release|Win32.ActiveCfg = Release|Win32 + {35EC4096-521D-44D0-B693-2BF11B85B275}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/rosapps/smartpdf/baseutils/common_unit_tests.vcproj b/rosapps/smartpdf/baseutils/common_unit_tests.vcproj new file mode 100644 index 00000000000..b2a234b3708 --- /dev/null +++ b/rosapps/smartpdf/baseutils/common_unit_tests.vcproj @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/smartpdf/baseutils/dstring.c b/rosapps/smartpdf/baseutils/dstring.c new file mode 100644 index 00000000000..02a0b6771d6 --- /dev/null +++ b/rosapps/smartpdf/baseutils/dstring.c @@ -0,0 +1,319 @@ +/**************************************************************************** + * + * Dynamic strings + ****************************************************************************/ + +/* + * tcl.h -- + * + * This header file describes the externally-visible facilities + * of the Tcl interpreter. + * + * Copyright (c) 1987-1994 The Regents of the University of California. + * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39 + */ + + +#include "dstring.h" +#include +#include +#include +#include +#include +#include "str_strsafe.h" + +/* + *---------------------------------------------------------------------- + * + * DStringInit -- + * + * Initializes a dynamic string, discarding any previous contents + * of the string (DStringFree should have been called already + * if the dynamic string was previously in use). + * + * Results: + * None. + * + * Side effects: + * The dynamic string is initialized to be empty. + * + *---------------------------------------------------------------------- + */ + +void +DStringInit(DString* pDs) +{ + pDs->pString = pDs->staticSpace; + pDs->length = 0; + pDs->spaceAvl = kDstringStaticSize; + pDs->staticSpace[0] = 0; +} + +/* + *---------------------------------------------------------------------- + * + * DStringAppend -- + * + * Append more characters to the current value of a dynamic string. + * + * Results: + * The return value is a pointer to the dynamic string's new value. + * + * Side effects: + * Length bytes from string (or all of string if length is less + * than zero) are added to the current value of the string. Memory + * gets reallocated if needed to accomodate the string's new size. + * + *---------------------------------------------------------------------- + */ + +char * +DStringAppend(DString *pDs, + const char* string, + int length) +{ + int newSize; + char* newString; + char* dst; + const char* end; + + if (length < 0) { + length = strlen(string); + } + newSize = length + pDs->length; + + /* + * Allocate a larger buffer for the string if the current one isn't + * large enough. Allocate extra space in the new buffer so that there + * will be room to grow before we have to allocate again. + */ + + if (newSize >= pDs->spaceAvl) { + pDs->spaceAvl = newSize*2; + newString = (char *) malloc((unsigned) pDs->spaceAvl); + memcpy((void *)newString, (void *) pDs->pString, + (size_t) pDs->length); + if (pDs->pString != pDs->staticSpace) { + free(pDs->pString); + } + pDs->pString = newString; + } + + /* + * Copy the new string into the buffer at the end of the old + * one. + */ + + for (dst = pDs->pString + pDs->length, end = string+length; + string < end; string++, dst++) { + *dst = *string; + } + *dst = 0; + pDs->length += length; + return pDs->pString; +} + +/* + *---------------------------------------------------------------------- + * + * DStringSetLength -- + * + * Change the length of a dynamic string. This can cause the + * string to either grow or shrink, depending on the value of + * length. + * + * Results: + * None. + * + * Side effects: + * The length of pDsis changed to length and a null byte is + * stored at that position in the string. If length is larger + * than the space allocated for pDs, then a panic occurs. + * + *---------------------------------------------------------------------- + */ + +void +DStringSetLength(DString* pDs, + int length) +{ + if (length < 0) { + length = 0; + } + if (length >= pDs->spaceAvl) { + char *newString; + + pDs->spaceAvl = length+1; + newString = (char *) malloc((unsigned) pDs->spaceAvl); + + /* + * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string + * to a larger buffer, since there may be embedded NULLs in the + * string in some cases. + */ + + memcpy((void *) newString, (void*) pDs->pString, + (size_t) pDs->length); + if (pDs->pString != pDs->staticSpace) { + free(pDs->pString); + } + pDs->pString = newString; + } + pDs->length = length; + pDs->pString[length] = 0; +} + +/* + *---------------------------------------------------------------------- + * + * DStringFree -- + * + * Frees up any memory allocated for the dynamic string and + * reinitializes the string to an empty state. + * + * Results: + * None. + * + * Side effects: + * The previous contents of the dynamic string are lost, and + * the new value is an empty string. + * + *---------------------------------------------------------------------- + */ + +void +DStringFree(DString* pDs) +{ + if (pDs->pString != pDs->staticSpace) { + free(pDs->pString); + } + pDs->pString = pDs->staticSpace; + pDs->length = 0; + pDs->spaceAvl = kDstringStaticSize; + pDs->staticSpace[0] = 0; +} + +/* + * DStringSprintf -- + * + * Append a formatted string to a dstring + */ + +void +DStringSprintf(DString* pDs, + const char* pFormat, + ...) +{ +#ifdef _WIN32 + HRESULT hr; + va_list args; + char message[256]; + char * buf; + size_t bufCchSize; + char * result = NULL; + + buf = &(message[0]); + bufCchSize = sizeof(message); + + va_start(args, pFormat); + for (;;) + { + /* TODO: this only works on windows with recent C library */ + hr = StringCchVPrintfA(buf, bufCchSize, pFormat, args); + if (S_OK == hr) + break; + if (STRSAFE_E_INSUFFICIENT_BUFFER != hr) + { + /* any error other than buffer not big enough: + a) should not happen + b) means we give up */ + goto Error; + } + /* we have to make the buffer bigger. The algorithm used to calculate + the new size is arbitrary (aka. educated guess) */ + if (buf != &(message[0])) + free(buf); + if (bufCchSize < 4*1024) + bufCchSize += bufCchSize; + else + bufCchSize += 1024; + buf = (char *)malloc(bufCchSize*sizeof(char)); + if (NULL == buf) + goto Error; + } + va_end(args); + + DStringAppend(pDs, buf, -1); +Error: + if (buf != &(message[0])) + free((void*)buf); + return; +#else + va_list args; + char* pBuffer; + int len; + + va_start(args, pFormat); + len = vasprintf(&pBuffer, pFormat, args); + DStringAppend(pDs, pBuffer, len); + free(pBuffer); + va_end(args); +#endif +} + +/**************************************************************************** + * DStringAppendLowerCase -- + * + * Append text to a dstring lowercased + */ + +char* +DStringAppendLowerCase(DString* pDs, + const char* string, + int length) +{ + int newSize; + char* newString; + char* dst; + const char* end; + + if (length < 0) { + length = strlen(string); + } + newSize = length + pDs->length; + + /* + * Allocate a larger buffer for the string if the current one isn't + * large enough. Allocate extra space in the new buffer so that there + * will be room to grow before we have to allocate again. + */ + + if (newSize >= pDs->spaceAvl) { + pDs->spaceAvl = newSize*2; + newString = (char *) malloc((unsigned) pDs->spaceAvl); + memcpy((void *)newString, (void *) pDs->pString, + (size_t) pDs->length); + if (pDs->pString != pDs->staticSpace) { + free(pDs->pString); + } + pDs->pString = newString; + } + + /* + * Copy the new string into the buffer at the end of the old + * one. + */ + + for (dst = pDs->pString + pDs->length, end = string+length; + string < end; string++, dst++) { + *dst = tolower(*string); + } + *dst = 0; + pDs->length += length; + return pDs->pString; +} diff --git a/rosapps/smartpdf/baseutils/dstring.h b/rosapps/smartpdf/baseutils/dstring.h new file mode 100644 index 00000000000..aa7b9a7281f --- /dev/null +++ b/rosapps/smartpdf/baseutils/dstring.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * Dynamic strings + ****************************************************************************/ + +/* + * tcl.h -- + * + * This header file describes the externally-visible facilities + * of the Tcl interpreter. + * + * Copyright (c) 1987-1994 The Regents of the University of California. + * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39 + */ +#ifndef DSTRING_H +#define DSTRING_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define kDstringStaticSize 200 + +typedef struct DString { + char *pString; /* Points to beginning of string: either + * staticSpace below or a malloc'ed array. */ + int length; /* Number of non-NULL characters in the + * string. */ + int spaceAvl; /* Total number of bytes available for the + * string and its terminating NULL char. */ + char staticSpace[kDstringStaticSize]; + /* Space to use in common case where string + * is small. */ +} DString; + +#define DStringLength(dsPtr) ((dsPtr)->length) +#define DStringValue(dsPtr) ((dsPtr)->pString) +#define DStringTrunc DStringSetLength + +char* +DStringAppend(DString* dsPtr, + const char* string, + int length); + +void +DStringFree(DString* dsPtr); + +void +DStringInit(DString* dsPtr); + +void +DStringSetLength(DString* dsPtr, + int length); + +void +DStringSprintf(DString* pDs, + const char* pFormat, + ...); +char* +DStringAppendLowerCase(DString* pDs, + const char* pIn, + int length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/file_util.c b/rosapps/smartpdf/baseutils/file_util.c new file mode 100644 index 00000000000..463ddbd84bd --- /dev/null +++ b/rosapps/smartpdf/baseutils/file_util.c @@ -0,0 +1,483 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" +#include "file_util.h" + +#include "str_util.h" +#include "strlist_util.h" + +char *FilePath_ConcatA(const char *path, const char *name) +{ + assert(path && name); + if (!path || !name) return NULL; + + if (str_endswith(path, DIR_SEP_STR)) + return str_cat(path, name); + else + return str_cat3(path, DIR_SEP_STR, name); +} + +const char *FilePath_GetBaseName(const char *path) +{ + const char *fileBaseName = (const char*)strrchr(path, DIR_SEP_CHAR); + if (NULL == fileBaseName) + fileBaseName = path; + else + ++fileBaseName; + return fileBaseName; +} + +char *FilePath_GetDir(const char *path) +{ + char *lastSep; + char *dir = str_dup(path); + if (!dir) return NULL; + lastSep = (char*)strrchr(dir, DIR_SEP_CHAR); + if (NULL != lastSep) + *lastSep = 0; + return dir; +} + +/* TODO: handle TCHAR (UNICODE) properly by converting to path to unicode + if UNICODE or _UNICODE symbols are defined */ +/* Start iteration of all files 'path'. 'path' should be a directory + name but doesn't have to end with "\" (we append it if it's missing) + Retuns NULL if there was an error. + When no longer needed, the result should be deleted with + 'DirIter_Delete'. +*/ +DirIterState *DirIter_New(const char *path) +{ + DirIterState *state; + + assert(path); + + if (!path) + return NULL; + + state = SA(DirIterState); + if (!state) + return NULL; + + /* TODO: made state->cleanPath cannonical */ + state->cleanPath = str_dup(path); + state->iterPath = FilePath_ConcatA(path, "*"); + if (!state->cleanPath || !state->iterPath) { + DirIter_Delete(state); + return NULL; + } + state->dir = INVALID_HANDLE_VALUE; + return state; +} + +/* Get information about next file in a directory. + Returns FALSE on end of iteration (or error). */ +BOOL DirIter_Next(DirIterState *s) +{ + BOOL found; + + if (INVALID_HANDLE_VALUE == s->dir) { + s->dir = FindFirstFileA(s->iterPath, &(s->fileInfo)); + if (INVALID_HANDLE_VALUE == s->dir) + return FALSE; + goto CheckFile; + } + + for(;;) { + found = FindNextFileA(s->dir, &(s->fileInfo)); + if (!found) + return FALSE; + else +CheckFile: + return TRUE; + } +} + +/* Free memory associated with 'state' */ +void DirIter_Delete(DirIterState *state) +{ + if (state) { + free(state->cleanPath); + free(state->iterPath); + } + free(state); +} + +static FileList *FileList_New(char *dir) +{ + FileList *fl; + + assert(dir); + + fl = SAZ(FileList); + if (!fl) + return NULL; + fl->dirName = str_dup(dir); + if (!fl->dirName) { + free((void*)fl); + return NULL; + } + return fl; +} + +static BOOL FileList_InsertFileInfo(FileList *fl, FileInfo *fi) +{ + int real_count; + FileInfo *last_fi; + + assert(fl); + if (!fl) + return FALSE; + assert(fi); + if (!fi) + return FALSE; + /* TODO: use scheme where we also track of the last node, so that + insert is O(1) and not O(n) */ + assert(!fi->next); + fi->next = NULL; + if (!fl->first) { + assert(0 == fl->filesCount); + fl->first = fi; + fl->filesCount = 1; + return TRUE; + } + + last_fi = fl->first; + assert(last_fi); + real_count = 1; + while (last_fi->next) { + ++real_count; + last_fi = last_fi->next; + } + + assert(real_count == fl->filesCount); + last_fi->next = fi; + ++fl->filesCount; + return TRUE; +} + +void FileInfo_Delete(FileInfo *fi) +{ + if (!fi) return; + free(fi->name); + free(fi->path); + free(fi); +} + +static FileInfo *FileInfo_New(char *path, char *name, int64 size, DWORD attr, FILETIME *modificationTime) +{ + FileInfo *fi; + + assert(name); + if (!name) + return NULL; + + assert(modificationTime); + if (!modificationTime) + return NULL; + + fi = SAZ(FileInfo); + if (!fi) + return NULL; + + fi->name = str_dup(name); + fi->path = str_dup(path); + if (!fi->name || !fi->path) { + FileInfo_Delete(fi); + return NULL; + } + + fi->size = size; + fi->attr = attr; + fi->modificationTime = *modificationTime; + return fi; +} + +static FileInfo* FileInfo_FromDirIterState(DirIterState *state) +{ + FileInfo * fi; + WIN32_FIND_DATAA *fd; + char * fileName; + int64 size; + char * filePath; + + assert(state); + if (!state) return NULL; + + fd = &state->fileInfo; + size = fd->nFileSizeHigh; + size = size >> 32; + size += fd->nFileSizeLow; + /* TODO: handle UNICODE */ + fileName = fd->cFileName; + filePath = FilePath_ConcatA(state->cleanPath, fileName); + fi = FileInfo_New(filePath, fileName, size, fd->dwFileAttributes, &fd->ftLastWriteTime); + return fi; +} + +BOOL FileInfo_IsFile(FileInfo *fi) +{ + DWORD attr; + assert(fi); + if (!fi) return +FALSE; + attr = fi->attr; + + if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) + return TRUE; + return FALSE; +} + +int FileInfo_IsDir(FileInfo *fi) +{ + DWORD attr; + assert(fi); + if (!fi) return +FALSE; + attr = fi->attr; + + if (attr & FILE_ATTRIBUTE_DIRECTORY) + return TRUE; + return FALSE; +} + +static int FileList_Append(char *path, FileList *fl, int (*filter)(FileInfo *)) +{ + FileInfo * fi; + DirIterState * state; + int shouldInsert; + + if (!path || !fl) + return 0; + + state = DirIter_New(path); + if (!state) { + return 0; + } + + /* TODO: handle errors from DirIter_Next */ + while (DirIter_Next(state)) { + fi = FileInfo_FromDirIterState(state); + if (!fi) { + DirIter_Delete(state); + return 0; + } + if (fi) { + shouldInsert = 1; + if (filter && !(*filter)(fi)) + shouldInsert = 0; + if (shouldInsert) + FileList_InsertFileInfo(fl, fi); + } + } + DirIter_Delete(state); + return 1; +} + +/* Return a list of files/directories in a 'path'. Use filter function + to filter out files that should not get included (return 0 from the function + to exclude it from the list. + Returns NULL in case of an error. + Use FileList_Delete() to free up all memory associated with this data. + Doesn't recurse into subdirectores, use FileList_GetRecursive for that. */ +/* TODO: 'filter' needs to be implemented. */ +/* TODO: add 'filterRegexp' argument that would allow filtering via regular + expression */ +FileList *FileList_Get(char* path, int (*filter)(FileInfo *)) +{ + FileList * fl; + int ok; + + if (!path) + return NULL; + + /* TODO: should I expand "." ? */ + fl = FileList_New(path); + if (!fl) + return NULL; + + ok = FileList_Append(path, fl, filter); + if (!ok) { + FileList_Delete(fl); + return NULL; + } + return fl; +} + +/* Like FileList_Get() except recurses into sub-directories */ +/* TODO: 'filter' needs to be implemented. */ +/* TODO: add 'filterRegexp' argument that would allow filtering via regular + expression */ +FileList *FileList_GetRecursive(char* path, int (*filter)(FileInfo *)) +{ + StrList *toVisit = NULL; + FileList *fl = NULL; + assert(0); + /* TODO: clearly, implement */ + return NULL; +} + +void FileList_Delete(FileList *fl) +{ + FileInfo *fi; + FileInfo *fi_next; + if (!fl) + return; + fi = fl->first; + while (fi) { + fi_next = fi->next; + FileInfo_Delete(fi); + fi = fi_next; + } + free((void*)fl->dirName); + free((void*)fl); +} + +int FileList_Len(FileList *fl) +{ + return fl->filesCount; +} + +FileInfo *FileList_GetFileInfo(FileList *fl, int file_no) +{ + FileInfo *fi; + if (!fl) + return NULL; + if (file_no >= fl->filesCount) + return NULL; + fi = fl->first; + while (file_no > 0) { + assert(fi->next); + if (!fi->next) + return NULL; + fi = fi->next; + --file_no; + } + return fi; +} + +#ifdef _WIN32 +size_t file_size_get(const char *file_path) +{ + int fOk; + WIN32_FILE_ATTRIBUTE_DATA fileInfo; + + if (NULL == file_path) + return INVALID_FILE_SIZE; + + fOk = GetFileAttributesExA(file_path, GetFileExInfoStandard, (void*)&fileInfo); + if (!fOk) + return INVALID_FILE_SIZE; + return (size_t)fileInfo.nFileSizeLow; +} +#else +#include +#include + +size_t file_size_get(const char *file_path) +{ + struct stat stat_buf; + int res; + unsigned long size; + if (NULL == file_path) + return INVALID_FILE_SIZE; + res = stat(file_path, &stat_buf); + if (0 != res) + return INVALID_FILE_SIZE; + size = (size_t)stat_buf.st_size; + return size; +} +#endif + +#ifdef _WIN32 +char *file_read_all(const char *file_path, size_t *file_size_out) +{ + DWORD size, size_read; + HANDLE h; + char * data = NULL; + int f_ok; + + h = CreateFileA(file_path, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) + return NULL; + + size = GetFileSize(h, NULL); + if (-1 == size) + goto Exit; + + /* allocate one byte more and 0-terminate just in case it's a text + file we'll want to treat as C string. Doesn't hurt for binary + files */ + data = (char*)malloc(size + 1); + if (!data) + goto Exit; + data[size] = 0; + + f_ok = ReadFile(h, data, size, &size_read, NULL); + if (!f_ok) { + free(data); + data = NULL; + } + *file_size_out = (size_t)size; +Exit: + CloseHandle(h); + return data; +} +#else +/* TODO: change unsinged long to int64 or size_t */ +char *file_read_all(const char *file_path, size_t *file_size_out) +{ + FILE *fp = NULL; + char *data = NULL; + size_t read; + + size_t file_size = file_size_get(file_path); + if (INVALID_FILE_SIZE == file_size) + return NULL; + + data = (char*)malloc(file_size + 1); + if (!data) + goto Exit; + data[file_size] = 0; + + fp = fopen(file_path, "rb"); + if (!fp) + goto Error; + + read = fread((void*)data, 1, file_size, fp); + if (ferror(fp)) + goto Error; + assert(read == file_size); + if (read != file_size) + goto Error; + fclose(fp); + return data; +Error: + if (fp) + fclose(fp); + free((void*)data); + return NULL; +} +#endif + +#ifdef _WIN32 +BOOL write_to_file(const TCHAR *file_path, void *data, size_t data_len) +{ + DWORD size; + HANDLE h; + BOOL f_ok; + + h = CreateFile(file_path, GENERIC_WRITE, FILE_SHARE_READ, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) + return FALSE; + + f_ok = WriteFile(h, data, (DWORD)data_len, &size, NULL); + assert(!f_ok || ((DWORD)data_len == size)); + CloseHandle(h); + return f_ok; +} +#else +// not supported +#endif diff --git a/rosapps/smartpdf/baseutils/file_util.h b/rosapps/smartpdf/baseutils/file_util.h new file mode 100644 index 00000000000..5ff05b8c72c --- /dev/null +++ b/rosapps/smartpdf/baseutils/file_util.h @@ -0,0 +1,61 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef FILE_UTILS_H_ +#define FILE_UTILS_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct DirIterState { + char * fileName; + char * cleanPath; + char * iterPath; + WIN32_FIND_DATAA fileInfo; + HANDLE dir; +} DirIterState; + +typedef struct FileInfo { + struct FileInfo *next; + char * path; /* full path of the file e.g. c:\foo\bar.txt */ + char * name; /* just the name part e.g. bar.txt, points into 'path' */ + int64 size; + FILETIME modificationTime; + FILETIME accessTime; + FILETIME createTime; + DWORD attr; + /* TODO: file attributes like file type etc. */ +} FileInfo; + +typedef struct FileList { + FileInfo * first; + char * dirName; /* directory where files lives e.g. c:\windows\ */ + int filesCount; +} FileList; + +DirIterState * DirIter_New(const char *path); +BOOL DirIter_Next(DirIterState *s); +void DirIter_Delete(DirIterState *state); + +BOOL FileInfo_IsFile(FileInfo *fi); +BOOL FileInfo_IsDir(FileInfo *fi); +void FileInfo_Delete(FileInfo *fi); +FileList * FileList_Get(char* path, int (*filter)(FileInfo *)); +FileList * FileList_GetRecursive(char* path, int (*filter)(FileInfo *)); +void FileList_Delete(FileList *fl); +int FileList_Len(FileList *fl); +FileInfo * FileList_GetFileInfo(FileList *fl, int file_no); + +const char * FilePath_GetBaseName(const char *path); +char * FilePath_GetDir(const char *path); + +char * file_read_all(const char *file_path, size_t *file_size_out); +size_t file_size_get(const char *file_path); +BOOL write_to_file(const TCHAR *file_path, void *data, size_t data_len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/geom_util.c b/rosapps/smartpdf/baseutils/geom_util.c new file mode 100644 index 00000000000..0b8d1e466f5 --- /dev/null +++ b/rosapps/smartpdf/baseutils/geom_util.c @@ -0,0 +1,225 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" +#include "geom_util.h" + +/* Return true if 'r1' and 'r2' intersect. Put the intersect area into + 'rIntersectOut'. + Return false if there is no intersection. */ +int RectI_Intersect(RectI *r1, RectI *r2, RectI *rIntersectOut) +{ + int x1s, x1e, x2s, x2e; + int y1s, y1e, y2s, y2e; + + int xIntersectS, xIntersectE; + int yIntersectS, yIntersectE; + + assert(r1 && r2 && rIntersectOut); + if (!r1 || !r2 || !rIntersectOut) + return 0; + + x1s = r1->x; + x2s = r2->x; + x1e = x1s + r1->dx; + x2e = x2s + r2->dx; + + /* { } visualizes r1 and | | visualizes r2 */ + + /* problem is symmetric, so reduce the number of different cases by + consistent ordering where r1 is always before r2 in axis-x */ + if (x2s < x1s) { + swap_int(&x1s, &x2s); + swap_int(&x1e, &x2e); + } + + /* case of non-overlapping rectangles i.e.: + { } | | */ + if (x2s > x1e) + return 0; + + /* partially overlapped i.e.: + { | } | + and one inside the other i.e.: + { | | } */ + + assert(x2s >= x1s); + assert(x2s <= x1e); + xIntersectS = x2s; + xIntersectE = MinInt(x1e, x2e); + assert(xIntersectE >= xIntersectS); + + /* the logic for y is the same */ + y1s = r1->y; + y2s = r2->y; + y1e = y1s + r1->dy; + y2e = y2s + r2->dy; + if (y2s < y1s) { + swap_int(&y1s, &y2s); + swap_int(&y1e, &y2e); + } + if (y2s > y1e) + return 0; + assert(y2s >= y1s); + assert(y2s <= y1e); + yIntersectS = y2s; + yIntersectE = MinInt(y1e, y2e); + + rIntersectOut->x = xIntersectS; + rIntersectOut->y = yIntersectS; + assert(xIntersectE >= xIntersectS); + assert(yIntersectE >= yIntersectS); + rIntersectOut->dx = xIntersectE - xIntersectS; + rIntersectOut->dy = yIntersectE - yIntersectS; + return 1; +} + +void RectI_FromXY(RectI *rOut, int xs, int xe, int ys, int ye) +{ + assert(rOut); + if (!rOut) + return; + assert(xs <= xe); + assert(ys <= ye); + rOut->x = xs; + rOut->y = ys; + rOut->dx = xe - xs; + rOut->dy = ye - ys; +} + +void RectD_FromRectI(RectD *rOut, RectI *rIn) +{ + rOut->x = (double)rIn->x; + rOut->y = (double)rIn->y; + rOut->dx = (double)rIn->dx; + rOut->dy = (double)rIn->dy; +} + +int intFromDouble (double d) { + double i1 = (int) d; + double i2 = i1 + 1; + + if (d - i1 < i2 - d) + return i1; + else + return i2; +} + +void RectI_FromRectD(RectI *rOut, RectD *rIn) +{ + rOut->x = intFromDouble(rIn->x); + rOut->y = intFromDouble(rIn->y); + rOut->dx = intFromDouble(rIn->dx); + rOut->dy = intFromDouble(rIn->dy); +} + +void RectD_Copy(RectD *rOut, RectD *rIn) { + rOut->x = (double)rIn->x; + rOut->y = (double)rIn->y; + rOut->dx = (double)rIn->dx; + rOut->dy = (double)rIn->dy; +} + +void RectD_FromXY(RectD *rOut, double xs, double xe, double ys, double ye) +{ + assert(rOut); + if (!rOut) + return; + if (xs > xe) + swap_double(&xs, &xe); + if (ys > ye) + swap_double(&ys, &ye); + + rOut->x = xs; + rOut->y = ys; + rOut->dx = xe - xs; + assert(rOut->dx >= 0.0); + rOut->dy = ye - ys; + assert(rOut->dy >= 0.0); +} + +/* Return TRUE if point 'x'/'y' is inside rectangle 'r' */ +int RectI_Inside(RectI *r, int x, int y) +{ + if (x < r->x) + return FALSE; + if (x > r->x + r->dx) + return FALSE; + if (y < r->y) + return FALSE; + if (y > r->y + r->dy) + return FALSE; + return TRUE; +} + +#ifndef NDEBUG +void RectI_AssertEqual(RectI *rIntersect, RectI *rExpected) +{ + assert(rIntersect->x == rExpected->x); + assert(rIntersect->y == rExpected->y); + assert(rIntersect->dx == rExpected->dx); + assert(rIntersect->dy == rExpected->dy); +} + +void u_RectI_Intersect(void) +{ + int i, dataLen; + RectI r1, r2, rIntersect, rExpected, rExpectedSwaped; + int doIntersect, doIntersectExpected; + + struct SRIData { + int x1s, x1e, y1s, y1e; + int x2s, x2e, y2s, y2e; + int intersect; + int i_xs, i_xe, i_ys, i_ye; + } testData[] = { + { 0,10, 0,10, 0,10, 0,10, 1, 0,10, 0,10 }, /* complete intersect */ + { 0,10, 0,10, 20,30,20,30, 0, 0, 0, 0, 0 }, /* no intersect */ + { 0,10, 0,10, 5,15, 0,10, 1, 5,10, 0,10 }, /* { | } | */ + { 0,10, 0,10, 5, 7, 0,10, 1, 5, 7, 0,10 }, /* { | | } */ + + { 0,10, 0,10, 5, 7, 5, 7, 1, 5, 7, 5, 7 }, + { 0,10, 0,10, 5, 15,5,15, 1, 5,10, 5,10 }, + }; + dataLen = dimof(testData); + for (i = 0; i < dataLen; i++) { + struct SRIData *curr; + curr = &(testData[i]); + RectI_FromXY(&rExpected, curr->i_xs, curr->i_xe, curr->i_ys, curr->i_ye); + RectI_FromXY(&rExpectedSwaped, curr->i_ys, curr->i_ye, curr->i_xs, curr->i_xe); + + RectI_FromXY(&r1, curr->x1s, curr->x1e, curr->y1s, curr->y1e); + RectI_FromXY(&r2, curr->x2s, curr->x2e, curr->y2s, curr->y2e); + doIntersectExpected = curr->intersect; + + doIntersect = RectI_Intersect(&r1, &r2, &rIntersect); + assert(doIntersect == doIntersectExpected); + if (doIntersect) + RectI_AssertEqual(&rIntersect, &rExpected); + + /* if we swap rectangles, the results should be the same */ + RectI_FromXY(&r2, curr->x1s, curr->x1e, curr->y1s, curr->y1e); + RectI_FromXY(&r1, curr->x2s, curr->x2e, curr->y2s, curr->y2e); + doIntersect = RectI_Intersect(&r1, &r2, &rIntersect); + assert(doIntersect == doIntersectExpected); + if (doIntersect) + RectI_AssertEqual(&rIntersect, &rExpected); + + /* if we swap x with y coordinates in a rectangle, results should be the same */ + RectI_FromXY(&r1, curr->y1s, curr->y1e, curr->x1s, curr->x1e); + RectI_FromXY(&r2, curr->y2s, curr->y2e, curr->x2s, curr->x2e); + doIntersect = RectI_Intersect(&r1, &r2, &rIntersect); + assert(doIntersect == doIntersectExpected); + if (doIntersect) + RectI_AssertEqual(&rIntersect, &rExpectedSwaped); + + /* swap both rectangles and x with y, results should be the same */ + RectI_FromXY(&r2, curr->y1s, curr->y1e, curr->x1s, curr->x1e); + RectI_FromXY(&r1, curr->y2s, curr->y2e, curr->x2s, curr->x2e); + doIntersect = RectI_Intersect(&r1, &r2, &rIntersect); + assert(doIntersect == doIntersectExpected); + if (doIntersect) + RectI_AssertEqual(&rIntersect, &rExpectedSwaped); + } +} +#endif + diff --git a/rosapps/smartpdf/baseutils/geom_util.h b/rosapps/smartpdf/baseutils/geom_util.h new file mode 100644 index 00000000000..219458753d8 --- /dev/null +++ b/rosapps/smartpdf/baseutils/geom_util.h @@ -0,0 +1,73 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef GEOM_UTIL_H_ +#define GEOM_UTIL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct RectI { + int x, y; + int dx, dy; +} RectI; + +typedef struct RectD { + double x,y; + double dx,dy; +} RectD; + +int RectI_Intersect(RectI *r1, RectI *r2, RectI *rIntersectOut); +void RectI_FromXY(RectI *rOut, int xs, int xe, int ys, int ye); +int RectI_Inside(RectI *r, int x, int y); +void RectD_FromXY(RectD *rOut, double xs, double xe, double ys, double ye); +void RectD_FromRectI(RectD *rOut, RectI *rIn); +void RectI_FromRectD(RectI *rOut, RectD *rIn); +void RectD_Copy(RectD *rOut, RectD *rIn); +void u_RectI_Intersect(void); + +#ifdef __cplusplus +} +#endif + +/* allow using from both C and C++ code */ +#ifdef __cplusplus +class PointD { +public: + PointD() { x = 0; y = 0; } + PointD(double _x, double _y) { x = _x; y = _y; } + void set(double _x, double _y) { x = _x; y = _y; } + double x; + double y; +}; + +class SizeI { +public: + SizeI(int _dx, int _dy) { dx = _dx; dy = _dy; } + void set(int _dx, int _dy) { dx = _dx; dy = _dy; } + int dx; + int dy; +}; + +class SizeD { +public: + SizeD(double dx, double dy) { m_dx = dx; m_dy = dy; } + SizeD(int dx, int dy) { m_dx = (double)dx; m_dy = (double)dy; } + SizeD(SizeI si) { m_dx = (double)si.dx; m_dy = (double)si.dy; } + SizeD() { m_dx = 0; m_dy = 0; } + int dxI() { return (int)m_dx; } + int dyI() { return (int)m_dy; } + double dx() { return m_dx; } + double dy() { return m_dy; } + void setDx(double dx) { m_dx = dx; } + void setDy(double dy) { m_dy = dy; } + SizeI size() { return SizeI((int)dx(), (int)dy()); } /* @note: int casts */ +private: + double m_dx; + double m_dy; +}; + +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/log_util.c b/rosapps/smartpdf/baseutils/log_util.c new file mode 100644 index 00000000000..1241f7f3e01 --- /dev/null +++ b/rosapps/smartpdf/baseutils/log_util.c @@ -0,0 +1,160 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "log_util.h" +#include "str_util.h" + +/* Simple logging. 'slog' stands for "simple logging". I figured that 'log' + is a very common name so used something else, but still short as a prefix + for API names */ + +/* TODO: slogfmt(const char *fmt, ...) */ + +/* TODO: extend to more than one file, by keeping a list of file names */ +const TCHAR * g_cur_fileName = NULL; + +/* initialize logging system, should be called before any logging calls */ +BOOL slog_init(void) +{ + /* do nothing yet */ + return TRUE; +} + +/* deinitialize logging system. Should be called before the program quits */ +void slog_deinit(void) +{ + slog_file_log_stop(NULL); +} + +/* start logging to a file 'fileName'. From now on until slog_file_log_stop() + all slog* logging will also go to a file. If a file of that name already + exists, it'll overwrite it. */ +BOOL slog_file_log_start(const TCHAR *fileName) +{ + if (!fileName) return FALSE; + g_cur_fileName = tstr_dup(fileName); + DeleteFile(fileName); + return TRUE; +} + +/* like 'slog_file_log_start' but will create a unique file based on 'fileName'. + If a 'fileName' has extension, it'll try the first available + '$file-$NNN.$ext' file (e.g. "my-app-log-000.txt") if 'fileName' is "my-app-log.txt" + If there is no extension, it'll be '$file-$NNN' */ +int slog_file_log_unique_start(const TCHAR *fileName) +{ + assert(0); /* not implemented */ + return FALSE; +} + +void slog_file_log_stop(const TCHAR *fileName) +{ + /* 'fileName' is currently unused. The idea is that it should match the + name given to slog_file_log_start */ + if (g_cur_fileName) { + free((void*)g_cur_fileName); + g_cur_fileName = NULL; + } +} + +/* log 'txt' to all currently enabled loggers */ +void slog_str(const char *txt) +{ + DWORD to_write_cb; + DWORD written_cb; + int f_ok; + HANDLE fh; + + if (!txt) return; + + if (!g_cur_fileName) return; + + /* we're using this inefficient way of re-opening the file for each + log so that we can also watch this file life using tail-like program */ + fh = CreateFile(g_cur_fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == fh) + return; + SetFilePointer(fh, 0, NULL, FILE_END); + to_write_cb = (DWORD)strlen(txt); + f_ok = WriteFile(fh, (void*)txt, to_write_cb, &written_cb, NULL); + assert(f_ok && (written_cb == to_write_cb)); + CloseHandle(fh); +} + +void slog_str_printf(const char *format, ...) +{ + char * tmp; + va_list args; + + va_start(args, format); + tmp = str_printf_args(format, args); + va_end(args); + if (!tmp) return; + slog_str(tmp); + free(tmp); +} + +static WCHAR* last_error_as_wstr(void) +{ + WCHAR *msgBuf = NULL; + WCHAR *copy; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &msgBuf, 0, NULL); + if (!msgBuf) return NULL; + copy = wstr_dup(msgBuf); + LocalFree(msgBuf); + return copy; +} + +void slog_last_error(const char *optional_prefix) +{ + WCHAR *txt = last_error_as_wstr(); + if (!txt) return; + slog_str(optional_prefix); + slog_wstr_nl(txt); + free(txt); +} + +/* TODO: converting by casting isn't always correct but here we don't care much */ +char *wstr_to_str(const WCHAR *txt) +{ + char *txt_copy, *tmp; + + if (!txt) return NULL; + + txt_copy = (char*)malloc(tstr_len(txt) + 1); + if (!txt_copy) return NULL; + + tmp = txt_copy; + while (*txt) { + *tmp++ = (char)*txt++; + } + *tmp = 0; + return txt_copy; +} + +void slog_wstr(const WCHAR *txt) +{ + char *txt_copy; + + txt_copy = wstr_to_str(txt); + if (!txt_copy) return; + slog_str(txt_copy); + free(txt_copy); +} + +/* log 'txt' to all currently enabled loggers and add newline */ +void slog_str_nl(const char *txt) +{ + /* TODO: given the 'reopen the file each time' implementation of + slgotxt, this should be optimized */ + slog_str(txt); + slog_str("\n"); +} + +void slog_wstr_nl(const WCHAR *txt) +{ + slog_wstr(txt); + slog_wstr(_T("\n")); +} diff --git a/rosapps/smartpdf/baseutils/log_util.h b/rosapps/smartpdf/baseutils/log_util.h new file mode 100644 index 00000000000..6dd8b180fcc --- /dev/null +++ b/rosapps/smartpdf/baseutils/log_util.h @@ -0,0 +1,23 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef LOG_UTIL_H_ +#define LOG_UTIL_H_ + +#include "base_util.h" +#include "tstr_util.h" + +BOOL slog_init(void); +void slog_deinit(void); +BOOL slog_file_log_start(const TCHAR *fileName); +void slog_file_log_stop(const TCHAR *fileName); +void slog_str(const char *txt); +void slog_str_printf(const char *format, ...); +void slog_str_nl(const char *txt); + +void slog_last_error(const char *optional_prefix); + +void slog_wstr(const WCHAR *txt); +void slog_wstr_nl(const WCHAR *txt); + +#endif + diff --git a/rosapps/smartpdf/baseutils/makefile.msvc b/rosapps/smartpdf/baseutils/makefile.msvc new file mode 100644 index 00000000000..6353b26ee2f --- /dev/null +++ b/rosapps/smartpdf/baseutils/makefile.msvc @@ -0,0 +1,76 @@ +OUTDIR=obj-dummy +CC=cl.exe + +VALID_TARGET=no + +!if "$(TARGET)"=="rel" +OUTDIR=obj-win-rel +CFLAGS = $(CFLAGS) /D "NDEBUG" /D "_SECURE_CSL=0" /MD /Ox +LDFLAGS = $(LDFLAGS) /OPT:NOWIN98 +VALID_TARGET=yes +!endif + +!if "$(TARGET)"=="rel-unicode" +OUTDIR=obj-win-rel-unicode +CFLAGS = $(CFLAGS) /D "NDEBUG" /D "_SECURE_CSL=0" /D "UNICODE" /MD /Ox +LDFLAGS = $(LDFLAGS) /OPT:NOWIN98 +VALID_TARGET=yes +!endif + +!if "$(TARGET)"=="dbg" +OUTDIR=obj-win-dbg +CFLAGS = $(CFLAGS) /D "_SECURE_CSL=0" /MDd /Od +VALID_TARGET=yes +!endif + +!if "$(TARGET)"=="dbg-unicode" +OUTDIR=obj-win-dbg-unicode +CFLAGS = $(CFLAGS) /D "_SECURE_CSL=0" /D "UNICODE" /MDd /Od +VALID_TARGET=yes +!endif + +O=$(OUTDIR) +CFLAGS = $(CFLAGS) /nologo /c +CFLAGS = $(CFLAGS) /D "WIN32" /D "_WIN32_WINNT=0x0500" +CFLAGS = $(CFLAGS) /W3 /Zc:forScope /Zc:wchar_t /GR /Zi +CFLAGS = $(CFLAGS) /I. + +LIBS = $(LIBS) kernel32.lib advapi32.lib comctl32.lib comdlg32.lib \ + shell32.lib user32.lib gdi32.lib + +LD = link.exe +LDFLAGS = $(LDFLAGS) /nologo /DEBUG + +TEST_FILE_UTIL_OBJS=$(O)\base_util.obj $(O)\file_util.obj $(O)\geom_util.obj \ + $(O)\prefs_util.obj $(O)\netstr.obj $(O)\str_util.obj $(O)\WinUtil.obj \ + $(O)\win_util.obj $(O)\wstr_util.obj \ + $(O)\test_file_util.obj +TEST_FILE_UTIL_EXE=$(O)\test_file_util.exe +TEST_FILE_UTIL_PDB=$(O)\test_file_util.pdb + +!if "$(VALID_TARGET)"=="yes" +all: $(OUTDIR) $(TEST_FILE_UTIL_EXE) + +$(OUTDIR): force + @if not exist $(OUTDIR) mkdir $(OUTDIR) + +clean: force + -rmdir /S /Q $(OUTDIR) +!else +all clean: force + @echo TARGET must be set to: rel, dbg, rel-unicode or dbg-unicode +!endif + +$(TEST_FILE_UTIL_EXE): $(TEST_FILE_UTIL_OBJS) + $(LD) $(LDFLAGS) /OUT:$@ \ + /PDB:$(TEST_FILE_UTIL_PDB) \ + $** $(LIBS) /SUBSYSTEM:CONSOLE /MACHINE:X86 + +.cpp{$(OUTDIR)}.obj:: + $(CC) $(CFLAGS) -Fo$(OUTDIR)\ $< + +.c{$(OUTDIR)}.obj:: + $(CC) $(CFLAGS) -Fo$(OUTDIR)\ $< + +force: ; + diff --git a/rosapps/smartpdf/baseutils/ms_ui_helper.c b/rosapps/smartpdf/baseutils/ms_ui_helper.c new file mode 100644 index 00000000000..ec42a33bf69 --- /dev/null +++ b/rosapps/smartpdf/baseutils/ms_ui_helper.c @@ -0,0 +1,634 @@ +/*++ + +Copyright (c) 2003 Microsoft Corporation + +Abstract: + + Helper functions for HIDPI/Landscape support. + +--*/ + +#include "ms_ui_helper.h" + +HIDPI_ENABLE; + +BOOL HIDPI_StretchBitmap( + HBITMAP* phbm, + int cxDstImg, + int cyDstImg, + int cImagesX, + int cImagesY + ) +{ + BOOL fRet = FALSE; + HBITMAP hbmNew; + BITMAP bm; + HDC hdcSrc, hdcDst, hdcScreen; + HBITMAP hbmOldSrc, hbmOldDst; + int cxSrcImg, cySrcImg; + int i, j, xDest, yDest, xBmp, yBmp; + + if (!phbm || !*phbm || (cxDstImg == 0 && cyDstImg == 0) || (cImagesX == 0 || cImagesY == 0)) + goto donestretch; + + if ((sizeof(bm) != GetObject(*phbm, sizeof(bm), &bm))) + goto donestretch; + + // If you hit this ASSERT, that mean your passed in image count in row and + // the column number of images is not correct. + // ASSERT(((bm.bmWidth % cImagesX) == 0) && ((bm.bmHeight % cImagesY) == 0)); + + cxSrcImg = bm.bmWidth / cImagesX; + cySrcImg = bm.bmHeight / cImagesY; + + if (cxSrcImg == cxDstImg && cySrcImg == cyDstImg) + { + fRet = TRUE; + goto donestretch; + } + + if (cxDstImg == 0) + cxDstImg = HIDPIMulDiv(cyDstImg, cxSrcImg, cySrcImg); + else if (cyDstImg == 0) + cyDstImg = HIDPIMulDiv(cxDstImg, cySrcImg, cxSrcImg); + + hdcSrc = CreateCompatibleDC(NULL); + hdcDst = CreateCompatibleDC(NULL); + hdcScreen = GetDC(NULL); + hbmOldSrc = (HBITMAP)SelectObject(hdcSrc, *phbm); + hbmNew = CreateCompatibleBitmap(hdcScreen, cxDstImg * cImagesX, cyDstImg * cImagesY); + hbmOldDst = (HBITMAP)SelectObject(hdcDst, hbmNew); + ReleaseDC(NULL, hdcScreen); + + // BLAST! + for (j = 0, yDest = 0, yBmp = 0; j < cImagesY; j++, yDest += cyDstImg, yBmp += cySrcImg) + { + for (i = 0, xDest = 0, xBmp = 0; i < cImagesX; i++, xDest += cxDstImg, xBmp += cxSrcImg) + { + StretchBlt(hdcDst, xDest, yDest, cxDstImg, cyDstImg, + hdcSrc, xBmp, yBmp, cxSrcImg, cySrcImg, + SRCCOPY); + } + } + + // Free allocated memory + SelectObject(hdcSrc, hbmOldSrc); + SelectObject(hdcDst, hbmOldDst); + DeleteDC(hdcSrc); + DeleteDC(hdcDst); + + // Delete the passed in bitmap + DeleteObject(*phbm); + *phbm = hbmNew; + + fRet = TRUE; + +donestretch: + return fRet; +} + +static BOOL HIDPI_StretchIcon_Internal( + HICON hiconIn, + HICON* phiconOut, + int cxIcon, + int cyIcon +) +{ + ICONINFO iconinfo; + + HDC hdc; + HBITMAP hbmImage, hbmMask; + HBITMAP hbmOld; + BOOL fDrawMaskOK; + BOOL fDrawImageOK; + + *phiconOut = NULL; + hdc = CreateCompatibleDC(NULL); + + hbmMask = CreateCompatibleBitmap(hdc, cxIcon, cyIcon); + hbmOld = (HBITMAP)SelectObject(hdc, hbmMask); + fDrawMaskOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_MASK); + SelectObject(hdc, hbmOld); + + hbmImage = CreateBitmap(cxIcon, cyIcon, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL); + hbmOld = (HBITMAP)SelectObject(hdc, hbmImage); + fDrawImageOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_IMAGE); + SelectObject(hdc, hbmOld); + + if (fDrawImageOK && fDrawMaskOK) + { + iconinfo.fIcon = TRUE; + iconinfo.hbmColor = hbmImage; + iconinfo.hbmMask = hbmMask; + *phiconOut = CreateIconIndirect(&iconinfo); + } + + DeleteObject(hbmImage); + DeleteObject(hbmMask); + + DeleteDC(hdc); + + return (fDrawImageOK && fDrawMaskOK && *phiconOut != NULL) ? TRUE : FALSE; +} + +BOOL HIDPI_StretchIcon( + HICON* phic, + int cxIcon, + int cyIcon +) +{ + HICON hiconOut; + + if (HIDPI_StretchIcon_Internal(*phic, &hiconOut, cxIcon, cyIcon)) + { + DestroyIcon(*phic); + *phic = hiconOut; + return TRUE; + } + + return FALSE; +} + + +BOOL HIDPI_GetBitmapLogPixels( + HINSTANCE hinst, + LPCTSTR lpbmp, + int* pnLogPixelsX, + int* pnLogPixelsY + ) +{ + BOOL fRet = FALSE; + HRSRC hResource; + HGLOBAL hResourceBitmap = NULL; + BITMAPINFO* pBitmapInfo; + int PelsPerMeterX, PelsPerMeterY; + + *pnLogPixelsX = 0; + *pnLogPixelsY = 0; + + hResource = FindResource(hinst, lpbmp, RT_BITMAP); + if (!hResource) + { + goto error; + } + hResourceBitmap = LoadResource(hinst, hResource); + if (!hResourceBitmap) + { + goto error; + } + pBitmapInfo = (BITMAPINFO*)LockResource(hResourceBitmap); + if (!pBitmapInfo) + { + goto error; + } + + // There are at least three kind value of PslsPerMeter used for 96 DPI bitmap: + // 0 - the bitmap just simply doesn't set this value + // 2834 - 72 DPI + // 3780 - 96 DPI + // So any value of PslsPerMeter under 3780 should be treated as 96 DPI bitmap. + PelsPerMeterX = (pBitmapInfo->bmiHeader.biXPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biXPelsPerMeter; + PelsPerMeterY = (pBitmapInfo->bmiHeader.biYPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biYPelsPerMeter; + + // The formula for converting PelsPerMeter to LogPixels(DPI) is: + // LogPixels = PelsPerMeter / 39.37 + // ( PelsPerMeter : Pixels per meter ) + // ( LogPixels : Pixels per inch ) + // Note: We need to round up. + *pnLogPixelsX = (int)((PelsPerMeterX * 100 + 1968) / 3937); + *pnLogPixelsY = (int)((PelsPerMeterY * 100 + 1968) / 3937); + + fRet = TRUE; + +error: + return fRet; +} + + +HIMAGELIST HIDPI_ImageList_LoadImage( + HINSTANCE hinst, + LPCTSTR lpbmp, + int cx, + int cGrow, + COLORREF crMask, + UINT uType, + UINT uFlags + ) +{ + HBITMAP hbmImage = NULL; + HIMAGELIST piml = NULL; + BITMAP bm; + int cImages, cxImage, cy; + int BmpLogPixelsX, BmpLogPixelsY; + UINT flags; + + if ((uType != IMAGE_BITMAP) || // Image type is not IMAGE_BITMAP + (cx == 0)) // Caller doesn't care about the dimensions of the image - assumes the ones in the file + { + piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags); + goto cleanup; + } + + if (!HIDPI_GetBitmapLogPixels(hinst, lpbmp, &BmpLogPixelsX, &BmpLogPixelsY)) + { + goto cleanup; + } + + hbmImage = (HBITMAP)LoadImage(hinst, lpbmp, uType, 0, 0, uFlags); + if (!hbmImage || (sizeof(bm) != GetObject(hbmImage, sizeof(bm), &bm))) + { + goto cleanup; + } + + // do we need to scale this image? + if (BmpLogPixelsX == g_HIDPI_LogPixelsX) + { + piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags); + goto cleanup; + } + + cxImage = HIDPIMulDiv(cx, BmpLogPixelsX, g_HIDPI_LogPixelsX); + + // Bitmap width should be multiple integral of image width. + // If not, that means either your bitmap is wrong or passed in cx is wrong. + // ASSERT((bm.bmWidth % cxImage) == 0); + + cImages = bm.bmWidth / cxImage; + + cy = HIDPIMulDiv(bm.bmHeight, g_HIDPI_LogPixelsY, BmpLogPixelsY); + + if ((g_HIDPI_LogPixelsX % BmpLogPixelsX) == 0) + { + HIDPI_StretchBitmap(&hbmImage, cx * cImages, cy, 1, 1); + } + else + { + // Here means the DPI is not integral multiple of standard DPI (96DPI). + // So if we stretch entire bitmap together, we are not sure each indivisual + // image will be stretch to right place. It is controled by StretchBlt(). + // (for example, a 16 pixel icon, the first one might be stretch to 22 pixels + // and next one might be stretched to 20 pixels) + // What we have to do here is stretching indivisual image separately to make sure + // every one is stretched properly. + HIDPI_StretchBitmap(&hbmImage, cx, cy, cImages, 1); + } + + flags = 0; + // ILC_MASK is important for supporting CLR_DEFAULT + if (crMask != CLR_NONE) + { + flags |= ILC_MASK; + } + // ILC_COLORMASK bits are important if we ever want to Merge ImageLists + if (bm.bmBits) + { + flags |= (bm.bmBitsPixel & ILC_COLORMASK); + } + + // bitmap MUST be de-selected from the DC + // create the image list of the size asked for. + piml = ImageList_Create(cx, cy, flags, cImages, cGrow); + + if (piml) + { + int added; + + if (crMask == CLR_NONE) + { + added = ImageList_Add(piml, hbmImage, NULL); + } + else + { + added = ImageList_AddMasked(piml, hbmImage, crMask); + } + + if (added < 0) + { + ImageList_Destroy(piml); + piml = NULL; + } + } + +cleanup: + DeleteObject(hbmImage); + return piml; +} + +int HIDPI_ImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon) +{ + int iRet; + int cxIcon, cyIcon; + HICON hiconStretched; + + ImageList_GetIconSize(himl, &cxIcon, &cyIcon); + HIDPI_StretchIcon_Internal(hicon, &hiconStretched, cxIcon, cyIcon); + if (hiconStretched != NULL) + { + iRet = ImageList_ReplaceIcon(himl, i, hiconStretched); + DestroyIcon(hiconStretched); + } + else + { + iRet = ImageList_ReplaceIcon(himl, i, hicon); + } + + return iRet; +} + +BOOL HIDPI_RectangleInternal(HDC hdc, int nLeft, int nTop, int nRight, int nBottom, int nThickness) +{ + int nOff = nThickness/2; + + nLeft += nOff; + nTop += nOff; + nRight -= nOff; + nBottom -= nOff; + + return Rectangle(hdc, nLeft, nTop, nRight, nBottom); +} + +#define BORDERX_PEN 32 + +BOOL HIDPI_BorderRectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom) +{ + HPEN hpenOld; + BOOL bRet; + + hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN)); + bRet = HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, GetSystemMetrics(SM_CXBORDER)); + SelectObject(hdc, hpenOld); + + return bRet; +} + +BOOL HIDPI_Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom) +{ + LOGPEN lpenSel; + HPEN hpenSel; + + // Obtain current pen thickness + hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN); + GetObject(hpenSel, sizeof(lpenSel), &lpenSel); + + return HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, lpenSel.lopnWidth.x); +} + + +BOOL HIDPI_PolylineInternal(HDC hdc, const POINT *lppt, int cPoints, int nStyle, int nThickness) +{ + int i; + int nHOff = 0, nVOff = 0; + BOOL bRet = TRUE; + POINT pts[2]; + + if (! (nStyle & PS_BIAS_MASK)) + { + // No drawing bias. Draw normally + return Polyline(hdc, lppt, cPoints); + } + + // Make sure caller didn't try to get both a left and a right bias or both a down and an up bias + // ASSERT(!(nStyle & PS_LEFTBIAS) || !(nStyle & PS_RIGHTBIAS)); + // ASSERT(!(nStyle & PS_UPBIAS) || !(nStyle & PS_DOWNBIAS)); + + if (nStyle & PS_LEFTBIAS) + { + nHOff = -((nThickness-1)/2); + } + + if (nStyle & PS_RIGHTBIAS) + { + nHOff = nThickness/2; + } + + if (nStyle & PS_UPBIAS) + { + nVOff = -((nThickness-1)/2); + } + + if (nStyle & PS_DOWNBIAS) + { + nVOff = nThickness/2; + } + + for (i = 1; i < cPoints; i++) + { + // Use the two points that specify current line segment + memcpy(pts, &lppt[i-1], 2*sizeof(POINT)); + if (abs(lppt[i].x - lppt[i-1].x) <= abs(lppt[i].y - lppt[i-1].y)) + { + // Shift current line segment horizontally if abs(slope) >= 1 + pts[0].x += nHOff; + pts[1].x += nHOff; + } + else + { + // Shift current line segment vertically if abs(slope) < 1 + pts[0].y += nVOff; + pts[1].y += nVOff; + } + bRet = bRet && Polyline(hdc, pts, 2); + if (!bRet) + { + goto Error; + } + } + +Error: + return bRet; +} + +BOOL HIDPI_BorderPolyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle) +{ + HPEN hpenOld; + BOOL bRet; + + hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN)); + bRet = HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, GetSystemMetrics(SM_CXBORDER)); + SelectObject(hdc, hpenOld); + + return bRet; +} + +BOOL HIDPI_Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle) +{ + LOGPEN lpenSel; + HPEN hpenSel; + + // Obtain current pen thickness + hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN); + GetObject(hpenSel, sizeof(lpenSel), &lpenSel); + + return HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, lpenSel.lopnWidth.x); +} + +// +// Called by RelayoutDialog to advance to the next item in the dialog template. +// +static LPBYTE WalkDialogData(LPBYTE lpData) +{ + LPWORD lpWord = (LPWORD)lpData; + if (*lpWord == 0xFFFF) + { + return (LPBYTE)(lpWord + 2); + } + while (*lpWord != 0x0000) + { + lpWord++; + } + return (LPBYTE)(lpWord + 1); +} + +// +// Post-processing step for each dialog item. +// Static controls and buttons: change text and bitmaps. +// Listboxes and combo boxes: ensures that the selected item is visible. +// +static void FixupDialogItem( + HINSTANCE hInst, + HWND hDlg, + LPDLGITEMTEMPLATE lpDlgItem, + LPWORD lpClass, + LPWORD lpData) +{ + if (lpClass[0] == 0xFFFF) + { + switch (lpClass[1]) + { + case 0x0080: // button + case 0x0082: // static + { + if (lpData[0] == 0xFFFF) + { + if (lpDlgItem->style & SS_ICON) + { + HICON hOld = (HICON)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_ICON, 0); + HICON hNew = LoadIcon(hInst, MAKEINTRESOURCE(lpData[1])); + SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hNew); + DestroyIcon(hOld); + } + else if (lpDlgItem->style & SS_BITMAP) + { + HBITMAP hOld = (HBITMAP)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_BITMAP, 0); + HBITMAP hNew = LoadBitmap(hInst, MAKEINTRESOURCE(lpData[1])); + SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hNew); + DeleteObject(hOld); + } + } + else // lpData[0] is not 0xFFFF (it's text). + { + SetDlgItemTextW(hDlg, lpDlgItem->id, (LPCTSTR)lpData); + } + } + break; + + case 0x0083: // list box + { + INT nSel = SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_GETCURSEL, 0, 0); + if (nSel != LB_ERR) + { + SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_SETCURSEL, nSel, 0); + } + } + break; + + case 0x0085: // combo box + { + INT nSel = SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_GETCURSEL, 0, 0); + if (nSel != CB_ERR) + { + SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_SETCURSEL, nSel, 0); + } + } + break; + } + } +} + +BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate) +{ + HRSRC hRsrc = FindResource((HMODULE)hInst, iddTemplate, RT_DIALOG); + INT nStatics = 0; + HGLOBAL hGlobal; + LPBYTE lpData; + LPDLGTEMPLATE lpTemplate; + HDWP hDWP; + int i; + LPDLGITEMTEMPLATE lpDlgItem; + HWND hwndCtl; + LPWORD lpClass; + WORD cbExtra; + + if (hRsrc == NULL) + { + return FALSE; + } + + hGlobal = LoadResource((HMODULE)hInst, hRsrc); + if (hGlobal == NULL) + { + return FALSE; + } + + lpData = (LPBYTE)LockResource(hGlobal); + lpTemplate = (LPDLGTEMPLATE)lpData; + hDWP = BeginDeferWindowPos(lpTemplate->cdit); + + // + // For more information about the data structures that we are walking, + // consult the DLGTEMPLATE and DLGITEMTEMPLATE documentation on MSDN. + // + lpData += sizeof(DLGTEMPLATE); + lpData = WalkDialogData(lpData); // menu + lpData = WalkDialogData(lpData); // class + lpData = WalkDialogData(lpData); // title + + if (lpTemplate->style & DS_SETFONT) + { + lpData += sizeof(WORD); // font size. + lpData = WalkDialogData(lpData); // font face. + } + + for (i = 0; i < lpTemplate->cdit; i++) + { + lpData = (LPBYTE) (((INT)lpData + 3) & ~3); // force to DWORD boundary. + lpDlgItem = (LPDLGITEMTEMPLATE)lpData; + hwndCtl = GetDlgItem(hDlg, lpDlgItem->id); + + if (lpDlgItem->id == 0xFFFF) + { + nStatics++; + } + + // + // Move the item around. + // + { + RECT r; + r.left = lpDlgItem->x; + r.top = lpDlgItem->y; + r.right = lpDlgItem->x + lpDlgItem->cx; + r.bottom = lpDlgItem->y + lpDlgItem->cy; + MapDialogRect(hDlg, &r); + DeferWindowPos(hDWP, hwndCtl, NULL, + r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER); + } + + lpData += sizeof(DLGITEMTEMPLATE); + lpClass = (LPWORD)lpData; + lpData = WalkDialogData(lpData); // class + + // + // Do some special handling for each dialog item (changing text, + // bitmaps, ensuring visible, etc. + // + FixupDialogItem(hInst, hDlg, lpDlgItem, lpClass, (LPWORD)lpData); + + lpData = WalkDialogData(lpData); // title + cbExtra = *((LPWORD)lpData); // extra class data. + lpData += (cbExtra ? cbExtra : sizeof(WORD)); + } + + EndDeferWindowPos(hDWP); + return nStatics < 2 ? TRUE : FALSE; +} diff --git a/rosapps/smartpdf/baseutils/ms_ui_helper.h b/rosapps/smartpdf/baseutils/ms_ui_helper.h new file mode 100644 index 00000000000..2c6b40b7e9b --- /dev/null +++ b/rosapps/smartpdf/baseutils/ms_ui_helper.h @@ -0,0 +1,348 @@ +/*++ + +Copyright (c) 2003 Microsoft Corporation + +Module Name: + + uihelper.h + +Abstract: + + Include file for HIDPI / orientation / font change helper functions. + +--*/ + +#ifndef __UIHELPER_H__ +#define __UIHELPER_H__ + +#include +#include +#include "ms_ui_shguim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////////////// +// HIDPI functions and constants. +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ILC_COLORMASK +#define ILC_COLORMASK 0x00FE +#endif + +// +// The two macros HIDPISIGN and HIDPIABS are there to ensure correct rounding +// for negative numbers passed into HIDPIMulDiv as x (we want -1.5 to round +// to -1, 2.5 to round to 2, etc). So we use the absolute value of x, and then +// multiply the result by the sign of x. Y and z should never be negative, as +// y is the dpi of the device (presumably 192 or 96), and z is always 96, as +// that is our original dpi we developed on. +// + +#define HIDPISIGN(x) (((x)<0)?-1:1) +#define HIDPIABS(x) (((x)<0)?-(x):x) +#define HIDPIMulDiv(x,y,z) ((((HIDPIABS(x)*(y))+((z)>>1))/(z))*HIDPISIGN(x)) + +// +// Cached values of GetDeviceCaps(LOGPIXELSX/Y) for the screen DC. +// +EXTERN_C int g_HIDPI_LogPixelsX; +EXTERN_C int g_HIDPI_LogPixelsY; + +// +// You need to define these somewhere in your .c files only if you make use of +// the scaling macros. (Defined in UIHelper.cpp). +// +#define HIDPI_ENABLE \ + int g_HIDPI_LogPixelsX; \ + int g_HIDPI_LogPixelsY; + +// +// Scaling macros. +// +#define SCALEX(argX) (HIDPIMulDiv(argX,g_HIDPI_LogPixelsX,96)) +#define SCALEY(argY) (HIDPIMulDiv(argY,g_HIDPI_LogPixelsY,96)) + +#define UNSCALEX(argX) (HIDPIMulDiv(argX,96,g_HIDPI_LogPixelsX)) +#define UNSCALEY(argY) (HIDPIMulDiv(argY,96,g_HIDPI_LogPixelsY)) + +#define SCALERECT(rc) { rc.left = SCALEX(rc.left); rc.right = SCALEX(rc.right); rc.top = SCALEY(rc.top); rc.bottom = SCALEY(rc.bottom);} +#define SCALEPT(pt) { pt.x = SCALEX(pt.x); pt.y = SCALEY(pt.y);} + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_InitScaling +// +// PURPOSE: Initializes g_HIDPI_LogPixelsX and g_HIDPI_LogPixelsY. This +// should be called once at the beginning of any HIDPI-aware application. +// +__inline void HIDPI_InitScaling() +{ + HDC screen; + + if( g_HIDPI_LogPixelsX ) + return; + + screen = GetDC(NULL); + g_HIDPI_LogPixelsX = GetDeviceCaps(screen, LOGPIXELSX); + g_HIDPI_LogPixelsY = GetDeviceCaps(screen, LOGPIXELSY); + ReleaseDC(NULL, screen); +} + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_StretchBitmap +// +// PURPOSE: Stretches a bitmap containing a grid of images. There are +// cImagesX images per row and cImagesY rows per bitmap. Each image is +// scaled individually, so that there are no artifacts with non-integral +// scaling factors. If the bitmap contains only one image, set cImagesX +// and cImagesY to 1. +// +// ON ENTRY: +// HBITMAP* phbm: a pointer to the bitmap to be scaled. +// INT cxDstImg: the width of each image after scaling. +// INT cyDstImg: the height of each image after scaling. +// INT cImagesX: the number of images per row. This value should +// evenly divide the width of the bitmap. +// INT cImagesY: the number of rows in the bitmap. This value should +// evenly divide the height of the bitmap. +// +// ON EXIT: +// Returns TRUE on success, FALSE on failure. +// +// If any scaling has occured, the bitmap pointed to by phbm is deleted +// and is replaced by a new bitmap handle. +// +BOOL HIDPI_StretchBitmap( + HBITMAP* phbm, + int cxDstImg, + int cyDstImg, + int cImagesX, + int cImagesY + ); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_GetBitmapLogPixels +// +// PURPOSE: retrieves the DPI fields of the specified bitmap. +// +// ON ENTRY: +// HINSTANCE hinst: the HINSTANCE of the bitmap resource. +// LPCTSTR lpbmp: the ID of the bitmap resource. The MAKEINTRESOURCE +// macro can be used for integer IDs. +// INT* pnLogPixelsX: the returned value for the horizontal DPI field of +// the bitmap. This value is never less than 96. +// INT* pnLogPixelsY: the returned value for the vertical DPI field of +// the bitmap. This value is never less than 96. +// +// ON EXIT: +// Returns TRUE on success, FALSE on failure. +// +BOOL HIDPI_GetBitmapLogPixels( + HINSTANCE hinst, + LPCTSTR lpbmp, + int* pnLogPixelsX, + int* pnLogPixelsY + ); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_StretchIcon +// +// PURPOSE: stretches an icon to the specified size on 4.21 devices and later. +// On 4.20 and previous revisions of the OS, this is a no-op. +// +// ON ENTRY: +// HICON* phic: the icon to stretch. +// INT cxIcon: the desired width of the icon. +// INT cyIcon: the desired height of the icon. +// +// ON EXIT: +// Returns TRUE on success, FALSE on failure. +// +// If any stretching occurred, the icon pointed to by phic is deleted and +// is replaced by a new icon handle. +// +BOOL HIDPI_StretchIcon( + HICON* phic, + int cxIcon, + int cyIcon + ); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_ImageList_LoadImage +// +// PURPOSE: This function operates identically to ImageList_LoadImage, except +// that it first checks the DPI fields of the bitmap (using +// HIDPI_GetBitmapLogPixels); compares it to the DPI of the screen +// (using g_HIDPI_LogPixelsX and g_HIDPI_LogPixelsY), and performs scaling +// (using HIDPI_StretchBitmap) if the values are different. +// +// ON ENTRY: +// See the MSDN documentation for ImageList_LoadImage. +// +// ON EXIT: +// See the MSDN documentation for ImageList_LoadImage. +// +HIMAGELIST HIDPI_ImageList_LoadImage( + HINSTANCE hinst, + LPCTSTR lpbmp, + int cx, + int cGrow, + COLORREF crMask, + UINT uType, + UINT uFlags + ); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_ImageList_ReplaceIcon +// +// PURPOSE: Replaces an icon in an ImageList, scaling it from its original size +// to the size of the images in the ImageList. +// +// ON ENTRY: +// See the MSDN documentation for ImageList_ReplaceIcon. +// +// ON EXIT: +// See the MSDN documentation for ImageList_ReplaceIcon. +// +int HIDPI_ImageList_ReplaceIcon( + HIMAGELIST himl, + int i, + HICON hicon + ); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_ImageList_AddIcon +// +// PURPOSE: Adds an icon to an ImageList, scaling it from its original size +// to the size of the images in the ImageList. +// +// ON ENTRY: +// See the MSDN documentation for ImageList_AddIcon. +// +// ON EXIT: +// See the MSDN documentation for ImageList_AddIcon. +// +#define HIDPI_ImageList_AddIcon(himl, hicon) HIDPI_ImageList_ReplaceIcon(himl, -1, hicon) + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_Rectangle +// +// PURPOSE: Draws a rectangle using the currently selected pen. Drawing occurs +// completely within the drawing rectangle (the rectangle has an "inside +// frame" drawing style). +// +// ON ENTRY: +// HDC hdc: the display context of the drawing surface. +// INT nLeft: left bound of rectangle +// INT nTop: top bound of rectangle +// INT nRight: right bound of rectangle plus one. +// INT nBottom: bottom bound of rectangle plus one. +// +// ON EXIT: +// Returns TRUE on success, FALSE on failure. +// +BOOL HIDPI_Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_BorderRectangle +// +// PURPOSE: Draws a rectangle with the system border pen. Drawing occurs +// completely within the drawing rectangle (the rectangle has an "inside +// frame" drawing style). +// +// ON ENTRY: +// HDC hdc: the display context of the drawing surface. +// INT nLeft: left bound of rectangle +// INT nTop: top bound of rectangle +// INT nRight: right bound of rectangle plus one. +// INT nBottom: bottom bound of rectangle plus one. +// +// ON EXIT: +// Returns TRUE on success, FALSE on failure. +// +BOOL HIDPI_BorderRectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_Polyline +// +// PURPOSE: Draws a polyline using the currently selected pen. In addition, +// this function provides control over how the line will be drawn. +// +// ON ENTRY: +// HDC hdc: the display context of the drawing surface. +// const POINT* lppt: array of POINTS that specify line to draw. +// INT cPoints: number of points in array. +// INT nStyle: the style the pen should be drawn in. This may be an +// existing pen style, such as PS_SOLID, or one of the following styles: +// +// PS_LEFTBIAS PS_UPBIAS PS_UPLEFT +// PS_RIGHTBIAS PS_DOWNBIAS PS_DOWNRIGHT +// +// These styles indicate how the pen should "hang" from each line +// segment. By default, the pen is centered along the line, but with +// these line styles the developer can draw lines above, below, to the +// left or to the right of the line segment. +// +// ON EXIT: +// Returns TRUE on success, FALSE on failure. +// + +#define PS_RIGHTBIAS 0x10 +#define PS_LEFTBIAS 0x20 +#define PS_DOWNBIAS 0x40 +#define PS_UPBIAS 0x80 +#define PS_DOWNRIGHT (PS_DOWNBIAS | PS_RIGHTBIAS) +#define PS_UPLEFT (PS_UPBIAS | PS_LEFTBIAS) +#define PS_BIAS_MASK (PS_RIGHTBIAS | PS_LEFTBIAS | PS_DOWNBIAS | PS_UPBIAS) + +BOOL HIDPI_Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: HIDPI_BorderPolyline +// +// PURPOSE: Draws a polyline, but with the system border pen. In addition, +// this function provides control over how the line will be drawn. +// +// ON ENTRY: +// HDC hdc: the display context of the drawing surface. +// const POINT* lppt: array of POINTS that specify line to draw. +// INT cPoints: number of points in array. +// INT nStyle: the style the pen should be drawn in. See HIDPI_Polyline +// for more details. +// +// ON EXIT: +// Returns TRUE on success, FALSE on failure. +// +BOOL HIDPI_BorderPolyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle); + +//////////////////////////////////////////////////////////////////////////////// +// Orientation functions. +//////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: RelayoutDialog +// +// PURPOSE: Re-lays out a dialog based on a dialog template. This function +// iterates through all the child window controls and does a SetWindowPos +// for each. It also does a SetWindowText for each static text control +// and updates the selected bitmap or icon in a static image control. +// This assumes that the current dialog and the new template have all the +// same controls, with the same IDCs. +// +// ON ENTRY: +// HINSTANCE hInst: the hInstance of the current module. +// HWND hDlg: the dialog to layout. +// LPCWSTR iddTemplate: the new template for the dialog (can use +// the MAKEINTRESOURCE macro). +// +// ON EXIT: TRUE if success; FALSE if failure (either the iddTemplate is +// invalid, or there are two or more IDC_STATICs in the template). +// +BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate); + +#ifdef __cplusplus +} +#endif + +#endif // __UIHELPER_H__ diff --git a/rosapps/smartpdf/baseutils/ms_ui_shguim.h b/rosapps/smartpdf/baseutils/ms_ui_shguim.h new file mode 100644 index 00000000000..16a830557e6 --- /dev/null +++ b/rosapps/smartpdf/baseutils/ms_ui_shguim.h @@ -0,0 +1,96 @@ +/*++ + +Copyright (c) 2003 Microsoft Corporation + +Abstract: + + Include file for SHGetUIMetric. + +--*/ + +#ifndef __SHGUIM_H__ +#define __SHGUIM_H__ + +#include + +// +// Call RegisterWindowMessage on this string if you are interested in knowing +// when the UI metrics have changed. wParam will be 0, lParam will be one of the +// SHUIMETRICTYPE values to indicate what value has changed. Call SHGetUIMetrics +// to find out the new value. +// +#define SH_UIMETRIC_CHANGE TEXT("SH_UIMETRIC_CHANGE") + +#if _MSC_VER >= 1400 +#include +#else + +// +// Enumeration of metrics you can ask for. Note that you will only receive a +// notification for SHUIM_FONTSIZE_POINT when any these three values changes. +// +typedef enum tagSHUIMETRIC +{ + SHUIM_INVALID = 0, // Illegal + SHUIM_FONTSIZE_POINT, // Application font size (hundredths of a point) -- buffer is pointer to DWORD + SHUIM_FONTSIZE_PIXEL, // Application font size (in pixels) -- buffer is pointer to DWORD + SHUIM_FONTSIZE_PERCENTAGE, // Application font size as percentage of normal -- buffer is pointer to DWORD +} SHUIMETRIC; + +typedef HRESULT (*PSHGETUIMETRICS)(SHUIMETRIC, PVOID, DWORD, DWORD*); + +////////////////////////////////////////////////////////////////////////////// +// FUNCTION: SHGetUIMetrics +// +// PURPOSE: retrieves the shell's UI metrics. Although this function does not +// exist in the Pocket PC 2003 SDK, it exists AYGSHELL.DLL in newer +// versions of the Pocket PC. This function simply LoadLibrary's AYGSHELL +// and calls the function if it exists. +// +// ON ENTRY: +// SHUIMETRIC shuim: the metric to retrieve. +// PVOID pvBuffer: the retrieved data for the metric. +// DWORD cbBufferSize: the size of pvBuffer (should be sizeof(DWORD)). +// DWORD* pcbRequired: retrieves the minimum size of the buffer necessary +// to get the specified system UI metric. This can be NULL. +// + +__inline HRESULT SHGetUIMetrics(SHUIMETRIC shuim, PVOID pvBuffer, DWORD cbBufferSize, DWORD *pcbRequired) +{ + PSHGETUIMETRICS pSHGetUIMetrics = (PSHGETUIMETRICS)GetProcAddress(LoadLibrary(_T("AYGSHELL")), _T("SHGetUIMetrics")); + if (pSHGetUIMetrics) + { + return pSHGetUIMetrics(shuim, pvBuffer, cbBufferSize, pcbRequired); + } + else if (pvBuffer != NULL && cbBufferSize >= sizeof(DWORD)) + { + // + // Not supported on this version of Pocket PC, so come up with a reasonable default. + // + LOGFONT lf; + HFONT hFont = (HFONT)GetStockObject(SYSTEM_FONT); + GetObject(hFont, sizeof(lf), &lf); + switch (shuim) + { + case SHUIM_FONTSIZE_POINT: + { + HDC hDC = GetDC(NULL); + int nDPI = GetDeviceCaps(hDC, LOGPIXELSY); + ReleaseDC(NULL, hDC); + *(DWORD*)pvBuffer = (-lf.lfHeight * 7200) / nDPI; + break; + } + case SHUIM_FONTSIZE_PIXEL: *(DWORD*)pvBuffer = -lf.lfHeight; break; + case SHUIM_FONTSIZE_PERCENTAGE: *(DWORD*)pvBuffer = 100; break; + } + } + else if (pcbRequired) + { + *pcbRequired = sizeof(DWORD); + } + return S_OK; +} + +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/netstr.c b/rosapps/smartpdf/baseutils/netstr.c new file mode 100644 index 00000000000..c75edc03e60 --- /dev/null +++ b/rosapps/smartpdf/baseutils/netstr.c @@ -0,0 +1,271 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" +#include "tstr_util.h" +#include "netstr.h" + +/* Implements djb idea of net strings */ +/* Return the number of digits needed to represents a given number in base 10 + string representation. +*/ +size_t digits_for_number(int num) +{ + size_t digits = 1; + /* negative numbers need '-' in front of them */ + if (num < 0) { + ++digits; + num = -num; + } + + while (num >= 10) + { + ++digits; + num = num / 10; + } + return digits; +} + +/* Netstring format is a safe, easy and mostly human readable format for + serializing strings (well, any binary data). Netstring format is: + - a byte length of the data as a string + - ':' (single character) + - data + - ',' (single character) + e.g. "foo" is encoded as "3:foo," + I learned about netstring format from djb (http://cr.yp.to/proto/netstrings.txt) +*/ +size_t netstr_tstrn_serialized_len_cb(size_t str_len_cch) +{ + size_t total_len_cch; + + /* 2 is for ':" and ',' */ + total_len_cch = str_len_cch + digits_for_number((int)str_len_cch) + 2; + return total_len_cch * sizeof(TCHAR); +} + +/* Return number of bytes needed to serialize string 'str' in netstring format. */ +size_t netstr_tstr_serialized_len_cb(const TCHAR *str) +{ + size_t str_len_cch; + + if (!str) return 0; + str_len_cch = tstr_len(str); + return netstr_tstrn_serialized_len_cb(str_len_cch); +} + +/* Return number of bytes needed to serialize integer 'num' in netstring format. */ +size_t netstr_int_serialized_len_cb(int num) +{ + size_t str_len_cch; + size_t total_len_cch; + + str_len_cch = digits_for_number(num); + total_len_cch = str_len_cch + digits_for_number((int)str_len_cch) + 2; + return total_len_cch * sizeof(TCHAR); +} + +int netstr_tstr_serialize(const TCHAR *str, TCHAR **buf_ptr, size_t *buf_len_cb_ptr) +{ + char * buf; + size_t buf_len_cb; + size_t len_needed_cb; + TCHAR * num_str; + size_t str_len_cch; + size_t len_cb; + size_t total_len_cb = 0; + + assert(buf_len_cb_ptr); + if (!buf_len_cb_ptr) + return FALSE; + + if (!buf_ptr) + { + *buf_len_cb_ptr += netstr_tstr_serialized_len_cb(str); + return TRUE; + } + + buf = (char*)*buf_ptr; + assert(buf); + if (!buf) + return FALSE; + + buf_len_cb = *buf_len_cb_ptr; + assert(buf_len_cb > 0); + if (buf_len_cb <= 0) + return FALSE; + + len_needed_cb = netstr_tstr_serialized_len_cb(str); + if (len_needed_cb > buf_len_cb) + return FALSE; + + str_len_cch = tstr_len(str); + num_str = tstr_printf(_T("%d:"), str_len_cch); + if (!num_str) + return FALSE; + + len_cb = tstr_len(num_str)*sizeof(TCHAR); + memcpy(buf, num_str, len_cb); + buf += len_cb; + total_len_cb += len_cb; + assert(total_len_cb <= len_needed_cb); + len_cb = tstr_len(str)*sizeof(TCHAR); + memcpy(buf, str, len_cb); + buf += len_cb; + total_len_cb += len_cb; + assert(total_len_cb <= len_needed_cb); + len_cb = sizeof(TCHAR); + memcpy(buf, _T(","), len_cb); + buf += len_cb; + total_len_cb += len_cb; + assert(total_len_cb == len_needed_cb); + + *buf_len_cb_ptr -= total_len_cb; + *buf_ptr = (TCHAR*)buf; + free((void*)num_str); + return TRUE; +} + +int netstr_int_serialize(int num, TCHAR **buf_ptr, size_t *buf_len_cb_ptr) +{ + TCHAR * num_str; + int f_ok; + + assert(buf_len_cb_ptr); + if (!buf_len_cb_ptr) + return FALSE; + + if (!buf_ptr) + { + *buf_len_cb_ptr += netstr_int_serialized_len_cb(num); + return TRUE; + } + + num_str = tstr_printf(_T("%d"), num); + if (!num_str) + return FALSE; + + f_ok = netstr_tstr_serialize(num_str, buf_ptr, buf_len_cb_ptr); + free((void*)num_str); + return f_ok; +} + +/* Parse a netstring number i.e. a list of digits until ':', skipping ':'. + Returns FALSE if there's an error parsing (string doesn't follow the format) */ +static int netstr_get_str_len(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *num_out) +{ + int num = 0; + const TCHAR * tmp; + size_t str_len_cb; + TCHAR c; + int digit = 0; + + assert(str_ptr); + if (!str_ptr) + return FALSE; + assert(str_len_cb_ptr); + if (!str_len_cb_ptr) + return FALSE; + assert(num_out); + if (!num_out) + return FALSE; + + tmp = *str_ptr; + assert(tmp); + if (!tmp) + return FALSE; + + str_len_cb = *str_len_cb_ptr; + assert(str_len_cb > 0); + if (str_len_cb <= 0) + return FALSE; + + for (;;) { + str_len_cb -= sizeof(TCHAR); + if (str_len_cb < 0) + return FALSE; + c = *tmp++; + if (_T(':') == c) + break; + if ( (c >= _T('0')) && (c <= _T('9')) ) + digit = (int)c - _T('0'); + else + return FALSE; + num = (num * 10) + digit; + } + if (str_len_cb == *str_len_cb_ptr) + return FALSE; + + *str_ptr = tmp; + *str_len_cb_ptr = str_len_cb; + *num_out = num; + return TRUE; +} + +int netstr_valid_separator(TCHAR c) +{ + if (c == _T(',')) + return TRUE; + return FALSE; +} + +int netstr_parse_str(const TCHAR **str_ptr, size_t *str_len_cb_ptr, const TCHAR **str_out, size_t *str_len_cch_out) +{ + int f_ok; + size_t str_len_cch; + size_t str_len_cb; + const TCHAR * str; + const TCHAR * str_copy; + int num; + + f_ok = netstr_get_str_len(str_ptr, str_len_cb_ptr, &num); + if (!f_ok) + return FALSE; + assert(num >= 0); + str_len_cch = (size_t)num; + str_len_cb = (str_len_cch+1)*sizeof(TCHAR); + if (str_len_cb > *str_len_cb_ptr) + return FALSE; + + str = *str_ptr; + if (!netstr_valid_separator(str[str_len_cch])) + return FALSE; + str_copy = (const TCHAR*)tstr_dupn(str, str_len_cch); + if (!str_copy) + return FALSE; + *str_out = str_copy; + *str_len_cch_out = str_len_cch; + *str_ptr = str + str_len_cch + 1; + *str_len_cb_ptr -= str_len_cb ; + return TRUE; +} + +int netstr_parse_int(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *int_out) +{ + const TCHAR * str = NULL; + const TCHAR * tmp; + TCHAR c; + size_t str_len_cch; + int f_ok; + int num = 0; + int digit = 0; + + f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &str, &str_len_cch); + if (!f_ok) + return FALSE; + + tmp = str; + while (*tmp) { + c = *tmp++; + if ( (c >= _T('0')) && (c <= _T('9')) ) + digit = (int)c - _T('0'); + else + goto Error; + num = (num * 10) + digit; + } + *int_out = num; + free((void*)str); + return TRUE; +Error: + free((void*)str); + return FALSE; +} diff --git a/rosapps/smartpdf/baseutils/netstr.h b/rosapps/smartpdf/baseutils/netstr.h new file mode 100644 index 00000000000..a81e6e6fd40 --- /dev/null +++ b/rosapps/smartpdf/baseutils/netstr.h @@ -0,0 +1,28 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef NETSTR_H__ +#define NETSTR_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define NETSTR_SEP_TC _T(':') +#define NETSTR_END_TC _T(',') + +size_t digits_for_number(int num); + +size_t netstr_int_serialized_len_cb(int num); +size_t netstr_tstr_serialized_len_cb(const TCHAR *str); +size_t netstr_tstrn_serialized_len_cb(size_t str_len_cch); +int netstr_tstr_serialize(const TCHAR *str, TCHAR **buf_ptr, size_t *buf_len_cb_ptr); +int netstr_int_serialize(int num, TCHAR **buf_ptr, size_t *buf_len_cb_ptr); +int netstr_parse_str(const TCHAR **str_ptr, size_t *str_len_cb_ptr, const TCHAR **str_out, size_t *str_len_cch_out); +int netstr_parse_int(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *int_out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/netstr_ut.c b/rosapps/smartpdf/baseutils/netstr_ut.c new file mode 100644 index 00000000000..9686d0aa677 --- /dev/null +++ b/rosapps/smartpdf/baseutils/netstr_ut.c @@ -0,0 +1,26 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "netstr.h" + +void netstr_ut(void) +{ + assert(1 == digits_for_number(0)); + assert(1 == digits_for_number(9)); + assert(2 == digits_for_number(10)); + assert(2 == digits_for_number(19)); + assert(2 == digits_for_number(25)); + assert(3 == digits_for_number(125)); + assert(4 == digits_for_number(3892)); + assert(5 == digits_for_number(38392)); + assert(6 == digits_for_number(889931)); + assert(7 == digits_for_number(7812345)); + + assert(1 == digits_for_number(-0)); + assert(2 == digits_for_number(-9)); + assert(3 == digits_for_number(-10)); + assert(4 == digits_for_number(-125)); + assert(5 == digits_for_number(-3892)); + assert(6 == digits_for_number(-38392)); + assert(7 == digits_for_number(-889931)); + assert(8 == digits_for_number(-7812345)); +} diff --git a/rosapps/smartpdf/baseutils/pdiff.cc b/rosapps/smartpdf/baseutils/pdiff.cc new file mode 100644 index 00000000000..816d9f0e12f --- /dev/null +++ b/rosapps/smartpdf/baseutils/pdiff.cc @@ -0,0 +1,387 @@ +/* +Copyright (C) 2006 Yangli Hector Yee + +This 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 + +Code from http://pdiff.svn.sourceforge.net +*/ + +#include "pdiff.h" +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265f +#endif + +CompareArgs::CompareArgs() +{ + ImgA = NULL; + ImgB = NULL; + ImgDiff = NULL; + FieldOfView = 45.0f; + Gamma = 2.2f; + Luminance = 100.0f; +} + +CompareArgs::~CompareArgs() +{ + if (ImgA) delete ImgA; + if (ImgB) delete ImgB; + if (ImgDiff) delete ImgDiff; +} + +#define MAX_PYR_LEVELS 8 + +class LPyramid +{ +public: + LPyramid(float *image, int width, int height); + virtual ~LPyramid(); + float Get_Value(int x, int y, int level); +protected: + float *Copy(float *img); + void Convolve(float *a, float *b); + + // Succesively blurred versions of the original image + float *Levels[MAX_PYR_LEVELS]; + + int Width; + int Height; +}; + +LPyramid::LPyramid(float *image, int width, int height) : + Width(width), + Height(height) +{ + // Make the Laplacian pyramid by successively + // copying the earlier levels and blurring them + for (int i=0; i=Width) nx=2*(Width-1)-nx; + if (ny>=Height) ny=2*(Height-1)-ny; + a[index] += Kernel[i+2] * Kernel[j+2] * b[ny * Width + nx]; + } + } + } + } +} + +float LPyramid::Get_Value(int x, int y, int level) +{ + int index = x + y * Width; + int l = level; + if (l > MAX_PYR_LEVELS) l = MAX_PYR_LEVELS; + return Levels[level][index]; +} + +/* +* Given the adaptation luminance, this function returns the +* threshold of visibility in cd per m^2 +* TVI means Threshold vs Intensity function +* This version comes from Ward Larson Siggraph 1997 +*/ + +float tvi(float adaptation_luminance) +{ + // returns the threshold luminance given the adaptation luminance + // units are candelas per meter squared + + float log_a, r, result; + log_a = log10f(adaptation_luminance); + + if (log_a < -3.94f) { + r = -2.86f; + } else if (log_a < -1.44f) { + r = powf(0.405f * log_a + 1.6f , 2.18f) - 2.86f; + } else if (log_a < -0.0184f) { + r = log_a - 0.395f; + } else if (log_a < 1.9f) { + r = powf(0.249f * log_a + 0.65f, 2.7f) - 0.72f; + } else { + r = log_a - 1.255f; + } + + result = powf(10.0f , r); + + return result; + +} + +// computes the contrast sensitivity function (Barten SPIE 1989) +// given the cycles per degree (cpd) and luminance (lum) +float csf(float cpd, float lum) +{ + float a, b, result; + + a = 440.0f * powf((1.0f + 0.7f / lum), -0.2f); + b = 0.3f * powf((1.0f + 100.0f / lum), 0.15f); + + result = a * cpd * expf(-b * cpd) * sqrtf(1.0f + 0.06f * expf(b * cpd)); + + return result; +} + +/* +* Visual Masking Function +* from Daly 1993 +*/ +float mask(float contrast) +{ + float a, b, result; + a = powf(392.498f * contrast, 0.7f); + b = powf(0.0153f * a, 4.0f); + result = powf(1.0f + b, 0.25f); + + return result; +} + +// convert Adobe RGB (1998) with reference white D65 to XYZ +void AdobeRGBToXYZ(float r, float g, float b, float &x, float &y, float &z) +{ + // matrix is from http://www.brucelindbloom.com/ + x = r * 0.576700f + g * 0.185556f + b * 0.188212f; + y = r * 0.297361f + g * 0.627355f + b * 0.0752847f; + z = r * 0.0270328f + g * 0.0706879f + b * 0.991248f; +} + +void XYZToLAB(float x, float y, float z, float &L, float &A, float &B) +{ + static float xw = -1; + static float yw; + static float zw; + // reference white + if (xw < 0) { + AdobeRGBToXYZ(1, 1, 1, xw, yw, zw); + } + const float epsilon = 216.0f / 24389.0f; + const float kappa = 24389.0f / 27.0f; + float f[3]; + float r[3]; + r[0] = x / xw; + r[1] = y / yw; + r[2] = z / zw; + for (int i = 0; i < 3; i++) { + if (r[i] > epsilon) { + f[i] = powf(r[i], 1.0f / 3.0f); + } else { + f[i] = (kappa * r[i] + 16.0f) / 116.0f; + } + } + L = 116.0f * f[1] - 16.0f; + A = 500.0f * (f[0] - f[1]); + B = 200.0f * (f[1] - f[2]); +} + +unsigned long Yee_Compare(CompareArgs &args) +{ + if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) || + (args.ImgA->Get_Height() != args.ImgB->Get_Height())) { + return DIFFERENT_SIZES; + } + + unsigned int i, dim; + dim = args.ImgA->Get_Width() * args.ImgA->Get_Height(); + bool identical = true; + for (i = 0; i < dim; i++) { + if (args.ImgA->Get(i) != args.ImgB->Get(i)) { + identical = false; + break; + } + } + if (identical) { + return IDENTICAL; + } + + // assuming colorspaces are in Adobe RGB (1998) convert to XYZ + float *aX = new float[dim]; + float *aY = new float[dim]; + float *aZ = new float[dim]; + float *bX = new float[dim]; + float *bY = new float[dim]; + float *bZ = new float[dim]; + float *aLum = new float[dim]; + float *bLum = new float[dim]; + + float *aA = new float[dim]; + float *bA = new float[dim]; + float *aB = new float[dim]; + float *bB = new float[dim]; + + unsigned int x, y, w, h; + w = args.ImgA->Get_Width(); + h = args.ImgA->Get_Height(); + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + float r, g, b, l; + i = x + y * w; + r = powf(args.ImgA->Get_Red(i) / 255.0f, args.Gamma); + g = powf(args.ImgA->Get_Green(i) / 255.0f, args.Gamma); + b = powf(args.ImgA->Get_Blue(i) / 255.0f, args.Gamma); + AdobeRGBToXYZ(r,g,b,aX[i],aY[i],aZ[i]); + XYZToLAB(aX[i], aY[i], aZ[i], l, aA[i], aB[i]); + r = powf(args.ImgB->Get_Red(i) / 255.0f, args.Gamma); + g = powf(args.ImgB->Get_Green(i) / 255.0f, args.Gamma); + b = powf(args.ImgB->Get_Blue(i) / 255.0f, args.Gamma); + AdobeRGBToXYZ(r,g,b,bX[i],bY[i],bZ[i]); + XYZToLAB(bX[i], bY[i], bZ[i], l, bA[i], bB[i]); + aLum[i] = aY[i] * args.Luminance; + bLum[i] = bY[i] * args.Luminance; + } + } + + LPyramid *la = new LPyramid(aLum, w, h); + LPyramid *lb = new LPyramid(bLum, w, h); + + float num_one_degree_pixels = (float) (2 * tan( args.FieldOfView * 0.5 * M_PI / 180) * 180 / M_PI); + float pixels_per_degree = w / num_one_degree_pixels; + + float num_pixels = 1; + unsigned int adaptation_level = 0; + for (i = 0; i < MAX_PYR_LEVELS; i++) { + adaptation_level = i; + if (num_pixels > num_one_degree_pixels) break; + num_pixels *= 2; + } + + float cpd[MAX_PYR_LEVELS]; + cpd[0] = 0.5f * pixels_per_degree; + for (i = 1; i < MAX_PYR_LEVELS; i++) cpd[i] = 0.5f * cpd[i - 1]; + float csf_max = csf(3.248f, 100.0f); + + float F_freq[MAX_PYR_LEVELS - 2]; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) F_freq[i] = csf_max / csf( cpd[i], 100.0f); + + unsigned int pixels_failed = 0; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + int index = x + y * w; + float contrast[MAX_PYR_LEVELS - 2]; + float sum_contrast = 0; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) { + float n1 = fabsf(la->Get_Value(x,y,i) - la->Get_Value(x,y,i + 1)); + float n2 = fabsf(lb->Get_Value(x,y,i) - lb->Get_Value(x,y,i + 1)); + float numerator = (n1 > n2) ? n1 : n2; + float d1 = fabsf(la->Get_Value(x,y,i+2)); + float d2 = fabsf(lb->Get_Value(x,y,i+2)); + float denominator = (d1 > d2) ? d1 : d2; + if (denominator < 1e-5f) denominator = 1e-5f; + contrast[i] = numerator / denominator; + sum_contrast += contrast[i]; + } + if (sum_contrast < 1e-5) sum_contrast = 1e-5f; + float F_mask[MAX_PYR_LEVELS - 2]; + float adapt = la->Get_Value(x,y,adaptation_level) + lb->Get_Value(x,y,adaptation_level); + adapt *= 0.5f; + if (adapt < 1e-5) adapt = 1e-5f; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) { + F_mask[i] = mask(contrast[i] * csf(cpd[i], adapt)); + } + float factor = 0; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) { + factor += contrast[i] * F_freq[i] * F_mask[i] / sum_contrast; + } + if (factor < 1) factor = 1; + if (factor > 10) factor = 10; + float delta = fabsf(la->Get_Value(x,y,0) - lb->Get_Value(x,y,0)); + bool pass = true; + // pure luminance test + if (delta > factor * tvi(adapt)) { + pass = false; + } else { + // CIE delta E test with modifications + float color_scale = 1.0f; + // ramp down the color test in scotopic regions + if (adapt < 10.0f) { + color_scale = 1.0f - (10.0f - color_scale) / 10.0f; + color_scale = color_scale * color_scale; + } + float da = aA[index] - bA[index]; + float db = aB[index] - bB[index]; + da = da * da; + db = db * db; + float delta_e = (da + db) * color_scale; + if (delta_e > factor) { + pass = false; + } + } + if (!pass) { + pixels_failed++; + if (args.ImgDiff) { + args.ImgDiff->Set(255, 0, 0, 255, index); + } + } else { + if (args.ImgDiff) { + args.ImgDiff->Set(0, 0, 0, 255, index); + } + } + } + } + + if (aX) delete[] aX; + if (aY) delete[] aY; + if (aZ) delete[] aZ; + if (bX) delete[] bX; + if (bY) delete[] bY; + if (bZ) delete[] bZ; + if (aLum) delete[] aLum; + if (bLum) delete[] bLum; + if (la) delete la; + if (lb) delete lb; + if (aA) delete aA; + if (bA) delete bA; + if (aB) delete aB; + if (bB) delete bB; + + return (unsigned long)pixels_failed; + +} diff --git a/rosapps/smartpdf/baseutils/pdiff.h b/rosapps/smartpdf/baseutils/pdiff.h new file mode 100644 index 00000000000..9e75f1918e9 --- /dev/null +++ b/rosapps/smartpdf/baseutils/pdiff.h @@ -0,0 +1,81 @@ +#ifndef PDIFF_H_ +#define PDIFF_H_ + +/* +Copyright (C) 2006 Yangli Hector Yee + +This 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 + +Code from http://pdiff.sourceforge.net +*/ + +class RGBAImage +{ +public: + virtual int Get_Width(void) const = 0; + virtual int Get_Height(void) const = 0; + virtual unsigned char Get_Red(unsigned int i) = 0; + virtual unsigned char Get_Green(unsigned int i) = 0; + virtual unsigned char Get_Blue(unsigned int i) = 0; + virtual unsigned char Get_Alpha(unsigned int i) = 0; + virtual void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i) = 0; + virtual unsigned int Get(int i) const = 0; +}; + +class RGBAImageData : RGBAImage +{ +public: + RGBAImageData(int w, int h) + { + Width = w; + Height = h; + Data = new unsigned int[w * h]; + }; + ~RGBAImageData() { if (Data) delete[] Data; } + unsigned char Get_Red(unsigned int i) { return (Data[i] & 0xFF); } + unsigned char Get_Green(unsigned int i) { return ((Data[i]>>8) & 0xFF); } + unsigned char Get_Blue(unsigned int i) { return ((Data[i]>>16) & 0xFF); } + unsigned char Get_Alpha(unsigned int i) { return ((Data[i]>>24) & 0xFF); } + void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i) + { Data[i] = r | (g << 8) | (b << 16) | (a << 24); } + int Get_Width(void) const { return Width; } + int Get_Height(void) const { return Height; } + void Set(int x, int y, unsigned int d) { Data[x + y * Width] = d; } + unsigned int Get(int x, int y) const { return Data[x + y * Width]; } + unsigned int Get(int i) const { return Data[i]; } + +protected: + int Width; + int Height; + unsigned int * Data; +}; + +class CompareArgs { +public: + CompareArgs(); + ~CompareArgs(); + + RGBAImage *ImgA; + RGBAImage *ImgB; + RGBAImage *ImgDiff; + float FieldOfView; // Field of view in degrees + float Gamma; // The gamma to convert to linear color space + float Luminance; // the display's luminance +}; + +#define DIFFERENT_SIZES (unsigned long)-1 +#define IDENTICAL (unsigned long)0 + +unsigned long Yee_Compare(CompareArgs &args); + +#endif + diff --git a/rosapps/smartpdf/baseutils/prefs_util.c b/rosapps/smartpdf/baseutils/prefs_util.c new file mode 100644 index 00000000000..feede45c4dd --- /dev/null +++ b/rosapps/smartpdf/baseutils/prefs_util.c @@ -0,0 +1,256 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" +#include "tstr_util.h" +#include "prefs_util.h" +#include "netstr.h" + +/* length of PT_*_PREFIX string in characters. All should have the same length */ +#define TYPE_PREFIX_CCH_LEN 2 + +/* when we serialize names of variables, we prepend name with the following + type indentifiers */ +#define PT_INT_PREFIX _T("i ") +#define PT_STRING_PREFIX _T("s ") + +static int pref_type_valid(pref_type type) +{ + if (PT_INT == type) + return TRUE; + if (PT_STRING == type) + return TRUE; + return FALSE; +} + +/* Given a string value 'txt' and it's type 'type', return a string that + encodes type within a string */ +TCHAR *pref_tstr_with_type(const TCHAR *txt, pref_type type) +{ + if (PT_INT == type) + return tstr_cat(PT_INT_PREFIX, txt); + else if (PT_STRING == type) + return tstr_cat(PT_STRING_PREFIX, txt); + else + assert(0); + return NULL; +} + +/* Serialize 'pref' to a buffer 'buf_ptr' of size 'buf_len_cb_ptr'. + Return TRUE if ok, FALSE if failed (e.g. buffer is not large enough). + If 'buf_ptr' is NULL, returns desired size in 'buf_len_cb_ptr'. + */ +static int prefs_serialize_pref(prefs_data *pref, TCHAR **buf_ptr, size_t *buf_len_cb_ptr) +{ + size_t len_cb; + TCHAR * name_with_type; + int f_ok; + + assert(pref); + assert(pref->name); + assert(pref_type_valid(pref->type)); + assert(buf_len_cb_ptr); + + if (!buf_ptr) { + len_cb = netstr_tstrn_serialized_len_cb(TYPE_PREFIX_CCH_LEN + tstr_len(pref->name)); + if (PT_INT == pref->type) + len_cb += netstr_int_serialized_len_cb(*pref->data.data_int); + else if (PT_STRING == pref->type) + len_cb += netstr_tstr_serialized_len_cb(*pref->data.data_str); + else + assert(0); + *buf_len_cb_ptr = len_cb; + return TRUE; + } + + name_with_type = pref_tstr_with_type(pref->name, pref->type); + if (!name_with_type) return FALSE; + f_ok = netstr_tstr_serialize(name_with_type, buf_ptr, buf_len_cb_ptr); + free((void*)name_with_type); + if (!f_ok) + return FALSE; + + if (PT_INT == pref->type) + f_ok = netstr_int_serialize(*pref->data.data_int, buf_ptr, buf_len_cb_ptr); + else if (PT_STRING == pref->type) + f_ok = netstr_tstr_serialize(*pref->data.data_str, buf_ptr, buf_len_cb_ptr); + else + assert(0); + + if (!f_ok) + return FALSE; + + return TRUE; +} + +/* Return the size of memory required to serialize 'pref' data */ +static size_t prefs_serialized_pref_cb_len(prefs_data *pref) +{ + int f_ok; + size_t len; + + f_ok = prefs_serialize_pref(pref, NULL, &len); + if (!f_ok) + return 0; + return len; +} + +/* Serialize 'prefs' as string. Returns newly allocated string and + length, in bytes, of string in '*tstr_len_cb_ptr' (not including + terminating zero). 'tstr_len_cb_ptr' can be NULL. + Returns NULL on error. + Caller needs to free() the result */ +TCHAR *prefs_to_tstr(prefs_data *prefs, size_t *tstr_len_cb_ptr) +{ + int i = 0; + size_t total_serialized_len_cb = 0; + size_t len_cb; + int f_ok; + TCHAR * serialized = NULL; + TCHAR * tmp; + size_t tmp_len_cb; + + /* calculate the size of buffer required to serialize 'prefs' */ + while (prefs[i].name) { + len_cb = prefs_serialized_pref_cb_len(&(prefs[i])); + assert(len_cb > 0); + total_serialized_len_cb += len_cb; + ++i; + } + + if (0 == total_serialized_len_cb) + return NULL; + + /* allocate the buffer and serialize to it */ + serialized = (TCHAR*)malloc(total_serialized_len_cb+sizeof(TCHAR)); + if (!serialized) return NULL; + tmp = serialized; + tmp_len_cb = total_serialized_len_cb; + i = 0; + while (prefs[i].name) { + f_ok = prefs_serialize_pref(&(prefs[i]), &tmp, &tmp_len_cb); + assert(f_ok); + assert(tmp_len_cb >= 0); + ++i; + } + assert(0 == tmp_len_cb); + *tmp = 0; + if (tstr_len_cb_ptr) + *tstr_len_cb_ptr = total_serialized_len_cb; + return serialized; +} + +/* Find a variable with a given 'name' and 'type' in 'prefs' array */ +prefs_data *prefs_find_by_name_type(prefs_data *prefs, const TCHAR *name, pref_type type) +{ + int i = 0; + while (prefs[i].name) { + if ((prefs[i].type == type) && (tstr_ieq(name, prefs[i].name))) { + return &(prefs[i]); + } + ++i; + } + return NULL; +} + +/* Incrementally parse one serialized variable in a string '*str_ptr' of + remaining size '*str_len_cb_ptr'. + It reads name, type and value of the variable from the string and + updates 'prefs' slot with this name/type with this value. If slot + with a given name/type doesn't exist, nothing happens. + It updates the '*str_ptr' and '*str_len_cb_ptr' to reflect consuming + the part that contained one variable. The idea is to call it in a + loop until '*str_len_cb_ptr' reaches 0. + Returns FALSE on error. */ +static int prefs_parse_item(prefs_data *prefs, const TCHAR **str_ptr, size_t *str_len_cb_ptr) +{ + const TCHAR * name_with_type = NULL; + const TCHAR * name; + size_t str_len_cch; + const TCHAR * value_str = NULL; + int value_int; + int f_ok; + pref_type type; + prefs_data * pref; + + assert(str_ptr); + if (!str_ptr) return FALSE; + assert(str_len_cb_ptr); + if (!str_len_cb_ptr) return FALSE; + + f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &name_with_type, &str_len_cch); + if (!f_ok) + goto Error; + + if (tstr_startswithi(name_with_type, PT_INT_PREFIX)) + type = PT_INT; + else if (tstr_startswithi(name_with_type, PT_STRING_PREFIX)) + type = PT_STRING; + else { + assert(0); + goto Error; + } + /* skip the type prefix */ + name = name_with_type + TYPE_PREFIX_CCH_LEN; + + pref = prefs_find_by_name_type(prefs, name, type); + + if (PT_STRING == type) + f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &value_str, &str_len_cch); + else if (PT_INT == type) + f_ok = netstr_parse_int(str_ptr, str_len_cb_ptr, &value_int); + else { + assert(0); + goto Error; + } + if (!f_ok) + goto Error; + + if (!pref) { + /* it's ok to not have a given preference e.g. when changing version some of the + preferences might go away. But we still want to be notified about that during + developement, since it's unlikely thing to happen */ + assert(0); + goto Exit; + } + + if (PT_INT == type) + *pref->data.data_int = value_int; + else if (PT_STRING == type) { + /* taking memory ownership */ + *pref->data.data_str = (TCHAR*)value_str; + value_str = NULL; + } else { + assert(0); + goto Error; + } + +Exit: + free((void*)name_with_type); + free((void*)value_str); + return TRUE; +Error: + free((void*)name_with_type); + free((void*)value_str); + return FALSE; +} + +int prefs_from_tstr(prefs_data *prefs, const TCHAR *str, size_t str_len_cch) +{ + int f_ok; + size_t str_len_cb; + + assert(str); + if (!str) return FALSE; + + if (-1 == str_len_cch) + str_len_cch = tstr_len(str); + + str_len_cb = str_len_cch * sizeof(TCHAR); + while (0 != str_len_cb) { + f_ok = prefs_parse_item(prefs, &str, &str_len_cb); + if (!f_ok) + return FALSE; + } + assert(0 == str_len_cb); + return TRUE; +} diff --git a/rosapps/smartpdf/baseutils/prefs_util.h b/rosapps/smartpdf/baseutils/prefs_util.h new file mode 100644 index 00000000000..1fd1eab2095 --- /dev/null +++ b/rosapps/smartpdf/baseutils/prefs_util.h @@ -0,0 +1,38 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef PREFS_H_ +#define PREFS_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef enum pref_type pref_type; +enum pref_type { + PT_INVALID = 0, + PT_INT, + PT_STRING +}; + +typedef struct prefs_data prefs_data; + +/* describes all preferences in a program */ +struct prefs_data { + const TCHAR * name; + pref_type type; + union { + void * data_void; + int * data_int; + TCHAR ** data_str; + } data; +}; + +TCHAR *prefs_to_tstr(prefs_data *prefs, size_t *tstr_len_cb_ptr); +int prefs_from_tstr(prefs_data *prefs, const TCHAR *str, size_t str_len_cb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/str_strsafe.h b/rosapps/smartpdf/baseutils/str_strsafe.h new file mode 100644 index 00000000000..d93e2116788 --- /dev/null +++ b/rosapps/smartpdf/baseutils/str_strsafe.h @@ -0,0 +1,22 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef __STR_STRSAFE_H +#define __STR_STRSAFE_H + +/* When using MSVC, use , emulate it on other compiler (e.g. mingw) */ + +#ifndef __GNUC__ + #include +#else + #include + #include + #include + #define STRSAFE_E_INSUFFICIENT_BUFFER -1 + #define _vsnprintf_s(p,s,z,f,a) vsnprintf(p,s,f,a) + #define StringCchVPrintfA vsnprintf + #define StringCchPrintfA snprintf + #define _stricmp strcasecmp + #define _strnicmp strncasecmp +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/str_util.c b/rosapps/smartpdf/baseutils/str_util.c new file mode 100644 index 00000000000..4e6abb11acb --- /dev/null +++ b/rosapps/smartpdf/baseutils/str_util.c @@ -0,0 +1,970 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ + +/* The most basic things, including string handling functions */ +#include "base_util.h" +#include "str_util.h" +#include "str_strsafe.h" + +/* TODO: should probably be based on MSVC version */ +#if defined(__GNUC__) || !defined(_WIN32) || (_MSC_VER < 1400) +void strcpy_s(char *dst, size_t dstLen, const char *src) +{ + size_t toCopy; + + assert(dst); + assert(src); + assert(dstLen > 0); + + if (!dst || !src || dstLen <= 0) + return; + + toCopy = strlen(src); + if (toCopy > (dstLen-1)) + toCopy = dstLen - 1; + + strncpy(dst, src, toCopy); + dst[toCopy] = 0; +} +#endif + +void no_op(void) +{ + /* This really is a no-op, just to silence the compiler */ +} + +int char_is_ws_or_zero(char c) +{ + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + case 0: + return TRUE; + } + return FALSE; +} + +int char_is_ws(char c) +{ + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + return TRUE; + } + return FALSE; +} + +int char_is_digit(char c) +{ + if ((c >= '0') && (c <= '9')) + return TRUE; + return FALSE; +} + +/* Concatenate 4 strings. Any string can be NULL. + Caller needs to free() memory. */ +char *str_cat4(const char *str1, const char *str2, const char *str3, const char *str4) +{ + char *str; + char *tmp; + size_t str1_len = 0; + size_t str2_len = 0; + size_t str3_len = 0; + size_t str4_len = 0; + + if (str1) + str1_len = strlen(str1); + if (str2) + str2_len = strlen(str2); + if (str3) + str3_len = strlen(str3); + if (str4) + str4_len = strlen(str4); + + str = (char*)zmalloc(str1_len + str2_len + str3_len + str4_len + 1); + if (!str) + return NULL; + + tmp = str; + if (str1) { + memcpy(tmp, str1, str1_len); + tmp += str1_len; + } + if (str2) { + memcpy(tmp, str2, str2_len); + tmp += str2_len; + } + if (str3) { + memcpy(tmp, str3, str3_len); + tmp += str3_len; + } + if (str4) { + memcpy(tmp, str4, str1_len); + } + return str; +} + +/* Concatenate 3 strings. Any string can be NULL. + Caller needs to free() memory. */ +char *str_cat3(const char *str1, const char *str2, const char *str3) +{ + return str_cat4(str1, str2, str3, NULL); +} + +/* Concatenate 2 strings. Any string can be NULL. + Caller needs to free() memory. */ +char *str_cat(const char *str1, const char *str2) +{ + return str_cat4(str1, str2, NULL, NULL); +} + +char *str_dup(const char *str) +{ + return str_cat4(str, NULL, NULL, NULL); +} + +char *str_dupn(const char *str, size_t str_len_cch) +{ + char *copy; + + if (!str) + return NULL; + copy = (char*)malloc(str_len_cch+1); + if (!copy) + return NULL; + memcpy(copy, str, str_len_cch); + copy[str_len_cch] = 0; + return copy; +} + +int str_copyn(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size) +{ + char *end = dst + dst_cch_size - 1; + if (0 == dst_cch_size) { + if (0 == src_cch_size) + return TRUE; + else + return FALSE; + } + + while ((dst < end) && (src_cch_size > 0)) { + *dst++ = *src++; + --src_cch_size; + } + *dst = 0; + if (0 == src_cch_size) + return TRUE; + else + return FALSE; +} + +int str_copy(char *dst, size_t dst_cch_size, const char *src) +{ + char *end = dst + dst_cch_size - 1; + if (0 == dst_cch_size) + return FALSE; + + while ((dst < end) && *src) { + *dst++ = *src++; + } + *dst = 0; + if (0 == *src) + return TRUE; + else + return FALSE; +} + +int str_eq(const char *str1, const char *str2) +{ + if (!str1 && !str2) + return TRUE; + if (!str1 || !str2) + return FALSE; + if (0 == strcmp(str1, str2)) + return TRUE; + return FALSE; +} + +int str_ieq(const char *str1, const char *str2) +{ + if (!str1 && !str2) + return TRUE; + if (!str1 || !str2) + return FALSE; + if (0 == _stricmp(str1, str2)) + return TRUE; + return FALSE; +} + +int str_eqn(const char *str1, const char *str2, int len) +{ + if (!str1 && !str2) + return TRUE; + if (!str1 || !str2) + return FALSE; + if (0 == strncmp(str1, str2, len)) + return TRUE; + return FALSE; +} + +/* return true if 'str' starts with 'txt', case-sensitive */ +int str_startswith(const char *str, const char *txt) +{ + if (!str && !txt) + return TRUE; + if (!str || !txt) + return FALSE; + + if (0 == strncmp(str, txt, strlen(txt))) + return TRUE; + return FALSE; +} + +/* return true if 'str' starts with 'txt', NOT case-sensitive */ +int str_startswithi(const char *str, const char *txt) +{ + if (!str && !txt) + return TRUE; + if (!str || !txt) + return FALSE; + + if (0 == _strnicmp(str, txt, strlen(txt))) + return TRUE; + return FALSE; +} + +int str_endswith(const char *txt, const char *end) +{ + size_t end_len; + size_t txt_len; + + if (!txt || !end) + return FALSE; + + txt_len = strlen(txt); + end_len = strlen(end); + if (end_len > txt_len) + return FALSE; + if (str_eq(txt+txt_len-end_len, end)) + return TRUE; + return FALSE; +} + +int str_endswithi(const char *txt, const char *end) +{ + size_t end_len; + size_t txt_len; + + if (!txt || !end) + return FALSE; + + txt_len = strlen(txt); + end_len = strlen(end); + if (end_len > txt_len) + return FALSE; + if (str_ieq(txt+txt_len-end_len, end)) + return TRUE; + return FALSE; +} + +int str_endswith_char(const char *str, char c) +{ + char end[2]; + end[0] = c; + end[1] = 0; + return str_endswith(str, end); +} + +int str_empty(const char *str) +{ + if (!str) + return TRUE; + if (0 == *str) + return TRUE; + return FALSE; +} + +/* Find character 'c' in string 'txt'. + Return pointer to this character or NULL if not found */ +const char *str_find_char(const char *txt, char c) +{ + while (*txt != c) { + if (0 == *txt) + return NULL; + ++txt; + } + return txt; +} + +/* split a string '*txt' at the border character 'c'. Something like python's + string.split() except called iteratively. + Returns a copy of the string (must be free()d by the caller). + Returns NULL to indicate there's no more items. */ +char *str_split_iter(char **txt, char c) +{ + const char *tmp; + const char *pos; + char *result; + + tmp = (const char*)*txt; + if (!tmp) + return NULL; + + pos = str_find_char(tmp, c); + if (pos) { + result = str_dupn(tmp, (int)(pos-tmp)); + *txt = (char*)pos+1; + } else { + result = str_dup(tmp); + *txt = NULL; /* next iteration will return NULL */ + } + return result; +} + +/* Replace all posible versions (Unix, Windows, Mac) of newline character + with 'replace'. Returns newly allocated string with normalized newlines + or NULL if error. + Caller needs to free() the result */ +char *str_normalize_newline(const char *txt, const char *replace) +{ + size_t replace_len; + char c; + char * result; + const char * tmp; + char * tmp_out; + size_t result_len = 0; + + replace_len = strlen(replace); + tmp = txt; + for (;;) { + c = *tmp++; + if (!c) + break; + if (0xa == c) { + /* a single 0xa => Unix */ + result_len += replace_len; + } else if (0xd == c) { + if (0xa == *tmp) { + /* 0xd 0xa => dos */ + result_len += replace_len; + ++tmp; + } + else { + /* just 0xd => Mac */ + result_len += replace_len; + } + } else + ++result_len; + } + + if (0 == result_len) + return NULL; + + result = (char*)malloc(result_len+1); + if (!result) + return NULL; + tmp_out = result; + for (;;) { + c = *txt++; + if (!c) + break; + if (0xa == c) { + /* a single 0xa => Unix */ + memcpy(tmp_out, replace, replace_len); + tmp_out += replace_len; + } else if (0xd == c) { + if (0xa == *txt) { + /* 0xd 0xa => dos */ + memcpy(tmp_out, replace, replace_len); + tmp_out += replace_len; + ++txt; + } + else { + /* just 0xd => Mac */ + memcpy(tmp_out, replace, replace_len); + tmp_out += replace_len; + } + } else + *tmp_out++ = c; + } + + *tmp_out = 0; + return result; +} + +#define WHITE_SPACE_CHARS " \n\t\r" + +/* Strip all 'to_strip' characters from the beginning of the string. + Does stripping in-place */ +void str_strip_left(char *txt, const char *to_strip) +{ + char *new_start = txt; + char c; + if (!txt || !to_strip) + return; + for (;;) { + c = *new_start; + if (0 == c) + break; + if (!str_contains(to_strip, c)) + break; + ++new_start; + } + + if (new_start != txt) { + memmove(txt, new_start, strlen(new_start)+1); + } +} + +/* Strip white-space characters from the beginning of the string. + Does stripping in-place */ +void str_strip_ws_left(char *txt) +{ + str_strip_left(txt, WHITE_SPACE_CHARS); +} + +void str_strip_right(char *txt, const char *to_strip) +{ + char * new_end; + char c; + if (!txt || !to_strip) + return; + if (0 == *txt) + return; + /* point at the last character in the string */ + new_end = txt + strlen(txt) - 1; + for (;;) { + c = *new_end; + if (!str_contains(to_strip, c)) + break; + if (txt == new_end) + break; + --new_end; + } + if (str_contains(to_strip, *new_end)) + new_end[0] = 0; + else + new_end[1] = 0; +} + +void str_strip_ws_right(char *txt) +{ + str_strip_right(txt, WHITE_SPACE_CHARS); +} + +void str_strip_both(char *txt, const char *to_strip) +{ + str_strip_left(txt, to_strip); + str_strip_right(txt, to_strip); +} + +void str_strip_ws_both(char *txt) +{ + str_strip_ws_left(txt); + str_strip_ws_right(txt); +} + +#if 0 +int utf8_eq(const utf8* str1, const utf8* str2) +{ + return str_eq(str1, str2); +} + +int utf8_eqn(const utf8* str1, const utf8* str2, int len) +{ + return str_eqn(str1, str2, len); +} + +int utf8_copy(utf8 *dst, int dst_size_bytes, utf8* src) +{ + return str_copy(dst, dst_size_bytes, src); +} + +utf8 *utf8_dup(const utf8 *str) +{ + return str_dup(str); +} + +utf8 *utf8_cat4(const utf8 *str1, const utf8 *str2, const utf8 *str3, const utf8 *str4) +{ + return str_cat4(str1, str2, str3, str4); +} + +utf8 *utf8_cat3(const utf8 *str1, const utf8 *str2, const utf8 *str3) +{ + return str_cat4(str1, str2, str3, NULL); +} + +utf8 *utf8_cat(const utf8 *str1, const utf8 *str2) +{ + return str_cat4(str1, str2, NULL, NULL); +} + +int utf8_endswith(const utf8 *str, const utf8 *end) +{ + return str_endswith(str, end); +} +#endif + +#define HEX_NUMBERS "0123456789ABCDEF" +static void char_to_hex(unsigned char c, char* buffer) +{ + buffer[0] = HEX_NUMBERS[c / 16]; + buffer[1] = HEX_NUMBERS[c % 16]; +} + +int str_contains(const char *str, char c) +{ + const char *pos = str_find_char(str, c); + if (!pos) + return FALSE; + return TRUE; +} + +#define CHAR_URL_DONT_ENCODE "-_.!~*'()" + +int char_needs_url_encode(char c) +{ + if ((c >= 'a') && (c <= 'z')) + return FALSE; + if ((c >= 'A') && (c <= 'Z')) + return FALSE; + if ((c >= '0') && (c <= '9')) + return FALSE; + if (str_contains(CHAR_URL_DONT_ENCODE, c)) + return FALSE; + return TRUE; +} + +/* url-encode 'str'. Returns NULL in case of error. Caller needs to free() + the result */ +char *str_url_encode(const char *str) +{ + char * encoded; + char * result; + int res_len = 0; + const char * tmp = str; + + /* calc the size of the string after url encoding */ + while (*tmp) { + if (char_needs_url_encode(*tmp)) + res_len += 3; + else + ++res_len; + tmp++; + } + if (0 == res_len) + return NULL; + + encoded = (char*)malloc(res_len+1); + if (!encoded) + return NULL; + + result = encoded; + tmp = str; + while (*tmp) { + if (char_needs_url_encode(*tmp)) { + *encoded++ = '%'; + char_to_hex(*tmp, encoded); + encoded += 2; + } else { + if (' ' == *tmp) + *encoded++ = '+'; + else + *encoded++ = *tmp; + } + tmp++; + } + *encoded = 0; + return result; +} + +char *str_escape(const char *txt) +{ + /* TODO: */ + return str_dup(txt); +} + +char *str_printf(const char *format, ...) +{ + char *result; + va_list args; + va_start(args, format); + result = str_printf_args(format, args); + va_end(args); + return result; +} + +char *str_printf_args(const char *format, va_list args) +{ +#ifdef _WIN32 + HRESULT hr; + char message[256]; + char * buf; + size_t bufCchSize; + char * result = NULL; + + buf = &(message[0]); + bufCchSize = sizeof(message); + + for (;;) + { + /* TODO: this only works on windows with recent C library */ + hr = StringCchVPrintfA(buf, bufCchSize, format, args); + if (S_OK == hr) + break; + if (STRSAFE_E_INSUFFICIENT_BUFFER != hr) + { + /* any error other than buffer not big enough: + a) should not happen + b) means we give up */ + assert(FALSE); + goto Error; + } + /* we have to make the buffer bigger. The algorithm used to calculate + the new size is arbitrary (aka. educated guess) */ + if (buf != &(message[0])) + free(buf); + if (bufCchSize < 4*1024) + bufCchSize += bufCchSize; + else + bufCchSize += 1024; + buf = (char *)malloc(bufCchSize*sizeof(char)); + if (NULL == buf) + goto Error; + } + + /* free the buffer if it was dynamically allocated */ + if (buf == &(message[0])) + return str_dup(buf); + + return buf; +Error: + if (buf != &(message[0])) + free((void*)buf); + + return NULL; +#else + char* buf; + int len = vasprintf(&buf, format, args); + return buf; +#endif +} + +#ifdef _WIN32 +void win32_dbg_out(const char *format, ...) +{ + char buf[4096]; + char * p = buf; + int written; + va_list args; + + va_start(args, format); + written = _vsnprintf(p,sizeof(buf), format, args); +/* printf(buf); + fflush(stdout); */ + OutputDebugStringA(buf); + va_end(args); +} + +void win32_dbg_out_hex(const char *dsc, const unsigned char *data, int dataLen) +{ + unsigned char buf[64+1]; + unsigned char * curPos; + int bufCharsLeft; + + if (dsc) win32_dbg_out(dsc); /* a bit dangerous if contains formatting codes */ + if (!data) return; + + bufCharsLeft = sizeof(buf)-1; + curPos = buf; + while (dataLen > 0) { + if (bufCharsLeft <= 1) { + *curPos = 0; + win32_dbg_out((char*)buf); + bufCharsLeft = sizeof(buf)-1; + curPos = buf; + } + char_to_hex(*data, curPos); + curPos += 2; + bufCharsLeft -= 2; + --dataLen; + ++data; + } + + if (curPos != buf) { + *curPos = 0; + win32_dbg_out(buf); + } + win32_dbg_out("\n"); +} +#endif + +/* Given a pointer to a string in '*txt', skip past whitespace in the string + and put the result in '*txt' */ +void str_skip_ws(char **txtInOut) +{ + char *cur; + if (!txtInOut) + return; + cur = *txtInOut; + if (!cur) + return; + while (char_is_ws(*cur)) { + ++cur; + } + *txtInOut = cur; +} + +char *str_parse_quoted(char **txt) +{ + char * strStart; + char * strCopy; + char * cur; + char * dst; + char c; + size_t len; + + assert(txt); + if (!txt) return NULL; + strStart = *txt; + assert(strStart); + if (!strStart) return NULL; + + assert('"' == *strStart); + /* TODO: rewrite as 2-phase logic so that counting and copying are always in sync */ + ++strStart; + cur = strStart; + len = 0; + for (;;) { + c = *cur; + if ((0 == c) || ('"' == c)) + break; + if ('\\' == c) { + /* TODO: should I un-escape more than '"' ? + I used to un-escape '\' as well, but it wasn't right and + files with UNC path like "\\foo\file.pdf" failed to load */ + if ('"' == cur[1]) { + ++cur; + c = *cur; + } + } + ++cur; + ++len; + } + + strCopy = (char*)malloc(len+1); + if (!strCopy) + return NULL; + + cur = strStart; + dst = strCopy; + for (;;) { + c = *cur; + if (0 == c) + break; + if ('"' == c) { + ++cur; + break; + } + if ('\\' == c) { + /* TODO: should I un-escape more than '"' ? + I used to un-escape '\' as well, but it wasn't right and + files with UNC path like "\\foo\file.pdf" failed to load */ + if ('"' == cur[1]) { + ++cur; + c = *cur; + } + } + *dst++ = c; + ++cur; + } + *dst = 0; + *txt = cur; + return strCopy; +} + +char *str_parse_non_quoted(char **txt) +{ + char * cur; + char * strStart; + char * strCopy; + char c; + size_t strLen; + + strStart = *txt; + assert(strStart); + if (!strStart) return NULL; + assert('"' != *strStart); + cur = strStart; + for (;;) { + c = *cur; + if (char_is_ws_or_zero(c)) + break; + ++cur; + } + + strLen = cur - strStart; + assert(strLen > 0); + strCopy = str_dupn(strStart, strLen); + *txt = cur; + return strCopy; +} + +/* 'txt' is path that can be: + - escaped, in which case it starts with '"', ends with '"' and each '"' that is part of the name is escaped + with '\' + - unescaped, in which case it start with != '"' and ends with ' ' or eol (0) + This function extracts escaped or unescaped path from 'txt'. Returns NULL in case of error. + Caller needs to free() the result. */ +char *str_parse_possibly_quoted(char **txt) +{ + char * cur; + char * str_copy; + + if (!txt) + return NULL; + cur = *txt; + if (!cur) + return NULL; + + str_skip_ws(&cur); + if (0 == *cur) + return NULL; + if ('"' == *cur) + str_copy = str_parse_quoted(&cur); + else + str_copy = str_parse_non_quoted(&cur); + *txt = cur; + return str_copy; +} + +void str_array_init(str_array *str_arr) +{ + assert(str_arr); + if (!str_arr) return; + memzero(str_arr, sizeof(str_array)); +} + +void str_array_free(str_array *str_arr) +{ + int i; + + assert(str_arr); + if (!str_arr) return; + + for (i = 0; i < str_arr->items_count; i++) + free(str_arr->items[i]); + free(str_arr->items); + str_array_init(str_arr); +} + +void str_array_delete(str_array *str_arr) +{ + assert(str_arr); + if (!str_arr) return; + str_array_free(str_arr); + free((void*)str_arr); +} + +str_item *str_array_get(str_array *str_arr, int index) +{ + assert(str_arr); + if (!str_arr) return NULL; + assert(index >= 0); + assert(index < str_arr->items_count); + if ((index < 0) || (index >= str_arr->items_count)) + return NULL; + return str_arr->items[index]; +} + +int str_array_get_count(str_array *str_arr) +{ + assert(str_arr); + if (!str_arr) return 0; + return str_arr->items_count; +} + +/* Set one string at position 'index' in 'str_arr'. Space for the item + must already be allocated. */ +str_item *str_array_set(str_array *str_arr, int index, const char *str) +{ + str_item * new_item; + size_t str_len_cch; + + assert(str_arr); + if (!str_arr) return NULL; + + if (index >= str_arr->items_count) + return NULL; + + str_len_cch = str_len(str); + new_item = (str_item*)malloc(sizeof(str_item) + str_len_cch*sizeof(char)); + if (!new_item) + return NULL; + str_copy(new_item->str, str_len_cch+1, str); + if (str_arr->items[index]) + free(str_arr->items[index]); + str_arr->items[index] = new_item; + return new_item; +} + +#define STR_ARR_GROW_VALUE 32 + +/* make a generic array alloc */ +str_item *str_array_add(str_array *str_arr, const char *str) +{ + str_item ** tmp; + str_item * new_item; + void * data; + int n; + + if (str_arr->items_count >= str_arr->items_allocated) { + /* increase memory for items if necessary */ + n = str_arr->items_allocated + STR_ARR_GROW_VALUE; + tmp = (str_item**)realloc(str_arr->items, n * sizeof(str_item *)); + if (!tmp) + return NULL; + str_arr->items = tmp; + data = &(str_arr->items[str_arr->items_count]); + memzero(data, STR_ARR_GROW_VALUE * sizeof(str_item *)); + str_arr->items_allocated = n; + } + str_arr->items_count++; + new_item = str_array_set(str_arr, str_arr->items_count - 1, str); + if (!new_item) + --str_arr->items_count; + return new_item; +} + +int str_array_exists_no_case(str_array *str_arr, const char *str) +{ + int count, i; + str_item * item; + char * item_str; + + if (!str_arr || !str) + return FALSE; + + count = str_arr->items_count; + for (i = 0; i < count; i++) + { + item = str_arr->items[i]; + item_str = item->str; + if (str_ieq(str, item_str)) + return TRUE; + } + return FALSE; +} + +str_item *str_array_add_no_dups(str_array *str_arr, const char *str) +{ + if (str_array_exists_no_case(str_arr, str)) + return NULL; + + return str_array_add(str_arr, str); +} diff --git a/rosapps/smartpdf/baseutils/str_util.h b/rosapps/smartpdf/baseutils/str_util.h new file mode 100644 index 00000000000..4e4e5cc7c7b --- /dev/null +++ b/rosapps/smartpdf/baseutils/str_util.h @@ -0,0 +1,117 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef STR_UTIL_H_ +#define STR_UTIL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* DOS is 0xd 0xa */ +#define DOS_NEWLINE "\x0d\x0a" +/* Mac is single 0xd */ +#define MAC_NEWLINE "\x0d" +/* Unix is single 0xa (10) */ +#define UNIX_NEWLINE "\x0a" +#define UNIX_NEWLINE_C 0xa + +#ifdef _WIN32 + #define DIR_SEP_CHAR '\\' + #define DIR_SEP_STR "\\" +#else + #define DIR_SEP_CHAR '/' + #define DIR_SEP_STR "/" +#endif + +void no_op(void); + +#ifdef DEBUG + #ifdef _WIN32 + #define DBG_OUT win32_dbg_out + #define DBG_OUT_HEX win32_dbg_out_hex + #else + #define DBG_OUT printf + #define DBG_OUT_HEX(...) no_op() + #endif +#else + #define DBG_OUT(...) no_op() + #define DBG_OUT_HEX(...) no_op() +#endif + +int char_is_ws_or_zero(char c); +int char_is_ws(char c); +int char_is_digit(char c); + +/* TODO: should probably be based on MSVC version */ +#if defined(__GNUC__) || !defined(_WIN32) || (_MSC_VER < 1400) +void strcpy_s(char *dst, size_t dstLen, const char *src); +#endif + +#define str_len strlen +int str_eq(const char *str1, const char *str2); +int str_ieq(const char *str1, const char *str2); +#define str_eq_no_case str_ieq +int str_eqn(const char *str1, const char *str2, int len); +int str_startswith(const char *str, const char *txt); +int str_startswithi(const char *str, const char *txt); +int str_endswith(const char *str, const char *end); +int str_endswithi(const char *str, const char *end); +int str_endswith_char(const char *str, char c); +int str_empty(const char *str); +int str_copy(char *dst, size_t dst_cch_size, const char *src); +int str_copyn(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size); +char * str_dup(const char *str); +char * str_dupn(const char *str, size_t len); +char * str_cat(const char *str1, const char *str2); +char * str_cat3(const char *str1, const char *str2, const char *str3); +char * str_cat4(const char *str1, const char *str2, const char *str3, const char *str4); +char * str_url_encode(const char *str); +int char_needs_url_escape(char c); +int str_contains(const char *str, char c); +char * str_printf_args(const char *format, va_list args); +char * str_printf(const char *format, ...); +const char *str_find_char(const char *txt, char c); +char * str_split_iter(char **txt, char c); +char * str_normalize_newline(const char *txt, const char *replace); +void str_strip_left(char *txt, const char *to_strip); +void str_strip_ws_left(char *txt); +void str_strip_right(char *txt, const char *to_strip); +void str_strip_ws_right(char *txt); +void str_strip_both(char *txt, const char *to_strip); +void str_strip_ws_both(char *txt); +char * str_escape(const char *txt); +char * str_parse_possibly_quoted(char **txt); + +#ifdef DEBUG +void str_util_test(void); +#endif + +typedef struct str_item str_item; +typedef struct str_array str_array; + +struct str_item { + void * opaque; /* opaque data that the user can use */ + char str[1]; +}; + +struct str_array { + int items_allocated; + int items_count; + str_item ** items; +}; + +void str_array_init(str_array *str_arr); +void str_array_free(str_array *str_arr); +void str_array_delete(str_array *str_arr); +str_item *str_array_set(str_array *str_arr, int index, const char *str); +str_item *str_array_add(str_array *str_arr, const char *str); +str_item *str_array_get(str_array *str_arr, int index); +int str_array_get_count(str_array *str_arr); +int str_array_exists_no_case(str_array *str_arr, const char *str); +str_item *str_array_add_no_dups(str_array *str_arr, const char *str); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/rosapps/smartpdf/baseutils/str_util_test.c b/rosapps/smartpdf/baseutils/str_util_test.c new file mode 100644 index 00000000000..1452bff204b --- /dev/null +++ b/rosapps/smartpdf/baseutils/str_util_test.c @@ -0,0 +1,44 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "str_util.h" + +#ifndef DEBUG +#define DEBUG 1 +#endif + +#define LAST_TXT "last" +void str_util_test(void) +{ + char buf[256]; + char * tmp; + + assert(!str_endswith(NULL, NULL)); + assert(!str_endswith(NULL, "foo")); + assert(!str_endswith("bar", NULL)); + assert(!str_endswith("bar", "baru")); + assert(str_endswith("whammy", "whammy")); + assert(str_endswith("whammy", "hammy")); + assert(str_endswith("whammy", "y")); + assert(str_endswith("whmmy", "")); + str_copy(buf, sizeof(buf), LAST_TXT); + str_strip_left(buf, "zot"); + assert(str_eq(buf, LAST_TXT)); + str_strip_right(buf, "zpo"); + assert(str_eq(buf, LAST_TXT)); + str_copy(buf, sizeof(buf), " \n last "); + str_strip_left(buf, " \n"); + assert(str_eq(buf, "last ")); + str_strip_right(buf, " \n"); + assert(str_eq(buf, LAST_TXT)); + str_copy(buf, sizeof(buf), LAST_TXT); + str_strip_left(buf, LAST_TXT); + assert(0 == buf[0]); + str_copy(buf, sizeof(buf), LAST_TXT); + str_strip_right(buf, LAST_TXT); + assert(0 == buf[0]); + str_copy(buf, sizeof(buf), "\x0d\x0a"); + tmp = str_normalize_newline(buf, UNIX_NEWLINE); + assert(str_eq(tmp, UNIX_NEWLINE)); + free((void*)tmp); + tmp = NULL; +} diff --git a/rosapps/smartpdf/baseutils/strlist_util.c b/rosapps/smartpdf/baseutils/strlist_util.c new file mode 100644 index 00000000000..b46ab1311cc --- /dev/null +++ b/rosapps/smartpdf/baseutils/strlist_util.c @@ -0,0 +1,70 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "strlist_util.h" +#include "str_util.h" + +int StrList_Len(StrList **root) +{ + int len = 0; + StrList * cur; + assert(root); + if (!root) + return 0; + cur = *root; + while (cur) { + ++len; + cur = cur->next; + } + return len; +} + +BOOL StrList_InsertAndOwn(StrList **root, char *txt) +{ + StrList * el; + assert(root && txt); + if (!root || !txt) + return FALSE; + + el = (StrList*)malloc(sizeof(StrList)); + if (!el) + return FALSE; + el->str = txt; + el->next = *root; + *root = el; + return TRUE; +} + +BOOL StrList_Insert(StrList **root, char *txt) +{ + char *txtDup; + + assert(root && txt); + if (!root || !txt) + return FALSE; + txtDup = str_dup(txt); + if (!txtDup) + return FALSE; + + if (!StrList_InsertAndOwn(root, txtDup)) { + free((void*)txtDup); + return FALSE; + } + return TRUE; +} + +void StrList_Destroy(StrList **root) +{ + StrList * cur; + StrList * next; + + if (!root) + return; + cur = *root; + while (cur) { + next = cur->next; + free((void*)cur->str); + free((void*)cur); + cur = next; + } + *root = NULL; +} diff --git a/rosapps/smartpdf/baseutils/strlist_util.h b/rosapps/smartpdf/baseutils/strlist_util.h new file mode 100644 index 00000000000..8360753bca4 --- /dev/null +++ b/rosapps/smartpdf/baseutils/strlist_util.h @@ -0,0 +1,28 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef STRLIST_UTIL_H_ +#define STRLIST_UTIL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct StrList { + struct StrList * next; + char * str; +} StrList; + +char * StrDupN(char *str, size_t len); +char * StrDup(char *str); + +int StrList_Len(StrList **root); +BOOL StrList_InsertAndOwn(StrList **root, char *txt); +BOOL StrList_Insert(StrList **root, char *txt); +void StrList_Destroy(StrList **root); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/test_file_util.cpp b/rosapps/smartpdf/baseutils/test_file_util.cpp new file mode 100644 index 00000000000..91bbfcf574f --- /dev/null +++ b/rosapps/smartpdf/baseutils/test_file_util.cpp @@ -0,0 +1,30 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" +#include "file_util.h" + +#define DIR_TO_READ "." + +int main(int argc, char **argv) +{ + FileList* fileList = FileList_Get(DIR_TO_READ, NULL); + if (!fileList) { + printf("Couldn't read dir %s\n", DIR_TO_READ); + goto Exit; + } + + FileInfo* fileInfo = fileList->first; + while (fileInfo) { + if (FileInfo_IsDir(fileInfo)) { + printf("d: %s, %s, %d\n", fileInfo->name, fileInfo->path, (int)fileInfo->size); + } else if (FileInfo_IsFile(fileInfo)) { + printf("f: %s, %s, %d\n", fileInfo->name, fileInfo->path, (int)fileInfo->size); + } else { + printf("Unknown type: %s\n", fileInfo->name); + } + fileInfo = fileInfo->next; + } +Exit: + FileList_Delete(fileList); + return 0; +} diff --git a/rosapps/smartpdf/baseutils/test_win.bat b/rosapps/smartpdf/baseutils/test_win.bat new file mode 100644 index 00000000000..1950253e6c2 --- /dev/null +++ b/rosapps/smartpdf/baseutils/test_win.bat @@ -0,0 +1,23 @@ +@echo off +pushd . +@call "C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" +IF ERRORLEVEL 1 goto VC_SETUP_FAILED + +nmake -f Makefile.vc8 +IF ERRORLEVEL 1 goto COMPILATION_FAILED + +del *.obj *.ilk +test_file_util_d.exe +goto END + +:VC_SETUP_FAILED +echo Failed to setup vc8 +goto END + +:COMPILATION_FAILED +echo Compilation failed! +goto END + +:END +popd + diff --git a/rosapps/smartpdf/baseutils/todo.txt b/rosapps/smartpdf/baseutils/todo.txt new file mode 100644 index 00000000000..95e214bf038 --- /dev/null +++ b/rosapps/smartpdf/baseutils/todo.txt @@ -0,0 +1,3 @@ +* netstr.c and prefs_util.c shouldn't support TCHAR, just utf8 char* +* add mingw makefile +* add cygwin makefile diff --git a/rosapps/smartpdf/baseutils/tstr_util.h b/rosapps/smartpdf/baseutils/tstr_util.h new file mode 100644 index 00000000000..1bf6ceaf637 --- /dev/null +++ b/rosapps/smartpdf/baseutils/tstr_util.h @@ -0,0 +1,44 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef TSTR_UTIL_H_ +#define TSTR_UTIL_H_ + +#ifdef _UNICODE + #include "wstr_util.h" + #define tstr_len wcslen + #define tstr_dup wstr_dup + #define tstr_dupn wstr_dupn + #define tstr_cat wstr_cat + #define tstr_cat3 wstr_cat3 + #define tstr_cat4 wstr_cat4 + #define tstr_copy wstr_copy + #define tstr_copyn wstr_copyn + #define tstr_startswith wstr_startswith + #define tstr_startswithi wstr_startswithi + #define tstr_url_encode wstr_url_encode + #define tchar_needs_url_escape wchar_needs_url_escape + #define tstr_contains wstr_contains + #define tstr_printf wstr_printf + #define tstr_ieq wstr_ieq + #define tstr_empty wstr_empty +#else + #include "str_util.h" + #define tstr_len strlen + #define tstr_dup str_dup + #define tstr_dupn str_dupn + #define tstr_cat str_cat + #define tstr_cat3 str_cat3 + #define tstr_cat4 str_cat4 + #define tstr_copy str_copy + #define tstr_copyn str_copyn + #define tstr_startswith str_startswith + #define tstr_startswithi str_startswithi + #define tstr_url_encode str_url_encode + #define tchar_needs_url_escape char_needs_url_escape + #define tstr_contains str_contains + #define tstr_printf str_printf + #define tstr_ieq str_ieq + #define tstr_empty str_empty +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/unit_tests_all.c b/rosapps/smartpdf/baseutils/unit_tests_all.c new file mode 100644 index 00000000000..b96f62221e4 --- /dev/null +++ b/rosapps/smartpdf/baseutils/unit_tests_all.c @@ -0,0 +1,13 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "str_util.h" + +extern void str_util_test(void); /* in str_util_test.c */ + +int main(int argc, char **argv) +{ + printf("starting unit tests\n"); + str_util_test(); + printf("finished unit tests\n"); + return 0; +} diff --git a/rosapps/smartpdf/baseutils/win-build.bat b/rosapps/smartpdf/baseutils/win-build.bat new file mode 100644 index 00000000000..babce10aaf6 --- /dev/null +++ b/rosapps/smartpdf/baseutils/win-build.bat @@ -0,0 +1,5 @@ +nmake -f makefile.msvc TARGET=rel +nmake -f makefile.msvc TARGET=dbg +nmake -f makefile.msvc TARGET=rel-unicode +nmake -f makefile.msvc TARGET=dbg-unicode + diff --git a/rosapps/smartpdf/baseutils/win-rebuild.bat b/rosapps/smartpdf/baseutils/win-rebuild.bat new file mode 100644 index 00000000000..21ca9d65f1d --- /dev/null +++ b/rosapps/smartpdf/baseutils/win-rebuild.bat @@ -0,0 +1,9 @@ +nmake -f makefile.msvc TARGET=rel clean +nmake -f makefile.msvc TARGET=dbg clean +nmake -f makefile.msvc TARGET=rel-unicode clean +nmake -f makefile.msvc TARGET=dbg-unicode clean + +nmake -f makefile.msvc TARGET=rel +nmake -f makefile.msvc TARGET=dbg +nmake -f makefile.msvc TARGET=rel-unicode +nmake -f makefile.msvc TARGET=dbg-unicode diff --git a/rosapps/smartpdf/baseutils/win_dib.cpp b/rosapps/smartpdf/baseutils/win_dib.cpp new file mode 100644 index 00000000000..371de51788e --- /dev/null +++ b/rosapps/smartpdf/baseutils/win_dib.cpp @@ -0,0 +1,1263 @@ +// CDIBSectionLite.cpp : implementation file +// +// General purpose DIBsection wrapper class for Win9x, NT 4.0, W2K and WinCE. +// +// Author : Chris Maunder (cmaunder@mail.com) +// Date : 17 May 1999 +// +// Copyright © Dundas Software Ltd. 1999, All Rights Reserved +// +// This code may be used in compiled form in any way you desire. This +// file may be redistributed unmodified by any means PROVIDING it is +// not sold for profit without the authors written consent, and +// providing that this notice and the authors name is included. If +// the source code in this file is used in any commercial application +// then a simple email would be nice. +// +// This file is provided "as is" with no expressed or implied warranty. +// The author accepts no liability for any damage, in any form, caused +// by this code. Use it at your own risk and as with all code expect bugs! +// It's been tested but I'm not perfect. +// +// Please use and enjoy. Please let me know of any bugs/mods/improvements +// that you have found/implemented and I will fix/incorporate them into this +// file. +// +// History : 25 May 1999 - First release +// 4 Jun 1999 - Fixed SetBitmap bug +// 4 May 2000 - 16 or 32 bit compression bug fix (Jim Miller ) +// Bug fix in Save() (saving 4 bytes too many - Tadeusz Dracz) +// 12 Dec 2000 - KennyG@magenic.com - Massive MFC extraxtion, remove that bloat! +// +#include "stdafx.h" +#include "CDIB.h" + +// Standard colors +RGBQUAD CDIB::ms_StdColors[] = { + { 0x00, 0x00, 0x00, 0 }, // System palette - first 10 colors + { 0x80, 0x00, 0x00, 0 }, + { 0x00, 0x80, 0x00, 0 }, + { 0x80, 0x80, 0x00, 0 }, + { 0x00, 0x00, 0x80, 0 }, + { 0x80, 0x00, 0x80, 0 }, + { 0x00, 0x80, 0x80, 0 }, + { 0xC0, 0xC0, 0xC0, 0 }, + { 0xC0, 0xDC, 0xC0, 0 }, + { 0xA6, 0xCA, 0xF0, 0 }, + + { 0x2C, 0x00, 0x00, 0 }, + { 0x56, 0x00, 0x00, 0 }, + { 0x87, 0x00, 0x00, 0 }, + { 0xC0, 0x00, 0x00, 0 }, + { 0xFF, 0x00, 0x00, 0 }, + { 0x00, 0x2C, 0x00, 0 }, + { 0x2C, 0x2C, 0x00, 0 }, + { 0x56, 0x2C, 0x00, 0 }, + { 0x87, 0x2C, 0x00, 0 }, + { 0xC0, 0x2C, 0x00, 0 }, + { 0xFF, 0x2C, 0x00, 0 }, + { 0x00, 0x56, 0x00, 0 }, + { 0x2C, 0x56, 0x00, 0 }, + { 0x56, 0x56, 0x00, 0 }, + { 0x87, 0x56, 0x00, 0 }, + { 0xC0, 0x56, 0x00, 0 }, + { 0xFF, 0x56, 0x00, 0 }, + { 0x00, 0x87, 0x00, 0 }, + { 0x2C, 0x87, 0x00, 0 }, + { 0x56, 0x87, 0x00, 0 }, + { 0x87, 0x87, 0x00, 0 }, + { 0xC0, 0x87, 0x00, 0 }, + { 0xFF, 0x87, 0x00, 0 }, + { 0x00, 0xC0, 0x00, 0 }, + { 0x2C, 0xC0, 0x00, 0 }, + { 0x56, 0xC0, 0x00, 0 }, + { 0x87, 0xC0, 0x00, 0 }, + { 0xC0, 0xC0, 0x00, 0 }, + { 0xFF, 0xC0, 0x00, 0 }, + { 0x00, 0xFF, 0x00, 0 }, + { 0x2C, 0xFF, 0x00, 0 }, + { 0x56, 0xFF, 0x00, 0 }, + { 0x87, 0xFF, 0x00, 0 }, + { 0xC0, 0xFF, 0x00, 0 }, + { 0xFF, 0xFF, 0x00, 0 }, + { 0x00, 0x00, 0x2C, 0 }, + { 0x2C, 0x00, 0x2C, 0 }, + { 0x56, 0x00, 0x2C, 0 }, + { 0x87, 0x00, 0x2C, 0 }, + { 0xC0, 0x00, 0x2C, 0 }, + { 0xFF, 0x00, 0x2C, 0 }, + { 0x00, 0x2C, 0x2C, 0 }, + { 0x2C, 0x2C, 0x2C, 0 }, + { 0x56, 0x2C, 0x2C, 0 }, + { 0x87, 0x2C, 0x2C, 0 }, + { 0xC0, 0x2C, 0x2C, 0 }, + { 0xFF, 0x2C, 0x2C, 0 }, + { 0x00, 0x56, 0x2C, 0 }, + { 0x2C, 0x56, 0x2C, 0 }, + { 0x56, 0x56, 0x2C, 0 }, + { 0x87, 0x56, 0x2C, 0 }, + { 0xC0, 0x56, 0x2C, 0 }, + { 0xFF, 0x56, 0x2C, 0 }, + { 0x00, 0x87, 0x2C, 0 }, + { 0x2C, 0x87, 0x2C, 0 }, + { 0x56, 0x87, 0x2C, 0 }, + { 0x87, 0x87, 0x2C, 0 }, + { 0xC0, 0x87, 0x2C, 0 }, + { 0xFF, 0x87, 0x2C, 0 }, + { 0x00, 0xC0, 0x2C, 0 }, + { 0x2C, 0xC0, 0x2C, 0 }, + { 0x56, 0xC0, 0x2C, 0 }, + { 0x87, 0xC0, 0x2C, 0 }, + { 0xC0, 0xC0, 0x2C, 0 }, + { 0xFF, 0xC0, 0x2C, 0 }, + { 0x00, 0xFF, 0x2C, 0 }, + { 0x2C, 0xFF, 0x2C, 0 }, + { 0x56, 0xFF, 0x2C, 0 }, + { 0x87, 0xFF, 0x2C, 0 }, + { 0xC0, 0xFF, 0x2C, 0 }, + { 0xFF, 0xFF, 0x2C, 0 }, + { 0x00, 0x00, 0x56, 0 }, + { 0x2C, 0x00, 0x56, 0 }, + { 0x56, 0x00, 0x56, 0 }, + { 0x87, 0x00, 0x56, 0 }, + { 0xC0, 0x00, 0x56, 0 }, + { 0xFF, 0x00, 0x56, 0 }, + { 0x00, 0x2C, 0x56, 0 }, + { 0x2C, 0x2C, 0x56, 0 }, + { 0x56, 0x2C, 0x56, 0 }, + { 0x87, 0x2C, 0x56, 0 }, + { 0xC0, 0x2C, 0x56, 0 }, + { 0xFF, 0x2C, 0x56, 0 }, + { 0x00, 0x56, 0x56, 0 }, + { 0x2C, 0x56, 0x56, 0 }, + { 0x56, 0x56, 0x56, 0 }, + { 0x87, 0x56, 0x56, 0 }, + { 0xC0, 0x56, 0x56, 0 }, + { 0xFF, 0x56, 0x56, 0 }, + { 0x00, 0x87, 0x56, 0 }, + { 0x2C, 0x87, 0x56, 0 }, + { 0x56, 0x87, 0x56, 0 }, + { 0x87, 0x87, 0x56, 0 }, + { 0xC0, 0x87, 0x56, 0 }, + { 0xFF, 0x87, 0x56, 0 }, + { 0x00, 0xC0, 0x56, 0 }, + { 0x2C, 0xC0, 0x56, 0 }, + { 0x56, 0xC0, 0x56, 0 }, + { 0x87, 0xC0, 0x56, 0 }, + { 0xC0, 0xC0, 0x56, 0 }, + { 0xFF, 0xC0, 0x56, 0 }, + { 0x00, 0xFF, 0x56, 0 }, + { 0x2C, 0xFF, 0x56, 0 }, + { 0x56, 0xFF, 0x56, 0 }, + { 0x87, 0xFF, 0x56, 0 }, + { 0xC0, 0xFF, 0x56, 0 }, + { 0xFF, 0xFF, 0x56, 0 }, + { 0x00, 0x00, 0x87, 0 }, + { 0x2C, 0x00, 0x87, 0 }, + { 0x56, 0x00, 0x87, 0 }, + { 0x87, 0x00, 0x87, 0 }, + { 0xC0, 0x00, 0x87, 0 }, + { 0xFF, 0x00, 0x87, 0 }, + { 0x00, 0x2C, 0x87, 0 }, + { 0x2C, 0x2C, 0x87, 0 }, + { 0x56, 0x2C, 0x87, 0 }, + { 0x87, 0x2C, 0x87, 0 }, + { 0xC0, 0x2C, 0x87, 0 }, + { 0xFF, 0x2C, 0x87, 0 }, + { 0x00, 0x56, 0x87, 0 }, + { 0x2C, 0x56, 0x87, 0 }, + { 0x56, 0x56, 0x87, 0 }, + { 0x87, 0x56, 0x87, 0 }, + { 0xC0, 0x56, 0x87, 0 }, + { 0xFF, 0x56, 0x87, 0 }, + { 0x00, 0x87, 0x87, 0 }, + { 0x2C, 0x87, 0x87, 0 }, + { 0x56, 0x87, 0x87, 0 }, + { 0x87, 0x87, 0x87, 0 }, + { 0xC0, 0x87, 0x87, 0 }, + { 0xFF, 0x87, 0x87, 0 }, + { 0x00, 0xC0, 0x87, 0 }, + { 0x2C, 0xC0, 0x87, 0 }, + { 0x56, 0xC0, 0x87, 0 }, + { 0x87, 0xC0, 0x87, 0 }, + { 0xC0, 0xC0, 0x87, 0 }, + { 0xFF, 0xC0, 0x87, 0 }, + { 0x00, 0xFF, 0x87, 0 }, + { 0x2C, 0xFF, 0x87, 0 }, + { 0x56, 0xFF, 0x87, 0 }, + { 0x87, 0xFF, 0x87, 0 }, + { 0xC0, 0xFF, 0x87, 0 }, + { 0xFF, 0xFF, 0x87, 0 }, + { 0x00, 0x00, 0xC0, 0 }, + { 0x2C, 0x00, 0xC0, 0 }, + { 0x56, 0x00, 0xC0, 0 }, + { 0x87, 0x00, 0xC0, 0 }, + { 0xC0, 0x00, 0xC0, 0 }, + { 0xFF, 0x00, 0xC0, 0 }, + { 0x00, 0x2C, 0xC0, 0 }, + { 0x2C, 0x2C, 0xC0, 0 }, + { 0x56, 0x2C, 0xC0, 0 }, + { 0x87, 0x2C, 0xC0, 0 }, + { 0xC0, 0x2C, 0xC0, 0 }, + { 0xFF, 0x2C, 0xC0, 0 }, + { 0x00, 0x56, 0xC0, 0 }, + { 0x2C, 0x56, 0xC0, 0 }, + { 0x56, 0x56, 0xC0, 0 }, + { 0x87, 0x56, 0xC0, 0 }, + { 0xC0, 0x56, 0xC0, 0 }, + { 0xFF, 0x56, 0xC0, 0 }, + { 0x00, 0x87, 0xC0, 0 }, + { 0x2C, 0x87, 0xC0, 0 }, + { 0x56, 0x87, 0xC0, 0 }, + { 0x87, 0x87, 0xC0, 0 }, + { 0xC0, 0x87, 0xC0, 0 }, + { 0xFF, 0x87, 0xC0, 0 }, + { 0x00, 0xC0, 0xC0, 0 }, + { 0x2C, 0xC0, 0xC0, 0 }, + { 0x56, 0xC0, 0xC0, 0 }, + { 0x87, 0xC0, 0xC0, 0 }, + { 0xFF, 0xC0, 0xC0, 0 }, + { 0x00, 0xFF, 0xC0, 0 }, + { 0x2C, 0xFF, 0xC0, 0 }, + { 0x56, 0xFF, 0xC0, 0 }, + { 0x87, 0xFF, 0xC0, 0 }, + { 0xC0, 0xFF, 0xC0, 0 }, + { 0xFF, 0xFF, 0xC0, 0 }, + { 0x00, 0x00, 0xFF, 0 }, + { 0x2C, 0x00, 0xFF, 0 }, + { 0x56, 0x00, 0xFF, 0 }, + { 0x87, 0x00, 0xFF, 0 }, + { 0xC0, 0x00, 0xFF, 0 }, + { 0xFF, 0x00, 0xFF, 0 }, + { 0x00, 0x2C, 0xFF, 0 }, + { 0x2C, 0x2C, 0xFF, 0 }, + { 0x56, 0x2C, 0xFF, 0 }, + { 0x87, 0x2C, 0xFF, 0 }, + { 0xC0, 0x2C, 0xFF, 0 }, + { 0xFF, 0x2C, 0xFF, 0 }, + { 0x00, 0x56, 0xFF, 0 }, + { 0x2C, 0x56, 0xFF, 0 }, + { 0x56, 0x56, 0xFF, 0 }, + { 0x87, 0x56, 0xFF, 0 }, + { 0xC0, 0x56, 0xFF, 0 }, + { 0xFF, 0x56, 0xFF, 0 }, + { 0x00, 0x87, 0xFF, 0 }, + { 0x2C, 0x87, 0xFF, 0 }, + { 0x56, 0x87, 0xFF, 0 }, + { 0x87, 0x87, 0xFF, 0 }, + { 0xC0, 0x87, 0xFF, 0 }, + { 0xFF, 0x87, 0xFF, 0 }, + { 0x00, 0xC0, 0xFF, 0 }, + { 0x2C, 0xC0, 0xFF, 0 }, + { 0x56, 0xC0, 0xFF, 0 }, + { 0x87, 0xC0, 0xFF, 0 }, + { 0xC0, 0xC0, 0xFF, 0 }, + { 0xFF, 0xC0, 0xFF, 0 }, + { 0x2C, 0xFF, 0xFF, 0 }, + { 0x56, 0xFF, 0xFF, 0 }, + { 0x87, 0xFF, 0xFF, 0 }, + { 0xC0, 0xFF, 0xFF, 0 }, + { 0xFF, 0xFF, 0xFF, 0 }, + { 0x11, 0x11, 0x11, 0 }, + { 0x18, 0x18, 0x18, 0 }, + { 0x1E, 0x1E, 0x1E, 0 }, + { 0x25, 0x25, 0x25, 0 }, + { 0x2C, 0x2C, 0x2C, 0 }, + { 0x34, 0x34, 0x34, 0 }, + { 0x3C, 0x3C, 0x3C, 0 }, + { 0x44, 0x44, 0x44, 0 }, + { 0x4D, 0x4D, 0x4D, 0 }, + { 0x56, 0x56, 0x56, 0 }, + { 0x5F, 0x5F, 0x5F, 0 }, + { 0x69, 0x69, 0x69, 0 }, + { 0x72, 0x72, 0x72, 0 }, + { 0x7D, 0x7D, 0x7D, 0 }, + { 0x92, 0x92, 0x92, 0 }, + { 0x9D, 0x9D, 0x9D, 0 }, + { 0xA8, 0xA8, 0xA8, 0 }, + { 0xB4, 0xB4, 0xB4, 0 }, + { 0xCC, 0xCC, 0xCC, 0 }, + { 0xD8, 0xD8, 0xD8, 0 }, + { 0xE5, 0xE5, 0xE5, 0 }, + { 0xF2, 0xF2, 0xF2, 0 }, + { 0xFF, 0xFF, 0xFF, 0 }, + + { 0xFF, 0xFB, 0xF0, 0 }, // System palette - last 10 colors + { 0xA0, 0xA0, 0xA4, 0 }, + { 0x80, 0x80, 0x80, 0 }, + { 0xFF, 0x00, 0x00, 0 }, + { 0x00, 0xFF, 0x00, 0 }, + { 0xFF, 0xFF, 0x00, 0 }, + { 0x00, 0x00, 0xFF, 0 }, + { 0xFF, 0x00, 0xFF, 0 }, + { 0x00, 0xFF, 0xFF, 0 }, + { 0xFF, 0xFF, 0xFF, 0 }, +}; + +///////////////////////////////////////////////////////////////////////////// +// CE DIBSection global functions + +#ifdef _WIN32_WCE +UINT CEGetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries, RGBQUAD *pColors); +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDIB static functions + +// +// --- In  : nBitsPerPixel - bits per pixel +// nCompression - type of compression +// --- Out : +// --- Returns :The number of colors for this color depth +// --- Effect : Returns the number of color table entries given the number +// of bits per pixel of a bitmap +/*static*/ int CDIB::NumColorEntries(int nBitsPerPixel, int nCompression) +{ + int nColors = 0; + + switch (nBitsPerPixel) + { + case 1: + nColors = 2; + break; +#ifdef _WIN32_WCE + case 2: + nColors = 4; + break; // winCE only +#endif + case 4: + nColors = 16; + break; + case 8: + nColors = 256; + break; + case 24: + nColors = 0; + break; + case 16: + case 32: + if (nCompression == BI_BITFIELDS) + nColors = 3; // 16 or 32 bpp have 3 colors(masks) in the color table if bitfield compression + else + nColors = 0; // 16 or 32 bpp have no color table if no bitfield compression + break; + + default: + ASSERT(FALSE); + } + + return nColors; +} + +// +// --- In  : nWidth - image width in pixels +// nBitsPerPixel - bits per pixel +// --- Out : +// --- Returns : Returns the number of storage bytes needed for each scanline +// in the bitmap +// --- Effect : +/*static*/ int CDIB::BytesPerLine(int nWidth, int nBitsPerPixel) +{ + return ( (nWidth * nBitsPerPixel + 31) & (~31) ) / 8; +} + +#ifndef DIBSECTION_NO_PALETTE + +// --- In  : palette - reference to a palette object which will be filled +// nNumColors - number of color entries to fill +// --- Out : +// --- Returns : TRUE on success, false otherwise +// --- Effect : Creates a halftone color palette independant of screen color depth. +// palette will be filled with the colors, and nNumColors is the No. +// of colors to file. If nNumColorsis 0 or > 256, then 256 colors are used. +/*static*/ +BOOL CDIB::CreateHalftonePalette(HPALETTE hPal, int nNumColors) +{ + ::DeleteObject(hPal); + + // Sanity check on requested number of colours. + if (nNumColors <= 0 || nNumColors > 256) + nNumColors = 256; + else if (nNumColors <= 2) + nNumColors = 2; + else if (nNumColors <= 16) + nNumColors = 16; + else if (nNumColors <= 256) + nNumColors = 256; + + PALETTEINFO pi; + pi.palNumEntries = (WORD) nNumColors; + + if (nNumColors == 2) + { + // According to the MS article "The Palette Manager: How and Why" + // monochrome palettes not really needed (will use B&W) + pi.palPalEntry[0].peRed = ms_StdColors[0].rgbRed; + pi.palPalEntry[0].peGreen = ms_StdColors[0].rgbGreen; + pi.palPalEntry[0].peBlue = ms_StdColors[0].rgbBlue; + pi.palPalEntry[0].peFlags = 0; + pi.palPalEntry[1].peRed = ms_StdColors[255].rgbRed; + pi.palPalEntry[1].peGreen = ms_StdColors[255].rgbGreen; + pi.palPalEntry[1].peBlue = ms_StdColors[255].rgbBlue; + pi.palPalEntry[1].peFlags = 0; + } + else if (nNumColors == 16) + { + // According to the MS article "The Palette Manager: How and Why" + // 4-bit palettes not really needed (will use VGA palette) + for (int i = 0; i < 8; i++) + { + pi.palPalEntry[i].peRed = ms_StdColors[i].rgbRed; + pi.palPalEntry[i].peGreen = ms_StdColors[i].rgbGreen; + pi.palPalEntry[i].peBlue = ms_StdColors[i].rgbBlue; + pi.palPalEntry[i].peFlags = 0; + } + for (i = 8; i < 16; i++) + { + pi.palPalEntry[i].peRed = ms_StdColors[248+i].rgbRed; + pi.palPalEntry[i].peGreen = ms_StdColors[248+i].rgbGreen; + pi.palPalEntry[i].peBlue = ms_StdColors[248+i].rgbBlue; + pi.palPalEntry[i].peFlags = 0; + } + } + else // if (nNumColors == 256) + { + // Fill palette with full halftone palette + for (int i = 0; i < 256; i++) + { + pi.palPalEntry[i].peRed = ms_StdColors[i].rgbRed; + pi.palPalEntry[i].peGreen = ms_StdColors[i].rgbGreen; + pi.palPalEntry[i].peBlue = ms_StdColors[i].rgbBlue; + pi.palPalEntry[i].peFlags = 0; + } + } + + hPal = ::CreatePalette((LPLOGPALETTE) pi); + return (hPal != NULL); +} +#endif // DIBSECTION_NO_PALETTE + + +///////////////////////////////////////////////////////////////////////////// +// CDIB + +CDIB::CDIB() +{ + // Just in case... + ASSERT(sizeof(ms_StdColors) / sizeof(ms_StdColors[0]) == 256); + + m_hBitmap = NULL; + m_hOldBitmap = NULL; + +#ifndef DIBSECTION_NO_MEMDC_REUSE + m_bReuseMemDC = FALSE; +#endif + +#ifndef DIBSECTION_NO_PALETTE + m_hOldPal = NULL; +#endif +} + + +CDIB::~CDIB() +{ + // Unselect the bitmap out of the memory DC before deleting bitmap + ReleaseMemoryDC(TRUE); + + if (m_hBitmap) + ::DeleteObject(m_hBitmap); + m_hBitmap = NULL; + m_ppvBits = NULL; + +#ifndef DIBSECTION_NO_PALETTE + DeleteObject((HGDIOBJ) m_hPal); +#endif + + memset(&m_DIBinfo, 0, sizeof(m_DIBinfo)); + + m_iColorDataType = DIB_RGB_COLORS; + m_iColorTableSize = 0; +} + + +///////////////////////////////////////////////////////////////////////////// +// +// CDIB operations +// +// --- In  : pDC - Pointer to a device context +// ptDest - point at which the topleft corner of the image is drawn +// --- Out : +// --- Returns : TRUE on success +// --- Effect : Draws the image 1:1 on the device context +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::Draw(HDC hDC, POINT& ptDest, BOOL bForceBackground /*=FALSE*/) +{ + if (!m_hBitmap) + return FALSE; + + SIZE size; // = GetSize(); + POINT ptOrigin = {0,0}; + BOOL bResult = FALSE; + + // Create a memory DC compatible with the destination DC + HDC hMemDC = GetMemoryDC(hDC, FALSE); + if (!hMemDC) + return FALSE; + +#ifndef DIBSECTION_NO_PALETTE + // Select and realize the palette + HPALETTE hOldPalette = NULL; + if (m_hPal && UsesPalette(hDC)) + { + hOldPalette = SelectPalette(hDC, m_hPal, bForceBackground ); + RealizePalette(hDC); + } +#endif // DIBSECTION_NO_PALETTE + + bResult = BitBlt(hDC, ptDest.x, ptDest.y, size.cx, size.cy, hMemDC, + ptOrigin.x, ptOrigin.y, SRCCOPY); + +#ifndef DIBSECTION_NO_PALETTE + if (hOldPalette) + SelectPalette(hDC, hOldPalette, FALSE); +#endif // DIBSECTION_NO_PALETTE + + ReleaseMemoryDC(); + + return bResult; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// --- In  : pDC - Pointer to a device context +// ptDest - point at which the topleft corner of the image is drawn +// size - size to stretch the image +// --- Out : +// --- Returns : TRUE on success +// --- Effect : Stretch draws the image to the desired size on the device context +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::Stretch(HDC hDC, POINT& ptDest, SIZE& size, BOOL bForceBackground /*=FALSE*/) +{ + if (!m_hBitmap) + return FALSE; + + BOOL bResult = FALSE; + + POINT ptOrigin = {0,0}; + SIZE imagesize; + GetSize(imagesize); + +#ifndef _WIN32_WCE + //pDC->SetStretchBltMode(COLORONCOLOR); +#endif + + // Create a memory DC compatible with the destination DC + HDC hMemDC = GetMemoryDC(hDC, FALSE); + if (!hMemDC) + return FALSE; + +#ifndef DIBSECTION_NO_PALETTE + // Select and realize the palette + HPALETTE hOldPalette = NULL; + if (m_hPal && UsesPalette(hDC)) + { + hOldPalette = SelectPalette(hDC, m_hPal, bForceBackground); + RealizePalette(hDC); + } +#endif // DIBSECTION_NO_PALETTE + + bResult = StretchBlt(hDC, ptDest.x, ptDest.y, size.cx, size.cy, + hMemDC, ptOrigin.x, ptOrigin.y, imagesize.cx, imagesize.cy, SRCCOPY); + +#ifndef DIBSECTION_NO_PALETTE + if (hOldPalette) + SelectPalette(hDC, hOldPalette, FALSE); +#endif // DIBSECTION_NO_PALETTE + + ReleaseMemoryDC(); + + return bResult; +} + +////////////////////////////////////////////////////////////////////////////// +// Setting the bitmap... +// +// --- In  : nIDResource - resource ID +// --- Out : +// --- Returns : Returns TRUE on success, FALSE otherwise +// --- Effect : Initialises the bitmap from a resource. If failure, then object is +// initialised back to an empty bitmap. +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::SetBitmap(UINT nIDResource, HINSTANCE hInst /*= NULL*/ ) +{ + return SetBitmap(MAKEINTRESOURCE(nIDResource), hInst); +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// --- In  : lpszResourceName - resource name +// --- Out : +// --- Returns : Returns TRUE on success, FALSE otherwise +// --- Effect : Initialises the bitmap from a resource. If failure, then object is +// initialised back to an empty bitmap. +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::SetBitmap(LPCTSTR lpszRes, HINSTANCE hInst /*= NULL*/ ) +{ + HBITMAP hBmp = (HBITMAP)::LoadImage(hInst, lpszRes, IMAGE_BITMAP, 0,0,0); + if (!hBmp) + { + TRACE0("Unable to LoadImage"); + return FALSE; + } + + BOOL bResult = SetBitmap(hBmp); + ::DeleteObject(hBmp); + return bResult; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// --- In  : lpBitmapInfo - pointer to a BITMAPINFO structure +// lpBits - pointer to image bits +// --- Out : +// --- Returns : Returns TRUE on success, FALSE otherwise +// --- Effect : Initialises the bitmap using the information in lpBitmapInfo to determine +// the dimensions and colors, and the then sets the bits from the bits in +// lpBits. If failure, then object is initialised back to an empty bitmap. +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::SetBitmap(LPBITMAPINFO lpBitmapInfo, LPVOID lpBits) +{ +// DeleteObject(); + + if (!lpBitmapInfo || !lpBits) + return FALSE; + + HDC hDC = NULL; + BITMAPINFOHEADER& bmih = lpBitmapInfo->bmiHeader; + + // Compute the number of colors in the color table + m_iColorTableSize = NumColorEntries(bmih.biBitCount, bmih.biCompression); + + DWORD dwBitmapInfoSize = sizeof(BITMAPINFO) + m_iColorTableSize*sizeof(RGBQUAD); + + // Copy over BITMAPINFO contents + memcpy(&m_DIBinfo, lpBitmapInfo, dwBitmapInfoSize); + + // Should now have all the info we need to create the sucker. + //TRACE(_T("Width %d, Height %d, Bits/pixel %d, Image Size %d\n"), + // bmih.biWidth, bmih.biHeight, bmih.biBitCount, bmih.biSizeImage); + + // Create a DC which will be used to get DIB, then create DIBsection + hDC = ::GetDC(NULL); + if (!hDC) + { + TRACE0("Unable to get DC\n"); + return FALSE; + } + + m_hBitmap = CreateDIBSection(hDC, (const BITMAPINFO*) m_DIBinfo, m_iColorDataType, &m_ppvBits, NULL, 0); + ::ReleaseDC(NULL, hDC); + if (!m_hBitmap) + { + TRACE0("CreateDIBSection failed\n"); + return FALSE; + } + + if (m_DIBinfo.bmiHeader.biSizeImage == 0) + { + int nBytesPerLine = BytesPerLine(lpBitmapInfo->bmiHeader.biWidth, + lpBitmapInfo->bmiHeader.biBitCount); + m_DIBinfo.bmiHeader.biSizeImage = nBytesPerLine * lpBitmapInfo->bmiHeader.biHeight; + } + + memcpy(m_ppvBits, lpBits, m_DIBinfo.bmiHeader.biSizeImage); + +#ifndef DIBSECTION_NO_PALETTE + if (!CreatePalette()) + { + TRACE0("Unable to create palette\n"); + return FALSE; + } +#endif // DIBSECTION_NO_PALETTE + + return TRUE; +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// --- In  : hBitmap - handle to image +// pPalette - optional palette to use when setting image +// --- Out : +// --- Returns : Returns TRUE on success, FALSE otherwise +// --- Effect : Initialises the bitmap from the HBITMAP supplied. If failure, then +// object is initialised back to an empty bitmap. +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::SetBitmap(HBITMAP hBitmap, HPALETTE hPal /*= NULL*/) +{ +// DeleteObject(); + + if (!hBitmap) + return FALSE; + + // Get dimensions of bitmap + BITMAP bm; + if (!::GetObject(hBitmap, sizeof(bm),(LPVOID)&bm)) + return FALSE; + bm.bmHeight = abs(bm.bmHeight); + + HDC hDC = GetWindowDC(NULL); + HPALETTE hOldPal = NULL; + + m_iColorTableSize = NumColorEntries(bm.bmBitsPixel, BI_RGB); + + // Initialize the BITMAPINFOHEADER in m_DIBinfo + BITMAPINFOHEADER& bih = m_DIBinfo.bmiHeader; + bih.biSize = sizeof(BITMAPINFOHEADER); + bih.biWidth = bm.bmWidth; + bih.biHeight = bm.bmHeight; + bih.biPlanes = 1; // Must always be 1 according to docs + bih.biBitCount = bm.bmBitsPixel; + bih.biCompression = BI_RGB; + bih.biSizeImage = BytesPerLine(bm.bmWidth, bm.bmBitsPixel) * bm.bmHeight; + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + + GetColorTableEntries(hDC, hBitmap); + + // If we have a palette supplied, then set the palette (and hance DIB color + // table) using this palette + if (hPal) + SetPalette(hPal); + + if (hPal) + { + hOldPal = SelectPalette(hDC, m_hPal, FALSE); + RealizePalette(hDC); + } + + // Create it! + m_hBitmap = CreateDIBSection(hDC, (const BITMAPINFO*) m_DIBinfo, m_iColorDataType, &m_ppvBits, NULL, 0); + if (hOldPal) + SelectPalette(hDC, hOldPal, FALSE); + hOldPal = NULL; + + if (! m_hBitmap) + { + TRACE0("Unable to CreateDIBSection\n"); + return FALSE; + } + + // If palette was supplied then create a palette using the entries in the DIB + // color table. + if (! hPal) + CreatePalette(); + + // Need to copy the supplied bitmap onto the newly created DIBsection + HDC hMemDC = CreateCompatibleDC(hDC); + HDC hCopyDC = CreateCompatibleDC(hDC); + + if (! hMemDC || ! hCopyDC) + { + TRACE0("Unable to create compatible DC's\n"); + //AfxThrowResourceException(); + } + + if (m_hPal) + { + SelectPalette(hMemDC, m_hPal, FALSE); RealizePalette(hMemDC); + SelectPalette(hCopyDC, m_hPal, FALSE); RealizePalette(hCopyDC); + } + + HBITMAP hOldMemBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap); + HBITMAP hOldCopyBitmap = (HBITMAP) SelectObject(hCopyDC, m_hBitmap); + + BitBlt(hCopyDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + + SelectObject(hMemDC, hOldMemBitmap); + SelectObject(hCopyDC, hOldCopyBitmap); + + if (m_hPal) + { + HGDIOBJ hObj = ::GetStockObject(DEFAULT_PALETTE); + SelectObject(hMemDC, hObj); + SelectObject(hCopyDC, hObj); + } + + ReleaseDC(NULL, hDC); + return TRUE; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// CDIB palette stuff +// +// --- In  : nNumColors - number of colors to set +// pColors - array of RGBQUAD's containing colors to set +// --- Out : +// --- Returns : Returns TRUE on success, FALSE otherwise +// --- Effect : Sets the colors used by the image. Only works if # colors <= 256 +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::SetColorTable(UINT nNumColors, RGBQUAD *pColors) +{ + if (!m_hBitmap ||!pColors || !nNumColors || m_iColorTableSize == 0 || nNumColors > 256) + return FALSE; + + LPRGBQUAD pColorTable = GetColorTable(); + ASSERT(pColorTable); + + int nCount = min(m_iColorTableSize, nNumColors); + ::memset(pColorTable, 0, m_iColorTableSize*sizeof(RGBQUAD)); + ::memcpy(pColorTable, pColors, nCount*sizeof(RGBQUAD)); + + return TRUE; +} + + +// --- In  : +// --- Out : +// --- Returns : TRUE on success +// --- Effect : Creates the palette from the DIBSection's color table. Assumes +// m_iColorTableSize has been set and the DIBsection m_hBitmap created +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::CreatePalette() +{ + //m_hPal DeleteObject(); + + if (!m_hBitmap) + return FALSE; + + // Create a 256 color halftone palette if there is no color table in the DIBSection + if (m_iColorTableSize == 0) + return CreateHalftonePalette(m_hPal, 256); + + // Get space for the color entries + RGBQUAD *pRGB = new RGBQUAD[m_iColorTableSize]; + if (!pRGB) + return CreateHalftonePalette(m_hPal, m_iColorTableSize); + + HDC hDC = ::GetDC(NULL); + if (!hDC) + { + delete [] pRGB; + return FALSE; + } + + // Create a memory DC compatible with the current DC + HDC hMemDC = CreateCompatibleDC(hDC); + if (!hMemDC) + { + delete [] pRGB; + ReleaseDC(NULL, hDC); + return CreateHalftonePalette(m_hPal, m_iColorTableSize); + } + ReleaseDC(NULL, hDC); + + HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemDC, m_hBitmap); + if (!hOldBitmap) + { + delete [] pRGB; + return CreateHalftonePalette(m_hPal, m_iColorTableSize); + } + + // Get the colors used. WinCE does not support GetDIBColorTable so if you + // are using this on a CE device with palettes, then you need to replace + // the call with code that manually gets the color table from the m_DIBinfo structure. + int nColors = CEGetDIBColorTable(hDC, 0, m_iColorTableSize, pRGB); + + // Clean up + SelectObject(hMemDC, hOldBitmap); + + if (!nColors) // No colors retrieved => the bitmap in the DC is not a DIB section + { + delete [] pRGB; + return CreateHalftonePalette(m_hPal, m_iColorTableSize); + } + + // Create and fill a LOGPALETTE structure with the colors used. + PALETTEINFO PaletteInfo; + PaletteInfo.palNumEntries = m_iColorTableSize; + + for (int ii = 0; ii < nColors; ii++) + { + PaletteInfo.palPalEntry[ii].peRed = pRGB[ii].rgbRed; + PaletteInfo.palPalEntry[ii].peGreen = pRGB[ii].rgbGreen; + PaletteInfo.palPalEntry[ii].peBlue = pRGB[ii].rgbBlue; + PaletteInfo.palPalEntry[ii].peFlags = 0; + } + + delete [] pRGB; + + // Create Palette! + m_hPal = ::CreatePalette( &PaletteInfo ); + return (NULL != m_hPal); +} + +// --- In  : pPalette - new palette to use +// --- Out : +// --- Returns : TRUE on success +// --- Effect : Sets the current palette used by the image from the supplied CPalette, +// and sets the color table in the DIBSection +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::SetPalette(HPALETTE hPal) +{ + // m_Palette.DeleteObject(); + + if (!hPal) + return FALSE; + + WORD nColors; + ::GetObject(hPal, sizeof(WORD), &nColors); + + if (nColors <= 0 || nColors > 256) + return FALSE; + + // Get palette entries + PALETTEINFO pi; + pi.palNumEntries = (WORD) ::GetPaletteEntries(hPal, 0, nColors, (LPPALETTEENTRY) pi); + return SetLogPalette(&pi); +} + +// --- In  : pLogPalette - new palette to use +// --- Out : +// --- Returns : TRUE on success +// --- Effect : Sets the current palette used by the image from the supplied LOGPALETTE +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::SetLogPalette(LOGPALETTE* pLogPalette) +{ + if (!pLogPalette) + { + CreatePalette(); + return FALSE; + } + + ASSERT(pLogPalette->palVersion == (WORD) 0x300); + + UINT nColors = pLogPalette->palNumEntries; + if (nColors <= 0 || nColors > 256) + { + CreatePalette(); + return FALSE; + } + + // Create new palette + DeleteObject( m_hPal ); + m_hPal = ::CreatePalette(pLogPalette); + if (!m_hPal) + { + CreatePalette(); + return FALSE; + } + + if (m_iColorTableSize == 0) + return TRUE; + + // Set the DIB colors + RGBQUAD RGBquads[256]; + for (UINT i = 0; i < nColors; i++) + { + RGBquads[i].rgbRed = pLogPalette->palPalEntry[i].peRed; + RGBquads[i].rgbGreen = pLogPalette->palPalEntry[i].peGreen; + RGBquads[i].rgbBlue = pLogPalette->palPalEntry[i].peBlue; + RGBquads[i].rgbReserved = 0; + } + + return FillDIBColorTable(nColors, RGBquads); +} + +// --- In  : nNumColors - number of colors to set +// pRGB - colors to fill +// --- Out : +// --- Returns : Returns TRUE on success +// --- Effect : Sets the colors used by the image. Only works if # colors <= 256 +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::FillDIBColorTable(UINT nNumColors, RGBQUAD *pRGB) +{ + if (!pRGB || !nNumColors || !m_iColorTableSize || nNumColors > 256) + return FALSE; + + // get the number of colors to return per BITMAPINFOHEADER docs + UINT nColors; + LPBITMAPINFOHEADER pBmih = GetBitmapInfoHeader(); + if (pBmih->biClrUsed) + nColors = pBmih->biClrUsed; + else + nColors = 1 << (pBmih->biBitCount*pBmih->biPlanes); + + // Initialize the loop variables + nColors = min(nNumColors, nColors); + + LPRGBQUAD pColorTable = GetColorTable(); + for (UINT iColor = 0; iColor < nColors; iColor++) + { + pColorTable[iColor].rgbReserved = 0; + pColorTable[iColor].rgbBlue = pRGB[iColor].rgbBlue; + pColorTable[iColor].rgbRed = pRGB[iColor].rgbRed; + pColorTable[iColor].rgbGreen = pRGB[iColor].rgbGreen; + } + + return TRUE; +} + +//#endif // DIBSECTION_NO_PALETTE + + +// --- In  : hdc - the Device Context in which the DIBSection is selected +// hBitmap - the bitmap whose solor entries are to be queried +// lpbi - a pointer to a BITMAPINFO structure that will have it's +// color table filled. +// --- Out : +// --- Returns : the number of colors placed in the color table +// --- Effect : This function is a replacement for GetDIBits, in that it retrieves +// (or synthesizes) the color table from the given bitmap, and stores +// the values in the BITMAPINFO structure supplied. +// +/////////////////////////////////////////////////////////////////////////////// + +UINT CDIB::GetColorTableEntries(HDC hdc, HBITMAP hBitmap) +{ + if (!m_iColorTableSize) + return 0; + + // Fill the color table with the colors from the bitmap's color table + LPRGBQUAD pColorTable = GetColorTable(); + + // Get the color table from the HBITMAP and copy them over. + UINT nCount; + RGBQUAD* pRGB = new RGBQUAD[m_iColorTableSize]; + if (pRGB) + { + HBITMAP hOldBitmap = (HBITMAP) SelectObject(hdc, hBitmap); + nCount = CEGetDIBColorTable(hdc, 0, m_iColorTableSize, pRGB); + SelectObject(hdc, hOldBitmap); + if (nCount) + { + // m_iColorTableSize = nCount; + memcpy(pColorTable, pRGB, nCount*sizeof(RGBQUAD)); + } + } + delete [] pRGB; + + // Didn't work - so synthesize one. + if (!nCount) + { + nCount = min( m_iColorTableSize, sizeof(ms_StdColors) / sizeof(ms_StdColors[0]) ); + memcpy(pColorTable, ms_StdColors, nCount*sizeof(RGBQUAD)); + } + + return nCount; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// This function is from the MS KB article "HOWTO: Get the Color Table of +// DIBSection in Windows CE". +// +// PARAMETERS: +// HDC - the Device Context in which the DIBSection is selected +/// UINT - the index of the first color table entry to retrieve +// UINT - the number of color table entries to retrieve +// RGBQUAD - a buffer large enough to hold the number of RGBQUAD +// entries requested +// +// RETURNS: +// UINT - the number of colors placed in the buffer +// +// +/////////////////////////////////////////////////////////////////////////////// + +UINT CEGetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries, RGBQUAD *pColors) +{ + if (pColors == NULL) + return 0; // No place to put them, fail + + // Get a description of the DIB Section + HBITMAP hDIBSection = (HBITMAP) GetCurrentObject( hdc, OBJ_BITMAP ); + + DIBSECTION ds; + DWORD dwSize = GetObject( hDIBSection, sizeof(DIBSECTION), &ds ); + + if (dwSize != sizeof(DIBSECTION)) + return 0; // Must not be a DIBSection, fail + + if (ds.dsBmih.biBitCount > 8) + return 0; // Not Palettized, fail + + // get the number of colors to return per BITMAPINFOHEADER docs + UINT cColors; + if (ds.dsBmih.biClrUsed) + cColors = ds.dsBmih.biClrUsed; + else + cColors = 1 << (ds.dsBmih.biBitCount * ds.dsBmih.biPlanes); + + // Create a mask for the palette index bits for 1, 2, 4, and 8 bpp + WORD wIndexMask = (0xFF << (8 - ds.dsBmih.biBitCount)) & 0x00FF; + + // Get the pointer to the image bits + LPBYTE pBits = (LPBYTE) ds.dsBm.bmBits; + + // Initialize the loop variables + cColors = min( cColors, cEntries ); + BYTE OldPalIndex = *pBits; + + UINT TestPixelY; + if (ds.dsBmih.biHeight > 0 ) + // If button up DIB, pBits points to last row + TestPixelY = ds.dsBm.bmHeight-1; + else + // If top down DIB, pBits points to first row + TestPixelY = 0; + + for (UINT iColor = uStartIndex; iColor < cColors; iColor++) + { + COLORREF rgbColor; + + // Set the palette index for the test pixel, + // modifying only the bits for one pixel + *pBits = (iColor << (8 - ds.dsBmih.biBitCount)) | (*pBits & ~wIndexMask); + + // now get the resulting color + rgbColor = GetPixel( hdc, 0, TestPixelY ); + + pColors[iColor - uStartIndex].rgbReserved = 0; + pColors[iColor - uStartIndex].rgbBlue = GetBValue(rgbColor); + pColors[iColor - uStartIndex].rgbRed = GetRValue(rgbColor); + pColors[iColor - uStartIndex].rgbGreen = GetGValue(rgbColor); + } + + // Restore the test pixel + *pBits = OldPalIndex; + + return cColors; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// --- In  : pDC - device context to use when calling CreateCompatibleDC +// bSelectPalette - if TRUE, the current palette will be preselected +// --- Out : +// --- Returns : A pointer to a memory DC +// --- Effect : Creates a memory DC and selects in the current bitmap so it can be +// modified using the GDI functions. Only one memDC can be created for +// a given CDIB object. If you have a memDC but wish to recreate it +// as compatible with a different DC, then call ReleaseMemoryDC first. +// If the memory DC has already been created then it will be recycled. +// Note that if using this in an environment where the color depth of +// the screen may change, then you will need to set "m_bReuseMemDC" to FALSE +// +/////////////////////////////////////////////////////////////////////////////// + +HDC CDIB::GetMemoryDC(HDC hDC /*=NULL*/, BOOL bSelectPalette /*=TRUE*/) +{ +#ifdef DIBSECTION_NO_MEMDC_REUSE + ReleaseMemoryDC(TRUE); +#else + if (!m_bReuseMemDC) + { + ReleaseMemoryDC(TRUE); + } + else if (m_hMemDC) // Already created? + { + return m_hMemDC; + } +#endif // DIBSECTION_NO_MEMDC_REUSE + + // Create a memory DC compatible with the given DC + m_hMemDC = CreateCompatibleDC(hDC); + if (!m_hMemDC) + return NULL; + + // Select in the bitmap + m_hOldBitmap = (HBITMAP) ::SelectObject(m_hMemDC, m_hBitmap); + + // Select in the palette + if (bSelectPalette && UsesPalette(m_hMemDC)) + { + // Palette should already have been created - but just in case... + if (!m_hPal) + CreatePalette(); + + m_hOldPal = SelectPalette( m_hMemDC, m_hPal, FALSE ); + RealizePalette( m_hMemDC ); + } + else + m_hOldPal = NULL; + + return m_hMemDC; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// --- In  : bForceRelease - if TRUE, then the memory DC is forcibly released +// --- Out : +// --- Returns : TRUE on success +// --- Effect : Selects out the current bitmap and deletes the mem dc. If bForceRelease +// is FALSE, then the DC release will not actually occur. This is provided +// so you can have +// +// GetMemoryDC(...) +// ... do something +// ReleaseMemoryDC() +// +// bracketed calls. If m_bReuseMemDC is subsequently set to FALSE, then +// the same code fragment will still work. +// +/////////////////////////////////////////////////////////////////////////////// + +BOOL CDIB::ReleaseMemoryDC(BOOL bForceRelease /*=FALSE*/) +{ + if ( !m_hMemDC +#ifndef DIBSECTION_NO_MEMDC_REUSE + || (m_bReuseMemDC && !bForceRelease) +#endif // DIBSECTION_NO_MEMDC_REUSE + ) + return TRUE; // Nothing to do + + // Select out the current bitmap + if (m_hOldBitmap) + ::SelectObject(m_hMemDC, m_hOldBitmap); + + m_hOldBitmap = NULL; + +#ifndef DIBSECTION_NO_PALETTE + // Select out the current palette + if (m_hOldPal) + SelectPalette(m_hMemDC, m_hOldPal, FALSE); + + m_hOldPal = NULL; +#endif // DIBSECTION_NO_PALETTE + + // Delete the memory DC + return DeleteDC(m_hMemDC); +} + diff --git a/rosapps/smartpdf/baseutils/win_dib.h b/rosapps/smartpdf/baseutils/win_dib.h new file mode 100644 index 00000000000..12b4deca475 --- /dev/null +++ b/rosapps/smartpdf/baseutils/win_dib.h @@ -0,0 +1,219 @@ +#ifndef __DIB_h__ +#define __DIB_h__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// CDIB.h : header file +// + +// Copyright © Dundas Software Ltd. 1999, All Rights Reserved + +// ////////////////////////////////////////////////////////////////////////// + +// Properties: +// NO Abstract class (does not have any objects) +// NO Derived from CWnd +// NO Is a CWnd. +// NO Two stage creation (constructor & Create()) +// NO Has a message map +// NO Needs a resource (template) +// YES Persistent objects (saveable on disk) +// YES Uses exceptions + +// ////////////////////////////////////////////////////////////////////////// + +// Desciption : + +// CDIBSectionLite is DIBSection wrapper class for win32 and WinCE platforms. +// This class provides a simple interface to DIBSections including loading, +// saving and displaying DIBsections. +// +// Full palette support is provided for Win32 and CE 2.11 and above. + +// Using CDIBSectionLite : + +// This class is very simple to use. The bitmap can be set using either SetBitmap() +// (which accepts either a Device dependant or device independant bitmap, or a +// resource ID) or by using Load(), which allows an image to be loaded from disk. +// To display the bitmap simply use Draw or Stretch. +// +// eg. +// +// CDIBsection dibsection; +// dibsection.Load(_T("image.bmp")); +// dibsection.Draw(pDC, CPoint(0,0)); // pDC is of type CDC* +// +// CDIBsection dibsection; +// dibsection.SetBitmap(IDB_BITMAP); +// dibsection.Draw(pDC, CPoint(0,0)); // pDC is of type CDC* +// +// The CDIBsection API includes many methods to extract information about the +// image, as well as palette options for getting and setting the current palette. +// +// Author : Chris Maunder (cmaunder@mail.com) +// Date : 12 April 1999 + +// Modified : Kenny Goers (kennyg@magenic.com) +// Date : 12 December 2000 +// Why : Remove all MFC bloat + +// CDIB.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// defines + +//#define DIBSECTION_NO_DITHER // Disallow dithering via DrawDib functions +#define DIBSECTION_NO_MEMDC_REUSE // Disallow the reuse of memory DC's +//#define DIBSECTION_NO_PALETTE // Remove palette support + +// Only provide palette support for non-CE platforms, or for CE 2.11 and above +#define DIBSECTION_NO_DITHER // DrawDib not supported on CE +#if (_WIN32_WCE < 211) +# define DIBSECTION_NO_PALETTE // No palette support on early CE devices +#endif + +#define DS_BITMAP_FILEMARKER ((WORD) ('M' << 8) | 'B') // is always "BM" = 0x4D42 + +///////////////////////////////////////////////////////////////////////////// +// BITMAPINFO wrapper + +struct DIBINFO : public BITMAPINFO +{ + RGBQUAD arColors[255]; // Color table info - adds an extra 255 entries to palette + + operator LPBITMAPINFO() { return (LPBITMAPINFO) this; } + operator LPBITMAPINFOHEADER() { return &bmiHeader; } + RGBQUAD* ColorTable() { return bmiColors; } +}; + +///////////////////////////////////////////////////////////////////////////// +// LOGPALETTE wrapper + +#ifndef DIBSECTION_NO_PALETTE +struct PALETTEINFO : public LOGPALETTE +{ + PALETTEENTRY arPalEntries[255]; // Palette entries + + PALETTEINFO() + { + palVersion = (WORD) 0x300; + palNumEntries = 0; + ::memset(palPalEntry, 0, 256*sizeof(PALETTEENTRY)); + } + + operator LPLOGPALETTE() { return (LPLOGPALETTE) this; } + operator LPPALETTEENTRY() { return (LPPALETTEENTRY) (palPalEntry); } +}; +#endif // DIBSECTION_NO_PALETTE + + +///////////////////////////////////////////////////////////////////////////// +// CeDIB object + +class CeDIB +{ +// Construction +public: + CeDIB(); + virtual ~CeDIB(); + +// static helpers +public: + static int BytesPerLine(int nWidth, int nBitsPerPixel); + static int NumColorEntries(int nBitsPerPixel, int nCompression); + + static RGBQUAD ms_StdColors[]; +#ifndef DIBSECTION_NO_PALETTE + static BOOL UsesPalette(HDC hDC) + { return (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE); } + static BOOL CreateHalftonePalette(HPALETTE palette, int nNumColors); +#endif // DIBSECTION_NO_PALETTE + +// Attributes +public: + HBITMAP GetSafeHandle() const { return (this)? m_hBitmap : NULL; } + operator HBITMAP() const { return GetSafeHandle(); } + void GetSize(SIZE& size) const { size.cx = GetWidth(); size.cy = GetHeight(); } + int GetHeight() const { return m_DIBinfo.bmiHeader.biHeight; } + int GetWidth() const { return m_DIBinfo.bmiHeader.biWidth; } + int GetPlanes() const { return m_DIBinfo.bmiHeader.biPlanes; } + int GetBitCount() const { return m_DIBinfo.bmiHeader.biBitCount; } + LPVOID GetDIBits() { return m_ppvBits; } + LPBITMAPINFO GetBitmapInfo() { return (BITMAPINFO*) m_DIBinfo; } + DWORD GetImageSize() const { return m_DIBinfo.bmiHeader.biSizeImage; } + LPBITMAPINFOHEADER GetBitmapInfoHeader() { return (BITMAPINFOHEADER*) m_DIBinfo; } + +// Operations (Palette) +public: + LPRGBQUAD GetColorTable() { return m_DIBinfo.ColorTable(); } + BOOL SetColorTable(UINT nNumColors, RGBQUAD *pColors); + int GetColorTableSize() { return m_iColorTableSize; } +#ifndef DIBSECTION_NO_PALETTE + HPALETTE GetPalette() { return m_hPal; } + BOOL SetPalette(HPALETTE pPalette); + BOOL SetLogPalette(LOGPALETTE* pLogPalette); +#endif // DIBSECTION_NO_PALETTE + +// Operations (Setting the bitmap) +public: + BOOL SetBitmap(UINT nIDResource, HINSTANCE hInst = NULL); + BOOL SetBitmap(LPCTSTR lpszResourceName, HINSTANCE hInst = NULL); + BOOL SetBitmap(HBITMAP hBitmap, HPALETTE hPal = NULL); + BOOL SetBitmap(LPBITMAPINFO lpBitmapInfo, LPVOID lpBits); + + BOOL Load(LPCTSTR lpszFileName); + BOOL Save(LPCTSTR lpszFileName); + BOOL Copy(CeDIB& Bitmap); + +// Operations (Display) +public: + BOOL Draw(HDC hDC, POINT& ptDest, BOOL bForceBackground = FALSE); + BOOL Stretch(HDC hDC, POINT& ptDest, SIZE& size, BOOL bForceBackground = FALSE); + + HDC GetMemoryDC(HDC hDC = NULL, BOOL bSelectPalette = TRUE); + BOOL ReleaseMemoryDC(BOOL bForceRelease = FALSE); + +// Overrideables + +// Implementation +public: + +// Implementation +protected: +#ifndef DIBSECTION_NO_PALETTE + BOOL CreatePalette(); + BOOL FillDIBColorTable(UINT nNumColors, RGBQUAD *pRGB); +#endif // DIBSECTION_NO_PALETTE + UINT GetColorTableEntries(HDC hdc, HBITMAP hBitmap); + +protected: + HBITMAP m_hBitmap; // Handle to DIBSECTION + DIBINFO m_DIBinfo; // Bitmap header & color table info + VOID *m_ppvBits; // Pointer to bitmap bits + UINT m_iColorDataType; // color data type (palette or RGB values) + UINT m_iColorTableSize; // Size of color table + + HDC m_hMemDC; // Memory DC for drawing on bitmap + +#ifndef DIBSECTION_NO_MEMDC_REUSE + BOOL m_bReuseMemDC; // Reeuse the memory DC? (Quicker, but not fully tested) +#endif + +#ifndef DIBSECTION_NO_PALETTE + HPALETTE m_hPal; // Color palette + HPALETTE m_hOldPal; +#endif // DIBSECTION_NO_PALETTE + +private: + HBITMAP m_hOldBitmap; // Storage for previous bitmap in Memory DC +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CeDIB_H__35D9F3D4_B960_11D2_A981_2C4476000000__INCLUDED_) diff --git a/rosapps/smartpdf/baseutils/win_image.cpp b/rosapps/smartpdf/baseutils/win_image.cpp new file mode 100644 index 00000000000..5097995ea6e --- /dev/null +++ b/rosapps/smartpdf/baseutils/win_image.cpp @@ -0,0 +1,139 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" +#include "win_image.h" +#define INITGUID +#include +#include + +#pragma comment(lib, "imaging") + +/* TODO: those only work on wince 5.0 so we should have fallback for + earlier versions */ + +struct win_image { + IImage * image; + int dx; + int dy; +}; + +win_image *win_image_from_file(const TCHAR *file_path) +{ + IImagingFactory* imageFactory; + ImageInfo info; + win_image * img = NULL; + + img = SAZ(win_image); + if (!img) + return NULL; + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + HRESULT hr = CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, + IID_IImagingFactory, (LPVOID*)&imageFactory); + + if (FAILED(hr)) + goto Error; + + hr = imageFactory->CreateImageFromFile(file_path, &img->image); + imageFactory->Release(); + if (FAILED(hr)) + goto Error; + + img->image->GetImageInfo(&info); + + img->dx = info.Width; + img->dy = info.Height; + + return img; + +Error: + win_image_delete(img); + return NULL; +} + +win_image * win_image_from_buffer(void *buf, UINT buf_size) +{ + IImagingFactory* imageFactory; + ImageInfo info; + win_image * img = NULL; + + img = SAZ(win_image); + if (!img) + return NULL; + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + HRESULT hr = CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, + IID_IImagingFactory, (LPVOID*)&imageFactory); + + if (FAILED(hr)) + goto Error; + + hr = imageFactory->CreateImageFromBuffer(buf, buf_size, BufferDisposalFlagNone, &img->image); + imageFactory->Release(); + if (FAILED(hr)) + goto Error; + + img->image->GetImageInfo(&info); + + img->dx = info.Width; + img->dy = info.Height; + + return img; + +Error: + win_image_delete(img); + return NULL; +} + +win_image *win_image_from_resource(HMODULE hinst, int resource_id) +{ + HRSRC hres; + void * buf; + DWORD res_size; + HGLOBAL hdata; + + hres = FindResource(hinst, MAKEINTRESOURCE(resource_id), RT_RCDATA); + if (!hres) + return NULL; + + res_size = SizeofResource(hinst, hres); + if (0 == res_size) + return NULL; + + hdata = LoadResource(hinst, hres); + if (!hdata) + return NULL; + + buf = (void*)LockResource(hdata); + if (!buf) + return NULL; + + return win_image_from_buffer(buf, (UINT)res_size); +} + +void win_image_delete(win_image *img) +{ + assert(img); + if (!img) + return; + if (img->image) + img->image->Release(); + free(img); +} +void win_image_blit_at(win_image *img, HDC dc, int x, int y) +{ + RECT r = {0}; + assert(img); + if (!img) + return; + + assert(img->image); + if (!img->image) + return; + r.left = x; + r.right = x + img->dx; + r.top = y; + r.bottom = y + img->dy; + img->image->Draw(dc, &r, NULL); +} + diff --git a/rosapps/smartpdf/baseutils/win_image.h b/rosapps/smartpdf/baseutils/win_image.h new file mode 100644 index 00000000000..40ad295e229 --- /dev/null +++ b/rosapps/smartpdf/baseutils/win_image.h @@ -0,0 +1,23 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef WIN_IMAGE_H__ +#define WIN_IMAGE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct win_image win_image; + +win_image * win_image_from_file(const TCHAR *file_path); +win_image * win_image_from_buffer(void *buf, UINT buf_size); +win_image * win_image_from_resource(HMODULE hinst, int resource_id); +void win_image_delete(win_image *img); +void win_image_blit_at(win_image *img, HDC dc, int x, int y); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/win_util.c b/rosapps/smartpdf/baseutils/win_util.c new file mode 100644 index 00000000000..b1588ac0c6a --- /dev/null +++ b/rosapps/smartpdf/baseutils/win_util.c @@ -0,0 +1,463 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#include "base_util.h" +#include "win_util.h" +#include "tstr_util.h" + +#ifdef _WIN32_WCE +#include +#include +#endif + +// Hmm, why have to redefine here (?!) +#ifdef __GNUC__ +#define LVM_GETSELECTIONMARK (LVM_FIRST+66) +#define ListView_GetSelectionMark(w) (INT)SNDMSG((w),LVM_GETSELECTIONMARK,0,0) +#endif + +int rect_dx(RECT *r) +{ + int dx = r->right - r->left; + assert(dx >= 0); + return dx; +} + +int rect_dy(RECT *r) +{ + int dy = r->bottom - r->top; + assert(dy >= 0); + return dy; +} + +void rect_set(RECT *r, int x, int y, int dx, int dy) +{ + r->left = x; + r->top = y; + r->right = x + dx; + r->bottom = y + dy; +} + +void win_set_font(HWND hwnd, HFONT font) +{ + SendMessage(hwnd, WM_SETFONT, (WPARAM)font, 0); +} + +int win_get_text_len(HWND hwnd) +{ + return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); +} + +void win_set_text(HWND hwnd, const TCHAR *txt) +{ + SendMessage(hwnd, WM_SETTEXT, (WPARAM)0, (LPARAM)txt); +} + +/* return a text in edit control represented by hwnd + return NULL in case of error (couldn't allocate memory) + caller needs to free() the text */ +TCHAR *win_get_text(HWND hwnd) +{ + int cchTxtLen = win_get_text_len(hwnd); + TCHAR * txt = (TCHAR*)malloc((cchTxtLen+1)*sizeof(TCHAR)); + + if (NULL == txt) + return NULL; + + SendMessage(hwnd, WM_GETTEXT, cchTxtLen + 1, (LPARAM)txt); + txt[cchTxtLen] = 0; + return txt; +} + +void win_edit_set_selection(HWND hwnd, DWORD selStart, DWORD selEnd) +{ + SendMessage(hwnd, EM_SETSEL, (WPARAM)selStart, (WPARAM)selEnd); +} + +void win_edit_select_all(HWND hwnd) +{ + win_edit_set_selection(hwnd, 0, -1); +} + +LRESULT lv_delete_all_items(HWND hwnd) +{ + return SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0); +} + +LRESULT lv_set_items_count(HWND hwnd, int items_count) +{ +#ifdef __GNUC__ + ListView_SetItemCount(hwnd, items_count); +#else + return ListView_SetItemCount(hwnd, items_count); +#endif +} + +int lv_get_items_count(HWND hwnd) +{ + LRESULT count = ListView_GetItemCount(hwnd); + if (LB_ERR == count) + return 0; + return (int)count; +} + +LRESULT lv_insert_column(HWND hwnd, int col, LVCOLUMN *lvc) +{ + return SendMessage(hwnd, LVM_INSERTCOLUMN, col, (LPARAM)lvc); +} + +LRESULT lv_set_column(HWND hwnd, int col, LVCOLUMN *lvc) +{ + return SendMessage(hwnd, LVM_SETCOLUMN, col, (LPARAM)lvc); +} + +LRESULT lv_set_column_dx(HWND hwnd, int col, int dx) +{ + return ListView_SetColumnWidth(hwnd, col, dx); +} + +LRESULT lv_insert_item(HWND hwnd, int row, LVITEM *lvi) +{ + lvi->iItem = row; + lvi->iSubItem = 0; + return SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM)lvi); +} + +LRESULT lb_delete_string(HWND hwnd, int pos) +{ + return SendMessage(hwnd, LB_DELETESTRING, pos, 0); +} + +LRESULT lb_delete_all_items(HWND hwnd) +{ +#if 1 + LRESULT remaining_count; + for (;;) { + remaining_count = lb_delete_string(hwnd, 0); + if ((LB_ERR == remaining_count) || (0 == remaining_count)) + break; + } + return 0; +#else + LRESULT count; + int i; + + count = lb_get_items_count(hwnd); + if (LB_ERR == count) + return LB_ERR; + + for (i=count-1; i--; i>=0) { + lb_delete_string(hwnd, i); + } + assert(0 == lb_get_items_count(hwnd); +#endif +} + +#if 0 +LRESULT lb_set_items_count(HWND hwnd, int items_count) +{ + return SendMessage(hwnd, LB_SETCOUNT, items_count, 0); +} +#endif + +LRESULT lb_get_items_count(HWND hwnd) +{ + return SendMessage(hwnd, LB_GETCOUNT, 0, 0); +} + +LRESULT lb_insert_item_text(HWND hwnd, int row, const TCHAR *txt) +{ + return SendMessage(hwnd, LB_INSERTSTRING, (WPARAM)row, (LPARAM)txt); +} + +LRESULT lb_append_string_no_sort(HWND hwnd, const TCHAR *txt) +{ + return lb_insert_item_text(hwnd, -1, txt); +} + +/* lb_get_selection and lb_set_selection only work for single-selection listbox */ +LRESULT lb_get_selection(HWND hwnd) +{ + return SendMessage(hwnd, LB_GETCURSEL, 0, 0); +} + +LRESULT lb_set_selection(HWND hwnd, int item) +{ + assert(item >= 0); + return SendMessage(hwnd, LB_SETCURSEL, (WPARAM)item, 0); +} + +LRESULT lv_insert_item_text(HWND hwnd, int row, const TCHAR *txt) +{ + LVITEM lvi = {0}; + + assert(txt); + if (!txt) + return -1; /* means failure */ + lvi.mask = LVIF_TEXT; + lvi.pszText = (LPTSTR)txt; + return lv_insert_item(hwnd, row, &lvi); +} + +/* Returns a selected item or -1 if no selection. + Assumes that the list is single-sel */ +int lv_get_selection_pos(HWND hwnd) +{ + int selection; + int selected_count = ListView_GetSelectedCount(hwnd); + assert(selected_count <= 1); + if (0 == selected_count) + return -1; + selection = ListView_GetSelectionMark(hwnd); + return selection; +} + +int font_get_dy_from_dc(HDC hdc, HFONT font) +{ + TEXTMETRIC tm; + HFONT font_prev; + int font_dy; + + font_prev = (HFONT)SelectObject(hdc, font); + GetTextMetrics(hdc, &tm); + font_dy = tm.tmAscent + tm.tmDescent; + SelectObject(hdc, font_prev); + return font_dy; +} + +int font_get_dy(HWND hwnd, HFONT font) +{ + HDC hdc; + int font_dy = 0; + + hdc = GetDC(hwnd); + if (hdc) + font_dy = font_get_dy_from_dc(hdc, font); + ReleaseDC(hwnd, hdc); + return font_dy; +} + +#ifdef _WIN32_WCE +/* see http://pocketpcdn.com/articles/wordcompletion.html for details + edit boxes on pocket pc by default have spelling suggestion/completion. + Sometimes we want/need to disable that and this is a function to do it. */ +void sip_completion_disable(void) +{ + SIPINFO info; + + SHSipInfo(SPI_GETSIPINFO, 0, &info, 0); + info.fdwFlags |= SIPF_DISABLECOMPLETION; + SHSipInfo(SPI_SETSIPINFO, 0, &info, 0); +} + +void sip_completion_enable(void) +{ + SIPINFO info; + + SHSipInfo(SPI_GETSIPINFO, 0, &info, 0); + info.fdwFlags &= ~SIPF_DISABLECOMPLETION; + SHSipInfo(SPI_SETSIPINFO, 0, &info, 0); +} +#endif + +void launch_url(const TCHAR *url) +{ + SHELLEXECUTEINFO sei; + BOOL res; + + if (NULL == url) + return; + + ZeroMemory(&sei, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_FLAG_NO_UI; + sei.lpVerb = TEXT("open"); + sei.lpFile = url; + sei.nShow = SW_SHOWNORMAL; + + res = ShellExecuteEx(&sei); + return; +} + +/* On windows those are defined as: +#define CSIDL_PROGRAMS 0x0002 +#define CSIDL_PERSONAL 0x0005 +#define CSIDL_APPDATA 0x001a + see shlobj.h for more */ + +#ifdef CSIDL_APPDATA +/* this doesn't seem to be defined on sm 2002 */ +#define SPECIAL_FOLDER_PATH CSIDL_APPDATA +#endif + +#ifdef CSIDL_PERSONAL +/* this is defined on sm 2002 and goes to "\My Documents". + Not sure if I should use it */ + #ifndef SPECIAL_FOLDER_PATH + #define SPECIAL_FOLDER_PATH CSIDL_PERSONAL + #endif +#endif + +/* see http://www.opennetcf.org/Forums/post.asp?method=TopicQuote&TOPIC_ID=95&FORUM_ID=12 + for more possibilities + return false on failure, true if ok. Even if returns false, it'll return root ("\") + directory so that clients can ignore failures from this function +*/ +TCHAR *get_app_data_folder_path(BOOL f_create) +{ +#ifdef SPECIAL_FOLDER_PATH + BOOL f_ok; + TCHAR path[MAX_PATH]; + + f_ok = SHGetSpecialFolderPath(NULL, path, SPECIAL_FOLDER_PATH, f_create); + if (f_ok) + return tstr_dup(path); + else + return tstr_dup(_T("")); +#else + /* if all else fails, just use root ("\") directory */ + return tstr_dup(_T("")); +#endif +} + +void screen_get_dx_dy(int *dx_out, int *dy_out) +{ + if (dx_out) + *dx_out = GetSystemMetrics(SM_CXSCREEN); + if (dy_out) + *dy_out = GetSystemMetrics(SM_CYSCREEN); +} + +int screen_get_dx(void) +{ + return (int)GetSystemMetrics(SM_CXSCREEN); +} + +int screen_get_dy(void) +{ + return (int)GetSystemMetrics(SM_CYSCREEN); +} + +int screen_get_menu_dy(void) +{ + return GetSystemMetrics(SM_CYMENU); +} + +int screen_get_caption_dy(void) +{ + return GetSystemMetrics(SM_CYCAPTION); +} + +/* given a string id 'strId' from resources, get the string in a dynamically + allocated string. + Returns the string or NULL if error. + Caller needs to free() the string. + TODO: string is limited to BUF_CCH_SIZE. Could do it better by dynamically + allocating more memory if needed */ +#define BUF_CCH_SIZE 256 +TCHAR *load_string_dup(int str_id) +{ + TCHAR buf[BUF_CCH_SIZE] = {0}; + LoadString(NULL, str_id, buf, BUF_CCH_SIZE); + if (0 == tstr_len(buf)) + { + assert(0); + return NULL; + } + return tstr_dup(buf); +} + +const TCHAR *load_string(int str_id) +{ + int res; + const TCHAR *str; + + /* little-known hack: when lpBuffer is NULL, LoadString() returns + a pointer to a string, that can be cast to TCHAR * (LPCTSTR) + requires -n option to RC (resource compiler) + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdk40/html/cerefLoadString.asp */ + res = LoadString(NULL, str_id, NULL, 0); + if (0 == res) + return NULL; + str = (const TCHAR*)res; + return str; +} + +// A helper to set a string, null-terminated 'keyValue' for a given 'keyName' +// in 'keyPath'/'keyClass' +// if 'keyName' is NULL then we set the default value for 'keyPath' +// Returns false if there was any error (can be ignored) +int regkey_set_str(HKEY key_class, TCHAR *key_path, TCHAR *key_name, TCHAR *key_value) +{ + HKEY hkey = NULL; + DWORD size = 0; + BOOL f_ok; + + if (ERROR_SUCCESS != RegCreateKeyEx(key_class, key_path, 0, NULL, 0, 0, NULL, &hkey, NULL)) + return FALSE; + + f_ok = TRUE; + size = (DWORD)(tstr_len(key_value)*sizeof(TCHAR)); + if (ERROR_SUCCESS != RegSetValueEx(hkey, key_name, 0, REG_SZ, (LPBYTE)key_value, size)) + f_ok = FALSE; + RegCloseKey(hkey); + + return f_ok; +} + +int regkey_set_dword(HKEY key_class, TCHAR *key_path, TCHAR *key_name, DWORD key_value) +{ + HKEY hkey = NULL; + DWORD size = 0; + BOOL f_ok; + + if (ERROR_SUCCESS != RegCreateKeyEx(key_class, key_path, 0, NULL, 0, 0, NULL, &hkey, NULL)) + return FALSE; + + f_ok = TRUE; + size = sizeof(DWORD); + if (ERROR_SUCCESS != RegSetValueEx(hkey, key_name, 0, REG_DWORD, (LPBYTE)&key_value, size)) + f_ok = FALSE; + RegCloseKey(hkey); + + return f_ok; +} + +static void rect_client_to_screen(RECT *r, HWND hwnd) +{ + POINT p1 = {r->left, r->top}; + POINT p2 = {r->right, r->bottom}; + ClientToScreen(hwnd, &p1); + ClientToScreen(hwnd, &p2); + r->left = p1.x; + r->top = p1.y; + r->right = p2.x; + r->bottom = p2.y; +} + +void paint_round_rect_around_hwnd(HDC hdc, HWND hwnd_edit_parent, HWND hwnd_edit, COLORREF col) +{ + RECT r; + HBRUSH br; + HBRUSH br_prev; + HPEN pen; + HPEN pen_prev; + GetClientRect(hwnd_edit, &r); + br = CreateSolidBrush(col); + if (!br) return; + pen = CreatePen(PS_SOLID, 1, col); + pen_prev = SelectObject(hdc, pen); + br_prev = SelectObject(hdc, br); + rect_client_to_screen(&r, hwnd_edit_parent); + /* TODO: the roundness value should probably be calculated from the dy of the rect */ + /* TODO: total hack: I manually adjust rectangle to values that fit g_hwnd_edit, as + found by experimentation. My mapping of coordinates isn't right (I think I need + mapping from window to window but even then it wouldn't explain -3 for y axis */ + RoundRect(hdc, r.left+4, r.top-3, r.right+12, r.bottom-3, 8, 8); + if (br_prev) + SelectObject(hdc, br_prev); + if (pen_prev) + SelectObject(hdc, pen_prev); + DeleteObject(pen); + DeleteObject(br); +} + diff --git a/rosapps/smartpdf/baseutils/win_util.h b/rosapps/smartpdf/baseutils/win_util.h new file mode 100644 index 00000000000..45d1b1e6345 --- /dev/null +++ b/rosapps/smartpdf/baseutils/win_util.h @@ -0,0 +1,128 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef WIN_UTIL_H_ +#define WIN_UTIL_H_ +#include + +/* Utilities to help in common windows programming tasks */ + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* constant to make it easier to return proper LRESULT values when handling + various windows messages */ +#define WM_KILLFOCUS_HANDLED 0 +#define WM_SETFOCUS_HANDLED 0 +#define WM_KEYDOWN_HANDLED 0 +#define WM_KEYUP_HANDLED 0 +#define WM_LBUTTONDOWN_HANDLED 0 +#define WM_LBUTTONUP_HANDLED 0 +#define WM_PAINT_HANDLED 0 +#define WM_DRAWITEM_HANDLED TRUE +#define WM_MEASUREITEM_HANDLED TRUE +#define WM_SIZE_HANDLED 0 +#define LVN_ITEMACTIVATE_HANDLED 0 +#define WM_VKEYTOITEM_HANDLED_FULLY -2 +#define WM_VKEYTOITEM_NOT_HANDLED -1 +#define WM_CREATE_OK 0 +#define WM_CREATE_FAILED -1 + +#define WIN_COL_RED RGB(255,0,0) +#define WIN_COL_WHITE RGB(255,255,255) +#define WIN_COL_BLACK RGB(0,0,0) +#define WIN_COL_BLUE RGB(0,0,255) +#define WIN_COL_GREEN RGB(0,255,0) +#define WIN_COL_GRAY RGB(215,215,215) + +int rect_dx(RECT *r); +int rect_dy(RECT *r); +void rect_set(RECT *r, int x, int y, int dx, int dy); + +void win_set_font(HWND hwnd, HFONT font); + +int win_get_text_len(HWND hwnd); +TCHAR * win_get_text(HWND hwnd); +void win_set_text(HWND hwnd, const TCHAR *txt); + +void win_edit_set_selection(HWND hwnd, DWORD selStart, DWORD selEnd); +void win_edit_select_all(HWND hwnd); + +LRESULT lv_delete_all_items(HWND hwnd); +LRESULT lv_set_items_count(HWND hwnd, int items_count); +int lv_get_items_count(HWND hwnd); +LRESULT lv_insert_column(HWND hwnd, int col, LVCOLUMN *lvc); +LRESULT lv_set_column(HWND hwnd, int col, LVCOLUMN *lvc); +LRESULT lv_set_column_dx(HWND hwnd, int col, int dx); +LRESULT lv_insert_item(HWND hwnd, int row, LVITEM *lvi); +LRESULT lv_insert_item_text(HWND hwnd, int row, const TCHAR *txt); +int lv_get_selection_pos(HWND hwnd); +LRESULT lb_delete_all_items(HWND hwnd); +#if 0 /* doesn't seem to be supported under wince */ +LRESULT lb_set_items_count(HWND hwnd, int items_count); +#endif +LRESULT lb_insert_item_text(HWND hwnd, int row, const TCHAR *txt); +LRESULT lb_append_string_no_sort(HWND hwnd, const TCHAR *txt); +LRESULT lb_get_items_count(HWND hwnd); +LRESULT lb_set_selection(HWND hwnd, int item); +LRESULT lb_get_selection(HWND hwnd); + +int font_get_dy(HWND hwnd, HFONT font); +int font_get_dy_from_dc(HDC hdc, HFONT font); + +void screen_get_dx_dy(int *dx_out, int *dy_out); +int screen_get_dx(void); +int screen_get_dy(void); +int screen_get_menu_dy(void); +int screen_get_caption_dy(void); + +#ifdef _WIN32_WCE +void sip_completion_disable(void); +void sip_completion_enable(void); +#endif + +void launch_url(const TCHAR *url); + +TCHAR * get_app_data_folder_path(BOOL f_create); + +TCHAR * load_string_dup(int str_id); +const TCHAR *load_string(int str_id); + +int regkey_set_dword(HKEY key_class, TCHAR *key_path, TCHAR *key_name, DWORD key_value); +int regkey_set_str(HKEY key_class, TCHAR *key_path, TCHAR *key_name, TCHAR *key_value); + +void paint_round_rect_around_hwnd(HDC hdc, HWND hwnd_edit_parent, HWND hwnd_edit, COLORREF col); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +class AppBarData { +public: + AppBarData() { + m_abd.cbSize = sizeof(m_abd); + /* default values for the case of SHAppBarMessage() failing + (shouldn't really happen) */ + RECT rc = {0, 0, 0, 0}; + m_abd.rc = rc; + m_abd.uEdge = ABE_TOP; + SHAppBarMessage(ABM_GETTASKBARPOS, &m_abd); + } + int dx() { return rect_dx(&m_abd.rc); } + int dy() { return rect_dy(&m_abd.rc); } + int x() { return m_abd.rc.left; } + int y() { return m_abd.rc.top; } + bool atTop() { return ABE_TOP == m_abd.uEdge; } + bool atBottom() { return ABE_BOTTOM == m_abd.uEdge; } + bool atLeft() { return ABE_LEFT == m_abd.uEdge; } + bool atRight() { return ABE_RIGHT == m_abd.uEdge; } + bool isHorizontal() { return atLeft() || atRight(); } + bool isVertical() { return atBottom() || atTop(); } +private: + APPBARDATA m_abd; +}; +#endif + +#endif diff --git a/rosapps/smartpdf/baseutils/wstr_util.c b/rosapps/smartpdf/baseutils/wstr_util.c new file mode 100644 index 00000000000..c030a3e4eb5 --- /dev/null +++ b/rosapps/smartpdf/baseutils/wstr_util.c @@ -0,0 +1,285 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ + +/* The most basic things, including string handling functions */ + +#include "base_util.h" +#include "wstr_util.h" + +#include + +WCHAR *wstr_cat4(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3, const WCHAR *str4) +{ + WCHAR *str; + WCHAR *tmp; + size_t str1_len = 0; + size_t str2_len = 0; + size_t str3_len = 0; + size_t str4_len = 0; + + if (str1) + str1_len = wstrlen(str1); + if (str2) + str2_len = wstrlen(str2); + if (str3) + str3_len = wstrlen(str3); + if (str4) + str4_len = wstrlen(str4); + + str = (WCHAR*)zmalloc((str1_len + str2_len + str3_len + str4_len + 1)*sizeof(WCHAR)); + if (!str) + return NULL; + + tmp = str; + if (str1) { + memcpy(tmp, str1, str1_len*sizeof(WCHAR)); + tmp += str1_len; + } + if (str2) { + memcpy(tmp, str2, str2_len*sizeof(WCHAR)); + tmp += str2_len; + } + if (str3) { + memcpy(tmp, str3, str3_len*sizeof(WCHAR)); + tmp += str3_len; + } + if (str4) { + memcpy(tmp, str4, str1_len*sizeof(WCHAR)); + } + return str; +} + +WCHAR *wstr_cat3(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3) +{ + return wstr_cat4(str1, str2, str3, NULL); +} + +WCHAR *wstr_cat(const WCHAR *str1, const WCHAR *str2) +{ + return wstr_cat4(str1, str2, NULL, NULL); +} + +WCHAR *wstr_dupn(const WCHAR *str, int str_len_cch) +{ + WCHAR *copy; + + if (!str) + return NULL; + copy = (WCHAR*)malloc((str_len_cch+1)*sizeof(WCHAR)); + if (!copy) + return NULL; + memcpy(copy, str, str_len_cch*sizeof(WCHAR)); + copy[str_len_cch] = 0; + return copy; +} + +WCHAR *wstr_dup(const WCHAR *str) +{ + return wstr_cat4(str, NULL, NULL, NULL); +} + +int wstr_copyn(WCHAR *dst, int dst_cch_size, const WCHAR *src, int src_cch_size) +{ + WCHAR *end = dst + dst_cch_size - 1; + if (0 == dst_cch_size) { + if (0 == src_cch_size) + return TRUE; + else + return FALSE; + } + + while ((dst < end) && (src_cch_size > 0)) { + *dst++ = *src++; + --src_cch_size; + } + *dst = 0; + if (0 == src_cch_size) + return TRUE; + else + return FALSE; +} + +int wstr_copy(WCHAR *dst, int dst_cch_size, const WCHAR *src) +{ + WCHAR *end = dst + dst_cch_size - 1; + if (0 == dst_cch_size) + return FALSE; + + while ((dst < end) && *src) { + *dst++ = *src++; + } + *dst = 0; + if (0 == *src) + return TRUE; + else + return FALSE; +} + +int wstr_ieq(const WCHAR *str1, const WCHAR *str2) +{ + if (!str1 && !str2) + return TRUE; + if (!str1 || !str2) + return FALSE; + if (0 == _wcsicmp(str1, str2)) + return TRUE; + return FALSE; +} + +/* return true if 'str' starts with 'txt', case-sensitive */ +int wstr_startswith(const WCHAR *str, const WCHAR *txt) +{ + if (!str && !txt) + return TRUE; + if (!str || !txt) + return FALSE; + + if (0 == wcsncmp(str, txt, wcslen(txt))) + return TRUE; + return FALSE; +} + +/* return true if 'str' starts with 'txt', NOT case-sensitive */ +int wstr_startswithi(const WCHAR *str, const WCHAR *txt) +{ + if (!str && !txt) + return TRUE; + if (!str || !txt) + return FALSE; + + if (0 == _wcsnicmp(str, txt, wcslen(txt))) + return TRUE; + return FALSE; +} + +int wstr_empty(const WCHAR *str) +{ + if (!str) + return TRUE; + if (0 == *str) + return TRUE; + return FALSE; +} + +static void wchar_to_hex(WCHAR c, WCHAR* buffer) +{ + const WCHAR* numbers = L"0123456789ABCDEF"; + buffer[0]=numbers[c / 16]; + buffer[1]=numbers[c % 16]; +} + +int wstr_contains(const WCHAR *str, WCHAR c) +{ + while (*str) { + if (c == *str++) + return TRUE; + } + return FALSE; +} + +#define WCHAR_URL_DONT_ENCODE L"-_.!~*'()" + +int wchar_needs_url_encode(WCHAR c) +{ + if ((c >= L'a') && (c <= L'z')) + return FALSE; + if ((c >= L'A') && (c <= L'Z')) + return FALSE; + if ((c >= L'0') && (c <= L'9')) + return FALSE; + if (wstr_contains(WCHAR_URL_DONT_ENCODE, c)) + return FALSE; + return TRUE; +} + +WCHAR *wstr_url_encode(const WCHAR *str) +{ + WCHAR * encoded; + WCHAR * result; + int res_len = 0; + const WCHAR * tmp = str; + + while (*tmp) { + if (wchar_needs_url_encode(*tmp)) + res_len += 3; + else + ++res_len; + tmp++; + } + if (0 == res_len) + return NULL; + + encoded = (WCHAR*)malloc((res_len+1)*sizeof(WCHAR)); + if (!encoded) + return NULL; + + result = encoded; + tmp = str; + while (*tmp) { + if (wchar_needs_url_encode(*tmp)) { + *encoded++ = L'%'; + wchar_to_hex(*tmp, encoded); + encoded += 2; + } else { + if (L' ' == *tmp) + *encoded++ = L'+'; + else + *encoded++ = *tmp; + } + tmp++; + } + *encoded = 0; + return result; +} + +WCHAR *wstr_printf(const WCHAR *format, ...) +{ + HRESULT hr; + va_list args; + WCHAR message[256]; + WCHAR * buf; + size_t bufCchSize; + + buf = &(message[0]); + bufCchSize = sizeof(message)/sizeof(message[0]); + + va_start(args, format); + for (;;) + { + hr = StringCchVPrintfW(buf, bufCchSize, format, args); + if (S_OK == hr) + break; + if (STRSAFE_E_INSUFFICIENT_BUFFER != hr) + { + /* any error other than buffer not big enough: + a) should not happen + b) means we give up */ + assert(FALSE); + goto Error; + } + /* we have to make the buffer bigger. The algorithm used to calculate + the new size is arbitrary (aka. educated guess) */ + if (buf != &(message[0])) + free(buf); + if (bufCchSize < 4*1024) + bufCchSize += bufCchSize; + else + bufCchSize += 1024; + buf = (WCHAR *)malloc(bufCchSize*sizeof(WCHAR)); + if (NULL == buf) + goto Error; + } + va_end(args); + + /* free the buffer if it was dynamically allocated */ + if (buf == &(message[0])) + return wstr_dup(buf); + + return buf; +Error: + if (buf != &(message[0])) + free((void*)buf); + + return NULL; +} + diff --git a/rosapps/smartpdf/baseutils/wstr_util.h b/rosapps/smartpdf/baseutils/wstr_util.h new file mode 100644 index 00000000000..1f251634cad --- /dev/null +++ b/rosapps/smartpdf/baseutils/wstr_util.h @@ -0,0 +1,35 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + The author disclaims copyright to this source code. */ +#ifndef WSTR_UTIL_H_ +#define WSTR_UTIL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define wstrlen wcslen +int wstr_ieq(const WCHAR *str1, const WCHAR *str2); +int wstr_startswith(const WCHAR *str, const WCHAR *txt); +int wstr_startswithi(const WCHAR *str, const WCHAR *txt); +int wstr_empty(const WCHAR *str); +int wstr_copy(WCHAR *dst, int dst_cch_size, const WCHAR *src); +int wstr_copyn(WCHAR *dst, int dst_cch_size, const WCHAR *src, int src_cch_size); +WCHAR * wstr_dup(const WCHAR *str); +WCHAR * wstr_dupn(const WCHAR *str, int str_len_cch); +WCHAR * wstr_cat(const WCHAR *str1, const WCHAR *str2); +WCHAR * wstr_cat3(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3); +WCHAR * wstr_cat4(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3, const WCHAR *str4); +WCHAR * wstr_url_encode(const WCHAR *str); +WCHAR wchar_needs_url_escape(WCHAR c); +int wstr_contains(const WCHAR *str, WCHAR c); +WCHAR * wstr_printf(const WCHAR *format, ...); + +#ifdef DEBUG +void wstr_util_test(void); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/rosapps/smartpdf/fitz.rbuild b/rosapps/smartpdf/fitz.rbuild new file mode 100644 index 00000000000..23ee80dbe9b --- /dev/null +++ b/rosapps/smartpdf/fitz.rbuild @@ -0,0 +1,167 @@ + + ntdll + kernel32 + libjpeg + zlib + freetype + + + + + + + + + + 1 + 1 + 1 + + + + . + . + include + . + baseutils + fitz + fitz/fonts + fitz/include + fitz/include/fitz + fitz/include/mupdf + fitz/include/samus + fitz/base + fitz/stream + fitz/raster + fitz/world + fitz/mupdf + + + Dingbats.cff.c + NimbusMonL-Bold.cff.c + NimbusMonL-BoldObli.cff.c + NimbusMonL-Regu.cff.c + NimbusMonL-ReguObli.cff.c + NimbusRomNo9L-Medi.cff.c + NimbusRomNo9L-MediItal.cff.c + NimbusRomNo9L-Regu.cff.c + NimbusRomNo9L-ReguItal.cff.c + NimbusSanL-Bold.cff.c + NimbusSanL-BoldItal.cff.c + NimbusSanL-Regu.cff.c + NimbusSanL-ReguItal.cff.c + StandardSymL.cff.c + URWChanceryL-MediItal.cff.c + + + base_cpudep.c + base_error.c + base_hash.c + base_matrix.c + base_memory.c + base_rect.c + base_rune.c + util_getopt.c + util_strlcat.c + util_strlcpy.c + util_strsep.c + + + crypt_arc4.c + crypt_crc32.c + crypt_md5.c + filt_a85d.c + filt_a85e.c + filt_ahxd.c + filt_ahxe.c + filt_arc4.c + filt_dctd.c + filt_dcte.c + filt_faxd.c + filt_faxdtab.c + filt_faxe.c + filt_faxetab.c + filt_flate.c + filt_lzwd.c + filt_lzwe.c + filt_null.c + filt_pipeline.c + filt_predict.c + filt_rld.c + filt_rle.c + obj_array.c + obj_dict.c + obj_parse.c + obj_print.c + obj_simple.c + stm_buffer.c + stm_filter.c + stm_misc.c + stm_open.c + stm_read.c + stm_write.c + + + glyphcache.c + imagedraw.c + imagescale.c + imageunpack.c + meshdraw.c + pathfill.c + pathscan.c + pathstroke.c + pixmap.c + porterduff.c + render.c + + + node_misc1.c + node_misc2.c + node_optimize.c + node_path.c + node_text.c + node_tree.c + res_colorspace.c + res_font.c + res_image.c + res_shade.c + + + pdf_annot.c + pdf_build.c + pdf_cmap.c + pdf_colorspace1.c + pdf_colorspace2.c + pdf_crypt.c + pdf_debug.c + pdf_doctor.c + pdf_font.c + pdf_fontagl.c + pdf_fontenc.c + pdf_fontfile.c + pdf_function.c + pdf_image.c + pdf_interpret.c + pdf_lex.c + pdf_nametree.c + pdf_open.c + pdf_outline.c + pdf_page.c + pdf_pagetree.c + pdf_parse.c + pdf_pattern.c + pdf_repair.c + pdf_resources.c + pdf_save.c + pdf_shade.c + pdf_shade1.c + pdf_shade4.c + pdf_store.c + pdf_stream.c + pdf_type3.c + pdf_unicode.c + pdf_xobject.c + pdf_xref.c + + + diff --git a/rosapps/smartpdf/fitz/COPYING b/rosapps/smartpdf/fitz/COPYING new file mode 100644 index 00000000000..d511905c164 --- /dev/null +++ b/rosapps/smartpdf/fitz/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/rosapps/smartpdf/fitz/DESIGN b/rosapps/smartpdf/fitz/DESIGN new file mode 100644 index 00000000000..4a1d87380bd --- /dev/null +++ b/rosapps/smartpdf/fitz/DESIGN @@ -0,0 +1,199 @@ +In implementing the Metro parser on top of Fitz, and with the new +road map, I am facing the task of designing the API for managing +resources in Fitz. Up till now I have punted on making any final +decisions, exploring as I go. Now I feel that I cannot do so much longer. +Therefore I would like to hear your opinions and ideas on this. +Please brainstorm and point out any missing pieces. + +First, a ten mile high overview of the Fitz architecture and +nomenclature, for those of you who are not in the loop or need +a refresher :) + +The Fitz world is a set of resources. There are many kinds of resources. +Resources can depend on other resources, but no circular dependencies. +The resource types are: tree, font, image, shade, and colorspace. +A document is a sequence of tree resources that define the contents +of its pages. + +A front-end is a producer of Fitz worlds, that reads a file and +creates a Fitz world from its contents. Abstracting this into +a high-level interface is useful primarily for viewers and +converters. + +A back-end is a consumer of Fitz worlds. The default rasterizer +is one back-end. PDF writers and other output drivers too. +I don't think there should be a special interface for these. +They are just functions or programs that take the Fitz world +and do something unspecified with it. + +The resource API is what I need help fleshing out. Keep in mind +that a Fitz world should be able to be serialized to disk, so having +callbacks and other hooks into the front-end is a no no. If it weren't +for this, my life would be a lot simpler :) + +Both creation, querying, and on-disk format. + +-------------------------------------------------------------------- + +TREE + +The Fitz tree resource is the primary data structure. +A tree consists of nodes. There are leaf nodes and branch +nodes. Leaf nodes produce images, branch nodes combine +or change images. An image here is a two-dimensional +region of color and shape (alpha). + +LEAF NODES + +SOLID. +A constant color or shape that stretches out to infinity. + +IMAGE. +A rectangular region of color and or shape derived +a from a grid of samples. +Outside this rectangle is transparent. +References an image resource. + +SHADE. +A mesh of patches that define a region of interpolated colors. +Outside the mesh is transparent. +References a shade resource. + +PATH. +A path defines only shape. +Moveto, lineto, curveto and closepath. +Stroke, fill, even-odd-fill. +Dash patterns. + +TEXT. +A text node is an optimization, space-effectively combining +a transform matrix and references to glyph shapes. +Text nodes define only shape. + +Text nodes have a b c d coefficients and a reference to a font. +Then an array of glyph index and e and f coefficient tuples. + +Text nodes may also have a separate unicode array, +associating the (glyph,e,f) tuples with unicode character codes. +One-to-many and many-to-one mappings are allowed. +For text search and copy. + +BRANCH NODES + +TRANSFORM. +Transform nodes apply an affine transform matrix to +its one and only child. + +OVER. +An over node stacks its children on top of each other, +combining their colors with a blending mode. + +MASK. +A mask node has two children. The second child is masked +with the first child, multiplying their shapes. +This causes the effect of clipping. + +(mask + (path ...) + (solid 'devicegray 0)) + +BLEND. +This does the magic of PDF 1.4 transparency. +The isolated and non-isolated and +knockout group stuff happens here. +It also sets the blend mode for its children. + +LINK. +This is a dummy node that grafts in another +tree resource. The effect is as if the other +tree was copied here instead. +References a tree resource. + +META. +A way to insert application specific data. +Transparent to the rasterizer, but can be +useful to preserve some non-Fitz semantics +that may be of use to specific producers/consumers +of Fitz trees. For example, tiling patterns +would be represented as an over node with +many transform and link nodes stamping out +the pattern to fill the page. Putting these +under an appropriate Meta node would allow +a PDF or Postscript backend to detect and +recreate the tiling pattern. + +(meta 'pattern "...tiling pattern info..." + (over + (transform 1 0 0 1 0 0 (link 'pat1)) + (transform 1 0 0 1 0 1 (link 'pat1)) + (transform 1 0 0 1 1 0 (link 'pat1)) + (transform 1 0 0 1 1 1 (link 'pat1)))) + +-------------------------------------------------------------------- + +COLORSPACES. + +A colorspace needs the capability to transform colors into +and out of any other colorspace. I suggest that this happens +by going either through a standard colorspace (CIE XYZ), +or by having an optional A-to-B shortcut transform. + +I am thinking of three sub-classes: + + Device colors. Fast and dirty: Gray, RGB, CMYK only. + + ICC Profiles. I am not very familiar with this. + Use Argyll? Are they easy to create programmatically + to represent the Cal* and L*a*b colorspaces? + + Separation. For Separation and DeviceN. + This is a list of named colors, with backend + specific tailoring required to make sense of it. Also has + an alternate colorspace (Device or ICC) with a transform. + How do we represent the transform function? + +SHADES. + +This is fairly simple. A mesh of patches as in PDF. +Three levels of detail: with full tensors, with only patches, +with linear quads. Axial and radial shadings are trivially +converted. Type 1 (functional) shadings need to be sampled. + +If the backends cannot cope, it can either convert to +linear shaded triangles (clip an axial shading with a triangular +path) or render to an image. + +FONTS. + +There need to be four types of font resources. +For now I am going to use FreeType, but that should not be a necessity. +The resource format for fonts should be independent. + + * Fake fonts for substituted fonts. Refer to another fall-back + font resource and override the metrics. + Could possibly be represented as a type 3 font, + but knowing that it is a substitute may be useful. + + * Type 3 fonts where each glyph is represented as a Fitz tree resource. + + * Postscript fonts, in CFF format. + Type 1 and Type 1 CID fonts are losslessly convertible to CFF. + OpenType fonts can have CFF glyph data. + + * TrueType fonts + +IMAGES. + +This is the tricky one. Raph, I forgot what we decided on the tiling. +What size, planar or chunky, etc. Which bit depths do we allow? +Image data should be chopped into tiles to allow for independent +and random access and more CPU-cache friendly image scaling and +color transforms. + + * JPEG encoded images. + Save byte+bit offsets to allow random access to groups of eight scanlines. + * Monochrome images. + * Contone images. + +The End + diff --git a/rosapps/smartpdf/fitz/Makefile.vc b/rosapps/smartpdf/fitz/Makefile.vc new file mode 100644 index 00000000000..677ce0b6abe --- /dev/null +++ b/rosapps/smartpdf/fitz/Makefile.vc @@ -0,0 +1,257 @@ +NULL= +BASEDIR=. +BINDIR=bin + +!if "$(DEBUG)"=="1" +OBJDIR=obj-dbg +!else +OBJDIR=obj-rel +!endif + +MUPDF=mupdf +FREETYPE_INC=$(BASEDIR)\windev\freetype_2_1_10\include +FREETYPE_LIB=$(BASEDIR)\windev\freetype_2_1_10 +ZLIB_INC=$(BASEDIR)\windev\zlib +ZLIB_LIB=$(BASEDIR)\windev\zlib +JPEG_INC=$(BASEDIR)\windev\jpeg +JPEG_LIB=$(BASEDIR)\windev\jpeg + +#DEBUG = 1 + +# +# Define compiler flags +# +CC = cl.exe +CFLAGS = $(CFLAGS) /nologo +CFLAGS = $(CFLAGS) /wd4996 +CFLAGS = $(CFLAGS) /D "WIN32" /D "_WINDOWS" /D "_WIN32" +CFLAGS = $(CFLAGS) /D "_WIN32_WINNT=0x4000" +CFLAGS = $(CFLAGS) /D "NEED_MATH" +CFLAGS = $(CFLAGS) /D "_MBCS" /D "_REENTRANT" /W1 /GR- +CFLAGS = $(CFLAGS) /I$(BASEDIR)\include +CFLAGS = $(CFLAGS) /I$(BASEDIR)\include\fitz +CFLAGS = $(CFLAGS) /I$(BASEDIR)\include\mupdf +CFLAGS = $(CFLAGS) /I$(BASEDIR)\include\samus +CFLAGS = $(CFLAGS) /I$(FREETYPE_INC) +CFLAGS = $(CFLAGS) /I$(ZLIB_INC) +CFLAGS = $(CFLAGS) /I$(JPEG_INC) + +# CFLAGS = /Ios-win32 /Fo$(OBJDIR) + +!if "$(DEBUG)"=="1" +CFLAGS = $(CFLAGS) /D "_DEBUG" /MTd /Od /Zi +!else +CFLAGS = $(CFLAGS) /D "NDEBUG" /MT /Zi /O2 /GL /Oi /Ot /Oy /GF +!endif + +# +# Define linker flags +# +LD = link.exe +LDFLAGS = $(LDFLAGS) /nologo +LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR) +LDFLAGS = $(LDFLAGS) /LIBPATH:$(FREETYPE_LIB) +LDFLAGS = $(LDFLAGS) /LIBPATH:$(ZLIB_LIB) +LDFLAGS = $(LDFLAGS) /LIBPATH:$(JPEG_LIB) +LDFLAGS = $(LDFLAGS) /SUBSYSTEM:WINDOWS + +LIBS = $(LIBS) gdi32.lib comdlg32.lib advapi32.lib user32.lib shell32.lib kernel32.lib + +!if "$(DEBUG)"=="1" +LIBS = $(LIBS) zlib_ds.lib freetype2110MT_D.lib jpeg_ds.lib +LDFLAGS = $(LDFLAGS) /DEBUG +!else +LDFLAGS = $(LDFLAGS) /OPT:NOWIN98 /LTCG /DEBUG +LIBS = $(LIBS) zlib_s.lib freetype2110MT.lib jpeg_s.lib +!endif + +# +# Archiver flags +# +AR = lib.exe +ARFLAGS = $(ARFLAGS) /nologo + +# +# mupdf.dll +# +MUPDF_DLL_OBJS= \ +# this is stream + $(OBJDIR)\crypt_arc4.obj \ + $(OBJDIR)\crypt_md5.obj \ + $(OBJDIR)\filt_a85d.obj \ + $(OBJDIR)\filt_ahxd.obj \ + $(OBJDIR)\filt_arc4.obj \ + $(OBJDIR)\filt_dctd.obj \ + $(OBJDIR)\filt_faxd.obj \ + $(OBJDIR)\filt_faxdtab.obj \ + $(OBJDIR)\filt_faxe.obj \ + $(OBJDIR)\filt_faxetab.obj \ + $(OBJDIR)\filt_flate.obj \ + $(OBJDIR)\filt_lzwd.obj \ + $(OBJDIR)\filt_null.obj \ + $(OBJDIR)\filt_pipeline.obj \ + $(OBJDIR)\filt_predict.obj \ + $(OBJDIR)\filt_rld.obj \ + $(OBJDIR)\obj_array.obj \ + $(OBJDIR)\obj_dict.obj \ + $(OBJDIR)\obj_parse.obj \ + $(OBJDIR)\obj_print.obj \ + $(OBJDIR)\obj_simple.obj \ + $(OBJDIR)\stm_filter.obj \ + $(OBJDIR)\stm_buffer.obj \ + $(OBJDIR)\stm_open.obj \ + $(OBJDIR)\stm_misc.obj \ + $(OBJDIR)\stm_read.obj \ + $(OBJDIR)\stm_write.obj \ +# this is for base + $(OBJDIR)\base_cpudep.obj \ + $(OBJDIR)\base_error.obj \ + $(OBJDIR)\base_hash.obj \ + $(OBJDIR)\base_matrix.obj \ + $(OBJDIR)\base_memory.obj \ + $(OBJDIR)\base_rect.obj \ + $(OBJDIR)\base_rune.obj \ + $(OBJDIR)\util_getopt.obj \ + $(OBJDIR)\util_strlcat.obj \ + $(OBJDIR)\util_strlcpy.obj \ + $(OBJDIR)\util_strsep.obj \ +# this is for world + $(OBJDIR)\node_misc1.obj \ + $(OBJDIR)\node_misc2.obj \ + $(OBJDIR)\node_optimize.obj \ + $(OBJDIR)\node_path.obj \ + $(OBJDIR)\node_text.obj \ + $(OBJDIR)\node_tree.obj \ + $(OBJDIR)\res_colorspace.obj \ + $(OBJDIR)\res_font.obj \ + $(OBJDIR)\res_image.obj \ + $(OBJDIR)\res_shade.obj \ +# this is for raster + $(OBJDIR)\glyphcache.obj \ + $(OBJDIR)\imagedraw.obj \ + $(OBJDIR)\imagescale.obj \ + $(OBJDIR)\imageunpack.obj \ + $(OBJDIR)\meshdraw.obj \ + $(OBJDIR)\pathfill.obj \ + $(OBJDIR)\pathscan.obj \ + $(OBJDIR)\pathstroke.obj \ + $(OBJDIR)\pixmap.obj \ + $(OBJDIR)\porterduff.obj \ + $(OBJDIR)\render.obj \ +# this is for draw +# $(OBJDIR)\draw_misc.obj \ +# this mupdf + $(OBJDIR)\pdf_annot.obj \ + $(OBJDIR)\pdf_build.obj \ + $(OBJDIR)\pdf_cmap.obj \ + $(OBJDIR)\pdf_colorspace1.obj \ + $(OBJDIR)\pdf_colorspace2.obj \ + $(OBJDIR)\pdf_crypt.obj \ + $(OBJDIR)\pdf_debug.obj \ + $(OBJDIR)\pdf_doctor.obj \ + $(OBJDIR)\pdf_font.obj \ + $(OBJDIR)\pdf_fontagl.obj \ + $(OBJDIR)\pdf_fontenc.obj \ +# $(OBJDIR)\pdf_fontfile.obj \ +# $(OBJDIR)\pdf_fontfilefc.obj \ + $(OBJDIR)\pdf_fontfilems.obj \ + $(OBJDIR)\pdf_function.obj \ + $(OBJDIR)\pdf_image.obj \ + $(OBJDIR)\pdf_interpret.obj \ + $(OBJDIR)\pdf_lex.obj \ + $(OBJDIR)\pdf_nametree.obj \ + $(OBJDIR)\pdf_open.obj \ + $(OBJDIR)\pdf_outline.obj \ + $(OBJDIR)\pdf_page.obj \ + $(OBJDIR)\pdf_pagetree.obj \ + $(OBJDIR)\pdf_parse.obj \ + $(OBJDIR)\pdf_pattern.obj \ + $(OBJDIR)\pdf_repair.obj \ + $(OBJDIR)\pdf_resources.obj \ + $(OBJDIR)\pdf_save.obj \ + $(OBJDIR)\pdf_shade.obj \ + $(OBJDIR)\pdf_shade1.obj \ + $(OBJDIR)\pdf_shade4.obj \ + $(OBJDIR)\pdf_store.obj \ + $(OBJDIR)\pdf_stream.obj \ + $(OBJDIR)\pdf_type3.obj \ + $(OBJDIR)\pdf_unicode.obj \ + $(OBJDIR)\pdf_xobject.obj \ + $(OBJDIR)\pdf_xref.obj \ + $(NULL) + +MUPDF_EXE_OBJS= \ + $(MUPDF_DLL_OBJS) \ + $(OBJDIR)\pdfapp.obj \ + $(OBJDIR)\winmain.obj \ + $(NULL) + +MUPDF_DLL_NAME=mupdf.dll +MUPDF_DLL_LIB_NAME=mupdf.lib + +!if "$(DEBUG)"=="1" +MUPDF_EXE_NAME=mupdf-dbg.exe +MUPDF_PDB_NAME=mupdf-dbg.pdb +!else +MUPDF_EXE_NAME=mupdf.exe +MUPDF_PDB_NAME=mupdf.pdb +!endif + +all: $(BINDIR)\$(MUPDF_EXE_NAME) + +clean: + if exist $(BINDIR) rmdir /S /Q $(BINDIR) + if exist $(OBJDIR) rmdir /S /Q $(OBJDIR) + +$(OBJDIR): + if not exist $(OBJDIR) mkdir $(OBJDIR) + +$(BINDIR): + if not exist $(BINDIR) mkdir $(BINDIR) + +# +# mupdf.dll +# +$(BINDIR)\$(MUPDF_DLL_NAME) : $(BINDIR) $(MUPDF_DLL_OBJS) + $(LD) $(LDFLAGS) /DLL \ + /IMPLIB:$(BINDIR)\$(MUPDF_DLL_LIB_NAME) \ + /OUT:$(BINDIR)\$(MUPDF_DLL_NAME) \ + $(MUPDF_DLL_OBJS) $(LIBS) + +$(OBJDIR)\winres.RES: + rc.exe /n /fo$(OBJDIR)\winres.RES apps\windows\winres.rc + +$(BINDIR)\$(MUPDF_EXE_NAME) : $(BINDIR) $(MUPDF_EXE_OBJS) $(OBJDIR)\winres.RES + $(LD) $(LDFLAGS) \ + /OUT:$(BINDIR)\$(MUPDF_EXE_NAME) \ + /PDB:$(BINDIR)\$(MUPDF_PDB_NAME) \ + $(MUPDF_EXE_OBJS) $(OBJDIR)\winres.RES $(LIBS) + +$(MUPDF_DLL_OBJS) : $(OBJDIR) + +#{$(BASEDIR)\mupdf}.cpp{$(OBJDIR)}.obj:: +# $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\draw}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\mupdf}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\stream}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\base}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\world}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\raster}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\apps\common}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< + +{$(BASEDIR)\apps\windows}.c{$(OBJDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $< diff --git a/rosapps/smartpdf/fitz/README b/rosapps/smartpdf/fitz/README new file mode 100644 index 00000000000..3fe47f14e34 --- /dev/null +++ b/rosapps/smartpdf/fitz/README @@ -0,0 +1,85 @@ +README for the Fitz distribution. + +Fitz is a graphics library. +MuPDF is a PDF parsing and manipulation library. +Samus is a Metro parser. +FzView is a PDF and Metro viewer application. +For Windows, there is also a Mozilla plugin version of the viewer. + +The Viewer has three ports: X11, Windows and Carbon. +The Carbon port is rotting, so don't bother trying it. + +This code is under the same licensing scheme as Ghostscript. +AFPL and one year or major release later GPL. +Because there have been no major releases yet; AFPL it is. + +PREREQUISITES + +Before compiling Fitz you need to install thirdy party dependencies. + + zlib + libjpeg + libpng + freetype2 + expat + +There are a few optional dependencies that you don't strictly need. +You will probably want the versions that Ghostscript maintains. + + jbig2dec + jasper + +Fitz uses the Perforce Jam build tool. You need the Perforce version 2.5 +or later. Earlier versions (including the FTJam fork) have crippling bugs. +Boost Jam is not backwards compatible. If you do not have a compiled +binary for your system, you can find the Jam homepage here: + + http://www.perforce.com/jam/jam.html + +The build also uses 'xxd', a hexdump tool that ships with Vim. +Here's a copy of the source if it's not on your system: + + http://ghostscript.com/~tor/download/xxd.c + +I use Mingw and MSYS to compile for Windows. If you use anything +else, you are on your own. + +COMPILING + +If all of that is installed, compiling should be a cinch. +Issue the command 'jam' in the root of the Fitz directory. +Add a parameter '-sBUILD=release' or '-sBUILD=profile' to +build release or profile versions. + + $ jam '-sBUILD=release' + +If the build fails because it cannot find header files or libraries, +look first in Jamrules to see if there is anything wrong with the +search paths or compiler flags for your system. + +To compile in the optional jbig2 and jpeg2000 support, you need +to add the following arguments to jam: + + $ jam '-sHAVE_JBIG2DEC=yes' '-sHAVE_JASPER=yes' + +To build the X11 version under MacOS X, add: + + $ jam '-sHAVE_X11=yes' + +INSTALLING + +There is no install. The command "jam install" will copy the +compiled binaries (for the specified build -- debug, release or profile) +into a "dist/" directory. + +There is no support for building a shared library. + +REPORTING BUGS AND PROBLEMS + +Send reports to tor@ghostscript.com. + +If you are reporting a problem with PDF parsing, +please include the problematic file as an attachment. + +-- tor + diff --git a/rosapps/smartpdf/fitz/TODO b/rosapps/smartpdf/fitz/TODO new file mode 100644 index 00000000000..78d579eb79f --- /dev/null +++ b/rosapps/smartpdf/fitz/TODO @@ -0,0 +1,177 @@ +heh. bug in pdfselect on compressed object streams. gc takes forever, no objects remain... + +lazy nametree +lazy pagetree + +builtin standard cmap files (?) +put unicode strings in text object, not font (a la metro) + +xml parser +unicode normaliser + +path stroke/dash/flatten work on real path struct +turn into gel as second step after stroke/flatten +add intersector for metro union/xor/difference stuff + +image rescale to exact size instead of by integer quantas + +public / private api + +fix the shading code: + 3 levels of detail patch mesh (quad, patch, tensor) + subdivide to triangles on the fly + draw tris as before + reuse more code in the parsing + error cleanup + +--- WORLD --- + +the fitz world is: + the set of resources: + trees, fonts, images, shades, colorspaces + the list of pages: + references to tree resources + opaque / transparent / invisible ? + +input device drivers create a fitz world from a document + readps -- use ghostscript + readpdf -- use mupdf + readmetro -- use samus + + the mapping from file -> pages and resources + internal to the driver, nothing fitz cares or knows about + should be lazy -- loaded on an as-needed basis + should be reference counted -- can free and reload resources + + minimal api (that works for *all* input drivers) + open(file) + close() + nextpage() + + extended api (that may or may not work optimally) + countpages() + loadpage(number) + +output drivers take a fitz world and produce whatever + raster + writeps + writepdf + writemetro + +--- WORLD API --- + +Fitz World APIs + +Trees: + fz_tree + + fz_node with subclasses + + leafs: + fz_solidnode + fz_imagenode + fz_shadenode + fz_pathnode + fz_textnode + + branches: + fz_transformnode + fz_overnode + fz_masknode + fz_blendnode # for pdf 1.4 and pcl rops + fz_linknode + fz_metanode + + construction api + navigation api + +Colorspaces: + fz_colorspace + fz_devicecolor (gray, rgb, cmyk) + fz_iccprofile (icc profile colorspace) + fz_separation (how do we do alternate tint functions?) + +Images: + fz_image + fz_jpegimage # jpeg-compressed + fz_tileimage # 1,8,16 bit image chopped into tiles + + ...or... + fz_monoimage # 1-bit image + fz_byteimage # 8-bit image + fz_wordimage # 16-bit image + +Shades: + fz_shade + mesh of quads, patches, tensors + +Fonts: + fz_font + fz_fakefont # substitute fonts + fz_t3font # sub-trees define glyphs + fz_psfont # cff postscript font + fz_ttfont # truetype font + + +--- OLD --- + +immediate plan: + + * clean up and 'freeze' public api + + * get font bbox from fontdescriptor if available + * refactor image loading + * refactor xref loading/repair + * restructure build.c and interpret.c (ftb vs csi) + * fix the colorspace/pattern/shading material mess + * font loading: + - configuration... where to find system files (asian font archive?) + - system fontfile + cmap store + - embedded fontfile store + - split type3 and ftfont malloc (dont waste t3 charprocs on ft fonts) + - make ftfontfile separate struct w/ refcounting + - refactor font loading more. simple/cid/type3 have too much in common. + + * structure low/high level stuff + - rewrite outline parser + - implement comments + + * clean high-level api + + - go through spec and check all features! + - altivec optimize + +transparency (v2) + - everything! + +colorspace conversions (v2) + - fast color cubes + - proper colorspace conversions + - gamut compression + - extended render intents + +image rendering (v2) + - tiles + - dct case + - better filter than box + - lazy decoding + +rendering + - fix glyphcache evictlast + - bbox culling per glyph + - render cache (link-nodes and scaled images and colorspaced shades) + +fz_optimizetree() + - error & memory + - concatenate chained transforms + - remove identity transforms + +for filters: + validate ahxd pushback + go through eof responsibility + be more defensive of api user errors + jbig2 rewrite + dctencode params + dctdecode app marker + jpxd rewrite (or do special trick to load into image directly) + diff --git a/rosapps/smartpdf/fitz/apps/common/pdfapp.c b/rosapps/smartpdf/fitz/apps/common/pdfapp.c new file mode 100644 index 00000000000..70a83b2927c --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/common/pdfapp.c @@ -0,0 +1,685 @@ +#include +#include +#include "pdfapp.h" + +void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage); + +void pdfapp_warn(pdfapp_t *app, const char *fmt, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + winwarn(app, buf); +} + +void pdfapp_error(pdfapp_t *app, fz_error *error) +{ + winerror(app, error->msg); +} + +char *pdfapp_usage(pdfapp_t *app) +{ + return + " l <\t\t-- rotate left\n" + " r >\t\t-- rotate right\n" + " u up\t\t-- scroll up\n" + " d down\t-- scroll down\n" + " = +\t\t-- zoom in\n" + " -\t\t-- zoom out\n" + " w\t\t-- shrinkwrap\n" + "\n" + " n pgdn space\t-- next page\n" + " b pgup back\t-- previous page\n" + " right\t\t-- next page\n" + " left\t\t-- previous page\n" + " N F\t\t-- next 10\n" + " B\t\t-- back 10\n" + " m\t\t-- mark page for snap back\n" + " t\t\t-- pop back to last mark\n" + " 123g\t\t-- go to page\n" + "\n" + " left drag to pan, right drag to copy text\n"; +} + +void pdfapp_init(pdfapp_t *app) +{ + fz_error *error; + + memset(app, 0, sizeof(pdfapp_t)); + + error = fz_newrenderer(&app->rast, pdf_devicergb, 0, 1024 * 512); + if (error) + pdfapp_error(app, error); + + app->scrw = 640; + app->scrh = 480; +} + +void pdfapp_open(pdfapp_t *app, char *filename) +{ + fz_error *error; + fz_obj *obj; + char *password = ""; + + /* + * Open PDF and load xref table + */ + + app->filename = filename; + + error = pdf_newxref(&app->xref); + if (error) + pdfapp_error(app, error); + + error = pdf_loadxref(app->xref, filename); + if (error) + { + if (!strncmp(error->msg, "ioerror", 7)) + pdfapp_error(app, error); + pdfapp_warn(app, + "There was a problem with file \"%s\".\n" + "It may be corrupted, or generated by broken software.\n\n" + "%s\n\nTrying to continue anyway...", + filename, error->msg); + error = pdf_repairxref(app->xref, filename); + if (error) + pdfapp_error(app, error); + } + + /* + * Handle encrypted PDF files + */ + + error = pdf_decryptxref(app->xref); + if (error) + pdfapp_error(app, error); + + if (app->xref->crypt) + { + error = pdf_setpassword(app->xref->crypt, password); + while (error) + { + fz_droperror(error); + password = winpassword(app, filename); + if (!password) + exit(1); + error = pdf_setpassword(app->xref->crypt, password); + if (error) + pdfapp_warn(app, "Invalid password."); + } + } + + /* + * Load page tree + */ + + error = pdf_loadpagetree(&app->pages, app->xref); + if (error) + pdfapp_error(app, error); + + /* + * Load meta information + * TODO: move this into mupdf library + */ + + obj = fz_dictgets(app->xref->trailer, "Root"); + if (!obj) + pdfapp_error(app, fz_throw("syntaxerror: missing Root object")); + + error = pdf_loadindirect(&app->xref->root, app->xref, obj); + if (error) + pdfapp_error(app, error); + + obj = fz_dictgets(app->xref->trailer, "Info"); + if (obj) + { + error = pdf_loadindirect(&app->xref->info, app->xref, obj); + if (error) + pdfapp_error(app, error); + } + + error = pdf_loadnametrees(app->xref); + if (error) + pdfapp_error(app, error); + + error = pdf_loadoutline(&app->outline, app->xref); + if (error) + pdfapp_error(app, error); + + app->doctitle = filename; + if (strrchr(app->doctitle, '\\')) + app->doctitle = strrchr(app->doctitle, '\\') + 1; + if (strrchr(app->doctitle, '/')) + app->doctitle = strrchr(app->doctitle, '/') + 1; + if (app->xref->info) + { + obj = fz_dictgets(app->xref->info, "Title"); + if (obj) + { + error = pdf_toutf8(&app->doctitle, obj); + if (error) + pdfapp_error(app, error); + } + } + + /* + * Start at first page + */ + + app->shrinkwrap = 1; + if (app->pageno < 1) + app->pageno = 1; + if (app->zoom <= 0.0) + app->zoom = 1.0; + app->rotate = 0; + app->panx = 0; + app->pany = 0; + + pdfapp_showpage(app, 1, 1); +} + +void pdfapp_close(pdfapp_t *app) +{ + if (app->pages) + pdf_droppagetree(app->pages); + app->pages = nil; + + if (app->page) + pdf_droppage(app->page); + app->page = nil; + + if (app->image) + fz_droppixmap(app->image); + app->image = nil; + + if (app->outline) + pdf_dropoutline(app->outline); + app->outline = nil; + + if (app->xref->store) + pdf_dropstore(app->xref->store); + app->xref->store = nil; + + pdf_closexref(app->xref); + app->xref = nil; +} + +fz_matrix pdfapp_viewctm(pdfapp_t *app) +{ + fz_matrix ctm; + ctm = fz_identity(); + ctm = fz_concat(ctm, fz_translate(0, -app->page->mediabox.y1)); + ctm = fz_concat(ctm, fz_scale(app->zoom, -app->zoom)); + ctm = fz_concat(ctm, fz_rotate(app->rotate + app->page->rotate)); + return ctm; +} + +void pdfapp_panview(pdfapp_t *app, int newx, int newy) +{ + if (newx > 0) + newx = 0; + if (newy > 0) + newy = 0; + + if (newx + app->image->w < app->winw) + newx = app->winw - app->image->w; + if (newy + app->image->h < app->winh) + newy = app->winh - app->image->h; + + if (app->winw >= app->image->w) + newx = (app->winw - app->image->w) / 2; + if (app->winh >= app->image->h) + newy = (app->winh - app->image->h) / 2; + + if (newx != app->panx || newy != app->pany) + winrepaint(app); + + app->panx = newx; + app->pany = newy; +} + +void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage) +{ + char buf[256]; + fz_error *error; + fz_matrix ctm; + fz_rect bbox; + fz_obj *obj; + + if (loadpage) + { + wincursor(app, WAIT); + + if (app->page) + pdf_droppage(app->page); + app->page = nil; + + obj = pdf_getpageobject(app->pages, app->pageno - 1); + + error = pdf_loadpage(&app->page, app->xref, obj); + if (error) + pdfapp_error(app, error); + + sprintf(buf, "%s - %d/%d", app->doctitle, + app->pageno, pdf_getpagecount(app->pages)); + wintitle(app, buf); + } + + if (drawpage) + { + wincursor(app, WAIT); + + if (app->image) + fz_droppixmap(app->image); + app->image = nil; + + ctm = pdfapp_viewctm(app); + bbox = fz_transformaabb(ctm, app->page->mediabox); + + error = fz_rendertree(&app->image, app->rast, app->page->tree, + ctm, fz_roundrect(bbox), 1); + if (error) + pdfapp_error(app, error); + + winconvert(app, app->image); + } + + pdfapp_panview(app, app->panx, app->pany); + + if (app->shrinkwrap) + { + int w = app->image->w; + int h = app->image->h; + if (app->winw == w) + app->panx = 0; + if (app->winh == h) + app->pany = 0; + if (w > app->scrw * 90 / 100) + w = app->scrw * 90 / 100; + if (h > app->scrh * 90 / 100) + h = app->scrh * 90 / 100; + if (w != app->winw || h != app->winh) + winresize(app, w, h); + } + + winrepaint(app); + + wincursor(app, ARROW); +} + + +void pdfapp_gotouri(pdfapp_t *app, fz_obj *uri) +{ + char buf[2048]; + memcpy(buf, fz_tostrbuf(uri), fz_tostrlen(uri)); + buf[fz_tostrlen(uri)] = 0; + winopenuri(app, buf); +} + +void pdfapp_gotopage(pdfapp_t *app, fz_obj *obj) +{ + int oid = fz_tonum(obj); + int i; + + for (i = 0; i < pdf_getpagecount(app->pages); i++) + { + if (fz_tonum(app->pages->pref[i]) == oid) + { + if (app->histlen + 1 == 256) + { + memmove(app->hist, app->hist + 1, sizeof(int) * 255); + app->histlen --; + } + app->hist[app->histlen++] = app->pageno; + app->pageno = i + 1; + pdfapp_showpage(app, 1, 1); + return; + } + } +} + +void pdfapp_onresize(pdfapp_t *app, int w, int h) +{ + if (app->winw != w || app->winh != h) + { + app->winw = w; + app->winh = h; + pdfapp_panview(app, app->panx, app->pany); + winrepaint(app); + } +} + +void pdfapp_onkey(pdfapp_t *app, int c) +{ + int oldpage = app->pageno; + int panto = 0; /* 0 = top, 1 = bottom, 2 = leave alone */ + + /* + * Save numbers typed for later + */ + + if (c >= '0' && c <= '9') + app->number[app->numberlen++] = c; + else + if (c != 'g' && c != 'G') + app->numberlen = 0; + + switch (c) + { + + /* + * Zoom and rotate + */ + + case '+': case '=': + app->zoom += 0.1; + if (app->zoom > 3.0) + app->zoom = 3.0; + pdfapp_showpage(app, 0, 1); + break; + case '-': + app->zoom -= 0.1; + if (app->zoom < 0.1) + app->zoom = 0.1; + pdfapp_showpage(app, 0, 1); + break; + case 'l': case '<': + app->rotate -= 90; + pdfapp_showpage(app, 0, 1); + break; + case 'r': case '>': + app->rotate += 90; + pdfapp_showpage(app, 0, 1); + break; + + case 'a': + app->rotate -= 15; + pdfapp_showpage(app, 0, 1); + break; + case 's': + app->rotate += 15; + pdfapp_showpage(app, 0, 1); + break; + + /* + * Pan view, but dont need to repaint image + */ + + case 'w': + app->shrinkwrap = 1; + app->panx = app->pany = 0; + pdfapp_showpage(app, 0, 0); + break; + + case 'd': + app->pany -= app->image->h / 10; + pdfapp_showpage(app, 0, 0); + break; + + case 'u': + app->pany += app->image->h / 10; + pdfapp_showpage(app, 0, 0); + break; + + case ',': + app->panx += app->image->w / 10; + pdfapp_showpage(app, 0, 0); + break; + + case '.': + app->panx -= app->image->w / 10; + pdfapp_showpage(app, 0, 0); + break; + + /* + * Page navigation + */ + + case 'g': + case '\n': + case '\r': + if (app->numberlen > 0) + { + app->number[app->numberlen] = '\0'; + app->pageno = atoi(app->number); + app->numberlen = 0; + } + break; + + case 'G': + app->pageno = pdf_getpagecount(app->pages); + break; + + case 'm': + if (app->histlen + 1 == 256) + { + memmove(app->hist, app->hist + 1, sizeof(int) * 255); + app->histlen --; + } + app->hist[app->histlen++] = app->pageno; + break; + + case 't': + if (app->histlen > 0) + app->pageno = app->hist[--app->histlen]; + break; + + /* + * Back and forth ... + */ + + case 'p': + panto = 2; + app->pageno--; + break; + + case 'b': case '\b': + panto = 1; + app->pageno--; + break; + + case 'n': + panto = 2; + case 'f': case ' ': + app->pageno++; + break; + + case 'B': + app->pageno -= 10; + break; + + case 'F': + app->pageno += 10; + break; + } + + if (app->pageno < 1) + app->pageno = 1; + if (app->pageno > pdf_getpagecount(app->pages)) + app->pageno = pdf_getpagecount(app->pages); + + if (app->pageno != oldpage) + { + switch (panto) + { + case 0: app->pany = 0; break; + case 1: app->pany = -2000; break; + case 2: break; + } + pdfapp_showpage(app, 1, 1); + } +} + +void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state) +{ + pdf_link *link; + fz_matrix ctm; + fz_point p; + + p.x = x - app->panx + app->image->x; + p.y = y - app->pany + app->image->y; + + ctm = pdfapp_viewctm(app); + ctm = fz_invertmatrix(ctm); + + p = fz_transformpoint(ctm, p); + + for (link = app->page->links; link; link = link->next) + { + if (p.x >= link->rect.x0 && p.x <= link->rect.x1) + if (p.y >= link->rect.y0 && p.y <= link->rect.y1) + break; + } + + if (link) + { + wincursor(app, HAND); + if (btn == 1 && state == 1) + { + if (fz_isstring(link->dest)) + pdfapp_gotouri(app, link->dest); + if (fz_isindirect(link->dest)) + pdfapp_gotopage(app, link->dest); + return; + } + } + else + { + wincursor(app, ARROW); + } + + if (state == 1) + { + if (btn == 1 && !app->iscopying) + { + app->ispanning = 1; + app->selx = x; + app->sely = y; + } + if (btn == 3 && !app->ispanning) + { + app->iscopying = 1; + app->selx = x; + app->sely = y; + app->selr.x0 = x; + app->selr.x1 = x; + app->selr.y0 = y; + app->selr.y1 = y; + } + if (btn == 4 || btn == 5) /* scroll wheel */ + { + int dir = btn == 4 ? 1 : -1; + app->ispanning = app->iscopying = 0; + if (modifiers & (1<<2)) + { + /* zoom in/out if ctrl is pressed */ + app->zoom += 0.1 * dir; + if (app->zoom > 3.0) + app->zoom = 3.0; + if (app->zoom < 0.1) + app->zoom = 0.1; + pdfapp_showpage(app, 0, 1); + } + else + { + /* scroll up/down, or left/right if + shift is pressed */ + int isx = (modifiers & (1<<0)); + int xstep = isx ? 20 * dir : 0; + int ystep = !isx ? 20 * dir : 0; + pdfapp_panview(app, app->panx + xstep, app->pany + ystep); + } + } + } + + else if (state == -1) + { + if (app->iscopying) + { + app->iscopying = 0; + app->selr.x0 = MIN(app->selx, x); + app->selr.x1 = MAX(app->selx, x); + app->selr.y0 = MIN(app->sely, y); + app->selr.y1 = MAX(app->sely, y); + winrepaint(app); + if (app->selr.x0 < app->selr.x1 && app->selr.y0 < app->selr.y1) + windocopy(app); + } + if (app->ispanning) + app->ispanning = 0; + } + + else if (app->ispanning) + { + int newx = app->panx + x - app->selx; + int newy = app->pany + y - app->sely; + pdfapp_panview(app, newx, newy); + app->selx = x; + app->sely = y; + } + + else if (app->iscopying) + { + app->selr.x0 = MIN(app->selx, x); + app->selr.x1 = MAX(app->selx, x); + app->selr.y0 = MIN(app->sely, y); + app->selr.y1 = MAX(app->sely, y); + winrepaint(app); + } + +} + +void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen) +{ + fz_error *error; + pdf_textline *line, *ln; + int y, c; + int i, p; + + int bx0, bx1, by0, by1; + + int x0 = app->image->x + app->selr.x0 - app->panx; + int x1 = app->image->x + app->selr.x1 - app->panx; + int y0 = app->image->y + app->selr.y0 - app->pany; + int y1 = app->image->y + app->selr.y1 - app->pany; + + error = pdf_loadtextfromtree(&line, app->page->tree, pdfapp_viewctm(app)); + if (error) + pdfapp_error(app, error); + + p = 0; + for (ln = line; ln; ln = ln->next) + { + y = y0 - 1; + for (i = 0; i < ln->len; i++) + { + bx0 = ln->text[i].bbox.x0; + bx1 = ln->text[i].bbox.x1; + by0 = ln->text[i].bbox.y0; + by1 = ln->text[i].bbox.y1; + c = ln->text[i].c; + if (c < 32) + c = '?'; + if (bx1 >= x0 && bx0 <= x1 && by1 >= y0 && by0 <= y1) + if (p < ucslen - 1) + ucsbuf[p++] = c; + } + + if (by1 >= y0 && by0 <= y1) + { +#ifdef WIN32 + if (p < ucslen - 1) + ucsbuf[p++] = '\r'; +#endif + if (p < ucslen - 1) + ucsbuf[p++] = '\n'; + } + } + + ucsbuf[p] = 0; + + pdf_droptextline(line); +} + diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Info.plist b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Info.plist new file mode 100644 index 00000000000..5b7681b2b71 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Info.plist @@ -0,0 +1,44 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ghostpdf + CFBundleIconFile + macpdf.icns + CFBundleIdentifier + com.artofcode.GhostPDF + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 0.1 + CSResourcesFileMapped + + + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + pdf + + CFBundleTypeIconFile + macpdf.icns + CFBundleTypeName + PDF Document + CFBundleTypeRole + Viewer + + + + NSAppleScriptEnabled + YES + + + diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/MacOS/.gitignore b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/MacOS/.gitignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/PkgInfo b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/PkgInfo new file mode 100644 index 00000000000..bd04210fb49 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/InfoPlist.strings b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/InfoPlist.strings new file mode 100644 index 00000000000..f3bc11277eb --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/InfoPlist.strings @@ -0,0 +1,7 @@ +/* Localized versions of Info.plist keys */ + +CFBundleName = "GhostPDF"; +CFBundleShortVersionString = "GhostPDF version 1.0.0"; +CFBundleGetInfoString = "Copyright (C) 2005 artofcode LLC."; +NSHumanReadableCopyright = "Copyright (C) 2005 artofcode LLC."; + diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/classes.nib b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/classes.nib new file mode 100644 index 00000000000..ea58db1189a --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/info.nib b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/info.nib new file mode 100644 index 00000000000..611a192f2d5 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/info.nib @@ -0,0 +1,24 @@ + + + + + IBDocumentLocation + 54 19 356 240 0 0 1024 746 + IBEditorPositions + + 29 + 15 273 236 44 0 0 1024 746 + + IBFramework Version + 349.0 + IBOpenObjects + + 166 + 29 + + IBSystem Version + 7W98 + targetFramework + IBCarbonFramework + + diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/objects.xib b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/objects.xib new file mode 100644 index 00000000000..143a0dd022a --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/English.lproj/main.nib/objects.xib @@ -0,0 +1,516 @@ + + + IBCarbonFramework + + NSApplication + + + + GhostPDF + + + MuView + + MuView + + + TRUE + About MuView + 0 + abou + + + _NSAppleMenu + + + + File + + File + + + TRUE + New + n + new + + + TRUE + Open… + o + open + + + TRUE + + + TRUE + Close + w + clos + + + TRUE + Save + s + save + + + TRUE + Save As… + S + svas + + + TRUE + Revert + r + rvrt + + + TRUE + + + TRUE + Page Setup… + P + page + + + TRUE + Print… + p + prnt + + + + + + Edit + + Edit + + + TRUE + Undo + z + undo + + + TRUE + Redo + Z + redo + + + TRUE + + + TRUE + Cut + x + cut + + + TRUE + Copy + c + copy + + + TRUE + Paste + v + past + + + TRUE + Delete + clea + + + TRUE + Select All + a + sall + + + TRUE + + + TRUE + Special Characters… + chrp + + + + + + Window + + Window + + + TRUE + TRUE + Minimize Window + m + mini + + + TRUE + TRUE + Minimize All Windows + m + 1572864 + mina + + + TRUE + Zoom + zoom + + + TRUE + + + TRUE + TRUE + Bring All to Front + bfrt + + + TRUE + TRUE + Arrange in Front + 1572864 + frnt + + + _NSWindowsMenu + + + + _NSMainMenu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 56 24 553 587 + Window + + 0 0 497 563 + 0 0 563 497 + + + 482 248 497 549 + 248 482 301 15 + + 1 + 2 + 2 + + + + -1 548 483 563 + 548 -1 15 484 + + 1 + 2 + 2 + + + + 482 23 498 47 + 23 482 24 16 + < + + 1 + 2 + + 0 + 3 + + + 482 46 498 70 + 46 482 24 16 + > + + 2 + + 0 + 3 + + + 482 92 498 112 + 92 482 20 16 + ( + + 2 + + 0 + 3 + + + 482 111 498 131 + 111 482 20 16 + ) + + 2 + + 0 + 3 + + + 485 199 495 237 + 199 485 38 10 + TRUE + 3 + + 2 + + TRUE + + + 482 0 498 24 + 0 482 24 16 + << + + 1 + 2 + + 0 + 3 + + + 482 69 498 93 + 69 482 24 16 + >> + + 2 + + 0 + 3 + + + 482 168 498 188 + 168 482 20 16 + + + + 2 + + 0 + 3 + + + 482 130 498 150 + 130 482 20 16 + - + + 2 + + 0 + 3 + + + 482 149 498 169 + 149 482 20 16 + % + + 2 + + 0 + 3 + + + 0 0 484 549 + 0 0 549 484 + Poof + 666 + + 1 + 1 + 2 + 2 + + com.artofcode.ghostpdf.View + + + + FALSE + TRUE + TRUE + FALSE + + + + + + + + + + + + + + + + + + + + + + + + + 200 83 330 337 + Password + + 0 0 130 254 + 0 0 254 130 + + + 20 20 36 234 + 20 20 214 16 + This document is encrypted. + + + 50 32 66 146 + 32 50 114 16 + Password: + + + 51 106 67 215 + 106 51 109 16 + TRUE + TRUE + TRUE + + + 90 132 110 202 + 132 90 70 20 + OK + 1 + + + 90 50 110 120 + 50 90 70 20 + Cancel + + + + FALSE + FALSE + TRUE + TRUE + 11 + FALSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Files Owner + + MainWindow + + MenuBar + + PasswordWindow + + View1 + + + 239 + diff --git a/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/macpdf.icns b/rosapps/smartpdf/fitz/apps/macosx/FzView.app/Contents/Resources/macpdf.icns new file mode 100644 index 0000000000000000000000000000000000000000..d11b8be13c93961043655bf312e17532287e3d64 GIT binary patch literal 31574 zcmcIt2S8NE)8FeHcU+~}d)KJ3L`{q>vBbnAmL%2~jmEBtHEQ%7z4zWxK&cj_sHmub zy=&}J#fs94AouLA0~{M)QJ#|o|b;H zxrd=i4 z6rxR59mlEY23fppz{i9L1a^eS73qn*2%jr4kjphnB6TA?kyNhKsQHG5YPGesNUSnbYgAkybR|TryEYVC6QZ^u9FfutRfdMRmDzz+ z1w(I*Z3t1=6Uwv7(3pct1v*6eG{FsrhdRE2Qf-9(aOCI^dt-|BN`)=q%aw*E5-LQc zQff&Aw9>@XfeM3GQcE`fN|!33VtVp^i^hxd%obg#dWAP{B`Ie1c*QK_4S< zGuzTHFftx$m}l)5xP2GLiwNhM`veAudqW{({_+Y83=Z}*@+9JQuKodmf&T8Bd%F|v z57s`KK!Kl^lhyJ*u7vxSi=QS?7~tpS=43a~necd49{#i-z~9fu%hs6)c-CHlK|z** z#LtBYr~3wlgaij^0=dE4{alG)T0m%M2)*4NJrTn9wI=$Uuf6>PKrS?94@#`;h)7}U z=@%FrwI8~2fUefM`Ugd(C{gKv-fFyqB2$f_t6?tC)oSyfoP*|blOVDxwDJgGHA>2cbABi(+)(@*45p`_SbJFkDvSp;~sI~G{=z`@XUR@ zz1&=!-F&vir5tl5`f97t?cqD4_a>(d@g#iyknhK}VwE=N*G03Tw62a(N6z24o0Sy+ zr7hZaBCD{f7Cxi4`WI)y|0DYPvl>RrExi4J(Gp)MZEE<)Q( zswY8tq8~Oa?iEFr4OzaF5WXI1@ZryJ^;~2m;5H~~aQQ>M|K6$MHz=;ZEUK@@@9FZl zaJ;Omt|~^yv~DeU_3d=O|7NRSq$h?r+c@~;YyWKd1_mWtU3AD}&X6wcJNEyU(SECH zh#-xvKWaBj!RK%|JpFc)()tM-0I=0HQ4=L~WgNxV!xXRUF+<=}>)GoSR~&;5%GVs| z>a||I8x)Be;IFH%`NrTi&W2Z*}@D^CUb@!y4VSD6bv>myPF>V@uY!v^55RGnFudV9#hT?%n_VpV8+F{aq+`8W!#n_7tA*wzV{{z5az^V%k zAi{gTvXbt)9tm2GT;cf|WUjIvL1(duz2u0DdQV&#T!+NDN4>0gn_AT4;^`UonOVa^ zM1N7Q0bcnhs@Fo}DMqmM$YakGvI(L1g;|dM9 zU9`2IN?(y^Put(|8}M4l;&~|OsHbE2b6Q=SveNWb158HCX<=TdP0&4hq17Jq98%9d z<&0-MtwLA9{;WP0IH`esQULWAj_?-jr}ko!^H=KE*eL>p3SFm}ZA-s?;aGBv>w^9U z|EQ)Yr0s`(KX2)xSz~*t1Z*4pSiFV?L;d^HdoBLOVIt-6MP_;ev7T5c0Hb2m8bfCzM1Mw>h8(#tok;5H z*~SbSGlm)?OJge|uAvbNXJ*Jz2#y1eQUQ;Y2*txOG-Qmdj0Hw&g~9-$;K>mnY7BWs zXs0pcC`Ct!KDWLN<%?1C3~8OQ$i&#hNGTO^F&S`pB8eOf6VT!)1xGONi1qbZI<$>I z4Jm*RW5$GMq}1aeM&yd+Y74;f4->HneWNT

~MQ7@%BZInRr51yYqcnCGStF^?6( zTY#YGN4Q+63Jk~(vb1%5tf!4&nK9uQOM(bTAOn!(01;Dd>WES?=z%|DV-r&&VJN~@ zC3>L}Bonc&=Q@J=EN1{RG3IY49KHhLR{}-|>AXh7Lq9=`h{9=9N#pZGB8D))kPeNw z9*wDVC!$wFwThcS^r-q+Bvimc%8ZGLVHC!P+Ry;iFs=Ibv>GH#O!cA(&p@r_#uGhm zeQPt7UY-0*3}dkxP|Hxu*J+%Zq^=fyFhDI=p+c?jP1G!9VI1KKm6E+gRNptV*KBcj z5spN$hv;#1coo1~&$A(CH{mFFyD3X`9Mehx+adKHtn{R)V;Q2-cvWYt-b;u+sxXG7 ztR=j{X{_enN4eycg<#Y%Y69~nJhtMMm9Z79Jri-m8gszwisdL4)|-YIMjvI&$dH#u z3Dn`if`%Hh6lJ{EWg3hLj#`+DFs!c70?jd~7tHNa3vz{-=L{Oqx4`4`Eoc`?iC78osm-Mse&U@2;_2^zL0YX`0G5Fm&y#~ zjGU`4;++RKby&PnY(|SEBFlNZUzzR>HKjRn!#0~K&&g+f%P9C z(y=lHpUP+~YLy1O`rB9)>sPrV1?u8dSmLH*Oi*Ix@cZfrl<1*^XTX*)mc z7xLz+lz``O^fdstQhP&%90h1|gfa$B&Q9&Fvc`-6_IO-h`mHBh<$lpSsyW91Hb138AhKw=K_WCy5-4mo3E zBYp%H@QQedP@>SVM#|1Bj4{!VAY6%3z7Nd|%whg@GY)Fx6rUmi#Km+5wgjj3jZ{0} z?v%nrY5-7)6;%QVp^+hK3{;9FtXwebF=(ap*a&^W^T^5owz^kj~3l%B_k78yAiU!^n36**P-cGo0 zrBX)Q>&CB{O8B~(3*qZAN}`YUdUfq}f-u&Y5Kbgbd?*$CL?n%nC{n;)7`2F_7FK&H>=S^6FaFf zrbHTt2ux-LzLh#1u}Q4E~5j{Q3J zD0LG7%#ka#0R3np6SKWXbJi$LKwcS-uux_J^n#rrubYhO)W){wQM**Ymq>WwL{8-c z>FY2+w!k1y#4rZ{SE0w-Mj;x|U?Dh$oFt5Cg%v>bc|pX8t5@fH*=_&^d>ZrjQy6Rb zXQ_zeOH^w-|og-RVmfMx3t*pl18%kpLVA^`_0 zdIZ&CgnV+H`Mwe&D~2ObqJa%uwFXL(NG$Zt3^X#e&U5O-LB|gmRUL)Es5!vDnkg*h z<}!{P;WYKZOr1f~fQV;ms^lC;0DuvwVLiCHoM0YcFpkA6Y1SN7QwWgzM^P}%^@ zLV+ZmiZw8Hu4dyxQ)7KNNsgY}0aKuo`gIj+{}`IOAd_pV=A9v2zC?*xi26)gtU&~5 zaDjEM)P=))S|Ie*81oU(DS4L(UmyV;2elWplDL0TxL_E5lss9(jUd0lH zMA7G?v0r^P@tbeH`+oB95$z2h5>sxgK@;aJTC#lQA8XdF->`Ah=D)UX`E$WHgO%CD zm}ffpr+Et(EnU89^%`3D7h`5_Zehh(^KF=UBNcZ@OK$tGexA4Bw`D6|cIev~1Oy4V$-`SpdS($=Sul&CT77ao2bV z+&!EY4H8@>9gWA${P~yPmi@kV(-w`TjlGkztDC2nw~vpnpTA##e*k{^Ykaw0OFzB@ z=05&$=G5uTRFlM^|sY%Px2oFr!eLsEn z{3XAy-)u&kc=-4R1O;yk3y)wTNt8vjJSr+WDstz}9Xle>&hIy)Q=~($$v@3rux!mn z#@f!=&C|y}kizebijIxlwQKk8J$rWVW_B@g(%9(e$Y>;YcSMA3>UDy&?KSPEIlrw~ zyUEak0B%&^jtAa)-l+bkefdRJ2^V zZi|(jv%9x%KyXM{L}c`?J@E;NNoL9VNlA$b@$q|gboJw6W8cZwucM9k(|jY5#$POp5T}!T6mX&Rdubf{pf$f#I>5IBslQEEB_x_M3E+ zbTXYhZO+0~>(JQE%hx|BWLrd3%$|hggDHoP966fgvus2g3D+FKlu*^>%fKsswQJvj!$;Fj1oiaAwBBu1uqK8ZWv6$5w3L7I!|dNyZL+X; z_4Ex04Bj3dwJZL>;o});iv$4(j|XaY#6Zof4-nIVQ>V{gzTV8%#lzPRNW*r<#qU3S z{6xy5fR(kClHhFQ)kRy0X*m^#RI1H9Xy(`OAm`a$=a};ntjAXFz$yri&k&3 zcJ}o43k(d|79O=b@$m7}UqunV{?_dg?c<4w(bVblmTfSzcZIkD0z)C*z55TR#q+TC zli7rAi6_S0f1J7C_sy1$?%s6V03tU2z>$n~v4q#nBgAMgF&_TY>?Nxi8yA=_#JG)0 z=U{5ua4hk@3R;Z%DKmb7@W3a8qO0F`@W|0ty9jrKJ63WgvL9ytx@x1P1GQoRY!8D( z_8&=<0YK?Ka5vF!|I_T>e&0;R>c<3%brh11M2WBzoVf<|y=MH3UfQ^L_^|a5MeLsB zlt>9C>Q%u1$&8% zePS|j&b*at&FsK=0JbAwd=Zgxd-o;$M62e`U%A$tR{7IbA?SA0?)ZH+_lfDJbADa1 z!Q9T3tqKeZ2FA#k-FtR^lt)?&n7d#(q)l}OVX*CXM8(GKTEovJlJ>tWSn;Qs9SkGD zp9$1wTkedCiQV=&Dm$Wby#`p(k_nWcDLloF$f!vBb~!}Cox5=PhOOwMw?Fn`1hi>b zIJ1KrvBoHe=zsUy^0ixRoL~iPC3SvbOgJxW+j3Plk&OCn*_t||4bTKiDdufq+rzep z2L0YLi%5F?wsg&AOFEwX1Iz;@!66}`+qYp0Cty>bOd?VJy7Z4ttTFrfn*}mKOo(16 z+^@f{!$j#lBKckqlb8YW-GgcDw{w1{wqh z1&6?I`}ugf+01Nlo5+<5SFZib!U3K3gX$;>Sx``LU{HX+kGH$4lf~rrw}|YE6>B$| z**be*(9u0B^FVn}U=S{_8|C5RXs?;k`v#Gp zGRE{8k@LP;z3wkdJBSguK+rl+5fI?#>*ML}>SAweW4UGKP@^kE-gd>hO&V(_H*Y%e z0F6zcl5T!^d$_qc+1pxKT5OsjbHcYRx3MK^q$3L6=+O50ixbs?yk;`4z|{o z7G_)LecACmks2@Cu-VKOUJi3!fL$OHVCWCR-k|L4Xm4i&q~^?`FHO!8$;X)aC{}ND z#U6mh{uI*7i&6)uwUs5X&Ke*+MWozm8@HI-qSusB2f)g8u$~kxfbDHH*4!1NWG9K# zaMfnU%HG+7rB6W_e?vcCblub4&DF)((b3-4+Qw$>7pfCP+GG7za~nr0B?!~;HLQ=9 zr-!>MFgrOq*xUaxTrY!2KmAK%NxKEx3qZg4R96Vr(*{A zT4Qc)@1mR4(Ln;EWCFPU7!!VSG@vag6&Dxt3Gy@|)thE!Ve9DX?u~&F-~@0ckV7dj z{vuHDp%fSozMH$t!cKtJpJr)o=j5hi-I;|puS3rB_4W2j$L~iNTLnwhqqj zbkIP-1pAqs0I*^iK)?vc*H`1iu^gR7^!3Lh3UOuGwF8)SJqP9i`sgu27e8M==LsOq zA8l^$Z=Hj)PQif~G~D1I{A2*^h7l&f zC<$^Kn@*%{<~kvqVa+}$hzaImXqdBLj)9z@Kqgp-ffy3%{5i6>@^M?;JUqS76$(j0 zG{I(+0g4k6Mv(|{)3)u~t-59qS*Lk4qVS`B4ef&&KxI7sSuBO;@sV6-Z0?*u)Ycuhsaq9zI@-H;=}~j6W>WOec}>$k;vciAnwvWIfyhcN4jO z--S*d?jD|=-c*(TEF5Mq3b!vQdGANaf!GIj#u8cd(EgPzYtnl<+ji}6Y-4+XYKNbrnxE+8JNS6@ zOCrW!Y-FsQFsma9LJYVgX7Bz($I>!-1HyE@hnF=VjQ-eUX6MYtK|$zr%wB|(>1kaN zkxh2-^qQYUjJ{j9#hOM^0f@$E#C8BQjvDVIg0>sn-5rM~5~IPZH)A?wqvLIe4HHt1 zrk^~*jU z>9Z${ci}vWy_1WptNXfcaYXgq%0Dd}+g9puHFG5;joj#$4{O)@5|Xs zBt5n`V$q4dZx|ukLDYknto_T%#oa#`(n&yAedg@RuKS2&u$7Yw2m;w}y~2sQ-*2lo znc2I02X51a&8N~!yBZ*OC{VfyHyCOA#iRxIk&bKDP0 zR{Xwp!(V1Lj*wm`q?f?j)j40$VIt_e32m{YSD-cKersz>b7t%O*)wNM*ZjnpzDBd! zbj>>C05Gw;x%&n|TzmGR^@-DGw@Xt=n;t9C*xd`xic&|sV{2n&VXk4AEq`s^xKZ)~PM)z{ODt^+vSAE`@fWS$xugL#b)$ zC*%5@#!hFSMXuD-BMQ_YK0scB#s~O;c#jR**~S0f#QiBpjvmiAx=wly+Xk$g|U0@zQpAHDTh*zrg{#$hNN!q>0A7QnQd(_IRhD{Q_QDWb?@H07YT&qg9i_% zCR+95+$8NK{TEpHAX!4^<*29_thILoXkS87a`M4L@owKsGD%DQE)##Z_1Q*e+gM%h zA_3ImeAkXN%qJ?Is?Ug@m#*1p@8aTVy?N=cW4h|qr>N-f@cJ~BqUHE;%T}*myJ5rT zzqZW&rGHzbsrbF7tZ~JtkJ-I1De1uB!$*#$A3qSd@rPE~q^+>)6kG2g*aN1t+bCn z4&Ml_lWyE0>s>I0cEs-6pPGK^?4_&MZr{0^nVFNDo1K@Nn|D7iFZcePkf{=6syeSg zG#wNHCv^Pexy#pY-^ag?f6Pn0nwsj$s>*Y}=_6Iu?=L$S->_ZDsi&`?$^FL# z#bsqLUe?ySYK676FJC?jYJZ9tj@fGK8n7ciCF9cHcXRTe6c$&!c=^&-%d35H_{$SS zHOAb=EjTLS$eC-mvhtriFRrM38LZ{}{YyGgjn>$@2FD~Gzwr0HyvGGaWfd=LL$#dj z6~~EkG-Klw5|f;9=|)!mV>Ej4(q3y&S#b6A{(bx6lg?d!RPxeB%Xz%f2TM~S!z)H(0SagIaOg30J1w=c>U0qA*===^Pw;=(y1%=@}52~Dyw=4MvA9}5U$$s z2|%i5!%=tIV&=MS4_L~5Tu@j7X@QI4FOUKH{szvf$!2S}u=tG2ck`YUJTI-Pw$Ks}q<)MJ)@VyUN+9yj&Fp=F;6~0v z7Qss($fle9s(sbklzl{@zrxBbbZ^?_yZMiwm6TLgg97;tNgsJyb>&C#MBd5F&S&TT zQ#YtQib|@g(f+Xj8J`xHUhYTr=T?pZaYxSI&U^Iid1={;8ng~Yx@W}w;`V!q{AU~2 zuss=9?g4jkNqIGhlOK`mSzQu{O2*D}XVU4va~?i@j$?^0UP8RJJ(0-SpM^}1!pPFm zKPKhe&D=)?#i*{P)uou~x$UwiV>y(TjILm%)+4>KarR7$D2zoPgRf_HH5Q z)4lsoo};$BiZ*_(LK0^eFi&&v2v5kknhDcJk1E*8@{Xt+zndthI(zL*I(0Sc!IPrr zC1qt*)%0Ls)tC2)@_SdG=)_akavl`W8W<3*skK7QWDmdSM0DgqL1AG@X{oL&r#N{; zHN(w6YX6yQ*$-*WD|DsfQ8mdUAo9TJ>p9RXTUE&lV2>!5s0VlkL>@eKjq-r1(z0?L z7sd0C+WEvQAS(F;t$SX`l<>>SDp~%o^+#fd?-96jfBIEOo7M?SOUo;(U)JJiX>DQ$ zWOg zW$CV-$n1O(91)*-9#-_U5UmY>yP~qH=0#OyY0=^F$nCW83*UA4%ysbftkA4PM!i-g z{*{+KFSxNrjqJ{bh}Z)suHCu+q@b|KtV9lgvhs?GveKf0hq*Cd@a_=F=T?om6etQsI0W``I84ZSDd;b%VQc8z3Pizm>-Q!dJ$EfL|8c={99}K5C{Y8dxafJolLxuk z_pV>Pd@jv#dPn4XK8i{>eDd;b9ZEo$mvD+pm||5SKp*DiWZu4h_2Rj+M_lH1;a?>3 zRfz}FF8rMZi9ClL7NftdVCf)GTvSw8@bvM6+^oB|Z(O~2{_LrA@1=v!6M4rS2U1U6 zxs&s-073*0IBbg+OtA?X6h43Y7`u#jhHf78N~z{tSIZXYbv)_4l<)7tftLd&>Dc^(mqdn5P^&edSj6gU8R%XEbBG zqA6BULTL2xK|Z*%{Q%F}Qn}pTB=f z8c`crU$}DPPTm9b1PUspC#G?%nv`0iA?44k$N(~b{_NRPG<*8={NgksQ?I&k4HNhS z2%0L#tb~hp3`+|PYKj$*3FWc)`SXHj1<&sO!8?xq<=@U+zmuK!@X0gSPHCB0DId5D)ioDCLy*B8>T@@jnpiQ&R8*E%R-hrLtc;=kK}+)z6>SK2TV76E zy+nMI(jtRM)N^*{Bl;?YAFg03IaQUK3NEKM&R^ytBQka|I<^J^wZMJdPG9nD7vG!;Tfm}*M{+tHMW%cxAsDymo(D%T?+ zbv7JFC5ElrbGx`4o#DcHG9{K6-~x8Spb^Gp0kTbnNJ$C1{TzA`-qE~>TUb=6DS|c9 zIR`Twph~|7)Klc7I{p}Zr2tVa#skc>5Z;VZ<^vs#ddLoBqzdlFVg=QERbt+gM~|4t zTtG90Tv(f?ghxA#;3!9dbW~m$=3wQ-;M<6z^B+8dOP~)7zzXP0M`IIC^?0OwZj>M! zWg;CHcr!C6`~HJRPY_ZA8SN?NLqOHq0V?Ckt$1Q2n-YKPR%TY-1D$`NFy${OU+Dnx zy;qn()UE9NTfbmjVQeOGeQcI9I<9TF1^Gn3;`|s)JF5jm0c<`bGT}Jgt zR1ZG&_yOWPfpglK%Xe}fVQ|*h&PB#4I{#5j5|MRJJa+EyyZ0Xz6c!_3p-q25D(Uwd zPaaN4A_j|7GA`Ukto#hod{qr9N29WH(*1{*P}yUS_V_x8_;L^^d(D&kIrE~SV&A&v?mGD}-C^B!F7lYp(B z*!>xQXCVMCt*k=Jn@B44IhdP$|F{ad582K{L|=$s5GJ8A9{Hq=cXM-dqNMQ{hha&_ zF5S(4T2#u)XaiD7o%UqHSMLxbxuV=2f9%p7gi>r=&8g~+G}5e__p)zyo5#VjMLhKj^4Y+nlWIdSKRG;_cC*G?t1o!L~4I?{11e(Nrf zXXhOFMYe;8r-ki1dhuRfVL2qtsT=??O}%(0llCm4kos*q;)#g)v2+XIMvoiCtb278KVlT&**xH z*dQGw`Tfeh%$a@c0BJOG1Z%Y z=3aJA4pzQdnRo77zkd1Le*4AKyU2J}L@kpH9=*Z}$))Ck)rB&8i&ILs( z={qteJ0~yi!To#$1vv-`5Pw}bbNXaP`tf6_hYzKs985Vvvqk5x-n#eTF@%kF$JED= zHD#{m-G9J5WFEAqG!gRLyn5}zg>z@loIZ8x%$alNFHt9u_26k?d9}5c`!WVeAAQk} zDY^L%v1ot%gn88ZK^`dHyLJqu)X{c zGj+l9r-(xkDm{6SpO>GDrc9nV{}Cc8tQo6c+G;sjBTkc!{4cjzIk_s9bW6qIQyiU zrULl2WvAAuGl@_&Z1t|IkIL<}g4*Jn+vl{)Cu)A1vA?)(-<^E%+O_K$Nr8^P;jxc~ z`I#`XhJA2qq+b046wUmN$CJ2RE>HKt74Dmf;opN((mZL0egg&$?A}T$5{ZOD0iVyK zO#FMKO>N2H$cHTTJ$b+4Ma|2XHPuyRclLWM{McBcuO|}z|MS3Uy>$1Zy2oc4{Hnbl zyP%ugK%yrSP%$*MFU^J1pSBN={k`K;x_?evl}sY0Quu%2K(XxhJ4n|T-?!^ytfB`M z{~tKu|C(J-<~_fkdh~8-D3|=_9B_u8dJolxRZq6`Xl*THG|E z4WaVpf83>&S}OVvbTEZJ=-TX0@rEJ2+8N381pliMeEV*X^IoPZ%|Gwk(L^r(9~t=M zgXAlUOY`sFzmJF?ncfDU7xrTYbZMdZ-xx4`zsoDgyqb}AB=yLll!FJ7aeVP|UW0L3 zr5QV@Ys>$M0bz234*lb@=IM>J^kb=q4kjnW@200gqv&Q+?BQGWk9TUz|D5nixBrQO zW&fc0`u1hsne?=yhYuv~iH!^o4Z_(mFC2@Yhi$j-Jocat?!n^!je*Y3UK4!ts^Dx! z+R>Ecy)hBNzV1%87Md;C)ZDoFFUG>g0lQQ24|KM0<>v{5yPC@N{@pO-?S7N!tGnu3 z8R^FkCGUw0^>MLg{`_OvqF;ZRGkf;zIdkXZ!1ekqICq(ZHxu9!H*@U3P9_GT#vaE0 z;OzgY?g8ajWa}>~FP=zCJrExi;$_dQTlVX$Y2SV|?u*f*MvfdkX6#qrPMtY#$se06 zT+h=-ssyeH9vm&aYrLO za@)+H%($SQ;v2sUPoy77jPkc#H~;%l1G~2~Rm-JfguVhq;Cz8VDAE&4WJ=@Koq7!( zHEG5&L@h}_e>=QaYlWC!{}}uS?T!WD{Q3sjS2tHOjwZ(h*sh)X^{0J0m?{m#A^{D% zUwwFdflyB(H*DFl_a|R`H}AZ*e8mr64(x1fAZ(rnIB~B?HoPdwIDT+`xOv?bTY@JOOY-jf+1s{YXND`{o7T4DH@Z zi72npH4lf2r*!n?#_f6x8a?;n)7g_o_U~vcZI%EyL*Jau>Sb`@_<`5}%jHu)>)A@F z|Ly<_90>HJs+L{)eYT>)?&~pwyS1cVuxYBNP~64!6yN-PIyE7}b;F!5`?meSm<9(z zeT8X<-k%5BAwx4wtWIVA#6r^uGpu+_QtROpn)O z1#oyb8l_)$G%>bVRtLclsSZ~pooitL$HGK#D!ac!Ol)j>g^r-}d zVkw@{mWrFP9OB9v*FRo35^A&T+ks7$zfJ`LJ-k=~uDZ$M#{++uIvf2w3UgRBWk@Hr zev`c!B)}Kq!*51rhATYYD0LK`a9uZJM0b;BOz4=BXr8Va&mz-d@J6Qxv-de;A#1H8effB6R)&_3JoO&GuFaX6@c<)_PK4phD3@}m{=(8IT|B)0pcq>QCT}`3R z!c?3z8*1{OvOpCu=7Y(%1`NKu>M)wJpi{)Fk@Rmbr~=vqHo)J6%j&C|K892ZbYb*A zS|e5uQschwPyaQ-Qbo+S*nnV%WYeRaMrFk1inSEm3Al$vx4 zZlsSNDyls>wY{lI$3dfAYg!>IfI+7}M6I#<7kh@Y9K3sh+yoY=0F1kQmD3o350({d z>D}H`DHSz+$?-NvSUxIR_nD{5Bz}W*i~3!)wXtIdc5TVViA~b@TR_l&)TrZtam$;s`Pv8SAS8=>;PqKI#X^=$L+*9tU;BRB0jc*2}*O$dh?VWh@;(r3Ne z{Cf$20kOPA*TLgwS=@eqMBE5*T2#LEJIcVn$-uMb02>r5T67&WZpMljyiU3Kp9jmo z{S?{Cf4vc>W1!1`FMe2Tb^1N4vUhTJ?ALGDEr2Fx4E`|;C!B?6sgNN&8e~AV2zcvBN01}C9x)1tt z>Vh>EzGs@dBObr<$C15}GX1w2sLSKE=+tlc*E5&=Y3-G8r-`w-PA|_b7kxLhxhab` ztN4&4T;#gVtVTGXR-h+U7`N$y4ZexfeqM}?RtFFNZOOMkG&>dh zF$*USXp#lke2+aex~bNP1n58z=t&ettvdGnc-WY)r_EWk>Q9ZGn{W8p4@^(H99I80 zyqn2~w+%S+6GS3CdYZ0L2I@GFt6Q|~(tE(CW4@j`d*R9r8awxp(+$o(ycT@@)oHIS z^TzdU{o%Yhr%zRXeW{clWNVxOmIIO4Kw;FfU6)=T4;wXM^2`M*H<&vF-gu7|a)WJ_ zf8UgS3$8rh&p@HXG7_QlE7N=P0$Sh;@pmbdMlITQ?%99H$O%(s|Mtfg+dUQa-F@qK zK}22N_+9VCucyG}rxbO^U${`q-Zx{?oHEOT!qBu$ryl)=j{f?`c`G;hzGK?}FA|UT z**bsRN3CR{cS!X$eRHjUi`MLh$-6Yb!q&4Om8-!*uK~lyPo2BM?&(`SuPeaD#ga)) z*f`+wKd&hp-LYf479S3p=s{Gz053#T7`ABNt>35Prp~v1SI*)4fQS?=Zr%JKfgL_`I8uROO?iLyAK#W`5ikK=cBzg%^BU(6ds^K+qW+fYkZ~E z=6*S-e>WO8f52Mm+EW(b8I`6T`g}I0@#x@aoG)I>)Eh4N{q(WqFhbfT{xEoC31FErSK@$%QGVSPIqH)+PK7XqE0RIPf< zYBWIGzdO);;e>vzK>xi4NY{KlvF0yY^u@5=?QnFb>5E5*K&X!eYh!z-m525OTKqPl zU+WLi#{dwk!Z2vFW_&rMM{Arict5`lbpY2a&{wr>EN}Vv5c=OF`Y-_ba4N!c)4ssD zg=UxlSfNQ9BgaO3P|l&2NJ7Bv2HAF>gfKRj18J|jFg(shPV4)oqiz3`>&tJ^!niVhYX>BmVp#U zZPL_{{W`!6HF*@$)_RR>9X&mo9O=Gc=7{dbk`MSFszZUqsNX}j6K7_O?AyLs3~;!j zy>Ivb*3rapr`10U>ujk10sl{p2)XChf9T@cI}1lp2AXaI9IpE9Nw_-gFb*y(`)*JN zrTD|+nawlauz=MU`Ks;QYo z&YHKipPzO(KGc5I)M1^Cns#mg0#LN>?NKkt7ct{|w!;CIcZQ^|d%zi6&-H6Is!tv} z5aY`%_zLGXntE;pL!jf}#8)_;I^axw-Dcx!VsBq@#=mWR+PmpT_JujGn=!JdDQ4gI z&OY@R;R9qXx{o~fiUDn&-6!>%jqgUGxBTtiYl}0E9fE-mRKs{j3b|7HDKX2Tpn89M+4o z%%B!^n~m)APP&yU`;#jkwY!ndYqd8rQj?>7%oct7NhhNZJHL7b;2rxSnQ7M{(;G?v zy{b6pIirUX&-viYCmy=0`|w+S<$AM0pBr4}rXM@FE5v^Fj8V<$KGgtUtZ3Eqv!6~h zK&HDaxtZv=WWuLCTdI`pJN22k$ZE&c;zk6|0_SHOKNKJCzWLX$26iw+_nTyWIt|cR zqD`L>Kg7Qa_gjp;UGU^Y+TnyqZ}X*7KI`7J^v5d&U>Xog4BPh|^+V`;SGI2xeO;1& zBJD_0w7<5h&KWnLqft|X`PULa zKx<&sq2H)!%MUj{?WuinJ>&S{#F!w54fDSKq>E{DLg_jdXu`(;5*Rsop&R|Pbj|t{ zoyH;kgy=wr4f7`r>)y;b@=XRl8vgCP^}CvyY-72s&df+lJs2P9Z@*zaoBwWB9Q{fK zZ06OlZLeWS{aPJsd}Y;$RB9ig^M{jnhkIME{bkapJ?RESGlt$P@~j&`>bG_G!DD|| zw81{5k=f;K@-H8qPdk3(KzwwFo7wMkCJyWIzw7|fMU6z+qI3U|-_BjN)j9rlqpPb1 zOjPHd1@(goapArWo0m?<22`sLXA&Cp_^nG0P5m0T?=@uH4-3|qIRzfedv~tw#p7$o zj^nwQgt&+R7xOjqCyyS`rKR$JJShev&@)iC>eB!7uV*e^XYS+^mVD{K+X?X6r&$-% zkER|zn6x)0JiyIr!;%>jKl_M%2&;*)<6B*?D_|Fv3KN`XA2n&_qBV@2N5J;TU1{g; z-OG7YiT8ax#H0BaP9DaCPzU!X?v33U>g#N|VcDE-M-S}Y2C;K>(8WE@v$yDo z#~Scp1)KTx$D2CwDnR;bz5Vo)oRkp1CoU=?#LwMMvu??p@4p<P@A%u-_aAk|8e$w{2_|fYuEp|apRvG)~#N(e9`>bKYllU z)X@GtI<~@7u>aX3pmn@Z4v^@gncvPm`wjkd6rOjQJng3$GiS}3Ipe1vrhGeb?5Ix% z_3hEAjVWHM@LyA>Od#Wkv@0I5F>2AKLzfj2JoM^UppVGN}JYJ-T#g OZHhxkcrK<%ivK@Ah(#R$ literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/fitz/apps/macosx/macpdf.c b/rosapps/smartpdf/fitz/apps/macosx/macpdf.c new file mode 100644 index 00000000000..90197cb5706 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/macosx/macpdf.c @@ -0,0 +1,438 @@ +#include + +#include +#include +#include "pdfapp.h" + +#define gDefaultFilename "/Users/giles/projects/ghostscript/tiger.pdf" + +#define kViewClassID CFSTR("com.artofcode.ghostpdf.View") +#define kViewPrivate 'MU_v' + +/* the pdfapp abstraction currently uses magic callbacks, so we have + to use a a global state for our own data, or subclass pdfapp_t and + do a lot of casting */ + +/* pdfapp callbacks - error handling */ +void winwarn(pdfapp_t *pdf, char *msg) +{ + fprintf(stderr, "ghostpdf warning: %s\n", msg); +} + +void winerror(pdfapp_t *pdf, char *msg) +{ + fprintf(stderr, "ghostpdf error: %s\n", msg); + exit(1); +} + +/* pdfapp callbacks - drawing */ + +void wintitle(pdfapp_t *pdf, char *title) +{ + /* set new document title */ +} + +void winresize(pdfapp_t *pdf, int w, int h) +{ + /* pdfapp as been asked to shrinkwrap the document image; + we're called to actually apply the new window size. */ +} + +void winconvert(pdfapp_t *pdf, fz_pixmap *image) +{ + /* notification that page drawing is complete */ + /* do nothing */ +} + +void winrepaint(pdfapp_t *pdf) +{ + /* image needs repainting */ + HIViewSetNeedsDisplay((HIViewRef)pdf->userdata, true); +} + +char* winpassword(pdfapp_t *pdf, char *filename) +{ + /* prompt user for document password */ + return NULL; +} + +void winopenuri(pdfapp_t *pdf, char *s) +{ + /* user clicked on an external uri */ + /* todo: launch browser and/or open a new window if it's a PDF */ +} + +void wincursor(pdfapp_t *pdf, int curs) +{ + /* cursor status change notification */ +} + +void windocopy(pdfapp_t *pdf) +{ + /* user selected some text; copy it to the clipboard */ +} + +static OSStatus +view_construct(EventRef inEvent) +{ + OSStatus err; + pdfapp_t *pdf; + + pdf = (pdfapp_t *)malloc(sizeof(pdfapp_t)); + require_action(pdf != NULL, CantMalloc, err = memFullErr); + + pdfapp_init(pdf); + + err = GetEventParameter(inEvent, kEventParamHIObjectInstance, + typeHIObjectRef, NULL, sizeof(HIObjectRef), NULL, + (HIObjectRef *)&pdf->userdata); + require_noerr(err, ParameterMissing); + err = SetEventParameter(inEvent, kEventParamHIObjectInstance, + typeVoidPtr, sizeof(pdfapp_t *), &pdf); + + ParameterMissing: + if (err != noErr) + free(pdf); + + CantMalloc: + return err; +} + +static OSStatus +view_destruct(EventRef inEvent, pdfapp_t *pdf) +{ + pdfapp_close(pdf); + free(pdf); + return noErr; +} + +static OSStatus +view_initialize(EventHandlerCallRef inCallRef, EventRef inEvent, + pdfapp_t *pdf) +{ + OSStatus err; + HIRect bounds; + HIViewRef view = (HIViewRef)pdf->userdata; + + err = CallNextEventHandler(inCallRef, inEvent); + require_noerr(err, TroubleInSuperClass); + + HIViewGetBounds (view, &bounds); + pdf->scrw = bounds.size.width; + pdf->scrh = bounds.size.height; + + pdfapp_open(pdf, gDefaultFilename); + + TroubleInSuperClass: + return err; +} + +static void +cgcontext_set_rgba(CGContextRef ctx, unsigned int rgba) +{ + const double norm = 1.0 / 255; + CGContextSetRGBFillColor(ctx, + ((rgba >> 24) & 0xff) * norm, + ((rgba >> 16) & 0xff) * norm, + ((rgba >> 8) & 0xff) * norm, + (rgba & 0xff) * norm); +} + +static void +draw_rect(CGContextRef ctx, double x0, double y0, double x1, double y1, + unsigned int rgba) +{ + HIRect rect; + + cgcontext_set_rgba(ctx, rgba); + rect.origin.x = x0; + rect.origin.y = y0; + rect.size.width = x1 - x0; + rect.size.height = y1 - y0; + CGContextFillRect(ctx, rect); +} + +static OSStatus +view_draw(EventRef inEvent, pdfapp_t *pdf) +{ + OSStatus err; + CGContextRef gc; + CGDataProviderRef provider; + CGImageRef image; + CGColorSpaceRef colorspace; + CGRect rect; + + err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, + NULL, sizeof(CGContextRef), NULL, &gc); + require_noerr(err, cleanup); + + colorspace = CGColorSpaceCreateDeviceRGB(); + provider = CGDataProviderCreateWithData(NULL, pdf->image->samples, + pdf->image->w * pdf->image->h * 4, + NULL); + image = CGImageCreate(pdf->image->w, pdf->image->h, + 8, 32, pdf->image->w * 4, + colorspace, kCGImageAlphaNoneSkipFirst, provider, + NULL, 0, kCGRenderingIntentDefault); + + rect.origin.x = 0; + rect.origin.y = 0; + rect.size.width = pdf->image->w; + rect.size.height = pdf->image->h; + HIViewDrawCGImage(gc, &rect, image); + + CGColorSpaceRelease(colorspace); + CGDataProviderRelease(provider); + + cleanup: + return err; +} + +static OSStatus +view_get_data(EventRef inEvent, pdfapp_t *pdf) +{ + OSStatus err; + OSType tag; + Ptr ptr; + Size outSize; + + /* Probably could use a bit more error checking here, for type + and size match. Also, just returning a viewctx seems a + little hacky. */ + err = GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration, + NULL, sizeof(OSType), NULL, &tag); + require_noerr(err, ParameterMissing); + + err = GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr, + NULL, sizeof(Ptr), NULL, &ptr); + + if (tag == kViewPrivate) { + *((pdfapp_t **)ptr) = pdf; + outSize = sizeof(pdfapp_t *); + } else + err = errDataNotSupported; + + if (err == noErr) + err = SetEventParameter(inEvent, kEventParamControlDataBufferSize, typeLongInteger, + sizeof(Size), &outSize); + + ParameterMissing: + return err; +} + +static OSStatus +view_set_data(EventRef inEvent, pdfapp_t *pdf) +{ + OSStatus err; + Ptr ptr; + OSType tag; + + err = GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration, + NULL, sizeof(OSType), NULL, &tag); + require_noerr(err, ParameterMissing); + + err = GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr, + NULL, sizeof(Ptr), NULL, &ptr); + require_noerr(err, ParameterMissing); + + /* we think we don't use this */ + err = errDataNotSupported; + + ParameterMissing: + return err; +} + +static OSStatus +view_hittest(EventRef inEvent, pdfapp_t *pdf) +{ + OSStatus err; + HIPoint where; + HIRect bounds; + ControlPartCode part; + + err = GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, + NULL, sizeof(HIPoint), NULL, &where); + require_noerr(err, ParameterMissing); + + err = HIViewGetBounds(pdf->userdata, &bounds); + require_noerr(err, ParameterMissing); + + if (CGRectContainsPoint(bounds, where)) + part = 1; + else + part = kControlNoPart; + err = SetEventParameter(inEvent, kEventParamControlPart, + typeControlPartCode, sizeof(ControlPartCode), + &part); + printf("hittest %g, %g!\n", where.x, where.y); + + ParameterMissing: + return err; +} + + +pascal OSStatus +view_handler(EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ) +{ + OSStatus err = eventNotHandledErr; + UInt32 eventClass = GetEventClass(inEvent); + UInt32 eventKind = GetEventKind(inEvent); + pdfapp_t *pdf = (pdfapp_t *)inUserData; + + switch (eventClass) { + case kEventClassHIObject: + switch (eventKind) { + case kEventHIObjectConstruct: + err = view_construct(inEvent); + break; + case kEventHIObjectInitialize: + err = view_initialize(inCallRef, inEvent, pdf); + break; + case kEventHIObjectDestruct: + err = view_destruct(inEvent, pdf); + break; + } + break; + case kEventClassControl: + switch (eventKind) { + case kEventControlInitialize: + err = noErr; + break; + case kEventControlDraw: + err = view_draw(inEvent, pdf); + break; + case kEventControlGetData: + err = view_get_data(inEvent, pdf); + break; + case kEventControlSetData: + err = view_set_data(inEvent, pdf); + break; + case kEventControlHitTest: + err = view_hittest(inEvent, pdf); + break; + /*...*/ + } + break; + } + return err; +} + +OSStatus +view_register(void) +{ + OSStatus err = noErr; + static HIObjectClassRef view_ClassRef = NULL; + + if (view_ClassRef == NULL) { + EventTypeSpec eventList[] = { + { kEventClassHIObject, kEventHIObjectConstruct }, + { kEventClassHIObject, kEventHIObjectInitialize }, + { kEventClassHIObject, kEventHIObjectDestruct }, + + { kEventClassControl, kEventControlActivate }, + { kEventClassControl, kEventControlDeactivate }, + { kEventClassControl, kEventControlDraw }, + { kEventClassControl, kEventControlHiliteChanged }, + { kEventClassControl, kEventControlHitTest }, + { kEventClassControl, kEventControlInitialize }, + { kEventClassControl, kEventControlGetData }, + { kEventClassControl, kEventControlSetData }, + }; + err = HIObjectRegisterSubclass(kViewClassID, + kHIViewClassID, + NULL, + view_handler, + GetEventTypeCount(eventList), + eventList, + NULL, + &view_ClassRef); + } + return err; +} + +OSStatus view_create( + WindowRef inWindow, + const HIRect* inBounds, + HIViewRef* outView) +{ + OSStatus err; + EventRef event; + + err = view_register(); + require_noerr(err, CantRegister); + + err = CreateEvent(NULL, kEventClassHIObject, kEventHIObjectInitialize, + GetCurrentEventTime(), 0, &event); + require_noerr(err, CantCreateEvent); + + if (inBounds != NULL) { + err = SetEventParameter(event, 'Boun', typeHIRect, sizeof(HIRect), + inBounds); + require_noerr(err, CantSetParameter); + } + + err = HIObjectCreate(kViewClassID, event, (HIObjectRef*)outView); + require_noerr(err, CantCreate); + + if (inWindow != NULL) { + HIViewRef root; + err = GetRootControl(inWindow, &root); + require_noerr(err, CantGetRootView); + err = HIViewAddSubview(root, *outView); + } + CantCreate: + CantGetRootView: + CantSetParameter: + CantCreateEvent: + ReleaseEvent(event); + CantRegister: + return err; +} + + + +int main(int argc, char *argv[]) +{ + IBNibRef nibRef; + OSStatus err; + WindowRef window; + + pdfapp_t pdf; + + fz_cpudetect(); + fz_accelerate(); + + err = view_register(); + require_noerr(err, CantRegisterView); + + err = CreateNibReference(CFSTR("main"), &nibRef); + printf("err = %d\n", (int)err); + require_noerr(err, CantGetNibRef); + + err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar")); + require_noerr(err, CantSetMenuBar); + + err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window); + require_noerr(err, CantCreateWindow); + + //openpdf(window, gDefaultFilename); + + DisposeNibReference(nibRef); + + pdfapp_init(&pdf); + pdfapp_open(&pdf, gDefaultFilename); + + ShowWindow(window); + RunApplicationEventLoop(); + + pdfapp_close(&pdf); + + CantGetNibRef: + CantSetMenuBar: + CantCreateWindow: + CantRegisterView: + + return err; +} diff --git a/rosapps/smartpdf/fitz/apps/mozilla/jri.h b/rosapps/smartpdf/fitz/apps/mozilla/jri.h new file mode 100644 index 00000000000..4a622bd20b7 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/mozilla/jri.h @@ -0,0 +1,5 @@ +/* dummy jri */ +#define jref void* +#define JRIEnv void +#define JRIGlobalRef void* +#define JRI_NewGlobalRef(e,c) 0 diff --git a/rosapps/smartpdf/fitz/apps/mozilla/moz_main.c b/rosapps/smartpdf/fitz/apps/mozilla/moz_main.c new file mode 100644 index 00000000000..4c38b78b6f7 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/mozilla/moz_main.c @@ -0,0 +1,889 @@ +#include "fitz.h" +#include "mupdf.h" + +#include +#include + +#include "npapi.h" +#include "npupp.h" + +#define PAD 5 + +#define MSG(s) MessageBox(0,s,"MuPDF Debug",MB_OK) + +typedef struct pdfmoz_s pdfmoz_t; +typedef struct page_s page_t; + +struct page_s +{ + fz_obj *ref; + fz_obj *obj; + pdf_page *page; + fz_pixmap *image; + int w, h; /* page size in units */ + int px; /* pixel height */ +}; + +struct pdfmoz_s +{ + NPP inst; + HWND hwnd; + HWND sbar; + WNDPROC winproc; + HCURSOR arrow, hand, wait; + BITMAPINFO *dibinf; + HBRUSH graybrush; + + int scrollpage; /* scrollbar -> page (n) */ + int scrollyofs; /* scrollbar -> page offset in pixels */ + + int pagecount; + page_t *pages; + + char *filename; + char *doctitle; + + pdf_xref *xref; + fz_renderer *rast; + + char error[1024]; /* empty if no error has occured */ +}; + +void pdfmoz_warn(pdfmoz_t *moz, const char *fmt, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + strcpy(moz->error, buf); + InvalidateRect(moz->hwnd, NULL, FALSE); + NPN_Status(moz->inst, moz->error); +} + +void pdfmoz_error(pdfmoz_t *moz, fz_error *error) +{ + strcpy(moz->error, error->msg); + InvalidateRect(moz->hwnd, NULL, FALSE); + NPN_Status(moz->inst, moz->error); +} + +void pdfmoz_open(pdfmoz_t *moz, char *filename) +{ + SCROLLINFO si; + fz_error *error; + fz_obj *obj; + char *password = ""; + pdf_pagetree *pages; + fz_irect bbox; + int rot; + int i; + + strcpy(moz->error, ""); + + error = fz_newrenderer(&moz->rast, pdf_devicergb, 0, 1024 * 512); + if (error) + pdfmoz_error(moz, error); + + /* + * Open PDF and load xref table + */ + + moz->filename = filename; + + error = pdf_newxref(&moz->xref); + if (error) + pdfmoz_error(moz, error); + + error = pdf_loadxref(moz->xref, filename); + if (error) + { + if (!strncmp(error->msg, "ioerror", 7)) + pdfmoz_error(moz, error); + error = pdf_repairxref(moz->xref, filename); + if (error) + pdfmoz_error(moz, error); + } + + /* + * Handle encrypted PDF files + */ + + error = pdf_decryptxref(moz->xref); + if (error) + pdfmoz_error(moz, error); + + if (moz->xref->crypt) + { + error = pdf_setpassword(moz->xref->crypt, password); + // while (error) + // { + // fz_droperror(error); + // password = winpassword(moz, filename); + // if (!password) + // exit(1); + // error = pdf_setpassword(moz->xref->crypt, password); + if (error) + pdfmoz_warn(moz, "Invalid password."); + // } + } + + /* + * Load page tree + */ + + error = pdf_loadpagetree(&pages, moz->xref); + if (error) + pdfmoz_error(moz, error); + + moz->pagecount = pdf_getpagecount(pages); + moz->pages = fz_malloc(sizeof(page_t) * moz->pagecount); + + for (i = 0; i < moz->pagecount; i++) + { + moz->pages[i].ref = fz_keepobj(pages->pref[i]); + moz->pages[i].obj = fz_keepobj(pdf_getpageobject(pages, i)); + moz->pages[i].page = nil; + moz->pages[i].image = nil; + + obj = fz_dictgets(moz->pages[i].obj, "CropBox"); + if (!obj) + obj = fz_dictgets(moz->pages[i].obj, "MediaBox"); + bbox = fz_roundrect(pdf_torect(obj)); + moz->pages[i].w = bbox.x1 - bbox.x0; + moz->pages[i].h = bbox.y1 - bbox.y0; + + rot = fz_toint(fz_dictgets(moz->pages[i].obj, "Rotate")); + if ((rot / 90) % 2) + { + int t = moz->pages[i].w; + moz->pages[i].w = moz->pages[i].h; + moz->pages[i].h = t; + } + + moz->pages[i].px = 1 + PAD; + } + + pdf_droppagetree(pages); + + /* + * Load meta information + * TODO: move this into mupdf library + */ + + obj = fz_dictgets(moz->xref->trailer, "Root"); + if (!obj) + pdfmoz_error(moz, fz_throw("syntaxerror: missing Root object")); + + error = pdf_loadindirect(&moz->xref->root, moz->xref, obj); + if (error) + pdfmoz_error(moz, error); + + obj = fz_dictgets(moz->xref->trailer, "Info"); + if (obj) + { + error = pdf_loadindirect(&moz->xref->info, moz->xref, obj); + if (error) + pdfmoz_error(moz, error); + } + + error = pdf_loadnametrees(moz->xref); + if (error) + pdfmoz_error(moz, error); + + moz->doctitle = filename; + if (strrchr(moz->doctitle, '\\')) + moz->doctitle = strrchr(moz->doctitle, '\\') + 1; + if (strrchr(moz->doctitle, '/')) + moz->doctitle = strrchr(moz->doctitle, '/') + 1; + if (moz->xref->info) + { + obj = fz_dictgets(moz->xref->info, "Title"); + if (obj) + { + error = pdf_toutf8(&moz->doctitle, obj); + if (error) + pdfmoz_error(moz, error); + } + } + + /* + * Start at first page + */ + + si.cbSize = sizeof(si); + si.fMask = SIF_POS | SIF_RANGE; // XXX | SIF_PAGE; + si.nPos = 0; + si.nMin = 0; + si.nMax = 1; + si.nPage = 1; + SetScrollInfo(moz->hwnd, SB_VERT, &si, TRUE); + + moz->scrollpage = 0; + moz->scrollyofs = 0; + + InvalidateRect(moz->hwnd, NULL, FALSE); +} + +static void decodescroll(pdfmoz_t *moz, int spos) +{ + int i, y = 0; + moz->scrollpage = 0; + moz->scrollyofs = 0; + for (i = 0; i < moz->pagecount; i++) + { + if (spos >= y && spos < y + moz->pages[i].px) + { + moz->scrollpage = i; + moz->scrollyofs = spos - y; + return; + } + y += moz->pages[i].px; + } +} + +fz_matrix pdfmoz_pagectm(pdfmoz_t *moz, int pagenum) +{ + page_t *page = moz->pages + pagenum; + fz_matrix ctm; + float zoom; + RECT rc; + + GetClientRect(moz->hwnd, &rc); + + zoom = (rc.right - rc.left) / (float) page->w; + + ctm = fz_identity(); + ctm = fz_concat(ctm, fz_translate(0, -page->page->mediabox.y1)); + ctm = fz_concat(ctm, fz_scale(zoom, -zoom)); + ctm = fz_concat(ctm, fz_rotate(page->page->rotate)); + + return ctm; +} + +void pdfmoz_loadpage(pdfmoz_t *moz, int pagenum) +{ + page_t *page = moz->pages + pagenum; + fz_error *error; + + if (page->page) + return; + + error = pdf_loadpage(&page->page, moz->xref, page->obj); + if (error) + pdfmoz_error(moz, error); +} + +void pdfmoz_drawpage(pdfmoz_t *moz, int pagenum) +{ + page_t *page = moz->pages + pagenum; + fz_error *error; + fz_matrix ctm; + fz_rect bbox; + + if (page->image) + return; + + ctm = pdfmoz_pagectm(moz, pagenum); + bbox = fz_transformaabb(ctm, page->page->mediabox); + + error = fz_rendertree(&page->image, moz->rast, page->page->tree, + ctm, fz_roundrect(bbox), 1); + if (error) + pdfmoz_error(moz, error); +} + +void pdfmoz_gotouri(pdfmoz_t *moz, fz_obj *uri) +{ + char buf[2048]; + memcpy(buf, fz_tostrbuf(uri), fz_tostrlen(uri)); + buf[fz_tostrlen(uri)] = 0; + NPN_GetURL(moz->inst, buf, "_blank"); +} + +int pdfmoz_getpagenum(pdfmoz_t *moz, fz_obj *obj) +{ + int oid = fz_tonum(obj); + int i; + for (i = 0; i < moz->pagecount; i++) + if (fz_tonum(moz->pages[i].ref) == oid) + return i; + return 0; +} + +void pdfmoz_gotopage(pdfmoz_t *moz, fz_obj *obj) +{ + int oid = fz_tonum(obj); + int i, y = 0; + for (i = 0; i < moz->pagecount; i++) + { + if (fz_tonum(moz->pages[i].ref) == oid) + { + SetScrollPos(moz->hwnd, SB_VERT, y, TRUE); + InvalidateRect(moz->hwnd, NULL, FALSE); + return; + } + y += moz->pages[i].px; + } +} + +void pdfmoz_onmouse(pdfmoz_t *moz, int x, int y, int click) +{ + char buf[512]; + pdf_link *link; + fz_matrix ctm; + fz_point p; + int pi; + int py; + + if (!moz->pages) + return; + + pi = moz->scrollpage; + py = -moz->scrollyofs; + while (pi < moz->pagecount) + { + if (!moz->pages[pi].image) + return; + if (y > py && y < moz->pages[pi].px) + break; + py += moz->pages[pi].px; + pi ++; + } + if (pi == moz->pagecount) + return; + + p.x = x + moz->pages[pi].image->x; + p.y = y + moz->pages[pi].image->y - py; + + ctm = pdfmoz_pagectm(moz, pi); + ctm = fz_invertmatrix(ctm); + + p = fz_transformpoint(ctm, p); + + for (link = moz->pages[pi].page->links; link; link = link->next) + { + if (p.x >= link->rect.x0 && p.x <= link->rect.x1) + if (p.y >= link->rect.y0 && p.y <= link->rect.y1) + break; + } + + if (link) + { + SetCursor(moz->hand); + if (click) + { + if (fz_isstring(link->dest)) + pdfmoz_gotouri(moz, link->dest); + if (fz_isindirect(link->dest)) + pdfmoz_gotopage(moz, link->dest); + return; + } + else + { + if (fz_isstring(link->dest)) + { + memcpy(buf, fz_tostrbuf(link->dest), fz_tostrlen(link->dest)); + buf[fz_tostrlen(link->dest)] = 0; + NPN_Status(moz->inst, buf); + } + else if (fz_isindirect(link->dest)) + { + sprintf(buf, "Go to page %d", + pdfmoz_getpagenum(moz, link->dest) + 1); + NPN_Status(moz->inst, buf); + } + else + NPN_Status(moz->inst, "Say what?"); + } + } + else + { + sprintf(buf, "Page %d of %d", moz->scrollpage + 1, moz->pagecount); + NPN_Status(moz->inst, buf); + SetCursor(moz->arrow); + } +} + +static void drawimage(HDC hdc, pdfmoz_t *moz, fz_pixmap *image, int yofs) +{ + int bmpstride = ((image->w * 3 + 3) / 4) * 4; + char *bmpdata = fz_malloc(image->h * bmpstride); + int x, y; + + if (!bmpdata) + return; + + for (y = 0; y < image->h; y++) + { + char *p = bmpdata + y * bmpstride; + char *s = image->samples + y * image->w * 4; + for (x = 0; x < image->w; x++) + { + p[x * 3 + 0] = s[x * 4 + 3]; + p[x * 3 + 1] = s[x * 4 + 2]; + p[x * 3 + 2] = s[x * 4 + 1]; + } + } + + moz->dibinf->bmiHeader.biWidth = image->w; + moz->dibinf->bmiHeader.biHeight = -image->h; + moz->dibinf->bmiHeader.biSizeImage = image->h * bmpstride; + SetDIBitsToDevice(hdc, + 0, /* destx */ + yofs, /* desty */ + image->w, /* destw */ + image->h, /* desth */ + 0, /* srcx */ + 0, /* srcy */ + 0, /* startscan */ + image->h, /* numscans */ + bmpdata, /* pBits */ + moz->dibinf, /* pInfo */ + DIB_RGB_COLORS /* color use flag */ + ); + + fz_free(bmpdata); +} + +LRESULT CALLBACK +MozWinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + pdfmoz_t *moz = (pdfmoz_t*) GetWindowLongPtr(hwnd, GWLP_USERDATA); + char buf[256]; + + int x = (signed short) LOWORD(lParam); + int y = (signed short) HIWORD(lParam); + int i, h; + + SCROLLINFO si; + PAINTSTRUCT ps; + HDC hdc; + RECT rc; + RECT pad; + WORD sendmsg; + float zoom; + + GetClientRect(hwnd, &rc); + h = rc.bottom - rc.top; + + if (strlen(moz->error)) + { + if (msg == WM_PAINT) + { + hdc = BeginPaint(hwnd, &ps); + FillRect(hdc, &rc, GetStockBrush(WHITE_BRUSH)); + rc.top += 10; + rc.bottom -= 10; + rc.left += 10; + rc.right -= 10; + DrawText(hdc, moz->error, strlen(moz->error), &rc, 0); + // DT_SINGLELINE|DT_CENTER|DT_VCENTER); + EndPaint(hwnd, &ps); + } + if (msg == WM_MOUSEMOVE) + { + SetCursor(moz->arrow); + } + return 0; + } + + switch (msg) + { + + case WM_PAINT: + GetClientRect(moz->hwnd, &rc); + + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(hwnd, SB_VERT, &si); + + decodescroll(moz, si.nPos); + + /* evict out-of-range images and pages */ + for (i = 0; i < moz->pagecount; i++) + { + if (i < moz->scrollpage - 2 || i > moz->scrollpage + 6) + { + if (moz->pages[i].page) + { + pdf_droppage(moz->pages[i].page); + moz->pages[i].page = nil; + } + } + if (i < moz->scrollpage - 1 || i > moz->scrollpage + 3) + { + if (moz->pages[i].image) + { + fz_droppixmap(moz->pages[i].image); + moz->pages[i].image = nil; + } + } + } + + i = moz->scrollpage; + + pdfmoz_loadpage(moz, i); + if (moz->error[0]) return 0; + + pdfmoz_drawpage(moz, i); + if (moz->error[0]) return 0; + + y = -moz->scrollyofs; + while (y < h && i < moz->pagecount) + { + pdfmoz_loadpage(moz, i); + if (moz->error[0]) return 0; + pdfmoz_drawpage(moz, i); + if (moz->error[0]) return 0; + y += moz->pages[i].image->h; + i ++; + } + + hdc = BeginPaint(hwnd, &ps); + + pad.left = rc.left; + pad.right = rc.right; + + i = moz->scrollpage; + y = -moz->scrollyofs; + while (y < h && i < moz->pagecount) + { + drawimage(hdc, moz, moz->pages[i].image, y); + y += moz->pages[i].image->h; + i ++; + + pad.top = y; + pad.bottom = y + PAD; + FillRect(hdc, &pad, moz->graybrush); + y += PAD; + } + + if (y < h) + { + pad.top = y; + pad.bottom = h; + FillRect(hdc, &pad, moz->graybrush); + } + + EndPaint(hwnd, &ps); + + return 0; + + case WM_SIZE: + ShowScrollBar(moz->hwnd, SB_VERT, TRUE); + GetClientRect(moz->hwnd, &rc); + + si.cbSize = sizeof(si); + si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE; + si.nPos = 0; + si.nMin = 0; + si.nMax = 0; + // si.nPage = MAX(30, rc.bottom - rc.top - 30); + si.nPage = rc.bottom - rc.top; + + for (i = 0; i < moz->pagecount; i++) + { + zoom = (rc.right - rc.left) / (float) moz->pages[i].w; + moz->pages[i].px = zoom * moz->pages[i].h + PAD; + + if (moz->scrollpage == i) + { + si.nPos = si.nMax; + if (moz->pages[i].image) + { + si.nPos += + moz->pages[i].px * + moz->scrollyofs / + moz->pages[i].image->h + 1; + } + } + + if (moz->pages[i].image) + { + fz_droppixmap(moz->pages[i].image); + moz->pages[i].image = nil; + } + + si.nMax += moz->pages[i].px; + } + + si.nMax --; + + SetScrollInfo(moz->hwnd, SB_VERT, &si, TRUE); + + break; + + case WM_MOUSEMOVE: + pdfmoz_onmouse(moz, x, y, 0); + break; + + case WM_LBUTTONDOWN: + SetFocus(hwnd); + pdfmoz_onmouse(moz, x, y, 1); + break; + + case WM_VSCROLL: + + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(hwnd, SB_VERT, &si); + + switch (LOWORD(wParam)) + { + case SB_BOTTOM: si.nPos = si.nMax; break; + case SB_TOP: si.nPos = 0; break; + case SB_LINEUP: si.nPos -= 50; break; + case SB_LINEDOWN: si.nPos += 50; break; + case SB_PAGEUP: si.nPos -= si.nPage; break; + case SB_PAGEDOWN: si.nPos += si.nPage; break; + case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; + case SB_THUMBPOSITION: si.nPos = si.nTrackPos; break; + } + + si.fMask = SIF_POS; + si.nPos = MAX(0, MIN(si.nPos, si.nMax)); + SetScrollInfo(hwnd, SB_VERT, &si, TRUE); + + InvalidateRect(moz->hwnd, NULL, FALSE); + + decodescroll(moz, si.nPos); + sprintf(buf, "Page %d of %d", moz->scrollpage + 1, moz->pagecount); + NPN_Status(moz->inst, buf); + + return 0; + + case WM_MOUSEWHEEL: + if ((signed short)HIWORD(wParam) > 0) + SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0); + else + SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0); + break; + + case WM_KEYDOWN: + sendmsg = 0xFFFF; + + switch (wParam) + { + case VK_UP: sendmsg = SB_LINEUP; break; + case VK_PRIOR: sendmsg = SB_PAGEUP; break; + case ' ': + case VK_NEXT: sendmsg = SB_PAGEDOWN; break; + case '\r': + case VK_DOWN: sendmsg = SB_LINEDOWN; break; + case VK_HOME: sendmsg = SB_TOP; break; + case VK_END: sendmsg = SB_BOTTOM; break; + } + + if (sendmsg != 0xFFFF) + SendMessage(hwnd, WM_VSCROLL, MAKELONG(sendmsg, 0), 0); + + /* ick! someone eats events instead of bubbling... not my fault! */ + + break; + + default: + break; + + } + + return moz->winproc(hwnd, msg, wParam, lParam); +} + +NPError +NPP_New(NPMIMEType mime, NPP inst, uint16 mode, + int16 argc, char *argn[], char *argv[], NPSavedData *saved) +{ + pdfmoz_t *moz; + + //MSG("NPP_New"); + + moz = fz_malloc(sizeof(pdfmoz_t)); + if (!moz) + return NPERR_OUT_OF_MEMORY_ERROR; + + memset(moz, 0, sizeof(pdfmoz_t)); + + sprintf(moz->error, "MuPDF is loading the file..."); + + moz->inst = inst; + + moz->arrow = LoadCursor(NULL, IDC_ARROW); + moz->hand = LoadCursor(NULL, IDC_HAND); + moz->wait = LoadCursor(NULL, IDC_WAIT); + + moz->dibinf = fz_malloc(sizeof(BITMAPINFO) + 12); + if (!moz->dibinf) + return NPERR_OUT_OF_MEMORY_ERROR; + + moz->dibinf->bmiHeader.biSize = sizeof(moz->dibinf->bmiHeader); + moz->dibinf->bmiHeader.biPlanes = 1; + moz->dibinf->bmiHeader.biBitCount = 24; + moz->dibinf->bmiHeader.biCompression = BI_RGB; + moz->dibinf->bmiHeader.biXPelsPerMeter = 2834; + moz->dibinf->bmiHeader.biYPelsPerMeter = 2834; + moz->dibinf->bmiHeader.biClrUsed = 0; + moz->dibinf->bmiHeader.biClrImportant = 0; + moz->dibinf->bmiHeader.biClrUsed = 0; + + moz->graybrush = CreateSolidBrush(RGB(0x70,0x70,0x70)); + + inst->pdata = moz; + + return NPERR_NO_ERROR; +} + +NPError +NPP_Destroy(NPP inst, NPSavedData **saved) +{ + pdfmoz_t *moz = inst->pdata; + int i; + + //MSG("NPP_Destroy"); + + inst->pdata = NULL; + + DeleteObject(moz->graybrush); + + DestroyCursor(moz->arrow); + DestroyCursor(moz->hand); + DestroyCursor(moz->wait); + + fz_free(moz->dibinf); + + for (i = 0; i < moz->pagecount; i++) + { + if (moz->pages[i].obj) + fz_dropobj(moz->pages[i].obj); + if (moz->pages[i].page) + pdf_droppage(moz->pages[i].page); + if (moz->pages[i].image) + fz_droppixmap(moz->pages[i].image); + } + + fz_free(moz->pages); + + if (moz->xref) + { + if (moz->xref->store) + { + pdf_dropstore(moz->xref->store); + moz->xref->store = nil; + } + + pdf_closexref(moz->xref); + } + + fz_free(moz); + + return NPERR_NO_ERROR; +} + +NPError +NPP_SetWindow(NPP inst, NPWindow *npwin) +{ + pdfmoz_t *moz = inst->pdata; + + if (moz->hwnd != npwin->window) + { + moz->hwnd = npwin->window; + SetWindowLongPtr(moz->hwnd, GWLP_USERDATA, (LONG_PTR)moz); + moz->winproc = (WNDPROC) + SetWindowLongPtr(moz->hwnd, GWLP_WNDPROC, (LONG_PTR)MozWinProc); + } + + SetFocus(moz->hwnd); + + return NPERR_NO_ERROR; +} + +NPError +NPP_NewStream(NPP inst, NPMIMEType type, + NPStream* stream, NPBool seekable, + uint16* stype) +{ + //MSG("NPP_NewStream"); + *stype = NP_ASFILE; + return NPERR_NO_ERROR; +} + +NPError +NPP_DestroyStream(NPP inst, NPStream* stream, NPReason reason) +{ + //MSG("NPP_DestroyStream"); + return NPERR_NO_ERROR; +} + +int32 +NPP_WriteReady(NPP inst, NPStream* stream) +{ + //MSG("NPP_WriteReady"); + return 2147483647; +} + +int32 +NPP_Write(NPP inst, NPStream* stream, int32 offset, int32 len, void* buffer) +{ + //MSG("NPP_Write"); + return len; +} + +void +NPP_StreamAsFile(NPP inst, NPStream* stream, const char* fname) +{ + pdfmoz_t *moz = inst->pdata; + //MSG("NPP_StreamAsFile"); + pdfmoz_open(moz, (char*)fname); +} + +void +NPP_Print(NPP inst, NPPrint* platformPrint) +{ + MSG("Sorry, printing is not supported."); +} + +int16 +NPP_HandleEvent(NPP inst, void* event) +{ + MSG("handle event\n"); + return 0; +} + +void +NPP_URLNotify(NPP inst, const char* url, + NPReason reason, void* notifyData) +{ + MSG("notify url\n"); +} + +NPError +NPP_GetValue(void* inst, NPPVariable variable, void *value) +{ + return NPERR_NO_ERROR; +} + +NPError +NPP_SetValue(void* inst, NPNVariable variable, void *value) +{ + return NPERR_NO_ERROR; +} + +void* NPP_GetJavaClass(void) +{ + return 0; +} + +NPError +NPP_Initialize(void) +{ + // MSG("NPP_Initialize"); + return NPERR_NO_ERROR; +} + +void +NPP_Shutdown(void) +{ + // MSG("NPP_Shutdown"); +} + + diff --git a/rosapps/smartpdf/fitz/apps/mozilla/moz_winres.rc b/rosapps/smartpdf/fitz/apps/mozilla/moz_winres.rc new file mode 100644 index 00000000000..ad37bf2b84d --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/mozilla/moz_winres.rc @@ -0,0 +1,21 @@ +// +// MuPDF Plugin description +// + +1 VERSIONINFO + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "ProductName", "MuPDF Plug-in\0" + VALUE "OriginalFilename", "npmupdf.dll\0" + VALUE "FileDescription", "The MuPDF plugin allows you to browse PDF files with a simple light-weight scrolling interface.\0" + VALUE "MIMEType", "application/pdf|application/x-mupdf\0" + VALUE "FileExtents", "pdf|foo" + VALUE "FileOpenName", "Acrobat PDF File|Acrobat PDF File" + END + END +END + diff --git a/rosapps/smartpdf/fitz/apps/mozilla/npapi.h b/rosapps/smartpdf/fitz/apps/mozilla/npapi.h new file mode 100644 index 00000000000..5cd11c83f58 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/mozilla/npapi.h @@ -0,0 +1,469 @@ +/* -*- Mode: C; tab-width: 4; -*- */ +/* + * npapi.h $Revision: 1.88 $ + * Netscape client plug-in API spec + */ + +#ifndef _NPAPI_H_ +#define _NPAPI_H_ + +#include "jri.h" /* Java Runtime Interface */ + +#ifdef _WINDOWS +# ifndef XP_WIN +# define XP_WIN 1 +# endif /* XP_WIN */ +#endif /* _WINDOWS */ + +#ifdef __MWERKS__ +# define _declspec __declspec +# ifdef macintosh +# ifndef XP_MAC +# define XP_MAC 1 +# endif /* XP_MAC */ +# endif /* macintosh */ +# ifdef __INTEL__ +# undef NULL +# ifndef XP_WIN +# define XP_WIN 1 +# endif /* __INTEL__ */ +# endif /* XP_PC */ +#endif /* __MWERKS__ */ + +#ifdef XP_MAC + #include + #include +#endif + +#ifdef XP_UNIX + #include + #include +#endif + + +/*----------------------------------------------------------------------*/ +/* Plugin Version Constants */ +/*----------------------------------------------------------------------*/ + +#define NP_VERSION_MAJOR 0 +#define NP_VERSION_MINOR 11 + + + +/*----------------------------------------------------------------------*/ +/* Definition of Basic Types */ +/*----------------------------------------------------------------------*/ + +#ifndef _UINT16 +typedef unsigned short uint16; +#endif +#ifndef _UINT32 +#if defined(__alpha) +typedef unsigned int uint32; +#else /* __alpha */ +typedef unsigned long uint32; +#endif /* __alpha */ +#endif +#ifndef _INT16 +typedef short int16; +#endif +#ifndef _INT32 +#if defined(__alpha) +typedef int int32; +#else /* __alpha */ +typedef long int32; +#endif /* __alpha */ +#endif + +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef NULL +#define NULL (0L) +#endif + +typedef unsigned char NPBool; +typedef int16 NPError; +typedef int16 NPReason; +typedef char* NPMIMEType; + + + +/*----------------------------------------------------------------------*/ +/* Structures and definitions */ +/*----------------------------------------------------------------------*/ + +#ifdef XP_MAC +#pragma options align=mac68k +#endif + +/* + * NPP is a plug-in's opaque instance handle + */ +typedef struct _NPP +{ + void* pdata; /* plug-in private data */ + void* ndata; /* netscape private data */ +} NPP_t; + +typedef NPP_t* NPP; + + +typedef struct _NPStream +{ + void* pdata; /* plug-in private data */ + void* ndata; /* netscape private data */ + const char* url; + uint32 end; + uint32 lastmodified; + void* notifyData; +} NPStream; + + +typedef struct _NPByteRange +{ + int32 offset; /* negative offset means from the end */ + uint32 length; + struct _NPByteRange* next; +} NPByteRange; + + +typedef struct _NPSavedData +{ + int32 len; + void* buf; +} NPSavedData; + + +typedef struct _NPRect +{ + uint16 top; + uint16 left; + uint16 bottom; + uint16 right; +} NPRect; + + +#ifdef XP_UNIX +/* + * Unix specific structures and definitions + */ + +/* + * Callback Structures. + * + * These are used to pass additional platform specific information. + */ +enum { + NP_SETWINDOW = 1, + NP_PRINT +}; + +typedef struct +{ + int32 type; +} NPAnyCallbackStruct; + +typedef struct +{ + int32 type; + Display* display; + Visual* visual; + Colormap colormap; + unsigned int depth; +} NPSetWindowCallbackStruct; + +typedef struct +{ + int32 type; + FILE* fp; +} NPPrintCallbackStruct; + +#endif /* XP_UNIX */ + +/* + * List of variable names for which NPP_GetValue shall be implemented + */ +typedef enum { + NPPVpluginNameString = 1, + NPPVpluginDescriptionString, + NPPVpluginWindowBool, + NPPVpluginTransparentBool +} NPPVariable; + +/* + * List of variable names for which NPN_GetValue is implemented by Mozilla + */ +typedef enum { + NPNVxDisplay = 1, + NPNVxtAppContext, + NPNVnetscapeWindow, + NPNVjavascriptEnabledBool, + NPNVasdEnabledBool, + NPNVisOfflineBool +} NPNVariable; + +/* + * The type of a NPWindow - it specifies the type of the data structure + * returned in the window field. + */ +typedef enum { + NPWindowTypeWindow = 1, + NPWindowTypeDrawable +} NPWindowType; + +typedef struct _NPWindow +{ + void* window; /* Platform specific window handle */ + int32 x; /* Position of top left corner relative */ + int32 y; /* to a netscape page. */ + uint32 width; /* Maximum window size */ + uint32 height; + NPRect clipRect; /* Clipping rectangle in port coordinates */ + /* Used by MAC only. */ +#ifdef XP_UNIX + void * ws_info; /* Platform-dependent additonal data */ +#endif /* XP_UNIX */ + NPWindowType type; /* Is this a window or a drawable? */ +} NPWindow; + + +typedef struct _NPFullPrint +{ + NPBool pluginPrinted; /* Set TRUE if plugin handled fullscreen */ + /* printing */ + NPBool printOne; /* TRUE if plugin should print one copy */ + /* to default printer */ + void* platformPrint; /* Platform-specific printing info */ +} NPFullPrint; + +typedef struct _NPEmbedPrint +{ + NPWindow window; + void* platformPrint; /* Platform-specific printing info */ +} NPEmbedPrint; + +typedef struct _NPPrint +{ + uint16 mode; /* NP_FULL or NP_EMBED */ + union + { + NPFullPrint fullPrint; /* if mode is NP_FULL */ + NPEmbedPrint embedPrint; /* if mode is NP_EMBED */ + } print; +} NPPrint; + +#ifdef XP_MAC +typedef EventRecord NPEvent; +#elif defined(XP_WIN) +typedef struct _NPEvent +{ + uint16 event; + uint32 wParam; + uint32 lParam; +} NPEvent; +#elif defined (XP_UNIX) +typedef XEvent NPEvent; +#else +typedef void* NPEvent; +#endif /* XP_MAC */ + +#ifdef XP_MAC +typedef RgnHandle NPRegion; +#elif defined(XP_WIN) +typedef HRGN NPRegion; +#elif defined(XP_UNIX) +typedef Region NPRegion; +#else +typedef void *NPRegion; +#endif /* XP_MAC */ + +#ifdef XP_MAC +/* + * Mac-specific structures and definitions. + */ + +typedef struct NP_Port +{ + CGrafPtr port; /* Grafport */ + int32 portx; /* position inside the topmost window */ + int32 porty; +} NP_Port; + +/* + * Non-standard event types that can be passed to HandleEvent + */ +#define getFocusEvent (osEvt + 16) +#define loseFocusEvent (osEvt + 17) +#define adjustCursorEvent (osEvt + 18) + +#endif /* XP_MAC */ + + +/* + * Values for mode passed to NPP_New: + */ +#define NP_EMBED 1 +#define NP_FULL 2 + +/* + * Values for stream type passed to NPP_NewStream: + */ +#define NP_NORMAL 1 +#define NP_SEEK 2 +#define NP_ASFILE 3 +#define NP_ASFILEONLY 4 + +#define NP_MAXREADY (((unsigned)(~0)<<1)>>1) + +#ifdef XP_MAC +#pragma options align=reset +#endif + + +/*----------------------------------------------------------------------*/ +/* Error and Reason Code definitions */ +/*----------------------------------------------------------------------*/ + +/* + * Values of type NPError: + */ +#define NPERR_BASE 0 +#define NPERR_NO_ERROR (NPERR_BASE + 0) +#define NPERR_GENERIC_ERROR (NPERR_BASE + 1) +#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2) +#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3) +#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4) +#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5) +#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6) +#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7) +#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8) +#define NPERR_INVALID_PARAM (NPERR_BASE + 9) +#define NPERR_INVALID_URL (NPERR_BASE + 10) +#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11) +#define NPERR_NO_DATA (NPERR_BASE + 12) +#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13) + +/* + * Values of type NPReason: + */ +#define NPRES_BASE 0 +#define NPRES_DONE (NPRES_BASE + 0) +#define NPRES_NETWORK_ERR (NPRES_BASE + 1) +#define NPRES_USER_BREAK (NPRES_BASE + 2) + +/* + * Don't use these obsolete error codes any more. + */ +#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR +#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR +#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK + +/* + * Version feature information + */ +#define NPVERS_HAS_STREAMOUTPUT 8 +#define NPVERS_HAS_NOTIFICATION 9 +#define NPVERS_HAS_LIVECONNECT 9 +#define NPVERS_WIN16_HAS_LIVECONNECT 9 +#define NPVERS_68K_HAS_LIVECONNECT 11 +#define NPVERS_HAS_WINDOWLESS 11 + + +/*----------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------*/ + +#if defined(_WINDOWS) && !defined(WIN32) +#define NP_LOADDS _loadds +#else +#define NP_LOADDS +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * NPP_* functions are provided by the plugin and called by the navigator. + */ + +#ifdef XP_UNIX +char* NPP_GetMIMEDescription(void); +#endif /* XP_UNIX */ + +NPError NPP_Initialize(void); +void NPP_Shutdown(void); +NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, + uint16 mode, int16 argc, char* argn[], + char* argv[], NPSavedData* saved); +NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save); +NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window); +NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, + NPStream* stream, NPBool seekable, + uint16* stype); +NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream, + NPReason reason); +int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream); +int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset, + int32 len, void* buffer); +void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream, + const char* fname); +void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint); +int16 NPP_HandleEvent(NPP instance, void* event); +void NP_LOADDS NPP_URLNotify(NPP instance, const char* url, + NPReason reason, void* notifyData); +jref NP_LOADDS NPP_GetJavaClass(void); +NPError NPP_GetValue(void *instance, NPPVariable variable, + void *value); +NPError NPP_SetValue(void *instance, NPNVariable variable, + void *value); + +/* + * NPN_* functions are provided by the navigator and called by the plugin. + */ + +void NPN_Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor); +NPError NPN_GetURLNotify(NPP instance, const char* url, + const char* target, void* notifyData); +NPError NPN_GetURL(NPP instance, const char* url, + const char* target); +NPError NPN_PostURLNotify(NPP instance, const char* url, + const char* target, uint32 len, + const char* buf, NPBool file, + void* notifyData); +NPError NPN_PostURL(NPP instance, const char* url, + const char* target, uint32 len, + const char* buf, NPBool file); +NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList); +NPError NPN_NewStream(NPP instance, NPMIMEType type, + const char* target, NPStream** stream); +int32 NPN_Write(NPP instance, NPStream* stream, int32 len, + void* buffer); +NPError NPN_DestroyStream(NPP instance, NPStream* stream, + NPReason reason); +void NPN_Status(NPP instance, const char* message); +const char* NPN_UserAgent(NPP instance); +void* NPN_MemAlloc(uint32 size); +void NPN_MemFree(void* ptr); +uint32 NPN_MemFlush(uint32 size); +void NPN_ReloadPlugins(NPBool reloadPages); +JRIEnv* NPN_GetJavaEnv(void); +jref NPN_GetJavaPeer(NPP instance); +NPError NPN_GetValue(NPP instance, NPNVariable variable, + void *value); +NPError NPN_SetValue(NPP instance, NPPVariable variable, + void *value); +void NPN_InvalidateRect(NPP instance, NPRect *invalidRect); +void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion); +void NPN_ForceRedraw(NPP instance); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* _NPAPI_H_ */ diff --git a/rosapps/smartpdf/fitz/apps/mozilla/npunix.c b/rosapps/smartpdf/fitz/apps/mozilla/npunix.c new file mode 100644 index 00000000000..1c742d6d1ab --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/mozilla/npunix.c @@ -0,0 +1,406 @@ +/* + * npunix.c + * + * Netscape Client Plugin API + * - Wrapper function to interface with the Netscape Navigator + * + * dp Suresh + * + *---------------------------------------------------------------------- + * PLUGIN DEVELOPERS: + * YOU WILL NOT NEED TO EDIT THIS FILE. + *---------------------------------------------------------------------- + */ + +#define XP_UNIX 1 + +#include +#include "npapi.h" +#include "npupp.h" + +/* + * Define PLUGIN_TRACE to have the wrapper functions print + * messages to stderr whenever they are called. + */ + +#ifdef PLUGIN_TRACE +#include +#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s\n", msg) +#else +#define PLUGINDEBUGSTR(msg) +#endif + + +/*********************************************************************** + * + * Globals + * + ***********************************************************************/ + +static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */ + + +/*********************************************************************** + * + * Wrapper functions : plugin calling Netscape Navigator + * + * These functions let the plugin developer just call the APIs + * as documented and defined in npapi.h, without needing to know + * about the function table and call macros in npupp.h. + * + ***********************************************************************/ + +void +NPN_Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor) +{ + *plugin_major = NP_VERSION_MAJOR; + *plugin_minor = NP_VERSION_MINOR; + + /* Major version is in high byte */ + *netscape_major = gNetscapeFuncs.version >> 8; + /* Minor version is in low byte */ + *netscape_minor = gNetscapeFuncs.version & 0xFF; +} + +NPError +NPN_GetValue(NPP instance, NPNVariable variable, void *r_value) +{ + return CallNPN_GetValueProc(gNetscapeFuncs.getvalue, + instance, variable, r_value); +} + +NPError +NPN_GetURL(NPP instance, const char* url, const char* window) +{ + return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window); +} + +NPError +NPN_PostURL(NPP instance, const char* url, const char* window, + uint32 len, const char* buf, NPBool file) +{ + return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance, + url, window, len, buf, file); +} + +NPError +NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) +{ + return CallNPN_RequestReadProc(gNetscapeFuncs.requestread, + stream, rangeList); +} + +NPError +NPN_NewStream(NPP instance, NPMIMEType type, const char *window, + NPStream** stream_ptr) +{ + return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance, + type, window, stream_ptr); +} + +int32 +NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer) +{ + return CallNPN_WriteProc(gNetscapeFuncs.write, instance, + stream, len, buffer); +} + +NPError +NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) +{ + return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream, + instance, stream, reason); +} + +void +NPN_Status(NPP instance, const char* message) +{ + CallNPN_StatusProc(gNetscapeFuncs.status, instance, message); +} + +const char* +NPN_UserAgent(NPP instance) +{ + return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance); +} + +void* +NPN_MemAlloc(uint32 size) +{ + return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size); +} + +void NPN_MemFree(void* ptr) +{ + CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr); +} + +uint32 NPN_MemFlush(uint32 size) +{ + return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size); +} + +void NPN_ReloadPlugins(NPBool reloadPages) +{ + CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages); +} + +JRIEnv* NPN_GetJavaEnv() +{ + return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv); +} + +jref NPN_GetJavaPeer(NPP instance) +{ + return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer, + instance); +} + + +/*********************************************************************** + * + * Wrapper functions : Netscape Navigator -> plugin + * + * These functions let the plugin developer just create the APIs + * as documented and defined in npapi.h, without needing to + * install those functions in the function table or worry about + * setting up globals for 68K plugins. + * + ***********************************************************************/ + +NPError +Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, + int16 argc, char* argn[], char* argv[], NPSavedData* saved) +{ + NPError ret; + PLUGINDEBUGSTR("New"); + ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved); + return ret; +} + +NPError +Private_Destroy(NPP instance, NPSavedData** save) +{ + PLUGINDEBUGSTR("Destroy"); + return NPP_Destroy(instance, save); +} + +NPError +Private_SetWindow(NPP instance, NPWindow* window) +{ + NPError err; + PLUGINDEBUGSTR("SetWindow"); + err = NPP_SetWindow(instance, window); + return err; +} + +NPError +Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, + NPBool seekable, uint16* stype) +{ + NPError err; + PLUGINDEBUGSTR("NewStream"); + err = NPP_NewStream(instance, type, stream, seekable, stype); + return err; +} + +int32 +Private_WriteReady(NPP instance, NPStream* stream) +{ + unsigned int result; + PLUGINDEBUGSTR("WriteReady"); + result = NPP_WriteReady(instance, stream); + return result; +} + +int32 +Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, + void* buffer) +{ + unsigned int result; + PLUGINDEBUGSTR("Write"); + result = NPP_Write(instance, stream, offset, len, buffer); + return result; +} + +void +Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname) +{ + PLUGINDEBUGSTR("StreamAsFile"); + NPP_StreamAsFile(instance, stream, fname); +} + + +NPError +Private_DestroyStream(NPP instance, NPStream* stream, NPError reason) +{ + NPError err; + PLUGINDEBUGSTR("DestroyStream"); + err = NPP_DestroyStream(instance, stream, reason); + return err; +} + + +void +Private_Print(NPP instance, NPPrint* platformPrint) +{ + PLUGINDEBUGSTR("Print"); + NPP_Print(instance, platformPrint); +} + +JRIGlobalRef +Private_GetJavaClass(void) +{ + jref clazz = NPP_GetJavaClass(); + if (clazz) { + JRIEnv* env = NPN_GetJavaEnv(); + return JRI_NewGlobalRef(env, clazz); + } + return NULL; +} + +/*********************************************************************** + * + * These functions are located automagically by netscape. + * + ***********************************************************************/ + +/* + * NP_GetMIMEDescription + * - Netscape needs to know about this symbol + * - Netscape uses the return value to identify when an object instance + * of this plugin should be created. + */ +char * +NP_GetMIMEDescription(void) +{ + return NPP_GetMIMEDescription(); +} + +/* + * NP_GetValue [optional] + * - Netscape needs to know about this symbol. + * - Interfaces with plugin to get values for predefined variables + * that the navigator needs. + */ +NPError +NP_GetValue(void *future, NPPVariable variable, void *value) +{ + return NPP_GetValue(future, variable, value); +} + +/* + * NP_Initialize + * - Netscape needs to know about this symbol. + * - It calls this function after looking up its symbol before it + * is about to create the first ever object of this kind. + * + * PARAMETERS + * nsTable - The netscape function table. If developers just use these + * wrappers, they dont need to worry about all these function + * tables. + * RETURN + * pluginFuncs + * - This functions needs to fill the plugin function table + * pluginFuncs and return it. Netscape Navigator plugin + * library will use this function table to call the plugin. + * + */ +NPError +NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs) +{ + NPError err = NPERR_NO_ERROR; + + PLUGINDEBUGSTR("NP_Initialize"); + + /* validate input parameters */ + + if ((nsTable == NULL) || (pluginFuncs == NULL)) + err = NPERR_INVALID_FUNCTABLE_ERROR; + + /* + * Check the major version passed in Netscape's function table. + * We won't load if the major version is newer than what we expect. + * Also check that the function tables passed in are big enough for + * all the functions we need (they could be bigger, if Netscape added + * new APIs, but that's OK with us -- we'll just ignore them). + * + */ + + if (err == NPERR_NO_ERROR) { + if ((nsTable->version >> 8) > NP_VERSION_MAJOR) + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + if (nsTable->size < sizeof(NPNetscapeFuncs)) + err = NPERR_INVALID_FUNCTABLE_ERROR; + if (pluginFuncs->size < sizeof(NPPluginFuncs)) + err = NPERR_INVALID_FUNCTABLE_ERROR; + } + + + if (err == NPERR_NO_ERROR) { + /* + * Copy all the fields of Netscape function table into our + * copy so we can call back into Netscape later. Note that + * we need to copy the fields one by one, rather than assigning + * the whole structure, because the Netscape function table + * could actually be bigger than what we expect. + */ + gNetscapeFuncs.version = nsTable->version; + gNetscapeFuncs.size = nsTable->size; + gNetscapeFuncs.posturl = nsTable->posturl; + gNetscapeFuncs.geturl = nsTable->geturl; + gNetscapeFuncs.requestread = nsTable->requestread; + gNetscapeFuncs.newstream = nsTable->newstream; + gNetscapeFuncs.write = nsTable->write; + gNetscapeFuncs.destroystream = nsTable->destroystream; + gNetscapeFuncs.status = nsTable->status; + gNetscapeFuncs.uagent = nsTable->uagent; + gNetscapeFuncs.memalloc = nsTable->memalloc; + gNetscapeFuncs.memfree = nsTable->memfree; + gNetscapeFuncs.memflush = nsTable->memflush; + gNetscapeFuncs.reloadplugins = nsTable->reloadplugins; + gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv; + gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer; + gNetscapeFuncs.getvalue = nsTable->getvalue; + + /* + * Set up the plugin function table that Netscape will use to + * call us. Netscape needs to know about our version and size + * and have a UniversalProcPointer for every function we + * implement. + */ + pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; + pluginFuncs->size = sizeof(NPPluginFuncs); + pluginFuncs->newp = NewNPP_NewProc(Private_New); + pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy); + pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow); + pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream); + pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream); + pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile); + pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady); + pluginFuncs->write = NewNPP_WriteProc(Private_Write); + pluginFuncs->print = NewNPP_PrintProc(Private_Print); + pluginFuncs->event = NULL; + pluginFuncs->javaClass = Private_GetJavaClass(); + + err = NPP_Initialize(); + } + + return err; +} + +/* + * NP_Shutdown [optional] + * - Netscape needs to know about this symbol. + * - It calls this function after looking up its symbol after + * the last object of this kind has been destroyed. + * + */ +NPError +NP_Shutdown(void) +{ + PLUGINDEBUGSTR("NP_Shutdown"); + NPP_Shutdown(); + return NPERR_NO_ERROR; +} diff --git a/rosapps/smartpdf/fitz/apps/mozilla/npupp.h b/rosapps/smartpdf/fitz/apps/mozilla/npupp.h new file mode 100644 index 00000000000..2a81647448c --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/mozilla/npupp.h @@ -0,0 +1,1160 @@ +/* -*- Mode: C; tab-width: 4; -*- */ +/* + * npupp.h $Revision: 1.41 $ + * function call mecahnics needed by platform specific glue code. + */ + + +#ifndef _NPUPP_H_ +#define _NPUPP_H_ + +#ifndef GENERATINGCFM +#define GENERATINGCFM 0 +#endif + +#ifndef _NPAPI_H_ +#include "npapi.h" +#endif + +#include "jri.h" + +/****************************************************************************************** + plug-in function table macros + for each function in and out of the plugin API we define + typedef NPP_FooUPP + #define NewNPP_FooProc + #define CallNPP_FooProc + for mac, define the UPP magic for PPC/68K calling + *******************************************************************************************/ + + +/* NPP_Initialize */ + +#if GENERATINGCFM +typedef UniversalProcPtr NPP_InitializeUPP; + +enum { + uppNPP_InitializeProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0)) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPP_InitializeProc(FUNC) \ + (NPP_InitializeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_InitializeProcInfo, GetCurrentArchitecture()) +#define CallNPP_InitializeProc(FUNC) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_InitializeProcInfo) + +#else + +typedef void (*NPP_InitializeUPP)(void); +#define NewNPP_InitializeProc(FUNC) \ + ((NPP_InitializeUPP) (FUNC)) +#define CallNPP_InitializeProc(FUNC) \ + (*(FUNC))() + +#endif + + +/* NPP_Shutdown */ + +#if GENERATINGCFM +typedef UniversalProcPtr NPP_ShutdownUPP; + +enum { + uppNPP_ShutdownProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0)) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPP_ShutdownProc(FUNC) \ + (NPP_ShutdownUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_ShutdownProcInfo, GetCurrentArchitecture()) +#define CallNPP_ShutdownProc(FUNC) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_ShutdownProcInfo) + +#else + +typedef void (*NPP_ShutdownUPP)(void); +#define NewNPP_ShutdownProc(FUNC) \ + ((NPP_ShutdownUPP) (FUNC)) +#define CallNPP_ShutdownProc(FUNC) \ + (*(FUNC))() + +#endif + + +/* NPP_New */ + +#if GENERATINGCFM +typedef UniversalProcPtr NPP_NewUPP; + +enum { + uppNPP_NewProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPMIMEType))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(uint16))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int16))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(char **))) + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(char **))) + | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(NPSavedData *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; + +#define NewNPP_NewProc(FUNC) \ + (NPP_NewUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewProcInfo, GetCurrentArchitecture()) +#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewProcInfo, \ + (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#else + +typedef NPError (*NPP_NewUPP)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); +#define NewNPP_NewProc(FUNC) \ + ((NPP_NewUPP) (FUNC)) +#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) + +#endif + + +/* NPP_Destroy */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_DestroyUPP; +enum { + uppNPP_DestroyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPSavedData **))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_DestroyProc(FUNC) \ + (NPP_DestroyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyProcInfo, GetCurrentArchitecture()) +#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyProcInfo, (ARG1), (ARG2)) +#else + +typedef NPError (*NPP_DestroyUPP)(NPP instance, NPSavedData** save); +#define NewNPP_DestroyProc(FUNC) \ + ((NPP_DestroyUPP) (FUNC)) +#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + + +/* NPP_SetWindow */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_SetWindowUPP; +enum { + uppNPP_SetWindowProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPWindow *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_SetWindowProc(FUNC) \ + (NPP_SetWindowUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_SetWindowProcInfo, GetCurrentArchitecture()) +#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_SetWindowProcInfo, (ARG1), (ARG2)) + +#else + +typedef NPError (*NPP_SetWindowUPP)(NPP instance, NPWindow* window); +#define NewNPP_SetWindowProc(FUNC) \ + ((NPP_SetWindowUPP) (FUNC)) +#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + + +/* NPP_NewStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_NewStreamUPP; +enum { + uppNPP_NewStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPBool))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(uint16 *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_NewStreamProc(FUNC) \ + (NPP_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewStreamProcInfo, GetCurrentArchitecture()) +#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewStreamProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) +#else + +typedef NPError (*NPP_NewStreamUPP)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); +#define NewNPP_NewStreamProc(FUNC) \ + ((NPP_NewStreamUPP) (FUNC)) +#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) +#endif + + +/* NPP_DestroyStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_DestroyStreamUPP; +enum { + uppNPP_DestroyStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_DestroyStreamProc(FUNC) \ + (NPP_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, GetCurrentArchitecture()) +#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, (NPParg), (NPStreamPtr), (NPReasonArg)) + +#else + +typedef NPError (*NPP_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); +#define NewNPP_DestroyStreamProc(FUNC) \ + ((NPP_DestroyStreamUPP) (FUNC)) +#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ + (*(FUNC))((NPParg), (NPStreamPtr), (NPReasonArg)) + +#endif + + +/* NPP_WriteReady */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_WriteReadyUPP; +enum { + uppNPP_WriteReadyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | RESULT_SIZE(SIZE_CODE(sizeof(int32))) +}; +#define NewNPP_WriteReadyProc(FUNC) \ + (NPP_WriteReadyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, GetCurrentArchitecture()) +#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ + (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, (NPParg), (NPStreamPtr)) + +#else + +typedef int32 (*NPP_WriteReadyUPP)(NPP instance, NPStream* stream); +#define NewNPP_WriteReadyProc(FUNC) \ + ((NPP_WriteReadyUPP) (FUNC)) +#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ + (*(FUNC))((NPParg), (NPStreamPtr)) + +#endif + + +/* NPP_Write */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_WriteUPP; +enum { + uppNPP_WriteProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int32))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(int32))) +}; +#define NewNPP_WriteProc(FUNC) \ + (NPP_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteProcInfo, GetCurrentArchitecture()) +#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ + (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteProcInfo, (NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) + +#else + +typedef int32 (*NPP_WriteUPP)(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); +#define NewNPP_WriteProc(FUNC) \ + ((NPP_WriteUPP) (FUNC)) +#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ + (*(FUNC))((NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) + +#endif + + +/* NPP_StreamAsFile */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_StreamAsFileUPP; +enum { + uppNPP_StreamAsFileProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *))) + | RESULT_SIZE(SIZE_CODE(0)) +}; +#define NewNPP_StreamAsFileProc(FUNC) \ + (NPP_StreamAsFileUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, GetCurrentArchitecture()) +#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, (ARG1), (ARG2), (ARG3)) + +#else + +typedef void (*NPP_StreamAsFileUPP)(NPP instance, NPStream* stream, const char* fname); +#define NewNPP_StreamAsFileProc(FUNC) \ + ((NPP_StreamAsFileUPP) (FUNC)) +#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + +/* NPP_Print */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_PrintUPP; +enum { + uppNPP_PrintProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPrint *))) + | RESULT_SIZE(SIZE_CODE(0)) +}; +#define NewNPP_PrintProc(FUNC) \ + (NPP_PrintUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_PrintProcInfo, GetCurrentArchitecture()) +#define CallNPP_PrintProc(FUNC, NPParg, voidPtr) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_PrintProcInfo, (NPParg), (voidPtr)) + +#else + +typedef void (*NPP_PrintUPP)(NPP instance, NPPrint* platformPrint); +#define NewNPP_PrintProc(FUNC) \ + ((NPP_PrintUPP) (FUNC)) +#define CallNPP_PrintProc(FUNC, NPParg, NPPrintArg) \ + (*(FUNC))((NPParg), (NPPrintArg)) + +#endif + + +/* NPP_HandleEvent */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_HandleEventUPP; +enum { + uppNPP_HandleEventProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *))) + | RESULT_SIZE(SIZE_CODE(sizeof(int16))) +}; +#define NewNPP_HandleEventProc(FUNC) \ + (NPP_HandleEventUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_HandleEventProcInfo, GetCurrentArchitecture()) +#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ + (int16)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_HandleEventProcInfo, (NPParg), (voidPtr)) + +#else + +typedef int16 (*NPP_HandleEventUPP)(NPP instance, void* event); +#define NewNPP_HandleEventProc(FUNC) \ + ((NPP_HandleEventUPP) (FUNC)) +#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ + (*(FUNC))((NPParg), (voidPtr)) + +#endif + + +/* NPP_URLNotify */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_URLNotifyUPP; +enum { + uppNPP_URLNotifyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(SIZE_CODE(0))) +}; +#define NewNPP_URLNotifyProc(FUNC) \ + (NPP_URLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, GetCurrentArchitecture()) +#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4)) + +#else + +typedef void (*NPP_URLNotifyUPP)(NPP instance, const char* url, NPReason reason, void* notifyData); +#define NewNPP_URLNotifyProc(FUNC) \ + ((NPP_URLNotifyUPP) (FUNC)) +#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +#endif + + +/* NPP_GetValue */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_GetValueUPP; +enum { + uppNPP_GetValueProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPVariable))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_GetValueProc(FUNC) \ + (NPP_GetValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_GetValueProcInfo, GetCurrentArchitecture()) +#define CallNPP_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_GetValueProcInfo, (ARG1), (ARG2), (ARG3)) +#else + +typedef NPError (*NPP_GetValueUPP)(NPP instance, NPPVariable variable, void *ret_alue); +#define NewNPP_GetValueProc(FUNC) \ + ((NPP_GetValueUPP) (FUNC)) +#define CallNPP_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + +/* NPP_SetValue */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_SetValueUPP; +enum { + uppNPP_SetValueProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPNVariable))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_SetValueProc(FUNC) \ + (NPP_SetValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_SetValueProcInfo, GetCurrentArchitecture()) +#define CallNPP_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_SetValueProcInfo, (ARG1), (ARG2), (ARG3)) +#else + +typedef NPError (*NPP_SetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); +#define NewNPP_SetValueProc(FUNC) \ + ((NPP_SetValueUPP) (FUNC)) +#define CallNPP_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + + + +/* + * Netscape entry points + */ + + +/* NPN_GetValue */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetValueUPP; +enum { + uppNPN_GetValueProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPNVariable))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_GetValueProc(FUNC) \ + (NPN_GetValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetValueProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetValueProcInfo, (ARG1), (ARG2), (ARG3)) +#else + +typedef NPError (*NPN_GetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); +#define NewNPN_GetValueProc(FUNC) \ + ((NPN_GetValueUPP) (FUNC)) +#define CallNPN_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + +/* NPN_SetValue */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_SetValueUPP; +enum { + uppNPN_SetValueProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPVariable))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_SetValueProc(FUNC) \ + (NPN_SetValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_SetValueProcInfo, GetCurrentArchitecture()) +#define CallNPN_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_SetValueProcInfo, (ARG1), (ARG2), (ARG3)) +#else + +typedef NPError (*NPN_SetValueUPP)(NPP instance, NPPVariable variable, void *ret_alue); +#define NewNPN_SetValueProc(FUNC) \ + ((NPN_SetValueUPP) (FUNC)) +#define CallNPN_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + +/* NPN_GetUrlNotify */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetURLNotifyUPP; +enum { + uppNPN_GetURLNotifyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_GetURLNotifyProc(FUNC) \ + (NPN_GetURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4)) +#else + +typedef NPError (*NPN_GetURLNotifyUPP)(NPP instance, const char* url, const char* window, void* notifyData); +#define NewNPN_GetURLNotifyProc(FUNC) \ + ((NPN_GetURLNotifyUPP) (FUNC)) +#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) +#endif + + +/* NPN_PostUrlNotify */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_PostURLNotifyUPP; +enum { + uppNPN_PostURLNotifyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool))) + | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_PostURLNotifyProc(FUNC) \ + (NPN_PostURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, GetCurrentArchitecture()) +#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#else + +typedef NPError (*NPN_PostURLNotifyUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData); +#define NewNPN_PostURLNotifyProc(FUNC) \ + ((NPN_PostURLNotifyUPP) (FUNC)) +#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#endif + + +/* NPN_GetUrl */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetURLUPP; +enum { + uppNPN_GetURLProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_GetURLProc(FUNC) \ + (NPN_GetURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLProcInfo, (ARG1), (ARG2), (ARG3)) +#else + +typedef NPError (*NPN_GetURLUPP)(NPP instance, const char* url, const char* window); +#define NewNPN_GetURLProc(FUNC) \ + ((NPN_GetURLUPP) (FUNC)) +#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) +#endif + + +/* NPN_PostUrl */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_PostURLUPP; +enum { + uppNPN_PostURLProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*))) + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_PostURLProc(FUNC) \ + (NPN_PostURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLProcInfo, GetCurrentArchitecture()) +#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) +#else + +typedef NPError (*NPN_PostURLUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file); +#define NewNPN_PostURLProc(FUNC) \ + ((NPN_PostURLUPP) (FUNC)) +#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) +#endif + + +/* NPN_RequestRead */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_RequestReadUPP; +enum { + uppNPN_RequestReadProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPByteRange *))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_RequestReadProc(FUNC) \ + (NPN_RequestReadUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_RequestReadProcInfo, GetCurrentArchitecture()) +#define CallNPN_RequestReadProc(FUNC, stream, range) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_RequestReadProcInfo, (stream), (range)) + +#else + +typedef NPError (*NPN_RequestReadUPP)(NPStream* stream, NPByteRange* rangeList); +#define NewNPN_RequestReadProc(FUNC) \ + ((NPN_RequestReadUPP) (FUNC)) +#define CallNPN_RequestReadProc(FUNC, stream, range) \ + (*(FUNC))((stream), (range)) + +#endif + + +/* NPN_NewStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_NewStreamUPP; +enum { + uppNPN_NewStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPStream **))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_NewStreamProc(FUNC) \ + (NPN_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_NewStreamProcInfo, GetCurrentArchitecture()) +#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_NewStreamProcInfo, (npp), (type), (window), (stream)) + +#else + +typedef NPError (*NPN_NewStreamUPP)(NPP instance, NPMIMEType type, const char* window, NPStream** stream); +#define NewNPN_NewStreamProc(FUNC) \ + ((NPN_NewStreamUPP) (FUNC)) +#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ + (*(FUNC))((npp), (type), (window), (stream)) + +#endif + + +/* NPN_Write */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_WriteUPP; +enum { + uppNPN_WriteProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) + | RESULT_SIZE(SIZE_CODE(sizeof(int32))) +}; +#define NewNPN_WriteProc(FUNC) \ + (NPN_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_WriteProcInfo, GetCurrentArchitecture()) +#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ + (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_WriteProcInfo, (npp), (stream), (len), (buffer)) + +#else + +typedef int32 (*NPN_WriteUPP)(NPP instance, NPStream* stream, int32 len, void* buffer); +#define NewNPN_WriteProc(FUNC) \ + ((NPN_WriteUPP) (FUNC)) +#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ + (*(FUNC))((npp), (stream), (len), (buffer)) + +#endif + + +/* NPN_DestroyStream */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_DestroyStreamUPP; +enum { + uppNPN_DestroyStreamProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP ))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPN_DestroyStreamProc(FUNC) \ + (NPN_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, GetCurrentArchitecture()) +#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ + (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, (npp), (stream), (reason)) + +#else + +typedef NPError (*NPN_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); +#define NewNPN_DestroyStreamProc(FUNC) \ + ((NPN_DestroyStreamUPP) (FUNC)) +#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ + (*(FUNC))((npp), (stream), (reason)) + +#endif + + +/* NPN_Status */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_StatusUPP; +enum { + uppNPN_StatusProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char *))) +}; + +#define NewNPN_StatusProc(FUNC) \ + (NPN_StatusUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_StatusProcInfo, GetCurrentArchitecture()) +#define CallNPN_StatusProc(FUNC, npp, msg) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_StatusProcInfo, (npp), (msg)) + +#else + +typedef void (*NPN_StatusUPP)(NPP instance, const char* message); +#define NewNPN_StatusProc(FUNC) \ + ((NPN_StatusUPP) (FUNC)) +#define CallNPN_StatusProc(FUNC, npp, msg) \ + (*(FUNC))((npp), (msg)) + +#endif + + +/* NPN_UserAgent */ +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_UserAgentUPP; +enum { + uppNPN_UserAgentProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | RESULT_SIZE(SIZE_CODE(sizeof(const char *))) +}; + +#define NewNPN_UserAgentProc(FUNC) \ + (NPN_UserAgentUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_UserAgentProcInfo, GetCurrentArchitecture()) +#define CallNPN_UserAgentProc(FUNC, ARG1) \ + (const char*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_UserAgentProcInfo, (ARG1)) + +#else + +typedef const char* (*NPN_UserAgentUPP)(NPP instance); +#define NewNPN_UserAgentProc(FUNC) \ + ((NPN_UserAgentUPP) (FUNC)) +#define CallNPN_UserAgentProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN_MemAlloc */ +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_MemAllocUPP; +enum { + uppNPN_MemAllocProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32))) + | RESULT_SIZE(SIZE_CODE(sizeof(void *))) +}; + +#define NewNPN_MemAllocProc(FUNC) \ + (NPN_MemAllocUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemAllocProcInfo, GetCurrentArchitecture()) +#define CallNPN_MemAllocProc(FUNC, ARG1) \ + (void*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemAllocProcInfo, (ARG1)) + +#else + +typedef void* (*NPN_MemAllocUPP)(uint32 size); +#define NewNPN_MemAllocProc(FUNC) \ + ((NPN_MemAllocUPP) (FUNC)) +#define CallNPN_MemAllocProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN__MemFree */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_MemFreeUPP; +enum { + uppNPN_MemFreeProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(void *))) +}; + +#define NewNPN_MemFreeProc(FUNC) \ + (NPN_MemFreeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFreeProcInfo, GetCurrentArchitecture()) +#define CallNPN_MemFreeProc(FUNC, ARG1) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFreeProcInfo, (ARG1)) + +#else + +typedef void (*NPN_MemFreeUPP)(void* ptr); +#define NewNPN_MemFreeProc(FUNC) \ + ((NPN_MemFreeUPP) (FUNC)) +#define CallNPN_MemFreeProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN_MemFlush */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_MemFlushUPP; +enum { + uppNPN_MemFlushProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32))) + | RESULT_SIZE(SIZE_CODE(sizeof(uint32))) +}; + +#define NewNPN_MemFlushProc(FUNC) \ + (NPN_MemFlushUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFlushProcInfo, GetCurrentArchitecture()) +#define CallNPN_MemFlushProc(FUNC, ARG1) \ + (uint32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFlushProcInfo, (ARG1)) + +#else + +typedef uint32 (*NPN_MemFlushUPP)(uint32 size); +#define NewNPN_MemFlushProc(FUNC) \ + ((NPN_MemFlushUPP) (FUNC)) +#define CallNPN_MemFlushProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + + +/* NPN_ReloadPlugins */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_ReloadPluginsUPP; +enum { + uppNPN_ReloadPluginsProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPBool))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_ReloadPluginsProc(FUNC) \ + (NPN_ReloadPluginsUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, GetCurrentArchitecture()) +#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, (ARG1)) + +#else + +typedef void (*NPN_ReloadPluginsUPP)(NPBool reloadPages); +#define NewNPN_ReloadPluginsProc(FUNC) \ + ((NPN_ReloadPluginsUPP) (FUNC)) +#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN_GetJavaEnv */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetJavaEnvUPP; +enum { + uppNPN_GetJavaEnvProcInfo = kThinkCStackBased + | RESULT_SIZE(SIZE_CODE(sizeof(JRIEnv*))) +}; + +#define NewNPN_GetJavaEnvProc(FUNC) \ + (NPN_GetJavaEnvUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetJavaEnvProc(FUNC) \ + (JRIEnv*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo) + +#else + +typedef JRIEnv* (*NPN_GetJavaEnvUPP)(void); +#define NewNPN_GetJavaEnvProc(FUNC) \ + ((NPN_GetJavaEnvUPP) (FUNC)) +#define CallNPN_GetJavaEnvProc(FUNC) \ + (*(FUNC))() + +#endif + + +/* NPN_GetJavaPeer */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_GetJavaPeerUPP; +enum { + uppNPN_GetJavaPeerProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | RESULT_SIZE(SIZE_CODE(sizeof(jref))) +}; + +#define NewNPN_GetJavaPeerProc(FUNC) \ + (NPN_GetJavaPeerUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, (ARG1)) + +#else + +typedef jref (*NPN_GetJavaPeerUPP)(NPP instance); +#define NewNPN_GetJavaPeerProc(FUNC) \ + ((NPN_GetJavaPeerUPP) (FUNC)) +#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/* NPN_InvalidateRect */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_InvalidateRectUPP; +enum { + uppNPN_InvalidateRectProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPRect *))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_InvalidateRectProc(FUNC) \ + (NPN_InvalidateRectUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_InvalidateRectProcInfo, GetCurrentArchitecture()) +#define CallNPN_InvalidateRectProc(FUNC, ARG1, ARG2) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_InvalidateRectProcInfo, (ARG1), (ARG2)) + +#else + +typedef void (*NPN_InvalidateRectUPP)(NPP instance, NPRect *rect); +#define NewNPN_InvalidateRectProc(FUNC) \ + ((NPN_InvalidateRectUPP) (FUNC)) +#define CallNPN_InvalidateRectProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + + +/* NPN_InvalidateRegion */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_InvalidateRegionUPP; +enum { + uppNPN_InvalidateRegionProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPRegion))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_InvalidateRegionProc(FUNC) \ + (NPN_InvalidateRegionUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_InvalidateRegionProcInfo, GetCurrentArchitecture()) +#define CallNPN_InvalidateRegionProc(FUNC, ARG1, ARG2) \ + (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_InvalidateRegionProcInfo, (ARG1), (ARG2)) + +#else + +typedef void (*NPN_InvalidateRegionUPP)(NPP instance, NPRegion region); +#define NewNPN_InvalidateRegionProc(FUNC) \ + ((NPN_InvalidateRegionUPP) (FUNC)) +#define CallNPN_InvalidateRegionProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + +/* NPN_ForceRedraw */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPN_ForceRedrawUPP; +enum { + uppNPN_ForceRedrawProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | RESULT_SIZE(SIZE_CODE(sizeof(0))) +}; + +#define NewNPN_ForceRedrawProc(FUNC) \ + (NPN_ForceRedrawUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_ForceRedrawProcInfo, GetCurrentArchitecture()) +#define CallNPN_ForceRedrawProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_ForceRedrawProcInfo, (ARG1)) + +#else + +typedef void (*NPN_ForceRedrawUPP)(NPP instance); +#define NewNPN_ForceRedrawProc(FUNC) \ + ((NPN_ForceRedrawUPP) (FUNC)) +#define CallNPN_ForceRedrawProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + + +/****************************************************************************************** + * The actual plugin function table definitions + *******************************************************************************************/ + +#ifdef XP_MAC +#pragma align=mac68k +#endif + +typedef struct _NPPluginFuncs { + uint16 size; + uint16 version; + NPP_NewUPP newp; + NPP_DestroyUPP destroy; + NPP_SetWindowUPP setwindow; + NPP_NewStreamUPP newstream; + NPP_DestroyStreamUPP destroystream; + NPP_StreamAsFileUPP asfile; + NPP_WriteReadyUPP writeready; + NPP_WriteUPP write; + NPP_PrintUPP print; + NPP_HandleEventUPP event; + NPP_URLNotifyUPP urlnotify; + JRIGlobalRef javaClass; + NPP_GetValueUPP getvalue; + NPP_SetValueUPP setvalue; +} NPPluginFuncs; + +typedef struct _NPNetscapeFuncs { + uint16 size; + uint16 version; + NPN_GetURLUPP geturl; + NPN_PostURLUPP posturl; + NPN_RequestReadUPP requestread; + NPN_NewStreamUPP newstream; + NPN_WriteUPP write; + NPN_DestroyStreamUPP destroystream; + NPN_StatusUPP status; + NPN_UserAgentUPP uagent; + NPN_MemAllocUPP memalloc; + NPN_MemFreeUPP memfree; + NPN_MemFlushUPP memflush; + NPN_ReloadPluginsUPP reloadplugins; + NPN_GetJavaEnvUPP getJavaEnv; + NPN_GetJavaPeerUPP getJavaPeer; + NPN_GetURLNotifyUPP geturlnotify; + NPN_PostURLNotifyUPP posturlnotify; + NPN_GetValueUPP getvalue; + NPN_SetValueUPP setvalue; + NPN_InvalidateRectUPP invalidaterect; + NPN_InvalidateRegionUPP invalidateregion; + NPN_ForceRedrawUPP forceredraw; +} NPNetscapeFuncs; + +#ifdef XP_MAC +#pragma align=reset +#endif + + +#ifdef XP_MAC +/****************************************************************************************** + * Mac platform-specific plugin glue stuff + *******************************************************************************************/ + +/* + * Main entry point of the plugin. + * This routine will be called when the plugin is loaded. The function + * tables are passed in and the plugin fills in the NPPluginFuncs table + * and NPPShutdownUPP for Netscape's use. + */ + +#if GENERATINGCFM + +typedef UniversalProcPtr NPP_MainEntryUPP; +enum { + uppNPP_MainEntryProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPNetscapeFuncs*))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPluginFuncs*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPP_ShutdownUPP*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) +}; +#define NewNPP_MainEntryProc(FUNC) \ + (NPP_MainEntryUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_MainEntryProcInfo, GetCurrentArchitecture()) +#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ + CallUniversalProc((UniversalProcPtr)(FUNC), (ProcInfoType)uppNPP_MainEntryProcInfo, (netscapeFunc), (pluginFunc), (shutdownUPP)) + +#else + +typedef NPError (*NPP_MainEntryUPP)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownUPP*); +#define NewNPP_MainEntryProc(FUNC) \ + ((NPP_MainEntryUPP) (FUNC)) +#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ + (*(FUNC))((netscapeFunc), (pluginFunc), (shutdownUPP)) + +#endif +#endif /* MAC */ + + +#ifdef _WINDOWS + +#ifdef __cplusplus +extern "C" { +#endif + +/* plugin meta member functions */ + +NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs); + +NPError WINAPI NP_Initialize(NPNetscapeFuncs* pFuncs); + +NPError WINAPI NP_Shutdown(); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS */ + +#ifdef XP_UNIX + +#ifdef __cplusplus +extern "C" { +#endif + +/* plugin meta member functions */ + +char* NP_GetMIMEDescription(void); +NPError NP_Initialize(NPNetscapeFuncs*, NPPluginFuncs*); +NPError NP_Shutdown(void); + +#ifdef __cplusplus +} +#endif + +#endif /* XP_UNIX */ + +#endif /* _NPUPP_H_ */ diff --git a/rosapps/smartpdf/fitz/apps/mozilla/npwin.c b/rosapps/smartpdf/fitz/apps/mozilla/npwin.c new file mode 100644 index 00000000000..5d60a893d89 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/mozilla/npwin.c @@ -0,0 +1,327 @@ +/* npwin.cpp */ + +//\\// INCLUDE +//#include "StdAfx.h" + +// TOR +#include + + +// netscape +#ifndef _NPAPI_H_ +#include "npapi.h" +#endif +#ifndef _NPUPP_H_ +#include "npupp.h" +#endif + +//\\// DEFINE +#ifdef WIN32 + #define NP_EXPORT +#else + #define NP_EXPORT _export +#endif + +//\\// GLOBAL DATA +NPNetscapeFuncs* g_pNavigatorFuncs = 0; +JRIGlobalRef Private_GetJavaClass(void); + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// Private_GetJavaClass (global function) +// +// Given a Java class reference (thru NPP_GetJavaClass) inform JRT +// of this class existence +// +JRIGlobalRef +Private_GetJavaClass(void) +{ + jref clazz = NPP_GetJavaClass(); + if (clazz) { + JRIEnv* env = NPN_GetJavaEnv(); + return JRI_NewGlobalRef(env, clazz); + } + return NULL; +} + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// PLUGIN DLL entry points +// +// These are the Windows specific DLL entry points. They must be exoprted +// + +// we need these to be global since we have to fill one of its field +// with a data (class) which requires knowlwdge of the navigator +// jump-table. This jump table is known at Initialize time (NP_Initialize) +// which is called after NP_GetEntryPoint +static NPPluginFuncs* g_pluginFuncs; + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// NP_GetEntryPoints +// +// fills in the func table used by Navigator to call entry points in +// plugin DLL. Note that these entry points ensure that DS is loaded +// by using the NP_LOADDS macro, when compiling for Win16 +// +NPError WINAPI NP_EXPORT +NP_GetEntryPoints(NPPluginFuncs* pFuncs) +{ + // trap a NULL ptr + if(pFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + // if the plugin's function table is smaller than the plugin expects, + // then they are incompatible, and should return an error + + pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + pFuncs->newp = NPP_New; + pFuncs->destroy = NPP_Destroy; + pFuncs->setwindow = NPP_SetWindow; + pFuncs->newstream = NPP_NewStream; + pFuncs->destroystream = NPP_DestroyStream; + pFuncs->asfile = NPP_StreamAsFile; + pFuncs->writeready = NPP_WriteReady; + pFuncs->write = NPP_Write; + pFuncs->print = NPP_Print; + pFuncs->event = 0; /// reserved + + g_pluginFuncs = pFuncs; + + return NPERR_NO_ERROR; +} + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// NP_Initialize +// +// called immediately after the plugin DLL is loaded +// +NPError WINAPI NP_EXPORT +NP_Initialize(NPNetscapeFuncs* pFuncs) +{ + // trap a NULL ptr + if(pFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + g_pNavigatorFuncs = pFuncs; // save it for future reference + + // if the plugin's major ver level is lower than the Navigator's, + // then they are incompatible, and should return an error + if(HIBYTE(pFuncs->version) > NP_VERSION_MAJOR) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + + // We have to defer these assignments until g_pNavigatorFuncs is set + int navMinorVers = g_pNavigatorFuncs->version & 0xFF; + + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) { + g_pluginFuncs->urlnotify = NPP_URLNotify; + } + +#ifdef WIN32 // An ugly hack, because Win16 lags behind in Java + if( navMinorVers >= NPVERS_HAS_LIVECONNECT ) { +#else + if( navMinorVers >= NPVERS_WIN16_HAS_LIVECONNECT ) { +#endif // WIN32 + g_pluginFuncs->javaClass = Private_GetJavaClass(); + } + + // NPP_Initialize is a standard (cross-platform) initialize function. + return NPP_Initialize(); +} + +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +// NP_Shutdown +// +// called immediately before the plugin DLL is unloaded. +// This functio shuold check for some ref count on the dll to see if it is +// unloadable or it needs to stay in memory. +// +NPError WINAPI NP_EXPORT +NP_Shutdown() +{ + NPP_Shutdown(); + g_pNavigatorFuncs = NULL; + return NPERR_NO_ERROR; +} + +// END - PLUGIN DLL entry points +////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//. +//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\. + +/* NAVIGATOR Entry points */ + +/* These entry points expect to be called from within the plugin. The + noteworthy assumption is that DS has already been set to point to the + plugin's DLL data segment. Don't call these functions from outside + the plugin without ensuring DS is set to the DLLs data segment first, + typically using the NP_LOADDS macro +*/ + +// TOR +void NPN_InvalidateRect(NPP instance, NPRect *rect) +{ + return g_pNavigatorFuncs->invalidaterect(instance, rect); +} + +/* returns the major/minor version numbers of the Plugin API for the plugin + and the Navigator +*/ +void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor) +{ + *plugin_major = NP_VERSION_MAJOR; + *plugin_minor = NP_VERSION_MINOR; + *netscape_major = HIBYTE(g_pNavigatorFuncs->version); + *netscape_minor = LOBYTE(g_pNavigatorFuncs->version); +} + +/* causes the specified URL to be fetched and streamed in +*/ +NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, void* notifyData) +{ + int navMinorVers = g_pNavigatorFuncs->version & 0xFF; + NPError err; + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) { + err = g_pNavigatorFuncs->geturlnotify(instance, url, target, notifyData); + } + else { + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + } + return err; +} + + +NPError NPN_GetURL(NPP instance, const char *url, const char *target) +{ + return g_pNavigatorFuncs->geturl(instance, url, target); +} + +NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData) +{ + int navMinorVers = g_pNavigatorFuncs->version & 0xFF; + NPError err; + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) { + err = g_pNavigatorFuncs->posturlnotify(instance, url, window, len, buf, file, notifyData); + } + else { + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + } + return err; +} + + +NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file) +{ + return g_pNavigatorFuncs->posturl(instance, url, window, len, buf, file); +} + +/* Requests that a number of bytes be provided on a stream. Typically + this would be used if a stream was in "pull" mode. An optional + position can be provided for streams which are seekable. +*/ +NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) +{ + return g_pNavigatorFuncs->requestread(stream, rangeList); +} + +/* Creates a new stream of data from the plug-in to be interpreted + by Netscape in the current window. + */ +NPError NPN_NewStream(NPP instance, NPMIMEType type, + const char* target, NPStream** stream) +{ + int navMinorVersion = g_pNavigatorFuncs->version & 0xFF; + NPError err; + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) { + err = g_pNavigatorFuncs->newstream(instance, type, target, stream); + } + else { + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + } + return err; +} + +/* Provides len bytes of data. +*/ +int32 NPN_Write(NPP instance, NPStream *stream, int32 len, void *buffer) +{ + int navMinorVersion = g_pNavigatorFuncs->version & 0xFF; + int32 result; + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) { + result = g_pNavigatorFuncs->write(instance, stream, len, buffer); + } + else { + result = -1; + } + return result; +} + +/* Closes a stream object. +reason indicates why the stream was closed. +*/ +NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) +{ + int navMinorVersion = g_pNavigatorFuncs->version & 0xFF; + NPError err; + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) { + err = g_pNavigatorFuncs->destroystream(instance, stream, reason); + } + else { + err = NPERR_INCOMPATIBLE_VERSION_ERROR; + } + return err; +} + +/* Provides a text status message in the Netscape client user interface +*/ +void NPN_Status(NPP instance, const char *message) +{ + g_pNavigatorFuncs->status(instance, message); +} + +/* returns the user agent string of Navigator, which contains version info +*/ +const char* NPN_UserAgent(NPP instance) +{ + return g_pNavigatorFuncs->uagent(instance); +} + +/* allocates memory from the Navigator's memory space. Necessary so that + saved instance data may be freed by Navigator when exiting. +*/ + + +void* NPN_MemAlloc(uint32 size) +{ + return g_pNavigatorFuncs->memalloc(size); +} + +/* reciprocal of MemAlloc() above +*/ +void NPN_MemFree(void* ptr) +{ + g_pNavigatorFuncs->memfree(ptr); +} + +/* private function to Netscape. do not use! + */ +void NPN_ReloadPlugins(NPBool reloadPages) +{ + g_pNavigatorFuncs->reloadplugins(reloadPages); +} + +JRIEnv* NPN_GetJavaEnv(void) +{ + return g_pNavigatorFuncs->getJavaEnv(); +} + +jref NPN_GetJavaPeer(NPP instance) +{ + return g_pNavigatorFuncs->getJavaPeer(instance); +} + diff --git a/rosapps/smartpdf/fitz/apps/pdftool.c b/rosapps/smartpdf/fitz/apps/pdftool.c new file mode 100644 index 00000000000..aa26dfe510b --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/pdftool.c @@ -0,0 +1,1017 @@ +/* + * Swiss army knife for manipulating and debugging PDFs. + * + * There are a few major modes of operation: + * + * show -- pretty-print objects and streams + * draw -- render pages to bitmap + * clean -- simple rewrite of pdf file + * edit -- edit pages (impose and copy operations) + */ + +#include "fitz.h" +#include "mupdf.h" + +/* + * Common operations. + * Parse page selectors. + * Load and decrypt a PDF file. + * Select pages. + */ + +char *srcname = "(null)"; +pdf_xref *src = nil; +pdf_pagetree *srcpages = nil; + +void die(fz_error *eo) +{ + fflush(stdout); + fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg); + fflush(stderr); + abort(); +} + +void closesrc(void) +{ + if (srcpages) + { + pdf_droppagetree(srcpages); + srcpages = nil; + } + + if (src) + { + if (src->store) + { + pdf_dropstore(src->store); + src->store = nil; + } + pdf_closexref(src); + src = nil; + } + + srcname = nil; +} + +void opensrc(char *filename, char *password, int loadpages) +{ + fz_error *error; + + closesrc(); + + srcname = filename; + + error = pdf_newxref(&src); + if (error) + die(error); + + error = pdf_loadxref(src, filename); + if (error) + { + fz_warn("trying to repair"); + error = pdf_repairxref(src, filename); + if (error) + die(error); + } + + error = pdf_decryptxref(src); + if (error) + die(error); + + if (src->crypt) + { + error = pdf_setpassword(src->crypt, password); + if (error) + die(error); + } + + if (loadpages) + { + error = pdf_loadpagetree(&srcpages, src); + if (error) + die(error); + } +} + +void preloadobjstms(void) +{ + fz_error *error; + fz_obj *obj; + int i; + + for (i = 0; i < src->len; i++) + { + if (src->table[i].type == 'o') + { + error = pdf_loadobject(&obj, src, i, 0); + if (error) die(error); + fz_dropobj(obj); + } + } +} + +/* --------------------------------------------------------------------- */ + +/* + * Debug print parts of the PDF. + */ + +int showbinary = 0; +int showdecode = 0; +int showcolumn; + +void showusage(void) +{ + fprintf(stderr, "usage: pdftool show [-bd] [xref] [trailer] [object numbers]\n"); + fprintf(stderr, " -b \tprint streams as raw binary data\n"); + fprintf(stderr, " -d \tdecode streams\n"); + exit(1); +} + +void showtrailer(void) +{ + if (!src) + die(fz_throw("no file specified")); + printf("trailer\n"); + fz_debugobj(src->trailer); + printf("\n\n"); +} + +void showxref(void) +{ + if (!src) + die(fz_throw("no file specified")); + pdf_debugxref(src); + printf("\n"); +} + +void showsafe(unsigned char *buf, int n) +{ + int i; + for (i = 0; i < n; i++) { + if (buf[i] == '\r' || buf[i] == '\n') { + putchar('\n'); + showcolumn = 0; + } + else if (buf[i] < 32 || buf[i] > 126) { + putchar('.'); + showcolumn ++; + } + else { + putchar(buf[i]); + showcolumn ++; + } + if (showcolumn == 79) { + putchar('\n'); + showcolumn = 0; + } + } +} + +void showstream(int num, int gen) +{ + fz_error *error; + fz_stream *stm; + unsigned char buf[2048]; + int n; + + showcolumn = 0; + + if (showdecode) + error = pdf_openstream(&stm, src, num, gen); + else + error = pdf_openrawstream(&stm, src, num, gen); + if (error) + die(error); + + while (1) + { + n = fz_read(stm, buf, sizeof buf); + if (n == 0) + break; + if (n < 0) + die(fz_ioerror(stm)); + + if (showbinary) + fwrite(buf, 1, n, stdout); + else + showsafe(buf, n); + } + + fz_dropstream(stm); +} + +void showobject(int num, int gen) +{ + fz_error *error; + fz_obj *obj; + + if (!src) + die(fz_throw("no file specified")); + + error = pdf_loadobject(&obj, src, num, gen); + if (error) + die(error); + + printf("%d %d obj\n", num, gen); + fz_debugobj(obj); + printf("\n"); + + if (pdf_isstream(src, num, gen)) + { + printf("stream\n"); + showstream(num, gen); + printf("endstream\n"); + } + + printf("endobj\n\n"); + + fz_dropobj(obj); +} + +void +showmain(int argc, char **argv) +{ + int c; + + while ((c = getopt(argc, argv, "bd")) != -1) + { + switch (c) + { + case 'b': showbinary ++; break; + case 'd': showdecode ++; break; + default: + showusage(); + break; + } + } + + if (optind == argc) + showusage(); + + opensrc(argv[optind++], "", 0); + + if (optind == argc) + showtrailer(); + + while (optind < argc) + { + if (!strcmp(argv[optind], "trailer")) + showtrailer(); + else if (!strcmp(argv[optind], "xref")) + showxref(); + else + showobject(atoi(argv[optind]), 0); + optind++; + } +} + +/* --------------------------------------------------------------------- */ + +/* + * Clean tool. + * Rewrite PDF. + * Garbage collect. + * Decompress streams. + * Encrypt or decrypt. + */ + +void +cleanusage(void) +{ + fprintf(stderr, + "usage: pdftool clean [options] input.pdf [outfile.pdf]\n" + " -d -\tpassword for decryption\n" + " -g \tgarbage collect unused objects\n" + " -x \texpand compressed streams\n" + " -e \tencrypt output\n" + " -u -\tset user password for encryption\n" + " -o -\tset owner password\n" + " -p -\tset permissions (combine letters 'pmca')\n" + " -n -\tkey length in bits: 40 <= n <= 128\n"); + exit(1); +} + +void +cleanexpand(void) +{ + fz_error *error; + fz_obj *stmobj; + fz_buffer *buf; + fz_obj *stmlen; + int i, gen; + + for (i = 0; i < src->len; i++) + { + if (src->table[i].type == 'n') + { + gen = src->table[i].gen; + + if (pdf_isstream(src, i, gen)) + { + error = pdf_loadobject(&stmobj, src, i, gen); + if (error) die(error); + + error = pdf_loadstream(&buf, src, i, gen); + if (error) die(error); + + fz_dictdels(stmobj, "Filter"); + fz_dictdels(stmobj, "DecodeParms"); + + error = fz_newint(&stmlen, buf->wp - buf->rp); + if (error) die(error); + error = fz_dictputs(stmobj, "Length", stmlen); + if (error) die(error); + fz_dropobj(stmlen); + + pdf_updateobject(src, i, gen, stmobj); + pdf_updatestream(src, i, gen, buf); + + fz_dropobj(stmobj); + } + } + } +} + +void +cleanmain(int argc, char **argv) +{ + int doencrypt = 0; + int dogarbage = 0; + int doexpand = 0; + pdf_crypt *encrypt = nil; + char *infile; + char *outfile = "out.pdf"; + char *userpw = ""; + char *ownerpw = ""; + unsigned perms = 0xfffff0c0; /* nothing allowed */ + int keylen = 40; + char *password = ""; + fz_error *error; + int c; + + while ((c = getopt(argc, argv, "d:egn:o:p:u:x")) != -1) + { + switch (c) + { + case 'p': + /* see TABLE 3.15 User access permissions */ + perms = 0xfffff0c0; + if (strchr(optarg, 'p')) /* print */ + perms |= (1 << 2) | (1 << 11); + if (strchr(optarg, 'm')) /* modify */ + perms |= (1 << 3) | (1 << 10); + if (strchr(optarg, 'c')) /* copy */ + perms |= (1 << 4) | (1 << 9); + if (strchr(optarg, 'a')) /* annotate / forms */ + perms |= (1 << 5) | (1 << 8); + break; + case 'd': password = optarg; break; + case 'e': doencrypt ++; break; + case 'g': dogarbage ++; break; + case 'n': keylen = atoi(optarg); break; + case 'o': ownerpw = optarg; break; + case 'u': userpw = optarg; break; + case 'x': doexpand ++; break; + default: cleanusage(); break; + } + } + + if (argc - optind < 1) + cleanusage(); + + infile = argv[optind++]; + if (argc - optind > 0) + outfile = argv[optind++]; + + opensrc(infile, password, 0); + + if (doencrypt) + { + fz_obj *id = fz_dictgets(src->trailer, "ID"); + if (!id) + { + error = fz_packobj(&id, "[(ABCDEFGHIJKLMNOP)(ABCDEFGHIJKLMNOP)]"); + if (error) + die(error); + } + else + fz_keepobj(id); + + error = pdf_newencrypt(&encrypt, userpw, ownerpw, perms, keylen, id); + if (error) + die(error); + + fz_dropobj(id); + } + + if (doexpand) + cleanexpand(); + + if (dogarbage) + { + preloadobjstms(); + pdf_garbagecollect(src); + } + + error = pdf_savexref(src, outfile, encrypt); + if (error) + die(error); + + if (encrypt) + pdf_dropcrypt(encrypt); + + pdf_closexref(src); +} + + +/* --------------------------------------------------------------------- */ + +/* + * Draw pages to PPM bitmaps. + */ + +enum { DRAWPNM, DRAWTXT, DRAWXML }; + +fz_renderer *drawgc = nil; +int drawmode = DRAWPNM; +char *drawpattern = "out%0.3d.pnm"; +pdf_page *drawpage = nil; +float drawzoom = 1.0; +int drawrotate = 0; +int drawbands = 1; +int drawcount = 0; + +void +drawusage(void) +{ + fprintf(stderr, + "usage: pdftool draw [options] [file.pdf pages ... ]\n" + " -b -\tdraw page in N bands\n" + " -d -\tpassword for decryption\n" + " -o -\tpattern (%%d for page number) for output file\n" + " -r -\tresolution in dpi\n" + " -t \tutf-8 text output instead of graphics\n" + " -x \txml dump of display tree\n" + " example:\n" + " pdftool draw -o out%%0.3d.pnm a.pdf 1-3,5,9-\n"); + exit(1); +} + +void +drawloadpage(int pagenum) +{ + fz_error *error; + fz_obj *pageobj; + + pageobj = pdf_getpageobject(srcpages, pagenum - 1); + error = pdf_loadpage(&drawpage, src, pageobj); + if (error) + die(error); + + fprintf(stderr, "draw %s page %d mediabox [ %g %g %g %g ] rotate %d\n", + srcname, pagenum, + drawpage->mediabox.x0, drawpage->mediabox.y0, + drawpage->mediabox.x1, drawpage->mediabox.y1, + drawpage->rotate); +} + +void +drawfreepage(void) +{ + pdf_droppage(drawpage); + drawpage = nil; +} + +void +drawpnm(int pagenum) +{ + fz_error *error; + fz_matrix ctm; + fz_irect bbox; + fz_pixmap *pix; + char namebuf[256]; + char buf[256]; + int x, y, w, h, b, bh; + int fd; + + drawloadpage(pagenum); + + ctm = fz_identity(); + ctm = fz_concat(ctm, fz_translate(0, -drawpage->mediabox.y1)); + ctm = fz_concat(ctm, fz_scale(drawzoom, -drawzoom)); + ctm = fz_concat(ctm, fz_rotate(drawrotate + drawpage->rotate)); + + bbox = fz_roundrect(fz_transformaabb(ctm, drawpage->mediabox)); + w = bbox.x1 - bbox.x0; + h = bbox.y1 - bbox.y0; + bh = h / drawbands; + + if (drawpattern) + { + sprintf(namebuf, drawpattern, drawcount++); + fd = open(namebuf, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (fd < 0) + die(fz_throw("ioerror: could not open file '%s'", namebuf)); + } + else + fd = 1; + + sprintf(buf, "P6\n%d %d\n255\n", w, h); + write(fd, buf, strlen(buf)); + + error = fz_newpixmap(&pix, bbox.x0, bbox.y0, w, bh, 4); + if (error) + die(error); + + memset(pix->samples, 0xff, pix->h * pix->w * pix->n); + + for (b = 0; b < drawbands; b++) + { + if (drawbands > 1) + fprintf(stderr, "drawing band %d / %d\n", b + 1, drawbands); + + error = fz_rendertreeover(drawgc, pix, drawpage->tree, ctm); + if (error) + die(error); + + for (y = 0; y < pix->h; y++) + { + unsigned char *src = pix->samples + y * pix->w * 4; + unsigned char *dst = src; + + for (x = 0; x < pix->w; x++) + { + dst[x * 3 + 0] = src[x * 4 + 1]; + dst[x * 3 + 1] = src[x * 4 + 2]; + dst[x * 3 + 2] = src[x * 4 + 3]; + } + + write(fd, dst, pix->w * 3); + + memset(src, 0xff, pix->w * 4); + } + + pix->y += bh; + if (pix->y + pix->h > bbox.y1) + pix->h = bbox.y1 - pix->y; + } + + fz_droppixmap(pix); + + if (drawpattern) + close(fd); + + drawfreepage(); +} + +void +drawtxt(int pagenum) +{ + fz_error *error; + pdf_textline *line; + fz_matrix ctm; + + drawloadpage(pagenum); + + ctm = fz_concat( + fz_translate(0, -drawpage->mediabox.y1), + fz_scale(drawzoom, -drawzoom)); + + error = pdf_loadtextfromtree(&line, drawpage->tree, ctm); + if (error) + die(error); + + pdf_debugtextline(line); + pdf_droptextline(line); + + drawfreepage(); +} + +void +drawxml(int pagenum) +{ + drawloadpage(pagenum); + fz_debugtree(drawpage->tree); + drawfreepage(); +} + +void +drawpages(char *pagelist) +{ + int page, spage, epage; + char *spec, *dash; + + if (!src) + drawusage(); + + spec = strsep(&pagelist, ","); + while (spec) + { + dash = strchr(spec, '-'); + + if (dash == spec) + spage = epage = 1; + else + spage = epage = atoi(spec); + + if (dash) + { + if (strlen(dash) > 1) + epage = atoi(dash + 1); + else + epage = pdf_getpagecount(srcpages); + } + + if (spage > epage) + page = spage, spage = epage, epage = page; + + for (page = spage; page <= epage; page++) + { + if (page < 1 || page > pdf_getpagecount(srcpages)) + continue; + switch (drawmode) + { + case DRAWPNM: drawpnm(page); break; + case DRAWTXT: drawtxt(page); break; + case DRAWXML: drawxml(page); break; + } + } + + spec = strsep(&pagelist, ","); + } +} + +void +drawmain(int argc, char **argv) +{ + fz_error *error; + char *password = ""; + int c; + + while ((c = getopt(argc, argv, "b:d:o:r:tx")) != -1) + { + switch (c) + { + case 'b': drawbands = atoi(optarg); break; + case 'd': password = optarg; break; + case 'o': drawpattern = optarg; break; + case 'r': drawzoom = atof(optarg) / 72.0; break; + case 't': drawmode = DRAWTXT; break; + case 'x': drawmode = DRAWXML; break; + default: + drawusage(); + break; + } + } + + if (optind == argc) + drawusage(); + + error = fz_newrenderer(&drawgc, pdf_devicergb, 0, 1024 * 512); + if (error) + die(error); + + while (optind < argc) + { + if (strstr(argv[optind], ".pdf")) + opensrc(argv[optind], password, 1); + else + drawpages(argv[optind]); + optind++; + } + + closesrc(); + + fz_droprenderer(drawgc); +} + +/* --------------------------------------------------------------------- */ + +/* + * Edit tool. + * Copy or impose pages from other pdf files into output pdf. + */ + +/* for each source pdf, build a list of objects to transplant. + * for each source pdf, do the transplants at the end of object collecting. + * build a new page tree structure for output. + * change page nodes into xobjects for over and n-up modes. + * create new page nodes. + * create new page tree. + */ + +enum { COPY, OVER, NUP2, NUP4, NUP8 }; + +pdf_xref *editxref = nil; +fz_obj *editpagelist = nil; +fz_obj *editmodelist = nil; +fz_obj *editobjects = nil; +int editmode = COPY; + +void +editusage(void) +{ + fprintf(stderr, "usage: pdftool edit [-o file.pdf] [mode file.pdf pages ... ]\n"); + fprintf(stderr, " mode is one of: copy over 2up 4up 8up\n"); + fprintf(stderr, " pages is a comma separated list of ranges\n"); + fprintf(stderr, " example:\n"); + fprintf(stderr, " pdftool edit -o output.pdf copy one.pdf 1-3,5,9 two.pdf 1-\n"); + exit(1); +} + +void +editcopy(int pagenum) +{ + fz_error *error; + fz_obj *obj; + fz_obj *ref; + fz_obj *num; + + printf("copy %s page %d\n", srcname, pagenum); + + ref = srcpages->pref[pagenum - 1]; + obj = pdf_getpageobject(srcpages, pagenum - 1); + + fz_dictdels(obj, "Parent"); + // fz_dictdels(obj, "B"); + // fz_dictdels(obj, "PieceInfo"); + // fz_dictdels(obj, "Metadata"); + // fz_dictdels(obj, "Annots"); + // fz_dictdels(obj, "Tabs"); + + pdf_updateobject(src, fz_tonum(ref), fz_togen(ref), obj); + + error = fz_arraypush(editobjects, ref); + if (error) + die(error); + + error = fz_newint(&num, editmode); + if (error) + die(error); + + error = fz_arraypush(editmodelist, num); + if (error) + die(error); + + fz_dropobj(num); +} + +void +editflushobjects(void) +{ + fz_error *error; + fz_obj *results; + int i; + + error = pdf_transplant(editxref, src, &results, editobjects); + if (error) + die(error); + + for (i = 0; i < fz_arraylen(results); i++) + { + error = fz_arraypush(editpagelist, fz_arrayget(results, i)); + if (error) + die(error); + } + + fz_dropobj(results); +} + +void +editflushpagetree(void) +{ + + /* TODO: merge pages where editmode != COPY by turning them into XObjects + and creating a new page object with resource dictionary and content + stream placing the xobjects on the page. */ +} + +void +editflushcatalog(void) +{ + fz_error *error; + int rootnum, rootgen; + int listnum, listgen; + fz_obj *listref; + fz_obj *obj; + int i; + + /* Create page tree and add back-links */ + + error = pdf_allocobject(editxref, &listnum, &listgen); + if (error) + die(error); + + error = fz_packobj(&obj, "<>", + fz_arraylen(editpagelist), + editpagelist); + if (error) + die(error); + + pdf_updateobject(editxref, listnum, listgen, obj); + + fz_dropobj(obj); + + error = fz_newindirect(&listref, listnum, listgen); + if (error) + die(error); + + for (i = 0; i < fz_arraylen(editpagelist); i++) + { + int num = fz_tonum(fz_arrayget(editpagelist, i)); + int gen = fz_togen(fz_arrayget(editpagelist, i)); + + error = pdf_loadobject(&obj, editxref, num, gen); + if (error) + die(error); + + error = fz_dictputs(obj, "Parent", listref); + if (error) + die(error); + + pdf_updateobject(editxref, num, gen, obj); + + fz_dropobj(obj); + } + + /* Create catalog */ + + error = pdf_allocobject(editxref, &rootnum, &rootgen); + if (error) + die(error); + + error = fz_packobj(&obj, "<>", listnum, listgen); + if (error) + die(error); + + pdf_updateobject(editxref, rootnum, rootgen, obj); + + fz_dropobj(obj); + + /* Create trailer */ + + error = fz_packobj(&editxref->trailer, "<>", rootnum, rootgen); + if (error) + die(error); +} + +void +editpages(char *pagelist) +{ + int page, spage, epage; + char *spec, *dash; + + if (!src) + editusage(); + + spec = strsep(&pagelist, ","); + while (spec) + { + dash = strchr(spec, '-'); + + if (dash == spec) + spage = epage = 1; + else + spage = epage = atoi(spec); + + if (dash) + { + if (strlen(dash) > 1) + epage = atoi(dash + 1); + else + epage = pdf_getpagecount(srcpages); + } + + if (spage > epage) + page = spage, spage = epage, epage = page; + + for (page = spage; page <= epage; page++) + { + if (page < 1 || page > pdf_getpagecount(srcpages)) + continue; + editcopy(page); + } + + spec = strsep(&pagelist, ","); + } +} + +void +editmain(int argc, char **argv) +{ + char *outfile = "out.pdf"; + fz_error *error; + int c; + + while ((c = getopt(argc, argv, "o:")) != -1) + { + switch (c) + { + case 'o': + outfile = optarg; + break; + default: + editusage(); + break; + } + } + + if (optind == argc) + editusage(); + + error = pdf_newxref(&editxref); + if (error) + die(error); + + error = pdf_initxref(editxref); + if (error) + die(error); + + error = fz_newarray(&editpagelist, 100); + if (error) + die(error); + + error = fz_newarray(&editmodelist, 100); + if (error) + die(error); + + while (optind < argc) + { + if (strstr(argv[optind], ".pdf")) + { + if (editobjects) + editflushobjects(); + + opensrc(argv[optind], "", 1); + + error = fz_newarray(&editobjects, 100); + if (error) + die(error); + } + else if (!strcmp(argv[optind], "copy")) + editmode = COPY; + else if (!strcmp(argv[optind], "over")) + editmode = OVER; + else if (!strcmp(argv[optind], "2up")) + editmode = NUP2; + else if (!strcmp(argv[optind], "4up")) + editmode = NUP4; + else if (!strcmp(argv[optind], "8up")) + editmode = NUP8; + else + editpages(argv[optind]); + optind++; + } + + if (editobjects) + editflushobjects(); + + closesrc(); + + editflushpagetree(); + editflushcatalog(); + + error = pdf_savexref(editxref, outfile, nil); + if (error) + die(error); + + pdf_closexref(editxref); +} + +/* --------------------------------------------------------------------- */ + +/* + * Main! + */ + +void +mainusage(void) +{ + fprintf(stderr, "usage: pdftool [options...]\n"); + fprintf(stderr, " command is one of: show, draw, clean, edit\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + if (argc >= 2) + { + optind = 2; + if (!strcmp(argv[1], "show")) + showmain(argc, argv); + else if (!strcmp(argv[1], "draw")) + drawmain(argc, argv); + else if (!strcmp(argv[1], "clean")) + cleanmain(argc, argv); + else if (!strcmp(argv[1], "edit")) + editmain(argc, argv); + else + mainusage(); + } + else + mainusage(); + return 0; +} + diff --git a/rosapps/smartpdf/fitz/apps/samshow.c b/rosapps/smartpdf/fitz/apps/samshow.c new file mode 100644 index 00000000000..a1563c9d159 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/samshow.c @@ -0,0 +1,188 @@ +#include "fitz.h" +#include "samus.h" + +void die(fz_error *eo) +{ + fflush(stdout); + fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg); + fflush(stderr); + abort(); +} + +void showfixdocseq(sa_package *pack, char *part) +{ + fz_error *error; + sa_fixdocseq *seq; + + error = sa_loadfixdocseq(&seq, pack, part); + if (error) + die(error); + + sa_debugfixdocseq(seq); + + sa_dropfixdocseq(seq); +} + +void showreach(sa_package *pack, sa_relation *rels) +{ + while (rels) + { + if (!strcmp(rels->type, SA_REL_FIXEDREPRESENTATION)) + { + if (!rels->external) + showfixdocseq(pack, rels->target); + } + rels = rels->next; + } +} + +int runpack(int argc, char **argv) +{ + fz_error *error; + sa_package *pack; + sa_relation *rels; + char *s; + int i; + + error = sa_openpackage(&pack, argv[1]); + if (error) + die(error); + + sa_debugpackage(pack); + printf("\n"); + + error = sa_loadrelations(&rels, pack, "/"); + if (error) + die(error); + sa_debugrelations(rels); + printf("\n"); + + if (argc == 2) + { + showreach(pack, rels); + return 0; + } + + for (i = 2; i < argc; i++) + { + printf("part %s\n", argv[i]); + + s = sa_typepart(pack, argv[i]); + if (!s) + printf("has no type!\n"); + else + printf("type %s\n", s); + + error = sa_loadrelations(&rels, pack, argv[i]); + if (error) + die(error); + sa_debugrelations(rels); + sa_droprelations(rels); + + printf("\n"); + } + + sa_closepackage(pack); + + return 0; +} + +int runzip(int argc, char **argv) +{ + fz_error *error; + fz_buffer *buf; + fz_stream *stm; + sa_zip *zip; + int i, n; + + error = sa_openzip(&zip, argv[1]); + if (error) + die(error); + + if (argc == 2) + sa_debugzip(zip); + + for (i = 2; i < argc; i++) + { + error = sa_openzipentry(&stm, zip, argv[i]); + if (error) + die(error); + n = fz_readall(&buf, stm); + if (n < 0) + die(fz_ioerror(stm)); + fz_dropstream(stm); + + fwrite(buf->rp, 1, buf->wp - buf->rp, stdout); + + fz_dropbuffer(buf); + } + + sa_closezip(zip); + + return 0; +} + +int runxml(int argc, char **argv) +{ + fz_error *error; + fz_stream *file; + sa_xmlparser *parser; + sa_xmlitem *item; + + error = fz_openrfile(&file, argv[1]); + if (error) + die(error); + + error = sa_openxml(&parser, file, 0); + if (error) + die(error); + + item = sa_xmlnext(parser); + if (item) + sa_debugxml(item, 0); + + sa_closexml(parser); + fz_dropstream(file); + + return 0; +} + +extern fz_error *sa_readtiff(fz_stream *); + +int runtiff(int argc, char **argv) +{ + fz_error *error; + fz_stream *file; + + error = fz_openrfile(&file, argv[1]); + if (error) + die(error); + + error = sa_readtiff(file); + if (error) + die(error); + + fz_dropstream(file); + + return 0; +} + +int main(int argc, char **argv) +{ + if (argc >= 2) + { + if (strstr(argv[1], "zip")) + return runzip(argc, argv); + if (strstr(argv[1], "xml")) + return runxml(argc, argv); + if (strstr(argv[1], "tif")) + return runtiff(argc, argv); + return runpack(argc, argv); + } + + fprintf(stderr, "usage: samshow \n"); + fprintf(stderr, "usage: samshow \n"); + fprintf(stderr, "usage: samshow \n"); + return 1; +} + diff --git a/rosapps/smartpdf/fitz/apps/unix/gs_l.xbm b/rosapps/smartpdf/fitz/apps/unix/gs_l.xbm new file mode 100644 index 00000000000..85014e439ee --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/unix/gs_l.xbm @@ -0,0 +1,29 @@ +#define gs_l_xbm_width 48 +#define gs_l_xbm_height 48 +#define gs_l_xbm_x_hot 0 +#define gs_l_xbm_y_hot 0 +static unsigned char gs_l_xbm_bits[] = { + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x07, 0x00, + 0x00, 0xe0, 0xff, 0x0f, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x81, 0x07, 0x00, + 0x00, 0xfc, 0x1f, 0xc0, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0xf0, 0x1f, 0x00, + 0x00, 0xff, 0x01, 0xf8, 0x1f, 0x00, 0x00, 0xff, 0x41, 0xfc, 0x3f, 0x00, + 0x80, 0xff, 0xc8, 0xfc, 0x3f, 0x00, 0x80, 0xff, 0xd8, 0xf8, 0x3f, 0x00, + 0x80, 0xff, 0x98, 0xf0, 0x3f, 0x00, 0x80, 0xff, 0x10, 0xe0, 0x3f, 0x00, + 0x00, 0xff, 0x01, 0xc0, 0x3f, 0x00, 0x00, 0xff, 0x81, 0x81, 0x1f, 0x00, + 0x00, 0xfe, 0x83, 0x83, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x83, 0x0f, 0x00, + 0x00, 0xf8, 0x1f, 0xc3, 0x03, 0x00, 0x00, 0xe0, 0x1f, 0xe0, 0x01, 0x00, + 0x00, 0xf0, 0x1f, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0xff, 0xff, 0x01, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x03, + 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x03, + 0xc0, 0x3f, 0x00, 0x00, 0xff, 0x03, 0xe0, 0x0f, 0x00, 0x00, 0xfe, 0x03, + 0xf0, 0x07, 0xfc, 0x00, 0xfc, 0x01, 0xf0, 0x07, 0x0e, 0x00, 0xff, 0x04, + 0xf0, 0x07, 0x7e, 0xe0, 0x7f, 0x02, 0xf0, 0x0f, 0xfc, 0xff, 0x1f, 0x01, + 0xe0, 0x1f, 0xf0, 0xff, 0xc3, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x78, 0x00, + 0x80, 0xff, 0x0f, 0xf8, 0x3f, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/rosapps/smartpdf/fitz/apps/unix/x11pdf.c b/rosapps/smartpdf/fitz/apps/unix/x11pdf.c new file mode 100644 index 00000000000..d97d0bc9450 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/unix/x11pdf.c @@ -0,0 +1,511 @@ +#include "fitz.h" +#include "mupdf.h" +#include "pdfapp.h" + +#include "gs_l.xbm" + +#include +#include +#include +#include +#include + +extern int ximage_init(Display *display, int screen, Visual *visual); +extern int ximage_get_depth(void); +extern Visual *ximage_get_visual(void); +extern Colormap ximage_get_colormap(void); +extern void ximage_blit(Drawable d, GC gc, int dstx, int dsty, + unsigned char *srcdata, + int srcx, int srcy, int srcw, int srch, int srcstride); + +static Display *xdpy; +static Atom XA_TARGETS; +static Atom XA_TIMESTAMP; +static Atom XA_UTF8_STRING; +static int xscr; +static Window xwin; +static GC xgc; +static XEvent xevt; +static int mapped = 0; +static Cursor xcarrow, xchand, xcwait; +static int justcopied = 0; +static int dirty = 0; +static char *password = ""; +static XColor xbgcolor; +static XColor xshcolor; +static int reqw = 0; +static int reqh = 0; +static char copylatin1[1024 * 16] = ""; +static char copyutf8[1024 * 48] = ""; +static Time copytime; + +static pdfapp_t gapp; + +/* + * Dialog boxes + */ + +void winwarn(pdfapp_t *app, char *msg) +{ + fprintf(stderr, "apparition: %s\n", msg); +} + +void winerror(pdfapp_t *app, char *msg) +{ + fprintf(stderr, "apparition: %s\n", msg); + exit(1); +} + +char *winpassword(pdfapp_t *app, char *filename) +{ + char *r = password; + password = NULL; + return r; +} + +/* + * X11 magic + */ + +void winopen(void) +{ + XWMHints *hints; + + xdpy = XOpenDisplay(nil); + if (!xdpy) + winerror(&gapp, "could not open display."); + + XA_TARGETS = XInternAtom(xdpy, "TARGETS", False); + XA_TIMESTAMP = XInternAtom(xdpy, "TIMESTAMP", False); + XA_UTF8_STRING = XInternAtom(xdpy, "UTF8_STRING", False); + + xscr = DefaultScreen(xdpy); + + ximage_init(xdpy, xscr, DefaultVisual(xdpy, xscr)); + + xcarrow = XCreateFontCursor(xdpy, XC_left_ptr); + xchand = XCreateFontCursor(xdpy, XC_hand2); + xcwait = XCreateFontCursor(xdpy, XC_watch); + + xbgcolor.red = 0x7000; + xbgcolor.green = 0x7000; + xbgcolor.blue = 0x7000; + + xshcolor.red = 0x4000; + xshcolor.green = 0x4000; + xshcolor.blue = 0x4000; + + XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xbgcolor); + XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xshcolor); + + xwin = XCreateWindow(xdpy, DefaultRootWindow(xdpy), + 10, 10, 200, 100, 1, + ximage_get_depth(), + InputOutput, + ximage_get_visual(), + 0, + nil); + + XSetWindowColormap(xdpy, xwin, ximage_get_colormap()); + XSelectInput(xdpy, xwin, + StructureNotifyMask | ExposureMask | KeyPressMask | + PointerMotionMask | ButtonPressMask | ButtonReleaseMask); + + mapped = 0; + + xgc = XCreateGC(xdpy, xwin, 0, nil); + + XDefineCursor(xdpy, xwin, xcarrow); + + hints = XAllocWMHints(); + if (hints) + { + hints->flags = IconPixmapHint; + hints->icon_pixmap = XCreateBitmapFromData(xdpy, xwin, + gs_l_xbm_bits, gs_l_xbm_width, gs_l_xbm_height); + if (hints->icon_pixmap) + { + XSetWMHints(xdpy, xwin, hints); + } + XFree(hints); + } +} + +void wincursor(pdfapp_t *app, int curs) +{ + if (curs == ARROW) + XDefineCursor(xdpy, xwin, xcarrow); + if (curs == HAND) + XDefineCursor(xdpy, xwin, xchand); + if (curs == WAIT) + XDefineCursor(xdpy, xwin, xcwait); + XFlush(xdpy); +} + +void wintitle(pdfapp_t *app, char *s) +{ +#ifdef X_HAVE_UTF8_STRING + Xutf8SetWMProperties(xdpy, xwin, s, s, 0, 0, 0, 0, 0); +#else + XmbSetWMProperties(xdpy, xwin, s, s, 0, 0, 0, 0, 0); +#endif +} + +void winconvert(pdfapp_t *app, fz_pixmap *image) +{ + // never mind +} + +void winresize(pdfapp_t *app, int w, int h) +{ + XWindowChanges values; + int mask; + + mask = CWWidth | CWHeight; + values.width = w; + values.height = h; + XConfigureWindow(xdpy, xwin, mask, &values); + + reqw = w; + reqh = h; + + if (!mapped) + { + gapp.winw = w; + gapp.winh = h; + + XMapWindow(xdpy, xwin); + XFlush(xdpy); + + while (1) + { + XNextEvent(xdpy, &xevt); + if (xevt.type == MapNotify) + break; + } + + XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr)); + XFillRectangle(xdpy, xwin, xgc, 0, 0, gapp.image->w, gapp.image->h); + XFlush(xdpy); + + mapped = 1; + } +} + +static void fillrect(int x, int y, int w, int h) +{ + if (w > 0 && h > 0) + XFillRectangle(xdpy, xwin, xgc, x, y, w, h); +} + +static void invertcopyrect() +{ + unsigned t, *p; + int x, y; + + int x0 = gapp.selr.x0 - gapp.panx; + int x1 = gapp.selr.x1 - gapp.panx; + int y0 = gapp.selr.y0 - gapp.pany; + int y1 = gapp.selr.y1 - gapp.pany; + + x0 = CLAMP(x0, 0, gapp.image->w - 1); + x1 = CLAMP(x1, 0, gapp.image->w - 1); + y0 = CLAMP(y0, 0, gapp.image->h - 1); + y1 = CLAMP(y1, 0, gapp.image->h - 1); + + for (y = y0; y < y1; y++) + { + p = (unsigned *)(gapp.image->samples + (y * gapp.image->w + x0) * 4); + for (x = x0; x < x1; x++) + { + *p = ~0 - *p; + p ++; + } + } + + justcopied = 1; +} + +void winblit(pdfapp_t *app) +{ + int x0 = gapp.panx; + int y0 = gapp.pany; + int x1 = gapp.panx + gapp.image->w; + int y1 = gapp.pany + gapp.image->h; + + XSetForeground(xdpy, xgc, xbgcolor.pixel); + fillrect(0, 0, x0, gapp.winh); + fillrect(x1, 0, gapp.winw - x1, gapp.winh); + fillrect(0, 0, gapp.winw, y0); + fillrect(0, y1, gapp.winw, gapp.winh - y1); + + XSetForeground(xdpy, xgc, xshcolor.pixel); + fillrect(x0+2, y1, gapp.image->w, 2); + fillrect(x1, y0+2, 2, gapp.image->h); + + if (gapp.iscopying || justcopied) + invertcopyrect(); + + ximage_blit(xwin, xgc, + x0, y0, + gapp.image->samples, + 0, 0, + gapp.image->w, + gapp.image->h, + gapp.image->w * gapp.image->n); + + if (gapp.iscopying || justcopied) + invertcopyrect(); +} + +void winrepaint(pdfapp_t *app) +{ + dirty = 1; +} + +void windocopy(pdfapp_t *app) +{ + unsigned short copyucs2[16 * 1024]; + char *latin1 = copylatin1; + char *utf8 = copyutf8; + unsigned short *ucs2; + int ucs; + + pdfapp_oncopy(&gapp, copyucs2, 16 * 1024); + + for (ucs2 = copyucs2; ucs2[0] != 0; ucs2++) + { + ucs = ucs2[0]; + + utf8 += runetochar(utf8, &ucs); + + if (ucs < 256) + *latin1++ = ucs; + else + *latin1++ = '?'; + } + + *utf8 = 0; + *latin1 = 0; + +printf("oncopy utf8=%d latin1=%d\n", strlen(copyutf8), strlen(copylatin1)); + + XSetSelectionOwner(xdpy, XA_PRIMARY, xwin, copytime); + + justcopied = 1; +} + +void onselreq(Window requestor, Atom selection, Atom target, Atom property, Time time) +{ + XEvent nevt; + +printf("onselreq\n"); + + if (property == None) + property = target; + + nevt.xselection.type = SelectionNotify; + nevt.xselection.send_event = True; + nevt.xselection.display = xdpy; + nevt.xselection.requestor = requestor; + nevt.xselection.selection = selection; + nevt.xselection.target = target; + nevt.xselection.property = property; + nevt.xselection.time = time; + + if (target == XA_TARGETS) + { + Atom atomlist[4]; + atomlist[0] = XA_TARGETS; + atomlist[1] = XA_TIMESTAMP; + atomlist[2] = XA_STRING; + atomlist[3] = XA_UTF8_STRING; +printf(" -> targets\n"); + XChangeProperty(xdpy, requestor, property, target, + 32, PropModeReplace, + (unsigned char *)atomlist, sizeof(atomlist)/sizeof(Atom)); + } + + else if (target == XA_STRING) + { +printf(" -> string %d\n", strlen(copylatin1)); + XChangeProperty(xdpy, requestor, property, target, + 8, PropModeReplace, + (unsigned char *)copylatin1, strlen(copylatin1)); + } + + else if (target == XA_UTF8_STRING) + { +printf(" -> utf8string\n"); + XChangeProperty(xdpy, requestor, property, target, + 8, PropModeReplace, + (unsigned char *)copyutf8, strlen(copyutf8)); + } + + else + { +printf(" -> unknown\n"); + nevt.xselection.property = None; + } + + XSendEvent(xdpy, requestor, False, SelectionNotify, &nevt); +} + +void winopenuri(pdfapp_t *app, char *buf) +{ + char cmd[2048]; + if (getenv("BROWSER")) + sprintf(cmd, "$BROWSER %s &", buf); + else + sprintf(cmd, "open %s", buf); + system(cmd); +} + +void onkey(int c) +{ + if (justcopied) + { + justcopied = 0; + winrepaint(&gapp); + } + + if (c == 'q') + exit(0); + + pdfapp_onkey(&gapp, c); +} + +void onmouse(int x, int y, int btn, int modifiers, int state) +{ + if (state != 0 && justcopied) + { + justcopied = 0; + winrepaint(&gapp); + } + + pdfapp_onmouse(&gapp, x, y, btn, modifiers, state); +} + +void usage(void) +{ + fprintf(stderr, "usage: apparition [-d password] [-z zoom] [-p pagenumber] file.pdf\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + char *filename; + int c; + int len; + unsigned char buf[128]; + KeySym keysym; + int oldx = 0; + int oldy = 0; + double zoom = 1.0; + int pageno = 1; + + while ((c = getopt(argc, argv, "d:z:p:")) != -1) + { + switch (c) + { + case 'd': password = optarg; break; + case 'z': zoom = atof(optarg); break; + case 'p': pageno = atoi(optarg); break; + default: usage(); + } + } + + if (argc - optind == 0) + usage(); + + filename = argv[optind++]; + + fz_cpudetect(); + fz_accelerate(); + + winopen(); + + pdfapp_init(&gapp); + gapp.scrw = DisplayWidth(xdpy, xscr); + gapp.scrh = DisplayHeight(xdpy, xscr); + gapp.zoom = zoom; + gapp.pageno = pageno; + + pdfapp_open(&gapp, filename); + + while (1) + { + do + { + XNextEvent(xdpy, &xevt); + + switch (xevt.type) + { + case Expose: + dirty = 1; + break; + + case ConfigureNotify: + if (gapp.image) + { + if (xevt.xconfigure.width != reqw || + xevt.xconfigure.height != reqh) + gapp.shrinkwrap = 0; + } + pdfapp_onresize(&gapp, + xevt.xconfigure.width, + xevt.xconfigure.height); + break; + + case KeyPress: + len = XLookupString(&xevt.xkey, buf, sizeof buf, &keysym, 0); + if (len) + onkey(buf[0]); + onmouse(oldx, oldy, 0, 0, 0); + + if (dirty) + { + winblit(&gapp); + dirty = 0; + } + + break; + + case MotionNotify: + oldx = xevt.xbutton.x; + oldy = xevt.xbutton.y; + onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 0); + break; + + case ButtonPress: + onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 1); + break; + + case ButtonRelease: + copytime = xevt.xbutton.time; + onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, -1); + break; + + case SelectionRequest: + onselreq(xevt.xselectionrequest.requestor, + xevt.xselectionrequest.selection, + xevt.xselectionrequest.target, + xevt.xselectionrequest.property, + xevt.xselectionrequest.time); + break; + } + } + while (XPending(xdpy)); + + if (dirty) + { + winblit(&gapp); + dirty = 0; + } + } + + pdfapp_close(&gapp); + + return 0; +} + diff --git a/rosapps/smartpdf/fitz/apps/unix/ximage.c b/rosapps/smartpdf/fitz/apps/unix/ximage.c new file mode 100644 index 00000000000..b37cf544acf --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/unix/ximage.c @@ -0,0 +1,672 @@ +/* + * Blit ARGB images to X with X(Shm)Images + */ + +#include + +#include +#include +#include +#include +#include + +extern int ffs(int); + +typedef void (*ximage_convert_func_t) + ( + const unsigned char *src, + int srcstride, + unsigned char *dst, + int dststride, + int w, + int h + ); + +#define POOLSIZE 4 +#define WIDTH 256 +#define HEIGHT 256 + +enum { + ARGB8888, + BGRA8888, + RGBA8888, + ABGR8888, + RGB888, + BGR888, + RGB565, + RGB565_BR, + RGB555, + RGB555_BR, + BGR233, + UNKNOWN +}; + +static char *modename[] = { + "ARGB8888", + "BGRA8888", + "RGBA8888", + "ABGR8888", + "RGB888", + "BGR888", + "RGB565", + "RGB565_BR", + "RGB555", + "RGB555_BR", + "BGR233", + "UNKNOWN" +}; + +extern ximage_convert_func_t ximage_convert_funcs[]; + +static struct +{ + Display *display; + int screen; + XVisualInfo visual; + Colormap colormap; + + int bitsperpixel; + int mode; + + XColor rgbcube[256]; + + ximage_convert_func_t convert_func; + + int useshm; + XImage *pool[POOLSIZE]; + /* MUST exist during the lifetime of the shared ximage according to the + xc/doc/hardcopy/Xext/mit-shm.PS.gz */ + XShmSegmentInfo shminfo[POOLSIZE]; + int lastused; +} info; + +static XImage * +createximage(Display *dpy, Visual *vis, XShmSegmentInfo *xsi, int depth, int w, int h) +{ + XImage *img; + Status status; + + if (!XShmQueryExtension(dpy)) goto fallback; + + img = XShmCreateImage(dpy, vis, depth, ZPixmap, nil, xsi, w, h); + if (!img) + { + fprintf(stderr, "warn: could not XShmCreateImage\n"); + goto fallback; + } + + xsi->shmid = shmget(IPC_PRIVATE, + img->bytes_per_line * img->height, + IPC_CREAT | 0777); + if (xsi->shmid < 0) + { + XDestroyImage(img); + fprintf(stderr, "warn: could not shmget\n"); + goto fallback; + } + + img->data = xsi->shmaddr = shmat(xsi->shmid, 0, 0); + if (img->data == (char*)-1) + { + XDestroyImage(img); + fprintf(stderr, "warn: could not shmat\n"); + goto fallback; + } + + xsi->readOnly = False; + status = XShmAttach(dpy, xsi); + if (!status) + { + shmdt(xsi->shmaddr); + XDestroyImage(img); + fprintf(stderr, "warn: could not XShmAttach\n"); + goto fallback; + } + + XSync(dpy, False); + + shmctl(xsi->shmid, IPC_RMID, 0); + + return img; + +fallback: + info.useshm = 0; + + img = XCreateImage(dpy, vis, depth, ZPixmap, 0, 0, w, h, 32, 0); + if (!img) + { + fprintf(stderr, "fail: could not XCreateImage"); + abort(); + } + + img->data = malloc(h * img->bytes_per_line); + if (!img->data) + { + fprintf(stderr, "fail: could not malloc"); + abort(); + } + + return img; +} + +static void +make_colormap(void) +{ + if (info.visual.class == PseudoColor && info.visual.depth == 8) + { + int i, r, g, b; + i = 0; + for (b = 0; b < 4; b++) { + for (g = 0; g < 8; g++) { + for (r = 0; r < 8; r++) { + info.rgbcube[i].pixel = i; + info.rgbcube[i].red = (r * 36) << 8; + info.rgbcube[i].green = (g * 36) << 8; + info.rgbcube[i].blue = (b * 85) << 8; + info.rgbcube[i].flags = + DoRed | DoGreen | DoBlue; + i++; + } + } + } + info.colormap = XCreateColormap(info.display, + RootWindow(info.display, info.screen), + info.visual.visual, + AllocAll); + XStoreColors(info.display, info.colormap, info.rgbcube, 256); + return; + } + else if (info.visual.class == TrueColor) + { + info.colormap = 0; + return; + } + fprintf(stderr, "Cannot handle visual class %d with depth: %d\n", + info.visual.class, info.visual.depth); + return; +} + +static void +select_mode(void) +{ + + int byteorder; + int byterev; + unsigned long rm, gm, bm; + unsigned long rs, gs, bs; + + byteorder = ImageByteOrder(info.display); +#if BYTE_ORDER == BIG_ENDIAN + byterev = byteorder != MSBFirst; +#else + byterev = byteorder != LSBFirst; +#endif + + rm = info.visual.red_mask; + gm = info.visual.green_mask; + bm = info.visual.blue_mask; + + rs = ffs(rm) - 1; + gs = ffs(gm) - 1; + bs = ffs(bm) - 1; + + printf("ximage: mode %d/%d %08lx %08lx %08lx (%ld,%ld,%ld) %s%s\n", + info.visual.depth, + info.bitsperpixel, + rm, gm, bm, rs, gs, bs, + byteorder == MSBFirst ? "msb" : "lsb", + byterev ? " ":""); + + info.mode = UNKNOWN; + if (info.bitsperpixel == 8) { + /* Either PseudoColor with BGR233 colormap, or TrueColor */ + info.mode = BGR233; + } + else if (info.bitsperpixel == 16) { + if (rm == 0xF800 && gm == 0x07E0 && bm == 0x001F) + info.mode = !byterev ? RGB565 : RGB565_BR; + if (rm == 0x7C00 && gm == 0x03E0 && bm == 0x001F) + info.mode = !byterev ? RGB555 : RGB555_BR; + } + else if (info.bitsperpixel == 24) { + if (rs == 0 && gs == 8 && bs == 16) + info.mode = byteorder == MSBFirst ? RGB888 : BGR888; + if (rs == 16 && gs == 8 && bs == 0) + info.mode = byteorder == MSBFirst ? BGR888 : RGB888; + } + else if (info.bitsperpixel == 32) { + if (rs == 0 && gs == 8 && bs == 16) + info.mode = byteorder == MSBFirst ? ABGR8888 : RGBA8888; + if (rs == 8 && gs == 16 && bs == 24) + info.mode = byteorder == MSBFirst ? BGRA8888 : ARGB8888; + if (rs == 16 && gs == 8 && bs == 0) + info.mode = byteorder == MSBFirst ? ARGB8888 : BGRA8888; + if (rs == 24 && gs == 16 && bs == 8) + info.mode = byteorder == MSBFirst ? RGBA8888 : ABGR8888; + } + + printf("ximage: ARGB8888 to %s\n", modename[info.mode]); + + /* select conversion function */ + info.convert_func = ximage_convert_funcs[info.mode]; +} + +static int +create_pool(void) +{ + int i; + + info.lastused = 0; + + for (i = 0; i < POOLSIZE; i++) { + info.pool[i] = nil; + } + + for (i = 0; i < POOLSIZE; i++) { + info.pool[i] = createximage(info.display, + info.visual.visual, &info.shminfo[i], info.visual.depth, + WIDTH, HEIGHT); + if (info.pool[i] == nil) { + return 0; + } + } + + return 1; +} + +static XImage * +next_pool_image(void) +{ + if (info.lastused + 1 >= POOLSIZE) { + if (info.useshm) + XSync(info.display, False); + else + XFlush(info.display); + info.lastused = 0; + } + return info.pool[info.lastused ++]; +} + +int +ximage_init(Display *display, int screen, Visual *visual) +{ + XVisualInfo template; + XVisualInfo *visuals; + int nvisuals; + XPixmapFormatValues *formats; + int nformats; + int ok; + int i; + + info.display = display; + info.screen = screen; + info.colormap = 0; + + /* Get XVisualInfo for this visual */ + template.visualid = XVisualIDFromVisual(visual); + visuals = XGetVisualInfo(display, VisualIDMask, &template, &nvisuals); + if (nvisuals != 1) { + fprintf(stderr, "Visual not found!\n"); + XFree(visuals); + return 0; + } + memcpy(&info.visual, visuals, sizeof (XVisualInfo)); + XFree(visuals); + + /* Get appropriate PixmapFormat for this visual */ + formats = XListPixmapFormats(info.display, &nformats); + for (i = 0; i < nformats; i++) { + if (formats[i].depth == info.visual.depth) { + info.bitsperpixel = formats[i].bits_per_pixel; + break; + } + } + XFree(formats); + if (i == nformats) { + fprintf(stderr, "PixmapFormat not found!\n"); + return 0; + } + + /* extract mode */ + select_mode(); + + /* prepare colormap */ + make_colormap(); + + /* prepare pool of XImages */ + info.useshm = 1; + ok = create_pool(); + if (!ok) + return 0; + + printf("ximage: %sPutImage\n", info.useshm ? "XShm" : "X"); + + return 1; +} + +int +ximage_get_depth(void) +{ + return info.visual.depth; +} + +Visual * +ximage_get_visual(void) +{ + return info.visual.visual; +} + +Colormap +ximage_get_colormap(void) +{ + return info.colormap; +} + +void +ximage_blit(Drawable d, GC gc, + int dstx, int dsty, + unsigned char *srcdata, + int srcx, int srcy, + int srcw, int srch, + int srcstride) +{ + XImage *image; + int ax, ay; + int w, h; + unsigned char *srcptr; + + for (ay = 0; ay < srch; ay += HEIGHT) + { + h = MIN(srch - ay, HEIGHT); + for (ax = 0; ax < srcw; ax += WIDTH) + { + w = MIN(srcw - ax, WIDTH); + + image = next_pool_image(); + + srcptr = srcdata + + (ay + srcy) * srcstride + + (ax + srcx) * 4; + + info.convert_func(srcptr, srcstride, + image->data, + image->bytes_per_line, w, h); + + if (info.useshm) + { + XShmPutImage(info.display, d, gc, image, + 0, 0, dstx + ax, dsty + ay, + w, h, False); + } + else + { + XPutImage(info.display, d, gc, image, + 0, 0, + dstx + ax, + dsty + ay, + w, h); + } + } + } +} + +/* + * Primitive conversion functions + */ + +#ifndef restrict +#ifndef _C99 +#ifdef __GNUC__ +#define restrict __restrict__ +#else +#define restrict +#endif +#endif +#endif + +#define PARAMS \ + const unsigned char * restrict src, \ + int srcstride, \ + unsigned char * restrict dst, \ + int dststride, \ + int w, \ + int h + +/* + * Convert byte:ARGB8888 to various formats + */ + +static void +ximage_convert_argb8888(PARAMS) +{ + int x, y; + unsigned * restrict s = (unsigned * restrict )src; + unsigned * restrict d = (unsigned * restrict )dst; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + d[x] = s[x]; + } + d += dststride>>2; + s += srcstride>>2; + } +} + +static void +ximage_convert_bgra8888(PARAMS) +{ + int x, y; + unsigned *s = (unsigned *)src; + unsigned *d = (unsigned *)dst; + unsigned val; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + val = s[x]; + d[x] = + (val >> 24) | + ((val >> 8) & 0xff00) | + (val << 24) | + ((val << 8) & 0xff0000); +/* + d[x] = + (((val >> 24) & 0xff) << 0) | + (((val >> 16) & 0xff) << 8) | + (((val >> 8) & 0xff) << 16) | + (((val >> 0) & 0xff) << 24); +*/ + } + d += dststride>>2; + s += srcstride>>2; + } +} + +/* following have yet to recieve some MMX love ;-) */ + +static void +ximage_convert_abgr8888(PARAMS) +{ + int x, y; + unsigned *s = (unsigned *)src; + unsigned *d = (unsigned *)dst; + unsigned val; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + val = s[x]; +#if 1 /* FZ_MSB */ + d[x] = (val & 0xff00ff00) | + (((val << 16) | (val >> 16)) & 0x00ff00ff); +#else /* FZ_LSB */ + d[x] = (val << 24) | ((val >> 8) & 0xff); +#endif + } + d += dststride>>2; + s += srcstride>>2; + } +} + +static void +ximage_convert_rgba8888(PARAMS) +{ + int x, y; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + dst[x * 4 + 0] = src[x * 4 + 1]; + dst[x * 4 + 1] = src[x * 4 + 2]; + dst[x * 4 + 2] = src[x * 4 + 3]; + dst[x * 4 + 3] = src[x * 4 + 0]; + } + dst += dststride; + src += srcstride; + } +} + +static void +ximage_convert_bgr888(PARAMS) +{ + int x, y; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + dst[3*x + 0] = src[4*x + 3]; + dst[3*x + 1] = src[4*x + 2]; + dst[3*x + 2] = src[4*x + 1]; + } + src += srcstride; + dst += dststride; + } +} + +static void +ximage_convert_rgb888(PARAMS) +{ + int x, y; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + dst[3*x + 0] = src[4*x + 1]; + dst[3*x + 1] = src[4*x + 2]; + dst[3*x + 2] = src[4*x + 3]; + } + src += srcstride; + dst += dststride; + } +} + +static void +ximage_convert_rgb565(PARAMS) +{ + unsigned char r, g, b; + int x, y; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + r = src[4*x + 1]; + g = src[4*x + 2]; + b = src[4*x + 3]; + ((unsigned short *)dst)[x] = + ((r & 0xF8) << 8) | + ((g & 0xFC) << 3) | + (b >> 3); + } + src += srcstride; + dst += dststride; + } +} + +static void +ximage_convert_rgb565_br(PARAMS) +{ + unsigned char r, g, b; + int x, y; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + r = src[4*x + 1]; + g = src[4*x + 2]; + b = src[4*x + 3]; + /* final word is: + g4 g3 g2 b7 b6 b5 b4 b3 r7 r6 r5 r4 r3 g7 g6 g5 + */ + ((unsigned short *)dst)[x] = + (r & 0xF8) | + ((g & 0xE0) >> 5) | + ((g & 0x1C) << 11) | + ((b & 0xF8) << 5); + } + src += srcstride; + dst += dststride; + } +} + +static void +ximage_convert_rgb555(PARAMS) +{ + unsigned char r, g, b; + int x, y; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + r = src[4*x + 1]; + g = src[4*x + 2]; + b = src[4*x + 3]; + ((unsigned short *)dst)[x] = + ((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3); + } + src += srcstride; + dst += dststride; + } +} + +static void +ximage_convert_rgb555_br(PARAMS) +{ + unsigned char r, g, b; + int x, y; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + r = src[4*x + 1]; + g = src[4*x + 2]; + b = src[4*x + 3]; + /* final word is: + g5 g4 g3 b7 b6 b5 b4 b3 0 r7 r6 r5 r4 r3 g7 g6 + */ + ((unsigned short *)dst)[x] = + ((r & 0xF8) >> 1) | + ((g & 0xC0) >> 6) | + ((g & 0x38) << 10) | + ((b & 0xF8) << 5); + } + src += srcstride; + dst += dststride; + } +} + +static void +ximage_convert_bgr233(PARAMS) +{ + unsigned char r, g, b; + int x,y; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + r = src[4*x + 1]; + g = src[4*x + 2]; + b = src[4*x + 3]; + /* format: b7 b6 g7 g6 g5 r7 r6 r5 */ + dst[x] = (b&0xC0) | ((g>>2)&0x38) | ((r>>5)&0x7); + } + src += srcstride; + dst += dststride; + } +} + +ximage_convert_func_t ximage_convert_funcs[] = { + ximage_convert_argb8888, + ximage_convert_bgra8888, + ximage_convert_rgba8888, + ximage_convert_abgr8888, + ximage_convert_rgb888, + ximage_convert_bgr888, + ximage_convert_rgb565, + ximage_convert_rgb565_br, + ximage_convert_rgb555, + ximage_convert_rgb555_br, + ximage_convert_bgr233, +}; + diff --git a/rosapps/smartpdf/fitz/apps/windows/gsapp.ico b/rosapps/smartpdf/fitz/apps/windows/gsapp.ico new file mode 100644 index 0000000000000000000000000000000000000000..d8b41fe2d6a381c220532267a03fcc587ba1b8c0 GIT binary patch literal 25214 zcmeI4d7M?nmB;JSKsV6)PIuEA-L#q*a2-cSVT^I#jgw>&6%&o z#QBJ$<1+dgHSQUW#wF6?Zcs#2+@MiWKml99?uK68e1COsy}s}Dd#{^CKly|6;ZV1# zPMtdE)TvX;y|0b&%osCeO1=@y7;Vh8q_wqve)R}r`YFrL_wze>#(X@+KyPT5W$w&1 zCU>0ZgM5}T504kUpPwh zXDCby5o7pgA`w5~e;!R+TN|k=qV}JOM)hQYN3v0~%!hWK1${w&pmbJqYwMgAss?J> zqur5!jcFaIXpgqKQqrusj#+f3id$#RibiM6YK@q=KCAXFQHe7>&_%OpvAwrLo<*r` z1<9Q5R@2nL{;!3kBgTLZPgy(1WOzcL!3XGj+@TuxhR+8G&*WiRCs=RTBM zL!iJy(bK^7U=86bpq8<6W#m~vghzjLX(W9!qrDW{j$-A?(}4WGzSz@xXW$KLd1?u4|qoB%#2wxD6&acYhKdw=&X=mg&MTSilhC; z)96K4$kwD0V=_qlv509grdR1yW2~ubf;2B7%?$F1DRj0yspUrsYdRXp+j96?I+wNt zd5Be>8KgC&qMsT{d9?XxTOj`mpI&*7N;@)2p>tt)o6<?Zk`Nq&mJHje;) z8tt%lWv;nYdN9V_Eu>m!YQbsXSG>-&%dvny-w^`e#G7q_9}{p%WK#jMnK@BbpE<2r znlVhSmcY%MH6^;40bOR!EKQwe@|qD{Sqg9wGlx9w=SF9>kY{RXh%$l#m?_Lz`$kRPDkY5GTA`sutio`x?n#)2f zjHziuBrr3KlxI?(sT9luYe49|sIUX<#(rQ6bW;PYA$2&FI$;Y_K%*Xwu8^Dm0{m4} zex483f?uhhYd6!+-7{bZ>gPeW;Sjp7oY9BS5}|svRb3i6TD@ru1J=R z)!imCbO$6g2`v*J-q}^+nMHX5B=J__wv1F_3{_Z zrmoM;XPV|@PN7h{`<`>x7=cGzWHWz_0?Ci zx0`GCv@Iq;(A&tJP0j6VEH3 z6jV1g)Kr(3mzP39Qc+XiU`$gjEkX@o?o&6_i4G_(udcCBU0&>!*ELO|e4v3>=9Aa? z3RX>YqS&;lzQU`TR26FA`2=;AwTA$R&;T^Kc9W_K>&pi^Ag&8!38XfLx&TV61HC2| z)(mvu`KIw@FEvep-TgLPQV1p%7RNdW)Sc)PR5Ucy)gW#F^k;!SoyMM5Yl|8x;yBv| zg--dp82N}1o>y2Q^Hl}rbi7L|>SH=Lgy?DDLveYP+SSQA)=sux`(J&SUJZ(C5-0{} z^%SzF1S(ETjEx7>MQyJ*CTBcXm#Z%fi{tr&>M94NP1VTjtSR<|gGfRJ)}cex&<73| zA_^WG{0S3gF8)O!%1I6NvS|hG9}Hg{Z)FDLZ>R`HVjvkrtp-JbeFi&3GIBa7^zGkN zSK+&LjDJ#k8hGVy#F{X+@_x(Y^wPmAt`3^iiQX%&pJeBAiWVXW%*61F8AFTGM$-`T z`?!XlSL2M@fIPWl)u0eF)RD$f+KlHp=63MCabrhAXAA3-H1NE-fP15zGb6{2D-gY% z*`cZKI`T>b@+RM$qccVARr{p_Q$0rS*u!f8Tw!?b`YmD(jX5$i^1LjhiA{CWI7s0b zJ{twz22F$Mg9vSqzaZZml@Zfb^b-fu7Y2c{$qzyK z{#c0^h>H!ua8>wKrYSZ90+;0^l4O8G@;1bRXN8>=bxFwOpXITb(loKg59y^8;e2kC z;!-58iM7BcEGu}Zq=_RN$Y@;0*Sm!ebtchCqp3(mZ|977YFz{-Her|smYo5XNuJb8 z0EJC8UQYGl}L?*x*hjc_>B(P znhnEABb+Bi*Y;K1TMh4=s`F|1TzcOX)8fvism`T3lj=MgK8w0@=#Dd}9AF3Ru)yD^ z1%j|0EJU#+E}B!CUs7Hf>>Mg9%ZlRSJ?m>_pj@Rud#Ca26Jo6GNvNt+o4vxqva+(G zlA`g|<+%ZY-DBIMXW4|9jjBpYD+2;g8w#!RMP@=-Ay7JAJxnMp^%>aqsxLHDlhTbC zRp$luxe~k-f%1cDFW+wOg7$1E3QNn1>@KkY_9bP(4yJ5CgWQtwPDOYH;1*yc3$}}{ z#-^3d0-o+w2SH5#WQURoV^ z43O)az7oborSYRHN_ZC9(J%ByL0ets#x7vv<@zRL6h@EJNqa&;NIsfd<7tdDMzcX> z?^T^2A_z`d8oQCB*p^xc3fJ3HTa}kHcGO7EE3w87Z}$9CU8R?uH8L}HA`Dr`-{Vj4 zMvWUe#+?A;+UHu90)O`wU=bRVqxe{uJI+Qo zuVB0>D=IE6EiEs}CZ6S(@!4Kk8Cf&Fl!9zCKG!SG=lX=@CWq$Z@=6K{N=k{Zex8pU z9B3u?7YW*y7GxE0AE zKWg--v2@}K%qliEE0Y_=BA?@!Vnit`D2N4n&l{VQQ&8&m6@Itb`D66ZmN~+UWR#Xg zkSF356h^!fo{ipHmPPVxJv6x`{(DRR{blgpvN$?-#E6{`W8l4It|uLIQ2Xpq4(y6e?4uDhb$zyALFYm;?_ul*5Lk>CQGT!-Kf99EI-Z6Xj?1wJC z_~M7bM^fRr=broE4}S22I}SMDfO)&@vdd-gIve~UD4qWSls>q=)n!}9MeX?-)YKFe z6&(o7{MpZbcEgodUim2RvX^j&(EjqvFRyv;z4tmk_~3&LAAb1Z#&ihH#`oWUf5Y2v zzy0}(FTVK6!w*0F!L`?3yX3s{&YOSu;fLQ|U0rDlwr$#4Fo~-MilqeeE zNhh7u&-nD;amO8f>{~W}^wCG1OO`D8?2$(vS&404h30PfTmqf|ego8ekvzi%>6?Gi zMHl_+6Hh!bANzjN+1c6i<*zj~80Kp)6yzeqmUE-_VK@;_pB|D%sSx^lPOcKZV~ z{{$+grvzfnUlG3tfqpPdy z2HahJIGbum!!O}vy!_Eh7L zPG0$f+KPw9SGEYtn(SG9u3WkDOYRc17JM7jUTjF9&2;own@k=jhj~Qy=X4R@yXKU_iZhjr|Ym7Bdk+~0lUCTM+ zdEjEs7dnq=zmRs%Lwy{u2l^?#zh-;LAC5I}toQxv)~(yXSz{r-doKHT zom;k8Zl?tM&;79fYs8>_%F>R3Vx;6zTo-OBu*PV=zv0$fZ@uTl6Hoj{`rFzwqZ40W zw`U{&ZR{hyNEdrF=GzMN)BEQ?|M_j^>?sJ~K17Vkvb7KR&q45hh8WbHN(b3qd(AD~ zvxRkDzkdCu%Pza@CFDE)&`R~H_a!~slol%CfMnN_-Ft5IW4$E;?Aemoj9aTHoKzp|E+$COq zF=NJzXOQMn@H^mk(}6Q|E@Qkz^UT>*HcltMEx!dtq;!!e(MqCHy?32C=*`SbzUb1^|H_D zV6M%F&-viqpw_Le)?vT>_RHaJ=_cm#Cdr;|zpJ{i-6bQxNs02C6^qJ;L3T&B7|JfJ zo4u5;=C1EP>P`i>X+FR7(o2Va^2sM}EnmKTNZFk~hh>!AB|pE%2^ZUE`CwRnJ!?#K zhjrh5_qFqB-xZYUo;U4zm-Bds`Wx7w~ zp7(zE9|LM0Yz>Uy-1gs_Hf`!o=Qq+V43bxVlM3WF>G)|3)~s36%`dc{M`+zmD;8}r zu>UV2?)-(jxTJRxFtoN0$9sOOW&OqJ!0)%>)JWztj!!sc&%YVk#gv@{Zq=F$j}rDl zy1(rW^GDF$9i_K;A#T?#r+ikbWfAqd4?R`T!#jwL~HgDdnm>lCD?n}?w zH-zK86`ue2elj)|DhtQ^L>}S1`qF-sJM`Nr*PX5Qqgw^+e~uvbzrotypKc7)XEGg} zE=sk37;5cPAM7Rih(F7TKc^wId}piIFS^ZTZJ&n^Z5(RuX&l0HAuPLlmX7i_WJ-#} z{eJFk*8TC1f4m-=8gLZ2O@RMQW(=N22m3xC-8j&Z^{1ik=Mv+;c=FyQ%DJzL_e%FR zH8p(;UOInm7eM}_8HWWr&&ZdCI~VEP?l*%wC^rl?4eKC&^wG;ZmnAtlIY-lOtLJPg zh1o;vOnEE)yu(<0iLcoAVMC3Fba3eQn@$mT_o=zfKBbfQV0S>Pd!8ZRvp}=OK)-qD zaU5&I)y(au(dPr!=MMHsU3cGocMtaky_a5kX}|W9k~NIsx$9!C<_khZ)rKEWumACn ze|#l*eLk>V&S0q&M2{?DbOZi+0&Da|Jm1RPe1QCXV(uI0_C9)k1g@5ToZot7bIo5D ziBC8^&?B2`?n;LXFTAja z@%xl`|Jd1QpM4;GY}0vVTVx!nEjpYJzD|7HzDc%{Ea?@e+Taa4*&|Cg4g|E%Kl>S`*Hf{0q`rVB3`g<53rj2vP*J=O^^LHiNCL(uxDI9Cbo4DJf<1-kE;zRmN&;342q;E_T82+~8rY2ZHK z-k{p+oUZR>u)6);#I0W=$UEOs%IL)Up2)NMJP_2H{X^F7Q+ZE(F0tWaAqe z;Ot#@-L)CI8Q>Y<$>4FI?wfS)`c1GA)Ok;FM184$w-#xBN_Xk3`{il;-1)n#2N$t7 zyoYas7IM~mf7Pm0pK^X&FXRq={d3Pf_nDrV>+6WepD^#2>w6x)g}QzB-FN?WW@hF& z@RBUD(f*)fa1~eps!xGrknJT~5o-s(Eq$u4@&G8Nnj)VW>b5Vm_cG51*3yT{S1lW&FO!h`yg9O_5= z6UA$X%DX**YbROwc4q^7-v!w7T*^-X_X9N+#h{ZxK39v(w{zFlnYeG#x~#R$fz}A^ z`_#AgN3P$nT&fpJ-fOP8W)u7FrwR%R{*8VP1E+u*YxS?aY%cfnQ#ez;qji&f40W~* zgZc>9i+`%Iksgv!a_~1*I@v?rM%(X!S`#!cnB4OB0l zTH_NzWs)~h9_1wi-ygj|d-QR=xs8AN)1R(T{~E_+dO$OX_i)O1ch>vZV~^bpt#qFRy7`yEv-;0J{`li} zXP>!1zCwPxployFjW_nf_ch|d_u;!U=+*;`z4{jB&Y3gkVD`H0+e2^h(EgWiE7$U^ z*S!ZHeDJaK5w^SLzH}F;|GXP+xM6?xLCbg^Qupxq>)Fi-`HFmoz53^Tclk8)`cl5B z)q1HlNO~*QDc(zWf&5Q$WSw!w8IxH{{>ppixH(9jjdS4`==?KT%3idGb>s2e+}xS8 z)jR5c0BbR)LX?E265ygTtt+c}IwhxFCFfhZ0&wqZFWm*%HZ0dchFf(tHqjCPlRKLWM( zHh?9d`jNfE{X2WeK8=jmL9F%5#4D8yF81jjU7*-2ACPRCKghR^?_}?R-|D4~JA=AH8 z_H9sepd6IF6G7ur#C~Nz&gz5KVe0HysNZCuzU8B$3*+mrzuw6lyo$2JK<(`mXXWc* zkUdmZ%z5o!@Sjh4j^m@eKsM+1V)osM?vw@UJ8{i*?YV31`Q7h+cMEy#0TqALe>Rv1 z^2vPeT8`xIWi`)9``7ye-Ct|W-F>|LE*ZVbc-PUxx8FDNtQgb;mVwFim;J{QGbdyJ zg~{ff^E-{V?7-icv-+p&pFQygenX&ns6B`CKgHfekp9{Sl(7e$!@G&3cl*iq0V5066*%+ufsJ&n|XZUY%7JiboqbJ$gt}^MYSf3b&96jIk z^|Oax$-YuCP;;*l)Y!}SUCiY%4&1yfJpcUjcP9qjMJ!#fJ2W@1p&m5W@;%8SP%4@S zAAImj)&TAO<#)S*+HXjA^^poxC)q@o%Y3TBA5TQb8}W&yoF~@ZdFP#-#FQTNvoTlW zAzzVv8Uw{k+D17atvdD8Q-990(_L}L#l2KAgv%8Vb!Jq%34ABE2j`;iAhdb_dps4&40;rU1YXuA`ry}ooxXM3tGxUrEel2^W} zm|Ym4_D$kf2R0se+;ImoPHpV3HpwT5HD7XWd-?aj|NUvyyLgw&v-EMidE6q<+z?8B z`KacJ^wD0Tl=Ic0jLm;CXKvw}_6u3NwcbtwC8uJI`cA5Q8|4vW4470l)g^;SKtGMN z4J4nTGM+Pp%7@ZSTKcvl=(~jzjsfe44YX4p~zigP>2_-mQb;Aq=;L-qNUy`51BS zgJ)ak_A2UIaaA$Qf!c|OFzC~=pkBI*r**+|X?8oo8tsNzEz;k-IoqLAw z&7vW1Q8MtGZ@Z>T4%t(6!T3yb?Odw9RWFnbT94hg6pDS${_-KWE>p^Bogv&A07k6Y*BPqaRKReXW?Bb=Fz)iRp6_+q4n=BA&^Kc)K@5ymc={ fyaW2lM=fS@U7EQ_7oj1HP&PffA`=(PTNM3&({@>n literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/fitz/apps/windows/gsdoc.ico b/rosapps/smartpdf/fitz/apps/windows/gsdoc.ico new file mode 100644 index 0000000000000000000000000000000000000000..ecf22c4ba3ec7d54e0bf3fbf9a39c5928e253b73 GIT binary patch literal 2238 zcmb`}y^hmB5Ww+?K=O4F4J}bBN~A3*px_mFg(+z%NqHshbaxUuA)X>Nn(|80r$Q+s z5o!3(Zem{?gAh79Kik>akJWVhRiMTp&-L~@=jh-Dv<}}FgOA^fdYlW5y(juC=8AO12DSQ)3`bUIr##G!4b#>DNq<3fn1~l zg~1WXg)2}P9D!WS0)@d5pd<3hOst;Hm7PL9ltW=~1VnGihjJJkfqXdy3WFn%FRVae za0K!t7AOpk01e0|S0yv?ddAf~`A`mp!4b#}P@ph40=X#)6b45iH%fuR;0SObAIf2H z1bA!p4UrwWu%Xys1qy>BKtuAN90o^#&SbOMFg~%mA+KvsxphkJE7q>C?{>dJzTDjK zJ6^E{wBthp?Z%ZyWZ^#@-SpA7?da?B=pH@Z?ejQ|Htv7lk0-UtD9+bC^PmIjWww{` z;~c1v9gN}>)bZ;mQ}Lm`>?itU2Hq}15T4Ud4H<4cs5C_JY?w{A) z1?Rq{cQHTmi9>g2TZJyh`PD#|(`Xa8h`0U3`u<`3I;l=B3()H;1Uw^7{(+5U76?T37bXZuR}{_8Mx`seAL`p@{VIzw-5-{tS{ yJlx*@aoXJEJbZfLeFYhHKK^+=9PzKu2mT&BCI-uY7GqB+%arGg^#X733Go|9t|e6f literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/fitz/apps/windows/winmain.c b/rosapps/smartpdf/fitz/apps/windows/winmain.c new file mode 100644 index 00000000000..326a9ed9cab --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/windows/winmain.c @@ -0,0 +1,821 @@ +#include +#include +#include "pdfapp.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#define ID_ABOUT 0x1000 +#define ID_DOCINFO 0x1001 + +static HWND hwndframe = NULL; +static HWND hwndview = NULL; +static HDC hdc; +static HBRUSH bgbrush; +static HBRUSH shbrush; +static BITMAPINFO *dibinf; +static HCURSOR arrowcurs, handcurs, waitcurs; +static LRESULT CALLBACK frameproc(HWND, UINT, WPARAM, LPARAM); +static LRESULT CALLBACK viewproc(HWND, UINT, WPARAM, LPARAM); + +static int bmpstride = 0; +static char *bmpdata = NULL; +static int justcopied = 0; + +static pdfapp_t gapp; + +/* + * Associate Apparition with PDF files. + */ + +void associate(char *argv0) +{ + char tmp[256]; + char *name = "Adobe PDF Document"; + HKEY key, kicon, kshell, kopen, kcmd; + DWORD disp; + + /* HKEY_CLASSES_ROOT\.pdf */ + + if (RegCreateKeyEx(HKEY_CLASSES_ROOT, + ".pdf", 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &key, &disp)) + return; + + if (RegSetValueEx(key, "", 0, REG_SZ, "Apparition", strlen("Apparition")+1)) + return; + + RegCloseKey(key); + + /* HKEY_CLASSES_ROOT\Apparition */ + + if (RegCreateKeyEx(HKEY_CLASSES_ROOT, + "Apparition", 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &key, &disp)) + return; + + if (RegSetValueEx(key, "", 0, REG_SZ, name, strlen(name)+1)) + return; + + /* HKEY_CLASSES_ROOT\Apparition\DefaultIcon */ + + if (RegCreateKeyEx(key, + "DefaultIcon", 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kicon, &disp)) + return; + + sprintf(tmp, "%s,1", argv0); + if (RegSetValueEx(kicon, "", 0, REG_SZ, tmp, strlen(tmp)+1)) + return; + + RegCloseKey(kicon); + + /* HKEY_CLASSES_ROOT\Apparition\Shell\Open\Command */ + + if (RegCreateKeyEx(key, + "shell", 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kshell, &disp)) + return; + if (RegCreateKeyEx(kshell, + "open", 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kopen, &disp)) + return; + if (RegCreateKeyEx(kopen, + "command", 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kcmd, &disp)) + return; + + sprintf(tmp, "\"%s\" \"%%1\"", argv0); + if (RegSetValueEx(kcmd, "", 0, REG_SZ, tmp, strlen(tmp)+1)) + return; + + RegCloseKey(kcmd); + RegCloseKey(kopen); + RegCloseKey(kshell); + + RegCloseKey(key); +} + +/* + * Dialog boxes + */ + +void winwarn(pdfapp_t *app, char *msg) +{ + MessageBoxA(hwndframe, msg, "Apparition: Warning", MB_ICONWARNING); +} + +void winerror(pdfapp_t *app, char *msg) +{ + MessageBoxA(hwndframe, msg, "Apparition: Error", MB_ICONERROR); + exit(1); +} + +int winfilename(char *buf, int len) +{ + OPENFILENAME ofn; + strcpy(buf, ""); + memset(&ofn, 0, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndframe; + ofn.lpstrFile = buf; + ofn.nMaxFile = len; + ofn.lpstrInitialDir = NULL; + ofn.lpstrTitle = "Apparition: Open PDF file"; + ofn.lpstrFilter = "PDF Files (*.pdf)\0*.pdf\0All Files\0*\0\0"; + ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; + return GetOpenFileName(&ofn); +} + +static char pd_filename[256] = "The file is encrypted."; +static char pd_password[256] = ""; +static int pd_okay = 0; + +INT CALLBACK +dlogpassproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case WM_INITDIALOG: + SetDlgItemText(hwnd, 4, pd_filename); + return TRUE; + case WM_COMMAND: + switch(wParam) + { + case 1: + pd_okay = 1; + GetDlgItemText(hwnd, 3, pd_password, sizeof pd_password); + EndDialog(hwnd, 0); + return TRUE; + case 2: + pd_okay = 0; + EndDialog(hwnd, 0); + return TRUE; + } + break; + } + return FALSE; +} + +char *winpassword(pdfapp_t *app, char *filename) +{ + char buf[124], *s; + strcpy(buf, filename); + s = buf; + if (strrchr(s, '\\')) s = strrchr(s, '\\') + 1; + if (strrchr(s, '/')) s = strrchr(s, '/') + 1; + if (strlen(s) > 32) + strcpy(s + 30, "..."); + sprintf(pd_filename, "The file \"%s\" is encrypted.", s); + DialogBox(NULL, "IDD_DLOGPASS", hwndframe, dlogpassproc); + if (pd_okay) + return pd_password; + return NULL; +} + +INT CALLBACK +dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + char buf[256]; + pdf_xref *xref = gapp.xref; + fz_obj *obj; + + switch(message) + { + case WM_INITDIALOG: + + SetDlgItemTextA(hwnd, 0x10, gapp.filename); + + sprintf(buf, "PDF %g", xref->version); + SetDlgItemTextA(hwnd, 0x11, buf); + + if (xref->crypt) + { + sprintf(buf, "Standard %d bit RC4", xref->crypt->n * 8); + SetDlgItemTextA(hwnd, 0x12, buf); + strcpy(buf, ""); + if (xref->crypt->p & (1 << 2)) + strcat(buf, "print, "); + if (xref->crypt->p & (1 << 3)) + strcat(buf, "modify, "); + if (xref->crypt->p & (1 << 4)) + strcat(buf, "copy, "); + if (xref->crypt->p & (1 << 5)) + strcat(buf, "annotate, "); + if (strlen(buf) > 2) + buf[strlen(buf)-2] = 0; + else + strcpy(buf, "none"); + SetDlgItemTextA(hwnd, 0x13, buf); + } + else + { + SetDlgItemTextA(hwnd, 0x12, "None"); + SetDlgItemTextA(hwnd, 0x13, "n/a"); + } + + if (!xref->info) + return TRUE; + +#define SETUCS(ID) \ + { \ + fz_error *error; \ + unsigned short *ucs; \ + error = pdf_toucs2(&ucs, obj); \ + if (!error) \ + { \ + SetDlgItemTextW(hwnd, ID, ucs); \ + fz_free(ucs); \ + } \ + } + + if ((obj = fz_dictgets(xref->info, "Title"))) SETUCS(0x20) + if ((obj = fz_dictgets(xref->info, "Author"))) SETUCS(0x21) + if ((obj = fz_dictgets(xref->info, "Subject"))) SETUCS(0x22) + if ((obj = fz_dictgets(xref->info, "Keywords"))) SETUCS(0x23) + if ((obj = fz_dictgets(xref->info, "Creator"))) SETUCS(0x24) + if ((obj = fz_dictgets(xref->info, "Producer"))) SETUCS(0x25) + if ((obj = fz_dictgets(xref->info, "CreationDate"))) SETUCS(0x26) + if ((obj = fz_dictgets(xref->info, "ModDate"))) SETUCS(0x27) + + return TRUE; + + case WM_COMMAND: + EndDialog(hwnd, 0); + return TRUE; + } + return FALSE; +} + +void info() +{ + DialogBox(NULL, "IDD_DLOGINFO", hwndframe, dloginfoproc); +} + +INT CALLBACK +dlogaboutproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case WM_INITDIALOG: + SetDlgItemTextA(hwnd, 0x10, gapp.filename); + SetDlgItemTextA(hwnd, 2, "Apparition is Copyright (C) 2006 artofcode, LLC"); + SetDlgItemTextA(hwnd, 3, pdfapp_usage(&gapp)); + return TRUE; + case WM_COMMAND: + EndDialog(hwnd, 0); + return TRUE; + } + return FALSE; +} + +void help() +{ + DialogBox(NULL, "IDD_DLOGABOUT", hwndframe, dlogaboutproc); +} + +/* + * Main window + */ + +void winopen() +{ + WNDCLASS wc = {0}; + HMENU menu; + RECT r; + ATOM atom; + + /* Create and register window frame class */ + wc.style = 0; + wc.lpfnWndProc = frameproc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = LoadIcon(wc.hInstance, "IDI_ICONAPP"); + wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "FrameWindow"; + atom = RegisterClass(&wc); + assert(atom && "Register window class"); + + /* Create and register window view class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = viewproc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "ViewWindow"; + atom = RegisterClass(&wc); + assert(atom && "Register window class"); + + /* Get screen size */ + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + gapp.scrw = r.right - r.left; + gapp.scrh = r.bottom - r.top; + + /* Create cursors */ + arrowcurs = LoadCursor(NULL, IDC_ARROW); + handcurs = LoadCursor(NULL, IDC_HAND); + waitcurs = LoadCursor(NULL, IDC_WAIT); + + /* And a background color */ + bgbrush = CreateSolidBrush(RGB(0x70,0x70,0x70)); + shbrush = CreateSolidBrush(RGB(0x40,0x40,0x40)); + + /* Init DIB info for buffer */ + dibinf = malloc(sizeof(BITMAPINFO) + 12); + assert(dibinf != NULL); + dibinf->bmiHeader.biSize = sizeof(dibinf->bmiHeader); + dibinf->bmiHeader.biPlanes = 1; + dibinf->bmiHeader.biBitCount = 24; + dibinf->bmiHeader.biCompression = BI_RGB; + dibinf->bmiHeader.biXPelsPerMeter = 2834; + dibinf->bmiHeader.biYPelsPerMeter = 2834; + dibinf->bmiHeader.biClrUsed = 0; + dibinf->bmiHeader.biClrImportant = 0; + dibinf->bmiHeader.biClrUsed = 0; + + /* Create window */ + hwndframe = CreateWindow("FrameWindow", // window class name + NULL, // window caption + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, // initial position + 300, // initial x size + 300, // initial y size + 0, // parent window handle + 0, // window menu handle + 0, // program instance handle + 0); // creation parameters + + hwndview = CreateWindow("ViewWindow", // window class name + NULL, + WS_VISIBLE | WS_CHILD, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hwndframe, 0, 0, 0); + + hdc = NULL; + + SetWindowTextA(hwndframe, "Apparition"); + + menu = GetSystemMenu(hwndframe, 0); + AppendMenu(menu, MF_SEPARATOR, 0, NULL); + AppendMenu(menu, MF_STRING, ID_ABOUT, "About Apparition..."); + AppendMenu(menu, MF_STRING, ID_DOCINFO, "Document Properties..."); + + SetCursor(arrowcurs); +} + +void wincursor(pdfapp_t *app, int curs) +{ + if (curs == ARROW) + SetCursor(arrowcurs); + if (curs == HAND) + SetCursor(handcurs); + if (curs == WAIT) + SetCursor(waitcurs); +} + +void wintitle(pdfapp_t *app, char *title) +{ + unsigned short wide[256], *dp; + char *sp; + int rune; + + dp = wide; + sp = title; + while (*sp && dp < wide + 255) + { + sp += chartorune(&rune, sp); + *dp++ = rune; + } + *dp = 0; + + SetWindowTextW(hwndframe, wide); +} + +void winconvert(pdfapp_t *app, fz_pixmap *image) +{ + int y, x; + + if (bmpdata) + fz_free(bmpdata); + + bmpstride = ((image->w * 3 + 3) / 4) * 4; + bmpdata = fz_malloc(image->h * bmpstride); + if (!bmpdata) + return; + + for (y = 0; y < image->h; y++) + { + char *p = bmpdata + y * bmpstride; + char *s = image->samples + y * image->w * 4; + for (x = 0; x < image->w; x++) + { + p[x * 3 + 0] = s[x * 4 + 3]; + p[x * 3 + 1] = s[x * 4 + 2]; + p[x * 3 + 2] = s[x * 4 + 1]; + } + } +} + +void invertcopyrect(void) +{ + unsigned char *p; + + int x0 = gapp.selr.x0 - gapp.panx; + int x1 = gapp.selr.x1 - gapp.panx; + int y0 = gapp.selr.y0 - gapp.pany; + int y1 = gapp.selr.y1 - gapp.pany; + int x, y; + + x0 = CLAMP(x0, 0, gapp.image->w - 1); + x1 = CLAMP(x1, 0, gapp.image->w - 1); + y0 = CLAMP(y0, 0, gapp.image->h - 1); + y1 = CLAMP(y1, 0, gapp.image->h - 1); + + for (y = y0; y < y1; y++) + { + p = bmpdata + y * bmpstride + x0 * 3; + for (x = x0; x < x1; x++) + { + p[0] = 255 - p[0]; + p[1] = 255 - p[1]; + p[2] = 255 - p[2]; + p += 3; + } + } + + justcopied = 1; +} + +void winblit() +{ + int x0 = gapp.panx; + int y0 = gapp.pany; + int x1 = gapp.panx + gapp.image->w; + int y1 = gapp.pany + gapp.image->h; + RECT r; + + if (bmpdata) + { + if (gapp.iscopying || justcopied) + invertcopyrect(); + + dibinf->bmiHeader.biWidth = gapp.image->w; + dibinf->bmiHeader.biHeight = -gapp.image->h; + dibinf->bmiHeader.biSizeImage = gapp.image->h * bmpstride; + SetDIBitsToDevice(hdc, + gapp.panx, /* destx */ + gapp.pany, /* desty */ + gapp.image->w, /* destw */ + gapp.image->h, /* desth */ + 0, /* srcx */ + 0, /* srcy */ + 0, /* startscan */ + gapp.image->h, /* numscans */ + bmpdata, /* pBits */ + dibinf, /* pInfo */ + DIB_RGB_COLORS /* color use flag */ + ); + + if (gapp.iscopying || justcopied) + invertcopyrect(); + } + + /* Grey background */ + r.top = 0; r.bottom = gapp.winh; + r.left = 0; r.right = x0; + FillRect(hdc, &r, bgbrush); + r.left = x1; r.right = gapp.winw; + FillRect(hdc, &r, bgbrush); + r.left = 0; r.right = gapp.winw; + r.top = 0; r.bottom = y0; + FillRect(hdc, &r, bgbrush); + r.top = y1; r.bottom = gapp.winh; + FillRect(hdc, &r, bgbrush); + + /* Drop shadow */ + r.left = x0 + 2; + r.right = x1 + 2; + r.top = y1; + r.bottom = y1 + 2; + FillRect(hdc, &r, shbrush); + r.left = x1; + r.right = x1 + 2; + r.top = y0 + 2; + r.bottom = y1; + FillRect(hdc, &r, shbrush); +} + +void winresize(pdfapp_t *app, int w, int h) +{ + ShowWindow(hwndframe, SW_SHOWDEFAULT); + w += GetSystemMetrics(SM_CXFRAME) * 2; + h += GetSystemMetrics(SM_CYFRAME) * 2; + h += GetSystemMetrics(SM_CYCAPTION); + SetWindowPos(hwndframe, 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE); +} + +void winrepaint(pdfapp_t *app) +{ + InvalidateRect(hwndview, NULL, 0); +} + +/* + * Event handling + */ + +void windocopy(pdfapp_t *app) +{ + HGLOBAL handle; + unsigned short *ucsbuf; + + if (!OpenClipboard(hwndframe)) + return; + EmptyClipboard(); + + handle = GlobalAlloc(GMEM_MOVEABLE, 4096 * sizeof(unsigned short)); + if (!handle) + { + CloseClipboard(); + return; + } + + ucsbuf = GlobalLock(handle); + pdfapp_oncopy(&gapp, ucsbuf, 4096); + GlobalUnlock(handle); + + SetClipboardData(CF_UNICODETEXT, handle); + CloseClipboard(); + + justcopied = 1; /* keep inversion around for a while... */ +} + +void winopenuri(pdfapp_t *app, char *buf) +{ + ShellExecute(hwndframe, "open", buf, 0, 0, SW_SHOWNORMAL); +} + +void handlekey(int c) +{ + if (GetCapture() == hwndview) + return; + + if (justcopied) + { + justcopied = 0; + winrepaint(&gapp); + } + + /* translate VK into ascii equivalents */ + switch (c) + { + case VK_F1: c = '?'; break; + case VK_ESCAPE: c = 'q'; break; + case VK_DOWN: c = 'd'; break; + case VK_UP: c = 'u'; break; + case VK_LEFT: c = 'p'; break; + case VK_RIGHT: c = 'n'; break; + case VK_PRIOR: c = 'b'; break; + case VK_NEXT: c = ' '; break; + } + + if (c == 'q') + exit(0); + else if (c == '?' || c == 'h') + help(); + else + pdfapp_onkey(&gapp, c); +} + +void handlemouse(int x, int y, int btn, int state) +{ + if (state != 0 && justcopied) + { + justcopied = 0; + winrepaint(&gapp); + } + + if (state == 1) + SetCapture(hwndview); + if (state == -1) + ReleaseCapture(); + + pdfapp_onmouse(&gapp, x, y, btn, 0, state); +} + +LRESULT CALLBACK +frameproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case WM_SETFOCUS: + PostMessage(hwnd, WM_APP+5, 0, 0); + return 0; + case WM_APP+5: + SetFocus(hwndview); + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + case WM_SYSCOMMAND: + if (wParam == ID_ABOUT) + { + help(); + return 0; + } + if (wParam == ID_DOCINFO) + { + info(); + return 0; + } + break; + + case WM_SIZE: + { + // More generally, you should use GetEffectiveClientRect + // if you have a toolbar etc. + RECT rect; + GetClientRect(hwnd, &rect); + MoveWindow(hwndview, rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top, TRUE); + } + return 0; + + case WM_SIZING: + gapp.shrinkwrap = 0; + break; + + case WM_NOTIFY: + case WM_COMMAND: + return SendMessage(hwndview, message, wParam, lParam); + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +LRESULT CALLBACK +viewproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static int oldx = 0; + static int oldy = 0; + int x = (signed short) LOWORD(lParam); + int y = (signed short) HIWORD(lParam); + + switch (message) + { + case WM_SIZE: + if (wParam == SIZE_MINIMIZED) + return 0; + if (wParam == SIZE_MAXIMIZED) + gapp.shrinkwrap = 0; + pdfapp_onresize(&gapp, LOWORD(lParam), HIWORD(lParam)); + break; + + /* Paint events are low priority and automagically catenated + * so we don't need to do any fancy waiting to defer repainting. + */ + case WM_PAINT: + { + //puts("WM_PAINT"); + PAINTSTRUCT ps; + hdc = BeginPaint(hwnd, &ps); + winblit(); + hdc = NULL; + EndPaint(hwnd, &ps); + return 0; + } + + case WM_ERASEBKGND: + return 1; // well, we don't need to erase to redraw cleanly + + /* Mouse events */ + + case WM_LBUTTONDOWN: + SetFocus(hwndview); + oldx = x; oldy = y; + handlemouse(x, y, 1, 1); + return 0; + case WM_MBUTTONDOWN: + SetFocus(hwndview); + oldx = x; oldy = y; + handlemouse(x, y, 2, 1); + return 0; + case WM_RBUTTONDOWN: + SetFocus(hwndview); + oldx = x; oldy = y; + handlemouse(x, y, 3, 1); + return 0; + + case WM_LBUTTONUP: + oldx = x; oldy = y; + handlemouse(x, y, 1, -1); + return 0; + case WM_MBUTTONUP: + oldx = x; oldy = y; + handlemouse(x, y, 2, -1); + return 0; + case WM_RBUTTONUP: + oldx = x; oldy = y; + handlemouse(x, y, 3, -1); + return 0; + + case WM_MOUSEMOVE: + oldx = x; oldy = y; + handlemouse(x, y, 0, 0); + return 0; + + /* Mouse wheel */ + case WM_MOUSEWHEEL: + if ((signed short)HIWORD(wParam) > 0) + handlekey(LOWORD(wParam) & MK_SHIFT ? '+' : 'u'); + else + handlekey(LOWORD(wParam) & MK_SHIFT ? '-' : 'd'); + return 0; + + /* Keyboard events */ + + case WM_KEYDOWN: + /* only handle special keys */ + switch (wParam) + { + case VK_F1: + case VK_LEFT: + case VK_UP: + case VK_PRIOR: + case VK_RIGHT: + case VK_DOWN: + case VK_NEXT: + case VK_ESCAPE: + handlekey(wParam); + handlemouse(oldx, oldy, 0, 0); /* update cursor */ + return 0; + } + return 1; + + /* unicode encoded chars, including escape, backspace etc... */ + case WM_CHAR: + handlekey(wParam); + handlemouse(oldx, oldy, 0, 0); /* update cursor */ + return 0; + } + + fflush(stdout); + + /* Pass on unhandled events to Windows */ + return DefWindowProc(hwnd, message, wParam, lParam); +} + +int main(int argc, char **argv) +{ + char buf[1024]; + char *filename; + MSG msg; + + fz_cpudetect(); + fz_accelerate(); + + pdfapp_init(&gapp); + + associate(argv[0]); + winopen(); + + if (argc == 2) + filename = strdup(argv[1]); + else + { + if (!winfilename(buf, sizeof buf)) + exit(0); + filename = buf; + } + + pdfapp_open(&gapp, filename); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + pdfapp_close(&gapp); + + return 0; +} + +int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + char * argv[1] = {"mupdf.exe"}; + int argc = 1; + main(argc, argv); +} + diff --git a/rosapps/smartpdf/fitz/apps/windows/winres.rc b/rosapps/smartpdf/fitz/apps/windows/winres.rc new file mode 100644 index 00000000000..af941f032b3 --- /dev/null +++ b/rosapps/smartpdf/fitz/apps/windows/winres.rc @@ -0,0 +1,62 @@ +IDI_ICONAPP ICON "gsapp.ico" +IDI_ICONDOC ICON "gsdoc.ico" + +IDD_DLOGPASS DIALOG 50, 50, 204, 60 +//STYLE DS_MODALFRAME | WS_POPUP +STYLE 128 | 0x80000000 +CAPTION " Apparition: Password " +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT 3, 57,20,140,12, 32 + DEFPUSHBUTTON "Okay", 1, 90,40,50,14, 0x50010001 + PUSHBUTTON "Cancel", 2, 147,40,50,14, 0x50010000 + LTEXT "The file is encrypted." 4, 10,7,180,10, 0x00000 + LTEXT "Password:" 5, 17,22,40,10, 0x00000 +END + +IDD_DLOGINFO DIALOG 50, 50, 300, 145 +STYLE 128 | 0x80000000 +CAPTION " Document Properties " +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "Okay", 1, 300-10-50,145-7-14,50,14, 0x50010001 + + LTEXT "File:" -1, 10,10,50,10, 0 + LTEXT "Format:" -1, 10,20,50,10, 0 + LTEXT "Encryption:" -1, 10,30,50,10, 0 + LTEXT "Permissions:" -1, 10,40,50,10, 0 + + LTEXT "" 2, 10,10,180,10, 0 + LTEXT "" 3, 10,25,180,160, 0 +END + diff --git a/rosapps/smartpdf/fitz/base/base_cleanname.c b/rosapps/smartpdf/fitz/base/base_cleanname.c new file mode 100644 index 00000000000..5476463005b --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_cleanname.c @@ -0,0 +1,52 @@ +/* + * In place, rewrite name to compress multiple /, eliminate ., and process .. + */ + +#define SEP(x) ((x)=='/' || (x) == 0) + +char * +cleanname(char *name) +{ + char *p, *q, *dotdot; + int rooted; + + rooted = name[0] == '/'; + + /* + * invariants: + * p points at beginning of path element we're considering. + * q points just past the last path element we wrote (no slash). + * dotdot points just past the point where .. cannot backtrack + * any further (no slash). + */ + p = q = dotdot = name+rooted; + while(*p) { + if(p[0] == '/') /* null element */ + p++; + else if(p[0] == '.' && SEP(p[1])) + p += 1; /* don't count the separator in case it is nul */ + else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) { + p += 2; + if(q > dotdot) { /* can backtrack */ + while(--q > dotdot && *q != '/') + ; + } else if(!rooted) { /* /.. is / but ./../ is .. */ + if(q != name) + *q++ = '/'; + *q++ = '.'; + *q++ = '.'; + dotdot = q; + } + } else { /* real path element */ + if(q != name+rooted) + *q++ = '/'; + while((*q = *p) != '/' && *q != 0) + p++, q++; + } + } + if(q == name) /* empty string is really ``.'' */ + *q++ = '.'; + *q = '\0'; + return name; +} + diff --git a/rosapps/smartpdf/fitz/base/base_cpudep.c b/rosapps/smartpdf/fitz/base/base_cpudep.c new file mode 100644 index 00000000000..d51d011cf9e --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_cpudep.c @@ -0,0 +1,221 @@ +/* +run-time cpu feature detection code +mm, alphabet soup... + +Glenn Kennard +*/ + +#include "fitz-base.h" + +/* global run-time constant */ +unsigned fz_cpuflags = 0; + +#ifndef HAVE_CPUDEP + +void fz_accelerate(void) +{ +} + +void fz_cpudetect(void) +{ +} + +#else + +#include /* signal/sigaction */ +#include /* sigsetjmp/siglongjmp */ + +#ifdef WIN32 +#define sigjmp_buf jmp_buf +#define sigsetjmp(a,b) setjmp(a) +#define siglongjmp longjmp +#endif + +typedef struct { + void (*test)(void); + const unsigned flag; + const char *name; +} featuretest; + + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + +/* need emms?? */ +static void mmx(void) +{ __asm__ ("pand %mm0, %mm0\n\t"); } + +static void m3dnow(void) +{ __asm__ ("pavgusb %mm0, %mm0\n\t"); } + +static void mmxext(void) /* aka Extended 3DNow! */ +{ __asm__ ("pmaxsw %mm0, %mm0\n\t"); } + +static void sse(void) +{ __asm__ ("andps %xmm0, %xmm0\n\t"); } + +static void sse2(void) +{ __asm__ ("andpd %xmm0, %xmm0\n\t"); } + +/* static void sse3(void) */ +/* { __asm__ ("haddps %%xmm0, %%xmm0\n\t" : : : "%xmm0"); } */ + +#ifdef ARCH_X86_64 +static void amd64(void) +{ __asm__ ("and %rax, %rax\n\t"); } +#endif + + +static const featuretest features[] = { + { mmx, HAVE_MMX, "mmx" }, + { m3dnow, HAVE_3DNOW, "3dnow" }, + { mmxext, HAVE_MMXEXT, "mmxext" }, + { sse, HAVE_SSE, "sse" }, + { sse2, HAVE_SSE2, "sse2" }, +/* { sse3, HAVE_SSE3, "sse3" }, */ +#ifdef ARCH_X86_64 + { amd64, HAVE_AMD64, "amd64" } +#endif +}; + +#endif + + +#if defined(ARCH_SPARC) +/* assembler must have -xarch=v8plusa passed to it (v9a for 64 bit binaries) */ +static void vis(void) +{ __asm__ ("fand %f8, %f8, %f8\n\t"); } + +static const featuretest features[] = { + { vis, HAVE_VIS, "vis" } +}; + +#endif + + +#if defined(ARCH_PPC) + +static void altivec(void) +{ __asm__ ("vand v0, v0, v0\n\t"); } + + +static const featuretest features[] = { + { altivec, HAVE_ALTIVEC, "altivec" }, +}; + +#endif + +static sigjmp_buf jmpbuf; +static volatile sig_atomic_t canjump; + +static void +sigillhandler(int sig) +{ + if (!canjump) { + signal(sig, SIG_DFL); + raise(sig); + } + + canjump = 0; + siglongjmp(jmpbuf, 1); +} + +static int +enabled(char *env, const char *ext) +{ + int len; + char *s; + if (!env) + return 1; + len = strlen(ext); + while ((s = strstr(env, ext))) + { + s += len; + if (*s == ' ' || *s == ',' || *s == '\0') + return 1; + } + return 0; +} + +static void +dumpflags(void) +{ + unsigned f = fz_cpuflags; + int i, n; + + fputs("detected cpu features:", stdout); + n = 0; + for (i = 0; i < sizeof(features) / sizeof(featuretest); i++) + { + if (f & features[i].flag) + { + fputc(' ', stdout); + fputs(features[i].name, stdout); + n ++; + } + } + if (!n) + fputs(" none", stdout); + fputc('\n', stdout); +} + +void fz_cpudetect(void) +{ + static int hasrun = 0; + + unsigned flags = 0; + int i; + void (*oldhandler)(int) = NULL; + void (*tmphandler)(int); + char *env; + + if (hasrun) + return; + hasrun = 1; + + env = getenv("CPUACCEL"); + + for (i = 0; i < sizeof(features) / sizeof(featuretest); i++) + { + canjump = 0; + + tmphandler = signal(SIGILL, sigillhandler); + if (!oldhandler) + oldhandler = tmphandler; + + if (sigsetjmp(jmpbuf, 1)) + { + /* test failed - disable feature */ + flags &= ~features[i].flag; + continue; + } + + canjump = 1; + + features[i].test(); + + /* if we got here the test succeeded */ + if (enabled(env, features[i].name)) + flags |= features[i].flag; + else + flags &= ~features[i].flag; + } + + /* restore previous signal handler */ + signal(SIGILL, oldhandler); + + fz_cpuflags = flags; + +#if defined(ARCH_X86) || defined(ARCH_X86_64) + __asm__ __volatile__ ("emms\n\t"); +#endif + + dumpflags(); +} + +static __attribute__((constructor, used)) void fzcpudetect(void) +{ + fz_cpudetect(); +} + +#endif + diff --git a/rosapps/smartpdf/fitz/base/base_error.c b/rosapps/smartpdf/fitz/base/base_error.c new file mode 100644 index 00000000000..e0bf156792a --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_error.c @@ -0,0 +1,74 @@ +#include "fitz-base.h" + +void +fz_warn(char *fmt, ...) +{ + va_list ap; + fprintf(stderr, "warning: "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +fz_error * +fz_throw1(char *fmt, ...) +{ + va_list ap; + fz_error *eo; + + eo = fz_malloc(sizeof(fz_error)); + if (!eo) return fz_outofmem; + + eo->refs = 1; + strlcpy(eo->func, "unknown", sizeof eo->func); + strlcpy(eo->file, "unknown", sizeof eo->file); + eo->line = 0; + + va_start(ap, fmt); + vsnprintf(eo->msg, sizeof eo->msg, fmt, ap); + eo->msg[sizeof(eo->msg) - 1] = '\0'; + va_end(ap); + + return eo; +} + +fz_error * +fz_throw0(const char *func, const char *file, int line, char *fmt, ...) +{ + va_list ap; + fz_error *eo; + + eo = fz_malloc(sizeof(fz_error)); + if (!eo) return fz_outofmem; + + eo->refs = 1; + strlcpy(eo->func, func, sizeof eo->func); + strlcpy(eo->file, file, sizeof eo->file); + eo->line = line; + + va_start(ap, fmt); + vsnprintf(eo->msg, sizeof eo->msg, fmt, ap); + eo->msg[sizeof(eo->msg) - 1] = '\0'; + va_end(ap); + + if (getenv("BOMB")) + { + fflush(stdout); + fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg); + fflush(stderr); + abort(); + } + + return eo; +} + +void +fz_droperror(fz_error *eo) +{ + if (eo->refs > 0) + eo->refs--; + if (eo->refs == 0) + fz_free(eo); +} + diff --git a/rosapps/smartpdf/fitz/base/base_hash.c b/rosapps/smartpdf/fitz/base/base_hash.c new file mode 100644 index 00000000000..37351b48c04 --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_hash.c @@ -0,0 +1,274 @@ +/* Linear probe hash table. + * 2004 (C) Tor Andersson. + * BSD license. + * + * Simple hashtable with open adressing linear probe. + * Unlike text book examples, removing entries works + * correctly in this implementation so it wont start + * exhibiting bad behaviour if entries are inserted + * and removed frequently. + */ + +#include "fitz-base.h" + +enum { MAXKEYLEN = 16 }; + +typedef struct fz_hashentry_s fz_hashentry; + +struct fz_hashentry_s +{ + unsigned char key[MAXKEYLEN]; + void *val; +}; + +struct fz_hashtable_s +{ + int keylen; + int size; + int load; + fz_hashentry *ents; +}; + +static unsigned hash(unsigned char *s, int len) +{ + unsigned hash = 0; + int i; + for (i = 0; i < len; i++) + { + hash += s[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; +} + +fz_error * +fz_newhash(fz_hashtable **tablep, int initialsize, int keylen) +{ + fz_hashtable *table; + + assert(keylen <= MAXKEYLEN); + + table = *tablep = fz_malloc(sizeof(fz_hashtable)); + if (!table) + return fz_outofmem; + + table->keylen = keylen; + table->size = initialsize; + table->load = 0; + + table->ents = fz_malloc(sizeof(fz_hashentry) * table->size); + if (!table->ents) + { + fz_free(table); + *tablep = nil; + return fz_outofmem; + } + + memset(table->ents, 0, sizeof(fz_hashentry) * table->size); + + return nil; +} + +void +fz_emptyhash(fz_hashtable *table) +{ + table->load = 0; + memset(table->ents, 0, sizeof(fz_hashentry) * table->size); +} + +int +fz_hashlen(fz_hashtable *table) +{ + return table->size; +} + +void * +fz_hashgetkey(fz_hashtable *table, int idx) +{ + return table->ents[idx].key; +} + +void * +fz_hashgetval(fz_hashtable *table, int idx) +{ + return table->ents[idx].val; +} + +void +fz_drophash(fz_hashtable *table) +{ + fz_free(table->ents); + fz_free(table); +} + +fz_error * +fz_resizehash(fz_hashtable *table, int newsize) +{ + fz_error *error; + fz_hashentry *newents; + fz_hashentry *oldents; + int oldload; + int oldsize; + int i; + + oldsize = table->size; + oldload = table->load; + oldents = table->ents; + + if (newsize < oldload * 8 / 10) + return fz_throw("rangecheck: resize hash too small"); + + newents = fz_malloc(sizeof(fz_hashentry) * newsize); + if (!newents) + return fz_outofmem; + + table->size = newsize; + table->load = 0; + table->ents = newents; + memset(table->ents, 0, sizeof(fz_hashentry) * table->size); + + for (i = 0; i < oldsize; i++) + { + if (oldents[i].val) + { + error = fz_hashinsert(table, oldents[i].key, oldents[i].val); + if (error) + { + table->size = oldsize; + table->load = oldload; + table->ents = oldents; + fz_free(newents); + return error; + } + } + } + + fz_free(oldents); + return nil; +} + +void * +fz_hashfind(fz_hashtable *table, void *key) +{ + fz_hashentry *ents = table->ents; + unsigned size = table->size; + unsigned pos = hash(key, table->keylen) % size; + + while (1) + { + if (!ents[pos].val) + return nil; + + if (memcmp(key, &ents[pos].key, table->keylen) == 0) + return ents[pos].val; + + pos = (pos + 1) % size; + } +} + +fz_error * +fz_hashinsert(fz_hashtable *table, void *key, void *val) +{ + fz_error *error; + fz_hashentry *ents; + unsigned size; + unsigned pos; + + if (table->load > table->size * 8 / 10) + { + error = fz_resizehash(table, table->size * 2); + if (error) + return error; + } + + ents = table->ents; + size = table->size; + pos = hash(key, table->keylen) % size; + + while (1) + { + if (!ents[pos].val) + { + memcpy(ents[pos].key, key, table->keylen); + ents[pos].val = val; + table->load ++; + return nil; + } + + if (memcmp(key, &ents[pos].key, table->keylen) == 0) + return fz_throw("rangecheck: overwrite hash slot"); + + pos = (pos + 1) % size; + } + + return nil; +} + +fz_error * +fz_hashremove(fz_hashtable *table, void *key) +{ + fz_hashentry *ents = table->ents; + unsigned size = table->size; + unsigned pos = hash(key, table->keylen) % size; + unsigned hole, look, code; + + while (1) + { + if (!ents[pos].val) + return fz_throw("rangecheck: remove inexistant hash entry"); + + if (memcmp(key, &ents[pos].key, table->keylen) == 0) + { + ents[pos].val = nil; + + hole = pos; + look = (hole + 1) % size; + + while (ents[look].val) + { + code = hash(ents[look].key, table->keylen) % size; + if ((code <= hole && hole < look) || + (look < code && code <= hole) || + (hole < look && look < code)) + { + ents[hole] = ents[look]; + ents[look].val = nil; + hole = look; + } + + look = (look + 1) % size; + } + + table->load --; + return nil; + } + + pos = (pos + 1) % size; + } +} + +void +fz_debughash(fz_hashtable *table) +{ + int i, k; + + printf("cache load %d / %d\n", table->load, table->size); + + for (i = 0; i < table->size; i++) + { + if (!table->ents[i].val) + printf("table % 4d: empty\n", i); + else + { + printf("table % 4d: key=", i); + for (k = 0; k < MAXKEYLEN; k++) + printf("%02x", ((char*)table->ents[i].key)[k]); + printf(" val=$%p\n", table->ents[i].val); + } + } +} + diff --git a/rosapps/smartpdf/fitz/base/base_matrix.c b/rosapps/smartpdf/fitz/base/base_matrix.c new file mode 100644 index 00000000000..054bb283def --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_matrix.c @@ -0,0 +1,151 @@ +#include "fitz-base.h" + +void fz_invert3x3(float *dst, float *m) +{ + float det; + int i; + +#define M3(m,i,j) (m)[3*i+j] +#define D2(a,b,c,d) (a * d - b * c) +#define D3(a1,a2,a3,b1,b2,b3,c1,c2,c3) \ + (a1 * D2(b2,b3,c2,c3)) - \ + (b1 * D2(a2,a3,c2,c3)) + \ + (c1 * D2(a2,a3,b2,b3)) + + det = D3(M3(m,0,0), M3(m,1,0), M3(m,2,0), + M3(m,0,1), M3(m,1,1), M3(m,2,1), + M3(m,0,2), M3(m,1,2), M3(m,2,2)); + if (det == 0) + det = 1.0; + det = 1.0 / det; + + M3(dst,0,0) = M3(m,1,1) * M3(m,2,2) - M3(m,1,2) * M3(m,2,1); + M3(dst,0,1) = -M3(m,0,1) * M3(m,2,2) + M3(m,0,2) * M3(m,2,1); + M3(dst,0,2) = M3(m,0,1) * M3(m,1,2) - M3(m,0,2) * M3(m,1,1); + + M3(dst,1,0) = -M3(m,1,0) * M3(m,2,2) + M3(m,1,2) * M3(m,2,0); + M3(dst,1,1) = M3(m,0,0) * M3(m,2,2) - M3(m,0,2) * M3(m,2,0); + M3(dst,1,2) = -M3(m,0,0) * M3(m,1,2) + M3(m,0,2) * M3(m,1,0); + + M3(dst,2,0) = M3(m,1,0) * M3(m,2,1) - M3(m,1,1) * M3(m,2,0); + M3(dst,2,1) = -M3(m,0,0) * M3(m,2,1) + M3(m,0,1) * M3(m,2,0); + M3(dst,2,2) = M3(m,0,0) * M3(m,1,1) - M3(m,0,1) * M3(m,1,0); + + for (i = 0; i < 9; i++) + dst[i] *= det; +} + +fz_matrix +fz_concat(fz_matrix one, fz_matrix two) +{ + fz_matrix dst; + dst.a = one.a * two.a + one.b * two.c; + dst.b = one.a * two.b + one.b * two.d; + dst.c = one.c * two.a + one.d * two.c; + dst.d = one.c * two.b + one.d * two.d; + dst.e = one.e * two.a + one.f * two.c + two.e; + dst.f = one.e * two.b + one.f * two.d + two.f; + return dst; +} + +fz_matrix +fz_identity(void) +{ + fz_matrix m; + m.a = 1; m.b = 0; + m.c = 0; m.d = 1; + m.e = 0; m.f = 0; + return m; +} + +fz_matrix +fz_scale(float sx, float sy) +{ + fz_matrix m; + m.a = sx; m.b = 0; + m.c = 0; m.d = sy; + m.e = 0; m.f = 0; + return m; +} + +fz_matrix +fz_rotate(float theta) +{ + fz_matrix m; + float s = sin(theta * M_PI / 180.0); + float c = cos(theta * M_PI / 180.0); + m.a = c; m.b = s; + m.c = -s; m.d = c; + m.e = 0; m.f = 0; + return m; +} + +fz_matrix +fz_translate(float tx, float ty) +{ + fz_matrix m; + m.a = 1; m.b = 0; + m.c = 0; m.d = 1; + m.e = tx; m.f = ty; + return m; +} + +fz_matrix +fz_invertmatrix(fz_matrix src) +{ + fz_matrix dst; + float rdet = 1.0 / (src.a * src.d - src.b * src.c); + dst.a = src.d * rdet; + dst.b = -src.b * rdet; + dst.c = -src.c * rdet; + dst.d = src.a * rdet; + dst.e = -src.e * dst.a - src.f * dst.c; + dst.f = -src.e * dst.b - src.f * dst.d; + return dst; +} + +int +fz_isrectilinear(fz_matrix m) +{ + return (fabs(m.b) < FLT_EPSILON && fabs(m.c) < FLT_EPSILON) || + (fabs(m.a) < FLT_EPSILON && fabs(m.d) < FLT_EPSILON); +} + +float +fz_matrixexpansion(fz_matrix m) +{ + return sqrt(fabs(m.a * m.d - m.b * m.c)); +} + +fz_point +fz_transformpoint(fz_matrix m, fz_point p) +{ + fz_point t; + t.x = p.x * m.a + p.y * m.c + m.e; + t.y = p.x * m.b + p.y * m.d + m.f; + return t; +} + +fz_rect +fz_transformaabb(fz_matrix m, fz_rect r) +{ + fz_point s, t, u, v; + + if (fz_isinfiniterect(r)) + return r; + + s.x = r.x0; s.y = r.y0; + t.x = r.x0; t.y = r.y1; + u.x = r.x1; u.y = r.y1; + v.x = r.x1; v.y = r.y0; + s = fz_transformpoint(m, s); + t = fz_transformpoint(m, t); + u = fz_transformpoint(m, u); + v = fz_transformpoint(m, v); + r.x0 = MIN4(s.x, t.x, u.x, v.x); + r.y0 = MIN4(s.y, t.y, u.y, v.y); + r.x1 = MAX4(s.x, t.x, u.x, v.x); + r.y1 = MAX4(s.y, t.y, u.y, v.y); + return r; +} + diff --git a/rosapps/smartpdf/fitz/base/base_memory.c b/rosapps/smartpdf/fitz/base/base_memory.c new file mode 100644 index 00000000000..64d5e383bd9 --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_memory.c @@ -0,0 +1,91 @@ +#include "fitz-base.h" + +/* Make this thread local storage if you wish. */ + +static void *stdmalloc(fz_memorycontext *mem, int n) +{ +#if 0 + void *p = malloc(n); + if (!p) + fprintf(stderr, "failed to malloc %d bytes\n", n); + return p; +#else + return malloc(n); +#endif +} + +static void *stdrealloc(fz_memorycontext *mem, void *p, int n) +{ +#if 0 + void *np = realloc(p, n); + if (np == nil) + fprintf(stderr, "realloc failed %d nytes", n); + else if (np == p) + fprintf(stderr, "realloc kept %d\n", n); + else + fprintf(stderr, "realloc moved %d\n", n); + return np; +#else + return realloc(p, n); +#endif +} + +static void stdfree(fz_memorycontext *mem, void *p) +{ + free(p); +} + +static fz_memorycontext defmem = { stdmalloc, stdrealloc, stdfree }; +static fz_memorycontext *curmem = &defmem; + +fz_error fz_koutofmem = { + -1, + {"out of memory"}, + {""}, + {"memory.c"}, + 0 +}; + +fz_memorycontext * +fz_currentmemorycontext() +{ + return curmem; +} + +void +fz_setmemorycontext(fz_memorycontext *mem) +{ + curmem = mem; +} + +void * +fz_malloc(int n) +{ + fz_memorycontext *mem = fz_currentmemorycontext(); + return mem->malloc(mem, n); +} + +void * +fz_realloc(void *p, int n) +{ + fz_memorycontext *mem = fz_currentmemorycontext(); + return mem->realloc(mem, p, n); +} + +void +fz_free(void *p) +{ + fz_memorycontext *mem = fz_currentmemorycontext(); + mem->free(mem, p); +} + +char * +fz_strdup(char *s) +{ + int len = strlen(s); + char *ns = fz_malloc(len + 1); + if (ns) + strcpy(ns, s); + return ns; +} + diff --git a/rosapps/smartpdf/fitz/base/base_rect.c b/rosapps/smartpdf/fitz/base/base_rect.c new file mode 100644 index 00000000000..3c00cb94bcd --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_rect.c @@ -0,0 +1,75 @@ +#include "fitz-base.h" + +fz_rect fz_infiniterect = { 1, 1, -1, -1 }; +fz_rect fz_emptyrect = { 0, 0, 0, 0 }; + +static fz_irect infinite = { 1, 1, -1, -1 }; +static fz_irect empty = { 0, 0, 0, 0 }; + +fz_irect +fz_roundrect(fz_rect f) +{ + fz_irect i; + i.x0 = fz_floor(f.x0); + i.y0 = fz_floor(f.y0); + i.x1 = fz_ceil(f.x1); + i.y1 = fz_ceil(f.y1); + return i; +} + +fz_rect +fz_intersectrects(fz_rect a, fz_rect b) +{ + fz_rect r; + if (fz_isinfiniterect(a)) return b; + if (fz_isinfiniterect(b)) return a; + r.x0 = MAX(a.x0, b.x0); + r.y0 = MAX(a.y0, b.y0); + r.x1 = MIN(a.x1, b.x1); + r.y1 = MIN(a.y1, b.y1); + return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_emptyrect : r; +} + +fz_rect +fz_mergerects(fz_rect a, fz_rect b) +{ + fz_rect r; + if (fz_isinfiniterect(a) || fz_isinfiniterect(b)) + return fz_infiniterect; + if (fz_isemptyrect(a)) return b; + if (fz_isemptyrect(b)) return a; + r.x0 = MIN(a.x0, b.x0); + r.y0 = MIN(a.y0, b.y0); + r.x1 = MAX(a.x1, b.x1); + r.y1 = MAX(a.y1, b.y1); + return r; +} + +fz_irect +fz_intersectirects(fz_irect a, fz_irect b) +{ + fz_irect r; + if (fz_isinfiniterect(a)) return b; + if (fz_isinfiniterect(b)) return a; + r.x0 = MAX(a.x0, b.x0); + r.y0 = MAX(a.y0, b.y0); + r.x1 = MIN(a.x1, b.x1); + r.y1 = MIN(a.y1, b.y1); + return (r.x1 < r.x0 || r.y1 < r.y0) ? empty : r; +} + +fz_irect +fz_mergeirects(fz_irect a, fz_irect b) +{ + fz_irect r; + if (fz_isinfiniterect(a) || fz_isinfiniterect(b)) + return infinite; + if (fz_isemptyrect(a)) return b; + if (fz_isemptyrect(b)) return a; + r.x0 = MIN(a.x0, b.x0); + r.y0 = MIN(a.y0, b.y0); + r.x1 = MAX(a.x1, b.x1); + r.y1 = MAX(a.y1, b.y1); + return r; +} + diff --git a/rosapps/smartpdf/fitz/base/base_rune.c b/rosapps/smartpdf/fitz/base/base_rune.c new file mode 100644 index 00000000000..4aa81df39f7 --- /dev/null +++ b/rosapps/smartpdf/fitz/base/base_rune.c @@ -0,0 +1,168 @@ +enum +{ + UTFmax = 3, /* maximum bytes per rune */ + Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ + Runeself = 0x80, /* rune and UTF sequences are the same (<) */ + Runeerror = 0x80 /* decoding error in UTF */ +}; + +enum +{ + Bit1 = 7, + Bitx = 6, + Bit2 = 5, + Bit3 = 4, + Bit4 = 3, + + T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */ + Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */ + T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */ + T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */ + T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ + + Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */ + Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */ + Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */ + + Maskx = (1< T1 + */ + c = *(unsigned char*)str; + if(c < Tx) { + *rune = c; + return 1; + } + + /* + * two character sequence + * 0080-07FF => T2 Tx + */ + c1 = *(unsigned char*)(str+1) ^ Tx; + if(c1 & Testx) + goto bad; + if(c < T3) { + if(c < T2) + goto bad; + l = ((c << Bitx) | c1) & Rune2; + if(l <= Rune1) + goto bad; + *rune = l; + return 2; + } + + /* + * three character sequence + * 0800-FFFF => T3 Tx Tx + */ + c2 = *(unsigned char*)(str+2) ^ Tx; + if(c2 & Testx) + goto bad; + if(c < T4) { + l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3; + if(l <= Rune2) + goto bad; + *rune = l; + return 3; + } + + /* + * bad decoding + */ +bad: + *rune = Bad; + return 1; +} + +int +runetochar(char *str, int *rune) +{ + int c; + + /* + * one character sequence + * 00000-0007F => 00-7F + */ + c = *rune; + if(c <= Rune1) { + str[0] = c; + return 1; + } + + /* + * two character sequence + * 0080-07FF => T2 Tx + */ + if(c <= Rune2) { + str[0] = T2 | (c >> 1*Bitx); + str[1] = Tx | (c & Maskx); + return 2; + } + + /* + * three character sequence + * 0800-FFFF => T3 Tx Tx + */ + str[0] = T3 | (c >> 2*Bitx); + str[1] = Tx | ((c >> 1*Bitx) & Maskx); + str[2] = Tx | (c & Maskx); + return 3; +} + +int +runelen(int c) +{ + int rune; + char str[10]; + + rune = c; + return runetochar(str, &rune); +} + +int +runenlen(int *r, int nrune) +{ + int nb, c; + + nb = 0; + while(nrune--) { + c = *r++; + if(c <= Rune1) + nb++; + else + if(c <= Rune2) + nb += 2; + else + nb += 3; + } + return nb; +} + +int +fullrune(char *str, int n) +{ + int c; + + if(n > 0) { + c = *(unsigned char*)str; + if(c < Tx) + return 1; + if(n > 1) + if(c < T3 || n > 2) + return 1; + } + return 0; +} + diff --git a/rosapps/smartpdf/fitz/base/util_getopt.c b/rosapps/smartpdf/fitz/base/util_getopt.c new file mode 100644 index 00000000000..c870e206ab6 --- /dev/null +++ b/rosapps/smartpdf/fitz/base/util_getopt.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1987 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +/* + * get option letter from argument vector + */ +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt; /* character checked for validity */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define EMSG "" + +int getopt(int nargc, char * const * nargv, const char *ostr) +{ + static char *place = EMSG; /* option letter processing */ + register char *oli; /* option letter list index */ + char *p; + + if (!*place) { /* update scanning pointer */ + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return(EOF); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return(EOF); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means EOF. + */ + if (optopt == (int)'-') + return(EOF); + if (!*place) + ++optind; + if (opterr) { + if (!(p = strrchr(*nargv, '/'))) + p = *nargv; + else + ++p; + (void)fprintf(stderr, "%s: illegal option -- %c\n", + p, optopt); + } + return(BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (!(p = strrchr(*nargv, '/'))) + p = *nargv; + else + ++p; + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + p, optopt); + return(BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return(optopt); /* dump back option letter */ +} diff --git a/rosapps/smartpdf/fitz/base/util_strlcat.c b/rosapps/smartpdf/fitz/base/util_strlcat.c new file mode 100644 index 00000000000..c659b73a591 --- /dev/null +++ b/rosapps/smartpdf/fitz/base/util_strlcat.c @@ -0,0 +1,35 @@ +/* Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ + +#include + +int strlcat(char *dst, const char *src, int siz) +{ + register char *d = dst; + register const char *s = src; + register int n = siz; + int dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (*d != '\0' && n-- != 0) + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return dlen + strlen(s); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return dlen + (s - src); /* count does not include NUL */ +} + diff --git a/rosapps/smartpdf/fitz/base/util_strlcpy.c b/rosapps/smartpdf/fitz/base/util_strlcpy.c new file mode 100644 index 00000000000..73416ae154d --- /dev/null +++ b/rosapps/smartpdf/fitz/base/util_strlcpy.c @@ -0,0 +1,32 @@ +/* Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ + +#include + +int strlcpy(char *dst, const char *src, int siz) +{ + register char *d = dst; + register const char *s = src; + register int n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + diff --git a/rosapps/smartpdf/fitz/base/util_strsep.c b/rosapps/smartpdf/fitz/base/util_strsep.c new file mode 100644 index 00000000000..e54903ce39e --- /dev/null +++ b/rosapps/smartpdf/fitz/base/util_strsep.c @@ -0,0 +1,11 @@ +#include + +char *strsep(char **stringp, const char *delim) +{ + char *ret = *stringp; + if (ret == NULL) return NULL; + if ((*stringp = strpbrk(*stringp, delim)) != NULL) + *((*stringp)++) = '\0'; + return ret; +} + diff --git a/rosapps/smartpdf/fitz/build-debug.bat b/rosapps/smartpdf/fitz/build-debug.bat new file mode 100644 index 00000000000..f5d2999d79f --- /dev/null +++ b/rosapps/smartpdf/fitz/build-debug.bat @@ -0,0 +1 @@ +nmake -f Makefile.vc DEBUG=1 diff --git a/rosapps/smartpdf/fitz/build.bat b/rosapps/smartpdf/fitz/build.bat new file mode 100644 index 00000000000..8f330af4638 --- /dev/null +++ b/rosapps/smartpdf/fitz/build.bat @@ -0,0 +1 @@ +nmake -f Makefile.vc diff --git a/rosapps/smartpdf/fitz/clean.bat b/rosapps/smartpdf/fitz/clean.bat new file mode 100644 index 00000000000..09a2fa18ea6 --- /dev/null +++ b/rosapps/smartpdf/fitz/clean.bat @@ -0,0 +1 @@ +nmake -f Makefile.vc clean \ No newline at end of file diff --git a/rosapps/smartpdf/fitz/fonts/Dingbats.cff.c b/rosapps/smartpdf/fitz/fonts/Dingbats.cff.c new file mode 100644 index 00000000000..a34da369096 --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/Dingbats.cff.c @@ -0,0 +1,2461 @@ +const unsigned char fonts_Dingbats_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x09, 0x44, 0x69, 0x6e, + 0x67, 0x62, 0x61, 0x74, 0x73, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x37, + 0xf8, 0xe4, 0x00, 0xf8, 0xe5, 0x01, 0xf8, 0xe6, 0x02, 0xf8, 0xe7, 0x03, + 0xf8, 0x18, 0x04, 0x43, 0x0c, 0x03, 0xaf, 0x0c, 0x04, 0x1d, 0x00, 0x4c, + 0x9a, 0x04, 0x0d, 0x8a, 0xfb, 0x23, 0xfa, 0x69, 0xf9, 0xc7, 0x05, 0x1c, + 0x04, 0xfd, 0x0f, 0x1c, 0x06, 0x92, 0x10, 0x1c, 0x07, 0x5e, 0x11, 0x1c, + 0x00, 0x1d, 0x1c, 0x73, 0x15, 0x12, 0x00, 0xcd, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x05, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0d, 0x00, 0x0f, 0x00, + 0x13, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x1e, 0x00, 0x21, 0x00, 0x24, 0x00, + 0x27, 0x00, 0x2a, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x34, 0x00, 0x37, 0x00, + 0x3a, 0x00, 0x3d, 0x00, 0x40, 0x00, 0x43, 0x00, 0x46, 0x00, 0x49, 0x00, + 0x4c, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x55, 0x00, 0x57, 0x00, 0x59, 0x00, + 0x5b, 0x00, 0x5d, 0x00, 0x60, 0x00, 0x63, 0x00, 0x66, 0x00, 0x69, 0x00, + 0x6c, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x75, 0x00, 0x78, 0x00, 0x7b, 0x00, + 0x7e, 0x00, 0x81, 0x00, 0x84, 0x00, 0x87, 0x00, 0x8a, 0x00, 0x8d, 0x00, + 0x90, 0x00, 0x93, 0x00, 0x96, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9f, 0x00, + 0xa2, 0x00, 0xa5, 0x00, 0xa8, 0x00, 0xab, 0x00, 0xae, 0x00, 0xb1, 0x00, + 0xb4, 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xc0, 0x00, 0xc3, 0x00, + 0xc6, 0x00, 0xc9, 0x00, 0xcc, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd5, 0x00, + 0xd8, 0x00, 0xdb, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xe4, 0x00, 0xe7, 0x00, + 0xea, 0x00, 0xee, 0x00, 0xf1, 0x00, 0xf5, 0x00, 0xf8, 0x00, 0xfb, 0x00, + 0xfe, 0x01, 0x01, 0x01, 0x04, 0x01, 0x07, 0x01, 0x0a, 0x01, 0x0d, 0x01, + 0x10, 0x01, 0x13, 0x01, 0x16, 0x01, 0x1a, 0x01, 0x1d, 0x01, 0x20, 0x01, + 0x23, 0x01, 0x26, 0x01, 0x29, 0x01, 0x2c, 0x01, 0x30, 0x01, 0x33, 0x01, + 0x37, 0x01, 0x3a, 0x01, 0x3d, 0x01, 0x40, 0x01, 0x43, 0x01, 0x46, 0x01, + 0x4a, 0x01, 0x4e, 0x01, 0x52, 0x01, 0x56, 0x01, 0x5a, 0x01, 0x5e, 0x01, + 0x62, 0x01, 0x66, 0x01, 0x6a, 0x01, 0x6e, 0x01, 0x72, 0x01, 0x76, 0x01, + 0x7a, 0x01, 0x7e, 0x01, 0x82, 0x01, 0x86, 0x01, 0x8a, 0x01, 0x8e, 0x01, + 0x92, 0x01, 0x96, 0x01, 0x9a, 0x01, 0x9e, 0x01, 0xa2, 0x01, 0xa6, 0x01, + 0xaa, 0x01, 0xae, 0x01, 0xb2, 0x01, 0xb6, 0x01, 0xba, 0x01, 0xbe, 0x01, + 0xc2, 0x01, 0xc6, 0x01, 0xca, 0x01, 0xce, 0x01, 0xd2, 0x01, 0xd6, 0x01, + 0xda, 0x01, 0xde, 0x01, 0xe2, 0x01, 0xe6, 0x01, 0xea, 0x01, 0xee, 0x01, + 0xf2, 0x01, 0xf6, 0x01, 0xfa, 0x01, 0xfe, 0x02, 0x02, 0x02, 0x06, 0x02, + 0x0a, 0x02, 0x0e, 0x02, 0x12, 0x02, 0x16, 0x02, 0x1a, 0x02, 0x1e, 0x02, + 0x22, 0x02, 0x26, 0x02, 0x2a, 0x02, 0x2e, 0x02, 0x32, 0x02, 0x36, 0x02, + 0x3a, 0x02, 0x3e, 0x02, 0x42, 0x02, 0x46, 0x02, 0x4a, 0x02, 0x4e, 0x02, + 0x52, 0x02, 0x56, 0x02, 0x5a, 0x02, 0x5e, 0x02, 0x62, 0x02, 0x66, 0x02, + 0x6a, 0x02, 0x6e, 0x02, 0x72, 0x02, 0x76, 0x02, 0x7a, 0x02, 0x7e, 0x02, + 0x82, 0x02, 0x86, 0x02, 0x8a, 0x02, 0x8e, 0x02, 0x92, 0x02, 0x96, 0x02, + 0x9a, 0x02, 0x9e, 0x02, 0xa2, 0x02, 0xa6, 0x02, 0xaa, 0x02, 0xae, 0x02, + 0xb2, 0x02, 0xb6, 0x02, 0xba, 0x02, 0xbe, 0x02, 0xfe, 0x03, 0x07, 0x03, + 0x0f, 0x61, 0x31, 0x61, 0x32, 0x61, 0x32, 0x30, 0x32, 0x61, 0x33, 0x61, + 0x34, 0x61, 0x35, 0x61, 0x31, 0x31, 0x39, 0x61, 0x31, 0x31, 0x38, 0x61, + 0x31, 0x31, 0x37, 0x61, 0x31, 0x31, 0x61, 0x31, 0x32, 0x61, 0x31, 0x33, + 0x61, 0x31, 0x34, 0x61, 0x31, 0x35, 0x61, 0x31, 0x36, 0x61, 0x31, 0x30, + 0x35, 0x61, 0x31, 0x37, 0x61, 0x31, 0x38, 0x61, 0x31, 0x39, 0x61, 0x32, + 0x30, 0x61, 0x32, 0x31, 0x61, 0x32, 0x32, 0x61, 0x32, 0x33, 0x61, 0x32, + 0x34, 0x61, 0x32, 0x35, 0x61, 0x32, 0x36, 0x61, 0x32, 0x37, 0x61, 0x32, + 0x38, 0x61, 0x36, 0x61, 0x37, 0x61, 0x38, 0x61, 0x39, 0x61, 0x31, 0x30, + 0x61, 0x32, 0x39, 0x61, 0x33, 0x30, 0x61, 0x33, 0x31, 0x61, 0x33, 0x32, + 0x61, 0x33, 0x33, 0x61, 0x33, 0x34, 0x61, 0x33, 0x35, 0x61, 0x33, 0x36, + 0x61, 0x33, 0x37, 0x61, 0x33, 0x38, 0x61, 0x33, 0x39, 0x61, 0x34, 0x30, + 0x61, 0x34, 0x31, 0x61, 0x34, 0x32, 0x61, 0x34, 0x33, 0x61, 0x34, 0x34, + 0x61, 0x34, 0x35, 0x61, 0x34, 0x36, 0x61, 0x34, 0x37, 0x61, 0x34, 0x38, + 0x61, 0x34, 0x39, 0x61, 0x35, 0x30, 0x61, 0x35, 0x31, 0x61, 0x35, 0x32, + 0x61, 0x35, 0x33, 0x61, 0x35, 0x34, 0x61, 0x35, 0x35, 0x61, 0x35, 0x36, + 0x61, 0x35, 0x37, 0x61, 0x35, 0x38, 0x61, 0x35, 0x39, 0x61, 0x36, 0x30, + 0x61, 0x36, 0x31, 0x61, 0x36, 0x32, 0x61, 0x36, 0x33, 0x61, 0x36, 0x34, + 0x61, 0x36, 0x35, 0x61, 0x36, 0x36, 0x61, 0x36, 0x37, 0x61, 0x36, 0x38, + 0x61, 0x36, 0x39, 0x61, 0x37, 0x30, 0x61, 0x37, 0x31, 0x61, 0x37, 0x32, + 0x61, 0x37, 0x33, 0x61, 0x37, 0x34, 0x61, 0x32, 0x30, 0x33, 0x61, 0x37, + 0x35, 0x61, 0x32, 0x30, 0x34, 0x61, 0x37, 0x36, 0x61, 0x37, 0x37, 0x61, + 0x37, 0x38, 0x61, 0x37, 0x39, 0x61, 0x38, 0x31, 0x61, 0x38, 0x32, 0x61, + 0x38, 0x33, 0x61, 0x38, 0x34, 0x61, 0x39, 0x37, 0x61, 0x39, 0x38, 0x61, + 0x39, 0x39, 0x61, 0x31, 0x30, 0x30, 0x61, 0x38, 0x39, 0x61, 0x39, 0x30, + 0x61, 0x39, 0x33, 0x61, 0x39, 0x34, 0x61, 0x39, 0x31, 0x61, 0x39, 0x32, + 0x61, 0x32, 0x30, 0x35, 0x61, 0x38, 0x35, 0x61, 0x32, 0x30, 0x36, 0x61, + 0x38, 0x36, 0x61, 0x38, 0x37, 0x61, 0x38, 0x38, 0x61, 0x39, 0x35, 0x61, + 0x39, 0x36, 0x61, 0x31, 0x30, 0x31, 0x61, 0x31, 0x30, 0x32, 0x61, 0x31, + 0x30, 0x33, 0x61, 0x31, 0x30, 0x34, 0x61, 0x31, 0x30, 0x36, 0x61, 0x31, + 0x30, 0x37, 0x61, 0x31, 0x30, 0x38, 0x61, 0x31, 0x31, 0x32, 0x61, 0x31, + 0x31, 0x31, 0x61, 0x31, 0x31, 0x30, 0x61, 0x31, 0x30, 0x39, 0x61, 0x31, + 0x32, 0x30, 0x61, 0x31, 0x32, 0x31, 0x61, 0x31, 0x32, 0x32, 0x61, 0x31, + 0x32, 0x33, 0x61, 0x31, 0x32, 0x34, 0x61, 0x31, 0x32, 0x35, 0x61, 0x31, + 0x32, 0x36, 0x61, 0x31, 0x32, 0x37, 0x61, 0x31, 0x32, 0x38, 0x61, 0x31, + 0x32, 0x39, 0x61, 0x31, 0x33, 0x30, 0x61, 0x31, 0x33, 0x31, 0x61, 0x31, + 0x33, 0x32, 0x61, 0x31, 0x33, 0x33, 0x61, 0x31, 0x33, 0x34, 0x61, 0x31, + 0x33, 0x35, 0x61, 0x31, 0x33, 0x36, 0x61, 0x31, 0x33, 0x37, 0x61, 0x31, + 0x33, 0x38, 0x61, 0x31, 0x33, 0x39, 0x61, 0x31, 0x34, 0x30, 0x61, 0x31, + 0x34, 0x31, 0x61, 0x31, 0x34, 0x32, 0x61, 0x31, 0x34, 0x33, 0x61, 0x31, + 0x34, 0x34, 0x61, 0x31, 0x34, 0x35, 0x61, 0x31, 0x34, 0x36, 0x61, 0x31, + 0x34, 0x37, 0x61, 0x31, 0x34, 0x38, 0x61, 0x31, 0x34, 0x39, 0x61, 0x31, + 0x35, 0x30, 0x61, 0x31, 0x35, 0x31, 0x61, 0x31, 0x35, 0x32, 0x61, 0x31, + 0x35, 0x33, 0x61, 0x31, 0x35, 0x34, 0x61, 0x31, 0x35, 0x35, 0x61, 0x31, + 0x35, 0x36, 0x61, 0x31, 0x35, 0x37, 0x61, 0x31, 0x35, 0x38, 0x61, 0x31, + 0x35, 0x39, 0x61, 0x31, 0x36, 0x30, 0x61, 0x31, 0x36, 0x31, 0x61, 0x31, + 0x36, 0x33, 0x61, 0x31, 0x36, 0x34, 0x61, 0x31, 0x39, 0x36, 0x61, 0x31, + 0x36, 0x35, 0x61, 0x31, 0x39, 0x32, 0x61, 0x31, 0x36, 0x36, 0x61, 0x31, + 0x36, 0x37, 0x61, 0x31, 0x36, 0x38, 0x61, 0x31, 0x36, 0x39, 0x61, 0x31, + 0x37, 0x30, 0x61, 0x31, 0x37, 0x31, 0x61, 0x31, 0x37, 0x32, 0x61, 0x31, + 0x37, 0x33, 0x61, 0x31, 0x36, 0x32, 0x61, 0x31, 0x37, 0x34, 0x61, 0x31, + 0x37, 0x35, 0x61, 0x31, 0x37, 0x36, 0x61, 0x31, 0x37, 0x37, 0x61, 0x31, + 0x37, 0x38, 0x61, 0x31, 0x37, 0x39, 0x61, 0x31, 0x39, 0x33, 0x61, 0x31, + 0x38, 0x30, 0x61, 0x31, 0x39, 0x39, 0x61, 0x31, 0x38, 0x31, 0x61, 0x32, + 0x30, 0x30, 0x61, 0x31, 0x38, 0x32, 0x61, 0x32, 0x30, 0x31, 0x61, 0x31, + 0x38, 0x33, 0x61, 0x31, 0x38, 0x34, 0x61, 0x31, 0x39, 0x37, 0x61, 0x31, + 0x38, 0x35, 0x61, 0x31, 0x39, 0x34, 0x61, 0x31, 0x39, 0x38, 0x61, 0x31, + 0x38, 0x36, 0x61, 0x31, 0x39, 0x35, 0x61, 0x31, 0x38, 0x37, 0x61, 0x31, + 0x38, 0x38, 0x61, 0x31, 0x38, 0x39, 0x61, 0x31, 0x39, 0x30, 0x61, 0x31, + 0x39, 0x31, 0x31, 0x2e, 0x30, 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, + 0x30, 0x33, 0x20, 0x62, 0x79, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, + 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x69, + 0x6e, 0x67, 0x62, 0x61, 0x74, 0x73, 0x20, 0x44, 0x69, 0x6e, 0x67, 0x62, + 0x61, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x87, 0x01, 0x88, + 0x01, 0x89, 0x01, 0x8a, 0x01, 0x8b, 0x01, 0x8c, 0x01, 0x8d, 0x01, 0x8e, + 0x01, 0x8f, 0x01, 0x90, 0x01, 0x91, 0x01, 0x92, 0x01, 0x93, 0x01, 0x94, + 0x01, 0x95, 0x01, 0x96, 0x01, 0x97, 0x01, 0x98, 0x01, 0x99, 0x01, 0x9a, + 0x01, 0x9b, 0x01, 0x9c, 0x01, 0x9d, 0x01, 0x9e, 0x01, 0x9f, 0x01, 0xa0, + 0x01, 0xa1, 0x01, 0xa2, 0x01, 0xa3, 0x01, 0xa4, 0x01, 0xa5, 0x01, 0xa6, + 0x01, 0xa7, 0x01, 0xa8, 0x01, 0xa9, 0x01, 0xaa, 0x01, 0xab, 0x01, 0xac, + 0x01, 0xad, 0x01, 0xae, 0x01, 0xaf, 0x01, 0xb0, 0x01, 0xb1, 0x01, 0xb2, + 0x01, 0xb3, 0x01, 0xb4, 0x01, 0xb5, 0x01, 0xb6, 0x01, 0xb7, 0x01, 0xb8, + 0x01, 0xb9, 0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, + 0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, 0xc3, 0x01, 0xc4, + 0x01, 0xc5, 0x01, 0xc6, 0x01, 0xc7, 0x01, 0xc8, 0x01, 0xc9, 0x01, 0xca, + 0x01, 0xcb, 0x01, 0xcc, 0x01, 0xcd, 0x01, 0xce, 0x01, 0xcf, 0x01, 0xd0, + 0x01, 0xd1, 0x01, 0xd2, 0x01, 0xd3, 0x01, 0xd4, 0x01, 0xd5, 0x01, 0xd6, + 0x01, 0xd7, 0x01, 0xd8, 0x01, 0xd9, 0x01, 0xda, 0x01, 0xdb, 0x01, 0xdc, + 0x01, 0xdd, 0x01, 0xde, 0x01, 0xdf, 0x01, 0xe0, 0x01, 0xe1, 0x01, 0xe2, + 0x01, 0xe3, 0x01, 0xe4, 0x01, 0xe5, 0x01, 0xe6, 0x01, 0xe7, 0x01, 0xe8, + 0x01, 0xe9, 0x01, 0xea, 0x01, 0xeb, 0x01, 0xec, 0x01, 0xed, 0x01, 0xee, + 0x01, 0xef, 0x01, 0xf0, 0x01, 0xf1, 0x01, 0xf2, 0x01, 0xf3, 0x01, 0xf4, + 0x01, 0xf5, 0x01, 0xf6, 0x01, 0xf7, 0x01, 0xf8, 0x01, 0xf9, 0x01, 0xfa, + 0x01, 0xfb, 0x01, 0xfc, 0x01, 0xfd, 0x01, 0xfe, 0x01, 0xff, 0x02, 0x00, + 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, 0x02, 0x06, + 0x02, 0x07, 0x02, 0x08, 0x02, 0x09, 0x02, 0x0a, 0x02, 0x0b, 0x02, 0x0c, + 0x02, 0x0d, 0x02, 0x0e, 0x02, 0x0f, 0x02, 0x10, 0x02, 0x11, 0x02, 0x12, + 0x02, 0x13, 0x02, 0x14, 0x02, 0x15, 0x02, 0x16, 0x02, 0x17, 0x02, 0x18, + 0x02, 0x19, 0x02, 0x1a, 0x02, 0x1b, 0x02, 0x1c, 0x02, 0x1d, 0x02, 0x1e, + 0x02, 0x1f, 0x02, 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x23, 0x02, 0x24, + 0x02, 0x25, 0x02, 0x26, 0x02, 0x27, 0x02, 0x28, 0x02, 0x29, 0x02, 0x2a, + 0x02, 0x2b, 0x02, 0x2c, 0x02, 0x2d, 0x02, 0x2e, 0x02, 0x2f, 0x02, 0x30, + 0x02, 0x31, 0x02, 0x32, 0x02, 0x33, 0x02, 0x34, 0x02, 0x35, 0x02, 0x36, + 0x02, 0x37, 0x02, 0x38, 0x02, 0x39, 0x02, 0x3a, 0x02, 0x3b, 0x02, 0x3c, + 0x02, 0x3d, 0x02, 0x3e, 0x02, 0x3f, 0x02, 0x40, 0x02, 0x41, 0x02, 0x42, + 0x02, 0x43, 0x02, 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x47, 0x02, 0x48, + 0x02, 0x49, 0x02, 0x4a, 0x02, 0x4b, 0x02, 0x4c, 0x02, 0x4d, 0x02, 0x4e, + 0x02, 0x4f, 0x00, 0xca, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, + 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, + 0xfd, 0xfe, 0x00, 0xcb, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x07, 0x00, + 0xc5, 0x01, 0x87, 0x02, 0x4c, 0x04, 0x37, 0x05, 0x4c, 0x06, 0x5d, 0x07, + 0x25, 0x07, 0xf0, 0x08, 0x5f, 0x09, 0x33, 0x0b, 0x1c, 0x0c, 0xf8, 0x0e, + 0xf3, 0x0f, 0xcf, 0x10, 0xab, 0x11, 0x8d, 0x12, 0x56, 0x13, 0x06, 0x13, + 0x60, 0x14, 0x07, 0x14, 0x37, 0x14, 0x6f, 0x15, 0x9f, 0x16, 0xd4, 0x17, + 0x28, 0x17, 0x48, 0x17, 0x7a, 0x17, 0xac, 0x17, 0xc9, 0x18, 0x10, 0x18, + 0x65, 0x18, 0xd6, 0x19, 0x68, 0x19, 0xfd, 0x1a, 0xaf, 0x1b, 0x40, 0x1c, + 0x4e, 0x1c, 0xb7, 0x1d, 0x35, 0x1d, 0x5f, 0x1d, 0xae, 0x1d, 0xfc, 0x1e, + 0x3c, 0x1e, 0xdc, 0x1f, 0x4d, 0x20, 0x07, 0x20, 0x78, 0x20, 0xd2, 0x21, + 0x17, 0x21, 0x7d, 0x21, 0xce, 0x22, 0x84, 0x23, 0x41, 0x23, 0xd9, 0x24, + 0x99, 0x24, 0xda, 0x25, 0x33, 0x25, 0xc8, 0x26, 0x93, 0x28, 0x03, 0x29, + 0x1c, 0x2a, 0x70, 0x2b, 0x79, 0x2d, 0x31, 0x2f, 0xff, 0x30, 0xef, 0x32, + 0x2f, 0x32, 0xda, 0x34, 0x35, 0x34, 0xda, 0x36, 0x3f, 0x37, 0xcb, 0x38, + 0x97, 0x39, 0xc8, 0x3a, 0xf7, 0x3b, 0x1f, 0x3b, 0x82, 0x3b, 0x90, 0x3b, + 0xb1, 0x3b, 0xd0, 0x3b, 0xf6, 0x3c, 0x1b, 0x3c, 0x2c, 0x3c, 0x3f, 0x3c, + 0x55, 0x3c, 0xaf, 0x3c, 0xd4, 0x3c, 0xe2, 0x3c, 0xf3, 0x3d, 0x04, 0x3d, + 0x4a, 0x3d, 0x99, 0x3d, 0xf2, 0x3e, 0x50, 0x3e, 0x98, 0x3e, 0xd7, 0x3f, + 0x08, 0x3f, 0x39, 0x3f, 0x52, 0x3f, 0x6b, 0x3f, 0x88, 0x3f, 0xa5, 0x3f, + 0xc0, 0x3f, 0xdb, 0x3f, 0xfa, 0x40, 0x18, 0x40, 0xa7, 0x41, 0x35, 0x41, + 0xdd, 0x42, 0x37, 0x42, 0x9e, 0x42, 0xf5, 0x43, 0x5f, 0x44, 0x79, 0x45, + 0x5a, 0x45, 0xd8, 0x46, 0x03, 0x46, 0x4d, 0x46, 0xa2, 0x47, 0x22, 0x47, + 0xd4, 0x48, 0xbc, 0x49, 0x51, 0x4a, 0x15, 0x4a, 0xd9, 0x4b, 0x83, 0x4c, + 0x44, 0x4d, 0x0c, 0x4d, 0xd1, 0x4e, 0x26, 0x4e, 0xc1, 0x4f, 0x7f, 0x4f, + 0xee, 0x50, 0x85, 0x51, 0x21, 0x51, 0x96, 0x52, 0x2b, 0x52, 0xc0, 0x53, + 0x67, 0x53, 0xcf, 0x54, 0x6c, 0x55, 0x38, 0x55, 0xba, 0x56, 0x58, 0x57, + 0x10, 0x57, 0x88, 0x58, 0x46, 0x58, 0xfe, 0x59, 0xae, 0x59, 0xe9, 0x5a, + 0x6b, 0x5b, 0x0c, 0x5b, 0x5e, 0x5b, 0xca, 0x5c, 0x5a, 0x5c, 0xa3, 0x5d, + 0x25, 0x5d, 0xaf, 0x5e, 0x24, 0x5e, 0x4b, 0x5e, 0x72, 0x5e, 0xb4, 0x5e, + 0xf6, 0x5f, 0x16, 0x5f, 0x34, 0x5f, 0x53, 0x5f, 0x8b, 0x5f, 0xe6, 0x60, + 0x01, 0x60, 0x1d, 0x60, 0x53, 0x60, 0x99, 0x60, 0xb3, 0x60, 0xda, 0x61, + 0x00, 0x61, 0x17, 0x61, 0x56, 0x61, 0x94, 0x61, 0xb4, 0x61, 0xdc, 0x62, + 0x17, 0x62, 0x53, 0x62, 0x90, 0x62, 0xcd, 0x63, 0x03, 0x63, 0x3e, 0x63, + 0x7b, 0x63, 0xb7, 0x64, 0x07, 0x64, 0xbe, 0x65, 0x30, 0x65, 0x9e, 0x66, + 0x11, 0x66, 0x90, 0x66, 0xe4, 0x67, 0x5c, 0x67, 0xd7, 0x68, 0x4f, 0x68, + 0xfd, 0x69, 0xbf, 0x6a, 0x1d, 0xfc, 0xc5, 0x0e, 0xfc, 0xc5, 0x0e, 0xf7, + 0x1b, 0xf8, 0xfd, 0xf7, 0x0c, 0x15, 0x2b, 0xf7, 0x02, 0xf8, 0x36, 0xc2, + 0x05, 0x41, 0xb5, 0x4b, 0x9e, 0x4b, 0x8b, 0x82, 0x8b, 0x76, 0x8a, 0x79, + 0x8a, 0x08, 0xfb, 0x9d, 0x7c, 0x05, 0x5d, 0xb7, 0x6a, 0xa4, 0x6c, 0x97, + 0x4a, 0xa4, 0x89, 0x8c, 0x8b, 0x95, 0x8b, 0x8e, 0x8c, 0x8f, 0x8e, 0x90, + 0x97, 0xa4, 0x8e, 0x95, 0x8b, 0x9b, 0x08, 0xc3, 0x54, 0xbf, 0x4e, 0x5d, + 0x65, 0x66, 0x5e, 0x1e, 0x8b, 0x59, 0xb4, 0x62, 0xcb, 0x7b, 0xee, 0x79, + 0xc8, 0x64, 0xb4, 0x46, 0x69, 0x68, 0x57, 0x71, 0x67, 0x8b, 0x7b, 0x8b, + 0x74, 0x8f, 0x6e, 0x92, 0x08, 0x74, 0x91, 0x75, 0x8e, 0x7a, 0x8b, 0x08, + 0x5d, 0x64, 0x65, 0x5d, 0x53, 0xc0, 0x59, 0xc7, 0xc1, 0xb1, 0xb0, 0xbe, + 0x1f, 0x8b, 0x90, 0x8a, 0x92, 0x8a, 0x8f, 0x88, 0x99, 0x89, 0x94, 0x8b, + 0x8e, 0x08, 0x94, 0x93, 0x91, 0x97, 0x1e, 0xbc, 0x89, 0x05, 0x97, 0x8b, + 0xd0, 0x92, 0xb4, 0x90, 0x08, 0xf0, 0xfb, 0x06, 0x05, 0xe7, 0x93, 0x05, + 0xfc, 0x65, 0xf8, 0x69, 0x15, 0xb5, 0xb5, 0x65, 0x64, 0x6c, 0x75, 0x73, + 0x70, 0x5e, 0x5c, 0xb2, 0xb1, 0xa8, 0xa5, 0xa5, 0xaa, 0x1f, 0x73, 0xfb, + 0xf8, 0x15, 0xb9, 0xb0, 0x6b, 0x62, 0x69, 0x6f, 0x70, 0x68, 0x5f, 0x63, + 0xb0, 0xb4, 0x1f, 0xaa, 0xa7, 0xa4, 0xaf, 0x1e, 0x0e, 0xf7, 0x0e, 0xf8, + 0xb9, 0xf7, 0xf0, 0x15, 0xf8, 0x0d, 0xf7, 0x24, 0x05, 0x68, 0xaa, 0x76, + 0x95, 0x67, 0x8b, 0x70, 0x8b, 0x67, 0x83, 0x65, 0x7d, 0x08, 0xfb, 0xcc, + 0xfb, 0x0a, 0x05, 0x59, 0xa2, 0x3f, 0xa2, 0x6f, 0x8b, 0x6f, 0x8d, 0x81, + 0x90, 0x8b, 0x96, 0x8b, 0x8e, 0x8d, 0x91, 0x8e, 0x92, 0x91, 0x98, 0x8f, + 0x9e, 0x8b, 0x98, 0x08, 0xbf, 0x5c, 0xb4, 0x51, 0x4e, 0x60, 0x62, 0x51, + 0x50, 0xbf, 0x61, 0xd4, 0x1e, 0xd1, 0x8d, 0x05, 0xc8, 0x8b, 0xb7, 0x74, + 0x9e, 0x61, 0x7d, 0x62, 0x5b, 0x70, 0x50, 0x8b, 0x08, 0x47, 0x8c, 0x05, + 0x40, 0x57, 0x5f, 0x4d, 0x54, 0xb6, 0x64, 0xc7, 0xc7, 0xb8, 0xb3, 0xc1, + 0x1f, 0x8b, 0x98, 0x89, 0x95, 0x87, 0x94, 0x81, 0xa2, 0x8b, 0x8b, 0x8b, + 0x91, 0x8b, 0x94, 0x93, 0x91, 0x9a, 0x8d, 0xcc, 0x93, 0x94, 0x8e, 0xe9, + 0xb0, 0x08, 0xf7, 0xc9, 0xfb, 0x06, 0x05, 0xb4, 0x7c, 0xa9, 0x85, 0xaa, + 0x8b, 0xb4, 0x8b, 0xa5, 0x96, 0xa7, 0xa8, 0x08, 0xfc, 0x0e, 0xf7, 0x22, + 0x05, 0xfc, 0x2f, 0xf7, 0x7b, 0x15, 0xb5, 0xaa, 0x6d, 0x64, 0x64, 0x70, + 0x6f, 0x65, 0x60, 0x68, 0xab, 0xb2, 0x1f, 0xb1, 0xa8, 0xa6, 0xb4, 0x1e, + 0x95, 0xfb, 0xde, 0x15, 0xb0, 0xa7, 0x70, 0x66, 0x5f, 0x6e, 0x6f, 0x5d, + 0x64, 0x6f, 0xa5, 0xaf, 0x1f, 0xb2, 0xaf, 0xae, 0xb4, 0x1e, 0x0e, 0xf7, + 0x1b, 0xf8, 0xfd, 0xf8, 0xcb, 0x15, 0x2f, 0x93, 0x26, 0xfb, 0x06, 0x05, + 0x61, 0x90, 0x49, 0x92, 0x7d, 0x8b, 0x08, 0x5a, 0x8a, 0x05, 0x7f, 0x83, + 0x91, 0x94, 0x1f, 0x8b, 0x8d, 0x8d, 0x95, 0x8e, 0x98, 0x8c, 0x90, 0x8c, + 0x91, 0x8b, 0x91, 0x08, 0xbd, 0x65, 0xaf, 0x55, 0x4f, 0x56, 0x59, 0x53, + 0x1e, 0x5d, 0xb2, 0x65, 0xb9, 0x1e, 0x9b, 0x8b, 0xa2, 0x8e, 0xa2, 0x92, + 0x08, 0xa7, 0x92, 0xa3, 0x8f, 0x9b, 0x8b, 0xaf, 0x8b, 0xbe, 0x71, 0xae, + 0x68, 0x75, 0x5d, 0x44, 0x53, 0x56, 0x7f, 0x40, 0x79, 0x8b, 0x8b, 0x7b, + 0x84, 0x62, 0x78, 0x70, 0x65, 0x8b, 0x65, 0x08, 0x5e, 0xb0, 0x66, 0xb9, + 0xc8, 0xc2, 0xbf, 0xc3, 0x1e, 0x8b, 0x9b, 0x88, 0x95, 0x7f, 0xa4, 0x88, + 0x90, 0x8a, 0x8f, 0x8b, 0x8e, 0x8b, 0x95, 0x8d, 0x8d, 0xcc, 0xa4, 0xa9, + 0x96, 0xad, 0xa4, 0xb9, 0xb8, 0x08, 0xf7, 0x9d, 0x7c, 0x05, 0x9c, 0x8a, + 0x9c, 0x8a, 0x99, 0x8b, 0xcb, 0x8b, 0xcc, 0x9f, 0xd4, 0xb4, 0x08, 0xfc, + 0x36, 0xc1, 0x05, 0xeb, 0xf7, 0x03, 0x05, 0xfc, 0x41, 0xfb, 0xe6, 0x15, + 0xa5, 0xa1, 0x72, 0x6c, 0x65, 0x61, 0x65, 0x60, 0x6d, 0x72, 0xa5, 0xa9, + 0xb0, 0xba, 0xb2, 0xb8, 0x1f, 0x61, 0xf7, 0xfa, 0x15, 0xb0, 0xa7, 0x71, + 0x68, 0x1f, 0x62, 0x67, 0x6b, 0x5c, 0x67, 0x6f, 0xa4, 0xab, 0xb3, 0xb2, + 0xb0, 0xb6, 0x1e, 0x0e, 0xf7, 0x21, 0xf7, 0x4a, 0xf7, 0x7a, 0x15, 0x58, + 0x63, 0x64, 0x5a, 0x59, 0xb3, 0x63, 0xbd, 0xbc, 0xb3, 0xb3, 0xbc, 0x1f, + 0xbb, 0x63, 0xb4, 0x5b, 0x1e, 0x90, 0x72, 0x15, 0xac, 0xa5, 0x6e, 0x68, + 0x67, 0x71, 0x6e, 0x69, 0x69, 0x6e, 0xa8, 0xaf, 0xae, 0xa8, 0xa8, 0xae, + 0x1f, 0x85, 0xf8, 0x46, 0x15, 0x59, 0x63, 0x64, 0x5a, 0x59, 0xb3, 0x63, + 0xbc, 0xbc, 0xb3, 0xb3, 0xbc, 0xbb, 0x63, 0xb4, 0x5b, 0x1f, 0x8f, 0x72, + 0x15, 0xaa, 0xa5, 0x6e, 0x69, 0x68, 0x71, 0x6f, 0x6b, 0x69, 0x6f, 0xa8, + 0xad, 0xae, 0xa8, 0xa7, 0xad, 0x1f, 0xf7, 0xb1, 0xfb, 0x69, 0x15, 0x72, + 0x77, 0x74, 0x6e, 0x6f, 0x9f, 0x74, 0xa3, 0xa4, 0xa0, 0xa3, 0xa8, 0xa7, + 0x77, 0xa1, 0x72, 0x1f, 0x8d, 0x78, 0x15, 0x98, 0x96, 0x7e, 0x7c, 0x7a, + 0x7f, 0x7c, 0x7d, 0x7c, 0x81, 0x98, 0x9b, 0x9c, 0x97, 0x99, 0x9a, 0x1f, + 0xf8, 0x6d, 0xf7, 0x2e, 0x15, 0x5a, 0xbf, 0x65, 0x9e, 0x53, 0x8b, 0x58, + 0x8b, 0x53, 0x78, 0x49, 0x65, 0x08, 0xfb, 0x36, 0x2c, 0x05, 0x74, 0x9e, + 0x7c, 0x93, 0x7d, 0x8b, 0x87, 0x8b, 0x85, 0x8a, 0x84, 0x89, 0x08, 0x6d, + 0x84, 0x78, 0x88, 0x77, 0x8b, 0x7e, 0x8b, 0x86, 0x8c, 0x80, 0x8f, 0xa0, + 0xac, 0x94, 0xa3, 0x8b, 0xa6, 0x08, 0xd4, 0x49, 0xc7, 0x39, 0x33, 0x50, + 0x50, 0x33, 0x1e, 0x8b, 0x58, 0x9f, 0x60, 0xb0, 0x70, 0xaa, 0x75, 0xb5, + 0x81, 0xcf, 0x87, 0xc7, 0x88, 0x95, 0x8a, 0x9b, 0x83, 0x96, 0x86, 0x93, + 0x7e, 0x8b, 0x7f, 0x8b, 0x70, 0x71, 0x7d, 0x59, 0x8a, 0x2f, 0x89, 0x6d, + 0x85, 0x65, 0x74, 0x08, 0x61, 0x70, 0x75, 0x61, 0x8b, 0x54, 0x08, 0x32, + 0xc6, 0x50, 0xe3, 0xdf, 0xc8, 0xc3, 0xd9, 0x1e, 0x8b, 0xa9, 0x83, 0xa4, + 0x75, 0xab, 0x9c, 0x90, 0x93, 0x8c, 0x94, 0x8b, 0x95, 0x8b, 0x9d, 0x89, + 0xa0, 0x87, 0x08, 0x93, 0x89, 0x94, 0x8a, 0x90, 0x8b, 0x91, 0x8b, 0x8f, + 0x8c, 0x8f, 0x8d, 0x08, 0xbb, 0xa9, 0xf7, 0x53, 0xfb, 0x12, 0x05, 0xb6, + 0x6e, 0xc5, 0x77, 0xb2, 0x8b, 0xc3, 0x8b, 0xc2, 0xa2, 0xac, 0xb1, 0x08, + 0xfb, 0xd6, 0xf7, 0x61, 0xf7, 0xd9, 0xf7, 0x56, 0x05, 0xfc, 0x9d, 0xfb, + 0xad, 0x15, 0x86, 0x88, 0x82, 0x89, 0x85, 0x8b, 0x08, 0x45, 0x8e, 0x05, + 0x6b, 0x69, 0x7b, 0x7c, 0x1f, 0x8b, 0x87, 0x8d, 0x87, 0x8d, 0x87, 0x9f, + 0x73, 0x91, 0x7c, 0x8b, 0x6f, 0x08, 0x45, 0x5b, 0x5a, 0x47, 0x43, 0x5b, + 0xbc, 0xd4, 0xde, 0xbf, 0xb9, 0xe6, 0x1e, 0xc4, 0x06, 0xcf, 0x8b, 0xad, + 0xa2, 0x87, 0xb9, 0x8b, 0x8d, 0x8b, 0x8d, 0x8a, 0x8d, 0x08, 0xf7, 0xb9, + 0xf7, 0x3e, 0x05, 0xc2, 0xab, 0x8b, 0x8b, 0x96, 0x90, 0xaf, 0x9c, 0xab, + 0x94, 0xa5, 0x8b, 0xaf, 0x8b, 0xa6, 0x80, 0xae, 0x6c, 0x08, 0xfc, 0x7a, + 0xfb, 0xb2, 0x05, 0xce, 0x95, 0x15, 0xf2, 0xc9, 0xf7, 0xc5, 0xfb, 0x56, + 0x05, 0x68, 0x70, 0x71, 0x80, 0x6b, 0x8b, 0x5d, 0x8b, 0x65, 0x9b, 0x40, + 0xbd, 0x08, 0xfb, 0x30, 0xf3, 0x05, 0xfb, 0x24, 0xf7, 0x0c, 0x15, 0x7b, + 0xa0, 0x70, 0x96, 0x64, 0x8b, 0x08, 0x48, 0x06, 0x37, 0x54, 0xbd, 0xd8, + 0xd3, 0xbb, 0xbe, 0xcf, 0xd0, 0xbe, 0x5b, 0x4a, 0x1f, 0x8b, 0x77, 0x86, + 0x77, 0x82, 0x7d, 0x7c, 0x74, 0x8b, 0x8b, 0x8b, 0x85, 0x8b, 0x7a, 0xa5, + 0x82, 0xb8, 0x8b, 0x99, 0x8b, 0x95, 0x8c, 0x91, 0x8d, 0x08, 0xad, 0x95, + 0x8b, 0x8b, 0x96, 0x8b, 0x98, 0x8b, 0x92, 0x87, 0x94, 0x7e, 0x08, 0x2d, + 0x53, 0x05, 0x0e, 0xfb, 0x0c, 0xf8, 0xbf, 0xf7, 0x1e, 0x15, 0x98, 0x8b, + 0x8c, 0x8b, 0x8c, 0x8d, 0x8e, 0x8c, 0x8e, 0xa2, 0x8c, 0xaf, 0x5a, 0xf7, + 0x21, 0x7d, 0xab, 0x79, 0x9e, 0x6c, 0xae, 0x8b, 0x8b, 0x8b, 0x98, 0x8b, + 0x96, 0x8c, 0x92, 0x8c, 0x97, 0xac, 0x84, 0x97, 0x82, 0x95, 0x70, 0x08, + 0xaa, 0x84, 0xa4, 0x89, 0xbb, 0x8b, 0xa5, 0x8b, 0x95, 0x8c, 0xa0, 0x8f, + 0x86, 0xbc, 0x83, 0xa3, 0x78, 0x9a, 0x66, 0xa8, 0xfb, 0x1c, 0xa5, 0xfb, + 0x0b, 0x8b, 0xfb, 0x0c, 0x8b, 0xfb, 0x1c, 0x71, 0x66, 0x6e, 0x79, 0x7c, + 0x82, 0x73, 0x86, 0x5a, 0x08, 0xa0, 0x87, 0x94, 0x8a, 0xa6, 0x8b, 0xbb, + 0x8b, 0xa5, 0x8d, 0xaa, 0x92, 0x95, 0xa6, 0x97, 0x94, 0xab, 0x92, 0x8d, + 0x7f, 0x8c, 0x83, 0x8b, 0x81, 0x8b, 0x7e, 0x8a, 0x8a, 0x82, 0x80, 0x83, + 0x82, 0x83, 0x82, 0x83, 0x83, 0x08, 0x81, 0x7f, 0x8a, 0x89, 0x87, 0x83, + 0x68, 0x35, 0x88, 0x84, 0x71, 0x41, 0x8d, 0x5b, 0x8d, 0x7e, 0x92, 0x8b, + 0x8c, 0x8a, 0x8f, 0x8b, 0x92, 0x8b, 0x08, 0xf8, 0x1c, 0x06, 0xfb, 0xb4, + 0xf7, 0xe2, 0x15, 0x9b, 0x8d, 0x05, 0xb7, 0x90, 0x95, 0x8c, 0xa1, 0x8b, + 0xa2, 0x8b, 0x95, 0x8a, 0xb6, 0x86, 0x08, 0x9b, 0x89, 0x7a, 0x62, 0x05, + 0x63, 0x8d, 0x7a, 0x8c, 0x79, 0x8b, 0x7a, 0x8b, 0x79, 0x8a, 0x63, 0x89, + 0x08, 0x7a, 0xb4, 0x05, 0xea, 0x45, 0x15, 0xbe, 0xb7, 0x5e, 0x57, 0x56, + 0x5f, 0x5f, 0x56, 0x55, 0x60, 0xb6, 0xc2, 0xc0, 0xb7, 0xb6, 0xc2, 0x1f, + 0xf7, 0xd7, 0x91, 0x15, 0x74, 0x85, 0x7e, 0x8a, 0x68, 0x8b, 0x6e, 0x8b, + 0x75, 0x8d, 0x67, 0x90, 0x92, 0x70, 0x98, 0x87, 0xdd, 0x8b, 0xb5, 0x8b, + 0x8f, 0x8d, 0x95, 0xa8, 0x08, 0xfd, 0x1f, 0x16, 0x96, 0x6f, 0x8f, 0x88, + 0xaf, 0x8b, 0xb3, 0x8b, 0xac, 0x8d, 0x98, 0x8f, 0x97, 0x8e, 0x8f, 0x8f, + 0x91, 0x9d, 0x69, 0x86, 0x67, 0x89, 0x6a, 0x8b, 0x6c, 0x8b, 0x86, 0x8c, + 0x77, 0x91, 0x08, 0x0e, 0x59, 0xf7, 0x34, 0xf7, 0x10, 0x15, 0x4b, 0xd2, + 0x6e, 0xd0, 0x8b, 0xdf, 0x08, 0xf7, 0x44, 0xf7, 0x29, 0xf7, 0x27, 0xf7, + 0x46, 0xf7, 0x47, 0xf7, 0x29, 0xfb, 0x27, 0xfb, 0x44, 0xfb, 0x4b, 0xfb, + 0x2c, 0xfb, 0x25, 0xfb, 0x53, 0x2f, 0x48, 0xb3, 0xc2, 0x99, 0x91, 0x99, + 0x91, 0x1e, 0x8c, 0x8b, 0x8d, 0x8a, 0x8e, 0x8a, 0x90, 0x88, 0x94, 0x88, + 0x91, 0x8b, 0xa5, 0x8b, 0xc2, 0xd4, 0x8b, 0xad, 0x8b, 0x8f, 0x89, 0x8f, + 0x87, 0x8f, 0x08, 0x7e, 0x98, 0x87, 0x92, 0x8b, 0x96, 0x8b, 0xa9, 0xbd, + 0xf5, 0xa7, 0xa9, 0x9a, 0x9b, 0x91, 0x8e, 0xa1, 0x8f, 0x96, 0x8c, 0x8f, + 0x8e, 0x90, 0x91, 0x9f, 0xa6, 0x97, 0xb3, 0x8b, 0xb3, 0x8b, 0x9a, 0x83, + 0x8f, 0x6e, 0x8b, 0x08, 0x63, 0x8b, 0x84, 0x87, 0x68, 0x63, 0x30, 0x24, + 0x40, 0xfb, 0x3d, 0x8b, 0x26, 0x8b, 0x82, 0x8d, 0x83, 0x8d, 0x88, 0x92, + 0x84, 0x8c, 0x89, 0x8b, 0x89, 0x8b, 0x89, 0x8a, 0x89, 0x89, 0x88, 0x08, + 0x7f, 0x7d, 0x85, 0x7a, 0x8b, 0x79, 0x08, 0x47, 0xdd, 0x58, 0xf7, 0x00, + 0xf7, 0x63, 0xf7, 0x37, 0xf7, 0x32, 0xf7, 0x5c, 0xf7, 0x5a, 0xfb, 0x37, + 0xf7, 0x38, 0xfb, 0x5a, 0xfb, 0x57, 0xfb, 0x38, 0xfb, 0x36, 0xfb, 0x54, + 0x1e, 0x8b, 0x38, 0xb1, 0x27, 0xbc, 0x63, 0x92, 0x85, 0x94, 0x87, 0x92, + 0x8b, 0x08, 0x8e, 0x8b, 0x90, 0x8c, 0x92, 0x8e, 0x08, 0xf7, 0xf3, 0xf8, + 0x68, 0x15, 0x87, 0x53, 0x7f, 0x69, 0x71, 0x68, 0x98, 0x86, 0x97, 0x89, + 0x9a, 0x8b, 0x9a, 0x8b, 0x8c, 0x8c, 0x95, 0x9c, 0x9a, 0xa5, 0x91, 0xa0, + 0x8b, 0xa6, 0x8b, 0x95, 0x8b, 0x8c, 0x83, 0x92, 0x7e, 0x96, 0x81, 0x91, + 0x7d, 0x90, 0x08, 0xfb, 0x2f, 0xfb, 0xf9, 0x15, 0x7b, 0x54, 0x74, 0x6a, + 0x64, 0x74, 0x9c, 0x80, 0x9f, 0x83, 0x94, 0x8b, 0xa2, 0x8b, 0xb8, 0xc7, + 0x8b, 0xaa, 0x8b, 0x92, 0x86, 0x91, 0x75, 0x9d, 0x08, 0x82, 0x93, 0x05, + 0x0e, 0x5a, 0xf8, 0xfd, 0xf7, 0x26, 0x15, 0x99, 0x95, 0xae, 0xc2, 0x90, + 0xa0, 0x08, 0xfb, 0x25, 0xf7, 0x09, 0x05, 0x8b, 0x58, 0x6f, 0x5e, 0x5f, + 0x76, 0x08, 0xf7, 0x37, 0x35, 0x05, 0xfc, 0x89, 0xee, 0x15, 0x96, 0x6c, + 0xa3, 0x62, 0x9c, 0x7a, 0x08, 0xf7, 0x3a, 0xd7, 0x05, 0x5d, 0xa6, 0x76, + 0xb2, 0x8a, 0xc4, 0x08, 0xfb, 0x2a, 0xfb, 0x02, 0x05, 0xf7, 0xd9, 0xf8, + 0x1e, 0x15, 0x7c, 0x90, 0x81, 0x8c, 0x76, 0x8b, 0x75, 0x8b, 0x7d, 0x89, + 0x7d, 0x87, 0x08, 0x76, 0xfb, 0x4d, 0x05, 0xa4, 0x9b, 0xa1, 0x91, 0xa6, + 0x8b, 0xa8, 0x8b, 0x9f, 0x85, 0xa1, 0x7b, 0x08, 0x6f, 0xf7, 0x4d, 0x05, + 0x60, 0xfb, 0x55, 0x15, 0x52, 0x5d, 0x5e, 0x54, 0x53, 0xb8, 0x5d, 0xc3, + 0xc3, 0xb8, 0xb8, 0xc3, 0xc2, 0x5e, 0xb9, 0x55, 0x1f, 0x8e, 0xf7, 0x98, + 0x15, 0xfb, 0x5f, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5e, 0xf7, + 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, 0x35, 0xf7, + 0x5b, 0xf7, 0x58, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x8a, 0x71, + 0x15, 0xd8, 0x8b, 0xde, 0x6a, 0xc5, 0x56, 0xd4, 0x49, 0xb1, 0x35, 0x8b, + 0x2c, 0x08, 0xfb, 0x4c, 0xfb, 0x2a, 0xfb, 0x2a, 0xfb, 0x4c, 0xfb, 0x4e, + 0xfb, 0x28, 0xf7, 0x29, 0xf7, 0x4f, 0x1e, 0x8b, 0xdb, 0xaa, 0xdb, 0xc2, + 0xc7, 0xce, 0xd5, 0xdf, 0xb0, 0xf1, 0x8b, 0x08, 0x0e, 0x5b, 0xae, 0xf7, + 0xef, 0x15, 0xae, 0x7d, 0x6a, 0xfb, 0x0a, 0xbe, 0x92, 0xd5, 0xee, 0x05, + 0xbb, 0x86, 0xda, 0x84, 0x93, 0x8b, 0xc4, 0x8a, 0x8b, 0x8b, 0x93, 0x87, + 0x94, 0x87, 0x90, 0x83, 0x8b, 0x81, 0x8b, 0x80, 0x89, 0x84, 0x76, 0x3b, + 0x08, 0x34, 0xfb, 0x59, 0xb0, 0x8b, 0x05, 0x9d, 0x8b, 0x91, 0x8f, 0x9c, + 0xa2, 0x08, 0xb2, 0xc2, 0xc8, 0x8b, 0x05, 0x91, 0x91, 0x93, 0x93, 0x94, + 0x85, 0x93, 0x85, 0x1f, 0x6a, 0x8b, 0xbc, 0xd1, 0xc7, 0x8b, 0x05, 0x91, + 0x91, 0x93, 0x94, 0x93, 0x85, 0x94, 0x84, 0x1f, 0x6c, 0x8b, 0xd5, 0xee, + 0x94, 0x8c, 0x05, 0xe9, 0x8f, 0x96, 0x8c, 0xad, 0x90, 0xaa, 0x90, 0x9f, + 0x97, 0x8b, 0x99, 0x8b, 0x9e, 0x5f, 0x98, 0x3f, 0x8e, 0x08, 0x45, 0x8e, + 0x82, 0x8c, 0x41, 0xee, 0xaa, 0x8b, 0x05, 0x92, 0x91, 0x94, 0x94, 0x93, + 0x85, 0x93, 0x85, 0x1f, 0x4f, 0x8b, 0x5a, 0xd1, 0xac, 0x8b, 0x05, 0x91, + 0x91, 0x93, 0x94, 0x93, 0x85, 0x93, 0x85, 0x1f, 0x4e, 0x8b, 0x64, 0xc2, + 0x05, 0x7a, 0xa3, 0x85, 0x8f, 0x79, 0x8b, 0x08, 0x66, 0x8b, 0xe2, 0xfb, + 0x5a, 0x05, 0xa0, 0x3d, 0x8d, 0x82, 0x8b, 0x80, 0x8b, 0x7a, 0x7f, 0x83, + 0x72, 0x8a, 0x08, 0x6a, 0x8a, 0x05, 0x79, 0x8b, 0x88, 0x8b, 0x65, 0x87, + 0x7b, 0x8a, 0x7b, 0x89, 0x7a, 0x8a, 0x08, 0x67, 0x87, 0x41, 0xee, 0x58, + 0x92, 0xac, 0xfb, 0x0a, 0x68, 0x80, 0x05, 0x0e, 0xfb, 0x29, 0xf9, 0x23, + 0xf8, 0xc0, 0x15, 0xfd, 0x00, 0xfc, 0x37, 0xf9, 0x00, 0xf8, 0x37, 0x06, + 0xfc, 0xed, 0x62, 0x15, 0xf7, 0x64, 0xfb, 0x37, 0x8b, 0x80, 0xfb, 0x64, + 0xfb, 0x37, 0x8b, 0xf7, 0xe5, 0x05, 0xf8, 0xda, 0xfb, 0xfb, 0x15, 0xfc, + 0xda, 0x8b, 0xf7, 0x64, 0xf7, 0x36, 0x05, 0x9c, 0x67, 0xa7, 0x78, 0xb1, + 0x8b, 0xb1, 0x8b, 0xa8, 0x9e, 0x9b, 0xaf, 0x08, 0xf7, 0x64, 0xfb, 0x36, + 0x05, 0xf7, 0xfb, 0x04, 0x8b, 0xfb, 0xe5, 0xfb, 0x64, 0xf7, 0x37, 0x8b, + 0x96, 0xf7, 0x64, 0xf7, 0x37, 0x05, 0xa1, 0x04, 0xfb, 0x64, 0xfb, 0x36, + 0x05, 0x7b, 0xaf, 0x6e, 0x9e, 0x65, 0x8b, 0x66, 0x8b, 0x6d, 0x78, 0x7b, + 0x67, 0x08, 0xfb, 0x64, 0xf7, 0x36, 0xf8, 0xda, 0x8b, 0x05, 0x0e, 0xf7, + 0x0d, 0xf9, 0x2a, 0xf8, 0x3d, 0x15, 0x9f, 0x8b, 0xb4, 0x85, 0xad, 0x82, + 0xb4, 0x81, 0x91, 0x8a, 0x9e, 0x8b, 0xa0, 0x8b, 0xb2, 0x8f, 0x9b, 0x90, + 0x9d, 0x90, 0x93, 0x92, 0x8b, 0x95, 0x8b, 0x99, 0x7e, 0x97, 0x6f, 0x9a, + 0x66, 0x9e, 0xfb, 0x00, 0xb2, 0x5b, 0x97, 0x08, 0x5d, 0x96, 0xfb, 0x19, + 0x9b, 0x58, 0x8b, 0x73, 0x8b, 0x7d, 0x88, 0x72, 0x80, 0x5e, 0x78, 0x5b, + 0x74, 0x6c, 0x7a, 0x6e, 0x7a, 0x84, 0x89, 0x67, 0x88, 0x5b, 0x88, 0x8a, + 0x8b, 0x80, 0x82, 0x74, 0x79, 0x7b, 0x54, 0x8b, 0x50, 0x08, 0x8b, 0x4e, + 0x9e, 0x46, 0x9d, 0x86, 0x9b, 0x87, 0xbe, 0x83, 0xa5, 0x89, 0x9f, 0x89, + 0x8d, 0x8b, 0x90, 0x89, 0x91, 0x89, 0x90, 0x88, 0x95, 0x85, 0xd7, 0x61, + 0x8d, 0x8a, 0xb5, 0x8b, 0xac, 0x8b, 0xd1, 0x95, 0xc6, 0x98, 0x08, 0xb0, + 0x93, 0x9c, 0x9b, 0x8b, 0xa6, 0x8b, 0x92, 0x8a, 0x93, 0x8a, 0x94, 0xaa, + 0x94, 0x95, 0x96, 0x8b, 0xa2, 0x8b, 0x9c, 0x86, 0x97, 0x7d, 0x9a, 0xae, + 0x99, 0x9c, 0x9d, 0x8b, 0xa1, 0x8b, 0x9f, 0x84, 0x96, 0x65, 0xab, 0x08, + 0x9d, 0x8c, 0x05, 0xfc, 0x9d, 0xd0, 0x15, 0x84, 0x97, 0x85, 0x8f, 0x82, + 0x8b, 0x08, 0x5c, 0x66, 0x35, 0x20, 0x21, 0xa9, 0x49, 0xbb, 0x1f, 0x96, + 0x8b, 0x93, 0x8f, 0x94, 0x96, 0x88, 0x8a, 0x89, 0x8b, 0x8a, 0x8b, 0x5b, + 0x8b, 0x6f, 0xc5, 0x8b, 0xef, 0x8b, 0xd2, 0x9c, 0xcd, 0xa3, 0xa4, 0x97, + 0x97, 0x93, 0x8d, 0xa0, 0x8c, 0x08, 0x0e, 0xef, 0xae, 0xf8, 0x8f, 0x15, + 0x8b, 0xfb, 0xee, 0xf4, 0x7e, 0x97, 0xa4, 0xde, 0x8b, 0x8b, 0xbc, 0x05, + 0xa2, 0x89, 0xa0, 0x88, 0x91, 0x89, 0x91, 0x89, 0x9c, 0x82, 0xa4, 0x7e, + 0xc5, 0x6d, 0x96, 0x8a, 0xf7, 0x05, 0x8c, 0x98, 0x78, 0x9f, 0x82, 0xa9, + 0x8b, 0xd3, 0x8b, 0xd1, 0xb3, 0x8b, 0xb4, 0x8b, 0x99, 0x85, 0x97, 0x78, + 0xa1, 0x08, 0x93, 0x95, 0x8d, 0x90, 0x8b, 0x96, 0x8b, 0xa4, 0x81, 0x9c, + 0x73, 0x9a, 0x08, 0x90, 0x97, 0x8d, 0x90, 0x8b, 0x91, 0x8b, 0x97, 0x86, + 0x95, 0x7e, 0x99, 0x9d, 0x8b, 0x8b, 0x8b, 0xca, 0x8f, 0xe9, 0x90, 0xa2, + 0x8e, 0x9e, 0x97, 0x9c, 0x95, 0x95, 0x9a, 0x8b, 0x9a, 0x8b, 0xa0, 0x77, + 0xa0, 0x6b, 0x98, 0x08, 0x6a, 0x99, 0xfb, 0x04, 0x94, 0xfb, 0x14, 0x8b, + 0x72, 0x8b, 0x77, 0x8a, 0x69, 0x87, 0x08, 0x78, 0x98, 0x7b, 0x90, 0x77, + 0x8b, 0x6c, 0x8b, 0x6c, 0x7f, 0x5d, 0x6e, 0x60, 0x70, 0x77, 0x83, 0x72, + 0x8b, 0x88, 0x8b, 0x87, 0x8b, 0x84, 0x8c, 0x08, 0x8b, 0xad, 0x05, 0xfb, + 0x5c, 0x80, 0x05, 0xf3, 0x74, 0x15, 0xca, 0xfb, 0xa4, 0x55, 0x06, 0x82, + 0xf7, 0xa4, 0x05, 0xeb, 0x69, 0x15, 0xad, 0x8b, 0x97, 0x8f, 0xa9, 0x9d, + 0xbf, 0xac, 0x8b, 0x8b, 0x9a, 0x92, 0xa5, 0x98, 0xa1, 0x92, 0x99, 0x8b, + 0x9f, 0x8b, 0xa3, 0x81, 0x99, 0x7c, 0x08, 0xd2, 0x44, 0x05, 0x97, 0x7e, + 0x93, 0x7d, 0x8b, 0x81, 0x8b, 0x7b, 0x78, 0x7d, 0x76, 0x8b, 0x76, 0x8b, + 0x7c, 0x92, 0x6f, 0xa4, 0x08, 0x50, 0xbc, 0x7f, 0x7d, 0xb6, 0x56, 0x05, + 0x72, 0x70, 0x6c, 0x7c, 0x6a, 0x8b, 0x7f, 0x8b, 0x78, 0x8e, 0x74, 0x90, + 0x08, 0x7e, 0x8e, 0x83, 0x7c, 0xce, 0x74, 0xc1, 0x8b, 0x05, 0x9a, 0x5c, + 0x93, 0x82, 0xae, 0x85, 0x8d, 0x68, 0x94, 0x7d, 0xa4, 0x86, 0x08, 0x7e, + 0x07, 0x71, 0x8a, 0x83, 0x8b, 0x82, 0x8b, 0x57, 0x8b, 0x60, 0x95, 0x6d, + 0x9e, 0x08, 0x73, 0x9a, 0x05, 0x7d, 0x93, 0x80, 0x91, 0x84, 0x8e, 0x7d, + 0x8f, 0x80, 0x8d, 0x73, 0x8c, 0x08, 0xf7, 0x5a, 0x07, 0xf7, 0xbf, 0xcf, + 0x15, 0xb5, 0x8d, 0x9f, 0x8c, 0xa2, 0x8b, 0xdc, 0x8b, 0xf5, 0x83, 0xa5, + 0x83, 0xa4, 0x83, 0x99, 0x7f, 0x8b, 0x7d, 0x8b, 0x83, 0x84, 0x81, 0x83, + 0x88, 0x76, 0x83, 0x2d, 0x84, 0x28, 0x8b, 0x86, 0x8b, 0x7d, 0x8b, 0x79, + 0x8c, 0x08, 0x44, 0xdd, 0x05, 0xea, 0xfb, 0x0f, 0x15, 0x98, 0x83, 0x90, + 0x84, 0x8b, 0x82, 0x8b, 0x79, 0x7d, 0x7e, 0x67, 0x7a, 0x58, 0x74, 0x58, + 0x78, 0x7c, 0x8b, 0x08, 0x77, 0x79, 0x9b, 0x9e, 0xa0, 0xa6, 0xa7, 0xa0, + 0x1f, 0x8d, 0x8b, 0x8f, 0x8a, 0x90, 0x89, 0x9a, 0x85, 0x9b, 0x88, 0x99, + 0x8b, 0xab, 0x8b, 0xa4, 0x97, 0xa1, 0xa4, 0x8d, 0x8e, 0x8b, 0x8b, 0x8d, + 0x8d, 0x08, 0x9f, 0x3f, 0x15, 0x97, 0x97, 0x7e, 0x7e, 0x1f, 0x8b, 0x77, + 0x78, 0x76, 0x6f, 0x80, 0x6b, 0x7d, 0x61, 0x81, 0x76, 0x8b, 0x7c, 0x8b, + 0x7e, 0x96, 0x8b, 0x99, 0x8b, 0x99, 0x90, 0x8f, 0xa7, 0x93, 0x8f, 0x8c, + 0x96, 0x90, 0x9b, 0x92, 0x08, 0xd9, 0xb1, 0x8b, 0x8b, 0x8f, 0x8b, 0x08, + 0x9e, 0x3a, 0x15, 0x92, 0x8a, 0x96, 0x79, 0x8b, 0x80, 0x08, 0x74, 0x4c, + 0x6d, 0x5d, 0x72, 0x79, 0x97, 0x9b, 0x1e, 0x8b, 0x93, 0x8e, 0x8d, 0x9a, + 0x8e, 0x96, 0x8e, 0x97, 0x8e, 0x96, 0x8d, 0x98, 0x8e, 0x93, 0x8e, 0x8c, + 0x8b, 0xb2, 0x9d, 0x91, 0x8e, 0x91, 0x8e, 0x08, 0x8f, 0x8e, 0x8e, 0x8c, + 0x8d, 0x8b, 0x08, 0x0e, 0xfb, 0xb6, 0xe8, 0xf7, 0xb8, 0x15, 0x83, 0x8c, + 0x7f, 0x87, 0x80, 0x84, 0x75, 0x7e, 0x80, 0x76, 0x8b, 0x72, 0x8b, 0x5f, + 0xa0, 0x4e, 0xab, 0x5d, 0xb0, 0x56, 0xca, 0x6e, 0xda, 0x8b, 0xd8, 0x8b, + 0xdf, 0xb5, 0xb7, 0xc7, 0xa8, 0xb4, 0xa0, 0xd0, 0x8b, 0xc6, 0x08, 0x8b, + 0xb2, 0x85, 0xaf, 0x7e, 0xa9, 0x84, 0x9d, 0x84, 0x90, 0x72, 0x91, 0x87, + 0x8c, 0x82, 0x8e, 0x81, 0x8e, 0x08, 0xc0, 0xf7, 0x29, 0x97, 0xb5, 0x8b, + 0xb1, 0x8b, 0xad, 0x75, 0xa6, 0x6f, 0x8b, 0x81, 0x8b, 0x80, 0x86, 0x82, + 0x84, 0x72, 0x76, 0x7d, 0x72, 0x71, 0x43, 0x08, 0x60, 0xfb, 0x05, 0x05, + 0x7f, 0xa8, 0x83, 0xa0, 0x7d, 0xb6, 0x08, 0x62, 0xf7, 0x0f, 0x72, 0xb4, + 0x68, 0x8b, 0x6d, 0x8b, 0x6e, 0x6d, 0x8b, 0x6c, 0x8b, 0x77, 0x9d, 0x47, + 0x9e, 0x57, 0x9d, 0x5c, 0x96, 0x6c, 0x8e, 0x81, 0x8b, 0x8a, 0x8d, 0x85, + 0x8d, 0x83, 0x7c, 0x92, 0x7f, 0x8e, 0x83, 0x8b, 0x08, 0x6e, 0x62, 0x63, + 0x6e, 0x1f, 0x8b, 0x7d, 0x8e, 0x79, 0x90, 0x78, 0x08, 0x8a, 0x06, 0xf7, + 0xea, 0xd5, 0x15, 0x91, 0x8a, 0x93, 0x88, 0x93, 0x85, 0x9e, 0x7d, 0x94, + 0x71, 0x8b, 0x62, 0x8b, 0xfb, 0x26, 0x2c, 0x25, 0xfb, 0x1b, 0x8b, 0x5a, + 0x8b, 0x5b, 0x99, 0x73, 0x9f, 0x7f, 0x96, 0x68, 0xc0, 0x85, 0x9c, 0x74, + 0xd2, 0x8b, 0x8b, 0x8b, 0x90, 0x08, 0x9d, 0xa5, 0xa5, 0x9d, 0x1e, 0x9b, + 0x8b, 0x90, 0x86, 0xad, 0x57, 0xb0, 0x55, 0x8b, 0x8b, 0x8b, 0x85, 0x8b, + 0x81, 0x7a, 0x7f, 0x7d, 0x8b, 0x75, 0x8b, 0x61, 0xb5, 0x7e, 0xad, 0x08, + 0x83, 0x75, 0x06, 0x98, 0x72, 0x98, 0x77, 0x95, 0x82, 0x9f, 0x79, 0xa5, + 0x7f, 0x9d, 0x8b, 0x94, 0x8b, 0x9a, 0x91, 0x94, 0x92, 0x95, 0x93, 0x8f, + 0x93, 0x8b, 0x9b, 0x8b, 0x8f, 0x8b, 0x92, 0x8a, 0x92, 0x08, 0xa1, 0x06, + 0x90, 0x5a, 0x90, 0x81, 0xab, 0x6b, 0x08, 0x95, 0x94, 0x05, 0x8a, 0x91, + 0x8a, 0x90, 0x8a, 0x8c, 0x83, 0xa9, 0x86, 0x9f, 0x8b, 0x92, 0x8b, 0xa0, + 0xa8, 0xbc, 0xa8, 0xa8, 0xa4, 0xa4, 0x9c, 0x93, 0xb1, 0x92, 0x08, 0xa6, + 0x81, 0x07, 0x85, 0x8b, 0x86, 0x8b, 0x85, 0x8a, 0x72, 0x89, 0x7c, 0x89, + 0x8a, 0x8b, 0x7d, 0x8b, 0x5a, 0x98, 0x7b, 0x92, 0x79, 0x94, 0x7a, 0xa3, + 0x8b, 0x9a, 0x8b, 0x93, 0x8e, 0x95, 0x90, 0x97, 0x9d, 0x85, 0x97, 0x88, + 0x8f, 0x8a, 0x08, 0xf7, 0x2f, 0x71, 0x05, 0xfb, 0x2c, 0xc6, 0x15, 0x7c, + 0x8e, 0x80, 0x8c, 0x83, 0x8b, 0x85, 0x8b, 0x80, 0x8a, 0x7e, 0x88, 0x86, + 0x94, 0x8b, 0x8b, 0x7d, 0xb2, 0x60, 0xf7, 0x07, 0x85, 0xa1, 0x8b, 0xab, + 0x8b, 0x9a, 0x95, 0x98, 0x97, 0x8b, 0x97, 0x8b, 0x94, 0x84, 0x93, 0x79, + 0x08, 0x98, 0x74, 0xb3, 0xfb, 0x04, 0xa7, 0x36, 0x08, 0xc4, 0x16, 0xd9, + 0xf7, 0x74, 0x8f, 0x95, 0xa3, 0x8b, 0x96, 0x8b, 0x96, 0x7f, 0x8b, 0x7e, + 0x8b, 0x75, 0x63, 0xfb, 0x16, 0x6f, 0x46, 0x08, 0x4f, 0x97, 0x05, 0xfb, + 0x53, 0x58, 0x15, 0xa0, 0x86, 0x94, 0x85, 0x94, 0x7d, 0xb3, 0x4c, 0xaa, + 0x4e, 0x8b, 0x7c, 0x8b, 0x81, 0x80, 0x81, 0x7f, 0x8b, 0x7f, 0x8b, 0x79, + 0x96, 0x7e, 0x99, 0x08, 0x66, 0xb5, 0x66, 0xc7, 0x8b, 0xa0, 0x8b, 0x95, + 0x93, 0x95, 0xa1, 0x9b, 0x08, 0xf7, 0x1d, 0xfb, 0x1f, 0x15, 0x74, 0xc2, + 0x05, 0xa5, 0x83, 0x96, 0x89, 0xaa, 0x88, 0x08, 0x5e, 0x61, 0x05, 0x0e, + 0x9b, 0xdd, 0xf7, 0x5e, 0x15, 0x97, 0x7a, 0x53, 0xfb, 0x03, 0x05, 0x88, + 0x84, 0x89, 0x87, 0x8b, 0x8b, 0x8b, 0x89, 0x8e, 0x89, 0x8d, 0x8b, 0x8d, + 0x8b, 0x90, 0x8c, 0x8e, 0x8c, 0x08, 0xe4, 0xac, 0xbf, 0xc3, 0x05, 0xc7, + 0x7b, 0xa6, 0x86, 0xad, 0x8b, 0x9c, 0x8b, 0xac, 0x8d, 0xd8, 0x92, 0x08, + 0xf3, 0x80, 0xe7, 0xa2, 0x98, 0x53, 0xf7, 0x2b, 0x8b, 0xa2, 0xf7, 0x22, + 0x8b, 0xf2, 0x74, 0xd2, 0xfb, 0x2b, 0x94, 0x7e, 0x77, 0x05, 0x6d, 0x8d, + 0x7f, 0x8e, 0x75, 0x9a, 0x08, 0x2e, 0xc6, 0xd5, 0xdf, 0x05, 0x90, 0x91, + 0x8d, 0x90, 0x8b, 0x92, 0x8b, 0xa6, 0x77, 0xa4, 0x75, 0x8b, 0x83, 0x8b, + 0x83, 0x87, 0x86, 0x86, 0x08, 0x36, 0x2b, 0x4e, 0xae, 0x05, 0x4a, 0x6e, + 0x66, 0x70, 0x2f, 0x34, 0x74, 0x48, 0x87, 0x7d, 0x81, 0x5d, 0x08, 0x68, + 0x31, 0x05, 0xf8, 0xc5, 0xf7, 0x44, 0x15, 0x95, 0x57, 0x8e, 0x72, 0x8b, + 0x6c, 0x8b, 0x71, 0x89, 0x75, 0x83, 0x5e, 0x50, 0x79, 0x71, 0x86, 0x70, + 0x8b, 0x7a, 0x8b, 0x81, 0x8c, 0x4f, 0x95, 0x6d, 0x88, 0x71, 0x87, 0x81, + 0x88, 0x74, 0x86, 0x7a, 0x88, 0x81, 0x8b, 0x08, 0x7f, 0x8c, 0x05, 0x80, + 0x8d, 0x80, 0x8c, 0x81, 0x8d, 0x7e, 0x8c, 0x83, 0x8e, 0x8c, 0x8f, 0x8b, + 0x8c, 0x8d, 0x8d, 0x8d, 0x8d, 0x96, 0x93, 0x91, 0x94, 0x8b, 0x94, 0x8b, + 0x91, 0x85, 0x99, 0x86, 0x91, 0x88, 0x8f, 0x78, 0x95, 0x87, 0x8b, 0x08, + 0x8a, 0x8b, 0x8a, 0x8b, 0x8a, 0x8a, 0x08, 0x8a, 0x8a, 0x05, 0x8a, 0x8b, + 0x8a, 0x8b, 0x1f, 0x8c, 0x06, 0x8c, 0x8b, 0x8b, 0x8a, 0x8c, 0x8a, 0x8b, + 0x8a, 0x8d, 0x88, 0x8e, 0x87, 0x90, 0x85, 0x90, 0x79, 0x8b, 0x81, 0x08, + 0x80, 0x83, 0x80, 0x84, 0x1e, 0x7d, 0x8d, 0x76, 0x8b, 0x05, 0x7d, 0x82, + 0x94, 0x99, 0x1f, 0x8b, 0x9e, 0x96, 0x9d, 0x9b, 0x93, 0x08, 0xa7, 0x98, + 0x05, 0xa1, 0x98, 0x8f, 0x8c, 0x9e, 0x8b, 0x08, 0xf7, 0x10, 0x06, 0xa0, + 0x9e, 0x8f, 0x90, 0x92, 0x9c, 0x62, 0x7a, 0x75, 0x84, 0x77, 0x8b, 0x89, + 0x8b, 0x86, 0x8b, 0x85, 0x8c, 0x08, 0xba, 0xc0, 0x05, 0x8b, 0x95, 0x8d, + 0x94, 0x8c, 0x8e, 0x8c, 0x92, 0x8c, 0x90, 0x8b, 0x8e, 0x8b, 0x8e, 0x89, + 0x91, 0x88, 0x95, 0x08, 0xc6, 0xd1, 0xf7, 0x0c, 0x45, 0xcd, 0x82, 0x05, + 0xfc, 0x30, 0x57, 0x15, 0x70, 0x49, 0x05, 0x85, 0x7d, 0x78, 0x74, 0x72, + 0x76, 0x08, 0x7a, 0x8b, 0xa5, 0xc5, 0x82, 0xa7, 0x7a, 0x95, 0xa5, 0xe4, + 0x05, 0x90, 0x97, 0x8b, 0x8c, 0xa0, 0x9e, 0x08, 0xd6, 0xcd, 0x05, 0xa1, + 0x9f, 0xc0, 0xaa, 0x97, 0x8b, 0x93, 0x8b, 0x94, 0x85, 0xa8, 0x74, 0x08, + 0xfb, 0x3a, 0xfb, 0x49, 0x05, 0xfb, 0x26, 0xfb, 0x87, 0x15, 0x87, 0x8a, + 0x88, 0x8a, 0x89, 0x8b, 0x83, 0x8b, 0x86, 0x90, 0x8b, 0x92, 0x8b, 0x8f, + 0x8d, 0x94, 0x8d, 0x8d, 0x08, 0x99, 0xa6, 0x05, 0x95, 0x9b, 0x8c, 0x8c, + 0x8f, 0x8b, 0x94, 0x8b, 0xa1, 0x6b, 0x8b, 0x7e, 0x8b, 0x85, 0x87, 0x87, + 0x83, 0x88, 0x08, 0x6d, 0x80, 0x05, 0xbf, 0xf7, 0x61, 0x15, 0x91, 0x83, + 0x8d, 0x86, 0x8b, 0x7f, 0x8b, 0x68, 0x7c, 0x70, 0x77, 0x8b, 0x88, 0x8b, + 0x87, 0x8b, 0x86, 0x8c, 0x08, 0xb2, 0xe1, 0x05, 0xf7, 0x88, 0xde, 0x15, + 0x5e, 0x6e, 0x58, 0x71, 0x1e, 0x85, 0x8b, 0x82, 0x8c, 0x82, 0x8d, 0x08, + 0xda, 0xe8, 0x05, 0xf8, 0x0c, 0x9b, 0x15, 0x9d, 0x61, 0x91, 0x67, 0x8b, + 0x53, 0x8b, 0x5b, 0x87, 0x6a, 0x7e, 0x5e, 0x08, 0x22, 0x82, 0x05, 0x9a, + 0xc1, 0x92, 0xbd, 0x8b, 0xbd, 0x8b, 0xa5, 0x89, 0x9d, 0x81, 0xd2, 0x08, + 0xe3, 0x06, 0x0e, 0xd3, 0xf7, 0x56, 0xf8, 0xbe, 0x15, 0x6b, 0x63, 0x58, + 0x61, 0x78, 0x99, 0x7a, 0x9c, 0xaa, 0xb1, 0xbe, 0xb5, 0x9f, 0x7f, 0x9b, + 0x7b, 0x1f, 0xd2, 0xe2, 0x15, 0xfb, 0x29, 0x72, 0x3a, 0xfb, 0x1c, 0xb4, + 0xfb, 0x2e, 0xf8, 0x46, 0xfb, 0x99, 0x05, 0x99, 0x83, 0xa0, 0x85, 0x9d, + 0x8b, 0x08, 0xf7, 0xa9, 0x06, 0xa3, 0x97, 0x93, 0x9b, 0x1f, 0x8b, 0x91, + 0x8a, 0x8e, 0x85, 0x96, 0x08, 0xfb, 0x23, 0xf7, 0x8f, 0x05, 0x80, 0x9f, + 0x86, 0x90, 0x7b, 0x94, 0x08, 0x81, 0x91, 0xfc, 0x37, 0xf7, 0x93, 0x05, + 0x83, 0x73, 0x15, 0xad, 0xfb, 0x0b, 0x42, 0xfb, 0x10, 0xfb, 0x0d, 0x71, + 0x6a, 0xf7, 0x16, 0xd0, 0xf7, 0x08, 0xf7, 0x10, 0xa2, 0x05, 0xf8, 0xad, + 0xfc, 0x4b, 0x15, 0xa1, 0x6a, 0x8b, 0x8a, 0x8b, 0x82, 0x8b, 0x7f, 0x7c, + 0x72, 0x7e, 0x7f, 0x84, 0x84, 0x7d, 0x87, 0x7c, 0x8b, 0x08, 0xfb, 0x49, + 0x06, 0xe9, 0xca, 0xb3, 0xd0, 0x93, 0xf7, 0x01, 0x08, 0xdc, 0xfb, 0x1e, + 0x05, 0xfc, 0x8c, 0xf8, 0x39, 0x15, 0xf8, 0x1e, 0xfb, 0x84, 0x05, 0x8e, + 0x79, 0x8c, 0x82, 0x8b, 0x7e, 0x8b, 0x7d, 0x8a, 0x81, 0x88, 0x77, 0x08, + 0xfc, 0x02, 0xf7, 0x6f, 0x6f, 0xf4, 0x05, 0x9b, 0xfb, 0x11, 0x15, 0xf8, + 0x05, 0xfb, 0x73, 0x05, 0x87, 0x70, 0x67, 0x4f, 0x74, 0x79, 0x08, 0xfc, + 0x05, 0xf7, 0x74, 0xca, 0xf3, 0x05, 0x40, 0xfb, 0x11, 0x15, 0xf8, 0x01, + 0xfb, 0x70, 0x05, 0x7b, 0x78, 0x6a, 0x6e, 0x7e, 0x85, 0x08, 0xfc, 0x32, + 0xf7, 0x91, 0xf7, 0x03, 0xa0, 0x05, 0x0e, 0xe9, 0xf7, 0x25, 0xf8, 0x3c, + 0x15, 0x72, 0x7d, 0x6f, 0x59, 0x58, 0x99, 0x6f, 0xa4, 0xa4, 0x99, 0xa7, + 0xbe, 0xbd, 0x7d, 0xa7, 0x72, 0x1f, 0x82, 0xfb, 0xaf, 0x15, 0xf8, 0x61, + 0x06, 0x9d, 0x8c, 0x8d, 0x8b, 0x8e, 0x8b, 0x94, 0x8c, 0x8b, 0x8c, 0x99, + 0x95, 0x08, 0xf7, 0x75, 0xf7, 0x31, 0x05, 0xa9, 0x9f, 0x8c, 0x8d, 0x8b, + 0x98, 0x8b, 0x97, 0x8a, 0x8d, 0x6d, 0x9f, 0x08, 0xfb, 0x75, 0xf7, 0x31, + 0x05, 0x88, 0x8d, 0x88, 0x8d, 0x88, 0x8e, 0x87, 0x8e, 0x86, 0x8d, 0x86, + 0x8b, 0x08, 0x74, 0x8c, 0xfc, 0x61, 0x8b, 0x26, 0xfb, 0x0b, 0x8b, 0xfb, + 0x40, 0xf0, 0xfb, 0x0a, 0x05, 0xe6, 0xf7, 0x13, 0x15, 0x39, 0x28, 0x39, + 0xea, 0x8b, 0xf7, 0x36, 0xdd, 0xea, 0xdd, 0x29, 0x8b, 0xfb, 0x2f, 0x05, + 0xf8, 0x38, 0x3f, 0x15, 0xa6, 0xc7, 0x98, 0xbc, 0x8b, 0xb8, 0x8b, 0xb7, + 0x7f, 0xba, 0x6f, 0xc8, 0x08, 0xf7, 0x33, 0xfb, 0x01, 0x05, 0x91, 0x7a, + 0x8d, 0x82, 0x8b, 0x79, 0x8b, 0x7a, 0x89, 0x81, 0x85, 0x7b, 0x08, 0xfb, + 0x33, 0xfb, 0x02, 0x05, 0x5c, 0xf7, 0xdb, 0x15, 0x97, 0x78, 0x97, 0x6f, + 0x96, 0x6a, 0x08, 0xfc, 0x14, 0x8b, 0x49, 0xdb, 0xf8, 0x33, 0x8b, 0x05, + 0xfb, 0xed, 0xfb, 0x85, 0x15, 0xf7, 0x17, 0xf8, 0x18, 0x07, 0x90, 0x79, + 0x8d, 0x7c, 0x8b, 0x6a, 0x8b, 0x6b, 0x89, 0x7c, 0x86, 0x79, 0x08, 0xfc, + 0x18, 0x06, 0xf8, 0x15, 0x6c, 0x15, 0x7b, 0x60, 0x86, 0x7f, 0x81, 0x76, + 0x08, 0xfc, 0x42, 0x8b, 0xcf, 0xd7, 0xf8, 0x1d, 0x8b, 0x05, 0x0e, 0xd3, + 0xf7, 0x2d, 0xf7, 0x9c, 0x15, 0x7a, 0x7d, 0x7b, 0x78, 0x61, 0xb2, 0x58, + 0xac, 0x9b, 0x97, 0x9a, 0xa0, 0xb5, 0x66, 0xbd, 0x6b, 0x1f, 0xf7, 0x04, + 0xfb, 0x6b, 0x15, 0xf8, 0x37, 0xf7, 0x92, 0x05, 0x8c, 0x8c, 0x90, 0x8d, + 0x8f, 0x8e, 0x9c, 0x94, 0x8f, 0x8f, 0x96, 0xa0, 0x08, 0xf7, 0x22, 0xf7, + 0x8d, 0x05, 0x91, 0x95, 0x8d, 0x90, 0x8b, 0x90, 0x08, 0x9b, 0x7f, 0x93, + 0x73, 0x1e, 0xfb, 0xa9, 0x06, 0x79, 0x8b, 0x77, 0x86, 0x7c, 0x82, 0x08, + 0xfc, 0x46, 0xfb, 0x97, 0x62, 0xfb, 0x2e, 0xdc, 0xfb, 0x1b, 0xf7, 0x29, + 0x72, 0x05, 0x83, 0xa4, 0x15, 0xfb, 0x10, 0xa2, 0x46, 0xf7, 0x06, 0xac, + 0xf7, 0x16, 0xf7, 0x0d, 0x71, 0xd4, 0xfb, 0x0f, 0x69, 0xfb, 0x0a, 0x05, + 0xf8, 0x5c, 0xf7, 0xbf, 0x15, 0x83, 0xf7, 0x00, 0x63, 0xcf, 0x2d, 0xca, + 0x08, 0xf7, 0x49, 0x06, 0x96, 0x8b, 0x9c, 0x87, 0x8f, 0x87, 0x9b, 0x7f, + 0x9b, 0x70, 0x8b, 0x7f, 0x8b, 0x81, 0x8a, 0x8a, 0x76, 0x6b, 0x08, 0x3a, + 0xfb, 0x1d, 0x05, 0xfc, 0x3b, 0xfb, 0xae, 0x15, 0xa7, 0xf3, 0xf8, 0x02, + 0xf7, 0x6e, 0x05, 0x8e, 0x77, 0x8c, 0x82, 0x8b, 0x7c, 0x8b, 0x7e, 0x8a, + 0x82, 0x88, 0x7a, 0x08, 0xfc, 0x1e, 0xfb, 0x83, 0x05, 0x9b, 0xf7, 0x10, + 0x15, 0x4c, 0xf3, 0xf8, 0x05, 0xf7, 0x72, 0x05, 0xa2, 0x7a, 0xaf, 0x4f, + 0x8e, 0x70, 0x08, 0xfc, 0x04, 0xfb, 0x72, 0x05, 0x40, 0xf7, 0x10, 0x15, + 0xfb, 0x03, 0xa1, 0xf8, 0x32, 0xf7, 0x8f, 0x05, 0x98, 0x85, 0xab, 0x6f, + 0x9b, 0x78, 0x08, 0xfc, 0x00, 0xfb, 0x70, 0x05, 0x0e, 0xf5, 0xf7, 0x3b, + 0xf8, 0x83, 0x15, 0x3e, 0x54, 0x4b, 0x31, 0x1f, 0x8b, 0x51, 0xa5, 0x59, + 0xb7, 0x71, 0x9c, 0x80, 0x96, 0x89, 0xa6, 0x8b, 0x08, 0xf7, 0x33, 0x06, + 0x97, 0xb6, 0xa4, 0xa2, 0xac, 0x8b, 0xa2, 0x8b, 0x9e, 0x7d, 0xa0, 0x69, + 0xb2, 0x4e, 0x99, 0x7f, 0xb0, 0x8b, 0xb8, 0x8b, 0xc8, 0xa6, 0xf7, 0x02, + 0xce, 0xd0, 0xb5, 0xb4, 0xa9, 0xb4, 0xb1, 0x42, 0xc8, 0x7f, 0x95, 0x61, + 0xa5, 0x08, 0xfb, 0x17, 0xdd, 0x4e, 0xa7, 0x5e, 0x8b, 0x66, 0x8b, 0x74, + 0x7a, 0x75, 0x5f, 0x73, 0x5d, 0x72, 0x74, 0x6f, 0x8b, 0x6c, 0x8b, 0x74, + 0xa5, 0x7e, 0xbc, 0x08, 0xfb, 0x2c, 0x06, 0xf8, 0xcd, 0xfb, 0x20, 0x15, + 0x2c, 0x06, 0x7e, 0xba, 0x77, 0xa2, 0x6c, 0x8b, 0x08, 0x65, 0x6c, 0x65, + 0x5c, 0x5e, 0xa9, 0x66, 0xaf, 0x1f, 0xab, 0x8b, 0xa1, 0xa3, 0x98, 0xbc, + 0x08, 0xea, 0x43, 0x06, 0x57, 0x63, 0x26, 0x5b, 0x6b, 0x8b, 0x70, 0x8b, + 0x78, 0x99, 0x75, 0xae, 0x69, 0xc2, 0x76, 0x9c, 0x65, 0x8b, 0x61, 0x8b, + 0x67, 0x72, 0x7d, 0x63, 0x08, 0xfb, 0x1f, 0x06, 0x5c, 0x5f, 0xc3, 0xc7, + 0xcd, 0xb7, 0xc0, 0xc2, 0x1f, 0xf7, 0x17, 0x06, 0x9e, 0x5a, 0xaa, 0x72, + 0xb3, 0x8b, 0xb0, 0x8b, 0xa3, 0x9e, 0xab, 0xc1, 0xa5, 0xb7, 0x9b, 0x98, + 0xaa, 0x8b, 0xa1, 0x8b, 0x9b, 0x85, 0xbb, 0x71, 0xbc, 0x72, 0xa2, 0x7d, + 0xa3, 0x7a, 0x08, 0x40, 0x07, 0x0e, 0xf7, 0x1b, 0xfa, 0x3e, 0xf7, 0xee, + 0x15, 0x88, 0x8c, 0x89, 0x8c, 0x89, 0x8b, 0x3c, 0x9c, 0x53, 0xb7, 0x46, + 0xed, 0x61, 0xc4, 0x69, 0xa3, 0x61, 0x8b, 0x73, 0x8b, 0x70, 0x7f, 0x77, + 0x78, 0x71, 0x72, 0x85, 0x7e, 0x7a, 0x4e, 0x7c, 0x57, 0x7f, 0x7e, 0x69, + 0x8b, 0x08, 0x73, 0x8b, 0x7e, 0x94, 0x7b, 0xa7, 0x6b, 0xc3, 0x8b, 0x8b, + 0xfb, 0x37, 0x8b, 0x50, 0x8b, 0x79, 0x88, 0x78, 0x7f, 0x6b, 0x77, 0x7a, + 0x5e, 0x8b, 0x4c, 0x8b, 0x49, 0xa0, 0x5a, 0xae, 0x7c, 0x9e, 0x83, 0x9b, + 0x89, 0xca, 0x8b, 0x08, 0xf7, 0x2c, 0x8b, 0x8b, 0x8b, 0xb3, 0xcb, 0x99, + 0xa0, 0x95, 0x91, 0xa1, 0x8b, 0xac, 0x8b, 0x9a, 0x7c, 0x98, 0x5d, 0x9b, + 0x51, 0x8b, 0x8b, 0x93, 0x7e, 0xa1, 0x66, 0xb0, 0x75, 0xb1, 0x8b, 0xb7, + 0x8b, 0xac, 0xa2, 0xb6, 0xc7, 0x08, 0xd4, 0xf3, 0xba, 0xaf, 0xe4, 0x9f, + 0x08, 0xfb, 0x94, 0x9b, 0x15, 0xf7, 0x1c, 0x87, 0xb9, 0x87, 0x8b, 0x83, + 0x8b, 0x84, 0x63, 0x86, 0x45, 0x89, 0x08, 0x43, 0x89, 0x7f, 0x8a, 0x05, + 0x7d, 0x68, 0x75, 0x78, 0x6f, 0x8b, 0x08, 0x68, 0x70, 0xaa, 0xb2, 0xb2, + 0xa7, 0xab, 0xad, 0x1f, 0xa7, 0x8b, 0xa1, 0x78, 0x99, 0x68, 0x08, 0x97, + 0x06, 0x0e, 0x37, 0xf9, 0x65, 0xf9, 0x55, 0x15, 0x53, 0x8c, 0x48, 0x77, + 0x62, 0x6e, 0x3e, 0x3e, 0xfb, 0x25, 0xfb, 0x5e, 0x23, 0xfb, 0x44, 0x7e, + 0x74, 0x85, 0x84, 0x85, 0x8b, 0x85, 0x8b, 0x84, 0x93, 0x84, 0x9c, 0x08, + 0x6e, 0xd2, 0x05, 0x85, 0x9a, 0x86, 0x90, 0x7f, 0x8b, 0x75, 0x8b, 0x6b, + 0x7d, 0x6f, 0x76, 0x7e, 0x81, 0x86, 0x82, 0x8b, 0x7e, 0x8b, 0x62, 0xad, + 0x24, 0xb1, 0x42, 0x93, 0x7b, 0x91, 0x89, 0xb4, 0x8b, 0xbd, 0x8b, 0x97, + 0x8f, 0x96, 0x9f, 0x08, 0xf7, 0x00, 0xf7, 0x5d, 0xf7, 0x7a, 0xf7, 0xd4, + 0xf7, 0x29, 0xf7, 0x32, 0x08, 0x9b, 0x07, 0x0e, 0x92, 0xf9, 0xbf, 0xf9, + 0x3b, 0x15, 0xa1, 0x85, 0x90, 0x74, 0x1e, 0x78, 0x8b, 0x83, 0x88, 0x7a, + 0x7e, 0x39, 0x4a, 0x5c, 0x61, 0x31, 0x2e, 0x4d, 0x4a, 0x5f, 0x60, 0x76, + 0x77, 0x55, 0x58, 0x6c, 0x6e, 0x82, 0x82, 0x83, 0x83, 0x82, 0x86, 0x85, + 0x8b, 0x89, 0x8b, 0x83, 0x8e, 0x84, 0x90, 0x08, 0x7f, 0x92, 0x87, 0x93, + 0x88, 0xa1, 0x85, 0xb4, 0x86, 0xa6, 0x89, 0x96, 0x86, 0xa7, 0x87, 0xa9, + 0x8c, 0x8d, 0x8b, 0x9f, 0x88, 0x90, 0x7d, 0x94, 0x83, 0x91, 0x81, 0x8e, + 0x82, 0x8b, 0x7d, 0x8b, 0x72, 0x87, 0x7e, 0x86, 0x08, 0x7b, 0x85, 0x84, + 0x85, 0x6b, 0x64, 0x72, 0x6c, 0x8b, 0x8b, 0x8a, 0x80, 0x8a, 0x82, 0x87, + 0x50, 0x8b, 0x81, 0x8b, 0x74, 0x8d, 0x71, 0x90, 0x6b, 0x92, 0x52, 0x93, + 0x4c, 0x89, 0x89, 0x8d, 0x73, 0x8d, 0x84, 0x95, 0x80, 0x08, 0x9a, 0x7a, + 0x9e, 0x7b, 0x9f, 0x7d, 0xac, 0x74, 0x99, 0x85, 0xa1, 0x8b, 0x9d, 0x8b, + 0x9c, 0x96, 0xb5, 0xaf, 0xf0, 0xe2, 0xf7, 0x5f, 0xf7, 0x5c, 0xcf, 0xd8, + 0xd6, 0xe2, 0xbe, 0xc4, 0x9b, 0x99, 0x9a, 0x9a, 0x95, 0x95, 0x8c, 0x90, + 0x08, 0x8c, 0xdd, 0x8b, 0x97, 0x05, 0x0e, 0x3e, 0xf9, 0x6b, 0xf9, 0x0d, + 0x15, 0x50, 0xc6, 0xfb, 0xb3, 0xfb, 0xb4, 0xfb, 0xb3, 0xf7, 0xb4, 0x50, + 0x50, 0xf7, 0xb4, 0xfb, 0xb2, 0xfb, 0xb4, 0xfb, 0xb4, 0xc6, 0x50, 0xf7, + 0xb3, 0xf7, 0xb5, 0xf7, 0xb3, 0xfb, 0xb5, 0xc6, 0xc6, 0xfb, 0xb4, 0xf7, + 0xb4, 0xf7, 0xb4, 0xf7, 0xb2, 0x05, 0x0e, 0x3d, 0xf9, 0x6b, 0xf8, 0x9a, + 0x15, 0xfb, 0x42, 0xf7, 0x42, 0xfb, 0x40, 0xfb, 0x42, 0xfb, 0x40, 0xf7, + 0x42, 0xfb, 0x42, 0xfb, 0x42, 0xf7, 0x42, 0xfb, 0x3f, 0xfb, 0x42, 0xfb, + 0x41, 0xf7, 0x42, 0xfb, 0x42, 0xf7, 0x40, 0xf7, 0x42, 0xf7, 0x40, 0xfb, + 0x42, 0xf7, 0x42, 0xf7, 0x42, 0xfb, 0x42, 0xf7, 0x41, 0xf7, 0x42, 0xf7, + 0x3f, 0x05, 0x0e, 0xfb, 0xa0, 0xf8, 0x0a, 0xf8, 0x03, 0x15, 0xba, 0xcc, + 0xea, 0xf7, 0x10, 0x9d, 0x9f, 0x94, 0x96, 0x93, 0x95, 0x94, 0x95, 0x8f, + 0x90, 0x8f, 0x8f, 0x8c, 0x8d, 0x8d, 0x8c, 0x8c, 0x8d, 0x8b, 0x8c, 0x8b, + 0x8c, 0x85, 0x95, 0x89, 0x8d, 0x08, 0x82, 0x95, 0x05, 0x8b, 0x8c, 0x89, + 0x8e, 0x89, 0x8e, 0x87, 0x91, 0x8a, 0x8d, 0x8a, 0x8b, 0x08, 0x8a, 0x06, + 0x8a, 0x8b, 0x89, 0x89, 0x8a, 0x8a, 0x87, 0x87, 0x88, 0x88, 0x88, 0x87, + 0x8a, 0x8a, 0x89, 0x89, 0x87, 0x88, 0x7e, 0x95, 0x7a, 0x95, 0x86, 0x8b, + 0x87, 0x8b, 0x89, 0x89, 0x68, 0x64, 0x08, 0xfb, 0x15, 0xfb, 0x2c, 0x05, + 0x86, 0x97, 0x8b, 0x8b, 0x83, 0x9a, 0x08, 0x5f, 0xe0, 0x05, 0x6f, 0xc4, + 0x8b, 0x8b, 0x83, 0x8b, 0x88, 0x8b, 0x87, 0x89, 0x8a, 0x8a, 0x89, 0x88, + 0x89, 0x88, 0x89, 0x89, 0x08, 0x84, 0x84, 0x05, 0x87, 0x8c, 0x89, 0x8b, + 0x89, 0x8b, 0x89, 0x8b, 0x89, 0x8b, 0x87, 0x8a, 0x84, 0x90, 0x87, 0x8d, + 0x87, 0x8b, 0x81, 0x8b, 0x79, 0x75, 0x8b, 0x7f, 0x8b, 0x8a, 0x8e, 0x83, + 0x8f, 0x81, 0x08, 0xab, 0x2e, 0xae, 0x2d, 0x05, 0x8c, 0x87, 0x8f, 0x81, + 0x90, 0x7c, 0xfb, 0x0f, 0xfb, 0x2a, 0x66, 0x5b, 0x79, 0x6b, 0x78, 0x69, + 0x7e, 0x74, 0x87, 0x86, 0x81, 0x7e, 0x85, 0x81, 0x8b, 0x85, 0x8b, 0x8a, + 0x8e, 0x84, 0x8f, 0x81, 0x8c, 0x88, 0x8c, 0x88, 0x8b, 0x8a, 0x08, 0x8b, + 0x89, 0x89, 0x84, 0x88, 0x81, 0x8a, 0x88, 0x8a, 0x89, 0x8b, 0x89, 0x8b, + 0x83, 0x8b, 0x8b, 0xa1, 0x68, 0x90, 0x82, 0x8d, 0x8a, 0x93, 0x8b, 0x9d, + 0x8b, 0xa3, 0x90, 0x95, 0x92, 0xba, 0xdc, 0xdb, 0xf7, 0x11, 0xd2, 0xf0, + 0x08, 0xac, 0x52, 0x8b, 0x8b, 0xce, 0x28, 0x9e, 0x70, 0x90, 0x85, 0x93, + 0x8b, 0x97, 0x8b, 0x9f, 0x9b, 0x8b, 0x94, 0x8b, 0x8d, 0x8a, 0x8e, 0x89, + 0x8f, 0x8a, 0x8c, 0x8b, 0x8d, 0x8b, 0x8c, 0x8b, 0x8d, 0x8e, 0x8e, 0x92, + 0x90, 0x08, 0x95, 0x93, 0x8b, 0x92, 0x05, 0x93, 0x8f, 0x8e, 0x8e, 0x8e, + 0x92, 0x08, 0x88, 0x95, 0x05, 0x87, 0x93, 0x8b, 0x8c, 0x7e, 0xa6, 0x08, + 0x4c, 0xf7, 0x19, 0x72, 0xbd, 0x05, 0x0e, 0xfb, 0x36, 0xf9, 0x07, 0xf9, + 0x14, 0x15, 0x85, 0x94, 0x7c, 0x87, 0x05, 0x79, 0x98, 0x8b, 0x8b, 0x8b, + 0x8e, 0x8b, 0x8c, 0x8c, 0x8d, 0x8c, 0x8c, 0x8d, 0x8e, 0x8c, 0x8e, 0x8b, + 0x8c, 0x8b, 0x8f, 0x6a, 0xa8, 0x88, 0x8b, 0x83, 0x8b, 0xfb, 0x1b, 0xfb, + 0x1c, 0x30, 0x27, 0x5d, 0xcb, 0x75, 0xac, 0x56, 0xe1, 0x08, 0x83, 0x94, + 0x85, 0x8f, 0x86, 0x8b, 0x7e, 0x8b, 0x81, 0x80, 0x89, 0x79, 0x8a, 0x83, + 0x85, 0x84, 0x85, 0x8b, 0x89, 0x8b, 0x88, 0x8d, 0x88, 0x90, 0x88, 0x8e, + 0x86, 0x8f, 0x84, 0x90, 0x77, 0x78, 0x88, 0x88, 0x7d, 0x75, 0x08, 0x90, + 0x68, 0xcb, 0xfb, 0x23, 0xbb, 0x37, 0x88, 0x88, 0x88, 0x87, 0x89, 0x88, + 0x08, 0xfb, 0x01, 0xfb, 0x12, 0x5a, 0x4c, 0x05, 0x8d, 0x84, 0x8d, 0x86, + 0x8c, 0x88, 0x95, 0x76, 0x8b, 0x8b, 0x8b, 0x89, 0x8b, 0x86, 0x88, 0x84, + 0x87, 0x85, 0x88, 0x87, 0x89, 0x88, 0x8b, 0x89, 0x8b, 0x84, 0xa9, 0x62, + 0x93, 0x87, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8b, 0x08, 0x93, 0x8f, 0x91, + 0x8d, 0x8f, 0x8b, 0x8e, 0x8b, 0x8e, 0x88, 0x8b, 0x88, 0x8b, 0x8a, 0x8a, + 0x89, 0x8a, 0x88, 0x8b, 0x8a, 0x8a, 0x88, 0x8a, 0x87, 0x08, 0x9e, 0x76, + 0x98, 0x8b, 0x05, 0xae, 0xbc, 0xa0, 0xa9, 0x9d, 0xa2, 0x08, 0xd0, 0xe5, + 0x95, 0x99, 0x05, 0x9a, 0x78, 0x8d, 0x88, 0xa7, 0x61, 0xa9, 0x5f, 0x96, + 0x7d, 0xa6, 0x6f, 0x8e, 0x89, 0x8e, 0x8a, 0x8d, 0x8b, 0x90, 0x8b, 0xa0, + 0x9d, 0x97, 0x9a, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8c, 0x8b, 0x8b, + 0x8b, 0x8c, 0x8a, 0x08, 0x8c, 0x8a, 0x8d, 0x8a, 0x8e, 0x89, 0x8e, 0x89, + 0x8e, 0x89, 0x8f, 0x88, 0x8f, 0x87, 0x8e, 0x89, 0x8e, 0x8b, 0x8e, 0x8b, + 0x9b, 0x97, 0x90, 0x91, 0x8e, 0x90, 0x8d, 0x8c, 0x8d, 0x8c, 0x08, 0x88, + 0x96, 0x8b, 0x8c, 0x05, 0x8b, 0x8c, 0x8f, 0x8e, 0x97, 0x95, 0xa6, 0x9f, + 0x90, 0x93, 0x90, 0xa6, 0x7d, 0x97, 0x4d, 0xd7, 0x43, 0xea, 0xc9, 0xd9, + 0xdb, 0xe3, 0xd8, 0xd9, 0x8a, 0x8d, 0x8a, 0x8d, 0x8b, 0x8c, 0x8b, 0x8c, + 0x8c, 0x8e, 0x8e, 0x8d, 0x08, 0x92, 0x94, 0x8c, 0x8c, 0x8d, 0x93, 0x08, + 0x7c, 0xa1, 0x05, 0x0e, 0x3f, 0xf8, 0x40, 0xf9, 0x04, 0x15, 0x2f, 0xfb, + 0x7b, 0xfb, 0x7b, 0x2f, 0xf7, 0x7b, 0xfb, 0x7a, 0xe7, 0xf7, 0x7a, 0xf7, + 0x7a, 0xe7, 0xfb, 0x7a, 0xf7, 0x7b, 0x06, 0xd0, 0xd1, 0x15, 0xfb, 0x7b, + 0xfb, 0x7b, 0xfb, 0x7b, 0xfb, 0x7b, 0xf7, 0x7b, 0xfb, 0x7c, 0xf7, 0x7b, + 0xf7, 0x7c, 0xf7, 0x7b, 0xf7, 0x7b, 0xfb, 0x7b, 0xf7, 0x7b, 0x06, 0x68, + 0x68, 0x15, 0xfb, 0x7b, 0xf7, 0x7b, 0xfb, 0x35, 0xfb, 0x7b, 0xfb, 0x7c, + 0xfb, 0x35, 0xf7, 0x7c, 0xfb, 0x7b, 0xf7, 0x35, 0xf7, 0x7b, 0xf7, 0x7b, + 0xf7, 0x35, 0x07, 0x0e, 0x3c, 0xf8, 0x84, 0xf9, 0x47, 0x15, 0xfb, 0x7b, + 0xfb, 0x7a, 0xfb, 0x7a, 0xfb, 0x7b, 0xf7, 0x7a, 0xfb, 0x7a, 0xf7, 0x7b, + 0xf7, 0x7a, 0xf7, 0x7a, 0xf7, 0x7b, 0xfb, 0x7a, 0xf7, 0x7a, 0x06, 0x0e, + 0x3b, 0xf7, 0xd9, 0x16, 0xf7, 0x02, 0xf7, 0xb6, 0xfb, 0x02, 0xfb, 0xb6, + 0x06, 0xf8, 0x24, 0x04, 0xf7, 0x02, 0xf7, 0xb6, 0xfb, 0x02, 0xfb, 0xb6, + 0x06, 0xfb, 0xb6, 0x16, 0xfb, 0x02, 0xf7, 0xb6, 0xf7, 0x02, 0xfb, 0xb6, + 0x07, 0xf8, 0x24, 0x16, 0xfb, 0x02, 0xf7, 0xb6, 0xf7, 0x02, 0xfb, 0xb6, + 0x07, 0x0e, 0x36, 0xf7, 0xa5, 0x16, 0xf7, 0x65, 0xf7, 0x82, 0xfb, 0x65, + 0xfb, 0x82, 0x06, 0xf8, 0x53, 0x04, 0xf7, 0x65, 0xf7, 0x82, 0xfb, 0x65, + 0xfb, 0x82, 0x06, 0xfb, 0x82, 0x16, 0xfb, 0x65, 0xf7, 0x82, 0xf7, 0x65, + 0xfb, 0x82, 0x07, 0xf8, 0x53, 0x16, 0xfb, 0x65, 0xf7, 0x82, 0xf7, 0x65, + 0xfb, 0x82, 0x07, 0x0e, 0xfb, 0xed, 0xf7, 0x5e, 0xf9, 0x47, 0x15, 0xfb, + 0x49, 0xfb, 0x3b, 0x30, 0xf7, 0x3b, 0xfc, 0x37, 0xe6, 0xf8, 0x37, 0xf7, + 0x3b, 0xe6, 0xfb, 0x3b, 0xf7, 0x49, 0x30, 0x07, 0x0e, 0xfb, 0xb3, 0xf7, + 0x49, 0xf9, 0x47, 0x15, 0xfb, 0x28, 0xfb, 0x26, 0xfb, 0x09, 0x07, 0xe5, + 0x3f, 0xc3, 0x8b, 0x8b, 0xfb, 0xab, 0xe1, 0x44, 0xf6, 0x8b, 0x8b, 0xf7, + 0xf2, 0xf7, 0x23, 0x8b, 0x8b, 0xf7, 0x10, 0x3d, 0xd0, 0x4a, 0x8b, 0x8b, + 0xd8, 0x3f, 0xd2, 0xfb, 0x09, 0x8b, 0x05, 0xa3, 0x73, 0x15, 0xe8, 0xfb, + 0x28, 0xf7, 0x21, 0x2e, 0xfb, 0x21, 0xfb, 0xf7, 0x2e, 0xf7, 0xf7, 0xfb, + 0x26, 0xe8, 0xf7, 0x26, 0xf7, 0x28, 0x06, 0x0e, 0xfb, 0xc2, 0xf7, 0x75, + 0xf9, 0x15, 0x15, 0xfb, 0x2c, 0xfb, 0x20, 0x36, 0xf7, 0x20, 0xfb, 0xf6, + 0xe6, 0xf7, 0xf6, 0xf7, 0x1d, 0xe0, 0xfb, 0x1d, 0xf7, 0x2c, 0x30, 0x07, + 0x59, 0xbd, 0x15, 0xfb, 0x2c, 0xfb, 0x20, 0xfb, 0x4d, 0xf7, 0x20, 0xfb, + 0xf6, 0xf7, 0x53, 0xf7, 0xf6, 0xf7, 0x1d, 0xf7, 0x4d, 0xfb, 0x1d, 0xf7, + 0x2c, 0xfb, 0x53, 0x07, 0xa4, 0x72, 0x15, 0xf7, 0x21, 0xfb, 0x2c, 0xf7, + 0x1d, 0xfb, 0x1b, 0xfb, 0x1d, 0xfb, 0xf6, 0xfb, 0x21, 0xf7, 0xf6, 0xfb, + 0x20, 0xf7, 0x1b, 0xf7, 0x20, 0xf7, 0x2c, 0x06, 0x0e, 0xfb, 0x9a, 0xf4, + 0xf8, 0xe7, 0x15, 0x75, 0x07, 0xef, 0x89, 0xd0, 0x33, 0x85, 0xfb, 0x0a, + 0x08, 0x79, 0x06, 0x52, 0x8b, 0x62, 0x98, 0x67, 0xa9, 0x62, 0xae, 0x7b, + 0xad, 0x8b, 0xbf, 0x08, 0x73, 0xfc, 0x03, 0xa3, 0x06, 0x8c, 0xea, 0xe1, + 0xd3, 0xf7, 0x00, 0x87, 0x08, 0x99, 0x7d, 0x06, 0x8f, 0xfb, 0x01, 0x45, + 0x38, 0x2a, 0x8b, 0x08, 0x74, 0xf8, 0x02, 0xa2, 0x07, 0x2b, 0x8d, 0x48, + 0xda, 0x8b, 0xf7, 0x02, 0x08, 0x9a, 0x07, 0xcd, 0x8b, 0xa8, 0x85, 0xb1, + 0x74, 0xbb, 0x6e, 0xa9, 0x5a, 0x8b, 0x58, 0x08, 0x86, 0xa2, 0xf8, 0x03, + 0x74, 0x07, 0x87, 0x29, 0x38, 0x46, 0xfb, 0x02, 0x8f, 0x08, 0x7d, 0x8a, + 0x05, 0x84, 0xf7, 0x0b, 0xd2, 0xe5, 0xee, 0x8a, 0x08, 0xa1, 0xfc, 0x02, + 0x07, 0x0e, 0xfb, 0x27, 0xf7, 0xee, 0xf9, 0x52, 0x15, 0x21, 0xfb, 0x4a, + 0xfb, 0x61, 0x8b, 0xf1, 0xfb, 0x42, 0x25, 0xfb, 0x45, 0xf7, 0x61, 0x8b, + 0xf5, 0xfb, 0x4b, 0xf4, 0xf7, 0x4b, 0xf7, 0x62, 0x8b, 0x25, 0xf7, 0x45, + 0xf1, 0xf7, 0x42, 0xfb, 0x62, 0x8b, 0x22, 0xf7, 0x4a, 0x05, 0x37, 0xfb, + 0x6b, 0x15, 0xf7, 0x3c, 0x8b, 0xdd, 0xfb, 0x21, 0x39, 0xfb, 0x24, 0xfb, + 0x3c, 0x8b, 0x39, 0xf7, 0x24, 0xdd, 0xf7, 0x21, 0x05, 0xdf, 0xf7, 0x23, + 0x15, 0xc9, 0xfb, 0x02, 0xfb, 0x11, 0x8b, 0xca, 0xf7, 0x02, 0x05, 0xf7, + 0x13, 0xfb, 0x23, 0x15, 0xf7, 0x0d, 0x8b, 0x4f, 0x24, 0x4e, 0xf2, 0x05, + 0xc8, 0xfb, 0x48, 0x15, 0xc6, 0x22, 0xfb, 0x0b, 0x8b, 0xc7, 0xf4, 0x05, + 0xfb, 0x0f, 0xfb, 0x1e, 0x15, 0x4a, 0xfb, 0x00, 0x50, 0xf7, 0x00, 0xf7, + 0x10, 0x8b, 0x05, 0xfb, 0x53, 0xac, 0x15, 0xfb, 0x0f, 0x8b, 0xc8, 0xf4, + 0xc9, 0x22, 0x05, 0x4d, 0xf7, 0x4a, 0x15, 0x50, 0xf2, 0xf7, 0x0b, 0x8b, + 0x4f, 0x24, 0x05, 0x0e, 0x56, 0xf8, 0x2e, 0xf7, 0xfd, 0x15, 0x8a, 0xa4, + 0x96, 0xbd, 0x9f, 0xca, 0xa9, 0xe9, 0x8b, 0x8b, 0x8b, 0xa4, 0x08, 0xbc, + 0x6a, 0xb1, 0x61, 0x60, 0x69, 0x64, 0x5a, 0x1e, 0x8b, 0x7b, 0x8e, 0x78, + 0x90, 0x7b, 0xb0, 0xfb, 0x07, 0x97, 0x5a, 0x8d, 0x62, 0x4a, 0x94, 0x79, + 0x8e, 0x65, 0x97, 0xfb, 0x00, 0xb0, 0x8b, 0x8b, 0x70, 0x8b, 0x08, 0x5b, + 0x65, 0x6a, 0x61, 0x61, 0xb1, 0x69, 0xbb, 0x1f, 0x9f, 0x8b, 0xa0, 0x8e, + 0x9e, 0x91, 0xf0, 0xac, 0xba, 0x97, 0xbb, 0x8f, 0x8c, 0x7b, 0x85, 0x69, + 0x79, 0x48, 0x67, 0xfb, 0x01, 0x8b, 0x8b, 0x8b, 0x6e, 0x08, 0x59, 0xac, + 0x66, 0xb6, 0xb4, 0xad, 0xb2, 0xbb, 0x1e, 0x8b, 0x9d, 0x87, 0xa0, 0x84, + 0xa1, 0x67, 0xf7, 0x03, 0x84, 0xa9, 0x86, 0xc0, 0xac, 0x89, 0xbb, 0x81, + 0xb8, 0x7c, 0xef, 0x6a, 0x8b, 0x8b, 0xa7, 0x8b, 0x08, 0xbd, 0xb0, 0xaa, + 0xb5, 0xb7, 0x65, 0xad, 0x58, 0x1f, 0x79, 0x8b, 0x78, 0x88, 0x7b, 0x86, + 0xfb, 0x06, 0x65, 0x84, 0x89, 0x3d, 0x80, 0x08, 0x0e, 0xf8, 0x16, 0xf8, + 0x2c, 0x15, 0x6c, 0x86, 0x77, 0x77, 0x86, 0x6c, 0x08, 0x7f, 0x8c, 0x05, + 0x54, 0x8b, 0x78, 0x92, 0x73, 0xab, 0x6e, 0xaf, 0x71, 0x99, 0x69, 0x8b, + 0x08, 0x57, 0x5f, 0x5e, 0x57, 0x55, 0xb7, 0x5f, 0xbf, 0x1f, 0xad, 0x8b, + 0xa5, 0x9a, 0xa8, 0xae, 0xa4, 0xac, 0x9b, 0x90, 0xd0, 0x8c, 0x90, 0x6d, + 0x9f, 0x77, 0xa9, 0x86, 0x8b, 0x48, 0x85, 0x7a, 0x6a, 0x71, 0x68, 0x6e, + 0x7c, 0x71, 0x8b, 0x69, 0x08, 0x57, 0xb8, 0x5f, 0xc0, 0xc0, 0xb7, 0xb7, + 0xbf, 0x1e, 0x8b, 0xad, 0x7d, 0xa5, 0x67, 0xa8, 0x6a, 0xa4, 0x85, 0x9b, + 0x8b, 0xd0, 0xa9, 0x90, 0x9f, 0x9f, 0x90, 0xa9, 0xd0, 0x8a, 0x9b, 0x86, + 0xa4, 0x6a, 0xa8, 0x68, 0xa5, 0x7c, 0xac, 0x8b, 0x08, 0xc0, 0xb7, 0xb7, + 0xc0, 0xc1, 0x5f, 0xb7, 0x57, 0x1f, 0x69, 0x8b, 0x71, 0x7d, 0x6e, 0x67, + 0x73, 0x6b, 0x78, 0x84, 0x54, 0x8b, 0x08, 0x7f, 0x8a, 0x05, 0x86, 0xaa, + 0x77, 0x9f, 0x6d, 0x90, 0x8b, 0xd0, 0x91, 0x9b, 0xac, 0xa4, 0xae, 0xa8, + 0x9a, 0xa5, 0x8b, 0xac, 0x08, 0xc0, 0x5f, 0xb7, 0x55, 0x56, 0x5f, 0x5f, + 0x57, 0x1e, 0x8b, 0x69, 0x99, 0x71, 0xaf, 0x6e, 0xaa, 0x73, 0x93, 0x78, + 0x8b, 0x54, 0x08, 0x8c, 0x7f, 0x05, 0x0e, 0xf8, 0x0f, 0xf7, 0xd7, 0x15, + 0x8b, 0x6c, 0x79, 0x6a, 0x67, 0x6a, 0x5f, 0x61, 0x7d, 0x72, 0x8b, 0x60, + 0x08, 0x44, 0xc7, 0x50, 0xd1, 0xd3, 0xc5, 0xc5, 0xd3, 0x1e, 0x8b, 0xad, + 0x7c, 0xae, 0x72, 0xa3, 0x55, 0xbd, 0x76, 0xab, 0x8b, 0xb2, 0xaf, 0x8b, + 0xa3, 0x7e, 0xb5, 0x5e, 0xb2, 0x63, 0xa8, 0x7c, 0xb5, 0x8b, 0x08, 0xd3, + 0xc4, 0xc4, 0xd3, 0xd3, 0x51, 0xc6, 0x44, 0x1f, 0x67, 0x8b, 0x67, 0x7b, + 0x72, 0x70, 0x5e, 0x58, 0x6c, 0x77, 0x64, 0x8b, 0x8f, 0xb7, 0x95, 0x9e, + 0xb7, 0xb4, 0xb2, 0xaf, 0x9b, 0xab, 0x8b, 0xb4, 0x08, 0xd2, 0x50, 0xc5, + 0x44, 0x44, 0x50, 0x51, 0x45, 0x1e, 0x8b, 0x61, 0x9a, 0x6e, 0xb4, 0x63, + 0xb3, 0x63, 0x9c, 0x6e, 0x8c, 0x69, 0x5f, 0x8b, 0x80, 0x92, 0x51, 0xc7, + 0x6c, 0xaa, 0x6b, 0x9a, 0x65, 0x8b, 0x08, 0x45, 0x4f, 0x50, 0x45, 0x44, + 0xc8, 0x4e, 0xd2, 0x1f, 0xb0, 0x8b, 0xa8, 0x98, 0xa8, 0xa9, 0xc5, 0xc6, + 0x96, 0x91, 0xbb, 0x92, 0x08, 0x84, 0x07, 0x0e, 0x5a, 0xf8, 0x31, 0xf7, + 0xe4, 0x15, 0xf7, 0x20, 0x06, 0x7c, 0x77, 0x86, 0x7f, 0x8b, 0x79, 0x8b, + 0x68, 0xa7, 0x6f, 0xae, 0x8b, 0xb0, 0x8b, 0xa2, 0xa2, 0x93, 0xb8, 0x96, + 0x85, 0x93, 0x89, 0x97, 0x8b, 0x08, 0xaf, 0xa4, 0xa5, 0xb0, 0xaf, 0x72, + 0xa6, 0x6a, 0x1f, 0x80, 0x8b, 0x83, 0x89, 0x7c, 0x84, 0x7f, 0xbb, 0x76, + 0xa2, 0x69, 0x8b, 0x67, 0x8b, 0x6f, 0x70, 0x8b, 0x68, 0x8b, 0x77, 0x90, + 0x7f, 0x9a, 0x7a, 0x08, 0xfb, 0x20, 0xf7, 0x1e, 0x06, 0xa1, 0x7e, 0x97, + 0x87, 0x9a, 0x8b, 0xae, 0x8b, 0xa6, 0xa8, 0x8b, 0xaf, 0x8b, 0xae, 0x70, + 0xa6, 0x63, 0x90, 0x90, 0x96, 0x8d, 0x92, 0x8b, 0x94, 0x08, 0xb0, 0x6c, + 0xa9, 0x66, 0x69, 0x6d, 0x71, 0x6d, 0x1e, 0x8b, 0x81, 0x8d, 0x84, 0x91, + 0x76, 0x5c, 0x86, 0x72, 0x75, 0x8b, 0x66, 0x8b, 0x65, 0xa6, 0x6e, 0xb0, + 0x8b, 0x9c, 0x8b, 0x99, 0x90, 0x9c, 0x96, 0x08, 0xfb, 0x1e, 0xfb, 0x1d, + 0x07, 0x99, 0x9e, 0x8f, 0x96, 0x8b, 0x9a, 0x8b, 0xae, 0x6c, 0xa9, 0x68, + 0x8b, 0x6f, 0x8b, 0x72, 0x79, 0x83, 0x72, 0x88, 0x85, 0x8a, 0x85, 0x8a, + 0x7c, 0x7e, 0x90, 0x84, 0x8c, 0x81, 0x8b, 0x08, 0x68, 0x6e, 0x70, 0x6a, + 0x69, 0xa9, 0x6e, 0xae, 0x1f, 0x95, 0x8b, 0x91, 0x8d, 0x98, 0x90, 0x92, + 0x60, 0xa5, 0x71, 0xaf, 0x8b, 0xad, 0x8b, 0xa7, 0xa8, 0x8b, 0xad, 0x8b, + 0x9d, 0x86, 0x99, 0x7f, 0x9f, 0x08, 0xf7, 0x1d, 0xfb, 0x23, 0x06, 0x79, + 0x98, 0x7f, 0x8f, 0x79, 0x8b, 0x68, 0x8b, 0x70, 0x70, 0x8b, 0x67, 0x8b, + 0x65, 0xa6, 0x71, 0xb6, 0x88, 0x86, 0x7e, 0x89, 0x85, 0x8b, 0x81, 0x08, + 0x67, 0xa9, 0x6e, 0xaf, 0xaf, 0xaa, 0xa9, 0xae, 0x1e, 0x8b, 0x94, 0x89, + 0x92, 0x84, 0x98, 0xb6, 0x90, 0xa4, 0xa4, 0x8b, 0xb1, 0x8b, 0xae, 0x70, + 0xa6, 0x68, 0x8b, 0x7a, 0x8b, 0x7c, 0x86, 0x79, 0x7f, 0x08, 0xf7, 0x23, + 0x07, 0x0e, 0x5d, 0xf8, 0x1f, 0xf9, 0x55, 0x15, 0x87, 0x8b, 0x88, 0x87, + 0x8a, 0x84, 0x80, 0x54, 0x54, 0x31, 0x48, 0x46, 0x56, 0x53, 0x46, 0x64, + 0x36, 0x72, 0x83, 0x89, 0x87, 0x88, 0x8b, 0x87, 0x8b, 0x87, 0x8f, 0x88, + 0x92, 0x89, 0xbe, 0x81, 0xf7, 0x01, 0x4a, 0xc1, 0x56, 0x08, 0xc8, 0x51, + 0xbc, 0x35, 0x98, 0x43, 0x8c, 0x83, 0x8d, 0x88, 0x8f, 0x8b, 0x8f, 0x8b, + 0x8d, 0x8e, 0x8d, 0x92, 0x97, 0xc6, 0xbe, 0xe0, 0xc9, 0xcd, 0xcc, 0xd0, + 0xd7, 0xb7, 0xde, 0x9d, 0x93, 0x8c, 0x8f, 0x8e, 0x8b, 0x90, 0x08, 0x8b, + 0x8f, 0x87, 0x8e, 0x84, 0x8c, 0xfb, 0x2d, 0xb1, 0xfb, 0x27, 0xf7, 0x1f, + 0x62, 0xf7, 0x23, 0x85, 0xa7, 0x8a, 0x8d, 0x86, 0x8b, 0x08, 0x0e, 0x5e, + 0xf8, 0x13, 0xf9, 0x55, 0x15, 0x5b, 0xfb, 0x3f, 0xfb, 0x1d, 0xfb, 0x1b, + 0xfb, 0x37, 0x62, 0x08, 0x78, 0x07, 0xf7, 0x45, 0x59, 0xf7, 0x1d, 0xfb, + 0x1e, 0xad, 0xfb, 0x39, 0x08, 0x9d, 0x06, 0xb5, 0xf7, 0x3e, 0xf7, 0x2d, + 0xf7, 0x2b, 0xf7, 0x37, 0xab, 0x08, 0x9e, 0x07, 0xfb, 0x3f, 0xb2, 0xfb, + 0x25, 0xf7, 0x20, 0x61, 0xf7, 0x3c, 0x08, 0x79, 0x06, 0x94, 0x61, 0x15, + 0xa3, 0xfb, 0x13, 0x9b, 0x59, 0xae, 0x4c, 0xd2, 0x65, 0xb6, 0x7e, 0xf7, + 0x1d, 0x74, 0x74, 0x86, 0x79, 0x87, 0x84, 0x89, 0xfb, 0x07, 0x74, 0x72, + 0x83, 0x4c, 0x68, 0x69, 0x52, 0x7a, 0x54, 0x73, 0xfb, 0x13, 0x70, 0xf7, + 0x16, 0x79, 0xc1, 0x6c, 0xc2, 0x08, 0x48, 0xaf, 0x6e, 0x94, 0xfb, 0x2b, + 0xab, 0xf7, 0x1d, 0xa5, 0xba, 0x99, 0xca, 0xad, 0xaf, 0xcc, 0x97, 0xb1, + 0xa7, 0xf7, 0x1d, 0x08, 0x0e, 0x74, 0xf8, 0x2d, 0xf9, 0x57, 0x15, 0x34, + 0xfb, 0xa2, 0xfb, 0xb3, 0x8b, 0xf7, 0x7e, 0xfb, 0x42, 0x31, 0xfb, 0xa8, + 0xf7, 0x7a, 0xf7, 0x3e, 0xf7, 0x7b, 0xfb, 0x3e, 0x32, 0xf7, 0xa8, 0xf7, + 0x7b, 0xf7, 0x42, 0xfb, 0xb4, 0x8b, 0x36, 0xf7, 0xa2, 0x05, 0x0e, 0x7b, + 0xf8, 0x32, 0xf9, 0x63, 0x15, 0x24, 0xfb, 0x86, 0xfb, 0xa8, 0x75, 0xf7, + 0x65, 0xfb, 0x4c, 0x4f, 0xfb, 0xa1, 0xf7, 0x7a, 0xf7, 0x2b, 0xf7, 0x80, + 0xfb, 0x2b, 0x45, 0xf7, 0xa1, 0xf7, 0x63, 0xf7, 0x4c, 0xfb, 0xa7, 0xa1, + 0x29, 0xf7, 0x86, 0x05, 0x6b, 0x04, 0xc8, 0xfb, 0x9a, 0xf7, 0xaa, 0x9d, + 0xfb, 0x7c, 0xfb, 0x2e, 0xf5, 0xfb, 0x95, 0xfb, 0x69, 0xf7, 0x4c, 0xfb, + 0x65, 0xfb, 0x4c, 0xef, 0xf7, 0x95, 0xfb, 0x7f, 0xf7, 0x2e, 0xf7, 0xab, + 0x79, 0xcc, 0xf7, 0x9a, 0x05, 0x0e, 0x59, 0xf8, 0x24, 0xf9, 0x56, 0x15, + 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, + 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5a, + 0xf7, 0x58, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x85, 0x71, 0x15, + 0xd7, 0xfb, 0x75, 0xf7, 0x88, 0x8b, 0xfb, 0x5a, 0xfb, 0x26, 0xd3, 0xfb, + 0x7d, 0xfb, 0x56, 0xf7, 0x25, 0xfb, 0x61, 0xfb, 0x25, 0xda, 0xf7, 0x7d, + 0xfb, 0x53, 0xf7, 0x26, 0xf7, 0x86, 0x8b, 0xd6, 0xf7, 0x75, 0x05, 0x0e, + 0x8d, 0xf8, 0x31, 0xf9, 0x56, 0x15, 0x38, 0xfb, 0xb8, 0xfb, 0xbb, 0x97, + 0xf7, 0x8e, 0xfb, 0x30, 0x23, 0xfb, 0xb0, 0xf7, 0x7c, 0xf7, 0x53, 0xf7, + 0x86, 0xfb, 0x53, 0xfb, 0x05, 0xf7, 0xb0, 0xf7, 0x9d, 0xf7, 0x30, 0xfb, + 0xcc, 0x7f, 0x39, 0xf7, 0xb8, 0x05, 0x8e, 0xfb, 0xb3, 0x15, 0xc4, 0xbb, + 0x5a, 0x51, 0x50, 0x5b, 0x5b, 0x50, 0x50, 0x5b, 0xbb, 0xc7, 0xc6, 0xbb, + 0xba, 0xc8, 0x1f, 0x0e, 0x7b, 0xf8, 0x33, 0xf9, 0x56, 0x15, 0x25, 0xfb, + 0x88, 0xfb, 0xaa, 0x76, 0xf7, 0x67, 0xfb, 0x4c, 0x4b, 0xfb, 0xa1, 0xf7, + 0x7d, 0xf7, 0x2b, 0xf7, 0x7e, 0xfb, 0x2b, 0x46, 0xf7, 0xa1, 0xf7, 0x65, + 0xf7, 0x4c, 0xfb, 0xa7, 0xa0, 0x28, 0xf7, 0x88, 0x05, 0x69, 0x04, 0xc8, + 0xfb, 0x99, 0x05, 0x73, 0x97, 0x7a, 0x8f, 0x75, 0x8b, 0x74, 0x8b, 0x7b, + 0x87, 0x75, 0x7f, 0x08, 0xca, 0xf7, 0x99, 0x05, 0xf7, 0xe9, 0xfb, 0x86, + 0x15, 0xfb, 0x7c, 0xfb, 0x2e, 0x05, 0x8f, 0x9b, 0x8d, 0x94, 0x8b, 0x98, + 0x8b, 0xaf, 0x7b, 0xaa, 0x68, 0xa9, 0x08, 0xf7, 0xa9, 0x9e, 0x05, 0xfb, + 0x14, 0xfc, 0x2f, 0x15, 0xfb, 0x69, 0xf7, 0x48, 0x05, 0xbe, 0x91, 0xad, + 0xa2, 0xa3, 0xb9, 0x08, 0xf3, 0xfb, 0x93, 0x05, 0xfc, 0x3b, 0x87, 0x15, + 0xf2, 0xf7, 0x97, 0x05, 0xa6, 0x58, 0xab, 0x75, 0xbb, 0x89, 0x08, 0xfb, + 0x66, 0xfb, 0x4c, 0x05, 0xfb, 0x1d, 0xf8, 0x33, 0x15, 0xf7, 0xae, 0x78, + 0x05, 0x6a, 0x6e, 0x7a, 0x6c, 0x8b, 0x6e, 0x8b, 0x7f, 0x8d, 0x7b, 0x90, + 0x78, 0x08, 0xfb, 0x83, 0xf7, 0x2f, 0x05, 0x0e, 0x85, 0xf8, 0x35, 0xf8, + 0xbb, 0x15, 0x48, 0xfb, 0x46, 0xfb, 0x2f, 0x8b, 0xf7, 0x08, 0x2f, 0x5e, + 0xfb, 0x38, 0xf7, 0x2b, 0xee, 0xf7, 0x28, 0x28, 0x54, 0xf7, 0x38, 0xf7, + 0x0e, 0xe7, 0xfb, 0x26, 0x8b, 0x46, 0xf7, 0x46, 0x05, 0xf7, 0x2f, 0x04, + 0x22, 0xfb, 0xaa, 0xfb, 0xa9, 0x8b, 0xf7, 0x69, 0xfb, 0x3b, 0x3e, 0xfb, + 0xa7, 0xf7, 0x8a, 0xf7, 0x37, 0xf7, 0x8d, 0xfb, 0x37, 0x31, 0xf7, 0xa7, + 0xf7, 0x72, 0xf7, 0x3b, 0xfb, 0xa6, 0x8b, 0x20, 0xf7, 0xaa, 0x05, 0x41, + 0x04, 0xe4, 0xfb, 0x78, 0xf7, 0x6b, 0x8b, 0xfb, 0x44, 0xfb, 0x19, 0xd1, + 0xfb, 0x70, 0xfb, 0x5a, 0xf7, 0x16, 0xfb, 0x5b, 0xfb, 0x16, 0xc8, 0xf7, + 0x70, 0xfb, 0x3c, 0xf7, 0x19, 0xf7, 0x6e, 0x8b, 0xe3, 0xf7, 0x78, 0x05, + 0x0e, 0x74, 0xf8, 0x2e, 0xf8, 0x7d, 0x15, 0x5e, 0xfb, 0x09, 0xfb, 0x08, + 0x8b, 0xe3, 0x44, 0x66, 0xfb, 0x16, 0xf7, 0x02, 0xd8, 0xf5, 0x3e, 0x69, + 0xf7, 0x16, 0xe8, 0xd2, 0xfb, 0x0c, 0x8b, 0x05, 0x5e, 0xf7, 0x09, 0x05, + 0xf7, 0x02, 0x70, 0x15, 0x24, 0xf7, 0x82, 0x05, 0x8a, 0x8f, 0x89, 0x8c, + 0x87, 0x8b, 0x88, 0x8b, 0x89, 0x89, 0x89, 0x88, 0x08, 0x25, 0xfb, 0x82, + 0xfb, 0x96, 0x70, 0x05, 0x86, 0x88, 0x88, 0x87, 0x1f, 0x8b, 0x8a, 0x8d, + 0x88, 0x8d, 0x89, 0x08, 0xf7, 0x57, 0xfb, 0x30, 0x4e, 0xfb, 0x9d, 0x8b, + 0x87, 0x05, 0x8c, 0x88, 0x8d, 0x88, 0x8e, 0x8b, 0x8c, 0x8b, 0x8e, 0x8c, + 0x8c, 0x8c, 0x08, 0xf7, 0x76, 0xf7, 0x23, 0xf7, 0x73, 0xfb, 0x27, 0x05, + 0x8d, 0x8a, 0x8d, 0x8a, 0x8d, 0x8b, 0x08, 0x8e, 0x8e, 0x8f, 0x8e, 0x1f, + 0x8a, 0x8e, 0x50, 0xf7, 0xa1, 0xf7, 0x55, 0xf7, 0x30, 0x05, 0x8d, 0x8d, + 0x8d, 0x8e, 0x8b, 0x8d, 0x08, 0x8f, 0x88, 0x8d, 0x86, 0x1e, 0xfb, 0x92, + 0xa6, 0x05, 0xfb, 0x02, 0xf7, 0x19, 0x15, 0xd5, 0xfb, 0x4b, 0xf7, 0x52, + 0x7f, 0xfb, 0x27, 0xfb, 0x05, 0xbd, 0xfb, 0x61, 0xfb, 0x3b, 0xf7, 0x08, + 0xfb, 0x3f, 0xfb, 0x08, 0xc0, 0xf7, 0x61, 0xfb, 0x25, 0xf7, 0x05, 0xf7, + 0x53, 0x97, 0xd3, 0xf7, 0x4b, 0x05, 0x0e, 0x83, 0xf8, 0x38, 0xf9, 0x57, + 0x15, 0x2a, 0xfb, 0xa6, 0xfb, 0xb4, 0x8b, 0xf7, 0x7c, 0xfb, 0x39, 0x2b, + 0xfb, 0xad, 0xf7, 0x8d, 0xf7, 0x44, 0xf7, 0x95, 0xfb, 0x44, 0x25, 0xf7, + 0xad, 0xf7, 0x71, 0xf7, 0x39, 0xfb, 0xad, 0x8b, 0x2c, 0xf7, 0xa6, 0x05, + 0x39, 0xfb, 0xb9, 0x15, 0xdd, 0xf7, 0x85, 0x8b, 0xfb, 0xe7, 0x39, 0xed, + 0x05, 0xf7, 0x34, 0x16, 0xf7, 0x87, 0x8b, 0xfb, 0xd5, 0x29, 0xd9, 0xed, + 0x05, 0xc2, 0xfb, 0x26, 0x15, 0xe4, 0xfb, 0x80, 0xfb, 0x72, 0xf7, 0xb0, + 0xf7, 0x19, 0x5b, 0x05, 0xfb, 0x19, 0x38, 0x15, 0xfb, 0x68, 0xfb, 0x2d, + 0xf7, 0x68, 0xf7, 0xaf, 0x8b, 0xfb, 0x16, 0x05, 0xfb, 0x15, 0xde, 0x15, + 0xfb, 0x5f, 0xf7, 0x26, 0xf7, 0xe0, 0x29, 0xfb, 0x15, 0x5b, 0x05, 0x0e, + 0xdf, 0xf8, 0x2b, 0xf9, 0x56, 0x15, 0x33, 0xfb, 0x9c, 0xfb, 0xb0, 0x8b, + 0xf7, 0x76, 0xfb, 0x41, 0x35, 0xfb, 0x97, 0xf7, 0x17, 0x74, 0xf7, 0x46, + 0xf7, 0x16, 0xf7, 0x26, 0x20, 0xf7, 0x19, 0x8b, 0x31, 0xf7, 0x97, 0xf7, + 0x6b, 0xf7, 0x2e, 0x4c, 0x9e, 0xfb, 0x69, 0x8b, 0x39, 0xf7, 0x89, 0xfb, + 0x0f, 0x9e, 0x05, 0x94, 0x66, 0x15, 0xdd, 0xfb, 0x8a, 0xf7, 0x8b, 0x8b, + 0xfb, 0x5f, 0xfb, 0x21, 0xd6, 0xfb, 0x83, 0xfb, 0x5d, 0xf7, 0x2c, 0xfb, + 0x66, 0xfb, 0x2c, 0xdc, 0xf7, 0x83, 0xfb, 0x52, 0xf7, 0x21, 0xf7, 0x82, + 0x8b, 0xdc, 0xf7, 0x8a, 0x05, 0x0e, 0x2c, 0xf8, 0x54, 0xf9, 0x47, 0x15, + 0xfb, 0x2a, 0xfb, 0x73, 0x06, 0xfb, 0x4d, 0xf7, 0x0a, 0x3d, 0xfb, 0x19, + 0xf7, 0x59, 0xfb, 0x01, 0xfb, 0x59, 0xfb, 0x02, 0xd9, 0xfb, 0x18, 0xf7, + 0x4d, 0xf7, 0x09, 0x8b, 0xfb, 0x6f, 0xf7, 0x2a, 0x8b, 0x8b, 0xf7, 0x6f, + 0xf7, 0x4c, 0xfb, 0x09, 0xd9, 0xf7, 0x18, 0xfb, 0x59, 0xf7, 0x02, 0xf7, + 0x59, 0xf7, 0x01, 0x3d, 0xf7, 0x19, 0xfb, 0x4c, 0xfb, 0x0a, 0x05, 0xf7, + 0x73, 0x07, 0x0e, 0xfb, 0x08, 0xf8, 0x34, 0xf9, 0x47, 0x15, 0xfb, 0x01, + 0xfb, 0x87, 0xf7, 0x01, 0xf7, 0x87, 0x06, 0xfb, 0x01, 0xfd, 0x47, 0x15, + 0xf7, 0x01, 0xf7, 0x87, 0xfb, 0x01, 0xfb, 0x87, 0x06, 0xf8, 0x11, 0xf8, + 0x6b, 0x15, 0x54, 0xea, 0xfb, 0x66, 0xfb, 0x0e, 0xc1, 0x2c, 0xf7, 0x67, + 0xf7, 0x0e, 0x05, 0xfd, 0x21, 0xfb, 0x8f, 0x15, 0xc2, 0x2c, 0xf7, 0x66, + 0xf7, 0x0e, 0x55, 0xea, 0xfb, 0x67, 0xfb, 0x0e, 0x05, 0xc2, 0xf7, 0xee, + 0x15, 0x54, 0x2c, 0xf7, 0x67, 0xfb, 0x0e, 0xc1, 0xea, 0xfb, 0x66, 0xf7, + 0x0e, 0x05, 0xf8, 0xb3, 0xfc, 0x4d, 0x15, 0xc2, 0xea, 0xfb, 0x67, 0xf7, + 0x0e, 0x55, 0x2c, 0xf7, 0x66, 0xfb, 0x0e, 0x05, 0x0e, 0x31, 0xf8, 0x21, + 0xf9, 0x47, 0x15, 0x5a, 0x8b, 0x99, 0xfb, 0xd5, 0xfb, 0x6c, 0xf7, 0x7b, + 0x70, 0x6b, 0xf7, 0x79, 0xfb, 0x68, 0xfb, 0xcd, 0x98, 0x8b, 0x60, 0xf7, + 0xcd, 0x8b, 0xfb, 0x79, 0xfb, 0x66, 0xb0, 0x6c, 0xf7, 0x62, 0xf7, 0x79, + 0x7d, 0xfb, 0xcf, 0xbc, 0x8b, 0x7f, 0xf7, 0xcf, 0xf7, 0x6b, 0xfb, 0x79, + 0x05, 0xaa, 0xaa, 0xfb, 0x7e, 0xf7, 0x66, 0xf7, 0xd1, 0x8b, 0x8b, 0xb6, + 0xfb, 0xd1, 0x7e, 0xf7, 0x7e, 0xf7, 0x68, 0x6c, 0xab, 0xfb, 0x6b, 0xfb, + 0x7b, 0x97, 0xf7, 0xd5, 0x05, 0x0e, 0x5a, 0xf7, 0xfa, 0xf8, 0x39, 0x15, + 0xfb, 0x6b, 0xf7, 0x47, 0x05, 0x89, 0x8d, 0x89, 0x8c, 0x89, 0x8b, 0x88, + 0x8b, 0x88, 0x87, 0x8b, 0x88, 0x8b, 0x89, 0x8b, 0x8a, 0x8c, 0x8a, 0x08, + 0xf7, 0x48, 0xfb, 0x6b, 0xfb, 0xa3, 0x6f, 0x05, 0x87, 0x88, 0x88, 0x87, + 0x1f, 0x8b, 0x88, 0x8d, 0x88, 0x8e, 0x8a, 0x08, 0xf7, 0xa5, 0x76, 0xfb, + 0x45, 0xfb, 0x67, 0x05, 0x88, 0x88, 0x8a, 0x89, 0x8b, 0x89, 0x8b, 0x88, + 0x8f, 0x87, 0x8f, 0x8b, 0x8c, 0x8b, 0x8d, 0x8c, 0x8c, 0x8c, 0x08, 0xf7, + 0x6b, 0xf7, 0x46, 0xa7, 0xfb, 0xa8, 0x05, 0x86, 0x8e, 0x88, 0x8f, 0x8e, + 0x8f, 0x8e, 0x8d, 0x1e, 0xa1, 0xf7, 0xab, 0xf7, 0x65, 0xfb, 0x46, 0x05, + 0x8d, 0x89, 0x8e, 0x8a, 0x8c, 0x8b, 0x08, 0x8e, 0x8e, 0x8f, 0x8e, 0x1f, + 0x8a, 0x8f, 0xfb, 0x41, 0xf7, 0x6b, 0xf7, 0xac, 0xa5, 0x05, 0x8f, 0x8c, + 0x8e, 0x8e, 0x8b, 0x8f, 0x08, 0x8f, 0x89, 0x8e, 0x88, 0x1e, 0xfb, 0xae, + 0xa1, 0xf7, 0x48, 0xf7, 0x6e, 0x05, 0x8d, 0x8d, 0x8c, 0x8e, 0x8b, 0x8d, + 0x08, 0x8e, 0x87, 0x8e, 0x87, 0x8a, 0x89, 0x8b, 0x8a, 0x1e, 0xfb, 0x6f, + 0xfb, 0x4e, 0x6e, 0xf7, 0xaa, 0x05, 0x8f, 0x88, 0x8e, 0x87, 0x88, 0x88, + 0x89, 0x89, 0x1e, 0x75, 0xfb, 0xad, 0x05, 0x0e, 0x5c, 0xf8, 0x2a, 0xf9, + 0x55, 0x15, 0x7f, 0x8b, 0x51, 0xfb, 0x71, 0xfb, 0x50, 0xf7, 0x0d, 0x83, + 0x84, 0xf7, 0x0c, 0xfb, 0x5f, 0xfb, 0x75, 0x58, 0x8b, 0x81, 0xf7, 0x75, + 0x56, 0xfb, 0x0c, 0xfb, 0x51, 0x93, 0x83, 0xf7, 0x5c, 0xf7, 0x0a, 0xb9, + 0xfb, 0x6c, 0x97, 0x8b, 0xc2, 0xf7, 0x75, 0xf7, 0x50, 0xfb, 0x0b, 0x05, + 0x94, 0x93, 0xfb, 0x09, 0xf7, 0x57, 0xf7, 0x6d, 0xbc, 0x8b, 0x97, 0xfb, + 0x70, 0xc1, 0xf7, 0x10, 0xf7, 0x54, 0x84, 0x93, 0xfb, 0x5f, 0xfb, 0x0f, + 0x5d, 0xf7, 0x6e, 0x05, 0x54, 0xfb, 0x81, 0x15, 0xbc, 0xf7, 0x5e, 0x8b, + 0xfb, 0xc9, 0x5a, 0xf6, 0x05, 0xf1, 0x89, 0x15, 0xf7, 0x45, 0xf7, 0x04, + 0xfb, 0x70, 0xfb, 0x70, 0xb6, 0xf7, 0x00, 0x05, 0xd2, 0x44, 0x15, 0xf7, + 0x57, 0x5d, 0xfb, 0xc3, 0x8b, 0xf7, 0x00, 0xb9, 0x05, 0x84, 0x27, 0x15, + 0xf7, 0x03, 0xfb, 0x42, 0xfb, 0x6a, 0xf7, 0x69, 0xf2, 0x64, 0x05, 0x45, + 0x43, 0x15, 0x5c, 0xfb, 0x5d, 0x8b, 0xf7, 0xc9, 0xba, 0xfb, 0x00, 0x05, + 0x28, 0x16, 0xfb, 0x49, 0xfb, 0x05, 0xf7, 0x74, 0xf7, 0x74, 0x60, 0xfb, + 0x03, 0x05, 0x44, 0xd3, 0x15, 0xfb, 0x66, 0xb9, 0xf7, 0xcd, 0x8e, 0x24, + 0x5a, 0x05, 0x8d, 0xef, 0x15, 0xfb, 0x01, 0xf7, 0x46, 0xf7, 0x6c, 0xfb, + 0x6d, 0x20, 0xb2, 0x05, 0x0e, 0xfb, 0x24, 0xf8, 0x66, 0xf7, 0xed, 0x15, + 0xf7, 0x54, 0xf7, 0x41, 0x05, 0x8d, 0x8d, 0x8c, 0x8d, 0x8b, 0x8c, 0x08, + 0x8e, 0x88, 0x8d, 0x89, 0x1e, 0x88, 0x8a, 0xfb, 0x8a, 0x3b, 0x55, 0xf7, + 0x91, 0x05, 0x8a, 0x8f, 0x89, 0x8d, 0x89, 0x8b, 0x89, 0x8b, 0x89, 0x89, + 0x8a, 0x87, 0x08, 0x55, 0xfb, 0x91, 0xfb, 0x8a, 0xdb, 0x05, 0x89, 0x8c, + 0x8a, 0x8b, 0x8b, 0x8b, 0x89, 0x8b, 0x88, 0x89, 0x8b, 0x88, 0x8b, 0x8a, + 0x8c, 0x89, 0x8d, 0x89, 0x08, 0xf7, 0x54, 0xfb, 0x41, 0xfb, 0x54, 0xfb, + 0x42, 0x05, 0x89, 0x8a, 0x8a, 0x89, 0x8b, 0x8a, 0x8b, 0x88, 0x8e, 0x89, + 0x8d, 0x8b, 0x8b, 0x8b, 0x8c, 0x8b, 0x8d, 0x8c, 0x08, 0xf7, 0x8a, 0xdb, + 0xc1, 0xfb, 0x92, 0x05, 0x8c, 0x88, 0x8d, 0x89, 0x8d, 0x8b, 0x8e, 0x8b, + 0x8c, 0x8d, 0x8c, 0x8e, 0x08, 0xc1, 0xf7, 0x92, 0xf7, 0x8a, 0x3b, 0x05, + 0x8d, 0x8a, 0x8c, 0x8b, 0x8b, 0x8b, 0x8d, 0x8b, 0x8e, 0x8d, 0x8b, 0x8e, + 0x8b, 0x8c, 0x8a, 0x8d, 0x89, 0x8c, 0x08, 0xfb, 0x54, 0xf7, 0x42, 0x05, + 0x0e, 0x4c, 0xf8, 0x7e, 0xf8, 0x5c, 0x15, 0xb6, 0xf7, 0x7a, 0x05, 0x8c, + 0x8d, 0x8b, 0x8c, 0x8b, 0x8c, 0x8b, 0x8e, 0x87, 0x8e, 0x87, 0x8b, 0x88, + 0x8b, 0x89, 0x89, 0x88, 0x88, 0x08, 0xfb, 0x18, 0xfb, 0x53, 0xfb, 0x1d, + 0xf7, 0x56, 0x05, 0x89, 0x8e, 0x89, 0x8c, 0x89, 0x8b, 0x88, 0x8b, 0x87, + 0x87, 0x8c, 0x89, 0x08, 0x8c, 0x88, 0xb6, 0xfb, 0x7d, 0xfb, 0x7e, 0xb7, + 0x88, 0x8b, 0x05, 0x88, 0x88, 0x88, 0x88, 0x1f, 0x8b, 0x88, 0x8d, 0x89, + 0x8d, 0x89, 0x08, 0xf7, 0x58, 0xfb, 0x21, 0xfb, 0x5a, 0xfb, 0x19, 0x05, + 0x87, 0x89, 0x8a, 0x89, 0x8b, 0x89, 0x08, 0x87, 0x8e, 0x89, 0x8f, 0x1e, + 0x8e, 0x8b, 0xf7, 0x80, 0xb2, 0x60, 0xfb, 0x83, 0x8a, 0x89, 0x05, 0x8a, + 0x88, 0x8f, 0x88, 0x8e, 0x8b, 0x8d, 0x8b, 0x8e, 0x8d, 0x8c, 0x8c, 0x08, + 0xf7, 0x1d, 0xf7, 0x58, 0xf7, 0x1c, 0xfb, 0x57, 0x05, 0x8d, 0x89, 0x8e, + 0x89, 0x8d, 0x8b, 0x08, 0x8e, 0x8d, 0x8f, 0x8d, 0x1f, 0x8a, 0x8f, 0x60, + 0xf7, 0x81, 0xf7, 0x86, 0x5b, 0x8e, 0x8a, 0x05, 0x8e, 0x8a, 0x8e, 0x8f, + 0x8b, 0x8e, 0x8b, 0x8e, 0x89, 0x8d, 0x89, 0x8d, 0x08, 0xfb, 0x5f, 0xf7, + 0x22, 0xf7, 0x5f, 0xf7, 0x22, 0x05, 0x8e, 0x8d, 0x8c, 0x8d, 0x8b, 0x8d, + 0x08, 0x8f, 0x89, 0x8d, 0x87, 0x1e, 0x88, 0x8b, 0xfb, 0x86, 0x5f, 0x05, + 0x0e, 0x44, 0xf8, 0xa7, 0xf9, 0x4f, 0x15, 0xfb, 0x28, 0xfb, 0x3d, 0xfb, + 0x25, 0xf7, 0x3d, 0x99, 0xfb, 0x6e, 0xfb, 0x6d, 0x9b, 0xf7, 0x3c, 0xfb, + 0x27, 0xfb, 0x3c, 0xfb, 0x26, 0xf7, 0x6d, 0x9a, 0x7d, 0xfb, 0x76, 0xf7, + 0x25, 0xf7, 0x3d, 0xf7, 0x28, 0xfb, 0x3d, 0x7d, 0xf7, 0x76, 0xf7, 0x6d, + 0x7c, 0xfb, 0x3b, 0xf7, 0x26, 0xf7, 0x3b, 0xf7, 0x27, 0xfb, 0x6d, 0x7b, + 0x05, 0x99, 0xf7, 0x6e, 0x05, 0x0e, 0x5c, 0xf8, 0xdb, 0xf9, 0x34, 0x15, + 0xfb, 0x20, 0xfb, 0x17, 0x59, 0xf7, 0x47, 0x5e, 0xfb, 0x47, 0xfb, 0x17, + 0xf7, 0x17, 0xb8, 0xfb, 0x43, 0xfb, 0x44, 0xb7, 0xf7, 0x17, 0xfb, 0x16, + 0xfb, 0x4a, 0x59, 0xf7, 0x4a, 0x55, 0xfb, 0x17, 0xfb, 0x17, 0xf7, 0x44, + 0xb9, 0x5e, 0xfb, 0x43, 0xf7, 0x17, 0xf7, 0x15, 0xb8, 0xfb, 0x45, 0xbd, + 0xf7, 0x45, 0x05, 0xf7, 0x20, 0xfb, 0x15, 0x5a, 0xf7, 0x43, 0xf7, 0x42, + 0x5d, 0xfb, 0x11, 0xf7, 0x17, 0xf7, 0x42, 0xc1, 0xfb, 0x42, 0xbd, 0xf7, + 0x11, 0xf7, 0x16, 0xfb, 0x42, 0x5f, 0xbc, 0xf7, 0x43, 0x05, 0x0e, 0x3b, + 0xf8, 0x00, 0xf9, 0x49, 0x15, 0x8b, 0xfb, 0xa1, 0x2a, 0xf7, 0x8e, 0x67, + 0x7d, 0xf5, 0xfb, 0x8c, 0xfb, 0x4f, 0xf7, 0x55, 0x70, 0x70, 0xf7, 0x57, + 0xfb, 0x51, 0xfb, 0x8e, 0xf6, 0x7d, 0x68, 0xf7, 0x92, 0x28, 0xfb, 0xa5, + 0x8b, 0x8b, 0x6a, 0xf7, 0xa5, 0x8b, 0xfb, 0x92, 0x2a, 0x99, 0x67, 0x05, + 0xf7, 0x8e, 0xf7, 0x02, 0xfb, 0x57, 0xfb, 0x53, 0xa6, 0x70, 0xf7, 0x4f, + 0xf7, 0x59, 0x21, 0xfb, 0x8f, 0xaf, 0x7d, 0xec, 0xf7, 0x92, 0x8b, 0xfb, + 0xa6, 0xac, 0x8b, 0x8b, 0xf7, 0xa6, 0xeb, 0xfb, 0x92, 0xae, 0x99, 0x21, + 0xf7, 0x8f, 0xf7, 0x50, 0xfb, 0x59, 0xa6, 0xa6, 0x05, 0xfb, 0x55, 0xf7, + 0x53, 0xf7, 0x8c, 0xfb, 0x02, 0x99, 0xaf, 0xfb, 0x8e, 0xec, 0xf7, 0xa1, + 0x8b, 0x8b, 0xac, 0xfb, 0xa1, 0x8b, 0xf7, 0x8e, 0xee, 0x7d, 0xae, 0xfb, + 0x8c, 0x20, 0xf7, 0x55, 0xf7, 0x51, 0x70, 0xa6, 0xfb, 0x50, 0xfb, 0x55, + 0xf5, 0xf7, 0x8c, 0x68, 0x99, 0x05, 0x2b, 0xfb, 0x8e, 0x8b, 0xf7, 0xa1, + 0x6a, 0x8b, 0x05, 0x0e, 0xfb, 0x18, 0xf7, 0x9c, 0xf7, 0xbb, 0x15, 0x37, + 0x84, 0x5b, 0x80, 0x58, 0x74, 0x69, 0x7c, 0x7f, 0x7c, 0x8b, 0x72, 0x8b, + 0x6b, 0xa7, 0x6d, 0xa9, 0x8b, 0x9c, 0x8b, 0xa0, 0x97, 0xab, 0xa6, 0xb2, + 0xad, 0x96, 0x98, 0xbe, 0xd3, 0x08, 0xf7, 0x47, 0xf2, 0x15, 0xe0, 0x92, + 0xb8, 0x95, 0xc0, 0xa3, 0xac, 0x9a, 0x98, 0x9a, 0x8b, 0xa4, 0x8b, 0xab, + 0x6f, 0xa9, 0x6e, 0x8b, 0x65, 0x8b, 0x46, 0x4b, 0x4a, 0x2d, 0x08, 0xfb, + 0x47, 0x16, 0x59, 0xd2, 0x88, 0x8e, 0x67, 0xad, 0x66, 0xad, 0x71, 0x9b, + 0x78, 0x8b, 0x6d, 0x8b, 0x6f, 0x6d, 0x8b, 0x6b, 0x8b, 0x72, 0x98, 0x7c, + 0xac, 0x7c, 0xbe, 0x74, 0xbb, 0x80, 0xdf, 0x84, 0x08, 0xf7, 0x47, 0x24, + 0x15, 0xcc, 0x2c, 0xd0, 0x4c, 0xb0, 0x8b, 0xa9, 0x8b, 0xa7, 0xa9, 0x8b, + 0xab, 0x8b, 0xa4, 0x7e, 0x9a, 0x6a, 0x9a, 0x56, 0xa3, 0x5e, 0x95, 0x36, + 0x92, 0x08, 0x32, 0xf7, 0x1c, 0x15, 0x5d, 0x64, 0x65, 0x5e, 0x5b, 0xb1, + 0x65, 0xb9, 0xbb, 0xb1, 0xb1, 0xba, 0xb9, 0x65, 0xb1, 0x5c, 0x1f, 0x9e, + 0x04, 0xb3, 0xe2, 0x9c, 0xc5, 0x8b, 0xbf, 0x08, 0xad, 0x74, 0xa2, 0x68, + 0x69, 0x74, 0x74, 0x6a, 0x1e, 0x8b, 0x56, 0x9b, 0x52, 0xb5, 0x33, 0x08, + 0xfb, 0x63, 0x04, 0x62, 0x34, 0x7a, 0x51, 0x8b, 0x57, 0x08, 0x69, 0xa2, + 0x74, 0xae, 0xad, 0xa2, 0xa2, 0xad, 0x1e, 0x8b, 0xbe, 0x79, 0xc8, 0x64, + 0xe0, 0x08, 0x0e, 0xfb, 0x17, 0xf7, 0xa0, 0xf7, 0x9e, 0x15, 0x8f, 0x8b, + 0x91, 0x88, 0x92, 0x85, 0x93, 0x84, 0x95, 0x85, 0x92, 0x89, 0x9b, 0x86, + 0x8e, 0x87, 0x8b, 0x7c, 0x8b, 0x7e, 0x87, 0x79, 0x81, 0x6b, 0x7a, 0x57, + 0x86, 0x74, 0x8b, 0x74, 0x08, 0x65, 0xa7, 0x6a, 0xaa, 0xaf, 0xa5, 0xaa, + 0xb4, 0x1e, 0x8b, 0xa4, 0x84, 0xaa, 0x7c, 0xb4, 0x81, 0xa5, 0x86, 0xa1, + 0x8b, 0x99, 0x8b, 0x9b, 0x8f, 0x90, 0x9a, 0x8f, 0x91, 0x8d, 0x95, 0x91, + 0x93, 0x92, 0x93, 0x91, 0x91, 0x8e, 0x8f, 0x8b, 0x95, 0x8b, 0xa5, 0x76, + 0xa4, 0x6f, 0x08, 0xc0, 0x4e, 0xa6, 0x78, 0xae, 0x8b, 0xaa, 0x8b, 0xa6, + 0xa4, 0x8b, 0xa9, 0x8b, 0xa3, 0x7d, 0xa3, 0x74, 0x98, 0x76, 0x98, 0x72, + 0x93, 0x58, 0x95, 0x58, 0x95, 0x72, 0x97, 0x8b, 0x9a, 0x8b, 0x8c, 0x8c, + 0x8f, 0x8c, 0x90, 0x08, 0x8c, 0x8e, 0x8b, 0x90, 0x8b, 0x91, 0x8b, 0x91, + 0x8b, 0x90, 0x8a, 0x8e, 0x8a, 0x90, 0x8a, 0x8f, 0x8b, 0x8c, 0x8b, 0x9a, + 0xa4, 0x97, 0xbe, 0x95, 0xbe, 0x95, 0xa4, 0x93, 0xa0, 0x98, 0xa2, 0x98, + 0x99, 0xa3, 0x8b, 0xa3, 0x08, 0xa8, 0x70, 0xa5, 0x6c, 0x1e, 0x68, 0x8b, + 0x70, 0x78, 0x56, 0x4e, 0x72, 0x6f, 0x71, 0x76, 0x81, 0x8b, 0x87, 0x8b, + 0x85, 0x8e, 0x83, 0x91, 0x83, 0x92, 0x81, 0x91, 0x85, 0x8d, 0x08, 0x7c, + 0x8f, 0x87, 0x90, 0x8b, 0x9b, 0x8b, 0x99, 0x90, 0xa1, 0x95, 0xa5, 0x9a, + 0xb5, 0x92, 0xa9, 0x8b, 0xa4, 0x08, 0xb4, 0x71, 0xaa, 0x68, 0x6b, 0x6f, + 0x6a, 0x65, 0x1e, 0x8b, 0x74, 0x90, 0x75, 0x9b, 0x56, 0x95, 0x6b, 0x8f, + 0x78, 0x8b, 0x7e, 0x8b, 0x7d, 0x88, 0x87, 0x7b, 0x86, 0x84, 0x89, 0x81, + 0x85, 0x84, 0x84, 0x83, 0x85, 0x85, 0x88, 0x88, 0x8b, 0x81, 0x8b, 0x72, + 0x9f, 0x72, 0xa8, 0x08, 0x54, 0xca, 0x71, 0x9c, 0x68, 0x8b, 0x6d, 0x8b, + 0x70, 0x71, 0x8b, 0x6e, 0x8b, 0x73, 0x9a, 0x73, 0xa1, 0x7e, 0xa0, 0x7e, + 0xa1, 0x84, 0xc2, 0x80, 0xbc, 0x81, 0xa5, 0x7f, 0x8b, 0x7e, 0x8b, 0x88, + 0x8a, 0x88, 0x8a, 0x85, 0x08, 0x8a, 0x88, 0x8b, 0x86, 0x8b, 0x85, 0x8b, + 0x85, 0x8b, 0x86, 0x8c, 0x87, 0x8c, 0x86, 0x8c, 0x87, 0x8b, 0x89, 0x8b, + 0x7e, 0x70, 0x7e, 0x5b, 0x82, 0x55, 0x80, 0x74, 0x84, 0x76, 0x7e, 0x75, + 0x7e, 0x7c, 0x73, 0x8b, 0x73, 0x08, 0x6e, 0xa6, 0x71, 0xa9, 0x1e, 0xaf, + 0x8b, 0xa5, 0x9d, 0xc1, 0xc9, 0x08, 0xa5, 0xa8, 0xa2, 0x9e, 0x96, 0x8c, + 0x08, 0xe1, 0xf7, 0x2d, 0x15, 0xb4, 0xab, 0x6a, 0x61, 0x63, 0x6a, 0x6a, + 0x63, 0x63, 0x6a, 0xac, 0xb4, 0xb4, 0xac, 0xac, 0xb3, 0x1f, 0x0e, 0xfb, + 0x31, 0xf7, 0xf3, 0xf7, 0xdb, 0x15, 0xb6, 0x72, 0x9d, 0x79, 0xce, 0x34, + 0xac, 0x5f, 0xa3, 0x7c, 0xab, 0x8b, 0xa6, 0x8b, 0x9d, 0x93, 0xa9, 0xa4, + 0x8e, 0x9a, 0x8c, 0x98, 0x8b, 0x94, 0x8b, 0x9e, 0x84, 0x9f, 0x7d, 0x9c, + 0x7c, 0x9f, 0x71, 0x95, 0x5c, 0x91, 0x08, 0x21, 0x99, 0x6f, 0x92, 0x61, + 0xa3, 0xb3, 0xa3, 0xab, 0x93, 0xf3, 0x99, 0xb4, 0x90, 0xa7, 0x95, 0x99, + 0x9a, 0x9b, 0x9c, 0x95, 0xa3, 0x8b, 0xa0, 0x8b, 0x94, 0x8a, 0x98, 0x88, + 0x9a, 0x6d, 0xa4, 0x79, 0x93, 0x70, 0x8b, 0x08, 0x6b, 0x8b, 0x73, 0x7c, + 0x6a, 0x5f, 0x4a, 0x36, 0x76, 0x75, 0x61, 0x73, 0x8b, 0xbb, 0x93, 0xa9, + 0xb4, 0xed, 0x97, 0xa7, 0x91, 0xa3, 0x8b, 0x9e, 0x8b, 0x9c, 0x81, 0xa0, + 0x7d, 0x9b, 0x7e, 0x98, 0x7f, 0x92, 0x6f, 0x95, 0x08, 0x74, 0x83, 0x7f, + 0x85, 0x81, 0x82, 0x78, 0x7b, 0x7e, 0x71, 0x8b, 0x78, 0x8b, 0x78, 0x91, + 0x73, 0x97, 0x6f, 0xb3, 0x2a, 0x94, 0x6c, 0x8b, 0x5b, 0x61, 0xa3, 0x76, + 0xa1, 0x4a, 0xe0, 0x6a, 0xb7, 0x73, 0x9a, 0x6b, 0x8b, 0x08, 0x70, 0x8b, + 0x79, 0x83, 0x6d, 0x72, 0x88, 0x7c, 0x8a, 0x7e, 0x8b, 0x82, 0x8b, 0x78, + 0x92, 0x77, 0x99, 0x7a, 0x9a, 0x77, 0xa5, 0x81, 0xba, 0x85, 0xf4, 0x7d, + 0xa9, 0x83, 0xb4, 0x73, 0x5f, 0x72, 0x78, 0x86, 0xfb, 0x05, 0x7c, 0x08, + 0x62, 0x86, 0x6f, 0x81, 0x7d, 0x7c, 0x7b, 0x7a, 0x81, 0x73, 0x8b, 0x76, + 0x8b, 0x82, 0x8c, 0x7e, 0x8e, 0x7c, 0xa9, 0x72, 0x9c, 0x83, 0xa7, 0x8b, + 0xac, 0x8b, 0xa2, 0x9a, 0xac, 0xb7, 0xcc, 0xe0, 0xa0, 0xa1, 0xb5, 0xa2, + 0x08, 0x8b, 0x5c, 0x82, 0x6c, 0x63, 0x2a, 0x7f, 0x6f, 0x85, 0x73, 0x8b, + 0x78, 0x8b, 0x7a, 0x95, 0x76, 0x99, 0x7b, 0x98, 0x7e, 0x97, 0x84, 0xa7, + 0x81, 0xa2, 0x93, 0x97, 0x91, 0x95, 0x94, 0x9e, 0x9b, 0x98, 0xa4, 0x8b, + 0x9f, 0x08, 0x8b, 0x9e, 0x85, 0xa3, 0x7f, 0xa7, 0x62, 0xed, 0x83, 0xa9, + 0x8b, 0xba, 0x08, 0x0e, 0xfb, 0x1e, 0xf7, 0xdc, 0xf8, 0x1a, 0x15, 0x28, + 0xf7, 0x11, 0x05, 0x72, 0xaa, 0x65, 0x9f, 0x69, 0x8b, 0x74, 0x8b, 0x70, + 0x81, 0x5e, 0x74, 0x8a, 0x77, 0x8a, 0x7b, 0x8b, 0x7c, 0x8b, 0x46, 0xaf, + 0x65, 0xd4, 0x83, 0x08, 0xf7, 0x36, 0x78, 0xfb, 0x36, 0x78, 0x05, 0x42, + 0x83, 0x67, 0x65, 0x8b, 0x46, 0x8b, 0x7c, 0x8c, 0x7a, 0x8c, 0x78, 0xb5, + 0x74, 0xa9, 0x80, 0x9d, 0x8b, 0xab, 0x8b, 0xbb, 0xa3, 0xa1, 0xa7, 0x08, + 0xee, 0xf7, 0x10, 0x4a, 0xfb, 0x22, 0x05, 0x80, 0x72, 0x86, 0x76, 0x8b, + 0x78, 0x8b, 0x5d, 0xa8, 0x6c, 0xd5, 0x69, 0xd7, 0xad, 0xa8, 0xab, 0x8b, + 0xba, 0x8b, 0xa0, 0x88, 0x96, 0x7d, 0xaa, 0x08, 0x4a, 0xf7, 0x22, 0xee, + 0xfb, 0x10, 0x05, 0xa2, 0x6e, 0xb9, 0x74, 0xae, 0x8b, 0x9a, 0x8b, 0xaa, + 0x97, 0xb5, 0xa1, 0x8c, 0x9e, 0x8c, 0x9b, 0x8b, 0x9a, 0x8b, 0xd1, 0x67, + 0xb1, 0x42, 0x93, 0x08, 0xfb, 0x36, 0x9e, 0xf7, 0x36, 0x9e, 0x05, 0xaf, + 0x8f, 0xaa, 0x98, 0x9a, 0x9b, 0x9c, 0x9f, 0x95, 0xa9, 0x8b, 0xab, 0x8b, + 0x9a, 0x8a, 0x9b, 0x8a, 0x9f, 0x5f, 0xa2, 0x70, 0x95, 0x74, 0x8b, 0x69, + 0x8b, 0x64, 0x77, 0x72, 0x6c, 0x08, 0x28, 0xfb, 0x11, 0xcc, 0xf7, 0x23, + 0x05, 0x95, 0xa2, 0x91, 0xa3, 0x8b, 0x9f, 0x8b, 0xb6, 0x6d, 0xaa, 0x41, + 0xad, 0x42, 0x69, 0x6d, 0x6c, 0x8b, 0x60, 0x8b, 0x77, 0x91, 0x73, 0x95, + 0x74, 0x08, 0xcc, 0xfb, 0x23, 0x05, 0xa2, 0x78, 0x15, 0x97, 0x95, 0x81, + 0x7f, 0x7e, 0x81, 0x81, 0x7e, 0x7f, 0x81, 0x95, 0x98, 0x97, 0x95, 0x95, + 0x98, 0x1f, 0x93, 0x9e, 0x15, 0x7a, 0x8b, 0x55, 0xf7, 0x2d, 0x05, 0x86, + 0x9a, 0x88, 0x9b, 0x8b, 0x9c, 0x8b, 0xbb, 0xa0, 0xa7, 0xbc, 0x9d, 0xbd, + 0x79, 0xa0, 0x6f, 0x8b, 0x5b, 0x8b, 0x7a, 0x88, 0x7c, 0x86, 0x7b, 0x08, + 0x55, 0xfb, 0x2d, 0x05, 0x5f, 0x43, 0x15, 0x21, 0xfb, 0x10, 0x05, 0x74, + 0x70, 0x6d, 0x7b, 0x72, 0x8b, 0x72, 0x8b, 0x78, 0x92, 0x6f, 0x9f, 0x8a, + 0x96, 0x8a, 0x96, 0x8b, 0x92, 0x8b, 0xbd, 0xae, 0xb2, 0xc0, 0x94, 0x08, + 0xf7, 0x35, 0xa6, 0x94, 0x7d, 0x05, 0xd2, 0x16, 0x94, 0x99, 0xf7, 0x35, + 0x70, 0x05, 0xc0, 0x82, 0xae, 0x64, 0x8b, 0x59, 0x8b, 0x84, 0x8a, 0x80, + 0x8a, 0x80, 0x6f, 0x77, 0x78, 0x84, 0x72, 0x8b, 0x73, 0x8b, 0x6b, 0x9c, + 0x75, 0xa5, 0x08, 0x21, 0xf7, 0x10, 0x05, 0x0e, 0x7e, 0xf8, 0x31, 0xf7, + 0x38, 0x15, 0x91, 0x90, 0x87, 0x85, 0x1f, 0x8b, 0x8a, 0x8b, 0x89, 0x8a, + 0x88, 0x89, 0x86, 0x8a, 0x84, 0x8b, 0x86, 0x8b, 0x78, 0x94, 0x67, 0x95, + 0x77, 0xa2, 0x5d, 0xb6, 0x6f, 0xba, 0x8b, 0xd9, 0x8b, 0xd5, 0xd0, 0x8b, + 0xd4, 0x8b, 0xc2, 0x68, 0xba, 0x4f, 0xa8, 0x08, 0x7f, 0x91, 0x84, 0x8c, + 0x81, 0x8c, 0x08, 0x83, 0x86, 0x8f, 0x91, 0x91, 0x90, 0x91, 0x91, 0x1f, + 0x8d, 0x8b, 0x8d, 0x8a, 0x8f, 0x88, 0x9a, 0x82, 0xa1, 0x86, 0xab, 0x8b, + 0x08, 0xda, 0xc4, 0xc0, 0xd7, 0xde, 0x4f, 0xcf, 0x42, 0x1f, 0x62, 0x8b, + 0x64, 0x78, 0x67, 0x65, 0x83, 0x82, 0x86, 0x85, 0x88, 0x82, 0x89, 0x84, + 0x88, 0x88, 0x86, 0x8b, 0x85, 0x8b, 0x85, 0x90, 0x8b, 0x91, 0x8b, 0x8f, + 0x8c, 0x8d, 0x90, 0x8f, 0xa2, 0x9d, 0x9f, 0xbe, 0x8b, 0xb4, 0x08, 0xd6, + 0x50, 0xc1, 0x3a, 0x3a, 0x50, 0x55, 0x40, 0x1e, 0x8b, 0x63, 0x9f, 0x57, + 0xa2, 0x79, 0x90, 0x87, 0x8c, 0x89, 0x8b, 0x87, 0x8b, 0x86, 0x85, 0x85, + 0x86, 0x8b, 0x85, 0x8b, 0x88, 0x8e, 0x89, 0x92, 0x7d, 0xb3, 0x48, 0xb4, + 0x58, 0x8b, 0x08, 0x42, 0x4f, 0x47, 0x38, 0x3f, 0xc4, 0x56, 0xdb, 0x1f, + 0xaa, 0x8b, 0xa1, 0x90, 0x9a, 0x94, 0x8f, 0x8e, 0x8d, 0x8c, 0x8d, 0x8b, + 0x08, 0x91, 0x90, 0x85, 0x85, 0x85, 0x86, 0x87, 0x83, 0x1f, 0x81, 0x8a, + 0x84, 0x89, 0x7f, 0x86, 0x4f, 0x6f, 0x68, 0x5a, 0x8b, 0x55, 0x8b, 0x43, + 0xd5, 0x45, 0xd8, 0x8b, 0xb8, 0x8b, 0xb4, 0xa4, 0xa3, 0xb4, 0x97, 0xa0, + 0x96, 0xb4, 0x8b, 0xa0, 0x8b, 0x8f, 0x8a, 0x93, 0x89, 0x90, 0x08, 0x8a, + 0x8e, 0x8b, 0x8d, 0x8b, 0x8c, 0x08, 0x90, 0x90, 0x90, 0x91, 0x1e, 0x8d, + 0xf7, 0xac, 0x15, 0xc9, 0xc0, 0x56, 0x4b, 0x4b, 0x56, 0x56, 0x4b, 0x4a, + 0x57, 0xc0, 0xcc, 0xcc, 0xc0, 0xbe, 0xcd, 0x1f, 0x0e, 0x73, 0xf7, 0xcf, + 0xf8, 0x53, 0x15, 0x48, 0xca, 0x67, 0x9e, 0x5b, 0x8b, 0x08, 0x44, 0x51, + 0x51, 0x44, 0x3a, 0xc8, 0x56, 0xe9, 0x1f, 0x9b, 0x8b, 0x9d, 0x8c, 0xad, + 0x90, 0x5b, 0x6f, 0x75, 0x7c, 0x77, 0x77, 0x71, 0x70, 0x7d, 0x69, 0x8b, + 0x69, 0x8b, 0x43, 0xc5, 0x51, 0xd3, 0x8b, 0xb7, 0x8b, 0xb4, 0xa2, 0xa5, + 0xb3, 0x9c, 0xa6, 0x94, 0xa6, 0x97, 0xc9, 0x08, 0x98, 0x4f, 0x93, 0x71, + 0x9b, 0x70, 0xa4, 0x62, 0xb5, 0x72, 0xb9, 0x8b, 0xd3, 0x8b, 0xc5, 0xc5, + 0x8b, 0xd3, 0x8b, 0xad, 0x7d, 0xad, 0x70, 0xa6, 0x78, 0x9f, 0x75, 0x9a, + 0x5b, 0xa7, 0xad, 0x86, 0x9d, 0x8a, 0x9b, 0x8b, 0x08, 0xe9, 0xc8, 0xc0, + 0xdc, 0xd1, 0x50, 0xc6, 0x45, 0x1f, 0x5b, 0x8b, 0x66, 0x77, 0x49, 0x4d, + 0xa7, 0xc9, 0x94, 0xa9, 0x8b, 0xad, 0x08, 0xd4, 0x52, 0xc6, 0x43, 0x43, + 0x51, 0x50, 0x42, 0x1e, 0x8b, 0x69, 0x94, 0x6d, 0xa7, 0x4d, 0x08, 0xd0, + 0x90, 0x15, 0x6a, 0x7e, 0x05, 0x6d, 0xb8, 0x82, 0xa3, 0x8b, 0xb3, 0x08, + 0xcb, 0xb3, 0xb9, 0xc3, 0xc2, 0xb3, 0x5d, 0x4b, 0x1e, 0x8b, 0x63, 0x82, + 0x72, 0x6d, 0x5f, 0x08, 0x6a, 0x98, 0x7d, 0xea, 0x05, 0x8a, 0x94, 0x87, + 0x8f, 0x86, 0x8b, 0x86, 0x8b, 0x88, 0x87, 0x8a, 0x82, 0x08, 0x7d, 0x2c, + 0x05, 0xf7, 0x0b, 0x62, 0x15, 0x9c, 0xa1, 0x93, 0x93, 0x95, 0x94, 0xa8, + 0xa3, 0xb1, 0x9a, 0xad, 0x8b, 0x08, 0xbf, 0xb5, 0x62, 0x58, 0x4f, 0x52, + 0x5d, 0x40, 0x1f, 0x79, 0x8b, 0x7e, 0x8d, 0x6b, 0x95, 0x08, 0x8d, 0xae, + 0xe1, 0xb6, 0x05, 0x92, 0x8e, 0x8e, 0x8f, 0x8b, 0x8f, 0x08, 0x90, 0x87, + 0x8e, 0x85, 0x1e, 0x89, 0x06, 0x8b, 0x89, 0x8a, 0x89, 0x1e, 0x2d, 0x7b, + 0x74, 0xa7, 0x05, 0x9f, 0xfb, 0x2e, 0x15, 0xad, 0x7f, 0x97, 0x85, 0x9c, + 0x7d, 0xae, 0x6f, 0xa2, 0x63, 0x8b, 0x67, 0x8b, 0x58, 0x62, 0x62, 0x58, + 0x8b, 0x65, 0x8b, 0x68, 0xa3, 0x73, 0xb5, 0x7a, 0xa8, 0x86, 0x9f, 0x8a, + 0xba, 0x08, 0xad, 0x94, 0xce, 0x46, 0x05, 0x8f, 0x87, 0x8f, 0x89, 0x8e, + 0x8b, 0x8f, 0x8b, 0x8f, 0x8f, 0x8b, 0x8f, 0x8b, 0x8c, 0x8a, 0x8e, 0x88, + 0x90, 0x08, 0x5f, 0xe0, 0x9e, 0xa9, 0x05, 0xfb, 0x7e, 0xf7, 0x12, 0x15, + 0x2d, 0x9b, 0x05, 0x86, 0x8c, 0x8b, 0x8b, 0x8a, 0x8b, 0x85, 0x8b, 0x87, + 0x88, 0x8b, 0x86, 0x8b, 0x87, 0x8e, 0x87, 0x92, 0x88, 0x08, 0xe1, 0x60, + 0x8d, 0x68, 0x05, 0x6b, 0x81, 0x7e, 0x89, 0x79, 0x8b, 0x08, 0x3f, 0x52, + 0xb9, 0xc7, 0xbe, 0xb6, 0xb4, 0xbf, 0x1f, 0xab, 0x8b, 0xae, 0x7e, 0xa8, + 0x75, 0x98, 0x81, 0x93, 0x82, 0x9e, 0x73, 0x08, 0x74, 0x6f, 0x05, 0xa3, + 0xfb, 0x29, 0x15, 0x5d, 0x2f, 0x05, 0x88, 0x86, 0x8a, 0x89, 0x8b, 0x89, + 0x8b, 0x87, 0x8f, 0x87, 0x8f, 0x8b, 0x8e, 0x8b, 0x8f, 0x8e, 0x8f, 0x8e, + 0x08, 0xce, 0xd0, 0xad, 0x82, 0x05, 0x8a, 0x5f, 0x87, 0x7a, 0x7e, 0x70, + 0x73, 0x5c, 0x66, 0x70, 0x62, 0x8b, 0x58, 0x8b, 0x62, 0xb4, 0x8b, 0xbe, + 0x8b, 0xaf, 0xa1, 0xb3, 0xaf, 0xa7, 0x9c, 0x99, 0x97, 0x91, 0xad, 0x97, + 0x08, 0xa0, 0x74, 0x05, 0x0e, 0x59, 0xf9, 0x22, 0xf7, 0x7d, 0x15, 0xac, + 0x93, 0x9e, 0x94, 0x98, 0x97, 0xa1, 0x9e, 0x98, 0xaa, 0x8b, 0xac, 0x8b, + 0xa8, 0x81, 0xa6, 0x7a, 0x9e, 0x7c, 0x9d, 0x78, 0x94, 0x64, 0x95, 0x9c, + 0xa7, 0x94, 0xa5, 0x8b, 0x9d, 0x8b, 0x9f, 0x7a, 0xac, 0x77, 0x9e, 0x08, + 0x77, 0x9f, 0x71, 0x96, 0x74, 0x8b, 0x7a, 0x8b, 0x78, 0x84, 0x6a, 0x79, + 0x81, 0xab, 0x83, 0x9d, 0x7e, 0x98, 0x76, 0xa0, 0x6d, 0x98, 0x6f, 0x8b, + 0x71, 0x8b, 0x73, 0x82, 0x76, 0x7a, 0x78, 0x7b, 0x82, 0x7a, 0x7f, 0x65, + 0x08, 0x6a, 0x9d, 0x78, 0x92, 0x7a, 0x8b, 0x74, 0x8b, 0x71, 0x80, 0x77, + 0x78, 0x78, 0x78, 0x79, 0x68, 0x8b, 0x78, 0x8b, 0x79, 0x94, 0x71, 0x9c, + 0x6f, 0x6a, 0x83, 0x78, 0x82, 0x7e, 0x7f, 0x75, 0x78, 0x7e, 0x6c, 0x8b, + 0x6a, 0x08, 0x8b, 0x6f, 0x95, 0x70, 0x9c, 0x77, 0x9a, 0x79, 0x9e, 0x82, + 0xb2, 0x81, 0x08, 0x7a, 0x6f, 0x82, 0x71, 0x8b, 0x7a, 0x8b, 0x77, 0x9c, + 0x69, 0x9f, 0x78, 0x9f, 0x78, 0xa5, 0x80, 0xa2, 0x8b, 0x9b, 0x8b, 0x9f, + 0x92, 0xac, 0x9c, 0x95, 0x6b, 0x93, 0x79, 0x98, 0x7e, 0xa1, 0x76, 0xa8, + 0x7e, 0xa7, 0x8b, 0x08, 0xa4, 0x8b, 0xa4, 0x94, 0xa0, 0x9c, 0x9e, 0x9b, + 0x95, 0x9c, 0x96, 0xb1, 0xac, 0x7a, 0x9e, 0x84, 0x9c, 0x8b, 0xa2, 0x8b, + 0xa5, 0x96, 0x9f, 0x9e, 0x9e, 0x9e, 0x9d, 0xad, 0x8b, 0x9f, 0x08, 0x8b, + 0x9c, 0x82, 0xa5, 0x7a, 0xa7, 0x08, 0xfb, 0x96, 0xf7, 0x5e, 0x15, 0xbb, + 0xb4, 0x62, 0x5a, 0x5a, 0x62, 0x62, 0x5a, 0x59, 0x62, 0xb4, 0xbc, 0x1f, + 0xbd, 0xb4, 0xb3, 0xbe, 0x1e, 0xa4, 0xfb, 0x63, 0x15, 0x96, 0x8d, 0xb4, + 0x21, 0x05, 0x8e, 0x82, 0x8d, 0x81, 0x8b, 0x82, 0x08, 0x5e, 0x65, 0x66, + 0x5d, 0x5e, 0x65, 0xb0, 0xb8, 0x1e, 0x8b, 0x94, 0x8d, 0x95, 0x8e, 0x94, + 0x08, 0xb4, 0xf5, 0x96, 0x89, 0x72, 0xfb, 0x01, 0x05, 0x8a, 0x86, 0x8b, + 0x88, 0x8b, 0x85, 0x08, 0x6c, 0xa3, 0x71, 0xa8, 0xa7, 0xa3, 0xa5, 0xaa, + 0x1e, 0x8b, 0x90, 0x8b, 0x8f, 0x8a, 0x90, 0x08, 0x72, 0xf7, 0x01, 0x05, + 0x30, 0x9b, 0x15, 0x95, 0x84, 0x5d, 0x24, 0x05, 0x7e, 0x6e, 0x6e, 0x79, + 0x6b, 0x8b, 0x5c, 0x8b, 0x65, 0xb1, 0x8b, 0xb9, 0x8b, 0xab, 0x9e, 0xa7, + 0xa8, 0x98, 0x08, 0xf3, 0xb9, 0x91, 0x82, 0x2c, 0x4f, 0x05, 0x7a, 0x80, + 0x80, 0x77, 0x8b, 0x78, 0x8b, 0x6e, 0xa1, 0x75, 0xa7, 0x8b, 0x9f, 0x8b, + 0x9e, 0x96, 0x96, 0x9d, 0x08, 0xc7, 0xea, 0x05, 0x57, 0xd6, 0x15, 0x8d, + 0x7f, 0x21, 0x63, 0x05, 0x82, 0x88, 0x82, 0x89, 0x81, 0x8b, 0x08, 0x5e, + 0x66, 0xb1, 0xb8, 0xb8, 0xb0, 0xb1, 0xb8, 0x1f, 0x95, 0x8b, 0x94, 0x8a, + 0x94, 0x87, 0x08, 0xf5, 0x63, 0x89, 0x7f, 0xfb, 0x02, 0xa4, 0x05, 0x86, + 0x8c, 0x86, 0x8c, 0x87, 0x8b, 0x08, 0x6c, 0x71, 0x73, 0x6e, 0x6e, 0xa5, + 0x73, 0xaa, 0x1f, 0x8f, 0x8b, 0x90, 0x8c, 0x90, 0x8c, 0x08, 0xf7, 0x02, + 0xa4, 0x05, 0x9a, 0xe5, 0x15, 0x85, 0x82, 0x23, 0xb9, 0x05, 0x6e, 0x98, + 0x79, 0xa7, 0x8b, 0xac, 0x8b, 0xb9, 0xb1, 0xb1, 0xb9, 0x8b, 0xab, 0x8b, + 0xa8, 0x79, 0x98, 0x6d, 0x08, 0xb9, 0x24, 0x81, 0x84, 0x50, 0xea, 0x05, + 0x7f, 0x9d, 0x78, 0x96, 0x77, 0x8b, 0x6f, 0x8b, 0x74, 0x74, 0x8b, 0x6f, + 0x8b, 0x78, 0x96, 0x77, 0x9d, 0x80, 0x08, 0xea, 0x4f, 0x05, 0xd6, 0xc0, + 0x15, 0x80, 0x89, 0x62, 0xf5, 0x05, 0x88, 0x94, 0x89, 0x95, 0x8b, 0x94, + 0x08, 0xb8, 0xb1, 0xb0, 0xb9, 0xb8, 0xb1, 0x66, 0x5e, 0x1e, 0x8b, 0x82, + 0x89, 0x81, 0x88, 0x82, 0x08, 0x62, 0x21, 0x80, 0x8d, 0xa4, 0xf7, 0x02, + 0x05, 0x8c, 0x8f, 0x8b, 0x8e, 0x8b, 0x91, 0x08, 0xaa, 0x73, 0xa5, 0x6e, + 0x6f, 0x73, 0x71, 0x6c, 0x1e, 0x8b, 0x86, 0x8b, 0x87, 0x8c, 0x87, 0x08, + 0xa4, 0xfb, 0x02, 0x05, 0xe6, 0x7b, 0x15, 0x81, 0x92, 0xb9, 0xf2, 0x05, + 0x98, 0xa9, 0xa8, 0x9d, 0xac, 0x8b, 0xb9, 0x8b, 0xb1, 0x65, 0x8b, 0x5d, + 0x8b, 0x6b, 0x78, 0x6e, 0x6e, 0x7e, 0x08, 0x23, 0x5d, 0x85, 0x94, 0xea, + 0xc7, 0x05, 0x9c, 0x96, 0x96, 0x9f, 0x8b, 0x9f, 0x8b, 0xa7, 0x74, 0xa2, + 0x6f, 0x8b, 0x78, 0x8b, 0x78, 0x80, 0x80, 0x78, 0x08, 0x4f, 0x2c, 0x05, + 0xbf, 0x40, 0x15, 0x89, 0x97, 0xf5, 0xb3, 0x05, 0x95, 0x8f, 0x95, 0x8d, + 0x94, 0x8b, 0x08, 0xb7, 0xb0, 0x65, 0x5d, 0x5e, 0x66, 0x65, 0x5e, 0x1f, + 0x81, 0x8b, 0x82, 0x8d, 0x82, 0x8e, 0x08, 0x21, 0xb3, 0x8d, 0x97, 0xf7, + 0x02, 0x72, 0x05, 0x90, 0x8a, 0x91, 0x8a, 0x8e, 0x8b, 0x08, 0xaa, 0xa5, + 0xa3, 0xa8, 0xa8, 0x71, 0xa3, 0x6c, 0x1f, 0x87, 0x8b, 0x86, 0x8a, 0x86, + 0x8a, 0x08, 0xfb, 0x02, 0x72, 0x05, 0x7c, 0x31, 0x15, 0x91, 0x94, 0xf3, + 0x5d, 0x05, 0xa8, 0x7e, 0x9d, 0x6f, 0x8b, 0x6b, 0x8b, 0x5d, 0x65, 0x65, + 0x5d, 0x8b, 0x6b, 0x8b, 0x6e, 0x9e, 0x7e, 0xa7, 0x08, 0x5d, 0xf2, 0x95, + 0x92, 0xc7, 0x2c, 0x05, 0x95, 0x7a, 0x9f, 0x80, 0x9f, 0x8b, 0xa7, 0x8b, + 0xa2, 0xa1, 0x8b, 0xa7, 0x8b, 0x9f, 0x80, 0x9e, 0x79, 0x96, 0x08, 0x2c, + 0xc7, 0x05, 0x0e, 0x59, 0xf8, 0x23, 0xf9, 0x54, 0x15, 0xfb, 0x5f, 0xfb, + 0x35, 0xfb, 0x33, 0xfb, 0x5d, 0xfb, 0x59, 0xf7, 0x36, 0xfb, 0x35, 0xf7, + 0x5a, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5a, 0x1f, 0xf7, 0x58, + 0xfb, 0x35, 0xf7, 0x37, 0xfb, 0x56, 0x1e, 0x86, 0x82, 0x15, 0xd0, 0xfb, + 0x38, 0x05, 0x72, 0x94, 0x79, 0x8e, 0x71, 0x8b, 0x72, 0x8b, 0x79, 0x88, + 0x72, 0x82, 0x08, 0xcf, 0xf7, 0x38, 0x05, 0xfd, 0x4f, 0x04, 0x47, 0xf7, + 0x38, 0x05, 0xa3, 0x81, 0x9e, 0x88, 0xa5, 0x8b, 0xa4, 0x8b, 0x9e, 0x8e, + 0xa3, 0x95, 0x08, 0x46, 0xfb, 0x38, 0x05, 0xf7, 0x8c, 0xf8, 0xe8, 0x15, + 0x47, 0xfb, 0x38, 0x05, 0x7a, 0xb3, 0x63, 0xb3, 0x63, 0x9c, 0x08, 0xf7, + 0x39, 0xce, 0x05, 0xfc, 0x83, 0xfc, 0x82, 0x15, 0xcf, 0xf7, 0x39, 0x05, + 0x9c, 0x62, 0xb3, 0x63, 0xb3, 0x7a, 0x08, 0xfb, 0x39, 0x48, 0x05, 0xf8, + 0xe9, 0xf7, 0x8b, 0x15, 0xfb, 0x38, 0x46, 0x05, 0x94, 0xa3, 0x8e, 0x9e, + 0x8b, 0xa5, 0x8b, 0xa6, 0x88, 0x9d, 0x82, 0xa3, 0x08, 0xf7, 0x38, 0x46, + 0x05, 0xfd, 0x4f, 0x16, 0xf7, 0x38, 0xd0, 0x05, 0x82, 0x73, 0x88, 0x79, + 0x8b, 0x70, 0x8b, 0x71, 0x8e, 0x78, 0x94, 0x73, 0x08, 0xfb, 0x38, 0xd0, + 0x05, 0xf1, 0xf7, 0x8b, 0x15, 0xf7, 0x39, 0x48, 0x05, 0x63, 0x7a, 0x63, + 0x63, 0x7a, 0x63, 0x08, 0x47, 0xf7, 0x38, 0x05, 0xf8, 0x83, 0xfc, 0x82, + 0x15, 0xfb, 0x39, 0xce, 0x05, 0xb3, 0x9c, 0xb3, 0xb3, 0x9c, 0xb4, 0x08, + 0xcf, 0xfb, 0x39, 0x05, 0xfb, 0x8a, 0xf8, 0x37, 0x15, 0xe7, 0xd9, 0x3c, + 0x2d, 0x2d, 0x3e, 0x3e, 0x2d, 0x2d, 0x3d, 0xd9, 0xe9, 0xeb, 0xd7, 0xd7, + 0xec, 0x1f, 0x0e, 0xfb, 0x18, 0xf7, 0xe6, 0xf8, 0x15, 0x15, 0x20, 0xf7, + 0x20, 0x4d, 0xc3, 0x58, 0x8b, 0x7a, 0x8b, 0x72, 0x7d, 0x69, 0x6e, 0x85, + 0x74, 0x88, 0x74, 0x8b, 0x7a, 0x8b, 0x47, 0xc5, 0x74, 0xf7, 0x7b, 0x71, + 0xfb, 0x68, 0x72, 0x40, 0x6a, 0x8b, 0x4a, 0x8b, 0x7d, 0x8e, 0x76, 0x8f, + 0x76, 0x08, 0xb0, 0x69, 0xa4, 0x7c, 0xa1, 0x8b, 0xbb, 0x8b, 0xbe, 0xbb, + 0xf7, 0x05, 0xf7, 0x2e, 0x56, 0xfb, 0x0f, 0x77, 0x48, 0x8b, 0x53, 0x8b, + 0x61, 0xa2, 0x74, 0xcc, 0x76, 0xcf, 0x9e, 0xa9, 0xa4, 0x8b, 0xb3, 0x8b, + 0xbb, 0x75, 0xcf, 0x4f, 0xf7, 0x18, 0x08, 0xf5, 0xfb, 0x1f, 0xca, 0x52, + 0xbe, 0x8b, 0x9c, 0x8b, 0xa4, 0x99, 0xad, 0xa8, 0x91, 0xa2, 0x8e, 0xa2, + 0x8b, 0x9c, 0x8b, 0xcf, 0x4f, 0xa3, 0xfb, 0x79, 0xa3, 0xf7, 0x68, 0xa6, + 0xd6, 0xab, 0x8b, 0xcc, 0x8b, 0x99, 0x88, 0xa0, 0x87, 0xa0, 0x08, 0x66, + 0xad, 0x72, 0x9a, 0x75, 0x8b, 0x5b, 0x8b, 0x58, 0x5a, 0xfb, 0x05, 0xfb, + 0x2d, 0x08, 0xbf, 0xf7, 0x0d, 0xa0, 0xd0, 0x8b, 0xc2, 0x8b, 0xb6, 0x73, + 0xa3, 0x4b, 0x9f, 0x47, 0x78, 0x6d, 0x71, 0x8b, 0x64, 0x08, 0x8b, 0x5b, + 0xa2, 0x45, 0xc6, 0xfb, 0x16, 0x08, 0x9b, 0x90, 0x15, 0x52, 0xf7, 0x13, + 0x7a, 0xbf, 0x8b, 0xc1, 0x8b, 0xba, 0x9d, 0x9c, 0xc3, 0x92, 0x08, 0xfb, + 0xc4, 0x07, 0xa6, 0x7b, 0x15, 0xc2, 0xd4, 0xa2, 0xa7, 0xa7, 0xa8, 0xb1, + 0xb2, 0xb0, 0xa1, 0xa7, 0x8b, 0x9d, 0x8b, 0x9a, 0x81, 0xa1, 0x6e, 0x08, + 0xfb, 0x9c, 0xfb, 0x2c, 0x05, 0x6c, 0x04, 0xf7, 0x01, 0x7e, 0xb7, 0x83, + 0xb2, 0x7e, 0xc2, 0x79, 0xa9, 0x71, 0x8b, 0x70, 0x8b, 0x7e, 0x87, 0x7b, + 0x82, 0x78, 0x08, 0xfb, 0x9c, 0xf7, 0x2d, 0x05, 0x6f, 0x7b, 0x15, 0xc4, + 0xfb, 0x13, 0x9c, 0x57, 0x8b, 0x55, 0x8b, 0x5c, 0x79, 0x7a, 0x53, 0x83, + 0x08, 0xf7, 0xc5, 0x07, 0x70, 0x9b, 0x15, 0x53, 0x41, 0x74, 0x6e, 0x70, + 0x70, 0x65, 0x64, 0x66, 0x75, 0x6f, 0x8b, 0x79, 0x8b, 0x7c, 0x95, 0x75, + 0xa7, 0x08, 0xf7, 0x9c, 0xf7, 0x2d, 0x05, 0xaa, 0x04, 0xfb, 0x03, 0x98, + 0x61, 0x93, 0x64, 0x98, 0x54, 0x9d, 0x6d, 0xa5, 0x8b, 0xa6, 0x8b, 0x97, + 0x8f, 0x9c, 0x94, 0x9d, 0x08, 0xf7, 0x9c, 0xfb, 0x2c, 0x05, 0x0e, 0xfb, + 0x2c, 0xf8, 0x0e, 0xf7, 0xec, 0x15, 0xf7, 0x20, 0xdc, 0xf7, 0x02, 0x54, + 0x9f, 0xa5, 0x2a, 0xbb, 0xef, 0xc3, 0x79, 0xab, 0x28, 0x50, 0x92, 0xf7, + 0x00, 0x6a, 0x87, 0x84, 0xfb, 0x0f, 0xfb, 0x20, 0x3a, 0x8b, 0xf7, 0x36, + 0xf2, 0xcf, 0x7e, 0xa9, 0x31, 0x50, 0x05, 0x8d, 0xf7, 0x06, 0x65, 0x8b, + 0x8d, 0xfb, 0x06, 0x31, 0xc6, 0x7e, 0x6d, 0xf2, 0x47, 0x8b, 0xfb, 0x36, + 0xfb, 0x20, 0xdc, 0x84, 0xf7, 0x0f, 0x6a, 0x8f, 0x92, 0xfb, 0x00, 0x28, + 0xc6, 0x78, 0x6b, 0xf0, 0x53, 0x2a, 0x5b, 0x05, 0x9f, 0x71, 0xf7, 0x02, + 0xc2, 0xf7, 0x20, 0x3a, 0xfb, 0x20, 0x3a, 0xfb, 0x02, 0xc2, 0x77, 0x71, + 0xec, 0x5b, 0x26, 0x53, 0x9e, 0x6b, 0xee, 0xc5, 0x84, 0x20, 0xac, 0x8f, + 0x92, 0xf7, 0x0f, 0xf7, 0x20, 0xdc, 0x8b, 0xfb, 0x36, 0x05, 0x24, 0x47, + 0x98, 0x6d, 0xe5, 0xc6, 0x89, 0xfb, 0x06, 0xb1, 0x8b, 0x89, 0xf7, 0x06, + 0xe5, 0x50, 0x98, 0xa9, 0x24, 0xcf, 0x8b, 0xf7, 0x36, 0xf7, 0x20, 0x3a, + 0x92, 0xfb, 0x0f, 0xac, 0x87, 0x84, 0xf6, 0xee, 0x51, 0x05, 0x9d, 0xab, + 0x27, 0xc3, 0xec, 0xbb, 0x77, 0xa5, 0xfb, 0x02, 0x54, 0xfb, 0x20, 0xdc, + 0x05, 0x0e, 0xfb, 0x23, 0xf7, 0x57, 0xf8, 0xf7, 0x15, 0x8a, 0xfb, 0x2c, + 0xfb, 0x12, 0xdf, 0x05, 0x8a, 0x8c, 0x8a, 0x8b, 0x8a, 0x8b, 0x89, 0x8b, + 0x88, 0x88, 0x8a, 0x88, 0x08, 0x83, 0x77, 0x7d, 0x7a, 0x05, 0x8a, 0x8a, + 0x8a, 0x88, 0x8b, 0x89, 0x08, 0x8a, 0x8d, 0x88, 0x8c, 0x1e, 0xf7, 0x1c, + 0x47, 0xfb, 0x18, 0x3e, 0xf7, 0x18, 0x3f, 0xfb, 0x1c, 0x47, 0x05, 0x89, + 0x8a, 0x8a, 0x8a, 0x8b, 0x8a, 0x8b, 0x89, 0x8c, 0x87, 0x8c, 0x8a, 0x08, + 0x99, 0x7a, 0x93, 0x77, 0x05, 0x8c, 0x88, 0x8e, 0x88, 0x8d, 0x8b, 0x8c, + 0x8b, 0x8c, 0x8b, 0x8c, 0x8c, 0x08, 0xf7, 0x12, 0xdf, 0x8c, 0xfb, 0x2c, + 0xf7, 0x18, 0xd6, 0x82, 0xfb, 0x2b, 0x05, 0x87, 0x8d, 0x89, 0x92, 0x1e, + 0xa0, 0x8f, 0xa0, 0x87, 0x05, 0x92, 0x8d, 0x8d, 0x8f, 0x1f, 0x82, 0xf7, + 0x2b, 0xf7, 0x18, 0x40, 0x8c, 0xf7, 0x2c, 0xf7, 0x11, 0x37, 0x05, 0x8d, + 0x8a, 0x8c, 0x8b, 0x8c, 0x8b, 0x8d, 0x8b, 0x8e, 0x8e, 0x8c, 0x8e, 0x08, + 0x93, 0x9f, 0x99, 0x9c, 0x05, 0x8c, 0x8c, 0x8c, 0x8e, 0x8b, 0x8d, 0x8b, + 0x8d, 0x8a, 0x8c, 0x89, 0x8c, 0x08, 0xfb, 0x1c, 0xcf, 0xf7, 0x18, 0xd7, + 0xfb, 0x18, 0xd8, 0xf7, 0x1c, 0xcf, 0x05, 0x8c, 0x8d, 0x8d, 0x8c, 0x1f, + 0x8b, 0x8d, 0x8a, 0x8f, 0x8a, 0x8c, 0x08, 0x7d, 0x9c, 0x83, 0x9f, 0x05, + 0x8a, 0x8e, 0x88, 0x8e, 0x89, 0x8b, 0x8a, 0x8b, 0x8a, 0x8b, 0x89, 0x8a, + 0x08, 0xfb, 0x11, 0x37, 0x8a, 0xf7, 0x2c, 0xfb, 0x18, 0x40, 0x94, 0xf7, + 0x2b, 0x05, 0x8b, 0x8f, 0x89, 0x8c, 0x86, 0x8c, 0x08, 0x89, 0x8b, 0x76, + 0x87, 0x76, 0x8f, 0x89, 0x8b, 0x05, 0x86, 0x89, 0x89, 0x87, 0x1f, 0x94, + 0xfb, 0x2b, 0xfb, 0x18, 0xd6, 0x05, 0x9f, 0x69, 0x15, 0xf7, 0x06, 0x4a, + 0x8b, 0xfb, 0x19, 0xfb, 0x06, 0xce, 0x8b, 0xf7, 0x17, 0x05, 0xf7, 0x9e, + 0x16, 0x8b, 0xfb, 0x17, 0xfb, 0x06, 0x49, 0x8b, 0xf7, 0x18, 0xf7, 0x06, + 0xcc, 0x05, 0xf7, 0x19, 0xfb, 0x7b, 0x15, 0xfb, 0x05, 0x4a, 0xfb, 0x07, + 0xcc, 0xf7, 0x07, 0xcd, 0xf7, 0x05, 0x49, 0x05, 0xfb, 0x19, 0xfb, 0x7a, + 0x15, 0xfb, 0x06, 0xcc, 0x8b, 0xf7, 0x19, 0xf7, 0x06, 0x48, 0x8b, 0xfb, + 0x17, 0x05, 0xfb, 0x9e, 0x16, 0x8b, 0xf7, 0x17, 0xf7, 0x06, 0xcd, 0x8b, + 0xfb, 0x18, 0xfb, 0x06, 0x4a, 0x05, 0xfb, 0x19, 0xf7, 0x7a, 0x15, 0xf7, + 0x05, 0xcd, 0xf7, 0x07, 0x49, 0xfb, 0x07, 0x4a, 0xfb, 0x05, 0xcc, 0x05, + 0x0e, 0xfb, 0x2a, 0xf8, 0x06, 0xf7, 0xe9, 0x15, 0xf4, 0xc8, 0xf7, 0x32, + 0x69, 0xa1, 0xbb, 0x28, 0xaa, 0xe7, 0xbc, 0x7a, 0xa9, 0x33, 0x53, 0xa1, + 0xf1, 0x57, 0x8f, 0x59, 0xfb, 0x2e, 0x22, 0x50, 0x89, 0xf7, 0x0d, 0xf7, + 0x01, 0xf7, 0x0c, 0x6d, 0xb6, 0x3e, 0x45, 0x05, 0x8f, 0xf3, 0x69, 0x8b, + 0x8f, 0x23, 0x3e, 0xd1, 0x6d, 0x60, 0xf7, 0x01, 0xfb, 0x0c, 0x89, 0xfb, + 0x0d, 0x22, 0xc6, 0x59, 0xf7, 0x2e, 0x57, 0x87, 0xa1, 0x25, 0x33, 0xc3, + 0x7a, 0x6d, 0xe7, 0x5a, 0x28, 0x6c, 0x05, 0xa1, 0x5b, 0xf7, 0x32, 0xad, + 0xf4, 0x4e, 0x22, 0x4d, 0xfb, 0x32, 0xad, 0x75, 0x5b, 0xee, 0x6c, 0x2f, + 0x5a, 0x9c, 0x6d, 0xe3, 0xc3, 0x75, 0x25, 0xbf, 0x87, 0xbd, 0xf7, 0x2e, + 0xf4, 0xc6, 0x8d, 0xfb, 0x0d, 0x05, 0xfb, 0x01, 0xfb, 0x0c, 0xa9, 0x60, + 0xd8, 0xd1, 0x87, 0x23, 0xad, 0x8b, 0x87, 0xf3, 0xd8, 0x45, 0xa9, 0xb6, + 0xfb, 0x01, 0xf7, 0x0c, 0x8d, 0xf7, 0x0d, 0xf4, 0x50, 0xbd, 0xfb, 0x2e, + 0xbf, 0x8f, 0x75, 0xf1, 0xe3, 0x53, 0x05, 0x9c, 0xa9, 0x2f, 0xbc, 0xee, + 0xaa, 0x75, 0xbb, 0xfb, 0x32, 0x69, 0x22, 0xc9, 0x05, 0x0e, 0x56, 0xf7, + 0xc5, 0xf8, 0x32, 0x15, 0x92, 0x06, 0x94, 0x8e, 0x8d, 0x93, 0x1f, 0x8b, + 0x8c, 0x8b, 0x8f, 0x8a, 0x8e, 0x08, 0xfb, 0x61, 0xf7, 0x6e, 0x05, 0x7f, + 0x76, 0x88, 0x89, 0x77, 0x80, 0x08, 0xf7, 0x72, 0xfb, 0x5e, 0x05, 0xf7, + 0x43, 0xfb, 0x1f, 0x15, 0x84, 0x06, 0x82, 0x88, 0x89, 0x83, 0x1f, 0x8b, + 0x8a, 0x8b, 0x87, 0x8c, 0x88, 0x08, 0xf7, 0x61, 0xfb, 0x6e, 0x05, 0x97, + 0xa0, 0x8e, 0x8d, 0x9f, 0x96, 0x08, 0xfb, 0x72, 0xf7, 0x5e, 0x05, 0xfb, + 0x31, 0x79, 0x15, 0x92, 0x07, 0x93, 0x88, 0x8f, 0x85, 0x1e, 0x89, 0x8b, + 0x84, 0x8b, 0xfb, 0x6e, 0xfb, 0x62, 0x05, 0xa0, 0x7f, 0x8d, 0x88, 0x96, + 0x77, 0x08, 0xf7, 0x5e, 0xf7, 0x72, 0x05, 0xf7, 0x1f, 0xf7, 0x43, 0x15, + 0x84, 0x07, 0x82, 0x8d, 0x88, 0x93, 0x1e, 0x8c, 0x8b, 0x8f, 0x8b, 0x8e, + 0x8c, 0x08, 0xf7, 0x6e, 0xf7, 0x61, 0x05, 0x76, 0x97, 0x89, 0x8e, 0x80, + 0x9f, 0x08, 0xfb, 0x5e, 0xfb, 0x72, 0x05, 0x45, 0x6f, 0x15, 0x6a, 0x70, + 0x70, 0x6b, 0x6a, 0xa5, 0x70, 0xad, 0xab, 0xa6, 0xa6, 0xac, 0xab, 0x70, + 0xa6, 0x6b, 0x1f, 0xf7, 0xbf, 0x04, 0x85, 0x8b, 0x85, 0x89, 0x84, 0x88, + 0x6f, 0x7e, 0x88, 0x88, 0x8b, 0x7b, 0x8b, 0x31, 0x8f, 0x5d, 0x96, 0x6a, + 0x9c, 0x5a, 0x98, 0x6e, 0x91, 0x8b, 0x8e, 0x8b, 0x8f, 0x92, 0x95, 0xa1, + 0xa2, 0xc1, 0x95, 0xc8, 0x8b, 0xf0, 0x08, 0x8b, 0xa2, 0x82, 0x93, 0x61, + 0x93, 0x08, 0xfd, 0x61, 0x04, 0x92, 0x8b, 0x91, 0x8d, 0x92, 0x8e, 0xa7, + 0x97, 0x8e, 0x8f, 0x8b, 0x9b, 0x8b, 0xe5, 0x87, 0xb9, 0x80, 0xac, 0x7a, + 0xbc, 0x7e, 0xa8, 0x85, 0x8b, 0x88, 0x8b, 0x87, 0x85, 0x81, 0x74, 0x74, + 0x56, 0x81, 0x4d, 0x8b, 0x26, 0x08, 0x8b, 0x74, 0x95, 0x83, 0xb3, 0x83, + 0x08, 0xf7, 0xfb, 0xf7, 0xfc, 0x15, 0x8b, 0x93, 0x88, 0x93, 0x82, 0x9a, + 0x81, 0x9d, 0x8b, 0x8b, 0x7c, 0x8b, 0x30, 0x8b, 0x5e, 0x87, 0x6a, 0x80, + 0x5b, 0x7a, 0x6d, 0x7e, 0x8b, 0x85, 0x8b, 0x88, 0x92, 0x87, 0xa1, 0x81, + 0xc2, 0x73, 0xc7, 0x82, 0xf0, 0x8b, 0x08, 0xa2, 0x8b, 0x93, 0x95, 0x93, + 0xb4, 0x08, 0x8c, 0x07, 0xfd, 0x61, 0x88, 0x15, 0x8b, 0x83, 0x8e, 0x83, + 0x94, 0x7c, 0x95, 0x79, 0x8b, 0x8b, 0x9a, 0x8b, 0xe7, 0x8b, 0xb7, 0x8f, + 0xac, 0x96, 0xbc, 0x9c, 0xa8, 0x98, 0x8b, 0x91, 0x8b, 0x8e, 0x84, 0x8f, + 0x75, 0x95, 0x56, 0xa3, 0x4d, 0x94, 0x26, 0x8b, 0x08, 0x74, 0x8b, 0x83, + 0x81, 0x83, 0x63, 0x08, 0x89, 0x07, 0x0e, 0x57, 0xe0, 0xf9, 0x0d, 0x15, + 0xf7, 0x5b, 0xfb, 0x5b, 0x9f, 0xa0, 0xfb, 0x5a, 0xf7, 0x5b, 0x76, 0x76, + 0x05, 0xf8, 0xfd, 0xfc, 0xd5, 0x15, 0xfb, 0x5b, 0xf7, 0x5b, 0x77, 0x76, + 0xf7, 0x5a, 0xfb, 0x5b, 0xa0, 0xa0, 0x05, 0x76, 0xf8, 0xea, 0x15, 0xfb, + 0x5a, 0xfb, 0x5b, 0x9f, 0x76, 0xf7, 0x5b, 0xf7, 0x5b, 0x76, 0xa0, 0x05, + 0xfc, 0xd3, 0xfc, 0xff, 0x15, 0xf7, 0x5a, 0xf7, 0x5b, 0x77, 0xa0, 0xfb, + 0x5b, 0xfb, 0x5b, 0xa0, 0x76, 0x05, 0xf7, 0xb4, 0xf8, 0x1b, 0x15, 0x5e, + 0x66, 0x66, 0x5e, 0x5e, 0xb0, 0x66, 0xb8, 0xb8, 0xb0, 0xb0, 0xb7, 0xb9, + 0x66, 0xb0, 0x5e, 0x1f, 0x8a, 0xf7, 0xa9, 0x15, 0x88, 0x8c, 0x88, 0x8b, + 0x8a, 0x8b, 0x68, 0x8b, 0x60, 0x54, 0x8b, 0x5f, 0x8b, 0x70, 0x95, 0x74, + 0xab, 0x59, 0x9d, 0x6f, 0x8f, 0x83, 0x98, 0x73, 0x8e, 0x85, 0x8b, 0x8b, + 0x91, 0x87, 0x8b, 0x8b, 0x8c, 0x8b, 0x8b, 0x8c, 0x08, 0x8b, 0x8b, 0x8c, + 0x8b, 0x8c, 0x8c, 0x8c, 0x8a, 0x8e, 0x8f, 0x8d, 0x8f, 0x95, 0x9e, 0x96, + 0x9e, 0x9b, 0xa5, 0xa9, 0xbd, 0x94, 0xa3, 0x8b, 0xa7, 0x8b, 0xba, 0x71, + 0xa7, 0x4f, 0x9d, 0x08, 0xfd, 0x61, 0x04, 0x8f, 0x8a, 0x8e, 0x8b, 0x8c, + 0x8b, 0xae, 0x8b, 0xb6, 0xc2, 0x8b, 0xb7, 0x8b, 0xa6, 0x81, 0xa3, 0x6b, + 0xbc, 0x79, 0xa7, 0x88, 0x91, 0x7d, 0xa5, 0x89, 0x90, 0x86, 0x90, 0x89, + 0x8b, 0x8b, 0x8b, 0x8a, 0x8b, 0x8b, 0x8a, 0x08, 0x8b, 0x8b, 0x8a, 0x8b, + 0x8a, 0x8a, 0x8a, 0x8b, 0x88, 0x88, 0x89, 0x87, 0x86, 0x82, 0x86, 0x82, + 0x86, 0x83, 0x89, 0x87, 0x81, 0x7a, 0x81, 0x7a, 0x6d, 0x59, 0x82, 0x74, + 0x8b, 0x6e, 0x8b, 0x5c, 0xa5, 0x6f, 0xc6, 0x79, 0x08, 0xe6, 0xf7, 0xf9, + 0x15, 0x8b, 0x8b, 0x8b, 0x8a, 0x8c, 0x8a, 0x8b, 0x8a, 0x8e, 0x88, 0x8f, + 0x89, 0x94, 0x86, 0x94, 0x86, 0x93, 0x86, 0x90, 0x89, 0x9b, 0x81, 0x9c, + 0x81, 0xbc, 0x6d, 0xa3, 0x82, 0xa8, 0x8b, 0xba, 0x8b, 0xa7, 0xa5, 0x9d, + 0xc7, 0x08, 0x8c, 0x8e, 0x8b, 0x8e, 0x8b, 0x8d, 0x8b, 0xae, 0x53, 0xb5, + 0x5c, 0x8b, 0x74, 0x8b, 0x73, 0x81, 0x5a, 0x6b, 0x6c, 0x78, 0x8a, 0x8a, + 0x6f, 0x7c, 0x85, 0x89, 0x8b, 0x8b, 0x87, 0x84, 0x08, 0x8c, 0x8a, 0x05, + 0xfc, 0x54, 0x8d, 0x15, 0x8a, 0x87, 0x8b, 0x89, 0x8b, 0x89, 0x8b, 0x68, + 0xc2, 0x60, 0xb8, 0x8b, 0xa5, 0x8b, 0xa2, 0x95, 0xbd, 0xab, 0xa7, 0x9d, + 0x8d, 0x8c, 0xa9, 0x9b, 0x91, 0x8d, 0x8b, 0x8b, 0x8f, 0x92, 0x8b, 0x8b, + 0x8b, 0x8c, 0x8a, 0x8b, 0x08, 0x8b, 0x8b, 0x8b, 0x8c, 0x8a, 0x8c, 0x8b, + 0x8c, 0x88, 0x8e, 0x87, 0x8d, 0x82, 0x90, 0x82, 0x90, 0x83, 0x90, 0x84, + 0x8e, 0x7c, 0x94, 0x7b, 0x95, 0x58, 0xa9, 0x75, 0x94, 0x6e, 0x8b, 0x5c, + 0x8b, 0x6f, 0x71, 0x79, 0x50, 0x08, 0x0e, 0xfb, 0x12, 0xf8, 0x09, 0xf8, + 0x0c, 0x15, 0xf7, 0x31, 0x07, 0xba, 0x9d, 0xa3, 0xa9, 0x8b, 0xb4, 0x08, + 0xba, 0x62, 0xb3, 0x5c, 0x5d, 0x63, 0x62, 0x5b, 0x1e, 0x8b, 0x63, 0xa3, + 0x6e, 0xb9, 0x79, 0x08, 0x8b, 0xfb, 0x31, 0xfb, 0x19, 0xd8, 0x05, 0x8d, + 0x97, 0x8d, 0x97, 0x8b, 0x91, 0x08, 0xb9, 0x63, 0xb2, 0x5c, 0x5a, 0x64, + 0x66, 0x5c, 0x59, 0xb3, 0x62, 0xbb, 0x1e, 0xa5, 0x8b, 0x9d, 0x94, 0xa2, + 0xa3, 0x08, 0xf7, 0x17, 0x3d, 0xfb, 0x17, 0x3d, 0x05, 0x75, 0xa2, 0x77, + 0x94, 0x72, 0x8b, 0x08, 0x5b, 0x62, 0x62, 0x5a, 0x5d, 0xb3, 0x65, 0xbc, + 0xba, 0xb4, 0xb3, 0xb8, 0x1f, 0x8b, 0x93, 0x8a, 0x92, 0x87, 0x9a, 0x08, + 0xf7, 0x19, 0xd7, 0x8b, 0xfb, 0x31, 0x05, 0x5c, 0x7a, 0x73, 0x6d, 0x8b, + 0x62, 0x08, 0x5c, 0xb4, 0x63, 0xba, 0xb9, 0xb3, 0xb4, 0xba, 0x1e, 0x8b, + 0xb3, 0x73, 0xa9, 0x5d, 0x9c, 0x08, 0x8b, 0xf7, 0x31, 0xf7, 0x19, 0x3f, + 0x05, 0x89, 0x7e, 0x89, 0x80, 0x8b, 0x84, 0x08, 0x5e, 0xb3, 0x64, 0xba, + 0xbc, 0xb2, 0xb0, 0xba, 0xbc, 0x63, 0xb4, 0x5b, 0x1e, 0x72, 0x8b, 0x77, + 0x82, 0x75, 0x74, 0x08, 0xfb, 0x17, 0xd9, 0xf7, 0x17, 0xd9, 0x05, 0xa1, + 0x74, 0x9e, 0x82, 0xa6, 0x8b, 0x08, 0xbb, 0xb3, 0xb4, 0xbb, 0xba, 0x63, + 0xb1, 0x5a, 0x5c, 0x62, 0x64, 0x5e, 0x1f, 0x8b, 0x83, 0x8c, 0x84, 0x8f, + 0x7b, 0x08, 0xfb, 0x19, 0x3e, 0x05, 0x0e, 0x5b, 0xf8, 0x28, 0xf8, 0x72, + 0x15, 0xab, 0xf7, 0x30, 0x05, 0x8e, 0x96, 0x8c, 0x95, 0x8b, 0x91, 0x08, + 0xa3, 0x76, 0xa1, 0x74, 0x73, 0x76, 0x75, 0x73, 0x1e, 0x8b, 0x85, 0x8c, + 0x81, 0x8e, 0x80, 0x08, 0xab, 0xfb, 0x30, 0x9c, 0x8b, 0x05, 0x7a, 0xfb, + 0x9b, 0x15, 0x6b, 0xfb, 0x30, 0x05, 0x88, 0x80, 0x8a, 0x81, 0x8b, 0x85, + 0x08, 0x73, 0xa0, 0x75, 0xa3, 0xa2, 0xa0, 0xa1, 0xa3, 0x1e, 0x8b, 0x91, + 0x8a, 0x95, 0x88, 0x96, 0x08, 0x6b, 0xf7, 0x30, 0x7a, 0x8b, 0x05, 0xf6, + 0xf7, 0x6e, 0x15, 0xf7, 0x1a, 0xe3, 0x05, 0xa5, 0x9c, 0x94, 0x98, 0x8b, + 0x9f, 0x8b, 0xa3, 0x78, 0x9e, 0x73, 0x8b, 0x77, 0x8b, 0x7e, 0x82, 0x7a, + 0x71, 0x08, 0x33, 0xfb, 0x1a, 0x97, 0x7f, 0x05, 0xfb, 0x59, 0xfb, 0x41, + 0x15, 0xfb, 0x1a, 0x33, 0x05, 0x71, 0x7a, 0x82, 0x7e, 0x8b, 0x77, 0x8b, + 0x73, 0x9e, 0x78, 0xa3, 0x8b, 0x9f, 0x8b, 0x98, 0x94, 0x9c, 0xa5, 0x08, + 0xe3, 0xf7, 0x1a, 0x7f, 0x97, 0x05, 0xf7, 0x7a, 0xd9, 0x15, 0xf7, 0x30, + 0x6b, 0x05, 0x96, 0x88, 0x95, 0x8a, 0x91, 0x8b, 0x08, 0xa3, 0xa1, 0xa0, + 0xa2, 0xa3, 0x75, 0xa0, 0x73, 0x1f, 0x85, 0x8b, 0x81, 0x8a, 0x80, 0x88, + 0x08, 0xfb, 0x30, 0x6b, 0x8b, 0x7a, 0x05, 0xfb, 0x9b, 0x9c, 0x15, 0xfb, + 0x30, 0xab, 0x05, 0x80, 0x8e, 0x81, 0x8c, 0x85, 0x8b, 0x08, 0x73, 0x75, + 0x76, 0x73, 0x74, 0xa1, 0x76, 0xa3, 0x1f, 0x91, 0x8b, 0x95, 0x8c, 0x96, + 0x8e, 0x08, 0xf7, 0x30, 0xab, 0x8b, 0x9c, 0x05, 0xf7, 0x6e, 0x20, 0x15, + 0xe3, 0xfb, 0x1a, 0x05, 0x9c, 0x71, 0x98, 0x82, 0x9f, 0x8b, 0xa3, 0x8b, + 0x9e, 0x9e, 0x8b, 0xa3, 0x8b, 0x9f, 0x82, 0x98, 0x71, 0x9c, 0x08, 0xfb, + 0x1a, 0xe3, 0x7f, 0x7f, 0x05, 0xfb, 0x41, 0xf7, 0x59, 0x15, 0x33, 0xf7, + 0x1a, 0x05, 0x7a, 0xa5, 0x7e, 0x94, 0x77, 0x8b, 0x73, 0x8b, 0x78, 0x78, + 0x8b, 0x73, 0x8b, 0x77, 0x94, 0x7e, 0xa5, 0x7a, 0x08, 0xf7, 0x1a, 0x33, + 0x97, 0x97, 0x05, 0xe3, 0x88, 0x15, 0x55, 0x60, 0x61, 0x55, 0x57, 0xb6, + 0x60, 0xc0, 0xbf, 0xb6, 0xb6, 0xbf, 0xc0, 0x60, 0xb6, 0x58, 0x1f, 0x0e, + 0x55, 0xf8, 0x05, 0xf8, 0x3c, 0x15, 0x84, 0x89, 0x84, 0x88, 0x86, 0x87, + 0x08, 0xfb, 0x01, 0xf7, 0x2d, 0x05, 0x74, 0xab, 0x7c, 0x95, 0x72, 0x8b, + 0x6c, 0x8b, 0x73, 0x73, 0x8b, 0x6c, 0x8b, 0x73, 0x96, 0x7b, 0xaa, 0x74, + 0x08, 0xf7, 0x2f, 0xfb, 0x02, 0x05, 0x88, 0x86, 0x88, 0x83, 0x8a, 0x85, + 0x08, 0xfb, 0x4e, 0xaa, 0x05, 0x7e, 0x8e, 0x7f, 0x8c, 0x85, 0x8b, 0x08, + 0x6b, 0x6f, 0x70, 0x6d, 0x6d, 0xa7, 0x70, 0xab, 0x1f, 0x93, 0x8b, 0x95, + 0x8c, 0x98, 0x8d, 0x08, 0xf7, 0x4f, 0xab, 0x05, 0x8d, 0x84, 0x8e, 0x84, + 0x8e, 0x86, 0x08, 0xfb, 0x2d, 0xfb, 0x01, 0x05, 0x6b, 0x75, 0x81, 0x7b, + 0x8b, 0x72, 0x8b, 0x6c, 0xa3, 0x73, 0xaa, 0x8b, 0xa3, 0x8b, 0x9b, 0x96, + 0xa2, 0xaa, 0x08, 0xf7, 0x01, 0xf7, 0x2e, 0x05, 0x91, 0x88, 0x91, 0x89, + 0x93, 0x89, 0x08, 0x6c, 0xfb, 0x4d, 0x05, 0x88, 0x7d, 0x8a, 0x80, 0x8b, + 0x84, 0x08, 0x6c, 0xa6, 0x6f, 0xa9, 0xa9, 0xa6, 0xa7, 0xab, 0x1e, 0x8b, + 0x93, 0x8a, 0x95, 0x89, 0x98, 0x08, 0x6b, 0xf7, 0x4e, 0x05, 0x91, 0x8d, + 0x92, 0x8e, 0x91, 0x8f, 0x08, 0xf7, 0x01, 0xfb, 0x2d, 0x05, 0xa1, 0x6b, + 0x9b, 0x81, 0xa4, 0x8b, 0xaa, 0x8b, 0xa3, 0xa3, 0x8b, 0xa9, 0x8b, 0xa4, + 0x81, 0x9b, 0x6b, 0xa2, 0x08, 0xfb, 0x2f, 0xf7, 0x01, 0x05, 0x8e, 0x91, + 0x8e, 0x93, 0x8c, 0x91, 0x08, 0xf7, 0x4e, 0x6b, 0x05, 0x98, 0x89, 0x97, + 0x8a, 0x91, 0x8b, 0x08, 0xab, 0xa7, 0xa6, 0xa9, 0xa9, 0x6f, 0xa6, 0x6b, + 0x1f, 0x84, 0x8b, 0x80, 0x8a, 0x7e, 0x89, 0x08, 0xfb, 0x4f, 0x6b, 0x05, + 0x88, 0x94, 0x89, 0x90, 0x88, 0x90, 0x08, 0xf7, 0x2d, 0xf7, 0x01, 0x05, + 0xaa, 0xa1, 0x96, 0x9b, 0x8b, 0xa4, 0x8b, 0xaa, 0x73, 0xa3, 0x6c, 0x8b, + 0x73, 0x8b, 0x7b, 0x81, 0x74, 0x6b, 0x08, 0xfb, 0x01, 0xfb, 0x2e, 0x05, + 0x85, 0x8e, 0x86, 0x8d, 0x82, 0x8d, 0x08, 0xaa, 0xf7, 0x4d, 0x05, 0x8e, + 0x99, 0x8c, 0x96, 0x8b, 0x91, 0x08, 0xab, 0x70, 0xa7, 0x6d, 0x6d, 0x70, + 0x6f, 0x6b, 0x1e, 0x8b, 0x83, 0x8c, 0x80, 0x8d, 0x7f, 0x08, 0xab, 0xfb, + 0x4e, 0x05, 0x0e, 0x5b, 0xf8, 0x26, 0xf9, 0x58, 0x15, 0xfb, 0x60, 0xfb, + 0x37, 0xfb, 0x33, 0xfb, 0x5b, 0xfb, 0x5e, 0xf7, 0x35, 0xfb, 0x36, 0xf7, + 0x5c, 0xf7, 0x5b, 0xf7, 0x36, 0xf7, 0x36, 0xf7, 0x5b, 0xf7, 0x59, 0xfb, + 0x36, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x0e, 0xad, 0xf8, 0x4b, 0xf9, 0x55, + 0x15, 0xfb, 0x80, 0xfb, 0x3c, 0xfb, 0x29, 0xfb, 0x66, 0x1f, 0x8b, 0xfb, + 0x04, 0xc1, 0x20, 0xe5, 0x49, 0xce, 0x5b, 0xe2, 0x71, 0xed, 0x8b, 0xf7, + 0x82, 0x8b, 0xf7, 0x3d, 0xf7, 0x29, 0x8b, 0xf7, 0x66, 0x8b, 0xed, 0x61, + 0xeb, 0x44, 0xcb, 0x45, 0xc9, 0xfb, 0x01, 0xb2, 0x20, 0x8b, 0x08, 0x61, + 0x69, 0x15, 0xd5, 0x8b, 0xdc, 0x6b, 0xc4, 0x58, 0xd1, 0x4a, 0xb0, 0x38, + 0x8b, 0x2e, 0x08, 0xfb, 0x47, 0xfb, 0x25, 0xfb, 0x25, 0xfb, 0x47, 0xfb, + 0x48, 0xfb, 0x24, 0xf7, 0x25, 0xf7, 0x4a, 0x1e, 0x8b, 0xd8, 0xa9, 0xd9, + 0xc0, 0xc6, 0xcc, 0xd2, 0xdd, 0xaf, 0xee, 0x8b, 0x08, 0x0e, 0x3d, 0xf9, + 0x6a, 0x16, 0xf9, 0x47, 0xfd, 0x47, 0xfd, 0x47, 0xf9, 0x47, 0x07, 0x0e, + 0x3e, 0xf9, 0x02, 0xf9, 0x47, 0x15, 0xfc, 0xdf, 0xfc, 0xe6, 0xf7, 0x00, + 0x2a, 0xf8, 0xdc, 0xf8, 0xdf, 0x22, 0xf3, 0x06, 0x6a, 0x6a, 0x15, 0xfc, + 0xa4, 0xfc, 0x9d, 0xf8, 0xa4, 0xf8, 0x9d, 0x07, 0x0e, 0x3e, 0xf9, 0x03, + 0x16, 0xf3, 0xf3, 0xf8, 0xdf, 0xfc, 0xdc, 0x25, 0xfb, 0x00, 0xfc, 0xe1, + 0xf8, 0xe0, 0x07, 0x6a, 0xac, 0x15, 0xfc, 0x9e, 0xf8, 0x9f, 0xf8, 0x9e, + 0xfc, 0x9f, 0x06, 0x0e, 0x3b, 0xf8, 0xea, 0xf9, 0x47, 0x15, 0xfc, 0xc7, + 0xfc, 0xd4, 0x06, 0xf7, 0x0b, 0xfb, 0x07, 0xf8, 0xcf, 0x8b, 0x8b, 0xf8, + 0xcf, 0xfb, 0x13, 0xf7, 0x0c, 0x05, 0x6a, 0x04, 0xfc, 0xab, 0xfc, 0xa6, + 0xf8, 0xab, 0xf8, 0xa6, 0x07, 0x0e, 0x3b, 0xf8, 0xea, 0x16, 0xf7, 0x13, + 0xf7, 0x0c, 0x8b, 0xf8, 0xcf, 0xfc, 0xcf, 0x8b, 0xfb, 0x0b, 0xfb, 0x07, + 0x8b, 0xfc, 0xd4, 0xf8, 0xc7, 0x8b, 0x05, 0xac, 0x04, 0xfc, 0xa6, 0xf8, + 0xab, 0xf8, 0xa6, 0xfc, 0xab, 0x06, 0x0e, 0xc0, 0xf9, 0xee, 0x16, 0xfc, + 0x2f, 0xf9, 0x56, 0xfc, 0x30, 0xfd, 0x56, 0xf9, 0xcb, 0x8b, 0x05, 0x0e, + 0xc0, 0xf9, 0xee, 0xf9, 0x47, 0x15, 0xfd, 0xcb, 0x8b, 0xf8, 0x30, 0xfd, + 0x55, 0xf8, 0x2f, 0xf9, 0x55, 0x05, 0x0e, 0xf8, 0x1f, 0x7d, 0x15, 0xf7, + 0xfb, 0xf7, 0xfc, 0xfb, 0xfb, 0xf7, 0xfb, 0xfb, 0xfc, 0xfb, 0xfb, 0xf7, + 0xfc, 0xfb, 0xfc, 0x05, 0x0e, 0x54, 0xf8, 0x1c, 0xf9, 0x55, 0x15, 0xfb, + 0x29, 0xfb, 0x35, 0xf7, 0x29, 0xfb, 0x29, 0xf7, 0x27, 0xf7, 0x29, 0xfb, + 0x27, 0xf7, 0x35, 0x05, 0xf7, 0xf9, 0xfb, 0xf9, 0x15, 0xfb, 0x34, 0xf7, + 0x29, 0xfb, 0x29, 0xfb, 0x29, 0xf7, 0x29, 0xfb, 0x2d, 0xf7, 0x34, 0xf7, + 0x2d, 0x05, 0xfb, 0xf9, 0xfb, 0xfe, 0x15, 0xf7, 0x2b, 0xf7, 0x38, 0xfb, + 0x2b, 0xf7, 0x2a, 0xfb, 0x29, 0xfb, 0x2a, 0xf7, 0x29, 0xfb, 0x38, 0x05, + 0xfb, 0xf9, 0xf7, 0xfe, 0x15, 0xf7, 0x33, 0xfb, 0x28, 0xf7, 0x29, 0xf7, + 0x28, 0xfb, 0x29, 0xf7, 0x29, 0xfb, 0x33, 0xfb, 0x29, 0x05, 0x0e, 0xfc, + 0x25, 0xae, 0xf9, 0x55, 0x15, 0xfd, 0x63, 0x07, 0xc8, 0x8c, 0xb8, 0x94, + 0xb8, 0x9e, 0xf7, 0x14, 0xc1, 0xe4, 0xf7, 0x1b, 0x8b, 0xf7, 0x22, 0x08, + 0xf7, 0x56, 0xfb, 0x38, 0xf7, 0x39, 0xfb, 0x55, 0x1e, 0x80, 0x06, 0x0e, + 0xfd, 0x51, 0xf3, 0xf9, 0x47, 0x15, 0x46, 0xfd, 0x47, 0xd0, 0xf9, 0x47, + 0x06, 0x0e, 0xfc, 0xc6, 0xf7, 0x86, 0xf9, 0x47, 0x15, 0xfb, 0x63, 0xfd, + 0x47, 0xf7, 0x63, 0xf9, 0x47, 0x06, 0x0e, 0xfc, 0x3c, 0xf8, 0x10, 0xf9, + 0x47, 0x15, 0xfb, 0xed, 0xfd, 0x47, 0xf7, 0xed, 0xf9, 0x47, 0x06, 0x0e, + 0xfc, 0x53, 0xf7, 0xee, 0xf9, 0x55, 0x15, 0x6e, 0x06, 0x2e, 0x8b, 0x44, + 0x71, 0x5b, 0x58, 0x5f, 0x5d, 0x71, 0x45, 0x8b, 0x44, 0x08, 0x20, 0xcb, + 0x44, 0xed, 0xe5, 0xd1, 0xca, 0xdd, 0xdb, 0x4a, 0xcc, 0x3b, 0x1e, 0x7b, + 0x8b, 0x7b, 0x88, 0x80, 0x87, 0x7d, 0x85, 0x8b, 0x8b, 0x86, 0x8b, 0x7c, + 0x8b, 0x80, 0x97, 0x8b, 0x9b, 0x8b, 0xa8, 0xaa, 0xb4, 0xaf, 0x9c, 0xb6, + 0xa0, 0xb0, 0x92, 0xcb, 0x8b, 0x08, 0x96, 0xa1, 0x06, 0x0e, 0xfc, 0x53, + 0xb8, 0xf7, 0x9c, 0x15, 0x9a, 0x8a, 0x99, 0x8a, 0x91, 0x8b, 0xe1, 0x8b, + 0xd5, 0xa7, 0xba, 0xbd, 0xb6, 0xb9, 0xa6, 0xd3, 0x8b, 0xce, 0x08, 0xf7, + 0x00, 0x4a, 0xd3, 0x29, 0x31, 0x45, 0x4c, 0x39, 0x3a, 0xcb, 0x4b, 0xdc, + 0x1e, 0x9a, 0x8b, 0x9c, 0x8e, 0x96, 0x8f, 0x99, 0x91, 0x8b, 0x8b, 0x90, + 0x8b, 0x9a, 0x8b, 0x96, 0x7f, 0x8b, 0x7b, 0x8b, 0x6e, 0x6c, 0x62, 0x67, + 0x79, 0x68, 0x7a, 0x5b, 0x80, 0x5e, 0x8b, 0x88, 0x8b, 0x89, 0x8b, 0x75, + 0x8c, 0x08, 0x76, 0x07, 0x0e, 0xfb, 0x3f, 0xf7, 0xd2, 0xf9, 0x55, 0x15, + 0xfb, 0x33, 0xfb, 0x10, 0xfb, 0x08, 0xfb, 0x29, 0x26, 0xcf, 0x3f, 0xe6, + 0x1f, 0xcc, 0x8b, 0xc5, 0xb4, 0x9f, 0xc9, 0xaa, 0x46, 0xba, 0x69, 0xcd, + 0x8b, 0x08, 0xe0, 0xce, 0xce, 0xdf, 0xdf, 0x46, 0xd0, 0x38, 0x1f, 0x72, + 0x8b, 0x78, 0x86, 0x6d, 0x7d, 0x9e, 0xd2, 0xee, 0xc7, 0xf0, 0x8c, 0x08, + 0x77, 0xa4, 0x05, 0xfb, 0x1e, 0x8d, 0x21, 0x38, 0x67, 0xfb, 0x1d, 0x6a, + 0xc0, 0x5e, 0xa6, 0x53, 0x8b, 0x72, 0x8b, 0x77, 0x86, 0x6f, 0x7d, 0xa2, + 0xd7, 0xe9, 0xc4, 0xf0, 0x8a, 0x08, 0x78, 0xa4, 0x05, 0x0e, 0xfb, 0x3f, + 0xf7, 0xf3, 0xf7, 0x9b, 0x15, 0xc0, 0x8c, 0xb5, 0x94, 0xb4, 0xa0, 0xe4, + 0xb8, 0xc5, 0xe8, 0x8b, 0xeb, 0x8b, 0xf0, 0x47, 0xd7, 0x30, 0x8b, 0x4a, + 0x8b, 0x51, 0x61, 0x76, 0x4f, 0x6d, 0xd0, 0x5c, 0xac, 0x49, 0x8b, 0x08, + 0x36, 0x48, 0x48, 0x37, 0x38, 0xcf, 0x46, 0xde, 0x1f, 0xa4, 0x8b, 0x9c, + 0x8f, 0xab, 0x9a, 0x79, 0x43, 0x25, 0x4e, 0x29, 0x8b, 0x08, 0x9f, 0x72, + 0x05, 0xf7, 0x1d, 0x89, 0xf6, 0xdf, 0xae, 0xf7, 0x1c, 0xac, 0x57, 0xb9, + 0x70, 0xc2, 0x8b, 0xa5, 0x8b, 0x9f, 0x90, 0xa7, 0x99, 0x74, 0x3e, 0x2c, + 0x52, 0x26, 0x8c, 0x08, 0x9f, 0x72, 0x05, 0x0e, 0xfc, 0x55, 0xf7, 0xf0, + 0xf9, 0x55, 0x15, 0x49, 0x79, 0x6d, 0x80, 0x67, 0x79, 0xfb, 0x01, 0x53, + 0x43, 0xfb, 0x10, 0x8b, 0xfb, 0x18, 0x8b, 0xfb, 0x19, 0xd3, 0xfb, 0x11, + 0xf7, 0x01, 0x54, 0xab, 0x7b, 0xab, 0x80, 0xcf, 0x77, 0x08, 0x93, 0x96, + 0x05, 0x5d, 0x9b, 0x6d, 0x9e, 0x6e, 0xaa, 0x48, 0xd2, 0x66, 0xef, 0x8b, + 0xf7, 0x03, 0x8b, 0xf7, 0x04, 0xb0, 0xef, 0xce, 0xd2, 0xa8, 0xaa, 0xa9, + 0x9e, 0xb9, 0x9b, 0x08, 0x83, 0x96, 0x05, 0x0e, 0xfc, 0x55, 0xae, 0xf9, + 0x4a, 0x15, 0xf7, 0x14, 0x5f, 0xdb, 0xfb, 0x1b, 0x8b, 0xfb, 0x3e, 0x8b, + 0xfb, 0x3d, 0x3a, 0xfb, 0x1c, 0xfb, 0x13, 0x60, 0x08, 0x93, 0x80, 0x05, + 0xce, 0x9e, 0xaa, 0x96, 0xad, 0x9c, 0xf7, 0x00, 0xc2, 0xd3, 0xf7, 0x11, + 0x8b, 0xf7, 0x19, 0x8b, 0xf7, 0x18, 0x43, 0xf7, 0x10, 0xfb, 0x00, 0xc3, + 0x69, 0x9c, 0x6b, 0x96, 0x49, 0x9e, 0x08, 0x83, 0x80, 0x05, 0x0e, 0xfc, + 0x9e, 0xf7, 0x42, 0xf9, 0x47, 0x15, 0x2e, 0xfb, 0x04, 0x5d, 0xfb, 0x06, + 0x8b, 0xfb, 0x0c, 0x8b, 0xfb, 0x0c, 0xbb, 0xfb, 0x0b, 0xe6, 0x21, 0x08, + 0xf7, 0x01, 0x06, 0x50, 0xf7, 0x12, 0x72, 0xf1, 0x8b, 0xf7, 0x0d, 0x8b, + 0xf7, 0x0f, 0xb2, 0xf7, 0x31, 0xb8, 0xc9, 0x08, 0xfb, 0x01, 0x06, 0x0e, + 0xfc, 0x9e, 0xae, 0xf9, 0x47, 0x15, 0xc9, 0xfb, 0x14, 0xa1, 0x2f, 0x8b, + 0xfb, 0x11, 0x8b, 0xfb, 0x0a, 0x71, 0xfb, 0x00, 0x51, 0xfb, 0x0c, 0x08, + 0xf7, 0x01, 0x06, 0xe5, 0xf2, 0xbc, 0xf7, 0x0e, 0x8b, 0xf7, 0x0c, 0x8b, + 0xf7, 0x0c, 0x5c, 0xf7, 0x07, 0x2f, 0xf7, 0x03, 0x08, 0xfb, 0x01, 0x06, + 0x0e, 0xfc, 0xc7, 0xf7, 0x1d, 0xf9, 0x47, 0x15, 0x25, 0xfb, 0xee, 0xf1, + 0xfb, 0xed, 0xf4, 0x8b, 0x23, 0xf7, 0xed, 0xf3, 0xf7, 0xee, 0x22, 0x8b, + 0x05, 0x0e, 0xfc, 0xc7, 0xf7, 0x1e, 0xf9, 0x47, 0x15, 0x24, 0x8b, 0xf2, + 0xfb, 0xee, 0x24, 0xfb, 0xed, 0xf2, 0x8b, 0xf3, 0xf7, 0xed, 0x23, 0xf7, + 0xee, 0x05, 0x0e, 0xfb, 0xde, 0xf7, 0xaa, 0x16, 0xf7, 0x59, 0x8b, 0xfb, + 0x87, 0xf7, 0xee, 0xf7, 0x87, 0xf7, 0xed, 0xfb, 0x59, 0x8b, 0xfb, 0x87, + 0xfb, 0xed, 0xf7, 0x87, 0xfb, 0xee, 0x05, 0x0e, 0xfb, 0xde, 0xf7, 0x7c, + 0x16, 0xf7, 0x87, 0xf7, 0xee, 0xfb, 0x87, 0xf7, 0xed, 0xfb, 0x59, 0x8b, + 0xf7, 0x87, 0xfb, 0xed, 0xfb, 0x87, 0xfb, 0xee, 0xf7, 0x59, 0x8b, 0x05, + 0x0e, 0xfc, 0x41, 0xf7, 0x1b, 0xf9, 0x47, 0x15, 0x27, 0xfb, 0xed, 0xef, + 0xfb, 0xee, 0xf7, 0x84, 0x8b, 0x27, 0xf7, 0xee, 0xef, 0xf7, 0xed, 0xfb, + 0x84, 0x8b, 0x05, 0x0e, 0xfc, 0x41, 0xf7, 0xa7, 0xf9, 0x47, 0x15, 0xfb, + 0x84, 0x8b, 0xef, 0xfb, 0xed, 0x27, 0xfb, 0xee, 0xf7, 0x84, 0x8b, 0xef, + 0xf7, 0xee, 0x27, 0xf7, 0xed, 0x05, 0x0e, 0xfc, 0xf1, 0xf7, 0x5b, 0xf9, + 0x4a, 0x15, 0x75, 0x96, 0xfb, 0x22, 0x32, 0x8b, 0xfc, 0xb1, 0xf7, 0x22, + 0x32, 0xa1, 0x96, 0xfb, 0x06, 0xd9, 0x8b, 0xf8, 0xb1, 0xf7, 0x06, 0xd9, + 0x05, 0x0e, 0xfc, 0xf1, 0xae, 0xf9, 0x4a, 0x15, 0xf7, 0x06, 0x3d, 0x8b, + 0xfc, 0xb1, 0xfb, 0x06, 0x3d, 0xa1, 0x80, 0xf7, 0x22, 0xe4, 0x8b, 0xf8, + 0xb1, 0xfb, 0x22, 0xe4, 0x75, 0x80, 0x05, 0x0e, 0xfc, 0x8d, 0xf7, 0xbf, + 0xf9, 0x47, 0x15, 0x34, 0x8b, 0x7c, 0x8b, 0x77, 0x89, 0x5d, 0x88, 0x72, + 0x7f, 0x7f, 0x72, 0x84, 0x7b, 0x8a, 0x84, 0x8b, 0x54, 0x08, 0xfb, 0x18, + 0x07, 0x8b, 0x5f, 0x8b, 0x87, 0x85, 0x80, 0x83, 0x78, 0x7c, 0x82, 0x75, + 0x8a, 0x08, 0x7f, 0x07, 0xa2, 0x8a, 0x97, 0x85, 0x93, 0x7d, 0x92, 0x7e, + 0x8c, 0x83, 0x8b, 0x5e, 0x08, 0xfb, 0x18, 0x07, 0x8b, 0x61, 0x8b, 0x8b, + 0x8c, 0x82, 0x8f, 0x6f, 0x95, 0x7b, 0x9f, 0x80, 0xa4, 0x7e, 0x9e, 0x8a, + 0xf7, 0x1a, 0x8b, 0x08, 0x97, 0x86, 0x07, 0x76, 0x8b, 0x77, 0x92, 0x82, + 0x95, 0x80, 0x98, 0x8a, 0x93, 0x8b, 0xc5, 0x08, 0xf7, 0x01, 0x07, 0x8b, + 0xc2, 0x88, 0x9e, 0x7e, 0x9d, 0x7d, 0x9f, 0x7c, 0x93, 0x68, 0x93, 0xae, + 0x94, 0x9a, 0x93, 0x99, 0x9f, 0x98, 0x9d, 0x8e, 0x9e, 0x8b, 0xc2, 0x08, + 0xf7, 0x01, 0x07, 0x8b, 0xcb, 0x8e, 0x96, 0x9c, 0x96, 0x98, 0x92, 0x98, + 0x8e, 0xa0, 0x8b, 0x08, 0x97, 0x07, 0x0e, 0xfc, 0x8d, 0xae, 0xf9, 0x3b, + 0x15, 0x9e, 0x8b, 0x97, 0x89, 0x96, 0x85, 0xa1, 0x81, 0x8e, 0x80, 0x8b, + 0x48, 0x08, 0xfb, 0x01, 0x07, 0x8b, 0x54, 0x8e, 0x78, 0x98, 0x79, 0x99, + 0x77, 0x9a, 0x83, 0xae, 0x82, 0x68, 0x83, 0x7c, 0x83, 0x7d, 0x77, 0x7e, + 0x79, 0x88, 0x78, 0x8b, 0x54, 0x08, 0xfb, 0x01, 0x07, 0x8b, 0x51, 0x8a, + 0x83, 0x80, 0x7e, 0x82, 0x81, 0x77, 0x84, 0x77, 0x8b, 0x08, 0x85, 0x7f, + 0x06, 0xe1, 0x8b, 0x9b, 0x8b, 0x9f, 0x8d, 0xb9, 0x8e, 0xa4, 0x97, 0x97, + 0xa4, 0x92, 0x9b, 0x8c, 0x92, 0x8b, 0xc2, 0x08, 0xf7, 0x18, 0x07, 0x8b, + 0xb4, 0x8c, 0x92, 0x8f, 0x97, 0x93, 0x9d, 0x97, 0x93, 0xa5, 0x8c, 0x08, + 0x97, 0x07, 0x77, 0x8c, 0x7f, 0x92, 0x81, 0x9a, 0x83, 0x98, 0x8a, 0x8f, + 0x8b, 0xbb, 0x08, 0xf7, 0x18, 0x07, 0x8b, 0xb4, 0x8b, 0x8b, 0x8a, 0x95, + 0x87, 0xa7, 0x81, 0x9a, 0x77, 0x96, 0x71, 0x99, 0x7d, 0x8c, 0xfb, 0x1e, + 0x8b, 0x08, 0x7f, 0x07, 0x0e, 0x20, 0xf9, 0x4d, 0xf9, 0x47, 0x15, 0xfb, + 0x46, 0xf7, 0x06, 0x06, 0x64, 0x81, 0x8b, 0x23, 0x2a, 0x8b, 0x05, 0x32, + 0x8b, 0x5f, 0x88, 0x5d, 0x81, 0x27, 0x76, 0x46, 0x33, 0x8b, 0x21, 0x8b, + 0x2e, 0xc1, 0x3c, 0xe2, 0x68, 0xb5, 0x7b, 0xba, 0x83, 0xc7, 0x8b, 0xb9, + 0x8b, 0xc2, 0x8f, 0xc1, 0x94, 0x89, 0xfb, 0x04, 0x84, 0x50, 0x7c, 0x5d, + 0x08, 0x6f, 0x35, 0x50, 0x57, 0x45, 0x8b, 0x5b, 0x8b, 0x63, 0xa8, 0x8b, + 0xad, 0x8b, 0x93, 0x8e, 0x93, 0x92, 0x91, 0x90, 0x90, 0x8c, 0x8b, 0xa3, + 0x8d, 0xab, 0x8d, 0xa2, 0xa6, 0x8b, 0xac, 0x08, 0xb6, 0x65, 0xae, 0x5d, + 0x4f, 0x5b, 0x56, 0x4a, 0x39, 0xd4, 0x4a, 0xe9, 0x1e, 0xb8, 0x8b, 0xb5, + 0x99, 0xb1, 0xa8, 0xb8, 0xad, 0xa6, 0xb5, 0x9d, 0xcc, 0x9d, 0xca, 0x90, + 0xca, 0x8b, 0xf7, 0x3b, 0x08, 0xf7, 0xd2, 0x07, 0x9e, 0x8a, 0x99, 0x8b, + 0x94, 0x8b, 0xb7, 0x8b, 0xa5, 0x8f, 0xbc, 0x98, 0x08, 0x9c, 0xa2, 0x05, + 0xfb, 0x6d, 0x64, 0x15, 0xfc, 0x19, 0x07, 0x6f, 0x8e, 0x6a, 0x95, 0x67, + 0x9d, 0x82, 0xb0, 0x86, 0xc7, 0x8b, 0xcb, 0x8b, 0xca, 0x91, 0xe5, 0x93, + 0xb7, 0x08, 0xec, 0x06, 0x0e, 0xfb, 0xbb, 0xf7, 0xa4, 0xf7, 0xbd, 0x15, + 0xa2, 0xcd, 0x97, 0x9a, 0xc3, 0xa8, 0xb7, 0xa2, 0x9a, 0x94, 0x99, 0x97, + 0xae, 0xa7, 0x9c, 0xad, 0x8b, 0xb6, 0x8b, 0xaf, 0x7d, 0xae, 0x74, 0xa5, + 0x66, 0xb4, 0x64, 0x96, 0x24, 0x8b, 0x24, 0x8b, 0x64, 0x80, 0x66, 0x62, + 0x08, 0x73, 0x71, 0x7e, 0x68, 0x8b, 0x67, 0x8b, 0x65, 0x98, 0x6b, 0xa6, + 0x72, 0x9c, 0x7a, 0x9a, 0x82, 0xc0, 0x6f, 0xc4, 0x6d, 0x96, 0x7e, 0xa2, + 0x48, 0x08, 0x8e, 0x70, 0x15, 0x3a, 0x4b, 0x4d, 0x3c, 0x3c, 0xca, 0x4b, + 0xdb, 0xd9, 0xcb, 0xcb, 0xd9, 0xd9, 0x4b, 0xcb, 0x3f, 0x1f, 0x0e, 0xfb, + 0xbb, 0xf7, 0xa3, 0xf9, 0x06, 0x15, 0x7f, 0x9f, 0x87, 0x92, 0x85, 0x92, + 0x75, 0xa7, 0x68, 0x9b, 0x66, 0x8b, 0x42, 0x8b, 0x5b, 0x54, 0x8b, 0x37, + 0x8b, 0x61, 0x99, 0x65, 0xa4, 0x70, 0x9d, 0x77, 0x8b, 0x8b, 0xcf, 0x6c, + 0xca, 0x6c, 0xa5, 0x70, 0xa2, 0x56, 0x08, 0xa2, 0xc1, 0xa5, 0xa4, 0xcb, + 0xab, 0xc9, 0xa8, 0x8b, 0x8b, 0x97, 0x96, 0xab, 0xa6, 0x9d, 0xb6, 0x8b, + 0xbb, 0x8b, 0xdf, 0x5b, 0xc2, 0x43, 0x8b, 0x65, 0x8b, 0x68, 0x7b, 0x75, + 0x6f, 0x85, 0x84, 0x87, 0x85, 0x7f, 0x76, 0x08, 0x8d, 0xfb, 0xf8, 0x15, + 0x3b, 0x4b, 0x4c, 0x3d, 0x3c, 0xca, 0x4b, 0xda, 0xd9, 0xcb, 0xcb, 0xd9, + 0xd8, 0x4b, 0xcc, 0x3f, 0x1f, 0x0e, 0xd2, 0xf8, 0x5b, 0xf8, 0x6e, 0x15, + 0x7b, 0xb4, 0x84, 0x9b, 0x7f, 0x9f, 0x66, 0xc8, 0x44, 0xb2, 0x41, 0x8b, + 0xfb, 0x09, 0x8b, 0x35, 0x34, 0x8b, 0xfb, 0x0a, 0x8b, 0x44, 0xa2, 0x57, + 0xbc, 0x65, 0xaa, 0x73, 0xac, 0x79, 0xe0, 0x66, 0xf7, 0x0c, 0x56, 0xb1, + 0x6c, 0xb4, 0x39, 0x08, 0xb5, 0xdd, 0xb0, 0xaa, 0xf7, 0x0c, 0xc0, 0xd1, + 0xa9, 0xad, 0x9c, 0xa4, 0x9c, 0xcc, 0xb7, 0xa6, 0xbf, 0x8b, 0xd9, 0x8b, + 0xf7, 0x0c, 0x36, 0xe2, 0xfb, 0x0a, 0x8b, 0x41, 0x8b, 0x44, 0x64, 0x66, + 0x4e, 0x7f, 0x77, 0x84, 0x7b, 0x7b, 0x62, 0x08, 0x0e, 0xfb, 0x40, 0xf9, + 0x0d, 0xf8, 0x11, 0x15, 0x79, 0x89, 0x7f, 0x8a, 0x81, 0x8b, 0x6b, 0x8b, + 0x66, 0x97, 0x6b, 0xa0, 0x62, 0xa5, 0x6c, 0xb6, 0x70, 0xcf, 0x76, 0xc1, + 0x82, 0x9d, 0x7e, 0x9c, 0x6a, 0xb7, 0x5a, 0xa4, 0x54, 0x8b, 0x29, 0x8b, + 0x3b, 0x3c, 0x8b, 0x2b, 0x08, 0x8b, 0x56, 0xa4, 0x58, 0xb6, 0x69, 0xa2, + 0x78, 0x9e, 0x83, 0xb5, 0x81, 0x08, 0x79, 0x07, 0x66, 0x82, 0x7a, 0x84, + 0x76, 0x7d, 0x5b, 0x69, 0x6e, 0x54, 0x8b, 0x52, 0x8b, 0x2a, 0xda, 0x3d, + 0xec, 0x8b, 0xd6, 0x8b, 0xcd, 0xb9, 0xa4, 0xd0, 0xaf, 0xec, 0x8f, 0x94, + 0xac, 0xb1, 0xb2, 0xb8, 0xc4, 0xa6, 0xc3, 0x8b, 0x08, 0x93, 0x8b, 0x92, + 0x8b, 0x9b, 0x89, 0x08, 0xcc, 0x07, 0x0e, 0x3c, 0xf7, 0xd9, 0xf9, 0x0e, + 0x15, 0x5c, 0xb2, 0x69, 0x9a, 0x66, 0x8b, 0x08, 0x3c, 0x2e, 0x2c, 0x3b, + 0x74, 0x9a, 0x79, 0x9f, 0x9e, 0xa1, 0x9e, 0x9b, 0x1f, 0x8b, 0x90, 0x8b, + 0x8b, 0x7f, 0x98, 0x82, 0x95, 0x86, 0x9a, 0x8b, 0x98, 0x8b, 0xbc, 0xb7, + 0xb6, 0xbd, 0x8b, 0xae, 0x8b, 0xba, 0x75, 0xea, 0x4f, 0xc2, 0x68, 0x90, + 0x87, 0xa5, 0x7e, 0x79, 0x5e, 0x88, 0x83, 0x84, 0x7c, 0x08, 0x7b, 0x6c, + 0x89, 0x85, 0x8b, 0x7e, 0x8b, 0x85, 0x8c, 0x87, 0x8d, 0x81, 0x8d, 0x8f, + 0x8d, 0x90, 0x8e, 0x90, 0xab, 0xc9, 0x8c, 0x8d, 0xa0, 0xbf, 0xad, 0x7c, + 0xa3, 0x84, 0x9a, 0x8b, 0x98, 0x8b, 0xa4, 0x8f, 0x99, 0x8f, 0x08, 0xdf, + 0xa2, 0xc4, 0xc4, 0x8b, 0xc8, 0x08, 0xb0, 0x71, 0xa7, 0x69, 0x6b, 0x73, + 0x6f, 0x64, 0x1e, 0x8b, 0x82, 0x8d, 0x86, 0x90, 0x88, 0xa1, 0x7c, 0x90, + 0x83, 0x8b, 0x76, 0x8b, 0x67, 0x69, 0x6c, 0x65, 0x8b, 0x6a, 0x8b, 0x66, + 0x98, 0x6a, 0xa1, 0x91, 0xa4, 0x8e, 0x9c, 0x8b, 0x9a, 0x08, 0xc4, 0x66, + 0xb7, 0x5b, 0x1e, 0x72, 0x8b, 0x79, 0x81, 0x72, 0x6f, 0x08, 0x6c, 0x07, + 0xf7, 0x12, 0x3b, 0x15, 0x7e, 0x90, 0x77, 0x97, 0x76, 0x9b, 0x76, 0x9b, + 0x81, 0x9a, 0x8b, 0x9d, 0x08, 0x9e, 0x9a, 0x9b, 0x9d, 0xaa, 0xa7, 0x66, + 0x62, 0x1e, 0x8b, 0x7e, 0x89, 0x82, 0x86, 0x7a, 0x08, 0x43, 0xfb, 0x55, + 0x15, 0xd6, 0x6a, 0xb1, 0x4a, 0x3c, 0x52, 0x3f, 0x21, 0xfb, 0x38, 0xf7, + 0x22, 0xfb, 0x21, 0xf7, 0x38, 0xe0, 0xd6, 0xb5, 0xbc, 0xa1, 0x79, 0x9b, + 0x72, 0x1e, 0x7e, 0x8b, 0x85, 0x88, 0x83, 0x81, 0x82, 0x4d, 0x71, 0x6d, + 0x5e, 0x8b, 0x69, 0x8b, 0x71, 0xa3, 0x8b, 0xa9, 0x8b, 0xaa, 0xa0, 0x9e, + 0xd7, 0xb0, 0xbe, 0xa4, 0xab, 0x9f, 0x9c, 0x9e, 0xa7, 0xa9, 0x9a, 0xb1, + 0x8b, 0xb1, 0x08, 0xd0, 0x58, 0xc4, 0x4e, 0x1e, 0x6e, 0x8b, 0x69, 0x7f, + 0x77, 0x7a, 0x7a, 0x7c, 0x7f, 0x7c, 0x77, 0x68, 0x08, 0x79, 0x92, 0x05, + 0x0e, 0x3c, 0xa1, 0xf7, 0x6c, 0x15, 0x91, 0x54, 0xad, 0x68, 0xbb, 0x8b, + 0xb1, 0x8b, 0xa2, 0xa1, 0x8b, 0xb0, 0x8b, 0x93, 0x8b, 0x8f, 0x89, 0x9e, + 0x7b, 0x7d, 0x80, 0x86, 0x7a, 0x8b, 0x70, 0x8b, 0x7b, 0x99, 0x84, 0xa8, + 0xdf, 0xad, 0xc2, 0xc8, 0x8a, 0xc6, 0x08, 0xb7, 0x8a, 0xb3, 0x74, 0x9a, + 0x6c, 0x5a, 0x71, 0x7b, 0x76, 0x8b, 0x64, 0x8b, 0x42, 0xde, 0x50, 0xf2, + 0x8b, 0xd5, 0x8b, 0xe3, 0xac, 0xe0, 0xc8, 0xc3, 0xb3, 0xa1, 0xa3, 0x8b, + 0xa3, 0x8b, 0x9e, 0x7e, 0x98, 0x77, 0x8b, 0x08, 0x7e, 0x8b, 0x82, 0x86, + 0x82, 0x7d, 0x90, 0x7c, 0x8d, 0x84, 0x8b, 0x81, 0x8b, 0x6b, 0x73, 0x73, + 0x6b, 0x8b, 0x75, 0x8b, 0x77, 0x97, 0x7e, 0xa0, 0x81, 0x9a, 0x88, 0x9a, + 0x87, 0xb8, 0x84, 0xd8, 0x88, 0x95, 0x77, 0xaa, 0x08, 0x6f, 0xb4, 0x58, + 0xa7, 0x59, 0x8b, 0x54, 0x8b, 0x5d, 0x63, 0x8b, 0x5a, 0x8b, 0x77, 0x8f, + 0x7c, 0x98, 0x6d, 0x65, 0xaa, 0x67, 0x9a, 0x68, 0x8b, 0x08, 0x83, 0x06, + 0x80, 0xa5, 0x7e, 0x9a, 0x6d, 0x9e, 0x5d, 0xa7, 0x80, 0x97, 0x8b, 0xa3, + 0x8b, 0x97, 0x91, 0x95, 0x98, 0x94, 0x08, 0x81, 0x06, 0x62, 0x6f, 0x72, + 0x67, 0x1f, 0x8b, 0x6a, 0x9d, 0x7a, 0xb9, 0x81, 0xc6, 0x7f, 0x8f, 0x89, + 0x95, 0x77, 0x3a, 0x7e, 0x42, 0x45, 0x88, 0x47, 0x7c, 0x7b, 0x87, 0x81, + 0x88, 0x75, 0x08, 0xa1, 0x06, 0xbc, 0xc9, 0x15, 0x88, 0xc4, 0xc5, 0xc5, + 0xc8, 0x8c, 0x8c, 0x85, 0x8c, 0x86, 0x8b, 0x88, 0x8b, 0x76, 0x79, 0x6f, + 0x70, 0x79, 0x76, 0x7c, 0x7b, 0x83, 0x67, 0x7f, 0x08, 0x0e, 0x4c, 0xf9, + 0x0a, 0x16, 0x9f, 0x07, 0x2f, 0x9c, 0x6c, 0x9a, 0x5f, 0xba, 0x5e, 0xbf, + 0x80, 0xae, 0x86, 0xf6, 0x9c, 0x6b, 0x93, 0x7d, 0x99, 0x7b, 0xaf, 0x5e, + 0xc5, 0x6e, 0xbd, 0x8b, 0x08, 0xe1, 0xd1, 0xd4, 0xe4, 0xe2, 0x4c, 0xd1, + 0x3c, 0x1f, 0x73, 0x8b, 0x7d, 0x87, 0x6a, 0x7b, 0x84, 0x87, 0x86, 0x89, + 0x82, 0x87, 0xa7, 0xb3, 0x96, 0xa9, 0x8b, 0xaf, 0x08, 0xdf, 0x44, 0xd0, + 0x34, 0x34, 0x44, 0x46, 0x37, 0x1e, 0x8b, 0x67, 0x96, 0x6d, 0xa7, 0x63, + 0x83, 0x8e, 0x81, 0x90, 0x88, 0x8d, 0x6a, 0x9b, 0x7d, 0x8f, 0x73, 0x8b, + 0x08, 0x3c, 0x4c, 0x45, 0x34, 0x32, 0xd1, 0x42, 0xe1, 0x1f, 0xbd, 0x8b, + 0xc5, 0xa8, 0xaf, 0xb8, 0x99, 0x9b, 0x93, 0x99, 0x9c, 0xab, 0x86, 0x20, + 0x80, 0x68, 0x5e, 0x57, 0x5f, 0x5c, 0x6c, 0x7c, 0x2f, 0x7a, 0x08, 0x77, + 0xf8, 0x78, 0x07, 0x0e, 0xfb, 0x88, 0xf7, 0xbc, 0xf9, 0x55, 0x15, 0x58, + 0x2e, 0x43, 0x29, 0xfb, 0x1f, 0xfb, 0x3c, 0xf7, 0x0a, 0xfb, 0x23, 0xe8, + 0xfb, 0x12, 0xbe, 0x30, 0xb6, 0xda, 0xf7, 0x12, 0xf7, 0x41, 0xea, 0xf7, + 0x00, 0x3f, 0xde, 0xfb, 0x30, 0xf7, 0x69, 0x6b, 0xca, 0x08, 0x0e, 0xfb, + 0x25, 0xf7, 0xf0, 0x7d, 0x15, 0xa0, 0xe2, 0xc3, 0xeb, 0xf7, 0x03, 0xf7, + 0x1d, 0xe7, 0xf7, 0x08, 0xaa, 0xcb, 0x8b, 0xd6, 0x8b, 0xd9, 0x48, 0xcc, + 0x3a, 0x8b, 0x5e, 0x8b, 0x60, 0x77, 0x6b, 0x67, 0x77, 0x73, 0x80, 0x77, + 0x7f, 0x5f, 0x80, 0xad, 0x83, 0x9c, 0x7f, 0x9d, 0x08, 0x6b, 0xbb, 0x5a, + 0xa6, 0x55, 0x8b, 0x38, 0x8b, 0x4b, 0x4a, 0x8b, 0x37, 0x8b, 0x4d, 0xa1, + 0x5c, 0xdc, 0x21, 0xf7, 0x26, 0xfb, 0x52, 0xb1, 0x4a, 0xa5, 0x28, 0x08, + 0x0e, 0xfb, 0x69, 0xd3, 0x16, 0xf8, 0x75, 0x9f, 0x06, 0x2f, 0x9c, 0x6c, + 0x99, 0x5f, 0xbb, 0x66, 0xb6, 0x7d, 0xad, 0x85, 0xc9, 0xac, 0x58, 0xbb, + 0x6e, 0xc0, 0x8b, 0xd2, 0x8b, 0xc4, 0xc3, 0x8b, 0xd2, 0x8b, 0xca, 0x72, + 0xb2, 0x27, 0xe5, 0x2a, 0xe3, 0x6c, 0xb8, 0x72, 0xea, 0x08, 0x70, 0x2b, + 0x6e, 0x60, 0x29, 0x32, 0x27, 0x31, 0x72, 0x64, 0x8b, 0x4c, 0x8b, 0x44, + 0xc4, 0x53, 0xd2, 0x8b, 0xc0, 0x8b, 0xbb, 0xa8, 0xac, 0xbe, 0x85, 0x4d, + 0x7d, 0x69, 0x66, 0x60, 0x5f, 0x5b, 0x6c, 0x7d, 0x2f, 0x7a, 0x08, 0x77, + 0x07, 0x0e, 0xf8, 0x51, 0xf8, 0xe0, 0x15, 0x6c, 0x06, 0x6d, 0x61, 0x58, + 0x72, 0x43, 0x83, 0x08, 0x70, 0xd1, 0x07, 0xa2, 0x90, 0x86, 0x70, 0x1f, + 0xfb, 0x82, 0x07, 0x56, 0x81, 0x7f, 0x5c, 0x1e, 0x70, 0x6a, 0xf7, 0x97, + 0xac, 0x67, 0x06, 0x64, 0x7d, 0x9c, 0xbb, 0x1f, 0xf8, 0x08, 0x07, 0x5e, + 0xf7, 0x0a, 0x15, 0xfb, 0x5f, 0xfb, 0x36, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, + 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5b, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, + 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, + 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x37, + 0x8b, 0x2e, 0x08, 0xfb, 0x48, 0xfb, 0x26, 0xfb, 0x27, 0xfb, 0x48, 0xfb, + 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, + 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0xa7, + 0xf7, 0xbd, 0x15, 0x61, 0x07, 0x5e, 0x86, 0x86, 0x5f, 0x1e, 0xfb, 0x58, + 0x06, 0x98, 0xb0, 0xbf, 0xb6, 0xd3, 0xab, 0x08, 0xea, 0xb8, 0xaf, 0xb3, + 0x8b, 0xcb, 0x08, 0xda, 0x4a, 0xbd, 0x26, 0x39, 0x50, 0x61, 0x52, 0x6b, + 0xa0, 0x74, 0xa7, 0xa6, 0xa1, 0xa0, 0xa5, 0x1e, 0x8b, 0x91, 0x8a, 0x90, + 0x89, 0x90, 0x82, 0x9e, 0x8b, 0x8b, 0x8b, 0x8d, 0x08, 0x9c, 0xa8, 0x9f, + 0xa3, 0xb0, 0xa4, 0x69, 0x58, 0x1e, 0x8b, 0x4f, 0x6e, 0x61, 0x33, 0x49, + 0x45, 0x56, 0x68, 0x54, 0x8b, 0x52, 0x8b, 0x84, 0x8b, 0x83, 0x8c, 0x80, + 0x08, 0xf7, 0xe5, 0xf7, 0x47, 0x06, 0x6a, 0x06, 0xfb, 0x17, 0xf8, 0x2d, + 0x15, 0xfb, 0x5f, 0xfb, 0x36, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, + 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, + 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, + 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x37, 0x8b, 0x2d, + 0x08, 0xfb, 0x48, 0xfb, 0x26, 0xfb, 0x27, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, + 0x25, 0xf7, 0x27, 0xf7, 0x4b, 0x1e, 0x8b, 0xd9, 0xa9, 0xd9, 0xc1, 0xc7, + 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf7, 0xd5, 0xf7, 0xf7, + 0x15, 0xa4, 0x91, 0x97, 0x8c, 0x99, 0x8b, 0x08, 0xc7, 0xb1, 0x67, 0x51, + 0x4b, 0x5e, 0x56, 0x55, 0x6c, 0x75, 0x99, 0x9d, 0x1f, 0x8b, 0x8f, 0x8c, + 0x8e, 0x8c, 0x8e, 0x91, 0x9b, 0x8b, 0x8b, 0x8b, 0x94, 0x08, 0xa8, 0x76, + 0x9f, 0x6c, 0x6b, 0x76, 0x76, 0x6c, 0x4f, 0xcd, 0x5f, 0xe5, 0xf7, 0x05, + 0xdd, 0xc9, 0xe2, 0x1e, 0x8b, 0xb2, 0x7a, 0xac, 0x6d, 0xa0, 0x7b, 0x96, + 0x63, 0x99, 0x75, 0x8d, 0x83, 0x8b, 0x88, 0x8d, 0x8b, 0x8e, 0x8b, 0x8e, + 0x8e, 0x8c, 0x9b, 0x90, 0x08, 0xc1, 0x9a, 0xa8, 0xae, 0x8b, 0xbb, 0x08, + 0xcd, 0x56, 0xb1, 0x2f, 0x32, 0x4d, 0x67, 0x57, 0x71, 0x9f, 0x77, 0xa4, + 0xa4, 0xa2, 0xa1, 0xa4, 0x1e, 0x8b, 0x90, 0x89, 0x94, 0x8a, 0x8e, 0x87, + 0x92, 0x8b, 0x8b, 0x8b, 0x8c, 0x08, 0x9a, 0xa4, 0x99, 0xa3, 0xb5, 0xa7, + 0x6d, 0x5e, 0x1e, 0x8b, 0x69, 0x7f, 0x71, 0x75, 0x7b, 0x78, 0x7e, 0x71, + 0x82, 0x74, 0x8b, 0x08, 0x84, 0x8b, 0x84, 0x8b, 0x81, 0x8c, 0x08, 0x67, + 0x07, 0xda, 0xf7, 0xf3, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, + 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, + 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, + 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, + 0xb0, 0x37, 0x8b, 0x2e, 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, + 0x49, 0xfb, 0x49, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xd9, + 0xa9, 0xda, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, + 0xf8, 0x5f, 0xf8, 0xe0, 0x15, 0x49, 0x8b, 0xfb, 0x69, 0xfb, 0xd5, 0x8b, + 0x6f, 0xf7, 0x55, 0x8b, 0x8b, 0x64, 0x05, 0x65, 0x82, 0x80, 0x6d, 0x1e, + 0x5c, 0x6a, 0xf7, 0x85, 0xac, 0x6b, 0x06, 0x7f, 0x8b, 0x7c, 0x90, 0x86, + 0x91, 0x88, 0x90, 0x89, 0x94, 0x8b, 0x9d, 0x08, 0xb8, 0xf7, 0x03, 0xb8, + 0xfb, 0x03, 0xf7, 0xc4, 0x07, 0x35, 0x2d, 0x15, 0xfb, 0x66, 0xfb, 0x1b, + 0x07, 0xf7, 0x1b, 0xf7, 0x66, 0x05, 0xa6, 0xf7, 0x67, 0x15, 0xfb, 0x5f, + 0xfb, 0x36, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, + 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, + 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, + 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x37, 0x8b, 0x2e, 0x08, 0xfb, 0x49, + 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, + 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, + 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf7, 0xb2, 0xf7, 0xcf, 0x15, 0xa6, 0xae, + 0xa4, 0x9a, 0xa8, 0x8b, 0x08, 0xb9, 0xad, 0x5f, 0x4f, 0x4a, 0x60, 0x57, + 0x56, 0x6f, 0x74, 0x99, 0x9d, 0x1f, 0x8b, 0x90, 0x8b, 0x8b, 0x92, 0x9a, + 0x8f, 0x93, 0x8d, 0x93, 0x8b, 0x92, 0x08, 0xa3, 0x73, 0x9f, 0x6f, 0x6d, + 0x75, 0x75, 0x6b, 0x53, 0xcc, 0x61, 0xe1, 0xf7, 0x05, 0xe1, 0xce, 0xe3, + 0xdc, 0x48, 0xc6, 0x2f, 0x1e, 0x5c, 0x8b, 0x67, 0x7f, 0x6c, 0x73, 0x08, + 0x96, 0xf7, 0x0d, 0x05, 0xad, 0x88, 0x9c, 0x8a, 0xab, 0x8b, 0xdf, 0x8b, + 0xa3, 0x8e, 0xa0, 0x9a, 0x9e, 0x99, 0x9a, 0xa8, 0x95, 0xb7, 0x64, 0x7d, + 0x69, 0x86, 0x56, 0x8b, 0x68, 0x8b, 0x66, 0x90, 0x36, 0x99, 0x88, 0x57, + 0x80, 0xfb, 0x0b, 0x80, 0x32, 0x08, 0xb4, 0x7a, 0x05, 0xf7, 0x06, 0xf8, + 0x1b, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, + 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, + 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, + 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, + 0x2d, 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, + 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, + 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf7, 0xc2, 0xf8, + 0x0b, 0x15, 0x8b, 0xd1, 0xa1, 0xcf, 0xac, 0xab, 0x96, 0x95, 0xa0, 0x92, + 0x9e, 0x8b, 0xa8, 0x8b, 0xa1, 0x7c, 0x8b, 0x79, 0x8b, 0x87, 0x8a, 0x88, + 0x8a, 0x86, 0x88, 0x80, 0x8a, 0x82, 0x8b, 0x84, 0x08, 0x76, 0xa1, 0x77, + 0xa3, 0xa6, 0x9f, 0xa2, 0xaa, 0xc0, 0x4d, 0xb2, 0x36, 0x1e, 0x52, 0x8b, + 0x5e, 0x79, 0x6c, 0x67, 0x61, 0x5b, 0x71, 0x41, 0x8b, 0x40, 0x8b, 0x4b, + 0x9d, 0x51, 0xac, 0x5f, 0xac, 0x5f, 0xbc, 0x74, 0xca, 0x8b, 0x08, 0xf3, + 0xd7, 0xd1, 0xe9, 0xd8, 0x51, 0xc4, 0x3c, 0x1f, 0x54, 0x8b, 0x5e, 0x72, + 0x69, 0x59, 0x08, 0x8a, 0xb4, 0x05, 0xee, 0x7f, 0x15, 0xbc, 0xac, 0x5f, + 0x47, 0x4c, 0x67, 0x5e, 0x57, 0x56, 0x66, 0xb9, 0xcb, 0xca, 0xb4, 0xba, + 0xc2, 0x1f, 0x8a, 0xf7, 0xeb, 0x15, 0xfb, 0x5f, 0xfb, 0x36, 0xfb, 0x33, + 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5b, 0xf7, 0x5b, + 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, + 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, + 0x4a, 0xb0, 0x37, 0x8b, 0x2e, 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, 0x26, + 0xfb, 0x49, 0xfb, 0x49, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, + 0xd9, 0xa9, 0xda, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, + 0x0e, 0xf7, 0x6f, 0xf8, 0xdd, 0x15, 0xfb, 0x3b, 0xa8, 0x07, 0x94, 0xad, + 0x05, 0x97, 0xb8, 0x8c, 0x8c, 0xac, 0x8c, 0x08, 0xf7, 0x4a, 0x8b, 0x43, + 0x26, 0x05, 0x7e, 0x79, 0x7c, 0x78, 0x7e, 0x7b, 0x56, 0x47, 0x70, 0x52, + 0x8b, 0x5d, 0x08, 0x66, 0xa5, 0x70, 0xae, 0xae, 0xa4, 0xa2, 0xad, 0x1e, + 0x8b, 0x90, 0x8a, 0x91, 0x8a, 0x90, 0x80, 0xb7, 0x8b, 0x8b, 0x8b, 0x98, + 0x8b, 0x9f, 0x90, 0xa3, 0x96, 0xa7, 0x94, 0xa0, 0x90, 0x94, 0xb9, 0xd8, + 0x08, 0xe8, 0xf7, 0x2e, 0x05, 0x8b, 0x8c, 0x8e, 0x8f, 0x8e, 0x92, 0x08, + 0xfb, 0xf8, 0x06, 0xf7, 0x49, 0xf7, 0x0d, 0x15, 0xfb, 0x5e, 0xfb, 0x37, + 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, + 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, + 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, + 0x57, 0xd2, 0x4a, 0xb0, 0x37, 0x8b, 0x2e, 0x08, 0xfb, 0x49, 0xfb, 0x26, + 0xfb, 0x26, 0xfb, 0x49, 0xfb, 0x49, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, + 0x1e, 0x8b, 0xd9, 0xa9, 0xd9, 0xc1, 0xc7, 0xcc, 0xd3, 0xde, 0xaf, 0xef, + 0x8b, 0x08, 0x0e, 0xf8, 0x5e, 0xf8, 0x24, 0x15, 0xc1, 0xae, 0x9d, 0xa4, + 0x8b, 0xb2, 0x08, 0xc3, 0x55, 0xb3, 0x41, 0x36, 0x4e, 0x58, 0x43, 0x1e, + 0x8b, 0x5f, 0x9c, 0x72, 0xbe, 0x69, 0x08, 0x40, 0x60, 0x72, 0x6a, 0x8b, + 0x53, 0x08, 0x3f, 0xcc, 0x59, 0xed, 0xf3, 0xd6, 0xca, 0xe3, 0x1e, 0x8b, + 0xc7, 0x6c, 0xb3, 0x3e, 0xb1, 0x08, 0x3f, 0xb2, 0x15, 0x68, 0x9e, 0x7c, + 0x9e, 0x8b, 0xa4, 0x08, 0xad, 0xa9, 0xa5, 0xb2, 0xb6, 0xa9, 0x6f, 0x63, + 0x1e, 0x8b, 0x6b, 0x7b, 0x72, 0x69, 0x76, 0x08, 0x61, 0xa2, 0x05, 0xac, + 0xfb, 0x0e, 0x15, 0xb8, 0x72, 0x9e, 0x71, 0x8b, 0x67, 0x08, 0x5a, 0x62, + 0x66, 0x56, 0x54, 0x62, 0xb4, 0xc3, 0x1e, 0x8b, 0xb7, 0xa3, 0xb2, 0xb7, + 0xa5, 0x08, 0xc5, 0x6a, 0x05, 0x7c, 0xf8, 0x19, 0x15, 0xfb, 0x5e, 0xfb, + 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, + 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, + 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, + 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, + 0x26, 0xfb, 0x26, 0xfb, 0x49, 0xfb, 0x49, 0xfb, 0x25, 0xf7, 0x26, 0xf7, + 0x4b, 0x1e, 0x8b, 0xd9, 0xa9, 0xda, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, + 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0x79, 0xf8, 0x08, 0x15, 0x8d, 0x75, 0x8b, + 0x80, 0x8b, 0x83, 0x8b, 0x46, 0x74, 0x46, 0x6a, 0x6b, 0x80, 0x81, 0x77, + 0x84, 0x77, 0x8b, 0x6f, 0x8b, 0x74, 0x9a, 0x8b, 0x9d, 0x8b, 0x8e, 0x8c, + 0x8f, 0x8c, 0x90, 0x8e, 0x96, 0x8d, 0x94, 0x8b, 0x92, 0x08, 0xa0, 0x75, + 0x9f, 0x73, 0x6f, 0x77, 0x74, 0x6c, 0x56, 0xc9, 0x64, 0xe1, 0x1e, 0xc3, + 0x8b, 0xb8, 0x9d, 0xab, 0xaf, 0xb5, 0xbb, 0xa5, 0xd5, 0x8b, 0xd6, 0x8b, + 0xcb, 0x79, 0xc5, 0x6a, 0xb7, 0x69, 0xb7, 0x5a, 0xa2, 0x4d, 0x8b, 0x08, + 0x23, 0x3e, 0x45, 0x2d, 0x3e, 0xc5, 0x52, 0xda, 0x1f, 0xc3, 0x8b, 0xb8, + 0xa4, 0xac, 0xbd, 0x08, 0x2f, 0xf7, 0x52, 0x15, 0xc0, 0xb1, 0x5d, 0x4b, + 0x4d, 0x61, 0x5b, 0x55, 0x59, 0x6a, 0xb7, 0xcf, 0xca, 0xb0, 0xb8, 0xbe, + 0x1f, 0x92, 0xf7, 0x24, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, + 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, + 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, + 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, + 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, + 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, + 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, + 0xf7, 0xd2, 0xf8, 0xe1, 0x15, 0x69, 0x06, 0x73, 0x63, 0x64, 0x78, 0x46, + 0x86, 0x08, 0x71, 0xbe, 0x07, 0xa9, 0x8b, 0x8d, 0x89, 0x8c, 0x64, 0x08, + 0xfb, 0x9d, 0x07, 0x68, 0x87, 0x86, 0x6e, 0x1e, 0x72, 0x68, 0xf7, 0x5a, + 0xae, 0x78, 0x06, 0x6c, 0x83, 0x94, 0xb1, 0x1f, 0xf8, 0x19, 0x07, 0xf7, + 0x4f, 0x91, 0x15, 0x2e, 0x58, 0x35, 0xfb, 0x30, 0x1f, 0x8b, 0x24, 0xa0, + 0x43, 0xb4, 0x63, 0x08, 0x9d, 0x7b, 0xaa, 0x80, 0xac, 0x8b, 0xc2, 0x8b, + 0xaf, 0x9d, 0xa2, 0xb0, 0xa3, 0xb3, 0x98, 0xca, 0x8b, 0xd6, 0x08, 0xf7, + 0x3d, 0x5a, 0xdd, 0x25, 0x1e, 0x8f, 0x6a, 0x15, 0xad, 0x9c, 0x46, 0xfb, + 0x1f, 0xfb, 0x1f, 0x7a, 0x47, 0x68, 0x6a, 0x79, 0xd4, 0xf7, 0x1b, 0xf7, + 0x1c, 0x9d, 0xd2, 0xad, 0x1f, 0xfb, 0x01, 0xf7, 0x24, 0x15, 0xfb, 0x5e, + 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, + 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, + 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, + 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, + 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, + 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, + 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, 0x5e, + 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, + 0xf7, 0x5b, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x58, + 0xfb, 0x35, 0xf7, 0x37, 0xfb, 0x55, 0x1f, 0xc1, 0x2e, 0x15, 0xfc, 0x31, + 0x07, 0x55, 0x9a, 0x79, 0xb6, 0x1e, 0xb3, 0x68, 0xfb, 0xb8, 0xae, 0xa9, + 0x06, 0xb8, 0x9e, 0x9b, 0xb2, 0x1f, 0x8a, 0x9c, 0x8b, 0xf7, 0x9c, 0x05, + 0xa9, 0x86, 0x90, 0x71, 0x1e, 0x3e, 0xa9, 0x06, 0xd9, 0x93, 0xc6, 0xa8, + 0xaf, 0xba, 0x08, 0xaf, 0x06, 0x0e, 0xf8, 0x25, 0xf9, 0x56, 0x15, 0xfb, + 0x5f, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x59, 0xfb, 0x5e, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0x1f, + 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x54, 0x1e, 0xf7, 0x25, 0xfc, + 0x30, 0x15, 0xb0, 0xfb, 0x5d, 0xfc, 0x09, 0x06, 0x8a, 0x97, 0x8b, 0x94, + 0x8b, 0x91, 0x8b, 0xce, 0xb0, 0xc7, 0xd9, 0xc5, 0xc8, 0xb8, 0x97, 0x96, + 0xa2, 0xaa, 0xa1, 0xa7, 0x97, 0xae, 0x8b, 0xac, 0x08, 0xc2, 0x70, 0xb0, + 0x63, 0x70, 0x6c, 0x76, 0x79, 0x1e, 0x8b, 0x89, 0x8c, 0x89, 0x8c, 0x88, + 0x94, 0x74, 0x8b, 0x8b, 0x8b, 0x82, 0x08, 0x70, 0x73, 0x74, 0x6d, 0x6b, + 0x74, 0xa4, 0xad, 0xca, 0xcc, 0xb9, 0xe6, 0x1e, 0xf7, 0x04, 0xd4, 0x54, + 0x36, 0x1f, 0x8b, 0x66, 0x7e, 0x6b, 0x70, 0x6e, 0x76, 0x74, 0x71, 0x7b, + 0x51, 0x70, 0x39, 0x66, 0x56, 0x5f, 0x7a, 0x60, 0x08, 0xf7, 0x6d, 0x06, + 0xae, 0x8b, 0x8d, 0x8c, 0x93, 0x94, 0x08, 0x91, 0x93, 0x8e, 0x98, 0x8b, + 0xa3, 0x08, 0xba, 0x07, 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, 0x5e, + 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, + 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0x1f, 0xf7, + 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1e, 0x34, 0xfb, 0xcf, 0x15, + 0x96, 0x8a, 0x94, 0x8a, 0x92, 0x8b, 0xa0, 0x8b, 0xa1, 0x91, 0x9f, 0x96, + 0xab, 0x9d, 0x9b, 0xa8, 0x8b, 0xb5, 0x8b, 0xbc, 0x6c, 0xad, 0x5e, 0x8b, + 0x71, 0x8b, 0x71, 0x7c, 0x8a, 0x7b, 0x8b, 0x8a, 0x8b, 0x8a, 0x8c, 0x8a, + 0x08, 0x8f, 0x82, 0x8c, 0x85, 0x8b, 0x82, 0x08, 0x6f, 0x73, 0x74, 0x6e, + 0x6f, 0x76, 0xa0, 0xa8, 0xc0, 0xd0, 0xb2, 0xe9, 0xf1, 0xc4, 0x62, 0x41, + 0x1e, 0x8b, 0x56, 0x6b, 0x64, 0x52, 0x7b, 0x7a, 0x86, 0x88, 0x8a, 0x8b, + 0x87, 0x8b, 0x88, 0x8f, 0x89, 0x93, 0x8a, 0x9c, 0x8a, 0xb8, 0x7e, 0x9b, + 0x82, 0xb2, 0x74, 0xa1, 0x64, 0x8b, 0x5c, 0x08, 0x2c, 0x31, 0x46, 0xfb, + 0x10, 0x27, 0x42, 0xbd, 0xcf, 0xaf, 0xa2, 0xa3, 0xae, 0x1e, 0xac, 0xa2, + 0x75, 0x6b, 0x1f, 0x8b, 0x85, 0x8a, 0x85, 0x8a, 0x86, 0x86, 0x7c, 0x8b, + 0x8b, 0x8b, 0x85, 0x08, 0x76, 0xa3, 0x7c, 0xac, 0xc4, 0xbb, 0xc5, 0xd2, + 0xca, 0x63, 0xb3, 0x4a, 0x1e, 0x7c, 0x8b, 0x7f, 0x89, 0x70, 0x86, 0x08, + 0xb3, 0x07, 0x0e, 0xf8, 0x06, 0xf8, 0x92, 0x15, 0xfb, 0x2a, 0xfb, 0x7a, + 0xf7, 0x2a, 0x8b, 0x8b, 0xf7, 0x7a, 0x05, 0xa9, 0xf7, 0x58, 0x15, 0xfb, + 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5b, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, + 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0xcf, 0x2e, 0x15, 0xfb, + 0xe1, 0xf7, 0x0c, 0x54, 0xfb, 0x0c, 0x5a, 0x07, 0x8b, 0x78, 0x8d, 0x7f, + 0x8f, 0x86, 0x90, 0x85, 0x9b, 0x85, 0x98, 0x8b, 0x08, 0xae, 0x68, 0xfb, + 0xa0, 0xae, 0xbf, 0x06, 0x9b, 0x8b, 0x9a, 0x91, 0x91, 0x93, 0x8f, 0x92, + 0x8d, 0x96, 0x8b, 0xa2, 0x08, 0xb5, 0xfb, 0x6a, 0xad, 0x07, 0xf7, 0x81, + 0xf7, 0xf6, 0xd6, 0x8b, 0x05, 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, + 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, + 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0xfb, 0x12, 0xfb, 0xe3, + 0x15, 0xac, 0xa6, 0xb5, 0x98, 0xbf, 0x8b, 0x08, 0xf1, 0xd5, 0x4a, 0x31, + 0x2a, 0x2b, 0x41, 0xfb, 0x13, 0x2e, 0x43, 0xbb, 0xc7, 0xae, 0xa3, 0xa4, + 0xac, 0xab, 0xa5, 0x74, 0x6e, 0x1f, 0x8b, 0x84, 0x89, 0x82, 0x87, 0x83, + 0x83, 0x7a, 0x8b, 0x8b, 0x8b, 0x85, 0x08, 0x77, 0xa4, 0x7a, 0xa9, 0xc6, + 0xba, 0xc6, 0xd4, 0xcd, 0x65, 0xbd, 0x58, 0x1e, 0x6c, 0x8b, 0x70, 0x7b, + 0x6d, 0x65, 0x08, 0x5f, 0x9e, 0x05, 0x97, 0xf0, 0x94, 0xe9, 0x90, 0xe8, + 0xf7, 0x0a, 0x79, 0x9b, 0x89, 0xb7, 0x8b, 0xc4, 0x8b, 0xad, 0x90, 0xb8, + 0x9a, 0x82, 0x60, 0x7a, 0x67, 0x7b, 0x7e, 0x72, 0x76, 0x71, 0x87, 0x28, + 0x8b, 0x68, 0x8b, 0x78, 0x8c, 0x66, 0x8e, 0x08, 0x7e, 0xfb, 0x1a, 0x05, + 0x0e, 0xf8, 0x26, 0xf8, 0x03, 0x15, 0x50, 0x5f, 0x57, 0x47, 0x46, 0xb3, + 0x59, 0xc4, 0xc3, 0xb2, 0xbb, 0xd0, 0xd5, 0x68, 0xbb, 0x55, 0x1f, 0x89, + 0xf7, 0xe7, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, + 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, + 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, + 0x21, 0xfc, 0x05, 0x15, 0xb1, 0xc2, 0xbc, 0xa6, 0xc8, 0x8b, 0x08, 0xe3, + 0xcb, 0x4c, 0x34, 0x21, 0x36, 0x3d, 0xfb, 0x07, 0x1f, 0x45, 0x8b, 0x56, + 0xa4, 0x65, 0xbd, 0x66, 0xbb, 0x78, 0xcb, 0x8b, 0xd2, 0x8b, 0xd5, 0xa1, + 0xd4, 0xb0, 0xc0, 0xb2, 0xc2, 0xbf, 0xa4, 0xd4, 0x8b, 0x08, 0xe8, 0xd0, + 0x60, 0x52, 0x69, 0x75, 0x72, 0x6d, 0x6f, 0x74, 0xa1, 0xa4, 0x1f, 0x8b, + 0x92, 0x8d, 0x95, 0x8d, 0x97, 0x8c, 0x90, 0x8c, 0x8f, 0x8b, 0x8f, 0x8b, + 0xa0, 0x73, 0x9b, 0x6b, 0x8b, 0x76, 0x8b, 0x74, 0x83, 0x7f, 0x7f, 0x66, + 0x68, 0x73, 0x40, 0x8b, 0x3c, 0x8b, 0x83, 0x8c, 0x72, 0x8c, 0x80, 0x08, + 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, 0x5f, 0xfb, 0x36, 0xfb, 0x33, + 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, + 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, + 0xfb, 0x55, 0x1f, 0xfb, 0x5c, 0x2c, 0x15, 0xf8, 0x1e, 0x06, 0x88, 0x84, + 0x88, 0x86, 0x8a, 0x89, 0x08, 0xfb, 0x0d, 0xfb, 0x61, 0x05, 0x59, 0x33, + 0x7f, 0x6c, 0x8b, 0x5d, 0x8b, 0x82, 0x8c, 0x82, 0x8c, 0x81, 0x92, 0x62, + 0x8b, 0x8b, 0x8b, 0x83, 0x08, 0x64, 0x71, 0x71, 0x63, 0x64, 0x70, 0xa9, + 0xb6, 0x1e, 0x8b, 0xbb, 0xa8, 0xc9, 0xc6, 0xd7, 0x08, 0xb8, 0xc6, 0xdc, + 0xf7, 0x03, 0xfb, 0x5e, 0x8b, 0x05, 0x66, 0x8a, 0x8a, 0x8a, 0x7e, 0x5a, + 0x08, 0x82, 0x65, 0x6a, 0x8b, 0x8b, 0xf7, 0x4e, 0x05, 0x0e, 0xf8, 0x40, + 0xf8, 0x40, 0x15, 0xae, 0xa1, 0x9c, 0xa7, 0x8b, 0xae, 0x08, 0xb6, 0x6a, + 0xab, 0x5f, 0x60, 0x6a, 0x6f, 0x66, 0x1e, 0x8b, 0x6f, 0x9c, 0x74, 0xb0, + 0x78, 0x08, 0xba, 0x72, 0x05, 0x40, 0x41, 0x15, 0x5d, 0x70, 0x71, 0x61, + 0x8b, 0x5b, 0x08, 0x4f, 0xb8, 0x5e, 0xc6, 0xc5, 0xb7, 0xb3, 0xbf, 0x1e, + 0x8b, 0xb2, 0x76, 0xa6, 0x5b, 0xa7, 0x08, 0x4a, 0xaf, 0x05, 0xba, 0xf7, + 0xf4, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, + 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, + 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0xcc, + 0xfb, 0xbc, 0x15, 0xe0, 0x60, 0xae, 0x5f, 0x8b, 0x47, 0x08, 0x28, 0x38, + 0x44, 0xfb, 0x07, 0xfb, 0x01, 0x43, 0xc3, 0xe1, 0x1e, 0x8b, 0xca, 0xa7, + 0xb1, 0xdd, 0xba, 0x52, 0xb2, 0x79, 0xa5, 0x8b, 0xbc, 0x08, 0xda, 0xcf, + 0xc4, 0xea, 0xdd, 0xc7, 0x5e, 0x4e, 0x1e, 0x8b, 0x60, 0x77, 0x70, 0x4e, + 0x64, 0x08, 0x0e, 0xf8, 0x19, 0xf8, 0xdf, 0x15, 0x53, 0x64, 0x5b, 0x45, + 0x42, 0xb0, 0x5c, 0xc4, 0xc4, 0xb5, 0xbe, 0xcf, 0xd0, 0x62, 0xbd, 0x52, + 0x1f, 0x96, 0xf7, 0x0b, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, + 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, + 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, + 0x55, 0x1f, 0xe9, 0xfb, 0xeb, 0x15, 0x65, 0x5c, 0x5f, 0x77, 0x4d, 0x8b, + 0x08, 0x2d, 0x4b, 0xc7, 0xe3, 0xf3, 0xdf, 0xd8, 0xf7, 0x05, 0xf7, 0x17, + 0xe2, 0x25, 0xfb, 0x2e, 0x1f, 0x8b, 0x3d, 0x75, 0x40, 0x65, 0x54, 0x67, + 0x58, 0x55, 0x72, 0x41, 0x8b, 0x08, 0x30, 0x47, 0xb7, 0xc7, 0xae, 0xa2, + 0xa7, 0xa9, 0xa7, 0xa1, 0x73, 0x6e, 0x1f, 0x8b, 0x86, 0x8a, 0x85, 0x8a, + 0x86, 0x88, 0x80, 0x8a, 0x83, 0x8b, 0x88, 0x8b, 0x75, 0xa4, 0x7a, 0xaa, + 0x8b, 0xa3, 0x8b, 0xa4, 0x96, 0x9a, 0x9b, 0xac, 0xb2, 0x9f, 0xd0, 0x8b, + 0xd7, 0x08, 0x8b, 0x95, 0x8b, 0x9f, 0x05, 0x0e, 0xf8, 0xa0, 0xf8, 0xe0, + 0x15, 0x63, 0x75, 0x3a, 0xfb, 0x2e, 0xfb, 0x2d, 0xa1, 0x39, 0xb3, 0xb4, + 0xa0, 0xd9, 0xf7, 0x30, 0xf7, 0x32, 0x76, 0xd9, 0x62, 0x1f, 0xfb, 0x13, + 0xf7, 0x0a, 0x15, 0xfb, 0x5c, 0xfb, 0x36, 0xfb, 0x35, 0xfb, 0x5b, 0xfb, + 0x59, 0xf7, 0x35, 0xfb, 0x36, 0xf7, 0x5a, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, + 0x35, 0xf7, 0x5a, 0xf7, 0x59, 0xfb, 0x35, 0xf7, 0x37, 0xfb, 0x58, 0x1f, + 0x33, 0x2e, 0x15, 0xfc, 0x42, 0x07, 0x8b, 0x74, 0x8d, 0x80, 0x8f, 0x85, + 0x91, 0x84, 0x9b, 0x86, 0x99, 0x8b, 0x08, 0xa1, 0x65, 0xfb, 0x70, 0xb1, + 0xa7, 0x06, 0xab, 0x8f, 0x90, 0xb2, 0x1f, 0xf7, 0xba, 0x07, 0x8a, 0xac, + 0x8b, 0x8b, 0x87, 0x90, 0x86, 0x8f, 0x7e, 0x8e, 0x7e, 0x8b, 0x08, 0x52, + 0xa8, 0x06, 0xd9, 0x90, 0xb4, 0x9f, 0xa7, 0xb8, 0x08, 0xb1, 0x06, 0xf7, + 0x67, 0x93, 0x15, 0xf7, 0x04, 0xc2, 0x30, 0xfb, 0x4f, 0x1f, 0x8b, 0x46, + 0x80, 0x49, 0x79, 0x63, 0x70, 0x50, 0x62, 0x73, 0x45, 0x8b, 0x67, 0x8b, + 0x68, 0x97, 0x77, 0x9d, 0x5d, 0xb7, 0x74, 0xda, 0x8b, 0xf7, 0x06, 0x08, + 0xf7, 0x42, 0xc3, 0xea, 0xf3, 0x1e, 0x0e, 0xf8, 0x1c, 0xf8, 0xe0, 0x15, + 0x81, 0x55, 0x6a, 0x77, 0x3e, 0x8c, 0x08, 0x62, 0xec, 0xfb, 0xf9, 0xc7, + 0xf8, 0x6b, 0x66, 0x07, 0x93, 0xf7, 0x0a, 0x15, 0xfb, 0x5e, 0xfb, 0x37, + 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, + 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, + 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, + 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, 0x26, + 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, + 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, + 0x8b, 0x08, 0x0e, 0xf8, 0xae, 0xf7, 0x3d, 0x15, 0xfb, 0x75, 0x06, 0x99, + 0xa8, 0x94, 0x94, 0xc2, 0xb0, 0xf7, 0x0c, 0xdb, 0xaa, 0xb4, 0x8b, 0xd7, + 0x08, 0xe0, 0x4a, 0xca, 0x33, 0x36, 0x4c, 0x4d, 0x37, 0x1e, 0x7d, 0xc8, + 0x07, 0x8a, 0x91, 0x8b, 0x91, 0x8b, 0x8e, 0x08, 0xc7, 0xae, 0xb3, 0xc0, + 0xc1, 0xb1, 0x61, 0x4f, 0x1e, 0x8b, 0x4e, 0x73, 0x6c, 0x2d, 0x4e, 0x3d, + 0x58, 0x66, 0x59, 0x8b, 0x54, 0x8b, 0x86, 0x8b, 0x87, 0x8c, 0x84, 0x08, + 0xf7, 0xb5, 0xbf, 0x06, 0xfb, 0x1e, 0xf8, 0xad, 0x15, 0xfb, 0x5e, 0xfb, + 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, + 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, + 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, + 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, + 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, + 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, + 0xef, 0x8b, 0x08, 0x0e, 0xf7, 0xca, 0xf8, 0x62, 0x15, 0x8b, 0x9d, 0x8d, + 0x94, 0x8e, 0x96, 0x94, 0xa9, 0xa8, 0x9f, 0xb0, 0x8b, 0xbe, 0x8b, 0xab, + 0x6b, 0x8b, 0x58, 0x8b, 0x6c, 0x82, 0x76, 0x78, 0x7e, 0x74, 0x7c, 0x75, + 0x83, 0x76, 0x8b, 0x88, 0x8b, 0x84, 0x8c, 0x81, 0x8c, 0x08, 0x82, 0x60, + 0xac, 0x06, 0xcf, 0xb2, 0x6b, 0x52, 0x57, 0x66, 0x67, 0x55, 0x1f, 0x6c, + 0x8b, 0x6f, 0x98, 0x7b, 0xa2, 0x81, 0x99, 0x87, 0x9d, 0x8b, 0xab, 0x08, + 0x55, 0x80, 0x05, 0x8a, 0x84, 0x8b, 0x84, 0x8b, 0x86, 0x08, 0x46, 0xc7, + 0x58, 0xdb, 0xe4, 0xc9, 0xc4, 0xdc, 0x1e, 0x8b, 0xc6, 0x70, 0xb0, 0x55, + 0x9d, 0x08, 0xbb, 0xa1, 0x9f, 0xa9, 0x8b, 0xbd, 0x8b, 0xd5, 0x4f, 0xc3, + 0x3a, 0x8b, 0x59, 0x8b, 0x5d, 0x74, 0x75, 0x65, 0x7f, 0x77, 0x86, 0x78, + 0x8a, 0x6a, 0x08, 0xc1, 0x06, 0xe5, 0xf7, 0x88, 0x15, 0xfb, 0x5e, 0xfb, + 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, + 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, + 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, + 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, + 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, + 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, + 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0xae, 0xf7, 0xb1, 0x15, 0x40, 0xf7, 0xc8, + 0x53, 0x06, 0xfb, 0x63, 0xfb, 0xc8, 0x8b, 0x59, 0xf7, 0x63, 0x8b, 0x8b, + 0xfb, 0x0a, 0xc3, 0x8b, 0x8b, 0xf7, 0x0a, 0xd6, 0x8b, 0x8b, 0xbd, 0x05, + 0xfb, 0x17, 0xf7, 0x79, 0x15, 0xfb, 0x79, 0xfb, 0x2b, 0x07, 0xf7, 0x2b, + 0xf7, 0x79, 0x05, 0x84, 0xf7, 0x54, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, + 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, + 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, + 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, + 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, + 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, + 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, + 0x08, 0x0e, 0xf7, 0xa1, 0xf8, 0xdd, 0x15, 0xfb, 0x9e, 0xb8, 0x07, 0x95, + 0xbf, 0xac, 0xa9, 0xb9, 0x8b, 0xc3, 0x8b, 0xb1, 0x62, 0x8b, 0x4e, 0x8b, + 0x61, 0x81, 0x62, 0x7b, 0x73, 0x7d, 0x78, 0x70, 0x7e, 0x6e, 0x8b, 0x58, + 0x8b, 0x68, 0xac, 0x8a, 0xbd, 0x08, 0x5e, 0x7f, 0x05, 0x8f, 0x41, 0xbd, + 0x5c, 0xd6, 0x8b, 0x08, 0xe7, 0xce, 0xd5, 0xf1, 0xe9, 0x4e, 0xcd, 0x34, + 0x1f, 0x5d, 0x8b, 0x70, 0x7e, 0x75, 0x6c, 0x08, 0xf7, 0x19, 0xf7, 0x5d, + 0xbd, 0xfb, 0x8a, 0x07, 0xf7, 0x17, 0xf7, 0x0d, 0x15, 0xfb, 0x5e, 0xfb, + 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, + 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, + 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, + 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, + 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, + 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, + 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0x9c, 0xf8, 0x7c, 0x15, 0x7e, 0xd1, 0x61, + 0xb0, 0x49, 0x8b, 0x51, 0x8b, 0x53, 0x67, 0x72, 0x56, 0x79, 0x63, 0x82, + 0x59, 0x8b, 0x47, 0x8b, 0x41, 0x96, 0x54, 0xa1, 0x65, 0xa3, 0x61, 0xbc, + 0x6f, 0xbc, 0x8b, 0x08, 0xde, 0xc9, 0xd0, 0xe7, 0xe2, 0x53, 0xc8, 0x3c, + 0x1f, 0x58, 0x8b, 0x67, 0x74, 0x76, 0x5e, 0x8a, 0x95, 0x8b, 0x94, 0x8b, + 0x8f, 0x8b, 0xf7, 0x00, 0xb4, 0xce, 0xcc, 0x8b, 0xa5, 0x8b, 0xa2, 0x7e, + 0x96, 0x78, 0x91, 0x80, 0x8d, 0x84, 0x91, 0x71, 0x08, 0xbe, 0x99, 0x05, + 0xfb, 0x16, 0x20, 0x15, 0xc0, 0xad, 0x5e, 0x44, 0x49, 0x69, 0x60, 0x58, + 0x53, 0x62, 0xbd, 0xcf, 0xc8, 0xb4, 0xb9, 0xc1, 0x1f, 0x95, 0xf7, 0xd9, + 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, + 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, + 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, + 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, + 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, + 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, + 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf7, 0x82, 0xf8, 0xdc, + 0x15, 0x59, 0xf7, 0x92, 0x07, 0x24, 0xfb, 0x0f, 0x3d, 0xfb, 0x38, 0x78, + 0xfb, 0x16, 0x08, 0xcf, 0x06, 0xa3, 0xf7, 0x1f, 0xc2, 0xf7, 0x10, 0xf7, + 0x03, 0xf7, 0x36, 0x08, 0xb5, 0xfb, 0xcc, 0x07, 0xf7, 0x36, 0xf7, 0x0e, + 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, + 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, + 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, + 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, + 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, + 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, + 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0x5e, 0xf8, 0x02, + 0x15, 0x9c, 0x92, 0x94, 0x90, 0x93, 0x90, 0xa5, 0x9d, 0x9a, 0xac, 0x8b, + 0xb0, 0x08, 0xd5, 0x55, 0xbd, 0x3d, 0x3b, 0x51, 0x57, 0x45, 0x1e, 0x8b, + 0x58, 0xa1, 0x6a, 0xbd, 0x74, 0x76, 0x84, 0x7f, 0x85, 0x81, 0x84, 0x08, + 0x6d, 0x77, 0x7a, 0x68, 0x8b, 0x60, 0x08, 0x3a, 0xc8, 0x53, 0xe2, 0xe2, + 0xca, 0xc5, 0xdb, 0x1e, 0x8b, 0xc7, 0x70, 0xb0, 0x51, 0x9f, 0x08, 0x4e, + 0xf7, 0x52, 0x15, 0xc0, 0xac, 0x6a, 0x56, 0x59, 0x67, 0x68, 0x58, 0x59, + 0x6a, 0xad, 0xbe, 0x1f, 0xbf, 0xad, 0xad, 0xbd, 0x1e, 0x88, 0xfb, 0x6c, + 0x15, 0xc6, 0xad, 0x68, 0x50, 0x53, 0x65, 0x63, 0x55, 0x55, 0x63, 0xb4, + 0xc2, 0x1f, 0xc3, 0xb1, 0xb1, 0xc2, 0x1e, 0x91, 0xf8, 0x02, 0x15, 0xfb, + 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, + 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, + 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, + 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, + 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, + 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf7, 0x9c, 0xf7, 0x69, 0x15, 0x90, + 0x70, 0x8f, 0x7e, 0x94, 0x7c, 0x9e, 0x6e, 0xb1, 0x78, 0xb4, 0x8b, 0xae, + 0x8b, 0xaf, 0x98, 0xa4, 0xa2, 0xba, 0xb5, 0xa0, 0xcb, 0x8b, 0xf4, 0x8b, + 0xce, 0x80, 0xc6, 0x79, 0xae, 0x71, 0xbd, 0x5f, 0xa6, 0x55, 0x8b, 0x08, + 0x36, 0x4d, 0x47, 0x30, 0x34, 0xc1, 0x4e, 0xd9, 0x1f, 0xc1, 0x8b, 0xae, + 0xa0, 0xa2, 0xba, 0x89, 0x3a, 0x85, 0x69, 0x7c, 0x6d, 0x79, 0x67, 0x6e, + 0x77, 0x6a, 0x8b, 0x66, 0x8b, 0x72, 0xa2, 0x81, 0xb8, 0x08, 0x5a, 0x81, + 0x05, 0xf7, 0x0e, 0xf7, 0xeb, 0x15, 0xc2, 0xb3, 0x59, 0x45, 0x4c, 0x65, + 0x5e, 0x54, 0x53, 0x6b, 0xb6, 0xd5, 0xcf, 0xac, 0xb6, 0xc0, 0x1f, 0x99, + 0xf7, 0x2a, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, + 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, + 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, + 0x6a, 0x04, 0xd5, 0x8b, 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, + 0x8b, 0x2d, 0x08, 0xfb, 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, + 0x4a, 0xfb, 0x25, 0xf7, 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, + 0xc1, 0xc6, 0xcc, 0xd3, 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0x74, + 0xf8, 0xe7, 0x15, 0x61, 0x8b, 0x66, 0x78, 0x72, 0x6a, 0x6e, 0x64, 0x7e, + 0x50, 0x8b, 0x33, 0x8b, 0x2e, 0x9d, 0x43, 0xad, 0x63, 0xa1, 0x70, 0xad, + 0x7c, 0xae, 0x8b, 0xb3, 0x8b, 0xad, 0x9c, 0xa5, 0xad, 0xa8, 0xaf, 0x9b, + 0xce, 0x8b, 0xdd, 0x08, 0xf7, 0x3b, 0x5c, 0xdd, 0x2c, 0x1e, 0x88, 0x64, + 0x15, 0xc5, 0xa7, 0x45, 0xfb, 0x1f, 0xfb, 0x17, 0x70, 0x49, 0x54, 0x53, + 0x6b, 0xd6, 0xf7, 0x19, 0xf7, 0x16, 0xa8, 0xcf, 0xc2, 0x1f, 0xfb, 0x74, + 0xab, 0x15, 0x86, 0x5d, 0x65, 0x6f, 0x50, 0x8a, 0x08, 0x62, 0xde, 0xfb, + 0xf7, 0xc7, 0xf8, 0x6b, 0x62, 0x07, 0xf7, 0x27, 0xf7, 0x0a, 0x15, 0xfb, + 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, + 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0x6a, 0x04, 0xd5, 0x8b, + 0xdd, 0x6b, 0xc4, 0x57, 0xd2, 0x4a, 0xb0, 0x38, 0x8b, 0x2d, 0x08, 0xfb, + 0x49, 0xfb, 0x26, 0xfb, 0x26, 0xfb, 0x48, 0xfb, 0x4a, 0xfb, 0x25, 0xf7, + 0x26, 0xf7, 0x4b, 0x1e, 0x8b, 0xda, 0xa9, 0xd9, 0xc1, 0xc6, 0xcc, 0xd3, + 0xde, 0xaf, 0xef, 0x8b, 0x08, 0x0e, 0xf8, 0x25, 0xf9, 0x56, 0x15, 0xfb, + 0x5f, 0xfb, 0x37, 0xfb, 0x32, 0xfb, 0x5a, 0xfb, 0x5e, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5c, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, + 0x58, 0xfb, 0x35, 0xf7, 0x37, 0xfb, 0x55, 0x1f, 0xb7, 0x22, 0x15, 0xfc, + 0x77, 0x30, 0xf7, 0xf8, 0x2b, 0xc1, 0x07, 0xe2, 0x8a, 0xa2, 0x99, 0x97, + 0xc7, 0x08, 0xcc, 0x06, 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, 0x5f, + 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, + 0xf7, 0x5c, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, + 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0xf7, 0x2b, 0xfc, 0x9f, 0x15, + 0x4a, 0xfb, 0xd0, 0x07, 0x8a, 0x94, 0x8a, 0x93, 0x8b, 0x8f, 0x8b, 0xaa, + 0x99, 0xac, 0xa2, 0xa8, 0xa1, 0xa6, 0x9d, 0x99, 0xbb, 0xaa, 0xdf, 0xc1, + 0xa4, 0xac, 0x8b, 0xc5, 0x08, 0xc4, 0x6b, 0xb2, 0x5d, 0x5d, 0x6e, 0x65, + 0x4e, 0x1e, 0x8b, 0x87, 0x8b, 0x84, 0x8c, 0x82, 0x08, 0x33, 0x93, 0x05, + 0x8a, 0x93, 0x8b, 0x93, 0x8b, 0x8f, 0x08, 0xe2, 0xd1, 0xcb, 0xe9, 0xed, + 0xd2, 0x49, 0x31, 0x1e, 0x8b, 0x4f, 0x70, 0x5d, 0x4e, 0x5c, 0x77, 0x7c, + 0x72, 0x7a, 0x6e, 0x77, 0x5c, 0x6c, 0x80, 0x81, 0x81, 0x77, 0x08, 0xf7, + 0x72, 0x06, 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, 0x5f, 0xfb, 0x37, + 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, + 0xf7, 0x5b, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, + 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0xfb, 0x32, 0xfb, 0x83, 0x15, 0x8d, 0xb2, + 0x90, 0xa0, 0x9a, 0xa1, 0xa3, 0xaf, 0xbc, 0xa2, 0xc1, 0x8b, 0xe3, 0x8b, + 0xcc, 0x51, 0x8b, 0x3c, 0x8b, 0x5e, 0x78, 0x69, 0x64, 0x76, 0x9c, 0x81, + 0x96, 0x83, 0x93, 0x85, 0xa2, 0x76, 0x98, 0x6b, 0x8b, 0x64, 0x08, 0x34, + 0x48, 0x4d, 0x2b, 0x31, 0x4a, 0xc2, 0xd9, 0x1e, 0x8b, 0x8e, 0x8c, 0x96, + 0x8c, 0x93, 0x08, 0xdd, 0x9d, 0x05, 0x8a, 0x84, 0x8b, 0x82, 0x8b, 0x89, + 0x08, 0x54, 0xa5, 0x6d, 0xba, 0xb8, 0xa9, 0xac, 0xbd, 0xbe, 0x6c, 0xa8, + 0x55, 0x1e, 0x7f, 0x8b, 0x7f, 0x8a, 0x71, 0x89, 0x08, 0xc8, 0x07, 0xa2, + 0x89, 0x94, 0x8a, 0x91, 0x8b, 0x08, 0xbf, 0xab, 0xa8, 0xb9, 0xbd, 0x73, + 0xa8, 0x60, 0x1f, 0x73, 0x8b, 0x77, 0x81, 0x80, 0x79, 0x82, 0x7d, 0x88, + 0x7e, 0x8b, 0x68, 0x08, 0x39, 0x94, 0x05, 0x0e, 0xf8, 0x1e, 0xf8, 0x7a, + 0x15, 0xfb, 0x0f, 0xfb, 0x4d, 0xf7, 0x0f, 0x8b, 0x8b, 0xf7, 0x4d, 0x05, + 0x91, 0xf7, 0x70, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, 0x59, + 0xfb, 0x5e, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, + 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, + 0x1f, 0xf7, 0x2b, 0xfc, 0x29, 0x15, 0x49, 0x40, 0xfb, 0x09, 0x39, 0xf7, + 0x09, 0xfb, 0x63, 0xcd, 0x07, 0xf7, 0x6d, 0xf7, 0xc5, 0xd3, 0x8b, 0x8b, + 0xfb, 0xc5, 0xd6, 0x8b, 0x05, 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, + 0x5f, 0xfb, 0x36, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5b, 0xf7, 0x5b, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, + 0x58, 0xfb, 0x35, 0xf7, 0x37, 0xfb, 0x55, 0x1f, 0xfb, 0x25, 0x21, 0x15, + 0xf7, 0xad, 0x4a, 0xfb, 0x66, 0x2c, 0x06, 0xad, 0x9b, 0x9c, 0x8f, 0xaa, + 0x8b, 0x08, 0xed, 0xcd, 0x48, 0x27, 0x21, 0x42, 0x3f, 0x25, 0x1f, 0x37, + 0x8b, 0x55, 0xbd, 0x87, 0xdc, 0x08, 0xd2, 0x9e, 0x05, 0x52, 0xa5, 0x6a, + 0xba, 0xc0, 0xa9, 0xb6, 0xd8, 0x1e, 0x8b, 0xb0, 0x87, 0x9e, 0x80, 0x9d, + 0x7d, 0xa0, 0x72, 0x99, 0x71, 0x8b, 0x62, 0x8b, 0x72, 0x70, 0x81, 0x55, + 0x08, 0x44, 0xf7, 0xad, 0x06, 0x0e, 0xf8, 0x19, 0xf8, 0x0c, 0x15, 0x5d, + 0x69, 0x61, 0x53, 0x4e, 0xae, 0x5d, 0xbb, 0xb6, 0xa6, 0xb1, 0xc7, 0xcd, + 0x6f, 0xb4, 0x5e, 0x1f, 0x96, 0xf7, 0xde, 0x15, 0xfb, 0x5e, 0xfb, 0x37, + 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, + 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, + 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0xc5, 0xfb, 0x7f, 0x15, 0x89, 0x93, 0x89, + 0x92, 0x8a, 0x8e, 0x80, 0xb6, 0x7c, 0x99, 0x69, 0x8b, 0x67, 0x8b, 0x71, + 0x76, 0x7f, 0x64, 0x82, 0x72, 0x89, 0x7a, 0x86, 0x58, 0xae, 0xaa, 0xa3, + 0x95, 0xb2, 0x8b, 0x08, 0xe0, 0xc8, 0x49, 0x30, 0x29, 0x47, 0x42, 0x30, + 0x1f, 0x56, 0x8b, 0x57, 0xa7, 0x6f, 0xb6, 0x73, 0xb1, 0x7f, 0xc3, 0x8b, + 0xdb, 0x8b, 0xd3, 0x94, 0xba, 0xa2, 0xb7, 0xa7, 0xc2, 0xc5, 0xae, 0xc9, + 0x8b, 0xba, 0x8b, 0xb4, 0x79, 0xa2, 0x6b, 0x97, 0x7a, 0x91, 0x7d, 0x91, + 0x6b, 0x08, 0x3f, 0x77, 0x05, 0x0e, 0xf8, 0x24, 0xf9, 0x56, 0x15, 0xfb, + 0x5f, 0xfb, 0x36, 0xfb, 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, + 0x35, 0xf7, 0x5c, 0xf7, 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5a, 0xf7, + 0x58, 0xfb, 0x35, 0xf7, 0x38, 0xfb, 0x55, 0x1f, 0xfb, 0x45, 0x20, 0x15, + 0xf7, 0xe8, 0x59, 0x06, 0x22, 0xfb, 0x43, 0x5f, 0xfb, 0x01, 0x74, 0xfb, + 0x28, 0x08, 0x2c, 0x06, 0x9e, 0xf7, 0x1b, 0xd2, 0xf7, 0x30, 0xee, 0xf7, + 0x12, 0x08, 0xfb, 0x9a, 0xcc, 0x06, 0x0e, 0xf8, 0x22, 0xf8, 0xbb, 0x15, + 0x63, 0x71, 0x6e, 0x5c, 0x5c, 0xa4, 0x6e, 0xb3, 0xb4, 0xa7, 0xaa, 0xba, + 0xb9, 0x71, 0xa7, 0x61, 0x1f, 0x86, 0xfb, 0x67, 0x15, 0x5c, 0x6c, 0x6a, + 0x59, 0x57, 0xac, 0x67, 0xba, 0xba, 0xab, 0xaf, 0xbf, 0xbf, 0x6d, 0xaa, + 0x58, 0x1f, 0x92, 0xf8, 0x02, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, + 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, 0x5a, + 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, + 0xfb, 0x55, 0x1f, 0xdb, 0xfb, 0xe0, 0x15, 0xc4, 0x69, 0x9e, 0x6e, 0x8b, + 0x57, 0x08, 0x34, 0x45, 0x49, 0x2e, 0x2f, 0x46, 0xcb, 0xe0, 0x1e, 0x8b, + 0xc4, 0xa7, 0xb3, 0xc1, 0xa1, 0x63, 0x9f, 0x73, 0xb1, 0x8b, 0xb9, 0x08, + 0xd5, 0xcd, 0xc4, 0xe0, 0xdf, 0xc8, 0x53, 0x3f, 0x1e, 0x8b, 0x5b, 0x79, + 0x6f, 0x5b, 0x70, 0x08, 0x0e, 0xf8, 0x14, 0xf8, 0xbb, 0x15, 0x60, 0x70, + 0x65, 0x4f, 0x49, 0xa7, 0x62, 0xb8, 0xb9, 0xad, 0xb5, 0xc3, 0xc8, 0x68, + 0xb9, 0x5b, 0x1f, 0x9b, 0xf7, 0x2f, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, + 0x33, 0xfb, 0x5a, 0xfb, 0x5d, 0xf7, 0x34, 0xfb, 0x35, 0xf7, 0x5c, 0xf7, + 0x5a, 0xf7, 0x35, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, + 0x38, 0xfb, 0x55, 0x1f, 0x40, 0xfc, 0x67, 0x15, 0x95, 0x57, 0x9d, 0x76, + 0xab, 0x8b, 0x9b, 0x8b, 0x9d, 0x93, 0x97, 0x97, 0xa5, 0xa7, 0x95, 0xab, + 0x90, 0xd6, 0x70, 0x70, 0x6c, 0x7f, 0x63, 0x8b, 0x08, 0x37, 0x4f, 0xcd, + 0xe7, 0xec, 0xcf, 0xd2, 0xe7, 0x1f, 0xbd, 0x8b, 0xb5, 0x77, 0xa9, 0x64, + 0xa9, 0x65, 0x9a, 0x4c, 0x8b, 0x35, 0x8b, 0x43, 0x7f, 0x4c, 0x76, 0x67, + 0x6c, 0x55, 0x56, 0x6c, 0x4f, 0x8b, 0x5e, 0x8b, 0x62, 0x9e, 0x75, 0xab, + 0x7f, 0x9c, 0x86, 0x9b, 0x85, 0xae, 0x08, 0xd7, 0x99, 0x05, 0x0e, 0xf8, + 0x78, 0xf8, 0xb9, 0x15, 0x5d, 0x73, 0x49, 0xfb, 0x0e, 0xfb, 0x0e, 0xa7, + 0x41, 0xb8, 0xb7, 0xa3, 0xcc, 0xf7, 0x0d, 0xf7, 0x16, 0x72, 0xcf, 0x5d, + 0x1f, 0x37, 0xf7, 0x31, 0x15, 0xfb, 0x5e, 0xfb, 0x37, 0xfb, 0x33, 0xfb, + 0x5a, 0xfb, 0x5d, 0xf7, 0x33, 0xfb, 0x35, 0xf7, 0x5d, 0xf7, 0x5b, 0xf7, + 0x34, 0xf7, 0x35, 0xf7, 0x5b, 0xf7, 0x57, 0xfb, 0x35, 0xf7, 0x38, 0xfb, + 0x55, 0x1f, 0x28, 0x22, 0x15, 0xfc, 0x78, 0x35, 0xf7, 0xf7, 0x38, 0xc1, + 0x07, 0xce, 0x8a, 0xa9, 0xa1, 0x91, 0xc1, 0x08, 0xcd, 0x06, 0xf7, 0x4d, + 0x92, 0x15, 0xf3, 0xc0, 0x36, 0xfb, 0x3d, 0xfb, 0x35, 0x53, 0x34, 0x23, + 0x25, 0x54, 0xe5, 0xf7, 0x3a, 0x1f, 0x8b, 0xe5, 0x9a, 0xca, 0xab, 0xb3, + 0xa7, 0xad, 0xb2, 0x9e, 0xb9, 0x8b, 0x08, 0x0e, 0xc2, 0xf8, 0x22, 0xf9, + 0x0e, 0x15, 0xf7, 0x6b, 0xfb, 0x70, 0xfc, 0xd6, 0x8b, 0x8b, 0xfb, 0x18, + 0xf8, 0xd6, 0x8b, 0xfb, 0x6b, 0xfb, 0x74, 0xf7, 0x47, 0x8b, 0xf7, 0xaf, + 0xf7, 0xb3, 0xfb, 0xaf, 0xf7, 0xb5, 0xfb, 0x47, 0x8b, 0x05, 0x0e, 0x8a, + 0xae, 0xf7, 0xf5, 0x15, 0x78, 0xf8, 0xe1, 0x07, 0x53, 0x46, 0x75, 0x55, + 0x8c, 0x4f, 0xc7, 0xe1, 0xf7, 0x02, 0xde, 0xe1, 0xa2, 0x36, 0xa3, 0x26, + 0xd8, 0x45, 0xe8, 0x89, 0x4e, 0xaf, 0x36, 0xb6, 0x65, 0x08, 0xfc, 0xe1, + 0x06, 0x0e, 0xf7, 0x45, 0xf7, 0x69, 0xf7, 0xf5, 0x15, 0xc1, 0xcd, 0xa4, + 0xc7, 0x89, 0xc5, 0x50, 0x36, 0xfb, 0x05, 0x35, 0x37, 0x74, 0xde, 0x75, + 0xf6, 0x3b, 0xcd, 0x31, 0x8d, 0xc8, 0x68, 0xde, 0x5f, 0xb2, 0x08, 0xf8, + 0xe2, 0x06, 0x53, 0x46, 0x74, 0x55, 0x8d, 0x4f, 0xc6, 0xe1, 0xf7, 0x03, + 0xdf, 0xe0, 0xa1, 0x37, 0xa2, 0x25, 0xd9, 0x46, 0xe8, 0x89, 0x4e, 0xaf, + 0x35, 0xb6, 0x66, 0x08, 0xfc, 0xe2, 0x06, 0x0e, 0xfc, 0x11, 0xf7, 0x82, + 0xf9, 0x14, 0x15, 0xcd, 0x55, 0xc6, 0x72, 0xc6, 0x8d, 0x36, 0xc5, 0x36, + 0xf7, 0x04, 0x73, 0xe1, 0x73, 0x35, 0x3f, 0x27, 0x2e, 0x45, 0xc8, 0x89, + 0xde, 0xae, 0xb3, 0xb7, 0x08, 0xfc, 0xe1, 0x07, 0x46, 0xc3, 0x52, 0xa3, + 0x51, 0x88, 0xe1, 0x4f, 0xdf, 0xfb, 0x02, 0xa2, 0x35, 0xa3, 0xe1, 0xda, + 0xf2, 0xe6, 0xce, 0x4e, 0x8d, 0x36, 0x68, 0x65, 0x5f, 0x08, 0xf8, 0xe1, + 0x07, 0x0e, 0x30, 0xf7, 0x0f, 0xf8, 0xe9, 0x15, 0x33, 0xfb, 0x11, 0xf8, + 0x04, 0xfb, 0x6b, 0x38, 0xfb, 0x04, 0xf8, 0x0e, 0x58, 0xfb, 0x40, 0xf7, + 0xeb, 0x3d, 0xfb, 0x09, 0xfb, 0xd9, 0xf7, 0xa9, 0x05, 0x0e, 0xe0, 0xae, + 0xf8, 0x4c, 0x15, 0x8b, 0xfb, 0x50, 0xf8, 0xb2, 0xcd, 0x3b, 0xfb, 0x46, + 0xf8, 0x1d, 0xf7, 0x62, 0xfc, 0x1d, 0xf7, 0x61, 0xdb, 0xfb, 0x46, 0xfc, + 0xb2, 0xce, 0x05, 0x0e, 0x30, 0xf7, 0x0f, 0xe9, 0x15, 0xf7, 0xd9, 0xf7, + 0xa9, 0xd9, 0xfb, 0x08, 0xf7, 0x40, 0xf7, 0xea, 0xfc, 0x0e, 0x59, 0xde, + 0xfb, 0x05, 0xfc, 0x04, 0xfb, 0x6b, 0xe3, 0xfb, 0x11, 0x05, 0x0e, 0xda, + 0xae, 0xf8, 0x04, 0x15, 0x8b, 0x5e, 0xf7, 0xff, 0x9a, 0x05, 0x66, 0x5b, + 0x61, 0x47, 0x71, 0x54, 0xf7, 0x2c, 0xcc, 0xc4, 0xa1, 0xd5, 0xa2, 0xf7, + 0x0a, 0xae, 0xf7, 0x19, 0xa8, 0xc4, 0x8f, 0xfb, 0x7f, 0xb2, 0x27, 0xaa, + 0xfb, 0x94, 0xf7, 0x03, 0x08, 0x87, 0x07, 0xa6, 0x54, 0xb4, 0x4a, 0xb0, + 0x5b, 0x08, 0xfb, 0xff, 0x99, 0x05, 0x0e, 0xe3, 0xf8, 0xda, 0xf7, 0x98, + 0x15, 0x56, 0x56, 0x05, 0x68, 0x68, 0x7e, 0x74, 0x8b, 0x6f, 0x8b, 0x58, + 0xb6, 0x61, 0xbd, 0x8b, 0xac, 0x8b, 0x9f, 0x97, 0xb0, 0xb7, 0x08, 0xf7, + 0x78, 0xf7, 0x9e, 0xfb, 0x78, 0xf7, 0x98, 0x05, 0x66, 0xb5, 0x78, 0x97, + 0x6c, 0x8b, 0x59, 0x8b, 0x61, 0x61, 0x8b, 0x5a, 0x8b, 0x71, 0x9a, 0x70, + 0xab, 0x6c, 0x08, 0xbd, 0x59, 0xfc, 0x3b, 0x8b, 0x05, 0x5d, 0x8b, 0x81, + 0x8a, 0x76, 0x80, 0x70, 0x7f, 0x77, 0x6a, 0x8b, 0x6b, 0x8b, 0x6a, 0x9f, + 0x6b, 0xa6, 0x7e, 0xa0, 0x81, 0x96, 0x89, 0xb8, 0x8b, 0x08, 0xf8, 0x3b, + 0x06, 0x0e, 0xe4, 0xae, 0xf7, 0xfe, 0x15, 0x6a, 0xf9, 0x11, 0xfb, 0x5c, + 0x07, 0xf7, 0x6f, 0xf7, 0x6c, 0xfb, 0x6f, 0xf7, 0x6d, 0x8b, 0xfb, 0x5c, + 0xfd, 0x11, 0x8b, 0x05, 0x0e, 0xe4, 0xae, 0xf8, 0x24, 0x15, 0xfb, 0x04, + 0xf9, 0x13, 0xfb, 0x33, 0x07, 0xf7, 0x6f, 0xf7, 0x6b, 0xfb, 0x6f, 0xf7, + 0x6d, 0x8b, 0xfb, 0x35, 0xfd, 0x13, 0x8b, 0x05, 0x0e, 0x86, 0xf7, 0xca, + 0xf8, 0x46, 0x15, 0xfb, 0x45, 0xf7, 0x99, 0x24, 0x07, 0xf7, 0x78, 0xf7, + 0x53, 0xfb, 0x78, 0xf7, 0x54, 0x8b, 0x24, 0xfb, 0x99, 0x8b, 0x05, 0x25, + 0x16, 0xfb, 0x45, 0xd7, 0xf7, 0x45, 0x3f, 0x07, 0x38, 0x16, 0xfb, 0x45, + 0xb8, 0xf7, 0x45, 0x5e, 0x07, 0x31, 0x16, 0xfb, 0x45, 0xa3, 0xf7, 0x45, + 0x73, 0x07, 0x0e, 0xad, 0xf8, 0x2b, 0xf8, 0x7c, 0x15, 0xfb, 0xb3, 0xf7, + 0x44, 0x23, 0x92, 0x07, 0xb0, 0xef, 0xf2, 0xf0, 0xf7, 0x00, 0xb7, 0xfb, + 0x07, 0xba, 0x28, 0xf0, 0x69, 0xf3, 0x08, 0x84, 0x21, 0xfb, 0x44, 0x06, + 0x2a, 0x16, 0xfb, 0xb3, 0xd2, 0xf7, 0xb3, 0x44, 0x07, 0x31, 0x16, 0xfb, + 0xb3, 0xbd, 0xf7, 0xb3, 0x59, 0x07, 0x30, 0x16, 0xfb, 0xb3, 0xac, 0xf7, + 0xb3, 0x6a, 0x07, 0x2d, 0x16, 0xfb, 0xb3, 0x9e, 0xf7, 0xb3, 0x78, 0x07, + 0x0e, 0x80, 0xae, 0xf8, 0x7f, 0x15, 0xfb, 0xb6, 0xf8, 0x93, 0x2a, 0x07, + 0xf7, 0x89, 0xf7, 0x86, 0xfb, 0x89, 0xf7, 0x86, 0x8b, 0x2a, 0xfc, 0x93, + 0x8b, 0x05, 0x0e, 0xe0, 0xae, 0xf8, 0xf6, 0x15, 0xf7, 0xba, 0xfb, 0xa4, + 0xfb, 0xba, 0xfb, 0x94, 0xf9, 0xea, 0xf7, 0x8c, 0xfd, 0xea, 0xf7, 0xac, + 0x05, 0xf7, 0x0e, 0x42, 0x15, 0xf9, 0x12, 0xfb, 0x63, 0xfc, 0x39, 0x95, + 0xfb, 0x6d, 0xf7, 0x59, 0x05, 0x0e, 0xe0, 0xae, 0xdd, 0x15, 0xf9, 0xea, + 0xf7, 0xab, 0xfd, 0xea, 0xf7, 0x8d, 0xf7, 0xba, 0xfb, 0x95, 0xfb, 0xba, + 0xfb, 0xa3, 0x05, 0xf7, 0x0e, 0xd3, 0x15, 0xf7, 0x6d, 0xf7, 0x59, 0xf8, + 0x39, 0x95, 0xfd, 0x12, 0xfb, 0x63, 0x05, 0x0e, 0xd9, 0xae, 0xf9, 0x44, + 0x15, 0xf7, 0x5d, 0xfb, 0xea, 0xfb, 0x5d, 0xfb, 0xea, 0xf9, 0xe3, 0xf7, + 0xea, 0xfd, 0xe3, 0xf7, 0xea, 0x05, 0x0e, 0xe6, 0xf8, 0xb5, 0xf8, 0xb8, + 0x15, 0x38, 0xfb, 0xb7, 0x07, 0x60, 0x8a, 0x05, 0x3c, 0x8b, 0x69, 0x9d, + 0x7c, 0xbd, 0x84, 0xa1, 0x8a, 0x95, 0x8b, 0xb7, 0x08, 0x63, 0xfb, 0x77, + 0x06, 0x8b, 0x59, 0x8c, 0x78, 0x90, 0x72, 0x95, 0x54, 0xb6, 0x5d, 0xc1, + 0x7e, 0xa3, 0x84, 0x91, 0x8b, 0xbf, 0x8b, 0x08, 0xf7, 0xcf, 0x38, 0x06, + 0xf7, 0xf3, 0xf7, 0x7d, 0xfb, 0xf3, 0xf7, 0x7c, 0x05, 0x0e, 0xe7, 0xf8, + 0xb5, 0xf7, 0x24, 0x15, 0xf7, 0xf3, 0xf7, 0x7c, 0xfb, 0xf3, 0xf7, 0x7c, + 0x8b, 0x38, 0xfb, 0xcf, 0x8b, 0x05, 0x62, 0x8b, 0x8b, 0x8b, 0x81, 0x8a, + 0x61, 0x87, 0x6c, 0x7d, 0x72, 0x71, 0x66, 0x65, 0x82, 0x68, 0x8b, 0x2b, + 0x08, 0xfb, 0x77, 0xb3, 0x96, 0x07, 0x8b, 0xc7, 0x99, 0xb1, 0xa7, 0x9c, + 0xa6, 0x9b, 0x99, 0x8d, 0xeb, 0x8b, 0x08, 0xf7, 0xb7, 0x37, 0x06, 0x0e, + 0xfc, 0x0c, 0xf8, 0x41, 0xf7, 0xee, 0x15, 0xfb, 0x9e, 0xf8, 0x50, 0x8b, + 0xfb, 0x24, 0xfb, 0x14, 0x8b, 0x8b, 0xfc, 0xed, 0xf7, 0x14, 0x8b, 0x8b, + 0xfb, 0x25, 0xf7, 0x9e, 0xf8, 0x52, 0x05, 0x0e, 0xb7, 0xae, 0xf8, 0xa4, + 0x15, 0xfc, 0x01, 0xf8, 0x1e, 0x2e, 0x96, 0x07, 0xf0, 0xf7, 0x2f, 0xf7, + 0x17, 0xe2, 0xf7, 0x44, 0xa9, 0x08, 0x93, 0x07, 0xfb, 0x3b, 0xa1, 0xfb, + 0x22, 0xea, 0x28, 0xf7, 0x2e, 0x08, 0x80, 0x2e, 0xfc, 0x1e, 0x06, 0x0e, + 0x88, 0xf8, 0x2d, 0xf9, 0x1c, 0x15, 0xfb, 0x32, 0xfc, 0x0a, 0xfb, 0xb7, + 0xf8, 0x0a, 0xfb, 0x30, 0xf7, 0x14, 0x07, 0xf7, 0x9d, 0xf7, 0xc1, 0xfb, + 0x9d, 0xf7, 0xc4, 0xfb, 0x14, 0x8b, 0x05, 0xa3, 0x75, 0x15, 0xf7, 0x8e, + 0xfb, 0xae, 0xfb, 0x8e, 0xfb, 0xad, 0x8b, 0xf7, 0x34, 0xfc, 0x0a, 0x8b, + 0x8b, 0xf7, 0x87, 0xf8, 0x0a, 0x8b, 0x8b, 0xf7, 0x34, 0x05, 0x0e, 0x88, + 0xf8, 0x2b, 0xf9, 0x1c, 0x15, 0xfb, 0x32, 0xfc, 0x08, 0xfb, 0xb7, 0xf8, + 0x08, 0xfb, 0x30, 0xf7, 0x16, 0x07, 0xf7, 0x9d, 0xf7, 0xc0, 0xfb, 0x9d, + 0xf7, 0xc5, 0xfb, 0x16, 0x8b, 0x05, 0xf7, 0x05, 0x75, 0x15, 0xf7, 0x8e, + 0xfb, 0xaf, 0xfb, 0x8e, 0xfb, 0xac, 0x8b, 0xf7, 0x34, 0xfc, 0x09, 0x8b, + 0x8b, 0xf7, 0x87, 0xf8, 0x09, 0x8b, 0x8b, 0xf7, 0x34, 0x05, 0x0e, 0xa7, + 0xf9, 0x30, 0xf8, 0xe1, 0x15, 0x47, 0x36, 0xfc, 0x15, 0x8b, 0xfb, 0x48, + 0xfb, 0x4c, 0x8b, 0xfb, 0x13, 0xf7, 0xef, 0x8b, 0x8b, 0x2f, 0xf8, 0x56, + 0xf7, 0x51, 0x8b, 0xf7, 0x09, 0xfb, 0x38, 0xf7, 0x4a, 0x05, 0x6b, 0x04, + 0xf7, 0x22, 0xfb, 0x31, 0xfc, 0x23, 0xfb, 0x3b, 0xc6, 0xd8, 0xfc, 0x32, + 0x8b, 0xf7, 0x3c, 0xf7, 0x43, 0xf8, 0x15, 0x8b, 0xc6, 0xd3, 0x05, 0x0e, + 0xa7, 0xf9, 0x31, 0xf0, 0x15, 0xf7, 0x37, 0xf7, 0x4b, 0x8b, 0xf7, 0x0a, + 0xfc, 0x54, 0xf7, 0x51, 0x8b, 0x2f, 0xfb, 0xf1, 0x8b, 0x8b, 0xfb, 0x13, + 0xf7, 0x48, 0xfb, 0x4f, 0xf8, 0x17, 0x8b, 0xce, 0x37, 0x05, 0x8c, 0xaa, + 0x15, 0x50, 0xd3, 0xfc, 0x17, 0x8b, 0xfb, 0x3c, 0xf7, 0x46, 0xf8, 0x33, + 0x8b, 0x51, 0xd7, 0xf8, 0x21, 0xfb, 0x3b, 0xfb, 0x20, 0xfb, 0x33, 0x05, + 0x0e, 0xfb, 0x23, 0xf7, 0xaf, 0xf9, 0x1f, 0x15, 0x22, 0xfb, 0x8c, 0xfb, + 0xe9, 0x07, 0xdd, 0x3a, 0xf7, 0x3a, 0x8b, 0x8b, 0x7a, 0xdf, 0x4c, 0xf7, + 0xba, 0xf7, 0xab, 0xfc, 0x0e, 0xf7, 0xdc, 0x05, 0xa3, 0xfc, 0xa3, 0x15, + 0xec, 0xfb, 0x8c, 0xf7, 0xb9, 0xf7, 0x8c, 0xda, 0x07, 0xf7, 0x97, 0xfb, + 0x77, 0xfb, 0x97, 0xfb, 0x86, 0x05, 0x0e, 0xfb, 0x23, 0xf7, 0xaf, 0xb7, + 0x15, 0xf8, 0x0e, 0xf7, 0xd9, 0xfb, 0xba, 0xf7, 0xa9, 0x37, 0x4c, 0x8b, + 0x7a, 0xfb, 0x3a, 0x8b, 0x39, 0x3a, 0x8b, 0xfb, 0xe4, 0xf7, 0x8c, 0x8b, + 0x8b, 0x22, 0x05, 0xa3, 0xf8, 0x3d, 0x15, 0x8b, 0xec, 0xf7, 0x97, 0xfb, + 0x83, 0xfb, 0x97, 0xfb, 0x75, 0x8b, 0xdb, 0xfb, 0x8c, 0x8b, 0x8b, 0xf7, + 0xb3, 0xf7, 0x8c, 0x8b, 0x05, 0x0e, 0xae, 0xf8, 0xcf, 0xf8, 0xf9, 0x15, + 0x31, 0xfc, 0xa5, 0x07, 0xc8, 0xfb, 0x30, 0x47, 0xfb, 0x17, 0xcf, 0x4a, + 0xf8, 0x62, 0x8b, 0x8b, 0x2b, 0xf7, 0xa7, 0xf7, 0x9f, 0xfb, 0xa1, 0xf7, + 0xa3, 0x05, 0x9e, 0x52, 0x15, 0xf7, 0x4e, 0xfb, 0x51, 0xfb, 0x54, 0xfb, + 0x49, 0x8b, 0xbd, 0xfc, 0x9d, 0x8b, 0xcf, 0xf7, 0x17, 0x54, 0xf7, 0x18, + 0xf8, 0x96, 0x8b, 0x8b, 0xc4, 0x05, 0x0e, 0xae, 0xf8, 0xcf, 0xd6, 0x15, + 0xf7, 0xa1, 0xf7, 0xa3, 0xfb, 0xa7, 0xf7, 0x9f, 0x8b, 0x2b, 0xfc, 0x62, + 0x8b, 0x47, 0x4a, 0xcf, 0xfb, 0x17, 0x47, 0xfb, 0x30, 0xf8, 0xac, 0x8b, + 0x8b, 0x31, 0x05, 0x9e, 0xc4, 0x15, 0xc4, 0xfc, 0x96, 0x07, 0xc2, 0xf7, + 0x18, 0x47, 0xf7, 0x17, 0xf8, 0x9d, 0x8b, 0x8b, 0xbe, 0xf7, 0x54, 0xfb, + 0x4a, 0xfb, 0x4e, 0xfb, 0x51, 0x05, 0x0e, 0x3c, 0xf8, 0x19, 0xf8, 0xb2, + 0x15, 0x8b, 0xf7, 0x0c, 0xf7, 0xcc, 0xfb, 0xd0, 0xfb, 0xcc, 0xfb, 0xd1, + 0x8b, 0xf7, 0x0c, 0xfb, 0xf6, 0x8b, 0x05, 0x90, 0x69, 0x96, 0x77, 0xa3, + 0x75, 0xba, 0x61, 0xf7, 0x01, 0x6d, 0xf3, 0x8b, 0xf2, 0x8b, 0xec, 0xab, + 0xce, 0xc1, 0xd8, 0xcc, 0xb9, 0xea, 0x8b, 0xee, 0x8b, 0xe1, 0x69, 0xde, + 0x4d, 0xca, 0x46, 0xd3, 0x21, 0xb3, 0xfb, 0x0b, 0x8b, 0x08, 0x2b, 0x8b, + 0x22, 0x70, 0x59, 0x65, 0x6d, 0x75, 0x7e, 0x74, 0x85, 0x65, 0x08, 0xf7, + 0xf6, 0x06, 0x0e, 0xf6, 0xf8, 0x94, 0xf7, 0xf6, 0x15, 0xfb, 0x0d, 0xf7, + 0x46, 0xfb, 0xf8, 0x8b, 0xf7, 0x16, 0xfb, 0x51, 0xfb, 0x16, 0xfb, 0x4c, + 0xf7, 0xf8, 0x8b, 0xf7, 0x0d, 0xf7, 0x3f, 0xf7, 0x6f, 0x8b, 0x05, 0x73, + 0x73, 0x81, 0x71, 0x8b, 0x68, 0x8b, 0x67, 0x96, 0x70, 0xa2, 0x74, 0xbf, + 0xf5, 0xc0, 0xc1, 0xd6, 0xa3, 0x46, 0x9c, 0x48, 0xd2, 0x5f, 0xf0, 0x73, + 0x6f, 0x81, 0x6f, 0x8b, 0x68, 0x8b, 0x69, 0x95, 0x72, 0xa3, 0x6f, 0x08, + 0xfb, 0x6f, 0x06, 0xfc, 0x41, 0xf7, 0x2e, 0x15, 0xbb, 0x8b, 0xf3, 0xfb, + 0x2e, 0x5b, 0x8b, 0x23, 0xf7, 0x2e, 0x05, 0xdc, 0x16, 0xbd, 0x8b, 0xf3, + 0xfb, 0x2e, 0x59, 0x8b, 0x23, 0xf7, 0x2e, 0x05, 0xde, 0x16, 0xbb, 0x8b, + 0xf3, 0xfb, 0x2e, 0x59, 0x8b, 0x25, 0xf7, 0x2e, 0x05, 0xdb, 0x16, 0xbc, + 0x8b, 0xf3, 0xfb, 0x2e, 0x5a, 0x8b, 0x23, 0xf7, 0x2e, 0x05, 0xfb, 0x21, + 0xfb, 0x46, 0x15, 0xbc, 0x8b, 0x26, 0xfb, 0x2c, 0x5b, 0x8b, 0xef, 0xf7, + 0x2c, 0x05, 0xdd, 0x16, 0xbd, 0x8b, 0x26, 0xfb, 0x2c, 0x58, 0x8b, 0xf1, + 0xf7, 0x2c, 0x05, 0xdd, 0x16, 0xbc, 0x8b, 0x25, 0xfb, 0x2c, 0x5a, 0x8b, + 0xf1, 0xf7, 0x2c, 0x05, 0xdc, 0x16, 0xbb, 0x8b, 0x25, 0xfb, 0x2c, 0x5b, + 0x8b, 0xf1, 0xf7, 0x2c, 0x05, 0x0e, 0x47, 0xf8, 0x7e, 0xf7, 0x9f, 0x15, + 0x73, 0x6e, 0xf7, 0x11, 0x22, 0x05, 0x67, 0x86, 0x63, 0x5e, 0x8b, 0x68, + 0xa5, 0x94, 0x9c, 0x8e, 0xa2, 0x8b, 0xbc, 0x8b, 0xc1, 0x82, 0xb7, 0x7c, + 0x08, 0x93, 0x97, 0x05, 0x69, 0xcb, 0x7a, 0xc6, 0x8b, 0xbf, 0x8b, 0x94, + 0x8b, 0x94, 0x8c, 0x99, 0x68, 0x83, 0x6b, 0x62, 0x87, 0x5f, 0x08, 0xfb, + 0x11, 0xf4, 0x05, 0xfb, 0x57, 0x63, 0x15, 0xcd, 0x96, 0xb6, 0x8e, 0xc5, + 0x8b, 0x08, 0xfb, 0x97, 0xf7, 0x6e, 0x05, 0x3c, 0x88, 0x55, 0x87, 0x67, + 0x84, 0x08, 0xf7, 0x99, 0xfb, 0x6e, 0x05, 0x36, 0xf8, 0x40, 0x15, 0x8b, + 0x6d, 0x95, 0x24, 0x92, 0x68, 0x08, 0xf7, 0x97, 0xfb, 0x6d, 0x05, 0x82, + 0xb5, 0x85, 0xcd, 0x8a, 0xc6, 0x08, 0xfb, 0x98, 0xf7, 0x6e, 0x05, 0x0e, + 0xa5, 0xf8, 0x87, 0xf7, 0xfc, 0x15, 0x69, 0xf7, 0x35, 0x07, 0x7e, 0x78, + 0x85, 0x7a, 0x8b, 0x73, 0x8b, 0x72, 0x90, 0x7c, 0x99, 0x7a, 0xa3, 0xb8, + 0xd4, 0xc3, 0xd4, 0xaa, 0x08, 0x97, 0x07, 0x84, 0x8e, 0x86, 0x8e, 0x87, + 0x8c, 0x49, 0xa3, 0x5a, 0xb2, 0x64, 0xc7, 0x7d, 0x79, 0x87, 0x7f, 0x8b, + 0x71, 0x8b, 0x73, 0x8f, 0x7a, 0x99, 0x71, 0x08, 0xfb, 0x35, 0x06, 0xfb, + 0x10, 0xfb, 0x2b, 0x15, 0xbf, 0xc3, 0xa4, 0xa3, 0xba, 0xb0, 0x08, 0xfb, + 0xeb, 0x06, 0x5a, 0x61, 0x5c, 0x5d, 0x73, 0x6e, 0x08, 0xf7, 0xe7, 0x06, + 0xfb, 0xe8, 0xf7, 0xa6, 0x15, 0xbe, 0x53, 0xbe, 0x57, 0x9e, 0x7c, 0x08, + 0xf7, 0xeb, 0x06, 0x66, 0xa9, 0x58, 0xbd, 0x66, 0xb6, 0x08, 0xfb, 0xe7, + 0x06, 0x0e, 0x47, 0xf8, 0x7e, 0xf8, 0x3d, 0x15, 0xf7, 0x11, 0xf4, 0x05, + 0x8f, 0x5f, 0xab, 0x61, 0xae, 0x83, 0x8a, 0x99, 0x8a, 0x96, 0x8b, 0x92, + 0x8b, 0xbd, 0x9e, 0xca, 0xac, 0xc9, 0x08, 0x83, 0x97, 0x05, 0x5d, 0x7b, + 0x58, 0x82, 0x62, 0x8b, 0x6f, 0x8b, 0x77, 0x8e, 0x70, 0x95, 0x8b, 0x68, + 0xb3, 0x5e, 0xaf, 0x86, 0x08, 0xfb, 0x11, 0x22, 0xa3, 0x6f, 0x05, 0xfc, + 0x5c, 0xfb, 0x47, 0x15, 0xb0, 0x84, 0xc1, 0x87, 0xd9, 0x89, 0x08, 0xf7, + 0x97, 0xf7, 0x6d, 0x05, 0x48, 0x8c, 0x73, 0x8d, 0x3f, 0x97, 0x08, 0xfb, + 0x99, 0xfb, 0x6f, 0x05, 0xf8, 0x48, 0x93, 0x15, 0x8c, 0xcc, 0x91, 0xc5, + 0x94, 0xb8, 0x08, 0xfb, 0x97, 0xfb, 0x6e, 0x05, 0x84, 0x68, 0x81, 0x24, + 0x8b, 0x6d, 0x08, 0xf7, 0x98, 0xf7, 0x6e, 0x05, 0x0e, 0xbc, 0xf7, 0xbb, + 0xf9, 0x5b, 0x15, 0x6d, 0x57, 0x7e, 0x61, 0x8b, 0x5d, 0x8b, 0x5f, 0x91, + 0x74, 0xa0, 0x61, 0x69, 0x95, 0x7d, 0x8e, 0x7b, 0x8b, 0x47, 0x8b, 0x54, + 0x74, 0x51, 0x57, 0x08, 0xf7, 0x99, 0xfb, 0x6e, 0x05, 0xbd, 0xb6, 0xc1, + 0xa2, 0xbd, 0x8b, 0xb1, 0x8b, 0xc0, 0x72, 0xbb, 0x62, 0x08, 0xf1, 0x34, + 0x05, 0x47, 0x80, 0x5b, 0x6e, 0x44, 0x42, 0xdc, 0x9c, 0xb7, 0x90, 0xc5, + 0x8b, 0xcd, 0x8b, 0xbe, 0x84, 0xbd, 0x7c, 0x75, 0xb6, 0x7e, 0xad, 0x80, + 0xb7, 0x81, 0xaf, 0x7f, 0xeb, 0x8b, 0xb4, 0x8b, 0x90, 0x8c, 0x97, 0x8c, + 0x9b, 0x08, 0x8c, 0x9a, 0x05, 0x5c, 0x51, 0x6d, 0x43, 0x8b, 0x55, 0x8b, + 0x87, 0x8b, 0x84, 0x8c, 0x82, 0x08, 0x26, 0xe0, 0x05, 0x42, 0xc8, 0x75, + 0xb2, 0x8b, 0xcb, 0x8b, 0xb6, 0x97, 0xb1, 0xa5, 0xb7, 0x08, 0xfb, 0x97, + 0xf7, 0x6d, 0x05, 0x0e, 0xf7, 0x14, 0xae, 0xf8, 0xb8, 0x15, 0x9b, 0x25, + 0xbd, 0x46, 0xdc, 0x6b, 0x3b, 0x6e, 0x53, 0x3e, 0x80, 0x2a, 0x08, 0xf7, + 0xe6, 0x06, 0x97, 0xce, 0xa7, 0xc0, 0xb3, 0xab, 0xa9, 0xa2, 0xbd, 0x97, + 0xce, 0x8b, 0x08, 0xf7, 0x1a, 0x06, 0x5d, 0x56, 0x79, 0x58, 0x82, 0x25, + 0xe5, 0xf7, 0x05, 0xea, 0xd8, 0xe1, 0xab, 0x24, 0xb7, 0x34, 0xd3, 0x3a, + 0xf6, 0x8d, 0x37, 0xa8, 0x3a, 0xb5, 0x62, 0x08, 0xfb, 0x18, 0x06, 0x3d, + 0x8b, 0x61, 0x95, 0x69, 0xa7, 0x64, 0xab, 0x70, 0xc0, 0x82, 0xca, 0x08, + 0xfb, 0xe6, 0x06, 0x0e, 0xbc, 0xf8, 0xbd, 0xf7, 0x59, 0x15, 0x6e, 0xbd, + 0x80, 0xac, 0x8b, 0xb7, 0x8b, 0xc6, 0xa5, 0xb7, 0xd2, 0xc6, 0x08, 0xf0, + 0xe0, 0x05, 0x8a, 0x83, 0x8b, 0x83, 0x8b, 0x88, 0x8b, 0x55, 0xa9, 0x42, + 0xba, 0x51, 0x89, 0xa5, 0x8b, 0x95, 0x8b, 0x97, 0x8b, 0xf7, 0x00, 0xa4, + 0xf7, 0x01, 0xb6, 0xd9, 0x57, 0x7b, 0x59, 0x84, 0x4a, 0x8b, 0x51, 0x8b, + 0x64, 0x90, 0x34, 0x9c, 0x08, 0xd3, 0x42, 0xba, 0x6e, 0xcf, 0x81, 0x08, + 0x25, 0x33, 0x05, 0x5a, 0x62, 0x57, 0x72, 0x65, 0x8b, 0x59, 0x8b, 0x55, + 0xa2, 0x59, 0xb6, 0x08, 0xfb, 0x98, 0xfb, 0x6e, 0x05, 0xc5, 0x57, 0xc2, + 0x74, 0xcf, 0x8b, 0x9b, 0x8b, 0x99, 0x8e, 0xac, 0x96, 0x77, 0x63, 0x84, + 0x6e, 0x8b, 0x64, 0x8b, 0x5a, 0x95, 0x6b, 0xac, 0x4e, 0x08, 0xf7, 0x97, + 0xf7, 0x6d, 0x05, 0x0e, 0x83, 0xf9, 0xb0, 0xf7, 0xf4, 0x15, 0x30, 0xa3, + 0x63, 0xaf, 0x69, 0xe4, 0x7d, 0xb1, 0x88, 0x92, 0x7c, 0x98, 0x7e, 0x97, + 0x78, 0x92, 0x7a, 0x8b, 0x62, 0x8b, 0x6c, 0x6c, 0x8b, 0x64, 0x8b, 0x6f, + 0x99, 0x75, 0xab, 0x73, 0xaa, 0x73, 0xa7, 0x80, 0xf7, 0x24, 0x5c, 0x08, + 0xfb, 0x53, 0x92, 0x36, 0x98, 0xfb, 0x46, 0xc0, 0x48, 0x9e, 0x6c, 0x91, + 0x6a, 0x8b, 0x08, 0x4a, 0x61, 0x62, 0x4b, 0x4c, 0xb5, 0x62, 0xcb, 0x1f, + 0xac, 0x8b, 0xaa, 0x91, 0xcf, 0x9e, 0xf7, 0x44, 0xbf, 0xe7, 0x9a, 0xf7, + 0x4e, 0x91, 0x2c, 0x6c, 0x77, 0x84, 0x61, 0x7a, 0x51, 0x73, 0x69, 0x65, + 0x8b, 0x62, 0x8b, 0x66, 0xab, 0x6c, 0xb3, 0x8b, 0x9c, 0x8b, 0x9e, 0x92, + 0x98, 0x97, 0x08, 0x99, 0x98, 0x8f, 0x92, 0x99, 0xb2, 0xae, 0xe4, 0xb2, + 0xae, 0xe6, 0xa3, 0x08, 0x98, 0x07, 0x0e, 0xad, 0xf9, 0xda, 0xf7, 0xf2, + 0x15, 0x28, 0xb4, 0x21, 0xf7, 0x04, 0x83, 0xd4, 0x5a, 0x6b, 0x6f, 0x5b, + 0x8b, 0x57, 0x8b, 0x67, 0x9e, 0x6e, 0xb7, 0x70, 0xfb, 0x0a, 0x8d, 0x51, + 0x9f, 0x44, 0xcb, 0x43, 0xc9, 0x70, 0x99, 0x5a, 0x8b, 0x6a, 0x8b, 0x6f, + 0x80, 0x75, 0x76, 0x08, 0x7b, 0x7b, 0x81, 0x79, 0x7b, 0x60, 0x7c, 0x61, + 0x83, 0x84, 0x6b, 0x85, 0xaa, 0x85, 0x95, 0x82, 0x99, 0x61, 0x98, 0x66, + 0x95, 0x75, 0x98, 0x7d, 0xa1, 0x70, 0xab, 0x7c, 0xab, 0x8b, 0xb8, 0x8b, + 0xb3, 0x9e, 0xc1, 0xb9, 0x08, 0xbc, 0xb7, 0x90, 0x8e, 0xa6, 0x99, 0xb3, + 0xa0, 0xc8, 0x99, 0xc1, 0x8b, 0x08, 0xa2, 0x06, 0x5d, 0x6e, 0x7b, 0x72, + 0x8b, 0x63, 0x8b, 0x57, 0xa6, 0x5e, 0xbc, 0x6b, 0x93, 0xd3, 0xf3, 0xf7, + 0x01, 0xf0, 0xb6, 0x08, 0x95, 0x07, 0x0e, 0xe3, 0xdb, 0xf8, 0xb2, 0x15, + 0x6f, 0x7b, 0x81, 0x79, 0x1f, 0x8b, 0x82, 0x91, 0x7c, 0x93, 0x7e, 0x08, + 0xc6, 0x30, 0x05, 0x9a, 0x74, 0x8e, 0x84, 0x8b, 0x81, 0x8b, 0x81, 0x8a, + 0x89, 0x7c, 0x72, 0x08, 0x4d, 0x27, 0x05, 0x7d, 0x78, 0x8b, 0x8b, 0x8b, + 0x81, 0x08, 0x79, 0x9b, 0x7e, 0xa0, 0x1e, 0xf7, 0x88, 0x06, 0xb6, 0x8b, + 0x93, 0x8f, 0xa6, 0xac, 0x08, 0xbb, 0xc6, 0x05, 0xad, 0xb6, 0x95, 0x90, + 0xc0, 0x8b, 0x08, 0xdc, 0x06, 0xa0, 0x97, 0x82, 0x7b, 0x1f, 0x8b, 0x82, + 0x89, 0x84, 0x7e, 0x70, 0x87, 0x82, 0x88, 0x81, 0x8b, 0x84, 0x8b, 0x79, + 0xad, 0x77, 0xa9, 0x8b, 0x9e, 0x8b, 0x9c, 0x94, 0xa3, 0xa1, 0x08, 0xf6, + 0xf0, 0x05, 0x9f, 0x9e, 0x94, 0x9b, 0x8b, 0x9d, 0x8b, 0x9d, 0x81, 0x9e, + 0x7a, 0x9b, 0x08, 0xfb, 0x0d, 0xf7, 0x02, 0x05, 0x7d, 0x97, 0x7a, 0x92, + 0x7c, 0x8b, 0x65, 0x8b, 0x6f, 0x7b, 0x8b, 0x75, 0x8b, 0x83, 0x8d, 0x84, + 0x8e, 0x85, 0x9c, 0x6b, 0x8b, 0x8b, 0x8b, 0x7d, 0x08, 0x7a, 0x81, 0x84, + 0x71, 0x1e, 0x39, 0x06, 0x5b, 0x8b, 0x80, 0x91, 0x68, 0xb5, 0x08, 0x55, + 0xcd, 0x05, 0x75, 0xa6, 0x85, 0x8d, 0x66, 0x8b, 0x08, 0xfb, 0x86, 0x06, + 0x0e, 0xf7, 0x17, 0xf7, 0x14, 0xf8, 0xfb, 0x15, 0x49, 0x70, 0x75, 0x57, + 0x1f, 0x8b, 0x7b, 0x8d, 0x7f, 0x94, 0x70, 0x08, 0xa9, 0x2d, 0x05, 0x95, + 0x67, 0x8c, 0x86, 0x8b, 0x84, 0x8b, 0x84, 0x88, 0x7f, 0x86, 0x7b, 0x87, + 0x82, 0x88, 0x81, 0x88, 0x82, 0x08, 0x70, 0x31, 0x05, 0x86, 0x7c, 0x89, + 0x7c, 0x8b, 0x7d, 0x8b, 0x72, 0x94, 0x76, 0x9a, 0x7f, 0x99, 0x80, 0x9b, + 0x88, 0xb4, 0x8b, 0x08, 0xf7, 0x70, 0x06, 0xd7, 0x8b, 0x9e, 0x96, 0xaf, + 0xcb, 0x08, 0xb2, 0xd1, 0x05, 0x9d, 0xab, 0x8b, 0x8b, 0x93, 0x95, 0x97, + 0x9c, 0x9e, 0x93, 0xa4, 0x8b, 0xa0, 0x8b, 0x98, 0x80, 0x8b, 0x7a, 0x8b, + 0x83, 0x89, 0x7e, 0x87, 0x7d, 0x82, 0x6e, 0x84, 0x68, 0x8b, 0x7e, 0x8b, + 0x6d, 0xa8, 0x70, 0xaa, 0x8b, 0x08, 0x9f, 0x8b, 0x9a, 0x94, 0xa9, 0xa9, + 0x08, 0xf7, 0x24, 0xf7, 0x25, 0x05, 0xbb, 0xbe, 0x8b, 0x8b, 0x8b, 0xa0, + 0x8b, 0xa0, 0x8a, 0x8d, 0x62, 0xb4, 0x08, 0xfb, 0x28, 0xf7, 0x2b, 0x05, + 0x6e, 0xa9, 0x7b, 0x94, 0x75, 0x8b, 0x68, 0x8b, 0x74, 0x71, 0x8b, 0x65, + 0x8b, 0x78, 0x8c, 0x87, 0x99, 0x56, 0x8e, 0x81, 0x8d, 0x80, 0x8b, 0x83, + 0x8b, 0x79, 0x7d, 0x82, 0x72, 0x8b, 0x6d, 0x8b, 0x7b, 0x98, 0x74, 0xb5, + 0x08, 0x60, 0xd9, 0x05, 0x67, 0xcd, 0x76, 0x97, 0x3d, 0x8b, 0x08, 0xfb, + 0x72, 0x06, 0x0e, 0xda, 0xf8, 0xc9, 0xf8, 0xe4, 0x15, 0xd0, 0x22, 0xcd, + 0x46, 0xf1, 0x41, 0xfb, 0x0d, 0x30, 0x68, 0x66, 0x3a, 0xfb, 0x09, 0x08, + 0xc9, 0x06, 0xc8, 0xeb, 0xd9, 0xd5, 0xf7, 0x0a, 0xd6, 0xfb, 0x0b, 0xd8, + 0x33, 0xdf, 0x59, 0xe2, 0x08, 0x4d, 0x06, 0xfb, 0x22, 0x16, 0x9d, 0x65, + 0xc3, 0x40, 0xba, 0x5a, 0x08, 0xfc, 0x92, 0x5e, 0xf9, 0x0f, 0x06, 0x46, + 0xbd, 0x3c, 0xe1, 0x61, 0xd2, 0x08, 0x53, 0x06, 0xfc, 0x19, 0xfb, 0xe2, + 0x15, 0xf8, 0x92, 0x06, 0x6b, 0x70, 0x4e, 0x3a, 0x71, 0x58, 0x08, 0xc3, + 0x06, 0xb9, 0xd7, 0xd4, 0xda, 0xd0, 0xbc, 0x08, 0xfd, 0x0f, 0x5e, 0x06, + 0x0e, 0xf9, 0xa8, 0x14, 0xf9, 0xdb, 0x15, 0x06, 0x1e, 0x0a, 0x03, 0x96, + 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0x8b, 0x0a, 0x0c, 0x0c, 0x8b, + 0x0b, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00, 0x00 +}; +const unsigned int fonts_Dingbats_cff_len = 29492; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusMonL-Bold.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusMonL-Bold.cff.c new file mode 100644 index 00000000000..12819adc9da --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusMonL-Bold.cff.c @@ -0,0 +1,2742 @@ +const unsigned char fonts_NimbusMonL_Bold_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x10, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x4d, 0x6f, 0x6e, 0x4c, 0x2d, 0x42, 0x6f, 0x6c, 0x64, + 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x3e, 0xf8, 0x1f, 0x00, 0xf8, 0x20, + 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, 0x14, 0x04, 0x8c, 0x0c, + 0x01, 0x1d, 0x00, 0x4c, 0x9d, 0x12, 0x0d, 0x60, 0xfb, 0x79, 0xf9, 0x0a, + 0xf9, 0xfb, 0x05, 0x1d, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x1d, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x1d, 0x00, 0x00, 0x02, 0xc3, 0x11, 0x1d, 0x00, 0x00, + 0x00, 0x29, 0x1d, 0x00, 0x00, 0x80, 0x33, 0x12, 0x00, 0x08, 0x02, 0x00, + 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, 0x00, + 0x5f, 0x00, 0x71, 0x00, 0x7e, 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, 0x64, + 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, + 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, 0x43, + 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, 0x52, + 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, 0x28, + 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, + 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x4d, 0x6f, + 0x6e, 0x6f, 0x20, 0x4c, 0x20, 0x42, 0x6f, 0x6c, 0x64, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x20, 0x4c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, + 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, + 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, + 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, + 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, + 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, + 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, + 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, + 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, + 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, + 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, + 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, + 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, + 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, + 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, + 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, + 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, + 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, + 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, + 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, + 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, + 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, + 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, + 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, + 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, 0xae, 0x00, 0xac, 0x00, 0xb0, 0x00, + 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, 0xb4, 0x00, 0xb2, 0x00, 0xb5, 0x00, + 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, 0xb9, 0x00, 0xb7, 0x00, 0xba, 0x00, + 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, 0xbc, 0x00, 0xbf, 0x00, 0xc0, 0x00, + 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, 0xc2, 0x00, 0xc5, 0x00, 0xc7, 0x00, + 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xc8, 0x00, 0xcb, 0x00, 0xc9, 0x00, + 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd1, 0x00, 0xcf, 0x00, 0xd2, 0x00, + 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd7, 0x00, + 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, 0xd9, 0x00, 0xdc, 0x00, 0xdd, 0x00, + 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xdf, 0x00, 0xe2, 0x00, 0xe4, 0x00, + 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, 0x87, 0x00, 0x96, 0x00, 0xa4, 0x00, + 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa8, 0x00, + 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa3, 0x00, + 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, 0x97, 0x00, 0xa0, 0x00, 0x98, 0x00, + 0xea, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x50, + 0x00, 0x89, 0x01, 0x86, 0x02, 0x83, 0x03, 0x0a, 0x03, 0xbc, 0x03, 0xe1, + 0x04, 0x2c, 0x04, 0x76, 0x04, 0xfb, 0x05, 0x7a, 0x05, 0x9f, 0x05, 0xdd, + 0x05, 0xf8, 0x06, 0x2e, 0x06, 0x86, 0x06, 0xe4, 0x07, 0x52, 0x07, 0xda, + 0x08, 0x3f, 0x08, 0xb6, 0x09, 0x26, 0x09, 0x66, 0x09, 0xca, 0x0a, 0x3a, + 0x0a, 0x6e, 0x0a, 0xa8, 0x0a, 0xfb, 0x0b, 0x74, 0x0b, 0xc7, 0x0c, 0x42, + 0x0c, 0xd6, 0x0d, 0x81, 0x0e, 0x11, 0x0e, 0xa2, 0x0f, 0x11, 0x0f, 0xd1, + 0x10, 0x8c, 0x11, 0x44, 0x12, 0x2b, 0x12, 0x9f, 0x13, 0x28, 0x14, 0x08, + 0x14, 0x87, 0x15, 0x3f, 0x15, 0xd8, 0x16, 0x1b, 0x16, 0xa4, 0x17, 0x52, + 0x17, 0xfe, 0x18, 0xbd, 0x19, 0x3f, 0x19, 0xd2, 0x1a, 0x5b, 0x1a, 0xe6, + 0x1b, 0xa7, 0x1c, 0x4d, 0x1c, 0xa6, 0x1c, 0xeb, 0x1d, 0x21, 0x1d, 0x65, + 0x1d, 0xa4, 0x1d, 0xb0, 0x1d, 0xd5, 0x1e, 0x63, 0x1f, 0x00, 0x1f, 0x8c, + 0x20, 0x30, 0x20, 0x8a, 0x21, 0x35, 0x21, 0xbb, 0x22, 0x7a, 0x22, 0xe9, + 0x23, 0x49, 0x23, 0xf7, 0x24, 0x59, 0x24, 0xfb, 0x25, 0x97, 0x25, 0xce, + 0x26, 0x73, 0x27, 0x1e, 0x27, 0xad, 0x28, 0x5c, 0x28, 0xf0, 0x29, 0x6d, + 0x29, 0xf9, 0x2a, 0x7e, 0x2b, 0x35, 0x2b, 0xd9, 0x2c, 0x2a, 0x2c, 0x8e, + 0x2c, 0xcc, 0x2d, 0x2f, 0x2d, 0x8c, 0x2d, 0xd8, 0x2e, 0x80, 0x2f, 0x35, + 0x2f, 0x6b, 0x30, 0x47, 0x30, 0xcc, 0x31, 0xa3, 0x32, 0x55, 0x32, 0x73, + 0x32, 0xba, 0x33, 0x35, 0x33, 0x74, 0x33, 0xb3, 0x34, 0xc5, 0x35, 0xb3, + 0x35, 0xf1, 0x36, 0x6c, 0x37, 0x23, 0x37, 0x3f, 0x37, 0xca, 0x37, 0xe1, + 0x38, 0x06, 0x38, 0x4d, 0x38, 0x94, 0x39, 0x0f, 0x39, 0x5c, 0x3a, 0x0c, + 0x3a, 0x87, 0x3a, 0xbd, 0x3a, 0xf3, 0x3b, 0x36, 0x3b, 0x93, 0x3b, 0xc3, + 0x3b, 0xf3, 0x3c, 0x0a, 0x3c, 0x35, 0x3c, 0x5f, 0x3c, 0xa4, 0x3d, 0x09, + 0x3d, 0x47, 0x3d, 0x86, 0x3d, 0xc4, 0x3e, 0x9f, 0x3f, 0x37, 0x3f, 0xe8, + 0x40, 0x89, 0x41, 0x35, 0x41, 0x85, 0x42, 0x6c, 0x42, 0xce, 0x43, 0x69, + 0x44, 0x07, 0x44, 0x9e, 0x45, 0x3d, 0x46, 0x12, 0x46, 0xf1, 0x47, 0xd1, + 0x48, 0xb9, 0x49, 0xc0, 0x4a, 0x93, 0x4b, 0x67, 0x4c, 0x0d, 0x4c, 0xf7, + 0x4d, 0xec, 0x4e, 0xe0, 0x4f, 0xdb, 0x50, 0x7b, 0x51, 0x23, 0x51, 0xcc, + 0x52, 0x83, 0x53, 0x7a, 0x53, 0xe6, 0x54, 0x5e, 0x54, 0xd5, 0x55, 0x55, + 0x55, 0xf6, 0x56, 0xf7, 0x57, 0xb5, 0x58, 0x7c, 0x59, 0x44, 0x5a, 0x1f, + 0x5a, 0xf9, 0x5b, 0x99, 0x5c, 0x42, 0x5d, 0x14, 0x5d, 0xcc, 0x5e, 0x8e, + 0x5f, 0x51, 0x60, 0x20, 0x61, 0x0a, 0x61, 0xc1, 0x62, 0x93, 0x63, 0x16, + 0x63, 0xa5, 0x64, 0x33, 0x64, 0xcf, 0x65, 0x5d, 0x65, 0xf3, 0x66, 0x8a, + 0x67, 0x29, 0x68, 0x23, 0x68, 0x85, 0x68, 0xf1, 0x69, 0x5c, 0x69, 0xda, + 0x6a, 0x6f, 0x6b, 0x5f, 0x6c, 0x06, 0x6c, 0xb7, 0x6d, 0x69, 0x6e, 0x28, + 0x6f, 0x01, 0x6f, 0x99, 0x70, 0x3e, 0x70, 0xe5, 0x71, 0xb2, 0x72, 0x71, + 0x72, 0xaf, 0x73, 0x0b, 0x73, 0x89, 0x73, 0xa5, 0x73, 0xe3, 0x74, 0x0d, + 0x74, 0x4b, 0x74, 0xb2, 0x75, 0x1a, 0x75, 0xc5, 0x76, 0x7f, 0x77, 0x4c, + 0x78, 0x0a, 0x79, 0x06, 0x79, 0xa4, 0x7a, 0x49, 0x7a, 0x4a, 0x7a, 0x8d, + 0x7b, 0x06, 0x7b, 0x98, 0x0e, 0x0e, 0x0e, 0xf8, 0x0f, 0xf8, 0xa1, 0x15, + 0x8c, 0x98, 0x8c, 0x99, 0x8b, 0x91, 0x08, 0xb9, 0x69, 0xad, 0x5d, 0x5c, + 0x69, 0x69, 0x5d, 0x1e, 0x8b, 0x84, 0x8c, 0x7d, 0x8c, 0x7f, 0x08, 0xa8, + 0xfb, 0xbd, 0x05, 0x8e, 0x6d, 0x9e, 0x78, 0xa7, 0x8b, 0xa7, 0x8b, 0x9d, + 0x9d, 0x8e, 0xaa, 0x08, 0xa8, 0xf7, 0xbd, 0x05, 0x45, 0xfc, 0xb0, 0x15, + 0xb0, 0xa8, 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x7a, 0x06, 0x66, + 0x6d, 0x6d, 0x67, 0x67, 0xa9, 0x6d, 0xb0, 0x1f, 0x9c, 0x06, 0x0e, 0xf7, + 0x1c, 0xf8, 0xee, 0x15, 0xad, 0xfb, 0x93, 0x05, 0x8e, 0x72, 0x94, 0x81, + 0x9e, 0x8b, 0x9f, 0x8b, 0x93, 0x95, 0x8f, 0xa5, 0x08, 0xaa, 0xf7, 0x92, + 0xfb, 0x14, 0x8b, 0x05, 0xf7, 0x5c, 0x16, 0xad, 0xfb, 0x93, 0x05, 0x8e, + 0x72, 0x94, 0x81, 0x9e, 0x8b, 0x9f, 0x8b, 0x93, 0x95, 0x8f, 0xa5, 0x08, + 0xaa, 0xf7, 0x92, 0xfb, 0x14, 0x8b, 0x05, 0x0e, 0xf8, 0x53, 0xf8, 0x50, + 0x15, 0x96, 0xf7, 0x35, 0x8d, 0xa1, 0x05, 0x8d, 0xa2, 0x71, 0xa4, 0x71, + 0x8b, 0x7c, 0x8b, 0x7c, 0x84, 0x81, 0x7f, 0x83, 0x81, 0x89, 0x85, 0x8a, + 0x6f, 0x08, 0x7f, 0xfb, 0x3c, 0x44, 0x8b, 0x96, 0xf7, 0x35, 0x8c, 0x9d, + 0x05, 0x8c, 0xa7, 0x75, 0xa3, 0x6e, 0x8b, 0x7c, 0x8b, 0x7c, 0x84, 0x81, + 0x7f, 0x83, 0x80, 0x89, 0x84, 0x8a, 0x71, 0x08, 0x7f, 0xfb, 0x3c, 0x71, + 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x81, 0x95, 0x84, 0x94, 0x89, + 0xa6, 0x8b, 0x08, 0x9e, 0x8b, 0x84, 0x21, 0x6a, 0x8b, 0x05, 0x71, 0x8b, + 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa4, 0x8b, 0x08, 0xa5, + 0x8b, 0x80, 0xfb, 0x35, 0x05, 0x8a, 0x84, 0x8b, 0x84, 0x8b, 0x87, 0x08, + 0x6d, 0xa0, 0x75, 0xa8, 0xac, 0x9c, 0xa1, 0xb4, 0x1e, 0x97, 0xf7, 0x3c, + 0xd3, 0x8b, 0x80, 0xfb, 0x35, 0x89, 0x78, 0x05, 0x89, 0x71, 0xa3, 0x72, + 0xa6, 0x8b, 0x99, 0x8b, 0x9a, 0x92, 0x95, 0x97, 0x90, 0x91, 0x92, 0xa2, + 0x8c, 0x9a, 0x08, 0x96, 0xf7, 0x3c, 0xa6, 0x8b, 0x05, 0xa2, 0x8b, 0x95, + 0x8d, 0x94, 0x90, 0x9a, 0x94, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x95, 0x82, 0x92, 0x81, 0x8d, 0x70, 0x8b, 0x08, 0x78, 0x8b, + 0x93, 0xf5, 0xab, 0x8b, 0x05, 0xa3, 0x8b, 0x94, 0x8d, 0x94, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x72, 0x06, 0x20, 0x27, 0x15, 0x84, + 0x21, 0x43, 0x8b, 0x93, 0xf5, 0xd2, 0x8b, 0x05, 0x0e, 0xf7, 0xf3, 0xf8, + 0xfe, 0x15, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, 0x7b, 0x94, + 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x83, 0x81, 0x7f, 0x84, 0x80, 0x89, 0x83, + 0x8b, 0x70, 0x08, 0x71, 0x07, 0x35, 0x7c, 0x50, 0x4b, 0x8b, 0x3d, 0x8b, + 0x3a, 0xc0, 0x55, 0xee, 0x77, 0x08, 0xd5, 0x7c, 0x05, 0xc3, 0x80, 0xa3, + 0x78, 0x8b, 0x68, 0x8b, 0x60, 0x5b, 0x6a, 0x4a, 0x8b, 0x54, 0x8b, 0x56, + 0xa4, 0x83, 0xaa, 0x83, 0xa6, 0x8b, 0x8b, 0x84, 0x93, 0x82, 0x93, 0x7d, + 0x91, 0x7e, 0x8b, 0x7b, 0x8b, 0x7c, 0x83, 0x81, 0x7e, 0x08, 0x84, 0x81, + 0x89, 0x82, 0x8b, 0x70, 0x08, 0x4e, 0x07, 0x8b, 0x72, 0x8d, 0x82, 0x90, + 0x82, 0x95, 0x7c, 0x9b, 0x82, 0x9d, 0x8b, 0x99, 0x8b, 0x94, 0x8f, 0x9b, + 0x99, 0xab, 0x7d, 0x90, 0x89, 0xb5, 0x82, 0x08, 0x38, 0x07, 0x8b, 0x72, + 0x8c, 0x82, 0x91, 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0x9a, 0x8b, + 0x9a, 0x93, 0x95, 0x98, 0x93, 0x95, 0x8c, 0x93, 0x8b, 0xa7, 0x08, 0xde, + 0x07, 0xf3, 0x9f, 0xc9, 0xcc, 0x8b, 0xe2, 0x8b, 0xb6, 0x7c, 0xb2, 0x70, + 0xa6, 0x71, 0xa5, 0x67, 0x9b, 0x4d, 0x98, 0x08, 0x4a, 0x99, 0x05, 0x58, + 0x95, 0x73, 0x9e, 0x8b, 0xa6, 0x8b, 0xb0, 0xb2, 0xa4, 0xc7, 0x8b, 0xb4, + 0x8b, 0xb3, 0x7a, 0x8e, 0x78, 0x91, 0x70, 0x9e, 0x7c, 0xa6, 0x8b, 0x9b, + 0x8b, 0x9a, 0x92, 0x95, 0x99, 0x92, 0x94, 0x8d, 0x95, 0x8b, 0xa5, 0x08, + 0xab, 0x07, 0x8b, 0x94, 0x8b, 0x8f, 0x8a, 0x93, 0x88, 0xa6, 0x78, 0x9d, + 0x70, 0x8b, 0x82, 0x8b, 0x83, 0x89, 0x80, 0x86, 0x87, 0x8c, 0x87, 0x8c, + 0x8a, 0x8c, 0x08, 0x7d, 0x90, 0x05, 0x82, 0x8e, 0x85, 0x8d, 0x86, 0x8c, + 0x83, 0x8d, 0x86, 0x8b, 0x80, 0x8d, 0x08, 0xa5, 0x07, 0x0e, 0xf7, 0x78, + 0xf8, 0xfd, 0x15, 0x3f, 0x4c, 0x4c, 0x3f, 0x3e, 0xca, 0x4c, 0xd8, 0xd7, + 0xca, 0xca, 0xd6, 0xda, 0x4e, 0xc9, 0x3c, 0x1f, 0x4a, 0x04, 0xb5, 0xac, + 0x6a, 0x61, 0x63, 0x69, 0x69, 0x62, 0x63, 0x69, 0xad, 0xb4, 0xb3, 0xad, + 0xad, 0xb3, 0x1f, 0xf7, 0x9b, 0xfb, 0x71, 0x15, 0xa1, 0x91, 0x93, 0x94, + 0x8b, 0x9b, 0x8b, 0x9c, 0x7d, 0x9a, 0x7c, 0x8b, 0x85, 0x8b, 0x89, 0x8b, + 0x7f, 0x87, 0x08, 0xfb, 0xfe, 0xfb, 0x0a, 0x05, 0x75, 0x84, 0x83, 0x83, + 0x8b, 0x7b, 0x8b, 0x7a, 0x99, 0x7c, 0x9a, 0x8b, 0x8f, 0x8b, 0x94, 0x8d, + 0x92, 0x8d, 0x08, 0xf7, 0xfe, 0xf7, 0x0a, 0x05, 0xfb, 0x0f, 0x48, 0x15, + 0x3f, 0x4c, 0x4c, 0x3f, 0x3e, 0xca, 0x4c, 0xd7, 0xd8, 0xca, 0xca, 0xd6, + 0xda, 0x4e, 0xc9, 0x3c, 0x1f, 0x4a, 0x04, 0xb5, 0xac, 0x6a, 0x61, 0x63, + 0x69, 0x69, 0x63, 0x62, 0x69, 0xad, 0xb4, 0xb3, 0xad, 0xad, 0xb3, 0x1f, + 0x0e, 0xf8, 0x01, 0xf7, 0x5a, 0x15, 0x27, 0xf7, 0x25, 0x05, 0x78, 0xa6, + 0x82, 0x9e, 0x8b, 0x96, 0x8b, 0xa7, 0xa3, 0xa1, 0xa8, 0x8b, 0x9f, 0x8b, + 0x99, 0x83, 0xa8, 0x71, 0x08, 0xb4, 0xa1, 0x05, 0xab, 0x9d, 0x94, 0x96, + 0x8b, 0xa2, 0x8b, 0xa4, 0x74, 0xa4, 0x72, 0x8b, 0x84, 0x8b, 0x82, 0x88, + 0x7f, 0x87, 0x71, 0x97, 0x77, 0x90, 0x73, 0x8b, 0x3a, 0x8b, 0x44, 0x45, + 0x8b, 0x3a, 0x8b, 0x6c, 0x92, 0x78, 0xa6, 0x5d, 0x08, 0x4d, 0x67, 0x69, + 0x53, 0x8b, 0x48, 0x8b, 0x2b, 0xd3, 0x4d, 0xf7, 0x02, 0x8b, 0xc0, 0x8b, + 0xa9, 0x93, 0xa9, 0xa0, 0x08, 0x96, 0x7c, 0xc8, 0x8b, 0x05, 0xa0, 0x8b, + 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x83, + 0x06, 0x97, 0xa0, 0x92, 0x9d, 0x96, 0xb4, 0xa3, 0x8d, 0x9e, 0xa0, 0x8b, + 0xa5, 0x8b, 0x9c, 0x84, 0x99, 0x7e, 0x95, 0x81, 0x93, 0x82, 0x8d, 0x70, + 0x8b, 0x08, 0x56, 0x8b, 0x05, 0x74, 0x39, 0x05, 0x56, 0x29, 0x15, 0x78, + 0x80, 0x80, 0x88, 0x72, 0x8b, 0x54, 0x8b, 0x70, 0x9e, 0x8b, 0xb2, 0x8b, + 0xac, 0x9d, 0xa6, 0xae, 0x9b, 0x08, 0xdf, 0xfb, 0x0c, 0x05, 0x0e, 0xf7, + 0x6f, 0xf9, 0x03, 0x15, 0x46, 0xfb, 0x89, 0x05, 0x88, 0x80, 0x8b, 0x89, + 0x8b, 0x85, 0x8b, 0x7c, 0x99, 0x7e, 0x9c, 0x8b, 0x97, 0x8b, 0x97, 0x93, + 0x93, 0x9b, 0x08, 0xf7, 0x21, 0xf7, 0xa0, 0xfb, 0x18, 0x8b, 0x05, 0x0e, + 0xf8, 0x49, 0xf9, 0x0c, 0x15, 0x75, 0x8b, 0x7f, 0x82, 0x74, 0x67, 0x42, + 0xfb, 0x01, 0x60, 0xfb, 0x14, 0x8b, 0x20, 0x8b, 0xfb, 0x02, 0xaf, 0xfb, + 0x07, 0xd2, 0xfb, 0x05, 0xa8, 0x5c, 0x98, 0x80, 0xa3, 0x8b, 0xa8, 0x8b, + 0xa1, 0xa1, 0x8b, 0xa6, 0x8b, 0x97, 0x89, 0x91, 0x81, 0x9b, 0x08, 0x46, + 0xf7, 0x04, 0x6b, 0xeb, 0x8b, 0xf1, 0x8b, 0xf0, 0xaa, 0xeb, 0xd1, 0xf7, + 0x04, 0x95, 0x9b, 0x8d, 0x91, 0x8b, 0x97, 0x8b, 0xa6, 0x75, 0xa1, 0x6e, + 0x8b, 0x08, 0x0e, 0xf7, 0x3c, 0xf9, 0x0c, 0x15, 0x6e, 0x75, 0x75, 0x70, + 0x1f, 0x8b, 0x7f, 0x8d, 0x85, 0x95, 0x7b, 0xd0, 0xfb, 0x04, 0xab, 0x2b, + 0x8b, 0x25, 0x8b, 0x26, 0x6c, 0x2b, 0x45, 0xfb, 0x04, 0x81, 0x7b, 0x89, + 0x85, 0x8b, 0x7f, 0x8b, 0x70, 0xa1, 0x75, 0xa8, 0x8b, 0xa1, 0x8b, 0x97, + 0x94, 0xa2, 0xae, 0x08, 0xd4, 0xf7, 0x02, 0xb6, 0xf7, 0x14, 0x8b, 0xf6, + 0x8b, 0xf7, 0x02, 0x67, 0xf7, 0x07, 0x44, 0xf7, 0x05, 0x6e, 0xba, 0x7e, + 0x96, 0x73, 0x8b, 0x08, 0x0e, 0xf7, 0x6f, 0xf8, 0x08, 0x15, 0x57, 0x44, + 0x05, 0x7c, 0x75, 0x87, 0x83, 0x8b, 0x7e, 0x8b, 0x70, 0xa2, 0x74, 0xa6, + 0x8b, 0x9f, 0x8b, 0x95, 0x91, 0x9f, 0xa7, 0x08, 0xbf, 0xd3, 0xbf, 0x43, + 0x05, 0xa0, 0x6f, 0x93, 0x85, 0xa0, 0x8b, 0xa6, 0x8b, 0xa2, 0xa2, 0x8b, + 0xa6, 0x8b, 0x98, 0x87, 0x94, 0x7c, 0xa0, 0x08, 0x57, 0xd2, 0xe1, 0xa7, + 0x05, 0xaf, 0x96, 0x99, 0x9a, 0x8b, 0xa5, 0x8b, 0xa5, 0x74, 0xa3, 0x72, + 0x8b, 0x82, 0x8b, 0x88, 0x8a, 0x76, 0x85, 0x08, 0x35, 0x6f, 0x8b, 0xe4, + 0x05, 0x8b, 0xa3, 0x89, 0x94, 0x86, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, + 0x8b, 0x7b, 0x8b, 0x7c, 0x83, 0x81, 0x7e, 0x84, 0x82, 0x89, 0x80, 0x8b, + 0x72, 0x08, 0x8b, 0x32, 0x35, 0xa7, 0x05, 0x76, 0x91, 0x88, 0x8c, 0x81, + 0x8b, 0x72, 0x8b, 0x75, 0x74, 0x8b, 0x70, 0x8b, 0x70, 0x98, 0x7d, 0xb0, + 0x80, 0x08, 0xe1, 0x6f, 0x05, 0x0e, 0xf7, 0xf2, 0xf7, 0x7a, 0x15, 0xf7, + 0x21, 0x06, 0xa2, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x6f, 0x8b, 0x08, 0xfb, 0x21, 0xf7, 0x38, 0x06, 0x8b, 0xa5, 0x8a, 0x92, + 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x84, + 0x82, 0x7d, 0x83, 0x82, 0x89, 0x81, 0x8b, 0x71, 0x08, 0xfb, 0x38, 0xfb, + 0x22, 0x07, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x97, 0x89, + 0xa3, 0x8b, 0x08, 0xf7, 0x22, 0xfb, 0x38, 0x06, 0x8b, 0x74, 0x8d, 0x81, + 0x90, 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, + 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0xf7, 0x38, 0x07, + 0x0e, 0xf7, 0x6f, 0xf7, 0x1a, 0x15, 0x46, 0xfb, 0x89, 0x05, 0x88, 0x80, + 0x8b, 0x89, 0x8b, 0x85, 0x8b, 0x7c, 0x99, 0x7e, 0x9c, 0x8b, 0x97, 0x8b, + 0x97, 0x93, 0x93, 0x9b, 0x08, 0xf7, 0x21, 0xf7, 0xa0, 0xfb, 0x18, 0x8b, + 0x05, 0x0e, 0xf8, 0x80, 0xf7, 0x79, 0x15, 0xa1, 0x8b, 0x97, 0x8d, 0x93, + 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, + 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0xfc, 0x14, 0x06, 0x72, + 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, + 0xf8, 0x14, 0x06, 0x0e, 0xf7, 0xc9, 0x7c, 0x15, 0xb0, 0xa8, 0xa8, 0xb0, + 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x79, 0x06, 0x67, 0x6d, 0x6d, 0x67, 0x67, + 0xa9, 0x6d, 0xaf, 0x1f, 0x9d, 0x06, 0x0e, 0xf8, 0x8d, 0xf8, 0xf6, 0x15, + 0x95, 0x9f, 0x8d, 0x91, 0x8b, 0x96, 0x8b, 0xa4, 0x74, 0xa2, 0x70, 0x8b, + 0x74, 0x8b, 0x7e, 0x81, 0x7c, 0x69, 0x08, 0xfb, 0xd5, 0xfd, 0x3a, 0x05, + 0x82, 0x79, 0x88, 0x81, 0x8b, 0x81, 0x8b, 0x72, 0xa3, 0x74, 0xa5, 0x8b, + 0xa3, 0x8b, 0x98, 0x95, 0x9a, 0xad, 0x08, 0xf7, 0xd4, 0xf9, 0x3b, 0x05, + 0x0e, 0xf8, 0x99, 0xf7, 0xfb, 0x15, 0x8b, 0xe6, 0x6f, 0xdc, 0x59, 0xbf, + 0x69, 0xaf, 0x5b, 0x9e, 0x52, 0x8b, 0x52, 0x8b, 0x5b, 0x78, 0x69, 0x67, + 0x59, 0x57, 0x6f, 0x3a, 0x8b, 0x30, 0x08, 0x2c, 0x07, 0x8b, 0x30, 0xa7, + 0x3a, 0xbd, 0x57, 0xad, 0x67, 0xbb, 0x78, 0xc4, 0x8b, 0xc4, 0x8b, 0xbb, + 0x9e, 0xad, 0xaf, 0xbd, 0xbf, 0xa7, 0xdc, 0x8b, 0xe6, 0x08, 0xea, 0x07, + 0xfb, 0xe2, 0x92, 0x15, 0xf3, 0xb9, 0xcf, 0xd2, 0xd2, 0xb9, 0x47, 0x23, + 0x1e, 0xfb, 0x01, 0x07, 0x23, 0x5d, 0x47, 0x44, 0x44, 0x5d, 0xcf, 0xf3, + 0x1e, 0xf7, 0x01, 0x07, 0x0e, 0xf7, 0xf2, 0xf9, 0x12, 0x15, 0xfb, 0x68, + 0x54, 0x05, 0x63, 0x81, 0x7e, 0x7f, 0x8b, 0x6e, 0x8b, 0x6e, 0x9f, 0x74, + 0xa5, 0x8b, 0x95, 0x8b, 0x8e, 0x8c, 0x9e, 0x90, 0x08, 0xe2, 0xa2, 0x8b, + 0xfc, 0x2d, 0x26, 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x93, + 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0xc2, 0x06, 0x9f, 0x8b, 0x9a, + 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x26, 0xf8, + 0xae, 0x06, 0x0e, 0xf7, 0x63, 0xef, 0x15, 0xe3, 0xd7, 0xc5, 0xbd, 0xa6, + 0xa4, 0xee, 0xe5, 0xa3, 0xb1, 0x8b, 0xcc, 0x8b, 0xf7, 0x03, 0x30, 0xde, + 0xfb, 0x0e, 0x8b, 0x50, 0x8b, 0x52, 0x77, 0x63, 0x67, 0x69, 0x6c, 0x71, + 0x5a, 0x8b, 0x6b, 0x8b, 0x71, 0xa2, 0x75, 0xa6, 0x8b, 0x08, 0xa0, 0x8b, + 0x9e, 0x97, 0x90, 0x9c, 0x96, 0xab, 0x8c, 0x8d, 0x95, 0x97, 0xa1, 0xa5, + 0xae, 0x9a, 0xb3, 0x8b, 0xcc, 0x8b, 0xbd, 0x64, 0x8b, 0x58, 0x8b, 0x69, + 0x7a, 0x75, 0x27, 0x30, 0x5e, 0x62, 0x78, 0x7b, 0xfb, 0x3c, 0xfb, 0x1f, + 0x08, 0x22, 0xf8, 0x5a, 0xe3, 0x07, 0x8b, 0xa3, 0x89, 0x94, 0x86, 0x94, + 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x6c, 0x8b, 0x7b, 0x79, 0x88, 0x67, + 0x08, 0xfb, 0x5d, 0x06, 0x0e, 0xf7, 0xa8, 0xf8, 0x13, 0x15, 0x6d, 0x75, + 0x76, 0x6e, 0x1f, 0x8b, 0x70, 0x9e, 0x7a, 0xac, 0x89, 0xb6, 0x89, 0x98, + 0x89, 0xa0, 0x82, 0xba, 0x78, 0xa8, 0x68, 0x8b, 0x66, 0x8b, 0x74, 0x80, + 0x72, 0x7a, 0x7b, 0x70, 0x73, 0x66, 0x81, 0x46, 0x8b, 0x4b, 0x8b, 0x6d, + 0x91, 0x71, 0x9c, 0x08, 0x7b, 0x95, 0x87, 0x8d, 0x7f, 0x8b, 0x08, 0x6f, + 0x75, 0x75, 0x6f, 0x58, 0xdd, 0x69, 0xf7, 0x0f, 0x1f, 0xe2, 0x8b, 0xc0, + 0x99, 0xb7, 0xac, 0xb9, 0xaf, 0xa7, 0xc3, 0x8b, 0xc5, 0x8b, 0xcb, 0x66, + 0xbd, 0x3f, 0xb0, 0x08, 0xcc, 0xb2, 0xa5, 0xb0, 0x8b, 0xc2, 0x8b, 0xb4, + 0x79, 0xb7, 0x6b, 0xaa, 0x65, 0xb2, 0x57, 0x9e, 0x49, 0x8b, 0x08, 0x20, + 0x28, 0x56, 0x51, 0x70, 0xa1, 0x74, 0xa6, 0x1f, 0x99, 0x8b, 0x98, 0x91, + 0x94, 0x94, 0xab, 0xae, 0xa7, 0x96, 0xc2, 0x8b, 0x08, 0xd0, 0xb6, 0x6e, + 0x5c, 0x61, 0x61, 0x66, 0x5a, 0x1f, 0x63, 0x06, 0x0e, 0xf8, 0x53, 0xf9, + 0x02, 0x15, 0xfb, 0x17, 0x8b, 0xfb, 0x85, 0xfc, 0x25, 0x8b, 0x38, 0xf7, + 0xa4, 0x8b, 0x8b, 0x65, 0x65, 0x8b, 0x05, 0x73, 0x8b, 0x82, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, + 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0x18, 0x06, 0xa0, + 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x08, + 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xb1, 0x07, 0xb3, 0x8c, 0xa0, 0x9c, 0x8b, + 0xab, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf8, 0x14, 0x07, 0x27, 0xfc, + 0x14, 0x15, 0xfb, 0x2a, 0x8b, 0xf7, 0x2a, 0xf7, 0x86, 0x8b, 0xfb, 0x86, + 0x05, 0x0e, 0xf7, 0x6f, 0xf8, 0x9e, 0x15, 0xf7, 0x5e, 0x06, 0xa0, 0x8b, + 0x99, 0x8d, 0x92, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7f, 0x95, 0x80, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, + 0xc2, 0xfb, 0xb0, 0x06, 0x6b, 0xa0, 0x73, 0xa8, 0x1e, 0x94, 0x8b, 0x91, + 0x8d, 0x98, 0x91, 0xb6, 0xa1, 0xb7, 0x97, 0xac, 0x8b, 0x08, 0xce, 0xb8, + 0x5a, 0x41, 0x3c, 0x5b, 0x66, 0x23, 0x1f, 0x4a, 0x8b, 0x6d, 0x93, 0x6d, + 0xa4, 0x7c, 0x97, 0x84, 0x8e, 0x7d, 0x8b, 0x08, 0x70, 0x74, 0x75, 0x70, + 0x53, 0xe7, 0x60, 0xf7, 0x0c, 0x1f, 0xe9, 0x8b, 0xc5, 0x9f, 0xb7, 0xbb, + 0xaf, 0xb2, 0x9e, 0xbf, 0x8b, 0xc5, 0x8b, 0xf7, 0x14, 0x31, 0xe9, 0xfb, + 0x0d, 0x8b, 0x6e, 0x8b, 0x69, 0x85, 0x67, 0x80, 0x08, 0xf7, 0x07, 0x07, + 0x0e, 0xf7, 0x64, 0xf7, 0xd8, 0x15, 0xa2, 0xf7, 0x0f, 0xe7, 0xe3, 0xf5, + 0x8b, 0x94, 0x8b, 0x90, 0x8a, 0x96, 0x87, 0x9b, 0x85, 0x95, 0x89, 0x94, + 0x8b, 0x08, 0xa7, 0xa2, 0xa2, 0xa7, 0xb2, 0x5c, 0xa5, 0x45, 0x1f, 0x2f, + 0x8b, 0x39, 0x61, 0x48, 0x39, 0x58, 0x4b, 0x71, 0x3f, 0x8b, 0x32, 0x8b, + 0x43, 0x9d, 0x3d, 0xa5, 0x5b, 0xb1, 0x47, 0xc8, 0x69, 0xde, 0x8b, 0xce, + 0x8b, 0xbc, 0x9e, 0xaf, 0xb3, 0xad, 0xb0, 0x9d, 0xbe, 0x8b, 0xc4, 0x08, + 0xf7, 0x05, 0x36, 0xe7, 0x22, 0x1e, 0x58, 0x8b, 0x65, 0x78, 0x5b, 0x58, + 0x08, 0x95, 0xfb, 0x07, 0x15, 0xa6, 0xbc, 0xbd, 0xaf, 0xb6, 0x8b, 0x08, + 0xc1, 0xb6, 0x5d, 0x51, 0x4a, 0x65, 0x63, 0x4c, 0x1f, 0x4a, 0x8b, 0x67, + 0xb0, 0x7c, 0xe2, 0x08, 0x0e, 0xf8, 0x27, 0xf8, 0x9e, 0x15, 0xfb, 0x2a, + 0xfc, 0x4d, 0x05, 0x86, 0x7a, 0x89, 0x83, 0x8b, 0x82, 0x8b, 0x71, 0xa3, + 0x75, 0xa6, 0x8b, 0xa5, 0x8b, 0x98, 0x98, 0x98, 0xaf, 0x08, 0xf7, 0x33, + 0xf8, 0x6f, 0x8b, 0xee, 0xfc, 0x45, 0x8b, 0x8b, 0x33, 0x05, 0x8b, 0x73, + 0x8d, 0x82, 0x90, 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0xaa, 0x8b, + 0x9b, 0x9d, 0x8e, 0xaf, 0x08, 0xf7, 0x78, 0x06, 0x0e, 0xf8, 0x38, 0xf7, + 0xd3, 0x15, 0xc7, 0xb3, 0xa7, 0xb6, 0x8b, 0xc2, 0x08, 0xef, 0x2e, 0xdc, + 0xfb, 0x07, 0xfb, 0x08, 0x2f, 0x3a, 0x25, 0x1e, 0x8b, 0x56, 0xa7, 0x60, + 0xc7, 0x63, 0x08, 0x4b, 0x63, 0x6a, 0x57, 0x8b, 0x4d, 0x08, 0x20, 0xe3, + 0x42, 0xf7, 0x14, 0xf7, 0x16, 0xe3, 0xd4, 0xf6, 0x1e, 0x8b, 0xc9, 0x6a, + 0xbf, 0x4b, 0xb3, 0x08, 0xfb, 0x0c, 0xf7, 0x6f, 0x15, 0xcb, 0xb7, 0x67, + 0x57, 0x59, 0x5e, 0x67, 0x4c, 0x4c, 0x5e, 0xaf, 0xbe, 0x1f, 0xbe, 0xb7, + 0xaf, 0xcb, 0x1e, 0xfb, 0xa7, 0x04, 0xcd, 0xbe, 0x63, 0x58, 0x59, 0x5a, + 0x66, 0x47, 0x47, 0x5a, 0xb0, 0xbe, 0x1f, 0xbd, 0xc0, 0xb3, 0xcb, 0x1e, + 0x0e, 0xf8, 0x4a, 0xf7, 0xbf, 0x15, 0x74, 0xfb, 0x0f, 0x2f, 0x33, 0x21, + 0x8b, 0x82, 0x8b, 0x86, 0x8c, 0x80, 0x8f, 0x7b, 0x91, 0x81, 0x8d, 0x82, + 0x8b, 0x08, 0x6f, 0x74, 0x74, 0x6f, 0x64, 0xba, 0x71, 0xd1, 0x1f, 0xe7, + 0x8b, 0xdd, 0xb5, 0xce, 0xdd, 0xbe, 0xcb, 0xa5, 0xd8, 0x8b, 0xe3, 0x8b, + 0xd2, 0x79, 0xdb, 0x71, 0xba, 0x65, 0xcf, 0x4e, 0xad, 0x38, 0x8b, 0x48, + 0x8b, 0x5a, 0x78, 0x67, 0x63, 0x69, 0x66, 0x79, 0x58, 0x8b, 0x52, 0x08, + 0xfb, 0x05, 0xe0, 0x2f, 0xf5, 0x1e, 0xbd, 0x8b, 0xb1, 0x9e, 0xbb, 0xbe, + 0x08, 0x81, 0xf7, 0x07, 0x15, 0x70, 0x5a, 0x59, 0x67, 0x60, 0x8b, 0x08, + 0x55, 0x60, 0xb9, 0xc5, 0xcc, 0xb1, 0xb3, 0xca, 0x1f, 0xcc, 0x8b, 0xaf, + 0x66, 0x9a, 0x34, 0x08, 0x0e, 0xf7, 0xc9, 0x7c, 0x15, 0xb0, 0xa8, 0xa8, + 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x79, 0x06, 0x67, 0x6d, 0x6d, 0x67, + 0x67, 0xa9, 0x6d, 0xaf, 0x1f, 0x9d, 0x06, 0xf7, 0xd3, 0x04, 0xb0, 0xa8, + 0xa8, 0xb0, 0xb1, 0x6e, 0xa8, 0x66, 0x1f, 0x79, 0x06, 0x67, 0x6d, 0x6d, + 0x66, 0x67, 0xa9, 0x6d, 0xaf, 0x1f, 0x9d, 0x06, 0x0e, 0xf7, 0x6f, 0xf7, + 0x1a, 0x15, 0x46, 0xfb, 0x89, 0x05, 0x88, 0x80, 0x8b, 0x89, 0x8b, 0x85, + 0x8b, 0x7c, 0x99, 0x7e, 0x9c, 0x8b, 0x97, 0x8b, 0x97, 0x93, 0x93, 0x9b, + 0x08, 0xf7, 0x21, 0xf7, 0xa0, 0xfb, 0x18, 0x8b, 0x05, 0xc4, 0xf7, 0xc3, + 0x15, 0x5e, 0x6d, 0x70, 0x64, 0x63, 0xa9, 0x70, 0xb8, 0xb8, 0xa9, 0xa5, + 0xb3, 0xb4, 0x6e, 0xa5, 0x5d, 0x1f, 0x0e, 0xf7, 0x8f, 0xf7, 0xab, 0x15, + 0xf7, 0x99, 0xf7, 0x19, 0x05, 0xa2, 0x97, 0x94, 0x97, 0x8b, 0x9e, 0x8b, + 0x91, 0x89, 0x92, 0x88, 0x91, 0x08, 0x8a, 0x8d, 0x05, 0x85, 0x99, 0x7b, + 0x96, 0x7d, 0x8b, 0x83, 0x8b, 0x81, 0x88, 0x7f, 0x85, 0x08, 0xfc, 0x42, + 0xfb, 0x68, 0xf8, 0x42, 0xfb, 0x6d, 0x05, 0x96, 0x85, 0x96, 0x88, 0x93, + 0x8b, 0x99, 0x8b, 0x9b, 0x96, 0x91, 0x99, 0x08, 0x8c, 0x8d, 0x05, 0x8e, + 0x92, 0x8d, 0x92, 0x8b, 0x90, 0x8b, 0x9e, 0x82, 0x97, 0x74, 0x97, 0x08, + 0xfb, 0x99, 0xf7, 0x1c, 0x05, 0x0e, 0xf7, 0x00, 0xf8, 0x3a, 0x15, 0x72, + 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x97, 0x89, 0xa3, 0x8b, 0x08, + 0xf8, 0x14, 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, + 0x8d, 0x70, 0x8b, 0x08, 0xfc, 0x14, 0x06, 0xfb, 0x4c, 0x04, 0x72, 0x8b, + 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x97, 0x89, 0xa3, 0x8b, 0x08, 0xf8, + 0x14, 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x70, 0x8b, 0x08, 0xfc, 0x14, 0x06, 0x0e, 0xf7, 0xf1, 0xf7, 0xa7, 0x15, + 0xfb, 0x99, 0xfb, 0x19, 0x05, 0x74, 0x7f, 0x82, 0x7f, 0x8b, 0x79, 0x8b, + 0x84, 0x8d, 0x85, 0x8e, 0x84, 0x08, 0x8c, 0x89, 0x05, 0x91, 0x7d, 0x9b, + 0x80, 0x99, 0x8b, 0x92, 0x8b, 0x96, 0x8e, 0x97, 0x91, 0x08, 0xf8, 0x42, + 0xf7, 0x68, 0xfc, 0x42, 0xf7, 0x6d, 0x05, 0x80, 0x91, 0x80, 0x8e, 0x83, + 0x8b, 0x7d, 0x8b, 0x7a, 0x7f, 0x86, 0x7e, 0x08, 0x8a, 0x89, 0x05, 0x88, + 0x84, 0x89, 0x84, 0x8b, 0x85, 0x8b, 0x79, 0x94, 0x7f, 0xa2, 0x80, 0x08, + 0xf7, 0x99, 0xfb, 0x1d, 0x05, 0x0e, 0xf3, 0xf8, 0x60, 0x15, 0x8b, 0x74, + 0x8d, 0x80, 0x90, 0x83, 0x94, 0x7d, 0x9c, 0x81, 0x9c, 0x8b, 0x9a, 0x8b, + 0x9b, 0x93, 0x95, 0x98, 0x92, 0x94, 0x8d, 0x95, 0x8b, 0xa5, 0x08, 0x99, + 0x07, 0xac, 0x9b, 0xad, 0x93, 0xb1, 0x8b, 0xcb, 0x8b, 0xb7, 0x69, 0x8b, + 0x59, 0x8b, 0x60, 0x67, 0x71, 0xfb, 0x14, 0x5a, 0x08, 0x53, 0x07, 0x8b, + 0x74, 0x8d, 0x81, 0x90, 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0xa8, + 0x8b, 0x9c, 0x9d, 0x8f, 0xaf, 0xf7, 0x0d, 0xc0, 0xb6, 0xba, 0x8b, 0xdc, + 0x8b, 0xf7, 0x04, 0x36, 0xd8, 0xfb, 0x10, 0x8b, 0x4b, 0x8b, 0x5f, 0x7e, + 0x2b, 0x5d, 0x08, 0x3c, 0x07, 0xf7, 0x63, 0xfc, 0x6f, 0x15, 0xb0, 0xa8, + 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x7a, 0x06, 0x66, 0x6d, 0x6d, + 0x67, 0x67, 0xa9, 0x6d, 0xb0, 0x1f, 0x9c, 0x06, 0x0e, 0xf8, 0x2b, 0xf8, + 0x21, 0x15, 0xfb, 0x04, 0x83, 0x3e, 0x45, 0x8b, 0x2e, 0x8b, 0x38, 0xd2, + 0x44, 0xe0, 0x8b, 0x94, 0x8b, 0x94, 0x8c, 0x9a, 0x8d, 0x08, 0x88, 0xba, + 0x07, 0xb0, 0x9d, 0x98, 0xa7, 0x1f, 0x8b, 0x9c, 0x84, 0x96, 0x7b, 0x92, + 0x08, 0xf7, 0xad, 0x07, 0xf7, 0x03, 0x3e, 0xdb, 0xfb, 0x00, 0xfb, 0x16, + 0x2c, 0xfb, 0x11, 0xfb, 0x40, 0x1e, 0xfb, 0x3d, 0x07, 0x8b, 0x42, 0x9c, + 0x43, 0xa9, 0x55, 0xb5, 0x41, 0xc2, 0x6a, 0xdd, 0x8b, 0x08, 0xea, 0xdd, + 0xb2, 0xba, 0xa2, 0x79, 0x9d, 0x75, 0x1f, 0x7f, 0x8b, 0x86, 0x88, 0x7d, + 0x7d, 0x78, 0x77, 0x63, 0x7f, 0x5f, 0x8b, 0x5f, 0x8b, 0x6c, 0x9a, 0x73, + 0xae, 0x69, 0xba, 0x7a, 0xc9, 0x8b, 0xd7, 0x08, 0xf7, 0x30, 0x07, 0xf7, + 0x14, 0xca, 0xeb, 0xdf, 0xc9, 0xb6, 0x5d, 0x49, 0x1e, 0x6b, 0x07, 0xfb, + 0x86, 0x04, 0x7d, 0x89, 0x86, 0x8b, 0x84, 0x8b, 0x5b, 0x8b, 0x67, 0xaa, + 0x8b, 0xb4, 0x8b, 0xbc, 0xb7, 0xaf, 0xcd, 0x91, 0x08, 0xfb, 0x35, 0x07, + 0x0e, 0xf8, 0x34, 0xf7, 0x32, 0x15, 0xa2, 0x51, 0x74, 0x8b, 0x05, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, + 0xf7, 0x1f, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x94, 0x81, 0x93, 0x82, + 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x5b, 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, + 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, + 0x08, 0xca, 0x8b, 0xfb, 0x2f, 0xfc, 0x13, 0x05, 0x72, 0x8b, 0x82, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, + 0xb7, 0x1e, 0xf7, 0x19, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x74, 0x8b, 0xa2, 0xc5, 0xf7, 0x82, + 0x8b, 0x05, 0x62, 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xda, 0xf7, 0x54, 0xd9, + 0xfb, 0x54, 0x05, 0x0e, 0xe9, 0xef, 0x15, 0x7c, 0x06, 0x73, 0x8b, 0x82, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, + 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0xbb, + 0x06, 0xf7, 0x0a, 0xda, 0xcb, 0xeb, 0x1f, 0x8b, 0xca, 0x69, 0xb9, 0x43, + 0xaf, 0x08, 0xb7, 0xad, 0x9e, 0xac, 0x8b, 0xb9, 0x08, 0xea, 0x38, 0xd1, + 0xfb, 0x05, 0x1e, 0xfb, 0x91, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, + 0x7d, 0x82, 0x81, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x81, + 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0x9a, 0x06, 0xfc, 0x13, 0x07, + 0xef, 0xf7, 0x86, 0x15, 0xf7, 0x21, 0xf7, 0x19, 0x07, 0xca, 0xb1, 0x73, + 0x63, 0x5d, 0x5a, 0x6c, 0x43, 0x1f, 0xfb, 0x05, 0x06, 0xfb, 0x86, 0x04, + 0xf7, 0x22, 0xf7, 0x1b, 0x07, 0xb5, 0x8b, 0xab, 0x84, 0xa4, 0x7c, 0x08, + 0xa5, 0x7b, 0x9c, 0x71, 0x8b, 0x73, 0x08, 0x67, 0x69, 0x79, 0x47, 0x1e, + 0xfb, 0x43, 0x06, 0x0e, 0xf8, 0x53, 0xf8, 0xc7, 0x15, 0x54, 0xa5, 0x68, + 0x93, 0x57, 0x8b, 0x08, 0xfb, 0x2e, 0xfb, 0x0a, 0xfb, 0x0e, 0xfb, 0x34, + 0x1f, 0x49, 0x07, 0xfb, 0x2c, 0xf7, 0x10, 0xfb, 0x03, 0xf7, 0x3e, 0x1e, + 0xd3, 0x8b, 0xcf, 0x9d, 0xb7, 0xab, 0xad, 0xa3, 0x9e, 0xa5, 0x8b, 0xa2, + 0x8b, 0xa6, 0x74, 0xa2, 0x70, 0x8b, 0x7e, 0x8b, 0x7f, 0x86, 0x80, 0x80, + 0x70, 0x6f, 0x8b, 0x8b, 0x80, 0x85, 0x72, 0x7c, 0x63, 0x83, 0x5e, 0x8b, + 0x08, 0xfb, 0x0c, 0x3e, 0xcc, 0xef, 0x1f, 0xcb, 0x07, 0xf4, 0xd5, 0xd8, + 0xf1, 0x1e, 0xad, 0x8b, 0xaf, 0x82, 0xa6, 0x7c, 0xa8, 0x7b, 0x95, 0x7e, + 0x90, 0x73, 0x8f, 0x73, 0x8d, 0x84, 0x93, 0x83, 0x93, 0x83, 0x99, 0x85, + 0x98, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x94, 0x8d, 0x96, + 0x8b, 0xa4, 0x08, 0xdf, 0x07, 0x8b, 0xa4, 0x8a, 0x93, 0x85, 0x94, 0x08, + 0x82, 0x9a, 0x7b, 0x94, 0x79, 0x8b, 0x7a, 0x8b, 0x7f, 0x85, 0x7e, 0x79, + 0x08, 0x81, 0x8f, 0x05, 0x0e, 0xd5, 0xef, 0x15, 0x65, 0x74, 0x79, 0x6b, + 0x1f, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, 0xa3, + 0x8b, 0x08, 0xf7, 0x60, 0x06, 0xe2, 0x8b, 0xc7, 0xa2, 0xbc, 0xbf, 0xb9, + 0xbb, 0xa3, 0xc9, 0x8b, 0xd4, 0x08, 0xba, 0x07, 0xf7, 0x31, 0xfb, 0x04, + 0xf7, 0x0d, 0xfb, 0x26, 0x1e, 0xfb, 0x68, 0x06, 0x70, 0x8b, 0x84, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, 0x6b, 0xa1, 0x79, + 0xb2, 0x1e, 0xfc, 0x13, 0x07, 0xef, 0x16, 0xf8, 0x13, 0xf7, 0x02, 0x07, + 0xc0, 0x8b, 0xb1, 0x7b, 0xa9, 0x68, 0xa8, 0x69, 0x9b, 0x5f, 0x8b, 0x5c, + 0x08, 0x5d, 0x07, 0x8b, 0x58, 0x7e, 0x68, 0x6f, 0x6c, 0x6c, 0x6b, 0x6a, + 0x7f, 0x4f, 0x8b, 0x08, 0xfb, 0x03, 0x06, 0x0e, 0xf7, 0x56, 0xf7, 0x87, + 0x15, 0xe0, 0x84, 0x06, 0x8b, 0x73, 0x8d, 0x82, 0x90, 0x82, 0x94, 0x7c, + 0x9c, 0x82, 0x9c, 0x8b, 0x9a, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x94, + 0x8d, 0x95, 0x8b, 0xa5, 0x08, 0xf7, 0x05, 0x07, 0x8b, 0x94, 0x8b, 0x8e, + 0x8a, 0x94, 0x87, 0xa7, 0x79, 0x9d, 0x70, 0x8b, 0x7c, 0x8b, 0x7c, 0x83, + 0x81, 0x7e, 0x84, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, 0x84, 0x36, 0xf7, + 0x21, 0xf7, 0x7e, 0x59, 0x07, 0x8b, 0x73, 0x8d, 0x81, 0x90, 0x82, 0x95, + 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, + 0x95, 0x8d, 0x93, 0x8b, 0xa7, 0x08, 0xf7, 0x2a, 0xfc, 0x55, 0x07, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, + 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, + 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, + 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf8, 0x6b, 0xf7, 0x2c, 0x06, 0x8b, + 0xa4, 0x89, 0x94, 0x86, 0x94, 0x81, 0x9a, 0x7b, 0x94, 0x7a, 0x8b, 0x7b, + 0x8b, 0x7c, 0x84, 0x81, 0x7d, 0x84, 0x81, 0x89, 0x83, 0x8b, 0x6f, 0x08, + 0x57, 0xfb, 0x94, 0x07, 0xf7, 0x23, 0x07, 0x0e, 0xf7, 0x56, 0xf7, 0x87, + 0x15, 0xe0, 0x84, 0x06, 0x8b, 0x74, 0x8d, 0x80, 0x90, 0x82, 0x94, 0x7d, + 0x9c, 0x81, 0x9c, 0x8b, 0x9a, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, + 0x8d, 0x94, 0x8b, 0xa6, 0x08, 0xf7, 0x05, 0x07, 0x8b, 0xa4, 0x8a, 0x92, + 0x85, 0x95, 0x82, 0x9a, 0x7b, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x83, + 0x81, 0x7e, 0x84, 0x82, 0x89, 0x80, 0x8b, 0x72, 0x08, 0x84, 0x36, 0xf7, + 0x21, 0xf7, 0x94, 0x58, 0x07, 0x8b, 0x74, 0x8d, 0x80, 0x90, 0x83, 0x95, + 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, + 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0xf7, 0x2b, 0xfc, 0x6b, 0x07, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, + 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x93, + 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0x6b, 0x06, 0x9f, 0x8b, 0x9a, + 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x27, 0xf7, + 0x23, 0x06, 0x0e, 0xf8, 0xba, 0xf7, 0x48, 0x15, 0xa7, 0x93, 0x99, 0x9c, + 0x8b, 0xa4, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x82, 0x8d, + 0x70, 0x8b, 0x08, 0xfb, 0x43, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, + 0x94, 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xef, 0x46, 0x06, 0x65, 0x7a, + 0x64, 0x83, 0x5b, 0x8b, 0x4c, 0x8b, 0x59, 0x9a, 0x69, 0xa8, 0x6c, 0xa5, + 0x7d, 0xb2, 0x8b, 0xc5, 0x08, 0xcb, 0x07, 0x8b, 0xbd, 0x9f, 0xbd, 0xac, + 0xac, 0xaa, 0xaa, 0xb8, 0x9b, 0xc3, 0x8b, 0xd4, 0x8b, 0xbd, 0x75, 0x95, + 0x68, 0x93, 0x6c, 0x8b, 0x8b, 0x91, 0x84, 0x93, 0x82, 0x99, 0x85, 0x98, + 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x08, 0x93, 0x95, 0x8c, 0x92, + 0x8b, 0xa7, 0x08, 0xd9, 0x07, 0x8b, 0xa3, 0x8a, 0x93, 0x85, 0x95, 0x84, + 0x9a, 0x7b, 0x94, 0x7a, 0x8b, 0x78, 0x8b, 0x81, 0x83, 0x7f, 0x73, 0x61, + 0xa0, 0x5a, 0x96, 0x55, 0x8b, 0x39, 0x8b, 0x4a, 0x72, 0x56, 0x57, 0x56, + 0x56, 0x6c, 0x41, 0x8b, 0x3f, 0x08, 0x44, 0x07, 0x8b, 0x45, 0xa4, 0x47, + 0xb4, 0x60, 0xbc, 0x59, 0xe0, 0x6e, 0xed, 0x8b, 0xd9, 0x8b, 0xbf, 0x9a, + 0xe4, 0xba, 0x08, 0xf7, 0x18, 0x07, 0x0e, 0xf8, 0x2d, 0xf7, 0x85, 0x15, + 0xfb, 0x21, 0x7c, 0x07, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x81, 0x94, 0x85, + 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x0d, 0x06, 0xa0, 0x8b, 0x98, 0x8d, + 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, + 0x7e, 0x95, 0x82, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x85, 0xf8, 0x13, + 0x06, 0xac, 0x8e, 0x9e, 0x9d, 0x8b, 0xa8, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, + 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x26, 0x06, 0x72, 0x8b, + 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x81, 0x95, 0x84, 0x94, 0x89, 0xa5, 0x8b, 0x08, 0x9a, + 0xfb, 0x22, 0xfb, 0x6a, 0xf7, 0x22, 0x9a, 0x06, 0xa3, 0x8b, 0x94, 0x8d, + 0x94, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, + 0x7e, 0x95, 0x82, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x26, 0x06, 0x72, + 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x6e, 0x9e, 0x79, 0xac, 0x88, 0x08, 0xfc, 0x13, 0x85, 0x07, 0x72, 0x8b, + 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, + 0x93, 0x7b, 0x97, 0x81, 0x94, 0x85, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, + 0x0d, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x82, 0x92, 0x81, 0x8d, + 0x71, 0x8b, 0x08, 0x7c, 0xf7, 0x21, 0xf7, 0x6a, 0x06, 0x0e, 0xf7, 0xf2, + 0xf8, 0x77, 0x15, 0xf0, 0x06, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0xc2, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, + 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf0, 0xfc, + 0x13, 0x26, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x84, 0x97, + 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0xc2, 0x06, 0xb7, 0xa1, 0x9c, 0xac, 0x1f, + 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, + 0x08, 0x26, 0xf8, 0x13, 0x06, 0x0e, 0xf8, 0x7e, 0xf8, 0x77, 0x15, 0xc4, + 0x06, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x82, 0x92, 0x82, 0x8d, 0x70, + 0x8b, 0x08, 0xfb, 0xa8, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, + 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf7, 0x0b, 0xfb, 0xb1, 0x06, 0x8b, + 0x5d, 0x88, 0x82, 0x76, 0x76, 0x74, 0x75, 0x67, 0x7d, 0x67, 0x8b, 0x69, + 0x8b, 0x69, 0x94, 0x5a, 0xa1, 0x08, 0xeb, 0x07, 0x8b, 0xa4, 0x8a, 0x94, + 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x83, + 0x81, 0x7e, 0x84, 0x82, 0x89, 0x80, 0x8b, 0x71, 0x08, 0xfb, 0x36, 0x07, + 0xe6, 0x5e, 0xce, 0x77, 0xc4, 0x8b, 0xc6, 0x8b, 0xc3, 0x9f, 0xb5, 0xaf, + 0xba, 0xb4, 0x9c, 0xb1, 0x8b, 0xcd, 0x08, 0xf7, 0xbc, 0x07, 0x0e, 0xf7, + 0x56, 0xf7, 0x64, 0x15, 0xc7, 0xbe, 0x05, 0xc8, 0x78, 0xcb, 0x2a, 0xba, + 0xfb, 0x23, 0x08, 0xf7, 0x02, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, + 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x6b, 0x06, 0x5d, 0xf7, 0x07, + 0x4d, 0xde, 0x4e, 0xab, 0x08, 0xf7, 0x44, 0xf7, 0x2d, 0x05, 0xb4, 0xa0, + 0x9c, 0xac, 0x1f, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, + 0x8d, 0x70, 0x8b, 0x08, 0x27, 0x06, 0x83, 0x8b, 0x8a, 0x8b, 0x7f, 0x89, + 0x6e, 0x88, 0x7b, 0x79, 0x8b, 0x6f, 0x8b, 0x74, 0x95, 0x7d, 0xa0, 0x83, + 0x08, 0xfb, 0x46, 0xfb, 0x2d, 0x8b, 0xf7, 0x29, 0xae, 0x8b, 0x05, 0xa2, + 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x82, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, + 0xfb, 0x2a, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, + 0x89, 0xa4, 0x8b, 0x08, 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, 0x82, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, + 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0x2a, + 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, + 0x8b, 0x08, 0x68, 0xf7, 0x00, 0x06, 0x0e, 0xf7, 0x94, 0xf8, 0x77, 0x15, + 0xc4, 0x06, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x70, 0x8b, 0x08, 0xfb, 0x6a, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, + 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xc4, 0xfc, 0x13, 0x52, 0x06, + 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, + 0x08, 0xf8, 0x6c, 0xf7, 0x54, 0x06, 0x8b, 0xa4, 0x8a, 0x94, 0x85, 0x94, + 0x81, 0x9a, 0x7b, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x84, 0x81, 0x7d, + 0x84, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, 0x2f, 0xfb, 0x6b, 0xf8, 0x13, + 0x07, 0x0e, 0xf7, 0x22, 0xf8, 0x19, 0x15, 0xf7, 0x0a, 0xfb, 0x8f, 0xe6, + 0x8b, 0xf7, 0x03, 0xf7, 0x8f, 0x8b, 0xfb, 0xb5, 0x68, 0x8b, 0x05, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, + 0xf7, 0x16, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, + 0x9b, 0x8b, 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf8, 0x13, 0x07, + 0xac, 0x8e, 0x9e, 0x9d, 0x8b, 0xa8, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, + 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x02, 0x8b, 0xfb, 0x1b, + 0xfb, 0xbd, 0xfb, 0x1e, 0xf7, 0xbd, 0xfb, 0x01, 0x8b, 0x05, 0x8a, 0x8c, + 0x8a, 0x8b, 0x89, 0x8b, 0x7f, 0x8b, 0x76, 0x87, 0x86, 0x88, 0x7c, 0x81, + 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x6d, 0x9e, 0x79, 0xac, 0x88, 0x08, 0xfc, + 0x13, 0x07, 0x64, 0x75, 0x79, 0x6b, 0x1f, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x82, 0x94, 0x84, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x15, 0x06, 0x9f, + 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, + 0x9b, 0x84, 0x9a, 0x7e, 0x95, 0x80, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, + 0x68, 0x06, 0xf7, 0xb5, 0x07, 0x0e, 0xf7, 0x41, 0xf8, 0x1e, 0x15, 0xf7, + 0x97, 0xfc, 0x1e, 0xee, 0x8b, 0x8b, 0xf8, 0x77, 0x05, 0xb3, 0xa0, 0x9d, + 0xab, 0x1f, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x70, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, + 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0xb8, 0x06, 0xfb, + 0x96, 0xf8, 0x1c, 0xfb, 0x07, 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0x9a, 0xfc, 0x13, 0x06, + 0x64, 0x75, 0x79, 0x6b, 0x1f, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x84, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x15, 0x06, 0x9f, 0x8b, 0x9a, + 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x68, 0xf7, + 0xba, 0x06, 0x0e, 0xf7, 0xc0, 0xf8, 0xe9, 0x15, 0xfb, 0x2e, 0xfb, 0x11, + 0xfb, 0x1d, 0xfb, 0x3c, 0xfb, 0x3d, 0xf7, 0x11, 0xfb, 0x1d, 0xf7, 0x2e, + 0xf7, 0x2c, 0xf7, 0x13, 0xf7, 0x1d, 0xf7, 0x38, 0x1f, 0x8b, 0xeb, 0x6c, + 0xd8, 0x4c, 0xc7, 0x56, 0xbd, 0x4a, 0xa6, 0x48, 0x8b, 0x08, 0x27, 0x04, + 0xee, 0xdb, 0x2e, 0xfb, 0x07, 0xfb, 0x02, 0x39, 0x2e, 0x2a, 0x29, 0x3a, + 0xe8, 0xf7, 0x05, 0xf7, 0x04, 0xdc, 0xe8, 0xed, 0x1f, 0x0e, 0xf7, 0x56, + 0xf7, 0x5c, 0x15, 0xed, 0x06, 0xe8, 0x8b, 0xbd, 0x9c, 0xb7, 0xbc, 0xab, + 0xae, 0x9d, 0xba, 0x8b, 0xb9, 0x08, 0xf7, 0x03, 0x31, 0xd9, 0xfb, 0x13, + 0x1e, 0xfb, 0x7d, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x81, 0x94, 0x84, + 0x96, 0x89, 0xa4, 0x8b, 0x08, 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, + 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, + 0x93, 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, + 0x6a, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x70, 0x8b, 0x08, 0x28, 0xef, 0x06, 0xf7, 0xaf, 0x04, 0xf7, 0x0a, 0x06, + 0xd0, 0xb5, 0x68, 0x52, 0x53, 0x61, 0x68, 0x46, 0x1f, 0xfb, 0x0a, 0xf7, + 0x4b, 0x06, 0x0e, 0xf7, 0xa3, 0x85, 0x15, 0x93, 0x8a, 0x93, 0x8b, 0x8d, + 0x8b, 0xc3, 0x8b, 0xb9, 0x96, 0xb1, 0xa2, 0xea, 0xc4, 0xc2, 0xee, 0x8b, + 0xf7, 0x03, 0x08, 0xf7, 0x3a, 0xfb, 0x12, 0xf7, 0x1d, 0xfb, 0x2d, 0xfb, + 0x2e, 0xfb, 0x11, 0xfb, 0x1d, 0xfb, 0x3c, 0x1e, 0x8b, 0x4e, 0x9b, 0x51, + 0xa7, 0x5a, 0xa7, 0x5c, 0xaa, 0x70, 0xd6, 0x60, 0x08, 0x4d, 0x4f, 0x05, + 0x7b, 0x7c, 0x87, 0x83, 0x8b, 0x7c, 0x8b, 0x6f, 0xa1, 0x73, 0xa5, 0x8b, + 0x91, 0x8b, 0x95, 0x8d, 0x97, 0x8e, 0xb6, 0x96, 0xc9, 0x95, 0xa0, 0x8b, + 0x99, 0x8b, 0xa2, 0x87, 0x96, 0x87, 0x08, 0xbb, 0x78, 0x8f, 0x8a, 0xa4, + 0x8b, 0xaa, 0x8b, 0xa7, 0x94, 0xaf, 0xa1, 0xa7, 0x9b, 0x95, 0x99, 0x8b, + 0xa0, 0x8b, 0xa7, 0x75, 0xa1, 0x6e, 0x8b, 0x80, 0x8b, 0x85, 0x89, 0x74, + 0x7c, 0x78, 0x7f, 0x82, 0x88, 0x7c, 0x8b, 0x08, 0x80, 0x8b, 0x84, 0x8c, + 0x74, 0x91, 0x08, 0x6b, 0x94, 0x71, 0x8f, 0x71, 0x8b, 0x7c, 0x8b, 0x7f, + 0x8a, 0x73, 0x87, 0x08, 0x8f, 0xa3, 0x05, 0xa8, 0xf8, 0x8b, 0x15, 0xee, + 0xdb, 0x2e, 0xfb, 0x08, 0xfb, 0x02, 0x39, 0x2e, 0x2a, 0x29, 0x3a, 0xe9, + 0xf7, 0x04, 0xf7, 0x05, 0xdc, 0xe8, 0xed, 0x1f, 0x0e, 0xf7, 0x56, 0xf7, + 0x72, 0x15, 0xeb, 0x06, 0xb5, 0x7c, 0xe7, 0xfb, 0x02, 0xbd, 0x2a, 0x08, + 0xda, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9b, 0x7f, 0x94, 0x81, 0x92, 0x80, 0x8d, + 0x72, 0x8b, 0x08, 0x7e, 0x06, 0x61, 0xce, 0x66, 0xb9, 0x5c, 0xb4, 0xd4, + 0xb3, 0xae, 0xbb, 0x8b, 0xca, 0x08, 0xf4, 0x31, 0xd4, 0xfb, 0x16, 0x1e, + 0xfb, 0x73, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, + 0x89, 0xa4, 0x8b, 0x08, 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, 0x82, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, + 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0x2a, + 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, + 0x8b, 0x08, 0x68, 0xf7, 0x0e, 0x06, 0xef, 0x04, 0xf7, 0x35, 0xf7, 0x04, + 0x07, 0xcb, 0xb9, 0x6b, 0x60, 0x59, 0x4d, 0x67, 0x37, 0x1f, 0x3f, 0x06, + 0x0e, 0xf8, 0x99, 0xf8, 0xa7, 0x15, 0x8b, 0xa5, 0x8a, 0x93, 0x85, 0x94, + 0x83, 0x99, 0x7a, 0x94, 0x7a, 0x8b, 0x77, 0x8b, 0x82, 0x83, 0x81, 0x72, + 0x68, 0xa1, 0x5f, 0x96, 0x58, 0x8b, 0xfb, 0x10, 0x8b, 0x2e, 0x3f, 0x8b, + 0x26, 0x8b, 0x52, 0xaa, 0x56, 0xbe, 0x6e, 0x08, 0xab, 0x79, 0xab, 0x81, + 0xcc, 0x80, 0xcf, 0x7f, 0x9b, 0x87, 0xa0, 0x80, 0xa1, 0x7f, 0x99, 0x77, + 0x8b, 0x76, 0x8b, 0x60, 0x51, 0x6a, 0x41, 0x8b, 0x49, 0x8b, 0x4c, 0xa8, + 0x81, 0xaf, 0x83, 0xa6, 0x8b, 0x8b, 0x84, 0x92, 0x08, 0x82, 0x94, 0x7e, + 0x90, 0x7d, 0x8b, 0x7b, 0x8b, 0x7c, 0x84, 0x81, 0x7e, 0x84, 0x81, 0x89, + 0x80, 0x8b, 0x72, 0x08, 0x49, 0x07, 0x5e, 0x9b, 0x76, 0xae, 0x1e, 0x9b, + 0x8b, 0x92, 0x8f, 0x9c, 0x9f, 0xbc, 0x71, 0xc0, 0x7e, 0xc1, 0x8b, 0xf7, + 0x1d, 0x8b, 0xe7, 0xd1, 0x8b, 0xf3, 0x8b, 0xbf, 0x78, 0xb4, 0x63, 0xab, + 0x6c, 0xa4, 0x65, 0x99, 0x34, 0x9b, 0x40, 0x99, 0x86, 0x8d, 0x77, 0x95, + 0x08, 0x75, 0x96, 0x7c, 0xa2, 0x8b, 0xa0, 0x8b, 0xb6, 0xbd, 0xac, 0xca, + 0x8b, 0xc9, 0x8b, 0xbb, 0x70, 0x94, 0x63, 0x92, 0x6b, 0x8b, 0x8b, 0x92, + 0x83, 0x93, 0x83, 0x99, 0x85, 0x99, 0x8b, 0x9a, 0x8b, 0x9a, 0x93, 0x95, + 0x98, 0x08, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa7, 0x08, 0xe3, 0x07, 0x0e, + 0xf7, 0xf1, 0xf8, 0x77, 0x15, 0xf7, 0x01, 0x2e, 0x06, 0x8b, 0x74, 0x8d, + 0x81, 0x90, 0x82, 0x94, 0x7d, 0x9c, 0x81, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, + 0x93, 0x95, 0x98, 0x93, 0x95, 0x8c, 0x92, 0x8b, 0xa7, 0x08, 0xf7, 0x55, + 0xfc, 0x98, 0xfb, 0x55, 0x07, 0x8b, 0x74, 0x8d, 0x81, 0x90, 0x82, 0x94, + 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, + 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0xe8, 0xf6, 0xfc, 0x13, 0x4a, 0x07, + 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, 0xa2, 0x8b, + 0x08, 0xf7, 0x7b, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x49, 0xf8, 0x13, 0x06, 0x0e, 0xf8, 0xa5, + 0xf8, 0x77, 0x15, 0xb3, 0xa0, 0x9d, 0xab, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, + 0x7e, 0x95, 0x80, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x16, 0x06, + 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x95, 0x89, 0xa5, 0x8b, + 0x08, 0xae, 0xfb, 0xb3, 0x06, 0x4e, 0x51, 0x5a, 0x44, 0x44, 0x51, 0xbc, + 0xc8, 0x1e, 0xf7, 0xb3, 0xae, 0x07, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, + 0x80, 0x93, 0x84, 0x8c, 0x6f, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x72, 0x8b, + 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x6b, + 0xa0, 0x7a, 0xb3, 0x8a, 0x08, 0xfb, 0xaa, 0x07, 0x8b, 0x44, 0xa7, 0x53, + 0xc3, 0x60, 0xb6, 0x6a, 0xbb, 0x7b, 0xc1, 0x8b, 0xc2, 0x8b, 0xba, 0x9b, + 0xb6, 0xac, 0xc4, 0xb6, 0xa6, 0xc3, 0x8b, 0xd2, 0x08, 0xf7, 0xaa, 0x07, + 0x0e, 0xf7, 0xc3, 0xf7, 0x24, 0x15, 0xfb, 0x24, 0xf7, 0xe7, 0x9e, 0x8b, + 0x05, 0xa3, 0x8b, 0x94, 0x8d, 0x94, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, + 0x8b, 0x08, 0xfb, 0x19, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x77, 0x99, 0x77, 0x9c, 0x85, 0x94, + 0x88, 0x93, 0x8a, 0x9f, 0x8b, 0x08, 0xf7, 0x5e, 0xfc, 0x77, 0xee, 0x8b, + 0xf7, 0x61, 0xf8, 0x77, 0x05, 0xa0, 0x8b, 0x92, 0x8c, 0x94, 0x8e, 0x9c, + 0x91, 0x99, 0x9f, 0x8b, 0x9f, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x82, + 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0xfb, 0x18, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, + 0x7c, 0x97, 0x81, 0x96, 0x84, 0x93, 0x89, 0xa6, 0x8b, 0x08, 0xa3, 0x8b, + 0xfb, 0x24, 0xfb, 0xe7, 0x05, 0x0e, 0xf7, 0xc0, 0xf7, 0xa9, 0x15, 0xe8, + 0xfb, 0xa9, 0xf7, 0x02, 0x8b, 0xc7, 0xf8, 0x77, 0x05, 0xa9, 0x90, 0x9c, + 0x9d, 0x8b, 0xa6, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, + 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x17, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xc0, 0x8b, 0x68, 0xfb, + 0xa4, 0x3f, 0xf7, 0x76, 0x23, 0x8b, 0x3f, 0xfb, 0x76, 0x67, 0xf7, 0xa4, + 0xbb, 0x8b, 0x05, 0xa3, 0x8b, 0x95, 0x8d, 0x94, 0x90, 0x9a, 0x94, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, + 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x17, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x78, 0x8b, 0x6f, 0x9b, 0x7b, 0xa9, + 0x87, 0x08, 0xc9, 0xfc, 0x77, 0xf7, 0x03, 0x8b, 0xe6, 0xf7, 0xa9, 0x05, + 0x0e, 0xf8, 0x00, 0xf7, 0xbd, 0x15, 0xf7, 0x31, 0xf7, 0x4e, 0x05, 0xae, + 0x8c, 0xa1, 0x9d, 0x8b, 0xaa, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x31, 0x06, 0x75, 0x8b, 0x7b, 0x88, + 0x83, 0x84, 0x7e, 0x82, 0x83, 0x7b, 0x8b, 0x7c, 0x8b, 0x75, 0x95, 0x7e, + 0xa7, 0x7d, 0x08, 0x2e, 0xfb, 0x01, 0x2c, 0xf7, 0x01, 0x05, 0xa8, 0x99, + 0x94, 0x98, 0x8b, 0xa1, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x6f, 0x8b, 0x08, 0x30, 0x06, 0x84, 0x8b, 0x8a, 0x8b, 0x7f, + 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x8b, 0x6d, 0xa0, 0x79, 0xb0, + 0x89, 0x08, 0xf7, 0x32, 0xfb, 0x4d, 0xfb, 0x3a, 0xfb, 0x5a, 0x05, 0x66, + 0x75, 0x78, 0x6c, 0x1f, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x85, + 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x03, 0x06, 0xa0, 0x8b, 0x98, 0x8d, + 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0xa9, 0x77, 0x9d, + 0x69, 0x8d, 0x08, 0xf1, 0xf7, 0x0c, 0xf0, 0xfb, 0x0c, 0x05, 0x68, 0x89, + 0x77, 0x79, 0x8b, 0x6d, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x03, + 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0xaa, 0x76, 0x9d, 0x65, 0x8c, 0x08, 0xfb, 0x3b, 0xf7, 0x59, + 0x05, 0x0e, 0xf7, 0xf2, 0xf7, 0x89, 0x15, 0xf7, 0x38, 0xf7, 0x82, 0x8d, + 0x8b, 0x05, 0xae, 0x87, 0xa7, 0xa2, 0x8b, 0xaa, 0x8b, 0x9b, 0x84, 0x9a, + 0x7d, 0x95, 0x82, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x2f, 0x06, 0x72, + 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x74, 0x98, 0x7b, 0xa6, 0x81, 0x08, 0x2d, 0xfb, 0x1c, 0x2c, 0xf7, 0x1c, + 0x05, 0xa5, 0x96, 0x97, 0x9a, 0x8b, 0xa2, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, + 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x32, 0x06, 0x83, 0x8b, + 0x8a, 0x8b, 0x7f, 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x08, 0x6b, + 0xa2, 0x79, 0xb4, 0x1e, 0xf7, 0x39, 0xfb, 0x82, 0x8b, 0xfb, 0x25, 0x4a, + 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, + 0xa3, 0x8b, 0x08, 0xf7, 0x7a, 0x06, 0xa0, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, + 0x81, 0x92, 0x83, 0x8d, 0x6f, 0x8b, 0x08, 0x4a, 0xf7, 0x25, 0x06, 0x0e, + 0xf7, 0x5d, 0xef, 0x15, 0xf7, 0xc3, 0xf8, 0x16, 0x8b, 0xec, 0xfc, 0x2c, + 0x8b, 0x8b, 0xfb, 0x3e, 0x05, 0x8b, 0x72, 0x8d, 0x83, 0x90, 0x82, 0x95, + 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, + 0x94, 0x8d, 0x94, 0x8b, 0xa6, 0x08, 0xd1, 0xf7, 0x47, 0x07, 0xfb, 0xc2, + 0xfc, 0x13, 0x8b, 0x27, 0xf8, 0x5a, 0x8b, 0x8b, 0xf7, 0x40, 0x05, 0x8b, + 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, + 0x8b, 0x7c, 0x83, 0x81, 0x7f, 0x84, 0x81, 0x89, 0x80, 0x8b, 0x72, 0x08, + 0x43, 0xfb, 0x76, 0x07, 0x0e, 0xf7, 0xf2, 0xf8, 0xa3, 0x15, 0xc5, 0x06, + 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, 0x80, 0x92, 0x83, 0x8d, 0x70, 0x8b, + 0x08, 0xfb, 0x32, 0xfd, 0x9b, 0xf7, 0x33, 0x06, 0xa1, 0x8b, 0x97, 0x8d, + 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, + 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x50, 0xf8, 0xd3, + 0x06, 0x0e, 0xf7, 0x4c, 0xf9, 0x1f, 0x15, 0x7c, 0xad, 0x7e, 0x95, 0x74, + 0x8b, 0x70, 0x8b, 0x74, 0x74, 0x8b, 0x72, 0x8b, 0x80, 0x8d, 0x85, 0x95, + 0x77, 0x08, 0xf7, 0xd4, 0xfd, 0x3b, 0x05, 0x9b, 0x69, 0x97, 0x81, 0xa3, + 0x8b, 0xa5, 0x8b, 0xa3, 0xa2, 0x8b, 0xa4, 0x8b, 0x95, 0x88, 0x95, 0x82, + 0x9d, 0x08, 0xfb, 0xd5, 0xf9, 0x3a, 0x05, 0x0e, 0xf7, 0x8e, 0x5b, 0x15, + 0x51, 0x06, 0x75, 0x8b, 0x7f, 0x89, 0x83, 0x86, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x92, 0x7c, 0x98, 0x81, 0x96, 0x84, 0x93, 0x89, + 0xa6, 0x8b, 0x08, 0xf7, 0x32, 0xf9, 0x9b, 0xfb, 0x33, 0x06, 0x75, 0x8b, + 0x7f, 0x89, 0x83, 0x86, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x81, 0x95, 0x84, 0x93, 0x89, 0xa6, 0x8b, 0x08, 0xc6, + 0xfc, 0xd3, 0x06, 0x0e, 0xf7, 0xbf, 0xf8, 0x82, 0x15, 0xf7, 0x0b, 0xfb, + 0x1f, 0x05, 0xa0, 0x72, 0x94, 0x86, 0x9e, 0x8b, 0xa6, 0x8b, 0xa2, 0xa2, + 0x8b, 0xa6, 0x8b, 0x9a, 0x87, 0x93, 0x79, 0xa0, 0x08, 0xfb, 0x58, 0xf7, + 0x7d, 0xfb, 0x56, 0xfb, 0x7d, 0x05, 0x79, 0x76, 0x87, 0x83, 0x8b, 0x7c, + 0x8b, 0x70, 0xa2, 0x74, 0xa6, 0x8b, 0x9f, 0x8b, 0x92, 0x90, 0xa1, 0xa5, + 0x08, 0xf7, 0x09, 0xf7, 0x1e, 0x05, 0x0e, 0xf8, 0xf8, 0x40, 0x15, 0xfd, + 0x04, 0x59, 0xf9, 0x04, 0xbd, 0x06, 0x0e, 0xf8, 0x11, 0xf8, 0xee, 0x15, + 0xfb, 0x18, 0x8b, 0xf7, 0x21, 0xfb, 0x7a, 0x05, 0x96, 0x79, 0x93, 0x85, + 0x98, 0x8b, 0x9b, 0x8b, 0x9a, 0x98, 0x8b, 0x9a, 0x8b, 0x90, 0x89, 0x94, + 0x8a, 0x90, 0x08, 0x46, 0xf7, 0x63, 0x05, 0x0e, 0xf8, 0x18, 0x16, 0xf7, + 0x09, 0x06, 0xa0, 0x8b, 0x99, 0x8d, 0x92, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, + 0x70, 0x8b, 0x08, 0x7b, 0xf7, 0x5e, 0x06, 0xe8, 0x41, 0xc2, 0xfb, 0x0f, + 0x1e, 0x59, 0x8b, 0x41, 0x7e, 0x5b, 0x7a, 0x77, 0x84, 0x81, 0x7d, 0x8b, + 0x76, 0x8b, 0x6e, 0xa0, 0x75, 0xa7, 0x8b, 0x94, 0x8b, 0x99, 0x8d, 0x9c, + 0x8f, 0xb9, 0x97, 0xb0, 0x90, 0xac, 0x8b, 0x08, 0xcb, 0xa8, 0x7c, 0x69, + 0x1f, 0x74, 0x07, 0x62, 0x92, 0x6c, 0x8e, 0x6b, 0x8b, 0x32, 0x8b, 0x46, + 0x71, 0x5e, 0x59, 0x73, 0x70, 0x7c, 0x68, 0x8b, 0x6c, 0x08, 0x41, 0xdc, + 0x4e, 0xee, 0x1e, 0xc6, 0x8b, 0xc6, 0x99, 0xbb, 0xa4, 0x08, 0x74, 0x07, + 0x8c, 0xf7, 0x1b, 0x15, 0x54, 0x69, 0x53, 0x7a, 0x55, 0x8b, 0x08, 0x60, + 0x6a, 0x9c, 0xa1, 0xb1, 0xc9, 0xae, 0xcf, 0x1f, 0xad, 0x8b, 0xb0, 0x87, + 0xb3, 0x84, 0x08, 0x59, 0x07, 0x0e, 0xf7, 0x42, 0xf9, 0x04, 0x15, 0xfb, + 0x08, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x97, 0x81, 0x95, 0x84, 0x95, 0x89, + 0xa5, 0x8b, 0x08, 0x9b, 0xfc, 0x3c, 0x7b, 0x06, 0x72, 0x8b, 0x83, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x97, 0x81, 0x94, 0x85, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x08, 0xae, + 0x06, 0xbf, 0x67, 0xb3, 0x7e, 0xc6, 0x8b, 0xd5, 0x8b, 0xc3, 0xa0, 0xb9, + 0xb7, 0xb9, 0xb8, 0xa3, 0xc4, 0x8b, 0xcc, 0x8b, 0xcd, 0x73, 0xc5, 0x5d, + 0xb7, 0x5d, 0xb7, 0x53, 0xa0, 0x40, 0x8b, 0x4f, 0x8b, 0x5c, 0x7b, 0x60, + 0x69, 0x08, 0xf7, 0x73, 0x07, 0xf7, 0x29, 0xfb, 0xa5, 0x15, 0xbb, 0x8b, + 0xab, 0x7f, 0xa8, 0x6f, 0xa3, 0x72, 0x9a, 0x69, 0x8b, 0x6a, 0x8b, 0x69, + 0x7d, 0x69, 0x72, 0x72, 0x6f, 0x70, 0x69, 0x7e, 0x5c, 0x8b, 0x33, 0x8b, + 0x4e, 0xc2, 0x8b, 0xda, 0x8b, 0xac, 0x99, 0xac, 0xa4, 0xa4, 0x08, 0xa7, + 0xa7, 0xac, 0x97, 0xbc, 0x8b, 0x08, 0x0e, 0xf8, 0xb0, 0xf8, 0x14, 0x15, + 0xb9, 0x7c, 0x9f, 0x6a, 0x1e, 0x76, 0x8b, 0x80, 0x82, 0x85, 0x76, 0x64, + 0x9f, 0x5b, 0x95, 0x52, 0x8b, 0xfb, 0x2b, 0x8b, 0x22, 0x27, 0x8b, 0xfb, + 0x23, 0x8b, 0x4e, 0xa0, 0x56, 0xb3, 0x63, 0xbc, 0x5b, 0xc9, 0x76, 0xec, + 0x8b, 0xd4, 0x8b, 0xcb, 0x97, 0xb4, 0x9f, 0x08, 0xb4, 0xa0, 0xa2, 0xa5, + 0x8b, 0xa5, 0x8b, 0xa7, 0x74, 0xa2, 0x70, 0x8b, 0x7f, 0x8b, 0x82, 0x87, + 0x82, 0x83, 0x71, 0x76, 0x86, 0x87, 0x78, 0x85, 0x73, 0x83, 0x62, 0x86, + 0x63, 0x8b, 0xfb, 0x09, 0x8b, 0x50, 0xb4, 0x8b, 0xdd, 0x08, 0x8b, 0xb1, + 0x99, 0xaf, 0xa5, 0xa5, 0xa7, 0xa8, 0xb0, 0x99, 0xbe, 0x8b, 0xb7, 0x8b, + 0xaf, 0x82, 0xa5, 0x7b, 0x98, 0x82, 0x91, 0x82, 0x8f, 0x79, 0x90, 0x75, + 0x8d, 0x85, 0x93, 0x85, 0x93, 0x83, 0x9a, 0x85, 0x98, 0x8b, 0x08, 0x9b, + 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x94, 0x8d, 0x95, 0x8b, 0xa5, 0x08, + 0xd8, 0x07, 0x0e, 0xf8, 0xa7, 0xf9, 0x04, 0x15, 0xfb, 0x08, 0x06, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7b, 0x8b, + 0x7b, 0x93, 0x7c, 0x97, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, + 0x9b, 0xfb, 0x10, 0x06, 0x60, 0xad, 0x5c, 0x9b, 0x4f, 0x8b, 0x3f, 0x8b, + 0x53, 0x76, 0x5d, 0x5f, 0x5d, 0x5f, 0x73, 0x51, 0x8b, 0x4a, 0x8b, 0x49, + 0xa3, 0x52, 0xb9, 0x5e, 0xb9, 0x5f, 0xc3, 0x76, 0xd6, 0x8b, 0xc6, 0x8b, + 0xb2, 0x98, 0xc0, 0xaf, 0x08, 0x68, 0xf7, 0x08, 0x07, 0xa2, 0x8b, 0x96, + 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x7b, 0x06, + 0xf8, 0xa0, 0x07, 0xfb, 0x8e, 0xfb, 0xa5, 0x15, 0xbd, 0x8b, 0xab, 0x7f, + 0xa8, 0x6f, 0xa4, 0x72, 0x99, 0x6a, 0x8b, 0x67, 0x8b, 0x6b, 0x7d, 0x69, + 0x72, 0x72, 0x08, 0x6f, 0x70, 0x69, 0x7e, 0x5b, 0x8b, 0x5b, 0x8b, 0x69, + 0x98, 0x6f, 0xa6, 0x72, 0xa5, 0x7d, 0xac, 0x8b, 0xad, 0x8b, 0xac, 0x99, + 0xad, 0xa4, 0xa4, 0xa7, 0xa7, 0xac, 0x97, 0xbb, 0x8b, 0x08, 0x0e, 0xf8, + 0xba, 0xf7, 0x40, 0x15, 0xb2, 0x07, 0xf7, 0x1e, 0xfb, 0x02, 0xf0, 0xfb, + 0x29, 0xfb, 0x26, 0xfb, 0x04, 0x25, 0xfb, 0x18, 0xfb, 0x1c, 0xf7, 0x01, + 0x2b, 0xf7, 0x2f, 0x1e, 0xd2, 0x8b, 0xf1, 0x9d, 0xb8, 0x9f, 0xa3, 0x96, + 0x96, 0x99, 0x8b, 0x9f, 0x8b, 0xa7, 0x76, 0xa1, 0x70, 0x8b, 0x82, 0x8b, + 0x7f, 0x89, 0x7f, 0x88, 0x2f, 0x73, 0x72, 0x87, 0x5d, 0x8b, 0x33, 0x8b, + 0x56, 0xa7, 0x74, 0xc7, 0x08, 0xf8, 0x2c, 0x06, 0xfc, 0x29, 0xe3, 0x15, + 0x9a, 0xc1, 0xc6, 0xaf, 0xd4, 0x8b, 0xd4, 0x8b, 0xc5, 0x68, 0x9b, 0x54, + 0x08, 0xfb, 0xba, 0x06, 0x0e, 0xf7, 0xbf, 0xf7, 0xe5, 0x15, 0xf7, 0x2b, + 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, + 0x8b, 0x08, 0xfb, 0x2b, 0xb0, 0x06, 0xac, 0xa6, 0x9b, 0xc4, 0x1e, 0xaa, + 0x8b, 0xbb, 0x86, 0xad, 0x85, 0x97, 0x89, 0x95, 0x8a, 0x91, 0x8b, 0xa5, + 0x8b, 0xa0, 0xa1, 0x8b, 0xa8, 0x8b, 0xa2, 0x7c, 0x9c, 0x70, 0x92, 0x6b, + 0x94, 0x4c, 0x92, 0x61, 0x8b, 0x08, 0xfb, 0x0b, 0x41, 0x52, 0x2f, 0x1f, + 0x66, 0x5d, 0x07, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x97, + 0x89, 0xa3, 0x8b, 0x08, 0xba, 0xfb, 0x81, 0x51, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, + 0x7b, 0x97, 0x82, 0x94, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0xbd, + 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, + 0x8b, 0x08, 0xfb, 0x1f, 0xf7, 0x81, 0x06, 0x0e, 0xf8, 0x2e, 0xf8, 0x25, + 0x15, 0x64, 0xac, 0x5b, 0x9c, 0x55, 0x8b, 0x08, 0xfb, 0x1a, 0x25, 0x27, + 0xfb, 0x19, 0xfb, 0x18, 0xf1, 0x27, 0xf7, 0x1a, 0x1f, 0xbf, 0x8b, 0xb6, + 0x9a, 0xb9, 0xad, 0x08, 0x54, 0x07, 0x57, 0x66, 0x6a, 0x52, 0x1e, 0xfb, + 0x01, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x96, 0x89, + 0xa4, 0x8b, 0x08, 0xf7, 0x04, 0x06, 0xf7, 0x01, 0xdd, 0xda, 0xf5, 0x1f, + 0xf7, 0xf9, 0x9b, 0x07, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x08, 0x81, + 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x08, 0x06, 0x67, 0x07, 0xfb, + 0x1f, 0x59, 0x15, 0xd9, 0xc8, 0x50, 0x40, 0x43, 0x4c, 0x50, 0x3f, 0x3f, + 0x4d, 0xc6, 0xd5, 0x1f, 0xd4, 0xc9, 0xc6, 0xd7, 0x1e, 0x0e, 0xf7, 0x57, + 0xf9, 0x04, 0x15, 0xfb, 0x08, 0x06, 0x73, 0x8b, 0x82, 0x89, 0x82, 0x86, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x97, 0x81, + 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0x9b, 0xfc, 0x3c, 0x85, 0x06, + 0x72, 0x8b, 0x83, 0x89, 0x82, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x81, 0x94, 0x85, 0x97, 0x88, 0xa3, 0x8b, + 0x08, 0xf7, 0x04, 0x06, 0xa0, 0x8b, 0x99, 0x8d, 0x93, 0x90, 0x9a, 0x95, + 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x6f, 0x8b, 0x08, 0x85, 0xf7, 0x4b, 0x06, 0xc4, 0xc2, 0xa1, + 0x97, 0xba, 0x8b, 0xaa, 0x8b, 0x9e, 0x86, 0x9c, 0x7d, 0x9c, 0x7d, 0x8f, + 0x7f, 0x8b, 0x69, 0x08, 0xfb, 0x3f, 0x85, 0x07, 0x72, 0x8b, 0x82, 0x89, + 0x82, 0x86, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x98, 0x81, 0x94, 0x85, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x04, 0x06, + 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, + 0x08, 0x85, 0xf7, 0x4c, 0x06, 0xef, 0x44, 0xcd, 0x21, 0x1e, 0x57, 0x8b, + 0x5e, 0x77, 0x63, 0x62, 0x08, 0xf7, 0x7f, 0x07, 0x0e, 0xf7, 0xf2, 0xf8, + 0x49, 0x15, 0xfb, 0x46, 0x06, 0x71, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x83, 0x97, 0x89, 0xa4, 0x8b, 0x08, 0xd9, 0xfb, 0x81, 0xfb, 0x0e, 0x06, + 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, + 0x08, 0xf7, 0xec, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, + 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x0e, 0x06, 0xf7, 0xe5, 0x07, 0x7d, + 0xf7, 0x4e, 0x15, 0xfb, 0x0a, 0x22, 0xf7, 0x0a, 0x06, 0xf4, 0x07, 0x0e, + 0xf8, 0x18, 0xf7, 0xe5, 0x15, 0xfb, 0xf9, 0x07, 0x57, 0x66, 0x6a, 0x52, + 0x1e, 0xfb, 0x03, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7d, 0x82, + 0x81, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, + 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf7, 0x06, 0x06, 0xf7, 0x01, 0xdd, 0xdb, + 0xf4, 0x1f, 0xf8, 0x5d, 0xfb, 0xc2, 0x07, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, + 0x82, 0x94, 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf7, 0x5e, 0x06, 0xb5, + 0xf7, 0xb2, 0x15, 0xfb, 0x0b, 0x22, 0xf7, 0x0b, 0x06, 0xf4, 0x07, 0x0e, + 0xf7, 0x6b, 0xf7, 0x38, 0x15, 0x9d, 0x99, 0xf2, 0x30, 0x05, 0x7f, 0x7e, + 0x87, 0x81, 0x8b, 0x7d, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x0a, + 0x06, 0xa1, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x6f, + 0x8b, 0x08, 0x6a, 0x8b, 0xfb, 0x34, 0xf7, 0x21, 0xf7, 0x0a, 0xeb, 0xa7, + 0x8b, 0x05, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, + 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x80, 0x8d, + 0x72, 0x8b, 0x08, 0xfb, 0x04, 0x06, 0x73, 0x8b, 0x80, 0x89, 0x83, 0x86, + 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7d, 0x8f, 0x82, 0x97, 0x7d, + 0x08, 0x3c, 0x4c, 0x8b, 0xf7, 0xe5, 0xfb, 0x08, 0x8b, 0x05, 0x73, 0x8b, + 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x97, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0x9b, + 0xfc, 0x3c, 0x7b, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x08, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, + 0x08, 0x06, 0xf7, 0x38, 0x07, 0x0e, 0xf7, 0xf2, 0xf9, 0x04, 0x15, 0xfb, + 0x46, 0x06, 0x72, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7b, + 0x8b, 0x79, 0x8b, 0x7b, 0x92, 0x7c, 0x99, 0x82, 0x94, 0x83, 0x97, 0x89, + 0xa4, 0x8b, 0x08, 0xd9, 0xfc, 0x3c, 0xfb, 0x0e, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, + 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0xec, + 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, + 0x8b, 0x08, 0xfb, 0x0e, 0xf8, 0xa0, 0x06, 0x0e, 0xf7, 0x21, 0xf8, 0x49, + 0x15, 0x2e, 0x06, 0x83, 0x8b, 0x89, 0x8b, 0x80, 0x89, 0x6e, 0x88, 0x7a, + 0x78, 0x8b, 0x71, 0x8b, 0x6c, 0xa1, 0x79, 0xb1, 0x8a, 0x08, 0xfb, 0x81, + 0x07, 0x65, 0x75, 0x79, 0x6b, 0x1f, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, + 0x94, 0x84, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xe3, 0x06, 0xa0, 0x8b, 0x98, + 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x08, 0xab, 0x75, + 0x9d, 0x64, 0x1e, 0xf7, 0x61, 0x07, 0xa9, 0xad, 0x9e, 0x96, 0xa6, 0x8b, + 0x08, 0xa4, 0x95, 0x80, 0x6f, 0x1f, 0xfb, 0xcb, 0xe9, 0x07, 0xa0, 0x8b, + 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x08, 0xaa, + 0x75, 0x9e, 0x65, 0x1e, 0xf7, 0x61, 0x07, 0xad, 0xaf, 0x9b, 0x94, 0xa5, + 0x8b, 0x08, 0xa5, 0x94, 0x81, 0x6e, 0x1f, 0xfb, 0xcb, 0xe9, 0x07, 0xb7, + 0xa1, 0x9c, 0xac, 0xab, 0x75, 0x9d, 0x65, 0x1f, 0xf7, 0x6f, 0x07, 0xd6, + 0x53, 0xc3, 0x40, 0x1e, 0x62, 0x8b, 0x6b, 0x7c, 0x6c, 0x69, 0x6d, 0xac, + 0x6a, 0x9b, 0x64, 0x8b, 0x6d, 0x8b, 0x77, 0x82, 0x68, 0x6f, 0x08, 0xa3, + 0x07, 0x0e, 0xf7, 0x57, 0xf8, 0x49, 0x15, 0x2d, 0x06, 0x83, 0x8b, 0x89, + 0x8b, 0x80, 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x8b, 0x6b, 0xa1, + 0x7a, 0xb2, 0x8a, 0x08, 0xfb, 0x81, 0x85, 0x07, 0x72, 0x8b, 0x83, 0x89, + 0x82, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, + 0x97, 0x82, 0x95, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x04, 0x06, + 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, + 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, + 0x08, 0x85, 0xf7, 0x4a, 0x06, 0xba, 0xbe, 0xab, 0x9c, 0xb9, 0x8b, 0x08, + 0xc9, 0xa7, 0x74, 0x5a, 0x1f, 0xfb, 0x46, 0x07, 0x64, 0x75, 0x79, 0x6b, + 0x6a, 0xa1, 0x7a, 0xb8, 0x1f, 0xe4, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, + 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, + 0x1e, 0xf7, 0x4a, 0x07, 0x8b, 0xc6, 0x78, 0xb5, 0x63, 0xa9, 0x6a, 0xa3, + 0x62, 0x98, 0x5e, 0x8b, 0x54, 0x8b, 0x69, 0x7c, 0x5b, 0x5d, 0x08, 0xbb, + 0x07, 0x0e, 0xf7, 0xc3, 0xf8, 0x56, 0x15, 0xfb, 0x28, 0xfb, 0x05, 0x26, + 0xfb, 0x18, 0xfb, 0x16, 0xf7, 0x06, 0x24, 0xf7, 0x24, 0xf7, 0x24, 0xf7, + 0x06, 0xf2, 0xf7, 0x16, 0xf7, 0x15, 0xfb, 0x06, 0xf3, 0xfb, 0x21, 0x1f, + 0x8a, 0x27, 0x15, 0xe2, 0xd0, 0x50, 0x41, 0x40, 0x46, 0x51, 0x32, 0x32, + 0x46, 0xc5, 0xd6, 0xd7, 0xd0, 0xc4, 0xe6, 0x1f, 0x0e, 0xf7, 0x42, 0xcd, + 0x15, 0xbf, 0x63, 0xb7, 0x7b, 0xc6, 0x8b, 0x08, 0xf7, 0x1f, 0xf2, 0xe6, + 0xf7, 0x0f, 0xf7, 0x15, 0x23, 0xec, 0xfb, 0x20, 0x1f, 0x4d, 0x8b, 0x61, + 0x7b, 0x5a, 0x61, 0x08, 0xb8, 0xfb, 0x08, 0x07, 0x73, 0x8b, 0x82, 0x89, + 0x82, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x97, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0x9b, 0xfc, 0x4e, + 0x7b, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x97, 0x82, 0x95, 0x83, 0x96, 0x89, + 0xa4, 0x8b, 0x08, 0xf7, 0x42, 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, + 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, + 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x51, 0x06, 0xf7, 0x3f, 0x07, + 0xf7, 0x29, 0xf7, 0xb0, 0x15, 0xb4, 0x8b, 0xac, 0x82, 0xa5, 0x77, 0xa8, + 0x76, 0x9e, 0x66, 0x8b, 0x6a, 0x08, 0x45, 0x4d, 0x59, 0x35, 0x33, 0x4e, + 0xbd, 0xd2, 0x1e, 0x8b, 0xab, 0x9e, 0xb0, 0xa8, 0xa0, 0x08, 0xa5, 0x9f, + 0xac, 0x94, 0xb5, 0x8b, 0x08, 0x0e, 0xf8, 0x43, 0x22, 0x15, 0x51, 0x06, + 0x73, 0x8b, 0x81, 0x89, 0x83, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7b, 0x92, 0x7d, 0x98, 0x81, 0x95, 0x83, 0x96, 0x89, 0xa4, 0x8b, + 0x08, 0xf7, 0x42, 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x95, + 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, + 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x7b, 0xf8, 0x4e, 0x9b, 0x06, 0xa2, 0x8b, + 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0xfb, + 0x08, 0x5e, 0x06, 0x5a, 0xb5, 0x61, 0x9b, 0x4c, 0x8b, 0x08, 0xfb, 0x20, + 0x23, 0x2b, 0xfb, 0x16, 0xfb, 0x0f, 0xf2, 0x30, 0xf7, 0x1f, 0x1f, 0xc6, + 0x8b, 0xb8, 0x9b, 0xbf, 0xb3, 0x08, 0xfb, 0x3f, 0x07, 0xfb, 0x2a, 0xf8, + 0x5b, 0x15, 0xe4, 0xc8, 0x59, 0x44, 0x1f, 0x8b, 0x6b, 0x78, 0x67, 0x6e, + 0x75, 0x72, 0x78, 0x69, 0x81, 0x61, 0x8b, 0x61, 0x8b, 0x69, 0x95, 0x72, + 0x9e, 0x6e, 0xa1, 0x78, 0xaf, 0x8b, 0xac, 0x8b, 0xac, 0x9e, 0xaf, 0xa8, + 0xa1, 0xa5, 0x9e, 0xac, 0x95, 0xb4, 0x8b, 0x08, 0x0e, 0xf7, 0xaa, 0xf8, + 0x49, 0x15, 0xfb, 0x1b, 0x06, 0x7a, 0x8b, 0x78, 0x88, 0x85, 0x86, 0x7c, + 0x82, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0x81, 0x51, 0x06, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7c, 0x93, 0x7b, 0x97, 0x82, 0x94, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, + 0xf7, 0xbd, 0x06, 0xa0, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, + 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x1f, 0xf7, 0x27, 0x06, 0xea, 0xd9, 0xb1, + 0xa3, 0xab, 0x8b, 0x99, 0x8b, 0x95, 0x86, 0x9a, 0x7e, 0x9a, 0x7e, 0x95, + 0x86, 0x99, 0x8b, 0xa6, 0x8b, 0xa2, 0xa2, 0x8b, 0xa7, 0x8b, 0x9d, 0x84, + 0x97, 0x76, 0x9c, 0x6c, 0xa5, 0x6b, 0x97, 0x68, 0x8b, 0x08, 0x5a, 0x8b, + 0x65, 0x7a, 0x3b, 0x4f, 0x08, 0xcc, 0x07, 0x0e, 0xf8, 0x2d, 0xf7, 0xcc, + 0x15, 0x97, 0x75, 0x99, 0x82, 0xa0, 0x8b, 0x9a, 0x8b, 0x9b, 0x93, 0x95, + 0x97, 0x92, 0x95, 0x8d, 0x95, 0x8b, 0xa5, 0x08, 0xb0, 0x07, 0xb9, 0x7c, + 0x9f, 0x6b, 0x1e, 0x7c, 0x8b, 0x82, 0x84, 0x83, 0x78, 0x64, 0x9d, 0x62, + 0x93, 0x5a, 0x8b, 0xfb, 0x0c, 0x8b, 0x35, 0x52, 0x8b, 0x3b, 0x8b, 0x3c, + 0xc6, 0x63, 0xf7, 0x20, 0x7c, 0xc1, 0x85, 0xa0, 0x87, 0x9c, 0x84, 0xa0, + 0x83, 0x98, 0x7d, 0x8b, 0x7e, 0x08, 0x74, 0x56, 0x77, 0x4b, 0x1e, 0x55, + 0x8b, 0x61, 0x98, 0x6e, 0xa5, 0x82, 0xa9, 0x7b, 0x99, 0x71, 0x8b, 0x7a, + 0x8b, 0x7d, 0x84, 0x81, 0x7d, 0x83, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, + 0x6a, 0x07, 0x8b, 0x73, 0x8d, 0x82, 0x90, 0x82, 0x95, 0x7b, 0x9b, 0x83, + 0x9d, 0x8b, 0x98, 0x8b, 0x93, 0x8e, 0x96, 0x94, 0xb3, 0x78, 0xbe, 0x81, + 0xc4, 0x8b, 0xf7, 0x15, 0x8b, 0xe9, 0xc6, 0x8b, 0xdd, 0x8b, 0xb9, 0x71, + 0xb6, 0x5f, 0xa3, 0x08, 0x6d, 0x9c, 0x63, 0x96, 0x40, 0x95, 0x4b, 0x94, + 0x85, 0x8c, 0x7d, 0x90, 0x7b, 0x91, 0x81, 0x94, 0x8b, 0x94, 0x8b, 0x9d, + 0xbb, 0x9c, 0xbe, 0x8b, 0xb5, 0x8b, 0xac, 0x82, 0xa7, 0x77, 0x08, 0x90, + 0x82, 0x05, 0x0e, 0xf7, 0x6a, 0xf7, 0xe5, 0x15, 0xf7, 0x49, 0x06, 0xa1, + 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x80, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, + 0xfb, 0x49, 0xe3, 0x06, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, + 0x7a, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x83, 0x82, 0x7f, 0x83, 0x81, + 0x89, 0x81, 0x8b, 0x71, 0x08, 0x33, 0x68, 0x07, 0x71, 0x8b, 0x84, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, + 0x97, 0x82, 0x95, 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0x6b, + 0x06, 0x36, 0xd2, 0x56, 0xf7, 0x06, 0x1e, 0xbf, 0x8b, 0xda, 0x9c, 0xbc, + 0xa2, 0xb1, 0x9c, 0x97, 0x98, 0x8b, 0xa3, 0x8b, 0xa7, 0x76, 0xa2, 0x70, + 0x8b, 0x80, 0x8b, 0x84, 0x89, 0x7a, 0x82, 0x5e, 0x74, 0x5b, 0x80, 0x56, + 0x8b, 0x65, 0x8b, 0x6f, 0x92, 0x7f, 0x98, 0x08, 0x85, 0x92, 0x89, 0x94, + 0x8b, 0xa0, 0x08, 0xf7, 0x58, 0x07, 0x0e, 0xf8, 0x92, 0xf8, 0x49, 0x15, + 0xfb, 0x1b, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, 0x96, + 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0x4a, 0x06, 0x57, 0x54, 0x72, 0x7e, + 0x59, 0x8b, 0x08, 0x4f, 0x6f, 0xa2, 0xbc, 0x1f, 0xf7, 0xaa, 0xfb, 0x08, + 0x07, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, + 0x7a, 0x8b, 0x6e, 0xa4, 0x74, 0xa9, 0x8d, 0x08, 0x96, 0x8c, 0x9b, 0x8b, + 0x8b, 0xfb, 0x4a, 0x05, 0x8b, 0x50, 0x9e, 0x60, 0xb3, 0x6d, 0xab, 0x73, + 0xb5, 0x7e, 0xb8, 0x8b, 0xc2, 0x8b, 0xab, 0x99, 0xbd, 0xba, 0x08, 0x5b, + 0xea, 0x07, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, + 0x8b, 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf7, 0xe5, 0x07, 0x0e, + 0xf7, 0xc2, 0xf7, 0x0e, 0x15, 0xfb, 0x01, 0xf7, 0x6b, 0x90, 0x8b, 0x05, + 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, + 0x08, 0xfb, 0x18, 0x06, 0x73, 0x8b, 0x82, 0x89, 0x82, 0x86, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, + 0x96, 0x89, 0xa4, 0x8b, 0x08, 0x99, 0x8b, 0xf7, 0x3b, 0xfb, 0xe5, 0xf3, + 0x8b, 0xf7, 0x3b, 0xf7, 0xe5, 0x9b, 0x8b, 0x05, 0xa2, 0x8b, 0x96, 0x8d, + 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, + 0x7f, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0xfb, 0x1b, 0x06, + 0x73, 0x8b, 0x82, 0x89, 0x82, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, + 0x08, 0x95, 0x8b, 0x20, 0xfb, 0x6b, 0x05, 0x0e, 0xf7, 0xc1, 0xf7, 0x49, + 0x15, 0xd2, 0xfb, 0x49, 0xe7, 0x8b, 0xdf, 0xf7, 0xe6, 0x05, 0xac, 0x8d, + 0x9e, 0x9d, 0x8b, 0xa8, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x82, 0x92, + 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x2e, 0x06, 0x76, 0x8b, 0x7b, 0x88, 0x83, + 0x84, 0x7e, 0x82, 0x83, 0x7b, 0x8b, 0x7c, 0x8b, 0x7c, 0x93, 0x7b, 0x98, + 0x82, 0x94, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0x92, 0x8b, 0x63, 0xfb, + 0x2d, 0x4e, 0xf7, 0x32, 0x33, 0x8b, 0x4f, 0xfb, 0x32, 0x64, 0xf7, 0x2d, + 0x05, 0xa4, 0x8b, 0x93, 0x8d, 0x93, 0x90, 0x99, 0x94, 0x94, 0x9b, 0x8b, + 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, + 0x8b, 0x08, 0x2f, 0x06, 0x83, 0x8b, 0x8a, 0x8b, 0x7f, 0x89, 0x6f, 0x88, + 0x7a, 0x79, 0x8b, 0x70, 0x8b, 0x6e, 0x9f, 0x79, 0xad, 0x89, 0x08, 0xe0, + 0xfb, 0xe6, 0xe9, 0x8b, 0xcf, 0xf7, 0x49, 0x05, 0x0e, 0xf8, 0x09, 0xf7, + 0x77, 0x15, 0xf7, 0x18, 0xf7, 0x02, 0x05, 0xad, 0x8e, 0x9e, 0x9d, 0x8b, + 0xa8, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, + 0x8b, 0x08, 0x30, 0x06, 0x83, 0x8b, 0x8a, 0x8b, 0x7f, 0x89, 0x6f, 0x88, + 0x7a, 0x79, 0x8b, 0x6f, 0x8b, 0x7a, 0x92, 0x7e, 0x9e, 0x7e, 0x08, 0x4e, + 0x59, 0x4e, 0xbc, 0x05, 0x9c, 0x96, 0x94, 0x9c, 0x8b, 0x9d, 0x8b, 0x9a, + 0x83, 0x9a, 0x7f, 0x94, 0x81, 0x93, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x2f, + 0x06, 0x83, 0x8b, 0x8a, 0x8b, 0x7f, 0x89, 0x6f, 0x88, 0x7a, 0x79, 0x8b, + 0x70, 0x8b, 0x6e, 0x9e, 0x79, 0xac, 0x88, 0x08, 0xf7, 0x14, 0xfb, 0x01, + 0xfb, 0x25, 0xfb, 0x14, 0x05, 0x69, 0x89, 0x77, 0x79, 0x8b, 0x6d, 0x08, + 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x03, 0x06, 0xb7, 0xa1, 0x9c, 0xad, + 0x1f, 0x8b, 0xa3, 0x81, 0x98, 0x6f, 0x97, 0x08, 0xd4, 0xc8, 0xd6, 0x4e, + 0x05, 0x72, 0x84, 0x7c, 0x78, 0x8b, 0x74, 0x8b, 0x7a, 0x92, 0x7d, 0x98, + 0x81, 0x95, 0x84, 0x97, 0x88, 0xa4, 0x8b, 0x08, 0xf7, 0x04, 0x06, 0xa0, + 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x99, 0x94, 0x95, 0x9c, 0x8b, 0x9c, 0x8b, + 0xa9, 0x77, 0x9d, 0x69, 0x8d, 0x08, 0xfb, 0x2c, 0xf7, 0x13, 0x05, 0x0e, + 0xf7, 0x86, 0x8e, 0x15, 0x54, 0xfb, 0x00, 0x27, 0x8b, 0x05, 0x73, 0x8b, + 0x82, 0x89, 0x82, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf7, + 0x6b, 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x81, 0x8d, + 0x71, 0x8b, 0x08, 0x86, 0x8b, 0xf7, 0x7a, 0xf8, 0x4e, 0x05, 0xac, 0x8e, + 0x9e, 0x9d, 0x8b, 0xa8, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x82, 0x92, + 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x2f, 0x06, 0x83, 0x8b, 0x89, 0x8b, 0x80, + 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x08, 0x6b, 0xa2, 0x79, 0xb4, + 0x1e, 0xfb, 0x0c, 0xfb, 0x73, 0xfb, 0x06, 0xf7, 0x73, 0x05, 0xb1, 0x8c, + 0xa0, 0x9d, 0x8b, 0xaa, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, + 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x31, 0x06, 0x84, 0x8b, 0x89, 0x8b, 0x80, + 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x8b, 0x6f, 0x9d, 0x79, 0xaa, + 0x87, 0x08, 0xf7, 0x40, 0xfb, 0xe2, 0x05, 0x0e, 0xf7, 0x88, 0xef, 0x15, + 0xf7, 0x9a, 0xf7, 0x94, 0x8b, 0xdc, 0xfc, 0x2d, 0x8b, 0x8b, 0xfb, 0x01, + 0x05, 0x8b, 0x74, 0x8d, 0x81, 0x90, 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, + 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, + 0xa6, 0x08, 0x94, 0xf7, 0x29, 0x07, 0xfb, 0x99, 0xfb, 0x92, 0x8b, 0x38, + 0xf8, 0x46, 0x8b, 0x8b, 0xe3, 0x05, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, + 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x6d, 0x8b, 0x79, 0x78, 0x89, 0x68, + 0x08, 0xfb, 0x43, 0x06, 0x0e, 0xf7, 0xf0, 0xf8, 0x79, 0x15, 0x8b, 0xa6, + 0x93, 0x94, 0xa7, 0x8c, 0xa8, 0x8d, 0x9f, 0xa0, 0x8b, 0xa7, 0x08, 0xa9, + 0x75, 0x9f, 0x69, 0x46, 0x4f, 0x4f, 0x44, 0x1e, 0xfb, 0x38, 0x07, 0x8b, + 0x70, 0x85, 0x83, 0x71, 0x88, 0x6b, 0x88, 0x7a, 0x79, 0x8b, 0x6e, 0x8b, + 0x6d, 0x9c, 0x7a, 0xab, 0x87, 0xa5, 0x88, 0x91, 0x84, 0x8b, 0x6f, 0x08, + 0xfb, 0x41, 0x07, 0x44, 0xc7, 0x4f, 0xd1, 0xac, 0xa1, 0x9f, 0xa9, 0x1e, + 0x8b, 0xa7, 0x77, 0xa0, 0x6e, 0x8d, 0x6f, 0x8d, 0x83, 0x93, 0x8b, 0xa6, + 0x08, 0xf7, 0x31, 0x07, 0x8b, 0xbf, 0x86, 0x9c, 0x73, 0xa8, 0xa2, 0xa7, + 0x91, 0x9c, 0x8b, 0xb6, 0x08, 0xf7, 0x31, 0x07, 0x0e, 0xf7, 0xf2, 0xf8, + 0xc0, 0x15, 0x8b, 0xa3, 0x89, 0x94, 0x86, 0x94, 0x82, 0x9a, 0x7a, 0x94, + 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x83, 0x81, 0x7f, 0x84, 0x81, 0x89, 0x81, + 0x8b, 0x71, 0x08, 0xfd, 0x17, 0x07, 0x8b, 0x74, 0x8d, 0x80, 0x90, 0x83, + 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, + 0x92, 0x95, 0x8d, 0x95, 0x8b, 0xa4, 0x08, 0xf9, 0x17, 0x07, 0x0e, 0xf7, + 0x90, 0x7c, 0x15, 0x8b, 0x70, 0x83, 0x82, 0x6f, 0x8a, 0x6e, 0x89, 0x77, + 0x76, 0x8b, 0x6f, 0x08, 0x6d, 0xa1, 0x77, 0xad, 0xd0, 0xc7, 0xc7, 0xd2, + 0x1e, 0xf7, 0x38, 0x07, 0x8b, 0xa6, 0x91, 0x93, 0xa5, 0x8e, 0xab, 0x8e, + 0x9c, 0x9d, 0x8b, 0xa8, 0x8b, 0xa9, 0x7a, 0x9c, 0x6b, 0x8f, 0x71, 0x8e, + 0x85, 0x92, 0x8b, 0xa7, 0x08, 0xf7, 0x41, 0x07, 0xd2, 0x4f, 0xc7, 0x45, + 0x6a, 0x75, 0x77, 0x6d, 0x1e, 0x8b, 0x6f, 0x9f, 0x76, 0xa8, 0x89, 0xa7, + 0x89, 0x93, 0x83, 0x8b, 0x70, 0x08, 0xfb, 0x31, 0x07, 0x8b, 0x57, 0x90, + 0x7a, 0xa3, 0x6e, 0x74, 0x6f, 0x85, 0x7a, 0x8b, 0x60, 0x08, 0xfb, 0x31, + 0x07, 0x0e, 0xf8, 0x7c, 0xf8, 0x00, 0x15, 0x77, 0x8b, 0x81, 0x84, 0x77, + 0x70, 0x72, 0x6a, 0x7e, 0x7e, 0x80, 0x8b, 0x82, 0x8b, 0x7f, 0x93, 0x79, + 0x9a, 0x08, 0x47, 0xca, 0x70, 0x9a, 0x61, 0x8b, 0x62, 0x8b, 0x6b, 0x79, + 0x64, 0x5e, 0x6e, 0x6b, 0x81, 0x78, 0x8b, 0x78, 0x8b, 0x70, 0xa3, 0x73, + 0xa6, 0x8b, 0x9d, 0x8b, 0x93, 0x91, 0xa5, 0xab, 0xa6, 0xac, 0x95, 0x94, + 0x95, 0x8b, 0x08, 0x93, 0x8b, 0x98, 0x82, 0xa0, 0x79, 0x08, 0xc7, 0x55, + 0xb1, 0x76, 0xb2, 0x8b, 0xb2, 0x8b, 0xa9, 0x9d, 0xb0, 0xb7, 0xac, 0xb2, + 0x93, 0x99, 0x8b, 0x9f, 0x08, 0xa6, 0x74, 0xa2, 0x70, 0x1e, 0x0e, 0xf7, + 0x72, 0xfb, 0x06, 0x15, 0x8a, 0x7f, 0x8a, 0x7d, 0x8b, 0x84, 0x08, 0x5d, + 0xad, 0x69, 0xb9, 0xba, 0xad, 0xad, 0xb9, 0x1e, 0x8b, 0x91, 0x8a, 0x99, + 0x8a, 0x98, 0x08, 0x6e, 0xf7, 0xbd, 0x05, 0x88, 0xa9, 0x78, 0x9e, 0x6f, + 0x8b, 0x6f, 0x8b, 0x79, 0x79, 0x88, 0x6c, 0x08, 0x6e, 0xfb, 0xbd, 0x05, + 0xd1, 0xf8, 0xb0, 0x15, 0x66, 0x6d, 0x6e, 0x66, 0x66, 0xa9, 0x6e, 0xb0, + 0x1f, 0x9c, 0x06, 0xb0, 0xa8, 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, + 0x7a, 0x06, 0x0e, 0xf7, 0xf3, 0xee, 0x15, 0xe3, 0x9a, 0xc7, 0xb1, 0x8b, + 0xb5, 0x8b, 0xa6, 0x73, 0xa3, 0x71, 0x8b, 0x7f, 0x8b, 0x81, 0x87, 0x7f, + 0x83, 0x69, 0x72, 0x69, 0x80, 0x66, 0x8b, 0x08, 0x43, 0x54, 0xbd, 0xca, + 0xce, 0xc5, 0xbd, 0xda, 0x1f, 0xb8, 0x8b, 0xa2, 0x7e, 0x92, 0x6d, 0x93, + 0x6d, 0x8b, 0x8b, 0x92, 0x83, 0x93, 0x84, 0x9a, 0x85, 0x97, 0x8b, 0x9b, + 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, + 0xb5, 0x07, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x81, 0x9a, 0x7b, 0x94, + 0x79, 0x8b, 0x85, 0x8b, 0x86, 0x8a, 0x82, 0x88, 0x77, 0x97, 0x75, 0x92, + 0x6c, 0x90, 0x08, 0xce, 0x07, 0x8b, 0xa5, 0x8a, 0x93, 0x85, 0x94, 0x82, + 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7d, 0x84, 0x81, 0x7d, 0x83, + 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, 0x3e, 0x07, 0x28, 0x73, 0x46, 0x37, + 0x8b, 0x2a, 0x8b, 0x24, 0xcc, 0x3a, 0xf2, 0x72, 0x08, 0x3a, 0x07, 0x8b, + 0x74, 0x8d, 0x80, 0x90, 0x83, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, + 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, + 0xd8, 0x07, 0x0e, 0xf7, 0xce, 0xf7, 0x87, 0x15, 0xa3, 0x8b, 0x95, 0x8d, + 0x94, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, + 0x7e, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x47, 0x06, 0x77, + 0xd2, 0x8b, 0x8d, 0x8b, 0xa0, 0x8b, 0xae, 0xaa, 0xa5, 0xb4, 0x8b, 0xa6, + 0x8b, 0x9f, 0x83, 0x9b, 0x79, 0xa2, 0x72, 0x90, 0x88, 0x9e, 0x8b, 0x08, + 0xa6, 0xa1, 0xa2, 0xa7, 0xbe, 0x3b, 0xbf, 0x3d, 0x26, 0x43, 0x46, 0x2a, + 0x1f, 0x8b, 0x6e, 0x90, 0x73, 0x97, 0x67, 0x08, 0x5f, 0x06, 0x72, 0x8b, + 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xd0, + 0x06, 0x8c, 0x83, 0x8b, 0x83, 0x8b, 0x88, 0x8b, 0x67, 0x85, 0x6c, 0x7e, + 0x72, 0x82, 0x78, 0x80, 0x83, 0x72, 0x86, 0x68, 0x84, 0x7c, 0x7c, 0x8b, + 0x70, 0x8b, 0x7b, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, 0xa2, + 0x8b, 0x08, 0xf7, 0xd5, 0x06, 0xd1, 0xb1, 0xab, 0xc5, 0xad, 0x77, 0xa1, + 0x6c, 0x1f, 0x6f, 0x8b, 0x7a, 0x7b, 0x87, 0x6d, 0x08, 0xfb, 0x5f, 0x06, + 0x9c, 0xb5, 0x91, 0xa9, 0x8b, 0xb7, 0x8b, 0x90, 0x8b, 0x95, 0x8a, 0x97, + 0x08, 0xb8, 0x06, 0x0e, 0xf8, 0xb3, 0xf8, 0x22, 0x15, 0xa8, 0x9e, 0x93, + 0x96, 0x8b, 0xa0, 0x8b, 0xa6, 0x74, 0xa3, 0x71, 0x8b, 0x7e, 0x8b, 0x83, + 0x88, 0x76, 0x7d, 0x08, 0xfc, 0x43, 0xfb, 0xab, 0x05, 0x6e, 0x78, 0x83, + 0x81, 0x8b, 0x76, 0x8b, 0x70, 0xa3, 0x72, 0xa4, 0x8b, 0x96, 0x8b, 0x98, + 0x90, 0x9d, 0x97, 0x08, 0xf8, 0x43, 0xf7, 0xab, 0x05, 0x0e, 0xf7, 0xc1, + 0xf7, 0xf0, 0x15, 0x2d, 0xf7, 0x1a, 0x05, 0xa2, 0x8f, 0x9b, 0x9f, 0x8b, + 0xa3, 0x8b, 0x9b, 0x84, 0x99, 0x7e, 0x95, 0x80, 0x93, 0x84, 0x8d, 0x6e, + 0x8b, 0x08, 0x2f, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x6c, 0xa6, 0x75, 0xad, 0x8e, 0x8c, 0x8b, + 0x8d, 0x8b, 0x8d, 0x8c, 0x08, 0xf7, 0x1e, 0xfb, 0x5c, 0x43, 0x8b, 0x05, + 0x76, 0x81, 0x81, 0x79, 0x79, 0x96, 0x81, 0x9f, 0x1f, 0xec, 0x69, 0x2a, + 0x06, 0x77, 0x80, 0x81, 0x79, 0x79, 0x96, 0x81, 0x9f, 0x1f, 0xec, 0x68, + 0x5d, 0x06, 0x71, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, + 0xa2, 0x8b, 0x08, 0xf7, 0x56, 0x06, 0xb7, 0xa1, 0x9c, 0xac, 0x1f, 0x8b, + 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, + 0x5c, 0xae, 0xec, 0x06, 0x9f, 0x96, 0x95, 0x9d, 0x9d, 0x80, 0x95, 0x77, + 0x1f, 0x2a, 0xad, 0xec, 0x06, 0x9f, 0x96, 0x95, 0x9d, 0x9d, 0x80, 0x95, + 0x77, 0x1f, 0x43, 0x8b, 0xf7, 0x1f, 0xf7, 0x5b, 0x8c, 0x8b, 0x05, 0x91, + 0x89, 0xa8, 0x91, 0x90, 0x8e, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, + 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x84, 0x8d, 0x6f, 0x8b, 0x08, + 0x30, 0x06, 0x71, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x73, 0x9a, 0x79, 0xa5, 0x84, 0x08, 0x2c, 0xfb, 0x19, + 0x05, 0x0e, 0xf7, 0xf6, 0xf8, 0x28, 0x15, 0xbf, 0x07, 0xb8, 0xac, 0xb0, + 0xb3, 0x1e, 0x9d, 0x8b, 0x9a, 0x88, 0x9b, 0x85, 0x97, 0x87, 0x90, 0x8a, + 0x92, 0x8b, 0x08, 0xa6, 0xa0, 0xa2, 0xa9, 0xb1, 0x5e, 0xa2, 0x40, 0x2b, + 0x3d, 0x3b, 0x28, 0x1f, 0x54, 0x52, 0x07, 0x70, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x81, 0x94, 0x84, 0x96, 0x89, 0xa5, 0x8b, 0x08, 0xc4, 0xfb, 0x82, 0x06, + 0x56, 0x6b, 0x67, 0x5d, 0x1e, 0x7b, 0x8b, 0x7b, 0x8e, 0x7b, 0x90, 0x7d, + 0x90, 0x88, 0x8c, 0x85, 0x8b, 0x08, 0x72, 0x74, 0x74, 0x70, 0x63, 0xb8, + 0x73, 0xd8, 0xee, 0xd7, 0xdd, 0xf6, 0x1f, 0xf7, 0x82, 0xc4, 0x07, 0xa2, + 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x93, 0x84, 0x8c, 0x6e, 0x8b, 0x08, + 0x52, 0x06, 0x0e, 0xf8, 0x43, 0xf8, 0x81, 0x15, 0x66, 0x07, 0x8b, 0x78, + 0x8d, 0x82, 0x8f, 0x84, 0x93, 0x7f, 0x9a, 0x83, 0x9a, 0x8b, 0x99, 0x8b, + 0x99, 0x92, 0x93, 0x96, 0x92, 0x93, 0x8c, 0x91, 0x8b, 0xa2, 0x08, 0xf7, + 0x13, 0xfb, 0x75, 0x07, 0x56, 0x8b, 0x67, 0x7d, 0x6c, 0x69, 0x70, 0x6f, + 0x7c, 0x65, 0x8b, 0x66, 0x8b, 0x7f, 0x8c, 0x85, 0x8f, 0x7f, 0x4a, 0x79, + 0x67, 0x61, 0x8b, 0x50, 0x8b, 0x52, 0xae, 0x64, 0xee, 0x52, 0x08, 0xf5, + 0x4e, 0x05, 0xd2, 0x63, 0xad, 0x6b, 0x8b, 0x71, 0x08, 0x6f, 0x6c, 0x72, + 0x67, 0x1e, 0xfb, 0x25, 0xb2, 0x06, 0x8b, 0xa0, 0x8a, 0x91, 0x86, 0x92, + 0x83, 0x98, 0x7d, 0x93, 0x7b, 0x8b, 0x08, 0x6d, 0x7d, 0x79, 0x66, 0x1f, + 0xfb, 0x13, 0xf7, 0x7b, 0x07, 0xc0, 0x8b, 0xad, 0x99, 0xa9, 0xac, 0xa4, + 0xa8, 0x98, 0xaa, 0x8b, 0xae, 0x8b, 0x97, 0x8a, 0x94, 0x87, 0x9c, 0xcc, + 0x9a, 0xb0, 0xb6, 0x8b, 0xc8, 0x8b, 0xc9, 0x6c, 0xae, 0xfb, 0x09, 0xcc, + 0x08, 0x2f, 0xbe, 0x05, 0x43, 0xb4, 0x68, 0xab, 0x8b, 0xa4, 0x08, 0xa8, + 0xaa, 0xa3, 0xb2, 0x1e, 0xf7, 0x24, 0x06, 0x4f, 0xfb, 0xab, 0x15, 0xc9, + 0x67, 0xae, 0x69, 0x8b, 0x74, 0x8b, 0x78, 0x78, 0x7e, 0x72, 0x8a, 0x08, + 0x80, 0x8b, 0x85, 0x8b, 0x05, 0x7a, 0x9a, 0x7b, 0x96, 0x56, 0xac, 0x08, + 0x24, 0xc5, 0x05, 0x50, 0xad, 0x70, 0xa6, 0x8b, 0xa5, 0x8b, 0xa1, 0xa0, + 0x97, 0xb2, 0x8b, 0xaf, 0x6e, 0x95, 0x84, 0xad, 0x78, 0x08, 0xee, 0x52, + 0x05, 0x0e, 0xf7, 0x17, 0xf8, 0x18, 0x15, 0x78, 0x67, 0x85, 0x73, 0x8b, + 0x67, 0x8b, 0x68, 0x91, 0x73, 0x9e, 0x66, 0x08, 0x6b, 0x69, 0x05, 0x75, + 0x74, 0x87, 0x84, 0x8b, 0x7a, 0x8b, 0x6f, 0xa2, 0x74, 0xa7, 0x8b, 0x9c, + 0x8b, 0x92, 0x8f, 0xa2, 0xa2, 0x08, 0xac, 0xab, 0x05, 0xb0, 0x77, 0xa2, + 0x85, 0xaf, 0x8b, 0xae, 0x8b, 0xa3, 0x91, 0xaf, 0x9e, 0x08, 0xad, 0x6b, + 0x05, 0xa1, 0x75, 0x92, 0x87, 0x9c, 0x8b, 0xa7, 0x8b, 0xa3, 0xa3, 0x8b, + 0xa7, 0x8b, 0x9b, 0x86, 0x94, 0x76, 0xa0, 0x08, 0x6a, 0xad, 0x05, 0x9f, + 0xb0, 0x91, 0xa3, 0x8b, 0xae, 0x8b, 0xae, 0x85, 0xa3, 0x78, 0xb0, 0x08, + 0xaa, 0xab, 0x05, 0xa1, 0xa1, 0x8f, 0x92, 0x8b, 0x9c, 0x8b, 0xa7, 0x74, + 0xa2, 0x6f, 0x8b, 0x7a, 0x8b, 0x83, 0x87, 0x75, 0x75, 0x08, 0x6c, 0x6d, + 0x05, 0x66, 0x9f, 0x73, 0x92, 0x67, 0x8b, 0x67, 0x8b, 0x73, 0x85, 0x66, + 0x77, 0x08, 0x6b, 0xaa, 0x05, 0x74, 0xa1, 0x84, 0x8f, 0x7a, 0x8b, 0x6f, + 0x8b, 0x74, 0x74, 0x8b, 0x70, 0x8b, 0x7d, 0x95, 0x77, 0x9a, 0x7c, 0x08, + 0xac, 0x6b, 0x05, 0xf7, 0x3d, 0x16, 0xc0, 0xb4, 0x61, 0x55, 0x58, 0x60, + 0x5f, 0x58, 0x58, 0x60, 0xb7, 0xbf, 0xc0, 0xb5, 0xb5, 0xbf, 0x1f, 0x0e, + 0xf7, 0x80, 0xf8, 0xee, 0x15, 0xad, 0xfb, 0x93, 0x05, 0x8e, 0x72, 0x94, + 0x81, 0x9e, 0x8b, 0x9f, 0x8b, 0x93, 0x95, 0x8f, 0xa5, 0x08, 0xaa, 0xf7, + 0x92, 0xfb, 0x14, 0x8b, 0x05, 0x0e, 0xf8, 0x42, 0xf8, 0xee, 0x15, 0xfb, + 0x18, 0x8b, 0xf7, 0x21, 0xfb, 0x7a, 0x05, 0x96, 0x79, 0x93, 0x85, 0x98, + 0x8b, 0x9b, 0x8b, 0x9a, 0x98, 0x8b, 0x9a, 0x8b, 0x90, 0x89, 0x94, 0x8a, + 0x90, 0x08, 0x46, 0xf7, 0x63, 0x05, 0xfb, 0x5c, 0x16, 0xfb, 0x18, 0x8b, + 0xf7, 0x21, 0xfb, 0x7a, 0x05, 0x96, 0x79, 0x93, 0x85, 0x98, 0x8b, 0x9b, + 0x8b, 0x9a, 0x98, 0x8b, 0x9a, 0x8b, 0x90, 0x89, 0x94, 0x8a, 0x90, 0x08, + 0x46, 0xf7, 0x63, 0x05, 0x0e, 0xf7, 0x43, 0xf7, 0x6e, 0x15, 0xf7, 0x2b, + 0xf7, 0x20, 0x05, 0x97, 0x95, 0x8f, 0x93, 0x8b, 0x94, 0x8b, 0x9b, 0x7c, + 0x99, 0x7a, 0x8b, 0x81, 0x8b, 0x86, 0x89, 0x7d, 0x80, 0x08, 0xfb, 0x8c, + 0xfb, 0x4c, 0xf7, 0x8c, 0xfb, 0x4d, 0x05, 0x99, 0x80, 0x90, 0x89, 0x94, + 0x8b, 0x9d, 0x8b, 0x9a, 0x99, 0x8b, 0x9b, 0x8b, 0x94, 0x86, 0x93, 0x80, + 0x95, 0x08, 0xfb, 0x2b, 0xf7, 0x21, 0x05, 0xf7, 0x79, 0x16, 0xf7, 0x2b, + 0xf7, 0x20, 0x05, 0x97, 0x95, 0x8f, 0x93, 0x8b, 0x94, 0x8b, 0x9b, 0x7c, + 0x99, 0x7a, 0x8b, 0x81, 0x8b, 0x86, 0x89, 0x7d, 0x80, 0x08, 0xfb, 0x8c, + 0xfb, 0x4c, 0xf7, 0x8c, 0xfb, 0x4d, 0x05, 0x99, 0x80, 0x90, 0x89, 0x94, + 0x8b, 0x9d, 0x8b, 0x9a, 0x99, 0x8b, 0x9b, 0x8b, 0x94, 0x86, 0x93, 0x80, + 0x95, 0x08, 0xfb, 0x2b, 0xf7, 0x21, 0x05, 0x0e, 0xf7, 0x43, 0xf7, 0x6e, + 0x15, 0xf7, 0x2b, 0xf7, 0x20, 0x05, 0x97, 0x95, 0x8f, 0x93, 0x8b, 0x94, + 0x8b, 0x9b, 0x7c, 0x99, 0x7a, 0x8b, 0x81, 0x8b, 0x86, 0x89, 0x7d, 0x80, + 0x08, 0xfb, 0x8c, 0xfb, 0x4c, 0xf7, 0x8c, 0xfb, 0x4d, 0x05, 0x99, 0x80, + 0x90, 0x89, 0x94, 0x8b, 0x9d, 0x8b, 0x9a, 0x99, 0x8b, 0x9b, 0x8b, 0x94, + 0x86, 0x93, 0x80, 0x95, 0x08, 0xfb, 0x2b, 0xf7, 0x21, 0x05, 0x0e, 0xf8, + 0x42, 0xf7, 0x6d, 0x15, 0xfb, 0x2b, 0xfb, 0x20, 0x05, 0x7f, 0x81, 0x87, + 0x83, 0x8b, 0x82, 0x8b, 0x7b, 0x9a, 0x7d, 0x9c, 0x8b, 0x95, 0x8b, 0x90, + 0x8d, 0x99, 0x96, 0x08, 0xf7, 0x8b, 0xf7, 0x4c, 0xfb, 0x8b, 0xf7, 0x4d, + 0x05, 0x7d, 0x96, 0x86, 0x8d, 0x82, 0x8b, 0x79, 0x8b, 0x7c, 0x7d, 0x8b, + 0x7b, 0x8b, 0x82, 0x90, 0x83, 0x96, 0x81, 0x08, 0xf7, 0x2b, 0xfb, 0x21, + 0x05, 0x0e, 0xf7, 0x57, 0xf7, 0xe5, 0x15, 0xac, 0x06, 0xa2, 0x8b, 0x96, + 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x6a, 0xb2, + 0x06, 0xa5, 0x9d, 0xa1, 0xa0, 0x1e, 0x95, 0x8b, 0x98, 0x88, 0x9b, 0x85, + 0x9c, 0x85, 0x8f, 0x8a, 0x94, 0x8b, 0xa6, 0x8b, 0xa1, 0xa2, 0x8b, 0xa7, + 0x8b, 0x9b, 0x83, 0x9a, 0x7d, 0x94, 0x77, 0x98, 0x60, 0x96, 0x67, 0x8b, + 0x08, 0x3f, 0x4f, 0x4a, 0x39, 0x1f, 0x64, 0x65, 0x07, 0x70, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, + 0x7c, 0x98, 0x82, 0x95, 0x83, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xb1, 0xfb, + 0x81, 0x61, 0x06, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x98, + 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x43, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, + 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, + 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x6a, 0x06, 0xf7, 0x81, + 0x07, 0xf7, 0xd6, 0xef, 0x15, 0xfb, 0x0c, 0x06, 0x71, 0x8b, 0x84, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x98, 0x82, 0x95, 0x83, 0x95, 0x89, 0xa4, 0x8b, 0x08, 0x9f, 0xfb, 0x81, + 0x65, 0x06, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, + 0xa3, 0x8b, 0x08, 0xf7, 0x42, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, + 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x67, 0xf7, 0xe5, 0x06, 0x7a, + 0xf7, 0x4f, 0x15, 0xfb, 0x0a, 0x22, 0xf7, 0x0a, 0x06, 0xf4, 0x07, 0x0e, + 0xf7, 0x54, 0xf7, 0xe5, 0x15, 0xac, 0x06, 0xa2, 0x8b, 0x96, 0x8d, 0x93, + 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, + 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x6a, 0xb1, 0x06, 0xa9, + 0x9a, 0x9d, 0xa4, 0x1e, 0x96, 0x8b, 0x92, 0x8a, 0xa3, 0x83, 0x98, 0x87, + 0x93, 0x89, 0x93, 0x8b, 0x9c, 0x8b, 0x98, 0x94, 0x95, 0x9d, 0x98, 0x82, + 0x93, 0x88, 0x9a, 0x8b, 0x08, 0xad, 0xfc, 0x3b, 0x65, 0x06, 0x70, 0x8b, + 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, + 0x43, 0x06, 0xa0, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x6f, 0x8b, 0x08, 0x66, 0xf8, 0x9f, 0xfb, 0x16, 0x06, 0x72, 0x8b, 0x7e, + 0x84, 0x80, 0x76, 0x6e, 0x9d, 0x65, 0x95, 0x61, 0x8b, 0x08, 0x42, 0x4f, + 0x49, 0x39, 0x1f, 0x65, 0x66, 0x07, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, + 0x95, 0x83, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xb0, 0xfb, 0x81, 0x60, 0x06, + 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x97, 0x82, 0x94, 0x84, 0x99, 0x88, 0xa2, 0x8b, + 0x08, 0xf7, 0x44, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, + 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x82, 0x92, + 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x6a, 0xf7, 0x81, 0x06, 0x0e, 0xf8, 0x80, + 0xf7, 0x79, 0x15, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x81, + 0x8d, 0x71, 0x8b, 0x08, 0xfc, 0x14, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, + 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf8, 0x14, 0x06, 0x0e, + 0xf7, 0xf2, 0xf7, 0xe5, 0x15, 0xe4, 0x06, 0xa3, 0x8b, 0x95, 0x8d, 0x94, + 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, + 0x95, 0x81, 0x92, 0x83, 0x8d, 0x6f, 0x8b, 0x08, 0x32, 0xf7, 0x0b, 0x06, + 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, + 0x7b, 0x8b, 0x7c, 0x83, 0x82, 0x7e, 0x83, 0x82, 0x89, 0x81, 0x8b, 0x71, + 0x08, 0xfb, 0x0b, 0x31, 0x07, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x97, 0x81, 0x95, + 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xe5, 0xfb, 0xff, 0x06, 0x8b, 0x74, + 0x8d, 0x80, 0x90, 0x83, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, + 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0xf7, + 0xff, 0x07, 0x0e, 0xf7, 0xf2, 0xf7, 0xe5, 0x15, 0xe4, 0x06, 0xa3, 0x8b, + 0x95, 0x8d, 0x94, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x6f, 0x8b, 0x08, 0x32, + 0xf7, 0x0b, 0x06, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, 0x7a, + 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x83, 0x82, 0x7e, 0x83, 0x82, 0x89, + 0x81, 0x8b, 0x71, 0x08, 0xfb, 0x0b, 0x31, 0x07, 0x72, 0x8b, 0x83, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x97, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xe5, 0xfb, 0x24, + 0x31, 0x06, 0x74, 0x8b, 0x80, 0x89, 0x83, 0x86, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x97, 0x81, 0x96, 0x84, 0x93, 0x89, + 0xa6, 0x8b, 0x08, 0xe5, 0xfb, 0x0b, 0x06, 0x8b, 0x74, 0x8d, 0x80, 0x90, + 0x83, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, + 0x98, 0x92, 0x95, 0x8d, 0x92, 0x8b, 0xa7, 0x08, 0xf7, 0x0b, 0xe4, 0x07, + 0xa4, 0x8b, 0x94, 0x8c, 0x94, 0x91, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, + 0x08, 0x32, 0xf7, 0x24, 0x06, 0x0e, 0xf7, 0xc9, 0xf7, 0x6a, 0x15, 0xb0, + 0xa8, 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x79, 0x06, 0x67, 0x6d, + 0x6d, 0x67, 0x67, 0xa9, 0x6d, 0xaf, 0x1f, 0x9d, 0x06, 0x0e, 0xf8, 0x68, + 0xf8, 0x8d, 0x15, 0xad, 0x06, 0xb0, 0x9c, 0x98, 0xa5, 0xa5, 0x79, 0x98, + 0x67, 0x1f, 0xfb, 0x59, 0x06, 0xfb, 0x22, 0xfb, 0x06, 0x3c, 0x2a, 0x1f, + 0x5d, 0x07, 0x8b, 0x32, 0xe7, 0x41, 0xf7, 0x15, 0x7e, 0x08, 0xfb, 0xad, + 0x3c, 0x07, 0x76, 0x8b, 0x86, 0x8a, 0x83, 0x86, 0x80, 0x84, 0x83, 0x7e, + 0x8b, 0x7e, 0x08, 0x71, 0x9d, 0x7e, 0xae, 0x1e, 0xf7, 0x1d, 0x06, 0xa3, + 0x8b, 0x93, 0x91, 0x96, 0xa7, 0x94, 0x72, 0x95, 0x82, 0xa0, 0x8b, 0x08, + 0xe8, 0x06, 0xaf, 0x9d, 0x98, 0xa5, 0xa5, 0x7a, 0x98, 0x66, 0x1f, 0x67, + 0xf8, 0xed, 0x06, 0xfb, 0x5a, 0xfb, 0x83, 0x15, 0x48, 0x99, 0x62, 0xaf, + 0x8b, 0xb8, 0x08, 0xb7, 0x07, 0x8b, 0xb8, 0xb4, 0xaf, 0xce, 0x99, 0x08, + 0xfb, 0x7e, 0x07, 0xf7, 0x0e, 0xf7, 0x83, 0x15, 0xfc, 0xed, 0x07, 0x80, + 0x85, 0x85, 0x84, 0x87, 0x7c, 0x86, 0x9b, 0x86, 0x91, 0x7e, 0x91, 0x08, + 0xf8, 0xed, 0xb7, 0x07, 0x0e, 0xf7, 0xbf, 0xf8, 0x59, 0x15, 0x39, 0x48, + 0x48, 0x39, 0x38, 0xce, 0x48, 0xdd, 0xdd, 0xcf, 0xce, 0xdc, 0xe0, 0x49, + 0xcd, 0x37, 0x1f, 0x0e, 0xf7, 0x6f, 0xf7, 0x1a, 0x15, 0x46, 0xfb, 0x89, + 0x05, 0x88, 0x80, 0x8b, 0x89, 0x8b, 0x85, 0x8b, 0x7c, 0x99, 0x7e, 0x9c, + 0x8b, 0x97, 0x8b, 0x97, 0x93, 0x93, 0x9b, 0x08, 0xf7, 0x21, 0xf7, 0xa0, + 0xfb, 0x18, 0x8b, 0x05, 0x0e, 0xf7, 0x33, 0xf7, 0x1a, 0x15, 0x46, 0xfb, + 0x63, 0x05, 0x89, 0x85, 0x8a, 0x83, 0x8b, 0x86, 0x8b, 0x7c, 0x9a, 0x7e, + 0x9b, 0x8b, 0x98, 0x8b, 0x93, 0x91, 0x96, 0x9d, 0x08, 0xf7, 0x21, 0xf7, + 0x7a, 0xfb, 0x18, 0x8b, 0x05, 0xf7, 0x5c, 0x16, 0x46, 0xfb, 0x63, 0x05, + 0x89, 0x85, 0x8a, 0x83, 0x8b, 0x86, 0x8b, 0x7c, 0x9a, 0x7e, 0x9b, 0x8b, + 0x98, 0x8b, 0x93, 0x91, 0x96, 0x9d, 0x08, 0xf7, 0x21, 0xf7, 0x7a, 0xfb, + 0x18, 0x8b, 0x05, 0x0e, 0xf7, 0x33, 0xf8, 0xee, 0x15, 0x46, 0xfb, 0x63, + 0x05, 0x89, 0x85, 0x8a, 0x83, 0x8b, 0x86, 0x8b, 0x7c, 0x9a, 0x7e, 0x9b, + 0x8b, 0x98, 0x8b, 0x93, 0x91, 0x96, 0x9d, 0x08, 0xf7, 0x21, 0xf7, 0x7a, + 0xfb, 0x18, 0x8b, 0x05, 0xf7, 0x5c, 0x16, 0x46, 0xfb, 0x63, 0x05, 0x89, + 0x85, 0x8a, 0x83, 0x8b, 0x86, 0x8b, 0x7c, 0x9a, 0x7e, 0x9b, 0x8b, 0x98, + 0x8b, 0x93, 0x91, 0x96, 0x9d, 0x08, 0xf7, 0x21, 0xf7, 0x7a, 0xfb, 0x18, + 0x8b, 0x05, 0x0e, 0xf8, 0x42, 0xf7, 0x6d, 0x15, 0xfb, 0x2b, 0xfb, 0x20, + 0x05, 0x7f, 0x81, 0x87, 0x83, 0x8b, 0x82, 0x8b, 0x7b, 0x9a, 0x7d, 0x9c, + 0x8b, 0x95, 0x8b, 0x90, 0x8d, 0x99, 0x96, 0x08, 0xf7, 0x8b, 0xf7, 0x4c, + 0xfb, 0x8b, 0xf7, 0x4d, 0x05, 0x7d, 0x96, 0x86, 0x8d, 0x82, 0x8b, 0x79, + 0x8b, 0x7c, 0x7d, 0x8b, 0x7b, 0x8b, 0x82, 0x90, 0x83, 0x96, 0x81, 0x08, + 0xf7, 0x2b, 0xfb, 0x21, 0x05, 0xfb, 0x7a, 0x16, 0xfb, 0x2b, 0xfb, 0x20, + 0x05, 0x7f, 0x81, 0x87, 0x83, 0x8b, 0x82, 0x8b, 0x7b, 0x9a, 0x7d, 0x9c, + 0x8b, 0x95, 0x8b, 0x90, 0x8d, 0x99, 0x96, 0x08, 0xf7, 0x8b, 0xf7, 0x4c, + 0xfb, 0x8b, 0xf7, 0x4d, 0x05, 0x7d, 0x96, 0x86, 0x8d, 0x82, 0x8b, 0x79, + 0x8b, 0x7c, 0x7d, 0x8b, 0x7b, 0x8b, 0x82, 0x90, 0x83, 0x96, 0x81, 0x08, + 0xf7, 0x2b, 0xfb, 0x21, 0x05, 0x0e, 0xf7, 0x01, 0x7c, 0x15, 0xb0, 0xa8, + 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x79, 0x06, 0x67, 0x6d, 0x6d, + 0x67, 0x67, 0xa9, 0x6d, 0xaf, 0x1f, 0x9d, 0x06, 0xf7, 0x5c, 0x16, 0xb0, + 0xa8, 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x79, 0x06, 0x67, 0x6d, + 0x6d, 0x67, 0x67, 0xa9, 0x6d, 0xaf, 0x1f, 0x9d, 0x06, 0xf7, 0x5c, 0x16, + 0xb0, 0xa8, 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, 0x66, 0x1f, 0x79, 0x06, 0x67, + 0x6d, 0x6d, 0x67, 0x67, 0xa9, 0x6d, 0xaf, 0x1f, 0x9d, 0x06, 0x0e, 0xf8, + 0x69, 0xf8, 0x0d, 0x15, 0xa0, 0x92, 0x93, 0x93, 0x8b, 0x9b, 0x8b, 0x9c, + 0x7d, 0x9a, 0x7c, 0x8b, 0x86, 0x8b, 0x89, 0x8b, 0x7f, 0x87, 0x08, 0xfc, + 0x01, 0xfb, 0x09, 0x05, 0x76, 0x84, 0x83, 0x82, 0x8b, 0x7c, 0x8b, 0x7a, + 0x99, 0x7b, 0x9a, 0x8b, 0x90, 0x8b, 0x8d, 0x8b, 0x97, 0x8f, 0x08, 0xf8, + 0x01, 0xf7, 0x0a, 0x05, 0xfb, 0xf5, 0xf7, 0x85, 0x15, 0x4b, 0x57, 0x57, + 0x4b, 0x1f, 0x4b, 0xbf, 0x57, 0xcb, 0xca, 0xc0, 0xbf, 0xca, 0xcc, 0x58, + 0xbf, 0x4a, 0x1e, 0x51, 0x04, 0xab, 0xa5, 0x71, 0x6a, 0x6c, 0x70, 0x71, + 0x6c, 0x6b, 0x71, 0xa5, 0xab, 0xab, 0xa5, 0xa5, 0xab, 0x1f, 0xed, 0xfb, + 0xdc, 0x15, 0x4b, 0x57, 0x57, 0x4b, 0x4b, 0xbf, 0x57, 0xcb, 0xca, 0xc0, + 0xbf, 0xca, 0xcc, 0x58, 0xbf, 0x4a, 0x1f, 0x51, 0x04, 0xab, 0xa5, 0x71, + 0x6a, 0x6c, 0x70, 0x71, 0x6c, 0x6b, 0x71, 0xa5, 0xab, 0xab, 0xa5, 0xa5, + 0xab, 0x1f, 0xf7, 0xa2, 0xc5, 0x15, 0x4b, 0x57, 0x57, 0x4b, 0x4b, 0xbf, + 0x57, 0xcb, 0xca, 0xc0, 0xbf, 0xca, 0xcc, 0x58, 0xbf, 0x4a, 0x1f, 0x51, + 0x04, 0xab, 0xa5, 0x71, 0x6a, 0x6c, 0x70, 0x71, 0x6c, 0x6b, 0x71, 0xa5, + 0xab, 0xab, 0xa5, 0xa5, 0xab, 0x1f, 0x0e, 0xf8, 0x84, 0x32, 0x15, 0x8b, + 0xa2, 0x89, 0x96, 0x86, 0x93, 0x82, 0x99, 0x7a, 0x95, 0x7a, 0x8b, 0x7c, + 0x8b, 0x7b, 0x83, 0x81, 0x7e, 0x84, 0x81, 0x89, 0x83, 0x8b, 0x70, 0x08, + 0x7d, 0x07, 0x6a, 0x7b, 0x69, 0x83, 0x65, 0x8b, 0x4b, 0x8b, 0x5f, 0xad, + 0x8b, 0xbd, 0x8b, 0xb6, 0xaf, 0xa5, 0xf7, 0x14, 0xbc, 0x08, 0xc3, 0x07, + 0x8b, 0xa2, 0x89, 0x95, 0x86, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, + 0x6e, 0x8b, 0x7a, 0x79, 0x87, 0x67, 0xfb, 0x0d, 0x56, 0x60, 0x5c, 0x8b, + 0x3a, 0x8b, 0xfb, 0x04, 0xe0, 0x3e, 0xf7, 0x10, 0x8b, 0xcb, 0x8b, 0xb6, + 0x97, 0xec, 0xba, 0x08, 0xda, 0x07, 0xfb, 0x63, 0xf8, 0x6f, 0x15, 0x66, + 0x6e, 0x6e, 0x66, 0x66, 0xa8, 0x6e, 0xb0, 0x1f, 0x9c, 0x06, 0xb0, 0xa9, + 0xa9, 0xaf, 0xaf, 0x6d, 0xa9, 0x66, 0x1f, 0x7a, 0x06, 0x0e, 0xf7, 0x56, + 0xf9, 0x3c, 0x15, 0x7b, 0x98, 0x86, 0x8e, 0x80, 0x8b, 0x76, 0x8b, 0x7b, + 0x7b, 0x8b, 0x77, 0x8b, 0x7e, 0x91, 0x81, 0x9c, 0x7e, 0x08, 0xf7, 0x19, + 0xfb, 0x04, 0x05, 0x9a, 0x7f, 0x92, 0x87, 0x95, 0x8b, 0x9f, 0x8b, 0x9c, + 0x9c, 0x8b, 0x9e, 0x8b, 0x98, 0x84, 0x96, 0x7b, 0x98, 0x08, 0xfb, 0x19, + 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x58, 0xf9, 0x04, 0x15, 0x9c, 0x98, 0x91, + 0x95, 0x8b, 0x97, 0x8b, 0xa0, 0x7b, 0x9b, 0x76, 0x8b, 0x80, 0x8b, 0x86, + 0x88, 0x7b, 0x7e, 0x08, 0xfb, 0x19, 0xfb, 0x03, 0x05, 0x7b, 0x7e, 0x84, + 0x80, 0x8b, 0x7e, 0x8b, 0x78, 0x9c, 0x7a, 0x9f, 0x8b, 0x95, 0x8b, 0x92, + 0x8f, 0x9a, 0x97, 0x08, 0xf7, 0x19, 0xf7, 0x04, 0x05, 0x0e, 0xf7, 0xc1, + 0xf8, 0xf3, 0x15, 0xf7, 0x04, 0x2a, 0x05, 0x96, 0x82, 0x94, 0x87, 0x94, + 0x8b, 0x9d, 0x8b, 0x9b, 0x9c, 0x8b, 0x9d, 0x8b, 0x96, 0x87, 0x93, 0x80, + 0x94, 0x89, 0x8d, 0x87, 0x8e, 0x88, 0x8d, 0x08, 0xfb, 0x2b, 0xf7, 0x15, + 0xfb, 0x2c, 0xfb, 0x15, 0x05, 0x75, 0x79, 0x89, 0x88, 0x8b, 0x7d, 0x8b, + 0x79, 0x9b, 0x7a, 0x9e, 0x8b, 0x94, 0x8b, 0x93, 0x8f, 0x96, 0x94, 0x08, + 0xf7, 0x05, 0xec, 0x05, 0x0e, 0xf8, 0x59, 0xf9, 0x24, 0x15, 0x7f, 0x8b, + 0x7e, 0x81, 0x7d, 0x77, 0x75, 0x6d, 0x87, 0x87, 0x7c, 0x8b, 0x80, 0x8b, + 0x7e, 0x91, 0x69, 0x9f, 0x08, 0x59, 0xaa, 0x7a, 0x92, 0x74, 0x8b, 0x6e, + 0x8b, 0x6e, 0x7b, 0x72, 0x6e, 0x7a, 0x76, 0x81, 0x77, 0x8b, 0x7d, 0x8b, + 0x7b, 0x99, 0x7d, 0x9c, 0x8b, 0x95, 0x8b, 0x93, 0x8f, 0x93, 0x96, 0xa8, + 0xb2, 0x93, 0x92, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x94, 0x88, 0xa6, 0x79, + 0x08, 0xb7, 0x6e, 0xac, 0x7d, 0xa1, 0x8b, 0xa8, 0x8b, 0xa3, 0x99, 0xa6, + 0xad, 0xa0, 0xa6, 0x93, 0x9a, 0x8b, 0x9a, 0x08, 0x99, 0x7c, 0x99, 0x7a, + 0x1e, 0x0e, 0xf7, 0x46, 0xf9, 0x06, 0x15, 0x69, 0x78, 0x7c, 0x72, 0x1f, + 0x8b, 0x83, 0x90, 0x7f, 0x91, 0x83, 0x94, 0x81, 0x93, 0x89, 0xa4, 0x8b, + 0x08, 0xf7, 0x88, 0x06, 0xac, 0x9f, 0x9a, 0xa4, 0x1f, 0x8b, 0x93, 0x86, + 0x99, 0x85, 0x92, 0x84, 0x93, 0x7f, 0x8e, 0x74, 0x8b, 0x08, 0xfb, 0x88, + 0x06, 0x0e, 0xf7, 0x33, 0xf9, 0x43, 0x15, 0x77, 0x7d, 0x7c, 0x74, 0x3f, + 0xde, 0x45, 0xe7, 0xe7, 0xde, 0xd1, 0xd7, 0xa2, 0x7d, 0x9a, 0x77, 0x1f, + 0x77, 0x8b, 0x84, 0x82, 0x84, 0x6c, 0x81, 0x5d, 0x61, 0x6d, 0x54, 0x8b, + 0x54, 0x8b, 0x61, 0xa9, 0x81, 0xb9, 0x84, 0xaa, 0x84, 0x94, 0x77, 0x8b, + 0x08, 0x0e, 0xf7, 0xc0, 0xf9, 0x22, 0x15, 0x6a, 0x70, 0x70, 0x6a, 0x6a, + 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, + 0x0e, 0xf7, 0x58, 0xf9, 0x22, 0x15, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, + 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0xf7, + 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, + 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0x0e, 0xf7, 0xc0, 0xf9, 0x6b, + 0x15, 0x48, 0x53, 0x54, 0x4a, 0x49, 0xc3, 0x54, 0xce, 0xcd, 0xc4, 0xc2, + 0xcb, 0xce, 0x54, 0xc2, 0x47, 0x1f, 0x56, 0x04, 0xb1, 0xab, 0x6c, 0x66, + 0x68, 0x6a, 0x6c, 0x66, 0x65, 0x6b, 0xaa, 0xaf, 0xaf, 0xab, 0xaa, 0xb1, + 0x1f, 0x0e, 0xf7, 0x9a, 0x16, 0x25, 0x07, 0x98, 0x8d, 0x8f, 0x8b, 0x90, + 0x8b, 0x08, 0xad, 0x9e, 0x7e, 0x76, 0x7b, 0x7e, 0x82, 0x74, 0x1f, 0x7a, + 0x8b, 0x75, 0x92, 0x79, 0x95, 0x79, 0x95, 0x88, 0x8c, 0x83, 0x8b, 0x78, + 0x8b, 0x7b, 0x7b, 0x8b, 0x78, 0x8b, 0x7b, 0x94, 0x7f, 0x9e, 0x80, 0xa3, + 0x7e, 0xb4, 0x80, 0xa6, 0x8b, 0xc9, 0x8b, 0xb8, 0xb3, 0x8b, 0xc4, 0x08, + 0x8b, 0xbe, 0x73, 0xa8, 0x58, 0x96, 0x08, 0xb4, 0x45, 0x07, 0x0e, 0xf7, + 0xb7, 0xf9, 0x02, 0x15, 0x9a, 0x9b, 0x90, 0x94, 0x8b, 0x96, 0x8b, 0x9e, + 0x7b, 0x9c, 0x79, 0x8b, 0x80, 0x8b, 0x84, 0x87, 0x80, 0x80, 0x08, 0x25, + 0xfb, 0x02, 0x05, 0x77, 0x74, 0x8a, 0x89, 0x8b, 0x80, 0x8b, 0x78, 0x9c, + 0x79, 0x9d, 0x8b, 0x94, 0x8b, 0x96, 0x91, 0x94, 0x95, 0x08, 0xf1, 0xf7, + 0x02, 0x05, 0xf7, 0x38, 0x16, 0x9a, 0x9b, 0x90, 0x94, 0x8b, 0x96, 0x8b, + 0x9e, 0x7b, 0x9c, 0x79, 0x8b, 0x80, 0x8b, 0x83, 0x87, 0x81, 0x80, 0x08, + 0x25, 0xfb, 0x02, 0x05, 0x77, 0x74, 0x8a, 0x89, 0x8b, 0x80, 0x8b, 0x78, + 0x9c, 0x79, 0x9d, 0x8b, 0x94, 0x8b, 0x95, 0x91, 0x95, 0x95, 0x08, 0xf1, + 0xf7, 0x02, 0x05, 0x0e, 0xf7, 0xdd, 0x16, 0x52, 0x67, 0x75, 0x69, 0x8b, + 0x5a, 0x8b, 0x54, 0xaf, 0x69, 0xc5, 0x8b, 0xa6, 0x8b, 0xa9, 0x92, 0xa6, + 0x97, 0xa3, 0x96, 0x96, 0x99, 0x8b, 0x9d, 0x8b, 0xa0, 0x7a, 0x9c, 0x75, + 0x8b, 0x84, 0x8b, 0x86, 0x8a, 0x81, 0x86, 0x08, 0x6e, 0x7d, 0x81, 0x87, + 0x7f, 0x8b, 0x7c, 0x8b, 0x82, 0x92, 0x8b, 0x98, 0x8b, 0xab, 0xa6, 0xaa, + 0xd4, 0xbc, 0x08, 0x29, 0x06, 0x0e, 0xf7, 0xc1, 0xf8, 0xde, 0x15, 0xfb, + 0x05, 0xeb, 0x05, 0x7e, 0x96, 0x85, 0x8e, 0x82, 0x8b, 0x78, 0x8b, 0x7b, + 0x7a, 0x8b, 0x78, 0x8b, 0x7e, 0x8d, 0x87, 0xa1, 0x79, 0x08, 0xf7, 0x2c, + 0xfb, 0x14, 0xf7, 0x2b, 0xf7, 0x14, 0x94, 0x92, 0x05, 0x96, 0x94, 0x8f, + 0x93, 0x8b, 0x96, 0x8b, 0x9e, 0x7b, 0x9c, 0x79, 0x8b, 0x81, 0x8b, 0x84, + 0x88, 0x7f, 0x80, 0x08, 0xfb, 0x04, 0x2b, 0x05, 0x0e, 0xf8, 0xc7, 0xf7, + 0x79, 0x15, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x82, 0x92, 0x81, 0x8d, + 0x71, 0x8b, 0x08, 0xfc, 0xa2, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x81, + 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf8, 0xa2, 0x06, 0x0e, 0xc0, + 0xef, 0x15, 0x84, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xea, 0x06, + 0xaf, 0xa0, 0x9e, 0xad, 0x1f, 0x8b, 0xa5, 0x7c, 0x9c, 0x71, 0x8f, 0x08, + 0x9c, 0xc5, 0xe8, 0x8b, 0x8b, 0x51, 0x83, 0x8b, 0x05, 0x6f, 0x75, 0x76, + 0x70, 0x6b, 0xa1, 0x77, 0xad, 0x1f, 0xf7, 0xf1, 0xf7, 0x0f, 0x06, 0x8b, + 0xa4, 0x8a, 0x93, 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, + 0x8b, 0x7c, 0x83, 0x81, 0x7e, 0x84, 0x81, 0x89, 0x81, 0x8b, 0x72, 0x08, + 0x74, 0x07, 0xfb, 0x27, 0xf7, 0x23, 0x9e, 0x06, 0x8c, 0x68, 0x9e, 0x76, + 0xa9, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x08, 0x92, 0x95, 0x8d, + 0x93, 0x8b, 0xa6, 0x08, 0xd9, 0x07, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, + 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x6d, 0x8b, 0x79, 0x77, 0x89, 0x68, + 0x08, 0x78, 0xf7, 0x21, 0xf7, 0x12, 0x4a, 0x06, 0x8b, 0x74, 0x8d, 0x80, + 0x90, 0x83, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, + 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0xf7, 0x39, 0xfc, + 0x4b, 0x07, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, + 0xa4, 0x8b, 0x08, 0x99, 0x8b, 0x05, 0xfb, 0x07, 0xfc, 0x13, 0x05, 0xf7, + 0x6a, 0xf7, 0x33, 0x15, 0x4b, 0x8b, 0xcb, 0xf7, 0x68, 0x8b, 0xfb, 0x68, + 0x05, 0x0e, 0xf7, 0xf6, 0xf7, 0xb0, 0x15, 0xe0, 0x06, 0xac, 0x9c, 0x99, + 0xa4, 0xa6, 0x7b, 0x97, 0x68, 0x1f, 0x85, 0xf7, 0x14, 0x06, 0xce, 0x58, + 0xb1, 0x32, 0x1e, 0x68, 0x8b, 0x5b, 0x83, 0x69, 0x7f, 0x7c, 0x85, 0x82, + 0x7f, 0x8b, 0x7b, 0x8b, 0x75, 0x9c, 0x79, 0xa0, 0x8b, 0x91, 0x8b, 0x96, + 0x8d, 0x96, 0x8e, 0xab, 0x93, 0xa3, 0x8e, 0xa2, 0x8b, 0x08, 0xb4, 0x9c, + 0x83, 0x78, 0x1f, 0x83, 0x07, 0x6e, 0x8f, 0x7e, 0x8c, 0x77, 0x8b, 0x48, + 0x8b, 0x5c, 0x7a, 0x6b, 0x67, 0x7a, 0x78, 0x80, 0x72, 0x8b, 0x76, 0x8b, + 0x56, 0xc4, 0x60, 0xd2, 0x8b, 0xb2, 0x8b, 0xa8, 0x91, 0xb3, 0x9b, 0x08, + 0x80, 0x07, 0xee, 0x04, 0x71, 0x79, 0x5f, 0x7e, 0x6b, 0x8b, 0x08, 0x72, + 0x79, 0x94, 0x98, 0xa2, 0xb0, 0x9f, 0xb5, 0x1f, 0x9e, 0x8b, 0x9a, 0x8a, + 0xab, 0x85, 0x08, 0x70, 0x07, 0xd9, 0xfb, 0x5d, 0x15, 0xad, 0x9c, 0x98, + 0xa5, 0xa5, 0x7b, 0x97, 0x67, 0x1f, 0xfb, 0x93, 0x06, 0x62, 0x80, 0x84, + 0x72, 0x65, 0x93, 0x84, 0xb7, 0x1f, 0xf7, 0x94, 0x06, 0x0e, 0xf7, 0x94, + 0xf8, 0x77, 0x15, 0xc4, 0x06, 0xa2, 0x8b, 0x95, 0x8d, 0x94, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x6a, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, + 0x7c, 0x97, 0x81, 0x95, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xc4, 0xfb, + 0x39, 0x06, 0x23, 0x4f, 0x05, 0x6b, 0x79, 0x83, 0x80, 0x8b, 0x75, 0x8b, + 0x70, 0xa2, 0x73, 0xa4, 0x8b, 0x96, 0x8b, 0x9a, 0x90, 0x9b, 0x95, 0x08, + 0xc1, 0xab, 0x8b, 0x24, 0x52, 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, + 0x1e, 0xf8, 0x6c, 0xf7, 0x53, 0x06, 0x8b, 0xa4, 0x89, 0x94, 0x86, 0x94, + 0x81, 0x9a, 0x7c, 0x94, 0x79, 0x8b, 0x7b, 0x8b, 0x7c, 0x84, 0x81, 0x7d, + 0x84, 0x82, 0x89, 0x81, 0x8b, 0x70, 0x08, 0x30, 0xfb, 0x6b, 0xf7, 0x24, + 0x07, 0xf7, 0x1d, 0xdc, 0x05, 0xaa, 0x9d, 0x93, 0x95, 0x8b, 0xa2, 0x8b, + 0xa5, 0x75, 0xa3, 0x72, 0x8b, 0x7f, 0x8b, 0x81, 0x87, 0x78, 0x80, 0x08, + 0x33, 0x57, 0x8b, 0xf7, 0x10, 0x05, 0x0e, 0xf7, 0x33, 0xa7, 0x15, 0xb6, + 0x70, 0xbc, 0x7c, 0xbc, 0x8b, 0xf7, 0x2e, 0x8b, 0xf7, 0x11, 0xf7, 0x1d, + 0x8b, 0xf7, 0x3c, 0x8b, 0xd4, 0x77, 0xcc, 0x62, 0xc1, 0x08, 0xbf, 0xcc, + 0x05, 0x9b, 0xa0, 0x8f, 0x93, 0x8b, 0x98, 0x8b, 0xa5, 0x75, 0xa1, 0x71, + 0x8b, 0x78, 0x8b, 0x82, 0x85, 0x78, 0x72, 0x08, 0x5d, 0x51, 0x05, 0x5b, + 0xab, 0x5a, 0x9b, 0x57, 0x8b, 0xfb, 0x2f, 0x8b, 0xfb, 0x11, 0xfb, 0x1d, + 0x8b, 0xfb, 0x3c, 0x8b, 0x3d, 0xa1, 0x4c, 0xb8, 0x50, 0x08, 0x52, 0x42, + 0x05, 0x7a, 0x76, 0x87, 0x83, 0x8b, 0x7e, 0x8b, 0x71, 0xa1, 0x76, 0xa6, + 0x8b, 0x9e, 0x8b, 0x93, 0x90, 0x9f, 0xa4, 0x08, 0xc1, 0xcf, 0x05, 0xf7, + 0xb9, 0xf8, 0x08, 0x15, 0x9c, 0x6c, 0x95, 0x62, 0x8b, 0x65, 0x8b, 0xfb, + 0x03, 0x39, 0x2e, 0x2a, 0x8b, 0x70, 0x8b, 0x70, 0x92, 0x72, 0x99, 0x08, + 0xf7, 0x7b, 0xf7, 0xb9, 0x05, 0xfb, 0xc0, 0xfb, 0x76, 0x15, 0x75, 0xb0, + 0x81, 0xb0, 0x8b, 0xb7, 0x8b, 0xf7, 0x04, 0xdc, 0xe8, 0xed, 0x8b, 0xaa, + 0x8b, 0xa7, 0x82, 0xa8, 0x7a, 0x08, 0xfb, 0x7f, 0xfb, 0xbd, 0x05, 0x0e, + 0xf8, 0x02, 0xf7, 0x87, 0x15, 0x9e, 0x06, 0x8c, 0x68, 0x9e, 0x76, 0xa8, + 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x08, 0x92, 0x95, 0x8d, 0x93, + 0x8b, 0xa6, 0x08, 0xd9, 0x07, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, + 0x9a, 0x7b, 0x94, 0x79, 0x8b, 0x6d, 0x8b, 0x7a, 0x78, 0x89, 0x67, 0x08, + 0x78, 0xf7, 0x21, 0xf7, 0x13, 0x4a, 0x06, 0x8b, 0x74, 0x8d, 0x80, 0x90, + 0x83, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, + 0x97, 0x92, 0x95, 0x8d, 0x94, 0x8b, 0xa6, 0x08, 0xf7, 0x39, 0xfb, 0xe2, + 0x07, 0xfb, 0x37, 0xfb, 0x08, 0xfb, 0x0e, 0xfb, 0x3d, 0xfb, 0x3e, 0xf7, + 0x09, 0xfb, 0x0e, 0xf7, 0x36, 0x1f, 0xf7, 0xf5, 0xf7, 0x0e, 0x06, 0x8b, + 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x83, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, + 0x8b, 0x7c, 0x83, 0x81, 0x7f, 0x84, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, + 0x75, 0xfb, 0x27, 0x07, 0xf7, 0x23, 0x07, 0x27, 0xfb, 0x23, 0x15, 0x5d, + 0x8b, 0x71, 0x92, 0x6f, 0x9c, 0x58, 0xaa, 0x68, 0xd0, 0x8b, 0xce, 0x8b, + 0xca, 0xa9, 0xcc, 0xb8, 0xac, 0xa9, 0xa1, 0xa9, 0x93, 0xbe, 0x8c, 0x08, + 0xfc, 0x13, 0x07, 0x0e, 0xf7, 0xc1, 0xf8, 0xe7, 0x15, 0x2e, 0x3e, 0x40, + 0x31, 0x34, 0xd7, 0x45, 0xe9, 0xe8, 0xd8, 0xd1, 0xe0, 0xe8, 0x40, 0xd5, + 0x2c, 0x1f, 0x3d, 0x04, 0xbc, 0xb5, 0x63, 0x5c, 0x61, 0x60, 0x66, 0x5b, + 0x5b, 0x60, 0xb0, 0xb5, 0xba, 0xb5, 0xb3, 0xbc, 0x1f, 0xf7, 0x13, 0xfb, + 0xe3, 0x15, 0xae, 0x9c, 0x98, 0xa5, 0xa5, 0x7b, 0x97, 0x67, 0x1f, 0xfb, + 0x92, 0x06, 0x76, 0x8b, 0x86, 0x8a, 0x83, 0x86, 0x80, 0x84, 0x84, 0x7e, + 0x8b, 0x7f, 0x08, 0x71, 0x9c, 0x7e, 0xae, 0x1e, 0xf7, 0x92, 0x06, 0x0e, + 0xf8, 0xf7, 0xf7, 0x40, 0x15, 0xb9, 0x07, 0x8b, 0xce, 0x7a, 0xc3, 0x6c, + 0xb3, 0x68, 0xb8, 0x5d, 0xa3, 0x5c, 0x8b, 0x61, 0x8b, 0x69, 0x7a, 0x67, + 0x64, 0x68, 0xb2, 0x68, 0x9c, 0x5d, 0x8b, 0x72, 0x8b, 0x51, 0x7f, 0x66, + 0x7f, 0x70, 0x82, 0x7d, 0x7b, 0x8b, 0x72, 0x08, 0x6f, 0xa1, 0x74, 0xa5, + 0x1e, 0x91, 0x8b, 0x93, 0x8c, 0x94, 0x8e, 0xcb, 0x9e, 0x94, 0x8d, 0x9c, + 0x8b, 0x08, 0xa7, 0x9f, 0x76, 0x6f, 0x1f, 0x77, 0x07, 0x71, 0x8e, 0x78, + 0x8d, 0x7c, 0x8b, 0x5c, 0x8b, 0x4c, 0x79, 0x63, 0x71, 0x61, 0x71, 0x7b, + 0x70, 0x8b, 0x5f, 0x8b, 0x2a, 0xcf, 0x4b, 0xf3, 0x8b, 0xb6, 0x8b, 0xa9, + 0x94, 0xb0, 0xa2, 0x08, 0x95, 0x80, 0x96, 0x85, 0x9a, 0x8b, 0x9b, 0x8b, + 0x97, 0x91, 0x94, 0x96, 0x08, 0xb0, 0x72, 0xa2, 0x84, 0xb3, 0x8b, 0xba, + 0x8b, 0xca, 0x9b, 0xae, 0xa1, 0x9b, 0x95, 0x94, 0x9a, 0x8b, 0x9e, 0x8b, + 0xa9, 0x77, 0xa1, 0x71, 0x8b, 0x7e, 0x8b, 0x7c, 0x86, 0x6e, 0x7f, 0x70, + 0x7f, 0x78, 0x86, 0x75, 0x8b, 0x08, 0x62, 0x8b, 0x74, 0xa4, 0x7a, 0xca, + 0x08, 0xf7, 0x8f, 0x06, 0xfb, 0xf8, 0x61, 0x15, 0x63, 0x69, 0x71, 0x7f, + 0x6c, 0x8b, 0x61, 0x8b, 0x6f, 0xa2, 0x8b, 0xae, 0x8b, 0x97, 0x90, 0x95, + 0x93, 0x92, 0x08, 0x9f, 0x9a, 0xb4, 0x96, 0xb0, 0x8b, 0x9c, 0x8b, 0x9b, + 0x89, 0xa2, 0x85, 0x08, 0x50, 0x07, 0xf6, 0xf7, 0x14, 0x15, 0x8f, 0xa2, + 0x8e, 0x98, 0x91, 0x98, 0x96, 0xa5, 0xa2, 0x9c, 0xa2, 0x8b, 0xa1, 0x8b, + 0xa1, 0x7c, 0x96, 0x75, 0x93, 0x7d, 0x8e, 0x7d, 0x8f, 0x70, 0x08, 0xfb, + 0x20, 0x06, 0x0e, 0xf7, 0xf2, 0xf8, 0x49, 0x15, 0xfb, 0x46, 0x06, 0x71, + 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x97, 0x89, 0xa4, 0x8b, 0x08, + 0xd9, 0xfb, 0x81, 0xfb, 0x0e, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, + 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0xec, 0x06, 0x9f, 0x8b, + 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, + 0x0e, 0xf7, 0xe5, 0x06, 0x0e, 0xf7, 0xf2, 0xf9, 0x04, 0x15, 0xfb, 0x43, + 0x06, 0x72, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, + 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, 0x96, 0x89, 0xa5, + 0x8b, 0x08, 0xd6, 0xfb, 0x39, 0x06, 0x38, 0x5c, 0x05, 0x6c, 0x79, 0x82, + 0x7f, 0x8b, 0x75, 0x8b, 0x70, 0xa2, 0x73, 0xa5, 0x8b, 0x95, 0x8b, 0x98, + 0x8f, 0x9c, 0x95, 0x08, 0xad, 0x9f, 0x8b, 0xfb, 0x23, 0xfb, 0x0e, 0x8b, + 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, + 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, + 0x8b, 0x08, 0xf7, 0xec, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, + 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x0e, 0xf7, 0x4b, 0x06, 0xe0, + 0xbc, 0x05, 0xa8, 0x9b, 0x95, 0x98, 0x8b, 0xa1, 0x8b, 0xa7, 0x74, 0xa3, + 0x71, 0x8b, 0x7f, 0x8b, 0x84, 0x88, 0x76, 0x7e, 0x08, 0x68, 0x77, 0x8b, + 0xf7, 0x75, 0x05, 0x0e, 0xf8, 0xb8, 0xf8, 0x26, 0x15, 0xa0, 0x9f, 0x8f, + 0x93, 0x8b, 0x9c, 0x8b, 0xa5, 0x76, 0xa0, 0x71, 0x8b, 0x7a, 0x8b, 0x83, + 0x86, 0x76, 0x76, 0x08, 0x5b, 0x5a, 0x05, 0x69, 0x9d, 0x53, 0x98, 0x5f, + 0x8b, 0xfb, 0x22, 0x8b, 0xfb, 0x06, 0x24, 0x8b, 0xfb, 0x16, 0x8b, 0x59, + 0x9f, 0x56, 0xad, 0x61, 0x08, 0x5b, 0x59, 0x05, 0x77, 0x77, 0x86, 0x82, + 0x8b, 0x7c, 0x8b, 0x70, 0xa0, 0x76, 0xa6, 0x8b, 0x9b, 0x8b, 0x93, 0x90, + 0xa0, 0xa0, 0x08, 0xc3, 0xc5, 0x05, 0xb4, 0x77, 0xb5, 0x81, 0xb8, 0x8b, + 0xf7, 0x24, 0x8b, 0xf7, 0x06, 0xf2, 0x8b, 0xf7, 0x16, 0x8b, 0xbd, 0x79, + 0xbc, 0x69, 0xb6, 0x08, 0xb5, 0xb6, 0x05, 0xfb, 0x04, 0xfb, 0x08, 0x15, + 0x99, 0x75, 0x93, 0x74, 0x8b, 0x73, 0x8b, 0x40, 0x46, 0x51, 0x31, 0x8b, + 0x77, 0x8b, 0x7d, 0x8d, 0x79, 0x90, 0x08, 0xf7, 0x51, 0xf7, 0x57, 0x05, + 0xfb, 0xa1, 0xfb, 0x21, 0x15, 0x7a, 0xa2, 0x83, 0xa3, 0x8b, 0xa4, 0x8b, + 0xd6, 0xd0, 0xc5, 0xe4, 0x8b, 0x9e, 0x8b, 0x9c, 0x88, 0xa0, 0x86, 0x08, + 0xfb, 0x52, 0xfb, 0x59, 0x05, 0x0e, 0xf8, 0xf8, 0xf7, 0x3f, 0x15, 0xb8, + 0x07, 0x8b, 0xd3, 0x78, 0xc8, 0x67, 0xb3, 0x68, 0xb3, 0x61, 0xa0, 0x5f, + 0x8b, 0x56, 0x8b, 0x5e, 0x70, 0x68, 0x56, 0x65, 0xc1, 0x60, 0xa5, 0x57, + 0x8b, 0x08, 0x26, 0x3b, 0x22, 0xfb, 0x19, 0xfb, 0x12, 0xdc, 0x25, 0xf0, + 0x1f, 0xbd, 0x8b, 0xba, 0xa5, 0xae, 0xbb, 0xae, 0x59, 0xb6, 0x73, 0xc4, + 0x8b, 0xb3, 0x8b, 0xcc, 0x99, 0xac, 0x9b, 0xa6, 0x99, 0x95, 0x98, 0x8b, + 0xa3, 0x8b, 0xa8, 0x75, 0xa2, 0x70, 0x8b, 0x83, 0x8b, 0x83, 0x89, 0x83, + 0x88, 0x08, 0x54, 0x73, 0x7e, 0x87, 0x6f, 0x8b, 0x60, 0x8b, 0x6f, 0xa8, + 0x7e, 0xc5, 0x08, 0xf7, 0x90, 0x06, 0xfc, 0x4c, 0xf7, 0x46, 0x15, 0xba, + 0xb0, 0x50, 0x40, 0x43, 0x65, 0x50, 0x5d, 0x5e, 0x65, 0xc7, 0xd3, 0xd4, + 0xb1, 0xc7, 0xb8, 0x1f, 0xf7, 0x53, 0x2f, 0x15, 0x91, 0xa4, 0x8f, 0x97, + 0x90, 0x97, 0x97, 0xa6, 0xa0, 0x9b, 0xa2, 0x8b, 0xa0, 0x8b, 0xa0, 0x7c, + 0x97, 0x73, 0x91, 0x7e, 0x90, 0x7d, 0x90, 0x71, 0x08, 0xfb, 0x21, 0x06, + 0x0e, 0xea, 0xef, 0x15, 0x7b, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, + 0x7d, 0x82, 0x81, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x97, 0x81, + 0x94, 0x85, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xe8, 0x06, 0xb8, 0xa0, 0x9b, + 0xae, 0x1f, 0x8b, 0xa6, 0x7c, 0x9c, 0x6f, 0x90, 0x08, 0xf7, 0xfd, 0x07, + 0xb4, 0xa5, 0xa0, 0xba, 0xb9, 0xab, 0x70, 0x66, 0x1e, 0x8b, 0x7a, 0x82, + 0x7a, 0x7b, 0x81, 0x80, 0x83, 0x83, 0x89, 0x71, 0x88, 0x69, 0x88, 0x78, + 0x79, 0x8b, 0x6f, 0x8b, 0x6d, 0x9d, 0x7b, 0xb0, 0x87, 0xbf, 0x85, 0xaa, + 0x7f, 0xa6, 0x71, 0x08, 0xa5, 0x72, 0x9a, 0x69, 0x8b, 0x67, 0x8b, 0x5b, + 0x78, 0x6b, 0x6f, 0x8b, 0x7b, 0x8b, 0x81, 0x95, 0x87, 0x9e, 0x86, 0xa0, + 0x8a, 0x8c, 0x85, 0x92, 0x83, 0x94, 0x7d, 0x90, 0x7e, 0x8b, 0x08, 0x6c, + 0x78, 0x75, 0x66, 0x49, 0xbd, 0x5c, 0xd0, 0xe8, 0xc9, 0xd4, 0xf7, 0x00, + 0x1f, 0x8b, 0xdf, 0x62, 0xd2, 0x3e, 0xb8, 0x08, 0xa6, 0xab, 0x93, 0xa1, + 0x8b, 0xb0, 0x08, 0xea, 0x3e, 0xd3, 0x26, 0x26, 0x43, 0x4f, 0x36, 0x1e, + 0xfc, 0x0e, 0x07, 0x0e, 0xf8, 0x34, 0xf7, 0x32, 0x15, 0xa2, 0x51, 0x74, + 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x97, 0x88, + 0xa3, 0x8b, 0x08, 0xf7, 0x1f, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x94, + 0x81, 0x93, 0x82, 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x5b, 0xf8, 0x77, 0xfb, + 0x6c, 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, + 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x95, 0x84, 0x95, + 0x89, 0xa5, 0x8b, 0x08, 0xca, 0x8b, 0xfb, 0x2f, 0xfc, 0x13, 0x05, 0x72, + 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, + 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x19, 0x06, 0xa0, 0x8b, 0x98, 0x8d, + 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, + 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x74, 0x8b, 0xa2, + 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x62, 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xda, + 0xf7, 0x54, 0xd9, 0xfb, 0x54, 0x05, 0xfb, 0x58, 0xf8, 0xb0, 0x15, 0x6a, + 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, + 0x71, 0xa6, 0x69, 0x1f, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, + 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, + 0x0e, 0xf8, 0x34, 0xf7, 0x32, 0x15, 0xa2, 0x51, 0x74, 0x8b, 0x05, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, + 0xf7, 0x1f, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x94, 0x81, 0x93, 0x82, + 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x5b, 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, + 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, + 0x08, 0xca, 0x8b, 0xfb, 0x2f, 0xfc, 0x13, 0x05, 0x72, 0x8b, 0x82, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, + 0xb7, 0x1e, 0xf7, 0x19, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x74, 0x8b, 0xa2, 0xc5, 0xf7, 0x82, + 0x8b, 0x05, 0x62, 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xda, 0xf7, 0x54, 0xd9, + 0xfb, 0x54, 0x05, 0xae, 0xf8, 0x91, 0x15, 0x9c, 0x99, 0x91, 0x94, 0x8b, + 0x98, 0x8b, 0x9f, 0x7a, 0x9b, 0x77, 0x8b, 0x81, 0x8b, 0x83, 0x87, 0x7d, + 0x80, 0x08, 0xfb, 0x1a, 0xfb, 0x04, 0x05, 0x7d, 0x7f, 0x83, 0x7f, 0x8b, + 0x7f, 0x8b, 0x78, 0x9c, 0x7a, 0x9f, 0x8b, 0x94, 0x8b, 0x93, 0x8f, 0x99, + 0x97, 0x08, 0xf7, 0x1a, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x34, 0xf7, 0x32, + 0x15, 0xa2, 0x51, 0x74, 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, + 0x94, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x1f, 0x06, 0xa0, 0x8b, + 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7e, 0x94, 0x81, 0x93, 0x82, 0x8d, 0x6f, 0x8b, 0x08, 0xfb, + 0x5b, 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xca, 0x8b, 0xfb, 0x2f, + 0xfc, 0x13, 0x05, 0x72, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x19, 0x06, + 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, + 0x08, 0x74, 0x8b, 0xa2, 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x62, 0xef, 0x15, + 0xfb, 0x31, 0x8b, 0xda, 0xf7, 0x54, 0xd9, 0xfb, 0x54, 0x05, 0xfb, 0x39, + 0xf8, 0xca, 0x15, 0x7c, 0x97, 0x85, 0x8e, 0x80, 0x8b, 0x76, 0x8b, 0x7b, + 0x7b, 0x8b, 0x77, 0x8b, 0x7e, 0x91, 0x81, 0x9b, 0x7e, 0x08, 0xf7, 0x1a, + 0xfb, 0x03, 0x05, 0x98, 0x80, 0x95, 0x86, 0x94, 0x8b, 0xa0, 0x8b, 0x9c, + 0x9c, 0x8b, 0x9e, 0x8b, 0x97, 0x85, 0x95, 0x79, 0x99, 0x08, 0xfb, 0x19, + 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0x34, 0xf7, 0x32, 0x15, 0xa2, 0x51, 0x74, + 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x97, 0x88, + 0xa3, 0x8b, 0x08, 0xf7, 0x1f, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x94, + 0x81, 0x93, 0x82, 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x5b, 0xf8, 0x77, 0xfb, + 0x6c, 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, + 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x95, 0x84, 0x95, + 0x89, 0xa5, 0x8b, 0x08, 0xca, 0x8b, 0xfb, 0x2f, 0xfc, 0x13, 0x05, 0x72, + 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, + 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x19, 0x06, 0xa0, 0x8b, 0x98, 0x8d, + 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, + 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x74, 0x8b, 0xa2, + 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x62, 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xda, + 0xf7, 0x54, 0xd9, 0xfb, 0x54, 0x05, 0x30, 0xf8, 0x80, 0x15, 0xf7, 0x04, + 0x2a, 0x05, 0x96, 0x82, 0x94, 0x87, 0x93, 0x8b, 0x9e, 0x8b, 0x9b, 0x9c, + 0x8b, 0x9e, 0x8b, 0x97, 0x87, 0x91, 0x7d, 0x97, 0x08, 0x85, 0x90, 0xfb, + 0x2b, 0xf7, 0x14, 0xfb, 0x2c, 0xfb, 0x14, 0x05, 0x75, 0x78, 0x89, 0x88, + 0x8b, 0x7d, 0x8b, 0x79, 0x9b, 0x7a, 0x9d, 0x8b, 0x95, 0x8b, 0x92, 0x8e, + 0x96, 0x95, 0x08, 0xf7, 0x06, 0xec, 0x05, 0x0e, 0xf8, 0x34, 0xf7, 0x32, + 0x15, 0xa2, 0x51, 0x74, 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, + 0x94, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x1f, 0x06, 0xa0, 0x8b, + 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7e, 0x94, 0x81, 0x93, 0x82, 0x8d, 0x6f, 0x8b, 0x08, 0xfb, + 0x5b, 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xca, 0x8b, 0xfb, 0x2f, + 0xfc, 0x13, 0x05, 0x72, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x19, 0x06, + 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, + 0x08, 0x74, 0x8b, 0xa2, 0xc5, 0x05, 0xf7, 0x82, 0x06, 0x62, 0xef, 0x15, + 0xfb, 0x31, 0x8b, 0xda, 0xf7, 0x54, 0xd9, 0xfb, 0x54, 0x05, 0xc8, 0xf8, + 0xb1, 0x15, 0x80, 0x8b, 0x7c, 0x81, 0x81, 0x7d, 0x73, 0x68, 0x87, 0x87, + 0x7b, 0x8b, 0x80, 0x8b, 0x7d, 0x91, 0x6a, 0x9f, 0x08, 0x5a, 0xa9, 0x79, + 0x92, 0x74, 0x8b, 0x6d, 0x8b, 0x6d, 0x7a, 0x72, 0x6c, 0x7a, 0x76, 0x83, + 0x7a, 0x8b, 0x7e, 0x8b, 0x7a, 0x99, 0x7e, 0x9c, 0x8b, 0x94, 0x8b, 0x94, + 0x8f, 0x90, 0x93, 0xab, 0xb5, 0x93, 0x91, 0x9d, 0x8b, 0x08, 0x99, 0x8b, + 0x94, 0x87, 0xa6, 0x7a, 0x08, 0xb7, 0x6f, 0xac, 0x7d, 0xa1, 0x8b, 0xa8, + 0x8b, 0xa3, 0x99, 0xa6, 0xad, 0xa0, 0xa5, 0x93, 0x9a, 0x8b, 0x9a, 0x8b, + 0x99, 0x7c, 0x99, 0x7a, 0x8b, 0x08, 0x0e, 0xf8, 0x34, 0xf7, 0x32, 0x15, + 0xa2, 0x51, 0x74, 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x1f, 0x06, 0xa0, 0x8b, 0x98, + 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x94, 0x81, 0x93, 0x82, 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x5b, + 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, + 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xca, 0x8b, 0xfb, 0x2f, 0xfc, + 0x13, 0x05, 0x72, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x08, 0x6a, 0xa1, 0x7a, 0xb7, 0x1e, 0xf7, 0x19, 0x06, 0xa0, + 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, + 0x74, 0x8b, 0xa2, 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x62, 0xef, 0x15, 0xfb, + 0x31, 0x8b, 0xda, 0xf7, 0x54, 0xd9, 0xfb, 0x54, 0x05, 0x2f, 0xf8, 0xf9, + 0x15, 0x48, 0x53, 0x54, 0x4a, 0x49, 0xc3, 0x54, 0xce, 0xcd, 0xc4, 0xc2, + 0xcb, 0xce, 0x54, 0xc2, 0x47, 0x1f, 0x56, 0x04, 0xb1, 0xab, 0x6c, 0x66, + 0x68, 0x6a, 0x6c, 0x66, 0x65, 0x6b, 0xaa, 0xaf, 0xaf, 0xab, 0xaa, 0xb1, + 0x1f, 0x0e, 0xf7, 0xe5, 0x7d, 0x15, 0xd0, 0x8f, 0xb8, 0x96, 0xb3, 0xa1, + 0xb7, 0xa4, 0xa8, 0xad, 0x8b, 0xa5, 0x8b, 0xa7, 0x74, 0xa2, 0x70, 0x8b, + 0x7e, 0x8b, 0x7f, 0x86, 0x80, 0x80, 0x70, 0x6f, 0x8b, 0x8b, 0x80, 0x85, + 0x72, 0x7c, 0x63, 0x83, 0x5d, 0x8b, 0x08, 0xfb, 0x0b, 0x3e, 0xcc, 0xef, + 0x1f, 0xcb, 0x07, 0xf5, 0xd5, 0xd7, 0xf1, 0x1e, 0xad, 0x8b, 0xaf, 0x82, + 0xa6, 0x7c, 0xa8, 0x7b, 0x95, 0x7e, 0x8f, 0x73, 0x90, 0x73, 0x8d, 0x84, + 0x93, 0x83, 0x93, 0x83, 0x99, 0x85, 0x98, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, + 0x95, 0x98, 0x92, 0x94, 0x8d, 0x96, 0x8b, 0xa4, 0x08, 0xdf, 0x07, 0x8b, + 0xa4, 0x8a, 0x93, 0x85, 0x94, 0x08, 0x82, 0x9a, 0x7b, 0x94, 0x79, 0x8b, + 0x7a, 0x8b, 0x7f, 0x85, 0x7e, 0x79, 0x08, 0x81, 0x8f, 0x05, 0x54, 0xa5, + 0x68, 0x93, 0x57, 0x8b, 0x08, 0xfb, 0x2f, 0xfb, 0x09, 0xfb, 0x0e, 0xfb, + 0x34, 0x1f, 0x49, 0x07, 0x8b, 0x39, 0xb1, 0x40, 0xcd, 0x5a, 0xb0, 0x70, + 0xad, 0x7e, 0xc6, 0x7f, 0x08, 0x2e, 0x07, 0x9c, 0x8d, 0x8f, 0x8b, 0x8f, + 0x8b, 0x08, 0xaa, 0x9e, 0x7e, 0x76, 0x7b, 0x7e, 0x82, 0x74, 0x1f, 0x7a, + 0x8b, 0x75, 0x91, 0x79, 0x96, 0x78, 0x95, 0x89, 0x8c, 0x83, 0x8b, 0x78, + 0x8b, 0x7b, 0x7b, 0x8b, 0x78, 0x8b, 0x7e, 0x92, 0x7f, 0x96, 0x83, 0xa6, + 0x79, 0xb5, 0x7f, 0xae, 0x8b, 0xc7, 0x8b, 0xb8, 0xb4, 0x8b, 0xc3, 0x08, + 0x8b, 0xbe, 0x73, 0xa8, 0x58, 0x95, 0x08, 0xa7, 0x07, 0x0e, 0xd5, 0xf7, + 0x87, 0x15, 0xfb, 0x23, 0x07, 0x65, 0x74, 0x79, 0x6b, 0x1f, 0x8b, 0x7c, + 0x93, 0x7b, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, 0xa2, 0x8b, 0x08, 0xf7, + 0x61, 0x06, 0xe2, 0x8b, 0xc7, 0xa2, 0xbc, 0xbf, 0xb9, 0xbb, 0xa3, 0xc9, + 0x8b, 0xd4, 0x08, 0xba, 0x07, 0xf7, 0x31, 0xfb, 0x04, 0xf7, 0x0d, 0xfb, + 0x26, 0x1e, 0xfb, 0x68, 0x06, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x08, 0x6b, 0xa1, 0x79, 0xb2, 0x1e, 0xfb, + 0x20, 0x84, 0x07, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x98, + 0x88, 0xa2, 0x8b, 0x08, 0x93, 0x06, 0xef, 0x16, 0xd5, 0x06, 0xb7, 0xa1, + 0x9c, 0xac, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x83, + 0x8d, 0x70, 0x8b, 0x08, 0x41, 0xf7, 0x20, 0xf7, 0x02, 0x06, 0xc0, 0x8b, + 0xb1, 0x7b, 0xa9, 0x68, 0xa8, 0x69, 0x9b, 0x5f, 0x8b, 0x5c, 0x08, 0x5d, + 0x07, 0x8b, 0x58, 0x7e, 0x68, 0x6f, 0x6c, 0x6c, 0x6b, 0x6a, 0x7f, 0x4f, + 0x8b, 0x08, 0xfb, 0x03, 0xf7, 0x23, 0x06, 0x0e, 0xf7, 0x56, 0xf7, 0x87, + 0x15, 0xe0, 0x84, 0x06, 0x8b, 0x73, 0x8d, 0x82, 0x90, 0x82, 0x94, 0x7c, + 0x9c, 0x82, 0x9c, 0x8b, 0x9a, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x94, + 0x8d, 0x95, 0x8b, 0xa5, 0x08, 0xf7, 0x05, 0x07, 0x8b, 0x94, 0x8b, 0x8e, + 0x8a, 0x94, 0x87, 0xa7, 0x79, 0x9d, 0x70, 0x8b, 0x7c, 0x8b, 0x7c, 0x83, + 0x81, 0x7e, 0x84, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, 0x84, 0x36, 0xf7, + 0x21, 0xf7, 0x7e, 0x59, 0x07, 0x8b, 0x73, 0x8d, 0x81, 0x90, 0x82, 0x95, + 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, + 0x95, 0x8d, 0x93, 0x8b, 0xa7, 0x08, 0xf7, 0x2a, 0xfc, 0x55, 0x07, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, + 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, + 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x84, 0x98, 0x88, 0xa2, 0x8b, 0x08, 0xf8, 0x6b, 0xf7, 0x2c, 0x06, 0x8b, + 0xa4, 0x89, 0x94, 0x86, 0x94, 0x81, 0x9a, 0x7b, 0x94, 0x7a, 0x8b, 0x7b, + 0x8b, 0x7c, 0x84, 0x81, 0x7d, 0x84, 0x81, 0x89, 0x83, 0x8b, 0x6f, 0x08, + 0x57, 0xfb, 0x94, 0x07, 0xf7, 0x23, 0x07, 0x84, 0xf8, 0xbf, 0x15, 0x6a, + 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0x1f, + 0xad, 0x71, 0xa6, 0x69, 0x1e, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, + 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, + 0x1f, 0x0e, 0xf7, 0x56, 0xf7, 0x87, 0x15, 0xe0, 0x84, 0x06, 0x8b, 0x73, + 0x8d, 0x82, 0x90, 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0x9a, 0x8b, + 0x9a, 0x93, 0x95, 0x98, 0x92, 0x94, 0x8d, 0x95, 0x8b, 0xa5, 0x08, 0xf7, + 0x05, 0x07, 0x8b, 0x94, 0x8b, 0x8e, 0x8a, 0x94, 0x87, 0xa7, 0x79, 0x9d, + 0x70, 0x8b, 0x7c, 0x8b, 0x7c, 0x83, 0x81, 0x7e, 0x84, 0x81, 0x89, 0x82, + 0x8b, 0x70, 0x08, 0x84, 0x36, 0xf7, 0x21, 0xf7, 0x7e, 0x59, 0x07, 0x8b, + 0x73, 0x8d, 0x81, 0x90, 0x82, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, + 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa7, 0x08, + 0xf7, 0x2a, 0xfc, 0x55, 0x07, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, + 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, + 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, + 0xf8, 0x6b, 0xf7, 0x2c, 0x06, 0x8b, 0xa4, 0x89, 0x94, 0x86, 0x94, 0x81, + 0x9a, 0x7b, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x84, 0x81, 0x7d, 0x84, + 0x81, 0x89, 0x83, 0x8b, 0x6f, 0x08, 0x57, 0xfb, 0x94, 0x07, 0xf7, 0x23, + 0x07, 0xf7, 0x74, 0xf8, 0xa0, 0x15, 0x9c, 0x99, 0x91, 0x94, 0x8b, 0x98, + 0x8b, 0x9f, 0x7b, 0x9b, 0x76, 0x8b, 0x81, 0x8b, 0x83, 0x87, 0x7d, 0x80, + 0x08, 0xfb, 0x1a, 0xfb, 0x04, 0x05, 0x7b, 0x7e, 0x84, 0x80, 0x8b, 0x7f, + 0x8b, 0x78, 0x9c, 0x7a, 0x9f, 0x8b, 0x95, 0x8b, 0x94, 0x90, 0x98, 0x96, + 0x08, 0xf7, 0x1a, 0xf7, 0x03, 0x05, 0x0e, 0xf7, 0x56, 0xf7, 0x87, 0x15, + 0xe0, 0x84, 0x06, 0x8b, 0x73, 0x8d, 0x82, 0x90, 0x82, 0x94, 0x7c, 0x9c, + 0x82, 0x9c, 0x8b, 0x9a, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x94, 0x8d, + 0x95, 0x8b, 0xa5, 0x08, 0xf7, 0x05, 0x07, 0x8b, 0x94, 0x8b, 0x8e, 0x8a, + 0x94, 0x87, 0xa7, 0x79, 0x9d, 0x70, 0x8b, 0x7c, 0x8b, 0x7c, 0x83, 0x81, + 0x7e, 0x84, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, 0x84, 0x36, 0xf7, 0x21, + 0xf7, 0x7e, 0x59, 0x07, 0x8b, 0x73, 0x8d, 0x81, 0x90, 0x82, 0x95, 0x7c, + 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, + 0x8d, 0x93, 0x8b, 0xa7, 0x08, 0xf7, 0x2a, 0xfc, 0x55, 0x07, 0x71, 0x8b, + 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0x9a, + 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x81, + 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, + 0x98, 0x88, 0xa2, 0x8b, 0x08, 0xf8, 0x6b, 0xf7, 0x2c, 0x06, 0x8b, 0xa4, + 0x89, 0x94, 0x86, 0x94, 0x81, 0x9a, 0x7b, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, + 0x7c, 0x84, 0x81, 0x7d, 0x84, 0x81, 0x89, 0x83, 0x8b, 0x6f, 0x08, 0x57, + 0xfb, 0x94, 0x07, 0xf7, 0x23, 0x07, 0x9c, 0xf8, 0xd9, 0x15, 0x7d, 0x96, + 0x83, 0x8f, 0x81, 0x8b, 0x76, 0x8b, 0x7b, 0x7b, 0x8b, 0x77, 0x8b, 0x7e, + 0x91, 0x82, 0x9c, 0x7d, 0x08, 0xf7, 0x1a, 0xfb, 0x03, 0x05, 0x98, 0x80, + 0x94, 0x86, 0x95, 0x8b, 0x9f, 0x8b, 0x9c, 0x9c, 0x8b, 0x9e, 0x8b, 0x97, + 0x84, 0x96, 0x7b, 0x98, 0x08, 0xfb, 0x1a, 0xf7, 0x04, 0x05, 0x0e, 0xf7, + 0x56, 0xf7, 0x87, 0x15, 0xe0, 0x84, 0x06, 0x8b, 0x73, 0x8d, 0x82, 0x90, + 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0x9a, 0x8b, 0x9a, 0x93, 0x95, + 0x98, 0x92, 0x94, 0x8d, 0x95, 0x8b, 0xa5, 0x08, 0xf7, 0x05, 0x07, 0x8b, + 0x94, 0x8b, 0x8e, 0x8a, 0x94, 0x87, 0xa7, 0x79, 0x9d, 0x70, 0x8b, 0x7c, + 0x8b, 0x7c, 0x83, 0x81, 0x7e, 0x84, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, + 0x84, 0x36, 0xf7, 0x21, 0xf7, 0x7e, 0x59, 0x07, 0x8b, 0x73, 0x8d, 0x81, + 0x90, 0x82, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, + 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa7, 0x08, 0xf7, 0x2a, 0xfc, + 0x55, 0x07, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, + 0xa4, 0x8b, 0x08, 0x9a, 0xfc, 0x13, 0x7c, 0x06, 0x73, 0x8b, 0x82, 0x8a, + 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, 0xa2, 0x8b, 0x08, 0xf8, 0x6b, 0xf7, + 0x2c, 0x06, 0x8b, 0xa4, 0x89, 0x94, 0x86, 0x94, 0x81, 0x9a, 0x7b, 0x94, + 0x7a, 0x8b, 0x7b, 0x8b, 0x7c, 0x84, 0x81, 0x7d, 0x84, 0x81, 0x89, 0x83, + 0x8b, 0x6f, 0x08, 0x57, 0xfb, 0x94, 0x07, 0xf7, 0x23, 0x07, 0xed, 0xf8, + 0x8f, 0x15, 0xf7, 0x04, 0x2a, 0x05, 0x96, 0x82, 0x94, 0x87, 0x93, 0x8b, + 0x9e, 0x8b, 0x9b, 0x9c, 0x8b, 0x9e, 0x8b, 0x98, 0x89, 0x8e, 0x75, 0x9e, + 0x08, 0xfb, 0x2b, 0xf7, 0x14, 0xfb, 0x2c, 0xfb, 0x14, 0x05, 0x75, 0x78, + 0x89, 0x88, 0x8b, 0x7e, 0x8b, 0x78, 0x9b, 0x7a, 0x9e, 0x8b, 0x94, 0x8b, + 0x92, 0x8e, 0x97, 0x95, 0x08, 0xf7, 0x05, 0xec, 0x05, 0x0e, 0xf7, 0xf2, + 0xf8, 0x77, 0x15, 0xf0, 0x06, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0xc2, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, + 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf0, 0xfc, + 0x13, 0x26, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x84, 0x97, + 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0xc2, 0x06, 0xb7, 0xa1, 0x9c, 0xac, 0x1f, + 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, + 0x08, 0x26, 0x06, 0xf8, 0x13, 0x07, 0xfb, 0x2e, 0xf7, 0xcf, 0x15, 0x6a, + 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0x1f, + 0xad, 0x71, 0xa6, 0x69, 0x1e, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, + 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, + 0x1f, 0x0e, 0xf7, 0xf2, 0xf8, 0x77, 0x15, 0xf0, 0x06, 0xa2, 0x8b, 0x96, + 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, + 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0xc2, + 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, + 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, + 0x8b, 0x08, 0xf0, 0xfc, 0x13, 0x26, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, + 0x82, 0x94, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0xc2, 0x06, 0xb7, + 0xa1, 0x9c, 0xac, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x26, 0xf8, 0x13, 0x06, 0xf1, 0xf7, 0xb0, + 0x15, 0x9c, 0x98, 0x91, 0x95, 0x8b, 0x98, 0x8b, 0x9f, 0x7b, 0x9b, 0x76, + 0x8b, 0x81, 0x8b, 0x83, 0x87, 0x7d, 0x80, 0x08, 0xfb, 0x19, 0xfb, 0x04, + 0x05, 0x7b, 0x7f, 0x84, 0x7f, 0x8b, 0x7f, 0x8b, 0x78, 0x9c, 0x7a, 0x9f, + 0x8b, 0x94, 0x8b, 0x95, 0x90, 0x98, 0x96, 0x08, 0xf7, 0x19, 0xf7, 0x03, + 0x05, 0x0e, 0xf7, 0xf2, 0xf8, 0x77, 0x15, 0xf0, 0x06, 0xa2, 0x8b, 0x96, + 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, + 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0xc2, + 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, + 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, + 0x8b, 0x08, 0xf0, 0xfc, 0x13, 0x26, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, + 0x82, 0x94, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0xc2, 0x06, 0xb7, + 0xa1, 0x9c, 0xac, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x26, 0xf8, 0x13, 0x06, 0xfb, 0x16, 0xf7, + 0xe9, 0x15, 0x7c, 0x97, 0x85, 0x8e, 0x80, 0x8b, 0x76, 0x8b, 0x7b, 0x7b, + 0x8b, 0x77, 0x8b, 0x7e, 0x91, 0x81, 0x9b, 0x7e, 0x08, 0xf7, 0x1a, 0xfb, + 0x03, 0x05, 0x98, 0x80, 0x95, 0x86, 0x94, 0x8b, 0xa0, 0x8b, 0x9c, 0x9c, + 0x8b, 0x9e, 0x8b, 0x97, 0x85, 0x95, 0x79, 0x99, 0x08, 0xfb, 0x19, 0xf7, + 0x04, 0x05, 0x0e, 0xf7, 0xf2, 0xf8, 0x77, 0x15, 0xf0, 0x06, 0xa2, 0x8b, + 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x84, 0x9a, 0x7d, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, + 0xc2, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, + 0xa4, 0x8b, 0x08, 0xf0, 0xfc, 0x13, 0x26, 0x06, 0x71, 0x8b, 0x84, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, + 0x98, 0x82, 0x94, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0xc2, 0x06, + 0xb7, 0xa1, 0x9c, 0xac, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x26, 0xf8, 0x13, 0x06, 0x5a, 0xf7, + 0x9f, 0x15, 0xf7, 0x04, 0x2a, 0x05, 0x96, 0x82, 0x93, 0x87, 0x94, 0x8b, + 0x9e, 0x8b, 0x9b, 0x9c, 0x8b, 0x9e, 0x8b, 0x96, 0x87, 0x92, 0x80, 0x94, + 0x87, 0x8e, 0x88, 0x8e, 0x89, 0x8d, 0x08, 0xfb, 0x2b, 0xf7, 0x14, 0xfb, + 0x2d, 0xfb, 0x14, 0x82, 0x83, 0x05, 0x80, 0x82, 0x87, 0x84, 0x8b, 0x80, + 0x8b, 0x78, 0x9b, 0x7a, 0x9e, 0x8b, 0x94, 0x8b, 0x93, 0x8e, 0x96, 0x95, + 0x08, 0xf7, 0x06, 0xec, 0x05, 0x0e, 0xf7, 0x41, 0xf8, 0x1e, 0x15, 0xf7, + 0x97, 0xfc, 0x1e, 0xee, 0x8b, 0x8b, 0xf8, 0x77, 0x05, 0xb3, 0xa0, 0x9d, + 0xab, 0x1f, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x70, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, + 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0xb8, 0x06, 0xfb, + 0x96, 0xf8, 0x1c, 0xfb, 0x07, 0x8b, 0x05, 0x71, 0x8b, 0x84, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, + 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0x9a, 0xfc, 0x13, 0x06, + 0x64, 0x75, 0x79, 0x6b, 0x1f, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x84, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x15, 0x06, 0x9f, 0x8b, 0x9a, + 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x68, 0x06, + 0xf7, 0xba, 0x07, 0xf7, 0xaa, 0xf8, 0x29, 0x15, 0x7e, 0x8a, 0x7f, 0x82, + 0x7e, 0x78, 0x75, 0x6d, 0x87, 0x87, 0x7c, 0x8b, 0x80, 0x8b, 0x7c, 0x92, + 0x6b, 0x9e, 0x08, 0x59, 0xa9, 0x7a, 0x92, 0x73, 0x8b, 0x6e, 0x8b, 0x6e, + 0x7b, 0x72, 0x6d, 0x7a, 0x76, 0x82, 0x79, 0x8b, 0x7d, 0x8b, 0x7a, 0x99, + 0x7e, 0x9c, 0x8b, 0x95, 0x8b, 0x93, 0x90, 0x92, 0x94, 0xa9, 0xb3, 0x93, + 0x91, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x94, 0x88, 0xa6, 0x79, 0x08, 0xb7, + 0x6f, 0xac, 0x7d, 0xa1, 0x8b, 0xa8, 0x8b, 0xa3, 0x99, 0xa6, 0xad, 0xa0, + 0xa5, 0x93, 0x9a, 0x8b, 0x9a, 0x8b, 0x9a, 0x7e, 0x96, 0x77, 0x8d, 0x08, + 0x0e, 0xf7, 0xc0, 0xf8, 0xe9, 0x15, 0xfb, 0x2e, 0xfb, 0x11, 0xfb, 0x1d, + 0xfb, 0x3c, 0xfb, 0x3d, 0xf7, 0x11, 0xfb, 0x1d, 0xf7, 0x2e, 0xf7, 0x2c, + 0xf7, 0x13, 0xf7, 0x1d, 0xf7, 0x38, 0x1f, 0x8b, 0xeb, 0x6c, 0xd8, 0x4c, + 0xc7, 0x56, 0xbd, 0x4a, 0xa6, 0x48, 0x8b, 0x08, 0x27, 0x04, 0xee, 0xdb, + 0x2e, 0xfb, 0x07, 0xfb, 0x02, 0x39, 0x2e, 0x2a, 0x29, 0x3a, 0xe8, 0xf7, + 0x05, 0xf7, 0x04, 0xdc, 0xe8, 0xed, 0x1f, 0x23, 0xf7, 0xc1, 0x15, 0x6a, + 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, + 0x71, 0xa6, 0x69, 0x1f, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, + 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, + 0x0e, 0xf7, 0xc0, 0xf8, 0xe9, 0x15, 0xfb, 0x2e, 0xfb, 0x11, 0xfb, 0x1d, + 0xfb, 0x3c, 0xfb, 0x3d, 0xf7, 0x11, 0xfb, 0x1d, 0xf7, 0x2e, 0xf7, 0x2c, + 0xf7, 0x13, 0xf7, 0x1d, 0xf7, 0x38, 0x1f, 0x8b, 0xeb, 0x6c, 0xd8, 0x4c, + 0xc7, 0x56, 0xbd, 0x4a, 0xa6, 0x48, 0x8b, 0x08, 0x27, 0x04, 0xee, 0xdb, + 0x2e, 0xfb, 0x07, 0xfb, 0x02, 0x39, 0x2e, 0x2a, 0x29, 0x3a, 0xe8, 0xf7, + 0x05, 0xf7, 0x04, 0xdc, 0xe8, 0xed, 0x1f, 0xf7, 0x0f, 0xf7, 0xa2, 0x15, + 0x9e, 0x9a, 0x90, 0x93, 0x8b, 0x98, 0x8b, 0x9f, 0x7a, 0x9b, 0x77, 0x8b, + 0x80, 0x8b, 0x83, 0x87, 0x7d, 0x80, 0x08, 0xfb, 0x1a, 0xfb, 0x04, 0x05, + 0x7c, 0x7f, 0x84, 0x7f, 0x8b, 0x7f, 0x8b, 0x78, 0x9c, 0x7a, 0x9f, 0x8b, + 0x94, 0x8b, 0x94, 0x8f, 0x98, 0x97, 0x08, 0xf7, 0x1a, 0xf7, 0x03, 0x05, + 0x0e, 0xf7, 0xc0, 0xf8, 0xe9, 0x15, 0xfb, 0x2e, 0xfb, 0x11, 0xfb, 0x1d, + 0xfb, 0x3c, 0xfb, 0x3d, 0xf7, 0x11, 0xfb, 0x1d, 0xf7, 0x2e, 0xf7, 0x2c, + 0xf7, 0x13, 0xf7, 0x1d, 0xf7, 0x38, 0x1f, 0x8b, 0xeb, 0x6c, 0xd8, 0x4c, + 0xc7, 0x56, 0xbd, 0x4a, 0xa6, 0x48, 0x8b, 0x08, 0x27, 0x04, 0xee, 0xdb, + 0x2e, 0xfb, 0x07, 0xfb, 0x02, 0x39, 0x2e, 0x2a, 0x29, 0x3a, 0xe8, 0xf7, + 0x05, 0xf7, 0x04, 0xdc, 0xe8, 0xed, 0x1f, 0x3e, 0xf7, 0xdb, 0x15, 0x7c, + 0x97, 0x85, 0x8e, 0x80, 0x8b, 0x76, 0x8b, 0x7b, 0x7b, 0x8b, 0x77, 0x8b, + 0x7e, 0x91, 0x82, 0x9c, 0x7d, 0x08, 0xf7, 0x1a, 0xfb, 0x03, 0x05, 0x97, + 0x80, 0x95, 0x86, 0x95, 0x8b, 0x9f, 0x8b, 0x9c, 0x9c, 0x8b, 0x9e, 0x8b, + 0x97, 0x85, 0x95, 0x7a, 0x99, 0x08, 0xfb, 0x1a, 0xf7, 0x04, 0x05, 0x0e, + 0xf7, 0xc0, 0xf8, 0xe9, 0x15, 0xfb, 0x2e, 0xfb, 0x11, 0xfb, 0x1d, 0xfb, + 0x3c, 0xfb, 0x3d, 0xf7, 0x11, 0xfb, 0x1d, 0xf7, 0x2e, 0xf7, 0x2c, 0xf7, + 0x13, 0xf7, 0x1d, 0xf7, 0x38, 0x1f, 0x8b, 0xeb, 0x6c, 0xd8, 0x4c, 0xc7, + 0x56, 0xbd, 0x4a, 0xa6, 0x48, 0x8b, 0x08, 0x27, 0x04, 0xee, 0xdb, 0x2e, + 0xfb, 0x07, 0xfb, 0x02, 0x39, 0x2e, 0x2a, 0x29, 0x3a, 0xe8, 0xf7, 0x05, + 0xf7, 0x04, 0xdc, 0xe8, 0xed, 0x1f, 0x8c, 0xf7, 0x91, 0x15, 0xf7, 0x04, + 0x2a, 0x05, 0x96, 0x82, 0x93, 0x87, 0x94, 0x8b, 0x9e, 0x8b, 0x9b, 0x9c, + 0x8b, 0x9d, 0x8b, 0x99, 0x89, 0x8e, 0x75, 0x9e, 0x08, 0xfb, 0x2b, 0xf7, + 0x14, 0xfb, 0x2d, 0xfb, 0x14, 0x83, 0x84, 0x05, 0x7f, 0x81, 0x87, 0x84, + 0x8b, 0x80, 0x8b, 0x78, 0x9b, 0x7a, 0x9e, 0x8b, 0x94, 0x8b, 0x93, 0x8e, + 0x96, 0x95, 0x08, 0xf7, 0x06, 0xec, 0x05, 0x0e, 0xf7, 0xc0, 0xf8, 0xe9, + 0x15, 0xfb, 0x2e, 0xfb, 0x11, 0xfb, 0x1d, 0xfb, 0x3c, 0xfb, 0x3d, 0xf7, + 0x11, 0xfb, 0x1d, 0xf7, 0x2e, 0xf7, 0x2c, 0xf7, 0x13, 0xf7, 0x1d, 0xf7, + 0x38, 0x1f, 0x8b, 0xeb, 0x6c, 0xd8, 0x4c, 0xc7, 0x08, 0x56, 0xbd, 0x4a, + 0xa6, 0x48, 0x8b, 0x08, 0x27, 0x04, 0xee, 0xdb, 0x2e, 0xfb, 0x07, 0xfb, + 0x02, 0x39, 0x2e, 0x2a, 0x29, 0x3a, 0xe8, 0xf7, 0x05, 0xf7, 0x04, 0xdc, + 0xe8, 0xed, 0x1f, 0xf7, 0x34, 0xf7, 0xc2, 0x15, 0x7f, 0x8b, 0x7e, 0x81, + 0x7d, 0x78, 0x75, 0x6c, 0x87, 0x88, 0x7c, 0x8b, 0x80, 0x8b, 0x7d, 0x91, + 0x6a, 0x9f, 0x08, 0x5a, 0xa9, 0x79, 0x92, 0x74, 0x8b, 0x6e, 0x8b, 0x6e, + 0x7c, 0x73, 0x6d, 0x79, 0x76, 0x81, 0x78, 0x8b, 0x7d, 0x8b, 0x7b, 0x99, + 0x7d, 0x9c, 0x8b, 0x94, 0x8b, 0x94, 0x90, 0x90, 0x92, 0xab, 0xb5, 0x93, + 0x91, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x94, 0x88, 0xa6, 0x79, 0x08, 0xb7, + 0x6f, 0xac, 0x7d, 0xa1, 0x8b, 0xa8, 0x8b, 0xa3, 0x99, 0xa6, 0xad, 0xa0, + 0xa5, 0x93, 0x9a, 0x8b, 0x9a, 0x8b, 0x99, 0x7c, 0x99, 0x7a, 0x8b, 0x08, + 0x0e, 0xf7, 0xce, 0xf9, 0x6d, 0x15, 0xfb, 0x06, 0xec, 0x05, 0x7f, 0x95, + 0x85, 0x8e, 0x82, 0x8b, 0x78, 0x8b, 0x7b, 0x7a, 0x8b, 0x79, 0x8b, 0x7d, + 0x8e, 0x87, 0xa0, 0x79, 0x08, 0xf7, 0x2c, 0xfb, 0x14, 0xf7, 0x2b, 0xf7, + 0x14, 0x05, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x96, 0x94, 0x8f, 0x92, + 0x8b, 0x96, 0x8b, 0x9e, 0x7b, 0x9c, 0x78, 0x8b, 0x82, 0x8b, 0x83, 0x87, + 0x80, 0x82, 0x08, 0xfb, 0x04, 0x2a, 0x05, 0xf7, 0x5f, 0xfb, 0x5a, 0x15, + 0x8b, 0xa5, 0x8a, 0x93, 0x85, 0x94, 0x83, 0x99, 0x7a, 0x94, 0x7a, 0x8b, + 0x77, 0x8b, 0x82, 0x83, 0x81, 0x72, 0x68, 0xa1, 0x5f, 0x96, 0x58, 0x8b, + 0xfb, 0x10, 0x8b, 0x2e, 0x3f, 0x8b, 0x26, 0x8b, 0x52, 0xaa, 0x56, 0xbe, + 0x6e, 0x08, 0xab, 0x79, 0xab, 0x81, 0xcc, 0x80, 0xcf, 0x7f, 0x9b, 0x87, + 0xa0, 0x80, 0xa1, 0x7f, 0x99, 0x77, 0x8b, 0x76, 0x8b, 0x60, 0x51, 0x6a, + 0x41, 0x8b, 0x49, 0x8b, 0x4c, 0xa8, 0x81, 0xaf, 0x83, 0xa6, 0x8b, 0x8b, + 0x84, 0x92, 0x08, 0x82, 0x94, 0x7e, 0x90, 0x7d, 0x8b, 0x7b, 0x8b, 0x7c, + 0x84, 0x81, 0x7e, 0x84, 0x81, 0x89, 0x80, 0x8b, 0x72, 0x08, 0x49, 0x07, + 0x5e, 0x9b, 0x76, 0xae, 0x1e, 0x9b, 0x8b, 0x92, 0x8f, 0x9c, 0x9f, 0xbc, + 0x71, 0xc0, 0x7e, 0xc1, 0x8b, 0xf7, 0x1d, 0x8b, 0xe7, 0xd1, 0x8b, 0xf3, + 0x8b, 0xbf, 0x78, 0xb4, 0x63, 0xab, 0x6c, 0xa4, 0x65, 0x99, 0x34, 0x9b, + 0x40, 0x99, 0x86, 0x8d, 0x77, 0x95, 0x08, 0x75, 0x96, 0x7c, 0xa2, 0x8b, + 0xa0, 0x8b, 0xb6, 0xbd, 0xac, 0xca, 0x8b, 0xc9, 0x8b, 0xbb, 0x70, 0x94, + 0x63, 0x92, 0x6b, 0x8b, 0x8b, 0x92, 0x83, 0x93, 0x83, 0x99, 0x85, 0x99, + 0x8b, 0x9a, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x08, 0x92, 0x95, 0x8d, 0x93, + 0x8b, 0xa7, 0x08, 0xe3, 0x07, 0x0e, 0xf8, 0xa5, 0xf8, 0x77, 0x15, 0xb3, + 0xa0, 0x9d, 0xab, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, 0x80, 0x92, + 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x71, 0x8b, 0x84, 0x8a, + 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x98, 0x81, 0x94, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xae, 0xfb, 0xb3, + 0x06, 0x4e, 0x51, 0x5a, 0x44, 0x44, 0x51, 0xbc, 0xc8, 0x1e, 0xf7, 0xb3, + 0xae, 0x07, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x80, 0x93, 0x84, 0x8c, + 0x6f, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x6b, 0xa0, 0x7a, 0xb3, 0x8a, + 0x08, 0xfb, 0xaa, 0x07, 0x8b, 0x44, 0xa7, 0x53, 0xc3, 0x60, 0xb6, 0x6a, + 0xbb, 0x7b, 0xc1, 0x8b, 0xc2, 0x8b, 0xba, 0x9b, 0xb6, 0xac, 0xc4, 0xb6, + 0xa6, 0xc3, 0x8b, 0xd2, 0x08, 0xf7, 0xaa, 0x07, 0xfb, 0xe1, 0xf7, 0xcf, + 0x15, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, + 0xab, 0x1f, 0xad, 0x71, 0xa6, 0x69, 0x1e, 0xf7, 0x64, 0x16, 0x6a, 0x70, + 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, + 0xa6, 0x69, 0x1f, 0x0e, 0xf8, 0xa5, 0xf8, 0x77, 0x15, 0xb3, 0xa0, 0x9d, + 0xab, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, 0x80, 0x92, 0x83, 0x8d, + 0x70, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, + 0x94, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xae, 0xfb, 0xb3, 0x06, 0x4e, + 0x51, 0x5a, 0x44, 0x44, 0x51, 0xbc, 0xc8, 0x1e, 0xf7, 0xb3, 0xae, 0x07, + 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x80, 0x93, 0x84, 0x8c, 0x6f, 0x8b, + 0x08, 0xfb, 0x16, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x6b, 0xa0, 0x7a, 0xb3, 0x8a, 0x08, 0xfb, + 0xaa, 0x07, 0x8b, 0x44, 0xa7, 0x53, 0xc3, 0x60, 0xb6, 0x6a, 0xbb, 0x7b, + 0xc1, 0x8b, 0xc2, 0x8b, 0xba, 0x9b, 0xb6, 0xac, 0xc4, 0xb6, 0xa6, 0xc3, + 0x8b, 0xd2, 0x08, 0xf7, 0xaa, 0x07, 0x21, 0xf7, 0xb0, 0x15, 0x9e, 0x9a, + 0x90, 0x93, 0x8b, 0x98, 0x8b, 0x9f, 0x7a, 0x9b, 0x77, 0x8b, 0x80, 0x8b, + 0x83, 0x87, 0x7d, 0x80, 0x08, 0xfb, 0x1a, 0xfb, 0x04, 0x05, 0x7c, 0x7f, + 0x84, 0x7f, 0x8b, 0x7f, 0x8b, 0x78, 0x9c, 0x7a, 0x9f, 0x8b, 0x94, 0x8b, + 0x94, 0x8f, 0x98, 0x97, 0x08, 0xf7, 0x1a, 0xf7, 0x03, 0x05, 0x0e, 0xf8, + 0xa5, 0xf8, 0x77, 0x15, 0xb3, 0xa0, 0x9d, 0xab, 0x1f, 0x8b, 0x9b, 0x84, + 0x9a, 0x7e, 0x95, 0x80, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x16, + 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, + 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x95, 0x89, 0xa5, + 0x8b, 0x08, 0xae, 0xfb, 0xb3, 0x06, 0x4e, 0x51, 0x5a, 0x44, 0x44, 0x51, + 0xbc, 0xc8, 0x1e, 0xf7, 0xb3, 0xae, 0x07, 0xa2, 0x8b, 0x96, 0x8d, 0x93, + 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, + 0x95, 0x80, 0x93, 0x84, 0x8c, 0x6f, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x72, + 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x6b, 0xa0, 0x7a, 0xb3, 0x8a, 0x08, 0xfb, 0xaa, 0x07, 0x8b, 0x44, 0xa7, + 0x53, 0xc3, 0x60, 0xb6, 0x6a, 0xbb, 0x7b, 0xc1, 0x8b, 0xc2, 0x8b, 0xba, + 0x9b, 0xb6, 0xac, 0xc4, 0xb6, 0xa6, 0xc3, 0x8b, 0xd2, 0x08, 0xf7, 0xaa, + 0x07, 0xfb, 0xc6, 0xf7, 0xe9, 0x15, 0x7c, 0x97, 0x85, 0x8e, 0x80, 0x8b, + 0x76, 0x8b, 0x7b, 0x7b, 0x8b, 0x77, 0x8b, 0x7e, 0x91, 0x82, 0x9c, 0x7d, + 0x08, 0xf7, 0x1a, 0xfb, 0x03, 0x05, 0x97, 0x80, 0x95, 0x86, 0x95, 0x8b, + 0x9f, 0x8b, 0x9c, 0x9c, 0x8b, 0x9e, 0x8b, 0x97, 0x85, 0x95, 0x7a, 0x99, + 0x08, 0xfb, 0x1a, 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0xa5, 0xf8, 0x77, 0x15, + 0xb3, 0xa0, 0x9d, 0xab, 0x1f, 0x8b, 0x9b, 0x84, 0x9a, 0x7e, 0x95, 0x80, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, + 0x7c, 0x98, 0x81, 0x94, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0xae, 0xfb, + 0xb3, 0x06, 0x4e, 0x51, 0x5a, 0x44, 0x44, 0x51, 0xbc, 0xc8, 0x1e, 0xf7, + 0xb3, 0xae, 0x07, 0xa2, 0x8b, 0x96, 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x80, 0x93, 0x84, + 0x8c, 0x6f, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x6b, 0xa0, 0x7a, 0xb3, + 0x8a, 0x08, 0xfb, 0xaa, 0x07, 0x8b, 0x44, 0xa7, 0x53, 0xc3, 0x60, 0xb6, + 0x6a, 0xbb, 0x7b, 0xc1, 0x8b, 0xc2, 0x8b, 0xba, 0x9b, 0xb6, 0xac, 0xc4, + 0xb6, 0xa6, 0xc3, 0x8b, 0xd2, 0x08, 0xf7, 0xaa, 0x07, 0xfb, 0x78, 0xf7, + 0x9f, 0x15, 0xf7, 0x04, 0x2a, 0x05, 0x96, 0x82, 0x93, 0x87, 0x94, 0x8b, + 0x9e, 0x8b, 0x9b, 0x9c, 0x8b, 0x9e, 0x8b, 0x96, 0x87, 0x92, 0x80, 0x94, + 0x87, 0x8e, 0x87, 0x8e, 0x8a, 0x8d, 0x08, 0xfb, 0x2b, 0xf7, 0x14, 0xfb, + 0x2d, 0xfb, 0x14, 0x05, 0x89, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x7d, 0x7f, + 0x87, 0x85, 0x8b, 0x7f, 0x8b, 0x77, 0x9b, 0x7b, 0x9e, 0x8b, 0x94, 0x8b, + 0x93, 0x8e, 0x96, 0x95, 0x08, 0xf7, 0x06, 0xec, 0x05, 0x0e, 0xf7, 0xf2, + 0xf7, 0x89, 0x15, 0xf7, 0x38, 0xf7, 0x82, 0x8d, 0x8b, 0x05, 0xae, 0x87, + 0xa7, 0xa2, 0x8b, 0xaa, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x82, 0x92, + 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x2f, 0x06, 0x72, 0x8b, 0x82, 0x8a, 0x82, + 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x74, 0x98, 0x7b, 0xa6, + 0x81, 0x08, 0x2d, 0xfb, 0x1c, 0x2c, 0xf7, 0x1c, 0x05, 0xa5, 0x96, 0x97, + 0x9a, 0x8b, 0xa2, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, + 0x8d, 0x70, 0x8b, 0x08, 0x32, 0x06, 0x83, 0x8b, 0x8a, 0x8b, 0x7f, 0x89, + 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x08, 0x6b, 0xa2, 0x79, 0xb4, 0x1e, + 0xf7, 0x39, 0xfb, 0x82, 0x8b, 0xfb, 0x25, 0x4a, 0x8b, 0x05, 0x70, 0x8b, + 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x82, 0x94, 0x84, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, + 0x7a, 0x06, 0xa0, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, + 0x6f, 0x8b, 0x08, 0x4a, 0xf7, 0x25, 0x06, 0xd8, 0xf8, 0x9e, 0x15, 0x9d, + 0x9a, 0x90, 0x93, 0x8b, 0x98, 0x8b, 0x9f, 0x7a, 0x9b, 0x77, 0x8b, 0x80, + 0x8b, 0x83, 0x87, 0x7e, 0x80, 0x08, 0xfb, 0x1a, 0xfb, 0x04, 0x05, 0x7b, + 0x7e, 0x84, 0x80, 0x8b, 0x7f, 0x8b, 0x78, 0x9c, 0x7a, 0x9f, 0x8b, 0x94, + 0x8b, 0x94, 0x8f, 0x99, 0x97, 0x08, 0xf7, 0x1a, 0xf7, 0x03, 0x05, 0x0e, + 0xf7, 0x5d, 0xef, 0x15, 0xf7, 0xc3, 0xf8, 0x16, 0x8b, 0xec, 0xfc, 0x2c, + 0x8b, 0x8b, 0xfb, 0x3e, 0x05, 0x8b, 0x72, 0x8d, 0x83, 0x90, 0x82, 0x95, + 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, + 0x94, 0x8d, 0x94, 0x8b, 0xa6, 0x08, 0xd1, 0xf7, 0x47, 0x07, 0xfb, 0xc2, + 0xfc, 0x13, 0x8b, 0x27, 0xf8, 0x5a, 0x8b, 0x8b, 0xf7, 0x40, 0x05, 0x8b, + 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, + 0x8b, 0x7c, 0x83, 0x81, 0x7f, 0x84, 0x81, 0x89, 0x80, 0x8b, 0x72, 0x08, + 0x43, 0xfb, 0x76, 0x07, 0xef, 0xf9, 0x09, 0x15, 0xfb, 0x06, 0xec, 0x05, + 0x80, 0x94, 0x83, 0x8f, 0x82, 0x8b, 0x78, 0x8b, 0x7b, 0x7a, 0x8b, 0x79, + 0x8b, 0x7f, 0x8f, 0x84, 0x99, 0x7f, 0x8d, 0x8a, 0x8d, 0x89, 0x8d, 0x89, + 0x08, 0xf7, 0x2d, 0xfb, 0x14, 0xf7, 0x2b, 0xf7, 0x14, 0x05, 0x8c, 0x8d, + 0x8f, 0x8d, 0x8f, 0x8f, 0x96, 0x94, 0x8f, 0x92, 0x8b, 0x96, 0x8b, 0x9e, + 0x7b, 0x9c, 0x78, 0x8b, 0x82, 0x8b, 0x83, 0x87, 0x80, 0x82, 0x08, 0xfb, + 0x04, 0x2a, 0x05, 0x0e, 0xf7, 0x57, 0xf7, 0x20, 0x15, 0xed, 0x06, 0xf1, + 0x8b, 0xbf, 0x9b, 0xb4, 0xb8, 0xa1, 0xa3, 0x98, 0xad, 0x8b, 0xac, 0x8b, + 0xac, 0x7e, 0xac, 0x75, 0xa3, 0x62, 0xb8, 0x57, 0x9b, 0x25, 0x8b, 0x08, + 0x29, 0xb3, 0xee, 0x06, 0xa3, 0x8b, 0x94, 0x8c, 0x94, 0x91, 0x9a, 0x94, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x82, 0x91, + 0x7f, 0x8e, 0x73, 0x8b, 0x08, 0xfb, 0x6a, 0x06, 0x76, 0x8b, 0x7e, 0x89, + 0x83, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, + 0x98, 0x81, 0x95, 0x84, 0x93, 0x89, 0xa6, 0x8b, 0x08, 0x9a, 0xfc, 0x13, + 0x7c, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, + 0xa2, 0x8b, 0x08, 0xf7, 0x6a, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, + 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x28, 0xb3, 0x06, 0xef, 0x04, + 0xf2, 0xf7, 0x17, 0x07, 0xce, 0xa7, 0x7c, 0x66, 0x67, 0x6e, 0x7c, 0x49, + 0x1f, 0xfb, 0x17, 0x06, 0x0e, 0xf7, 0xf2, 0xf7, 0x89, 0x15, 0xf7, 0x38, + 0xf7, 0x82, 0x8d, 0x8b, 0x05, 0xae, 0x87, 0xa7, 0xa2, 0x8b, 0xaa, 0x8b, + 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x82, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, + 0x2f, 0x06, 0x72, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x74, 0x98, 0x7b, 0xa6, 0x81, 0x08, 0x2d, 0xfb, 0x1c, + 0x2c, 0xf7, 0x1c, 0x05, 0xa5, 0x96, 0x97, 0x9a, 0x8b, 0xa2, 0x8b, 0x9b, + 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x32, + 0x06, 0x83, 0x8b, 0x8a, 0x8b, 0x7f, 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, + 0x70, 0x08, 0x6b, 0xa2, 0x79, 0xb4, 0x1e, 0xf7, 0x39, 0xfb, 0x82, 0x8b, + 0xfb, 0x25, 0x4a, 0x8b, 0x05, 0x70, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x84, 0x98, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x7a, 0x06, 0xa0, 0x8b, 0x9a, + 0x8e, 0x92, 0x8f, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x6f, 0x8b, 0x08, 0x4a, 0x06, + 0xf7, 0x25, 0x07, 0xfb, 0x2e, 0xf8, 0xbd, 0x15, 0x6a, 0x70, 0x70, 0x6a, + 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0x1f, 0xad, 0x71, 0xa6, + 0x69, 0x1e, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, + 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0x0e, 0xf8, + 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa0, 0x8b, 0x99, 0x8d, 0x92, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, + 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x7b, 0xf7, 0x5e, 0x06, 0xe8, 0x41, + 0xc2, 0xfb, 0x0f, 0x1e, 0x59, 0x8b, 0x46, 0x7f, 0x59, 0x7a, 0x75, 0x83, + 0x80, 0x7d, 0x8b, 0x76, 0x8b, 0x6e, 0xa0, 0x75, 0xa7, 0x8b, 0x94, 0x8b, + 0x99, 0x8d, 0x9c, 0x8f, 0xb9, 0x97, 0xb0, 0x90, 0xac, 0x8b, 0x08, 0xcb, + 0xa8, 0x7c, 0x69, 0x1f, 0x74, 0x07, 0x62, 0x92, 0x6c, 0x8e, 0x6b, 0x8b, + 0x32, 0x8b, 0x46, 0x71, 0x5e, 0x59, 0x73, 0x70, 0x7c, 0x68, 0x8b, 0x6c, + 0x08, 0x41, 0xdc, 0x4e, 0xee, 0x1e, 0xc6, 0x8b, 0xc6, 0x99, 0xbb, 0xa4, + 0x08, 0x74, 0x07, 0x8c, 0xf7, 0x1b, 0x15, 0x54, 0x69, 0x53, 0x7a, 0x55, + 0x8b, 0x08, 0x60, 0x6a, 0x9c, 0xa1, 0xb1, 0xc9, 0xae, 0xcf, 0x1f, 0xad, + 0x8b, 0xb0, 0x87, 0xb3, 0x84, 0x08, 0x59, 0x07, 0xfb, 0x60, 0xf8, 0x9b, + 0x15, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, + 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, + 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, + 0x69, 0x1f, 0x0e, 0xf8, 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa0, 0x8b, 0x99, + 0x8d, 0x92, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x7b, 0xf7, + 0x5e, 0x06, 0xe8, 0x41, 0xc2, 0xfb, 0x0f, 0x1e, 0x59, 0x8b, 0x41, 0x7e, + 0x5b, 0x7a, 0x77, 0x84, 0x81, 0x7d, 0x8b, 0x76, 0x8b, 0x6e, 0xa0, 0x75, + 0xa7, 0x8b, 0x94, 0x8b, 0x99, 0x8d, 0x9c, 0x8f, 0xb9, 0x97, 0xb0, 0x90, + 0xac, 0x8b, 0x08, 0xcb, 0xa8, 0x7c, 0x69, 0x1f, 0x74, 0x07, 0x62, 0x92, + 0x6c, 0x8e, 0x6b, 0x8b, 0x32, 0x8b, 0x46, 0x71, 0x5e, 0x59, 0x73, 0x70, + 0x7c, 0x68, 0x8b, 0x6c, 0x08, 0x41, 0xdc, 0x4e, 0xee, 0x1e, 0xc6, 0x8b, + 0xc6, 0x99, 0xbb, 0xa4, 0x08, 0x74, 0x07, 0x8c, 0xf7, 0x1b, 0x15, 0x54, + 0x69, 0x53, 0x7a, 0x55, 0x8b, 0x08, 0x60, 0x6a, 0x9c, 0xa1, 0xb1, 0xc9, + 0xae, 0xcf, 0x1f, 0xad, 0x8b, 0xb0, 0x87, 0xb3, 0x84, 0x08, 0x59, 0x07, + 0xaa, 0xf8, 0x7d, 0x15, 0x9c, 0x99, 0x91, 0x94, 0x8b, 0x97, 0x8b, 0xa0, + 0x7a, 0x9b, 0x77, 0x8b, 0x80, 0x8b, 0x85, 0x88, 0x7c, 0x7e, 0x08, 0xfb, + 0x1a, 0xfb, 0x03, 0x05, 0x7b, 0x7e, 0x84, 0x80, 0x8b, 0x7e, 0x8b, 0x78, + 0x9c, 0x7a, 0x9f, 0x8b, 0x95, 0x8b, 0x92, 0x8f, 0x9a, 0x97, 0x08, 0xf7, + 0x1a, 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa0, + 0x8b, 0x99, 0x8d, 0x92, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, + 0x7b, 0xf7, 0x5e, 0x06, 0xe8, 0x41, 0xc2, 0xfb, 0x0f, 0x1e, 0x59, 0x8b, + 0x41, 0x7e, 0x5b, 0x7a, 0x77, 0x84, 0x81, 0x7d, 0x8b, 0x76, 0x8b, 0x6e, + 0xa0, 0x75, 0xa7, 0x8b, 0x94, 0x8b, 0x99, 0x8d, 0x9c, 0x8f, 0xb9, 0x97, + 0xb0, 0x90, 0xac, 0x8b, 0x08, 0xcb, 0xa8, 0x7c, 0x69, 0x1f, 0x74, 0x07, + 0x62, 0x92, 0x6c, 0x8e, 0x6b, 0x8b, 0x32, 0x8b, 0x46, 0x71, 0x5e, 0x59, + 0x73, 0x70, 0x7c, 0x68, 0x8b, 0x6c, 0x08, 0x41, 0xdc, 0x4e, 0xee, 0x1e, + 0xc6, 0x8b, 0xc6, 0x99, 0xbb, 0xa4, 0x08, 0x74, 0x07, 0x8c, 0xf7, 0x1b, + 0x15, 0x54, 0x69, 0x53, 0x7a, 0x55, 0x8b, 0x08, 0x60, 0x6a, 0x9c, 0xa1, + 0xb1, 0xc9, 0xae, 0xcf, 0x1f, 0xad, 0x8b, 0xb0, 0x87, 0xb3, 0x84, 0x08, + 0x59, 0x07, 0xfb, 0x4b, 0xf8, 0xb5, 0x15, 0x7c, 0x98, 0x85, 0x8e, 0x80, + 0x8b, 0x76, 0x8b, 0x7b, 0x7b, 0x8b, 0x77, 0x8b, 0x7e, 0x91, 0x82, 0x9c, + 0x7d, 0x08, 0xf7, 0x1a, 0xfb, 0x04, 0x05, 0x9a, 0x7f, 0x92, 0x87, 0x95, + 0x8b, 0x9f, 0x8b, 0x9c, 0x9c, 0x8b, 0x9e, 0x8b, 0x98, 0x84, 0x95, 0x7b, + 0x99, 0x08, 0xfb, 0x1a, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x18, 0x16, 0xf7, + 0x09, 0x06, 0xa0, 0x8b, 0x99, 0x8d, 0x92, 0x90, 0x9a, 0x94, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, + 0x70, 0x8b, 0x08, 0x7b, 0xf7, 0x5e, 0x06, 0xe8, 0x41, 0xc2, 0xfb, 0x0f, + 0x1e, 0x59, 0x8b, 0x41, 0x7e, 0x5b, 0x7a, 0x77, 0x84, 0x81, 0x7d, 0x8b, + 0x76, 0x8b, 0x6e, 0xa0, 0x75, 0xa7, 0x8b, 0x94, 0x8b, 0x99, 0x8d, 0x9c, + 0x8f, 0xb9, 0x97, 0xb0, 0x90, 0xac, 0x8b, 0x08, 0xcb, 0xa8, 0x7c, 0x69, + 0x1f, 0x74, 0x07, 0x62, 0x92, 0x6c, 0x8e, 0x6b, 0x8b, 0x32, 0x8b, 0x46, + 0x71, 0x5e, 0x59, 0x73, 0x70, 0x7c, 0x68, 0x8b, 0x6c, 0x08, 0x41, 0xdc, + 0x4e, 0xee, 0x1e, 0xc6, 0x8b, 0xc6, 0x99, 0xbb, 0xa4, 0x08, 0x74, 0x07, + 0x8c, 0xf7, 0x1b, 0x15, 0x54, 0x69, 0x53, 0x7a, 0x55, 0x8b, 0x08, 0x60, + 0x6a, 0x9c, 0xa1, 0xb1, 0xc9, 0xae, 0xcf, 0x1f, 0xad, 0x8b, 0xb0, 0x87, + 0xb3, 0x84, 0x08, 0x59, 0x07, 0x29, 0xf8, 0x6c, 0x15, 0xf7, 0x04, 0x2a, + 0x05, 0x95, 0x82, 0x94, 0x87, 0x94, 0x8b, 0x9e, 0x8b, 0x9b, 0x9c, 0x8b, + 0x9d, 0x8b, 0x97, 0x87, 0x92, 0x80, 0x94, 0x86, 0x8f, 0x88, 0x8d, 0x8a, + 0x8c, 0x08, 0xfb, 0x2b, 0xf7, 0x15, 0xfb, 0x2d, 0xfb, 0x15, 0x05, 0x75, + 0x79, 0x89, 0x88, 0x8b, 0x7d, 0x8b, 0x78, 0x9b, 0x7b, 0x9e, 0x8b, 0x94, + 0x8b, 0x93, 0x8f, 0x96, 0x94, 0x08, 0xf7, 0x06, 0xec, 0x05, 0x0e, 0xf8, + 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa0, 0x8b, 0x99, 0x8d, 0x92, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, + 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, 0x7b, 0xf7, 0x5e, 0x06, 0xe8, 0x41, + 0xc2, 0xfb, 0x0f, 0x1e, 0x59, 0x8b, 0x41, 0x7e, 0x5b, 0x7a, 0x77, 0x84, + 0x81, 0x7d, 0x8b, 0x76, 0x8b, 0x6e, 0xa0, 0x75, 0xa7, 0x8b, 0x94, 0x8b, + 0x99, 0x8d, 0x9c, 0x8f, 0xb9, 0x97, 0xb0, 0x90, 0xac, 0x8b, 0x08, 0xcb, + 0xa8, 0x7c, 0x69, 0x1f, 0x74, 0x07, 0x62, 0x92, 0x6c, 0x8e, 0x6b, 0x8b, + 0x32, 0x8b, 0x46, 0x71, 0x5e, 0x59, 0x73, 0x70, 0x7c, 0x68, 0x8b, 0x6c, + 0x08, 0x41, 0xdc, 0x4e, 0xee, 0x1e, 0xc6, 0x8b, 0xc6, 0x99, 0xbb, 0xa4, + 0x08, 0x74, 0x07, 0x8c, 0xf7, 0x1b, 0x15, 0x54, 0x69, 0x53, 0x7a, 0x55, + 0x8b, 0x08, 0x60, 0x6a, 0x9c, 0xa1, 0xb1, 0xc9, 0xae, 0xcf, 0x1f, 0xad, + 0x8b, 0xb0, 0x87, 0xb3, 0x84, 0x08, 0x59, 0x07, 0xc4, 0xf8, 0x9d, 0x15, + 0x80, 0x8b, 0x7c, 0x81, 0x81, 0x7c, 0x73, 0x68, 0x87, 0x87, 0x7b, 0x8b, + 0x80, 0x8b, 0x7d, 0x91, 0x6a, 0x9f, 0x08, 0x5a, 0xa9, 0x79, 0x93, 0x74, + 0x8b, 0x6e, 0x8b, 0x6f, 0x7b, 0x72, 0x6f, 0x79, 0x76, 0x81, 0x76, 0x8b, + 0x7d, 0x8b, 0x7b, 0x99, 0x7d, 0x9c, 0x8b, 0x94, 0x8b, 0x94, 0x8f, 0x90, + 0x93, 0xab, 0xb6, 0x93, 0x91, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x94, 0x88, + 0xa6, 0x79, 0x08, 0xb7, 0x6e, 0xac, 0x7d, 0xa1, 0x8b, 0xa8, 0x8b, 0xa3, + 0x99, 0xa6, 0xad, 0xa0, 0xa6, 0x93, 0x9a, 0x8b, 0x9a, 0x8b, 0x99, 0x7c, + 0x99, 0x7a, 0x8b, 0x08, 0x0e, 0xf8, 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa0, + 0x8b, 0x99, 0x8d, 0x92, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x82, 0x8d, 0x70, 0x8b, 0x08, + 0x7b, 0xf7, 0x5e, 0x06, 0xe8, 0x41, 0xc2, 0xfb, 0x0f, 0x1e, 0x59, 0x8b, + 0x41, 0x7e, 0x5b, 0x7a, 0x77, 0x84, 0x81, 0x7d, 0x8b, 0x76, 0x8b, 0x6e, + 0xa0, 0x75, 0xa7, 0x8b, 0x94, 0x8b, 0x99, 0x8d, 0x9c, 0x8f, 0xb9, 0x97, + 0xb0, 0x90, 0xac, 0x8b, 0x08, 0xcb, 0xa8, 0x7c, 0x69, 0x1f, 0x74, 0x07, + 0x62, 0x92, 0x6c, 0x8e, 0x6b, 0x8b, 0x32, 0x8b, 0x46, 0x71, 0x5e, 0x59, + 0x73, 0x70, 0x7c, 0x68, 0x8b, 0x6c, 0x08, 0x41, 0xdc, 0x4e, 0xee, 0x1e, + 0xc6, 0x8b, 0xc6, 0x99, 0xbb, 0xa4, 0x08, 0x74, 0x07, 0x8c, 0xf7, 0x1b, + 0x15, 0x54, 0x69, 0x53, 0x7a, 0x55, 0x8b, 0x08, 0x60, 0x6a, 0x9c, 0xa1, + 0xb1, 0xc9, 0xae, 0xcf, 0x1f, 0xad, 0x8b, 0xb0, 0x87, 0xb3, 0x84, 0x08, + 0x59, 0x07, 0x27, 0xf8, 0xe4, 0x15, 0x48, 0x53, 0x54, 0x4a, 0x49, 0xc3, + 0x54, 0xce, 0x1f, 0xcd, 0xc4, 0xc2, 0xcb, 0xce, 0x54, 0xc2, 0x47, 0x1f, + 0x56, 0x04, 0xb1, 0xab, 0x6c, 0x66, 0x68, 0x6b, 0x6c, 0x66, 0x65, 0x6b, + 0xaa, 0xaf, 0xaf, 0xab, 0xaa, 0xb0, 0x1f, 0x0e, 0xf7, 0xea, 0x7b, 0x15, + 0xc3, 0x8d, 0xb1, 0x91, 0xb2, 0x98, 0xc0, 0x9d, 0xb0, 0xae, 0x8b, 0xaa, + 0x8b, 0xa7, 0x74, 0xa2, 0x70, 0x8b, 0x7f, 0x8b, 0x82, 0x87, 0x82, 0x83, + 0x72, 0x76, 0x85, 0x87, 0x78, 0x85, 0x73, 0x83, 0x62, 0x86, 0x63, 0x8b, + 0x08, 0xfb, 0x09, 0x50, 0xb4, 0xdd, 0x1f, 0x8b, 0xb1, 0x99, 0xaf, 0xa5, + 0xa5, 0xa7, 0xa8, 0xb0, 0x99, 0xbf, 0x8b, 0xb6, 0x8b, 0xb0, 0x82, 0xa5, + 0x7b, 0x97, 0x82, 0x91, 0x82, 0x8f, 0x79, 0x90, 0x75, 0x8d, 0x85, 0x93, + 0x85, 0x93, 0x83, 0x9a, 0x85, 0x98, 0x8b, 0x08, 0x9b, 0x8b, 0x9a, 0x93, + 0x95, 0x98, 0x92, 0x94, 0x8d, 0x95, 0x8b, 0xa5, 0x08, 0xd8, 0x07, 0x8b, + 0xa6, 0x8a, 0x93, 0x85, 0x94, 0x84, 0x98, 0x79, 0x94, 0x7a, 0x8b, 0x77, + 0x8b, 0x80, 0x82, 0x85, 0x76, 0x64, 0x9f, 0x5b, 0x95, 0x53, 0x8b, 0xfb, + 0x2c, 0x8b, 0x22, 0x27, 0x8b, 0xfb, 0x24, 0x8b, 0x40, 0xac, 0x4a, 0xc8, + 0x63, 0x08, 0xaf, 0x73, 0xac, 0x81, 0xc2, 0x85, 0x08, 0x33, 0x07, 0x94, + 0x8c, 0x90, 0x8c, 0x90, 0x8b, 0x08, 0xaf, 0x9f, 0x7f, 0x75, 0x7b, 0x7e, + 0x82, 0x74, 0x1f, 0x7a, 0x8b, 0x75, 0x92, 0x79, 0x95, 0x79, 0x95, 0x88, + 0x8c, 0x83, 0x8b, 0x78, 0x8b, 0x7b, 0x7b, 0x8b, 0x78, 0x8b, 0x7e, 0x92, + 0x7f, 0x96, 0x83, 0xa6, 0x79, 0xb6, 0x7f, 0xad, 0x8b, 0xc7, 0x8b, 0xb8, + 0xb4, 0x8b, 0xc2, 0x08, 0x8b, 0xbf, 0x73, 0xa8, 0x58, 0x95, 0x08, 0xa5, + 0x07, 0x0e, 0xf8, 0xba, 0xf7, 0x40, 0x15, 0xb2, 0x07, 0xf7, 0x1e, 0xfb, + 0x02, 0xf0, 0xfb, 0x29, 0xfb, 0x26, 0xfb, 0x04, 0x25, 0xfb, 0x18, 0xfb, + 0x1c, 0xf7, 0x01, 0x2b, 0xf7, 0x2f, 0x1e, 0xd2, 0x8b, 0xf1, 0x9d, 0xb8, + 0x9f, 0xa3, 0x96, 0x96, 0x99, 0x8b, 0x9f, 0x8b, 0xa7, 0x76, 0xa1, 0x70, + 0x8b, 0x82, 0x8b, 0x7f, 0x89, 0x7f, 0x88, 0x2f, 0x73, 0x72, 0x87, 0x5d, + 0x8b, 0x33, 0x8b, 0x56, 0xa8, 0x74, 0xc6, 0x08, 0xf8, 0x2c, 0x06, 0xfc, + 0x29, 0xe3, 0x15, 0x9a, 0xc1, 0xc6, 0xaf, 0xd4, 0x8b, 0xd4, 0x8b, 0xc5, + 0x68, 0x9b, 0x54, 0x08, 0xfb, 0xba, 0x06, 0xc2, 0xf8, 0x1e, 0x15, 0x6a, + 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, + 0x71, 0xa6, 0x69, 0x1f, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, + 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, + 0x0e, 0xf8, 0xba, 0xf7, 0x40, 0x15, 0xb2, 0x07, 0xf7, 0x1e, 0xfb, 0x02, + 0xf0, 0xfb, 0x29, 0xfb, 0x26, 0xfb, 0x04, 0x25, 0xfb, 0x18, 0xfb, 0x1c, + 0xf7, 0x01, 0x2b, 0xf7, 0x2f, 0x1e, 0xd2, 0x8b, 0xf1, 0x9d, 0xb8, 0x9f, + 0xa3, 0x96, 0x96, 0x99, 0x8b, 0x9f, 0x8b, 0xa7, 0x76, 0xa1, 0x70, 0x8b, + 0x82, 0x8b, 0x7f, 0x89, 0x7f, 0x88, 0x2f, 0x73, 0x72, 0x87, 0x5d, 0x8b, + 0x33, 0x8b, 0x56, 0xa8, 0x74, 0xc6, 0x08, 0xf8, 0x2c, 0x06, 0xfc, 0x29, + 0xe3, 0x15, 0x9a, 0xc1, 0xc6, 0xaf, 0xd4, 0x8b, 0xd4, 0x8b, 0xc5, 0x68, + 0x9b, 0x54, 0x08, 0xfb, 0xba, 0x06, 0xf7, 0xb3, 0xf8, 0x00, 0x15, 0x9b, + 0x98, 0x91, 0x95, 0x8b, 0x97, 0x8b, 0xa0, 0x7b, 0x9b, 0x76, 0x8b, 0x80, + 0x8b, 0x86, 0x88, 0x7b, 0x7e, 0x08, 0xfb, 0x1a, 0xfb, 0x03, 0x05, 0x7c, + 0x7f, 0x84, 0x7e, 0x8b, 0x7f, 0x8b, 0x78, 0x9c, 0x7a, 0x9f, 0x8b, 0x95, + 0x8b, 0x91, 0x8e, 0x9b, 0x98, 0x08, 0xf7, 0x1a, 0xf7, 0x04, 0x05, 0x0e, + 0xf8, 0xba, 0xf7, 0x40, 0x15, 0xb2, 0x07, 0xf7, 0x1e, 0xfb, 0x02, 0xf0, + 0xfb, 0x29, 0xfb, 0x26, 0xfb, 0x04, 0x25, 0xfb, 0x18, 0xfb, 0x1c, 0xf7, + 0x01, 0x2b, 0xf7, 0x2f, 0x1e, 0xd2, 0x8b, 0xf1, 0x9d, 0xb8, 0x9f, 0xa3, + 0x96, 0x96, 0x99, 0x8b, 0x9f, 0x8b, 0xa7, 0x76, 0xa1, 0x70, 0x8b, 0x82, + 0x8b, 0x7f, 0x89, 0x7f, 0x88, 0x2f, 0x73, 0x72, 0x87, 0x5d, 0x8b, 0x33, + 0x8b, 0x56, 0xa8, 0x74, 0xc6, 0x08, 0xf8, 0x2c, 0x06, 0xfc, 0x29, 0xe3, + 0x15, 0x9a, 0xc1, 0xc6, 0xaf, 0xd4, 0x8b, 0xd4, 0x8b, 0xc5, 0x68, 0x9b, + 0x54, 0x08, 0xfb, 0xba, 0x06, 0xd4, 0xf8, 0x38, 0x15, 0x7b, 0x98, 0x85, + 0x8e, 0x81, 0x8b, 0x76, 0x8b, 0x7b, 0x7b, 0x8b, 0x77, 0x8b, 0x7e, 0x91, + 0x81, 0x9b, 0x7e, 0x08, 0xf7, 0x1a, 0xfb, 0x04, 0x05, 0x9b, 0x7e, 0x91, + 0x88, 0x95, 0x8b, 0x9f, 0x8b, 0x9c, 0x9c, 0x8b, 0x9e, 0x8b, 0x98, 0x84, + 0x96, 0x7c, 0x98, 0x08, 0xfb, 0x1a, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0xba, + 0xf7, 0x40, 0x15, 0xb2, 0x07, 0xf7, 0x1e, 0xfb, 0x02, 0xf0, 0xfb, 0x29, + 0xfb, 0x26, 0xfb, 0x04, 0x25, 0xfb, 0x18, 0xfb, 0x1c, 0xf7, 0x01, 0x2b, + 0xf7, 0x2f, 0x1e, 0xd2, 0x8b, 0xf1, 0x9d, 0xb8, 0x9f, 0xa3, 0x96, 0x96, + 0x99, 0x8b, 0x9f, 0x8b, 0xa7, 0x76, 0xa1, 0x70, 0x8b, 0x82, 0x8b, 0x7f, + 0x89, 0x7f, 0x88, 0x2e, 0x73, 0x73, 0x87, 0x5d, 0x8b, 0x33, 0x8b, 0x56, + 0xa7, 0x74, 0xc7, 0x08, 0xf8, 0x2c, 0x06, 0xfc, 0x29, 0xe3, 0x15, 0x9a, + 0xc1, 0xc6, 0xaf, 0xd4, 0x8b, 0xd4, 0x8b, 0xc5, 0x68, 0x9b, 0x54, 0x08, + 0xfb, 0xba, 0x06, 0xf7, 0x35, 0xf7, 0xef, 0x15, 0xf7, 0x04, 0x2a, 0x05, + 0x95, 0x82, 0x94, 0x87, 0x94, 0x8b, 0x9e, 0x8b, 0x9b, 0x9c, 0x8b, 0x9d, + 0x8b, 0x97, 0x87, 0x92, 0x80, 0x94, 0x86, 0x8f, 0x88, 0x8d, 0x8a, 0x8c, + 0x08, 0xfb, 0x2b, 0xf7, 0x15, 0xfb, 0x2d, 0xfb, 0x15, 0x05, 0x75, 0x79, + 0x89, 0x88, 0x8b, 0x7d, 0x8b, 0x78, 0x9b, 0x7b, 0x9e, 0x8b, 0x94, 0x8b, + 0x93, 0x8f, 0x96, 0x94, 0x08, 0xf7, 0x06, 0xec, 0x05, 0x0e, 0xf7, 0xf2, + 0xf8, 0x49, 0x15, 0xfb, 0x46, 0x06, 0x71, 0x8b, 0x83, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, + 0x94, 0x83, 0x97, 0x89, 0xa4, 0x8b, 0x08, 0xd9, 0xfb, 0x81, 0xfb, 0x0e, + 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, + 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, + 0x8b, 0x08, 0xf7, 0xec, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, + 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, + 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x0e, 0x06, 0xf7, 0xe5, 0x07, + 0xfb, 0x3f, 0xf7, 0x6d, 0x15, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, + 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0xf7, 0x64, + 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, + 0xab, 0x1f, 0xad, 0x71, 0xa6, 0x69, 0x1e, 0x0e, 0xf7, 0xf2, 0xf8, 0x49, + 0x15, 0xfb, 0x46, 0x06, 0x71, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, + 0x97, 0x89, 0xa4, 0x8b, 0x08, 0xd9, 0xfb, 0x81, 0xfb, 0x0e, 0x06, 0x71, + 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, + 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, + 0xf7, 0xec, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, + 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, + 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x0e, 0xf7, 0xe5, 0x06, 0xc7, 0xf7, 0x4f, + 0x15, 0x9c, 0x99, 0x91, 0x94, 0x8b, 0x98, 0x8b, 0x9f, 0x7a, 0x9b, 0x77, + 0x8b, 0x80, 0x8b, 0x85, 0x88, 0x7c, 0x7e, 0x08, 0xfb, 0x1a, 0xfb, 0x03, + 0x05, 0x7d, 0x7f, 0x83, 0x7e, 0x8b, 0x80, 0x8b, 0x77, 0x9c, 0x7a, 0x9f, + 0x8b, 0x94, 0x8b, 0x91, 0x8e, 0x9b, 0x98, 0x08, 0xf7, 0x1a, 0xf7, 0x04, + 0x05, 0x0e, 0xf7, 0xf2, 0xf8, 0x49, 0x15, 0xfb, 0x46, 0x06, 0x71, 0x8b, + 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, + 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x97, 0x89, 0xa4, 0x8b, 0x08, 0xd9, + 0xfb, 0x81, 0xfb, 0x0e, 0x06, 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, + 0x84, 0x99, 0x88, 0xa2, 0x8b, 0x08, 0xf7, 0xec, 0x06, 0x9f, 0x8b, 0x9a, + 0x8e, 0x92, 0x8f, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x0e, + 0xf7, 0xe5, 0x06, 0xfb, 0x24, 0xf7, 0x87, 0x15, 0x7c, 0x98, 0x85, 0x8e, + 0x81, 0x8b, 0x76, 0x8b, 0x7b, 0x7b, 0x8b, 0x77, 0x8b, 0x7e, 0x92, 0x80, + 0x9a, 0x7f, 0x08, 0xf7, 0x1a, 0xfb, 0x04, 0x05, 0x9a, 0x7f, 0x92, 0x87, + 0x95, 0x8b, 0x9f, 0x8b, 0x9c, 0x9c, 0x8b, 0x9e, 0x8b, 0x98, 0x84, 0x96, + 0x7b, 0x98, 0x08, 0xfb, 0x1a, 0xf7, 0x03, 0x05, 0x0e, 0xf7, 0xf2, 0xf8, + 0x49, 0x15, 0xfb, 0x46, 0x06, 0x71, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x83, 0x97, 0x89, 0xa4, 0x8b, 0x08, 0xd9, 0xfb, 0x81, 0xfb, 0x0e, 0x06, + 0x71, 0x8b, 0x84, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x93, 0x84, 0x99, 0x88, 0xa2, 0x8b, + 0x08, 0xf7, 0xec, 0x06, 0x9f, 0x8b, 0x9a, 0x8e, 0x92, 0x8f, 0x9a, 0x95, + 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfb, 0x0e, 0xf7, 0xe5, 0x06, 0x49, 0xf7, + 0x3e, 0x15, 0xf7, 0x04, 0x2a, 0x05, 0x95, 0x82, 0x95, 0x87, 0x93, 0x8b, + 0x9e, 0x8b, 0x9b, 0x9c, 0x8b, 0x9d, 0x8b, 0x97, 0x87, 0x92, 0x7f, 0x95, + 0x08, 0x83, 0x91, 0xfb, 0x2b, 0xf7, 0x15, 0xfb, 0x2c, 0xfb, 0x15, 0x05, + 0x76, 0x7a, 0x88, 0x87, 0x8b, 0x7d, 0x8b, 0x79, 0x9b, 0x7a, 0x9d, 0x8b, + 0x95, 0x8b, 0x93, 0x8f, 0x95, 0x94, 0x08, 0xf7, 0x06, 0xec, 0x05, 0x0e, + 0xf7, 0x57, 0xf8, 0x49, 0x15, 0x2d, 0x06, 0x83, 0x8b, 0x89, 0x8b, 0x80, + 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x8b, 0x6b, 0xa1, 0x7a, 0xb2, + 0x8a, 0x08, 0xfb, 0x81, 0x85, 0x07, 0x72, 0x8b, 0x83, 0x89, 0x82, 0x86, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x97, 0x82, + 0x95, 0x84, 0x97, 0x88, 0xa3, 0x8b, 0x08, 0xf7, 0x04, 0x06, 0xa0, 0x8b, + 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0x85, + 0xf7, 0x4a, 0x06, 0xbf, 0xc2, 0xa4, 0x98, 0xbd, 0x8b, 0x08, 0xc7, 0xa7, + 0x74, 0x5a, 0x1f, 0xfb, 0x46, 0x07, 0x64, 0x75, 0x79, 0x6b, 0x6a, 0xa1, + 0x7a, 0xb8, 0x1f, 0xe4, 0x06, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, + 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf7, + 0x4a, 0x07, 0x8b, 0xc6, 0x78, 0xb5, 0x63, 0xa9, 0x6a, 0xa3, 0x62, 0x98, + 0x5e, 0x8b, 0x54, 0x8b, 0x69, 0x7c, 0x5b, 0x5d, 0x08, 0xbb, 0x07, 0xf7, + 0x8f, 0xf7, 0x6f, 0x15, 0x80, 0x8a, 0x7d, 0x81, 0x81, 0x7d, 0x73, 0x68, + 0x86, 0x87, 0x7c, 0x8b, 0x7f, 0x8b, 0x7e, 0x91, 0x6a, 0x9f, 0x08, 0x59, + 0xaa, 0x7a, 0x92, 0x73, 0x8b, 0x6f, 0x8b, 0x6e, 0x7b, 0x72, 0x6d, 0x7a, + 0x76, 0x81, 0x78, 0x8b, 0x7d, 0x8b, 0x7b, 0x99, 0x7d, 0x9c, 0x8b, 0x95, + 0x8b, 0x93, 0x90, 0x92, 0x94, 0xa9, 0xb4, 0x93, 0x91, 0x9d, 0x8b, 0x08, + 0x99, 0x8b, 0x93, 0x88, 0xa7, 0x79, 0x08, 0xb7, 0x6e, 0xac, 0x7d, 0xa1, + 0x8b, 0xa8, 0x8b, 0xa3, 0x99, 0xa6, 0xad, 0xa0, 0xa6, 0x93, 0x9a, 0x8b, + 0x99, 0x08, 0x8b, 0x9b, 0x7e, 0x96, 0x77, 0x8d, 0x08, 0x0e, 0xf7, 0xc3, + 0xf8, 0x56, 0x15, 0xfb, 0x28, 0xfb, 0x05, 0x26, 0xfb, 0x18, 0xfb, 0x16, + 0xf7, 0x06, 0x24, 0xf7, 0x24, 0xf7, 0x24, 0xf7, 0x06, 0xf2, 0xf7, 0x16, + 0x1f, 0xf7, 0x15, 0xfb, 0x06, 0xf3, 0xfb, 0x21, 0x1e, 0x8a, 0x27, 0x15, + 0xe2, 0xd0, 0x50, 0x41, 0x40, 0x46, 0x51, 0x32, 0x32, 0x46, 0xc5, 0xd6, + 0xd7, 0xd0, 0xc4, 0xe6, 0x1f, 0x21, 0xf7, 0xc4, 0x15, 0x6a, 0x70, 0x70, + 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0x1f, 0xad, 0x71, + 0xa6, 0x69, 0x1e, 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, + 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0x0e, + 0xf7, 0xc3, 0xf8, 0x56, 0x15, 0xfb, 0x28, 0xfb, 0x05, 0x26, 0xfb, 0x18, + 0xfb, 0x16, 0xf7, 0x06, 0x24, 0xf7, 0x24, 0xf7, 0x24, 0xf7, 0x06, 0xf2, + 0xf7, 0x16, 0xf7, 0x15, 0xfb, 0x06, 0xf3, 0xfb, 0x21, 0x1f, 0x8a, 0x27, + 0x15, 0xe2, 0xd0, 0x50, 0x41, 0x40, 0x46, 0x51, 0x32, 0x32, 0x46, 0xc5, + 0xd6, 0xd7, 0xd0, 0xc4, 0xe6, 0x1f, 0xf7, 0x14, 0xf7, 0xa6, 0x15, 0x9c, + 0x99, 0x91, 0x94, 0x8b, 0x98, 0x8b, 0x9f, 0x7a, 0x9b, 0x77, 0x8b, 0x80, + 0x8b, 0x85, 0x88, 0x7c, 0x7e, 0x08, 0xfb, 0x1a, 0xfb, 0x03, 0x05, 0x7d, + 0x7f, 0x83, 0x7e, 0x8b, 0x80, 0x8b, 0x77, 0x9c, 0x7a, 0x9f, 0x8b, 0x94, + 0x8b, 0x91, 0x8e, 0x9b, 0x98, 0x08, 0xf7, 0x1a, 0xf7, 0x04, 0x05, 0x0e, + 0xf7, 0xc3, 0xf8, 0x56, 0x15, 0xfb, 0x28, 0xfb, 0x05, 0x26, 0xfb, 0x18, + 0xfb, 0x16, 0xf7, 0x06, 0x24, 0xf7, 0x24, 0xf7, 0x24, 0xf7, 0x06, 0xf2, + 0xf7, 0x16, 0xf7, 0x15, 0xfb, 0x06, 0xf3, 0xfb, 0x21, 0x1f, 0x8a, 0x27, + 0x15, 0xe2, 0xd0, 0x50, 0x41, 0x40, 0x46, 0x51, 0x32, 0x32, 0x46, 0xc5, + 0xd6, 0xd7, 0xd0, 0xc4, 0xe6, 0x1f, 0x35, 0xf7, 0xde, 0x15, 0x7c, 0x98, + 0x85, 0x8e, 0x81, 0x8b, 0x76, 0x8b, 0x7b, 0x7b, 0x8b, 0x77, 0x8b, 0x7e, + 0x92, 0x80, 0x9a, 0x7f, 0x08, 0xf7, 0x1a, 0xfb, 0x04, 0x05, 0x9a, 0x7f, + 0x92, 0x87, 0x95, 0x8b, 0x9f, 0x8b, 0x9c, 0x9c, 0x8b, 0x9e, 0x8b, 0x98, + 0x84, 0x96, 0x7b, 0x98, 0x08, 0xfb, 0x1a, 0xf7, 0x03, 0x05, 0x0e, 0xf7, + 0xc3, 0xf8, 0x56, 0x15, 0xfb, 0x28, 0xfb, 0x05, 0x26, 0xfb, 0x18, 0xfb, + 0x16, 0xf7, 0x06, 0x24, 0xf7, 0x24, 0xf7, 0x24, 0xf7, 0x06, 0xf2, 0xf7, + 0x16, 0xf7, 0x15, 0xfb, 0x06, 0xf3, 0xfb, 0x21, 0x1f, 0x8a, 0x27, 0x15, + 0xe2, 0xd0, 0x50, 0x41, 0x40, 0x46, 0x51, 0x32, 0x32, 0x46, 0xc5, 0xd6, + 0xd7, 0xd0, 0xc4, 0xe6, 0x1f, 0x8a, 0xf7, 0x95, 0x15, 0xf7, 0x04, 0x2a, + 0x05, 0x95, 0x82, 0x94, 0x87, 0x94, 0x8b, 0x9e, 0x8b, 0x9b, 0x9c, 0x8b, + 0x9d, 0x8b, 0x97, 0x87, 0x92, 0x80, 0x94, 0x87, 0x8e, 0x87, 0x8e, 0x8a, + 0x8c, 0x08, 0xfb, 0x2b, 0xf7, 0x15, 0xfb, 0x2d, 0xfb, 0x15, 0x05, 0x88, + 0x89, 0x89, 0x89, 0x87, 0x88, 0x80, 0x82, 0x87, 0x83, 0x8b, 0x80, 0x8b, + 0x79, 0x9b, 0x7a, 0x9e, 0x8b, 0x94, 0x8b, 0x93, 0x8f, 0x96, 0x94, 0x08, + 0xf7, 0x06, 0xec, 0x05, 0x0e, 0xf7, 0xc3, 0xf8, 0x56, 0x15, 0xfb, 0x28, + 0xfb, 0x05, 0x26, 0xfb, 0x18, 0xfb, 0x16, 0xf7, 0x06, 0x24, 0xf7, 0x24, + 0xf7, 0x24, 0xf7, 0x06, 0xf2, 0xf7, 0x16, 0x1f, 0xf7, 0x15, 0xfb, 0x06, + 0xf3, 0xfb, 0x21, 0x1e, 0x8a, 0x27, 0x15, 0xe2, 0xd0, 0x50, 0x41, 0x40, + 0x46, 0x51, 0x32, 0x32, 0x46, 0xc5, 0xd6, 0xd7, 0xd0, 0xc4, 0xe6, 0x1f, + 0xf7, 0x32, 0xf7, 0xc6, 0x15, 0x7f, 0x8b, 0x7d, 0x81, 0x7e, 0x78, 0x76, + 0x6c, 0x86, 0x87, 0x7c, 0x8b, 0x80, 0x8b, 0x7e, 0x91, 0x69, 0x9f, 0x08, + 0x59, 0xaa, 0x7a, 0x92, 0x74, 0x8b, 0x6e, 0x8b, 0x6e, 0x7b, 0x72, 0x6e, + 0x7a, 0x75, 0x81, 0x78, 0x8b, 0x7d, 0x8b, 0x7b, 0x99, 0x7d, 0x9c, 0x8b, + 0x95, 0x8b, 0x93, 0x90, 0x92, 0x95, 0xa9, 0xb2, 0x93, 0x92, 0x9d, 0x8b, + 0x08, 0x99, 0x8b, 0x93, 0x88, 0xa7, 0x79, 0x08, 0xb7, 0x6e, 0xac, 0x7d, + 0xa1, 0x8b, 0xa8, 0x8b, 0xa3, 0x99, 0xa6, 0xad, 0xa0, 0xa6, 0x93, 0x9a, + 0x8b, 0x9a, 0x8b, 0x99, 0x7c, 0x99, 0x7a, 0x8b, 0x08, 0x0e, 0xf7, 0xcb, + 0xf8, 0xde, 0x15, 0xfb, 0x06, 0xeb, 0x05, 0x7f, 0x96, 0x84, 0x8e, 0x82, + 0x8b, 0x78, 0x8b, 0x7b, 0x7a, 0x8b, 0x78, 0x8b, 0x7e, 0x8d, 0x87, 0xa1, + 0x79, 0x08, 0xf7, 0x2d, 0xfb, 0x14, 0xf7, 0x2b, 0xf7, 0x14, 0x05, 0x8b, + 0x8b, 0x90, 0x8f, 0x8f, 0x8f, 0x96, 0x94, 0x8f, 0x92, 0x8b, 0x96, 0x8b, + 0x9e, 0x7b, 0x9c, 0x78, 0x8b, 0x82, 0x8b, 0x83, 0x87, 0x80, 0x81, 0x08, + 0xfb, 0x04, 0x2b, 0x05, 0xed, 0xfb, 0xa6, 0x15, 0x97, 0x75, 0x99, 0x82, + 0xa0, 0x8b, 0x9a, 0x8b, 0x9b, 0x93, 0x95, 0x97, 0x92, 0x95, 0x8d, 0x95, + 0x8b, 0xa5, 0x08, 0xb0, 0x07, 0xb9, 0x7c, 0x9f, 0x6b, 0x1e, 0x7c, 0x8b, + 0x82, 0x84, 0x83, 0x78, 0x64, 0x9d, 0x62, 0x93, 0x5a, 0x8b, 0xfb, 0x0c, + 0x8b, 0x35, 0x52, 0x8b, 0x3b, 0x8b, 0x3c, 0xc6, 0x63, 0xf7, 0x20, 0x7c, + 0xc1, 0x85, 0xa0, 0x87, 0x9c, 0x84, 0xa0, 0x83, 0x98, 0x7d, 0x8b, 0x7e, + 0x08, 0x74, 0x56, 0x77, 0x4b, 0x1e, 0x55, 0x8b, 0x61, 0x98, 0x6e, 0xa5, + 0x82, 0xa9, 0x7b, 0x99, 0x71, 0x8b, 0x7a, 0x8b, 0x7d, 0x84, 0x81, 0x7d, + 0x83, 0x81, 0x89, 0x82, 0x8b, 0x70, 0x08, 0x6a, 0x07, 0x8b, 0x73, 0x8d, + 0x82, 0x90, 0x82, 0x95, 0x7b, 0x9b, 0x83, 0x9d, 0x8b, 0x98, 0x8b, 0x93, + 0x8e, 0x96, 0x94, 0xb3, 0x78, 0xbe, 0x81, 0xc4, 0x8b, 0xf7, 0x15, 0x8b, + 0xe9, 0xc6, 0x8b, 0xdd, 0x8b, 0xb9, 0x71, 0xb6, 0x5f, 0xa3, 0x08, 0x6d, + 0x9c, 0x63, 0x96, 0x40, 0x95, 0x4b, 0x94, 0x85, 0x8c, 0x7d, 0x90, 0x7b, + 0x91, 0x81, 0x94, 0x8b, 0x94, 0x8b, 0x9d, 0xbb, 0x9c, 0xbe, 0x8b, 0xb5, + 0x8b, 0xac, 0x82, 0xa7, 0x77, 0x08, 0x90, 0x82, 0x05, 0x0e, 0xf8, 0x92, + 0xf8, 0x49, 0x15, 0xfb, 0x1b, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, + 0x94, 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0x4a, 0x06, 0x57, + 0x54, 0x72, 0x7e, 0x59, 0x8b, 0x08, 0x4f, 0x6f, 0xa2, 0xbc, 0x1f, 0xf7, + 0xaa, 0xfb, 0x08, 0x07, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x6e, 0xa4, 0x74, 0xa9, 0x8d, 0x08, 0x96, + 0x8c, 0x9b, 0x8b, 0x8b, 0xfb, 0x4a, 0x05, 0x8b, 0x50, 0x9e, 0x60, 0xb3, + 0x6d, 0xab, 0x73, 0xb5, 0x7e, 0xb8, 0x8b, 0xc2, 0x8b, 0xab, 0x99, 0xbd, + 0xba, 0x08, 0x5b, 0xea, 0x07, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, + 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf7, + 0xe5, 0x07, 0xfb, 0xd3, 0xf7, 0x6d, 0x15, 0x6a, 0x70, 0x70, 0x6a, 0x6a, + 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, + 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, + 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0x0e, 0xf8, 0x92, 0xf8, + 0x49, 0x15, 0xfb, 0x1b, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, + 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0x4a, 0x06, 0x57, 0x54, + 0x72, 0x7e, 0x59, 0x8b, 0x08, 0x4f, 0x6f, 0xa2, 0xbc, 0x1f, 0xf7, 0xaa, + 0xfb, 0x08, 0x07, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, + 0x7a, 0x8b, 0x7a, 0x8b, 0x6e, 0xa4, 0x74, 0xa9, 0x8d, 0x08, 0x96, 0x8c, + 0x9b, 0x8b, 0x8b, 0xfb, 0x4a, 0x05, 0x8b, 0x50, 0x9e, 0x60, 0xb3, 0x6d, + 0xab, 0x73, 0xb5, 0x7e, 0xb8, 0x8b, 0xc2, 0x8b, 0xab, 0x99, 0xbd, 0xba, + 0x08, 0x5b, 0xea, 0x07, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, + 0x94, 0x9b, 0x8b, 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf7, 0xe5, + 0x07, 0x30, 0xf7, 0x4f, 0x15, 0x9c, 0x99, 0x91, 0x94, 0x8b, 0x98, 0x8b, + 0x9f, 0x7a, 0x9b, 0x77, 0x8b, 0x80, 0x8b, 0x84, 0x88, 0x7d, 0x7e, 0x08, + 0xfb, 0x1a, 0xfb, 0x03, 0x05, 0x7b, 0x7e, 0x84, 0x80, 0x8b, 0x7f, 0x8b, + 0x77, 0x9c, 0x7a, 0x9f, 0x8b, 0x95, 0x8b, 0x91, 0x8e, 0x9b, 0x98, 0x08, + 0xf7, 0x1a, 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0x92, 0xf8, 0x49, 0x15, 0xfb, + 0x1b, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, 0x96, 0x89, + 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0x4a, 0x06, 0x57, 0x54, 0x72, 0x7e, 0x59, + 0x8b, 0x08, 0x4f, 0x6f, 0xa2, 0xbc, 0x1f, 0xf7, 0xaa, 0xfb, 0x08, 0x07, + 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x6e, 0xa4, 0x74, 0xa9, 0x8d, 0x08, 0x96, 0x8c, 0x9b, 0x8b, 0x8b, + 0xfb, 0x4a, 0x05, 0x8b, 0x50, 0x9e, 0x60, 0xb3, 0x6d, 0xab, 0x73, 0xb5, + 0x7e, 0xb8, 0x8b, 0xc2, 0x8b, 0xab, 0x99, 0xbd, 0xba, 0x08, 0x5b, 0xea, + 0x07, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, + 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf7, 0xe5, 0x07, 0xfb, 0xbb, + 0xf7, 0x87, 0x15, 0x7b, 0x98, 0x86, 0x8e, 0x80, 0x8b, 0x76, 0x8b, 0x7b, + 0x7b, 0x8b, 0x77, 0x8b, 0x7e, 0x91, 0x81, 0x9c, 0x7e, 0x08, 0xf7, 0x1a, + 0xfb, 0x04, 0x05, 0x99, 0x7f, 0x93, 0x87, 0x95, 0x8b, 0x9f, 0x8b, 0x9c, + 0x9c, 0x8b, 0x9e, 0x8b, 0x98, 0x85, 0x95, 0x7a, 0x99, 0x08, 0xfb, 0x1a, + 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x92, 0xf8, 0x49, 0x15, 0xfb, 0x1b, 0x06, + 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, + 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, 0x96, 0x89, 0xa4, 0x8b, + 0x08, 0xae, 0xfb, 0x4a, 0x06, 0x57, 0x54, 0x72, 0x7e, 0x59, 0x8b, 0x08, + 0x4f, 0x6f, 0xa2, 0xbc, 0x1f, 0xf7, 0xaa, 0xfb, 0x08, 0x07, 0x72, 0x8b, + 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x6e, + 0xa4, 0x74, 0xa9, 0x8d, 0x08, 0x96, 0x8c, 0x9b, 0x8b, 0x8b, 0xfb, 0x4a, + 0x05, 0x8b, 0x50, 0x9e, 0x60, 0xb3, 0x6d, 0xab, 0x73, 0xb5, 0x7e, 0xb8, + 0x8b, 0xc2, 0x8b, 0xab, 0x99, 0xbd, 0xba, 0x08, 0x5b, 0xea, 0x07, 0xa0, + 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x08, + 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf7, 0xe5, 0x07, 0xfb, 0x6a, 0xf7, 0x3e, + 0x15, 0xf7, 0x04, 0x2a, 0x05, 0x95, 0x82, 0x95, 0x87, 0x93, 0x8b, 0x9e, + 0x8b, 0x9b, 0x9c, 0x8b, 0x9d, 0x8b, 0x97, 0x87, 0x92, 0x7f, 0x95, 0x89, + 0x8d, 0x88, 0x8d, 0x88, 0x8d, 0x08, 0xfb, 0x2b, 0xf7, 0x15, 0xfb, 0x2c, + 0xfb, 0x15, 0x05, 0x76, 0x7a, 0x88, 0x87, 0x8b, 0x7d, 0x8b, 0x78, 0x9b, + 0x7b, 0x9e, 0x8b, 0x94, 0x8b, 0x93, 0x8f, 0x95, 0x94, 0x08, 0xf7, 0x06, + 0xec, 0x05, 0x0e, 0xf7, 0x86, 0x8e, 0x15, 0x54, 0xfb, 0x00, 0x27, 0x8b, + 0x05, 0x73, 0x8b, 0x82, 0x89, 0x82, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, + 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, 0x83, 0x96, 0x89, 0xa4, + 0x8b, 0x08, 0xf7, 0x6b, 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, + 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, + 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x86, 0x8b, 0xf7, 0x7a, 0xf8, 0x4e, + 0x05, 0xac, 0x8e, 0x9e, 0x9d, 0x8b, 0xa8, 0x8b, 0x9b, 0x84, 0x9a, 0x7d, + 0x95, 0x82, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x2f, 0x06, 0x83, 0x8b, + 0x89, 0x8b, 0x80, 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x08, 0x6b, + 0xa2, 0x79, 0xb4, 0x1e, 0xfb, 0x0c, 0xfb, 0x73, 0xfb, 0x06, 0xf7, 0x73, + 0x05, 0xb1, 0x8c, 0xa0, 0x9d, 0x8b, 0xaa, 0x8b, 0x9b, 0x83, 0x9a, 0x7f, + 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x31, 0x06, 0x84, 0x8b, + 0x89, 0x8b, 0x80, 0x89, 0x6e, 0x88, 0x7a, 0x79, 0x8b, 0x70, 0x8b, 0x6f, + 0x9d, 0x79, 0xaa, 0x87, 0x08, 0xf7, 0x40, 0xfb, 0xe2, 0x05, 0xf7, 0x66, + 0xf9, 0x01, 0x15, 0x9c, 0x98, 0x91, 0x95, 0x8b, 0x97, 0x8b, 0xa0, 0x7b, + 0x9b, 0x76, 0x8b, 0x80, 0x8b, 0x86, 0x88, 0x7b, 0x7e, 0x08, 0xfb, 0x19, + 0xfb, 0x03, 0x05, 0x7b, 0x7e, 0x84, 0x80, 0x8b, 0x7e, 0x8b, 0x78, 0x9c, + 0x7a, 0x9f, 0x8b, 0x95, 0x8b, 0x92, 0x8f, 0x9a, 0x97, 0x08, 0xf7, 0x19, + 0xf7, 0x04, 0x05, 0x0e, 0xf7, 0x88, 0xef, 0x15, 0xf7, 0x9a, 0xf7, 0x94, + 0x8b, 0xdc, 0xfc, 0x2d, 0x8b, 0x8b, 0xfb, 0x01, 0x05, 0x8b, 0x74, 0x8d, + 0x81, 0x90, 0x82, 0x94, 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, + 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0x94, 0xf7, + 0x29, 0x07, 0xfb, 0x99, 0xfb, 0x92, 0x8b, 0x38, 0xf8, 0x46, 0x8b, 0x8b, + 0xe3, 0x05, 0x8b, 0xa5, 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, + 0x7a, 0x8b, 0x6d, 0x8b, 0x79, 0x78, 0x89, 0x68, 0x08, 0xfb, 0x43, 0x06, + 0xc6, 0xf8, 0x7a, 0x15, 0xfb, 0x06, 0xeb, 0x05, 0x7f, 0x96, 0x84, 0x8e, + 0x82, 0x8b, 0x78, 0x8b, 0x7b, 0x7a, 0x8b, 0x78, 0x8b, 0x80, 0x8f, 0x84, + 0x96, 0x82, 0x8e, 0x88, 0x8e, 0x88, 0x8e, 0x89, 0x08, 0xf7, 0x2d, 0xfb, + 0x14, 0xf7, 0x2b, 0xf7, 0x14, 0x05, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8e, + 0x96, 0x94, 0x8f, 0x92, 0x8b, 0x96, 0x8b, 0x9e, 0x7b, 0x9c, 0x78, 0x8b, + 0x82, 0x8b, 0x84, 0x87, 0x7f, 0x81, 0x08, 0xfb, 0x04, 0x2b, 0x05, 0x0e, + 0xf8, 0x35, 0xf8, 0xdb, 0x15, 0x9a, 0x92, 0x93, 0x96, 0x8b, 0x97, 0x8b, + 0x9e, 0x7d, 0x99, 0x7a, 0x8b, 0x81, 0x8b, 0x80, 0x88, 0x7f, 0x85, 0x08, + 0x3e, 0x62, 0x6f, 0x98, 0x05, 0x5d, 0xa1, 0x6d, 0x94, 0x74, 0x8b, 0x76, + 0x8b, 0x78, 0x7a, 0x8b, 0x78, 0x8b, 0x7d, 0x94, 0x80, 0x9c, 0x85, 0x08, + 0x9b, 0x86, 0x05, 0x8d, 0x8a, 0x91, 0x88, 0x95, 0x87, 0x8e, 0x8a, 0x94, + 0x87, 0x94, 0x87, 0x08, 0x59, 0x6e, 0x05, 0x76, 0x7f, 0x88, 0x88, 0x8b, + 0x7d, 0x8b, 0x76, 0x98, 0x7b, 0x9c, 0x8b, 0x94, 0x8b, 0x8f, 0x8c, 0x9e, + 0x96, 0x08, 0xe7, 0xbd, 0x05, 0xbb, 0x6f, 0xbd, 0x5e, 0xb2, 0x5a, 0x08, + 0x4c, 0xb0, 0x6c, 0x95, 0x59, 0x8b, 0x08, 0xfb, 0x1b, 0xfb, 0x01, 0x23, + 0xfb, 0x14, 0xfb, 0x12, 0xf7, 0x07, 0x26, 0xf7, 0x23, 0x1f, 0xd1, 0x8b, + 0xd0, 0xa5, 0xbd, 0xb8, 0xbb, 0xb7, 0xa0, 0xc1, 0x8b, 0xdb, 0x8b, 0xf7, + 0x1b, 0x52, 0xef, 0xfb, 0x15, 0xe5, 0x08, 0xb8, 0xa4, 0x05, 0xfb, 0x09, + 0xfb, 0x7d, 0x15, 0xe3, 0xcf, 0x4e, 0x3c, 0x46, 0x44, 0x52, 0x36, 0x35, + 0x45, 0xc4, 0xd2, 0xd8, 0xd0, 0xc8, 0xe2, 0x1f, 0x0e, 0xf7, 0x42, 0xcd, + 0x15, 0xbf, 0x63, 0xb7, 0x7b, 0xc6, 0x8b, 0x08, 0xf7, 0x1f, 0xf2, 0xe6, + 0xf7, 0x0f, 0xf7, 0x16, 0x23, 0xeb, 0xfb, 0x1f, 0x1f, 0x4c, 0x8b, 0x61, + 0x7b, 0x5a, 0x61, 0x08, 0xf7, 0x7c, 0xfb, 0x08, 0x07, 0x73, 0x8b, 0x82, + 0x89, 0x82, 0x86, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, + 0x7c, 0x97, 0x81, 0x95, 0x84, 0x95, 0x89, 0xa5, 0x8b, 0x08, 0x9b, 0xfd, + 0x09, 0x7b, 0x06, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x08, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x97, 0x82, 0x95, 0x83, + 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf7, 0x42, 0x06, 0xa1, 0x8b, 0x97, 0x8d, + 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, 0x9a, + 0x7e, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x51, 0x06, 0xf7, + 0x3f, 0x07, 0xf7, 0x29, 0xf7, 0xb0, 0x15, 0xb4, 0x8b, 0xac, 0x82, 0xa5, + 0x77, 0xa8, 0x76, 0x9e, 0x66, 0x8b, 0x6a, 0x08, 0x45, 0x4d, 0x59, 0x35, + 0x1e, 0x33, 0x4e, 0xbd, 0xd2, 0x1f, 0x8b, 0xab, 0x9e, 0xb0, 0xa8, 0xa0, + 0xa5, 0x9f, 0xac, 0x94, 0xb5, 0x8b, 0x08, 0x0e, 0xf7, 0x86, 0x8e, 0x15, + 0x54, 0xfb, 0x00, 0x27, 0x8b, 0x05, 0x73, 0x8b, 0x82, 0x89, 0x82, 0x86, + 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, + 0x94, 0x83, 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xf7, 0x6b, 0x06, 0xa1, 0x8b, + 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x8b, 0x9b, + 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0x86, + 0x8b, 0xf7, 0x7a, 0xf8, 0x4e, 0x05, 0xac, 0x8e, 0x9e, 0x9d, 0x8b, 0xa8, + 0x8b, 0x9b, 0x84, 0x9a, 0x7d, 0x95, 0x82, 0x92, 0x81, 0x8d, 0x71, 0x8b, + 0x08, 0x2f, 0x06, 0x83, 0x8b, 0x89, 0x8b, 0x80, 0x89, 0x6e, 0x88, 0x7a, + 0x79, 0x8b, 0x70, 0x08, 0x6b, 0xa2, 0x79, 0xb4, 0x1e, 0xfb, 0x0c, 0xfb, + 0x73, 0xfb, 0x06, 0xf7, 0x73, 0x05, 0xb1, 0x8c, 0xa0, 0x9d, 0x8b, 0xaa, + 0x8b, 0x9b, 0x83, 0x9a, 0x7f, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, + 0x08, 0x31, 0x06, 0x84, 0x8b, 0x89, 0x8b, 0x80, 0x89, 0x6e, 0x88, 0x7a, + 0x79, 0x8b, 0x70, 0x8b, 0x6f, 0x9d, 0x79, 0xaa, 0x87, 0x08, 0xf7, 0x40, + 0xfb, 0xe2, 0x05, 0x5d, 0xf9, 0x1f, 0x15, 0x6a, 0x70, 0x70, 0x6a, 0x6a, + 0xa6, 0x70, 0xac, 0xac, 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, + 0xf7, 0x64, 0x16, 0x6a, 0x70, 0x70, 0x6a, 0x6a, 0xa6, 0x70, 0xac, 0xac, + 0xa6, 0xa6, 0xab, 0xad, 0x71, 0xa6, 0x69, 0x1f, 0x0e, 0xf7, 0x41, 0xf7, + 0xfb, 0x15, 0x9a, 0xe0, 0xbf, 0xc0, 0xd0, 0x8b, 0xa8, 0x8b, 0xac, 0x82, + 0xa3, 0x7c, 0xa5, 0x7b, 0x95, 0x7e, 0x8e, 0x73, 0x91, 0x65, 0x98, 0x7c, + 0xa5, 0x8b, 0x99, 0x8b, 0x99, 0x93, 0x94, 0x98, 0x91, 0x94, 0x8d, 0x96, + 0x8b, 0xa4, 0x08, 0xdf, 0x07, 0x8b, 0xa4, 0x8a, 0x93, 0x86, 0x94, 0x08, + 0x82, 0x9a, 0x7d, 0x94, 0x7b, 0x8b, 0x7b, 0x8b, 0x81, 0x84, 0x7f, 0x7a, + 0x08, 0x82, 0x8f, 0x05, 0x59, 0xa5, 0x6c, 0x93, 0x5d, 0x8b, 0xfb, 0x12, + 0x8b, 0x26, 0x28, 0x7b, 0xfb, 0x1f, 0x08, 0x6c, 0x06, 0x79, 0x82, 0x81, + 0x79, 0x79, 0x95, 0x81, 0x9c, 0x1f, 0xa7, 0x61, 0x6f, 0x06, 0x79, 0x82, + 0x81, 0x79, 0x79, 0x95, 0x81, 0x9c, 0x1f, 0xaa, 0x06, 0xa1, 0xfb, 0x19, + 0xf2, 0x35, 0xf7, 0x1e, 0x8b, 0xcb, 0x8b, 0xc9, 0x9e, 0xb2, 0xaa, 0xaa, + 0xa3, 0x9c, 0xa5, 0x8b, 0xa2, 0x8b, 0xa6, 0x76, 0xa2, 0x72, 0x8b, 0x80, + 0x8b, 0x81, 0x86, 0x81, 0x80, 0x72, 0x6f, 0x8b, 0x8b, 0x81, 0x85, 0x08, + 0x75, 0x7d, 0x66, 0x82, 0x65, 0x8b, 0x39, 0x8b, 0x52, 0xb7, 0x7b, 0xd6, + 0x08, 0xf7, 0x3b, 0x06, 0x9c, 0x95, 0x95, 0x9d, 0x9d, 0x82, 0x95, 0x79, + 0x1f, 0xfb, 0x40, 0xb5, 0xf7, 0x5b, 0x06, 0x9d, 0x95, 0x95, 0x9d, 0x9d, + 0x81, 0x95, 0x79, 0x1f, 0xfb, 0x57, 0x06, 0x0e, 0xf7, 0xe2, 0xf9, 0x12, + 0x15, 0xfb, 0x18, 0x69, 0x05, 0x72, 0x84, 0x82, 0x83, 0x8b, 0x78, 0x8b, + 0x78, 0x99, 0x7b, 0x9c, 0x8b, 0x91, 0x8b, 0x8e, 0x8c, 0x96, 0x8e, 0x08, + 0xbb, 0x97, 0x8b, 0xfb, 0x81, 0x52, 0x8b, 0x05, 0x6d, 0x7d, 0x80, 0x75, + 0x75, 0x9b, 0x7f, 0xa7, 0x1f, 0xf7, 0x49, 0x06, 0xa7, 0x9a, 0x97, 0xa1, + 0xa1, 0x7d, 0x96, 0x6e, 0x1f, 0x52, 0xf7, 0xd8, 0x06, 0x0e, 0xf7, 0x91, + 0xf7, 0xce, 0x15, 0xf7, 0x29, 0xf7, 0x11, 0xa2, 0xa6, 0x8b, 0xbe, 0x8b, + 0xd0, 0x53, 0xbe, 0x40, 0x8b, 0x67, 0x8b, 0x68, 0x7e, 0x72, 0x75, 0x76, + 0x78, 0x7b, 0x6d, 0x8b, 0x77, 0x8b, 0x79, 0x9a, 0x7c, 0x9e, 0x8b, 0x98, + 0x8b, 0x98, 0x93, 0x8f, 0x97, 0x08, 0x91, 0x9e, 0x8c, 0x8c, 0x90, 0x91, + 0x98, 0x9b, 0x9f, 0x93, 0xa2, 0x8b, 0xb0, 0x8b, 0xa7, 0x75, 0x8b, 0x6f, + 0x8b, 0x6f, 0x74, 0x74, 0xfb, 0x4e, 0xfb, 0x2e, 0x08, 0x47, 0xf7, 0xac, + 0xc3, 0x07, 0xa8, 0x80, 0x99, 0x74, 0x1e, 0x78, 0x8b, 0x80, 0x80, 0x88, + 0x76, 0x08, 0xfb, 0x01, 0x06, 0x0e, 0xf7, 0xb2, 0xf8, 0x78, 0x15, 0x78, + 0x7c, 0x7d, 0x78, 0x1f, 0x8b, 0x78, 0x98, 0x7f, 0xa0, 0x89, 0xa7, 0x8a, + 0x90, 0x8a, 0x97, 0x86, 0xa5, 0x7f, 0x9d, 0x76, 0x8b, 0x76, 0x8b, 0x69, + 0x6b, 0x79, 0x4f, 0x8b, 0x65, 0x8b, 0x79, 0x8e, 0x7c, 0x95, 0x81, 0x92, + 0x87, 0x8c, 0x83, 0x8b, 0x08, 0x79, 0x7c, 0x7c, 0x78, 0x6a, 0xbd, 0x76, + 0xd9, 0x1f, 0xbd, 0x8b, 0xae, 0x94, 0xa5, 0x9e, 0xa7, 0xa0, 0x9d, 0xae, + 0x8b, 0xac, 0x8b, 0xb1, 0x74, 0xad, 0x62, 0xa0, 0x8c, 0x8c, 0x8d, 0x8c, + 0x8b, 0x8b, 0x08, 0xa9, 0x9e, 0x9d, 0xa8, 0x8b, 0xaa, 0x08, 0xc9, 0x55, + 0xb9, 0x42, 0x49, 0x4e, 0x6a, 0x66, 0x79, 0x9a, 0x7b, 0x9d, 0x1e, 0x94, + 0x8b, 0x94, 0x8f, 0x91, 0x91, 0x9e, 0xa0, 0x9a, 0x91, 0xac, 0x8b, 0x08, + 0xb1, 0xa4, 0x7b, 0x71, 0x74, 0x73, 0x76, 0x70, 0x1f, 0x72, 0x06, 0x0e, + 0xf7, 0xc9, 0xf7, 0x6a, 0x15, 0xb0, 0xa8, 0xa8, 0xb0, 0xb0, 0x6e, 0xa8, + 0x66, 0x1f, 0x79, 0x06, 0x67, 0x6d, 0x6d, 0x67, 0x67, 0xa9, 0x6d, 0xaf, + 0x1f, 0x9d, 0x06, 0x0e, 0xf8, 0x80, 0xf7, 0x79, 0x15, 0xa1, 0x8b, 0x97, + 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x84, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x81, 0x8d, 0x71, 0x8b, 0x08, 0xfc, 0x14, + 0x06, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, 0x81, 0x82, 0x7b, 0x8b, + 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x81, 0x94, 0x84, 0x96, 0x89, 0xa4, + 0x8b, 0x08, 0xf8, 0x14, 0x06, 0x0e, 0xf7, 0xc0, 0xf8, 0xe8, 0x15, 0x2a, + 0x3d, 0x3c, 0x2a, 0x2a, 0xda, 0x3b, 0xe9, 0xee, 0xd9, 0xd9, 0xee, 0xec, + 0x3d, 0xda, 0x2a, 0x1f, 0x4e, 0x04, 0xca, 0xbe, 0x57, 0x4c, 0x4b, 0x58, + 0x57, 0x4b, 0x4e, 0x57, 0xc0, 0xca, 0xca, 0xbe, 0xbf, 0xca, 0x1f, 0x0e, + 0xf7, 0x00, 0xf7, 0xde, 0x15, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7c, + 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x93, 0x7c, 0x98, 0x82, 0x94, + 0x83, 0x97, 0x89, 0xa3, 0x8b, 0x08, 0xf8, 0x14, 0x06, 0xa1, 0x8b, 0x97, + 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfc, 0x14, + 0x06, 0x0e, 0xf7, 0xc0, 0xf7, 0x65, 0x15, 0xf2, 0x24, 0x05, 0xa0, 0x76, + 0x94, 0x86, 0x9c, 0x8b, 0xa6, 0x8b, 0xa2, 0xa2, 0x8b, 0xa6, 0x8b, 0x9b, + 0x85, 0x96, 0x77, 0x9f, 0x08, 0x24, 0xf2, 0xf2, 0xf2, 0x05, 0x9f, 0xa0, + 0x91, 0x95, 0x8b, 0x9b, 0x8b, 0xa6, 0x74, 0xa2, 0x70, 0x8b, 0x7a, 0x8b, + 0x83, 0x86, 0x75, 0x76, 0x08, 0x24, 0x24, 0x24, 0xf2, 0x05, 0x76, 0x9f, + 0x81, 0x91, 0x7b, 0x8b, 0x70, 0x8b, 0x74, 0x74, 0x8b, 0x70, 0x8b, 0x7a, + 0x90, 0x83, 0xa0, 0x75, 0x08, 0xf2, 0x24, 0x24, 0x24, 0x05, 0x76, 0x76, + 0x86, 0x82, 0x8b, 0x7b, 0x8b, 0x6f, 0xa2, 0x74, 0xa6, 0x8b, 0x9b, 0x8b, + 0x95, 0x91, 0xa0, 0x9f, 0x08, 0xf2, 0xf2, 0x05, 0x0e, 0xf7, 0x00, 0xf7, + 0xde, 0x15, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7d, 0x82, 0x81, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, 0x97, 0x89, + 0xa3, 0x8b, 0x08, 0xf8, 0x14, 0x06, 0xa1, 0x8b, 0x97, 0x8d, 0x93, 0x90, + 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, + 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfc, 0x14, 0x06, 0xf7, 0x54, + 0xfb, 0x3e, 0x15, 0x5e, 0x6d, 0x70, 0x64, 0x64, 0xa9, 0x70, 0xb8, 0xb8, + 0xa9, 0xa5, 0xb2, 0xb4, 0x6e, 0xa5, 0x5d, 0x1f, 0xf8, 0x08, 0x04, 0x5e, + 0x6d, 0x70, 0x64, 0x64, 0xa9, 0x70, 0xb8, 0xb8, 0xa9, 0xa5, 0xb2, 0xb4, + 0x6e, 0xa5, 0x5d, 0x1f, 0x0e, 0xf7, 0x28, 0xf8, 0x92, 0x15, 0xae, 0x5a, + 0x06, 0x6d, 0x98, 0x7b, 0xa3, 0xa3, 0x98, 0x9b, 0xa9, 0x1e, 0xf7, 0x0e, + 0xfb, 0xb6, 0xfb, 0x0e, 0x07, 0x6d, 0x98, 0x7b, 0xa2, 0xa3, 0x98, 0x9b, + 0xa9, 0x1e, 0xbc, 0xae, 0xfb, 0x6d, 0x74, 0x07, 0x6d, 0x7b, 0x7f, 0x73, + 0x73, 0x9c, 0x7e, 0xa8, 0x1f, 0xf7, 0x0a, 0x06, 0xa9, 0x9c, 0x98, 0xa3, + 0xa3, 0x7b, 0x97, 0x6c, 0x1f, 0x75, 0xf7, 0x6d, 0x06, 0xf7, 0x77, 0x3c, + 0x15, 0xc8, 0xfb, 0x14, 0x9e, 0x8b, 0xc3, 0xf7, 0x12, 0x8b, 0xfb, 0x1c, + 0x05, 0x6c, 0x7b, 0x7f, 0x73, 0x73, 0x9c, 0x7e, 0xa9, 0x1f, 0xca, 0x06, + 0xa9, 0x9b, 0x98, 0xa3, 0x1f, 0x8b, 0x9f, 0x7d, 0x99, 0x75, 0x8d, 0x08, + 0xf7, 0x6e, 0x07, 0x9e, 0x8e, 0x97, 0x99, 0x8b, 0x9e, 0x08, 0xa3, 0x7b, + 0x97, 0x6d, 0x1e, 0x41, 0x8b, 0x57, 0xfb, 0x15, 0x56, 0xf7, 0x15, 0x42, + 0x8b, 0x05, 0x6c, 0x7c, 0x7f, 0x73, 0x1f, 0x8b, 0x78, 0x97, 0x7d, 0x9e, + 0x88, 0x08, 0xfb, 0x6e, 0x07, 0x74, 0x89, 0x7e, 0x7d, 0x8b, 0x77, 0x08, + 0x73, 0x9b, 0x7e, 0xa9, 0x1e, 0xca, 0x06, 0xaa, 0x9b, 0x98, 0xa3, 0xa3, + 0x7b, 0x97, 0x6c, 0x1f, 0xf7, 0x1e, 0x07, 0x0e, 0xf7, 0xf2, 0xf7, 0xde, + 0x15, 0xf7, 0x21, 0x06, 0xa2, 0x8b, 0x97, 0x8d, 0x93, 0x90, 0x9a, 0x94, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, 0x9a, 0x7e, 0x95, 0x81, 0x92, + 0x83, 0x8d, 0x6f, 0x8b, 0x08, 0xfb, 0x21, 0xf7, 0x14, 0x06, 0x8b, 0xa5, + 0x8a, 0x92, 0x85, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, 0x7b, 0x8b, + 0x7c, 0x83, 0x82, 0x7e, 0x83, 0x82, 0x89, 0x81, 0x8b, 0x71, 0x08, 0xfb, + 0x14, 0xfb, 0x22, 0x07, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7d, 0x82, + 0x81, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, + 0x97, 0x89, 0xa3, 0x8b, 0x08, 0xf7, 0x22, 0x27, 0x06, 0x8b, 0x74, 0x8d, + 0x81, 0x90, 0x82, 0x94, 0x7d, 0x9c, 0x81, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, + 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0xef, 0x07, + 0xfb, 0x86, 0xfb, 0x7a, 0x15, 0x72, 0x8b, 0x83, 0x8a, 0x82, 0x85, 0x7d, + 0x82, 0x81, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, + 0x83, 0x97, 0x89, 0xa3, 0x8b, 0x08, 0xf8, 0x14, 0x06, 0xa1, 0x8b, 0x97, + 0x8d, 0x93, 0x90, 0x9a, 0x94, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x83, + 0x9a, 0x7e, 0x95, 0x81, 0x92, 0x83, 0x8d, 0x70, 0x8b, 0x08, 0xfc, 0x14, + 0x06, 0x0e, 0xf7, 0x1a, 0xf9, 0x12, 0x15, 0xfb, 0x18, 0x69, 0x05, 0x72, + 0x84, 0x82, 0x83, 0x8b, 0x78, 0x8b, 0x78, 0x99, 0x7b, 0x9c, 0x8b, 0x91, + 0x8b, 0x8e, 0x8c, 0x96, 0x8e, 0x08, 0xbb, 0x97, 0x8b, 0xfb, 0x81, 0x52, + 0x8b, 0x05, 0x6d, 0x7d, 0x80, 0x75, 0x75, 0x9b, 0x7f, 0xa7, 0x1f, 0xf7, + 0x49, 0x06, 0xa7, 0x9a, 0x97, 0xa1, 0xa1, 0x7d, 0x96, 0x6e, 0x1f, 0x52, + 0xf7, 0xd8, 0x06, 0xf7, 0xe7, 0xfb, 0x02, 0x15, 0x93, 0x98, 0x8e, 0x92, + 0x8b, 0x92, 0x8b, 0x9b, 0x7a, 0x9b, 0x7a, 0x8b, 0x7c, 0x8b, 0x83, 0x85, + 0x7f, 0x77, 0x08, 0xfb, 0x98, 0xfc, 0x57, 0x05, 0x84, 0x80, 0x88, 0x82, + 0x8b, 0x85, 0x8b, 0x7a, 0x9b, 0x7b, 0x9d, 0x8b, 0x99, 0x8b, 0x94, 0x92, + 0x96, 0x9e, 0x08, 0xf7, 0x98, 0xf8, 0x57, 0x05, 0x77, 0xfc, 0x61, 0x15, + 0xf7, 0x29, 0xf7, 0x11, 0xa2, 0xa6, 0x8b, 0xbe, 0x8b, 0xd0, 0x53, 0xbe, + 0x40, 0x8b, 0x67, 0x8b, 0x68, 0x7e, 0x72, 0x75, 0x76, 0x78, 0x7b, 0x6d, + 0x8b, 0x77, 0x8b, 0x79, 0x9a, 0x7c, 0x9e, 0x8b, 0x98, 0x8b, 0x98, 0x93, + 0x8f, 0x97, 0x08, 0x91, 0x9e, 0x8c, 0x8c, 0x90, 0x91, 0x98, 0x9b, 0x9f, + 0x93, 0xa2, 0x8b, 0xb0, 0x8b, 0xa7, 0x75, 0x8b, 0x6f, 0x8b, 0x6f, 0x74, + 0x74, 0xfb, 0x4e, 0xfb, 0x2e, 0x08, 0x47, 0xf7, 0xac, 0xc3, 0x07, 0xa8, + 0x80, 0x99, 0x74, 0x1e, 0x78, 0x8b, 0x80, 0x80, 0x88, 0x76, 0x08, 0xfb, + 0x01, 0x06, 0x0e, 0xf7, 0x1a, 0xf9, 0x12, 0x15, 0xfb, 0x18, 0x69, 0x05, + 0x72, 0x84, 0x82, 0x83, 0x8b, 0x78, 0x8b, 0x78, 0x99, 0x7b, 0x9c, 0x8b, + 0x91, 0x8b, 0x8e, 0x8c, 0x96, 0x8e, 0x08, 0xbb, 0x97, 0x8b, 0xfb, 0x81, + 0x52, 0x8b, 0x05, 0x6d, 0x7d, 0x80, 0x75, 0x75, 0x9b, 0x7f, 0xa7, 0x1f, + 0xf7, 0x49, 0x06, 0xa7, 0x9a, 0x97, 0xa1, 0xa1, 0x7d, 0x96, 0x6e, 0x1f, + 0x52, 0xf7, 0xd8, 0x06, 0xf7, 0xe7, 0xfb, 0x02, 0x15, 0x93, 0x98, 0x8e, + 0x92, 0x8b, 0x92, 0x8b, 0x9b, 0x7a, 0x9b, 0x7a, 0x8b, 0x7c, 0x8b, 0x83, + 0x85, 0x7f, 0x77, 0x08, 0xfb, 0x98, 0xfc, 0x57, 0x05, 0x84, 0x80, 0x88, + 0x82, 0x8b, 0x85, 0x8b, 0x7a, 0x9b, 0x7b, 0x9d, 0x8b, 0x99, 0x8b, 0x94, + 0x92, 0x96, 0x9e, 0x08, 0xf7, 0x98, 0xf8, 0x57, 0x05, 0xf7, 0x0b, 0xfb, + 0x28, 0x15, 0x37, 0x8b, 0xfb, 0x26, 0xfb, 0x86, 0x8b, 0x54, 0xf7, 0x37, + 0x8b, 0x8b, 0x7b, 0x78, 0x8b, 0x05, 0x6e, 0x7d, 0x80, 0x75, 0x75, 0x9a, + 0x7f, 0xa7, 0x1f, 0xda, 0x06, 0xa7, 0x9b, 0x97, 0xa1, 0x1f, 0x8b, 0x9f, + 0x7d, 0x97, 0x74, 0x8c, 0x08, 0x9b, 0x07, 0xa3, 0x8c, 0x98, 0x98, 0x8b, + 0x9f, 0x8b, 0x9f, 0x7d, 0x97, 0x74, 0x8c, 0x08, 0xf7, 0x7a, 0x07, 0x48, + 0xfb, 0x7a, 0x15, 0x3c, 0x8b, 0xda, 0xf7, 0x15, 0x8b, 0xfb, 0x15, 0x05, + 0x0e, 0xe1, 0xf8, 0x78, 0x15, 0x78, 0x7c, 0x7d, 0x78, 0x1f, 0x8b, 0x78, + 0x98, 0x7f, 0xa0, 0x89, 0xa7, 0x8a, 0x90, 0x8a, 0x97, 0x86, 0xa5, 0x7f, + 0x9d, 0x76, 0x8b, 0x76, 0x8b, 0x69, 0x6b, 0x79, 0x4f, 0x8b, 0x65, 0x8b, + 0x79, 0x8e, 0x7c, 0x95, 0x81, 0x92, 0x87, 0x8c, 0x83, 0x8b, 0x08, 0x79, + 0x7c, 0x7c, 0x78, 0x6a, 0xbd, 0x76, 0xd9, 0x1f, 0xbd, 0x8b, 0xae, 0x94, + 0xa5, 0x9e, 0xa7, 0xa0, 0x9d, 0xae, 0x8b, 0xac, 0x8b, 0xb1, 0x74, 0xad, + 0x62, 0xa0, 0x8c, 0x8c, 0x8d, 0x8c, 0x8b, 0x8b, 0x08, 0xa9, 0x9e, 0x9d, + 0xa8, 0x8b, 0xaa, 0x08, 0xc9, 0x55, 0xb9, 0x42, 0x49, 0x4e, 0x6a, 0x66, + 0x79, 0x9a, 0x7b, 0x9d, 0x1e, 0x94, 0x8b, 0x94, 0x8f, 0x91, 0x91, 0x9e, + 0xa0, 0x9a, 0x91, 0xac, 0x8b, 0x08, 0xb1, 0xa4, 0x7b, 0x71, 0x74, 0x73, + 0x76, 0x70, 0x1f, 0x72, 0x06, 0xf8, 0x18, 0xb7, 0x15, 0x91, 0x96, 0x8f, + 0x95, 0x8b, 0x91, 0x8b, 0x9b, 0x7a, 0x9b, 0x7a, 0x8b, 0x7c, 0x8b, 0x83, + 0x85, 0x80, 0x77, 0x08, 0xfb, 0x99, 0xfc, 0x57, 0x05, 0x83, 0x7e, 0x89, + 0x85, 0x8b, 0x84, 0x8b, 0x79, 0x9b, 0x7c, 0x9d, 0x8b, 0x99, 0x8b, 0x94, + 0x92, 0x96, 0x9e, 0x08, 0xf7, 0x99, 0xf8, 0x57, 0x05, 0xf7, 0x0b, 0xfb, + 0x28, 0x15, 0x37, 0x8b, 0xfb, 0x27, 0xfb, 0x86, 0x8b, 0x54, 0xf7, 0x38, + 0x8b, 0x8b, 0x7b, 0x78, 0x8b, 0x05, 0x6d, 0x7d, 0x80, 0x75, 0x75, 0x9b, + 0x7f, 0xa7, 0x1f, 0xda, 0x06, 0xa7, 0x9b, 0x97, 0xa1, 0x1f, 0x8b, 0x9f, + 0x7d, 0x97, 0x74, 0x8c, 0x08, 0x9b, 0x07, 0xa3, 0x8c, 0x98, 0x98, 0x8b, + 0x9f, 0x8b, 0x9f, 0x7d, 0x97, 0x74, 0x8c, 0x08, 0xf7, 0x7a, 0x07, 0x48, + 0xfb, 0x7a, 0x15, 0x3b, 0x8b, 0xdb, 0xf7, 0x15, 0x8b, 0xfb, 0x15, 0x05, + 0x0e, 0xf7, 0x1b, 0xf7, 0xa1, 0x15, 0x34, 0xd2, 0x4b, 0xeb, 0xd2, 0xcd, + 0xaf, 0xb2, 0x9e, 0x7a, 0x9c, 0x78, 0x1e, 0x82, 0x8b, 0x82, 0x87, 0x84, + 0x84, 0x74, 0x73, 0x7e, 0x86, 0x64, 0x8b, 0x08, 0x50, 0x65, 0xab, 0xbc, + 0x1f, 0xad, 0x07, 0xc0, 0xaf, 0xb1, 0xbe, 0x1e, 0xad, 0x8b, 0xa9, 0x7b, + 0x8e, 0x78, 0x90, 0x72, 0x95, 0x80, 0xa0, 0x8b, 0x08, 0xa1, 0x98, 0x9b, + 0xa7, 0x1f, 0x8b, 0xc1, 0x8b, 0x91, 0x05, 0xa2, 0x7e, 0x9a, 0x77, 0x1e, + 0x7d, 0x8b, 0x82, 0x84, 0x86, 0x7f, 0x6f, 0x99, 0x74, 0x90, 0x6f, 0x8b, + 0x08, 0x32, 0x48, 0x46, 0x2f, 0x1f, 0x67, 0x07, 0xf7, 0x38, 0xf7, 0xdd, + 0x15, 0xfb, 0x3d, 0xfb, 0x1d, 0xfb, 0x1d, 0xfb, 0x3d, 0xfb, 0x3c, 0xf7, + 0x1e, 0xfb, 0x1f, 0xf7, 0x39, 0xf7, 0x41, 0xf7, 0x1d, 0xf7, 0x1c, 0xf7, + 0x3f, 0xf7, 0x3d, 0xfb, 0x1d, 0xf7, 0x1d, 0xfb, 0x3e, 0x1f, 0x8c, 0x42, + 0x15, 0xf7, 0x14, 0xf4, 0x23, 0xfb, 0x15, 0xfb, 0x17, 0x23, 0x24, 0xfb, + 0x18, 0xfb, 0x12, 0x22, 0xf5, 0xf7, 0x14, 0xf7, 0x15, 0xf3, 0xf3, 0xf7, + 0x16, 0x1f, 0x0e, 0xf7, 0xa1, 0xf7, 0x8a, 0x15, 0x9a, 0x06, 0xa7, 0x7e, + 0xb2, 0x51, 0x97, 0x5a, 0x08, 0xb3, 0x06, 0xa7, 0x9b, 0x98, 0xa2, 0x1f, + 0x8b, 0x9f, 0x7e, 0x98, 0x74, 0x8d, 0x75, 0xb1, 0x84, 0x94, 0x73, 0xa1, + 0xb0, 0x9c, 0xa3, 0xad, 0x8b, 0xb0, 0x08, 0xc8, 0x57, 0xb6, 0x40, 0x1e, + 0x2e, 0x06, 0x6e, 0x7b, 0x7f, 0x74, 0x1f, 0x8b, 0x75, 0x9a, 0x7e, 0xa7, + 0x8a, 0x08, 0xfb, 0x52, 0x07, 0x6f, 0x7c, 0x7e, 0x75, 0x74, 0x9b, 0x7e, + 0xa8, 0x1f, 0xcf, 0x06, 0xa7, 0x9b, 0x98, 0xa2, 0xa1, 0x7b, 0x98, 0x71, + 0x1f, 0xbc, 0x07, 0xd1, 0x04, 0xd2, 0xa4, 0x07, 0xac, 0xa0, 0x7e, 0x78, + 0x75, 0x74, 0x7a, 0x6c, 0x1f, 0x72, 0x06, 0xaa, 0xf7, 0xae, 0x15, 0xfb, + 0x3d, 0xfb, 0x1e, 0xfb, 0x1e, 0xfb, 0x3c, 0xfb, 0x3c, 0xf7, 0x1e, 0xfb, + 0x1f, 0xf7, 0x39, 0xf7, 0x41, 0xf7, 0x1d, 0xf7, 0x1c, 0xf7, 0x3f, 0xf7, + 0x3d, 0xfb, 0x1e, 0xf7, 0x1d, 0xfb, 0x3c, 0x1f, 0x42, 0x04, 0xf7, 0x14, + 0xf4, 0x22, 0xfb, 0x14, 0xfb, 0x17, 0x23, 0x24, 0xfb, 0x18, 0xfb, 0x12, + 0x22, 0xf5, 0xf7, 0x14, 0xf7, 0x14, 0xf4, 0xf4, 0xf7, 0x15, 0x1f, 0x0e, + 0x0e, 0xf8, 0x65, 0xf8, 0x51, 0x15, 0xfb, 0xf9, 0x06, 0x71, 0x8b, 0x84, + 0x8a, 0x82, 0x85, 0x7c, 0x82, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, + 0x7b, 0x98, 0x82, 0x94, 0x83, 0x97, 0x89, 0xa3, 0x8b, 0x08, 0xf7, 0x95, + 0xfb, 0x38, 0x06, 0x8b, 0x74, 0x8d, 0x81, 0x90, 0x82, 0x94, 0x7c, 0x9c, + 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, 0x8d, + 0x93, 0x8b, 0xa6, 0x08, 0xf7, 0x9c, 0x07, 0x0e, 0xf7, 0xf2, 0xf8, 0xc0, + 0x15, 0x8b, 0x93, 0x8b, 0x8d, 0x8a, 0x96, 0x87, 0xa7, 0x79, 0x9c, 0x70, + 0x8b, 0x7b, 0x8b, 0x7c, 0x83, 0x81, 0x7e, 0x84, 0x82, 0x89, 0x80, 0x8b, + 0x72, 0x08, 0xfb, 0x5f, 0x07, 0x8b, 0x74, 0x8d, 0x80, 0x90, 0x83, 0x94, + 0x7c, 0x9c, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, + 0x95, 0x8d, 0x93, 0x8b, 0xa6, 0x08, 0xf7, 0x5f, 0x07, 0xfc, 0x4c, 0x04, + 0x8b, 0xa3, 0x89, 0x94, 0x86, 0x94, 0x82, 0x9a, 0x7a, 0x94, 0x7a, 0x8b, + 0x7b, 0x8b, 0x7c, 0x83, 0x81, 0x7f, 0x84, 0x81, 0x89, 0x81, 0x8b, 0x71, + 0x08, 0xfb, 0x5f, 0x07, 0x8b, 0x74, 0x8d, 0x80, 0x90, 0x83, 0x95, 0x7c, + 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, 0x98, 0x92, 0x95, + 0x8d, 0x95, 0x8b, 0xa4, 0x08, 0xf7, 0x5f, 0x07, 0x0e, 0xf7, 0x57, 0x84, + 0x15, 0x9f, 0x85, 0x9c, 0x88, 0xa0, 0x8b, 0xbf, 0x8b, 0xbe, 0x97, 0xc1, + 0xa5, 0x08, 0x75, 0xea, 0x07, 0xa0, 0x8b, 0x98, 0x8d, 0x93, 0x90, 0x9a, + 0x95, 0x94, 0x9b, 0x8b, 0x9c, 0x08, 0xab, 0x75, 0x9d, 0x64, 0x1e, 0xf7, + 0xe5, 0xfb, 0x1b, 0x07, 0x73, 0x8b, 0x82, 0x8a, 0x82, 0x85, 0x7c, 0x82, + 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x98, 0x82, 0x94, 0x83, + 0x96, 0x89, 0xa4, 0x8b, 0x08, 0xae, 0xfb, 0x5b, 0x06, 0x4b, 0x64, 0x61, + 0x7c, 0x5f, 0x8b, 0x08, 0x5d, 0x78, 0x9c, 0xb6, 0x1f, 0xf7, 0xb9, 0xfb, + 0x08, 0x07, 0x70, 0x8b, 0x86, 0x8a, 0x81, 0x85, 0x7c, 0x82, 0x82, 0x7a, + 0x8b, 0x7a, 0x8b, 0x7c, 0x93, 0x7b, 0x97, 0x82, 0x95, 0x83, 0x96, 0x89, + 0xa4, 0x8b, 0x08, 0x9b, 0xfc, 0x3c, 0x06, 0x8b, 0x74, 0x8d, 0x80, 0x90, + 0x83, 0x95, 0x7c, 0x9b, 0x82, 0x9c, 0x8b, 0x9b, 0x8b, 0x9a, 0x93, 0x95, + 0x98, 0x92, 0x95, 0x8d, 0x94, 0x8b, 0xa5, 0x08, 0xdb, 0x07, 0x0e, 0xf8, + 0xec, 0x14, 0x8b, 0x15, 0x7d, 0x99, 0xf8, 0x49, 0x98, 0xf7, 0x19, 0x99, + 0xa5, 0x9a, 0x06, 0x1e, 0x0a, 0x03, 0x96, 0x25, 0xff, 0x0c, 0x09, 0x8b, + 0x0c, 0x0a, 0xf0, 0x0a, 0xe8, 0x93, 0x0c, 0x0c, 0xf0, 0x0b, 0xf0, 0x0c, + 0x0d, 0x8b, 0x0c, 0x0e +}; +const unsigned int fonts_NimbusMonL_Bold_cff_len = 32860; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusMonL-BoldObli.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusMonL-BoldObli.cff.c new file mode 100644 index 00000000000..19d39a70339 --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusMonL-BoldObli.cff.c @@ -0,0 +1,2802 @@ +const unsigned char fonts_NimbusMonL_BoldObli_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x14, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x4d, 0x6f, 0x6e, 0x4c, 0x2d, 0x42, 0x6f, 0x6c, 0x64, + 0x4f, 0x62, 0x6c, 0x69, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x41, 0xf8, + 0x1f, 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, + 0x14, 0x04, 0x8c, 0x0c, 0x01, 0x7f, 0x0c, 0x02, 0x1d, 0x00, 0x4c, 0x9d, + 0x14, 0x0d, 0x4e, 0xfb, 0x79, 0xf9, 0x73, 0xf9, 0xfb, 0x05, 0x1d, 0x00, + 0x00, 0x00, 0xff, 0x0f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1d, 0x00, + 0x00, 0x02, 0xd2, 0x11, 0x1d, 0x00, 0x00, 0x00, 0x28, 0x1d, 0x00, 0x00, + 0x83, 0x08, 0x12, 0x00, 0x08, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, + 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x5f, 0x00, 0x79, 0x00, 0x86, + 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, + 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, + 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, + 0x6d, 0x62, 0x75, 0x73, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x20, 0x4c, 0x20, + 0x42, 0x6f, 0x6c, 0x64, 0x20, 0x4f, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, + 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x20, + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, + 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, + 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, + 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, + 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, + 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, + 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, + 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, + 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, + 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, + 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, + 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, + 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, + 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, + 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, + 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, + 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, + 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, + 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, + 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, + 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, + 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x00, 0x81, + 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, + 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8c, 0x00, 0x8d, + 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, + 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, 0xae, 0x00, 0xac, + 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, 0xb4, 0x00, 0xb2, + 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, 0xb9, 0x00, 0xb7, + 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, 0xbc, 0x00, 0xbf, + 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, 0xc2, 0x00, 0xc5, + 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xc8, 0x00, 0xcb, + 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd1, 0x00, 0xcf, + 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd6, 0x00, 0xd4, + 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, 0xd9, 0x00, 0xdc, + 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xdf, 0x00, 0xe2, + 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, 0x87, 0x00, 0x96, + 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, 0xa1, 0x00, 0xa6, + 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9b, 0x00, 0x9e, + 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, 0x97, 0x00, 0xa0, + 0x00, 0x98, 0x00, 0xea, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x59, 0x00, 0x9e, 0x01, 0x9e, 0x02, 0x98, 0x03, 0x23, 0x03, + 0xd4, 0x03, 0xfa, 0x04, 0x47, 0x04, 0x93, 0x05, 0x12, 0x05, 0x8b, 0x05, + 0xb1, 0x05, 0xe8, 0x06, 0x03, 0x06, 0x39, 0x06, 0xab, 0x07, 0x05, 0x07, + 0x7a, 0x08, 0x02, 0x08, 0x69, 0x08, 0xf2, 0x09, 0x7d, 0x09, 0xbd, 0x0a, + 0x2f, 0x0a, 0xba, 0x0a, 0xef, 0x0b, 0x2b, 0x0b, 0x7e, 0x0b, 0xea, 0x0c, + 0x3d, 0x0c, 0xc0, 0x0d, 0x78, 0x0e, 0x15, 0x0e, 0xa2, 0x0f, 0x3b, 0x0f, + 0xba, 0x10, 0x7d, 0x11, 0x39, 0x11, 0xf1, 0x12, 0xd8, 0x13, 0x4a, 0x13, + 0xd1, 0x14, 0xaf, 0x15, 0x28, 0x15, 0xda, 0x16, 0x71, 0x16, 0xbc, 0x17, + 0x3e, 0x17, 0xf1, 0x18, 0x90, 0x19, 0x53, 0x19, 0xd9, 0x1a, 0x79, 0x1a, + 0xfc, 0x1b, 0x83, 0x1c, 0x42, 0x1c, 0xec, 0x1d, 0x48, 0x1d, 0x94, 0x1d, + 0xca, 0x1e, 0x15, 0x1e, 0x53, 0x1e, 0x5f, 0x1e, 0x7e, 0x1f, 0x27, 0x1f, + 0xbb, 0x20, 0x4c, 0x20, 0xf1, 0x21, 0x53, 0x21, 0xfc, 0x22, 0x86, 0x23, + 0x41, 0x23, 0xa9, 0x24, 0x05, 0x24, 0xaf, 0x25, 0x10, 0x25, 0xcf, 0x26, + 0x7a, 0x26, 0xb6, 0x27, 0x57, 0x28, 0x06, 0x28, 0x84, 0x29, 0x38, 0x29, + 0xd8, 0x2a, 0x59, 0x2a, 0xd6, 0x2b, 0x62, 0x2c, 0x1e, 0x2c, 0xbb, 0x2d, + 0x0d, 0x2d, 0x91, 0x2d, 0xd3, 0x2e, 0x56, 0x2e, 0xb3, 0x2f, 0x08, 0x2f, + 0xb8, 0x30, 0x62, 0x30, 0x98, 0x31, 0x7b, 0x32, 0x09, 0x32, 0xe8, 0x33, + 0x9a, 0x33, 0xbe, 0x33, 0xf9, 0x34, 0x74, 0x34, 0xb3, 0x34, 0xf2, 0x35, + 0xfb, 0x36, 0xed, 0x37, 0x24, 0x37, 0xa6, 0x38, 0x6a, 0x38, 0x86, 0x39, + 0x3e, 0x39, 0x55, 0x39, 0x7b, 0x39, 0xc4, 0x3a, 0x0d, 0x3a, 0x88, 0x3a, + 0xd4, 0x3b, 0x87, 0x3c, 0x09, 0x3c, 0x3f, 0x3c, 0x75, 0x3c, 0xb1, 0x3d, + 0x0e, 0x3d, 0x2c, 0x3d, 0x67, 0x3d, 0x7e, 0x3d, 0xa9, 0x3d, 0xd4, 0x3e, + 0x1c, 0x3e, 0x85, 0x3e, 0xc9, 0x3f, 0x0b, 0x3f, 0x42, 0x40, 0x27, 0x40, + 0xd9, 0x41, 0x83, 0x42, 0x2c, 0x42, 0xe8, 0x43, 0x42, 0x44, 0x34, 0x44, + 0x8d, 0x45, 0x1c, 0x45, 0xbc, 0x46, 0x54, 0x46, 0xfb, 0x47, 0xc1, 0x48, + 0x93, 0x49, 0x64, 0x4a, 0x3d, 0x4b, 0x37, 0x4b, 0xfd, 0x4c, 0xd0, 0x4d, + 0x8c, 0x4e, 0x79, 0x4f, 0x71, 0x50, 0x69, 0x51, 0x6d, 0x52, 0x08, 0x52, + 0xb2, 0x53, 0x58, 0x54, 0x04, 0x54, 0xf9, 0x55, 0x6d, 0x55, 0xed, 0x56, + 0x6c, 0x56, 0xf1, 0x57, 0x98, 0x58, 0x9a, 0x59, 0x64, 0x5a, 0x38, 0x5b, + 0x0d, 0x5b, 0xee, 0x5c, 0xcd, 0x5d, 0x66, 0x5e, 0x0c, 0x5e, 0xe0, 0x5f, + 0xb2, 0x60, 0x83, 0x61, 0x60, 0x62, 0x45, 0x63, 0x43, 0x64, 0x16, 0x64, + 0xde, 0x65, 0x6a, 0x66, 0x01, 0x66, 0x98, 0x67, 0x37, 0x67, 0xba, 0x68, + 0x47, 0x68, 0xd4, 0x69, 0x6f, 0x6a, 0x77, 0x6a, 0xdc, 0x6b, 0x4d, 0x6b, + 0xbd, 0x6c, 0x35, 0x6c, 0xcf, 0x6d, 0xbd, 0x6e, 0x68, 0x6f, 0x1d, 0x6f, + 0xd3, 0x70, 0x91, 0x71, 0x63, 0x71, 0xf0, 0x72, 0xa8, 0x73, 0x49, 0x74, + 0x11, 0x74, 0xe7, 0x75, 0x27, 0x75, 0x8d, 0x76, 0x0b, 0x76, 0x27, 0x76, + 0x5e, 0x76, 0x8d, 0x76, 0xc4, 0x77, 0x2f, 0x77, 0x91, 0x78, 0x67, 0x79, + 0x14, 0x79, 0xee, 0x7a, 0xb0, 0x7b, 0xb0, 0x7c, 0x64, 0x7d, 0x0d, 0x7d, + 0x0e, 0x7d, 0x4d, 0x7d, 0xcb, 0x7e, 0x5e, 0x0e, 0x0e, 0x0e, 0xf8, 0x7e, + 0xf8, 0xa1, 0x15, 0x94, 0xa7, 0x8d, 0x96, 0x8b, 0x98, 0x8b, 0xaf, 0x70, + 0xa4, 0x64, 0x8b, 0x70, 0x8b, 0x6f, 0x7e, 0x78, 0x75, 0x7a, 0x79, 0x85, + 0x7a, 0x86, 0x60, 0x08, 0x69, 0xfb, 0xbd, 0x05, 0x8a, 0x88, 0x8b, 0x87, + 0x8b, 0x89, 0x8b, 0x72, 0x9a, 0x7c, 0xa4, 0x8b, 0xa7, 0x8b, 0xa1, 0x9d, + 0x95, 0xaa, 0x08, 0xe7, 0xf7, 0xbd, 0x05, 0xfb, 0x4d, 0xfc, 0xb0, 0x15, + 0xb6, 0xb2, 0xb2, 0xb4, 0xa9, 0x75, 0xa1, 0x6b, 0x1f, 0x7a, 0x06, 0x61, + 0x63, 0x64, 0x63, 0x6c, 0xa1, 0x75, 0xab, 0x1f, 0x9c, 0x06, 0x0e, 0xf7, + 0x9c, 0xf8, 0xee, 0x15, 0x77, 0xfb, 0x93, 0x05, 0x8a, 0x86, 0x8b, 0x86, + 0x8b, 0x89, 0x8b, 0x7e, 0x95, 0x81, 0x99, 0x8b, 0x9f, 0x8b, 0x96, 0x96, + 0x93, 0xa4, 0x08, 0xe1, 0xf7, 0x92, 0xfb, 0x14, 0x8b, 0x05, 0xf7, 0x5c, + 0x16, 0x77, 0xfb, 0x93, 0x05, 0x8a, 0x86, 0x8b, 0x85, 0x8b, 0x8a, 0x8b, + 0x7e, 0x95, 0x81, 0x99, 0x8b, 0x9f, 0x8b, 0x96, 0x95, 0x94, 0xa5, 0x08, + 0xe0, 0xf7, 0x92, 0xfb, 0x14, 0x8b, 0x05, 0x0e, 0xf8, 0xb1, 0xf8, 0x50, + 0x15, 0xb9, 0xf7, 0x35, 0x05, 0x92, 0xa4, 0x8b, 0x8b, 0x8b, 0x90, 0x8b, + 0xa2, 0x79, 0x9c, 0x75, 0x8b, 0x7b, 0x8b, 0x7b, 0x84, 0x7f, 0x7f, 0x81, + 0x81, 0x88, 0x85, 0x83, 0x6f, 0x08, 0x5c, 0xfb, 0x3c, 0x43, 0x8b, 0xb9, + 0xf7, 0x35, 0x05, 0x90, 0x9e, 0x8c, 0x91, 0x8b, 0x93, 0x8b, 0x9f, 0x79, + 0x9c, 0x75, 0x8b, 0x6a, 0x8b, 0x76, 0x76, 0x80, 0x61, 0x08, 0x5c, 0xfb, + 0x3c, 0x70, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, + 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7b, 0x94, 0x7c, 0x98, 0x86, 0x93, 0x88, + 0x92, 0x8a, 0x9f, 0x8b, 0x08, 0x9f, 0x8b, 0x6d, 0x21, 0x6a, 0x8b, 0x05, + 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7c, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xa5, 0x8b, 0x5d, 0xfb, 0x35, 0x05, + 0x86, 0x7a, 0x8a, 0x84, 0x8b, 0x83, 0x8b, 0x76, 0x9d, 0x7a, 0xa1, 0x8b, + 0xac, 0x8b, 0xa1, 0xa1, 0x94, 0xb4, 0x08, 0xbb, 0xf7, 0x3c, 0xd3, 0x8b, + 0x5d, 0xfb, 0x35, 0x05, 0x84, 0x73, 0x8b, 0x8b, 0x8b, 0x83, 0x8b, 0x76, + 0x9c, 0x7a, 0xa1, 0x8b, 0x9a, 0x8b, 0x9b, 0x92, 0x98, 0x97, 0x91, 0x91, + 0x96, 0xa1, 0x90, 0x9b, 0x08, 0xba, 0xf7, 0x3c, 0xa5, 0x8b, 0x05, 0xa9, + 0x8b, 0x96, 0x8e, 0x9a, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, + 0x9b, 0x81, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x78, 0x8b, 0x08, + 0x78, 0x8b, 0xa9, 0xf5, 0xab, 0x8b, 0x05, 0xaa, 0x8b, 0x95, 0x8e, 0x99, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, + 0x8f, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x72, 0x06, 0xfb, 0x13, + 0x27, 0x15, 0x6c, 0x21, 0x44, 0x8b, 0xa9, 0xf5, 0xd3, 0x8b, 0x05, 0x0e, + 0xf8, 0x77, 0xf8, 0xfe, 0x15, 0x8f, 0x9e, 0x8b, 0x8d, 0x8b, 0x92, 0x8b, + 0xa1, 0x7a, 0x9b, 0x75, 0x8b, 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7f, 0x81, + 0x80, 0x87, 0x83, 0x86, 0x70, 0x08, 0x85, 0x71, 0x05, 0x24, 0x7a, 0x3c, + 0x39, 0x8b, 0x31, 0x8b, 0x4a, 0xb4, 0x62, 0xdd, 0x7a, 0x08, 0xd1, 0x7c, + 0x05, 0xbb, 0x81, 0xa0, 0x7c, 0x8b, 0x71, 0x8b, 0x59, 0x50, 0x63, 0x44, + 0x8b, 0x52, 0x8b, 0x5c, 0xa4, 0x89, 0xaa, 0x8a, 0xa6, 0x8b, 0x8b, 0x85, + 0x92, 0x84, 0x94, 0x7e, 0x91, 0x7e, 0x8b, 0x7b, 0x8b, 0x7b, 0x83, 0x7e, + 0x7e, 0x08, 0x81, 0x81, 0x87, 0x83, 0x85, 0x6f, 0x08, 0x7e, 0x4e, 0x05, + 0x88, 0x7b, 0x8a, 0x84, 0x8b, 0x85, 0x8b, 0x75, 0x9c, 0x7b, 0xa3, 0x8b, + 0x99, 0x8b, 0x95, 0x8f, 0x9e, 0x99, 0xa7, 0x7d, 0x91, 0x89, 0xb3, 0x82, + 0x08, 0x79, 0x38, 0x05, 0x88, 0x7e, 0x8a, 0x81, 0x8b, 0x84, 0x8b, 0x76, + 0x9c, 0x7b, 0xa2, 0x8b, 0x9a, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, + 0x8e, 0x93, 0x91, 0xa7, 0x08, 0x9d, 0xde, 0x05, 0xf7, 0x10, 0xa2, 0xde, + 0xdf, 0x8b, 0xf0, 0x8b, 0xd2, 0x64, 0xaf, 0x2a, 0xa0, 0x08, 0x4d, 0x99, + 0x05, 0x60, 0x94, 0x76, 0x9b, 0x8b, 0xa1, 0x08, 0xb4, 0xbb, 0xa9, 0xcc, + 0xb3, 0xb0, 0x7a, 0x79, 0x6f, 0x9a, 0x7c, 0xa7, 0x1e, 0x9b, 0x8b, 0x9b, + 0x92, 0x98, 0x99, 0x95, 0x95, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0x92, 0xab, + 0x05, 0x8e, 0x97, 0x8c, 0x95, 0x8b, 0x92, 0x8b, 0xa0, 0x7a, 0x9b, 0x74, + 0x8b, 0x81, 0x8b, 0x84, 0x89, 0x7f, 0x86, 0x86, 0x8c, 0x88, 0x8c, 0x8a, + 0x8c, 0x84, 0x8d, 0x83, 0x8e, 0x84, 0x8e, 0x08, 0x81, 0x8e, 0x05, 0x83, + 0x8d, 0x87, 0x8b, 0x80, 0x8d, 0x08, 0x91, 0xa5, 0x05, 0x0e, 0xf7, 0xfc, + 0xf8, 0xfd, 0x15, 0x33, 0x37, 0x39, 0x35, 0x4b, 0xba, 0x5c, 0xcb, 0xe5, + 0xdf, 0xdc, 0xe2, 0x1f, 0xcd, 0x5d, 0xb8, 0x48, 0x1e, 0x7d, 0x4a, 0x15, + 0xaf, 0xa4, 0x72, 0x69, 0x5d, 0x5e, 0x5f, 0x5b, 0x68, 0x72, 0xa4, 0xae, + 0xb8, 0xb8, 0xb7, 0xba, 0x1f, 0xf7, 0x6c, 0xfb, 0x71, 0x15, 0xa5, 0x92, + 0x96, 0x97, 0x8b, 0x9d, 0x8b, 0x9a, 0x82, 0x96, 0x7d, 0x8b, 0x85, 0x8b, + 0x89, 0x8b, 0x7e, 0x87, 0x08, 0xfc, 0x17, 0xfb, 0x0a, 0x05, 0x71, 0x83, + 0x80, 0x80, 0x8b, 0x79, 0x8b, 0x7c, 0x94, 0x80, 0x98, 0x8b, 0x90, 0x8b, + 0x93, 0x8c, 0x93, 0x8e, 0x08, 0xf8, 0x18, 0xf7, 0x0a, 0x05, 0xfb, 0x1d, + 0x48, 0x15, 0x33, 0x37, 0x39, 0x35, 0x4b, 0xba, 0x5c, 0xcb, 0xe5, 0xdf, + 0xdc, 0xe2, 0x1f, 0xcd, 0x5d, 0xb8, 0x48, 0x1e, 0x7d, 0x4a, 0x15, 0xaf, + 0xa4, 0x73, 0x67, 0x5d, 0x5e, 0x60, 0x5b, 0x69, 0x72, 0xa4, 0xad, 0xb9, + 0xb8, 0xb7, 0xb9, 0x1f, 0x0e, 0xf8, 0x2b, 0xf7, 0x5a, 0x15, 0x46, 0xf7, + 0x25, 0x05, 0x81, 0x9e, 0x84, 0xa1, 0x8b, 0x93, 0x8b, 0xa8, 0xab, 0xa8, + 0xab, 0x8b, 0x9f, 0x8b, 0x99, 0x83, 0xa1, 0x71, 0x08, 0xba, 0xa1, 0x05, + 0xb3, 0x9f, 0x98, 0x9a, 0x8b, 0xa7, 0x8b, 0x9f, 0x79, 0x9e, 0x77, 0x8b, + 0x83, 0x8b, 0x81, 0x89, 0x7f, 0x86, 0x73, 0x97, 0x78, 0x90, 0x73, 0x8b, + 0x30, 0x8b, 0x2b, 0x31, 0x8b, 0x35, 0x8b, 0x78, 0x8f, 0x78, 0x98, 0x6a, + 0x08, 0x37, 0x60, 0x59, 0x41, 0x8b, 0x3b, 0x8b, 0x41, 0xc5, 0x5d, 0xea, + 0x8b, 0xbf, 0x8b, 0xab, 0x93, 0xad, 0xa0, 0x08, 0x93, 0x7c, 0xc8, 0x8b, + 0x05, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, + 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, + 0x8b, 0x08, 0x83, 0x06, 0x9c, 0xa0, 0x96, 0x9e, 0x9e, 0xb3, 0xa8, 0x8d, + 0xa5, 0xa7, 0x8b, 0xaa, 0x8b, 0x9a, 0x82, 0x9a, 0x7e, 0x90, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x57, 0x8b, 0x05, 0x62, 0x39, 0x05, 0x41, + 0x29, 0x15, 0x76, 0x80, 0x7f, 0x88, 0x72, 0x8b, 0x5c, 0x8b, 0x73, 0x99, + 0x8b, 0xa8, 0x8b, 0xb1, 0xa6, 0xad, 0xb7, 0x9e, 0x08, 0xc5, 0xfb, 0x0c, + 0x05, 0x0e, 0xf7, 0xf2, 0xf9, 0x03, 0x15, 0xfb, 0x0c, 0xfb, 0x89, 0x05, + 0x84, 0x7d, 0x8a, 0x87, 0x8b, 0x84, 0x8b, 0x7f, 0x97, 0x81, 0x99, 0x8b, + 0x97, 0x8b, 0x98, 0x93, 0x97, 0x9b, 0x08, 0xf7, 0x5a, 0xf7, 0xa0, 0xfb, + 0x19, 0x8b, 0x05, 0x0e, 0xf8, 0xd0, 0xf9, 0x0c, 0x15, 0x6f, 0x8b, 0x77, + 0x7a, 0x56, 0x47, 0xfb, 0x07, 0xfb, 0x29, 0x57, 0xfb, 0x15, 0x8b, 0xfb, + 0x1e, 0x8b, 0x34, 0xa8, 0xfb, 0x08, 0xb0, 0x4d, 0x92, 0x7e, 0x97, 0x85, + 0x9b, 0x8b, 0xab, 0x8b, 0xa9, 0xa8, 0x8b, 0xab, 0x8b, 0x90, 0x8a, 0x90, + 0x86, 0x97, 0x08, 0x6b, 0xda, 0x7e, 0xc9, 0x8b, 0xd0, 0x8b, 0xf7, 0x1c, + 0xc1, 0xf7, 0x11, 0xf7, 0x0f, 0xf7, 0x28, 0x9a, 0x9d, 0x90, 0x96, 0x8b, + 0x9a, 0x8b, 0xa2, 0x7a, 0x9b, 0x73, 0x8b, 0x08, 0x0e, 0xf7, 0xc2, 0xf9, + 0x0c, 0x15, 0x6a, 0x6e, 0x6e, 0x6b, 0x1f, 0x8b, 0x85, 0x8c, 0x86, 0x90, + 0x80, 0xaa, 0x3d, 0x99, 0x4c, 0x8b, 0x47, 0x8b, 0xfb, 0x1e, 0x57, 0xfb, + 0x0d, 0xfb, 0x11, 0xfb, 0x2b, 0x7c, 0x79, 0x86, 0x80, 0x8b, 0x7c, 0x8b, + 0x74, 0x9c, 0x7b, 0xa3, 0x8b, 0xa7, 0x8b, 0xa0, 0x9d, 0xbf, 0xce, 0x08, + 0xf7, 0x09, 0xf7, 0x2c, 0xbd, 0xf7, 0x12, 0x8b, 0xf7, 0x1e, 0x8b, 0xe2, + 0x6e, 0xf7, 0x08, 0x66, 0xc9, 0x84, 0x98, 0x7f, 0x91, 0x7b, 0x8b, 0x08, + 0x0e, 0xf7, 0xbe, 0xf8, 0x08, 0x15, 0x48, 0x44, 0x05, 0x74, 0x72, 0x85, + 0x80, 0x8b, 0x7a, 0x8b, 0x74, 0x9c, 0x7a, 0xa3, 0x8b, 0x9f, 0x8b, 0x95, + 0x91, 0xa5, 0xa7, 0x08, 0xcf, 0xd3, 0xaf, 0x43, 0x05, 0x9a, 0x6f, 0x93, + 0x85, 0x9f, 0x8b, 0xaa, 0x8b, 0xaa, 0xa9, 0x8b, 0xa8, 0x8b, 0x94, 0x89, + 0x92, 0x82, 0x9d, 0x08, 0x66, 0xd2, 0xe7, 0xa7, 0x05, 0xb6, 0x98, 0x9e, + 0x9e, 0x8b, 0xa9, 0x8b, 0xa1, 0x7a, 0x9d, 0x76, 0x8b, 0x81, 0x8b, 0x88, + 0x8a, 0x75, 0x85, 0x08, 0x2f, 0x6f, 0x9e, 0xe4, 0x05, 0x8e, 0x98, 0x8c, + 0x94, 0x8b, 0x91, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, 0x6a, 0x8b, 0x76, + 0x75, 0x81, 0x5f, 0x08, 0x78, 0x32, 0x3b, 0xa7, 0x05, 0x77, 0x91, 0x88, + 0x8c, 0x83, 0x8b, 0x6c, 0x8b, 0x6e, 0x6d, 0x8b, 0x6c, 0x8b, 0x76, 0x95, + 0x81, 0xa9, 0x81, 0x08, 0xdb, 0x6f, 0x05, 0x0e, 0xf8, 0x23, 0xf7, 0x7a, + 0x15, 0xf7, 0x22, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x99, 0x7e, 0x90, 0x82, 0x8f, + 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfb, 0x21, 0x8b, 0xad, 0xf7, 0x38, 0x05, + 0x90, 0x9e, 0x8b, 0x8d, 0x8b, 0x92, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, + 0x69, 0x8b, 0x76, 0x75, 0x81, 0x5f, 0x08, 0x69, 0xfb, 0x38, 0xfb, 0x22, + 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x21, 0x8b, 0x69, + 0xfb, 0x38, 0x05, 0x89, 0x82, 0x89, 0x7e, 0x8b, 0x84, 0x8b, 0x76, 0x9c, + 0x7b, 0xa2, 0x8b, 0x9a, 0x8b, 0x9d, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, + 0x93, 0x91, 0xa6, 0x08, 0xad, 0xf7, 0x38, 0x05, 0x0e, 0xf7, 0x8a, 0xf7, + 0x1a, 0x15, 0xfb, 0x0c, 0xfb, 0x89, 0x05, 0x84, 0x7d, 0x8a, 0x87, 0x8b, + 0x84, 0x8b, 0x7f, 0x97, 0x81, 0x99, 0x8b, 0x97, 0x8b, 0x98, 0x93, 0x97, + 0x9b, 0x08, 0xf7, 0x5a, 0xf7, 0xa0, 0xfb, 0x19, 0x8b, 0x05, 0x0e, 0xf8, + 0xb1, 0xf7, 0x79, 0x15, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, + 0x83, 0x8c, 0x78, 0x8b, 0x08, 0xfc, 0x13, 0x06, 0x6c, 0x8b, 0x82, 0x89, + 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, + 0xb4, 0x1e, 0xf8, 0x13, 0x06, 0x0e, 0xf7, 0xc5, 0x7c, 0x15, 0xb5, 0xb3, + 0xb2, 0xb4, 0xa9, 0x75, 0xa1, 0x6b, 0x1f, 0x7a, 0x06, 0x61, 0x63, 0x64, + 0x63, 0x6c, 0xa1, 0x75, 0xab, 0x1f, 0x9c, 0x06, 0x0e, 0xf9, 0x10, 0xf8, + 0xf6, 0x15, 0x9b, 0xa3, 0x8f, 0x94, 0x8b, 0x98, 0x8b, 0xa1, 0x7a, 0x9c, + 0x74, 0x8b, 0x73, 0x8b, 0x7d, 0x81, 0x74, 0x69, 0x08, 0xfc, 0x65, 0xfd, + 0x3a, 0x05, 0x7b, 0x75, 0x86, 0x7f, 0x8b, 0x7e, 0x8b, 0x75, 0x9d, 0x7a, + 0xa2, 0x8b, 0xa3, 0x8b, 0x99, 0x95, 0xa2, 0xad, 0x08, 0xf8, 0x65, 0xf9, + 0x3b, 0x05, 0x0e, 0xf8, 0xe5, 0xf7, 0xfb, 0x15, 0x91, 0xa7, 0x8e, 0xa8, + 0x8b, 0xa7, 0x8b, 0xf7, 0x10, 0x4f, 0xd1, 0x21, 0x8b, 0x51, 0x8b, 0x57, + 0x78, 0x62, 0x67, 0x4e, 0x56, 0x5d, 0x3a, 0x78, 0x31, 0x08, 0x77, 0x2c, + 0x05, 0x85, 0x6f, 0x88, 0x6e, 0x8b, 0x6f, 0x8b, 0xfb, 0x10, 0xc7, 0x45, + 0xf5, 0x8b, 0xc5, 0x8b, 0xbe, 0x9e, 0xb5, 0xaf, 0xc8, 0xc0, 0xb9, 0xdc, + 0x9e, 0xe5, 0x08, 0x9f, 0xea, 0x05, 0xfb, 0xe1, 0x92, 0x15, 0xa2, 0xf3, + 0xc7, 0xcf, 0xd2, 0x8b, 0xc2, 0x8b, 0xab, 0x63, 0x8b, 0x45, 0x8b, 0x76, + 0x89, 0x76, 0x86, 0x77, 0x08, 0x74, 0xfb, 0x01, 0x05, 0x75, 0x23, 0x4e, + 0x47, 0x45, 0x8b, 0x54, 0x8b, 0x6b, 0xb4, 0x8b, 0xd0, 0x8b, 0xa0, 0x8d, + 0xa0, 0x90, 0x9f, 0x08, 0xa1, 0xf7, 0x01, 0x05, 0x0e, 0xf8, 0x7a, 0xf9, + 0x12, 0x15, 0xfb, 0x74, 0x54, 0x05, 0x5c, 0x80, 0x79, 0x79, 0x8b, 0x69, + 0x8b, 0x73, 0x9a, 0x7b, 0xa0, 0x8b, 0x95, 0x8b, 0x8e, 0x8c, 0xa0, 0x90, + 0x08, 0xe6, 0xa2, 0x35, 0xfc, 0x2d, 0x26, 0x8b, 0x05, 0x6b, 0x8b, 0x83, + 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, + 0x7f, 0xb4, 0x1e, 0xf7, 0xc1, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, + 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x26, 0x8b, 0xf7, 0x07, 0xf8, + 0xae, 0x05, 0x0e, 0xf7, 0x78, 0xef, 0x15, 0xbb, 0xae, 0xd7, 0xc1, 0x05, + 0xf6, 0xda, 0xcb, 0xbf, 0xa7, 0xab, 0xac, 0xb2, 0x9d, 0xb9, 0x8b, 0xba, + 0x8b, 0xe6, 0x43, 0xca, 0x23, 0x8b, 0x4f, 0x8b, 0x4e, 0x77, 0x5c, 0x67, + 0x5d, 0x67, 0x64, 0x54, 0x8b, 0x6c, 0x8b, 0x76, 0x9e, 0x7a, 0xa1, 0x8b, + 0x08, 0xa0, 0x8b, 0xa0, 0x97, 0x94, 0x9c, 0x9d, 0xab, 0x8c, 0x8d, 0x98, + 0x97, 0xa6, 0xa5, 0xb2, 0x9a, 0xb3, 0x8b, 0xc3, 0x8b, 0xb4, 0x6c, 0x8b, + 0x61, 0x8b, 0x60, 0x7a, 0x78, 0xfb, 0x19, 0x25, 0x59, 0x65, 0x61, 0x6d, + 0xfb, 0x4a, 0xfb, 0x14, 0x08, 0x75, 0x22, 0xf8, 0x5a, 0x8b, 0x9e, 0xe3, + 0x05, 0x8e, 0x9c, 0x8c, 0x8f, 0x8b, 0x92, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, + 0x8b, 0x6c, 0x8b, 0x77, 0x79, 0x81, 0x67, 0x08, 0xfb, 0x5e, 0x06, 0x0e, + 0xf7, 0xf9, 0xf8, 0x13, 0x15, 0x6a, 0x6d, 0x6f, 0x6c, 0x1f, 0x8b, 0x74, + 0x99, 0x7f, 0xa8, 0x89, 0xb4, 0x89, 0x99, 0x89, 0x9e, 0x83, 0xad, 0x7b, + 0xa3, 0x6d, 0x8b, 0x6f, 0x8b, 0x6d, 0x7a, 0x6b, 0x71, 0x77, 0x6b, 0x72, + 0x64, 0x82, 0x46, 0x8b, 0x4b, 0x8b, 0x6e, 0x91, 0x75, 0x9c, 0x08, 0x7e, + 0x95, 0x86, 0x8d, 0x80, 0x8b, 0x08, 0x6a, 0x6e, 0x6e, 0x6a, 0x60, 0xd7, + 0x6d, 0xf7, 0x04, 0x1f, 0xf3, 0x8b, 0xcd, 0xa0, 0xc3, 0xbf, 0xb8, 0xb4, + 0xab, 0xcb, 0x8b, 0xbb, 0x8b, 0xbe, 0x70, 0xb3, 0x52, 0xaa, 0x8e, 0x8d, + 0x8e, 0x8c, 0x8c, 0x8b, 0x08, 0xd6, 0xb3, 0xb3, 0xc1, 0x8b, 0xcc, 0x08, + 0xe2, 0x49, 0xc3, 0x22, 0xfb, 0x0a, 0xfb, 0x06, 0x4f, 0x4d, 0x75, 0x9d, + 0x7a, 0xa1, 0x1e, 0x98, 0x8b, 0x9a, 0x91, 0x95, 0x94, 0xb3, 0xae, 0xa9, + 0x96, 0xc3, 0x8b, 0x08, 0xc7, 0xb0, 0x74, 0x65, 0x5b, 0x56, 0x5d, 0x53, + 0x1f, 0x62, 0x06, 0x0e, 0xf8, 0xd7, 0xf9, 0x02, 0x15, 0xfb, 0x17, 0x8b, + 0xfb, 0xda, 0xfc, 0x25, 0x79, 0x38, 0xf7, 0xa4, 0x8b, 0x83, 0x65, 0x65, + 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x18, 0x06, 0xa7, + 0x8b, 0x99, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x08, + 0xa6, 0x7a, 0x98, 0x68, 0x1e, 0x93, 0xb1, 0x05, 0xa5, 0x8b, 0x95, 0x8e, + 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x08, 0xa7, 0x7b, 0x97, + 0x67, 0x1e, 0xdd, 0xf8, 0x14, 0x05, 0xfb, 0x4a, 0xfc, 0x14, 0x15, 0xfb, + 0x29, 0x8b, 0xf7, 0x5d, 0xf7, 0x86, 0x57, 0xfb, 0x86, 0x05, 0x0e, 0xf7, + 0xde, 0xf8, 0x9e, 0x15, 0xf7, 0x5e, 0x06, 0xa8, 0x8b, 0x98, 0x8e, 0x98, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x99, 0x7e, + 0x90, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0xc1, 0x8b, 0x4e, + 0xfb, 0xb0, 0x05, 0x8a, 0x85, 0x8a, 0x86, 0x8b, 0x86, 0x8a, 0x75, 0x9d, + 0x79, 0xa2, 0x8b, 0x94, 0x8b, 0x91, 0x8d, 0x99, 0x91, 0xba, 0xa0, 0xbb, + 0x98, 0xad, 0x8b, 0xc1, 0x8b, 0xae, 0x69, 0x8b, 0x55, 0x8b, 0x69, 0x80, + 0x68, 0x78, 0x72, 0x08, 0x6d, 0x63, 0x5e, 0x7a, 0x3f, 0x8b, 0x4a, 0x8b, + 0x6f, 0x93, 0x72, 0xa4, 0x7f, 0x97, 0x85, 0x8e, 0x7d, 0x8b, 0x08, 0x6b, + 0x6d, 0x6e, 0x6b, 0x59, 0xdd, 0x66, 0xf7, 0x01, 0x1f, 0xf7, 0x02, 0x8b, + 0xd2, 0xa7, 0xc4, 0xcd, 0xb5, 0xbc, 0xa3, 0xcc, 0x8b, 0xc9, 0x8b, 0xf1, + 0x48, 0xce, 0x26, 0x8b, 0x6c, 0x8b, 0x69, 0x85, 0x64, 0x80, 0x08, 0xa3, + 0xf7, 0x07, 0x05, 0x0e, 0xf7, 0xa8, 0xf7, 0xd8, 0x15, 0x95, 0xa3, 0x8e, + 0x92, 0x91, 0x96, 0xbf, 0xed, 0xf5, 0xd2, 0xe5, 0x8b, 0x94, 0x8b, 0x8f, + 0x8a, 0x95, 0x87, 0x9a, 0x85, 0x96, 0x89, 0x93, 0x8b, 0x08, 0xab, 0xaa, + 0xa9, 0xaa, 0xac, 0x62, 0xa1, 0x4c, 0x1f, 0x52, 0x8b, 0x59, 0x7d, 0x55, + 0x6d, 0x4a, 0x67, 0x4e, 0x53, 0x62, 0x50, 0x59, 0x40, 0x70, 0x2f, 0x8b, + 0x2b, 0x8b, 0xfb, 0x16, 0xc5, 0x4a, 0xf7, 0x08, 0x8b, 0xda, 0x8b, 0xca, + 0xa7, 0xbb, 0xc4, 0xb2, 0xb9, 0xa3, 0xcb, 0x8b, 0xc5, 0x08, 0xe4, 0x49, + 0xce, 0x34, 0x1e, 0x58, 0x8b, 0x61, 0x77, 0x50, 0x59, 0x08, 0x7d, 0xfb, + 0x07, 0x15, 0xb1, 0xbd, 0xc4, 0xae, 0xb7, 0x8b, 0xb7, 0x8b, 0xac, 0x69, + 0x8b, 0x5d, 0x8b, 0x72, 0x81, 0x6c, 0x79, 0x73, 0x74, 0x6a, 0x6b, 0x7b, + 0x60, 0x8b, 0x6d, 0x8b, 0x71, 0x95, 0x7e, 0x9a, 0x7f, 0x9c, 0x81, 0xaf, + 0x8b, 0xaa, 0x08, 0x8b, 0x8e, 0x8b, 0x90, 0x8c, 0x92, 0x08, 0x0e, 0xf8, + 0x95, 0xf8, 0x9e, 0x15, 0xfb, 0x87, 0xfc, 0x4d, 0x05, 0x7e, 0x73, 0x88, + 0x82, 0x8b, 0x80, 0x8b, 0x77, 0x9e, 0x79, 0xa1, 0x8b, 0xa6, 0x8b, 0x9c, + 0x98, 0x9f, 0xaf, 0x08, 0xf7, 0x98, 0xf8, 0x6f, 0xa0, 0xee, 0xfc, 0x45, + 0x8b, 0x78, 0x33, 0x05, 0x88, 0x7e, 0x8a, 0x82, 0x8b, 0x85, 0x8b, 0x75, + 0x9c, 0x7b, 0xa2, 0x8b, 0xaa, 0x8b, 0x9f, 0x9d, 0x95, 0xaf, 0x08, 0xf7, + 0x78, 0x06, 0x0e, 0xf8, 0x7b, 0xf7, 0xd3, 0x15, 0xdd, 0xbb, 0xb2, 0xc1, + 0x8b, 0xcf, 0x8b, 0xe2, 0x44, 0xc9, 0x25, 0x8b, 0x4b, 0x8b, 0x49, 0x72, + 0x5c, 0x60, 0x5f, 0x64, 0x6e, 0x52, 0x8b, 0x5e, 0x8b, 0x60, 0x9e, 0x6a, + 0xb7, 0x69, 0x08, 0x34, 0x5b, 0x5c, 0x49, 0x8b, 0x3f, 0x8b, 0x32, 0xd0, + 0x54, 0xf7, 0x04, 0x8b, 0xdb, 0x8b, 0xda, 0xaa, 0xb8, 0xbb, 0xad, 0xb0, + 0xa2, 0xc0, 0x8b, 0xb7, 0x08, 0x8b, 0xbb, 0x75, 0xb3, 0x5c, 0xac, 0x08, + 0x41, 0xf7, 0x6f, 0x15, 0xc4, 0xae, 0x70, 0x5e, 0x53, 0x51, 0x5d, 0x44, + 0x54, 0x67, 0xa7, 0xb4, 0x1f, 0xc6, 0xc3, 0xb9, 0xd3, 0x1e, 0x53, 0xfb, + 0xa7, 0x15, 0xc4, 0xb5, 0x6b, 0x5f, 0x53, 0x4d, 0x5d, 0x3f, 0x4e, 0x64, + 0xa7, 0xb8, 0x1f, 0xc3, 0xcc, 0xbc, 0xd5, 0x1e, 0x0e, 0xf8, 0x8a, 0xf7, + 0xbf, 0x15, 0x81, 0x73, 0x88, 0x84, 0x85, 0x80, 0x57, 0x2a, 0x21, 0x43, + 0x31, 0x8b, 0x82, 0x8b, 0x87, 0x8c, 0x81, 0x8f, 0x7c, 0x91, 0x81, 0x8d, + 0x82, 0x8b, 0x08, 0x6b, 0x6c, 0x6d, 0x6c, 0x6a, 0xb5, 0x75, 0xc9, 0x1f, + 0xc4, 0x8b, 0xbd, 0x99, 0xc1, 0xa9, 0xcc, 0xaf, 0xc8, 0xc3, 0xb4, 0xc6, + 0xbd, 0xd6, 0xa6, 0xe7, 0x8b, 0xeb, 0x8b, 0xf7, 0x16, 0x51, 0xcc, 0xfb, + 0x08, 0x8b, 0x3c, 0x8b, 0x4d, 0x6f, 0x5a, 0x52, 0x64, 0x5d, 0x73, 0x4b, + 0x8b, 0x51, 0x08, 0x32, 0xcd, 0x48, 0xe2, 0x1e, 0xbe, 0x8b, 0xb4, 0x9e, + 0xc7, 0xbe, 0x08, 0x99, 0xf7, 0x07, 0x15, 0x65, 0x59, 0x52, 0x68, 0x5f, + 0x8b, 0x5f, 0x8b, 0x6a, 0xad, 0x8b, 0xb8, 0x8b, 0xa5, 0x96, 0xaa, 0x9c, + 0xa3, 0xa2, 0xac, 0xab, 0x9b, 0xb6, 0x8b, 0xaa, 0x8b, 0xa4, 0x81, 0x98, + 0x7c, 0x98, 0x7a, 0x94, 0x68, 0x8b, 0x6a, 0x08, 0x8b, 0x89, 0x8b, 0x85, + 0x8a, 0x85, 0x08, 0x0e, 0xf7, 0xc5, 0x7c, 0x15, 0xb6, 0xb2, 0xb2, 0xb4, + 0xa9, 0x75, 0xa1, 0x6b, 0x1f, 0x7a, 0x06, 0x61, 0x63, 0x64, 0x63, 0x6c, + 0xa1, 0x75, 0xab, 0x1f, 0x9c, 0x06, 0xcf, 0xf7, 0xd3, 0x15, 0xb5, 0xb3, + 0xb2, 0xb4, 0xaa, 0x75, 0xa1, 0x6b, 0x1f, 0x7a, 0x06, 0x61, 0x63, 0x64, + 0x62, 0x6c, 0xa1, 0x75, 0xab, 0x1f, 0x9c, 0x06, 0x0e, 0xf7, 0x8b, 0xf7, + 0x1a, 0x15, 0xfb, 0x0d, 0xfb, 0x89, 0x05, 0x84, 0x7d, 0x8a, 0x87, 0x8b, + 0x84, 0x8b, 0x7f, 0x97, 0x81, 0x99, 0x8b, 0x97, 0x8b, 0x98, 0x93, 0x97, + 0x9b, 0x08, 0xf7, 0x5a, 0xf7, 0xa0, 0xfb, 0x18, 0x8b, 0x05, 0xf7, 0x0d, + 0xf7, 0xc3, 0x15, 0x59, 0x63, 0x67, 0x5f, 0x69, 0xa2, 0x78, 0xb2, 0xbe, + 0xb3, 0xae, 0xb8, 0xad, 0x75, 0x9e, 0x62, 0x1f, 0x0e, 0xf7, 0xcb, 0xf7, + 0xab, 0x15, 0xf7, 0xb5, 0xf7, 0x19, 0x05, 0xa8, 0x98, 0x98, 0x9c, 0x8b, + 0xa0, 0x8b, 0x8f, 0x8b, 0x8e, 0x8a, 0x8f, 0x08, 0x8a, 0x8d, 0x05, 0x87, + 0x99, 0x7e, 0x96, 0x7d, 0x8b, 0x83, 0x8b, 0x80, 0x88, 0x7e, 0x85, 0x08, + 0xfc, 0x6f, 0xfb, 0x68, 0xf8, 0x14, 0xfb, 0x6d, 0x05, 0x95, 0x85, 0x95, + 0x88, 0x93, 0x8b, 0x99, 0x8b, 0x9d, 0x96, 0x95, 0x99, 0x08, 0x8c, 0x8d, + 0x05, 0x91, 0x94, 0x8f, 0x95, 0x8b, 0x94, 0x8b, 0x9a, 0x85, 0x93, 0x79, + 0x96, 0x08, 0xfb, 0x7c, 0xf7, 0x1c, 0x05, 0x0e, 0xf7, 0x5a, 0xf8, 0x3a, + 0x15, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf8, 0x13, 0x06, 0xa8, 0x8b, + 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, + 0x82, 0x99, 0x7e, 0x90, 0x82, 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfc, + 0x13, 0x06, 0x64, 0xfb, 0x4c, 0x15, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xf8, 0x13, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, + 0x9d, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x99, 0x7e, 0x90, 0x82, 0x8f, 0x87, + 0x8b, 0x75, 0x8b, 0x08, 0xfc, 0x13, 0x06, 0x0e, 0xf8, 0x2b, 0xf7, 0xa7, + 0x15, 0xfb, 0xb5, 0xfb, 0x19, 0x05, 0x6e, 0x7e, 0x7e, 0x7b, 0x8b, 0x75, + 0x8b, 0x87, 0x8b, 0x88, 0x8c, 0x87, 0x08, 0x8c, 0x89, 0x05, 0x8f, 0x7d, + 0x98, 0x80, 0x99, 0x8b, 0x92, 0x8b, 0x97, 0x8e, 0x98, 0x91, 0x08, 0xf8, + 0x6f, 0xf7, 0x68, 0xfc, 0x14, 0xf7, 0x6d, 0x05, 0x81, 0x91, 0x81, 0x8e, + 0x83, 0x8b, 0x7d, 0x8b, 0x78, 0x7f, 0x82, 0x7e, 0x08, 0x8a, 0x89, 0x05, + 0x84, 0x81, 0x88, 0x81, 0x8b, 0x83, 0x8b, 0x7c, 0x91, 0x83, 0x9d, 0x81, + 0x08, 0xf7, 0x7c, 0xfb, 0x1d, 0x05, 0x0e, 0xf7, 0x5d, 0xf8, 0x60, 0x15, + 0x88, 0x7e, 0x8a, 0x81, 0x8b, 0x85, 0x8b, 0x76, 0x9d, 0x7b, 0xa1, 0x8b, + 0x9a, 0x8b, 0x9d, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, 0x92, 0x91, 0xa7, + 0x08, 0x8e, 0x99, 0x05, 0xaf, 0x9b, 0xb0, 0x93, 0xb1, 0x8b, 0xc5, 0x8b, + 0xac, 0x71, 0x8b, 0x5f, 0x8b, 0x58, 0x63, 0x6f, 0xfb, 0x2b, 0x56, 0x08, + 0x80, 0x53, 0x05, 0x86, 0x78, 0x8b, 0x89, 0x8b, 0x83, 0x8b, 0x77, 0x9d, + 0x7a, 0xa1, 0x8b, 0xa8, 0x8b, 0xa0, 0x9d, 0x97, 0xaf, 0xd1, 0xa7, 0xb4, + 0xa2, 0xae, 0xa9, 0xb1, 0xad, 0xa2, 0xbf, 0x8b, 0xc2, 0x8b, 0xe7, 0x4a, + 0xc3, 0x20, 0x8b, 0x08, 0x49, 0x8b, 0x60, 0x7f, 0xfb, 0x01, 0x5c, 0x08, + 0x7a, 0x3c, 0x05, 0xf6, 0xfc, 0x6f, 0x15, 0xb5, 0xb2, 0xb2, 0xb4, 0xa9, + 0x75, 0xa1, 0x6c, 0x1f, 0x79, 0x06, 0x61, 0x63, 0x64, 0x63, 0x6c, 0xa1, + 0x75, 0xab, 0x1f, 0x9d, 0x06, 0x0e, 0xf8, 0x80, 0xf8, 0x22, 0x15, 0xfb, + 0x14, 0x82, 0x25, 0x31, 0x8b, 0x24, 0x08, 0x41, 0xc1, 0x59, 0xdb, 0x1e, + 0xd4, 0x06, 0xa4, 0x8b, 0x94, 0x8d, 0x97, 0x95, 0x97, 0x95, 0x92, 0x99, + 0x8b, 0x99, 0x8b, 0x98, 0x87, 0x92, 0x7e, 0x91, 0x08, 0xc7, 0xf7, 0xad, + 0x05, 0x8e, 0x9a, 0x8d, 0x9a, 0x8b, 0x99, 0x8b, 0xe5, 0x51, 0xc4, 0x30, + 0x8b, 0xfb, 0x17, 0x8b, 0xfb, 0x0d, 0xfb, 0x11, 0x66, 0xfb, 0x40, 0x08, + 0x67, 0xfb, 0x3d, 0x05, 0x84, 0x6b, 0x88, 0x6b, 0x8b, 0x6c, 0x8b, 0x51, + 0x97, 0x5b, 0xa2, 0x65, 0xa7, 0x5d, 0xb6, 0x76, 0xcc, 0x8b, 0x08, 0xf3, + 0xe8, 0xb8, 0xbd, 0x9e, 0x7e, 0x98, 0x78, 0x1f, 0x7f, 0x8b, 0x85, 0x88, + 0x7a, 0x7d, 0x74, 0x77, 0x61, 0x7f, 0x5e, 0x8b, 0x6c, 0x8b, 0x76, 0x92, + 0x7a, 0x9b, 0x71, 0xa3, 0x7c, 0xbc, 0x8b, 0xc3, 0x8b, 0xa4, 0x8e, 0xa6, + 0x92, 0xaa, 0x08, 0xac, 0xf7, 0x30, 0x05, 0xa6, 0xf7, 0x14, 0xdf, 0xeb, + 0xdf, 0x8b, 0xbf, 0x8b, 0xab, 0x6b, 0x8b, 0x58, 0x8b, 0x80, 0x8a, 0x83, + 0x89, 0x81, 0x08, 0x85, 0x6c, 0x05, 0x57, 0xfb, 0x87, 0x15, 0x7d, 0x89, + 0x84, 0x8b, 0x85, 0x8b, 0x62, 0x8b, 0x6e, 0xa3, 0x8b, 0xad, 0x8b, 0xc0, + 0xc4, 0xb8, 0xd5, 0x92, 0x08, 0x69, 0xfb, 0x35, 0x05, 0x0e, 0xf8, 0x56, + 0xf7, 0x32, 0x15, 0x96, 0x51, 0x74, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, + 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, + 0xb3, 0x1e, 0xf7, 0x1f, 0x06, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, + 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x90, 0x82, + 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2a, 0xf8, 0x77, 0xfb, 0x6c, 0x8b, + 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xca, 0x8b, 0xfb, 0x80, 0xfc, + 0x13, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, 0x7f, 0x7d, 0x80, 0x82, 0x79, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x18, 0x06, 0xa8, + 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, + 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x76, 0x8b, 0x08, + 0x74, 0x8b, 0xaf, 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x77, 0xef, 0x15, 0xfb, + 0x31, 0x8b, 0xf7, 0x0b, 0xf7, 0x54, 0xb1, 0xfb, 0x54, 0x05, 0x0e, 0xf7, + 0x07, 0xef, 0x15, 0x7c, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, + 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, + 0xbb, 0x06, 0xd3, 0x8b, 0xc6, 0xa0, 0xb7, 0xb5, 0xaf, 0xad, 0xa2, 0xbd, + 0x8b, 0xb5, 0x8b, 0xbd, 0x73, 0xaf, 0x54, 0xa9, 0x08, 0xc8, 0xb3, 0xa9, + 0xb9, 0x8b, 0xc4, 0x8b, 0xad, 0x7d, 0xac, 0x73, 0xa3, 0x6d, 0xa9, 0x63, + 0x99, 0x52, 0x8b, 0x08, 0xfb, 0x90, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, + 0x80, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, + 0x1e, 0x9a, 0x8b, 0x05, 0x3a, 0xfc, 0x13, 0x05, 0xf7, 0x2b, 0xf7, 0x86, + 0x15, 0xa9, 0xf7, 0x21, 0xf7, 0x19, 0x8b, 0x05, 0xc3, 0xac, 0x78, 0x6a, + 0x58, 0x4f, 0x65, 0x3c, 0x1f, 0xfb, 0x05, 0x06, 0x58, 0xfb, 0x86, 0x15, + 0xa9, 0xf7, 0x22, 0xf7, 0x1b, 0x8b, 0x05, 0xd7, 0xbb, 0x6e, 0x5c, 0x60, + 0x63, 0x74, 0x41, 0x1f, 0xfb, 0x43, 0x06, 0x0e, 0xf8, 0xcb, 0xf8, 0xc7, + 0x15, 0x59, 0xa5, 0x6a, 0x93, 0x57, 0x8b, 0xfb, 0x2f, 0x8b, 0xfb, 0x23, + 0xfb, 0x0e, 0x69, 0xfb, 0x34, 0x08, 0x7d, 0x49, 0x05, 0x87, 0x79, 0x89, + 0x79, 0x8b, 0x79, 0x8b, 0xfb, 0x12, 0xeb, 0x38, 0xf7, 0x28, 0x8b, 0xe5, + 0x8b, 0xda, 0xa4, 0xc4, 0xbb, 0xa5, 0xa0, 0x97, 0x9e, 0x8b, 0x9e, 0x8b, + 0xa2, 0x79, 0x9d, 0x74, 0x8b, 0x7e, 0x8b, 0x7f, 0x86, 0x7d, 0x80, 0x08, + 0x6b, 0x70, 0x8a, 0x8b, 0x7f, 0x84, 0x70, 0x7d, 0x60, 0x82, 0x5d, 0x8b, + 0x25, 0x8b, 0x4c, 0xbc, 0x8b, 0xda, 0x8b, 0x96, 0x8c, 0x98, 0x8e, 0x98, + 0x08, 0x99, 0xcb, 0x05, 0xa1, 0xf4, 0xe6, 0xd8, 0xf1, 0x8b, 0xce, 0x8b, + 0xc6, 0x69, 0x89, 0x65, 0x08, 0x8a, 0x78, 0x05, 0x8a, 0x74, 0x9b, 0x7b, + 0xa3, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, 0x94, + 0x91, 0xa5, 0x08, 0x9d, 0xdf, 0x05, 0x8f, 0x9c, 0x8b, 0x8f, 0x8b, 0x92, + 0x08, 0xa1, 0x7a, 0x9b, 0x74, 0x1e, 0x7a, 0x8b, 0x7e, 0x84, 0x7a, 0x7a, + 0x08, 0x82, 0x8f, 0x05, 0x0e, 0xeb, 0xef, 0x15, 0x72, 0x8b, 0x80, 0x88, + 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, + 0xb4, 0x1e, 0xf7, 0x61, 0x06, 0xe1, 0x8b, 0xcd, 0xa2, 0xc7, 0xbf, 0xc3, + 0xbb, 0xb0, 0xc9, 0x9a, 0xd4, 0x08, 0x95, 0xba, 0x05, 0x90, 0xa0, 0x8d, + 0xa1, 0x8b, 0xa0, 0x08, 0xf7, 0x14, 0x38, 0xe1, 0xfb, 0x0e, 0x1e, 0xfb, + 0x69, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x70, 0x9b, 0x7e, 0xae, 0x1e, 0x3a, 0xfc, 0x13, 0x05, + 0xef, 0x16, 0xdc, 0xf8, 0x13, 0xf7, 0x02, 0x8b, 0x05, 0xb0, 0x8b, 0xab, + 0x82, 0x9e, 0x7a, 0xa7, 0x74, 0x9c, 0x61, 0x8b, 0x61, 0x8b, 0x7c, 0x8a, + 0x7d, 0x88, 0x7d, 0x08, 0x81, 0x5d, 0x05, 0x80, 0x58, 0x77, 0x67, 0x68, + 0x6d, 0x64, 0x6b, 0x68, 0x7f, 0x4f, 0x8b, 0x08, 0xfb, 0x02, 0x06, 0x0e, + 0xf7, 0x8a, 0xf7, 0x87, 0x15, 0xe0, 0x8b, 0x89, 0x84, 0x05, 0x88, 0x7d, + 0x8a, 0x83, 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9a, 0x8b, + 0x9c, 0x93, 0x97, 0x97, 0x95, 0x96, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0xa4, + 0xf7, 0x05, 0x05, 0x8f, 0x9f, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0xa1, 0x7a, + 0x9b, 0x74, 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7e, 0x7e, 0x81, 0x81, 0x88, + 0x84, 0x85, 0x6e, 0x08, 0x8a, 0x84, 0x36, 0x8b, 0xa9, 0xf7, 0x21, 0xf7, + 0x7e, 0x8b, 0x80, 0x59, 0x05, 0x88, 0x7e, 0x8a, 0x81, 0x8b, 0x85, 0x8b, + 0x75, 0x9d, 0x7b, 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, + 0x95, 0x8e, 0x93, 0x91, 0xa7, 0x08, 0xab, 0xf7, 0x2a, 0xfc, 0x54, 0x8b, + 0x05, 0x6b, 0x8b, 0x82, 0x89, 0x7d, 0x7f, 0x7c, 0x7f, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, + 0x7c, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, + 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9c, 0x7f, 0xb3, 0x1e, 0xf8, 0x6a, 0x8b, + 0xac, 0xf7, 0x2c, 0x05, 0x8e, 0x9d, 0x8c, 0x8f, 0x8b, 0x93, 0x8b, 0xa0, + 0x79, 0x9b, 0x74, 0x8b, 0x7c, 0x8b, 0x7a, 0x84, 0x7f, 0x7d, 0x81, 0x81, + 0x87, 0x83, 0x86, 0x6f, 0x08, 0x7f, 0x57, 0xfb, 0x93, 0x8b, 0xa9, 0xf7, + 0x23, 0x05, 0x0e, 0xf7, 0x8a, 0xf7, 0x87, 0x15, 0xe0, 0x8b, 0x89, 0x84, + 0x05, 0x89, 0x80, 0x89, 0x7f, 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa1, + 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8f, 0x94, 0x90, + 0xa6, 0x08, 0xa3, 0xf7, 0x05, 0x05, 0x90, 0x9e, 0x8b, 0x8c, 0x8b, 0x93, + 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7e, + 0x82, 0x81, 0x86, 0x82, 0x86, 0x71, 0x08, 0x89, 0x84, 0x37, 0x8b, 0xa9, + 0xf7, 0x21, 0xf7, 0x94, 0x8b, 0x80, 0x58, 0x05, 0x89, 0x80, 0x89, 0x7f, + 0x8b, 0x85, 0x8b, 0x76, 0x9d, 0x7b, 0xa1, 0x8b, 0x9b, 0x8b, 0x9b, 0x93, + 0x98, 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, 0xa6, 0x08, 0xab, 0xf7, 0x2b, + 0xfc, 0x6a, 0x8b, 0x05, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, + 0x3a, 0xfc, 0x13, 0x7c, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, + 0xf7, 0x6a, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, + 0x8c, 0x77, 0x8b, 0x08, 0x28, 0x8b, 0xa9, 0xf7, 0x23, 0x05, 0x0e, 0xf8, + 0xe0, 0xf7, 0x48, 0x15, 0xac, 0x94, 0xa0, 0xa2, 0x8b, 0xa8, 0x8b, 0x9b, + 0x82, 0x9a, 0x7e, 0x8f, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0xfb, + 0x43, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xee, 0x8b, 0x7d, 0x46, + 0x05, 0x60, 0x7a, 0x63, 0x83, 0x5a, 0x8b, 0x24, 0x8b, 0x51, 0xb4, 0x8b, + 0xd3, 0x8b, 0x9d, 0x8d, 0x9c, 0x8f, 0x9e, 0x08, 0x99, 0xcb, 0x05, 0xa1, + 0xf7, 0x00, 0xe5, 0xd3, 0xf7, 0x02, 0x8b, 0xd4, 0x8b, 0xb9, 0x75, 0x8d, + 0x68, 0x8d, 0x6c, 0x8b, 0x8b, 0x90, 0x84, 0x90, 0x82, 0x98, 0x85, 0x98, + 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, + 0xa6, 0x08, 0x9c, 0xd9, 0x05, 0x8f, 0x9e, 0x8b, 0x8d, 0x8b, 0x93, 0x8b, + 0xa1, 0x7c, 0x9a, 0x75, 0x8b, 0x78, 0x8b, 0x7f, 0x83, 0x7b, 0x73, 0x64, + 0xa1, 0x5d, 0x95, 0x55, 0x8b, 0x39, 0x8b, 0x45, 0x72, 0x4b, 0x57, 0x4a, + 0x56, 0x5d, 0x41, 0x7b, 0x3f, 0x08, 0x7c, 0x44, 0x05, 0x86, 0x76, 0x89, + 0x77, 0x8b, 0x76, 0x8b, 0x46, 0xa3, 0x57, 0xb9, 0x6c, 0xb7, 0x6d, 0xcb, + 0x7b, 0xd1, 0x8b, 0xdb, 0x8b, 0xc0, 0x99, 0xef, 0xbb, 0x08, 0xa7, 0xf7, + 0x18, 0x05, 0x0e, 0xf8, 0x60, 0xf7, 0x85, 0x15, 0x6d, 0xfb, 0x21, 0x7c, + 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x0d, 0x06, 0xa7, + 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, + 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, + 0x85, 0x8b, 0xdc, 0xf8, 0x13, 0x05, 0xb1, 0x8e, 0xa5, 0xa4, 0x8b, 0xac, + 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, + 0x08, 0x27, 0x06, 0x6c, 0x8b, 0x81, 0x89, 0x7d, 0x7f, 0x7d, 0x7e, 0x82, + 0x7a, 0x8b, 0x7b, 0x8b, 0x7a, 0x94, 0x7d, 0x98, 0x86, 0x94, 0x88, 0x91, + 0x8a, 0x9e, 0x8b, 0x08, 0x9a, 0x8b, 0x6d, 0xfb, 0x22, 0xfb, 0x6a, 0x8b, + 0xa9, 0xf7, 0x22, 0x9a, 0x8b, 0x05, 0xaa, 0x8b, 0x94, 0x8e, 0x9a, 0x97, + 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, + 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x27, 0x06, 0x6c, 0x8b, 0x82, + 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x72, 0x99, + 0x7e, 0xa7, 0x89, 0x08, 0x3a, 0xfc, 0x13, 0x85, 0x8b, 0x05, 0x6c, 0x8b, + 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x0d, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, + 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x78, 0x8b, 0x08, 0x7d, 0x8b, 0xa9, 0xf7, + 0x21, 0xf7, 0x6a, 0x8b, 0x05, 0x0e, 0xf8, 0x59, 0xf8, 0x77, 0x15, 0xf0, + 0x06, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, + 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, + 0x8b, 0x08, 0xfb, 0xc1, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, + 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xf0, + 0x8b, 0x3a, 0xfc, 0x13, 0x26, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0xc1, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x27, 0x8b, 0xdc, 0xf8, 0x13, 0x05, 0x0e, + 0xf8, 0xe4, 0xf8, 0x77, 0x15, 0xc4, 0x06, 0xa9, 0x8b, 0x96, 0x8e, 0x99, + 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, + 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0xa8, 0x06, 0x6c, + 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x0b, 0x8b, 0x4e, 0xfb, 0xb1, 0x05, + 0x82, 0x5d, 0x86, 0x82, 0x71, 0x76, 0x6f, 0x75, 0x64, 0x7d, 0x67, 0x8b, + 0x6a, 0x8b, 0x6b, 0x94, 0x5e, 0xa1, 0x08, 0xa0, 0xeb, 0x05, 0x8e, 0x9e, + 0x8c, 0x8e, 0x8b, 0x93, 0x8b, 0xa0, 0x7a, 0x9b, 0x74, 0x8b, 0x7b, 0x8b, + 0x7a, 0x83, 0x7f, 0x7e, 0x81, 0x81, 0x87, 0x82, 0x85, 0x70, 0x08, 0x69, + 0xfb, 0x36, 0x05, 0xdd, 0x5e, 0xc9, 0x77, 0xc5, 0x8b, 0xc5, 0x8b, 0xc7, + 0x9f, 0xbd, 0xb0, 0xc3, 0xb3, 0xa4, 0xb1, 0x99, 0xcd, 0x08, 0xca, 0xf7, + 0xbc, 0x05, 0x0e, 0xf7, 0x82, 0xf7, 0x64, 0x15, 0xd1, 0xbe, 0x05, 0xc4, + 0x78, 0xb7, 0x2a, 0x9c, 0xfb, 0x23, 0x08, 0xf7, 0x01, 0x06, 0xa7, 0x8b, + 0x99, 0x8f, 0x99, 0x96, 0x99, 0x96, 0x94, 0x9e, 0x8b, 0x9b, 0x8b, 0x9a, + 0x81, 0x9b, 0x7f, 0x8f, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x6b, + 0x06, 0x75, 0xf7, 0x07, 0x5f, 0xde, 0x54, 0xab, 0x08, 0xf7, 0x65, 0xf7, + 0x2d, 0x05, 0xa6, 0x8b, 0x95, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, + 0x78, 0x8b, 0x08, 0x26, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7d, 0x7e, 0x7c, + 0x7f, 0x82, 0x79, 0x8b, 0x79, 0x8b, 0x7a, 0x92, 0x81, 0x9b, 0x85, 0x08, + 0xfb, 0x66, 0xfb, 0x2d, 0xaa, 0xf7, 0x29, 0xae, 0x8b, 0x05, 0xa9, 0x8b, + 0x96, 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9c, + 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, + 0x29, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, + 0x13, 0x7c, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x29, + 0x06, 0xa7, 0x8b, 0x99, 0x8f, 0x98, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, + 0x8b, 0x08, 0x68, 0x8b, 0xa2, 0xf7, 0x00, 0x05, 0x0e, 0xf7, 0xfa, 0xf8, + 0x77, 0x15, 0xc4, 0x06, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x69, 0x06, 0x6b, 0x8b, 0x83, 0x89, + 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, + 0xb4, 0x1e, 0xc3, 0x8b, 0x3a, 0xfc, 0x13, 0x52, 0x8b, 0x05, 0x6b, 0x8b, + 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, + 0x9b, 0x7f, 0xb4, 0x1e, 0xf8, 0x6c, 0x8b, 0xb4, 0xf7, 0x54, 0x05, 0x8e, + 0x9a, 0x8c, 0x93, 0x8b, 0x91, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, 0x7b, + 0x8b, 0x7b, 0x84, 0x7e, 0x7d, 0x81, 0x81, 0x87, 0x82, 0x86, 0x70, 0x08, + 0x77, 0x2f, 0xfb, 0x6b, 0x8b, 0xdc, 0xf8, 0x13, 0x05, 0x0e, 0xf7, 0x74, + 0xf8, 0x19, 0x15, 0xcc, 0xfb, 0x8f, 0xe6, 0x8b, 0xf7, 0x38, 0xf7, 0x8f, + 0x4e, 0xfb, 0xb5, 0x68, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, + 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xf7, 0x15, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x96, 0x94, + 0x9d, 0x8b, 0x9c, 0x08, 0xa6, 0x7b, 0x97, 0x68, 0x1e, 0xdc, 0xf8, 0x13, + 0x05, 0xa3, 0x8d, 0x95, 0x90, 0x98, 0x99, 0x96, 0x96, 0x91, 0x9a, 0x8b, + 0x99, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, + 0x8b, 0x08, 0xfb, 0x01, 0x8b, 0xfb, 0x5b, 0xfb, 0xbd, 0x40, 0xf7, 0xbd, + 0xfb, 0x00, 0x8b, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7f, + 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x72, 0x98, 0x7f, 0xa8, 0x88, 0x08, 0x3a, + 0xfc, 0x13, 0x05, 0x72, 0x8b, 0x80, 0x88, 0x7d, 0x7f, 0x7d, 0x80, 0x82, + 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x15, 0x06, + 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, + 0x08, 0x68, 0x8b, 0xc8, 0xf7, 0xb5, 0x05, 0x0e, 0xf7, 0x94, 0xf8, 0x1e, + 0x15, 0xf7, 0x44, 0xfc, 0x1e, 0xed, 0x8b, 0xf2, 0xf8, 0x77, 0x05, 0xa4, + 0x8b, 0x96, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, + 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, + 0xfb, 0x16, 0x06, 0x6c, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, + 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x4d, + 0xfb, 0xb8, 0xfb, 0x43, 0xf8, 0x1c, 0xfb, 0x06, 0x8b, 0x05, 0x6c, 0x8b, + 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9a, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, 0x05, 0x71, 0x8b, + 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x15, 0x06, 0xa7, 0x8b, 0x99, 0x8f, 0x98, + 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, + 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x68, 0x8b, 0xc9, 0xf7, + 0xba, 0x05, 0x0e, 0xf8, 0x3e, 0xf8, 0xe9, 0x15, 0x3a, 0x8b, 0x2c, 0x5e, + 0x47, 0x44, 0x49, 0x45, 0x62, 0x28, 0x8b, 0x2f, 0x8b, 0xfb, 0x1a, 0xea, + 0x27, 0xf7, 0x13, 0x8b, 0xde, 0x8b, 0xe7, 0xb7, 0xd0, 0xd3, 0xd0, 0xd3, + 0xb2, 0xeb, 0x8b, 0xeb, 0x8b, 0xf7, 0x18, 0x2c, 0xee, 0xfb, 0x14, 0x8b, + 0x08, 0x76, 0x27, 0x15, 0xdc, 0xc7, 0x49, 0x32, 0xfb, 0x17, 0xfb, 0x04, + 0xfb, 0x11, 0xfb, 0x09, 0x3b, 0x50, 0xce, 0xe5, 0xf7, 0x14, 0xf7, 0x04, + 0xf7, 0x12, 0xf7, 0x07, 0x1f, 0x0e, 0xf7, 0x81, 0xf7, 0x5c, 0x15, 0xed, + 0x06, 0xf4, 0x8b, 0xc9, 0xa4, 0xc3, 0xcb, 0xb1, 0xb5, 0xa0, 0xc0, 0x8b, + 0xba, 0x08, 0xe9, 0x46, 0xc5, 0xfb, 0x04, 0x1e, 0xfb, 0x7d, 0x06, 0x6c, + 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9a, 0x80, 0xb5, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, 0x7c, 0x8b, + 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, + 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x69, 0x06, 0xa7, 0x8b, + 0x99, 0x8f, 0x98, 0x96, 0x99, 0x96, 0x94, 0x9e, 0x8b, 0x9b, 0x8b, 0x9a, + 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x29, + 0x8b, 0xa0, 0xef, 0x05, 0xc7, 0xf7, 0xaf, 0x15, 0xf7, 0x0a, 0x06, 0xc5, + 0xaf, 0x71, 0x60, 0x48, 0x54, 0x5c, 0x3d, 0x1f, 0xfb, 0x0a, 0x8b, 0xb2, + 0xf7, 0x4b, 0x05, 0x0e, 0xf7, 0xa1, 0x85, 0x15, 0x93, 0x8a, 0x92, 0x8b, + 0x8d, 0x8b, 0xd5, 0x8b, 0xc3, 0x9c, 0xc7, 0xb6, 0xf7, 0x02, 0xd8, 0xca, + 0xf7, 0x05, 0x8b, 0xf7, 0x0c, 0x08, 0xf7, 0x1a, 0x2d, 0xef, 0xfb, 0x14, + 0xfb, 0x49, 0xfb, 0x3f, 0xfb, 0x4c, 0xfb, 0x55, 0x1e, 0x8b, 0x60, 0x95, + 0x61, 0x9c, 0x69, 0x9c, 0x69, 0xa5, 0x73, 0xc2, 0x67, 0x08, 0x40, 0x4f, + 0x05, 0x75, 0x79, 0x84, 0x7f, 0x8b, 0x76, 0x8b, 0x76, 0x9c, 0x79, 0xa0, + 0x8b, 0x92, 0x8b, 0x95, 0x8d, 0x97, 0x8e, 0xb6, 0x95, 0xce, 0x96, 0xa1, + 0x8b, 0x98, 0x8b, 0xa1, 0x87, 0x95, 0x87, 0x08, 0xb7, 0x78, 0x90, 0x8a, + 0xa3, 0x8b, 0xb0, 0x8b, 0xb9, 0x9b, 0xb3, 0xa6, 0x9d, 0x97, 0x96, 0x9e, + 0x8b, 0x9e, 0x8b, 0xa2, 0x7a, 0x9b, 0x73, 0x8b, 0x7f, 0x8b, 0x85, 0x89, + 0x71, 0x7c, 0x75, 0x7f, 0x82, 0x88, 0x7c, 0x8b, 0x08, 0x7f, 0x8b, 0x85, + 0x8c, 0x75, 0x91, 0x08, 0x6c, 0x94, 0x73, 0x8f, 0x70, 0x8b, 0x7d, 0x8b, + 0x7f, 0x8a, 0x72, 0x87, 0x08, 0x93, 0xa3, 0x05, 0xf7, 0x1c, 0xf8, 0x8b, + 0x15, 0xdc, 0xc7, 0x49, 0x32, 0xfb, 0x18, 0xfb, 0x04, 0xfb, 0x11, 0xfb, + 0x09, 0x3b, 0x4f, 0xce, 0xe5, 0xf7, 0x15, 0xf7, 0x05, 0xf7, 0x12, 0xf7, + 0x07, 0x1f, 0x0e, 0xf7, 0x86, 0xf7, 0x72, 0x15, 0xeb, 0x06, 0xb2, 0x7c, + 0xce, 0xfb, 0x01, 0xaa, 0x29, 0x08, 0xd9, 0x06, 0xa7, 0x8b, 0x99, 0x8f, + 0x98, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x08, 0xa9, 0x7c, 0x95, + 0x61, 0x1e, 0x7e, 0x06, 0x70, 0xcd, 0x6f, 0xbb, 0x66, 0xb3, 0xea, 0xba, + 0xbb, 0xc8, 0x8b, 0xd7, 0x08, 0xe5, 0x45, 0xc2, 0xfb, 0x07, 0x1e, 0xfb, + 0x73, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, + 0x13, 0x7c, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x7f, 0x7d, 0x7f, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x29, + 0x06, 0xa7, 0x8b, 0x99, 0x8f, 0x98, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x79, + 0x8b, 0x08, 0x68, 0x8b, 0xa5, 0xf7, 0x0e, 0x05, 0xa0, 0xef, 0x15, 0xad, + 0xf7, 0x35, 0xf7, 0x04, 0x8b, 0x05, 0xc4, 0xb1, 0x72, 0x65, 0x55, 0x41, + 0x5f, 0x30, 0x1f, 0x3f, 0x06, 0x0e, 0xf9, 0x0a, 0xf8, 0xa7, 0x15, 0x8e, + 0x9d, 0x8c, 0x90, 0x8b, 0x92, 0x8b, 0xa0, 0x7b, 0x9a, 0x73, 0x8b, 0x78, + 0x8b, 0x80, 0x83, 0x7b, 0x72, 0x6d, 0xa1, 0x61, 0x96, 0x58, 0x8b, 0xfb, + 0x21, 0x8b, 0xfb, 0x09, 0x2b, 0x8b, 0xfb, 0x08, 0x8b, 0x62, 0xa1, 0x63, + 0xad, 0x74, 0x08, 0xa7, 0x79, 0xa9, 0x81, 0xcb, 0x80, 0xd0, 0x7e, 0x9f, + 0x85, 0x9b, 0x7e, 0x98, 0x81, 0x92, 0x7e, 0x8b, 0x7d, 0x8b, 0x5b, 0x47, + 0x64, 0x38, 0x8b, 0x4a, 0x8b, 0x52, 0xa8, 0x88, 0xaf, 0x89, 0xa6, 0x8b, + 0x8b, 0x86, 0x92, 0x08, 0x84, 0x94, 0x7f, 0x90, 0x7e, 0x8b, 0x68, 0x8b, + 0x77, 0x76, 0x81, 0x5e, 0x08, 0x7d, 0x49, 0x05, 0x89, 0x7f, 0x89, 0x80, + 0x8b, 0x85, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, 0x94, 0x90, + 0xa0, 0x9e, 0xb7, 0x71, 0xbd, 0x7e, 0xc1, 0x8b, 0xf7, 0x2f, 0x8b, 0xf7, + 0x07, 0xe6, 0x8b, 0xf7, 0x0e, 0x8b, 0xbb, 0x70, 0xb4, 0x5e, 0xa0, 0x08, + 0x71, 0x97, 0x6f, 0x93, 0x53, 0x96, 0x3f, 0x9a, 0x80, 0x8e, 0x7d, 0x97, + 0x7f, 0x95, 0x83, 0x9b, 0x8b, 0x9a, 0x08, 0xb9, 0xc8, 0xb3, 0xd1, 0xc9, + 0xb5, 0x70, 0x63, 0x1e, 0x8c, 0x6b, 0x8b, 0x8b, 0x90, 0x84, 0x92, 0x82, + 0x98, 0x85, 0x98, 0x8b, 0x9a, 0x8b, 0x9c, 0x93, 0x98, 0x98, 0x94, 0x95, + 0x8f, 0x93, 0x91, 0xa7, 0x08, 0x9e, 0xe3, 0x05, 0x0e, 0xf8, 0x58, 0xf8, + 0x77, 0x15, 0xf7, 0x01, 0x8b, 0x77, 0x2e, 0x05, 0x88, 0x7e, 0x8a, 0x82, + 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, + 0x97, 0x98, 0x95, 0x95, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0xb4, 0xf7, 0x55, + 0xfc, 0x98, 0x8b, 0x62, 0xfb, 0x55, 0x05, 0x88, 0x7f, 0x8a, 0x81, 0x8b, + 0x84, 0x8b, 0x77, 0x9d, 0x7a, 0xa1, 0x8b, 0x9a, 0x8b, 0x9c, 0x93, 0x98, + 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, 0xa6, 0x08, 0x9f, 0xe8, 0xf6, 0x8b, + 0x39, 0xfc, 0x13, 0x4b, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, + 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb3, 0x1e, + 0xf7, 0x7b, 0x06, 0xa6, 0x8b, 0x99, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x82, 0x8e, 0x85, + 0x8c, 0x77, 0x8b, 0x08, 0x49, 0x8b, 0xdd, 0xf8, 0x13, 0x05, 0x0e, 0xf9, + 0x0c, 0xf8, 0x77, 0x15, 0xa4, 0x8b, 0x96, 0x8f, 0x99, 0x96, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x15, 0x06, 0x6b, 0x8b, 0x83, 0x89, + 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, + 0xb4, 0x1e, 0xae, 0x8b, 0x4e, 0xfb, 0xb3, 0x05, 0x7e, 0x4e, 0x47, 0x5a, + 0x44, 0x8b, 0x4d, 0x8b, 0x5d, 0xb1, 0x8b, 0xbf, 0x8b, 0x91, 0x8c, 0x92, + 0x8c, 0x92, 0x08, 0xc8, 0xf7, 0xb3, 0xae, 0x8b, 0x05, 0xa9, 0x8b, 0x96, + 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, + 0x9b, 0x7e, 0x8f, 0x83, 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfb, 0x16, + 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6f, 0x9a, 0x7f, 0xaf, 0x1e, 0x50, 0xfb, 0xaa, 0x05, 0x88, + 0x7a, 0x89, 0x7c, 0x8b, 0x7c, 0x8b, 0x28, 0xda, 0x42, 0xf7, 0x01, 0x8b, + 0xf7, 0x15, 0x8b, 0xf7, 0x0c, 0xea, 0xa5, 0xf7, 0x10, 0x08, 0xc6, 0xf7, + 0xaa, 0x05, 0x0e, 0xf7, 0xe1, 0xf7, 0x24, 0x15, 0x43, 0xf7, 0xe7, 0x9e, + 0x8b, 0x05, 0xaa, 0x8b, 0x95, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, + 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, + 0x79, 0x8b, 0x08, 0xfb, 0x19, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x71, 0x9a, 0x7f, 0xaa, 0x89, + 0x08, 0x97, 0x8b, 0xef, 0xfc, 0x77, 0xed, 0x8b, 0xf7, 0xc8, 0xf8, 0x77, + 0x05, 0xa6, 0x8b, 0x93, 0x8c, 0x96, 0x91, 0x9f, 0x96, 0x99, 0xa1, 0x8b, + 0x9f, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x78, + 0x8b, 0x08, 0xfb, 0x17, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, + 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7b, 0x94, 0x7c, 0x98, 0x86, 0x93, + 0x88, 0x91, 0x8a, 0x9f, 0x8b, 0x08, 0xa4, 0x8b, 0xfb, 0x6d, 0xfb, 0xe7, + 0x05, 0x0e, 0xf7, 0xfb, 0xf7, 0xa9, 0x15, 0xae, 0xfb, 0xa9, 0xf7, 0x02, + 0x8b, 0xf7, 0x37, 0xf8, 0x77, 0x05, 0xae, 0x91, 0xa2, 0xa3, 0x8b, 0xaa, + 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, + 0x08, 0xfb, 0x16, 0x06, 0x6b, 0x8b, 0x82, 0x89, 0x7d, 0x7f, 0x7d, 0x7e, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xc1, 0x8b, + 0x2d, 0xfb, 0xa4, 0x6f, 0xf7, 0x76, 0x24, 0x8b, 0xfb, 0x10, 0xfb, 0x76, + 0xa0, 0xf7, 0xa4, 0xbb, 0x8b, 0x05, 0xa9, 0x8b, 0x96, 0x8e, 0x9a, 0x97, + 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, + 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x18, 0x06, 0x6c, 0x8b, + 0x83, 0x89, 0x7c, 0x7f, 0x7c, 0x7e, 0x82, 0x78, 0x8b, 0x79, 0x8b, 0x76, + 0x97, 0x7f, 0xa4, 0x88, 0x08, 0x62, 0xfc, 0x77, 0xf7, 0x03, 0x8b, 0xf7, + 0x2a, 0xf7, 0xa9, 0x05, 0x0e, 0xf8, 0x3f, 0xf7, 0xbd, 0x15, 0xf7, 0x58, + 0xf7, 0x4e, 0x05, 0xb3, 0x8c, 0xa8, 0xa4, 0x8b, 0xae, 0x8b, 0x9b, 0x82, + 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x31, 0x06, + 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x80, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, + 0x8b, 0x78, 0x90, 0x84, 0xa2, 0x7e, 0x08, 0xfb, 0x08, 0xfb, 0x01, 0x44, + 0xf7, 0x01, 0x05, 0xad, 0x9b, 0x9a, 0x9c, 0x8b, 0xa6, 0x8b, 0x9b, 0x81, + 0x9a, 0x7f, 0x8f, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x30, 0x06, + 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, + 0x8b, 0x71, 0x9a, 0x7e, 0xac, 0x8a, 0x08, 0xf7, 0x0b, 0xfb, 0x4d, 0xfb, + 0x65, 0xfb, 0x5a, 0x05, 0x62, 0x6e, 0x72, 0x68, 0x6e, 0x9b, 0x80, 0xb4, + 0x1f, 0xf7, 0x02, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0xa5, 0x7c, 0x98, 0x6d, 0x8c, 0x08, 0xf7, + 0x14, 0xf7, 0x0c, 0xd7, 0xfb, 0x0c, 0x05, 0x72, 0x89, 0x7f, 0x87, 0x7e, + 0x7c, 0x80, 0x80, 0x85, 0x7c, 0x8b, 0x7e, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0x02, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x08, 0xa6, 0x7b, 0x98, 0x6a, 0x1e, 0xfb, 0x11, + 0xf7, 0x59, 0x05, 0x0e, 0xf8, 0x26, 0xf7, 0x89, 0x15, 0xf7, 0x6b, 0xf7, + 0x82, 0x8e, 0x8b, 0x05, 0xa4, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x2e, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, + 0x80, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x77, 0x93, 0x80, 0xa1, + 0x82, 0x08, 0xfb, 0x0f, 0xfb, 0x1b, 0x49, 0xf7, 0x1b, 0x05, 0xac, 0x98, + 0x9c, 0xa0, 0x8b, 0xa6, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x31, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, + 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x71, 0x9c, 0x7d, 0xaa, + 0x1e, 0x91, 0x8b, 0xf7, 0x06, 0xfb, 0x82, 0x6d, 0xfb, 0x25, 0x49, 0x8b, + 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x7b, 0x06, 0xa7, 0x8b, + 0x98, 0x8f, 0x99, 0x96, 0x99, 0x96, 0x94, 0x9e, 0x8b, 0x9b, 0x8b, 0x9a, + 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x4a, + 0x8b, 0xa9, 0xf7, 0x25, 0x05, 0x0e, 0xf7, 0x72, 0xef, 0x15, 0xf8, 0x15, + 0xf8, 0x16, 0xa0, 0xec, 0xfc, 0x2c, 0x8b, 0x67, 0xfb, 0x3e, 0x05, 0x86, + 0x78, 0x8b, 0x89, 0x8b, 0x83, 0x8b, 0x77, 0x9d, 0x7a, 0xa1, 0x8b, 0x9b, + 0x8b, 0x9c, 0x93, 0x98, 0x98, 0x94, 0x94, 0x8f, 0x95, 0x91, 0xa5, 0x08, + 0x9a, 0xd1, 0xf7, 0x46, 0x8b, 0xfc, 0x13, 0xfc, 0x13, 0x76, 0x27, 0xf8, + 0x5a, 0x8b, 0xb0, 0xf7, 0x40, 0x05, 0x8f, 0x9e, 0x8b, 0x8c, 0x8b, 0x93, + 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7f, + 0x82, 0x81, 0x86, 0x81, 0x86, 0x71, 0x08, 0x7b, 0x43, 0xfb, 0x76, 0x8b, + 0x05, 0x0e, 0xf8, 0x62, 0xf8, 0xa3, 0x15, 0xc5, 0x06, 0xa9, 0x8b, 0x96, + 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, + 0x99, 0x7e, 0x90, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x32, + 0x8b, 0xfb, 0x39, 0xfd, 0x9b, 0xf7, 0x33, 0x8b, 0x05, 0xa8, 0x8b, 0x97, + 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, + 0x9a, 0x7e, 0x8f, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x50, 0x8b, + 0xf7, 0x0e, 0xf8, 0xd3, 0x05, 0x0e, 0xf7, 0xd6, 0xf9, 0x1f, 0x15, 0x83, + 0xad, 0x81, 0x95, 0x73, 0x8b, 0x6c, 0x8b, 0x6d, 0x6e, 0x8b, 0x6d, 0x8b, + 0x85, 0x8c, 0x84, 0x8f, 0x7e, 0x08, 0xf7, 0x44, 0xfd, 0x3b, 0x05, 0x93, + 0x69, 0x95, 0x81, 0xa4, 0x8b, 0xaa, 0x8b, 0xa9, 0xa8, 0x8b, 0xa9, 0x8b, + 0x91, 0x89, 0x95, 0x88, 0x96, 0x08, 0xfb, 0x45, 0xf9, 0x3a, 0x05, 0x0e, + 0xf7, 0x84, 0x5b, 0x15, 0x51, 0x06, 0x6d, 0x8b, 0x80, 0x88, 0x7d, 0x7f, + 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7b, 0x94, 0x7d, 0x98, 0x86, + 0x93, 0x88, 0x91, 0x8a, 0x9f, 0x8b, 0x08, 0xf7, 0x32, 0x8b, 0xf7, 0x39, + 0xf9, 0x9b, 0xfb, 0x33, 0x8b, 0x05, 0x6e, 0x8b, 0x7f, 0x88, 0x7d, 0x7f, + 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7a, 0x8b, 0x7b, 0x94, 0x7c, 0x98, 0x87, + 0x94, 0x88, 0x91, 0x8a, 0x9f, 0x8b, 0x08, 0xc6, 0x8b, 0xfb, 0x0e, 0xfc, + 0xd3, 0x05, 0x0e, 0xf8, 0x28, 0xf8, 0x82, 0x15, 0xe5, 0xfb, 0x1f, 0x05, + 0x9b, 0x72, 0x92, 0x86, 0x9e, 0x8b, 0xaa, 0x8b, 0xaa, 0xa9, 0x8b, 0xa8, + 0x8b, 0x96, 0x88, 0x92, 0x80, 0x9c, 0x08, 0xfb, 0x26, 0xf7, 0x7d, 0xfb, + 0x89, 0xfb, 0x7d, 0x05, 0x72, 0x73, 0x84, 0x80, 0x8b, 0x78, 0x8b, 0x74, + 0x9c, 0x7a, 0xa3, 0x8b, 0x9e, 0x8b, 0x93, 0x90, 0xa7, 0xa5, 0x08, 0xf7, + 0x27, 0xf7, 0x1e, 0x05, 0x0e, 0xf8, 0xc8, 0x40, 0x15, 0xfd, 0x05, 0x59, + 0xf9, 0x05, 0xbd, 0x06, 0x0e, 0xf8, 0x91, 0xf8, 0xee, 0x15, 0xfb, 0x18, + 0x8b, 0xe7, 0xfb, 0x7a, 0x05, 0x93, 0x79, 0x91, 0x85, 0x98, 0x8b, 0x08, + 0xa0, 0x9c, 0x9c, 0xa1, 0x1f, 0x8b, 0x93, 0x72, 0xf7, 0x63, 0x05, 0x0e, + 0xf8, 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa8, 0x8b, 0x98, 0x8e, 0x98, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, + 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x7a, 0x8b, 0xb6, 0xf7, 0x5e, + 0x05, 0x8e, 0x97, 0x8c, 0x95, 0x8b, 0x98, 0x8b, 0xd1, 0x4b, 0xb6, 0x23, + 0x8b, 0x54, 0x8b, 0x29, 0x7a, 0x69, 0x7b, 0x77, 0x82, 0x7e, 0x77, 0x8b, + 0x75, 0x8b, 0x74, 0x9b, 0x7b, 0xa1, 0x8b, 0x96, 0x8b, 0x99, 0x8d, 0x9c, + 0x8f, 0x08, 0xb9, 0x96, 0xb5, 0x91, 0xab, 0x8b, 0xc4, 0x8b, 0xa6, 0x7f, + 0x8b, 0x70, 0x8b, 0x85, 0x8b, 0x8b, 0x8a, 0x87, 0x08, 0x86, 0x74, 0x05, + 0x64, 0x92, 0x6d, 0x8e, 0x6b, 0x8b, 0x25, 0x8b, 0x35, 0x68, 0x56, 0x4c, + 0x71, 0x6c, 0x7d, 0x6b, 0x8b, 0x6e, 0x08, 0x49, 0xcc, 0x5b, 0xe4, 0x1e, + 0xc6, 0x8b, 0xc9, 0x99, 0xc0, 0xa4, 0x08, 0x86, 0x74, 0x05, 0xa9, 0xf7, + 0x1b, 0x15, 0x4c, 0x69, 0x50, 0x7a, 0x54, 0x8b, 0x65, 0x8b, 0x6e, 0x9a, + 0x8b, 0x9e, 0x8b, 0x97, 0x93, 0x97, 0x9b, 0x99, 0xab, 0xa5, 0xb4, 0x99, + 0xbc, 0x8b, 0xad, 0x8b, 0xaf, 0x87, 0xb1, 0x84, 0x08, 0x81, 0x59, 0x05, + 0x0e, 0xf7, 0xc7, 0xf9, 0x04, 0x15, 0xfb, 0x08, 0x06, 0x6c, 0x8b, 0x81, + 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, + 0x80, 0xb5, 0x1e, 0x9b, 0x8b, 0x31, 0xfc, 0x3c, 0x7b, 0x8b, 0x05, 0x6c, + 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x08, 0x8b, 0x93, 0xae, 0x05, 0xb7, + 0x67, 0xb0, 0x7e, 0xc5, 0x8b, 0xe3, 0x8b, 0xd3, 0xa9, 0xc7, 0xc8, 0xbe, + 0xbf, 0xaa, 0xd3, 0x8b, 0xcf, 0x8b, 0xc2, 0x74, 0xbf, 0x63, 0xac, 0x6b, + 0xa7, 0x5a, 0x99, 0x4e, 0x8b, 0x51, 0x8b, 0x58, 0x7b, 0x59, 0x69, 0x08, + 0xbb, 0xf7, 0x73, 0x05, 0xe3, 0xfb, 0xa5, 0x15, 0xaf, 0x8b, 0xa8, 0x84, + 0x9d, 0x7d, 0xa6, 0x77, 0x9a, 0x6c, 0x8b, 0x68, 0x8b, 0x6c, 0x7d, 0x69, + 0x74, 0x6f, 0x68, 0x60, 0x5b, 0x75, 0x52, 0x8b, 0x3c, 0x8b, 0x5d, 0xb3, + 0x8b, 0xce, 0x8b, 0xaa, 0x98, 0xad, 0xa3, 0xa7, 0x08, 0xaf, 0xb6, 0xb9, + 0xa1, 0xc5, 0x8b, 0x08, 0x0e, 0xf9, 0x02, 0xf8, 0x14, 0x15, 0x8e, 0x9b, + 0x8c, 0x90, 0x8b, 0x92, 0x8b, 0xa3, 0x7d, 0x99, 0x73, 0x8b, 0x76, 0x8b, + 0x7e, 0x82, 0x81, 0x76, 0x68, 0x9f, 0x5d, 0x95, 0x53, 0x8b, 0x2e, 0x8b, + 0x3b, 0x69, 0x4f, 0x4a, 0x59, 0x55, 0x6c, 0x41, 0x8b, 0x48, 0x08, 0x8b, + 0x57, 0xa1, 0x5b, 0xb2, 0x6d, 0xae, 0x6f, 0xc2, 0x7d, 0xd4, 0x8b, 0xef, + 0x8b, 0xd5, 0x9d, 0xc0, 0xb0, 0xa5, 0x9d, 0x9a, 0xa1, 0x8b, 0x9f, 0x8b, + 0xa3, 0x7a, 0x9c, 0x74, 0x8b, 0x7f, 0x8b, 0x81, 0x87, 0x80, 0x83, 0x08, + 0x5b, 0x69, 0x67, 0x81, 0x3b, 0x8b, 0x24, 0x8b, 0x59, 0xaa, 0x8b, 0xca, + 0x8b, 0xae, 0x9a, 0xb2, 0xa3, 0xa9, 0xb0, 0xb8, 0xbd, 0xa2, 0xcb, 0x8b, + 0xb7, 0x8b, 0xad, 0x82, 0xa2, 0x7b, 0x96, 0x82, 0x8f, 0x81, 0x8b, 0x7a, + 0x08, 0x8b, 0x76, 0x8c, 0x85, 0x91, 0x84, 0x92, 0x83, 0x99, 0x85, 0x97, + 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x97, 0x95, 0x95, 0x8f, 0x96, 0x91, + 0xa4, 0x08, 0x9b, 0xd8, 0x05, 0x0e, 0xf9, 0x2c, 0xf9, 0x04, 0x15, 0xfb, + 0x08, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, + 0x8b, 0x7c, 0x8b, 0x7a, 0x94, 0x7c, 0x98, 0x87, 0x93, 0x88, 0x94, 0x8a, + 0x9d, 0x8b, 0x08, 0x9b, 0x8b, 0x71, 0xfb, 0x10, 0x05, 0x67, 0xad, 0x5f, + 0x9b, 0x50, 0x8b, 0x31, 0x8b, 0x44, 0x6e, 0x4e, 0x4d, 0x58, 0x57, 0x6c, + 0x43, 0x8b, 0x47, 0x8b, 0x54, 0xa2, 0x57, 0xb3, 0x6a, 0xac, 0x6f, 0xbb, + 0x7d, 0xc7, 0x8b, 0xc5, 0x8b, 0xb6, 0x98, 0xc7, 0xaf, 0x08, 0x83, 0x68, + 0xf7, 0x08, 0x8b, 0x05, 0xa9, 0x8b, 0x96, 0x8e, 0x99, 0x97, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x7b, 0x8b, 0x05, 0xf7, 0x03, 0xf8, 0xa0, + 0x05, 0xfb, 0xca, 0xfb, 0xa5, 0x15, 0xb1, 0x8b, 0xa8, 0x84, 0x9d, 0x7d, + 0xa6, 0x77, 0x9a, 0x6c, 0x8b, 0x68, 0x8b, 0x6c, 0x7d, 0x69, 0x74, 0x6f, + 0x08, 0x67, 0x60, 0x5c, 0x75, 0x50, 0x8b, 0x3d, 0x8b, 0x5c, 0xb3, 0x8b, + 0xce, 0x8b, 0xaa, 0x99, 0xad, 0xa2, 0xa7, 0xaf, 0xb6, 0xba, 0xa1, 0xc4, + 0x8b, 0x08, 0x0e, 0xf8, 0xdf, 0xf7, 0x40, 0x15, 0x93, 0xb2, 0x05, 0x8e, + 0x9b, 0x8d, 0x9b, 0x8b, 0x9b, 0x08, 0xf7, 0x08, 0x38, 0xd6, 0xfb, 0x16, + 0xfb, 0x3a, 0xfb, 0x27, 0xfb, 0x18, 0xfb, 0x29, 0xfb, 0x06, 0xdf, 0x44, + 0xf7, 0x1c, 0x1e, 0xdb, 0x8b, 0xf7, 0x08, 0xa0, 0xb6, 0xa2, 0xa0, 0x96, + 0x97, 0x9d, 0x8b, 0xa1, 0x8b, 0xa1, 0x7c, 0x9b, 0x74, 0x8b, 0x82, 0x8b, + 0x7e, 0x89, 0x7e, 0x88, 0x2c, 0x74, 0x6e, 0x86, 0x5f, 0x8b, 0x33, 0x8b, + 0x5b, 0xa7, 0x80, 0xc7, 0x08, 0xf8, 0x2d, 0x06, 0xfc, 0x17, 0xe3, 0x15, + 0xa7, 0xc2, 0xcc, 0xae, 0xd5, 0x8b, 0xd3, 0x8b, 0xbe, 0x67, 0x90, 0x55, + 0x08, 0xfb, 0xbb, 0x06, 0x0e, 0xf8, 0x06, 0xf7, 0xe5, 0x15, 0xf7, 0x2b, + 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x76, + 0x8b, 0x08, 0xfb, 0x2a, 0x8b, 0x92, 0xb0, 0x05, 0x93, 0xac, 0xa9, 0x9b, + 0xc4, 0x8b, 0xaa, 0x8b, 0xb8, 0x87, 0xae, 0x84, 0x97, 0x89, 0x94, 0x8a, + 0x91, 0x8b, 0xa9, 0x8b, 0xa8, 0xa9, 0x8b, 0xaa, 0x8b, 0x9e, 0x80, 0x97, + 0x75, 0x91, 0x6d, 0x94, 0x4d, 0x92, 0x62, 0x8b, 0x08, 0xfb, 0x0c, 0x8b, + 0x35, 0x52, 0x77, 0x2f, 0x08, 0x83, 0x66, 0x5d, 0x8b, 0x05, 0x6b, 0x8b, + 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb5, 0x1e, 0xb9, 0x8b, 0x59, 0xfb, 0x81, 0x51, 0x8b, 0x05, + 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, + 0x08, 0x6f, 0x9b, 0x7f, 0xb3, 0x1e, 0xf7, 0xbe, 0x06, 0xa7, 0x8b, 0x98, + 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, + 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x1f, + 0x8b, 0xbd, 0xf7, 0x81, 0x05, 0x0e, 0xf8, 0x83, 0xf8, 0x25, 0x15, 0x6b, + 0xac, 0x5e, 0x9c, 0x56, 0x8b, 0x08, 0xfb, 0x2e, 0xfb, 0x1e, 0xfb, 0x19, + 0xfb, 0x2a, 0xfb, 0x00, 0xd9, 0x41, 0xf7, 0x06, 0x1f, 0xbf, 0x8b, 0xb9, + 0x9a, 0xc1, 0xad, 0x08, 0x7f, 0x54, 0x05, 0x80, 0x57, 0x5f, 0x6a, 0x52, + 0x8b, 0x08, 0xfb, 0x01, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, + 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, + 0x03, 0x06, 0xf7, 0x02, 0x8b, 0xee, 0xda, 0xa1, 0xf5, 0x08, 0xd7, 0xf7, + 0xf9, 0x9b, 0x8b, 0x05, 0xa9, 0x8b, 0x96, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x08, 0x83, + 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x09, 0x8b, 0x05, 0x84, 0x67, + 0x05, 0xfb, 0x2a, 0x59, 0x15, 0xce, 0xba, 0x5f, 0x4c, 0x3a, 0x39, 0x3e, + 0x33, 0x49, 0x5c, 0xb7, 0xca, 0x1f, 0xdc, 0xde, 0xd8, 0xe1, 0x1e, 0x0e, + 0xf7, 0xdc, 0xf9, 0x04, 0x15, 0xfb, 0x08, 0x06, 0x6c, 0x8b, 0x81, 0x88, + 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, + 0xb5, 0x1e, 0x9b, 0x8b, 0x31, 0xfc, 0x3c, 0x85, 0x8b, 0x05, 0x6c, 0x8b, + 0x82, 0x88, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x04, 0x06, 0xa8, 0x8b, 0x98, 0x8e, 0x99, + 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x81, 0x9a, 0x7f, + 0x90, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x85, 0x8b, 0xb2, 0xf7, + 0x4b, 0x05, 0xcf, 0xc3, 0xa3, 0x96, 0xbb, 0x8b, 0xb9, 0x8b, 0xa8, 0x78, + 0x8b, 0x6e, 0x8b, 0x83, 0x8a, 0x80, 0x88, 0x7f, 0x08, 0x67, 0xfb, 0x3f, + 0x85, 0x8b, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, + 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x04, 0x06, + 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, + 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x90, 0x83, 0x8e, 0x85, 0x8c, 0x76, 0x8b, + 0x08, 0x85, 0x8b, 0xb3, 0xf7, 0x4c, 0x05, 0x8e, 0x99, 0x8c, 0x99, 0x8b, + 0x98, 0x8b, 0xd7, 0x51, 0xbc, 0x33, 0x8b, 0x57, 0x8b, 0x5a, 0x77, 0x5a, + 0x62, 0x08, 0xbd, 0xf7, 0x7f, 0x05, 0x0e, 0xf8, 0x4f, 0xf8, 0x49, 0x15, + 0xfb, 0x46, 0x06, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, + 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb5, 0x1e, 0xd9, 0x8b, 0x59, + 0xfb, 0x81, 0xfb, 0x0e, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, + 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xf7, 0xeb, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, + 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x0d, 0x8b, 0xd2, 0xf7, 0xe5, 0x05, 0xa5, + 0xf7, 0x4e, 0x15, 0xfb, 0x0a, 0x8b, 0x74, 0x22, 0xf7, 0x0a, 0x8b, 0xa2, + 0xf4, 0x05, 0x0e, 0xf8, 0x60, 0xf7, 0xe5, 0x15, 0x3f, 0xfb, 0xf9, 0x05, + 0x80, 0x57, 0x5f, 0x6a, 0x51, 0x8b, 0x08, 0xfb, 0x02, 0x06, 0x6c, 0x8b, + 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x05, 0x06, 0xf7, 0x01, 0x8b, 0xef, 0xdb, + 0xa1, 0xf4, 0x08, 0xec, 0xf8, 0x5d, 0xfb, 0xc2, 0x8b, 0x05, 0x6c, 0x8b, + 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x5e, 0x06, 0xf2, 0xf7, 0xb2, 0x15, 0xfb, + 0x0c, 0x8b, 0x75, 0x22, 0xf7, 0x0b, 0x8b, 0xa2, 0xf4, 0x05, 0x0e, 0xf7, + 0x8d, 0xf7, 0x38, 0x15, 0xa0, 0x99, 0xdf, 0x30, 0x05, 0x79, 0x7b, 0x84, + 0x7d, 0x8b, 0x7a, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x0a, 0x06, + 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, + 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x78, 0x8b, + 0x08, 0x6a, 0x8b, 0xfb, 0x16, 0xf7, 0x21, 0xf7, 0x1f, 0xeb, 0xa6, 0x8b, + 0x05, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9c, 0x08, 0xa7, 0x7b, 0x96, 0x62, 0x1e, 0xfb, 0x04, 0x06, 0x6d, 0x8b, + 0x80, 0x88, 0x7d, 0x7f, 0x7c, 0x7f, 0x83, 0x7a, 0x8b, 0x7a, 0x8b, 0x81, + 0x8d, 0x86, 0x91, 0x80, 0x08, 0x2f, 0x4c, 0xd3, 0xf7, 0xe5, 0xfb, 0x08, + 0x8b, 0x05, 0x6d, 0x8b, 0x80, 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, + 0x8b, 0x7a, 0x8b, 0x7b, 0x94, 0x7c, 0x98, 0x87, 0x93, 0x88, 0x94, 0x8a, + 0x9d, 0x8b, 0x08, 0x9b, 0x8b, 0x31, 0xfc, 0x3c, 0x7b, 0x8b, 0x05, 0x6c, + 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x09, 0x8b, 0xad, 0xf7, 0x38, 0x05, + 0x0e, 0xf8, 0x77, 0xf9, 0x04, 0x15, 0xfb, 0x46, 0x06, 0x6c, 0x8b, 0x81, + 0x88, 0x7d, 0x80, 0x7c, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7b, 0x95, + 0x7b, 0x98, 0x87, 0x92, 0x88, 0x96, 0x8a, 0x9b, 0x8b, 0x08, 0xda, 0x8b, + 0x31, 0xfc, 0x3c, 0xfb, 0x0e, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0xeb, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x0d, 0x8b, 0xf7, 0x03, 0xf8, 0xa0, + 0x05, 0x0e, 0xf7, 0x7e, 0xf8, 0x49, 0x15, 0x2e, 0x06, 0x6c, 0x8b, 0x81, + 0x88, 0x7d, 0x7f, 0x7c, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x70, 0x9c, + 0x7e, 0xad, 0x1e, 0x59, 0xfb, 0x81, 0x05, 0x61, 0x6d, 0x72, 0x68, 0x6e, + 0x9b, 0x80, 0xb4, 0x1f, 0xe3, 0x06, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x08, 0xa6, 0x7a, 0x98, 0x69, 0x1e, + 0xb6, 0xf7, 0x61, 0x05, 0xb0, 0xad, 0xa1, 0x96, 0xa7, 0x8b, 0x9d, 0x8b, + 0x95, 0x84, 0x8b, 0x7d, 0x8b, 0x88, 0x8a, 0x83, 0x89, 0x84, 0x08, 0x49, + 0xfb, 0xcb, 0xe9, 0x8b, 0x05, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, + 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x08, 0xa6, 0x7a, 0x98, 0x6a, 0x1e, 0xb6, + 0xf7, 0x61, 0x05, 0xb5, 0xaf, 0x9c, 0x94, 0xa6, 0x8b, 0x9d, 0x8b, 0x94, + 0x84, 0x8c, 0x7e, 0x8b, 0x85, 0x8b, 0x85, 0x89, 0x84, 0x08, 0x49, 0xfb, + 0xcb, 0xe9, 0x8b, 0x05, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x08, 0xa6, 0x7a, 0x98, 0x69, 0x1e, 0xba, 0xf7, + 0x6f, 0x05, 0x8d, 0x96, 0x8c, 0x92, 0x8b, 0x98, 0x8b, 0xc6, 0x5f, 0xb4, + 0x4c, 0x8b, 0x63, 0x8b, 0x68, 0x7c, 0x64, 0x69, 0x75, 0xac, 0x6d, 0x9b, + 0x64, 0x8b, 0x6d, 0x8b, 0x75, 0x82, 0x62, 0x6f, 0x08, 0x90, 0xa3, 0x05, + 0x0e, 0xf7, 0xb4, 0xf8, 0x49, 0x15, 0x2d, 0x06, 0x6c, 0x8b, 0x81, 0x88, + 0x7c, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x70, 0x9c, 0x7e, + 0xae, 0x1e, 0x59, 0xfb, 0x81, 0x85, 0x8b, 0x05, 0x6c, 0x8b, 0x81, 0x88, + 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, + 0xb3, 0x1e, 0xf7, 0x04, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, + 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x90, 0x83, + 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x85, 0x8b, 0xb1, 0xf7, 0x4a, 0x05, + 0xc5, 0xbe, 0xae, 0x9c, 0xb9, 0x8b, 0xbd, 0x8b, 0xa7, 0x7a, 0x8b, 0x6b, + 0x8b, 0x84, 0x8a, 0x84, 0x89, 0x82, 0x08, 0x66, 0xfb, 0x46, 0x05, 0x72, + 0x8b, 0x80, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xe4, 0x06, 0xa7, 0x8b, 0x98, 0x8e, 0x99, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x08, 0xa6, 0x7a, 0x98, 0x68, + 0x1e, 0xb2, 0xf7, 0x4a, 0x05, 0x8e, 0x9b, 0x8d, 0x99, 0x8b, 0x9b, 0x8b, + 0xd4, 0x50, 0xbc, 0x33, 0x8b, 0x54, 0x8b, 0x66, 0x7c, 0x51, 0x5d, 0x08, + 0x95, 0xbb, 0x05, 0x0e, 0xf8, 0x23, 0xf8, 0x56, 0x15, 0x30, 0x8b, 0x2f, + 0x63, 0x51, 0x4b, 0x5c, 0x58, 0x70, 0x4b, 0x8b, 0x52, 0x08, 0xfb, 0x06, + 0xe0, 0x3f, 0xf7, 0x14, 0xf7, 0x37, 0xf7, 0x29, 0xf7, 0x17, 0xf7, 0x25, + 0xf7, 0x04, 0x35, 0xd9, 0xfb, 0x10, 0x1e, 0x74, 0x27, 0x15, 0xd7, 0xc2, + 0x5e, 0x4c, 0x37, 0x33, 0x41, 0x26, 0x3e, 0x54, 0xb8, 0xca, 0xe0, 0xe3, + 0xd4, 0xf1, 0x1f, 0x0e, 0xf7, 0x50, 0xcd, 0x15, 0xb6, 0x64, 0xb4, 0x7a, + 0xc4, 0x8b, 0x08, 0xf7, 0x35, 0xf7, 0x19, 0xf7, 0x09, 0xf7, 0x22, 0xf7, + 0x02, 0x3d, 0xd2, 0xfb, 0x0e, 0x1f, 0x4d, 0x8b, 0x5d, 0x7b, 0x51, 0x61, + 0x08, 0x95, 0xb8, 0xfb, 0x08, 0x8b, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7d, + 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, + 0x1e, 0x9c, 0x8b, 0x2d, 0xfc, 0x4e, 0x7b, 0x8b, 0x05, 0x6c, 0x8b, 0x81, + 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, + 0x80, 0xb3, 0x1e, 0xf7, 0x42, 0x06, 0xa9, 0x8b, 0x96, 0x8e, 0x99, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, + 0x83, 0x8e, 0x83, 0x8c, 0x79, 0x8b, 0x08, 0x51, 0x8b, 0x05, 0xaf, 0xf7, + 0x3f, 0x05, 0xf7, 0x66, 0xf7, 0xb0, 0x15, 0xd6, 0xbc, 0x65, 0x4f, 0x1f, + 0x8b, 0x62, 0x6f, 0x5e, 0x62, 0x70, 0x6d, 0x78, 0x67, 0x81, 0x62, 0x8b, + 0x61, 0x8b, 0x6c, 0x95, 0x75, 0x9e, 0x78, 0x9d, 0x7f, 0xa8, 0x8c, 0xa4, + 0x08, 0x8f, 0xda, 0xd7, 0xc7, 0xec, 0x8b, 0x08, 0x0e, 0xf8, 0x2c, 0x22, + 0x15, 0x51, 0x06, 0x6d, 0x8b, 0x80, 0x88, 0x7d, 0x7f, 0x7d, 0x80, 0x82, + 0x78, 0x8b, 0x7b, 0x8b, 0x7c, 0x95, 0x7b, 0x97, 0x87, 0x92, 0x88, 0x96, + 0x8a, 0x9c, 0x8b, 0x08, 0xf7, 0x42, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x99, 0x7e, + 0x90, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x7b, 0x8b, 0xe9, 0xf8, + 0x4e, 0x9b, 0x8b, 0x05, 0xa9, 0x8b, 0x96, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x99, 0x7e, 0x90, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x09, 0x8b, 0x82, 0x5e, 0x05, 0x63, + 0xb5, 0x64, 0x9b, 0x4d, 0x8b, 0x42, 0x8b, 0x46, 0x73, 0x55, 0x5e, 0x4c, + 0x56, 0x64, 0x3d, 0x8b, 0x42, 0x8b, 0x28, 0xde, 0x47, 0xf7, 0x0b, 0x8b, + 0xc6, 0x8b, 0xbb, 0x9b, 0xc7, 0xb3, 0x08, 0x67, 0xfb, 0x3f, 0x05, 0x57, + 0xf8, 0x5b, 0x15, 0xda, 0xba, 0x66, 0x4b, 0x1f, 0x8b, 0x65, 0x6e, 0x5d, + 0x63, 0x71, 0x6d, 0x78, 0x67, 0x81, 0x61, 0x8b, 0x3e, 0x8b, 0x5a, 0xb1, + 0x8b, 0xc7, 0x8b, 0xb4, 0xa7, 0xb8, 0xb4, 0xa6, 0xaa, 0x9e, 0xae, 0x95, + 0xb5, 0x8b, 0x08, 0x0e, 0xf8, 0x07, 0xf8, 0x49, 0x15, 0xfb, 0x1b, 0x06, + 0x72, 0x8b, 0x7b, 0x87, 0x7e, 0x80, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, + 0x08, 0x6f, 0x9b, 0x80, 0xb3, 0x1e, 0xae, 0x8b, 0x59, 0xfb, 0x82, 0x50, + 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7d, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0xbe, 0x06, 0xa7, + 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, + 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, + 0xfb, 0x1f, 0x8b, 0xaa, 0xf7, 0x28, 0x05, 0xf6, 0xd6, 0xbb, 0xa6, 0xaa, + 0x8b, 0x9a, 0x8b, 0x94, 0x86, 0x97, 0x7e, 0x97, 0x7e, 0x94, 0x86, 0x99, + 0x8b, 0x08, 0xaa, 0xaa, 0xaa, 0xa9, 0xae, 0x53, 0xb2, 0x56, 0x1f, 0x5a, + 0x8b, 0x66, 0x7c, 0x2a, 0x4e, 0x08, 0x98, 0xcb, 0x05, 0x0e, 0xf8, 0x6f, + 0xf7, 0xcc, 0x15, 0x93, 0x75, 0x97, 0x82, 0xa0, 0x8b, 0x9a, 0x8b, 0x9c, + 0x93, 0x98, 0x97, 0x95, 0x95, 0x8e, 0x94, 0x91, 0xa6, 0x08, 0x93, 0xb0, + 0x05, 0x8e, 0x99, 0x8c, 0x94, 0x8b, 0x92, 0x8b, 0xa1, 0x7c, 0x99, 0x75, + 0x8b, 0x7b, 0x8b, 0x82, 0x85, 0x7e, 0x77, 0x68, 0x9d, 0x63, 0x93, 0x5b, + 0x8b, 0xfb, 0x1a, 0x8b, 0x23, 0x44, 0x8b, 0x31, 0x8b, 0x4a, 0xbd, 0x6b, + 0xf7, 0x0e, 0x7e, 0x08, 0xc0, 0x85, 0xa0, 0x87, 0x9a, 0x84, 0x9c, 0x84, + 0x95, 0x7f, 0x8b, 0x7f, 0x8b, 0x72, 0x51, 0x75, 0x47, 0x8b, 0x55, 0x8b, + 0x63, 0x98, 0x74, 0xa5, 0x88, 0xa9, 0x7e, 0x99, 0x71, 0x8b, 0x68, 0x8b, + 0x77, 0x76, 0x81, 0x5d, 0x08, 0x84, 0x6a, 0x05, 0x88, 0x7c, 0x8a, 0x84, + 0x8b, 0x85, 0x8b, 0x74, 0x9c, 0x7c, 0xa3, 0x8b, 0x98, 0x8b, 0x93, 0x8e, + 0x99, 0x94, 0xaf, 0x78, 0xbb, 0x81, 0xc5, 0x8b, 0xf7, 0x24, 0x8b, 0xf7, + 0x03, 0xd4, 0x8b, 0xe8, 0x8b, 0xb0, 0x79, 0xab, 0x6c, 0x9f, 0x08, 0x71, + 0x9b, 0x66, 0x96, 0x42, 0x95, 0x4d, 0x94, 0x85, 0x8c, 0x7f, 0x90, 0x7e, + 0x90, 0x82, 0x94, 0x8b, 0x92, 0x8b, 0x9e, 0xbf, 0x9e, 0xc2, 0x8b, 0xb5, + 0x8b, 0xaa, 0x82, 0xa2, 0x77, 0x08, 0x8e, 0x82, 0x05, 0x0e, 0xf7, 0xb2, + 0xf7, 0xe5, 0x15, 0xf7, 0x49, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, + 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x49, 0x8b, 0x9e, 0xe3, + 0x05, 0x8f, 0x9e, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, + 0x8b, 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7f, 0x81, 0x81, 0x87, 0x81, 0x86, + 0x71, 0x08, 0x78, 0x33, 0x68, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xae, 0x8b, 0x5d, 0xfb, 0x6b, 0x05, 0x89, 0x81, 0x8a, 0x83, 0x8b, + 0x7f, 0x8b, 0x6b, 0x99, 0x6f, 0xa2, 0x7b, 0xa8, 0x77, 0xb7, 0x7f, 0xb7, + 0x8b, 0xd1, 0x8b, 0xeb, 0xa2, 0xc2, 0xa9, 0xa3, 0x98, 0x96, 0x9c, 0x8b, + 0xa1, 0x8b, 0xa3, 0x7b, 0x9b, 0x74, 0x8b, 0x08, 0x80, 0x8b, 0x84, 0x89, + 0x79, 0x82, 0x59, 0x74, 0x58, 0x80, 0x56, 0x8b, 0x58, 0x8b, 0x71, 0x96, + 0x8b, 0xa1, 0x8b, 0x91, 0x8c, 0x94, 0x8d, 0x94, 0x08, 0xb5, 0xf7, 0x58, + 0x05, 0x0e, 0xf8, 0xef, 0xf8, 0x49, 0x15, 0xfb, 0x1b, 0x06, 0x6c, 0x8b, + 0x82, 0x88, 0x7c, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, + 0x9b, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x64, 0xfb, 0x4b, 0x05, 0x4c, 0x55, + 0x6e, 0x7d, 0x59, 0x8b, 0x5b, 0x8b, 0x70, 0x9d, 0x8b, 0xaa, 0x8b, 0x93, + 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xc6, 0xf7, 0xaa, 0xfb, 0x08, 0x8b, 0x05, + 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7c, + 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0x9b, 0x8b, 0x65, 0xfb, 0x4a, 0x05, + 0x87, 0x7b, 0x8a, 0x7e, 0x8b, 0x7a, 0x8b, 0x41, 0xc6, 0x5a, 0xe3, 0x8b, + 0xc3, 0x8b, 0xad, 0x99, 0xc7, 0xba, 0x08, 0x81, 0x5b, 0xe9, 0x8b, 0x05, + 0xa8, 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x9a, 0x96, 0x94, 0x9d, 0x8b, 0x9c, + 0x08, 0xa5, 0x7a, 0x98, 0x68, 0x1e, 0xd3, 0xf7, 0xe5, 0x05, 0x0e, 0xf7, + 0xdb, 0xf7, 0x0e, 0x15, 0x4c, 0xf7, 0x6b, 0x91, 0x8b, 0x05, 0xa8, 0x8b, + 0x96, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, + 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x79, 0x8b, 0x08, 0xfb, + 0x18, 0x06, 0x6d, 0x8b, 0x80, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x98, 0x8b, 0xeb, 0xfb, + 0xe5, 0xf2, 0x8b, 0xf7, 0x83, 0xf7, 0xe5, 0x9b, 0x8b, 0x05, 0xa9, 0x8b, + 0x96, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x78, 0x8b, 0x08, 0xfb, + 0x1a, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x95, 0x8b, 0xfb, 0x2e, + 0xfb, 0x6b, 0x05, 0x0e, 0xf7, 0xe8, 0xf7, 0x49, 0x15, 0xac, 0xfb, 0x49, + 0xe7, 0x8b, 0xf7, 0x2f, 0xf7, 0xe6, 0x05, 0xa2, 0x8d, 0x96, 0x8f, 0x98, + 0x99, 0x96, 0x96, 0x91, 0x9a, 0x8b, 0x98, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, + 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2f, 0x06, 0x6c, 0x8b, + 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7b, + 0x94, 0x7c, 0x98, 0x87, 0x93, 0x88, 0x93, 0x8a, 0x9e, 0x8b, 0x08, 0x92, + 0x8b, 0x42, 0xfb, 0x2d, 0x70, 0xf7, 0x32, 0x32, 0x8b, 0x2e, 0xfb, 0x32, + 0x85, 0xf7, 0x2d, 0x05, 0xa9, 0x8b, 0x94, 0x8e, 0x99, 0x96, 0x98, 0x97, + 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x2f, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, + 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x72, 0x9a, 0x7e, 0xa9, + 0x8a, 0x08, 0x98, 0xfb, 0xe6, 0xe9, 0x8b, 0xf5, 0xf7, 0x49, 0x05, 0x0e, + 0xf8, 0x39, 0xf7, 0x77, 0x15, 0xf7, 0x2f, 0xf7, 0x02, 0x05, 0xb2, 0x8f, + 0xa5, 0xa3, 0x8b, 0xac, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x82, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x2f, 0x06, 0x6d, 0x8b, 0x81, 0x88, 0x7c, + 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7e, 0x90, 0x82, 0x98, + 0x80, 0x08, 0x44, 0x59, 0x58, 0xbc, 0x05, 0xa2, 0x98, 0x99, 0xa1, 0x8b, + 0x9f, 0x8b, 0x9c, 0x82, 0x99, 0x7e, 0x90, 0x83, 0x8e, 0x85, 0x8c, 0x77, + 0x8b, 0x08, 0x2e, 0x06, 0x6d, 0x8b, 0x81, 0x88, 0x7c, 0x7f, 0x7d, 0x80, + 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x73, 0x99, 0x7e, 0xa8, 0x88, 0x08, 0xf4, + 0xfb, 0x01, 0xfb, 0x40, 0xfb, 0x14, 0x05, 0x73, 0x89, 0x7f, 0x87, 0x7e, + 0x7c, 0x80, 0x80, 0x85, 0x7c, 0x8b, 0x7e, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0x02, 0x06, 0xa8, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9e, 0x84, 0x93, 0x74, 0x96, 0x08, 0xe2, + 0xc8, 0xc9, 0x4e, 0x05, 0x6c, 0x83, 0x76, 0x72, 0x8b, 0x70, 0x08, 0x6e, + 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x04, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0xa5, 0x7c, 0x98, 0x6d, + 0x8c, 0x08, 0xfb, 0x10, 0xf7, 0x13, 0x05, 0x0e, 0xf7, 0x87, 0x8e, 0x15, + 0x3d, 0xfb, 0x00, 0x27, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xf7, 0x6a, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x83, + 0x8c, 0x78, 0x8b, 0x08, 0x86, 0x8b, 0xf7, 0xd9, 0xf8, 0x4e, 0x05, 0xb0, + 0x8f, 0xa5, 0xa3, 0x8b, 0xab, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, + 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2f, 0x06, 0x6c, 0x8b, 0x81, 0x88, + 0x7d, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x71, 0x9c, 0x7d, + 0xab, 0x1e, 0x90, 0x8b, 0xfb, 0x3a, 0xfb, 0x73, 0x47, 0xf7, 0x73, 0x05, + 0xb5, 0x8c, 0xa8, 0xa3, 0x8b, 0xaf, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, + 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x31, 0x06, 0x6c, 0x8b, 0x82, + 0x88, 0x7c, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x73, 0x98, + 0x7f, 0xa6, 0x87, 0x08, 0xf0, 0xfb, 0xe2, 0x05, 0x0e, 0xf7, 0x9d, 0xef, + 0x15, 0xf7, 0xd1, 0xf7, 0x94, 0x9c, 0xdc, 0xfc, 0x2d, 0x8b, 0x74, 0xfb, + 0x01, 0x05, 0x89, 0x82, 0x89, 0x7d, 0x8b, 0x85, 0x8b, 0x76, 0x9c, 0x7b, + 0xa2, 0x8b, 0x9b, 0x8b, 0x9b, 0x93, 0x98, 0x98, 0x95, 0x95, 0x8e, 0x93, + 0x91, 0xa6, 0x08, 0x8d, 0x94, 0xf7, 0x28, 0x8b, 0xfb, 0xce, 0xfb, 0x92, + 0x79, 0x38, 0xf8, 0x46, 0x8b, 0x9e, 0xe3, 0x05, 0x8e, 0x9a, 0x8c, 0x92, + 0x8b, 0x92, 0x8b, 0xa0, 0x7a, 0x9b, 0x74, 0x8b, 0x6d, 0x8b, 0x76, 0x78, + 0x81, 0x68, 0x08, 0xfb, 0x44, 0x06, 0x0e, 0xf8, 0x57, 0xf8, 0x79, 0x15, + 0x92, 0xa7, 0x95, 0x94, 0xa6, 0x8b, 0xad, 0x8e, 0xa6, 0xa6, 0x8b, 0xaa, + 0x8b, 0xa4, 0x7a, 0x9a, 0x6f, 0x8b, 0x44, 0x8b, 0x43, 0x4f, 0x7c, 0x44, + 0x08, 0x68, 0xfb, 0x38, 0x05, 0x85, 0x6f, 0x83, 0x84, 0x71, 0x88, 0x65, + 0x87, 0x74, 0x73, 0x8b, 0x68, 0x8b, 0x74, 0x97, 0x7f, 0xa6, 0x88, 0x9f, + 0x89, 0x92, 0x85, 0x8b, 0x7f, 0x8b, 0x87, 0x8a, 0x84, 0x89, 0x84, 0x08, + 0x67, 0xfb, 0x41, 0x05, 0x89, 0x82, 0x8a, 0x83, 0x8b, 0x82, 0x08, 0x4f, + 0xb8, 0x5e, 0xc6, 0xb1, 0xa9, 0xa6, 0xae, 0x1e, 0x8b, 0xa1, 0x7c, 0x9a, + 0x72, 0x8d, 0x73, 0x8c, 0x85, 0x90, 0x8b, 0x9b, 0x8b, 0x8e, 0x8c, 0x91, + 0x8c, 0x91, 0x08, 0xac, 0xf7, 0x31, 0x05, 0x90, 0xa1, 0x8e, 0x9f, 0x8b, + 0x95, 0x8b, 0x9a, 0x86, 0x98, 0x80, 0x9d, 0xa7, 0xa5, 0x95, 0x9d, 0x95, + 0xb7, 0x08, 0xac, 0xf7, 0x31, 0x05, 0x0e, 0xf8, 0x68, 0xf8, 0xc0, 0x15, + 0x8e, 0x99, 0x8c, 0x93, 0x8b, 0x91, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, + 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7e, 0x82, 0x82, 0x86, 0x80, 0x86, 0x72, + 0x08, 0xfb, 0x1d, 0xfd, 0x17, 0x05, 0x88, 0x7e, 0x8a, 0x82, 0x8b, 0x84, + 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, 0x9b, 0x93, 0x98, 0x98, + 0x95, 0x95, 0x8f, 0x94, 0x90, 0xa5, 0x08, 0xf7, 0x1d, 0xf9, 0x17, 0x05, + 0x0e, 0xf7, 0x8d, 0x7c, 0x15, 0x84, 0x6f, 0x81, 0x82, 0x70, 0x8b, 0x69, + 0x88, 0x70, 0x70, 0x8b, 0x6c, 0x8b, 0x72, 0x9c, 0x7c, 0xa7, 0x8b, 0xd2, + 0x8b, 0xd3, 0xc7, 0x9a, 0xd2, 0x08, 0xae, 0xf7, 0x38, 0x05, 0x91, 0xa6, + 0x93, 0x93, 0xa5, 0x8e, 0xb1, 0x8f, 0xa2, 0xa3, 0x8b, 0xae, 0x8b, 0xa2, + 0x7f, 0x97, 0x70, 0x8e, 0x77, 0x8d, 0x84, 0x91, 0x8b, 0x97, 0x8b, 0x8f, + 0x8c, 0x92, 0x8d, 0x92, 0x08, 0xaf, 0xf7, 0x41, 0x05, 0x8d, 0x94, 0x8c, + 0x93, 0x8b, 0x94, 0x08, 0xc7, 0x5e, 0xb8, 0x50, 0x65, 0x6d, 0x70, 0x69, + 0x1e, 0x8b, 0x74, 0x9a, 0x7c, 0xa4, 0x89, 0xa3, 0x8a, 0x91, 0x86, 0x8b, + 0x7b, 0x8b, 0x88, 0x8a, 0x85, 0x8a, 0x85, 0x08, 0x6a, 0xfb, 0x31, 0x05, + 0x86, 0x75, 0x88, 0x77, 0x8b, 0x81, 0x8b, 0x7c, 0x90, 0x7e, 0x96, 0x79, + 0x6f, 0x71, 0x81, 0x79, 0x81, 0x5f, 0x08, 0x6a, 0xfb, 0x31, 0x05, 0x0e, + 0xf8, 0xc9, 0xf8, 0x00, 0x15, 0x78, 0x8b, 0x7f, 0x84, 0x71, 0x70, 0x6c, + 0x6a, 0x7a, 0x7e, 0x80, 0x8b, 0x83, 0x8b, 0x80, 0x93, 0x7d, 0x9a, 0x08, + 0x54, 0xca, 0x73, 0x9a, 0x61, 0x8b, 0x61, 0x8b, 0x68, 0x79, 0x5a, 0x5e, + 0x62, 0x65, 0x7d, 0x77, 0x8b, 0x73, 0x8b, 0x76, 0x9e, 0x79, 0xa2, 0x8b, + 0x9d, 0x8b, 0x94, 0x91, 0xac, 0xab, 0xad, 0xac, 0x97, 0x94, 0x94, 0x8b, + 0x08, 0x93, 0x8b, 0x97, 0x82, 0x9c, 0x79, 0x08, 0xbb, 0x55, 0xad, 0x76, + 0xb1, 0x8b, 0xb9, 0x8b, 0xab, 0x9d, 0xcc, 0xcc, 0xa4, 0xa5, 0x95, 0x9c, + 0x8b, 0x9e, 0x08, 0xa2, 0x79, 0x9c, 0x74, 0x1e, 0x0e, 0xf7, 0x59, 0xfb, + 0x06, 0x15, 0x83, 0x6f, 0x88, 0x7f, 0x8b, 0x7e, 0x8b, 0x68, 0xa6, 0x72, + 0xb2, 0x8b, 0xa6, 0x8b, 0xa7, 0x98, 0x9e, 0xa1, 0x9d, 0x9e, 0x90, 0x9a, + 0x90, 0xb7, 0x08, 0xad, 0xf7, 0xbd, 0x05, 0x8c, 0x8e, 0x8b, 0x8e, 0x8b, + 0x8d, 0x8b, 0xa5, 0x7c, 0x9a, 0x72, 0x8b, 0x6f, 0x8b, 0x75, 0x79, 0x81, + 0x6c, 0x08, 0x2f, 0xfb, 0xbd, 0x05, 0xf7, 0x4d, 0xf8, 0xb0, 0x15, 0x60, + 0x64, 0x64, 0x62, 0x6d, 0xa1, 0x75, 0xaa, 0x1f, 0x9d, 0x06, 0xb5, 0xb3, + 0xb2, 0xb3, 0xaa, 0x75, 0xa1, 0x6b, 0x1f, 0x7a, 0x06, 0x0e, 0xf8, 0x08, + 0xee, 0x15, 0xef, 0x9c, 0xd0, 0xb5, 0x8b, 0xb9, 0x8b, 0xa2, 0x79, 0x9d, + 0x75, 0x8b, 0x7e, 0x8b, 0x81, 0x88, 0x7d, 0x82, 0x64, 0x73, 0x66, 0x7f, + 0x66, 0x8b, 0x08, 0x4e, 0x5f, 0xb1, 0xc0, 0xd6, 0xd7, 0xcb, 0xe3, 0x1f, + 0xb9, 0x8b, 0x9f, 0x7e, 0x8c, 0x6d, 0x8c, 0x6f, 0x8b, 0x89, 0x91, 0x84, + 0x91, 0x83, 0x99, 0x85, 0x97, 0x8b, 0x9a, 0x8b, 0x9d, 0x93, 0x97, 0x98, + 0x95, 0x95, 0x8e, 0x94, 0x91, 0xa5, 0x08, 0x94, 0xb5, 0x05, 0x8e, 0x9a, + 0x8c, 0x92, 0x8b, 0x91, 0x8b, 0xa1, 0x7a, 0x9b, 0x73, 0x8b, 0x85, 0x8b, + 0x85, 0x8a, 0x82, 0x88, 0x7a, 0x97, 0x76, 0x93, 0x6d, 0x8f, 0x08, 0x99, + 0xce, 0x05, 0x90, 0x9f, 0x8b, 0x8d, 0x8b, 0x92, 0x8b, 0xa1, 0x7a, 0x9b, + 0x74, 0x8b, 0x7b, 0x8b, 0x7b, 0x84, 0x7e, 0x7d, 0x81, 0x82, 0x87, 0x81, + 0x85, 0x70, 0x08, 0x7b, 0x3e, 0x05, 0xfb, 0x10, 0x6f, 0x2e, 0xfb, 0x01, + 0x8b, 0xfb, 0x07, 0x8b, 0x39, 0xba, 0x50, 0xdd, 0x76, 0x08, 0x79, 0x3a, + 0x05, 0x87, 0x77, 0x8b, 0x8a, 0x8b, 0x83, 0x8b, 0x77, 0x9d, 0x7a, 0xa1, + 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8f, 0x93, 0x91, + 0xa6, 0x08, 0x9b, 0xd8, 0x05, 0x0e, 0xf8, 0x02, 0xf7, 0x87, 0x15, 0xa9, + 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, + 0x9c, 0x82, 0x99, 0x7e, 0x90, 0x82, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, + 0x47, 0x8b, 0x8a, 0x97, 0x05, 0x89, 0xa2, 0x8a, 0xa0, 0x8b, 0x95, 0x8b, + 0xc0, 0xaf, 0xaf, 0xc0, 0x8b, 0xa5, 0x8b, 0x9e, 0x83, 0x97, 0x79, 0x9d, + 0x72, 0x8f, 0x88, 0x9d, 0x8b, 0x08, 0xaa, 0xaa, 0xa9, 0xaa, 0xbb, 0x49, + 0xb8, 0x43, 0xfb, 0x0b, 0x2d, 0x2d, 0xfb, 0x0b, 0x1f, 0x8b, 0x7e, 0x8c, + 0x80, 0x8e, 0x79, 0x08, 0x5f, 0x06, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7e, + 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7a, 0x94, 0x7d, 0x98, 0x86, + 0x94, 0x88, 0x93, 0x8a, 0x9d, 0x8b, 0x08, 0xd0, 0x06, 0x7c, 0x34, 0x69, + 0x57, 0x5f, 0x87, 0x61, 0x83, 0x77, 0x77, 0x8b, 0x6b, 0x08, 0x6e, 0x9b, + 0x80, 0xb4, 0x1e, 0xf7, 0xd5, 0x06, 0xb8, 0x8b, 0xa7, 0x95, 0xa3, 0xa3, + 0x9e, 0x9e, 0x98, 0xa9, 0x8b, 0xa4, 0x8b, 0xa2, 0x7a, 0x9a, 0x73, 0x8b, + 0x6e, 0x8b, 0x78, 0x7b, 0x80, 0x6d, 0x08, 0xfb, 0x60, 0x06, 0xa9, 0xbb, + 0x97, 0xab, 0x96, 0xca, 0x08, 0xb9, 0x06, 0x0e, 0xf9, 0x08, 0xf8, 0x22, + 0x15, 0xaf, 0xa0, 0x97, 0x9a, 0x8b, 0xa5, 0x8b, 0xa1, 0x79, 0x9d, 0x76, + 0x8b, 0x7e, 0x8b, 0x82, 0x88, 0x73, 0x7d, 0x08, 0xfc, 0x7e, 0xfb, 0xab, + 0x05, 0x65, 0x76, 0x80, 0x7d, 0x8b, 0x71, 0x8b, 0x75, 0x9d, 0x78, 0xa0, + 0x8b, 0x96, 0x8b, 0x99, 0x90, 0xa0, 0x97, 0x08, 0xf8, 0x7f, 0xf7, 0xab, + 0x05, 0x0e, 0xf8, 0x0b, 0xf7, 0xf0, 0x15, 0x4a, 0xf7, 0x19, 0x05, 0xa7, + 0x91, 0xa1, 0xa5, 0x8b, 0xa7, 0x8b, 0x9a, 0x82, 0x9a, 0x7e, 0x90, 0x82, + 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0x2f, 0x06, 0x6b, 0x8b, 0x83, 0x89, + 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x71, 0x9c, 0x7d, + 0xaa, 0x1e, 0x93, 0x8b, 0xeb, 0xfb, 0x5b, 0x43, 0x8b, 0x05, 0x75, 0x7c, + 0x7d, 0x77, 0x7b, 0x92, 0x85, 0x9d, 0x1f, 0xec, 0x8b, 0x84, 0x69, 0x2a, + 0x8b, 0x05, 0x74, 0x7c, 0x7d, 0x77, 0x7b, 0x92, 0x85, 0x9e, 0x1f, 0xec, + 0x8b, 0x84, 0x68, 0x5c, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xf7, 0x55, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x99, 0x7e, 0x90, 0x82, 0x8f, 0x87, + 0x8b, 0x75, 0x8b, 0x08, 0x5d, 0x8b, 0x92, 0xae, 0xec, 0x8b, 0x05, 0xa2, + 0x9a, 0x99, 0xa0, 0x9a, 0x84, 0x91, 0x78, 0x1f, 0x2a, 0x8b, 0x92, 0xad, + 0xec, 0x8b, 0x05, 0xa1, 0x9b, 0x99, 0x9f, 0x9b, 0x84, 0x91, 0x78, 0x1f, + 0x43, 0x8b, 0xf7, 0x49, 0xf7, 0x5b, 0x8d, 0x8b, 0x05, 0xa5, 0x8b, 0x97, + 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, + 0x9a, 0x7e, 0x8f, 0x82, 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0x30, 0x06, + 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, + 0x8b, 0x77, 0x95, 0x7e, 0xa0, 0x85, 0x08, 0xfb, 0x0f, 0xfb, 0x19, 0x05, + 0x0e, 0xf8, 0x4c, 0xf8, 0x28, 0x15, 0x96, 0xbf, 0x05, 0x95, 0xb8, 0xb3, + 0xb0, 0xb4, 0x8b, 0x9c, 0x8b, 0x9a, 0x88, 0x9a, 0x85, 0x96, 0x87, 0x90, + 0x8a, 0x92, 0x8b, 0x08, 0xa9, 0xa9, 0xaa, 0xab, 0xaa, 0x62, 0x9f, 0x4a, + 0x1f, 0x29, 0x8b, 0x2c, 0x3c, 0x76, 0x27, 0x08, 0x7f, 0x54, 0x52, 0x8b, + 0x05, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xc5, 0x8b, 0x58, 0xfb, 0x82, + 0x05, 0x80, 0x56, 0x63, 0x67, 0x5e, 0x8b, 0x7a, 0x8b, 0x7c, 0x8e, 0x7c, + 0x90, 0x7f, 0x90, 0x87, 0x8c, 0x86, 0x8b, 0x08, 0x6c, 0x6d, 0x6d, 0x6c, + 0x6b, 0xb5, 0x76, 0xcc, 0x1f, 0xf1, 0x8b, 0xe8, 0xdc, 0xa2, 0xf7, 0x00, + 0x08, 0xbe, 0xf7, 0x82, 0xc4, 0x8b, 0x05, 0xa9, 0x8b, 0x96, 0x8e, 0x9a, + 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7d, + 0x8f, 0x83, 0x8f, 0x87, 0x8b, 0x74, 0x8b, 0x08, 0x52, 0x06, 0x0e, 0xf8, + 0xac, 0xf8, 0x81, 0x15, 0x83, 0x66, 0x05, 0x89, 0x84, 0x8a, 0x7f, 0x8b, + 0x86, 0x8b, 0x7a, 0x9b, 0x7d, 0x9e, 0x8b, 0xaa, 0x8b, 0x9c, 0x9c, 0x93, + 0xb1, 0x08, 0xa6, 0xf7, 0x13, 0xfb, 0x75, 0x8b, 0x05, 0x4f, 0x8b, 0x5c, + 0x77, 0x62, 0x5e, 0x70, 0x6d, 0x76, 0x5f, 0x8b, 0x6e, 0x8b, 0x87, 0x8b, + 0x88, 0x8c, 0x85, 0x3c, 0x77, 0x58, 0x52, 0x8b, 0x49, 0x8b, 0x5f, 0xa9, + 0x66, 0xd6, 0x5b, 0x08, 0xe8, 0x4e, 0x05, 0xc1, 0x68, 0xaa, 0x6b, 0x8b, + 0x74, 0x08, 0x6c, 0x64, 0x6d, 0x63, 0x1e, 0xfb, 0x25, 0x8b, 0x93, 0xb2, + 0x05, 0x8f, 0x9b, 0x8b, 0x8c, 0x8b, 0x91, 0x8b, 0x9d, 0x7c, 0x99, 0x76, + 0x8b, 0x6d, 0x8b, 0x79, 0x79, 0x83, 0x66, 0x08, 0x70, 0xfb, 0x13, 0xf7, + 0x7b, 0x8b, 0x05, 0xd3, 0x8b, 0xc5, 0xac, 0xb1, 0xcb, 0x98, 0xa1, 0x93, + 0xa7, 0x8b, 0xa5, 0x8b, 0x8c, 0x8b, 0x8e, 0x8a, 0x8e, 0xd9, 0x9c, 0xbf, + 0xc5, 0x8b, 0xd0, 0x8b, 0xbd, 0x72, 0xa8, 0x30, 0xc5, 0x08, 0x3a, 0xbe, + 0x05, 0x52, 0xb0, 0x6d, 0xaa, 0x8b, 0xa2, 0x08, 0xaa, 0xb3, 0xa8, 0xb5, + 0x1e, 0xf7, 0x24, 0x06, 0xfb, 0xa7, 0xfb, 0x3b, 0x15, 0xa9, 0x6e, 0x94, + 0x84, 0xa8, 0x78, 0x08, 0xe3, 0x52, 0x05, 0xbc, 0x6a, 0xa7, 0x6c, 0x8b, + 0x73, 0x8b, 0x77, 0x75, 0x7a, 0x6e, 0x8a, 0x08, 0x81, 0x8b, 0x83, 0x8b, + 0x05, 0x7e, 0x9a, 0x7d, 0x96, 0x5d, 0xac, 0x08, 0x31, 0xc5, 0x05, 0x5a, + 0xab, 0x77, 0xa2, 0x8b, 0xa3, 0x8b, 0xa2, 0xa3, 0x9d, 0xa9, 0x8c, 0x08, + 0x96, 0x8b, 0x8e, 0x8b, 0x05, 0x0e, 0xf7, 0x69, 0xf8, 0x18, 0x15, 0x6b, + 0x5f, 0x79, 0x5c, 0x8b, 0x64, 0x8b, 0x7c, 0x8e, 0x75, 0x92, 0x72, 0x08, + 0x63, 0x69, 0x05, 0x6e, 0x72, 0x83, 0x7f, 0x8b, 0x77, 0x8b, 0x73, 0x9d, + 0x7a, 0xa2, 0x8b, 0x9d, 0x8b, 0x92, 0x8f, 0xa7, 0xa2, 0x08, 0xb2, 0xab, + 0x05, 0xac, 0x77, 0xa2, 0x85, 0xae, 0x8b, 0xae, 0x8b, 0xa4, 0x91, 0xb4, + 0x9e, 0x08, 0xa6, 0x6b, 0x05, 0x9c, 0x76, 0x92, 0x86, 0x9b, 0x8b, 0xab, + 0x8b, 0xac, 0xaa, 0x8b, 0xa8, 0x8b, 0x97, 0x87, 0x93, 0x7d, 0x9d, 0x08, + 0x72, 0xad, 0x05, 0xac, 0xb7, 0x9d, 0xb9, 0x8b, 0xb3, 0x8b, 0x9a, 0x88, + 0xa1, 0x84, 0xa4, 0x08, 0xb1, 0xab, 0x05, 0xa8, 0xa3, 0x93, 0x97, 0x8b, + 0x9f, 0x8b, 0xa3, 0x7a, 0x9c, 0x73, 0x8b, 0x7a, 0x8b, 0x82, 0x87, 0x70, + 0x75, 0x08, 0x66, 0x6d, 0x05, 0x6a, 0xa0, 0x75, 0x91, 0x66, 0x8b, 0x68, + 0x8b, 0x71, 0x84, 0x62, 0x78, 0x08, 0x71, 0xaa, 0x05, 0x79, 0xa1, 0x85, + 0x8f, 0x7a, 0x8b, 0x6d, 0x8b, 0x6a, 0x6d, 0x8b, 0x6f, 0x8b, 0x84, 0x95, + 0x71, 0x92, 0x83, 0x08, 0xa4, 0x6b, 0x05, 0xf7, 0x3d, 0x16, 0xb8, 0xab, + 0x6c, 0x5f, 0x50, 0x51, 0x52, 0x4f, 0x60, 0x6b, 0xac, 0xb6, 0xc6, 0xc3, + 0xc3, 0xc7, 0x1f, 0x0e, 0xf8, 0x00, 0xf8, 0xee, 0x15, 0x77, 0xfb, 0x93, + 0x05, 0x8a, 0x86, 0x8b, 0x86, 0x8b, 0x89, 0x8b, 0x7e, 0x95, 0x81, 0x99, + 0x8b, 0x9f, 0x8b, 0x96, 0x95, 0x94, 0xa5, 0x08, 0xe0, 0xf7, 0x92, 0xfb, + 0x14, 0x8b, 0x05, 0x0e, 0xf8, 0xc2, 0xf8, 0xee, 0x15, 0xfb, 0x18, 0x8b, + 0xe7, 0xfb, 0x7a, 0x05, 0x93, 0x79, 0x91, 0x85, 0x98, 0x8b, 0x08, 0xa0, + 0x9c, 0x9c, 0xa1, 0x1f, 0x8b, 0x93, 0x72, 0xf7, 0x63, 0x05, 0xfb, 0x5c, + 0x16, 0xfb, 0x18, 0x8b, 0xe7, 0xfb, 0x7a, 0x05, 0x93, 0x79, 0x91, 0x85, + 0x98, 0x8b, 0x08, 0xa0, 0x9c, 0x9c, 0xa1, 0x1f, 0x8b, 0x93, 0x72, 0xf7, + 0x63, 0x05, 0x0e, 0xf7, 0x72, 0xf7, 0x6e, 0x15, 0xf7, 0x49, 0xf7, 0x20, + 0x05, 0x9b, 0x97, 0x91, 0x95, 0x8b, 0x96, 0x8b, 0x99, 0x80, 0x95, 0x7b, + 0x8b, 0x82, 0x8b, 0x86, 0x89, 0x7a, 0x80, 0x08, 0xfb, 0xb3, 0xfb, 0x4c, + 0xf7, 0x65, 0xfb, 0x4d, 0x05, 0x97, 0x80, 0x8f, 0x89, 0x94, 0x8b, 0x9f, + 0x8b, 0x9f, 0x9d, 0x8b, 0x9c, 0x8b, 0x90, 0x87, 0x95, 0x84, 0x92, 0x08, + 0xfb, 0x0d, 0xf7, 0x21, 0x05, 0xf7, 0x79, 0x16, 0xf7, 0x49, 0xf7, 0x20, + 0x05, 0x9b, 0x97, 0x91, 0x95, 0x8b, 0x96, 0x8b, 0x99, 0x80, 0x95, 0x7b, + 0x8b, 0x82, 0x8b, 0x86, 0x89, 0x7a, 0x80, 0x08, 0xfb, 0xb3, 0xfb, 0x4c, + 0xf7, 0x65, 0xfb, 0x4d, 0x05, 0x97, 0x80, 0x8f, 0x89, 0x94, 0x8b, 0x9f, + 0x8b, 0x9f, 0x9d, 0x8b, 0x9b, 0x8b, 0x92, 0x87, 0x93, 0x84, 0x93, 0x08, + 0xfb, 0x0d, 0xf7, 0x21, 0x05, 0x0e, 0xf7, 0x72, 0xf7, 0x6e, 0x15, 0xf7, + 0x49, 0xf7, 0x20, 0x05, 0x9b, 0x97, 0x91, 0x95, 0x8b, 0x96, 0x8b, 0x99, + 0x80, 0x95, 0x7b, 0x8b, 0x82, 0x8b, 0x86, 0x89, 0x7a, 0x80, 0x08, 0xfb, + 0xb3, 0xfb, 0x4c, 0xf7, 0x65, 0xfb, 0x4d, 0x05, 0x97, 0x80, 0x8f, 0x89, + 0x94, 0x8b, 0x9f, 0x8b, 0x9f, 0x9d, 0x8b, 0x9c, 0x8b, 0x91, 0x87, 0x93, + 0x84, 0x93, 0x08, 0xfb, 0x0d, 0xf7, 0x21, 0x05, 0x0e, 0xf8, 0x70, 0xf7, + 0x6d, 0x15, 0xfb, 0x49, 0xfb, 0x20, 0x05, 0x7b, 0x7f, 0x85, 0x81, 0x8b, + 0x80, 0x8b, 0x7d, 0x96, 0x81, 0x9b, 0x8b, 0x94, 0x8b, 0x90, 0x8d, 0x9c, + 0x96, 0x08, 0xf7, 0xb2, 0xf7, 0x4c, 0xfb, 0x64, 0xf7, 0x4d, 0x05, 0x7f, + 0x96, 0x87, 0x8d, 0x82, 0x8b, 0x77, 0x8b, 0x77, 0x79, 0x8b, 0x7a, 0x8b, + 0x85, 0x8f, 0x83, 0x92, 0x83, 0x08, 0xf7, 0x0d, 0xfb, 0x21, 0x05, 0x0e, + 0xf7, 0x9f, 0xf7, 0xe5, 0x15, 0xac, 0x06, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, + 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x6a, 0x8b, 0x94, 0xb2, + 0x05, 0x90, 0xa6, 0xa2, 0xa0, 0xa0, 0x8b, 0x95, 0x8b, 0x97, 0x88, 0x9a, + 0x85, 0x9b, 0x85, 0x8f, 0x8a, 0x93, 0x8b, 0x08, 0xaa, 0xa9, 0xa9, 0xab, + 0xaa, 0x5f, 0xa1, 0x4d, 0x1f, 0x3d, 0x8b, 0x41, 0x4c, 0x7a, 0x37, 0x08, + 0x82, 0x64, 0x65, 0x8b, 0x05, 0x6b, 0x8b, 0x82, 0x89, 0x7d, 0x7f, 0x7c, + 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x7b, 0x94, 0x7c, 0x99, 0x86, 0x93, + 0x88, 0x93, 0x8a, 0x9e, 0x8b, 0x08, 0xb1, 0x8b, 0x59, 0xfb, 0x81, 0x60, + 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, + 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x43, 0x06, 0xa7, + 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x76, 0x8b, 0x08, + 0x6b, 0x8b, 0x05, 0xbd, 0xf7, 0x81, 0x05, 0xf7, 0xeb, 0xef, 0x15, 0xfb, + 0x0b, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0x9f, 0x8b, 0x59, 0xfb, + 0x81, 0x64, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, + 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x43, + 0x06, 0xa6, 0x8b, 0x99, 0x8f, 0x98, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, + 0x8b, 0x08, 0x67, 0x8b, 0xd2, 0xf7, 0xe5, 0x05, 0xa2, 0xf7, 0x4f, 0x15, + 0xfb, 0x0a, 0x8b, 0x75, 0x22, 0xf7, 0x0a, 0x8b, 0x05, 0xa1, 0xf4, 0x05, + 0x0e, 0xf7, 0x9b, 0xf7, 0xe5, 0x15, 0xac, 0x06, 0xa9, 0x8b, 0x95, 0x8e, + 0x9a, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, 0x9b, + 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x6a, 0x8b, 0x93, + 0xb1, 0x05, 0x92, 0xa8, 0x9e, 0x9e, 0xa3, 0x8b, 0x96, 0x8b, 0x93, 0x89, + 0xa1, 0x84, 0x97, 0x87, 0x93, 0x89, 0x92, 0x8b, 0x9c, 0x8b, 0x9a, 0x94, + 0x9a, 0x9d, 0x95, 0x82, 0x93, 0x88, 0x99, 0x8b, 0x08, 0xae, 0x8b, 0x31, + 0xfc, 0x3b, 0x65, 0x8b, 0x05, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, + 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9c, 0x7f, 0xb3, 0x1e, 0xf7, + 0x44, 0x06, 0xa7, 0x8b, 0x99, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, + 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, + 0x76, 0x8b, 0x08, 0x66, 0x8b, 0xf7, 0x03, 0xf8, 0x9f, 0xfb, 0x16, 0x8b, + 0x05, 0x72, 0x8b, 0x7c, 0x84, 0x7c, 0x76, 0x73, 0x9c, 0x65, 0x96, 0x65, + 0x8b, 0x3f, 0x8b, 0x41, 0x4a, 0x79, 0x38, 0x08, 0x83, 0x65, 0x66, 0x8b, + 0x05, 0x6b, 0x8b, 0x82, 0x89, 0x7d, 0x7e, 0x7c, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x8b, 0x7b, 0x95, 0x7c, 0x98, 0x86, 0x93, 0x88, 0x93, 0x8a, 0x9e, + 0x8b, 0x08, 0xb0, 0x8b, 0x59, 0xfb, 0x81, 0x60, 0x8b, 0x05, 0x6b, 0x8b, + 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x44, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, + 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, + 0x8f, 0x84, 0x8e, 0x82, 0x8c, 0x78, 0x8b, 0x08, 0x6b, 0x8b, 0xbd, 0xf7, + 0x81, 0x05, 0x0e, 0xf8, 0xb1, 0xf7, 0x79, 0x15, 0xa8, 0x8b, 0x97, 0x8e, + 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, + 0x7f, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x78, 0x8b, 0x08, 0xfc, 0x13, 0x06, + 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf8, 0x13, 0x06, 0x0e, 0xf8, 0x39, + 0xf7, 0xe5, 0x15, 0xe4, 0x06, 0xaa, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, + 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x82, + 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x32, 0x8b, 0xa4, 0xf7, 0x0b, 0x05, + 0x8e, 0x9b, 0x8c, 0x90, 0x8b, 0x92, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, + 0x7b, 0x8b, 0x7b, 0x83, 0x7e, 0x7f, 0x82, 0x81, 0x86, 0x81, 0x86, 0x71, + 0x08, 0x72, 0xfb, 0x0b, 0x31, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x88, 0x7c, + 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x7b, 0x94, 0x7b, 0x98, + 0x87, 0x93, 0x88, 0x93, 0x8a, 0x9d, 0x8b, 0x08, 0xe5, 0x8b, 0x3e, 0xfb, + 0xff, 0x05, 0x88, 0x7b, 0x8a, 0x85, 0x8b, 0x84, 0x8b, 0x76, 0x9d, 0x7b, + 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8f, 0x93, + 0x90, 0xa6, 0x08, 0xd8, 0xf7, 0xff, 0x05, 0x0e, 0xf8, 0x39, 0xf7, 0xe5, + 0x15, 0xe4, 0x06, 0xaa, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x82, 0x8e, 0x85, + 0x8c, 0x77, 0x8b, 0x08, 0x31, 0x8b, 0xa5, 0xf7, 0x0b, 0x05, 0x8e, 0x9b, + 0x8c, 0x90, 0x8b, 0x92, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, 0x7b, 0x8b, + 0x7b, 0x83, 0x7e, 0x7f, 0x81, 0x81, 0x87, 0x81, 0x86, 0x71, 0x08, 0x72, + 0xfb, 0x0b, 0x30, 0x8b, 0x05, 0x6d, 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, + 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x7b, 0x94, 0x7b, 0x98, 0x87, 0x93, + 0x88, 0x93, 0x8a, 0x9d, 0x8b, 0x08, 0xe5, 0x8b, 0x6d, 0xfb, 0x24, 0x30, + 0x8b, 0x05, 0x6e, 0x8b, 0x80, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, + 0x8b, 0x7b, 0x8b, 0x7a, 0x94, 0x7c, 0x98, 0x87, 0x93, 0x88, 0x91, 0x8a, + 0x9f, 0x8b, 0x08, 0xe5, 0x8b, 0x72, 0xfb, 0x0b, 0x05, 0x88, 0x7d, 0x8a, + 0x83, 0x8b, 0x84, 0x8b, 0x76, 0x9d, 0x7b, 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, + 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0xa4, 0xf7, + 0x0b, 0xe5, 0x8b, 0x05, 0xaa, 0x8b, 0x94, 0x8e, 0x9a, 0x96, 0x99, 0x97, + 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, + 0x82, 0x8c, 0x79, 0x8b, 0x08, 0x32, 0x8b, 0xa9, 0xf7, 0x24, 0x05, 0x0e, + 0xf7, 0xf6, 0xf7, 0x6a, 0x15, 0xb5, 0xb3, 0xb2, 0xb4, 0xa9, 0x75, 0xa1, + 0x6b, 0x1f, 0x7a, 0x06, 0x61, 0x63, 0x64, 0x63, 0x6c, 0xa1, 0x75, 0xab, + 0x1f, 0x9c, 0x06, 0x0e, 0xf8, 0xd3, 0xf8, 0x8d, 0x15, 0xae, 0x06, 0xa0, + 0x8b, 0x91, 0x8c, 0x93, 0x90, 0x9c, 0x94, 0x95, 0x9b, 0x8b, 0x9b, 0x08, + 0xa1, 0x7e, 0x94, 0x6a, 0x1e, 0xfb, 0x59, 0x06, 0xfb, 0x22, 0x8b, 0xfb, + 0x17, 0x3c, 0x76, 0x2a, 0x08, 0x82, 0x5d, 0x05, 0x89, 0x83, 0x8a, 0x83, + 0x8b, 0x80, 0x8b, 0x3d, 0xd5, 0x50, 0xf7, 0x04, 0x7f, 0x08, 0x4f, 0xfb, + 0xad, 0x3d, 0x8b, 0x05, 0x76, 0x8b, 0x85, 0x8a, 0x82, 0x86, 0x7b, 0x83, + 0x80, 0x79, 0x8b, 0x7c, 0x08, 0x75, 0x98, 0x82, 0xac, 0x1e, 0xf7, 0x1d, + 0x06, 0xa3, 0x8b, 0x93, 0x90, 0x9d, 0xa8, 0x8f, 0x72, 0x93, 0x82, 0xa0, + 0x8b, 0x08, 0xe8, 0x06, 0x9f, 0x8b, 0x93, 0x8c, 0x93, 0x90, 0x9b, 0x94, + 0x95, 0x9b, 0x8b, 0x9b, 0x08, 0xa2, 0x7f, 0x93, 0x6a, 0x1e, 0x66, 0x8b, + 0xf7, 0x14, 0xf8, 0xed, 0x05, 0xfb, 0x8d, 0xfb, 0x83, 0x15, 0x52, 0x98, + 0x6b, 0xa8, 0x8b, 0xb2, 0x8b, 0x8f, 0x8c, 0x90, 0x8c, 0x90, 0x08, 0x94, + 0xb7, 0x05, 0x94, 0xb7, 0xc0, 0xb2, 0xcd, 0x97, 0x08, 0x59, 0xfb, 0x7e, + 0x05, 0xf7, 0x41, 0xf7, 0x83, 0x15, 0xfb, 0x14, 0xfc, 0xed, 0x05, 0x7f, + 0x85, 0x84, 0x84, 0x83, 0x7c, 0x8a, 0x9b, 0x87, 0x91, 0x7f, 0x91, 0x08, + 0xf7, 0x14, 0xf8, 0xed, 0xb7, 0x8b, 0x05, 0x0e, 0xf8, 0x1f, 0xf8, 0x59, + 0x15, 0x2d, 0x31, 0x33, 0x2f, 0x46, 0xbd, 0x59, 0xd1, 0xeb, 0xe5, 0xe3, + 0xe7, 0xd1, 0x59, 0xbc, 0x43, 0x1f, 0x0e, 0xf7, 0x8a, 0xf7, 0x1a, 0x15, + 0xfb, 0x0c, 0xfb, 0x89, 0x05, 0x84, 0x7d, 0x8a, 0x87, 0x8b, 0x84, 0x8b, + 0x7f, 0x97, 0x81, 0x99, 0x8b, 0x97, 0x8b, 0x98, 0x93, 0x97, 0x9b, 0x08, + 0xf7, 0x5a, 0xf7, 0xa0, 0xfb, 0x19, 0x8b, 0x05, 0x0e, 0xf7, 0x4e, 0xf7, + 0x1a, 0x15, 0xfb, 0x04, 0xfb, 0x63, 0x05, 0x86, 0x82, 0x88, 0x81, 0x8b, + 0x85, 0x8b, 0x7f, 0x97, 0x81, 0x98, 0x8b, 0x98, 0x8b, 0x95, 0x91, 0x9a, + 0x9d, 0x08, 0xf7, 0x52, 0xf7, 0x7a, 0xfb, 0x19, 0x8b, 0x05, 0xf7, 0x5d, + 0x16, 0xfb, 0x05, 0xfb, 0x63, 0x05, 0x86, 0x82, 0x88, 0x81, 0x8b, 0x85, + 0x8b, 0x7f, 0x97, 0x81, 0x98, 0x8b, 0x99, 0x8b, 0x94, 0x91, 0x9a, 0x9d, + 0x08, 0xf7, 0x52, 0xf7, 0x7a, 0xfb, 0x18, 0x8b, 0x05, 0x0e, 0xf7, 0xb2, + 0xf8, 0xee, 0x15, 0xfb, 0x04, 0xfb, 0x63, 0x05, 0x86, 0x82, 0x88, 0x81, + 0x8b, 0x85, 0x8b, 0x7f, 0x97, 0x81, 0x98, 0x8b, 0x98, 0x8b, 0x95, 0x91, + 0x9a, 0x9d, 0x08, 0xf7, 0x52, 0xf7, 0x7a, 0xfb, 0x19, 0x8b, 0x05, 0xf7, + 0x5d, 0x16, 0xfb, 0x05, 0xfb, 0x63, 0x05, 0x86, 0x82, 0x88, 0x81, 0x8b, + 0x85, 0x8b, 0x7f, 0x97, 0x81, 0x98, 0x8b, 0x99, 0x8b, 0x94, 0x91, 0x9a, + 0x9d, 0x08, 0xf7, 0x52, 0xf7, 0x7a, 0xfb, 0x18, 0x8b, 0x05, 0x0e, 0xf8, + 0x70, 0xf7, 0x6d, 0x15, 0xfb, 0x49, 0xfb, 0x20, 0x05, 0x7b, 0x7f, 0x85, + 0x81, 0x8b, 0x80, 0x8b, 0x7d, 0x96, 0x81, 0x9b, 0x8b, 0x94, 0x8b, 0x90, + 0x8d, 0x9c, 0x96, 0x08, 0xf7, 0xb2, 0xf7, 0x4c, 0xfb, 0x64, 0xf7, 0x4d, + 0x05, 0x7f, 0x96, 0x87, 0x8d, 0x82, 0x8b, 0x77, 0x8b, 0x77, 0x79, 0x8b, + 0x7a, 0x8b, 0x86, 0x8f, 0x81, 0x92, 0x84, 0x08, 0xf7, 0x0d, 0xfb, 0x21, + 0x05, 0xfb, 0x7a, 0x16, 0xfb, 0x49, 0xfb, 0x20, 0x05, 0x7b, 0x7f, 0x85, + 0x81, 0x8b, 0x80, 0x8b, 0x7d, 0x96, 0x81, 0x9b, 0x8b, 0x94, 0x8b, 0x90, + 0x8d, 0x9c, 0x96, 0x08, 0xf7, 0xb2, 0xf7, 0x4c, 0xfb, 0x64, 0xf7, 0x4d, + 0x05, 0x7f, 0x96, 0x87, 0x8d, 0x82, 0x8b, 0x77, 0x8b, 0x77, 0x79, 0x8b, + 0x7b, 0x8b, 0x84, 0x8f, 0x83, 0x92, 0x83, 0x08, 0xf7, 0x0d, 0xfb, 0x21, + 0x05, 0x0e, 0xf4, 0x7c, 0x15, 0xb5, 0xb3, 0xb2, 0xb4, 0xa9, 0x75, 0xa1, + 0x6b, 0x1f, 0x7a, 0x06, 0x61, 0x63, 0x64, 0x63, 0x6c, 0xa1, 0x75, 0xab, + 0x1f, 0x9c, 0x06, 0xf7, 0x5c, 0x16, 0xb5, 0xb3, 0xb2, 0xb4, 0xa9, 0x75, + 0xa1, 0x6b, 0x1f, 0x7a, 0x06, 0x61, 0x63, 0x64, 0x63, 0x6c, 0xa1, 0x75, + 0xab, 0x1f, 0x9c, 0x06, 0xf7, 0x5c, 0x16, 0xb5, 0xb3, 0xb2, 0xb4, 0xa9, + 0x75, 0xa1, 0x6b, 0x1f, 0x7a, 0x06, 0x61, 0x63, 0x64, 0x63, 0x6c, 0xa1, + 0x75, 0xab, 0x1f, 0x9c, 0x06, 0x0e, 0xf8, 0xb9, 0xf8, 0x0d, 0x15, 0xa4, + 0x93, 0x96, 0x96, 0x8b, 0x9e, 0x8b, 0x99, 0x81, 0x96, 0x7f, 0x8b, 0x85, + 0x8b, 0x89, 0x8b, 0x7e, 0x87, 0x08, 0xfc, 0x19, 0xfb, 0x09, 0x05, 0x71, + 0x83, 0x80, 0x80, 0x8b, 0x78, 0x8b, 0x7c, 0x95, 0x80, 0x97, 0x8b, 0x91, + 0x8b, 0x8d, 0x8b, 0x98, 0x8f, 0x08, 0xf8, 0x1a, 0xf7, 0x0a, 0x05, 0xfb, + 0xc2, 0xf7, 0x85, 0x15, 0x42, 0x45, 0x47, 0x43, 0x1f, 0x56, 0xb2, 0x64, + 0xc1, 0xd5, 0xd1, 0xcf, 0xd3, 0xc1, 0x64, 0xb1, 0x54, 0x1e, 0x7f, 0x51, + 0x15, 0xa6, 0x9f, 0x78, 0x70, 0x67, 0x68, 0x69, 0x65, 0x71, 0x77, 0x9f, + 0xa5, 0xaf, 0xae, 0xad, 0xb0, 0x1f, 0xa7, 0xfb, 0xdc, 0x15, 0x42, 0x45, + 0x47, 0x43, 0x56, 0xb2, 0x64, 0xc1, 0xd5, 0xd1, 0xce, 0xd3, 0xc2, 0x64, + 0xb1, 0x54, 0x1f, 0x7f, 0x51, 0x15, 0xa6, 0x9f, 0x78, 0x70, 0x67, 0x68, + 0x69, 0x65, 0x71, 0x77, 0x9f, 0xa5, 0xaf, 0xae, 0xad, 0xb0, 0x1f, 0xf7, + 0xae, 0xc5, 0x15, 0x42, 0x45, 0x47, 0x43, 0x56, 0xb2, 0x64, 0xc1, 0xd5, + 0xd1, 0xce, 0xd3, 0xc2, 0x64, 0xb1, 0x54, 0x1f, 0x7f, 0x51, 0x15, 0xa6, + 0x9f, 0x78, 0x70, 0x67, 0x68, 0x69, 0x65, 0x71, 0x77, 0x9f, 0xa5, 0xaf, + 0xae, 0xad, 0xb0, 0x1f, 0x0e, 0xf8, 0x71, 0x32, 0x15, 0x8e, 0x98, 0x8c, + 0x94, 0x8b, 0x92, 0x8b, 0xa0, 0x7a, 0x9b, 0x74, 0x8b, 0x7c, 0x8b, 0x79, + 0x83, 0x7f, 0x7f, 0x81, 0x80, 0x88, 0x84, 0x85, 0x6f, 0x08, 0x88, 0x7d, + 0x05, 0x67, 0x7b, 0x66, 0x83, 0x65, 0x8b, 0x51, 0x8b, 0x6a, 0xa5, 0x8b, + 0xb7, 0x8b, 0xbe, 0xb5, 0xa7, 0xf7, 0x29, 0xc0, 0x08, 0x97, 0xc3, 0x05, + 0x8f, 0x9e, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0xa0, 0x7a, 0x9c, 0x74, 0x8b, + 0x6e, 0x8b, 0x76, 0x79, 0x7f, 0x67, 0x45, 0x6f, 0x62, 0x74, 0x68, 0x6d, + 0x65, 0x69, 0x74, 0x56, 0x8b, 0x55, 0x8b, 0x2f, 0xcc, 0x53, 0xf6, 0x8b, + 0x08, 0xcd, 0x8b, 0xb6, 0x97, 0xf7, 0x01, 0xba, 0x08, 0x9c, 0xda, 0x05, + 0x20, 0xf8, 0x6f, 0x15, 0x61, 0x64, 0x64, 0x62, 0x6d, 0xa1, 0x75, 0xaa, + 0x1f, 0x9d, 0x06, 0xb5, 0xb3, 0xb2, 0xb3, 0xaa, 0x75, 0xa1, 0x6b, 0x1f, + 0x79, 0x06, 0x0e, 0xf7, 0xe6, 0xf9, 0x3c, 0x15, 0x7f, 0x98, 0x85, 0x8e, + 0x81, 0x8b, 0x73, 0x8b, 0x75, 0x76, 0x8b, 0x74, 0x8b, 0x83, 0x90, 0x81, + 0x96, 0x81, 0x08, 0xf7, 0x02, 0xfb, 0x04, 0x05, 0x97, 0x7f, 0x92, 0x87, + 0x94, 0x8b, 0xa2, 0x8b, 0xa2, 0xa0, 0x8b, 0xa2, 0x8b, 0x94, 0x86, 0x95, + 0x80, 0x95, 0x08, 0xfb, 0x02, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0xdd, 0xf9, + 0x04, 0x15, 0xa1, 0x9a, 0x94, 0x98, 0x8b, 0x9a, 0x8b, 0x9c, 0x7f, 0x97, + 0x79, 0x8b, 0x80, 0x8b, 0x85, 0x88, 0x79, 0x7e, 0x08, 0xfb, 0x32, 0xfb, + 0x03, 0x05, 0x76, 0x7c, 0x81, 0x7e, 0x8b, 0x7c, 0x8b, 0x79, 0x97, 0x7f, + 0x9d, 0x8b, 0x95, 0x8b, 0x92, 0x8e, 0x9d, 0x98, 0x08, 0xf7, 0x32, 0xf7, + 0x04, 0x05, 0x0e, 0xf8, 0x42, 0xf8, 0xf3, 0x15, 0xe7, 0x2a, 0x05, 0x93, + 0x82, 0x93, 0x87, 0x94, 0x8b, 0xa1, 0x8b, 0xa0, 0xa0, 0x8b, 0xa1, 0x8b, + 0x95, 0x8a, 0x8c, 0x7b, 0x9b, 0x08, 0xfb, 0x10, 0xf7, 0x15, 0xfb, 0x48, + 0xfb, 0x15, 0x05, 0x70, 0x78, 0x86, 0x85, 0x8b, 0x7a, 0x8b, 0x7b, 0x97, + 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x94, 0x8f, 0x98, 0x94, 0x08, 0xf7, 0x1a, + 0xec, 0x05, 0x0e, 0xf8, 0xe4, 0xf9, 0x24, 0x15, 0x7f, 0x8b, 0x7c, 0x81, + 0x79, 0x77, 0x6f, 0x6c, 0x86, 0x88, 0x7c, 0x8b, 0x80, 0x8b, 0x7f, 0x91, + 0x6e, 0x9f, 0x08, 0x60, 0xa9, 0x7a, 0x93, 0x75, 0x8b, 0x6e, 0x8b, 0x6b, + 0x7b, 0x6c, 0x6e, 0x70, 0x71, 0x7e, 0x77, 0x8b, 0x7b, 0x8b, 0x7e, 0x96, + 0x81, 0x99, 0x8b, 0x95, 0x8b, 0x94, 0x8f, 0x95, 0x96, 0xb1, 0xb2, 0x94, + 0x92, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x93, 0x87, 0xa2, 0x7a, 0x08, 0xb1, + 0x6f, 0xa9, 0x7c, 0xa1, 0x8b, 0xac, 0x8b, 0xa8, 0x9c, 0xb4, 0xb7, 0x9f, + 0xa1, 0x94, 0x9a, 0x8b, 0x97, 0x08, 0x97, 0x7e, 0x96, 0x7d, 0x1e, 0x0e, + 0xf7, 0xcb, 0xf9, 0x06, 0x15, 0x66, 0x72, 0x78, 0x6f, 0x72, 0x97, 0x83, + 0xac, 0x1f, 0xf7, 0x88, 0x06, 0xaf, 0xa5, 0x9f, 0xa6, 0xa3, 0x7f, 0x94, + 0x6a, 0x1f, 0xfb, 0x88, 0x06, 0x0e, 0xf7, 0xc6, 0xf9, 0x43, 0x15, 0x70, + 0x79, 0x74, 0x69, 0x43, 0xca, 0x54, 0xde, 0x1f, 0xcb, 0x8b, 0xca, 0xa9, + 0xb7, 0xbe, 0xa0, 0xa4, 0x9a, 0xaa, 0x8b, 0x9f, 0x8b, 0x9c, 0x81, 0x95, + 0x7a, 0x8b, 0x77, 0x8b, 0x82, 0x82, 0x7d, 0x6c, 0x78, 0x5d, 0x5a, 0x6d, + 0x54, 0x8b, 0x53, 0x8b, 0x68, 0xaa, 0x8b, 0xbb, 0x08, 0x8c, 0xa6, 0x84, + 0x95, 0x79, 0x8b, 0x08, 0x0e, 0xf8, 0x4b, 0xf9, 0x22, 0x15, 0x65, 0x67, + 0x68, 0x66, 0x70, 0xa0, 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, + 0x9f, 0x6e, 0x1f, 0x0e, 0xf7, 0xe3, 0xf9, 0x22, 0x15, 0x66, 0x66, 0x67, + 0x67, 0x70, 0xa0, 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, + 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x66, 0x66, 0x67, 0x67, 0x70, 0xa0, 0x76, + 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0x0e, 0xf8, + 0x59, 0xf9, 0x6b, 0x15, 0x40, 0x40, 0x44, 0x43, 0x52, 0xb5, 0x62, 0xc4, + 0xd8, 0xd6, 0xd1, 0xd4, 0xc5, 0x61, 0xb3, 0x50, 0x1f, 0x80, 0x56, 0x15, + 0xad, 0xa3, 0x74, 0x6a, 0x64, 0x60, 0x64, 0x60, 0x6a, 0x73, 0xa2, 0xab, + 0xb3, 0xb6, 0xb2, 0xb5, 0x1f, 0x0e, 0xf7, 0x9a, 0x16, 0x75, 0x25, 0x05, + 0x97, 0x8d, 0x90, 0x8b, 0x91, 0x8b, 0x08, 0xa9, 0x9b, 0x81, 0x79, 0x78, + 0x7b, 0x7f, 0x71, 0x1f, 0x7a, 0x8b, 0x76, 0x92, 0x7b, 0x95, 0x7b, 0x95, + 0x89, 0x8c, 0x83, 0x8b, 0x74, 0x8b, 0x76, 0x76, 0x8b, 0x75, 0x8b, 0x7e, + 0x92, 0x82, 0x99, 0x82, 0xa0, 0x7e, 0xb2, 0x80, 0xa6, 0x8b, 0xd3, 0x8b, + 0xc5, 0xc1, 0x8b, 0xce, 0x08, 0x8b, 0xb3, 0x7b, 0x9d, 0x61, 0x94, 0x08, + 0x94, 0xb4, 0x45, 0x8b, 0x05, 0x0e, 0xf8, 0x3b, 0xf9, 0x02, 0x15, 0xa5, + 0xa2, 0x8e, 0x90, 0x8b, 0x9a, 0x8b, 0x9c, 0x7f, 0x97, 0x7c, 0x8b, 0x80, + 0x8b, 0x82, 0x86, 0x7e, 0x81, 0x08, 0xfb, 0x11, 0xfb, 0x02, 0x05, 0x70, + 0x73, 0x88, 0x87, 0x8b, 0x7c, 0x8b, 0x7b, 0x98, 0x7d, 0x9a, 0x8b, 0x94, + 0x8b, 0x97, 0x91, 0x97, 0x95, 0x08, 0xf7, 0x11, 0xf7, 0x02, 0x05, 0xf7, + 0x38, 0x16, 0xa4, 0xa2, 0x8f, 0x90, 0x8b, 0x9a, 0x8b, 0x9b, 0x7f, 0x98, + 0x7c, 0x8b, 0x80, 0x8b, 0x82, 0x87, 0x7f, 0x80, 0x08, 0xfb, 0x12, 0xfb, + 0x02, 0x05, 0x6f, 0x72, 0x89, 0x88, 0x8b, 0x7c, 0x8b, 0x7b, 0x98, 0x7d, + 0x9a, 0x8b, 0x94, 0x8b, 0x98, 0x91, 0x96, 0x95, 0x08, 0xf7, 0x11, 0xf7, + 0x02, 0x05, 0x0e, 0xf7, 0xdd, 0x16, 0x42, 0x62, 0x69, 0x5e, 0x8b, 0x53, + 0x8b, 0x62, 0xa8, 0x72, 0xbb, 0x8b, 0xaf, 0x8b, 0xb9, 0x98, 0xa7, 0x9c, + 0x99, 0x94, 0x95, 0x9b, 0x8b, 0x9a, 0x8b, 0x9d, 0x7e, 0x97, 0x79, 0x8b, + 0x84, 0x8b, 0x85, 0x8a, 0x80, 0x86, 0x08, 0x6c, 0x7d, 0x7f, 0x87, 0x7e, + 0x8b, 0x7f, 0x8b, 0x84, 0x90, 0x8b, 0x95, 0x8b, 0x93, 0x90, 0x97, 0x95, + 0x98, 0x9e, 0xa6, 0xa2, 0x9c, 0xce, 0xb3, 0x08, 0x29, 0x06, 0x0e, 0xf8, + 0x3d, 0xf8, 0xde, 0x15, 0x2e, 0xeb, 0x05, 0x81, 0x96, 0x86, 0x8e, 0x81, + 0x8b, 0x75, 0x8b, 0x76, 0x76, 0x8b, 0x75, 0x8b, 0x81, 0x8c, 0x8a, 0x9b, + 0x7a, 0x08, 0xf7, 0x12, 0xfb, 0x14, 0xf7, 0x46, 0xf7, 0x14, 0x05, 0x8e, + 0x8d, 0x8f, 0x8e, 0x8f, 0x8d, 0x99, 0x96, 0x92, 0x96, 0x8b, 0x98, 0x8b, + 0x9c, 0x7f, 0x97, 0x7b, 0x8b, 0x82, 0x8b, 0x83, 0x87, 0x7d, 0x81, 0x08, + 0xfb, 0x19, 0x2b, 0x05, 0x0e, 0xf8, 0xf8, 0xf7, 0x79, 0x15, 0xa8, 0x8b, + 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, + 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x82, 0x8c, 0x79, 0x8b, 0x08, 0xfc, + 0xa1, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf8, 0xa1, 0x06, 0x0e, + 0xd6, 0xef, 0x15, 0x84, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, + 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xe9, + 0x06, 0xb4, 0xa8, 0xa6, 0xb1, 0x1f, 0x8b, 0x9f, 0x80, 0x97, 0x75, 0x8e, + 0x08, 0xa9, 0xc5, 0xe8, 0x8b, 0x7f, 0x51, 0x82, 0x8b, 0x05, 0x6a, 0x6f, + 0x6f, 0x6c, 0x70, 0x9c, 0x7d, 0xa9, 0x1f, 0xf7, 0xf0, 0x8b, 0xa5, 0xf7, + 0x0f, 0x05, 0x90, 0x9e, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0xa1, 0x7a, 0x9b, + 0x73, 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7f, 0x7e, 0x81, 0x81, 0x87, 0x82, + 0x85, 0x71, 0x08, 0x86, 0x74, 0xfb, 0x26, 0x8b, 0xa9, 0xf7, 0x23, 0x9e, + 0x8b, 0x05, 0x89, 0x81, 0x8b, 0x87, 0x8b, 0x87, 0x8b, 0x76, 0x9c, 0x7a, + 0xa2, 0x8b, 0x9b, 0x8b, 0x9b, 0x93, 0x98, 0x98, 0x95, 0x95, 0x8e, 0x93, + 0x91, 0xa6, 0x08, 0x9b, 0xd9, 0x05, 0x90, 0x9f, 0x8b, 0x8c, 0x8b, 0x93, + 0x8b, 0x9f, 0x79, 0x9c, 0x75, 0x8b, 0x6d, 0x8b, 0x75, 0x77, 0x81, 0x68, + 0x08, 0x78, 0x8b, 0xa9, 0xf7, 0x21, 0xf7, 0x12, 0x8b, 0x7d, 0x4a, 0x05, + 0x88, 0x7e, 0x8a, 0x82, 0x8b, 0x84, 0x8b, 0x77, 0x9d, 0x7a, 0xa0, 0x8b, + 0x9c, 0x8b, 0x9b, 0x93, 0x98, 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, 0xa6, + 0x08, 0xae, 0xf7, 0x39, 0xfc, 0x4a, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, + 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, + 0xb4, 0x1e, 0x99, 0x8b, 0xfb, 0x58, 0xfc, 0x13, 0x05, 0xf7, 0x8b, 0xf7, + 0x33, 0x15, 0x4b, 0x8b, 0xf7, 0x01, 0xf7, 0x68, 0x5e, 0xfb, 0x68, 0x05, + 0x0e, 0xf8, 0x33, 0xf7, 0xb0, 0x15, 0xe0, 0x06, 0xaf, 0xa2, 0x9e, 0xa7, + 0xa2, 0x80, 0x93, 0x6b, 0x1f, 0x84, 0x8b, 0xa7, 0xf7, 0x14, 0x05, 0x8d, + 0x94, 0x8b, 0x90, 0x8b, 0x96, 0x8b, 0xbd, 0x5e, 0xa9, 0x41, 0x8b, 0x64, + 0x8b, 0x49, 0x7f, 0x74, 0x80, 0x7b, 0x84, 0x81, 0x7b, 0x8b, 0x7a, 0x8b, + 0x79, 0x98, 0x7e, 0x9c, 0x8b, 0x92, 0x8b, 0x95, 0x8d, 0x98, 0x8e, 0x08, + 0xaa, 0x92, 0xa6, 0x8f, 0xa1, 0x8b, 0xb0, 0x8b, 0x9a, 0x85, 0x8c, 0x7c, + 0x08, 0x8b, 0x85, 0x89, 0x83, 0x05, 0x6f, 0x8f, 0x7e, 0x8c, 0x77, 0x8b, + 0x3f, 0x8b, 0x50, 0x74, 0x65, 0x5e, 0x79, 0x75, 0x81, 0x74, 0x8b, 0x77, + 0x8b, 0x5c, 0xb9, 0x69, 0xcb, 0x8b, 0xb1, 0x8b, 0xaa, 0x91, 0xb6, 0x9b, + 0x08, 0x89, 0x80, 0x05, 0xa0, 0xee, 0x15, 0x6b, 0x79, 0x5e, 0x7e, 0x6a, + 0x8b, 0x08, 0x76, 0x7a, 0x93, 0x95, 0xa3, 0xb7, 0xa2, 0xb8, 0x1f, 0x9e, + 0x8b, 0x99, 0x8a, 0xab, 0x85, 0x08, 0x85, 0x70, 0x05, 0xae, 0xfb, 0x5d, + 0x15, 0xa2, 0x8b, 0x93, 0x8d, 0x96, 0x94, 0x96, 0x95, 0x92, 0x98, 0x8b, + 0x98, 0x08, 0xa1, 0x7f, 0x93, 0x6a, 0x1e, 0xfb, 0x92, 0x06, 0x5b, 0x7d, + 0x7e, 0x61, 0x79, 0x94, 0x87, 0xaf, 0x1f, 0xf7, 0x94, 0x06, 0x0e, 0xf7, + 0xfb, 0xf8, 0x77, 0x15, 0xc3, 0x06, 0xa9, 0x8b, 0x96, 0x8e, 0x9a, 0x97, + 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, + 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x69, 0x06, 0x6b, 0x8b, + 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb4, 0x1e, 0xc4, 0x8b, 0x68, 0xfb, 0x39, 0xfb, 0x09, 0x4f, + 0x05, 0x64, 0x77, 0x7f, 0x7c, 0x8b, 0x6f, 0x8b, 0x76, 0x9d, 0x79, 0x9f, + 0x8b, 0x96, 0x8b, 0x9a, 0x90, 0x9e, 0x95, 0x08, 0xc7, 0xab, 0x76, 0x24, + 0x52, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, + 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf8, 0x6b, 0x8b, + 0xb4, 0xf7, 0x53, 0x05, 0x8e, 0x9b, 0x8c, 0x91, 0x8b, 0x92, 0x8b, 0xa1, + 0x7a, 0x9b, 0x74, 0x8b, 0x69, 0x8b, 0x76, 0x75, 0x82, 0x5e, 0x08, 0x77, + 0x30, 0xfb, 0x6a, 0x8b, 0xa9, 0xf7, 0x24, 0xf7, 0x2e, 0xdc, 0x05, 0xb2, + 0x9f, 0x97, 0x9a, 0x8b, 0xa7, 0x8b, 0x9f, 0x7a, 0x9d, 0x77, 0x8b, 0x7f, + 0x8b, 0x81, 0x88, 0x74, 0x7f, 0x08, 0x29, 0x57, 0xa5, 0xf7, 0x10, 0x05, + 0x0e, 0xf7, 0x39, 0xa7, 0x15, 0xb1, 0x6f, 0xb8, 0x7d, 0xbd, 0x8b, 0xde, + 0x8b, 0xe7, 0xb7, 0xd0, 0xd3, 0xcf, 0xd3, 0xb2, 0xeb, 0x8b, 0xea, 0x8b, + 0xb7, 0x82, 0xb3, 0x78, 0xad, 0x08, 0xcd, 0xcc, 0x05, 0xa3, 0xa4, 0x91, + 0x94, 0x8b, 0x9d, 0x8b, 0xa1, 0x7a, 0x9b, 0x75, 0x8b, 0x79, 0x8b, 0x80, + 0x85, 0x72, 0x72, 0x08, 0x51, 0x51, 0x05, 0x62, 0xab, 0x5e, 0x9b, 0x56, + 0x8b, 0xfb, 0x48, 0x8b, 0xfb, 0x40, 0xfb, 0x4c, 0x8b, 0xfb, 0x55, 0x8b, + 0x5a, 0x95, 0x64, 0xa2, 0x63, 0x08, 0x42, 0x42, 0x05, 0x72, 0x73, 0x85, + 0x80, 0x8b, 0x7a, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9e, 0x8b, 0x94, + 0x90, 0xa4, 0xa4, 0x08, 0xcf, 0xcf, 0x05, 0xf8, 0x09, 0xf8, 0x08, 0x15, + 0x91, 0x77, 0x8d, 0x7b, 0x8b, 0x75, 0x8b, 0xfb, 0x16, 0xfb, 0x03, 0xfb, + 0x12, 0xfb, 0x08, 0x8b, 0x70, 0x8b, 0x72, 0x92, 0x74, 0x99, 0x08, 0xf7, + 0xba, 0xf7, 0xb9, 0x05, 0xfb, 0xf0, 0xfb, 0x76, 0x15, 0x83, 0xa2, 0x87, + 0x9f, 0x8b, 0xa5, 0x8b, 0xf7, 0x14, 0xf7, 0x04, 0xf7, 0x12, 0xf7, 0x07, + 0x8b, 0xaa, 0x8b, 0xa6, 0x82, 0xa3, 0x7a, 0x08, 0xfb, 0xbd, 0xfb, 0xbd, + 0x05, 0x0e, 0xf8, 0x36, 0xf7, 0x87, 0x15, 0x9d, 0x06, 0x8a, 0x84, 0x8a, + 0x84, 0x8b, 0x87, 0x8b, 0x76, 0x9c, 0x7a, 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, + 0x93, 0x98, 0x98, 0x94, 0x95, 0x8f, 0x94, 0x91, 0xa5, 0x08, 0x9b, 0xd9, + 0x05, 0x90, 0x9e, 0x8b, 0x8d, 0x8b, 0x92, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, + 0x8b, 0x6d, 0x8b, 0x75, 0x78, 0x81, 0x67, 0x08, 0x79, 0x8b, 0xa9, 0xf7, + 0x21, 0xf7, 0x13, 0x8b, 0x7d, 0x4a, 0x05, 0x89, 0x80, 0x89, 0x80, 0x8b, + 0x84, 0x8b, 0x77, 0x9d, 0x7a, 0xa0, 0x8b, 0x9c, 0x8b, 0x9b, 0x93, 0x98, + 0x97, 0x94, 0x95, 0x8f, 0x94, 0x91, 0xa6, 0x08, 0xae, 0xf7, 0x39, 0xfb, + 0xe2, 0x8b, 0x05, 0xfb, 0x51, 0xfb, 0x34, 0xfb, 0x3b, 0xfb, 0x58, 0xfb, + 0x19, 0xe4, 0x34, 0xf7, 0x1c, 0x1f, 0xf7, 0xf5, 0x8b, 0xa5, 0xf7, 0x0e, + 0x05, 0x8e, 0x9a, 0x8c, 0x92, 0x8b, 0x92, 0x8b, 0xa0, 0x7a, 0x9b, 0x75, + 0x8b, 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7f, 0x81, 0x81, 0x87, 0x81, 0x86, + 0x71, 0x08, 0x86, 0x75, 0xfb, 0x27, 0x8b, 0xaa, 0xf7, 0x23, 0x05, 0xfb, + 0x17, 0xfb, 0x23, 0x15, 0x67, 0x8b, 0x7a, 0x8e, 0x76, 0x94, 0x5c, 0x9f, + 0x6e, 0xbe, 0x8b, 0xcc, 0x8b, 0xcd, 0xae, 0xd3, 0xc2, 0xbb, 0xb2, 0xad, + 0xb4, 0x99, 0xc9, 0x8c, 0x08, 0x39, 0xfc, 0x13, 0x05, 0x0e, 0xf8, 0x3f, + 0xf8, 0xe7, 0x15, 0x22, 0x24, 0x2a, 0x29, 0x41, 0xc6, 0x56, 0xdc, 0xf7, + 0x01, 0xed, 0xe5, 0xef, 0xd8, 0x51, 0xc2, 0x3a, 0x1f, 0x7b, 0x3d, 0x15, + 0xb6, 0xaa, 0x6d, 0x61, 0x5b, 0x55, 0x5d, 0x53, 0x62, 0x69, 0xa8, 0xaf, + 0xbd, 0xc3, 0xbe, 0xc2, 0x1f, 0xc3, 0xfb, 0xe3, 0x15, 0xa2, 0x8b, 0x94, + 0x8d, 0x96, 0x94, 0x96, 0x95, 0x92, 0x98, 0x8b, 0x98, 0x08, 0xa1, 0x7f, + 0x93, 0x6b, 0x1e, 0xfb, 0x93, 0x06, 0x72, 0x8b, 0x85, 0x89, 0x7f, 0x82, + 0x80, 0x82, 0x84, 0x7d, 0x8b, 0x7f, 0x08, 0x75, 0x98, 0x82, 0xaa, 0x1e, + 0xf7, 0x93, 0x06, 0x0e, 0xf9, 0x1b, 0xf7, 0x40, 0x15, 0x95, 0xb9, 0x05, + 0x90, 0xa4, 0x8e, 0xa3, 0x8b, 0xa2, 0x8b, 0xe9, 0x53, 0xcd, 0x3d, 0x8b, + 0x60, 0x8b, 0x66, 0x7a, 0x5e, 0x64, 0x71, 0xb2, 0x6c, 0x9c, 0x5c, 0x8b, + 0x70, 0x8b, 0x41, 0x7c, 0x6c, 0x80, 0x6f, 0x80, 0x7a, 0x75, 0x8b, 0x71, + 0x08, 0x74, 0x9b, 0x7a, 0xa1, 0x1e, 0x91, 0x8b, 0x94, 0x8c, 0x94, 0x8e, + 0xd0, 0x9e, 0x94, 0x8d, 0x9c, 0x8b, 0xa1, 0x8b, 0x9a, 0x7d, 0x8c, 0x75, + 0x8b, 0x87, 0x8b, 0x86, 0x8a, 0x87, 0x08, 0x87, 0x77, 0x05, 0x71, 0x8e, + 0x79, 0x8d, 0x7c, 0x8b, 0x4d, 0x8b, 0x39, 0x6f, 0x5b, 0x66, 0x6a, 0x71, + 0x7a, 0x64, 0x8b, 0x59, 0x8b, 0x3f, 0xc0, 0x5d, 0xe4, 0x8b, 0xb5, 0x8b, + 0xab, 0x94, 0xb5, 0xa2, 0x08, 0x93, 0x80, 0x95, 0x85, 0x9a, 0x8b, 0x9a, + 0x8b, 0x99, 0x91, 0x97, 0x96, 0x08, 0xaa, 0x73, 0xa1, 0x83, 0xb1, 0x8b, + 0xc0, 0x8b, 0xd8, 0x9f, 0xab, 0xa1, 0x9e, 0x98, 0x95, 0x9e, 0x8b, 0xa1, + 0x8b, 0xa1, 0x7c, 0x9b, 0x76, 0x8b, 0x7e, 0x8b, 0x7a, 0x86, 0x6c, 0x7f, + 0x6c, 0x7f, 0x78, 0x86, 0x75, 0x8b, 0x08, 0x62, 0x8b, 0x79, 0xa4, 0x88, + 0xca, 0x08, 0xf7, 0x8e, 0x06, 0xfc, 0x00, 0x61, 0x15, 0x5a, 0x69, 0x70, + 0x7f, 0x6d, 0x8b, 0x66, 0x8b, 0x74, 0x9c, 0x8b, 0xa8, 0x8b, 0x98, 0x90, + 0x97, 0x93, 0x94, 0x08, 0x9c, 0x9d, 0xbe, 0x9a, 0xb6, 0x8b, 0x9c, 0x8b, + 0x9a, 0x89, 0xa1, 0x85, 0x08, 0x7f, 0x50, 0x05, 0xf7, 0x1a, 0xf7, 0x14, + 0x15, 0x94, 0xa3, 0x91, 0x98, 0x93, 0x97, 0x9c, 0xa5, 0xa5, 0x9c, 0xa3, + 0x8b, 0xab, 0x8b, 0x9e, 0x70, 0x8b, 0x60, 0x8b, 0x86, 0x8b, 0x84, 0x8a, + 0x81, 0x08, 0xfb, 0x20, 0x06, 0x0e, 0xf8, 0x4f, 0xf8, 0x49, 0x15, 0xfb, + 0x46, 0x06, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, + 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb5, 0x1e, 0xd9, 0x8b, 0x59, 0xfb, + 0x81, 0xfb, 0x0e, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, + 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, + 0xeb, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, + 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, + 0x77, 0x8b, 0x08, 0xfb, 0x0d, 0x8b, 0xd2, 0xf7, 0xe5, 0x05, 0x0e, 0xf8, + 0x77, 0xf9, 0x04, 0x15, 0xfb, 0x43, 0x06, 0x6b, 0x8b, 0x82, 0x88, 0x7d, + 0x80, 0x7c, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xd7, 0x8b, 0x68, 0xfb, 0x39, 0x2d, 0x5c, 0x05, 0x66, 0x77, 0x7d, + 0x7b, 0x8b, 0x70, 0x8b, 0x75, 0x9c, 0x79, 0xa0, 0x8b, 0x97, 0x8b, 0x97, + 0x8f, 0x9f, 0x95, 0x08, 0xb1, 0x9f, 0x6d, 0xfb, 0x23, 0xfb, 0x0e, 0x8b, + 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6f, 0x9c, 0x7f, 0xb3, 0x1e, 0xf7, 0xeb, 0x06, 0xa7, 0x8b, + 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, + 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, + 0x0e, 0x8b, 0xb2, 0xf7, 0x4b, 0xeb, 0xbc, 0x05, 0xb1, 0x9e, 0x98, 0x9b, + 0x8b, 0xa7, 0x8b, 0xa1, 0x79, 0x9d, 0x77, 0x8b, 0x7d, 0x8b, 0x84, 0x89, + 0x73, 0x7d, 0x08, 0x64, 0x77, 0xbb, 0xf7, 0x75, 0x05, 0x0e, 0xf9, 0x0e, + 0xf8, 0x26, 0x15, 0xa6, 0xa1, 0x93, 0x98, 0x8b, 0x9e, 0x8b, 0xa1, 0x7b, + 0x9b, 0x74, 0x8b, 0x7b, 0x8b, 0x81, 0x86, 0x73, 0x76, 0x08, 0x50, 0x5a, + 0x05, 0x6d, 0x9d, 0x55, 0x98, 0x5e, 0x8b, 0xfb, 0x34, 0x8b, 0xfb, 0x29, + 0xfb, 0x19, 0x8b, 0xfb, 0x23, 0x8b, 0x65, 0x94, 0x6a, 0x9e, 0x6c, 0x08, + 0x50, 0x59, 0x05, 0x70, 0x74, 0x83, 0x7f, 0x8b, 0x78, 0x8b, 0x75, 0x9b, + 0x7b, 0xa2, 0x8b, 0x9a, 0x8b, 0x96, 0x90, 0xa3, 0xa0, 0x08, 0xcf, 0xc5, + 0x05, 0xb0, 0x77, 0xb3, 0x81, 0xb9, 0x8b, 0xf7, 0x37, 0x8b, 0xf7, 0x29, + 0xf7, 0x18, 0x8b, 0xf7, 0x24, 0x8b, 0xb0, 0x82, 0xab, 0x7a, 0xa9, 0x08, + 0xbe, 0xb6, 0x05, 0xfb, 0x1e, 0xfb, 0x08, 0x15, 0x93, 0x7c, 0x8e, 0x7e, + 0x8b, 0x7a, 0x8b, 0x37, 0x32, 0x42, 0x25, 0x8b, 0x78, 0x8b, 0x7d, 0x8d, + 0x7a, 0x90, 0x08, 0xf7, 0x7a, 0xf7, 0x57, 0x05, 0xfb, 0xbf, 0xfb, 0x21, + 0x15, 0x83, 0x9b, 0x87, 0x9b, 0x8b, 0x9a, 0x8b, 0xdf, 0xe4, 0xd5, 0xef, + 0x8b, 0x9e, 0x8b, 0x9c, 0x88, 0x9f, 0x86, 0x08, 0xfb, 0x7d, 0xfb, 0x59, + 0x05, 0x0e, 0xf9, 0x1c, 0xf7, 0x3f, 0x15, 0x95, 0xb8, 0x05, 0x90, 0xa4, + 0x8e, 0xa5, 0x8b, 0xa3, 0x8b, 0xe8, 0x53, 0xcd, 0x3d, 0x8b, 0x55, 0x8b, + 0x5a, 0x71, 0x5c, 0x55, 0x71, 0xc0, 0x64, 0xa6, 0x5a, 0x8b, 0x4c, 0x8b, + 0x4d, 0x67, 0x5d, 0x4b, 0x5f, 0x50, 0x72, 0x42, 0x8b, 0x49, 0x08, 0x28, + 0xc5, 0x46, 0xde, 0x1e, 0xbc, 0x8b, 0xbf, 0xa5, 0xb8, 0xbb, 0xa4, 0x59, + 0xb1, 0x73, 0xc3, 0x8b, 0xbb, 0x8b, 0xd5, 0x9c, 0xb0, 0x9f, 0xa1, 0x97, + 0x98, 0xa0, 0x8b, 0xa2, 0x8b, 0xa2, 0x7a, 0x9c, 0x76, 0x8b, 0x82, 0x8b, + 0x82, 0x89, 0x83, 0x88, 0x08, 0x4e, 0x72, 0x7e, 0x88, 0x6e, 0x8b, 0x08, + 0x61, 0x75, 0xa8, 0xc5, 0x1f, 0xf7, 0x8f, 0x06, 0xfc, 0x25, 0xf7, 0x46, + 0x15, 0xb0, 0xa1, 0x69, 0x52, 0x35, 0x51, 0x33, 0x51, 0x66, 0x75, 0xad, + 0xc4, 0xe1, 0xc5, 0xe3, 0xc5, 0x1f, 0xf7, 0xcc, 0x2f, 0x15, 0xfb, 0x21, + 0x06, 0x96, 0xa4, 0x91, 0x97, 0x93, 0x97, 0x9c, 0xa6, 0xa4, 0x9b, 0xa3, + 0x8b, 0x08, 0xac, 0x9c, 0x6e, 0x52, 0x1f, 0x85, 0x07, 0x0e, 0xf7, 0x08, + 0xef, 0x15, 0x7b, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xe8, 0x06, + 0xa1, 0x8b, 0x99, 0x8d, 0x94, 0x90, 0xa0, 0x97, 0x98, 0xa1, 0x8b, 0xa1, + 0x8b, 0xa0, 0x80, 0x97, 0x74, 0x8f, 0x08, 0xd8, 0xf7, 0xfd, 0x05, 0x93, + 0xb4, 0xa9, 0xa0, 0xbc, 0x8b, 0xb3, 0x8b, 0xa3, 0x77, 0x8b, 0x6a, 0x8b, + 0x7b, 0x83, 0x7b, 0x7e, 0x7e, 0x7b, 0x7d, 0x7e, 0x86, 0x69, 0x87, 0x64, + 0x87, 0x72, 0x74, 0x8b, 0x6a, 0x8b, 0x73, 0x98, 0x80, 0xac, 0x87, 0x08, + 0xac, 0x87, 0xa6, 0x84, 0x9b, 0x80, 0x08, 0xaa, 0x77, 0x9d, 0x69, 0x8b, + 0x67, 0x08, 0x55, 0x6a, 0x56, 0x68, 0x7b, 0x83, 0x95, 0x9e, 0x1e, 0x97, + 0x07, 0x9d, 0x7b, 0x98, 0x76, 0x65, 0x6f, 0x68, 0x5c, 0x53, 0xb1, 0x69, + 0xc7, 0x1e, 0xc4, 0x8b, 0xb9, 0xa2, 0xb1, 0xb9, 0xaf, 0xb8, 0xa1, 0xc7, + 0x8b, 0xc3, 0x8b, 0xcb, 0x70, 0xbd, 0x56, 0xb0, 0x08, 0xb4, 0xb3, 0x9b, + 0xaf, 0x8b, 0xbc, 0x8b, 0xdb, 0x51, 0xc0, 0x33, 0x8b, 0x26, 0x8b, 0x36, + 0x4f, 0x79, 0x36, 0x08, 0x3b, 0xfc, 0x0e, 0x05, 0x0e, 0xf8, 0x56, 0xf7, + 0x32, 0x15, 0x96, 0x51, 0x74, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, + 0x1e, 0xf7, 0x1f, 0x06, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x90, 0x82, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2a, 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, + 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xca, 0x8b, 0xfb, 0x80, 0xfc, 0x13, + 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x18, 0x06, 0xa8, 0x8b, + 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, + 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x76, 0x8b, 0x08, 0x74, + 0x8b, 0xaf, 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x77, 0xef, 0x15, 0xfb, 0x31, + 0x8b, 0xf7, 0x0b, 0xf7, 0x54, 0xb1, 0xfb, 0x54, 0x05, 0x3a, 0xf8, 0xb0, + 0x15, 0x65, 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, + 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x65, 0x67, 0x68, + 0x66, 0x70, 0xa0, 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, + 0x6e, 0x1f, 0x0e, 0xf8, 0x56, 0xf7, 0x32, 0x15, 0x96, 0x51, 0x74, 0x8b, + 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x1f, 0x06, 0xa7, 0x8b, + 0x98, 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, + 0x82, 0x9a, 0x7e, 0x90, 0x82, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2a, + 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xca, 0x8b, 0xfb, 0x80, 0xfc, 0x13, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, + 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0x18, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x76, 0x8b, 0x08, 0x74, 0x8b, 0xaf, 0xc5, 0xf7, 0x82, 0x8b, + 0x05, 0x77, 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xf7, 0x0b, 0xf7, 0x54, 0xb1, + 0xfb, 0x54, 0x05, 0xf7, 0x23, 0xf8, 0x91, 0x15, 0xa3, 0x9c, 0x93, 0x95, + 0x8b, 0x9b, 0x8b, 0x9c, 0x7f, 0x97, 0x79, 0x8b, 0x80, 0x8b, 0x82, 0x87, + 0x7b, 0x80, 0x08, 0xfb, 0x31, 0xfb, 0x04, 0x05, 0x76, 0x7d, 0x81, 0x7d, + 0x8b, 0x7c, 0x8b, 0x7a, 0x98, 0x7f, 0x9c, 0x8b, 0x94, 0x8b, 0x95, 0x90, + 0x9b, 0x96, 0x08, 0xf7, 0x31, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x56, 0xf7, + 0x32, 0x15, 0x96, 0x51, 0x74, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, + 0x1e, 0xf7, 0x1f, 0x06, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x90, 0x82, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2a, 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, + 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xca, 0x8b, 0xfb, 0x80, 0xfc, 0x13, + 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x18, 0x06, 0xa8, 0x8b, + 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, + 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x76, 0x8b, 0x08, 0x74, + 0x8b, 0xaf, 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x77, 0xef, 0x15, 0xfb, 0x31, + 0x8b, 0xf7, 0x0b, 0xf7, 0x54, 0xb1, 0xfb, 0x54, 0x05, 0x5e, 0xf8, 0xca, + 0x15, 0x7f, 0x97, 0x85, 0x8e, 0x80, 0x8b, 0x74, 0x8b, 0x75, 0x76, 0x8b, + 0x73, 0x8b, 0x84, 0x90, 0x81, 0x96, 0x81, 0x08, 0xf7, 0x02, 0xfb, 0x03, + 0x05, 0x95, 0x80, 0x94, 0x86, 0x94, 0x8b, 0xa2, 0x8b, 0xa2, 0xa0, 0x8b, + 0xa1, 0x8b, 0x94, 0x86, 0x94, 0x80, 0x96, 0x08, 0xfb, 0x02, 0xf7, 0x04, + 0x05, 0x0e, 0xf8, 0x56, 0xf7, 0x32, 0x15, 0x96, 0x51, 0x74, 0x8b, 0x05, + 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x1f, 0x06, 0xa7, 0x8b, 0x98, + 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, + 0x9a, 0x7e, 0x90, 0x82, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2a, 0xf8, + 0x77, 0xfb, 0x6c, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, + 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xca, + 0x8b, 0xfb, 0x80, 0xfc, 0x13, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, 0x7f, + 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xf7, 0x18, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, + 0x8c, 0x76, 0x8b, 0x08, 0x74, 0x8b, 0xaf, 0xc5, 0xf7, 0x82, 0x8b, 0x05, + 0x77, 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xf7, 0x0b, 0xf7, 0x54, 0xb1, 0xfb, + 0x54, 0x05, 0x99, 0xf8, 0x80, 0x15, 0xe6, 0x2a, 0x05, 0x94, 0x82, 0x93, + 0x87, 0x94, 0x8b, 0xa0, 0x8b, 0xa1, 0xa0, 0x8b, 0xa1, 0x8b, 0x94, 0x89, + 0x8f, 0x80, 0x95, 0x08, 0x86, 0x90, 0xfb, 0x0f, 0xf7, 0x14, 0xfb, 0x48, + 0xfb, 0x14, 0x05, 0x70, 0x78, 0x86, 0x84, 0x8b, 0x7a, 0x8b, 0x7b, 0x97, + 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x93, 0x8e, 0x99, 0x95, 0x08, 0xf7, 0x1a, + 0xec, 0x05, 0x0e, 0xf8, 0x56, 0xf7, 0x32, 0x15, 0x96, 0x51, 0x74, 0x8b, + 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x1f, 0x06, 0xa7, 0x8b, + 0x98, 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, + 0x82, 0x9a, 0x7e, 0x90, 0x82, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2a, + 0xf8, 0x77, 0xfb, 0x6c, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xca, 0x8b, 0xfb, 0x80, 0xfc, 0x13, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, + 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0x18, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x76, 0x8b, 0x08, 0x74, 0x8b, 0xaf, 0xc5, 0x05, 0xf7, 0x82, + 0x06, 0x77, 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xf7, 0x0b, 0xf7, 0x54, 0xb1, + 0xfb, 0x54, 0x05, 0xf7, 0x44, 0xf8, 0xb1, 0x15, 0x81, 0x8b, 0x79, 0x80, + 0x7f, 0x7e, 0x6b, 0x68, 0x86, 0x87, 0x7b, 0x8b, 0x80, 0x8b, 0x7e, 0x92, + 0x6f, 0x9e, 0x08, 0x60, 0xa9, 0x7a, 0x92, 0x75, 0x8b, 0x6c, 0x8b, 0x6a, + 0x7a, 0x6b, 0x6c, 0x73, 0x72, 0x7f, 0x79, 0x8b, 0x7c, 0x8b, 0x7e, 0x96, + 0x81, 0x99, 0x8b, 0x94, 0x8b, 0x95, 0x8f, 0x92, 0x93, 0xb4, 0xb5, 0x94, + 0x91, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x93, 0x87, 0xa3, 0x7a, 0x08, 0xb1, + 0x6f, 0xa8, 0x7d, 0xa1, 0x8b, 0xac, 0x8b, 0xa9, 0x9d, 0xb3, 0xb6, 0x9f, + 0xa1, 0x94, 0x99, 0x8b, 0x97, 0x8b, 0x97, 0x7e, 0x96, 0x7d, 0x8b, 0x08, + 0x0e, 0xf8, 0x56, 0xf7, 0x32, 0x15, 0x96, 0x51, 0x74, 0x8b, 0x05, 0x6b, + 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x1f, 0x06, 0xa7, 0x8b, 0x98, 0x8e, + 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9a, + 0x7e, 0x90, 0x82, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2a, 0xf8, 0x77, + 0xfb, 0x6c, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, + 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xca, 0x8b, + 0xfb, 0x80, 0xfc, 0x13, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7c, 0x7f, 0x7d, + 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, + 0x18, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, + 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, + 0x76, 0x8b, 0x08, 0x74, 0x8b, 0xaf, 0xc5, 0xf7, 0x82, 0x8b, 0x05, 0x77, + 0xef, 0x15, 0xfb, 0x31, 0x8b, 0xf7, 0x0b, 0xf7, 0x54, 0xb1, 0xfb, 0x54, + 0x05, 0xb1, 0xf8, 0xf9, 0x15, 0x3f, 0x41, 0x44, 0x42, 0x53, 0xb5, 0x62, + 0xc4, 0xd8, 0xd5, 0xd1, 0xd4, 0xc5, 0x62, 0xb3, 0x50, 0x1f, 0x80, 0x56, + 0x15, 0xad, 0xa2, 0x74, 0x6b, 0x63, 0x61, 0x64, 0x5f, 0x6b, 0x73, 0xa2, + 0xaa, 0xb4, 0xb5, 0xb2, 0xb6, 0x1f, 0x0e, 0xf7, 0xe2, 0x7d, 0x15, 0xdc, + 0x90, 0xc2, 0x99, 0xbb, 0xaa, 0xb9, 0xa7, 0xa3, 0xa8, 0x8b, 0xa4, 0x8b, + 0xa2, 0x79, 0x9d, 0x74, 0x8b, 0x7e, 0x8b, 0x7f, 0x86, 0x7d, 0x80, 0x6b, + 0x70, 0x8a, 0x8b, 0x7f, 0x84, 0x70, 0x7d, 0x60, 0x82, 0x5d, 0x8b, 0x08, + 0x25, 0x4c, 0xbc, 0xda, 0x1f, 0x8b, 0x96, 0x8c, 0x98, 0x8e, 0x98, 0x08, + 0x99, 0xcb, 0x05, 0xa1, 0xf4, 0xe6, 0xd8, 0xf1, 0x8b, 0xcf, 0x8b, 0xc5, + 0x69, 0x89, 0x65, 0x08, 0x8a, 0x78, 0x05, 0x8a, 0x74, 0x9b, 0x7b, 0xa3, + 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x94, 0x95, 0x8f, 0x94, 0x91, + 0xa5, 0x08, 0x9d, 0xdf, 0x05, 0x8f, 0x9c, 0x8b, 0x8f, 0x8b, 0x92, 0x08, + 0xa1, 0x7a, 0x9b, 0x74, 0x1e, 0x7a, 0x8b, 0x7e, 0x84, 0x7a, 0x7a, 0x08, + 0x82, 0x8f, 0x05, 0x59, 0xa5, 0x6a, 0x93, 0x57, 0x8b, 0xfb, 0x2f, 0x8b, + 0xfb, 0x23, 0xfb, 0x0e, 0x69, 0xfb, 0x34, 0x08, 0x7d, 0x49, 0x05, 0x87, + 0x79, 0x89, 0x79, 0x8b, 0x79, 0x8b, 0x3b, 0xb4, 0x47, 0xd0, 0x6b, 0xa2, + 0x80, 0x9c, 0x85, 0xae, 0x84, 0x08, 0x78, 0x2e, 0x05, 0x9c, 0x8d, 0x8f, + 0x8b, 0x91, 0x8b, 0x08, 0xa4, 0x9b, 0x80, 0x7a, 0x78, 0x7b, 0x7f, 0x71, + 0x1f, 0x7a, 0x8b, 0x76, 0x91, 0x7b, 0x96, 0x7b, 0x95, 0x89, 0x8c, 0x83, + 0x8b, 0x08, 0x74, 0x76, 0x76, 0x75, 0x6e, 0xc0, 0x71, 0xc4, 0xd1, 0xc5, + 0xc2, 0xcc, 0x1f, 0x8b, 0xb3, 0x7b, 0x9e, 0x61, 0x93, 0x08, 0x91, 0xa7, + 0x05, 0x0e, 0xf7, 0x12, 0xf7, 0x87, 0x15, 0x6d, 0xfb, 0x23, 0x05, 0x72, + 0x8b, 0x80, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x61, 0x06, 0xe1, 0x8b, 0xcd, 0xa2, + 0xc7, 0xbf, 0xc3, 0xbb, 0xb0, 0xc9, 0x9a, 0xd4, 0x08, 0x95, 0xba, 0x05, + 0x90, 0xa0, 0x8d, 0xa1, 0x8b, 0xa0, 0x08, 0xf7, 0x14, 0x38, 0xe1, 0xfb, + 0x0e, 0x1e, 0xfb, 0x69, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, + 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x70, 0x9b, 0x7e, 0xae, 0x1e, 0x6d, + 0xfb, 0x20, 0x84, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, + 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x92, + 0x06, 0xef, 0x16, 0xd5, 0x06, 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, + 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, 0x83, + 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x41, 0x8b, 0xa9, 0xf7, 0x20, 0xf7, + 0x02, 0x8b, 0x05, 0xb0, 0x8b, 0xab, 0x82, 0x9e, 0x7a, 0xa7, 0x74, 0x9c, + 0x61, 0x8b, 0x61, 0x8b, 0x7c, 0x8a, 0x7d, 0x88, 0x7d, 0x08, 0x81, 0x5d, + 0x05, 0x80, 0x58, 0x77, 0x67, 0x68, 0x6d, 0x64, 0x6b, 0x68, 0x7f, 0x4f, + 0x8b, 0x08, 0xfb, 0x02, 0x8b, 0xa9, 0xf7, 0x23, 0x05, 0x0e, 0xf7, 0x8a, + 0xf7, 0x87, 0x15, 0xe0, 0x8b, 0x89, 0x84, 0x05, 0x88, 0x7d, 0x8a, 0x83, + 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9a, 0x8b, 0x9c, 0x93, + 0x97, 0x97, 0x95, 0x96, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0xa4, 0xf7, 0x05, + 0x05, 0x8e, 0x9d, 0x8c, 0x8f, 0x8b, 0x93, 0x8b, 0xa0, 0x7a, 0x9b, 0x74, + 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7e, 0x7e, 0x81, 0x81, 0x88, 0x84, 0x85, + 0x6e, 0x08, 0x8a, 0x84, 0x36, 0x8b, 0xa9, 0xf7, 0x21, 0xf7, 0x7e, 0x8b, + 0x80, 0x59, 0x05, 0x88, 0x7e, 0x8a, 0x81, 0x8b, 0x85, 0x8b, 0x75, 0x9d, + 0x7b, 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, + 0x93, 0x91, 0xa7, 0x08, 0xab, 0xf7, 0x2a, 0xfc, 0x54, 0x8b, 0x05, 0x6b, + 0x8b, 0x82, 0x89, 0x7d, 0x7f, 0x7c, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, 0x7c, 0x8b, + 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf8, 0x6a, 0x8b, 0xac, 0xf7, + 0x2c, 0x05, 0x8e, 0x9d, 0x8c, 0x90, 0x8b, 0x92, 0x8b, 0xa0, 0x79, 0x9b, + 0x74, 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7f, 0x7e, 0x81, 0x81, 0x87, 0x83, + 0x86, 0x6f, 0x08, 0x7f, 0x57, 0xfb, 0x93, 0x8b, 0xa9, 0xf7, 0x23, 0x05, + 0xf7, 0x03, 0xf8, 0xbf, 0x15, 0x65, 0x67, 0x68, 0x66, 0x70, 0xa0, 0x76, + 0xa6, 0xb1, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6f, 0x1f, 0xf7, 0x64, + 0x16, 0x65, 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb1, 0xaf, 0xae, + 0xb0, 0xa7, 0x77, 0x9f, 0x6f, 0x1f, 0x0e, 0xf7, 0x8a, 0xf7, 0x87, 0x15, + 0xe0, 0x8b, 0x89, 0x84, 0x05, 0x88, 0x7d, 0x8a, 0x83, 0x8b, 0x84, 0x8b, + 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9a, 0x8b, 0x9c, 0x93, 0x97, 0x97, 0x95, + 0x96, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0xa4, 0xf7, 0x05, 0x05, 0x8f, 0x9f, + 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, 0x7c, 0x8b, + 0x7a, 0x83, 0x7e, 0x7e, 0x81, 0x81, 0x88, 0x84, 0x85, 0x6e, 0x08, 0x8a, + 0x84, 0x36, 0x8b, 0xa9, 0xf7, 0x21, 0xf7, 0x7e, 0x8b, 0x80, 0x59, 0x05, + 0x88, 0x7e, 0x8a, 0x81, 0x8b, 0x85, 0x8b, 0x75, 0x9d, 0x7b, 0xa1, 0x8b, + 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, 0xa7, + 0x08, 0xab, 0xf7, 0x2a, 0xfc, 0x54, 0x8b, 0x05, 0x6b, 0x8b, 0x82, 0x89, + 0x7d, 0x7f, 0x7c, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, + 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, 0x7c, 0x8b, 0x05, 0x6c, 0x8b, + 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, + 0x9c, 0x7f, 0xb3, 0x1e, 0xf8, 0x6a, 0x8b, 0xac, 0xf7, 0x2c, 0x05, 0x8e, + 0x9d, 0x8c, 0x8f, 0x8b, 0x93, 0x8b, 0xa0, 0x79, 0x9b, 0x74, 0x8b, 0x7c, + 0x8b, 0x7a, 0x84, 0x7f, 0x7d, 0x81, 0x81, 0x87, 0x83, 0x86, 0x6f, 0x08, + 0x7f, 0x57, 0xfb, 0x93, 0x8b, 0xa9, 0xf7, 0x23, 0x05, 0xf7, 0xe3, 0xf8, + 0xa0, 0x15, 0xa1, 0x9a, 0x94, 0x98, 0x8b, 0x9a, 0x8b, 0x9c, 0x7f, 0x97, + 0x79, 0x8b, 0x81, 0x8b, 0x83, 0x88, 0x7a, 0x7f, 0x08, 0xfb, 0x31, 0xfb, + 0x04, 0x05, 0x74, 0x7b, 0x82, 0x7f, 0x8b, 0x7c, 0x8b, 0x7a, 0x98, 0x7f, + 0x9c, 0x8b, 0x95, 0x8b, 0x96, 0x90, 0x9a, 0x96, 0x08, 0xf7, 0x31, 0xf7, + 0x03, 0x05, 0x0e, 0xf7, 0x8a, 0xf7, 0x87, 0x15, 0xe0, 0x8b, 0x89, 0x84, + 0x05, 0x88, 0x7d, 0x8a, 0x83, 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, + 0x8b, 0x9a, 0x8b, 0x9c, 0x93, 0x97, 0x97, 0x95, 0x96, 0x8e, 0x92, 0x91, + 0xa7, 0x08, 0xa4, 0xf7, 0x05, 0x05, 0x8e, 0x9d, 0x8c, 0x8f, 0x8b, 0x93, + 0x8b, 0xa0, 0x7a, 0x9b, 0x74, 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7e, 0x7e, + 0x81, 0x81, 0x88, 0x84, 0x85, 0x6e, 0x08, 0x8a, 0x84, 0x36, 0x8b, 0xa9, + 0xf7, 0x21, 0xf7, 0x7e, 0x8b, 0x80, 0x59, 0x05, 0x88, 0x7e, 0x8a, 0x81, + 0x8b, 0x85, 0x8b, 0x75, 0x9d, 0x7b, 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, + 0x97, 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, 0xa7, 0x08, 0xab, 0xf7, 0x2a, + 0xfc, 0x54, 0x8b, 0x05, 0x6b, 0x8b, 0x82, 0x89, 0x7d, 0x7f, 0x7c, 0x7e, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, + 0x3a, 0xfc, 0x13, 0x7c, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, + 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, + 0xf8, 0x6a, 0x8b, 0xac, 0xf7, 0x2c, 0x05, 0x8e, 0x9d, 0x8c, 0x90, 0x8b, + 0x92, 0x8b, 0xa0, 0x79, 0x9b, 0x74, 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7f, + 0x7e, 0x81, 0x81, 0x87, 0x83, 0x86, 0x6f, 0x08, 0x7f, 0x57, 0xfb, 0x93, + 0x8b, 0xa9, 0xf7, 0x23, 0x05, 0xf7, 0x20, 0xf8, 0xd9, 0x15, 0x80, 0x96, + 0x84, 0x8f, 0x81, 0x8b, 0x73, 0x8b, 0x75, 0x76, 0x8b, 0x74, 0x8b, 0x83, + 0x90, 0x82, 0x96, 0x80, 0x08, 0xf7, 0x02, 0xfb, 0x03, 0x05, 0x96, 0x80, + 0x93, 0x86, 0x94, 0x8b, 0xa2, 0x8b, 0xa2, 0xa0, 0x8b, 0xa1, 0x8b, 0x94, + 0x86, 0x95, 0x80, 0x95, 0x08, 0xfb, 0x02, 0xf7, 0x04, 0x05, 0x0e, 0xf7, + 0x8a, 0xf7, 0x87, 0x15, 0xe0, 0x8b, 0x89, 0x84, 0x05, 0x88, 0x7d, 0x8a, + 0x83, 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9a, 0x8b, 0x9c, + 0x93, 0x97, 0x97, 0x95, 0x96, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0xa4, 0xf7, + 0x05, 0x05, 0x8e, 0x9d, 0x8c, 0x8f, 0x8b, 0x93, 0x8b, 0xa0, 0x7a, 0x9b, + 0x74, 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7e, 0x7e, 0x81, 0x81, 0x88, 0x84, + 0x85, 0x6e, 0x08, 0x8a, 0x84, 0x36, 0x8b, 0xa9, 0xf7, 0x21, 0xf7, 0x7e, + 0x8b, 0x80, 0x59, 0x05, 0x88, 0x7e, 0x8a, 0x81, 0x8b, 0x85, 0x8b, 0x75, + 0x9d, 0x7b, 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, + 0x8e, 0x93, 0x91, 0xa7, 0x08, 0xab, 0xf7, 0x2a, 0xfc, 0x54, 0x8b, 0x05, + 0x6b, 0x8b, 0x82, 0x89, 0x7d, 0x7f, 0x7c, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, 0x7c, + 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, + 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf8, 0x6a, 0x8b, 0xac, + 0xf7, 0x2c, 0x05, 0x8e, 0x9d, 0x8c, 0x90, 0x8b, 0x92, 0x8b, 0xa0, 0x79, + 0x9b, 0x74, 0x8b, 0x7c, 0x8b, 0x7a, 0x83, 0x7f, 0x7e, 0x81, 0x81, 0x87, + 0x83, 0x86, 0x6f, 0x08, 0x7f, 0x57, 0xfb, 0x93, 0x8b, 0xa9, 0xf7, 0x23, + 0x05, 0xf7, 0x62, 0xf8, 0x8f, 0x15, 0xe6, 0x2a, 0x05, 0x94, 0x82, 0x93, + 0x87, 0x94, 0x8b, 0xa0, 0x8b, 0xa1, 0xa1, 0x8b, 0xa0, 0x8b, 0x93, 0x89, + 0x90, 0x83, 0x93, 0x88, 0x8d, 0x88, 0x8e, 0x89, 0x8d, 0x08, 0xfb, 0x0f, + 0xf7, 0x14, 0xfb, 0x48, 0xfb, 0x14, 0x05, 0x70, 0x77, 0x86, 0x85, 0x8b, + 0x7b, 0x8b, 0x7a, 0x97, 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x93, 0x8f, 0x99, + 0x94, 0x08, 0xf7, 0x1a, 0xec, 0x05, 0x0e, 0xf8, 0x59, 0xf8, 0x77, 0x15, + 0xf0, 0x06, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x96, 0x94, 0x9d, + 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x84, 0x8c, + 0x77, 0x8b, 0x08, 0xfb, 0xc1, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, + 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, + 0xf0, 0x8b, 0x3a, 0xfc, 0x13, 0x26, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, + 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, + 0xb4, 0x1e, 0xf7, 0xc1, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, + 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, + 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x27, 0x8b, 0xdc, 0xf8, 0x13, 0x05, + 0x34, 0xf7, 0xcf, 0x15, 0x65, 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, + 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, + 0x65, 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, + 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0x0e, 0xf8, 0x59, 0xf8, 0x77, 0x15, 0xf0, + 0x06, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, + 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, + 0x8b, 0x08, 0xfb, 0xc1, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, + 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xf0, + 0x8b, 0x3a, 0xfc, 0x13, 0x26, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0xc1, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x27, 0x8b, 0xdc, 0xf8, 0x13, 0x05, 0xf7, + 0x08, 0xf7, 0xb0, 0x15, 0x92, 0x90, 0x05, 0x9b, 0x96, 0x93, 0x98, 0x8b, + 0x99, 0x8b, 0x9c, 0x7e, 0x97, 0x79, 0x8b, 0x81, 0x8b, 0x82, 0x87, 0x7c, + 0x80, 0x08, 0xfb, 0x2b, 0xfb, 0x04, 0x05, 0x75, 0x7b, 0x83, 0x7f, 0x8b, + 0x7c, 0x8b, 0x7a, 0x98, 0x7f, 0x9c, 0x8b, 0x94, 0x8b, 0x8b, 0x8b, 0xa5, + 0x9b, 0x08, 0xf7, 0x2a, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x59, 0xf8, 0x77, + 0x15, 0xf0, 0x06, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x96, 0x94, + 0x9d, 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x84, + 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0xc1, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, + 0x1e, 0xf0, 0x8b, 0x3a, 0xfc, 0x13, 0x26, 0x8b, 0x05, 0x6b, 0x8b, 0x83, + 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, + 0x80, 0xb4, 0x1e, 0xf7, 0xc1, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, + 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x27, 0x8b, 0xdc, 0xf8, 0x13, + 0x05, 0x51, 0xf7, 0xe9, 0x15, 0x7f, 0x97, 0x85, 0x8e, 0x81, 0x8b, 0x73, + 0x8b, 0x75, 0x76, 0x8b, 0x74, 0x8b, 0x83, 0x90, 0x81, 0x96, 0x81, 0x08, + 0xf7, 0x02, 0xfb, 0x03, 0x05, 0x95, 0x80, 0x95, 0x86, 0x93, 0x8b, 0xa2, + 0x8b, 0xa2, 0xa0, 0x8b, 0xa1, 0x8b, 0x94, 0x86, 0x95, 0x80, 0x95, 0x08, + 0xfb, 0x02, 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0x59, 0xf8, 0x77, 0x15, 0xf0, + 0x06, 0xa9, 0x8b, 0x95, 0x8e, 0x9a, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, + 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, + 0x8b, 0x08, 0xfb, 0xc1, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, + 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xf0, + 0x8b, 0x3a, 0xfc, 0x13, 0x26, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, + 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0xc1, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x27, 0x8b, 0xdc, 0xf8, 0x13, 0x05, 0x93, + 0xf7, 0x9f, 0x15, 0xe6, 0x2a, 0x05, 0x94, 0x82, 0x93, 0x87, 0x93, 0x8b, + 0xa1, 0x8b, 0xa0, 0xa0, 0x8b, 0xa1, 0x8b, 0x95, 0x8a, 0x8c, 0x7b, 0x9c, + 0x08, 0xfb, 0x0f, 0xf7, 0x14, 0xfb, 0x48, 0xfb, 0x14, 0x05, 0x71, 0x78, + 0x85, 0x84, 0x8b, 0x7a, 0x8b, 0x7b, 0x97, 0x7f, 0x9b, 0x8b, 0x94, 0x8b, + 0x93, 0x8f, 0x98, 0x94, 0x08, 0xf7, 0x1b, 0xec, 0x05, 0x0e, 0xf8, 0x10, + 0xf9, 0x6e, 0x15, 0x9a, 0x8b, 0x93, 0x87, 0xa2, 0x7a, 0x08, 0xaf, 0x70, + 0xab, 0x7c, 0xa1, 0x8b, 0xab, 0x8b, 0xaa, 0x9d, 0xb3, 0xb6, 0x9f, 0xa0, + 0x94, 0x9a, 0x8b, 0x97, 0x8b, 0x97, 0x7e, 0x96, 0x7d, 0x8b, 0x80, 0x8b, + 0x7a, 0x80, 0x7a, 0x79, 0x6f, 0x6c, 0x86, 0x88, 0x7c, 0x8b, 0x08, 0x80, + 0x8b, 0x7e, 0x91, 0x6f, 0x9f, 0x08, 0x5f, 0xa9, 0x7b, 0x92, 0x74, 0x8b, + 0x6d, 0x8b, 0x6b, 0x7b, 0x6b, 0x6d, 0x71, 0x72, 0x7f, 0x77, 0x8b, 0x7c, + 0x8b, 0x7e, 0x96, 0x81, 0x99, 0x8b, 0x95, 0x8b, 0x94, 0x8f, 0x94, 0x95, + 0x08, 0xb2, 0xb3, 0x94, 0x91, 0x9d, 0x8b, 0x08, 0xfb, 0x10, 0xfb, 0xe4, + 0x15, 0xf7, 0x44, 0xfc, 0x1e, 0xed, 0x8b, 0xf2, 0xf8, 0x77, 0x05, 0xa4, + 0x8b, 0x96, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, + 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, + 0xfb, 0x16, 0x06, 0x6c, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, + 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x4d, + 0xfb, 0xb8, 0xfb, 0x43, 0xf8, 0x1c, 0xfb, 0x06, 0x8b, 0x05, 0x6c, 0x8b, + 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9a, 0x80, 0xb4, 0x1e, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, 0x05, 0x71, 0x8b, + 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x15, 0x06, 0xa7, 0x8b, 0x99, 0x8f, 0x98, + 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, + 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x68, 0x8b, 0xc9, 0xf7, + 0xba, 0x05, 0x0e, 0xf8, 0x3e, 0xf8, 0xe9, 0x15, 0x3a, 0x8b, 0x2c, 0x5e, + 0x47, 0x44, 0x49, 0x45, 0x62, 0x28, 0x8b, 0x2f, 0x8b, 0xfb, 0x1a, 0xea, + 0x27, 0xf7, 0x13, 0x8b, 0xde, 0x8b, 0xe7, 0xb7, 0xd0, 0xd3, 0xd0, 0xd3, + 0xb2, 0xeb, 0x8b, 0xeb, 0x8b, 0xf7, 0x18, 0x2c, 0xee, 0xfb, 0x14, 0x8b, + 0x08, 0x76, 0x27, 0x15, 0xdc, 0xc7, 0x49, 0x32, 0xfb, 0x17, 0xfb, 0x04, + 0xfb, 0x11, 0xfb, 0x09, 0x3b, 0x50, 0xce, 0xe5, 0xf7, 0x14, 0xf7, 0x04, + 0xf7, 0x12, 0xf7, 0x07, 0x1f, 0x63, 0xf7, 0xc1, 0x15, 0x65, 0x67, 0x68, + 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, + 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x66, 0x67, 0x68, 0x66, 0x6f, 0x9f, 0x77, + 0xa7, 0xb1, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0x0e, 0xf8, + 0x3e, 0xf8, 0xe9, 0x15, 0x3a, 0x8b, 0x2c, 0x5e, 0x47, 0x44, 0x49, 0x45, + 0x62, 0x28, 0x8b, 0x2f, 0x8b, 0xfb, 0x1a, 0xea, 0x27, 0xf7, 0x13, 0x8b, + 0xde, 0x8b, 0xe7, 0xb7, 0xd0, 0xd3, 0xd0, 0xd3, 0xb2, 0xeb, 0x8b, 0xeb, + 0x8b, 0xf7, 0x18, 0x2c, 0xee, 0xfb, 0x14, 0x8b, 0x08, 0x76, 0x27, 0x15, + 0xdc, 0xc7, 0x49, 0x32, 0xfb, 0x17, 0xfb, 0x04, 0xfb, 0x11, 0xfb, 0x09, + 0x3b, 0x50, 0xce, 0xe5, 0xf7, 0x14, 0xf7, 0x04, 0xf7, 0x12, 0xf7, 0x07, + 0x1f, 0xf7, 0x4a, 0xf7, 0xa2, 0x15, 0xa2, 0x9b, 0x93, 0x97, 0x8b, 0x9a, + 0x8b, 0x9c, 0x7e, 0x97, 0x7a, 0x8b, 0x80, 0x8b, 0x83, 0x87, 0x7a, 0x80, + 0x08, 0xfb, 0x31, 0xfb, 0x04, 0x05, 0x76, 0x7d, 0x81, 0x7d, 0x8b, 0x7d, + 0x8b, 0x79, 0x97, 0x7f, 0x9d, 0x8b, 0x94, 0x8b, 0x95, 0x8f, 0x9b, 0x97, + 0x08, 0xf7, 0x32, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x3e, 0xf8, 0xe9, 0x15, + 0x3a, 0x8b, 0x2c, 0x5e, 0x47, 0x44, 0x49, 0x45, 0x62, 0x28, 0x8b, 0x2f, + 0x8b, 0xfb, 0x1a, 0xea, 0x27, 0xf7, 0x13, 0x8b, 0xde, 0x8b, 0xe7, 0xb7, + 0xd0, 0xd3, 0xd0, 0xd3, 0xb2, 0xeb, 0x8b, 0xeb, 0x8b, 0xf7, 0x18, 0x2c, + 0xee, 0xfb, 0x14, 0x8b, 0x08, 0x76, 0x27, 0x15, 0xdc, 0xc7, 0x49, 0x32, + 0xfb, 0x17, 0xfb, 0x04, 0xfb, 0x11, 0xfb, 0x09, 0x3b, 0x50, 0xce, 0xe5, + 0xf7, 0x14, 0xf7, 0x04, 0xf7, 0x12, 0xf7, 0x07, 0x1f, 0x84, 0xf7, 0xdb, + 0x15, 0x7f, 0x97, 0x85, 0x8e, 0x81, 0x8b, 0x73, 0x8b, 0x75, 0x76, 0x8b, + 0x74, 0x8b, 0x83, 0x90, 0x81, 0x96, 0x81, 0x08, 0xf7, 0x02, 0xfb, 0x03, + 0x05, 0x95, 0x80, 0x94, 0x86, 0x94, 0x8b, 0xa2, 0x8b, 0xa2, 0xa0, 0x8b, + 0xa1, 0x8b, 0x94, 0x86, 0x95, 0x80, 0x95, 0x08, 0xfb, 0x02, 0xf7, 0x04, + 0x05, 0x0e, 0xf8, 0x3e, 0xf8, 0xe9, 0x15, 0x3a, 0x8b, 0x2c, 0x5e, 0x47, + 0x44, 0x49, 0x45, 0x62, 0x28, 0x8b, 0x2f, 0x8b, 0xfb, 0x1a, 0xea, 0x27, + 0xf7, 0x13, 0x8b, 0xde, 0x8b, 0xe7, 0xb7, 0xd0, 0xd3, 0xd0, 0xd3, 0xb2, + 0xeb, 0x8b, 0xeb, 0x8b, 0xf7, 0x18, 0x2c, 0xee, 0xfb, 0x14, 0x8b, 0x08, + 0x76, 0x27, 0x15, 0xdc, 0xc7, 0x49, 0x32, 0xfb, 0x17, 0xfb, 0x04, 0xfb, + 0x11, 0xfb, 0x09, 0x3b, 0x50, 0xce, 0xe5, 0xf7, 0x14, 0xf7, 0x04, 0xf7, + 0x12, 0xf7, 0x07, 0x1f, 0xc2, 0xf7, 0x91, 0x15, 0xe7, 0x2a, 0x05, 0x94, + 0x82, 0x92, 0x87, 0x94, 0x8b, 0xa1, 0x8b, 0xa0, 0xa0, 0x8b, 0xa1, 0x8b, + 0x95, 0x8b, 0x8b, 0x7a, 0x9d, 0x08, 0xfb, 0x10, 0xf7, 0x14, 0xfb, 0x48, + 0xfb, 0x14, 0x05, 0x6f, 0x77, 0x87, 0x85, 0x8b, 0x7a, 0x8b, 0x7b, 0x97, + 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x94, 0x8f, 0x98, 0x94, 0x08, 0xf7, 0x1a, + 0xec, 0x05, 0x0e, 0xf8, 0x3e, 0xf8, 0xe9, 0x15, 0x3a, 0x8b, 0x2c, 0x5e, + 0x47, 0x44, 0x49, 0x45, 0x62, 0x28, 0x8b, 0x2f, 0x8b, 0xfb, 0x1b, 0xe9, + 0x28, 0xf7, 0x14, 0x8b, 0xde, 0x8b, 0xe7, 0xb7, 0xd0, 0xd3, 0xd0, 0xd3, + 0xb2, 0xeb, 0x8b, 0xeb, 0x08, 0xf7, 0x18, 0x2c, 0xee, 0xfb, 0x14, 0x1e, + 0x76, 0x27, 0x15, 0xdc, 0xc7, 0x49, 0x32, 0xfb, 0x17, 0xfb, 0x04, 0xfb, + 0x11, 0xfb, 0x09, 0x3b, 0x50, 0xce, 0xe5, 0xf7, 0x14, 0xf7, 0x04, 0xf7, + 0x12, 0xf7, 0x07, 0x1f, 0xf7, 0x74, 0xf7, 0xc2, 0x15, 0x7f, 0x8b, 0x7c, + 0x81, 0x79, 0x78, 0x6f, 0x6d, 0x86, 0x87, 0x7c, 0x8b, 0x80, 0x8b, 0x7e, + 0x91, 0x6f, 0x9f, 0x08, 0x5f, 0xa8, 0x7b, 0x93, 0x74, 0x8b, 0x6e, 0x8b, + 0x6b, 0x7c, 0x6c, 0x6d, 0x70, 0x72, 0x7e, 0x77, 0x8b, 0x7b, 0x8b, 0x7e, + 0x96, 0x81, 0x99, 0x8b, 0x94, 0x8b, 0x95, 0x90, 0x92, 0x92, 0xb4, 0xb5, + 0x94, 0x91, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x93, 0x87, 0xa3, 0x7a, 0x08, + 0xb1, 0x6f, 0xa9, 0x7d, 0xa1, 0x8b, 0xac, 0x8b, 0xa8, 0x9c, 0xb4, 0xb7, + 0x9f, 0xa1, 0x94, 0x99, 0x8b, 0x97, 0x8b, 0x97, 0x7e, 0x96, 0x7d, 0x8b, + 0x08, 0x0e, 0xf8, 0x69, 0xf9, 0x6d, 0x15, 0x2e, 0xec, 0x05, 0x81, 0x95, + 0x85, 0x8e, 0x81, 0x8b, 0x76, 0x8b, 0x75, 0x76, 0x8b, 0x75, 0x8b, 0x83, + 0x8d, 0x86, 0x96, 0x81, 0x08, 0x90, 0x86, 0xf7, 0x11, 0xfb, 0x14, 0xf7, + 0x46, 0xf7, 0x14, 0x96, 0x93, 0x05, 0x9a, 0x95, 0x91, 0x96, 0x8b, 0x98, + 0x8b, 0x9c, 0x7f, 0x97, 0x7b, 0x8b, 0x82, 0x8b, 0x82, 0x87, 0x7e, 0x82, + 0x08, 0xfb, 0x18, 0x2a, 0x05, 0xf7, 0x34, 0xfb, 0x5a, 0x15, 0x90, 0x9f, + 0x8b, 0x8d, 0x8b, 0x93, 0x8b, 0xa0, 0x7b, 0x9a, 0x74, 0x8b, 0x77, 0x8b, + 0x80, 0x83, 0x7b, 0x72, 0x6d, 0xa1, 0x61, 0x96, 0x58, 0x8b, 0xfb, 0x21, + 0x8b, 0xfb, 0x09, 0x2b, 0x8b, 0xfb, 0x08, 0x8b, 0x62, 0xa1, 0x63, 0xad, + 0x74, 0x08, 0xa7, 0x79, 0xa9, 0x81, 0xcb, 0x80, 0xd0, 0x7e, 0x9f, 0x85, + 0x9b, 0x7e, 0x98, 0x81, 0x92, 0x7e, 0x8b, 0x7d, 0x8b, 0x5b, 0x47, 0x64, + 0x39, 0x8b, 0x49, 0x8b, 0x52, 0xa8, 0x88, 0xaf, 0x89, 0xa6, 0x8b, 0x8b, + 0x86, 0x92, 0x08, 0x84, 0x94, 0x7f, 0x90, 0x7e, 0x8b, 0x68, 0x8b, 0x77, + 0x76, 0x81, 0x5e, 0x08, 0x7d, 0x49, 0x05, 0x89, 0x7f, 0x89, 0x80, 0x8b, + 0x85, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, 0x94, 0x90, 0xa0, + 0x9e, 0xb7, 0x71, 0xbd, 0x7e, 0xc1, 0x8b, 0xf7, 0x2f, 0x8b, 0xf7, 0x07, + 0xe6, 0x8b, 0xf7, 0x0e, 0x8b, 0xbb, 0x70, 0xb4, 0x5e, 0xa0, 0x08, 0x71, + 0x97, 0x6f, 0x93, 0x53, 0x96, 0x3f, 0x9a, 0x81, 0x8e, 0x7c, 0x97, 0x7f, + 0x95, 0x83, 0x9b, 0x8b, 0x9a, 0x08, 0xb9, 0xc8, 0xb3, 0xd1, 0xc9, 0xb5, + 0x70, 0x63, 0x1e, 0x8c, 0x6b, 0x8b, 0x8b, 0x90, 0x83, 0x92, 0x83, 0x98, + 0x85, 0x98, 0x8b, 0x9a, 0x8b, 0x9c, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8f, + 0x93, 0x91, 0xa7, 0x08, 0x9d, 0xe3, 0x05, 0x0e, 0xf9, 0x0c, 0xf8, 0x77, + 0x15, 0xa4, 0x8b, 0x96, 0x8f, 0x99, 0x96, 0x99, 0x96, 0x94, 0x9d, 0x8b, + 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, + 0x8b, 0x08, 0xfb, 0x15, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, + 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xae, + 0x8b, 0x4e, 0xfb, 0xb3, 0x05, 0x7e, 0x4e, 0x47, 0x5a, 0x44, 0x8b, 0x4d, + 0x8b, 0x5d, 0xb1, 0x8b, 0xbf, 0x8b, 0x91, 0x8c, 0x92, 0x8c, 0x92, 0x08, + 0xc8, 0xf7, 0xb3, 0xae, 0x8b, 0x05, 0xa9, 0x8b, 0x96, 0x8e, 0x99, 0x97, + 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, + 0x83, 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x6c, 0x8b, + 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, + 0x9a, 0x7f, 0xaf, 0x1e, 0x50, 0xfb, 0xaa, 0x05, 0x88, 0x7a, 0x89, 0x7c, + 0x8b, 0x7c, 0x8b, 0x28, 0xda, 0x42, 0xf7, 0x01, 0x8b, 0xf7, 0x15, 0x8b, + 0xf7, 0x0c, 0xea, 0xa5, 0xf7, 0x10, 0x08, 0xc6, 0xf7, 0xaa, 0x05, 0xfb, + 0x9e, 0xf7, 0xcf, 0x15, 0x65, 0x67, 0x68, 0x66, 0x70, 0xa0, 0x76, 0xa6, + 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, + 0x65, 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, + 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0x0e, 0xf9, 0x0c, 0xf8, 0x77, 0x15, 0xa4, + 0x8b, 0x96, 0x8f, 0x99, 0x96, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, + 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, + 0xfb, 0x15, 0x06, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, + 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x4e, + 0xfb, 0xb3, 0x05, 0x7e, 0x4e, 0x47, 0x5a, 0x44, 0x8b, 0x4d, 0x8b, 0x5d, + 0xb1, 0x8b, 0xbf, 0x8b, 0x91, 0x8c, 0x92, 0x8c, 0x92, 0x08, 0xc8, 0xf7, + 0xb3, 0xae, 0x8b, 0x05, 0xa9, 0x8b, 0x96, 0x8e, 0x99, 0x97, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8f, + 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfb, 0x16, 0x06, 0x6c, 0x8b, 0x82, 0x89, + 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9a, 0x7f, + 0xaf, 0x1e, 0x50, 0xfb, 0xaa, 0x05, 0x88, 0x7a, 0x89, 0x7c, 0x8b, 0x7c, + 0x8b, 0x28, 0xda, 0x42, 0xf7, 0x01, 0x8b, 0xf7, 0x15, 0x8b, 0xf7, 0x0c, + 0xea, 0xa5, 0xf7, 0x10, 0x08, 0xc6, 0xf7, 0xaa, 0x05, 0x5e, 0xf7, 0xb0, + 0x15, 0xa4, 0x9c, 0x92, 0x95, 0x8b, 0x9b, 0x8b, 0x9c, 0x7e, 0x97, 0x7a, + 0x8b, 0x80, 0x8b, 0x82, 0x87, 0x7b, 0x80, 0x08, 0xfb, 0x32, 0xfb, 0x04, + 0x05, 0x77, 0x7d, 0x81, 0x7d, 0x8b, 0x7d, 0x8b, 0x79, 0x97, 0x7f, 0x9d, + 0x8b, 0x94, 0x8b, 0x95, 0x8f, 0x9a, 0x97, 0x08, 0xf7, 0x32, 0xf7, 0x03, + 0x05, 0x0e, 0xf9, 0x0c, 0xf8, 0x77, 0x15, 0xa4, 0x8b, 0x96, 0x8f, 0x99, + 0x96, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, + 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x15, 0x06, 0x6b, + 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, + 0x6e, 0x9a, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x4e, 0xfb, 0xb3, 0x05, 0x7e, + 0x4e, 0x47, 0x5a, 0x44, 0x8b, 0x4d, 0x8b, 0x5d, 0xb1, 0x8b, 0xbf, 0x8b, + 0x91, 0x8c, 0x92, 0x8c, 0x92, 0x08, 0xc8, 0xf7, 0xb3, 0xae, 0x8b, 0x05, + 0xa9, 0x8b, 0x96, 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, + 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8f, 0x87, 0x8b, 0x75, 0x8b, + 0x08, 0xfb, 0x16, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, + 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9a, 0x7f, 0xaf, 0x1e, 0x50, 0xfb, + 0xaa, 0x05, 0x88, 0x7a, 0x89, 0x7c, 0x8b, 0x7c, 0x8b, 0x28, 0xda, 0x42, + 0xf7, 0x01, 0x8b, 0xf7, 0x15, 0x8b, 0xf7, 0x0c, 0xea, 0xa5, 0xf7, 0x10, + 0x08, 0xc6, 0xf7, 0xaa, 0x05, 0xfb, 0x7d, 0xf7, 0xe9, 0x15, 0x7f, 0x97, + 0x85, 0x8e, 0x80, 0x8b, 0x74, 0x8b, 0x75, 0x76, 0x8b, 0x74, 0x8b, 0x83, + 0x90, 0x81, 0x95, 0x81, 0x08, 0xf7, 0x03, 0xfb, 0x03, 0x05, 0x95, 0x80, + 0x94, 0x86, 0x94, 0x8b, 0xa2, 0x8b, 0xa2, 0xa0, 0x8b, 0xa1, 0x8b, 0x94, + 0x86, 0x94, 0x80, 0x96, 0x08, 0xfb, 0x02, 0xf7, 0x04, 0x05, 0x0e, 0xf9, + 0x0c, 0xf8, 0x77, 0x15, 0xa4, 0x8b, 0x96, 0x8f, 0x99, 0x96, 0x99, 0x96, + 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x15, 0x06, 0x6b, 0x8b, 0x83, 0x89, + 0x7c, 0x7f, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9a, 0x80, + 0xb4, 0x1e, 0xae, 0x8b, 0x4e, 0xfb, 0xb3, 0x05, 0x7e, 0x4e, 0x47, 0x5a, + 0x44, 0x8b, 0x4d, 0x8b, 0x5d, 0xb1, 0x8b, 0xbf, 0x8b, 0x91, 0x8c, 0x92, + 0x8c, 0x92, 0x08, 0xc8, 0xf7, 0xb3, 0xae, 0x8b, 0x05, 0xa9, 0x8b, 0x96, + 0x8e, 0x99, 0x97, 0x99, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, + 0x9b, 0x7e, 0x8f, 0x83, 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfb, 0x16, + 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6f, 0x9a, 0x7f, 0xaf, 0x1e, 0x50, 0xfb, 0xaa, 0x05, 0x88, + 0x7a, 0x89, 0x7c, 0x8b, 0x7c, 0x8b, 0x28, 0xda, 0x42, 0xf7, 0x01, 0x8b, + 0xf7, 0x15, 0x8b, 0xf7, 0x0c, 0xea, 0xa5, 0xf7, 0x10, 0x08, 0xc6, 0xf7, + 0xaa, 0x05, 0xfb, 0x3f, 0xf7, 0x9f, 0x15, 0xe6, 0x2a, 0x05, 0x94, 0x82, + 0x93, 0x87, 0x94, 0x8b, 0xa0, 0x8b, 0xa1, 0xa0, 0x8b, 0xa1, 0x8b, 0x93, + 0x89, 0x90, 0x83, 0x92, 0x89, 0x8e, 0x88, 0x8d, 0x88, 0x8e, 0x08, 0xfb, + 0x0f, 0xf7, 0x14, 0xfb, 0x48, 0xfb, 0x14, 0x05, 0x70, 0x78, 0x86, 0x84, + 0x8b, 0x7b, 0x8b, 0x7a, 0x97, 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x93, 0x8e, + 0x99, 0x95, 0x08, 0xf7, 0x1a, 0xec, 0x05, 0x0e, 0xf8, 0xe2, 0xf9, 0x93, + 0x15, 0xa3, 0x9c, 0x93, 0x95, 0x8b, 0x9b, 0x8b, 0x9c, 0x7e, 0x97, 0x7a, + 0x8b, 0x80, 0x8b, 0x82, 0x87, 0x7b, 0x80, 0x08, 0xfb, 0x32, 0xfb, 0x04, + 0x05, 0x77, 0x7d, 0x81, 0x7d, 0x8b, 0x7c, 0x8b, 0x7a, 0x97, 0x7f, 0x9d, + 0x8b, 0x94, 0x8b, 0x95, 0x8f, 0x9b, 0x97, 0x08, 0xf7, 0x31, 0xf7, 0x03, + 0x05, 0xfb, 0x50, 0xfc, 0x9e, 0x15, 0xf7, 0x6b, 0xf7, 0x82, 0x8e, 0x8b, + 0x05, 0xa4, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, + 0x8b, 0x08, 0x2e, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7e, + 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x77, 0x93, 0x80, 0xa1, 0x82, 0x08, 0xfb, + 0x0f, 0xfb, 0x1b, 0x49, 0xf7, 0x1b, 0x05, 0xac, 0x98, 0x9c, 0xa0, 0x8b, + 0xa6, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, + 0x8b, 0x08, 0x31, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, + 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x71, 0x9c, 0x7d, 0xaa, 0x1e, 0x91, 0x8b, + 0xf7, 0x06, 0xfb, 0x82, 0x6d, 0xfb, 0x25, 0x49, 0x8b, 0x05, 0x6c, 0x8b, + 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, + 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x7b, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, + 0x96, 0x99, 0x96, 0x94, 0x9e, 0x8b, 0x9b, 0x8b, 0x9a, 0x82, 0x9b, 0x7e, + 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x4a, 0x8b, 0xa9, 0xf7, + 0x25, 0x05, 0x0e, 0xf7, 0x72, 0xef, 0x15, 0xf8, 0x15, 0xf8, 0x16, 0xa0, + 0xec, 0xfc, 0x2c, 0x8b, 0x67, 0xfb, 0x3e, 0x05, 0x86, 0x78, 0x8b, 0x89, + 0x8b, 0x83, 0x8b, 0x77, 0x9d, 0x7a, 0xa1, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, + 0x98, 0x98, 0x94, 0x94, 0x8f, 0x95, 0x91, 0xa5, 0x08, 0x9a, 0xd1, 0xf7, + 0x46, 0x8b, 0xfc, 0x13, 0xfc, 0x13, 0x76, 0x27, 0xf8, 0x5a, 0x8b, 0xaf, + 0xf7, 0x40, 0x05, 0x90, 0x9e, 0x8b, 0x8d, 0x8b, 0x92, 0x8b, 0xa1, 0x7a, + 0x9b, 0x74, 0x8b, 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7f, 0x81, 0x81, 0x87, + 0x80, 0x85, 0x72, 0x08, 0x7c, 0x43, 0xfb, 0x76, 0x8b, 0x05, 0xf7, 0x7e, + 0xf9, 0x09, 0x15, 0x2e, 0xec, 0x05, 0x81, 0x94, 0x84, 0x8f, 0x82, 0x8b, + 0x76, 0x8b, 0x75, 0x76, 0x8b, 0x75, 0x8b, 0x83, 0x8d, 0x86, 0x96, 0x81, + 0x08, 0x90, 0x86, 0xf7, 0x11, 0xfb, 0x14, 0xf7, 0x46, 0xf7, 0x14, 0x05, + 0xa6, 0x9e, 0x90, 0x92, 0x8b, 0x9c, 0x8b, 0x9b, 0x7f, 0x97, 0x7b, 0x8b, + 0x82, 0x8b, 0x82, 0x87, 0x7e, 0x82, 0x08, 0xfb, 0x18, 0x2a, 0x05, 0x0e, + 0xf7, 0x74, 0xf7, 0x20, 0x15, 0xed, 0x06, 0xf2, 0x8b, 0xc4, 0x9c, 0xbb, + 0xb7, 0xaf, 0xac, 0xa1, 0xb8, 0x8b, 0xb5, 0x8b, 0xb0, 0x77, 0xaf, 0x6a, + 0xa0, 0x6b, 0x9f, 0x61, 0x93, 0x41, 0x8b, 0x08, 0x29, 0x8b, 0x93, 0xb3, + 0xee, 0x8b, 0x05, 0xaa, 0x8b, 0x94, 0x8e, 0x9a, 0x97, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9b, 0x08, 0xa8, 0x7b, 0x96, 0x62, 0x1e, 0xfb, 0x69, 0x06, + 0x6e, 0x8b, 0x7f, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, + 0x8b, 0x7b, 0x94, 0x7b, 0x98, 0x87, 0x93, 0x88, 0x91, 0x8a, 0x9f, 0x8b, + 0x08, 0x9a, 0x8b, 0x3a, 0xfc, 0x13, 0x7c, 0x8b, 0x05, 0x6c, 0x8b, 0x81, + 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, + 0x7f, 0xb4, 0x1e, 0xf7, 0x69, 0x06, 0xa7, 0x8b, 0x99, 0x8f, 0x99, 0x96, + 0x99, 0x96, 0x94, 0x9e, 0x8b, 0x9b, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, + 0x82, 0x8e, 0x85, 0x8c, 0x76, 0x8b, 0x08, 0x29, 0x8b, 0x93, 0xb3, 0x05, + 0xa1, 0xef, 0x15, 0xa0, 0xf2, 0xf7, 0x17, 0x8b, 0x05, 0xc8, 0xa4, 0x7f, + 0x6e, 0x62, 0x67, 0x76, 0x43, 0x1f, 0xfb, 0x16, 0x06, 0x0e, 0xf8, 0x02, + 0xf9, 0xb2, 0x15, 0x65, 0x67, 0x68, 0x66, 0x70, 0xa0, 0x76, 0xa6, 0xb1, + 0xb0, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x65, + 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, + 0x77, 0x9f, 0x6e, 0x1f, 0xfb, 0x40, 0xfc, 0xbd, 0x15, 0xf7, 0x6b, 0xf7, + 0x82, 0x8e, 0x8b, 0x05, 0xa4, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x2e, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, + 0x80, 0x7d, 0x7e, 0x82, 0x7a, 0x8b, 0x7b, 0x8b, 0x77, 0x93, 0x80, 0xa1, + 0x82, 0x08, 0xfb, 0x0f, 0xfb, 0x1b, 0x49, 0xf7, 0x1b, 0x05, 0xac, 0x98, + 0x9c, 0xa0, 0x8b, 0xa6, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x31, 0x06, 0x6c, 0x8b, 0x82, 0x89, 0x7c, + 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x71, 0x9c, 0x7d, 0xaa, + 0x1e, 0x91, 0x8b, 0xf7, 0x06, 0xfb, 0x82, 0x6d, 0xfb, 0x25, 0x49, 0x8b, + 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0x7b, 0x06, 0xa7, 0x8b, + 0x98, 0x8f, 0x99, 0x96, 0x99, 0x96, 0x94, 0x9e, 0x8b, 0x9b, 0x8b, 0x9a, + 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x4a, + 0x8b, 0xa9, 0xf7, 0x25, 0x05, 0x0e, 0xf8, 0x18, 0x16, 0xf7, 0x09, 0x06, + 0xa8, 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, + 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, + 0x08, 0x7a, 0x8b, 0xb6, 0xf7, 0x5e, 0x05, 0x8e, 0x97, 0x8c, 0x95, 0x8b, + 0x97, 0x8b, 0xd2, 0x4b, 0xb6, 0x23, 0x8b, 0x55, 0x8b, 0x2d, 0x7b, 0x66, + 0x7b, 0x75, 0x81, 0x7e, 0x79, 0x8b, 0x74, 0x8b, 0x73, 0x9b, 0x7b, 0xa1, + 0x8b, 0x96, 0x8b, 0x99, 0x8d, 0x9c, 0x8f, 0x08, 0xb9, 0x96, 0xb5, 0x91, + 0xab, 0x8b, 0xc4, 0x8b, 0xa6, 0x7f, 0x8b, 0x70, 0x8b, 0x85, 0x8b, 0x8b, + 0x8a, 0x87, 0x08, 0x86, 0x74, 0x05, 0x64, 0x92, 0x6d, 0x8e, 0x6b, 0x8b, + 0x25, 0x8b, 0x35, 0x68, 0x56, 0x4c, 0x71, 0x6c, 0x7d, 0x6b, 0x8b, 0x6e, + 0x08, 0x49, 0xcc, 0x5b, 0xe4, 0x1e, 0xc6, 0x8b, 0xc9, 0x99, 0xc0, 0xa4, + 0x08, 0x86, 0x74, 0x05, 0xa9, 0xf7, 0x1b, 0x15, 0x4c, 0x69, 0x50, 0x7a, + 0x54, 0x8b, 0x65, 0x8b, 0x6e, 0x9a, 0x8b, 0x9e, 0x8b, 0x97, 0x93, 0x97, + 0x9b, 0x99, 0xab, 0xa5, 0xb4, 0x99, 0xbc, 0x8b, 0xad, 0x8b, 0xaf, 0x87, + 0xb1, 0x84, 0x08, 0x81, 0x59, 0x05, 0x2d, 0xf8, 0x9b, 0x15, 0x65, 0x67, + 0x68, 0x66, 0x70, 0xa0, 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, + 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x65, 0x67, 0x68, 0x66, 0x6f, 0xa0, + 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0x0e, + 0xf8, 0x19, 0x16, 0xf7, 0x09, 0x06, 0xa7, 0x8b, 0x98, 0x8e, 0x98, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, + 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x7b, 0x8b, 0xb6, 0xf7, 0x5e, + 0x05, 0x8d, 0x97, 0x8d, 0x99, 0x8b, 0x94, 0x8b, 0xd1, 0x4b, 0xb6, 0x23, + 0x8b, 0x54, 0x8b, 0x2a, 0x7a, 0x68, 0x7b, 0x77, 0x82, 0x7e, 0x78, 0x8b, + 0x74, 0x8b, 0x74, 0x9b, 0x7b, 0xa1, 0x8b, 0x96, 0x8b, 0x99, 0x8d, 0x9c, + 0x8f, 0x08, 0xb9, 0x96, 0xb5, 0x91, 0xab, 0x8b, 0x08, 0xc5, 0xa5, 0x7f, + 0x70, 0x1f, 0x8a, 0x81, 0x86, 0x74, 0x05, 0x64, 0x92, 0x6c, 0x8e, 0x6b, + 0x8b, 0x25, 0x8b, 0x36, 0x68, 0x56, 0x4c, 0x71, 0x6c, 0x7d, 0x6b, 0x8b, + 0x6e, 0x08, 0x49, 0xcc, 0x5b, 0xe4, 0x1e, 0xc5, 0x8b, 0xca, 0x99, 0xc0, + 0xa4, 0x08, 0x86, 0x74, 0x05, 0xa8, 0xf7, 0x1b, 0x15, 0x4d, 0x69, 0x4f, + 0x7a, 0x55, 0x8b, 0x08, 0x64, 0x6e, 0x9a, 0x9e, 0xb1, 0xd6, 0xb3, 0xd3, + 0x1f, 0xad, 0x8b, 0xae, 0x87, 0xb2, 0x84, 0x08, 0x80, 0x59, 0x05, 0xf7, + 0x1b, 0xf8, 0x7d, 0x15, 0xa2, 0x9b, 0x93, 0x96, 0x8b, 0x9b, 0x8b, 0x9c, + 0x7f, 0x97, 0x79, 0x8b, 0x80, 0x8b, 0x85, 0x88, 0x79, 0x7e, 0x08, 0xfb, + 0x32, 0xfb, 0x03, 0x05, 0x75, 0x7b, 0x82, 0x7e, 0x8b, 0x7d, 0x8b, 0x7a, + 0x98, 0x7e, 0x9c, 0x8b, 0x95, 0x8b, 0x93, 0x8f, 0x9d, 0x97, 0x08, 0xf7, + 0x31, 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa8, + 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, + 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, + 0x7a, 0x8b, 0xb6, 0xf7, 0x5e, 0x05, 0x8e, 0x97, 0x8c, 0x95, 0x8b, 0x98, + 0x8b, 0xd1, 0x4b, 0xb6, 0x23, 0x8b, 0x54, 0x8b, 0x29, 0x7a, 0x69, 0x7b, + 0x77, 0x82, 0x7e, 0x77, 0x8b, 0x75, 0x8b, 0x74, 0x9b, 0x7b, 0xa1, 0x8b, + 0x96, 0x8b, 0x99, 0x8d, 0x9c, 0x8f, 0x08, 0xb9, 0x96, 0xb5, 0x91, 0xab, + 0x8b, 0xc4, 0x8b, 0xa6, 0x7f, 0x8b, 0x70, 0x8b, 0x85, 0x8b, 0x8b, 0x8a, + 0x87, 0x08, 0x86, 0x74, 0x05, 0x64, 0x92, 0x6d, 0x8e, 0x6b, 0x8b, 0x25, + 0x8b, 0x35, 0x68, 0x56, 0x4c, 0x71, 0x6c, 0x7d, 0x6b, 0x8b, 0x6e, 0x08, + 0x49, 0xcc, 0x5b, 0xe4, 0x1e, 0xc6, 0x8b, 0xc9, 0x99, 0xc0, 0xa4, 0x08, + 0x86, 0x74, 0x05, 0xa9, 0xf7, 0x1b, 0x15, 0x4c, 0x69, 0x50, 0x7a, 0x54, + 0x8b, 0x65, 0x8b, 0x6e, 0x9a, 0x8b, 0x9e, 0x8b, 0x97, 0x93, 0x97, 0x9b, + 0x99, 0xab, 0xa5, 0xb4, 0x99, 0xbc, 0x8b, 0xad, 0x8b, 0xaf, 0x87, 0xb1, + 0x84, 0x08, 0x81, 0x59, 0x05, 0x48, 0xf8, 0xb5, 0x15, 0x7e, 0x98, 0x86, + 0x8e, 0x80, 0x8b, 0x73, 0x8b, 0x75, 0x76, 0x8b, 0x74, 0x8b, 0x82, 0x90, + 0x83, 0x96, 0x80, 0x08, 0xf7, 0x03, 0xfb, 0x04, 0x05, 0x97, 0x7f, 0x92, + 0x87, 0x94, 0x8b, 0xa3, 0x8b, 0xa1, 0xa0, 0x8b, 0xa2, 0x8b, 0x94, 0x86, + 0x94, 0x80, 0x96, 0x08, 0xfb, 0x02, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x18, + 0x16, 0xf7, 0x09, 0x06, 0xa8, 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x99, 0x97, + 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x7a, 0x8b, 0xb6, 0xf7, 0x5e, 0x05, 0x8e, + 0x97, 0x8c, 0x95, 0x8b, 0x98, 0x8b, 0xd1, 0x4b, 0xb6, 0x23, 0x8b, 0x54, + 0x8b, 0x29, 0x7a, 0x69, 0x7b, 0x77, 0x82, 0x7e, 0x77, 0x8b, 0x75, 0x8b, + 0x74, 0x9b, 0x7b, 0xa1, 0x8b, 0x96, 0x8b, 0x99, 0x8d, 0x9c, 0x8f, 0x08, + 0xb9, 0x96, 0xb5, 0x91, 0xab, 0x8b, 0xc4, 0x8b, 0xa6, 0x7f, 0x8b, 0x70, + 0x8b, 0x85, 0x8b, 0x8b, 0x8a, 0x87, 0x08, 0x86, 0x74, 0x05, 0x64, 0x92, + 0x6d, 0x8e, 0x6b, 0x8b, 0x25, 0x8b, 0x35, 0x68, 0x56, 0x4c, 0x71, 0x6c, + 0x7d, 0x6b, 0x8b, 0x6e, 0x08, 0x49, 0xcc, 0x5b, 0xe4, 0x1e, 0xc6, 0x8b, + 0xc9, 0x99, 0xc0, 0xa4, 0x08, 0x86, 0x74, 0x05, 0xa9, 0xf7, 0x1b, 0x15, + 0x4c, 0x69, 0x50, 0x7a, 0x54, 0x8b, 0x65, 0x8b, 0x6e, 0x9a, 0x8b, 0x9e, + 0x8b, 0x97, 0x93, 0x97, 0x9b, 0x99, 0xab, 0xa5, 0xb4, 0x99, 0xbc, 0x8b, + 0xad, 0x8b, 0xaf, 0x87, 0xb1, 0x84, 0x08, 0x81, 0x59, 0x05, 0x8d, 0xf8, + 0x6c, 0x15, 0xe6, 0x2a, 0x05, 0x94, 0x82, 0x93, 0x87, 0x94, 0x8b, 0xa0, + 0x8b, 0xa1, 0xa0, 0x8b, 0xa1, 0x8b, 0x93, 0x89, 0x90, 0x83, 0x92, 0x08, + 0x83, 0x92, 0xfb, 0x0f, 0xf7, 0x15, 0xfb, 0x48, 0xfb, 0x15, 0x05, 0x71, + 0x79, 0x85, 0x83, 0x8b, 0x7b, 0x8b, 0x7b, 0x97, 0x7f, 0x9b, 0x8b, 0x94, + 0x8b, 0x94, 0x8f, 0x97, 0x94, 0x08, 0xf7, 0x1b, 0xec, 0x05, 0x0e, 0xf8, + 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa7, 0x8b, 0x99, 0x8e, 0x98, 0x97, 0x99, + 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, + 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x7b, 0x8b, 0xb6, 0xf7, 0x5e, 0x05, + 0x8e, 0x97, 0x8c, 0x98, 0x8b, 0x95, 0x8b, 0xd1, 0x4b, 0xb6, 0x23, 0x8b, + 0x54, 0x8b, 0x29, 0x7a, 0x69, 0x7b, 0x77, 0x82, 0x7e, 0x77, 0x8b, 0x75, + 0x8b, 0x74, 0x9b, 0x7b, 0xa1, 0x8b, 0x96, 0x8b, 0x99, 0x8d, 0x9c, 0x8f, + 0x08, 0xb9, 0x96, 0xb5, 0x91, 0xab, 0x8b, 0xc5, 0x8b, 0xa5, 0x7f, 0x8b, + 0x70, 0x8b, 0x88, 0x8b, 0x88, 0x8a, 0x87, 0x08, 0x86, 0x74, 0x05, 0x64, + 0x92, 0x6c, 0x8e, 0x6b, 0x8b, 0x26, 0x8b, 0x35, 0x68, 0x56, 0x4c, 0x71, + 0x6c, 0x7d, 0x6b, 0x8b, 0x6e, 0x08, 0x49, 0xcc, 0x5b, 0xe4, 0x1e, 0xc5, + 0x8b, 0xca, 0x99, 0xc0, 0xa4, 0x08, 0x86, 0x74, 0x05, 0xa9, 0xf7, 0x1b, + 0x15, 0x4c, 0x69, 0x50, 0x7a, 0x54, 0x8b, 0x08, 0x64, 0x6e, 0x9a, 0x9e, + 0xb1, 0xd6, 0xb3, 0xd3, 0x1f, 0xad, 0x8b, 0xaf, 0x87, 0xb1, 0x84, 0x08, + 0x81, 0x59, 0x05, 0xf7, 0x3c, 0xf8, 0x9d, 0x15, 0x80, 0x8b, 0x79, 0x80, + 0x7f, 0x7d, 0x6b, 0x68, 0x86, 0x87, 0x7b, 0x8b, 0x80, 0x8b, 0x7e, 0x91, + 0x6f, 0x9f, 0x08, 0x60, 0xa9, 0x7a, 0x93, 0x75, 0x8b, 0x6e, 0x8b, 0x6c, + 0x7c, 0x6c, 0x6e, 0x70, 0x71, 0x7d, 0x76, 0x8b, 0x7b, 0x8b, 0x7f, 0x96, + 0x80, 0x99, 0x8b, 0x94, 0x8b, 0x95, 0x90, 0x92, 0x92, 0xb5, 0xb6, 0x93, + 0x91, 0x9d, 0x8b, 0x08, 0x99, 0x8b, 0x93, 0x87, 0xa3, 0x7a, 0x08, 0xb1, + 0x6e, 0xa8, 0x7d, 0xa1, 0x8b, 0xac, 0x8b, 0xa8, 0x9c, 0xb4, 0xb7, 0x9f, + 0xa1, 0x94, 0x9a, 0x8b, 0x97, 0x8b, 0x97, 0x7e, 0x96, 0x7e, 0x8b, 0x08, + 0x0e, 0xf8, 0x18, 0x16, 0xf7, 0x09, 0x06, 0xa8, 0x8b, 0x98, 0x8e, 0x98, + 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, + 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x7a, 0x8b, 0xb6, 0xf7, + 0x5e, 0x05, 0x8e, 0x97, 0x8c, 0x95, 0x8b, 0x98, 0x8b, 0xd1, 0x4b, 0xb6, + 0x23, 0x8b, 0x54, 0x8b, 0x29, 0x7a, 0x69, 0x7b, 0x77, 0x82, 0x7e, 0x77, + 0x8b, 0x75, 0x8b, 0x74, 0x9b, 0x7b, 0xa1, 0x8b, 0x96, 0x8b, 0x99, 0x8d, + 0x9c, 0x8f, 0x08, 0xb9, 0x96, 0xb5, 0x91, 0xab, 0x8b, 0xc4, 0x8b, 0xa6, + 0x7f, 0x8b, 0x70, 0x8b, 0x85, 0x8b, 0x8b, 0x8a, 0x87, 0x08, 0x86, 0x74, + 0x05, 0x64, 0x92, 0x6d, 0x8e, 0x6b, 0x8b, 0x25, 0x8b, 0x35, 0x68, 0x56, + 0x4c, 0x71, 0x6c, 0x7d, 0x6b, 0x8b, 0x6e, 0x08, 0x49, 0xcc, 0x5b, 0xe4, + 0x1e, 0xc6, 0x8b, 0xc9, 0x99, 0xc0, 0xa4, 0x08, 0x86, 0x74, 0x05, 0xa9, + 0xf7, 0x1b, 0x15, 0x4c, 0x69, 0x50, 0x7a, 0x54, 0x8b, 0x65, 0x8b, 0x6e, + 0x9a, 0x8b, 0x9e, 0x8b, 0x97, 0x93, 0x97, 0x9b, 0x99, 0xab, 0xa5, 0xb4, + 0x99, 0xbc, 0x8b, 0xad, 0x8b, 0xaf, 0x87, 0xb1, 0x84, 0x08, 0x81, 0x59, + 0x05, 0xa4, 0xf8, 0xe4, 0x15, 0x40, 0x40, 0x44, 0x42, 0x53, 0xb5, 0x62, + 0xc4, 0x1f, 0xd8, 0xd6, 0xd2, 0xd3, 0xc5, 0x62, 0xb3, 0x4f, 0x1f, 0x81, + 0x56, 0x15, 0xad, 0xa2, 0x74, 0x6b, 0x63, 0x60, 0x64, 0x60, 0x6b, 0x73, + 0xa2, 0xaa, 0xb3, 0xb5, 0xb3, 0xb6, 0x1f, 0x0e, 0xf7, 0xe6, 0x7b, 0x15, + 0xd2, 0x8d, 0xbf, 0x96, 0xb6, 0x9e, 0xbf, 0xa3, 0xa8, 0xa9, 0x8b, 0xa8, + 0x8b, 0xa3, 0x7a, 0x9c, 0x73, 0x8b, 0x80, 0x8b, 0x81, 0x87, 0x80, 0x83, + 0x5b, 0x69, 0x67, 0x81, 0x3b, 0x8b, 0x24, 0x8b, 0x59, 0xaa, 0x8b, 0xcb, + 0x08, 0x8b, 0xad, 0x9a, 0xb1, 0xa3, 0xaa, 0xb0, 0xb9, 0xbd, 0xa1, 0xcb, + 0x8b, 0xb6, 0x8b, 0xae, 0x82, 0xa1, 0x7b, 0x96, 0x82, 0x8f, 0x81, 0x8b, + 0x7a, 0x8b, 0x76, 0x8d, 0x85, 0x90, 0x84, 0x92, 0x83, 0x99, 0x85, 0x98, + 0x8b, 0x08, 0x9b, 0x8b, 0x9c, 0x93, 0x97, 0x97, 0x94, 0x95, 0x90, 0x95, + 0x90, 0xa5, 0x08, 0x9b, 0xd8, 0x05, 0x90, 0x9f, 0x8b, 0x8d, 0x8b, 0x94, + 0x8b, 0xa0, 0x7a, 0x99, 0x74, 0x8b, 0x77, 0x8b, 0x7f, 0x82, 0x80, 0x76, + 0x68, 0x9f, 0x5d, 0x95, 0x53, 0x8b, 0x2f, 0x8b, 0x3a, 0x69, 0x4f, 0x4a, + 0x59, 0x55, 0x6c, 0x41, 0x8b, 0x48, 0x08, 0x8b, 0x41, 0xb6, 0x4f, 0xd1, + 0x73, 0x9f, 0x85, 0x99, 0x88, 0xa8, 0x88, 0x08, 0x79, 0x33, 0x05, 0x94, + 0x8c, 0x91, 0x8c, 0x8f, 0x8b, 0x08, 0xac, 0x9b, 0x82, 0x78, 0x78, 0x7b, + 0x7f, 0x71, 0x1f, 0x7b, 0x8b, 0x75, 0x92, 0x7c, 0x95, 0x7b, 0x95, 0x88, + 0x8c, 0x84, 0x8b, 0x08, 0x74, 0x76, 0x76, 0x75, 0x6e, 0xbf, 0x71, 0xc5, + 0xd0, 0xc5, 0xc2, 0xcc, 0x1f, 0x8b, 0xb3, 0x7b, 0x9e, 0x61, 0x93, 0x08, + 0x91, 0xa5, 0x05, 0x0e, 0xf8, 0xdf, 0xf7, 0x40, 0x15, 0x93, 0xb2, 0x05, + 0x8e, 0x9b, 0x8d, 0x9b, 0x8b, 0x9b, 0x08, 0xf7, 0x08, 0x38, 0xd6, 0xfb, + 0x16, 0xfb, 0x3a, 0xfb, 0x27, 0xfb, 0x18, 0xfb, 0x29, 0xfb, 0x06, 0xdf, + 0x44, 0xf7, 0x1c, 0x1e, 0xdb, 0x8b, 0xf7, 0x08, 0xa0, 0xb6, 0xa2, 0xa0, + 0x96, 0x97, 0x9d, 0x8b, 0xa1, 0x8b, 0xa1, 0x7c, 0x9b, 0x74, 0x8b, 0x82, + 0x8b, 0x7e, 0x89, 0x7e, 0x88, 0x2b, 0x73, 0x70, 0x87, 0x5d, 0x8b, 0x33, + 0x8b, 0x5c, 0xa7, 0x80, 0xc7, 0x08, 0xf8, 0x2d, 0x06, 0xfc, 0x17, 0xe3, + 0x15, 0xa7, 0xc2, 0xcc, 0xae, 0xd5, 0x8b, 0xd3, 0x8b, 0xbe, 0x67, 0x90, + 0x55, 0x08, 0xfb, 0xbb, 0x06, 0xf7, 0x1f, 0xf8, 0x1e, 0x15, 0x65, 0x67, + 0x68, 0x66, 0x70, 0xa0, 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, + 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x65, 0x67, 0x68, 0x66, 0x70, 0xa0, + 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0x0e, + 0xf8, 0xdf, 0xf7, 0x40, 0x15, 0x93, 0xb2, 0x05, 0x8e, 0x9b, 0x8d, 0x9b, + 0x8b, 0x9b, 0x08, 0xf7, 0x08, 0x38, 0xd6, 0xfb, 0x16, 0xfb, 0x3a, 0xfb, + 0x27, 0xfb, 0x18, 0xfb, 0x29, 0xfb, 0x06, 0xdf, 0x44, 0xf7, 0x1c, 0x1e, + 0xdb, 0x8b, 0xf7, 0x08, 0xa0, 0xb6, 0xa2, 0xa0, 0x96, 0x97, 0x9d, 0x8b, + 0xa1, 0x8b, 0xa1, 0x7c, 0x9b, 0x74, 0x8b, 0x82, 0x8b, 0x7e, 0x89, 0x7e, + 0x88, 0x2b, 0x74, 0x6f, 0x86, 0x5f, 0x8b, 0x33, 0x8b, 0x5b, 0xa7, 0x80, + 0xc7, 0x08, 0xf8, 0x2d, 0x06, 0xfc, 0x17, 0xe3, 0x15, 0xa7, 0xc2, 0xcc, + 0xae, 0xd5, 0x8b, 0xd3, 0x8b, 0xbe, 0x67, 0x90, 0x55, 0x08, 0xfb, 0xbb, + 0x06, 0xf8, 0x00, 0xf8, 0x00, 0x15, 0xa1, 0x9a, 0x94, 0x98, 0x8b, 0x9a, + 0x8b, 0x9c, 0x7f, 0x97, 0x79, 0x8b, 0x81, 0x8b, 0x84, 0x88, 0x79, 0x7e, + 0x08, 0xfb, 0x31, 0xfb, 0x03, 0x05, 0x74, 0x7b, 0x82, 0x7f, 0x8b, 0x7c, + 0x8b, 0x79, 0x97, 0x7f, 0x9d, 0x8b, 0x95, 0x8b, 0x93, 0x8f, 0x9d, 0x97, + 0x08, 0xf7, 0x31, 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0xdf, 0xf7, 0x40, 0x15, + 0x93, 0xb2, 0x05, 0x8e, 0x9b, 0x8d, 0x9b, 0x8b, 0x9b, 0x08, 0xf7, 0x08, + 0x38, 0xd6, 0xfb, 0x16, 0xfb, 0x3a, 0xfb, 0x27, 0xfb, 0x18, 0xfb, 0x29, + 0xfb, 0x06, 0xdf, 0x44, 0xf7, 0x1c, 0x1e, 0xdb, 0x8b, 0xf7, 0x08, 0xa0, + 0xb6, 0xa2, 0xa0, 0x96, 0x97, 0x9d, 0x8b, 0xa1, 0x8b, 0xa1, 0x7c, 0x9b, + 0x74, 0x8b, 0x82, 0x8b, 0x7e, 0x89, 0x7e, 0x88, 0x2a, 0x73, 0x71, 0x87, + 0x5d, 0x8b, 0x33, 0x8b, 0x5c, 0xa7, 0x80, 0xc7, 0x08, 0xf8, 0x2d, 0x06, + 0xfc, 0x17, 0xe3, 0x15, 0xa7, 0xc2, 0xcc, 0xae, 0xd5, 0x8b, 0xd3, 0x8b, + 0xbe, 0x67, 0x90, 0x55, 0x08, 0xfb, 0xbb, 0x06, 0xf7, 0x36, 0xf8, 0x38, + 0x15, 0x7f, 0x98, 0x85, 0x8e, 0x81, 0x8b, 0x73, 0x8b, 0x75, 0x76, 0x8b, + 0x73, 0x8b, 0x83, 0x90, 0x83, 0x96, 0x80, 0x08, 0xf7, 0x02, 0xfb, 0x04, + 0x05, 0x98, 0x7f, 0x91, 0x87, 0x94, 0x8b, 0xa3, 0x8b, 0xa1, 0xa0, 0x8b, + 0xa2, 0x8b, 0x94, 0x86, 0x95, 0x81, 0x95, 0x08, 0xfb, 0x03, 0xf7, 0x03, + 0x05, 0x0e, 0xf8, 0xdf, 0xf7, 0x40, 0x15, 0x93, 0xb2, 0x05, 0x8e, 0x9b, + 0x8d, 0x9b, 0x8b, 0x9b, 0x08, 0xf7, 0x08, 0x38, 0xd6, 0xfb, 0x16, 0xfb, + 0x3a, 0xfb, 0x27, 0xfb, 0x18, 0xfb, 0x29, 0xfb, 0x06, 0xdf, 0x44, 0xf7, + 0x1c, 0x1e, 0xdb, 0x8b, 0xf7, 0x08, 0xa0, 0xb6, 0xa2, 0xa0, 0x96, 0x97, + 0x9d, 0x8b, 0xa1, 0x8b, 0xa1, 0x7c, 0x9b, 0x74, 0x8b, 0x82, 0x8b, 0x7e, + 0x89, 0x7e, 0x88, 0x2b, 0x74, 0x70, 0x86, 0x5e, 0x8b, 0x33, 0x8b, 0x5b, + 0xa7, 0x80, 0xc7, 0x08, 0xf8, 0x2d, 0x06, 0xfc, 0x17, 0xe3, 0x15, 0xa7, + 0xc2, 0xcc, 0xae, 0xd5, 0x8b, 0xd3, 0x8b, 0xbe, 0x67, 0x90, 0x55, 0x08, + 0xfb, 0xbb, 0x06, 0xf7, 0x7f, 0xf7, 0xef, 0x15, 0xe6, 0x2a, 0x05, 0x93, + 0x82, 0x94, 0x87, 0x94, 0x8b, 0xa0, 0x8b, 0xa1, 0xa0, 0x8b, 0xa1, 0x8b, + 0x93, 0x89, 0x90, 0x83, 0x92, 0x08, 0x83, 0x92, 0xfb, 0x0f, 0xf7, 0x15, + 0xfb, 0x48, 0xfb, 0x15, 0x05, 0x70, 0x78, 0x86, 0x85, 0x8b, 0x7a, 0x8b, + 0x7b, 0x97, 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x94, 0x8f, 0x98, 0x94, 0x08, + 0xf7, 0x1a, 0xec, 0x05, 0x0e, 0xf8, 0x4f, 0xf8, 0x49, 0x15, 0xfb, 0x46, + 0x06, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb5, 0x1e, 0xd9, 0x8b, 0x58, 0xfb, 0x81, + 0xfb, 0x0d, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, 0x7f, 0xb4, 0x1e, 0xf7, 0xeb, + 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, + 0x8b, 0x08, 0xfb, 0x0e, 0x8b, 0xd3, 0xf7, 0xe5, 0x05, 0xfb, 0x11, 0xf7, + 0x6d, 0x15, 0x66, 0x67, 0x68, 0x66, 0x6f, 0x9f, 0x77, 0xa7, 0xb1, 0xaf, + 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x65, 0x67, + 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, + 0x9f, 0x6e, 0x1f, 0x0e, 0xf8, 0x4f, 0xf8, 0x49, 0x15, 0xfb, 0x47, 0x06, + 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xd9, 0x8b, 0x59, 0xfb, 0x81, 0xfb, + 0x0e, 0x8b, 0x05, 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, + 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0xeb, 0x06, + 0xa7, 0x8b, 0x99, 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, + 0x8b, 0x9b, 0x81, 0x9b, 0x7f, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, + 0x08, 0xfb, 0x0e, 0x8b, 0xd3, 0xf7, 0xe5, 0x05, 0xee, 0xf7, 0x4f, 0x15, + 0xa3, 0x9b, 0x93, 0x96, 0x8b, 0x9b, 0x8b, 0x9c, 0x7e, 0x97, 0x7a, 0x8b, + 0x80, 0x8b, 0x84, 0x88, 0x79, 0x7e, 0x08, 0xfb, 0x31, 0xfb, 0x03, 0x05, + 0x76, 0x7d, 0x81, 0x7c, 0x8b, 0x7d, 0x8b, 0x79, 0x97, 0x7f, 0x9d, 0x8b, + 0x94, 0x8b, 0x92, 0x8e, 0x9e, 0x98, 0x08, 0xf7, 0x31, 0xf7, 0x04, 0x05, + 0x0e, 0xf8, 0x4f, 0xf8, 0x49, 0x15, 0xfb, 0x46, 0x06, 0x6b, 0x8b, 0x82, + 0x89, 0x7c, 0x7e, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, + 0x80, 0xb5, 0x1e, 0xd9, 0x8b, 0x59, 0xfb, 0x81, 0xfb, 0x0e, 0x8b, 0x05, + 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0xeb, 0x06, 0xa7, 0x8b, 0x98, + 0x8f, 0x99, 0x96, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, + 0x9b, 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x0d, + 0x8b, 0xd2, 0xf7, 0xe5, 0x05, 0x2f, 0xf7, 0x87, 0x15, 0x7e, 0x98, 0x86, + 0x8e, 0x81, 0x8b, 0x73, 0x8b, 0x75, 0x76, 0x8b, 0x73, 0x8b, 0x83, 0x90, + 0x82, 0x96, 0x81, 0x08, 0xf7, 0x02, 0xfb, 0x04, 0x05, 0x97, 0x7f, 0x92, + 0x87, 0x94, 0x8b, 0xa2, 0x8b, 0xa2, 0xa0, 0x8b, 0xa1, 0x8b, 0x95, 0x86, + 0x94, 0x80, 0x96, 0x08, 0xfb, 0x02, 0xf7, 0x03, 0x05, 0x0e, 0xf8, 0x4f, + 0xf8, 0x49, 0x15, 0xfb, 0x46, 0x06, 0x6b, 0x8b, 0x82, 0x89, 0x7c, 0x7e, + 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb5, 0x1e, + 0xd9, 0x8b, 0x59, 0xfb, 0x81, 0xfb, 0x0e, 0x8b, 0x05, 0x6b, 0x8b, 0x83, + 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, + 0x80, 0xb4, 0x1e, 0xf7, 0xeb, 0x06, 0xa7, 0x8b, 0x98, 0x8f, 0x99, 0x96, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, 0x82, 0x9b, 0x7e, 0x8f, + 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0xfb, 0x0d, 0x8b, 0xd2, 0xf7, + 0xe5, 0x05, 0x6d, 0xf7, 0x3e, 0x15, 0xe7, 0x2a, 0x05, 0x93, 0x82, 0x93, + 0x87, 0x94, 0x8b, 0xa1, 0x8b, 0xa0, 0xa0, 0x8b, 0xa1, 0x8b, 0x93, 0x89, + 0x90, 0x83, 0x93, 0x08, 0x84, 0x91, 0xfb, 0x10, 0xf7, 0x15, 0xfb, 0x47, + 0xfb, 0x15, 0x05, 0x88, 0x89, 0x88, 0x89, 0x87, 0x89, 0x7b, 0x80, 0x84, + 0x80, 0x8b, 0x7e, 0x8b, 0x7a, 0x97, 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x95, + 0x8f, 0x97, 0x94, 0x08, 0xf7, 0x1a, 0xec, 0x05, 0x0e, 0xf7, 0xed, 0xf8, + 0xdf, 0x15, 0x99, 0x8b, 0x94, 0x87, 0xa2, 0x7a, 0x08, 0xaf, 0x6f, 0xab, + 0x7c, 0xa0, 0x8b, 0xac, 0x8b, 0xa8, 0x9c, 0xb3, 0xb6, 0xa0, 0xa1, 0x95, + 0x9b, 0x8b, 0x97, 0x8b, 0x97, 0x7e, 0x96, 0x7d, 0x8b, 0x81, 0x8b, 0x78, + 0x80, 0x7f, 0x7d, 0x6b, 0x68, 0x86, 0x87, 0x7b, 0x8b, 0x08, 0x80, 0x8b, + 0x7f, 0x91, 0x6f, 0x9f, 0x08, 0x5f, 0xa9, 0x7b, 0x93, 0x74, 0x8b, 0x6e, + 0x8b, 0x6a, 0x7b, 0x6c, 0x6d, 0x71, 0x72, 0x7e, 0x77, 0x8b, 0x7b, 0x8b, + 0x7e, 0x96, 0x81, 0x99, 0x8b, 0x95, 0x8b, 0x94, 0x90, 0x94, 0x94, 0x08, + 0xb2, 0xb4, 0x94, 0x91, 0x9d, 0x8b, 0x08, 0x52, 0xfb, 0x2a, 0x15, 0x2d, + 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7c, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, + 0x7b, 0x08, 0x70, 0x9c, 0x7e, 0xae, 0x1e, 0x59, 0xfb, 0x81, 0x85, 0x8b, + 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x04, 0x06, 0xa8, 0x8b, + 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9b, + 0x82, 0x9a, 0x7e, 0x90, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x85, + 0x8b, 0xb1, 0xf7, 0x4a, 0x05, 0xc5, 0xbe, 0xae, 0x9c, 0xb9, 0x8b, 0xbd, + 0x8b, 0xa7, 0x7a, 0x8b, 0x6b, 0x8b, 0x84, 0x8a, 0x84, 0x89, 0x82, 0x08, + 0x66, 0xfb, 0x46, 0x05, 0x72, 0x8b, 0x80, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xe4, 0x06, + 0xa7, 0x8b, 0x98, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, + 0x08, 0xa6, 0x7a, 0x98, 0x68, 0x1e, 0xb2, 0xf7, 0x4a, 0x05, 0x8e, 0x9b, + 0x8d, 0x99, 0x8b, 0x9b, 0x8b, 0xd4, 0x50, 0xbc, 0x33, 0x8b, 0x54, 0x8b, + 0x66, 0x7c, 0x51, 0x5d, 0x08, 0x95, 0xbb, 0x05, 0x0e, 0xf8, 0x23, 0xf8, + 0x56, 0x15, 0x30, 0x8b, 0x2f, 0x63, 0x51, 0x4b, 0x5c, 0x58, 0x70, 0x4b, + 0x8b, 0x52, 0x08, 0xfb, 0x06, 0xe0, 0x3f, 0xf7, 0x14, 0xf7, 0x37, 0xf7, + 0x29, 0xf7, 0x17, 0xf7, 0x25, 0xf7, 0x04, 0x35, 0xd9, 0xfb, 0x10, 0x1e, + 0x74, 0x27, 0x15, 0xd7, 0xc2, 0x5e, 0x4c, 0x37, 0x33, 0x41, 0x26, 0x3e, + 0x54, 0xb8, 0xca, 0xe0, 0xe3, 0xd4, 0xf1, 0x1f, 0x62, 0xf7, 0xc4, 0x15, + 0x65, 0x67, 0x68, 0x66, 0x70, 0xa0, 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, + 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xf7, 0x64, 0x16, 0x65, 0x67, 0x68, 0x66, + 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, + 0x1f, 0x0e, 0xf8, 0x23, 0xf8, 0x56, 0x15, 0x30, 0x8b, 0x2f, 0x63, 0x51, + 0x4b, 0x5c, 0x58, 0x70, 0x4b, 0x8b, 0x52, 0x08, 0xfb, 0x06, 0xe0, 0x3f, + 0xf7, 0x14, 0xf7, 0x37, 0xf7, 0x29, 0xf7, 0x17, 0xf7, 0x25, 0xf7, 0x04, + 0x35, 0xd9, 0xfb, 0x10, 0x1e, 0x74, 0x27, 0x15, 0xd7, 0xc2, 0x5e, 0x4c, + 0x37, 0x33, 0x41, 0x26, 0x3e, 0x54, 0xb8, 0xca, 0xe0, 0xe3, 0xd4, 0xf1, + 0x1f, 0xf7, 0x4f, 0xf7, 0xa6, 0x15, 0xa3, 0x9c, 0x93, 0x95, 0x8b, 0x9b, + 0x8b, 0x9c, 0x7e, 0x97, 0x7a, 0x8b, 0x80, 0x8b, 0x83, 0x87, 0x7a, 0x7f, + 0x08, 0xfb, 0x32, 0xfb, 0x03, 0x05, 0x77, 0x7d, 0x81, 0x7c, 0x8b, 0x7d, + 0x8b, 0x79, 0x97, 0x7f, 0x9d, 0x8b, 0x94, 0x8b, 0x92, 0x8e, 0x9d, 0x98, + 0x08, 0xf7, 0x32, 0xf7, 0x04, 0x05, 0x0e, 0xf8, 0x23, 0xf8, 0x56, 0x15, + 0x30, 0x8b, 0x2f, 0x63, 0x51, 0x4b, 0x5c, 0x58, 0x70, 0x4b, 0x8b, 0x52, + 0x08, 0xfb, 0x06, 0xe0, 0x3f, 0xf7, 0x14, 0xf7, 0x37, 0xf7, 0x29, 0xf7, + 0x17, 0xf7, 0x25, 0xf7, 0x04, 0x35, 0xd9, 0xfb, 0x10, 0x1e, 0x74, 0x27, + 0x15, 0xd7, 0xc2, 0x5e, 0x4c, 0x37, 0x33, 0x41, 0x26, 0x3e, 0x54, 0xb8, + 0xca, 0xe0, 0xe3, 0xd4, 0xf1, 0x1f, 0x7c, 0xf7, 0xde, 0x15, 0x7f, 0x98, + 0x85, 0x8e, 0x81, 0x8b, 0x73, 0x8b, 0x75, 0x76, 0x8b, 0x73, 0x8b, 0x83, + 0x90, 0x82, 0x96, 0x81, 0x08, 0xf7, 0x02, 0xfb, 0x04, 0x05, 0x97, 0x7f, + 0x92, 0x87, 0x94, 0x8b, 0xa3, 0x8b, 0xa2, 0xa0, 0x8b, 0xa1, 0x8b, 0x95, + 0x87, 0x92, 0x7e, 0x98, 0x08, 0xfb, 0x02, 0xf7, 0x03, 0x05, 0x0e, 0xf8, + 0x23, 0xf8, 0x56, 0x15, 0x30, 0x8b, 0x2f, 0x63, 0x51, 0x4b, 0x5c, 0x58, + 0x70, 0x4b, 0x8b, 0x52, 0x08, 0xfb, 0x06, 0xe0, 0x3f, 0xf7, 0x14, 0xf7, + 0x37, 0xf7, 0x29, 0xf7, 0x17, 0xf7, 0x25, 0xf7, 0x04, 0x35, 0xd9, 0xfb, + 0x10, 0x1e, 0x74, 0x27, 0x15, 0xd7, 0xc2, 0x5e, 0x4c, 0x37, 0x33, 0x41, + 0x26, 0x3e, 0x54, 0xb8, 0xca, 0xe0, 0xe3, 0xd4, 0xf1, 0x1f, 0xc1, 0xf7, + 0x95, 0x15, 0xe7, 0x2a, 0x05, 0x93, 0x82, 0x93, 0x87, 0x94, 0x8b, 0xa1, + 0x8b, 0xa0, 0xa0, 0x8b, 0xa1, 0x8b, 0x93, 0x89, 0x8f, 0x83, 0x93, 0x08, + 0x84, 0x92, 0xfb, 0x10, 0xf7, 0x15, 0xfb, 0x48, 0xfb, 0x15, 0x05, 0x70, + 0x78, 0x86, 0x85, 0x8b, 0x7a, 0x8b, 0x7b, 0x97, 0x7f, 0x9b, 0x8b, 0x94, + 0x8b, 0x94, 0x8f, 0x98, 0x94, 0x08, 0xf7, 0x1a, 0xec, 0x05, 0x0e, 0xf8, + 0x23, 0xf8, 0x56, 0x15, 0x30, 0x8b, 0x2f, 0x63, 0x51, 0x4b, 0x5c, 0x58, + 0x70, 0x4b, 0x8b, 0x52, 0x08, 0xfb, 0x06, 0xe0, 0x3f, 0xf7, 0x14, 0xf7, + 0x37, 0xf7, 0x29, 0xf7, 0x18, 0xf7, 0x24, 0x1e, 0xf7, 0x04, 0x35, 0xd9, + 0xfb, 0x10, 0x1e, 0x74, 0x27, 0x15, 0xd7, 0xc2, 0x5e, 0x4c, 0x37, 0x33, + 0x41, 0x26, 0x3e, 0x54, 0xb8, 0xca, 0xe0, 0xe3, 0xd4, 0xf1, 0x1f, 0xf7, + 0x74, 0xf7, 0xc6, 0x15, 0x7f, 0x8b, 0x7b, 0x81, 0x7a, 0x78, 0x6f, 0x6c, + 0x85, 0x87, 0x7c, 0x8b, 0x80, 0x8b, 0x7e, 0x91, 0x6f, 0x9f, 0x08, 0x5f, + 0xaa, 0x7b, 0x92, 0x75, 0x8b, 0x6d, 0x8b, 0x6b, 0x7b, 0x6c, 0x6e, 0x71, + 0x71, 0x7e, 0x77, 0x8b, 0x7b, 0x8b, 0x7e, 0x96, 0x81, 0x99, 0x8b, 0x95, + 0x8b, 0x94, 0x8f, 0x95, 0x96, 0xb1, 0xb3, 0x94, 0x91, 0x9d, 0x8b, 0x08, + 0x99, 0x8b, 0x93, 0x87, 0xa3, 0x7a, 0x08, 0xb0, 0x6e, 0xa9, 0x7d, 0xa1, + 0x8b, 0xac, 0x8b, 0xa8, 0x9c, 0xb4, 0xb7, 0x9f, 0xa1, 0x94, 0x9a, 0x8b, + 0x97, 0x8b, 0x97, 0x7e, 0x96, 0x7e, 0x8b, 0x08, 0x0e, 0xf8, 0x47, 0xf8, + 0xde, 0x15, 0x2e, 0xeb, 0x05, 0x81, 0x96, 0x85, 0x8e, 0x82, 0x8b, 0x76, + 0x8b, 0x75, 0x75, 0x8b, 0x76, 0x8b, 0x81, 0x8c, 0x8a, 0x9b, 0x7a, 0x08, + 0xf7, 0x12, 0xfb, 0x14, 0xf7, 0x46, 0xf7, 0x14, 0x05, 0xa6, 0x9e, 0x90, + 0x92, 0x8b, 0x9b, 0x8b, 0x9c, 0x7f, 0x97, 0x7b, 0x8b, 0x82, 0x8b, 0x83, + 0x87, 0x7d, 0x81, 0x08, 0xfb, 0x19, 0x2b, 0x05, 0xb4, 0xfb, 0xa6, 0x15, + 0x92, 0x75, 0x97, 0x82, 0xa0, 0x8b, 0x9a, 0x8b, 0x9c, 0x93, 0x98, 0x97, + 0x95, 0x96, 0x8e, 0x92, 0x91, 0xa7, 0x08, 0x93, 0xb0, 0x05, 0x8d, 0x96, + 0x8d, 0x98, 0x8b, 0x92, 0x8b, 0xa0, 0x7c, 0x99, 0x75, 0x8b, 0x7b, 0x8b, + 0x82, 0x85, 0x7e, 0x77, 0x68, 0x9d, 0x64, 0x93, 0x5a, 0x8b, 0xfb, 0x1a, + 0x8b, 0x23, 0x44, 0x8b, 0x31, 0x8b, 0x4a, 0xbd, 0x6b, 0xf7, 0x0f, 0x7e, + 0x08, 0xbf, 0x85, 0xa1, 0x87, 0x9a, 0x84, 0x9c, 0x84, 0x95, 0x7f, 0x8b, + 0x7f, 0x8b, 0x72, 0x51, 0x75, 0x47, 0x8b, 0x54, 0x8b, 0x63, 0x98, 0x74, + 0xa5, 0x88, 0xa9, 0x7e, 0x99, 0x71, 0x8b, 0x68, 0x8b, 0x77, 0x76, 0x81, + 0x5d, 0x08, 0x84, 0x6a, 0x05, 0x88, 0x7c, 0x8a, 0x84, 0x8b, 0x85, 0x8b, + 0x74, 0x9c, 0x7c, 0xa3, 0x8b, 0x98, 0x8b, 0x93, 0x8e, 0x99, 0x94, 0xaf, + 0x78, 0xbc, 0x81, 0xc4, 0x8b, 0xf7, 0x24, 0x8b, 0xf7, 0x04, 0xd4, 0x8b, + 0xe8, 0x8b, 0xb0, 0x79, 0xab, 0x6c, 0x9f, 0x08, 0x71, 0x9b, 0x66, 0x96, + 0x41, 0x95, 0x4e, 0x94, 0x84, 0x8c, 0x7f, 0x90, 0x7e, 0x90, 0x82, 0x93, + 0x8b, 0x93, 0x8b, 0x9e, 0xbf, 0x9e, 0xc2, 0x8b, 0xb5, 0x8b, 0xaa, 0x82, + 0xa2, 0x77, 0x08, 0x8f, 0x82, 0x05, 0x0e, 0xf7, 0xde, 0xf9, 0x22, 0x15, + 0x65, 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, + 0x1f, 0xa7, 0x77, 0x9f, 0x6e, 0x1e, 0xf7, 0x64, 0x16, 0x65, 0x67, 0x68, + 0x66, 0x70, 0xa0, 0x76, 0xa6, 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, + 0x6e, 0x1f, 0xcc, 0xfb, 0x6d, 0x15, 0xfb, 0x1b, 0x06, 0x6c, 0x8b, 0x82, + 0x88, 0x7c, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, 0x9b, + 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x64, 0xfb, 0x4b, 0x05, 0x4c, 0x55, 0x6e, + 0x7d, 0x59, 0x8b, 0x5b, 0x8b, 0x70, 0x9d, 0x8b, 0xaa, 0x8b, 0x93, 0x8c, + 0x92, 0x8d, 0x93, 0x08, 0xc6, 0xf7, 0xaa, 0xfb, 0x08, 0x8b, 0x05, 0x6c, + 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7c, 0x08, + 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0x9b, 0x8b, 0x65, 0xfb, 0x4a, 0x05, 0x87, + 0x7b, 0x8a, 0x7e, 0x8b, 0x7a, 0x8b, 0x41, 0xc6, 0x5a, 0xe3, 0x8b, 0xc3, + 0x8b, 0xad, 0x99, 0xc7, 0xba, 0x08, 0x81, 0x5b, 0xe9, 0x8b, 0x05, 0xa8, + 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x9a, 0x96, 0x94, 0x9d, 0x8b, 0x9c, 0x08, + 0xa5, 0x7a, 0x98, 0x68, 0x1e, 0xd3, 0xf7, 0xe5, 0x05, 0x0e, 0xf8, 0xbb, + 0xf9, 0x04, 0x15, 0xa3, 0x9b, 0x93, 0x96, 0x8b, 0x9b, 0x8b, 0x9c, 0x7f, + 0x97, 0x79, 0x8b, 0x80, 0x8b, 0x84, 0x88, 0x79, 0x7e, 0x08, 0xfb, 0x32, + 0xfb, 0x03, 0x05, 0x77, 0x7d, 0x81, 0x7c, 0x8b, 0x7d, 0x8b, 0x79, 0x97, + 0x7f, 0x9d, 0x8b, 0x94, 0x8b, 0x92, 0x8e, 0x9e, 0x98, 0x08, 0xf7, 0x31, + 0xf7, 0x04, 0x05, 0xbf, 0xfb, 0x4f, 0x15, 0xfb, 0x1b, 0x06, 0x6c, 0x8b, + 0x82, 0x88, 0x7c, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, + 0x9b, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x64, 0xfb, 0x4b, 0x05, 0x4c, 0x55, + 0x6e, 0x7d, 0x59, 0x8b, 0x5b, 0x8b, 0x70, 0x9d, 0x8b, 0xaa, 0x8b, 0x93, + 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xc6, 0xf7, 0xaa, 0xfb, 0x08, 0x8b, 0x05, + 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7c, + 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0x9b, 0x8b, 0x65, 0xfb, 0x4a, 0x05, + 0x87, 0x7b, 0x8a, 0x7e, 0x8b, 0x7a, 0x8b, 0x41, 0xc6, 0x5a, 0xe3, 0x8b, + 0xc3, 0x8b, 0xad, 0x99, 0xc7, 0xba, 0x08, 0x81, 0x5b, 0xe9, 0x8b, 0x05, + 0xa8, 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x9a, 0x96, 0x94, 0x9d, 0x8b, 0x9c, + 0x08, 0xa5, 0x7a, 0x98, 0x68, 0x1e, 0xd3, 0xf7, 0xe5, 0x05, 0x0e, 0xf7, + 0xfb, 0xf9, 0x3c, 0x15, 0x7f, 0x98, 0x86, 0x8e, 0x80, 0x8b, 0x73, 0x8b, + 0x75, 0x76, 0x8b, 0x73, 0x8b, 0x83, 0x90, 0x82, 0x96, 0x81, 0x08, 0xf7, + 0x02, 0xfb, 0x04, 0x05, 0x97, 0x7f, 0x93, 0x87, 0x93, 0x8b, 0xa3, 0x8b, + 0xa2, 0xa0, 0x8b, 0xa1, 0x8b, 0x95, 0x87, 0x93, 0x7f, 0x97, 0x08, 0xfb, + 0x03, 0xf7, 0x03, 0x05, 0xf7, 0x88, 0xfb, 0x87, 0x15, 0xfb, 0x1b, 0x06, + 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, + 0x08, 0x6f, 0x9b, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x64, 0xfb, 0x4b, 0x05, + 0x4c, 0x55, 0x6e, 0x7d, 0x59, 0x8b, 0x5b, 0x8b, 0x70, 0x9d, 0x8b, 0xaa, + 0x8b, 0x93, 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xc6, 0xf7, 0xaa, 0xfb, 0x08, + 0x8b, 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, + 0x8b, 0x7c, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0x9b, 0x8b, 0x65, 0xfb, + 0x4a, 0x05, 0x87, 0x7b, 0x8a, 0x7e, 0x8b, 0x7a, 0x8b, 0x41, 0xc6, 0x5a, + 0xe3, 0x8b, 0xc3, 0x8b, 0xad, 0x99, 0xc7, 0xba, 0x08, 0x81, 0x5b, 0xe9, + 0x8b, 0x05, 0xa8, 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x9a, 0x96, 0x94, 0x9d, + 0x8b, 0x9c, 0x08, 0xa5, 0x7a, 0x98, 0x68, 0x1e, 0xd3, 0xf7, 0xe5, 0x05, + 0x0e, 0xf8, 0x3d, 0xf8, 0xf3, 0x15, 0xe7, 0x2a, 0x05, 0x93, 0x82, 0x93, + 0x87, 0x94, 0x8b, 0xa1, 0x8b, 0xa0, 0xa0, 0x8b, 0xa1, 0x8b, 0x93, 0x89, + 0x90, 0x82, 0x93, 0x08, 0x85, 0x91, 0xfb, 0x10, 0xf7, 0x15, 0xfb, 0x48, + 0xfb, 0x15, 0x05, 0x70, 0x78, 0x86, 0x85, 0x8b, 0x7a, 0x8b, 0x7b, 0x97, + 0x7f, 0x9b, 0x8b, 0x94, 0x8b, 0x94, 0x8f, 0x98, 0x94, 0x08, 0xf7, 0x1a, + 0xec, 0x05, 0xf7, 0x46, 0xfb, 0x3e, 0x15, 0xfb, 0x1b, 0x06, 0x6c, 0x8b, + 0x82, 0x88, 0x7c, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6f, + 0x9b, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x64, 0xfb, 0x4b, 0x05, 0x4c, 0x55, + 0x6e, 0x7d, 0x59, 0x8b, 0x5b, 0x8b, 0x70, 0x9d, 0x8b, 0xaa, 0x8b, 0x93, + 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xc6, 0xf7, 0xaa, 0xfb, 0x08, 0x8b, 0x05, + 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7c, + 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0x9b, 0x8b, 0x65, 0xfb, 0x4a, 0x05, + 0x87, 0x7b, 0x8a, 0x7e, 0x8b, 0x7a, 0x8b, 0x41, 0xc6, 0x5a, 0xe3, 0x8b, + 0xc3, 0x8b, 0xad, 0x99, 0xc7, 0xba, 0x08, 0x81, 0x5b, 0xe9, 0x8b, 0x05, + 0xa8, 0x8b, 0x98, 0x8e, 0x98, 0x97, 0x9a, 0x96, 0x94, 0x9d, 0x8b, 0x9c, + 0x08, 0xa5, 0x7a, 0x98, 0x68, 0x1e, 0xd3, 0xf7, 0xe5, 0x05, 0x0e, 0xf7, + 0x87, 0x8e, 0x15, 0x3d, 0xfb, 0x00, 0x27, 0x8b, 0x05, 0x6c, 0x8b, 0x82, + 0x88, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, + 0x80, 0xb4, 0x1e, 0xf7, 0x6a, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, + 0x83, 0x8e, 0x83, 0x8c, 0x78, 0x8b, 0x08, 0x86, 0x8b, 0xf7, 0xd9, 0xf8, + 0x4e, 0x05, 0xb0, 0x8f, 0xa5, 0xa3, 0x8b, 0xab, 0x8b, 0x9c, 0x82, 0x9a, + 0x7e, 0x8f, 0x83, 0x8e, 0x84, 0x8c, 0x77, 0x8b, 0x08, 0x2f, 0x06, 0x6c, + 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, + 0x71, 0x9c, 0x7d, 0xab, 0x1e, 0x90, 0x8b, 0xfb, 0x3a, 0xfb, 0x73, 0x47, + 0xf7, 0x73, 0x05, 0xb5, 0x8c, 0xa8, 0xa3, 0x8b, 0xaf, 0x8b, 0x9b, 0x82, + 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x31, 0x06, + 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, + 0x8b, 0x73, 0x98, 0x7f, 0xa6, 0x87, 0x08, 0xf0, 0xfb, 0xe2, 0x05, 0xf7, + 0xea, 0xf9, 0x01, 0x15, 0xa1, 0x9a, 0x94, 0x98, 0x8b, 0x9a, 0x8b, 0x9c, + 0x7f, 0x97, 0x79, 0x8b, 0x80, 0x8b, 0x85, 0x88, 0x79, 0x7e, 0x08, 0xfb, + 0x32, 0xfb, 0x03, 0x05, 0x76, 0x7c, 0x81, 0x7e, 0x8b, 0x7c, 0x8b, 0x79, + 0x97, 0x7f, 0x9d, 0x8b, 0x95, 0x8b, 0x92, 0x8e, 0x9d, 0x98, 0x08, 0xf7, + 0x32, 0xf7, 0x04, 0x05, 0x0e, 0xf7, 0x9d, 0xef, 0x15, 0xf7, 0xd1, 0xf7, + 0x94, 0x9c, 0xdc, 0xfc, 0x2d, 0x8b, 0x74, 0xfb, 0x01, 0x05, 0x89, 0x81, + 0x89, 0x7f, 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, + 0x9b, 0x93, 0x98, 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, 0xa6, 0x08, 0x8d, + 0x94, 0xf7, 0x28, 0x8b, 0xfb, 0xce, 0xfb, 0x92, 0x79, 0x38, 0xf8, 0x46, + 0x8b, 0x9e, 0xe3, 0x05, 0x8e, 0x98, 0x8c, 0x94, 0x8b, 0x92, 0x8b, 0xa0, + 0x7a, 0x9b, 0x74, 0x8b, 0x6d, 0x8b, 0x76, 0x78, 0x81, 0x68, 0x08, 0xfb, + 0x44, 0x06, 0xf7, 0x36, 0xf8, 0x7a, 0x15, 0x2e, 0xeb, 0x05, 0x81, 0x96, + 0x85, 0x8e, 0x82, 0x8b, 0x76, 0x8b, 0x75, 0x76, 0x8b, 0x75, 0x8b, 0x81, + 0x8b, 0x8a, 0x9c, 0x7a, 0x08, 0xf7, 0x12, 0xfb, 0x14, 0xf7, 0x46, 0xf7, + 0x14, 0x05, 0xa6, 0x9e, 0x90, 0x92, 0x8b, 0x9b, 0x8b, 0x9c, 0x7f, 0x97, + 0x7b, 0x8b, 0x82, 0x8b, 0x83, 0x87, 0x7d, 0x81, 0x08, 0xfb, 0x19, 0x2b, + 0x05, 0x0e, 0xf8, 0xb2, 0xf8, 0xdb, 0x15, 0x9e, 0x94, 0x96, 0x98, 0x8b, + 0x9a, 0x8b, 0x9a, 0x81, 0x96, 0x7c, 0x8b, 0x81, 0x8b, 0x7f, 0x88, 0x7e, + 0x85, 0x08, 0x35, 0x62, 0x72, 0x98, 0x05, 0x62, 0xa0, 0x6e, 0x95, 0x74, + 0x8b, 0x73, 0x8b, 0x73, 0x76, 0x8b, 0x75, 0x8b, 0x80, 0x92, 0x83, 0x98, + 0x86, 0x08, 0x9b, 0x86, 0x05, 0x8b, 0x8b, 0x92, 0x88, 0x94, 0x86, 0x8e, + 0x8a, 0x92, 0x87, 0x94, 0x87, 0x08, 0x52, 0x6e, 0x05, 0x72, 0x7e, 0x86, + 0x85, 0x8b, 0x78, 0x8b, 0x7a, 0x94, 0x80, 0x99, 0x8b, 0x94, 0x8b, 0x8f, + 0x8c, 0xa0, 0x96, 0x08, 0xf2, 0xbd, 0x05, 0xb4, 0x6f, 0xb4, 0x5f, 0xa7, + 0x59, 0x08, 0x54, 0xb0, 0x6f, 0x95, 0x5a, 0x8b, 0x38, 0x8b, 0x38, 0x66, + 0x52, 0x4c, 0x5c, 0x58, 0x6e, 0x49, 0x8b, 0x53, 0x8b, 0xfb, 0x00, 0xe5, + 0x3d, 0xf7, 0x11, 0x8b, 0xdf, 0x8b, 0xe6, 0xb2, 0xc7, 0xc8, 0xbf, 0xc0, + 0xab, 0xe2, 0x8b, 0xe3, 0x08, 0x8b, 0xca, 0x78, 0xc8, 0x67, 0xbd, 0x78, + 0xa5, 0x7c, 0x9b, 0x66, 0xa9, 0x08, 0xbe, 0xa4, 0x05, 0xfb, 0x3c, 0xfb, + 0x7d, 0x15, 0xd7, 0xc1, 0x5c, 0x4a, 0x1f, 0x8b, 0x6b, 0x7e, 0x69, 0x75, + 0x74, 0x63, 0x62, 0x54, 0x73, 0x53, 0x8b, 0x08, 0x42, 0x51, 0xb9, 0xc5, + 0xde, 0xe6, 0xda, 0xeb, 0x1f, 0x0e, 0xf7, 0x50, 0xcd, 0x15, 0xb6, 0x64, + 0xb4, 0x7a, 0xc4, 0x8b, 0x08, 0xf7, 0x35, 0xf7, 0x19, 0xf7, 0x09, 0xf7, + 0x22, 0xf7, 0x02, 0x3d, 0xd2, 0xfb, 0x0e, 0x1f, 0x4d, 0x8b, 0x5d, 0x7b, + 0x51, 0x61, 0x08, 0xbd, 0xf7, 0x7c, 0xfb, 0x08, 0x8b, 0x05, 0x6c, 0x8b, + 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9a, 0x80, 0xb4, 0x1e, 0x9b, 0x8b, 0xfb, 0x19, 0xfd, 0x09, 0x7b, 0x8b, + 0x05, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x7f, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, + 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb3, 0x1e, 0xf7, 0x42, 0x06, 0xa9, 0x8b, + 0x96, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9b, + 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x79, 0x8b, 0x08, 0x51, + 0x8b, 0xaf, 0xf7, 0x3f, 0x05, 0xf7, 0x66, 0xf7, 0xb0, 0x15, 0xd6, 0xbc, + 0x65, 0x4f, 0x1f, 0x8b, 0x62, 0x6f, 0x5e, 0x62, 0x70, 0x6d, 0x78, 0x67, + 0x81, 0x62, 0x8b, 0x61, 0x8b, 0x6c, 0x95, 0x75, 0x9e, 0x78, 0x9d, 0x7f, + 0xa8, 0x8c, 0xa4, 0x8f, 0xda, 0xd7, 0xc7, 0xec, 0x8b, 0x08, 0x0e, 0xf7, + 0xe3, 0xf9, 0x22, 0x15, 0x65, 0x67, 0x68, 0x66, 0x70, 0xa0, 0x76, 0xa6, + 0xb2, 0xaf, 0xae, 0xb0, 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xf7, 0x63, 0x16, + 0x66, 0x67, 0x68, 0x66, 0x6f, 0xa0, 0x77, 0xa6, 0xb1, 0xaf, 0xae, 0xb0, + 0xa7, 0x77, 0x9f, 0x6e, 0x1f, 0xfb, 0xbf, 0xfd, 0x1f, 0x15, 0x3d, 0xfb, + 0x00, 0x27, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x88, 0x7c, 0x7f, 0x7d, 0x7f, + 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x6a, + 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9c, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x83, 0x8c, 0x78, + 0x8b, 0x08, 0x86, 0x8b, 0xf7, 0xd9, 0xf8, 0x4e, 0x05, 0xb0, 0x8f, 0xa5, + 0xa3, 0x8b, 0xab, 0x8b, 0x9c, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, 0x84, + 0x8c, 0x77, 0x8b, 0x08, 0x2f, 0x06, 0x6c, 0x8b, 0x81, 0x88, 0x7d, 0x7f, + 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x71, 0x9c, 0x7d, 0xab, 0x1e, + 0x90, 0x8b, 0xfb, 0x3a, 0xfb, 0x73, 0x47, 0xf7, 0x73, 0x05, 0xb5, 0x8c, + 0xa8, 0xa3, 0x8b, 0xaf, 0x8b, 0x9b, 0x82, 0x9a, 0x7e, 0x8f, 0x83, 0x8e, + 0x85, 0x8c, 0x77, 0x8b, 0x08, 0x31, 0x06, 0x6c, 0x8b, 0x82, 0x88, 0x7c, + 0x7f, 0x7d, 0x80, 0x82, 0x79, 0x8b, 0x7b, 0x8b, 0x73, 0x98, 0x7f, 0xa6, + 0x87, 0x08, 0xf0, 0xfb, 0xe2, 0x05, 0x0e, 0xf7, 0x8e, 0xf7, 0xfb, 0x15, + 0xab, 0xe0, 0xcc, 0xc0, 0xd0, 0x8b, 0xb0, 0x8b, 0xb0, 0x7c, 0xa0, 0x75, + 0x96, 0x7f, 0x8d, 0x84, 0x8b, 0x76, 0x8b, 0x73, 0x8c, 0x85, 0x8f, 0x83, + 0x90, 0x82, 0x97, 0x85, 0x97, 0x8b, 0x99, 0x8b, 0x9a, 0x93, 0x96, 0x98, + 0x08, 0x94, 0x95, 0x8f, 0x93, 0x90, 0xa6, 0x08, 0x9d, 0xdf, 0x05, 0x90, + 0x9d, 0x8b, 0x8e, 0x8b, 0x93, 0x08, 0xa1, 0x7d, 0x9a, 0x76, 0x1e, 0x7b, + 0x8b, 0x7f, 0x84, 0x7b, 0x7a, 0x89, 0x8d, 0x88, 0x8c, 0x89, 0x8c, 0x08, + 0x5e, 0xa5, 0x6e, 0x93, 0x5c, 0x8b, 0xfb, 0x10, 0x8b, 0xfb, 0x12, 0x25, + 0x60, 0xfb, 0x1c, 0x08, 0x6d, 0x06, 0x76, 0x7d, 0x7d, 0x76, 0x7c, 0x91, + 0x85, 0x9c, 0x1f, 0xa6, 0x8b, 0x83, 0x61, 0x6f, 0x8b, 0x05, 0x77, 0x7d, + 0x7d, 0x76, 0x7c, 0x91, 0x85, 0x9b, 0x1f, 0xaa, 0x06, 0x8a, 0x84, 0x8b, + 0x84, 0x8b, 0x89, 0x8b, 0xfb, 0x0f, 0xe0, 0x3b, 0xf7, 0x16, 0x8b, 0xdc, + 0x8b, 0xd4, 0xa5, 0xbf, 0xba, 0xa3, 0xa0, 0x96, 0x9f, 0x8b, 0x9f, 0x8b, + 0xa1, 0x7c, 0x9c, 0x77, 0x8b, 0x7f, 0x8b, 0x7f, 0x86, 0x7f, 0x80, 0x08, + 0x6d, 0x70, 0x8b, 0x8b, 0x80, 0x84, 0x72, 0x7d, 0x64, 0x82, 0x64, 0x8b, + 0x3a, 0x8b, 0x5d, 0xb6, 0x89, 0xd7, 0x08, 0xf7, 0x3b, 0x06, 0x9f, 0x99, + 0x99, 0xa0, 0x9a, 0x85, 0x91, 0x7b, 0x1f, 0xfb, 0x3f, 0x8b, 0x93, 0xb5, + 0xf7, 0x5b, 0x8b, 0x05, 0x9f, 0x99, 0x99, 0xa0, 0x9a, 0x85, 0x91, 0x7b, + 0x1f, 0xfb, 0x57, 0x06, 0x0e, 0xf8, 0x69, 0xf9, 0x12, 0x15, 0xfb, 0x1f, + 0x69, 0x05, 0x6d, 0x83, 0x7e, 0x7f, 0x8b, 0x75, 0x8b, 0x7b, 0x95, 0x80, + 0x99, 0x8b, 0x91, 0x8b, 0x8f, 0x8c, 0x97, 0x8e, 0x08, 0xbd, 0x97, 0x59, + 0xfb, 0x81, 0x52, 0x8b, 0x05, 0x6b, 0x77, 0x7c, 0x72, 0x78, 0x97, 0x83, + 0xa4, 0x1f, 0xf7, 0x4a, 0x06, 0xaa, 0x9f, 0x9b, 0xa4, 0x9e, 0x81, 0x92, + 0x70, 0x1f, 0x52, 0x8b, 0xd0, 0xf7, 0xd8, 0x05, 0x0e, 0xf7, 0xd5, 0xf7, + 0xce, 0x15, 0xf7, 0x54, 0xf7, 0x1d, 0xa4, 0xa6, 0x8b, 0xcb, 0x8b, 0xc3, + 0x5f, 0xb2, 0x4b, 0x8b, 0x5c, 0x8b, 0x5e, 0x77, 0x6b, 0x69, 0x78, 0x78, + 0x7e, 0x73, 0x8b, 0x7d, 0x8b, 0x7c, 0x97, 0x80, 0x9a, 0x8b, 0x99, 0x8b, + 0x99, 0x93, 0x92, 0x97, 0x08, 0x95, 0x9e, 0x8c, 0x8c, 0x92, 0x91, 0x9b, + 0x9b, 0xa1, 0x93, 0xa2, 0x8b, 0xab, 0x8b, 0xa2, 0x7a, 0x8b, 0x73, 0x8b, + 0x6b, 0x79, 0x7b, 0xfb, 0x7f, 0xfb, 0x3a, 0x08, 0x7c, 0x47, 0xf7, 0xac, + 0x8b, 0x97, 0xc3, 0x05, 0x8c, 0x91, 0x8c, 0x93, 0x8b, 0x8f, 0x8b, 0x99, + 0x7f, 0x96, 0x7c, 0x8b, 0x78, 0x8b, 0x7e, 0x80, 0x84, 0x76, 0x08, 0xfb, + 0x01, 0x06, 0x0e, 0xf8, 0x19, 0xf8, 0x78, 0x15, 0x74, 0x77, 0x78, 0x76, + 0x1f, 0x8b, 0x7b, 0x95, 0x82, 0x9d, 0x8a, 0xa5, 0x8a, 0x92, 0x8a, 0x96, + 0x86, 0x9e, 0x81, 0x99, 0x79, 0x8b, 0x7b, 0x8b, 0x63, 0x65, 0x75, 0x49, + 0x8b, 0x65, 0x8b, 0x7a, 0x8e, 0x7e, 0x95, 0x83, 0x92, 0x87, 0x8c, 0x83, + 0x8b, 0x08, 0x76, 0x77, 0x77, 0x76, 0x6f, 0xba, 0x78, 0xd1, 0x1f, 0xc8, + 0x8b, 0xb5, 0x98, 0xad, 0xa9, 0xa7, 0xa4, 0x9e, 0xb1, 0x8b, 0xa9, 0x8b, + 0xa9, 0x7b, 0xa6, 0x6d, 0x9c, 0x8c, 0x8c, 0x8d, 0x8c, 0x8b, 0x8b, 0x08, + 0xb5, 0xa2, 0xa4, 0xb0, 0x8b, 0xb1, 0x08, 0xc2, 0x62, 0xad, 0x4b, 0x41, + 0x45, 0x65, 0x63, 0x7d, 0x97, 0x7f, 0x9a, 0x1e, 0x93, 0x8b, 0x96, 0x8f, + 0x92, 0x91, 0xa2, 0xa0, 0x9c, 0x91, 0xac, 0x8b, 0x08, 0xad, 0xa0, 0x7e, + 0x76, 0x71, 0x6d, 0x71, 0x6b, 0x1f, 0x73, 0x06, 0x0e, 0xf7, 0xf6, 0xf7, + 0x6a, 0x15, 0xb5, 0xb3, 0xb2, 0xb4, 0xa9, 0x75, 0xa1, 0x6b, 0x1f, 0x7a, + 0x06, 0x61, 0x63, 0x64, 0x63, 0x6c, 0xa1, 0x75, 0xab, 0x1f, 0x9c, 0x06, + 0x0e, 0xf8, 0xb1, 0xf7, 0x79, 0x15, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, + 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x8b, 0x9a, 0x81, 0x9b, 0x7f, 0x8f, + 0x83, 0x8e, 0x83, 0x8c, 0x78, 0x8b, 0x08, 0xfc, 0x13, 0x06, 0x6c, 0x8b, + 0x82, 0x89, 0x7c, 0x7e, 0x7d, 0x7f, 0x82, 0x7a, 0x8b, 0x7b, 0x08, 0x6e, + 0x9b, 0x80, 0xb4, 0x1e, 0xf8, 0x13, 0x06, 0x0e, 0xf8, 0x40, 0xf8, 0xe8, + 0x15, 0xfb, 0x05, 0x22, 0x25, 0xfb, 0x03, 0x3a, 0xc6, 0x50, 0xdc, 0xf7, + 0x04, 0xf5, 0xf2, 0xf7, 0x03, 0xdb, 0x50, 0xc6, 0x3a, 0x1f, 0x7d, 0x4e, + 0x15, 0xc0, 0xb2, 0x65, 0x56, 0x43, 0x46, 0x47, 0x41, 0x56, 0x65, 0xb2, + 0xc0, 0xd3, 0xd0, 0xce, 0xd4, 0x1f, 0x0e, 0xf7, 0x47, 0xf7, 0xde, 0x15, + 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf8, 0x13, 0x06, 0xa8, 0x8b, 0x97, + 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, + 0x99, 0x7e, 0x90, 0x82, 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfc, 0x13, + 0x06, 0x0e, 0xf7, 0xec, 0xf7, 0x65, 0x15, 0xdc, 0x24, 0x05, 0x9b, 0x76, + 0x94, 0x86, 0x9b, 0x8b, 0xaa, 0x8b, 0xab, 0xa9, 0x8b, 0xa8, 0x8b, 0x97, + 0x87, 0x93, 0x7d, 0x9d, 0x08, 0x3a, 0xf2, 0xf7, 0x11, 0xf2, 0x05, 0xa7, + 0xa3, 0x94, 0x98, 0x8b, 0x9f, 0x8b, 0xa2, 0x7a, 0x9c, 0x73, 0x8b, 0x7a, + 0x8b, 0x82, 0x86, 0x71, 0x76, 0x08, 0xfb, 0x11, 0x24, 0x3a, 0xf2, 0x05, + 0x7b, 0x9f, 0x81, 0x91, 0x7c, 0x8b, 0x6c, 0x8b, 0x6b, 0x6d, 0x8b, 0x6e, + 0x8b, 0x7e, 0x8e, 0x84, 0x9a, 0x79, 0x08, 0xdc, 0x24, 0xfb, 0x11, 0x24, + 0x05, 0x6e, 0x73, 0x83, 0x7f, 0x8b, 0x76, 0x8b, 0x74, 0x9c, 0x7a, 0xa3, + 0x8b, 0x9b, 0x8b, 0x96, 0x90, 0xa4, 0xa0, 0x08, 0xf7, 0x11, 0xf2, 0x05, + 0x0e, 0xf7, 0x47, 0xf7, 0xde, 0x15, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, + 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, + 0xf8, 0x13, 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, + 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, 0x99, 0x7e, 0x90, 0x82, 0x8f, 0x87, + 0x8b, 0x75, 0x8b, 0x08, 0xfc, 0x13, 0x06, 0xf7, 0x30, 0xfb, 0x3e, 0x15, + 0x58, 0x63, 0x68, 0x5e, 0x6a, 0xa2, 0x78, 0xb2, 0xbe, 0xb3, 0xae, 0xb8, + 0xac, 0x75, 0x9e, 0x63, 0x1f, 0xd9, 0xf8, 0x08, 0x15, 0x59, 0x63, 0x67, + 0x5f, 0x6a, 0xa2, 0x78, 0xb2, 0xbe, 0xb3, 0xae, 0xb8, 0xac, 0x75, 0x9e, + 0x62, 0x1f, 0x0e, 0xf7, 0x95, 0xf8, 0x92, 0x15, 0xae, 0x8b, 0x80, 0x5a, + 0x05, 0x88, 0x7f, 0x8b, 0x89, 0x8b, 0x86, 0x8b, 0x7c, 0x98, 0x7f, 0x9c, + 0x8b, 0xa3, 0x8b, 0x9c, 0x9b, 0x91, 0xa9, 0x08, 0xa5, 0xf7, 0x0e, 0xfb, + 0xb6, 0x8b, 0x71, 0xfb, 0x0e, 0x05, 0x8a, 0x87, 0x8a, 0x80, 0x8b, 0x87, + 0x8b, 0x7c, 0x98, 0x7f, 0x9b, 0x8b, 0xa3, 0x8b, 0x9b, 0x9b, 0x91, 0xa9, + 0x08, 0x96, 0xbc, 0xae, 0x8b, 0x5c, 0xfb, 0x6d, 0x75, 0x8b, 0x05, 0x69, + 0x76, 0x7a, 0x71, 0x76, 0x97, 0x82, 0xa6, 0x1f, 0xf7, 0x0a, 0x06, 0xac, + 0xa2, 0x9d, 0xa5, 0xa0, 0x7f, 0x93, 0x6f, 0x1f, 0x74, 0x8b, 0xba, 0xf7, + 0x6d, 0x05, 0xf7, 0x66, 0x3c, 0x15, 0xac, 0xfb, 0x14, 0x9e, 0x8b, 0xde, + 0xf7, 0x12, 0x6e, 0xfb, 0x1c, 0x05, 0x76, 0x8b, 0x84, 0x89, 0x81, 0x82, + 0x81, 0x83, 0x84, 0x7e, 0x8b, 0x80, 0x08, 0x76, 0x97, 0x82, 0xa6, 0x1e, + 0xcb, 0x06, 0xab, 0xa1, 0x9d, 0xa5, 0x1f, 0x8b, 0x9d, 0x81, 0x94, 0x78, + 0x8d, 0x08, 0xba, 0xf7, 0x6e, 0x05, 0xa1, 0x8f, 0x9c, 0x9d, 0x8b, 0xa0, + 0x08, 0xa0, 0x80, 0x93, 0x6f, 0x1e, 0x41, 0x8b, 0x3c, 0xfb, 0x15, 0x71, + 0xf7, 0x15, 0x42, 0x8b, 0x05, 0x6a, 0x76, 0x7a, 0x71, 0x1f, 0x8b, 0x7a, + 0x93, 0x82, 0x9b, 0x88, 0x08, 0x5c, 0xfb, 0x6e, 0x05, 0x72, 0x88, 0x78, + 0x79, 0x8b, 0x74, 0x08, 0x77, 0x97, 0x82, 0xa6, 0x1e, 0xca, 0x06, 0xad, + 0xa1, 0x9d, 0xa5, 0xa0, 0x7f, 0x93, 0x6e, 0x1f, 0xa9, 0xf7, 0x1e, 0x05, + 0x0e, 0xf8, 0x38, 0xf7, 0xde, 0x15, 0xf7, 0x22, 0x06, 0xa8, 0x8b, 0x97, + 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, 0x9b, 0x8b, 0x9c, 0x82, + 0x99, 0x7e, 0x90, 0x82, 0x8f, 0x87, 0x8b, 0x75, 0x8b, 0x08, 0xfb, 0x21, + 0x8b, 0xa6, 0xf7, 0x14, 0x05, 0x8e, 0x9b, 0x8c, 0x90, 0x8b, 0x92, 0x8b, + 0xa1, 0x7a, 0x9b, 0x74, 0x8b, 0x69, 0x8b, 0x76, 0x75, 0x82, 0x5f, 0x08, + 0x70, 0xfb, 0x14, 0xfb, 0x22, 0x8b, 0x05, 0x6c, 0x8b, 0x82, 0x89, 0x7c, + 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, + 0x1e, 0xf7, 0x22, 0x8b, 0x75, 0x27, 0x05, 0x87, 0x78, 0x8b, 0x8a, 0x8b, + 0x82, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, 0x9c, 0x93, 0x97, + 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, 0xa6, 0x08, 0xa0, 0xef, 0x05, 0xfb, + 0xb6, 0xfb, 0x7a, 0x15, 0x6c, 0x8b, 0x82, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, + 0x82, 0x79, 0x8b, 0x7b, 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf8, 0x13, + 0x06, 0xa8, 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x99, 0x97, 0x94, 0x9c, 0x8b, + 0x9b, 0x8b, 0x9c, 0x82, 0x99, 0x7e, 0x90, 0x82, 0x8f, 0x87, 0x8b, 0x75, + 0x8b, 0x08, 0xfc, 0x13, 0x06, 0x0e, 0xf7, 0xa2, 0xf9, 0x12, 0x15, 0xfb, + 0x1f, 0x69, 0x05, 0x6d, 0x84, 0x7e, 0x7e, 0x8b, 0x75, 0x8b, 0x7b, 0x95, + 0x80, 0x99, 0x8b, 0x91, 0x8b, 0x8f, 0x8c, 0x97, 0x8e, 0x08, 0xbd, 0x97, + 0x59, 0xfb, 0x81, 0x52, 0x8b, 0x05, 0x6b, 0x77, 0x7c, 0x72, 0x78, 0x97, + 0x83, 0xa4, 0x1f, 0xf7, 0x4a, 0x06, 0xa9, 0xa0, 0x9b, 0xa4, 0x9e, 0x81, + 0x92, 0x70, 0x1f, 0x52, 0x8b, 0xd0, 0xf7, 0xd8, 0x05, 0xf7, 0xcf, 0xfb, + 0x02, 0x15, 0x98, 0x9b, 0x8f, 0x92, 0x8b, 0x94, 0x8b, 0x9a, 0x7f, 0x97, + 0x7c, 0x8b, 0x7c, 0x8b, 0x81, 0x85, 0x7c, 0x77, 0x08, 0xfb, 0xf9, 0xfc, + 0x57, 0x05, 0x7e, 0x7b, 0x88, 0x84, 0x8b, 0x82, 0x8b, 0x7b, 0x96, 0x80, + 0x9b, 0x8b, 0x99, 0x8b, 0x96, 0x92, 0x9a, 0x9e, 0x08, 0xf7, 0xf8, 0xf8, + 0x57, 0x05, 0xfb, 0x09, 0xfc, 0x61, 0x15, 0xf7, 0x53, 0xf7, 0x1c, 0xa5, + 0xa7, 0x8b, 0xcb, 0x8b, 0xc3, 0x5f, 0xb2, 0x4b, 0x8b, 0x5c, 0x8b, 0x5e, + 0x77, 0x6b, 0x69, 0x78, 0x77, 0x7e, 0x74, 0x8b, 0x7d, 0x8b, 0x7c, 0x97, + 0x80, 0x9a, 0x8b, 0x99, 0x8b, 0x99, 0x93, 0x92, 0x97, 0x08, 0x96, 0x9e, + 0x8b, 0x8c, 0x92, 0x91, 0x9b, 0x9b, 0xa1, 0x93, 0xa2, 0x8b, 0xab, 0x8b, + 0xa2, 0x7a, 0x8b, 0x73, 0x8b, 0x6b, 0x79, 0x7b, 0xfb, 0x80, 0xfb, 0x3a, + 0x08, 0x7d, 0x47, 0xf7, 0xac, 0x8b, 0x97, 0xc3, 0x05, 0x8c, 0x91, 0x8c, + 0x93, 0x8b, 0x8f, 0x8b, 0x99, 0x7f, 0x96, 0x7c, 0x8b, 0x78, 0x8b, 0x7e, + 0x80, 0x84, 0x76, 0x08, 0xfb, 0x01, 0x06, 0x0e, 0xf7, 0xa2, 0xf9, 0x12, + 0x15, 0xfb, 0x1f, 0x69, 0x05, 0x6d, 0x84, 0x7e, 0x7e, 0x8b, 0x75, 0x8b, + 0x7b, 0x95, 0x80, 0x99, 0x8b, 0x91, 0x8b, 0x8f, 0x8c, 0x97, 0x8e, 0x08, + 0xbd, 0x97, 0x59, 0xfb, 0x81, 0x52, 0x8b, 0x05, 0x6b, 0x77, 0x7c, 0x72, + 0x78, 0x97, 0x83, 0xa4, 0x1f, 0xf7, 0x4a, 0x06, 0xa9, 0xa0, 0x9b, 0xa4, + 0x9e, 0x81, 0x92, 0x70, 0x1f, 0x52, 0x8b, 0xd0, 0xf7, 0xd8, 0x05, 0xf7, + 0xd0, 0xfb, 0x02, 0x15, 0x96, 0x99, 0x90, 0x95, 0x8b, 0x93, 0x8b, 0x9a, + 0x7f, 0x97, 0x7c, 0x8b, 0x7c, 0x8b, 0x82, 0x85, 0x7b, 0x77, 0x08, 0xfb, + 0xf9, 0xfc, 0x57, 0x05, 0x7e, 0x7a, 0x88, 0x86, 0x8b, 0x81, 0x8b, 0x7b, + 0x96, 0x80, 0x9b, 0x8b, 0x9a, 0x8b, 0x95, 0x92, 0x9a, 0x9e, 0x08, 0xf7, + 0xf9, 0xf8, 0x57, 0x05, 0xe2, 0xfb, 0x28, 0x15, 0x37, 0x8b, 0xfb, 0x5a, + 0xfb, 0x86, 0x80, 0x54, 0xf7, 0x37, 0x8b, 0x87, 0x7b, 0x78, 0x8b, 0x05, + 0x6c, 0x78, 0x7c, 0x72, 0x78, 0x96, 0x83, 0xa4, 0x1f, 0xda, 0x06, 0xaa, + 0xa0, 0x9b, 0xa3, 0x1f, 0x8b, 0x9c, 0x81, 0x94, 0x76, 0x8c, 0x08, 0x8f, + 0x9b, 0x05, 0xa6, 0x8d, 0x9d, 0x9b, 0x8b, 0xa2, 0x8b, 0x9c, 0x81, 0x93, + 0x76, 0x8c, 0x08, 0xbc, 0xf7, 0x7a, 0x05, 0xfb, 0x08, 0xfb, 0x7a, 0x15, + 0x3c, 0x8b, 0xf5, 0xf7, 0x15, 0x70, 0xfb, 0x15, 0x05, 0x0e, 0xf7, 0x51, + 0xf8, 0x78, 0x15, 0x74, 0x77, 0x78, 0x76, 0x1f, 0x8b, 0x7b, 0x95, 0x82, + 0x9d, 0x8a, 0xa5, 0x8a, 0x92, 0x8a, 0x96, 0x86, 0x9e, 0x81, 0x99, 0x79, + 0x8b, 0x7b, 0x8b, 0x63, 0x65, 0x75, 0x49, 0x8b, 0x65, 0x8b, 0x7a, 0x8e, + 0x7e, 0x95, 0x82, 0x92, 0x88, 0x8c, 0x83, 0x8b, 0x08, 0x76, 0x77, 0x77, + 0x76, 0x6f, 0xba, 0x78, 0xd1, 0x1f, 0xc8, 0x8b, 0xb5, 0x98, 0xad, 0xa9, + 0xa7, 0xa5, 0x9e, 0xb0, 0x8b, 0xa9, 0x8b, 0xa9, 0x7b, 0xa6, 0x6d, 0x9c, + 0x8c, 0x8c, 0x8d, 0x8c, 0x8b, 0x8b, 0x08, 0xb5, 0xa2, 0xa4, 0xb0, 0x8b, + 0xb1, 0x08, 0xc2, 0x62, 0xad, 0x4b, 0x41, 0x45, 0x65, 0x63, 0x7d, 0x97, + 0x7f, 0x9a, 0x1e, 0x94, 0x8b, 0x95, 0x8f, 0x92, 0x91, 0xa2, 0xa0, 0x9c, + 0x91, 0xac, 0x8b, 0x08, 0xad, 0xa0, 0x7e, 0x76, 0x71, 0x6d, 0x71, 0x6b, + 0x1f, 0x73, 0x06, 0xf8, 0x20, 0xb7, 0x15, 0x96, 0x98, 0x90, 0x96, 0x8b, + 0x93, 0x8b, 0x9a, 0x7f, 0x97, 0x7c, 0x8b, 0x7c, 0x8b, 0x82, 0x85, 0x7b, + 0x77, 0x08, 0xfb, 0xf8, 0xfc, 0x57, 0x05, 0x7d, 0x7a, 0x88, 0x86, 0x8b, + 0x81, 0x8b, 0x7b, 0x97, 0x80, 0x9a, 0x8b, 0x9a, 0x8b, 0x96, 0x92, 0x9a, + 0x9e, 0x08, 0xf7, 0xf8, 0xf8, 0x57, 0x05, 0xe3, 0xfb, 0x28, 0x15, 0x37, + 0x8b, 0xfb, 0x5a, 0xfb, 0x86, 0x7f, 0x54, 0xf7, 0x38, 0x8b, 0x88, 0x7b, + 0x77, 0x8b, 0x05, 0x6c, 0x77, 0x7c, 0x72, 0x78, 0x97, 0x83, 0xa4, 0x1f, + 0xda, 0x06, 0xaa, 0xa0, 0x9b, 0xa3, 0x1f, 0x8b, 0x9c, 0x81, 0x94, 0x77, + 0x8c, 0x08, 0x8e, 0x9b, 0x05, 0xa6, 0x8d, 0x9d, 0x9b, 0x8b, 0xa2, 0x8b, + 0x9c, 0x81, 0x93, 0x76, 0x8c, 0x08, 0xbc, 0xf7, 0x7a, 0x05, 0xfb, 0x08, + 0xfb, 0x7a, 0x15, 0x3b, 0x8b, 0xf7, 0x00, 0xf7, 0x15, 0x6f, 0xfb, 0x15, + 0x05, 0x0e, 0xf7, 0x54, 0xf7, 0xa1, 0x15, 0x89, 0x80, 0x8a, 0x83, 0x8b, + 0x7f, 0x08, 0x43, 0xc3, 0x5b, 0xdd, 0xd8, 0xd8, 0xb4, 0xb4, 0x9c, 0x7f, + 0x97, 0x7a, 0x1e, 0x82, 0x8b, 0x81, 0x87, 0x83, 0x84, 0x6f, 0x73, 0x7d, + 0x86, 0x64, 0x8b, 0x58, 0x8b, 0x6e, 0xa1, 0x89, 0xb4, 0x8b, 0x91, 0x8b, + 0x91, 0x8c, 0x91, 0x08, 0x93, 0xad, 0x05, 0x96, 0xc0, 0xb7, 0xb1, 0xbe, + 0x8b, 0x08, 0xab, 0xa7, 0x7c, 0x7a, 0x6e, 0x92, 0x81, 0xa0, 0x1f, 0xa2, + 0x8b, 0x9a, 0x9b, 0x91, 0xa7, 0x08, 0x97, 0xc1, 0x8c, 0x91, 0x05, 0x8c, + 0x8f, 0x8c, 0x90, 0x8b, 0x8f, 0x8b, 0x99, 0x80, 0x96, 0x7b, 0x8b, 0x7d, + 0x8b, 0x80, 0x85, 0x84, 0x7e, 0x71, 0x99, 0x77, 0x90, 0x6e, 0x8b, 0x32, + 0x8b, 0x39, 0x46, 0x78, 0x2f, 0x08, 0x83, 0x67, 0x05, 0xf7, 0x81, 0xf7, + 0xdd, 0x15, 0xfb, 0x59, 0xfb, 0x4c, 0xfb, 0x46, 0xfb, 0x54, 0xfb, 0x20, + 0xf3, 0x24, 0xf7, 0x21, 0xf7, 0x5a, 0xf7, 0x4c, 0xf7, 0x47, 0xf7, 0x53, + 0xf7, 0x20, 0x23, 0xf2, 0xfb, 0x22, 0x1f, 0x7a, 0x42, 0x15, 0xf7, 0x01, + 0xda, 0x3d, 0x20, 0xfb, 0x26, 0xfb, 0x20, 0xfb, 0x1c, 0xfb, 0x2a, 0xfb, + 0x00, 0x3c, 0xd9, 0xf6, 0xf7, 0x26, 0xf7, 0x20, 0xf7, 0x1c, 0xf7, 0x29, + 0x1f, 0x0e, 0xf7, 0xd5, 0xf7, 0x8a, 0x15, 0x9a, 0x06, 0xa5, 0x7e, 0xa5, + 0x51, 0x8d, 0x5a, 0x08, 0xb3, 0x06, 0xaa, 0xa0, 0x9d, 0xa4, 0x1f, 0x8b, + 0x9d, 0x82, 0x93, 0x77, 0x8d, 0x7d, 0xb1, 0x86, 0x94, 0x78, 0xa1, 0xbc, + 0xa0, 0xab, 0xb5, 0x8b, 0xb7, 0x08, 0xc0, 0x62, 0xab, 0x49, 0x1e, 0x2e, + 0x06, 0x6b, 0x76, 0x7a, 0x72, 0x1f, 0x8b, 0x77, 0x96, 0x83, 0xa4, 0x8a, + 0x08, 0x63, 0xfb, 0x52, 0x05, 0x6c, 0x76, 0x79, 0x72, 0x78, 0x98, 0x82, + 0xa4, 0x1f, 0xd0, 0x06, 0xa9, 0xa1, 0x9d, 0xa4, 0x9e, 0x80, 0x94, 0x73, + 0x1f, 0x95, 0xbc, 0x05, 0x9a, 0xd1, 0x15, 0x9a, 0xd2, 0xa4, 0x8b, 0x05, + 0xa9, 0x9d, 0x81, 0x7a, 0x74, 0x6e, 0x76, 0x6a, 0x1f, 0x71, 0x06, 0xe8, + 0xf7, 0xae, 0x15, 0xfb, 0x59, 0xfb, 0x4c, 0xfb, 0x46, 0xfb, 0x54, 0xfb, + 0x20, 0xf3, 0x24, 0xf7, 0x21, 0xf7, 0x5a, 0xf7, 0x4c, 0xf7, 0x46, 0xf7, + 0x54, 0xf7, 0x20, 0x24, 0xf2, 0xfb, 0x23, 0x1f, 0x7b, 0x42, 0x15, 0xf7, + 0x00, 0xda, 0x3d, 0x20, 0xfb, 0x26, 0xfb, 0x20, 0xfb, 0x1c, 0xfb, 0x2a, + 0xfb, 0x00, 0x3c, 0xd9, 0xf6, 0xf7, 0x26, 0xf7, 0x20, 0xf7, 0x1c, 0xf7, + 0x2a, 0x1f, 0x0e, 0x0e, 0xf8, 0xc4, 0xf8, 0x51, 0x15, 0xfb, 0xf9, 0x06, + 0x6b, 0x8b, 0x83, 0x89, 0x7c, 0x7f, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, + 0x08, 0x6e, 0x9b, 0x80, 0xb4, 0x1e, 0xf7, 0x95, 0x8b, 0x68, 0xfb, 0x38, + 0x05, 0x88, 0x80, 0x8a, 0x80, 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, + 0x8b, 0x9a, 0x8b, 0x9d, 0x93, 0x97, 0x98, 0x95, 0x95, 0x8e, 0x93, 0x91, + 0xa6, 0x08, 0xc3, 0xf7, 0x9c, 0x05, 0x0e, 0xf8, 0x68, 0xf8, 0xc0, 0x15, + 0x8e, 0x99, 0x8c, 0x93, 0x8b, 0x91, 0x8b, 0xa1, 0x7a, 0x9b, 0x74, 0x8b, + 0x7b, 0x8b, 0x7a, 0x83, 0x7f, 0x7e, 0x82, 0x82, 0x86, 0x80, 0x86, 0x72, + 0x08, 0x60, 0xfb, 0x5f, 0x05, 0x89, 0x82, 0x89, 0x7d, 0x8b, 0x85, 0x8b, + 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, 0x9b, 0x93, 0x98, 0x98, 0x95, + 0x95, 0x8e, 0x93, 0x91, 0xa6, 0x08, 0xb6, 0xf7, 0x5f, 0x05, 0x2d, 0xfc, + 0x4c, 0x15, 0x8d, 0x94, 0x8d, 0x98, 0x8b, 0x92, 0x8b, 0xa0, 0x7a, 0x9b, + 0x75, 0x8b, 0x7b, 0x8b, 0x7a, 0x83, 0x7e, 0x7e, 0x82, 0x81, 0x87, 0x82, + 0x85, 0x71, 0x08, 0x60, 0xfb, 0x5f, 0x05, 0x88, 0x7e, 0x8a, 0x82, 0x8b, + 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, 0x8b, 0x9b, 0x93, 0x98, + 0x98, 0x95, 0x95, 0x8e, 0x94, 0x91, 0xa5, 0x08, 0xb6, 0xf7, 0x5f, 0x05, + 0x0e, 0xf7, 0x55, 0x84, 0x15, 0x9e, 0x85, 0x9c, 0x88, 0x9f, 0x8b, 0xbf, + 0x8b, 0xc0, 0x97, 0xc8, 0xa6, 0x08, 0x86, 0x74, 0xe9, 0x8b, 0x05, 0xa8, + 0x8b, 0x97, 0x8e, 0x99, 0x97, 0x9a, 0x97, 0x94, 0x9c, 0x8b, 0x9c, 0x08, + 0xa6, 0x7b, 0x97, 0x67, 0x1e, 0xd3, 0xf7, 0xe5, 0xfb, 0x1b, 0x8b, 0x05, + 0x6d, 0x8b, 0x81, 0x88, 0x7c, 0x80, 0x7d, 0x7f, 0x82, 0x79, 0x8b, 0x7b, + 0x08, 0x6f, 0x9b, 0x80, 0xb4, 0x1e, 0xae, 0x8b, 0x60, 0xfb, 0x5c, 0x05, + 0x44, 0x65, 0x5c, 0x7b, 0x5e, 0x8b, 0x6a, 0x8b, 0x76, 0x99, 0x8b, 0xa1, + 0x8b, 0x90, 0x8c, 0x94, 0x8d, 0x95, 0x08, 0xca, 0xf7, 0xb9, 0xfb, 0x09, + 0x8b, 0x05, 0x7c, 0x8c, 0x05, 0x6e, 0x8d, 0x6a, 0x6a, 0x8b, 0x6d, 0x08, + 0x6f, 0x9b, 0x80, 0xb3, 0x1e, 0x9b, 0x8b, 0x31, 0xfc, 0x3d, 0x05, 0x88, + 0x7e, 0x8a, 0x82, 0x8b, 0x84, 0x8b, 0x76, 0x9c, 0x7b, 0xa2, 0x8b, 0x9b, + 0x8b, 0x9b, 0x93, 0x98, 0x98, 0x95, 0x95, 0x8f, 0x94, 0x90, 0xa5, 0x08, + 0x9c, 0xdb, 0x05, 0x0e, 0xf8, 0xec, 0x14, 0x8b, 0x15, 0x7d, 0x99, 0xf8, + 0x49, 0x98, 0xf7, 0x19, 0x99, 0xa5, 0x9a, 0x06, 0x1e, 0x0a, 0x03, 0x96, + 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xf0, 0x0a, 0xe8, 0x93, 0x0c, + 0x0c, 0xf2, 0x0b, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e +}; +const unsigned int fonts_NimbusMonL_BoldObli_cff_len = 33584; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusMonL-Regu.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusMonL-Regu.cff.c new file mode 100644 index 00000000000..b759061b6ca --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusMonL-Regu.cff.c @@ -0,0 +1,2138 @@ +const unsigned char fonts_NimbusMonL_Regu_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x10, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x4d, 0x6f, 0x6e, 0x4c, 0x2d, 0x52, 0x65, 0x67, 0x75, + 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x34, 0xf8, 0x1f, 0x00, 0xf8, 0x20, + 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, 0x18, 0x04, 0x8c, 0x0c, + 0x01, 0x1d, 0x00, 0x4c, 0x9d, 0x11, 0x0d, 0x7f, 0xfb, 0x6c, 0xf8, 0xf8, + 0xf9, 0xbf, 0x05, 0x1c, 0x00, 0xe9, 0x0f, 0x1c, 0x00, 0x00, 0x10, 0x1c, + 0x02, 0xbc, 0x11, 0x1c, 0x00, 0x28, 0x1c, 0x63, 0xe7, 0x12, 0x00, 0x08, + 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, + 0x1f, 0x00, 0x5f, 0x00, 0x74, 0x00, 0x81, 0x45, 0x75, 0x72, 0x6f, 0x6d, + 0x69, 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, + 0x65, 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, + 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, + 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, + 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, + 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, + 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, + 0x4d, 0x6f, 0x6e, 0x6f, 0x20, 0x4c, 0x20, 0x52, 0x65, 0x67, 0x75, 0x6c, + 0x61, 0x72, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x4d, 0x6f, 0x6e, + 0x6f, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, + 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, + 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, + 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, + 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, + 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, + 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, + 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, + 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, + 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, + 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, + 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, + 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, + 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, + 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, + 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, + 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, + 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, + 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, + 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, + 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, + 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, + 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8c, + 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, + 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, 0xae, + 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, 0xb4, + 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, 0xb9, + 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, 0xbc, + 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, 0xc2, + 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xc8, + 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd1, + 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd6, + 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, 0xd9, + 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xdf, + 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, 0x87, + 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, 0xa1, + 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9b, + 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, 0x97, + 0x00, 0xa0, 0x00, 0x98, 0x00, 0xea, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x04, 0x00, 0x50, 0x00, 0x89, 0x01, 0x33, 0x01, 0xeb, 0x02, + 0x73, 0x03, 0x15, 0x03, 0x3a, 0x03, 0x83, 0x03, 0xcc, 0x04, 0x4c, 0x04, + 0x8b, 0x04, 0xb0, 0x04, 0xce, 0x04, 0xea, 0x05, 0x20, 0x05, 0x82, 0x05, + 0xc3, 0x06, 0x23, 0x06, 0xac, 0x06, 0xf7, 0x07, 0x5e, 0x07, 0xd8, 0x08, + 0x12, 0x08, 0x71, 0x08, 0xec, 0x09, 0x21, 0x09, 0x60, 0x09, 0xb2, 0x09, + 0xeb, 0x0a, 0x3e, 0x0a, 0xa6, 0x0b, 0x34, 0x0b, 0xa1, 0x0c, 0x0d, 0x0c, + 0x80, 0x0c, 0xd2, 0x0d, 0x35, 0x0d, 0x93, 0x0e, 0x16, 0x0e, 0x8d, 0x0e, + 0xcc, 0x0f, 0x18, 0x0f, 0x99, 0x0f, 0xd9, 0x10, 0x4a, 0x10, 0xa0, 0x10, + 0xe6, 0x11, 0x37, 0x11, 0xd7, 0x12, 0x45, 0x12, 0xe1, 0x13, 0x23, 0x13, + 0x7a, 0x13, 0xc7, 0x14, 0x22, 0x14, 0xb1, 0x15, 0x1a, 0x15, 0x56, 0x15, + 0x7b, 0x15, 0xb1, 0x15, 0xd5, 0x16, 0x14, 0x16, 0x20, 0x16, 0x45, 0x16, + 0xba, 0x17, 0x11, 0x17, 0x75, 0x17, 0xcd, 0x18, 0x21, 0x18, 0x8b, 0x18, + 0xf7, 0x19, 0x68, 0x19, 0xa6, 0x19, 0xe2, 0x1a, 0x51, 0x1a, 0x84, 0x1b, + 0x08, 0x1b, 0x7c, 0x1b, 0xae, 0x1c, 0x11, 0x1c, 0x74, 0x1c, 0xd4, 0x1d, + 0x6c, 0x1d, 0xc0, 0x1e, 0x0d, 0x1e, 0x5a, 0x1e, 0xb1, 0x1f, 0x40, 0x1f, + 0xa8, 0x1f, 0xdf, 0x20, 0x43, 0x20, 0x61, 0x20, 0xc4, 0x21, 0x1e, 0x21, + 0x6a, 0x21, 0xe7, 0x22, 0x83, 0x22, 0xbb, 0x23, 0x5c, 0x23, 0xd5, 0x24, + 0x92, 0x25, 0x45, 0x25, 0x63, 0x25, 0xaa, 0x26, 0x24, 0x26, 0x62, 0x26, + 0xa1, 0x27, 0x40, 0x27, 0xd5, 0x27, 0xf3, 0x28, 0x41, 0x28, 0xaf, 0x28, + 0xcb, 0x29, 0x49, 0x29, 0x60, 0x29, 0x85, 0x29, 0xcc, 0x2a, 0x13, 0x2a, + 0x8e, 0x2a, 0xcb, 0x2b, 0x7c, 0x2b, 0xe4, 0x2c, 0x1a, 0x2c, 0x4e, 0x2c, + 0x89, 0x2c, 0xe3, 0x2d, 0x01, 0x2d, 0x31, 0x2d, 0x48, 0x2d, 0x73, 0x2d, + 0x9d, 0x2d, 0xdc, 0x2e, 0x3f, 0x2e, 0x75, 0x2e, 0xb0, 0x2e, 0xce, 0x2f, + 0x61, 0x2f, 0xd6, 0x30, 0x52, 0x30, 0xf5, 0x31, 0x70, 0x31, 0x9a, 0x32, + 0x76, 0x32, 0xa9, 0x33, 0x16, 0x33, 0xb1, 0x34, 0x46, 0x34, 0xc5, 0x35, + 0x5c, 0x35, 0xfb, 0x36, 0x9d, 0x37, 0x49, 0x38, 0x0e, 0x38, 0xa4, 0x39, + 0x56, 0x39, 0xc9, 0x3a, 0x56, 0x3a, 0xec, 0x3b, 0x87, 0x3c, 0x27, 0x3c, + 0x90, 0x3d, 0x02, 0x3d, 0x75, 0x3d, 0xef, 0x3e, 0x9d, 0x3f, 0x0d, 0x3f, + 0x85, 0x3f, 0xff, 0x40, 0x7f, 0x41, 0x1e, 0x41, 0xf6, 0x42, 0x78, 0x43, + 0x01, 0x43, 0x8b, 0x44, 0x1e, 0x44, 0xb9, 0x45, 0x32, 0x45, 0x91, 0x46, + 0x24, 0x46, 0xc3, 0x47, 0x6a, 0x48, 0x14, 0x48, 0xc4, 0x49, 0x91, 0x4a, + 0x2f, 0x4a, 0xd3, 0x4b, 0x50, 0x4b, 0xd7, 0x4c, 0x60, 0x4c, 0xef, 0x4d, + 0x4c, 0x4d, 0xb1, 0x4e, 0x16, 0x4e, 0x87, 0x4f, 0x4d, 0x4f, 0xa9, 0x50, + 0x0d, 0x50, 0x73, 0x50, 0xdf, 0x51, 0x6a, 0x52, 0x3e, 0x52, 0xb5, 0x53, + 0x34, 0x53, 0xb6, 0x54, 0x3f, 0x54, 0xda, 0x55, 0x4d, 0x55, 0xde, 0x56, + 0x41, 0x56, 0xd3, 0x57, 0x76, 0x57, 0xb6, 0x58, 0x10, 0x58, 0x80, 0x58, + 0x9c, 0x58, 0xba, 0x58, 0xe4, 0x59, 0x01, 0x59, 0x78, 0x59, 0xc0, 0x5a, + 0x66, 0x5a, 0xc2, 0x5b, 0x8f, 0x5c, 0x52, 0x5d, 0x43, 0x5d, 0xed, 0x5e, + 0x9c, 0x5e, 0x9d, 0x5e, 0xc0, 0x5e, 0xf9, 0x5f, 0x53, 0x0e, 0x0e, 0x0e, + 0xf7, 0xe6, 0xf8, 0xc7, 0x15, 0x8c, 0x93, 0x8b, 0x91, 0x8b, 0x8d, 0x08, + 0xa1, 0x7a, 0x9c, 0x75, 0x74, 0x7a, 0x7a, 0x75, 0x1e, 0x8b, 0x87, 0x8b, + 0x86, 0x8c, 0x84, 0x08, 0x9d, 0xfb, 0xda, 0x05, 0x8c, 0x78, 0x91, 0x82, + 0x98, 0x8b, 0x99, 0x8b, 0x91, 0x93, 0x8c, 0x9f, 0x08, 0x9d, 0xf7, 0xda, + 0x05, 0x5e, 0xfc, 0x72, 0x15, 0x6d, 0x74, 0x75, 0x6f, 0x6f, 0xa2, 0x75, + 0xa9, 0x1f, 0x98, 0x06, 0xa9, 0xa3, 0xa1, 0xa7, 0xa7, 0x73, 0xa1, 0x6d, + 0x1f, 0x7e, 0x06, 0x0e, 0xf7, 0x26, 0xf8, 0xf0, 0x15, 0xad, 0xfb, 0x91, + 0x05, 0x8e, 0x72, 0x94, 0x80, 0x9d, 0x8b, 0x9d, 0x8b, 0x94, 0x96, 0x8e, + 0xa4, 0x08, 0xad, 0xf7, 0x91, 0xfb, 0x14, 0x8b, 0x05, 0xf7, 0x48, 0x16, + 0xad, 0xfb, 0x91, 0x05, 0x8e, 0x72, 0x94, 0x80, 0x9d, 0x8b, 0x9d, 0x8b, + 0x94, 0x96, 0x8e, 0xa4, 0x08, 0xad, 0xf7, 0x91, 0xfb, 0x14, 0x8b, 0x05, + 0x0e, 0xf8, 0x1a, 0xf7, 0xf8, 0x15, 0xe6, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x32, 0x8b, 0x9b, 0xf7, 0x72, 0x05, 0x8c, + 0x9c, 0x84, 0x96, 0x7d, 0x8b, 0x7e, 0x8b, 0x85, 0x83, 0x8a, 0x7a, 0x08, + 0x7b, 0xfb, 0x75, 0x30, 0x8b, 0x9a, 0xf7, 0x72, 0x8c, 0x92, 0x05, 0x8c, + 0x96, 0x81, 0x95, 0x80, 0x8b, 0x7e, 0x8b, 0x84, 0x83, 0x8a, 0x7a, 0x08, + 0x7b, 0xfb, 0x75, 0x3a, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xd9, 0x8b, 0x82, 0xfb, 0x12, 0x32, 0x8b, 0x05, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xe2, 0x8b, 0x7b, 0xfb, + 0x72, 0x8b, 0x83, 0x05, 0x7f, 0x94, 0x82, 0x96, 0x1e, 0x98, 0x8b, 0x91, + 0x93, 0x8d, 0x9d, 0x08, 0x9a, 0xf7, 0x75, 0xe6, 0x8b, 0x7c, 0xfb, 0x72, + 0x8a, 0x83, 0x05, 0x8a, 0x81, 0x95, 0x80, 0x96, 0x8b, 0x98, 0x8b, 0x92, + 0x93, 0x8c, 0x9d, 0x08, 0x9b, 0xf7, 0x75, 0xde, 0x8b, 0x05, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x3b, 0x8b, 0x94, 0xf7, 0x12, + 0x05, 0x62, 0x16, 0x82, 0xfb, 0x12, 0x30, 0x8b, 0x94, 0xf7, 0x12, 0xe6, + 0x8b, 0x05, 0x0e, 0xf7, 0xac, 0xf8, 0xd4, 0x15, 0x37, 0x81, 0x4f, 0x50, + 0x8b, 0x43, 0x8b, 0x65, 0x9d, 0x67, 0xa8, 0x77, 0xa5, 0x7b, 0xa8, 0x81, + 0xcb, 0x7f, 0xce, 0x7e, 0x9b, 0x86, 0xa2, 0x7e, 0xa3, 0x7c, 0x99, 0x71, + 0x8b, 0x6d, 0x8b, 0x4c, 0x4d, 0x5e, 0x36, 0x8b, 0x08, 0x41, 0x8b, 0x48, + 0xb0, 0x87, 0xb6, 0x89, 0x9d, 0x86, 0x92, 0x7e, 0x8b, 0x08, 0x7d, 0x84, + 0x82, 0x79, 0x1f, 0x3c, 0x07, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, + 0x9d, 0x1e, 0x9b, 0x07, 0xa5, 0x6e, 0xc1, 0x74, 0xb9, 0x89, 0x08, 0xfb, + 0x0b, 0x07, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, + 0x0b, 0x07, 0xf1, 0x96, 0xcb, 0xc4, 0x8b, 0xda, 0x8b, 0xb6, 0x79, 0xaf, + 0x6c, 0xa0, 0x6f, 0x9e, 0x71, 0x93, 0x43, 0x99, 0x50, 0x96, 0x76, 0x91, + 0x77, 0x97, 0x08, 0x76, 0x98, 0x7d, 0xa3, 0x8b, 0xa5, 0x8b, 0xc4, 0xc3, + 0xba, 0xd0, 0x8b, 0xc8, 0x8b, 0xc4, 0x6c, 0x90, 0x67, 0x8d, 0x7b, 0x91, + 0x85, 0x98, 0x8b, 0x08, 0x98, 0x92, 0x94, 0x9d, 0x1f, 0xc7, 0x07, 0x9d, + 0x85, 0x94, 0x7d, 0x1e, 0x7e, 0x8b, 0x84, 0x81, 0x8a, 0x78, 0x67, 0xa7, + 0x74, 0x95, 0x5e, 0x8f, 0x08, 0xbf, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, + 0x84, 0x82, 0x79, 0x1e, 0x57, 0x07, 0x0e, 0xf7, 0xfd, 0xf7, 0x80, 0x15, + 0x48, 0x54, 0x53, 0x47, 0x47, 0xc2, 0x53, 0xcf, 0xcd, 0xc3, 0xc3, 0xcd, + 0xd2, 0x55, 0xc2, 0x46, 0x1f, 0x65, 0x04, 0xbb, 0xb0, 0x65, 0x5a, 0x5d, + 0x65, 0x64, 0x5d, 0x5c, 0x65, 0xb2, 0xba, 0xbb, 0xb1, 0xb1, 0xb9, 0x1f, + 0xfb, 0x10, 0xf8, 0x31, 0x15, 0x48, 0x54, 0x53, 0x47, 0x47, 0xc2, 0x53, + 0xcf, 0xcd, 0xc3, 0xc3, 0xce, 0xd1, 0x55, 0xc2, 0x46, 0x1f, 0x65, 0x04, + 0xbb, 0xb0, 0x65, 0x5a, 0x5d, 0x64, 0x64, 0x5e, 0x5c, 0x65, 0xb2, 0xba, + 0xba, 0xb1, 0xb2, 0xb9, 0x1f, 0xf7, 0x96, 0xfb, 0x79, 0x15, 0x98, 0x8f, + 0x90, 0x91, 0x8b, 0x94, 0x8b, 0x95, 0x83, 0x94, 0x82, 0x8b, 0x87, 0x8b, + 0x87, 0x8a, 0x87, 0x8a, 0x08, 0xfc, 0x0f, 0xfb, 0x0e, 0x05, 0x7e, 0x87, + 0x86, 0x85, 0x8b, 0x81, 0x8b, 0x81, 0x94, 0x82, 0x93, 0x8b, 0x8d, 0x8b, + 0x90, 0x8c, 0x90, 0x8d, 0x08, 0xf8, 0x0f, 0xf7, 0x0e, 0x05, 0x0e, 0xf8, + 0x1d, 0x16, 0xc5, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x65, 0x8b, 0x70, 0xb4, 0x05, 0x9f, 0xa7, 0x9e, 0xb9, 0x99, 0xbf, + 0x08, 0x97, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0x60, 0x06, 0x81, 0x5b, 0x7b, 0x60, 0x77, 0x66, 0x08, 0xfb, 0x03, 0xf7, + 0x45, 0x05, 0x6a, 0xbf, 0x80, 0xa4, 0x8b, 0xa2, 0x8b, 0xb5, 0xb2, 0xb1, + 0xb6, 0x8b, 0xa2, 0x8b, 0x9e, 0x83, 0xa0, 0x79, 0x08, 0xab, 0x9b, 0x05, + 0x97, 0x92, 0x8f, 0x90, 0x8b, 0x94, 0x8b, 0x96, 0x82, 0x95, 0x81, 0x8b, + 0x87, 0x8b, 0x85, 0x89, 0x85, 0x88, 0x08, 0x81, 0x85, 0x05, 0x74, 0x99, + 0x77, 0x91, 0x74, 0x8b, 0x48, 0x8b, 0x53, 0x55, 0x8b, 0x4a, 0x8b, 0x6e, + 0x90, 0x80, 0xb8, 0x42, 0x46, 0x76, 0x61, 0x54, 0x8b, 0x46, 0x08, 0x36, + 0xce, 0x42, 0xd9, 0x1e, 0xb9, 0x8b, 0xaf, 0xa0, 0xa9, 0xb6, 0x08, 0xaa, + 0x5b, 0x05, 0x54, 0xe1, 0x15, 0x75, 0x64, 0x6b, 0x75, 0x68, 0x8b, 0x54, + 0x8b, 0x5b, 0xc1, 0x8b, 0xca, 0x8b, 0xc2, 0xad, 0xb5, 0xc0, 0x97, 0x08, + 0xf4, 0xfb, 0x39, 0x05, 0x0e, 0xf7, 0x63, 0xf8, 0xf0, 0x15, 0x45, 0xfb, + 0x8e, 0x05, 0x8a, 0x87, 0x8a, 0x88, 0x8b, 0x87, 0x8b, 0x7b, 0x98, 0x7e, + 0x9b, 0x8b, 0x98, 0x8b, 0x93, 0x91, 0x95, 0x9e, 0x08, 0xf7, 0x25, 0xf7, + 0x9d, 0xfb, 0x19, 0x8b, 0x05, 0x0e, 0xf8, 0x4a, 0xf8, 0xf0, 0x15, 0x81, + 0x8b, 0x84, 0x84, 0x7a, 0x70, 0x44, 0xfb, 0x02, 0x64, 0xfb, 0x09, 0x8b, + 0x27, 0x8b, 0x24, 0xac, 0x23, 0xcf, 0xfb, 0x05, 0xa2, 0x66, 0x94, 0x81, + 0x95, 0x8b, 0x96, 0x8b, 0x95, 0x94, 0x8b, 0x96, 0x8b, 0x8f, 0x8a, 0x8d, + 0x89, 0x90, 0x08, 0x46, 0xf7, 0x10, 0x6c, 0xf1, 0x8b, 0xf6, 0x8b, 0xf6, + 0xaa, 0xf3, 0xd0, 0xf7, 0x0e, 0x8d, 0x90, 0x8c, 0x8d, 0x8b, 0x8f, 0x8b, + 0x96, 0x82, 0x94, 0x80, 0x8b, 0x08, 0x0e, 0xf7, 0x3c, 0xf8, 0xf0, 0x15, + 0x80, 0x81, 0x82, 0x80, 0x1f, 0x8b, 0x87, 0x8c, 0x89, 0x8d, 0x86, 0xd1, + 0xfb, 0x11, 0xa9, 0x27, 0x8b, 0xfb, 0x00, 0x8b, 0x20, 0x6c, 0x23, 0x46, + 0xfb, 0x0e, 0x89, 0x86, 0x8a, 0x89, 0x8b, 0x87, 0x8b, 0x80, 0x94, 0x82, + 0x96, 0x8b, 0x95, 0x8b, 0x92, 0x92, 0x9c, 0xa6, 0x08, 0xd2, 0xf7, 0x02, + 0xb2, 0xf7, 0x09, 0x8b, 0xef, 0x8b, 0xf2, 0x6a, 0xf4, 0x47, 0xf7, 0x04, + 0x74, 0xb1, 0x82, 0x94, 0x81, 0x8b, 0x08, 0x0e, 0xf7, 0xab, 0xf8, 0x4a, + 0x15, 0xfb, 0x19, 0xb5, 0x05, 0x84, 0x8d, 0x89, 0x8c, 0x87, 0x8b, 0x80, + 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x81, 0x93, 0x82, 0x93, 0x8a, 0x08, + 0x8f, 0x8a, 0xf7, 0x19, 0x61, 0x3a, 0xfb, 0x04, 0x05, 0x84, 0x81, 0x8a, + 0x89, 0x8b, 0x86, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x93, 0x8b, 0x90, + 0x8f, 0x93, 0x95, 0x08, 0xdc, 0xf7, 0x04, 0xdd, 0xfb, 0x04, 0x05, 0x93, + 0x80, 0x8f, 0x88, 0x93, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, + 0x90, 0x88, 0x91, 0x87, 0x92, 0x08, 0x3a, 0xf7, 0x04, 0xf7, 0x19, 0xb5, + 0x05, 0x9a, 0x90, 0x91, 0x91, 0x8b, 0x96, 0x8b, 0x95, 0x82, 0x95, 0x81, + 0x8b, 0x88, 0x8b, 0x84, 0x8a, 0x86, 0x89, 0x08, 0xfb, 0x19, 0x60, 0x8b, + 0xf7, 0x1f, 0x05, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, + 0xfb, 0x1f, 0x07, 0x0e, 0xf7, 0xd4, 0xf7, 0x99, 0x15, 0xf7, 0x48, 0x06, + 0x9e, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x48, 0xf7, + 0x5d, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0xfb, + 0x5d, 0xfb, 0x48, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x48, 0xfb, 0x5e, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, + 0x94, 0x9d, 0x1e, 0xf7, 0x5e, 0x07, 0x0e, 0xf7, 0x63, 0xf7, 0x25, 0x15, + 0x45, 0xfb, 0x8e, 0x05, 0x8a, 0x87, 0x8a, 0x88, 0x8b, 0x87, 0x8b, 0x7b, + 0x98, 0x7e, 0x9b, 0x8b, 0x98, 0x8b, 0x93, 0x91, 0x95, 0x9e, 0x08, 0xf7, + 0x25, 0xf7, 0x9d, 0xfb, 0x19, 0x8b, 0x05, 0x0e, 0xf8, 0x89, 0xf7, 0x96, + 0x15, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfc, 0x26, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x26, + 0x06, 0x0e, 0xf7, 0xbb, 0xf7, 0x08, 0x15, 0x64, 0x6d, 0x6f, 0x66, 0x66, + 0xa9, 0x6e, 0xb2, 0x1f, 0x95, 0x06, 0xb2, 0xa9, 0xa7, 0xb1, 0xb0, 0x6d, + 0xa7, 0x64, 0x1f, 0x81, 0x06, 0x0e, 0xf8, 0x76, 0xf9, 0x0d, 0x15, 0x8f, + 0x93, 0x8c, 0x8f, 0x8b, 0x8f, 0x8b, 0x95, 0x81, 0x94, 0x81, 0x8b, 0x81, + 0x8b, 0x86, 0x87, 0x84, 0x7d, 0x08, 0xfb, 0xdb, 0xfd, 0x4c, 0x05, 0x87, + 0x84, 0x8a, 0x86, 0x8b, 0x87, 0x8b, 0x81, 0x95, 0x82, 0x95, 0x8b, 0x95, + 0x8b, 0x90, 0x8f, 0x92, 0x99, 0x08, 0xf7, 0xdb, 0xf9, 0x4c, 0x05, 0x0e, + 0xf8, 0x7b, 0xf7, 0xf3, 0x15, 0xf7, 0x33, 0x3f, 0xf7, 0x00, 0xfb, 0x03, + 0xfb, 0x03, 0x3f, 0xfb, 0x00, 0xfb, 0x33, 0x1e, 0x27, 0x07, 0xfb, 0x32, + 0xd7, 0xfb, 0x00, 0xf7, 0x03, 0xf7, 0x03, 0xd7, 0xf7, 0x00, 0xf7, 0x32, + 0x1e, 0xef, 0x07, 0xfb, 0xe1, 0x86, 0x15, 0x8b, 0xcb, 0x9d, 0xcf, 0xa9, + 0xb9, 0xa1, 0xad, 0xad, 0x9e, 0xb5, 0x8b, 0xb5, 0x8b, 0xad, 0x78, 0xa1, + 0x69, 0xa9, 0x5d, 0x9d, 0x47, 0x8b, 0x4b, 0x08, 0x32, 0x07, 0x8b, 0x4b, + 0x79, 0x47, 0x6d, 0x5d, 0x75, 0x69, 0x69, 0x78, 0x61, 0x8b, 0x61, 0x8b, + 0x69, 0x9e, 0x75, 0xad, 0x6d, 0xb9, 0x79, 0xcf, 0x8b, 0xcb, 0x08, 0xe4, + 0x07, 0x0e, 0xf7, 0xd5, 0xf8, 0xf8, 0x15, 0xfb, 0x4d, 0x51, 0x05, 0x7b, + 0x86, 0x86, 0x85, 0x8b, 0x80, 0x8b, 0x81, 0x95, 0x81, 0x94, 0x8b, 0x8d, + 0x8b, 0x93, 0x8d, 0x8f, 0x8c, 0x08, 0xf7, 0x18, 0xb5, 0x8b, 0xfc, 0x98, + 0xfb, 0x1f, 0x8b, 0x05, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x95, 0x84, 0x9d, + 0x1f, 0xf7, 0xd3, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0xfb, 0x1f, 0xf8, 0xcf, 0x06, 0x0e, 0xf7, 0x0f, 0xb4, 0x15, 0x8e, + 0x07, 0xc4, 0xbb, 0xca, 0xc6, 0xe2, 0xe1, 0xf7, 0x10, 0xf7, 0x0d, 0x9f, + 0xa8, 0x8b, 0xc6, 0x8b, 0xe6, 0x35, 0xdc, 0x29, 0x8b, 0x4e, 0x8b, 0x53, + 0x6f, 0x66, 0x5b, 0x78, 0x73, 0x7e, 0x6d, 0x8b, 0x79, 0x8b, 0x82, 0x94, + 0x82, 0x95, 0x8b, 0x08, 0x96, 0x8b, 0x91, 0x91, 0x8f, 0x99, 0x9b, 0xc7, + 0xc9, 0xb8, 0xcf, 0x8b, 0xd7, 0x8b, 0xce, 0x4e, 0x8b, 0x46, 0x8b, 0x5e, + 0x78, 0x6f, 0x2d, 0x2f, 0x08, 0xfb, 0x80, 0xfb, 0x72, 0x8b, 0x4f, 0x05, + 0xf8, 0x1e, 0xd8, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, + 0x1e, 0x67, 0x07, 0xfb, 0xce, 0x06, 0x0e, 0xf8, 0x0a, 0xf7, 0xdc, 0x15, + 0x8d, 0x8c, 0x8d, 0x8c, 0x8c, 0x8b, 0xc7, 0xa4, 0xb1, 0xbf, 0x8b, 0xc4, + 0x8b, 0xe2, 0x3f, 0xce, 0x27, 0x8b, 0x57, 0x8b, 0x59, 0x7b, 0x64, 0x6d, + 0x76, 0x7b, 0x7d, 0x79, 0x8b, 0x81, 0x8b, 0x81, 0x94, 0x82, 0x96, 0x8b, + 0x08, 0x93, 0x8b, 0x8e, 0x8d, 0x95, 0x97, 0xa8, 0xad, 0xbc, 0x9f, 0xc3, + 0x8b, 0xd8, 0x8b, 0xc6, 0x5a, 0x8b, 0x4a, 0x8b, 0x61, 0x6f, 0x64, 0x61, + 0x79, 0x76, 0x81, 0x7b, 0x8a, 0x59, 0x8b, 0x08, 0x7a, 0x81, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xec, 0xdd, 0x49, 0x3d, 0x3e, 0x3f, 0x4a, + 0x30, 0x1f, 0x53, 0x8b, 0x53, 0x9e, 0x5c, 0xaf, 0x84, 0x90, 0x87, 0x8d, + 0x85, 0x8b, 0x81, 0x8b, 0x82, 0x82, 0x8b, 0x81, 0x8b, 0x7e, 0x98, 0x7e, + 0xac, 0x7a, 0xbf, 0x6f, 0xba, 0x7e, 0xbc, 0x8b, 0xf7, 0x07, 0x8b, 0xe9, + 0xdd, 0x8b, 0xf0, 0x08, 0x8b, 0xcf, 0x5c, 0xc7, 0x3d, 0xab, 0x08, 0x0e, + 0xf8, 0x0c, 0xf7, 0x3d, 0x15, 0xfb, 0x14, 0x3f, 0x07, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x2b, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf7, 0x14, 0xad, 0x06, 0x9d, + 0x94, 0x92, 0x98, 0x99, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf8, 0x1e, 0x37, + 0x06, 0xfb, 0x78, 0xfc, 0x18, 0x8b, 0x5c, 0xf7, 0xa3, 0x8b, 0x05, 0xb4, + 0x04, 0xfb, 0x7c, 0x8b, 0xf7, 0x64, 0xf7, 0xf5, 0xa3, 0x8b, 0x8b, 0xfb, + 0xf5, 0x05, 0x0e, 0xf7, 0x52, 0xf8, 0xc7, 0x15, 0xf7, 0x85, 0x06, 0x9e, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0xae, 0xfb, 0xa1, + 0x06, 0x7e, 0x93, 0x82, 0x96, 0x1e, 0x90, 0x8b, 0x90, 0x8d, 0x97, 0x91, + 0xb5, 0xa1, 0xb7, 0x96, 0xb3, 0x8b, 0x08, 0xdf, 0xc5, 0x4d, 0x32, 0x22, + 0x48, 0x43, 0x29, 0x1f, 0x51, 0x8b, 0x55, 0xa2, 0x5b, 0xb7, 0x84, 0x92, + 0x87, 0x8d, 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x7f, + 0x99, 0x7c, 0xab, 0x76, 0xbd, 0x6a, 0xbd, 0x7b, 0xc0, 0x8b, 0x08, 0xf7, + 0x0b, 0xe0, 0xe5, 0xf7, 0x12, 0xf7, 0x04, 0x40, 0xdd, 0x25, 0x1f, 0x5f, + 0x8b, 0x66, 0x82, 0x58, 0x76, 0x08, 0xf7, 0x5a, 0x07, 0x0e, 0xf7, 0x45, + 0xf7, 0x86, 0x15, 0x8a, 0x9e, 0x8a, 0x9a, 0x8b, 0x94, 0x8b, 0xcb, 0x9c, + 0xc9, 0xa7, 0xb7, 0xbc, 0xd6, 0xda, 0xba, 0xd7, 0x8b, 0x9e, 0x8b, 0x9d, + 0x88, 0x95, 0x86, 0x93, 0x86, 0x8f, 0x8a, 0x90, 0x8b, 0x08, 0x96, 0x93, + 0x94, 0x96, 0x9e, 0x67, 0x9b, 0x60, 0x1f, 0x4a, 0x8b, 0x4a, 0x72, 0x56, + 0x5d, 0x41, 0x4c, 0x68, 0x35, 0x8b, 0xfb, 0x08, 0x08, 0xfb, 0x43, 0xde, + 0xfb, 0x0e, 0xf7, 0x0a, 0xec, 0xd7, 0xe0, 0xf7, 0x00, 0xf1, 0x3f, 0xdf, + 0x30, 0x1e, 0x44, 0x8b, 0x55, 0x63, 0x62, 0x39, 0x08, 0x91, 0x55, 0x15, + 0xa3, 0xb7, 0x96, 0x9d, 0x9a, 0x9b, 0xab, 0xaf, 0xb3, 0xa0, 0xb0, 0x8b, + 0x08, 0xd1, 0xc4, 0x49, 0x3c, 0x35, 0x52, 0x49, 0x41, 0x1f, 0x47, 0x8b, + 0x58, 0xb8, 0x70, 0xdf, 0x88, 0x94, 0x8b, 0x8c, 0x85, 0xa2, 0x08, 0x0e, + 0xf8, 0x49, 0xf8, 0xb5, 0x15, 0xfb, 0x34, 0xfc, 0x95, 0x05, 0x8a, 0x87, + 0x8a, 0x85, 0x8b, 0x88, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x08, 0x95, + 0x8b, 0x90, 0x90, 0x90, 0x9b, 0x08, 0xf7, 0x37, 0xf8, 0x9b, 0x8b, 0xcc, + 0xfc, 0x09, 0x8b, 0x8b, 0x3f, 0x05, 0x78, 0x92, 0x82, 0x99, 0x98, 0x92, + 0x94, 0x9e, 0x1e, 0xae, 0xf7, 0xb7, 0x07, 0x79, 0x07, 0x0e, 0xf8, 0x0b, + 0xf7, 0xcd, 0x15, 0xd2, 0xaf, 0xaa, 0xb6, 0x8b, 0xc8, 0x08, 0xe5, 0x3a, + 0xd6, 0x2b, 0x2b, 0x3a, 0x40, 0x31, 0x1e, 0x8b, 0x4e, 0xab, 0x60, 0xd1, + 0x67, 0x08, 0x42, 0x69, 0x64, 0x57, 0x8b, 0x49, 0x08, 0x2a, 0xdf, 0x3c, + 0xf2, 0xf2, 0xdf, 0xda, 0xec, 0x1e, 0x8b, 0xcd, 0x64, 0xc0, 0x42, 0xac, + 0x08, 0x40, 0xf7, 0x9c, 0x15, 0xd7, 0xc7, 0x53, 0x44, 0x4a, 0x4e, 0x57, + 0x40, 0x3f, 0x4f, 0xbf, 0xcd, 0x1f, 0xd1, 0xc7, 0xc3, 0xd7, 0x1e, 0xfb, + 0xb0, 0x04, 0xde, 0xca, 0x52, 0x3f, 0x41, 0x49, 0x4f, 0x3b, 0x3a, 0x4a, + 0xc7, 0xd6, 0x1f, 0xd5, 0xcb, 0xc5, 0xdd, 0x1e, 0x0e, 0xf8, 0x69, 0xf7, + 0xfd, 0x15, 0x8c, 0x78, 0x8c, 0x7c, 0x8b, 0x82, 0x8b, 0x4b, 0x7a, 0x4d, + 0x6f, 0x5f, 0x5a, 0x40, 0x3c, 0x5c, 0x3f, 0x8b, 0x78, 0x8b, 0x79, 0x8e, + 0x81, 0x90, 0x83, 0x90, 0x87, 0x8c, 0x86, 0x8b, 0x08, 0x80, 0x83, 0x82, + 0x80, 0x1f, 0x78, 0xaf, 0x7b, 0xb6, 0x1e, 0xcc, 0x8b, 0xcc, 0xa4, 0xc0, + 0xb9, 0xd5, 0xca, 0xae, 0xe1, 0x8b, 0xf7, 0x08, 0x08, 0xf7, 0x43, 0x38, + 0xf7, 0x0e, 0xfb, 0x0a, 0x2a, 0x3f, 0x36, 0xfb, 0x00, 0x25, 0xd7, 0x37, + 0xe6, 0x1e, 0xd2, 0x8b, 0xc1, 0xb3, 0xb4, 0xdd, 0x08, 0x85, 0xc1, 0x15, + 0x73, 0x5f, 0x80, 0x79, 0x7c, 0x7b, 0x6b, 0x67, 0x63, 0x76, 0x66, 0x8b, + 0x08, 0x45, 0x52, 0xcd, 0xda, 0xe1, 0xc4, 0xcd, 0xd5, 0x1f, 0xcf, 0x8b, + 0xbe, 0x5e, 0xa6, 0x37, 0x8e, 0x82, 0x8b, 0x8a, 0x91, 0x74, 0x08, 0x0e, + 0xf7, 0xbb, 0xf7, 0x08, 0x15, 0x64, 0x6d, 0x6f, 0x66, 0x66, 0xa9, 0x6e, + 0xb2, 0x1f, 0x95, 0x06, 0xb2, 0xa9, 0xa7, 0xb1, 0xb0, 0x6d, 0xa7, 0x64, + 0x1f, 0x81, 0x06, 0xf7, 0xc1, 0x04, 0x64, 0x6d, 0x6e, 0x66, 0x66, 0xa9, + 0x6e, 0xb2, 0x1f, 0x95, 0x06, 0xb2, 0xa9, 0xa8, 0xb0, 0xb0, 0x6d, 0xa8, + 0x64, 0x1f, 0x81, 0x06, 0x0e, 0xf7, 0x67, 0xf7, 0x25, 0x15, 0x45, 0xfb, + 0x8e, 0x05, 0x8a, 0x87, 0x8a, 0x88, 0x8b, 0x87, 0x8b, 0x7b, 0x98, 0x7e, + 0x9b, 0x8b, 0x98, 0x8b, 0x93, 0x91, 0x95, 0x9e, 0x08, 0xf7, 0x25, 0xf7, + 0x9d, 0xfb, 0x19, 0x8b, 0x05, 0xc7, 0xf7, 0xa4, 0x15, 0x64, 0x6d, 0x6e, + 0x66, 0x66, 0xa9, 0x6e, 0xb2, 0x1f, 0x95, 0x06, 0xb2, 0xa9, 0xa8, 0xb0, + 0xb0, 0x6d, 0xa8, 0x64, 0x1f, 0x81, 0x06, 0x0e, 0xd3, 0xf7, 0xad, 0x15, + 0xf8, 0x35, 0xfb, 0x7c, 0x05, 0x90, 0x88, 0x90, 0x89, 0x8e, 0x8b, 0x91, + 0x8b, 0x91, 0x8f, 0x8e, 0x91, 0x08, 0x8d, 0x8e, 0x05, 0x8d, 0x8e, 0x8c, + 0x8f, 0x8b, 0x8e, 0x8b, 0x91, 0x87, 0x91, 0x82, 0x90, 0x08, 0xfb, 0xf7, + 0xf7, 0x59, 0xf7, 0xf7, 0xf7, 0x59, 0x05, 0x94, 0x90, 0x8f, 0x90, 0x8b, + 0x93, 0x8b, 0x8e, 0x8a, 0x8e, 0x89, 0x8e, 0x08, 0x8a, 0x8e, 0x05, 0x87, + 0x91, 0x85, 0x8f, 0x85, 0x8b, 0x88, 0x8b, 0x87, 0x89, 0x86, 0x88, 0x08, + 0xfc, 0x36, 0xfb, 0x7c, 0x05, 0x0e, 0xf8, 0x9e, 0xf7, 0xe2, 0x15, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfc, 0x50, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x50, 0x06, 0xfb, + 0x24, 0x04, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfc, + 0x50, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, + 0x50, 0x06, 0x0e, 0xf8, 0xa4, 0xf7, 0xad, 0x15, 0xfc, 0x35, 0xf7, 0x7c, + 0x05, 0x86, 0x8e, 0x86, 0x8d, 0x88, 0x8b, 0x85, 0x8b, 0x85, 0x87, 0x88, + 0x85, 0x08, 0x89, 0x88, 0x05, 0x89, 0x88, 0x8a, 0x88, 0x8b, 0x88, 0x8b, + 0x84, 0x8f, 0x85, 0x94, 0x86, 0x08, 0xf7, 0xf7, 0xfb, 0x59, 0xfb, 0xf7, + 0xfb, 0x59, 0x05, 0x82, 0x86, 0x87, 0x86, 0x8b, 0x84, 0x8b, 0x87, 0x8c, + 0x88, 0x8d, 0x88, 0x08, 0x8c, 0x88, 0x05, 0x8e, 0x85, 0x92, 0x87, 0x91, + 0x8b, 0x8e, 0x8b, 0x8f, 0x8d, 0x90, 0x8e, 0x08, 0xf8, 0x36, 0xf7, 0x7c, + 0x05, 0x0e, 0xf7, 0xd6, 0xf7, 0x8b, 0x15, 0xf7, 0x11, 0xc6, 0xb3, 0xb6, + 0x8b, 0xd5, 0x8b, 0xe7, 0x43, 0xc9, 0x21, 0x8b, 0x58, 0x8b, 0x6b, 0x83, + 0x4c, 0x6f, 0x83, 0x88, 0x7f, 0x85, 0x82, 0x88, 0x08, 0x47, 0x07, 0x79, + 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xb4, 0x07, 0xbf, 0xa5, + 0xab, 0x93, 0xb8, 0x8b, 0xde, 0x8b, 0xc6, 0x5c, 0x8b, 0x49, 0x8b, 0x52, + 0x5a, 0x60, 0xfb, 0x08, 0x5a, 0x08, 0x47, 0x07, 0x79, 0x92, 0x82, 0x99, + 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xb4, 0x07, 0x68, 0xfb, 0x36, 0x15, 0x69, + 0x74, 0x77, 0x6d, 0x6d, 0xa2, 0x77, 0xad, 0x1f, 0xa6, 0x06, 0xad, 0xa2, + 0xa0, 0xa8, 0xa9, 0x74, 0x9f, 0x69, 0x1f, 0x70, 0x06, 0x0e, 0xf8, 0x36, + 0xf7, 0x25, 0x15, 0xac, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x1f, 0x8b, 0x96, + 0x84, 0x92, 0x7f, 0x8d, 0x08, 0xf7, 0xa9, 0x07, 0xe7, 0x47, 0xd0, 0x30, + 0xfb, 0x05, 0x39, 0xfb, 0x03, 0xfb, 0x2c, 0x1e, 0xfb, 0x37, 0x07, 0x8b, + 0x44, 0x9d, 0x4d, 0xaf, 0x57, 0xaf, 0x58, 0xb7, 0x73, 0xc7, 0x8b, 0x08, + 0xd5, 0xd7, 0xab, 0xaa, 0x95, 0x82, 0x94, 0x80, 0x1f, 0x84, 0x8b, 0x8a, + 0x8a, 0x80, 0x81, 0x76, 0x79, 0x62, 0x7f, 0x60, 0x8b, 0x59, 0x8b, 0x68, + 0x9d, 0x70, 0xb2, 0x6d, 0xb8, 0x7a, 0xc4, 0x8b, 0xc7, 0x08, 0xf7, 0x34, + 0x07, 0xf7, 0x18, 0xcb, 0xe8, 0xe6, 0xcf, 0xbc, 0x59, 0x45, 0x1e, 0x5c, + 0x07, 0x25, 0x8c, 0x41, 0x4e, 0x8b, 0x37, 0x8b, 0x44, 0xc5, 0x55, 0xd9, + 0x8b, 0x95, 0x8b, 0x95, 0x8c, 0x9f, 0x8d, 0x08, 0x86, 0x07, 0xba, 0x04, + 0x7f, 0x88, 0x7d, 0x8a, 0x80, 0x8b, 0x08, 0x51, 0x63, 0xae, 0xbd, 0xc7, + 0xc4, 0xb6, 0xd9, 0x1f, 0xfb, 0x4c, 0x07, 0x0e, 0xf8, 0x40, 0xf7, 0x50, + 0x15, 0xc3, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x30, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0x66, 0x8b, 0xfb, 0x59, 0xf8, 0x9e, 0xfb, 0x60, + 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x0c, 0x8b, 0xfb, 0x47, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x2b, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x3c, 0x8b, 0xc1, 0xf7, 0x27, 0xf7, + 0x9e, 0x8b, 0x05, 0x7c, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, 0x00, 0xf7, + 0xb9, 0x9a, 0x8b, 0xf7, 0x04, 0xfb, 0xb9, 0x05, 0x0e, 0xf7, 0x10, 0xb4, + 0x15, 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xf7, 0xc6, 0x06, 0xe6, 0xd5, 0xd0, 0xdf, 0x1f, 0x8b, 0xce, 0x60, 0xbb, + 0x37, 0xa9, 0xc6, 0xab, 0xa5, 0xb0, 0x8b, 0xbe, 0x08, 0xdd, 0x41, 0xca, + 0x2a, 0x1e, 0xfb, 0x96, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x06, 0xb4, 0xf7, 0xa4, 0x15, 0xf7, 0x65, + 0xf7, 0x38, 0x07, 0xd4, 0xc3, 0x5e, 0x51, 0x4d, 0x4e, 0x5f, 0x36, 0x1f, + 0xfb, 0x27, 0x06, 0xfb, 0xa4, 0x04, 0xf7, 0x7b, 0xf7, 0x29, 0x07, 0xc8, + 0x8b, 0xad, 0x84, 0xab, 0x78, 0xb0, 0x75, 0xa1, 0x68, 0x8b, 0x67, 0x08, + 0x4d, 0x53, 0x59, 0x44, 0x1e, 0xfb, 0x64, 0x06, 0x0e, 0xf8, 0x72, 0xf8, + 0x8f, 0x15, 0x5c, 0xb8, 0x4f, 0xa3, 0x49, 0x8b, 0x48, 0x8b, 0x50, 0x71, + 0x5e, 0x5b, 0x60, 0x5d, 0x6f, 0x45, 0x8b, 0x4e, 0x08, 0x38, 0x07, 0xfb, + 0x1b, 0xf7, 0x0f, 0xfb, 0x0f, 0xf7, 0x1c, 0x1e, 0xcb, 0x8b, 0xc8, 0xa4, + 0xbc, 0xb9, 0xa5, 0xa3, 0x97, 0x9c, 0x8b, 0x95, 0x8b, 0x96, 0x83, 0x93, + 0x7f, 0x8b, 0x84, 0x8b, 0x87, 0x89, 0x84, 0x83, 0x55, 0x4b, 0x58, 0x71, + 0x46, 0x8b, 0x08, 0xfb, 0x0a, 0x27, 0xf2, 0xf7, 0x0c, 0x1f, 0xd2, 0x07, + 0xf7, 0x0b, 0xe5, 0xec, 0xf7, 0x03, 0x1e, 0xe4, 0x8b, 0xdb, 0x56, 0x8f, + 0x4e, 0x8c, 0x7b, 0x92, 0x83, 0x97, 0x8b, 0x08, 0x99, 0x92, 0x94, 0x9d, + 0x1f, 0xf7, 0x04, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, + 0x1e, 0x6e, 0x07, 0x0e, 0xf3, 0xb4, 0x15, 0x69, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x70, 0x06, 0xf7, 0x15, 0xf0, + 0xf7, 0x04, 0xf7, 0x22, 0x1f, 0xc3, 0x07, 0xf7, 0x21, 0x26, 0xf7, 0x04, + 0xfb, 0x15, 0x1e, 0xfb, 0x70, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xad, 0xfc, 0x75, 0x06, 0xb4, 0x16, 0xf8, 0x75, 0xf7, + 0x23, 0x07, 0xc1, 0x8b, 0xb0, 0x7c, 0xae, 0x68, 0xb3, 0x62, 0xa4, 0x4f, + 0x8b, 0x56, 0x08, 0x42, 0x07, 0x21, 0x33, 0x29, 0x2b, 0x1e, 0xfb, 0x2a, + 0x06, 0x0e, 0xf7, 0x39, 0xf7, 0xa4, 0x15, 0xf7, 0x25, 0x5e, 0x06, 0x79, + 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x17, 0x07, 0x9d, + 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x5e, 0xfb, 0x25, 0xf7, + 0x65, 0xf7, 0xb9, 0x29, 0x07, 0x79, 0x92, 0x82, 0x98, 0x99, 0x92, 0x94, + 0x9d, 0x1e, 0xf7, 0x1f, 0xfc, 0x41, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x55, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x56, 0xf7, 0x34, 0x06, 0x9d, + 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0xfb, 0x0b, 0xfb, 0xce, + 0x07, 0xf7, 0x7b, 0x07, 0x0e, 0xf7, 0x39, 0xf7, 0xa4, 0x15, 0xf7, 0x25, + 0x5e, 0x06, 0x79, 0x92, 0x82, 0x98, 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xf7, + 0x17, 0x07, 0x9d, 0x84, 0x94, 0x7d, 0x7e, 0x84, 0x82, 0x79, 0x1e, 0x5e, + 0xfb, 0x25, 0xf7, 0x65, 0xf7, 0xce, 0x29, 0x07, 0x79, 0x92, 0x82, 0x98, + 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x1f, 0xfc, 0x56, 0x07, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x55, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x7d, 0x06, + 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x1e, 0xf7, + 0x7b, 0x06, 0x0e, 0xf8, 0x9c, 0xf7, 0x65, 0x15, 0x99, 0x06, 0x9e, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x56, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x1f, 0xfb, 0x2a, 0x06, + 0x53, 0x71, 0x68, 0x83, 0x57, 0x8b, 0x08, 0xfb, 0x24, 0x33, 0xde, 0xf7, + 0x1c, 0x1f, 0xd4, 0x07, 0x8b, 0xc6, 0xa7, 0xcb, 0xb7, 0xb4, 0xb1, 0xb0, + 0xb8, 0x9c, 0xc3, 0x8b, 0xe4, 0x8b, 0xd3, 0x62, 0x8f, 0x58, 0x8c, 0x7a, + 0x91, 0x83, 0x98, 0x8b, 0x08, 0x98, 0x92, 0x94, 0x9d, 0x1f, 0xe6, 0x07, + 0x9e, 0x85, 0x93, 0x7d, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x7d, 0x07, 0x5e, + 0xaf, 0x54, 0x9d, 0x49, 0x8b, 0x49, 0x8b, 0x51, 0x74, 0x5e, 0x61, 0x59, + 0x5b, 0x6c, 0x41, 0x8b, 0x44, 0x08, 0x41, 0x07, 0xfb, 0x32, 0xf5, 0x25, + 0xf7, 0x38, 0x1e, 0xc9, 0x8b, 0xcd, 0x9d, 0xc6, 0xad, 0x08, 0xf7, 0x41, + 0x07, 0x0e, 0xf8, 0x49, 0xf7, 0xa4, 0x15, 0xfb, 0x7b, 0x55, 0x07, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x21, 0x06, 0x9c, + 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x5d, 0xf8, 0x75, 0xa4, + 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x0c, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfb, + 0x65, 0xfb, 0xa2, 0xf7, 0x65, 0xc1, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x0c, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xa4, 0xfc, 0x75, 0x5e, 0x06, 0x78, 0x82, 0x84, + 0x7e, 0x7d, 0x95, 0x84, 0x9d, 0x1f, 0xf7, 0x20, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x55, 0xf7, 0x7b, 0xf7, 0xa2, 0x06, + 0x0e, 0xf7, 0xd4, 0xf8, 0x9e, 0x15, 0xf7, 0x1f, 0x06, 0x9e, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0xd3, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x1f, 0xfc, 0x75, 0xfb, 0x1f, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xd3, + 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x1f, + 0xf8, 0x75, 0x06, 0x0e, 0xf8, 0x60, 0xf8, 0x9e, 0x15, 0xeb, 0x06, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0xbc, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x33, 0xfb, 0xf9, + 0x06, 0x3d, 0x4a, 0x4d, 0x3a, 0x1e, 0x59, 0x8b, 0x5c, 0xa1, 0x58, 0xb9, + 0x08, 0xf7, 0x16, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, + 0x1e, 0xfb, 0x29, 0x07, 0xd3, 0x4a, 0xbf, 0x72, 0xcb, 0x8b, 0x08, 0xf2, + 0xe0, 0xdd, 0xee, 0x1f, 0xf7, 0xf9, 0x07, 0x0e, 0xf7, 0x39, 0xf7, 0x71, + 0x15, 0xdc, 0xd4, 0x05, 0xea, 0x6c, 0xb7, 0x4f, 0xd4, 0xfb, 0x5f, 0x08, + 0xe2, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x53, + 0x06, 0x40, 0xf7, 0x54, 0x66, 0xbe, 0x2a, 0xb3, 0x08, 0xf7, 0x72, 0xf7, + 0x5a, 0x9b, 0x8b, 0x05, 0x9e, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, + 0x1f, 0xfb, 0x0a, 0x06, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, + 0x1f, 0xb8, 0x8b, 0xfb, 0xac, 0xfb, 0x8d, 0x8b, 0xf7, 0x8d, 0xd6, 0x8b, + 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x3e, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, + 0x75, 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xf7, 0x3e, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0x40, 0xf7, 0x48, 0x06, 0x0e, 0xf7, 0x77, 0xf8, 0x9e, 0x15, 0xeb, 0x06, + 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x7d, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xeb, 0xfc, 0x75, + 0x2b, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, + 0x57, 0xf7, 0x5d, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, + 0x1e, 0xfb, 0x34, 0xfb, 0xa5, 0xf8, 0x75, 0x07, 0x0e, 0xf7, 0xda, 0xf7, + 0x3d, 0x15, 0xf7, 0x31, 0xf7, 0xf5, 0x93, 0x8b, 0x8b, 0xfc, 0x75, 0x41, + 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x29, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, + 0xf8, 0x75, 0xa4, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x27, 0x8b, 0xfb, 0x2e, 0xfb, 0xf0, 0xfb, 0x31, 0xf7, 0xf0, 0x28, + 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xa4, + 0xfc, 0x75, 0x69, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x29, 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, + 0x1f, 0x41, 0xf8, 0x75, 0x93, 0x06, 0xf7, 0x33, 0xfb, 0xf5, 0xb9, 0x8b, + 0x05, 0x0e, 0xf8, 0x89, 0x16, 0xf8, 0x9e, 0xad, 0x07, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x29, 0x06, 0x78, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xd5, 0xfc, 0x63, 0x06, 0xfb, 0xc5, + 0xf8, 0x8c, 0x21, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x69, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x2a, 0x06, 0x9c, 0x95, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0x40, 0xf8, 0x63, 0x06, 0xf7, 0xc5, 0xfc, 0x8c, + 0xbf, 0x8b, 0x05, 0x0e, 0xf7, 0xc0, 0xf8, 0xd4, 0x15, 0xfb, 0x1f, 0xfb, + 0x02, 0xfb, 0x17, 0xfb, 0x39, 0xfb, 0x39, 0xf7, 0x02, 0xfb, 0x17, 0xf7, + 0x1f, 0xf7, 0x1d, 0xf7, 0x04, 0xf7, 0x17, 0xf7, 0x35, 0xf7, 0x3e, 0xfb, + 0x00, 0xf7, 0x16, 0xfb, 0x21, 0x1f, 0x62, 0x04, 0xf7, 0x08, 0xe7, 0xfb, + 0x06, 0xfb, 0x24, 0xfb, 0x1d, 0x2c, 0xfb, 0x07, 0xfb, 0x05, 0xfb, 0x06, + 0x2d, 0xf7, 0x07, 0xf7, 0x20, 0xf7, 0x20, 0xe8, 0xf7, 0x07, 0xf7, 0x07, + 0x1f, 0x0e, 0xf7, 0x39, 0xf7, 0x7b, 0x15, 0xf7, 0x17, 0x06, 0xf7, 0x06, + 0xe4, 0xd5, 0xe8, 0xe8, 0x38, 0xd3, 0x21, 0x1f, 0xfb, 0x84, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x55, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x7d, + 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x1e, + 0xf7, 0x52, 0x06, 0xb4, 0x04, 0xf7, 0x8e, 0xf7, 0x29, 0x07, 0xda, 0xcc, + 0x53, 0x47, 0x46, 0x43, 0x52, 0x34, 0x1f, 0xfb, 0x1a, 0x06, 0x0e, 0xf7, + 0xc5, 0x7b, 0x15, 0xf7, 0x1e, 0x8f, 0xf5, 0xf7, 0x14, 0x8b, 0xf7, 0x38, + 0x08, 0xf7, 0x39, 0xfb, 0x02, 0xf7, 0x17, 0xfb, 0x1f, 0xfb, 0x1f, 0xfb, + 0x02, 0xfb, 0x17, 0xfb, 0x39, 0x1e, 0x8b, 0xfb, 0x21, 0xdf, 0xfb, 0x10, + 0xf7, 0x06, 0x72, 0x08, 0x31, 0x4a, 0x05, 0x84, 0x86, 0x87, 0x85, 0x8b, + 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x8e, 0x8b, 0x8e, 0x8c, 0x8f, + 0x8c, 0xb6, 0x97, 0xce, 0x96, 0xa9, 0x8b, 0xa4, 0x8b, 0x9b, 0x88, 0xa6, + 0x81, 0x08, 0xa8, 0x81, 0x96, 0x88, 0x9b, 0x8b, 0x08, 0xb5, 0xc9, 0xaa, + 0x9f, 0x97, 0x82, 0x94, 0x80, 0x1f, 0x87, 0x8b, 0x87, 0x8a, 0x87, 0x88, + 0x6c, 0x77, 0x7a, 0x84, 0x76, 0x8b, 0x7e, 0x8b, 0x83, 0x8d, 0x73, 0x94, + 0x08, 0x6d, 0x96, 0x74, 0x8f, 0x6e, 0x8b, 0x76, 0x8b, 0x7b, 0x89, 0x6d, + 0x85, 0x08, 0xc1, 0xb3, 0x05, 0x86, 0xf8, 0xbb, 0x15, 0xf7, 0x08, 0xe7, + 0xfb, 0x06, 0xfb, 0x24, 0xfb, 0x1d, 0x2c, 0xfb, 0x07, 0xfb, 0x05, 0xfb, + 0x06, 0x2d, 0xf7, 0x07, 0xf7, 0x20, 0xf7, 0x20, 0xe8, 0xf7, 0x07, 0xf7, + 0x07, 0x1f, 0x0e, 0xf7, 0x39, 0xf7, 0x8f, 0x15, 0xf7, 0x18, 0x06, 0xd7, + 0x68, 0xb7, 0x55, 0xe3, 0xfb, 0x36, 0x08, 0xc4, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x6c, 0x06, 0x3a, 0xf7, 0x21, 0x6f, + 0xb0, 0x4c, 0xb6, 0xe8, 0xab, 0xb9, 0xbb, 0x8b, 0xcc, 0x08, 0xdf, 0x38, + 0xd3, 0x2a, 0x1e, 0xfb, 0x8c, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x3e, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x40, 0xf7, 0x66, 0x06, 0xb4, 0x04, 0xf7, + 0x7a, 0xf7, 0x2d, 0x07, 0xd3, 0xce, 0x55, 0x4f, 0x4b, 0x3b, 0x57, 0x29, + 0x1f, 0xfb, 0x06, 0x06, 0x0e, 0xf8, 0x51, 0xf8, 0x99, 0x15, 0x61, 0xb4, + 0x5e, 0x9d, 0x50, 0x8b, 0x22, 0x8b, 0x3c, 0x48, 0x8b, 0x33, 0x8b, 0x61, + 0x9e, 0x64, 0xac, 0x74, 0xa9, 0x75, 0xaf, 0x7f, 0xd1, 0x7f, 0xd2, 0x7f, + 0xa0, 0x85, 0xa3, 0x7b, 0x08, 0xa7, 0x7a, 0x9c, 0x6b, 0x8b, 0x68, 0x8b, + 0x41, 0x45, 0x55, 0x2e, 0x8b, 0x30, 0x8b, 0x41, 0xbe, 0x88, 0xcd, 0x8a, + 0x9b, 0x85, 0x93, 0x7e, 0x8b, 0x08, 0x7d, 0x84, 0x82, 0x79, 0x1f, 0xfb, + 0x04, 0x07, 0x79, 0x92, 0x82, 0x98, 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xa8, + 0x07, 0xb4, 0x5c, 0xc6, 0x72, 0xd0, 0x8b, 0xf7, 0x0c, 0x8b, 0xe1, 0xd1, + 0x8b, 0xec, 0x8b, 0xbe, 0x74, 0xb6, 0x64, 0xa3, 0x6d, 0x9e, 0x6f, 0x93, + 0x3e, 0x98, 0x4d, 0x95, 0x72, 0x93, 0x71, 0x9c, 0x08, 0x72, 0x9c, 0x7d, + 0xa7, 0x8b, 0xaa, 0x8b, 0xcd, 0xc8, 0xbc, 0xdd, 0x8b, 0xd9, 0x8b, 0xc8, + 0x5e, 0x8f, 0x4f, 0x8c, 0x7b, 0x92, 0x83, 0x98, 0x8b, 0x08, 0x98, 0x92, + 0x94, 0x9d, 0x1f, 0xf2, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, + 0x79, 0x1e, 0x78, 0x07, 0x0e, 0xf7, 0xd5, 0xb4, 0x15, 0xf8, 0x75, 0xf7, + 0x3a, 0x42, 0x07, 0x7b, 0x94, 0x80, 0x97, 0x99, 0x91, 0x93, 0x9e, 0x1e, + 0xf7, 0x06, 0xfc, 0x5c, 0xfb, 0x06, 0x07, 0x79, 0x92, 0x82, 0x98, 0x99, + 0x92, 0x94, 0x9d, 0x1e, 0xd4, 0xf7, 0x3b, 0xfc, 0x75, 0x22, 0x07, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x8f, 0x06, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x22, 0x06, 0x0e, 0xf8, + 0x87, 0xf8, 0x9e, 0x15, 0xad, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x83, + 0x91, 0x78, 0x1f, 0xfb, 0x29, 0x06, 0x78, 0x83, 0x85, 0x7d, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xd5, 0xfb, 0xe5, 0x06, 0x31, 0x45, 0x45, 0x33, 0x32, + 0x46, 0xd1, 0xe5, 0x1e, 0xf7, 0xe5, 0xd5, 0x07, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x29, 0x06, 0x79, 0x82, 0x85, 0x7d, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xad, 0xfb, 0xe5, 0x06, 0xfb, 0x06, 0xe1, + 0x34, 0xf7, 0x05, 0xf7, 0x04, 0xe2, 0xe2, 0xf7, 0x06, 0x1e, 0xf7, 0xe5, + 0x07, 0x0e, 0xf7, 0x9f, 0x16, 0xc4, 0x8b, 0xf7, 0x65, 0xf8, 0x9e, 0xaa, + 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x82, 0x91, 0x79, 0x1f, 0xfb, + 0x2a, 0x06, 0x78, 0x83, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xd9, + 0x8b, 0xfb, 0x55, 0xfc, 0x75, 0x88, 0x8b, 0xfb, 0x4e, 0xf8, 0x75, 0xd8, + 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x82, 0x91, 0x79, 0x1f, 0xfb, + 0x2b, 0x06, 0x79, 0x82, 0x85, 0x7d, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xaa, + 0x8b, 0xf7, 0x5c, 0xfc, 0x9e, 0x05, 0x0e, 0xf7, 0x0e, 0x16, 0xca, 0x8b, + 0xf7, 0x07, 0xf8, 0x24, 0xf7, 0x04, 0xfc, 0x24, 0xcb, 0x8b, 0xc9, 0xf8, + 0x9e, 0x9a, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0xfb, 0x2a, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xeb, 0x8b, 0x52, 0xfc, 0x70, 0xfb, 0x01, 0xf8, 0x1c, 0x4d, 0x8b, + 0xfb, 0x04, 0xfc, 0x1c, 0x53, 0xf8, 0x70, 0xe8, 0x8b, 0x05, 0x9e, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x29, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0x9a, 0x8b, 0xc7, 0xfc, 0x9e, + 0x05, 0x0e, 0xf7, 0xd9, 0xf7, 0xb4, 0x15, 0xf7, 0x47, 0xf7, 0x7e, 0x9a, + 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x82, 0x91, 0x79, 0x1f, 0xfb, + 0x03, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xb8, + 0x8b, 0xfb, 0x2d, 0xfb, 0x5d, 0xfb, 0x2f, 0xf7, 0x5d, 0xb6, 0x8b, 0x05, + 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x02, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0x9a, 0x8b, 0xf7, + 0x47, 0xfb, 0x7e, 0xfb, 0x50, 0xfb, 0x8b, 0x7a, 0x8b, 0x05, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x17, 0x06, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x4b, 0x8b, 0xf7, 0x38, 0xf7, + 0x6a, 0xf7, 0x39, 0xfb, 0x6a, 0x4d, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x18, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x7a, 0x8b, 0xfb, 0x53, 0xf7, 0x8b, 0x05, + 0x0e, 0xf7, 0xd6, 0xf7, 0x92, 0x15, 0xf7, 0x44, 0xf7, 0xa0, 0xa3, 0x8b, + 0x05, 0x9b, 0x96, 0x93, 0x98, 0x97, 0x81, 0x93, 0x7a, 0x1f, 0xfb, 0x02, + 0x06, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xb3, 0x8b, + 0xfb, 0x29, 0xfb, 0x77, 0xfb, 0x2c, 0xf7, 0x77, 0xb1, 0x8b, 0x05, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x03, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xa3, 0x8b, 0xf7, 0x47, + 0xfb, 0xa0, 0x8b, 0xfb, 0x69, 0x22, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x8f, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x22, 0xf7, 0x69, 0x06, 0x0e, 0xf8, 0x85, + 0x16, 0xf7, 0x4a, 0x07, 0x9d, 0x84, 0x94, 0x7d, 0x7d, 0x85, 0x82, 0x79, + 0x1e, 0xfb, 0x21, 0xfb, 0xce, 0x8f, 0x07, 0xf7, 0xdc, 0xf8, 0x60, 0x8b, + 0xc5, 0xfb, 0xf1, 0x8b, 0x8b, 0xfb, 0x33, 0x05, 0x78, 0x92, 0x82, 0x99, + 0x98, 0x92, 0x94, 0x9e, 0x1e, 0xf7, 0x0a, 0xf7, 0xa1, 0x88, 0x07, 0xfb, + 0xdc, 0xfc, 0x60, 0x8b, 0x50, 0xf8, 0x1e, 0x8b, 0x05, 0x0e, 0xf7, 0xd5, + 0xf8, 0xc7, 0x15, 0xec, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0xfb, 0x1e, 0xfd, 0x6c, 0xf7, 0x1e, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x2a, 0xf9, 0x1a, 0x06, 0x0e, 0xf7, + 0x2f, 0xf9, 0x1e, 0x15, 0x84, 0x99, 0x86, 0x8f, 0x82, 0x8b, 0x80, 0x8b, + 0x81, 0x82, 0x8b, 0x81, 0x8b, 0x87, 0x8c, 0x87, 0x8f, 0x83, 0x08, 0xf7, + 0xdb, 0xfd, 0x4c, 0x05, 0x92, 0x7d, 0x90, 0x87, 0x95, 0x8b, 0x95, 0x8b, + 0x95, 0x94, 0x8b, 0x95, 0x8b, 0x8f, 0x8a, 0x90, 0x87, 0x92, 0x08, 0xfb, + 0xdb, 0xf9, 0x4c, 0x05, 0x0e, 0xf7, 0xab, 0x38, 0x15, 0x2a, 0x06, 0x79, + 0x82, 0x84, 0x7d, 0x7e, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x1e, 0xf9, 0x6c, + 0xfb, 0x1e, 0x06, 0x79, 0x82, 0x84, 0x7d, 0x7e, 0x94, 0x84, 0x9d, 0x1f, + 0xec, 0xfd, 0x1a, 0x06, 0x0e, 0xf7, 0xc0, 0xf8, 0xfb, 0x15, 0xfb, 0x46, + 0xfb, 0x73, 0x05, 0x84, 0x83, 0x89, 0x87, 0x8b, 0x85, 0x8b, 0x80, 0x94, + 0x82, 0x96, 0x8b, 0x93, 0x8b, 0x90, 0x8e, 0x92, 0x95, 0x08, 0xf7, 0x27, + 0xf7, 0x4d, 0xf7, 0x27, 0xfb, 0x4d, 0x05, 0x92, 0x81, 0x90, 0x88, 0x93, + 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x90, 0x88, 0x91, 0x85, + 0x92, 0x08, 0xfb, 0x46, 0xf7, 0x73, 0x05, 0x0e, 0xf8, 0xf8, 0x40, 0x15, + 0xfd, 0x04, 0x59, 0xf9, 0x04, 0xbd, 0x06, 0x0e, 0xf8, 0x1d, 0xf8, 0xf0, + 0x15, 0xfb, 0x19, 0x8b, 0xf7, 0x25, 0xfb, 0x83, 0x05, 0x95, 0x7a, 0x93, + 0x86, 0x98, 0x8b, 0x9b, 0x8b, 0x98, 0x97, 0x8b, 0x99, 0x8b, 0x8e, 0x8a, + 0x8f, 0x8a, 0x8e, 0x08, 0x45, 0xf7, 0x75, 0x05, 0x0e, 0xf8, 0x37, 0x16, + 0xea, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x55, + 0xf7, 0x9f, 0x06, 0xd2, 0x47, 0xbf, 0x2e, 0x1e, 0x66, 0x8b, 0x4a, 0x7e, + 0x54, 0x78, 0x80, 0x87, 0x85, 0x84, 0x8b, 0x81, 0x8b, 0x80, 0x94, 0x82, + 0x95, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, 0x8f, 0x8c, 0xd9, 0xa3, 0xa7, 0x91, + 0xaf, 0x8b, 0x08, 0xd4, 0xbd, 0x6a, 0x5a, 0x1f, 0x44, 0x07, 0x50, 0x9b, + 0x6c, 0x90, 0x5d, 0x8b, 0x08, 0xfb, 0x11, 0x35, 0x50, 0x34, 0x1f, 0x3f, + 0xca, 0x57, 0xe8, 0x1e, 0xd1, 0x8b, 0xc7, 0xa5, 0xc8, 0xc4, 0x08, 0x48, + 0x07, 0xf7, 0x04, 0x04, 0x48, 0x4c, 0x55, 0x73, 0x44, 0x8b, 0x08, 0x46, + 0x5e, 0xad, 0xbf, 0xca, 0xd3, 0xb6, 0xf5, 0x1f, 0xb7, 0x8b, 0xbb, 0x85, + 0xaf, 0x82, 0x08, 0x31, 0x07, 0x0e, 0xf7, 0x24, 0xf8, 0xf0, 0x15, 0x2c, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, + 0x9e, 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xea, 0xe3, 0x06, 0xba, 0x45, 0xc7, 0x69, 0xd4, 0x8b, 0x08, 0xf7, 0x0c, + 0xec, 0xf0, 0xf7, 0x11, 0xf7, 0x10, 0x2c, 0xec, 0xfb, 0x0e, 0x1f, 0x41, + 0x8b, 0x53, 0x6b, 0x59, 0x44, 0x08, 0xf7, 0xa8, 0x07, 0xf7, 0x46, 0xfb, + 0x6a, 0x15, 0xef, 0xd9, 0x3a, 0x23, 0x29, 0x3a, 0x39, 0x2a, 0x1f, 0x28, + 0x3c, 0xdd, 0xf0, 0xf0, 0xda, 0xdc, 0xee, 0x1f, 0x0e, 0xf8, 0x6a, 0xf8, + 0x0c, 0x15, 0x62, 0xaf, 0x55, 0x9e, 0x4e, 0x8b, 0x08, 0xfb, 0x1a, 0x2b, + 0x2c, 0xfb, 0x18, 0xfb, 0x14, 0xe9, 0x2f, 0xf7, 0x17, 0x1f, 0xcd, 0x8b, + 0xcd, 0x9f, 0xbe, 0xae, 0xa7, 0x9e, 0x9a, 0x9d, 0x8b, 0x97, 0x8b, 0x95, + 0x82, 0x94, 0x81, 0x8b, 0x84, 0x8b, 0x88, 0x89, 0x83, 0x83, 0x57, 0x5b, + 0x4d, 0x73, 0x42, 0x8b, 0x08, 0xfb, 0x01, 0x3e, 0xd6, 0xf4, 0xf7, 0x02, + 0xd7, 0xd6, 0xf7, 0x02, 0x1f, 0xdf, 0x8b, 0xd2, 0x61, 0x8f, 0x56, 0x8d, + 0x7a, 0x91, 0x84, 0x98, 0x8b, 0x08, 0x98, 0x92, 0x94, 0x9d, 0x1f, 0xe6, + 0x07, 0x9e, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x78, 0x1e, 0x7e, 0x07, + 0x0e, 0xf8, 0x8a, 0xf8, 0xf0, 0x15, 0x2c, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfb, 0x80, 0x06, 0x5a, 0xd2, 0x51, + 0xac, 0x40, 0x8b, 0x08, 0xfb, 0x0b, 0x2a, 0x27, 0xfb, 0x0f, 0xfb, 0x0f, + 0xec, 0x26, 0xf7, 0x0b, 0x1f, 0xd6, 0x8b, 0xc7, 0xae, 0xba, 0xd1, 0x08, + 0x32, 0xea, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0x55, 0x06, 0xf8, 0xc7, 0x07, 0xfb, 0x70, 0xfb, 0x6a, 0x15, 0xf0, 0xd9, + 0x3b, 0x23, 0x1f, 0x27, 0x3b, 0x3a, 0x29, 0x27, 0x3c, 0xdc, 0xf1, 0xf0, + 0xda, 0xdc, 0xee, 0x1e, 0x0e, 0xf8, 0x9c, 0xf7, 0x5b, 0x15, 0x8b, 0xb9, + 0x88, 0x9e, 0x7d, 0xac, 0x67, 0xde, 0x3b, 0xbe, 0x2b, 0x8b, 0x08, 0xfb, + 0x14, 0x27, 0x2e, 0xfb, 0x0d, 0xfb, 0x16, 0xf6, 0x24, 0xf7, 0x1b, 0xe6, + 0xf7, 0x0c, 0xba, 0xae, 0x96, 0x82, 0x94, 0x81, 0x1f, 0x86, 0x8b, 0x87, + 0x89, 0x84, 0x86, 0x63, 0x6b, 0x42, 0x75, 0x4d, 0x8b, 0xfb, 0x00, 0x8b, + 0x3b, 0xd0, 0x7d, 0xf4, 0x08, 0xf8, 0x34, 0x06, 0xfc, 0x34, 0xb4, 0x15, + 0x9d, 0xe7, 0xd3, 0xc5, 0xec, 0x8b, 0xec, 0x8b, 0xd5, 0x50, 0x9b, 0x30, + 0x08, 0xfc, 0x0a, 0x06, 0x0e, 0xf7, 0xa3, 0xf8, 0x0c, 0x15, 0xf7, 0x51, + 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x51, + 0xc8, 0x06, 0xbd, 0xb8, 0xae, 0xcd, 0x1e, 0xa1, 0x8b, 0xb2, 0x88, 0xa6, + 0x88, 0xbb, 0x85, 0x8b, 0x8b, 0x8d, 0x8b, 0x97, 0x8b, 0x94, 0x93, 0x8b, + 0x97, 0x8b, 0x95, 0x85, 0x92, 0x7f, 0x8e, 0x6b, 0x91, 0x46, 0x92, 0x65, + 0x8b, 0x08, 0x31, 0x4b, 0x56, 0x42, 0x1f, 0x4e, 0x33, 0x07, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xe3, 0xfb, 0xe3, 0x29, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xd1, 0x06, + 0x9c, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x46, 0xf7, + 0xe3, 0x06, 0x0e, 0xf8, 0x4c, 0xf7, 0xe2, 0x15, 0x5e, 0xce, 0x56, 0xa9, + 0x42, 0x8b, 0x08, 0xfb, 0x05, 0x2e, 0x2d, 0xfb, 0x08, 0xfb, 0x08, 0xe8, + 0x2c, 0xf7, 0x05, 0x1f, 0xd3, 0x8b, 0xc1, 0xaa, 0xb8, 0xcd, 0x08, 0xfb, + 0x15, 0x07, 0x47, 0x55, 0x54, 0x47, 0x1e, 0xfb, 0x08, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x06, 0x06, 0xbd, 0x8b, + 0xb0, 0x9c, 0xae, 0xb0, 0xa9, 0xab, 0x98, 0xaa, 0x8b, 0xb4, 0x08, 0xf8, + 0x28, 0xc1, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0x2c, 0x06, 0x38, 0x07, 0xfb, 0x3c, 0xc3, 0x15, 0xea, 0xd4, 0x41, 0x2a, + 0x2e, 0x40, 0x40, 0x2e, 0x2e, 0x40, 0xd6, 0xea, 0x1f, 0xe9, 0xd5, 0xd6, + 0xe9, 0x1e, 0x0e, 0xf7, 0x39, 0xf8, 0xf0, 0x15, 0x2c, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x9e, 0x5d, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x95, 0x84, 0x9c, 0x1f, 0xf7, 0x18, 0x06, + 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0x5e, 0xf7, 0x93, + 0x06, 0x96, 0x98, 0x05, 0xc1, 0xcb, 0xa7, 0x9c, 0xc3, 0x8b, 0xb3, 0x8b, + 0xa1, 0x84, 0xa2, 0x78, 0xa4, 0x77, 0x98, 0x71, 0x8b, 0x6d, 0x08, 0xfb, + 0x8b, 0x5e, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xf7, 0x17, 0x06, 0x9e, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, + 0x5e, 0xf7, 0x8e, 0x06, 0xdc, 0x49, 0xc6, 0x2e, 0x1e, 0x4e, 0x8b, 0x61, + 0x74, 0x58, 0x4e, 0x08, 0xf7, 0x95, 0x07, 0x0e, 0xf7, 0xd4, 0xf8, 0x35, + 0x15, 0xfb, 0x33, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x0a, 0xfb, 0xe3, 0xfb, 0x34, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xfd, 0x06, 0x9d, 0x95, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x34, 0x06, 0xf8, 0x0c, 0x07, 0x89, + 0xf7, 0x63, 0x15, 0x50, 0x23, 0xc6, 0x06, 0xf3, 0x07, 0x0e, 0xf8, 0x35, + 0xf8, 0x0c, 0x15, 0xfc, 0x28, 0x07, 0x47, 0x5a, 0x5a, 0x49, 0x1e, 0xfb, + 0x14, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x15, 0x06, 0xe6, 0xcb, 0xcc, 0xe8, 0x1f, 0xf8, 0x51, 0xfb, 0xae, 0x07, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x85, 0x06, + 0x88, 0xf7, 0x8c, 0x15, 0x50, 0x23, 0xc6, 0xf3, 0x06, 0x0e, 0xf7, 0x4d, + 0xf7, 0x48, 0x15, 0xb9, 0xb2, 0xf7, 0x48, 0xfb, 0x46, 0x6f, 0x8b, 0x05, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x17, 0x06, + 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x5e, 0x8b, 0xfb, + 0x63, 0xf7, 0x60, 0xf7, 0x31, 0xf7, 0x17, 0xba, 0x8b, 0x05, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x16, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xa1, 0x8b, 0x05, 0xfb, 0x41, + 0xfb, 0x27, 0x8b, 0xf8, 0x0b, 0x2c, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x9e, 0x55, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xea, 0x06, 0xf7, 0x48, 0x07, + 0x0e, 0xf7, 0xd4, 0xf8, 0xf0, 0x15, 0xfb, 0x32, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x09, 0xfc, 0x9e, 0xfb, 0x34, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xfd, + 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x34, + 0xf8, 0xc7, 0x06, 0x0e, 0xf7, 0x04, 0xf8, 0x35, 0x15, 0x41, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xad, 0xfb, 0xe3, 0x69, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9c, 0x1f, 0xf7, 0x01, + 0x06, 0x9c, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf7, + 0x9f, 0x06, 0xb1, 0xc4, 0xab, 0xa4, 0xae, 0x8b, 0x08, 0xad, 0xaa, 0x68, + 0x64, 0x1f, 0xfb, 0xd0, 0xd5, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, + 0x92, 0x79, 0x1f, 0x69, 0xf7, 0x9f, 0x06, 0xb1, 0xc5, 0xa9, 0xa3, 0xaf, + 0x8b, 0x08, 0xae, 0xaa, 0x6a, 0x65, 0x1f, 0xfb, 0xd3, 0xd5, 0x07, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf7, 0xae, 0x06, + 0xc6, 0x5c, 0xbc, 0x51, 0x1e, 0x62, 0x8b, 0x6a, 0x76, 0x64, 0x59, 0x75, + 0xbb, 0x6b, 0xa2, 0x60, 0x8b, 0x08, 0x61, 0x8b, 0x6e, 0x79, 0x69, 0x5b, + 0x08, 0xbf, 0x07, 0x0e, 0xf7, 0x3b, 0xf8, 0x35, 0x15, 0x40, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xad, 0xfb, 0xe3, 0x5e, + 0x06, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xf7, 0x17, + 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x5e, 0xf7, + 0x91, 0x06, 0xab, 0xb4, 0x95, 0x96, 0x9a, 0x96, 0x08, 0xa7, 0xa2, 0xa8, + 0x95, 0xb1, 0x8b, 0xb2, 0x8b, 0x9e, 0x85, 0xa3, 0x77, 0xa4, 0x76, 0x98, + 0x72, 0x8b, 0x6d, 0x08, 0xfb, 0x8b, 0x69, 0x07, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x01, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf7, 0x92, 0x06, 0xd8, 0x47, 0xc6, + 0x32, 0x1e, 0x4d, 0x8b, 0x67, 0x78, 0x51, 0x4b, 0x08, 0xd0, 0x07, 0x0e, + 0xf7, 0xc0, 0xf8, 0x43, 0x15, 0xfb, 0x13, 0x26, 0x27, 0xfb, 0x0f, 0xfb, + 0x11, 0xf0, 0x28, 0xf7, 0x13, 0xf7, 0x12, 0xf1, 0xee, 0xf7, 0x0e, 0xf7, + 0x13, 0x27, 0xee, 0xfb, 0x14, 0x1f, 0x62, 0x04, 0xf4, 0xdd, 0x3b, 0x22, + 0x28, 0x37, 0x3a, 0x24, 0x23, 0x38, 0xdc, 0xf1, 0xf0, 0xde, 0xdc, 0xf3, + 0x1f, 0x0e, 0xf7, 0x24, 0xf8, 0x35, 0x15, 0x2c, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x9d, 0x55, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x55, 0x06, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x29, 0xf7, 0x8f, 0x06, + 0xb9, 0x49, 0xc3, 0x6d, 0xd8, 0x8b, 0x08, 0xf7, 0x0f, 0xea, 0xe7, 0xf7, + 0x0b, 0x1f, 0xf7, 0x0b, 0x2d, 0xe6, 0xfb, 0x10, 0x1e, 0x3f, 0x8b, 0x59, + 0x70, 0x56, 0x46, 0x08, 0xdd, 0x07, 0xf7, 0x46, 0x70, 0x15, 0xf0, 0xd8, + 0x41, 0x2a, 0x2e, 0x3b, 0x40, 0x29, 0x28, 0x3c, 0xd6, 0xea, 0x1f, 0xe9, + 0xda, 0xd6, 0xee, 0x1e, 0x0e, 0xf8, 0x61, 0xf7, 0xe3, 0x15, 0x5c, 0xcd, + 0x54, 0xa9, 0x3e, 0x8b, 0x08, 0xfb, 0x10, 0x2c, 0x30, 0xfb, 0x0b, 0xfb, + 0x0b, 0xea, 0x2f, 0xf7, 0x0f, 0x1f, 0xd9, 0x8b, 0xc3, 0xa9, 0xb9, 0xcd, + 0x08, 0xfb, 0x8f, 0x29, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xf7, 0x55, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0x55, 0x06, 0xf8, 0x9d, 0xc1, 0x07, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x2c, 0x06, 0x39, 0x07, 0xfb, 0x47, 0xc2, + 0x15, 0xf0, 0xd9, 0x41, 0x2a, 0x2e, 0x3b, 0x40, 0x28, 0x27, 0x3d, 0xd6, + 0xea, 0x1f, 0xea, 0xd9, 0xd5, 0xef, 0x1e, 0x0e, 0xf7, 0x8c, 0xf8, 0x35, + 0x15, 0xfb, 0x08, 0x06, 0x7a, 0x81, 0x83, 0x7f, 0x7e, 0x95, 0x83, 0x9c, + 0x1f, 0xd6, 0xfb, 0xe3, 0x2b, 0x06, 0x7a, 0x81, 0x83, 0x7f, 0x7e, 0x95, + 0x83, 0x9c, 0x1f, 0xf7, 0xd0, 0x06, 0x9c, 0x95, 0x93, 0x97, 0x98, 0x81, + 0x93, 0x7a, 0x1f, 0xfb, 0x47, 0xf7, 0x71, 0x06, 0xf7, 0x02, 0xf0, 0xae, + 0xa2, 0xb8, 0x8b, 0xa1, 0x8b, 0x9f, 0x80, 0xa3, 0x74, 0x92, 0x84, 0x8d, + 0x8a, 0x92, 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x94, 0x85, + 0x93, 0x7a, 0x99, 0x71, 0xa1, 0x75, 0x94, 0x6e, 0x8b, 0x08, 0x58, 0x8b, + 0x5a, 0x6f, 0x2e, 0x37, 0x08, 0xf1, 0x07, 0x0e, 0xf8, 0x44, 0xf8, 0x15, + 0x15, 0x68, 0xaa, 0x5e, 0x9a, 0x52, 0x8b, 0x29, 0x8b, 0x42, 0x5b, 0x8b, + 0x4a, 0x8b, 0x6c, 0x9d, 0x6d, 0xa7, 0x79, 0xa7, 0x7a, 0xa7, 0x84, 0xd5, + 0x83, 0xc2, 0x85, 0xa6, 0x84, 0xa5, 0x7d, 0x08, 0xa6, 0x7c, 0x9c, 0x72, + 0x8b, 0x74, 0x08, 0x56, 0x49, 0x64, 0x33, 0x36, 0x46, 0xb0, 0xb9, 0x1e, + 0x92, 0x07, 0x98, 0x83, 0x94, 0x7f, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x38, + 0x07, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0x96, 0x07, + 0xb5, 0x66, 0xbd, 0x7a, 0xcc, 0x8b, 0xf7, 0x05, 0x8b, 0xde, 0xc3, 0x8b, + 0xd7, 0x8b, 0xae, 0x78, 0xad, 0x6c, 0xa0, 0x6b, 0xa0, 0x66, 0x96, 0x4e, + 0x92, 0x33, 0x94, 0x85, 0x8d, 0x75, 0x99, 0x08, 0x76, 0x97, 0x80, 0x9c, + 0x8b, 0x9b, 0x8b, 0xb6, 0xc3, 0xab, 0xd5, 0x8b, 0xd7, 0x8b, 0xbf, 0x6e, + 0x90, 0x5e, 0x8d, 0x7b, 0x92, 0x84, 0x97, 0x8b, 0x08, 0x98, 0x92, 0x94, + 0x9d, 0x1f, 0xd0, 0x07, 0x9e, 0x84, 0x94, 0x7e, 0x7e, 0x83, 0x80, 0x7a, + 0x1e, 0x87, 0x07, 0x0e, 0xf7, 0x4e, 0xf8, 0x35, 0x15, 0xf7, 0x0b, 0x07, + 0x9e, 0x85, 0x93, 0x7d, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0xfb, 0x0b, 0x41, + 0x07, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xd5, 0xfb, + 0xa1, 0x06, 0x40, 0xc8, 0x5b, 0xe9, 0xe0, 0xf7, 0x06, 0xb1, 0xa8, 0x95, + 0x82, 0x95, 0x81, 0x1e, 0x86, 0x8b, 0x88, 0x8a, 0x83, 0x86, 0x64, 0x74, + 0x44, 0x7a, 0x53, 0x8b, 0x08, 0x46, 0x60, 0xac, 0xbe, 0x1f, 0xf7, 0x9f, + 0xf7, 0x70, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0xfb, 0x70, 0x06, 0x0e, 0xf8, 0x4b, 0x16, 0xd6, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf8, 0x0c, 0xfb, 0x07, 0x06, + 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xd5, 0xfb, 0x99, + 0x06, 0x54, 0x4f, 0x4e, 0x6d, 0x48, 0x8b, 0x08, 0x58, 0x63, 0xb3, 0xbd, + 0x1f, 0xf7, 0xc2, 0x2c, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xc1, 0xfb, 0x99, 0x06, 0x3c, 0xc0, 0x57, 0xdb, 0x1e, 0xcd, + 0x8b, 0xc8, 0xa7, 0xc2, 0xc1, 0x08, 0x49, 0x07, 0x0e, 0xf7, 0xe4, 0x16, + 0xf7, 0x3a, 0xf8, 0x0c, 0xb4, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x2c, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xcf, 0x8b, 0xfb, 0x27, 0xfb, 0xe3, 0x78, 0x8b, + 0xfb, 0x2a, 0xf7, 0xe3, 0xcc, 0x8b, 0x05, 0x9e, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x2b, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xb4, 0x8b, 0xf7, 0x3c, 0xfc, 0x0c, 0xd1, 0x8b, + 0x05, 0x0e, 0xf8, 0x4d, 0x16, 0xde, 0xf8, 0x0c, 0x9e, 0x8b, 0x05, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x03, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xbd, 0x8b, 0x46, 0xfb, + 0xd4, 0x32, 0xf7, 0x93, 0x58, 0x8b, 0x35, 0xfb, 0x93, 0x43, 0xf7, 0xd4, + 0xc0, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0xfb, 0x03, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0x9e, 0x8b, 0xdf, 0xfc, 0x0c, 0xbe, 0x8b, 0xe4, 0xf7, 0x97, 0xe6, 0xfb, + 0x97, 0xbd, 0x8b, 0x05, 0x0e, 0xf7, 0xdd, 0xf7, 0x6f, 0x15, 0xf7, 0x37, + 0xf7, 0x31, 0x92, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0xfb, 0x02, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xbb, 0x8b, 0xfb, 0x1d, 0xfb, 0x16, 0xfb, 0x1a, 0xf7, 0x16, + 0xb9, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x82, 0x91, 0x79, 0x1f, + 0xfb, 0x03, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0x92, 0x8b, 0xf7, 0x37, 0xfb, 0x31, 0xfb, 0x4c, 0xfb, 0x46, 0x82, 0x8b, + 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x19, + 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x47, 0x8b, + 0xf7, 0x31, 0xf7, 0x29, 0xf7, 0x2f, 0xfb, 0x29, 0x4a, 0x8b, 0x05, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x18, 0x06, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x82, 0x8b, 0xfb, 0x4c, + 0xf7, 0x46, 0x05, 0x0e, 0xf7, 0xae, 0x16, 0x44, 0xfb, 0x25, 0xfb, 0x13, + 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x7d, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x4a, + 0x8b, 0xf7, 0x94, 0xf8, 0x9d, 0x99, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x02, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0x8b, 0xfb, 0x35, 0xfb, 0xdf, 0xfb, + 0x38, 0xf7, 0xdf, 0xbf, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, + 0x92, 0x79, 0x1f, 0xfb, 0x07, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0x9b, 0x8b, 0x05, 0xf7, 0x50, 0xfc, 0x0c, 0x05, 0x0e, + 0xf8, 0x6e, 0xf8, 0x35, 0x15, 0xfb, 0xf2, 0x2b, 0x06, 0x79, 0x92, 0x82, + 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xc2, 0xf7, 0x8f, 0x07, 0xfb, 0xc1, + 0xfb, 0xe8, 0x8b, 0x67, 0xf8, 0x0a, 0x8b, 0x8b, 0xec, 0x05, 0x9d, 0x84, + 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x53, 0xfb, 0xa9, 0x07, 0xf7, + 0xc3, 0xf7, 0xe8, 0x8b, 0xaf, 0x05, 0x0e, 0xf7, 0xd6, 0xf8, 0x87, 0x15, + 0x8b, 0xad, 0xa2, 0xa6, 0xab, 0x8e, 0x9e, 0x8d, 0x92, 0x90, 0x8b, 0x99, + 0x08, 0x97, 0x82, 0x93, 0x7c, 0x54, 0x60, 0x5d, 0x50, 0x1e, 0xfb, 0x41, + 0x07, 0x8b, 0x66, 0x73, 0x72, 0x67, 0x88, 0x7b, 0x8a, 0x83, 0x84, 0x8b, + 0x7e, 0x8b, 0x7d, 0x93, 0x85, 0x9b, 0x8a, 0xaf, 0x88, 0xa3, 0x71, 0x8b, + 0x67, 0x08, 0xfb, 0x41, 0x07, 0x50, 0xb6, 0x5d, 0xc2, 0x9a, 0x94, 0x93, + 0x97, 0x1e, 0x8b, 0x99, 0x84, 0x90, 0x78, 0x8d, 0x6b, 0x8e, 0x74, 0xa6, + 0x8b, 0xad, 0x08, 0xf7, 0x41, 0x07, 0x8b, 0xb4, 0x80, 0xa0, 0x6a, 0xa3, + 0xac, 0xa3, 0x96, 0xa0, 0x8b, 0xb4, 0x08, 0xf7, 0x41, 0x07, 0x0e, 0xf7, + 0xd4, 0xf8, 0xd5, 0x15, 0x9d, 0x84, 0x94, 0x7e, 0x7e, 0x84, 0x82, 0x79, + 0x1e, 0xfd, 0x36, 0x07, 0x79, 0x92, 0x82, 0x98, 0x98, 0x92, 0x94, 0x9d, + 0x1e, 0xf9, 0x36, 0x07, 0x0e, 0xf7, 0xaa, 0x78, 0x15, 0x8b, 0x69, 0x74, + 0x70, 0x6b, 0x88, 0x78, 0x89, 0x84, 0x86, 0x8b, 0x7d, 0x08, 0x7f, 0x94, + 0x83, 0x9a, 0xc2, 0xb6, 0xb9, 0xc6, 0x1e, 0xf7, 0x41, 0x07, 0x8b, 0xb0, + 0xa3, 0xa4, 0xaf, 0x8e, 0x9b, 0x8c, 0x93, 0x92, 0x8b, 0x98, 0x8b, 0x99, + 0x83, 0x91, 0x7b, 0x8c, 0x67, 0x8e, 0x73, 0xa5, 0x8b, 0xaf, 0x08, 0xf7, + 0x41, 0x07, 0xc6, 0x60, 0xb9, 0x54, 0x7c, 0x82, 0x83, 0x7f, 0x1e, 0x8b, + 0x7d, 0x92, 0x86, 0x9e, 0x89, 0xab, 0x88, 0xa2, 0x70, 0x8b, 0x69, 0x08, + 0xfb, 0x41, 0x07, 0x8b, 0x62, 0x96, 0x76, 0xac, 0x73, 0x6a, 0x73, 0x80, + 0x76, 0x8b, 0x62, 0x08, 0xfb, 0x41, 0x07, 0x0e, 0xf8, 0x7c, 0xf7, 0xde, + 0x15, 0x81, 0x8b, 0x87, 0x88, 0x7c, 0x75, 0x72, 0x68, 0x73, 0x7a, 0x73, + 0x8b, 0x7b, 0x8b, 0x7e, 0x93, 0x5f, 0xaf, 0x55, 0xb6, 0x7c, 0x93, 0x6b, + 0x8b, 0x6a, 0x8b, 0x72, 0x7c, 0x69, 0x64, 0x77, 0x74, 0x83, 0x7d, 0x8b, + 0x83, 0x08, 0x81, 0x94, 0x82, 0x95, 0x1e, 0x93, 0x8b, 0x90, 0x8e, 0x92, + 0x94, 0xb7, 0xc3, 0x96, 0x94, 0xa5, 0x8b, 0x9c, 0x8b, 0x9e, 0x81, 0xa4, + 0x77, 0xca, 0x56, 0xa0, 0x7f, 0xab, 0x8b, 0xaa, 0x8b, 0xa8, 0x9d, 0xad, + 0xb4, 0x9c, 0x9f, 0x93, 0x97, 0x8b, 0x93, 0x08, 0x95, 0x82, 0x94, 0x80, + 0x1e, 0x0e, 0xf7, 0x9a, 0xfb, 0x35, 0x15, 0x8a, 0x83, 0x8b, 0x85, 0x8b, + 0x89, 0x08, 0x75, 0x9c, 0x7a, 0xa1, 0xa2, 0x9c, 0x9c, 0xa1, 0x1e, 0x8b, + 0x8f, 0x8b, 0x90, 0x8a, 0x92, 0x08, 0x79, 0xf7, 0xda, 0x05, 0x8a, 0x9e, + 0x85, 0x94, 0x7e, 0x8b, 0x7d, 0x8b, 0x85, 0x83, 0x8a, 0x77, 0x08, 0x79, + 0xfb, 0xda, 0x05, 0xb8, 0xf8, 0x72, 0x15, 0xa9, 0xa2, 0xa1, 0xa7, 0xa7, + 0x74, 0xa1, 0x6d, 0x1f, 0x7e, 0x06, 0x6d, 0x73, 0x75, 0x6f, 0x6f, 0xa3, + 0x75, 0xa9, 0x1f, 0x98, 0x06, 0x0e, 0xf7, 0xac, 0xf8, 0x84, 0x15, 0x61, + 0x82, 0x76, 0x82, 0x74, 0x7c, 0x58, 0x69, 0x6d, 0x53, 0x8b, 0x4d, 0x8b, + 0x2c, 0xd1, 0x3d, 0xec, 0x80, 0x08, 0xfb, 0x05, 0x07, 0x79, 0x92, 0x82, + 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x05, 0x07, 0xce, 0x8e, 0xdc, + 0xb1, 0x8b, 0xa6, 0x8b, 0x97, 0x83, 0x93, 0x80, 0x8b, 0x85, 0x8b, 0x88, + 0x8a, 0x82, 0x84, 0x6a, 0x70, 0x5d, 0x7c, 0x5d, 0x8b, 0x08, 0x33, 0x4a, + 0xc9, 0xdf, 0xe1, 0xcd, 0xc8, 0xe6, 0x1f, 0xcb, 0x8b, 0xb8, 0x6f, 0x91, + 0x60, 0x8d, 0x7b, 0x91, 0x84, 0x97, 0x8b, 0x08, 0x98, 0x92, 0x94, 0x9e, + 0x1f, 0xc8, 0x07, 0x9b, 0x83, 0x94, 0x7e, 0x1e, 0x81, 0x8b, 0x84, 0x85, + 0x88, 0x80, 0x72, 0xa1, 0x62, 0x99, 0x65, 0x8b, 0x08, 0xf5, 0x07, 0x9d, + 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x20, 0x07, 0x0e, 0xf7, + 0x4a, 0xb4, 0x15, 0xb0, 0xb9, 0x9f, 0xc8, 0x8b, 0xcf, 0x8b, 0x9d, 0x89, + 0x9d, 0x88, 0xa0, 0x08, 0xe5, 0x06, 0x9d, 0x94, 0x92, 0x98, 0x99, 0x82, + 0x92, 0x79, 0x1f, 0x28, 0x06, 0x89, 0x92, 0x8a, 0x91, 0x8a, 0x8c, 0x77, + 0xd0, 0x88, 0x9a, 0x8b, 0xa2, 0x8b, 0xc2, 0xba, 0xba, 0xc1, 0x8b, 0xae, + 0x8b, 0xa6, 0x7c, 0xa7, 0x69, 0x92, 0x82, 0x90, 0x88, 0x91, 0x8b, 0x94, + 0x8b, 0x96, 0x95, 0x8b, 0x94, 0x08, 0x8b, 0x95, 0x7f, 0x9c, 0x78, 0x9c, + 0x6e, 0xa5, 0x6a, 0x98, 0x67, 0x8b, 0x3d, 0x8b, 0x4c, 0x4b, 0x8b, 0x3c, + 0x8b, 0x71, 0x91, 0x6e, 0xa0, 0x49, 0x08, 0x2d, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf3, 0x06, 0x8d, 0x7e, 0x8d, 0x74, + 0x8b, 0x7a, 0x8b, 0x2f, 0x60, 0x35, 0x5c, 0x89, 0x08, 0x7d, 0x83, 0x83, + 0x80, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xd7, 0x06, 0xb9, 0xb1, 0xb5, + 0xbe, 0x98, 0x83, 0x94, 0x7f, 0x1f, 0x7e, 0x8b, 0x85, 0x84, 0x89, 0x7b, + 0x89, 0x6b, 0x79, 0x78, 0x72, 0x8b, 0x08, 0xfb, 0x90, 0x06, 0x0e, 0xf8, + 0xaa, 0xf8, 0x42, 0x15, 0x97, 0x92, 0x8e, 0x90, 0x8b, 0x93, 0x8b, 0x95, + 0x81, 0x95, 0x81, 0x8b, 0x87, 0x8b, 0x84, 0x89, 0x85, 0x87, 0x08, 0xfc, + 0x53, 0xfb, 0xb0, 0x05, 0x80, 0x84, 0x87, 0x85, 0x8b, 0x83, 0x8b, 0x80, + 0x95, 0x81, 0x95, 0x8b, 0x8f, 0x8b, 0x90, 0x8d, 0x8f, 0x8e, 0x08, 0x8f, + 0x8e, 0xf8, 0x53, 0xf7, 0xb0, 0x05, 0x0e, 0xf7, 0xd5, 0xf7, 0x82, 0x15, + 0xf7, 0x17, 0x06, 0x9b, 0x90, 0x90, 0x99, 0x98, 0x86, 0x90, 0x7b, 0x1f, + 0xfb, 0x0a, 0x8b, 0xf7, 0x38, 0xf7, 0x8b, 0xa3, 0x8b, 0x05, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x02, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xb2, 0x8b, 0xfb, 0x2b, 0xfb, + 0x77, 0xfb, 0x2b, 0xf7, 0x77, 0xb2, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x02, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xa3, 0x8b, 0xf7, 0x38, 0xfb, 0x8b, 0xfb, + 0x08, 0x8b, 0x05, 0x7a, 0x86, 0x86, 0x7e, 0x7d, 0x91, 0x86, 0x9b, 0x1f, + 0xf7, 0x16, 0x4f, 0xfb, 0x16, 0x06, 0x7b, 0x85, 0x86, 0x7e, 0x7d, 0x91, + 0x86, 0x9b, 0x1f, 0xf7, 0x16, 0x27, 0x35, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x69, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x35, 0xef, 0xf7, 0x17, 0x06, 0x9a, 0x91, + 0x90, 0x99, 0x98, 0x85, 0x90, 0x7c, 0x1f, 0xfb, 0x17, 0xc7, 0x06, 0x0e, + 0xf7, 0xd5, 0xf8, 0x0b, 0x15, 0xe2, 0x07, 0xcf, 0xb9, 0xba, 0xcf, 0x1e, + 0x95, 0x8b, 0x9f, 0x89, 0x94, 0x88, 0xa1, 0x85, 0x8b, 0x8b, 0x8e, 0x8b, + 0x95, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x94, 0x87, 0x90, 0x81, 0x8f, + 0x78, 0x94, 0x6e, 0x90, 0x72, 0x8b, 0x08, 0x36, 0x49, 0x46, 0x34, 0x1f, + 0x34, 0x2b, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xeb, 0xfb, 0xa2, 0x06, 0x47, 0x5f, 0x5b, 0x4e, 0x1e, 0x7f, 0x8b, 0x79, + 0x8d, 0x83, 0x8e, 0x72, 0x92, 0x89, 0x8c, 0x86, 0x8b, 0x81, 0x8b, 0x83, + 0x82, 0x8b, 0x80, 0x8b, 0x83, 0x8f, 0x85, 0x93, 0x87, 0x9d, 0x82, 0xab, + 0x84, 0xa4, 0x8b, 0x08, 0xdd, 0xcc, 0xce, 0xdf, 0x1f, 0xf7, 0xa8, 0xeb, + 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x2b, 0x06, + 0x0e, 0xf8, 0x84, 0xf8, 0xef, 0x15, 0xfb, 0x68, 0x06, 0x46, 0x50, 0x56, + 0x4c, 0x1f, 0x8b, 0x79, 0x8f, 0x7e, 0x94, 0x7c, 0x4d, 0x86, 0x62, 0x6a, + 0x8b, 0x5e, 0x8b, 0x5d, 0xb7, 0x5d, 0xed, 0x54, 0x08, 0xcc, 0x67, 0x05, + 0xeb, 0x55, 0xae, 0x6a, 0x8b, 0x68, 0x08, 0x61, 0x63, 0x6a, 0x56, 0x1e, + 0xfb, 0x39, 0xd2, 0x06, 0x9a, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x7c, + 0x1e, 0xfb, 0x03, 0xf7, 0x63, 0x07, 0xd7, 0xc4, 0xbc, 0xcc, 0x1f, 0x8b, + 0x9e, 0x87, 0x9a, 0x82, 0x9a, 0xad, 0x8f, 0x9a, 0x90, 0x9c, 0x96, 0xa2, + 0x9b, 0x98, 0xa1, 0x8b, 0xa5, 0x8b, 0xbc, 0x64, 0xb5, 0x2d, 0xbe, 0x08, + 0x53, 0xaa, 0x05, 0xfb, 0x0b, 0xcd, 0x6d, 0xa5, 0x8b, 0xb0, 0x08, 0xb4, + 0xb5, 0xae, 0xbc, 0x1e, 0xf7, 0x3c, 0x46, 0x06, 0x7c, 0x93, 0x82, 0x98, + 0x98, 0x92, 0x94, 0x9a, 0x1e, 0xf7, 0x01, 0x07, 0xfb, 0x04, 0xfb, 0xcd, + 0x15, 0xcc, 0x68, 0xb5, 0x61, 0x8b, 0x6e, 0x8b, 0x72, 0x6f, 0x7b, 0x5e, + 0x8a, 0x7d, 0x8a, 0x8b, 0x8b, 0x87, 0x89, 0x79, 0x9d, 0x6c, 0x9f, 0x54, + 0xaa, 0x08, 0x4d, 0xae, 0x05, 0x38, 0xba, 0x61, 0xb1, 0x8b, 0xa8, 0x8b, + 0xa5, 0xab, 0x9e, 0xb5, 0x8b, 0x97, 0x8b, 0x8b, 0x8b, 0x91, 0x8c, 0xa6, + 0x73, 0xa7, 0x79, 0xcb, 0x68, 0x08, 0xcb, 0x67, 0x05, 0x0e, 0xf7, 0x5b, + 0xf7, 0x36, 0x15, 0xa9, 0x74, 0xad, 0x7f, 0xb0, 0x8b, 0xb0, 0x8b, 0xab, + 0x96, 0xab, 0xa3, 0x08, 0xc3, 0x53, 0x05, 0x92, 0x83, 0x91, 0x88, 0x91, + 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x91, 0x87, 0x93, 0x85, + 0x91, 0x08, 0x54, 0xc3, 0x05, 0xa2, 0xa8, 0x97, 0xaf, 0x8b, 0xb0, 0x8b, + 0xaf, 0x80, 0xac, 0x74, 0xab, 0x08, 0xc2, 0xc3, 0x05, 0x94, 0x94, 0x8c, + 0x8d, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x80, 0x8b, 0x84, 0x8b, 0x87, + 0x89, 0x82, 0x82, 0x08, 0x54, 0x54, 0x05, 0x6f, 0xa1, 0x66, 0x98, 0x66, + 0x8b, 0x66, 0x8b, 0x67, 0x7f, 0x6e, 0x74, 0x08, 0x53, 0xc2, 0x05, 0x83, + 0x93, 0x87, 0x8e, 0x84, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, + 0x84, 0x8d, 0x87, 0x94, 0x83, 0x08, 0xc2, 0x53, 0x05, 0x75, 0x6f, 0x7f, + 0x66, 0x8b, 0x66, 0x8b, 0x67, 0x96, 0x6a, 0xa3, 0x6b, 0x08, 0x53, 0x53, + 0x05, 0x83, 0x83, 0x88, 0x86, 0x8b, 0x84, 0x8b, 0x80, 0x94, 0x82, 0x97, + 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x93, 0x94, 0x08, 0xc4, 0xc3, 0x05, 0xf0, + 0xf7, 0x93, 0x15, 0xd0, 0xc2, 0x53, 0x45, 0x48, 0x52, 0x53, 0x48, 0x47, + 0x53, 0xc3, 0xd0, 0xcf, 0xc3, 0xc3, 0xcf, 0x1f, 0x0e, 0xf7, 0x80, 0xf8, + 0xf0, 0x15, 0xad, 0xfb, 0x91, 0x05, 0x8e, 0x72, 0x94, 0x80, 0x9d, 0x8b, + 0x9d, 0x8b, 0x94, 0x96, 0x8e, 0xa4, 0x08, 0xad, 0xf7, 0x91, 0xfb, 0x14, + 0x8b, 0x05, 0x0e, 0xf8, 0x47, 0xf8, 0xf0, 0x15, 0xfb, 0x11, 0x8b, 0xf7, + 0x1d, 0xfb, 0x83, 0x05, 0x94, 0x7b, 0x94, 0x85, 0x98, 0x8b, 0x9b, 0x8b, + 0x98, 0x97, 0x8b, 0x99, 0x8b, 0x8e, 0x8a, 0x8f, 0x8a, 0x8e, 0x08, 0x45, + 0xf7, 0x75, 0x05, 0xfb, 0x6d, 0x16, 0xfb, 0x11, 0x8b, 0xf7, 0x1d, 0xfb, + 0x83, 0x05, 0x94, 0x7b, 0x94, 0x85, 0x98, 0x8b, 0x9b, 0x8b, 0x98, 0x97, + 0x8b, 0x99, 0x8b, 0x8e, 0x8a, 0x8f, 0x8a, 0x8e, 0x08, 0x45, 0xf7, 0x75, + 0x05, 0x0e, 0xca, 0xf7, 0x65, 0x15, 0xf7, 0x64, 0xfb, 0x5a, 0x05, 0x93, + 0x84, 0x92, 0x87, 0x91, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, + 0x92, 0x8a, 0x8d, 0x81, 0x96, 0x08, 0xfb, 0x23, 0xf7, 0x3d, 0xf7, 0x23, + 0xf7, 0x3c, 0x05, 0x95, 0x96, 0x8c, 0x8d, 0x8b, 0x92, 0x8b, 0x96, 0x82, + 0x94, 0x80, 0x8b, 0x84, 0x8b, 0x85, 0x88, 0x83, 0x83, 0x08, 0xfb, 0x64, + 0xfb, 0x59, 0x05, 0xf7, 0x79, 0x16, 0xf7, 0x64, 0xfb, 0x5a, 0x05, 0x93, + 0x84, 0x92, 0x87, 0x91, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, + 0x92, 0x8a, 0x8d, 0x81, 0x96, 0x08, 0xfb, 0x23, 0xf7, 0x3d, 0xf7, 0x23, + 0xf7, 0x3c, 0x05, 0x95, 0x96, 0x8c, 0x8d, 0x8b, 0x92, 0x8b, 0x96, 0x82, + 0x94, 0x80, 0x8b, 0x84, 0x8b, 0x85, 0x88, 0x83, 0x83, 0x08, 0xfb, 0x64, + 0xfb, 0x59, 0x05, 0x0e, 0xca, 0xf7, 0x65, 0x15, 0xf7, 0x64, 0xfb, 0x5a, + 0x05, 0x93, 0x84, 0x92, 0x87, 0x91, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, + 0x96, 0x8b, 0x92, 0x8a, 0x8d, 0x81, 0x96, 0x08, 0xfb, 0x23, 0xf7, 0x3d, + 0xf7, 0x23, 0xf7, 0x3c, 0x05, 0x95, 0x96, 0x8c, 0x8d, 0x8b, 0x92, 0x8b, + 0x96, 0x82, 0x94, 0x80, 0x8b, 0x84, 0x8b, 0x85, 0x88, 0x83, 0x83, 0x08, + 0xfb, 0x64, 0xfb, 0x59, 0x05, 0x0e, 0xf8, 0xb1, 0xf7, 0x64, 0x15, 0xfb, + 0x63, 0xf7, 0x5a, 0x05, 0x83, 0x92, 0x84, 0x8f, 0x85, 0x8b, 0x80, 0x8b, + 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, 0x8c, 0x89, 0x95, 0x80, 0x08, 0xf7, + 0x22, 0xfb, 0x3d, 0xfb, 0x22, 0xfb, 0x3c, 0x05, 0x81, 0x80, 0x8a, 0x89, + 0x8b, 0x84, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x92, 0x8b, 0x91, 0x8e, + 0x93, 0x93, 0x08, 0xf7, 0x63, 0xf7, 0x59, 0x05, 0x0e, 0xf7, 0x35, 0xf8, + 0x0c, 0x15, 0xd3, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x43, 0xc6, 0x06, 0xbc, 0xa8, 0xb1, 0xb1, 0x1e, 0x99, 0x8b, 0x9c, + 0x88, 0xa6, 0x83, 0x96, 0x88, 0x8b, 0x8b, 0x8d, 0x8b, 0x96, 0x8b, 0x93, + 0x94, 0x8b, 0x96, 0x8b, 0x94, 0x85, 0x92, 0x81, 0x8f, 0x77, 0x93, 0x68, + 0x92, 0x77, 0x8b, 0x08, 0x50, 0x5b, 0x52, 0x44, 0x1f, 0x50, 0x3e, 0x07, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xd8, 0xfb, 0xe3, + 0x38, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x58, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x43, + 0x06, 0xf7, 0xe3, 0x07, 0xf7, 0xd6, 0xb4, 0x15, 0x29, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc4, 0xfb, 0xe3, 0x3e, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x55, 0x06, + 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x40, 0xf8, 0x0c, + 0x06, 0x8a, 0xf7, 0x63, 0x15, 0x50, 0x23, 0xc6, 0x06, 0xf3, 0x07, 0x0e, + 0xf7, 0x35, 0xf8, 0x0c, 0x15, 0xd3, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0x43, 0xc6, 0x06, 0xbc, 0xa8, 0xb1, 0xb0, 0x1e, + 0x9b, 0x8b, 0x9c, 0x88, 0xab, 0x81, 0x8e, 0x8a, 0x8e, 0x8b, 0x8c, 0x8b, + 0x96, 0x8b, 0x93, 0x94, 0x8b, 0x96, 0x8b, 0x94, 0x85, 0x92, 0x81, 0x8f, + 0x78, 0x93, 0x66, 0x92, 0x78, 0x8b, 0x08, 0x50, 0x5b, 0x52, 0x44, 0x1f, + 0x50, 0x3e, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xd8, 0xfb, 0xe3, 0x38, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xf7, 0x58, 0x06, 0x9c, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0x43, 0xf7, 0xe3, 0x06, 0xf7, 0xd6, 0xf7, 0x78, 0x15, 0x29, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc4, 0xfc, + 0x9e, 0x3e, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xf7, 0x57, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0x3e, 0xf8, 0xc7, 0x06, 0x0e, 0xf8, 0x89, 0xf7, 0x99, 0x15, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfc, 0x26, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x26, 0x06, 0x0e, 0xf7, + 0xd4, 0xf8, 0x0c, 0x15, 0xf7, 0x14, 0x06, 0x9e, 0x94, 0x92, 0x98, 0x99, + 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x14, 0xf7, 0x34, 0x06, 0x9d, 0x84, 0x94, + 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0xfb, 0x33, 0xfb, 0x14, 0x07, 0x88, + 0x8a, 0x89, 0x8b, 0x89, 0x8b, 0x82, 0x89, 0x8b, 0x8b, 0x8a, 0x8a, 0x85, + 0x87, 0x87, 0x84, 0x8b, 0x84, 0x08, 0x7e, 0x94, 0x84, 0x9d, 0x1e, 0xf7, + 0x14, 0xfc, 0x30, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, + 0x1e, 0xf8, 0x30, 0x07, 0x0e, 0xf7, 0xd4, 0xf8, 0x0c, 0x15, 0xf7, 0x14, + 0x06, 0x9e, 0x94, 0x92, 0x98, 0x99, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x14, + 0xf7, 0x34, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, + 0xfb, 0x33, 0xfb, 0x14, 0x07, 0x88, 0x8a, 0x89, 0x8b, 0x89, 0x8b, 0x82, + 0x89, 0x8b, 0x8b, 0x8a, 0x8a, 0x85, 0x87, 0x87, 0x84, 0x8b, 0x84, 0x08, + 0x7e, 0x94, 0x84, 0x9d, 0x1e, 0xf7, 0x14, 0xfb, 0x67, 0xfb, 0x14, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x14, 0xfb, + 0x33, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, + 0x33, 0xf7, 0x14, 0x07, 0x9e, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, + 0x1f, 0xfb, 0x14, 0xf7, 0x67, 0x06, 0x0e, 0xf7, 0xbb, 0xf7, 0xf0, 0x15, + 0x64, 0x6d, 0x6f, 0x66, 0x66, 0xa9, 0x6e, 0xb2, 0x1f, 0x95, 0x06, 0xb2, + 0xa9, 0xa7, 0xb1, 0xb0, 0x6d, 0xa7, 0x64, 0x1f, 0x81, 0x06, 0x0e, 0xf8, + 0x49, 0xf8, 0xc7, 0x15, 0xc8, 0x06, 0x9b, 0x94, 0x93, 0x98, 0x97, 0x82, + 0x93, 0x7b, 0x1f, 0xfb, 0x5c, 0x06, 0xfb, 0x16, 0x32, 0x4e, 0x31, 0x1f, + 0x5c, 0x07, 0x8b, 0x5a, 0xaf, 0x5c, 0xc5, 0x71, 0xa9, 0x7e, 0xad, 0x83, + 0xba, 0x88, 0x08, 0xfb, 0xad, 0x2a, 0x07, 0x7a, 0x82, 0x84, 0x7e, 0x7e, + 0x95, 0x83, 0x9b, 0x1f, 0xf7, 0x1a, 0x06, 0x9b, 0x94, 0x92, 0x99, 0x1f, + 0x8b, 0x96, 0x83, 0x93, 0x7e, 0x8c, 0x08, 0xf8, 0xdc, 0xd3, 0xfc, 0xdc, + 0x07, 0x7e, 0x8a, 0x83, 0x83, 0x8b, 0x80, 0x08, 0x7e, 0x95, 0x83, 0x9a, + 0x1e, 0xed, 0x06, 0x9c, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x7a, 0x1f, + 0x4d, 0xf8, 0xdc, 0x06, 0xfb, 0x2d, 0xfb, 0x94, 0x15, 0x3e, 0x93, 0x51, + 0xb9, 0x8b, 0xc0, 0x08, 0xb0, 0x07, 0x8b, 0xc0, 0xc5, 0xb9, 0xd8, 0x93, + 0x08, 0xfb, 0x8f, 0x07, 0x0e, 0xf7, 0xc2, 0xf7, 0xe5, 0x15, 0x53, 0x5f, + 0x60, 0x55, 0x54, 0xb7, 0x5f, 0xc1, 0xc1, 0xb7, 0xb7, 0xc1, 0xc0, 0x5f, + 0xb8, 0x57, 0x1f, 0x0e, 0xf7, 0x63, 0xf7, 0x25, 0x15, 0x45, 0xfb, 0x8e, + 0x05, 0x8a, 0x87, 0x8a, 0x88, 0x8b, 0x87, 0x8b, 0x7b, 0x98, 0x7e, 0x9b, + 0x8b, 0x98, 0x8b, 0x93, 0x91, 0x95, 0x9e, 0x08, 0xf7, 0x25, 0xf7, 0x9d, + 0xfb, 0x19, 0x8b, 0x05, 0x0e, 0xf7, 0x39, 0xf7, 0x25, 0x15, 0x45, 0xfb, + 0x75, 0x05, 0x8a, 0x88, 0x8a, 0x87, 0x8b, 0x88, 0x8b, 0x7d, 0x98, 0x7f, + 0x9b, 0x8b, 0x98, 0x8b, 0x94, 0x91, 0x94, 0x9b, 0x08, 0xf7, 0x1d, 0xf7, + 0x83, 0xfb, 0x11, 0x8b, 0x05, 0xf7, 0x6d, 0x16, 0x45, 0xfb, 0x75, 0x05, + 0x8a, 0x88, 0x8a, 0x87, 0x8b, 0x88, 0x8b, 0x7d, 0x98, 0x7f, 0x9b, 0x8b, + 0x98, 0x8b, 0x94, 0x91, 0x94, 0x9b, 0x08, 0xf7, 0x1d, 0xf7, 0x83, 0xfb, + 0x11, 0x8b, 0x05, 0x0e, 0xf7, 0x39, 0xf8, 0xf0, 0x15, 0x45, 0xfb, 0x75, + 0x05, 0x8a, 0x88, 0x8a, 0x87, 0x8b, 0x88, 0x8b, 0x7d, 0x98, 0x7f, 0x9b, + 0x8b, 0x98, 0x8b, 0x94, 0x91, 0x94, 0x9b, 0x08, 0xf7, 0x1d, 0xf7, 0x83, + 0xfb, 0x11, 0x8b, 0x05, 0xf7, 0x6d, 0x16, 0x45, 0xfb, 0x75, 0x05, 0x8a, + 0x88, 0x8a, 0x87, 0x8b, 0x88, 0x8b, 0x7d, 0x98, 0x7f, 0x9b, 0x8b, 0x98, + 0x8b, 0x94, 0x91, 0x94, 0x9b, 0x08, 0xf7, 0x1d, 0xf7, 0x83, 0xfb, 0x11, + 0x8b, 0x05, 0x0e, 0xf7, 0xcb, 0xf7, 0x64, 0x15, 0xfb, 0x63, 0xf7, 0x5a, + 0x05, 0x83, 0x92, 0x84, 0x8f, 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, + 0x80, 0x8b, 0x84, 0x8c, 0x89, 0x95, 0x80, 0x08, 0xf7, 0x22, 0xfb, 0x3d, + 0xfb, 0x22, 0xfb, 0x3c, 0x05, 0x81, 0x80, 0x8a, 0x89, 0x8b, 0x84, 0x8b, + 0x80, 0x94, 0x82, 0x96, 0x8b, 0x92, 0x8b, 0x91, 0x8e, 0x93, 0x93, 0x08, + 0xf7, 0x63, 0xf7, 0x59, 0x05, 0xf7, 0x7a, 0x16, 0xfb, 0x63, 0xf7, 0x5a, + 0x05, 0x83, 0x92, 0x84, 0x8f, 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, + 0x80, 0x8b, 0x84, 0x8c, 0x89, 0x95, 0x80, 0x08, 0xf7, 0x22, 0xfb, 0x3d, + 0xfb, 0x22, 0xfb, 0x3c, 0x05, 0x81, 0x80, 0x8a, 0x89, 0x8b, 0x84, 0x8b, + 0x80, 0x94, 0x82, 0x96, 0x8b, 0x92, 0x8b, 0x91, 0x8e, 0x93, 0x93, 0x08, + 0xf7, 0x63, 0xf7, 0x59, 0x05, 0x0e, 0xef, 0xdf, 0x15, 0x70, 0x75, 0x75, + 0x6f, 0x70, 0xa1, 0x75, 0xa7, 0xa5, 0xa2, 0xa1, 0xa6, 0xa7, 0x75, 0xa1, + 0x6f, 0x1f, 0xf7, 0x5b, 0x16, 0x70, 0x75, 0x74, 0x70, 0x70, 0xa1, 0x75, + 0xa6, 0xa6, 0xa2, 0xa1, 0xa6, 0xa7, 0x75, 0xa1, 0x6f, 0x1f, 0xf7, 0x5d, + 0x16, 0x70, 0x74, 0x75, 0x70, 0x6f, 0xa1, 0x75, 0xa7, 0xa5, 0xa2, 0xa1, + 0xa6, 0xa7, 0x75, 0xa1, 0x70, 0x1f, 0x0e, 0xf7, 0x24, 0xf8, 0xfa, 0x15, + 0x4f, 0x59, 0x59, 0x4e, 0x4d, 0xbd, 0x59, 0xc7, 0xc7, 0xbd, 0xbd, 0xc7, + 0x1f, 0xca, 0x5a, 0xbd, 0x4e, 0x1e, 0x69, 0x04, 0xb6, 0xac, 0x69, 0x5f, + 0x61, 0x69, 0x68, 0x61, 0x61, 0x69, 0xae, 0xb6, 0xb5, 0xad, 0xae, 0xb5, + 0x1f, 0xf7, 0xf4, 0xfb, 0x54, 0x15, 0x96, 0x8e, 0x90, 0x90, 0x8b, 0x94, + 0x8b, 0x93, 0x84, 0x93, 0x83, 0x8b, 0x88, 0x8b, 0x87, 0x8a, 0x87, 0x8a, + 0x08, 0xfc, 0x0a, 0xfb, 0x0e, 0x05, 0x80, 0x88, 0x86, 0x86, 0x8b, 0x82, + 0x8b, 0x83, 0x93, 0x83, 0x92, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, 0x8f, 0x8c, + 0x08, 0xf8, 0x0a, 0xf7, 0x0e, 0x05, 0xfb, 0xce, 0xfb, 0x42, 0x15, 0x4f, + 0x59, 0x59, 0x4e, 0x4d, 0xbd, 0x59, 0xc7, 0xc7, 0xbd, 0xbd, 0xc7, 0xca, + 0x5a, 0xbd, 0x4e, 0x1f, 0x69, 0x04, 0xb6, 0xac, 0x69, 0x5f, 0x61, 0x69, + 0x68, 0x61, 0x61, 0x69, 0xae, 0xb6, 0xb5, 0xad, 0xae, 0xb5, 0x1f, 0xf7, + 0xa4, 0xad, 0x15, 0x4f, 0x59, 0x59, 0x4e, 0x4d, 0xbd, 0x59, 0xc7, 0xc7, + 0xbd, 0xbd, 0xc7, 0xca, 0x5a, 0xbd, 0x4e, 0x1f, 0x69, 0x04, 0xb6, 0xac, + 0x69, 0x5f, 0x61, 0x69, 0x68, 0x61, 0x61, 0x69, 0xae, 0xb6, 0xb5, 0xad, + 0xae, 0xb5, 0x1f, 0x0e, 0xf7, 0xaa, 0xf7, 0x2f, 0x15, 0xfb, 0x11, 0x50, + 0x63, 0x60, 0x8b, 0x41, 0x8b, 0x2f, 0xd3, 0x4d, 0xf5, 0x8b, 0xbe, 0x8b, + 0xab, 0x93, 0xca, 0xa7, 0x96, 0x90, 0x93, 0x8e, 0x95, 0x90, 0x08, 0xce, + 0x07, 0x9d, 0x84, 0x94, 0x7d, 0x7e, 0x84, 0x82, 0x79, 0x1e, 0x62, 0x07, + 0x56, 0x71, 0x6c, 0x83, 0x5e, 0x8b, 0x38, 0x8b, 0x50, 0xba, 0x8b, 0xcd, + 0x8b, 0xc4, 0xbc, 0xb7, 0xf7, 0x08, 0xbb, 0x08, 0xcf, 0x07, 0x9d, 0x84, + 0x94, 0x7d, 0x7e, 0x84, 0x82, 0x79, 0x1e, 0x62, 0x07, 0xae, 0xf7, 0x36, + 0x15, 0xad, 0xa2, 0x9f, 0xa9, 0xa9, 0x74, 0x9f, 0x69, 0x1f, 0x70, 0x06, + 0x69, 0x74, 0x76, 0x6e, 0x6e, 0xa2, 0x76, 0xad, 0x1f, 0xa6, 0x06, 0x0e, + 0xf7, 0x56, 0xf9, 0x0a, 0x15, 0x83, 0x91, 0x86, 0x8e, 0x85, 0x8b, 0x80, + 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x83, 0x8e, 0x87, 0x94, 0x83, 0x08, + 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x91, 0x88, 0x90, 0x8b, 0x97, 0x8b, + 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x91, 0x8b, 0x8b, 0x86, 0x90, 0x08, 0x84, + 0x93, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x45, 0xf8, 0xeb, 0x15, 0x94, + 0x93, 0x8e, 0x8f, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x80, 0x8b, 0x85, + 0x8b, 0x87, 0x89, 0x82, 0x84, 0x08, 0xfb, 0x06, 0x27, 0x05, 0x81, 0x82, + 0x89, 0x88, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, + 0x8f, 0x8d, 0x94, 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, 0x0e, 0xf7, 0xc0, + 0xf9, 0x13, 0x15, 0xfb, 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, 0x88, 0x86, + 0x8b, 0x83, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, 0x8e, + 0x92, 0x90, 0x08, 0xf6, 0xe3, 0xf6, 0x33, 0x05, 0x92, 0x86, 0x91, 0x88, + 0x90, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x93, 0x89, 0x8f, + 0x80, 0x94, 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x47, 0xf8, + 0xef, 0x15, 0x85, 0x8b, 0x87, 0x89, 0x85, 0x85, 0x6d, 0x6c, 0x81, 0x84, + 0x7a, 0x8b, 0x7e, 0x8b, 0x83, 0x8f, 0x65, 0xa0, 0x6b, 0x9e, 0x7f, 0x8f, + 0x77, 0x8b, 0x72, 0x8b, 0x76, 0x81, 0x6e, 0x70, 0x7e, 0x7e, 0x85, 0x82, + 0x8b, 0x83, 0x08, 0x80, 0x94, 0x83, 0x96, 0x1e, 0x91, 0x8b, 0x92, 0x8e, + 0x8f, 0x90, 0xa8, 0xaa, 0x94, 0x91, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x87, + 0x9f, 0x7e, 0xb3, 0x73, 0x9e, 0x84, 0xa1, 0x8b, 0xa2, 0x8b, 0x9f, 0x95, + 0xa5, 0xa5, 0x9d, 0x9c, 0x8f, 0x91, 0x8b, 0x93, 0x08, 0x96, 0x81, 0x94, + 0x81, 0x1e, 0x0e, 0xf8, 0x36, 0xf8, 0xac, 0x15, 0x9d, 0x94, 0x92, 0x98, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x80, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7e, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x80, 0x06, 0x0e, 0xf7, 0x44, 0xf9, + 0x00, 0x15, 0x7e, 0x83, 0x82, 0x7d, 0x4f, 0xca, 0x5c, 0xdd, 0xdd, 0xca, + 0xba, 0xc7, 0x99, 0x82, 0x94, 0x80, 0x1f, 0x7e, 0x8b, 0x85, 0x84, 0x89, + 0x7c, 0x87, 0x65, 0x5f, 0x6e, 0x53, 0x8b, 0x53, 0x8b, 0x5e, 0xa8, 0x88, + 0xb1, 0x89, 0x9a, 0x85, 0x92, 0x7f, 0x8b, 0x08, 0x0e, 0xf7, 0xc0, 0xf8, + 0xf7, 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, + 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, 0xf7, 0x52, 0xf8, 0xf7, + 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, + 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0xf7, 0x71, 0x16, 0x70, 0x74, 0x74, + 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, + 0x6f, 0x1f, 0x0e, 0xf7, 0xc0, 0xf9, 0x29, 0x15, 0x58, 0x61, 0x62, 0x5a, + 0x59, 0xb5, 0x62, 0xbe, 0xbe, 0xb5, 0xb4, 0xbb, 0xbf, 0x62, 0xb3, 0x57, + 0x1f, 0x6a, 0x04, 0xac, 0xa6, 0x71, 0x6b, 0x6c, 0x70, 0x71, 0x6a, 0x6a, + 0x70, 0xa5, 0xab, 0xaa, 0xa6, 0xa5, 0xac, 0x1f, 0x0e, 0xf7, 0xa6, 0x16, + 0x3a, 0x9f, 0x07, 0xaa, 0x9a, 0x83, 0x7a, 0x7a, 0x79, 0x7f, 0x71, 0x1f, + 0x7c, 0x8b, 0x7d, 0x8f, 0x75, 0x97, 0x83, 0x8f, 0x88, 0x8c, 0x87, 0x8b, + 0x80, 0x8b, 0x82, 0x83, 0x8b, 0x80, 0x8b, 0x81, 0x8f, 0x86, 0x99, 0x84, + 0x9e, 0x81, 0xaa, 0x83, 0x9f, 0x8b, 0xba, 0x8b, 0xab, 0xa5, 0x8b, 0xb2, + 0x08, 0x8b, 0xb1, 0x73, 0xa1, 0x62, 0x8c, 0x08, 0xba, 0x65, 0x07, 0x0e, + 0xf7, 0xb7, 0xf8, 0xe5, 0x15, 0x95, 0x95, 0x8d, 0x8e, 0x8b, 0x91, 0x8b, + 0x97, 0x82, 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x85, 0x88, 0x85, 0x85, 0x08, + 0x29, 0x2d, 0x05, 0x80, 0x81, 0x8a, 0x89, 0x8b, 0x84, 0x8b, 0x7f, 0x94, + 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x91, 0x8e, 0x92, 0x91, 0x08, 0xec, 0xe9, + 0x05, 0xf7, 0x22, 0x16, 0x96, 0x95, 0x8c, 0x8e, 0x8b, 0x91, 0x8b, 0x97, + 0x82, 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x85, 0x88, 0x84, 0x85, 0x08, 0x29, + 0x2d, 0x88, 0x88, 0x05, 0x85, 0x86, 0x88, 0x86, 0x8b, 0x85, 0x8b, 0x7f, + 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x91, 0x8e, 0x92, 0x91, 0x08, 0xed, + 0xe9, 0x05, 0x0e, 0xf8, 0x28, 0x16, 0x5c, 0x06, 0x54, 0x71, 0x75, 0x70, + 0x8b, 0x62, 0x08, 0x65, 0xa7, 0x74, 0xbb, 0xb1, 0xb2, 0x9e, 0x9c, 0x93, + 0x84, 0x92, 0x84, 0x1e, 0x89, 0x8b, 0x88, 0x8a, 0x88, 0x89, 0x73, 0x7d, + 0x86, 0x89, 0x77, 0x8b, 0x6e, 0x8b, 0x7d, 0x96, 0x8b, 0xa2, 0x8b, 0xa6, + 0xa0, 0xa5, 0xb0, 0xa0, 0x08, 0xa6, 0x9a, 0x05, 0x0e, 0xf7, 0xc0, 0xf8, + 0x7e, 0x15, 0xf7, 0x18, 0xf7, 0x00, 0x05, 0x96, 0x94, 0x8d, 0x8f, 0x8b, + 0x93, 0x8b, 0x95, 0x81, 0x95, 0x81, 0x8b, 0x86, 0x8b, 0x85, 0x88, 0x84, + 0x86, 0x08, 0x20, 0x33, 0x20, 0xe3, 0x05, 0x84, 0x90, 0x85, 0x8e, 0x86, + 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x82, 0x8e, 0x87, 0x95, + 0x84, 0x08, 0xf7, 0x18, 0xfb, 0x01, 0x05, 0x0e, 0xf8, 0xd0, 0xf7, 0x99, + 0x15, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfc, 0xb4, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0xb4, + 0x06, 0x0e, 0xf7, 0xbd, 0xf7, 0x51, 0x15, 0xfb, 0x28, 0x57, 0x07, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xed, 0xf7, 0x1a, + 0x06, 0x9a, 0x83, 0x96, 0x7e, 0x7d, 0x85, 0x84, 0x78, 0x1e, 0x2e, 0xfb, + 0x67, 0xf7, 0x7c, 0xd9, 0x70, 0x07, 0x7a, 0x92, 0x81, 0x98, 0x98, 0x92, + 0x94, 0x9d, 0x1e, 0xeb, 0x07, 0x9d, 0x85, 0x94, 0x7d, 0x7e, 0x84, 0x82, + 0x79, 0x1e, 0x6f, 0x3d, 0xf7, 0x64, 0x07, 0xf7, 0x53, 0xfb, 0x03, 0x06, + 0x79, 0x92, 0x82, 0x98, 0x1e, 0x99, 0x92, 0x94, 0x9d, 0x1f, 0xf7, 0x2c, + 0xfc, 0x3e, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xca, 0x8b, 0xfb, 0x19, 0xfc, 0x75, 0x66, 0x8b, 0x05, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf3, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x71, 0x8b, 0xb4, 0xf7, 0x28, 0x05, 0xf7, + 0x21, 0x06, 0xb4, 0x04, 0xfb, 0x16, 0x8b, 0xdb, 0xf7, 0xb8, 0xbd, 0x8b, + 0x8b, 0xfb, 0xb8, 0x05, 0x0e, 0xf7, 0xfd, 0xf7, 0xae, 0x15, 0xca, 0x06, + 0x99, 0x94, 0x92, 0x96, 0x97, 0x83, 0x92, 0x7c, 0x1f, 0x71, 0xf7, 0x3f, + 0x06, 0xbc, 0x61, 0xae, 0x51, 0x1e, 0x73, 0x8b, 0x62, 0x81, 0x6d, 0x7f, + 0x81, 0x86, 0x87, 0x86, 0x8b, 0x82, 0x8b, 0x81, 0x93, 0x82, 0x94, 0x8b, + 0x8f, 0x8b, 0x8d, 0x8b, 0x93, 0x8f, 0xa9, 0x97, 0xa7, 0x92, 0x9d, 0x8b, + 0x08, 0xb2, 0xa5, 0x78, 0x6f, 0x1f, 0x5f, 0x07, 0x6d, 0x91, 0x77, 0x8e, + 0x74, 0x8b, 0x08, 0x3e, 0x53, 0x63, 0x52, 0x1f, 0x5c, 0xb3, 0x6b, 0xc6, + 0x1e, 0xb2, 0x8b, 0xa6, 0x92, 0xb4, 0xa1, 0x08, 0x71, 0x07, 0xcf, 0x04, + 0x68, 0x74, 0x69, 0x80, 0x65, 0x8b, 0x08, 0x66, 0x72, 0x9b, 0xa3, 0xb0, + 0xb4, 0xa6, 0xc4, 0x1f, 0xa2, 0x8b, 0xab, 0x86, 0x9b, 0x85, 0x08, 0x50, + 0x07, 0x0e, 0xf7, 0x76, 0xf8, 0x9e, 0x15, 0xeb, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x7d, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xeb, 0xfb, 0x79, 0x06, 0xfb, 0x12, + 0x41, 0x05, 0x7f, 0x84, 0x87, 0x86, 0x8b, 0x83, 0x8b, 0x80, 0x95, 0x81, + 0x94, 0x8b, 0x8f, 0x8b, 0x92, 0x8d, 0x91, 0x8f, 0x08, 0xf5, 0xc9, 0x8b, + 0xfb, 0x61, 0x2b, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xf8, 0x58, 0xf7, 0x5e, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, + 0x84, 0x82, 0x79, 0x1e, 0xfb, 0x35, 0xfb, 0xa6, 0xf7, 0x72, 0x07, 0xf7, + 0x2e, 0xe7, 0x05, 0x98, 0x92, 0x8f, 0x8f, 0x8b, 0x94, 0x8b, 0x95, 0x82, + 0x95, 0x80, 0x8b, 0x87, 0x8b, 0x83, 0x88, 0x86, 0x89, 0x08, 0xfb, 0x1a, + 0x3b, 0x8b, 0xf7, 0x68, 0x05, 0x0e, 0xf7, 0x21, 0xbe, 0x15, 0xb8, 0x5f, + 0xc1, 0x74, 0xc7, 0x8b, 0xf7, 0x1f, 0x8b, 0xf7, 0x02, 0xf7, 0x17, 0x8b, + 0xf7, 0x39, 0x8b, 0xd7, 0x73, 0xd5, 0x60, 0xc0, 0x08, 0xd1, 0xe3, 0x05, + 0x91, 0x93, 0x8d, 0x8e, 0x8b, 0x90, 0x8b, 0x95, 0x83, 0x93, 0x81, 0x8b, + 0x84, 0x8b, 0x87, 0x88, 0x84, 0x82, 0x08, 0x49, 0x38, 0x05, 0x5a, 0xb8, + 0x5a, 0xa0, 0x4f, 0x8b, 0xfb, 0x1f, 0x8b, 0xfb, 0x02, 0xfb, 0x16, 0x8b, + 0xfb, 0x3a, 0x8b, 0x3f, 0xa0, 0x49, 0xb8, 0x4f, 0x08, 0x46, 0x34, 0x05, + 0x84, 0x82, 0x8a, 0x88, 0x8b, 0x87, 0x8b, 0x81, 0x93, 0x83, 0x95, 0x8b, + 0x91, 0x8b, 0x90, 0x8e, 0x92, 0x94, 0x08, 0xcc, 0xdd, 0x05, 0x8e, 0xc8, + 0x15, 0x68, 0xbf, 0x7a, 0xc1, 0x8b, 0xc9, 0x8b, 0xf7, 0x20, 0xe8, 0xf7, + 0x07, 0xf7, 0x07, 0x8b, 0xbc, 0x8b, 0xb6, 0x78, 0xb3, 0x63, 0x08, 0xfb, + 0xb4, 0xfc, 0x00, 0x05, 0xf7, 0xcc, 0xf7, 0xe5, 0x15, 0xad, 0x5a, 0x9d, + 0x52, 0x8b, 0x4c, 0x8b, 0xfb, 0x20, 0x2d, 0xfb, 0x07, 0xfb, 0x06, 0x8b, + 0x5a, 0x8b, 0x5e, 0x9f, 0x64, 0xb2, 0x08, 0xf7, 0xb5, 0xf8, 0x01, 0x05, + 0x0e, 0xf7, 0xe6, 0xf7, 0xa4, 0x15, 0xd9, 0x6f, 0x06, 0x79, 0x92, 0x82, + 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xeb, 0x07, 0x9d, 0x84, 0x94, 0x7e, + 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x70, 0x3d, 0xf7, 0x65, 0xf7, 0x53, 0xfb, + 0x05, 0x07, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, + 0x2e, 0xfb, 0xcf, 0x07, 0xfb, 0x26, 0x28, 0xfb, 0x06, 0xfb, 0x3b, 0xfb, + 0x3e, 0xf0, 0xfb, 0x04, 0xf7, 0x2c, 0x1f, 0xf7, 0xdb, 0xf7, 0x19, 0x06, + 0x9b, 0x83, 0x96, 0x7e, 0x7d, 0x85, 0x84, 0x77, 0x1e, 0x2f, 0xfb, 0x67, + 0x07, 0xf7, 0x7b, 0x07, 0x62, 0xf7, 0x8e, 0x15, 0xfc, 0x75, 0x6b, 0x07, + 0x43, 0x8b, 0x58, 0xa1, 0x65, 0xbb, 0x68, 0xb7, 0x79, 0xc5, 0x8b, 0xcf, + 0x8b, 0xcf, 0x9d, 0xc6, 0xae, 0xb7, 0xb1, 0xbb, 0xbd, 0xa1, 0xd4, 0x8b, + 0x08, 0xab, 0x06, 0x0e, 0xf7, 0xc1, 0xf8, 0xd5, 0x15, 0x3a, 0x49, 0x49, + 0x3b, 0x3a, 0xcd, 0x49, 0xdc, 0xdb, 0xce, 0xcd, 0xda, 0xde, 0x4a, 0xcc, + 0x39, 0x1f, 0x66, 0x04, 0xc9, 0xbb, 0x5a, 0x4d, 0x50, 0x59, 0x5a, 0x4f, + 0x4f, 0x59, 0xbc, 0xc8, 0xc7, 0xbc, 0xbc, 0xc8, 0x1f, 0x0e, 0xf7, 0xd4, + 0xc8, 0x15, 0xab, 0x5a, 0xb9, 0x6f, 0xb9, 0x8b, 0xab, 0x8b, 0xa9, 0x99, + 0xb4, 0xaa, 0xa2, 0x9e, 0x93, 0x94, 0x8b, 0x95, 0x8b, 0x95, 0x82, 0x95, + 0x80, 0x8b, 0x87, 0x8b, 0x86, 0x89, 0x87, 0x88, 0x5b, 0x5f, 0x75, 0x7e, + 0x6e, 0x8b, 0x08, 0x48, 0x8b, 0x56, 0xd3, 0x84, 0xf1, 0x08, 0xf7, 0x96, + 0x06, 0x8a, 0xc0, 0x86, 0xaf, 0x7f, 0xb0, 0x76, 0xce, 0x5b, 0xb2, 0x4f, + 0x8b, 0x5b, 0x8b, 0x5d, 0x6b, 0x73, 0x57, 0x78, 0xbe, 0x5e, 0xac, 0x5a, + 0x8b, 0x6d, 0x8b, 0x6c, 0x83, 0x65, 0x7a, 0x76, 0x82, 0x83, 0x83, 0x8b, + 0x80, 0x08, 0x82, 0x95, 0x80, 0x94, 0x1e, 0x8f, 0x8b, 0x92, 0x8e, 0x92, + 0x8f, 0xa4, 0x9b, 0xab, 0x94, 0xa6, 0x8b, 0x08, 0xbc, 0xb2, 0x65, 0x5c, + 0x1f, 0x4f, 0x07, 0x6e, 0x93, 0x6f, 0x8f, 0x6f, 0x8b, 0x5a, 0x8b, 0x51, + 0x7a, 0x6c, 0x74, 0x6d, 0x73, 0x7c, 0x70, 0x8b, 0x69, 0x8b, 0x36, 0xca, + 0x4c, 0xe0, 0x8b, 0xb7, 0x8b, 0xb0, 0xa0, 0xb2, 0xba, 0x08, 0x72, 0x07, + 0x79, 0x92, 0x82, 0x98, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xad, 0x07, 0x63, + 0xbc, 0x15, 0x5c, 0x4f, 0x69, 0x72, 0x66, 0x8b, 0x4e, 0x8b, 0x5f, 0xb3, + 0x8b, 0xc3, 0x8b, 0xa3, 0x92, 0x9c, 0x99, 0x99, 0xa1, 0xa0, 0xc5, 0x9e, + 0xb6, 0x8b, 0xa2, 0x8b, 0xa8, 0x86, 0xa6, 0x83, 0x08, 0x2e, 0x07, 0xb3, + 0xf7, 0x16, 0x15, 0x98, 0xef, 0xaf, 0xbd, 0xc7, 0x8b, 0xae, 0x8b, 0xaa, + 0x77, 0x9c, 0x68, 0x96, 0x75, 0x91, 0x72, 0x91, 0x5b, 0x08, 0xfb, 0x6b, + 0x06, 0x0e, 0xf7, 0xd4, 0xf8, 0x35, 0x15, 0xfb, 0x33, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x0a, 0xfb, 0xe3, 0xfb, + 0x34, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0xfd, 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, + 0x34, 0xf8, 0x0c, 0x06, 0x0e, 0xf7, 0xd3, 0xf8, 0xf0, 0x15, 0xfb, 0x32, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x09, + 0xfb, 0x80, 0x06, 0x20, 0x4e, 0x05, 0x7f, 0x84, 0x87, 0x86, 0x8b, 0x82, + 0x8b, 0x80, 0x94, 0x81, 0x95, 0x8b, 0x91, 0x8b, 0x8d, 0x8c, 0x94, 0x90, + 0x08, 0xe2, 0xbd, 0x8b, 0xfb, 0x83, 0xfb, 0x33, 0x8b, 0x05, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xfe, 0x06, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x36, 0xf7, 0x94, 0x06, + 0xf7, 0x00, 0xc9, 0x05, 0x97, 0x92, 0x8f, 0x8f, 0x8b, 0x95, 0x8b, 0x96, + 0x82, 0x94, 0x81, 0x8b, 0x86, 0x8b, 0x86, 0x89, 0x84, 0x87, 0x08, 0x33, + 0x58, 0x8b, 0xf7, 0x99, 0x05, 0x0e, 0xf7, 0x2e, 0xae, 0x15, 0xb7, 0x69, + 0xba, 0x7a, 0xc2, 0x8b, 0xf7, 0x13, 0x8b, 0xf0, 0xee, 0x8b, 0xf7, 0x10, + 0x8b, 0xc4, 0x77, 0xbe, 0x64, 0xb6, 0x08, 0xcb, 0xcc, 0x05, 0x93, 0x93, + 0x8d, 0x8f, 0x8b, 0x90, 0x8b, 0x95, 0x83, 0x93, 0x82, 0x8b, 0x85, 0x8b, + 0x88, 0x89, 0x82, 0x83, 0x08, 0x4b, 0x49, 0x05, 0x61, 0xac, 0x5b, 0x9b, + 0x55, 0x8b, 0xfb, 0x13, 0x8b, 0x26, 0x28, 0x8b, 0xfb, 0x10, 0x8b, 0x54, + 0x9f, 0x58, 0xb0, 0x60, 0x08, 0x49, 0x48, 0x05, 0x83, 0x83, 0x89, 0x87, + 0x8b, 0x86, 0x8b, 0x81, 0x93, 0x83, 0x95, 0x8b, 0x90, 0x8b, 0x8f, 0x8d, + 0x93, 0x93, 0x08, 0xcd, 0xcf, 0x05, 0xf7, 0xb3, 0xf7, 0xba, 0x15, 0xa9, + 0x68, 0x9b, 0x62, 0x8b, 0x5d, 0x8b, 0x26, 0x38, 0x3a, 0x23, 0x8b, 0x5f, + 0x8b, 0x63, 0x99, 0x6a, 0xa5, 0x08, 0xf7, 0x96, 0xf7, 0x9c, 0x05, 0xfb, + 0xaf, 0xfb, 0x84, 0x15, 0x6e, 0xac, 0x7b, 0xb5, 0x8b, 0xb7, 0x8b, 0xf0, + 0xde, 0xdc, 0xf3, 0x8b, 0xb6, 0x8b, 0xb2, 0x7e, 0xac, 0x72, 0x08, 0xfb, + 0x95, 0xfb, 0x9b, 0x05, 0x0e, 0xf8, 0xd5, 0xf7, 0x5b, 0x15, 0x8b, 0xc0, + 0x86, 0xaf, 0x7f, 0xb0, 0x75, 0xce, 0x5b, 0xb2, 0x50, 0x8b, 0x6c, 0x8b, + 0x6e, 0x7f, 0x72, 0x73, 0x77, 0x78, 0x81, 0x7b, 0x7a, 0x60, 0x6f, 0xd1, + 0x57, 0xb7, 0x55, 0x8b, 0x08, 0x38, 0x45, 0x26, 0xfb, 0x0a, 0xfb, 0x0f, + 0xd2, 0x22, 0xde, 0x1f, 0xc3, 0x8b, 0xbb, 0xb6, 0xa8, 0xd7, 0xa9, 0x42, + 0xc2, 0x5d, 0xc7, 0x8b, 0xab, 0x8b, 0xa9, 0x99, 0xb4, 0xaa, 0xa2, 0x9e, + 0x93, 0x94, 0x8b, 0x95, 0x8b, 0x95, 0x81, 0x95, 0x81, 0x8b, 0x87, 0x8b, + 0x86, 0x89, 0x87, 0x88, 0x08, 0x5b, 0x5f, 0x75, 0x7e, 0x6e, 0x8b, 0x4b, + 0x8b, 0x54, 0xd6, 0x83, 0xee, 0x08, 0xf7, 0x96, 0x06, 0xfb, 0x95, 0xb4, + 0x15, 0x98, 0xef, 0xb0, 0xbd, 0xc6, 0x8b, 0xaf, 0x8b, 0xa9, 0x77, 0x9d, + 0x68, 0x96, 0x75, 0x91, 0x72, 0x91, 0x5b, 0x08, 0xfb, 0x6c, 0x06, 0xfb, + 0x2e, 0xf7, 0x2a, 0x15, 0xc9, 0xbf, 0x36, 0x28, 0x2c, 0x55, 0x35, 0x50, + 0x4e, 0x56, 0xe1, 0xec, 0xec, 0xc0, 0xe0, 0xc7, 0x1f, 0x0e, 0xf7, 0x10, + 0xb4, 0x15, 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x02, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x7c, 0xf8, 0x47, 0x06, 0xbc, 0xb8, 0xb1, 0xc3, 0xc5, 0xba, 0x5c, + 0x52, 0x5f, 0x5e, 0x63, 0x58, 0x1e, 0x86, 0x06, 0x7d, 0x82, 0x83, 0x7f, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0x90, 0x06, 0xb1, 0x8b, 0xbb, 0x79, 0xab, + 0x71, 0xb2, 0x6b, 0xa1, 0x5d, 0x8b, 0x59, 0x08, 0x3e, 0x62, 0x4f, 0x57, + 0x1e, 0x65, 0x8b, 0x73, 0xa8, 0x88, 0xb9, 0x8a, 0x9b, 0x84, 0x93, 0x7e, + 0x8b, 0x08, 0x7f, 0x83, 0x82, 0x7d, 0x49, 0xb9, 0x58, 0xc7, 0xd7, 0xc5, + 0xd7, 0xf0, 0x1f, 0x8b, 0xe7, 0x5a, 0xce, 0x2b, 0xb2, 0xb3, 0xa6, 0x9d, + 0xaa, 0x8b, 0xb4, 0x08, 0xdc, 0x4a, 0xcc, 0x3a, 0x3d, 0x4b, 0x52, 0x44, + 0x1e, 0xfc, 0x47, 0x07, 0x0e, 0xf8, 0x40, 0xf7, 0x50, 0x15, 0xc3, 0xfb, + 0x27, 0x3f, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x30, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x66, 0x8b, 0xfb, 0x59, 0xf8, 0x9e, 0xfb, 0x60, 0x8b, 0x05, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, + 0x47, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xf7, 0x2b, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, + 0x92, 0x79, 0x1f, 0x3c, 0x8b, 0xc1, 0xf7, 0x27, 0xf7, 0x9e, 0x8b, 0x05, + 0x7c, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, 0x00, 0xf7, 0xb9, 0x9a, 0x8b, + 0xf7, 0x04, 0xfb, 0xb9, 0x05, 0xfb, 0x8f, 0xf8, 0xa8, 0x15, 0x70, 0x74, + 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, + 0xa2, 0x6f, 0x1f, 0xf7, 0x72, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, + 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, + 0xf8, 0x40, 0xf7, 0x50, 0x15, 0xc3, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x30, 0x06, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x66, 0x8b, 0xfb, 0x59, + 0xf8, 0x9e, 0xfb, 0x60, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0x47, 0xfc, 0x75, 0x6c, 0x8b, + 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x2b, + 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x3c, 0x8b, + 0xc1, 0xf7, 0x27, 0xf7, 0x9e, 0x8b, 0x05, 0x7c, 0xb4, 0x15, 0xfb, 0x7f, + 0x8b, 0xf7, 0x00, 0xf7, 0xb9, 0x9a, 0x8b, 0xf7, 0x04, 0xfb, 0xb9, 0x05, + 0x60, 0xf8, 0x9c, 0x15, 0x96, 0x94, 0x8d, 0x8e, 0x8b, 0x92, 0x8b, 0x97, + 0x82, 0x94, 0x7f, 0x8b, 0x86, 0x8b, 0x86, 0x89, 0x83, 0x84, 0x08, 0xfb, + 0x06, 0x27, 0x05, 0x82, 0x84, 0x88, 0x86, 0x8b, 0x84, 0x8b, 0x7f, 0x94, + 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x93, 0x92, 0x08, 0xf7, 0x06, + 0xef, 0x05, 0x0e, 0xf8, 0x40, 0xf7, 0x50, 0x15, 0xc3, 0xfb, 0x27, 0x3f, + 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x30, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x66, + 0x8b, 0xfb, 0x59, 0xf8, 0x9e, 0xfb, 0x60, 0x8b, 0x05, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0x47, 0xfc, + 0x75, 0x6c, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x2b, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x3c, 0x8b, 0xc1, 0xf7, 0x27, 0xf7, 0x9e, 0x8b, 0x05, 0x7c, 0xb4, + 0x15, 0xfb, 0x7f, 0x8b, 0xf7, 0x00, 0xf7, 0xb9, 0x9a, 0x8b, 0xf7, 0x04, + 0xfb, 0xb9, 0x05, 0xfb, 0x66, 0xf8, 0xbb, 0x15, 0x83, 0x92, 0x87, 0x8d, + 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, 0x8f, 0x85, + 0x92, 0x84, 0x08, 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x92, 0x88, 0x90, + 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x90, 0x8a, 0x8d, 0x87, + 0x8f, 0x08, 0x83, 0x93, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x40, 0xf7, + 0x50, 0x15, 0xc3, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x30, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x66, 0x8b, 0xfb, 0x59, 0xf8, 0x9e, 0xfb, + 0x60, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xf7, 0x0c, 0x8b, 0xfb, 0x47, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x2b, 0x06, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x3c, 0x8b, 0xc1, 0xf7, 0x27, + 0xf7, 0x9e, 0x8b, 0x05, 0x7c, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, 0x00, + 0xf7, 0xb9, 0x9a, 0x8b, 0xf7, 0x04, 0xfb, 0xb9, 0x05, 0xfb, 0x20, 0xf8, + 0xc4, 0x15, 0xfb, 0x17, 0xfb, 0x01, 0x87, 0x89, 0x05, 0x84, 0x86, 0x88, + 0x85, 0x8b, 0x84, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, + 0x8e, 0x92, 0x90, 0x08, 0xf6, 0xe3, 0xf7, 0x00, 0x33, 0x05, 0x91, 0x86, + 0x92, 0x88, 0x8f, 0x8b, 0x96, 0x8b, 0x95, 0x94, 0x8b, 0x96, 0x8b, 0x92, + 0x88, 0x91, 0x84, 0x90, 0x08, 0x87, 0x8e, 0xfb, 0x18, 0xf7, 0x00, 0x05, + 0x0e, 0xf8, 0x40, 0xf7, 0x50, 0x15, 0xc3, 0xfb, 0x27, 0x3f, 0x8b, 0x05, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x30, 0x06, + 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x66, 0x8b, 0xfb, + 0x59, 0xf8, 0x9e, 0xfb, 0x60, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0x47, 0xfc, 0x75, 0x6c, + 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x2b, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x3c, + 0x8b, 0xc1, 0xf7, 0x27, 0xf7, 0x9e, 0x8b, 0x05, 0x7c, 0xb4, 0x15, 0xfb, + 0x7f, 0x8b, 0xf7, 0x00, 0xf7, 0xb9, 0x9a, 0x8b, 0xf7, 0x04, 0xfb, 0xb9, + 0x05, 0x86, 0xf8, 0xa0, 0x15, 0x85, 0x8b, 0x87, 0x89, 0x85, 0x85, 0x6d, + 0x6c, 0x81, 0x84, 0x7a, 0x8b, 0x7e, 0x8b, 0x83, 0x8f, 0x65, 0xa0, 0x6b, + 0x9e, 0x7f, 0x8f, 0x77, 0x8b, 0x72, 0x8b, 0x76, 0x81, 0x6e, 0x70, 0x7e, + 0x7e, 0x85, 0x82, 0x8b, 0x83, 0x08, 0x80, 0x94, 0x83, 0x96, 0x1e, 0x91, + 0x8b, 0x92, 0x8e, 0x8f, 0x90, 0xa8, 0xaa, 0x94, 0x91, 0x9f, 0x8b, 0x97, + 0x8b, 0x96, 0x87, 0x9f, 0x7e, 0xb3, 0x73, 0x9e, 0x84, 0xa1, 0x8b, 0xa2, + 0x8b, 0x9f, 0x95, 0xa5, 0xa5, 0x9d, 0x9c, 0x8f, 0x91, 0x8b, 0x93, 0x08, + 0x96, 0x81, 0x94, 0x81, 0x1e, 0x0e, 0xf8, 0x40, 0xf7, 0x50, 0x15, 0xc3, + 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xf7, 0x30, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0x66, 0x8b, 0xfb, 0x59, 0xf8, 0x9e, 0xfb, 0x60, 0x8b, 0x05, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x0c, 0x8b, + 0xfb, 0x47, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x2b, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0x3c, 0x8b, 0xc1, 0xf7, 0x27, 0xf7, 0x9e, 0x8b, + 0x05, 0x7c, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, 0x00, 0xf7, 0xb9, 0x9a, + 0x8b, 0xf7, 0x04, 0xfb, 0xb9, 0x05, 0xfb, 0x1c, 0xf8, 0xda, 0x15, 0x58, + 0x61, 0x62, 0x5a, 0x59, 0xb5, 0x62, 0xbe, 0xbe, 0xb5, 0xb4, 0xbb, 0xbf, + 0x62, 0xb3, 0x57, 0x1f, 0x6a, 0x04, 0xac, 0xa6, 0x71, 0x6b, 0x6c, 0x70, + 0x71, 0x6a, 0x6a, 0x70, 0xa5, 0xab, 0xaa, 0xa6, 0xa5, 0xac, 0x1f, 0x0e, + 0xf7, 0xd1, 0x7b, 0x15, 0x98, 0x06, 0xc2, 0x8b, 0xcc, 0xa7, 0xb9, 0xb6, + 0xa5, 0xa3, 0x97, 0x9c, 0x8b, 0x95, 0x8b, 0x96, 0x83, 0x93, 0x7f, 0x8b, + 0x84, 0x8b, 0x87, 0x89, 0x84, 0x83, 0x55, 0x4b, 0x58, 0x71, 0x46, 0x8b, + 0x08, 0xfb, 0x0a, 0x27, 0xf2, 0xf7, 0x0c, 0x1f, 0xd2, 0x07, 0xf7, 0x0b, + 0xe5, 0xec, 0xf7, 0x03, 0x1e, 0xe4, 0x8b, 0xdb, 0x56, 0x8f, 0x4e, 0x8c, + 0x7b, 0x92, 0x83, 0x97, 0x8b, 0x08, 0x99, 0x92, 0x94, 0x9d, 0x1f, 0xf7, + 0x04, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x6e, + 0x07, 0x5c, 0xb8, 0x4f, 0xa3, 0x49, 0x8b, 0x48, 0x8b, 0x50, 0x71, 0x5e, + 0x5b, 0x60, 0x5d, 0x6f, 0x45, 0x8b, 0x4e, 0x08, 0x38, 0x07, 0x8b, 0x3a, + 0xba, 0x38, 0xd4, 0x59, 0xa7, 0x77, 0xa3, 0x82, 0xb7, 0x80, 0x08, 0x46, + 0x9f, 0x07, 0xaa, 0x9a, 0x83, 0x7a, 0x7a, 0x79, 0x7f, 0x71, 0x1f, 0x7c, + 0x8b, 0x7e, 0x8f, 0x74, 0x97, 0x83, 0x8f, 0x87, 0x8c, 0x88, 0x8b, 0x80, + 0x8b, 0x82, 0x83, 0x8b, 0x80, 0x8b, 0x81, 0x8f, 0x86, 0x99, 0x84, 0x9e, + 0x81, 0xaa, 0x83, 0x9f, 0x8b, 0xba, 0x8b, 0xab, 0xa5, 0x8b, 0xb2, 0x08, + 0x8b, 0xb1, 0x73, 0xa1, 0x62, 0x8c, 0x08, 0xaa, 0x07, 0x0e, 0xf3, 0xf7, + 0xa4, 0x15, 0xfb, 0x7b, 0x69, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xf7, 0x70, 0x06, 0xf7, 0x12, 0xf3, 0xf7, 0x07, 0xf7, + 0x1f, 0x1f, 0xc3, 0x07, 0xf7, 0x1e, 0x23, 0xf7, 0x07, 0xfb, 0x12, 0x1e, + 0xfb, 0x70, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xad, 0xfb, 0x65, 0x3e, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xd8, 0x06, 0xb4, 0xf7, 0x8e, 0x15, 0xf7, 0x23, 0x06, 0xc1, + 0x8b, 0xb0, 0x7c, 0xae, 0x68, 0xb3, 0x62, 0xa4, 0x4f, 0x8b, 0x57, 0x08, + 0x41, 0x07, 0x22, 0x31, 0x28, 0x2d, 0x1e, 0xfb, 0x2a, 0xf7, 0x7b, 0xf7, + 0x36, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, + 0x36, 0xf7, 0x65, 0x06, 0x0e, 0xf7, 0x39, 0xf7, 0xa4, 0x15, 0xf7, 0x25, + 0x5e, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, + 0x17, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x5e, + 0xfb, 0x25, 0xf7, 0x65, 0xf7, 0xb9, 0x29, 0x07, 0x79, 0x92, 0x82, 0x98, + 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x1f, 0xfc, 0x41, 0x07, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x55, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x56, 0xf7, + 0x34, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0xfb, + 0x0b, 0xfb, 0xce, 0x07, 0xf7, 0x7b, 0x07, 0x9b, 0xf8, 0x7d, 0x15, 0x70, + 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0x1f, + 0xa7, 0x75, 0xa2, 0x6f, 0x1e, 0xf7, 0x71, 0x16, 0x70, 0x74, 0x74, 0x70, + 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, + 0x1f, 0x0e, 0xf7, 0x39, 0xf7, 0xa4, 0x15, 0xf7, 0x25, 0x5e, 0x06, 0x79, + 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x17, 0x07, 0x9d, + 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x5e, 0xfb, 0x25, 0xf7, + 0x65, 0xf7, 0xb9, 0x29, 0x07, 0x79, 0x92, 0x82, 0x98, 0x99, 0x92, 0x94, + 0x9d, 0x1e, 0xf7, 0x1f, 0xfc, 0x41, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x55, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x56, 0xf7, 0x34, 0x06, 0x9d, + 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0xfb, 0x0b, 0xfb, 0xce, + 0x07, 0xf7, 0x7b, 0x07, 0xf7, 0x74, 0xf8, 0x71, 0x15, 0x95, 0x94, 0x8d, + 0x8e, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x7f, 0x8b, 0x86, 0x8b, 0x86, + 0x89, 0x83, 0x84, 0x08, 0xfb, 0x06, 0x27, 0x05, 0x82, 0x83, 0x88, 0x87, + 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, + 0x93, 0x92, 0x08, 0xf7, 0x07, 0xef, 0x05, 0x0e, 0xf7, 0x39, 0xf7, 0xa4, + 0x15, 0xf7, 0x25, 0x5e, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, + 0x9d, 0x1e, 0xf7, 0x17, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, + 0x79, 0x1e, 0x5e, 0xfb, 0x25, 0xf7, 0x65, 0xf7, 0xb9, 0x29, 0x07, 0x79, + 0x92, 0x82, 0x98, 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x1f, 0xfc, 0x41, + 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, + 0x75, 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xf8, 0x56, 0xf7, 0x34, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, + 0x79, 0x1e, 0xfb, 0x0b, 0xfb, 0xce, 0x07, 0xf7, 0x7b, 0x07, 0xbc, 0xf8, + 0x90, 0x15, 0x84, 0x92, 0x86, 0x8d, 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, + 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x85, 0x94, 0x84, 0x08, 0xf7, 0x06, 0x27, + 0x05, 0x92, 0x85, 0x91, 0x88, 0x90, 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, + 0x97, 0x8b, 0x90, 0x8a, 0x8d, 0x87, 0x8f, 0x88, 0x8e, 0x89, 0x8e, 0x88, + 0x8d, 0x08, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf7, 0x39, 0xf7, 0xa4, 0x15, + 0xf7, 0x25, 0x5e, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, + 0x1e, 0xf7, 0x17, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, + 0x1e, 0x5e, 0xfb, 0x25, 0xf7, 0x65, 0xf7, 0xb9, 0x29, 0x07, 0x79, 0x92, + 0x82, 0x98, 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x1f, 0xfc, 0x41, 0x07, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, + 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, + 0x56, 0xf7, 0x34, 0x06, 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, + 0x1e, 0xfb, 0x0b, 0xfb, 0xce, 0x07, 0xf7, 0x7b, 0x07, 0xf7, 0x13, 0xf8, + 0x99, 0x15, 0xfb, 0x18, 0xfb, 0x01, 0x87, 0x89, 0x05, 0x85, 0x86, 0x87, + 0x85, 0x8b, 0x84, 0x8b, 0x80, 0x94, 0x82, 0x97, 0x8b, 0x90, 0x8b, 0x90, + 0x8e, 0x92, 0x90, 0x08, 0xf7, 0x00, 0xe3, 0xf6, 0x33, 0x05, 0x92, 0x86, + 0x91, 0x88, 0x90, 0x8b, 0x95, 0x8b, 0x95, 0x94, 0x8b, 0x96, 0x8b, 0x93, + 0x89, 0x8f, 0x7f, 0x94, 0x08, 0xfb, 0x17, 0xf7, 0x00, 0x05, 0x0e, 0xf7, + 0xd4, 0xf8, 0x9e, 0x15, 0xf7, 0x1f, 0x06, 0x9e, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x78, 0x1f, 0xfb, 0xd3, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x1f, 0xfc, 0x75, 0xfb, 0x1f, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xd3, 0x06, 0x9d, + 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x1f, 0xf8, 0x75, + 0x06, 0xfb, 0x17, 0xf7, 0x83, 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, + 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0xf7, + 0x72, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, + 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, 0xf7, 0xd4, 0xf8, 0x9e, + 0x15, 0xf7, 0x1f, 0x06, 0x9e, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, + 0x1f, 0xfb, 0xd3, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x1f, 0xfc, 0x75, 0xfb, 0x1f, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xd3, 0x06, 0x9d, 0x95, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x1f, 0xf8, 0x75, 0x06, 0xf7, 0x05, + 0xf7, 0x77, 0x15, 0x94, 0x93, 0x8e, 0x8f, 0x8b, 0x92, 0x8b, 0x97, 0x82, + 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x87, 0x89, 0x82, 0x84, 0x08, 0xfb, 0x06, + 0x27, 0x05, 0x81, 0x82, 0x89, 0x88, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, + 0x96, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x94, 0x92, 0x08, 0xf7, 0x06, 0xef, + 0x05, 0x0e, 0xf7, 0xd4, 0xf8, 0x9e, 0x15, 0xf7, 0x1f, 0x06, 0x9e, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0xd3, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x1f, 0xfc, 0x75, 0xfb, + 0x1f, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0xd3, 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, + 0x1f, 0xf8, 0x75, 0x06, 0x31, 0xf7, 0x96, 0x15, 0x83, 0x92, 0x86, 0x8d, + 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x86, + 0x94, 0x83, 0x08, 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x91, 0x88, 0x90, + 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x90, 0x8a, 0x8d, 0x87, + 0x8f, 0x08, 0x84, 0x93, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf7, 0xd4, 0xf8, + 0x9e, 0x15, 0xf7, 0x1f, 0x06, 0x9e, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x78, 0x1f, 0xfb, 0xd3, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xf7, 0x1f, 0xfc, 0x75, 0xfb, 0x1f, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xd3, 0x06, 0x9d, 0x95, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x1f, 0xf8, 0x75, 0x06, 0x77, + 0xf7, 0x9f, 0x15, 0xfb, 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, 0x88, 0x87, + 0x8b, 0x82, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, 0x8e, + 0x91, 0x90, 0x08, 0xf7, 0x00, 0xe3, 0xf7, 0x00, 0x33, 0x05, 0x91, 0x86, + 0x91, 0x88, 0x90, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x93, + 0x89, 0x8f, 0x80, 0x94, 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf8, + 0x89, 0x16, 0xf8, 0x9e, 0xad, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, + 0x92, 0x79, 0x1f, 0xfb, 0x29, 0x06, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9e, 0x1f, 0xd5, 0xfc, 0x63, 0x06, 0xfb, 0xc5, 0xf8, 0x8c, 0x21, + 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, + 0xfc, 0x75, 0x69, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x2a, 0x06, 0x9c, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x40, 0xf8, 0x63, 0x06, 0xf7, 0xc5, 0xfc, 0x8c, 0xbf, 0x8b, 0x05, + 0x47, 0xf9, 0x85, 0x15, 0x86, 0x8b, 0x87, 0x89, 0x85, 0x85, 0x6d, 0x6c, + 0x80, 0x84, 0x7b, 0x8b, 0x7e, 0x8b, 0x83, 0x8e, 0x65, 0xa1, 0x6a, 0x9e, + 0x7f, 0x8f, 0x77, 0x8b, 0x72, 0x8b, 0x76, 0x81, 0x6f, 0x70, 0x7d, 0x7e, + 0x85, 0x82, 0x8b, 0x83, 0x08, 0x80, 0x94, 0x83, 0x96, 0x1e, 0x91, 0x8b, + 0x92, 0x8e, 0x8f, 0x90, 0xa8, 0xaa, 0x94, 0x91, 0x9f, 0x8b, 0x97, 0x8b, + 0x96, 0x87, 0xa0, 0x7e, 0xb3, 0x73, 0x9e, 0x84, 0xa0, 0x8b, 0xa3, 0x8b, + 0x9f, 0x95, 0xa5, 0xa5, 0x9d, 0x9c, 0x8f, 0x91, 0x8b, 0x93, 0x08, 0x96, + 0x81, 0x94, 0x80, 0x1e, 0x0e, 0xf7, 0xc0, 0xf8, 0xd4, 0x15, 0xfb, 0x1f, + 0xfb, 0x02, 0xfb, 0x17, 0xfb, 0x39, 0xfb, 0x39, 0xf7, 0x02, 0xfb, 0x17, + 0xf7, 0x1f, 0xf7, 0x1d, 0xf7, 0x04, 0xf7, 0x17, 0xf7, 0x35, 0xf7, 0x3e, + 0xfb, 0x00, 0xf7, 0x16, 0xfb, 0x21, 0x1f, 0x62, 0x04, 0xf7, 0x08, 0xe7, + 0xfb, 0x06, 0xfb, 0x24, 0xfb, 0x1d, 0x2c, 0xfb, 0x07, 0xfb, 0x05, 0xfb, + 0x06, 0x2d, 0xf7, 0x07, 0xf7, 0x20, 0xf7, 0x20, 0xe8, 0xf7, 0x07, 0xf7, + 0x07, 0x1f, 0xfb, 0x03, 0xf7, 0x76, 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, + 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, + 0xf7, 0x72, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, + 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, 0xf7, 0xc0, 0xf8, + 0xd4, 0x15, 0xfb, 0x1f, 0xfb, 0x02, 0xfb, 0x17, 0xfb, 0x39, 0xfb, 0x39, + 0xf7, 0x02, 0xfb, 0x17, 0xf7, 0x1f, 0xf7, 0x1d, 0xf7, 0x04, 0xf7, 0x17, + 0xf7, 0x35, 0xf7, 0x3e, 0xfb, 0x00, 0xf7, 0x16, 0xfb, 0x21, 0x1f, 0x62, + 0x04, 0xf7, 0x08, 0xe7, 0xfb, 0x06, 0xfb, 0x24, 0xfb, 0x1d, 0x2c, 0xfb, + 0x07, 0xfb, 0x05, 0xfb, 0x06, 0x2d, 0xf7, 0x07, 0xf7, 0x20, 0xf7, 0x20, + 0xe8, 0xf7, 0x07, 0xf7, 0x07, 0x1f, 0xf3, 0xf7, 0x6a, 0x15, 0x95, 0x94, + 0x8d, 0x8e, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x80, 0x8b, 0x85, 0x8b, + 0x86, 0x89, 0x83, 0x84, 0x08, 0xfb, 0x06, 0x27, 0x05, 0x82, 0x83, 0x88, + 0x87, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, + 0x8d, 0x94, 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, 0x0e, 0xf7, 0xc0, 0xf8, + 0xd4, 0x15, 0xfb, 0x1f, 0xfb, 0x02, 0xfb, 0x17, 0xfb, 0x39, 0xfb, 0x39, + 0xf7, 0x02, 0xfb, 0x17, 0xf7, 0x1f, 0xf7, 0x1d, 0xf7, 0x04, 0xf7, 0x17, + 0xf7, 0x35, 0xf7, 0x3e, 0xfb, 0x00, 0xf7, 0x16, 0xfb, 0x21, 0x1f, 0x62, + 0x04, 0xf7, 0x08, 0xe7, 0xfb, 0x06, 0xfb, 0x24, 0xfb, 0x1d, 0x2c, 0xfb, + 0x07, 0xfb, 0x05, 0xfb, 0x06, 0x2d, 0xf7, 0x07, 0xf7, 0x20, 0xf7, 0x20, + 0xe8, 0xf7, 0x07, 0xf7, 0x07, 0x1f, 0x3e, 0xf7, 0x89, 0x15, 0x83, 0x92, + 0x87, 0x8d, 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, + 0x8f, 0x85, 0x92, 0x84, 0x08, 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x92, + 0x88, 0x90, 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x90, 0x8a, + 0x8d, 0x87, 0x8f, 0x08, 0x83, 0x93, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf7, + 0xc0, 0xf8, 0xd4, 0x15, 0xfb, 0x1f, 0xfb, 0x02, 0xfb, 0x17, 0xfb, 0x39, + 0xfb, 0x39, 0xf7, 0x02, 0xfb, 0x17, 0xf7, 0x1f, 0xf7, 0x1d, 0xf7, 0x04, + 0xf7, 0x17, 0xf7, 0x35, 0xf7, 0x3e, 0xfb, 0x00, 0xf7, 0x16, 0xfb, 0x21, + 0x1f, 0x62, 0x04, 0xf7, 0x08, 0xe7, 0xfb, 0x06, 0xfb, 0x24, 0xfb, 0x1d, + 0x2c, 0xfb, 0x07, 0xfb, 0x05, 0xfb, 0x06, 0x2d, 0xf7, 0x07, 0xf7, 0x20, + 0xf7, 0x20, 0xe8, 0xf7, 0x07, 0xf7, 0x07, 0x1f, 0xf7, 0x92, 0x04, 0xfb, + 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, 0x88, 0x87, 0x8b, 0x82, 0x8b, 0x80, + 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, 0x8e, 0x91, 0x90, 0x08, 0xf7, + 0x00, 0xe3, 0xf7, 0x00, 0x33, 0x05, 0x91, 0x86, 0x91, 0x88, 0x90, 0x8b, + 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x93, 0x89, 0x8f, 0x80, 0x94, + 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf7, 0xc0, 0xf8, 0xd4, 0x15, + 0xfb, 0x1f, 0xfb, 0x02, 0xfb, 0x17, 0xfb, 0x39, 0xfb, 0x39, 0xf7, 0x02, + 0xfb, 0x17, 0xf7, 0x1f, 0xf7, 0x1d, 0xf7, 0x04, 0xf7, 0x17, 0xf7, 0x35, + 0xf7, 0x3e, 0xfb, 0x00, 0xf7, 0x16, 0xfb, 0x21, 0x1f, 0x62, 0x04, 0xf7, + 0x08, 0xe7, 0xfb, 0x06, 0xfb, 0x24, 0xfb, 0x1d, 0x2c, 0xfb, 0x07, 0xfb, + 0x05, 0xfb, 0x06, 0x2d, 0xf7, 0x07, 0xf7, 0x20, 0xf7, 0x20, 0xe8, 0xf7, + 0x07, 0xf7, 0x07, 0x1f, 0xf7, 0x21, 0xf7, 0x6e, 0x15, 0x86, 0x8b, 0x87, + 0x89, 0x85, 0x85, 0x6d, 0x6c, 0x80, 0x84, 0x7b, 0x8b, 0x7e, 0x8b, 0x83, + 0x8e, 0x65, 0xa1, 0x6a, 0x9e, 0x7f, 0x8f, 0x77, 0x8b, 0x72, 0x8b, 0x76, + 0x81, 0x6f, 0x70, 0x7d, 0x7e, 0x85, 0x82, 0x8b, 0x83, 0x08, 0x80, 0x94, + 0x83, 0x96, 0x1e, 0x91, 0x8b, 0x92, 0x8e, 0x8f, 0x90, 0xa8, 0xaa, 0x94, + 0x91, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x87, 0xa0, 0x7e, 0xb3, 0x73, 0x9e, + 0x84, 0xa0, 0x8b, 0xa3, 0x8b, 0x9f, 0x95, 0xa5, 0xa5, 0x9d, 0x9c, 0x8f, + 0x91, 0x8b, 0x93, 0x08, 0x96, 0x81, 0x94, 0x80, 0x1e, 0x0e, 0xf8, 0x51, + 0xf8, 0x99, 0x15, 0x61, 0xb4, 0x5e, 0x9d, 0x50, 0x8b, 0x22, 0x8b, 0x3c, + 0x48, 0x8b, 0x33, 0x8b, 0x61, 0x9e, 0x64, 0xac, 0x74, 0xa9, 0x75, 0xaf, + 0x7f, 0xd1, 0x7f, 0xd2, 0x7f, 0xa0, 0x85, 0xa3, 0x7b, 0x08, 0xa7, 0x7a, + 0x9c, 0x6b, 0x8b, 0x68, 0x8b, 0x41, 0x45, 0x55, 0x2e, 0x8b, 0x30, 0x8b, + 0x41, 0xbe, 0x88, 0xcd, 0x8a, 0x9b, 0x85, 0x93, 0x7e, 0x8b, 0x08, 0x7d, + 0x84, 0x82, 0x79, 0x1f, 0xfb, 0x04, 0x07, 0x79, 0x92, 0x82, 0x98, 0x99, + 0x92, 0x94, 0x9d, 0x1e, 0xa8, 0x07, 0xb4, 0x5c, 0xc6, 0x72, 0xd0, 0x8b, + 0xf7, 0x0c, 0x8b, 0xe1, 0xd1, 0x8b, 0xec, 0x8b, 0xbe, 0x74, 0xb6, 0x64, + 0xa3, 0x6d, 0x9e, 0x6f, 0x93, 0x3e, 0x98, 0x4d, 0x95, 0x72, 0x93, 0x71, + 0x9c, 0x08, 0x72, 0x9c, 0x7d, 0xa7, 0x8b, 0xaa, 0x8b, 0xcd, 0xc8, 0xbc, + 0xdd, 0x8b, 0xd9, 0x8b, 0xc8, 0x5e, 0x8f, 0x4f, 0x8c, 0x7b, 0x92, 0x83, + 0x98, 0x8b, 0x08, 0x98, 0x92, 0x94, 0x9d, 0x1f, 0xf2, 0x07, 0x9d, 0x84, + 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x78, 0x07, 0xfb, 0x1b, 0xf7, + 0x0f, 0x15, 0xf7, 0x18, 0xf7, 0x00, 0x05, 0x96, 0x94, 0x8d, 0x8f, 0x8b, + 0x93, 0x8b, 0x95, 0x82, 0x95, 0x80, 0x8b, 0x86, 0x8b, 0x85, 0x88, 0x85, + 0x86, 0x08, 0xfb, 0x00, 0x33, 0xfb, 0x00, 0xe3, 0x05, 0x85, 0x90, 0x85, + 0x8e, 0x86, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x82, 0x8e, + 0x87, 0x95, 0x84, 0x08, 0xf7, 0x18, 0xfb, 0x01, 0x05, 0x0e, 0xf8, 0x87, + 0xf8, 0x9e, 0x15, 0xad, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x83, 0x91, + 0x78, 0x1f, 0xfb, 0x29, 0x06, 0x78, 0x83, 0x85, 0x7d, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xd5, 0xfb, 0xe5, 0x06, 0x31, 0x45, 0x45, 0x33, 0x32, 0x46, + 0xd1, 0xe5, 0x1e, 0xf7, 0xe5, 0xd5, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x29, 0x06, 0x79, 0x82, 0x85, 0x7d, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xad, 0xfb, 0xe5, 0x06, 0xfb, 0x06, 0xe1, 0x34, + 0xf7, 0x05, 0xf7, 0x04, 0xe2, 0xe2, 0xf7, 0x06, 0x1e, 0xf7, 0xe5, 0x07, + 0xfb, 0xca, 0xf7, 0x83, 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, + 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0x1f, 0xa7, 0x75, 0xa2, 0x6f, 0x1e, 0xf7, + 0x72, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, + 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, 0xf8, 0x87, 0xf8, 0x9e, + 0x15, 0xad, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x83, 0x91, 0x78, 0x1f, + 0xfb, 0x29, 0x06, 0x78, 0x83, 0x85, 0x7d, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xd5, 0xfb, 0xe5, 0x06, 0x31, 0x45, 0x45, 0x33, 0x32, 0x46, 0xd1, 0xe5, + 0x1e, 0xf7, 0xe5, 0xd5, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0xfb, 0x29, 0x06, 0x79, 0x82, 0x85, 0x7d, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xad, 0xfb, 0xe5, 0x06, 0xfb, 0x06, 0xe1, 0x34, 0xf7, 0x05, + 0xf7, 0x04, 0xe2, 0xe2, 0xf7, 0x06, 0x1e, 0xf7, 0xe5, 0x07, 0x28, 0xf7, + 0x77, 0x15, 0x96, 0x94, 0x8d, 0x8e, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, + 0x7f, 0x8b, 0x86, 0x8b, 0x86, 0x89, 0x83, 0x84, 0x08, 0xfb, 0x06, 0x27, + 0x05, 0x82, 0x84, 0x88, 0x86, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, + 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x93, 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, + 0x0e, 0xf8, 0x87, 0xf8, 0x9e, 0x15, 0xad, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x99, 0x83, 0x91, 0x78, 0x1f, 0xfb, 0x29, 0x06, 0x78, 0x83, 0x85, 0x7d, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xd5, 0xfb, 0xe5, 0x06, 0x31, 0x45, 0x45, + 0x33, 0x32, 0x46, 0xd1, 0xe5, 0x1e, 0xf7, 0xe5, 0xd5, 0x07, 0x9d, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x29, 0x06, 0x79, 0x82, + 0x85, 0x7d, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xad, 0xfb, 0xe5, 0x06, 0xfb, + 0x06, 0xe1, 0x34, 0xf7, 0x05, 0xf7, 0x04, 0xe2, 0xe2, 0xf7, 0x06, 0x1e, + 0xf7, 0xe5, 0x07, 0xfb, 0xa5, 0xf7, 0x96, 0x15, 0x83, 0x92, 0x87, 0x8d, + 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x85, + 0x94, 0x84, 0x08, 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x91, 0x88, 0x90, + 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x91, 0x8b, 0x8b, 0x7e, + 0x98, 0x08, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x87, 0xf8, 0x9e, 0x15, + 0xad, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x99, 0x83, 0x91, 0x78, 0x1f, 0xfb, + 0x29, 0x06, 0x78, 0x83, 0x85, 0x7d, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xd5, + 0xfb, 0xe5, 0x06, 0x31, 0x45, 0x45, 0x33, 0x32, 0x46, 0xd1, 0xe5, 0x1e, + 0xf7, 0xe5, 0xd5, 0x07, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0xfb, 0x29, 0x06, 0x79, 0x82, 0x85, 0x7d, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xad, 0xfb, 0xe5, 0x06, 0xfb, 0x06, 0xe1, 0x34, 0xf7, 0x05, 0xf7, + 0x04, 0xe2, 0xe2, 0xf7, 0x06, 0x1e, 0xf7, 0xe5, 0x07, 0xfb, 0x5b, 0xf7, + 0x9f, 0x15, 0xfb, 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, 0x88, 0x87, 0x8b, + 0x82, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, 0x8e, 0x91, + 0x90, 0x08, 0xf7, 0x00, 0xe3, 0xf7, 0x00, 0x33, 0x05, 0x91, 0x86, 0x91, + 0x88, 0x90, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x93, 0x89, + 0x8f, 0x80, 0x94, 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf7, 0xd6, + 0xf7, 0x92, 0x15, 0xf7, 0x44, 0xf7, 0xa0, 0xa3, 0x8b, 0x05, 0x9b, 0x96, + 0x93, 0x98, 0x97, 0x81, 0x93, 0x7a, 0x1f, 0xfb, 0x02, 0x06, 0x78, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xb3, 0x8b, 0xfb, 0x29, 0xfb, + 0x77, 0xfb, 0x2c, 0xf7, 0x77, 0xb1, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x03, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xa3, 0x8b, 0xf7, 0x47, 0xfb, 0xa0, 0x8b, + 0xfb, 0x69, 0x22, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xf7, 0x8f, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0x22, 0xf7, 0x69, 0x06, 0xd9, 0xf8, 0x83, 0x15, 0x96, 0x94, + 0x8d, 0x8e, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x7f, 0x8b, 0x86, 0x8b, + 0x86, 0x89, 0x83, 0x84, 0x08, 0xfb, 0x06, 0x27, 0x05, 0x82, 0x84, 0x88, + 0x86, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, + 0x8d, 0x93, 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x85, 0x16, + 0xf7, 0x4a, 0x07, 0x9d, 0x84, 0x94, 0x7d, 0x7d, 0x85, 0x82, 0x79, 0x1e, + 0xfb, 0x21, 0xfb, 0xce, 0x8f, 0x07, 0xf7, 0xdc, 0xf8, 0x60, 0x8b, 0xc5, + 0xfb, 0xf1, 0x8b, 0x8b, 0xfb, 0x33, 0x05, 0x78, 0x92, 0x82, 0x99, 0x98, + 0x92, 0x94, 0x9e, 0x1e, 0xf7, 0x0a, 0xf7, 0xa1, 0x88, 0x07, 0xfb, 0xdc, + 0xfc, 0x60, 0x8b, 0x50, 0xf8, 0x1e, 0x8b, 0x05, 0xfb, 0x5c, 0xf9, 0x14, + 0x15, 0xf7, 0x18, 0xf7, 0x00, 0x05, 0x96, 0x94, 0x8d, 0x8f, 0x8b, 0x93, + 0x8b, 0x95, 0x81, 0x95, 0x81, 0x8b, 0x86, 0x8b, 0x85, 0x88, 0x84, 0x86, + 0x08, 0x20, 0x33, 0xfb, 0x00, 0xe3, 0x05, 0x85, 0x90, 0x85, 0x8e, 0x86, + 0x8b, 0x7f, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x85, 0x92, + 0x86, 0x08, 0x8f, 0x89, 0xf7, 0x18, 0xfb, 0x01, 0x05, 0x0e, 0xf7, 0x39, + 0xf7, 0x17, 0x15, 0xf7, 0x17, 0x06, 0xf7, 0x06, 0xe4, 0xd5, 0xe8, 0xe8, + 0x38, 0xd3, 0x21, 0x1f, 0xfb, 0x25, 0xc6, 0xf7, 0x1e, 0x06, 0x9e, 0x94, + 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x7d, 0x06, 0x79, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, 0x75, 0x55, 0x06, + 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x7d, 0x06, + 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x1e, 0xe5, + 0x06, 0xb4, 0x04, 0xf7, 0x8e, 0xf7, 0x29, 0x07, 0xda, 0xcc, 0x53, 0x47, + 0x46, 0x43, 0x52, 0x34, 0x1f, 0xfb, 0x1a, 0x06, 0x0e, 0xf7, 0xd6, 0xf7, + 0x92, 0x15, 0xf7, 0x44, 0xf7, 0xa0, 0xa3, 0x8b, 0x05, 0x9b, 0x96, 0x93, + 0x98, 0x97, 0x81, 0x93, 0x7a, 0x1f, 0xfb, 0x02, 0x06, 0x78, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xb3, 0x8b, 0xfb, 0x29, 0xfb, 0x77, + 0xfb, 0x2c, 0xf7, 0x77, 0xb1, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x03, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xa3, 0x8b, 0xf7, 0x47, 0xfb, 0xa0, 0x8b, 0xfb, + 0x69, 0x22, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x8f, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0x22, 0xf7, 0x69, 0x06, 0xfb, 0x19, 0xf8, 0x8f, 0x15, 0x70, 0x74, + 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, + 0xa2, 0x6f, 0x1f, 0xf7, 0x72, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, + 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, + 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0x55, 0xf7, 0x9f, 0x06, 0xd2, 0x47, 0xbf, 0x2e, 0x1e, 0x66, + 0x8b, 0x4a, 0x7e, 0x54, 0x78, 0x80, 0x87, 0x85, 0x84, 0x8b, 0x81, 0x8b, + 0x80, 0x94, 0x82, 0x95, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, 0x8f, 0x8c, 0xd9, + 0xa3, 0xa7, 0x91, 0xaf, 0x8b, 0x08, 0xd4, 0xbd, 0x6a, 0x5a, 0x1f, 0x44, + 0x07, 0x52, 0x9b, 0x69, 0x90, 0x5f, 0x8b, 0x08, 0xfb, 0x12, 0x35, 0x50, + 0x34, 0x1f, 0x3f, 0xca, 0x57, 0xe8, 0x1e, 0xd1, 0x8b, 0xc7, 0xa5, 0xc8, + 0xc4, 0x08, 0x48, 0x07, 0xf7, 0x04, 0x04, 0x48, 0x4c, 0x55, 0x73, 0x44, + 0x8b, 0x08, 0x46, 0x5e, 0xad, 0xc0, 0xc9, 0xd4, 0xb6, 0xf5, 0x1f, 0xb5, + 0x8b, 0xbc, 0x85, 0xaf, 0x82, 0x08, 0x31, 0x07, 0xfb, 0x84, 0xf8, 0x87, + 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, + 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0xf7, 0x71, 0x16, 0x70, 0x74, 0x74, + 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, + 0x6f, 0x1f, 0x0e, 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x55, 0xf7, 0x9f, 0x06, 0xd2, 0x47, 0xbf, + 0x2e, 0x1e, 0x66, 0x8b, 0x4a, 0x7e, 0x54, 0x78, 0x80, 0x87, 0x85, 0x84, + 0x8b, 0x81, 0x8b, 0x80, 0x94, 0x82, 0x95, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, + 0x8f, 0x8c, 0xd9, 0xa3, 0xa7, 0x91, 0xaf, 0x8b, 0x08, 0xd4, 0xbd, 0x6a, + 0x5a, 0x1f, 0x44, 0x07, 0x52, 0x9b, 0x69, 0x90, 0x5f, 0x8b, 0x08, 0xfb, + 0x12, 0x35, 0x50, 0x34, 0x1f, 0x3f, 0xca, 0x57, 0xe8, 0x1e, 0xd1, 0x8b, + 0xc7, 0xa5, 0xc8, 0xc4, 0x08, 0x48, 0x07, 0xf7, 0x04, 0x04, 0x48, 0x4c, + 0x55, 0x73, 0x44, 0x8b, 0x08, 0x46, 0x5e, 0xad, 0xc0, 0xc9, 0xd4, 0xb6, + 0xf5, 0x1f, 0xb5, 0x8b, 0xbc, 0x85, 0xaf, 0x82, 0x08, 0x31, 0x07, 0x6b, + 0xf8, 0x7b, 0x15, 0x94, 0x93, 0x8e, 0x8f, 0x8b, 0x92, 0x8b, 0x97, 0x82, + 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x87, 0x89, 0x82, 0x84, 0x08, 0xfb, 0x06, + 0x27, 0x05, 0x81, 0x82, 0x89, 0x88, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, + 0x97, 0x8b, 0x90, 0x8b, 0x90, 0x8d, 0x93, 0x92, 0x08, 0xf7, 0x06, 0xef, + 0x05, 0x0e, 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0x55, 0xf7, 0x9f, 0x06, 0xd2, 0x47, 0xbf, 0x2e, + 0x1e, 0x66, 0x8b, 0x4a, 0x7e, 0x54, 0x78, 0x80, 0x87, 0x85, 0x84, 0x8b, + 0x81, 0x8b, 0x80, 0x94, 0x82, 0x95, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, 0x8f, + 0x8c, 0xd9, 0xa3, 0xa7, 0x91, 0xaf, 0x8b, 0x08, 0xd4, 0xbd, 0x6a, 0x5a, + 0x1f, 0x44, 0x07, 0x52, 0x9b, 0x69, 0x90, 0x5f, 0x8b, 0x08, 0xfb, 0x12, + 0x35, 0x50, 0x34, 0x1f, 0x3f, 0xca, 0x57, 0xe8, 0x1e, 0xd1, 0x8b, 0xc7, + 0xa5, 0xc8, 0xc4, 0x08, 0x48, 0x07, 0xf7, 0x04, 0x04, 0x48, 0x4c, 0x55, + 0x73, 0x44, 0x8b, 0x08, 0x46, 0x5e, 0xad, 0xc0, 0xc9, 0xd4, 0xb6, 0xf5, + 0x1f, 0xb5, 0x8b, 0xbc, 0x85, 0xaf, 0x82, 0x08, 0x31, 0x07, 0xfb, 0x62, + 0xf8, 0x9a, 0x15, 0x83, 0x91, 0x86, 0x8e, 0x85, 0x8b, 0x80, 0x8b, 0x82, + 0x82, 0x8b, 0x80, 0x8b, 0x83, 0x8e, 0x87, 0x94, 0x83, 0x08, 0xf7, 0x06, + 0x27, 0x05, 0x93, 0x85, 0x90, 0x88, 0x90, 0x8b, 0x97, 0x8b, 0x94, 0x94, + 0x8b, 0x97, 0x8b, 0x91, 0x8b, 0x8b, 0x86, 0x90, 0x08, 0x84, 0x93, 0xfb, + 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x55, 0xf7, 0x9f, 0x06, 0xd2, 0x47, + 0xbf, 0x2e, 0x1e, 0x66, 0x8b, 0x4a, 0x7e, 0x54, 0x78, 0x80, 0x87, 0x85, + 0x84, 0x8b, 0x81, 0x8b, 0x80, 0x94, 0x82, 0x95, 0x8b, 0x8d, 0x8b, 0x8f, + 0x8c, 0x8f, 0x8c, 0xd9, 0xa3, 0xa7, 0x91, 0xaf, 0x8b, 0x08, 0xd4, 0xbd, + 0x6a, 0x5a, 0x1f, 0x44, 0x07, 0x50, 0x9b, 0x6c, 0x90, 0x5d, 0x8b, 0x08, + 0xfb, 0x11, 0x35, 0x50, 0x34, 0x1f, 0x3f, 0xca, 0x57, 0xe8, 0x1e, 0xd1, + 0x8b, 0xc7, 0xa5, 0xc8, 0xc4, 0x08, 0x48, 0x07, 0xf7, 0x04, 0x04, 0x48, + 0x4c, 0x55, 0x73, 0x44, 0x8b, 0x08, 0x46, 0x5e, 0xad, 0xbf, 0xca, 0xd3, + 0xb6, 0xf5, 0x1f, 0xb7, 0x8b, 0xbb, 0x85, 0xaf, 0x82, 0x08, 0x31, 0x07, + 0xfb, 0x15, 0xf8, 0xa3, 0x15, 0xfb, 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, + 0x88, 0x86, 0x8b, 0x83, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, + 0x91, 0x8d, 0x91, 0x91, 0x08, 0xf7, 0x00, 0xe3, 0xf6, 0x33, 0x05, 0x92, + 0x86, 0x91, 0x88, 0x90, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, + 0x93, 0x89, 0x8f, 0x80, 0x94, 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, + 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0x55, 0xf7, 0x9f, 0x06, 0xd2, 0x47, 0xbf, 0x2e, 0x1e, 0x66, + 0x8b, 0x4a, 0x7e, 0x54, 0x78, 0x80, 0x87, 0x85, 0x84, 0x8b, 0x81, 0x8b, + 0x80, 0x94, 0x82, 0x95, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, 0x8f, 0x8c, 0xd9, + 0xa3, 0xa7, 0x91, 0xaf, 0x8b, 0x08, 0xd4, 0xbd, 0x6a, 0x5a, 0x1f, 0x44, + 0x07, 0x52, 0x9b, 0x69, 0x90, 0x5f, 0x8b, 0x08, 0xfb, 0x12, 0x35, 0x50, + 0x34, 0x1f, 0x3f, 0xca, 0x57, 0xe8, 0x1e, 0xd1, 0x8b, 0xc7, 0xa5, 0xc8, + 0xc4, 0x08, 0x48, 0x07, 0xf7, 0x04, 0x04, 0x48, 0x4c, 0x55, 0x73, 0x44, + 0x8b, 0x08, 0x46, 0x5e, 0xad, 0xc0, 0xc9, 0xd4, 0xb6, 0xf5, 0x1f, 0xb5, + 0x8b, 0xbc, 0x85, 0xaf, 0x82, 0x08, 0x31, 0x07, 0x91, 0xf8, 0x7f, 0x15, + 0x85, 0x8b, 0x87, 0x89, 0x85, 0x85, 0x6d, 0x6c, 0x81, 0x84, 0x7a, 0x8b, + 0x7e, 0x8b, 0x83, 0x8e, 0x65, 0xa1, 0x6b, 0x9e, 0x7f, 0x8f, 0x77, 0x8b, + 0x72, 0x8b, 0x76, 0x81, 0x6e, 0x70, 0x7e, 0x7e, 0x85, 0x82, 0x8b, 0x83, + 0x08, 0x80, 0x94, 0x83, 0x96, 0x1e, 0x91, 0x8b, 0x92, 0x8e, 0x8f, 0x90, + 0xa8, 0xaa, 0x94, 0x91, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x87, 0x9f, 0x7e, + 0xb4, 0x73, 0x9d, 0x84, 0xa1, 0x8b, 0xa2, 0x8b, 0x9f, 0x95, 0xa5, 0xa5, + 0x9d, 0x9c, 0x8f, 0x91, 0x8b, 0x93, 0x08, 0x96, 0x81, 0x94, 0x81, 0x1e, + 0x0e, 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, + 0x92, 0x79, 0x1f, 0x55, 0xf7, 0x9f, 0x06, 0xd2, 0x47, 0xbf, 0x2e, 0x1e, + 0x66, 0x8b, 0x4a, 0x7e, 0x54, 0x78, 0x80, 0x87, 0x85, 0x84, 0x8b, 0x81, + 0x8b, 0x80, 0x94, 0x82, 0x95, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, 0x8f, 0x8c, + 0xd9, 0xa3, 0xa7, 0x91, 0xaf, 0x8b, 0x08, 0xd4, 0xbd, 0x6a, 0x5a, 0x1f, + 0x44, 0x07, 0x52, 0x9b, 0x69, 0x90, 0x5f, 0x8b, 0x08, 0xfb, 0x12, 0x35, + 0x50, 0x34, 0x1f, 0x3f, 0xca, 0x57, 0xe8, 0x1e, 0xd1, 0x8b, 0xc7, 0xa5, + 0xc8, 0xc4, 0x08, 0x48, 0x07, 0xf7, 0x04, 0x04, 0x48, 0x4c, 0x55, 0x73, + 0x44, 0x8b, 0x08, 0x46, 0x5e, 0xad, 0xc0, 0xc9, 0xd4, 0xb6, 0xf5, 0x1f, + 0xb5, 0x8b, 0xbc, 0x85, 0xaf, 0x82, 0x08, 0x31, 0x07, 0xfb, 0x15, 0xf8, + 0xb9, 0x15, 0x58, 0x61, 0x62, 0x5a, 0x59, 0xb5, 0x62, 0xbe, 0xbe, 0xb5, + 0xb4, 0xbb, 0xbe, 0x62, 0xb4, 0x57, 0x1f, 0x6a, 0x04, 0xac, 0xa6, 0x71, + 0x6b, 0x6c, 0x70, 0x71, 0x6a, 0x6a, 0x70, 0xa5, 0xab, 0xaa, 0xa6, 0xa5, + 0xac, 0x1f, 0x0e, 0xf7, 0xcf, 0x7b, 0x15, 0xc5, 0x8e, 0xb6, 0x95, 0xb6, + 0xa1, 0xb7, 0xa2, 0xab, 0xa8, 0x8b, 0x9c, 0x8b, 0x95, 0x82, 0x94, 0x81, + 0x8b, 0x84, 0x8b, 0x88, 0x89, 0x83, 0x83, 0x57, 0x5b, 0x4d, 0x73, 0x42, + 0x8b, 0x08, 0xfb, 0x01, 0x3e, 0xd6, 0xf4, 0xf7, 0x02, 0xd7, 0xd6, 0xf7, + 0x02, 0x1f, 0xdf, 0x8b, 0xd1, 0x61, 0x90, 0x56, 0x8c, 0x7a, 0x92, 0x84, + 0x98, 0x8b, 0x08, 0x98, 0x92, 0x94, 0x9d, 0x1f, 0xe6, 0x07, 0x9e, 0x84, + 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x78, 0x1e, 0x7e, 0x07, 0x62, 0xaf, 0x56, + 0x9e, 0x4d, 0x8b, 0xfb, 0x1a, 0x8b, 0x2b, 0x2c, 0x8b, 0xfb, 0x18, 0x8b, + 0x42, 0xab, 0x4a, 0xc3, 0x62, 0xa9, 0x75, 0xa5, 0x81, 0xbc, 0x84, 0x08, + 0x48, 0xa0, 0x07, 0xa9, 0x9a, 0x83, 0x7a, 0x7a, 0x79, 0x7f, 0x71, 0x1f, + 0x7c, 0x8b, 0x7e, 0x8f, 0x74, 0x97, 0x83, 0x8f, 0x88, 0x8c, 0x87, 0x8b, + 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x82, 0x8f, 0x86, 0x99, 0x84, + 0x9e, 0x81, 0xaa, 0x83, 0x9f, 0x8b, 0xba, 0x8b, 0xab, 0xa5, 0x8b, 0xb2, + 0x08, 0x8b, 0xb1, 0x73, 0xa1, 0x62, 0x8c, 0x08, 0xaa, 0x07, 0x0e, 0xf8, + 0x9c, 0xf7, 0x5b, 0x15, 0x8b, 0xb9, 0x88, 0x9e, 0x7d, 0xac, 0x67, 0xde, + 0x3b, 0xbe, 0x2b, 0x8b, 0x08, 0xfb, 0x14, 0x27, 0x2e, 0xfb, 0x0d, 0xfb, + 0x16, 0xf6, 0x24, 0xf7, 0x1b, 0xe6, 0xf7, 0x0c, 0xba, 0xae, 0x96, 0x82, + 0x94, 0x81, 0x1f, 0x86, 0x8b, 0x87, 0x89, 0x84, 0x86, 0x63, 0x6b, 0x42, + 0x75, 0x4d, 0x8b, 0xfb, 0x00, 0x8b, 0x3b, 0xd0, 0x7d, 0xf4, 0x08, 0xf8, + 0x34, 0x06, 0xfc, 0x34, 0xb4, 0x15, 0x9d, 0xe7, 0xd3, 0xc5, 0xec, 0x8b, + 0xec, 0x8b, 0xd5, 0x50, 0x9b, 0x30, 0x08, 0xfc, 0x0a, 0x06, 0xe5, 0xf8, + 0x07, 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, + 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0xf7, 0x71, 0x16, 0x70, 0x74, + 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, + 0xa2, 0x6f, 0x1f, 0x0e, 0xf8, 0x9c, 0xf7, 0x5b, 0x15, 0x8b, 0xb9, 0x88, + 0x9e, 0x7d, 0xac, 0x67, 0xde, 0x3b, 0xbe, 0x2b, 0x8b, 0x08, 0xfb, 0x14, + 0x27, 0x2e, 0xfb, 0x0d, 0xfb, 0x16, 0xf6, 0x24, 0xf7, 0x1b, 0xe6, 0xf7, + 0x0c, 0xba, 0xae, 0x96, 0x82, 0x94, 0x81, 0x1f, 0x86, 0x8b, 0x87, 0x89, + 0x84, 0x86, 0x63, 0x6b, 0x42, 0x75, 0x4d, 0x8b, 0xfb, 0x00, 0x8b, 0x3b, + 0xd0, 0x7d, 0xf4, 0x08, 0xf8, 0x34, 0x06, 0xfc, 0x34, 0xb4, 0x15, 0x9d, + 0xe7, 0xd3, 0xc5, 0xec, 0x8b, 0xec, 0x8b, 0xd5, 0x50, 0x9b, 0x30, 0x08, + 0xfc, 0x0a, 0x06, 0xf7, 0xbe, 0xf7, 0xfb, 0x15, 0x94, 0x93, 0x8e, 0x8f, + 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x87, 0x89, + 0x82, 0x84, 0x08, 0xfb, 0x06, 0x27, 0x05, 0x81, 0x82, 0x89, 0x88, 0x8b, + 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x94, + 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x9c, 0xf7, 0x5b, 0x15, + 0x8b, 0xb9, 0x88, 0x9e, 0x7d, 0xac, 0x67, 0xde, 0x3b, 0xbe, 0x2b, 0x8b, + 0x08, 0xfb, 0x14, 0x27, 0x2e, 0xfb, 0x0d, 0xfb, 0x16, 0xf6, 0x24, 0xf7, + 0x1b, 0xe6, 0xf7, 0x0c, 0xba, 0xae, 0x96, 0x82, 0x94, 0x81, 0x1f, 0x86, + 0x8b, 0x87, 0x89, 0x84, 0x86, 0x63, 0x6b, 0x42, 0x75, 0x4d, 0x8b, 0xfb, + 0x00, 0x8b, 0x3b, 0xd0, 0x7d, 0xf4, 0x08, 0xf8, 0x34, 0x06, 0xfc, 0x34, + 0xb4, 0x15, 0x9d, 0xe7, 0xd3, 0xc5, 0xec, 0x8b, 0xec, 0x8b, 0xd5, 0x50, + 0x9b, 0x30, 0x08, 0xfc, 0x0a, 0x06, 0xf7, 0x10, 0xf8, 0x1a, 0x15, 0x83, + 0x91, 0x86, 0x8e, 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, + 0x83, 0x8e, 0x87, 0x94, 0x83, 0x08, 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, + 0x91, 0x88, 0x90, 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x91, + 0x8b, 0x8b, 0x86, 0x90, 0x08, 0x84, 0x93, 0xfb, 0x06, 0xef, 0x05, 0x0e, + 0xf8, 0x9c, 0xf7, 0x5b, 0x15, 0x8b, 0xb9, 0x88, 0x9e, 0x7d, 0xac, 0x67, + 0xde, 0x3b, 0xbe, 0x2b, 0x8b, 0x08, 0xfb, 0x14, 0x27, 0x2e, 0xfb, 0x0d, + 0xfb, 0x16, 0xf6, 0x24, 0xf7, 0x1b, 0xe6, 0xf7, 0x0c, 0xba, 0xae, 0x96, + 0x82, 0x94, 0x81, 0x1f, 0x86, 0x8b, 0x87, 0x89, 0x84, 0x86, 0x63, 0x6b, + 0x42, 0x75, 0x4d, 0x8b, 0xfb, 0x00, 0x8b, 0x3b, 0xd0, 0x7d, 0xf4, 0x08, + 0xf8, 0x34, 0x06, 0xfc, 0x34, 0xb4, 0x15, 0x9d, 0xe7, 0xd3, 0xc5, 0xec, + 0x8b, 0xec, 0x8b, 0xd5, 0x50, 0x9b, 0x30, 0x08, 0xfc, 0x0a, 0x06, 0xf7, + 0x5d, 0xf8, 0x23, 0x15, 0xfb, 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, 0x88, + 0x86, 0x8b, 0x83, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, + 0x8d, 0x91, 0x91, 0x08, 0xf7, 0x00, 0xe3, 0xf6, 0x33, 0x05, 0x92, 0x86, + 0x91, 0x88, 0x90, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x93, + 0x89, 0x8f, 0x80, 0x94, 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf7, + 0xd4, 0xf8, 0x35, 0x15, 0xfb, 0x33, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x0a, 0xfb, 0xe3, 0xfb, 0x34, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xfd, 0x06, 0x9d, + 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x34, 0xf8, 0x0c, + 0x06, 0xfb, 0x24, 0xf7, 0x56, 0x15, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, + 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0xf7, + 0x72, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, + 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, 0xf7, 0xd4, 0xf8, 0x35, + 0x15, 0xfb, 0x33, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf7, 0x0a, 0xfb, 0xe3, 0xfb, 0x34, 0x06, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xfd, 0x06, 0x9d, 0x95, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x34, 0xf8, 0x0c, 0x06, 0xd1, 0xf7, + 0x4a, 0x15, 0x96, 0x94, 0x8d, 0x8e, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, + 0x7f, 0x8b, 0x86, 0x8b, 0x86, 0x89, 0x83, 0x84, 0x08, 0xfb, 0x06, 0x27, + 0x05, 0x82, 0x84, 0x88, 0x86, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, + 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x93, 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, + 0x0e, 0xf7, 0xd4, 0xf8, 0x35, 0x15, 0xfb, 0x33, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x0a, 0xfb, 0xe3, 0xfb, 0x34, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0xfd, + 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, 0x92, 0x78, 0x1f, 0xfb, 0x34, + 0xf8, 0x0c, 0x06, 0x23, 0xf7, 0x69, 0x15, 0x83, 0x92, 0x87, 0x8d, 0x85, + 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x85, 0x94, + 0x84, 0x08, 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x91, 0x88, 0x90, 0x8b, + 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x91, 0x8b, 0x8b, 0x7e, 0x98, + 0x08, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf7, 0xd4, 0xf8, 0x35, 0x15, 0xfb, + 0x33, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x0a, 0xfb, 0xe3, 0xfb, 0x34, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xf7, 0xfd, 0x06, 0x9d, 0x95, 0x92, 0x99, 0x98, 0x82, + 0x92, 0x78, 0x1f, 0xfb, 0x34, 0xf8, 0x0c, 0x06, 0x66, 0xf7, 0x72, 0x15, + 0xfb, 0x17, 0xfb, 0x01, 0x87, 0x89, 0x05, 0x84, 0x86, 0x88, 0x85, 0x8b, + 0x84, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, 0x8e, 0x92, + 0x90, 0x08, 0xf6, 0xe3, 0xf7, 0x00, 0x33, 0x05, 0x91, 0x86, 0x92, 0x88, + 0x8f, 0x8b, 0x96, 0x8b, 0x95, 0x94, 0x8b, 0x96, 0x8b, 0x92, 0x88, 0x91, + 0x84, 0x90, 0x08, 0x87, 0x8e, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf7, + 0x3b, 0xf8, 0x35, 0x15, 0x40, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, + 0x84, 0x9d, 0x1f, 0xad, 0xfb, 0xe3, 0x5e, 0x06, 0x78, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xf7, 0x17, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x5e, 0xf7, 0x91, 0x06, 0xca, 0xda, 0xa6, + 0x9c, 0xca, 0x8b, 0xb0, 0x8b, 0x9f, 0x85, 0xa3, 0x77, 0xa4, 0x76, 0x98, + 0x72, 0x8b, 0x6d, 0x08, 0xfb, 0x8b, 0x69, 0x07, 0x79, 0x82, 0x84, 0x7e, + 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x01, 0x06, 0x9d, 0x94, 0x92, 0x99, + 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf7, 0x92, 0x06, 0xd8, 0x47, 0xc6, + 0x32, 0x1e, 0x4d, 0x8b, 0x67, 0x78, 0x51, 0x4b, 0x08, 0xd0, 0x07, 0xf7, + 0x96, 0xf7, 0x4e, 0x15, 0x85, 0x8b, 0x87, 0x89, 0x85, 0x85, 0x6d, 0x6c, + 0x81, 0x84, 0x7a, 0x8b, 0x7e, 0x8b, 0x83, 0x8f, 0x65, 0xa0, 0x6b, 0x9e, + 0x7f, 0x8f, 0x77, 0x8b, 0x72, 0x8b, 0x76, 0x81, 0x6e, 0x70, 0x7e, 0x7e, + 0x85, 0x82, 0x8b, 0x83, 0x08, 0x80, 0x94, 0x83, 0x96, 0x1e, 0x91, 0x8b, + 0x92, 0x8e, 0x8f, 0x90, 0xa8, 0xaa, 0x94, 0x91, 0x9f, 0x8b, 0x97, 0x8b, + 0x96, 0x87, 0x9f, 0x7e, 0xb3, 0x73, 0x9e, 0x84, 0xa1, 0x8b, 0xa2, 0x8b, + 0x9f, 0x95, 0xa5, 0xa5, 0x9d, 0x9c, 0x8f, 0x91, 0x8b, 0x93, 0x08, 0x96, + 0x81, 0x94, 0x81, 0x1e, 0x0e, 0xf7, 0xc0, 0xf8, 0x43, 0x15, 0xfb, 0x13, + 0x26, 0x27, 0xfb, 0x0f, 0xfb, 0x11, 0xf0, 0x28, 0xf7, 0x13, 0xf7, 0x12, + 0xf1, 0xee, 0xf7, 0x0e, 0xf7, 0x13, 0x27, 0xee, 0xfb, 0x14, 0x1f, 0x62, + 0x04, 0xf4, 0xdd, 0x3b, 0x22, 0x28, 0x37, 0x3a, 0x24, 0x23, 0x38, 0xdc, + 0xf1, 0xf0, 0xde, 0xdc, 0xf3, 0x1f, 0xfb, 0x03, 0xf7, 0x71, 0x15, 0x70, + 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, + 0x75, 0xa2, 0x6f, 0x1f, 0xf7, 0x71, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, + 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, + 0x0e, 0xf7, 0xc0, 0xf8, 0x43, 0x15, 0xfb, 0x13, 0x26, 0x27, 0xfb, 0x0f, + 0xfb, 0x11, 0xf0, 0x28, 0xf7, 0x13, 0xf7, 0x12, 0xf1, 0xee, 0xf7, 0x0e, + 0xf7, 0x13, 0x27, 0xee, 0xfb, 0x14, 0x1f, 0x62, 0x04, 0xf4, 0xdd, 0x3b, + 0x22, 0x28, 0x37, 0x3a, 0x24, 0x23, 0x38, 0xdc, 0xf1, 0xf0, 0xde, 0xdc, + 0xf3, 0x1f, 0xec, 0xf7, 0x65, 0x15, 0x96, 0x94, 0x8d, 0x8e, 0x8b, 0x92, + 0x8b, 0x97, 0x82, 0x94, 0x7f, 0x8b, 0x85, 0x8b, 0x86, 0x88, 0x83, 0x85, + 0x08, 0xfb, 0x06, 0x27, 0x05, 0x83, 0x84, 0x88, 0x85, 0x8b, 0x85, 0x8b, + 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8e, 0x8d, 0x94, 0x92, 0x08, + 0xf7, 0x06, 0xef, 0x05, 0x0e, 0xf7, 0xc0, 0xf8, 0x43, 0x15, 0xfb, 0x13, + 0x26, 0x27, 0xfb, 0x0f, 0xfb, 0x11, 0xf0, 0x28, 0xf7, 0x13, 0xf7, 0x12, + 0xf1, 0xee, 0xf7, 0x0e, 0xf7, 0x13, 0x27, 0xee, 0xfb, 0x14, 0x1f, 0x62, + 0x04, 0xf4, 0xdd, 0x3b, 0x22, 0x28, 0x37, 0x3a, 0x24, 0x23, 0x38, 0xdc, + 0xf1, 0xf0, 0xde, 0xdc, 0xf3, 0x1f, 0x45, 0xf7, 0x84, 0x15, 0x83, 0x92, + 0x86, 0x8d, 0x85, 0x8b, 0x80, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, + 0x8e, 0x86, 0x94, 0x83, 0x08, 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x91, + 0x88, 0x90, 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x90, 0x8a, + 0x8d, 0x87, 0x8f, 0x08, 0x84, 0x93, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf7, + 0xc0, 0xf8, 0x43, 0x15, 0xfb, 0x13, 0x26, 0x27, 0xfb, 0x0f, 0xfb, 0x11, + 0xf0, 0x28, 0xf7, 0x13, 0xf7, 0x12, 0xf1, 0xee, 0xf7, 0x0e, 0xf7, 0x13, + 0x27, 0xee, 0xfb, 0x14, 0x1f, 0x62, 0x04, 0xf4, 0xdd, 0x3b, 0x22, 0x28, + 0x37, 0x3a, 0x24, 0x23, 0x38, 0xdc, 0xf1, 0xf0, 0xde, 0xdc, 0xf3, 0x1f, + 0xf7, 0x8d, 0x04, 0xfb, 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, 0x88, 0x87, + 0x8b, 0x82, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, 0x8e, + 0x91, 0x90, 0x08, 0xf7, 0x00, 0xe3, 0xf7, 0x00, 0x33, 0x05, 0x91, 0x86, + 0x91, 0x88, 0x90, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x93, + 0x89, 0x8f, 0x80, 0x94, 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf7, + 0xc0, 0xf8, 0x43, 0x15, 0xfb, 0x13, 0x26, 0x27, 0xfb, 0x0f, 0xfb, 0x11, + 0xf0, 0x28, 0xf7, 0x13, 0xf7, 0x12, 0xf1, 0xee, 0xf7, 0x0e, 0xf7, 0x13, + 0x27, 0xee, 0xfb, 0x14, 0x1f, 0x62, 0x04, 0xf4, 0xdd, 0x3b, 0x22, 0x28, + 0x37, 0x3a, 0x24, 0x23, 0x38, 0xdc, 0xf1, 0xf0, 0xde, 0xdc, 0xf3, 0x1f, + 0xf7, 0x21, 0xf7, 0x69, 0x15, 0x86, 0x8b, 0x87, 0x89, 0x85, 0x85, 0x6d, + 0x6c, 0x80, 0x84, 0x7b, 0x8b, 0x7e, 0x8b, 0x83, 0x8e, 0x65, 0xa1, 0x6a, + 0x9e, 0x7f, 0x8f, 0x77, 0x8b, 0x72, 0x8b, 0x76, 0x81, 0x6f, 0x70, 0x7d, + 0x7e, 0x85, 0x82, 0x8b, 0x83, 0x08, 0x80, 0x94, 0x83, 0x96, 0x1e, 0x91, + 0x8b, 0x92, 0x8e, 0x8f, 0x90, 0xa8, 0xaa, 0x94, 0x91, 0x9f, 0x8b, 0x97, + 0x8b, 0x96, 0x87, 0xa0, 0x7e, 0xb3, 0x73, 0x9e, 0x84, 0xa0, 0x8b, 0xa3, + 0x8b, 0x9f, 0x95, 0xa5, 0xa5, 0x9d, 0x9c, 0x8f, 0x91, 0x8b, 0x93, 0x08, + 0x96, 0x81, 0x94, 0x80, 0x1e, 0x0e, 0xf8, 0x44, 0xf8, 0x15, 0x15, 0x68, + 0xaa, 0x5e, 0x9a, 0x52, 0x8b, 0x29, 0x8b, 0x42, 0x5b, 0x8b, 0x4a, 0x8b, + 0x6c, 0x9d, 0x6d, 0xa7, 0x79, 0xa7, 0x7a, 0xa7, 0x84, 0xd5, 0x83, 0xc2, + 0x85, 0xa6, 0x84, 0xa5, 0x7d, 0x08, 0xa6, 0x7c, 0x9c, 0x72, 0x8b, 0x74, + 0x08, 0x56, 0x49, 0x64, 0x33, 0x36, 0x46, 0xb0, 0xb9, 0x1e, 0x92, 0x07, + 0x98, 0x83, 0x94, 0x7f, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x38, 0x07, 0x79, + 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, 0x1e, 0x96, 0x07, 0xb5, 0x66, + 0xbd, 0x7a, 0xcc, 0x8b, 0xf7, 0x05, 0x8b, 0xde, 0xc3, 0x8b, 0xd7, 0x8b, + 0xae, 0x78, 0xad, 0x6c, 0xa0, 0x6b, 0xa0, 0x66, 0x96, 0x4e, 0x92, 0x33, + 0x94, 0x85, 0x8d, 0x75, 0x99, 0x08, 0x76, 0x97, 0x80, 0x9c, 0x8b, 0x9b, + 0x8b, 0xb6, 0xc3, 0xab, 0xd5, 0x8b, 0xd7, 0x8b, 0xbf, 0x6e, 0x90, 0x5e, + 0x8d, 0x7b, 0x92, 0x84, 0x97, 0x8b, 0x08, 0x98, 0x92, 0x94, 0x9d, 0x1f, + 0xd0, 0x07, 0x9e, 0x84, 0x94, 0x7e, 0x7e, 0x83, 0x80, 0x7a, 0x1e, 0x87, + 0x07, 0xfb, 0x11, 0xf4, 0x15, 0xf7, 0x17, 0xf7, 0x00, 0x05, 0x97, 0x94, + 0x8d, 0x8f, 0x8b, 0x93, 0x8b, 0x95, 0x81, 0x95, 0x81, 0x8b, 0x86, 0x8b, + 0x85, 0x88, 0x84, 0x86, 0x08, 0x20, 0x33, 0xfb, 0x00, 0xe3, 0x05, 0x85, + 0x90, 0x85, 0x8e, 0x86, 0x8b, 0x7f, 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, + 0x84, 0x8e, 0x85, 0x92, 0x86, 0x08, 0x8f, 0x89, 0xf7, 0x18, 0xfb, 0x01, + 0x05, 0x0e, 0xf8, 0x4b, 0x16, 0xd6, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf8, 0x0c, 0xfb, 0x07, 0x06, 0x78, 0x82, + 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xd5, 0xfb, 0x99, 0x06, 0x54, + 0x4f, 0x4e, 0x6d, 0x48, 0x8b, 0x08, 0x58, 0x63, 0xb3, 0xbd, 0x1f, 0xf7, + 0xc2, 0x2c, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xc1, 0xfb, 0x99, 0x06, 0x3c, 0xc0, 0x57, 0xdb, 0x1e, 0xcd, 0x8b, 0xc8, + 0xa7, 0xc2, 0xc1, 0x08, 0x49, 0x07, 0xfb, 0x96, 0xf8, 0xf7, 0x15, 0x70, + 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, + 0x75, 0xa2, 0x6f, 0x1f, 0xf7, 0x71, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, + 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, + 0x0e, 0xf8, 0x4b, 0x16, 0xd6, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, + 0x92, 0x79, 0x1f, 0x69, 0xf8, 0x0c, 0xfb, 0x07, 0x06, 0x78, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xd5, 0xfb, 0x99, 0x06, 0x54, 0x4f, + 0x4e, 0x6d, 0x48, 0x8b, 0x08, 0x58, 0x63, 0xb3, 0xbd, 0x1f, 0xf7, 0xc2, + 0x2c, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, + 0xfb, 0x99, 0x06, 0x3c, 0xc0, 0x57, 0xdb, 0x1e, 0xcd, 0x8b, 0xc8, 0xa7, + 0xc2, 0xc1, 0x08, 0x49, 0x07, 0x52, 0xf8, 0xeb, 0x15, 0x96, 0x94, 0x8d, + 0x8e, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x7f, 0x8b, 0x86, 0x8b, 0x86, + 0x89, 0x83, 0x84, 0x08, 0xfb, 0x06, 0x27, 0x05, 0x82, 0x84, 0x88, 0x86, + 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, + 0x93, 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x4b, 0x16, 0xd6, + 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf8, + 0x0c, 0xfb, 0x07, 0x06, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, + 0x1f, 0xd5, 0xfb, 0x99, 0x06, 0x54, 0x4f, 0x4e, 0x6d, 0x48, 0x8b, 0x08, + 0x58, 0x63, 0xb3, 0xbd, 0x1f, 0xf7, 0xc2, 0x2c, 0x07, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfb, 0x99, 0x06, 0x3c, 0xc0, + 0x57, 0xdb, 0x1e, 0xcd, 0x8b, 0xc8, 0xa7, 0xc2, 0xc1, 0x08, 0x49, 0x07, + 0xfb, 0x6d, 0xf9, 0x0a, 0x15, 0x83, 0x92, 0x86, 0x8d, 0x85, 0x8b, 0x80, + 0x8b, 0x82, 0x82, 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x86, 0x94, 0x83, 0x08, + 0xf7, 0x06, 0x27, 0x05, 0x92, 0x85, 0x91, 0x88, 0x90, 0x8b, 0x97, 0x8b, + 0x94, 0x94, 0x8b, 0x97, 0x8b, 0x90, 0x8a, 0x8d, 0x87, 0x8f, 0x08, 0x84, + 0x93, 0xfb, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x4b, 0x16, 0xd6, 0x06, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x69, 0xf8, 0x0c, 0xfb, + 0x07, 0x06, 0x78, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9e, 0x1f, 0xd5, + 0xfb, 0x99, 0x06, 0x54, 0x4f, 0x4e, 0x6d, 0x48, 0x8b, 0x08, 0x58, 0x63, + 0xb3, 0xbd, 0x1f, 0xf7, 0xc2, 0x2c, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfb, 0x99, 0x06, 0x3c, 0xc0, 0x57, 0xdb, + 0x1e, 0xcd, 0x8b, 0xc8, 0xa7, 0xc2, 0xc1, 0x08, 0x49, 0x07, 0xfb, 0x27, + 0xf9, 0x13, 0x15, 0xfb, 0x18, 0xfb, 0x01, 0x05, 0x81, 0x84, 0x88, 0x87, + 0x8b, 0x82, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x90, 0x8b, 0x91, 0x8e, + 0x91, 0x90, 0x08, 0xf7, 0x00, 0xe3, 0xf7, 0x00, 0x33, 0x05, 0x91, 0x86, + 0x91, 0x88, 0x90, 0x8b, 0x96, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, 0x93, + 0x89, 0x8f, 0x80, 0x94, 0x08, 0xfb, 0x18, 0xf7, 0x00, 0x05, 0x0e, 0xf7, + 0xae, 0x16, 0x44, 0xfb, 0x25, 0xfb, 0x13, 0x8b, 0x05, 0x79, 0x82, 0x84, + 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x7d, 0x06, 0x9d, 0x94, 0x92, + 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0x4a, 0x8b, 0xf7, 0x94, 0xf8, 0x9d, + 0x99, 0x8b, 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0xfb, 0x02, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xc1, 0x8b, 0xfb, 0x35, 0xfb, 0xdf, 0xfb, 0x38, 0xf7, 0xdf, 0xbf, 0x8b, + 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x07, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0x9b, 0x8b, + 0x05, 0xf7, 0x50, 0xfc, 0x0c, 0x05, 0xf7, 0x2b, 0xf8, 0xeb, 0x15, 0x94, + 0x93, 0x8e, 0x8f, 0x8b, 0x92, 0x8b, 0x97, 0x82, 0x94, 0x80, 0x8b, 0x85, + 0x8b, 0x87, 0x89, 0x82, 0x84, 0x08, 0xfb, 0x06, 0x27, 0x05, 0x81, 0x82, + 0x89, 0x88, 0x8b, 0x84, 0x8b, 0x7f, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, + 0x8f, 0x8d, 0x94, 0x92, 0x08, 0xf7, 0x06, 0xef, 0x05, 0x0e, 0xf8, 0x6e, + 0xf8, 0x35, 0x15, 0xfb, 0xf2, 0x2b, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, + 0x92, 0x94, 0x9d, 0x1e, 0xc2, 0xf7, 0x8f, 0x07, 0xfb, 0xc1, 0xfb, 0xe8, + 0x8b, 0x67, 0xf8, 0x0a, 0x8b, 0x8b, 0xec, 0x05, 0x9d, 0x84, 0x94, 0x7e, + 0x7d, 0x84, 0x82, 0x79, 0x1e, 0x53, 0xfb, 0xa9, 0x07, 0xf7, 0xc3, 0xf7, + 0xe8, 0x8b, 0xaf, 0x05, 0xfb, 0x43, 0xd4, 0x15, 0xf7, 0x18, 0xf7, 0x00, + 0x05, 0x96, 0x94, 0x8d, 0x8f, 0x8b, 0x93, 0x8b, 0x95, 0x81, 0x95, 0x81, + 0x8b, 0x86, 0x8b, 0x85, 0x88, 0x84, 0x86, 0x08, 0x20, 0x33, 0xfb, 0x00, + 0xe3, 0x05, 0x85, 0x90, 0x85, 0x8e, 0x86, 0x8b, 0x7f, 0x8b, 0x82, 0x82, + 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x85, 0x92, 0x86, 0x08, 0x8f, 0x89, 0xf7, + 0x18, 0xfb, 0x01, 0x05, 0x0e, 0xf8, 0x4c, 0xf8, 0xd5, 0x15, 0x90, 0x8d, + 0x8f, 0x92, 0x8b, 0x93, 0x08, 0x97, 0x82, 0x94, 0x81, 0x1e, 0x84, 0x8a, + 0x2c, 0x61, 0x05, 0x50, 0xa7, 0x4d, 0x9f, 0x70, 0x8b, 0x7f, 0x8b, 0x82, + 0x82, 0x8b, 0x7e, 0x8b, 0x81, 0x91, 0x86, 0x99, 0x88, 0xb3, 0x83, 0x9f, + 0x84, 0xb1, 0x7b, 0x08, 0x4c, 0x6f, 0x05, 0x85, 0x89, 0x88, 0x84, 0x8b, + 0x84, 0x8b, 0x7f, 0x95, 0x80, 0x95, 0x8b, 0x8e, 0x8b, 0x8d, 0x8b, 0x8d, + 0x8c, 0x08, 0xe6, 0xb5, 0x05, 0xb5, 0x6d, 0xb8, 0x55, 0xad, 0x4b, 0x55, + 0xb2, 0x66, 0x99, 0x54, 0x8b, 0x08, 0xfb, 0x11, 0x26, 0x27, 0xfb, 0x0f, + 0xfb, 0x11, 0xf0, 0x28, 0xf7, 0x13, 0x1f, 0xc9, 0x8b, 0xc4, 0xa2, 0xb6, + 0xb5, 0xb8, 0xb8, 0xa0, 0xc2, 0x8b, 0xd4, 0x8b, 0xf7, 0x02, 0x4c, 0xf7, + 0x12, 0x27, 0xe1, 0x08, 0xd6, 0xad, 0x05, 0xfb, 0x1f, 0xfb, 0x4f, 0x15, + 0xf4, 0xdd, 0x3b, 0x22, 0x28, 0x37, 0x3a, 0x24, 0x23, 0x38, 0xdc, 0xf1, + 0xf0, 0xde, 0xdc, 0xf3, 0x1f, 0x0e, 0xf7, 0x24, 0xf8, 0xe2, 0x15, 0x2c, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfd, + 0x4a, 0x55, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, + 0xf7, 0x55, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, + 0x29, 0xf7, 0x8f, 0x06, 0xb9, 0x49, 0xc3, 0x6d, 0xd8, 0x8b, 0x08, 0xf7, + 0x0f, 0xea, 0xe7, 0xf7, 0x0b, 0xf7, 0x0b, 0x2d, 0xe6, 0xfb, 0x10, 0x1f, + 0x3f, 0x8b, 0x59, 0x70, 0x56, 0x46, 0x08, 0xf7, 0x93, 0x07, 0xf7, 0x46, + 0xfb, 0x5c, 0x15, 0xf0, 0xd8, 0x41, 0x2a, 0x2e, 0x3b, 0x40, 0x29, 0x28, + 0x3c, 0xd6, 0xea, 0xe9, 0xda, 0xd6, 0xee, 0x1f, 0x0e, 0xf7, 0xae, 0x16, + 0x44, 0xfb, 0x25, 0xfb, 0x13, 0x8b, 0x05, 0x79, 0x82, 0x84, 0x7e, 0x7d, + 0x94, 0x84, 0x9d, 0x1f, 0xf7, 0x7d, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, + 0x82, 0x92, 0x79, 0x1f, 0x4a, 0x8b, 0xf7, 0x94, 0xf8, 0x9d, 0x99, 0x8b, + 0x05, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x02, + 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0x8b, + 0xfb, 0x35, 0xfb, 0xdf, 0xfb, 0x38, 0xf7, 0xdf, 0xbf, 0x8b, 0x05, 0x9d, + 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfb, 0x07, 0x06, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0x9b, 0x8b, 0x05, 0xf7, + 0x50, 0xfc, 0x0c, 0x05, 0x2e, 0xf8, 0xf7, 0x15, 0x70, 0x74, 0x74, 0x70, + 0x70, 0xa2, 0x74, 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0x1f, 0xa7, 0x75, 0xa2, + 0x6f, 0x1e, 0xf7, 0x71, 0x16, 0x70, 0x74, 0x74, 0x70, 0x70, 0xa2, 0x74, + 0xa6, 0xa6, 0xa2, 0xa2, 0xa5, 0xa7, 0x75, 0xa2, 0x6f, 0x1f, 0x0e, 0xf5, + 0xf7, 0xf3, 0x15, 0x9d, 0xf7, 0x01, 0xdc, 0xd6, 0xef, 0x8b, 0xe4, 0x8b, + 0xdb, 0x56, 0x8f, 0x4e, 0x8c, 0x7b, 0x92, 0x83, 0x97, 0x8b, 0x08, 0x99, + 0x92, 0x94, 0x9d, 0x1f, 0xf7, 0x04, 0x07, 0x9d, 0x84, 0x94, 0x7e, 0x7d, + 0x84, 0x82, 0x79, 0x1e, 0x6e, 0x07, 0x5d, 0xb8, 0x4e, 0xa3, 0x49, 0x8b, + 0xfb, 0x0f, 0x8b, 0x25, 0x2b, 0x7c, 0xfb, 0x15, 0x08, 0x6b, 0x06, 0x7a, + 0x86, 0x86, 0x7e, 0x7d, 0x91, 0x86, 0x9b, 0x1f, 0xa9, 0x4f, 0x6d, 0x06, + 0x7b, 0x85, 0x86, 0x7e, 0x7d, 0x91, 0x86, 0x9b, 0x1f, 0xab, 0x06, 0x9a, + 0xfb, 0x14, 0xf7, 0x08, 0x22, 0xf7, 0x12, 0x8b, 0xcb, 0x8b, 0xc7, 0xa4, + 0xbd, 0xb9, 0xa5, 0xa3, 0x97, 0x9c, 0x8b, 0x95, 0x8b, 0x96, 0x83, 0x93, + 0x7f, 0x8b, 0x84, 0x8b, 0x87, 0x89, 0x84, 0x83, 0x55, 0x4b, 0x58, 0x71, + 0x46, 0x8b, 0x08, 0x21, 0x8b, 0x2f, 0xdd, 0x79, 0xf7, 0x02, 0x08, 0xf7, + 0x97, 0x06, 0x9a, 0x91, 0x90, 0x99, 0x98, 0x86, 0x90, 0x7b, 0x1f, 0xfb, + 0x99, 0xc7, 0xf7, 0xb6, 0x06, 0x9b, 0x90, 0x90, 0x99, 0x98, 0x86, 0x90, + 0x7b, 0x1f, 0xfb, 0xb4, 0x06, 0x0e, 0xf7, 0xd3, 0xf8, 0xf8, 0x15, 0xfb, + 0x13, 0x64, 0x8b, 0x8b, 0x8b, 0x7c, 0x8b, 0x82, 0x94, 0x82, 0x93, 0x8b, + 0x8d, 0x8b, 0x8e, 0x8c, 0x8f, 0x8c, 0x08, 0xcc, 0xa0, 0x8b, 0xfb, 0xa0, + 0x05, 0x75, 0x8c, 0x6c, 0x8b, 0x83, 0x8b, 0x08, 0x76, 0x81, 0x85, 0x7e, + 0x80, 0x93, 0x84, 0x98, 0x1f, 0xf7, 0x46, 0x06, 0x97, 0x93, 0x92, 0x96, + 0x96, 0x83, 0x92, 0x7f, 0x1f, 0x44, 0xf7, 0xd1, 0x06, 0x0e, 0xf7, 0x6f, + 0xf7, 0xbb, 0x15, 0xf7, 0x3b, 0xf7, 0x2d, 0x9c, 0x9f, 0x8b, 0xb6, 0x8b, + 0xc1, 0x59, 0xba, 0x51, 0x8b, 0x68, 0x8b, 0x6a, 0x7b, 0x75, 0x6f, 0x80, + 0x7d, 0x83, 0x79, 0x8b, 0x80, 0x8b, 0x82, 0x93, 0x83, 0x94, 0x8b, 0x94, + 0x8b, 0x91, 0x90, 0x8e, 0x96, 0x08, 0x94, 0xaa, 0xaa, 0xa0, 0xad, 0x8b, + 0xb1, 0x8b, 0xad, 0x6d, 0x8b, 0x68, 0x8b, 0x75, 0x81, 0x7d, 0x59, 0x59, + 0x08, 0xfb, 0x18, 0xfb, 0x0f, 0x8b, 0x60, 0xf7, 0x7a, 0x8b, 0x8b, 0xb2, + 0x05, 0x97, 0x84, 0x93, 0x80, 0x80, 0x84, 0x83, 0x7f, 0x1e, 0x88, 0x07, + 0xfb, 0x2a, 0x06, 0x0e, 0xf7, 0xfa, 0xf8, 0x52, 0x15, 0xac, 0xa1, 0x98, + 0xa1, 0x8b, 0xa9, 0x08, 0xbf, 0x5e, 0xb3, 0x50, 0x5d, 0x52, 0x6c, 0x72, + 0x82, 0x93, 0x83, 0x95, 0x1e, 0x91, 0x8b, 0x8f, 0x8d, 0x91, 0x93, 0x9a, + 0x9c, 0xa4, 0x95, 0xa8, 0x8b, 0x08, 0xb2, 0xa8, 0x73, 0x6b, 0x6d, 0x70, + 0x74, 0x66, 0x1f, 0x72, 0x8b, 0x8b, 0x8b, 0x88, 0x89, 0x85, 0x87, 0x88, + 0x85, 0x8b, 0x85, 0x8b, 0x80, 0x93, 0x85, 0x98, 0x8a, 0x08, 0xc0, 0x8a, + 0xb2, 0x6b, 0x8b, 0x63, 0x8b, 0x65, 0x64, 0x6a, 0x5d, 0x8b, 0x6d, 0x8b, + 0x73, 0x93, 0x6d, 0xa0, 0x86, 0x8f, 0x88, 0x8c, 0x86, 0x8b, 0x08, 0x82, + 0x83, 0x83, 0x82, 0x74, 0xcb, 0x6d, 0xbd, 0xcd, 0xc2, 0xbb, 0xc6, 0x1f, + 0x8b, 0xaf, 0x78, 0xa7, 0x64, 0xa3, 0x08, 0x0e, 0xf7, 0xbb, 0xf7, 0xf0, + 0x15, 0x64, 0x6d, 0x6f, 0x66, 0x66, 0xa9, 0x6e, 0xb2, 0x1f, 0x95, 0x06, + 0xb2, 0xa9, 0xa7, 0xb1, 0xb0, 0x6d, 0xa7, 0x64, 0x1f, 0x81, 0x06, 0x0e, + 0xf8, 0x89, 0xf7, 0x96, 0x15, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, + 0x79, 0x1f, 0xfc, 0x26, 0x06, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, + 0x9d, 0x1f, 0xf8, 0x26, 0x06, 0x0e, 0xf7, 0xc0, 0xf9, 0x10, 0x15, 0x3c, + 0x49, 0x4a, 0x3d, 0x39, 0xcb, 0x4a, 0xdc, 0xdb, 0xcc, 0xcc, 0xdb, 0xdb, + 0x4a, 0xcc, 0x3b, 0x1f, 0x62, 0x04, 0xc4, 0xba, 0x5c, 0x52, 0x52, 0x5c, + 0x5c, 0x52, 0x51, 0x5d, 0xba, 0xc5, 0xc3, 0xba, 0xba, 0xc4, 0x1f, 0x0e, + 0xee, 0xf7, 0xc2, 0x15, 0x79, 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, + 0x1f, 0xf8, 0x26, 0x06, 0x9d, 0x94, 0x92, 0x99, 0x98, 0x82, 0x92, 0x79, + 0x1f, 0xfc, 0x26, 0x06, 0x0e, 0xf7, 0xc0, 0xf7, 0xcb, 0x15, 0xfb, 0x23, + 0xf7, 0x22, 0x05, 0x83, 0x93, 0x87, 0x8e, 0x85, 0x8b, 0x7f, 0x8b, 0x82, + 0x82, 0x8b, 0x7f, 0x8b, 0x85, 0x8e, 0x86, 0x92, 0x83, 0x08, 0xf7, 0x23, + 0xfb, 0x22, 0xfb, 0x23, 0xfb, 0x23, 0x05, 0x84, 0x84, 0x88, 0x86, 0x8b, + 0x84, 0x8b, 0x80, 0x94, 0x82, 0x97, 0x8b, 0x91, 0x8b, 0x90, 0x8e, 0x93, + 0x92, 0x08, 0xf7, 0x22, 0xf7, 0x23, 0xf7, 0x22, 0xfb, 0x23, 0x05, 0x93, + 0x83, 0x90, 0x89, 0x91, 0x8b, 0x97, 0x8b, 0x94, 0x94, 0x8b, 0x96, 0x8b, + 0x92, 0x89, 0x8f, 0x82, 0x93, 0x08, 0xfb, 0x22, 0xf7, 0x23, 0xf7, 0x22, + 0xf7, 0x22, 0x05, 0x93, 0x93, 0x8e, 0x90, 0x8b, 0x91, 0x8b, 0x97, 0x81, + 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x87, 0x89, 0x82, 0x82, 0x08, 0xfb, 0x22, + 0xfb, 0x22, 0x05, 0x0e, 0xf8, 0x89, 0xf7, 0x9a, 0x15, 0x9d, 0x94, 0x92, + 0x98, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfc, 0x26, 0x06, 0x79, 0x82, 0x84, + 0x7e, 0x7e, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x26, 0x06, 0xfb, 0x5d, 0xfb, + 0x1e, 0x15, 0x70, 0x75, 0x74, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa2, + 0xa1, 0xa6, 0xa7, 0x75, 0xa1, 0x6f, 0x1f, 0xf8, 0x34, 0x04, 0x70, 0x75, + 0x74, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa2, 0xa1, 0xa6, 0xa7, 0x75, + 0xa1, 0x6f, 0x1f, 0x0e, 0xf7, 0x21, 0xf8, 0xa6, 0x15, 0xd2, 0x42, 0x06, + 0x80, 0x93, 0x83, 0x94, 0x95, 0x92, 0x93, 0x96, 0x1e, 0xf5, 0xfb, 0x86, + 0x21, 0x07, 0x80, 0x92, 0x83, 0x95, 0x94, 0x92, 0x93, 0x96, 0x1e, 0xd4, + 0xd2, 0xfb, 0x92, 0x56, 0x07, 0x7f, 0x83, 0x84, 0x82, 0x81, 0x93, 0x84, + 0x97, 0x1f, 0xf7, 0x20, 0x06, 0x96, 0x93, 0x92, 0x95, 0x95, 0x83, 0x91, + 0x80, 0x1f, 0x55, 0xf7, 0x92, 0x06, 0xf7, 0xc8, 0xfb, 0x56, 0x15, 0xdd, + 0xf7, 0x4c, 0x8b, 0xfb, 0x88, 0x66, 0x8b, 0x05, 0x80, 0x83, 0x85, 0x81, + 0x81, 0x93, 0x84, 0x96, 0x1f, 0xe0, 0x06, 0x96, 0x93, 0x92, 0x95, 0x95, + 0x83, 0x91, 0x80, 0x1f, 0x7c, 0xf7, 0x92, 0x95, 0x06, 0x96, 0x93, 0x92, + 0x95, 0x95, 0x84, 0x91, 0x7f, 0x1f, 0x4f, 0x8b, 0x3a, 0xfb, 0x4c, 0x38, + 0xf7, 0x4c, 0x50, 0x8b, 0x05, 0x7f, 0x84, 0x85, 0x81, 0x81, 0x93, 0x84, + 0x96, 0x1f, 0x95, 0xfb, 0x92, 0x7d, 0x06, 0x7f, 0x84, 0x85, 0x81, 0x81, + 0x93, 0x84, 0x95, 0x1f, 0xe0, 0x06, 0x96, 0x93, 0x92, 0x95, 0x94, 0x83, + 0x92, 0x80, 0x1f, 0x66, 0xf7, 0x88, 0x06, 0xde, 0xfb, 0x4c, 0xab, 0x8b, + 0x05, 0x0e, 0xf7, 0xd4, 0xf7, 0xc1, 0x15, 0xf7, 0x48, 0x06, 0x9e, 0x94, + 0x92, 0x98, 0x99, 0x82, 0x91, 0x78, 0x1f, 0xfb, 0x48, 0xf7, 0x35, 0x06, + 0x9d, 0x84, 0x94, 0x7e, 0x7d, 0x84, 0x82, 0x79, 0x1e, 0xfb, 0x35, 0xfb, + 0x48, 0x07, 0x79, 0x82, 0x84, 0x7e, 0x7e, 0x94, 0x84, 0x9d, 0x1f, 0xf7, + 0x48, 0xfb, 0x36, 0x06, 0x79, 0x92, 0x82, 0x99, 0x98, 0x92, 0x94, 0x9d, + 0x1e, 0xf7, 0x36, 0x07, 0xfb, 0x71, 0xfb, 0x99, 0x15, 0x79, 0x82, 0x84, + 0x7e, 0x7e, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x26, 0x06, 0x9d, 0x94, 0x92, + 0x98, 0x98, 0x82, 0x92, 0x79, 0x1f, 0xfc, 0x26, 0x06, 0x0e, 0xf8, 0x79, + 0xf8, 0x71, 0x15, 0x8f, 0x91, 0x8f, 0x92, 0x8b, 0x8f, 0x8b, 0x96, 0x82, + 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x88, 0x89, 0x82, 0x81, 0x08, 0xfb, 0xf2, + 0xfc, 0x32, 0x05, 0x85, 0x84, 0x88, 0x85, 0x8b, 0x87, 0x8b, 0x80, 0x94, + 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x93, 0x95, 0x08, 0xf7, 0xf3, + 0xf8, 0x32, 0x05, 0xfb, 0xe2, 0xf7, 0x1b, 0x15, 0xfb, 0x13, 0x64, 0x8b, + 0x8b, 0x8b, 0x7c, 0x8b, 0x82, 0x94, 0x82, 0x93, 0x8b, 0x8d, 0x8b, 0x8e, + 0x8c, 0x8f, 0x8c, 0x08, 0xcc, 0xa0, 0x8b, 0xfb, 0xa0, 0x05, 0x75, 0x8c, + 0x6c, 0x8b, 0x83, 0x8b, 0x08, 0x76, 0x81, 0x85, 0x7e, 0x80, 0x93, 0x84, + 0x98, 0x1f, 0xf7, 0x46, 0x06, 0x97, 0x93, 0x92, 0x96, 0x96, 0x83, 0x92, + 0x7f, 0x1f, 0x44, 0xf7, 0xd1, 0x06, 0xf7, 0x80, 0xfc, 0xd4, 0x15, 0xf7, + 0x3b, 0xf7, 0x2d, 0x9c, 0x9f, 0x8b, 0xb6, 0x8b, 0xc1, 0x59, 0xba, 0x51, + 0x8b, 0x68, 0x8b, 0x6a, 0x7b, 0x75, 0x6f, 0x80, 0x7d, 0x83, 0x79, 0x8b, + 0x80, 0x8b, 0x82, 0x93, 0x83, 0x94, 0x8b, 0x94, 0x8b, 0x91, 0x90, 0x8e, + 0x96, 0x08, 0x94, 0xaa, 0xaa, 0xa0, 0xad, 0x8b, 0xb1, 0x8b, 0xad, 0x6d, + 0x8b, 0x68, 0x8b, 0x75, 0x81, 0x7d, 0x59, 0x59, 0x08, 0xfb, 0x18, 0xfb, + 0x0f, 0x8b, 0x60, 0xf7, 0x7a, 0x8b, 0x8b, 0xb2, 0x05, 0x97, 0x84, 0x93, + 0x80, 0x80, 0x84, 0x83, 0x7f, 0x1e, 0x88, 0xfb, 0x2a, 0x07, 0x0e, 0xf7, + 0x24, 0xf8, 0xf8, 0x15, 0xfb, 0x13, 0x64, 0x8b, 0x8b, 0x8b, 0x7c, 0x8b, + 0x82, 0x94, 0x82, 0x93, 0x8b, 0x8d, 0x8b, 0x8e, 0x8c, 0x8f, 0x8c, 0x08, + 0xcc, 0xa0, 0x8b, 0xfb, 0xa0, 0x05, 0x75, 0x8c, 0x6c, 0x8b, 0x83, 0x8b, + 0x08, 0x76, 0x81, 0x85, 0x7e, 0x80, 0x93, 0x84, 0x98, 0x1f, 0xf7, 0x46, + 0x06, 0x97, 0x94, 0x92, 0x96, 0x96, 0x83, 0x92, 0x7e, 0x1f, 0x44, 0x06, + 0xf7, 0xd1, 0x07, 0xf7, 0xf0, 0xfb, 0x1b, 0x15, 0x8f, 0x91, 0x8f, 0x92, + 0x8b, 0x8f, 0x8b, 0x96, 0x82, 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x88, 0x89, + 0x82, 0x81, 0x08, 0xfb, 0xf2, 0xfc, 0x32, 0x05, 0x85, 0x84, 0x88, 0x85, + 0x8b, 0x87, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, + 0x93, 0x95, 0x08, 0xf7, 0xf3, 0xf8, 0x32, 0x05, 0x9d, 0xfc, 0x14, 0x15, + 0x52, 0x07, 0x62, 0x8b, 0x8b, 0x8b, 0x86, 0x8a, 0x85, 0x88, 0x86, 0x84, + 0x8b, 0x84, 0x08, 0x80, 0x93, 0x84, 0x98, 0x1e, 0xe0, 0x06, 0x98, 0x93, + 0x92, 0x96, 0x96, 0x83, 0x92, 0x7e, 0x1f, 0x7e, 0xc4, 0x94, 0x06, 0x9b, + 0x94, 0x91, 0x97, 0x96, 0x83, 0x92, 0x7e, 0x1f, 0x7e, 0xf7, 0x6c, 0x52, + 0x06, 0xfb, 0x14, 0xfb, 0x6e, 0x8b, 0x69, 0xf7, 0x29, 0x8b, 0x05, 0xaf, + 0x04, 0xfb, 0x01, 0x8b, 0xf6, 0xf7, 0x48, 0x8d, 0x8b, 0x05, 0xfb, 0x48, + 0x07, 0x0e, 0xf7, 0x4b, 0xf8, 0x52, 0x15, 0xac, 0xa1, 0x98, 0xa1, 0x8b, + 0xa9, 0x08, 0xbf, 0x5e, 0xb3, 0x50, 0x5d, 0x52, 0x6c, 0x72, 0x82, 0x93, + 0x83, 0x95, 0x1e, 0x91, 0x8b, 0x8f, 0x8d, 0x91, 0x93, 0x9a, 0x9c, 0xa4, + 0x95, 0xa8, 0x8b, 0x08, 0xb2, 0xa8, 0x73, 0x6b, 0x6d, 0x70, 0x74, 0x66, + 0x1f, 0x72, 0x8b, 0x8b, 0x8b, 0x88, 0x89, 0x85, 0x87, 0x88, 0x85, 0x8b, + 0x85, 0x8b, 0x80, 0x93, 0x85, 0x98, 0x8a, 0x08, 0xc0, 0x8a, 0xb2, 0x6b, + 0x8b, 0x63, 0x8b, 0x65, 0x64, 0x6a, 0x5d, 0x8b, 0x6d, 0x8b, 0x73, 0x93, + 0x6d, 0xa0, 0x86, 0x8f, 0x88, 0x8c, 0x86, 0x8b, 0x08, 0x82, 0x83, 0x83, + 0x82, 0x74, 0xcb, 0x6d, 0xbd, 0xcd, 0xc2, 0xbb, 0xc6, 0x1f, 0x8b, 0xaf, + 0x78, 0xa7, 0x64, 0xa3, 0x08, 0xf7, 0xc8, 0xaa, 0x15, 0x8f, 0x91, 0x8f, + 0x92, 0x8b, 0x8f, 0x8b, 0x96, 0x82, 0x94, 0x80, 0x8b, 0x85, 0x8b, 0x88, + 0x89, 0x82, 0x81, 0x08, 0xfb, 0xf2, 0xfc, 0x32, 0x05, 0x84, 0x83, 0x89, + 0x87, 0x8b, 0x86, 0x8b, 0x80, 0x94, 0x82, 0x96, 0x8b, 0x91, 0x8b, 0x8f, + 0x8d, 0x93, 0x95, 0x08, 0xf7, 0xf3, 0xf8, 0x32, 0x05, 0x9e, 0xfc, 0x14, + 0x15, 0x52, 0x07, 0x62, 0x8b, 0x8b, 0x8b, 0x86, 0x8a, 0x85, 0x88, 0x86, + 0x84, 0x8b, 0x84, 0x08, 0x80, 0x93, 0x84, 0x98, 0x1e, 0xe0, 0x06, 0x98, + 0x93, 0x92, 0x96, 0x96, 0x83, 0x92, 0x7e, 0x1f, 0x7e, 0xc4, 0x94, 0x06, + 0x9b, 0x94, 0x91, 0x97, 0x96, 0x83, 0x92, 0x7e, 0x1f, 0x7e, 0xf7, 0x6c, + 0x52, 0x06, 0xfb, 0x14, 0xfb, 0x6e, 0x8b, 0x69, 0xf7, 0x29, 0x8b, 0x05, + 0xaf, 0x04, 0xfb, 0x01, 0x8b, 0xf6, 0xf7, 0x48, 0x8d, 0x8b, 0x05, 0xfb, + 0x48, 0x07, 0x0e, 0xf7, 0x2d, 0xf7, 0x98, 0x15, 0x3c, 0xd1, 0x45, 0xda, + 0x1e, 0xaf, 0x8b, 0xae, 0x99, 0xa8, 0xa6, 0x9b, 0x99, 0x92, 0x96, 0x8b, + 0x93, 0x8b, 0x94, 0x83, 0x93, 0x82, 0x8b, 0x84, 0x8b, 0x87, 0x89, 0x86, + 0x85, 0x6e, 0x69, 0x72, 0x7e, 0x67, 0x8b, 0x08, 0x4d, 0x58, 0xc0, 0xca, + 0x1f, 0xb2, 0x07, 0xc9, 0xb9, 0xbd, 0xc5, 0x1e, 0xb8, 0x8b, 0xb3, 0x71, + 0x8e, 0x6c, 0x8d, 0x7f, 0x91, 0x84, 0x95, 0x8b, 0x08, 0x96, 0x92, 0x93, + 0x97, 0x1f, 0xcc, 0x07, 0x97, 0x84, 0x93, 0x80, 0x80, 0x84, 0x83, 0x7d, + 0x1e, 0x68, 0xa1, 0x75, 0x92, 0x6b, 0x8b, 0x08, 0x3f, 0x4c, 0x4a, 0x3b, + 0x1f, 0x5e, 0x07, 0xf7, 0x27, 0xf7, 0xd2, 0x15, 0xfb, 0x38, 0xfb, 0x19, + 0xfb, 0x19, 0xfb, 0x37, 0xfb, 0x36, 0xf7, 0x19, 0xfb, 0x1b, 0xf7, 0x34, + 0xf7, 0x3c, 0xf7, 0x18, 0xf7, 0x17, 0xf7, 0x3a, 0xf7, 0x37, 0xfb, 0x19, + 0xf7, 0x19, 0xfb, 0x37, 0x1f, 0x62, 0x04, 0xf7, 0x20, 0xf7, 0x07, 0xfb, + 0x07, 0xfb, 0x20, 0xfb, 0x23, 0xfb, 0x06, 0xfb, 0x05, 0xfb, 0x25, 0xfb, + 0x1d, 0xfb, 0x07, 0xf7, 0x08, 0xf7, 0x20, 0xf7, 0x21, 0xf7, 0x07, 0xf7, + 0x06, 0xf7, 0x21, 0x1f, 0x0e, 0xf7, 0x7d, 0xf7, 0x96, 0x15, 0xca, 0x06, + 0xae, 0x7f, 0xb2, 0x5b, 0xb0, 0x3d, 0x08, 0xb2, 0x06, 0x97, 0x93, 0x92, + 0x96, 0x96, 0x83, 0x92, 0x7f, 0x1f, 0x7c, 0x06, 0x62, 0xd3, 0x80, 0x9a, + 0x6a, 0xa5, 0xb6, 0x97, 0xa6, 0xaa, 0x8b, 0xb1, 0x08, 0xc1, 0x5f, 0xb2, + 0x4e, 0x1e, 0xfb, 0x1e, 0x06, 0x7e, 0x83, 0x84, 0x80, 0x80, 0x93, 0x84, + 0x98, 0x1f, 0xa3, 0xfb, 0x8f, 0x73, 0x06, 0x7e, 0x83, 0x84, 0x80, 0x80, + 0x93, 0x84, 0x98, 0x1f, 0xeb, 0x06, 0x97, 0x93, 0x92, 0x96, 0x96, 0x83, + 0x92, 0x7f, 0x1f, 0x67, 0xf1, 0x06, 0xaf, 0x04, 0xf7, 0x05, 0xd8, 0x07, + 0xb4, 0xa8, 0x74, 0x6b, 0x67, 0x68, 0x75, 0x53, 0x1f, 0x53, 0x06, 0xce, + 0xf7, 0xb0, 0x15, 0xfb, 0x38, 0xfb, 0x19, 0xfb, 0x19, 0xfb, 0x37, 0xfb, + 0x36, 0xf7, 0x19, 0xfb, 0x1b, 0xf7, 0x34, 0xf7, 0x3c, 0xf7, 0x18, 0xf7, + 0x17, 0xf7, 0x3a, 0xf7, 0x37, 0xfb, 0x19, 0xf7, 0x19, 0xfb, 0x37, 0x1f, + 0x62, 0x04, 0xf7, 0x20, 0xf7, 0x07, 0xfb, 0x07, 0xfb, 0x20, 0xfb, 0x23, + 0xfb, 0x06, 0xfb, 0x05, 0xfb, 0x25, 0xfb, 0x1d, 0xfb, 0x07, 0xf7, 0x08, + 0xf7, 0x20, 0xf7, 0x21, 0xf7, 0x07, 0xf7, 0x06, 0xf7, 0x21, 0x1f, 0x0e, + 0x0e, 0xf8, 0x7b, 0xf8, 0x21, 0x15, 0xfb, 0x5e, 0x07, 0x79, 0x92, 0x82, + 0x98, 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x87, 0xfc, 0x41, 0x07, 0x79, + 0x82, 0x84, 0x7e, 0x7d, 0x94, 0x84, 0x9d, 0x1f, 0xf8, 0x18, 0x06, 0x0e, + 0xf7, 0xd4, 0xf8, 0xd5, 0x15, 0x9d, 0x84, 0x94, 0x7e, 0x7e, 0x84, 0x82, + 0x79, 0x1e, 0xfb, 0x9f, 0x07, 0x79, 0x92, 0x82, 0x98, 0x98, 0x92, 0x94, + 0x9d, 0x1e, 0xf7, 0x9f, 0x07, 0xfc, 0x2b, 0x04, 0x9d, 0x84, 0x94, 0x7e, + 0x7e, 0x84, 0x82, 0x79, 0x1e, 0xfb, 0x9f, 0x07, 0x79, 0x92, 0x82, 0x98, + 0x98, 0x92, 0x94, 0x9d, 0x1e, 0xf7, 0x9f, 0x07, 0x0e, 0xf7, 0x39, 0x9b, + 0x15, 0xa6, 0x73, 0xa4, 0x83, 0xb4, 0x8b, 0xcc, 0x8b, 0xcb, 0xa5, 0xbf, + 0xbc, 0x08, 0x50, 0xd6, 0x07, 0x9d, 0x94, 0x92, 0x98, 0x99, 0x82, 0x91, + 0x79, 0x1f, 0x69, 0xf8, 0x0d, 0xfb, 0x07, 0x06, 0x78, 0x82, 0x85, 0x7d, + 0x7e, 0x94, 0x84, 0x9e, 0x1f, 0xd5, 0xfb, 0x9a, 0x06, 0x54, 0x4e, 0x4f, + 0x6d, 0x47, 0x8b, 0x08, 0x55, 0x66, 0xb0, 0xc1, 0x1f, 0xf7, 0xc2, 0x2c, + 0x07, 0x79, 0x82, 0x85, 0x7d, 0x7e, 0x94, 0x84, 0x9d, 0x1f, 0xc1, 0xfc, + 0xba, 0x06, 0x79, 0x92, 0x82, 0x98, 0x99, 0x92, 0x94, 0x9d, 0x1e, 0xf7, + 0x51, 0x07, 0x0e, 0xf8, 0xec, 0x14, 0x8b, 0x15, 0x7b, 0x9b, 0xf8, 0x35, + 0x99, 0xf7, 0x18, 0x98, 0xa6, 0x9a, 0x06, 0x1e, 0x0a, 0x03, 0x96, 0x25, + 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xb6, 0x0a, 0xb6, 0x0c, 0x0c, 0xb4, + 0x0b, 0xb4, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00 +}; +const unsigned int fonts_NimbusMonL_Regu_cff_len = 25616; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusMonL-ReguObli.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusMonL-ReguObli.cff.c new file mode 100644 index 00000000000..c3ff97ae6ed --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusMonL-ReguObli.cff.c @@ -0,0 +1,2371 @@ +const unsigned char fonts_NimbusMonL_ReguObli_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x14, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x4d, 0x6f, 0x6e, 0x4c, 0x2d, 0x52, 0x65, 0x67, 0x75, + 0x4f, 0x62, 0x6c, 0x69, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x37, 0xf8, + 0x1f, 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, + 0x18, 0x04, 0x8c, 0x0c, 0x01, 0x7f, 0x0c, 0x02, 0x1d, 0x00, 0x4c, 0x9d, + 0x13, 0x0d, 0x4e, 0xfb, 0x6c, 0xf9, 0x5a, 0xf9, 0xbf, 0x05, 0x1c, 0x00, + 0xf8, 0x0f, 0x1c, 0x00, 0x00, 0x10, 0x1c, 0x02, 0xcb, 0x11, 0x1c, 0x00, + 0x27, 0x1c, 0x6e, 0xd7, 0x12, 0x00, 0x08, 0x02, 0x00, 0x01, 0x00, 0x05, + 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x5f, 0x00, 0x7c, + 0x00, 0x89, 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, 0x64, 0x64, 0x6f, 0x74, + 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x6e, 0x62, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, + 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, 0x28, 0x55, 0x52, 0x57, + 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x26, + 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, + 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x20, + 0x4c, 0x20, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x4f, 0x62, + 0x6c, 0x69, 0x71, 0x75, 0x65, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, + 0x4d, 0x6f, 0x6e, 0x6f, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, + 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, + 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, + 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, + 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, + 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, + 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, + 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, + 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, + 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, + 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, + 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, + 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, + 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, + 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, + 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, + 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, + 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, + 0x7f, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, + 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, + 0x8b, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, + 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, + 0xab, 0x00, 0xae, 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, + 0x9a, 0x00, 0xb4, 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, + 0xb6, 0x00, 0xb9, 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, + 0xbe, 0x00, 0xbc, 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, + 0xc4, 0x00, 0xc2, 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, + 0xca, 0x00, 0xc8, 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, + 0xce, 0x00, 0xd1, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, + 0xd3, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, + 0xdb, 0x00, 0xd9, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, + 0xe1, 0x00, 0xdf, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, + 0xe3, 0x01, 0x87, 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, + 0x89, 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, + 0x9c, 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, + 0x8a, 0x00, 0x97, 0x00, 0xa0, 0x00, 0x98, 0x00, 0xea, 0x02, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x53, 0x00, 0x8e, 0x01, 0x4b, + 0x02, 0x3c, 0x02, 0xc5, 0x03, 0x66, 0x03, 0x8c, 0x03, 0xde, 0x04, 0x2a, + 0x04, 0xb0, 0x05, 0x00, 0x05, 0x26, 0x05, 0x44, 0x05, 0x60, 0x05, 0x96, + 0x06, 0x0c, 0x06, 0x51, 0x06, 0xbf, 0x07, 0x49, 0x07, 0x9c, 0x08, 0x17, + 0x08, 0x8d, 0x08, 0xd4, 0x09, 0x3a, 0x09, 0xb6, 0x09, 0xec, 0x0a, 0x2d, + 0x0a, 0x80, 0x0a, 0xba, 0x0b, 0x0d, 0x0b, 0x8d, 0x0c, 0x48, 0x0c, 0xb3, + 0x0d, 0x31, 0x0d, 0xca, 0x0e, 0x35, 0x0e, 0xc7, 0x0f, 0x48, 0x0f, 0xef, + 0x10, 0x76, 0x10, 0xba, 0x11, 0x12, 0x11, 0x98, 0x11, 0xea, 0x12, 0x61, + 0x12, 0xbf, 0x13, 0x00, 0x13, 0x5a, 0x13, 0xff, 0x14, 0x76, 0x15, 0x45, + 0x15, 0xa0, 0x16, 0x10, 0x16, 0x5b, 0x16, 0xb6, 0x17, 0x45, 0x17, 0xaf, + 0x18, 0x06, 0x18, 0x32, 0x18, 0x68, 0x18, 0x93, 0x18, 0xd1, 0x18, 0xdd, + 0x18, 0xfc, 0x19, 0x87, 0x19, 0xea, 0x1a, 0x6b, 0x1a, 0xce, 0x1b, 0x38, + 0x1b, 0xae, 0x1c, 0x23, 0x1c, 0xab, 0x1c, 0xf0, 0x1d, 0x37, 0x1d, 0xaa, + 0x1d, 0xe4, 0x1e, 0x8a, 0x1f, 0x0e, 0x1f, 0x49, 0x1f, 0xb6, 0x20, 0x23, + 0x20, 0x8a, 0x21, 0x4e, 0x21, 0xcc, 0x22, 0x31, 0x22, 0x7c, 0x22, 0xd7, + 0x23, 0x65, 0x23, 0xcb, 0x24, 0x17, 0x24, 0x9b, 0x24, 0xd1, 0x25, 0x54, + 0x25, 0xba, 0x26, 0x09, 0x26, 0xb8, 0x27, 0x55, 0x27, 0x8d, 0x28, 0x38, + 0x28, 0xb5, 0x29, 0x89, 0x2a, 0x3d, 0x2a, 0x5c, 0x2a, 0x97, 0x2b, 0x10, + 0x2b, 0x4e, 0x2b, 0x8c, 0x2c, 0x40, 0x2c, 0xe8, 0x2d, 0x06, 0x2d, 0x6a, + 0x2d, 0xef, 0x2e, 0x0b, 0x2e, 0xa4, 0x2e, 0xbb, 0x2e, 0xe1, 0x2f, 0x2a, + 0x2f, 0x73, 0x2f, 0xec, 0x30, 0x2a, 0x30, 0xde, 0x31, 0x5e, 0x31, 0x90, + 0x31, 0xc4, 0x32, 0x02, 0x32, 0x5c, 0x32, 0x7a, 0x32, 0xbf, 0x32, 0xd6, + 0x33, 0x01, 0x33, 0x2c, 0x33, 0x64, 0x33, 0xcb, 0x34, 0x01, 0x34, 0x3d, + 0x34, 0x5b, 0x35, 0x22, 0x35, 0xac, 0x36, 0x3a, 0x36, 0xdf, 0x37, 0x8c, + 0x37, 0xb7, 0x38, 0xaf, 0x38, 0xe7, 0x39, 0x57, 0x39, 0xfc, 0x3a, 0xab, + 0x3b, 0x44, 0x3b, 0xd9, 0x3c, 0x79, 0x3d, 0x14, 0x3d, 0xbb, 0x3e, 0x7e, + 0x3f, 0x12, 0x3f, 0xe3, 0x40, 0x74, 0x41, 0x30, 0x41, 0xf5, 0x42, 0xb8, + 0x43, 0x87, 0x43, 0xf4, 0x44, 0x6b, 0x44, 0xdf, 0x45, 0x5d, 0x46, 0x13, + 0x46, 0x7d, 0x46, 0xf1, 0x47, 0x62, 0x47, 0xdf, 0x48, 0x79, 0x49, 0x85, + 0x4a, 0x1f, 0x4a, 0xc1, 0x4b, 0x62, 0x4c, 0x0f, 0x4c, 0xac, 0x4d, 0x3f, + 0x4d, 0xaa, 0x4e, 0x3d, 0x4e, 0xf2, 0x4f, 0xaf, 0x50, 0x6a, 0x51, 0x2f, + 0x52, 0x13, 0x52, 0xc8, 0x53, 0x83, 0x54, 0x17, 0x54, 0xb4, 0x55, 0x4f, + 0x55, 0xf4, 0x56, 0x55, 0x56, 0xc0, 0x57, 0x28, 0x57, 0x9c, 0x58, 0x79, + 0x58, 0xdd, 0x59, 0x4e, 0x59, 0xb9, 0x5a, 0x2e, 0x5a, 0xc2, 0x5b, 0xc1, + 0x5c, 0x50, 0x5c, 0xe7, 0x5d, 0x7c, 0x5e, 0x1d, 0x5e, 0xb6, 0x5f, 0x3c, + 0x5f, 0xcd, 0x60, 0x3a, 0x60, 0xc9, 0x61, 0x87, 0x61, 0xca, 0x62, 0x2b, + 0x62, 0x99, 0x62, 0xb5, 0x62, 0xd3, 0x62, 0xfe, 0x63, 0x1c, 0x63, 0x93, + 0x63, 0xdc, 0x64, 0xa6, 0x65, 0x1f, 0x65, 0xf9, 0x66, 0xbf, 0x67, 0xac, + 0x68, 0x77, 0x69, 0x28, 0x69, 0x29, 0x69, 0x5f, 0x69, 0xbc, 0x6a, 0x34, + 0x0e, 0x0e, 0x0e, 0xf8, 0x5e, 0xf8, 0xc7, 0x15, 0x8e, 0x97, 0x8d, 0x94, + 0x8b, 0x90, 0x8b, 0x9c, 0x7d, 0x97, 0x79, 0x8b, 0x6e, 0x8b, 0x7b, 0x7a, + 0x85, 0x65, 0x08, 0x58, 0xfb, 0xda, 0x05, 0x8a, 0x85, 0x8b, 0x88, 0x8b, + 0x87, 0x8b, 0x83, 0x92, 0x84, 0x93, 0x8b, 0x99, 0x8b, 0x93, 0x93, 0x90, + 0x9f, 0x08, 0xe3, 0xf7, 0xda, 0x05, 0xfb, 0x27, 0xfc, 0x72, 0x15, 0x69, + 0x6c, 0x6f, 0x6a, 0x74, 0x9d, 0x7b, 0xa5, 0x1f, 0x97, 0x06, 0xae, 0xaa, + 0xa7, 0xab, 0xa3, 0x79, 0x9b, 0x70, 0x1f, 0x7f, 0x06, 0x0e, 0xf7, 0xa6, + 0xf8, 0xf0, 0x15, 0x77, 0xfb, 0x91, 0x8b, 0x81, 0x05, 0x7b, 0x94, 0x81, + 0x99, 0x1e, 0x9d, 0x8b, 0x96, 0x96, 0x94, 0xa4, 0x08, 0xe2, 0xf7, 0x91, + 0xfb, 0x14, 0x8b, 0x05, 0xf7, 0x48, 0x16, 0x77, 0xfb, 0x91, 0x8b, 0x81, + 0x05, 0x7b, 0x94, 0x81, 0x99, 0x1e, 0x9c, 0x8b, 0x97, 0x96, 0x94, 0xa4, + 0x08, 0xe2, 0xf7, 0x91, 0xfb, 0x14, 0x8b, 0x05, 0x0e, 0xf8, 0x66, 0xf7, + 0xf8, 0x15, 0xe6, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x85, 0x90, 0x7a, + 0x1f, 0x32, 0x8b, 0xca, 0xf7, 0x72, 0x05, 0x8e, 0x95, 0x8b, 0x8b, 0x8b, + 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x81, 0x8b, 0x7f, 0x8b, 0x82, 0x83, 0x86, + 0x7a, 0x08, 0x4c, 0xfb, 0x75, 0x30, 0x8b, 0xca, 0xf7, 0x72, 0x05, 0x8c, + 0x8f, 0x8c, 0x91, 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7e, + 0x8b, 0x83, 0x83, 0x86, 0x7a, 0x08, 0x4b, 0xfb, 0x75, 0x3b, 0x8b, 0x05, + 0x76, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xd9, 0x8b, 0x67, + 0xfb, 0x12, 0x32, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xe2, 0x8b, 0x4c, 0xfb, 0x72, 0x05, 0x88, 0x81, 0x8b, 0x8b, + 0x8b, 0x88, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x98, 0x8b, 0x94, 0x93, + 0x90, 0x9d, 0x08, 0xca, 0xf7, 0x75, 0xe6, 0x8b, 0x4c, 0xfb, 0x72, 0x05, + 0x8a, 0x85, 0x8a, 0x87, 0x8b, 0x88, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, + 0x98, 0x8b, 0x93, 0x93, 0x90, 0x9d, 0x08, 0xcb, 0xf7, 0x75, 0xdd, 0x8b, + 0x05, 0x9f, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0x3b, 0x8b, + 0xaf, 0xf7, 0x12, 0x05, 0x62, 0x16, 0x68, 0xfb, 0x12, 0x30, 0x8b, 0xae, + 0xf7, 0x12, 0xe6, 0x8b, 0x05, 0x0e, 0xf8, 0x27, 0xf8, 0xd4, 0x15, 0x29, + 0x80, 0x3b, 0x3f, 0x8b, 0x3b, 0x8b, 0x71, 0x98, 0x70, 0x9d, 0x7c, 0xa0, + 0x7b, 0xa6, 0x81, 0xc9, 0x7f, 0xce, 0x7d, 0x9a, 0x87, 0x9d, 0x7d, 0x9a, + 0x80, 0x96, 0x76, 0x8b, 0x78, 0x8b, 0x46, 0x3b, 0x50, 0x2f, 0x8b, 0x08, + 0x6a, 0x8b, 0x63, 0x94, 0x79, 0x98, 0x7e, 0x94, 0x70, 0xa7, 0x8b, 0x8f, + 0x08, 0x8e, 0xab, 0x05, 0x86, 0x93, 0x85, 0x8f, 0x86, 0x8b, 0x7e, 0x8b, + 0x81, 0x80, 0x87, 0x7a, 0x08, 0x7b, 0x3c, 0x05, 0x8a, 0x87, 0x8a, 0x85, + 0x8b, 0x89, 0x8b, 0x83, 0x93, 0x84, 0x93, 0x8b, 0x99, 0x8b, 0x93, 0x94, + 0x8f, 0x9d, 0x08, 0x8f, 0x9b, 0x05, 0x9f, 0x6e, 0xbc, 0x74, 0xb9, 0x89, + 0x08, 0x71, 0xfb, 0x0b, 0x8a, 0x80, 0x05, 0x82, 0x92, 0x84, 0x94, 0x1e, + 0x99, 0x8b, 0x93, 0x94, 0x8f, 0x9d, 0x08, 0xa5, 0xf7, 0x0b, 0x05, 0xf7, + 0x09, 0x97, 0xdf, 0xd5, 0x8b, 0xe7, 0x8b, 0xa4, 0x7e, 0xa8, 0x78, 0x9a, + 0x75, 0x9e, 0x71, 0x94, 0x46, 0x98, 0x51, 0x97, 0x78, 0x91, 0x7a, 0x96, + 0x7d, 0x95, 0x81, 0x9f, 0x8b, 0x9c, 0x8b, 0xc7, 0xd6, 0xc8, 0xd5, 0x8b, + 0x08, 0xa4, 0x8b, 0xad, 0x82, 0x9d, 0x81, 0x99, 0x82, 0x9f, 0x76, 0x8b, + 0x86, 0x08, 0x89, 0x73, 0x05, 0x90, 0x82, 0x90, 0x87, 0x92, 0x8b, 0x97, + 0x8b, 0x95, 0x95, 0x8e, 0x9d, 0x08, 0x98, 0xc7, 0x05, 0x8d, 0x92, 0x8b, + 0x8d, 0x8b, 0x8e, 0x08, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7e, 0x8b, 0x82, + 0x81, 0x86, 0x78, 0x6c, 0xa7, 0x76, 0x95, 0x60, 0x8f, 0x08, 0x96, 0xbf, + 0x8c, 0x96, 0x05, 0x94, 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x83, 0x82, + 0x87, 0x79, 0x08, 0x80, 0x57, 0x05, 0x0e, 0xf8, 0x30, 0xf7, 0x80, 0x15, + 0x3d, 0x41, 0x42, 0x3e, 0x53, 0xb5, 0x61, 0xc3, 0xda, 0xd5, 0xd4, 0xd7, + 0xc6, 0x62, 0xb3, 0x51, 0x1f, 0x82, 0x65, 0x15, 0xb4, 0xa7, 0x6f, 0x64, + 0x54, 0x58, 0x59, 0x54, 0x64, 0x6f, 0xa8, 0xb2, 0xc0, 0xbe, 0xbe, 0xc0, + 0x1f, 0x67, 0xf8, 0x31, 0x15, 0x3e, 0x41, 0x42, 0x3f, 0x52, 0xb4, 0x61, + 0xc4, 0xda, 0xd5, 0xd4, 0xd7, 0xc5, 0x62, 0xb4, 0x50, 0x1f, 0x84, 0x65, + 0x15, 0xb3, 0xa7, 0x6f, 0x63, 0x55, 0x58, 0x59, 0x54, 0x65, 0x6e, 0xa8, + 0xb2, 0xc0, 0xbe, 0xbe, 0xc1, 0x1f, 0xf7, 0x65, 0xfb, 0x79, 0x15, 0x9a, + 0x8f, 0x92, 0x93, 0x8b, 0x96, 0x8b, 0x93, 0x85, 0x92, 0x84, 0x8b, 0x86, + 0x8b, 0x88, 0x8a, 0x86, 0x8a, 0x08, 0xfc, 0x2a, 0xfb, 0x0e, 0x05, 0x7d, + 0x86, 0x83, 0x83, 0x8b, 0x81, 0x8b, 0x83, 0x91, 0x84, 0x93, 0x8b, 0x8e, + 0x8b, 0x90, 0x8b, 0x8f, 0x8d, 0x08, 0xf8, 0x2a, 0xf7, 0x0e, 0x05, 0x0e, + 0xf8, 0x1d, 0x16, 0xc5, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x84, 0x8f, + 0x7b, 0x1f, 0x65, 0x8b, 0x78, 0xb4, 0x05, 0xa5, 0xa7, 0xa7, 0xb7, 0xa5, + 0xc1, 0x08, 0x97, 0x06, 0x9f, 0x97, 0x94, 0x9b, 0x97, 0x85, 0x8f, 0x7a, + 0x1f, 0x60, 0x06, 0x76, 0x5a, 0x74, 0x62, 0x6e, 0x65, 0x08, 0x41, 0xf7, + 0x45, 0x05, 0x7a, 0xb4, 0x84, 0xa4, 0x8b, 0x9c, 0x8b, 0xbb, 0xbe, 0xbc, + 0xbd, 0x8b, 0xa2, 0x8b, 0x9c, 0x83, 0x9c, 0x79, 0x08, 0xae, 0x9b, 0x05, + 0x9b, 0x93, 0x91, 0x92, 0x8b, 0x96, 0x8b, 0x93, 0x84, 0x93, 0x83, 0x8b, + 0x87, 0x8b, 0x84, 0x89, 0x84, 0x88, 0x08, 0x80, 0x85, 0x05, 0x78, 0x99, + 0x77, 0x91, 0x74, 0x8b, 0x40, 0x8b, 0x40, 0x45, 0x8b, 0x45, 0x8b, 0x77, + 0x8f, 0x80, 0xa3, 0x4e, 0x36, 0x73, 0x4f, 0x41, 0x8b, 0x3a, 0x08, 0x44, + 0xbc, 0x56, 0xcd, 0x1e, 0xb9, 0x8b, 0xb4, 0xa0, 0xb1, 0xb6, 0x08, 0xa0, + 0x5b, 0x05, 0x67, 0xe1, 0x15, 0x6c, 0x64, 0x67, 0x75, 0x68, 0x8b, 0x5d, + 0x8b, 0x68, 0xb3, 0x8b, 0xbe, 0x8b, 0xcb, 0xbb, 0xc4, 0xcc, 0x99, 0x08, + 0xd1, 0xfb, 0x39, 0x05, 0x0e, 0xf7, 0xe3, 0xf8, 0xf0, 0x15, 0xfb, 0x0f, + 0xfb, 0x8e, 0x05, 0x88, 0x85, 0x89, 0x85, 0x8b, 0x86, 0x8b, 0x7e, 0x95, + 0x81, 0x98, 0x8b, 0x99, 0x8b, 0x93, 0x91, 0x9a, 0x9e, 0x08, 0xf7, 0x5d, + 0xf7, 0x9d, 0xfb, 0x19, 0x8b, 0x05, 0x0e, 0xf8, 0xca, 0xf8, 0xf0, 0x15, + 0x7e, 0x8b, 0x7a, 0x79, 0x60, 0x53, 0xfb, 0x04, 0xfb, 0x27, 0x5d, 0xfb, + 0x07, 0x8b, 0xfb, 0x16, 0x8b, 0x5a, 0x90, 0x68, 0x99, 0x59, 0x9b, 0x51, + 0x98, 0x67, 0x9a, 0x72, 0x8e, 0x85, 0x90, 0x88, 0x90, 0x8b, 0x98, 0x8b, + 0x98, 0x97, 0x8b, 0x96, 0x08, 0x8b, 0x8d, 0x8a, 0x8e, 0x8a, 0x8e, 0x6e, + 0xdf, 0x7f, 0xcc, 0x8b, 0xcf, 0x8b, 0xf7, 0x26, 0xc2, 0xf7, 0x1c, 0xf7, + 0x0f, 0xf7, 0x35, 0x96, 0x99, 0x8b, 0x8b, 0x8b, 0x92, 0x8b, 0x94, 0x84, + 0x92, 0x81, 0x8b, 0x08, 0x0e, 0xf7, 0xbc, 0xf8, 0xf0, 0x15, 0x7e, 0x7e, + 0x7f, 0x80, 0x1f, 0x8b, 0x89, 0x8c, 0x88, 0x8c, 0x88, 0xa8, 0x37, 0x97, + 0x4a, 0x8b, 0x47, 0x8b, 0xfb, 0x28, 0x52, 0xfb, 0x1f, 0xfb, 0x12, 0xfb, + 0x36, 0x86, 0x85, 0x8a, 0x87, 0x8b, 0x86, 0x8b, 0x82, 0x92, 0x84, 0x95, + 0x8b, 0x98, 0x8b, 0x9d, 0x9d, 0xb5, 0xc3, 0x08, 0xf7, 0x04, 0xf7, 0x27, + 0xb9, 0xf7, 0x07, 0x8b, 0xf7, 0x16, 0x8b, 0xdb, 0x70, 0xf7, 0x03, 0x67, + 0xc9, 0x88, 0x91, 0x86, 0x8e, 0x86, 0x8b, 0x08, 0x0e, 0xf8, 0x08, 0xf8, + 0x4a, 0x15, 0xfb, 0x0f, 0xb5, 0x05, 0x83, 0x8e, 0x8a, 0x8b, 0x87, 0x8b, + 0x7e, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, 0x8b, 0x84, 0x91, 0x84, 0x92, 0x8a, + 0x08, 0x8e, 0x8a, 0xf7, 0x10, 0x61, 0x22, 0xfb, 0x04, 0x05, 0x81, 0x7f, + 0x89, 0x89, 0x8b, 0x83, 0x8b, 0x82, 0x92, 0x84, 0x95, 0x8b, 0x92, 0x8b, + 0x91, 0x8f, 0x95, 0x95, 0x08, 0xf4, 0xf7, 0x04, 0xc5, 0xfb, 0x04, 0x05, + 0x91, 0x80, 0x8e, 0x88, 0x93, 0x8b, 0x97, 0x8b, 0x98, 0x97, 0x8b, 0x96, + 0x8b, 0x8e, 0x89, 0x93, 0x89, 0x8f, 0x08, 0x51, 0xf7, 0x04, 0xf7, 0x23, + 0xb5, 0x05, 0x9d, 0x91, 0x93, 0x92, 0x8b, 0x98, 0x8b, 0x93, 0x84, 0x93, + 0x83, 0x8b, 0x88, 0x8b, 0x84, 0x8a, 0x86, 0x89, 0x08, 0xfb, 0x23, 0x60, + 0xa9, 0xf7, 0x1f, 0x8c, 0x97, 0x05, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7d, + 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x6d, 0xfb, 0x1f, 0x05, 0x0e, 0xf8, + 0x0b, 0xf7, 0x99, 0x15, 0xf7, 0x49, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, + 0x84, 0x8f, 0x7a, 0x1f, 0xfb, 0x48, 0x8b, 0xb6, 0xf7, 0x5d, 0x8c, 0x96, + 0x05, 0x94, 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x82, 0x82, 0x88, 0x79, + 0x08, 0x60, 0xfb, 0x5d, 0xfb, 0x49, 0x8b, 0x05, 0x78, 0x7f, 0x81, 0x7c, + 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x48, 0x8b, 0x60, 0xfb, 0x5e, 0x8a, + 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x93, 0x94, 0x8f, + 0x9d, 0x08, 0xb6, 0xf7, 0x5e, 0x05, 0x0e, 0xf7, 0x82, 0xf7, 0x25, 0x15, + 0xfb, 0x0f, 0xfb, 0x8e, 0x05, 0x88, 0x85, 0x89, 0x85, 0x8b, 0x86, 0x8b, + 0x7e, 0x95, 0x81, 0x98, 0x8b, 0x99, 0x8b, 0x93, 0x91, 0x9a, 0x9e, 0x08, + 0xf7, 0x5d, 0xf7, 0x9d, 0xfb, 0x19, 0x8b, 0x05, 0x0e, 0xf8, 0xc0, 0xf7, + 0x96, 0x15, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfc, + 0x26, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf8, + 0x26, 0x06, 0x0e, 0xf7, 0xd3, 0xf7, 0x08, 0x15, 0x5f, 0x63, 0x66, 0x61, + 0x6c, 0xa2, 0x76, 0xac, 0x1f, 0x96, 0x06, 0xb7, 0xb3, 0xb0, 0xb5, 0xaa, + 0x74, 0xa0, 0x6a, 0x1f, 0x80, 0x06, 0x0e, 0xf8, 0xfd, 0xf9, 0x0d, 0x15, + 0x91, 0x95, 0x8d, 0x8f, 0x8b, 0x90, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, + 0x82, 0x8b, 0x84, 0x87, 0x82, 0x7d, 0x08, 0xfc, 0x70, 0xfd, 0x4c, 0x05, + 0x85, 0x82, 0x89, 0x86, 0x8b, 0x86, 0x8b, 0x82, 0x93, 0x84, 0x93, 0x8b, + 0x95, 0x8b, 0x91, 0x8f, 0x95, 0x99, 0x08, 0xf8, 0x70, 0xf9, 0x4c, 0x05, + 0x0e, 0xf8, 0xc5, 0xf7, 0xf3, 0x15, 0x92, 0xaa, 0x8e, 0xa9, 0x8b, 0xa8, + 0x8b, 0xf7, 0x04, 0x57, 0xcc, 0x32, 0x8b, 0xfb, 0x02, 0x8b, 0x27, 0xfb, + 0x01, 0x6a, 0xfb, 0x32, 0x08, 0x76, 0x27, 0x05, 0x84, 0x6d, 0x88, 0x6d, + 0x8b, 0x6e, 0x8b, 0xfb, 0x04, 0xbf, 0x4a, 0xe5, 0x8b, 0xf7, 0x02, 0x8b, + 0xed, 0xf7, 0x01, 0xad, 0xf7, 0x31, 0x08, 0xa0, 0xef, 0x05, 0xfb, 0xe2, + 0x86, 0x15, 0x98, 0xcb, 0xac, 0xcf, 0xb3, 0xb9, 0xa8, 0xae, 0xb1, 0x9d, + 0xb5, 0x8b, 0xd1, 0x8b, 0xae, 0x58, 0x8b, 0x26, 0x8b, 0x70, 0x88, 0x6f, + 0x86, 0x73, 0x08, 0x78, 0x32, 0x05, 0x7d, 0x4b, 0x6a, 0x46, 0x64, 0x5e, + 0x6e, 0x68, 0x64, 0x79, 0x62, 0x8b, 0x45, 0x8b, 0x68, 0xbe, 0x8b, 0xf0, + 0x8b, 0xa7, 0x8e, 0xa6, 0x90, 0xa3, 0x08, 0x9e, 0xe4, 0x05, 0x0e, 0xf8, + 0x57, 0xf8, 0xf8, 0x15, 0xfb, 0x59, 0x51, 0x05, 0x79, 0x85, 0x83, 0x84, + 0x8b, 0x7e, 0x8b, 0x83, 0x92, 0x83, 0x93, 0x8b, 0x8e, 0x8b, 0x8c, 0x8b, + 0x96, 0x8e, 0x08, 0xf7, 0x20, 0xb5, 0xfb, 0x01, 0xfc, 0x98, 0xfb, 0x20, + 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xf7, + 0xd4, 0x06, 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, + 0x1f, 0x8b, 0xf7, 0x0d, 0xf8, 0xcf, 0x05, 0x0e, 0xf7, 0x18, 0xb4, 0x15, + 0x8c, 0x8e, 0x05, 0xf5, 0xd9, 0xf7, 0x67, 0xf7, 0x3c, 0xb9, 0xb7, 0xc3, + 0xc1, 0x9f, 0xb2, 0x8b, 0xbf, 0x8b, 0xd7, 0x48, 0xca, 0x3a, 0x8b, 0x4b, + 0x8b, 0x4e, 0x70, 0x5a, 0x5a, 0x72, 0x71, 0x75, 0x68, 0x8b, 0x7c, 0x8b, + 0x84, 0x93, 0x84, 0x93, 0x8b, 0x08, 0x96, 0x8b, 0x92, 0x91, 0x92, 0x99, + 0xa8, 0xc8, 0xd2, 0xb7, 0xd1, 0x8b, 0xcb, 0x8b, 0xbf, 0x5b, 0x8b, 0x51, + 0x8b, 0x52, 0x74, 0x6e, 0xfb, 0x13, 0x24, 0x08, 0xfb, 0xaf, 0xfb, 0x72, + 0x7e, 0x4f, 0xf8, 0x1e, 0x8b, 0x9b, 0xd8, 0x05, 0x8d, 0x93, 0x8b, 0x8c, + 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, + 0x87, 0x79, 0x08, 0x84, 0x67, 0xfb, 0xce, 0x8b, 0x05, 0x0e, 0xf8, 0x50, + 0xf7, 0xdc, 0x15, 0xdf, 0xac, 0xbe, 0xc8, 0x8b, 0xd2, 0x8b, 0xd5, 0x50, + 0xbe, 0x34, 0x8b, 0x50, 0x8b, 0x4e, 0x76, 0x5d, 0x67, 0x76, 0x7b, 0x82, + 0x80, 0x8b, 0x82, 0x8b, 0x81, 0x92, 0x85, 0x94, 0x8b, 0x93, 0x8b, 0x8e, + 0x8d, 0x98, 0x97, 0x08, 0xb1, 0xae, 0xbf, 0x9e, 0xc4, 0x8b, 0x08, 0xce, + 0xb9, 0x65, 0x55, 0x43, 0x44, 0x4f, 0x35, 0x1f, 0x62, 0x8b, 0x8b, 0x8b, + 0x84, 0x85, 0x85, 0x86, 0x87, 0x84, 0x8b, 0x84, 0x8b, 0x80, 0x92, 0x86, + 0x9b, 0x8b, 0x08, 0xde, 0x8c, 0xcf, 0x56, 0x8b, 0x48, 0x8b, 0x35, 0x2b, + 0x3a, 0x24, 0x8b, 0x52, 0x8b, 0x59, 0x9d, 0x62, 0xb0, 0x85, 0x90, 0x87, + 0x8d, 0x85, 0x8b, 0x80, 0x8b, 0x7f, 0x7f, 0x8b, 0x7f, 0x8b, 0x80, 0x97, + 0x7f, 0xa5, 0x7c, 0x08, 0xb9, 0x6f, 0xb7, 0x7e, 0xbc, 0x8b, 0xf7, 0x14, + 0x8b, 0xf7, 0x0f, 0xf3, 0x8b, 0xf7, 0x00, 0x08, 0x8b, 0xc4, 0x6a, 0xba, + 0x4e, 0xa6, 0x08, 0x0e, 0xf8, 0x30, 0xf7, 0x3d, 0x15, 0x70, 0xfb, 0x14, + 0x3f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x2b, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, + 0x69, 0x8b, 0xa7, 0xf7, 0x14, 0xad, 0x8b, 0x05, 0x9e, 0x97, 0x94, 0x9b, + 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x69, 0x8b, 0xdf, 0xf8, 0x1e, 0x37, 0x8b, + 0xfb, 0xca, 0xfc, 0x18, 0x81, 0x5c, 0xf7, 0xa3, 0x8b, 0x05, 0x93, 0xb4, + 0x15, 0xfb, 0x7b, 0x8b, 0xf7, 0xaf, 0xf7, 0xf5, 0xa2, 0x8b, 0x40, 0xfb, + 0xf5, 0x05, 0x0e, 0xf7, 0xca, 0xf8, 0xc7, 0x15, 0xf7, 0x86, 0x06, 0x9f, + 0x97, 0x94, 0x9b, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0xae, 0x8b, 0x52, + 0xfb, 0xa1, 0x05, 0x8a, 0x89, 0x8b, 0x88, 0x8b, 0x89, 0x8c, 0x82, 0x91, + 0x85, 0x93, 0x8b, 0x91, 0x8b, 0x90, 0x8d, 0x98, 0x91, 0xb9, 0xa0, 0xba, + 0x97, 0xb3, 0x8b, 0xd1, 0x8b, 0xb7, 0x60, 0x8b, 0x46, 0x8b, 0x63, 0x7c, + 0x5e, 0x72, 0x64, 0x08, 0x64, 0x50, 0x4f, 0x6a, 0x47, 0x8b, 0x52, 0x8b, + 0x59, 0xa2, 0x64, 0xb7, 0x85, 0x92, 0x87, 0x8d, 0x86, 0x8b, 0x7e, 0x8b, + 0x7f, 0x7f, 0x8b, 0x7f, 0x8b, 0x7e, 0x9f, 0x77, 0xab, 0x75, 0xb0, 0x72, + 0xb6, 0x7e, 0xba, 0x8b, 0x08, 0xf7, 0x1d, 0xf7, 0x0b, 0xf7, 0x0f, 0xf7, + 0x22, 0xe3, 0x52, 0xc4, 0x35, 0x1f, 0x61, 0x8b, 0x64, 0x82, 0x53, 0x76, + 0x08, 0xb5, 0xf7, 0x5a, 0x05, 0x0e, 0xf7, 0x78, 0xf7, 0x86, 0x15, 0x96, + 0xd7, 0x9d, 0xbe, 0xac, 0xbe, 0xc6, 0xe5, 0xf7, 0x01, 0xce, 0xe3, 0x8b, + 0x9e, 0x8b, 0x9c, 0x88, 0x94, 0x86, 0x93, 0x86, 0x8f, 0x8a, 0x90, 0x8b, + 0x08, 0x97, 0x96, 0x97, 0x97, 0x9c, 0x6a, 0x99, 0x65, 0x1f, 0x39, 0x8b, + 0x33, 0x65, 0x44, 0x48, 0x37, 0x3c, 0x58, 0xfb, 0x12, 0x8b, 0xfb, 0x15, + 0x08, 0xfb, 0x0b, 0xc5, 0x40, 0xe6, 0xf7, 0x04, 0xf6, 0xf7, 0x06, 0xf7, + 0x0c, 0xe0, 0x54, 0xc7, 0x3e, 0x1e, 0x44, 0x8b, 0x4d, 0x63, 0x50, 0x39, + 0x08, 0x85, 0x55, 0x15, 0xad, 0xb7, 0x9a, 0x9d, 0x9d, 0x9b, 0xb3, 0xb0, + 0xb7, 0x9f, 0xb2, 0x8b, 0x08, 0xc3, 0xb5, 0x5b, 0x4c, 0x2b, 0x3a, 0x31, + 0x35, 0x1f, 0x4f, 0x8b, 0x66, 0xab, 0x7b, 0xcc, 0x86, 0xa1, 0x8a, 0x8e, + 0x89, 0xb3, 0x08, 0x0e, 0xf8, 0xbd, 0xf8, 0xb5, 0x15, 0xfb, 0xa1, 0xfc, + 0x95, 0x05, 0x87, 0x83, 0x89, 0x86, 0x8b, 0x86, 0x8b, 0x83, 0x92, 0x84, + 0x94, 0x8b, 0x08, 0x96, 0x8b, 0x91, 0x90, 0x93, 0x9b, 0x08, 0xf7, 0xa5, + 0xf8, 0x9b, 0x99, 0xcc, 0xfc, 0x09, 0x8b, 0x7b, 0x3f, 0x05, 0x8a, 0x86, + 0x8a, 0x86, 0x8b, 0x88, 0x8b, 0x83, 0x93, 0x84, 0x93, 0x8b, 0x99, 0x8b, + 0x94, 0x94, 0x8f, 0x9e, 0x08, 0x92, 0xae, 0xf7, 0xb8, 0x8b, 0x05, 0x87, + 0x79, 0x05, 0x0e, 0xf8, 0x4d, 0xf7, 0xcd, 0x15, 0xad, 0x9a, 0x9b, 0x95, + 0x9e, 0x9a, 0xb5, 0xae, 0xa3, 0xbb, 0x8b, 0xba, 0x08, 0xd9, 0x4e, 0xc4, + 0x38, 0xfb, 0x01, 0x20, 0x2b, 0x29, 0x1e, 0x8b, 0x5b, 0xa0, 0x6b, 0xc1, + 0x6c, 0x2d, 0x64, 0x55, 0x47, 0x8b, 0x3d, 0x08, 0x38, 0xcb, 0x4f, 0xe4, + 0xf7, 0x08, 0xf7, 0x04, 0xf1, 0xf4, 0x1e, 0x8b, 0xbf, 0x6f, 0xb4, 0x54, + 0xa7, 0x08, 0x78, 0xf7, 0x9c, 0x15, 0xce, 0xb8, 0x61, 0x4d, 0x41, 0x3e, + 0x49, 0x34, 0x4a, 0x5b, 0xb4, 0xc2, 0xd6, 0xdc, 0xd4, 0xdf, 0x1f, 0x4e, + 0xfb, 0xb0, 0x15, 0xd4, 0xbb, 0x60, 0x49, 0x3a, 0x35, 0x3e, 0x30, 0x45, + 0x59, 0xb8, 0xcb, 0xdf, 0xde, 0xd5, 0xe8, 0x1f, 0x0e, 0xf8, 0xb5, 0xf7, + 0xfd, 0x15, 0x88, 0x76, 0x8b, 0x8b, 0x8a, 0x85, 0x82, 0x57, 0x75, 0x52, + 0x70, 0x61, 0x50, 0x31, 0xfb, 0x01, 0x48, 0x33, 0x8b, 0x78, 0x8b, 0x7a, + 0x8e, 0x82, 0x90, 0x83, 0x90, 0x87, 0x8c, 0x86, 0x8b, 0x08, 0x7f, 0x80, + 0x7f, 0x7f, 0x7a, 0xac, 0x7d, 0xb1, 0x1f, 0xdd, 0x8b, 0xe3, 0xb1, 0xd2, + 0xce, 0xdf, 0xda, 0xbe, 0xf7, 0x12, 0x8b, 0xf7, 0x15, 0x08, 0xf7, 0x0b, + 0x51, 0xd6, 0x30, 0xfb, 0x04, 0x20, 0xfb, 0x06, 0xfb, 0x0c, 0x36, 0xc2, + 0x4f, 0xd8, 0x1e, 0xd2, 0x8b, 0xca, 0xb3, 0xc5, 0xdd, 0x08, 0x91, 0xc1, + 0x15, 0x69, 0x5f, 0x7c, 0x79, 0x79, 0x7b, 0x63, 0x66, 0x5f, 0x77, 0x64, + 0x8b, 0x08, 0x53, 0x61, 0xbb, 0xca, 0xeb, 0xdc, 0xe5, 0xe1, 0x1f, 0xc7, + 0x8b, 0xb0, 0x6b, 0x9b, 0x4a, 0x90, 0x76, 0x8c, 0x86, 0x8d, 0x64, 0x08, + 0x0e, 0xf7, 0xd3, 0xf7, 0x08, 0x15, 0x5f, 0x63, 0x66, 0x61, 0x6c, 0xa2, + 0x76, 0xac, 0x1f, 0x96, 0x06, 0xb7, 0xb3, 0xb0, 0xb6, 0xa9, 0x74, 0xa0, + 0x6a, 0x1f, 0x80, 0x06, 0xcb, 0xf7, 0xc1, 0x15, 0x5f, 0x63, 0x65, 0x61, + 0x6c, 0xa2, 0x76, 0xac, 0x1f, 0x96, 0x06, 0xb7, 0xb3, 0xb1, 0xb5, 0xaa, + 0x74, 0xa0, 0x6a, 0x1f, 0x80, 0x06, 0x0e, 0xf7, 0x86, 0xf7, 0x25, 0x15, + 0xfb, 0x0f, 0xfb, 0x8e, 0x05, 0x88, 0x85, 0x89, 0x85, 0x8b, 0x86, 0x8b, + 0x7e, 0x95, 0x81, 0x99, 0x8b, 0x98, 0x8b, 0x93, 0x91, 0x9a, 0x9e, 0x08, + 0xf7, 0x5d, 0xf7, 0x9d, 0xfb, 0x19, 0x8b, 0x05, 0xf7, 0x09, 0xf7, 0xa4, + 0x15, 0x5f, 0x63, 0x65, 0x61, 0x6c, 0xa2, 0x76, 0xac, 0x1f, 0x96, 0x06, + 0xb7, 0xb3, 0xb1, 0xb5, 0xaa, 0x74, 0xa0, 0x6a, 0x1f, 0x80, 0x06, 0x0e, + 0xf7, 0x17, 0xf7, 0xad, 0x15, 0xf8, 0x03, 0xfb, 0x7c, 0x05, 0x90, 0x88, + 0x90, 0x89, 0x8e, 0x8b, 0x90, 0x8b, 0x93, 0x8f, 0x8f, 0x91, 0x08, 0x8d, + 0x8e, 0x05, 0x8e, 0x8f, 0x8d, 0x90, 0x8b, 0x8f, 0x8b, 0x91, 0x89, 0x8e, + 0x84, 0x90, 0x08, 0xfb, 0xcd, 0xf7, 0x59, 0xf8, 0x21, 0xf7, 0x59, 0x05, + 0x96, 0x91, 0x91, 0x92, 0x8b, 0x93, 0x8b, 0x8e, 0x8b, 0x8c, 0x8a, 0x8d, + 0x08, 0x8a, 0x8e, 0x05, 0x89, 0x91, 0x86, 0x8f, 0x84, 0x8b, 0x89, 0x8b, + 0x86, 0x89, 0x85, 0x88, 0x08, 0xfc, 0x67, 0xfb, 0x7c, 0x05, 0x0e, 0xf8, + 0xe5, 0xf7, 0xe2, 0x15, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, + 0x1f, 0xfc, 0x50, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, + 0x1f, 0xf8, 0x50, 0x06, 0x6c, 0xfb, 0x24, 0x15, 0x9f, 0x97, 0x95, 0x9a, + 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfc, 0x50, 0x06, 0x77, 0x7f, 0x82, 0x7b, + 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0x50, 0x06, 0x0e, 0xf8, 0xe0, 0xf7, + 0xad, 0x15, 0xfc, 0x03, 0xf7, 0x7c, 0x05, 0x86, 0x8e, 0x86, 0x8d, 0x88, + 0x8b, 0x86, 0x8b, 0x84, 0x87, 0x86, 0x85, 0x08, 0x89, 0x88, 0x05, 0x88, + 0x88, 0x89, 0x85, 0x8b, 0x87, 0x8b, 0x85, 0x8d, 0x88, 0x92, 0x86, 0x08, + 0xf7, 0xcd, 0xfb, 0x59, 0xfc, 0x21, 0xfb, 0x59, 0x05, 0x80, 0x85, 0x85, + 0x84, 0x8b, 0x83, 0x8b, 0x89, 0x8b, 0x89, 0x8c, 0x89, 0x08, 0x8c, 0x88, + 0x05, 0x8d, 0x85, 0x90, 0x87, 0x92, 0x8b, 0x8d, 0x8b, 0x90, 0x8d, 0x91, + 0x8e, 0x08, 0xf8, 0x67, 0xf7, 0x7c, 0x05, 0x0e, 0xf8, 0x0b, 0xf7, 0x8b, + 0x15, 0xd0, 0xa9, 0xb0, 0x9f, 0xad, 0xa5, 0xb4, 0xac, 0xa4, 0xbd, 0x8b, + 0xbc, 0x8b, 0xd7, 0x53, 0xb9, 0x2f, 0x8b, 0x57, 0x8b, 0x6a, 0x83, 0x46, + 0x6f, 0x7c, 0x85, 0x86, 0x89, 0x7f, 0x87, 0x08, 0x7d, 0x47, 0x05, 0x8a, + 0x86, 0x8a, 0x87, 0x8b, 0x89, 0x8b, 0x82, 0x92, 0x84, 0x95, 0x8b, 0x98, + 0x8b, 0x94, 0x94, 0x8f, 0x9d, 0x08, 0x93, 0xb4, 0x05, 0xc5, 0xa5, 0xad, + 0x93, 0xb8, 0x8b, 0xd4, 0x8b, 0xba, 0x67, 0x8b, 0x53, 0x8b, 0x48, 0x52, + 0x5a, 0xfb, 0x22, 0x55, 0x08, 0x7c, 0x47, 0x8a, 0x7f, 0x05, 0x83, 0x92, + 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, 0x94, 0xb4, + 0x05, 0x45, 0xfb, 0x36, 0x15, 0x66, 0x6c, 0x70, 0x69, 0x73, 0x9d, 0x7c, + 0xa8, 0x1f, 0xa7, 0x06, 0xb0, 0xaa, 0xa6, 0xac, 0xa4, 0x7a, 0x9a, 0x6d, + 0x1f, 0x6f, 0x06, 0x0e, 0xf8, 0x55, 0xf7, 0x25, 0x15, 0xac, 0x06, 0x9f, + 0x97, 0x94, 0x9b, 0x1f, 0x8b, 0x95, 0x86, 0x8f, 0x80, 0x8d, 0x08, 0xc6, + 0xf7, 0xa9, 0x05, 0x8e, 0x97, 0x8c, 0x97, 0x8b, 0x97, 0x8b, 0xd6, 0x58, + 0xbd, 0x3e, 0x8b, 0xfb, 0x05, 0x8b, 0x21, 0xfb, 0x03, 0x6b, 0xfb, 0x2c, + 0x08, 0x68, 0xfb, 0x37, 0x05, 0x86, 0x71, 0x88, 0x71, 0x8b, 0x72, 0x8b, + 0x58, 0x9a, 0x59, 0xa3, 0x6a, 0xa3, 0x6a, 0xaf, 0x7b, 0xbb, 0x8b, 0x08, + 0xd9, 0xe1, 0xae, 0xab, 0x93, 0x84, 0x92, 0x82, 0x1f, 0x84, 0x8b, 0x89, + 0x8a, 0x7e, 0x81, 0x73, 0x79, 0x5f, 0x7f, 0x60, 0x8b, 0x66, 0x8b, 0x6f, + 0x95, 0x79, 0x9f, 0x74, 0xa5, 0x7d, 0xba, 0x8b, 0xbc, 0x8b, 0xa0, 0x8e, + 0xa3, 0x8f, 0xa1, 0x08, 0xad, 0xf7, 0x34, 0x05, 0xa7, 0xf7, 0x18, 0xdf, + 0xe8, 0xe6, 0x8b, 0xc5, 0x8b, 0xaf, 0x67, 0x8b, 0x52, 0x8b, 0x81, 0x8a, + 0x83, 0x89, 0x82, 0x08, 0x81, 0x5c, 0x05, 0x6e, 0x8b, 0x7b, 0x89, 0x74, + 0x85, 0x39, 0x73, 0x50, 0x47, 0x8b, 0x44, 0x8b, 0x51, 0xb9, 0x63, 0xcc, + 0x8b, 0x96, 0x8b, 0x96, 0x8c, 0x9f, 0x8d, 0x08, 0x8a, 0x86, 0x05, 0x95, + 0xba, 0x15, 0x7e, 0x88, 0x7d, 0x8a, 0x7f, 0x8b, 0x08, 0x5a, 0x6b, 0xa5, + 0xb4, 0xce, 0xd2, 0xc1, 0xe3, 0x1f, 0x64, 0xfb, 0x4c, 0x05, 0x0e, 0xf8, + 0x68, 0xf7, 0x50, 0x15, 0xa4, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x77, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x30, 0x06, 0x9f, 0x97, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x66, 0x8b, 0x34, 0xf8, 0x9e, + 0xfb, 0x5f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, + 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0xad, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2b, 0x06, 0x9e, + 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x3c, 0x8b, 0xe1, 0xf7, + 0x27, 0xf7, 0x9d, 0x8b, 0x05, 0x85, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, + 0x3e, 0xf7, 0xb9, 0x9a, 0x8b, 0xbd, 0xfb, 0xb9, 0x05, 0x0e, 0xf7, 0x19, + 0xb4, 0x15, 0x55, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, + 0x1f, 0xf7, 0xc7, 0x06, 0xf1, 0xed, 0xe3, 0xe8, 0x1f, 0x8b, 0xc0, 0x6a, + 0xb2, 0x48, 0xa4, 0x08, 0xd8, 0xb0, 0xb0, 0xbb, 0x8b, 0xc9, 0x08, 0xd1, + 0x51, 0xbb, 0x36, 0x1e, 0xfb, 0x96, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, + 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x05, 0x25, 0xfc, 0x75, 0x05, 0xee, + 0xf7, 0xa4, 0x15, 0xb7, 0xf7, 0x65, 0xf7, 0x38, 0x8b, 0x05, 0xaf, 0x8b, + 0xa4, 0x83, 0x9f, 0x79, 0x9c, 0x7b, 0x96, 0x74, 0x8b, 0x77, 0x08, 0x46, + 0x40, 0x54, 0x2c, 0x1e, 0xfb, 0x27, 0x06, 0x51, 0xfb, 0xa4, 0x15, 0xbc, + 0xf7, 0x7b, 0xf7, 0x29, 0x8b, 0x05, 0xc8, 0x8b, 0xab, 0x84, 0xa7, 0x78, + 0xa4, 0x7a, 0x9c, 0x6f, 0x8b, 0x71, 0x08, 0x44, 0x43, 0x4c, 0x3a, 0x1e, + 0xfb, 0x64, 0x06, 0x0e, 0xf8, 0xde, 0xf8, 0x8f, 0x15, 0x66, 0xb8, 0x54, + 0xa3, 0x49, 0x8b, 0x48, 0x8b, 0x4a, 0x71, 0x55, 0x5b, 0x55, 0x5c, 0x60, + 0x46, 0x7e, 0x4e, 0x08, 0x7a, 0x38, 0x05, 0x88, 0x7c, 0x89, 0x7c, 0x8b, + 0x7b, 0x8b, 0xfb, 0x0c, 0xe6, 0x2f, 0xf7, 0x0a, 0x8b, 0xd1, 0x8b, 0xd3, + 0xa9, 0xca, 0xc0, 0xa6, 0xa3, 0x92, 0x94, 0x8b, 0x96, 0x8b, 0x93, 0x85, + 0x91, 0x81, 0x8b, 0x83, 0x8b, 0x87, 0x89, 0x83, 0x83, 0x08, 0x47, 0x4b, + 0x52, 0x71, 0x46, 0x8b, 0x26, 0x8b, 0x40, 0xd7, 0x8b, 0xf1, 0x8b, 0x99, + 0x8d, 0x9b, 0x8e, 0x9a, 0x08, 0x9a, 0xd2, 0x05, 0xa4, 0xf7, 0x0b, 0xf7, + 0x04, 0xed, 0xf7, 0x02, 0x8b, 0xb8, 0x8b, 0xbe, 0x79, 0xa2, 0x73, 0x93, + 0x83, 0xa3, 0x66, 0x8b, 0x88, 0x08, 0x87, 0x65, 0x05, 0x91, 0x82, 0x90, + 0x88, 0x91, 0x8b, 0x98, 0x8b, 0x95, 0x95, 0x8e, 0x9d, 0x08, 0xa3, 0xf7, + 0x04, 0x05, 0x8c, 0x90, 0x8c, 0x90, 0x8b, 0x8d, 0x08, 0x94, 0x84, 0x91, + 0x81, 0x1e, 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x85, 0x6e, 0x05, + 0x0e, 0xf7, 0x05, 0xb4, 0x15, 0x69, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x70, 0x06, 0xf7, 0x15, 0x8b, 0xf7, 0x11, + 0xf7, 0x04, 0xa9, 0xf7, 0x22, 0x08, 0x97, 0xc3, 0x05, 0x8f, 0x9e, 0x8d, + 0x9e, 0x8b, 0x9f, 0x08, 0xf7, 0x08, 0x42, 0xda, 0xfb, 0x01, 0x1e, 0xfb, + 0x70, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xad, + 0x8b, 0x25, 0xfc, 0x75, 0x05, 0xb4, 0x16, 0xf1, 0xf8, 0x75, 0xf7, 0x23, + 0x8b, 0x05, 0xc1, 0x8b, 0xae, 0x7c, 0xa5, 0x68, 0xa3, 0x6b, 0x98, 0x62, + 0x8b, 0x61, 0x8b, 0x80, 0x89, 0x7d, 0x89, 0x7d, 0x08, 0x7b, 0x42, 0x05, + 0x74, 0x21, 0xfb, 0x01, 0x29, 0x2b, 0x8b, 0x08, 0xfb, 0x29, 0x06, 0x0e, + 0xf7, 0x73, 0xf7, 0xa4, 0x15, 0xf7, 0x25, 0x8b, 0x81, 0x5e, 0x8a, 0x7f, + 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, + 0x08, 0xa7, 0xf7, 0x17, 0x05, 0x8c, 0x8f, 0x8c, 0x91, 0x8b, 0x8d, 0x8b, + 0x93, 0x84, 0x92, 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, + 0x82, 0x5e, 0xfb, 0x25, 0x8b, 0xb7, 0xf7, 0x65, 0xf7, 0xb9, 0x8b, 0x76, + 0x29, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, + 0x94, 0x8e, 0x9d, 0x08, 0xa9, 0xf7, 0x1f, 0xfc, 0x41, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x25, 0xfc, + 0x75, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, + 0x1f, 0xf8, 0x56, 0x8b, 0xad, 0xf7, 0x34, 0x05, 0x8c, 0x90, 0x8c, 0x8f, + 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, + 0x87, 0x79, 0x08, 0x72, 0xfb, 0x0b, 0xfb, 0xce, 0x8b, 0xbc, 0xf7, 0x7b, + 0x05, 0x0e, 0xf7, 0x73, 0xf7, 0xa4, 0x15, 0xf7, 0x25, 0x8b, 0x81, 0x5e, + 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, + 0x8e, 0x9d, 0x08, 0xa7, 0xf7, 0x17, 0x05, 0x8c, 0x8f, 0x8c, 0x91, 0x8b, + 0x8d, 0x8b, 0x94, 0x84, 0x91, 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, 0x87, + 0x79, 0x08, 0x82, 0x5e, 0xfb, 0x25, 0x8b, 0xb7, 0xf7, 0x65, 0xf7, 0xce, + 0x8b, 0x76, 0x29, 0x8a, 0x7f, 0x05, 0x83, 0x93, 0x84, 0x93, 0x1e, 0x99, + 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, 0xa9, 0xf7, 0x1f, 0xfc, 0x56, 0x8b, + 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, + 0x25, 0xfc, 0x75, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0x7e, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, + 0x90, 0x7a, 0x1f, 0xfb, 0x1e, 0x8b, 0xbc, 0xf7, 0x7b, 0x05, 0x0e, 0xf8, + 0xc9, 0xf7, 0x65, 0x15, 0x99, 0x06, 0x9f, 0x98, 0x95, 0x9a, 0x96, 0x84, + 0x90, 0x7a, 0x1f, 0xfb, 0x56, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0x1f, 0x8b, 0x6b, 0xfb, 0x2a, 0x05, 0x4d, 0x71, + 0x66, 0x83, 0x57, 0x8b, 0xfb, 0x0b, 0x8b, 0x43, 0xc8, 0x8b, 0xf0, 0x8b, + 0x9e, 0x8d, 0x9d, 0x8f, 0x9f, 0x08, 0x9b, 0xd4, 0x05, 0xa4, 0xf7, 0x0d, + 0xf7, 0x08, 0xed, 0xf7, 0x07, 0x8b, 0xb3, 0x8b, 0xb8, 0x80, 0xa3, 0x7a, + 0x9a, 0x82, 0xa3, 0x6f, 0x8a, 0x85, 0x08, 0x88, 0x67, 0x05, 0x91, 0x83, + 0x90, 0x87, 0x90, 0x8b, 0x98, 0x8b, 0x95, 0x95, 0x8f, 0x9d, 0x08, 0x9e, + 0xe6, 0x05, 0x8d, 0x93, 0x8b, 0x8c, 0x8b, 0x8e, 0x08, 0x93, 0x84, 0x92, + 0x81, 0x1e, 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x88, 0x7d, 0x05, + 0x66, 0xaf, 0x58, 0x9d, 0x49, 0x8b, 0xfb, 0x21, 0x8b, 0xfb, 0x19, 0xfb, + 0x05, 0x6c, 0xfb, 0x25, 0x08, 0x7b, 0x41, 0x05, 0x86, 0x75, 0x89, 0x75, + 0x8b, 0x76, 0x8b, 0xfb, 0x0c, 0xe0, 0x40, 0xf7, 0x1d, 0x8b, 0xc9, 0x8b, + 0xd1, 0x9d, 0xcd, 0xad, 0x08, 0xb0, 0xf7, 0x41, 0x05, 0x0e, 0xf8, 0x83, + 0xf7, 0xa4, 0x15, 0x5a, 0xfb, 0x7b, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x21, 0x06, 0x9e, 0x98, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0x5e, 0x8b, 0xf1, 0xf8, 0x75, 0xa4, + 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, + 0x0c, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xc1, + 0x8b, 0x5f, 0xfb, 0x65, 0xfb, 0xa2, 0x8b, 0xb7, 0xf7, 0x65, 0xc1, 0x8b, + 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x0c, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xa4, 0x8b, + 0x25, 0xfc, 0x75, 0x5d, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9c, 0x1f, 0xf7, 0x20, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7a, 0x1f, 0x55, 0x8b, 0xbc, 0xf7, 0x7b, 0xf7, 0xa2, 0x8b, 0x05, + 0x0e, 0xf8, 0x43, 0xf8, 0x9e, 0x15, 0xf7, 0x20, 0x06, 0x9e, 0x98, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0xd4, 0x06, 0x78, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x1f, 0x8b, 0x25, 0xfc, 0x75, + 0xfb, 0x20, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, + 0x1f, 0xf7, 0xd4, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, + 0x1f, 0xfb, 0x1f, 0x8b, 0xf1, 0xf8, 0x75, 0x05, 0x0e, 0xf8, 0xcf, 0xf8, + 0x9e, 0x15, 0xeb, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, + 0x1f, 0xfb, 0xbc, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, + 0x1f, 0xf7, 0x32, 0x8b, 0x3f, 0xfb, 0xf9, 0x05, 0x7b, 0x3d, 0x3d, 0x4d, + 0x39, 0x8b, 0x59, 0x8b, 0x61, 0xa1, 0x62, 0xb9, 0x08, 0xa7, 0xf7, 0x16, + 0x8c, 0x97, 0x05, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x83, 0x82, + 0x87, 0x79, 0x08, 0x6b, 0xfb, 0x29, 0x05, 0xc5, 0x4a, 0xba, 0x72, 0xcb, + 0x8b, 0xf1, 0x8b, 0xf2, 0xde, 0xa0, 0xed, 0x08, 0xd7, 0xf7, 0xf9, 0x05, + 0x0e, 0xf7, 0x68, 0xf7, 0x71, 0x15, 0xec, 0xd4, 0x05, 0xe3, 0x6c, 0xaa, + 0x50, 0xaa, 0xfb, 0x60, 0x08, 0xe1, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, + 0x84, 0x90, 0x7b, 0x1f, 0x53, 0x06, 0x69, 0xf7, 0x54, 0x70, 0xbe, 0x33, + 0xb3, 0x08, 0xf7, 0x9c, 0xf7, 0x5a, 0x9c, 0x8b, 0x05, 0x9f, 0x97, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0x0b, 0x06, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xb8, 0x8b, 0xfb, 0xe1, 0xfb, 0x8d, + 0xc0, 0xf7, 0x8d, 0xd6, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x79, 0x1f, 0xfb, 0x3d, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, + 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x25, 0xfc, 0x75, 0x55, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x3e, 0x06, 0x9e, + 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0x41, 0x8b, 0xb1, 0xf7, + 0x48, 0x05, 0x0e, 0xf7, 0xe6, 0xf8, 0x9e, 0x15, 0xeb, 0x06, 0x9f, 0x97, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x7e, 0x06, 0x78, 0x7f, + 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xeb, 0x8b, 0x25, 0xfc, 0x75, + 0x2b, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xf8, 0x57, 0x8b, 0xb5, 0xf7, 0x5d, 0x05, 0x8c, 0x90, 0x8c, 0x90, 0x8b, + 0x8e, 0x8b, 0x93, 0x84, 0x91, 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, 0x87, + 0x79, 0x08, 0x69, 0xfb, 0x34, 0xfb, 0xa4, 0x8b, 0xf1, 0xf8, 0x75, 0x05, + 0x0e, 0xf7, 0xfe, 0xf7, 0x3d, 0x15, 0xf7, 0x7c, 0xf7, 0xf5, 0x93, 0x8b, + 0x25, 0xfc, 0x75, 0x40, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7c, 0x7f, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0x29, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, + 0x90, 0x7b, 0x1f, 0x69, 0x8b, 0xf1, 0xf8, 0x75, 0xa4, 0x8b, 0x05, 0x9f, + 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x27, 0x8b, 0xfb, 0x78, + 0xfb, 0xf0, 0x38, 0xf7, 0xf0, 0x28, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, + 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xa4, 0x8b, 0x25, 0xfc, 0x75, 0x69, 0x8b, + 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2a, + 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0x41, 0x8b, + 0xf1, 0xf8, 0x75, 0x93, 0x8b, 0xdf, 0xfb, 0xf5, 0xb9, 0x8b, 0x05, 0x0e, + 0xf8, 0x89, 0x16, 0xf7, 0x03, 0xf8, 0x9e, 0xad, 0x8b, 0x05, 0x9f, 0x97, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x2a, 0x06, 0x77, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x29, 0xfc, 0x63, + 0xfb, 0x5a, 0xf8, 0x8c, 0x21, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, + 0x91, 0x86, 0x9c, 0x1f, 0xc1, 0x8b, 0x25, 0xfc, 0x75, 0x69, 0x8b, 0x05, + 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2a, 0x06, + 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x84, 0x8f, 0x7a, 0x1f, 0x41, 0x8b, 0xed, + 0xf8, 0x63, 0xf7, 0x5a, 0xfc, 0x8c, 0xbf, 0x8b, 0x05, 0x0e, 0xf8, 0x3a, + 0xf8, 0xd4, 0x15, 0xfb, 0x38, 0xfb, 0x30, 0xfb, 0x48, 0xfb, 0x51, 0xfb, + 0x19, 0xda, 0x31, 0xf7, 0x07, 0xf7, 0x39, 0xf7, 0x2f, 0xf7, 0x48, 0xf7, + 0x55, 0xf7, 0x15, 0x3b, 0xe5, 0xfb, 0x06, 0x1f, 0x84, 0x62, 0x15, 0xe7, + 0xce, 0x3b, 0xfb, 0x02, 0xfb, 0x38, 0xfb, 0x19, 0xfb, 0x30, 0xfb, 0x1f, + 0x30, 0x48, 0xdc, 0xf7, 0x02, 0xf7, 0x36, 0xf7, 0x19, 0xf7, 0x31, 0xf7, + 0x1e, 0x1f, 0x0e, 0xf7, 0x6a, 0xf7, 0x7b, 0x15, 0xf7, 0x18, 0x06, 0xf7, + 0x14, 0xf7, 0x05, 0xe8, 0xf6, 0xd8, 0x4a, 0xc2, 0x2f, 0x1f, 0xfb, 0x84, + 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xc1, 0x8b, + 0x25, 0xfc, 0x75, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0x7d, 0x06, 0x9f, 0x98, 0x95, 0x9a, 0x96, 0x84, + 0x90, 0x7a, 0x1f, 0xfb, 0x1e, 0x8b, 0xb3, 0xf7, 0x52, 0x05, 0x94, 0xb4, + 0x15, 0xc0, 0xf7, 0x8e, 0xf7, 0x29, 0x8b, 0x05, 0xd0, 0xbe, 0x60, 0x51, + 0x3d, 0x31, 0x44, 0x29, 0x1f, 0xfb, 0x1a, 0x06, 0x0e, 0xf7, 0xc1, 0x7b, + 0x15, 0xf7, 0x38, 0x90, 0xf7, 0x2b, 0xf7, 0x45, 0x8b, 0xf7, 0x50, 0x08, + 0xf7, 0x18, 0x3c, 0xe5, 0xfb, 0x07, 0xfb, 0x38, 0xfb, 0x30, 0xfb, 0x48, + 0xfb, 0x52, 0x1e, 0x8b, 0xfb, 0x01, 0xc5, 0x34, 0xe1, 0x77, 0x08, 0x23, + 0x4a, 0x05, 0x81, 0x85, 0x86, 0x83, 0x8b, 0x83, 0x8b, 0x81, 0x91, 0x84, + 0x95, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, 0x8f, 0x8c, 0xba, 0x97, 0xd0, 0x96, + 0xa8, 0x8b, 0xa4, 0x8b, 0x9b, 0x88, 0xa4, 0x81, 0x08, 0xa6, 0x81, 0x96, + 0x88, 0x9b, 0x8b, 0xa4, 0x8b, 0xae, 0x96, 0xab, 0x9d, 0x9c, 0x95, 0x91, + 0x91, 0x8b, 0x96, 0x8b, 0x95, 0x84, 0x91, 0x82, 0x8b, 0x87, 0x8b, 0x87, + 0x8a, 0x86, 0x88, 0x67, 0x77, 0x79, 0x84, 0x76, 0x8b, 0x08, 0x7e, 0x8b, + 0x84, 0x8d, 0x74, 0x94, 0x08, 0x70, 0x96, 0x75, 0x8f, 0x6d, 0x8b, 0x76, + 0x8b, 0x7b, 0x89, 0x6b, 0x85, 0x08, 0xca, 0xb3, 0x05, 0xf7, 0x06, 0xf8, + 0xbb, 0x15, 0xe7, 0xce, 0x3b, 0xfb, 0x01, 0xfb, 0x39, 0xfb, 0x19, 0xfb, + 0x30, 0xfb, 0x1f, 0x30, 0x48, 0xdc, 0xf7, 0x02, 0xf7, 0x37, 0xf7, 0x19, + 0xf7, 0x30, 0xf7, 0x1e, 0x1f, 0x0e, 0xf7, 0x6e, 0xf7, 0x8f, 0x15, 0xf7, + 0x19, 0x06, 0xcf, 0x68, 0xac, 0x55, 0xc0, 0xfb, 0x36, 0x08, 0xc4, 0x06, + 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0x6d, 0x06, 0x58, + 0xf7, 0x22, 0x76, 0xae, 0x55, 0xb7, 0xf7, 0x06, 0xb0, 0xc6, 0xc5, 0x8b, + 0xd8, 0x08, 0xd4, 0x4a, 0xc3, 0x37, 0x1e, 0xfb, 0x8d, 0x06, 0x78, 0x7f, + 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xc1, 0x8b, 0x25, 0xfc, 0x75, + 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x3e, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x84, 0x8f, 0x7a, 0x1f, + 0x41, 0x8b, 0xb7, 0xf7, 0x66, 0x05, 0x94, 0xb4, 0x15, 0xbc, 0xf7, 0x7a, + 0xf7, 0x2d, 0x8b, 0x05, 0xcb, 0xbf, 0x60, 0x55, 0x45, 0x2a, 0x4c, 0x20, + 0x1f, 0xfb, 0x06, 0x06, 0x0e, 0xf8, 0xbf, 0xf8, 0x99, 0x15, 0x6b, 0xb4, + 0x5f, 0x9e, 0x50, 0x8b, 0xfb, 0x07, 0x8b, 0x23, 0x33, 0x8b, 0x2a, 0x8b, + 0x6f, 0x98, 0x6d, 0x9f, 0x7a, 0xa4, 0x75, 0xad, 0x7f, 0xcf, 0x7f, 0xd0, + 0x7f, 0x9f, 0x85, 0x9f, 0x7b, 0x9c, 0x7e, 0x98, 0x72, 0x8b, 0x75, 0x08, + 0x39, 0x31, 0x44, 0x24, 0x1e, 0x64, 0x8b, 0x5d, 0x98, 0x76, 0x9d, 0x7e, + 0x95, 0x6f, 0xb1, 0x8b, 0x91, 0x08, 0x8f, 0xb9, 0x05, 0x86, 0x93, 0x86, + 0x8f, 0x85, 0x8b, 0x7e, 0x8b, 0x81, 0x81, 0x87, 0x79, 0x08, 0x74, 0xfb, + 0x04, 0x05, 0x8a, 0x87, 0x8a, 0x85, 0x8b, 0x89, 0x08, 0x83, 0x92, 0x84, + 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8f, 0x9d, 0x08, 0x91, 0xa8, 0x05, + 0xaa, 0x5c, 0xc2, 0x71, 0xd1, 0x8b, 0xca, 0x8b, 0xd4, 0xa6, 0xb8, 0xb3, + 0xb1, 0xad, 0xa4, 0xc0, 0x8b, 0xbb, 0x8b, 0xab, 0x7a, 0xae, 0x74, 0x9c, + 0x72, 0x9d, 0x70, 0x94, 0x40, 0x98, 0x4e, 0x95, 0x72, 0x94, 0x77, 0x9b, + 0x08, 0x7c, 0x97, 0x80, 0xa2, 0x8b, 0x9f, 0x8b, 0xd3, 0xdb, 0xcc, 0xe5, + 0x8b, 0xae, 0x8b, 0xb3, 0x7e, 0x9c, 0x7a, 0x94, 0x82, 0xa1, 0x6a, 0x8b, + 0x86, 0x08, 0x88, 0x61, 0x05, 0x91, 0x82, 0x90, 0x88, 0x91, 0x8b, 0x97, + 0x8b, 0x95, 0x96, 0x8e, 0x9c, 0x08, 0xa1, 0xf2, 0x05, 0x8d, 0x92, 0x8b, + 0x8d, 0x8b, 0x8e, 0x08, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x82, + 0x82, 0x87, 0x79, 0x08, 0x87, 0x78, 0x05, 0x0e, 0xf7, 0xde, 0xb4, 0x15, + 0xf1, 0xf8, 0x75, 0xf7, 0x3a, 0x8b, 0x7c, 0x42, 0x05, 0x8a, 0x89, 0x8b, + 0x80, 0x8b, 0x8a, 0x8c, 0x84, 0x94, 0x84, 0x91, 0x8b, 0x98, 0x8b, 0x94, + 0x95, 0x8f, 0x9d, 0x08, 0xa3, 0xf7, 0x06, 0xfc, 0x5c, 0x8b, 0x72, 0xfb, + 0x06, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, + 0x94, 0x8f, 0x9d, 0x08, 0x9a, 0xd4, 0xf7, 0x3b, 0x8b, 0x25, 0xfc, 0x75, + 0x22, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x8f, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, + 0x22, 0x06, 0x0e, 0xf8, 0xf6, 0xf8, 0x9e, 0x15, 0xad, 0x06, 0x9f, 0x97, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x29, 0x06, 0x77, 0x7f, + 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x44, 0xfb, 0xe5, + 0x05, 0x78, 0x31, 0x36, 0x45, 0x32, 0x8b, 0x40, 0x8b, 0x57, 0xbe, 0x8b, + 0xd6, 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0x97, 0x08, 0xd2, 0xf7, 0xe5, 0xd6, + 0x8b, 0x05, 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7b, 0x1f, 0xfb, + 0x2a, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xac, + 0x8b, 0x44, 0xfb, 0xe5, 0x05, 0x88, 0x7c, 0x89, 0x7b, 0x8b, 0x7d, 0x8b, + 0x2e, 0xcc, 0x4c, 0xeb, 0x8b, 0xf7, 0x04, 0x8b, 0xf5, 0xe3, 0xa3, 0xf7, + 0x05, 0x08, 0xd2, 0xf7, 0xe5, 0x05, 0x0e, 0xf7, 0xa0, 0x16, 0xc3, 0x8b, + 0xf7, 0xd4, 0xf8, 0x9e, 0xaa, 0x8b, 0x05, 0x9f, 0x97, 0x94, 0x9b, 0x97, + 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x2b, 0x06, 0x78, 0x7f, 0x82, 0x7b, 0x80, + 0x91, 0x86, 0x9c, 0x1f, 0xda, 0x8b, 0xfb, 0xbd, 0xfc, 0x75, 0x89, 0x8b, + 0x38, 0xf8, 0x75, 0xd7, 0x8b, 0x05, 0x9f, 0x97, 0x94, 0x9b, 0x97, 0x85, + 0x8f, 0x79, 0x1f, 0xfb, 0x2a, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x91, + 0x86, 0x9c, 0x1f, 0xaa, 0x8b, 0xe5, 0xfc, 0x9e, 0x05, 0x0e, 0xf7, 0x0e, + 0x16, 0xca, 0x8b, 0xf7, 0x5c, 0xf8, 0x24, 0xa6, 0xfc, 0x24, 0xcb, 0x8b, + 0xf7, 0x41, 0xf8, 0x9e, 0x9a, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, + 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x2a, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xeb, 0x8b, 0xfb, 0x32, 0xfc, 0x70, 0x71, 0xf8, + 0x1c, 0x4d, 0x8b, 0xfb, 0x57, 0xfc, 0x1c, 0xb8, 0xf8, 0x70, 0xe9, 0x8b, + 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0x29, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0x9a, 0x8b, + 0x58, 0xfc, 0x9e, 0x05, 0x0e, 0xf8, 0x16, 0xf7, 0xb4, 0x15, 0xf7, 0x79, + 0xf7, 0x7e, 0x9a, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, + 0x7a, 0x1f, 0xfb, 0x03, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xb9, 0x8b, 0xfb, 0x59, 0xfb, 0x5d, 0xfb, 0x04, 0xf7, 0x5d, + 0xb6, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0xfb, 0x03, 0x06, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0x9a, 0x8b, 0xf7, 0x16, 0xfb, 0x7e, 0xfb, 0x85, 0xfb, 0x8b, 0x7a, 0x8b, + 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x17, + 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x4a, 0x8b, + 0xf7, 0x66, 0xf7, 0x6a, 0xf7, 0x0c, 0xfb, 0x6a, 0x4d, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x18, 0x06, 0x9e, + 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x7a, 0x8b, 0xfb, 0x1f, + 0xf7, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf7, 0x92, 0x15, 0xf7, 0x7e, 0xf7, + 0xa0, 0xa2, 0x8b, 0x05, 0x9e, 0x98, 0x95, 0x99, 0x97, 0x84, 0x90, 0x7b, + 0x1f, 0xfb, 0x02, 0x06, 0x76, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, + 0x1f, 0xb4, 0x8b, 0xfb, 0x5a, 0xfb, 0x77, 0x23, 0xf7, 0x77, 0xb1, 0x8b, + 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x03, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xa3, 0x8b, + 0xf7, 0x0e, 0xfb, 0xa0, 0x5e, 0xfb, 0x69, 0x22, 0x8b, 0x05, 0x77, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x8f, 0x06, 0x9f, 0x97, + 0x95, 0x9a, 0x96, 0x85, 0x90, 0x7a, 0x1f, 0x22, 0x8b, 0xb8, 0xf7, 0x69, + 0x05, 0x0e, 0xf8, 0x85, 0x16, 0xb2, 0xf7, 0x4a, 0x8c, 0x8f, 0x05, 0x8c, + 0x8e, 0x8b, 0x8e, 0x8b, 0x8d, 0x8b, 0x93, 0x84, 0x92, 0x81, 0x8b, 0x7d, + 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x6d, 0xfb, 0x21, 0xfb, 0xcf, 0x8b, + 0x8c, 0x8f, 0xf8, 0x3f, 0xf8, 0x60, 0x97, 0xc5, 0xfb, 0xf1, 0x8b, 0x69, + 0xfb, 0x33, 0x05, 0x89, 0x83, 0x8b, 0x8a, 0x8b, 0x88, 0x8b, 0x82, 0x92, + 0x84, 0x94, 0x8b, 0x99, 0x8b, 0x94, 0x94, 0x8f, 0x9e, 0x08, 0xa4, 0xf7, + 0x0a, 0xf7, 0xa1, 0x8b, 0x8a, 0x88, 0xfc, 0x3d, 0xfc, 0x60, 0x7e, 0x50, + 0xf8, 0x1e, 0x8b, 0x05, 0x0e, 0xf8, 0x4d, 0xf8, 0xc7, 0x15, 0xec, 0x06, + 0x9f, 0x97, 0x94, 0x9b, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x1e, 0x8b, + 0xfb, 0x2f, 0xfd, 0x6c, 0xf7, 0x1e, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, + 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x2a, 0x8b, 0xf7, 0x1d, 0xf9, 0x1a, 0x05, + 0x0e, 0xf7, 0xb8, 0xf9, 0x1e, 0x15, 0x88, 0x99, 0x87, 0x8f, 0x81, 0x8b, + 0x7e, 0x8b, 0x7f, 0x7f, 0x8b, 0x7f, 0x8b, 0x89, 0x8c, 0x86, 0x8c, 0x87, + 0x08, 0xf7, 0x48, 0xfd, 0x4c, 0x05, 0x8e, 0x7d, 0x8f, 0x87, 0x95, 0x8b, + 0x98, 0x8b, 0x97, 0x97, 0x8b, 0x97, 0x8b, 0x8d, 0x8a, 0x90, 0x8a, 0x8f, + 0x08, 0xfb, 0x48, 0xf9, 0x4c, 0x05, 0x0e, 0xf7, 0x99, 0x38, 0x15, 0x2a, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x7f, 0x91, 0x87, 0x9c, 0x1f, 0xf7, 0x1e, + 0x8b, 0xf7, 0x2f, 0xf9, 0x6c, 0xfb, 0x1e, 0x8b, 0x05, 0x77, 0x7f, 0x81, + 0x7c, 0x7f, 0x91, 0x87, 0x9c, 0x1f, 0xec, 0x8b, 0xfb, 0x1d, 0xfd, 0x1a, + 0x05, 0x0e, 0xf8, 0x42, 0xf8, 0xfb, 0x15, 0xfb, 0x75, 0xfb, 0x73, 0x05, + 0x81, 0x81, 0x88, 0x86, 0x8b, 0x84, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, + 0x93, 0x8b, 0x90, 0x8e, 0x95, 0x95, 0x08, 0xf7, 0x4e, 0xf7, 0x4d, 0xf6, + 0xfb, 0x4d, 0x05, 0x91, 0x81, 0x8f, 0x88, 0x93, 0x8b, 0x97, 0x8b, 0x98, + 0x97, 0x8b, 0x97, 0x8b, 0x8e, 0x89, 0x91, 0x88, 0x90, 0x08, 0xfb, 0x18, + 0xf7, 0x73, 0x05, 0x0e, 0xf8, 0xc8, 0x40, 0x15, 0xfd, 0x05, 0x59, 0xf9, + 0x05, 0xbd, 0x06, 0x0e, 0xf8, 0x9e, 0xf8, 0xf0, 0x15, 0xfb, 0x1a, 0x8b, + 0xe9, 0xfb, 0x83, 0x05, 0x92, 0x7a, 0x91, 0x86, 0x98, 0x8b, 0x08, 0x9e, + 0x9c, 0x9a, 0x9c, 0x1f, 0x8b, 0x8f, 0x75, 0xf7, 0x75, 0x05, 0x0e, 0xf8, + 0x37, 0x16, 0xea, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, + 0x1f, 0x55, 0x8b, 0xc4, 0xf7, 0x9f, 0x05, 0x8c, 0x93, 0x8c, 0x91, 0x8b, + 0x94, 0x8b, 0xc6, 0x53, 0xb4, 0x3a, 0x8b, 0x65, 0x8b, 0x2d, 0x78, 0x67, + 0x7c, 0x7f, 0x86, 0x85, 0x83, 0x8b, 0x81, 0x8b, 0x82, 0x92, 0x84, 0x93, + 0x8b, 0x8e, 0x8b, 0x8e, 0x8c, 0x90, 0x8c, 0x08, 0xd4, 0xa1, 0xb4, 0x93, + 0xad, 0x8b, 0xcc, 0x8b, 0xb5, 0x70, 0x8b, 0x62, 0x8b, 0x85, 0x8b, 0x88, + 0x8a, 0x86, 0x08, 0x7c, 0x44, 0x05, 0x53, 0x9b, 0x6d, 0x90, 0x5d, 0x8b, + 0x08, 0xfb, 0x1e, 0x20, 0x41, 0x2a, 0x1f, 0x4b, 0xbd, 0x64, 0xdd, 0x1e, + 0xd1, 0x8b, 0xcc, 0xa5, 0xd4, 0xc4, 0x08, 0x7d, 0x48, 0x05, 0xa3, 0xf7, + 0x04, 0x15, 0x39, 0x4c, 0x52, 0x73, 0x42, 0x8b, 0x08, 0x4e, 0x68, 0xa5, + 0xb8, 0xd0, 0xe2, 0xbf, 0xf7, 0x07, 0x1f, 0xb8, 0x8b, 0xb8, 0x85, 0xae, + 0x82, 0x08, 0x78, 0x31, 0x05, 0x0e, 0xf7, 0xa4, 0xf8, 0xf0, 0x15, 0x2c, + 0x06, 0x78, 0x7f, 0x82, 0x7c, 0x7e, 0x91, 0x87, 0x9c, 0x1f, 0xc1, 0x8b, + 0xfb, 0x03, 0xfc, 0x9e, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, + 0x92, 0x86, 0x9b, 0x1f, 0xea, 0x8b, 0x9e, 0xe3, 0x05, 0xab, 0x46, 0xbf, + 0x68, 0xd3, 0x8b, 0x08, 0xf7, 0x20, 0xf7, 0x18, 0xf7, 0x19, 0xf7, 0x21, + 0xf1, 0x43, 0xd2, 0x24, 0x1f, 0x41, 0x8b, 0x4c, 0x6b, 0x4a, 0x44, 0x08, + 0xc5, 0xf7, 0xa8, 0x05, 0xf7, 0x18, 0xfb, 0x6a, 0x15, 0xdf, 0xc8, 0x4f, + 0x38, 0xfb, 0x07, 0xfb, 0x00, 0x20, 0xfb, 0x07, 0x3a, 0x4e, 0xc8, 0xdc, + 0xf7, 0x07, 0xf5, 0xf7, 0x00, 0xf7, 0x06, 0x1f, 0x0e, 0xf8, 0xbb, 0xf8, + 0x0c, 0x15, 0x68, 0xb0, 0x58, 0x9e, 0x4d, 0x8b, 0x08, 0xfb, 0x2a, 0xfb, + 0x18, 0xfb, 0x17, 0xfb, 0x29, 0x28, 0xd6, 0x45, 0xf4, 0x1f, 0xcf, 0x8b, + 0xd4, 0x9f, 0xc6, 0xaf, 0xac, 0x9f, 0xa0, 0x9f, 0x8b, 0x97, 0x8b, 0x93, + 0x82, 0x94, 0x84, 0x8b, 0x86, 0x8b, 0x84, 0x87, 0x83, 0x84, 0x50, 0x5c, + 0x42, 0x71, 0x40, 0x8b, 0x34, 0x8b, 0x4d, 0xc4, 0x8b, 0xdc, 0x08, 0x8b, + 0xbb, 0x9f, 0xc1, 0xac, 0xb5, 0xb5, 0xc1, 0xcc, 0xaa, 0xd1, 0x8b, 0xb3, + 0x8b, 0xb7, 0x7f, 0xa0, 0x7a, 0x97, 0x82, 0xa4, 0x6d, 0x8b, 0x86, 0x08, + 0x88, 0x67, 0x05, 0x90, 0x82, 0x90, 0x88, 0x92, 0x8b, 0x98, 0x8b, 0x94, + 0x95, 0x8f, 0x9d, 0x08, 0x9e, 0xe6, 0x05, 0x8c, 0x91, 0x8c, 0x8f, 0x8b, + 0x8e, 0x08, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x82, 0x82, 0x88, + 0x78, 0x08, 0x88, 0x7e, 0x05, 0x0e, 0xf9, 0x0a, 0xf8, 0xf0, 0x15, 0x2c, + 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7e, 0x91, 0x87, 0x9c, 0x1f, 0xc1, 0x8b, + 0x59, 0xfb, 0x80, 0x05, 0x69, 0xd2, 0x59, 0xac, 0x40, 0x8b, 0x08, 0xfb, + 0x1f, 0xfb, 0x16, 0xfb, 0x18, 0xfb, 0x22, 0x28, 0xd5, 0x41, 0xed, 0x1f, + 0xd7, 0x8b, 0xce, 0xad, 0xca, 0xd2, 0x08, 0x78, 0x32, 0xea, 0x8b, 0x05, + 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7b, 0x1f, 0x54, 0x8b, 0x05, + 0xf7, 0x0c, 0xf8, 0xc7, 0x05, 0xfb, 0x9d, 0xfb, 0x6a, 0x15, 0xe0, 0xc6, + 0x50, 0x38, 0x1f, 0xfb, 0x08, 0x21, 0x20, 0xfb, 0x08, 0x37, 0x50, 0xc6, + 0xe0, 0xf7, 0x07, 0xf6, 0xf5, 0xf7, 0x06, 0x1e, 0x0e, 0xf8, 0xc6, 0xf7, + 0x5b, 0x15, 0x90, 0xa4, 0x8e, 0xa3, 0x8b, 0x99, 0x08, 0xee, 0x3d, 0xd1, + 0xfb, 0x01, 0xfb, 0x28, 0xfb, 0x17, 0xfb, 0x0e, 0xfb, 0x1e, 0xfb, 0x03, + 0xdb, 0x3f, 0xf7, 0x08, 0x1e, 0xcb, 0x8b, 0xd4, 0x9d, 0xc1, 0xa9, 0xa9, + 0x9b, 0x95, 0x95, 0x8b, 0x97, 0x8b, 0x94, 0x85, 0x92, 0x82, 0x8b, 0x86, + 0x8b, 0x87, 0x89, 0x82, 0x86, 0x5b, 0x6b, 0x3e, 0x75, 0x4c, 0x8b, 0x2a, + 0x8b, 0x47, 0xc9, 0x8b, 0xe5, 0x08, 0x8b, 0x8f, 0x8b, 0x93, 0x8c, 0x95, + 0x08, 0xf8, 0x34, 0x06, 0xfc, 0x2b, 0xb4, 0x15, 0xb0, 0xe7, 0xe0, 0xc5, + 0xed, 0x8b, 0xe6, 0x8b, 0xcb, 0x52, 0x8b, 0x3a, 0x8b, 0x89, 0x8b, 0x86, + 0x8a, 0x86, 0x08, 0xfc, 0x0a, 0x06, 0x0e, 0xf7, 0xf3, 0xf8, 0x0c, 0x15, + 0xf7, 0x51, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0xfb, 0x51, 0x8b, 0x98, 0xc8, 0x05, 0x95, 0xbe, 0xc0, 0xad, 0xcd, 0x8b, + 0xa2, 0x8b, 0xb4, 0x88, 0xa2, 0x88, 0xb9, 0x85, 0x8b, 0x8b, 0x8d, 0x8b, + 0x99, 0x8b, 0x97, 0x96, 0x8b, 0x99, 0x8b, 0x92, 0x86, 0x91, 0x82, 0x8d, + 0x6b, 0x91, 0x49, 0x92, 0x64, 0x8b, 0x08, 0x32, 0x8b, 0x3f, 0x56, 0x7c, + 0x42, 0x08, 0x7e, 0x4e, 0x33, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, + 0x92, 0x86, 0x9b, 0x1f, 0xe3, 0x8b, 0x44, 0xfb, 0xe3, 0x29, 0x8b, 0x05, + 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xd1, 0x06, + 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x84, 0x8f, 0x7a, 0x1f, 0xfb, 0x45, 0x8b, + 0xd2, 0xf7, 0xe3, 0x05, 0x0e, 0xf8, 0x93, 0xf7, 0xe2, 0x15, 0x6c, 0xce, + 0x5c, 0xa9, 0x43, 0x8b, 0x08, 0xfb, 0x17, 0xfb, 0x11, 0xfb, 0x10, 0xfb, + 0x16, 0x29, 0xd0, 0x46, 0xec, 0x1f, 0xd4, 0x8b, 0xc6, 0xa9, 0xc7, 0xce, + 0x08, 0x6f, 0xfb, 0x15, 0x05, 0x7d, 0x47, 0x49, 0x54, 0x47, 0x8b, 0x08, + 0xfb, 0x08, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x07, 0x06, 0xbc, 0x8b, 0xb4, 0x9b, 0xb6, 0xb1, 0xb0, 0xab, 0x9e, + 0xaa, 0x94, 0xb4, 0x08, 0xe1, 0xf8, 0x28, 0xc1, 0x8b, 0x05, 0x9f, 0x97, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x2c, 0x8b, 0x05, 0x79, 0x38, + 0x05, 0xfb, 0x31, 0xc3, 0x15, 0xdc, 0xc3, 0x55, 0x3d, 0xfb, 0x00, 0x28, + 0x28, 0xfb, 0x02, 0x3b, 0x54, 0xc2, 0xdb, 0x1f, 0xf4, 0xef, 0xee, 0xf6, + 0x1e, 0x0e, 0xf7, 0xb9, 0xf8, 0xf0, 0x15, 0x2c, 0x06, 0x78, 0x7f, 0x82, + 0x7c, 0x7e, 0x91, 0x87, 0x9b, 0x1f, 0xc2, 0x8b, 0xfb, 0x03, 0xfc, 0x9e, + 0x5d, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x18, 0x06, 0x9f, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, + 0x5e, 0x8b, 0xc1, 0xf7, 0x93, 0x98, 0x98, 0x05, 0xcf, 0xcb, 0xab, 0x9c, + 0xc2, 0x8b, 0xb5, 0x8b, 0x9e, 0x85, 0x9f, 0x77, 0x9b, 0x7c, 0x93, 0x78, + 0x8b, 0x76, 0x8b, 0x86, 0x8a, 0x82, 0x89, 0x84, 0x08, 0x57, 0xfb, 0x8b, + 0x5d, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x18, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, + 0x5e, 0x8b, 0xc0, 0xf7, 0x8e, 0x05, 0x8d, 0x95, 0x8c, 0x94, 0x8b, 0x94, + 0x8b, 0xcf, 0x57, 0xb7, 0x3b, 0x8b, 0x4e, 0x8b, 0x5c, 0x74, 0x4b, 0x4e, + 0x08, 0xc1, 0xf7, 0x95, 0x05, 0x0e, 0xf8, 0x2d, 0xf8, 0x35, 0x15, 0xfb, + 0x33, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, + 0x0a, 0x8b, 0x44, 0xfb, 0xe3, 0xfb, 0x35, 0x8b, 0x05, 0x78, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xfe, 0x06, 0x9e, 0x98, 0x95, + 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0x34, 0x8b, 0xdb, 0xf8, 0x0c, + 0x05, 0xb5, 0xf7, 0x63, 0x15, 0x50, 0x8b, 0x75, 0x23, 0xc6, 0x8b, 0xa1, + 0xf3, 0x05, 0x0e, 0xf8, 0x85, 0xf8, 0x0c, 0x15, 0x35, 0xfc, 0x28, 0x05, + 0x7d, 0x47, 0x50, 0x5a, 0x49, 0x8b, 0x08, 0xfb, 0x14, 0x06, 0x77, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x15, 0x06, 0xe6, 0x8b, + 0xd9, 0xcc, 0x9e, 0xe8, 0x08, 0xea, 0xf8, 0x51, 0xfb, 0xad, 0x8b, 0x05, + 0x76, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xf7, 0x84, 0x06, + 0xbd, 0xf7, 0x8c, 0x15, 0x50, 0x8b, 0x75, 0x23, 0xc6, 0x8b, 0xa1, 0xf3, + 0x05, 0x0e, 0xf7, 0x73, 0xf7, 0x48, 0x15, 0xc2, 0xb2, 0xf7, 0x22, 0xfb, + 0x46, 0x6f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, + 0x1f, 0xf7, 0x17, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x84, 0x8f, 0x7b, + 0x1f, 0x5e, 0x8b, 0xfb, 0x38, 0xf7, 0x60, 0xf7, 0x4d, 0xf7, 0x17, 0xba, + 0x8b, 0x05, 0x9e, 0x98, 0x95, 0x99, 0x98, 0x85, 0x8f, 0x79, 0x1f, 0xfb, + 0x15, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xa1, + 0x8b, 0xfb, 0x60, 0xfb, 0x27, 0xdb, 0xf8, 0x0b, 0x2b, 0x8b, 0x05, 0x78, + 0x7f, 0x82, 0x7c, 0x7e, 0x91, 0x87, 0x9c, 0x1f, 0xc1, 0x8b, 0xfb, 0x03, + 0xfc, 0x9e, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, + 0x9b, 0x1f, 0xea, 0x8b, 0xb1, 0xf7, 0x48, 0x05, 0x0e, 0xf8, 0x55, 0xf8, + 0xf0, 0x15, 0xfb, 0x32, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x7f, 0x91, 0x87, + 0x9c, 0x1f, 0xf7, 0x09, 0x8b, 0xfb, 0x03, 0xfc, 0x9e, 0xfb, 0x35, 0x8b, + 0x05, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xfe, + 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0x34, + 0x8b, 0xf7, 0x0c, 0xf8, 0xc7, 0x05, 0x0e, 0xf7, 0x5d, 0xf8, 0x35, 0x15, + 0x41, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xad, + 0x8b, 0x44, 0xfb, 0xe3, 0x69, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9a, 0x1f, 0xf7, 0x01, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, + 0x84, 0x90, 0x7b, 0x1f, 0x69, 0x8b, 0xc4, 0xf7, 0x9f, 0x05, 0xbd, 0xc5, + 0xb0, 0xa3, 0xae, 0x8b, 0xa7, 0x8b, 0xa2, 0x71, 0x8b, 0x6b, 0x8b, 0x86, + 0x8a, 0x86, 0x8a, 0x85, 0x08, 0x48, 0xfb, 0xd0, 0xd5, 0x8b, 0x05, 0x9f, + 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x69, 0x8b, 0xc3, 0xf7, + 0x9f, 0x05, 0xbd, 0xc5, 0xaf, 0xa3, 0xaf, 0x8b, 0xa9, 0x8b, 0xa1, 0x72, + 0x8b, 0x6b, 0x8b, 0x85, 0x8b, 0x88, 0x8a, 0x86, 0x08, 0x47, 0xfb, 0xd3, + 0xd5, 0x8b, 0x05, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0x69, 0x8b, 0xc6, 0xf7, 0xae, 0x05, 0x8d, 0x93, 0x8c, 0x92, 0x8b, 0x92, + 0x8b, 0xbd, 0x68, 0xaf, 0x5a, 0x8b, 0x61, 0x8b, 0x66, 0x76, 0x5a, 0x59, + 0x7f, 0xbb, 0x70, 0xa2, 0x60, 0x8b, 0x61, 0x8b, 0x69, 0x78, 0x60, 0x5c, + 0x08, 0x96, 0xbf, 0x05, 0x0e, 0xf7, 0x94, 0xf8, 0x35, 0x15, 0x40, 0x06, + 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xad, 0x8b, 0x44, + 0xfb, 0xe3, 0x5d, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9c, 0x1f, 0xf7, 0x17, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, + 0x7a, 0x1f, 0x5e, 0x8b, 0xc1, 0xf7, 0x91, 0x05, 0xda, 0xda, 0xa9, 0x9c, + 0xcb, 0x8b, 0xb0, 0x8b, 0x9d, 0x85, 0x9f, 0x77, 0x9a, 0x7c, 0x94, 0x77, + 0x8b, 0x76, 0x8b, 0x81, 0x8b, 0x88, 0x89, 0x84, 0x08, 0x57, 0xfb, 0x8b, + 0x69, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x01, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0x69, 0x8b, 0xc1, 0xf7, 0x92, 0x05, 0x8c, 0x93, 0x8c, 0x91, 0x8b, 0x95, + 0x8b, 0xcf, 0x57, 0xb7, 0x3c, 0x8b, 0x4e, 0x8b, 0x63, 0x78, 0x43, 0x4b, + 0x08, 0x9a, 0xd0, 0x05, 0x0e, 0xf8, 0x1b, 0xf8, 0x43, 0x15, 0xfb, 0x24, + 0xfb, 0x1c, 0xfb, 0x16, 0xfb, 0x1f, 0x23, 0xd7, 0x41, 0xf7, 0x01, 0xf7, + 0x25, 0xf7, 0x1c, 0xf7, 0x15, 0xf7, 0x1f, 0xf5, 0x3f, 0xd4, 0xfb, 0x02, + 0x1f, 0x82, 0x62, 0x15, 0xe6, 0xc9, 0x50, 0x34, 0xfb, 0x06, 0xfb, 0x03, + 0x22, 0xfb, 0x0b, 0x32, 0x4c, 0xc7, 0xe1, 0xf7, 0x05, 0xf7, 0x03, 0xf5, + 0xf7, 0x0a, 0x1f, 0x0e, 0xf7, 0x7d, 0xf8, 0x35, 0x15, 0x2c, 0x06, 0x77, + 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0xfb, 0x02, + 0xfc, 0x9d, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xf7, 0x55, 0x06, 0x9f, 0x97, 0x94, 0x9b, 0x97, 0x85, 0x8f, + 0x79, 0x1f, 0x2a, 0x8b, 0xc0, 0xf7, 0x8f, 0x05, 0xab, 0x49, 0xbd, 0x6d, + 0xd8, 0x8b, 0x08, 0xf7, 0x20, 0xf7, 0x13, 0xf7, 0x0d, 0xf7, 0x19, 0x1f, + 0xf0, 0x45, 0xcd, 0xfb, 0x00, 0x1e, 0x3f, 0x8b, 0x53, 0x70, 0x48, 0x46, + 0x08, 0x9c, 0xdd, 0x05, 0xf7, 0x40, 0x70, 0x15, 0xe1, 0xc7, 0x54, 0x3b, + 0x21, 0x23, 0x29, 0xfb, 0x06, 0x36, 0x4f, 0xc3, 0xdb, 0x1f, 0xf4, 0xf3, + 0xed, 0xf7, 0x05, 0x1e, 0x0e, 0xf8, 0xa8, 0xf7, 0xe3, 0x15, 0x6b, 0xcd, + 0x59, 0xa9, 0x3f, 0x8b, 0x08, 0xfb, 0x21, 0xfb, 0x14, 0xfb, 0x0c, 0xfb, + 0x19, 0x27, 0xd3, 0x47, 0xf6, 0x1f, 0xd8, 0x8b, 0xc9, 0xa9, 0xc8, 0xcd, + 0x08, 0x55, 0xfb, 0x8f, 0x29, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9c, 0x1f, 0xf7, 0x55, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, + 0x84, 0x8f, 0x7a, 0x1f, 0x55, 0x8b, 0x05, 0xf7, 0x03, 0xf8, 0x9d, 0xc1, + 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x2c, + 0x8b, 0x05, 0x79, 0x39, 0x05, 0xfb, 0x3b, 0xc2, 0x15, 0xe2, 0xc7, 0x54, + 0x3a, 0x21, 0x22, 0x2a, 0xfb, 0x06, 0x35, 0x4f, 0xc3, 0xda, 0x1f, 0xf6, + 0xf3, 0xec, 0xf7, 0x06, 0x1e, 0x0e, 0xf7, 0xe5, 0xf8, 0x35, 0x15, 0xfb, + 0x08, 0x06, 0x79, 0x7e, 0x81, 0x7d, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xd5, + 0x8b, 0x44, 0xfb, 0xe3, 0x2b, 0x8b, 0x05, 0x78, 0x7e, 0x81, 0x7d, 0x7f, + 0x93, 0x86, 0x9a, 0x1f, 0xf7, 0xd0, 0x06, 0x9e, 0x98, 0x95, 0x99, 0x97, + 0x83, 0x90, 0x7c, 0x1f, 0xfb, 0x47, 0x8b, 0xba, 0xf7, 0x71, 0x05, 0xf7, + 0x17, 0xf0, 0xb3, 0xa2, 0xb8, 0x8b, 0xa1, 0x8b, 0x9c, 0x81, 0x9e, 0x73, + 0x91, 0x84, 0x8d, 0x8a, 0x91, 0x8b, 0x99, 0x8b, 0x98, 0x98, 0x8b, 0x97, + 0x8b, 0x93, 0x82, 0x97, 0x7c, 0x99, 0x77, 0x9c, 0x7a, 0x92, 0x71, 0x8b, + 0x08, 0x57, 0x8b, 0x56, 0x70, 0xfb, 0x04, 0x36, 0x08, 0xa1, 0xf1, 0x05, + 0x0e, 0xf7, 0x02, 0xa6, 0x15, 0x8a, 0x88, 0x8a, 0x84, 0x8b, 0x89, 0x8b, + 0x83, 0x93, 0x84, 0x93, 0x8b, 0x99, 0x8b, 0x93, 0x94, 0x8f, 0x9d, 0x08, + 0x8e, 0x96, 0x05, 0xad, 0x66, 0xbb, 0x79, 0xcc, 0x8b, 0xf7, 0x0f, 0x8b, + 0xf1, 0xd2, 0x8b, 0xdf, 0x8b, 0xa3, 0x7d, 0xa7, 0x77, 0x9b, 0x71, 0xa0, + 0x68, 0x96, 0x4f, 0x92, 0x3e, 0x93, 0x8b, 0x8b, 0x77, 0x94, 0x76, 0x94, + 0x7a, 0x9f, 0x8b, 0x9b, 0x08, 0xb7, 0xd1, 0xb3, 0xd8, 0x1e, 0xad, 0x8b, + 0xb0, 0x82, 0x9e, 0x7f, 0x95, 0x84, 0x9f, 0x73, 0x8b, 0x87, 0x08, 0x88, + 0x6c, 0x05, 0x90, 0x83, 0x90, 0x87, 0x91, 0x8b, 0x98, 0x8b, 0x95, 0x95, + 0x8f, 0x9d, 0x08, 0x99, 0xd0, 0x05, 0x8c, 0x90, 0x8c, 0x90, 0x8b, 0x8e, + 0x08, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7e, 0x8b, 0x81, 0x80, 0x87, 0x76, + 0x08, 0x6e, 0xaa, 0x61, 0x9a, 0x51, 0x8b, 0xfb, 0x01, 0x8b, 0x34, 0x50, + 0x8b, 0x41, 0x8b, 0x75, 0x98, 0x73, 0x9d, 0x7e, 0xa3, 0x7a, 0xa6, 0x84, + 0xd3, 0x83, 0xc2, 0x85, 0xa4, 0x84, 0xa2, 0x7d, 0x9d, 0x7f, 0x99, 0x76, + 0x8b, 0x7a, 0x08, 0x51, 0x3d, 0x5c, 0x2b, 0x3b, 0x51, 0xaa, 0xb6, 0x1e, + 0x8b, 0x8e, 0x8c, 0x91, 0x8c, 0x92, 0x8c, 0x8d, 0x8b, 0x8e, 0x8b, 0x8d, + 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, 0x87, 0x79, + 0x08, 0x7a, 0x38, 0x05, 0x0e, 0xf7, 0xa7, 0xf8, 0x35, 0x15, 0xa4, 0xf7, + 0x0b, 0x05, 0x8d, 0x93, 0x8b, 0x8c, 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, + 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x72, 0xfb, 0x0b, + 0x40, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, + 0xd5, 0x8b, 0x52, 0xfb, 0xa1, 0x05, 0x89, 0x81, 0x8a, 0x83, 0x8b, 0x81, + 0x8b, 0x52, 0xbf, 0x65, 0xda, 0x8b, 0x08, 0xc0, 0x8b, 0xd5, 0x9a, 0xbb, + 0xa0, 0xa8, 0x98, 0x96, 0x94, 0x8b, 0x97, 0x8b, 0x95, 0x84, 0x92, 0x83, + 0x8b, 0x86, 0x8b, 0x88, 0x8a, 0x81, 0x86, 0x08, 0x60, 0x74, 0x3f, 0x7a, + 0x53, 0x8b, 0x51, 0x8b, 0x65, 0xa5, 0x8b, 0xb3, 0x8b, 0x8f, 0x8c, 0x92, + 0x8c, 0x92, 0x08, 0xc4, 0xf7, 0x9f, 0xf7, 0x70, 0x8b, 0x05, 0x9e, 0x98, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x70, 0x06, 0x0e, 0xf8, + 0x4b, 0x16, 0xd6, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, + 0x1f, 0x69, 0x8b, 0xdb, 0xf8, 0x0c, 0xfb, 0x07, 0x8b, 0x05, 0x76, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x54, 0xfb, 0x99, + 0x05, 0x46, 0x4e, 0x49, 0x6e, 0x47, 0x8b, 0x60, 0x8b, 0x6d, 0xa9, 0x8b, + 0xb5, 0x8b, 0x93, 0x8b, 0x8f, 0x8d, 0x91, 0x08, 0xcb, 0xf7, 0xc2, 0x2c, + 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xc1, + 0x8b, 0x54, 0xfb, 0x99, 0x05, 0x88, 0x80, 0x8a, 0x80, 0x8b, 0x80, 0x8b, + 0x4f, 0xb5, 0x65, 0xcd, 0x8b, 0xce, 0x8b, 0xce, 0xa6, 0xcd, 0xc2, 0x08, + 0x7d, 0x49, 0x05, 0x0e, 0xf7, 0xe4, 0x16, 0xf7, 0x8a, 0xf8, 0x0c, 0xb4, + 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, + 0x2c, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xd0, + 0x8b, 0xfb, 0x6f, 0xfb, 0xe3, 0x78, 0x8b, 0x3c, 0xf7, 0xe3, 0xcd, 0x8b, + 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0x2b, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xb4, 0x8b, + 0xe3, 0xfc, 0x0c, 0xd1, 0x8b, 0x05, 0x0e, 0xf8, 0x4e, 0x16, 0xf7, 0x36, + 0xf8, 0x0c, 0x9e, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, + 0x7a, 0x1f, 0xfb, 0x03, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xbd, 0x8b, 0xfb, 0x1d, 0xfb, 0xd4, 0x69, 0xf7, 0x93, 0x57, + 0x8b, 0xfb, 0x20, 0xfb, 0x93, 0x87, 0xf7, 0xd4, 0xc0, 0x8b, 0x05, 0x9f, + 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x03, 0x06, 0x77, + 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0x9e, 0x8b, 0x8f, 0xfc, + 0x0c, 0xbe, 0x8b, 0xf7, 0x25, 0xf7, 0x97, 0xae, 0xfb, 0x97, 0xbe, 0x8b, + 0x05, 0x0e, 0xf8, 0x0b, 0xf7, 0x6f, 0x15, 0xf7, 0x5a, 0xf7, 0x31, 0x91, + 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, + 0x02, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xbb, + 0x8b, 0xfb, 0x39, 0xfb, 0x16, 0x21, 0xf7, 0x16, 0xb9, 0x8b, 0x05, 0x9f, + 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x03, 0x06, 0x77, + 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0x92, 0x8b, 0xf7, 0x16, + 0xfb, 0x31, 0xfb, 0x72, 0xfb, 0x46, 0x82, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x19, 0x06, 0x9e, 0x98, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x47, 0x8b, 0xf7, 0x50, 0xf7, 0x29, + 0xf7, 0x0f, 0xfb, 0x29, 0x4b, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x18, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, + 0x85, 0x8f, 0x7a, 0x1f, 0x81, 0x8b, 0xfb, 0x26, 0xf7, 0x46, 0x05, 0x0e, + 0xf7, 0xae, 0x16, 0x25, 0xfb, 0x25, 0xfb, 0x12, 0x8b, 0x05, 0x77, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x7d, 0x06, 0x9e, 0x98, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0x4b, 0x8b, 0xf8, 0x03, 0xf8, + 0x9d, 0x98, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, + 0x1f, 0xfb, 0x02, 0x06, 0x77, 0x7f, 0x81, 0x7d, 0x7f, 0x92, 0x86, 0x9b, + 0x1f, 0xc1, 0x8b, 0xfb, 0x7b, 0xfb, 0xdf, 0x2d, 0xf7, 0xdf, 0xbf, 0x8b, + 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfb, 0x07, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0x9b, 0x8b, + 0x05, 0xf6, 0xfc, 0x0c, 0x05, 0x0e, 0xf8, 0xc7, 0xf8, 0x35, 0x15, 0xfb, + 0xf2, 0x8b, 0x76, 0x2b, 0x8a, 0x7f, 0x05, 0x83, 0x93, 0x84, 0x93, 0x1e, + 0x99, 0x8b, 0x93, 0x94, 0x8f, 0x9d, 0x08, 0x97, 0xc2, 0xf7, 0x90, 0x8b, + 0xfc, 0x0a, 0xfb, 0xe8, 0x83, 0x67, 0xf8, 0x0a, 0x8b, 0xa0, 0xec, 0x8c, + 0x8f, 0x05, 0x8c, 0x8e, 0x8b, 0x8d, 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, + 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x7f, 0x53, 0xfb, + 0xa9, 0x8b, 0xf8, 0x0b, 0xf7, 0xe8, 0x93, 0xaf, 0x05, 0x0e, 0xf8, 0x40, + 0xf8, 0x87, 0x15, 0x93, 0xad, 0xa6, 0xa5, 0xad, 0x8f, 0xa1, 0x8d, 0x94, + 0x93, 0x8b, 0x9a, 0x8b, 0x95, 0x84, 0x91, 0x7f, 0x8b, 0x53, 0x8b, 0x56, + 0x5d, 0x7f, 0x50, 0x08, 0x66, 0xfb, 0x41, 0x05, 0x83, 0x66, 0x6d, 0x71, + 0x67, 0x89, 0x78, 0x8a, 0x81, 0x81, 0x8b, 0x7c, 0x8b, 0x80, 0x90, 0x86, + 0x9a, 0x8b, 0xa9, 0x89, 0x9d, 0x78, 0x8b, 0x6f, 0x8b, 0x86, 0x8a, 0x85, + 0x8a, 0x86, 0x08, 0x67, 0xfb, 0x41, 0x05, 0x89, 0x83, 0x8a, 0x83, 0x8b, + 0x83, 0x08, 0x5c, 0xac, 0x69, 0xb8, 0x9b, 0x98, 0x95, 0x99, 0x1e, 0x8b, + 0x97, 0x86, 0x8e, 0x7a, 0x8d, 0x72, 0x8d, 0x79, 0x9f, 0x8b, 0xa5, 0x8b, + 0x92, 0x8b, 0x8f, 0x8d, 0x90, 0x08, 0xaf, 0xf7, 0x41, 0x05, 0x8e, 0x96, + 0x8c, 0x97, 0x8b, 0x92, 0x8b, 0xa2, 0x83, 0x9a, 0x75, 0x9d, 0xb0, 0xa1, + 0x9c, 0xa2, 0x94, 0xb4, 0x08, 0xaf, 0xf7, 0x41, 0x05, 0x0e, 0xf8, 0x4e, + 0xf8, 0xd5, 0x15, 0x8d, 0x93, 0x8b, 0x8c, 0x8b, 0x8e, 0x8b, 0x93, 0x84, + 0x92, 0x82, 0x8b, 0x7e, 0x8b, 0x82, 0x81, 0x87, 0x7a, 0x08, 0xfb, 0x23, + 0xfd, 0x36, 0x05, 0x8a, 0x87, 0x8a, 0x85, 0x8b, 0x89, 0x8b, 0x83, 0x92, + 0x84, 0x94, 0x8b, 0x98, 0x8b, 0x94, 0x94, 0x8f, 0x9d, 0x08, 0xf7, 0x23, + 0xf9, 0x36, 0x05, 0x0e, 0xf7, 0xa7, 0x78, 0x15, 0x83, 0x69, 0x70, 0x71, + 0x69, 0x87, 0x75, 0x89, 0x82, 0x83, 0x8b, 0x7c, 0x8b, 0x81, 0x92, 0x85, + 0x97, 0x8b, 0xc3, 0x8b, 0xc0, 0xb9, 0x97, 0xc6, 0x08, 0xb0, 0xf7, 0x41, + 0x05, 0x93, 0xb0, 0xa9, 0xa5, 0xaf, 0x8d, 0x9e, 0x8c, 0x95, 0x95, 0x8b, + 0x9a, 0x8b, 0x96, 0x86, 0x90, 0x7c, 0x8b, 0x6d, 0x8d, 0x79, 0x9e, 0x8b, + 0xa8, 0x8b, 0x8f, 0x8c, 0x91, 0x8c, 0x90, 0x08, 0xaf, 0xf7, 0x41, 0x05, + 0x8d, 0x93, 0x8c, 0x93, 0x8b, 0x94, 0x08, 0xb9, 0x6a, 0xad, 0x5e, 0x7b, + 0x7e, 0x81, 0x7d, 0x1e, 0x8b, 0x7f, 0x90, 0x88, 0x9c, 0x89, 0xa4, 0x89, + 0x9d, 0x77, 0x8b, 0x71, 0x8b, 0x84, 0x8b, 0x87, 0x89, 0x86, 0x08, 0x67, + 0xfb, 0x41, 0x05, 0x88, 0x80, 0x8a, 0x80, 0x8b, 0x83, 0x8b, 0x75, 0x93, + 0x7b, 0xa1, 0x79, 0x66, 0x75, 0x7a, 0x74, 0x82, 0x62, 0x08, 0x67, 0xfb, + 0x41, 0x05, 0x0e, 0xf8, 0xc2, 0xf7, 0xde, 0x15, 0x82, 0x8b, 0x86, 0x88, + 0x77, 0x75, 0x6a, 0x67, 0x70, 0x7b, 0x73, 0x8b, 0x7c, 0x8b, 0x83, 0x90, + 0x71, 0xa3, 0x7c, 0x99, 0x8b, 0x8b, 0x87, 0x90, 0x08, 0x74, 0xa1, 0x05, + 0x75, 0x9c, 0x78, 0x93, 0x76, 0x8b, 0x6a, 0x8b, 0x6f, 0x7c, 0x60, 0x64, + 0x6f, 0x70, 0x81, 0x7f, 0x8b, 0x81, 0x8b, 0x83, 0x92, 0x84, 0x94, 0x8b, + 0x92, 0x8b, 0x91, 0x8f, 0x94, 0x93, 0xc3, 0xc4, 0x97, 0x93, 0xa6, 0x8b, + 0x08, 0x9c, 0x8b, 0x9c, 0x81, 0x9f, 0x77, 0xbe, 0x56, 0x9e, 0x7f, 0xaa, + 0x8b, 0xab, 0x8b, 0xac, 0x9d, 0xb6, 0xb4, 0xa4, 0xa2, 0x94, 0x97, 0x8b, + 0x94, 0x8b, 0x93, 0x83, 0x92, 0x82, 0x8b, 0x08, 0x0e, 0xf7, 0x77, 0xfb, + 0x35, 0x15, 0x88, 0x7f, 0x89, 0x82, 0x8b, 0x86, 0x8b, 0x7b, 0x99, 0x7e, + 0x9d, 0x8b, 0xa8, 0x8b, 0x9b, 0x9d, 0x91, 0xb0, 0x08, 0xbe, 0xf7, 0xda, + 0x05, 0x8c, 0x91, 0x8b, 0x8e, 0x8b, 0x8f, 0x8b, 0x93, 0x84, 0x92, 0x83, + 0x8b, 0x7d, 0x8b, 0x83, 0x83, 0x86, 0x77, 0x08, 0x33, 0xfb, 0xda, 0x05, + 0xf7, 0x27, 0xf8, 0x72, 0x15, 0xad, 0xaa, 0xa7, 0xac, 0xa2, 0x79, 0x9b, + 0x71, 0x1f, 0x7f, 0x06, 0x67, 0x6c, 0x6f, 0x6b, 0x73, 0x9e, 0x7b, 0xa6, + 0x1f, 0x97, 0x06, 0x0e, 0xf8, 0x15, 0xf8, 0x84, 0x15, 0x50, 0x7e, 0x69, + 0x7c, 0x67, 0x6c, 0x59, 0x61, 0x6c, 0x4c, 0x8b, 0x50, 0x8b, 0x3c, 0xbf, + 0x52, 0xdb, 0x81, 0x08, 0x73, 0xfb, 0x05, 0x8a, 0x87, 0x05, 0x8a, 0x88, + 0x8b, 0x88, 0x8b, 0x89, 0x8b, 0x83, 0x93, 0x84, 0x93, 0x8b, 0x99, 0x8b, + 0x94, 0x94, 0x8f, 0x9d, 0x08, 0xa3, 0xf7, 0x05, 0x05, 0xb3, 0x8d, 0xb7, + 0x98, 0xb5, 0xa0, 0xa6, 0x98, 0x96, 0x97, 0x8b, 0x99, 0x8b, 0x91, 0x82, + 0x93, 0x84, 0x8b, 0x87, 0x8b, 0x83, 0x87, 0x84, 0x86, 0x66, 0x71, 0x55, + 0x7a, 0x5c, 0x8b, 0x08, 0x45, 0x56, 0xbc, 0xcb, 0xed, 0xe4, 0xdf, 0xf1, + 0x1f, 0xaa, 0x8b, 0xa9, 0x83, 0x9b, 0x7e, 0x95, 0x84, 0x9a, 0x75, 0x8b, + 0x86, 0x08, 0x89, 0x6e, 0x05, 0x87, 0x96, 0x83, 0x90, 0x1e, 0x98, 0x8b, + 0x94, 0x95, 0x8f, 0x9e, 0x08, 0x98, 0xc8, 0x05, 0x8c, 0x8e, 0x8b, 0x8d, + 0x8b, 0x8e, 0x8b, 0x96, 0x85, 0x91, 0x80, 0x8b, 0x82, 0x8b, 0x83, 0x85, + 0x85, 0x80, 0x77, 0xa1, 0x65, 0x99, 0x65, 0x8b, 0x08, 0xa1, 0xf5, 0x05, + 0x8d, 0x93, 0x8b, 0x8b, 0x8b, 0x8e, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, + 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x74, 0x20, 0x05, 0x0e, 0xf7, + 0x53, 0xb4, 0x15, 0xc4, 0xc0, 0xb4, 0xea, 0x8e, 0xdf, 0x08, 0xe5, 0x06, + 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x28, 0x8b, 0x8a, + 0x99, 0x05, 0x87, 0xbe, 0x8b, 0x8b, 0x8b, 0x9c, 0x8b, 0xb6, 0x95, 0xa6, + 0xa5, 0xa8, 0xa4, 0xa5, 0xac, 0x9b, 0xab, 0x8b, 0xae, 0x8b, 0xa4, 0x7c, + 0x9f, 0x69, 0x90, 0x82, 0x8f, 0x88, 0x91, 0x8b, 0x97, 0x8b, 0x98, 0x97, + 0x8b, 0x96, 0x08, 0x8b, 0x94, 0x82, 0x9c, 0x7e, 0x99, 0x73, 0xa5, 0x6d, + 0x98, 0x67, 0x8b, 0x2c, 0x8b, 0x3a, 0x36, 0x8b, 0x27, 0x8b, 0x77, 0x8c, + 0x77, 0x90, 0x64, 0x08, 0x2d, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, + 0x86, 0x9b, 0x1f, 0xf3, 0x06, 0x87, 0x20, 0x42, 0xfb, 0x11, 0x51, 0x8a, + 0x08, 0x7b, 0x80, 0x81, 0x7e, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xd7, + 0x06, 0xa8, 0x8b, 0xa7, 0x9a, 0xa0, 0xa5, 0x9a, 0x9d, 0x97, 0xa6, 0x8b, + 0x99, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7e, 0x8b, 0x83, 0x84, 0x86, + 0x7b, 0x81, 0x6b, 0x77, 0x78, 0x71, 0x8b, 0x08, 0xfb, 0x90, 0x06, 0x0e, + 0xf9, 0x05, 0xf8, 0x42, 0x15, 0x9a, 0x93, 0x90, 0x91, 0x8b, 0x95, 0x8b, + 0x94, 0x83, 0x92, 0x83, 0x8b, 0x86, 0x8b, 0x84, 0x89, 0x84, 0x87, 0x08, + 0xfc, 0x8e, 0xfb, 0xb0, 0x05, 0x7d, 0x83, 0x85, 0x84, 0x8b, 0x81, 0x8b, + 0x82, 0x92, 0x83, 0x94, 0x8b, 0x8f, 0x8b, 0x90, 0x8d, 0x90, 0x8e, 0x08, + 0x90, 0x8e, 0xf8, 0x8e, 0xf7, 0xb0, 0x05, 0x0e, 0xf8, 0x08, 0xf7, 0x82, + 0x15, 0xf7, 0x17, 0x06, 0x9c, 0x94, 0x93, 0x9d, 0x93, 0x85, 0x8e, 0x7e, + 0x1f, 0xfb, 0x0a, 0x8b, 0xf7, 0x6d, 0xf7, 0x8b, 0xa3, 0x8b, 0x05, 0x9f, + 0x97, 0x95, 0x99, 0x98, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x02, 0x06, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xb2, 0x8b, 0xfb, 0x5b, + 0xfb, 0x77, 0x24, 0xf7, 0x77, 0xb2, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, + 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x02, 0x06, 0x77, 0x7f, 0x82, 0x7b, + 0x80, 0x91, 0x86, 0x9c, 0x1f, 0xa3, 0x8b, 0xf7, 0x03, 0xfb, 0x8b, 0xfb, + 0x08, 0x8b, 0x05, 0x79, 0x83, 0x83, 0x7a, 0x82, 0x90, 0x88, 0x98, 0x1f, + 0xf7, 0x17, 0x8b, 0x7e, 0x4f, 0xfb, 0x17, 0x8b, 0x05, 0x7a, 0x82, 0x83, + 0x7a, 0x83, 0x91, 0x87, 0x98, 0x1f, 0xf7, 0x16, 0x8b, 0x76, 0x27, 0x35, + 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, + 0x69, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x35, + 0x8b, 0xa0, 0xef, 0xf7, 0x17, 0x8b, 0x05, 0x9c, 0x94, 0x94, 0x9c, 0x92, + 0x85, 0x8f, 0x7f, 0x1f, 0xfb, 0x17, 0x8b, 0x98, 0xc7, 0x05, 0x0e, 0xf8, + 0x25, 0xf8, 0x0b, 0x15, 0x9d, 0xe2, 0x05, 0x9a, 0xd0, 0xc3, 0xb9, 0xd0, + 0x8b, 0x95, 0x8b, 0x9d, 0x89, 0x93, 0x88, 0x9f, 0x85, 0x8c, 0x8b, 0x8f, + 0x8b, 0x96, 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x91, 0x88, 0x8f, 0x84, + 0x8e, 0x79, 0x94, 0x6f, 0x90, 0x72, 0x8b, 0x08, 0x37, 0x8b, 0x3a, 0x46, + 0x78, 0x34, 0x08, 0x79, 0x34, 0x2a, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7c, + 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xeb, 0x8b, 0x52, 0xfb, 0xa2, 0x05, 0x7c, + 0x47, 0x55, 0x5b, 0x4d, 0x8b, 0x80, 0x8b, 0x7a, 0x8d, 0x83, 0x8e, 0x74, + 0x92, 0x88, 0x8c, 0x87, 0x8b, 0x08, 0x7f, 0x80, 0x7f, 0x7f, 0x7b, 0xb1, + 0x7d, 0xb5, 0x1f, 0xdd, 0x8b, 0xda, 0xce, 0x9d, 0xdf, 0x08, 0xc6, 0xf7, + 0xa8, 0xeb, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, + 0x1f, 0x2b, 0x06, 0x0e, 0xf9, 0x04, 0xf8, 0xef, 0x15, 0xfb, 0x68, 0x06, + 0x3d, 0x3e, 0x48, 0x47, 0x1f, 0x8b, 0x81, 0x8c, 0x84, 0x8f, 0x81, 0x46, + 0x86, 0x56, 0x61, 0x8b, 0x5a, 0x8b, 0x5f, 0xad, 0x62, 0xd9, 0x5a, 0x08, + 0xc4, 0x67, 0x05, 0xd7, 0x5b, 0xaa, 0x6b, 0x8b, 0x6d, 0x08, 0x5d, 0x57, + 0x62, 0x51, 0x1e, 0xfb, 0x39, 0x8b, 0x9a, 0xd2, 0x8c, 0x94, 0x05, 0x94, + 0x84, 0x91, 0x81, 0x1e, 0x7e, 0x8b, 0x82, 0x82, 0x88, 0x7c, 0x08, 0x73, + 0xfb, 0x03, 0xf7, 0x63, 0x8b, 0x05, 0xe1, 0xd5, 0xca, 0xd5, 0x1f, 0x8b, + 0x94, 0x8a, 0x92, 0x87, 0x95, 0xb5, 0x90, 0x9f, 0x92, 0xa2, 0x9e, 0xa3, + 0x9d, 0x98, 0xa4, 0x8b, 0xa6, 0x8b, 0xb6, 0x6d, 0xaf, 0x40, 0xb9, 0x08, + 0x5a, 0xaa, 0x05, 0x2c, 0xc6, 0x6f, 0xa6, 0x8b, 0xa9, 0x08, 0xb8, 0xc0, + 0xb7, 0xc2, 0x1e, 0xf7, 0x3c, 0x8b, 0x7d, 0x46, 0x05, 0x8a, 0x86, 0x8a, + 0x88, 0x8b, 0x89, 0x8a, 0x83, 0x93, 0x84, 0x95, 0x8b, 0x98, 0x8b, 0x94, + 0x94, 0x8f, 0x9b, 0x08, 0xa2, 0xf7, 0x01, 0x05, 0xfb, 0x47, 0xfb, 0xcd, + 0x15, 0xc0, 0x6b, 0xac, 0x65, 0x8b, 0x6f, 0x8b, 0x6e, 0x69, 0x77, 0x59, + 0x8a, 0x7e, 0x8a, 0x8a, 0x8b, 0x87, 0x89, 0x7c, 0x9d, 0x72, 0x9f, 0x5a, + 0xaa, 0x08, 0x54, 0xae, 0x05, 0x49, 0xb5, 0x68, 0xb0, 0x8b, 0xa7, 0x08, + 0xa8, 0xb0, 0xa2, 0xba, 0x1e, 0x92, 0x06, 0x90, 0x8b, 0x8d, 0x8b, 0x8f, + 0x8c, 0xa1, 0x73, 0xa3, 0x79, 0xc3, 0x68, 0x08, 0xc4, 0x67, 0x05, 0x0e, + 0xf7, 0x7d, 0xf7, 0x36, 0x15, 0xa5, 0x74, 0xaa, 0x7f, 0xaf, 0x8b, 0xb1, + 0x8b, 0xaf, 0x96, 0xaf, 0xa3, 0x08, 0xb6, 0x53, 0x05, 0x91, 0x83, 0x90, + 0x88, 0x90, 0x8b, 0x98, 0x8b, 0x98, 0x98, 0x8b, 0x96, 0x86, 0x9a, 0x8b, + 0x8b, 0x8a, 0x8c, 0x08, 0x5f, 0xc3, 0x05, 0xb2, 0xb2, 0xa1, 0xbd, 0x8b, + 0xba, 0x8b, 0xa3, 0x86, 0xa1, 0x7f, 0xa0, 0x08, 0xce, 0xc3, 0x05, 0x97, + 0x94, 0x8e, 0x90, 0x8b, 0x94, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, 0x85, + 0x8b, 0x86, 0x89, 0x81, 0x82, 0x08, 0x48, 0x54, 0x05, 0x73, 0xa2, 0x6a, + 0x97, 0x67, 0x8b, 0x64, 0x8b, 0x66, 0x7f, 0x68, 0x74, 0x08, 0x5f, 0xc2, + 0x05, 0x85, 0x94, 0x87, 0x8d, 0x84, 0x8b, 0x7f, 0x8b, 0x7e, 0x7f, 0x8b, + 0x7f, 0x8b, 0x87, 0x8d, 0x86, 0x90, 0x85, 0x08, 0xb7, 0x53, 0x05, 0x67, + 0x67, 0x73, 0x56, 0x8b, 0x5d, 0x8b, 0x74, 0x91, 0x75, 0x96, 0x74, 0x08, + 0x47, 0x53, 0x05, 0x80, 0x81, 0x87, 0x85, 0x8b, 0x83, 0x8b, 0x82, 0x92, + 0x84, 0x95, 0x8b, 0x91, 0x8b, 0x90, 0x8e, 0x95, 0x93, 0x08, 0xcf, 0xc3, + 0x05, 0xf7, 0x2f, 0xf7, 0x93, 0x15, 0xc6, 0xb5, 0x62, 0x51, 0x3e, 0x40, + 0x42, 0x3b, 0x52, 0x61, 0xb5, 0xc4, 0xd8, 0xd6, 0xd4, 0xd9, 0x1f, 0x0e, + 0xf8, 0x00, 0xf8, 0xf0, 0x15, 0x77, 0xfb, 0x91, 0x8b, 0x81, 0x05, 0x7b, + 0x94, 0x81, 0x99, 0x1e, 0x9c, 0x8b, 0x97, 0x96, 0x94, 0xa4, 0x08, 0xe2, + 0xf7, 0x91, 0xfb, 0x14, 0x8b, 0x05, 0x0e, 0xf8, 0xc8, 0xf8, 0xf0, 0x15, + 0xfb, 0x12, 0x8b, 0xe1, 0xfb, 0x83, 0x05, 0x91, 0x7b, 0x92, 0x85, 0x98, + 0x8b, 0x08, 0x9e, 0x9c, 0x9a, 0x9c, 0x1f, 0x8b, 0x8f, 0x75, 0xf7, 0x75, + 0x05, 0xfb, 0x6d, 0x16, 0xfb, 0x12, 0x8b, 0xe1, 0xfb, 0x83, 0x05, 0x91, + 0x7b, 0x92, 0x85, 0x98, 0x8b, 0x08, 0x9e, 0x9c, 0x9a, 0x9c, 0x1f, 0x8b, + 0x8f, 0x75, 0xf7, 0x75, 0x05, 0x0e, 0xf7, 0x00, 0xf7, 0x65, 0x15, 0xf7, + 0x3a, 0xfb, 0x5a, 0x05, 0x91, 0x84, 0x91, 0x87, 0x91, 0x8b, 0x98, 0x8b, + 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x8f, 0x8a, 0x8e, 0x85, 0x93, 0x08, 0x20, + 0xf7, 0x3d, 0xf7, 0x47, 0xf7, 0x3c, 0x05, 0x98, 0x97, 0x8d, 0x8f, 0x8b, + 0x93, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x84, 0x8b, 0x85, 0x88, 0x81, + 0x83, 0x08, 0xfb, 0x8e, 0xfb, 0x59, 0x05, 0xf7, 0x79, 0x16, 0xf7, 0x3a, + 0xfb, 0x5a, 0x05, 0x91, 0x84, 0x91, 0x87, 0x91, 0x8b, 0x98, 0x8b, 0x97, + 0x97, 0x8b, 0x98, 0x8b, 0x8f, 0x8a, 0x8e, 0x85, 0x93, 0x08, 0x20, 0xf7, + 0x3d, 0xf7, 0x47, 0xf7, 0x3c, 0x05, 0x98, 0x97, 0x8d, 0x8f, 0x8b, 0x93, + 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x84, 0x8b, 0x85, 0x88, 0x80, 0x83, + 0x08, 0xfb, 0x8d, 0xfb, 0x59, 0x05, 0x0e, 0xf7, 0x00, 0xf7, 0x65, 0x15, + 0xf7, 0x3a, 0xfb, 0x5a, 0x05, 0x91, 0x84, 0x91, 0x87, 0x91, 0x8b, 0x98, + 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x8f, 0x8a, 0x8e, 0x85, 0x93, 0x08, + 0x20, 0xf7, 0x3d, 0xf7, 0x47, 0xf7, 0x3c, 0x05, 0x98, 0x97, 0x8d, 0x8f, + 0x8b, 0x93, 0x8b, 0x95, 0x84, 0x91, 0x82, 0x8b, 0x84, 0x8b, 0x85, 0x88, + 0x80, 0x83, 0x08, 0xfb, 0x8d, 0xfb, 0x59, 0x05, 0x0e, 0xf8, 0xdd, 0xf7, + 0x64, 0x15, 0xfb, 0x39, 0xf7, 0x5a, 0x05, 0x85, 0x92, 0x85, 0x8f, 0x85, + 0x8b, 0x7e, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, 0x8b, 0x87, 0x8c, 0x88, 0x91, + 0x83, 0x08, 0xf5, 0xfb, 0x3d, 0xfb, 0x46, 0xfb, 0x3c, 0x05, 0x7e, 0x7f, + 0x89, 0x87, 0x8b, 0x83, 0x8b, 0x81, 0x92, 0x85, 0x94, 0x8b, 0x92, 0x8b, + 0x92, 0x8e, 0x95, 0x93, 0x08, 0xf7, 0x8c, 0xf7, 0x59, 0x05, 0x0e, 0xf7, + 0x85, 0xf8, 0x0c, 0x15, 0xd3, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x79, 0x1f, 0x44, 0x8b, 0x97, 0xc6, 0x05, 0x96, 0xbd, 0xb0, 0xb0, + 0xb1, 0x8b, 0x99, 0x8b, 0x9d, 0x88, 0xa3, 0x83, 0x95, 0x88, 0x8b, 0x8b, + 0x8e, 0x8b, 0x97, 0x8b, 0x96, 0x97, 0x8b, 0x97, 0x8b, 0x92, 0x87, 0x91, + 0x83, 0x8e, 0x79, 0x93, 0x69, 0x92, 0x78, 0x8b, 0x08, 0x4e, 0x8b, 0x50, + 0x53, 0x7b, 0x43, 0x08, 0x7f, 0x50, 0x3d, 0x8b, 0x05, 0x78, 0x7f, 0x82, + 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xd8, 0x8b, 0x44, 0xfb, 0xe3, 0x38, + 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, + 0x58, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0x44, + 0x8b, 0x05, 0xd2, 0xf7, 0xe3, 0x05, 0xf7, 0xdf, 0xb4, 0x15, 0x29, 0x06, + 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xc4, 0x8b, 0x44, + 0xfb, 0xe3, 0x3e, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xf7, 0x55, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, + 0x7a, 0x1f, 0x40, 0x8b, 0xdb, 0xf8, 0x0c, 0x05, 0xb6, 0xf7, 0x63, 0x15, + 0x50, 0x8b, 0x75, 0x23, 0xc6, 0x8b, 0x05, 0xa1, 0xf3, 0x05, 0x0e, 0xf7, + 0x85, 0xf8, 0x0c, 0x15, 0xd2, 0x06, 0x9f, 0x98, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x79, 0x1f, 0x44, 0x8b, 0x97, 0xc6, 0x05, 0x96, 0xbc, 0xb0, 0xb1, + 0xb0, 0x8b, 0x99, 0x8b, 0x9e, 0x87, 0xa2, 0x84, 0x95, 0x88, 0x8b, 0x8b, + 0x8e, 0x8b, 0x97, 0x8b, 0x96, 0x97, 0x8b, 0x97, 0x8b, 0x92, 0x87, 0x91, + 0x83, 0x8e, 0x79, 0x93, 0x69, 0x92, 0x78, 0x8b, 0x08, 0x4f, 0x8b, 0x4f, + 0x52, 0x7c, 0x44, 0x08, 0x7f, 0x50, 0x3d, 0x8b, 0x05, 0x78, 0x7f, 0x82, + 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xd8, 0x8b, 0x44, 0xfb, 0xe3, 0x38, + 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, + 0x57, 0x06, 0x9f, 0x98, 0x95, 0x9a, 0x97, 0x84, 0x8f, 0x7a, 0x1f, 0x44, + 0x8b, 0xd2, 0xf7, 0xe3, 0x05, 0xf8, 0x06, 0xf7, 0x78, 0x15, 0x29, 0x06, + 0x77, 0x7f, 0x82, 0x7c, 0x7e, 0x91, 0x87, 0x9c, 0x1f, 0xc4, 0x8b, 0xfb, + 0x03, 0xfc, 0x9e, 0x3e, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0x57, 0x06, 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7b, 0x1f, 0x3d, 0x8b, 0xf7, 0x0c, 0xf8, 0xc7, 0x05, 0x0e, 0xf8, + 0xc0, 0xf7, 0x99, 0x15, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, + 0x1f, 0xfc, 0x26, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, + 0x1f, 0xf8, 0x26, 0x06, 0x0e, 0xf8, 0x24, 0xf8, 0x0c, 0x15, 0xf7, 0x15, + 0x06, 0x9f, 0x97, 0x94, 0x9b, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0x14, + 0x8b, 0xad, 0xf7, 0x34, 0x8c, 0x97, 0x05, 0x93, 0x84, 0x92, 0x82, 0x1e, + 0x7d, 0x8b, 0x82, 0x82, 0x88, 0x79, 0x08, 0x69, 0xfb, 0x33, 0xfb, 0x14, + 0x8b, 0x05, 0x86, 0x8a, 0x8b, 0x8b, 0x89, 0x8b, 0x81, 0x89, 0x8b, 0x8b, + 0x8a, 0x8a, 0x83, 0x86, 0x85, 0x82, 0x8b, 0x83, 0x08, 0x80, 0x92, 0x86, + 0x9b, 0x1e, 0xf7, 0x14, 0x8b, 0x34, 0xfc, 0x30, 0x05, 0x8a, 0x88, 0x8a, + 0x85, 0x8b, 0x88, 0x8b, 0x83, 0x92, 0x84, 0x94, 0x8b, 0x99, 0x8b, 0x94, + 0x94, 0x8f, 0x9d, 0x08, 0xe2, 0xf8, 0x30, 0x05, 0x0e, 0xf8, 0x24, 0xf8, + 0x0c, 0x15, 0xf7, 0x15, 0x06, 0x9f, 0x97, 0x94, 0x9b, 0x96, 0x84, 0x90, + 0x7a, 0x1f, 0xfb, 0x14, 0x8b, 0xad, 0xf7, 0x34, 0x8c, 0x96, 0x05, 0x94, + 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x82, 0x82, 0x88, 0x79, 0x08, 0x69, + 0xfb, 0x33, 0xfb, 0x15, 0x8b, 0x05, 0x87, 0x8a, 0x8b, 0x8b, 0x89, 0x8b, + 0x81, 0x89, 0x8b, 0x8b, 0x8a, 0x8a, 0x83, 0x86, 0x85, 0x82, 0x8b, 0x83, + 0x08, 0x80, 0x91, 0x86, 0x9c, 0x1e, 0xf7, 0x14, 0x8b, 0x5e, 0xfb, 0x67, + 0xfb, 0x14, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x91, 0x86, 0x9c, + 0x1f, 0xf7, 0x14, 0x8b, 0x69, 0xfb, 0x33, 0x8a, 0x7f, 0x05, 0x83, 0x92, + 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, 0xad, 0xf7, + 0x33, 0xf7, 0x15, 0x8b, 0x05, 0x9f, 0x97, 0x94, 0x9b, 0x97, 0x85, 0x8f, + 0x79, 0x1f, 0xfb, 0x14, 0x8b, 0xb8, 0xf7, 0x67, 0x05, 0x0e, 0xf8, 0x05, + 0xf7, 0xf0, 0x15, 0x5f, 0x63, 0x66, 0x61, 0x6c, 0xa2, 0x76, 0xac, 0x1f, + 0x96, 0x06, 0xb7, 0xb3, 0xb0, 0xb5, 0xaa, 0x74, 0xa0, 0x6a, 0x1f, 0x80, + 0x06, 0x0e, 0xf8, 0xc1, 0xf8, 0xc7, 0x15, 0xc8, 0x06, 0x9d, 0x97, 0x95, + 0x9a, 0x96, 0x84, 0x90, 0x7d, 0x1f, 0xfb, 0x5c, 0x06, 0xfb, 0x16, 0x8b, + 0x25, 0x4e, 0x78, 0x31, 0x08, 0x81, 0x5c, 0x05, 0x89, 0x84, 0x8a, 0x83, + 0x8b, 0x86, 0x8b, 0x60, 0xa5, 0x67, 0xb8, 0x74, 0xa6, 0x7e, 0xac, 0x83, + 0xb9, 0x88, 0x08, 0x4f, 0xfb, 0xad, 0x29, 0x8b, 0x05, 0x79, 0x7f, 0x81, + 0x7c, 0x81, 0x92, 0x85, 0x9a, 0x1f, 0xf7, 0x1a, 0x06, 0x9d, 0x97, 0x95, + 0x9a, 0x1f, 0x8b, 0x95, 0x85, 0x90, 0x80, 0x8c, 0x08, 0xf7, 0x10, 0xf8, + 0xdc, 0xd3, 0x8b, 0xfb, 0x10, 0xfc, 0xdc, 0x05, 0x7c, 0x8a, 0x80, 0x80, + 0x8b, 0x7f, 0x08, 0x7f, 0x92, 0x86, 0x99, 0x1e, 0xee, 0x06, 0x9d, 0x97, + 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7c, 0x1f, 0x4d, 0x8b, 0xf7, 0x10, 0xf8, + 0xdc, 0x05, 0xfb, 0x63, 0xfb, 0x94, 0x15, 0x47, 0x92, 0x59, 0xb3, 0x8e, + 0xb9, 0x8b, 0x8e, 0x8c, 0x90, 0x8c, 0x91, 0x08, 0x93, 0xb0, 0x05, 0x98, + 0xc1, 0xd1, 0xbb, 0xd6, 0x90, 0x08, 0x56, 0xfb, 0x8f, 0x05, 0x0e, 0xf7, + 0xf5, 0xf7, 0xe5, 0x15, 0x53, 0x5f, 0x60, 0x55, 0x54, 0xb7, 0x5f, 0xc1, + 0xc1, 0xb7, 0xb7, 0xc1, 0xc0, 0x5f, 0xb8, 0x57, 0x1f, 0x0e, 0xf7, 0x82, + 0xf7, 0x25, 0x15, 0xfb, 0x0f, 0xfb, 0x8e, 0x05, 0x88, 0x85, 0x89, 0x85, + 0x8b, 0x86, 0x8b, 0x7e, 0x95, 0x81, 0x98, 0x8b, 0x99, 0x8b, 0x93, 0x91, + 0x9a, 0x9e, 0x08, 0xf7, 0x5d, 0xf7, 0x9d, 0xfb, 0x19, 0x8b, 0x05, 0x0e, + 0xf7, 0x57, 0xf7, 0x25, 0x15, 0xfb, 0x0a, 0xfb, 0x75, 0x05, 0x89, 0x86, + 0x89, 0x85, 0x8b, 0x87, 0x8b, 0x7f, 0x96, 0x82, 0x98, 0x8b, 0x98, 0x8b, + 0x95, 0x91, 0x98, 0x9b, 0x08, 0xf7, 0x50, 0xf7, 0x83, 0xfb, 0x12, 0x8b, + 0x05, 0xf7, 0x6d, 0x16, 0xfb, 0x0a, 0xfb, 0x75, 0x05, 0x88, 0x85, 0x8a, + 0x86, 0x8b, 0x87, 0x8b, 0x7f, 0x96, 0x82, 0x99, 0x8b, 0x98, 0x8b, 0x94, + 0x91, 0x98, 0x9b, 0x08, 0xf7, 0x50, 0xf7, 0x83, 0xfb, 0x12, 0x8b, 0x05, + 0x0e, 0xf7, 0xb8, 0xf8, 0xf0, 0x15, 0xfb, 0x0a, 0xfb, 0x75, 0x05, 0x89, + 0x86, 0x89, 0x85, 0x8b, 0x87, 0x8b, 0x7f, 0x96, 0x82, 0x98, 0x8b, 0x98, + 0x8b, 0x95, 0x91, 0x98, 0x9b, 0x08, 0xf7, 0x50, 0xf7, 0x83, 0xfb, 0x12, + 0x8b, 0x05, 0xf7, 0x6d, 0x16, 0xfb, 0x0a, 0xfb, 0x75, 0x05, 0x88, 0x85, + 0x8a, 0x86, 0x8b, 0x87, 0x8b, 0x7f, 0x96, 0x82, 0x99, 0x8b, 0x98, 0x8b, + 0x94, 0x91, 0x98, 0x9b, 0x08, 0xf7, 0x50, 0xf7, 0x83, 0xfb, 0x12, 0x8b, + 0x05, 0x0e, 0xf7, 0xf7, 0xf7, 0x64, 0x15, 0xfb, 0x39, 0xf7, 0x5a, 0x05, + 0x85, 0x92, 0x85, 0x8f, 0x85, 0x8b, 0x7e, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, + 0x8b, 0x87, 0x8c, 0x89, 0x91, 0x82, 0x08, 0xf5, 0xfb, 0x3d, 0xfb, 0x46, + 0xfb, 0x3c, 0x05, 0x7e, 0x7f, 0x89, 0x87, 0x8b, 0x83, 0x8b, 0x81, 0x92, + 0x85, 0x94, 0x8b, 0x92, 0x8b, 0x92, 0x8e, 0x95, 0x93, 0x08, 0xf7, 0x8c, + 0xf7, 0x59, 0x05, 0xf7, 0x7a, 0x16, 0xfb, 0x39, 0xf7, 0x5a, 0x05, 0x85, + 0x92, 0x85, 0x8f, 0x85, 0x8b, 0x7e, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, 0x8b, + 0x87, 0x8c, 0x88, 0x91, 0x83, 0x08, 0xf5, 0xfb, 0x3d, 0xfb, 0x46, 0xfb, + 0x3c, 0x05, 0x7f, 0x7f, 0x88, 0x87, 0x8b, 0x83, 0x8b, 0x82, 0x92, 0x84, + 0x94, 0x8b, 0x92, 0x8b, 0x91, 0x8e, 0x95, 0x93, 0x08, 0xf7, 0x8d, 0xf7, + 0x59, 0x05, 0x0e, 0xf7, 0x0a, 0xdf, 0x15, 0x6c, 0x6d, 0x6e, 0x6c, 0x75, + 0x9c, 0x7a, 0xa1, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9b, 0x74, 0x1f, + 0xf7, 0x5b, 0x16, 0x6c, 0x6d, 0x6e, 0x6c, 0x75, 0x9c, 0x7a, 0xa1, 0xab, + 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9b, 0x74, 0x1f, 0xf7, 0x5c, 0x16, 0x6c, + 0x6d, 0x6e, 0x6d, 0x74, 0x9c, 0x7a, 0xa1, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, + 0x7a, 0x9b, 0x74, 0x1f, 0x0e, 0xf7, 0xa6, 0xf8, 0xfa, 0x15, 0x45, 0x49, + 0x49, 0x46, 0x58, 0xb0, 0x66, 0xbe, 0xd1, 0xce, 0xcc, 0xd0, 0x1f, 0xc0, + 0x66, 0xaf, 0x57, 0x1e, 0x84, 0x69, 0x15, 0xaf, 0xa4, 0x72, 0x68, 0x59, + 0x5e, 0x5e, 0x59, 0x68, 0x72, 0xa5, 0xaf, 0xbb, 0xb9, 0xb8, 0xbb, 0x1f, + 0xf7, 0xcb, 0xfb, 0x54, 0x15, 0x98, 0x8f, 0x92, 0x92, 0x8b, 0x94, 0x8b, + 0x92, 0x86, 0x91, 0x84, 0x8b, 0x88, 0x8b, 0x87, 0x8a, 0x87, 0x8a, 0x08, + 0xfc, 0x24, 0xfb, 0x0e, 0x05, 0x7e, 0x88, 0x84, 0x83, 0x8b, 0x82, 0x8b, + 0x84, 0x91, 0x85, 0x91, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, 0x8f, 0x8c, 0x08, + 0xf8, 0x24, 0xf7, 0x0e, 0x05, 0xfb, 0xf3, 0xfb, 0x42, 0x15, 0x46, 0x48, + 0x49, 0x47, 0x57, 0xb0, 0x66, 0xbe, 0xd1, 0xce, 0xcc, 0xd0, 0xc0, 0x67, + 0xaf, 0x56, 0x1f, 0x84, 0x69, 0x15, 0xaf, 0xa4, 0x72, 0x68, 0x59, 0x5e, + 0x5e, 0x59, 0x68, 0x72, 0xa5, 0xae, 0xbb, 0xb9, 0xb9, 0xbb, 0x1f, 0xf7, + 0xab, 0xad, 0x15, 0x46, 0x48, 0x49, 0x47, 0x57, 0xb0, 0x66, 0xbe, 0xd1, + 0xce, 0xcc, 0xd0, 0xc0, 0x67, 0xaf, 0x56, 0x1f, 0x84, 0x69, 0x15, 0xaf, + 0xa4, 0x72, 0x68, 0x59, 0x5e, 0x5e, 0x59, 0x68, 0x72, 0xa5, 0xae, 0xbb, + 0xb9, 0xb9, 0xbb, 0x1f, 0x0e, 0xf7, 0xcb, 0xf7, 0x2f, 0x15, 0x46, 0x6d, + 0x66, 0x77, 0x69, 0x71, 0x62, 0x6a, 0x72, 0x59, 0x8b, 0x5a, 0x8b, 0x3f, + 0xc3, 0x5d, 0xe7, 0x8b, 0xbf, 0x8b, 0xac, 0x93, 0xd0, 0xa7, 0x96, 0x8f, + 0x92, 0x8e, 0x99, 0x91, 0x08, 0x99, 0xce, 0x05, 0x8c, 0x90, 0x8c, 0x8f, + 0x8b, 0x8d, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, + 0x87, 0x79, 0x08, 0x83, 0x62, 0x05, 0x50, 0x71, 0x6b, 0x83, 0x5d, 0x8b, + 0x42, 0x8b, 0x5c, 0xaf, 0x8b, 0xc3, 0x8b, 0xce, 0xc4, 0xbb, 0xf7, 0x22, + 0xc2, 0x08, 0x9a, 0xcf, 0x8c, 0x97, 0x05, 0x93, 0x84, 0x92, 0x82, 0x1e, + 0x7d, 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x82, 0x62, 0x05, 0xd1, 0xf7, + 0x36, 0x15, 0xb0, 0xaa, 0xa6, 0xac, 0xa4, 0x79, 0x9a, 0x6e, 0x1f, 0x6f, + 0x06, 0x66, 0x6c, 0x70, 0x6a, 0x72, 0x9c, 0x7c, 0xa9, 0x1f, 0xa7, 0x06, + 0x0e, 0xf7, 0xdc, 0xf9, 0x0a, 0x15, 0x84, 0x92, 0x87, 0x8d, 0x86, 0x8b, + 0x7d, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, 0x8b, 0x87, 0x8e, 0x86, 0x90, 0x85, + 0x08, 0xe8, 0x27, 0x05, 0x91, 0x85, 0x90, 0x88, 0x90, 0x8b, 0x97, 0x8b, + 0x99, 0x97, 0x8b, 0x97, 0x8b, 0x8d, 0x85, 0x97, 0x88, 0x8d, 0x08, 0x2f, + 0xef, 0x05, 0x0e, 0xf8, 0xc4, 0xf8, 0xeb, 0x15, 0x98, 0x94, 0x8f, 0x91, + 0x8b, 0x94, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x85, 0x8b, 0x86, 0x89, + 0x81, 0x84, 0x08, 0xfb, 0x1b, 0x27, 0x05, 0x7e, 0x81, 0x87, 0x86, 0x8b, + 0x82, 0x8b, 0x82, 0x92, 0x84, 0x95, 0x8b, 0x90, 0x8b, 0x91, 0x8e, 0x94, + 0x91, 0x08, 0xf7, 0x1b, 0xef, 0x05, 0x0e, 0xf8, 0x48, 0xf9, 0x13, 0x15, + 0xfb, 0x2f, 0xfb, 0x01, 0x87, 0x89, 0x05, 0x82, 0x85, 0x86, 0x83, 0x8b, + 0x83, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x90, 0x8b, 0x92, 0x8e, 0x92, + 0x90, 0x08, 0xf7, 0x13, 0xe3, 0xe3, 0x33, 0x05, 0x91, 0x86, 0x90, 0x88, + 0x90, 0x8b, 0x98, 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x90, 0x89, 0x8e, + 0x84, 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0xc6, 0xf8, + 0xef, 0x15, 0x86, 0x8b, 0x86, 0x89, 0x84, 0x85, 0x66, 0x6c, 0x7f, 0x84, + 0x7b, 0x8b, 0x7e, 0x8b, 0x82, 0x8f, 0x6b, 0xa0, 0x6f, 0x9d, 0x7f, 0x90, + 0x77, 0x8b, 0x73, 0x8b, 0x73, 0x80, 0x69, 0x71, 0x79, 0x7c, 0x83, 0x81, + 0x8b, 0x82, 0x08, 0x82, 0x92, 0x85, 0x94, 0x1e, 0x91, 0x8b, 0x93, 0x8e, + 0x90, 0x90, 0xae, 0xaa, 0x96, 0x91, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x86, + 0x9c, 0x7f, 0xae, 0x73, 0x9c, 0x84, 0xa1, 0x8b, 0xa4, 0x8b, 0xa3, 0x97, + 0xae, 0xa9, 0x9d, 0x9a, 0x8f, 0x90, 0x8b, 0x94, 0x08, 0x94, 0x83, 0x92, + 0x82, 0x1e, 0x0e, 0xf8, 0xa8, 0xf8, 0xac, 0x15, 0x9f, 0x97, 0x94, 0x9a, + 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfb, 0x80, 0x06, 0x77, 0x7f, 0x82, 0x7c, + 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x80, 0x06, 0x0e, 0xf7, 0xd8, 0xf8, + 0xf6, 0x15, 0x84, 0x94, 0x87, 0x8d, 0x85, 0x8b, 0x08, 0x7d, 0x7e, 0x7a, + 0x77, 0x53, 0xbf, 0x64, 0xd3, 0x1f, 0xba, 0x8b, 0xbc, 0x9c, 0xab, 0xa7, + 0x9f, 0x9d, 0xa1, 0xaf, 0x8b, 0x9c, 0x8b, 0x92, 0x82, 0x94, 0x83, 0x8b, + 0x7f, 0x8b, 0x83, 0x83, 0x86, 0x7c, 0x7f, 0x65, 0x56, 0x6d, 0x56, 0x8b, + 0x71, 0x8b, 0x6f, 0x94, 0x7c, 0x97, 0x08, 0x84, 0x91, 0x7b, 0x9f, 0x8b, + 0x8f, 0x08, 0x8d, 0xa8, 0x05, 0x0e, 0xf8, 0x41, 0xf8, 0xf7, 0x15, 0x6c, + 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, + 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf7, 0xd3, 0xf8, 0xf7, 0x15, 0x6c, 0x6d, + 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, + 0x9c, 0x73, 0x1f, 0xf7, 0x71, 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, + 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, + 0xf8, 0x4c, 0xf9, 0x29, 0x15, 0x51, 0x53, 0x56, 0x53, 0x62, 0xab, 0x6c, + 0xb7, 0xc6, 0xc2, 0xc0, 0xc3, 0xb5, 0x6b, 0xa9, 0x5f, 0x1f, 0x84, 0x6a, + 0x15, 0xa7, 0xa0, 0x78, 0x70, 0x67, 0x68, 0x6a, 0x65, 0x6f, 0x76, 0x9f, + 0xa5, 0xae, 0xaf, 0xad, 0xb0, 0x1f, 0x0e, 0xf7, 0xa6, 0x16, 0x7a, 0x3a, + 0xa0, 0x8b, 0x05, 0xa6, 0x99, 0x84, 0x7e, 0x77, 0x75, 0x7d, 0x6e, 0x1f, + 0x7c, 0x8b, 0x7e, 0x8f, 0x77, 0x97, 0x84, 0x8f, 0x88, 0x8c, 0x86, 0x8b, + 0x08, 0x7e, 0x80, 0x80, 0x7e, 0x7b, 0xb7, 0x78, 0xb0, 0xc0, 0xb4, 0xae, + 0xb8, 0x1f, 0x8b, 0xa9, 0x79, 0x9a, 0x67, 0x8c, 0x08, 0x95, 0xba, 0x65, + 0x8b, 0x05, 0x0e, 0xf8, 0x35, 0xf8, 0xe5, 0x15, 0x99, 0x96, 0x8e, 0x8f, + 0x8b, 0x94, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x85, 0x8b, 0x84, 0x88, + 0x83, 0x85, 0x08, 0xfb, 0x09, 0x2d, 0x05, 0x7d, 0x80, 0x88, 0x87, 0x8b, + 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, 0x92, 0x8e, 0x93, + 0x91, 0x08, 0xf7, 0x09, 0xe9, 0x05, 0xf7, 0x22, 0x16, 0x99, 0x96, 0x8e, + 0x8f, 0x8b, 0x94, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x85, 0x8b, 0x84, + 0x88, 0x83, 0x85, 0x08, 0xfb, 0x0a, 0x2d, 0x87, 0x88, 0x05, 0x82, 0x85, + 0x87, 0x84, 0x8b, 0x83, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, + 0x92, 0x8e, 0x93, 0x91, 0x08, 0xf7, 0x0a, 0xe9, 0x05, 0x0e, 0xf8, 0x28, + 0x16, 0x5c, 0x06, 0x48, 0x6e, 0x6b, 0x68, 0x8b, 0x5e, 0x08, 0x6e, 0xa3, + 0x7a, 0xb4, 0xb4, 0xb7, 0xa0, 0x9d, 0x92, 0x86, 0x90, 0x85, 0x1e, 0x89, + 0x8b, 0x87, 0x8a, 0x88, 0x89, 0x72, 0x7d, 0x82, 0x89, 0x79, 0x8b, 0x72, + 0x8b, 0x7e, 0x93, 0x8b, 0x9b, 0x8b, 0xa9, 0xa6, 0xa9, 0xbc, 0xa3, 0x08, + 0xa9, 0x9a, 0x05, 0x0e, 0xf8, 0x28, 0xf8, 0x7e, 0x15, 0xf7, 0x2f, 0xf7, + 0x00, 0x05, 0x99, 0x95, 0x8f, 0x90, 0x8b, 0x95, 0x8b, 0x94, 0x84, 0x92, + 0x82, 0x8b, 0x86, 0x8b, 0x84, 0x88, 0x84, 0x86, 0x08, 0xfb, 0x13, 0x33, + 0x33, 0xe3, 0x05, 0x85, 0x90, 0x86, 0x8e, 0x86, 0x8b, 0x7e, 0x8b, 0x7f, + 0x7f, 0x8b, 0x7e, 0x8b, 0x85, 0x8d, 0x88, 0x93, 0x85, 0x08, 0xf7, 0x00, + 0xfb, 0x01, 0x05, 0x0e, 0xf9, 0x07, 0xf7, 0x99, 0x15, 0x9f, 0x97, 0x95, + 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfc, 0xb4, 0x06, 0x77, 0x7f, 0x81, + 0x7c, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0xb4, 0x06, 0x0e, 0xf7, 0xe5, + 0xf7, 0x51, 0x15, 0x6c, 0xfb, 0x28, 0x57, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xed, 0x8b, 0xa8, 0xf7, 0x1a, + 0x8c, 0x95, 0x05, 0x94, 0x84, 0x92, 0x82, 0x1e, 0x7c, 0x8b, 0x82, 0x83, + 0x89, 0x79, 0x08, 0x77, 0x2e, 0xfb, 0x67, 0x8b, 0xbc, 0xf7, 0x7c, 0xd9, + 0x8b, 0x86, 0x70, 0x05, 0x89, 0x86, 0x8b, 0x88, 0x8b, 0x88, 0x8b, 0x82, + 0x92, 0x84, 0x94, 0x8b, 0x98, 0x8b, 0x94, 0x94, 0x8f, 0x9d, 0x08, 0x9f, + 0xeb, 0x05, 0x8d, 0x93, 0x8b, 0x8c, 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, + 0x82, 0x8b, 0x7d, 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x85, 0x6f, 0x3d, + 0x8b, 0xb7, 0xf7, 0x64, 0xf7, 0x53, 0x8b, 0x74, 0xfb, 0x03, 0x05, 0x8a, + 0x87, 0x8a, 0x85, 0x8b, 0x89, 0x8b, 0x83, 0x92, 0x84, 0x94, 0x8b, 0x99, + 0x8b, 0x94, 0x94, 0x8f, 0x9d, 0x08, 0xab, 0xf7, 0x2c, 0xfc, 0x3e, 0x8b, + 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xca, 0x8b, + 0xfb, 0x7f, 0xfc, 0x75, 0x66, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xf3, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7a, 0x1f, 0x71, 0x8b, 0xd3, 0xf7, 0x28, 0xf7, 0x21, 0x8b, 0x05, + 0x94, 0xb4, 0x15, 0xfb, 0x16, 0x8b, 0xf7, 0x22, 0xf7, 0xb8, 0xbd, 0x8b, + 0x4d, 0xfb, 0xb8, 0x05, 0x0e, 0xf8, 0x39, 0xf7, 0xae, 0x15, 0xca, 0x06, + 0x9b, 0x96, 0x94, 0x99, 0x94, 0x85, 0x90, 0x7e, 0x1f, 0x71, 0x8b, 0xaf, + 0xf7, 0x3f, 0x05, 0x8c, 0x91, 0x8c, 0x90, 0x8b, 0x90, 0x8b, 0xb4, 0x69, + 0xa6, 0x59, 0x8b, 0x71, 0x8b, 0x55, 0x7e, 0x74, 0x80, 0x80, 0x86, 0x86, + 0x84, 0x8b, 0x81, 0x8b, 0x84, 0x91, 0x84, 0x93, 0x8b, 0x8e, 0x8b, 0x8c, + 0x8b, 0x95, 0x8f, 0x08, 0xae, 0x97, 0xa7, 0x92, 0x9d, 0x8b, 0xac, 0x8b, + 0xa2, 0x7c, 0x8b, 0x75, 0x8b, 0x86, 0x8b, 0x8a, 0x8a, 0x87, 0x08, 0x82, + 0x5f, 0x05, 0x6e, 0x91, 0x77, 0x8e, 0x75, 0x8b, 0x08, 0x36, 0x44, 0x58, + 0x4e, 0x1f, 0x63, 0xab, 0x73, 0xbf, 0x1e, 0xb2, 0x8b, 0xa8, 0x92, 0xb8, + 0xa1, 0x08, 0x86, 0x71, 0x05, 0x99, 0xcf, 0x15, 0x62, 0x73, 0x68, 0x81, + 0x64, 0x8b, 0x08, 0x6a, 0x76, 0x98, 0x9e, 0xb2, 0xbf, 0xac, 0xc8, 0x1f, + 0xa2, 0x8b, 0xab, 0x86, 0x99, 0x85, 0x08, 0x7e, 0x50, 0x05, 0x0e, 0xf7, + 0xe5, 0xf8, 0x9e, 0x15, 0xec, 0x06, 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7a, 0x1f, 0xfb, 0x7d, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xeb, 0x8b, 0x5b, 0xfb, 0x79, 0xfb, 0x23, 0x41, 0x05, + 0x7c, 0x84, 0x86, 0x84, 0x8b, 0x81, 0x8b, 0x82, 0x92, 0x83, 0x93, 0x8b, + 0x8f, 0x8b, 0x92, 0x8e, 0x92, 0x8e, 0x08, 0xf7, 0x0c, 0xc9, 0x5f, 0xfb, + 0x61, 0x2b, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, + 0x1f, 0xf8, 0x58, 0x8b, 0xb6, 0xf7, 0x5e, 0x05, 0x8c, 0x8f, 0x8c, 0x91, + 0x8b, 0x8d, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, + 0x87, 0x79, 0x08, 0x69, 0xfb, 0x35, 0xfb, 0xa6, 0x8b, 0xba, 0xf7, 0x72, + 0xf7, 0x42, 0xe7, 0x90, 0x8d, 0x05, 0x96, 0x91, 0x91, 0x92, 0x8b, 0x94, + 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x87, 0x8b, 0x81, 0x88, 0x86, 0x89, + 0x08, 0xfb, 0x2b, 0x3b, 0xb8, 0xf7, 0x68, 0x05, 0x0e, 0xf7, 0x2c, 0xbe, + 0x15, 0xae, 0x5f, 0xbc, 0x74, 0xc7, 0x8b, 0xf7, 0x38, 0x8b, 0xf7, 0x30, + 0xf7, 0x48, 0x8b, 0xf7, 0x52, 0x8b, 0xbd, 0x80, 0xb6, 0x77, 0xaf, 0x08, + 0xe3, 0xe3, 0x05, 0x94, 0x94, 0x8e, 0x90, 0x8b, 0x91, 0x8b, 0x93, 0x85, + 0x91, 0x82, 0x8b, 0x85, 0x8b, 0x86, 0x88, 0x82, 0x82, 0x08, 0x37, 0x38, + 0x05, 0x63, 0xb9, 0x60, 0x9f, 0x4f, 0x8b, 0xfb, 0x38, 0x8b, 0xfb, 0x31, + 0xfb, 0x48, 0x8b, 0xfb, 0x51, 0x8b, 0x5b, 0x95, 0x62, 0xa1, 0x63, 0x08, + 0x33, 0x34, 0x05, 0x82, 0x82, 0x88, 0x86, 0x8b, 0x85, 0x8b, 0x83, 0x91, + 0x85, 0x93, 0x8b, 0x92, 0x8b, 0x90, 0x8e, 0x94, 0x94, 0x08, 0xde, 0xdd, + 0x05, 0x9a, 0xc8, 0x15, 0x7b, 0xac, 0x84, 0xac, 0x8b, 0xb2, 0x8b, 0xf7, + 0x35, 0xf7, 0x1a, 0xf7, 0x31, 0xf7, 0x1e, 0x8b, 0xb9, 0x8b, 0xb3, 0x77, + 0xaa, 0x64, 0x08, 0xfc, 0x02, 0xfc, 0x00, 0x05, 0xf8, 0x14, 0xf7, 0xe5, + 0x15, 0x9a, 0x6c, 0x93, 0x68, 0x8b, 0x64, 0x8b, 0xfb, 0x37, 0xfb, 0x19, + 0xfb, 0x30, 0xfb, 0x1f, 0x8b, 0x5d, 0x8b, 0x62, 0xa0, 0x6d, 0xb1, 0x08, + 0xf8, 0x02, 0xf8, 0x01, 0x05, 0x0e, 0xf8, 0x20, 0xf7, 0xa4, 0x15, 0xd9, + 0x8b, 0x85, 0x6f, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, + 0x8b, 0x93, 0x94, 0x8f, 0x9d, 0x08, 0xa0, 0xeb, 0x8c, 0x90, 0x05, 0x8c, + 0x8d, 0x8b, 0x8e, 0x8b, 0x8d, 0x8b, 0x93, 0x84, 0x92, 0x81, 0x8b, 0x7d, + 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x85, 0x70, 0x3d, 0x8b, 0xb7, 0xf7, + 0x65, 0xf7, 0x53, 0x8b, 0x73, 0xfb, 0x05, 0x8a, 0x7f, 0x05, 0x83, 0x92, + 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x93, 0x94, 0x8f, 0x9d, 0x08, 0xac, 0xf7, + 0x2e, 0xfb, 0xce, 0x8b, 0x05, 0xfb, 0x40, 0xfb, 0x22, 0xfb, 0x37, 0xfb, + 0x59, 0x1f, 0x8b, 0x4e, 0xa1, 0x51, 0xaf, 0x68, 0xac, 0x6b, 0xbc, 0x7a, + 0xc9, 0x8b, 0x08, 0xf7, 0xda, 0x8b, 0xa8, 0xf7, 0x19, 0x8c, 0x96, 0x05, + 0x94, 0x84, 0x92, 0x82, 0x1e, 0x7c, 0x8b, 0x83, 0x83, 0x88, 0x78, 0x08, + 0x77, 0x2f, 0xfb, 0x67, 0x8b, 0xbc, 0xf7, 0x7b, 0x05, 0x97, 0xf7, 0x8e, + 0x15, 0x25, 0xfc, 0x75, 0x6b, 0x8b, 0x05, 0x5b, 0x8b, 0x64, 0x96, 0x71, + 0x9f, 0x67, 0xa8, 0x76, 0xbe, 0x8b, 0xc5, 0x8b, 0xd0, 0xa1, 0xd5, 0xb1, + 0xc2, 0xc0, 0xd8, 0xd0, 0xb0, 0xe5, 0x8b, 0x08, 0xab, 0x06, 0x0e, 0xf8, + 0x3c, 0xf8, 0xd5, 0x15, 0x2e, 0x33, 0x35, 0x30, 0x48, 0xbd, 0x5a, 0xce, + 0xe9, 0xe4, 0xe0, 0xe6, 0xd0, 0x5a, 0xbb, 0x45, 0x1f, 0x83, 0x66, 0x15, + 0xbf, 0xb0, 0x67, 0x58, 0x47, 0x49, 0x4b, 0x45, 0x58, 0x66, 0xb0, 0xbd, + 0xcf, 0xcd, 0xcb, 0xd0, 0x1f, 0x0e, 0xf7, 0xe1, 0xc8, 0x15, 0xa2, 0x59, + 0xb1, 0x70, 0xba, 0x8b, 0xad, 0x8b, 0xb5, 0x9d, 0xbb, 0xaf, 0xa1, 0x9b, + 0x91, 0x92, 0x8b, 0x94, 0x8b, 0x95, 0x84, 0x92, 0x82, 0x8b, 0x87, 0x8b, + 0x85, 0x89, 0x87, 0x88, 0x52, 0x5f, 0x72, 0x7e, 0x6d, 0x8b, 0x08, 0x55, + 0x64, 0xc1, 0xd6, 0x1f, 0x8b, 0x96, 0x8c, 0x9b, 0x8d, 0x9d, 0x08, 0xf7, + 0x96, 0x06, 0x93, 0xb4, 0x8e, 0xa2, 0x8b, 0xac, 0x8b, 0xb9, 0x81, 0xac, + 0x77, 0xa1, 0x78, 0xa0, 0x6e, 0x98, 0x6c, 0x8b, 0x5b, 0x8b, 0x57, 0x6b, + 0x67, 0x57, 0x84, 0xbd, 0x65, 0xad, 0x59, 0x8b, 0x6d, 0x8b, 0x69, 0x83, + 0x62, 0x7a, 0x08, 0x72, 0x81, 0x81, 0x82, 0x8b, 0x7e, 0x8b, 0x83, 0x93, + 0x83, 0x92, 0x8b, 0x90, 0x8b, 0x92, 0x8e, 0x93, 0x8f, 0xa5, 0x9a, 0xaf, + 0x95, 0xa7, 0x8b, 0xb5, 0x8b, 0xa9, 0x6f, 0x8b, 0x63, 0x8b, 0x88, 0x8a, + 0x83, 0x8a, 0x85, 0x08, 0x7e, 0x4f, 0x05, 0x70, 0x93, 0x6f, 0x8f, 0x6f, + 0x8b, 0x47, 0x8b, 0x44, 0x70, 0x64, 0x63, 0x74, 0x73, 0x7f, 0x6d, 0x8b, + 0x66, 0x8b, 0x45, 0xba, 0x5e, 0xd4, 0x8b, 0xb7, 0x8b, 0xb5, 0xa0, 0xbc, + 0xba, 0x08, 0x85, 0x72, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, + 0x98, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, 0x93, 0xad, 0x05, 0x6d, 0xbc, + 0x15, 0x4f, 0x4e, 0x64, 0x73, 0x64, 0x8b, 0x58, 0x8b, 0x69, 0xa9, 0x8b, + 0xb8, 0x8b, 0x9f, 0x93, 0xa4, 0x95, 0x99, 0xa3, 0xaa, 0xcf, 0xa5, 0xc3, + 0x8b, 0xa2, 0x8b, 0xa7, 0x86, 0xa5, 0x83, 0x08, 0x77, 0x2e, 0x05, 0xce, + 0xf7, 0x16, 0x15, 0xae, 0xef, 0xba, 0xbd, 0xc7, 0x8b, 0xbd, 0x8b, 0xa6, + 0x67, 0x8b, 0x49, 0x8b, 0x7d, 0x8a, 0x7f, 0x89, 0x75, 0x08, 0xfb, 0x6c, + 0x06, 0x0e, 0xf8, 0x2d, 0xf8, 0x35, 0x15, 0xfb, 0x33, 0x06, 0x77, 0x7f, + 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x0a, 0x8b, 0x44, 0xfb, + 0xe3, 0xfb, 0x35, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xf7, 0xfe, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, + 0x7a, 0x1f, 0xfb, 0x34, 0x8b, 0xdb, 0xf8, 0x0c, 0x05, 0x0e, 0xf8, 0x53, + 0xf8, 0xf0, 0x15, 0xfb, 0x31, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7e, 0x91, + 0x87, 0x9c, 0x1f, 0xf7, 0x08, 0x8b, 0x59, 0xfb, 0x80, 0xfb, 0x0c, 0x4e, + 0x05, 0x7c, 0x83, 0x85, 0x84, 0x8b, 0x80, 0x8b, 0x82, 0x92, 0x84, 0x93, + 0x8b, 0x91, 0x8b, 0x8e, 0x8c, 0x95, 0x90, 0x08, 0xec, 0xbd, 0x59, 0xfb, + 0x83, 0xfb, 0x33, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xf7, 0xfe, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, + 0x7a, 0x1f, 0xfb, 0x36, 0x8b, 0xc1, 0xf7, 0x94, 0xf7, 0x0d, 0xc9, 0x05, + 0x9a, 0x92, 0x91, 0x92, 0x8b, 0x96, 0x8b, 0x94, 0x84, 0x92, 0x83, 0x8b, + 0x86, 0x8b, 0x86, 0x89, 0x82, 0x87, 0x08, 0x29, 0x58, 0xc2, 0xf7, 0x99, + 0x05, 0x0e, 0xf7, 0x35, 0xae, 0x15, 0xaf, 0x69, 0xb7, 0x7a, 0xc2, 0x8b, + 0xf7, 0x26, 0x8b, 0xf7, 0x1b, 0xf7, 0x15, 0x8b, 0xf7, 0x21, 0x8b, 0xb3, + 0x81, 0xab, 0x75, 0xab, 0x08, 0xd9, 0xcc, 0x05, 0x95, 0x94, 0x8f, 0x90, + 0x8b, 0x92, 0x8b, 0x93, 0x85, 0x91, 0x83, 0x8b, 0x85, 0x8b, 0x87, 0x89, + 0x81, 0x83, 0x08, 0x3d, 0x49, 0x05, 0x68, 0xac, 0x5f, 0x9b, 0x55, 0x8b, + 0xfb, 0x26, 0x8b, 0xfb, 0x1b, 0xfb, 0x15, 0x8b, 0xfb, 0x20, 0x8b, 0x64, + 0x95, 0x6a, 0x9f, 0x6c, 0x08, 0x3b, 0x48, 0x05, 0x81, 0x82, 0x87, 0x86, + 0x8b, 0x84, 0x8b, 0x83, 0x91, 0x85, 0x93, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, + 0x94, 0x93, 0x08, 0xdc, 0xcf, 0x05, 0xf7, 0xf2, 0xf7, 0xba, 0x15, 0x9b, + 0x72, 0x93, 0x70, 0x8b, 0x6b, 0x8b, 0xfb, 0x06, 0xfb, 0x02, 0x21, 0xfb, + 0x0c, 0x8b, 0x5f, 0x8b, 0x66, 0x99, 0x70, 0xa5, 0x08, 0xf7, 0xce, 0xf7, + 0x9c, 0x05, 0xfb, 0xe3, 0xfb, 0x84, 0x15, 0x7c, 0xa3, 0x83, 0xa6, 0x8b, + 0xaa, 0x8b, 0xf7, 0x06, 0xf7, 0x02, 0xf4, 0xf7, 0x0c, 0x8b, 0xb6, 0x8b, + 0xae, 0x7f, 0xa8, 0x71, 0x08, 0xfb, 0xce, 0xfb, 0x9b, 0x05, 0x0e, 0xf8, + 0xff, 0xf7, 0x5b, 0x15, 0x93, 0xb4, 0x8e, 0xa1, 0x8b, 0xac, 0x8b, 0xba, + 0x82, 0xac, 0x76, 0xa1, 0x78, 0xa0, 0x6e, 0x98, 0x6c, 0x8b, 0x6e, 0x8b, + 0x6b, 0x7e, 0x6c, 0x73, 0x74, 0x79, 0x7e, 0x7b, 0x71, 0x60, 0x7e, 0xd0, + 0x60, 0xb8, 0x56, 0x8b, 0x08, 0x23, 0x23, 0xfb, 0x24, 0xfb, 0x22, 0x2e, + 0xba, 0x47, 0xcc, 0x1f, 0xc3, 0x8b, 0xc4, 0xb6, 0xb9, 0xd7, 0x99, 0x41, + 0xb9, 0x5e, 0xc6, 0x8b, 0xad, 0x8b, 0xb5, 0x9d, 0xbb, 0xaf, 0xa1, 0x9b, + 0x91, 0x92, 0x8b, 0x94, 0x8b, 0x95, 0x84, 0x92, 0x82, 0x8b, 0x87, 0x8b, + 0x85, 0x89, 0x87, 0x88, 0x08, 0x52, 0x5f, 0x72, 0x7e, 0x6e, 0x8b, 0x55, + 0x8b, 0x65, 0xc3, 0x8b, 0xdd, 0x8b, 0x93, 0x8c, 0x97, 0x8d, 0x9b, 0x08, + 0xf7, 0x95, 0x06, 0xfb, 0x8c, 0xb4, 0x15, 0xad, 0xef, 0xba, 0xbd, 0xc7, + 0x8b, 0xbd, 0x8b, 0xa6, 0x67, 0x8b, 0x48, 0x8b, 0x7e, 0x8a, 0x7f, 0x89, + 0x75, 0x08, 0xfb, 0x6b, 0x06, 0xfb, 0x0e, 0xf7, 0x2a, 0x15, 0xbb, 0x88, + 0xac, 0x58, 0x8b, 0x46, 0x08, 0xfb, 0x0a, 0x39, 0xfb, 0x10, 0x3d, 0x5f, + 0x68, 0xc3, 0xd0, 0x1e, 0x8b, 0xbe, 0x9b, 0xc3, 0xa6, 0xb8, 0xaa, 0xbf, + 0xbd, 0xb1, 0xad, 0x89, 0x08, 0x0e, 0xf7, 0x19, 0xb4, 0x15, 0x55, 0x06, + 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x02, 0x06, + 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x7c, 0x8b, 0xe8, + 0xf8, 0x47, 0x05, 0x95, 0xbc, 0xbf, 0xb1, 0xc4, 0x8b, 0xbd, 0x8b, 0xae, + 0x68, 0x8b, 0x5b, 0x8b, 0x69, 0x7b, 0x6f, 0x6c, 0x77, 0x75, 0x7c, 0x71, + 0x83, 0x76, 0x8b, 0x08, 0x86, 0x06, 0x7b, 0x7f, 0x80, 0x7d, 0x80, 0x91, + 0x86, 0x9d, 0x1f, 0x8f, 0x06, 0xdc, 0xcd, 0x4f, 0x41, 0x34, 0x4c, 0x33, + 0x4c, 0x6a, 0x79, 0x9f, 0xb1, 0x1f, 0x8b, 0x91, 0x8b, 0x91, 0x8c, 0x90, + 0x8c, 0x8f, 0x8b, 0x8e, 0x8b, 0x8d, 0x08, 0x94, 0x84, 0x91, 0x82, 0x79, + 0x81, 0x7a, 0x6f, 0x4e, 0xa9, 0x69, 0xc0, 0x1e, 0xbf, 0x8b, 0xba, 0xa9, + 0xb0, 0xc4, 0xa5, 0xb3, 0x9b, 0xbf, 0x8b, 0xb6, 0x8b, 0xd1, 0x68, 0xbd, + 0x42, 0xac, 0x08, 0xc2, 0xab, 0xa6, 0xb6, 0x8b, 0xc0, 0x8b, 0xd0, 0x5b, + 0xbb, 0x46, 0x8b, 0x3c, 0x8b, 0x3e, 0x52, 0x7c, 0x44, 0x08, 0x2f, 0xfc, + 0x47, 0x05, 0x0e, 0xf8, 0x68, 0xf7, 0x50, 0x15, 0xa4, 0xfb, 0x27, 0x3f, + 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, + 0x30, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x66, + 0x8b, 0x34, 0xf8, 0x9e, 0xfb, 0x5f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, + 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0xad, 0xfc, 0x75, + 0x6c, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x2b, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0x3c, 0x8b, 0xe1, 0xf7, 0x27, 0xf7, 0x9d, 0x8b, 0x05, 0x85, 0xb4, 0x15, + 0xfb, 0x7f, 0x8b, 0xf7, 0x3e, 0xf7, 0xb9, 0x9a, 0x8b, 0xbd, 0xfb, 0xb9, + 0x05, 0xfb, 0x1e, 0xf8, 0xa8, 0x15, 0x6c, 0x6c, 0x6d, 0x6d, 0x74, 0x9c, + 0x7a, 0xa3, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, + 0x72, 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, + 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf8, 0x68, 0xf7, 0x50, + 0x15, 0xa4, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x30, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, + 0x85, 0x8f, 0x7a, 0x1f, 0x66, 0x8b, 0x34, 0xf8, 0x9e, 0xfb, 0x5f, 0x8b, + 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x0c, + 0x8b, 0xfb, 0xad, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, + 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2b, 0x06, 0x9e, 0x98, 0x95, 0x9a, + 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x3c, 0x8b, 0xe1, 0xf7, 0x27, 0xf7, 0x9d, + 0x8b, 0x05, 0x85, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, 0x3e, 0xf7, 0xb9, + 0x9a, 0x8b, 0xbd, 0xfb, 0xb9, 0x05, 0xcf, 0xf8, 0x9c, 0x15, 0x8f, 0x8e, + 0x05, 0x94, 0x92, 0x8f, 0x91, 0x8b, 0x93, 0x8b, 0x94, 0x84, 0x92, 0x81, + 0x8b, 0x86, 0x8b, 0x85, 0x88, 0x82, 0x85, 0x08, 0xfb, 0x1c, 0x27, 0x05, + 0x7f, 0x82, 0x87, 0x85, 0x8b, 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, + 0x91, 0x8b, 0x8f, 0x8d, 0x95, 0x92, 0x08, 0xf7, 0x1c, 0xef, 0x05, 0x0e, + 0xf8, 0x68, 0xf7, 0x50, 0x15, 0xa4, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x30, 0x06, 0x9f, + 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x66, 0x8b, 0x34, 0xf8, + 0x9e, 0xfb, 0x5f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0xad, 0xfc, 0x75, 0x6c, 0x8b, 0x05, + 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2b, 0x06, + 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x3c, 0x8b, 0xe1, + 0xf7, 0x27, 0xf7, 0x9d, 0x8b, 0x05, 0x85, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, + 0xf7, 0x3e, 0xf7, 0xb9, 0x9a, 0x8b, 0xbd, 0xfb, 0xb9, 0x05, 0x2e, 0xf8, + 0xbb, 0x15, 0x84, 0x92, 0x87, 0x8d, 0x86, 0x8b, 0x7e, 0x8b, 0x7e, 0x7f, + 0x8b, 0x7f, 0x8b, 0x86, 0x8e, 0x86, 0x90, 0x85, 0x08, 0xe8, 0x27, 0x05, + 0x91, 0x85, 0x91, 0x88, 0x90, 0x8b, 0x99, 0x8b, 0x97, 0x97, 0x8b, 0x98, + 0x8b, 0x8e, 0x8b, 0x8b, 0x82, 0x97, 0x08, 0x2e, 0xef, 0x05, 0x0e, 0xf8, + 0x68, 0xf7, 0x50, 0x15, 0xa4, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x77, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x30, 0x06, 0x9f, 0x97, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x66, 0x8b, 0x34, 0xf8, 0x9e, + 0xfb, 0x5f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, + 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0xad, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2b, 0x06, 0x9e, + 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x3c, 0x8b, 0xe1, 0xf7, + 0x27, 0xf7, 0x9d, 0x8b, 0x05, 0x85, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, + 0x3e, 0xf7, 0xb9, 0x9a, 0x8b, 0xbd, 0xfb, 0xb9, 0x05, 0x76, 0xf8, 0xc4, + 0x15, 0xfb, 0x2f, 0xfb, 0x01, 0x87, 0x89, 0x05, 0x82, 0x85, 0x86, 0x83, + 0x8b, 0x83, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, 0x91, 0x8e, + 0x93, 0x90, 0x08, 0xf7, 0x12, 0xe3, 0xe4, 0x33, 0x05, 0x90, 0x86, 0x91, + 0x88, 0x8f, 0x8b, 0x98, 0x8b, 0x98, 0x97, 0x8b, 0x98, 0x8b, 0x90, 0x89, + 0x8e, 0x83, 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x68, + 0xf7, 0x50, 0x15, 0xa4, 0xfb, 0x27, 0x3f, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x30, 0x06, 0x9f, 0x97, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x66, 0x8b, 0x34, 0xf8, 0x9e, 0xfb, + 0x5f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x0c, 0x8b, 0xfb, 0xad, 0xfc, 0x75, 0x6c, 0x8b, 0x05, 0x77, 0x7f, + 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2b, 0x06, 0x9e, 0x98, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x3c, 0x8b, 0xe1, 0xf7, 0x27, + 0xf7, 0x9d, 0x8b, 0x05, 0x85, 0xb4, 0x15, 0xfb, 0x7f, 0x8b, 0xf7, 0x3e, + 0xf7, 0xb9, 0x9a, 0x8b, 0xbd, 0xfb, 0xb9, 0x05, 0xf5, 0xf8, 0xa0, 0x15, + 0x86, 0x8b, 0x86, 0x89, 0x84, 0x85, 0x67, 0x6c, 0x7e, 0x84, 0x7b, 0x8b, + 0x7e, 0x8b, 0x81, 0x90, 0x6c, 0x9f, 0x6f, 0x9e, 0x80, 0x8f, 0x76, 0x8b, + 0x72, 0x8b, 0x74, 0x81, 0x69, 0x70, 0x78, 0x7c, 0x84, 0x81, 0x8b, 0x82, + 0x08, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x91, 0x8b, 0x93, 0x8e, 0x90, 0x90, + 0xae, 0xa9, 0x96, 0x92, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x86, 0x9c, 0x7f, + 0xae, 0x73, 0x9c, 0x84, 0xa1, 0x8b, 0xa4, 0x8b, 0xa4, 0x97, 0xad, 0xa9, + 0x9d, 0x9a, 0x8f, 0x90, 0x8b, 0x95, 0x08, 0x93, 0x83, 0x92, 0x82, 0x1e, + 0x0e, 0xf8, 0x68, 0xf7, 0x50, 0x15, 0xa4, 0xfb, 0x27, 0x3f, 0x8b, 0x05, + 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x30, 0x06, + 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x66, 0x8b, 0x34, + 0xf8, 0x9e, 0xfb, 0x5f, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0x0c, 0x8b, 0xfb, 0xad, 0xfc, 0x75, 0x6c, 0x8b, + 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2b, + 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x3c, 0x8b, + 0xe1, 0xf7, 0x27, 0xf7, 0x9d, 0x8b, 0x05, 0x85, 0xb4, 0x15, 0xfb, 0x7f, + 0x8b, 0xf7, 0x3e, 0xf7, 0xb9, 0x9a, 0x8b, 0xbd, 0xfb, 0xb9, 0x05, 0x7e, + 0xf8, 0xda, 0x15, 0x51, 0x53, 0x56, 0x54, 0x61, 0xab, 0x6c, 0xb6, 0xc7, + 0xc2, 0xc0, 0xc3, 0xb5, 0x6b, 0xa9, 0x5f, 0x1f, 0x84, 0x6a, 0x15, 0xa7, + 0xa0, 0x78, 0x70, 0x67, 0x68, 0x6a, 0x64, 0x70, 0x76, 0x9f, 0xa5, 0xae, + 0xae, 0xad, 0xb1, 0x1f, 0x0e, 0xf7, 0xce, 0x7b, 0x15, 0x98, 0x06, 0xc8, + 0x8b, 0xd8, 0xac, 0xc6, 0xbe, 0xa6, 0xa2, 0x92, 0x94, 0x8b, 0x96, 0x8b, + 0x93, 0x84, 0x91, 0x82, 0x8b, 0x83, 0x8b, 0x87, 0x89, 0x83, 0x83, 0x47, + 0x4b, 0x52, 0x71, 0x46, 0x8b, 0x26, 0x8b, 0x40, 0xd7, 0x8b, 0xf1, 0x08, + 0x8b, 0x99, 0x8d, 0x9b, 0x8e, 0x9a, 0x08, 0x9a, 0xd2, 0x05, 0xa4, 0xf7, + 0x0b, 0xf7, 0x04, 0xed, 0xf7, 0x02, 0x8b, 0xb8, 0x8b, 0xbe, 0x79, 0xa2, + 0x73, 0x93, 0x83, 0xa3, 0x66, 0x8b, 0x88, 0x08, 0x87, 0x65, 0x05, 0x90, + 0x83, 0x91, 0x87, 0x91, 0x8b, 0x98, 0x8b, 0x95, 0x95, 0x8e, 0x9d, 0x08, + 0xa3, 0xf7, 0x04, 0x05, 0x8c, 0x90, 0x8c, 0x90, 0x8b, 0x8d, 0x08, 0x94, + 0x84, 0x91, 0x81, 0x1e, 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x85, + 0x6e, 0x05, 0x66, 0xb8, 0x54, 0xa3, 0x49, 0x8b, 0x48, 0x8b, 0x4a, 0x71, + 0x55, 0x5b, 0x55, 0x5c, 0x60, 0x46, 0x7e, 0x4e, 0x08, 0x7a, 0x38, 0x05, + 0x88, 0x7c, 0x89, 0x7c, 0x8b, 0x7b, 0x8b, 0x49, 0xa9, 0x4c, 0xbc, 0x64, + 0xa4, 0x77, 0xa0, 0x82, 0xb5, 0x80, 0x08, 0x7c, 0x46, 0xa0, 0x8b, 0x05, + 0xa7, 0x98, 0x84, 0x7e, 0x77, 0x75, 0x7d, 0x6e, 0x1f, 0x7c, 0x8b, 0x7d, + 0x8f, 0x78, 0x97, 0x83, 0x8f, 0x89, 0x8c, 0x86, 0x8b, 0x08, 0x7f, 0x7f, + 0x80, 0x7e, 0x7b, 0xb7, 0x78, 0xb0, 0xc0, 0xb4, 0xae, 0xb8, 0x1f, 0x8b, + 0xa9, 0x79, 0x9a, 0x67, 0x8c, 0x08, 0x92, 0xaa, 0x05, 0x0e, 0xf7, 0x36, + 0xf7, 0xa4, 0x15, 0x5a, 0xfb, 0x7b, 0x69, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x70, 0x06, 0xf7, 0x12, 0x8b, + 0xf7, 0x14, 0xf7, 0x07, 0xa9, 0xf7, 0x1f, 0x08, 0x97, 0xc3, 0x05, 0x8f, + 0x9e, 0x8d, 0x9d, 0x8b, 0x9e, 0x08, 0xf7, 0x07, 0x3f, 0xdd, 0x21, 0x1e, + 0xfb, 0x70, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xad, 0x8b, 0x5f, 0xfb, 0x65, 0x3e, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, + 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xd8, 0x06, 0xe9, 0xf7, 0x8e, 0x15, 0xf7, + 0x23, 0x06, 0xc1, 0x8b, 0xae, 0x7c, 0xa5, 0x68, 0xa3, 0x6b, 0x98, 0x62, + 0x8b, 0x61, 0x8b, 0x7f, 0x8a, 0x7d, 0x88, 0x7f, 0x08, 0x7b, 0x41, 0x05, + 0x75, 0x22, 0xfb, 0x03, 0x28, 0x2c, 0x8b, 0x08, 0xfb, 0x29, 0x8b, 0xbc, + 0xf7, 0x7b, 0xf7, 0x36, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7a, 0x1f, 0xfb, 0x36, 0x8b, 0xb7, 0xf7, 0x65, 0x05, 0x0e, 0xf7, + 0x73, 0xf7, 0xa4, 0x15, 0xf7, 0x25, 0x8b, 0x81, 0x5e, 0x8a, 0x7f, 0x05, + 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, + 0xa7, 0xf7, 0x17, 0x05, 0x8c, 0x8f, 0x8c, 0x91, 0x8b, 0x8d, 0x8b, 0x93, + 0x84, 0x92, 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x82, + 0x5e, 0xfb, 0x25, 0x8b, 0xb7, 0xf7, 0x65, 0xf7, 0xb9, 0x8b, 0x76, 0x29, + 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, + 0x8e, 0x9d, 0x08, 0xa9, 0xf7, 0x1f, 0xfc, 0x41, 0x8b, 0x05, 0x77, 0x7f, + 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x25, 0xfc, 0x75, + 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf8, 0x56, 0x8b, 0xad, 0xf7, 0x34, 0x05, 0x8c, 0x90, 0x8c, 0x8f, 0x8b, + 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, 0x87, + 0x79, 0x08, 0x72, 0xfb, 0x0b, 0xfb, 0xce, 0x8b, 0xbc, 0xf7, 0x7b, 0x05, + 0xf7, 0x0c, 0xf8, 0x7d, 0x15, 0x6c, 0x6c, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, + 0xa3, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, 0x71, + 0x16, 0x6c, 0x6c, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa3, 0xab, 0xa9, 0xa8, + 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf7, 0x73, 0xf7, 0xa4, 0x15, + 0xf7, 0x25, 0x8b, 0x81, 0x5e, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, + 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, 0xa7, 0xf7, 0x17, 0x05, + 0x8c, 0x8f, 0x8c, 0x91, 0x8b, 0x8d, 0x8b, 0x93, 0x84, 0x92, 0x81, 0x8b, + 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x82, 0x5e, 0xfb, 0x25, 0x8b, + 0xb7, 0xf7, 0x65, 0xf7, 0xb9, 0x8b, 0x76, 0x29, 0x8a, 0x7f, 0x05, 0x83, + 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, 0xa9, + 0xf7, 0x1f, 0xfc, 0x41, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, + 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x25, 0xfc, 0x75, 0x55, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0x56, 0x8b, 0xad, + 0xf7, 0x34, 0x05, 0x8c, 0x90, 0x8c, 0x8f, 0x8b, 0x8e, 0x8b, 0x93, 0x84, + 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x72, 0xfb, + 0x0b, 0xfb, 0xce, 0x8b, 0xbc, 0xf7, 0x7b, 0x05, 0xf7, 0xd9, 0xf8, 0x71, + 0x15, 0x98, 0x95, 0x8f, 0x90, 0x8b, 0x94, 0x8b, 0x94, 0x84, 0x92, 0x81, + 0x8b, 0x86, 0x8b, 0x85, 0x89, 0x82, 0x84, 0x08, 0xfb, 0x1b, 0x27, 0x05, + 0x7e, 0x82, 0x87, 0x85, 0x8b, 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, + 0x91, 0x8b, 0x90, 0x8d, 0x95, 0x92, 0x08, 0xf7, 0x1b, 0xef, 0x05, 0x0e, + 0xf7, 0x73, 0xf7, 0xa4, 0x15, 0xf7, 0x25, 0x8b, 0x81, 0x5e, 0x8a, 0x7f, + 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, + 0x08, 0xa7, 0xf7, 0x17, 0x05, 0x8c, 0x8f, 0x8c, 0x91, 0x8b, 0x8d, 0x8b, + 0x93, 0x84, 0x92, 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, + 0x82, 0x5e, 0xfb, 0x25, 0x8b, 0xb7, 0xf7, 0x65, 0xf7, 0xb9, 0x8b, 0x76, + 0x29, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, + 0x94, 0x8e, 0x9d, 0x08, 0xa9, 0xf7, 0x1f, 0xfc, 0x41, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x25, 0xfc, + 0x75, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, + 0x1f, 0xf8, 0x56, 0x8b, 0xad, 0xf7, 0x34, 0x05, 0x8c, 0x90, 0x8c, 0x8f, + 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, + 0x87, 0x79, 0x08, 0x72, 0xfb, 0x0b, 0xfb, 0xce, 0x8b, 0xbc, 0xf7, 0x7b, + 0x05, 0xf7, 0x31, 0xf8, 0x90, 0x15, 0x85, 0x91, 0x87, 0x8e, 0x85, 0x8b, + 0x7f, 0x8b, 0x7e, 0x7f, 0x8b, 0x7f, 0x8b, 0x86, 0x8e, 0x85, 0x90, 0x86, + 0x08, 0xe8, 0x27, 0x05, 0x91, 0x85, 0x90, 0x88, 0x90, 0x8b, 0x99, 0x8b, + 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x8e, 0x86, 0x93, 0x87, 0x8f, 0x08, 0x2e, + 0xef, 0x05, 0x0e, 0xf7, 0x73, 0xf7, 0xa4, 0x15, 0xf7, 0x25, 0x8b, 0x81, + 0x5e, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, + 0x94, 0x8e, 0x9d, 0x08, 0xa7, 0xf7, 0x17, 0x05, 0x8c, 0x8f, 0x8c, 0x91, + 0x8b, 0x8d, 0x8b, 0x93, 0x84, 0x92, 0x81, 0x8b, 0x7e, 0x8b, 0x82, 0x82, + 0x87, 0x79, 0x08, 0x82, 0x5e, 0xfb, 0x25, 0x8b, 0xb7, 0xf7, 0x65, 0xf7, + 0xb9, 0x8b, 0x76, 0x29, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, + 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, 0xa9, 0xf7, 0x1f, 0xfc, 0x41, + 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xc1, + 0x8b, 0x25, 0xfc, 0x75, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, + 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0x56, 0x8b, 0xad, 0xf7, 0x34, 0x05, 0x8c, + 0x90, 0x8c, 0x8f, 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, + 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x72, 0xfb, 0x0b, 0xfb, 0xce, 0x8b, + 0xbc, 0xf7, 0x7b, 0x05, 0xf7, 0x81, 0xf8, 0x99, 0x15, 0xfb, 0x2f, 0xfb, + 0x01, 0x86, 0x89, 0x05, 0x82, 0x85, 0x86, 0x83, 0x8b, 0x83, 0x8b, 0x82, + 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, 0x91, 0x8e, 0x93, 0x90, 0x08, 0xf7, + 0x12, 0xe3, 0xe4, 0x33, 0x05, 0x91, 0x86, 0x90, 0x88, 0x90, 0x8b, 0x97, + 0x8b, 0x98, 0x97, 0x8b, 0x98, 0x8b, 0x90, 0x89, 0x8e, 0x83, 0x93, 0x08, + 0xfb, 0x00, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x43, 0xf8, 0x9e, 0x15, 0xf7, + 0x1f, 0x06, 0x9f, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, + 0xd4, 0x06, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, + 0x1f, 0x8b, 0x25, 0xfc, 0x75, 0xfb, 0x20, 0x8b, 0x05, 0x78, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xd3, 0x06, 0x9f, 0x98, 0x95, + 0x9a, 0x97, 0x84, 0x8f, 0x7a, 0x1f, 0xfb, 0x1f, 0x8b, 0xf1, 0xf8, 0x75, + 0x05, 0x3a, 0xf7, 0x83, 0x15, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, + 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, 0x72, + 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, + 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf8, 0x43, 0xf8, 0x9e, 0x15, + 0xf7, 0x20, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, + 0xfb, 0xd4, 0x06, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x1f, 0x8b, 0x25, 0xfc, 0x75, 0xfb, 0x20, 0x8b, 0x05, 0x78, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xd4, 0x06, 0x9e, 0x98, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0x1f, 0x8b, 0xf1, 0xf8, + 0x75, 0x05, 0xf7, 0x10, 0xf7, 0x77, 0x15, 0x97, 0x94, 0x90, 0x92, 0x8b, + 0x92, 0x8b, 0x94, 0x84, 0x93, 0x82, 0x8b, 0x84, 0x8b, 0x86, 0x89, 0x82, + 0x84, 0x08, 0xfb, 0x1b, 0x27, 0x05, 0x7f, 0x82, 0x86, 0x84, 0x8b, 0x84, + 0x8b, 0x81, 0x92, 0x84, 0x96, 0x8b, 0x8f, 0x8b, 0x95, 0x8f, 0x91, 0x90, + 0x08, 0xf7, 0x1a, 0xef, 0x05, 0x0e, 0xf8, 0x43, 0xf8, 0x9e, 0x15, 0xf7, + 0x20, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, + 0xd4, 0x06, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, + 0x1f, 0x8b, 0x25, 0xfc, 0x75, 0xfb, 0x20, 0x8b, 0x05, 0x78, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xd4, 0x06, 0x9e, 0x98, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0x1f, 0x8b, 0xf1, 0xf8, 0x75, + 0x05, 0x68, 0xf7, 0x96, 0x15, 0x84, 0x92, 0x87, 0x8d, 0x86, 0x8b, 0x7e, + 0x8b, 0x7e, 0x7f, 0x8b, 0x7f, 0x8b, 0x86, 0x8d, 0x86, 0x91, 0x85, 0x08, + 0xe8, 0x27, 0x05, 0x91, 0x85, 0x91, 0x88, 0x90, 0x8b, 0x98, 0x8b, 0x98, + 0x97, 0x8b, 0x98, 0x8b, 0x8e, 0x8b, 0x8b, 0x81, 0x97, 0x08, 0x2f, 0xef, + 0x05, 0x0e, 0xf8, 0x43, 0xf8, 0x9e, 0x15, 0xf7, 0x20, 0x06, 0x9e, 0x98, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0xd4, 0x06, 0x78, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x1f, 0x8b, 0x25, 0xfc, + 0x75, 0xfb, 0x20, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xf7, 0xd4, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, + 0x79, 0x1f, 0xfb, 0x1f, 0x8b, 0xf1, 0xf8, 0x75, 0x05, 0xb0, 0xf7, 0x9f, + 0x15, 0xfb, 0x2f, 0xfb, 0x01, 0x05, 0x7e, 0x83, 0x86, 0x85, 0x8b, 0x81, + 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x90, 0x8b, 0x91, 0x8d, 0x93, 0x91, + 0x08, 0xf7, 0x13, 0xe3, 0xe4, 0x33, 0x05, 0x90, 0x86, 0x90, 0x88, 0x90, + 0x8b, 0x97, 0x8b, 0x98, 0x97, 0x8b, 0x98, 0x8b, 0x91, 0x8a, 0x8d, 0x83, + 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x89, 0x16, 0xf7, + 0x03, 0xf8, 0x9e, 0xad, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7a, 0x1f, 0xfb, 0x2a, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x29, 0xfc, 0x63, 0xfb, 0x5a, 0xf8, 0x8c, + 0x21, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, + 0xc1, 0x8b, 0x25, 0xfc, 0x75, 0x69, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, + 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x2a, 0x06, 0x9e, 0x98, 0x95, 0x9a, + 0x97, 0x84, 0x8f, 0x7a, 0x1f, 0x41, 0x8b, 0xed, 0xf8, 0x63, 0xf7, 0x5a, + 0xfc, 0x8c, 0xbf, 0x8b, 0x05, 0xe7, 0xf9, 0x85, 0x15, 0x86, 0x8b, 0x86, + 0x89, 0x84, 0x85, 0x66, 0x6c, 0x7f, 0x84, 0x7b, 0x8b, 0x7e, 0x8b, 0x82, + 0x90, 0x6b, 0x9f, 0x6f, 0x9e, 0x80, 0x8f, 0x76, 0x8b, 0x72, 0x8b, 0x74, + 0x80, 0x69, 0x71, 0x78, 0x7c, 0x84, 0x81, 0x8b, 0x82, 0x08, 0x82, 0x92, + 0x85, 0x94, 0x1e, 0x91, 0x8b, 0x93, 0x8e, 0x90, 0x90, 0xae, 0xaa, 0x96, + 0x91, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x86, 0x9c, 0x7f, 0xae, 0x73, 0x9c, + 0x84, 0xa1, 0x8b, 0xa4, 0x8b, 0xa4, 0x97, 0xad, 0xa9, 0x9d, 0x9a, 0x8f, + 0x90, 0x8b, 0x95, 0x08, 0x93, 0x83, 0x92, 0x82, 0x1e, 0x0e, 0xf8, 0x3a, + 0xf8, 0xd4, 0x15, 0xfb, 0x38, 0xfb, 0x30, 0xfb, 0x48, 0xfb, 0x51, 0xfb, + 0x19, 0xda, 0x31, 0xf7, 0x07, 0xf7, 0x39, 0xf7, 0x2f, 0xf7, 0x48, 0xf7, + 0x55, 0xf7, 0x15, 0x3b, 0xe5, 0xfb, 0x06, 0x1f, 0x84, 0x62, 0x15, 0xe7, + 0xce, 0x3b, 0xfb, 0x02, 0xfb, 0x38, 0xfb, 0x19, 0xfb, 0x30, 0xfb, 0x1f, + 0x30, 0x48, 0xdc, 0xf7, 0x02, 0xf7, 0x36, 0xf7, 0x19, 0xf7, 0x31, 0xf7, + 0x1e, 0x1f, 0x4a, 0xf7, 0x76, 0x15, 0x6c, 0x6c, 0x6d, 0x6d, 0x74, 0x9c, + 0x7a, 0xa2, 0xab, 0xaa, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, + 0x72, 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, + 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf8, 0x3a, 0xf8, 0xd4, + 0x15, 0xfb, 0x38, 0xfb, 0x30, 0xfb, 0x48, 0xfb, 0x51, 0xfb, 0x19, 0xda, + 0x31, 0xf7, 0x07, 0xf7, 0x39, 0xf7, 0x2f, 0xf7, 0x48, 0xf7, 0x55, 0xf7, + 0x15, 0x3b, 0xe5, 0xfb, 0x06, 0x1f, 0x84, 0x62, 0x15, 0xe7, 0xce, 0x3b, + 0xfb, 0x02, 0xfb, 0x38, 0xfb, 0x19, 0xfb, 0x30, 0xfb, 0x1f, 0x30, 0x48, + 0xdc, 0xf7, 0x02, 0xf7, 0x36, 0xf7, 0x19, 0xf7, 0x31, 0xf7, 0x1e, 0x1f, + 0xf7, 0x27, 0xf7, 0x6a, 0x15, 0x99, 0x95, 0x8f, 0x8f, 0x8b, 0x95, 0x8b, + 0x94, 0x84, 0x92, 0x81, 0x8b, 0x85, 0x8b, 0x85, 0x88, 0x82, 0x85, 0x08, + 0xfb, 0x1b, 0x27, 0x05, 0x80, 0x83, 0x86, 0x84, 0x8b, 0x82, 0x8b, 0x82, + 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x95, 0x92, 0x08, 0xf7, + 0x1b, 0xef, 0x05, 0x0e, 0xf8, 0x3a, 0xf8, 0xd4, 0x15, 0xfb, 0x38, 0xfb, + 0x30, 0xfb, 0x48, 0xfb, 0x51, 0xfb, 0x19, 0xda, 0x31, 0xf7, 0x07, 0xf7, + 0x39, 0xf7, 0x2f, 0xf7, 0x48, 0xf7, 0x55, 0xf7, 0x15, 0x3b, 0xe5, 0xfb, + 0x06, 0x1f, 0x84, 0x62, 0x15, 0xe7, 0xce, 0x3b, 0xfb, 0x02, 0xfb, 0x38, + 0xfb, 0x19, 0xfb, 0x30, 0xfb, 0x1f, 0x30, 0x48, 0xdc, 0xf7, 0x02, 0xf7, + 0x36, 0xf7, 0x19, 0xf7, 0x31, 0xf7, 0x1e, 0x1f, 0x70, 0xf7, 0x89, 0x15, + 0x85, 0x92, 0x87, 0x8d, 0x85, 0x8b, 0x7f, 0x8b, 0x7e, 0x7f, 0x8b, 0x7f, + 0x8b, 0x86, 0x8e, 0x85, 0x90, 0x86, 0x08, 0xe8, 0x27, 0x05, 0x91, 0x85, + 0x90, 0x88, 0x90, 0x8b, 0x99, 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x8d, + 0x88, 0x90, 0x85, 0x93, 0x08, 0x2e, 0xef, 0x05, 0x0e, 0xf8, 0x3a, 0xf8, + 0xd4, 0x15, 0xfb, 0x38, 0xfb, 0x30, 0xfb, 0x48, 0xfb, 0x51, 0xfb, 0x19, + 0xda, 0x31, 0xf7, 0x07, 0xf7, 0x39, 0xf7, 0x2f, 0xf7, 0x48, 0xf7, 0x55, + 0xf7, 0x15, 0x3b, 0xe5, 0xfb, 0x06, 0x1f, 0x84, 0x62, 0x15, 0xe7, 0xce, + 0x3b, 0xfb, 0x02, 0xfb, 0x38, 0xfb, 0x19, 0xfb, 0x30, 0xfb, 0x1f, 0x30, + 0x48, 0xdc, 0xf7, 0x02, 0xf7, 0x36, 0xf7, 0x19, 0xf7, 0x31, 0xf7, 0x1e, + 0x1f, 0xbf, 0xf7, 0x92, 0x15, 0xfb, 0x2f, 0xfb, 0x01, 0x87, 0x89, 0x05, + 0x82, 0x85, 0x86, 0x83, 0x8b, 0x83, 0x8b, 0x82, 0x92, 0x84, 0x95, 0x8b, + 0x90, 0x8b, 0x91, 0x8e, 0x93, 0x90, 0x08, 0xf7, 0x12, 0xe3, 0xe4, 0x33, + 0x05, 0x91, 0x86, 0x90, 0x88, 0x8f, 0x8b, 0x98, 0x8b, 0x98, 0x97, 0x8b, + 0x98, 0x8b, 0x90, 0x89, 0x8e, 0x83, 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, + 0x05, 0x0e, 0xf8, 0x3b, 0xf8, 0xd4, 0x15, 0xfb, 0x38, 0xfb, 0x30, 0xfb, + 0x48, 0xfb, 0x51, 0xfb, 0x19, 0xda, 0x31, 0xf7, 0x07, 0xf7, 0x39, 0xf7, + 0x2f, 0xf7, 0x48, 0xf7, 0x55, 0xf7, 0x15, 0x3b, 0xe5, 0xfb, 0x06, 0x1f, + 0x84, 0x62, 0x15, 0xe7, 0xce, 0x3b, 0xfb, 0x02, 0xfb, 0x38, 0xfb, 0x19, + 0xfb, 0x30, 0xfb, 0x1f, 0x2f, 0x49, 0xdb, 0xf7, 0x03, 0xf7, 0x36, 0xf7, + 0x19, 0xf7, 0x31, 0xf7, 0x1e, 0x1f, 0xf7, 0x4d, 0xf7, 0x6e, 0x15, 0x86, + 0x8b, 0x86, 0x89, 0x84, 0x85, 0x66, 0x6c, 0x80, 0x84, 0x7a, 0x8b, 0x7e, + 0x8b, 0x81, 0x90, 0x6c, 0x9f, 0x70, 0x9d, 0x7f, 0x90, 0x77, 0x8b, 0x71, + 0x8b, 0x73, 0x80, 0x6a, 0x71, 0x78, 0x7c, 0x84, 0x81, 0x8b, 0x82, 0x08, + 0x83, 0x92, 0x84, 0x94, 0x1e, 0x91, 0x8b, 0x93, 0x8e, 0x90, 0x90, 0xae, + 0xaa, 0x96, 0x91, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x86, 0x9c, 0x7f, 0xae, + 0x73, 0x9c, 0x84, 0xa1, 0x8b, 0xa4, 0x8b, 0xa3, 0x97, 0xae, 0xa9, 0x9d, + 0x9a, 0x8f, 0x90, 0x8b, 0x94, 0x08, 0x94, 0x83, 0x92, 0x82, 0x1e, 0x0e, + 0xf8, 0xbf, 0xf8, 0x99, 0x15, 0x6b, 0xb4, 0x5f, 0x9e, 0x4f, 0x8b, 0xfb, + 0x06, 0x8b, 0x22, 0x33, 0x8b, 0x2a, 0x8b, 0x6f, 0x98, 0x6d, 0x9f, 0x7a, + 0xa4, 0x75, 0xad, 0x7f, 0xcf, 0x7f, 0xd0, 0x7f, 0x9f, 0x85, 0x9f, 0x7b, + 0x9c, 0x7e, 0x98, 0x72, 0x8b, 0x75, 0x08, 0x39, 0x31, 0x44, 0x24, 0x1e, + 0x65, 0x8b, 0x5d, 0x98, 0x76, 0x9d, 0x7e, 0x95, 0x6f, 0xb1, 0x8b, 0x91, + 0x08, 0x8f, 0xba, 0x05, 0x86, 0x92, 0x86, 0x8f, 0x85, 0x8b, 0x7e, 0x8b, + 0x81, 0x81, 0x87, 0x79, 0x08, 0x74, 0xfb, 0x04, 0x05, 0x8a, 0x87, 0x8a, + 0x85, 0x8b, 0x89, 0x08, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, 0x8b, 0x94, + 0x94, 0x8f, 0x9d, 0x08, 0x91, 0xa8, 0x05, 0xaa, 0x5c, 0xc2, 0x71, 0xd0, + 0x8b, 0xcb, 0x8b, 0xd3, 0xa6, 0xb8, 0xb3, 0xb1, 0xad, 0xa4, 0xc0, 0x8b, + 0xbb, 0x8b, 0xab, 0x7a, 0xae, 0x74, 0x9c, 0x72, 0x9d, 0x6f, 0x94, 0x41, + 0x98, 0x4e, 0x95, 0x72, 0x93, 0x77, 0x9c, 0x08, 0x7c, 0x98, 0x80, 0xa1, + 0x8b, 0x9f, 0x8b, 0xd3, 0xdc, 0xcc, 0xe4, 0x8b, 0xaf, 0x8b, 0xb3, 0x7e, + 0x9c, 0x79, 0x94, 0x82, 0xa1, 0x6b, 0x8b, 0x86, 0x08, 0x87, 0x61, 0x05, + 0x91, 0x82, 0x8f, 0x88, 0x92, 0x8b, 0x97, 0x8b, 0x95, 0x95, 0x8f, 0x9d, + 0x08, 0xa1, 0xf2, 0x8c, 0x8f, 0x05, 0x8c, 0x8e, 0x8b, 0x8e, 0x8b, 0x8d, + 0x08, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x82, 0x82, 0x87, 0x79, + 0x08, 0x87, 0x78, 0x05, 0xfb, 0x01, 0xf7, 0x0f, 0x15, 0xf7, 0x2f, 0xf7, + 0x00, 0x05, 0x99, 0x95, 0x8f, 0x90, 0x8b, 0x95, 0x8b, 0x94, 0x84, 0x92, + 0x82, 0x8b, 0x86, 0x8b, 0x84, 0x88, 0x83, 0x86, 0x08, 0xfb, 0x12, 0x33, + 0x32, 0xe3, 0x05, 0x86, 0x90, 0x86, 0x8e, 0x86, 0x8b, 0x7e, 0x8b, 0x7f, + 0x7f, 0x8b, 0x7e, 0x8b, 0x85, 0x8d, 0x88, 0x92, 0x85, 0x08, 0xf7, 0x01, + 0xfb, 0x01, 0x05, 0x0e, 0xf8, 0xf6, 0xf8, 0x9e, 0x15, 0xad, 0x06, 0x9f, + 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x29, 0x06, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x44, 0xfb, + 0xe5, 0x05, 0x78, 0x31, 0x36, 0x45, 0x32, 0x8b, 0x40, 0x8b, 0x57, 0xbe, + 0x8b, 0xd6, 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0x97, 0x08, 0xd2, 0xf7, 0xe5, + 0xd6, 0x8b, 0x05, 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7b, 0x1f, + 0xfb, 0x2a, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, + 0xac, 0x8b, 0x44, 0xfb, 0xe5, 0x05, 0x88, 0x7c, 0x89, 0x7b, 0x8b, 0x7d, + 0x8b, 0x2e, 0xcc, 0x4c, 0xeb, 0x8b, 0xf7, 0x04, 0x8b, 0xf5, 0xe3, 0xa3, + 0xf7, 0x05, 0x08, 0xd2, 0xf7, 0xe5, 0x05, 0xfb, 0x97, 0xf7, 0x83, 0x15, + 0x6c, 0x6c, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xaa, 0xa8, 0xaa, + 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, 0x72, 0x16, 0x6b, 0x6d, 0x6d, 0x6d, + 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xaa, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, + 0x1f, 0x0e, 0xf8, 0xf6, 0xf8, 0x9e, 0x15, 0xad, 0x06, 0x9f, 0x97, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x29, 0x06, 0x77, 0x7f, 0x82, + 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x44, 0xfb, 0xe5, 0x05, + 0x78, 0x31, 0x36, 0x45, 0x32, 0x8b, 0x40, 0x8b, 0x57, 0xbe, 0x8b, 0xd6, + 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0x97, 0x08, 0xd2, 0xf7, 0xe5, 0xd6, 0x8b, + 0x05, 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7b, 0x1f, 0xfb, 0x2a, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xac, 0x8b, + 0x44, 0xfb, 0xe5, 0x05, 0x88, 0x7c, 0x89, 0x7b, 0x8b, 0x7d, 0x8b, 0x2e, + 0xcc, 0x4c, 0xeb, 0x8b, 0xf7, 0x04, 0x8b, 0xf5, 0xe3, 0xa3, 0xf7, 0x05, + 0x08, 0xd2, 0xf7, 0xe5, 0x05, 0x59, 0xf7, 0x77, 0x15, 0x99, 0x95, 0x8e, + 0x8f, 0x8b, 0x95, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, 0x86, 0x8b, 0x86, + 0x89, 0x81, 0x84, 0x08, 0xfb, 0x1b, 0x27, 0x05, 0x7e, 0x82, 0x87, 0x85, + 0x8b, 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, + 0x96, 0x92, 0x08, 0xf7, 0x1b, 0xef, 0x05, 0x0e, 0xf8, 0xf6, 0xf8, 0x9e, + 0x15, 0xad, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0xfb, 0x29, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x91, 0x86, 0x9c, 0x1f, + 0xd5, 0x8b, 0x44, 0xfb, 0xe5, 0x05, 0x78, 0x31, 0x36, 0x45, 0x32, 0x8b, + 0x40, 0x8b, 0x57, 0xbe, 0x8b, 0xd6, 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0x97, + 0x08, 0xd2, 0xf7, 0xe5, 0xd6, 0x8b, 0x05, 0x9e, 0x97, 0x95, 0x9a, 0x97, + 0x85, 0x8f, 0x7b, 0x1f, 0xfb, 0x2a, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9c, 0x1f, 0xac, 0x8b, 0x44, 0xfb, 0xe5, 0x05, 0x88, 0x7c, + 0x89, 0x7b, 0x8b, 0x7d, 0x8b, 0x2e, 0xcc, 0x4c, 0xeb, 0x8b, 0xf7, 0x04, + 0x8b, 0xf5, 0xe3, 0xa3, 0xf7, 0x05, 0x08, 0xd2, 0xf7, 0xe5, 0x05, 0xfb, + 0x6e, 0xf7, 0x96, 0x15, 0x85, 0x91, 0x87, 0x8e, 0x85, 0x8b, 0x7f, 0x8b, + 0x7e, 0x7f, 0x8b, 0x7f, 0x8b, 0x86, 0x8d, 0x86, 0x91, 0x85, 0x08, 0xe8, + 0x27, 0x05, 0x91, 0x85, 0x90, 0x88, 0x90, 0x8b, 0x99, 0x8b, 0x97, 0x97, + 0x8b, 0x98, 0x8b, 0x8d, 0x88, 0x90, 0x85, 0x93, 0x08, 0x2e, 0xef, 0x05, + 0x0e, 0xf8, 0xf6, 0xf8, 0x9e, 0x15, 0xad, 0x06, 0x9f, 0x97, 0x95, 0x9a, + 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0xfb, 0x29, 0x06, 0x77, 0x7f, 0x82, 0x7c, + 0x7f, 0x91, 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x44, 0xfb, 0xe5, 0x05, 0x78, + 0x31, 0x36, 0x45, 0x32, 0x8b, 0x40, 0x8b, 0x57, 0xbe, 0x8b, 0xd6, 0x8b, + 0x95, 0x8c, 0x97, 0x8e, 0x97, 0x08, 0xd2, 0xf7, 0xe5, 0xd6, 0x8b, 0x05, + 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7b, 0x1f, 0xfb, 0x2a, 0x06, + 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xac, 0x8b, 0x44, + 0xfb, 0xe5, 0x05, 0x88, 0x7c, 0x89, 0x7b, 0x8b, 0x7d, 0x8b, 0x2e, 0xcc, + 0x4c, 0xeb, 0x8b, 0xf7, 0x04, 0x8b, 0xf5, 0xe3, 0xa3, 0xf7, 0x05, 0x08, + 0xd2, 0xf7, 0xe5, 0x05, 0xfb, 0x22, 0xf7, 0x9f, 0x15, 0xfb, 0x2f, 0xfb, + 0x01, 0x87, 0x89, 0x05, 0x82, 0x85, 0x86, 0x83, 0x8b, 0x83, 0x8b, 0x82, + 0x92, 0x84, 0x94, 0x8b, 0x90, 0x8b, 0x93, 0x8e, 0x92, 0x90, 0x08, 0xf7, + 0x12, 0xe3, 0xe4, 0x33, 0x05, 0x90, 0x86, 0x90, 0x88, 0x90, 0x8b, 0x98, + 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x90, 0x8a, 0x8e, 0x83, 0x93, 0x08, + 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x0c, 0xf7, 0x92, 0x15, 0xf7, + 0x7e, 0xf7, 0xa0, 0xa2, 0x8b, 0x05, 0x9e, 0x98, 0x95, 0x99, 0x97, 0x84, + 0x90, 0x7b, 0x1f, 0xfb, 0x02, 0x06, 0x76, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9c, 0x1f, 0xb4, 0x8b, 0xfb, 0x5a, 0xfb, 0x77, 0x23, 0xf7, 0x77, + 0xb1, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0xfb, 0x03, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xa3, 0x8b, 0xf7, 0x0e, 0xfb, 0xa0, 0x5e, 0xfb, 0x69, 0x22, 0x8b, 0x05, + 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x8f, 0x06, + 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x85, 0x90, 0x7a, 0x1f, 0x22, 0x8b, 0xb8, + 0xf7, 0x69, 0x05, 0xf7, 0x4c, 0xf8, 0x83, 0x15, 0x99, 0x95, 0x8e, 0x8f, + 0x8b, 0x95, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, 0x86, 0x8b, 0x85, 0x89, + 0x82, 0x84, 0x08, 0xfb, 0x1c, 0x27, 0x05, 0x7f, 0x82, 0x87, 0x85, 0x8b, + 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, 0x90, 0x8d, 0x95, + 0x92, 0x08, 0xf7, 0x1b, 0xef, 0x05, 0x0e, 0xf8, 0x85, 0x16, 0xb2, 0xf7, + 0x4a, 0x8c, 0x8f, 0x05, 0x8c, 0x8e, 0x8b, 0x8e, 0x8b, 0x8d, 0x8b, 0x93, + 0x84, 0x92, 0x81, 0x8b, 0x7d, 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x6d, + 0xfb, 0x21, 0xfb, 0xcf, 0x8b, 0x8c, 0x8f, 0xf8, 0x3f, 0xf8, 0x60, 0x97, + 0xc5, 0xfb, 0xf1, 0x8b, 0x69, 0xfb, 0x33, 0x05, 0x89, 0x83, 0x8b, 0x8a, + 0x8b, 0x88, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x99, 0x8b, 0x94, 0x94, + 0x8f, 0x9e, 0x08, 0xa4, 0xf7, 0x0a, 0xf7, 0xa1, 0x8b, 0x8a, 0x88, 0xfc, + 0x3d, 0xfc, 0x60, 0x7e, 0x50, 0xf8, 0x1e, 0x8b, 0x05, 0x4b, 0xf9, 0x14, + 0x15, 0xf7, 0x2f, 0xf7, 0x00, 0x05, 0x99, 0x95, 0x8f, 0x90, 0x8b, 0x95, + 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x86, 0x8b, 0x84, 0x88, 0x83, 0x86, + 0x08, 0xfb, 0x12, 0x33, 0x32, 0xe3, 0x05, 0x86, 0x90, 0x85, 0x8e, 0x87, + 0x8b, 0x7d, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, 0x8b, 0x86, 0x8e, 0x87, 0x8f, + 0x87, 0x08, 0x8e, 0x89, 0xf7, 0x01, 0xfb, 0x01, 0x05, 0x0e, 0xf7, 0x55, + 0xf7, 0x17, 0x15, 0xf7, 0x17, 0x06, 0xf7, 0x15, 0xf7, 0x05, 0xe8, 0xf6, + 0xd8, 0x49, 0xc2, 0x2f, 0x1f, 0xfb, 0x25, 0x8b, 0x98, 0xc6, 0xf7, 0x1f, + 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, + 0x7d, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xc1, + 0x8b, 0x25, 0xfc, 0x75, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x7f, + 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x7e, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, + 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0x1e, 0x8b, 0x9e, 0xe5, 0x05, 0x94, 0xb4, + 0x15, 0xc0, 0xf7, 0x8e, 0xf7, 0x29, 0x8b, 0x05, 0xd0, 0xbe, 0x60, 0x51, + 0x3d, 0x31, 0x44, 0x29, 0x1f, 0xfb, 0x1a, 0x06, 0x0e, 0xf8, 0x0c, 0xf7, + 0x92, 0x15, 0xf7, 0x7e, 0xf7, 0xa0, 0xa2, 0x8b, 0x05, 0x9e, 0x98, 0x95, + 0x99, 0x97, 0x84, 0x90, 0x7b, 0x1f, 0xfb, 0x02, 0x06, 0x76, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xb4, 0x8b, 0xfb, 0x5a, 0xfb, 0x77, + 0x23, 0xf7, 0x77, 0xb1, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7a, 0x1f, 0xfb, 0x03, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xa3, 0x8b, 0xf7, 0x0e, 0xfb, 0xa0, 0x5e, 0xfb, 0x69, + 0x22, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x8f, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x85, 0x90, 0x7a, 0x1f, + 0x22, 0x8b, 0xb8, 0xf7, 0x69, 0x05, 0x72, 0xf8, 0x8f, 0x15, 0x6c, 0x6c, + 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xaa, 0xa8, 0xaa, 0xa2, 0x7a, + 0x9c, 0x73, 0x1f, 0xf7, 0x72, 0x16, 0x6b, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, + 0x7a, 0xa3, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, + 0xf8, 0x37, 0x16, 0xeb, 0x06, 0x9e, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, + 0x7a, 0x1f, 0x55, 0x8b, 0xc4, 0xf7, 0x9f, 0x05, 0x8c, 0x92, 0x8c, 0x92, + 0x8b, 0x94, 0x8b, 0xc6, 0x53, 0xb4, 0x3a, 0x8b, 0x66, 0x8b, 0x2c, 0x78, + 0x67, 0x7c, 0x7f, 0x86, 0x85, 0x83, 0x8b, 0x81, 0x8b, 0x82, 0x92, 0x84, + 0x93, 0x8b, 0x8d, 0x8b, 0x8f, 0x8c, 0x90, 0x8c, 0x08, 0xd6, 0xa1, 0xb2, + 0x93, 0xad, 0x8b, 0xcc, 0x8b, 0xb5, 0x70, 0x8b, 0x62, 0x8b, 0x85, 0x8b, + 0x88, 0x8a, 0x86, 0x08, 0x7c, 0x44, 0x05, 0x54, 0x9b, 0x6b, 0x90, 0x5f, + 0x8b, 0x08, 0xfb, 0x1f, 0x20, 0x41, 0x2a, 0x1f, 0x4b, 0xbd, 0x64, 0xdd, + 0x1e, 0xd1, 0x8b, 0xcd, 0xa5, 0xd3, 0xc4, 0x08, 0x7d, 0x48, 0x05, 0xa3, + 0xf7, 0x04, 0x15, 0x3a, 0x4c, 0x51, 0x73, 0x42, 0x8b, 0x08, 0x4e, 0x68, + 0xa5, 0xb8, 0xd0, 0xe2, 0xbf, 0xf7, 0x08, 0x1f, 0xb5, 0x8b, 0xbb, 0x85, + 0xad, 0x82, 0x08, 0x78, 0x31, 0x05, 0xfb, 0x1a, 0xf8, 0x87, 0x15, 0x6c, + 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, + 0x7a, 0x9c, 0x73, 0x1f, 0xf7, 0x71, 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, + 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, + 0x0e, 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x7a, 0x1f, 0x55, 0x8b, 0xc4, 0xf7, 0x9f, 0x05, 0x8c, 0x93, 0x8c, + 0x91, 0x8b, 0x94, 0x8b, 0xc6, 0x53, 0xb4, 0x3a, 0x8b, 0x66, 0x8b, 0x2c, + 0x78, 0x67, 0x7c, 0x7f, 0x86, 0x85, 0x83, 0x8b, 0x81, 0x8b, 0x82, 0x92, + 0x84, 0x93, 0x8b, 0x8e, 0x8b, 0x8e, 0x8c, 0x90, 0x8c, 0x08, 0xd4, 0xa1, + 0xb4, 0x93, 0xad, 0x8b, 0xcc, 0x8b, 0xb5, 0x70, 0x8b, 0x62, 0x8b, 0x85, + 0x8b, 0x88, 0x8a, 0x86, 0x08, 0x7c, 0x44, 0x05, 0x55, 0x9b, 0x6a, 0x90, + 0x5f, 0x8b, 0x08, 0xfb, 0x1f, 0x20, 0x41, 0x2a, 0x1f, 0x4b, 0xbd, 0x64, + 0xdd, 0x1e, 0xd1, 0x8b, 0xcc, 0xa5, 0xd4, 0xc4, 0x08, 0x7d, 0x48, 0x05, + 0xa3, 0xf7, 0x04, 0x15, 0x39, 0x4c, 0x52, 0x73, 0x42, 0x8b, 0x08, 0x4e, + 0x68, 0xa5, 0xb8, 0xd0, 0xe2, 0xbf, 0xf7, 0x08, 0x1f, 0xb5, 0x8b, 0xbb, + 0x85, 0xad, 0x82, 0x08, 0x78, 0x31, 0x05, 0xd2, 0xf8, 0x7b, 0x15, 0x98, + 0x94, 0x8f, 0x91, 0x8b, 0x94, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x85, + 0x8b, 0x86, 0x89, 0x81, 0x84, 0x08, 0xfb, 0x1b, 0x27, 0x05, 0x7e, 0x81, + 0x87, 0x86, 0x8b, 0x82, 0x8b, 0x82, 0x92, 0x84, 0x95, 0x8b, 0x90, 0x8b, + 0x90, 0x8d, 0x95, 0x92, 0x08, 0xf7, 0x1b, 0xef, 0x05, 0x0e, 0xf8, 0x37, + 0x16, 0xea, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0x55, 0x8b, 0xc4, 0xf7, 0x9f, 0x05, 0x8c, 0x93, 0x8c, 0x91, 0x8b, 0x94, + 0x8b, 0xc6, 0x53, 0xb4, 0x3a, 0x8b, 0x66, 0x8b, 0x2c, 0x78, 0x67, 0x7c, + 0x7f, 0x86, 0x85, 0x83, 0x8b, 0x81, 0x8b, 0x82, 0x92, 0x84, 0x93, 0x8b, + 0x8e, 0x8b, 0x8e, 0x8c, 0x90, 0x8c, 0x08, 0xd4, 0xa1, 0xb4, 0x93, 0xad, + 0x8b, 0xcc, 0x8b, 0xb5, 0x70, 0x8b, 0x62, 0x8b, 0x85, 0x8b, 0x88, 0x8a, + 0x86, 0x08, 0x7c, 0x44, 0x05, 0x55, 0x9b, 0x6a, 0x90, 0x5f, 0x8b, 0x08, + 0xfb, 0x1f, 0x20, 0x41, 0x2a, 0x1f, 0x4b, 0xbd, 0x64, 0xdd, 0x1e, 0xd1, + 0x8b, 0xcc, 0xa5, 0xd4, 0xc4, 0x08, 0x7d, 0x48, 0x05, 0xa3, 0xf7, 0x04, + 0x15, 0x39, 0x4c, 0x52, 0x73, 0x42, 0x8b, 0x08, 0x4e, 0x68, 0xa5, 0xb8, + 0xd0, 0xe2, 0xbf, 0xf7, 0x08, 0x1f, 0xb5, 0x8b, 0xbb, 0x85, 0xad, 0x82, + 0x08, 0x78, 0x31, 0x05, 0x2b, 0xf8, 0x9a, 0x15, 0x85, 0x91, 0x86, 0x8e, + 0x86, 0x8b, 0x7d, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, 0x8b, 0x87, 0x8d, 0x87, + 0x91, 0x84, 0x08, 0xe8, 0x27, 0x05, 0x91, 0x85, 0x90, 0x88, 0x90, 0x8b, + 0x99, 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x8d, 0x88, 0x90, 0x86, 0x93, + 0x08, 0x2e, 0xef, 0x05, 0x0e, 0xf8, 0x37, 0x16, 0xea, 0x06, 0x9f, 0x97, + 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x55, 0x8b, 0xc4, 0xf7, 0x9f, + 0x05, 0x8c, 0x93, 0x8c, 0x91, 0x8b, 0x94, 0x8b, 0xc6, 0x53, 0xb4, 0x3a, + 0x8b, 0x65, 0x8b, 0x2d, 0x78, 0x67, 0x7c, 0x7f, 0x86, 0x85, 0x83, 0x8b, + 0x81, 0x8b, 0x82, 0x92, 0x84, 0x93, 0x8b, 0x8e, 0x8b, 0x8e, 0x8c, 0x90, + 0x8c, 0x08, 0xd4, 0xa1, 0xb4, 0x93, 0xad, 0x8b, 0xcc, 0x8b, 0xb5, 0x70, + 0x8b, 0x62, 0x8b, 0x85, 0x8b, 0x88, 0x8a, 0x86, 0x08, 0x7c, 0x44, 0x05, + 0x53, 0x9b, 0x6d, 0x90, 0x5d, 0x8b, 0x08, 0xfb, 0x1e, 0x20, 0x41, 0x2a, + 0x1f, 0x4b, 0xbd, 0x64, 0xdd, 0x1e, 0xd1, 0x8b, 0xcc, 0xa5, 0xd4, 0xc4, + 0x08, 0x7d, 0x48, 0x05, 0xa3, 0xf7, 0x04, 0x15, 0x39, 0x4c, 0x52, 0x73, + 0x42, 0x8b, 0x08, 0x4e, 0x68, 0xa5, 0xb8, 0xd0, 0xe2, 0xbf, 0xf7, 0x07, + 0x1f, 0xb8, 0x8b, 0xb8, 0x85, 0xae, 0x82, 0x08, 0x78, 0x31, 0x05, 0x7a, + 0xf8, 0xa3, 0x15, 0xfb, 0x2f, 0xfb, 0x01, 0x05, 0x7e, 0x83, 0x86, 0x85, + 0x8b, 0x81, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x90, 0x8b, 0x91, 0x8e, + 0x93, 0x90, 0x08, 0xf7, 0x13, 0xe3, 0xe4, 0x33, 0x05, 0x90, 0x86, 0x90, + 0x88, 0x90, 0x8b, 0x98, 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x91, 0x8a, + 0x8d, 0x83, 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x37, + 0x16, 0xea, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0x55, 0x8b, 0xc3, 0xf7, 0x9f, 0x05, 0x8d, 0x93, 0x8c, 0x94, 0x8b, 0x91, + 0x8b, 0xc6, 0x53, 0xb4, 0x3a, 0x8b, 0x66, 0x8b, 0x2c, 0x78, 0x67, 0x7c, + 0x7f, 0x86, 0x85, 0x83, 0x8b, 0x81, 0x8b, 0x82, 0x92, 0x84, 0x93, 0x8b, + 0x8d, 0x8b, 0x8f, 0x8c, 0x90, 0x8c, 0x08, 0xd6, 0xa1, 0xb2, 0x93, 0xad, + 0x8b, 0xcc, 0x8b, 0xb5, 0x70, 0x8b, 0x62, 0x8b, 0x87, 0x8a, 0x86, 0x8a, + 0x86, 0x08, 0x7c, 0x44, 0x05, 0x55, 0x9b, 0x6b, 0x90, 0x5f, 0x8b, 0x08, + 0xfb, 0x1f, 0x20, 0x41, 0x2a, 0x1f, 0x4b, 0xbd, 0x64, 0xdc, 0x1e, 0xd2, + 0x8b, 0xcd, 0xa5, 0xd3, 0xc4, 0x08, 0x7d, 0x48, 0x05, 0xa3, 0xf7, 0x04, + 0x15, 0x3a, 0x4c, 0x51, 0x73, 0x42, 0x8b, 0x08, 0x4e, 0x68, 0xa5, 0xb8, + 0xd0, 0xe2, 0xbf, 0xf7, 0x08, 0x1f, 0xb5, 0x8b, 0xba, 0x85, 0xae, 0x82, + 0x08, 0x78, 0x31, 0x05, 0xf7, 0x01, 0xf8, 0x7f, 0x15, 0x86, 0x8b, 0x86, + 0x89, 0x84, 0x85, 0x66, 0x6b, 0x80, 0x85, 0x7a, 0x8b, 0x7f, 0x8b, 0x81, + 0x8f, 0x6c, 0xa0, 0x6f, 0x9e, 0x7f, 0x8f, 0x77, 0x8b, 0x72, 0x8b, 0x75, + 0x81, 0x68, 0x70, 0x79, 0x7c, 0x83, 0x81, 0x8b, 0x82, 0x08, 0x83, 0x92, + 0x84, 0x94, 0x1e, 0x91, 0x8b, 0x93, 0x8e, 0x90, 0x90, 0xaf, 0xaa, 0x95, + 0x91, 0x9f, 0x8b, 0x96, 0x8b, 0x97, 0x86, 0x9c, 0x7f, 0xad, 0x73, 0x9c, + 0x84, 0xa1, 0x8b, 0xa4, 0x8b, 0xa4, 0x97, 0xad, 0xa9, 0x9d, 0x9a, 0x8f, + 0x90, 0x8b, 0x94, 0x08, 0x94, 0x83, 0x92, 0x82, 0x1e, 0x0e, 0xf8, 0x37, + 0x16, 0xea, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0x55, 0x8b, 0xc4, 0xf7, 0x9f, 0x05, 0x8c, 0x93, 0x8c, 0x91, 0x8b, 0x94, + 0x8b, 0xc6, 0x53, 0xb4, 0x3a, 0x8b, 0x66, 0x8b, 0x2c, 0x78, 0x67, 0x7c, + 0x7f, 0x86, 0x85, 0x83, 0x8b, 0x81, 0x8b, 0x82, 0x92, 0x84, 0x93, 0x8b, + 0x8e, 0x8b, 0x8e, 0x8c, 0x90, 0x8c, 0x08, 0xd4, 0xa1, 0xb4, 0x93, 0xad, + 0x8b, 0xcc, 0x8b, 0xb5, 0x70, 0x8b, 0x62, 0x8b, 0x85, 0x8b, 0x88, 0x8a, + 0x86, 0x08, 0x7c, 0x44, 0x05, 0x55, 0x9b, 0x6a, 0x90, 0x5f, 0x8b, 0x08, + 0xfb, 0x1f, 0x20, 0x41, 0x2a, 0x1f, 0x4b, 0xbd, 0x64, 0xdd, 0x1e, 0xd1, + 0x8b, 0xcc, 0xa5, 0xd4, 0xc4, 0x08, 0x7d, 0x48, 0x05, 0xa3, 0xf7, 0x04, + 0x15, 0x39, 0x4c, 0x52, 0x73, 0x42, 0x8b, 0x08, 0x4e, 0x68, 0xa5, 0xb8, + 0xd0, 0xe2, 0xbf, 0xf7, 0x08, 0x1f, 0xb5, 0x8b, 0xbb, 0x85, 0xad, 0x82, + 0x08, 0x78, 0x31, 0x05, 0x7e, 0xf8, 0xb9, 0x15, 0x51, 0x53, 0x56, 0x53, + 0x62, 0xab, 0x6c, 0xb6, 0x1f, 0xc7, 0xc2, 0xc0, 0xc3, 0xb5, 0x6b, 0xa9, + 0x5f, 0x1f, 0x84, 0x6a, 0x15, 0xa8, 0x9f, 0x78, 0x70, 0x67, 0x68, 0x6a, + 0x64, 0x70, 0x76, 0x9f, 0xa5, 0xae, 0xaf, 0xad, 0xb0, 0x1f, 0x0e, 0xf7, + 0xcb, 0x7b, 0x15, 0xc6, 0x8e, 0xba, 0x95, 0xb9, 0xa1, 0xbf, 0xa3, 0xb3, + 0xab, 0x8b, 0x9b, 0x8b, 0x93, 0x82, 0x94, 0x84, 0x8b, 0x86, 0x8b, 0x84, + 0x87, 0x83, 0x84, 0x50, 0x5c, 0x43, 0x71, 0x40, 0x8b, 0x34, 0x8b, 0x4d, + 0xc4, 0x8b, 0xdc, 0x08, 0x8b, 0xba, 0x9f, 0xc2, 0xac, 0xb5, 0xb5, 0xc1, + 0xcb, 0xaa, 0xd1, 0x8b, 0xb4, 0x8b, 0xb6, 0x7f, 0xa0, 0x7a, 0x97, 0x82, + 0xa4, 0x6d, 0x8b, 0x86, 0x08, 0x88, 0x67, 0x05, 0x90, 0x82, 0x90, 0x88, + 0x92, 0x8b, 0x98, 0x8b, 0x94, 0x95, 0x8f, 0x9d, 0x08, 0x9e, 0xe6, 0x05, + 0x8c, 0x91, 0x8c, 0x8f, 0x8b, 0x8e, 0x08, 0x93, 0x84, 0x92, 0x82, 0x1e, + 0x7d, 0x8b, 0x82, 0x82, 0x88, 0x78, 0x08, 0x88, 0x7e, 0x05, 0x68, 0xaf, + 0x5b, 0x9e, 0x4d, 0x8b, 0xfb, 0x2d, 0x8b, 0xfb, 0x17, 0xfb, 0x14, 0x8b, + 0xfb, 0x29, 0x8b, 0x48, 0xac, 0x51, 0xc1, 0x72, 0x9e, 0x82, 0x99, 0x87, + 0xab, 0x86, 0x08, 0x7d, 0x48, 0x9f, 0x8b, 0x05, 0xa7, 0x99, 0x84, 0x7e, + 0x77, 0x75, 0x7d, 0x6e, 0x1f, 0x7c, 0x8b, 0x7e, 0x8f, 0x77, 0x97, 0x84, + 0x8f, 0x88, 0x8c, 0x86, 0x8b, 0x08, 0x7f, 0x7f, 0x80, 0x7e, 0x7b, 0xb7, + 0x78, 0xb0, 0xc0, 0xb4, 0xae, 0xb8, 0x1f, 0x8b, 0xa9, 0x78, 0x9a, 0x68, + 0x8c, 0x08, 0x91, 0xaa, 0x05, 0x0e, 0xf8, 0xc7, 0xf7, 0x5b, 0x15, 0x8f, + 0xa4, 0x8e, 0xa3, 0x8b, 0x99, 0x08, 0xee, 0x3d, 0xd1, 0xfb, 0x01, 0xfb, + 0x28, 0xfb, 0x17, 0xfb, 0x0e, 0xfb, 0x1e, 0xfb, 0x03, 0xdb, 0x3f, 0xf7, + 0x08, 0x1e, 0xcb, 0x8b, 0xd4, 0x9d, 0xc1, 0xa9, 0xa9, 0x9b, 0x95, 0x95, + 0x8b, 0x97, 0x8b, 0x94, 0x85, 0x92, 0x82, 0x8b, 0x86, 0x8b, 0x87, 0x89, + 0x82, 0x86, 0x5c, 0x6b, 0x3d, 0x75, 0x4c, 0x8b, 0x2a, 0x8b, 0x47, 0xc9, + 0x8b, 0xe5, 0x08, 0x8b, 0x8f, 0x8b, 0x93, 0x8c, 0x95, 0x08, 0xf8, 0x35, + 0x06, 0xfc, 0x2c, 0xb4, 0x15, 0xb0, 0xe7, 0xe0, 0xc5, 0xec, 0x8b, 0xc2, + 0x8b, 0xb5, 0x79, 0xa9, 0x66, 0x9e, 0x73, 0x93, 0x73, 0x8d, 0x5c, 0x08, + 0xfc, 0x0b, 0x06, 0xf7, 0x3d, 0xf8, 0x07, 0x15, 0x6c, 0x6d, 0x6d, 0x6d, + 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, + 0x1f, 0xf7, 0x71, 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, + 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf8, 0xc6, + 0xf7, 0x5b, 0x15, 0x90, 0xa4, 0x8e, 0xa3, 0x8b, 0x99, 0x08, 0xee, 0x3d, + 0xd1, 0xfb, 0x01, 0xfb, 0x28, 0xfb, 0x17, 0xfb, 0x0e, 0xfb, 0x1e, 0xfb, + 0x03, 0xdb, 0x3f, 0xf7, 0x08, 0x1e, 0xcb, 0x8b, 0xd4, 0x9d, 0xc1, 0xa9, + 0xa9, 0x9b, 0x95, 0x95, 0x8b, 0x97, 0x8b, 0x94, 0x85, 0x92, 0x82, 0x8b, + 0x86, 0x8b, 0x87, 0x89, 0x82, 0x86, 0x5b, 0x6b, 0x3e, 0x75, 0x4c, 0x8b, + 0x2a, 0x8b, 0x47, 0xc9, 0x8b, 0xe5, 0x08, 0x8b, 0x8f, 0x8b, 0x93, 0x8c, + 0x95, 0x08, 0xf8, 0x34, 0x06, 0xfc, 0x2b, 0xb4, 0x15, 0xb0, 0xe7, 0xe0, + 0xc5, 0xed, 0x8b, 0xe6, 0x8b, 0xcb, 0x52, 0x8b, 0x3a, 0x8b, 0x89, 0x8b, + 0x86, 0x8a, 0x86, 0x08, 0xfc, 0x0a, 0x06, 0xf8, 0x0a, 0xf7, 0xfb, 0x15, + 0x98, 0x94, 0x8f, 0x91, 0x8b, 0x94, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, + 0x85, 0x8b, 0x86, 0x89, 0x81, 0x84, 0x08, 0xfb, 0x1b, 0x27, 0x05, 0x7e, + 0x81, 0x87, 0x86, 0x8b, 0x82, 0x8b, 0x82, 0x92, 0x84, 0x95, 0x8b, 0x90, + 0x8b, 0x91, 0x8e, 0x94, 0x91, 0x08, 0xf7, 0x1b, 0xef, 0x05, 0x0e, 0xf8, + 0xc6, 0xf7, 0x5b, 0x15, 0x90, 0xa4, 0x8e, 0xa3, 0x8b, 0x99, 0x08, 0xee, + 0x3d, 0xd1, 0xfb, 0x01, 0xfb, 0x28, 0xfb, 0x17, 0xfb, 0x0e, 0xfb, 0x1e, + 0xfb, 0x03, 0xdb, 0x3f, 0xf7, 0x08, 0x1e, 0xcb, 0x8b, 0xd4, 0x9d, 0xc1, + 0xa9, 0xa9, 0x9b, 0x95, 0x95, 0x8b, 0x97, 0x8b, 0x94, 0x85, 0x92, 0x82, + 0x8b, 0x86, 0x8b, 0x87, 0x89, 0x82, 0x86, 0x5b, 0x6b, 0x3e, 0x75, 0x4c, + 0x8b, 0x2a, 0x8b, 0x47, 0xc9, 0x8b, 0xe5, 0x08, 0x8b, 0x8f, 0x8b, 0x93, + 0x8c, 0x95, 0x08, 0xf8, 0x34, 0x06, 0xfc, 0x2b, 0xb4, 0x15, 0xb0, 0xe7, + 0xe0, 0xc5, 0xed, 0x8b, 0xe6, 0x8b, 0xcb, 0x52, 0x8b, 0x3a, 0x8b, 0x89, + 0x8b, 0x86, 0x8a, 0x86, 0x08, 0xfc, 0x0a, 0x06, 0xf7, 0x63, 0xf8, 0x1a, + 0x15, 0x84, 0x91, 0x87, 0x8e, 0x85, 0x8b, 0x7f, 0x8b, 0x7e, 0x7f, 0x8b, + 0x7f, 0x8b, 0x86, 0x8d, 0x86, 0x91, 0x85, 0x08, 0xe8, 0x27, 0x05, 0x92, + 0x85, 0x8f, 0x88, 0x90, 0x8b, 0x97, 0x8b, 0x9a, 0x98, 0x8a, 0x96, 0x8b, + 0x8c, 0x84, 0x98, 0x8a, 0x8d, 0x08, 0x2e, 0xef, 0x05, 0x0e, 0xf8, 0xc6, + 0xf7, 0x5b, 0x15, 0x90, 0xa4, 0x8e, 0xa3, 0x8b, 0x99, 0x08, 0xee, 0x3d, + 0xd1, 0xfb, 0x01, 0xfb, 0x28, 0xfb, 0x17, 0xfb, 0x0e, 0xfb, 0x1e, 0xfb, + 0x03, 0xdb, 0x3f, 0xf7, 0x08, 0x1e, 0xcb, 0x8b, 0xd4, 0x9d, 0xc1, 0xa9, + 0xa9, 0x9b, 0x95, 0x95, 0x8b, 0x97, 0x8b, 0x94, 0x85, 0x92, 0x82, 0x8b, + 0x86, 0x8b, 0x87, 0x89, 0x82, 0x86, 0x5b, 0x6b, 0x3e, 0x75, 0x4c, 0x8b, + 0x2a, 0x8b, 0x47, 0xc9, 0x8b, 0xe5, 0x08, 0x8b, 0x8f, 0x8b, 0x93, 0x8c, + 0x95, 0x08, 0xf8, 0x34, 0x06, 0xfc, 0x2b, 0xb4, 0x15, 0xb0, 0xe7, 0xe0, + 0xc5, 0xed, 0x8b, 0xe6, 0x8b, 0xcb, 0x52, 0x8b, 0x3a, 0x8b, 0x89, 0x8b, + 0x86, 0x8a, 0x86, 0x08, 0xfc, 0x0a, 0x06, 0xf7, 0xb2, 0xf8, 0x23, 0x15, + 0xfb, 0x2f, 0xfb, 0x01, 0x05, 0x7d, 0x83, 0x87, 0x85, 0x8b, 0x81, 0x8b, + 0x82, 0x92, 0x84, 0x94, 0x8b, 0x90, 0x8b, 0x91, 0x8d, 0x93, 0x91, 0x08, + 0xf7, 0x13, 0xe3, 0xe3, 0x33, 0x05, 0x91, 0x86, 0x90, 0x88, 0x90, 0x8b, + 0x97, 0x8b, 0x98, 0x97, 0x8b, 0x98, 0x8b, 0x90, 0x89, 0x8e, 0x84, 0x93, + 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x2d, 0xf8, 0x35, 0x15, + 0xfb, 0x33, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x0a, 0x8b, 0x44, 0xfb, 0xe3, 0xfb, 0x35, 0x8b, 0x05, 0x78, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xfd, 0x06, 0x9f, 0x98, + 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0x34, 0x8b, 0xdb, 0xf8, + 0x0c, 0x05, 0x23, 0xf7, 0x56, 0x15, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, + 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, + 0x72, 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, + 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf8, 0x2d, 0xf8, 0x35, + 0x15, 0xfb, 0x33, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, + 0x1f, 0xf7, 0x0a, 0x8b, 0x44, 0xfb, 0xe3, 0xfb, 0x35, 0x8b, 0x05, 0x78, + 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xfe, 0x06, 0x9e, + 0x98, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0x34, 0x8b, 0xdb, + 0xf8, 0x0c, 0x05, 0xf7, 0x01, 0xf7, 0x4a, 0x15, 0x99, 0x95, 0x8e, 0x8f, + 0x8b, 0x95, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, 0x86, 0x8b, 0x85, 0x88, + 0x82, 0x85, 0x08, 0xfb, 0x1c, 0x27, 0x05, 0x7f, 0x82, 0x87, 0x85, 0x8b, + 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x95, + 0x92, 0x08, 0xf7, 0x1c, 0xef, 0x05, 0x0e, 0xf8, 0x2d, 0xf8, 0x35, 0x15, + 0xfb, 0x33, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, + 0xf7, 0x0a, 0x8b, 0x44, 0xfb, 0xe3, 0xfb, 0x35, 0x8b, 0x05, 0x78, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0xfe, 0x06, 0x9e, 0x98, + 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7a, 0x1f, 0xfb, 0x34, 0x8b, 0xdb, 0xf8, + 0x0c, 0x05, 0x50, 0xf7, 0x69, 0x15, 0x85, 0x92, 0x87, 0x8d, 0x85, 0x8b, + 0x7f, 0x8b, 0x7e, 0x7f, 0x8b, 0x7f, 0x8b, 0x86, 0x8e, 0x86, 0x90, 0x85, + 0x08, 0xe8, 0x27, 0x05, 0x91, 0x85, 0x90, 0x88, 0x90, 0x8b, 0x99, 0x8b, + 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x8d, 0x88, 0x90, 0x85, 0x93, 0x08, 0x2e, + 0xef, 0x05, 0x0e, 0xf8, 0x2c, 0xf8, 0x35, 0x15, 0xfb, 0x33, 0x06, 0x77, + 0x7f, 0x82, 0x7c, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x0a, 0x8b, 0x44, + 0xfb, 0xe3, 0xfb, 0x35, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0xfe, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x96, 0x84, + 0x90, 0x7b, 0x1f, 0xfb, 0x35, 0x8b, 0xdb, 0xf8, 0x0c, 0x05, 0x96, 0xf7, + 0x72, 0x15, 0xfb, 0x2f, 0xfb, 0x01, 0x86, 0x89, 0x05, 0x82, 0x85, 0x86, + 0x83, 0x8b, 0x83, 0x8b, 0x82, 0x92, 0x84, 0x95, 0x8b, 0x90, 0x8b, 0x91, + 0x8e, 0x93, 0x90, 0x08, 0xf7, 0x12, 0xe3, 0xe4, 0x33, 0x05, 0x91, 0x86, + 0x90, 0x88, 0x90, 0x8b, 0x97, 0x8b, 0x98, 0x97, 0x8b, 0x98, 0x8b, 0x90, + 0x89, 0x8e, 0x84, 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf7, + 0x94, 0xf8, 0x35, 0x15, 0x40, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xad, 0x8b, 0x44, 0xfb, 0xe3, 0x5d, 0x8b, 0x05, 0x77, + 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xf7, 0x17, 0x06, 0x9f, + 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x5e, 0x8b, 0xc1, 0xf7, + 0x91, 0x05, 0xda, 0xd9, 0xaa, 0x9d, 0xc9, 0x8b, 0xb2, 0x8b, 0x9d, 0x85, + 0x9f, 0x77, 0x9b, 0x7b, 0x93, 0x78, 0x8b, 0x76, 0x8b, 0x86, 0x8a, 0x84, + 0x8a, 0x83, 0x08, 0x56, 0xfb, 0x8b, 0x69, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xf7, 0x00, 0x06, 0x9e, 0x98, 0x95, + 0x9a, 0x96, 0x85, 0x90, 0x7a, 0x1f, 0x69, 0x8b, 0xc1, 0xf7, 0x92, 0x05, + 0x8d, 0x94, 0x8c, 0x94, 0x8b, 0x91, 0x8b, 0xcf, 0x57, 0xb7, 0x3c, 0x8b, + 0x4d, 0x8b, 0x62, 0x77, 0x44, 0x4c, 0x08, 0x9a, 0xd0, 0x05, 0xf7, 0xbd, + 0xf7, 0x4e, 0x15, 0x86, 0x8b, 0x86, 0x89, 0x84, 0x85, 0x66, 0x6c, 0x80, + 0x84, 0x7a, 0x8b, 0x7e, 0x8b, 0x82, 0x90, 0x6b, 0x9f, 0x6f, 0x9e, 0x80, + 0x8f, 0x76, 0x8b, 0x72, 0x8b, 0x73, 0x80, 0x6a, 0x71, 0x78, 0x7c, 0x84, + 0x81, 0x8b, 0x82, 0x08, 0x82, 0x92, 0x85, 0x94, 0x1e, 0x91, 0x8b, 0x93, + 0x8e, 0x90, 0x90, 0xaf, 0xaa, 0x95, 0x91, 0x9f, 0x8b, 0x97, 0x8b, 0x96, + 0x86, 0x9c, 0x7f, 0xae, 0x73, 0x9c, 0x84, 0xa1, 0x8b, 0xa4, 0x8b, 0xa4, + 0x97, 0xad, 0xa9, 0x9d, 0x9a, 0x8f, 0x90, 0x8b, 0x94, 0x08, 0x94, 0x83, + 0x92, 0x82, 0x1e, 0x0e, 0xf8, 0x1b, 0xf8, 0x43, 0x15, 0xfb, 0x24, 0xfb, + 0x1c, 0xfb, 0x16, 0xfb, 0x1f, 0x23, 0xd7, 0x41, 0xf7, 0x01, 0xf7, 0x25, + 0xf7, 0x1c, 0xf7, 0x15, 0xf7, 0x1f, 0xf5, 0x3f, 0xd4, 0xfb, 0x02, 0x1f, + 0x82, 0x62, 0x15, 0xe6, 0xc9, 0x50, 0x34, 0xfb, 0x06, 0xfb, 0x03, 0x22, + 0xfb, 0x0b, 0x32, 0x4c, 0xc7, 0xe1, 0xf7, 0x05, 0xf7, 0x03, 0xf5, 0xf7, + 0x0a, 0x1f, 0x4c, 0xf7, 0x71, 0x15, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, + 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, + 0x71, 0x16, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, + 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf8, 0x1b, 0xf8, 0x43, + 0x15, 0xfb, 0x24, 0xfb, 0x1c, 0xfb, 0x16, 0xfb, 0x1f, 0x23, 0xd7, 0x41, + 0xf7, 0x01, 0xf7, 0x25, 0xf7, 0x1c, 0xf7, 0x15, 0xf7, 0x1f, 0xf5, 0x3f, + 0xd4, 0xfb, 0x02, 0x1f, 0x82, 0x62, 0x15, 0xe6, 0xc9, 0x50, 0x34, 0xfb, + 0x06, 0xfb, 0x03, 0x22, 0xfb, 0x0b, 0x32, 0x4c, 0xc7, 0xe1, 0xf7, 0x05, + 0xf7, 0x03, 0xf5, 0xf7, 0x0a, 0x1f, 0xf7, 0x22, 0xf7, 0x65, 0x15, 0x90, + 0x8e, 0x05, 0x94, 0x91, 0x8f, 0x92, 0x8b, 0x92, 0x8b, 0x95, 0x84, 0x92, + 0x81, 0x8b, 0x86, 0x8b, 0x84, 0x88, 0x82, 0x85, 0x08, 0xfb, 0x1b, 0x27, + 0x05, 0x80, 0x83, 0x86, 0x84, 0x8b, 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, + 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x95, 0x92, 0x08, 0xf7, 0x1b, 0xef, 0x05, + 0x0e, 0xf8, 0x1b, 0xf8, 0x43, 0x15, 0xfb, 0x24, 0xfb, 0x1c, 0xfb, 0x16, + 0xfb, 0x1f, 0x23, 0xd7, 0x41, 0xf7, 0x01, 0xf7, 0x25, 0xf7, 0x1c, 0xf7, + 0x15, 0xf7, 0x1f, 0xf5, 0x3f, 0xd4, 0xfb, 0x02, 0x1f, 0x82, 0x62, 0x15, + 0xe6, 0xc9, 0x50, 0x34, 0xfb, 0x06, 0xfb, 0x03, 0x22, 0xfb, 0x0b, 0x32, + 0x4c, 0xc7, 0xe1, 0xf7, 0x05, 0xf7, 0x03, 0xf5, 0xf7, 0x0a, 0x1f, 0x78, + 0xf7, 0x84, 0x15, 0x85, 0x91, 0x87, 0x8e, 0x86, 0x8b, 0x7e, 0x8b, 0x7e, + 0x7f, 0x8b, 0x7f, 0x8b, 0x86, 0x8e, 0x86, 0x90, 0x85, 0x08, 0xe8, 0x27, + 0x05, 0x91, 0x85, 0x90, 0x88, 0x90, 0x8b, 0x99, 0x8b, 0x97, 0x97, 0x8b, + 0x98, 0x8b, 0x8d, 0x88, 0x90, 0x85, 0x93, 0x08, 0x2e, 0xef, 0x05, 0x0e, + 0xf8, 0x1b, 0xf8, 0x43, 0x15, 0xfb, 0x24, 0xfb, 0x1c, 0xfb, 0x16, 0xfb, + 0x1f, 0x23, 0xd7, 0x41, 0xf7, 0x01, 0xf7, 0x25, 0xf7, 0x1c, 0xf7, 0x15, + 0xf7, 0x1f, 0xf5, 0x3f, 0xd4, 0xfb, 0x02, 0x1f, 0x82, 0x62, 0x15, 0xe6, + 0xc9, 0x50, 0x34, 0xfb, 0x06, 0xfb, 0x03, 0x22, 0xfb, 0x0b, 0x32, 0x4c, + 0xc7, 0xe1, 0xf7, 0x05, 0xf7, 0x03, 0xf5, 0xf7, 0x0a, 0x1f, 0xc1, 0xf7, + 0x8d, 0x15, 0xfb, 0x2f, 0xfb, 0x01, 0x05, 0x7d, 0x83, 0x87, 0x85, 0x8b, + 0x81, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x90, 0x8b, 0x91, 0x8e, 0x93, + 0x90, 0x08, 0xf7, 0x13, 0xe3, 0xe4, 0x33, 0x05, 0x90, 0x86, 0x90, 0x88, + 0x90, 0x8b, 0x98, 0x8b, 0x97, 0x97, 0x8b, 0x98, 0x8b, 0x91, 0x8a, 0x8d, + 0x83, 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf8, 0x1b, 0xf8, + 0x43, 0x15, 0xfb, 0x24, 0xfb, 0x1c, 0xfb, 0x16, 0xfb, 0x1f, 0x23, 0xd7, + 0x41, 0xf7, 0x01, 0xf7, 0x25, 0xf7, 0x1c, 0xf7, 0x15, 0xf7, 0x1f, 0xf5, + 0x3f, 0xd4, 0xfb, 0x02, 0x1f, 0x82, 0x62, 0x15, 0xe6, 0xc9, 0x50, 0x34, + 0xfb, 0x06, 0xfb, 0x03, 0x22, 0xfb, 0x0b, 0x32, 0x4c, 0xc7, 0xe1, 0xf7, + 0x05, 0xf7, 0x03, 0xf5, 0xf7, 0x0a, 0x1f, 0xf7, 0x4f, 0xf7, 0x69, 0x15, + 0x86, 0x8b, 0x86, 0x89, 0x84, 0x85, 0x67, 0x6c, 0x7e, 0x84, 0x7b, 0x8b, + 0x7e, 0x8b, 0x82, 0x90, 0x6b, 0x9f, 0x6f, 0x9d, 0x80, 0x90, 0x76, 0x8b, + 0x72, 0x8b, 0x74, 0x81, 0x69, 0x70, 0x79, 0x7c, 0x83, 0x81, 0x8b, 0x82, + 0x08, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x91, 0x8b, 0x93, 0x8e, 0x90, 0x90, + 0xae, 0xa9, 0x96, 0x92, 0x9f, 0x8b, 0x97, 0x8b, 0x96, 0x86, 0x9c, 0x7f, + 0xae, 0x73, 0x9c, 0x84, 0xa1, 0x8b, 0xa4, 0x8b, 0xa4, 0x97, 0xad, 0xa9, + 0x9d, 0x9a, 0x8f, 0x90, 0x8b, 0x94, 0x08, 0x94, 0x83, 0x92, 0x82, 0x1e, + 0x0e, 0xf7, 0x01, 0xa6, 0x15, 0x8a, 0x88, 0x8a, 0x84, 0x8b, 0x89, 0x8b, + 0x83, 0x92, 0x84, 0x94, 0x8b, 0x99, 0x8b, 0x94, 0x94, 0x8e, 0x9d, 0x08, + 0x8e, 0x96, 0x05, 0xad, 0x66, 0xbb, 0x79, 0xcd, 0x8b, 0xf7, 0x0e, 0x8b, + 0xf2, 0xd2, 0x8b, 0xdf, 0x8b, 0xa3, 0x7d, 0xa7, 0x77, 0x9b, 0x71, 0xa0, + 0x68, 0x96, 0x4f, 0x92, 0x3e, 0x93, 0x8b, 0x8b, 0x77, 0x94, 0x76, 0x94, + 0x7a, 0x9f, 0x8b, 0x9b, 0x08, 0xb7, 0xd1, 0xb3, 0xd8, 0x1e, 0xad, 0x8b, + 0xaf, 0x82, 0x9e, 0x7e, 0x95, 0x84, 0x9f, 0x75, 0x8b, 0x86, 0x08, 0x89, + 0x6c, 0x05, 0x90, 0x83, 0x90, 0x87, 0x91, 0x8b, 0x98, 0x8b, 0x94, 0x95, + 0x8f, 0x9d, 0x08, 0x9a, 0xd0, 0x05, 0x8d, 0x94, 0x8b, 0x8b, 0x8b, 0x8f, + 0x08, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7d, 0x8b, 0x82, 0x80, 0x86, 0x76, + 0x08, 0x6f, 0xaa, 0x61, 0x9a, 0x51, 0x8b, 0xfb, 0x01, 0x8b, 0x34, 0x50, + 0x8b, 0x41, 0x8b, 0x75, 0x97, 0x73, 0x9e, 0x7e, 0xa3, 0x7a, 0xa6, 0x84, + 0xd3, 0x83, 0xc1, 0x85, 0xa4, 0x84, 0xa2, 0x7d, 0x9d, 0x7f, 0x99, 0x76, + 0x8b, 0x7a, 0x08, 0x51, 0x3d, 0x5c, 0x2b, 0x3c, 0x50, 0xaa, 0xb6, 0x1e, + 0x8b, 0x8e, 0x8c, 0x91, 0x8c, 0x92, 0x8c, 0x8d, 0x8b, 0x8e, 0x8b, 0x8d, + 0x8b, 0x93, 0x84, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x82, 0x82, 0x87, 0x79, + 0x08, 0x7a, 0x38, 0x05, 0xf7, 0xc2, 0xf8, 0x63, 0x15, 0xf7, 0x2f, 0xf7, + 0x00, 0x05, 0x99, 0x95, 0x8f, 0x90, 0x8b, 0x94, 0x8b, 0x95, 0x84, 0x92, + 0x82, 0x8b, 0x86, 0x8b, 0x84, 0x88, 0x84, 0x86, 0x08, 0xfb, 0x13, 0x33, + 0x32, 0xe3, 0x05, 0x86, 0x91, 0x86, 0x8d, 0x86, 0x8b, 0x7e, 0x8b, 0x7f, + 0x7f, 0x8b, 0x7e, 0x8b, 0x85, 0x8d, 0x88, 0x92, 0x85, 0x08, 0xf7, 0x01, + 0xfb, 0x01, 0x05, 0x0e, 0xf8, 0x4b, 0x16, 0xd6, 0x06, 0x9e, 0x98, 0x95, + 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x69, 0x8b, 0xdb, 0xf8, 0x0c, 0xfb, + 0x08, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, + 0xd5, 0x8b, 0x54, 0xfb, 0x99, 0x05, 0x46, 0x4e, 0x49, 0x6e, 0x47, 0x8b, + 0x60, 0x8b, 0x6d, 0xa9, 0x8b, 0xb5, 0x8b, 0x93, 0x8b, 0x8f, 0x8d, 0x91, + 0x08, 0xcb, 0xf7, 0xc2, 0x2c, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x54, 0xfb, 0x99, 0x05, 0x88, 0x80, + 0x8a, 0x80, 0x8b, 0x80, 0x8b, 0x4f, 0xb5, 0x65, 0xcd, 0x8b, 0xce, 0x8b, + 0xcd, 0xa6, 0xce, 0xc2, 0x08, 0x7d, 0x49, 0x05, 0xfb, 0x14, 0xf8, 0xf7, + 0x15, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, + 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, 0x71, 0x16, 0x6c, 0x6d, 0x6d, + 0x6d, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, + 0x73, 0x1f, 0x0e, 0xf8, 0x4b, 0x16, 0xd6, 0x06, 0x9f, 0x97, 0x95, 0x9a, + 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x69, 0x8b, 0xdb, 0xf8, 0x0c, 0xfb, 0x07, + 0x8b, 0x05, 0x76, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xd5, + 0x8b, 0x54, 0xfb, 0x99, 0x05, 0x46, 0x4e, 0x49, 0x6e, 0x47, 0x8b, 0x60, + 0x8b, 0x6d, 0xa9, 0x8b, 0xb5, 0x8b, 0x93, 0x8b, 0x8f, 0x8d, 0x91, 0x08, + 0xcb, 0xf7, 0xc2, 0x2c, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x54, 0xfb, 0x99, 0x05, 0x88, 0x80, 0x8a, + 0x80, 0x8b, 0x80, 0x8b, 0x4f, 0xb5, 0x65, 0xcd, 0x8b, 0xce, 0x8b, 0xce, + 0xa6, 0xcd, 0xc2, 0x08, 0x7d, 0x49, 0x05, 0xd2, 0xf8, 0xeb, 0x15, 0x99, + 0x95, 0x8e, 0x8f, 0x8b, 0x95, 0x8b, 0x94, 0x84, 0x92, 0x81, 0x8b, 0x86, + 0x8b, 0x85, 0x89, 0x82, 0x84, 0x08, 0xfb, 0x1b, 0x27, 0x05, 0x7e, 0x82, + 0x87, 0x85, 0x8b, 0x82, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, 0x8b, + 0x90, 0x8d, 0x95, 0x92, 0x08, 0xf7, 0x1b, 0xef, 0x05, 0x0e, 0xf8, 0x4b, + 0x16, 0xd6, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x97, 0x85, 0x8f, 0x7a, 0x1f, + 0x69, 0x8b, 0xdb, 0xf8, 0x0c, 0xfb, 0x07, 0x8b, 0x05, 0x76, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xd5, 0x8b, 0x54, 0xfb, 0x99, 0x05, + 0x46, 0x4e, 0x49, 0x6e, 0x47, 0x8b, 0x60, 0x8b, 0x6d, 0xa9, 0x8b, 0xb5, + 0x8b, 0x93, 0x8b, 0x8f, 0x8d, 0x91, 0x08, 0xcb, 0xf7, 0xc2, 0x2c, 0x8b, + 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, + 0x54, 0xfb, 0x99, 0x05, 0x88, 0x80, 0x8a, 0x80, 0x8b, 0x80, 0x8b, 0x4f, + 0xb5, 0x65, 0xcd, 0x8b, 0xce, 0x8b, 0xce, 0xa6, 0xcd, 0xc2, 0x08, 0x7d, + 0x49, 0x05, 0x38, 0xf9, 0x0a, 0x15, 0x84, 0x92, 0x87, 0x8d, 0x86, 0x8b, + 0x7e, 0x8b, 0x7e, 0x7f, 0x8b, 0x7f, 0x8b, 0x86, 0x8e, 0x86, 0x90, 0x85, + 0x08, 0xe9, 0x27, 0x05, 0x90, 0x85, 0x91, 0x88, 0x90, 0x8b, 0x98, 0x8b, + 0x98, 0x97, 0x8b, 0x98, 0x8b, 0x8d, 0x88, 0x90, 0x85, 0x93, 0x08, 0x2e, + 0xef, 0x05, 0x0e, 0xf8, 0x4b, 0x16, 0xd6, 0x06, 0x9f, 0x97, 0x95, 0x9a, + 0x97, 0x85, 0x8f, 0x7a, 0x1f, 0x69, 0x8b, 0xdb, 0xf8, 0x0c, 0xfb, 0x07, + 0x8b, 0x05, 0x76, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xd5, + 0x8b, 0x54, 0xfb, 0x99, 0x05, 0x46, 0x4e, 0x49, 0x6e, 0x47, 0x8b, 0x60, + 0x8b, 0x6d, 0xa9, 0x8b, 0xb5, 0x8b, 0x93, 0x8b, 0x8f, 0x8d, 0x91, 0x08, + 0xcb, 0xf7, 0xc2, 0x2c, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0x54, 0xfb, 0x99, 0x05, 0x88, 0x80, 0x8a, + 0x80, 0x8b, 0x80, 0x8b, 0x4f, 0xb5, 0x65, 0xcd, 0x8b, 0xce, 0x8b, 0xce, + 0xa6, 0xcd, 0xc2, 0x08, 0x7d, 0x49, 0x05, 0x80, 0xf9, 0x13, 0x15, 0xfb, + 0x2f, 0xfb, 0x01, 0x87, 0x89, 0x05, 0x82, 0x85, 0x86, 0x83, 0x8b, 0x83, + 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x90, 0x8b, 0x92, 0x8e, 0x92, 0x90, + 0x08, 0xf7, 0x13, 0xe3, 0xe4, 0x33, 0x05, 0x90, 0x86, 0x91, 0x88, 0x8f, + 0x8b, 0x98, 0x8b, 0x98, 0x97, 0x8b, 0x98, 0x8b, 0x90, 0x89, 0x8e, 0x83, + 0x93, 0x08, 0xfb, 0x01, 0xf7, 0x00, 0x05, 0x0e, 0xf7, 0xae, 0x16, 0x25, + 0xfb, 0x25, 0xfb, 0x12, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, + 0x86, 0x9b, 0x1f, 0xf7, 0x7d, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, 0x85, + 0x8f, 0x79, 0x1f, 0x4b, 0x8b, 0xf8, 0x03, 0xf8, 0x9d, 0x98, 0x8b, 0x05, + 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfb, 0x02, 0x06, + 0x77, 0x7f, 0x81, 0x7d, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, 0xfb, + 0x7b, 0xfb, 0xdf, 0x2d, 0xf7, 0xdf, 0xbf, 0x8b, 0x05, 0x9f, 0x97, 0x95, + 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfb, 0x07, 0x06, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0x9b, 0x8b, 0x05, 0xf6, 0xfc, 0x0c, + 0x05, 0xf7, 0xaa, 0xf8, 0xeb, 0x15, 0x98, 0x94, 0x8f, 0x91, 0x8b, 0x94, + 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x85, 0x8b, 0x86, 0x89, 0x81, 0x84, + 0x08, 0xfb, 0x1b, 0x27, 0x05, 0x7e, 0x81, 0x87, 0x86, 0x8b, 0x82, 0x8b, + 0x82, 0x92, 0x84, 0x95, 0x8b, 0x90, 0x8b, 0x91, 0x8e, 0x94, 0x91, 0x08, + 0xf7, 0x1b, 0xef, 0x05, 0x0e, 0xf8, 0xc7, 0xf8, 0x35, 0x15, 0xfb, 0xf2, + 0x8b, 0x76, 0x2b, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x99, + 0x8b, 0x93, 0x94, 0x8f, 0x9d, 0x08, 0x97, 0xc2, 0xf7, 0x8f, 0x8b, 0xfc, + 0x09, 0xfb, 0xe8, 0x83, 0x67, 0xf8, 0x0a, 0x8b, 0xa0, 0xec, 0x8c, 0x8f, + 0x05, 0x8c, 0x8e, 0x8b, 0x8d, 0x8b, 0x8e, 0x8b, 0x93, 0x84, 0x92, 0x82, + 0x8b, 0x7c, 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x7f, 0x53, 0xfb, 0xaa, + 0x8b, 0xf8, 0x0c, 0xf7, 0xe8, 0x93, 0xaf, 0x05, 0xfb, 0x34, 0xd4, 0x15, + 0xf7, 0x2f, 0xf7, 0x00, 0x05, 0x99, 0x95, 0x8f, 0x90, 0x8b, 0x95, 0x8b, + 0x94, 0x84, 0x92, 0x82, 0x8b, 0x86, 0x8b, 0x84, 0x88, 0x83, 0x86, 0x08, + 0xfb, 0x12, 0x33, 0x32, 0xe3, 0x05, 0x86, 0x90, 0x86, 0x8e, 0x86, 0x8b, + 0x7e, 0x8b, 0x7f, 0x7f, 0x8b, 0x7e, 0x8b, 0x85, 0x8d, 0x88, 0x92, 0x85, + 0x08, 0xf7, 0x01, 0xfb, 0x01, 0x05, 0x0e, 0xf8, 0xc6, 0xf8, 0xd5, 0x15, + 0x93, 0x8e, 0x90, 0x94, 0x8b, 0x95, 0x08, 0x94, 0x84, 0x92, 0x83, 0x1e, + 0x84, 0x8a, 0x24, 0x61, 0x05, 0x56, 0xa7, 0x50, 0x9f, 0x71, 0x8b, 0x7d, + 0x8b, 0x7f, 0x7f, 0x8b, 0x7d, 0x8b, 0x83, 0x90, 0x87, 0x96, 0x89, 0xaf, + 0x83, 0xa1, 0x84, 0xac, 0x7b, 0x08, 0x46, 0x6f, 0x05, 0x84, 0x88, 0x86, + 0x83, 0x8b, 0x81, 0x08, 0x81, 0x92, 0x83, 0x94, 0x1e, 0x92, 0x8c, 0xee, + 0xb5, 0x05, 0xaf, 0x6d, 0xac, 0x55, 0xa0, 0x4b, 0x5d, 0xb2, 0x69, 0x99, + 0x55, 0x8b, 0x08, 0xfb, 0x24, 0xfb, 0x1b, 0xfb, 0x16, 0xfb, 0x1f, 0x23, + 0xd7, 0x41, 0xf7, 0x01, 0x1f, 0xd5, 0x8b, 0xd5, 0xac, 0xc4, 0xc6, 0xbd, + 0xc0, 0xaa, 0xdb, 0x8b, 0xd9, 0x8b, 0xe9, 0x66, 0xe9, 0x4a, 0xd0, 0x08, + 0xdd, 0xad, 0x05, 0xfb, 0x47, 0xfb, 0x4f, 0x15, 0xe6, 0xc9, 0x50, 0x34, + 0xfb, 0x06, 0xfb, 0x03, 0x22, 0xfb, 0x0b, 0x32, 0x4c, 0xc7, 0xe1, 0xf7, + 0x05, 0xf7, 0x03, 0xf5, 0xf7, 0x0a, 0x1f, 0x0e, 0xf7, 0xa2, 0xf8, 0xe2, + 0x15, 0x2c, 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xc1, 0x8b, 0xfb, 0x27, 0xfd, 0x4a, 0x55, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x55, 0x06, 0x9f, 0x97, 0x94, + 0x9b, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0x2a, 0x8b, 0xc0, 0xf7, 0x8f, 0x05, + 0xab, 0x49, 0xbd, 0x6d, 0xd8, 0x8b, 0x08, 0xf7, 0x20, 0xf7, 0x13, 0xf7, + 0x0d, 0xf7, 0x19, 0xf0, 0x45, 0xcd, 0xfb, 0x00, 0x1f, 0x3f, 0x8b, 0x53, + 0x70, 0x48, 0x46, 0x08, 0xc1, 0xf7, 0x93, 0x05, 0xf7, 0x1b, 0xfb, 0x5c, + 0x15, 0xe1, 0xc7, 0x54, 0x3b, 0x21, 0x23, 0x29, 0xfb, 0x06, 0x36, 0x4f, + 0xc3, 0xdb, 0xf4, 0xf3, 0xed, 0xf7, 0x05, 0x1f, 0x0e, 0xf7, 0xae, 0x16, + 0x25, 0xfb, 0x25, 0xfb, 0x12, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7b, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xf7, 0x7d, 0x06, 0x9e, 0x98, 0x95, 0x9a, 0x97, + 0x85, 0x8f, 0x79, 0x1f, 0x4b, 0x8b, 0xf8, 0x03, 0xf8, 0x9d, 0x98, 0x8b, + 0x05, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfb, 0x02, + 0x06, 0x77, 0x7f, 0x81, 0x7d, 0x7f, 0x92, 0x86, 0x9b, 0x1f, 0xc1, 0x8b, + 0xfb, 0x7b, 0xfb, 0xdf, 0x2d, 0xf7, 0xdf, 0xbf, 0x8b, 0x05, 0x9f, 0x97, + 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfb, 0x07, 0x06, 0x77, 0x7f, + 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0x9b, 0x8b, 0x05, 0xf6, 0xfc, + 0x0c, 0x05, 0xb0, 0xf8, 0xf7, 0x15, 0x6c, 0x6d, 0x6d, 0x6d, 0x74, 0x9c, + 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0xf7, + 0x71, 0x16, 0x6c, 0x6d, 0x6e, 0x6c, 0x74, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, + 0xa8, 0xaa, 0xa2, 0x7a, 0x9c, 0x73, 0x1f, 0x0e, 0xf7, 0x49, 0xf7, 0xf3, + 0x15, 0xb2, 0xf7, 0x00, 0xed, 0xd7, 0xf0, 0x8b, 0xdb, 0x8b, 0xd0, 0x5c, + 0x8b, 0x54, 0x8b, 0x87, 0x8b, 0x87, 0x8a, 0x87, 0x8a, 0x87, 0x8b, 0x88, + 0x8b, 0x89, 0x8b, 0x83, 0x92, 0x84, 0x94, 0x8b, 0x99, 0x8b, 0x94, 0x94, + 0x8f, 0x9d, 0x08, 0xa3, 0xf7, 0x04, 0x8c, 0x97, 0x05, 0x94, 0x84, 0x91, + 0x82, 0x1e, 0x7d, 0x8b, 0x83, 0x82, 0x87, 0x79, 0x08, 0x85, 0x6e, 0x05, + 0x65, 0xb8, 0x54, 0xa3, 0x49, 0x8b, 0xfb, 0x0f, 0x8b, 0xfb, 0x0d, 0x2d, + 0x5f, 0xfb, 0x17, 0x08, 0x6b, 0x06, 0x79, 0x82, 0x83, 0x7a, 0x82, 0x90, + 0x88, 0x99, 0x1f, 0xa9, 0x8b, 0x7f, 0x4f, 0x6c, 0x8b, 0x05, 0x79, 0x83, + 0x83, 0x7a, 0x82, 0x90, 0x88, 0x98, 0x1f, 0xab, 0x8b, 0x8a, 0x75, 0x05, + 0xfb, 0x0b, 0xe7, 0x2f, 0xf7, 0x0a, 0x1e, 0xd0, 0x8b, 0xd3, 0xa9, 0xca, + 0xc0, 0xa6, 0xa3, 0x92, 0x94, 0x8b, 0x96, 0x8b, 0x93, 0x85, 0x91, 0x81, + 0x8b, 0x83, 0x8b, 0x87, 0x89, 0x83, 0x83, 0x48, 0x4c, 0x51, 0x70, 0x46, + 0x8b, 0x08, 0x27, 0x40, 0xd7, 0xf1, 0x1f, 0x99, 0xf7, 0x97, 0x07, 0x9d, + 0x93, 0x93, 0x9d, 0x93, 0x85, 0x8e, 0x7f, 0x1f, 0xfb, 0x99, 0x8b, 0x97, + 0xc7, 0xf7, 0xb6, 0x8b, 0x05, 0x9d, 0x93, 0x93, 0x9d, 0x93, 0x86, 0x8e, + 0x7e, 0x1f, 0xfb, 0xb3, 0x06, 0x0e, 0xf8, 0x55, 0xf8, 0xf8, 0x15, 0xfb, + 0x02, 0x6b, 0x7a, 0x86, 0x86, 0x86, 0x87, 0x87, 0x88, 0x85, 0x8b, 0x86, + 0x8b, 0x84, 0x91, 0x84, 0x92, 0x8b, 0x8e, 0x8b, 0x8f, 0x8b, 0x8e, 0x8c, + 0x08, 0xd0, 0xa0, 0x52, 0xfb, 0xa0, 0x4f, 0x8b, 0x05, 0x72, 0x80, 0x85, + 0x7b, 0x82, 0x91, 0x86, 0x96, 0x1f, 0xf7, 0x47, 0x06, 0x98, 0x96, 0x95, + 0x97, 0x94, 0x85, 0x90, 0x80, 0x1f, 0x44, 0x8b, 0xcf, 0xf7, 0xd1, 0x05, + 0x0e, 0xf7, 0xae, 0xf7, 0xbb, 0x15, 0xf7, 0x6c, 0xf7, 0x3a, 0x9b, 0x9b, + 0x8b, 0xc0, 0x8b, 0xb8, 0x64, 0xb0, 0x5b, 0x8b, 0x66, 0x8b, 0x67, 0x7b, + 0x6f, 0x6f, 0x7a, 0x7a, 0x7f, 0x77, 0x8b, 0x81, 0x8b, 0x84, 0x92, 0x85, + 0x92, 0x8b, 0x94, 0x8b, 0x92, 0x90, 0x90, 0x96, 0x08, 0x9c, 0xaa, 0xad, + 0xa0, 0xae, 0x8b, 0xab, 0x8b, 0xa6, 0x73, 0x8b, 0x6e, 0x8b, 0x6f, 0x80, + 0x7d, 0x46, 0x53, 0x08, 0xfb, 0x32, 0xfb, 0x0f, 0x82, 0x60, 0xf7, 0x7a, + 0x8b, 0x94, 0xb2, 0x8b, 0x92, 0x05, 0x8a, 0x93, 0x86, 0x90, 0x83, 0x8b, + 0x80, 0x8b, 0x82, 0x83, 0x89, 0x7f, 0x08, 0x8a, 0x88, 0xfb, 0x2a, 0x8b, + 0x05, 0x0e, 0xf8, 0x5e, 0xf8, 0x56, 0x15, 0xb1, 0xa1, 0x9f, 0xaa, 0x8b, + 0xae, 0x08, 0xb7, 0x68, 0xa9, 0x58, 0x5a, 0x49, 0x69, 0x72, 0x83, 0x91, + 0x85, 0x93, 0x1e, 0x92, 0x8b, 0x8e, 0x8d, 0x94, 0x93, 0x9e, 0x9c, 0xa5, + 0x95, 0xa8, 0x8b, 0x08, 0xad, 0xa2, 0x79, 0x70, 0x68, 0x68, 0x6e, 0x61, + 0x1f, 0x7c, 0x06, 0x7d, 0x80, 0x82, 0x7f, 0x1f, 0x8b, 0x81, 0x91, 0x87, + 0x97, 0x8a, 0x08, 0xb8, 0x8a, 0xab, 0x72, 0x8b, 0x69, 0x8b, 0x60, 0x5a, + 0x62, 0x57, 0x8b, 0x6d, 0x8b, 0x74, 0x93, 0x72, 0xa0, 0x87, 0x8f, 0x88, + 0x8c, 0x86, 0x8b, 0x08, 0x80, 0x81, 0x81, 0x80, 0x75, 0xc4, 0x70, 0xb9, + 0xd5, 0xd3, 0xc8, 0xcb, 0x1f, 0x8b, 0xa8, 0x7f, 0xa0, 0x6d, 0x9f, 0x08, + 0x91, 0x8f, 0x05, 0x0e, 0xf8, 0x05, 0xf7, 0xf0, 0x15, 0x5f, 0x63, 0x66, + 0x61, 0x6c, 0xa2, 0x76, 0xac, 0x1f, 0x96, 0x06, 0xb7, 0xb3, 0xb0, 0xb5, + 0xaa, 0x74, 0xa0, 0x6a, 0x1f, 0x80, 0x06, 0x0e, 0xf8, 0xc0, 0xf7, 0x96, + 0x15, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfc, 0x26, + 0x06, 0x77, 0x7f, 0x82, 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0x26, + 0x06, 0x0e, 0xf8, 0x49, 0xf9, 0x10, 0x15, 0x2e, 0x34, 0x37, 0x31, 0x47, + 0xbc, 0x5b, 0xd0, 0xe6, 0xe2, 0xe1, 0xe4, 0xcd, 0x5a, 0xbc, 0x48, 0x1f, + 0x82, 0x62, 0x15, 0xbb, 0xae, 0x68, 0x5c, 0x4a, 0x4d, 0x4e, 0x49, 0x5a, + 0x68, 0xad, 0xbc, 0xcc, 0xc9, 0xc7, 0xce, 0x1f, 0x0e, 0xf7, 0x37, 0xf7, + 0xc2, 0x15, 0x77, 0x7f, 0x81, 0x7c, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf8, + 0x26, 0x06, 0x9f, 0x97, 0x95, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfc, + 0x26, 0x06, 0x0e, 0xf8, 0x02, 0xf7, 0xcb, 0x15, 0xfb, 0x04, 0xf7, 0x22, + 0x05, 0x85, 0x93, 0x86, 0x8e, 0x86, 0x8b, 0x7e, 0x8b, 0x7e, 0x7f, 0x8b, + 0x7f, 0x8b, 0x87, 0x8e, 0x84, 0x8f, 0x86, 0x08, 0xf7, 0x04, 0xfb, 0x22, + 0xfb, 0x41, 0xfb, 0x23, 0x05, 0x80, 0x83, 0x87, 0x84, 0x8b, 0x83, 0x8b, + 0x82, 0x92, 0x84, 0x94, 0x8b, 0x92, 0x8b, 0x91, 0x8e, 0x94, 0x92, 0x08, + 0xf7, 0x41, 0xf7, 0x23, 0xf7, 0x04, 0xfb, 0x23, 0x05, 0x91, 0x84, 0x8f, + 0x88, 0x91, 0x8b, 0x98, 0x8b, 0x98, 0x97, 0x8b, 0x97, 0x8b, 0x8f, 0x88, + 0x91, 0x87, 0x90, 0x08, 0xfb, 0x04, 0xf7, 0x23, 0xf7, 0x41, 0xf7, 0x22, + 0x05, 0x96, 0x94, 0x8f, 0x92, 0x8b, 0x92, 0x8b, 0x95, 0x84, 0x92, 0x81, + 0x8b, 0x85, 0x8b, 0x86, 0x88, 0x81, 0x83, 0x08, 0xfb, 0x41, 0xfb, 0x22, + 0x05, 0x0e, 0xf8, 0xc0, 0xf7, 0x9a, 0x15, 0x9f, 0x97, 0x94, 0x9a, 0x96, + 0x84, 0x90, 0x7b, 0x1f, 0xfc, 0x26, 0x06, 0x77, 0x7f, 0x82, 0x7c, 0x80, + 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0x26, 0x06, 0xfb, 0x7a, 0xfb, 0x1e, 0x15, + 0x6c, 0x6d, 0x6e, 0x6c, 0x75, 0x9c, 0x7a, 0xa2, 0xab, 0xa9, 0xa8, 0xa9, + 0xa3, 0x7a, 0x9b, 0x73, 0x1f, 0xe4, 0xf8, 0x34, 0x15, 0x6c, 0x6d, 0x6e, + 0x6c, 0x75, 0x9c, 0x7a, 0xa1, 0xab, 0xa9, 0xa8, 0xa9, 0xa3, 0x7a, 0x9b, + 0x74, 0x1f, 0x0e, 0xf7, 0x92, 0xf8, 0xa6, 0x15, 0xd2, 0x8b, 0x7c, 0x42, + 0x05, 0x8a, 0x89, 0x8b, 0x89, 0x8b, 0x8a, 0x8b, 0x83, 0x91, 0x85, 0x92, + 0x8b, 0x96, 0x8b, 0x93, 0x92, 0x8e, 0x97, 0x08, 0xa1, 0xf5, 0xfb, 0x86, + 0x8b, 0x74, 0x21, 0x8b, 0x85, 0x05, 0x8c, 0x83, 0x90, 0x86, 0x92, 0x8b, + 0x95, 0x8b, 0x93, 0x92, 0x8d, 0x97, 0x08, 0x9b, 0xd4, 0xd2, 0x8b, 0x55, + 0xfb, 0x92, 0x55, 0x8b, 0x05, 0x7e, 0x81, 0x82, 0x80, 0x83, 0x91, 0x86, + 0x95, 0x1f, 0xf7, 0x21, 0x06, 0x98, 0x95, 0x94, 0x96, 0x93, 0x85, 0x90, + 0x81, 0x1f, 0x55, 0x8b, 0xc1, 0xf7, 0x92, 0x05, 0xf7, 0x9f, 0xfb, 0x56, + 0x15, 0xf7, 0x0d, 0xf7, 0x4c, 0x57, 0xfb, 0x88, 0x66, 0x8b, 0x05, 0x7e, + 0x81, 0x82, 0x80, 0x83, 0x91, 0x86, 0x95, 0x1f, 0xe0, 0x06, 0x98, 0x95, + 0x94, 0x96, 0x93, 0x85, 0x90, 0x81, 0x1f, 0x7c, 0x8b, 0xc1, 0xf7, 0x92, + 0x95, 0x8b, 0x05, 0x98, 0x95, 0x94, 0x96, 0x94, 0x86, 0x8f, 0x80, 0x1f, + 0x50, 0x8b, 0xfb, 0x0d, 0xfb, 0x4c, 0x60, 0xf7, 0x4c, 0x4f, 0x8b, 0x05, + 0x7e, 0x81, 0x82, 0x80, 0x83, 0x91, 0x86, 0x95, 0x1f, 0x95, 0x8b, 0x55, + 0xfb, 0x92, 0x7d, 0x8b, 0x05, 0x7e, 0x81, 0x82, 0x80, 0x83, 0x91, 0x86, + 0x94, 0x1f, 0xe0, 0x06, 0x98, 0x95, 0x94, 0x96, 0x94, 0x86, 0x8f, 0x80, + 0x1f, 0x66, 0x8b, 0xbf, 0xf7, 0x88, 0xb7, 0xfb, 0x4c, 0xab, 0x8b, 0x05, + 0x0e, 0xf8, 0x14, 0xf7, 0xc1, 0x15, 0xf7, 0x49, 0x06, 0x9f, 0x97, 0x94, + 0x9a, 0x97, 0x85, 0x8f, 0x79, 0x1f, 0xfb, 0x48, 0x8b, 0xad, 0xf7, 0x35, + 0x8c, 0x8f, 0x05, 0x8c, 0x8e, 0x8b, 0x8e, 0x8b, 0x8d, 0x8b, 0x93, 0x83, + 0x92, 0x83, 0x8b, 0x7d, 0x8b, 0x82, 0x82, 0x87, 0x79, 0x08, 0x69, 0xfb, + 0x35, 0xfb, 0x49, 0x8b, 0x05, 0x78, 0x7f, 0x82, 0x7c, 0x80, 0x92, 0x86, + 0x9b, 0x1f, 0xf7, 0x48, 0x8b, 0x69, 0xfb, 0x36, 0x05, 0x89, 0x83, 0x8b, + 0x8a, 0x8b, 0x88, 0x8b, 0x83, 0x93, 0x84, 0x94, 0x8b, 0x98, 0x8b, 0x94, + 0x94, 0x8f, 0x9d, 0x08, 0xad, 0xf7, 0x36, 0x05, 0xfb, 0xa8, 0xfb, 0x99, + 0x15, 0x77, 0x7f, 0x82, 0x7c, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0x26, + 0x06, 0x9f, 0x97, 0x94, 0x9a, 0x96, 0x84, 0x90, 0x7b, 0x1f, 0xfc, 0x26, + 0x06, 0x0e, 0xf8, 0xdf, 0xf8, 0x71, 0x15, 0x93, 0x93, 0x8f, 0x92, 0x8b, + 0x91, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x85, 0x8b, 0x88, 0x89, 0x7f, + 0x81, 0x08, 0xfc, 0x4a, 0xfc, 0x32, 0x05, 0x81, 0x82, 0x88, 0x85, 0x8b, + 0x85, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x92, 0x8b, 0x8f, 0x8d, 0x95, + 0x95, 0x08, 0xf8, 0x4b, 0xf8, 0x32, 0x05, 0xfb, 0xc6, 0xf7, 0x1b, 0x15, + 0xfb, 0x1e, 0x63, 0x8b, 0x8b, 0x8b, 0x7a, 0x8b, 0x84, 0x91, 0x84, 0x92, + 0x8b, 0x8e, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, 0x08, 0xd0, 0xa0, 0x52, 0xfb, + 0xa0, 0x05, 0x74, 0x8c, 0x76, 0x8b, 0x7a, 0x8b, 0x08, 0x75, 0x7e, 0x83, + 0x7c, 0x82, 0x91, 0x86, 0x96, 0x1f, 0xf7, 0x47, 0x06, 0x98, 0x96, 0x95, + 0x97, 0x94, 0x85, 0x90, 0x80, 0x1f, 0x44, 0x8b, 0xce, 0xf7, 0xd1, 0x05, + 0xf7, 0x06, 0xfc, 0xd4, 0x15, 0xf7, 0x6c, 0xf7, 0x3a, 0x9b, 0x9b, 0x8b, + 0xc0, 0x8b, 0xb8, 0x64, 0xb0, 0x5b, 0x8b, 0x66, 0x8b, 0x67, 0x7b, 0x6e, + 0x6f, 0x7b, 0x7a, 0x7f, 0x78, 0x8b, 0x80, 0x8b, 0x84, 0x92, 0x85, 0x92, + 0x8b, 0x94, 0x8b, 0x92, 0x90, 0x90, 0x96, 0x08, 0x9c, 0xaa, 0xad, 0xa0, + 0xae, 0x8b, 0xab, 0x8b, 0xa6, 0x73, 0x8b, 0x6e, 0x8b, 0x6f, 0x80, 0x7d, + 0x46, 0x53, 0x08, 0xfb, 0x31, 0xfb, 0x0f, 0x81, 0x60, 0xf7, 0x7a, 0x8b, + 0x94, 0xb2, 0x05, 0x8f, 0x8c, 0x8e, 0x8b, 0x1e, 0x8c, 0x92, 0x83, 0x91, + 0x83, 0x8b, 0x81, 0x8b, 0x81, 0x83, 0x89, 0x7f, 0x08, 0x8a, 0x88, 0xfb, + 0x2a, 0x8b, 0x05, 0x0e, 0xf7, 0xa6, 0xf8, 0xf8, 0x15, 0xfb, 0x1f, 0x63, + 0x8b, 0x8b, 0x8b, 0x7a, 0x8b, 0x84, 0x91, 0x84, 0x92, 0x8b, 0x8e, 0x8b, + 0x8e, 0x8b, 0x8f, 0x8c, 0x08, 0xd0, 0xa0, 0x52, 0xfb, 0xa0, 0x05, 0x74, + 0x8c, 0x76, 0x8b, 0x7a, 0x8b, 0x08, 0x75, 0x7e, 0x83, 0x7c, 0x82, 0x91, + 0x86, 0x96, 0x1f, 0xf7, 0x47, 0x06, 0x99, 0x96, 0x95, 0x97, 0x94, 0x85, + 0x90, 0x7f, 0x1f, 0x44, 0x8b, 0xcf, 0xf7, 0xd1, 0x05, 0xf7, 0xd3, 0xfb, + 0x1b, 0x15, 0x93, 0x92, 0x8f, 0x93, 0x8b, 0x91, 0x8b, 0x94, 0x84, 0x92, + 0x82, 0x8b, 0x85, 0x8b, 0x88, 0x89, 0x80, 0x81, 0x08, 0xfc, 0x4b, 0xfc, + 0x32, 0x05, 0x81, 0x82, 0x88, 0x85, 0x8b, 0x85, 0x8b, 0x82, 0x92, 0x84, + 0x94, 0x8b, 0x92, 0x8b, 0x8f, 0x8d, 0x95, 0x95, 0x08, 0xf8, 0x4b, 0xf8, + 0x32, 0x05, 0x4b, 0xfc, 0x14, 0x15, 0x7f, 0x52, 0x6d, 0x8b, 0x05, 0x78, + 0x8c, 0x7f, 0x82, 0x8b, 0x7d, 0x08, 0x82, 0x91, 0x86, 0x96, 0x1e, 0xe1, + 0x06, 0x99, 0x96, 0x95, 0x97, 0x94, 0x85, 0x90, 0x80, 0x1f, 0x7d, 0x8b, + 0x97, 0xc4, 0x05, 0xa7, 0x96, 0x91, 0x9b, 0x94, 0x85, 0x90, 0x7f, 0x1f, + 0x7e, 0x8b, 0xb9, 0xf7, 0x6c, 0x52, 0x8b, 0xfb, 0x42, 0xfb, 0x6e, 0x83, + 0x69, 0xf7, 0x29, 0x8b, 0x05, 0x93, 0xaf, 0x15, 0xfb, 0x00, 0x8b, 0xf7, + 0x25, 0xf7, 0x48, 0x8c, 0x8b, 0x65, 0xfb, 0x48, 0x05, 0x0e, 0xf7, 0x68, + 0xf8, 0x67, 0x15, 0x7d, 0x80, 0x82, 0x7f, 0x1f, 0x8b, 0x81, 0x91, 0x87, + 0x97, 0x8a, 0xb8, 0x8a, 0xab, 0x72, 0x8b, 0x69, 0x8b, 0x60, 0x5a, 0x62, + 0x57, 0x8b, 0x6d, 0x8b, 0x74, 0x93, 0x72, 0xa0, 0x87, 0x8f, 0x88, 0x8c, + 0x86, 0x8b, 0x08, 0x80, 0x81, 0x81, 0x80, 0x75, 0xc4, 0x70, 0xb9, 0xd5, + 0xd3, 0xc8, 0xcb, 0x1f, 0x8b, 0xa8, 0x7f, 0xa0, 0x6d, 0x9f, 0x08, 0xb7, + 0xa5, 0x9f, 0xa8, 0x8b, 0xb0, 0x08, 0xb7, 0x68, 0xa9, 0x58, 0x5a, 0x49, + 0x69, 0x72, 0x83, 0x91, 0x85, 0x93, 0x1e, 0x92, 0x8b, 0x8e, 0x8d, 0x94, + 0x93, 0x9e, 0x9c, 0xa5, 0x95, 0xa8, 0x8b, 0x08, 0xad, 0xa2, 0x79, 0x70, + 0x68, 0x68, 0x6e, 0x62, 0x1f, 0x7b, 0x06, 0xf8, 0x10, 0x95, 0x15, 0x93, + 0x92, 0x8f, 0x93, 0x8b, 0x91, 0x8b, 0x94, 0x84, 0x92, 0x82, 0x8b, 0x85, + 0x8b, 0x88, 0x89, 0x80, 0x81, 0x08, 0xfc, 0x4b, 0xfc, 0x32, 0x05, 0x81, + 0x81, 0x88, 0x86, 0x8b, 0x85, 0x8b, 0x82, 0x92, 0x84, 0x94, 0x8b, 0x91, + 0x8b, 0x91, 0x8e, 0x94, 0x94, 0x08, 0xf8, 0x4b, 0xf8, 0x32, 0x05, 0x4d, + 0xfc, 0x14, 0x15, 0x7e, 0x52, 0x6d, 0x8b, 0x05, 0x78, 0x8c, 0x7f, 0x82, + 0x8b, 0x7d, 0x08, 0x82, 0x91, 0x86, 0x96, 0x1e, 0xe1, 0x06, 0x99, 0x96, + 0x95, 0x97, 0x94, 0x85, 0x90, 0x80, 0x1f, 0x7d, 0x8b, 0x97, 0xc4, 0x05, + 0xa8, 0x95, 0x91, 0x9b, 0x94, 0x85, 0x90, 0x7f, 0x1f, 0x7e, 0x8b, 0xb9, + 0xf7, 0x6c, 0x52, 0x8b, 0xfb, 0x42, 0xfb, 0x6e, 0x84, 0x69, 0xf7, 0x29, + 0x8b, 0x05, 0x92, 0xaf, 0x15, 0xfb, 0x00, 0x8b, 0xf7, 0x25, 0xf7, 0x48, + 0x8c, 0x8b, 0x65, 0xfb, 0x48, 0x05, 0x0e, 0xf7, 0x65, 0xf7, 0x98, 0x15, + 0x89, 0x82, 0x8a, 0x81, 0x8b, 0x82, 0x8b, 0x47, 0xbf, 0x56, 0xcf, 0x8b, + 0xb3, 0x8b, 0xb5, 0x9c, 0xae, 0xaa, 0x9c, 0x99, 0x90, 0x92, 0x8b, 0x94, + 0x8b, 0x93, 0x85, 0x90, 0x83, 0x8b, 0x85, 0x8b, 0x86, 0x89, 0x85, 0x85, + 0x08, 0x69, 0x6a, 0x6d, 0x7d, 0x67, 0x8b, 0x57, 0x8b, 0x64, 0xb2, 0x8b, + 0xc0, 0x8b, 0x93, 0x8c, 0x93, 0x8d, 0x93, 0x08, 0x93, 0xb2, 0x05, 0x98, + 0xc9, 0xc5, 0xbe, 0xc3, 0x8b, 0xa1, 0x8b, 0xa7, 0x81, 0x97, 0x7f, 0x8e, + 0x87, 0x98, 0x78, 0x8b, 0x8a, 0x08, 0x89, 0x76, 0x05, 0x8f, 0x84, 0x90, + 0x87, 0x91, 0x8b, 0x94, 0x8b, 0x95, 0x95, 0x8e, 0x96, 0x08, 0x98, 0xcc, + 0x05, 0x8c, 0x8d, 0x8b, 0x8c, 0x8b, 0x8e, 0x8b, 0x93, 0x85, 0x91, 0x83, + 0x8b, 0x80, 0x8b, 0x83, 0x83, 0x87, 0x7d, 0x6d, 0xa1, 0x76, 0x92, 0x6c, + 0x8b, 0x3e, 0x8b, 0x3e, 0x4a, 0x7b, 0x3b, 0x08, 0x81, 0x5e, 0x05, 0xf7, + 0x6d, 0xf7, 0xd2, 0x15, 0xfb, 0x53, 0xfb, 0x46, 0xfb, 0x41, 0xfb, 0x4d, + 0xfb, 0x1b, 0xef, 0x27, 0xf7, 0x1d, 0xf7, 0x53, 0xf7, 0x46, 0xf7, 0x41, + 0xf7, 0x4d, 0xf7, 0x1c, 0x27, 0xee, 0xfb, 0x1d, 0x1f, 0x81, 0x62, 0x15, + 0xf7, 0x0a, 0xe2, 0x35, 0xfb, 0x09, 0xfb, 0x33, 0xfb, 0x2d, 0xfb, 0x29, + 0xfb, 0x39, 0xfb, 0x0a, 0x35, 0xe1, 0xf7, 0x09, 0xf7, 0x33, 0xf7, 0x2d, + 0xf7, 0x29, 0xf7, 0x38, 0x1f, 0x0e, 0xf7, 0xb4, 0xf7, 0x96, 0x15, 0xcb, + 0x06, 0xac, 0x7f, 0xa7, 0x5b, 0x9f, 0x3d, 0x08, 0xb2, 0x06, 0x98, 0x96, + 0x95, 0x97, 0x94, 0x85, 0x90, 0x81, 0x1f, 0x7c, 0x06, 0x70, 0xd5, 0x84, + 0x97, 0x70, 0xa6, 0xc0, 0x99, 0xaf, 0xb3, 0x8b, 0xb9, 0x08, 0xb8, 0x68, + 0xa8, 0x56, 0x1e, 0xfb, 0x1d, 0x06, 0x7d, 0x80, 0x82, 0x7e, 0x82, 0x91, + 0x86, 0x96, 0x1f, 0xa3, 0x8b, 0x56, 0xfb, 0x8f, 0x72, 0x8b, 0x05, 0x7e, + 0x80, 0x81, 0x7f, 0x82, 0x91, 0x86, 0x96, 0x1f, 0xeb, 0x06, 0x98, 0x96, + 0x95, 0x97, 0x94, 0x85, 0x90, 0x80, 0x1f, 0x68, 0x8b, 0xa0, 0xf1, 0x05, + 0x93, 0xaf, 0x15, 0xa3, 0xf7, 0x05, 0xd8, 0x8b, 0x05, 0xaf, 0xa2, 0x7a, + 0x6f, 0x63, 0x60, 0x6f, 0x4e, 0x1f, 0x53, 0x06, 0xf7, 0x16, 0xf7, 0xb0, + 0x15, 0xfb, 0x53, 0xfb, 0x46, 0xfb, 0x41, 0xfb, 0x4d, 0xfb, 0x1b, 0xef, + 0x27, 0xf7, 0x1d, 0xf7, 0x53, 0xf7, 0x46, 0xf7, 0x41, 0xf7, 0x4d, 0xf7, + 0x1c, 0x27, 0xee, 0xfb, 0x1d, 0x1f, 0x81, 0x62, 0x15, 0xf7, 0x0a, 0xe2, + 0x35, 0xfb, 0x09, 0xfb, 0x33, 0xfb, 0x2d, 0xfb, 0x29, 0xfb, 0x39, 0xfb, + 0x0a, 0x35, 0xe1, 0xf7, 0x09, 0xf7, 0x33, 0xf7, 0x2d, 0xf7, 0x29, 0xf7, + 0x38, 0x1f, 0x0e, 0x0e, 0xf8, 0xcf, 0xf8, 0x21, 0x15, 0x60, 0xfb, 0x5e, + 0x05, 0x8b, 0x8b, 0x8b, 0x89, 0x8a, 0x89, 0x8a, 0x88, 0x8b, 0x88, 0x8b, + 0x89, 0x8b, 0x83, 0x93, 0x84, 0x93, 0x8b, 0x99, 0x8b, 0x95, 0x95, 0x8e, + 0x9c, 0x08, 0xbf, 0xf7, 0x87, 0xfc, 0x41, 0x8b, 0x05, 0x77, 0x7f, 0x82, + 0x7b, 0x80, 0x92, 0x86, 0x9b, 0x1f, 0xf8, 0x18, 0x06, 0x0e, 0xf8, 0x4e, + 0xf8, 0xd5, 0x15, 0x8d, 0x93, 0x8b, 0x8c, 0x8b, 0x8e, 0x8b, 0x93, 0x84, + 0x92, 0x82, 0x8b, 0x7e, 0x8b, 0x82, 0x81, 0x87, 0x7a, 0x08, 0x52, 0xfb, + 0x9f, 0x8a, 0x7f, 0x05, 0x83, 0x92, 0x84, 0x94, 0x1e, 0x98, 0x8b, 0x93, + 0x94, 0x8f, 0x9d, 0x08, 0xc4, 0xf7, 0x9f, 0x05, 0x35, 0xfc, 0x2b, 0x15, + 0x8c, 0x97, 0x05, 0x93, 0x84, 0x92, 0x82, 0x1e, 0x7e, 0x8b, 0x82, 0x82, + 0x87, 0x79, 0x08, 0x53, 0xfb, 0x9f, 0x05, 0x8a, 0x87, 0x8a, 0x85, 0x8b, + 0x89, 0x8b, 0x83, 0x92, 0x84, 0x94, 0x8b, 0x98, 0x8b, 0x94, 0x94, 0x8f, + 0x9d, 0x08, 0xc4, 0xf7, 0x9f, 0x05, 0x0e, 0xf7, 0x3d, 0x9b, 0x15, 0xa1, + 0x74, 0xa2, 0x82, 0xb3, 0x8b, 0xcd, 0x8b, 0xd0, 0xa5, 0xca, 0xbc, 0x08, + 0x7e, 0x50, 0xd6, 0x8b, 0x05, 0x9f, 0x97, 0x95, 0x99, 0x97, 0x84, 0x8f, + 0x7b, 0x1f, 0x69, 0x8b, 0xdb, 0xf8, 0x0d, 0xfb, 0x07, 0x8b, 0x05, 0x76, + 0x7f, 0x82, 0x7c, 0x80, 0x92, 0x86, 0x9c, 0x1f, 0xd6, 0x8b, 0x53, 0xfb, + 0x9a, 0x05, 0x46, 0x4d, 0x49, 0x6e, 0x46, 0x8b, 0x5d, 0x8b, 0x70, 0xa5, + 0x8b, 0xb7, 0x8b, 0x8f, 0x8c, 0x94, 0x8d, 0x93, 0x08, 0xcb, 0xf7, 0xc2, + 0x2c, 0x8b, 0x05, 0x77, 0x7f, 0x82, 0x7c, 0x80, 0x92, 0x86, 0x9b, 0x1f, + 0xc2, 0x8b, 0xfb, 0x09, 0xfc, 0xba, 0x05, 0x8a, 0x86, 0x8a, 0x86, 0x8b, + 0x89, 0x8b, 0x83, 0x92, 0x84, 0x94, 0x8b, 0x99, 0x8b, 0x94, 0x94, 0x8f, + 0x9d, 0x08, 0xb3, 0xf7, 0x51, 0x05, 0x0e, 0xf8, 0xec, 0x14, 0x8b, 0x15, + 0x7b, 0x9b, 0xf8, 0x35, 0x99, 0xf7, 0x18, 0x98, 0xa6, 0x9a, 0x06, 0x1e, + 0x0a, 0x03, 0x96, 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xb4, 0x0a, + 0xb4, 0x0c, 0x0c, 0xb6, 0x0b, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00, 0x00 +}; +const unsigned int fonts_NimbusMonL_ReguObli_cff_len = 28416; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Medi.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Medi.cff.c new file mode 100644 index 00000000000..69ab920bf0c --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Medi.cff.c @@ -0,0 +1,2030 @@ +const unsigned char fonts_NimbusRomNo9L_Medi_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x13, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x52, 0x6f, 0x6d, 0x4e, 0x6f, 0x39, 0x4c, 0x2d, 0x4d, + 0x65, 0x64, 0x69, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x32, 0xf8, 0x1f, + 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, 0x14, + 0x04, 0x1d, 0x00, 0x4c, 0x9d, 0x05, 0x0d, 0xfb, 0x3c, 0xfb, 0x6e, 0xfa, + 0x7c, 0xfa, 0x48, 0x05, 0x1c, 0x00, 0xf3, 0x0f, 0x1c, 0x00, 0x00, 0x10, + 0x1c, 0x02, 0xc4, 0x11, 0x1c, 0x00, 0x33, 0x1c, 0x5e, 0xd1, 0x12, 0x00, + 0x08, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, + 0x00, 0x1f, 0x00, 0x5f, 0x00, 0x78, 0x00, 0x8a, 0x45, 0x75, 0x72, 0x6f, + 0x6d, 0x69, 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, + 0x68, 0x65, 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, + 0x30, 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, + 0x79, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, + 0x73, 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, + 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, + 0x20, 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x4e, 0x6f, 0x39, 0x20, 0x4c, + 0x20, 0x4d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x4e, 0x69, 0x6d, 0x62, 0x75, + 0x73, 0x20, 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x4e, 0x6f, 0x39, 0x20, + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, + 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, + 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, + 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, + 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, + 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, + 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, + 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, + 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, + 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, + 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, + 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, + 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, + 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, + 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, + 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, + 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, + 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, + 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, + 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, + 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, + 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, + 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8e, + 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, + 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, 0xae, 0x00, 0xac, 0x00, 0xb0, + 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, 0xb4, 0x00, 0xb2, 0x00, 0xb5, + 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, 0xb9, 0x00, 0xb7, 0x00, 0xba, + 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, 0xbc, 0x00, 0xbf, 0x00, 0xc0, + 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, 0xc2, 0x00, 0xc5, 0x00, 0xc7, + 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xc8, 0x00, 0xcb, 0x00, 0xc9, + 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd1, 0x00, 0xcf, 0x00, 0xd2, + 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd7, + 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, 0xd9, 0x00, 0xdc, 0x00, 0xdd, + 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xdf, 0x00, 0xe2, 0x00, 0xe4, + 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, 0x87, 0x00, 0x96, 0x00, 0xa4, + 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa8, + 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa3, + 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, 0x97, 0x00, 0xa0, 0x00, 0x98, + 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x07, 0x00, 0x4a, 0x00, + 0x94, 0x00, 0xf2, 0x01, 0x84, 0x02, 0x5a, 0x03, 0x1f, 0x03, 0x57, 0x03, + 0x99, 0x03, 0xda, 0x04, 0xb8, 0x04, 0xd4, 0x05, 0x0e, 0x05, 0x1f, 0x05, + 0x38, 0x05, 0x4d, 0x05, 0x9e, 0x05, 0xd7, 0x06, 0x33, 0x06, 0xa1, 0x06, + 0xd6, 0x07, 0x29, 0x07, 0x8e, 0x07, 0xb2, 0x08, 0x28, 0x08, 0x93, 0x08, + 0xc0, 0x09, 0x11, 0x09, 0x2e, 0x09, 0x46, 0x09, 0x62, 0x09, 0xc8, 0x0a, + 0x80, 0x0a, 0xe1, 0x0b, 0x54, 0x0b, 0xc3, 0x0c, 0x1e, 0x0c, 0x87, 0x0c, + 0xe2, 0x0d, 0x5c, 0x0d, 0xc5, 0x0d, 0xf8, 0x0e, 0x4a, 0x0e, 0xd1, 0x0f, + 0x14, 0x0f, 0x79, 0x0f, 0xcb, 0x10, 0x14, 0x10, 0x78, 0x10, 0xf4, 0x11, + 0x71, 0x12, 0x00, 0x12, 0x40, 0x12, 0xa4, 0x12, 0xf8, 0x13, 0x7b, 0x14, + 0x1b, 0x14, 0x8b, 0x14, 0xce, 0x14, 0xef, 0x15, 0x03, 0x15, 0x23, 0x15, + 0x41, 0x15, 0x4e, 0x15, 0x87, 0x16, 0x0d, 0x16, 0x60, 0x16, 0xab, 0x17, + 0x17, 0x17, 0x76, 0x17, 0xcf, 0x18, 0x6b, 0x18, 0xd0, 0x19, 0x12, 0x19, + 0x71, 0x19, 0xe9, 0x1a, 0x15, 0x1a, 0xb2, 0x1b, 0x17, 0x1b, 0x4e, 0x1b, + 0xbd, 0x1c, 0x17, 0x1c, 0x68, 0x1c, 0xe3, 0x1d, 0x1c, 0x1d, 0x6f, 0x1d, + 0xc6, 0x1e, 0x46, 0x1e, 0xdd, 0x1f, 0x67, 0x1f, 0xa4, 0x1f, 0xfd, 0x20, + 0x0a, 0x20, 0x63, 0x20, 0xa5, 0x20, 0xe9, 0x21, 0x72, 0x22, 0x24, 0x22, + 0x39, 0x22, 0xc2, 0x23, 0x3e, 0x24, 0x02, 0x24, 0x6e, 0x24, 0x96, 0x25, + 0x01, 0x25, 0x9a, 0x25, 0xe8, 0x26, 0x31, 0x26, 0xb7, 0x27, 0x37, 0x27, + 0x42, 0x27, 0xea, 0x28, 0xe7, 0x29, 0x00, 0x29, 0x7b, 0x29, 0x94, 0x29, + 0xce, 0x2a, 0x3b, 0x2a, 0xa6, 0x2b, 0x39, 0x2b, 0x7a, 0x2c, 0x83, 0x2c, + 0xed, 0x2d, 0x13, 0x2d, 0x38, 0x2d, 0x55, 0x2d, 0x9a, 0x2d, 0xa9, 0x2d, + 0xdb, 0x2d, 0xf4, 0x2e, 0x20, 0x2e, 0x4d, 0x2e, 0x91, 0x2e, 0xd7, 0x2f, + 0x1c, 0x2f, 0x39, 0x2f, 0x46, 0x2f, 0xf8, 0x30, 0x78, 0x30, 0xd1, 0x31, + 0x64, 0x32, 0x1e, 0x32, 0x4a, 0x32, 0xfb, 0x33, 0x27, 0x33, 0x68, 0x33, + 0xe5, 0x34, 0x77, 0x34, 0xf0, 0x35, 0x7a, 0x35, 0xfd, 0x36, 0x81, 0x36, + 0xfc, 0x37, 0xa0, 0x38, 0x26, 0x38, 0xcf, 0x39, 0x41, 0x39, 0xd4, 0x3a, + 0x5f, 0x3a, 0xea, 0x3b, 0x6c, 0x3b, 0xc9, 0x3c, 0x1e, 0x3c, 0x74, 0x3c, + 0xc1, 0x3d, 0x54, 0x3d, 0xc7, 0x3e, 0x31, 0x3e, 0x9b, 0x3e, 0xfc, 0x3f, + 0x88, 0x40, 0x2f, 0x40, 0xbe, 0x41, 0x45, 0x41, 0xcc, 0x42, 0x4a, 0x42, + 0xdc, 0x43, 0x39, 0x43, 0xa6, 0x44, 0x41, 0x44, 0xf2, 0x45, 0x9b, 0x46, + 0x43, 0x46, 0xe2, 0x47, 0xab, 0x48, 0x5b, 0x48, 0xe3, 0x49, 0x6b, 0x49, + 0xec, 0x4a, 0x6e, 0x4a, 0xe7, 0x4b, 0x3e, 0x4b, 0x8c, 0x4b, 0xd9, 0x4c, + 0x1d, 0x4c, 0xc3, 0x4d, 0x25, 0x4d, 0x7d, 0x4d, 0xd5, 0x4e, 0x25, 0x4e, + 0x9f, 0x4f, 0x33, 0x4f, 0xb0, 0x50, 0x26, 0x50, 0x9b, 0x51, 0x07, 0x51, + 0xb3, 0x52, 0x09, 0x52, 0x84, 0x52, 0xf3, 0x53, 0xa8, 0x54, 0x3d, 0x54, + 0x75, 0x54, 0xbd, 0x55, 0x1f, 0x55, 0x38, 0x55, 0x49, 0x55, 0x75, 0x55, + 0x83, 0x55, 0xb3, 0x55, 0xeb, 0x56, 0x88, 0x56, 0xb0, 0x57, 0x3f, 0x57, + 0xb4, 0x58, 0x56, 0x58, 0xf4, 0x59, 0xa0, 0x59, 0xa3, 0x59, 0xb5, 0x59, + 0xcc, 0x5a, 0x37, 0xfc, 0x1d, 0x0e, 0xfc, 0x1d, 0x0e, 0xfb, 0xca, 0xf7, + 0x3a, 0xf7, 0x30, 0x15, 0x5d, 0x65, 0x64, 0x5e, 0x5b, 0xaf, 0x66, 0xba, + 0xbb, 0xb1, 0xb0, 0xb9, 0xba, 0x65, 0xb2, 0x5c, 0x1f, 0x99, 0xd9, 0x15, + 0x98, 0xf7, 0x0f, 0x94, 0xbc, 0xa9, 0xeb, 0x99, 0xb7, 0x8f, 0x9f, 0x8b, + 0xa2, 0x08, 0xcc, 0x6c, 0xb0, 0x56, 0x55, 0x6c, 0x66, 0x4c, 0x1e, 0x8b, + 0x72, 0x8f, 0x78, 0x99, 0x5e, 0xa8, 0x2c, 0x95, 0x59, 0x98, 0xfb, 0x0f, + 0x08, 0xa8, 0x06, 0x0e, 0x33, 0xf7, 0x3c, 0xf8, 0x28, 0x15, 0xad, 0xf7, + 0x27, 0x95, 0xbe, 0x8b, 0xa1, 0x08, 0xb1, 0x6f, 0xa8, 0x66, 0x65, 0x71, + 0x6f, 0x60, 0x1e, 0x8b, 0x76, 0x97, 0x4b, 0xa0, 0x38, 0x8d, 0x84, 0x8f, + 0x78, 0x90, 0x75, 0x08, 0xb4, 0x06, 0xf7, 0x98, 0x16, 0xaa, 0xf7, 0x19, + 0x98, 0xcc, 0x8b, 0xa1, 0x08, 0xb1, 0x6f, 0xa8, 0x66, 0x65, 0x71, 0x6f, + 0x60, 0x1e, 0x8b, 0x76, 0x97, 0x4c, 0xa0, 0x37, 0x8c, 0x84, 0x90, 0x77, + 0x90, 0x76, 0x08, 0xb4, 0x06, 0x0e, 0xf8, 0x67, 0xf7, 0xaf, 0x15, 0x34, + 0x8b, 0x9d, 0xf7, 0x1a, 0xed, 0x8b, 0x8b, 0xd4, 0x33, 0x8b, 0xa8, 0xf7, + 0x66, 0x3e, 0x8b, 0x6d, 0xfb, 0x66, 0xfb, 0x05, 0x8b, 0xa8, 0xf7, 0x66, + 0x3e, 0x8b, 0x6d, 0xfb, 0x66, 0x21, 0x8b, 0x8b, 0x42, 0xeb, 0x8b, 0x05, + 0x79, 0xfb, 0x1a, 0x20, 0x8b, 0x8b, 0x42, 0xeb, 0x8b, 0x6e, 0xfb, 0x66, + 0xd9, 0x8b, 0xa8, 0xf7, 0x66, 0xf7, 0x05, 0x8b, 0x6e, 0xfb, 0x66, 0xd9, + 0x8b, 0xa8, 0xf7, 0x66, 0xed, 0x8b, 0x8b, 0xd4, 0x05, 0xfb, 0x27, 0xf7, + 0x1a, 0x15, 0x79, 0xfb, 0x1a, 0xfb, 0x05, 0x8b, 0x9d, 0xf7, 0x1a, 0xf7, + 0x05, 0x8b, 0x05, 0x0e, 0xf8, 0x40, 0xf8, 0x75, 0x15, 0xf7, 0x21, 0x07, + 0x5c, 0xa7, 0x69, 0x96, 0x3d, 0x98, 0x08, 0xd7, 0x54, 0x3d, 0x07, 0x5d, + 0x86, 0x75, 0x85, 0x6c, 0x7a, 0x54, 0x6b, 0x6c, 0x56, 0x8b, 0x4c, 0x8b, + 0x32, 0xbd, 0x50, 0xf7, 0x1a, 0x48, 0x08, 0xfb, 0x8f, 0x07, 0x41, 0x99, + 0x63, 0xb8, 0x6b, 0xf7, 0x00, 0x08, 0x76, 0x8d, 0x8b, 0xfb, 0x30, 0x05, + 0xdd, 0x69, 0xa3, 0x85, 0xc9, 0x88, 0x08, 0x28, 0xc2, 0xee, 0x07, 0xdd, + 0x9a, 0xb2, 0x9c, 0xab, 0xaa, 0xac, 0xab, 0x9c, 0xb8, 0x8b, 0xc3, 0x8b, + 0xbb, 0x7c, 0xb6, 0x71, 0xa8, 0x68, 0xb3, 0x6d, 0x9f, 0x2a, 0xbd, 0x08, + 0xf7, 0x6b, 0x07, 0xd2, 0x7b, 0xb1, 0x5f, 0xa8, 0x27, 0x08, 0xa0, 0x06, + 0xfb, 0x33, 0xfb, 0x7b, 0x15, 0xdb, 0x5e, 0x98, 0x7a, 0x8b, 0x55, 0x8b, + 0x50, 0x6d, 0x6a, 0x4c, 0x7f, 0x08, 0xf7, 0x70, 0x07, 0x53, 0xf7, 0x60, + 0x15, 0x4f, 0xa0, 0x6e, 0xac, 0x8b, 0xb9, 0x8b, 0xbb, 0xa5, 0xa5, 0xca, + 0x9b, 0x08, 0xfb, 0x52, 0x07, 0x0e, 0xf7, 0xf9, 0xf9, 0x8d, 0xf8, 0x08, + 0x15, 0xfb, 0x05, 0xfb, 0x05, 0xfb, 0x10, 0xfb, 0x0f, 0x37, 0xc0, 0x54, + 0xdb, 0x1f, 0xb7, 0x8b, 0xb9, 0x9f, 0xaa, 0xac, 0xc1, 0xc3, 0xad, 0xdf, + 0x8b, 0xd9, 0x08, 0xd1, 0x5d, 0xb8, 0x45, 0x1e, 0xaa, 0x58, 0x15, 0xa9, + 0xa1, 0x6c, 0x62, 0x1f, 0x8b, 0x63, 0x7e, 0x60, 0x6f, 0x59, 0x6d, 0x54, + 0x68, 0x6e, 0x66, 0x8b, 0x6b, 0x8b, 0x7a, 0x9f, 0x8b, 0xaf, 0x8b, 0xb4, + 0xad, 0xe6, 0xac, 0xbc, 0xa4, 0xaf, 0xa1, 0x9b, 0xa5, 0x8b, 0x08, 0x4b, + 0xf8, 0x07, 0x15, 0x65, 0x06, 0x86, 0x8b, 0x86, 0x87, 0x86, 0x84, 0x75, + 0x6c, 0x41, 0x70, 0x4e, 0x8b, 0x62, 0x8b, 0x76, 0x91, 0x6c, 0xa1, 0x08, + 0x70, 0x9e, 0x74, 0x93, 0x72, 0x8b, 0x08, 0xfb, 0x08, 0xfb, 0x02, 0xfb, + 0x0c, 0xfb, 0x14, 0x3b, 0xc0, 0x53, 0xd7, 0x1f, 0xc7, 0x8b, 0xc0, 0xaa, + 0xb3, 0xc5, 0xb5, 0xc9, 0x9b, 0xc3, 0x8c, 0xe4, 0xa0, 0x87, 0x97, 0x8a, + 0x99, 0x8b, 0xad, 0x8b, 0xb2, 0x94, 0xb5, 0x9d, 0x08, 0xfb, 0xf0, 0xfd, + 0x00, 0xc2, 0x8b, 0xf8, 0x1e, 0xf9, 0x50, 0x05, 0xfb, 0xf9, 0x4e, 0x15, + 0x8f, 0x8a, 0x8e, 0x8a, 0x94, 0x85, 0x94, 0x84, 0x8c, 0x8a, 0x91, 0x89, + 0xa0, 0x82, 0x93, 0x7e, 0x8b, 0x75, 0x8b, 0x59, 0x75, 0x4a, 0x67, 0x56, + 0x6e, 0x61, 0x70, 0x78, 0x6b, 0x8b, 0x6d, 0x8b, 0x77, 0xa3, 0x8d, 0xab, + 0x08, 0x8e, 0xb9, 0xac, 0xe2, 0xae, 0xbf, 0x08, 0xa0, 0xaa, 0xa4, 0xa0, + 0x9b, 0x89, 0x08, 0x0e, 0xf7, 0x52, 0xf8, 0xd5, 0xf8, 0x37, 0x15, 0x73, + 0x07, 0xc6, 0x84, 0x92, 0x86, 0x8b, 0x6e, 0x8b, 0x63, 0x79, 0x6a, 0x51, + 0x43, 0x08, 0xfb, 0x2b, 0xf7, 0x6a, 0x05, 0xf5, 0xb2, 0xb9, 0xb7, 0x8b, + 0xca, 0x08, 0xd5, 0x49, 0xbb, 0x26, 0xfb, 0x0c, 0x40, 0x4e, 0x2a, 0x1e, + 0x8b, 0x5f, 0x97, 0x6b, 0xb3, 0x46, 0xfb, 0x22, 0x45, 0x55, 0x4c, 0x8b, + 0x2d, 0x8b, 0x24, 0xda, 0x42, 0xf7, 0x04, 0x8b, 0xd5, 0x8b, 0xcd, 0xa5, + 0xdd, 0xc8, 0x08, 0xc7, 0x49, 0xaf, 0x75, 0xc0, 0x8b, 0xaa, 0x8b, 0xb1, + 0x98, 0xa3, 0x9d, 0x9b, 0x98, 0x98, 0x9b, 0xa4, 0xb4, 0x08, 0x9b, 0xa5, + 0x77, 0x97, 0x05, 0x7a, 0x70, 0x7a, 0x80, 0x73, 0x8b, 0x65, 0x8b, 0x72, + 0x9e, 0x53, 0xd3, 0xc2, 0xd7, 0x96, 0x9b, 0xa6, 0xb6, 0x08, 0xa6, 0xb7, + 0x05, 0x9d, 0xa8, 0x97, 0x92, 0xb6, 0x8f, 0x08, 0xa3, 0x07, 0xfb, 0x62, + 0x06, 0xfb, 0x92, 0xfb, 0x19, 0x15, 0xd6, 0xfb, 0x04, 0xa1, 0x6b, 0xab, + 0x61, 0x64, 0x6f, 0x72, 0x80, 0x71, 0x8b, 0x6d, 0x8b, 0x69, 0x9b, 0x72, + 0xa5, 0x60, 0xb8, 0x6e, 0xcb, 0x8b, 0xbf, 0x8b, 0xb0, 0x9e, 0xa4, 0xc2, + 0xab, 0x08, 0xbb, 0x43, 0x05, 0xd5, 0xf7, 0x3a, 0x15, 0x56, 0xcd, 0x76, + 0xb6, 0x8b, 0xb4, 0x08, 0xae, 0x9f, 0xa0, 0xab, 0xbc, 0xb6, 0x51, 0x48, + 0x1e, 0x8b, 0x62, 0x77, 0x74, 0x59, 0x7a, 0x08, 0x0e, 0xfb, 0xca, 0xec, + 0xf7, 0xf8, 0x15, 0xf7, 0x08, 0xce, 0xbd, 0xcd, 0x8b, 0xe1, 0x08, 0xd0, + 0x62, 0xba, 0x4f, 0x59, 0x6a, 0x6a, 0x5a, 0x5b, 0xa8, 0x6c, 0xb8, 0x1e, + 0x90, 0x8b, 0x90, 0x8b, 0x91, 0x8c, 0x8e, 0x8c, 0x8d, 0x8b, 0x8d, 0x8b, + 0x96, 0x8b, 0x93, 0x81, 0x8b, 0x7f, 0x8b, 0x65, 0x68, 0x61, 0x41, 0x57, + 0x08, 0x96, 0x75, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0xc6, 0xf9, 0x4a, 0x15, + 0x4d, 0x6a, 0x6f, 0x76, 0x64, 0x62, 0x36, 0x2f, 0x5d, 0xfb, 0x0b, 0x8b, + 0xfb, 0x15, 0x8b, 0x30, 0xa4, 0x32, 0xbb, 0x3f, 0xb9, 0x43, 0xb6, 0x63, + 0xed, 0x50, 0x08, 0xa7, 0x07, 0x52, 0xaf, 0x72, 0xa5, 0x76, 0xb8, 0x6d, + 0xc9, 0x7d, 0xe7, 0x8b, 0xf7, 0x1d, 0x8b, 0xf7, 0x1e, 0x99, 0xf0, 0xa7, + 0xc7, 0xa0, 0xb7, 0xa3, 0xa5, 0xc7, 0xb3, 0x08, 0xa6, 0x07, 0x0e, 0xfb, + 0xca, 0xa6, 0xfb, 0x3c, 0x15, 0xc9, 0xac, 0xa7, 0xa0, 0xb1, 0xb4, 0xe1, + 0xe7, 0xb9, 0xf7, 0x0b, 0x8b, 0xf7, 0x14, 0x8b, 0xe7, 0x72, 0xe4, 0x5b, + 0xd7, 0x5d, 0xd3, 0x60, 0xb3, 0x29, 0xc6, 0x08, 0x6f, 0x07, 0xc4, 0x66, + 0xa4, 0x72, 0xa0, 0x5e, 0xa9, 0x4d, 0x99, 0x2e, 0x8b, 0xfb, 0x1c, 0x8b, + 0xfb, 0x1e, 0x7d, 0x26, 0x6f, 0x4f, 0x77, 0x5f, 0x72, 0x71, 0x4f, 0x63, + 0x08, 0x70, 0x07, 0x0e, 0xf7, 0xaa, 0xf8, 0x70, 0x15, 0xac, 0xa0, 0x97, + 0x8f, 0xb6, 0x8d, 0xa3, 0x8b, 0x94, 0x8d, 0x97, 0x90, 0x9f, 0x94, 0x9b, + 0xa1, 0x8b, 0x9d, 0x8b, 0xa5, 0x72, 0xa3, 0x70, 0x8b, 0x75, 0x8b, 0x7f, + 0x83, 0x77, 0x6c, 0x71, 0x66, 0x83, 0x81, 0x66, 0x6e, 0x08, 0x83, 0x8e, + 0x8b, 0x9e, 0x05, 0x8b, 0xa4, 0x90, 0x9e, 0x9c, 0xa7, 0x98, 0xa2, 0x8e, + 0x95, 0x8b, 0x9a, 0x08, 0xac, 0x77, 0xa1, 0x6f, 0x6d, 0x75, 0x75, 0x6f, + 0x1e, 0x8b, 0x7a, 0x8f, 0x81, 0x99, 0x71, 0xa0, 0x65, 0x8e, 0x80, 0x8c, + 0x61, 0x08, 0x84, 0x88, 0x05, 0x65, 0xa0, 0x85, 0x91, 0x72, 0xb3, 0x76, + 0xad, 0x7c, 0x96, 0x70, 0x8b, 0x6e, 0x8b, 0x78, 0x77, 0x8b, 0x6e, 0x8b, + 0x67, 0x9b, 0x7f, 0xbf, 0x87, 0xb9, 0x87, 0x9b, 0x87, 0xb3, 0x79, 0x08, + 0x84, 0x07, 0x6b, 0x75, 0x81, 0x88, 0x61, 0x89, 0x08, 0x53, 0x6e, 0x78, + 0x66, 0x6f, 0xa1, 0x75, 0xa7, 0x1f, 0xa0, 0x8b, 0x98, 0x94, 0x9f, 0xaa, + 0xa6, 0xb2, 0x93, 0x93, 0xb1, 0xa7, 0x08, 0x92, 0x86, 0x05, 0x8a, 0x5d, + 0x89, 0x81, 0x77, 0x69, 0x7f, 0x75, 0x88, 0x82, 0x8b, 0x7b, 0x08, 0x69, + 0x9e, 0x74, 0xa8, 0xa8, 0xa1, 0xa2, 0xa8, 0x1e, 0x8b, 0x97, 0x88, 0x94, + 0x80, 0xa0, 0x77, 0xb3, 0x87, 0x9a, 0x86, 0xb8, 0x08, 0x92, 0x90, 0x05, + 0xa8, 0x7c, 0x93, 0x84, 0x9f, 0x6f, 0xab, 0x5a, 0x9b, 0x7e, 0xa6, 0x8b, + 0xa7, 0x8b, 0xa0, 0xa1, 0x8b, 0xa7, 0x8b, 0xac, 0x78, 0x99, 0x55, 0x8f, + 0x5e, 0x8f, 0x7c, 0x8f, 0x67, 0x9c, 0x08, 0x93, 0x07, 0x0e, 0x42, 0xf7, + 0x85, 0xf7, 0xbd, 0x15, 0xfb, 0x64, 0x33, 0xf7, 0x64, 0xfb, 0x65, 0xe3, + 0xf7, 0x65, 0xf7, 0x64, 0xe3, 0xfb, 0x64, 0xf7, 0x65, 0x33, 0xfb, 0x65, + 0x06, 0x0e, 0xfc, 0x1d, 0xc4, 0xfb, 0x48, 0x15, 0xf7, 0x08, 0xce, 0xbd, + 0xcd, 0x8b, 0xe1, 0x08, 0xd0, 0x62, 0xba, 0x4f, 0x59, 0x6a, 0x6a, 0x59, + 0x1e, 0x5d, 0xa9, 0x6b, 0xb6, 0x1e, 0x90, 0x8b, 0x91, 0x8b, 0x91, 0x8c, + 0x08, 0x8e, 0x8c, 0x8d, 0x8b, 0x8d, 0x8b, 0x96, 0x8b, 0x93, 0x82, 0x8b, + 0x7e, 0x8b, 0x65, 0x69, 0x61, 0x40, 0x57, 0x08, 0x96, 0x75, 0x05, 0x0e, + 0xfb, 0xca, 0xf7, 0xb3, 0xf7, 0xb3, 0x15, 0xfb, 0x87, 0xfb, 0x08, 0xf7, + 0x87, 0xf7, 0x08, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, 0x11, 0xf7, 0x30, 0x15, + 0x5d, 0x65, 0x64, 0x5e, 0x5b, 0xaf, 0x66, 0xba, 0xbb, 0xb1, 0xb0, 0xb9, + 0xba, 0x65, 0xb2, 0x5c, 0x1f, 0x0e, 0xfc, 0x01, 0xf7, 0xc2, 0xf9, 0x47, + 0x15, 0x31, 0x8b, 0xfb, 0x80, 0xfd, 0x5a, 0xe5, 0x8b, 0xf7, 0x80, 0xf9, + 0x5a, 0x05, 0x0e, 0xf7, 0x8e, 0xf9, 0x44, 0x15, 0x4a, 0x8b, 0x49, 0x5f, + 0x62, 0x43, 0x6b, 0x54, 0x75, 0x2d, 0x8b, 0x38, 0x08, 0xfb, 0x62, 0xe9, + 0xfb, 0x27, 0xf7, 0x19, 0xf7, 0x15, 0xeb, 0xf7, 0x29, 0xf7, 0x5d, 0xf7, + 0x5c, 0x2a, 0xf7, 0x2b, 0xfb, 0x15, 0x1e, 0xcf, 0xfc, 0x66, 0x15, 0x8b, + 0x50, 0x83, 0x3d, 0x82, 0x70, 0x80, 0x6e, 0x7b, 0x7d, 0x74, 0x8b, 0x08, + 0x59, 0x78, 0xc6, 0xf7, 0x28, 0x1f, 0xf7, 0x79, 0x07, 0xf7, 0x2b, 0x9e, + 0xc5, 0xbb, 0xbc, 0x9f, 0x4d, 0xfb, 0x27, 0x1e, 0xfb, 0x79, 0x07, 0x0e, + 0xf7, 0xd1, 0xf9, 0x44, 0x15, 0xfb, 0x90, 0xfb, 0x01, 0x8b, 0x71, 0x05, + 0x94, 0x8e, 0x93, 0x8e, 0x8e, 0x8d, 0xa6, 0x95, 0xa4, 0x92, 0x98, 0x8b, + 0x08, 0xa4, 0x96, 0x75, 0x5c, 0x1f, 0xfc, 0x15, 0x07, 0x8b, 0x39, 0x77, + 0x7a, 0x28, 0x8a, 0x08, 0x73, 0xf8, 0x0b, 0xa3, 0x07, 0x30, 0x8d, 0x7a, + 0x9a, 0x8b, 0xd8, 0x08, 0xf8, 0xce, 0x7a, 0x07, 0x0e, 0xf8, 0x72, 0xf7, + 0x67, 0x15, 0x73, 0x06, 0x6e, 0x43, 0x7f, 0x85, 0x25, 0x8b, 0x08, 0xfb, + 0x2b, 0x8b, 0xf7, 0x36, 0xf7, 0x2e, 0x05, 0xda, 0xd6, 0xae, 0xce, 0x8b, + 0xd7, 0x8b, 0xf6, 0x3e, 0xd7, 0xfb, 0x00, 0x8b, 0x59, 0x8b, 0x5b, 0x77, + 0x68, 0x67, 0x64, 0x64, 0x77, 0x69, 0x6f, 0x40, 0x08, 0xa7, 0x06, 0xaa, + 0xc9, 0xb0, 0xa7, 0xc1, 0x8b, 0xb7, 0x8b, 0xac, 0x78, 0xa1, 0x67, 0x97, + 0x76, 0x93, 0x6f, 0x8b, 0x74, 0x8b, 0x5f, 0x78, 0x54, 0x6b, 0x5a, 0x58, + 0x3d, 0x68, 0x61, 0xfb, 0x26, 0xfb, 0x30, 0x08, 0x74, 0xf8, 0x34, 0x07, + 0xb8, 0xf7, 0x67, 0x05, 0x0e, 0xc5, 0xf8, 0x9f, 0x15, 0xb1, 0xc8, 0xac, + 0xa2, 0xbf, 0x8b, 0xca, 0x8b, 0xb2, 0x63, 0x8b, 0x4c, 0x8b, 0x49, 0x68, + 0x68, 0x2c, 0x6d, 0x08, 0x7a, 0x07, 0xde, 0x6e, 0xac, 0x7a, 0xaf, 0x69, + 0x08, 0xaa, 0x6e, 0x9d, 0x5e, 0x8b, 0x5b, 0x8b, 0x43, 0x65, 0x5d, 0x4f, + 0x8b, 0x73, 0x8b, 0x78, 0x96, 0x6a, 0xab, 0x64, 0xb2, 0x6d, 0x9b, 0x6d, + 0x8b, 0x08, 0x65, 0x70, 0x73, 0x69, 0x55, 0xc8, 0x67, 0xe7, 0xf7, 0x3b, + 0xf7, 0x18, 0xf7, 0x06, 0xf7, 0x26, 0x1f, 0x8b, 0xb9, 0x7c, 0xb6, 0x6e, + 0xae, 0x76, 0xa3, 0x7a, 0x97, 0x63, 0x9d, 0x08, 0xcb, 0xb2, 0x9e, 0xa8, + 0x8b, 0xc6, 0x8b, 0xe1, 0x4e, 0xbe, 0x25, 0x8b, 0x28, 0x8b, 0x40, 0x59, + 0x54, 0x24, 0x08, 0xa0, 0x7f, 0x05, 0x0e, 0xf8, 0x30, 0xf7, 0x93, 0x15, + 0xf8, 0x45, 0x3b, 0x07, 0x50, 0x3e, 0x05, 0xfb, 0x14, 0xfb, 0x3b, 0x49, + 0x2f, 0x4f, 0x2c, 0x08, 0xfb, 0x05, 0xf7, 0x8c, 0xfb, 0x24, 0x07, 0xf7, + 0x25, 0xf7, 0x24, 0xca, 0xf7, 0x03, 0x06, 0x4c, 0x06, 0xfb, 0x23, 0x16, + 0xfb, 0x65, 0x8b, 0xf7, 0x65, 0xf7, 0xbd, 0x05, 0xfb, 0xbd, 0x07, 0x0e, + 0xf7, 0x29, 0xf8, 0xb9, 0x15, 0xf7, 0xaa, 0x8b, 0xb6, 0xf7, 0x13, 0xfb, + 0xd6, 0x8b, 0x2a, 0xfb, 0xed, 0x05, 0xea, 0x84, 0xb4, 0x85, 0xb7, 0x7d, + 0xe4, 0x6f, 0xc0, 0x52, 0x8b, 0x49, 0x8b, 0x53, 0x5f, 0x5f, 0x53, 0x8b, + 0x74, 0x8b, 0x70, 0x97, 0x63, 0xa9, 0x60, 0xab, 0x6d, 0x98, 0x71, 0x8b, + 0x08, 0x67, 0x71, 0x72, 0x68, 0x56, 0xc5, 0x68, 0xe4, 0xf7, 0x39, 0xf7, + 0x09, 0xef, 0xf7, 0x21, 0x1f, 0x8b, 0xf3, 0x4b, 0xdb, 0xfb, 0x01, 0xaa, + 0x65, 0x96, 0x6c, 0x8f, 0x39, 0x90, 0x08, 0xa1, 0xdc, 0x05, 0x0e, 0xf8, + 0x6a, 0xf9, 0x44, 0x15, 0xfb, 0x19, 0x78, 0x4d, 0x75, 0x3f, 0x57, 0xfb, + 0x04, 0x3e, 0x50, 0xfb, 0x04, 0x8b, 0xfb, 0x19, 0x08, 0xfb, 0x41, 0xe7, + 0xfb, 0x05, 0xf7, 0x20, 0xf7, 0x10, 0xe6, 0xee, 0xf7, 0x1c, 0xf7, 0x0d, + 0x42, 0xd9, 0xfb, 0x06, 0x1e, 0x6b, 0x8b, 0x75, 0x87, 0x6d, 0x7e, 0xb0, + 0xf7, 0x27, 0xde, 0xdc, 0xf7, 0x26, 0xa9, 0x08, 0xa5, 0x07, 0xfb, 0x81, + 0xfb, 0xcc, 0x15, 0xce, 0xa2, 0x54, 0xfb, 0x33, 0xfb, 0x0a, 0x7f, 0x6d, + 0x5a, 0x1f, 0x74, 0x8b, 0x79, 0x95, 0x81, 0x9e, 0x7a, 0xac, 0x81, 0xd4, + 0x8b, 0xe8, 0x8b, 0xc9, 0x91, 0xc4, 0x92, 0x90, 0x93, 0x91, 0x99, 0x8f, + 0x99, 0x8b, 0x08, 0x0e, 0xf8, 0x71, 0xf9, 0x38, 0x15, 0xfc, 0x34, 0x8b, + 0x5f, 0xfb, 0x72, 0xa4, 0x8b, 0x05, 0x9e, 0xcb, 0xa3, 0xa0, 0xc2, 0x8b, + 0x08, 0xf7, 0x63, 0x8b, 0xfb, 0x5c, 0xfc, 0xaf, 0xea, 0x8b, 0xf7, 0x7f, + 0xf9, 0x38, 0x05, 0x0e, 0xf7, 0x46, 0xf7, 0xd8, 0x15, 0x52, 0x78, 0x74, + 0x7e, 0x71, 0x72, 0x6e, 0x6f, 0x7c, 0x65, 0x8b, 0x5f, 0x08, 0x25, 0xe0, + 0x47, 0xf7, 0x13, 0xf7, 0x1f, 0xe8, 0xdb, 0xf7, 0x0c, 0x1e, 0x8b, 0xe2, + 0x60, 0xc9, 0x20, 0xcf, 0x08, 0xeb, 0xad, 0xb3, 0xb4, 0x8b, 0xcb, 0x08, + 0xe4, 0x3f, 0xc3, 0xfb, 0x0b, 0xfb, 0x1b, 0x32, 0x45, 0x22, 0x1e, 0x8b, + 0x40, 0xb3, 0x54, 0xee, 0x50, 0x08, 0xf7, 0x0c, 0xed, 0x15, 0x37, 0xb6, + 0x5d, 0xc2, 0x8b, 0xc3, 0x08, 0xba, 0xaf, 0xaf, 0xba, 0xc3, 0xab, 0x5e, + 0x3d, 0x1e, 0x8b, 0x5c, 0x83, 0x74, 0x6a, 0x5f, 0x08, 0x29, 0xfb, 0x08, + 0x15, 0xf7, 0x01, 0x42, 0xa3, 0x6b, 0x8b, 0x41, 0x08, 0x48, 0x6a, 0x62, + 0x55, 0x4e, 0x67, 0xc0, 0xe4, 0x1e, 0x8b, 0xc2, 0x96, 0xaa, 0xb3, 0xc6, + 0x08, 0x0e, 0xaa, 0x7e, 0x15, 0xf7, 0x20, 0x9f, 0xcf, 0xa4, 0xd9, 0xc6, + 0xf1, 0xd8, 0xc1, 0xf6, 0x8b, 0xf7, 0x13, 0x08, 0xf7, 0x41, 0x2f, 0xf7, + 0x05, 0xfb, 0x20, 0xfb, 0x11, 0x31, 0x28, 0xfb, 0x1d, 0xfb, 0x0a, 0xd4, + 0x3b, 0xf7, 0x01, 0x1e, 0xb1, 0x8b, 0xa5, 0x90, 0xa6, 0x99, 0x60, 0xfb, + 0x2c, 0x3a, 0x3c, 0xfb, 0x24, 0x6e, 0x08, 0x71, 0x07, 0xf7, 0xaa, 0xf7, + 0xe9, 0x15, 0x8a, 0x7e, 0x8a, 0x86, 0x88, 0x89, 0x84, 0x86, 0x78, 0x87, + 0x7c, 0x8b, 0x08, 0x4d, 0x74, 0xc6, 0xf7, 0x31, 0xf7, 0x08, 0x97, 0xa9, + 0xbc, 0x1f, 0xa4, 0x8b, 0x9c, 0x80, 0x96, 0x74, 0x9a, 0x6f, 0x95, 0x45, + 0x8b, 0x44, 0x8b, 0x70, 0x89, 0x6b, 0x88, 0x5e, 0x08, 0x88, 0x71, 0x05, + 0x0e, 0xfb, 0xca, 0xf7, 0x3a, 0xf7, 0x30, 0x15, 0x5d, 0x65, 0x64, 0x5e, + 0x5b, 0xaf, 0x66, 0xba, 0xbb, 0xb1, 0xb0, 0xb9, 0xba, 0x65, 0xb2, 0x5c, + 0x1f, 0xf7, 0xd0, 0x04, 0x5d, 0x65, 0x65, 0x5e, 0x5a, 0xaf, 0x66, 0xbb, + 0xba, 0xb1, 0xb1, 0xb9, 0xba, 0x65, 0xb1, 0x5c, 0x1f, 0x0e, 0xfb, 0xca, + 0xef, 0xfb, 0x48, 0x15, 0xf7, 0x08, 0xce, 0xbd, 0xcd, 0x8b, 0xe1, 0x08, + 0xd0, 0x62, 0xba, 0x4f, 0x59, 0x6a, 0x6a, 0x59, 0x1e, 0x8b, 0x71, 0x94, + 0x76, 0x9c, 0x7d, 0x95, 0x82, 0xa2, 0x83, 0x97, 0x8b, 0x08, 0x93, 0x8b, + 0x97, 0x8d, 0x92, 0x8b, 0x05, 0x95, 0x93, 0x81, 0x80, 0x1f, 0x8b, 0x64, + 0x69, 0x61, 0x40, 0x57, 0x08, 0x96, 0x75, 0x05, 0xcd, 0xf9, 0x20, 0x15, + 0x5d, 0x65, 0x65, 0x5e, 0x5a, 0xaf, 0x66, 0xbb, 0xba, 0xb1, 0xb1, 0xb9, + 0x1f, 0xba, 0x65, 0xb1, 0x5c, 0x1e, 0x0e, 0x42, 0xf8, 0xaf, 0x7f, 0x15, + 0x8b, 0xeb, 0xfc, 0x15, 0xf7, 0x3d, 0xf8, 0x15, 0xf7, 0x3d, 0x8b, 0xeb, + 0xfc, 0x90, 0xfb, 0x73, 0x8b, 0x37, 0xf8, 0x90, 0xfb, 0x73, 0x05, 0x0e, + 0x42, 0xf8, 0xad, 0xf8, 0x23, 0x15, 0xfc, 0x8c, 0x33, 0xf8, 0x8c, 0xe3, + 0x06, 0xfb, 0x60, 0x04, 0xfc, 0x8c, 0x33, 0xf8, 0x8c, 0xe3, 0x06, 0x0e, + 0x42, 0xaa, 0x7f, 0x15, 0xf8, 0x90, 0xf7, 0x73, 0x8b, 0xdf, 0xfc, 0x90, + 0xf7, 0x73, 0x8b, 0x2b, 0xf8, 0x15, 0xfb, 0x3d, 0xfc, 0x15, 0xfb, 0x3d, + 0x8b, 0x2b, 0x05, 0x0e, 0xf7, 0x91, 0xf7, 0x7b, 0x15, 0x8b, 0xd4, 0x93, + 0x99, 0xca, 0xb2, 0xe6, 0xc3, 0xa9, 0xb4, 0x8b, 0xd0, 0x08, 0xef, 0x3b, + 0xcd, 0xfb, 0x0c, 0xfb, 0x02, 0x3d, 0x4f, 0x37, 0x5f, 0xa8, 0x6b, 0xb2, + 0xb1, 0xa4, 0xa5, 0xb1, 0x1e, 0x8b, 0x9f, 0x86, 0x97, 0x7a, 0x9e, 0x7f, + 0x98, 0x88, 0x91, 0x8b, 0x95, 0x08, 0xa3, 0xa4, 0x9b, 0xaf, 0xc0, 0xaa, + 0x5b, 0x39, 0x1e, 0x8b, 0x57, 0x81, 0x68, 0x6a, 0x4d, 0x73, 0x5d, 0x83, + 0x74, 0x8b, 0x6f, 0x8b, 0x80, 0x8b, 0x86, 0x8d, 0x6d, 0x08, 0xa9, 0x06, + 0x7d, 0x40, 0x15, 0x5d, 0x64, 0x64, 0x5e, 0x5b, 0xb0, 0x66, 0xbb, 0xba, + 0xb0, 0xb0, 0xba, 0x1f, 0xb9, 0x65, 0xb2, 0x5d, 0x1e, 0x0e, 0xf7, 0xb3, + 0xf8, 0xe7, 0xf8, 0x66, 0x15, 0x75, 0xb6, 0x7c, 0x95, 0x67, 0x8b, 0x5f, + 0x8b, 0x60, 0x78, 0x6b, 0x6a, 0x57, 0x54, 0x6b, 0x3c, 0x8b, 0x41, 0x8b, + 0x4a, 0xb4, 0x59, 0xc0, 0x8b, 0xb6, 0x8b, 0xbb, 0xa7, 0xae, 0xb9, 0x08, + 0x92, 0x5e, 0xb0, 0x6d, 0xbd, 0x8b, 0x08, 0xf1, 0xe2, 0xf7, 0x06, 0xf7, + 0x19, 0xf7, 0x3e, 0xfb, 0x27, 0xf7, 0x17, 0xfb, 0x52, 0xfb, 0x66, 0xfb, + 0x3b, 0xfb, 0x34, 0xfb, 0x5d, 0xfb, 0x58, 0xf7, 0x3a, 0xfb, 0x2d, 0xf7, + 0x69, 0x1f, 0xd5, 0x8b, 0xc0, 0x99, 0xec, 0xb9, 0x08, 0x7e, 0xae, 0x05, + 0x39, 0x66, 0x59, 0x7f, 0x48, 0x8b, 0x08, 0xfb, 0x43, 0xfb, 0x10, 0xf7, + 0x10, 0xf7, 0x42, 0xf7, 0x52, 0xf7, 0x0c, 0xf7, 0x1d, 0xf7, 0x3a, 0xf7, + 0x30, 0xf7, 0x19, 0xfb, 0x0f, 0xfb, 0x24, 0x21, 0x4d, 0x28, 0x49, 0x72, + 0x7e, 0x9c, 0xaa, 0x1f, 0x8b, 0x91, 0x8c, 0x92, 0x8c, 0x90, 0x08, 0xcd, + 0xf7, 0x98, 0x44, 0x8b, 0x05, 0x80, 0x63, 0x05, 0x4f, 0x90, 0x15, 0xa8, + 0x89, 0x9a, 0x73, 0x89, 0x64, 0x89, 0x5e, 0x7a, 0x4e, 0x76, 0x62, 0x75, + 0x60, 0x6d, 0x72, 0x6d, 0x8b, 0x67, 0x8b, 0x74, 0xac, 0x8b, 0xc0, 0x8b, + 0xc1, 0x9d, 0xbe, 0xad, 0xb1, 0x08, 0xa7, 0xac, 0xad, 0x9f, 0xa4, 0x89, + 0x08, 0x0e, 0xda, 0xf9, 0x45, 0xa4, 0x15, 0x87, 0x06, 0x64, 0x8b, 0x7b, + 0xa0, 0x59, 0xf7, 0x0a, 0x08, 0xfb, 0x73, 0xf8, 0xa2, 0x6f, 0x8b, 0xfb, + 0x72, 0xfc, 0xb8, 0x05, 0x65, 0x2e, 0x7f, 0x7c, 0x5b, 0x82, 0x08, 0x72, + 0xf7, 0x5f, 0xa4, 0x07, 0x50, 0x8f, 0x74, 0x96, 0x8b, 0xa5, 0x8b, 0x98, + 0x93, 0xa4, 0xa0, 0xc1, 0x08, 0x9a, 0xb2, 0xf7, 0x75, 0x8b, 0x05, 0xad, + 0x3d, 0x97, 0x67, 0x8b, 0x75, 0x8b, 0x76, 0x7e, 0x81, 0x68, 0x89, 0x86, + 0x8b, 0x7e, 0x8a, 0x7d, 0x89, 0x08, 0x72, 0xf7, 0xd8, 0xa4, 0x07, 0xfc, + 0x88, 0xf7, 0x67, 0x15, 0xe9, 0xf7, 0x87, 0xf0, 0xfb, 0x87, 0xfb, 0x57, + 0x8b, 0x05, 0x0e, 0xa3, 0x9b, 0xf9, 0x38, 0x15, 0x72, 0x07, 0xd0, 0x87, + 0x9e, 0x7b, 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x58, 0x7c, 0x7f, + 0x42, 0x83, 0x08, 0x72, 0xf7, 0xd6, 0x07, 0xf7, 0x3d, 0xf7, 0x04, 0xd6, + 0xf7, 0x05, 0x1f, 0x8b, 0xb8, 0x78, 0xb4, 0x68, 0xaa, 0x68, 0xa9, 0x69, + 0x9a, 0x45, 0x9a, 0x08, 0xf7, 0x08, 0xad, 0xb6, 0xb4, 0x8b, 0xd7, 0x08, + 0xf2, 0x2e, 0xc4, 0xfb, 0x3b, 0x1e, 0xfb, 0xc9, 0x06, 0xf7, 0x8c, 0xfb, + 0xe1, 0x15, 0xa9, 0x06, 0xf2, 0xbd, 0x55, 0xfb, 0x02, 0x2a, 0x62, 0x59, + 0x3a, 0x5f, 0x7a, 0x9c, 0xb7, 0x1f, 0xf7, 0x8e, 0x07, 0xf7, 0x92, 0x04, + 0xaf, 0x9a, 0x98, 0xb2, 0x1e, 0xd1, 0xab, 0x60, 0x2d, 0x1f, 0x8b, 0x22, + 0x6a, 0x6f, 0xfb, 0x0f, 0x88, 0x08, 0xf7, 0x74, 0x07, 0x0e, 0xda, 0xf9, + 0x25, 0xf7, 0x2c, 0x15, 0x50, 0x4d, 0x6b, 0x73, 0x5a, 0x78, 0x6e, 0x7f, + 0x6a, 0x85, 0x6f, 0x8b, 0x49, 0x8b, 0x4c, 0xae, 0x6e, 0xbf, 0x6e, 0xc0, + 0x7d, 0xd3, 0x8b, 0xef, 0x8b, 0xf7, 0x63, 0xcb, 0xf7, 0x02, 0xf7, 0x0c, + 0x8b, 0xba, 0x8b, 0xb6, 0x79, 0xb6, 0x65, 0x08, 0xb6, 0x64, 0xa2, 0x6a, + 0xae, 0x3f, 0x08, 0xa4, 0xf7, 0x7e, 0x70, 0x06, 0x7d, 0x68, 0x80, 0x80, + 0x78, 0x8b, 0x82, 0x8b, 0x7c, 0x8f, 0x75, 0x95, 0x50, 0xa3, 0x5b, 0x96, + 0x5b, 0x8b, 0x08, 0xfb, 0x5b, 0xfb, 0x29, 0xfb, 0x2e, 0xfb, 0x60, 0xfb, + 0x62, 0xf7, 0x27, 0xfb, 0x26, 0xf7, 0x63, 0x1f, 0xd2, 0x8b, 0xc6, 0x9c, + 0xc2, 0xb0, 0xab, 0xa1, 0xa1, 0x9f, 0xb8, 0xbd, 0x08, 0x6d, 0xa4, 0x05, + 0x0e, 0xda, 0xec, 0xe6, 0x15, 0x8b, 0x5f, 0x72, 0x77, 0x51, 0x89, 0x08, + 0x72, 0xf7, 0xd0, 0x07, 0xf7, 0x6c, 0xf7, 0x24, 0xf7, 0x1e, 0xf7, 0x63, + 0xf7, 0x62, 0xfb, 0x20, 0xf7, 0x11, 0xfb, 0x7b, 0x1f, 0xfb, 0xc5, 0x06, + 0x72, 0x07, 0xcb, 0x85, 0x9e, 0x7c, 0x8b, 0x5d, 0x08, 0xfc, 0x81, 0x07, + 0xf7, 0x36, 0xf8, 0x98, 0x15, 0xa2, 0x9f, 0x97, 0xb2, 0x1e, 0xd3, 0x8b, + 0xbe, 0x6a, 0xad, 0x46, 0xa6, 0x56, 0x99, 0x42, 0x8b, 0x37, 0x8b, 0x2c, + 0x77, 0x35, 0x6b, 0x5e, 0x69, 0x5d, 0x5b, 0x74, 0x4a, 0x8b, 0x08, 0x5e, + 0x7e, 0x98, 0xb8, 0x1f, 0xf8, 0x96, 0x07, 0x0e, 0xa3, 0xf8, 0xe5, 0xf9, + 0x38, 0x15, 0xfc, 0xd5, 0x06, 0x72, 0x07, 0xd0, 0x87, 0x9e, 0x7b, 0x8b, + 0x58, 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x57, 0x7d, 0x80, 0x41, 0x83, 0x08, + 0x72, 0xf8, 0xdd, 0x07, 0xb3, 0xf7, 0x64, 0x6f, 0x8b, 0x05, 0x6c, 0x48, + 0x77, 0x6f, 0x67, 0x6e, 0x5d, 0x66, 0x54, 0x7b, 0x3f, 0x8b, 0x08, 0x4b, + 0x78, 0x98, 0xb6, 0x1f, 0xf7, 0x86, 0x07, 0xf7, 0x01, 0x8b, 0xb4, 0x64, + 0x97, 0xfb, 0x08, 0x08, 0xa5, 0xf7, 0xe6, 0x71, 0x06, 0x7c, 0xfb, 0x06, + 0x64, 0x67, 0xfb, 0x00, 0x8c, 0x08, 0xf7, 0x7c, 0x07, 0xb1, 0x98, 0x94, + 0xbf, 0x1e, 0xf7, 0x37, 0x8b, 0xbc, 0x69, 0xa4, 0xfb, 0x19, 0x08, 0xa4, + 0x06, 0xf7, 0x5d, 0x07, 0x0e, 0x6b, 0xf8, 0xdb, 0xf9, 0x38, 0x15, 0xfc, + 0xcb, 0x06, 0x72, 0x07, 0xd0, 0x87, 0x9e, 0x7c, 0x8b, 0x57, 0x08, 0xfc, + 0x78, 0x07, 0x8b, 0x57, 0x7d, 0x80, 0x41, 0x83, 0x08, 0x72, 0xf7, 0xfc, + 0xa4, 0x07, 0x2f, 0x8f, 0x79, 0x97, 0x8b, 0xc2, 0x08, 0xf7, 0x7d, 0x07, + 0xf1, 0x89, 0xb0, 0x66, 0x99, 0xfb, 0x08, 0x08, 0xa4, 0xf7, 0xe6, 0x72, + 0x06, 0x79, 0xfb, 0x06, 0x68, 0x68, 0x27, 0x8b, 0x08, 0xf7, 0x7c, 0x07, + 0xb0, 0x98, 0x95, 0xbe, 0x1e, 0xe7, 0x8b, 0xc6, 0x7a, 0xaa, 0x68, 0xa1, + 0x72, 0x96, 0x70, 0x99, 0x4c, 0x08, 0xa3, 0x06, 0xf7, 0x5d, 0x07, 0x0e, + 0xf7, 0x1b, 0xf9, 0x87, 0xf7, 0xb3, 0x15, 0xfb, 0xeb, 0x72, 0x06, 0xe1, + 0x86, 0x9a, 0x80, 0x8b, 0x55, 0x08, 0x22, 0x07, 0x58, 0x6e, 0x75, 0x48, + 0x1e, 0x4c, 0x8b, 0x61, 0x9e, 0x6a, 0xb6, 0x5f, 0xc3, 0x76, 0xe1, 0x8b, + 0xf7, 0x0c, 0x8b, 0xf7, 0x65, 0xca, 0xf7, 0x03, 0xf7, 0x0d, 0x8b, 0xb9, + 0x8b, 0xb6, 0x79, 0xb7, 0x65, 0xb6, 0x65, 0xa2, 0x69, 0xae, 0x3f, 0x08, + 0xa4, 0xf7, 0x7e, 0x70, 0x06, 0x7d, 0x68, 0x80, 0x80, 0x78, 0x8b, 0x82, + 0x8b, 0x7c, 0x8f, 0x75, 0x95, 0x50, 0xa3, 0x5b, 0x96, 0x5b, 0x8b, 0x08, + 0xfb, 0x5b, 0xfb, 0x29, 0xfb, 0x2e, 0xfb, 0x62, 0xfb, 0x62, 0xf7, 0x26, + 0xfb, 0x24, 0xf7, 0x66, 0x1f, 0xf2, 0x8b, 0xf7, 0x01, 0xa3, 0xcb, 0xb1, + 0x08, 0xf7, 0x13, 0x07, 0x8b, 0xd3, 0x96, 0x97, 0xd6, 0x93, 0x08, 0xa4, + 0x07, 0x0e, 0xf7, 0x1b, 0xf8, 0x91, 0xf7, 0xda, 0x15, 0xfb, 0x7a, 0x07, + 0x8b, 0x5a, 0x7a, 0x7d, 0x42, 0x83, 0x08, 0x72, 0xf7, 0xe8, 0xa4, 0x07, + 0x43, 0x94, 0x7b, 0x98, 0x8b, 0xbc, 0x08, 0xf8, 0x78, 0x07, 0x8b, 0xbd, + 0x9f, 0x9b, 0xcf, 0x90, 0x08, 0xa4, 0xfb, 0xe8, 0x72, 0x07, 0xd1, 0x86, + 0x9f, 0x7b, 0x8b, 0x59, 0x08, 0xfb, 0x63, 0xfb, 0x85, 0xf7, 0x63, 0x07, + 0x8b, 0xbd, 0x9f, 0x9b, 0xd1, 0x90, 0x08, 0xa4, 0xfb, 0xe5, 0x72, 0x07, + 0xce, 0x85, 0x9d, 0x7c, 0x8b, 0x59, 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x5a, + 0x7c, 0x7e, 0x45, 0x82, 0x08, 0x72, 0xf7, 0xe5, 0xa4, 0x07, 0x42, 0x93, + 0x7a, 0x99, 0x8b, 0xbc, 0x08, 0xf7, 0x7a, 0xf7, 0x85, 0x07, 0x0e, 0xfb, + 0x92, 0xf7, 0x05, 0xeb, 0x15, 0x8b, 0x59, 0x79, 0x7d, 0x40, 0x84, 0x08, + 0x72, 0xf7, 0xf2, 0xa4, 0x07, 0x3f, 0x90, 0x78, 0x99, 0x8b, 0xbf, 0x08, + 0xf8, 0x78, 0x07, 0x8b, 0xbf, 0xa0, 0x9b, 0xd5, 0x8e, 0x08, 0xa4, 0xfb, + 0xf2, 0x72, 0x07, 0xd3, 0x86, 0xa0, 0x7c, 0x8b, 0x58, 0x08, 0xfc, 0x78, + 0x07, 0x0e, 0xf8, 0x1a, 0xf8, 0xc3, 0x15, 0x8b, 0xd3, 0x99, 0x9a, 0xd6, + 0x90, 0x08, 0xa4, 0xfb, 0xf4, 0x72, 0x07, 0xdc, 0x88, 0x9f, 0x7d, 0x8b, + 0x55, 0x08, 0xfc, 0xc0, 0x07, 0x4d, 0x78, 0x72, 0x5e, 0x70, 0x79, 0x98, + 0x9e, 0x1e, 0x8b, 0x93, 0x8e, 0x91, 0x94, 0x97, 0x97, 0x9a, 0x8e, 0x93, + 0x8b, 0x9a, 0x08, 0xb3, 0x69, 0xae, 0x64, 0x66, 0x6a, 0x69, 0x65, 0x1e, + 0x8b, 0x62, 0xa7, 0x5e, 0xb2, 0x74, 0xa5, 0x7d, 0xb3, 0x82, 0xb3, 0x8b, + 0x08, 0xf7, 0x20, 0xd5, 0xd7, 0xf7, 0x23, 0x1f, 0xf8, 0x48, 0x07, 0x0e, + 0xf7, 0x1b, 0xf9, 0x95, 0xa4, 0x15, 0x72, 0x8c, 0x80, 0x90, 0x7e, 0x9a, + 0x08, 0xfb, 0xc5, 0xf8, 0x0e, 0x05, 0xf7, 0x50, 0xf7, 0x56, 0xaf, 0xa4, + 0xec, 0x93, 0x08, 0xa4, 0xfb, 0xb5, 0x72, 0x07, 0x9c, 0x8a, 0x99, 0x8a, + 0x90, 0x8a, 0xaf, 0x89, 0x98, 0x83, 0x8b, 0x77, 0x8b, 0x7b, 0x86, 0x83, + 0x6c, 0x6c, 0x08, 0xfb, 0x6d, 0xfb, 0x6e, 0x8b, 0xf7, 0x6a, 0x05, 0x8b, + 0xd2, 0x9a, 0x9b, 0xd5, 0x90, 0x08, 0xa4, 0xfb, 0xe6, 0x72, 0x07, 0xd0, + 0x87, 0x9d, 0x7c, 0x8b, 0x57, 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x58, 0x7c, + 0x7f, 0x43, 0x83, 0x08, 0x72, 0xf7, 0xe5, 0xa4, 0x07, 0x43, 0x94, 0x7b, + 0x98, 0x8b, 0xbc, 0x08, 0x8b, 0xf7, 0x58, 0xa6, 0xa4, 0xf7, 0x4a, 0xfb, + 0x77, 0x05, 0x9e, 0x73, 0x90, 0x82, 0x8b, 0x80, 0x8b, 0x7e, 0x7d, 0x86, + 0x6a, 0x89, 0x86, 0x8b, 0x7e, 0x8b, 0x7d, 0x8a, 0x08, 0x72, 0xf7, 0xe4, + 0xa4, 0x07, 0x0e, 0xa3, 0xf9, 0x12, 0xf7, 0x77, 0x15, 0x6e, 0x06, 0x6a, + 0x3d, 0x77, 0x6c, 0x68, 0x6b, 0x62, 0x66, 0x53, 0x79, 0x3e, 0x8b, 0x08, + 0x4e, 0x78, 0x98, 0xb6, 0x1f, 0xf8, 0x6c, 0x07, 0x8b, 0xd6, 0x99, 0x98, + 0xe2, 0x8f, 0x08, 0xa4, 0xfb, 0xf1, 0x72, 0x07, 0xcf, 0x87, 0x9d, 0x7b, + 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x58, 0x7e, 0x80, 0x42, 0x82, + 0x08, 0x72, 0xf8, 0xd6, 0x07, 0xb4, 0xf7, 0x77, 0x05, 0x0e, 0xf7, 0xc1, + 0xf9, 0x3a, 0xf8, 0xf5, 0x15, 0xfc, 0x91, 0x07, 0x8b, 0x53, 0x7d, 0x7f, + 0x40, 0x84, 0x08, 0x72, 0xf7, 0xe0, 0xa4, 0x07, 0x3d, 0x95, 0x81, 0x96, + 0x8b, 0xd2, 0x08, 0xf8, 0x4e, 0x07, 0x8b, 0xd3, 0x9a, 0x9a, 0xd4, 0x90, + 0x08, 0xa4, 0xfb, 0x90, 0x07, 0xfb, 0x5c, 0xfc, 0x6c, 0xfb, 0x5c, 0xf8, + 0x6c, 0xfb, 0x91, 0x8b, 0x8b, 0x72, 0x05, 0xd4, 0x85, 0x9b, 0x7e, 0x8b, + 0x57, 0x08, 0xfc, 0x6f, 0x07, 0x8b, 0x4f, 0x7e, 0x7f, 0x3d, 0x83, 0x08, + 0x72, 0xf7, 0x7e, 0xa4, 0x07, 0x39, 0x91, 0x78, 0x9e, 0x8b, 0xd5, 0x08, + 0x8b, 0xf8, 0x6a, 0xf7, 0x90, 0xfc, 0xe6, 0xa6, 0x8b, 0xf7, 0x90, 0xf8, + 0xf5, 0x05, 0x0e, 0xda, 0xf7, 0x7a, 0xf9, 0x38, 0x15, 0xfb, 0x67, 0x72, + 0x06, 0x9f, 0x8b, 0x9c, 0x7c, 0xbb, 0x52, 0x08, 0xfc, 0x6e, 0x07, 0x8b, + 0x52, 0x7c, 0x7d, 0x42, 0x82, 0x08, 0x72, 0xf7, 0x77, 0xa4, 0x07, 0x3e, + 0x94, 0x79, 0x9e, 0x8b, 0xd2, 0x08, 0x8b, 0xf8, 0x26, 0x05, 0xf8, 0x53, + 0xfc, 0xb4, 0xa7, 0x8b, 0x8b, 0xf8, 0xe1, 0x05, 0x8b, 0xc4, 0x98, 0x98, + 0xcc, 0x95, 0x08, 0xa4, 0xfb, 0x6b, 0x72, 0x07, 0xd5, 0x84, 0x9e, 0x76, + 0x8b, 0x44, 0x08, 0x8b, 0xfb, 0xc5, 0x05, 0xfb, 0xf1, 0xf8, 0x41, 0x05, + 0x0e, 0xf7, 0x1b, 0xf8, 0x1d, 0xf9, 0x47, 0x15, 0xfb, 0x65, 0xfb, 0x29, + 0xfb, 0x28, 0xfb, 0x64, 0xfb, 0x63, 0xf7, 0x27, 0xfb, 0x27, 0xf7, 0x63, + 0xf7, 0x63, 0xf7, 0x27, 0xf7, 0x28, 0xf7, 0x63, 0xf7, 0x60, 0xfb, 0x29, + 0xf7, 0x2b, 0xfb, 0x5d, 0x1f, 0x8a, 0x6a, 0x15, 0xf7, 0x02, 0xcb, 0xfb, + 0x0d, 0xfb, 0x64, 0xfb, 0x61, 0x4d, 0xfb, 0x02, 0xfb, 0x07, 0xfb, 0x07, + 0x4d, 0xf7, 0x02, 0xf7, 0x5e, 0xf7, 0x6c, 0xca, 0xf7, 0x08, 0xf7, 0x09, + 0x1f, 0x0e, 0x6b, 0xf7, 0x9a, 0xf7, 0xc3, 0x15, 0xf7, 0x1b, 0x8c, 0xad, + 0x8e, 0xb7, 0x9d, 0xdc, 0xaa, 0xb7, 0xc8, 0x8b, 0xd8, 0x08, 0xf7, 0x08, + 0x2c, 0xcd, 0xfb, 0x3b, 0x1e, 0xfb, 0xd6, 0x06, 0x72, 0x07, 0xd1, 0x85, + 0x99, 0x7b, 0x8b, 0x45, 0x08, 0xfc, 0x4e, 0x07, 0x8b, 0x4d, 0x7e, 0x77, + 0x5c, 0x85, 0x88, 0x8b, 0x81, 0x89, 0x80, 0x89, 0x08, 0x72, 0xf7, 0xe2, + 0xa4, 0x07, 0x3c, 0x95, 0x82, 0x94, 0x8b, 0xd4, 0x08, 0xf7, 0x4e, 0x07, + 0xf7, 0xc3, 0x04, 0xa2, 0x9c, 0x97, 0xac, 0xde, 0xac, 0x5f, 0xfb, 0x00, + 0x1e, 0x8b, 0x4c, 0x7f, 0x65, 0x71, 0x74, 0x73, 0x77, 0x6a, 0x84, 0x44, + 0x8b, 0x08, 0xf7, 0xa0, 0x07, 0x0e, 0xf7, 0x1b, 0xf9, 0x6e, 0xfb, 0x09, + 0x15, 0x6b, 0x82, 0x7b, 0x88, 0x78, 0x8b, 0x5c, 0x8b, 0x5e, 0x9d, 0x69, + 0xad, 0x78, 0x9e, 0x81, 0x9a, 0x79, 0xb0, 0xdc, 0xa5, 0xae, 0x9f, 0xb6, + 0xb9, 0xc8, 0xcc, 0xac, 0xe1, 0x8b, 0xec, 0x08, 0xf7, 0x64, 0xfb, 0x28, + 0xf7, 0x29, 0xfb, 0x62, 0xfb, 0x60, 0xfb, 0x2a, 0xfb, 0x2c, 0xfb, 0x64, + 0x1e, 0x8b, 0x30, 0xaa, 0x37, 0xc5, 0x4b, 0xb4, 0x5d, 0xab, 0x77, 0xd7, + 0x6f, 0xa0, 0x5f, 0x97, 0x78, 0xa2, 0x74, 0xc3, 0x53, 0xdf, 0x6b, 0xe3, + 0x8b, 0xc8, 0x8b, 0xb6, 0x93, 0xd6, 0xa6, 0x08, 0x85, 0xa3, 0x05, 0xfb, + 0xe8, 0xf9, 0x9b, 0x15, 0xf7, 0x04, 0xcb, 0xfb, 0x0c, 0xfb, 0x64, 0xfb, + 0x62, 0x4d, 0xfb, 0x02, 0xfb, 0x07, 0xfb, 0x08, 0x4e, 0xf7, 0x01, 0xf7, + 0x64, 0xf7, 0x66, 0xcb, 0xf7, 0x09, 0xf7, 0x06, 0x1f, 0x0e, 0xda, 0xf9, + 0x5f, 0xa4, 0x15, 0x79, 0x8b, 0x7e, 0x91, 0x81, 0x98, 0x08, 0xfb, 0x5d, + 0xf7, 0xb1, 0x05, 0xc6, 0x9e, 0xa4, 0x98, 0xa7, 0xa4, 0xa8, 0xa6, 0x9b, + 0xb3, 0x8b, 0xb8, 0x08, 0xf7, 0x07, 0x28, 0xca, 0xfb, 0x4b, 0x1e, 0xfb, + 0xd6, 0x06, 0x72, 0x07, 0xd5, 0x86, 0x99, 0x7c, 0x8b, 0x43, 0x08, 0xfc, + 0x4e, 0x07, 0x8b, 0x42, 0x81, 0x81, 0x3d, 0x82, 0x08, 0x72, 0xf7, 0xe6, + 0xa4, 0x07, 0x3d, 0x95, 0x81, 0x96, 0x8b, 0xd2, 0x08, 0xf7, 0x58, 0xa6, + 0x07, 0xf7, 0x63, 0xfb, 0xcd, 0xf7, 0x61, 0x8b, 0x05, 0xa4, 0x07, 0xfc, + 0x4b, 0xf8, 0xd3, 0x15, 0x8b, 0x91, 0x8f, 0x9a, 0x8e, 0x91, 0x91, 0x95, + 0x9b, 0x90, 0xa4, 0x8b, 0xe7, 0x8b, 0xb0, 0x60, 0x8b, 0x22, 0x8b, 0x4b, + 0x7c, 0x64, 0x6b, 0x76, 0x71, 0x7a, 0x69, 0x84, 0x3f, 0x8a, 0x08, 0xf7, + 0x93, 0x07, 0x0e, 0x34, 0xf8, 0x78, 0xf8, 0x6f, 0x15, 0xf7, 0x6d, 0x6d, + 0x07, 0x84, 0x71, 0x83, 0x83, 0x7a, 0x8b, 0x82, 0x8b, 0x80, 0x8e, 0x75, + 0x93, 0x08, 0x5c, 0x9b, 0x6b, 0x91, 0x65, 0x8b, 0xfb, 0x1c, 0x8b, 0x38, + 0x3e, 0x8b, 0xfb, 0x12, 0x8b, 0x33, 0xbf, 0x4c, 0xf7, 0x0b, 0x52, 0x08, + 0xce, 0x6b, 0x05, 0xe3, 0x61, 0xa3, 0x71, 0x8b, 0x57, 0x8b, 0x46, 0x5a, + 0x5e, 0x3e, 0x8b, 0x51, 0x8b, 0x59, 0xa4, 0x65, 0xbc, 0x70, 0xb0, 0x7d, + 0xac, 0x7a, 0xd1, 0x08, 0x6e, 0xfb, 0x8b, 0xa8, 0x06, 0x91, 0xa4, 0x93, + 0x94, 0x9b, 0x8b, 0x93, 0x8b, 0x96, 0x88, 0xa1, 0x84, 0xbd, 0x7a, 0xb0, + 0x84, 0xb6, 0x8b, 0xf7, 0x28, 0x8b, 0xef, 0xe0, 0x8b, 0xf7, 0x12, 0x8b, + 0xd6, 0x5d, 0xd6, 0x4b, 0xab, 0x08, 0xfb, 0x27, 0xd4, 0x05, 0x3a, 0xb3, + 0x75, 0xa4, 0x8b, 0xbb, 0x8b, 0xc9, 0xb5, 0xb1, 0xcf, 0x8b, 0xb8, 0x8b, + 0xb5, 0x78, 0xaf, 0x66, 0xad, 0x68, 0x9b, 0x6e, 0x9f, 0x4a, 0x08, 0xa7, + 0x06, 0x0e, 0xa3, 0xf7, 0x91, 0xf7, 0x09, 0x15, 0x8b, 0x41, 0x80, 0x80, + 0x35, 0x84, 0x08, 0x72, 0xf7, 0xf9, 0xa4, 0x07, 0x34, 0x91, 0x80, 0x95, + 0x8b, 0xd7, 0x08, 0xf8, 0xa3, 0x07, 0xf7, 0x0f, 0x87, 0xbf, 0x5d, 0x9c, + 0xfb, 0x0b, 0x08, 0xa8, 0x8b, 0x89, 0xf7, 0x5d, 0xfc, 0xec, 0x8b, 0x88, + 0xfb, 0x5d, 0xa8, 0x8b, 0x05, 0x9c, 0xf7, 0x0b, 0xbf, 0xb9, 0xf7, 0x10, + 0x8f, 0x08, 0xfc, 0xa3, 0x07, 0x0e, 0xda, 0xf9, 0x03, 0xf8, 0xca, 0x15, + 0x8b, 0xc6, 0x99, 0x9b, 0xcb, 0x95, 0x08, 0xa4, 0xfb, 0x70, 0x72, 0x07, + 0xd9, 0x85, 0x9f, 0x77, 0x8b, 0x42, 0x08, 0xfb, 0xc5, 0x07, 0xfb, 0x28, + 0x53, 0x46, 0xfb, 0x0b, 0x25, 0x5e, 0xc6, 0xf7, 0x1c, 0x1e, 0xf7, 0xe2, + 0x07, 0x8b, 0xb3, 0x91, 0xa1, 0x9a, 0x99, 0x97, 0x95, 0x9b, 0x8f, 0xbb, + 0x8d, 0x08, 0xa4, 0xfb, 0xe6, 0x72, 0x07, 0xd1, 0x84, 0x97, 0x7e, 0x8b, + 0x43, 0x08, 0xfb, 0xe2, 0x07, 0x8b, 0x29, 0xa0, 0x5a, 0xc8, 0x5f, 0xbb, + 0x68, 0xcb, 0x79, 0xd4, 0x8b, 0xd5, 0x8b, 0xd1, 0xa1, 0xb6, 0xb0, 0xb8, + 0xb1, 0xa5, 0xd7, 0x8b, 0xe8, 0x08, 0xf7, 0xd3, 0x07, 0x0e, 0xda, 0xf9, + 0x51, 0xf9, 0x38, 0x15, 0xfb, 0x69, 0x72, 0x06, 0xd2, 0x86, 0x9a, 0x84, + 0x8b, 0x6b, 0x8b, 0x7b, 0x88, 0x7f, 0x7a, 0x60, 0x08, 0xfb, 0x13, 0xfb, + 0xdd, 0xfb, 0x1e, 0xf7, 0xe2, 0x05, 0x78, 0xb8, 0x87, 0x97, 0x8b, 0x9a, + 0x8b, 0xa2, 0x9a, 0x96, 0xb1, 0x8d, 0x90, 0x8b, 0x98, 0x8c, 0x9a, 0x8c, + 0x08, 0xa4, 0xfb, 0xe4, 0x72, 0x07, 0xbd, 0x84, 0x94, 0x83, 0xa4, 0x54, + 0x08, 0xf7, 0x94, 0xfc, 0xeb, 0xa6, 0x8b, 0xf7, 0x78, 0xf8, 0xdf, 0x05, + 0xa3, 0xc9, 0x99, 0x98, 0xbf, 0x92, 0x08, 0xa4, 0x07, 0x0e, 0xf7, 0xf9, + 0xfa, 0x69, 0xf9, 0x38, 0x15, 0xfb, 0x4a, 0x72, 0x06, 0xc1, 0x88, 0x9a, + 0x81, 0x8b, 0x6c, 0x8b, 0x7e, 0x89, 0x7c, 0x86, 0x7d, 0x08, 0xfb, 0x04, + 0xfb, 0xeb, 0xfb, 0x00, 0xf7, 0xe4, 0x05, 0x81, 0xab, 0x87, 0x9a, 0x8b, + 0x94, 0x8b, 0xa3, 0x9a, 0x94, 0xb7, 0x8e, 0x8d, 0x8b, 0x90, 0x8b, 0x91, + 0x8c, 0x08, 0xa4, 0xfb, 0xcc, 0x72, 0x07, 0xb4, 0x89, 0x9f, 0x82, 0x96, + 0x73, 0x08, 0xae, 0x2b, 0xfb, 0x0a, 0xfb, 0xc8, 0xfb, 0x0c, 0xf8, 0x00, + 0x05, 0x86, 0x9b, 0x89, 0x93, 0x8b, 0x94, 0x8b, 0xa8, 0x97, 0x94, 0xbf, + 0x8f, 0x08, 0xa4, 0xfb, 0xba, 0x72, 0x07, 0xb5, 0x85, 0x95, 0x82, 0x9c, + 0x5a, 0x08, 0xf7, 0x68, 0xfc, 0xee, 0xa7, 0x8b, 0xf7, 0x4e, 0xf8, 0x71, + 0xf7, 0x3f, 0xfc, 0x71, 0xa6, 0x8b, 0xf7, 0x5c, 0xf8, 0xee, 0x05, 0x98, + 0xb3, 0xa2, 0xa0, 0xac, 0x8e, 0x08, 0xa4, 0x07, 0x0e, 0xda, 0xf9, 0x44, + 0xf9, 0x38, 0x15, 0xfb, 0x8e, 0x72, 0x06, 0x94, 0x8a, 0x93, 0x8b, 0x8e, + 0x8a, 0xb3, 0x89, 0x97, 0x82, 0x8b, 0x73, 0x8b, 0x76, 0x80, 0x76, 0x5c, + 0x4b, 0x83, 0x81, 0x74, 0x6b, 0x72, 0x68, 0x08, 0x2a, 0xf7, 0x2a, 0x05, + 0x7e, 0x9f, 0x89, 0x90, 0x8b, 0x97, 0x8b, 0xa0, 0x97, 0x93, 0xaf, 0x8d, + 0x90, 0x8b, 0x97, 0x8c, 0x99, 0x8c, 0x08, 0xa4, 0xfb, 0xee, 0x72, 0x07, + 0xaf, 0x88, 0x98, 0x81, 0xaa, 0x5e, 0x08, 0xf7, 0x5a, 0xfb, 0xb7, 0xfb, + 0x43, 0xfb, 0x71, 0x05, 0x6d, 0x66, 0x73, 0x7e, 0x59, 0x85, 0x08, 0x72, + 0xf7, 0x8e, 0xa4, 0x07, 0x4e, 0x91, 0x77, 0x95, 0x8b, 0xa4, 0x8b, 0xa1, + 0x9f, 0xab, 0xd5, 0xef, 0x08, 0xb1, 0xbe, 0xf0, 0xfb, 0x36, 0x05, 0x97, + 0x78, 0x94, 0x73, 0x8b, 0x80, 0x8b, 0x7a, 0x7a, 0x82, 0x68, 0x89, 0x87, + 0x8b, 0x80, 0x8a, 0x7e, 0x8a, 0x08, 0x72, 0xf7, 0xe8, 0xa4, 0x07, 0x69, + 0x8c, 0x7c, 0x98, 0x5b, 0xd3, 0x08, 0xfb, 0x4a, 0xf7, 0xaf, 0xdb, 0xf7, + 0x03, 0x05, 0xe3, 0xf7, 0x0c, 0xa5, 0x9e, 0xd5, 0x92, 0x08, 0xa4, 0x07, + 0x0e, 0xda, 0xf9, 0x4f, 0xf9, 0x38, 0x15, 0xfb, 0x70, 0x72, 0x06, 0xce, + 0x86, 0x9c, 0x83, 0x8b, 0x6e, 0x8b, 0x78, 0x7d, 0x68, 0x72, 0x62, 0x08, + 0xfb, 0x03, 0xfb, 0x4d, 0xfb, 0x0c, 0xf7, 0x7c, 0x05, 0x8a, 0x8e, 0x86, + 0x94, 0x8b, 0x8b, 0x7d, 0xa4, 0x87, 0x96, 0x8b, 0x96, 0x08, 0xa1, 0x9a, + 0x93, 0xb4, 0x1e, 0xa4, 0x8c, 0x8b, 0xa4, 0xfb, 0xe3, 0x8b, 0x8b, 0x72, + 0x05, 0xad, 0x89, 0xa5, 0x78, 0x9f, 0x69, 0x08, 0xf7, 0x4b, 0xfb, 0xe0, + 0x8b, 0xfb, 0x27, 0x05, 0x8b, 0x42, 0x80, 0x80, 0x39, 0x83, 0x08, 0x72, + 0xf7, 0xef, 0xa4, 0x07, 0x39, 0x93, 0x81, 0x95, 0x8b, 0xd5, 0x08, 0x8b, + 0xf7, 0x4c, 0xf7, 0x53, 0xf7, 0xcb, 0x05, 0x9a, 0xa2, 0x9e, 0x96, 0xad, + 0x90, 0x08, 0xa4, 0x07, 0x0e, 0xa3, 0xf9, 0x0e, 0xf7, 0x85, 0x15, 0x71, + 0x06, 0x70, 0x2d, 0x74, 0x63, 0x5c, 0x6a, 0x69, 0x73, 0x39, 0x7c, 0x2b, + 0x8b, 0x08, 0x41, 0x8b, 0xf8, 0x0f, 0xf9, 0x05, 0x8b, 0x9b, 0xfc, 0xa0, + 0x8b, 0x76, 0xfb, 0x62, 0xa7, 0x8b, 0x05, 0xbb, 0xf7, 0x1f, 0xb7, 0xaa, + 0xf7, 0x28, 0x89, 0x97, 0x8c, 0xad, 0x8c, 0xb0, 0x8c, 0x08, 0xfc, 0x12, + 0xfd, 0x05, 0x8b, 0x7b, 0xf8, 0xd8, 0x8b, 0xa5, 0xf7, 0x85, 0x05, 0x0e, + 0xfb, 0xca, 0xf7, 0xc1, 0xfb, 0x08, 0x15, 0x3b, 0x06, 0x62, 0x82, 0x95, + 0xb6, 0x1f, 0xf9, 0x12, 0x07, 0xc5, 0x96, 0x97, 0xc3, 0x1e, 0xca, 0xac, + 0xfb, 0x7e, 0xfd, 0xcf, 0xf7, 0x7e, 0xac, 0x06, 0x0e, 0xfc, 0x01, 0xf7, + 0x67, 0x78, 0x15, 0xe7, 0x8b, 0xfb, 0x7f, 0xf9, 0x5a, 0x2e, 0x8b, 0xf7, + 0x80, 0xfd, 0x5a, 0x05, 0x0e, 0xfb, 0xca, 0xab, 0xfb, 0x29, 0x15, 0xf7, + 0x7e, 0xf9, 0xcf, 0xfb, 0x7e, 0x6a, 0xca, 0x06, 0xc3, 0x96, 0x7f, 0x51, + 0x1f, 0xfd, 0x12, 0x07, 0x5f, 0x83, 0x82, 0x61, 0x1e, 0x3b, 0x6a, 0x06, + 0x0e, 0x4d, 0xf7, 0x36, 0xf7, 0xcb, 0x15, 0xf7, 0x15, 0xf7, 0xa4, 0xf7, + 0x15, 0xfb, 0xa4, 0xe4, 0x8b, 0xfb, 0x46, 0xf8, 0x01, 0x3b, 0x8b, 0xfb, + 0x46, 0xfc, 0x01, 0xe4, 0x8b, 0x05, 0x0e, 0xf8, 0x88, 0xfb, 0x11, 0x15, + 0xbd, 0xfc, 0x88, 0x59, 0xf8, 0x88, 0x07, 0x0e, 0xfb, 0xca, 0xf7, 0x80, + 0xf9, 0x47, 0x15, 0xfb, 0x08, 0x48, 0x59, 0x49, 0x8b, 0x35, 0x08, 0x46, + 0xb4, 0x5c, 0xc7, 0xbd, 0xac, 0xac, 0xbd, 0xb9, 0x6d, 0xab, 0x60, 0x1e, + 0x86, 0x8b, 0x85, 0x8b, 0x85, 0x8a, 0x88, 0x8a, 0x89, 0x8b, 0x89, 0x8b, + 0x80, 0x8b, 0x83, 0x94, 0x8b, 0x97, 0x8b, 0xb2, 0xad, 0xb5, 0xd6, 0xbf, + 0x08, 0x80, 0xa1, 0x05, 0x0e, 0xf8, 0x6d, 0xcb, 0x15, 0x81, 0x81, 0x05, + 0x88, 0x88, 0x88, 0x8a, 0x86, 0x8b, 0x08, 0x7d, 0x84, 0x94, 0x9b, 0x1f, + 0xf7, 0x99, 0x07, 0xdf, 0x3f, 0xc0, 0xfb, 0x0e, 0xfb, 0x05, 0x3f, 0x58, + 0x40, 0x62, 0xa3, 0x72, 0xb4, 0xb3, 0xa7, 0xa3, 0xad, 0x1e, 0x8b, 0x99, + 0x85, 0x98, 0x7f, 0x9b, 0x82, 0x95, 0x88, 0x91, 0x8b, 0x91, 0x08, 0xa0, + 0xa7, 0x9b, 0xae, 0x1e, 0xc5, 0xa5, 0x70, 0x4e, 0x1f, 0x42, 0x07, 0xfb, + 0x0b, 0x67, 0x5a, 0x77, 0x66, 0x72, 0x60, 0x6d, 0x76, 0x69, 0x8b, 0x60, + 0x8b, 0x4e, 0xba, 0x5e, 0xcb, 0x8b, 0xc4, 0x8b, 0xb9, 0x9f, 0xc2, 0xbd, + 0x96, 0x58, 0xa1, 0x78, 0xbc, 0x8b, 0xb6, 0x8b, 0xaa, 0x9b, 0xb1, 0xb4, + 0x08, 0x7c, 0xa0, 0x05, 0xfb, 0x48, 0xaf, 0x15, 0x70, 0x6c, 0x77, 0x7f, + 0x73, 0x8b, 0x6d, 0x8b, 0x76, 0xa6, 0x8b, 0xb3, 0x8b, 0xc5, 0xb5, 0xb5, + 0xdb, 0xa0, 0x08, 0xfb, 0x25, 0x07, 0x0e, 0x34, 0xf7, 0x67, 0xf9, 0x38, + 0x15, 0xfb, 0x56, 0x73, 0x06, 0xb9, 0x82, 0x94, 0x82, 0x8b, 0x63, 0x08, + 0xfc, 0xf3, 0x97, 0x07, 0xda, 0xc3, 0x05, 0xb9, 0x62, 0xaf, 0x7b, 0xbd, + 0x8b, 0x08, 0xf7, 0x19, 0xe8, 0xf3, 0xf7, 0x29, 0xf7, 0x1e, 0x3e, 0xeb, + 0xfb, 0x03, 0x1f, 0x5b, 0x8b, 0x66, 0x7a, 0x66, 0x64, 0x08, 0xf7, 0x97, + 0x07, 0xfb, 0xd0, 0x04, 0x9c, 0xb6, 0x9f, 0x9b, 0xac, 0x8b, 0x08, 0xc9, + 0xaa, 0x48, 0xfb, 0x17, 0xfb, 0x1e, 0x6d, 0x4a, 0x4b, 0x61, 0x70, 0xaa, + 0xbb, 0x1f, 0xf7, 0x9b, 0x07, 0x0e, 0xfb, 0x5b, 0xf8, 0x30, 0xf7, 0x01, + 0x15, 0x66, 0x61, 0x71, 0x7d, 0x62, 0x8b, 0x08, 0x34, 0x54, 0xe2, 0xf7, + 0x1c, 0xf2, 0xab, 0xca, 0xbf, 0x1f, 0x9b, 0x8b, 0x9a, 0x83, 0x91, 0x80, + 0x90, 0x82, 0x8b, 0x8b, 0x8b, 0x61, 0x8c, 0x5a, 0x9d, 0x74, 0xb0, 0x8b, + 0x08, 0xb5, 0xa5, 0xa3, 0xb2, 0xc9, 0x48, 0xbb, 0x33, 0xfb, 0x1c, 0x27, + 0x21, 0xfb, 0x24, 0xfb, 0x1e, 0xe5, 0x28, 0xf7, 0x10, 0x1f, 0xd8, 0x8b, + 0xc3, 0xaa, 0xc5, 0xd5, 0x08, 0x79, 0x9d, 0x05, 0x0e, 0x34, 0xf7, 0xe7, + 0x7e, 0x15, 0xb9, 0x98, 0xa4, 0x90, 0xc9, 0x92, 0x08, 0xc9, 0x93, 0x8b, + 0xa2, 0x05, 0x5d, 0x8e, 0x7e, 0x98, 0x8b, 0xb5, 0x08, 0xf8, 0xd3, 0xfb, + 0x6b, 0x73, 0x07, 0xce, 0x86, 0x94, 0x84, 0x8b, 0x5d, 0x08, 0xfb, 0x4b, + 0x07, 0x60, 0xb9, 0x6d, 0x9b, 0x5d, 0x8b, 0x08, 0xfb, 0x02, 0x39, 0x20, + 0xfb, 0x25, 0x1f, 0xfb, 0x1c, 0xd7, 0x28, 0xf4, 0x1e, 0xc0, 0x8b, 0xac, + 0x9b, 0xba, 0xbd, 0x08, 0x4a, 0x07, 0x88, 0xf7, 0x11, 0x15, 0x8b, 0x85, + 0x81, 0x7a, 0x7f, 0x7e, 0x77, 0x74, 0x76, 0x80, 0x75, 0x8b, 0x08, 0x56, + 0x72, 0xc7, 0xf7, 0x13, 0xf7, 0x15, 0xa6, 0xc6, 0xc5, 0x1f, 0xac, 0x8b, + 0xaa, 0x73, 0x99, 0x65, 0x08, 0xfb, 0x87, 0x07, 0x0e, 0xfb, 0x5b, 0xf8, + 0x26, 0xf7, 0x11, 0x15, 0x63, 0x5a, 0x6c, 0x79, 0x60, 0x8b, 0x64, 0x8b, + 0x6e, 0x9d, 0x76, 0xae, 0x79, 0xab, 0x83, 0xac, 0x87, 0xd0, 0x08, 0xf7, + 0x90, 0x06, 0x85, 0xdf, 0x7c, 0xba, 0x6b, 0xb1, 0x6a, 0xb2, 0x5d, 0x9f, + 0x54, 0x8b, 0x08, 0xfb, 0x11, 0x37, 0x28, 0xfb, 0x26, 0xfb, 0x26, 0xdd, + 0x2b, 0xf7, 0x10, 0x1f, 0xdc, 0x8b, 0xbc, 0xab, 0xcc, 0xe8, 0x08, 0x73, + 0x99, 0x05, 0xfb, 0x82, 0xf7, 0x31, 0x15, 0x8e, 0xf7, 0x0c, 0x9d, 0xb3, + 0xbc, 0x8b, 0xa7, 0x8b, 0x9e, 0x7b, 0x93, 0x6c, 0x90, 0x78, 0x8d, 0x6f, + 0x8d, 0x58, 0x08, 0x7c, 0xfb, 0x1a, 0x07, 0x0e, 0xfb, 0xca, 0xd2, 0xf8, + 0x35, 0x15, 0xfb, 0xe1, 0x07, 0x8b, 0x60, 0x80, 0x7f, 0x5d, 0x86, 0x08, + 0x73, 0xf7, 0xaa, 0xa3, 0x07, 0x45, 0x8d, 0x7f, 0x97, 0x8b, 0xcc, 0x08, + 0xf7, 0xce, 0xe2, 0xb7, 0x34, 0xf7, 0x0e, 0x07, 0xc2, 0x9a, 0xa1, 0xae, + 0x9d, 0x96, 0x84, 0x7f, 0x1e, 0x8b, 0x87, 0x88, 0x84, 0x85, 0x81, 0x82, + 0x7c, 0x87, 0x80, 0x8b, 0x81, 0x08, 0x6c, 0xa5, 0x73, 0xad, 0xb0, 0xa4, + 0xa4, 0xb0, 0xc6, 0x50, 0xb4, 0x37, 0x1e, 0x48, 0x8b, 0x57, 0x73, 0x70, + 0x5f, 0x75, 0x68, 0x84, 0x62, 0x8b, 0x35, 0x08, 0x52, 0x5f, 0xc4, 0x06, + 0x0e, 0xf8, 0x76, 0xf8, 0x22, 0x15, 0xc0, 0xfb, 0x16, 0x07, 0x5f, 0x9b, + 0x6f, 0x91, 0x63, 0x8b, 0xfb, 0x0b, 0x8b, 0x37, 0x49, 0x8b, 0x2c, 0x8b, + 0x69, 0x98, 0x6a, 0xa2, 0x6f, 0xa1, 0x73, 0x9e, 0x7e, 0xba, 0x77, 0x3c, + 0x70, 0x63, 0x65, 0x8b, 0x57, 0x8b, 0x62, 0x9d, 0x79, 0xcb, 0x74, 0x08, + 0x4c, 0x82, 0x6a, 0x72, 0x8b, 0x62, 0x08, 0x51, 0xd6, 0x69, 0xf7, 0x12, + 0xf7, 0x3a, 0xe3, 0xbf, 0xee, 0xd8, 0x4d, 0xb9, 0x25, 0x1e, 0x4a, 0x06, + 0x3b, 0x77, 0x92, 0xa7, 0xa9, 0xa7, 0xa1, 0xb3, 0x1f, 0xb8, 0x8a, 0x05, + 0xba, 0x8b, 0xa4, 0x91, 0xad, 0x9f, 0x08, 0xb8, 0xa5, 0xa2, 0xb4, 0x8b, + 0xc0, 0x8b, 0xb3, 0x7f, 0xa9, 0x6f, 0xa7, 0x08, 0xdc, 0x06, 0xfb, 0x32, + 0xfc, 0x56, 0x15, 0xc1, 0xa5, 0x7a, 0x6a, 0x5d, 0x54, 0x71, 0x28, 0x33, + 0x5d, 0xa2, 0xb7, 0x1f, 0x8b, 0xa0, 0x92, 0x96, 0xa7, 0xa2, 0x08, 0xf7, + 0x41, 0x06, 0x37, 0xf8, 0x82, 0x15, 0xba, 0x9e, 0x65, 0x2e, 0x2e, 0x78, + 0x67, 0x5c, 0x5b, 0x79, 0xaf, 0xe8, 0x1f, 0xe9, 0x9e, 0xb0, 0xba, 0x1e, + 0x0e, 0x34, 0xf7, 0x64, 0xf9, 0x38, 0x15, 0xfb, 0x54, 0x73, 0x06, 0xb9, + 0x82, 0x92, 0x83, 0x8b, 0x62, 0x08, 0xfc, 0x92, 0x07, 0x8b, 0x61, 0x83, + 0x82, 0x5e, 0x82, 0x08, 0x73, 0xf7, 0x85, 0xa3, 0x07, 0x66, 0x90, 0x7f, + 0x9a, 0x8b, 0xb0, 0x08, 0xf7, 0x9f, 0x07, 0x8b, 0x8f, 0x92, 0x95, 0x95, + 0x94, 0xa1, 0xa2, 0xa3, 0x97, 0xa2, 0x8b, 0x08, 0xae, 0x9c, 0x70, 0x53, + 0x1f, 0xfb, 0x86, 0x07, 0x8b, 0x66, 0x7e, 0x7b, 0x69, 0x87, 0x08, 0x73, + 0xf7, 0x7f, 0xa3, 0x07, 0x67, 0x8e, 0x7e, 0x9a, 0x8b, 0xb5, 0x08, 0xf7, + 0x8c, 0x07, 0xe1, 0x56, 0xc2, 0x39, 0x1e, 0x56, 0x8b, 0x66, 0x77, 0x57, + 0x51, 0x08, 0xf7, 0xad, 0x07, 0x0e, 0xfc, 0x01, 0xf7, 0x64, 0xf8, 0x61, + 0x15, 0xfb, 0x54, 0x73, 0x06, 0xb7, 0x82, 0x94, 0x82, 0x8b, 0x62, 0x08, + 0xfb, 0xba, 0x07, 0x8b, 0x62, 0x84, 0x83, 0x5d, 0x80, 0x08, 0x73, 0xf7, + 0x83, 0xa3, 0x07, 0x68, 0x90, 0x7f, 0x99, 0x8b, 0xb1, 0x08, 0xf8, 0x10, + 0x07, 0x45, 0xf7, 0x7a, 0x15, 0x60, 0x68, 0x68, 0x61, 0x5e, 0xac, 0x6a, + 0xb7, 0xb7, 0xad, 0xac, 0xb7, 0x1f, 0xb6, 0x69, 0xae, 0x60, 0x1e, 0x0e, + 0xfb, 0xca, 0xf7, 0x98, 0xf8, 0x61, 0x15, 0xfb, 0x5e, 0x73, 0x06, 0xbe, + 0x87, 0x97, 0x7f, 0x8b, 0x60, 0x08, 0xfc, 0x6e, 0x07, 0x56, 0x7c, 0x74, + 0x6a, 0x78, 0x7e, 0x92, 0x95, 0x1e, 0x8b, 0x90, 0x8e, 0x92, 0x91, 0x95, + 0x95, 0x9b, 0x8f, 0x96, 0x8b, 0x95, 0x08, 0xa9, 0x70, 0xa3, 0x6b, 0x66, + 0x72, 0x72, 0x67, 0x50, 0xc5, 0x62, 0xdd, 0x1e, 0xd0, 0x8b, 0xc0, 0xa6, + 0xa7, 0xbc, 0x9e, 0xab, 0x93, 0xb1, 0x8b, 0xc6, 0x08, 0xf8, 0x5f, 0x07, + 0x40, 0xf7, 0x7a, 0x15, 0x60, 0x69, 0x68, 0x61, 0x5e, 0xab, 0x6a, 0xb8, + 0xb6, 0xae, 0xad, 0xb6, 0x1f, 0xb6, 0x68, 0xae, 0x60, 0x1e, 0x0e, 0x34, + 0xf8, 0x95, 0xf8, 0x61, 0x15, 0xfb, 0x6a, 0x74, 0x06, 0x96, 0x89, 0x95, + 0x8a, 0x8e, 0x8a, 0xa3, 0x88, 0x96, 0x84, 0x8b, 0x7e, 0x8b, 0x82, 0x81, + 0x79, 0x80, 0x80, 0x08, 0xfb, 0x14, 0xfb, 0x14, 0x8b, 0xf8, 0x43, 0xfb, + 0x4f, 0x8b, 0x8b, 0x73, 0x05, 0xad, 0x88, 0x99, 0x7a, 0x8b, 0x65, 0x08, + 0xfc, 0x92, 0x07, 0x8b, 0x64, 0x7c, 0x79, 0x6a, 0x88, 0x08, 0x73, 0xf7, + 0x83, 0xa3, 0x07, 0x5c, 0x92, 0x86, 0x91, 0x8b, 0xba, 0x08, 0x8b, 0xf7, + 0x06, 0xa2, 0xa3, 0xea, 0xfb, 0x1a, 0x05, 0x9c, 0x72, 0x92, 0x7f, 0x8b, + 0x83, 0x8b, 0x7f, 0x7d, 0x85, 0x6f, 0x8a, 0x08, 0x73, 0xf7, 0x7e, 0xa3, + 0x07, 0x80, 0x8b, 0x86, 0x8e, 0x82, 0x97, 0x08, 0xfb, 0x56, 0xf7, 0xa0, + 0x05, 0xef, 0xf4, 0xa5, 0x9d, 0xca, 0x93, 0x08, 0xa2, 0x07, 0x0e, 0xfc, + 0x01, 0xf7, 0x62, 0xf9, 0x38, 0x15, 0xfb, 0x52, 0x73, 0x06, 0xae, 0x88, + 0x9b, 0x79, 0x8b, 0x66, 0x08, 0xfc, 0x92, 0x07, 0x8b, 0x66, 0x7a, 0x77, + 0x69, 0x88, 0x08, 0x73, 0xf7, 0x83, 0xa3, 0x07, 0x6a, 0x8c, 0x7b, 0x9e, + 0x8b, 0xb3, 0x08, 0xf8, 0xe4, 0x07, 0x0e, 0xf7, 0x52, 0xf7, 0x63, 0xf8, + 0x61, 0x15, 0xfb, 0x53, 0x73, 0x06, 0xb7, 0x85, 0x96, 0x7f, 0x8b, 0x62, + 0x08, 0xfb, 0xba, 0x07, 0x8b, 0x62, 0x80, 0x80, 0x5f, 0x83, 0x08, 0x73, + 0xf7, 0x84, 0xa3, 0x07, 0x68, 0x90, 0x80, 0x99, 0x8b, 0xb1, 0x08, 0xf7, + 0x9f, 0x07, 0x8b, 0x91, 0x9b, 0x9e, 0x98, 0x95, 0x08, 0xa0, 0x9b, 0x9c, + 0x92, 0x9c, 0x8b, 0x08, 0xb2, 0x9a, 0x74, 0x4f, 0x1f, 0xfb, 0x86, 0x07, + 0x8b, 0x62, 0x80, 0x7e, 0x66, 0x88, 0x08, 0x73, 0xf7, 0x7e, 0xa3, 0x07, + 0x68, 0x8f, 0x7f, 0x9a, 0x8b, 0xb1, 0x08, 0xf7, 0x9f, 0x07, 0x8b, 0x90, + 0x9b, 0x9e, 0x98, 0x95, 0xa1, 0x9c, 0x9c, 0x92, 0x9c, 0x8b, 0x08, 0xb1, + 0x9a, 0x73, 0x50, 0x1f, 0xfb, 0x86, 0x07, 0x8b, 0x61, 0x80, 0x7f, 0x65, + 0x88, 0x08, 0x73, 0xf7, 0x82, 0xa3, 0x07, 0x64, 0x8d, 0x80, 0x97, 0x8b, + 0xb6, 0x08, 0xf7, 0x8f, 0x07, 0xe1, 0x56, 0xc2, 0x39, 0x1e, 0x52, 0x8b, + 0x65, 0x74, 0x57, 0x4b, 0x6d, 0xca, 0x68, 0xa3, 0x4c, 0x8b, 0x4c, 0x8b, + 0x5d, 0x70, 0x65, 0x4f, 0x08, 0xd6, 0x07, 0x0e, 0x34, 0xf7, 0x68, 0xf8, + 0x61, 0x15, 0xfb, 0x53, 0x73, 0x06, 0xb7, 0x84, 0x94, 0x81, 0x8b, 0x61, + 0x08, 0xfb, 0xba, 0x07, 0x8b, 0x61, 0x83, 0x82, 0x5e, 0x82, 0x08, 0x73, + 0xf7, 0x85, 0xa3, 0x07, 0x66, 0x90, 0x7f, 0x9a, 0x8b, 0xb0, 0x08, 0xf7, + 0x9f, 0x07, 0x8b, 0x8f, 0x92, 0x95, 0x95, 0x94, 0x08, 0xa1, 0xa2, 0xa3, + 0x97, 0xa2, 0x8b, 0x08, 0xae, 0x9c, 0x70, 0x53, 0x1f, 0xfb, 0x86, 0x07, + 0x8b, 0x66, 0x7e, 0x7b, 0x69, 0x87, 0x08, 0x73, 0xf7, 0x7f, 0xa3, 0x07, + 0x64, 0x8e, 0x81, 0x97, 0x8b, 0xb5, 0x08, 0xf7, 0x8f, 0x07, 0xe1, 0x56, + 0xc2, 0x39, 0x1e, 0x4f, 0x8b, 0x5d, 0x6f, 0x66, 0x50, 0x08, 0xd6, 0x07, + 0x0e, 0xf7, 0x8f, 0xf8, 0x6d, 0x15, 0xfb, 0x13, 0x28, 0x22, 0xfb, 0x1c, + 0xfb, 0x23, 0xea, 0x24, 0xf7, 0x17, 0xf7, 0x15, 0xeb, 0xf3, 0xf7, 0x1f, + 0xf7, 0x20, 0x2b, 0xf3, 0xfb, 0x15, 0x1f, 0x8c, 0x6c, 0x15, 0xc5, 0x9e, + 0x54, 0xfb, 0x38, 0xfb, 0x2e, 0x77, 0x57, 0x51, 0x50, 0x77, 0xbe, 0xf7, + 0x26, 0xf7, 0x44, 0x9d, 0xbf, 0xc9, 0x1f, 0x0e, 0x34, 0xf7, 0x68, 0xf8, + 0x61, 0x15, 0xfb, 0x53, 0x73, 0x06, 0xb7, 0x84, 0x95, 0x81, 0x8b, 0x61, + 0x08, 0xfc, 0x89, 0x07, 0x8b, 0x62, 0x83, 0x82, 0x5b, 0x83, 0x08, 0x73, + 0xf7, 0xa5, 0x07, 0xa0, 0x07, 0x4e, 0x8e, 0x7a, 0x9f, 0x8b, 0xce, 0x08, + 0xf7, 0x21, 0x07, 0xbb, 0x5c, 0xa5, 0x7e, 0xb7, 0x8b, 0x08, 0xf7, 0x04, + 0xdb, 0xf3, 0xf7, 0x28, 0xf7, 0x1f, 0x40, 0xea, 0xfb, 0x03, 0x1f, 0x50, + 0x8b, 0x67, 0x74, 0x6c, 0x51, 0x08, 0xd0, 0x07, 0x8d, 0xfb, 0x07, 0x15, + 0x8b, 0x92, 0x94, 0x9b, 0x97, 0x98, 0x9f, 0xa1, 0xa2, 0x97, 0xa1, 0x8b, + 0x08, 0xbf, 0xa3, 0x4f, 0xfb, 0x17, 0xfb, 0x10, 0x6f, 0x50, 0x52, 0x1f, + 0x6a, 0x8b, 0x6e, 0xa2, 0x7c, 0xb1, 0x08, 0xf7, 0x87, 0x07, 0x0e, 0x34, + 0xf7, 0xea, 0x2a, 0x15, 0x8b, 0x4d, 0x83, 0x82, 0x4a, 0x7f, 0x08, 0x72, + 0xf7, 0x9f, 0xa3, 0x07, 0x5d, 0x94, 0x82, 0x94, 0x8b, 0xb3, 0x08, 0xf8, + 0xe7, 0x7c, 0x07, 0x3d, 0x53, 0x05, 0x58, 0xb6, 0x6c, 0x99, 0x59, 0x8b, + 0x08, 0xfb, 0x16, 0x2f, 0x22, 0xfb, 0x29, 0xfb, 0x1d, 0xd7, 0x2b, 0xf7, + 0x01, 0x1f, 0xba, 0x8b, 0xae, 0x9b, 0xb4, 0xb3, 0x08, 0xfb, 0x1f, 0x07, + 0xf7, 0x57, 0x04, 0x81, 0x66, 0x72, 0x76, 0x69, 0x8b, 0x08, 0x4d, 0x6c, + 0xcc, 0xf7, 0x17, 0xf7, 0x1b, 0xab, 0xd1, 0xca, 0xb3, 0xa6, 0x6b, 0x5b, + 0x1f, 0xfb, 0x9b, 0x07, 0x0e, 0xfb, 0x5b, 0xf7, 0x6e, 0xf8, 0x61, 0x15, + 0xfb, 0x51, 0x73, 0x06, 0xb6, 0x85, 0x96, 0x7e, 0x8b, 0x63, 0x08, 0xfb, + 0xba, 0x07, 0x8b, 0x62, 0x81, 0x80, 0x5f, 0x83, 0x08, 0x73, 0xf7, 0x9e, + 0xa3, 0x07, 0x4e, 0x8f, 0x7f, 0x98, 0x8b, 0xc9, 0x08, 0xf7, 0x51, 0x07, + 0xbf, 0xa7, 0xb6, 0xac, 0x1e, 0x93, 0x8b, 0x94, 0x84, 0x96, 0x7b, 0x9e, + 0x70, 0x9a, 0x82, 0xa5, 0x8b, 0x08, 0xb0, 0xa5, 0xa7, 0xb2, 0x1f, 0xb8, + 0x69, 0xac, 0x5c, 0x1e, 0x59, 0x8b, 0x65, 0x70, 0x5c, 0x48, 0x08, 0xdd, + 0x07, 0x0e, 0xfb, 0x92, 0xf7, 0xe8, 0xf7, 0xda, 0x15, 0xf7, 0x25, 0x75, + 0x07, 0x85, 0x7c, 0x85, 0x86, 0x7f, 0x8b, 0x85, 0x8b, 0x81, 0x8d, 0x7b, + 0x90, 0x6a, 0x96, 0x74, 0x8f, 0x75, 0x8b, 0x30, 0x8b, 0x49, 0x4d, 0x8b, + 0x37, 0x8b, 0x49, 0xb4, 0x5d, 0xf0, 0x60, 0xcf, 0x6d, 0xa7, 0x72, 0x8b, + 0x6b, 0x08, 0x64, 0x6d, 0x71, 0x5e, 0x1e, 0x45, 0x8b, 0x5d, 0xb8, 0x76, + 0xe2, 0x08, 0x6f, 0xfb, 0x39, 0xa4, 0x06, 0x96, 0xa0, 0x91, 0x92, 0x94, + 0x8b, 0x90, 0x8b, 0x93, 0x89, 0x95, 0x87, 0xa6, 0x7f, 0xc0, 0x80, 0xa7, + 0x8b, 0xe6, 0x8b, 0xca, 0xc9, 0x8b, 0xe5, 0x8b, 0xd2, 0x64, 0xb6, 0x28, + 0xb5, 0x47, 0xa8, 0x6f, 0xa4, 0x8b, 0xad, 0x08, 0xac, 0xa7, 0xa4, 0xb1, + 0x1e, 0xa5, 0x8b, 0xa6, 0x80, 0xa1, 0x76, 0xa0, 0x77, 0x96, 0x79, 0x9a, + 0x5f, 0x08, 0xa4, 0x06, 0x0e, 0xfb, 0xca, 0xf7, 0xc5, 0xf8, 0x61, 0x15, + 0x2d, 0xf7, 0x3d, 0x72, 0x06, 0x4e, 0x35, 0x63, 0x5e, 0x4a, 0x54, 0x08, + 0x70, 0xbf, 0xfb, 0xd8, 0x07, 0x4a, 0xb6, 0x63, 0xd0, 0x1e, 0xce, 0x8b, + 0xb3, 0xa9, 0xb4, 0xdd, 0x08, 0x72, 0x96, 0x05, 0x77, 0x65, 0x7b, 0x7d, + 0x76, 0x8b, 0x08, 0x6f, 0x80, 0x9c, 0xb3, 0x1f, 0xf7, 0xc1, 0xe9, 0xb7, + 0x07, 0x0e, 0x34, 0xf7, 0xeb, 0x7e, 0x15, 0xb6, 0x9a, 0xa3, 0x8f, 0xcc, + 0x92, 0x08, 0xc9, 0x92, 0x8b, 0xa2, 0x05, 0x5f, 0x8d, 0x7f, 0x98, 0x8b, + 0xb6, 0x08, 0xf7, 0xfc, 0xfb, 0x5d, 0x73, 0x07, 0xbd, 0x87, 0x97, 0x7f, + 0x8b, 0x60, 0x08, 0xfb, 0xaf, 0x07, 0x6a, 0x6a, 0x76, 0x80, 0x6f, 0x8b, + 0x08, 0x62, 0x7c, 0x9f, 0xbe, 0x1f, 0xf7, 0xe7, 0xfb, 0x50, 0x73, 0x07, + 0xb4, 0x83, 0x93, 0x82, 0x8b, 0x61, 0x08, 0xfb, 0x90, 0x07, 0x33, 0xbd, + 0x57, 0xde, 0x1e, 0xbf, 0x8b, 0xae, 0x9b, 0xc5, 0xbd, 0x08, 0x4a, 0x07, + 0x0e, 0xf8, 0x79, 0xf8, 0x61, 0x15, 0xfb, 0x2b, 0x73, 0x06, 0xb6, 0x89, + 0x97, 0x84, 0x8b, 0x73, 0x8b, 0x80, 0x87, 0x7b, 0x84, 0x79, 0x08, 0x43, + 0xfb, 0x4a, 0x3c, 0xf7, 0x5f, 0x05, 0x84, 0x9e, 0x89, 0x91, 0x8b, 0x91, + 0x8b, 0x9a, 0x95, 0x92, 0xa4, 0x8d, 0x8d, 0x8b, 0x93, 0x8c, 0x93, 0x8c, + 0x08, 0xa3, 0xfb, 0x8e, 0x73, 0x07, 0xa2, 0x88, 0x91, 0x88, 0x91, 0x82, + 0x8d, 0x8c, 0xba, 0x27, 0x9b, 0x62, 0x08, 0xf7, 0x0c, 0xfb, 0xbc, 0xa5, + 0x8b, 0xf7, 0x34, 0xf8, 0x20, 0x05, 0x9e, 0xb7, 0x93, 0x93, 0xaa, 0x8e, + 0x08, 0xa3, 0x07, 0x0e, 0xda, 0xf9, 0x57, 0xf8, 0x61, 0x15, 0xfb, 0x1b, + 0x73, 0x06, 0xb0, 0x87, 0x96, 0x83, 0x8b, 0x74, 0x8b, 0x7f, 0x7e, 0x66, + 0x6c, 0x3c, 0x7c, 0x64, 0x83, 0x76, 0x7f, 0x69, 0x81, 0xb4, 0x88, 0x97, + 0x76, 0xd5, 0x77, 0xd0, 0x84, 0xa7, 0x8b, 0x94, 0x8b, 0x9b, 0x95, 0x90, + 0xb1, 0x8e, 0x08, 0xa3, 0xfb, 0x7e, 0x73, 0x07, 0xb2, 0x87, 0x8c, 0x8a, + 0x9e, 0x49, 0x08, 0x91, 0x78, 0x47, 0xfb, 0x3f, 0x73, 0xcb, 0x05, 0x82, + 0xa0, 0x84, 0x9e, 0x86, 0x99, 0x6f, 0xd1, 0x80, 0xab, 0x8b, 0x98, 0x8b, + 0x9b, 0x95, 0x93, 0xa7, 0x8f, 0x08, 0xa3, 0xfb, 0x72, 0x73, 0x07, 0xa5, + 0x86, 0x8f, 0x85, 0xa6, 0x49, 0x08, 0xf7, 0x28, 0xfc, 0x0a, 0xa3, 0x8b, + 0xf7, 0x11, 0xf7, 0xca, 0xf1, 0xfb, 0xca, 0xa2, 0x8b, 0xf7, 0x2f, 0xf8, + 0x25, 0x05, 0x9b, 0xb0, 0x93, 0x93, 0xa5, 0x90, 0x08, 0xa3, 0x07, 0x0e, + 0xf8, 0x78, 0xa3, 0x15, 0x7b, 0x90, 0x84, 0x8f, 0x84, 0x96, 0x08, 0xfb, + 0x28, 0xf7, 0x78, 0xf0, 0xf7, 0x12, 0x05, 0x9e, 0xa2, 0x9f, 0x96, 0xaa, + 0x90, 0x08, 0xa3, 0xfb, 0x3c, 0x73, 0x07, 0x94, 0x8a, 0x93, 0x8a, 0x8e, + 0x8b, 0xa2, 0x8a, 0x93, 0x85, 0x8b, 0x7c, 0x8b, 0x7c, 0x81, 0x7a, 0x6f, + 0x6b, 0x85, 0x85, 0x7c, 0x78, 0x7c, 0x76, 0x85, 0x92, 0x87, 0x91, 0x88, + 0x8f, 0x6b, 0xb5, 0x71, 0xb6, 0x8b, 0x98, 0x08, 0x8b, 0x97, 0x99, 0x91, + 0xac, 0x8c, 0x08, 0xa3, 0xfb, 0x8e, 0x73, 0x07, 0xa5, 0x87, 0x91, 0x86, + 0x9f, 0x6d, 0x08, 0xf7, 0x14, 0xfb, 0x59, 0x05, 0x6e, 0x66, 0x70, 0x6a, + 0x82, 0x7d, 0x53, 0x41, 0x77, 0x7a, 0x66, 0x89, 0x08, 0x73, 0xf7, 0x3d, + 0xa3, 0x07, 0x67, 0x8d, 0x7d, 0x92, 0x8b, 0x9a, 0x8b, 0x9a, 0xa5, 0xb5, + 0xb1, 0xb9, 0x8d, 0x8e, 0x92, 0x93, 0x92, 0x94, 0x08, 0xb5, 0x4c, 0x05, + 0xa2, 0x6a, 0x95, 0x78, 0x8b, 0x7f, 0x8b, 0x7f, 0x7d, 0x85, 0x6c, 0x89, + 0x08, 0x73, 0xf7, 0x85, 0xa3, 0x07, 0x0e, 0xf8, 0x74, 0xf8, 0x61, 0x15, + 0xfb, 0x2b, 0x73, 0x06, 0xb6, 0x89, 0x97, 0x84, 0x8b, 0x73, 0x8b, 0x80, + 0x89, 0x82, 0x82, 0x72, 0x08, 0x47, 0xfb, 0x54, 0x43, 0xf7, 0x4d, 0x05, + 0x77, 0xbe, 0x8b, 0x8b, 0x8b, 0x93, 0x8b, 0x99, 0x97, 0x94, 0xa4, 0x8d, + 0x08, 0x9b, 0x8c, 0x8b, 0xa3, 0xfb, 0x8e, 0x8b, 0x8b, 0x73, 0x05, 0xa2, + 0x88, 0x91, 0x88, 0x91, 0x82, 0x8e, 0x8b, 0xb8, 0x29, 0x9c, 0x61, 0x08, + 0xf7, 0x0c, 0xfb, 0xbb, 0x79, 0x56, 0x05, 0x7a, 0x59, 0x71, 0x6b, 0x74, + 0x8b, 0x82, 0x8b, 0x83, 0x93, 0x8b, 0x94, 0x8b, 0x8c, 0x8b, 0x8d, 0x8c, + 0x8e, 0x8c, 0x90, 0x8c, 0x90, 0x8b, 0x8f, 0x08, 0xa8, 0x73, 0x9f, 0x69, + 0x66, 0x70, 0x71, 0x65, 0x5d, 0xb3, 0x6a, 0xc4, 0x1e, 0xad, 0x8b, 0xa8, + 0x97, 0xa0, 0xa0, 0xa0, 0xa2, 0x9f, 0xb3, 0xae, 0xe9, 0x08, 0xf7, 0x29, + 0xf8, 0x21, 0x05, 0x9c, 0xb5, 0x95, 0x95, 0xaa, 0x8e, 0x08, 0xa3, 0x07, + 0x0e, 0xfb, 0x5b, 0xf8, 0x38, 0xf7, 0x34, 0x15, 0x6f, 0x06, 0x82, 0x6b, + 0x83, 0x79, 0x7b, 0x76, 0x6b, 0x5f, 0x6a, 0x7e, 0x3b, 0x8b, 0x08, 0x6e, + 0x8b, 0xf7, 0x7b, 0xf8, 0x27, 0x8b, 0xa5, 0xfc, 0x07, 0x8b, 0x84, 0xfb, + 0x22, 0xa5, 0x8b, 0x05, 0xa4, 0xea, 0xa5, 0x9b, 0xf7, 0x20, 0x8a, 0x08, + 0xfb, 0x7e, 0xfc, 0x28, 0x8b, 0x72, 0xf8, 0x13, 0x8b, 0x9b, 0xf7, 0x34, + 0x05, 0x0e, 0xfb, 0x8d, 0xf7, 0x15, 0x69, 0x15, 0x8b, 0x5a, 0x97, 0x6a, + 0xa6, 0x75, 0xa9, 0x71, 0xb7, 0x81, 0xed, 0x8a, 0x08, 0x97, 0x07, 0x3c, + 0x9b, 0x70, 0xaa, 0x8b, 0xd7, 0x08, 0xf7, 0x3f, 0x07, 0x8b, 0xdf, 0x73, + 0xa5, 0x2d, 0x9f, 0xe9, 0x9f, 0xa3, 0xa5, 0x8b, 0xdf, 0x08, 0xf7, 0x3f, + 0x07, 0x8b, 0xd7, 0xa5, 0xaa, 0xdb, 0x9c, 0x08, 0x97, 0x07, 0x32, 0x8a, + 0x63, 0x84, 0x6b, 0x76, 0x69, 0x76, 0x7b, 0x66, 0x8b, 0x54, 0x08, 0xfb, + 0x47, 0x07, 0x8b, 0x44, 0x75, 0x73, 0x36, 0x76, 0xe0, 0x76, 0xa1, 0x73, + 0x8b, 0x44, 0x08, 0xfb, 0x47, 0x07, 0x0e, 0xfc, 0x3b, 0xcd, 0x78, 0x15, + 0xe3, 0xf9, 0x5a, 0x33, 0xfd, 0x5a, 0x06, 0x0e, 0xfb, 0x8d, 0xf7, 0x34, + 0x64, 0x15, 0x8b, 0x3f, 0x71, 0x6c, 0x3b, 0x7a, 0x08, 0x7f, 0x07, 0xe4, + 0x8c, 0xb3, 0x92, 0xab, 0xa0, 0xad, 0xa0, 0x9b, 0xb0, 0x8b, 0xc2, 0x08, + 0xf7, 0x47, 0x07, 0x8b, 0xd2, 0xa1, 0xa3, 0xe0, 0xa0, 0x36, 0xa0, 0x75, + 0xa3, 0x8b, 0xd2, 0x08, 0xf7, 0x47, 0x07, 0x8b, 0xc2, 0x7b, 0xaf, 0x69, + 0xa0, 0x6b, 0xa0, 0x64, 0x92, 0x31, 0x8c, 0x08, 0x7f, 0x07, 0xda, 0x7b, + 0xa6, 0x6b, 0x8b, 0x40, 0x08, 0xfb, 0x3f, 0x07, 0x8b, 0x37, 0xa3, 0x71, + 0xe9, 0x77, 0x2e, 0x77, 0x72, 0x70, 0x8b, 0x38, 0x08, 0xfb, 0x3f, 0x07, + 0x0e, 0xfb, 0x0f, 0xf8, 0x48, 0xf7, 0xc8, 0x15, 0x72, 0x6b, 0x77, 0x7e, + 0x74, 0x8b, 0x7a, 0x8b, 0x79, 0x91, 0x5d, 0x9f, 0x08, 0x40, 0xad, 0x71, + 0x93, 0x6a, 0x8b, 0x55, 0x8b, 0x67, 0x72, 0x69, 0x50, 0x08, 0xc0, 0x5d, + 0x05, 0xa2, 0xab, 0x9c, 0x95, 0xa8, 0x8b, 0xae, 0x8b, 0xaa, 0x81, 0xb9, + 0x72, 0x08, 0xb9, 0x72, 0xa5, 0x83, 0xac, 0x8b, 0xb9, 0x8b, 0xab, 0xa1, + 0xb8, 0xca, 0x08, 0x54, 0xbb, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0x3c, 0xf8, + 0x89, 0x15, 0x5b, 0x65, 0x66, 0x5c, 0x5d, 0xb1, 0x64, 0xba, 0xb9, 0xb1, + 0xb1, 0xb9, 0xbb, 0x67, 0xb0, 0x5c, 0x1f, 0x7c, 0xfb, 0x8b, 0x15, 0x7e, + 0xfb, 0x10, 0x81, 0x5b, 0x6e, 0x2b, 0x7d, 0x5e, 0x87, 0x78, 0x8b, 0x73, + 0x08, 0x4b, 0xaa, 0x66, 0xc0, 0xc0, 0xab, 0xb0, 0xca, 0x1e, 0x8b, 0xa4, + 0x87, 0x9e, 0x7d, 0xb8, 0x6d, 0xeb, 0x82, 0xbc, 0x7e, 0xf7, 0x0f, 0x08, + 0x6e, 0x06, 0x0e, 0xf8, 0x41, 0xf8, 0xe0, 0x15, 0x63, 0x8b, 0x5f, 0xfb, + 0x0f, 0x05, 0x73, 0x91, 0x7c, 0x8d, 0x76, 0x8b, 0xfb, 0x19, 0x8b, 0x28, + 0x20, 0x8b, 0xfb, 0x23, 0x8b, 0x45, 0xa1, 0x4e, 0xb5, 0x60, 0x9d, 0x79, + 0x98, 0x81, 0xac, 0x7b, 0x08, 0x58, 0xfb, 0x25, 0xb3, 0x8b, 0xba, 0xf7, + 0x19, 0x05, 0x9e, 0x86, 0x97, 0x89, 0x9e, 0x8b, 0xb2, 0x8b, 0xb0, 0x95, + 0xad, 0x9e, 0xa6, 0x9a, 0x9f, 0x9e, 0xad, 0xb5, 0x08, 0x79, 0x9d, 0x05, + 0x69, 0x62, 0x6f, 0x7c, 0x60, 0x8b, 0x69, 0x8b, 0x75, 0x95, 0x70, 0xa6, + 0x08, 0xdd, 0xf7, 0x7a, 0x05, 0x97, 0x7d, 0x99, 0x85, 0x9d, 0x8b, 0xb2, + 0x8b, 0xa6, 0xa5, 0x8b, 0xb1, 0x8b, 0xb0, 0x78, 0xa6, 0x5f, 0xa3, 0x08, + 0xbb, 0xf7, 0x1c, 0x05, 0xfb, 0x60, 0xfc, 0x60, 0x15, 0x75, 0xb9, 0x82, + 0xb5, 0x8b, 0xc5, 0x08, 0xf1, 0xac, 0xcd, 0xbe, 0xa4, 0x9d, 0x79, 0x73, + 0x1e, 0x8b, 0x88, 0x2b, 0xfb, 0xa1, 0x05, 0x0e, 0xf8, 0x14, 0xf8, 0x09, + 0x15, 0xfb, 0x06, 0x06, 0x78, 0xe0, 0x77, 0xf7, 0x03, 0x8b, 0xa1, 0x08, + 0xb1, 0xa2, 0xa4, 0xac, 0xa7, 0x9b, 0x7c, 0x6f, 0x1e, 0x8b, 0x88, 0x89, + 0x5f, 0x05, 0x89, 0x65, 0xa5, 0x70, 0xb1, 0x8b, 0x08, 0xb5, 0xa5, 0xa7, + 0xb7, 0xd0, 0x51, 0xb7, 0x2e, 0x1f, 0x59, 0x8b, 0x5f, 0x7e, 0x6b, 0x74, + 0x5b, 0x68, 0x6e, 0x4f, 0x8b, 0x4b, 0x8b, 0x6d, 0x8e, 0x72, 0x96, 0x4e, + 0x08, 0x3b, 0x4a, 0xed, 0x06, 0xae, 0x29, 0x8f, 0x7b, 0x8d, 0x66, 0x77, + 0x90, 0x7e, 0x8d, 0x79, 0x8b, 0x08, 0x46, 0x66, 0x6b, 0x4f, 0x55, 0xab, + 0x6c, 0xc3, 0x1f, 0xb8, 0x8b, 0xad, 0x9e, 0xac, 0xb6, 0x08, 0xc1, 0x5a, + 0xa7, 0x7d, 0xb6, 0x8b, 0xb3, 0x8b, 0xab, 0x9c, 0xa0, 0xaa, 0xa0, 0xaa, + 0x95, 0xb2, 0x92, 0xda, 0x08, 0x74, 0x06, 0x7c, 0x55, 0x74, 0x7a, 0x4d, + 0x8b, 0x70, 0x8b, 0x70, 0x91, 0x60, 0x9b, 0x9b, 0xb9, 0x8f, 0xa5, 0x8b, + 0xbb, 0x8b, 0xa0, 0x8a, 0x99, 0x8a, 0x9e, 0x08, 0xf7, 0x01, 0x06, 0xcc, + 0x07, 0xfb, 0x5f, 0xfb, 0xb3, 0x15, 0x7d, 0x5a, 0x76, 0x77, 0x66, 0x8b, + 0x08, 0x6a, 0x74, 0x9f, 0xa8, 0xab, 0xa1, 0x9f, 0xad, 0x1f, 0xa6, 0x8b, + 0x9d, 0x83, 0xa6, 0x73, 0x08, 0x0e, 0xfc, 0x70, 0xf7, 0xa5, 0xf9, 0x44, + 0x15, 0xfc, 0x4d, 0xfd, 0x50, 0xc5, 0x8b, 0xf8, 0x4b, 0xf9, 0x50, 0x53, + 0x8b, 0x05, 0x0e, 0xf8, 0x56, 0xf7, 0xb8, 0x15, 0xbd, 0xfb, 0x03, 0x07, + 0xf7, 0x24, 0xf7, 0xa3, 0x05, 0x98, 0xa3, 0x9c, 0x95, 0xad, 0x8e, 0x08, + 0xa5, 0xfb, 0x61, 0x71, 0x07, 0xcb, 0x88, 0x99, 0x83, 0x8b, 0x6b, 0x8b, + 0x7f, 0x88, 0x7f, 0x86, 0x80, 0x08, 0xfb, 0x0b, 0xfb, 0x7a, 0x7c, 0xa8, + 0x05, 0x7c, 0xab, 0x7c, 0xa6, 0x7f, 0xa3, 0x56, 0xf0, 0x74, 0xbd, 0x8b, + 0x9b, 0x8b, 0xa0, 0x9c, 0x91, 0xc7, 0x8d, 0x08, 0xa5, 0xfb, 0xc1, 0x71, + 0x07, 0xb4, 0x88, 0xa2, 0x7d, 0x9e, 0x67, 0x08, 0xf7, 0x16, 0xfb, 0x93, + 0x28, 0x8b, 0x8b, 0x59, 0xf7, 0x10, 0x8b, 0x96, 0x76, 0x8b, 0x52, 0xfb, + 0x1b, 0x8b, 0x8b, 0x59, 0xf7, 0x1b, 0x8b, 0x8b, 0x5a, 0x05, 0x8b, 0x47, + 0x7a, 0x7c, 0x36, 0x84, 0x08, 0x72, 0xf7, 0xdf, 0xa4, 0x07, 0x38, 0x92, + 0x7b, 0x9a, 0x8b, 0xcf, 0x08, 0xbc, 0xf7, 0x1b, 0xbd, 0xfb, 0x1b, 0xce, + 0x07, 0x8f, 0x96, 0xf7, 0x17, 0x8b, 0x05, 0x0e, 0xd5, 0xf8, 0x1e, 0x15, + 0xf7, 0x08, 0x8b, 0x7e, 0xfc, 0x2a, 0x05, 0x89, 0x47, 0x71, 0x5e, 0x66, + 0x8b, 0x80, 0x8b, 0x80, 0x93, 0x8b, 0x93, 0x8b, 0x8e, 0x8d, 0x8e, 0x90, + 0x91, 0x93, 0x95, 0x8e, 0x92, 0x8b, 0x96, 0x08, 0xa8, 0x75, 0x9f, 0x6c, + 0x6a, 0x75, 0x74, 0x69, 0x5b, 0xaf, 0x6d, 0xc4, 0x1e, 0xf5, 0x8b, 0xd2, + 0xe3, 0xa8, 0xf7, 0x3a, 0x93, 0xb9, 0x8d, 0xa2, 0x98, 0xf7, 0x76, 0x08, + 0xf7, 0x0e, 0xb9, 0xfb, 0x0e, 0xe5, 0x06, 0xec, 0xa1, 0xbc, 0xb5, 0x97, + 0x96, 0x84, 0x83, 0x1e, 0x8b, 0x89, 0x89, 0x87, 0x88, 0x86, 0x83, 0x7f, + 0x86, 0x7d, 0x8b, 0x80, 0x08, 0x72, 0xa4, 0x76, 0xa7, 0xa9, 0xa3, 0xa6, + 0xad, 0xba, 0x62, 0xaa, 0x4e, 0x1e, 0x56, 0x8b, 0x5e, 0x75, 0x6a, 0x60, + 0x69, 0x5e, 0x77, 0x54, 0x7a, 0x26, 0x08, 0xfb, 0x0c, 0x5d, 0x06, 0x0e, + 0xf7, 0x48, 0xf8, 0x33, 0x15, 0x3c, 0x5f, 0x60, 0x3c, 0x1f, 0x8b, 0x48, + 0xa6, 0x69, 0xf7, 0x21, 0xfb, 0x06, 0x08, 0xc4, 0x5d, 0x05, 0xa7, 0x74, + 0x94, 0x7b, 0x8b, 0x6c, 0x08, 0x5c, 0x71, 0x73, 0x56, 0x68, 0x6a, 0x99, + 0x9a, 0x1e, 0x8b, 0x8f, 0x8f, 0x8f, 0x96, 0x92, 0xa2, 0x99, 0x93, 0x97, + 0x8b, 0x9b, 0x08, 0xa9, 0x6d, 0xa5, 0x68, 0x68, 0x6f, 0x6f, 0x66, 0x54, + 0xce, 0x5e, 0xde, 0xea, 0xd0, 0xc1, 0xd6, 0x1e, 0x8b, 0xc1, 0x6f, 0xb4, + 0x41, 0xbf, 0xc1, 0x8c, 0xa6, 0x92, 0xa1, 0x9d, 0x08, 0xa3, 0x9e, 0x99, + 0xaa, 0x8b, 0xaf, 0x8b, 0xaa, 0x84, 0xa7, 0x7e, 0xa1, 0x6d, 0xbe, 0x59, + 0xbc, 0x49, 0xb6, 0x46, 0xb9, 0x68, 0xb2, 0x8b, 0xad, 0x08, 0xb4, 0xad, + 0xa7, 0xbc, 0xa7, 0xa5, 0x81, 0x80, 0x1e, 0x8b, 0x87, 0x85, 0x84, 0x82, + 0x83, 0x79, 0x7d, 0x82, 0x7c, 0x8b, 0x7d, 0x08, 0x70, 0xaa, 0x6d, 0xa8, + 0xad, 0xaa, 0xaa, 0xac, 0xc0, 0x48, 0xb9, 0x3d, 0x34, 0x4d, 0x55, 0x3f, + 0x1e, 0x8b, 0x5b, 0x9d, 0x71, 0xdd, 0x43, 0x08, 0x78, 0x06, 0x91, 0x74, + 0x15, 0xa9, 0x8b, 0xb5, 0x70, 0xcd, 0x4c, 0xac, 0x6c, 0x95, 0x78, 0x8b, + 0x70, 0x8b, 0x69, 0x74, 0x73, 0x6d, 0x8b, 0x6d, 0x8b, 0x76, 0x98, 0x4e, + 0xc0, 0x08, 0x4f, 0xbf, 0x81, 0x9a, 0x8b, 0xaf, 0x8b, 0xab, 0xa2, 0xa3, + 0xaa, 0x8b, 0x08, 0x0e, 0x71, 0xf7, 0x0b, 0x15, 0xc5, 0x51, 0xeb, 0xed, + 0x05, 0xb4, 0x71, 0xb0, 0x80, 0xb7, 0x8b, 0xb7, 0x8b, 0xb0, 0x96, 0xb4, + 0xa5, 0x08, 0xeb, 0x29, 0xc5, 0xc5, 0x29, 0xed, 0x05, 0xa5, 0xaf, 0x96, + 0xb0, 0x8b, 0xba, 0x8b, 0xb9, 0x81, 0xac, 0x70, 0xb6, 0x08, 0xed, 0xed, + 0x51, 0xc3, 0x2b, 0x2b, 0x05, 0x63, 0xa4, 0x67, 0x95, 0x5d, 0x8b, 0x5d, + 0x8b, 0x67, 0x81, 0x63, 0x72, 0x08, 0x2b, 0xeb, 0x51, 0x53, 0xed, 0x29, + 0x05, 0x71, 0x64, 0x80, 0x66, 0x8b, 0x5d, 0x8b, 0x5c, 0x96, 0x68, 0xa5, + 0x65, 0x08, 0x29, 0x29, 0x05, 0xf7, 0xa8, 0xf7, 0xf3, 0x15, 0xd2, 0xc3, + 0x4f, 0x40, 0x44, 0x51, 0x4f, 0x46, 0x44, 0x53, 0xc6, 0xd5, 0xd6, 0xc3, + 0xc5, 0xd2, 0x1f, 0x0e, 0xfc, 0x01, 0xf7, 0x34, 0xf8, 0x28, 0x15, 0xac, + 0xf7, 0x24, 0x96, 0xc1, 0x8b, 0xa1, 0x08, 0xb1, 0x6f, 0xa8, 0x66, 0x65, + 0x71, 0x6f, 0x60, 0x1e, 0x8b, 0x76, 0x97, 0x4b, 0xa0, 0x38, 0x8c, 0x84, + 0x90, 0x77, 0x90, 0x76, 0x08, 0xb4, 0x06, 0x0e, 0xf7, 0x5a, 0xf9, 0x47, + 0x15, 0xfb, 0x08, 0x48, 0x59, 0x49, 0x8b, 0x35, 0x08, 0x46, 0xb4, 0x5c, + 0xc7, 0xbd, 0xac, 0xac, 0xbd, 0xb9, 0x6d, 0xab, 0x60, 0x1e, 0x86, 0x8b, + 0x85, 0x8b, 0x85, 0x8a, 0x88, 0x8a, 0x89, 0x8b, 0x89, 0x8b, 0x80, 0x8b, + 0x83, 0x94, 0x8b, 0x97, 0x8b, 0xb2, 0xad, 0xb5, 0xd6, 0xbf, 0x08, 0x80, + 0xa1, 0x05, 0xf7, 0xa2, 0x16, 0xfb, 0x08, 0x48, 0x59, 0x49, 0x8b, 0x35, + 0x08, 0x46, 0xb4, 0x5c, 0xc7, 0xbd, 0xac, 0xac, 0xbd, 0xb9, 0x6d, 0xab, + 0x60, 0x1e, 0x86, 0x8b, 0x85, 0x8b, 0x85, 0x8a, 0x88, 0x8a, 0x89, 0x8b, + 0x89, 0x8b, 0x80, 0x8b, 0x83, 0x94, 0x8b, 0x97, 0x8b, 0xb2, 0xad, 0xb5, + 0xd6, 0xbf, 0x08, 0x80, 0xa1, 0x05, 0x0e, 0xa2, 0xf7, 0x79, 0x15, 0x8b, + 0x87, 0xf7, 0x62, 0xfb, 0x3a, 0x05, 0x8c, 0x8a, 0x8e, 0x88, 0x8f, 0x88, + 0x97, 0x80, 0x94, 0x86, 0x92, 0x8b, 0x92, 0x8b, 0x90, 0x91, 0x8b, 0x94, + 0x8b, 0x9f, 0x6f, 0xb7, 0x59, 0xc5, 0x7d, 0x9c, 0x80, 0x9a, 0x7c, 0xa1, + 0x95, 0x98, 0x95, 0x98, 0x8f, 0x8f, 0x08, 0xc4, 0xd2, 0xae, 0xc2, 0x8b, + 0xa0, 0x8b, 0x92, 0x87, 0x8f, 0x83, 0x8b, 0x83, 0x8b, 0x83, 0x87, 0x7c, + 0x7e, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x89, 0x08, 0xfb, 0x5f, 0xfb, 0x38, + 0x05, 0xf7, 0x58, 0x16, 0x8b, 0x87, 0xf7, 0x62, 0xfb, 0x3a, 0x05, 0x8c, + 0x8a, 0x8e, 0x88, 0x8f, 0x88, 0x97, 0x80, 0x94, 0x86, 0x92, 0x8b, 0x92, + 0x8b, 0x90, 0x91, 0x8b, 0x94, 0x8b, 0x9f, 0x6f, 0xb7, 0x59, 0xc5, 0x7d, + 0x9c, 0x80, 0x9a, 0x7c, 0xa1, 0x08, 0xa2, 0xa9, 0x05, 0xc5, 0xd2, 0xae, + 0xc2, 0x8b, 0xa0, 0x8b, 0x92, 0x87, 0x8f, 0x83, 0x8b, 0x83, 0x8b, 0x83, + 0x87, 0x7c, 0x7e, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x89, 0x08, 0xfb, 0x5f, + 0xfb, 0x38, 0x05, 0x0e, 0xfb, 0xca, 0xbe, 0xf7, 0x79, 0x15, 0x8b, 0x87, + 0xf7, 0x62, 0xfb, 0x3a, 0x05, 0x8c, 0x8a, 0x8e, 0x88, 0x8f, 0x88, 0x97, + 0x80, 0x94, 0x86, 0x92, 0x8b, 0x92, 0x8b, 0x90, 0x91, 0x8b, 0x94, 0x8b, + 0x9f, 0x6f, 0xb7, 0x59, 0xc5, 0x7d, 0x9c, 0x80, 0x9a, 0x7c, 0xa1, 0x08, + 0xa2, 0xa9, 0x05, 0xc5, 0xd2, 0xae, 0xc2, 0x8b, 0xa0, 0x8b, 0x92, 0x87, + 0x8f, 0x83, 0x8b, 0x83, 0x8b, 0x83, 0x87, 0x7c, 0x7e, 0x8a, 0x8a, 0x89, + 0x89, 0x88, 0x89, 0x08, 0xfb, 0x5f, 0xfb, 0x38, 0x05, 0x0e, 0xfb, 0xca, + 0xda, 0xc5, 0x15, 0xf7, 0x5f, 0xf7, 0x38, 0x8b, 0x8f, 0xfb, 0x62, 0xf7, + 0x3a, 0x05, 0x8a, 0x8c, 0x88, 0x8e, 0x87, 0x8e, 0x7f, 0x96, 0x81, 0x90, + 0x84, 0x8b, 0x85, 0x8b, 0x86, 0x85, 0x8b, 0x82, 0x8b, 0x77, 0xa6, 0x60, + 0xbe, 0x4f, 0x98, 0x7c, 0x97, 0x7b, 0x9a, 0x75, 0x08, 0x74, 0x6d, 0x05, + 0x51, 0x44, 0x68, 0x54, 0x8b, 0x76, 0x8b, 0x84, 0x8f, 0x87, 0x93, 0x8b, + 0x93, 0x8b, 0x92, 0x8e, 0x9b, 0x99, 0x08, 0x91, 0x90, 0x05, 0x0e, 0x34, + 0xf7, 0x66, 0xf8, 0x35, 0x15, 0xf3, 0x06, 0xa5, 0x93, 0x83, 0x71, 0x1f, + 0xfb, 0xc2, 0x07, 0x8b, 0x63, 0x80, 0x7e, 0x67, 0x87, 0x08, 0x73, 0xf7, + 0x7f, 0xa3, 0x07, 0x67, 0x8d, 0x7e, 0x9a, 0x8b, 0xb3, 0x08, 0xf8, 0x1c, + 0x07, 0x30, 0x82, 0x5e, 0x88, 0x68, 0x8b, 0x08, 0x21, 0x06, 0x8b, 0xf4, + 0x8f, 0xae, 0x9a, 0xa6, 0x98, 0xa1, 0xa2, 0x96, 0xac, 0x8b, 0x08, 0xa9, + 0xa3, 0x7f, 0x7c, 0x1f, 0x8b, 0x8a, 0x8a, 0x88, 0x8a, 0x88, 0x86, 0x80, + 0x89, 0x80, 0x8b, 0x7f, 0x08, 0x6b, 0xa5, 0x75, 0xb1, 0xb1, 0xa6, 0xa4, + 0xae, 0xc4, 0x47, 0xae, 0xfb, 0x02, 0x1e, 0x42, 0x8b, 0x53, 0x79, 0x66, + 0x67, 0x63, 0x63, 0x7c, 0x5c, 0x89, 0x32, 0x08, 0x52, 0x5f, 0xc4, 0xfb, + 0xe1, 0x06, 0x8b, 0x60, 0x81, 0x80, 0x5c, 0x85, 0x08, 0x73, 0xf7, 0x87, + 0xa3, 0x07, 0x67, 0x90, 0x80, 0x98, 0x8b, 0xb2, 0x08, 0xf7, 0xe4, 0x07, + 0x0e, 0x34, 0xf7, 0xf0, 0xf8, 0x35, 0x15, 0xfb, 0xe4, 0x07, 0x8b, 0x67, + 0x80, 0x7a, 0x6f, 0x88, 0x08, 0x83, 0x8a, 0x8b, 0x73, 0xf7, 0x7f, 0x8b, + 0x8b, 0xa3, 0x7f, 0x8c, 0x05, 0x72, 0x8d, 0x7f, 0x9d, 0x8b, 0xaf, 0x08, + 0xf8, 0xf5, 0x78, 0x07, 0x5c, 0x6d, 0x05, 0x54, 0xa2, 0x62, 0x93, 0x55, + 0x8b, 0x49, 0x8b, 0x57, 0x77, 0x69, 0x65, 0x6b, 0x67, 0x7e, 0x5e, 0x88, + 0x30, 0x08, 0x52, 0x5f, 0xc4, 0xfb, 0xe1, 0x06, 0x8b, 0x60, 0x81, 0x80, + 0x5c, 0x85, 0x08, 0x73, 0xf7, 0x87, 0xa3, 0x07, 0x67, 0x90, 0x80, 0x98, + 0x8b, 0xb2, 0x08, 0xf7, 0xe4, 0xf7, 0x1e, 0x07, 0xb7, 0x04, 0xfb, 0x1e, + 0xc9, 0x06, 0xf1, 0xa0, 0xac, 0xce, 0xa5, 0x9b, 0x83, 0x7e, 0x1e, 0x8b, + 0x87, 0x89, 0x85, 0x88, 0x84, 0x85, 0x80, 0x89, 0x83, 0x8b, 0x84, 0x8b, + 0x7b, 0x94, 0x7c, 0x97, 0x87, 0x08, 0x29, 0x07, 0x0e, 0xf7, 0xa3, 0x04, + 0x31, 0xf8, 0x88, 0xe5, 0xfc, 0x88, 0x07, 0x0e, 0xf7, 0x99, 0xfb, 0x1a, + 0x15, 0x90, 0xf7, 0x24, 0x05, 0x8d, 0xde, 0xa1, 0xf7, 0x03, 0xa6, 0xc6, + 0x8c, 0x8d, 0x8b, 0x8d, 0x8b, 0x8c, 0x8b, 0x8d, 0x89, 0x8e, 0x87, 0x8f, + 0x6a, 0xb5, 0x77, 0xcd, 0x8d, 0xc8, 0xb1, 0x89, 0x93, 0x88, 0xb3, 0x78, + 0xa5, 0x7d, 0x99, 0x87, 0x9b, 0x8b, 0x08, 0xaa, 0x9e, 0x9f, 0xab, 0xac, + 0x77, 0xa0, 0x6c, 0x1f, 0x7d, 0x8b, 0x7f, 0x87, 0x71, 0x7f, 0x63, 0x79, + 0x7d, 0x86, 0x68, 0x86, 0x8b, 0xc0, 0x8f, 0x99, 0xa3, 0xba, 0x99, 0xa7, + 0x8f, 0x97, 0x8b, 0x9b, 0x08, 0xae, 0x76, 0x9f, 0x68, 0x68, 0x75, 0x74, + 0x66, 0x1e, 0x8b, 0x7c, 0x8e, 0x83, 0x97, 0x76, 0xa2, 0x62, 0x8f, 0x7b, + 0x8d, 0x4b, 0x67, 0x8f, 0x7f, 0x8e, 0x65, 0x9e, 0x72, 0x99, 0x7e, 0x8f, + 0x7c, 0x8b, 0x08, 0x6a, 0x78, 0x78, 0x69, 0x6b, 0x9f, 0x75, 0xa9, 0x1f, + 0x9c, 0x8b, 0x95, 0x8e, 0xa4, 0x98, 0xb0, 0x9f, 0x95, 0x8e, 0xb5, 0x8f, + 0x88, 0x38, 0x85, 0x72, 0x6b, 0x5f, 0x83, 0x80, 0x86, 0x82, 0x8b, 0x87, + 0x8b, 0x87, 0x8d, 0x85, 0x8e, 0x84, 0xa5, 0x4a, 0x9d, 0x2a, 0x8d, 0x3a, + 0x08, 0x90, 0xfb, 0x24, 0xa0, 0x8b, 0x05, 0x0e, 0xf7, 0x71, 0xf8, 0x65, + 0x15, 0x76, 0x8d, 0x80, 0x8f, 0x6a, 0x9a, 0x6e, 0x98, 0x7a, 0x91, 0x7b, + 0x8b, 0x08, 0x6e, 0x77, 0x77, 0x6d, 0x6f, 0xa0, 0x76, 0xa8, 0x1f, 0x99, + 0x8b, 0x98, 0x8f, 0xa5, 0x98, 0xb5, 0x9e, 0x95, 0x8d, 0xb2, 0x8d, 0x89, + 0x4a, 0x80, 0x69, 0x61, 0x47, 0xb4, 0x47, 0x97, 0x66, 0x8d, 0x4c, 0x68, + 0x8d, 0x81, 0x8d, 0x60, 0x9f, 0x70, 0x97, 0x7b, 0x90, 0x7d, 0x8b, 0x08, + 0x6f, 0x76, 0x76, 0x6f, 0x6d, 0x9f, 0x77, 0xa9, 0x1f, 0x9a, 0x8b, 0x9c, + 0x90, 0xa8, 0x99, 0xa7, 0x99, 0xa1, 0x92, 0x9a, 0x8b, 0x08, 0x9d, 0x06, + 0x8a, 0x55, 0x87, 0x7c, 0x76, 0x5a, 0x7e, 0x70, 0x88, 0x80, 0x8b, 0x7c, + 0x08, 0x6b, 0xa0, 0x75, 0xab, 0xab, 0xa3, 0xa3, 0xaa, 0x1e, 0x8b, 0x99, + 0x87, 0x98, 0x7f, 0xa7, 0x74, 0xbe, 0x87, 0x9d, 0x8a, 0xba, 0xb0, 0x87, + 0x98, 0x88, 0xb5, 0x79, 0xa4, 0x7f, 0x99, 0x87, 0x97, 0x8b, 0x08, 0xaa, + 0x9f, 0x9e, 0xa8, 0xaa, 0x79, 0x9d, 0x6d, 0x1f, 0x7a, 0x8b, 0x7e, 0x87, + 0x6f, 0x7e, 0x62, 0x78, 0x7e, 0x88, 0x69, 0x8b, 0x8c, 0xca, 0x99, 0xb9, + 0xab, 0xba, 0x90, 0x91, 0x8d, 0x8f, 0x8b, 0x8d, 0x8b, 0x8e, 0x89, 0x8f, + 0x86, 0x90, 0x6e, 0xb1, 0x79, 0xc6, 0x8b, 0xc5, 0x08, 0xb1, 0x8a, 0x98, + 0x88, 0xb5, 0x78, 0xa4, 0x7f, 0x96, 0x87, 0x9a, 0x8b, 0x08, 0xaa, 0x9e, + 0x9e, 0xa9, 0xa9, 0x77, 0x9e, 0x6d, 0x1f, 0x7e, 0x8b, 0x7d, 0x87, 0x72, + 0x80, 0x60, 0x78, 0x7f, 0x88, 0x66, 0x87, 0x8c, 0xba, 0x8f, 0x9d, 0xa2, + 0xbf, 0x97, 0xa7, 0x8f, 0x98, 0x8b, 0x99, 0x08, 0xaa, 0x73, 0xa3, 0x6b, + 0x6c, 0x75, 0x75, 0x6b, 0x1e, 0x8b, 0x7d, 0x8e, 0x7f, 0x97, 0x71, 0xa1, + 0x58, 0x8f, 0x7b, 0x8c, 0x56, 0x08, 0x79, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, + 0x11, 0xf8, 0x35, 0x15, 0x5d, 0x65, 0x64, 0x5e, 0x5b, 0xaf, 0x66, 0xba, + 0xbb, 0xb1, 0xb0, 0xba, 0xb9, 0x65, 0xb2, 0x5c, 0x1f, 0x0e, 0x24, 0xf7, + 0xb9, 0xf9, 0x1f, 0x15, 0xbd, 0xfd, 0xd9, 0xf7, 0x3f, 0xa4, 0x06, 0x81, + 0x8c, 0x81, 0x8c, 0x88, 0x8b, 0x5b, 0x91, 0x87, 0x90, 0x8a, 0xb2, 0x08, + 0x8a, 0x95, 0x8b, 0xb1, 0x8b, 0xf8, 0xf8, 0x8b, 0xb1, 0x8c, 0x95, 0x05, + 0x8b, 0xb2, 0x91, 0x90, 0xbc, 0x91, 0x8f, 0x8b, 0x96, 0x8c, 0x96, 0x8c, + 0x08, 0xa4, 0xfb, 0xc0, 0x07, 0xfb, 0x2a, 0x46, 0x4e, 0xfb, 0x1a, 0x1f, + 0x8b, 0x32, 0xab, 0x4a, 0xc7, 0x68, 0xa9, 0x79, 0xa5, 0x84, 0xbe, 0x89, + 0x08, 0x8b, 0xfb, 0xda, 0x8b, 0x65, 0x8a, 0x81, 0x05, 0x8b, 0x62, 0x85, + 0x87, 0x41, 0x84, 0x08, 0x72, 0xf7, 0x43, 0xf9, 0xd9, 0x07, 0x2d, 0xfb, + 0xfd, 0x15, 0x40, 0xa6, 0x69, 0xc8, 0x8b, 0xf4, 0x8b, 0xbc, 0x94, 0xb3, + 0x9b, 0xa5, 0x9c, 0xa8, 0x9f, 0x97, 0xba, 0x97, 0x08, 0xfb, 0xfd, 0x07, + 0x0e, 0xfb, 0xb9, 0xf7, 0x44, 0xf8, 0x72, 0x15, 0x3e, 0x4b, 0x4c, 0x3f, + 0x3c, 0xc9, 0x4d, 0xda, 0xd9, 0xc8, 0xc9, 0xd8, 0xda, 0x4d, 0xc9, 0x3e, + 0x1f, 0x0e, 0xfb, 0xca, 0xec, 0xfb, 0x48, 0x15, 0xf7, 0x08, 0xce, 0xbd, + 0xcd, 0x8b, 0xe1, 0x08, 0xd0, 0x62, 0xba, 0x4f, 0x59, 0x6a, 0x6a, 0x59, + 0x1e, 0x5d, 0xa9, 0x6b, 0xb6, 0x1e, 0x90, 0x8b, 0x91, 0x8b, 0x91, 0x8c, + 0x08, 0x8e, 0x8c, 0x8d, 0x8b, 0x8d, 0x8b, 0x96, 0x8b, 0x93, 0x82, 0x8b, + 0x7e, 0x8b, 0x65, 0x69, 0x61, 0x40, 0x57, 0x08, 0x96, 0x75, 0x05, 0x0e, + 0xf7, 0xc2, 0xfb, 0x48, 0x15, 0xf7, 0x08, 0xce, 0xbd, 0xcd, 0x8b, 0xe1, + 0x08, 0xd0, 0x62, 0xba, 0x4f, 0x59, 0x6a, 0x6a, 0x59, 0x1e, 0x5d, 0xa9, + 0x6b, 0xb6, 0x1e, 0x90, 0x8b, 0x91, 0x8b, 0x91, 0x8c, 0x08, 0x8e, 0x8c, + 0x8d, 0x8b, 0x8d, 0x8b, 0x96, 0x8b, 0x93, 0x82, 0x8b, 0x7e, 0x8b, 0x65, + 0x69, 0x61, 0x40, 0x57, 0x08, 0x96, 0x75, 0x05, 0xfb, 0xa2, 0x16, 0xf7, + 0x08, 0xce, 0xbd, 0xcd, 0x8b, 0xe1, 0x08, 0xd0, 0x62, 0xba, 0x4f, 0x59, + 0x6a, 0x6a, 0x59, 0x5d, 0xa9, 0x6b, 0xb6, 0x1e, 0x90, 0x8b, 0x91, 0x8b, + 0x91, 0x8c, 0x8e, 0x8c, 0x8d, 0x8b, 0x8d, 0x8b, 0x96, 0x8b, 0x93, 0x82, + 0x8b, 0x7e, 0x8b, 0x65, 0x69, 0x61, 0x40, 0x57, 0x08, 0x96, 0x75, 0x05, + 0x0e, 0xf7, 0xc2, 0xf7, 0xf8, 0x15, 0xf7, 0x08, 0xce, 0xbd, 0xcd, 0x8b, + 0xe1, 0x08, 0xd0, 0x62, 0xba, 0x4f, 0x59, 0x6a, 0x6a, 0x5a, 0x5b, 0xa8, + 0x6c, 0xb8, 0x1e, 0x90, 0x8b, 0x90, 0x8b, 0x91, 0x8c, 0x8e, 0x8c, 0x8d, + 0x8b, 0x8d, 0x8b, 0x96, 0x8b, 0x93, 0x81, 0x8b, 0x7f, 0x8b, 0x65, 0x68, + 0x61, 0x41, 0x57, 0x08, 0x96, 0x75, 0x05, 0xfb, 0xa2, 0x16, 0xf7, 0x08, + 0xce, 0xbd, 0xcd, 0x8b, 0xe1, 0x08, 0xd0, 0x62, 0xba, 0x4f, 0x59, 0x6a, + 0x6a, 0x5a, 0x5b, 0xa8, 0x6c, 0xb8, 0x1e, 0x90, 0x8b, 0x90, 0x8b, 0x91, + 0x8c, 0x8e, 0x8c, 0x8d, 0x8b, 0x8d, 0x8b, 0x96, 0x8b, 0x93, 0x81, 0x8b, + 0x7f, 0x8b, 0x65, 0x68, 0x61, 0x41, 0x57, 0x08, 0x96, 0x75, 0x05, 0x0e, + 0xd9, 0xc5, 0x15, 0xf7, 0x5f, 0xf7, 0x38, 0x8b, 0x8f, 0xfb, 0x62, 0xf7, + 0x3a, 0x05, 0x8a, 0x8c, 0x88, 0x8e, 0x87, 0x8e, 0x7f, 0x96, 0x81, 0x90, + 0x84, 0x8b, 0x85, 0x8b, 0x86, 0x85, 0x8b, 0x82, 0x8b, 0x77, 0xa6, 0x60, + 0xbe, 0x4f, 0x98, 0x7c, 0x97, 0x7b, 0x9a, 0x75, 0x08, 0x74, 0x6d, 0x05, + 0x51, 0x44, 0x68, 0x54, 0x8b, 0x76, 0x8b, 0x84, 0x8f, 0x87, 0x93, 0x8b, + 0x93, 0x8b, 0x92, 0x8e, 0x9b, 0x99, 0x08, 0x91, 0x90, 0x05, 0xf8, 0x23, + 0xf7, 0x38, 0x15, 0x8b, 0x8f, 0xfb, 0x62, 0xf7, 0x3a, 0x05, 0x89, 0x8c, + 0x88, 0x8e, 0x88, 0x8e, 0x7e, 0x96, 0x82, 0x90, 0x85, 0x8b, 0x84, 0x8b, + 0x86, 0x85, 0x8b, 0x82, 0x8b, 0x77, 0xa6, 0x60, 0xbe, 0x4f, 0x98, 0x7c, + 0x97, 0x7b, 0x9a, 0x75, 0x08, 0x73, 0x6d, 0x05, 0x52, 0x45, 0x68, 0x53, + 0x8b, 0x76, 0x8b, 0x84, 0x8f, 0x87, 0x93, 0x8b, 0x93, 0x8b, 0x91, 0x8e, + 0x9b, 0x99, 0x8f, 0x8e, 0x8d, 0x8c, 0x8c, 0x8c, 0x08, 0xf7, 0x5f, 0xf7, + 0x38, 0x05, 0x0e, 0xf7, 0xf9, 0xf7, 0x3a, 0xf7, 0x30, 0x15, 0x5d, 0x65, + 0x64, 0x5e, 0x5b, 0xaf, 0x66, 0xba, 0xbb, 0xb1, 0xb0, 0xb9, 0xba, 0x65, + 0xb2, 0x5c, 0x1f, 0xf7, 0xe1, 0x16, 0x5d, 0x65, 0x64, 0x5e, 0x5b, 0xaf, + 0x66, 0xba, 0xbb, 0xb1, 0xb0, 0xb9, 0xba, 0x65, 0xb2, 0x5c, 0x1f, 0xf7, + 0xe1, 0x16, 0x5d, 0x65, 0x64, 0x5e, 0x5b, 0xaf, 0x66, 0xba, 0xbb, 0xb1, + 0xb0, 0xb9, 0xba, 0x65, 0xb2, 0x5c, 0x1f, 0x0e, 0xf7, 0xf9, 0xf8, 0xd0, + 0xf9, 0x56, 0x15, 0x5b, 0x06, 0x58, 0x4b, 0x5a, 0x70, 0x49, 0x8b, 0x67, + 0x8b, 0x78, 0x92, 0x6f, 0xa2, 0x71, 0xa0, 0x78, 0x93, 0x71, 0x8b, 0x08, + 0x22, 0x2f, 0x27, 0xfb, 0x05, 0x3a, 0xbf, 0x51, 0xd4, 0x1f, 0xb0, 0x8b, + 0xb0, 0x9b, 0xa7, 0xa7, 0xb4, 0xb4, 0xa8, 0xd9, 0x8b, 0xd0, 0x8b, 0x97, + 0x8a, 0x96, 0x89, 0x9f, 0xa4, 0x81, 0x99, 0x88, 0xa0, 0x8b, 0xb3, 0x8b, + 0xad, 0x97, 0xb2, 0xa9, 0x08, 0xfc, 0x18, 0xfd, 0x23, 0xbb, 0x8b, 0x05, + 0xf8, 0x4a, 0xf9, 0x73, 0x05, 0xfc, 0x02, 0x43, 0x15, 0x90, 0x8b, 0x8f, + 0x89, 0x95, 0x84, 0x96, 0x84, 0x8e, 0x8a, 0x92, 0x88, 0xa5, 0x81, 0x91, + 0x81, 0x8b, 0x69, 0x08, 0x20, 0x4e, 0x26, 0x4b, 0x6a, 0x7a, 0xa3, 0xb8, + 0x1e, 0x8b, 0xe2, 0xc9, 0xf7, 0x15, 0xb4, 0x88, 0x08, 0xf9, 0x42, 0xfb, + 0xc1, 0x15, 0x21, 0x31, 0x29, 0xfb, 0x06, 0x36, 0xbd, 0x55, 0xd8, 0x1f, + 0xb1, 0x8b, 0xaf, 0x9a, 0xa5, 0xa6, 0xb7, 0xb9, 0xa7, 0xd4, 0x8b, 0xd1, + 0x08, 0xd6, 0x64, 0xb8, 0x4b, 0x1e, 0x9e, 0x6a, 0x15, 0xad, 0xa4, 0x68, + 0x5d, 0x1f, 0x8b, 0x59, 0x76, 0x47, 0x6e, 0x61, 0x74, 0x6a, 0x72, 0x7b, + 0x6e, 0x8b, 0x6b, 0x8b, 0x7a, 0xa2, 0x8b, 0xb8, 0x8b, 0xbe, 0xa6, 0xde, + 0xaa, 0xb9, 0x9e, 0xa7, 0x9e, 0x99, 0xa0, 0x8b, 0x08, 0xfc, 0x11, 0xac, + 0x15, 0x24, 0x2e, 0x27, 0xfb, 0x01, 0x35, 0xbd, 0x53, 0xd8, 0x1f, 0xb2, + 0x8b, 0xae, 0x9a, 0xa5, 0xa6, 0xb8, 0xba, 0xa7, 0xd4, 0x8b, 0xd1, 0x08, + 0xd5, 0x64, 0xb8, 0x4a, 0x1e, 0x9f, 0x6a, 0x15, 0xad, 0xa4, 0x68, 0x5d, + 0x1f, 0x8b, 0x58, 0x76, 0x48, 0x6e, 0x61, 0x74, 0x6a, 0x72, 0x7b, 0x6e, + 0x8b, 0x6a, 0x8b, 0x7a, 0xa2, 0x8b, 0xb9, 0x8b, 0xbd, 0xa6, 0xdd, 0xaa, + 0xb9, 0x9f, 0xa8, 0x9e, 0x99, 0xa0, 0x8b, 0x08, 0x0e, 0xf7, 0x8b, 0xf7, + 0x95, 0x15, 0x8b, 0x42, 0x83, 0x7d, 0x4c, 0x64, 0x30, 0x53, 0x6d, 0x62, + 0x8b, 0x46, 0x08, 0x27, 0xdb, 0x49, 0xf7, 0x0c, 0xf7, 0x01, 0xda, 0xc7, + 0xdf, 0xb7, 0x6e, 0xab, 0x64, 0x65, 0x72, 0x71, 0x65, 0x1e, 0x8b, 0x77, + 0x90, 0x7f, 0x9c, 0x78, 0x97, 0x7e, 0x8e, 0x85, 0x8b, 0x81, 0x08, 0x73, + 0x72, 0x7b, 0x67, 0x56, 0x6c, 0xbb, 0xdd, 0x1e, 0x8b, 0xbf, 0x95, 0xad, + 0xac, 0xca, 0xa3, 0xb9, 0x93, 0xa3, 0x8b, 0xa6, 0x8b, 0x92, 0x8b, 0x97, + 0x8a, 0x98, 0x08, 0x8a, 0x99, 0x05, 0x6d, 0x06, 0x9a, 0xf7, 0x88, 0x15, + 0x5b, 0x66, 0x66, 0x5c, 0x5d, 0xb1, 0x64, 0xb9, 0xb9, 0xb2, 0xb2, 0xb8, + 0x1f, 0xbb, 0x66, 0xb0, 0x5c, 0x1e, 0x0e, 0xfb, 0xca, 0xf7, 0x8a, 0xf8, + 0xa4, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, 0x78, 0x95, 0x78, + 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, 0x96, 0x7d, 0xa8, + 0x79, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, 0xfb, 0xca, 0xe1, + 0xf8, 0xa4, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, 0x93, + 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x78, 0x8b, 0x7a, + 0x82, 0x7a, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xfb, 0xca, + 0xf7, 0xaa, 0xf8, 0xa4, 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, + 0x8b, 0xfb, 0x0e, 0xfb, 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, + 0x29, 0x05, 0x0e, 0xfb, 0xca, 0xa5, 0xf8, 0xb9, 0x15, 0x8f, 0xa7, 0x9e, + 0x9e, 0xa5, 0x8b, 0x98, 0x8b, 0x93, 0x88, 0xb6, 0x78, 0x08, 0xa8, 0x7e, + 0x05, 0x9e, 0x83, 0xa4, 0x85, 0x9f, 0x8b, 0xc4, 0x8b, 0xb0, 0xb3, 0xa2, + 0xe2, 0x08, 0x60, 0x06, 0x7e, 0x67, 0x7d, 0x7e, 0x70, 0x8b, 0x80, 0x8b, + 0x87, 0x8c, 0x73, 0x96, 0x08, 0x63, 0x9d, 0x05, 0x6f, 0x98, 0x73, 0x91, + 0x76, 0x8b, 0x4d, 0x8b, 0x67, 0x64, 0x79, 0x35, 0x08, 0xb5, 0x06, 0x0e, + 0xfb, 0xca, 0xf7, 0xdf, 0xf9, 0x11, 0x15, 0xfb, 0xde, 0x43, 0xf7, 0xde, + 0xd3, 0x06, 0x0e, 0xfb, 0xca, 0xf7, 0xa6, 0xf9, 0x47, 0x15, 0x7a, 0x4c, + 0x6e, 0x73, 0x4d, 0x8b, 0x4b, 0x8b, 0x6b, 0xa5, 0x80, 0xc8, 0x08, 0x5f, + 0x06, 0x8e, 0x54, 0x92, 0x72, 0xa0, 0x6f, 0xa4, 0x67, 0xb5, 0x78, 0xc0, + 0x8b, 0xc2, 0x8b, 0xb4, 0x9f, 0xa5, 0xb4, 0x9c, 0xa5, 0x92, 0xa4, 0x91, + 0xbe, 0x08, 0x5f, 0x06, 0x0e, 0xfb, 0xca, 0xf7, 0x3a, 0xf9, 0x2e, 0x15, + 0x6a, 0x6d, 0x6d, 0x6a, 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, + 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xfb, 0xca, 0xc9, 0xf9, 0x2e, 0x15, + 0x69, 0x6d, 0x6d, 0x69, 0x68, 0xa8, 0x6d, 0xae, 0xaf, 0xa8, 0xa7, 0xae, + 0xaf, 0x6d, 0xa9, 0x68, 0x1f, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, + 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, + 0x1f, 0x0e, 0xfb, 0xca, 0xf7, 0x3b, 0xf9, 0x82, 0x15, 0x51, 0x5a, 0x5a, + 0x53, 0x4f, 0xba, 0x5b, 0xc6, 0xc6, 0xbb, 0xba, 0xc6, 0xc5, 0x5b, 0xbc, + 0x51, 0x1f, 0x8a, 0x5b, 0x15, 0xab, 0xa6, 0x6f, 0x6b, 0x6c, 0x70, 0x71, + 0x6a, 0x6c, 0x71, 0xa5, 0xab, 0xaa, 0xa6, 0xa7, 0xaa, 0x1f, 0x0e, 0xfb, + 0xca, 0xf7, 0x08, 0x2b, 0x15, 0x96, 0x83, 0x05, 0x96, 0x8e, 0x93, 0x8c, + 0x94, 0x8b, 0x08, 0xa8, 0x9c, 0x7d, 0x75, 0x71, 0x76, 0x7c, 0x67, 0x1f, + 0x7a, 0x8b, 0x7d, 0x8e, 0x74, 0x94, 0x08, 0x85, 0x8d, 0x7b, 0x66, 0x05, + 0xaf, 0x7e, 0xa6, 0x86, 0xac, 0x8b, 0x08, 0xdb, 0xbd, 0xad, 0xc2, 0xb7, + 0x6a, 0xa5, 0x54, 0x1f, 0x7e, 0x8b, 0x83, 0x8a, 0x7f, 0x87, 0x08, 0xa7, + 0xcb, 0x61, 0x8b, 0x60, 0x2b, 0x05, 0x0e, 0xfb, 0xca, 0x7e, 0xf8, 0xa4, + 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, 0x93, 0x95, 0x8b, + 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x78, 0x8b, 0x7a, 0x82, 0x7a, + 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0xf7, 0x5c, 0x16, 0xc3, 0x8b, + 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, 0x93, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, + 0x78, 0x9d, 0x6e, 0x8b, 0x78, 0x8b, 0x7a, 0x82, 0x7a, 0x78, 0x08, 0xfb, + 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0x32, 0xab, 0x15, 0x87, + 0x85, 0x89, 0x89, 0x83, 0x81, 0x62, 0x59, 0x7e, 0x71, 0x8b, 0x6d, 0x8b, + 0x5c, 0xb8, 0x69, 0xc8, 0x8b, 0xbd, 0x8b, 0xbb, 0xa8, 0xa4, 0xb9, 0x08, + 0x75, 0x99, 0x05, 0x86, 0x89, 0x8a, 0x8a, 0x83, 0x87, 0x77, 0x81, 0x80, + 0x88, 0x7c, 0x8b, 0x62, 0x8b, 0x75, 0xa2, 0x8b, 0xb4, 0x8b, 0x98, 0x8f, + 0x9e, 0x93, 0xab, 0x8e, 0x95, 0x8c, 0x8e, 0x8c, 0x92, 0x08, 0x6a, 0x7f, + 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0xe3, 0xf9, 0x54, 0x15, 0x52, 0x8b, 0xfb, + 0x04, 0x28, 0xfb, 0x04, 0xee, 0x53, 0x8b, 0xf7, 0x0e, 0xfb, 0x44, 0xe7, + 0x8b, 0xf7, 0x0f, 0xf7, 0x44, 0x05, 0x0e, 0xf7, 0xf9, 0xf7, 0xa3, 0x04, + 0x31, 0xfa, 0x7c, 0xe5, 0xfe, 0x7c, 0x07, 0x0e, 0xf7, 0xf9, 0xf8, 0x44, + 0xf7, 0xc3, 0x15, 0xfb, 0x4c, 0x07, 0x8b, 0x41, 0x7c, 0x7b, 0x42, 0x87, + 0x08, 0x72, 0xf8, 0xca, 0x07, 0xb4, 0xf7, 0x67, 0x74, 0x8b, 0x05, 0x83, + 0x6d, 0x69, 0x58, 0x69, 0x68, 0x63, 0x61, 0x50, 0x78, 0x36, 0x8b, 0x08, + 0x4f, 0x7b, 0x96, 0xb6, 0x1f, 0xf7, 0x87, 0x07, 0xf7, 0x04, 0x84, 0xa4, + 0x71, 0x9d, 0xfb, 0x10, 0x08, 0xa2, 0xf7, 0xe6, 0x74, 0x06, 0x6f, 0xfb, + 0x15, 0x81, 0x81, 0xfb, 0x09, 0x81, 0x08, 0xf7, 0x8c, 0x07, 0xa3, 0x99, + 0x91, 0xc1, 0x1e, 0xe7, 0x8b, 0xc7, 0x7a, 0xa7, 0x68, 0xa0, 0x71, 0x95, + 0x73, 0x98, 0x4b, 0x08, 0xa4, 0xf7, 0x5d, 0xfd, 0x0e, 0x75, 0x06, 0xcd, + 0x87, 0xa0, 0x82, 0x8b, 0x73, 0x8b, 0x81, 0x82, 0x77, 0x78, 0x6b, 0x89, + 0x88, 0x89, 0x86, 0x88, 0x86, 0x08, 0xfb, 0x69, 0xfc, 0x19, 0x05, 0x4c, + 0xfb, 0x05, 0x83, 0x82, 0x64, 0x85, 0x08, 0x72, 0xf7, 0x62, 0x07, 0x8b, + 0xa4, 0x7a, 0x8d, 0x05, 0x57, 0x91, 0x7d, 0x95, 0x8b, 0xa6, 0x8b, 0x97, + 0x8f, 0x98, 0x96, 0x9f, 0x08, 0xef, 0xf7, 0x50, 0x05, 0xf7, 0x52, 0x06, + 0xfb, 0x3c, 0xb3, 0x15, 0xf7, 0x35, 0xf7, 0xb6, 0x92, 0x8b, 0x8b, 0xfb, + 0xb6, 0xfb, 0x3c, 0x8b, 0x05, 0x0e, 0xfb, 0xeb, 0xf7, 0xb7, 0xf8, 0x4f, + 0x15, 0x85, 0x85, 0x05, 0x8a, 0x8a, 0x89, 0x8a, 0x88, 0x8b, 0x08, 0x83, + 0x88, 0x8f, 0x96, 0x1f, 0xf7, 0x30, 0x07, 0xbd, 0x5a, 0xab, 0x3d, 0x3d, + 0x58, 0x6e, 0x5d, 0x72, 0x9b, 0x7c, 0xa5, 0xa7, 0x9f, 0x99, 0xa0, 0x1e, + 0x8b, 0x91, 0x88, 0x92, 0x83, 0x93, 0x85, 0x91, 0x88, 0x90, 0x8b, 0x8e, + 0x08, 0x97, 0x9e, 0x95, 0xa1, 0x1e, 0xaf, 0x99, 0x7c, 0x66, 0x1f, 0x63, + 0x07, 0xfb, 0x1b, 0x68, 0x64, 0x72, 0x8b, 0x59, 0x8b, 0x64, 0xa9, 0x70, + 0xb7, 0x8b, 0xb1, 0x8b, 0xa8, 0x97, 0xae, 0xa8, 0x92, 0x6d, 0x99, 0x80, + 0xab, 0x8b, 0xa8, 0x8b, 0x9f, 0x94, 0xa3, 0xa4, 0x08, 0x81, 0x97, 0x05, + 0xfb, 0x0b, 0xa1, 0x15, 0x7d, 0x79, 0x7e, 0x83, 0x7b, 0x8b, 0x78, 0x8b, + 0x7e, 0x9c, 0x8b, 0xa2, 0x8b, 0xad, 0xa4, 0xa3, 0xbd, 0x9a, 0x08, 0x34, + 0x07, 0x0e, 0xa3, 0xf9, 0x12, 0xf7, 0x77, 0x15, 0x6e, 0x06, 0x6a, 0x3d, + 0x77, 0x6c, 0x68, 0x6b, 0x62, 0x66, 0x53, 0x79, 0x3e, 0x8b, 0x08, 0x4e, + 0x78, 0x98, 0xb6, 0x1f, 0x8b, 0xf7, 0xba, 0xf7, 0x0f, 0xd7, 0x8b, 0xc8, + 0xfb, 0x0f, 0x3f, 0x8b, 0xf7, 0x09, 0x05, 0x8b, 0xd6, 0x99, 0x98, 0xe2, + 0x8f, 0x08, 0xa4, 0xfb, 0xf1, 0x72, 0x07, 0xcf, 0x87, 0x9d, 0x7b, 0x8b, + 0x58, 0x08, 0x8b, 0xfb, 0x7d, 0x3a, 0x5a, 0x8b, 0x4e, 0xdc, 0xbc, 0x8b, + 0xfb, 0x52, 0x05, 0x8b, 0x58, 0x7e, 0x80, 0x42, 0x82, 0x08, 0x72, 0xf8, + 0xd6, 0x07, 0xb4, 0xf7, 0x77, 0x05, 0x0e, 0xf7, 0x1b, 0xf9, 0x41, 0xf9, + 0x75, 0x15, 0x59, 0x8b, 0x4c, 0x2e, 0x05, 0x4c, 0xad, 0x58, 0x98, 0x47, + 0x8b, 0xfb, 0x63, 0x8b, 0xfb, 0x28, 0xfb, 0x29, 0x8b, 0xfb, 0x63, 0x8b, + 0x5a, 0x94, 0x5c, 0x9c, 0x5f, 0xa2, 0x4f, 0xa3, 0x6b, 0xc6, 0x58, 0x08, + 0x35, 0xfb, 0x12, 0xbd, 0x8b, 0xd2, 0xf3, 0x05, 0xca, 0x68, 0xbf, 0x7d, + 0xd3, 0x8b, 0xf7, 0x63, 0x8b, 0xf7, 0x27, 0xf7, 0x27, 0x8b, 0xf7, 0x64, + 0x8b, 0xcf, 0x7b, 0xcb, 0x6c, 0xc2, 0x75, 0xb1, 0x78, 0xa0, 0x5b, 0xb3, + 0x08, 0xd9, 0xf7, 0x07, 0x05, 0xfc, 0x57, 0xfc, 0xde, 0x15, 0x7a, 0xc8, + 0x86, 0xb5, 0x8b, 0xd5, 0x8b, 0xf7, 0x67, 0xcb, 0xf7, 0x0b, 0xf7, 0x05, + 0x8b, 0xc6, 0x8b, 0xb0, 0x72, 0xae, 0x4b, 0x08, 0xfb, 0xb2, 0xfc, 0x36, + 0x05, 0xf7, 0xc6, 0xf8, 0x09, 0x15, 0x9f, 0x4a, 0x91, 0x5b, 0x8b, 0x3b, + 0x8b, 0xfb, 0x63, 0x4e, 0xfb, 0x02, 0xfb, 0x08, 0x8b, 0x4c, 0x8b, 0x64, + 0xa5, 0x69, 0xcb, 0x08, 0xf7, 0xb3, 0xf8, 0x38, 0x05, 0x0e, 0xf7, 0xf9, + 0xfa, 0x69, 0xf7, 0x67, 0x15, 0x70, 0x06, 0x6a, 0x46, 0x76, 0x6d, 0x67, + 0x6e, 0x61, 0x6a, 0x59, 0x7c, 0x43, 0x8b, 0x08, 0x50, 0x7d, 0x94, 0xb2, + 0x1f, 0xf7, 0x8e, 0x07, 0xf5, 0x85, 0xa9, 0x6b, 0x9a, 0xfb, 0x0b, 0x08, + 0xa2, 0xf7, 0xe6, 0x74, 0x06, 0x71, 0xfb, 0x13, 0x79, 0x79, 0x20, 0x88, + 0x08, 0xf7, 0x8d, 0x07, 0x9f, 0x98, 0x91, 0xb5, 0x1e, 0xd2, 0x8b, 0xc8, + 0x80, 0xa8, 0x79, 0xb4, 0x71, 0x9b, 0x6b, 0x99, 0x3c, 0x08, 0xa5, 0xf7, + 0x5d, 0xfc, 0x30, 0x06, 0x86, 0x06, 0x2e, 0x90, 0x56, 0x8e, 0x7e, 0x8b, + 0xfb, 0x5f, 0x8b, 0xfb, 0x1f, 0xfb, 0x22, 0x8b, 0xfb, 0x64, 0x8b, 0xfb, + 0x04, 0xb5, 0x29, 0xd4, 0x4f, 0xc2, 0x5e, 0xd8, 0x73, 0xe4, 0x8b, 0x99, + 0x8b, 0x9a, 0x8c, 0x9a, 0x8c, 0x08, 0xa2, 0x8d, 0xae, 0x8c, 0xbc, 0x8b, + 0x08, 0xf8, 0x42, 0x8b, 0x05, 0xb5, 0xf7, 0x67, 0x05, 0xfc, 0x91, 0x8c, + 0x15, 0x8b, 0x27, 0x87, 0x6a, 0x7a, 0x76, 0x7a, 0x75, 0x73, 0x82, 0x5f, + 0x8b, 0x48, 0x8b, 0x63, 0xa0, 0x70, 0xbb, 0x73, 0xb5, 0x7b, 0xe6, 0x8b, + 0xe6, 0x8b, 0xf7, 0x70, 0xca, 0xf7, 0x04, 0xf7, 0x0e, 0x8b, 0xaf, 0x8b, + 0xa6, 0x81, 0x99, 0x77, 0x08, 0x99, 0x76, 0x8f, 0x71, 0x8b, 0x43, 0x08, + 0xfb, 0xb7, 0x07, 0x0e, 0xfb, 0xcd, 0xf7, 0x39, 0xf9, 0x44, 0x15, 0x37, + 0x4c, 0x4d, 0x37, 0x38, 0xc9, 0x4d, 0xde, 0xe2, 0xc9, 0xc7, 0xe1, 0xde, + 0x4c, 0xc9, 0x37, 0x1f, 0x76, 0x04, 0xb0, 0x97, 0x6c, 0x27, 0x32, 0x7e, + 0x6d, 0x66, 0x67, 0x7e, 0xab, 0xe4, 0xec, 0x97, 0xab, 0xb1, 0x1f, 0x0e, + 0xda, 0xf9, 0x34, 0xf7, 0x14, 0x15, 0x64, 0x5b, 0x68, 0x78, 0x5a, 0x8b, + 0x08, 0x3a, 0x69, 0xbc, 0xf7, 0x07, 0x1f, 0xa2, 0xf7, 0x92, 0x07, 0x8b, + 0xc9, 0x86, 0xa9, 0x7a, 0xae, 0x6d, 0xc8, 0x4e, 0xb0, 0x41, 0x8b, 0x57, + 0x8b, 0x65, 0x7c, 0x66, 0x67, 0x08, 0x65, 0xb0, 0x65, 0x99, 0x49, 0x8b, + 0x08, 0x22, 0x3e, 0x56, 0x43, 0x64, 0xa6, 0x72, 0xb5, 0xb3, 0xa2, 0xa0, + 0xaf, 0x1f, 0x8b, 0x9e, 0x87, 0x94, 0x7e, 0x9a, 0x82, 0x95, 0x88, 0x90, + 0x8b, 0x92, 0x08, 0x9f, 0xa6, 0x9a, 0xb1, 0xc3, 0xa1, 0x74, 0x51, 0x1e, + 0x3b, 0x07, 0xfb, 0x15, 0x61, 0x5e, 0x7a, 0x6b, 0x74, 0x64, 0x70, 0x79, + 0x6a, 0x8b, 0x5f, 0x8b, 0x45, 0xb4, 0x65, 0xd8, 0x8b, 0xcc, 0x8b, 0xc6, + 0xa6, 0xc3, 0xc3, 0x08, 0x91, 0x91, 0x05, 0xb1, 0x4d, 0xb2, 0x75, 0xd1, + 0x8b, 0xea, 0x8b, 0xc2, 0xab, 0xc6, 0xe5, 0x08, 0x76, 0x9a, 0x05, 0xfc, + 0x0c, 0x5c, 0x15, 0x73, 0x72, 0x7c, 0x84, 0x74, 0x8b, 0x66, 0x8b, 0x77, + 0xa4, 0x8b, 0xba, 0x8b, 0xc9, 0xaa, 0xac, 0xe3, 0xab, 0x08, 0xfb, 0x3b, + 0x07, 0xf7, 0x1e, 0xf7, 0x60, 0x15, 0xf7, 0x0a, 0x9d, 0xb3, 0xbf, 0xba, + 0x9b, 0x6b, 0x2e, 0x1e, 0x6a, 0xfb, 0x19, 0x07, 0x0e, 0xfc, 0x01, 0xf7, + 0x64, 0xf8, 0x61, 0x15, 0xfb, 0x54, 0x73, 0x06, 0xb7, 0x82, 0x94, 0x82, + 0x8b, 0x62, 0x08, 0xfb, 0xba, 0x07, 0x8b, 0x62, 0x84, 0x83, 0x5d, 0x80, + 0x08, 0x73, 0xf7, 0x83, 0xa3, 0x07, 0x68, 0x90, 0x7f, 0x99, 0x8b, 0xb1, + 0x08, 0xf8, 0x10, 0x07, 0x0e, 0xfc, 0x01, 0xf7, 0x62, 0xf8, 0x24, 0x15, + 0xec, 0xdb, 0x8b, 0xbd, 0x2a, 0x3b, 0x8b, 0xf7, 0x76, 0xfb, 0x52, 0x8b, + 0x8b, 0x73, 0x05, 0xae, 0x88, 0x9b, 0x79, 0x8b, 0x66, 0x08, 0x8b, 0xfb, + 0x7d, 0x32, 0x43, 0x8b, 0x59, 0xe4, 0xd3, 0x8b, 0xfb, 0x77, 0x05, 0x8b, + 0x66, 0x7a, 0x77, 0x69, 0x88, 0x08, 0x73, 0xf7, 0x83, 0xa3, 0x07, 0x6a, + 0x8c, 0x7b, 0x9e, 0x8b, 0xb3, 0x08, 0xf7, 0xd0, 0x07, 0x0e, 0xf8, 0x61, + 0xf8, 0xb9, 0x15, 0x5d, 0x8b, 0x4f, 0x26, 0x05, 0x68, 0x9d, 0x6d, 0x92, + 0x65, 0x8b, 0xfb, 0x16, 0x8b, 0x2a, 0x23, 0x8b, 0xfb, 0x20, 0x8b, 0x3c, + 0xa4, 0x51, 0xc7, 0x53, 0x08, 0x3f, 0xfb, 0x14, 0xba, 0x8b, 0xca, 0xf4, + 0x05, 0xaf, 0x78, 0xaa, 0x83, 0xb3, 0x8b, 0xf7, 0x15, 0x8b, 0xeb, 0xf2, + 0x8b, 0xf7, 0x20, 0x8b, 0xdd, 0x70, 0xc7, 0x4e, 0xc2, 0x08, 0xd4, 0xf7, + 0x0f, 0x05, 0xfb, 0xb4, 0xfc, 0x2d, 0x15, 0x8a, 0x9f, 0x8b, 0xa1, 0x8b, + 0xa7, 0x8b, 0xf7, 0x48, 0x9d, 0xbf, 0xc9, 0x8b, 0xac, 0x8b, 0x9d, 0x7a, + 0x98, 0x60, 0x08, 0xfb, 0x23, 0xfb, 0x86, 0x05, 0xf7, 0x2e, 0xf7, 0x4c, + 0x15, 0x8c, 0x5c, 0x8c, 0x6d, 0x8b, 0x6f, 0x8b, 0xfb, 0x29, 0x77, 0x56, + 0x51, 0x8b, 0x68, 0x8b, 0x77, 0x9d, 0x7e, 0xb8, 0x08, 0xf7, 0x24, 0xf7, + 0x88, 0x05, 0x0e, 0xda, 0xf9, 0x38, 0xf7, 0x11, 0x15, 0x5e, 0x57, 0x70, + 0x7c, 0x5d, 0x8b, 0x3e, 0x8b, 0x64, 0xc5, 0x8d, 0xf7, 0x01, 0x08, 0x8b, + 0x8e, 0x8b, 0x9c, 0xf7, 0x8d, 0x8b, 0x05, 0x87, 0xd0, 0x84, 0xac, 0x78, + 0xaf, 0x6c, 0xc6, 0x53, 0xaa, 0x41, 0x8b, 0x59, 0x8b, 0x6d, 0x80, 0x5a, + 0x65, 0x68, 0xae, 0x67, 0x99, 0x55, 0x8b, 0x08, 0xfb, 0x18, 0x2d, 0x25, + 0xfb, 0x22, 0x1f, 0xfb, 0x24, 0xe6, 0x28, 0xf7, 0x18, 0x1e, 0xc4, 0x8b, + 0xb4, 0x99, 0xb3, 0xad, 0x08, 0xa9, 0x69, 0xac, 0x7d, 0xbf, 0x8b, 0xdf, + 0x8b, 0xbc, 0xa9, 0xcc, 0xe8, 0x08, 0x77, 0x9b, 0x05, 0xfb, 0x7c, 0xf7, + 0x31, 0x15, 0xc1, 0x07, 0xd2, 0xa2, 0xb0, 0xb5, 0x1e, 0xb3, 0x8b, 0x9c, + 0x6c, 0x8e, 0x40, 0x8b, 0x81, 0x8c, 0x76, 0x8c, 0x72, 0x08, 0xfb, 0x13, + 0x06, 0xfb, 0x1c, 0xfb, 0x19, 0x15, 0x2f, 0x77, 0x62, 0x5d, 0x53, 0x78, + 0xc5, 0xf7, 0x42, 0xf7, 0x2a, 0x9c, 0xb9, 0xc2, 0xbd, 0x9e, 0x66, 0x2b, + 0x1e, 0xfb, 0x36, 0x07, 0x0e, 0x34, 0xd1, 0xe2, 0x15, 0x8b, 0x5d, 0x83, + 0x81, 0x60, 0x84, 0x08, 0x73, 0xf7, 0x52, 0xf8, 0xde, 0x07, 0xbd, 0xa0, + 0xa6, 0xb1, 0xbd, 0xa0, 0x64, 0x2d, 0x1e, 0x8b, 0x28, 0x7e, 0x74, 0x52, + 0x8a, 0x08, 0x69, 0x07, 0xac, 0x89, 0x9b, 0x86, 0x9a, 0x7f, 0x08, 0xa5, + 0x74, 0x97, 0x5a, 0x8b, 0x34, 0x8b, 0xfb, 0x18, 0x7d, 0x63, 0x5c, 0x8b, + 0x82, 0x8b, 0x87, 0x8c, 0x82, 0x91, 0x08, 0x81, 0x92, 0x7d, 0x69, 0x05, + 0xa9, 0x80, 0x9b, 0x87, 0x9d, 0x8b, 0xf4, 0x8b, 0xdf, 0xe7, 0x8b, 0xf7, + 0x06, 0x8b, 0xc0, 0x7a, 0xb7, 0x6a, 0xaa, 0x6b, 0xaa, 0x69, 0x9b, 0x3a, + 0xa3, 0xbc, 0x96, 0xa1, 0x94, 0xa5, 0x9d, 0x08, 0xb1, 0xa5, 0xa0, 0xb1, + 0x8b, 0xb5, 0x08, 0xe3, 0x36, 0xcd, 0xfb, 0x06, 0xfb, 0x0d, 0x35, 0x3e, + 0x20, 0x1e, 0xfc, 0x38, 0x07, 0x0e, 0xda, 0xf9, 0x45, 0xa4, 0x15, 0x87, + 0x06, 0x64, 0x8b, 0x7b, 0xa0, 0x59, 0xf7, 0x0a, 0x08, 0xfb, 0x73, 0xf8, + 0xa2, 0x6f, 0x8b, 0xfb, 0x72, 0xfc, 0xb8, 0x05, 0x65, 0x2e, 0x7f, 0x7c, + 0x5b, 0x82, 0x08, 0x72, 0xf7, 0x5f, 0xa4, 0x07, 0x50, 0x8f, 0x74, 0x96, + 0x8b, 0xa5, 0x8b, 0x98, 0x93, 0xa4, 0xa0, 0xc1, 0x08, 0x9a, 0xb2, 0xf7, + 0x75, 0x8b, 0x05, 0xad, 0x3d, 0x97, 0x67, 0x8b, 0x75, 0x8b, 0x76, 0x7e, + 0x81, 0x68, 0x89, 0x86, 0x8b, 0x7e, 0x8a, 0x7d, 0x89, 0x08, 0x72, 0xf7, + 0xd8, 0xa4, 0x07, 0xfc, 0x88, 0xf7, 0x67, 0x15, 0xe9, 0xf7, 0x87, 0xf0, + 0xfb, 0x87, 0xfb, 0x57, 0x8b, 0x05, 0xbc, 0xf9, 0x14, 0x15, 0x69, 0x6d, + 0x6d, 0x69, 0x67, 0xa8, 0x6e, 0xae, 0xaf, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, + 0xa9, 0x68, 0x1f, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, 0x66, 0xa7, + 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, + 0xda, 0xf9, 0x45, 0xa4, 0x15, 0x87, 0x06, 0x64, 0x8b, 0x7b, 0xa0, 0x59, + 0xf7, 0x0a, 0x08, 0xfb, 0x73, 0xf8, 0xa2, 0x6f, 0x8b, 0xfb, 0x72, 0xfc, + 0xb8, 0x05, 0x65, 0x2e, 0x7f, 0x7c, 0x5b, 0x82, 0x08, 0x72, 0xf7, 0x5f, + 0xa4, 0x07, 0x50, 0x8f, 0x74, 0x96, 0x8b, 0xa5, 0x8b, 0x98, 0x93, 0xa4, + 0xa0, 0xc1, 0x08, 0x9a, 0xb2, 0xf7, 0x75, 0x8b, 0x05, 0xad, 0x3d, 0x97, + 0x67, 0x8b, 0x75, 0x8b, 0x76, 0x7e, 0x81, 0x68, 0x89, 0x86, 0x8b, 0x7e, + 0x8a, 0x7d, 0x89, 0x08, 0x72, 0xf7, 0xd8, 0xa4, 0x07, 0xfc, 0x88, 0xf7, + 0x67, 0x15, 0xe9, 0xf7, 0x87, 0xf0, 0xfb, 0x87, 0xfb, 0x57, 0x8b, 0x05, + 0xd4, 0xf8, 0x8a, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, + 0x93, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x77, 0x8b, + 0x7a, 0x82, 0x7b, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xda, + 0xf9, 0x45, 0xa4, 0x15, 0x87, 0x06, 0x64, 0x8b, 0x7b, 0xa0, 0x59, 0xf7, + 0x0a, 0x08, 0xfb, 0x73, 0xf8, 0xa2, 0x6f, 0x8b, 0xfb, 0x72, 0xfc, 0xb8, + 0x05, 0x65, 0x2e, 0x7f, 0x7c, 0x5b, 0x82, 0x08, 0x72, 0xf7, 0x5f, 0xa4, + 0x07, 0x50, 0x8f, 0x74, 0x96, 0x8b, 0xa5, 0x8b, 0x98, 0x93, 0xa4, 0xa0, + 0xc1, 0x08, 0x9a, 0xb2, 0xf7, 0x75, 0x8b, 0x05, 0xad, 0x3d, 0x97, 0x67, + 0x8b, 0x75, 0x8b, 0x76, 0x7e, 0x81, 0x68, 0x89, 0x86, 0x8b, 0x7e, 0x8a, + 0x7d, 0x89, 0x08, 0x72, 0xf7, 0xd8, 0xa4, 0x07, 0xfc, 0x88, 0xf7, 0x67, + 0x15, 0xe9, 0xf7, 0x87, 0xf0, 0xfb, 0x87, 0xfb, 0x57, 0x8b, 0x05, 0xf7, + 0x89, 0xf8, 0x8a, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, 0x78, + 0x95, 0x78, 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, 0x96, + 0x7d, 0xa8, 0x79, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, 0xda, + 0xf9, 0x45, 0xa4, 0x15, 0x87, 0x06, 0x64, 0x8b, 0x7b, 0xa0, 0x59, 0xf7, + 0x0a, 0x08, 0xfb, 0x73, 0xf8, 0xa2, 0x6f, 0x8b, 0xfb, 0x72, 0xfc, 0xb8, + 0x05, 0x65, 0x2e, 0x7f, 0x7c, 0x5b, 0x82, 0x08, 0x72, 0xf7, 0x5f, 0xa4, + 0x07, 0x50, 0x8f, 0x74, 0x96, 0x8b, 0xa5, 0x8b, 0x98, 0x93, 0xa4, 0xa0, + 0xc1, 0x08, 0x9a, 0xb2, 0xf7, 0x75, 0x8b, 0x05, 0xad, 0x3d, 0x97, 0x67, + 0x8b, 0x75, 0x8b, 0x76, 0x7e, 0x81, 0x68, 0x89, 0x86, 0x8b, 0x7e, 0x8a, + 0x7d, 0x89, 0x08, 0x72, 0xf7, 0xd8, 0xa4, 0x07, 0xfc, 0x88, 0xf7, 0x67, + 0x15, 0xe9, 0xf7, 0x87, 0xf0, 0xfb, 0x87, 0xfb, 0x57, 0x8b, 0x05, 0xf7, + 0x9e, 0xf8, 0x8a, 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, 0x8b, + 0xfb, 0x0e, 0xfb, 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, 0x29, + 0x05, 0x0e, 0xda, 0xf9, 0x45, 0xa4, 0x15, 0x87, 0x06, 0x64, 0x8b, 0x7b, + 0xa0, 0x59, 0xf7, 0x0a, 0x08, 0xfb, 0x73, 0xf8, 0xa2, 0x6f, 0x8b, 0xfb, + 0x72, 0xfc, 0xb8, 0x05, 0x65, 0x2e, 0x7f, 0x7c, 0x5b, 0x82, 0x08, 0x72, + 0xf7, 0x5f, 0xa4, 0x07, 0x50, 0x8f, 0x74, 0x96, 0x8b, 0xa5, 0x8b, 0x98, + 0x93, 0xa4, 0xa0, 0xc1, 0x08, 0x9a, 0xb2, 0xf7, 0x75, 0x8b, 0x05, 0xad, + 0x3d, 0x97, 0x67, 0x8b, 0x75, 0x8b, 0x76, 0x7e, 0x81, 0x68, 0x89, 0x86, + 0x8b, 0x7e, 0x8a, 0x7d, 0x89, 0x08, 0x72, 0xf7, 0xd8, 0x07, 0xa4, 0x07, + 0xfc, 0x88, 0xf7, 0x67, 0x15, 0xe9, 0xf7, 0x87, 0xf0, 0xfb, 0x87, 0xfb, + 0x57, 0x8b, 0x05, 0xa0, 0xf8, 0x9f, 0x15, 0x8f, 0xa7, 0x9f, 0x9e, 0xa5, + 0x8b, 0x98, 0x8b, 0x92, 0x88, 0xb6, 0x78, 0x08, 0xa8, 0x7e, 0x05, 0x9e, + 0x83, 0xa5, 0x85, 0x9e, 0x8b, 0xc4, 0x8b, 0xb0, 0xb3, 0xa2, 0xe2, 0x08, + 0x60, 0x06, 0x7f, 0x67, 0x7d, 0x7e, 0x70, 0x8b, 0x7f, 0x8b, 0x88, 0x8c, + 0x72, 0x96, 0x08, 0x63, 0x9d, 0x05, 0x6f, 0x98, 0x73, 0x91, 0x76, 0x8b, + 0x4e, 0x8b, 0x66, 0x64, 0x79, 0x35, 0x08, 0xb5, 0x06, 0x0e, 0xda, 0xf9, + 0x45, 0xa4, 0x15, 0x5f, 0x8b, 0x80, 0x99, 0x55, 0xf7, 0x11, 0x08, 0xfb, + 0x73, 0xf8, 0xa2, 0x6f, 0x8b, 0xfb, 0x72, 0xfc, 0xb8, 0x05, 0x65, 0x2d, + 0x7f, 0x7d, 0x5b, 0x82, 0x08, 0x72, 0xf7, 0x5f, 0xa4, 0x07, 0x4f, 0x8f, + 0x75, 0x96, 0x8b, 0xa5, 0x8b, 0x9a, 0x91, 0x9c, 0xb1, 0xee, 0x08, 0xf7, + 0x75, 0x06, 0xad, 0x3d, 0x97, 0x67, 0x8b, 0x75, 0x8b, 0x75, 0x7e, 0x82, + 0x68, 0x89, 0x86, 0x8a, 0x7e, 0x8a, 0x7d, 0x8a, 0x08, 0x72, 0xf7, 0xd8, + 0xa4, 0x07, 0xfc, 0x88, 0xf7, 0x67, 0x15, 0xe9, 0xf7, 0x87, 0xf0, 0xfb, + 0x87, 0xfb, 0x57, 0x8b, 0x05, 0xf7, 0x2d, 0xf9, 0x5c, 0x15, 0x51, 0x5a, + 0x5a, 0x53, 0x4f, 0xba, 0x5b, 0xc6, 0xc6, 0xbb, 0xba, 0xc6, 0xc5, 0x5b, + 0xbc, 0x51, 0x1f, 0x8a, 0x5b, 0x15, 0xab, 0xa6, 0x6f, 0x6b, 0x6c, 0x70, + 0x71, 0x6a, 0x6c, 0x71, 0xa5, 0xab, 0xaa, 0xa6, 0xa7, 0xaa, 0x1f, 0x0e, + 0xda, 0xf8, 0x25, 0x78, 0x15, 0xf7, 0x09, 0x8c, 0xd6, 0xb1, 0xe9, 0xf6, + 0x08, 0x6d, 0xa4, 0x05, 0x50, 0x4d, 0x6b, 0x73, 0x5a, 0x78, 0x6e, 0x7f, + 0x6a, 0x85, 0x6f, 0x8b, 0x49, 0x8b, 0x4c, 0xae, 0x6e, 0xbf, 0x6e, 0xc0, + 0x7d, 0xd3, 0x8b, 0xef, 0x8b, 0xf7, 0x63, 0xcb, 0xf7, 0x02, 0xf7, 0x0c, + 0x8b, 0xba, 0x8b, 0xb6, 0x79, 0xb6, 0x65, 0x08, 0xb6, 0x64, 0xa2, 0x6a, + 0xae, 0x3f, 0x08, 0xa4, 0xf7, 0x7e, 0x70, 0x06, 0x7d, 0x68, 0x80, 0x80, + 0x78, 0x8b, 0x82, 0x8b, 0x7c, 0x8f, 0x75, 0x95, 0x50, 0xa3, 0x5b, 0x96, + 0x5b, 0x8b, 0xfb, 0x5b, 0x8b, 0xfb, 0x29, 0xfb, 0x2e, 0x8b, 0xfb, 0x61, + 0x8b, 0xfb, 0x50, 0xf7, 0x11, 0xfb, 0x22, 0xf7, 0x4a, 0x79, 0x08, 0x8e, + 0x8a, 0x68, 0x3c, 0x96, 0x83, 0x05, 0x96, 0x8e, 0x93, 0x8c, 0x94, 0x8b, + 0x08, 0xa8, 0x9c, 0x7d, 0x75, 0x71, 0x76, 0x7c, 0x66, 0x1f, 0x7b, 0x8b, + 0x7f, 0x8e, 0x72, 0x94, 0x08, 0x85, 0x8d, 0x7b, 0x66, 0x05, 0xaf, 0x7e, + 0xa6, 0x86, 0xac, 0x8b, 0x08, 0xdb, 0xbd, 0xad, 0xc2, 0xb7, 0x6a, 0xa5, + 0x54, 0x1f, 0x7e, 0x8b, 0x83, 0x8a, 0x7f, 0x87, 0x08, 0x9f, 0xb8, 0x05, + 0x0e, 0xda, 0x91, 0xf7, 0xda, 0x15, 0xe6, 0xfb, 0x7f, 0x06, 0x8b, 0x5f, + 0x72, 0x77, 0x51, 0x89, 0x08, 0x72, 0xf7, 0xd0, 0x07, 0xf7, 0x6c, 0xf7, + 0x24, 0xf7, 0x1e, 0xf7, 0x63, 0xf7, 0x62, 0xfb, 0x20, 0xf7, 0x11, 0xfb, + 0x7b, 0x1f, 0xfb, 0xc5, 0x06, 0x72, 0x07, 0xcb, 0x85, 0x9e, 0x7c, 0x8b, + 0x5d, 0x08, 0xfb, 0x67, 0x30, 0x07, 0x5c, 0x07, 0xf8, 0x03, 0xba, 0x15, + 0xfb, 0x06, 0xf7, 0x72, 0x06, 0x8b, 0x9c, 0x8c, 0x93, 0x8f, 0x90, 0x08, + 0x93, 0x96, 0x9e, 0x91, 0xa7, 0x8b, 0xd2, 0x8b, 0xbe, 0x6a, 0xad, 0x46, + 0xa6, 0x56, 0x99, 0x42, 0x8b, 0x37, 0x8b, 0x2c, 0x77, 0x35, 0x6b, 0x5e, + 0x69, 0x5d, 0x5b, 0x74, 0x4a, 0x8b, 0x08, 0x5e, 0x7e, 0x98, 0xb8, 0x1f, + 0xf7, 0x7d, 0xf7, 0x06, 0xba, 0x07, 0x0e, 0xa3, 0xf8, 0xe5, 0xf9, 0x38, + 0x15, 0xfc, 0xd5, 0x06, 0x72, 0x07, 0xd0, 0x87, 0x9e, 0x7b, 0x8b, 0x58, + 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x57, 0x7d, 0x80, 0x41, 0x83, 0x08, 0x72, + 0xf8, 0xdd, 0x07, 0xb3, 0xf7, 0x64, 0x6f, 0x8b, 0x05, 0x6c, 0x48, 0x77, + 0x6f, 0x67, 0x6e, 0x5d, 0x66, 0x54, 0x7b, 0x3f, 0x8b, 0x08, 0x4b, 0x78, + 0x98, 0xb6, 0x1f, 0xf7, 0x86, 0x07, 0xf7, 0x01, 0x8b, 0xb4, 0x64, 0x97, + 0xfb, 0x08, 0x08, 0xa5, 0xf7, 0xe6, 0x71, 0x06, 0x7c, 0xfb, 0x06, 0x64, + 0x67, 0xfb, 0x00, 0x8c, 0x08, 0xf7, 0x7c, 0x07, 0xb1, 0x98, 0x94, 0xbf, + 0x1e, 0xf7, 0x37, 0x8b, 0xbc, 0x69, 0xa4, 0xfb, 0x19, 0x08, 0xa4, 0x06, + 0xf7, 0x5d, 0x07, 0xfc, 0x07, 0xf7, 0x5c, 0x15, 0x69, 0x6d, 0x6d, 0x69, + 0x67, 0xa8, 0x6e, 0xae, 0xaf, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x68, + 0x1f, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, 0x66, 0xa7, 0x6e, 0xae, + 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xa3, 0xf8, + 0xe5, 0xf9, 0x38, 0x15, 0xfc, 0xd5, 0x06, 0x72, 0x07, 0xd0, 0x87, 0x9e, + 0x7b, 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x57, 0x7d, 0x80, 0x41, + 0x83, 0x08, 0x72, 0xf8, 0xdd, 0x07, 0xb3, 0xf7, 0x64, 0x6f, 0x8b, 0x05, + 0x6c, 0x48, 0x77, 0x6f, 0x67, 0x6e, 0x5d, 0x66, 0x54, 0x7b, 0x3f, 0x8b, + 0x08, 0x4b, 0x78, 0x98, 0xb6, 0x1f, 0xf7, 0x86, 0x07, 0xf7, 0x01, 0x8b, + 0xb4, 0x64, 0x97, 0xfb, 0x08, 0x08, 0xa5, 0xf7, 0xe6, 0x71, 0x06, 0x7c, + 0xfb, 0x06, 0x64, 0x67, 0xfb, 0x00, 0x8c, 0x08, 0xf7, 0x7c, 0x07, 0xb1, + 0x98, 0x94, 0xbf, 0x1e, 0xf7, 0x37, 0x8b, 0xbc, 0x69, 0xa4, 0xfb, 0x19, + 0x08, 0xa4, 0x06, 0xf7, 0x5d, 0x07, 0xfb, 0xee, 0xc9, 0x15, 0xc3, 0x8b, + 0xf7, 0x22, 0xe3, 0x05, 0xac, 0x9f, 0x92, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, + 0x78, 0x9d, 0x6e, 0x8b, 0x77, 0x8b, 0x7a, 0x82, 0x7b, 0x78, 0x08, 0xfb, + 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xa3, 0xf8, 0xe5, 0xf9, 0x38, 0x15, 0xfc, + 0xd5, 0x06, 0x72, 0x07, 0xd0, 0x87, 0x9e, 0x7b, 0x8b, 0x58, 0x08, 0xfc, + 0x78, 0x07, 0x8b, 0x57, 0x7d, 0x80, 0x41, 0x83, 0x08, 0x72, 0xf8, 0xdd, + 0x07, 0xb3, 0xf7, 0x64, 0x6f, 0x8b, 0x05, 0x6c, 0x48, 0x77, 0x6f, 0x67, + 0x6e, 0x5d, 0x66, 0x54, 0x7b, 0x3f, 0x8b, 0x08, 0x4b, 0x78, 0x98, 0xb6, + 0x1f, 0xf7, 0x86, 0x07, 0xf7, 0x01, 0x8b, 0xb4, 0x64, 0x97, 0xfb, 0x08, + 0x08, 0xa5, 0xf7, 0xe6, 0x71, 0x06, 0x7c, 0xfb, 0x06, 0x64, 0x67, 0xfb, + 0x00, 0x8c, 0x08, 0xf7, 0x7c, 0x07, 0xb1, 0x98, 0x94, 0xbf, 0x1e, 0xf7, + 0x37, 0x8b, 0xbc, 0x69, 0xa4, 0xfb, 0x19, 0x08, 0xa4, 0x06, 0xf7, 0x5d, + 0x07, 0xfb, 0x4e, 0xc9, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, + 0x77, 0x95, 0x78, 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, + 0x96, 0x7e, 0xa9, 0x78, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, + 0xa3, 0xf8, 0xe5, 0xf9, 0x38, 0x15, 0xfc, 0xd5, 0x06, 0x72, 0x07, 0xd0, + 0x87, 0x9e, 0x7b, 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, 0x8b, 0x57, 0x7d, + 0x80, 0x41, 0x83, 0x08, 0x72, 0xf8, 0xdd, 0x07, 0xb3, 0xf7, 0x64, 0x6f, + 0x8b, 0x05, 0x6c, 0x48, 0x77, 0x6f, 0x67, 0x6e, 0x5d, 0x66, 0x54, 0x7b, + 0x3f, 0x8b, 0x08, 0x4b, 0x78, 0x98, 0xb6, 0x1f, 0xf7, 0x86, 0x07, 0xf7, + 0x01, 0x8b, 0xb4, 0x64, 0x97, 0xfb, 0x08, 0x08, 0xa5, 0xf7, 0xe6, 0x71, + 0x06, 0x7c, 0xfb, 0x06, 0x64, 0x67, 0xfb, 0x00, 0x8c, 0x08, 0xf7, 0x7c, + 0x07, 0xb1, 0x98, 0x94, 0xbf, 0x1e, 0xf7, 0x37, 0x8b, 0xbc, 0x69, 0xa4, + 0xfb, 0x19, 0x08, 0xa4, 0x06, 0xf7, 0x5d, 0x07, 0xfb, 0x2e, 0xc9, 0x15, + 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, 0x8b, 0xfb, 0x0e, 0xfb, 0x44, + 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, 0x29, 0x05, 0x0e, 0xfb, 0x92, + 0xf7, 0x05, 0xeb, 0x15, 0x8b, 0x59, 0x79, 0x7d, 0x40, 0x84, 0x08, 0x72, + 0xf7, 0xf2, 0xa4, 0x07, 0x3f, 0x90, 0x78, 0x99, 0x8b, 0xbf, 0x08, 0xf8, + 0x78, 0x07, 0x8b, 0xbf, 0xa0, 0x9b, 0xd5, 0x8e, 0x08, 0xa4, 0xfb, 0xf2, + 0x72, 0x07, 0xd3, 0x86, 0xa0, 0x7c, 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, + 0x74, 0xf9, 0xa0, 0x15, 0x69, 0x6d, 0x6d, 0x69, 0x67, 0xa8, 0x6e, 0xae, + 0xaf, 0xa8, 0xa7, 0xae, 0x1f, 0xaf, 0x6d, 0xa9, 0x68, 0x1e, 0xf7, 0x65, + 0x16, 0x6a, 0x6d, 0x6d, 0x6a, 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, + 0xae, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xfb, 0x92, 0xf7, 0x05, 0xeb, + 0x15, 0x8b, 0x59, 0x79, 0x7d, 0x40, 0x84, 0x08, 0x72, 0xf7, 0xf2, 0xa4, + 0x07, 0x3f, 0x90, 0x78, 0x99, 0x8b, 0xbf, 0x08, 0xf8, 0x78, 0x07, 0x8b, + 0xbf, 0xa0, 0x9b, 0xd5, 0x8e, 0x08, 0xa4, 0xfb, 0xf2, 0x72, 0x07, 0xd3, + 0x86, 0xa0, 0x7c, 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, 0x8c, 0xf9, 0x16, + 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, 0x93, 0x95, 0x8b, + 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x78, 0x8b, 0x7a, 0x82, 0x7a, + 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xfb, 0x92, 0xf7, 0x05, + 0xeb, 0x15, 0x8b, 0x59, 0x79, 0x7d, 0x40, 0x84, 0x08, 0x72, 0xf7, 0xf2, + 0xa4, 0x07, 0x3f, 0x90, 0x78, 0x99, 0x8b, 0xbf, 0x08, 0xf8, 0x78, 0x07, + 0x8b, 0xbf, 0xa0, 0x9b, 0xd5, 0x8e, 0x08, 0xa4, 0xfb, 0xf2, 0x72, 0x07, + 0xd3, 0x86, 0xa0, 0x7c, 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, 0xf7, 0x2f, + 0xf9, 0x16, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, 0x77, 0x95, + 0x78, 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, 0x96, 0x7e, + 0xa9, 0x78, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, 0xfb, 0x92, + 0xf7, 0x05, 0xeb, 0x15, 0x8b, 0x59, 0x79, 0x7d, 0x40, 0x84, 0x08, 0x72, + 0xf7, 0xf2, 0xa4, 0x07, 0x3f, 0x90, 0x78, 0x99, 0x8b, 0xbf, 0x08, 0xf8, + 0x78, 0x07, 0x8b, 0xbf, 0xa0, 0x9b, 0xd5, 0x8e, 0x08, 0xa4, 0xfb, 0xf2, + 0x72, 0x07, 0xd3, 0x86, 0xa0, 0x7c, 0x8b, 0x58, 0x08, 0xfc, 0x78, 0x07, + 0xf7, 0x55, 0xf9, 0x16, 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, + 0x8b, 0xfb, 0x0e, 0xfb, 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, + 0x29, 0x05, 0x0e, 0xda, 0xf7, 0x7a, 0xf9, 0x38, 0x15, 0xfb, 0x67, 0x72, + 0x06, 0x9f, 0x8b, 0x9c, 0x7c, 0xbb, 0x52, 0x08, 0xfc, 0x6e, 0x07, 0x8b, + 0x52, 0x7c, 0x7d, 0x42, 0x82, 0x08, 0x72, 0xf7, 0x77, 0xa4, 0x07, 0x3e, + 0x94, 0x79, 0x9e, 0x8b, 0xd2, 0x08, 0x8b, 0xf8, 0x26, 0x05, 0xf8, 0x53, + 0xfc, 0xb4, 0xa7, 0x8b, 0x8b, 0xf8, 0xe1, 0x05, 0x8b, 0xc4, 0x98, 0x98, + 0xcc, 0x95, 0x08, 0xa4, 0xfb, 0x6b, 0x72, 0x07, 0xd5, 0x84, 0x9e, 0x76, + 0x8b, 0x44, 0x08, 0x8b, 0xfb, 0xc5, 0x05, 0xfb, 0xf1, 0xf8, 0x41, 0x05, + 0x7b, 0xde, 0x15, 0x8f, 0xa7, 0x9e, 0x9e, 0xa5, 0x8b, 0x98, 0x8b, 0x93, + 0x88, 0xb6, 0x78, 0x08, 0xa8, 0x7e, 0x05, 0x9e, 0x83, 0xa4, 0x85, 0x9f, + 0x8b, 0xc4, 0x8b, 0xb0, 0xb3, 0xa2, 0xe2, 0x08, 0x60, 0x06, 0x7e, 0x67, + 0x7d, 0x7e, 0x70, 0x8b, 0x80, 0x8b, 0x87, 0x8c, 0x73, 0x96, 0x08, 0x63, + 0x9d, 0x05, 0x6f, 0x98, 0x73, 0x91, 0x76, 0x8b, 0x4d, 0x8b, 0x67, 0x64, + 0x79, 0x35, 0x08, 0xb5, 0x06, 0x0e, 0xf7, 0x1b, 0xf8, 0x1d, 0xf9, 0x47, + 0x15, 0xfb, 0x65, 0xfb, 0x29, 0xfb, 0x28, 0xfb, 0x64, 0xfb, 0x63, 0xf7, + 0x27, 0xfb, 0x27, 0xf7, 0x63, 0xf7, 0x63, 0xf7, 0x27, 0xf7, 0x28, 0xf7, + 0x63, 0xf7, 0x60, 0xfb, 0x29, 0xf7, 0x2b, 0xfb, 0x5d, 0x1f, 0x8a, 0x6a, + 0x15, 0xf7, 0x02, 0xcb, 0xfb, 0x0d, 0xfb, 0x64, 0xfb, 0x61, 0x4d, 0xfb, + 0x02, 0xfb, 0x07, 0xfb, 0x07, 0x4d, 0xf7, 0x02, 0xf7, 0x5e, 0xf7, 0x6c, + 0xca, 0xf7, 0x08, 0xf7, 0x09, 0x1f, 0xfb, 0x06, 0xf7, 0x6e, 0x15, 0x69, + 0x6d, 0x6d, 0x69, 0x67, 0xa8, 0x6e, 0xae, 0xaf, 0xa8, 0xa7, 0xae, 0xaf, + 0x6d, 0xa9, 0x68, 0x1f, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, 0x66, + 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, + 0x0e, 0xf7, 0x1b, 0xf8, 0x1d, 0xf9, 0x47, 0x15, 0xfb, 0x65, 0xfb, 0x29, + 0xfb, 0x28, 0xfb, 0x64, 0xfb, 0x63, 0xf7, 0x27, 0xfb, 0x27, 0xf7, 0x63, + 0xf7, 0x63, 0xf7, 0x27, 0xf7, 0x28, 0xf7, 0x63, 0xf7, 0x60, 0xfb, 0x29, + 0xf7, 0x2b, 0xfb, 0x5d, 0x1f, 0x8a, 0x6a, 0x15, 0xf7, 0x02, 0xcb, 0xfb, + 0x0d, 0xfb, 0x64, 0xfb, 0x61, 0x4d, 0xfb, 0x02, 0xfb, 0x07, 0xfb, 0x07, + 0x4d, 0xf7, 0x02, 0xf7, 0x5e, 0xf7, 0x6c, 0xca, 0xf7, 0x08, 0xf7, 0x09, + 0x1f, 0x31, 0xdb, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, + 0x93, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x78, 0x8b, + 0x7a, 0x82, 0x7a, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xf7, + 0x1b, 0xf8, 0x1d, 0xf9, 0x47, 0x15, 0xfb, 0x65, 0xfb, 0x29, 0xfb, 0x28, + 0xfb, 0x64, 0xfb, 0x63, 0xf7, 0x27, 0xfb, 0x27, 0xf7, 0x63, 0xf7, 0x63, + 0xf7, 0x27, 0xf7, 0x28, 0xf7, 0x63, 0xf7, 0x60, 0xfb, 0x29, 0xf7, 0x2b, + 0xfb, 0x5d, 0x1f, 0x8a, 0x6a, 0x15, 0xf7, 0x02, 0xcb, 0xfb, 0x0d, 0xfb, + 0x64, 0xfb, 0x61, 0x4d, 0xfb, 0x02, 0xfb, 0x07, 0xfb, 0x07, 0x4d, 0xf7, + 0x02, 0xf7, 0x5e, 0xf7, 0x6c, 0xca, 0xf7, 0x08, 0xf7, 0x09, 0x1f, 0xd1, + 0xdb, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, 0x78, 0x95, 0x78, + 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, 0x96, 0x7d, 0xa8, + 0x79, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, 0xf7, 0x1b, 0xf8, + 0x1d, 0xf9, 0x47, 0x15, 0xfb, 0x65, 0xfb, 0x29, 0xfb, 0x28, 0xfb, 0x64, + 0xfb, 0x63, 0xf7, 0x27, 0xfb, 0x27, 0xf7, 0x63, 0xf7, 0x63, 0xf7, 0x27, + 0xf7, 0x28, 0xf7, 0x63, 0xf7, 0x60, 0xfb, 0x29, 0xf7, 0x2b, 0xfb, 0x5d, + 0x1f, 0x8a, 0x6a, 0x15, 0xf7, 0x02, 0xcb, 0xfb, 0x0d, 0xfb, 0x64, 0xfb, + 0x61, 0x4d, 0xfb, 0x02, 0xfb, 0x07, 0xfb, 0x07, 0x4d, 0xf7, 0x02, 0xf7, + 0x5e, 0xf7, 0x6c, 0xca, 0xf7, 0x08, 0xf7, 0x09, 0x1f, 0xf1, 0xdb, 0x15, + 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, 0x8b, 0xfb, 0x0e, 0xfb, 0x44, + 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, 0x29, 0x05, 0x0e, 0xf7, 0x1b, + 0xf8, 0x1d, 0xf9, 0x47, 0x15, 0xfb, 0x65, 0xfb, 0x29, 0xfb, 0x28, 0xfb, + 0x64, 0xfb, 0x63, 0xf7, 0x27, 0xfb, 0x27, 0xf7, 0x63, 0xf7, 0x63, 0xf7, + 0x27, 0xf7, 0x28, 0xf7, 0x63, 0x1f, 0xf7, 0x60, 0xfb, 0x29, 0xf7, 0x2b, + 0xfb, 0x5d, 0x1e, 0x8a, 0x6a, 0x15, 0xf7, 0x02, 0xcb, 0xfb, 0x0d, 0xfb, + 0x64, 0xfb, 0x61, 0x4d, 0xfb, 0x02, 0xfb, 0x07, 0xfb, 0x07, 0x4d, 0xf7, + 0x02, 0xf7, 0x5e, 0xf7, 0x6c, 0xca, 0xf7, 0x08, 0xf7, 0x09, 0x1f, 0xfb, + 0x2a, 0xf0, 0x15, 0x8f, 0xa7, 0x9e, 0x9e, 0xa5, 0x8b, 0x98, 0x8b, 0x93, + 0x88, 0xb6, 0x78, 0x08, 0xa8, 0x7e, 0x05, 0x9e, 0x83, 0xa4, 0x85, 0x9f, + 0x8b, 0xc4, 0x8b, 0xb0, 0xb3, 0xa2, 0xe2, 0x08, 0x60, 0x06, 0x7e, 0x67, + 0x7d, 0x7e, 0x70, 0x8b, 0x80, 0x8b, 0x87, 0x8c, 0x73, 0x96, 0x08, 0x63, + 0x9d, 0x05, 0x6f, 0x98, 0x73, 0x91, 0x76, 0x8b, 0x4d, 0x8b, 0x67, 0x64, + 0x79, 0x35, 0x08, 0xb5, 0x06, 0x0e, 0x34, 0xf8, 0x78, 0xf8, 0x6f, 0x15, + 0xf7, 0x6d, 0x6d, 0x07, 0x84, 0x71, 0x83, 0x83, 0x7a, 0x8b, 0x82, 0x8b, + 0x80, 0x8e, 0x75, 0x93, 0x5c, 0x9b, 0x6b, 0x91, 0x65, 0x8b, 0xfb, 0x1c, + 0x8b, 0x38, 0x3e, 0x8b, 0xfb, 0x12, 0x8b, 0x33, 0xbf, 0x4c, 0xf7, 0x0b, + 0x52, 0x08, 0xce, 0x6b, 0x05, 0xe3, 0x61, 0xa3, 0x71, 0x8b, 0x57, 0x8b, + 0x46, 0x5a, 0x5e, 0x3e, 0x8b, 0x51, 0x8b, 0x59, 0xa4, 0x65, 0xbc, 0x70, + 0xb0, 0x7d, 0xac, 0x7a, 0xd1, 0x08, 0x6e, 0xfb, 0x8b, 0xa8, 0x06, 0x91, + 0xa4, 0x93, 0x94, 0x9b, 0x8b, 0x93, 0x8b, 0x96, 0x88, 0xa1, 0x84, 0xbd, + 0x7a, 0xb0, 0x84, 0xb6, 0x8b, 0xf7, 0x28, 0x8b, 0xef, 0xe0, 0x8b, 0xf7, + 0x12, 0x8b, 0xd6, 0x5d, 0xd6, 0x4b, 0xab, 0x08, 0xfb, 0x27, 0xd4, 0x05, + 0x3a, 0xb3, 0x75, 0xa4, 0x8b, 0xbb, 0x8b, 0xc9, 0xb5, 0xb1, 0xcf, 0x8b, + 0xb8, 0x8b, 0xb5, 0x78, 0xaf, 0x66, 0xad, 0x68, 0x9b, 0x6e, 0x9f, 0x4a, + 0x08, 0xa7, 0x06, 0x66, 0xf8, 0x4b, 0x15, 0x52, 0x8b, 0xfb, 0x04, 0x28, + 0xfb, 0x04, 0xee, 0x53, 0x8b, 0xf7, 0x0e, 0xfb, 0x44, 0xe7, 0x8b, 0xf7, + 0x0f, 0xf7, 0x44, 0x05, 0x0e, 0xda, 0xf9, 0x03, 0xf8, 0xca, 0x15, 0x8b, + 0xc6, 0x99, 0x9b, 0xcb, 0x95, 0x08, 0xa4, 0xfb, 0x70, 0x72, 0x07, 0xd9, + 0x85, 0x9f, 0x77, 0x8b, 0x42, 0x08, 0xfb, 0xc5, 0x07, 0xfb, 0x28, 0x53, + 0x46, 0xfb, 0x0b, 0x25, 0x5e, 0xc6, 0xf7, 0x1c, 0x1e, 0xf7, 0xe2, 0x07, + 0x8b, 0xb3, 0x91, 0xa1, 0x9a, 0x99, 0x97, 0x95, 0x9b, 0x8f, 0xbb, 0x8d, + 0x08, 0xa4, 0xfb, 0xe6, 0x72, 0x07, 0xd1, 0x84, 0x97, 0x7e, 0x8b, 0x43, + 0x08, 0xfb, 0xe2, 0x07, 0x8b, 0x29, 0xa0, 0x5a, 0xc8, 0x5f, 0xbb, 0x68, + 0xcb, 0x79, 0xd4, 0x8b, 0xd5, 0x8b, 0xd1, 0xa1, 0xb6, 0xb0, 0xb8, 0xb1, + 0xa5, 0xd7, 0x8b, 0xe8, 0x08, 0xf7, 0xd3, 0x07, 0xfb, 0xed, 0xf7, 0xca, + 0x15, 0x69, 0x6d, 0x6d, 0x69, 0x67, 0xa8, 0x6e, 0xae, 0xaf, 0xa8, 0xa7, + 0xae, 0x1f, 0xaf, 0x6d, 0xa9, 0x68, 0x1e, 0xf7, 0x65, 0x16, 0x6a, 0x6d, + 0x6d, 0x6a, 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, + 0xa9, 0x67, 0x1f, 0x0e, 0xda, 0xf9, 0x03, 0xf8, 0xca, 0x15, 0x8b, 0xc6, + 0x99, 0x9b, 0xcb, 0x95, 0x08, 0xa4, 0xfb, 0x70, 0x72, 0x07, 0xd9, 0x85, + 0x9f, 0x77, 0x8b, 0x42, 0x08, 0xfb, 0xc5, 0x07, 0xfb, 0x28, 0x53, 0x46, + 0xfb, 0x0b, 0x25, 0x5e, 0xc6, 0xf7, 0x1c, 0x1e, 0xf7, 0xe2, 0x07, 0x8b, + 0xb3, 0x91, 0xa1, 0x9a, 0x99, 0x97, 0x95, 0x9b, 0x8f, 0xbb, 0x8d, 0x08, + 0xa4, 0xfb, 0xe6, 0x72, 0x07, 0xd1, 0x84, 0x97, 0x7e, 0x8b, 0x43, 0x08, + 0xfb, 0xe2, 0x07, 0x8b, 0x29, 0xa0, 0x5a, 0xc8, 0x5f, 0xbb, 0x68, 0xcb, + 0x79, 0xd4, 0x8b, 0xd5, 0x8b, 0xd1, 0xa1, 0xb6, 0xb0, 0xb8, 0xb1, 0xa5, + 0xd7, 0x8b, 0xe8, 0x08, 0xf7, 0xd3, 0x07, 0xfb, 0xce, 0xf7, 0x40, 0x15, + 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, 0x93, 0x95, 0x8b, 0xa2, + 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x78, 0x8b, 0x7a, 0x82, 0x7a, 0x78, + 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xda, 0xf9, 0x03, 0xf8, 0xca, + 0x15, 0x8b, 0xc6, 0x99, 0x9b, 0xcb, 0x95, 0x08, 0xa4, 0xfb, 0x70, 0x72, + 0x07, 0xd9, 0x85, 0x9f, 0x77, 0x8b, 0x42, 0x08, 0xfb, 0xc5, 0x07, 0xfb, + 0x28, 0x53, 0x46, 0xfb, 0x0b, 0x25, 0x5e, 0xc6, 0xf7, 0x1c, 0x1e, 0xf7, + 0xe2, 0x07, 0x8b, 0xb3, 0x91, 0xa1, 0x9a, 0x99, 0x97, 0x95, 0x9b, 0x8f, + 0xbb, 0x8d, 0x08, 0xa4, 0xfb, 0xe6, 0x72, 0x07, 0xd1, 0x84, 0x97, 0x7e, + 0x8b, 0x43, 0x08, 0xfb, 0xe2, 0x07, 0x8b, 0x29, 0xa0, 0x5a, 0xc8, 0x5f, + 0xbb, 0x68, 0xcb, 0x79, 0xd4, 0x8b, 0xd5, 0x8b, 0xd1, 0xa1, 0xb6, 0xb0, + 0xb8, 0xb1, 0xa5, 0xd7, 0x8b, 0xe8, 0x08, 0xf7, 0xd3, 0x07, 0xfb, 0x45, + 0xf7, 0x40, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7c, 0x9d, 0x77, 0x95, + 0x78, 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, 0x96, 0x7d, + 0xa8, 0x79, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, 0xda, 0xf9, + 0x03, 0xf8, 0xca, 0x15, 0x8b, 0xc6, 0x99, 0x9b, 0xcb, 0x95, 0x08, 0xa4, + 0xfb, 0x70, 0x72, 0x07, 0xd9, 0x85, 0x9f, 0x77, 0x8b, 0x42, 0x08, 0xfb, + 0xc5, 0x07, 0xfb, 0x28, 0x53, 0x46, 0xfb, 0x0b, 0x25, 0x5e, 0xc6, 0xf7, + 0x1c, 0x1e, 0xf7, 0xe2, 0x07, 0x8b, 0xb3, 0x91, 0xa1, 0x9a, 0x99, 0x97, + 0x95, 0x9b, 0x8f, 0xbb, 0x8d, 0x08, 0xa4, 0xfb, 0xe6, 0x72, 0x07, 0xd1, + 0x84, 0x97, 0x7e, 0x8b, 0x43, 0x08, 0xfb, 0xe2, 0x07, 0x8b, 0x29, 0xa0, + 0x5a, 0xc8, 0x5f, 0xbb, 0x68, 0xcb, 0x79, 0xd4, 0x8b, 0xd5, 0x8b, 0xd1, + 0xa1, 0xb6, 0xb0, 0xb8, 0xb1, 0xa5, 0xd7, 0x8b, 0xe8, 0x08, 0xf7, 0xd3, + 0x07, 0xfb, 0x0e, 0xf7, 0x40, 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, + 0x2f, 0x8b, 0xfb, 0x0e, 0xfb, 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, + 0x04, 0x29, 0x05, 0x0e, 0xda, 0xf9, 0x4f, 0xf9, 0x38, 0x15, 0xfb, 0x70, + 0x72, 0x06, 0xce, 0x86, 0x9c, 0x83, 0x8b, 0x6e, 0x8b, 0x78, 0x7d, 0x68, + 0x72, 0x62, 0x08, 0xfb, 0x03, 0xfb, 0x4d, 0xfb, 0x0c, 0xf7, 0x7c, 0x05, + 0x8a, 0x8e, 0x86, 0x94, 0x8b, 0x8b, 0x7d, 0xa4, 0x87, 0x96, 0x8b, 0x96, + 0x08, 0xa1, 0x9a, 0x93, 0xb4, 0x1e, 0xa4, 0x8c, 0x8b, 0xa4, 0xfb, 0xe3, + 0x8b, 0x8b, 0x72, 0x05, 0xad, 0x89, 0xa5, 0x78, 0x9f, 0x69, 0x08, 0xf7, + 0x4b, 0xfb, 0xe0, 0x8b, 0xfb, 0x27, 0x05, 0x8b, 0x42, 0x80, 0x80, 0x39, + 0x83, 0x08, 0x72, 0xf7, 0xef, 0xa4, 0x07, 0x39, 0x93, 0x81, 0x95, 0x8b, + 0xd5, 0x08, 0x8b, 0xf7, 0x4c, 0xf7, 0x53, 0xf7, 0xcb, 0x05, 0x9a, 0xa2, + 0x9e, 0x96, 0xad, 0x90, 0x08, 0xa4, 0x07, 0xfc, 0x16, 0xc9, 0x15, 0xc3, + 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xac, 0x9f, 0x92, 0x95, 0x8b, 0xa2, 0x8b, + 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x77, 0x8b, 0x7a, 0x82, 0x7b, 0x78, 0x08, + 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xa3, 0xf9, 0x0e, 0xf7, 0x85, 0x15, + 0x71, 0x06, 0x70, 0x2d, 0x74, 0x63, 0x5c, 0x6a, 0x69, 0x73, 0x39, 0x7c, + 0x2b, 0x8b, 0x08, 0x41, 0x8b, 0xf8, 0x0f, 0xf9, 0x05, 0x8b, 0x9b, 0xfc, + 0xa0, 0x8b, 0x76, 0xfb, 0x62, 0xa7, 0x8b, 0x05, 0xbb, 0xf7, 0x1f, 0xb7, + 0xaa, 0xf7, 0x28, 0x89, 0x97, 0x8c, 0xad, 0x8c, 0xb0, 0x8c, 0x08, 0xfc, + 0x12, 0xfd, 0x05, 0x8b, 0x7b, 0xf8, 0xd8, 0x8b, 0xa5, 0xf7, 0x85, 0x05, + 0xfb, 0x17, 0xf9, 0x35, 0x15, 0x52, 0x8b, 0xfb, 0x04, 0x28, 0xfb, 0x04, + 0xee, 0x53, 0x8b, 0xf7, 0x0e, 0xfb, 0x44, 0xe7, 0x8b, 0xf7, 0x0f, 0xf7, + 0x44, 0x05, 0x0e, 0x6b, 0xf7, 0x9a, 0xf8, 0xb6, 0x15, 0x97, 0x07, 0x8b, + 0xd4, 0x93, 0x94, 0xdb, 0x96, 0x08, 0xa4, 0xfb, 0xe2, 0x72, 0x07, 0xd1, + 0x85, 0x99, 0x7b, 0x8b, 0x45, 0x08, 0xfc, 0x4e, 0x07, 0x8b, 0x4d, 0x7e, + 0x77, 0x5c, 0x85, 0x88, 0x8b, 0x81, 0x89, 0x80, 0x89, 0x08, 0x72, 0xf7, + 0xe2, 0xa4, 0x07, 0x3c, 0x95, 0x82, 0x94, 0x8b, 0xd4, 0x08, 0xc3, 0x07, + 0xf7, 0x33, 0x8c, 0xaf, 0x91, 0xc2, 0xab, 0xc4, 0xae, 0xaa, 0xbf, 0x8b, + 0xcb, 0x08, 0xf7, 0x0c, 0x2e, 0xca, 0xfb, 0x47, 0x1e, 0x49, 0x06, 0x45, + 0x04, 0xa2, 0x9c, 0x97, 0xac, 0xde, 0xac, 0x5f, 0xfb, 0x00, 0x1e, 0x8b, + 0x4c, 0x7f, 0x65, 0x71, 0x74, 0x73, 0x77, 0x6a, 0x84, 0x44, 0x8b, 0x08, + 0xf7, 0xa0, 0x07, 0x0e, 0xda, 0xf9, 0x4f, 0xf9, 0x38, 0x15, 0xfb, 0x70, + 0x72, 0x06, 0xce, 0x86, 0x9c, 0x83, 0x8b, 0x6e, 0x8b, 0x78, 0x7d, 0x68, + 0x72, 0x62, 0x08, 0xfb, 0x03, 0xfb, 0x4d, 0xfb, 0x0c, 0xf7, 0x7c, 0x05, + 0x8a, 0x8e, 0x86, 0x94, 0x8b, 0x8b, 0x7d, 0xa4, 0x87, 0x96, 0x8b, 0x96, + 0x08, 0xa1, 0x9a, 0x93, 0xb4, 0x1e, 0xa4, 0x8c, 0x8b, 0xa4, 0xfb, 0xe3, + 0x8b, 0x8b, 0x72, 0x05, 0xad, 0x89, 0xa5, 0x78, 0x9f, 0x69, 0x08, 0xf7, + 0x4b, 0xfb, 0xe0, 0x8b, 0xfb, 0x27, 0x05, 0x8b, 0x42, 0x80, 0x80, 0x39, + 0x83, 0x08, 0x72, 0xf7, 0xef, 0xa4, 0x07, 0x39, 0x93, 0x81, 0x95, 0x8b, + 0xd5, 0x08, 0x8b, 0xf7, 0x4c, 0xf7, 0x53, 0xf7, 0xcb, 0x05, 0x9a, 0xa2, + 0x9e, 0x96, 0xad, 0x90, 0x08, 0xa4, 0x07, 0xfc, 0x32, 0xf7, 0x5c, 0x15, + 0x69, 0x6d, 0x6d, 0x69, 0x67, 0xa8, 0x6e, 0xae, 0xaf, 0xa8, 0xa7, 0xae, + 0x1f, 0xaf, 0x6d, 0xa9, 0x68, 0x1e, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, + 0x6a, 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, + 0x67, 0x1f, 0x0e, 0xf8, 0x6d, 0xcb, 0x15, 0x81, 0x81, 0x05, 0x88, 0x88, + 0x88, 0x8a, 0x86, 0x8b, 0x08, 0x7d, 0x84, 0x94, 0x9b, 0x1f, 0xf7, 0x99, + 0x07, 0xdf, 0x3f, 0xc0, 0xfb, 0x0e, 0xfb, 0x05, 0x3f, 0x58, 0x40, 0x62, + 0xa3, 0x72, 0xb4, 0xb3, 0xa7, 0xa3, 0xad, 0x1e, 0x8b, 0x99, 0x85, 0x98, + 0x7f, 0x9b, 0x82, 0x95, 0x88, 0x91, 0x8b, 0x91, 0x08, 0xa0, 0xa7, 0x9b, + 0xae, 0x1e, 0xc5, 0xa5, 0x70, 0x4e, 0x1f, 0x42, 0x07, 0xfb, 0x0b, 0x67, + 0x5a, 0x77, 0x66, 0x72, 0x60, 0x6d, 0x76, 0x69, 0x8b, 0x60, 0x8b, 0x4e, + 0xba, 0x5e, 0xcb, 0x8b, 0xc4, 0x8b, 0xb9, 0x9f, 0xc2, 0xbd, 0x96, 0x58, + 0xa1, 0x78, 0xbc, 0x8b, 0xb6, 0x8b, 0xaa, 0x9b, 0xb1, 0xb4, 0x08, 0x7c, + 0xa0, 0x05, 0xfb, 0x48, 0xaf, 0x15, 0x70, 0x6c, 0x77, 0x7f, 0x73, 0x8b, + 0x6d, 0x8b, 0x76, 0xa6, 0x8b, 0xb3, 0x8b, 0xc5, 0xb5, 0xb5, 0xdb, 0xa0, + 0x08, 0xfb, 0x25, 0x07, 0xfb, 0x2d, 0xf8, 0xca, 0x15, 0x69, 0x6d, 0x6d, + 0x69, 0x68, 0xa8, 0x6d, 0xae, 0xaf, 0xa8, 0xa7, 0xae, 0x1f, 0xaf, 0x6d, + 0xa9, 0x68, 0x1e, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, 0x66, 0xa7, + 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, + 0xf8, 0x6d, 0xcb, 0x15, 0x81, 0x81, 0x05, 0x88, 0x88, 0x88, 0x8a, 0x86, + 0x8b, 0x08, 0x7d, 0x84, 0x94, 0x9b, 0x1f, 0xf7, 0x99, 0x07, 0xdf, 0x3f, + 0xc0, 0xfb, 0x0e, 0xfb, 0x05, 0x3f, 0x58, 0x40, 0x62, 0xa3, 0x72, 0xb4, + 0xb3, 0xa7, 0xa3, 0xad, 0x1e, 0x8b, 0x99, 0x85, 0x98, 0x7f, 0x9b, 0x82, + 0x95, 0x88, 0x91, 0x8b, 0x91, 0x08, 0xa0, 0xa7, 0x9b, 0xae, 0x1e, 0xc5, + 0xa5, 0x70, 0x4e, 0x1f, 0x42, 0x07, 0xfb, 0x0b, 0x67, 0x5a, 0x77, 0x66, + 0x72, 0x60, 0x6d, 0x76, 0x69, 0x8b, 0x60, 0x8b, 0x4e, 0xba, 0x5e, 0xcb, + 0x8b, 0xc4, 0x8b, 0xb9, 0x9f, 0xc2, 0xbd, 0x96, 0x58, 0xa1, 0x78, 0xbc, + 0x8b, 0xb6, 0x8b, 0xaa, 0x9b, 0xb1, 0xb4, 0x08, 0x7c, 0xa0, 0x05, 0xfb, + 0x48, 0xaf, 0x15, 0x70, 0x6c, 0x77, 0x7f, 0x73, 0x8b, 0x6d, 0x8b, 0x76, + 0xa6, 0x8b, 0xb3, 0x8b, 0xc5, 0xb5, 0xb5, 0xdb, 0xa0, 0x08, 0xfb, 0x25, + 0x07, 0xfb, 0x1f, 0xf8, 0x40, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, + 0xab, 0x9f, 0x93, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, + 0x77, 0x8b, 0x7a, 0x82, 0x7b, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, + 0x0e, 0xf8, 0x6d, 0xcb, 0x15, 0x81, 0x81, 0x05, 0x88, 0x88, 0x88, 0x8a, + 0x86, 0x8b, 0x08, 0x7d, 0x84, 0x94, 0x9b, 0x1f, 0xf7, 0x99, 0x07, 0xdf, + 0x3f, 0xc0, 0xfb, 0x0e, 0xfb, 0x05, 0x3f, 0x58, 0x40, 0x62, 0xa3, 0x72, + 0xb4, 0xb3, 0xa7, 0xa3, 0xad, 0x1e, 0x8b, 0x99, 0x85, 0x98, 0x7f, 0x9b, + 0x82, 0x95, 0x88, 0x91, 0x8b, 0x91, 0x08, 0xa0, 0xa7, 0x9b, 0xae, 0x1e, + 0xc5, 0xa5, 0x70, 0x4e, 0x1f, 0x42, 0x07, 0xfb, 0x0b, 0x67, 0x5a, 0x77, + 0x66, 0x72, 0x60, 0x6d, 0x76, 0x69, 0x8b, 0x60, 0x8b, 0x4e, 0xba, 0x5e, + 0xcb, 0x8b, 0xc4, 0x8b, 0xb9, 0x9f, 0xc2, 0xbd, 0x96, 0x58, 0xa1, 0x78, + 0xbc, 0x8b, 0xb6, 0x8b, 0xaa, 0x9b, 0xb1, 0xb4, 0x08, 0x7c, 0xa0, 0x05, + 0xfb, 0x48, 0xaf, 0x15, 0x70, 0x6c, 0x77, 0x7f, 0x73, 0x8b, 0x6d, 0x8b, + 0x76, 0xa6, 0x8b, 0xb3, 0x8b, 0xc5, 0xb5, 0xb5, 0xdb, 0xa0, 0x08, 0xfb, + 0x25, 0x07, 0xb0, 0xf8, 0x40, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, + 0x9d, 0x77, 0x95, 0x78, 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, + 0x77, 0x96, 0x7e, 0xa9, 0x78, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, + 0x0e, 0xf8, 0x6d, 0xcb, 0x15, 0x81, 0x81, 0x05, 0x88, 0x88, 0x88, 0x8a, + 0x86, 0x8b, 0x08, 0x7d, 0x84, 0x94, 0x9b, 0x1f, 0xf7, 0x99, 0x07, 0xdf, + 0x3f, 0xc0, 0xfb, 0x0e, 0xfb, 0x05, 0x3f, 0x58, 0x40, 0x62, 0xa3, 0x72, + 0xb4, 0xb3, 0xa7, 0xa3, 0xad, 0x1e, 0x8b, 0x99, 0x85, 0x98, 0x7f, 0x9b, + 0x82, 0x95, 0x88, 0x91, 0x8b, 0x91, 0x08, 0xa0, 0xa7, 0x9b, 0xae, 0x1e, + 0xc5, 0xa5, 0x70, 0x4e, 0x1f, 0x42, 0x07, 0xfb, 0x0b, 0x67, 0x5a, 0x77, + 0x66, 0x72, 0x60, 0x6d, 0x76, 0x69, 0x8b, 0x60, 0x8b, 0x4e, 0xba, 0x5e, + 0xcb, 0x8b, 0xc4, 0x8b, 0xb9, 0x9f, 0xc2, 0xbd, 0x96, 0x58, 0xa1, 0x78, + 0xbc, 0x8b, 0xb6, 0x8b, 0xaa, 0x9b, 0xb1, 0xb4, 0x08, 0x7c, 0xa0, 0x05, + 0xfb, 0x48, 0xaf, 0x15, 0x70, 0x6c, 0x77, 0x7f, 0x73, 0x8b, 0x6d, 0x8b, + 0x76, 0xa6, 0x8b, 0xb3, 0x8b, 0xc5, 0xb5, 0xb5, 0xdb, 0xa0, 0x08, 0xfb, + 0x25, 0x07, 0xd0, 0xf8, 0x40, 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, + 0x2f, 0x8b, 0xfb, 0x0e, 0xfb, 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, + 0x04, 0x29, 0x05, 0x0e, 0xf8, 0x6d, 0xcb, 0x15, 0x81, 0x81, 0x05, 0x88, + 0x88, 0x88, 0x8a, 0x86, 0x8b, 0x08, 0x7d, 0x84, 0x94, 0x9b, 0x1f, 0xf7, + 0x99, 0x07, 0xdf, 0x3f, 0xc0, 0xfb, 0x0e, 0xfb, 0x05, 0x3f, 0x58, 0x40, + 0x62, 0xa3, 0x72, 0xb4, 0xb3, 0xa7, 0xa3, 0xad, 0x1e, 0x8b, 0x99, 0x85, + 0x98, 0x7f, 0x9b, 0x82, 0x95, 0x88, 0x91, 0x8b, 0x91, 0x08, 0xa0, 0xa7, + 0x9b, 0xae, 0x1e, 0xc5, 0xa5, 0x70, 0x4e, 0x1f, 0x42, 0x07, 0xfb, 0x0b, + 0x67, 0x5a, 0x77, 0x66, 0x72, 0x60, 0x6d, 0x76, 0x69, 0x8b, 0x60, 0x8b, + 0x4e, 0xba, 0x5e, 0xcb, 0x8b, 0xc4, 0x8b, 0xb9, 0x9f, 0xc2, 0xbd, 0x96, + 0x58, 0xa1, 0x78, 0xbc, 0x8b, 0xb6, 0x8b, 0xaa, 0x9b, 0xb1, 0xb4, 0x08, + 0x7c, 0xa0, 0x05, 0xfb, 0x48, 0xaf, 0x15, 0x70, 0x6c, 0x77, 0x7f, 0x73, + 0x8b, 0x6d, 0x8b, 0x76, 0xa6, 0x8b, 0xb3, 0x8b, 0xc5, 0xb5, 0xb5, 0xdb, + 0xa0, 0x08, 0xfb, 0x25, 0x07, 0xfb, 0x4b, 0xf8, 0x55, 0x15, 0x8e, 0xa7, + 0x9f, 0x9e, 0xa5, 0x8b, 0x98, 0x8b, 0x92, 0x88, 0xb7, 0x78, 0x08, 0xa8, + 0x7e, 0x05, 0x9d, 0x83, 0xa5, 0x85, 0x9f, 0x8b, 0xc4, 0x8b, 0xaf, 0xb3, + 0xa3, 0xe2, 0x08, 0x60, 0x06, 0x7e, 0x67, 0x7d, 0x7e, 0x70, 0x8b, 0x7f, + 0x8b, 0x88, 0x8c, 0x73, 0x96, 0x08, 0x63, 0x9d, 0x05, 0x6e, 0x98, 0x73, + 0x91, 0x76, 0x8b, 0x4e, 0x8b, 0x67, 0x64, 0x79, 0x35, 0x08, 0xb5, 0x06, + 0x0e, 0xf8, 0x6d, 0xcb, 0x15, 0x81, 0x81, 0x05, 0x88, 0x88, 0x88, 0x8a, + 0x86, 0x8b, 0x08, 0x7d, 0x84, 0x94, 0x9b, 0x1f, 0xf7, 0x99, 0x07, 0xdf, + 0x3f, 0xc0, 0xfb, 0x0e, 0xfb, 0x05, 0x3f, 0x58, 0x40, 0x62, 0xa3, 0x72, + 0xb4, 0xb3, 0xa7, 0xa3, 0xad, 0x1e, 0x8b, 0x99, 0x85, 0x98, 0x7f, 0x9b, + 0x82, 0x95, 0x88, 0x91, 0x8b, 0x91, 0x08, 0xa0, 0xa7, 0x9b, 0xae, 0x1e, + 0xc5, 0xa5, 0x70, 0x4e, 0x1f, 0x42, 0x07, 0xfb, 0x0b, 0x67, 0x5a, 0x77, + 0x66, 0x72, 0x60, 0x6d, 0x76, 0x69, 0x8b, 0x60, 0x8b, 0x4e, 0xba, 0x5e, + 0xcb, 0x8b, 0xc4, 0x8b, 0xb9, 0x9f, 0xc2, 0xbd, 0x96, 0x58, 0xa1, 0x78, + 0xbc, 0x8b, 0xb6, 0x8b, 0xaa, 0x9b, 0xb1, 0xb4, 0x08, 0x7c, 0xa0, 0x05, + 0xfb, 0x48, 0xaf, 0x15, 0x70, 0x6c, 0x77, 0x7f, 0x73, 0x8b, 0x6d, 0x8b, + 0x76, 0xa6, 0x8b, 0xb3, 0x8b, 0xc5, 0xb5, 0xb5, 0xdb, 0xa0, 0x08, 0xfb, + 0x25, 0x07, 0x56, 0xf9, 0x1e, 0x15, 0x51, 0x5a, 0x5a, 0x53, 0x4f, 0xba, + 0x5b, 0xc6, 0xc6, 0xbb, 0xba, 0xc6, 0x1f, 0xc5, 0x5b, 0xbc, 0x51, 0x1e, + 0x8a, 0x5b, 0x15, 0xab, 0xa6, 0x6f, 0x6b, 0x6c, 0x70, 0x71, 0x6a, 0x6c, + 0x71, 0xa5, 0xab, 0xaa, 0xa6, 0xa7, 0xaa, 0x1f, 0x0e, 0xfb, 0x5b, 0xf7, + 0x9d, 0x7e, 0x15, 0xd0, 0x95, 0xbc, 0xaa, 0xba, 0xca, 0x08, 0x79, 0x9d, + 0x05, 0x66, 0x61, 0x71, 0x7d, 0x62, 0x8b, 0x08, 0x34, 0x54, 0xe2, 0xf7, + 0x1c, 0xf2, 0xab, 0xca, 0xbf, 0x1f, 0x9b, 0x8b, 0x9a, 0x83, 0x91, 0x80, + 0x90, 0x82, 0x8b, 0x8b, 0x8b, 0x61, 0x8c, 0x5a, 0x9d, 0x74, 0xb0, 0x8b, + 0x08, 0xb5, 0xa5, 0xa3, 0xb2, 0xc9, 0x48, 0xbb, 0x33, 0xfb, 0x1c, 0x27, + 0x21, 0xfb, 0x25, 0x1f, 0x8b, 0xfb, 0x17, 0xd9, 0x2e, 0xf7, 0x0b, 0x80, + 0x08, 0x66, 0x38, 0x96, 0x83, 0x05, 0x96, 0x8e, 0x93, 0x8c, 0x94, 0x8b, + 0x08, 0xa8, 0x9c, 0x7d, 0x75, 0x71, 0x76, 0x7c, 0x66, 0x1f, 0x7b, 0x8b, + 0x7f, 0x8e, 0x72, 0x94, 0x08, 0x85, 0x8d, 0x7b, 0x66, 0x05, 0xaf, 0x7e, + 0xa6, 0x86, 0xac, 0x8b, 0x08, 0xdb, 0xbd, 0xad, 0xc2, 0xb7, 0x6a, 0xa5, + 0x54, 0x1f, 0x7e, 0x8b, 0x83, 0x8a, 0x7f, 0x87, 0x08, 0xa2, 0xbe, 0x05, + 0x0e, 0xfb, 0x5b, 0xf8, 0x26, 0xf7, 0x11, 0x15, 0x63, 0x5a, 0x6c, 0x79, + 0x60, 0x8b, 0x64, 0x8b, 0x6e, 0x9d, 0x76, 0xae, 0x79, 0xab, 0x83, 0xac, + 0x87, 0xd0, 0x08, 0xf7, 0x90, 0x06, 0x85, 0xdf, 0x7c, 0xba, 0x6b, 0xb1, + 0x6a, 0xb2, 0x5d, 0x9f, 0x54, 0x8b, 0x08, 0xfb, 0x11, 0x37, 0x28, 0xfb, + 0x26, 0xfb, 0x26, 0xdd, 0x2b, 0xf7, 0x10, 0x1f, 0xdc, 0x8b, 0xbc, 0xab, + 0xcc, 0xe8, 0x08, 0x73, 0x99, 0x05, 0xfb, 0x82, 0xf7, 0x31, 0x15, 0x8e, + 0xf7, 0x0c, 0x9d, 0xb3, 0xbc, 0x8b, 0xa7, 0x8b, 0x9e, 0x7b, 0x93, 0x6c, + 0x90, 0x78, 0x8d, 0x6f, 0x8d, 0x58, 0x08, 0x7c, 0xfb, 0x1a, 0x07, 0x63, + 0xf8, 0x14, 0x15, 0x69, 0x6d, 0x6d, 0x69, 0x68, 0xa8, 0x6d, 0xae, 0xaf, + 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x68, 0x1f, 0xf7, 0x65, 0x16, 0x6a, + 0x6d, 0x6d, 0x6a, 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, + 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xfb, 0x5b, 0xf8, 0x26, 0xf7, 0x11, 0x15, + 0x63, 0x5a, 0x6c, 0x79, 0x60, 0x8b, 0x64, 0x8b, 0x6e, 0x9d, 0x76, 0xae, + 0x79, 0xab, 0x83, 0xac, 0x87, 0xd0, 0x08, 0xf7, 0x90, 0x06, 0x85, 0xdf, + 0x7c, 0xba, 0x6b, 0xb1, 0x6a, 0xb2, 0x5d, 0x9f, 0x54, 0x8b, 0x08, 0xfb, + 0x11, 0x37, 0x28, 0xfb, 0x26, 0xfb, 0x26, 0xdd, 0x2b, 0xf7, 0x10, 0x1f, + 0xdc, 0x8b, 0xbc, 0xab, 0xcc, 0xe8, 0x08, 0x73, 0x99, 0x05, 0xfb, 0x82, + 0xf7, 0x31, 0x15, 0x8e, 0xf7, 0x0c, 0x9d, 0xb3, 0xbc, 0x8b, 0xa7, 0x8b, + 0x9e, 0x7b, 0x93, 0x6c, 0x90, 0x78, 0x8d, 0x6f, 0x8d, 0x58, 0x08, 0x7c, + 0xfb, 0x1a, 0x07, 0x86, 0xf7, 0x8a, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, + 0x05, 0xab, 0x9f, 0x93, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, + 0x8b, 0x78, 0x8b, 0x7a, 0x82, 0x7a, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, + 0x05, 0x0e, 0xfb, 0x5b, 0xf8, 0x26, 0xf7, 0x11, 0x15, 0x63, 0x5a, 0x6c, + 0x79, 0x60, 0x8b, 0x64, 0x8b, 0x6e, 0x9d, 0x76, 0xae, 0x79, 0xab, 0x83, + 0xac, 0x87, 0xd0, 0x08, 0xf7, 0x90, 0x06, 0x85, 0xdf, 0x7c, 0xba, 0x6b, + 0xb1, 0x6a, 0xb2, 0x5d, 0x9f, 0x54, 0x8b, 0x08, 0xfb, 0x11, 0x37, 0x28, + 0xfb, 0x26, 0xfb, 0x26, 0xdd, 0x2b, 0xf7, 0x10, 0x1f, 0xdc, 0x8b, 0xbc, + 0xab, 0xcc, 0xe8, 0x08, 0x73, 0x99, 0x05, 0xfb, 0x82, 0xf7, 0x31, 0x15, + 0x8e, 0xf7, 0x0c, 0x9d, 0xb3, 0xbc, 0x8b, 0xa7, 0x8b, 0x9e, 0x7b, 0x93, + 0x6c, 0x90, 0x78, 0x8d, 0x6f, 0x8d, 0x58, 0x08, 0x7c, 0xfb, 0x1a, 0x07, + 0xf7, 0x28, 0xf7, 0x8a, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, + 0x78, 0x95, 0x78, 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, + 0x96, 0x7d, 0xa8, 0x79, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, + 0xfb, 0x5b, 0xf8, 0x26, 0xf7, 0x11, 0x15, 0x63, 0x5a, 0x6c, 0x79, 0x60, + 0x8b, 0x64, 0x8b, 0x6e, 0x9d, 0x76, 0xae, 0x79, 0xab, 0x83, 0xac, 0x87, + 0xd0, 0x08, 0xf7, 0x90, 0x06, 0x85, 0xdf, 0x7c, 0xba, 0x6b, 0xb1, 0x6a, + 0xb2, 0x5d, 0x9f, 0x54, 0x8b, 0x08, 0xfb, 0x11, 0x37, 0x28, 0xfb, 0x26, + 0xfb, 0x26, 0xdd, 0x2b, 0xf7, 0x10, 0x1f, 0xdc, 0x8b, 0xbc, 0xab, 0xcc, + 0xe8, 0x08, 0x73, 0x99, 0x05, 0xfb, 0x82, 0xf7, 0x31, 0x15, 0x8e, 0xf7, + 0x0c, 0x9d, 0xb3, 0xbc, 0x8b, 0xa7, 0x8b, 0x9e, 0x7b, 0x93, 0x6c, 0x90, + 0x78, 0x8d, 0x6f, 0x8d, 0x58, 0x08, 0x7c, 0xfb, 0x1a, 0x07, 0xf7, 0x4c, + 0xf7, 0x8a, 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, 0x8b, 0xfb, + 0x0e, 0xfb, 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, 0x29, 0x05, + 0x0e, 0xfc, 0x01, 0xf7, 0x64, 0xf8, 0x61, 0x15, 0xfb, 0x54, 0x73, 0x06, + 0xb7, 0x82, 0x94, 0x82, 0x8b, 0x62, 0x08, 0xfb, 0xba, 0x07, 0x8b, 0x62, + 0x84, 0x83, 0x5d, 0x80, 0x08, 0x73, 0xf7, 0x83, 0xa3, 0x07, 0x68, 0x90, + 0x7f, 0x99, 0x8b, 0xb1, 0x08, 0xf8, 0x10, 0x07, 0xfb, 0x48, 0xf7, 0x61, + 0x15, 0x69, 0x6d, 0x6d, 0x69, 0x68, 0xa8, 0x6d, 0xae, 0xaf, 0xa8, 0xa7, + 0xae, 0x1f, 0xaf, 0x6d, 0xa9, 0x68, 0x1e, 0xf7, 0x65, 0x16, 0x6a, 0x6d, + 0x6d, 0x6a, 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, + 0xa9, 0x67, 0x1f, 0x0e, 0xfc, 0x01, 0xf7, 0x64, 0xf8, 0x61, 0x15, 0xfb, + 0x54, 0x73, 0x06, 0xb7, 0x82, 0x94, 0x82, 0x8b, 0x62, 0x08, 0xfb, 0xba, + 0x07, 0x8b, 0x62, 0x84, 0x83, 0x5d, 0x80, 0x08, 0x73, 0xf7, 0x83, 0xa3, + 0x07, 0x68, 0x90, 0x7f, 0x99, 0x8b, 0xb1, 0x08, 0xf8, 0x10, 0x07, 0xfb, + 0x30, 0xce, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, 0x9f, 0x93, + 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x78, 0x8b, 0x7a, + 0x82, 0x7a, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, 0xfc, 0x01, + 0xf7, 0x64, 0xf8, 0x61, 0x15, 0xfb, 0x54, 0x73, 0x06, 0xb7, 0x82, 0x94, + 0x82, 0x8b, 0x62, 0x08, 0xfb, 0xba, 0x07, 0x8b, 0x62, 0x84, 0x83, 0x5d, + 0x80, 0x08, 0x73, 0xf7, 0x83, 0xa3, 0x07, 0x68, 0x90, 0x7f, 0x99, 0x8b, + 0xb1, 0x08, 0xf8, 0x10, 0x07, 0x8f, 0xce, 0x15, 0xfb, 0x1d, 0xf7, 0x31, + 0x05, 0x7b, 0x9d, 0x78, 0x95, 0x78, 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, + 0x72, 0x8b, 0x77, 0x96, 0x7d, 0xa8, 0x79, 0x08, 0xf7, 0x22, 0x33, 0xc3, + 0x8b, 0x05, 0x0e, 0xfc, 0x01, 0xf7, 0x64, 0xf8, 0x61, 0x15, 0xfb, 0x54, + 0x73, 0x06, 0xb7, 0x82, 0x94, 0x82, 0x8b, 0x62, 0x08, 0xfb, 0xba, 0x07, + 0x8b, 0x62, 0x84, 0x83, 0x5d, 0x80, 0x08, 0x73, 0xf7, 0x83, 0xa3, 0x07, + 0x68, 0x90, 0x7f, 0x99, 0x8b, 0xb1, 0x08, 0xf8, 0x10, 0x07, 0xaf, 0xce, + 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, 0x8b, 0xfb, 0x0e, 0xfb, + 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, 0x29, 0x05, 0x0e, 0x34, + 0xf7, 0x68, 0xf8, 0x61, 0x15, 0xfb, 0x53, 0x73, 0x06, 0xb7, 0x84, 0x94, + 0x81, 0x8b, 0x61, 0x08, 0xfb, 0xba, 0x07, 0x8b, 0x61, 0x83, 0x82, 0x5e, + 0x82, 0x08, 0x73, 0xf7, 0x85, 0xa3, 0x07, 0x66, 0x90, 0x7f, 0x9a, 0x8b, + 0xb0, 0x08, 0xf7, 0x9f, 0x07, 0x8b, 0x8f, 0x92, 0x95, 0x95, 0x94, 0x08, + 0xa1, 0xa2, 0xa3, 0x97, 0xa2, 0x8b, 0x08, 0xae, 0x9c, 0x70, 0x53, 0x1f, + 0xfb, 0x86, 0x07, 0x8b, 0x66, 0x7e, 0x7b, 0x69, 0x87, 0x08, 0x73, 0xf7, + 0x7f, 0xa3, 0x07, 0x64, 0x8e, 0x81, 0x97, 0x8b, 0xb5, 0x08, 0xf7, 0x8f, + 0x07, 0xe1, 0x56, 0xc2, 0x39, 0x1e, 0x4f, 0x8b, 0x5d, 0x6f, 0x66, 0x50, + 0x08, 0xd6, 0x07, 0x41, 0xe3, 0x15, 0x8e, 0xa7, 0x9f, 0x9e, 0xa5, 0x8b, + 0x98, 0x8b, 0x92, 0x88, 0xb7, 0x78, 0x08, 0xa8, 0x7e, 0x05, 0x9d, 0x83, + 0xa5, 0x85, 0x9f, 0x8b, 0xc4, 0x8b, 0xaf, 0xb3, 0xa3, 0xe2, 0x08, 0x60, + 0x06, 0x7e, 0x67, 0x7d, 0x7e, 0x70, 0x8b, 0x7f, 0x8b, 0x88, 0x8c, 0x73, + 0x96, 0x08, 0x63, 0x9d, 0x05, 0x6e, 0x98, 0x73, 0x91, 0x76, 0x8b, 0x4e, + 0x8b, 0x67, 0x64, 0x79, 0x35, 0x08, 0xb5, 0x06, 0x0e, 0xf7, 0x8f, 0xf8, + 0x6d, 0x15, 0xfb, 0x13, 0x28, 0x22, 0xfb, 0x1c, 0xfb, 0x23, 0xea, 0x24, + 0xf7, 0x17, 0xf7, 0x15, 0xeb, 0xf3, 0xf7, 0x1f, 0x1f, 0xf7, 0x20, 0x2b, + 0xf3, 0xfb, 0x15, 0x1e, 0x8c, 0x6c, 0x15, 0xc5, 0x9e, 0x54, 0xfb, 0x38, + 0xfb, 0x2e, 0x77, 0x57, 0x51, 0x50, 0x77, 0xbe, 0xf7, 0x26, 0xf7, 0x44, + 0x9d, 0xbf, 0xc9, 0x1f, 0x20, 0xf7, 0x74, 0x15, 0x69, 0x6d, 0x6d, 0x69, + 0x68, 0xa8, 0x6d, 0xae, 0xaf, 0xa8, 0xa7, 0xae, 0x1f, 0xaf, 0x6d, 0xa9, + 0x68, 0x1e, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, 0x66, 0xa7, 0x6e, + 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xf7, + 0x8f, 0xf8, 0x6d, 0x15, 0xfb, 0x13, 0x28, 0x22, 0xfb, 0x1c, 0xfb, 0x23, + 0xea, 0x24, 0xf7, 0x17, 0xf7, 0x15, 0xeb, 0xf3, 0xf7, 0x1f, 0xf7, 0x20, + 0x2b, 0xf3, 0xfb, 0x15, 0x1f, 0x8c, 0x6c, 0x15, 0xc5, 0x9e, 0x54, 0xfb, + 0x38, 0xfb, 0x2e, 0x77, 0x57, 0x51, 0x50, 0x77, 0xbe, 0xf7, 0x26, 0xf7, + 0x44, 0x9d, 0xbf, 0xc9, 0x1f, 0x39, 0xe1, 0x15, 0xc3, 0x8b, 0xf7, 0x22, + 0xe3, 0x05, 0xac, 0x9f, 0x92, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, + 0x6e, 0x8b, 0x77, 0x8b, 0x7a, 0x82, 0x7b, 0x78, 0x08, 0xfb, 0x1d, 0xfb, + 0x31, 0x05, 0x0e, 0xf7, 0x8f, 0xf8, 0x6d, 0x15, 0xfb, 0x13, 0x28, 0x22, + 0xfb, 0x1c, 0xfb, 0x23, 0xea, 0x24, 0xf7, 0x17, 0xf7, 0x15, 0xeb, 0xf3, + 0xf7, 0x1f, 0xf7, 0x20, 0x2b, 0xf3, 0xfb, 0x15, 0x1f, 0x8c, 0x6c, 0x15, + 0xc5, 0x9e, 0x54, 0xfb, 0x38, 0xfb, 0x2e, 0x77, 0x57, 0x51, 0x50, 0x77, + 0xbe, 0xf7, 0x26, 0xf7, 0x44, 0x9d, 0xbf, 0xc9, 0x1f, 0xd9, 0xe1, 0x15, + 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, 0x77, 0x95, 0x78, 0x8b, 0x71, + 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, 0x96, 0x7e, 0xa9, 0x78, 0x08, + 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, 0xf7, 0x8f, 0xf8, 0x6d, 0x15, + 0xfb, 0x13, 0x28, 0x22, 0xfb, 0x1c, 0xfb, 0x23, 0xea, 0x24, 0xf7, 0x17, + 0xf7, 0x15, 0xeb, 0xf3, 0xf7, 0x1f, 0xf7, 0x20, 0x2b, 0xf3, 0xfb, 0x15, + 0x1f, 0x8c, 0x6c, 0x15, 0xc5, 0x9e, 0x54, 0xfb, 0x38, 0xfb, 0x2e, 0x77, + 0x57, 0x51, 0x50, 0x77, 0xbe, 0xf7, 0x26, 0xf7, 0x44, 0x9d, 0xbf, 0xc9, + 0x1f, 0xf7, 0x02, 0xe1, 0x15, 0xc4, 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, + 0x8b, 0xfb, 0x0e, 0xfb, 0x44, 0xc3, 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, + 0x29, 0x05, 0x0e, 0xf7, 0x8f, 0xf8, 0x6d, 0x15, 0xfb, 0x13, 0x28, 0x22, + 0xfb, 0x1c, 0xfb, 0x23, 0xea, 0x24, 0xf7, 0x17, 0xf7, 0x15, 0xeb, 0xf3, + 0xf7, 0x1f, 0x1f, 0xf7, 0x20, 0x2b, 0xf3, 0xfb, 0x15, 0x1e, 0x8c, 0x6c, + 0x15, 0xc5, 0x9e, 0x54, 0xfb, 0x38, 0xfb, 0x2e, 0x77, 0x57, 0x51, 0x50, + 0x77, 0xbe, 0xf7, 0x26, 0xf7, 0x44, 0x9d, 0xbf, 0xc9, 0x1f, 0xfb, 0x22, + 0xf6, 0x15, 0x8e, 0xa7, 0x9f, 0x9e, 0xa5, 0x8b, 0x98, 0x8b, 0x92, 0x88, + 0xb7, 0x78, 0x08, 0xa8, 0x7e, 0x05, 0x9d, 0x83, 0xa5, 0x85, 0x9f, 0x8b, + 0xc4, 0x8b, 0xaf, 0xb3, 0xa3, 0xe2, 0x08, 0x60, 0x06, 0x7e, 0x67, 0x7d, + 0x7e, 0x70, 0x8b, 0x7f, 0x8b, 0x88, 0x8c, 0x73, 0x96, 0x08, 0x63, 0x9d, + 0x05, 0x6e, 0x98, 0x73, 0x91, 0x76, 0x8b, 0x4e, 0x8b, 0x67, 0x64, 0x79, + 0x35, 0x08, 0xb5, 0x06, 0x0e, 0xfb, 0x92, 0xf7, 0xe8, 0xf7, 0xda, 0x15, + 0xf7, 0x25, 0x75, 0x07, 0x85, 0x7c, 0x85, 0x86, 0x7f, 0x8b, 0x85, 0x8b, + 0x81, 0x8d, 0x7b, 0x90, 0x6a, 0x96, 0x74, 0x8f, 0x75, 0x8b, 0x30, 0x8b, + 0x49, 0x4d, 0x8b, 0x37, 0x8b, 0x49, 0xb4, 0x5d, 0xf0, 0x60, 0xcf, 0x6d, + 0xa7, 0x72, 0x8b, 0x6b, 0x08, 0x64, 0x6d, 0x71, 0x5e, 0x1e, 0x45, 0x8b, + 0x5d, 0xb8, 0x76, 0xe2, 0x08, 0x6f, 0xfb, 0x39, 0xa4, 0x06, 0x96, 0xa0, + 0x91, 0x92, 0x94, 0x8b, 0x90, 0x8b, 0x93, 0x89, 0x95, 0x87, 0xa6, 0x7f, + 0xc0, 0x80, 0xa7, 0x8b, 0xe6, 0x8b, 0xca, 0xc9, 0x8b, 0xe5, 0x8b, 0xd2, + 0x64, 0xb6, 0x28, 0xb5, 0x47, 0xa8, 0x6f, 0xa4, 0x8b, 0xad, 0x08, 0xac, + 0xa7, 0xa4, 0xb1, 0x1e, 0xa5, 0x8b, 0xa6, 0x80, 0xa1, 0x76, 0xa0, 0x77, + 0x96, 0x79, 0x9a, 0x5f, 0x08, 0xa4, 0x06, 0xa2, 0xf8, 0x0e, 0x15, 0x52, + 0x8b, 0xfb, 0x04, 0x28, 0xfb, 0x04, 0xee, 0x53, 0x8b, 0xf7, 0x0e, 0xfb, + 0x44, 0xe7, 0x8b, 0xf7, 0x0f, 0xf7, 0x44, 0x05, 0x0e, 0x34, 0xf7, 0xeb, + 0x7e, 0x15, 0xb6, 0x9a, 0xa3, 0x8f, 0xcc, 0x92, 0x08, 0xc9, 0x92, 0x8b, + 0xa2, 0x05, 0x5f, 0x8d, 0x7f, 0x98, 0x8b, 0xb6, 0x08, 0xf7, 0xfc, 0xfb, + 0x5d, 0x73, 0x07, 0xbd, 0x87, 0x97, 0x7f, 0x8b, 0x60, 0x08, 0xfb, 0xaf, + 0x07, 0x6a, 0x6a, 0x76, 0x80, 0x6f, 0x8b, 0x08, 0x62, 0x7c, 0x9f, 0xbe, + 0x1f, 0xf7, 0xe7, 0xfb, 0x50, 0x73, 0x07, 0xb4, 0x83, 0x93, 0x82, 0x8b, + 0x61, 0x08, 0xfb, 0x90, 0x07, 0x33, 0xbd, 0x57, 0xde, 0x1e, 0xbf, 0x8b, + 0xae, 0x9b, 0xc5, 0xbd, 0x08, 0x4a, 0x07, 0xfb, 0x4c, 0xf9, 0x3b, 0x15, + 0x69, 0x6d, 0x6d, 0x69, 0x68, 0xa8, 0x6d, 0xae, 0xaf, 0xa8, 0xa7, 0xae, + 0xaf, 0x6d, 0xa9, 0x68, 0x1f, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, + 0x66, 0xa7, 0x6e, 0xae, 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, + 0x1f, 0x0e, 0x34, 0xf7, 0xeb, 0x7e, 0x15, 0xb6, 0x9a, 0xa3, 0x8f, 0xcc, + 0x92, 0x08, 0xc9, 0x92, 0x8b, 0xa2, 0x05, 0x5f, 0x8d, 0x7f, 0x98, 0x8b, + 0xb6, 0x08, 0xf7, 0xfc, 0xfb, 0x5d, 0x73, 0x07, 0xbd, 0x87, 0x97, 0x7f, + 0x8b, 0x60, 0x08, 0xfb, 0xaf, 0x07, 0x6a, 0x6a, 0x76, 0x80, 0x6f, 0x8b, + 0x08, 0x62, 0x7c, 0x9f, 0xbe, 0x1f, 0xf7, 0xe7, 0xfb, 0x50, 0x73, 0x07, + 0xb4, 0x83, 0x93, 0x82, 0x8b, 0x61, 0x08, 0xfb, 0x90, 0x07, 0x33, 0xbd, + 0x57, 0xde, 0x1e, 0xbf, 0x8b, 0xae, 0x9b, 0xc5, 0xbd, 0x08, 0x4a, 0x07, + 0xfb, 0x32, 0xf8, 0xb1, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, 0xab, + 0x9f, 0x93, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, 0x78, + 0x8b, 0x7a, 0x82, 0x7a, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, 0x0e, + 0x34, 0xf7, 0xeb, 0x7e, 0x15, 0xb6, 0x9a, 0xa3, 0x8f, 0xcc, 0x92, 0x08, + 0xc9, 0x92, 0x8b, 0xa2, 0x05, 0x5f, 0x8d, 0x7f, 0x98, 0x8b, 0xb6, 0x08, + 0xf7, 0xfc, 0xfb, 0x5d, 0x73, 0x07, 0xbd, 0x87, 0x97, 0x7f, 0x8b, 0x60, + 0x08, 0xfb, 0xaf, 0x07, 0x6a, 0x6a, 0x76, 0x80, 0x6f, 0x8b, 0x08, 0x62, + 0x7c, 0x9f, 0xbe, 0x1f, 0xf7, 0xe7, 0xfb, 0x50, 0x73, 0x07, 0xb4, 0x83, + 0x93, 0x82, 0x8b, 0x61, 0x08, 0xfb, 0x90, 0x07, 0x33, 0xbd, 0x57, 0xde, + 0x1e, 0xbf, 0x8b, 0xae, 0x9b, 0xc5, 0xbd, 0x08, 0x4a, 0x07, 0x9a, 0xf8, + 0xb1, 0x15, 0xfb, 0x1d, 0xf7, 0x31, 0x05, 0x7b, 0x9d, 0x77, 0x95, 0x78, + 0x8b, 0x71, 0x8b, 0x76, 0x77, 0x8b, 0x72, 0x8b, 0x77, 0x96, 0x7e, 0xa9, + 0x78, 0x08, 0xf7, 0x22, 0x33, 0xc3, 0x8b, 0x05, 0x0e, 0x34, 0xf7, 0xeb, + 0x7e, 0x15, 0xb6, 0x9a, 0xa3, 0x8f, 0xcc, 0x92, 0x08, 0xc9, 0x92, 0x8b, + 0xa2, 0x05, 0x5f, 0x8d, 0x7f, 0x98, 0x8b, 0xb6, 0x08, 0xf7, 0xfc, 0xfb, + 0x5d, 0x73, 0x07, 0xbd, 0x87, 0x97, 0x7f, 0x8b, 0x60, 0x08, 0xfb, 0xaf, + 0x07, 0x6a, 0x6a, 0x76, 0x80, 0x6f, 0x8b, 0x08, 0x62, 0x7c, 0x9f, 0xbe, + 0x1f, 0xf7, 0xe7, 0xfb, 0x50, 0x73, 0x07, 0xb4, 0x83, 0x93, 0x82, 0x8b, + 0x61, 0x08, 0xfb, 0x90, 0x07, 0x33, 0xbd, 0x57, 0xde, 0x1e, 0xbf, 0x8b, + 0xae, 0x9b, 0xc5, 0xbd, 0x08, 0x4a, 0x07, 0xb6, 0xf8, 0xb1, 0x15, 0xc4, + 0x8b, 0xfb, 0x0f, 0xf7, 0x44, 0x2f, 0x8b, 0xfb, 0x0e, 0xfb, 0x44, 0xc3, + 0x8b, 0xf7, 0x04, 0xed, 0xf7, 0x04, 0x29, 0x05, 0x0e, 0xf8, 0x74, 0xf8, + 0x61, 0x15, 0xfb, 0x2b, 0x73, 0x06, 0xb6, 0x89, 0x97, 0x84, 0x8b, 0x73, + 0x8b, 0x80, 0x89, 0x82, 0x82, 0x72, 0x08, 0x47, 0xfb, 0x54, 0x43, 0xf7, + 0x4d, 0x05, 0x77, 0xbe, 0x8b, 0x8b, 0x8b, 0x93, 0x8b, 0x99, 0x97, 0x94, + 0xa4, 0x8d, 0x08, 0x9b, 0x8c, 0x8b, 0xa3, 0xfb, 0x8e, 0x8b, 0x8b, 0x73, + 0x05, 0xa2, 0x88, 0x91, 0x88, 0x91, 0x82, 0x8e, 0x8b, 0xb8, 0x29, 0x9c, + 0x61, 0x08, 0xf7, 0x0c, 0xfb, 0xbb, 0x79, 0x56, 0x05, 0x7a, 0x59, 0x71, + 0x6b, 0x74, 0x8b, 0x82, 0x8b, 0x83, 0x93, 0x8b, 0x94, 0x8b, 0x8c, 0x8b, + 0x8d, 0x8c, 0x8e, 0x8c, 0x90, 0x8c, 0x90, 0x8b, 0x8f, 0x08, 0xa8, 0x73, + 0x9f, 0x69, 0x66, 0x70, 0x71, 0x65, 0x5d, 0xb3, 0x6a, 0xc4, 0x1e, 0xad, + 0x8b, 0xa8, 0x97, 0xa0, 0xa0, 0xa0, 0xa2, 0x9f, 0xb3, 0xae, 0xe9, 0x08, + 0xf7, 0x29, 0xf8, 0x21, 0x05, 0x9c, 0xb5, 0x95, 0x95, 0xaa, 0x8e, 0x08, + 0xa3, 0x07, 0xfb, 0xca, 0xce, 0x15, 0xc3, 0x8b, 0xf7, 0x22, 0xe3, 0x05, + 0xac, 0x9f, 0x92, 0x95, 0x8b, 0xa2, 0x8b, 0xa5, 0x78, 0x9d, 0x6e, 0x8b, + 0x77, 0x8b, 0x7a, 0x82, 0x7b, 0x78, 0x08, 0xfb, 0x1d, 0xfb, 0x31, 0x05, + 0x0e, 0xfb, 0x5b, 0xf8, 0x38, 0xf7, 0x34, 0x15, 0x6f, 0x06, 0x82, 0x6b, + 0x83, 0x79, 0x7b, 0x76, 0x6b, 0x5f, 0x6a, 0x7e, 0x3b, 0x8b, 0x08, 0x6e, + 0x8b, 0xf7, 0x7b, 0xf8, 0x27, 0x8b, 0xa5, 0xfc, 0x07, 0x8b, 0x84, 0xfb, + 0x22, 0xa5, 0x8b, 0x05, 0xa4, 0xea, 0xa5, 0x9b, 0xf7, 0x20, 0x8a, 0x08, + 0xfb, 0x7e, 0xfc, 0x28, 0x8b, 0x72, 0xf8, 0x13, 0x8b, 0x9b, 0xf7, 0x34, + 0x05, 0x78, 0xf8, 0xb4, 0x15, 0x52, 0x8b, 0xfb, 0x04, 0x28, 0xfb, 0x04, + 0xee, 0x53, 0x8b, 0xf7, 0x0e, 0xfb, 0x44, 0xe7, 0x8b, 0xf7, 0x0f, 0xf7, + 0x44, 0x05, 0x0e, 0xf7, 0x94, 0xf8, 0xd2, 0x15, 0xb4, 0x62, 0xa5, 0x62, + 0x9e, 0x52, 0x08, 0x89, 0x88, 0x05, 0x71, 0xa9, 0x74, 0x96, 0x61, 0x8b, + 0x08, 0xfb, 0x13, 0x2a, 0x22, 0xfb, 0x1f, 0xfb, 0x20, 0xeb, 0x24, 0xf7, + 0x16, 0xf7, 0x22, 0xde, 0xf7, 0x05, 0xf7, 0x56, 0x1f, 0x8b, 0xce, 0x81, + 0xc6, 0x76, 0xbf, 0x72, 0xc8, 0x73, 0xab, 0x4e, 0xbd, 0x08, 0xe7, 0xba, + 0x5a, 0xa9, 0x31, 0x5d, 0x05, 0x59, 0xa5, 0x5a, 0x99, 0x4e, 0x91, 0x08, + 0x5d, 0x72, 0x05, 0xbd, 0x82, 0xb3, 0x79, 0xb6, 0x6c, 0x08, 0xfb, 0x09, + 0x50, 0xbb, 0x6c, 0xf7, 0x02, 0xc3, 0x05, 0x87, 0xfb, 0x18, 0x15, 0xc4, + 0x9f, 0x54, 0xfb, 0x2e, 0xfb, 0x38, 0x78, 0x57, 0x51, 0x1f, 0x71, 0x8b, + 0x78, 0x96, 0x7e, 0xa1, 0x7b, 0xa9, 0x85, 0xba, 0x8b, 0xea, 0x08, 0xf7, + 0x3a, 0x9e, 0xc1, 0xc8, 0x1e, 0x0e, 0x34, 0xf7, 0x6a, 0xf9, 0x38, 0x15, + 0xfb, 0x56, 0x73, 0x06, 0xb9, 0x82, 0x94, 0x82, 0x8b, 0x63, 0x08, 0xfd, + 0x61, 0x07, 0x8b, 0x62, 0x83, 0x82, 0x5b, 0x83, 0x08, 0x73, 0xf7, 0xa5, + 0x07, 0xa0, 0x07, 0x4e, 0x8e, 0x7a, 0x9f, 0x8b, 0xce, 0x08, 0xf7, 0x21, + 0x07, 0xbb, 0x5c, 0xa5, 0x7e, 0xb7, 0x8b, 0x08, 0xf7, 0x04, 0xdb, 0xf3, + 0xf7, 0x28, 0xf7, 0x1f, 0x40, 0xea, 0xfb, 0x03, 0x1f, 0x4f, 0x8b, 0x68, + 0x74, 0x6e, 0x50, 0x08, 0xf7, 0xb1, 0x07, 0xfb, 0xde, 0x04, 0x8b, 0x92, + 0x94, 0x9b, 0x97, 0x98, 0x9f, 0xa1, 0xa2, 0x97, 0xa1, 0x8b, 0x08, 0xbf, + 0xa3, 0x4f, 0xfb, 0x17, 0xfb, 0x0e, 0x6f, 0x4e, 0x54, 0x1f, 0x69, 0x8b, + 0x71, 0x9f, 0x78, 0xb4, 0x08, 0xf7, 0x87, 0x07, 0x0e, 0xf8, 0x74, 0xf8, + 0x61, 0x15, 0xfb, 0x2b, 0x73, 0x06, 0xb6, 0x89, 0x97, 0x84, 0x8b, 0x73, + 0x8b, 0x80, 0x89, 0x82, 0x82, 0x72, 0x08, 0x47, 0xfb, 0x54, 0x43, 0xf7, + 0x4d, 0x05, 0x77, 0xbe, 0x8b, 0x8b, 0x8b, 0x93, 0x8b, 0x99, 0x97, 0x94, + 0xa4, 0x8d, 0x08, 0x9b, 0x8c, 0x8b, 0xa3, 0xfb, 0x8e, 0x8b, 0x8b, 0x73, + 0x05, 0xa2, 0x88, 0x91, 0x88, 0x91, 0x82, 0x8e, 0x8b, 0xb8, 0x29, 0x9c, + 0x61, 0x08, 0xf7, 0x0c, 0xfb, 0xbb, 0x79, 0x56, 0x05, 0x7a, 0x59, 0x71, + 0x6b, 0x74, 0x8b, 0x82, 0x8b, 0x83, 0x93, 0x8b, 0x94, 0x8b, 0x8c, 0x8b, + 0x8d, 0x8c, 0x8e, 0x8c, 0x90, 0x8c, 0x90, 0x8b, 0x8f, 0x08, 0xa8, 0x73, + 0x9f, 0x69, 0x66, 0x70, 0x71, 0x65, 0x5d, 0xb3, 0x6a, 0xc4, 0x1e, 0xad, + 0x8b, 0xa8, 0x97, 0xa0, 0xa0, 0xa0, 0xa2, 0x9f, 0xb3, 0xae, 0xe9, 0x08, + 0xf7, 0x29, 0xf8, 0x21, 0x05, 0x9c, 0xb5, 0x95, 0x95, 0xaa, 0x8e, 0x08, + 0xa3, 0x07, 0xfb, 0xd3, 0xf7, 0x61, 0x15, 0x69, 0x6d, 0x6d, 0x69, 0x68, + 0xa8, 0x6d, 0xae, 0xaf, 0xa8, 0xa7, 0xae, 0x1f, 0xaf, 0x6d, 0xa9, 0x68, + 0x1e, 0xf7, 0x65, 0x16, 0x6a, 0x6d, 0x6d, 0x6a, 0x66, 0xa7, 0x6e, 0xae, + 0xb0, 0xa8, 0xa7, 0xae, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xae, 0xf7, + 0x7f, 0x15, 0xa7, 0xfb, 0x3d, 0xe2, 0x31, 0xf7, 0x1d, 0x8b, 0xd4, 0x8b, + 0xc6, 0xa7, 0xbf, 0xc5, 0x08, 0xbf, 0x07, 0x6a, 0x4b, 0x4a, 0x5e, 0x4f, + 0x8b, 0x42, 0x8b, 0x5c, 0xde, 0x7f, 0xf7, 0x27, 0x08, 0xe7, 0x8b, 0xa8, + 0xbd, 0xfb, 0x10, 0x8b, 0x05, 0x8a, 0x9b, 0x8b, 0x91, 0x8b, 0x97, 0x8b, + 0x8e, 0x8b, 0x91, 0x8c, 0x95, 0x08, 0xf7, 0x39, 0x8b, 0xa8, 0xbd, 0xfb, + 0x55, 0x8b, 0x05, 0x99, 0xf7, 0x3e, 0xb4, 0xd9, 0xd7, 0x8b, 0xb6, 0x8b, + 0xb4, 0x71, 0xa7, 0x5f, 0x9f, 0x6c, 0x95, 0x69, 0x92, 0x56, 0x08, 0x9e, + 0xf7, 0x73, 0x78, 0x06, 0x87, 0x6e, 0x7f, 0x7a, 0x7a, 0x8b, 0x84, 0x8b, + 0x82, 0x8d, 0x84, 0x8f, 0x56, 0xa9, 0x79, 0x91, 0x63, 0x8b, 0x31, 0x8b, + 0x38, 0x4f, 0x5b, 0x29, 0x78, 0x63, 0x83, 0x71, 0x81, 0x54, 0x08, 0x61, + 0x8b, 0x6f, 0x59, 0xcd, 0x8b, 0x05, 0x8a, 0x7f, 0x8b, 0x85, 0x8b, 0x83, + 0x8b, 0x83, 0x8b, 0x84, 0x8c, 0x7f, 0x08, 0x65, 0x8b, 0x6f, 0x59, 0xd2, + 0x8b, 0x05, 0x0e, 0xfb, 0xeb, 0xf7, 0xa5, 0xf7, 0xbb, 0x15, 0x50, 0x8c, + 0x80, 0x94, 0x8b, 0xb9, 0x08, 0xf7, 0xe5, 0x80, 0x07, 0xfb, 0x38, 0x4a, + 0x8b, 0x76, 0x05, 0x91, 0x8d, 0x90, 0x8d, 0x8d, 0x8c, 0x9d, 0x91, 0x9b, + 0x8f, 0x94, 0x8b, 0x08, 0x9b, 0x92, 0x7e, 0x6f, 0x1f, 0xfb, 0x71, 0x07, + 0x59, 0x7e, 0x81, 0x4b, 0x1e, 0x77, 0xf7, 0x87, 0x9f, 0x07, 0x0e, 0xfb, + 0xeb, 0xf7, 0xc0, 0xf8, 0x26, 0x15, 0x7b, 0x06, 0x78, 0x60, 0x83, 0x87, + 0x49, 0x8b, 0x08, 0x2f, 0x8b, 0xee, 0xe7, 0x05, 0xc0, 0xbd, 0xa0, 0xaf, + 0x8b, 0xb7, 0x8b, 0xcc, 0x59, 0xb9, 0x45, 0x8b, 0x4b, 0x8b, 0x5e, 0x65, + 0x69, 0x37, 0x08, 0xa3, 0x06, 0xa0, 0xb2, 0xa0, 0x9a, 0xad, 0x8b, 0xb5, + 0x8b, 0xac, 0x69, 0x8b, 0x61, 0x8b, 0x51, 0x68, 0x5b, 0xfb, 0x29, 0xfb, + 0x29, 0x08, 0x7d, 0xf7, 0xa2, 0x07, 0xa9, 0xf7, 0x13, 0x05, 0x0e, 0xfb, + 0xeb, 0xaf, 0xf8, 0xe2, 0x15, 0xa4, 0xb0, 0x9e, 0x98, 0xaa, 0x8b, 0xb2, + 0x8b, 0xa5, 0x73, 0x8b, 0x66, 0x8b, 0x63, 0x74, 0x76, 0x4e, 0x79, 0x08, + 0x81, 0x07, 0xeb, 0x6c, 0xad, 0x6b, 0x8b, 0x51, 0x8b, 0x64, 0x72, 0x71, + 0x65, 0x8b, 0x7b, 0x8b, 0x7f, 0x91, 0x76, 0x9f, 0x6d, 0xa5, 0x83, 0x8f, + 0x6e, 0x8e, 0x70, 0x82, 0x7e, 0x7e, 0x8b, 0x78, 0x08, 0x6a, 0xb2, 0x76, + 0xc8, 0xf7, 0x00, 0xe1, 0xd0, 0xe2, 0x1e, 0x8b, 0xbd, 0x71, 0xae, 0x55, + 0xa1, 0x08, 0xb4, 0xa1, 0x98, 0x9d, 0x8b, 0xaf, 0x8b, 0xbe, 0x64, 0xa9, + 0x48, 0x8b, 0x4a, 0x8b, 0x5b, 0x6d, 0x67, 0x4e, 0x08, 0x9f, 0x84, 0x05, + 0x0e, 0xfc, 0x1d, 0xf7, 0x11, 0xf8, 0x35, 0x15, 0x5d, 0x65, 0x64, 0x5e, + 0x5b, 0xaf, 0x66, 0xba, 0xbb, 0xb1, 0xb0, 0xba, 0xb9, 0x65, 0xb2, 0x5c, + 0x1f, 0x0e, 0xfb, 0xca, 0xf7, 0xb3, 0xf7, 0xb3, 0x15, 0xfb, 0x87, 0xfb, + 0x08, 0xf7, 0x87, 0xf7, 0x08, 0x06, 0x0e, 0xfb, 0x87, 0xf7, 0x5c, 0xf9, + 0x44, 0x15, 0x3b, 0x4c, 0x4c, 0x3b, 0x3c, 0xca, 0x4b, 0xd9, 0xdd, 0xca, + 0xc9, 0xdc, 0xdb, 0x4c, 0xca, 0x3b, 0x1f, 0x67, 0x04, 0xc2, 0xba, 0x5a, + 0x51, 0x50, 0x5d, 0x5b, 0x52, 0x54, 0x5d, 0xbc, 0xc5, 0xc5, 0xb9, 0xbc, + 0xc3, 0x1f, 0x0e, 0x42, 0xf8, 0xad, 0xf7, 0x65, 0x15, 0xe3, 0xfc, 0x8c, + 0x33, 0xf8, 0x8c, 0x07, 0x0e, 0x42, 0xf7, 0x73, 0xf7, 0x91, 0x15, 0xfb, + 0x43, 0xfb, 0x43, 0xc9, 0x4d, 0xf7, 0x43, 0xf7, 0x44, 0xf7, 0x43, 0xfb, + 0x44, 0xc9, 0xc9, 0xfb, 0x44, 0xf7, 0x43, 0xf7, 0x44, 0xf7, 0x43, 0x4d, + 0xc9, 0xfb, 0x43, 0xfb, 0x44, 0xfb, 0x43, 0xf7, 0x44, 0x4d, 0x4d, 0xf7, + 0x43, 0xfb, 0x43, 0x05, 0x0e, 0x42, 0xf8, 0xad, 0xf7, 0x65, 0x15, 0xe3, + 0xfc, 0x8c, 0x33, 0xf8, 0x8c, 0x07, 0xfb, 0x90, 0xf7, 0xdc, 0x15, 0x63, + 0x67, 0x67, 0x63, 0x61, 0xae, 0x68, 0xb5, 0xb3, 0xaf, 0xb0, 0xb3, 0xb3, + 0x67, 0xaf, 0x62, 0x1f, 0xfc, 0x33, 0x04, 0x62, 0x68, 0x68, 0x63, 0x61, + 0xae, 0x67, 0xb5, 0xb2, 0xb0, 0xb1, 0xb3, 0xb3, 0x67, 0xae, 0x62, 0x1f, + 0x0e, 0xf7, 0xf9, 0xf7, 0x8f, 0xf9, 0x20, 0x15, 0xb9, 0x06, 0xae, 0x8b, + 0x9e, 0x78, 0x97, 0x5e, 0x08, 0xa2, 0xe3, 0xfb, 0xfe, 0x33, 0xa2, 0x06, + 0x97, 0xb9, 0x9d, 0x9d, 0xae, 0x8b, 0x08, 0xb9, 0xfb, 0xc9, 0x06, 0x8b, + 0x60, 0x8a, 0x8a, 0x5a, 0x87, 0x08, 0x74, 0xf7, 0x56, 0xa2, 0x07, 0x59, + 0x8f, 0x8a, 0x8c, 0x8b, 0xb6, 0x08, 0xf7, 0xc9, 0x07, 0xf8, 0x35, 0xfc, + 0x11, 0x15, 0x98, 0x8b, 0xf7, 0x29, 0xf7, 0xbe, 0x8b, 0xfb, 0x76, 0x05, + 0x8b, 0x60, 0x8b, 0x8a, 0x59, 0x87, 0x08, 0x74, 0xf7, 0x56, 0xa2, 0x07, + 0x59, 0x8f, 0x8a, 0x8c, 0x8b, 0xb6, 0x08, 0xf7, 0x9a, 0x07, 0x8b, 0xaf, + 0x95, 0x94, 0xb7, 0x8e, 0x08, 0xa2, 0xfb, 0x0a, 0x07, 0xfb, 0x2b, 0xfb, + 0xb5, 0xfb, 0x22, 0xf7, 0xb5, 0xfb, 0x1f, 0x8b, 0x05, 0x74, 0x07, 0xa9, + 0x8a, 0xa4, 0x79, 0x9a, 0x6a, 0x08, 0xfb, 0x81, 0x07, 0x8b, 0x54, 0x83, + 0x81, 0x5f, 0x87, 0x08, 0x74, 0xf7, 0x19, 0xa2, 0x07, 0x5e, 0x8f, 0x84, + 0x95, 0x8b, 0xc2, 0x08, 0x8b, 0xf7, 0x5f, 0x05, 0xf7, 0x22, 0xfb, 0xbc, + 0x05, 0x0e, 0x42, 0xf7, 0x85, 0xf7, 0xfb, 0x15, 0xfb, 0x64, 0x33, 0xf7, + 0x64, 0xfb, 0x23, 0xe3, 0xf7, 0x23, 0xf7, 0x64, 0xe3, 0xfb, 0x64, 0xf7, + 0x65, 0x33, 0xfb, 0x65, 0x06, 0xfb, 0x64, 0xfb, 0xfb, 0x15, 0xf8, 0x8c, + 0xe3, 0xfc, 0x8c, 0x33, 0x06, 0x0e, 0xf6, 0xf8, 0xd1, 0xf9, 0x44, 0x15, + 0xfc, 0x4d, 0xfd, 0x50, 0xc5, 0x8b, 0xf8, 0x4b, 0xf9, 0x50, 0x05, 0x53, + 0x06, 0xfb, 0xe3, 0xfc, 0x1d, 0x15, 0x50, 0x8c, 0x80, 0x94, 0x8b, 0xb9, + 0x08, 0xf7, 0xe5, 0x80, 0x07, 0xfb, 0x38, 0x4a, 0x8b, 0x76, 0x05, 0x91, + 0x8d, 0x90, 0x8d, 0x8d, 0x8c, 0x9d, 0x91, 0x9b, 0x8f, 0x94, 0x8b, 0x08, + 0x9b, 0x92, 0x7e, 0x6f, 0x1f, 0xfb, 0x71, 0x07, 0x59, 0x7e, 0x81, 0x4b, + 0x1e, 0x77, 0xf7, 0x87, 0x9f, 0x07, 0xf8, 0xad, 0xfb, 0x3c, 0x15, 0x7b, + 0x06, 0x78, 0x60, 0x83, 0x87, 0x49, 0x8b, 0x08, 0x35, 0x90, 0x06, 0xe8, + 0xe2, 0x05, 0xc1, 0xbd, 0x9f, 0xaf, 0x8b, 0xb7, 0x8b, 0xcc, 0x59, 0xb9, + 0x45, 0x8b, 0x4b, 0x8b, 0x5e, 0x65, 0x69, 0x37, 0x08, 0xa3, 0x06, 0xa0, + 0xb2, 0xa0, 0x9a, 0xad, 0x8b, 0xb5, 0x8b, 0xac, 0x69, 0x8b, 0x61, 0x8b, + 0x51, 0x68, 0x5b, 0xfb, 0x29, 0xfb, 0x29, 0x08, 0x7d, 0xf7, 0xa2, 0x07, + 0xa9, 0xf7, 0x13, 0x05, 0x0e, 0xf6, 0xf9, 0x52, 0xf7, 0x2d, 0x15, 0xf7, + 0x98, 0x57, 0x07, 0x64, 0x5d, 0x05, 0x32, 0xfb, 0x00, 0x6a, 0x61, 0x61, + 0x4c, 0x08, 0x48, 0xf7, 0x35, 0x34, 0x07, 0xe9, 0xe2, 0xb4, 0xcd, 0x06, + 0x62, 0x06, 0x2e, 0x16, 0xfb, 0x1d, 0x8b, 0xf7, 0x1d, 0xf7, 0x43, 0x05, + 0xfb, 0x43, 0x07, 0x91, 0xf8, 0xab, 0x15, 0xfc, 0x4d, 0xfd, 0x50, 0xc5, + 0x8b, 0xf8, 0x4b, 0xf9, 0x50, 0x53, 0x8b, 0x05, 0xfb, 0xea, 0xfc, 0x1d, + 0x15, 0x50, 0x8c, 0x80, 0x94, 0x8b, 0xb9, 0x08, 0xf7, 0xe5, 0x80, 0x07, + 0xfb, 0x38, 0x4a, 0x8b, 0x76, 0x05, 0x91, 0x8d, 0x90, 0x8d, 0x8d, 0x8c, + 0x9d, 0x91, 0x9b, 0x8f, 0x94, 0x8b, 0x08, 0x9b, 0x92, 0x7e, 0x6f, 0x1f, + 0xfb, 0x71, 0x07, 0x59, 0x7e, 0x81, 0x4b, 0x1e, 0x77, 0xf7, 0x87, 0x9f, + 0x07, 0x0e, 0xf6, 0xf8, 0xf9, 0xf9, 0x44, 0x15, 0xfc, 0x4d, 0xfd, 0x50, + 0xc5, 0x8b, 0xf8, 0x4b, 0xf9, 0x50, 0x05, 0x53, 0x06, 0xfc, 0xc1, 0x29, + 0x15, 0xa4, 0xb0, 0x9e, 0x98, 0xaa, 0x8b, 0xb2, 0x8b, 0xa5, 0x73, 0x8b, + 0x66, 0x8b, 0x63, 0x74, 0x76, 0x4e, 0x79, 0x08, 0x81, 0x07, 0xeb, 0x6c, + 0xad, 0x6b, 0x8b, 0x51, 0x8b, 0x64, 0x72, 0x71, 0x65, 0x8b, 0x7b, 0x8b, + 0x7f, 0x91, 0x76, 0x9f, 0x6d, 0xa5, 0x83, 0x8f, 0x6e, 0x8e, 0x70, 0x82, + 0x7e, 0x7e, 0x8b, 0x78, 0x08, 0x6a, 0xb2, 0x76, 0xc8, 0xf7, 0x00, 0xe1, + 0xd0, 0xe2, 0x1e, 0x8b, 0xbc, 0x71, 0xaf, 0x59, 0x9f, 0x08, 0x8f, 0x07, + 0xb0, 0x9f, 0x98, 0x9e, 0x8b, 0xae, 0x8b, 0xbe, 0x64, 0xa9, 0x48, 0x8b, + 0x4a, 0x8b, 0x5b, 0x6d, 0x67, 0x4e, 0x08, 0x9f, 0x84, 0x05, 0xf9, 0x10, + 0xfc, 0x49, 0x15, 0xf7, 0x98, 0x57, 0x07, 0x64, 0x5d, 0x05, 0x32, 0xfb, + 0x00, 0x6a, 0x61, 0x61, 0x4c, 0x08, 0x48, 0xf7, 0x35, 0x07, 0x34, 0x07, + 0xe9, 0xe2, 0xb4, 0xcd, 0x62, 0x06, 0x2e, 0x16, 0xfb, 0x1d, 0x8b, 0xf7, + 0x1d, 0xf7, 0x43, 0x05, 0xfb, 0x43, 0x07, 0x0e, 0xf3, 0xf8, 0xa1, 0xf7, + 0x94, 0x15, 0x6b, 0x4a, 0x67, 0x71, 0x53, 0x8b, 0x08, 0x3d, 0x5e, 0xcc, + 0xf7, 0x06, 0xf7, 0x06, 0xb7, 0xca, 0xda, 0x1f, 0xc3, 0x8b, 0xac, 0x6f, + 0x9d, 0x4e, 0x08, 0x9e, 0xd3, 0x06, 0x8b, 0x95, 0x85, 0x90, 0x7b, 0x91, + 0x63, 0x99, 0x71, 0x90, 0x66, 0x8b, 0x08, 0xfb, 0x1e, 0x33, 0x3b, 0xfb, + 0x10, 0xfb, 0x0e, 0xde, 0x3f, 0xf7, 0x17, 0x1f, 0xa9, 0x8b, 0xa7, 0x8f, + 0xb0, 0x95, 0x90, 0x8d, 0x92, 0x8c, 0x8b, 0x8b, 0x9e, 0x90, 0x96, 0x93, + 0x8c, 0x95, 0x08, 0x9b, 0xd5, 0x78, 0x8b, 0x05, 0xfb, 0x2b, 0xf8, 0x47, + 0x15, 0xfb, 0x58, 0xfb, 0x2c, 0xfb, 0x30, 0xfb, 0x5c, 0xfb, 0x59, 0xf7, + 0x2c, 0xfb, 0x31, 0xf7, 0x53, 0xf7, 0x5e, 0xf7, 0x2a, 0xf7, 0x2c, 0xf7, + 0x60, 0xf7, 0x5b, 0xfb, 0x2c, 0xf7, 0x2f, 0xfb, 0x57, 0x1f, 0x57, 0x04, + 0xf7, 0x2d, 0xf7, 0x0f, 0xfb, 0x1b, 0xfb, 0x3c, 0xfb, 0x3e, 0xfb, 0x0e, + 0xfb, 0x19, 0xfb, 0x32, 0xfb, 0x2a, 0xfb, 0x0f, 0xf7, 0x1c, 0xf7, 0x3a, + 0xf7, 0x3d, 0xf7, 0x0f, 0xf7, 0x1b, 0xf7, 0x2e, 0x1f, 0x0e, 0xf3, 0xf7, + 0x63, 0xf8, 0x96, 0x15, 0xb9, 0x88, 0x8b, 0x8b, 0x8b, 0x62, 0x08, 0xfb, + 0x93, 0x07, 0x8b, 0x63, 0x8a, 0x8a, 0x5e, 0x88, 0x08, 0x79, 0xf7, 0x40, + 0x9d, 0x07, 0x5e, 0x8e, 0x8a, 0x8c, 0x8b, 0xb3, 0x08, 0xf4, 0xb0, 0x07, + 0xa0, 0x69, 0x95, 0x7b, 0x9d, 0x67, 0xaa, 0x4f, 0x9b, 0x76, 0x9b, 0x8b, + 0x08, 0xdc, 0x96, 0x06, 0x76, 0x9f, 0x77, 0xa4, 0x6e, 0xb3, 0x08, 0x51, + 0xdd, 0x05, 0xc0, 0xa0, 0xa6, 0xaf, 0x8b, 0xbb, 0x08, 0xc6, 0x5f, 0xb0, + 0x44, 0x1e, 0xfb, 0x55, 0x79, 0x06, 0xf7, 0x12, 0x87, 0x15, 0xaf, 0x06, + 0xb4, 0x9f, 0x71, 0x55, 0x53, 0x74, 0x6b, 0x64, 0x1f, 0x68, 0xf7, 0x3c, + 0x06, 0xb4, 0xf7, 0x49, 0x15, 0xfb, 0x58, 0xfb, 0x2c, 0xfb, 0x30, 0xfb, + 0x5c, 0xfb, 0x59, 0xf7, 0x2c, 0xfb, 0x31, 0xf7, 0x53, 0xf7, 0x5e, 0xf7, + 0x2a, 0xf7, 0x2c, 0xf7, 0x60, 0xf7, 0x5b, 0xfb, 0x2c, 0xf7, 0x2f, 0xfb, + 0x57, 0x1f, 0x57, 0x04, 0xf7, 0x2d, 0xf7, 0x0f, 0xfb, 0x1b, 0xfb, 0x3c, + 0xfb, 0x3e, 0xfb, 0x0e, 0xfb, 0x19, 0xfb, 0x32, 0xfb, 0x2a, 0xfb, 0x0f, + 0xf7, 0x1c, 0xf7, 0x3a, 0xf7, 0x3d, 0xf7, 0x0f, 0xf7, 0x1b, 0xf7, 0x2e, + 0x1f, 0x0e, 0xfc, 0x1d, 0x0e, 0x42, 0xf8, 0x55, 0xf7, 0x00, 0x15, 0xe3, + 0xf7, 0xb7, 0xfc, 0x8c, 0x33, 0xf8, 0x34, 0xfb, 0x5f, 0x06, 0x0e, 0xfc, + 0x3b, 0xcd, 0x78, 0x15, 0xe3, 0xf7, 0xa9, 0x33, 0xfb, 0xa9, 0x06, 0xf8, + 0x45, 0x04, 0xe3, 0xf7, 0xa9, 0x33, 0xfb, 0xa9, 0x06, 0x0e, 0x34, 0xf8, + 0x6f, 0xf8, 0x61, 0x15, 0xfb, 0x1f, 0xfb, 0xfb, 0x06, 0x6f, 0x79, 0x72, + 0x82, 0x76, 0x8b, 0x08, 0x69, 0x74, 0xa9, 0xb7, 0x1f, 0xf7, 0xcc, 0xfb, + 0x1f, 0xfc, 0x09, 0x07, 0x8b, 0x56, 0x85, 0x5e, 0x7b, 0x4d, 0x83, 0x6e, + 0x88, 0x7c, 0x8b, 0x7e, 0x08, 0x5a, 0xa3, 0x6f, 0xb4, 0xb3, 0xa2, 0xa6, + 0xbc, 0x1e, 0x8b, 0x9c, 0x87, 0x9f, 0x80, 0xad, 0x7f, 0xb4, 0x89, 0x92, + 0x87, 0xac, 0xab, 0x72, 0xa9, 0x81, 0xb3, 0x8b, 0xb4, 0x8b, 0xa6, 0x99, + 0xaa, 0xb1, 0xa1, 0x67, 0xaa, 0x7b, 0xbb, 0x8b, 0xb5, 0x8b, 0x9f, 0x95, + 0xb7, 0xb2, 0x08, 0xa3, 0x07, 0x82, 0x86, 0x86, 0x8a, 0x84, 0x8b, 0x08, + 0x75, 0x79, 0xa0, 0xa5, 0x1f, 0xf7, 0xfc, 0x07, 0x0e, 0xf8, 0x88, 0x14, + 0xf9, 0x17, 0x15, 0x78, 0x9e, 0xf8, 0x61, 0x97, 0xf7, 0x5f, 0x9a, 0x06, + 0x1e, 0x0a, 0x03, 0x96, 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xac, + 0x0a, 0xac, 0x96, 0x8f, 0x92, 0x96, 0x92, 0x0c, 0x0c, 0xf7, 0x20, 0x0b, + 0xf7, 0x0a, 0xa1, 0x93, 0x9a, 0x96, 0x8f, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e +}; +const unsigned int fonts_NimbusRomNo9L_Medi_cff_len = 24324; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-MediItal.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-MediItal.cff.c new file mode 100644 index 00000000000..0fb847fa257 --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-MediItal.cff.c @@ -0,0 +1,2263 @@ +const unsigned char fonts_NimbusRomNo9L_MediItal_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x17, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x52, 0x6f, 0x6d, 0x4e, 0x6f, 0x39, 0x4c, 0x2d, 0x4d, + 0x65, 0x64, 0x69, 0x49, 0x74, 0x61, 0x6c, 0x00, 0x01, 0x02, 0x00, 0x01, + 0x00, 0x38, 0xf8, 0x1f, 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, + 0x22, 0x03, 0xf8, 0x14, 0x04, 0x1e, 0xe1, 0x5a, 0x3f, 0x0c, 0x02, 0x1d, + 0x00, 0x4c, 0x9d, 0x0b, 0x0d, 0xfb, 0x5c, 0xfb, 0x6e, 0xfa, 0x78, 0xfa, + 0x49, 0x05, 0x1c, 0x01, 0x04, 0x0f, 0x1c, 0x00, 0x00, 0x10, 0x1c, 0x02, + 0xd5, 0x11, 0x1c, 0x00, 0x2e, 0x1c, 0x69, 0xc1, 0x12, 0x00, 0x08, 0x02, + 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, + 0x00, 0x5f, 0x00, 0x7f, 0x00, 0x91, 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, + 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, + 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, + 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, + 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, + 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x52, + 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x4e, 0x6f, 0x39, 0x20, 0x4c, 0x20, 0x4d, + 0x65, 0x64, 0x69, 0x75, 0x6d, 0x20, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, + 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x52, 0x6f, 0x6d, 0x61, 0x6e, + 0x20, 0x4e, 0x6f, 0x39, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, + 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, + 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, + 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, + 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, + 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, + 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, + 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, + 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, + 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, + 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, + 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, + 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, + 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, + 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, + 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, + 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, + 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, + 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, + 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, + 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, + 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, + 0xae, 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, + 0xb4, 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, + 0xb9, 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, + 0xbc, 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, + 0xc2, 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, + 0xc8, 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, + 0xd1, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, + 0xd6, 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, + 0xd9, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, + 0xdf, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, + 0x87, 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, + 0xa1, 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, + 0x9b, 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, + 0x97, 0x00, 0xa0, 0x00, 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, 0x04, + 0x00, 0x07, 0x00, 0x4f, 0x00, 0x97, 0x00, 0xf5, 0x01, 0xa4, 0x02, 0x77, + 0x03, 0x30, 0x03, 0x5f, 0x03, 0x9b, 0x03, 0xd8, 0x04, 0xd6, 0x04, 0xf2, + 0x05, 0x20, 0x05, 0x35, 0x05, 0x4d, 0x05, 0x62, 0x05, 0xc3, 0x06, 0x08, + 0x06, 0x5b, 0x06, 0xce, 0x07, 0x01, 0x07, 0x55, 0x07, 0xbb, 0x07, 0xdd, + 0x08, 0x5f, 0x08, 0xcf, 0x08, 0xfe, 0x09, 0x42, 0x09, 0x5f, 0x09, 0x77, + 0x09, 0x93, 0x09, 0xf9, 0x0a, 0xbb, 0x0b, 0x18, 0x0b, 0xb8, 0x0c, 0x29, + 0x0c, 0x9d, 0x0d, 0x33, 0x0d, 0xb5, 0x0e, 0x4b, 0x0e, 0xe8, 0x0f, 0x31, + 0x0f, 0x91, 0x10, 0x2b, 0x10, 0x86, 0x11, 0x07, 0x11, 0x6a, 0x11, 0xca, + 0x12, 0x4a, 0x13, 0x02, 0x13, 0x8b, 0x14, 0x1b, 0x14, 0x64, 0x14, 0xe9, + 0x15, 0x3c, 0x15, 0xb3, 0x16, 0x4f, 0x16, 0xc2, 0x17, 0x02, 0x17, 0x36, + 0x17, 0x4a, 0x17, 0x77, 0x17, 0x95, 0x17, 0xa2, 0x17, 0xd1, 0x18, 0x4f, + 0x18, 0xbf, 0x19, 0x1c, 0x19, 0xb0, 0x1a, 0x10, 0x1a, 0x9f, 0x1b, 0x6e, + 0x1c, 0x0a, 0x1c, 0x70, 0x1c, 0xda, 0x1d, 0x4c, 0x1d, 0xa2, 0x1e, 0x6b, + 0x1e, 0xfa, 0x1f, 0x42, 0x1f, 0xcf, 0x20, 0x53, 0x20, 0xaa, 0x21, 0x2a, + 0x21, 0x7a, 0x22, 0x02, 0x22, 0x5d, 0x22, 0xd1, 0x23, 0x6d, 0x23, 0xec, + 0x24, 0x59, 0x24, 0xc5, 0x24, 0xd2, 0x25, 0x3e, 0x25, 0x7f, 0x25, 0xc8, + 0x26, 0x49, 0x26, 0xfe, 0x27, 0x13, 0x27, 0x9e, 0x28, 0x26, 0x28, 0xef, + 0x29, 0x5a, 0x29, 0x81, 0x29, 0xd8, 0x2a, 0x5f, 0x2a, 0xa6, 0x2a, 0xed, + 0x2b, 0xb5, 0x2c, 0x75, 0x2c, 0x86, 0x2d, 0x2e, 0x2e, 0x38, 0x2e, 0x51, + 0x2e, 0xd8, 0x2e, 0xf1, 0x2f, 0x1f, 0x2f, 0x76, 0x2f, 0xcd, 0x30, 0x54, + 0x30, 0x95, 0x31, 0xa3, 0x32, 0x0a, 0x32, 0x30, 0x32, 0x56, 0x32, 0x71, + 0x32, 0xb4, 0x32, 0xc7, 0x32, 0xed, 0x33, 0x06, 0x33, 0x33, 0x33, 0x60, + 0x33, 0xa1, 0x33, 0xe8, 0x34, 0x2c, 0x34, 0x47, 0x34, 0x5a, 0x35, 0x1f, + 0x35, 0x9a, 0x36, 0x07, 0x36, 0xa8, 0x37, 0x8c, 0x37, 0xd2, 0x38, 0x86, + 0x38, 0xd7, 0x39, 0x3a, 0x39, 0xc4, 0x3a, 0x7c, 0x3b, 0x3f, 0x3b, 0xc6, + 0x3c, 0x46, 0x3c, 0xc6, 0x3d, 0x3b, 0x3d, 0xd9, 0x3e, 0x60, 0x3f, 0x11, + 0x3f, 0x99, 0x40, 0x59, 0x41, 0x12, 0x41, 0xcb, 0x42, 0x78, 0x42, 0xea, + 0x43, 0x55, 0x43, 0xc0, 0x44, 0x20, 0x44, 0xc3, 0x45, 0x4c, 0x45, 0xcd, + 0x46, 0x4e, 0x46, 0xc5, 0x47, 0x64, 0x48, 0x0c, 0x48, 0xbb, 0x49, 0x62, + 0x4a, 0x09, 0x4a, 0xa5, 0x4b, 0x3b, 0x4b, 0x92, 0x4c, 0x1f, 0x4c, 0xbb, + 0x4d, 0x62, 0x4e, 0x01, 0x4e, 0xa1, 0x4f, 0x36, 0x4f, 0xf4, 0x50, 0x9b, + 0x51, 0x39, 0x51, 0xc3, 0x52, 0x45, 0x52, 0xc8, 0x53, 0x40, 0x53, 0xbb, + 0x54, 0x2e, 0x54, 0xa1, 0x55, 0x09, 0x55, 0xd7, 0x56, 0x4a, 0x56, 0xb3, + 0x57, 0x1c, 0x57, 0x7b, 0x58, 0x04, 0x58, 0x9b, 0x59, 0x4e, 0x59, 0xf9, + 0x5a, 0xa3, 0x5b, 0x42, 0x5b, 0xe3, 0x5c, 0x68, 0x5c, 0xe6, 0x5d, 0x76, + 0x5e, 0x20, 0x5e, 0xb3, 0x5e, 0xfc, 0x5f, 0x4a, 0x5f, 0xae, 0x5f, 0xc7, + 0x5f, 0xdc, 0x60, 0x08, 0x60, 0x16, 0x60, 0x46, 0x60, 0x7d, 0x61, 0x19, + 0x61, 0x41, 0x61, 0xe6, 0x62, 0x70, 0x63, 0x15, 0x63, 0xad, 0x64, 0x59, + 0x64, 0x5c, 0x64, 0x6e, 0x64, 0x85, 0x65, 0x16, 0xfc, 0x1d, 0x0e, 0xfc, + 0x1d, 0x0e, 0xfb, 0x92, 0xf7, 0x58, 0xf7, 0x60, 0x15, 0xb5, 0xf7, 0x00, + 0xb8, 0xee, 0xc3, 0xf7, 0x03, 0xa5, 0xba, 0x90, 0x9a, 0x8b, 0xa6, 0x8b, + 0xb7, 0x6f, 0xa8, 0x62, 0x8b, 0x6c, 0x8b, 0x73, 0x7a, 0x7d, 0x6e, 0x83, + 0x79, 0x89, 0x80, 0x89, 0x5f, 0x86, 0x3d, 0x79, 0xfb, 0x0b, 0x6d, 0xfb, + 0x30, 0x08, 0xa8, 0x83, 0x05, 0x53, 0x44, 0x15, 0x62, 0x6b, 0x6a, 0x61, + 0x62, 0xaa, 0x6d, 0xb4, 0xb4, 0xac, 0xab, 0xb2, 0xb2, 0x68, 0xaf, 0x65, + 0x1f, 0x0e, 0x33, 0xf7, 0x45, 0xf8, 0x22, 0x15, 0xdd, 0xf7, 0x4e, 0x8d, + 0x90, 0x05, 0x99, 0xaa, 0x8c, 0x8d, 0x8b, 0x99, 0x8b, 0xa6, 0x77, 0xa1, + 0x71, 0x8b, 0x65, 0x8b, 0x66, 0x68, 0x88, 0x65, 0x08, 0x7b, 0xfb, 0x6a, + 0xb4, 0x8b, 0x05, 0xf7, 0x98, 0x16, 0xdd, 0xf7, 0x4e, 0x8d, 0x90, 0x05, + 0x99, 0xaa, 0x8c, 0x8d, 0x8b, 0x99, 0x8b, 0xa6, 0x77, 0xa1, 0x71, 0x8b, + 0x65, 0x8b, 0x66, 0x68, 0x88, 0x65, 0x08, 0x7b, 0xfb, 0x6a, 0xb4, 0x8b, + 0x05, 0x0e, 0xf8, 0x55, 0xf7, 0xaf, 0x15, 0x34, 0x8b, 0xc1, 0xf7, 0x1a, + 0xec, 0x8b, 0x9f, 0xd4, 0x33, 0x8b, 0xe1, 0xf7, 0x66, 0x3e, 0x8b, 0x34, + 0xfb, 0x66, 0xfb, 0x05, 0x8b, 0xe1, 0xf7, 0x66, 0x3e, 0x8b, 0x34, 0xfb, + 0x66, 0x22, 0x8b, 0x77, 0x42, 0xeb, 0x8b, 0x05, 0x55, 0xfb, 0x1a, 0x21, + 0x8b, 0x77, 0x42, 0xeb, 0x8b, 0x36, 0xfb, 0x66, 0xd9, 0x8b, 0xe0, 0xf7, + 0x66, 0xf7, 0x05, 0x8b, 0x36, 0xfb, 0x66, 0xd9, 0x8b, 0xe0, 0xf7, 0x66, + 0xec, 0x8b, 0x9f, 0xd4, 0x05, 0xfb, 0x03, 0xf7, 0x1a, 0x15, 0x55, 0xfb, + 0x1a, 0xfb, 0x05, 0x8b, 0xc1, 0xf7, 0x1a, 0xf7, 0x05, 0x8b, 0x05, 0x0e, + 0xf8, 0x85, 0xf8, 0xea, 0x15, 0x79, 0x99, 0x05, 0x65, 0xa3, 0x5c, 0x9e, + 0x6a, 0x91, 0x08, 0x9f, 0xd3, 0x59, 0x8b, 0x79, 0x4a, 0x05, 0x75, 0x8d, + 0x83, 0x8b, 0x83, 0x8b, 0xfb, 0x03, 0x8b, 0x36, 0x3c, 0x8b, 0x24, 0x8b, + 0x47, 0xa5, 0x67, 0xf5, 0x3a, 0x08, 0x41, 0xfb, 0x99, 0x05, 0x45, 0xab, + 0x77, 0xb3, 0x88, 0xf7, 0x00, 0x08, 0x75, 0x91, 0x61, 0xfb, 0x22, 0x05, + 0xc0, 0x5c, 0xaa, 0x7a, 0xca, 0x7c, 0x08, 0x6e, 0x20, 0xbf, 0x8b, 0xa7, + 0xef, 0xa2, 0x8b, 0x05, 0xf7, 0x16, 0xf0, 0xe2, 0xf7, 0x06, 0x1f, 0x8b, + 0xb0, 0x7e, 0xb2, 0x74, 0xaa, 0x73, 0xa9, 0x78, 0x9e, 0x4e, 0xc0, 0x08, + 0xc6, 0xf7, 0x6b, 0x05, 0xc7, 0x77, 0xa3, 0x67, 0x8b, 0x46, 0x8b, 0x85, + 0x8b, 0x7e, 0x8a, 0x80, 0x08, 0xa0, 0x86, 0xb5, 0xf7, 0x19, 0x05, 0xfb, + 0x8d, 0xfb, 0x36, 0x15, 0x56, 0xb3, 0x7a, 0xa5, 0x8b, 0xb3, 0x8b, 0xc4, + 0xb7, 0xb1, 0xcd, 0x8b, 0x91, 0x8b, 0x8f, 0x8b, 0x90, 0x89, 0x08, 0x54, + 0xfb, 0x5b, 0x05, 0x90, 0xfb, 0x36, 0x15, 0xc2, 0x5f, 0x9a, 0x71, 0x8b, + 0x5c, 0x8b, 0x53, 0x6e, 0x5f, 0x5c, 0x79, 0x7a, 0x85, 0x82, 0x8a, 0x68, + 0x8b, 0x08, 0xce, 0xf7, 0x86, 0x05, 0x0e, 0xf7, 0x52, 0xf9, 0x38, 0xf8, + 0x0c, 0x15, 0x5a, 0x8b, 0x5e, 0x77, 0x60, 0x63, 0x55, 0x58, 0x68, 0x42, + 0x8b, 0x4b, 0x8b, 0x38, 0xc0, 0x54, 0xdb, 0x8b, 0xb8, 0x8b, 0xb9, 0x9f, + 0xab, 0xad, 0xc1, 0xc4, 0xac, 0xde, 0x8b, 0xd7, 0x8b, 0xd0, 0x5c, 0xba, + 0x45, 0x8b, 0x08, 0xab, 0x58, 0x15, 0xa9, 0x89, 0xa0, 0x6f, 0x8b, 0x65, + 0x8b, 0x60, 0x7d, 0x5d, 0x70, 0x5a, 0x6d, 0x55, 0x68, 0x6e, 0x67, 0x8b, + 0x6d, 0x8b, 0x75, 0xa4, 0x8d, 0xab, 0x8e, 0xb7, 0xae, 0xe8, 0xa9, 0xb6, + 0xa2, 0xae, 0xa5, 0x9d, 0xa3, 0x8a, 0x08, 0xfc, 0x96, 0xfb, 0xe1, 0x15, + 0xc3, 0x8b, 0xf8, 0x1e, 0xf9, 0x50, 0x64, 0x8b, 0x05, 0x53, 0x5a, 0x59, + 0x77, 0x4c, 0x8b, 0x61, 0x8b, 0x71, 0x93, 0x6f, 0x9f, 0x6e, 0xa0, 0x78, + 0x92, 0x6e, 0x8b, 0x08, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x10, 0xfb, 0x10, + 0x3b, 0xc1, 0x52, 0xd6, 0x1f, 0xc7, 0x8b, 0xc0, 0xaa, 0xb2, 0xc4, 0xb6, + 0xc9, 0x9c, 0xc4, 0x8c, 0xe4, 0x9f, 0x88, 0x98, 0x89, 0x95, 0x8b, 0xb0, + 0x8b, 0xb2, 0x94, 0xb6, 0x9d, 0x08, 0xfb, 0xf1, 0xfd, 0x00, 0x05, 0xe8, + 0xf9, 0x13, 0x15, 0x90, 0x8a, 0x8e, 0x8a, 0x92, 0x85, 0x93, 0x83, 0x8c, + 0x8b, 0x92, 0x88, 0xa7, 0x80, 0x8c, 0x89, 0x8b, 0x75, 0x8b, 0xfb, 0x06, + 0x40, 0xfb, 0x0f, 0x45, 0x8b, 0x6e, 0x8b, 0x76, 0xa2, 0x8d, 0xaa, 0x8e, + 0xba, 0xad, 0xe5, 0xac, 0xbd, 0x08, 0xa1, 0xab, 0xa3, 0x9f, 0x9c, 0x89, + 0x08, 0x0e, 0xf7, 0x1b, 0xf9, 0x35, 0xf0, 0x15, 0x6e, 0x6e, 0x76, 0x80, + 0x70, 0x8b, 0x64, 0x8b, 0x6b, 0xa0, 0x64, 0xbe, 0xf7, 0x1e, 0xf7, 0x4e, + 0x90, 0x90, 0xc9, 0x97, 0x08, 0xa4, 0xfb, 0x68, 0x72, 0x07, 0xb5, 0x84, + 0x99, 0x82, 0x8b, 0x75, 0x8b, 0x6f, 0x7a, 0x6e, 0x52, 0x43, 0x62, 0xcd, + 0x6a, 0xe2, 0x7f, 0xd5, 0x08, 0xf7, 0x10, 0xbd, 0xc5, 0xc2, 0x8b, 0xce, + 0x08, 0xcd, 0x51, 0xbb, 0x3b, 0xfb, 0x02, 0x40, 0x37, 0xfb, 0x0e, 0x1e, + 0x8b, 0x73, 0x8e, 0x74, 0x93, 0x5e, 0xfb, 0x08, 0x59, 0x6b, 0x79, 0x69, + 0x67, 0x66, 0x65, 0x76, 0x5b, 0x8b, 0x5d, 0x08, 0x28, 0xda, 0x47, 0xf7, + 0x06, 0x1e, 0xd1, 0x8b, 0xc3, 0x9d, 0xcd, 0xb8, 0x08, 0xb8, 0x5f, 0xb4, + 0x79, 0xc0, 0x8b, 0xcd, 0x8b, 0xb6, 0xa4, 0xc8, 0xd4, 0x08, 0x71, 0xa0, + 0x05, 0xfc, 0x38, 0xf7, 0x86, 0x15, 0xa5, 0xfb, 0x03, 0xa6, 0x4a, 0xc3, + 0x34, 0x63, 0x77, 0x71, 0x83, 0x6c, 0x8b, 0x43, 0x8b, 0x54, 0xc6, 0x8b, + 0xda, 0x08, 0x8b, 0xd1, 0xaa, 0xb5, 0xdf, 0xb4, 0x08, 0xf7, 0x05, 0xe6, + 0x15, 0x82, 0xc1, 0x89, 0x9c, 0x8b, 0xa4, 0x08, 0xd8, 0xa4, 0xb5, 0xb8, + 0xac, 0x9e, 0x72, 0x61, 0x1e, 0x8b, 0x5f, 0x73, 0x60, 0x64, 0x6d, 0x80, + 0x82, 0x8b, 0x8b, 0x66, 0x75, 0x08, 0x0e, 0xfb, 0xca, 0xf7, 0x03, 0xf8, + 0x05, 0x15, 0xf7, 0x07, 0xbd, 0xd7, 0xe2, 0x8b, 0xdc, 0x08, 0xc6, 0x69, + 0xb2, 0x58, 0x62, 0x6d, 0x6c, 0x61, 0x1e, 0x8b, 0x70, 0x95, 0x7b, 0xa9, + 0x76, 0xa2, 0x7c, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x67, 0x63, 0x64, 0x3d, + 0x61, 0x08, 0x98, 0x73, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0xda, 0xf9, 0x41, + 0x15, 0xfb, 0x2c, 0xfb, 0x04, 0x4f, 0x4a, 0x5d, 0x23, 0x70, 0x4f, 0x7e, + 0x4a, 0x8b, 0x43, 0x8b, 0xfb, 0x1d, 0xb4, 0xfb, 0x03, 0xf0, 0xfb, 0x1e, + 0x08, 0xa2, 0x9a, 0x05, 0x54, 0xeb, 0x7b, 0xc9, 0x8b, 0xf7, 0x08, 0x8b, + 0xf7, 0x13, 0xa4, 0xf7, 0x15, 0xb6, 0xeb, 0xaf, 0xdc, 0xb0, 0xbb, 0xdc, + 0xd5, 0x08, 0x79, 0x9f, 0x05, 0x0e, 0xfb, 0xca, 0x70, 0xfb, 0x47, 0x15, + 0xf7, 0x09, 0xdf, 0xbe, 0xbb, 0xbe, 0xdb, 0xc0, 0xdc, 0xa5, 0xe3, 0x8b, + 0xec, 0x8b, 0xd4, 0x7b, 0xd9, 0x6c, 0xd5, 0x74, 0xc3, 0x76, 0xad, 0x57, + 0xd2, 0x08, 0x74, 0x7c, 0x05, 0xc1, 0x31, 0x9d, 0x48, 0x8b, 0xfb, 0x06, + 0x8b, 0xfb, 0x19, 0x6b, 0xfb, 0x2c, 0x59, 0x27, 0x6b, 0x4a, 0x6c, 0x65, + 0x3f, 0x45, 0x08, 0x9c, 0x77, 0x05, 0x0e, 0xf7, 0x91, 0xf8, 0x76, 0x15, + 0x80, 0x91, 0x05, 0x6e, 0x9c, 0x7f, 0x97, 0x73, 0xb1, 0x75, 0xae, 0x7a, + 0x98, 0x73, 0x8b, 0x72, 0x8b, 0x73, 0x71, 0x8b, 0x6f, 0x8b, 0x7a, 0x94, + 0x7e, 0x9c, 0x80, 0x99, 0x82, 0x95, 0x89, 0xa8, 0x8b, 0xb7, 0x8a, 0x98, + 0x88, 0xac, 0x78, 0x08, 0x96, 0x85, 0x80, 0x85, 0x05, 0x6a, 0x78, 0x80, + 0x89, 0x5d, 0x89, 0x6e, 0x8b, 0x7f, 0x88, 0x7f, 0x84, 0x7b, 0x82, 0x81, + 0x7a, 0x8b, 0x7c, 0x8b, 0x6e, 0xa2, 0x72, 0xa6, 0x8b, 0xa4, 0x8b, 0x9b, + 0x97, 0xa0, 0xaf, 0xa1, 0xaf, 0x95, 0x95, 0xac, 0x9f, 0x08, 0x96, 0x91, + 0x8b, 0x7f, 0x05, 0x8b, 0x6b, 0x84, 0x73, 0x78, 0x6a, 0x7f, 0x75, 0x86, + 0x7e, 0x8b, 0x7d, 0x08, 0x6c, 0x9f, 0x76, 0xa9, 0xaa, 0x9f, 0xa0, 0xa9, + 0x1e, 0x8b, 0x9a, 0x86, 0x98, 0x7f, 0xa1, 0x78, 0xac, 0x84, 0xa3, 0x8b, + 0xab, 0x08, 0x8b, 0x97, 0x96, 0x85, 0x05, 0xac, 0x77, 0x95, 0x81, 0xa1, + 0x67, 0xa0, 0x67, 0x9b, 0x7f, 0xa4, 0x8b, 0xa6, 0x8b, 0xa2, 0xa4, 0x8b, + 0xa8, 0x8b, 0x9a, 0x81, 0x9c, 0x7b, 0x94, 0x7e, 0x92, 0x80, 0x8e, 0x6e, + 0x8b, 0x5d, 0x8d, 0x80, 0x8d, 0x6a, 0x9e, 0x08, 0x80, 0x91, 0x96, 0x91, + 0x05, 0xac, 0x9e, 0x98, 0x8e, 0xb7, 0x8c, 0xa8, 0x8b, 0x95, 0x8d, 0x99, + 0x94, 0x9c, 0x96, 0x94, 0x99, 0x8b, 0x9a, 0x8b, 0xa8, 0x73, 0xa5, 0x72, + 0x8b, 0x73, 0x8b, 0x79, 0x7e, 0x76, 0x68, 0x73, 0x65, 0x7f, 0x7f, 0x6e, + 0x7a, 0x08, 0x80, 0x85, 0x8b, 0x97, 0x05, 0x8b, 0xac, 0x92, 0xa4, 0x9e, + 0xab, 0x98, 0xa1, 0x8f, 0x97, 0x8b, 0x9a, 0x08, 0xaa, 0x77, 0xa0, 0x6d, + 0x6c, 0x77, 0x76, 0x6c, 0x1e, 0x8b, 0x7c, 0x8f, 0x7f, 0x98, 0x75, 0x9e, + 0x6b, 0x92, 0x72, 0x8b, 0x6a, 0x08, 0x7f, 0x07, 0x0e, 0x42, 0xf7, 0x85, + 0xf7, 0xbd, 0x15, 0xfb, 0x64, 0x33, 0xf7, 0x64, 0xfb, 0x65, 0xe3, 0xf7, + 0x65, 0xf7, 0x64, 0xe3, 0xfb, 0x64, 0xf7, 0x65, 0x33, 0xfb, 0x65, 0x06, + 0x0e, 0xfc, 0x1d, 0x5c, 0xfb, 0x4a, 0x15, 0xf7, 0x07, 0xbe, 0xd7, 0xe1, + 0x8b, 0xdc, 0x08, 0xc6, 0x69, 0xb2, 0x58, 0x62, 0x6d, 0x6c, 0x61, 0x1e, + 0x8b, 0x70, 0x95, 0x7b, 0xa9, 0x77, 0xa2, 0x7c, 0x92, 0x81, 0x8b, 0x7d, + 0x8b, 0x67, 0x63, 0x64, 0x3d, 0x61, 0x08, 0x98, 0x73, 0x05, 0x0e, 0xfb, + 0xca, 0xf7, 0xa3, 0xf7, 0xae, 0x15, 0xfb, 0x89, 0x8b, 0x73, 0xfb, 0x08, + 0xf7, 0x8a, 0x8b, 0xa2, 0xf7, 0x08, 0x05, 0x0e, 0xfc, 0x1d, 0xcd, 0xf7, + 0x1b, 0x15, 0x60, 0x6b, 0x6b, 0x60, 0x62, 0xab, 0x6b, 0xb4, 0xb5, 0xac, + 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, 0x0e, 0xfc, 0x01, 0xf7, 0x93, + 0xf9, 0x41, 0x15, 0xfb, 0xd3, 0xfd, 0x53, 0xe2, 0x8b, 0xf7, 0xd3, 0xf9, + 0x53, 0x34, 0x8b, 0x05, 0x0e, 0xf7, 0xdb, 0xf9, 0x3f, 0x15, 0x54, 0x8b, + 0x54, 0x71, 0x5e, 0x5d, 0x2e, 0x2b, 0x4d, 0xfb, 0x35, 0x8b, 0xfb, 0x28, + 0x8b, 0xfb, 0x19, 0xcb, 0x34, 0xeb, 0x8b, 0xb5, 0x8b, 0xb3, 0x99, 0xb2, + 0xa8, 0xef, 0xd6, 0xda, 0xf7, 0x49, 0x8b, 0xf7, 0x31, 0x8b, 0xf7, 0x26, + 0x50, 0xea, 0x30, 0x8b, 0x08, 0x89, 0x6e, 0x15, 0xaa, 0x9d, 0x70, 0x5e, + 0x1f, 0x8b, 0x78, 0x87, 0x6b, 0x83, 0x66, 0x7a, 0x35, 0x5a, 0xfb, 0x54, + 0x74, 0x48, 0x6a, 0x2b, 0x6e, 0x65, 0x62, 0x8b, 0x6d, 0x8b, 0x77, 0xa5, + 0x8b, 0xb3, 0x8b, 0xcb, 0xc3, 0xf7, 0x7f, 0xba, 0xf7, 0x16, 0xb0, 0xf3, + 0xa7, 0xb3, 0xb0, 0x8b, 0x08, 0x0e, 0x90, 0x16, 0xf7, 0xed, 0xa2, 0x06, + 0x3c, 0x8c, 0x79, 0x93, 0x8b, 0xb0, 0x8b, 0x94, 0x8c, 0x90, 0x96, 0xb3, + 0x08, 0xf7, 0x2e, 0xf8, 0xc4, 0x05, 0x30, 0x75, 0x4c, 0x7e, 0xfb, 0x08, + 0x7a, 0x08, 0x89, 0x74, 0x05, 0xa6, 0x8f, 0x9c, 0x8c, 0x9e, 0x8b, 0xaa, + 0x8b, 0x9a, 0x80, 0x8b, 0x75, 0x8b, 0x85, 0x89, 0x82, 0x89, 0x82, 0x08, + 0xfb, 0x14, 0xfc, 0x5f, 0x05, 0x7a, 0x54, 0x6d, 0x78, 0x43, 0x8b, 0x08, + 0x74, 0x07, 0x0e, 0xf8, 0x37, 0xf7, 0x53, 0x15, 0x72, 0x06, 0x65, 0x49, + 0x74, 0x7d, 0x3d, 0x8b, 0x08, 0xfb, 0x29, 0x8b, 0xf7, 0x58, 0xf7, 0x3b, + 0x05, 0xe9, 0xdb, 0xbd, 0xdd, 0x8b, 0xd6, 0x8b, 0xe9, 0x43, 0xd5, 0x2e, + 0x8b, 0x56, 0x8b, 0x5c, 0x77, 0x5f, 0x63, 0x6e, 0x71, 0x7b, 0x73, 0x6f, + 0x55, 0x08, 0xa1, 0x7f, 0x05, 0xb3, 0xc6, 0xb4, 0xa6, 0xbf, 0x8b, 0xc5, + 0x8b, 0xae, 0x62, 0x8b, 0x46, 0x8b, 0x30, 0x4e, 0x30, 0xfb, 0x50, 0xfb, + 0x4f, 0x08, 0x31, 0x31, 0x8b, 0x73, 0xf8, 0x03, 0x8b, 0xda, 0xf7, 0x53, + 0x05, 0x0e, 0xf7, 0x14, 0xf7, 0xef, 0x15, 0xb5, 0x89, 0x9e, 0x87, 0xa3, + 0x7e, 0xba, 0x73, 0xa4, 0x5b, 0x8b, 0x48, 0x8b, 0x32, 0x5a, 0x42, 0x4e, + 0x8b, 0x7b, 0x8b, 0x7b, 0x91, 0x83, 0x93, 0x89, 0x8d, 0x85, 0x94, 0x7a, + 0xa4, 0x74, 0xae, 0x7b, 0x96, 0x71, 0x8b, 0x08, 0x67, 0x73, 0x75, 0x69, + 0x5a, 0xbe, 0x6c, 0xdd, 0xf7, 0x35, 0xf7, 0x15, 0xf7, 0x09, 0xf7, 0x26, + 0x1f, 0x8b, 0xcd, 0x77, 0xb1, 0x52, 0xb6, 0x08, 0x97, 0x91, 0x05, 0xd2, + 0xae, 0xaf, 0xbc, 0x8b, 0xc7, 0x8b, 0xd9, 0x4b, 0xc5, 0x36, 0x8b, 0x3a, + 0x8b, 0x4e, 0x63, 0x4d, 0x2e, 0x08, 0xa0, 0x7e, 0x05, 0xb4, 0xc4, 0xa7, + 0x9d, 0xba, 0x8b, 0xc0, 0x8b, 0xad, 0x68, 0x8b, 0x54, 0x8b, 0x3e, 0x4f, + 0x5a, 0xfb, 0x15, 0x70, 0x08, 0x87, 0x75, 0x05, 0x0e, 0xf8, 0x59, 0xf7, + 0x8c, 0x15, 0x46, 0x8b, 0xf7, 0x0b, 0xf8, 0x47, 0x4c, 0x8b, 0xfc, 0x3f, + 0xfc, 0x40, 0x6f, 0x22, 0xf7, 0x88, 0x8b, 0x62, 0xfb, 0x2a, 0xf7, 0x14, + 0x8b, 0xb5, 0xf7, 0x2a, 0xcf, 0x8b, 0xa6, 0xed, 0x05, 0xfc, 0x24, 0x16, + 0xf7, 0xae, 0xf7, 0xac, 0x3c, 0xfb, 0xac, 0xfb, 0x5f, 0x8b, 0x05, 0x0e, + 0xf7, 0x59, 0xf8, 0xc4, 0x15, 0xf7, 0x92, 0x8b, 0xaf, 0xf7, 0x01, 0xfb, + 0xaf, 0x8b, 0xfb, 0x17, 0xfb, 0xbd, 0x05, 0xcd, 0x88, 0xab, 0x84, 0xb1, + 0x77, 0xc9, 0x6c, 0xaf, 0x51, 0x8b, 0x4b, 0x8b, 0x36, 0x4b, 0x3e, 0x45, + 0x8b, 0x76, 0x8b, 0x7f, 0x94, 0x76, 0xad, 0x73, 0xb3, 0x7a, 0x98, 0x6d, + 0x8b, 0x08, 0x69, 0x72, 0x73, 0x6a, 0x5c, 0xbf, 0x6b, 0xda, 0xf7, 0x38, + 0xf7, 0x14, 0xf7, 0x07, 0xf7, 0x28, 0x1f, 0x8b, 0xd9, 0x69, 0xcc, 0x4d, + 0xb3, 0x69, 0xa2, 0x70, 0x94, 0x2f, 0x9e, 0x08, 0xad, 0xd7, 0x05, 0x0e, + 0xf8, 0x8b, 0xf9, 0x3b, 0x15, 0xfb, 0x1a, 0x71, 0x4b, 0x72, 0x3a, 0x50, + 0xfb, 0x12, 0x2d, 0x40, 0xfb, 0x1f, 0x8b, 0xfb, 0x21, 0x08, 0xfb, 0x17, + 0xcc, 0x3c, 0xf7, 0x01, 0xf7, 0x1d, 0xf7, 0x01, 0xf7, 0x0a, 0xf7, 0x28, + 0xf5, 0x52, 0xcc, 0x2e, 0x1e, 0x77, 0x8b, 0x7f, 0x88, 0x6d, 0x81, 0xc8, + 0xf7, 0x0d, 0xdd, 0xd5, 0xf7, 0x1b, 0xbe, 0x08, 0x85, 0xa3, 0x05, 0xfb, + 0x90, 0xfb, 0xbd, 0x15, 0xba, 0xa0, 0x76, 0x5d, 0x1f, 0x8b, 0x4d, 0x68, + 0xfb, 0x1a, 0x6a, 0x4c, 0x7e, 0x73, 0x74, 0x7c, 0x72, 0x8b, 0x66, 0x8b, + 0x79, 0xa4, 0x8b, 0xc0, 0x8b, 0xc0, 0xa0, 0xe5, 0xac, 0xdd, 0xa0, 0xc0, + 0x94, 0x94, 0xab, 0x8b, 0x08, 0x0e, 0xde, 0xf8, 0x73, 0x15, 0xb0, 0xcc, + 0xa6, 0x97, 0xf3, 0x8b, 0x08, 0xf7, 0x19, 0x8b, 0xfb, 0xe0, 0xfc, 0xc0, + 0xe7, 0x8b, 0xf8, 0x11, 0xf9, 0x31, 0xfc, 0x11, 0x8b, 0x34, 0xfb, 0x52, + 0xa5, 0x8b, 0x05, 0x0e, 0xf7, 0xe1, 0xf8, 0x11, 0x15, 0xf2, 0xb7, 0xb3, + 0xb7, 0x8b, 0xd2, 0x8b, 0xae, 0x7f, 0xa9, 0x75, 0xa2, 0x69, 0xad, 0x55, + 0xa0, 0x55, 0x8b, 0xfb, 0x02, 0x8b, 0x3a, 0x3d, 0x8b, 0x21, 0x8b, 0x51, + 0x9d, 0x66, 0xc3, 0x50, 0x08, 0x86, 0x07, 0xfb, 0x10, 0x5f, 0x53, 0x51, + 0x8b, 0x36, 0x08, 0x28, 0xda, 0x48, 0xf7, 0x07, 0x1e, 0xf7, 0x14, 0xe9, + 0xe2, 0xf7, 0x0b, 0x1f, 0x8b, 0xcb, 0x72, 0xbf, 0x4e, 0xce, 0x08, 0x90, + 0x07, 0xfb, 0x10, 0x4f, 0x15, 0xe1, 0x25, 0x96, 0x77, 0x8b, 0x57, 0x08, + 0x40, 0x5e, 0x54, 0x4d, 0x4e, 0x65, 0xba, 0xd8, 0x1e, 0x8b, 0xcf, 0xa8, + 0xc0, 0xc8, 0xb8, 0x8e, 0x8e, 0x8b, 0x8b, 0x9b, 0x96, 0x08, 0xf0, 0xdd, + 0x15, 0x46, 0xcc, 0x76, 0xaf, 0x8b, 0xbc, 0x08, 0xc3, 0xad, 0xb4, 0xbb, + 0x1e, 0xbc, 0xab, 0x61, 0x4b, 0x1f, 0x8b, 0x58, 0x7b, 0x6d, 0x52, 0x4f, + 0x08, 0x0e, 0x85, 0x81, 0x15, 0xf7, 0x1b, 0xa4, 0xcb, 0xa4, 0xdb, 0xc6, + 0xf7, 0x11, 0xe7, 0xd8, 0xf7, 0x23, 0x8b, 0xf7, 0x22, 0x8b, 0xcd, 0x76, + 0xc6, 0x66, 0xb1, 0x6e, 0xa8, 0x63, 0x9a, 0x5a, 0x8b, 0x08, 0xfb, 0x1e, + 0xfb, 0x00, 0xfb, 0x0b, 0xfb, 0x2c, 0x27, 0xc8, 0x48, 0xe5, 0x1f, 0xa1, + 0x8b, 0x9a, 0x8e, 0xa3, 0x96, 0x4e, 0xfb, 0x10, 0x2d, 0x38, 0xfb, 0x0e, + 0x66, 0x08, 0x91, 0x72, 0x05, 0xf7, 0xd4, 0xf9, 0x29, 0x15, 0xac, 0x9b, + 0x74, 0x5d, 0x1f, 0x8b, 0x76, 0x87, 0x66, 0x85, 0x6a, 0x83, 0x62, 0x8b, + 0x8b, 0x72, 0x42, 0x70, 0x3c, 0x83, 0x81, 0x61, 0x8b, 0x60, 0x8b, 0x74, + 0xa2, 0x8b, 0xb4, 0x8b, 0xcb, 0xa6, 0xf7, 0x04, 0xaa, 0xc8, 0xa0, 0xb4, + 0xa6, 0xa0, 0xaa, 0x8b, 0x08, 0x0e, 0xfb, 0xca, 0xed, 0xf7, 0x1b, 0x15, + 0x61, 0x6a, 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, + 0x1f, 0xb3, 0x6a, 0xad, 0x63, 0x1e, 0xe8, 0xf7, 0xd8, 0x15, 0x61, 0x6a, + 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, 0x1f, 0xb3, + 0x6a, 0xad, 0x63, 0x1e, 0x0e, 0xfb, 0xca, 0x7f, 0xfb, 0x4b, 0x15, 0xf7, + 0x08, 0xbe, 0xd6, 0xe1, 0x8b, 0xdc, 0x08, 0xc6, 0x69, 0xb2, 0x58, 0x62, + 0x6d, 0x6c, 0x61, 0x1e, 0x8b, 0x70, 0x95, 0x7b, 0xa9, 0x77, 0xa2, 0x7c, + 0x92, 0x81, 0x8b, 0x7d, 0x8b, 0x67, 0x63, 0x64, 0x3d, 0x61, 0x08, 0x98, + 0x73, 0x05, 0xf7, 0x5f, 0xf9, 0x16, 0x15, 0x61, 0x6a, 0x6b, 0x61, 0x61, + 0xab, 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, + 0x0e, 0x42, 0xf8, 0xaf, 0x7f, 0x15, 0x8b, 0xeb, 0xfc, 0x15, 0xf7, 0x3d, + 0xf8, 0x15, 0xf7, 0x3d, 0x8b, 0xeb, 0xfc, 0x90, 0xfb, 0x73, 0x8b, 0x37, + 0xf8, 0x90, 0xfb, 0x73, 0x05, 0x0e, 0x42, 0xf8, 0xad, 0xf8, 0x23, 0x15, + 0xfc, 0x8c, 0x33, 0xf8, 0x8c, 0xe3, 0x06, 0xfb, 0x60, 0x04, 0xfc, 0x8c, + 0x33, 0xf8, 0x8c, 0xe3, 0x06, 0x0e, 0x42, 0xaa, 0x7f, 0x15, 0xf8, 0x90, + 0xf7, 0x73, 0x8b, 0xdf, 0xfc, 0x90, 0xf7, 0x73, 0x8b, 0x2b, 0xf8, 0x15, + 0xfb, 0x3d, 0xfc, 0x15, 0xfb, 0x3d, 0x8b, 0x2b, 0x05, 0x0e, 0xf7, 0x58, + 0xf7, 0x64, 0x15, 0xa7, 0xd1, 0x9b, 0xa2, 0xb1, 0xa4, 0x08, 0xcd, 0xb6, + 0x05, 0xe4, 0xc5, 0xb0, 0xbd, 0x8b, 0xc9, 0x08, 0xe2, 0x44, 0xc5, 0x22, + 0x26, 0x41, 0x55, 0x40, 0x65, 0xa6, 0x6e, 0xad, 0xad, 0xa6, 0xa6, 0xab, + 0x1e, 0x8b, 0x9a, 0x86, 0x99, 0x7e, 0x9c, 0x83, 0x95, 0x88, 0x91, 0x8b, + 0x91, 0x08, 0x9e, 0xa9, 0x9e, 0xab, 0xb5, 0xa6, 0x6c, 0x5a, 0x1e, 0x8b, + 0x5c, 0x77, 0x5d, 0x5f, 0x54, 0x08, 0x62, 0x58, 0x05, 0x5d, 0x51, 0x76, + 0x5d, 0x87, 0x54, 0x08, 0xa8, 0x84, 0x05, 0x61, 0x42, 0x15, 0x61, 0x6a, + 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, 0xb3, 0x6a, + 0xad, 0x63, 0x1f, 0x0e, 0xf7, 0x51, 0xf8, 0xb5, 0xf8, 0x63, 0x15, 0x75, + 0xb5, 0x7d, 0x95, 0x67, 0x8b, 0x60, 0x8b, 0x5f, 0x78, 0x6c, 0x6a, 0x58, + 0x55, 0x6b, 0x3c, 0x8b, 0x42, 0x8b, 0x4b, 0xb4, 0x59, 0xbf, 0x8b, 0xb6, + 0x8b, 0xba, 0xa7, 0xae, 0xb9, 0x08, 0x8d, 0x62, 0xb5, 0x69, 0xbc, 0x8b, + 0x08, 0xef, 0xe2, 0xf7, 0x05, 0xf7, 0x18, 0xf7, 0x3c, 0xfb, 0x26, 0xf7, + 0x16, 0xfb, 0x50, 0xfb, 0x64, 0xfb, 0x39, 0xfb, 0x32, 0xfb, 0x5b, 0xfb, + 0x56, 0xf7, 0x39, 0xfb, 0x2c, 0xf7, 0x67, 0x1f, 0xd3, 0x8b, 0xbf, 0x99, + 0xec, 0xb8, 0x08, 0x7e, 0xae, 0x05, 0x3d, 0x67, 0x58, 0x7f, 0x46, 0x8b, + 0x08, 0xfb, 0x40, 0xfb, 0x0f, 0xf7, 0x0f, 0xf7, 0x3f, 0xf7, 0x51, 0xf7, + 0x0a, 0xf7, 0x1b, 0xf7, 0x39, 0xf7, 0x31, 0xf7, 0x16, 0xfb, 0x0d, 0xfb, + 0x26, 0x1f, 0x8b, 0x59, 0x79, 0x51, 0x6e, 0x62, 0x74, 0x69, 0x70, 0x7a, + 0x6d, 0x8b, 0x74, 0x8b, 0x7d, 0x9b, 0x8b, 0xa8, 0x8b, 0x94, 0x8b, 0x90, + 0x8d, 0x91, 0x08, 0xcc, 0xf7, 0x95, 0x44, 0x8b, 0x05, 0x80, 0x65, 0x05, + 0x50, 0x8f, 0x15, 0xa8, 0x89, 0x9a, 0x73, 0x89, 0x64, 0x89, 0x5f, 0x7a, + 0x4f, 0x76, 0x62, 0x75, 0x61, 0x6d, 0x72, 0x6e, 0x8b, 0x67, 0x8b, 0x74, + 0xac, 0x8b, 0xbf, 0x8b, 0xc1, 0x9d, 0xbd, 0xac, 0xb1, 0x08, 0xa7, 0xab, + 0xad, 0x9f, 0xa4, 0x89, 0x08, 0x0e, 0xa3, 0xf8, 0xe5, 0xa4, 0x15, 0x49, + 0x90, 0x86, 0x90, 0x7e, 0xd7, 0x08, 0x2b, 0xf8, 0xd0, 0x72, 0x8b, 0xfc, + 0x08, 0xfc, 0xe0, 0x05, 0x6b, 0x5a, 0x7c, 0x7e, 0x67, 0x83, 0x08, 0x72, + 0xf7, 0x58, 0xa4, 0x07, 0x5d, 0x78, 0x96, 0xa3, 0x1f, 0x8b, 0x98, 0x90, + 0x9b, 0x95, 0x9c, 0x08, 0xc6, 0xf1, 0xf7, 0x6b, 0x8b, 0x05, 0x8e, 0x73, + 0x8e, 0x76, 0x8c, 0x84, 0x91, 0x64, 0x8d, 0x77, 0x8b, 0x7e, 0x8b, 0x61, + 0x7c, 0x80, 0x4b, 0x85, 0x08, 0x72, 0xf7, 0xc4, 0xa4, 0x07, 0xfc, 0x44, + 0xf7, 0x73, 0x15, 0xf7, 0x28, 0xf7, 0x87, 0xb0, 0xfb, 0x87, 0xfb, 0x4d, + 0x8b, 0x05, 0x0e, 0xa3, 0xf7, 0x08, 0xf9, 0x18, 0x15, 0xaf, 0x89, 0x94, + 0x89, 0x97, 0x84, 0x94, 0x86, 0x92, 0x7e, 0x8b, 0x7f, 0x8b, 0x81, 0x87, + 0x75, 0x84, 0x72, 0x08, 0xfb, 0x0e, 0xfc, 0x55, 0x05, 0x7b, 0x58, 0x7b, + 0x7c, 0x5b, 0x85, 0x08, 0x72, 0xf7, 0xc1, 0x07, 0xf7, 0x4b, 0xf7, 0x04, + 0xd9, 0xf7, 0x14, 0x1f, 0x8b, 0xd9, 0x67, 0xb1, 0x26, 0xac, 0xd7, 0x9e, + 0xaa, 0x99, 0xae, 0xa8, 0x08, 0xa8, 0xa4, 0x9d, 0xb3, 0x8b, 0xb4, 0x08, + 0xeb, 0x3a, 0xbd, 0xfb, 0x2f, 0x1e, 0xfb, 0xa4, 0x06, 0x72, 0x07, 0xf7, + 0x2d, 0xfb, 0xc6, 0x15, 0xcd, 0x89, 0xa9, 0x85, 0x9f, 0x7a, 0xa1, 0x79, + 0x97, 0x6e, 0x8b, 0x66, 0x8b, 0x51, 0x73, 0x4c, 0x68, 0x67, 0x70, 0x70, + 0x69, 0x7e, 0x5f, 0x8b, 0x65, 0x8b, 0x78, 0x96, 0x8b, 0xa1, 0x8b, 0x92, + 0x8d, 0x94, 0x8e, 0x98, 0x08, 0xcd, 0xf7, 0x88, 0x05, 0xd0, 0xf7, 0x93, + 0x15, 0x95, 0xaf, 0x95, 0x93, 0xab, 0x8b, 0xc5, 0x8b, 0xa8, 0x69, 0x8b, + 0x48, 0x8b, 0x4b, 0x76, 0x5b, 0x63, 0x71, 0x6c, 0x77, 0x69, 0x84, 0x41, + 0x88, 0x08, 0xc8, 0xf7, 0x75, 0x05, 0x0e, 0xa3, 0xf9, 0x39, 0xf9, 0x41, + 0x15, 0x6d, 0x06, 0x7d, 0x75, 0x82, 0x84, 0x7c, 0x8b, 0x83, 0x8b, 0x7c, + 0x8e, 0x7c, 0x90, 0x60, 0x98, 0x5c, 0x93, 0x62, 0x8b, 0x08, 0xfb, 0x73, + 0xfb, 0x4d, 0xfb, 0x5e, 0xfb, 0x86, 0xfb, 0x2f, 0xf7, 0x01, 0x23, 0xf7, + 0x37, 0x1f, 0xd2, 0x8b, 0xcd, 0xa1, 0xc4, 0xb6, 0xa9, 0xa1, 0x9b, 0x9d, + 0xab, 0xb7, 0x08, 0x6d, 0xa1, 0x05, 0x59, 0x50, 0x6f, 0x74, 0x61, 0x79, + 0x6f, 0x7f, 0x6c, 0x85, 0x6c, 0x8b, 0x2d, 0x8b, 0x53, 0xcc, 0x8b, 0xf7, + 0x01, 0x8b, 0xf7, 0x26, 0xd3, 0xf7, 0x41, 0xe6, 0xd7, 0xb0, 0xa9, 0xb2, + 0x9b, 0xb4, 0x8b, 0xdc, 0x8b, 0xbd, 0x4f, 0x8b, 0x29, 0x08, 0x8b, 0x7e, + 0x8a, 0x82, 0x89, 0x7e, 0x08, 0xab, 0x85, 0xbe, 0xf7, 0x7e, 0x05, 0x0e, + 0xda, 0xe9, 0xf9, 0x18, 0x15, 0x99, 0x89, 0x98, 0x89, 0x8f, 0x8a, 0xab, + 0x86, 0x95, 0x83, 0x8b, 0x73, 0x8b, 0x81, 0x87, 0x7a, 0x83, 0x6b, 0x08, + 0xfb, 0x0d, 0xfc, 0x52, 0x05, 0x7c, 0x58, 0x7b, 0x7c, 0x5a, 0x85, 0x08, + 0x72, 0xf7, 0xb2, 0x07, 0xf7, 0x93, 0xf7, 0x52, 0xf7, 0x3d, 0xf7, 0x77, + 0xf7, 0x3f, 0xfb, 0x04, 0xf1, 0xfb, 0x51, 0x1f, 0xfb, 0xb6, 0x72, 0x06, + 0xf7, 0x74, 0x5f, 0x15, 0x92, 0xa6, 0x9b, 0x96, 0xab, 0x8b, 0xf7, 0x03, + 0x8b, 0xc1, 0x50, 0x8b, 0xfb, 0x0e, 0x8b, 0xfb, 0x06, 0x69, 0xfb, 0x0b, + 0x55, 0x3e, 0x56, 0x3f, 0x44, 0x66, 0x2c, 0x8b, 0x66, 0x8b, 0x7a, 0x96, + 0x8b, 0xa2, 0x8b, 0x97, 0x8e, 0x9b, 0x94, 0xa5, 0x08, 0x8d, 0x8c, 0x8d, + 0x8b, 0x1e, 0xf7, 0x14, 0xf8, 0x6e, 0x05, 0x0e, 0xa3, 0xf8, 0xde, 0xf7, + 0x56, 0x15, 0x72, 0x90, 0x05, 0x68, 0x52, 0x76, 0x72, 0x64, 0x70, 0x53, + 0x64, 0x47, 0x78, 0x35, 0x8b, 0x60, 0x8b, 0x79, 0x95, 0x8b, 0xa3, 0x8b, + 0x92, 0x8e, 0x96, 0x90, 0x9f, 0x8d, 0x90, 0x8d, 0x91, 0x8c, 0x93, 0x08, + 0x8d, 0x91, 0xc3, 0xf7, 0x65, 0x05, 0xf7, 0x06, 0x89, 0xa9, 0x78, 0x8b, + 0x46, 0x8b, 0x7d, 0x8a, 0x80, 0x88, 0x78, 0x08, 0xa7, 0x86, 0xd5, 0xf7, + 0xa5, 0x6f, 0x8f, 0x05, 0x5c, 0x2d, 0x71, 0x7e, 0xfb, 0x18, 0x8c, 0x08, + 0xc8, 0xf7, 0x73, 0x05, 0x95, 0xae, 0x97, 0x94, 0xb4, 0x8b, 0xd4, 0x8b, + 0xc1, 0x7c, 0xa6, 0x70, 0xa2, 0x73, 0x92, 0x72, 0x8b, 0x4d, 0x08, 0xa6, + 0x86, 0xb6, 0xf7, 0x52, 0xfc, 0xb0, 0x8b, 0x8b, 0x72, 0x05, 0x99, 0x89, + 0x97, 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x96, 0x83, 0x8b, 0x76, 0x8b, 0x7c, + 0x87, 0x74, 0x85, 0x75, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x56, + 0x7f, 0x80, 0x57, 0x83, 0x08, 0x72, 0xf8, 0xbe, 0x07, 0xc6, 0xf7, 0x56, + 0x05, 0x0e, 0xa3, 0xf8, 0x97, 0xf8, 0x6c, 0x15, 0x6f, 0x8f, 0x05, 0x5c, + 0x2d, 0x77, 0x80, 0xfb, 0x17, 0x8a, 0x08, 0xc8, 0xf7, 0x73, 0x05, 0x95, + 0xae, 0x98, 0x94, 0xb3, 0x8b, 0xd4, 0x8b, 0xbe, 0x7b, 0xa6, 0x6c, 0x9f, + 0x74, 0x91, 0x70, 0x8b, 0x53, 0x08, 0xa6, 0x86, 0xb6, 0xf7, 0x52, 0xfc, + 0xa9, 0x8b, 0x8b, 0x72, 0x05, 0x99, 0x89, 0x97, 0x89, 0x90, 0x8a, 0xaa, + 0x88, 0x96, 0x82, 0x8b, 0x76, 0x8b, 0x7d, 0x87, 0x73, 0x85, 0x75, 0x08, + 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x56, 0x7f, 0x80, 0x57, 0x83, 0x08, + 0x72, 0xf7, 0xbb, 0xa4, 0x07, 0x53, 0x8f, 0x7c, 0x94, 0x8b, 0xaa, 0x8b, + 0x97, 0x8e, 0x9b, 0x93, 0xa4, 0x8d, 0x92, 0x8c, 0x91, 0x8c, 0x8d, 0x08, + 0xc1, 0xf7, 0x5d, 0x05, 0xf6, 0x89, 0xa9, 0x77, 0x8b, 0x47, 0x8b, 0x7d, + 0x8a, 0x80, 0x88, 0x78, 0x08, 0xa7, 0x86, 0xd5, 0xf7, 0xa5, 0x05, 0x0e, + 0xda, 0xf9, 0x56, 0xf7, 0xde, 0x15, 0xfb, 0xb3, 0x71, 0x06, 0xb6, 0x87, + 0x93, 0x89, 0x96, 0x85, 0x91, 0x87, 0x91, 0x80, 0x8b, 0x82, 0x8b, 0x71, + 0x87, 0x7a, 0x70, 0x2f, 0x74, 0x3d, 0x8b, 0x8b, 0x87, 0x86, 0x7d, 0x7a, + 0x62, 0x7e, 0x64, 0x8b, 0x21, 0x8b, 0x51, 0xcd, 0x8b, 0xf7, 0x0e, 0x08, + 0x8b, 0xf7, 0x29, 0xcf, 0xf7, 0x3b, 0xe6, 0xd8, 0xb1, 0xab, 0xb6, 0x9b, + 0xb8, 0x8b, 0xba, 0x8b, 0xb2, 0x78, 0xa1, 0x6b, 0xa1, 0x6a, 0x92, 0x6e, + 0x8d, 0x47, 0x08, 0xa8, 0x87, 0xbe, 0xf7, 0x71, 0x6c, 0x8b, 0x05, 0x80, + 0x75, 0x80, 0x83, 0x77, 0x8b, 0x82, 0x8b, 0x83, 0x8d, 0x78, 0x92, 0x5e, + 0x9a, 0x6a, 0x91, 0x5d, 0x8b, 0x3f, 0x8b, 0x44, 0x79, 0x4e, 0x68, 0xfb, + 0x18, 0x3e, 0x34, 0xfb, 0x2b, 0x8b, 0xfb, 0x2d, 0x8b, 0xfb, 0x33, 0xf7, + 0x0d, 0xfb, 0x02, 0xf7, 0x43, 0x8b, 0x08, 0xd8, 0x8b, 0xef, 0x9f, 0xc4, + 0xa5, 0x08, 0xa7, 0x98, 0xbb, 0xf7, 0x49, 0x05, 0x9e, 0xd1, 0x92, 0x93, + 0xc0, 0x8f, 0x08, 0xa5, 0x07, 0x0e, 0xf7, 0x1b, 0xf9, 0x25, 0xa4, 0x15, + 0x54, 0x8d, 0x79, 0x95, 0x8b, 0xa8, 0x8b, 0x99, 0x90, 0xa2, 0x99, 0xbd, + 0x08, 0x91, 0xa1, 0xf7, 0x01, 0xf8, 0x21, 0x05, 0x9b, 0xc0, 0x99, 0x97, + 0xbe, 0x92, 0x08, 0xa4, 0xfb, 0xbe, 0x72, 0x07, 0x99, 0x89, 0x98, 0x89, + 0x90, 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, 0x77, 0x8b, 0x7f, 0x86, 0x6c, + 0x86, 0x79, 0x08, 0x5c, 0xfb, 0x41, 0xfb, 0x83, 0x8b, 0xc1, 0xf7, 0x5b, + 0x05, 0x9b, 0xc2, 0x9f, 0x9a, 0xcc, 0x8d, 0x08, 0xa4, 0xfb, 0xd1, 0x72, + 0x07, 0x99, 0x89, 0x97, 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x96, 0x82, 0x8b, + 0x75, 0x8b, 0x80, 0x87, 0x76, 0x84, 0x71, 0x08, 0xfb, 0x0e, 0xfc, 0x55, + 0x05, 0x7b, 0x57, 0x7d, 0x7e, 0x59, 0x84, 0x08, 0x72, 0xf7, 0xbc, 0xa4, + 0x07, 0x4c, 0x90, 0x81, 0x91, 0x8b, 0xab, 0x8b, 0x99, 0x8f, 0x9d, 0x94, + 0xab, 0x8c, 0x91, 0x8d, 0x90, 0x8c, 0x90, 0x08, 0xbd, 0xf7, 0x49, 0xf7, + 0x83, 0x8b, 0x4b, 0xfb, 0x7c, 0x05, 0x7d, 0x55, 0x77, 0x7d, 0x48, 0x87, + 0x08, 0x72, 0xf7, 0xd1, 0xa4, 0x07, 0x0e, 0xfb, 0x92, 0xf7, 0x9c, 0xa4, + 0x15, 0x52, 0x8e, 0x7c, 0x94, 0x8b, 0xa7, 0x8b, 0x9a, 0x90, 0xa2, 0x98, + 0xbc, 0x08, 0xf7, 0x06, 0xf8, 0x38, 0x05, 0x9b, 0xc0, 0x9a, 0x98, 0xbe, + 0x91, 0x08, 0xa4, 0xfb, 0xbe, 0x72, 0x07, 0x99, 0x89, 0x98, 0x89, 0x90, + 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, 0x77, 0x8b, 0x7f, 0x86, 0x6c, 0x86, + 0x79, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x57, 0x7c, 0x7d, 0x5a, + 0x85, 0x08, 0x72, 0xf7, 0xbc, 0xa4, 0x07, 0x0e, 0xf8, 0xa0, 0xf9, 0x31, + 0x15, 0xfb, 0xbd, 0x72, 0x06, 0x99, 0x89, 0x97, 0x89, 0x90, 0x8a, 0xa8, + 0x87, 0x98, 0x81, 0x8b, 0x79, 0x8b, 0x7f, 0x87, 0x74, 0x84, 0x71, 0x08, + 0xfb, 0x06, 0xfc, 0x44, 0x05, 0x64, 0xfb, 0x29, 0x7c, 0x6f, 0x67, 0x8b, + 0x79, 0x8b, 0x82, 0x91, 0x8b, 0x97, 0x8b, 0x92, 0x8d, 0x90, 0x93, 0x94, + 0x95, 0x98, 0x8e, 0x91, 0x8b, 0x99, 0x08, 0xae, 0x6f, 0xa7, 0x68, 0x67, + 0x6f, 0x6c, 0x64, 0x51, 0xcb, 0x60, 0xe3, 0x1e, 0xf7, 0x00, 0x8b, 0xcd, + 0xc8, 0xae, 0xf7, 0x17, 0x08, 0xf7, 0x14, 0xf8, 0x73, 0x05, 0x9c, 0xc0, + 0x9a, 0x98, 0xbc, 0x91, 0x08, 0xa4, 0x07, 0x0e, 0xa3, 0xf8, 0x1c, 0xf8, + 0x22, 0x15, 0xf7, 0x6c, 0xf7, 0x5a, 0x05, 0xb6, 0xb2, 0x93, 0x8e, 0xb6, + 0x91, 0x08, 0xa4, 0xfb, 0x67, 0x72, 0x07, 0x94, 0x8a, 0x94, 0x8a, 0x8e, + 0x8b, 0xa4, 0x88, 0x95, 0x84, 0x8b, 0x7c, 0x8b, 0x6e, 0x47, 0x47, 0xfb, + 0x62, 0xfb, 0x44, 0x08, 0xc9, 0xf7, 0x78, 0x05, 0x9b, 0xbf, 0x9e, 0x9a, + 0xc6, 0x90, 0x08, 0xa4, 0xfb, 0xca, 0x72, 0x07, 0x99, 0x89, 0x97, 0x89, + 0x90, 0x8a, 0xaa, 0x87, 0x96, 0x82, 0x8b, 0x75, 0x8b, 0x80, 0x87, 0x76, + 0x84, 0x71, 0x08, 0xfb, 0x0e, 0xfc, 0x55, 0x05, 0x7b, 0x56, 0x7c, 0x7e, + 0x5a, 0x85, 0x08, 0x72, 0xf7, 0xb5, 0xa4, 0x07, 0x57, 0x8f, 0x7d, 0x94, + 0x8b, 0xac, 0x8b, 0x91, 0x8c, 0x91, 0x8c, 0x90, 0x08, 0xce, 0xf7, 0x8d, + 0xf7, 0x05, 0xfb, 0x86, 0x05, 0x94, 0x77, 0x8f, 0x7f, 0x8b, 0x80, 0x8b, + 0x7d, 0x7f, 0x83, 0x71, 0x89, 0x87, 0x8a, 0x80, 0x8a, 0x7f, 0x8a, 0x08, + 0x72, 0xf7, 0xac, 0xa4, 0x07, 0x65, 0x8f, 0x7d, 0x92, 0x80, 0xa3, 0x08, + 0xfb, 0x31, 0xf7, 0xe6, 0x05, 0x0e, 0x6b, 0xf8, 0xe2, 0xf7, 0x56, 0x15, + 0x73, 0x90, 0x05, 0x69, 0x53, 0x75, 0x72, 0x64, 0x6f, 0x55, 0x65, 0x44, + 0x77, 0x39, 0x8b, 0x5f, 0x8b, 0x77, 0x94, 0x8b, 0xa0, 0x8b, 0x93, 0x8d, + 0x98, 0x8e, 0x96, 0x08, 0xf7, 0x15, 0xf8, 0x72, 0x05, 0x9b, 0xc2, 0x9e, + 0x98, 0xcd, 0x8f, 0x08, 0xa4, 0xfb, 0xd1, 0x72, 0x07, 0x99, 0x89, 0x98, + 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, 0x77, 0x8b, 0x7f, 0x86, + 0x6c, 0x86, 0x79, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x57, 0x7c, + 0x7e, 0x5a, 0x84, 0x08, 0x72, 0xf8, 0xbd, 0x07, 0xc6, 0xf7, 0x56, 0x05, + 0x0e, 0xf7, 0x8a, 0xfa, 0x29, 0xf9, 0x31, 0x15, 0xfb, 0x68, 0x8b, 0xfb, + 0xca, 0xfc, 0x74, 0x55, 0xf8, 0x74, 0xfb, 0x71, 0x8b, 0x8b, 0x72, 0x05, + 0xca, 0x88, 0x94, 0x87, 0x8b, 0x6f, 0x8b, 0x7e, 0x87, 0x77, 0x84, 0x72, + 0x08, 0xfb, 0x01, 0xfc, 0x09, 0x05, 0x63, 0xfb, 0x16, 0x84, 0x80, 0x55, + 0x7f, 0x08, 0x72, 0xf7, 0x63, 0xa4, 0x07, 0x4b, 0x93, 0x7b, 0x97, 0x8b, + 0xb4, 0x8b, 0x9b, 0x91, 0xa7, 0x98, 0xbb, 0x08, 0xf0, 0xf8, 0x05, 0x05, + 0xce, 0xfc, 0xc3, 0xa7, 0x8b, 0xf8, 0x0b, 0xf8, 0xd1, 0xfb, 0x11, 0xfc, + 0x64, 0x05, 0x7b, 0x55, 0x78, 0x7d, 0x4a, 0x87, 0x08, 0x72, 0xf7, 0xcc, + 0xa4, 0x07, 0x51, 0x8e, 0x7d, 0x93, 0x8b, 0xab, 0x8b, 0x95, 0x8d, 0x99, + 0x91, 0xa0, 0x08, 0x8c, 0x90, 0x8c, 0x90, 0xf7, 0x0f, 0xf8, 0x55, 0x05, + 0x9a, 0xbf, 0x9a, 0x99, 0xbe, 0x91, 0x08, 0xa4, 0x07, 0x0e, 0xda, 0xf7, + 0xc6, 0xf9, 0x31, 0x15, 0xfb, 0x57, 0x72, 0x06, 0xc2, 0x86, 0x94, 0x85, + 0x9e, 0x5f, 0x08, 0xfb, 0x0c, 0xfc, 0x2f, 0x05, 0x64, 0xfb, 0x17, 0x84, + 0x80, 0x54, 0x80, 0x08, 0x72, 0xf7, 0x64, 0xa4, 0x07, 0x50, 0x90, 0x76, + 0x9a, 0x8b, 0xb2, 0x8b, 0x9d, 0x92, 0xae, 0x96, 0xb4, 0x08, 0xee, 0xf7, + 0xf8, 0x05, 0xf7, 0x95, 0xfc, 0xb9, 0xa7, 0x8b, 0xf7, 0x23, 0xf8, 0x8e, + 0x05, 0xb2, 0xf7, 0x18, 0x90, 0x93, 0xc5, 0x98, 0x08, 0xa4, 0xfb, 0x65, + 0x72, 0x07, 0xc6, 0x86, 0xa0, 0x7b, 0x8b, 0x65, 0x8b, 0x79, 0x84, 0x67, + 0x80, 0x63, 0x08, 0x3b, 0xfb, 0xb3, 0x05, 0xfb, 0x6b, 0xf8, 0x65, 0x05, + 0x0e, 0xda, 0xf8, 0x55, 0xf9, 0x41, 0x15, 0x42, 0x8b, 0x41, 0x71, 0x47, + 0x59, 0xfb, 0x0d, 0x33, 0x35, 0xfb, 0x35, 0x8b, 0xfb, 0x1f, 0x8b, 0xfb, + 0x23, 0xea, 0x2b, 0xf7, 0x21, 0x8b, 0xda, 0x8b, 0xd7, 0xa5, 0xce, 0xbd, + 0xf7, 0x10, 0xe6, 0xdd, 0xf7, 0x33, 0x8b, 0xf7, 0x26, 0x8b, 0xf7, 0x19, + 0x24, 0xed, 0xfb, 0x1f, 0x8b, 0x08, 0x87, 0x69, 0x15, 0xc8, 0xb4, 0x5b, + 0x43, 0x1f, 0x8b, 0xfb, 0x0c, 0x4d, 0xfb, 0x5c, 0x48, 0x29, 0x5d, 0x48, + 0x5e, 0x6d, 0x55, 0x8b, 0x4c, 0x8b, 0x64, 0xba, 0x8b, 0xd5, 0x8b, 0xf1, + 0xbe, 0xf7, 0x4d, 0xc2, 0xeb, 0xbe, 0xe5, 0xc0, 0xb4, 0xcb, 0x8b, 0x08, + 0x0e, 0x6b, 0xf7, 0x05, 0xf9, 0x18, 0x15, 0x99, 0x89, 0x97, 0x89, 0x90, + 0x8a, 0xaa, 0x88, 0x96, 0x82, 0x8b, 0x76, 0x8b, 0x7d, 0x87, 0x73, 0x85, + 0x75, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x56, 0x7f, 0x80, 0x57, + 0x83, 0x08, 0x72, 0xf7, 0xba, 0xa4, 0x07, 0x53, 0x8e, 0x7b, 0x94, 0x8b, + 0xa6, 0x8b, 0x95, 0x91, 0xac, 0x8f, 0x9b, 0x08, 0xc1, 0xf7, 0x5b, 0x05, + 0xaf, 0x87, 0x9e, 0x8a, 0xa5, 0x8b, 0x08, 0xf7, 0x3a, 0xf6, 0xd8, 0xf7, + 0x0c, 0xf0, 0x41, 0xc1, 0xfb, 0x1f, 0x1f, 0xfb, 0xb3, 0x72, 0x06, 0xf7, + 0x70, 0x58, 0x15, 0x92, 0xa3, 0x8b, 0x8b, 0x8f, 0x90, 0x94, 0x96, 0x96, + 0x8f, 0x9e, 0x8b, 0xc0, 0x8b, 0xaa, 0x6a, 0x8b, 0x51, 0x8b, 0x68, 0x82, + 0x5d, 0x7d, 0x6c, 0x71, 0x50, 0x66, 0x74, 0x45, 0x8b, 0x7d, 0x8b, 0x80, + 0x8c, 0x7a, 0x8c, 0x08, 0xcb, 0xf7, 0x83, 0x05, 0x0e, 0xda, 0xf9, 0x0e, + 0x63, 0x15, 0x51, 0x50, 0x66, 0x78, 0x4f, 0x8b, 0x71, 0x8b, 0x76, 0x8f, + 0x67, 0x96, 0x08, 0x61, 0x98, 0x05, 0x73, 0x93, 0x5f, 0x92, 0x61, 0x8e, + 0x6f, 0x8d, 0x81, 0x8d, 0x8b, 0x8f, 0x8b, 0x8d, 0xa4, 0xa4, 0xa0, 0x9f, + 0xf7, 0x16, 0x93, 0xc2, 0x9f, 0xd8, 0xd0, 0xf7, 0x02, 0xee, 0xce, 0xf7, + 0x20, 0x8b, 0xf7, 0x19, 0x08, 0xf7, 0x1b, 0x25, 0xed, 0xfb, 0x20, 0xfb, + 0x6c, 0xfb, 0x62, 0xfb, 0x7b, 0xfb, 0x87, 0x1e, 0x8b, 0x4a, 0xa4, 0x4f, + 0xb8, 0x61, 0xa5, 0x72, 0x98, 0x84, 0xc0, 0x78, 0x93, 0x88, 0x8e, 0x89, + 0x8e, 0x87, 0x89, 0x88, 0x8a, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x86, 0x87, + 0x83, 0x84, 0x08, 0xfb, 0x30, 0xfb, 0x16, 0x99, 0x73, 0x05, 0xc2, 0xa0, + 0xa6, 0x92, 0xab, 0x8b, 0xa8, 0x8b, 0xa2, 0x86, 0xbf, 0x7b, 0xc9, 0x77, + 0xac, 0x85, 0xb4, 0x8b, 0xf7, 0x01, 0x8b, 0xd0, 0xb3, 0xdc, 0xf7, 0x01, + 0x08, 0x76, 0x9e, 0x05, 0xfb, 0x51, 0xf9, 0x47, 0x15, 0xc8, 0xb4, 0x5b, + 0x43, 0x1f, 0x8b, 0xfb, 0x0c, 0x4d, 0xfb, 0x5b, 0x48, 0x29, 0x5d, 0x48, + 0x5e, 0x6d, 0x55, 0x8b, 0x4c, 0x8b, 0x64, 0xb9, 0x8b, 0xd4, 0x8b, 0xf2, + 0xbe, 0xf7, 0x4c, 0xc2, 0xec, 0xbe, 0xe5, 0xc0, 0xb4, 0xcb, 0x8b, 0x08, + 0x0e, 0xa3, 0xf7, 0x03, 0xf9, 0x18, 0x15, 0x99, 0x89, 0x98, 0x89, 0x90, + 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, 0x77, 0x8b, 0x7f, 0x86, 0x6b, 0x86, + 0x7a, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x57, 0x7c, 0x7d, 0x5a, + 0x85, 0x08, 0x72, 0xf7, 0xbc, 0xa4, 0x07, 0x51, 0x8f, 0x7d, 0x93, 0x8b, + 0xa9, 0x8b, 0x99, 0x90, 0xa5, 0x94, 0xaa, 0x08, 0xc2, 0xf7, 0x55, 0xa8, + 0x8b, 0xf6, 0xfb, 0xdf, 0xf7, 0x5e, 0x8b, 0x8b, 0xa4, 0x05, 0x53, 0x90, + 0x81, 0x93, 0x75, 0xc6, 0x08, 0x38, 0xf7, 0x8a, 0x05, 0xc2, 0x96, 0xa4, + 0x95, 0xab, 0xa0, 0xbe, 0xad, 0xa8, 0xbe, 0x8b, 0xc3, 0x08, 0xeb, 0x3d, + 0xba, 0xfb, 0x32, 0x1e, 0xfb, 0xa8, 0x72, 0x06, 0xf7, 0x72, 0x58, 0x15, + 0x94, 0xaf, 0x94, 0x93, 0xaa, 0x8b, 0xc4, 0x8b, 0xac, 0x68, 0x8b, 0x4f, + 0x8b, 0x49, 0x6e, 0x4e, 0x60, 0x70, 0x71, 0x7a, 0x64, 0x84, 0x4d, 0x8a, + 0x08, 0xc7, 0xf7, 0x7a, 0x05, 0x0e, 0x34, 0x8d, 0x79, 0x15, 0xa9, 0x06, + 0x97, 0xa8, 0x92, 0x91, 0x9e, 0x8b, 0x95, 0x8b, 0x98, 0x88, 0xa2, 0x83, + 0xbc, 0x7a, 0xad, 0x84, 0xb3, 0x8b, 0xf7, 0x20, 0x8b, 0xe4, 0xda, 0x8b, + 0xf7, 0x10, 0x8b, 0xe1, 0x5d, 0xce, 0xfb, 0x0e, 0xe8, 0x4d, 0xba, 0x7c, + 0xa1, 0x8b, 0xb8, 0x08, 0xcb, 0xb3, 0xb4, 0xcb, 0x1e, 0xdb, 0x8b, 0xb2, + 0x5a, 0x98, 0xfb, 0x09, 0x08, 0xa6, 0x87, 0xb3, 0xf7, 0x5d, 0x6d, 0x8b, + 0x05, 0x82, 0x79, 0x7d, 0x83, 0x76, 0x8b, 0x82, 0x8b, 0x7a, 0x8f, 0x72, + 0x92, 0x60, 0x99, 0x70, 0x90, 0x6f, 0x8b, 0xfb, 0x06, 0x8b, 0x34, 0x37, + 0x8b, 0xfb, 0x02, 0x8b, 0x70, 0x90, 0x75, 0x93, 0x7a, 0xa1, 0x61, 0xb4, + 0x5f, 0xc3, 0x5f, 0x08, 0xd9, 0x4f, 0xae, 0x5c, 0x8b, 0x5d, 0x8b, 0x75, + 0x84, 0x73, 0x7f, 0x75, 0x74, 0x64, 0x68, 0x78, 0x5a, 0x8b, 0x57, 0x8b, + 0x5d, 0xa4, 0x72, 0xb5, 0x78, 0xaa, 0x83, 0xa9, 0x87, 0xc7, 0x08, 0x6e, + 0x8d, 0x67, 0xfb, 0x74, 0x05, 0x0e, 0x6b, 0xf9, 0x1e, 0xf9, 0x31, 0x15, + 0xfc, 0xbb, 0x8b, 0x65, 0xfb, 0x3f, 0xa4, 0x84, 0x05, 0xbf, 0xef, 0xca, + 0xb4, 0xf1, 0x8d, 0x08, 0xfb, 0x28, 0xfc, 0xad, 0x05, 0x7d, 0x58, 0x71, + 0x76, 0x58, 0x8b, 0x08, 0x7d, 0x72, 0xf7, 0xdf, 0xa4, 0x06, 0x45, 0x8e, + 0x7e, 0x91, 0x8b, 0xab, 0x8b, 0x9a, 0x8f, 0xa0, 0x92, 0xa5, 0x08, 0xf7, + 0x20, 0xf8, 0x8e, 0x05, 0xe9, 0x8a, 0xb2, 0x60, 0x90, 0xfb, 0x03, 0x08, + 0xa6, 0x89, 0xaf, 0xf7, 0x54, 0x05, 0x0e, 0xda, 0xf9, 0x7c, 0xf9, 0x31, + 0x15, 0xfb, 0x64, 0x72, 0x06, 0xc4, 0x86, 0xa2, 0x7b, 0x8b, 0x68, 0x8b, + 0x7a, 0x83, 0x64, 0x80, 0x62, 0x08, 0x51, 0xfb, 0x65, 0x05, 0x70, 0x2a, + 0x75, 0x59, 0x6d, 0x66, 0x69, 0x63, 0x5f, 0x77, 0x54, 0x8b, 0x3f, 0x8b, + 0x5d, 0xb1, 0x8b, 0xca, 0x8b, 0xa6, 0x8e, 0x9a, 0xa4, 0xe6, 0x08, 0xdd, + 0xf7, 0xc0, 0x05, 0x9c, 0xc4, 0x9a, 0x97, 0xc9, 0x8e, 0x08, 0xa4, 0xfb, + 0xcb, 0x72, 0x07, 0x99, 0x89, 0x98, 0x89, 0x8f, 0x8b, 0xab, 0x86, 0x95, + 0x83, 0x8b, 0x75, 0x8b, 0x7f, 0x85, 0x6c, 0x82, 0x6a, 0x08, 0x53, 0xfb, + 0x62, 0x05, 0x76, 0x3b, 0x7f, 0x4d, 0x8b, 0x6a, 0x8b, 0x29, 0xe7, 0x47, + 0xf7, 0x17, 0x8b, 0xe0, 0x8b, 0xce, 0xa6, 0xb8, 0xc0, 0xad, 0xb2, 0xa3, + 0xc1, 0xaa, 0xf7, 0x00, 0x08, 0xcd, 0xf7, 0x78, 0x05, 0xb3, 0xf7, 0x18, + 0x92, 0x95, 0xc2, 0x96, 0x08, 0xa4, 0x07, 0x0e, 0xa3, 0xf9, 0x5f, 0xf9, + 0x31, 0x15, 0xfb, 0x54, 0x72, 0x06, 0x96, 0x8a, 0x95, 0x8a, 0x8f, 0x8b, + 0xa7, 0x88, 0x97, 0x82, 0x8b, 0x78, 0x8b, 0x75, 0x77, 0x5f, 0x64, 0x4e, + 0x08, 0xfb, 0x52, 0xfb, 0xc2, 0x58, 0xf8, 0x25, 0x05, 0x8a, 0x91, 0x8b, + 0x8f, 0x8b, 0x91, 0x8b, 0xad, 0x94, 0x90, 0xce, 0x91, 0x08, 0xa4, 0xfb, + 0xbe, 0x72, 0x07, 0xc9, 0x8b, 0x91, 0x81, 0xa1, 0xfb, 0x23, 0x08, 0xd7, + 0xfc, 0x91, 0xab, 0x8b, 0xf8, 0x1d, 0xf9, 0x02, 0x05, 0x98, 0x9e, 0x9d, + 0x97, 0xa7, 0x94, 0x08, 0xa4, 0x07, 0x0e, 0xf7, 0x8a, 0xfa, 0x40, 0xf9, + 0x31, 0x15, 0xfb, 0x4f, 0x72, 0x06, 0xc3, 0x87, 0x92, 0x86, 0x8b, 0x67, + 0x8b, 0x7f, 0x88, 0x83, 0x7f, 0x71, 0x08, 0xfb, 0x30, 0xfb, 0xdb, 0x6a, + 0xf7, 0xbb, 0x05, 0x85, 0xbe, 0x8b, 0x8e, 0x8b, 0x96, 0x8b, 0xb7, 0x95, + 0x94, 0xc0, 0x90, 0x08, 0xa4, 0xfb, 0xa1, 0x73, 0x07, 0xc7, 0x83, 0x95, + 0x7d, 0x8c, 0x35, 0x08, 0xfb, 0x2a, 0xfb, 0xcb, 0x64, 0xf7, 0xf1, 0x05, + 0x8a, 0x90, 0x8b, 0x92, 0x8b, 0x8f, 0x8b, 0xaf, 0x99, 0x96, 0xba, 0x91, + 0x08, 0xa4, 0xfb, 0xa9, 0x73, 0x07, 0xcc, 0x80, 0x8d, 0x89, 0x95, 0x44, + 0x08, 0xd9, 0xfc, 0xd7, 0xa8, 0x8b, 0xf7, 0x7d, 0xf8, 0x7d, 0xc6, 0xfc, + 0x7d, 0xa8, 0x8b, 0xf7, 0xb2, 0xf8, 0xe2, 0x05, 0xa7, 0xc2, 0x99, 0x97, + 0xb5, 0x91, 0x08, 0xa3, 0x07, 0x0e, 0xa3, 0xf8, 0xde, 0xa4, 0x15, 0x43, + 0x93, 0x7c, 0x99, 0x6e, 0xe9, 0x08, 0x41, 0xf7, 0x81, 0xf7, 0x5b, 0xf7, + 0x61, 0x05, 0xb7, 0xb7, 0x9e, 0x97, 0xaf, 0x90, 0x08, 0xa4, 0xfb, 0x5f, + 0x72, 0x07, 0x95, 0x8a, 0x93, 0x8a, 0x8f, 0x8b, 0xa2, 0x89, 0x95, 0x84, + 0x8b, 0x7c, 0x8b, 0x79, 0x78, 0x71, 0x58, 0x55, 0x08, 0x2d, 0x28, 0x80, + 0xb0, 0x05, 0x89, 0x92, 0x89, 0x91, 0x89, 0x90, 0x74, 0xd4, 0x80, 0xb5, + 0x8b, 0x99, 0x8b, 0xa2, 0x96, 0x94, 0xac, 0x8f, 0x90, 0x8b, 0x96, 0x8c, + 0x99, 0x8d, 0x08, 0xa4, 0xfb, 0xc5, 0x72, 0x07, 0xc7, 0x85, 0x9a, 0x80, + 0x9b, 0x5d, 0x08, 0xdf, 0xfb, 0xa4, 0x47, 0x41, 0x05, 0xfb, 0x32, 0xfb, + 0x42, 0x6c, 0x6f, 0x61, 0x83, 0x08, 0x72, 0xf7, 0x6a, 0xa4, 0x07, 0x5e, + 0x8f, 0x77, 0x98, 0x8b, 0xa2, 0x8b, 0x98, 0x93, 0x99, 0xa1, 0xa3, 0x08, + 0xf7, 0x1a, 0xf7, 0x28, 0x05, 0x8f, 0x7d, 0x8d, 0x84, 0x98, 0x64, 0xa6, + 0x3e, 0x96, 0x60, 0x8b, 0x76, 0x8b, 0x72, 0x7d, 0x83, 0x55, 0x86, 0x08, + 0x72, 0xf7, 0xc8, 0xa4, 0x07, 0x0e, 0x6b, 0xf7, 0x7e, 0xf7, 0xcd, 0x15, + 0x4f, 0xfb, 0x6c, 0x05, 0x79, 0x52, 0x7d, 0x81, 0x46, 0x86, 0x08, 0x72, + 0xf7, 0xd6, 0xa4, 0x07, 0x4a, 0x8e, 0x7f, 0x92, 0x8b, 0xb0, 0x8b, 0x97, + 0x8d, 0x95, 0x91, 0xa2, 0x08, 0xbf, 0xf7, 0x53, 0xf7, 0x52, 0xf7, 0x9f, + 0x05, 0xad, 0xb9, 0x9e, 0x9a, 0xb1, 0x93, 0x08, 0xa4, 0xfb, 0x64, 0x72, + 0x07, 0xc0, 0x89, 0x99, 0x82, 0x8b, 0x68, 0x8b, 0x79, 0x85, 0x7e, 0x77, + 0x6e, 0x08, 0xfb, 0x15, 0xfb, 0x4e, 0x05, 0x84, 0xa1, 0x7c, 0xb7, 0x88, + 0x96, 0x82, 0xa8, 0x84, 0x9f, 0x88, 0x95, 0x74, 0xcd, 0x81, 0xaf, 0x8b, + 0x9c, 0x8b, 0xa7, 0x9a, 0x93, 0xc2, 0x8c, 0x08, 0xa4, 0xfb, 0xaf, 0x72, + 0x07, 0xbe, 0x84, 0x8e, 0x88, 0x9e, 0x56, 0x08, 0xe3, 0xfb, 0xa0, 0x05, + 0x0e, 0x6b, 0xf8, 0xbe, 0xf7, 0x56, 0x15, 0x70, 0x90, 0x05, 0x6c, 0x59, + 0x65, 0x61, 0x63, 0x70, 0x5e, 0x6c, 0x50, 0x7d, 0x33, 0x8b, 0x08, 0x45, + 0x8b, 0xf8, 0x46, 0xf8, 0xf1, 0x8b, 0xa8, 0xfc, 0x68, 0x8b, 0x52, 0xfb, + 0x46, 0xa7, 0x87, 0x05, 0xda, 0xf7, 0x02, 0xca, 0xb0, 0xf7, 0x02, 0x8b, + 0x08, 0xd9, 0x8b, 0xfc, 0x46, 0xfc, 0xf1, 0x8b, 0x6e, 0xf8, 0x8e, 0x8b, + 0xc6, 0xf7, 0x56, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0xf7, 0xf9, 0x13, 0x15, + 0x92, 0xae, 0xfb, 0x5c, 0x8b, 0xfb, 0x5b, 0xfd, 0xd5, 0xf7, 0x6f, 0x8b, + 0x92, 0xae, 0x3d, 0x8b, 0x05, 0x7c, 0x8b, 0x83, 0x8d, 0x86, 0x90, 0x87, + 0x8f, 0x87, 0x94, 0x8c, 0x8f, 0x08, 0xf7, 0x32, 0xf9, 0x38, 0x05, 0x99, + 0xc7, 0x8d, 0x8e, 0xaf, 0x8b, 0x08, 0xd0, 0x06, 0x0e, 0xfc, 0x01, 0x8a, + 0xf9, 0x41, 0x15, 0xf7, 0x58, 0xfd, 0x53, 0xdf, 0x8b, 0xfb, 0x57, 0xf9, + 0x53, 0x36, 0x8b, 0x05, 0x0e, 0xfb, 0xca, 0x5a, 0xfb, 0x0e, 0x15, 0x84, + 0x68, 0xf7, 0x5b, 0x8b, 0xf7, 0x5c, 0xf9, 0xd3, 0xfb, 0x70, 0x8b, 0x84, + 0x68, 0xd9, 0x8b, 0x05, 0xa1, 0x8b, 0x9b, 0x80, 0x88, 0x7f, 0x08, 0xfb, + 0x32, 0xfd, 0x39, 0x05, 0x7d, 0x51, 0x89, 0x88, 0x67, 0x8b, 0x08, 0x47, + 0x06, 0x0e, 0x42, 0xf7, 0x30, 0xf7, 0xc4, 0x15, 0xf7, 0x15, 0xf7, 0xa4, + 0xf7, 0x15, 0xfb, 0xa4, 0xe4, 0x8b, 0xfb, 0x46, 0xf8, 0x01, 0x3b, 0x8b, + 0xfb, 0x46, 0xfc, 0x01, 0xe4, 0x8b, 0x05, 0x0e, 0xf8, 0x88, 0xfb, 0x11, + 0x15, 0xbd, 0xfc, 0x88, 0x59, 0xf8, 0x88, 0x07, 0x0e, 0xfb, 0xca, 0xf7, + 0xd3, 0xf9, 0x41, 0x15, 0xfb, 0x08, 0x58, 0x40, 0x35, 0x8b, 0x3a, 0x08, + 0x50, 0xad, 0x64, 0xbe, 0xb4, 0xa9, 0xaa, 0xb5, 0x1e, 0x8b, 0xa6, 0x81, + 0x9b, 0x6d, 0x9f, 0x74, 0x9a, 0x84, 0x95, 0x8b, 0x9a, 0x8b, 0xae, 0xb2, + 0xb2, 0xda, 0xb5, 0x08, 0x7e, 0xa3, 0x05, 0x0e, 0xf8, 0x46, 0xf7, 0x13, + 0x15, 0x62, 0x54, 0x7c, 0x7c, 0x7b, 0x8b, 0x84, 0x8b, 0x86, 0x91, 0x8b, + 0x94, 0x8b, 0xa4, 0x95, 0xb5, 0xa3, 0xdc, 0x08, 0xd2, 0xf7, 0x80, 0xfb, + 0x03, 0x84, 0x79, 0x50, 0x05, 0x82, 0xbe, 0x75, 0xa0, 0x60, 0x8b, 0x08, + 0xfb, 0x0f, 0xfb, 0x2a, 0xfb, 0x54, 0xfb, 0x30, 0x3f, 0xb6, 0x58, 0xcc, + 0x1f, 0xc8, 0x8b, 0xb9, 0xb0, 0xc4, 0xea, 0x80, 0x64, 0x88, 0x7d, 0x8b, + 0x7d, 0x08, 0x66, 0xa9, 0x6e, 0xb0, 0x1e, 0xba, 0x8b, 0xba, 0xb2, 0xc4, + 0xe2, 0x08, 0x76, 0x9a, 0x05, 0xfb, 0x3c, 0xf7, 0xb9, 0x15, 0xa1, 0x89, + 0x9a, 0x79, 0x8b, 0x70, 0x8b, 0x50, 0x69, 0xfb, 0x05, 0x65, 0x47, 0x70, + 0x5b, 0x6d, 0x70, 0x70, 0x8b, 0x71, 0x8b, 0x78, 0xa2, 0x8b, 0xaa, 0x8b, + 0xbf, 0xac, 0xef, 0xb4, 0xd5, 0x08, 0xa9, 0xc0, 0xac, 0xaa, 0xa6, 0x89, + 0x08, 0x0e, 0xd7, 0xf9, 0x16, 0x15, 0xbc, 0x99, 0x84, 0x74, 0x1f, 0x8b, + 0x7e, 0x7e, 0x56, 0x71, 0x30, 0x08, 0x2d, 0xfb, 0xdb, 0x05, 0x82, 0x6b, + 0x80, 0x5f, 0x8b, 0x86, 0x08, 0x6f, 0xd4, 0x6b, 0xcc, 0xf7, 0x37, 0xf7, + 0x31, 0xf7, 0x40, 0xf7, 0x47, 0xd4, 0x5d, 0xbe, 0x49, 0x1e, 0x58, 0x8b, + 0x67, 0x73, 0x58, 0x48, 0x08, 0xe5, 0xf7, 0xdc, 0x05, 0x45, 0x7e, 0x5a, + 0x84, 0x32, 0x81, 0x08, 0x70, 0x07, 0xf7, 0x5b, 0xfb, 0x8c, 0x15, 0xa8, + 0x9a, 0x74, 0x5d, 0x1f, 0x8b, 0x50, 0x70, 0x2e, 0x67, 0x4d, 0x69, 0x4f, + 0x64, 0x6c, 0x60, 0x8b, 0x79, 0x8b, 0x7e, 0x97, 0x8b, 0x9a, 0x8b, 0x94, + 0x9d, 0xdd, 0x93, 0xab, 0x96, 0xb2, 0xa2, 0xca, 0x9a, 0xae, 0xa5, 0xc4, + 0xab, 0xa9, 0xac, 0x8b, 0x08, 0x0e, 0xfb, 0x5b, 0xf7, 0xd2, 0xf7, 0x21, + 0x15, 0x5b, 0x48, 0x6c, 0x74, 0x60, 0x8b, 0x60, 0x8b, 0x6d, 0xaf, 0x8b, + 0xc1, 0x8b, 0xc9, 0xa5, 0xe5, 0xaf, 0xcc, 0xa5, 0xba, 0xa9, 0xa3, 0xa9, + 0x8b, 0x97, 0x8b, 0x95, 0x84, 0x8b, 0x81, 0x8b, 0x87, 0x89, 0x85, 0x85, + 0x82, 0x08, 0x82, 0x7b, 0x87, 0x80, 0x8b, 0x7f, 0x08, 0x6d, 0xa4, 0x75, + 0xac, 0xaf, 0xa5, 0xa8, 0xb4, 0xc0, 0x5d, 0xb0, 0x49, 0xfb, 0x21, 0xfb, + 0x24, 0xfb, 0x38, 0xfb, 0x34, 0x32, 0xca, 0x4d, 0xe5, 0x1e, 0xb7, 0x8b, + 0xb6, 0x9b, 0xad, 0xa8, 0xa5, 0xa1, 0x9b, 0x9e, 0xae, 0xbd, 0x08, 0x6f, + 0x9d, 0x05, 0x0e, 0xf8, 0x3f, 0xf7, 0x17, 0x15, 0x70, 0x5e, 0x72, 0x70, + 0x7c, 0x8b, 0x86, 0x8b, 0x85, 0x91, 0x8b, 0x91, 0x8b, 0x94, 0xa1, 0xe2, + 0xae, 0xf7, 0x13, 0x08, 0xf7, 0x03, 0xf8, 0x29, 0x05, 0x4f, 0x7d, 0x5a, + 0x84, 0x27, 0x83, 0x08, 0x70, 0xa0, 0x07, 0xa5, 0x9a, 0x81, 0x79, 0x1f, + 0x8b, 0x82, 0x85, 0x72, 0x74, 0x37, 0x08, 0x79, 0x47, 0x05, 0x73, 0xa3, + 0x78, 0x94, 0x6e, 0x8b, 0x08, 0xfb, 0x0e, 0xfb, 0x2a, 0xfb, 0x55, 0xfb, + 0x31, 0x43, 0xb8, 0x56, 0xc8, 0x1f, 0xca, 0x8b, 0xb9, 0xaf, 0xc4, 0xea, + 0x83, 0x66, 0x88, 0x7c, 0x8b, 0x7c, 0x08, 0x64, 0xa1, 0x74, 0xb1, 0x1e, + 0xbc, 0x8b, 0xb8, 0xb1, 0xc2, 0xe3, 0x08, 0x75, 0x9b, 0x05, 0xfb, 0x30, + 0xf7, 0xb5, 0x15, 0xa1, 0x8a, 0x9a, 0x76, 0x8b, 0x6f, 0x8b, 0x61, 0x5f, + 0xfb, 0x18, 0x69, 0x4c, 0x6f, 0x5a, 0x6e, 0x72, 0x6e, 0x8b, 0x72, 0x8b, + 0x79, 0xa7, 0x8d, 0xae, 0x8e, 0xc1, 0xaa, 0xe7, 0xaf, 0xcc, 0x08, 0xab, + 0xc4, 0xaf, 0xab, 0xa9, 0x89, 0x08, 0x0e, 0xfb, 0x5b, 0xf7, 0xd1, 0xf7, + 0x22, 0x15, 0x5c, 0x46, 0x6f, 0x75, 0x61, 0x8b, 0x60, 0x8b, 0x75, 0xa7, + 0x8b, 0xc1, 0x8b, 0x9b, 0x8d, 0x98, 0x8f, 0x9f, 0xf3, 0x9f, 0xbc, 0xa1, + 0xbd, 0xb9, 0xae, 0xab, 0x9e, 0xb1, 0x8b, 0xae, 0x08, 0xbe, 0x5f, 0xaf, + 0x4e, 0xfb, 0x24, 0xfb, 0x24, 0xfb, 0x37, 0xfb, 0x39, 0x37, 0xcb, 0x4c, + 0xe2, 0x1e, 0xd7, 0x8b, 0xc1, 0xb2, 0xc7, 0xee, 0x08, 0x6e, 0x9c, 0x05, + 0xfb, 0x3d, 0xd3, 0x15, 0xaf, 0xf7, 0x1e, 0xb9, 0xd8, 0xbb, 0x8b, 0x9e, + 0x8b, 0x94, 0x7f, 0x8b, 0x75, 0x8b, 0x3f, 0x5b, 0x4a, 0x3e, 0x6e, 0x84, + 0x89, 0x7c, 0x86, 0x80, 0x87, 0x08, 0x0e, 0xfb, 0xca, 0xf7, 0xdc, 0xf8, + 0x55, 0x15, 0x2f, 0x8b, 0x9d, 0xd2, 0x05, 0xa4, 0xee, 0xaa, 0xbd, 0xae, + 0x8b, 0x95, 0x8b, 0x92, 0x86, 0x8b, 0x83, 0x8b, 0x89, 0x8a, 0x88, 0x87, + 0x85, 0x83, 0x7f, 0x88, 0x82, 0x8b, 0x81, 0x08, 0x70, 0xa1, 0x75, 0xa6, + 0xa9, 0xa0, 0xa1, 0xaa, 0xbc, 0x64, 0xaa, 0x4f, 0x1e, 0x57, 0x8b, 0x5b, + 0x75, 0x67, 0x64, 0x61, 0x5d, 0x78, 0x62, 0x6e, 0x26, 0x08, 0x42, 0x8b, + 0x82, 0x61, 0xd4, 0x8b, 0x05, 0x55, 0xfb, 0x82, 0x6f, 0xfb, 0x11, 0x85, + 0x6e, 0x6c, 0xfb, 0x28, 0x78, 0x62, 0x63, 0x8b, 0x81, 0x8b, 0x83, 0x90, + 0x8b, 0x91, 0x8b, 0x8d, 0x8c, 0x8e, 0x8e, 0x8f, 0x93, 0x96, 0x8f, 0x97, + 0x8b, 0x96, 0x08, 0xa3, 0x73, 0xa3, 0x72, 0x6f, 0x73, 0x72, 0x6e, 0x5b, + 0xb2, 0x6c, 0xc7, 0x1e, 0xb5, 0x8b, 0xb0, 0x99, 0xaa, 0xa8, 0xb3, 0xaf, + 0xa6, 0xc0, 0xac, 0xf2, 0xa3, 0xda, 0x96, 0xb8, 0xc1, 0xf7, 0x91, 0x08, + 0xe5, 0x8b, 0x94, 0xb5, 0x05, 0x0e, 0xf8, 0x72, 0xf8, 0x41, 0x15, 0xfb, + 0x03, 0x06, 0x6a, 0xa3, 0x6c, 0x94, 0x5d, 0x8b, 0xfb, 0x0f, 0x8b, 0x28, + 0x3a, 0x8b, 0x26, 0x8b, 0x58, 0xa5, 0x67, 0xc1, 0x74, 0x3a, 0x5d, 0x7c, + 0x7d, 0x8b, 0x66, 0x8b, 0x6c, 0x9d, 0x77, 0xb7, 0x7c, 0x4d, 0x7c, 0x77, + 0x83, 0x74, 0x78, 0x08, 0x7a, 0x7d, 0x80, 0x73, 0x8b, 0x73, 0x08, 0x4a, + 0xd4, 0x62, 0xf7, 0x07, 0xf7, 0x20, 0xee, 0xc9, 0xe3, 0x1e, 0x8b, 0xc7, + 0x63, 0xad, 0xfb, 0x01, 0xaa, 0x08, 0x56, 0x9a, 0x05, 0x6b, 0x94, 0x78, + 0x99, 0x8b, 0x9a, 0x8b, 0x9b, 0x9a, 0x9f, 0x98, 0x8b, 0x90, 0x8b, 0x92, + 0x8a, 0x93, 0x88, 0x96, 0x88, 0x94, 0x8a, 0x96, 0x8b, 0xb7, 0x8b, 0xb7, + 0x97, 0xb2, 0xa1, 0x08, 0xc5, 0xac, 0xaa, 0xbe, 0x8b, 0xc7, 0x8b, 0x9b, + 0x8a, 0x95, 0x86, 0x9b, 0x08, 0xce, 0x06, 0xc3, 0x07, 0xfb, 0xff, 0xfc, + 0x47, 0x15, 0x96, 0x8a, 0xda, 0x71, 0x9f, 0x81, 0xa7, 0x7e, 0x98, 0x79, + 0x8b, 0x71, 0x08, 0x60, 0x5f, 0x71, 0x3f, 0x4a, 0x5d, 0xab, 0xb9, 0x1e, + 0x8b, 0x9f, 0x94, 0x9b, 0xa0, 0x9f, 0x08, 0x97, 0x97, 0xaa, 0x9d, 0x92, + 0x8a, 0x08, 0xf7, 0x20, 0xf8, 0x49, 0x15, 0xa5, 0x9e, 0x72, 0x69, 0x1f, + 0x8b, 0x69, 0x7f, 0x59, 0x7a, 0x67, 0x75, 0x5d, 0x72, 0x75, 0x6d, 0x8b, + 0x6f, 0x8b, 0x7c, 0xa0, 0x8b, 0xb1, 0x8b, 0xb3, 0x9c, 0xc8, 0xa0, 0xb1, + 0x08, 0x9e, 0xac, 0xa0, 0x9b, 0xa5, 0x8b, 0x08, 0x0e, 0x34, 0xf8, 0x70, + 0xf7, 0x22, 0x15, 0x60, 0x4d, 0x78, 0x76, 0x7e, 0x8b, 0x84, 0x8b, 0x81, + 0x94, 0x8b, 0x92, 0x8b, 0x8d, 0x8b, 0x8c, 0x8e, 0x94, 0x08, 0xc5, 0xf7, + 0x46, 0x05, 0x9e, 0xc8, 0x96, 0xb5, 0x8b, 0x9e, 0x8b, 0xba, 0x6e, 0xa7, + 0x5c, 0x8b, 0x67, 0x8b, 0x6e, 0x7e, 0x67, 0x6d, 0x6c, 0x71, 0x73, 0x6d, + 0x53, 0x3b, 0x08, 0xf6, 0xf8, 0x34, 0x05, 0x3e, 0x7c, 0x59, 0x83, 0x3a, + 0x84, 0x08, 0x70, 0x07, 0x93, 0x8c, 0x94, 0x8b, 0x90, 0x8b, 0xa6, 0x8b, + 0x99, 0x80, 0x8b, 0x75, 0x8b, 0x82, 0x88, 0x7c, 0x86, 0x78, 0x08, 0xfb, + 0x2e, 0xfc, 0xcb, 0xf7, 0x0d, 0x8b, 0x05, 0xbe, 0xf7, 0x46, 0xa0, 0xbd, + 0xbd, 0xd4, 0xb5, 0xc7, 0xac, 0xa8, 0xa5, 0x8b, 0x97, 0x8b, 0x95, 0x81, + 0x8b, 0x80, 0x8b, 0x85, 0x89, 0x83, 0x88, 0x82, 0x8b, 0x89, 0x87, 0x80, + 0x84, 0x77, 0x87, 0x7f, 0x88, 0x80, 0x87, 0x81, 0x08, 0x5b, 0xfb, 0x20, + 0x7e, 0x59, 0x8b, 0x62, 0x8b, 0x69, 0xa6, 0x73, 0xb2, 0x8b, 0xc8, 0x8b, + 0xb3, 0xac, 0xcd, 0xf2, 0x08, 0x75, 0x9a, 0x05, 0x0e, 0xfc, 0x01, 0xf7, + 0x6c, 0xf7, 0x21, 0x15, 0x7d, 0x77, 0x05, 0x71, 0x64, 0x74, 0x76, 0x7c, + 0x8b, 0x83, 0x8b, 0x84, 0x92, 0x8b, 0x93, 0x8b, 0x91, 0x91, 0xad, 0x8e, + 0x97, 0x08, 0xe6, 0xf7, 0xe2, 0x05, 0x55, 0x7f, 0x45, 0x81, 0x3d, 0x85, + 0x08, 0x70, 0x07, 0xb6, 0x9b, 0x83, 0x76, 0x1f, 0x8b, 0x83, 0x88, 0x7c, + 0x87, 0x7a, 0x08, 0x51, 0xfb, 0x6b, 0x05, 0x83, 0x6f, 0x86, 0x6f, 0x8b, + 0x7e, 0x8b, 0x66, 0xa7, 0x71, 0xb4, 0x8b, 0xc7, 0x8b, 0xb0, 0xaa, 0xd1, + 0xf4, 0x08, 0x75, 0x99, 0x05, 0x75, 0xf8, 0xb4, 0x15, 0x68, 0x6c, 0x6c, + 0x68, 0x64, 0xa8, 0x6d, 0xb0, 0xb1, 0xaa, 0xa9, 0xb0, 0xb0, 0x6b, 0xaa, + 0x66, 0x1f, 0x0e, 0xfc, 0x01, 0xaa, 0xf8, 0x2b, 0x15, 0xbd, 0x97, 0x86, + 0x71, 0x1f, 0x8b, 0x7f, 0x86, 0x72, 0x84, 0x6e, 0x08, 0x2f, 0xfb, 0xf7, + 0x05, 0x71, 0x27, 0x7a, 0x6c, 0x6f, 0x8b, 0x80, 0x8b, 0x7e, 0x92, 0x8b, + 0x90, 0x8b, 0x8d, 0x8c, 0x8d, 0x8c, 0x8d, 0x96, 0x9b, 0x8d, 0x90, 0x8b, + 0x96, 0x08, 0xa6, 0x75, 0xa1, 0x70, 0x71, 0x74, 0x73, 0x6e, 0x5d, 0xb6, + 0x6c, 0xc9, 0x1e, 0xef, 0x8b, 0xd0, 0xd7, 0xb3, 0xf7, 0x2f, 0x08, 0xf7, + 0x06, 0xf8, 0x4a, 0x05, 0x50, 0x7e, 0x66, 0x86, 0xfb, 0x04, 0x81, 0x08, + 0x70, 0x07, 0xf7, 0x47, 0xf7, 0xaa, 0x15, 0x68, 0x6c, 0x6c, 0x68, 0x64, + 0xa8, 0x6d, 0xb0, 0xb1, 0xaa, 0xa9, 0xb0, 0xb0, 0x6c, 0xaa, 0x65, 0x1f, + 0x0e, 0xf7, 0x29, 0xf7, 0x50, 0x15, 0xb2, 0xa6, 0x05, 0xaa, 0xfb, 0x3e, + 0xa9, 0x56, 0xc9, 0x8b, 0xbd, 0x8b, 0xaf, 0xac, 0xbd, 0xe6, 0x08, 0x75, + 0x96, 0x05, 0x70, 0x5c, 0x7b, 0x7a, 0x78, 0x8b, 0x6f, 0x8b, 0x7f, 0xae, + 0x65, 0xf7, 0x57, 0x08, 0xca, 0xc2, 0x05, 0xcf, 0xc5, 0xa0, 0x97, 0xb9, + 0x91, 0x08, 0xa4, 0xfb, 0x63, 0x72, 0x07, 0xb2, 0x89, 0x97, 0x86, 0x8b, + 0x7b, 0x8b, 0x71, 0x65, 0x66, 0xfb, 0x12, 0x28, 0x08, 0xf7, 0x0f, 0xf8, + 0x60, 0x05, 0x3e, 0x7d, 0x57, 0x83, 0x3c, 0x83, 0x08, 0x70, 0x07, 0x93, + 0x8c, 0x94, 0x8b, 0x8f, 0x8b, 0xa7, 0x8b, 0x99, 0x80, 0x8b, 0x74, 0x8b, + 0x82, 0x88, 0x7d, 0x86, 0x78, 0x08, 0xfb, 0x30, 0xfc, 0xcb, 0xf7, 0x0e, + 0x8b, 0x05, 0xbd, 0xf7, 0x50, 0x05, 0x0e, 0xfc, 0x01, 0xf7, 0x6c, 0xf7, + 0x21, 0x15, 0x63, 0x50, 0x76, 0x76, 0x7a, 0x8b, 0x83, 0x8b, 0x84, 0x92, + 0x8b, 0x93, 0x8b, 0x99, 0x93, 0xad, 0x99, 0xbf, 0x08, 0xf7, 0x25, 0xf8, + 0x9f, 0x05, 0x35, 0x7a, 0x5b, 0x85, 0x40, 0x84, 0x08, 0x70, 0x07, 0x96, + 0x8c, 0x91, 0x8b, 0x8f, 0x8b, 0xa6, 0x8b, 0x9a, 0x81, 0x8b, 0x79, 0x8b, + 0x7e, 0x7d, 0x4d, 0x77, 0x48, 0x08, 0x41, 0xfb, 0x9c, 0x05, 0x75, 0x3f, + 0x7f, 0x51, 0x8b, 0x73, 0x8b, 0x67, 0xa6, 0x73, 0xb3, 0x8b, 0xc9, 0x8b, + 0xb1, 0xaa, 0xd0, 0xf4, 0x08, 0x75, 0x99, 0x05, 0x0e, 0xf7, 0x1b, 0xad, + 0xf8, 0x2b, 0x15, 0x93, 0x06, 0xab, 0x99, 0x83, 0x79, 0x1f, 0x8b, 0x7d, + 0x83, 0x69, 0x70, 0x2c, 0x08, 0x48, 0xfb, 0x82, 0xf7, 0x0d, 0x8b, 0x05, + 0xc0, 0xf7, 0x52, 0xb1, 0xe1, 0xc3, 0xce, 0xa1, 0xa4, 0xa8, 0xa0, 0x98, + 0x8b, 0x95, 0x8b, 0x94, 0x81, 0x8b, 0x7e, 0x8b, 0x7c, 0x7f, 0x61, 0x6a, + 0x25, 0x08, 0x4a, 0xfb, 0x63, 0xf7, 0x0c, 0x8b, 0x05, 0xc6, 0xf7, 0x54, + 0x91, 0x9d, 0xaf, 0xca, 0xb5, 0xd5, 0xb3, 0xb5, 0xa9, 0x8b, 0x97, 0x8b, + 0x96, 0x81, 0x8b, 0x80, 0x8b, 0x85, 0x88, 0x80, 0x87, 0x7e, 0x08, 0x5e, + 0xfb, 0x17, 0x05, 0x75, 0x4c, 0x7d, 0x4d, 0x8b, 0x6f, 0x8b, 0x62, 0xa3, + 0x75, 0xb6, 0x8b, 0xc9, 0x8b, 0xb3, 0xac, 0xc5, 0xed, 0x08, 0x75, 0x98, + 0x05, 0x86, 0x83, 0x86, 0x84, 0x89, 0x88, 0x74, 0x67, 0x76, 0x75, 0x7e, + 0x8b, 0x82, 0x8b, 0x84, 0x92, 0x8b, 0x92, 0x8b, 0x96, 0x8b, 0x8b, 0xa0, + 0xce, 0x08, 0xb8, 0xf7, 0x19, 0x05, 0x9a, 0xb6, 0x93, 0xb1, 0x8b, 0xa5, + 0x8b, 0xb3, 0x6a, 0xaa, 0x5f, 0x8b, 0x47, 0x8b, 0x5d, 0x63, 0x37, 0xfb, + 0x18, 0x9e, 0xbd, 0x92, 0xa5, 0x8b, 0xa7, 0x8b, 0xb5, 0x72, 0xa5, 0x61, + 0x8b, 0x6f, 0x8b, 0x6d, 0x80, 0x6f, 0x74, 0x08, 0x66, 0x6f, 0x6d, 0x65, + 0x4a, 0x27, 0x08, 0xcb, 0xf7, 0x5b, 0x05, 0x4b, 0x7c, 0x76, 0x88, 0xfb, + 0x07, 0x82, 0x08, 0x70, 0x07, 0x0e, 0x34, 0xf8, 0x6b, 0xf7, 0x1b, 0x15, + 0x63, 0x4d, 0x7e, 0x7d, 0x7a, 0x8b, 0x83, 0x8b, 0x85, 0x92, 0x8b, 0x95, + 0x8b, 0x95, 0x92, 0xa2, 0x9d, 0xc1, 0x08, 0xaf, 0xf7, 0x01, 0x05, 0x9b, + 0xb9, 0x95, 0xb8, 0x8b, 0xa3, 0x8b, 0xbb, 0x71, 0xa6, 0x5c, 0x8b, 0x66, + 0x8b, 0x67, 0x7c, 0x6f, 0x71, 0x67, 0x68, 0x78, 0x73, 0x48, 0x28, 0x08, + 0xcb, 0xf7, 0x5a, 0x05, 0x4b, 0x7d, 0x3b, 0x80, 0x53, 0x89, 0x08, 0x70, + 0x07, 0xb5, 0x8a, 0x97, 0x86, 0x8b, 0x78, 0x8b, 0x80, 0x7f, 0x5c, 0x69, + 0xfb, 0x0c, 0x08, 0x70, 0x2b, 0x6e, 0xfb, 0x00, 0xf7, 0x0d, 0x8b, 0x05, + 0xba, 0xf7, 0x41, 0xaf, 0xe2, 0xc9, 0xdc, 0x9f, 0xa6, 0xaa, 0xa1, 0x9d, + 0x8b, 0x97, 0x8b, 0x98, 0x80, 0x8b, 0x81, 0x8b, 0x88, 0x89, 0x83, 0x88, + 0x81, 0x08, 0x54, 0xfb, 0x3a, 0x05, 0x7b, 0x5b, 0x7f, 0x52, 0x8b, 0x71, + 0x8b, 0x66, 0xa5, 0x74, 0xb5, 0x8b, 0xc6, 0x8b, 0xb5, 0xad, 0xc5, 0xec, + 0x08, 0x75, 0x98, 0x05, 0x0e, 0xf7, 0xb0, 0xf8, 0x62, 0x15, 0xfb, 0x27, + 0xfb, 0x20, 0xfb, 0x33, 0xfb, 0x3c, 0x36, 0xce, 0x4c, 0xe7, 0xf7, 0x29, + 0xf7, 0x1c, 0xf7, 0x2f, 0xf7, 0x3d, 0xe3, 0x49, 0xca, 0x30, 0x1f, 0x82, + 0x6e, 0x15, 0xa8, 0x9d, 0x75, 0x67, 0x1f, 0x8b, 0x47, 0x6c, 0xfb, 0x16, + 0x6b, 0x45, 0x6e, 0x4d, 0x6d, 0x6e, 0x68, 0x8b, 0x6d, 0x8b, 0x78, 0xa3, + 0x8b, 0xb1, 0x8b, 0xd9, 0xb0, 0xf7, 0x26, 0xae, 0xc9, 0xa5, 0xb9, 0xa8, + 0xa2, 0xab, 0x8b, 0x08, 0x0e, 0xa2, 0xf8, 0x2b, 0x15, 0xb8, 0x89, 0x94, + 0x87, 0x8b, 0x78, 0x8b, 0x82, 0x82, 0x63, 0x7e, 0x5a, 0x08, 0x27, 0xfc, + 0x18, 0x05, 0x7b, 0x4e, 0x7f, 0x7e, 0x62, 0x8b, 0x08, 0x85, 0x70, 0xf7, + 0x8d, 0xa6, 0x06, 0x5a, 0x8c, 0x7b, 0x93, 0x8b, 0xa3, 0x8b, 0x97, 0x93, + 0xac, 0x9d, 0xcf, 0x08, 0x93, 0xa7, 0x8e, 0x98, 0x05, 0xae, 0x79, 0x97, + 0x87, 0xa0, 0x8b, 0x08, 0xf7, 0x1b, 0xf7, 0x22, 0xf7, 0x49, 0xf7, 0x41, + 0xd5, 0x61, 0xba, 0x49, 0x1f, 0x52, 0x8b, 0x5f, 0x6b, 0x50, 0x38, 0x08, + 0xb1, 0xf7, 0x07, 0x05, 0x25, 0x7b, 0x64, 0x85, 0x57, 0x85, 0x08, 0x70, + 0x07, 0xf7, 0x97, 0x7b, 0x15, 0xa5, 0x89, 0x9a, 0x74, 0x89, 0x6b, 0x87, + 0x4a, 0x6b, 0x27, 0x67, 0x4a, 0x6c, 0x55, 0x6a, 0x6f, 0x6a, 0x8b, 0x75, + 0x8b, 0x7a, 0x9b, 0x8b, 0x9f, 0x8b, 0x9b, 0x93, 0xa9, 0xa6, 0xe6, 0xa3, + 0xdd, 0x95, 0xa7, 0x9b, 0xa3, 0x08, 0xa4, 0xb2, 0xac, 0xa4, 0xa5, 0x89, + 0x08, 0x0e, 0xf8, 0x07, 0xfb, 0x46, 0x15, 0x7d, 0x06, 0x67, 0x7c, 0x93, + 0x9f, 0x1f, 0x8b, 0x9b, 0xb1, 0xf7, 0x1f, 0xb5, 0xf7, 0x20, 0xa3, 0xd9, + 0x9e, 0xd2, 0xb5, 0xf7, 0x2f, 0x08, 0xfb, 0x01, 0x8b, 0x7c, 0x50, 0x05, + 0x86, 0xa7, 0x88, 0x96, 0x82, 0x96, 0x08, 0x81, 0x99, 0x76, 0x93, 0x74, + 0x8b, 0x3f, 0x8b, 0x33, 0x47, 0x50, 0x25, 0x69, 0x4e, 0x79, 0x50, 0x8b, + 0x54, 0x8b, 0x3b, 0xb3, 0x59, 0xcb, 0x8b, 0xc7, 0x8b, 0xb3, 0xa8, 0xbf, + 0xdd, 0x08, 0x4c, 0xfb, 0x69, 0x05, 0x7a, 0x57, 0x80, 0x83, 0x4d, 0x88, + 0x08, 0x70, 0xf7, 0x9f, 0x07, 0xa6, 0x07, 0x3a, 0xf8, 0xe9, 0x15, 0xa1, + 0x89, 0x98, 0x79, 0x8b, 0x6f, 0x8b, 0x56, 0x66, 0xfb, 0x0f, 0x68, 0x4d, + 0x6f, 0x59, 0x6e, 0x73, 0x6c, 0x8b, 0x71, 0x8b, 0x7e, 0x9e, 0x8b, 0xb1, + 0x8b, 0xc3, 0xa8, 0xe5, 0xb3, 0xd3, 0xab, 0xc3, 0xae, 0xaa, 0xa7, 0x89, + 0x08, 0x0e, 0xfb, 0x92, 0xa6, 0xf8, 0x2b, 0x15, 0xb8, 0x89, 0x94, 0x87, + 0x8b, 0x78, 0x8b, 0x72, 0x69, 0xfb, 0x14, 0x47, 0xfb, 0x79, 0x08, 0xf7, + 0x0d, 0x06, 0x9a, 0xb9, 0x99, 0xb6, 0x8f, 0x9a, 0xab, 0xf0, 0x9a, 0xb1, + 0xa8, 0xbb, 0xa5, 0xb8, 0xa1, 0xa4, 0x98, 0x8b, 0x8f, 0x8b, 0x90, 0x87, + 0x92, 0x82, 0x9a, 0x7a, 0x98, 0x83, 0x9b, 0x8b, 0x08, 0xad, 0xa4, 0xaa, + 0xb5, 0xb3, 0x74, 0xa5, 0x69, 0x1f, 0x58, 0x8b, 0x62, 0x58, 0x3c, 0xfb, + 0x32, 0x08, 0xcd, 0xf7, 0x65, 0x05, 0x4f, 0x7c, 0x78, 0x88, 0xfb, 0x0d, + 0x81, 0x08, 0x70, 0x07, 0x0e, 0xfb, 0x92, 0xf7, 0xe1, 0xf8, 0x61, 0x15, + 0x6e, 0x06, 0x80, 0x78, 0x88, 0x89, 0x7c, 0x8b, 0x82, 0x8b, 0x82, 0x8d, + 0x79, 0x92, 0x72, 0x95, 0x7e, 0x8e, 0x77, 0x8b, 0x3a, 0x8b, 0x56, 0x59, + 0x8b, 0x3f, 0x8b, 0x55, 0x99, 0x6e, 0xcd, 0x3d, 0xb1, 0x5e, 0x9d, 0x69, + 0x8b, 0x72, 0x08, 0x6d, 0x72, 0x73, 0x6b, 0x1e, 0x74, 0x8b, 0x76, 0x96, + 0x7b, 0x9f, 0x77, 0xa4, 0x83, 0xa2, 0x83, 0xc1, 0x08, 0x70, 0x8e, 0x75, + 0xfb, 0x3a, 0xa6, 0x8b, 0x05, 0x8f, 0x97, 0x97, 0x93, 0x98, 0x8b, 0x92, + 0x8b, 0x96, 0x88, 0x98, 0x86, 0xa3, 0x83, 0x9e, 0x87, 0x9f, 0x8b, 0xdf, + 0x8b, 0xcb, 0xc4, 0x8b, 0xd6, 0x8b, 0xb8, 0x72, 0xbc, 0x53, 0xcc, 0x65, + 0xb8, 0x79, 0xaa, 0x8b, 0xa1, 0x08, 0xab, 0xa0, 0xa0, 0xab, 0x1e, 0xb9, + 0x8b, 0xa5, 0x67, 0x9b, 0x38, 0x08, 0xa6, 0x89, 0xa2, 0xf7, 0x2d, 0x05, + 0x0e, 0xfc, 0x01, 0xf7, 0xad, 0xf8, 0x55, 0x15, 0x43, 0x8b, 0xb2, 0xf7, + 0x25, 0x68, 0x8b, 0x05, 0x55, 0x3a, 0x59, 0x62, 0x3c, 0x6d, 0x08, 0x68, + 0xbe, 0x07, 0x47, 0xfb, 0x82, 0x05, 0x7d, 0x58, 0x81, 0x5e, 0x8b, 0x7a, + 0x8b, 0x64, 0xa7, 0x71, 0xb5, 0x8b, 0xc7, 0x8b, 0xb3, 0xac, 0xcd, 0xf2, + 0x08, 0x75, 0x99, 0x05, 0x69, 0x56, 0x71, 0x70, 0x7b, 0x8b, 0x83, 0x8b, + 0x83, 0x93, 0x8b, 0x92, 0x8b, 0x9d, 0x9d, 0xd4, 0xaf, 0xf7, 0x0e, 0x08, + 0xac, 0xf7, 0x0a, 0xde, 0x8b, 0x8b, 0xb5, 0x05, 0x0e, 0x34, 0xf8, 0x6b, + 0xf7, 0x19, 0x15, 0x68, 0x56, 0x77, 0x76, 0x7a, 0x8b, 0x83, 0x8b, 0x85, + 0x93, 0x8b, 0x94, 0x8b, 0x95, 0x8b, 0x8b, 0xa4, 0xea, 0x08, 0xd9, 0xf7, + 0xa0, 0xfb, 0x0a, 0x8b, 0x05, 0x53, 0xfb, 0x55, 0x6e, 0x49, 0x52, 0x43, + 0x6c, 0x65, 0x75, 0x7a, 0x77, 0x8b, 0x7d, 0x8b, 0x84, 0x93, 0x8b, 0x9c, + 0x8b, 0x9a, 0x8d, 0x93, 0x98, 0xb6, 0x08, 0xe9, 0xf7, 0xc8, 0x05, 0x85, + 0x8a, 0x85, 0x8a, 0x7b, 0x88, 0x41, 0x7e, 0x50, 0x83, 0x5b, 0x89, 0x08, + 0x70, 0x07, 0xb9, 0x88, 0x95, 0x86, 0x8b, 0x77, 0x8b, 0x7b, 0x86, 0x6f, + 0x82, 0x6e, 0x08, 0x63, 0xfb, 0x19, 0x05, 0x7d, 0x5b, 0x84, 0x67, 0x8b, + 0x73, 0x8b, 0x5a, 0xa5, 0x72, 0xbc, 0x8b, 0xce, 0x8b, 0xa9, 0xa5, 0xf2, + 0xf7, 0x24, 0x79, 0x54, 0x85, 0x70, 0x8b, 0x6f, 0x8b, 0x63, 0xa0, 0x77, + 0xb7, 0x8b, 0xc7, 0x8b, 0xbc, 0xb3, 0xbf, 0xe4, 0x08, 0x76, 0x98, 0x05, + 0x0e, 0xfb, 0x5b, 0x9b, 0xf8, 0x2b, 0x15, 0xaa, 0x8b, 0x94, 0x88, 0x91, + 0x7e, 0x9c, 0x6b, 0x96, 0x33, 0x8b, 0x20, 0x8b, 0x87, 0x8b, 0x7b, 0x8a, + 0x76, 0x08, 0x87, 0xfb, 0x1c, 0xa5, 0x8b, 0x05, 0xf7, 0x13, 0xf7, 0x0d, + 0xba, 0xc0, 0xc2, 0xdb, 0xb3, 0xc5, 0xa0, 0xc1, 0x8b, 0xb5, 0x08, 0xae, + 0x6d, 0xab, 0x6c, 0x6e, 0x70, 0x6f, 0x6d, 0x1e, 0x8b, 0x7a, 0x92, 0x7d, + 0x9c, 0x77, 0x9a, 0x7a, 0x90, 0x81, 0x8b, 0x81, 0x8b, 0x68, 0x70, 0x62, + 0x28, 0xfb, 0x04, 0x87, 0xf7, 0x58, 0x85, 0xc5, 0x76, 0xdb, 0x5a, 0x7f, + 0x74, 0x87, 0x38, 0x7f, 0x08, 0x70, 0x07, 0x0e, 0xa3, 0x9b, 0xf8, 0x2b, + 0x15, 0xa4, 0x8b, 0x94, 0x8a, 0x93, 0x84, 0x9f, 0x79, 0x99, 0x2e, 0x8e, + 0xfb, 0x1e, 0x08, 0x8d, 0x3d, 0x05, 0x8b, 0x87, 0x8b, 0x8a, 0x8a, 0x68, + 0x08, 0x8a, 0x5e, 0xa6, 0x8b, 0xc4, 0xe1, 0x05, 0x91, 0x93, 0xb7, 0xd8, + 0xb7, 0xda, 0x08, 0x9e, 0xae, 0xa2, 0xfb, 0xb1, 0xa6, 0x8b, 0x05, 0xf7, + 0x4d, 0xf7, 0x58, 0xe2, 0xf7, 0x19, 0x8b, 0xdf, 0x08, 0xac, 0x6e, 0xa8, + 0x6b, 0x6d, 0x71, 0x6f, 0x6b, 0x1e, 0x8b, 0x7d, 0x91, 0x7d, 0x9a, 0x76, + 0x99, 0x78, 0x91, 0x7e, 0x8b, 0x81, 0x8b, 0x6d, 0x6d, 0x5d, 0x32, 0x22, + 0x08, 0x6b, 0xf7, 0xe0, 0x70, 0x8b, 0xfb, 0x30, 0xfb, 0xa7, 0x05, 0x88, + 0xf7, 0x11, 0x84, 0xcb, 0x74, 0xe1, 0x62, 0x82, 0x6c, 0x86, 0x38, 0x7d, + 0x08, 0x70, 0x07, 0x0e, 0xf8, 0x24, 0xf7, 0x0f, 0x15, 0x64, 0x59, 0x81, + 0x82, 0x79, 0x8b, 0x78, 0x8b, 0x81, 0x9a, 0x83, 0xb1, 0x08, 0x6b, 0xf7, + 0x30, 0x05, 0x8e, 0x8f, 0x8c, 0x8c, 0x90, 0x93, 0xae, 0xc5, 0xa4, 0xa3, + 0xa2, 0x8b, 0x91, 0x8b, 0x92, 0x88, 0x97, 0x85, 0x99, 0x82, 0x92, 0x89, + 0x96, 0x8b, 0x08, 0xa9, 0xa5, 0xa3, 0xa7, 0xac, 0x6f, 0xa8, 0x6d, 0x1f, + 0x5c, 0x8b, 0x6c, 0x70, 0x3b, 0xfb, 0x03, 0x79, 0xe0, 0x83, 0xa4, 0x78, + 0xa7, 0x08, 0xfb, 0x3b, 0x73, 0x8b, 0x70, 0x05, 0xa0, 0x8d, 0x90, 0x8b, + 0x94, 0x8b, 0xab, 0x8b, 0x99, 0x79, 0x95, 0x5a, 0x08, 0xa9, 0xfb, 0x2e, + 0x5f, 0x45, 0x05, 0x77, 0x6b, 0x80, 0x82, 0x7a, 0x8b, 0x85, 0x8b, 0x86, + 0x8d, 0x81, 0x91, 0x7b, 0x94, 0x7f, 0x8f, 0x7f, 0x8b, 0x08, 0x6c, 0x73, + 0x72, 0x6c, 0x68, 0xa5, 0x73, 0xb1, 0x1f, 0xbd, 0x8b, 0xa2, 0x9f, 0xc5, + 0xeb, 0x08, 0xa3, 0xb2, 0x05, 0x9a, 0x40, 0x93, 0x71, 0xa1, 0x6f, 0x97, + 0x7b, 0x9f, 0x81, 0x9f, 0x8b, 0xbb, 0x8b, 0xb5, 0xad, 0xc8, 0xe3, 0x08, + 0x76, 0x99, 0x05, 0x0e, 0xfb, 0x5b, 0x99, 0xf8, 0x2f, 0x15, 0x9d, 0x8b, + 0x90, 0x8a, 0x92, 0x87, 0x9c, 0x81, 0x9b, 0x62, 0x9a, 0x44, 0xac, 0xfb, + 0x34, 0x9c, 0x2a, 0x8b, 0x6c, 0x8b, 0x74, 0x82, 0x73, 0x79, 0x72, 0x76, + 0x6f, 0x70, 0x76, 0x7a, 0x8b, 0x84, 0x8b, 0x78, 0x92, 0x83, 0x92, 0x08, + 0x7a, 0x97, 0x72, 0x94, 0x79, 0x8b, 0x08, 0x71, 0x73, 0x71, 0x6e, 0x6a, + 0xa6, 0x70, 0xae, 0x1f, 0xc2, 0x8b, 0xcc, 0xb3, 0xc2, 0xcd, 0xf7, 0x16, + 0xf7, 0x33, 0xf7, 0x0b, 0xf7, 0x81, 0x8b, 0xf0, 0x08, 0xad, 0x6e, 0xa9, + 0x6a, 0x6d, 0x70, 0x70, 0x6c, 0x1e, 0x8b, 0x73, 0x92, 0x7f, 0xa3, 0x79, + 0x9d, 0x7d, 0x91, 0x83, 0x8b, 0x7e, 0x8b, 0x6d, 0x79, 0x61, 0x46, 0xfb, + 0x19, 0x08, 0x7f, 0xd6, 0x05, 0x75, 0xf7, 0x0a, 0x71, 0xf7, 0x04, 0x79, + 0xba, 0x5b, 0x7f, 0x67, 0x85, 0x4a, 0x85, 0x08, 0x70, 0x07, 0x0e, 0xfb, + 0x92, 0x98, 0xf7, 0xbb, 0x15, 0xa7, 0x88, 0x05, 0x9c, 0xb9, 0x9b, 0x9a, + 0xa9, 0x8b, 0x08, 0xf7, 0x25, 0x8b, 0xfb, 0xb8, 0xfb, 0xf6, 0xa4, 0x75, + 0x05, 0x93, 0x91, 0x93, 0x90, 0x8e, 0x8e, 0x9a, 0x96, 0x92, 0x8e, 0x96, + 0x8b, 0x9d, 0x8b, 0x9f, 0x82, 0xae, 0x73, 0xc1, 0x67, 0xb0, 0x7d, 0xb3, + 0x8b, 0x08, 0xc8, 0xba, 0xb3, 0xbe, 0xa7, 0x72, 0xa3, 0x6f, 0x70, 0x74, + 0x73, 0x6f, 0x1f, 0x8b, 0x80, 0x8f, 0x83, 0x94, 0x7f, 0x90, 0x84, 0x8d, + 0x86, 0x8b, 0x88, 0x8b, 0x82, 0x81, 0x84, 0x7f, 0x8b, 0x79, 0x8b, 0x7f, + 0x97, 0x7a, 0xae, 0x6b, 0xc8, 0x73, 0xa2, 0x58, 0xa1, 0x08, 0xf7, 0xad, + 0xf7, 0xe3, 0x8b, 0x95, 0xfb, 0xcc, 0x8b, 0x60, 0xfb, 0x2e, 0x05, 0x0e, + 0xfb, 0xbb, 0xf8, 0x48, 0xf9, 0x42, 0x15, 0xfb, 0x33, 0x8b, 0x51, 0x6a, + 0x6c, 0xfb, 0x01, 0x08, 0x5d, 0xfb, 0x47, 0x05, 0x77, 0x43, 0x6f, 0x72, + 0x32, 0x78, 0xc9, 0x7b, 0xa1, 0x78, 0x8b, 0x68, 0x8b, 0x73, 0x81, 0x5f, + 0x7b, 0x5b, 0x08, 0x78, 0x54, 0x7b, 0x40, 0x8b, 0x6e, 0x8b, 0x71, 0x93, + 0x78, 0x9c, 0x7c, 0xa4, 0x76, 0xb2, 0x83, 0xe8, 0x89, 0x08, 0x8e, 0x97, + 0x05, 0x50, 0x96, 0x75, 0xa0, 0x8b, 0xb9, 0x8b, 0xa5, 0x96, 0xbe, 0x9e, + 0xca, 0x08, 0x9e, 0xc7, 0x95, 0xba, 0x8b, 0xa2, 0x8b, 0xb5, 0x7a, 0x99, + 0x40, 0x9f, 0xed, 0x9e, 0xa9, 0xa5, 0xa2, 0xe0, 0x08, 0xb8, 0xf7, 0x3f, + 0x05, 0x9f, 0xd7, 0xb0, 0xac, 0xdc, 0x9a, 0x08, 0x8e, 0x97, 0x05, 0x0e, + 0xfc, 0x3b, 0xcd, 0x79, 0x15, 0xe3, 0xf9, 0x53, 0x33, 0xfd, 0x53, 0x06, + 0x0e, 0xfb, 0xbb, 0xfb, 0x15, 0xfb, 0x4f, 0x15, 0xf7, 0x33, 0x8b, 0xc5, + 0xac, 0xaa, 0xf7, 0x01, 0x08, 0xb9, 0xf7, 0x47, 0x05, 0x9f, 0xd3, 0xa7, + 0xa3, 0xe4, 0x9f, 0x4d, 0x9b, 0x75, 0x9e, 0x8b, 0xae, 0x8b, 0xa3, 0x95, + 0xb7, 0x9b, 0xbb, 0x08, 0x9e, 0xc4, 0x9b, 0xd5, 0x8b, 0xaa, 0x8b, 0xa2, + 0x83, 0x9e, 0x7a, 0x9a, 0x72, 0xa0, 0x64, 0x93, 0x2e, 0x8d, 0x08, 0x88, + 0x7f, 0x05, 0xc4, 0x80, 0xa3, 0x75, 0x8b, 0x5f, 0x8b, 0x72, 0x81, 0x5d, + 0x76, 0x45, 0x08, 0x78, 0x49, 0x82, 0x61, 0x8b, 0x75, 0x8b, 0x61, 0x9c, + 0x7d, 0xd6, 0x77, 0x29, 0x78, 0x6d, 0x71, 0x74, 0x36, 0x08, 0x5e, 0xfb, + 0x3f, 0x05, 0x77, 0x3f, 0x66, 0x6a, 0x3a, 0x7c, 0x08, 0x88, 0x7f, 0x05, + 0x0e, 0x42, 0xf8, 0x61, 0xf7, 0xc8, 0x15, 0x72, 0x6b, 0x77, 0x7e, 0x74, + 0x8b, 0x79, 0x8b, 0x7c, 0x90, 0x5a, 0xa1, 0x08, 0x3d, 0xad, 0x76, 0x92, + 0x66, 0x8b, 0x59, 0x8b, 0x65, 0x71, 0x6a, 0x51, 0x08, 0xc0, 0x5d, 0x05, + 0xa3, 0xab, 0x9b, 0x95, 0xa8, 0x8b, 0xae, 0x8b, 0xaa, 0x81, 0xb9, 0x72, + 0x08, 0xb9, 0x72, 0xa5, 0x83, 0xac, 0x8b, 0xb9, 0x8b, 0xaa, 0xa1, 0xb9, + 0xca, 0x08, 0x54, 0xbb, 0x05, 0x0e, 0xfb, 0x92, 0xf7, 0x55, 0xf7, 0xa7, + 0x15, 0x61, 0xfb, 0x00, 0x5e, 0x26, 0x53, 0xfb, 0x01, 0x71, 0x5d, 0x86, + 0x7b, 0x8b, 0x71, 0x8b, 0x5e, 0xa7, 0x6e, 0xb4, 0x8b, 0xa9, 0x8b, 0xa4, + 0x9c, 0x99, 0xa8, 0x93, 0x9d, 0x8d, 0x98, 0x8d, 0xb5, 0x8f, 0xd6, 0x9e, + 0xf7, 0x11, 0xa9, 0xf7, 0x2d, 0x08, 0x6e, 0x93, 0x05, 0xc2, 0xf7, 0x6f, + 0x15, 0x62, 0x6a, 0x6c, 0x63, 0x63, 0xae, 0x68, 0xb1, 0xb4, 0xab, 0xac, + 0xb5, 0xb4, 0x6d, 0xa9, 0x61, 0x1f, 0x0e, 0xf8, 0x43, 0xf8, 0xd4, 0x15, + 0x68, 0x8b, 0x62, 0xfb, 0x09, 0x05, 0x7f, 0x8d, 0x84, 0x8c, 0x82, 0x8b, + 0xfb, 0x22, 0x8b, 0xfb, 0x23, 0xfb, 0x37, 0x8b, 0xfb, 0x35, 0x8b, 0x31, + 0xc1, 0x54, 0xe9, 0x85, 0x08, 0x5d, 0xfb, 0x16, 0xad, 0x8b, 0xba, 0xf7, + 0x19, 0x05, 0xce, 0x98, 0xb0, 0xa9, 0xca, 0xe5, 0x08, 0x70, 0x9d, 0x05, + 0x62, 0x4f, 0x68, 0x70, 0x61, 0x89, 0x08, 0xe7, 0xf7, 0x99, 0x05, 0x95, + 0x84, 0x96, 0x87, 0x99, 0x8b, 0xb0, 0x8b, 0xa7, 0xa8, 0x8b, 0xb2, 0x8b, + 0xad, 0x7a, 0xa4, 0x67, 0x9f, 0x08, 0xb8, 0xf7, 0x13, 0x05, 0xfb, 0x6d, + 0xfc, 0x9b, 0x15, 0x77, 0x96, 0x84, 0x93, 0x84, 0x9b, 0x84, 0x9b, 0x87, + 0xa1, 0x8b, 0x9c, 0x8b, 0xc4, 0xa5, 0xe4, 0xaf, 0xca, 0xa7, 0xbd, 0xa6, + 0xa2, 0xaa, 0x8b, 0x98, 0x8b, 0x97, 0x83, 0x88, 0x83, 0x08, 0xfb, 0x11, + 0xfb, 0xf8, 0x05, 0x0e, 0xf8, 0x1e, 0xf8, 0x06, 0x15, 0xfb, 0x06, 0x8b, + 0xb2, 0xf7, 0x5e, 0x05, 0x95, 0xbd, 0xa0, 0xa6, 0xa8, 0x8b, 0x99, 0x8b, + 0x95, 0x82, 0x8b, 0x7f, 0x8b, 0x86, 0x8a, 0x84, 0x89, 0x84, 0x89, 0x7f, + 0x89, 0x7f, 0x8b, 0x81, 0x08, 0x6e, 0xa2, 0x75, 0xa9, 0xad, 0xa6, 0xa9, + 0xb1, 0xbf, 0x5d, 0xb2, 0x4c, 0x1e, 0x52, 0x8b, 0x55, 0x70, 0x61, 0x5a, + 0x5a, 0x53, 0x73, 0x52, 0x72, 0xfb, 0x10, 0x08, 0x22, 0x8b, 0x81, 0x4f, + 0xf7, 0x01, 0x8b, 0x05, 0x81, 0x37, 0x89, 0x80, 0x84, 0x48, 0x72, 0x96, + 0x7c, 0x8e, 0x76, 0x8b, 0x08, 0x52, 0x64, 0x68, 0x57, 0x59, 0xb0, 0x67, + 0xc0, 0x1f, 0xb6, 0x8b, 0xa7, 0x9c, 0xa6, 0xb6, 0x08, 0xbf, 0x5e, 0xac, + 0x7b, 0xb5, 0x8b, 0xb5, 0x8b, 0xb3, 0x9f, 0xa4, 0xae, 0xa0, 0xa7, 0x96, + 0xa6, 0x97, 0xc4, 0x08, 0x72, 0x06, 0x75, 0x5a, 0x77, 0x7d, 0x5b, 0x8b, + 0x6b, 0x8b, 0x6a, 0x94, 0x4f, 0xa2, 0x08, 0x96, 0x9c, 0x05, 0xa5, 0xb6, + 0xa4, 0xcf, 0x98, 0xc5, 0x08, 0xf7, 0x07, 0x8b, 0x05, 0x95, 0xc7, 0x05, + 0xfb, 0xad, 0xfb, 0xac, 0x15, 0x80, 0x5a, 0x79, 0x75, 0x6d, 0x8b, 0x08, + 0x6a, 0x74, 0xa0, 0xa9, 0xa9, 0x9f, 0x9f, 0xaa, 0x1f, 0xa1, 0x8b, 0x9f, + 0x82, 0xa1, 0x76, 0x08, 0x0e, 0xfc, 0x70, 0xf7, 0xd8, 0xf9, 0x3f, 0x15, + 0x51, 0x8b, 0xfc, 0x47, 0xfd, 0x4d, 0xc5, 0x8b, 0xf8, 0x47, 0xf9, 0x4d, + 0x05, 0x0e, 0xf8, 0x8c, 0xf7, 0xea, 0x15, 0xfb, 0x1b, 0x8b, 0xf7, 0x3a, + 0xf7, 0x7d, 0x05, 0xad, 0xb9, 0x9e, 0x9a, 0xb3, 0x93, 0x08, 0xa4, 0xfb, + 0x5c, 0x72, 0x07, 0xc3, 0x89, 0x99, 0x82, 0x8b, 0x68, 0x8b, 0x79, 0x85, + 0x7e, 0x77, 0x6e, 0x08, 0xfb, 0x1b, 0xfb, 0x56, 0x3b, 0xf7, 0x80, 0x05, + 0x87, 0x97, 0x89, 0x96, 0x8b, 0x94, 0x8b, 0xa2, 0x9d, 0x92, 0xc4, 0x8d, + 0x08, 0xa4, 0xfb, 0xac, 0x72, 0x07, 0xc2, 0x85, 0x92, 0x85, 0x9f, 0x58, + 0x08, 0xda, 0xfb, 0x83, 0xfb, 0x11, 0x8b, 0x7d, 0x59, 0xf7, 0x22, 0x8b, + 0x75, 0x3d, 0xfb, 0x21, 0x8b, 0x7d, 0x59, 0xf7, 0x21, 0x8b, 0x78, 0x48, + 0x05, 0x79, 0x52, 0x7d, 0x81, 0x3e, 0x86, 0x08, 0x72, 0xf7, 0xd6, 0xa4, + 0x07, 0x48, 0x8e, 0x7d, 0x93, 0x8b, 0xab, 0x8b, 0x9e, 0x8f, 0xa2, 0x97, + 0xb6, 0x08, 0x8e, 0x96, 0xf7, 0x2c, 0x8b, 0x99, 0xbd, 0xfb, 0x2c, 0x8b, + 0xa0, 0xd9, 0xf7, 0x2a, 0x8b, 0x98, 0xbd, 0x05, 0x0e, 0xf8, 0x4f, 0xf8, + 0x4c, 0x15, 0xfb, 0x0a, 0x06, 0xa1, 0xf7, 0x16, 0x94, 0xb1, 0x9d, 0xab, + 0x99, 0xa3, 0x9e, 0x98, 0xa0, 0x8b, 0x99, 0x8b, 0x96, 0x85, 0x8b, 0x82, + 0x8b, 0x87, 0x88, 0x88, 0x85, 0x85, 0x7d, 0x7e, 0x85, 0x80, 0x8b, 0x7b, + 0x08, 0x6d, 0xa0, 0x77, 0xab, 0xaf, 0xa3, 0xa4, 0xaf, 0xbd, 0x5c, 0xb0, + 0x4c, 0x1e, 0xfb, 0x02, 0x8b, 0x34, 0x28, 0x66, 0xfb, 0x3c, 0x08, 0x20, + 0x8b, 0x83, 0x5f, 0xf4, 0x8b, 0x45, 0xfc, 0x00, 0x05, 0x7e, 0x49, 0x74, + 0x4f, 0x77, 0x78, 0x81, 0x81, 0x81, 0x87, 0x7a, 0x8b, 0x7a, 0x8b, 0x83, + 0x8f, 0x8b, 0x94, 0x8b, 0x8f, 0x8e, 0x90, 0x92, 0x93, 0x97, 0x99, 0x91, + 0x98, 0x8b, 0x96, 0x08, 0xa7, 0x74, 0xa1, 0x6d, 0x6a, 0x73, 0x72, 0x68, + 0x57, 0xb7, 0x68, 0xcd, 0x1e, 0xf7, 0x1a, 0x8b, 0xe2, 0xf7, 0x15, 0xba, + 0xf7, 0xa1, 0x08, 0xa6, 0xf7, 0x2e, 0xf7, 0x08, 0x8b, 0x94, 0xb7, 0x05, + 0x0e, 0xf7, 0xb4, 0xf7, 0x11, 0x15, 0x97, 0x88, 0x93, 0x8a, 0x95, 0x8b, + 0xcb, 0x8b, 0xc0, 0xc3, 0x8b, 0xcd, 0x8b, 0xba, 0x75, 0xbe, 0x65, 0xb8, + 0x08, 0x46, 0xdc, 0x05, 0x59, 0xc6, 0x79, 0xab, 0x8b, 0xab, 0x08, 0xb6, + 0xaf, 0xa9, 0xbc, 0xaa, 0xa7, 0x7e, 0x7c, 0x1e, 0x8b, 0x86, 0x87, 0x86, + 0x81, 0x84, 0x7b, 0x7e, 0x85, 0x81, 0x8b, 0x7c, 0x08, 0x6e, 0xa4, 0x72, + 0xa9, 0xac, 0xa4, 0xa5, 0xae, 0xc4, 0x52, 0xb4, 0x3c, 0x30, 0x4b, 0x54, + 0x3c, 0x1e, 0x8b, 0x5f, 0x9f, 0x5d, 0xae, 0x64, 0x08, 0x89, 0x88, 0x05, + 0x7f, 0x8e, 0x72, 0x8e, 0x7f, 0x8b, 0x52, 0x8b, 0x5c, 0x52, 0x8b, 0x46, + 0x8b, 0x60, 0x9b, 0x64, 0xae, 0x61, 0x08, 0xcd, 0x3b, 0x05, 0xd2, 0x35, + 0x97, 0x77, 0x8b, 0x6a, 0x08, 0x5f, 0x67, 0x6b, 0x59, 0x69, 0x6a, 0x99, + 0x9a, 0x1e, 0x8b, 0x90, 0x8e, 0x90, 0x95, 0x93, 0x9b, 0x99, 0x91, 0x96, + 0x8b, 0x9f, 0x08, 0xa8, 0x73, 0xa0, 0x6b, 0x6a, 0x72, 0x72, 0x68, 0x50, + 0xca, 0x5d, 0xdd, 0xe7, 0xd3, 0xc6, 0xd6, 0x1e, 0x8b, 0xb5, 0x7b, 0xad, + 0x60, 0xc1, 0x08, 0x8d, 0x8f, 0x05, 0x2e, 0xf7, 0xa7, 0x15, 0xc5, 0xf7, + 0x03, 0xfb, 0x13, 0x48, 0x6c, 0x6f, 0x70, 0x6c, 0x1f, 0x75, 0x8b, 0x7b, + 0x93, 0x73, 0xa2, 0x74, 0xa0, 0x6f, 0xac, 0x73, 0xac, 0x7a, 0xa4, 0x7f, + 0xa9, 0x8b, 0xa0, 0x08, 0xab, 0xa4, 0xa5, 0xaa, 0x1e, 0x0e, 0x71, 0xe7, + 0x15, 0xc5, 0x51, 0xeb, 0xed, 0x05, 0xb4, 0x71, 0xb0, 0x80, 0xb7, 0x8b, + 0xb7, 0x8b, 0xb0, 0x96, 0xb4, 0xa5, 0x08, 0xeb, 0x29, 0xc5, 0xc5, 0x29, + 0xed, 0x05, 0xa5, 0xaf, 0x96, 0xb0, 0x8b, 0xba, 0x8b, 0xb9, 0x81, 0xac, + 0x70, 0xb6, 0x08, 0xed, 0xed, 0x51, 0xc3, 0x2b, 0x2b, 0x05, 0x63, 0xa4, + 0x67, 0x95, 0x5d, 0x8b, 0x5d, 0x8b, 0x67, 0x81, 0x63, 0x72, 0x08, 0x2b, + 0xeb, 0x51, 0x53, 0xed, 0x29, 0x05, 0x71, 0x64, 0x80, 0x66, 0x8b, 0x5d, + 0x8b, 0x5c, 0x96, 0x68, 0xa5, 0x65, 0x08, 0x29, 0x29, 0x05, 0xf7, 0xa8, + 0xf7, 0xf3, 0x15, 0xd2, 0xc3, 0x4f, 0x40, 0x44, 0x51, 0x4f, 0x46, 0x44, + 0x53, 0xc6, 0xd5, 0xd6, 0xc3, 0xc5, 0xd2, 0x1f, 0x0e, 0xfc, 0x01, 0xf7, + 0x3d, 0xf8, 0x22, 0x15, 0xdd, 0xf7, 0x4e, 0x8d, 0x90, 0x05, 0x99, 0xaa, + 0x8c, 0x8d, 0x8b, 0x99, 0x8b, 0xa6, 0x77, 0xa1, 0x71, 0x8b, 0x65, 0x8b, + 0x66, 0x68, 0x88, 0x65, 0x08, 0x7b, 0xfb, 0x6a, 0xb4, 0x8b, 0x05, 0x0e, + 0xf7, 0x88, 0xf9, 0x41, 0x15, 0xfb, 0x08, 0x58, 0x40, 0x35, 0x8b, 0x3a, + 0x08, 0x50, 0xad, 0x64, 0xbe, 0xb4, 0xa9, 0xaa, 0xb5, 0x1e, 0x8b, 0xa6, + 0x81, 0x9b, 0x6d, 0x9f, 0x74, 0x9a, 0x84, 0x95, 0x8b, 0x9a, 0x8b, 0xae, + 0xb2, 0xb2, 0xda, 0xb5, 0x08, 0x7e, 0xa3, 0x05, 0xf7, 0x94, 0x16, 0xfb, + 0x08, 0x58, 0x40, 0x35, 0x8b, 0x3a, 0x08, 0x50, 0xad, 0x64, 0xbe, 0xb4, + 0xa9, 0xaa, 0xb5, 0x1e, 0x8b, 0xa6, 0x81, 0x9b, 0x6d, 0x9f, 0x74, 0x9a, + 0x84, 0x95, 0x8b, 0x9a, 0x8b, 0xae, 0xb2, 0xb2, 0xda, 0xb5, 0x08, 0x7e, + 0xa3, 0x05, 0x0e, 0xf7, 0x1d, 0xf7, 0x70, 0x15, 0xb8, 0xbc, 0x05, 0xd1, + 0xd3, 0xaa, 0xb4, 0x8b, 0xa0, 0x8b, 0x91, 0x85, 0x91, 0x84, 0x8b, 0x83, + 0x8b, 0x7d, 0x81, 0x78, 0x79, 0x7e, 0x7f, 0x81, 0x83, 0x73, 0x7a, 0x08, + 0xfb, 0x3e, 0xfb, 0x10, 0x8b, 0x82, 0x05, 0xd6, 0x3f, 0xd2, 0x41, 0xa1, + 0x72, 0x92, 0x83, 0x8e, 0x89, 0x90, 0x8b, 0x93, 0x8b, 0x92, 0x92, 0x8b, + 0x93, 0x8b, 0x9a, 0x81, 0xa7, 0x74, 0xba, 0x08, 0x63, 0xde, 0x05, 0xf7, + 0x4d, 0x16, 0xb8, 0xbc, 0x05, 0xd1, 0xd3, 0xaa, 0xb4, 0x8b, 0xa0, 0x8b, + 0x91, 0x85, 0x91, 0x84, 0x8b, 0x83, 0x8b, 0x7d, 0x81, 0x78, 0x79, 0x7e, + 0x7f, 0x81, 0x83, 0x73, 0x7a, 0x08, 0xfb, 0x3e, 0xfb, 0x10, 0x8b, 0x82, + 0x05, 0xd6, 0x3f, 0xd2, 0x41, 0xa1, 0x72, 0x92, 0x83, 0x8e, 0x89, 0x90, + 0x8b, 0x93, 0x8b, 0x92, 0x92, 0x8b, 0x93, 0x8b, 0x9a, 0x81, 0xa7, 0x74, + 0xba, 0x08, 0x63, 0xde, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0x31, 0xf7, 0x70, + 0x15, 0xb8, 0xbc, 0x05, 0xd1, 0xd3, 0xaa, 0xb4, 0x8b, 0xa0, 0x8b, 0x91, + 0x85, 0x91, 0x84, 0x8b, 0x83, 0x8b, 0x7d, 0x81, 0x78, 0x79, 0x7e, 0x7f, + 0x81, 0x83, 0x73, 0x7a, 0x08, 0xfb, 0x3e, 0xfb, 0x10, 0x8b, 0x82, 0x05, + 0xd6, 0x3f, 0xd2, 0x41, 0xa1, 0x72, 0x92, 0x83, 0x8e, 0x89, 0x90, 0x8b, + 0x93, 0x8b, 0x92, 0x92, 0x8b, 0x93, 0x8b, 0x9a, 0x81, 0xa7, 0x74, 0xba, + 0x08, 0x63, 0xde, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0x30, 0xf7, 0x77, 0x15, + 0x5e, 0x5a, 0x05, 0x44, 0x42, 0x6d, 0x63, 0x8b, 0x76, 0x8b, 0x85, 0x91, + 0x85, 0x92, 0x8b, 0x93, 0x8b, 0x99, 0x94, 0x9e, 0x9e, 0x98, 0x96, 0x95, + 0x94, 0xa3, 0x9c, 0x08, 0xf7, 0x3e, 0xf7, 0x10, 0x8b, 0x94, 0x05, 0x33, + 0xe4, 0x62, 0xb5, 0x64, 0xb7, 0x84, 0x93, 0x88, 0x8d, 0x86, 0x8b, 0x83, + 0x8b, 0x84, 0x84, 0x8b, 0x83, 0x8b, 0x7c, 0x95, 0x70, 0xa2, 0x5b, 0x08, + 0xb3, 0x38, 0x05, 0x0e, 0x34, 0x9c, 0xf8, 0x2b, 0x15, 0xd6, 0x8b, 0x2f, + 0xfc, 0x2f, 0x05, 0x6c, 0xfb, 0x21, 0x7c, 0x71, 0x5f, 0x8b, 0x80, 0x8b, + 0x85, 0x8e, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, 0x8e, 0x90, 0x91, 0x94, 0x95, + 0x8e, 0x91, 0x8b, 0x96, 0x08, 0xa7, 0x75, 0xa0, 0x6e, 0x6e, 0x77, 0x75, + 0x6b, 0x5e, 0xb4, 0x6a, 0xc3, 0x1e, 0xbc, 0x8b, 0xbc, 0xa4, 0xac, 0xb5, + 0xaa, 0xb2, 0xac, 0xd0, 0x98, 0xbf, 0x08, 0xe9, 0xf8, 0x15, 0xf7, 0x2a, + 0x8b, 0x46, 0xfb, 0xa1, 0x05, 0x7d, 0x55, 0x89, 0x80, 0x8b, 0x7b, 0x8b, + 0x61, 0xa6, 0x73, 0xb7, 0x8b, 0xc7, 0x8b, 0xb2, 0xaa, 0xcf, 0xf4, 0x08, + 0x75, 0x98, 0x05, 0x64, 0x53, 0x74, 0x74, 0x7c, 0x8b, 0x83, 0x8b, 0x83, + 0x93, 0x8b, 0x93, 0x8b, 0x96, 0x93, 0xae, 0x98, 0xbc, 0x08, 0x8c, 0x8f, + 0xd4, 0xf7, 0xaf, 0x05, 0x76, 0x8a, 0x77, 0x89, 0x85, 0x8b, 0x53, 0x86, + 0x66, 0x89, 0x7c, 0x8b, 0x08, 0xfb, 0x0a, 0x06, 0xac, 0xf7, 0x0b, 0x97, + 0xa9, 0xab, 0xb1, 0x9e, 0xa2, 0xad, 0x99, 0xb0, 0x8b, 0x9c, 0x8b, 0x94, + 0x86, 0x8b, 0x80, 0x8b, 0x87, 0x89, 0x87, 0x86, 0x84, 0x80, 0x7f, 0x87, + 0x80, 0x8b, 0x7e, 0x08, 0x6c, 0xa4, 0x73, 0xac, 0xac, 0xa3, 0xa3, 0xac, + 0xc3, 0x51, 0xb2, 0x37, 0x1e, 0x4b, 0x8b, 0x4d, 0x73, 0x65, 0x62, 0x62, + 0x60, 0x77, 0x64, 0x66, 0x20, 0x08, 0x3f, 0x8b, 0x81, 0x61, 0x05, 0x0e, + 0x34, 0x9f, 0xf8, 0x2b, 0x15, 0xd5, 0x8b, 0x2f, 0xfc, 0x26, 0x05, 0x6a, + 0xfb, 0x23, 0x7c, 0x6b, 0x68, 0x8b, 0x7e, 0x8b, 0x82, 0x90, 0x8b, 0x92, + 0x8b, 0x8e, 0x8d, 0x8f, 0x8f, 0x91, 0x92, 0x96, 0x8e, 0x92, 0x8b, 0x95, + 0x08, 0xa7, 0x78, 0x9d, 0x6f, 0x6b, 0x77, 0x77, 0x6a, 0x5b, 0xb2, 0x6a, + 0xc5, 0x1e, 0xf2, 0x8b, 0xd5, 0xea, 0xb9, 0xf7, 0x53, 0x08, 0xda, 0xf7, + 0xda, 0xf7, 0x27, 0x8b, 0x3c, 0xfb, 0xd5, 0x05, 0x88, 0x7e, 0x89, 0x7e, + 0x8b, 0x80, 0x8b, 0x69, 0xa9, 0x73, 0xb5, 0x8b, 0xc6, 0x8b, 0xb0, 0xa9, + 0xce, 0xf4, 0x08, 0x77, 0x96, 0x05, 0x68, 0x56, 0x74, 0x75, 0x79, 0x8b, + 0x82, 0x8b, 0x83, 0x93, 0x8b, 0x94, 0x8b, 0x8e, 0x8c, 0x8f, 0x8e, 0x98, + 0x08, 0xf7, 0x2b, 0xf8, 0xee, 0x28, 0x7f, 0x7e, 0x8e, 0x05, 0x50, 0x96, + 0x84, 0x8c, 0x75, 0x8b, 0x4d, 0x8b, 0x50, 0x73, 0x68, 0x64, 0x63, 0x60, + 0x78, 0x63, 0x69, 0xfb, 0x01, 0x08, 0x41, 0x8b, 0x81, 0x61, 0x05, 0xf7, + 0xf4, 0xb5, 0x15, 0xfb, 0x2b, 0x06, 0xa0, 0xe5, 0x9a, 0xb5, 0xa0, 0xae, + 0xa3, 0xb1, 0xaa, 0xa0, 0xac, 0x8b, 0x9d, 0x8b, 0x9d, 0x82, 0x8b, 0x81, + 0x8b, 0x8a, 0x8a, 0x88, 0x89, 0x88, 0x7d, 0x76, 0x87, 0x83, 0x8b, 0x7e, + 0x8b, 0x7b, 0x92, 0x7f, 0x99, 0x80, 0x08, 0x6d, 0xfb, 0x0b, 0x05, 0x0e, + 0xf8, 0x71, 0xf7, 0xa1, 0x15, 0xfc, 0x88, 0x8b, 0x7a, 0x30, 0xf8, 0x88, + 0x8b, 0x9c, 0xe6, 0x05, 0x0e, 0xf7, 0x47, 0xfb, 0x25, 0x15, 0x9b, 0xc4, + 0x8f, 0x98, 0x9a, 0xca, 0xad, 0xf7, 0x20, 0xaf, 0xe7, 0xb2, 0xbc, 0x78, + 0xbb, 0x84, 0xac, 0x8b, 0xb0, 0x8b, 0x9d, 0x8d, 0x9a, 0x8f, 0xa2, 0xae, + 0x8c, 0x98, 0x87, 0xb2, 0x76, 0xa1, 0x7e, 0x97, 0x87, 0x97, 0x8b, 0x08, + 0xad, 0xa3, 0xa1, 0xa9, 0xaa, 0x76, 0xa0, 0x6a, 0x1f, 0x7d, 0x8b, 0x80, + 0x88, 0x72, 0x7e, 0x66, 0x79, 0x7d, 0x87, 0x6c, 0x8a, 0x93, 0xb0, 0x92, + 0x9e, 0x99, 0x9d, 0x08, 0x9a, 0x9e, 0x05, 0xa2, 0xa8, 0x94, 0xa0, 0x8b, + 0xa0, 0x08, 0xaa, 0x73, 0xa2, 0x6b, 0x68, 0x76, 0x74, 0x65, 0x1e, 0x8b, + 0x7c, 0x8e, 0x7b, 0x92, 0x70, 0x92, 0x74, 0x8d, 0x7f, 0x8b, 0x81, 0x8b, + 0x7a, 0x89, 0x7c, 0x84, 0x75, 0x6b, 0x8b, 0x7f, 0x8e, 0x64, 0x9e, 0x70, + 0x98, 0x7e, 0x8f, 0x7b, 0x8b, 0x08, 0x6b, 0x77, 0x77, 0x6c, 0x6c, 0x9f, + 0x77, 0xaa, 0x1f, 0x9f, 0x8b, 0x98, 0x8f, 0xa7, 0x9a, 0xae, 0x9d, 0x90, + 0x8c, 0xae, 0x8c, 0x82, 0x4e, 0x69, 0x4a, 0x5f, 0x64, 0x90, 0x67, 0x8c, + 0x78, 0x8b, 0x74, 0x8b, 0x5c, 0x85, 0x37, 0x84, 0x62, 0x08, 0x6f, 0xfb, + 0x41, 0xa2, 0x8b, 0x05, 0x0e, 0xf7, 0xd1, 0xf7, 0xa5, 0x15, 0x77, 0xae, + 0x87, 0x9d, 0x8b, 0xbf, 0x8b, 0xac, 0x8c, 0x99, 0x91, 0xa2, 0xb1, 0x88, + 0x94, 0x88, 0xb5, 0x78, 0xa4, 0x80, 0x99, 0x86, 0x97, 0x8b, 0x08, 0xa8, + 0xa3, 0xa2, 0xa8, 0xa5, 0x75, 0xa0, 0x6f, 0x1f, 0x80, 0x8b, 0x7e, 0x87, + 0x74, 0x82, 0x61, 0x7b, 0x80, 0x88, 0x63, 0x87, 0x9a, 0xbc, 0x90, 0x96, + 0xa9, 0xb5, 0xa0, 0xa8, 0x92, 0x9b, 0x8b, 0x9b, 0x08, 0xa9, 0x74, 0xa1, + 0x6c, 0x69, 0x77, 0x75, 0x66, 0x1e, 0x8b, 0x81, 0x8d, 0x80, 0x8f, 0x76, + 0x91, 0x71, 0x8d, 0x7f, 0x8b, 0x77, 0x8b, 0x76, 0x8a, 0x7e, 0x86, 0x76, + 0x68, 0x8a, 0x7e, 0x8f, 0x62, 0x9d, 0x73, 0x97, 0x7e, 0x8f, 0x7e, 0x8b, + 0x6c, 0x8b, 0x76, 0x77, 0x8b, 0x6e, 0x08, 0x8b, 0x6e, 0x9e, 0x79, 0xac, + 0x89, 0x9b, 0x8b, 0x90, 0x8d, 0xa5, 0x98, 0xb0, 0x9d, 0x9e, 0x90, 0xab, + 0x8c, 0x73, 0x2b, 0x7a, 0x69, 0x59, 0x5d, 0x9f, 0x68, 0x8f, 0x78, 0x8b, + 0x59, 0x8b, 0x6a, 0x8a, 0x7d, 0x85, 0x73, 0x08, 0x65, 0x8e, 0x82, 0x8d, + 0x61, 0x9f, 0x72, 0x96, 0x7c, 0x90, 0x7f, 0x8b, 0x08, 0x6f, 0x73, 0x73, + 0x6f, 0x70, 0xa1, 0x77, 0xa7, 0x1f, 0x96, 0x8b, 0x98, 0x8f, 0xa2, 0x94, + 0xb5, 0x9b, 0x96, 0x8e, 0xb3, 0x8f, 0x7c, 0x5a, 0x85, 0x80, 0x6e, 0x61, + 0x76, 0x6e, 0x84, 0x7b, 0x8b, 0x7a, 0x08, 0x6e, 0xa2, 0x75, 0xaa, 0xad, + 0x9f, 0xa1, 0xb0, 0x1e, 0x8b, 0x95, 0x89, 0x96, 0x87, 0xa0, 0x84, 0xa5, + 0x8a, 0x97, 0x8b, 0x9f, 0x8b, 0xa1, 0x8c, 0x97, 0x90, 0xa0, 0xae, 0x8c, + 0x98, 0x87, 0xb4, 0x79, 0xa3, 0x7f, 0x97, 0x87, 0x98, 0x8b, 0xab, 0x8b, + 0xa0, 0x9f, 0x8b, 0xa8, 0x08, 0x8b, 0xa8, 0x78, 0x9d, 0x6a, 0x8d, 0x7b, + 0x8b, 0x86, 0x89, 0x71, 0x7e, 0x65, 0x78, 0x79, 0x86, 0x6b, 0x8b, 0xa3, + 0xeb, 0x9c, 0xad, 0xbd, 0xb9, 0x08, 0x0e, 0xfc, 0x1d, 0xf7, 0x12, 0xf8, + 0x29, 0x15, 0x61, 0x6a, 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, 0xb5, 0xac, + 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, 0x0e, 0xf7, 0xde, 0xf9, 0x18, + 0x15, 0xc2, 0x8b, 0xfb, 0x6d, 0xfd, 0xd9, 0xf7, 0x3f, 0x8b, 0x92, 0xa4, + 0x05, 0x81, 0x8c, 0x81, 0x8c, 0x88, 0x8b, 0x66, 0x8f, 0x7d, 0x92, 0x8c, + 0x99, 0x93, 0xb3, 0x8f, 0x9c, 0x8f, 0x9b, 0x08, 0xf7, 0x3d, 0xf9, 0x1d, + 0x05, 0x99, 0xc1, 0x8e, 0x8d, 0xdc, 0x92, 0x08, 0x91, 0xa4, 0xfb, 0xbb, + 0x8b, 0x05, 0x32, 0x8b, 0x4a, 0x75, 0x62, 0x5f, 0x60, 0x5d, 0x6a, 0x2e, + 0x8b, 0x3f, 0x8b, 0x5e, 0x9c, 0x64, 0xa9, 0x76, 0xa4, 0x7a, 0xa2, 0x85, + 0xbd, 0x89, 0x08, 0x36, 0xfb, 0xda, 0x05, 0x7b, 0x4d, 0x86, 0x7d, 0x83, + 0x85, 0x80, 0x81, 0x7a, 0x87, 0x5a, 0x87, 0x08, 0x84, 0x72, 0xf7, 0x3e, + 0x8b, 0xf7, 0x6d, 0xf9, 0xd9, 0x05, 0xfb, 0x4b, 0xfb, 0xfd, 0x15, 0x5d, + 0x9e, 0x71, 0xb3, 0x8b, 0xbf, 0x8b, 0xc1, 0x9f, 0xd1, 0xa7, 0xb9, 0xa8, + 0xba, 0xa5, 0x9c, 0xca, 0x9b, 0x08, 0x2d, 0xfb, 0xfd, 0x05, 0x0e, 0xfb, + 0xb9, 0xf7, 0x44, 0xf8, 0xa1, 0x15, 0x28, 0x3e, 0x3e, 0x29, 0x2a, 0xd8, + 0x3d, 0xed, 0xea, 0xdb, 0xd9, 0xe9, 0xee, 0x3e, 0xda, 0x2a, 0x1f, 0x0e, + 0xfb, 0xca, 0x93, 0xfb, 0x4a, 0x15, 0xf7, 0x08, 0xbe, 0xd6, 0xe1, 0x8b, + 0xdc, 0x08, 0xc6, 0x69, 0xb2, 0x58, 0x62, 0x6d, 0x6c, 0x61, 0x1e, 0x8b, + 0x70, 0x95, 0x7b, 0xa9, 0x77, 0xa2, 0x7c, 0x92, 0x81, 0x8b, 0x7d, 0x8b, + 0x67, 0x64, 0x64, 0x3c, 0x61, 0x08, 0x98, 0x73, 0x05, 0x0e, 0xf7, 0x68, + 0xfb, 0x4a, 0x15, 0xf7, 0x08, 0xbe, 0xd6, 0xe1, 0x8b, 0xdc, 0x08, 0xc6, + 0x69, 0xb2, 0x58, 0x62, 0x6d, 0x6c, 0x61, 0x1e, 0x8b, 0x70, 0x95, 0x7b, + 0xa9, 0x77, 0xa2, 0x7c, 0x92, 0x81, 0x8b, 0x7d, 0x8b, 0x67, 0x64, 0x64, + 0x3c, 0x61, 0x08, 0x98, 0x73, 0x05, 0xfb, 0x94, 0x16, 0xf7, 0x07, 0xbe, + 0xd7, 0xe1, 0x8b, 0xdc, 0x08, 0xc6, 0x69, 0xb2, 0x58, 0x62, 0x6d, 0x6c, + 0x61, 0x1e, 0x8b, 0x70, 0x95, 0x7b, 0xa9, 0x77, 0xa2, 0x7c, 0x92, 0x81, + 0x8b, 0x7d, 0x8b, 0x67, 0x63, 0x64, 0x3d, 0x61, 0x08, 0x98, 0x73, 0x05, + 0x0e, 0xf7, 0xd6, 0xf8, 0x05, 0x15, 0xf7, 0x07, 0xbd, 0xd7, 0xe2, 0x8b, + 0xdc, 0x08, 0xc6, 0x69, 0xb2, 0x58, 0x62, 0x6d, 0x6c, 0x61, 0x1e, 0x8b, + 0x70, 0x95, 0x7b, 0xa9, 0x76, 0xa2, 0x7c, 0x92, 0x82, 0x8b, 0x7d, 0x8b, + 0x67, 0x63, 0x64, 0x3d, 0x61, 0x08, 0x98, 0x73, 0x05, 0xfb, 0x94, 0x16, + 0xf7, 0x07, 0xbd, 0xd7, 0xe2, 0x8b, 0xdc, 0x08, 0xc6, 0x69, 0xb2, 0x58, + 0x62, 0x6d, 0x6c, 0x61, 0x1e, 0x8b, 0x70, 0x95, 0x7b, 0xa9, 0x76, 0xa2, + 0x7c, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x67, 0x63, 0x64, 0x3d, 0x61, 0x08, + 0x98, 0x73, 0x05, 0x0e, 0xf7, 0xeb, 0xf7, 0x77, 0x15, 0x5e, 0x5a, 0x05, + 0x44, 0x42, 0x6d, 0x63, 0x8b, 0x76, 0x8b, 0x85, 0x91, 0x85, 0x92, 0x8b, + 0x93, 0x8b, 0x99, 0x94, 0x9e, 0x9e, 0x98, 0x96, 0x95, 0x94, 0xa3, 0x9c, + 0x08, 0xf7, 0x3e, 0xf7, 0x10, 0x8b, 0x94, 0x05, 0x33, 0xe4, 0x62, 0xb5, + 0x64, 0xb7, 0x84, 0x93, 0x88, 0x8d, 0x86, 0x8b, 0x83, 0x8b, 0x84, 0x84, + 0x8b, 0x83, 0x8b, 0x7c, 0x95, 0x70, 0xa2, 0x5b, 0x08, 0xb3, 0x38, 0x05, + 0xfb, 0x4d, 0x16, 0x5e, 0x5a, 0x05, 0x44, 0x42, 0x6d, 0x63, 0x8b, 0x76, + 0x8b, 0x85, 0x91, 0x85, 0x92, 0x8b, 0x93, 0x8b, 0x99, 0x94, 0x9e, 0x9e, + 0x98, 0x96, 0x95, 0x94, 0xa3, 0x9c, 0x08, 0xf7, 0x3e, 0xf7, 0x10, 0x8b, + 0x94, 0x05, 0x33, 0xe4, 0x62, 0xb5, 0x64, 0xb7, 0x84, 0x93, 0x88, 0x8d, + 0x86, 0x8b, 0x83, 0x8b, 0x84, 0x84, 0x8b, 0x83, 0x8b, 0x7c, 0x95, 0x70, + 0xa2, 0x5b, 0x08, 0xb3, 0x38, 0x05, 0x0e, 0xf7, 0xf9, 0xf7, 0x07, 0xf7, + 0x1b, 0x15, 0x61, 0x6a, 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, 0xb5, 0xac, + 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, 0xf7, 0xe0, 0x16, 0x61, 0x6a, + 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, 0xb3, 0x6a, + 0xad, 0x63, 0x1f, 0xf7, 0xe0, 0x16, 0x61, 0x6a, 0x6b, 0x61, 0x61, 0xab, + 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, 0x0e, + 0xf7, 0xf9, 0xe1, 0x6e, 0x15, 0xbb, 0x8b, 0xf8, 0x4a, 0xf9, 0x73, 0x5b, + 0x8b, 0x05, 0x58, 0x4b, 0x5a, 0x70, 0x49, 0x8b, 0x67, 0x8b, 0x78, 0x92, + 0x6f, 0xa2, 0x71, 0xa0, 0x78, 0x93, 0x71, 0x8b, 0x08, 0x21, 0x30, 0x27, + 0xfb, 0x08, 0x3c, 0xc0, 0x52, 0xd3, 0x1f, 0xb0, 0x8b, 0xb0, 0x9b, 0xa7, + 0xa7, 0xb4, 0xb4, 0xa8, 0xd9, 0x8b, 0xd0, 0x8b, 0x97, 0x8a, 0x96, 0x89, + 0x9f, 0xa4, 0x81, 0x98, 0x88, 0xa1, 0x8b, 0xb3, 0x8b, 0xac, 0x97, 0xb3, + 0xa9, 0x08, 0xfc, 0x18, 0xfd, 0x23, 0x05, 0xf7, 0x0c, 0xf9, 0x2b, 0x15, + 0x91, 0x8b, 0x90, 0x88, 0x98, 0x82, 0x97, 0x83, 0x8e, 0x89, 0x96, 0x88, + 0x95, 0x88, 0x8f, 0x89, 0x8c, 0x88, 0x8e, 0x84, 0x8f, 0x71, 0x8b, 0x7e, + 0x08, 0x25, 0x4d, 0x26, 0x4c, 0x6a, 0x7a, 0xa3, 0xb7, 0x1e, 0x8b, 0xe4, + 0xc9, 0xf7, 0x14, 0xb4, 0x88, 0x08, 0xf7, 0xd8, 0xfb, 0xc1, 0x15, 0x24, + 0x2e, 0x27, 0xfb, 0x01, 0x35, 0xbd, 0x53, 0xd9, 0x1f, 0xb1, 0x8b, 0xaf, + 0x9a, 0xa4, 0xa6, 0xb8, 0xbb, 0xa7, 0xd3, 0x8b, 0xd1, 0x08, 0xd5, 0x64, + 0xb8, 0x4a, 0x1e, 0x9f, 0x6a, 0x15, 0xad, 0xa4, 0x68, 0x5d, 0x1f, 0x8b, + 0x58, 0x76, 0x48, 0x6e, 0x61, 0x74, 0x6a, 0x72, 0x7b, 0x6e, 0x8b, 0x6a, + 0x8b, 0x7b, 0xa1, 0x8b, 0xb9, 0x8b, 0xbf, 0xa5, 0xdd, 0xab, 0xb9, 0x9f, + 0xa8, 0x9e, 0x98, 0x9f, 0x8b, 0x08, 0xf7, 0xe9, 0xac, 0x15, 0x25, 0x2e, + 0x27, 0xfb, 0x01, 0x35, 0xbd, 0x53, 0xd8, 0x1f, 0xb2, 0x8b, 0xae, 0x9a, + 0xa5, 0xa6, 0xb8, 0xba, 0xa7, 0xd4, 0x8b, 0xd1, 0x08, 0xd5, 0x64, 0xb8, + 0x49, 0x1e, 0xa0, 0x6a, 0x15, 0xad, 0xa4, 0x68, 0x5d, 0x1f, 0x8b, 0x58, + 0x76, 0x48, 0x6e, 0x61, 0x74, 0x6a, 0x72, 0x7b, 0x6e, 0x8b, 0x6a, 0x8b, + 0x7b, 0xa1, 0x8b, 0xb9, 0x8b, 0xbf, 0xa5, 0xdd, 0xab, 0xb9, 0x9e, 0xa7, + 0x9f, 0x99, 0x9f, 0x8b, 0x08, 0x0e, 0xf7, 0xc4, 0xf7, 0xa3, 0x15, 0x6f, + 0x45, 0x7b, 0x74, 0x65, 0x72, 0x08, 0x49, 0x60, 0x05, 0x32, 0x51, 0x66, + 0x59, 0x8b, 0x4d, 0x08, 0x34, 0xd2, 0x51, 0xf4, 0xf0, 0xd5, 0xc1, 0xd6, + 0xb1, 0x70, 0xa8, 0x69, 0x69, 0x70, 0x70, 0x6a, 0x1e, 0x8b, 0x7d, 0x90, + 0x7d, 0x98, 0x7b, 0x93, 0x80, 0x8e, 0x85, 0x8b, 0x85, 0x08, 0x78, 0x6d, + 0x78, 0x6b, 0x61, 0x70, 0xaa, 0xbc, 0x1e, 0x8b, 0xba, 0x9f, 0xb9, 0xb7, + 0xc2, 0x08, 0xb4, 0xbe, 0x05, 0xb9, 0xc5, 0x9f, 0xb9, 0x90, 0xc2, 0x08, + 0x6e, 0x92, 0x05, 0xb7, 0xf7, 0x71, 0x15, 0x61, 0x6a, 0x6b, 0x61, 0x61, + 0xab, 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, + 0x0e, 0xfb, 0xca, 0xf7, 0xbd, 0xf8, 0x98, 0x15, 0xfb, 0x03, 0xf7, 0x27, + 0x05, 0x7b, 0xa0, 0x76, 0x98, 0x78, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, + 0x73, 0x8b, 0x7c, 0x97, 0x7a, 0xa1, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, + 0x8b, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0x50, 0xf8, 0x98, 0x15, 0xf7, 0x2c, + 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, + 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, + 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xfb, 0xca, 0xf7, 0xd0, 0xf8, 0x98, 0x15, + 0xbe, 0x8b, 0x35, 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, 0x42, 0xc4, + 0x8b, 0xf7, 0x17, 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xfb, 0xca, 0xf8, 0x02, + 0xf9, 0x23, 0x15, 0x7c, 0x6c, 0x7e, 0x80, 0x74, 0x8b, 0x80, 0x8b, 0x7a, + 0x90, 0x71, 0x96, 0x08, 0x62, 0x9d, 0x6b, 0x93, 0x73, 0x8b, 0x52, 0x8b, + 0x5d, 0x5d, 0x7e, 0x43, 0x08, 0xb3, 0x06, 0x98, 0xab, 0x98, 0x96, 0xa1, + 0x8b, 0x96, 0x8b, 0x99, 0x88, 0x98, 0x86, 0x08, 0xc6, 0x74, 0x05, 0xa5, + 0x81, 0x97, 0x88, 0x9e, 0x8b, 0xc7, 0x8b, 0xae, 0xaf, 0xa1, 0xde, 0x08, + 0x62, 0x06, 0x0e, 0xfb, 0xca, 0xf8, 0x1d, 0xf9, 0x03, 0x15, 0xfb, 0xd9, + 0x8b, 0x7a, 0x45, 0xf7, 0xda, 0x8b, 0x9b, 0xd1, 0x05, 0x0e, 0xfb, 0xca, + 0xf7, 0xf0, 0xf9, 0x3a, 0x15, 0x6c, 0x49, 0x67, 0x73, 0x4a, 0x8b, 0x4c, + 0x8b, 0x6a, 0xa8, 0x85, 0xc8, 0x08, 0x60, 0x7e, 0x06, 0x26, 0xb7, 0x5b, + 0xe8, 0x1e, 0xec, 0x8b, 0xcb, 0xc5, 0x9d, 0xf3, 0x08, 0x64, 0x06, 0x0e, + 0xfb, 0xca, 0xf7, 0x77, 0xf9, 0x23, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, + 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, + 0x0e, 0xfb, 0xca, 0xf7, 0x0b, 0xf9, 0x23, 0x15, 0x68, 0x6e, 0x6d, 0x67, + 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, + 0x1f, 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, + 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xfb, 0xca, + 0xf7, 0x7e, 0xf9, 0x86, 0x15, 0x51, 0x5a, 0x5b, 0x52, 0x4f, 0xba, 0x5a, + 0xc6, 0xc6, 0xbb, 0xbb, 0xc6, 0xc6, 0x5b, 0xbb, 0x51, 0x1f, 0x89, 0x5b, + 0x15, 0xac, 0xa6, 0x70, 0x6a, 0x6b, 0x70, 0x71, 0x6a, 0x6c, 0x71, 0xa6, + 0xab, 0xaa, 0xa6, 0xa7, 0xa9, 0x1f, 0x0e, 0xfb, 0xca, 0x72, 0x2f, 0x15, + 0x98, 0x7f, 0x05, 0x97, 0x8e, 0x93, 0x8c, 0x95, 0x8b, 0x08, 0xa8, 0x9d, + 0x7d, 0x75, 0x72, 0x75, 0x7b, 0x69, 0x1f, 0x75, 0x8b, 0x7a, 0x8f, 0x6f, + 0x98, 0x08, 0x75, 0x6a, 0x05, 0xb7, 0x79, 0xab, 0x84, 0xaf, 0x8b, 0x08, + 0xd2, 0xc0, 0xb0, 0xbd, 0xb5, 0x65, 0xa9, 0x57, 0x1f, 0x81, 0x8b, 0x85, + 0x8a, 0x81, 0x89, 0x08, 0xb8, 0xce, 0x5f, 0x8b, 0x49, 0x2a, 0x05, 0x0e, + 0xfb, 0xca, 0xf7, 0x0a, 0xf8, 0x98, 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, + 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, + 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, + 0x05, 0xf7, 0x51, 0x16, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, + 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, + 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xfb, + 0xca, 0xa7, 0xab, 0x15, 0x87, 0x85, 0x89, 0x89, 0x83, 0x81, 0x62, 0x59, + 0x7e, 0x70, 0x8b, 0x6e, 0x8b, 0x5c, 0xb8, 0x69, 0xc8, 0x8b, 0xbd, 0x8b, + 0xbb, 0xa8, 0xa4, 0xb9, 0x08, 0x75, 0x99, 0x05, 0x86, 0x89, 0x8a, 0x8a, + 0x83, 0x87, 0x77, 0x81, 0x80, 0x88, 0x7c, 0x8b, 0x62, 0x8b, 0x75, 0xa2, + 0x8b, 0xb4, 0x8b, 0x98, 0x8f, 0x9e, 0x93, 0xab, 0x8e, 0x95, 0x8c, 0x8e, + 0x8c, 0x92, 0x08, 0x6a, 0x7f, 0x05, 0x0e, 0xfb, 0xca, 0xf8, 0x2f, 0xf9, + 0x46, 0x15, 0x53, 0x8b, 0xfb, 0x1b, 0x2a, 0x30, 0xec, 0x59, 0x8b, 0xe3, + 0xfb, 0x42, 0xdd, 0x8b, 0xf7, 0x36, 0xf7, 0x42, 0x05, 0x0e, 0xf7, 0xf9, + 0xfa, 0x65, 0xf7, 0xa1, 0x15, 0xfe, 0x7c, 0x8b, 0x7a, 0x30, 0xfa, 0x7c, + 0x8b, 0x9c, 0xe6, 0x05, 0x0e, 0xf7, 0xc1, 0xf7, 0x9c, 0x16, 0xf8, 0xa3, + 0x8b, 0xc6, 0xf7, 0x58, 0x71, 0x8e, 0x05, 0x61, 0x48, 0x72, 0x6f, 0x66, + 0x71, 0x60, 0x6d, 0x4c, 0x7b, 0x44, 0x8b, 0x62, 0x8b, 0x7a, 0x96, 0x8b, + 0xa5, 0x8b, 0x91, 0x8d, 0x96, 0x8e, 0x96, 0x08, 0xca, 0xf7, 0x85, 0x05, + 0xf7, 0x02, 0x84, 0xa2, 0x7c, 0x8b, 0x4a, 0x8b, 0x85, 0x8b, 0x82, 0x8a, + 0x7f, 0x08, 0x8a, 0x82, 0x8a, 0x80, 0xa4, 0x86, 0xd4, 0xf7, 0xa5, 0x71, + 0x8f, 0x05, 0x63, 0x35, 0x6a, 0x77, 0x25, 0x8b, 0x08, 0x82, 0x8b, 0x81, + 0x8b, 0xcc, 0xf7, 0x7f, 0x05, 0x92, 0xa6, 0x95, 0x90, 0xb5, 0x8b, 0xf3, + 0x8b, 0xc1, 0x65, 0x8f, 0x40, 0x08, 0x8d, 0x63, 0xa3, 0x86, 0xb8, 0xf7, + 0x52, 0xfc, 0xe1, 0x8b, 0x8b, 0x74, 0x05, 0xcc, 0x87, 0x9b, 0x85, 0x8b, + 0x79, 0x8b, 0x80, 0x83, 0x7a, 0x7f, 0x7b, 0x08, 0xfc, 0x02, 0xfc, 0x6c, + 0x05, 0x63, 0x59, 0x7f, 0x7c, 0x85, 0x88, 0x83, 0x86, 0x85, 0x8a, 0x7b, + 0x88, 0x08, 0x72, 0xf7, 0x57, 0xa4, 0x07, 0x5b, 0x8f, 0x7b, 0x93, 0x8b, + 0xa1, 0x8b, 0x97, 0x91, 0x99, 0x94, 0x98, 0x08, 0xf7, 0x06, 0xf7, 0x31, + 0xf7, 0x54, 0x8b, 0x5d, 0xfb, 0x33, 0x05, 0x7b, 0x56, 0x81, 0x81, 0x57, + 0x83, 0x08, 0x72, 0x07, 0x64, 0xf7, 0xba, 0x15, 0xf7, 0x91, 0xf7, 0xe1, + 0x97, 0x8b, 0x2f, 0xfb, 0xe1, 0xfb, 0x41, 0x8b, 0x05, 0x0e, 0xfc, 0x0d, + 0xf7, 0xcd, 0xf8, 0x78, 0x15, 0x88, 0x88, 0x8b, 0x8b, 0x89, 0x88, 0x78, + 0x75, 0x7c, 0x7d, 0x84, 0x8b, 0x88, 0x8b, 0x89, 0x8f, 0x8b, 0x90, 0x8b, + 0x9b, 0x91, 0xa5, 0x9b, 0xba, 0x08, 0xb9, 0xf7, 0x20, 0x3f, 0x87, 0x80, + 0x67, 0x05, 0x84, 0xab, 0x7d, 0x98, 0x71, 0x8b, 0x08, 0x39, 0x29, 0xfb, + 0x05, 0x2b, 0x5e, 0xa8, 0x6c, 0xb4, 0x1f, 0xb7, 0x8b, 0xa8, 0xa2, 0xb0, + 0xcc, 0x81, 0x69, 0x8a, 0x85, 0x8b, 0x80, 0x8b, 0x77, 0xa0, 0x79, 0xa2, + 0x8b, 0xa9, 0x8b, 0xa8, 0xa2, 0xb1, 0xc0, 0x08, 0x7e, 0x94, 0x05, 0xfb, + 0x07, 0xf7, 0x42, 0x15, 0x96, 0x8a, 0x94, 0x7f, 0x8b, 0x7c, 0x8b, 0x6e, + 0x78, 0x4d, 0x77, 0x66, 0x78, 0x67, 0x74, 0x76, 0x78, 0x8b, 0x7e, 0x8b, + 0x80, 0x98, 0x8b, 0x9a, 0x8b, 0xcc, 0xd0, 0xf7, 0x10, 0xae, 0x87, 0x08, + 0x0e, 0x6b, 0xf8, 0xe2, 0xf7, 0x56, 0x15, 0x73, 0x90, 0x05, 0x69, 0x53, + 0x75, 0x72, 0x64, 0x6f, 0x55, 0x65, 0x44, 0x77, 0x39, 0x8b, 0x5f, 0x8b, + 0x77, 0x94, 0x8b, 0xa0, 0x8b, 0x93, 0x8d, 0x98, 0x8e, 0x96, 0x08, 0xcd, + 0xf7, 0x88, 0xf7, 0x28, 0xde, 0xa0, 0xd1, 0xfb, 0x2a, 0x3a, 0xb7, 0xf7, + 0x36, 0x05, 0x9b, 0xc2, 0x9e, 0x98, 0xcd, 0x8f, 0x08, 0xa4, 0xfb, 0xd1, + 0x72, 0x07, 0x99, 0x89, 0x98, 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x95, 0x83, + 0x8b, 0x77, 0x8b, 0x7f, 0x86, 0x6c, 0x86, 0x79, 0x08, 0x54, 0xfb, 0x5d, + 0x27, 0x56, 0x75, 0x45, 0xf3, 0xc3, 0x59, 0xfb, 0x49, 0x05, 0x7b, 0x57, + 0x7d, 0x7e, 0x59, 0x84, 0x08, 0x72, 0xf8, 0xbd, 0x07, 0xc6, 0xf7, 0x56, + 0x05, 0x0e, 0xda, 0xf9, 0x0d, 0xf9, 0x90, 0x15, 0x5a, 0x8b, 0x56, 0x2f, + 0x05, 0x6b, 0x95, 0x77, 0x8e, 0x6d, 0x8b, 0xfb, 0x6b, 0x8b, 0xfb, 0x63, + 0xfb, 0x7c, 0x8b, 0xfb, 0x85, 0x8b, 0x51, 0x9f, 0x55, 0xb0, 0x61, 0x9b, + 0x78, 0x98, 0x81, 0xaa, 0x79, 0x08, 0x3c, 0xfb, 0x1c, 0xbb, 0x8b, 0xd1, + 0xf7, 0x0c, 0x05, 0xaa, 0x81, 0xa0, 0x88, 0xaa, 0x8b, 0xd7, 0x8b, 0xd6, + 0xa5, 0xce, 0xbd, 0xf7, 0x10, 0xe6, 0xde, 0xf7, 0x32, 0x8b, 0xf7, 0x26, + 0x8b, 0xbe, 0x7a, 0xc0, 0x6d, 0xb1, 0x78, 0xa4, 0x7b, 0x98, 0x64, 0xa2, + 0x08, 0xca, 0xf7, 0x00, 0x05, 0xfc, 0x57, 0xfd, 0x43, 0x15, 0x84, 0x9f, + 0x87, 0xa1, 0x8b, 0xa1, 0x8b, 0xf1, 0xbc, 0xf7, 0x43, 0xc5, 0xf2, 0xbc, + 0xe2, 0xc2, 0xb6, 0xc8, 0x8b, 0xa4, 0x8b, 0x9e, 0x85, 0x9e, 0x7c, 0x08, + 0xfb, 0xd8, 0xfc, 0xbd, 0x05, 0xf7, 0xf3, 0xf8, 0x98, 0x15, 0x94, 0x75, + 0x90, 0x74, 0x8b, 0x75, 0x8b, 0xfb, 0x06, 0x4b, 0xfb, 0x60, 0x4a, 0x2c, + 0x5d, 0x49, 0x5e, 0x6c, 0x55, 0x8b, 0x71, 0x8b, 0x78, 0x91, 0x77, 0x9b, + 0x08, 0xf7, 0xd9, 0xf8, 0xbf, 0x05, 0x0e, 0xf7, 0xc1, 0xfa, 0x46, 0xf9, + 0x31, 0x15, 0xfb, 0xe3, 0x06, 0x7a, 0x8b, 0x6a, 0x8d, 0x62, 0x8e, 0x08, + 0x6c, 0x8d, 0x80, 0x8c, 0x7d, 0x8b, 0xfb, 0x00, 0x8b, 0x4a, 0x77, 0x41, + 0x54, 0xfb, 0x0a, 0x32, 0x3f, 0xfb, 0x29, 0x8b, 0xfb, 0x21, 0x8b, 0x40, + 0xa4, 0x4c, 0xba, 0x64, 0xb7, 0x65, 0xc2, 0x7a, 0xdb, 0x8b, 0x08, 0x9f, + 0x8c, 0xf7, 0x2e, 0x92, 0xa1, 0x8b, 0x05, 0x90, 0x8b, 0x94, 0x8b, 0x95, + 0x8c, 0x08, 0xa7, 0x8b, 0xf7, 0xbc, 0x8b, 0xc7, 0xf7, 0x56, 0x70, 0x90, + 0x05, 0x46, 0xfb, 0x0d, 0x44, 0x5d, 0xfb, 0x09, 0x8b, 0x57, 0x8b, 0x76, + 0x95, 0x8b, 0xa3, 0x8b, 0x91, 0x8d, 0x95, 0x8d, 0x94, 0x08, 0xcb, 0xf7, + 0x89, 0x05, 0xd6, 0x84, 0x9f, 0x86, 0x9a, 0x7e, 0x98, 0x7f, 0x92, 0x7a, + 0x8b, 0x78, 0x8b, 0x83, 0x8a, 0x7b, 0x89, 0x7a, 0x8b, 0x88, 0x8b, 0x84, + 0x8a, 0x82, 0x08, 0xa6, 0x86, 0xd3, 0xf7, 0xa4, 0x70, 0x8e, 0x05, 0x6b, + 0x3e, 0x61, 0x70, 0x31, 0x8c, 0x08, 0x87, 0x8b, 0x76, 0x8b, 0xc8, 0xf7, + 0x70, 0x05, 0x96, 0xb4, 0x92, 0x91, 0xae, 0x8b, 0xf7, 0x02, 0x8b, 0xc2, + 0x65, 0x8b, 0x3d, 0x8b, 0x82, 0x8a, 0x7d, 0x8a, 0x7d, 0x08, 0xa4, 0x85, + 0x05, 0xb9, 0xf7, 0x53, 0x05, 0xfc, 0xbe, 0xfc, 0xb6, 0x15, 0x77, 0x43, + 0x6e, 0x70, 0x51, 0x8b, 0x42, 0x8b, 0x5b, 0xc0, 0x8b, 0xdc, 0x8b, 0xf7, + 0x09, 0xc1, 0xf7, 0x47, 0xca, 0xe6, 0xbb, 0xcf, 0xbd, 0xab, 0xc7, 0x8b, + 0xba, 0x8b, 0xa5, 0x75, 0x8b, 0x62, 0x8b, 0x7c, 0x86, 0x70, 0x84, 0x71, + 0x08, 0xfb, 0x00, 0xfc, 0x1b, 0x05, 0x0e, 0xfb, 0xeb, 0xf7, 0x87, 0xf9, + 0x41, 0x15, 0x2c, 0x2f, 0x2b, 0x27, 0x58, 0xb8, 0x65, 0xc8, 0x1f, 0xe7, + 0x8b, 0xe3, 0xe3, 0x90, 0xee, 0x8e, 0xc4, 0x5f, 0xb4, 0x4c, 0x8b, 0x08, + 0x89, 0x77, 0x15, 0x9c, 0x8a, 0x94, 0x7d, 0x8a, 0x74, 0x89, 0x60, 0x7b, + 0x4e, 0x78, 0x63, 0x76, 0x60, 0x77, 0x77, 0x74, 0x8b, 0x7a, 0x8b, 0x80, + 0x98, 0x8b, 0xa1, 0x8b, 0xb7, 0xa0, 0xd8, 0xa2, 0xb4, 0x9c, 0xaa, 0xa2, + 0x9d, 0x9f, 0x8a, 0x08, 0x0e, 0xda, 0xf7, 0xf4, 0xf8, 0x20, 0x15, 0x79, + 0xbd, 0x77, 0x9b, 0x60, 0x8b, 0x08, 0xfb, 0x12, 0xfb, 0x2a, 0xfb, 0x55, + 0xfb, 0x37, 0x47, 0xbb, 0x59, 0xcd, 0x1f, 0xce, 0x8b, 0xbd, 0xb1, 0xc3, + 0xe7, 0x93, 0x5d, 0x93, 0x77, 0x9c, 0x76, 0x08, 0xa1, 0x6f, 0xb4, 0x7b, + 0xba, 0x8b, 0xdf, 0x8b, 0xce, 0xba, 0xb6, 0xe3, 0x08, 0x6f, 0x9c, 0x05, + 0x69, 0x50, 0x61, 0x6d, 0x5c, 0x8b, 0x62, 0x8b, 0x71, 0xac, 0x8b, 0xbe, + 0x8b, 0x9b, 0x8c, 0x96, 0x8f, 0x9f, 0x08, 0xb2, 0x94, 0x05, 0xf7, 0x25, + 0xac, 0xde, 0xce, 0x8b, 0xdd, 0x8b, 0xc2, 0x66, 0xab, 0x4c, 0x8b, 0x5a, + 0x8b, 0x6f, 0x7c, 0x60, 0x59, 0x08, 0x9f, 0xcc, 0x24, 0x86, 0x05, 0x79, + 0x51, 0x05, 0x48, 0xa2, 0x15, 0xa7, 0x9f, 0x73, 0x6b, 0x1f, 0x8b, 0x55, + 0x6a, 0x22, 0x65, 0x48, 0x6e, 0x55, 0x6c, 0x72, 0x6a, 0x8b, 0x6d, 0x8b, + 0x77, 0xa6, 0x8d, 0xb2, 0x8e, 0xc5, 0xa6, 0xdf, 0xb0, 0xcd, 0x08, 0xac, + 0xc5, 0xab, 0xa8, 0xab, 0x8b, 0x08, 0xf7, 0x19, 0xfb, 0x50, 0x15, 0xb3, + 0xf7, 0x1a, 0xb5, 0xcb, 0xbd, 0x8b, 0xa2, 0x8b, 0x95, 0x7e, 0x8b, 0x6f, + 0x8b, 0x52, 0x6c, 0x5a, 0x51, 0x67, 0x6c, 0x78, 0x75, 0x82, 0x6f, 0x87, + 0x08, 0x90, 0x9c, 0x05, 0x0e, 0xfc, 0x01, 0xf7, 0x6c, 0xf7, 0x21, 0x15, + 0x7d, 0x77, 0x05, 0x71, 0x64, 0x74, 0x76, 0x7c, 0x8b, 0x83, 0x8b, 0x84, + 0x92, 0x8b, 0x93, 0x8b, 0x91, 0x91, 0xad, 0x8e, 0x97, 0x08, 0xe6, 0xf7, + 0xe2, 0x05, 0x55, 0x7f, 0x45, 0x81, 0x3d, 0x85, 0x08, 0x70, 0x07, 0xb6, + 0x9b, 0x83, 0x76, 0x1f, 0x8b, 0x83, 0x88, 0x7c, 0x87, 0x7a, 0x08, 0x51, + 0xfb, 0x6b, 0x05, 0x83, 0x6f, 0x86, 0x6f, 0x8b, 0x7e, 0x8b, 0x66, 0xa7, + 0x71, 0xb4, 0x8b, 0xc7, 0x8b, 0xb0, 0xaa, 0xd1, 0xf4, 0x08, 0x75, 0x99, + 0x05, 0x0e, 0xfc, 0x01, 0xf7, 0x6c, 0xf7, 0x21, 0x15, 0x63, 0x50, 0x77, + 0x76, 0x79, 0x8b, 0x83, 0x8b, 0x84, 0x92, 0x8b, 0x93, 0x8b, 0x99, 0x93, + 0xae, 0x99, 0xbe, 0x08, 0xbe, 0xf7, 0x4b, 0xe1, 0xba, 0x9e, 0xcf, 0x35, + 0x5c, 0xd6, 0xf7, 0xa4, 0x05, 0x35, 0x7b, 0x5b, 0x84, 0x40, 0x84, 0x08, + 0x70, 0x07, 0x96, 0x8c, 0x90, 0x8b, 0x90, 0x8b, 0xa6, 0x8b, 0x9a, 0x81, + 0x8b, 0x79, 0x8b, 0x7b, 0x7a, 0x47, 0x60, 0xfb, 0x2c, 0x08, 0x3d, 0x60, + 0x78, 0x45, 0xd8, 0xb6, 0x05, 0x5b, 0xfb, 0x40, 0x7d, 0x51, 0x8b, 0x71, + 0x8b, 0x65, 0xa5, 0x73, 0xb5, 0x8b, 0xc8, 0x8b, 0xb1, 0xaa, 0xd0, 0xf4, + 0x08, 0x75, 0x99, 0x05, 0x0e, 0xf8, 0x3c, 0xf8, 0xc4, 0x15, 0x66, 0x8b, + 0x50, 0x23, 0x05, 0x79, 0x90, 0x81, 0x8c, 0x7d, 0x8b, 0xfb, 0x2a, 0x8b, + 0xfb, 0x1f, 0xfb, 0x32, 0x8b, 0xfb, 0x3e, 0x8b, 0x52, 0xa3, 0x63, 0xc0, + 0x6d, 0x08, 0x43, 0xfb, 0x12, 0xb3, 0x8b, 0xcb, 0xf7, 0x06, 0x05, 0x9f, + 0x85, 0x98, 0x89, 0x9d, 0x8b, 0xf7, 0x28, 0x8b, 0xf7, 0x1c, 0xf7, 0x30, + 0x8b, 0xf7, 0x3c, 0x8b, 0xcb, 0x72, 0xb4, 0x52, 0xa7, 0x08, 0xcc, 0xf7, + 0x08, 0x05, 0xfb, 0xc8, 0xfc, 0x76, 0x15, 0x93, 0x07, 0x8b, 0xd5, 0xb0, + 0xf7, 0x20, 0xaf, 0xcb, 0xa4, 0xb9, 0xa8, 0xa2, 0xab, 0x8b, 0x98, 0x8b, + 0x94, 0x87, 0x95, 0x81, 0x08, 0xfb, 0x53, 0xfb, 0xe9, 0x05, 0xf7, 0x61, + 0xf7, 0xbf, 0x15, 0x8c, 0x89, 0x8b, 0x8a, 0x8b, 0x89, 0x8b, 0x4f, 0x70, + 0xfb, 0x0a, 0x6e, 0x46, 0x6c, 0x40, 0x6c, 0x69, 0x64, 0x8b, 0x7b, 0x8b, + 0x80, 0x91, 0x81, 0x97, 0x08, 0xf7, 0x55, 0xf7, 0xeb, 0x05, 0x0e, 0xda, + 0xf8, 0xe3, 0xf7, 0x1f, 0x15, 0x5f, 0x47, 0x6f, 0x76, 0x5d, 0x8b, 0x60, + 0x8b, 0x73, 0xa6, 0x8b, 0xbe, 0x8b, 0x9a, 0x8d, 0x98, 0x91, 0xa7, 0xf2, + 0xa2, 0xa4, 0x94, 0xb8, 0xa8, 0xc4, 0xb0, 0xa9, 0xb7, 0x8b, 0xb8, 0x8b, + 0xc3, 0x60, 0xae, 0x46, 0x8b, 0x08, 0x57, 0x8b, 0x68, 0x7c, 0x50, 0x5c, + 0x08, 0x6c, 0xb8, 0x6b, 0x9c, 0x56, 0x8b, 0x2a, 0x8b, 0x2d, 0x4e, 0x51, + 0x27, 0x6e, 0x57, 0x7b, 0x55, 0x8b, 0x58, 0x8b, 0x2e, 0xcc, 0x4b, 0xea, + 0x8b, 0xc5, 0x8b, 0xba, 0x9d, 0xb6, 0xb2, 0x08, 0xb2, 0x62, 0xab, 0x7b, + 0xb9, 0x8b, 0xb8, 0x8b, 0xb4, 0x9a, 0xae, 0xa9, 0xa3, 0x9f, 0x9c, 0xa2, + 0xa5, 0xbc, 0x08, 0x6f, 0x9a, 0x05, 0xfb, 0x3e, 0xda, 0x15, 0xbf, 0xf7, + 0x23, 0x94, 0x9e, 0xaa, 0xaf, 0x94, 0x95, 0x99, 0x91, 0x98, 0x8b, 0xa2, + 0x8b, 0x99, 0x7b, 0x8b, 0x73, 0x8b, 0x4b, 0x59, 0x47, 0x48, 0x71, 0x7f, + 0x86, 0x82, 0x88, 0x70, 0x83, 0x08, 0xfb, 0x1f, 0xf7, 0x6b, 0x15, 0xaf, + 0x9e, 0x72, 0x5a, 0x1f, 0x8b, 0x58, 0x68, 0xfb, 0x1c, 0x6e, 0x4d, 0x6c, + 0x4a, 0x6e, 0x6e, 0x67, 0x8b, 0x69, 0x8b, 0x78, 0xa8, 0x8b, 0xbf, 0x8b, + 0xb6, 0x97, 0xc4, 0xa2, 0xcf, 0x08, 0xb3, 0xf7, 0x0c, 0xae, 0xbb, 0xbb, + 0x8b, 0x08, 0x0e, 0xf7, 0x85, 0xf8, 0x14, 0x15, 0xa8, 0x87, 0x96, 0x88, + 0x95, 0x83, 0x9a, 0x80, 0x94, 0x73, 0x8b, 0x6d, 0x8b, 0x4a, 0x76, 0x25, + 0x73, 0x57, 0x79, 0x64, 0x77, 0x78, 0x74, 0x8b, 0x7b, 0x8b, 0x78, 0x93, + 0x83, 0x95, 0x08, 0x87, 0x90, 0x77, 0x68, 0x05, 0xa1, 0x7b, 0xa0, 0x85, + 0xa9, 0x8b, 0xf7, 0x08, 0x8b, 0xf3, 0xf7, 0x10, 0x8b, 0xf7, 0x1f, 0x8b, + 0xb5, 0x7c, 0xae, 0x6f, 0xa3, 0x73, 0xa1, 0x73, 0x94, 0x56, 0x96, 0xd8, + 0xa8, 0xa9, 0x9b, 0xad, 0xac, 0x08, 0xa4, 0xa3, 0x9b, 0xb0, 0x8b, 0xaf, + 0x8b, 0xd7, 0x4e, 0xc2, 0x36, 0x8b, 0xfb, 0x0e, 0x8b, 0x35, 0x23, 0x60, + 0xfb, 0x5a, 0x08, 0x2f, 0xfc, 0x3b, 0x05, 0x7d, 0x4c, 0x7a, 0x5b, 0x7b, + 0x76, 0x81, 0x7f, 0x81, 0x86, 0x78, 0x8b, 0x7f, 0x8b, 0x87, 0x8e, 0x8b, + 0x93, 0x8b, 0x90, 0x8c, 0x8d, 0x90, 0x90, 0x94, 0x95, 0x8d, 0x92, 0x8b, + 0x99, 0x08, 0xa7, 0x79, 0x9c, 0x6d, 0x6c, 0x77, 0x76, 0x6b, 0x5d, 0xb3, + 0x6c, 0xc4, 0x1e, 0xf4, 0x8b, 0xd7, 0xf1, 0xb8, 0xf7, 0x5c, 0x08, 0xe6, + 0xf8, 0x2b, 0x05, 0xa5, 0xf7, 0x09, 0xa9, 0xbc, 0xb8, 0x8b, 0xab, 0x8b, + 0x9a, 0x77, 0x8b, 0x63, 0x8b, 0x5c, 0x7f, 0x50, 0x7a, 0x67, 0x7a, 0x69, + 0x6d, 0x72, 0x79, 0x91, 0x89, 0x8c, 0x8a, 0x8b, 0x8a, 0x8b, 0x08, 0x7b, + 0x8b, 0x05, 0x84, 0x66, 0x05, 0x0e, 0xa3, 0xf8, 0xe5, 0xa4, 0x15, 0x49, + 0x90, 0x86, 0x90, 0x7e, 0xd7, 0x08, 0x2b, 0xf8, 0xd0, 0x72, 0x8b, 0xfc, + 0x08, 0xfc, 0xe0, 0x05, 0x6b, 0x5a, 0x7c, 0x7e, 0x67, 0x83, 0x08, 0x72, + 0xf7, 0x58, 0xa4, 0x07, 0x5d, 0x78, 0x96, 0xa3, 0x1f, 0x8b, 0x98, 0x90, + 0x9b, 0x95, 0x9c, 0x08, 0xc6, 0xf1, 0xf7, 0x6b, 0x8b, 0x05, 0x8e, 0x73, + 0x8e, 0x76, 0x8c, 0x84, 0x91, 0x64, 0x8d, 0x77, 0x8b, 0x7e, 0x8b, 0x61, + 0x7c, 0x80, 0x4b, 0x85, 0x08, 0x72, 0xf7, 0xc4, 0xa4, 0x07, 0xfc, 0x44, + 0xf7, 0x73, 0x15, 0xf7, 0x28, 0xf7, 0x87, 0xb0, 0xfb, 0x87, 0xfb, 0x4d, + 0x8b, 0x05, 0xf7, 0x1d, 0xf8, 0xfa, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, + 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, + 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, + 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xa3, 0xf8, 0xe5, + 0xa4, 0x15, 0x49, 0x90, 0x86, 0x90, 0x7e, 0xd7, 0x08, 0x2b, 0xf8, 0xd0, + 0x72, 0x8b, 0xfc, 0x08, 0xfc, 0xe0, 0x05, 0x6b, 0x5a, 0x7c, 0x7e, 0x67, + 0x83, 0x08, 0x72, 0xf7, 0x58, 0xa4, 0x07, 0x5d, 0x78, 0x96, 0xa3, 0x1f, + 0x8b, 0x98, 0x90, 0x9b, 0x95, 0x9c, 0x08, 0xc6, 0xf1, 0xf7, 0x6b, 0x8b, + 0x05, 0x8e, 0x73, 0x8e, 0x76, 0x8c, 0x84, 0x91, 0x64, 0x8d, 0x77, 0x8b, + 0x7e, 0x8b, 0x61, 0x7c, 0x80, 0x4b, 0x85, 0x08, 0x72, 0xf7, 0xc4, 0xa4, + 0x07, 0xfc, 0x44, 0xf7, 0x73, 0x15, 0xf7, 0x28, 0xf7, 0x87, 0xb0, 0xfb, + 0x87, 0xfb, 0x4d, 0x8b, 0x05, 0xf7, 0x69, 0xf8, 0x6f, 0x15, 0xf7, 0x2c, + 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, + 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, + 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xa3, 0xf8, 0xe5, 0xa4, 0x15, 0x49, 0x90, + 0x86, 0x90, 0x7e, 0xd7, 0x08, 0x2b, 0xf8, 0xd0, 0x72, 0x8b, 0xfc, 0x08, + 0xfc, 0xe0, 0x05, 0x6b, 0x5a, 0x7c, 0x7e, 0x67, 0x83, 0x08, 0x72, 0xf7, + 0x58, 0xa4, 0x07, 0x5d, 0x78, 0x96, 0xa3, 0x1f, 0x8b, 0x98, 0x90, 0x9b, + 0x95, 0x9c, 0x08, 0xc6, 0xf1, 0xf7, 0x6b, 0x8b, 0x05, 0x8e, 0x73, 0x8e, + 0x76, 0x8c, 0x84, 0x91, 0x64, 0x8d, 0x77, 0x8b, 0x7e, 0x8b, 0x61, 0x7c, + 0x80, 0x4b, 0x85, 0x08, 0x72, 0xf7, 0xc4, 0xa4, 0x07, 0xfc, 0x44, 0xf7, + 0x73, 0x15, 0xf7, 0x28, 0xf7, 0x87, 0xb0, 0xfb, 0x87, 0xfb, 0x4d, 0x8b, + 0x05, 0xf7, 0xc8, 0xf8, 0x6f, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, 0x7b, + 0xa0, 0x76, 0x98, 0x78, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, 0x8b, + 0x7c, 0x97, 0x7a, 0xa1, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, 0x05, + 0x0e, 0xa3, 0xf8, 0xe5, 0xa4, 0x15, 0x49, 0x90, 0x86, 0x90, 0x7e, 0xd7, + 0x08, 0x2b, 0xf8, 0xd0, 0x72, 0x8b, 0xfc, 0x08, 0xfc, 0xe0, 0x05, 0x6b, + 0x5a, 0x7c, 0x7e, 0x67, 0x83, 0x08, 0x72, 0xf7, 0x58, 0xa4, 0x07, 0x5d, + 0x78, 0x96, 0xa3, 0x1f, 0x8b, 0x98, 0x90, 0x9b, 0x95, 0x9c, 0x08, 0xc6, + 0xf1, 0xf7, 0x6b, 0x8b, 0x05, 0x8e, 0x73, 0x8e, 0x76, 0x8c, 0x84, 0x91, + 0x64, 0x8d, 0x77, 0x8b, 0x7e, 0x8b, 0x61, 0x7c, 0x80, 0x4b, 0x85, 0x08, + 0x72, 0xf7, 0xc4, 0xa4, 0x07, 0xfc, 0x44, 0xf7, 0x73, 0x15, 0xf7, 0x28, + 0xf7, 0x87, 0xb0, 0xfb, 0x87, 0xfb, 0x4d, 0x8b, 0x05, 0xf7, 0xec, 0xf8, + 0x6f, 0x15, 0xbe, 0x8b, 0x35, 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, + 0x42, 0xc4, 0x8b, 0xf7, 0x17, 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xa3, 0xf8, + 0xe5, 0xa4, 0x15, 0x49, 0x90, 0x86, 0x90, 0x7e, 0xd7, 0x08, 0x2b, 0xf8, + 0xd0, 0x72, 0x8b, 0xfc, 0x08, 0xfc, 0xe0, 0x05, 0x6b, 0x5a, 0x7c, 0x7e, + 0x67, 0x83, 0x08, 0x72, 0xf7, 0x58, 0xa4, 0x07, 0x5d, 0x78, 0x96, 0xa3, + 0x1f, 0x8b, 0x98, 0x90, 0x9b, 0x95, 0x9c, 0x08, 0xc6, 0xf1, 0xf7, 0x6b, + 0x8b, 0x05, 0x8e, 0x73, 0x8e, 0x76, 0x8c, 0x84, 0x91, 0x64, 0x8d, 0x77, + 0x8b, 0x7e, 0x8b, 0x61, 0x7c, 0x80, 0x4b, 0x85, 0x08, 0x72, 0xf7, 0xc4, + 0x07, 0xa4, 0x07, 0xfc, 0x44, 0xf7, 0x73, 0x15, 0xf7, 0x28, 0xf7, 0x87, + 0xb0, 0xfb, 0x87, 0xfb, 0x4d, 0x8b, 0x05, 0xf8, 0x0f, 0xf8, 0xfa, 0x15, + 0x7c, 0x6c, 0x7e, 0x80, 0x74, 0x8b, 0x80, 0x8b, 0x7a, 0x90, 0x71, 0x96, + 0x08, 0x62, 0x9d, 0x6b, 0x93, 0x73, 0x8b, 0x52, 0x8b, 0x5d, 0x5d, 0x7e, + 0x43, 0x08, 0xb3, 0x06, 0x98, 0xab, 0x98, 0x96, 0xa1, 0x8b, 0x96, 0x8b, + 0x99, 0x88, 0x98, 0x86, 0x08, 0xc6, 0x74, 0x05, 0xa5, 0x81, 0x97, 0x88, + 0x9e, 0x8b, 0xc7, 0x8b, 0xae, 0xaf, 0xa1, 0xde, 0x08, 0x62, 0x06, 0x0e, + 0xa3, 0xf8, 0xe5, 0xa4, 0x15, 0x49, 0x90, 0x86, 0x90, 0x7e, 0xd7, 0x08, + 0x2b, 0xf8, 0xd0, 0x72, 0x8b, 0xfc, 0x08, 0xfc, 0xe0, 0x05, 0x6b, 0x5a, + 0x7c, 0x7e, 0x67, 0x83, 0x08, 0x72, 0xf7, 0x58, 0xa4, 0x07, 0x5d, 0x78, + 0x96, 0xa3, 0x1f, 0x8b, 0x98, 0x90, 0x9b, 0x95, 0x9c, 0x08, 0xc6, 0xf1, + 0xf7, 0x6b, 0x8b, 0x05, 0x8e, 0x73, 0x8e, 0x76, 0x8c, 0x84, 0x91, 0x64, + 0x8d, 0x77, 0x8b, 0x7e, 0x8b, 0x61, 0x7c, 0x80, 0x4b, 0x85, 0x08, 0x72, + 0xf7, 0xc4, 0xa4, 0x07, 0xfc, 0x44, 0xf7, 0x73, 0x15, 0xf7, 0x28, 0xf7, + 0x87, 0xb0, 0xfb, 0x87, 0xfb, 0x4d, 0x8b, 0x05, 0xf7, 0x8b, 0xf9, 0x51, + 0x15, 0x51, 0x5a, 0x5b, 0x52, 0x4f, 0xbb, 0x5b, 0xc5, 0xc7, 0xbb, 0xbb, + 0xc6, 0xc5, 0x5b, 0xbb, 0x50, 0x1f, 0x8a, 0x5b, 0x15, 0xac, 0xa6, 0x70, + 0x6a, 0x6c, 0x6f, 0x71, 0x6b, 0x6b, 0x71, 0xa6, 0xaa, 0xab, 0xa6, 0xa6, + 0xaa, 0x1f, 0x0e, 0xa3, 0xf7, 0x85, 0x7f, 0x15, 0xa1, 0x87, 0x9f, 0x89, + 0xa0, 0x8b, 0xd2, 0x8b, 0xcd, 0xa1, 0xc4, 0xb6, 0xa9, 0xa2, 0x9b, 0x9c, + 0xab, 0xb7, 0x08, 0x6d, 0xa1, 0x05, 0x59, 0x50, 0x6f, 0x74, 0x61, 0x79, + 0x6f, 0x7f, 0x6c, 0x85, 0x6c, 0x8b, 0x2d, 0x8b, 0x53, 0xcc, 0x8b, 0xf7, + 0x01, 0x8b, 0xf7, 0x26, 0xd3, 0xf7, 0x41, 0xe6, 0xd7, 0xb0, 0xa9, 0xb2, + 0x9b, 0xb4, 0x8b, 0xdc, 0x8b, 0xbd, 0x4f, 0x8b, 0x29, 0x08, 0x8b, 0x7e, + 0x8a, 0x82, 0x89, 0x7e, 0x08, 0xab, 0x85, 0xbe, 0xf7, 0x7e, 0x6d, 0x8b, + 0x05, 0x7d, 0x75, 0x82, 0x84, 0x7c, 0x8b, 0x83, 0x8b, 0x7c, 0x8e, 0x7c, + 0x90, 0x60, 0x98, 0x5c, 0x93, 0x62, 0x8b, 0xfb, 0x73, 0x8b, 0xfb, 0x4d, + 0xfb, 0x5e, 0x8b, 0xfb, 0x86, 0x8b, 0xfb, 0x0b, 0xc9, 0x33, 0xf7, 0x01, + 0x67, 0x08, 0x4e, 0x31, 0x98, 0x7f, 0x05, 0x97, 0x8e, 0x93, 0x8c, 0x95, + 0x8b, 0x08, 0xa8, 0x9d, 0x7d, 0x75, 0x72, 0x75, 0x7b, 0x69, 0x1f, 0x75, + 0x8b, 0x7a, 0x8f, 0x6f, 0x98, 0x08, 0x75, 0x6a, 0x05, 0xb6, 0x79, 0xab, + 0x84, 0xb0, 0x8b, 0x08, 0xd2, 0xc0, 0xb0, 0xbd, 0xb5, 0x65, 0xa9, 0x57, + 0x1f, 0x81, 0x8b, 0x85, 0x8a, 0x81, 0x89, 0x08, 0xad, 0xbd, 0x05, 0x0e, + 0xda, 0xf7, 0x10, 0xf8, 0x09, 0x15, 0x25, 0x8b, 0x7f, 0x5f, 0xf1, 0x8b, + 0x4c, 0xfb, 0x7c, 0x05, 0x7c, 0x58, 0x7b, 0x7c, 0x5a, 0x85, 0x08, 0x72, + 0xf7, 0xb2, 0x07, 0xf7, 0x93, 0xf7, 0x52, 0xf7, 0x3d, 0xf7, 0x77, 0xf7, + 0x3f, 0xfb, 0x04, 0xf1, 0xfb, 0x51, 0x1f, 0xfb, 0xb6, 0x72, 0x06, 0x99, + 0x89, 0x97, 0x89, 0x90, 0x8a, 0xab, 0x86, 0x95, 0x83, 0x8b, 0x73, 0x8b, + 0x81, 0x87, 0x79, 0x83, 0x6c, 0x08, 0x5d, 0xfb, 0x3e, 0x05, 0xf7, 0x28, + 0x16, 0xc8, 0xf7, 0x77, 0x05, 0x92, 0xa6, 0x9b, 0x96, 0xab, 0x8b, 0xf7, + 0x03, 0x8b, 0xc1, 0x50, 0x8b, 0xfb, 0x0e, 0x8b, 0xfb, 0x06, 0x69, 0xfb, + 0x0b, 0x55, 0x3e, 0x56, 0x3f, 0x44, 0x66, 0x2c, 0x8b, 0x66, 0x8b, 0x7a, + 0x96, 0x8b, 0xa2, 0x8b, 0x97, 0x8e, 0x9b, 0x94, 0xa5, 0x08, 0x8d, 0x8c, + 0x8d, 0x8b, 0x1e, 0xc2, 0xf7, 0x5f, 0xf7, 0x0e, 0x8b, 0x97, 0xb7, 0xfb, + 0x0e, 0x8b, 0x05, 0x0e, 0xa3, 0xf8, 0xde, 0xf7, 0x56, 0x15, 0x72, 0x90, + 0x05, 0x68, 0x52, 0x76, 0x72, 0x64, 0x70, 0x53, 0x64, 0x47, 0x78, 0x35, + 0x8b, 0x60, 0x8b, 0x79, 0x95, 0x8b, 0xa3, 0x8b, 0x92, 0x8e, 0x96, 0x90, + 0x9f, 0x8d, 0x90, 0x8d, 0x91, 0x8c, 0x93, 0x08, 0x8d, 0x91, 0xc3, 0xf7, + 0x65, 0x05, 0xf7, 0x06, 0x89, 0xa9, 0x78, 0x8b, 0x46, 0x8b, 0x7d, 0x8a, + 0x80, 0x88, 0x78, 0x08, 0xa7, 0x86, 0xd5, 0xf7, 0xa5, 0x6f, 0x8f, 0x05, + 0x5c, 0x2d, 0x71, 0x7e, 0xfb, 0x18, 0x8c, 0x08, 0xc8, 0xf7, 0x73, 0x05, + 0x95, 0xae, 0x97, 0x94, 0xb4, 0x8b, 0xd4, 0x8b, 0xc1, 0x7c, 0xa6, 0x70, + 0xa2, 0x73, 0x92, 0x72, 0x8b, 0x4d, 0x08, 0xa6, 0x86, 0xb6, 0xf7, 0x52, + 0xfc, 0xb0, 0x8b, 0x8b, 0x72, 0x05, 0x99, 0x89, 0x97, 0x89, 0x90, 0x8a, + 0xaa, 0x87, 0x96, 0x83, 0x8b, 0x76, 0x8b, 0x7c, 0x87, 0x74, 0x85, 0x75, + 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x56, 0x7f, 0x80, 0x57, 0x83, + 0x08, 0x72, 0xf8, 0xbe, 0x07, 0xc6, 0xf7, 0x56, 0x05, 0xfb, 0xb2, 0xf9, + 0x30, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, + 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0xf7, 0x68, 0x16, 0x68, 0x6e, + 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, + 0xa9, 0x67, 0x1f, 0x0e, 0xa3, 0xf8, 0xde, 0xf7, 0x56, 0x15, 0x72, 0x90, + 0x05, 0x68, 0x52, 0x76, 0x72, 0x64, 0x70, 0x53, 0x64, 0x47, 0x78, 0x35, + 0x8b, 0x60, 0x8b, 0x79, 0x95, 0x8b, 0xa3, 0x8b, 0x92, 0x8e, 0x96, 0x90, + 0x9f, 0x8d, 0x90, 0x8d, 0x91, 0x8c, 0x93, 0x08, 0x8d, 0x91, 0xc3, 0xf7, + 0x65, 0x05, 0xf7, 0x06, 0x89, 0xa9, 0x78, 0x8b, 0x46, 0x8b, 0x7d, 0x8a, + 0x80, 0x88, 0x78, 0x08, 0xa7, 0x86, 0xd5, 0xf7, 0xa5, 0x6f, 0x8f, 0x05, + 0x5c, 0x2d, 0x71, 0x7e, 0xfb, 0x18, 0x8c, 0x08, 0xc8, 0xf7, 0x73, 0x05, + 0x95, 0xae, 0x97, 0x94, 0xb4, 0x8b, 0xd4, 0x8b, 0xc1, 0x7c, 0xa6, 0x70, + 0xa2, 0x73, 0x92, 0x72, 0x8b, 0x4d, 0x08, 0xa6, 0x86, 0xb6, 0xf7, 0x52, + 0xfc, 0xb0, 0x8b, 0x8b, 0x72, 0x05, 0x99, 0x89, 0x97, 0x89, 0x90, 0x8a, + 0xaa, 0x87, 0x96, 0x83, 0x8b, 0x76, 0x8b, 0x7c, 0x87, 0x74, 0x85, 0x75, + 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x56, 0x7f, 0x80, 0x57, 0x83, + 0x08, 0x72, 0xf8, 0xbe, 0x07, 0xc6, 0xf7, 0x56, 0x05, 0xfb, 0x68, 0xf8, + 0xa5, 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, 0x8b, 0x9e, + 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, 0x65, + 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xa3, 0xf8, 0xde, + 0xf7, 0x56, 0x15, 0x72, 0x90, 0x05, 0x68, 0x52, 0x76, 0x72, 0x64, 0x70, + 0x53, 0x64, 0x47, 0x78, 0x35, 0x8b, 0x60, 0x8b, 0x79, 0x95, 0x8b, 0xa3, + 0x8b, 0x92, 0x8e, 0x96, 0x90, 0x9f, 0x8d, 0x90, 0x8d, 0x91, 0x8c, 0x93, + 0x08, 0x8d, 0x91, 0xc3, 0xf7, 0x65, 0x05, 0xf7, 0x06, 0x89, 0xa9, 0x78, + 0x8b, 0x46, 0x8b, 0x7d, 0x8a, 0x80, 0x88, 0x78, 0x08, 0xa7, 0x86, 0xd5, + 0xf7, 0xa5, 0x6f, 0x8f, 0x05, 0x5c, 0x2d, 0x71, 0x7e, 0xfb, 0x18, 0x8c, + 0x08, 0xc8, 0xf7, 0x73, 0x05, 0x95, 0xae, 0x97, 0x94, 0xb4, 0x8b, 0xd4, + 0x8b, 0xc1, 0x7c, 0xa6, 0x70, 0xa2, 0x73, 0x92, 0x72, 0x8b, 0x4d, 0x08, + 0xa6, 0x86, 0xb6, 0xf7, 0x52, 0xfc, 0xb0, 0x8b, 0x8b, 0x72, 0x05, 0x99, + 0x89, 0x97, 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x96, 0x83, 0x8b, 0x76, 0x8b, + 0x7c, 0x87, 0x74, 0x85, 0x75, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, + 0x56, 0x7f, 0x80, 0x57, 0x83, 0x08, 0x72, 0xf8, 0xbe, 0x07, 0xc6, 0xf7, + 0x56, 0x05, 0xfb, 0x02, 0xf8, 0xa5, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, + 0x7b, 0xa0, 0x76, 0x98, 0x78, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, + 0x8b, 0x7c, 0x97, 0x7a, 0xa1, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, + 0x05, 0x0e, 0xa3, 0xf8, 0xde, 0xf7, 0x56, 0x15, 0x72, 0x90, 0x05, 0x68, + 0x52, 0x76, 0x72, 0x64, 0x70, 0x53, 0x64, 0x47, 0x78, 0x35, 0x8b, 0x60, + 0x8b, 0x79, 0x95, 0x8b, 0xa3, 0x8b, 0x92, 0x8e, 0x96, 0x90, 0x9f, 0x8d, + 0x90, 0x8d, 0x91, 0x8c, 0x93, 0x08, 0x8d, 0x91, 0xc3, 0xf7, 0x65, 0x05, + 0xf7, 0x06, 0x89, 0xa9, 0x78, 0x8b, 0x46, 0x8b, 0x7d, 0x8a, 0x80, 0x88, + 0x78, 0x08, 0xa7, 0x86, 0xd5, 0xf7, 0xa5, 0x6f, 0x8f, 0x05, 0x5c, 0x2d, + 0x71, 0x7e, 0xfb, 0x18, 0x8c, 0x08, 0xc8, 0xf7, 0x73, 0x05, 0x95, 0xae, + 0x97, 0x94, 0xb4, 0x8b, 0xd4, 0x8b, 0xc1, 0x7c, 0xa6, 0x70, 0xa2, 0x73, + 0x92, 0x72, 0x8b, 0x4d, 0x08, 0xa6, 0x86, 0xb6, 0xf7, 0x52, 0xfc, 0xb0, + 0x8b, 0x8b, 0x72, 0x05, 0x99, 0x89, 0x97, 0x89, 0x90, 0x8a, 0xaa, 0x87, + 0x96, 0x83, 0x8b, 0x76, 0x8b, 0x7c, 0x87, 0x74, 0x85, 0x75, 0x08, 0xfb, + 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x56, 0x7f, 0x80, 0x57, 0x83, 0x08, 0x72, + 0xf8, 0xbe, 0x07, 0xc6, 0xf7, 0x56, 0x05, 0x38, 0xf8, 0xa5, 0x15, 0xbe, + 0x8b, 0x35, 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, 0x42, 0xc4, 0x8b, + 0xf7, 0x17, 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xfb, 0x92, 0xf7, 0x9c, 0xa4, + 0x15, 0x52, 0x8e, 0x7c, 0x94, 0x8b, 0xa7, 0x8b, 0x9a, 0x90, 0xa2, 0x98, + 0xbc, 0x08, 0xf7, 0x06, 0xf8, 0x38, 0x05, 0x9b, 0xc0, 0x9a, 0x98, 0xbe, + 0x91, 0x08, 0xa4, 0xfb, 0xbe, 0x72, 0x07, 0x99, 0x89, 0x98, 0x89, 0x90, + 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, 0x77, 0x8b, 0x7f, 0x86, 0x6c, 0x86, + 0x79, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, 0x57, 0x7c, 0x7d, 0x5a, + 0x85, 0x08, 0x72, 0xf7, 0xbc, 0xa4, 0x07, 0x2a, 0xf9, 0xd9, 0x15, 0x68, + 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, + 0x6d, 0xa9, 0x67, 0x1f, 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, 0x69, + 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, + 0x0e, 0xfb, 0x92, 0xf7, 0x9c, 0xa4, 0x15, 0x52, 0x8e, 0x7c, 0x94, 0x8b, + 0xa7, 0x8b, 0x9a, 0x90, 0xa2, 0x98, 0xbc, 0x08, 0xf7, 0x06, 0xf8, 0x38, + 0x05, 0x9b, 0xc0, 0x9a, 0x98, 0xbe, 0x91, 0x08, 0xa4, 0xfb, 0xbe, 0x72, + 0x07, 0x99, 0x89, 0x98, 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, + 0x77, 0x8b, 0x7f, 0x86, 0x6c, 0x86, 0x79, 0x08, 0xfb, 0x0f, 0xfc, 0x55, + 0x05, 0x7b, 0x57, 0x7c, 0x7d, 0x5a, 0x85, 0x08, 0x72, 0xf7, 0xbc, 0xa4, + 0x07, 0x5b, 0xf9, 0x51, 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9c, 0x94, + 0x96, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, + 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, + 0xfb, 0x92, 0xf7, 0x9c, 0xa4, 0x15, 0x52, 0x8e, 0x7c, 0x94, 0x8b, 0xa7, + 0x8b, 0x9a, 0x90, 0xa2, 0x98, 0xbc, 0x08, 0xf7, 0x06, 0xf8, 0x38, 0x05, + 0x9b, 0xc0, 0x9a, 0x98, 0xbe, 0x91, 0x08, 0xa4, 0xfb, 0xbe, 0x72, 0x07, + 0x99, 0x89, 0x98, 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, 0x77, + 0x8b, 0x7f, 0x86, 0x6c, 0x86, 0x79, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, + 0x7b, 0x57, 0x7c, 0x7d, 0x5a, 0x85, 0x08, 0x72, 0xf7, 0xbc, 0xa4, 0x07, + 0xe9, 0xf9, 0x4e, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, 0x7b, 0xa0, 0x76, + 0x98, 0x78, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, 0x8b, 0x7c, 0x97, + 0x7a, 0xa1, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, 0x05, 0x0e, 0xfb, + 0x92, 0xf7, 0x9c, 0xa4, 0x15, 0x52, 0x8e, 0x7c, 0x94, 0x8b, 0xa7, 0x8b, + 0x9a, 0x90, 0xa2, 0x98, 0xbc, 0x08, 0xf7, 0x06, 0xf8, 0x38, 0x05, 0x9b, + 0xc0, 0x9a, 0x98, 0xbe, 0x91, 0x08, 0xa4, 0xfb, 0xbe, 0x72, 0x07, 0x99, + 0x89, 0x98, 0x89, 0x90, 0x8a, 0xaa, 0x87, 0x95, 0x83, 0x8b, 0x77, 0x8b, + 0x7f, 0x86, 0x6c, 0x86, 0x79, 0x08, 0xfb, 0x0f, 0xfc, 0x55, 0x05, 0x7b, + 0x57, 0x7c, 0x7d, 0x5a, 0x85, 0x08, 0x72, 0xf7, 0xbc, 0xa4, 0x07, 0xf4, + 0xf9, 0x4e, 0x15, 0xbe, 0x8b, 0x35, 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, + 0xfb, 0x42, 0xc4, 0x8b, 0xf7, 0x17, 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xda, + 0xf7, 0xc6, 0xf9, 0x31, 0x15, 0xfb, 0x57, 0x72, 0x06, 0xc2, 0x86, 0x94, + 0x85, 0x9e, 0x5f, 0x08, 0xfb, 0x0c, 0xfc, 0x2f, 0x05, 0x64, 0xfb, 0x17, + 0x84, 0x80, 0x54, 0x80, 0x08, 0x72, 0xf7, 0x64, 0xa4, 0x07, 0x50, 0x90, + 0x76, 0x9a, 0x8b, 0xb2, 0x8b, 0x9d, 0x92, 0xae, 0x96, 0xb4, 0x08, 0xee, + 0xf7, 0xf8, 0x05, 0xf7, 0x95, 0xfc, 0xb9, 0xa7, 0x8b, 0xf7, 0x23, 0xf8, + 0x8e, 0x05, 0xb2, 0xf7, 0x18, 0x90, 0x93, 0xc5, 0x98, 0x08, 0xa4, 0xfb, + 0x65, 0x72, 0x07, 0xc6, 0x86, 0xa0, 0x7b, 0x8b, 0x65, 0x8b, 0x79, 0x84, + 0x67, 0x80, 0x63, 0x08, 0x3b, 0xfb, 0xb3, 0x05, 0xfb, 0x6b, 0xf8, 0x65, + 0x05, 0xf7, 0xb9, 0xf7, 0x55, 0x15, 0x7c, 0x6c, 0x7e, 0x80, 0x74, 0x8b, + 0x80, 0x8b, 0x7a, 0x90, 0x71, 0x96, 0x08, 0x62, 0x9d, 0x6b, 0x93, 0x73, + 0x8b, 0x52, 0x8b, 0x5d, 0x5d, 0x7e, 0x43, 0x08, 0xb3, 0x06, 0x98, 0xab, + 0x98, 0x96, 0xa1, 0x8b, 0x96, 0x8b, 0x99, 0x88, 0x98, 0x86, 0x08, 0xc6, + 0x74, 0x05, 0xa5, 0x81, 0x97, 0x88, 0x9e, 0x8b, 0xc7, 0x8b, 0xae, 0xaf, + 0xa1, 0xde, 0x08, 0x62, 0x06, 0x0e, 0xda, 0xf8, 0x55, 0xf9, 0x41, 0x15, + 0x42, 0x8b, 0x41, 0x71, 0x47, 0x59, 0xfb, 0x0d, 0x33, 0x35, 0xfb, 0x35, + 0x8b, 0xfb, 0x1f, 0x8b, 0xfb, 0x23, 0xea, 0x2b, 0xf7, 0x21, 0x8b, 0xda, + 0x8b, 0xd7, 0xa5, 0xce, 0xbd, 0xf7, 0x10, 0xe6, 0xdd, 0xf7, 0x33, 0x8b, + 0xf7, 0x26, 0x08, 0xf7, 0x19, 0x24, 0xed, 0xfb, 0x1f, 0x1e, 0x87, 0x69, + 0x15, 0xc8, 0xb4, 0x5b, 0x43, 0x1f, 0x8b, 0xfb, 0x0c, 0x4d, 0xfb, 0x5c, + 0x48, 0x29, 0x5d, 0x48, 0x5e, 0x6d, 0x55, 0x8b, 0x4c, 0x8b, 0x64, 0xba, + 0x8b, 0xd5, 0x8b, 0xf1, 0xbe, 0xf7, 0x4d, 0xc2, 0xeb, 0xbe, 0xe5, 0xc0, + 0xb4, 0xcb, 0x8b, 0x08, 0x2c, 0xf7, 0x67, 0x15, 0x68, 0x6e, 0x6d, 0x67, + 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, + 0x1f, 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, + 0xae, 0xaa, 0xa9, 0xad, 0x1f, 0xaf, 0x6d, 0xa9, 0x67, 0x1e, 0x0e, 0xda, + 0xf8, 0x55, 0xf9, 0x41, 0x15, 0x42, 0x8b, 0x41, 0x71, 0x47, 0x59, 0xfb, + 0x0d, 0x33, 0x35, 0xfb, 0x35, 0x8b, 0xfb, 0x1f, 0x8b, 0xfb, 0x23, 0xea, + 0x2b, 0xf7, 0x21, 0x8b, 0xda, 0x8b, 0xd7, 0xa5, 0xce, 0xbd, 0xf7, 0x10, + 0xe6, 0xdd, 0xf7, 0x33, 0x8b, 0xf7, 0x26, 0x8b, 0xf7, 0x19, 0x24, 0xed, + 0xfb, 0x1f, 0x8b, 0x08, 0x87, 0x69, 0x15, 0xc8, 0xb4, 0x5b, 0x43, 0x1f, + 0x8b, 0xfb, 0x0c, 0x4d, 0xfb, 0x5c, 0x48, 0x29, 0x5d, 0x48, 0x5e, 0x6d, + 0x55, 0x8b, 0x4c, 0x8b, 0x64, 0xba, 0x8b, 0xd5, 0x8b, 0xf1, 0xbe, 0xf7, + 0x4d, 0xc2, 0xeb, 0xbe, 0xe5, 0xc0, 0xb4, 0xcb, 0x8b, 0x08, 0x7f, 0xd3, + 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, + 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7b, 0x7f, 0x67, 0x65, 0x08, + 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xda, 0xf8, 0x55, 0xf9, + 0x41, 0x15, 0x42, 0x8b, 0x41, 0x71, 0x47, 0x59, 0xfb, 0x0d, 0x33, 0x35, + 0xfb, 0x35, 0x8b, 0xfb, 0x1f, 0x8b, 0xfb, 0x23, 0xea, 0x2b, 0xf7, 0x21, + 0x8b, 0xda, 0x8b, 0xd7, 0xa5, 0xce, 0xbd, 0xf7, 0x10, 0xe6, 0xdd, 0xf7, + 0x33, 0x8b, 0xf7, 0x26, 0x8b, 0xf7, 0x19, 0x24, 0xed, 0xfb, 0x1f, 0x8b, + 0x08, 0x87, 0x69, 0x15, 0xc8, 0xb4, 0x5b, 0x43, 0x1f, 0x8b, 0xfb, 0x0c, + 0x4d, 0xfb, 0x5c, 0x48, 0x29, 0x5d, 0x48, 0x5e, 0x6d, 0x55, 0x8b, 0x4c, + 0x8b, 0x64, 0xba, 0x8b, 0xd5, 0x8b, 0xf1, 0xbe, 0xf7, 0x4d, 0xc2, 0xeb, + 0xbe, 0xe5, 0xc0, 0xb4, 0xcb, 0x8b, 0x08, 0xec, 0xd3, 0x15, 0xfb, 0x03, + 0xf7, 0x27, 0x05, 0x7b, 0xa1, 0x76, 0x97, 0x78, 0x8b, 0x73, 0x8b, 0x76, + 0x76, 0x8b, 0x73, 0x8b, 0x7c, 0x97, 0x7a, 0xa1, 0x7c, 0x08, 0xf7, 0x19, + 0x32, 0xb8, 0x8b, 0x05, 0x0e, 0xda, 0xf8, 0x55, 0xf9, 0x41, 0x15, 0x42, + 0x8b, 0x41, 0x71, 0x47, 0x59, 0xfb, 0x0d, 0x33, 0x35, 0xfb, 0x35, 0x8b, + 0xfb, 0x1f, 0x8b, 0xfb, 0x23, 0xea, 0x2b, 0xf7, 0x21, 0x8b, 0xda, 0x8b, + 0xd7, 0xa5, 0xce, 0xbd, 0xf7, 0x10, 0xe6, 0xdd, 0xf7, 0x33, 0x8b, 0xf7, + 0x26, 0x8b, 0xf7, 0x19, 0x24, 0xed, 0xfb, 0x1f, 0x8b, 0x08, 0x87, 0x69, + 0x15, 0xc8, 0xb4, 0x5b, 0x43, 0x1f, 0x8b, 0xfb, 0x0c, 0x4d, 0xfb, 0x5c, + 0x48, 0x29, 0x5d, 0x48, 0x5e, 0x6d, 0x55, 0x8b, 0x4c, 0x8b, 0x64, 0xba, + 0x8b, 0xd5, 0x8b, 0xf1, 0xbe, 0xf7, 0x4d, 0xc2, 0xeb, 0xbe, 0xe5, 0xc0, + 0xb4, 0xcb, 0x8b, 0x08, 0xf7, 0x10, 0xd3, 0x15, 0xbe, 0x8b, 0x35, 0xf7, + 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, 0x42, 0xc4, 0x8b, 0xf7, 0x17, 0xea, + 0xe3, 0x2c, 0x05, 0x0e, 0xda, 0xf8, 0x55, 0xf9, 0x41, 0x15, 0x42, 0x8b, + 0x41, 0x71, 0x47, 0x59, 0xfb, 0x0d, 0x33, 0x35, 0xfb, 0x35, 0x8b, 0xfb, + 0x1f, 0x8b, 0xfb, 0x23, 0xea, 0x2b, 0xf7, 0x21, 0x8b, 0xda, 0x8b, 0xd7, + 0xa5, 0xce, 0xbd, 0xf7, 0x10, 0xe6, 0xdd, 0xf7, 0x33, 0x8b, 0xf7, 0x26, + 0x08, 0xf7, 0x19, 0x24, 0xed, 0xfb, 0x1f, 0x1e, 0x87, 0x69, 0x15, 0xc8, + 0xb4, 0x5b, 0x43, 0x1f, 0x8b, 0xfb, 0x0c, 0x4d, 0xfb, 0x5c, 0x48, 0x29, + 0x5d, 0x48, 0x5e, 0x6d, 0x55, 0x8b, 0x4c, 0x8b, 0x64, 0xba, 0x8b, 0xd5, + 0x8b, 0xf1, 0xbe, 0xf7, 0x4d, 0xc2, 0xeb, 0xbe, 0xe5, 0xc0, 0xb4, 0xcb, + 0x8b, 0x08, 0xf7, 0x30, 0xf7, 0x67, 0x15, 0x7c, 0x6c, 0x7e, 0x80, 0x74, + 0x8b, 0x7f, 0x8b, 0x7b, 0x90, 0x71, 0x96, 0x08, 0x62, 0x9d, 0x6b, 0x93, + 0x72, 0x8b, 0x52, 0x8b, 0x5e, 0x5d, 0x7e, 0x43, 0x08, 0xb3, 0x06, 0x98, + 0xab, 0x97, 0x96, 0xa2, 0x8b, 0x96, 0x8b, 0x99, 0x88, 0x98, 0x86, 0x08, + 0xc6, 0x74, 0x05, 0xa5, 0x81, 0x97, 0x88, 0x9d, 0x8b, 0xc7, 0x8b, 0xaf, + 0xaf, 0xa1, 0xde, 0x08, 0x62, 0x06, 0x0e, 0x34, 0x8d, 0x79, 0x15, 0xa9, + 0x06, 0x97, 0xa8, 0x92, 0x91, 0x9e, 0x8b, 0x95, 0x8b, 0x98, 0x88, 0xa2, + 0x83, 0xbc, 0x7a, 0xad, 0x84, 0xb3, 0x8b, 0xf7, 0x20, 0x8b, 0xe4, 0xda, + 0x8b, 0xf7, 0x10, 0x8b, 0xe1, 0x5d, 0xce, 0xfb, 0x0e, 0xe8, 0x4d, 0xba, + 0x7c, 0xa1, 0x8b, 0xb8, 0x08, 0xcb, 0xb3, 0xb4, 0xcb, 0x1e, 0xdb, 0x8b, + 0xb2, 0x5a, 0x98, 0xfb, 0x09, 0x08, 0xa6, 0x87, 0xb3, 0xf7, 0x5d, 0x6d, + 0x8b, 0x05, 0x82, 0x79, 0x7d, 0x83, 0x76, 0x8b, 0x82, 0x8b, 0x7a, 0x8f, + 0x72, 0x92, 0x60, 0x99, 0x70, 0x90, 0x6f, 0x8b, 0xfb, 0x06, 0x8b, 0x34, + 0x37, 0x8b, 0xfb, 0x02, 0x8b, 0x70, 0x90, 0x75, 0x93, 0x7a, 0xa1, 0x61, + 0xb4, 0x5f, 0xc3, 0x5f, 0x08, 0xd9, 0x4f, 0xae, 0x5c, 0x8b, 0x5d, 0x8b, + 0x75, 0x84, 0x73, 0x7f, 0x75, 0x74, 0x64, 0x68, 0x78, 0x5a, 0x8b, 0x57, + 0x8b, 0x5d, 0xa4, 0x72, 0xb5, 0x78, 0xaa, 0x83, 0xa9, 0x87, 0xc7, 0x08, + 0x6e, 0x8d, 0x67, 0xfb, 0x74, 0x05, 0xf8, 0x9d, 0xfa, 0x27, 0x15, 0x53, + 0x8b, 0xfb, 0x1b, 0x2a, 0x30, 0xec, 0x59, 0x8b, 0xe3, 0xfb, 0x42, 0xdd, + 0x8b, 0xf7, 0x36, 0xf7, 0x42, 0x05, 0x0e, 0xda, 0xf9, 0x7c, 0xf9, 0x31, + 0x15, 0xfb, 0x64, 0x72, 0x06, 0xc4, 0x86, 0xa2, 0x7b, 0x8b, 0x68, 0x8b, + 0x7a, 0x83, 0x64, 0x80, 0x62, 0x08, 0x51, 0xfb, 0x65, 0x05, 0x70, 0x2a, + 0x75, 0x59, 0x6d, 0x66, 0x69, 0x63, 0x5f, 0x77, 0x54, 0x8b, 0x3f, 0x8b, + 0x5d, 0xb1, 0x8b, 0xca, 0x8b, 0xa6, 0x8e, 0x9a, 0xa4, 0xe6, 0x08, 0xdd, + 0xf7, 0xc0, 0x05, 0x9c, 0xc4, 0x9a, 0x97, 0xc9, 0x8e, 0x08, 0xa4, 0xfb, + 0xcb, 0x72, 0x07, 0x99, 0x89, 0x98, 0x89, 0x8f, 0x8b, 0xab, 0x86, 0x95, + 0x83, 0x8b, 0x75, 0x8b, 0x7f, 0x85, 0x6c, 0x82, 0x6a, 0x08, 0x53, 0xfb, + 0x62, 0x05, 0x76, 0x3b, 0x7f, 0x4d, 0x8b, 0x6a, 0x8b, 0x29, 0xe7, 0x47, + 0xf7, 0x17, 0x8b, 0xe0, 0x8b, 0xce, 0xa6, 0xb8, 0xc0, 0xad, 0xb2, 0xa3, + 0xc1, 0xaa, 0xf7, 0x00, 0x08, 0xcd, 0xf7, 0x78, 0x05, 0xb3, 0xf7, 0x18, + 0x92, 0x95, 0xc2, 0x96, 0x08, 0xa4, 0x07, 0xfc, 0x1a, 0xf7, 0x55, 0x15, + 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, + 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, + 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, + 0x1f, 0x0e, 0xda, 0xf9, 0x7c, 0xf9, 0x31, 0x15, 0xfb, 0x64, 0x72, 0x06, + 0xc4, 0x86, 0xa2, 0x7b, 0x8b, 0x68, 0x8b, 0x7a, 0x83, 0x64, 0x80, 0x62, + 0x08, 0x51, 0xfb, 0x65, 0x05, 0x70, 0x2a, 0x75, 0x59, 0x6d, 0x66, 0x69, + 0x63, 0x5f, 0x77, 0x54, 0x8b, 0x3f, 0x8b, 0x5d, 0xb1, 0x8b, 0xca, 0x8b, + 0xa6, 0x8e, 0x9a, 0xa4, 0xe6, 0x08, 0xdd, 0xf7, 0xc0, 0x05, 0x9c, 0xc4, + 0x9a, 0x97, 0xc9, 0x8e, 0x08, 0xa4, 0xfb, 0xcb, 0x72, 0x07, 0x99, 0x89, + 0x98, 0x89, 0x8f, 0x8b, 0xab, 0x86, 0x95, 0x83, 0x8b, 0x75, 0x8b, 0x7f, + 0x85, 0x6c, 0x82, 0x6a, 0x08, 0x53, 0xfb, 0x62, 0x05, 0x76, 0x3b, 0x7f, + 0x4d, 0x8b, 0x6a, 0x8b, 0x29, 0xe7, 0x47, 0xf7, 0x17, 0x8b, 0xe0, 0x8b, + 0xce, 0xa6, 0xb8, 0xc0, 0xad, 0xb2, 0xa3, 0xc1, 0xaa, 0xf7, 0x00, 0x08, + 0xcd, 0xf7, 0x78, 0x05, 0xb3, 0xf7, 0x18, 0x92, 0x95, 0xc2, 0x96, 0x08, + 0xa4, 0x07, 0xfb, 0xe3, 0xc1, 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9d, + 0x94, 0x95, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, + 0x7a, 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, + 0x0e, 0xda, 0xf9, 0x7c, 0xf9, 0x31, 0x15, 0xfb, 0x64, 0x72, 0x06, 0xc4, + 0x86, 0xa2, 0x7b, 0x8b, 0x68, 0x8b, 0x7a, 0x83, 0x64, 0x80, 0x62, 0x08, + 0x51, 0xfb, 0x65, 0x05, 0x70, 0x2a, 0x75, 0x59, 0x6d, 0x66, 0x69, 0x63, + 0x5f, 0x77, 0x54, 0x8b, 0x3f, 0x8b, 0x5d, 0xb1, 0x8b, 0xca, 0x8b, 0xa6, + 0x8e, 0x9a, 0xa4, 0xe6, 0x08, 0xdd, 0xf7, 0xc0, 0x05, 0x9c, 0xc4, 0x9a, + 0x97, 0xc9, 0x8e, 0x08, 0xa4, 0xfb, 0xcb, 0x72, 0x07, 0x99, 0x89, 0x98, + 0x89, 0x8f, 0x8b, 0xab, 0x86, 0x95, 0x83, 0x8b, 0x75, 0x8b, 0x7f, 0x85, + 0x6c, 0x82, 0x6a, 0x08, 0x53, 0xfb, 0x62, 0x05, 0x76, 0x3b, 0x7f, 0x4d, + 0x8b, 0x6a, 0x8b, 0x29, 0xe7, 0x47, 0xf7, 0x17, 0x8b, 0xe0, 0x8b, 0xce, + 0xa6, 0xb8, 0xc0, 0xad, 0xb2, 0xa3, 0xc1, 0xaa, 0xf7, 0x00, 0x08, 0xcd, + 0xf7, 0x78, 0x05, 0xb3, 0xf7, 0x18, 0x92, 0x95, 0xc2, 0x96, 0x08, 0xa4, + 0x07, 0xfb, 0x55, 0xc1, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, 0x7b, 0xa1, + 0x76, 0x97, 0x78, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, 0x8b, 0x7c, + 0x97, 0x79, 0xa1, 0x7d, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, 0x05, 0x0e, + 0xda, 0xf9, 0x7c, 0xf9, 0x31, 0x15, 0xfb, 0x64, 0x72, 0x06, 0xc4, 0x86, + 0xa2, 0x7b, 0x8b, 0x68, 0x8b, 0x7a, 0x83, 0x64, 0x80, 0x62, 0x08, 0x51, + 0xfb, 0x65, 0x05, 0x70, 0x2a, 0x75, 0x59, 0x6d, 0x66, 0x69, 0x63, 0x5f, + 0x77, 0x54, 0x8b, 0x3f, 0x8b, 0x5d, 0xb1, 0x8b, 0xca, 0x8b, 0xa6, 0x8e, + 0x9a, 0xa4, 0xe6, 0x08, 0xdd, 0xf7, 0xc0, 0x05, 0x9c, 0xc4, 0x9a, 0x97, + 0xc9, 0x8e, 0x08, 0xa4, 0xfb, 0xcb, 0x72, 0x07, 0x99, 0x89, 0x98, 0x89, + 0x8f, 0x8b, 0xab, 0x86, 0x95, 0x83, 0x8b, 0x75, 0x8b, 0x7f, 0x85, 0x6c, + 0x82, 0x6a, 0x08, 0x53, 0xfb, 0x62, 0x05, 0x76, 0x3b, 0x7f, 0x4d, 0x8b, + 0x6a, 0x8b, 0x29, 0xe7, 0x47, 0xf7, 0x17, 0x8b, 0xe0, 0x8b, 0xce, 0xa6, + 0xb8, 0xc0, 0xad, 0xb2, 0xa3, 0xc1, 0xaa, 0xf7, 0x00, 0x08, 0xcd, 0xf7, + 0x78, 0x05, 0xb3, 0xf7, 0x18, 0x92, 0x95, 0xc2, 0x96, 0x08, 0xa4, 0x07, + 0xfb, 0x41, 0xc1, 0x15, 0xbe, 0x8b, 0x35, 0xf7, 0x42, 0x3a, 0x8b, 0xfb, + 0x34, 0xfb, 0x42, 0xc4, 0x8b, 0xf7, 0x17, 0xea, 0xe3, 0x2c, 0x05, 0x0e, + 0x6b, 0xf7, 0x7e, 0xf7, 0xcd, 0x15, 0x4f, 0xfb, 0x6c, 0x05, 0x79, 0x52, + 0x7d, 0x81, 0x46, 0x86, 0x08, 0x72, 0xf7, 0xd6, 0xa4, 0x07, 0x4a, 0x8e, + 0x7f, 0x92, 0x8b, 0xb0, 0x8b, 0x97, 0x8d, 0x95, 0x91, 0xa2, 0x08, 0xbf, + 0xf7, 0x53, 0xf7, 0x52, 0xf7, 0x9f, 0x05, 0xad, 0xb9, 0x9e, 0x9a, 0xb1, + 0x93, 0x08, 0xa4, 0xfb, 0x64, 0x72, 0x07, 0xc0, 0x89, 0x99, 0x82, 0x8b, + 0x68, 0x8b, 0x79, 0x85, 0x7e, 0x77, 0x6e, 0x08, 0xfb, 0x15, 0xfb, 0x4e, + 0x05, 0x84, 0xa1, 0x7c, 0xb7, 0x88, 0x96, 0x82, 0xa8, 0x84, 0x9f, 0x88, + 0x95, 0x74, 0xcd, 0x81, 0xaf, 0x8b, 0x9c, 0x8b, 0xa7, 0x9a, 0x93, 0xc2, + 0x8c, 0x08, 0xa4, 0xfb, 0xaf, 0x72, 0x07, 0xbe, 0x84, 0x8e, 0x88, 0x9e, + 0x56, 0x08, 0xe3, 0xfb, 0xa0, 0x05, 0xf7, 0x08, 0xf8, 0x2e, 0x15, 0xf7, + 0x2c, 0xe2, 0x05, 0xa9, 0x9d, 0x94, 0x95, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, + 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, + 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0x6b, 0xf8, 0xbe, 0xf7, 0x56, 0x15, + 0x70, 0x90, 0x05, 0x6c, 0x59, 0x65, 0x61, 0x63, 0x70, 0x5e, 0x6c, 0x50, + 0x7d, 0x33, 0x8b, 0x08, 0x45, 0x8b, 0xf8, 0x46, 0xf8, 0xf1, 0x8b, 0xa8, + 0xfc, 0x68, 0x8b, 0x52, 0xfb, 0x46, 0xa7, 0x87, 0x05, 0xda, 0xf7, 0x02, + 0xca, 0xb0, 0xf7, 0x02, 0x8b, 0x08, 0xd9, 0x8b, 0xfc, 0x46, 0xfc, 0xf1, + 0x8b, 0x6e, 0xf8, 0x8e, 0x8b, 0xc6, 0xf7, 0x56, 0x05, 0x88, 0xf9, 0x53, + 0x15, 0x53, 0x8b, 0xfb, 0x1b, 0x2a, 0x30, 0xec, 0x59, 0x8b, 0xe3, 0xfb, + 0x42, 0xdd, 0x8b, 0xf7, 0x36, 0xf7, 0x42, 0x05, 0x0e, 0x6b, 0xf7, 0x05, + 0xf9, 0x18, 0x15, 0x99, 0x89, 0x97, 0x89, 0x90, 0x8b, 0xaa, 0x87, 0x96, + 0x82, 0x8b, 0x77, 0x8b, 0x7c, 0x87, 0x73, 0x85, 0x75, 0x08, 0xfb, 0x0f, + 0xfc, 0x55, 0x05, 0x7b, 0x56, 0x7f, 0x80, 0x57, 0x83, 0x08, 0x72, 0xf7, + 0xba, 0xa4, 0x07, 0x53, 0x8e, 0x7b, 0x94, 0x8b, 0xa6, 0x8b, 0x94, 0x8e, + 0x9e, 0x92, 0xaa, 0x08, 0x99, 0xcb, 0x05, 0xaf, 0x87, 0x9e, 0x8a, 0xa5, + 0x8b, 0x08, 0xf7, 0x3b, 0xf6, 0xd8, 0xf7, 0x0c, 0xf0, 0x40, 0xc1, 0xfb, + 0x1f, 0x1f, 0x5b, 0x8b, 0x98, 0xb1, 0x05, 0x9f, 0xc4, 0x94, 0x93, 0xc0, + 0x92, 0x08, 0xa4, 0xfb, 0xba, 0x72, 0x07, 0xf7, 0x48, 0xfb, 0x4e, 0x15, + 0x92, 0xa3, 0x8b, 0x8b, 0x8f, 0x90, 0x95, 0x96, 0x96, 0x8f, 0x9e, 0x8b, + 0xc0, 0x8b, 0xaa, 0x6a, 0x8b, 0x51, 0x8b, 0x68, 0x82, 0x5d, 0x7d, 0x6c, + 0x71, 0x50, 0x66, 0x74, 0x44, 0x8b, 0x80, 0x8b, 0x7f, 0x8c, 0x78, 0x8c, + 0x08, 0xcb, 0xf7, 0x83, 0x05, 0x0e, 0x6b, 0xf7, 0x7e, 0xf7, 0xcd, 0x15, + 0x4f, 0xfb, 0x6c, 0x05, 0x79, 0x52, 0x7d, 0x81, 0x46, 0x86, 0x08, 0x72, + 0xf7, 0xd6, 0xa4, 0x07, 0x4a, 0x8e, 0x7f, 0x92, 0x8b, 0xb0, 0x8b, 0x97, + 0x8d, 0x95, 0x91, 0xa2, 0x08, 0xbf, 0xf7, 0x53, 0xf7, 0x52, 0xf7, 0x9f, + 0x05, 0xad, 0xb9, 0x9e, 0x9a, 0xb1, 0x93, 0x08, 0xa4, 0xfb, 0x64, 0x72, + 0x07, 0xc0, 0x89, 0x99, 0x82, 0x8b, 0x68, 0x8b, 0x79, 0x85, 0x7e, 0x77, + 0x6e, 0x08, 0xfb, 0x15, 0xfb, 0x4e, 0x05, 0x84, 0xa1, 0x7c, 0xb7, 0x88, + 0x96, 0x82, 0xa8, 0x84, 0x9f, 0x88, 0x95, 0x74, 0xcd, 0x81, 0xaf, 0x8b, + 0x9c, 0x8b, 0xa7, 0x9a, 0x93, 0xc2, 0x8c, 0x08, 0xa4, 0xfb, 0xaf, 0x72, + 0x07, 0xbe, 0x84, 0x8e, 0x88, 0x9e, 0x56, 0x08, 0xe3, 0xfb, 0xa0, 0x05, + 0xc9, 0xf8, 0xb9, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, + 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0xf7, 0x68, 0x16, + 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, + 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xf8, 0x46, 0xf7, 0x13, 0x15, 0x62, + 0x54, 0x7c, 0x7c, 0x7b, 0x8b, 0x84, 0x8b, 0x86, 0x91, 0x8b, 0x94, 0x8b, + 0xa4, 0x95, 0xb5, 0xa3, 0xdc, 0x08, 0xd2, 0xf7, 0x80, 0xfb, 0x03, 0x84, + 0x79, 0x50, 0x05, 0x82, 0xbe, 0x75, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x0f, + 0xfb, 0x2a, 0xfb, 0x54, 0xfb, 0x30, 0x3f, 0xb6, 0x58, 0xcc, 0x1f, 0xc8, + 0x8b, 0xb9, 0xb0, 0xc4, 0xea, 0x80, 0x64, 0x88, 0x7d, 0x8b, 0x7d, 0x08, + 0x66, 0xa9, 0x6e, 0xb0, 0x1e, 0xba, 0x8b, 0xba, 0xb2, 0xc4, 0xe2, 0x08, + 0x76, 0x9a, 0x05, 0xfb, 0x3c, 0xf7, 0xb9, 0x15, 0xa1, 0x89, 0x9a, 0x79, + 0x8b, 0x70, 0x8b, 0x50, 0x69, 0xfb, 0x05, 0x65, 0x47, 0x70, 0x5b, 0x6d, + 0x70, 0x70, 0x8b, 0x71, 0x8b, 0x78, 0xa2, 0x8b, 0xaa, 0x8b, 0xbf, 0xac, + 0xef, 0xb4, 0xd5, 0x08, 0xa9, 0xc0, 0xac, 0xaa, 0xa6, 0x89, 0x08, 0x42, + 0xf7, 0x7f, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, + 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0xf7, 0x68, 0x16, 0x68, + 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, + 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xf8, 0x46, 0xf7, 0x13, 0x15, 0x62, 0x54, + 0x7c, 0x7c, 0x7b, 0x8b, 0x84, 0x8b, 0x86, 0x91, 0x8b, 0x94, 0x8b, 0xa4, + 0x95, 0xb5, 0xa3, 0xdc, 0x08, 0xd2, 0xf7, 0x80, 0xfb, 0x03, 0x84, 0x79, + 0x50, 0x05, 0x82, 0xbe, 0x75, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x0f, 0xfb, + 0x2a, 0xfb, 0x54, 0xfb, 0x30, 0x3f, 0xb6, 0x58, 0xcc, 0x1f, 0xc8, 0x8b, + 0xb9, 0xb0, 0xc4, 0xea, 0x80, 0x64, 0x88, 0x7d, 0x8b, 0x7d, 0x08, 0x66, + 0xa9, 0x6e, 0xb0, 0x1e, 0xba, 0x8b, 0xba, 0xb2, 0xc4, 0xe2, 0x08, 0x76, + 0x9a, 0x05, 0xfb, 0x3c, 0xf7, 0xb9, 0x15, 0xa1, 0x89, 0x9a, 0x79, 0x8b, + 0x70, 0x8b, 0x50, 0x69, 0xfb, 0x05, 0x65, 0x47, 0x70, 0x5b, 0x6d, 0x70, + 0x70, 0x8b, 0x71, 0x8b, 0x78, 0xa2, 0x8b, 0xaa, 0x8b, 0xbf, 0xac, 0xef, + 0xb4, 0xd5, 0x08, 0xa9, 0xc0, 0xac, 0xaa, 0xa6, 0x89, 0x08, 0x91, 0xeb, + 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, + 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, + 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xf8, 0x46, 0xf7, 0x13, + 0x15, 0x62, 0x54, 0x7c, 0x7c, 0x7b, 0x8b, 0x84, 0x8b, 0x86, 0x91, 0x8b, + 0x94, 0x8b, 0xa4, 0x95, 0xb5, 0xa3, 0xdc, 0x08, 0xd2, 0xf7, 0x80, 0xfb, + 0x03, 0x84, 0x79, 0x50, 0x05, 0x82, 0xbe, 0x75, 0xa0, 0x60, 0x8b, 0x08, + 0xfb, 0x0f, 0xfb, 0x2a, 0xfb, 0x54, 0xfb, 0x30, 0x3f, 0xb6, 0x58, 0xcc, + 0x1f, 0xc8, 0x8b, 0xb9, 0xb0, 0xc4, 0xea, 0x80, 0x64, 0x88, 0x7d, 0x8b, + 0x7d, 0x08, 0x66, 0xa9, 0x6e, 0xb0, 0x1e, 0xba, 0x8b, 0xba, 0xb2, 0xc4, + 0xe2, 0x08, 0x76, 0x9a, 0x05, 0xfb, 0x3c, 0xf7, 0xb9, 0x15, 0xa1, 0x89, + 0x9a, 0x79, 0x8b, 0x70, 0x8b, 0x50, 0x69, 0xfb, 0x05, 0x65, 0x47, 0x70, + 0x5b, 0x6d, 0x70, 0x70, 0x8b, 0x71, 0x8b, 0x78, 0xa2, 0x8b, 0xaa, 0x8b, + 0xbf, 0xac, 0xef, 0xb4, 0xd5, 0x08, 0xa9, 0xc0, 0xac, 0xaa, 0xa6, 0x89, + 0x08, 0xf7, 0x07, 0xeb, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, 0x7a, 0xa0, + 0x77, 0x98, 0x77, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, 0x8b, 0x7c, + 0x97, 0x7a, 0xa2, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, 0x05, 0x0e, + 0xf8, 0x46, 0xf7, 0x13, 0x15, 0x62, 0x54, 0x7c, 0x7c, 0x7b, 0x8b, 0x84, + 0x8b, 0x86, 0x91, 0x8b, 0x94, 0x8b, 0xa4, 0x95, 0xb5, 0xa3, 0xdc, 0x08, + 0xd2, 0xf7, 0x80, 0xfb, 0x03, 0x84, 0x79, 0x50, 0x05, 0x82, 0xbe, 0x75, + 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x0f, 0xfb, 0x2a, 0xfb, 0x54, 0xfb, 0x30, + 0x3f, 0xb6, 0x58, 0xcc, 0x1f, 0xc8, 0x8b, 0xb9, 0xb0, 0xc4, 0xea, 0x80, + 0x64, 0x88, 0x7d, 0x8b, 0x7d, 0x08, 0x66, 0xa9, 0x6e, 0xb0, 0x1e, 0xba, + 0x8b, 0xba, 0xb2, 0xc4, 0xe2, 0x08, 0x76, 0x9a, 0x05, 0xfb, 0x3c, 0xf7, + 0xb9, 0x15, 0xa1, 0x89, 0x9a, 0x79, 0x8b, 0x70, 0x8b, 0x50, 0x69, 0xfb, + 0x05, 0x65, 0x47, 0x70, 0x5b, 0x6d, 0x70, 0x70, 0x8b, 0x71, 0x8b, 0x78, + 0xa2, 0x8b, 0xaa, 0x8b, 0xbf, 0xac, 0xef, 0xb4, 0xd5, 0x08, 0xa9, 0xc0, + 0xac, 0xaa, 0xa6, 0x89, 0x08, 0xf7, 0x1a, 0xeb, 0x15, 0xbe, 0x8b, 0x35, + 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, 0x42, 0xc4, 0x8b, 0xf7, 0x17, + 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xf8, 0x46, 0xf7, 0x13, 0x15, 0x62, 0x54, + 0x7c, 0x7c, 0x7b, 0x8b, 0x84, 0x8b, 0x86, 0x91, 0x8b, 0x94, 0x8b, 0xa4, + 0x95, 0xb5, 0xa3, 0xdc, 0x08, 0xd2, 0xf7, 0x80, 0xfb, 0x03, 0x84, 0x79, + 0x50, 0x05, 0x82, 0xbe, 0x75, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x0f, 0xfb, + 0x2a, 0xfb, 0x54, 0xfb, 0x30, 0x3f, 0xb6, 0x58, 0xcc, 0x1f, 0xc8, 0x8b, + 0xb9, 0xb0, 0xc4, 0xea, 0x80, 0x64, 0x88, 0x7d, 0x8b, 0x7d, 0x08, 0x66, + 0xa9, 0x6e, 0xb0, 0x1e, 0xba, 0x8b, 0xba, 0xb2, 0xc4, 0xe2, 0x08, 0x76, + 0x9a, 0x05, 0xfb, 0x3c, 0xf7, 0xb9, 0x15, 0xa1, 0x89, 0x9a, 0x79, 0x8b, + 0x70, 0x8b, 0x50, 0x69, 0xfb, 0x05, 0x65, 0x47, 0x70, 0x5b, 0x6d, 0x70, + 0x70, 0x8b, 0x71, 0x8b, 0x78, 0xa2, 0x8b, 0xaa, 0x8b, 0xbf, 0xac, 0xef, + 0xb4, 0xd5, 0x08, 0xa9, 0xc0, 0xac, 0xaa, 0xa6, 0x89, 0x08, 0xf7, 0x4c, + 0xf7, 0x7f, 0x15, 0x7c, 0x6c, 0x7e, 0x80, 0x74, 0x8b, 0x80, 0x8b, 0x7a, + 0x90, 0x71, 0x96, 0x08, 0x62, 0x9d, 0x6b, 0x93, 0x73, 0x8b, 0x52, 0x8b, + 0x5d, 0x5d, 0x7e, 0x43, 0x08, 0xb3, 0x06, 0x98, 0xab, 0x98, 0x96, 0xa1, + 0x8b, 0x96, 0x8b, 0x99, 0x88, 0x98, 0x86, 0x08, 0xc6, 0x74, 0x05, 0xa5, + 0x81, 0x97, 0x88, 0x9e, 0x8b, 0xc7, 0x8b, 0xae, 0xaf, 0xa1, 0xde, 0x08, + 0x62, 0x06, 0x0e, 0xf8, 0x46, 0xf7, 0x13, 0x15, 0x62, 0x54, 0x7c, 0x7c, + 0x7b, 0x8b, 0x84, 0x8b, 0x86, 0x91, 0x8b, 0x94, 0x8b, 0xa4, 0x95, 0xb5, + 0xa3, 0xdc, 0x08, 0xd2, 0xf7, 0x80, 0xfb, 0x03, 0x84, 0x79, 0x50, 0x05, + 0x82, 0xbe, 0x75, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x0f, 0xfb, 0x2a, 0xfb, + 0x54, 0xfb, 0x30, 0x3f, 0xb6, 0x58, 0xcc, 0x1f, 0xc8, 0x8b, 0xb9, 0xb0, + 0xc4, 0xea, 0x80, 0x64, 0x88, 0x7d, 0x8b, 0x7d, 0x08, 0x66, 0xa9, 0x6e, + 0xb0, 0x1e, 0xba, 0x8b, 0xba, 0xb2, 0xc4, 0xe2, 0x08, 0x76, 0x9a, 0x05, + 0xfb, 0x3c, 0xf7, 0xb9, 0x15, 0xa1, 0x89, 0x9a, 0x79, 0x8b, 0x70, 0x8b, + 0x50, 0x69, 0xfb, 0x05, 0x65, 0x47, 0x70, 0x5b, 0x6d, 0x70, 0x70, 0x8b, + 0x71, 0x8b, 0x78, 0xa2, 0x8b, 0xaa, 0x8b, 0xbf, 0xac, 0xef, 0xb4, 0xd5, + 0x08, 0xa9, 0xc0, 0xac, 0xaa, 0xa6, 0x89, 0x08, 0xbe, 0xf7, 0xe2, 0x15, + 0x51, 0x5a, 0x5b, 0x52, 0x4f, 0xbb, 0x5a, 0xc5, 0xc7, 0xbb, 0xbb, 0xc6, + 0xc6, 0x5b, 0xbb, 0x50, 0x1f, 0x8a, 0x5b, 0x15, 0xac, 0xa6, 0x70, 0x6a, + 0x6b, 0x6f, 0x71, 0x6b, 0x6b, 0x71, 0xa6, 0xab, 0xaa, 0xa6, 0xa7, 0xaa, + 0x1f, 0x0e, 0xfb, 0x5b, 0xf7, 0x16, 0x7f, 0x15, 0x92, 0x8a, 0x90, 0x8b, + 0x91, 0x8b, 0xb7, 0x8b, 0xb7, 0x9b, 0xac, 0xa8, 0xa5, 0xa1, 0x9b, 0x9e, + 0xae, 0xbd, 0x08, 0x6f, 0x9d, 0x05, 0x5b, 0x48, 0x6c, 0x74, 0x60, 0x8b, + 0x60, 0x8b, 0x6d, 0xaf, 0x8b, 0xc1, 0x8b, 0xc9, 0xa5, 0xe5, 0xaf, 0xcc, + 0xa6, 0xba, 0xa8, 0xa3, 0xa9, 0x8b, 0x97, 0x8b, 0x95, 0x84, 0x8b, 0x81, + 0x8b, 0x87, 0x89, 0x85, 0x85, 0x82, 0x08, 0x82, 0x7b, 0x87, 0x80, 0x8b, + 0x7f, 0x08, 0x6d, 0xa4, 0x75, 0xac, 0xaf, 0xa5, 0xa8, 0xb4, 0xc0, 0x5e, + 0xb0, 0x48, 0xfb, 0x21, 0xfb, 0x24, 0xfb, 0x38, 0xfb, 0x34, 0x1e, 0x8b, + 0x47, 0xae, 0x57, 0xc8, 0x75, 0x08, 0x4f, 0x33, 0x98, 0x7f, 0x05, 0x97, + 0x8e, 0x93, 0x8c, 0x95, 0x8b, 0x08, 0xa8, 0x9d, 0x7d, 0x75, 0x72, 0x75, + 0x7b, 0x69, 0x1f, 0x75, 0x8b, 0x7a, 0x8f, 0x6f, 0x98, 0x08, 0x75, 0x6a, + 0x05, 0xb7, 0x79, 0xab, 0x84, 0xaf, 0x8b, 0x08, 0xd2, 0xc0, 0xb0, 0xbd, + 0xb5, 0x65, 0xa9, 0x57, 0x1f, 0x81, 0x8b, 0x85, 0x8a, 0x81, 0x89, 0x08, + 0xad, 0xbd, 0x05, 0x0e, 0xfb, 0x5b, 0xf7, 0xd1, 0xf7, 0x22, 0x15, 0x5c, + 0x46, 0x6f, 0x75, 0x61, 0x8b, 0x60, 0x8b, 0x75, 0xa7, 0x8b, 0xc1, 0x8b, + 0x9b, 0x8d, 0x98, 0x8f, 0x9f, 0xf3, 0x9f, 0xbc, 0xa1, 0xbd, 0xb9, 0xae, + 0xab, 0x9e, 0xb1, 0x8b, 0xae, 0x08, 0xbe, 0x5f, 0xaf, 0x4e, 0xfb, 0x24, + 0xfb, 0x24, 0xfb, 0x37, 0xfb, 0x39, 0x37, 0xcb, 0x4c, 0xe2, 0x1e, 0xd7, + 0x8b, 0xc1, 0xb2, 0xc7, 0xee, 0x08, 0x6e, 0x9c, 0x05, 0xfb, 0x3d, 0xd3, + 0x15, 0xaf, 0xf7, 0x1e, 0xb9, 0xd8, 0xbb, 0x8b, 0x9e, 0x8b, 0x94, 0x7f, + 0x8b, 0x75, 0x8b, 0x3f, 0x5b, 0x4a, 0x3e, 0x6e, 0x84, 0x89, 0x7c, 0x86, + 0x80, 0x87, 0x08, 0x9c, 0xf8, 0x4d, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, + 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0x1f, 0xaf, 0x6d, 0xa9, 0x67, + 0x1e, 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, + 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xfb, 0x5b, + 0xf7, 0xd1, 0xf7, 0x22, 0x15, 0x5c, 0x46, 0x6f, 0x75, 0x61, 0x8b, 0x60, + 0x8b, 0x75, 0xa7, 0x8b, 0xc1, 0x8b, 0x9b, 0x8d, 0x98, 0x8f, 0x9f, 0xf3, + 0x9f, 0xbc, 0xa1, 0xbd, 0xb9, 0xae, 0xab, 0x9e, 0xb1, 0x8b, 0xae, 0x08, + 0xbe, 0x5f, 0xaf, 0x4e, 0xfb, 0x24, 0xfb, 0x24, 0xfb, 0x37, 0xfb, 0x39, + 0x37, 0xcb, 0x4c, 0xe2, 0x1e, 0xd7, 0x8b, 0xc1, 0xb2, 0xc7, 0xee, 0x08, + 0x6e, 0x9c, 0x05, 0xfb, 0x3d, 0xd3, 0x15, 0xaf, 0xf7, 0x1e, 0xb9, 0xd8, + 0xbb, 0x8b, 0x9e, 0x8b, 0x94, 0x7f, 0x8b, 0x75, 0x8b, 0x3f, 0x5b, 0x4a, + 0x3e, 0x6e, 0x84, 0x89, 0x7c, 0x86, 0x80, 0x87, 0x08, 0xeb, 0xf7, 0xc2, + 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, + 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, + 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xfb, 0x5b, 0xf7, 0xd1, + 0xf7, 0x22, 0x15, 0x5c, 0x46, 0x6f, 0x75, 0x61, 0x8b, 0x60, 0x8b, 0x75, + 0xa7, 0x8b, 0xc1, 0x8b, 0x9b, 0x8d, 0x98, 0x8f, 0x9f, 0xf3, 0x9f, 0xbc, + 0xa1, 0xbd, 0xb9, 0xae, 0xab, 0x9e, 0xb1, 0x8b, 0xae, 0x08, 0xbe, 0x5f, + 0xaf, 0x4e, 0xfb, 0x24, 0xfb, 0x24, 0xfb, 0x37, 0xfb, 0x39, 0x37, 0xcb, + 0x4c, 0xe2, 0x1e, 0xd7, 0x8b, 0xc1, 0xb2, 0xc7, 0xee, 0x08, 0x6e, 0x9c, + 0x05, 0xfb, 0x3d, 0xd3, 0x15, 0xaf, 0xf7, 0x1e, 0xb9, 0xd8, 0xbb, 0x8b, + 0x9e, 0x8b, 0x94, 0x7f, 0x8b, 0x75, 0x8b, 0x3f, 0x5b, 0x4a, 0x3e, 0x6e, + 0x84, 0x89, 0x7c, 0x86, 0x80, 0x87, 0x08, 0xf7, 0x6f, 0xf7, 0xc2, 0x15, + 0xfb, 0x03, 0xf7, 0x27, 0x05, 0x7a, 0xa0, 0x77, 0x98, 0x77, 0x8b, 0x73, + 0x8b, 0x76, 0x76, 0x8b, 0x73, 0x8b, 0x7c, 0x97, 0x7a, 0xa2, 0x7c, 0x08, + 0xf7, 0x19, 0x32, 0xb8, 0x8b, 0x05, 0x0e, 0xfb, 0x5b, 0xf7, 0xd1, 0xf7, + 0x22, 0x15, 0x5c, 0x46, 0x6f, 0x75, 0x61, 0x8b, 0x60, 0x8b, 0x75, 0xa7, + 0x8b, 0xc1, 0x8b, 0x9b, 0x8d, 0x98, 0x8f, 0x9f, 0xf3, 0x9f, 0xbc, 0xa1, + 0xbd, 0xb9, 0xae, 0xab, 0x9e, 0xb1, 0x8b, 0xae, 0x08, 0xbe, 0x5f, 0xaf, + 0x4e, 0xfb, 0x24, 0xfb, 0x24, 0xfb, 0x37, 0xfb, 0x39, 0x37, 0xcb, 0x4c, + 0xe2, 0x1e, 0xd7, 0x8b, 0xc1, 0xb2, 0xc7, 0xee, 0x08, 0x6e, 0x9c, 0x05, + 0xfb, 0x3d, 0xd3, 0x15, 0xaf, 0xf7, 0x1e, 0xb9, 0xd8, 0xbb, 0x8b, 0x9e, + 0x8b, 0x94, 0x7f, 0x8b, 0x75, 0x8b, 0x3f, 0x5b, 0x4a, 0x3e, 0x6e, 0x84, + 0x89, 0x7c, 0x86, 0x80, 0x87, 0x08, 0xf7, 0x74, 0xf7, 0xc2, 0x15, 0xbe, + 0x8b, 0x35, 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, 0x42, 0xc4, 0x8b, + 0xf7, 0x17, 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xfc, 0x01, 0xf7, 0x6c, 0xf7, + 0x21, 0x15, 0x7d, 0x77, 0x05, 0x71, 0x64, 0x74, 0x76, 0x7c, 0x8b, 0x83, + 0x8b, 0x84, 0x92, 0x8b, 0x93, 0x8b, 0x91, 0x91, 0xad, 0x8e, 0x97, 0x08, + 0xe6, 0xf7, 0xe2, 0x05, 0x55, 0x7f, 0x45, 0x81, 0x3d, 0x85, 0x08, 0x70, + 0x07, 0xb6, 0x9b, 0x83, 0x76, 0x1f, 0x8b, 0x83, 0x88, 0x7c, 0x87, 0x7a, + 0x08, 0x51, 0xfb, 0x6b, 0x05, 0x83, 0x6f, 0x86, 0x6f, 0x8b, 0x7e, 0x8b, + 0x66, 0xa7, 0x71, 0xb4, 0x8b, 0xc7, 0x8b, 0xb0, 0xa9, 0xd1, 0xf5, 0x08, + 0x75, 0x99, 0x05, 0xfb, 0x1a, 0xf8, 0x96, 0x15, 0x68, 0x6e, 0x6d, 0x67, + 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, + 0x1f, 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, + 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0xfc, 0x01, + 0xf7, 0x6c, 0xf7, 0x21, 0x15, 0x7d, 0x77, 0x05, 0x71, 0x64, 0x74, 0x76, + 0x7c, 0x8b, 0x83, 0x8b, 0x84, 0x92, 0x8b, 0x93, 0x8b, 0x91, 0x91, 0xad, + 0x8e, 0x97, 0x08, 0xe6, 0xf7, 0xe2, 0x05, 0x55, 0x7f, 0x45, 0x81, 0x3d, + 0x85, 0x08, 0x70, 0x07, 0xb6, 0x9b, 0x83, 0x76, 0x1f, 0x8b, 0x83, 0x88, + 0x7c, 0x87, 0x7a, 0x08, 0x51, 0xfb, 0x6b, 0x05, 0x83, 0x6f, 0x86, 0x6f, + 0x8b, 0x7e, 0x8b, 0x66, 0xa7, 0x71, 0xb4, 0x8b, 0xc7, 0x8b, 0xb0, 0xa9, + 0xd1, 0xf5, 0x08, 0x75, 0x99, 0x05, 0x54, 0xf8, 0x0b, 0x15, 0xf7, 0x2c, + 0xe2, 0x05, 0xa9, 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, + 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, + 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xfc, 0x01, 0xf7, 0x6c, 0xf7, 0x21, 0x15, + 0x7d, 0x77, 0x05, 0x71, 0x64, 0x74, 0x76, 0x7c, 0x8b, 0x83, 0x8b, 0x84, + 0x92, 0x8b, 0x93, 0x8b, 0x93, 0x90, 0xa9, 0x8f, 0x99, 0x08, 0xe6, 0xf7, + 0xe2, 0x05, 0x55, 0x7f, 0x45, 0x81, 0x3d, 0x85, 0x08, 0x70, 0x07, 0xb6, + 0x9b, 0x83, 0x76, 0x1f, 0x8b, 0x83, 0x88, 0x7c, 0x87, 0x7a, 0x08, 0x51, + 0xfb, 0x6b, 0x05, 0x83, 0x6f, 0x86, 0x6f, 0x8b, 0x7e, 0x8b, 0x66, 0xa7, + 0x71, 0xb4, 0x8b, 0xc7, 0x8b, 0xb0, 0xaa, 0xd1, 0xf4, 0x08, 0x75, 0x99, + 0x05, 0xb7, 0xf8, 0x0b, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, 0x7b, 0xa1, + 0x76, 0x97, 0x78, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, 0x8b, 0x7c, + 0x97, 0x7a, 0xa1, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, 0x05, 0x0e, + 0xfc, 0x01, 0xf7, 0xa6, 0xf8, 0x98, 0x15, 0xbe, 0x8b, 0x35, 0xf7, 0x42, + 0x3a, 0x8b, 0xfb, 0x34, 0xfb, 0x42, 0xc4, 0x8b, 0xf7, 0x17, 0xea, 0xe3, + 0x2c, 0x05, 0x51, 0xfc, 0x0b, 0x15, 0x7d, 0x77, 0x05, 0x71, 0x64, 0x74, + 0x76, 0x7c, 0x8b, 0x83, 0x8b, 0x84, 0x92, 0x8b, 0x93, 0x8b, 0x91, 0x91, + 0xad, 0x8e, 0x97, 0x08, 0xe6, 0xf7, 0xe2, 0x05, 0x55, 0x7f, 0x45, 0x81, + 0x3d, 0x85, 0x08, 0x70, 0x07, 0xb6, 0x9b, 0x83, 0x76, 0x1f, 0x8b, 0x83, + 0x88, 0x7c, 0x87, 0x7a, 0x08, 0x51, 0xfb, 0x6b, 0x05, 0x83, 0x6e, 0x86, + 0x71, 0x8b, 0x7d, 0x8b, 0x65, 0xa7, 0x72, 0xb4, 0x8b, 0xc7, 0x8b, 0xb1, + 0xaa, 0xd0, 0xf4, 0x08, 0x75, 0x99, 0x05, 0x0e, 0x34, 0xf8, 0x6b, 0xf7, + 0x1b, 0x15, 0x63, 0x4d, 0x7e, 0x7d, 0x7a, 0x8b, 0x83, 0x8b, 0x85, 0x92, + 0x8b, 0x95, 0x8b, 0x95, 0x92, 0xa2, 0x9d, 0xc1, 0x08, 0xaf, 0xf7, 0x01, + 0x05, 0x9b, 0xb9, 0x95, 0xb8, 0x8b, 0xa3, 0x8b, 0xbb, 0x71, 0xa6, 0x5c, + 0x8b, 0x66, 0x8b, 0x67, 0x7c, 0x6f, 0x71, 0x67, 0x68, 0x78, 0x73, 0x48, + 0x28, 0x08, 0xcb, 0xf7, 0x5a, 0x05, 0x4b, 0x7d, 0x3b, 0x80, 0x53, 0x89, + 0x08, 0x70, 0x07, 0xb5, 0x8a, 0x97, 0x86, 0x8b, 0x78, 0x8b, 0x80, 0x7f, + 0x5c, 0x69, 0xfb, 0x0c, 0x08, 0x70, 0x2b, 0x6e, 0xfb, 0x00, 0xf7, 0x0d, + 0x8b, 0x05, 0xba, 0xf7, 0x41, 0xaf, 0xe2, 0xc9, 0xdc, 0x9f, 0xa6, 0xaa, + 0xa1, 0x9d, 0x8b, 0x97, 0x8b, 0x98, 0x80, 0x8b, 0x81, 0x8b, 0x88, 0x89, + 0x83, 0x88, 0x81, 0x08, 0x54, 0xfb, 0x3a, 0x05, 0x7b, 0x5b, 0x7f, 0x52, + 0x8b, 0x71, 0x8b, 0x66, 0xa5, 0x74, 0xb5, 0x8b, 0xc6, 0x8b, 0xb5, 0xad, + 0xc5, 0xec, 0x08, 0x75, 0x98, 0x05, 0x83, 0xf8, 0x9c, 0x15, 0x7c, 0x6c, + 0x7e, 0x80, 0x74, 0x8b, 0x80, 0x8b, 0x7a, 0x90, 0x71, 0x96, 0x08, 0x62, + 0x9d, 0x6b, 0x93, 0x73, 0x8b, 0x52, 0x8b, 0x5d, 0x5d, 0x7e, 0x43, 0x08, + 0xb3, 0x06, 0x98, 0xab, 0x98, 0x96, 0xa1, 0x8b, 0x96, 0x8b, 0x99, 0x88, + 0x98, 0x86, 0x08, 0xc6, 0x74, 0x05, 0xa5, 0x81, 0x97, 0x88, 0x9e, 0x8b, + 0xc7, 0x8b, 0xae, 0xaf, 0xa1, 0xde, 0x08, 0x62, 0x06, 0x0e, 0xf7, 0xb0, + 0xf8, 0x62, 0x15, 0xfb, 0x27, 0xfb, 0x20, 0xfb, 0x33, 0xfb, 0x3c, 0x36, + 0xce, 0x4c, 0xe7, 0xf7, 0x29, 0xf7, 0x1c, 0xf7, 0x2f, 0xf7, 0x3d, 0x1f, + 0xe3, 0x49, 0xca, 0x30, 0x1e, 0x82, 0x6e, 0x15, 0xa8, 0x9d, 0x75, 0x67, + 0x1f, 0x8b, 0x47, 0x6c, 0xfb, 0x16, 0x6b, 0x45, 0x6e, 0x4d, 0x6d, 0x6e, + 0x68, 0x8b, 0x6d, 0x8b, 0x78, 0xa3, 0x8b, 0xb1, 0x8b, 0xd9, 0xb0, 0xf7, + 0x26, 0xae, 0xc9, 0xa5, 0xb9, 0xa8, 0xa2, 0xab, 0x8b, 0x08, 0x34, 0xf7, + 0x72, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, + 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0xf7, 0x68, 0x16, 0x68, 0x6e, + 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0x1f, 0xaf, + 0x6d, 0xa9, 0x67, 0x1e, 0x0e, 0xf7, 0xb0, 0xf8, 0x62, 0x15, 0xfb, 0x27, + 0xfb, 0x20, 0xfb, 0x33, 0xfb, 0x3c, 0x36, 0xce, 0x4c, 0xe7, 0xf7, 0x29, + 0xf7, 0x1c, 0xf7, 0x2f, 0xf7, 0x3d, 0xe3, 0x49, 0xca, 0x30, 0x1f, 0x82, + 0x6e, 0x15, 0xa8, 0x9d, 0x75, 0x67, 0x1f, 0x8b, 0x47, 0x6c, 0xfb, 0x16, + 0x6b, 0x45, 0x6e, 0x4d, 0x6d, 0x6e, 0x68, 0x8b, 0x6d, 0x8b, 0x78, 0xa3, + 0x8b, 0xb1, 0x8b, 0xd9, 0xb0, 0xf7, 0x26, 0xae, 0xc9, 0xa5, 0xb9, 0xa8, + 0xa2, 0xab, 0x8b, 0x08, 0x88, 0xde, 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, + 0x9c, 0x94, 0x96, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, + 0x8b, 0x7a, 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, + 0x05, 0x0e, 0xf7, 0xb0, 0xf8, 0x62, 0x15, 0xfb, 0x27, 0xfb, 0x20, 0xfb, + 0x33, 0xfb, 0x3c, 0x36, 0xce, 0x4c, 0xe7, 0xf7, 0x29, 0xf7, 0x1c, 0xf7, + 0x2f, 0xf7, 0x3d, 0xe3, 0x49, 0xca, 0x30, 0x1f, 0x82, 0x6e, 0x15, 0xa8, + 0x9d, 0x75, 0x67, 0x1f, 0x8b, 0x47, 0x6c, 0xfb, 0x16, 0x6b, 0x45, 0x6e, + 0x4d, 0x6d, 0x6e, 0x68, 0x8b, 0x6d, 0x8b, 0x78, 0xa3, 0x8b, 0xb1, 0x8b, + 0xd9, 0xb0, 0xf7, 0x26, 0xae, 0xc9, 0xa5, 0xb9, 0xa8, 0xa2, 0xab, 0x8b, + 0x08, 0xf5, 0xde, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, 0x7a, 0xa0, 0x77, + 0x98, 0x77, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, 0x8b, 0x7c, 0x97, + 0x7a, 0xa2, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, 0x05, 0x0e, 0xf7, + 0xb0, 0xf8, 0x62, 0x15, 0xfb, 0x27, 0xfb, 0x20, 0xfb, 0x33, 0xfb, 0x3c, + 0x36, 0xce, 0x4c, 0xe7, 0xf7, 0x29, 0xf7, 0x1c, 0xf7, 0x2f, 0xf7, 0x3d, + 0xe3, 0x49, 0xca, 0x30, 0x1f, 0x82, 0x6e, 0x15, 0xa8, 0x9d, 0x75, 0x67, + 0x1f, 0x8b, 0x47, 0x6c, 0xfb, 0x16, 0x6b, 0x45, 0x6e, 0x4d, 0x6d, 0x6e, + 0x68, 0x8b, 0x6d, 0x8b, 0x78, 0xa3, 0x8b, 0xb1, 0x8b, 0xd9, 0xb0, 0xf7, + 0x26, 0xae, 0xc9, 0xa5, 0xb9, 0xa8, 0xa2, 0xab, 0x8b, 0x08, 0xf7, 0x11, + 0xde, 0x15, 0xbe, 0x8b, 0x35, 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, + 0x42, 0xc4, 0x8b, 0xf7, 0x17, 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xf7, 0xb0, + 0xf8, 0x62, 0x15, 0xfb, 0x27, 0xfb, 0x20, 0xfb, 0x33, 0xfb, 0x3c, 0x36, + 0xce, 0x4c, 0xe7, 0xf7, 0x29, 0xf7, 0x1c, 0xf7, 0x2f, 0xf7, 0x3d, 0x1f, + 0xe3, 0x49, 0xca, 0x30, 0x1e, 0x82, 0x6e, 0x15, 0xa8, 0x9d, 0x75, 0x67, + 0x1f, 0x8b, 0x47, 0x6c, 0xfb, 0x16, 0x6b, 0x45, 0x6e, 0x4d, 0x6d, 0x6e, + 0x68, 0x8b, 0x6d, 0x8b, 0x78, 0xa3, 0x8b, 0xb1, 0x8b, 0xd9, 0xb0, 0xf7, + 0x26, 0xae, 0xc9, 0xa5, 0xb9, 0xa8, 0xa2, 0xab, 0x8b, 0x08, 0xf7, 0x43, + 0xf7, 0x72, 0x15, 0x7c, 0x6c, 0x7e, 0x80, 0x74, 0x8b, 0x80, 0x8b, 0x7a, + 0x90, 0x71, 0x96, 0x08, 0x62, 0x9d, 0x6b, 0x93, 0x73, 0x8b, 0x52, 0x8b, + 0x5d, 0x5d, 0x7e, 0x43, 0x08, 0xb3, 0x06, 0x98, 0xab, 0x98, 0x96, 0xa1, + 0x8b, 0x96, 0x8b, 0x99, 0x88, 0x98, 0x86, 0x08, 0xc6, 0x74, 0x05, 0xa5, + 0x81, 0x97, 0x88, 0x9e, 0x8b, 0xc7, 0x8b, 0xae, 0xaf, 0xa1, 0xde, 0x08, + 0x62, 0x06, 0x0e, 0xfb, 0x92, 0xf7, 0xe1, 0xf8, 0x61, 0x15, 0x6e, 0x06, + 0x80, 0x78, 0x88, 0x89, 0x7c, 0x8b, 0x82, 0x8b, 0x82, 0x8d, 0x79, 0x92, + 0x72, 0x95, 0x7e, 0x8e, 0x77, 0x8b, 0x3a, 0x8b, 0x56, 0x59, 0x8b, 0x3f, + 0x8b, 0x55, 0x99, 0x6e, 0xcd, 0x3d, 0xb1, 0x5e, 0x9d, 0x69, 0x8b, 0x72, + 0x08, 0x6d, 0x72, 0x73, 0x6b, 0x1e, 0x74, 0x8b, 0x76, 0x96, 0x7b, 0x9f, + 0x77, 0xa4, 0x83, 0xa2, 0x83, 0xc1, 0x08, 0x70, 0x8e, 0x75, 0xfb, 0x3a, + 0xa6, 0x8b, 0x05, 0x8f, 0x97, 0x97, 0x93, 0x98, 0x8b, 0x92, 0x8b, 0x96, + 0x88, 0x98, 0x86, 0xa3, 0x83, 0x9e, 0x87, 0x9f, 0x8b, 0xdf, 0x8b, 0xcb, + 0xc4, 0x8b, 0xd6, 0x8b, 0xb8, 0x72, 0xbc, 0x53, 0xcc, 0x65, 0xb8, 0x79, + 0xaa, 0x8b, 0xa1, 0x08, 0xab, 0xa0, 0xa0, 0xab, 0x1e, 0xb9, 0x8b, 0xa5, + 0x67, 0x9b, 0x38, 0x08, 0xa6, 0x89, 0xa2, 0xf7, 0x2d, 0x05, 0xf5, 0xf7, + 0x79, 0x15, 0x53, 0x8b, 0xfb, 0x1b, 0x2a, 0x30, 0xec, 0x59, 0x8b, 0xe3, + 0xfb, 0x42, 0xdd, 0x8b, 0xf7, 0x36, 0xf7, 0x42, 0x05, 0x0e, 0x34, 0xf8, + 0x6b, 0xf7, 0x19, 0x15, 0x68, 0x56, 0x77, 0x76, 0x7a, 0x8b, 0x83, 0x8b, + 0x85, 0x93, 0x8b, 0x94, 0x8b, 0x95, 0x8b, 0x8b, 0xa4, 0xea, 0x08, 0xd9, + 0xf7, 0xa0, 0xfb, 0x0a, 0x8b, 0x05, 0x53, 0xfb, 0x55, 0x6e, 0x49, 0x52, + 0x43, 0x6c, 0x65, 0x75, 0x7a, 0x77, 0x8b, 0x7d, 0x8b, 0x84, 0x93, 0x8b, + 0x9c, 0x8b, 0x9a, 0x8d, 0x93, 0x98, 0xb6, 0x08, 0xe9, 0xf7, 0xc8, 0x05, + 0x85, 0x8a, 0x85, 0x8a, 0x7b, 0x88, 0x41, 0x7e, 0x50, 0x83, 0x5b, 0x89, + 0x08, 0x70, 0x07, 0xb9, 0x88, 0x95, 0x86, 0x8b, 0x77, 0x8b, 0x7b, 0x86, + 0x6f, 0x82, 0x6e, 0x08, 0x63, 0xfb, 0x19, 0x05, 0x7d, 0x5b, 0x84, 0x67, + 0x8b, 0x73, 0x8b, 0x5a, 0xa5, 0x72, 0xbc, 0x8b, 0xce, 0x8b, 0xa9, 0xa5, + 0xf2, 0xf7, 0x24, 0x79, 0x54, 0x85, 0x70, 0x8b, 0x6f, 0x8b, 0x63, 0xa0, + 0x77, 0xb7, 0x8b, 0xc7, 0x8b, 0xbc, 0xb3, 0xbf, 0xe4, 0x08, 0x76, 0x98, + 0x05, 0xfb, 0x93, 0xf8, 0x9e, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, + 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, 0x1f, 0xaf, 0x6d, 0xa9, 0x67, 0x1e, + 0xf7, 0x68, 0x16, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, + 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0x0e, 0x34, 0xf8, 0x6b, + 0xf7, 0x19, 0x15, 0x68, 0x56, 0x77, 0x76, 0x7a, 0x8b, 0x83, 0x8b, 0x85, + 0x93, 0x8b, 0x94, 0x8b, 0x95, 0x8b, 0x8b, 0xa4, 0xea, 0x08, 0xd9, 0xf7, + 0xa0, 0xfb, 0x0a, 0x8b, 0x05, 0x53, 0xfb, 0x55, 0x6e, 0x49, 0x52, 0x43, + 0x6c, 0x65, 0x75, 0x7a, 0x77, 0x8b, 0x7d, 0x8b, 0x84, 0x93, 0x8b, 0x9c, + 0x8b, 0x9a, 0x8d, 0x93, 0x98, 0xb6, 0x08, 0xe9, 0xf7, 0xc8, 0x05, 0x85, + 0x8a, 0x85, 0x8a, 0x7b, 0x88, 0x41, 0x7e, 0x50, 0x83, 0x5b, 0x89, 0x08, + 0x70, 0x07, 0xb9, 0x88, 0x95, 0x86, 0x8b, 0x77, 0x8b, 0x7b, 0x86, 0x6f, + 0x82, 0x6e, 0x08, 0x63, 0xfb, 0x19, 0x05, 0x7d, 0x5b, 0x84, 0x67, 0x8b, + 0x73, 0x8b, 0x5a, 0xa5, 0x72, 0xbc, 0x8b, 0xce, 0x8b, 0xa9, 0xa5, 0xf2, + 0xf7, 0x24, 0x79, 0x54, 0x85, 0x70, 0x8b, 0x6f, 0x8b, 0x63, 0xa0, 0x77, + 0xb7, 0x8b, 0xc7, 0x8b, 0xbc, 0xb3, 0xbf, 0xe4, 0x08, 0x76, 0x98, 0x05, + 0xfb, 0x3f, 0xf8, 0x13, 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9d, 0x94, + 0x95, 0x8b, 0x9e, 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, + 0x7f, 0x68, 0x65, 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, + 0x34, 0xf8, 0x6b, 0xf7, 0x19, 0x15, 0x68, 0x56, 0x77, 0x76, 0x7a, 0x8b, + 0x83, 0x8b, 0x85, 0x93, 0x8b, 0x94, 0x8b, 0x95, 0x8b, 0x8b, 0xa4, 0xea, + 0x08, 0xd9, 0xf7, 0xa0, 0xfb, 0x0a, 0x8b, 0x05, 0x53, 0xfb, 0x55, 0x6e, + 0x49, 0x52, 0x43, 0x6c, 0x65, 0x75, 0x7a, 0x77, 0x8b, 0x7d, 0x8b, 0x84, + 0x93, 0x8b, 0x9c, 0x8b, 0x9a, 0x8d, 0x93, 0x98, 0xb6, 0x08, 0xe9, 0xf7, + 0xc8, 0x05, 0x85, 0x8a, 0x85, 0x8a, 0x7b, 0x88, 0x41, 0x7e, 0x50, 0x83, + 0x5b, 0x89, 0x08, 0x70, 0x07, 0xb9, 0x88, 0x95, 0x86, 0x8b, 0x77, 0x8b, + 0x7b, 0x86, 0x6f, 0x82, 0x6e, 0x08, 0x63, 0xfb, 0x19, 0x05, 0x7d, 0x5b, + 0x84, 0x67, 0x8b, 0x73, 0x8b, 0x5a, 0xa5, 0x72, 0xbc, 0x8b, 0xce, 0x8b, + 0xa9, 0xa5, 0xf2, 0xf7, 0x24, 0x79, 0x54, 0x85, 0x70, 0x8b, 0x6f, 0x8b, + 0x63, 0xa0, 0x77, 0xb7, 0x8b, 0xc7, 0x8b, 0xbc, 0xb3, 0xbf, 0xe4, 0x08, + 0x76, 0x98, 0x05, 0x4d, 0xf8, 0x13, 0x15, 0xfb, 0x03, 0xf7, 0x27, 0x05, + 0x7a, 0xa0, 0x77, 0x98, 0x77, 0x8b, 0x73, 0x8b, 0x76, 0x76, 0x8b, 0x73, + 0x8b, 0x7c, 0x97, 0x7a, 0xa2, 0x7c, 0x08, 0xf7, 0x19, 0x32, 0xb8, 0x8b, + 0x05, 0x0e, 0x34, 0xf8, 0x6b, 0xf7, 0x19, 0x15, 0x68, 0x56, 0x77, 0x76, + 0x7a, 0x8b, 0x83, 0x8b, 0x85, 0x93, 0x8b, 0x94, 0x8b, 0x95, 0x8b, 0x8b, + 0xa4, 0xea, 0x08, 0xd9, 0xf7, 0xa0, 0xfb, 0x0a, 0x8b, 0x05, 0x53, 0xfb, + 0x55, 0x6e, 0x49, 0x52, 0x43, 0x6c, 0x65, 0x75, 0x7a, 0x77, 0x8b, 0x7d, + 0x8b, 0x84, 0x93, 0x8b, 0x9c, 0x8b, 0x9a, 0x8d, 0x93, 0x98, 0xb6, 0x08, + 0xe9, 0xf7, 0xc8, 0x05, 0x85, 0x8a, 0x85, 0x8a, 0x7b, 0x88, 0x41, 0x7e, + 0x50, 0x83, 0x5b, 0x89, 0x08, 0x70, 0x07, 0xb9, 0x88, 0x95, 0x86, 0x8b, + 0x77, 0x8b, 0x7b, 0x86, 0x6f, 0x82, 0x6e, 0x08, 0x63, 0xfb, 0x19, 0x05, + 0x7d, 0x5b, 0x84, 0x67, 0x8b, 0x73, 0x8b, 0x5a, 0xa5, 0x72, 0xbc, 0x8b, + 0xce, 0x8b, 0xa9, 0xa5, 0xf2, 0xf7, 0x24, 0x79, 0x54, 0x85, 0x70, 0x8b, + 0x6f, 0x8b, 0x63, 0xa0, 0x77, 0xb7, 0x8b, 0xc7, 0x8b, 0xbc, 0xb3, 0xbf, + 0xe4, 0x08, 0x76, 0x98, 0x05, 0x5c, 0xf8, 0x13, 0x15, 0xbe, 0x8b, 0x35, + 0xf7, 0x42, 0x3a, 0x8b, 0xfb, 0x34, 0xfb, 0x42, 0xc4, 0x8b, 0xf7, 0x17, + 0xea, 0xe3, 0x2c, 0x05, 0x0e, 0xfb, 0x5b, 0x99, 0xf8, 0x2f, 0x15, 0x9d, + 0x8b, 0x90, 0x8a, 0x92, 0x87, 0x9c, 0x81, 0x9b, 0x62, 0x9a, 0x44, 0xac, + 0xfb, 0x34, 0x9c, 0x2a, 0x8b, 0x6c, 0x8b, 0x74, 0x82, 0x73, 0x79, 0x72, + 0x76, 0x6f, 0x70, 0x76, 0x7a, 0x8b, 0x84, 0x8b, 0x78, 0x92, 0x83, 0x92, + 0x08, 0x7a, 0x97, 0x72, 0x94, 0x79, 0x8b, 0x08, 0x71, 0x73, 0x71, 0x6e, + 0x6a, 0xa6, 0x70, 0xae, 0x1f, 0xc2, 0x8b, 0xcc, 0xb3, 0xc2, 0xcd, 0xf7, + 0x16, 0xf7, 0x33, 0xf7, 0x0b, 0xf7, 0x81, 0x8b, 0xf0, 0x08, 0xad, 0x6e, + 0xa9, 0x6a, 0x6d, 0x70, 0x70, 0x6c, 0x1e, 0x8b, 0x73, 0x92, 0x7f, 0xa3, + 0x79, 0x9d, 0x7d, 0x91, 0x83, 0x8b, 0x7e, 0x8b, 0x6d, 0x79, 0x61, 0x46, + 0xfb, 0x19, 0x08, 0x7f, 0xd6, 0x05, 0x75, 0xf7, 0x0a, 0x71, 0xf7, 0x04, + 0x79, 0xba, 0x5b, 0x7f, 0x67, 0x85, 0x4a, 0x85, 0x08, 0x70, 0x07, 0xf7, + 0x7a, 0xf4, 0x15, 0xf7, 0x2c, 0xe2, 0x05, 0xa9, 0x9d, 0x94, 0x95, 0x8b, + 0x9e, 0x8b, 0xa4, 0x75, 0xa1, 0x71, 0x8b, 0x79, 0x8b, 0x7a, 0x7f, 0x68, + 0x65, 0x08, 0xfb, 0x0e, 0xfb, 0x17, 0xbc, 0x8b, 0x05, 0x0e, 0xfb, 0x92, + 0x98, 0xf7, 0xbb, 0x15, 0xa7, 0x88, 0x05, 0x9c, 0xb9, 0x9b, 0x9a, 0xa9, + 0x8b, 0x08, 0xf7, 0x25, 0x8b, 0xfb, 0xb8, 0xfb, 0xf6, 0xa4, 0x75, 0x05, + 0x93, 0x91, 0x93, 0x90, 0x8e, 0x8e, 0x9a, 0x96, 0x92, 0x8e, 0x96, 0x8b, + 0x9d, 0x8b, 0x9f, 0x82, 0xae, 0x73, 0xc1, 0x67, 0xb0, 0x7d, 0xb3, 0x8b, + 0x08, 0xc8, 0xba, 0xb3, 0xbe, 0xa7, 0x72, 0xa3, 0x6f, 0x70, 0x74, 0x73, + 0x6f, 0x1f, 0x8b, 0x80, 0x8f, 0x83, 0x94, 0x7f, 0x90, 0x84, 0x8d, 0x86, + 0x8b, 0x88, 0x8b, 0x82, 0x81, 0x84, 0x7f, 0x8b, 0x79, 0x8b, 0x7f, 0x97, + 0x7a, 0xae, 0x6b, 0xc8, 0x73, 0xa2, 0x58, 0xa1, 0x08, 0xf7, 0xad, 0xf7, + 0xe3, 0x8b, 0x95, 0xfb, 0xcc, 0x8b, 0x60, 0xfb, 0x2e, 0x05, 0xf8, 0x2f, + 0xf8, 0x1f, 0x15, 0x53, 0x8b, 0xfb, 0x1b, 0x2a, 0x30, 0xec, 0x59, 0x8b, + 0xe3, 0xfb, 0x42, 0xdd, 0x8b, 0xf7, 0x36, 0xf7, 0x42, 0x05, 0x0e, 0xf7, + 0xaf, 0xf8, 0xd2, 0x15, 0xb2, 0x59, 0x9e, 0x5d, 0x8f, 0x55, 0x08, 0x89, + 0x87, 0x05, 0x78, 0xa8, 0x76, 0x98, 0x6c, 0x8b, 0x08, 0xfb, 0x1e, 0xfb, + 0x1d, 0xfb, 0x37, 0xfb, 0x39, 0x37, 0xcf, 0x4c, 0xe5, 0xf7, 0x2f, 0xf7, + 0x17, 0xf7, 0x44, 0xf7, 0x65, 0x1f, 0x8b, 0xe5, 0x70, 0xce, 0x48, 0xda, + 0x08, 0xf6, 0xc3, 0x69, 0xab, 0x20, 0x52, 0x05, 0x60, 0xae, 0x63, 0x9d, + 0x5a, 0x92, 0x08, 0x5f, 0x70, 0x05, 0xb3, 0x84, 0xb0, 0x76, 0xb2, 0x66, + 0x08, 0xfb, 0x0e, 0x4b, 0xac, 0x6c, 0xf7, 0x0b, 0xc9, 0x05, 0x84, 0xfb, + 0x21, 0x15, 0xa7, 0x9d, 0x75, 0x67, 0x1f, 0x8b, 0x47, 0x6c, 0xfb, 0x15, + 0x6b, 0x44, 0x6e, 0x4d, 0x6d, 0x6e, 0x68, 0x8b, 0x6a, 0x8b, 0x7b, 0xa2, + 0x8b, 0xba, 0x8b, 0xd4, 0xb0, 0xf7, 0x21, 0xaf, 0xcc, 0xa5, 0xb9, 0xa7, + 0xa1, 0xac, 0x8b, 0x08, 0x0e, 0xf7, 0x15, 0xfb, 0x46, 0x15, 0x59, 0x8c, + 0x7c, 0x92, 0x8b, 0xa3, 0x8b, 0x98, 0x92, 0xac, 0x9e, 0xcf, 0x08, 0x93, + 0xa7, 0x8e, 0x98, 0x05, 0xae, 0x79, 0x97, 0x87, 0xa0, 0x8b, 0x08, 0xf7, + 0x1b, 0xf7, 0x22, 0xf7, 0x49, 0xf7, 0x41, 0xd4, 0x61, 0xbb, 0x4a, 0x1f, + 0x52, 0x8b, 0x5f, 0x6c, 0x59, 0x40, 0x08, 0x88, 0x8e, 0xea, 0xf7, 0xe8, + 0x05, 0x47, 0x7e, 0x5a, 0x84, 0x32, 0x81, 0x08, 0x70, 0x07, 0xbc, 0x99, + 0x84, 0x74, 0x1f, 0x8b, 0x85, 0x86, 0x74, 0x7f, 0x5d, 0x08, 0xfb, 0x36, + 0xfd, 0x0a, 0x05, 0x79, 0x41, 0x80, 0x7f, 0x5a, 0x8c, 0x08, 0x70, 0xf7, + 0x8d, 0xa6, 0x07, 0xf7, 0x2d, 0xf8, 0xcd, 0x15, 0xa5, 0x89, 0x9a, 0x74, + 0x89, 0x6b, 0x87, 0x4a, 0x6b, 0x27, 0x67, 0x4a, 0x6c, 0x55, 0x6a, 0x6f, + 0x6a, 0x8b, 0x75, 0x8b, 0x7a, 0x9b, 0x8b, 0x9f, 0x8b, 0x9b, 0x93, 0xa9, + 0xa6, 0xe6, 0xa3, 0xdd, 0x95, 0xa7, 0x9b, 0xa3, 0x08, 0xa4, 0xb2, 0xac, + 0xa4, 0xa5, 0x89, 0x08, 0x0e, 0xfb, 0x5b, 0x99, 0xf8, 0x2f, 0x15, 0x9d, + 0x8b, 0x90, 0x8a, 0x92, 0x87, 0x9c, 0x81, 0x9b, 0x62, 0x9a, 0x44, 0xac, + 0xfb, 0x34, 0x9c, 0x2a, 0x8b, 0x6c, 0x8b, 0x74, 0x82, 0x73, 0x79, 0x72, + 0x76, 0x6f, 0x70, 0x76, 0x7a, 0x8b, 0x84, 0x8b, 0x78, 0x92, 0x83, 0x92, + 0x08, 0x7a, 0x97, 0x72, 0x94, 0x79, 0x8b, 0x08, 0x71, 0x73, 0x71, 0x6e, + 0x6a, 0xa6, 0x70, 0xae, 0x1f, 0xc2, 0x8b, 0xcc, 0xb3, 0xc2, 0xcd, 0xf7, + 0x16, 0xf7, 0x33, 0xf7, 0x0b, 0xf7, 0x81, 0x8b, 0xf0, 0x08, 0xad, 0x6e, + 0xa9, 0x6a, 0x6d, 0x70, 0x70, 0x6c, 0x1e, 0x8b, 0x73, 0x92, 0x7f, 0xa3, + 0x79, 0x9d, 0x7d, 0x91, 0x83, 0x8b, 0x7e, 0x8b, 0x6d, 0x79, 0x61, 0x46, + 0xfb, 0x19, 0x08, 0x7f, 0xd6, 0x05, 0x75, 0xf7, 0x0a, 0x71, 0xf7, 0x04, + 0x79, 0xba, 0x5b, 0x7f, 0x67, 0x85, 0x4a, 0x85, 0x08, 0x70, 0x07, 0xf7, + 0x26, 0xf7, 0x88, 0x15, 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, + 0xae, 0xaa, 0xa9, 0xad, 0xaf, 0x6d, 0xa9, 0x67, 0x1f, 0xf7, 0x68, 0x16, + 0x68, 0x6e, 0x6d, 0x67, 0x69, 0xa9, 0x6d, 0xad, 0xae, 0xaa, 0xa9, 0xad, + 0x1f, 0xaf, 0x6d, 0xa9, 0x67, 0x1e, 0x0e, 0xf7, 0xb5, 0xf8, 0x2d, 0x15, + 0xc5, 0xf7, 0x28, 0xdc, 0xe7, 0xd3, 0x8b, 0x08, 0xc6, 0xb2, 0x4f, 0x30, + 0x1f, 0x7f, 0x9e, 0x07, 0xbc, 0xf7, 0x5e, 0x78, 0x8b, 0x05, 0x82, 0x7a, + 0x81, 0x84, 0x7d, 0x8b, 0x84, 0x8b, 0x81, 0x8d, 0x81, 0x8f, 0x08, 0x59, + 0x9b, 0x7e, 0x8e, 0x6e, 0x8b, 0xfb, 0x17, 0x8b, 0xfb, 0x25, 0xfb, 0x0e, + 0x51, 0xfb, 0x32, 0x08, 0x5e, 0x8b, 0x6a, 0x59, 0xcb, 0x8b, 0x05, 0x85, + 0x78, 0x87, 0x7b, 0x88, 0x79, 0x08, 0x5b, 0x8b, 0x6a, 0x59, 0xd9, 0x8b, + 0x05, 0x8a, 0x86, 0x8b, 0x84, 0x8b, 0x8b, 0x8b, 0xfb, 0x31, 0xd3, 0x2f, + 0xf7, 0x0d, 0x8b, 0xdf, 0x8b, 0xcd, 0xac, 0xb6, 0xca, 0x08, 0x98, 0xb5, + 0x05, 0x5b, 0x4a, 0x54, 0x6c, 0x4a, 0x8b, 0x43, 0x8b, 0x62, 0xc4, 0x8b, + 0xef, 0x8b, 0x9e, 0x8d, 0xa0, 0x8e, 0xa1, 0x08, 0xf7, 0x01, 0x8b, 0xac, + 0xbd, 0xfb, 0x1b, 0x8b, 0x05, 0x8f, 0x9d, 0x91, 0xa1, 0x90, 0x98, 0x08, + 0xf7, 0x3b, 0x8b, 0xac, 0xbd, 0x05, 0xfb, 0x4e, 0x06, 0x0e, 0xfb, 0xeb, + 0xa9, 0xf7, 0xa6, 0x15, 0xf7, 0x74, 0x9e, 0x06, 0x5a, 0x81, 0x8f, 0xa1, + 0x1f, 0x8b, 0x94, 0x8d, 0x98, 0x8f, 0x97, 0x08, 0xef, 0xf7, 0xde, 0x05, + 0x4c, 0x7e, 0x61, 0x84, 0x43, 0x80, 0x08, 0x89, 0x76, 0x96, 0x8c, 0x05, + 0x9a, 0x8c, 0x96, 0x8c, 0x91, 0x8b, 0x99, 0x8b, 0x94, 0x84, 0x8e, 0x7d, + 0x8d, 0x86, 0x66, 0xfb, 0x0d, 0x72, 0x42, 0x85, 0x79, 0x85, 0x78, 0x8a, + 0x87, 0x7a, 0x49, 0x7c, 0x7d, 0x53, 0x8b, 0x08, 0x78, 0x07, 0x0e, 0xfb, + 0xeb, 0xf7, 0xb7, 0xf8, 0x18, 0x15, 0x7b, 0x06, 0x72, 0x66, 0x7c, 0x83, + 0x59, 0x8b, 0x08, 0x32, 0x8b, 0xf7, 0x11, 0xf0, 0x05, 0xcd, 0xc0, 0xa5, + 0xb2, 0x8b, 0xbb, 0x8b, 0xc2, 0x5b, 0xb7, 0x4f, 0x8b, 0x4e, 0x8b, 0x5c, + 0x6b, 0x67, 0x49, 0x08, 0x9d, 0x80, 0x05, 0xab, 0xaf, 0xa0, 0x97, 0xa8, + 0x8b, 0xaf, 0x8b, 0xa2, 0x72, 0x8b, 0x62, 0x8b, 0x6c, 0x78, 0x69, 0x58, + 0x53, 0x6e, 0x6b, 0x7c, 0x7d, 0x23, 0x28, 0x08, 0x7b, 0xf7, 0x82, 0x07, + 0xbe, 0xf7, 0x06, 0x05, 0x0e, 0xfb, 0xeb, 0xf7, 0x02, 0xf8, 0x75, 0x15, + 0xce, 0x88, 0xac, 0x6d, 0x8b, 0x51, 0x8b, 0x57, 0x6c, 0x63, 0x64, 0x8b, + 0x78, 0x8b, 0x88, 0x8d, 0x76, 0xa7, 0x7e, 0x9e, 0x7d, 0x94, 0x7b, 0x8b, + 0x08, 0x76, 0x7b, 0x7a, 0x73, 0x6c, 0xab, 0x78, 0xc0, 0xf5, 0xe1, 0xd2, + 0xe2, 0x1f, 0x8b, 0xb2, 0x7d, 0xa2, 0x65, 0xa5, 0x08, 0x92, 0x8f, 0x05, + 0xc5, 0xac, 0x99, 0x9c, 0x8b, 0xb0, 0x8b, 0xb9, 0x60, 0xae, 0x53, 0x8b, + 0x56, 0x8b, 0x63, 0x73, 0x63, 0x53, 0x08, 0x99, 0x7e, 0x05, 0xa7, 0xab, + 0x9e, 0x95, 0xa7, 0x8b, 0xad, 0x8b, 0xa0, 0x77, 0x8b, 0x6b, 0x8b, 0x60, + 0x64, 0x70, 0x39, 0x7c, 0x08, 0x89, 0x7d, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, + 0x12, 0xf8, 0x29, 0x15, 0x61, 0x6a, 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, + 0xb5, 0xac, 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, 0x0e, 0xfb, 0xca, + 0xf7, 0xa3, 0xf7, 0xae, 0x15, 0xfb, 0x89, 0x8b, 0x73, 0xfb, 0x08, 0xf7, + 0x8a, 0x8b, 0xa2, 0xf7, 0x08, 0x05, 0x0e, 0xfb, 0x87, 0xf7, 0x76, 0xf9, + 0x3f, 0x15, 0x3b, 0x4c, 0x4c, 0x3b, 0x3c, 0xca, 0x4b, 0xd9, 0xdd, 0xca, + 0xc9, 0xdc, 0xdb, 0x4c, 0xca, 0x3b, 0x1f, 0x67, 0x04, 0xc2, 0xba, 0x5a, + 0x51, 0x50, 0x5d, 0x5b, 0x52, 0x54, 0x5d, 0xbc, 0xc5, 0xc5, 0xb9, 0xbc, + 0xc3, 0x1f, 0x0e, 0x66, 0xf8, 0xbf, 0xf7, 0x65, 0x15, 0xe3, 0xfc, 0x8c, + 0x33, 0xf8, 0x8c, 0x07, 0x0e, 0x42, 0xf7, 0x73, 0xf7, 0x91, 0x15, 0xfb, + 0x43, 0xfb, 0x43, 0xc9, 0x4d, 0xf7, 0x43, 0xf7, 0x44, 0xf7, 0x43, 0xfb, + 0x44, 0xc9, 0xc9, 0xfb, 0x44, 0xf7, 0x43, 0xf7, 0x44, 0xf7, 0x43, 0x4d, + 0xc9, 0xfb, 0x43, 0xfb, 0x44, 0xfb, 0x43, 0xf7, 0x44, 0x4d, 0x4d, 0xf7, + 0x43, 0xfb, 0x43, 0x05, 0x0e, 0x42, 0xf8, 0xad, 0xf7, 0x65, 0x15, 0xe3, + 0xfc, 0x8c, 0x33, 0xf8, 0x8c, 0x07, 0xfb, 0x8f, 0x31, 0x15, 0x61, 0x6a, + 0x6b, 0x61, 0x61, 0xab, 0x6b, 0xb4, 0xb5, 0xac, 0xac, 0xb4, 0xb3, 0x6a, + 0xad, 0x63, 0x1f, 0xf8, 0x34, 0x04, 0x61, 0x6a, 0x6b, 0x61, 0x61, 0xab, + 0x6b, 0xb4, 0xb5, 0xac, 0xab, 0xb5, 0xb3, 0x6a, 0xad, 0x63, 0x1f, 0x0e, + 0xf7, 0xf9, 0xf7, 0x8a, 0xf9, 0x1b, 0x15, 0xbc, 0x06, 0xae, 0x8b, 0x9e, + 0x78, 0x97, 0x5c, 0x08, 0xa0, 0xe3, 0xfb, 0xf2, 0x33, 0xa0, 0x06, 0x97, + 0xba, 0x9e, 0x9e, 0xae, 0x8b, 0x08, 0xbc, 0xfb, 0xc9, 0x06, 0x8b, 0x5c, + 0x8b, 0x8b, 0x59, 0x86, 0x08, 0x76, 0xf7, 0x46, 0xa0, 0x07, 0x59, 0x90, + 0x8b, 0x8b, 0x8b, 0xba, 0x08, 0xf7, 0xc9, 0x07, 0xf8, 0x3c, 0xfc, 0x14, + 0x15, 0x96, 0x8b, 0xf7, 0x2d, 0xf7, 0xc8, 0x8b, 0xfb, 0x7d, 0x05, 0x8b, + 0x5c, 0x8b, 0x8b, 0x59, 0x86, 0x08, 0x76, 0xf7, 0x46, 0xa0, 0x07, 0x59, + 0x90, 0x8b, 0x8b, 0x8b, 0xba, 0x08, 0xf7, 0x95, 0x07, 0x8b, 0xb1, 0x98, + 0x97, 0xb6, 0x8f, 0x08, 0x9f, 0xfb, 0x01, 0x07, 0xfb, 0x31, 0xfb, 0xc2, + 0xfb, 0x2a, 0xf7, 0xc2, 0xfb, 0x13, 0x8b, 0x8b, 0x77, 0x05, 0xaa, 0x89, + 0xa4, 0x78, 0x99, 0x6c, 0x08, 0xfb, 0x88, 0x07, 0x8b, 0x58, 0x82, 0x80, + 0x60, 0x86, 0x08, 0x76, 0xf7, 0x17, 0xa0, 0x07, 0x60, 0x90, 0x82, 0x96, + 0x8b, 0xbe, 0x08, 0x8b, 0xf7, 0x6c, 0xf7, 0x28, 0xfb, 0xc6, 0x05, 0x0e, + 0x42, 0xf7, 0x85, 0xf7, 0xfb, 0x15, 0xfb, 0x64, 0x33, 0xf7, 0x64, 0xfb, + 0x23, 0xe3, 0xf7, 0x23, 0xf7, 0x64, 0xe3, 0xfb, 0x64, 0xf7, 0x65, 0x33, + 0xfb, 0x65, 0x06, 0xfb, 0x64, 0xfb, 0xfb, 0x15, 0xf8, 0x8c, 0xe3, 0xfc, + 0x8c, 0x33, 0x06, 0x0e, 0xf6, 0xf8, 0xfa, 0xf9, 0x3f, 0x15, 0x51, 0x8b, + 0xfc, 0x47, 0xfd, 0x4d, 0xc5, 0x8b, 0x05, 0xf8, 0x47, 0xf9, 0x4d, 0x05, + 0xe2, 0xfc, 0xcd, 0x15, 0x7b, 0x06, 0x72, 0x66, 0x7c, 0x83, 0x59, 0x8b, + 0x08, 0x32, 0x8b, 0xf7, 0x11, 0xf0, 0x05, 0xcd, 0xc0, 0xa5, 0xb2, 0x8b, + 0xbb, 0x8b, 0xc2, 0x5b, 0xb7, 0x4f, 0x8b, 0x4e, 0x8b, 0x5c, 0x6b, 0x67, + 0x49, 0x08, 0x9d, 0x80, 0x05, 0xab, 0xaf, 0xa0, 0x97, 0xa8, 0x8b, 0xaf, + 0x8b, 0xa2, 0x72, 0x8b, 0x62, 0x8b, 0x6c, 0x78, 0x69, 0x58, 0x53, 0x6e, + 0x6b, 0x7c, 0x7d, 0x23, 0x28, 0x08, 0x7b, 0xf7, 0x82, 0x07, 0xbe, 0xf7, + 0x06, 0x05, 0xfd, 0x5a, 0xf7, 0x34, 0x15, 0xf7, 0x74, 0x9e, 0x06, 0x5a, + 0x81, 0x8f, 0xa1, 0x1f, 0x8b, 0x94, 0x8d, 0x98, 0x8f, 0x97, 0x08, 0xef, + 0xf7, 0xde, 0x05, 0x4c, 0x7e, 0x61, 0x84, 0x43, 0x80, 0x08, 0x89, 0x76, + 0x96, 0x8c, 0x05, 0x99, 0x8c, 0x96, 0x8c, 0x92, 0x8b, 0x99, 0x8b, 0x97, + 0x81, 0x8b, 0x80, 0x8b, 0x80, 0x6c, 0x23, 0x6e, 0x37, 0x85, 0x79, 0x86, + 0x7b, 0x89, 0x84, 0x7a, 0x49, 0x7c, 0x7d, 0x53, 0x8b, 0x08, 0x78, 0x07, + 0x0e, 0xf6, 0xf9, 0x44, 0xf7, 0x29, 0x15, 0x5e, 0x8b, 0xd9, 0xf7, 0x99, + 0x5d, 0x8b, 0xfb, 0xaa, 0xfb, 0x93, 0x7b, 0x48, 0xf7, 0x33, 0x8b, 0x70, + 0x33, 0xe1, 0x8b, 0xa7, 0xe3, 0xb7, 0x8b, 0x05, 0x9c, 0xc8, 0x05, 0xfb, + 0x9b, 0x16, 0xf7, 0x4c, 0xf7, 0x3e, 0x57, 0xfb, 0x3e, 0xfb, 0x18, 0x8b, + 0x05, 0xf7, 0x60, 0xf8, 0xaa, 0x15, 0x51, 0x8b, 0x05, 0xfc, 0x47, 0xfd, + 0x4d, 0xc5, 0x8b, 0xf8, 0x47, 0xf9, 0x4d, 0x05, 0xfd, 0x02, 0xfc, 0x2d, + 0x15, 0xf7, 0x74, 0x9e, 0x06, 0x5a, 0x81, 0x8f, 0xa1, 0x1f, 0x8b, 0x94, + 0x8d, 0x98, 0x8f, 0x97, 0x08, 0xef, 0xf7, 0xde, 0x05, 0x4c, 0x7e, 0x61, + 0x84, 0x43, 0x80, 0x08, 0x89, 0x76, 0x96, 0x8c, 0x05, 0x99, 0x8c, 0x96, + 0x8c, 0x92, 0x8b, 0x99, 0x8b, 0x97, 0x81, 0x8b, 0x80, 0x8b, 0x80, 0x6c, + 0x23, 0x6e, 0x37, 0x85, 0x79, 0x86, 0x7b, 0x89, 0x84, 0x7a, 0x49, 0x7c, + 0x7d, 0x53, 0x8b, 0x08, 0x78, 0x07, 0x0e, 0xf6, 0xf9, 0x49, 0xf7, 0x29, + 0x15, 0x5e, 0x8b, 0xd9, 0xf7, 0x99, 0x5d, 0x8b, 0xfb, 0xaa, 0xfb, 0x93, + 0x7b, 0x48, 0xf7, 0x33, 0x8b, 0x70, 0x33, 0xe1, 0x8b, 0xa7, 0xe3, 0xb7, + 0x8b, 0x05, 0x9c, 0xc8, 0x05, 0xfb, 0x9b, 0x16, 0xf7, 0x4c, 0xf7, 0x3e, + 0x57, 0xfb, 0x3e, 0xfb, 0x18, 0x8b, 0x05, 0xf7, 0x60, 0xf8, 0xaa, 0x15, + 0x51, 0x8b, 0xfc, 0x47, 0xfd, 0x4d, 0xc5, 0x8b, 0x05, 0xf8, 0x47, 0xf9, + 0x4d, 0x05, 0xfc, 0xaa, 0xfb, 0x5e, 0x15, 0xcf, 0x88, 0xab, 0x6d, 0x8b, + 0x50, 0x8b, 0x58, 0x6c, 0x63, 0x63, 0x8b, 0x79, 0x8b, 0x89, 0x8d, 0x75, + 0xa7, 0x7e, 0x9e, 0x7d, 0x94, 0x7b, 0x8b, 0x08, 0x76, 0x7b, 0x7a, 0x73, + 0x6c, 0xab, 0x78, 0xc1, 0xf4, 0xe1, 0xd2, 0xe2, 0x1f, 0x8b, 0xb2, 0x7d, + 0xa2, 0x65, 0xa5, 0x08, 0x92, 0x8f, 0x05, 0xc4, 0xac, 0x9a, 0x9c, 0x8b, + 0xb0, 0x8b, 0xb9, 0x60, 0xae, 0x53, 0x8b, 0x56, 0x8b, 0x63, 0x73, 0x63, + 0x53, 0x08, 0x99, 0x7e, 0x05, 0xa7, 0xab, 0x9e, 0x95, 0xa7, 0x8b, 0xad, + 0x8b, 0xa0, 0x77, 0x8b, 0x6b, 0x8b, 0x60, 0x64, 0x70, 0x39, 0x7c, 0x08, + 0x89, 0x7d, 0x05, 0x0e, 0xf3, 0xf8, 0xa2, 0xf7, 0x8e, 0x15, 0x6e, 0x4e, + 0x67, 0x71, 0x51, 0x8b, 0x08, 0x33, 0x59, 0xcc, 0xf7, 0x06, 0xf7, 0x04, + 0xbc, 0xcb, 0xe1, 0x1f, 0xc8, 0x8b, 0xaf, 0x6d, 0x98, 0x4f, 0x08, 0x9c, + 0xd2, 0x06, 0x8b, 0x94, 0x84, 0x91, 0x7c, 0x91, 0x66, 0x98, 0x70, 0x90, + 0x67, 0x8b, 0x08, 0xfb, 0x1c, 0x32, 0x3a, 0xfb, 0x0e, 0xfb, 0x0d, 0xdd, + 0x41, 0xf7, 0x1a, 0x1f, 0xac, 0x8b, 0xc5, 0x97, 0xa7, 0x97, 0x94, 0x8e, + 0x8c, 0x8c, 0x8d, 0x95, 0x08, 0x9c, 0xd3, 0x79, 0x8b, 0x05, 0xfb, 0x2c, + 0xf8, 0x47, 0x15, 0xfb, 0x54, 0xfb, 0x2c, 0xfb, 0x30, 0xfb, 0x59, 0xfb, + 0x55, 0xf7, 0x2c, 0xfb, 0x31, 0xf7, 0x4f, 0xf7, 0x5b, 0xf7, 0x2a, 0xf7, + 0x2c, 0xf7, 0x5c, 0xf7, 0x58, 0xfb, 0x2c, 0xf7, 0x2f, 0xfb, 0x54, 0x1f, + 0x5d, 0x04, 0xf7, 0x2e, 0xf7, 0x15, 0xfb, 0x1f, 0xfb, 0x3a, 0xfb, 0x3e, + 0xfb, 0x13, 0xfb, 0x1c, 0xfb, 0x34, 0xfb, 0x2a, 0xfb, 0x15, 0xf7, 0x20, + 0xf7, 0x39, 0xf7, 0x3c, 0xf7, 0x14, 0xf7, 0x1e, 0xf7, 0x2f, 0x1f, 0x0e, + 0xf3, 0xf7, 0x66, 0xf8, 0x93, 0x15, 0xba, 0x86, 0x8b, 0x8b, 0x8b, 0x61, + 0x08, 0xfb, 0x8d, 0x07, 0x8b, 0x60, 0x8b, 0x8b, 0x5c, 0x86, 0x08, 0x7b, + 0xf7, 0x3a, 0x9b, 0x07, 0x5b, 0x90, 0x8b, 0x8b, 0x8b, 0xb6, 0x08, 0xf1, + 0xb7, 0x07, 0xa2, 0x68, 0x96, 0x78, 0x9d, 0x6c, 0xad, 0x4e, 0x9b, 0x77, + 0x9d, 0x8b, 0x08, 0xd1, 0x96, 0x06, 0x77, 0x9b, 0x74, 0xa5, 0x6c, 0xb5, + 0x08, 0x50, 0xdd, 0x05, 0xc1, 0x9f, 0xa6, 0xaf, 0x8b, 0xbb, 0x08, 0xc5, + 0x5e, 0xb0, 0x43, 0x1e, 0xfb, 0x4b, 0x7b, 0x06, 0xf7, 0x0a, 0x86, 0x15, + 0xb3, 0x06, 0xb9, 0xa2, 0x71, 0x57, 0x51, 0x72, 0x6a, 0x60, 0x1f, 0x62, + 0xf7, 0x3d, 0x06, 0xb9, 0xf7, 0x47, 0x15, 0xfb, 0x54, 0xfb, 0x2c, 0xfb, + 0x30, 0xfb, 0x59, 0xfb, 0x55, 0xf7, 0x2c, 0xfb, 0x31, 0xf7, 0x4f, 0xf7, + 0x5b, 0xf7, 0x2a, 0xf7, 0x2c, 0xf7, 0x5c, 0xf7, 0x58, 0xfb, 0x2c, 0xf7, + 0x2f, 0xfb, 0x54, 0x1f, 0x5d, 0x04, 0xf7, 0x2e, 0xf7, 0x15, 0xfb, 0x1f, + 0xfb, 0x3a, 0xfb, 0x3e, 0xfb, 0x13, 0xfb, 0x1c, 0xfb, 0x34, 0xfb, 0x2a, + 0xfb, 0x15, 0xf7, 0x20, 0xf7, 0x39, 0xf7, 0x3c, 0xf7, 0x14, 0xf7, 0x1e, + 0xf7, 0x2f, 0x1f, 0x0e, 0xfc, 0x1d, 0x0e, 0x66, 0xf8, 0x67, 0xf7, 0x00, + 0x15, 0xe3, 0xf7, 0xb7, 0xfc, 0x8c, 0x33, 0xf8, 0x34, 0xfb, 0x5f, 0x06, + 0x0e, 0xfc, 0x3b, 0xcd, 0x79, 0x15, 0xe3, 0xf7, 0x97, 0x33, 0xfb, 0x97, + 0x06, 0xf8, 0x50, 0x04, 0xe3, 0xf7, 0x97, 0x33, 0xfb, 0x97, 0x06, 0x0e, + 0x48, 0xf8, 0x98, 0xf8, 0x55, 0x15, 0xfb, 0x1b, 0x8b, 0x58, 0xfb, 0x38, + 0x05, 0x69, 0xfb, 0x00, 0x40, 0x20, 0x61, 0x8b, 0x7f, 0x8b, 0x84, 0x94, + 0x8b, 0x9b, 0x8b, 0x96, 0x8e, 0x9c, 0x8f, 0x99, 0x08, 0xe8, 0xf7, 0xcc, + 0xfb, 0x1b, 0x8b, 0xfb, 0x03, 0xfc, 0x0b, 0x05, 0x79, 0x59, 0x85, 0x7a, + 0x78, 0x5f, 0x72, 0x51, 0x85, 0x75, 0x8b, 0x6e, 0x8b, 0x64, 0x9d, 0x75, + 0xab, 0x8b, 0xaa, 0x8b, 0xa7, 0x9f, 0x98, 0xa9, 0x90, 0x97, 0x8d, 0x94, + 0x8b, 0xa7, 0x8c, 0xb6, 0x93, 0xb9, 0x99, 0xb6, 0x08, 0xa5, 0x78, 0x97, + 0x86, 0xa3, 0x8b, 0xb9, 0x8b, 0xaa, 0xa7, 0xc0, 0xe5, 0x82, 0x65, 0x89, + 0x80, 0x8b, 0x78, 0x08, 0x67, 0xa6, 0x70, 0xaf, 0x1e, 0xa8, 0x8b, 0xab, + 0x98, 0xa3, 0xa0, 0xa4, 0xa1, 0x99, 0x9b, 0xb6, 0xc6, 0x08, 0x76, 0x9b, + 0x05, 0x6d, 0x5f, 0x79, 0x79, 0x7c, 0x8b, 0x84, 0x8b, 0x86, 0x91, 0x8b, + 0x93, 0x8b, 0x92, 0x8d, 0x95, 0x8e, 0x95, 0x08, 0xf3, 0xf7, 0xe4, 0x05, + 0x0e, 0xf8, 0x88, 0x14, 0xf9, 0x17, 0x15, 0x79, 0x9d, 0xf8, 0x55, 0x98, + 0xf7, 0x63, 0x9b, 0x06, 0x1e, 0x0a, 0x03, 0x96, 0x25, 0xff, 0x0c, 0x09, + 0x8b, 0x0c, 0x0a, 0xa6, 0x0a, 0xa6, 0x91, 0x8e, 0x92, 0x96, 0x95, 0x94, + 0x9d, 0x0c, 0x0c, 0xf7, 0x0c, 0x0b, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00 +}; +const unsigned int fonts_NimbusRomNo9L_MediItal_cff_len = 27120; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Regu.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Regu.cff.c new file mode 100644 index 00000000000..3e298cb36cb --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-Regu.cff.c @@ -0,0 +1,2109 @@ +const unsigned char fonts_NimbusRomNo9L_Regu_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x13, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x52, 0x6f, 0x6d, 0x4e, 0x6f, 0x39, 0x4c, 0x2d, 0x52, + 0x65, 0x67, 0x75, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x32, 0xf8, 0x1f, + 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, 0x18, + 0x04, 0x1d, 0x00, 0x4c, 0x9d, 0x03, 0x0d, 0xfb, 0x3c, 0xfb, 0x6e, 0xfa, + 0x7c, 0xfa, 0x27, 0x05, 0x1c, 0x00, 0xf4, 0x0f, 0x1c, 0x00, 0x00, 0x10, + 0x1c, 0x02, 0xc5, 0x11, 0x1c, 0x00, 0x31, 0x1c, 0x62, 0x7f, 0x12, 0x00, + 0x08, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, + 0x00, 0x1f, 0x00, 0x5f, 0x00, 0x79, 0x00, 0x8b, 0x45, 0x75, 0x72, 0x6f, + 0x6d, 0x69, 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, + 0x68, 0x65, 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, + 0x30, 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, + 0x79, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, + 0x73, 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, + 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, + 0x20, 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x4e, 0x6f, 0x39, 0x20, 0x4c, + 0x20, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4e, 0x69, 0x6d, 0x62, + 0x75, 0x73, 0x20, 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x4e, 0x6f, 0x39, + 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, + 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, + 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, + 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, + 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, + 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, + 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, + 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, + 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, + 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, + 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, + 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, + 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, + 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, + 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, + 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, + 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, + 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, + 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x00, 0x81, 0x00, + 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, + 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8c, 0x00, 0x8d, 0x00, + 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, + 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, 0xae, 0x00, 0xac, 0x00, + 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, 0xb4, 0x00, 0xb2, 0x00, + 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, 0xb9, 0x00, 0xb7, 0x00, + 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, 0xbc, 0x00, 0xbf, 0x00, + 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, 0xc2, 0x00, 0xc5, 0x00, + 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xc8, 0x00, 0xcb, 0x00, + 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd1, 0x00, 0xcf, 0x00, + 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd6, 0x00, 0xd4, 0x00, + 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, 0xd9, 0x00, 0xdc, 0x00, + 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xdf, 0x00, 0xe2, 0x00, + 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, 0x87, 0x00, 0x96, 0x00, + 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, 0xa1, 0x00, 0xa6, 0x00, + 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9b, 0x00, 0x9e, 0x00, + 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, 0x97, 0x00, 0xa0, 0x00, + 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x05, 0x00, 0x47, + 0x00, 0x89, 0x00, 0xeb, 0x01, 0x7f, 0x02, 0x4d, 0x03, 0x06, 0x03, 0x3c, + 0x03, 0x7d, 0x03, 0xbd, 0x04, 0xa2, 0x04, 0xbf, 0x04, 0xf7, 0x05, 0x04, + 0x05, 0x1b, 0x05, 0x2f, 0x05, 0x82, 0x05, 0xc2, 0x06, 0x16, 0x06, 0x94, + 0x06, 0xc1, 0x07, 0x38, 0x07, 0x9e, 0x07, 0xc4, 0x08, 0x3c, 0x08, 0xa4, + 0x08, 0xd0, 0x09, 0x1d, 0x09, 0x3b, 0x09, 0x54, 0x09, 0x71, 0x09, 0xe1, + 0x0a, 0x9f, 0x0a, 0xfd, 0x0b, 0x8a, 0x0b, 0xfa, 0x0c, 0x63, 0x0c, 0xdc, + 0x0d, 0x3a, 0x0d, 0xc1, 0x0e, 0x2a, 0x0e, 0x5d, 0x0e, 0x9e, 0x0f, 0x26, + 0x0f, 0x6c, 0x0f, 0xd1, 0x10, 0x2f, 0x10, 0x9f, 0x11, 0x07, 0x11, 0x90, + 0x12, 0x0c, 0x12, 0xa0, 0x12, 0xe4, 0x13, 0x4c, 0x13, 0xa1, 0x14, 0x28, + 0x14, 0xc2, 0x15, 0x30, 0x15, 0x76, 0x15, 0x96, 0x15, 0xa9, 0x15, 0xc8, + 0x15, 0xe6, 0x15, 0xf3, 0x16, 0x2a, 0x16, 0xbd, 0x17, 0x15, 0x17, 0x6b, + 0x17, 0xe4, 0x18, 0x41, 0x18, 0x94, 0x19, 0x5f, 0x19, 0xcd, 0x1a, 0x1b, + 0x1a, 0x81, 0x1b, 0x11, 0x1b, 0x4a, 0x1b, 0xf0, 0x1c, 0x59, 0x1c, 0x98, + 0x1d, 0x06, 0x1d, 0x6e, 0x1d, 0xc9, 0x1e, 0x53, 0x1e, 0xa0, 0x1e, 0xfb, + 0x1f, 0x58, 0x1f, 0xec, 0x20, 0x75, 0x20, 0xf3, 0x21, 0x33, 0x21, 0x8d, + 0x21, 0x9a, 0x21, 0xf4, 0x22, 0x34, 0x22, 0x77, 0x23, 0x02, 0x23, 0xc1, + 0x23, 0xd6, 0x24, 0x5a, 0x24, 0xfa, 0x25, 0xb8, 0x26, 0x24, 0x26, 0x47, + 0x26, 0xb1, 0x27, 0x61, 0x27, 0xbb, 0x28, 0x11, 0x28, 0x98, 0x29, 0x2a, + 0x29, 0x35, 0x29, 0xc3, 0x2a, 0xae, 0x2a, 0xc6, 0x2b, 0x29, 0x2b, 0x41, + 0x2b, 0x79, 0x2b, 0xe4, 0x2c, 0x4d, 0x2c, 0xf4, 0x2d, 0x34, 0x2e, 0x18, + 0x2e, 0x83, 0x2e, 0xa8, 0x2e, 0xcd, 0x2e, 0xe9, 0x2f, 0x2e, 0x2f, 0x3b, + 0x2f, 0x66, 0x2f, 0x7e, 0x2f, 0xa9, 0x2f, 0xd5, 0x30, 0x15, 0x30, 0x5b, + 0x30, 0x8c, 0x30, 0xa8, 0x30, 0xb5, 0x31, 0x67, 0x31, 0xed, 0x32, 0x48, + 0x32, 0xdc, 0x33, 0x8a, 0x33, 0xc0, 0x34, 0x86, 0x34, 0xbd, 0x35, 0x08, + 0x35, 0x91, 0x36, 0x2b, 0x36, 0xad, 0x37, 0x34, 0x37, 0xb4, 0x38, 0x35, + 0x38, 0xad, 0x39, 0x4f, 0x39, 0xd7, 0x3a, 0x82, 0x3a, 0xfa, 0x3b, 0x9d, + 0x3c, 0x39, 0x3c, 0xd5, 0x3d, 0x68, 0x3d, 0xc5, 0x3e, 0x1a, 0x3e, 0x70, + 0x3e, 0xbd, 0x3f, 0x5e, 0x3f, 0xf7, 0x40, 0x88, 0x41, 0x19, 0x41, 0xa2, + 0x42, 0x56, 0x43, 0x03, 0x43, 0x95, 0x44, 0x20, 0x44, 0xab, 0x45, 0x2c, + 0x45, 0xbc, 0x46, 0x1c, 0x46, 0x89, 0x47, 0x22, 0x47, 0xe0, 0x48, 0x95, + 0x49, 0x4a, 0x49, 0xf6, 0x4a, 0xcb, 0x4b, 0x88, 0x4c, 0x10, 0x4c, 0x96, + 0x4d, 0x15, 0x4d, 0x95, 0x4e, 0x0c, 0x4e, 0x6d, 0x4e, 0xc5, 0x4f, 0x1d, + 0x4f, 0x6d, 0x50, 0x19, 0x50, 0x83, 0x50, 0xe3, 0x51, 0x43, 0x51, 0x9b, + 0x52, 0x1e, 0x52, 0xc1, 0x53, 0x46, 0x53, 0xc4, 0x54, 0x42, 0x54, 0xb6, + 0x55, 0x56, 0x55, 0xaf, 0x56, 0x2a, 0x56, 0x9a, 0x57, 0x42, 0x57, 0xe0, + 0x58, 0x14, 0x58, 0x64, 0x58, 0xcc, 0x58, 0xe4, 0x58, 0xf1, 0x59, 0x1c, + 0x59, 0x2b, 0x59, 0x5c, 0x59, 0x95, 0x5a, 0x36, 0x5a, 0x5c, 0x5a, 0xf3, + 0x5b, 0x66, 0x5c, 0x0e, 0x5c, 0xa2, 0x5d, 0x4f, 0x5d, 0x51, 0x5d, 0x64, + 0x5d, 0x7b, 0x5d, 0xe4, 0x2b, 0x0e, 0x2b, 0x0e, 0x7e, 0xf7, 0x51, 0xf7, + 0x44, 0x15, 0xb8, 0xf8, 0x13, 0x05, 0x8c, 0x97, 0x8c, 0x96, 0x8b, 0x99, + 0x08, 0xbf, 0x78, 0xa7, 0x69, 0x6a, 0x77, 0x6d, 0x5c, 0x1e, 0x8b, 0x74, + 0x94, 0x39, 0x96, 0x43, 0x94, 0x4f, 0x91, 0x56, 0x8d, 0x72, 0x08, 0x94, + 0xfb, 0x00, 0x98, 0x8b, 0x05, 0x85, 0x3d, 0x15, 0x6d, 0x74, 0x73, 0x6c, + 0x6d, 0xa1, 0x75, 0xa9, 0xab, 0xa2, 0xa1, 0xa9, 0xa9, 0x73, 0xa4, 0x6d, + 0x1f, 0x0e, 0xc9, 0xf7, 0xbf, 0xf8, 0x43, 0x15, 0x92, 0xb3, 0x05, 0x9b, + 0xd7, 0x94, 0xc6, 0x8b, 0xa9, 0x08, 0xa1, 0x78, 0x9d, 0x74, 0x73, 0x78, + 0x79, 0x74, 0x1e, 0x8b, 0x7b, 0x9a, 0x2a, 0x9c, 0x30, 0x08, 0xa0, 0x06, + 0xfb, 0x3d, 0x16, 0x92, 0xb3, 0x05, 0x9b, 0xd7, 0x94, 0xc6, 0x8b, 0xa9, + 0x08, 0xa1, 0x78, 0x9d, 0x74, 0x73, 0x78, 0x79, 0x74, 0x1e, 0x8b, 0x7b, + 0x9a, 0x2a, 0x9c, 0x30, 0x08, 0xa0, 0x06, 0x0e, 0xf8, 0x6b, 0xf7, 0xa3, + 0x15, 0x27, 0x8b, 0x9f, 0xf7, 0x1a, 0xf4, 0x8b, 0x8b, 0xc2, 0x2a, 0x8b, + 0xa9, 0xf7, 0x5e, 0x51, 0x8b, 0x6d, 0xfb, 0x5e, 0xfb, 0x19, 0x8b, 0xaa, + 0xf7, 0x5e, 0x51, 0x8b, 0x6c, 0xfb, 0x5e, 0xfb, 0x0a, 0x8b, 0x8b, 0x54, + 0xf7, 0x02, 0x8b, 0x05, 0x76, 0xfb, 0x1a, 0xfb, 0x08, 0x8b, 0x8b, 0x54, + 0xf6, 0x8b, 0x6a, 0xfb, 0x6c, 0xc5, 0x8b, 0xac, 0xf7, 0x6c, 0xf7, 0x1a, + 0x8b, 0x6c, 0xfb, 0x6c, 0xc5, 0x8b, 0xaa, 0xf7, 0x6c, 0xf7, 0x01, 0x8b, + 0x8b, 0xc2, 0x05, 0xfb, 0x1e, 0xf7, 0x1a, 0x15, 0x77, 0xfb, 0x1a, 0xfb, + 0x1a, 0x8b, 0xa0, 0xf7, 0x1a, 0xf7, 0x19, 0x8b, 0x05, 0x0e, 0xf8, 0x3d, + 0xf8, 0x88, 0x15, 0xf7, 0x03, 0x07, 0x69, 0xa7, 0x60, 0x9a, 0x37, 0x95, + 0x08, 0xca, 0x69, 0x4c, 0x07, 0x4c, 0x84, 0x6f, 0x82, 0x6a, 0x71, 0x69, + 0x70, 0x77, 0x63, 0x8b, 0x60, 0x8b, 0x5c, 0x9b, 0x68, 0xb3, 0x66, 0xa8, + 0x6f, 0xa1, 0x7c, 0xd2, 0x63, 0x08, 0xfb, 0xae, 0x07, 0x2d, 0x8c, 0x56, + 0xba, 0x73, 0xf4, 0x08, 0x7c, 0xfb, 0x16, 0x06, 0xc7, 0x66, 0xb5, 0x80, + 0xdf, 0x88, 0x08, 0x34, 0xad, 0xe2, 0x07, 0xd5, 0x97, 0xaa, 0x97, 0xaf, + 0xa8, 0xac, 0xa7, 0x9e, 0xb4, 0x8b, 0xbb, 0x8b, 0xad, 0x83, 0xaf, 0x7f, + 0x9f, 0x72, 0xb4, 0x70, 0x9f, 0xfb, 0x0d, 0xd1, 0x08, 0xf7, 0x8a, 0x07, + 0xdf, 0x81, 0xb8, 0x61, 0x9c, 0x36, 0x08, 0x9a, 0x06, 0xfb, 0x58, 0x2e, + 0x15, 0x38, 0xc3, 0x77, 0xa4, 0x8b, 0xb9, 0x8b, 0xc2, 0xad, 0xad, 0xd0, + 0x99, 0x08, 0xfb, 0x7a, 0x07, 0xae, 0xfb, 0x06, 0x15, 0xe8, 0x51, 0xa0, + 0x70, 0x8b, 0x4d, 0x8b, 0x49, 0x67, 0x66, 0x3d, 0x7c, 0x08, 0xf7, 0x9d, + 0x07, 0x0e, 0xf8, 0x7b, 0xf9, 0x31, 0xf8, 0x07, 0x15, 0xfb, 0x05, 0x20, + 0xfb, 0x09, 0xfb, 0x11, 0x3d, 0xbb, 0x58, 0xd3, 0x1f, 0xb8, 0x8b, 0xb0, + 0x9b, 0xae, 0xae, 0xc0, 0xc1, 0xac, 0xdc, 0x8b, 0xd9, 0x08, 0xcf, 0x65, + 0xb2, 0x4a, 0x1e, 0x92, 0x6b, 0x15, 0xb1, 0xab, 0x67, 0x5f, 0x1f, 0x8b, + 0x52, 0x72, 0x47, 0x65, 0x5c, 0x6b, 0x63, 0x6e, 0x7a, 0x67, 0x8b, 0x67, + 0x8b, 0x72, 0xa5, 0x8b, 0xb1, 0x8b, 0xc0, 0xa7, 0xdd, 0xb0, 0xbf, 0xa6, + 0xb3, 0xa7, 0x9d, 0xaa, 0x8b, 0x08, 0x61, 0xf7, 0xe5, 0x15, 0x64, 0x06, + 0x55, 0x58, 0x63, 0x7a, 0x4d, 0x8b, 0x63, 0x8b, 0x74, 0x92, 0x73, 0x9f, + 0x08, 0x71, 0xa1, 0x7e, 0x90, 0x6c, 0x8b, 0x08, 0xfb, 0x06, 0x20, 0xfb, + 0x0b, 0xfb, 0x13, 0x45, 0xc0, 0x52, 0xcc, 0x1f, 0xb6, 0x8b, 0xb8, 0x9f, + 0xac, 0xae, 0xbf, 0xc0, 0xab, 0xda, 0x8b, 0xd4, 0x8b, 0x99, 0x89, 0x97, + 0x86, 0x9d, 0x9d, 0x84, 0x9d, 0x88, 0xa8, 0x8b, 0xb7, 0x8b, 0xa5, 0x92, + 0xb3, 0xa2, 0x08, 0xfb, 0xf3, 0xfd, 0x06, 0xbb, 0x8b, 0xf8, 0x15, 0xf9, + 0x45, 0x05, 0xfb, 0xb0, 0x3f, 0x15, 0x91, 0x77, 0x8e, 0x7c, 0x8b, 0x7d, + 0x08, 0xfb, 0x05, 0x39, 0xfb, 0x07, 0x3a, 0x68, 0x73, 0xa4, 0xaf, 0x1e, + 0x8b, 0xb5, 0x9f, 0xcf, 0xa6, 0xbd, 0x08, 0xa8, 0xc1, 0xb1, 0xad, 0xaa, + 0x8b, 0x90, 0x8b, 0x8d, 0x8a, 0x91, 0x86, 0x08, 0x99, 0x7e, 0x97, 0x86, + 0xa8, 0x83, 0x08, 0x0e, 0xf8, 0x44, 0xf9, 0x5b, 0xf8, 0x3e, 0x15, 0xfb, + 0x6c, 0x76, 0x06, 0xbd, 0x86, 0x99, 0x81, 0x8b, 0x6d, 0x8b, 0x60, 0x70, + 0x55, 0x4b, 0x36, 0x53, 0xd0, 0x6b, 0xbe, 0x5f, 0xe1, 0xcf, 0xab, 0xa4, + 0x9c, 0xa7, 0xaa, 0xa0, 0xa2, 0x98, 0xae, 0x8b, 0xac, 0x08, 0xd2, 0x53, + 0xbd, 0x3c, 0x35, 0x47, 0x47, 0x35, 0x1e, 0x8b, 0x65, 0x93, 0x6b, 0xa6, + 0x40, 0x08, 0x65, 0x75, 0x05, 0x21, 0x4e, 0x58, 0x44, 0x8b, 0x37, 0x8b, + 0x2c, 0xcc, 0x52, 0xf5, 0x8b, 0xdc, 0x8b, 0xc7, 0xa4, 0xd6, 0xcd, 0x08, + 0xca, 0x4a, 0xbc, 0x71, 0xc5, 0x8b, 0xcb, 0x8b, 0xc4, 0xb5, 0xa9, 0xd2, + 0x08, 0x7c, 0x96, 0x05, 0x6b, 0x63, 0x75, 0x7e, 0x67, 0x8b, 0x53, 0x8b, + 0x57, 0xaa, 0x5d, 0xc8, 0xb7, 0xc6, 0xa4, 0xb0, 0xaa, 0xc1, 0x08, 0xa5, + 0xb9, 0x05, 0xa3, 0xb4, 0x9f, 0x97, 0xbd, 0x91, 0x08, 0xa0, 0x07, 0xfc, + 0x1a, 0x81, 0x15, 0x6d, 0xca, 0x81, 0xb1, 0x8b, 0xb8, 0x08, 0xbb, 0xaa, + 0xad, 0xb9, 0xb9, 0xad, 0x67, 0x5a, 0x1e, 0x8b, 0x53, 0x68, 0x60, 0x39, + 0x5f, 0x08, 0x46, 0x42, 0x15, 0xc7, 0xfb, 0x06, 0xae, 0x54, 0xc4, 0x45, + 0x50, 0x5c, 0x63, 0x79, 0x61, 0x8b, 0x45, 0x8b, 0x50, 0xcb, 0x8b, 0xd8, + 0x08, 0x8b, 0xcb, 0xaa, 0xb6, 0xe2, 0xc3, 0x08, 0x0e, 0x7e, 0xf5, 0xf8, + 0x45, 0x15, 0xce, 0xac, 0xb8, 0xc8, 0x8b, 0xc7, 0x08, 0xbd, 0x68, 0xb2, + 0x5e, 0x68, 0x73, 0x74, 0x69, 0x6b, 0xa2, 0x78, 0xaf, 0x1e, 0x91, 0x8b, + 0x92, 0x8c, 0x91, 0x8c, 0x92, 0x8d, 0x8b, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, + 0x91, 0x85, 0x8b, 0x83, 0x8b, 0x6a, 0x6f, 0x67, 0x55, 0x66, 0x08, 0x94, + 0x78, 0x05, 0x0e, 0x7e, 0xf7, 0xbb, 0xf9, 0x38, 0x15, 0x41, 0x5b, 0x6d, + 0x71, 0x66, 0x5d, 0x44, 0x34, 0x68, 0x27, 0x8b, 0xfb, 0x09, 0x8b, 0xfb, + 0x13, 0xb0, 0x29, 0xe3, 0x25, 0xb4, 0x5b, 0xa5, 0x75, 0xbf, 0x6b, 0x08, + 0x97, 0x9b, 0x05, 0x3b, 0xca, 0x6f, 0xae, 0x70, 0xd6, 0x73, 0xce, 0x80, + 0xd7, 0x8b, 0xef, 0x8b, 0xf4, 0x98, 0xdd, 0xa6, 0xc9, 0xa7, 0xc9, 0xa9, + 0xaf, 0xd3, 0xc5, 0x08, 0x82, 0x9b, 0x05, 0x0e, 0x7e, 0xb1, 0xfb, 0x45, + 0x15, 0xd5, 0xbb, 0xa9, 0xa5, 0xb0, 0xb9, 0xd2, 0xe2, 0xae, 0xef, 0x8b, + 0xf7, 0x09, 0x8b, 0xf7, 0x14, 0x66, 0xec, 0x33, 0xf1, 0x62, 0xbb, 0x71, + 0xa1, 0x57, 0xab, 0x08, 0x7f, 0x7b, 0x05, 0xdb, 0x4c, 0xa6, 0x68, 0xa7, + 0x40, 0xa3, 0x48, 0x96, 0x3f, 0x8b, 0x27, 0x8b, 0x23, 0x7e, 0x38, 0x70, + 0x4e, 0x6f, 0x4c, 0x6d, 0x67, 0x43, 0x51, 0x08, 0x94, 0x7b, 0x05, 0x0e, + 0xf7, 0x85, 0xf8, 0x55, 0x15, 0x8c, 0x7a, 0x05, 0x8d, 0x76, 0x85, 0x6e, + 0x7e, 0x69, 0x84, 0x79, 0x87, 0x7a, 0x8b, 0x80, 0x08, 0x77, 0x9b, 0x7a, + 0x9e, 0xa0, 0x9d, 0x9e, 0xa0, 0x1e, 0x8b, 0x91, 0x88, 0x98, 0x86, 0x98, + 0x7e, 0xae, 0x84, 0xb1, 0x8b, 0xb2, 0x08, 0x8b, 0x92, 0x92, 0x88, 0x05, + 0xa1, 0x82, 0xa0, 0x79, 0xa6, 0x6a, 0xa4, 0x6c, 0x9c, 0x7f, 0x9d, 0x8b, + 0xa0, 0x8b, 0x99, 0x9a, 0x8b, 0xa1, 0x8b, 0xa5, 0x7c, 0x96, 0x5f, 0x92, + 0x64, 0x91, 0x6b, 0x97, 0x71, 0x9b, 0x08, 0x83, 0x90, 0x05, 0xbc, 0xa7, + 0x9e, 0x92, 0xb7, 0x92, 0xb1, 0x91, 0x98, 0x96, 0x8b, 0xa4, 0x8b, 0xa2, + 0x7c, 0x9b, 0x76, 0x8b, 0x7c, 0x8b, 0x7a, 0x7e, 0x73, 0x6f, 0x72, 0x6d, + 0x72, 0x75, 0x75, 0x7f, 0x08, 0x84, 0x87, 0x8b, 0xa5, 0x05, 0x8b, 0xa3, + 0x91, 0xa7, 0x96, 0xaa, 0x91, 0x9e, 0x8f, 0x9b, 0x8b, 0x96, 0x08, 0xa0, + 0x7b, 0x9b, 0x77, 0x77, 0x7c, 0x7c, 0x77, 0x1e, 0x8b, 0x7f, 0x8f, 0x79, + 0x91, 0x76, 0x95, 0x6a, 0x90, 0x6c, 0x8b, 0x70, 0x08, 0x7e, 0x07, 0x65, + 0xa0, 0x78, 0x9b, 0x6a, 0xaf, 0x77, 0xa3, 0x7f, 0x93, 0x7b, 0x8b, 0x78, + 0x8b, 0x7c, 0x7b, 0x8b, 0x77, 0x8b, 0x73, 0x9f, 0x7d, 0xbb, 0x82, 0xb0, + 0x84, 0xa9, 0x81, 0x9e, 0x7e, 0x08, 0x96, 0x84, 0x05, 0x62, 0x72, 0x7b, + 0x85, 0x5d, 0x82, 0x5e, 0x83, 0x7a, 0x7f, 0x8b, 0x72, 0x8b, 0x75, 0x99, + 0x7e, 0xa1, 0x8b, 0x9b, 0x8b, 0x94, 0x90, 0x9c, 0x9e, 0xa8, 0xac, 0x90, + 0x90, 0x93, 0x92, 0x95, 0x94, 0x92, 0x90, 0xae, 0xa1, 0x08, 0x84, 0x07, + 0x0e, 0xf7, 0x6e, 0xf7, 0x8d, 0xf7, 0xb2, 0x15, 0xfb, 0x6f, 0x49, 0xf7, + 0x6f, 0xfb, 0x70, 0xcd, 0xf7, 0x70, 0xf7, 0x6f, 0xcd, 0xfb, 0x6f, 0xf7, + 0x70, 0x49, 0xfb, 0x70, 0x06, 0x0e, 0x2b, 0xde, 0xfb, 0x21, 0x15, 0xce, + 0xac, 0xb8, 0xc8, 0x8b, 0xc7, 0x08, 0xbd, 0x68, 0xb2, 0x5e, 0x68, 0x73, + 0x74, 0x69, 0x1e, 0x6b, 0xa2, 0x78, 0xaf, 0x1e, 0x91, 0x8b, 0x92, 0x8c, + 0x91, 0x8c, 0x08, 0x92, 0x8d, 0x8b, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0x91, + 0x85, 0x8b, 0x83, 0x8b, 0x6b, 0x6f, 0x66, 0x55, 0x66, 0x08, 0x94, 0x78, + 0x05, 0x0e, 0x7e, 0xb2, 0xf7, 0x95, 0x15, 0x4c, 0xf7, 0x8a, 0xca, 0xfb, + 0x8a, 0x07, 0x0e, 0x2b, 0xf7, 0x11, 0xef, 0x15, 0x6d, 0x72, 0x71, 0x6c, + 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, 0x71, 0xa5, 0x6d, + 0x1f, 0x0e, 0x47, 0xf7, 0xb3, 0xf9, 0x38, 0x15, 0x48, 0x8b, 0xfb, 0x79, + 0xfd, 0x46, 0xcf, 0x8b, 0xf7, 0x78, 0xf9, 0x46, 0x05, 0x0e, 0xf7, 0x92, + 0xf9, 0x38, 0x15, 0x54, 0x8b, 0x61, 0x7a, 0x66, 0x68, 0x51, 0x53, 0x65, + 0xfb, 0x07, 0x8b, 0xfb, 0x09, 0x8b, 0xfb, 0x01, 0xac, 0xfb, 0x09, 0xba, + 0x53, 0xb0, 0x5f, 0xbe, 0x73, 0xc5, 0x8b, 0xbe, 0x8b, 0xb6, 0x9c, 0xaf, + 0xae, 0xc5, 0xc2, 0xb1, 0xf7, 0x08, 0x8b, 0xf7, 0x0d, 0x08, 0xf7, 0x61, + 0x30, 0xf7, 0x21, 0xfb, 0x17, 0x1e, 0x88, 0x71, 0x15, 0xdf, 0xb8, 0xfb, + 0x05, 0xfb, 0x65, 0xfb, 0x65, 0x5f, 0x20, 0x35, 0x35, 0x5f, 0xf6, 0xf7, + 0x64, 0xf7, 0x68, 0xb8, 0xf7, 0x03, 0xe1, 0x1f, 0x0e, 0xf7, 0xb7, 0xf9, + 0x38, 0x15, 0xfb, 0x48, 0x30, 0x8b, 0x7d, 0x05, 0x97, 0x90, 0x96, 0x8f, + 0x8f, 0x8d, 0x9d, 0x92, 0x9c, 0x8f, 0x95, 0x8b, 0x08, 0xa0, 0x94, 0x7c, + 0x6b, 0x1f, 0xfc, 0x59, 0x07, 0x8b, 0x6a, 0x83, 0x74, 0x7b, 0x82, 0x7c, + 0x82, 0x7d, 0x88, 0x61, 0x8a, 0x08, 0x7c, 0xf7, 0xa8, 0x9a, 0x07, 0x3c, + 0x8c, 0x7b, 0x95, 0x8b, 0xbb, 0x08, 0x8b, 0xf8, 0xec, 0x83, 0x8d, 0x05, + 0x0e, 0xf8, 0x6f, 0xf7, 0x1d, 0x15, 0x7e, 0x90, 0x05, 0x66, 0x52, 0x7e, + 0x82, 0x5e, 0x8b, 0x08, 0xfb, 0x83, 0x8b, 0xf7, 0x3c, 0xf7, 0x44, 0x05, + 0xe4, 0xe8, 0xb2, 0xd7, 0x8b, 0xd9, 0x8b, 0xef, 0x3a, 0xd8, 0x23, 0x8b, + 0x54, 0x8b, 0x57, 0x75, 0x66, 0x63, 0x6b, 0x69, 0x7c, 0x6b, 0x7a, 0x44, + 0x08, 0xa0, 0x86, 0x05, 0xb3, 0xed, 0xaf, 0xab, 0xd0, 0x8b, 0xdf, 0x8b, + 0xc4, 0x52, 0x8b, 0x37, 0x8b, 0x3d, 0x5d, 0x2e, 0x37, 0x32, 0x08, 0xfb, + 0x46, 0xfb, 0x51, 0x8b, 0x7f, 0xf8, 0x1a, 0x8b, 0xc2, 0xf7, 0x1d, 0x05, + 0x0e, 0xf7, 0x2d, 0xf7, 0xde, 0x15, 0xc6, 0x8b, 0xa2, 0x89, 0xa3, 0x82, + 0xc9, 0x75, 0xb2, 0x52, 0x8b, 0x46, 0x8b, 0x37, 0x52, 0x4a, 0x41, 0x8b, + 0x70, 0x8b, 0x77, 0x92, 0x66, 0xa3, 0x6d, 0x9d, 0x7a, 0x92, 0x7a, 0x8b, + 0x08, 0x74, 0x7c, 0x7d, 0x76, 0x68, 0xb6, 0x75, 0xd1, 0x1f, 0xd8, 0x8b, + 0xda, 0xa5, 0xba, 0xb4, 0xba, 0xb4, 0xa5, 0xc5, 0x8b, 0xce, 0x8b, 0xbe, + 0x7b, 0xba, 0x6e, 0xaa, 0x77, 0xa1, 0x78, 0x97, 0x5f, 0x9e, 0x08, 0xd0, + 0xba, 0xa4, 0xb0, 0x8b, 0xc1, 0x8b, 0xdc, 0x4b, 0xc3, 0x2f, 0x8b, 0x59, + 0x8b, 0x5f, 0x7a, 0x67, 0x6b, 0x6d, 0x70, 0x7c, 0x71, 0x75, 0x4f, 0x08, + 0x9a, 0x87, 0x05, 0xb4, 0xd4, 0xb8, 0xac, 0xca, 0x8b, 0xcc, 0x8b, 0xb8, + 0x5f, 0x8b, 0x4c, 0x8b, 0x67, 0x7c, 0x67, 0x72, 0x72, 0x6d, 0x6d, 0x6f, + 0x7c, 0x47, 0x73, 0x08, 0x7e, 0x07, 0x0e, 0xf8, 0x6c, 0xf7, 0x7b, 0x15, + 0x25, 0xf8, 0x51, 0x5f, 0x06, 0xfb, 0xce, 0xfc, 0x51, 0x8b, 0x4b, 0xf7, + 0xad, 0x8b, 0x8b, 0xfb, 0x3b, 0x05, 0xd8, 0xf7, 0x3b, 0xf1, 0x06, 0xcb, + 0x07, 0xfb, 0x48, 0x16, 0xfb, 0x84, 0x8b, 0xf7, 0x84, 0xf7, 0xeb, 0x8b, + 0xfb, 0xeb, 0x05, 0x0e, 0xf7, 0x49, 0xf8, 0xdb, 0x15, 0xf7, 0x58, 0x06, + 0x9b, 0x8b, 0x8f, 0x8d, 0x8e, 0x92, 0x08, 0xb1, 0xe4, 0x82, 0x92, 0x05, + 0x7c, 0x76, 0x81, 0x86, 0x76, 0x8b, 0x08, 0xfb, 0x65, 0x8b, 0xfb, 0x01, + 0xfb, 0x81, 0x05, 0x8a, 0x89, 0x8b, 0x8a, 0x8b, 0x89, 0x8b, 0x86, 0x8f, + 0x88, 0x93, 0x8b, 0xab, 0x8b, 0xb3, 0x84, 0xb4, 0x7e, 0xf7, 0x07, 0x66, + 0xc0, 0x4d, 0x8b, 0x28, 0x8b, 0x2b, 0x4e, 0x40, 0x3d, 0x8b, 0x77, 0x8b, + 0x7a, 0x92, 0x6d, 0xa1, 0x08, 0x6b, 0xa2, 0x74, 0x95, 0x76, 0x8b, 0x08, + 0x6e, 0x7d, 0x7f, 0x72, 0x65, 0xba, 0x73, 0xd6, 0x1f, 0xdf, 0x8b, 0xd3, + 0xa6, 0xbd, 0xbe, 0xb9, 0xb8, 0xa0, 0xc4, 0x8b, 0xd7, 0x8b, 0xd3, 0x78, + 0xb9, 0x59, 0xbd, 0x5f, 0xb7, 0x52, 0xa2, 0xfb, 0x0a, 0xa0, 0x08, 0xb5, + 0xe0, 0x05, 0x0e, 0xf8, 0x52, 0xf9, 0x40, 0x15, 0xfb, 0x06, 0x81, 0x51, + 0x78, 0x42, 0x58, 0xfb, 0x00, 0x3e, 0x50, 0xfb, 0x06, 0x8b, 0xfb, 0x1a, + 0x8b, 0x34, 0xa6, 0x33, 0xb6, 0x59, 0xb1, 0x5f, 0xc1, 0x73, 0xc9, 0x8b, + 0x08, 0xf7, 0x10, 0xe1, 0xea, 0xf7, 0x1e, 0xf7, 0x14, 0x42, 0xdc, 0xfb, + 0x07, 0x1f, 0x5f, 0x8b, 0x76, 0x84, 0x4c, 0x65, 0xa6, 0xf7, 0x2b, 0xf7, + 0x04, 0xf7, 0x00, 0xf7, 0x31, 0xa5, 0x08, 0x89, 0x9b, 0x05, 0xfb, 0x60, + 0xfb, 0xc2, 0x15, 0xe1, 0xbd, 0x43, 0xfb, 0x11, 0xfb, 0x02, 0x64, 0x4e, + 0x45, 0x33, 0x55, 0xe9, 0xf7, 0x2f, 0x1f, 0x8b, 0xbe, 0x93, 0xa7, 0x9f, + 0x9a, 0xa0, 0x9b, 0xaa, 0x94, 0xae, 0x8b, 0x08, 0x0e, 0xf8, 0x55, 0xf9, + 0x2a, 0x15, 0xfc, 0x06, 0x8b, 0x50, 0xfb, 0x27, 0x9c, 0x83, 0x05, 0xb6, + 0xcf, 0x9d, 0x98, 0xc2, 0x8b, 0x08, 0xf7, 0x6d, 0x8b, 0xfb, 0x5a, 0xfc, + 0xe8, 0xcc, 0x8b, 0xf7, 0x68, 0xf9, 0x22, 0x8b, 0x9b, 0x05, 0x0e, 0xf7, + 0xb6, 0xf8, 0x07, 0x15, 0xee, 0xc0, 0xae, 0xb5, 0x8b, 0xcf, 0x08, 0xdd, + 0x43, 0xc7, 0x27, 0xfb, 0x01, 0x3a, 0x48, 0x30, 0x1e, 0x8b, 0x4a, 0x9e, + 0x6e, 0xf4, 0x2f, 0x08, 0xfb, 0x00, 0x39, 0x75, 0x6c, 0x8b, 0x47, 0x08, + 0x2a, 0xda, 0x47, 0xf7, 0x05, 0xf7, 0x0c, 0xd8, 0xcd, 0xf2, 0x1e, 0x8b, + 0xd8, 0x69, 0xbc, 0xfb, 0x0d, 0xe5, 0x08, 0x79, 0x24, 0x15, 0xd4, 0x57, + 0xa3, 0x67, 0x8b, 0x53, 0x08, 0x4a, 0x5e, 0x5e, 0x4a, 0x3f, 0x58, 0xc5, + 0xe2, 0x1e, 0x8b, 0xcb, 0xa1, 0xb5, 0xc5, 0xba, 0x08, 0xc7, 0x5f, 0x05, + 0x80, 0xf7, 0x0d, 0x15, 0x32, 0xc5, 0x67, 0xb9, 0x8b, 0xc3, 0x08, 0xc5, + 0xb8, 0xb4, 0xca, 0xcf, 0xb6, 0x5f, 0x46, 0x1e, 0x8b, 0x52, 0x6f, 0x5e, + 0x52, 0x65, 0x08, 0x86, 0x88, 0x8b, 0x8b, 0x87, 0x88, 0x08, 0x0e, 0xc6, + 0x75, 0x15, 0xf7, 0x04, 0x98, 0xc2, 0x9e, 0xcf, 0xbc, 0xf3, 0xd7, 0xc8, + 0xf7, 0x10, 0x8b, 0xf7, 0x1b, 0x08, 0xf7, 0x39, 0x2f, 0xf7, 0x09, 0xfb, + 0x15, 0xfb, 0x0b, 0x32, 0x26, 0xfb, 0x1b, 0xfb, 0x0e, 0xd3, 0x3a, 0xf7, + 0x00, 0x1e, 0xc2, 0x8b, 0xb5, 0x9b, 0xc0, 0xb4, 0x62, 0xfb, 0x37, 0xfb, + 0x03, 0x20, 0xfb, 0x2c, 0x71, 0x08, 0x8e, 0x77, 0x05, 0xf7, 0xc3, 0xf8, + 0x0d, 0x15, 0x8b, 0x77, 0x87, 0x82, 0x80, 0x82, 0x6f, 0x73, 0x66, 0x7e, + 0x67, 0x8b, 0x3f, 0x8b, 0x5b, 0xd6, 0x8b, 0xf7, 0x0b, 0x8b, 0xc4, 0x9b, + 0xc7, 0xa0, 0xa5, 0x9c, 0x9f, 0xa4, 0x96, 0xa8, 0x8b, 0x08, 0xe2, 0xb8, + 0x35, 0xfb, 0x3c, 0x1f, 0x64, 0x07, 0x0e, 0x47, 0xf7, 0x1c, 0xf8, 0x5f, + 0x15, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, + 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0xfb, 0xfb, 0x04, 0x6d, 0x72, 0x71, + 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, 0x71, 0xa5, + 0x6d, 0x1f, 0x0e, 0x47, 0xf6, 0xfb, 0x21, 0x15, 0xd0, 0xad, 0xb6, 0xc7, + 0x8b, 0xc7, 0x08, 0xbd, 0x68, 0xb2, 0x5e, 0x68, 0x73, 0x75, 0x69, 0x1e, + 0x6a, 0xa1, 0x78, 0xb0, 0x1e, 0x91, 0x8b, 0x92, 0x8c, 0x91, 0x8c, 0x08, + 0x92, 0x8d, 0x8b, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0x91, 0x85, 0x8b, 0x83, + 0x8b, 0x6b, 0x6f, 0x66, 0x55, 0x66, 0x08, 0x94, 0x78, 0x05, 0xa8, 0xf8, + 0xec, 0x15, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, + 0xa4, 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0x0e, 0xf7, 0x6e, 0xf8, 0xac, + 0x81, 0x15, 0x8b, 0xd3, 0xfc, 0x38, 0xf7, 0x53, 0xf8, 0x38, 0xf7, 0x53, + 0x8b, 0xd3, 0xfc, 0x90, 0xfb, 0x7a, 0x8b, 0x49, 0xf8, 0x90, 0xfb, 0x7a, + 0x05, 0x0e, 0xf7, 0x6e, 0xf8, 0xaa, 0xf8, 0x16, 0x15, 0xfc, 0x8c, 0x49, + 0xf8, 0x8c, 0xcd, 0x06, 0xfb, 0x5c, 0x04, 0xfc, 0x8c, 0x49, 0xf8, 0x8c, + 0xcd, 0x06, 0x0e, 0xf7, 0x6e, 0xa7, 0x81, 0x15, 0xf8, 0x90, 0xf7, 0x7a, + 0x8b, 0xcd, 0xfc, 0x90, 0xf7, 0x7a, 0x8b, 0x43, 0xf8, 0x38, 0xfb, 0x53, + 0xfc, 0x38, 0xfb, 0x53, 0x8b, 0x43, 0x05, 0x0e, 0xed, 0xf7, 0x88, 0xf7, + 0x38, 0x15, 0x96, 0xce, 0x9c, 0xb3, 0xb0, 0xba, 0xb9, 0xc3, 0x8b, 0x8b, + 0x99, 0xa0, 0xab, 0xbc, 0x98, 0xaf, 0x8b, 0xb4, 0x8b, 0xb1, 0x7e, 0xaf, + 0x74, 0xa2, 0x68, 0xae, 0x50, 0xa2, 0x55, 0x8b, 0x08, 0x2f, 0x45, 0x4d, + 0x38, 0x63, 0x9c, 0x75, 0xaa, 0xa3, 0x9c, 0x9c, 0xa3, 0x1f, 0x8b, 0x99, + 0x85, 0x97, 0x7c, 0x9c, 0x7f, 0x99, 0x86, 0x94, 0x8b, 0x93, 0x08, 0xab, + 0xb9, 0xa9, 0xbc, 0xc7, 0xbb, 0x56, 0x48, 0x1e, 0x8b, 0x5d, 0x7e, 0x54, + 0x73, 0x54, 0x08, 0x6f, 0x4b, 0x05, 0x78, 0x5a, 0x81, 0x5a, 0x8a, 0x5f, + 0x08, 0x9c, 0x06, 0x84, 0x4a, 0x15, 0x6d, 0x74, 0x73, 0x6b, 0x6e, 0xa1, + 0x75, 0xa9, 0xab, 0xa2, 0xa1, 0xa9, 0xa9, 0x72, 0xa4, 0x6e, 0x1f, 0x0e, + 0xf8, 0xd3, 0xf9, 0x44, 0xd4, 0x15, 0x3d, 0x68, 0x58, 0x7e, 0x48, 0x8b, + 0xfb, 0x3e, 0x8b, 0xfb, 0x0e, 0xf7, 0x10, 0x8b, 0xf7, 0x42, 0x8b, 0xe8, + 0xaf, 0xe9, 0xc4, 0xc6, 0xbc, 0xbc, 0xce, 0xa6, 0xd4, 0x8b, 0x08, 0xf7, + 0x31, 0xf7, 0x16, 0xfb, 0x0f, 0xfb, 0x29, 0x27, 0x4c, 0x2a, 0x49, 0x71, + 0x7e, 0x9a, 0xaa, 0x1f, 0x8b, 0x92, 0x8c, 0x90, 0x8c, 0x91, 0x08, 0xcc, + 0xf7, 0x92, 0x46, 0x8b, 0x81, 0x65, 0x05, 0x75, 0xb4, 0x7c, 0x96, 0x68, + 0x8b, 0x60, 0x8b, 0x68, 0x7b, 0x69, 0x69, 0x56, 0x56, 0x6c, 0x3f, 0x8b, + 0x42, 0x08, 0x4c, 0xb2, 0x5a, 0xbc, 0x1e, 0xb7, 0x8b, 0xba, 0xa6, 0xad, + 0xb8, 0x08, 0x91, 0x5f, 0xb0, 0x6e, 0xbb, 0x8b, 0x08, 0xee, 0xe0, 0xf7, + 0x03, 0xf7, 0x15, 0xf7, 0x39, 0xfb, 0x23, 0xf7, 0x14, 0xfb, 0x4d, 0xfb, + 0x5f, 0xfb, 0x36, 0xfb, 0x2f, 0xfb, 0x57, 0xfb, 0x54, 0xf7, 0x34, 0xfb, + 0x28, 0xf7, 0x63, 0x1f, 0xd1, 0x8b, 0xbd, 0x98, 0xec, 0xb7, 0x08, 0x7f, + 0xa9, 0x05, 0xfb, 0x31, 0xf8, 0x1b, 0x15, 0xa7, 0x89, 0x9a, 0x73, 0x89, + 0x64, 0x89, 0x5b, 0x7a, 0x50, 0x71, 0x5c, 0x78, 0x67, 0x6e, 0x75, 0x70, + 0x8b, 0x66, 0x8b, 0x74, 0xac, 0x8b, 0xbf, 0x8b, 0xc1, 0x9d, 0xbd, 0xad, + 0xb1, 0x08, 0xa7, 0xab, 0xae, 0x9f, 0xa3, 0x89, 0x08, 0x0e, 0xf8, 0x0c, + 0xf9, 0x56, 0x9e, 0x15, 0x5e, 0x8e, 0x81, 0x95, 0x68, 0xd5, 0x08, 0xfb, + 0x8d, 0xf8, 0xcc, 0x77, 0x8b, 0xfb, 0x64, 0xfc, 0x7f, 0x05, 0x4b, 0xfb, + 0x26, 0x7f, 0x7b, 0x5b, 0x89, 0x08, 0x78, 0xf7, 0x5a, 0x9e, 0x07, 0x5b, + 0x77, 0x98, 0xa7, 0x1f, 0x8b, 0x97, 0x8e, 0x99, 0x90, 0x98, 0x08, 0xb9, + 0xf7, 0x09, 0xf7, 0x9a, 0x8b, 0xb4, 0x2b, 0x05, 0x97, 0x70, 0x92, 0x71, + 0x8b, 0x7d, 0x8b, 0x72, 0x7a, 0x83, 0x56, 0x8a, 0x08, 0x78, 0xf7, 0x93, + 0x9e, 0x07, 0xfc, 0x7e, 0xf7, 0x82, 0x15, 0xf7, 0x07, 0xf7, 0xa7, 0xf7, + 0x08, 0xfb, 0xa7, 0xfb, 0x7b, 0x8b, 0x05, 0x0e, 0xf7, 0xd5, 0x9c, 0xf9, + 0x2a, 0x15, 0x78, 0x07, 0xdf, 0x86, 0x97, 0x80, 0x8b, 0x41, 0x08, 0xfc, + 0x50, 0x07, 0x8b, 0x41, 0x7e, 0x7e, 0x38, 0x88, 0x08, 0x78, 0xf7, 0xe2, + 0x07, 0xd9, 0x8b, 0xd2, 0xa0, 0xb0, 0xad, 0xaf, 0xab, 0x9f, 0xb8, 0x8b, + 0xbb, 0x8b, 0xb7, 0x79, 0xb3, 0x6c, 0xa8, 0x6d, 0xa6, 0x70, 0x97, 0x4a, + 0x9b, 0xbf, 0x98, 0xa0, 0x95, 0xa3, 0xa0, 0x08, 0xa4, 0xa1, 0x9a, 0xb0, + 0x8b, 0xb4, 0x08, 0xf7, 0x04, 0x32, 0xc5, 0xfb, 0x41, 0x1e, 0xfb, 0xac, + 0x06, 0xf7, 0x5a, 0xfb, 0xe4, 0x15, 0xec, 0x8b, 0xb9, 0x86, 0xaf, 0x7c, + 0x08, 0xc4, 0x73, 0xa6, 0x63, 0x8b, 0x4c, 0x8b, 0x55, 0x76, 0x64, 0x63, + 0x74, 0x6b, 0x79, 0x62, 0x83, 0x49, 0x8b, 0x08, 0x5a, 0x7d, 0x94, 0xab, + 0x1f, 0xf7, 0x8c, 0x07, 0xb3, 0x04, 0xf7, 0x79, 0x07, 0xa0, 0x92, 0x94, + 0x9a, 0x1e, 0xb7, 0x06, 0xf7, 0x07, 0xc8, 0x5b, 0x32, 0x3d, 0x56, 0x5f, + 0x2d, 0x1f, 0x2c, 0x06, 0x0e, 0xf7, 0xd5, 0xf9, 0x00, 0xf8, 0x56, 0x15, + 0x82, 0xf7, 0x76, 0x76, 0x8b, 0x05, 0x85, 0x76, 0x7b, 0x7f, 0x77, 0x8b, + 0x82, 0x8b, 0x7c, 0x8e, 0x7c, 0x91, 0x5a, 0x9b, 0x59, 0x93, 0x5c, 0x8b, + 0x39, 0x8b, 0x38, 0x6c, 0x4d, 0x54, 0x45, 0x4d, 0x65, 0x2e, 0x8b, 0xfb, + 0x02, 0x8b, 0x2e, 0xa9, 0x35, 0xbe, 0x52, 0x08, 0xc7, 0x4a, 0xe7, 0x65, + 0xee, 0x8b, 0xf7, 0x05, 0x8b, 0xee, 0xb9, 0xc8, 0xdc, 0x08, 0x79, 0x9d, + 0x05, 0x41, 0x44, 0x49, 0x6d, 0x38, 0x8b, 0x4c, 0x8b, 0x53, 0x9f, 0x60, + 0xb1, 0x54, 0xbc, 0x6c, 0xe5, 0x8b, 0xf7, 0x03, 0x8b, 0xf7, 0x49, 0xe8, + 0xf7, 0x09, 0xf7, 0x25, 0x8b, 0xc4, 0x8b, 0xbf, 0x76, 0xb3, 0x63, 0xab, + 0x6b, 0x9a, 0x6f, 0x9e, 0x4a, 0x08, 0xa2, 0x06, 0x0e, 0xf8, 0x0c, 0xf3, + 0xf7, 0x01, 0x15, 0x8b, 0x43, 0x7f, 0x7e, 0x3f, 0x86, 0x08, 0x78, 0xf7, + 0xb0, 0x07, 0xf7, 0x08, 0x8b, 0xf4, 0xac, 0xc9, 0xc3, 0xcc, 0xc6, 0xb0, + 0xe4, 0x8b, 0xec, 0x8b, 0xe5, 0x6d, 0xd9, 0x54, 0xc2, 0x47, 0xd0, 0xfb, + 0x01, 0xaf, 0xfb, 0x1d, 0x8b, 0x08, 0xfb, 0xa2, 0x06, 0x78, 0x07, 0xda, + 0x84, 0x94, 0x82, 0x8b, 0x41, 0x08, 0xfc, 0x50, 0x07, 0xf1, 0xf8, 0x71, + 0x15, 0xaa, 0x96, 0x93, 0xb4, 0x1e, 0xe1, 0x8b, 0xcc, 0x7b, 0xbb, 0x69, + 0xd9, 0x55, 0xb4, 0x35, 0x8b, 0xfb, 0x00, 0x8b, 0xfb, 0x0a, 0x62, 0x37, + 0x3a, 0x5c, 0x58, 0x6e, 0x51, 0x7f, 0x34, 0x8b, 0x08, 0x63, 0x7f, 0x94, + 0xab, 0x1f, 0xf8, 0x90, 0x07, 0x0e, 0xf7, 0x9d, 0xf8, 0xe9, 0xf7, 0x3d, + 0x15, 0x6f, 0x06, 0x59, 0xfb, 0x00, 0x60, 0x73, 0xfb, 0x23, 0x8b, 0x08, + 0x70, 0x06, 0x5a, 0x8b, 0x61, 0x90, 0x84, 0x92, 0x86, 0x8e, 0x89, 0x96, + 0x8b, 0x9c, 0x08, 0xf7, 0x8b, 0xf7, 0x2e, 0x07, 0xdd, 0x8b, 0x9a, 0x7e, + 0x98, 0x38, 0x08, 0xa2, 0xf7, 0x7c, 0x74, 0x06, 0x84, 0x62, 0x87, 0x7c, + 0x80, 0x7d, 0x7e, 0x7a, 0x6f, 0x83, 0x5c, 0x8b, 0x08, 0xfb, 0x2e, 0xf7, + 0x72, 0x06, 0xa7, 0x91, 0x91, 0xa6, 0x1e, 0xf7, 0x1b, 0x06, 0xf7, 0x05, + 0x8b, 0xa1, 0x7c, 0x9c, 0x31, 0x08, 0xa4, 0x8b, 0x88, 0xf7, 0x23, 0xfc, + 0xa7, 0x8b, 0x05, 0x78, 0x07, 0xd5, 0x85, 0x98, 0x7d, 0x8b, 0x45, 0x08, + 0xfc, 0x50, 0x07, 0x8b, 0x45, 0x7d, 0x7c, 0x42, 0x86, 0x08, 0x78, 0xf8, + 0xb0, 0x07, 0xb8, 0xf7, 0x3d, 0x05, 0x0e, 0xf7, 0x66, 0xf8, 0x73, 0xf7, + 0x7b, 0x15, 0xf7, 0x7c, 0x74, 0x07, 0x7f, 0x3b, 0x79, 0x7c, 0x3b, 0x8b, + 0x08, 0xfb, 0x25, 0xf7, 0x72, 0x06, 0xa7, 0x90, 0x91, 0xa6, 0x1e, 0xf7, + 0x1c, 0x06, 0xf7, 0x05, 0x8b, 0xa1, 0x7c, 0x9c, 0x31, 0x08, 0xa4, 0x8b, + 0x88, 0xf7, 0x23, 0xfc, 0xa7, 0x8b, 0x05, 0x78, 0x07, 0xd5, 0x85, 0x98, + 0x7d, 0x8b, 0x45, 0x08, 0xfc, 0x45, 0x07, 0x8b, 0x38, 0x80, 0x7e, 0x3f, + 0x86, 0x08, 0x78, 0xf7, 0xac, 0x9e, 0x07, 0x3e, 0x8f, 0x7d, 0x99, 0x8b, + 0xd3, 0x08, 0xf7, 0x6e, 0xf7, 0x25, 0x07, 0xdc, 0x8b, 0x9c, 0x7c, 0x97, + 0x3a, 0x08, 0xa2, 0x06, 0x0e, 0xf8, 0x0c, 0xf9, 0x59, 0xf7, 0xf6, 0x15, + 0xfb, 0x93, 0x79, 0x06, 0xb6, 0x88, 0x97, 0x88, 0x97, 0x83, 0x9a, 0x82, + 0x91, 0x74, 0x8b, 0x60, 0x08, 0xfb, 0x36, 0x07, 0x6b, 0x4e, 0x70, 0x43, + 0xfb, 0x37, 0x27, 0xf7, 0x06, 0xf7, 0x4e, 0x1e, 0x8b, 0xe9, 0xa7, 0xe6, + 0xb7, 0xbc, 0xb7, 0xbc, 0xc9, 0xa6, 0xcf, 0x8b, 0xc3, 0x8b, 0xbc, 0x78, + 0xb2, 0x67, 0xa9, 0x6f, 0x9b, 0x70, 0xa4, 0x4e, 0x08, 0xa2, 0x8b, 0x83, + 0xf7, 0x67, 0x75, 0x8b, 0x05, 0x85, 0x78, 0x79, 0x7d, 0x76, 0x8b, 0x81, + 0x8b, 0x7b, 0x8e, 0x79, 0x92, 0x5e, 0x9a, 0x5d, 0x93, 0x5e, 0x8b, 0xfb, + 0x5c, 0x8b, 0xfb, 0x23, 0xfb, 0x27, 0x8b, 0xfb, 0x60, 0x8b, 0x29, 0xa6, + 0x40, 0xc3, 0x50, 0xce, 0x46, 0xeb, 0x65, 0xf7, 0x02, 0x8b, 0x08, 0xe1, + 0x8b, 0xf7, 0x11, 0xae, 0xb3, 0xae, 0x08, 0xf7, 0x5f, 0x07, 0x8b, 0xc6, + 0x97, 0x98, 0xc5, 0x90, 0x08, 0x9d, 0x07, 0x0e, 0xf8, 0x0c, 0xf7, 0x65, + 0xf7, 0xfb, 0x15, 0xf7, 0x56, 0x07, 0x8b, 0xd3, 0x96, 0x96, 0xd8, 0x92, + 0x08, 0x9e, 0xfb, 0xaa, 0x78, 0x07, 0xd8, 0x84, 0x96, 0x80, 0x8b, 0x43, + 0x08, 0xfc, 0x45, 0x07, 0x8b, 0x37, 0x81, 0x7f, 0x3d, 0x86, 0x08, 0x78, + 0xf7, 0xaa, 0x9e, 0x07, 0x40, 0x91, 0x7e, 0x98, 0x8b, 0xd2, 0x08, 0xf7, + 0x62, 0xf7, 0xc3, 0xfb, 0x57, 0x07, 0x8b, 0x37, 0x81, 0x7f, 0x3d, 0x86, + 0x08, 0x78, 0xf7, 0xaa, 0x9e, 0x07, 0x40, 0x91, 0x7e, 0x98, 0x8b, 0xd2, + 0x08, 0xf8, 0x50, 0x07, 0x8b, 0xd3, 0x96, 0x96, 0xd8, 0x92, 0x08, 0x9e, + 0xfb, 0xaa, 0x78, 0x07, 0xd8, 0x84, 0x96, 0x80, 0x8b, 0x43, 0x08, 0xfb, + 0x56, 0xfb, 0xc3, 0x07, 0x0e, 0x7e, 0xf7, 0x07, 0xf7, 0x01, 0x15, 0x8b, + 0x40, 0x7e, 0x7f, 0x37, 0x88, 0x08, 0x78, 0xf7, 0xbd, 0x9e, 0x07, 0x39, + 0x8e, 0x7b, 0x99, 0x8b, 0xd4, 0x08, 0xf8, 0x50, 0x07, 0x8b, 0xd4, 0x99, + 0x98, 0xdf, 0x8f, 0x08, 0x9e, 0xfb, 0xbd, 0x78, 0x07, 0xe0, 0x86, 0x97, + 0x80, 0x8b, 0x41, 0x08, 0xfc, 0x50, 0x07, 0x0e, 0xb6, 0xf7, 0xaa, 0xf8, + 0xbd, 0x15, 0x8b, 0xd4, 0x96, 0x96, 0xdc, 0x91, 0x08, 0x9e, 0xfb, 0xb3, + 0x78, 0x07, 0xdd, 0x85, 0x96, 0x80, 0x8b, 0x42, 0x08, 0xfc, 0x63, 0x07, + 0x5e, 0x7f, 0x76, 0x71, 0x1e, 0x7d, 0x8b, 0x85, 0x93, 0x84, 0xa4, 0x81, + 0xae, 0x7b, 0x9b, 0x71, 0x8b, 0x08, 0x70, 0x75, 0x74, 0x70, 0x61, 0xb4, + 0x6d, 0xc5, 0xf7, 0x00, 0xc8, 0xd3, 0xf7, 0x11, 0x1f, 0xf8, 0x06, 0x07, + 0x0e, 0xf8, 0x0c, 0xf8, 0x31, 0xf9, 0x17, 0x15, 0x97, 0x8a, 0x95, 0x8b, + 0x8f, 0x8b, 0xa9, 0x89, 0x97, 0x83, 0x8b, 0x77, 0x8b, 0x75, 0x74, 0x6d, + 0x54, 0x58, 0x08, 0xfb, 0x45, 0xfb, 0x35, 0x8b, 0xf7, 0x61, 0x05, 0x8b, + 0xd4, 0x96, 0x96, 0xdc, 0x91, 0x08, 0x9e, 0xfb, 0xb0, 0x78, 0x07, 0xd9, + 0x85, 0x97, 0x7e, 0x8b, 0x44, 0x08, 0xfc, 0x45, 0x07, 0x8b, 0x38, 0x80, + 0x7e, 0x3c, 0x86, 0x08, 0x78, 0xf7, 0xae, 0x9e, 0x07, 0x3d, 0x90, 0x7f, + 0x97, 0x8b, 0xd4, 0x08, 0x8b, 0xf7, 0x4f, 0xa5, 0xa0, 0xf5, 0x22, 0x05, + 0xd7, 0x40, 0xc1, 0x44, 0x8b, 0x73, 0x8b, 0x7d, 0x7d, 0x84, 0x6f, 0x8a, + 0x86, 0x8b, 0x80, 0x8b, 0x7f, 0x8a, 0x08, 0x78, 0xf7, 0xc5, 0x9e, 0x07, + 0x57, 0x8c, 0x7d, 0x95, 0x30, 0xec, 0x08, 0xfb, 0x7d, 0xf7, 0x8e, 0xf7, + 0x52, 0xf7, 0x50, 0x05, 0xcf, 0xcc, 0x9b, 0x93, 0xcf, 0x90, 0x08, 0x9e, + 0xfb, 0x9a, 0x78, 0x07, 0x0e, 0xf7, 0x9d, 0xf8, 0xd1, 0xf7, 0x42, 0x15, + 0x7a, 0x65, 0x7d, 0x74, 0x7c, 0x7a, 0x68, 0x64, 0x54, 0x79, 0x38, 0x8b, + 0x08, 0x48, 0x06, 0x42, 0x7e, 0x91, 0xae, 0x1f, 0xf8, 0x6d, 0x07, 0x8b, + 0xd2, 0x99, 0x99, 0xda, 0x90, 0x08, 0x9e, 0xfb, 0xae, 0x78, 0x07, 0xd5, + 0x85, 0x98, 0x7d, 0x8b, 0x45, 0x08, 0xfc, 0x50, 0x07, 0x8b, 0x45, 0x7d, + 0x7c, 0x42, 0x86, 0x08, 0x78, 0xf8, 0xae, 0x07, 0xbb, 0xf7, 0x42, 0x05, + 0x72, 0x06, 0x0e, 0xf8, 0xb3, 0xf9, 0x36, 0xf8, 0xd1, 0x15, 0xfc, 0x59, + 0x07, 0x8b, 0x38, 0x7f, 0x7e, 0x3c, 0x86, 0x08, 0x78, 0xf7, 0xac, 0x9e, + 0x07, 0x42, 0x90, 0x7d, 0x99, 0x8b, 0xd2, 0x08, 0xf8, 0x50, 0x07, 0x8b, + 0xd2, 0x98, 0x98, 0xd5, 0x91, 0x08, 0x9e, 0xfb, 0x5b, 0x07, 0xfb, 0x71, + 0xfc, 0x8d, 0xfb, 0x7b, 0xf8, 0x8d, 0xfb, 0x5a, 0x8b, 0x8b, 0x78, 0x05, + 0xdd, 0x86, 0x98, 0x7f, 0x8b, 0x42, 0x08, 0xfc, 0x2a, 0x07, 0x8b, 0x24, + 0x7d, 0x78, 0x38, 0x85, 0x08, 0x78, 0xf7, 0x7f, 0x9e, 0x07, 0x3e, 0x8f, + 0x7a, 0xa2, 0x8b, 0xf0, 0x08, 0x8b, 0xf8, 0x27, 0xf7, 0x8f, 0xfc, 0xba, + 0x99, 0x8b, 0xf7, 0x94, 0xf8, 0xd1, 0x05, 0x0e, 0xf8, 0x0c, 0xf8, 0xf8, + 0x80, 0x15, 0xf8, 0xa2, 0x07, 0x8b, 0xc7, 0x95, 0xb0, 0x9e, 0x98, 0x99, + 0x95, 0x99, 0x8f, 0xb1, 0x8f, 0x08, 0x9e, 0xfb, 0x7f, 0x78, 0x07, 0xb1, + 0x88, 0x99, 0x87, 0x9a, 0x82, 0x9f, 0x7d, 0x94, 0x67, 0x8b, 0x4d, 0x08, + 0x8b, 0xfb, 0xe5, 0xfc, 0x15, 0xf8, 0x78, 0xfb, 0x3f, 0x8b, 0x8b, 0x78, + 0x05, 0xb6, 0x8b, 0x99, 0x83, 0xb3, 0x5c, 0x08, 0xfc, 0x4d, 0x07, 0x8b, + 0x24, 0x7d, 0x78, 0x38, 0x85, 0x08, 0x78, 0xf7, 0x7f, 0x9e, 0x07, 0x3e, + 0x8f, 0x7a, 0xa2, 0x8b, 0xf0, 0x08, 0x8b, 0xf8, 0x1c, 0x05, 0xf8, 0x4e, + 0xfc, 0xba, 0x05, 0x9c, 0x06, 0x0e, 0xf8, 0x0c, 0xf7, 0xfd, 0xf9, 0x38, + 0x15, 0xfb, 0x53, 0xfb, 0x1c, 0xfb, 0x24, 0xfb, 0x5d, 0x1f, 0x8b, 0x2d, + 0xab, 0x30, 0xc1, 0x51, 0xc5, 0x4c, 0xe4, 0x64, 0xe3, 0x8b, 0xf7, 0x59, + 0x8b, 0xf7, 0x1c, 0xf7, 0x20, 0x8b, 0xf7, 0x5d, 0x8b, 0xee, 0x6e, 0xe0, + 0x54, 0xc7, 0x4c, 0xd0, 0x37, 0xaf, 0x2b, 0x8b, 0x08, 0x67, 0x04, 0xb9, + 0x8b, 0xb9, 0x79, 0xaf, 0x6b, 0xc1, 0x5a, 0xaa, 0x2d, 0x8b, 0xfb, 0x0b, + 0x8b, 0x50, 0x7e, 0x46, 0x77, 0x57, 0x82, 0x72, 0x7a, 0x72, 0x74, 0x74, + 0x68, 0x68, 0x5e, 0x79, 0x56, 0x8b, 0x5d, 0x8b, 0x5e, 0x9d, 0x68, 0xaa, + 0x08, 0x57, 0xb9, 0x6a, 0xf0, 0x8b, 0xf7, 0x03, 0x8b, 0xf1, 0xa7, 0xec, + 0xb5, 0xba, 0xb2, 0xb6, 0xbc, 0xa1, 0xc2, 0x8b, 0x08, 0x0e, 0xf7, 0x66, + 0xf7, 0x5e, 0xf7, 0xb7, 0x15, 0xa5, 0x89, 0x9c, 0x8a, 0xa5, 0x8b, 0xd9, + 0x8b, 0xc1, 0x95, 0xb6, 0xa3, 0xc7, 0xab, 0xaf, 0xc8, 0x8b, 0xcd, 0x8b, + 0xb5, 0x7d, 0xb1, 0x70, 0xa8, 0x63, 0xb7, 0x34, 0xa7, 0x2d, 0x8b, 0x08, + 0xfb, 0x9c, 0x06, 0x78, 0x07, 0xd5, 0x83, 0x95, 0x81, 0x8b, 0x43, 0x08, + 0xfc, 0x45, 0x07, 0x8b, 0x37, 0x83, 0x81, 0x3f, 0x84, 0x08, 0x78, 0xf7, + 0xac, 0x9e, 0x07, 0x3c, 0x8e, 0x7c, 0x99, 0x8b, 0xd4, 0x08, 0xf7, 0x4a, + 0x07, 0xf7, 0xc0, 0x04, 0xa6, 0x92, 0x92, 0xa6, 0xf7, 0x1b, 0xc9, 0x5c, + 0x24, 0x2a, 0x50, 0x59, 0xfb, 0x07, 0x1e, 0x77, 0x8b, 0x7d, 0x8c, 0x74, + 0x8d, 0x08, 0xf7, 0x98, 0x07, 0x0e, 0xf8, 0x0c, 0xf9, 0x51, 0xfb, 0x33, + 0x15, 0xfb, 0x06, 0x8e, 0x3b, 0xb7, 0x3a, 0xf4, 0xcf, 0x98, 0xaf, 0x9c, + 0xb9, 0xb3, 0xd5, 0xcd, 0xb1, 0xe6, 0x8b, 0xf7, 0x03, 0x08, 0xf7, 0x5d, + 0xfb, 0x1c, 0xf7, 0x24, 0xfb, 0x53, 0xfb, 0x53, 0xfb, 0x1c, 0xfb, 0x24, + 0xfb, 0x5f, 0x1e, 0x8b, 0x29, 0xa9, 0x39, 0xc6, 0x4b, 0xb2, 0x61, 0xab, + 0x77, 0xd2, 0x73, 0x08, 0xba, 0x54, 0x05, 0xcf, 0x3c, 0xf7, 0x0d, 0x60, + 0xf7, 0x33, 0x8b, 0x9a, 0x8b, 0x94, 0x8b, 0x96, 0x8c, 0x08, 0x91, 0x9d, + 0x06, 0xfb, 0xe5, 0xf9, 0xb3, 0x15, 0xb6, 0x8b, 0xb9, 0x78, 0xae, 0x6c, + 0xc1, 0x5b, 0xab, 0x2b, 0x8b, 0xfb, 0x05, 0x8b, 0x28, 0x6e, 0x25, 0x63, + 0x5d, 0x66, 0x62, 0x57, 0x74, 0x54, 0x8b, 0x5b, 0x8b, 0x5f, 0x9c, 0x67, + 0xab, 0x56, 0xba, 0x6b, 0xef, 0x8b, 0xf7, 0x09, 0x08, 0x8b, 0xeb, 0xa8, + 0xed, 0xb4, 0xb9, 0xb4, 0xb7, 0xba, 0xa0, 0xc5, 0x8b, 0x08, 0x0e, 0xf7, + 0xd5, 0xf9, 0x27, 0x9e, 0x15, 0x65, 0x8e, 0x77, 0x95, 0x6e, 0xad, 0x08, + 0xfb, 0x62, 0xf7, 0x91, 0x05, 0xce, 0x98, 0xa9, 0x97, 0xac, 0xa6, 0xab, + 0xa5, 0x9e, 0xb5, 0x8b, 0xba, 0x8b, 0xb6, 0x7e, 0xb0, 0x71, 0xa8, 0x65, + 0xb4, 0x38, 0xa5, 0x2d, 0x8b, 0x08, 0xfb, 0xa8, 0x06, 0x78, 0x07, 0xd6, + 0x83, 0x95, 0x80, 0x8b, 0x44, 0x08, 0xfc, 0x45, 0x07, 0x8b, 0x38, 0x81, + 0x7f, 0x40, 0x85, 0x08, 0x78, 0xf7, 0xa9, 0x9e, 0x07, 0x3e, 0x90, 0x7e, + 0x98, 0x8b, 0xd3, 0x08, 0x8b, 0xf7, 0x59, 0xc3, 0x8d, 0xf7, 0x82, 0xfb, + 0xc8, 0xf7, 0x35, 0x8b, 0x05, 0x9e, 0x07, 0xfc, 0x5b, 0xf8, 0xce, 0x15, + 0xa7, 0x96, 0x93, 0xb3, 0xf7, 0x11, 0xc5, 0x60, 0x2d, 0x1e, 0x8b, 0x59, + 0x76, 0x61, 0x67, 0x78, 0x5d, 0x71, 0x68, 0x85, 0x2b, 0x89, 0x08, 0xf7, + 0x8a, 0x07, 0x0e, 0xf7, 0x66, 0xf8, 0x53, 0xf9, 0x38, 0x15, 0x76, 0x06, + 0x87, 0x74, 0x80, 0x80, 0x7a, 0x8b, 0x81, 0x8b, 0x7a, 0x8f, 0x7a, 0x93, + 0x08, 0x66, 0x99, 0x66, 0x93, 0x6b, 0x8b, 0x60, 0x8b, 0x5f, 0x7a, 0x6a, + 0x6e, 0x68, 0x6c, 0x79, 0x61, 0x8b, 0x57, 0x8b, 0x3b, 0xb7, 0x53, 0xf7, + 0x04, 0x50, 0xd3, 0x65, 0xbf, 0x62, 0xa4, 0x65, 0x94, 0x7e, 0x90, 0x76, + 0x8b, 0x73, 0x08, 0x48, 0x59, 0x5d, 0x42, 0x1e, 0x32, 0x8b, 0x4c, 0xc2, + 0x59, 0xf7, 0x0e, 0x08, 0x74, 0x8b, 0xa9, 0xfb, 0x68, 0xa1, 0x8b, 0x05, + 0x8c, 0x9e, 0x97, 0x99, 0x9a, 0x8b, 0x96, 0x8b, 0x9c, 0x87, 0x9e, 0x84, + 0x08, 0xb1, 0x7c, 0xb3, 0x83, 0xb3, 0x8b, 0xf7, 0x07, 0x8b, 0xe4, 0xda, + 0x8b, 0xf2, 0x8b, 0xdd, 0x54, 0xcc, 0xfb, 0x18, 0xd2, 0x22, 0xc5, 0x61, + 0xb7, 0x8b, 0xc1, 0x8b, 0xc2, 0xb5, 0xb1, 0xc9, 0x8b, 0xb8, 0x8b, 0xb5, + 0x78, 0xae, 0x67, 0x08, 0xaa, 0x6b, 0x99, 0x71, 0x9b, 0x50, 0x08, 0xa4, + 0x8b, 0x05, 0x75, 0xf7, 0x69, 0x05, 0x0e, 0xf7, 0x9d, 0xf7, 0x92, 0xf9, + 0x00, 0x15, 0xfc, 0x88, 0x07, 0x8b, 0x36, 0x80, 0x80, 0x38, 0x86, 0x08, + 0x78, 0xf7, 0xb8, 0x9e, 0x07, 0x39, 0x8f, 0x7d, 0x98, 0x8b, 0xd4, 0x08, + 0xf8, 0x93, 0xc1, 0x07, 0xf7, 0x06, 0x8b, 0xa1, 0x79, 0xa2, 0xfb, 0x02, + 0x08, 0xa3, 0x8b, 0x85, 0xf7, 0x3e, 0xfc, 0xc8, 0x8b, 0x85, 0xfb, 0x3e, + 0xa3, 0x8b, 0x05, 0xa3, 0xf7, 0x01, 0xa2, 0x9e, 0xf7, 0x04, 0x8b, 0x08, + 0xc1, 0x06, 0x0e, 0xf8, 0x0c, 0xf8, 0xf7, 0xf8, 0x97, 0x15, 0x8b, 0xf1, + 0x97, 0x9b, 0xdd, 0x95, 0x08, 0x9e, 0xfb, 0x7c, 0x78, 0x07, 0xd9, 0x85, + 0x9b, 0x75, 0x8b, 0x27, 0x08, 0xfb, 0xa2, 0x07, 0x8b, 0x47, 0x84, 0x65, + 0x7b, 0x6d, 0x70, 0x5b, 0x4b, 0x6c, 0x40, 0x8b, 0x44, 0x8b, 0x5a, 0xa3, + 0x70, 0xba, 0x79, 0xab, 0x84, 0xb0, 0x8b, 0xca, 0x08, 0xf7, 0xd4, 0x07, + 0x8b, 0xd3, 0x96, 0x96, 0xdb, 0x92, 0x08, 0x9e, 0xfb, 0xaf, 0x78, 0x07, + 0xda, 0x85, 0x96, 0x80, 0x8b, 0x42, 0x08, 0xfb, 0xcc, 0x07, 0xfb, 0x41, + 0xdc, 0x39, 0xf7, 0x3e, 0x1e, 0xf7, 0x01, 0x8b, 0xd6, 0xae, 0xb2, 0xcf, + 0xa3, 0xb5, 0x94, 0xb9, 0x8b, 0xd8, 0x08, 0xf7, 0x99, 0x07, 0x0e, 0xf8, + 0x0c, 0xf9, 0x4d, 0xf9, 0x2a, 0x15, 0xfb, 0x61, 0x78, 0x06, 0xc2, 0x88, + 0x9d, 0x80, 0x8b, 0x6f, 0x8b, 0x7b, 0x84, 0x70, 0x7f, 0x6d, 0x08, 0xfb, + 0x27, 0xfc, 0x03, 0xfb, 0x2b, 0xf7, 0xe6, 0x05, 0x6a, 0xd4, 0x83, 0xa2, + 0x8b, 0x9a, 0x8b, 0x9e, 0x99, 0x95, 0xab, 0x8d, 0x8f, 0x8b, 0x96, 0x8c, + 0x99, 0x8c, 0x08, 0x9e, 0xfb, 0x9e, 0x78, 0x07, 0xbc, 0x89, 0x99, 0x7d, + 0xb6, 0x32, 0x08, 0xf7, 0x8a, 0xfc, 0xb9, 0x9a, 0x8b, 0xf7, 0x72, 0xf8, + 0xc5, 0x05, 0xac, 0xda, 0x96, 0x96, 0xbb, 0x8e, 0x08, 0x9e, 0x07, 0x0e, + 0xf8, 0xea, 0xfa, 0x38, 0xf9, 0x2a, 0x15, 0xfb, 0x5a, 0x78, 0x06, 0xbe, + 0x86, 0x9d, 0x80, 0x8b, 0x70, 0x8b, 0x76, 0x85, 0x71, 0x81, 0x6f, 0x08, + 0xfb, 0x11, 0xfb, 0xe7, 0xfb, 0x18, 0xf7, 0xe9, 0x05, 0x89, 0x90, 0x82, + 0xa1, 0x8a, 0x8e, 0x82, 0xa0, 0x85, 0x9e, 0x8b, 0x96, 0x8b, 0xa3, 0xa2, + 0x95, 0xc1, 0x8c, 0x08, 0x9e, 0xfb, 0x9f, 0x78, 0x07, 0xc4, 0x8a, 0x95, + 0x82, 0xad, 0x3b, 0x08, 0xac, 0x39, 0x20, 0xfb, 0xae, 0xfb, 0x24, 0xf8, + 0x0c, 0x05, 0x84, 0x9d, 0x87, 0x9c, 0x8b, 0x96, 0x8b, 0xa1, 0x99, 0x92, + 0xbe, 0x8e, 0x08, 0x9e, 0xfb, 0x89, 0x78, 0x07, 0xbe, 0x86, 0x9a, 0x79, + 0xb0, 0x2d, 0x08, 0xf7, 0x55, 0xfc, 0xad, 0x9a, 0x8b, 0xf7, 0x2e, 0xf8, + 0x3b, 0xf7, 0x34, 0xfc, 0x3b, 0x9a, 0x8b, 0x05, 0xe0, 0xf7, 0x99, 0x95, + 0xa7, 0xf7, 0x01, 0xf7, 0xba, 0x9e, 0xbf, 0x96, 0x94, 0xc0, 0x95, 0x08, + 0x9e, 0x07, 0x0e, 0xf8, 0x0c, 0xf9, 0x4c, 0xf9, 0x2a, 0x15, 0xfb, 0x82, + 0x78, 0x06, 0xc1, 0x89, 0x9b, 0x84, 0x8b, 0x74, 0x8b, 0x7c, 0x80, 0x79, + 0x6e, 0x67, 0x08, 0xfb, 0x05, 0xfb, 0x1e, 0x61, 0xc6, 0x05, 0x4e, 0xe0, + 0x73, 0xb6, 0x8b, 0xa1, 0x8b, 0x9f, 0x9a, 0x93, 0xac, 0x8c, 0x08, 0xa7, + 0x8c, 0x8b, 0x9e, 0xfb, 0xc2, 0x8b, 0x8b, 0x78, 0x05, 0xcc, 0x88, 0x9d, + 0x7c, 0xed, 0xfb, 0x1f, 0x08, 0xf7, 0x01, 0xfb, 0x34, 0xfb, 0x31, 0xfb, + 0x55, 0x05, 0x32, 0x21, 0x86, 0x87, 0x58, 0x87, 0x08, 0x78, 0xf7, 0x7d, + 0x9e, 0x07, 0x51, 0x8f, 0x79, 0x93, 0x8b, 0xa2, 0x8b, 0x9a, 0x9a, 0xa4, + 0xb0, 0xb9, 0x08, 0xf7, 0x0b, 0xf7, 0x28, 0xea, 0xfb, 0x20, 0x05, 0xac, + 0x5a, 0x9d, 0x69, 0x8b, 0x7c, 0x8b, 0x79, 0x7b, 0x81, 0x69, 0x8a, 0x87, + 0x8b, 0x80, 0x8a, 0x7f, 0x8a, 0x08, 0x78, 0xf7, 0xbd, 0x9e, 0x07, 0x56, + 0x91, 0x7c, 0x95, 0x60, 0xc5, 0x08, 0xfb, 0x54, 0xf7, 0xa6, 0xf7, 0x26, + 0xf7, 0x4a, 0x05, 0xcc, 0xd9, 0x9f, 0x97, 0xcb, 0x8f, 0x08, 0x9e, 0x07, + 0x0e, 0xf8, 0x0c, 0xf9, 0x53, 0xf9, 0x2a, 0x15, 0xfb, 0x6f, 0x78, 0x06, + 0xbf, 0x8a, 0x9c, 0x83, 0x8b, 0x73, 0x8b, 0x81, 0x86, 0x7f, 0x82, 0x7c, + 0x08, 0xfb, 0x23, 0xfb, 0x76, 0xfb, 0x28, 0xf7, 0x72, 0x05, 0x80, 0x9b, + 0x85, 0x9c, 0x8b, 0x96, 0x8b, 0x9d, 0x99, 0x94, 0xab, 0x8d, 0x8f, 0x8b, + 0x95, 0x8b, 0x96, 0x8c, 0x08, 0x9e, 0xfb, 0xac, 0x78, 0x07, 0xbb, 0x89, + 0x99, 0x7d, 0xef, 0xfb, 0x21, 0x08, 0xf7, 0x17, 0xfb, 0x54, 0x8b, 0xfb, + 0x42, 0x05, 0x8b, 0x34, 0x81, 0x81, 0x30, 0x87, 0x08, 0x78, 0xf7, 0xc6, + 0x9e, 0x07, 0x32, 0x8d, 0x7d, 0x97, 0x8b, 0xd7, 0x08, 0x8b, 0xf7, 0x56, + 0xf7, 0x28, 0xf7, 0x76, 0x05, 0xc8, 0xe3, 0xa5, 0xa1, 0xbe, 0x8f, 0x08, + 0x9e, 0x07, 0x0e, 0xf7, 0x9d, 0xf8, 0xd2, 0xf7, 0x44, 0x15, 0x7a, 0x53, + 0x81, 0x76, 0x77, 0x75, 0x73, 0x72, 0x5f, 0x7d, 0x52, 0x8b, 0x08, 0xfb, + 0x95, 0x8b, 0xf8, 0x44, 0xf8, 0xf5, 0x8b, 0x9a, 0xfc, 0xa2, 0x8b, 0x77, + 0xfb, 0x3f, 0xa5, 0x8b, 0x05, 0x94, 0xbc, 0x93, 0x9f, 0x9c, 0xa0, 0xa2, + 0xa8, 0xb8, 0x99, 0xcd, 0x8b, 0x08, 0xf7, 0x71, 0x8b, 0xfc, 0x49, 0xfc, + 0xf5, 0x8b, 0x7c, 0xf8, 0xc8, 0x8b, 0xa3, 0xf7, 0x44, 0x74, 0x8b, 0x05, + 0x0e, 0x7e, 0xf7, 0xbf, 0xfb, 0x17, 0x15, 0x35, 0x06, 0x6a, 0x7b, 0x9c, + 0xae, 0x1f, 0xf9, 0x34, 0x07, 0xaa, 0x98, 0x98, 0xab, 0x1e, 0xe5, 0xa4, + 0xfb, 0x67, 0xfd, 0xc6, 0xf7, 0x67, 0xa4, 0x06, 0x0e, 0x47, 0x82, 0xf9, + 0x38, 0x15, 0xf7, 0x78, 0xfd, 0x46, 0xcf, 0x8b, 0xfb, 0x79, 0xf9, 0x46, + 0x48, 0x8b, 0x05, 0x0e, 0x7e, 0xad, 0xfb, 0x17, 0x15, 0x72, 0xf7, 0x67, + 0xf9, 0xc6, 0xfb, 0x67, 0x72, 0xe1, 0x07, 0xac, 0x9b, 0x7a, 0x68, 0x1f, + 0xfd, 0x34, 0x07, 0x6c, 0x7d, 0x7e, 0x6c, 0x1e, 0x31, 0x06, 0x0e, 0xf7, + 0x0f, 0xe7, 0xf7, 0xbd, 0x15, 0xf7, 0x23, 0xf7, 0xb5, 0xf7, 0x23, 0xfb, + 0xb5, 0xcf, 0x8b, 0xfb, 0x49, 0xf8, 0x01, 0x4f, 0x8b, 0xfb, 0x49, 0xfc, + 0x01, 0xcf, 0x8b, 0x05, 0x0e, 0xf8, 0x88, 0xfb, 0x11, 0x15, 0xbd, 0xfc, + 0x88, 0x59, 0xf8, 0x88, 0x07, 0x0e, 0x7e, 0xf7, 0x77, 0xf9, 0x38, 0x15, + 0x48, 0x6a, 0x5e, 0x4e, 0x8b, 0x4f, 0x08, 0x58, 0xae, 0x65, 0xb8, 0xae, + 0xa3, 0xa2, 0xad, 0xaa, 0x74, 0x9f, 0x67, 0x1e, 0x85, 0x8b, 0x84, 0x8a, + 0x85, 0x8a, 0x84, 0x89, 0x8b, 0x8b, 0x8a, 0x8b, 0x83, 0x8b, 0x85, 0x91, + 0x8b, 0x93, 0x8b, 0xac, 0xa7, 0xaf, 0xc1, 0xb0, 0x08, 0x82, 0x9e, 0x05, + 0x0e, 0xed, 0xf8, 0x4e, 0xcd, 0x15, 0x7a, 0x7d, 0x7f, 0x86, 0x7c, 0x8b, + 0x08, 0x74, 0x84, 0x99, 0xb7, 0x1f, 0xf7, 0x57, 0x07, 0x8b, 0xbf, 0x86, + 0xa8, 0x7c, 0xa3, 0x75, 0xaf, 0x60, 0x9e, 0x50, 0x8b, 0x08, 0x2d, 0x41, + 0x5a, 0x4c, 0x74, 0x9f, 0x77, 0xa2, 0xa3, 0xa0, 0x9f, 0xa1, 0x1f, 0x8b, + 0x8f, 0x8a, 0x90, 0x8a, 0x92, 0x89, 0x94, 0x8a, 0x93, 0x8b, 0x92, 0x08, + 0xa6, 0xab, 0xa1, 0xb3, 0xbc, 0xa6, 0x6e, 0x55, 0x1e, 0x4e, 0x07, 0xfb, + 0x2e, 0x4d, 0x7a, 0x83, 0x60, 0x65, 0x75, 0x77, 0x7d, 0x69, 0x8b, 0x6a, + 0x08, 0x4c, 0xb7, 0x5f, 0xc8, 0x1e, 0xb7, 0x8b, 0xb4, 0xa0, 0xc8, 0xbf, + 0x08, 0x90, 0x57, 0x9d, 0x76, 0xb4, 0x8b, 0xad, 0x8b, 0xa0, 0x97, 0xae, + 0xb1, 0x08, 0xa5, 0x07, 0xfb, 0x2f, 0xc4, 0x15, 0x8b, 0x6c, 0x86, 0x82, + 0x76, 0x7f, 0x73, 0x7d, 0x6f, 0x82, 0x76, 0x8b, 0x08, 0x68, 0x6f, 0xad, + 0xb6, 0x1f, 0x8f, 0x07, 0x8b, 0xc6, 0xb4, 0xaf, 0xf7, 0x0d, 0xb7, 0x08, + 0xfb, 0x25, 0x07, 0x0e, 0xf7, 0x2d, 0xf9, 0x3d, 0x15, 0x86, 0x8d, 0x05, + 0x61, 0x7c, 0x70, 0x83, 0x5c, 0x7e, 0x08, 0x6e, 0x83, 0x8b, 0x7b, 0x05, + 0x91, 0x8c, 0x8f, 0x8b, 0x92, 0x8b, 0x08, 0xb3, 0x94, 0x82, 0x61, 0x1f, + 0xfc, 0x9b, 0x07, 0x6c, 0xe0, 0x6a, 0xdb, 0xf7, 0x18, 0xf1, 0xf7, 0x02, + 0xf7, 0x23, 0xf7, 0x0f, 0x3f, 0xe9, 0x27, 0x1e, 0x4e, 0x8b, 0x51, 0x67, + 0x77, 0x5a, 0x08, 0xf7, 0xc6, 0x07, 0xfb, 0xfb, 0x04, 0xb2, 0xba, 0xaf, + 0xbf, 0xd9, 0xbd, 0x3d, 0xfb, 0x0e, 0xfb, 0x03, 0x5b, 0x4b, 0x39, 0x57, + 0x5e, 0xa2, 0xa4, 0x1e, 0xf7, 0x90, 0x07, 0x0e, 0xed, 0xf8, 0x22, 0xf7, + 0x30, 0x15, 0x5b, 0x45, 0x67, 0x73, 0x52, 0x8b, 0x08, 0x30, 0x4b, 0xdb, + 0xf7, 0x07, 0xf2, 0xc2, 0xd2, 0xdc, 0x1f, 0xaf, 0x8b, 0x98, 0x80, 0x95, + 0x66, 0x08, 0x91, 0x75, 0x05, 0x93, 0x6f, 0x9d, 0x79, 0xa0, 0x8b, 0x08, + 0xa5, 0xa1, 0x9e, 0xa2, 0xc3, 0x45, 0xba, 0x37, 0x1f, 0x5a, 0x8b, 0x58, + 0x77, 0x62, 0x67, 0x59, 0x5f, 0x6f, 0x47, 0x8b, 0x3c, 0x8b, 0xfb, 0x16, + 0xda, 0x2e, 0xf7, 0x03, 0x8b, 0xb8, 0x8b, 0xb3, 0x9b, 0xaf, 0xaa, 0xa6, + 0xa3, 0x9e, 0xa6, 0xa9, 0xc6, 0x08, 0x7d, 0x94, 0x05, 0x0e, 0xf7, 0xec, + 0x81, 0x15, 0xf7, 0x27, 0xbf, 0x8b, 0x9b, 0x05, 0x79, 0x8a, 0x89, 0x8b, + 0x88, 0x8b, 0x08, 0x67, 0x83, 0x96, 0xb9, 0x1f, 0x8b, 0xf8, 0xcb, 0x86, + 0x8d, 0x05, 0x5b, 0x7a, 0x68, 0x81, 0x4b, 0x7a, 0x08, 0x7b, 0x07, 0x93, + 0x8c, 0x91, 0x8b, 0x93, 0x8b, 0x08, 0xb0, 0x94, 0x81, 0x62, 0x1f, 0xfb, + 0x30, 0x07, 0x65, 0xab, 0x70, 0x96, 0x63, 0x8b, 0x08, 0xfb, 0x07, 0x2e, + 0xfb, 0x05, 0xfb, 0x22, 0xfb, 0x14, 0xd6, 0x34, 0xf7, 0x02, 0x1f, 0xc3, + 0x8b, 0xb1, 0x9f, 0xad, 0xba, 0x08, 0x8b, 0x4b, 0x8f, 0x88, 0x05, 0x87, + 0xf7, 0x04, 0x15, 0x8b, 0x84, 0x84, 0x7f, 0x81, 0x80, 0x79, 0x77, 0x72, + 0x81, 0x6e, 0x8b, 0x08, 0x38, 0x54, 0xdb, 0xf7, 0x0f, 0xf7, 0x05, 0xbc, + 0xd5, 0xd7, 0xc0, 0xbc, 0x5c, 0x56, 0x1f, 0xfb, 0x7a, 0x07, 0x0e, 0xed, + 0xf8, 0x2c, 0xf7, 0x38, 0x15, 0x5b, 0x3f, 0x60, 0x6e, 0x4b, 0x8b, 0x52, + 0x8b, 0x60, 0xa8, 0x6e, 0xc4, 0x79, 0xb1, 0x84, 0xac, 0x89, 0xc8, 0x08, + 0xf7, 0xc8, 0x06, 0x83, 0xcc, 0x81, 0xa8, 0x72, 0xab, 0x6d, 0xaf, 0x5d, + 0xa0, 0x57, 0x8b, 0x59, 0x8b, 0x5c, 0x79, 0x65, 0x69, 0x5c, 0x62, 0x70, + 0x44, 0x8b, 0x39, 0x8b, 0xfb, 0x1e, 0xd3, 0x35, 0xf7, 0x07, 0x8b, 0xea, + 0x8b, 0xd6, 0xc6, 0xb5, 0xf7, 0x00, 0x08, 0x7b, 0x92, 0x05, 0xfb, 0xc9, + 0xf7, 0x25, 0x15, 0x96, 0xd9, 0xad, 0xb0, 0xc8, 0x8b, 0xc8, 0x8b, 0xa3, + 0x6f, 0x98, 0x34, 0x08, 0xfb, 0x60, 0x06, 0x0e, 0x7e, 0xf7, 0xc9, 0xf8, + 0x56, 0x15, 0xfb, 0x0f, 0xf7, 0x08, 0x06, 0xc5, 0x9e, 0xaa, 0xb1, 0x1e, + 0xa0, 0x8b, 0x99, 0x81, 0x9d, 0x6e, 0x9b, 0x71, 0x97, 0x81, 0x9c, 0x8b, + 0x08, 0xa2, 0x9e, 0x9d, 0xa2, 0xaf, 0x5f, 0xa5, 0x4f, 0x1f, 0x4d, 0x8b, + 0x56, 0x70, 0x71, 0x5d, 0x71, 0x5f, 0x83, 0x67, 0x8a, 0x3b, 0x08, 0x39, + 0x6b, 0xdd, 0xfb, 0xce, 0x06, 0x8b, 0x42, 0x80, 0x7f, 0x43, 0x87, 0x08, + 0x7c, 0xf7, 0x98, 0x9a, 0x07, 0x39, 0x8e, 0x80, 0x96, 0x8b, 0xd6, 0x08, + 0xf7, 0xce, 0xf7, 0x0e, 0xab, 0x07, 0x0e, 0xf8, 0x6a, 0xf8, 0x18, 0x15, + 0xb2, 0x3e, 0x07, 0x77, 0x8b, 0x7c, 0x8e, 0x77, 0x92, 0x08, 0x75, 0x93, + 0x05, 0x70, 0x95, 0x70, 0x90, 0x71, 0x8b, 0x2e, 0x8b, 0x41, 0x43, 0x8b, + 0x30, 0x8b, 0x4c, 0xa6, 0x65, 0xcd, 0x6a, 0x78, 0x79, 0x79, 0x7a, 0x85, + 0x86, 0x6a, 0x6e, 0x7e, 0x77, 0x8b, 0x77, 0x8b, 0x76, 0x97, 0x7f, 0xb4, + 0x77, 0x08, 0x44, 0x57, 0x70, 0x6a, 0x8b, 0x66, 0x8b, 0x56, 0xd9, 0x5f, + 0xea, 0x8b, 0xd6, 0x8b, 0xd9, 0xa5, 0xbf, 0xb5, 0xb1, 0xaa, 0x9c, 0xab, + 0x8b, 0xb1, 0x8b, 0xc9, 0x5c, 0xb5, 0x41, 0x8e, 0x08, 0xfb, 0x15, 0x91, + 0x05, 0x56, 0x8d, 0x72, 0x94, 0x8b, 0x9b, 0x8b, 0x9f, 0xac, 0xae, 0xa6, + 0x93, 0x94, 0x8a, 0x92, 0x8a, 0x8e, 0x8b, 0x9e, 0x89, 0x98, 0x8a, 0x91, + 0x8b, 0xb0, 0x8b, 0xb3, 0x9a, 0xaa, 0xa6, 0xac, 0xa7, 0x9a, 0xae, 0x8b, + 0xbd, 0x08, 0x8b, 0xa8, 0x86, 0xa2, 0x7d, 0xab, 0x08, 0xde, 0x06, 0xfb, + 0xd7, 0xfc, 0x1a, 0x15, 0xac, 0x84, 0xdb, 0x85, 0xbc, 0x8b, 0x08, 0xe6, + 0xac, 0x7e, 0x67, 0x51, 0x3f, 0x64, 0xfb, 0x05, 0x33, 0x51, 0xa8, 0xb7, + 0x1f, 0x8b, 0xa2, 0x92, 0x98, 0xb5, 0xbd, 0x08, 0x90, 0xf7, 0xe8, 0x15, + 0xc6, 0xa7, 0xae, 0xb9, 0x1e, 0xaa, 0x8b, 0xa5, 0x7a, 0x9b, 0x6d, 0x9d, + 0x68, 0x97, 0x5d, 0x8b, 0x64, 0x08, 0x53, 0x6e, 0x68, 0x5d, 0x4f, 0x61, + 0xcc, 0xeb, 0x1e, 0x8e, 0x07, 0x0e, 0xf7, 0x31, 0xf7, 0xeb, 0x15, 0xb5, + 0xb9, 0xa9, 0x9c, 0xb2, 0x8b, 0x08, 0xbd, 0xa4, 0x67, 0x45, 0x1f, 0xfb, + 0x5a, 0x07, 0x8b, 0x47, 0x81, 0x7e, 0x51, 0x85, 0x08, 0x7c, 0xf7, 0x68, + 0x9a, 0x07, 0x55, 0x95, 0x85, 0x93, 0x8b, 0xd0, 0x08, 0xf7, 0x5b, 0x07, + 0xf4, 0x61, 0xc1, 0x3a, 0x1e, 0x50, 0x8b, 0x61, 0x73, 0x5d, 0x4f, 0x08, + 0x8b, 0xf7, 0xc4, 0x86, 0x8e, 0x05, 0x69, 0x7f, 0x72, 0x83, 0x53, 0x7b, + 0x08, 0x70, 0x83, 0x8b, 0x7b, 0x05, 0x8f, 0x8c, 0x8e, 0x8b, 0x90, 0x8b, + 0x08, 0xb6, 0x93, 0x83, 0x60, 0x1f, 0xfc, 0x6b, 0x07, 0x8b, 0x45, 0x85, + 0x82, 0x51, 0x83, 0x08, 0x7c, 0xf7, 0x6c, 0x9a, 0x07, 0x51, 0x91, 0x81, + 0x97, 0x8b, 0xd0, 0x08, 0xf7, 0x85, 0x07, 0x0e, 0x47, 0xf7, 0x43, 0xf8, + 0x60, 0x15, 0xfb, 0x2f, 0x54, 0x8b, 0x7c, 0x93, 0x8c, 0x05, 0x97, 0x8d, + 0x98, 0x8c, 0x94, 0x8b, 0x08, 0xa3, 0x94, 0x7b, 0x5f, 0x1f, 0xfb, 0x7c, + 0x07, 0x8b, 0x43, 0x81, 0x80, 0x46, 0x87, 0x08, 0x7c, 0xf7, 0x81, 0x9a, + 0x07, 0x49, 0x90, 0x83, 0x95, 0x8b, 0xd3, 0x08, 0x8b, 0xf7, 0xf7, 0x05, + 0x87, 0x8e, 0x05, 0x5c, 0xf7, 0x73, 0x15, 0x70, 0x74, 0x74, 0x6f, 0x6f, + 0xa1, 0x74, 0xa7, 0xa8, 0xa2, 0xa1, 0xa8, 0x1f, 0xa7, 0x74, 0xa2, 0x6e, + 0x1e, 0x0e, 0x47, 0xf7, 0x55, 0xf8, 0x5d, 0x15, 0x86, 0x8e, 0x05, 0x50, + 0x74, 0x65, 0x7e, 0x50, 0x79, 0x08, 0x8b, 0x7b, 0x90, 0x8c, 0x05, 0x9a, + 0x8d, 0x9a, 0x8c, 0x95, 0x8b, 0x08, 0xa2, 0x94, 0x7a, 0x60, 0x1f, 0xfc, + 0x0f, 0x07, 0x8b, 0x3f, 0x88, 0x72, 0x80, 0x77, 0x85, 0x81, 0x7d, 0x83, + 0x7d, 0x8b, 0x7c, 0x8b, 0x81, 0x92, 0x7a, 0xa0, 0x79, 0xa2, 0x7d, 0x94, + 0x7b, 0x8b, 0x08, 0x74, 0x79, 0x7a, 0x75, 0x6b, 0xb3, 0x74, 0xc1, 0xf7, + 0x02, 0xc6, 0xd7, 0xf7, 0x22, 0x1f, 0xf8, 0x5d, 0x07, 0x58, 0xf7, 0x76, + 0x15, 0x70, 0x74, 0x74, 0x6f, 0x6f, 0xa1, 0x74, 0xa7, 0xa8, 0xa2, 0xa1, + 0xa8, 0x1f, 0xa7, 0x74, 0xa2, 0x6e, 0x1e, 0x0e, 0x92, 0xf9, 0x03, 0x15, + 0x98, 0x8c, 0x94, 0x8c, 0x95, 0x8b, 0x08, 0xac, 0x95, 0x7e, 0x5b, 0x1f, + 0xfc, 0x76, 0x07, 0x8b, 0x57, 0x88, 0x88, 0x43, 0x7f, 0x08, 0x7c, 0xf7, + 0x7e, 0x9a, 0x07, 0x77, 0x8c, 0x05, 0x63, 0x8d, 0x7c, 0x99, 0x8b, 0xae, + 0x08, 0x8b, 0xf7, 0x4c, 0xf7, 0x20, 0xfb, 0x4f, 0x8e, 0x87, 0x05, 0x8d, + 0x88, 0x8d, 0x88, 0x8e, 0x88, 0x93, 0x81, 0x8e, 0x85, 0x8b, 0x86, 0x08, + 0x82, 0x82, 0x85, 0x7f, 0x1e, 0x78, 0x7c, 0xf7, 0x6e, 0x9a, 0x06, 0x5f, + 0x8e, 0x6c, 0x9e, 0x61, 0xbe, 0x08, 0xfb, 0x2d, 0xf7, 0x56, 0xa8, 0xa6, + 0x05, 0xd2, 0xcd, 0xc9, 0xb9, 0xa8, 0x93, 0x9a, 0x8f, 0x99, 0x8d, 0x9c, + 0x8b, 0x08, 0x93, 0x9a, 0xfb, 0x60, 0x7d, 0x06, 0xb2, 0x8a, 0x96, 0x87, + 0x8b, 0x7d, 0x8b, 0x83, 0x82, 0x7d, 0x7d, 0x7f, 0x08, 0xfb, 0x1d, 0xfb, + 0x0e, 0x8b, 0xf8, 0x38, 0x87, 0x8d, 0x05, 0x65, 0x7f, 0x6e, 0x83, 0x51, + 0x7b, 0x08, 0x6d, 0x83, 0x8b, 0x7b, 0x05, 0x0e, 0x47, 0x9e, 0xf9, 0x03, + 0x15, 0x91, 0x06, 0x96, 0x8c, 0x97, 0x8c, 0x93, 0x8b, 0x08, 0xab, 0x95, + 0x7d, 0x5c, 0x1f, 0xfc, 0x71, 0x07, 0x8b, 0x55, 0x7d, 0x7e, 0x4c, 0x86, + 0x08, 0x7c, 0xf7, 0x80, 0x9a, 0x07, 0x4c, 0x8f, 0x7f, 0x95, 0x8b, 0xc2, + 0x08, 0x8b, 0xf8, 0xe9, 0x87, 0x8d, 0x05, 0x57, 0x7a, 0x65, 0x81, 0x46, + 0x7a, 0x08, 0x7b, 0x07, 0x0e, 0xf8, 0x44, 0x9e, 0xf8, 0x22, 0x15, 0x98, + 0x8e, 0x93, 0x8c, 0x96, 0x8b, 0x08, 0xa5, 0x94, 0x7b, 0x5b, 0x1f, 0xfb, + 0x91, 0x07, 0x8b, 0x55, 0x7d, 0x7c, 0x53, 0x8a, 0x08, 0x7c, 0xf7, 0x72, + 0x9a, 0x07, 0x56, 0x8d, 0x7c, 0x96, 0x8b, 0xb2, 0x08, 0xf7, 0xae, 0x07, + 0x8b, 0x8d, 0x93, 0x95, 0x92, 0x92, 0xa4, 0xa2, 0xb6, 0x9c, 0xae, 0x8b, + 0x08, 0xb7, 0xa1, 0x68, 0x45, 0x1f, 0xfb, 0x6d, 0x07, 0x8b, 0x53, 0x80, + 0x80, 0x52, 0x87, 0x08, 0x7c, 0xf7, 0x74, 0x9a, 0x07, 0x52, 0x8c, 0x7c, + 0x9c, 0x8b, 0xc9, 0x08, 0xf7, 0x90, 0x07, 0xa9, 0xb6, 0xac, 0x9d, 0xb9, + 0x8b, 0x08, 0xc4, 0x9d, 0x70, 0x38, 0x1f, 0xfb, 0x67, 0x07, 0x8b, 0x52, + 0x83, 0x83, 0x51, 0x84, 0x08, 0x7c, 0xf7, 0x6f, 0x9a, 0x07, 0x71, 0x8d, + 0x05, 0x6d, 0x8d, 0x7e, 0x9d, 0x8b, 0xb2, 0x08, 0xf7, 0x62, 0x07, 0xf7, + 0x0a, 0x64, 0xc7, 0x3e, 0x1e, 0x51, 0x8b, 0x58, 0x71, 0x55, 0x51, 0x79, + 0xc4, 0x69, 0xa6, 0x55, 0x8b, 0x5f, 0x8b, 0x6f, 0x7d, 0x38, 0x4c, 0x08, + 0x8b, 0xd6, 0x84, 0x8d, 0x05, 0x58, 0x78, 0x69, 0x80, 0x54, 0x7c, 0x08, + 0x7a, 0x07, 0x0e, 0x9b, 0xf8, 0x22, 0x15, 0x91, 0x8e, 0x95, 0x8c, 0x96, + 0x8b, 0x08, 0xa7, 0x94, 0x7c, 0x5a, 0x1f, 0xfb, 0x8c, 0x07, 0x8b, 0x52, + 0x80, 0x7d, 0x58, 0x87, 0x08, 0x7c, 0xf7, 0x68, 0x9a, 0x07, 0x58, 0x8f, + 0x7c, 0x97, 0x8b, 0xaf, 0x08, 0xf7, 0xad, 0x07, 0xbb, 0xb8, 0xa1, 0x97, + 0xac, 0x8b, 0x08, 0xbc, 0xa3, 0x6c, 0x49, 0x1f, 0xfb, 0x65, 0x07, 0x8b, + 0x4c, 0x7e, 0x7a, 0x59, 0x87, 0x08, 0x7c, 0xf7, 0x64, 0x9a, 0x07, 0x5a, + 0x90, 0x7f, 0x97, 0x8b, 0xbc, 0x08, 0xf7, 0x79, 0x07, 0xe9, 0x5f, 0xc3, + 0x41, 0x1e, 0x5d, 0x8b, 0x6c, 0x7a, 0x47, 0x4b, 0x08, 0x8b, 0xda, 0x84, + 0x8d, 0x05, 0x5a, 0x79, 0x69, 0x80, 0x54, 0x7b, 0x08, 0x7a, 0x07, 0x0e, + 0xf7, 0x8e, 0xf8, 0x60, 0x15, 0xfb, 0x16, 0x30, 0x2b, 0xfb, 0x1e, 0xfb, + 0x1b, 0xe8, 0x26, 0xf7, 0x12, 0xf7, 0x12, 0xeb, 0xf5, 0xf7, 0x1e, 0xf7, + 0x17, 0x2f, 0xea, 0xfb, 0x14, 0x1f, 0x7e, 0x6f, 0x15, 0xdf, 0xc6, 0x2b, + 0xfb, 0x1d, 0xfb, 0x05, 0x5e, 0x47, 0x40, 0x1f, 0x64, 0x8b, 0x66, 0xa3, + 0x76, 0xb3, 0x6f, 0xbf, 0x7b, 0xd1, 0x8b, 0xd2, 0x08, 0xea, 0xba, 0xc9, + 0xd2, 0x1e, 0x0e, 0x94, 0xf8, 0x1d, 0x15, 0x94, 0x8c, 0x92, 0x8b, 0x94, + 0x8b, 0x08, 0xad, 0x92, 0x81, 0x5c, 0x1f, 0xfc, 0x68, 0x07, 0x8b, 0x57, + 0x80, 0x80, 0x50, 0x85, 0x08, 0x7a, 0xf7, 0x86, 0x07, 0x9d, 0x07, 0x40, + 0x8c, 0x7e, 0x96, 0x8b, 0xca, 0x08, 0xf7, 0x31, 0x07, 0xae, 0x6a, 0xa3, + 0x81, 0xb5, 0x8b, 0x08, 0xf7, 0x0a, 0xe7, 0xf7, 0x04, 0xf7, 0x25, 0xf7, + 0x10, 0x45, 0xe4, 0x2a, 0x1f, 0x53, 0x8b, 0x5f, 0x72, 0x5f, 0x55, 0x08, + 0x8b, 0xd8, 0x85, 0x8d, 0x05, 0x55, 0x76, 0x68, 0x7e, 0x54, 0x7a, 0x08, + 0x7b, 0x07, 0xf7, 0x2a, 0x50, 0x15, 0xa9, 0xc3, 0xaf, 0xb9, 0xd5, 0xbc, + 0x3f, 0xfb, 0x08, 0xfb, 0x03, 0x5a, 0x40, 0x43, 0x5c, 0x52, 0xaf, 0xa9, + 0x1e, 0xf7, 0x8a, 0x07, 0x0e, 0xf7, 0xfc, 0xf8, 0x3d, 0x15, 0x5d, 0xa6, + 0x6d, 0x94, 0x64, 0x8b, 0x08, 0xfb, 0x11, 0x2b, 0xfb, 0x04, 0xfb, 0x24, + 0xfb, 0x12, 0xcd, 0x32, 0xe9, 0x1f, 0xc5, 0x8b, 0xc2, 0xa5, 0xb7, 0xbb, + 0x08, 0xfb, 0x50, 0x07, 0x8b, 0x53, 0x79, 0x7c, 0x44, 0x86, 0x08, 0x7a, + 0xf7, 0x80, 0x99, 0x07, 0x54, 0x97, 0x83, 0x93, 0x8b, 0xb5, 0x08, 0xf8, + 0xea, 0x80, 0x07, 0x55, 0x6b, 0x05, 0x78, 0xfb, 0xbe, 0x15, 0x8b, 0x73, + 0x87, 0x7e, 0x81, 0x83, 0x75, 0x78, 0x6a, 0x7f, 0x6c, 0x8b, 0x6c, 0x8b, + 0x70, 0x95, 0x77, 0x9f, 0x6b, 0xa8, 0x76, 0xcc, 0x8b, 0xcd, 0x08, 0xf7, + 0x0a, 0xc0, 0xd5, 0xe0, 0xc9, 0xaa, 0x6a, 0x48, 0x1e, 0xfb, 0x62, 0x07, + 0x0e, 0x7e, 0x92, 0xf8, 0x1a, 0x15, 0x99, 0x8e, 0x94, 0x8c, 0x97, 0x8b, + 0x08, 0xa4, 0x94, 0x7b, 0x5f, 0x1f, 0xfb, 0x8e, 0x07, 0x8b, 0x59, 0x84, + 0x84, 0x4b, 0x7f, 0x08, 0x7c, 0xf7, 0x84, 0x9a, 0x07, 0x47, 0x8e, 0x7a, + 0x9a, 0x8b, 0xc4, 0x08, 0xf7, 0x75, 0x07, 0xab, 0xb6, 0xbd, 0xa6, 0x1e, + 0x91, 0x8b, 0x94, 0x86, 0x96, 0x81, 0x9b, 0x7d, 0x96, 0x85, 0x98, 0x8b, + 0x08, 0xa3, 0x9a, 0x9c, 0xa7, 0xac, 0x76, 0x9f, 0x69, 0x1f, 0x61, 0x8b, + 0x6e, 0x74, 0x5a, 0x44, 0x08, 0x8b, 0xe7, 0x86, 0x8d, 0x05, 0x56, 0x75, + 0x67, 0x7e, 0x50, 0x78, 0x08, 0x7b, 0x07, 0x0e, 0xb6, 0xf7, 0xcf, 0xf7, + 0xce, 0x15, 0x87, 0xf7, 0x1c, 0x80, 0x8b, 0x89, 0x89, 0x05, 0x82, 0x84, + 0x8a, 0x8a, 0x87, 0x8b, 0x85, 0x8b, 0x81, 0x8d, 0x80, 0x90, 0x08, 0x75, + 0x93, 0x75, 0x8f, 0x71, 0x8b, 0x3c, 0x8b, 0x52, 0x58, 0x8b, 0x43, 0x8b, + 0x53, 0xab, 0x63, 0xe0, 0x5b, 0x08, 0xc5, 0x6a, 0x05, 0xae, 0x77, 0x9c, + 0x73, 0x8b, 0x6c, 0x8b, 0x5f, 0x6b, 0x6f, 0x58, 0x8b, 0x69, 0x8b, 0x6c, + 0x98, 0x78, 0xa1, 0x76, 0xa4, 0x82, 0xa2, 0x7e, 0xc4, 0x08, 0x7b, 0xfb, + 0x30, 0x98, 0x06, 0x92, 0x95, 0x8f, 0x8d, 0x97, 0x8b, 0x08, 0x94, 0x8b, + 0x99, 0x89, 0xa2, 0x85, 0x08, 0xa7, 0x85, 0xa6, 0x87, 0x9d, 0x8b, 0xd8, + 0x8b, 0xcb, 0xc5, 0x8b, 0xd1, 0x8b, 0xbd, 0x73, 0xac, 0x4f, 0xaf, 0x08, + 0xfb, 0x00, 0xcb, 0x05, 0x6f, 0x9b, 0x7c, 0xa4, 0x8b, 0xa6, 0x8b, 0xb3, + 0xaa, 0xa7, 0xb9, 0x8b, 0xc4, 0x8b, 0xa9, 0x69, 0xa2, 0x32, 0x08, 0x9a, + 0x06, 0x0e, 0x47, 0xf7, 0x93, 0xf8, 0x56, 0x15, 0x26, 0xf7, 0x08, 0x06, + 0x95, 0x8a, 0x8e, 0x85, 0x1e, 0x84, 0x81, 0x85, 0x82, 0x84, 0x82, 0x65, + 0x54, 0x60, 0x5b, 0x7b, 0x87, 0x80, 0x84, 0x85, 0x84, 0x8b, 0x86, 0x8b, + 0x88, 0x8c, 0x89, 0x8e, 0x89, 0x08, 0xc0, 0xfb, 0xc1, 0x06, 0x37, 0xa9, + 0x60, 0xc6, 0x1e, 0xbc, 0x8b, 0xb1, 0xa3, 0xac, 0xbf, 0x08, 0x7e, 0x96, + 0x05, 0x76, 0x72, 0x7a, 0x81, 0x75, 0x8b, 0x08, 0x66, 0x7c, 0xa6, 0xca, + 0x1f, 0xf7, 0xb2, 0xf0, 0xab, 0x07, 0x0e, 0xf8, 0x73, 0xbd, 0x15, 0x86, + 0x06, 0x5d, 0x80, 0x96, 0xb9, 0x1f, 0xf7, 0xeb, 0xfb, 0x32, 0x07, 0x7a, + 0x07, 0xc9, 0x88, 0x97, 0x81, 0x8b, 0x59, 0x08, 0xfb, 0x7f, 0x07, 0x8b, + 0x6f, 0x86, 0x7d, 0x7d, 0x80, 0x70, 0x75, 0x6c, 0x7f, 0x6d, 0x8b, 0x08, + 0x64, 0x6b, 0xad, 0xb5, 0x1f, 0xf7, 0xda, 0xfb, 0x26, 0x7d, 0x07, 0xbb, + 0x88, 0x99, 0x7c, 0x8b, 0x5d, 0x08, 0xfb, 0x90, 0x07, 0x3c, 0xbb, 0x58, + 0xd4, 0x1e, 0xb0, 0x8b, 0xb2, 0x9b, 0xa6, 0xa6, 0x08, 0xb6, 0xb6, 0x8b, + 0x38, 0x8f, 0x89, 0x05, 0xbd, 0x9f, 0xaf, 0x96, 0xbe, 0x99, 0x08, 0x99, + 0x07, 0x0e, 0xf8, 0x71, 0xf8, 0x56, 0x15, 0xfb, 0x1f, 0x7c, 0x06, 0xab, + 0x88, 0x9a, 0x81, 0x8b, 0x78, 0x8b, 0x81, 0x89, 0x81, 0x87, 0x81, 0x08, + 0x28, 0xfb, 0x97, 0x25, 0xf7, 0x94, 0x05, 0x85, 0x99, 0x88, 0x99, 0x8b, + 0x94, 0x8b, 0x9d, 0x96, 0x92, 0xae, 0x8e, 0x08, 0x9a, 0xfb, 0x58, 0x7c, + 0x07, 0xb1, 0x89, 0x92, 0x81, 0xb9, 0x24, 0x08, 0xf7, 0x0c, 0xfb, 0xb3, + 0x05, 0x8d, 0x85, 0x8e, 0x84, 0x8e, 0x83, 0x91, 0x79, 0x91, 0x83, 0x91, + 0x8b, 0x91, 0x8b, 0x92, 0x98, 0x9a, 0xb0, 0x08, 0xf7, 0x14, 0xf7, 0xd5, + 0x05, 0xa8, 0xcf, 0x91, 0x92, 0xa9, 0x8e, 0x08, 0x9a, 0x07, 0x0e, 0xf8, + 0x0c, 0xf8, 0xcf, 0xf8, 0x56, 0x15, 0x7c, 0x07, 0xad, 0x84, 0x95, 0x84, + 0x8b, 0x7a, 0x8b, 0x7c, 0x85, 0x73, 0x80, 0x70, 0x08, 0x31, 0xfb, 0x72, + 0x37, 0xf7, 0x74, 0x05, 0x7a, 0xb9, 0x8b, 0x8b, 0x8b, 0x98, 0x8b, 0xa1, + 0x96, 0x92, 0xba, 0x92, 0x08, 0x9a, 0xfb, 0x5f, 0x7c, 0x07, 0xb0, 0x87, + 0x97, 0x80, 0x9f, 0x55, 0x92, 0x78, 0x92, 0x78, 0x91, 0x79, 0x08, 0x30, + 0xfb, 0x5b, 0x28, 0xf7, 0x99, 0x05, 0x87, 0x95, 0x89, 0x95, 0x8b, 0x95, + 0x8b, 0xa0, 0x97, 0x93, 0xad, 0x8f, 0x08, 0x9a, 0xfb, 0x48, 0x7c, 0x07, + 0xa2, 0x89, 0x93, 0x81, 0xa1, 0x58, 0x08, 0xf7, 0x1b, 0xfb, 0xea, 0x05, + 0x97, 0x6d, 0x93, 0x7d, 0x91, 0x8b, 0x90, 0x8b, 0x93, 0x98, 0x97, 0xa5, + 0x08, 0xf7, 0x04, 0xf7, 0x84, 0xe6, 0xfb, 0x80, 0x05, 0x99, 0x66, 0x8f, + 0x85, 0x91, 0x8b, 0x92, 0x8b, 0x90, 0x94, 0x9b, 0xb3, 0x08, 0xf7, 0x1e, + 0xf7, 0xee, 0x05, 0x9d, 0xb5, 0x8e, 0x90, 0x9f, 0x92, 0x08, 0x9a, 0xfb, + 0x0f, 0x07, 0x0e, 0xf7, 0xaa, 0x16, 0xf7, 0x5d, 0x9a, 0x06, 0x6c, 0x8b, + 0x77, 0x9b, 0x6c, 0xb7, 0x08, 0xfb, 0x14, 0xf7, 0x58, 0xde, 0xf7, 0x0c, + 0x05, 0x9e, 0xa6, 0xa9, 0x9b, 0xab, 0x8c, 0x08, 0x9a, 0xfb, 0x32, 0x7c, + 0x07, 0xa9, 0x89, 0x95, 0x85, 0x8b, 0x7d, 0x8b, 0x7f, 0x7f, 0x75, 0x72, + 0x6c, 0x86, 0x85, 0x7f, 0x79, 0x7e, 0x77, 0x08, 0x7d, 0x9f, 0x05, 0x6f, + 0xb5, 0x79, 0xad, 0x8b, 0x98, 0x8b, 0x99, 0x98, 0x92, 0xa9, 0x8c, 0x08, + 0x9a, 0xfb, 0x63, 0x7c, 0x94, 0x07, 0xa9, 0x8b, 0x9b, 0x7e, 0xaa, 0x5c, + 0x08, 0xe9, 0xfb, 0x24, 0xfb, 0x06, 0xfb, 0x39, 0x05, 0x6d, 0x62, 0x81, + 0x84, 0x6a, 0x88, 0x08, 0x7c, 0xf7, 0x25, 0x9a, 0x07, 0x6f, 0x7f, 0x90, + 0x98, 0x1f, 0x8b, 0x91, 0x92, 0x9a, 0x98, 0x9f, 0x08, 0xda, 0xf7, 0x0f, + 0xe6, 0xfb, 0x20, 0x05, 0x8f, 0x85, 0x8d, 0x85, 0x8b, 0x85, 0x8b, 0x79, + 0x84, 0x87, 0x6a, 0x89, 0x08, 0x7c, 0x07, 0x0e, 0xf8, 0x6f, 0xf8, 0x56, + 0x15, 0xfb, 0x1b, 0x7c, 0x06, 0xab, 0x9b, 0x82, 0x7b, 0x1f, 0x8b, 0x87, + 0x8a, 0x85, 0x88, 0x84, 0x08, 0x2a, 0xfb, 0xa8, 0xfb, 0x07, 0xf7, 0x91, + 0x05, 0x85, 0x99, 0x87, 0x98, 0x8b, 0x96, 0x8b, 0x9d, 0x9a, 0x92, 0xb6, + 0x8d, 0x08, 0x9a, 0xfb, 0x62, 0x7d, 0x07, 0xa5, 0x87, 0x9c, 0x80, 0x93, + 0x7a, 0x08, 0xf7, 0x06, 0xfb, 0x8a, 0x8e, 0x83, 0x9a, 0x6d, 0x05, 0xa7, + 0x59, 0x9b, 0x67, 0x8b, 0x7c, 0x8b, 0x7c, 0x74, 0x4c, 0x7a, 0x6d, 0x7d, + 0x71, 0x75, 0x78, 0x7d, 0x8b, 0x85, 0x8b, 0x82, 0x8d, 0x81, 0x90, 0x78, + 0x92, 0x7a, 0x8f, 0x7a, 0x8b, 0x08, 0x74, 0x77, 0x77, 0x73, 0x6a, 0xab, + 0x72, 0xb5, 0x1f, 0xce, 0x8b, 0xbb, 0xc3, 0xc1, 0xf7, 0x24, 0x08, 0xf7, + 0x2e, 0xf8, 0x2c, 0x05, 0x98, 0xab, 0x96, 0x95, 0xa3, 0x8e, 0x08, 0x9a, + 0x07, 0x0e, 0xed, 0xf8, 0x36, 0xf7, 0x1b, 0x15, 0x79, 0x8f, 0x05, 0x81, + 0x59, 0x85, 0x7b, 0x7e, 0x7a, 0x7d, 0x7a, 0x69, 0x82, 0x58, 0x8b, 0x08, + 0xfb, 0x1e, 0x8b, 0xf7, 0xa1, 0xf8, 0x29, 0x8b, 0x9a, 0xfb, 0xef, 0x8b, + 0x88, 0xfb, 0x0a, 0x9d, 0x8b, 0x05, 0x94, 0xd4, 0x9a, 0x9a, 0xc7, 0x8b, + 0x08, 0xf7, 0x1e, 0x8b, 0xfb, 0x9e, 0xfc, 0x29, 0x8b, 0x7c, 0xf8, 0x0d, + 0x8b, 0x99, 0xf7, 0x1b, 0x05, 0x0e, 0xf7, 0x1a, 0xf7, 0xf2, 0xfb, 0x3e, + 0x15, 0x46, 0x9d, 0x75, 0xa9, 0x8b, 0xd6, 0x08, 0xf7, 0x3c, 0x07, 0x8b, + 0xde, 0x78, 0xa5, 0x40, 0x9e, 0xd6, 0x9f, 0x9e, 0xa5, 0x8b, 0xde, 0x08, + 0xf7, 0x3c, 0x07, 0x8b, 0xd6, 0xa1, 0xa9, 0xd0, 0x9d, 0x08, 0x96, 0x07, + 0x49, 0x8a, 0x71, 0x85, 0x6e, 0x79, 0x6e, 0x79, 0x7c, 0x64, 0x8b, 0x52, + 0x08, 0xfb, 0x46, 0x07, 0x8b, 0x45, 0x79, 0x74, 0x48, 0x77, 0xce, 0x76, + 0x9d, 0x73, 0x8b, 0x46, 0x08, 0xfb, 0x45, 0x07, 0x8b, 0x53, 0x9b, 0x62, + 0xa7, 0x79, 0xa7, 0x79, 0xa6, 0x85, 0xcd, 0x8a, 0x08, 0x96, 0x07, 0x0e, + 0xfb, 0x26, 0xce, 0x7d, 0x15, 0xcd, 0xf9, 0x46, 0x49, 0xfd, 0x46, 0x06, + 0x0e, 0xf7, 0x1a, 0xf7, 0x16, 0xf9, 0x31, 0x15, 0xd0, 0x79, 0xa1, 0x6d, + 0x8b, 0x40, 0x08, 0xfb, 0x3c, 0x07, 0x8b, 0x37, 0x9e, 0x72, 0xd6, 0x78, + 0x40, 0x77, 0x78, 0x71, 0x8b, 0x38, 0x08, 0xfb, 0x3c, 0x07, 0x8b, 0x40, + 0x75, 0x6d, 0x46, 0x79, 0x08, 0x80, 0x07, 0xcd, 0x8c, 0xa5, 0x91, 0xa8, + 0x9d, 0xa8, 0x9d, 0x9a, 0xb2, 0x8b, 0xc4, 0x08, 0xf7, 0x46, 0x07, 0x8b, + 0xd1, 0x9d, 0xa2, 0xce, 0xa0, 0x48, 0x9f, 0x79, 0xa2, 0x8b, 0xd1, 0x08, + 0xf7, 0x45, 0x07, 0x8b, 0xc3, 0x7b, 0xb4, 0x6f, 0x9d, 0x6f, 0x9d, 0x71, + 0x91, 0x48, 0x8c, 0x08, 0x80, 0x07, 0x0e, 0xf7, 0x57, 0xf8, 0x54, 0xf7, + 0xc3, 0x15, 0x71, 0x64, 0x7a, 0x7f, 0x6c, 0x8b, 0x76, 0x8b, 0x76, 0x90, + 0x7a, 0x94, 0x32, 0xba, 0x79, 0x92, 0x5e, 0x8b, 0x5d, 0x8b, 0x6c, 0x76, + 0x5d, 0x4b, 0x08, 0xc1, 0x6b, 0x05, 0xa5, 0xb2, 0x9c, 0x97, 0xaa, 0x8b, + 0xa0, 0x8b, 0xa0, 0x86, 0x9c, 0x82, 0xe4, 0x5c, 0x9d, 0x84, 0xb8, 0x8b, + 0xb9, 0x8b, 0xaa, 0xa0, 0xb9, 0xcb, 0x08, 0x55, 0xab, 0x05, 0x0e, 0x7e, + 0xf7, 0x24, 0xf7, 0xae, 0x15, 0x5e, 0xfc, 0x13, 0x05, 0x8a, 0x7f, 0x8a, + 0x7e, 0x8b, 0x7f, 0x08, 0x57, 0x9e, 0x6f, 0xad, 0xac, 0x9f, 0xa9, 0xbb, + 0x1e, 0x8b, 0xad, 0x83, 0xd2, 0x7f, 0xd2, 0x84, 0xb8, 0x85, 0xb9, 0x87, + 0xba, 0x08, 0x82, 0xf7, 0x00, 0x7e, 0x8b, 0x05, 0x92, 0xf7, 0x4f, 0x15, + 0x6b, 0x75, 0x76, 0x6d, 0x6b, 0xa2, 0x73, 0xa9, 0xa9, 0xa3, 0xa4, 0xa9, + 0xa8, 0x73, 0xa2, 0x6e, 0x1f, 0x0e, 0xf8, 0x27, 0xf8, 0xd7, 0x15, 0x68, + 0x8b, 0x5f, 0xfb, 0x10, 0x05, 0x73, 0x8f, 0x7e, 0x8c, 0x7d, 0x8b, 0xfb, + 0x10, 0x8b, 0x2b, 0x21, 0x8b, 0xfb, 0x1b, 0x8b, 0x55, 0x9c, 0x55, 0xa8, + 0x63, 0x9d, 0x72, 0x9a, 0x7e, 0xb0, 0x76, 0x08, 0x58, 0xfb, 0x2a, 0xad, + 0x8b, 0xbc, 0xf7, 0x1e, 0x05, 0xa3, 0x84, 0x9a, 0x89, 0x9c, 0x8b, 0xb1, + 0x8b, 0xb0, 0x99, 0xa7, 0xa3, 0xae, 0xa9, 0x9e, 0xa6, 0xad, 0xd1, 0x08, + 0x7e, 0x93, 0x05, 0x57, 0x40, 0x67, 0x72, 0x50, 0x8b, 0x77, 0x8b, 0x7c, + 0x8e, 0x73, 0x94, 0x08, 0xf0, 0xf7, 0xb7, 0x05, 0x9d, 0x64, 0x9a, 0x7e, + 0xa4, 0x8b, 0xa4, 0x8b, 0x9d, 0x9e, 0x8b, 0xa5, 0x8b, 0xae, 0x70, 0xa9, + 0x5b, 0x9e, 0x08, 0xba, 0xf7, 0x1b, 0x05, 0xfb, 0x61, 0xfc, 0x75, 0x15, + 0x5a, 0xb8, 0x78, 0xb8, 0x8b, 0xd3, 0x8b, 0xf1, 0xc1, 0xcf, 0xdd, 0x8b, + 0x9c, 0x8b, 0x97, 0x89, 0x9d, 0x84, 0x08, 0xfb, 0x07, 0xfb, 0xd7, 0x05, + 0x0e, 0xf7, 0xec, 0xf8, 0x09, 0x15, 0xfb, 0x11, 0x06, 0x83, 0xcf, 0x88, + 0xac, 0x8b, 0xaf, 0x8b, 0xe3, 0xae, 0xbe, 0xc7, 0x8b, 0xb0, 0x8b, 0x9d, + 0x7a, 0x8c, 0x68, 0x8c, 0x56, 0x93, 0x7d, 0xa9, 0x8b, 0x08, 0xa8, 0xa0, + 0xa1, 0xaa, 0xc0, 0x53, 0xb3, 0x41, 0xfb, 0x0b, 0x3f, 0x30, 0xfb, 0x23, + 0x1f, 0x8b, 0x73, 0x8d, 0x78, 0x90, 0x71, 0x08, 0x20, 0x5e, 0xf7, 0x00, + 0x06, 0x9f, 0xfb, 0x27, 0x8d, 0x7a, 0x8b, 0x79, 0x8b, 0x84, 0x8a, 0x85, + 0x88, 0x83, 0x78, 0x8f, 0x7f, 0x8c, 0x7c, 0x8b, 0x08, 0x55, 0x66, 0x6d, + 0x5d, 0x65, 0xa6, 0x73, 0xb4, 0x1f, 0xae, 0x8b, 0xa2, 0x9a, 0xb3, 0xba, + 0x08, 0xcf, 0x5c, 0xac, 0x7d, 0xb6, 0x8b, 0xbb, 0x8b, 0xb8, 0xa0, 0xab, + 0xb0, 0xa0, 0xa3, 0xa1, 0xb7, 0x8b, 0x9c, 0x8b, 0x8e, 0x89, 0x8d, 0x87, + 0x8b, 0x86, 0x8b, 0x83, 0x86, 0x81, 0x80, 0x6b, 0x69, 0x68, 0x7c, 0x5d, + 0x8b, 0x08, 0x5a, 0x8b, 0x68, 0x93, 0x4a, 0xa6, 0xa3, 0xf7, 0x0e, 0x8c, + 0x90, 0x8b, 0xae, 0x08, 0x8a, 0xa7, 0x8b, 0xa6, 0xf7, 0x0d, 0x8b, 0x05, + 0xb8, 0x07, 0xfb, 0x93, 0xfb, 0xab, 0x15, 0xa3, 0xa8, 0x81, 0x83, 0x1f, + 0x8b, 0x83, 0x85, 0x7f, 0x80, 0x7e, 0x08, 0x7d, 0x7a, 0x7f, 0x85, 0x77, + 0x8b, 0x08, 0x73, 0x7a, 0x9a, 0xa1, 0xa3, 0x9d, 0x98, 0xac, 0x1f, 0x0e, + 0xfb, 0x47, 0xf7, 0xdf, 0xf9, 0x38, 0x15, 0x5d, 0x8b, 0xfc, 0x59, 0xfd, + 0x46, 0xbc, 0x8b, 0xf8, 0x56, 0xf9, 0x46, 0x05, 0x0e, 0xf7, 0x52, 0xf7, + 0x4a, 0x15, 0x4d, 0x07, 0x8b, 0x38, 0x7f, 0x7c, 0x48, 0x88, 0x08, 0x78, + 0xf7, 0x88, 0x9e, 0x07, 0x4b, 0x8d, 0x7b, 0x9d, 0x8b, 0xd1, 0x08, 0xd4, + 0xf7, 0x41, 0xb3, 0xfb, 0x41, 0xd7, 0x07, 0x92, 0x99, 0xf7, 0x3a, 0x8b, + 0x8b, 0xb3, 0xfb, 0x26, 0x8b, 0xe7, 0xf7, 0x4c, 0x05, 0xb0, 0xd0, 0xa9, + 0xa6, 0xbe, 0x96, 0x08, 0x9e, 0xfb, 0x57, 0x78, 0x99, 0x07, 0xa9, 0xa0, + 0x7f, 0x78, 0x1f, 0x8b, 0x81, 0x86, 0x7a, 0x82, 0x7a, 0x08, 0xfb, 0x04, + 0xfb, 0x70, 0xfb, 0x0a, 0xf7, 0x71, 0x05, 0x83, 0x9b, 0x86, 0x9b, 0x8b, + 0x98, 0x8b, 0x9f, 0x9d, 0x93, 0xba, 0x8c, 0x08, 0x9e, 0xfb, 0x87, 0x78, + 0x07, 0xb9, 0x88, 0x9c, 0x7b, 0xc2, 0x28, 0x08, 0xea, 0xfb, 0x41, 0xfb, + 0x24, 0x8b, 0x8b, 0x63, 0xf7, 0x3b, 0x8b, 0x92, 0x7d, 0x8b, 0x3f, 0xfb, + 0x42, 0x8b, 0x8b, 0x63, 0xf7, 0x42, 0x8b, 0x05, 0x0e, 0xf8, 0x44, 0xf8, + 0x2b, 0x15, 0xfb, 0x12, 0x06, 0x8f, 0xad, 0x8e, 0xaa, 0x8c, 0x96, 0x91, + 0xca, 0x9e, 0xcb, 0x9e, 0x9f, 0x96, 0x96, 0x99, 0x91, 0x9b, 0x8b, 0x97, + 0x8b, 0x93, 0x86, 0x8b, 0x84, 0x8b, 0x88, 0x89, 0x86, 0x88, 0x85, 0x86, + 0x82, 0x88, 0x82, 0x8b, 0x85, 0x08, 0x79, 0x9d, 0x7b, 0x9f, 0xa4, 0xa0, + 0x9f, 0xa4, 0xb1, 0x65, 0xa9, 0x5c, 0x1e, 0x61, 0x8b, 0x60, 0x74, 0x71, + 0x65, 0x65, 0x53, 0x7a, 0x5b, 0x7b, 0x23, 0x08, 0x20, 0x8b, 0x81, 0x6c, + 0xf7, 0x03, 0x8b, 0x89, 0x7c, 0x80, 0x48, 0x05, 0x8a, 0x87, 0x85, 0x53, + 0x86, 0x56, 0x08, 0x7c, 0xfb, 0x40, 0x05, 0x81, 0xfb, 0x08, 0x70, 0x51, + 0x5e, 0x8b, 0x7f, 0x8b, 0x82, 0x91, 0x8b, 0x92, 0x8b, 0x8e, 0x8d, 0x8f, + 0x8f, 0x92, 0x91, 0x96, 0x8e, 0x92, 0x8b, 0x94, 0x08, 0xa1, 0x7d, 0x99, + 0x75, 0x70, 0x78, 0x78, 0x71, 0x63, 0xac, 0x6e, 0xba, 0x1e, 0xc2, 0x8b, + 0xb2, 0xac, 0xac, 0xd3, 0xaa, 0xd1, 0x9c, 0xdb, 0xa3, 0xf7, 0x4d, 0x8c, + 0x98, 0x93, 0xc4, 0x92, 0xc2, 0x08, 0xf7, 0x0c, 0x8b, 0x95, 0xaa, 0x05, + 0x0e, 0xf7, 0xca, 0xf7, 0x11, 0x15, 0xcf, 0xbb, 0xbd, 0xd1, 0x1f, 0x8b, + 0xc0, 0x6c, 0xc1, 0x51, 0xbb, 0x08, 0xfb, 0x1d, 0xf7, 0x05, 0x05, 0x77, + 0x9c, 0x7d, 0xa8, 0x8b, 0xa4, 0x08, 0xb5, 0xad, 0xa8, 0xbe, 0xad, 0xa7, + 0x7d, 0x79, 0x1e, 0x8b, 0x88, 0x88, 0x88, 0x86, 0x86, 0x7b, 0x7f, 0x81, + 0x7b, 0x8b, 0x7b, 0x08, 0x72, 0x9f, 0x79, 0xa6, 0xab, 0x9e, 0x9f, 0xac, + 0xc3, 0x54, 0xb5, 0x42, 0x38, 0x53, 0x59, 0x43, 0x1e, 0x8b, 0x55, 0x9f, + 0x6d, 0xdb, 0x49, 0x81, 0x8c, 0x82, 0x8b, 0x85, 0x8b, 0x08, 0x49, 0x5a, + 0x58, 0x47, 0x1f, 0x8b, 0x42, 0xbc, 0x4b, 0xf7, 0x0e, 0x37, 0xcb, 0x5f, + 0xa4, 0x6b, 0x8b, 0x64, 0x08, 0x5c, 0x69, 0x6d, 0x56, 0x66, 0x69, 0x9c, + 0x9d, 0x1e, 0x8b, 0x8f, 0x8f, 0x90, 0x92, 0x91, 0x9b, 0x99, 0x92, 0x98, + 0x8b, 0x99, 0x08, 0xa3, 0x76, 0x9d, 0x70, 0x6c, 0x74, 0x74, 0x6c, 0x53, + 0xc7, 0x5f, 0xd9, 0xe2, 0xc4, 0xbe, 0xd7, 0x1e, 0x8b, 0xbe, 0x78, 0xa9, + 0x40, 0xcc, 0x08, 0x9d, 0x06, 0xfb, 0x0b, 0xf7, 0x96, 0x15, 0xaa, 0x8b, + 0xc0, 0x6b, 0xb9, 0x5d, 0xad, 0x69, 0x9e, 0x6a, 0x8b, 0x71, 0x8b, 0x68, + 0x6b, 0x6c, 0x66, 0x8b, 0x65, 0x8b, 0x65, 0xa2, 0x4f, 0xc7, 0x69, 0xad, + 0x7f, 0xa2, 0x8b, 0xa9, 0x08, 0xb2, 0xa8, 0xa7, 0xb2, 0x1e, 0x0e, 0x75, + 0xf7, 0x00, 0x15, 0xbd, 0x59, 0xeb, 0xed, 0x05, 0xb5, 0x6f, 0xb2, 0x7e, + 0xb9, 0x8b, 0xba, 0x8b, 0xb2, 0x98, 0xb2, 0xa7, 0x08, 0xed, 0x29, 0xbb, + 0xbd, 0x2b, 0xeb, 0x05, 0xa8, 0xb8, 0x95, 0xad, 0x8b, 0xbb, 0x8b, 0xbc, + 0x81, 0xac, 0x6e, 0xb6, 0x08, 0xeb, 0xed, 0x5b, 0xbb, 0x29, 0x2b, 0x05, + 0x64, 0xa6, 0x65, 0x97, 0x5b, 0x8b, 0x5a, 0x8b, 0x6a, 0x81, 0x5e, 0x6e, + 0x08, 0x2b, 0xeb, 0x59, 0x5b, 0xed, 0x29, 0x05, 0x6e, 0x63, 0x7f, 0x65, + 0x8b, 0x5b, 0x8b, 0x5c, 0x97, 0x66, 0xa8, 0x61, 0x08, 0x29, 0x2b, 0x05, + 0xf7, 0xa7, 0xf8, 0x09, 0x15, 0xda, 0xcc, 0x47, 0x39, 0x36, 0x4a, 0x48, + 0x3a, 0x39, 0x49, 0xcf, 0xde, 0xdf, 0xcd, 0xce, 0xdf, 0x1f, 0x0e, 0xfb, + 0x3a, 0xf0, 0xf8, 0x43, 0x15, 0x92, 0xb3, 0x05, 0x9b, 0xd7, 0x94, 0xc6, + 0x8b, 0xa9, 0x08, 0xa1, 0x78, 0x9d, 0x74, 0x73, 0x78, 0x79, 0x74, 0x1e, + 0x8b, 0x7b, 0x9a, 0x2a, 0x9c, 0x30, 0x08, 0xa0, 0x06, 0x0e, 0xed, 0xf7, + 0x2f, 0xf9, 0x38, 0x15, 0x48, 0x6a, 0x5e, 0x4e, 0x8b, 0x4f, 0x08, 0x58, + 0xae, 0x65, 0xb8, 0xae, 0xa3, 0xa2, 0xad, 0xab, 0x74, 0x9e, 0x67, 0x1e, + 0x85, 0x8b, 0x84, 0x8a, 0x85, 0x8a, 0x84, 0x89, 0x8b, 0x8b, 0x8a, 0x8b, + 0x83, 0x8b, 0x85, 0x91, 0x8b, 0x93, 0x8b, 0xac, 0xa7, 0xaf, 0xc1, 0xb0, + 0x08, 0x82, 0x9e, 0x05, 0xf7, 0x7c, 0x16, 0x48, 0x6a, 0x5e, 0x4e, 0x8b, + 0x4f, 0x08, 0x58, 0xae, 0x65, 0xb8, 0xae, 0xa3, 0xa2, 0xad, 0xab, 0x74, + 0x9e, 0x67, 0x1e, 0x85, 0x8b, 0x84, 0x8a, 0x85, 0x8a, 0x84, 0x89, 0x8b, + 0x8b, 0x8a, 0x8b, 0x83, 0x8b, 0x85, 0x91, 0x8b, 0x93, 0x8b, 0xac, 0xa7, + 0xaf, 0xc1, 0xb0, 0x08, 0x82, 0x9e, 0x05, 0x0e, 0xb5, 0xf7, 0x72, 0x15, + 0xaa, 0x70, 0x05, 0xd3, 0x4d, 0xb4, 0x65, 0xc4, 0x53, 0x8f, 0x86, 0x8d, + 0x8a, 0x90, 0x8b, 0x90, 0x8b, 0x8f, 0x8f, 0x8b, 0x90, 0x8b, 0x98, 0x62, + 0xc6, 0x3e, 0xec, 0x88, 0x8f, 0x8a, 0x8b, 0x85, 0x94, 0xa2, 0xaa, 0x9a, + 0x9d, 0xb0, 0xb7, 0x08, 0xa8, 0xaf, 0xa4, 0xb3, 0x8b, 0x98, 0x8b, 0x90, + 0x86, 0x90, 0x86, 0x8b, 0x85, 0x8b, 0x76, 0x79, 0x7a, 0x76, 0x87, 0x85, + 0x70, 0x70, 0x6e, 0x71, 0x82, 0x84, 0x84, 0x84, 0x83, 0x84, 0x08, 0x88, + 0x89, 0x05, 0x86, 0x86, 0x86, 0x86, 0x85, 0x87, 0x08, 0x4a, 0x50, 0x05, + 0xf7, 0x54, 0x16, 0xaa, 0x70, 0x05, 0xd3, 0x4d, 0xb4, 0x65, 0xc4, 0x53, + 0x8f, 0x86, 0x8d, 0x8a, 0x90, 0x8b, 0x90, 0x8b, 0x8f, 0x8f, 0x8b, 0x90, + 0x8b, 0x98, 0x62, 0xc6, 0x3e, 0xec, 0x88, 0x8f, 0x8a, 0x8b, 0x85, 0x94, + 0xa2, 0xaa, 0x9a, 0x9d, 0xb0, 0xb7, 0x08, 0xa8, 0xaf, 0xa4, 0xb3, 0x8b, + 0x98, 0x8b, 0x90, 0x86, 0x90, 0x86, 0x8b, 0x85, 0x8b, 0x76, 0x79, 0x7a, + 0x76, 0x87, 0x85, 0x70, 0x70, 0x6e, 0x71, 0x82, 0x84, 0x84, 0x84, 0x83, + 0x84, 0x08, 0x88, 0x89, 0x05, 0x86, 0x86, 0x86, 0x86, 0x85, 0x87, 0x08, + 0x4a, 0x50, 0x05, 0x0e, 0x7e, 0xca, 0xf7, 0x72, 0x15, 0xaa, 0x70, 0x05, + 0xd3, 0x4d, 0xb4, 0x65, 0xc4, 0x53, 0x8f, 0x86, 0x8d, 0x8a, 0x90, 0x8b, + 0x90, 0x8b, 0x8f, 0x8f, 0x8b, 0x90, 0x8b, 0x98, 0x62, 0xc6, 0x3e, 0xec, + 0x88, 0x8f, 0x8a, 0x8b, 0x85, 0x94, 0xa2, 0xaa, 0x9a, 0x9d, 0xb0, 0xb7, + 0x08, 0xa8, 0xaf, 0xa4, 0xb3, 0x8b, 0x98, 0x8b, 0x90, 0x86, 0x90, 0x86, + 0x8b, 0x85, 0x8b, 0x76, 0x79, 0x7a, 0x76, 0x87, 0x85, 0x70, 0x70, 0x6e, + 0x71, 0x82, 0x84, 0x84, 0x84, 0x83, 0x84, 0x08, 0x88, 0x89, 0x05, 0x86, + 0x86, 0x86, 0x86, 0x85, 0x87, 0x08, 0x4a, 0x50, 0x05, 0x0e, 0x7e, 0xf7, + 0xa2, 0xf7, 0x72, 0x15, 0x4a, 0xc6, 0x05, 0x85, 0x8f, 0x86, 0x90, 0x86, + 0x90, 0x08, 0x88, 0x8d, 0x05, 0x85, 0x90, 0x83, 0x92, 0x82, 0x94, 0x6d, + 0xa5, 0x6e, 0xa7, 0x89, 0x90, 0x7a, 0xa0, 0x76, 0x9d, 0x85, 0x8b, 0x86, + 0x8b, 0x86, 0x86, 0x8b, 0x86, 0x8b, 0x7e, 0xa4, 0x62, 0xa8, 0x68, 0x08, + 0xd6, 0x2e, 0x87, 0x85, 0x85, 0x84, 0x05, 0x40, 0x2c, 0x60, 0x4d, 0x8b, + 0x7f, 0x8b, 0x86, 0x8f, 0x87, 0x91, 0x8b, 0x8f, 0x8b, 0x8d, 0x8c, 0x8f, + 0x90, 0xc4, 0xc3, 0xb3, 0xb0, 0xd4, 0xca, 0x08, 0xaa, 0xa6, 0x05, 0x0e, + 0xf7, 0x66, 0xaa, 0xf8, 0x35, 0x15, 0xcf, 0xfb, 0xd7, 0x06, 0x8b, 0x4b, + 0x80, 0x7e, 0x53, 0x89, 0x08, 0x7c, 0xf7, 0x70, 0x9a, 0x07, 0x53, 0x8f, + 0x7e, 0x99, 0x8b, 0xc2, 0x08, 0xf7, 0xdd, 0xe1, 0x07, 0xeb, 0x90, 0x88, + 0x56, 0x1f, 0xfb, 0x9c, 0x07, 0x8b, 0x47, 0x84, 0x82, 0x4d, 0x86, 0x08, + 0x7c, 0xf7, 0x70, 0x9a, 0x07, 0x53, 0x90, 0x80, 0x98, 0x8b, 0xcb, 0x08, + 0xf7, 0x9a, 0x07, 0x8b, 0xa1, 0x8b, 0xa2, 0x8d, 0xc0, 0x08, 0x87, 0x8e, + 0x05, 0x5f, 0x84, 0x6e, 0x88, 0x63, 0x8b, 0x08, 0xfb, 0x31, 0xb6, 0x06, + 0x8b, 0xb7, 0x8e, 0xaa, 0x90, 0x9c, 0x99, 0xb6, 0xb2, 0xa9, 0xb8, 0x8b, + 0xa7, 0x8b, 0x9e, 0x7e, 0xa3, 0x69, 0x9e, 0x70, 0x98, 0x81, 0x9c, 0x8b, + 0x08, 0xa0, 0x9a, 0x9c, 0xa1, 0xb5, 0x59, 0xa7, 0x3e, 0x1f, 0x3f, 0x8b, + 0x51, 0x71, 0x67, 0x5a, 0x6d, 0x62, 0x80, 0x66, 0x85, 0x3b, 0x08, 0x46, + 0x6a, 0x06, 0x0e, 0xf7, 0x66, 0xab, 0xf8, 0x36, 0x15, 0xd0, 0xfb, 0xcd, + 0x06, 0x8b, 0x5e, 0x85, 0x72, 0x7d, 0x82, 0x81, 0x84, 0x81, 0x89, 0x6e, + 0x89, 0x08, 0x7c, 0xf7, 0x74, 0x9a, 0x07, 0x52, 0x91, 0x7d, 0x97, 0x8b, + 0xb9, 0x08, 0xf7, 0xe7, 0xf7, 0x50, 0xfb, 0xe2, 0x07, 0x8b, 0x5a, 0x7c, + 0x7b, 0x57, 0x87, 0x08, 0x7c, 0xf7, 0x6b, 0x9a, 0x07, 0x55, 0x8f, 0x81, + 0x95, 0x8b, 0xbf, 0x08, 0x8b, 0xf8, 0xec, 0x86, 0x8d, 0x05, 0x83, 0x8a, + 0x80, 0x87, 0x7f, 0x85, 0x78, 0x82, 0x7d, 0x86, 0x82, 0x8b, 0x86, 0x8b, + 0x81, 0x8e, 0x7c, 0x90, 0x08, 0x6f, 0x96, 0x6e, 0x91, 0x73, 0x8b, 0x5c, + 0x8b, 0x5d, 0x73, 0x6f, 0x64, 0x6d, 0x60, 0x81, 0x64, 0x87, 0x33, 0x08, + 0x44, 0x06, 0x6b, 0x07, 0xf7, 0xe9, 0xab, 0x15, 0xfb, 0x50, 0xbf, 0x06, + 0xf3, 0xa0, 0xbd, 0xb7, 0x1e, 0xa1, 0x8b, 0x97, 0x83, 0x9d, 0x70, 0x08, + 0x9e, 0x6f, 0x98, 0x82, 0xa2, 0x8b, 0x92, 0x8b, 0x8f, 0x8d, 0x90, 0x90, + 0x08, 0xfb, 0x21, 0x07, 0x0e, 0xf7, 0x8e, 0x04, 0x5a, 0xf8, 0x88, 0xbc, + 0xfc, 0x88, 0x07, 0x0e, 0xf7, 0x9b, 0xfb, 0x29, 0x15, 0xf7, 0x0f, 0x07, + 0x8b, 0xf7, 0x0b, 0x98, 0xe5, 0xa6, 0xd1, 0x6e, 0xa9, 0x7e, 0xc4, 0x8b, + 0xed, 0xae, 0x88, 0x9a, 0x88, 0xb5, 0x7b, 0x9f, 0x84, 0x9e, 0x86, 0x98, + 0x8b, 0x08, 0xa1, 0x9b, 0x9d, 0xa4, 0xa4, 0x7a, 0x9e, 0x75, 0x1f, 0x7f, + 0x8b, 0x79, 0x86, 0x77, 0x83, 0x62, 0x7a, 0x7b, 0x87, 0x67, 0x8a, 0x8b, + 0xc1, 0x90, 0xa3, 0x9e, 0xbd, 0x93, 0x9e, 0x90, 0x9c, 0x8b, 0x95, 0x08, + 0xa3, 0x74, 0xa1, 0x73, 0x73, 0x74, 0x75, 0x73, 0x1e, 0x8b, 0x81, 0x90, + 0x7a, 0x92, 0x78, 0x9f, 0x58, 0x90, 0x73, 0x8a, 0x56, 0x69, 0x8c, 0x7a, + 0x8f, 0x62, 0x9c, 0x77, 0x93, 0x79, 0x90, 0x80, 0x8b, 0x08, 0x74, 0x7a, + 0x79, 0x71, 0x6f, 0x9b, 0x7c, 0xa7, 0x1f, 0x97, 0x8b, 0x95, 0x8e, 0xa3, + 0x94, 0xb3, 0x9a, 0x9c, 0x8f, 0xad, 0x8e, 0x8c, 0x28, 0x7e, 0x54, 0x6d, + 0x6c, 0xa4, 0x47, 0x9d, 0xfb, 0x0c, 0x8b, 0x30, 0x08, 0xfb, 0x0f, 0xa1, + 0x07, 0x0e, 0xf7, 0x99, 0xf8, 0x5c, 0x15, 0x8b, 0xc1, 0x8f, 0xa3, 0x9f, + 0xbd, 0x92, 0x9e, 0x90, 0x9c, 0x8b, 0x95, 0x08, 0xa3, 0x75, 0xa1, 0x72, + 0x73, 0x75, 0x75, 0x73, 0x1e, 0x8b, 0x81, 0x90, 0x7a, 0x92, 0x78, 0x9f, + 0x58, 0x8f, 0x73, 0x8b, 0x56, 0x69, 0x8c, 0x79, 0x8f, 0x62, 0x9c, 0x78, + 0x93, 0x79, 0x90, 0x80, 0x8b, 0x08, 0x74, 0x7a, 0x79, 0x71, 0x6f, 0x9b, + 0x7c, 0xa7, 0x1f, 0x97, 0x8b, 0x95, 0x8e, 0xa3, 0x94, 0xb3, 0x9a, 0x9b, + 0x8f, 0xae, 0x8e, 0x8c, 0x34, 0x7f, 0x57, 0x6d, 0x64, 0xa8, 0x70, 0x97, + 0x59, 0x8a, 0x29, 0x69, 0x8e, 0x7c, 0x8e, 0x61, 0x9b, 0x77, 0x92, 0x77, + 0x90, 0x80, 0x8b, 0x08, 0x74, 0x7b, 0x7a, 0x71, 0x71, 0x9c, 0x79, 0xa2, + 0x1f, 0x96, 0x8b, 0x9d, 0x90, 0x9e, 0x93, 0xb4, 0x9c, 0x9d, 0x8f, 0xad, + 0x8c, 0x8b, 0x56, 0x87, 0x72, 0x77, 0x59, 0x84, 0x78, 0x86, 0x7a, 0x8b, + 0x81, 0x08, 0x73, 0xa1, 0x75, 0xa3, 0xa4, 0xa1, 0xa1, 0xa3, 0x1e, 0x8b, + 0x95, 0x86, 0x9c, 0x84, 0x9e, 0x77, 0xbd, 0x87, 0xa4, 0x8b, 0xc0, 0xaf, + 0x8a, 0x9a, 0x87, 0xb5, 0x7a, 0x9e, 0x83, 0x9d, 0x86, 0x96, 0x8b, 0x08, + 0xa2, 0x9c, 0x9d, 0xa4, 0xa6, 0x7b, 0x9c, 0x74, 0x1f, 0x7f, 0x8b, 0x77, + 0x86, 0x78, 0x84, 0x61, 0x7b, 0x7c, 0x88, 0x69, 0x88, 0x8b, 0xed, 0x95, + 0xb5, 0xaa, 0xae, 0x6d, 0xb0, 0x80, 0xb9, 0x8c, 0xea, 0xad, 0x88, 0x9b, + 0x88, 0xb4, 0x7b, 0x9f, 0x84, 0x9f, 0x86, 0x97, 0x8b, 0x08, 0xa1, 0x9b, + 0x9d, 0xa4, 0xa4, 0x7a, 0x9e, 0x75, 0x1f, 0x7f, 0x8b, 0x79, 0x86, 0x78, + 0x83, 0x61, 0x7a, 0x7c, 0x87, 0x67, 0x8a, 0x08, 0x0e, 0x2b, 0xf7, 0x11, + 0xf7, 0xca, 0x15, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, + 0xa5, 0xa4, 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0x0e, 0xf6, 0xf7, 0x82, + 0xf9, 0x14, 0x15, 0xc5, 0xfd, 0xae, 0xf7, 0x2e, 0xa1, 0x06, 0x3f, 0x91, + 0x7f, 0x98, 0x8b, 0xd2, 0x08, 0xf8, 0xe7, 0x07, 0x8b, 0xd3, 0x96, 0x96, + 0xd8, 0x92, 0x08, 0x9e, 0xfb, 0x9b, 0x07, 0xfb, 0x27, 0x4d, 0x54, 0xfb, + 0x16, 0x1f, 0x8b, 0x3a, 0xa2, 0x52, 0xba, 0x6b, 0xac, 0x73, 0xa7, 0x83, + 0xca, 0x89, 0x08, 0xfb, 0xc4, 0x07, 0x8b, 0x37, 0x81, 0x7f, 0x3d, 0x86, + 0x08, 0x75, 0xf7, 0x2e, 0x07, 0xf9, 0xae, 0x07, 0x49, 0xfb, 0xed, 0x15, + 0x35, 0x94, 0x6b, 0xbe, 0x8b, 0xf7, 0x12, 0x8b, 0xd2, 0x99, 0xb8, 0xa8, + 0xa0, 0x9d, 0x98, 0x9c, 0x91, 0xb3, 0x8e, 0x08, 0xfb, 0xed, 0x07, 0x0e, + 0x8f, 0xf7, 0x42, 0xf8, 0x66, 0x15, 0x40, 0x50, 0x4f, 0x41, 0x3f, 0xc7, + 0x4f, 0xd6, 0xd5, 0xc8, 0xc8, 0xd3, 0xd8, 0x50, 0xc7, 0x3e, 0x1f, 0x0e, + 0x7e, 0xf5, 0xfb, 0x21, 0x15, 0xce, 0xac, 0xb8, 0xc8, 0x8b, 0xc7, 0x08, + 0xbd, 0x68, 0xb2, 0x5e, 0x68, 0x73, 0x74, 0x69, 0x1e, 0x6b, 0xa2, 0x78, + 0xaf, 0x1e, 0x91, 0x8b, 0x92, 0x8c, 0x91, 0x8c, 0x08, 0x92, 0x8d, 0x8b, + 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0x91, 0x85, 0x8b, 0x83, 0x8b, 0x6b, 0x6f, + 0x66, 0x55, 0x66, 0x08, 0x94, 0x78, 0x05, 0x0e, 0xed, 0xd3, 0xfb, 0x21, + 0x15, 0xce, 0xac, 0xb8, 0xc8, 0x8b, 0xc7, 0x08, 0xbd, 0x68, 0xb2, 0x5e, + 0x68, 0x73, 0x74, 0x69, 0x1e, 0x6b, 0xa1, 0x78, 0xb0, 0x1e, 0x91, 0x8b, + 0x92, 0x8c, 0x91, 0x8c, 0x08, 0x92, 0x8d, 0x8b, 0x8b, 0x8c, 0x8b, 0x93, + 0x8b, 0x91, 0x85, 0x8b, 0x83, 0x8b, 0x6b, 0x6f, 0x66, 0x55, 0x66, 0x08, + 0x94, 0x78, 0x05, 0xf7, 0x7c, 0x16, 0xce, 0xac, 0xb8, 0xc8, 0x8b, 0xc7, + 0x08, 0xbd, 0x68, 0xb2, 0x5e, 0x68, 0x73, 0x74, 0x69, 0x6b, 0xa1, 0x78, + 0xb0, 0x1e, 0x91, 0x8b, 0x92, 0x8c, 0x91, 0x8c, 0x92, 0x8d, 0x8b, 0x8b, + 0x8c, 0x8b, 0x93, 0x8b, 0x91, 0x85, 0x8b, 0x83, 0x8b, 0x6b, 0x6f, 0x66, + 0x55, 0x66, 0x08, 0x94, 0x78, 0x05, 0x0e, 0xed, 0xc4, 0xf8, 0x45, 0x15, + 0xce, 0xac, 0xb8, 0xc8, 0x8b, 0xc7, 0x08, 0xbd, 0x68, 0xb2, 0x5e, 0x68, + 0x73, 0x74, 0x69, 0x6b, 0xa1, 0x78, 0xb0, 0x1e, 0x91, 0x8b, 0x92, 0x8c, + 0x91, 0x8c, 0x92, 0x8d, 0x8b, 0x8b, 0x8c, 0x8b, 0x93, 0x8b, 0x91, 0x85, + 0x8b, 0x83, 0x8b, 0x6b, 0x6f, 0x66, 0x55, 0x66, 0x08, 0x94, 0x78, 0x05, + 0xf7, 0x7c, 0x16, 0xce, 0xac, 0xb8, 0xc8, 0x8b, 0xc7, 0x08, 0xbd, 0x68, + 0xb2, 0x5e, 0x68, 0x73, 0x74, 0x69, 0x6b, 0xa1, 0x78, 0xb0, 0x1e, 0x91, + 0x8b, 0x92, 0x8c, 0x91, 0x8c, 0x92, 0x8d, 0x8b, 0x8b, 0x8c, 0x8b, 0x93, + 0x8b, 0x91, 0x85, 0x8b, 0x83, 0x8b, 0x6b, 0x6f, 0x66, 0x55, 0x66, 0x08, + 0x94, 0x78, 0x05, 0x0e, 0xf8, 0x5e, 0xf7, 0x72, 0x15, 0x4a, 0xc6, 0x05, + 0x85, 0x8f, 0x86, 0x90, 0x86, 0x90, 0x08, 0x88, 0x8d, 0x05, 0x85, 0x90, + 0x83, 0x92, 0x82, 0x94, 0x6d, 0xa5, 0x6e, 0xa7, 0x89, 0x90, 0x7a, 0xa0, + 0x76, 0x9d, 0x85, 0x8b, 0x86, 0x8b, 0x86, 0x86, 0x8b, 0x86, 0x8b, 0x7e, + 0xa4, 0x62, 0xa8, 0x68, 0x08, 0xd6, 0x2e, 0x87, 0x85, 0x85, 0x84, 0x05, + 0x40, 0x2c, 0x60, 0x4d, 0x8b, 0x7f, 0x8b, 0x86, 0x8f, 0x87, 0x91, 0x8b, + 0x8f, 0x8b, 0x8d, 0x8c, 0x8f, 0x90, 0xc4, 0xc3, 0xb3, 0xb0, 0xd4, 0xca, + 0x08, 0xaa, 0xa6, 0x05, 0xfb, 0x54, 0x16, 0x4a, 0xc6, 0x05, 0x85, 0x8f, + 0x86, 0x90, 0x86, 0x90, 0x08, 0x88, 0x8d, 0x05, 0x85, 0x90, 0x83, 0x92, + 0x82, 0x94, 0x6d, 0xa5, 0x6e, 0xa7, 0x89, 0x90, 0x7a, 0xa0, 0x76, 0x9d, + 0x85, 0x8b, 0x86, 0x8b, 0x86, 0x86, 0x8b, 0x86, 0x8b, 0x7e, 0xa4, 0x62, + 0xa8, 0x68, 0x08, 0xd6, 0x2e, 0x87, 0x85, 0x85, 0x84, 0x05, 0x40, 0x2c, + 0x60, 0x4d, 0x8b, 0x7f, 0x8b, 0x86, 0x8f, 0x87, 0x91, 0x8b, 0x8f, 0x8b, + 0x8d, 0x8c, 0x8f, 0x90, 0xc4, 0xc3, 0xb3, 0xb0, 0xd4, 0xca, 0x08, 0xaa, + 0xa6, 0x05, 0x0e, 0xf9, 0x22, 0xf7, 0x3a, 0xef, 0x15, 0x6d, 0x72, 0x71, + 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, 0x71, 0xa5, + 0x6d, 0x1f, 0xf7, 0xe1, 0x16, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, + 0xa8, 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0xf7, 0xe1, + 0x16, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, + 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0x0e, 0xf9, 0x22, 0xf8, 0xcb, 0xf9, + 0x56, 0x15, 0x5f, 0x06, 0x31, 0x33, 0x7b, 0x82, 0x51, 0x8b, 0x63, 0x8b, + 0x74, 0x94, 0x67, 0xa9, 0x70, 0xa1, 0x7f, 0x91, 0x76, 0x8b, 0x08, 0x25, + 0x30, 0x27, 0xfb, 0x05, 0x3d, 0xbe, 0x50, 0xce, 0x1f, 0xad, 0x8b, 0xa7, + 0x98, 0xa8, 0xa8, 0xb9, 0xb9, 0xa8, 0xd3, 0x8b, 0xce, 0x8b, 0x99, 0x8a, + 0x97, 0x88, 0x9d, 0xab, 0x80, 0x9d, 0x88, 0xa5, 0x8b, 0xc0, 0x8b, 0xaa, + 0x99, 0xb0, 0xb6, 0x08, 0xfc, 0x1e, 0xfd, 0x26, 0xba, 0x8b, 0x05, 0xf8, + 0x42, 0xf9, 0x68, 0x05, 0xfc, 0x05, 0x52, 0x15, 0x9c, 0x79, 0x98, 0x82, + 0x99, 0x84, 0xa0, 0x81, 0x8f, 0x84, 0x8b, 0x6e, 0x08, 0xfb, 0x07, 0x4d, + 0x26, 0x45, 0x69, 0x74, 0xa7, 0xb5, 0x1e, 0x8b, 0xe2, 0xb7, 0xec, 0xbf, + 0xa8, 0x90, 0x8e, 0x96, 0x91, 0x93, 0x8f, 0x08, 0xf7, 0xe6, 0xfb, 0xd3, + 0x15, 0x2b, 0x2e, 0x23, 0x20, 0x3d, 0xc0, 0x4f, 0xcf, 0xe1, 0xd9, 0xf7, + 0x03, 0xf7, 0x0d, 0x1f, 0xd5, 0x68, 0xb6, 0x4e, 0x1e, 0x97, 0x6f, 0x15, + 0xae, 0xa5, 0x66, 0x58, 0x22, 0x49, 0x26, 0x47, 0x6b, 0x73, 0xa9, 0xb2, + 0x1f, 0x8b, 0xce, 0xad, 0xe3, 0xb7, 0xba, 0x98, 0x99, 0x9f, 0x94, 0x9d, + 0x8b, 0x08, 0xf7, 0xf2, 0xa7, 0x15, 0x2b, 0x2e, 0x23, 0x21, 0x3c, 0xc0, + 0x4f, 0xd0, 0xdf, 0xda, 0xf7, 0x03, 0xf7, 0x0d, 0xd5, 0x68, 0xb6, 0x4e, + 0x1f, 0x96, 0x6f, 0x15, 0xb0, 0xa4, 0x67, 0x57, 0x22, 0x49, 0x26, 0x47, + 0x6b, 0x73, 0xa9, 0xb4, 0x1f, 0x8b, 0xc1, 0xaa, 0xe4, 0xac, 0xb4, 0xa0, + 0xa6, 0x9f, 0x97, 0xa2, 0x8b, 0x08, 0x0e, 0xed, 0xf7, 0x5c, 0xf7, 0xba, + 0x15, 0x7d, 0x3a, 0x79, 0x68, 0x4c, 0x41, 0x58, 0x4d, 0x73, 0x55, 0x8b, + 0x58, 0x8b, 0x65, 0x98, 0x67, 0xa2, 0x74, 0xae, 0x68, 0xc6, 0x74, 0xc1, + 0x8b, 0x08, 0xe7, 0xd1, 0xc9, 0xde, 0xb3, 0x7a, 0xa1, 0x6c, 0x72, 0x7b, + 0x7a, 0x73, 0x1f, 0x8b, 0x7d, 0x91, 0x7f, 0x9a, 0x7a, 0x97, 0x7d, 0x90, + 0x82, 0x8b, 0x83, 0x08, 0x6b, 0x5c, 0x6d, 0x5b, 0x4f, 0x5b, 0xc0, 0xce, + 0x1e, 0x8b, 0xb9, 0x98, 0xc2, 0xa3, 0xc2, 0x08, 0xa7, 0xcb, 0x05, 0x9e, + 0xbb, 0x95, 0xbd, 0x8c, 0xb7, 0x08, 0x7a, 0x06, 0x93, 0xf7, 0x42, 0x15, + 0x6b, 0x75, 0x76, 0x6d, 0x6b, 0xa2, 0x73, 0xa9, 0xa8, 0xa4, 0xa4, 0xa9, + 0xa8, 0x73, 0xa2, 0x6e, 0x1f, 0x0e, 0x7e, 0xf7, 0x86, 0xf8, 0x8f, 0x15, + 0xfb, 0x27, 0xf7, 0x28, 0x05, 0x79, 0x9d, 0x82, 0x90, 0x7c, 0x8b, 0x76, + 0x8b, 0x7e, 0x7f, 0x8b, 0x78, 0x8b, 0x7b, 0x96, 0x7c, 0x9d, 0x7f, 0x08, + 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, 0x05, 0x0e, 0x7e, 0xf7, 0x19, 0xf8, 0x8f, + 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, 0x8b, + 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x82, 0x86, 0x79, 0x79, 0x08, + 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0x7e, 0xf7, 0xd6, 0xf8, + 0x8f, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, 0x10, 0xfb, 0x3b, + 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, 0x24, 0xad, 0x8b, 0x05, 0x0e, + 0x7e, 0xf7, 0xc2, 0xf9, 0x12, 0x15, 0x7a, 0x65, 0x7e, 0x7f, 0x74, 0x8b, + 0x7c, 0x8b, 0x78, 0x91, 0x78, 0x94, 0x08, 0x73, 0x97, 0x05, 0x74, 0x97, + 0x72, 0x91, 0x75, 0x8b, 0x59, 0x8b, 0x67, 0x67, 0x7c, 0x4a, 0x08, 0xa8, + 0x06, 0x96, 0xaa, 0x9c, 0x9a, 0xa2, 0x8b, 0x97, 0x8b, 0x99, 0x87, 0x9a, + 0x84, 0x08, 0xa2, 0x80, 0x05, 0xb4, 0x77, 0x9a, 0x87, 0xa4, 0x8b, 0xc2, + 0x8b, 0xa8, 0xa9, 0xa0, 0xd7, 0x08, 0x6e, 0x06, 0x0e, 0x7e, 0x96, 0xf8, + 0xed, 0x15, 0x55, 0xf7, 0xcb, 0xc1, 0xfb, 0xcb, 0x07, 0x0e, 0x7e, 0xf7, + 0xaa, 0xf9, 0x2c, 0x15, 0x6f, 0x3f, 0x72, 0x76, 0x51, 0x8b, 0x4b, 0x8b, + 0x69, 0xa9, 0x7d, 0xce, 0x08, 0x6e, 0x06, 0x8c, 0x58, 0x92, 0x73, 0x9e, + 0x6f, 0xa4, 0x68, 0xb3, 0x78, 0xba, 0x8b, 0xdf, 0x8b, 0xb9, 0xbe, 0x97, + 0xf5, 0x08, 0x6e, 0x06, 0x0e, 0x7e, 0xf7, 0x3a, 0xf9, 0x02, 0x15, 0x72, + 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, + 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0x7e, 0xcd, 0xf9, 0x02, 0x15, 0x72, 0x74, + 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, + 0xa2, 0x6f, 0x1f, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, + 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, + 0x7e, 0xf7, 0x3a, 0xf9, 0x5b, 0x15, 0x55, 0x5e, 0x5e, 0x55, 0x53, 0xb6, + 0x5f, 0xc3, 0xc2, 0xb8, 0xb7, 0xc2, 0xc2, 0x5e, 0xb8, 0x54, 0x1f, 0x8c, + 0x69, 0x15, 0xae, 0xa9, 0x6d, 0x67, 0x67, 0x6d, 0x6e, 0x66, 0x68, 0x6e, + 0xa9, 0xaf, 0xaf, 0xa9, 0xa8, 0xaf, 0x1f, 0x0e, 0x7e, 0xed, 0x28, 0x15, + 0x92, 0x86, 0x05, 0x93, 0x8e, 0x94, 0x8c, 0x96, 0x8b, 0x08, 0xb1, 0x9a, + 0x81, 0x71, 0x70, 0x76, 0x7a, 0x69, 0x1f, 0x76, 0x8b, 0x7b, 0x8e, 0x6f, + 0x94, 0x08, 0x7d, 0x6c, 0x05, 0xa8, 0x7f, 0xa2, 0x87, 0xab, 0x8b, 0x08, + 0xd8, 0xbb, 0xab, 0xbf, 0xb6, 0x6b, 0xa5, 0x55, 0x1f, 0x81, 0x8b, 0x85, + 0x8a, 0x81, 0x89, 0x08, 0xa4, 0xcc, 0x68, 0x8b, 0x62, 0x28, 0x05, 0x0e, + 0x7e, 0xf7, 0x55, 0xf8, 0x8f, 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, + 0x94, 0x98, 0x8b, 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, + 0x82, 0x86, 0x79, 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, + 0xfb, 0x30, 0x16, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, + 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x82, 0x86, 0x79, + 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0x7e, 0xf7, + 0x79, 0x42, 0x15, 0x6c, 0x71, 0x78, 0x81, 0x76, 0x8b, 0x75, 0x8b, 0x7b, + 0x9c, 0x8b, 0xa2, 0x8b, 0xa2, 0x98, 0xa0, 0xaa, 0xa4, 0x08, 0x5d, 0x06, + 0x65, 0x6d, 0x7b, 0x70, 0x8b, 0x6b, 0x8b, 0x60, 0xab, 0x6a, 0xb4, 0x8b, + 0xb4, 0x8b, 0xad, 0xa2, 0xb0, 0xc0, 0x08, 0x77, 0x9b, 0x05, 0x0e, 0x7e, + 0xf7, 0xd6, 0xf9, 0x36, 0x15, 0x69, 0x8b, 0xfb, 0x0e, 0x24, 0xfb, 0x0d, + 0xf2, 0x69, 0x8b, 0xf7, 0x10, 0xfb, 0x3b, 0xc9, 0x8b, 0xf7, 0x11, 0xf7, + 0x3b, 0x05, 0x0e, 0xf9, 0x22, 0xf7, 0x8e, 0x04, 0x5a, 0xfa, 0x7c, 0xbc, + 0xfe, 0x7c, 0x07, 0x0e, 0xf8, 0xb3, 0xf9, 0xc4, 0xf8, 0x9d, 0x15, 0xf7, + 0x21, 0xfc, 0xc8, 0x77, 0x07, 0xcc, 0x89, 0xa4, 0x82, 0x8b, 0x75, 0x8b, + 0x85, 0x88, 0x80, 0x85, 0x80, 0x08, 0xfb, 0x89, 0xfc, 0x78, 0x05, 0x6a, + 0x4e, 0x7f, 0x80, 0x60, 0x85, 0x08, 0x78, 0xf7, 0x5b, 0x07, 0x9e, 0x8a, + 0x07, 0x60, 0x8f, 0x72, 0x96, 0x8b, 0x9a, 0x8b, 0xa1, 0xa3, 0xc5, 0xb3, + 0xd9, 0x08, 0xa7, 0xc0, 0xf7, 0x44, 0x8b, 0x8b, 0xfb, 0x2c, 0x05, 0x8b, + 0x49, 0x7f, 0x7d, 0x4f, 0x84, 0x08, 0x7a, 0x89, 0x05, 0x78, 0xf8, 0x92, + 0x07, 0xb7, 0xf7, 0x3c, 0x73, 0x8b, 0x05, 0x51, 0xfb, 0x02, 0x6c, 0x77, + 0xfb, 0x00, 0x8b, 0x08, 0x3f, 0x06, 0x4a, 0x87, 0x8e, 0xbd, 0x1f, 0xf7, + 0x82, 0xf7, 0x25, 0x07, 0xb1, 0x8b, 0xa6, 0x81, 0x98, 0x79, 0x96, 0x7b, + 0x8f, 0x7c, 0x90, 0x62, 0x08, 0xa0, 0xf7, 0x7e, 0x76, 0x06, 0x87, 0x66, + 0x87, 0x7c, 0x81, 0x7c, 0x7b, 0x76, 0x68, 0x82, 0x4c, 0x8b, 0x08, 0xfb, + 0x03, 0xf7, 0x7a, 0x06, 0xa1, 0x93, 0x93, 0x9e, 0x1e, 0xe2, 0x06, 0xf7, + 0x26, 0x8b, 0xa2, 0x7d, 0x98, 0x30, 0x08, 0xa2, 0x06, 0xfc, 0xd5, 0xfb, + 0x72, 0x15, 0xf7, 0x33, 0xf7, 0xd3, 0x8b, 0xfb, 0xd3, 0xfb, 0x33, 0x8b, + 0x05, 0x0e, 0x45, 0xf7, 0xa2, 0xf8, 0x4e, 0x15, 0x81, 0x83, 0x83, 0x87, + 0x81, 0x8b, 0x08, 0x80, 0x89, 0x91, 0xa8, 0x1f, 0xf7, 0x07, 0x07, 0xcb, + 0x68, 0xab, 0x45, 0x4d, 0x5d, 0x6f, 0x64, 0x7a, 0x99, 0x7d, 0x9d, 0x9b, + 0x9a, 0x97, 0x98, 0x1e, 0x8b, 0x8d, 0x8b, 0x8e, 0x8a, 0x8e, 0x8a, 0x90, + 0x8a, 0x90, 0x8b, 0x8f, 0x08, 0x96, 0xa2, 0x97, 0xa1, 0xa2, 0x98, 0x7c, + 0x70, 0x1e, 0x6d, 0x07, 0x30, 0x6a, 0x7e, 0x84, 0x70, 0x74, 0x08, 0x7e, + 0x80, 0x82, 0x77, 0x8b, 0x77, 0x8b, 0x63, 0xa9, 0x6f, 0xb4, 0x8b, 0xa9, + 0x8b, 0xa7, 0x99, 0xac, 0xa9, 0x91, 0x6b, 0x97, 0x7f, 0xa6, 0x8b, 0xa1, + 0x8b, 0x99, 0x92, 0xa2, 0xa2, 0x08, 0x9d, 0x07, 0xfb, 0x04, 0xab, 0x15, + 0x8b, 0x83, 0x88, 0x84, 0x83, 0x84, 0x7a, 0x83, 0x7f, 0x88, 0x7e, 0x8b, + 0x76, 0x8b, 0x7a, 0x9f, 0x8b, 0xa3, 0x8b, 0xa5, 0xa0, 0x9a, 0xd1, 0xa4, + 0x08, 0x3e, 0x07, 0x0e, 0xf7, 0x9d, 0xee, 0xf7, 0xd9, 0x15, 0x34, 0x59, + 0x8b, 0x5a, 0xe2, 0xbd, 0x8b, 0xfb, 0x3b, 0x05, 0x8b, 0x45, 0x7d, 0x7c, + 0x42, 0x86, 0x08, 0x78, 0xf8, 0xae, 0x07, 0xbb, 0xf7, 0x42, 0x72, 0x8b, + 0x05, 0x7a, 0x65, 0x7d, 0x74, 0x7c, 0x7a, 0x68, 0x64, 0x54, 0x79, 0x38, + 0x8b, 0x08, 0x48, 0x06, 0x42, 0x7e, 0x91, 0xae, 0x1f, 0x8b, 0xf7, 0x93, + 0xf7, 0x2f, 0xe4, 0x8b, 0xbc, 0xfb, 0x2f, 0x32, 0x8b, 0xf7, 0x3d, 0x05, + 0x8b, 0xd2, 0x99, 0x99, 0xda, 0x90, 0x08, 0x9e, 0xfb, 0xae, 0x78, 0x07, + 0xd5, 0x85, 0x98, 0x7d, 0x8b, 0x45, 0x08, 0xfb, 0x78, 0x07, 0x0e, 0xf8, + 0x0c, 0xf9, 0x26, 0xf9, 0x72, 0x15, 0x5a, 0x8b, 0x43, 0x20, 0x05, 0x4b, + 0xaf, 0x5e, 0x98, 0x49, 0x8b, 0xfb, 0x54, 0x8b, 0xfb, 0x1c, 0xfb, 0x23, + 0x8b, 0xfb, 0x5f, 0x8b, 0x4c, 0x9a, 0x4a, 0xa5, 0x59, 0x9d, 0x68, 0x9b, + 0x77, 0xb5, 0x65, 0x08, 0x2c, 0xfb, 0x1f, 0xbc, 0x8b, 0xda, 0xf7, 0x08, + 0x05, 0xc9, 0x66, 0xb9, 0x7e, 0xce, 0x8b, 0xf7, 0x56, 0x8b, 0xf7, 0x1b, + 0xf7, 0x22, 0x8b, 0xf7, 0x5f, 0x8b, 0xcc, 0x7c, 0xcc, 0x70, 0xbd, 0x79, + 0xae, 0x7a, 0x9f, 0x62, 0xb1, 0x08, 0xe3, 0xf7, 0x16, 0x05, 0xfb, 0x17, + 0xfb, 0x56, 0x15, 0xad, 0x4a, 0x98, 0x53, 0x8b, 0x32, 0x8b, 0xfb, 0x53, + 0x3a, 0xfb, 0x09, 0xfb, 0x18, 0x8b, 0x51, 0x8b, 0x62, 0x9e, 0x60, 0xba, + 0x08, 0xf7, 0xc8, 0xf8, 0x58, 0x05, 0xfb, 0xe1, 0xfc, 0x35, 0x15, 0x69, + 0xcb, 0x7f, 0xc2, 0x8b, 0xe3, 0x8b, 0xf7, 0x53, 0xdd, 0xf7, 0x0b, 0xf7, + 0x17, 0x8b, 0xc2, 0x8b, 0xb5, 0x78, 0xb7, 0x5d, 0x08, 0xfb, 0xc8, 0xfc, + 0x58, 0x05, 0x0e, 0xf8, 0xb3, 0xf9, 0xda, 0xf8, 0x9d, 0x15, 0xf7, 0x21, + 0xfb, 0xda, 0x07, 0x76, 0x8b, 0x49, 0x8d, 0x79, 0x8c, 0x08, 0x5b, 0x8e, + 0x88, 0x8b, 0x7d, 0x8b, 0x38, 0x8b, 0x42, 0x71, 0x54, 0x5a, 0x4b, 0x53, + 0x66, 0x27, 0x8b, 0xfb, 0x07, 0x8b, 0xfb, 0x00, 0xa9, 0x37, 0xc7, 0x50, + 0xbd, 0x59, 0xcf, 0x70, 0xd5, 0x8b, 0x99, 0x8b, 0xa0, 0x8c, 0xa2, 0x8c, + 0x08, 0xb3, 0x8d, 0xc7, 0x8d, 0xa0, 0x8b, 0x08, 0xf7, 0xf2, 0x8b, 0xb7, + 0xf7, 0x3c, 0x73, 0x8b, 0x05, 0x58, 0x2c, 0x67, 0x6c, 0x4c, 0x89, 0x08, + 0xfb, 0x10, 0x89, 0x05, 0x5f, 0x8a, 0x7f, 0x95, 0x8b, 0xb0, 0x08, 0xf7, + 0x89, 0xf7, 0x1e, 0x07, 0xd0, 0x8b, 0x9f, 0x77, 0x94, 0x3c, 0x08, 0xa0, + 0xf7, 0x7e, 0x76, 0x06, 0x88, 0x66, 0x86, 0x7c, 0x80, 0x7c, 0x7c, 0x76, + 0x67, 0x81, 0x4d, 0x8b, 0x08, 0x23, 0xf7, 0x80, 0x06, 0xa0, 0x94, 0x8e, + 0xc3, 0x1e, 0xbe, 0x06, 0xf7, 0x17, 0x8b, 0xa4, 0x7b, 0x97, 0x32, 0x08, + 0xa2, 0x06, 0xfc, 0x2b, 0xfc, 0x1a, 0x15, 0x44, 0x6e, 0x6e, 0x44, 0xfb, + 0x0e, 0x48, 0xf3, 0xf7, 0x52, 0xf7, 0x58, 0xd0, 0xf7, 0x03, 0xf7, 0x0d, + 0xd0, 0xa9, 0x6b, 0x42, 0x1e, 0xfc, 0x20, 0x07, 0x0e, 0x67, 0xf7, 0x33, + 0xf9, 0x38, 0x15, 0x30, 0x4d, 0x51, 0x36, 0x3b, 0xc8, 0x50, 0xdf, 0xe2, + 0xcd, 0xcb, 0xdf, 0xda, 0x4f, 0xc2, 0x36, 0x1f, 0x82, 0x6a, 0x15, 0xbb, + 0xac, 0x55, 0x40, 0x53, 0x72, 0x6c, 0x5d, 0x1f, 0x72, 0x8b, 0x78, 0x97, + 0x7f, 0xa1, 0x7b, 0xa8, 0x82, 0xb3, 0x8b, 0xb2, 0x08, 0xb8, 0xa7, 0xa8, + 0xb6, 0x1e, 0x0e, 0xf7, 0xd5, 0xf9, 0x00, 0xf7, 0x2e, 0x15, 0x5b, 0x45, + 0x64, 0x70, 0x52, 0x8b, 0x62, 0x8b, 0x66, 0x9f, 0x7a, 0xa9, 0x76, 0xb2, + 0x86, 0xab, 0x8a, 0xee, 0x08, 0xf7, 0x9a, 0x06, 0x80, 0xf7, 0x15, 0x5b, + 0xc1, 0x26, 0x8b, 0x5d, 0x8b, 0x6f, 0x80, 0x5e, 0x69, 0x08, 0x65, 0xac, + 0x6d, 0x97, 0x5a, 0x8b, 0x08, 0x30, 0x46, 0x5d, 0x4d, 0x6e, 0x9c, 0x78, + 0xa6, 0x1f, 0xa7, 0x8b, 0x9b, 0x9e, 0x8a, 0xa8, 0x08, 0x8a, 0x9c, 0x8b, + 0x96, 0x05, 0x8b, 0x8b, 0x8b, 0x8e, 0x8a, 0x8e, 0x86, 0xa6, 0xaa, 0xa2, + 0xb5, 0x8b, 0xa3, 0x8b, 0x9e, 0x82, 0x92, 0x7d, 0x93, 0x7c, 0x90, 0x6c, + 0x8a, 0x74, 0x08, 0x89, 0x4c, 0x35, 0x67, 0x05, 0x20, 0x5f, 0x61, 0x62, + 0x8b, 0x4f, 0x8b, 0x4a, 0xbb, 0x5e, 0xcf, 0x8b, 0xbd, 0x8b, 0xad, 0x9c, + 0xcf, 0xc3, 0x08, 0xad, 0x57, 0xb1, 0x76, 0xc4, 0x8b, 0xba, 0x8b, 0xb4, + 0x9b, 0xaf, 0xab, 0xa6, 0xa3, 0x9e, 0xa7, 0xa6, 0xc6, 0x08, 0x7f, 0x90, + 0x05, 0xfb, 0xee, 0xba, 0x15, 0x8b, 0x67, 0x91, 0x66, 0x98, 0x66, 0x8c, + 0x8a, 0x8b, 0x8a, 0x8b, 0x8a, 0x08, 0x79, 0x4a, 0x6b, 0x66, 0x66, 0x6d, + 0xb2, 0xbb, 0x1e, 0x8b, 0xc7, 0xa7, 0xa3, 0xf7, 0x0d, 0xb7, 0x08, 0x57, + 0x07, 0xdc, 0xf5, 0x15, 0x90, 0xe3, 0xa4, 0xaf, 0xc4, 0x8b, 0xc1, 0x8b, + 0xa2, 0x66, 0x8d, 0x34, 0x08, 0xfb, 0x3a, 0x06, 0x0e, 0x47, 0xf7, 0x43, + 0xf8, 0x60, 0x15, 0xfb, 0x2f, 0x54, 0x8b, 0x7c, 0x93, 0x8c, 0x05, 0x97, + 0x8d, 0x98, 0x8c, 0x94, 0x8b, 0x08, 0xa3, 0x94, 0x7b, 0x5f, 0x1f, 0xfb, + 0x7c, 0x07, 0x8b, 0x43, 0x81, 0x80, 0x46, 0x87, 0x08, 0x7c, 0xf7, 0x81, + 0x9a, 0x07, 0x49, 0x90, 0x83, 0x95, 0x8b, 0xd3, 0x08, 0x8b, 0xf7, 0xf7, + 0x87, 0x8e, 0x05, 0x0e, 0x47, 0xed, 0xf7, 0xfe, 0x15, 0x3d, 0x55, 0x8b, + 0x5f, 0xd9, 0xc1, 0x8b, 0xfb, 0x7b, 0x05, 0x8b, 0x55, 0x7d, 0x7e, 0x4c, + 0x86, 0x08, 0x7c, 0xf7, 0x80, 0x9a, 0x07, 0x4c, 0x8f, 0x7f, 0x95, 0x8b, + 0xc2, 0x08, 0x8b, 0xf7, 0xb7, 0xd8, 0xc0, 0x8b, 0xb7, 0x3e, 0x56, 0x8b, + 0xf7, 0x9a, 0x87, 0x8d, 0x05, 0x57, 0x7a, 0x65, 0x81, 0x46, 0x7a, 0x08, + 0x7b, 0x91, 0x07, 0x96, 0x8c, 0x97, 0x8c, 0x93, 0x8b, 0x08, 0xab, 0x95, + 0x7d, 0x5c, 0x1f, 0xfb, 0x5e, 0x07, 0x0e, 0xf8, 0x49, 0xf8, 0xbb, 0x15, + 0x64, 0x8b, 0x52, 0xfb, 0x01, 0x05, 0x68, 0x98, 0x73, 0x90, 0x6a, 0x8b, + 0xfb, 0x15, 0x8b, 0x30, 0x2a, 0x8b, 0xfb, 0x1c, 0x8b, 0x5d, 0x97, 0x5d, + 0xa0, 0x65, 0x9b, 0x70, 0x98, 0x7c, 0xad, 0x70, 0x08, 0x42, 0xfb, 0x20, + 0xb0, 0x8b, 0xcc, 0xf7, 0x0f, 0x05, 0xae, 0x7b, 0xa2, 0x86, 0xae, 0x8b, + 0xf7, 0x13, 0x8b, 0xeb, 0xf4, 0x8b, 0xf7, 0x1f, 0x8b, 0xbb, 0x7d, 0xbb, + 0x73, 0xb1, 0x7b, 0xa3, 0x7e, 0x97, 0x6c, 0xa1, 0x08, 0xcc, 0xf7, 0x11, + 0x05, 0x2a, 0xfb, 0x4d, 0x15, 0xa8, 0x54, 0x96, 0x5f, 0x8b, 0x4b, 0x8b, + 0xfb, 0x08, 0x5f, 0x46, 0x40, 0x8b, 0x69, 0x8b, 0x74, 0x97, 0x72, 0xa9, + 0x08, 0xf7, 0x35, 0xf7, 0xc6, 0x05, 0xfb, 0x4a, 0xfb, 0xa6, 0x15, 0x70, + 0xc4, 0x7f, 0xc5, 0x8b, 0xd0, 0x8b, 0xe9, 0xba, 0xc9, 0xd2, 0x8b, 0xaa, + 0x8b, 0xa1, 0x81, 0xa6, 0x71, 0x08, 0xfb, 0x33, 0xfb, 0xc4, 0x05, 0x0e, + 0xf8, 0x0c, 0xf9, 0x3b, 0xf7, 0x25, 0x15, 0x5c, 0x4b, 0x68, 0x73, 0x5b, + 0x8b, 0x66, 0x8b, 0x68, 0x9f, 0x79, 0xa9, 0x71, 0xb9, 0x82, 0xb0, 0x87, + 0xe2, 0x08, 0xf7, 0x92, 0x06, 0x88, 0xc8, 0x83, 0xa8, 0x74, 0xaa, 0x6f, + 0xb2, 0x5b, 0xa2, 0x59, 0x8b, 0x55, 0x8b, 0x68, 0x77, 0x62, 0x53, 0x59, + 0xc3, 0x63, 0x9f, 0x4d, 0x8b, 0x59, 0x8b, 0x60, 0x7a, 0x69, 0x6c, 0x5d, + 0x5f, 0x6e, 0x41, 0x8b, 0x3f, 0x08, 0xfb, 0x19, 0xe0, 0x2c, 0xf7, 0x0d, + 0x1e, 0xcf, 0x8b, 0xb4, 0xa6, 0xb1, 0xcf, 0x08, 0xa9, 0x47, 0xaf, 0x70, + 0xc9, 0x8b, 0xd9, 0x8b, 0xbc, 0xb4, 0xbf, 0xf7, 0x00, 0x08, 0x80, 0x91, + 0x05, 0xfc, 0x56, 0xf7, 0xb2, 0x15, 0xd4, 0xb4, 0x38, 0xfb, 0x29, 0x1f, + 0xfb, 0x0c, 0x68, 0x4c, 0x47, 0x3c, 0x62, 0xe1, 0xf7, 0x3d, 0x1e, 0x8b, + 0xbf, 0x99, 0xc1, 0x9f, 0xa0, 0xa1, 0xa1, 0xa3, 0x96, 0xa8, 0x8b, 0x08, + 0xf7, 0x52, 0xfb, 0x10, 0x15, 0x8c, 0xde, 0xa6, 0xb4, 0xc0, 0x8b, 0x08, + 0xb9, 0xac, 0x62, 0x53, 0x1f, 0x70, 0xfb, 0x34, 0x07, 0x0e, 0xd4, 0xdf, + 0x15, 0x8b, 0x56, 0x80, 0x7f, 0x59, 0x87, 0x08, 0x7c, 0xf7, 0x25, 0xf8, + 0xb9, 0x07, 0xcc, 0xad, 0xb5, 0xbf, 0xc4, 0xad, 0x57, 0x34, 0x1e, 0x8b, + 0x3b, 0x6d, 0x62, 0x4a, 0x84, 0x76, 0x89, 0x83, 0x87, 0x8b, 0x82, 0x8b, + 0x80, 0x94, 0x86, 0xa2, 0x8a, 0x08, 0xe3, 0x88, 0xb7, 0x46, 0x8b, 0xfb, + 0x1b, 0x8b, 0x36, 0x75, 0x5e, 0x61, 0x8b, 0x78, 0x8b, 0x83, 0x93, 0x89, + 0xa1, 0x08, 0x89, 0xa1, 0x05, 0x89, 0xa2, 0x79, 0x9c, 0x75, 0x8b, 0x08, + 0x71, 0x78, 0x76, 0x70, 0x60, 0xb3, 0x6d, 0xc4, 0xef, 0xda, 0xe1, 0xf7, + 0x01, 0x1f, 0x8b, 0xc3, 0x75, 0xbd, 0x63, 0xad, 0x6b, 0xa7, 0x6e, 0x96, + 0x4e, 0x97, 0x08, 0xf6, 0xbc, 0xa9, 0xac, 0x8b, 0xd3, 0x8b, 0xe7, 0x49, + 0xc7, 0x23, 0x8b, 0x47, 0x8b, 0x58, 0x71, 0x6e, 0x58, 0x76, 0x66, 0x82, + 0x5e, 0x8b, 0x45, 0x08, 0xfc, 0x06, 0x07, 0x0e, 0xf8, 0x0c, 0xf9, 0x56, + 0x9e, 0x15, 0x5e, 0x8e, 0x81, 0x95, 0x68, 0xd5, 0x08, 0xfb, 0x8d, 0xf8, + 0xcc, 0x77, 0x8b, 0xfb, 0x64, 0xfc, 0x7f, 0x05, 0x4b, 0xfb, 0x26, 0x7f, + 0x7b, 0x5b, 0x89, 0x08, 0x78, 0xf7, 0x5a, 0x9e, 0x07, 0x5b, 0x77, 0x98, + 0xa7, 0x1f, 0x8b, 0x97, 0x8e, 0x99, 0x90, 0x98, 0x08, 0xb9, 0xf7, 0x09, + 0xf7, 0x9a, 0x8b, 0xb4, 0x2b, 0x05, 0x97, 0x70, 0x92, 0x71, 0x8b, 0x7d, + 0x8b, 0x72, 0x7a, 0x83, 0x56, 0x8a, 0x08, 0x78, 0xf7, 0x93, 0x9e, 0x07, + 0xfc, 0x7e, 0xf7, 0x82, 0x15, 0xf7, 0x07, 0xf7, 0xa7, 0xf7, 0x08, 0xfb, + 0xa7, 0xfb, 0x7b, 0x8b, 0x05, 0xb1, 0xf8, 0xd5, 0x15, 0x72, 0x74, 0x74, + 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, + 0x6f, 0x1f, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, + 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0xf8, + 0x0c, 0xf9, 0x56, 0x9e, 0x15, 0x5e, 0x8e, 0x81, 0x95, 0x68, 0xd5, 0x08, + 0xfb, 0x8d, 0xf8, 0xcc, 0x77, 0x8b, 0xfb, 0x64, 0xfc, 0x7f, 0x05, 0x4b, + 0xfb, 0x26, 0x7f, 0x7b, 0x5b, 0x89, 0x08, 0x78, 0xf7, 0x5a, 0x9e, 0x07, + 0x5b, 0x77, 0x98, 0xa7, 0x1f, 0x8b, 0x97, 0x8e, 0x99, 0x90, 0x98, 0x08, + 0xb9, 0xf7, 0x09, 0xf7, 0x9a, 0x8b, 0xb4, 0x2b, 0x05, 0x97, 0x70, 0x92, + 0x71, 0x8b, 0x7d, 0x8b, 0x72, 0x7a, 0x83, 0x56, 0x8a, 0x08, 0x78, 0xf7, + 0x93, 0x9e, 0x07, 0xfc, 0x7e, 0xf7, 0x82, 0x15, 0xf7, 0x07, 0xf7, 0xa7, + 0xf7, 0x08, 0xfb, 0xa7, 0xfb, 0x7b, 0x8b, 0x05, 0xf6, 0xf8, 0x62, 0x15, + 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, 0x8b, 0x9f, + 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x82, 0x86, 0x79, 0x79, 0x08, 0xfb, + 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf9, 0x56, 0x9e, + 0x15, 0x5e, 0x8e, 0x81, 0x95, 0x68, 0xd5, 0x08, 0xfb, 0x8d, 0xf8, 0xcc, + 0x77, 0x8b, 0xfb, 0x64, 0xfc, 0x7f, 0x05, 0x4b, 0xfb, 0x26, 0x7f, 0x7b, + 0x5b, 0x89, 0x08, 0x78, 0xf7, 0x5a, 0x9e, 0x07, 0x5b, 0x77, 0x98, 0xa7, + 0x1f, 0x8b, 0x97, 0x8e, 0x99, 0x90, 0x98, 0x08, 0xb9, 0xf7, 0x09, 0xf7, + 0x9a, 0x8b, 0xb4, 0x2b, 0x05, 0x97, 0x70, 0x92, 0x71, 0x8b, 0x7d, 0x8b, + 0x72, 0x7a, 0x83, 0x56, 0x8a, 0x08, 0x78, 0xf7, 0x93, 0x9e, 0x07, 0xfc, + 0x7e, 0xf7, 0x82, 0x15, 0xf7, 0x07, 0xf7, 0xa7, 0xf7, 0x08, 0xfb, 0xa7, + 0xfb, 0x7b, 0x8b, 0x05, 0xf7, 0x71, 0xf8, 0x62, 0x15, 0xfb, 0x27, 0xf7, + 0x28, 0x05, 0x79, 0x9d, 0x82, 0x90, 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, + 0x8b, 0x78, 0x8b, 0x7b, 0x96, 0x7c, 0x9d, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, + 0xb3, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf9, 0x56, 0x9e, 0x15, 0x5e, 0x8e, + 0x81, 0x95, 0x68, 0xd5, 0x08, 0xfb, 0x8d, 0xf8, 0xcc, 0x77, 0x8b, 0xfb, + 0x64, 0xfc, 0x7f, 0x05, 0x4b, 0xfb, 0x26, 0x7f, 0x7b, 0x5b, 0x89, 0x08, + 0x78, 0xf7, 0x5a, 0x9e, 0x07, 0x5b, 0x77, 0x98, 0xa7, 0x1f, 0x8b, 0x97, + 0x8e, 0x99, 0x90, 0x98, 0x08, 0xb9, 0xf7, 0x09, 0xf7, 0x9a, 0x8b, 0xb4, + 0x2b, 0x05, 0x97, 0x70, 0x92, 0x71, 0x8b, 0x7d, 0x8b, 0x72, 0x7a, 0x83, + 0x56, 0x8a, 0x08, 0x78, 0xf7, 0x93, 0x9e, 0x07, 0xfc, 0x7e, 0xf7, 0x82, + 0x15, 0xf7, 0x07, 0xf7, 0xa7, 0xf7, 0x08, 0xfb, 0xa7, 0xfb, 0x7b, 0x8b, + 0x05, 0xf7, 0xbc, 0xf8, 0x62, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, 0x8b, + 0xfb, 0x10, 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, 0x24, + 0xad, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf9, 0x56, 0x9e, 0x15, 0x5e, 0x8e, + 0x81, 0x95, 0x68, 0xd5, 0x08, 0xfb, 0x8d, 0xf8, 0xcc, 0x77, 0x8b, 0xfb, + 0x64, 0xfc, 0x7f, 0x05, 0x4b, 0xfb, 0x26, 0x7f, 0x7b, 0x5b, 0x89, 0x08, + 0x78, 0xf7, 0x5a, 0x9e, 0x07, 0x5b, 0x77, 0x98, 0xa7, 0x1f, 0x8b, 0x97, + 0x8e, 0x99, 0x90, 0x98, 0x08, 0xb9, 0xf7, 0x09, 0xf7, 0x9a, 0x8b, 0xb4, + 0x2b, 0x05, 0x97, 0x70, 0x92, 0x71, 0x8b, 0x7d, 0x8b, 0x72, 0x7a, 0x83, + 0x56, 0x8a, 0x08, 0x78, 0xf7, 0x93, 0x07, 0x9e, 0x07, 0xfc, 0x7e, 0xf7, + 0x82, 0x15, 0xf7, 0x07, 0xf7, 0xa7, 0xf7, 0x08, 0xfb, 0xa7, 0xfb, 0x7b, + 0x8b, 0x05, 0xf7, 0xad, 0xf8, 0xe5, 0x15, 0x7a, 0x65, 0x7e, 0x7f, 0x74, + 0x8b, 0x7c, 0x8b, 0x78, 0x91, 0x78, 0x94, 0x08, 0x73, 0x97, 0x05, 0x74, + 0x97, 0x72, 0x91, 0x75, 0x8b, 0x59, 0x8b, 0x67, 0x67, 0x7c, 0x4a, 0x08, + 0xa8, 0x06, 0x96, 0xaa, 0x9c, 0x9a, 0xa2, 0x8b, 0x97, 0x8b, 0x99, 0x87, + 0x9a, 0x84, 0x08, 0xa2, 0x80, 0x05, 0xb4, 0x77, 0x9a, 0x87, 0xa4, 0x8b, + 0xc2, 0x8b, 0xa8, 0xa9, 0xa0, 0xd7, 0x08, 0x6e, 0x06, 0x0e, 0xf8, 0x0c, + 0xf9, 0x56, 0x9e, 0x15, 0x5e, 0x8e, 0x81, 0x95, 0x68, 0xd5, 0x08, 0xfb, + 0x8d, 0xf8, 0xcc, 0x77, 0x8b, 0xfb, 0x64, 0xfc, 0x7f, 0x05, 0x4b, 0xfb, + 0x26, 0x7f, 0x7b, 0x5b, 0x89, 0x08, 0x78, 0xf7, 0x5a, 0x9e, 0x07, 0x5b, + 0x77, 0x98, 0xa7, 0x1f, 0x8b, 0x97, 0x8e, 0x99, 0x90, 0x98, 0x08, 0xb9, + 0xf7, 0x09, 0xf7, 0x9a, 0x8b, 0xb4, 0x2b, 0x05, 0x97, 0x70, 0x92, 0x71, + 0x8b, 0x7d, 0x8b, 0x72, 0x7a, 0x83, 0x56, 0x8a, 0x08, 0x78, 0xf7, 0x93, + 0x9e, 0x07, 0xfc, 0x7e, 0xf7, 0x82, 0x15, 0xf7, 0x07, 0xf7, 0xa7, 0xf7, + 0x08, 0xfb, 0xa7, 0xfb, 0x7b, 0x8b, 0x05, 0xf7, 0x1b, 0xf9, 0x26, 0x15, + 0x55, 0x5e, 0x5e, 0x55, 0x53, 0xb6, 0x5f, 0xc3, 0xc2, 0xb8, 0xb7, 0xc2, + 0xc2, 0x5e, 0xb8, 0x54, 0x1f, 0x8c, 0x69, 0x15, 0xae, 0xa9, 0x6d, 0x67, + 0x67, 0x6d, 0x6e, 0x66, 0x68, 0x6e, 0xa9, 0xaf, 0xaf, 0xa9, 0xa8, 0xaf, + 0x1f, 0x0e, 0xf7, 0xd5, 0xf7, 0xe4, 0x7e, 0x15, 0x94, 0x8a, 0x92, 0x8b, + 0x93, 0x8b, 0xf7, 0x05, 0x8b, 0xef, 0xb9, 0xc7, 0xdc, 0x08, 0x79, 0x9d, + 0x05, 0x41, 0x44, 0x49, 0x6d, 0x38, 0x8b, 0x4c, 0x8b, 0x53, 0x9f, 0x60, + 0xb1, 0x54, 0xbc, 0x6c, 0xe5, 0x8b, 0xf7, 0x03, 0x8b, 0xf7, 0x49, 0xe8, + 0xf7, 0x09, 0xf7, 0x25, 0x8b, 0xc4, 0x8b, 0xbf, 0x76, 0xb3, 0x63, 0xab, + 0x6b, 0x9a, 0x6f, 0x9e, 0x4a, 0x08, 0xa2, 0x8b, 0x82, 0xf7, 0x76, 0x76, + 0x8b, 0x05, 0x85, 0x76, 0x7b, 0x7f, 0x77, 0x8b, 0x82, 0x8b, 0x7c, 0x8e, + 0x7c, 0x91, 0x5a, 0x9b, 0x59, 0x93, 0x5c, 0x8b, 0x39, 0x8b, 0x38, 0x6c, + 0x4d, 0x54, 0x45, 0x4d, 0x65, 0x2e, 0x8b, 0xfb, 0x02, 0x8b, 0xfb, 0x49, + 0xf6, 0xfb, 0x16, 0xf7, 0x3b, 0x73, 0x08, 0x66, 0x32, 0x92, 0x86, 0x05, + 0x93, 0x8e, 0x94, 0x8c, 0x96, 0x8b, 0x08, 0xb1, 0x9a, 0x81, 0x71, 0x70, + 0x76, 0x7a, 0x69, 0x1f, 0x76, 0x8b, 0x7b, 0x8e, 0x6f, 0x94, 0x08, 0x7d, + 0x6c, 0x05, 0xa8, 0x7f, 0xa2, 0x87, 0xab, 0x8b, 0x08, 0xd8, 0xbb, 0xab, + 0xbf, 0xb6, 0x6b, 0xa5, 0x55, 0x1f, 0x81, 0x8b, 0x85, 0x8a, 0x81, 0x89, + 0x08, 0x9f, 0xbf, 0x05, 0x0e, 0xf8, 0x0c, 0xf3, 0xf7, 0xcf, 0x15, 0xfb, + 0x62, 0x07, 0x8b, 0x43, 0x7f, 0x7e, 0x3f, 0x86, 0x08, 0x78, 0xf7, 0xb0, + 0x07, 0xf7, 0x08, 0x8b, 0xf4, 0xac, 0xc9, 0xc3, 0xcc, 0xc6, 0xb0, 0xe4, + 0x8b, 0xec, 0x8b, 0xe5, 0x6d, 0xd9, 0x54, 0xc2, 0x47, 0xd0, 0xfb, 0x01, + 0xaf, 0xfb, 0x1d, 0x8b, 0x08, 0xfb, 0xa2, 0x06, 0x78, 0x07, 0xda, 0x84, + 0x94, 0x82, 0x8b, 0x41, 0x08, 0xfb, 0x56, 0x38, 0x5f, 0x07, 0xde, 0x06, + 0xf7, 0x8c, 0xb7, 0x15, 0xfb, 0x26, 0xf7, 0x77, 0x06, 0xaa, 0x95, 0x93, + 0xb3, 0x1e, 0xe4, 0x8b, 0xcb, 0x7b, 0xbb, 0x69, 0xd9, 0x55, 0xb4, 0x35, + 0x8b, 0xfb, 0x00, 0x8b, 0xfb, 0x0a, 0x62, 0x37, 0x3a, 0x5c, 0x58, 0x6e, + 0x51, 0x7f, 0x34, 0x8b, 0x08, 0x63, 0x7f, 0x94, 0xab, 0x1f, 0xf7, 0x81, + 0xf7, 0x26, 0xb7, 0x07, 0x0e, 0xf7, 0x9d, 0xf8, 0xe9, 0xf7, 0x3d, 0x15, + 0x6f, 0x06, 0x59, 0xfb, 0x00, 0x60, 0x73, 0xfb, 0x23, 0x8b, 0x08, 0x70, + 0x06, 0x5a, 0x8b, 0x61, 0x90, 0x84, 0x92, 0x86, 0x8e, 0x89, 0x96, 0x8b, + 0x9c, 0x08, 0xf7, 0x8b, 0xf7, 0x2e, 0x07, 0xdd, 0x8b, 0x9a, 0x7e, 0x98, + 0x38, 0x08, 0xa2, 0xf7, 0x7c, 0x74, 0x06, 0x84, 0x62, 0x87, 0x7c, 0x80, + 0x7d, 0x7e, 0x7a, 0x6f, 0x83, 0x5c, 0x8b, 0x08, 0xfb, 0x2e, 0xf7, 0x72, + 0x06, 0xa7, 0x91, 0x91, 0xa6, 0x1e, 0xf7, 0x1b, 0x06, 0xf7, 0x05, 0x8b, + 0xa1, 0x7c, 0x9c, 0x31, 0x08, 0xa4, 0x8b, 0x88, 0xf7, 0x23, 0xfc, 0xa7, + 0x8b, 0x05, 0x78, 0x07, 0xd5, 0x85, 0x98, 0x7d, 0x8b, 0x45, 0x08, 0xfc, + 0x50, 0x07, 0x8b, 0x45, 0x7d, 0x7c, 0x42, 0x86, 0x08, 0x78, 0xf8, 0xb0, + 0x07, 0xb8, 0xf7, 0x3d, 0x05, 0xfc, 0x1c, 0xf9, 0x2d, 0x15, 0x72, 0x74, + 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, + 0xa2, 0x6f, 0x1f, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, + 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, + 0xf7, 0x9d, 0xf8, 0xe9, 0xf7, 0x3d, 0x15, 0x6f, 0x06, 0x59, 0xfb, 0x00, + 0x60, 0x73, 0xfb, 0x23, 0x8b, 0x08, 0x70, 0x06, 0x5a, 0x8b, 0x61, 0x90, + 0x84, 0x92, 0x86, 0x8e, 0x89, 0x96, 0x8b, 0x9c, 0x08, 0xf7, 0x8b, 0xf7, + 0x2e, 0x07, 0xdd, 0x8b, 0x9a, 0x7e, 0x98, 0x38, 0x08, 0xa2, 0xf7, 0x7c, + 0x74, 0x06, 0x84, 0x62, 0x87, 0x7c, 0x80, 0x7d, 0x7e, 0x7a, 0x6f, 0x83, + 0x5c, 0x8b, 0x08, 0xfb, 0x2e, 0xf7, 0x72, 0x06, 0xa7, 0x91, 0x91, 0xa6, + 0x1e, 0xf7, 0x1b, 0x06, 0xf7, 0x05, 0x8b, 0xa1, 0x7c, 0x9c, 0x31, 0x08, + 0xa4, 0x8b, 0x88, 0xf7, 0x23, 0xfc, 0xa7, 0x8b, 0x05, 0x78, 0x07, 0xd5, + 0x85, 0x98, 0x7d, 0x8b, 0x45, 0x08, 0xfc, 0x50, 0x07, 0x8b, 0x45, 0x7d, + 0x7c, 0x42, 0x86, 0x08, 0x78, 0xf8, 0xb0, 0x07, 0xb8, 0xf7, 0x3d, 0x05, + 0xfb, 0xd8, 0xf8, 0xba, 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, + 0x98, 0x8b, 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x81, + 0x86, 0x7a, 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, + 0xf7, 0x9d, 0xf8, 0xe9, 0xf7, 0x3d, 0x15, 0x6f, 0x06, 0x59, 0xfb, 0x00, + 0x60, 0x73, 0xfb, 0x23, 0x8b, 0x08, 0x70, 0x06, 0x5a, 0x8b, 0x61, 0x90, + 0x84, 0x92, 0x86, 0x8e, 0x89, 0x96, 0x8b, 0x9c, 0x08, 0xf7, 0x8b, 0xf7, + 0x2e, 0x07, 0xdd, 0x8b, 0x9a, 0x7e, 0x98, 0x38, 0x08, 0xa2, 0xf7, 0x7c, + 0x74, 0x06, 0x84, 0x62, 0x87, 0x7c, 0x80, 0x7d, 0x7e, 0x7a, 0x6f, 0x83, + 0x5c, 0x8b, 0x08, 0xfb, 0x2e, 0xf7, 0x72, 0x06, 0xa7, 0x91, 0x91, 0xa6, + 0x1e, 0xf7, 0x1b, 0x06, 0xf7, 0x05, 0x8b, 0xa1, 0x7c, 0x9c, 0x31, 0x08, + 0xa4, 0x8b, 0x88, 0xf7, 0x23, 0xfc, 0xa7, 0x8b, 0x05, 0x78, 0x07, 0xd5, + 0x85, 0x98, 0x7d, 0x8b, 0x45, 0x08, 0xfc, 0x50, 0x07, 0x8b, 0x45, 0x7d, + 0x7c, 0x42, 0x86, 0x08, 0x78, 0xf8, 0xb0, 0x07, 0xb8, 0xf7, 0x3d, 0x05, + 0xfb, 0x6b, 0xf8, 0xba, 0x15, 0xfb, 0x27, 0xf7, 0x28, 0x05, 0x79, 0x9d, + 0x81, 0x90, 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, 0x78, 0x8b, 0x7b, + 0x96, 0x7c, 0x9e, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, 0x05, 0x0e, + 0xf7, 0x9d, 0xf8, 0xe9, 0xf7, 0x3d, 0x15, 0x6f, 0x06, 0x59, 0xfb, 0x00, + 0x60, 0x73, 0xfb, 0x23, 0x8b, 0x08, 0x70, 0x06, 0x5a, 0x8b, 0x61, 0x90, + 0x84, 0x92, 0x86, 0x8e, 0x89, 0x96, 0x8b, 0x9c, 0x08, 0xf7, 0x8b, 0xf7, + 0x2e, 0x07, 0xdd, 0x8b, 0x9a, 0x7e, 0x98, 0x38, 0x08, 0xa2, 0xf7, 0x7c, + 0x74, 0x06, 0x84, 0x62, 0x87, 0x7c, 0x80, 0x7d, 0x7e, 0x7a, 0x6f, 0x83, + 0x5c, 0x8b, 0x08, 0xfb, 0x2e, 0xf7, 0x72, 0x06, 0xa7, 0x91, 0x91, 0xa6, + 0x1e, 0xf7, 0x1b, 0x06, 0xf7, 0x05, 0x8b, 0xa1, 0x7c, 0x9c, 0x31, 0x08, + 0xa4, 0x8b, 0x88, 0xf7, 0x23, 0xfc, 0xa7, 0x8b, 0x05, 0x78, 0x07, 0xd5, + 0x85, 0x98, 0x7d, 0x8b, 0x45, 0x08, 0xfc, 0x50, 0x07, 0x8b, 0x45, 0x7d, + 0x7c, 0x42, 0x86, 0x08, 0x78, 0xf8, 0xb0, 0x07, 0xb8, 0xf7, 0x3d, 0x05, + 0xfb, 0x1b, 0xf8, 0xba, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, + 0x10, 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, 0x24, 0xad, + 0x8b, 0x05, 0x0e, 0x7e, 0xf7, 0x07, 0xf7, 0x01, 0x15, 0x8b, 0x40, 0x7e, + 0x7f, 0x37, 0x88, 0x08, 0x78, 0xf7, 0xbd, 0x9e, 0x07, 0x39, 0x8e, 0x7b, + 0x99, 0x8b, 0xd4, 0x08, 0xf8, 0x50, 0x07, 0x8b, 0xd4, 0x99, 0x98, 0xdf, + 0x8f, 0x08, 0x9e, 0xfb, 0xbd, 0x78, 0x07, 0xe0, 0x86, 0x97, 0x80, 0x8b, + 0x41, 0x08, 0xfc, 0x50, 0x07, 0x5a, 0xf9, 0x69, 0x15, 0x72, 0x74, 0x74, + 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0x1f, 0xa6, 0x74, + 0xa2, 0x6f, 0x1e, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, + 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, + 0x7e, 0xf7, 0x07, 0xf7, 0x01, 0x15, 0x8b, 0x40, 0x7e, 0x7f, 0x37, 0x88, + 0x08, 0x78, 0xf7, 0xbd, 0x9e, 0x07, 0x39, 0x8e, 0x7b, 0x99, 0x8b, 0xd4, + 0x08, 0xf8, 0x50, 0x07, 0x8b, 0xd4, 0x99, 0x98, 0xdf, 0x8f, 0x08, 0x9e, + 0xfb, 0xbd, 0x78, 0x07, 0xe0, 0x86, 0x97, 0x80, 0x8b, 0x41, 0x08, 0xfc, + 0x50, 0x07, 0x9d, 0xf8, 0xf6, 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, + 0x94, 0x98, 0x8b, 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, + 0x82, 0x86, 0x79, 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, + 0x0e, 0x7e, 0xf7, 0x07, 0xf7, 0x01, 0x15, 0x8b, 0x40, 0x7e, 0x7f, 0x37, + 0x88, 0x08, 0x78, 0xf7, 0xbd, 0x9e, 0x07, 0x39, 0x8e, 0x7b, 0x99, 0x8b, + 0xd4, 0x08, 0xf8, 0x50, 0x07, 0x8b, 0xd4, 0x99, 0x98, 0xdf, 0x8f, 0x08, + 0x9e, 0xfb, 0xbd, 0x78, 0x07, 0xe0, 0x86, 0x97, 0x80, 0x8b, 0x41, 0x08, + 0xfc, 0x50, 0x07, 0xf7, 0x14, 0xf8, 0xf6, 0x15, 0xfb, 0x27, 0xf7, 0x28, + 0x05, 0x79, 0x9d, 0x81, 0x90, 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, + 0x78, 0x8b, 0x7b, 0x96, 0x7c, 0x9e, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, + 0x8b, 0x05, 0x0e, 0x7e, 0xf7, 0x07, 0xf7, 0x01, 0x15, 0x8b, 0x40, 0x7e, + 0x7f, 0x37, 0x88, 0x08, 0x78, 0xf7, 0xbd, 0x9e, 0x07, 0x39, 0x8e, 0x7b, + 0x99, 0x8b, 0xd4, 0x08, 0xf8, 0x50, 0x07, 0x8b, 0xd4, 0x99, 0x98, 0xdf, + 0x8f, 0x08, 0x9e, 0xfb, 0xbd, 0x78, 0x07, 0xe0, 0x86, 0x97, 0x80, 0x8b, + 0x41, 0x08, 0xfc, 0x50, 0x07, 0xf7, 0x63, 0xf8, 0xf6, 0x15, 0xfb, 0x11, + 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, 0x10, 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, + 0xf2, 0xf7, 0x0e, 0x24, 0xad, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf8, 0xf8, + 0x80, 0x15, 0xf8, 0xa2, 0x07, 0x8b, 0xc7, 0x95, 0xb0, 0x9e, 0x98, 0x99, + 0x95, 0x99, 0x8f, 0xb1, 0x8f, 0x08, 0x9e, 0xfb, 0x7f, 0x78, 0x07, 0xb1, + 0x88, 0x99, 0x87, 0x9a, 0x82, 0x9f, 0x7d, 0x94, 0x67, 0x8b, 0x4d, 0x08, + 0x8b, 0xfb, 0xe5, 0xfc, 0x15, 0xf8, 0x78, 0xfb, 0x3f, 0x8b, 0x8b, 0x78, + 0x05, 0xb6, 0x8b, 0x99, 0x83, 0xb3, 0x5c, 0x08, 0xfc, 0x4d, 0x07, 0x8b, + 0x24, 0x7d, 0x78, 0x38, 0x85, 0x08, 0x78, 0xf7, 0x7f, 0x9e, 0x07, 0x3e, + 0x8f, 0x7a, 0xa2, 0x8b, 0xf0, 0x08, 0x8b, 0xf8, 0x1c, 0x05, 0xf8, 0x4e, + 0xfc, 0xba, 0x05, 0x9c, 0x06, 0xfb, 0x07, 0xf9, 0xf1, 0x15, 0x7a, 0x65, + 0x7e, 0x7f, 0x74, 0x8b, 0x7c, 0x8b, 0x78, 0x91, 0x78, 0x94, 0x08, 0x73, + 0x97, 0x05, 0x74, 0x97, 0x72, 0x91, 0x75, 0x8b, 0x59, 0x8b, 0x67, 0x67, + 0x7c, 0x4a, 0x08, 0xa8, 0x06, 0x96, 0xaa, 0x9c, 0x9a, 0xa2, 0x8b, 0x97, + 0x8b, 0x99, 0x87, 0x9a, 0x84, 0x08, 0xa2, 0x80, 0x05, 0xb4, 0x77, 0x9a, + 0x87, 0xa4, 0x8b, 0xc2, 0x8b, 0xa8, 0xa9, 0xa0, 0xd7, 0x08, 0x6e, 0x06, + 0x0e, 0xf8, 0x0c, 0xf7, 0xfd, 0xf9, 0x38, 0x15, 0xfb, 0x53, 0xfb, 0x1c, + 0xfb, 0x24, 0xfb, 0x5d, 0x1f, 0x8b, 0x2d, 0xab, 0x30, 0xc1, 0x51, 0xc5, + 0x4c, 0xe4, 0x64, 0xe3, 0x8b, 0xf7, 0x59, 0x8b, 0xf7, 0x1c, 0xf7, 0x20, + 0x8b, 0xf7, 0x5d, 0x8b, 0xee, 0x6e, 0xe0, 0x54, 0xc7, 0x4c, 0xd0, 0x37, + 0xaf, 0x2b, 0x8b, 0x08, 0x67, 0x04, 0xb9, 0x8b, 0xb9, 0x79, 0xaf, 0x6b, + 0xc1, 0x5a, 0xaa, 0x2d, 0x8b, 0xfb, 0x0b, 0x8b, 0x50, 0x7e, 0x46, 0x77, + 0x57, 0x82, 0x72, 0x7a, 0x72, 0x74, 0x74, 0x68, 0x68, 0x5e, 0x79, 0x56, + 0x8b, 0x5d, 0x8b, 0x5e, 0x9d, 0x68, 0xaa, 0x08, 0x57, 0xb9, 0x6a, 0xf0, + 0x8b, 0xf7, 0x03, 0x8b, 0xf1, 0xa7, 0xec, 0xb5, 0xba, 0xb2, 0xb6, 0xbc, + 0xa1, 0xc2, 0x8b, 0x08, 0x27, 0xf7, 0x56, 0x15, 0x72, 0x74, 0x74, 0x71, + 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, + 0x1f, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, + 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0xf8, 0x0c, + 0xf7, 0xfd, 0xf9, 0x38, 0x15, 0xfb, 0x53, 0xfb, 0x1c, 0xfb, 0x24, 0xfb, + 0x5d, 0x1f, 0x8b, 0x2d, 0xab, 0x30, 0xc1, 0x51, 0xc5, 0x4c, 0xe4, 0x64, + 0xe3, 0x8b, 0xf7, 0x59, 0x8b, 0xf7, 0x1c, 0xf7, 0x20, 0x8b, 0xf7, 0x5d, + 0x8b, 0xee, 0x6e, 0xe0, 0x54, 0xc7, 0x4c, 0xd0, 0x37, 0xaf, 0x2b, 0x8b, + 0x08, 0x67, 0x04, 0xb9, 0x8b, 0xb9, 0x79, 0xaf, 0x6b, 0xc1, 0x5a, 0xaa, + 0x2d, 0x8b, 0xfb, 0x0b, 0x8b, 0x50, 0x7e, 0x46, 0x77, 0x57, 0x82, 0x72, + 0x7a, 0x72, 0x74, 0x74, 0x68, 0x68, 0x5e, 0x79, 0x56, 0x8b, 0x5d, 0x8b, + 0x5e, 0x9d, 0x68, 0xaa, 0x08, 0x57, 0xb9, 0x6a, 0xf0, 0x8b, 0xf7, 0x03, + 0x8b, 0xf1, 0xa7, 0xec, 0xb5, 0xba, 0xb2, 0xb6, 0xbc, 0xa1, 0xc2, 0x8b, + 0x08, 0x6a, 0xda, 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, + 0x8b, 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x82, 0x86, + 0x79, 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xf8, + 0x0c, 0xf7, 0xfd, 0xf9, 0x38, 0x15, 0xfb, 0x53, 0xfb, 0x1c, 0xfb, 0x24, + 0xfb, 0x5d, 0x1f, 0x8b, 0x2d, 0xab, 0x30, 0xc1, 0x51, 0xc5, 0x4c, 0xe4, + 0x64, 0xe3, 0x8b, 0xf7, 0x59, 0x8b, 0xf7, 0x1c, 0xf7, 0x20, 0x8b, 0xf7, + 0x5d, 0x8b, 0xee, 0x6e, 0xe0, 0x54, 0xc7, 0x4c, 0xd0, 0x37, 0xaf, 0x2b, + 0x8b, 0x08, 0x67, 0x04, 0xb9, 0x8b, 0xb9, 0x79, 0xaf, 0x6b, 0xc1, 0x5a, + 0xaa, 0x2d, 0x8b, 0xfb, 0x0b, 0x8b, 0x50, 0x7e, 0x46, 0x77, 0x57, 0x82, + 0x72, 0x7a, 0x72, 0x74, 0x74, 0x68, 0x68, 0x5e, 0x79, 0x56, 0x8b, 0x5d, + 0x8b, 0x5e, 0x9d, 0x68, 0xaa, 0x08, 0x57, 0xb9, 0x6a, 0xf0, 0x8b, 0xf7, + 0x03, 0x8b, 0xf1, 0xa7, 0xec, 0xb5, 0xba, 0xb2, 0xb6, 0xbc, 0xa1, 0xc2, + 0x8b, 0x08, 0xd7, 0xda, 0x15, 0xfb, 0x27, 0xf7, 0x28, 0x05, 0x79, 0x9d, + 0x82, 0x90, 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, 0x78, 0x8b, 0x7b, + 0x96, 0x7c, 0x9d, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, 0x05, 0x0e, + 0xf8, 0x0c, 0xf7, 0xfd, 0xf9, 0x38, 0x15, 0xfb, 0x53, 0xfb, 0x1c, 0xfb, + 0x24, 0xfb, 0x5d, 0x1f, 0x8b, 0x2d, 0xab, 0x30, 0xc1, 0x51, 0xc5, 0x4c, + 0xe4, 0x64, 0xe3, 0x8b, 0xf7, 0x59, 0x8b, 0xf7, 0x1c, 0xf7, 0x20, 0x8b, + 0xf7, 0x5d, 0x8b, 0xee, 0x6e, 0xe0, 0x54, 0xc7, 0x4c, 0xd0, 0x37, 0xaf, + 0x2b, 0x8b, 0x08, 0x67, 0x04, 0xb9, 0x8b, 0xb9, 0x79, 0xaf, 0x6b, 0xc1, + 0x5a, 0xaa, 0x2d, 0x8b, 0xfb, 0x0b, 0x8b, 0x50, 0x7e, 0x46, 0x77, 0x57, + 0x82, 0x72, 0x7a, 0x72, 0x74, 0x74, 0x68, 0x68, 0x5e, 0x79, 0x56, 0x8b, + 0x5d, 0x8b, 0x5e, 0x9d, 0x68, 0xaa, 0x08, 0x57, 0xb9, 0x6a, 0xf0, 0x8b, + 0xf7, 0x03, 0x8b, 0xf1, 0xa7, 0xec, 0xb5, 0xba, 0xb2, 0xb6, 0xbc, 0xa1, + 0xc2, 0x8b, 0x08, 0xf7, 0x30, 0xda, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, + 0x8b, 0xfb, 0x10, 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, + 0x24, 0xad, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf7, 0xfd, 0xf9, 0x38, 0x15, + 0xfb, 0x53, 0xfb, 0x1c, 0xfb, 0x24, 0xfb, 0x5d, 0x1f, 0x8b, 0x2d, 0xab, + 0x30, 0xc1, 0x51, 0xc5, 0x4c, 0xe4, 0x64, 0xe3, 0x8b, 0xf7, 0x59, 0x8b, + 0xf7, 0x1c, 0xf7, 0x20, 0x8b, 0xf7, 0x5d, 0x8b, 0xee, 0x6e, 0xe0, 0x54, + 0xc7, 0x08, 0x4c, 0xd0, 0x37, 0xaf, 0x2b, 0x8b, 0x08, 0x67, 0x04, 0xb9, + 0x8b, 0xb9, 0x79, 0xaf, 0x6b, 0xc1, 0x5a, 0xaa, 0x2d, 0x8b, 0xfb, 0x0b, + 0x8b, 0x50, 0x7e, 0x46, 0x77, 0x57, 0x82, 0x72, 0x7a, 0x72, 0x74, 0x74, + 0x68, 0x68, 0x5e, 0x79, 0x56, 0x8b, 0x5d, 0x8b, 0x5e, 0x9d, 0x68, 0xaa, + 0x08, 0x57, 0xb9, 0x6a, 0xf0, 0x8b, 0xf7, 0x03, 0x8b, 0xf1, 0xa7, 0xec, + 0xb5, 0xba, 0xb2, 0xb6, 0xbc, 0xa1, 0xc2, 0x8b, 0x08, 0xf7, 0x1c, 0xf7, + 0x66, 0x15, 0x7a, 0x65, 0x7e, 0x7f, 0x74, 0x8b, 0x7c, 0x8b, 0x78, 0x91, + 0x78, 0x94, 0x08, 0x73, 0x97, 0x05, 0x74, 0x97, 0x72, 0x91, 0x75, 0x8b, + 0x59, 0x8b, 0x67, 0x67, 0x7c, 0x4a, 0x08, 0xa8, 0x06, 0x96, 0xaa, 0x9c, + 0x9a, 0xa2, 0x8b, 0x97, 0x8b, 0x99, 0x87, 0x9a, 0x84, 0x08, 0xa2, 0x80, + 0x05, 0xb4, 0x77, 0x9a, 0x87, 0xa4, 0x8b, 0xc2, 0x8b, 0xa8, 0xa9, 0xa0, + 0xd7, 0x08, 0x6e, 0x06, 0x0e, 0xf7, 0x66, 0xf8, 0x53, 0xf9, 0x38, 0x15, + 0x76, 0x06, 0x87, 0x74, 0x80, 0x80, 0x7a, 0x8b, 0x81, 0x8b, 0x7a, 0x8f, + 0x7a, 0x93, 0x08, 0x66, 0x99, 0x66, 0x93, 0x6b, 0x8b, 0x60, 0x8b, 0x5f, + 0x7a, 0x6a, 0x6e, 0x68, 0x6c, 0x79, 0x61, 0x8b, 0x57, 0x8b, 0x3b, 0xb7, + 0x53, 0xf7, 0x04, 0x50, 0xd3, 0x65, 0xbf, 0x62, 0xa4, 0x65, 0x94, 0x7e, + 0x90, 0x76, 0x8b, 0x73, 0x08, 0x48, 0x59, 0x5d, 0x42, 0x1e, 0x32, 0x8b, + 0x4c, 0xc2, 0x59, 0xf7, 0x0e, 0x08, 0x74, 0x8b, 0xa9, 0xfb, 0x68, 0xa1, + 0x8b, 0x05, 0x8c, 0x9e, 0x97, 0x99, 0x9a, 0x8b, 0x96, 0x8b, 0x9c, 0x87, + 0x9e, 0x84, 0x08, 0xb1, 0x7c, 0xb3, 0x83, 0xb3, 0x8b, 0xf7, 0x07, 0x8b, + 0xe4, 0xda, 0x8b, 0xf2, 0x8b, 0xdd, 0x54, 0xcc, 0xfb, 0x18, 0xd2, 0x22, + 0xc5, 0x61, 0xb7, 0x8b, 0xc1, 0x8b, 0xc2, 0xb5, 0xb1, 0xc9, 0x8b, 0xb8, + 0x8b, 0xb5, 0x78, 0xae, 0x67, 0x08, 0xaa, 0x6b, 0x99, 0x71, 0x9b, 0x50, + 0x08, 0xa4, 0x8b, 0x05, 0x75, 0xf7, 0x69, 0x05, 0x7e, 0xf7, 0x66, 0x15, + 0x69, 0x8b, 0xfb, 0x0e, 0x24, 0xfb, 0x0d, 0xf2, 0x69, 0x8b, 0xf7, 0x10, + 0xfb, 0x3b, 0xc9, 0x8b, 0xf7, 0x11, 0xf7, 0x3b, 0x05, 0x0e, 0xf8, 0x0c, + 0xf8, 0xf7, 0xf8, 0x97, 0x15, 0x8b, 0xf1, 0x97, 0x9b, 0xdd, 0x95, 0x08, + 0x9e, 0xfb, 0x7c, 0x78, 0x07, 0xd9, 0x85, 0x9b, 0x75, 0x8b, 0x27, 0x08, + 0xfb, 0xa2, 0x07, 0x8b, 0x47, 0x84, 0x65, 0x7b, 0x6d, 0x70, 0x5b, 0x4b, + 0x6c, 0x40, 0x8b, 0x44, 0x8b, 0x5a, 0xa3, 0x70, 0xba, 0x79, 0xab, 0x84, + 0xb0, 0x8b, 0xca, 0x08, 0xf7, 0xd4, 0x07, 0x8b, 0xd3, 0x96, 0x96, 0xdb, + 0x92, 0x08, 0x9e, 0xfb, 0xaf, 0x78, 0x07, 0xda, 0x85, 0x96, 0x80, 0x8b, + 0x42, 0x08, 0xfb, 0xcc, 0x07, 0xfb, 0x41, 0xdc, 0x39, 0xf7, 0x3e, 0x1e, + 0xf7, 0x01, 0x8b, 0xd6, 0xae, 0xb2, 0xcf, 0xa3, 0xb5, 0x94, 0xb9, 0x8b, + 0xd8, 0x08, 0xf7, 0x99, 0x07, 0xfb, 0xe1, 0xf7, 0xd3, 0x15, 0x72, 0x74, + 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, + 0xa2, 0x6f, 0x1f, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, + 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, + 0xf8, 0x0c, 0xf8, 0xf7, 0xf8, 0x97, 0x15, 0x8b, 0xf1, 0x97, 0x9b, 0xdd, + 0x95, 0x08, 0x9e, 0xfb, 0x7c, 0x78, 0x07, 0xd9, 0x85, 0x9b, 0x75, 0x8b, + 0x27, 0x08, 0xfb, 0xa2, 0x07, 0x8b, 0x47, 0x84, 0x65, 0x7b, 0x6d, 0x70, + 0x5b, 0x4b, 0x6c, 0x40, 0x8b, 0x44, 0x8b, 0x5a, 0xa3, 0x70, 0xba, 0x79, + 0xab, 0x84, 0xb0, 0x8b, 0xca, 0x08, 0xf7, 0xd4, 0x07, 0x8b, 0xd3, 0x96, + 0x96, 0xdb, 0x92, 0x08, 0x9e, 0xfb, 0xaf, 0x78, 0x07, 0xda, 0x85, 0x96, + 0x80, 0x8b, 0x42, 0x08, 0xfb, 0xcc, 0x07, 0xfb, 0x41, 0xdc, 0x39, 0xf7, + 0x3e, 0x1e, 0xf7, 0x01, 0x8b, 0xd6, 0xae, 0xb2, 0xcf, 0xa3, 0xb5, 0x94, + 0xb9, 0x8b, 0xd8, 0x08, 0xf7, 0x99, 0x07, 0xfb, 0x96, 0xf7, 0x60, 0x15, + 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, 0x8b, 0x9f, + 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x81, 0x86, 0x7a, 0x79, 0x08, 0xfb, + 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf8, 0xf7, 0xf8, + 0x97, 0x15, 0x8b, 0xf1, 0x97, 0x9b, 0xdd, 0x95, 0x08, 0x9e, 0xfb, 0x7c, + 0x78, 0x07, 0xd9, 0x85, 0x9b, 0x75, 0x8b, 0x27, 0x08, 0xfb, 0xa2, 0x07, + 0x8b, 0x47, 0x84, 0x65, 0x7b, 0x6d, 0x70, 0x5b, 0x4b, 0x6c, 0x40, 0x8b, + 0x44, 0x8b, 0x5a, 0xa3, 0x70, 0xba, 0x79, 0xab, 0x84, 0xb0, 0x8b, 0xca, + 0x08, 0xf7, 0xd4, 0x07, 0x8b, 0xd3, 0x96, 0x96, 0xdb, 0x92, 0x08, 0x9e, + 0xfb, 0xaf, 0x78, 0x07, 0xda, 0x85, 0x96, 0x80, 0x8b, 0x42, 0x08, 0xfb, + 0xcc, 0x07, 0xfb, 0x41, 0xdc, 0x39, 0xf7, 0x3e, 0x1e, 0xf7, 0x01, 0x8b, + 0xd6, 0xae, 0xb2, 0xcf, 0xa3, 0xb5, 0x94, 0xb9, 0x8b, 0xd8, 0x08, 0xf7, + 0x99, 0x07, 0xfb, 0x30, 0xf7, 0x60, 0x15, 0xfb, 0x27, 0xf7, 0x28, 0x05, + 0x79, 0x9d, 0x81, 0x90, 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, 0x78, + 0x8b, 0x7b, 0x96, 0x7c, 0x9e, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, + 0x05, 0x0e, 0xf8, 0x0c, 0xf8, 0xf7, 0xf8, 0x97, 0x15, 0x8b, 0xf1, 0x97, + 0x9b, 0xdd, 0x95, 0x08, 0x9e, 0xfb, 0x7c, 0x78, 0x07, 0xd9, 0x85, 0x9b, + 0x75, 0x8b, 0x27, 0x08, 0xfb, 0xa2, 0x07, 0x8b, 0x47, 0x84, 0x65, 0x7b, + 0x6d, 0x70, 0x5b, 0x4b, 0x6c, 0x40, 0x8b, 0x44, 0x8b, 0x5a, 0xa3, 0x70, + 0xba, 0x79, 0xab, 0x84, 0xb0, 0x8b, 0xca, 0x08, 0xf7, 0xd4, 0x07, 0x8b, + 0xd3, 0x96, 0x96, 0xdb, 0x92, 0x08, 0x9e, 0xfb, 0xaf, 0x78, 0x07, 0xda, + 0x85, 0x96, 0x80, 0x8b, 0x42, 0x08, 0xfb, 0xcc, 0x07, 0xfb, 0x41, 0xdc, + 0x39, 0xf7, 0x3e, 0x1e, 0xf7, 0x01, 0x8b, 0xd6, 0xae, 0xb2, 0xcf, 0xa3, + 0xb5, 0x94, 0xb9, 0x8b, 0xd8, 0x08, 0xf7, 0x99, 0x07, 0x40, 0xf7, 0x60, + 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, 0x10, 0xfb, 0x3b, 0xad, + 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, 0x24, 0xad, 0x8b, 0x05, 0x0e, 0xf8, + 0x0c, 0xf9, 0x53, 0xf9, 0x2a, 0x15, 0xfb, 0x6f, 0x78, 0x06, 0xbf, 0x8a, + 0x9c, 0x83, 0x8b, 0x73, 0x8b, 0x81, 0x86, 0x7f, 0x82, 0x7c, 0x08, 0xfb, + 0x23, 0xfb, 0x76, 0xfb, 0x28, 0xf7, 0x72, 0x05, 0x80, 0x9b, 0x85, 0x9c, + 0x8b, 0x96, 0x8b, 0x9d, 0x99, 0x94, 0xab, 0x8d, 0x8f, 0x8b, 0x95, 0x8b, + 0x96, 0x8c, 0x08, 0x9e, 0xfb, 0xac, 0x78, 0x07, 0xbb, 0x89, 0x99, 0x7d, + 0xef, 0xfb, 0x21, 0x08, 0xf7, 0x17, 0xfb, 0x54, 0x8b, 0xfb, 0x42, 0x05, + 0x8b, 0x34, 0x81, 0x81, 0x30, 0x87, 0x08, 0x78, 0xf7, 0xc6, 0x9e, 0x07, + 0x32, 0x8d, 0x7d, 0x97, 0x8b, 0xd7, 0x08, 0x8b, 0xf7, 0x56, 0xf7, 0x28, + 0xf7, 0x76, 0x05, 0xc8, 0xe3, 0xa5, 0xa1, 0xbe, 0x8f, 0x08, 0x9e, 0x07, + 0xfb, 0xeb, 0xc4, 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, + 0x8b, 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x81, 0x86, + 0x7a, 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xf7, + 0x9d, 0xf8, 0xd2, 0xf7, 0x44, 0x15, 0x7a, 0x53, 0x81, 0x76, 0x77, 0x75, + 0x73, 0x72, 0x5f, 0x7d, 0x52, 0x8b, 0x08, 0xfb, 0x95, 0x8b, 0xf8, 0x44, + 0xf8, 0xf5, 0x8b, 0x9a, 0xfc, 0xa2, 0x8b, 0x77, 0xfb, 0x3f, 0xa5, 0x8b, + 0x05, 0x94, 0xbc, 0x93, 0x9f, 0x9c, 0xa0, 0xa2, 0xa8, 0xb8, 0x99, 0xcd, + 0x8b, 0x08, 0xf7, 0x71, 0x8b, 0xfc, 0x49, 0xfc, 0xf5, 0x8b, 0x7c, 0xf8, + 0xc8, 0x8b, 0xa3, 0xf7, 0x44, 0x74, 0x8b, 0x05, 0xfb, 0x04, 0xf9, 0x5a, + 0x15, 0x69, 0x8b, 0xfb, 0x0e, 0x24, 0xfb, 0x0d, 0xf2, 0x69, 0x8b, 0xf7, + 0x10, 0xfb, 0x3b, 0xc9, 0x8b, 0xf7, 0x11, 0xf7, 0x3b, 0x05, 0x0e, 0xf7, + 0x66, 0xf7, 0xb9, 0xf9, 0x2a, 0x15, 0xfb, 0xa9, 0x78, 0x06, 0xd5, 0x83, + 0x95, 0x81, 0x8b, 0x43, 0x08, 0xfc, 0x45, 0x07, 0x8b, 0x37, 0x83, 0x81, + 0x3f, 0x84, 0x08, 0x78, 0xf7, 0xac, 0x9e, 0x07, 0x3c, 0x8e, 0x7c, 0x99, + 0x8b, 0xd4, 0x08, 0xbf, 0x07, 0xa6, 0x89, 0x9d, 0x8a, 0xa3, 0x8b, 0xd9, + 0x8b, 0xc1, 0x95, 0xb6, 0xa3, 0xc6, 0xab, 0xb0, 0xc8, 0x8b, 0xcd, 0x08, + 0xf7, 0x03, 0x27, 0xd1, 0xfb, 0x34, 0x1e, 0x3b, 0x06, 0x8a, 0xe6, 0x95, + 0x98, 0xdd, 0x92, 0x08, 0x9e, 0x07, 0x30, 0xfb, 0x5d, 0x15, 0xa5, 0x92, + 0x92, 0xa4, 0xf7, 0x1e, 0xc8, 0x5d, 0x24, 0x2a, 0x50, 0x59, 0xfb, 0x07, + 0x1e, 0x77, 0x8b, 0x7d, 0x8c, 0x74, 0x8d, 0x08, 0xf7, 0x98, 0x07, 0x0e, + 0xf8, 0x0c, 0xf9, 0x53, 0xf9, 0x2a, 0x15, 0xfb, 0x6f, 0x78, 0x06, 0xbf, + 0x8a, 0x9c, 0x83, 0x8b, 0x73, 0x8b, 0x81, 0x86, 0x7f, 0x82, 0x7c, 0x08, + 0xfb, 0x23, 0xfb, 0x76, 0xfb, 0x28, 0xf7, 0x72, 0x05, 0x80, 0x9b, 0x85, + 0x9c, 0x8b, 0x96, 0x8b, 0x9d, 0x99, 0x94, 0xab, 0x8d, 0x8f, 0x8b, 0x95, + 0x8b, 0x96, 0x8c, 0x08, 0x9e, 0xfb, 0xac, 0x78, 0x07, 0xbb, 0x89, 0x99, + 0x7d, 0xef, 0xfb, 0x21, 0x08, 0xf7, 0x17, 0xfb, 0x54, 0x8b, 0xfb, 0x42, + 0x05, 0x8b, 0x34, 0x81, 0x81, 0x30, 0x87, 0x08, 0x78, 0xf7, 0xc6, 0x9e, + 0x07, 0x32, 0x8d, 0x7d, 0x97, 0x8b, 0xd7, 0x08, 0x8b, 0xf7, 0x56, 0xf7, + 0x28, 0xf7, 0x76, 0x05, 0xc8, 0xe3, 0xa5, 0xa1, 0xbe, 0x8f, 0x08, 0x9e, + 0x07, 0xfc, 0x3e, 0xf7, 0x40, 0x15, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, + 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0x1f, 0xa6, 0x74, 0xa2, 0x6f, 0x1e, + 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, + 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0xed, 0xf8, 0x4e, + 0xcd, 0x15, 0x7a, 0x7d, 0x7f, 0x86, 0x7c, 0x8b, 0x08, 0x74, 0x84, 0x99, + 0xb7, 0x1f, 0xf7, 0x57, 0x07, 0x8b, 0xbf, 0x86, 0xa8, 0x7c, 0xa3, 0x75, + 0xaf, 0x60, 0x9e, 0x50, 0x8b, 0x08, 0x2d, 0x41, 0x5a, 0x4c, 0x74, 0x9f, + 0x77, 0xa2, 0xa3, 0xa0, 0x9f, 0xa1, 0x1f, 0x8b, 0x8f, 0x8a, 0x90, 0x8a, + 0x92, 0x89, 0x94, 0x8a, 0x93, 0x8b, 0x92, 0x08, 0xa6, 0xab, 0xa1, 0xb3, + 0xbc, 0xa6, 0x6e, 0x55, 0x1e, 0x4e, 0x07, 0xfb, 0x2e, 0x4d, 0x7a, 0x83, + 0x60, 0x65, 0x75, 0x77, 0x7d, 0x69, 0x8b, 0x6a, 0x08, 0x4c, 0xb7, 0x5f, + 0xc8, 0x1e, 0xb7, 0x8b, 0xb4, 0xa0, 0xc8, 0xbf, 0x08, 0x90, 0x57, 0x9d, + 0x76, 0xb4, 0x8b, 0xad, 0x8b, 0xa0, 0x97, 0xae, 0xb1, 0x08, 0xa5, 0x07, + 0xfb, 0x2f, 0xc4, 0x15, 0x8b, 0x6c, 0x86, 0x82, 0x76, 0x7f, 0x08, 0x73, + 0x7d, 0x6f, 0x82, 0x76, 0x8b, 0x08, 0x68, 0x6f, 0xad, 0xb6, 0x1f, 0x8f, + 0x07, 0x8b, 0xc6, 0xb4, 0xaf, 0xf7, 0x0d, 0xb7, 0x08, 0xfb, 0x25, 0x07, + 0xfb, 0x3a, 0xf8, 0x87, 0x15, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, + 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0xf7, 0x5b, + 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, + 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0xed, 0xf8, 0x4e, 0xcd, 0x15, + 0x7a, 0x7d, 0x7f, 0x86, 0x7c, 0x8b, 0x08, 0x74, 0x84, 0x99, 0xb7, 0x1f, + 0xf7, 0x57, 0x07, 0x8b, 0xbf, 0x86, 0xa8, 0x7c, 0xa3, 0x75, 0xaf, 0x60, + 0x9e, 0x50, 0x8b, 0x08, 0x2d, 0x41, 0x5a, 0x4c, 0x74, 0x9f, 0x77, 0xa2, + 0xa3, 0xa0, 0x9f, 0xa1, 0x1f, 0x8b, 0x8f, 0x8a, 0x90, 0x8a, 0x92, 0x89, + 0x94, 0x8a, 0x93, 0x8b, 0x92, 0x08, 0xa6, 0xab, 0xa1, 0xb3, 0xbc, 0xa6, + 0x6e, 0x55, 0x1e, 0x4e, 0x07, 0xfb, 0x2e, 0x4d, 0x7a, 0x83, 0x60, 0x65, + 0x75, 0x77, 0x7d, 0x69, 0x8b, 0x6a, 0x08, 0x4c, 0xb7, 0x5f, 0xc8, 0x1e, + 0xb7, 0x8b, 0xb4, 0xa0, 0xc8, 0xbf, 0x08, 0x90, 0x57, 0x9d, 0x76, 0xb4, + 0x8b, 0xad, 0x8b, 0xa0, 0x97, 0xae, 0xb1, 0x08, 0xa5, 0x07, 0xfb, 0x2f, + 0xc4, 0x15, 0x8b, 0x6c, 0x86, 0x82, 0x76, 0x7f, 0x73, 0x7d, 0x6f, 0x82, + 0x76, 0x8b, 0x08, 0x68, 0x6f, 0xad, 0xb6, 0x1f, 0x8f, 0x07, 0x8b, 0xc6, + 0xb4, 0xaf, 0xf7, 0x0d, 0xb7, 0x08, 0xfb, 0x25, 0x07, 0x29, 0xf8, 0x14, + 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, 0x8b, + 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x81, 0x86, 0x7a, 0x79, 0x08, + 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xed, 0xf8, 0x4e, 0xcd, + 0x15, 0x7a, 0x7d, 0x7f, 0x86, 0x7c, 0x8b, 0x08, 0x74, 0x84, 0x99, 0xb7, + 0x1f, 0xf7, 0x57, 0x07, 0x8b, 0xbf, 0x86, 0xa8, 0x7c, 0xa3, 0x75, 0xaf, + 0x60, 0x9e, 0x50, 0x8b, 0x08, 0x2d, 0x41, 0x5a, 0x4c, 0x74, 0x9f, 0x77, + 0xa2, 0xa3, 0xa0, 0x9f, 0xa1, 0x1f, 0x8b, 0x8f, 0x8a, 0x90, 0x8a, 0x92, + 0x89, 0x94, 0x8a, 0x93, 0x8b, 0x92, 0x08, 0xa6, 0xab, 0xa1, 0xb3, 0xbc, + 0xa6, 0x6e, 0x55, 0x1e, 0x4e, 0x07, 0xfb, 0x2e, 0x4d, 0x7a, 0x83, 0x60, + 0x65, 0x75, 0x77, 0x7d, 0x69, 0x8b, 0x6a, 0x08, 0x4c, 0xb7, 0x5f, 0xc8, + 0x1e, 0xb7, 0x8b, 0xb4, 0xa0, 0xc8, 0xbf, 0x08, 0x90, 0x57, 0x9d, 0x76, + 0xb4, 0x8b, 0xad, 0x8b, 0xa0, 0x97, 0xae, 0xb1, 0x08, 0xa5, 0x07, 0xfb, + 0x2f, 0xc4, 0x15, 0x8b, 0x6c, 0x86, 0x82, 0x76, 0x7f, 0x73, 0x7d, 0x6f, + 0x82, 0x76, 0x8b, 0x08, 0x68, 0x6f, 0xad, 0xb6, 0x1f, 0x8f, 0x07, 0x8b, + 0xc6, 0xb4, 0xaf, 0xf7, 0x0d, 0xb7, 0x08, 0xfb, 0x25, 0x07, 0x96, 0xf8, + 0x14, 0x15, 0xfb, 0x27, 0xf7, 0x28, 0x05, 0x79, 0x9d, 0x81, 0x90, 0x7c, + 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, 0x78, 0x8b, 0x7b, 0x96, 0x7c, 0x9e, + 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, 0x05, 0x0e, 0xed, 0xf8, 0x4e, + 0xcd, 0x15, 0x7a, 0x7d, 0x7f, 0x86, 0x7c, 0x8b, 0x08, 0x74, 0x84, 0x99, + 0xb7, 0x1f, 0xf7, 0x57, 0x07, 0x8b, 0xbf, 0x86, 0xa8, 0x7c, 0xa3, 0x75, + 0xaf, 0x60, 0x9e, 0x50, 0x8b, 0x08, 0x2d, 0x41, 0x5a, 0x4c, 0x74, 0x9f, + 0x77, 0xa2, 0xa3, 0xa0, 0x9f, 0xa1, 0x1f, 0x8b, 0x8f, 0x8a, 0x90, 0x8a, + 0x92, 0x89, 0x94, 0x8a, 0x93, 0x8b, 0x92, 0x08, 0xa6, 0xab, 0xa1, 0xb3, + 0xbc, 0xa6, 0x6e, 0x55, 0x1e, 0x4e, 0x07, 0xfb, 0x2e, 0x4d, 0x7a, 0x83, + 0x60, 0x65, 0x75, 0x77, 0x7d, 0x69, 0x8b, 0x6a, 0x08, 0x4c, 0xb7, 0x5f, + 0xc8, 0x1e, 0xb7, 0x8b, 0xb4, 0xa0, 0xc8, 0xbf, 0x08, 0x90, 0x57, 0x9d, + 0x76, 0xb4, 0x8b, 0xad, 0x8b, 0xa0, 0x97, 0xae, 0xb1, 0x08, 0xa5, 0x07, + 0xfb, 0x2f, 0xc4, 0x15, 0x8b, 0x6c, 0x86, 0x82, 0x76, 0x7f, 0x73, 0x7d, + 0x6f, 0x82, 0x76, 0x8b, 0x08, 0x68, 0x6f, 0xad, 0xb6, 0x1f, 0x8f, 0x07, + 0x8b, 0xc6, 0xb4, 0xaf, 0xf7, 0x0d, 0xb7, 0x08, 0xfb, 0x25, 0x07, 0xe6, + 0xf8, 0x14, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, 0x10, 0xfb, + 0x3b, 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, 0x24, 0xad, 0x8b, 0x05, + 0x0e, 0xed, 0xf8, 0x4e, 0xcd, 0x15, 0x7a, 0x7d, 0x7f, 0x86, 0x7c, 0x8b, + 0x08, 0x74, 0x84, 0x99, 0xb7, 0x1f, 0xf7, 0x57, 0x07, 0x8b, 0xbf, 0x86, + 0xa8, 0x7c, 0xa3, 0x75, 0xaf, 0x60, 0x9e, 0x50, 0x8b, 0x08, 0x2d, 0x41, + 0x5a, 0x4c, 0x74, 0x9f, 0x77, 0xa2, 0xa3, 0xa0, 0x9f, 0xa1, 0x1f, 0x8b, + 0x8f, 0x8a, 0x90, 0x8a, 0x92, 0x89, 0x94, 0x8a, 0x93, 0x8b, 0x92, 0x08, + 0xa6, 0xab, 0xa1, 0xb3, 0xbc, 0xa6, 0x6e, 0x55, 0x1e, 0x4e, 0x07, 0xfb, + 0x2e, 0x4d, 0x7a, 0x83, 0x60, 0x65, 0x75, 0x77, 0x7d, 0x69, 0x8b, 0x6a, + 0x08, 0x4c, 0xb7, 0x5f, 0xc8, 0x1e, 0xb7, 0x8b, 0xb4, 0xa0, 0xc8, 0xbf, + 0x08, 0x90, 0x57, 0x9d, 0x76, 0xb4, 0x8b, 0xad, 0x8b, 0xa0, 0x97, 0xae, + 0xb1, 0x08, 0xa5, 0x07, 0xfb, 0x2f, 0xc4, 0x15, 0x8b, 0x6c, 0x86, 0x82, + 0x76, 0x7f, 0x73, 0x7d, 0x6f, 0x82, 0x76, 0x8b, 0x08, 0x68, 0x6f, 0xad, + 0xb6, 0x1f, 0x8f, 0x07, 0x8b, 0xc6, 0xb4, 0xaf, 0xf7, 0x0d, 0xb7, 0x08, + 0xfb, 0x25, 0x07, 0xd2, 0xf8, 0x97, 0x15, 0x79, 0x65, 0x7e, 0x7f, 0x74, + 0x8b, 0x7d, 0x8b, 0x77, 0x91, 0x79, 0x94, 0x08, 0x73, 0x97, 0x05, 0x73, + 0x97, 0x73, 0x91, 0x75, 0x8b, 0x59, 0x8b, 0x67, 0x67, 0x7c, 0x4a, 0x08, + 0xa8, 0x06, 0x96, 0xaa, 0x9b, 0x9a, 0xa3, 0x8b, 0x96, 0x8b, 0x9a, 0x87, + 0x9a, 0x84, 0x08, 0xa2, 0x80, 0x05, 0xb3, 0x77, 0x9a, 0x87, 0xa4, 0x8b, + 0xc3, 0x8b, 0xa8, 0xa9, 0xa0, 0xd7, 0x08, 0x6e, 0x06, 0x0e, 0xed, 0xf8, + 0x4e, 0xcd, 0x15, 0x7a, 0x7d, 0x7f, 0x86, 0x7c, 0x8b, 0x08, 0x74, 0x84, + 0x99, 0xb7, 0x1f, 0xf7, 0x57, 0x07, 0x8b, 0xbf, 0x86, 0xa8, 0x7c, 0xa3, + 0x75, 0xaf, 0x60, 0x9e, 0x50, 0x8b, 0x08, 0x2d, 0x41, 0x5a, 0x4c, 0x74, + 0x9f, 0x77, 0xa2, 0xa3, 0xa0, 0x9f, 0xa1, 0x1f, 0x8b, 0x8f, 0x8a, 0x90, + 0x8a, 0x92, 0x89, 0x94, 0x8a, 0x93, 0x8b, 0x92, 0x08, 0xa6, 0xab, 0xa1, + 0xb3, 0xbc, 0xa6, 0x6e, 0x55, 0x1e, 0x4e, 0x07, 0xfb, 0x2e, 0x4d, 0x7a, + 0x83, 0x60, 0x65, 0x75, 0x77, 0x7d, 0x69, 0x8b, 0x6a, 0x08, 0x4c, 0xb7, + 0x5f, 0xc8, 0x1e, 0xb7, 0x8b, 0xb4, 0xa0, 0xc8, 0xbf, 0x08, 0x90, 0x57, + 0x9d, 0x76, 0xb4, 0x8b, 0xad, 0x8b, 0xa0, 0x97, 0xae, 0xb1, 0x08, 0xa5, + 0x07, 0xfb, 0x2f, 0xc4, 0x15, 0x8b, 0x6c, 0x86, 0x82, 0x76, 0x7f, 0x08, + 0x73, 0x7d, 0x6f, 0x82, 0x76, 0x8b, 0x08, 0x68, 0x6f, 0xad, 0xb6, 0x1f, + 0x8f, 0x07, 0x8b, 0xc6, 0xb4, 0xaf, 0xf7, 0x0d, 0xb7, 0x08, 0xfb, 0x25, + 0x07, 0x49, 0xf8, 0xeb, 0x15, 0x55, 0x5e, 0x5e, 0x55, 0x52, 0xb6, 0x5f, + 0xc3, 0xc3, 0xb8, 0xb7, 0xc2, 0xc3, 0x5e, 0xb8, 0x53, 0x1f, 0x8d, 0x69, + 0x15, 0xae, 0xa9, 0x6c, 0x68, 0x66, 0x6d, 0x6e, 0x66, 0x67, 0x6e, 0xa9, + 0xaf, 0xaf, 0xa9, 0xa9, 0xb0, 0x1f, 0x0e, 0xed, 0xf7, 0x76, 0x81, 0x15, + 0xdc, 0x92, 0xc0, 0xb8, 0xbf, 0xf4, 0x08, 0x7d, 0x94, 0x05, 0x5b, 0x45, + 0x67, 0x73, 0x52, 0x8b, 0x08, 0x30, 0x4b, 0xdb, 0xf7, 0x07, 0xf2, 0xc2, + 0xd2, 0xdc, 0x1f, 0xaf, 0x8b, 0x98, 0x80, 0x95, 0x66, 0x08, 0x91, 0x75, + 0x05, 0x93, 0x6e, 0x9d, 0x7a, 0xa1, 0x8b, 0x08, 0xa4, 0xa1, 0x9e, 0xa2, + 0xc3, 0x45, 0xba, 0x37, 0x1f, 0x5a, 0x8b, 0x58, 0x77, 0x62, 0x67, 0x59, + 0x5f, 0x6f, 0x47, 0x8b, 0x3b, 0x8b, 0xfb, 0x0b, 0xcd, 0x33, 0xf0, 0x7e, + 0x08, 0x65, 0x30, 0x92, 0x86, 0x05, 0x93, 0x8e, 0x94, 0x8c, 0x96, 0x8b, + 0x08, 0xb1, 0x9a, 0x81, 0x71, 0x70, 0x76, 0x7a, 0x69, 0x1f, 0x76, 0x8b, + 0x7a, 0x8e, 0x70, 0x94, 0x08, 0x7d, 0x6c, 0x05, 0xa8, 0x7f, 0xa2, 0x87, + 0xab, 0x8b, 0x08, 0xd8, 0xbb, 0xab, 0xbf, 0xb6, 0x6b, 0xa5, 0x55, 0x1f, + 0x81, 0x8b, 0x85, 0x8a, 0x81, 0x89, 0x08, 0xa0, 0xc2, 0x05, 0x0e, 0xed, + 0xf8, 0x2c, 0xf7, 0x38, 0x15, 0x5b, 0x3f, 0x60, 0x6e, 0x4b, 0x8b, 0x52, + 0x8b, 0x60, 0xa8, 0x6e, 0xc4, 0x79, 0xb1, 0x84, 0xac, 0x89, 0xc8, 0x08, + 0xf7, 0xc8, 0x06, 0x83, 0xcc, 0x81, 0xa8, 0x72, 0xab, 0x6d, 0xaf, 0x5d, + 0xa0, 0x57, 0x8b, 0x59, 0x8b, 0x5c, 0x79, 0x65, 0x69, 0x5c, 0x62, 0x70, + 0x44, 0x8b, 0x39, 0x8b, 0xfb, 0x1e, 0xd3, 0x35, 0xf7, 0x07, 0x8b, 0xea, + 0x8b, 0xd6, 0xc6, 0xb5, 0xf7, 0x00, 0x08, 0x7b, 0x92, 0x05, 0xfb, 0xc9, + 0xf7, 0x25, 0x15, 0x96, 0xd9, 0xad, 0xb0, 0xc8, 0x8b, 0xc8, 0x8b, 0xa3, + 0x6f, 0x98, 0x34, 0x08, 0xfb, 0x60, 0x06, 0xa1, 0xf7, 0xcd, 0x15, 0x72, + 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, + 0x74, 0xa2, 0x6f, 0x1f, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, + 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, + 0x0e, 0xed, 0xf8, 0x2c, 0xf7, 0x38, 0x15, 0x5b, 0x3f, 0x60, 0x6e, 0x4b, + 0x8b, 0x52, 0x8b, 0x60, 0xa8, 0x6e, 0xc4, 0x79, 0xb1, 0x84, 0xac, 0x89, + 0xc8, 0x08, 0xf7, 0xc8, 0x06, 0x83, 0xcc, 0x81, 0xa8, 0x72, 0xab, 0x6d, + 0xaf, 0x5d, 0xa0, 0x57, 0x8b, 0x59, 0x8b, 0x5c, 0x79, 0x65, 0x69, 0x5c, + 0x62, 0x70, 0x44, 0x8b, 0x39, 0x8b, 0xfb, 0x1e, 0xd3, 0x35, 0xf7, 0x07, + 0x8b, 0xea, 0x8b, 0xd6, 0xc6, 0xb5, 0xf7, 0x00, 0x08, 0x7b, 0x92, 0x05, + 0xfb, 0xc9, 0xf7, 0x25, 0x15, 0x96, 0xd9, 0xad, 0xb0, 0xc8, 0x8b, 0xc8, + 0x8b, 0xa3, 0x6f, 0x98, 0x34, 0x08, 0xfb, 0x60, 0x06, 0xe5, 0xf7, 0x5a, + 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, 0x8b, + 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x81, 0x86, 0x7a, 0x79, 0x08, + 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xed, 0xf8, 0x2c, 0xf7, + 0x38, 0x15, 0x5b, 0x3f, 0x60, 0x6e, 0x4b, 0x8b, 0x52, 0x8b, 0x60, 0xa8, + 0x6e, 0xc4, 0x79, 0xb1, 0x84, 0xac, 0x89, 0xc8, 0x08, 0xf7, 0xc8, 0x06, + 0x83, 0xcc, 0x81, 0xa8, 0x72, 0xab, 0x6d, 0xaf, 0x5d, 0xa0, 0x57, 0x8b, + 0x59, 0x8b, 0x5c, 0x79, 0x65, 0x69, 0x5c, 0x62, 0x70, 0x44, 0x8b, 0x39, + 0x8b, 0xfb, 0x1e, 0xd3, 0x35, 0xf7, 0x07, 0x8b, 0xea, 0x8b, 0xd6, 0xc6, + 0xb5, 0xf7, 0x00, 0x08, 0x7b, 0x92, 0x05, 0xfb, 0xc9, 0xf7, 0x25, 0x15, + 0x96, 0xd9, 0xad, 0xb0, 0xc8, 0x8b, 0xc8, 0x8b, 0xa3, 0x6f, 0x98, 0x34, + 0x08, 0xfb, 0x60, 0x06, 0xf7, 0x5b, 0xf7, 0x5a, 0x15, 0xfb, 0x27, 0xf7, + 0x28, 0x05, 0x79, 0x9d, 0x81, 0x90, 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, + 0x8b, 0x78, 0x8b, 0x7b, 0x96, 0x7c, 0x9e, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, + 0xb3, 0x8b, 0x05, 0x0e, 0xed, 0xf8, 0x2c, 0xf7, 0x38, 0x15, 0x5b, 0x3f, + 0x60, 0x6e, 0x4b, 0x8b, 0x52, 0x8b, 0x60, 0xa8, 0x6e, 0xc4, 0x79, 0xb1, + 0x84, 0xac, 0x89, 0xc8, 0x08, 0xf7, 0xc8, 0x06, 0x83, 0xcc, 0x81, 0xa8, + 0x72, 0xab, 0x6d, 0xaf, 0x5d, 0xa0, 0x57, 0x8b, 0x59, 0x8b, 0x5c, 0x79, + 0x65, 0x69, 0x5c, 0x62, 0x70, 0x44, 0x8b, 0x39, 0x8b, 0xfb, 0x1e, 0xd3, + 0x35, 0xf7, 0x07, 0x8b, 0xea, 0x8b, 0xd6, 0xc6, 0xb5, 0xf7, 0x00, 0x08, + 0x7b, 0x92, 0x05, 0xfb, 0xc9, 0xf7, 0x25, 0x15, 0x96, 0xd9, 0xad, 0xb0, + 0xc8, 0x8b, 0xc8, 0x8b, 0xa3, 0x6f, 0x98, 0x34, 0x08, 0xfb, 0x60, 0x06, + 0xf7, 0xab, 0xf7, 0x5a, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, + 0x10, 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, 0x24, 0xad, + 0x8b, 0x05, 0x0e, 0x47, 0xc6, 0xf9, 0x02, 0x15, 0x72, 0x74, 0x74, 0x71, + 0x6f, 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0x1f, 0xa6, 0x74, 0xa2, + 0x6f, 0x1e, 0xf7, 0x33, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, + 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x60, 0xfb, + 0x36, 0x15, 0xfb, 0x2f, 0x54, 0x8b, 0x7c, 0x93, 0x8c, 0x05, 0x97, 0x8d, + 0x98, 0x8c, 0x94, 0x8b, 0x08, 0xa3, 0x94, 0x7b, 0x5f, 0x1f, 0xfb, 0x7c, + 0x07, 0x8b, 0x43, 0x81, 0x80, 0x46, 0x87, 0x08, 0x7c, 0xf7, 0x81, 0x9a, + 0x07, 0x49, 0x90, 0x83, 0x95, 0x8b, 0xd3, 0x08, 0x8b, 0xf7, 0xf7, 0x05, + 0x87, 0x8e, 0x05, 0x0e, 0x47, 0xf7, 0x43, 0xf8, 0x60, 0x15, 0xfb, 0x2f, + 0x54, 0x8b, 0x7c, 0x93, 0x8c, 0x05, 0x97, 0x8d, 0x98, 0x8c, 0x94, 0x8b, + 0x08, 0xa3, 0x94, 0x7b, 0x5f, 0x1f, 0xfb, 0x7c, 0x07, 0x8b, 0x43, 0x81, + 0x80, 0x46, 0x87, 0x08, 0x7c, 0xf7, 0x81, 0x9a, 0x07, 0x49, 0x90, 0x83, + 0x95, 0x8b, 0xd3, 0x08, 0x8b, 0xf7, 0xf7, 0x87, 0x8e, 0x05, 0x46, 0xba, + 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, 0x8b, + 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x82, 0x86, 0x79, 0x79, 0x08, + 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0x47, 0xf7, 0x43, 0xf8, + 0x60, 0x15, 0xfb, 0x2f, 0x54, 0x8b, 0x7c, 0x93, 0x8c, 0x05, 0x97, 0x8d, + 0x98, 0x8c, 0x94, 0x8b, 0x08, 0xa3, 0x94, 0x7b, 0x5f, 0x1f, 0xfb, 0x7c, + 0x07, 0x8b, 0x43, 0x81, 0x80, 0x46, 0x87, 0x08, 0x7c, 0xf7, 0x81, 0x9a, + 0x07, 0x49, 0x90, 0x83, 0x95, 0x8b, 0xd3, 0x08, 0x8b, 0xf7, 0xf7, 0x87, + 0x8e, 0x05, 0xb3, 0xba, 0x15, 0xfb, 0x27, 0xf7, 0x28, 0x05, 0x79, 0x9d, + 0x82, 0x90, 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, 0x78, 0x8b, 0x7b, + 0x96, 0x7c, 0x9d, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, 0x05, 0x0e, + 0x47, 0xf7, 0x43, 0xf8, 0x60, 0x15, 0xfb, 0x2f, 0x54, 0x8b, 0x7c, 0x93, + 0x8c, 0x05, 0x97, 0x8d, 0x98, 0x8c, 0x94, 0x8b, 0x08, 0xa3, 0x94, 0x7b, + 0x5f, 0x1f, 0xfb, 0x7c, 0x07, 0x8b, 0x43, 0x81, 0x80, 0x46, 0x87, 0x08, + 0x7c, 0xf7, 0x81, 0x9a, 0x07, 0x49, 0x90, 0x83, 0x95, 0x8b, 0xd3, 0x08, + 0x8b, 0xf7, 0xf7, 0x87, 0x8e, 0x05, 0xf7, 0x0c, 0xba, 0x15, 0xfb, 0x11, + 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, 0x10, 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, + 0xf2, 0xf7, 0x0e, 0x24, 0xad, 0x8b, 0x05, 0x0e, 0x9b, 0xf8, 0x22, 0x15, + 0x91, 0x8e, 0x95, 0x8c, 0x96, 0x8b, 0x08, 0xa7, 0x94, 0x7c, 0x5a, 0x1f, + 0xfb, 0x8c, 0x07, 0x8b, 0x52, 0x80, 0x7d, 0x58, 0x87, 0x08, 0x7c, 0xf7, + 0x68, 0x9a, 0x07, 0x58, 0x8f, 0x7c, 0x97, 0x8b, 0xaf, 0x08, 0xf7, 0xad, + 0x07, 0xbb, 0xb8, 0xa1, 0x97, 0xac, 0x8b, 0x08, 0xbc, 0xa3, 0x6c, 0x49, + 0x1f, 0xfb, 0x65, 0x07, 0x8b, 0x4c, 0x7e, 0x7a, 0x59, 0x87, 0x08, 0x7c, + 0xf7, 0x64, 0x9a, 0x07, 0x5a, 0x90, 0x7f, 0x97, 0x8b, 0xbc, 0x08, 0xf7, + 0x79, 0x07, 0xe9, 0x5f, 0xc3, 0x41, 0x1e, 0x5d, 0x8b, 0x6c, 0x7a, 0x47, + 0x4b, 0x08, 0x8b, 0xda, 0x84, 0x8d, 0x05, 0x5a, 0x79, 0x69, 0x80, 0x54, + 0x7b, 0x08, 0x7a, 0x07, 0xf8, 0x06, 0xf7, 0x84, 0x15, 0x79, 0x65, 0x7e, + 0x7f, 0x74, 0x8b, 0x7d, 0x8b, 0x77, 0x91, 0x79, 0x94, 0x08, 0x73, 0x97, + 0x05, 0x73, 0x97, 0x73, 0x91, 0x75, 0x8b, 0x59, 0x8b, 0x67, 0x67, 0x7c, + 0x4a, 0x08, 0xa8, 0x06, 0x96, 0xaa, 0x9b, 0x9a, 0xa3, 0x8b, 0x96, 0x8b, + 0x9a, 0x87, 0x9a, 0x84, 0x08, 0xa2, 0x80, 0x05, 0xb3, 0x77, 0x9a, 0x87, + 0xa4, 0x8b, 0xc3, 0x8b, 0xa8, 0xa9, 0xa0, 0xd7, 0x08, 0x6e, 0x06, 0x0e, + 0xf7, 0x8e, 0xf8, 0x60, 0x15, 0xfb, 0x16, 0x30, 0x2b, 0xfb, 0x1e, 0xfb, + 0x1b, 0xe8, 0x26, 0xf7, 0x12, 0xf7, 0x12, 0xeb, 0xf5, 0xf7, 0x1e, 0x1f, + 0xf7, 0x17, 0x2f, 0xea, 0xfb, 0x14, 0x1e, 0x7e, 0x6f, 0x15, 0xdf, 0xc6, + 0x2b, 0xfb, 0x1d, 0xfb, 0x05, 0x5e, 0x47, 0x40, 0x1f, 0x64, 0x8b, 0x66, + 0xa3, 0x76, 0xb3, 0x6f, 0xbf, 0x7b, 0xd1, 0x8b, 0xd2, 0x08, 0xea, 0xba, + 0xc9, 0xd2, 0x1e, 0x33, 0xf7, 0x52, 0x15, 0x72, 0x74, 0x74, 0x71, 0x6f, + 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0x1f, 0xa6, 0x74, 0xa2, 0x6f, + 0x1e, 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, + 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0xf7, 0x8e, + 0xf8, 0x60, 0x15, 0xfb, 0x16, 0x30, 0x2b, 0xfb, 0x1e, 0xfb, 0x1b, 0xe8, + 0x26, 0xf7, 0x12, 0xf7, 0x12, 0xeb, 0xf5, 0xf7, 0x1e, 0xf7, 0x17, 0x2f, + 0xea, 0xfb, 0x14, 0x1f, 0x7e, 0x6f, 0x15, 0xdf, 0xc6, 0x2b, 0xfb, 0x1d, + 0xfb, 0x05, 0x5e, 0x47, 0x40, 0x1f, 0x64, 0x8b, 0x66, 0xa3, 0x76, 0xb3, + 0x6f, 0xbf, 0x7b, 0xd1, 0x8b, 0xd2, 0x08, 0xea, 0xba, 0xc9, 0xd2, 0x1e, + 0x77, 0xd6, 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, + 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x81, 0x86, 0x7a, + 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xf7, 0x8e, + 0xf8, 0x60, 0x15, 0xfb, 0x16, 0x30, 0x2b, 0xfb, 0x1e, 0xfb, 0x1b, 0xe8, + 0x26, 0xf7, 0x12, 0xf7, 0x12, 0xeb, 0xf5, 0xf7, 0x1e, 0xf7, 0x17, 0x2f, + 0xea, 0xfb, 0x14, 0x1f, 0x7e, 0x6f, 0x15, 0xdf, 0xc6, 0x2b, 0xfb, 0x1d, + 0xfb, 0x05, 0x5e, 0x47, 0x40, 0x1f, 0x64, 0x8b, 0x66, 0xa3, 0x76, 0xb3, + 0x6f, 0xbf, 0x7b, 0xd1, 0x8b, 0xd2, 0x08, 0xea, 0xba, 0xc9, 0xd2, 0x1e, + 0xe4, 0xd6, 0x15, 0xfb, 0x27, 0xf7, 0x28, 0x05, 0x79, 0x9d, 0x81, 0x90, + 0x7c, 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, 0x78, 0x8b, 0x7b, 0x96, 0x7c, + 0x9e, 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, 0x05, 0x0e, 0xf7, 0x8e, + 0xf8, 0x60, 0x15, 0xfb, 0x16, 0x30, 0x2b, 0xfb, 0x1e, 0xfb, 0x1b, 0xe8, + 0x26, 0xf7, 0x12, 0xf7, 0x12, 0xeb, 0xf5, 0xf7, 0x1e, 0xf7, 0x17, 0x2f, + 0xea, 0xfb, 0x14, 0x1f, 0x7e, 0x6f, 0x15, 0xdf, 0xc6, 0x2b, 0xfb, 0x1d, + 0xfb, 0x05, 0x5e, 0x47, 0x40, 0x1f, 0x64, 0x8b, 0x66, 0xa3, 0x76, 0xb3, + 0x6f, 0xbf, 0x7b, 0xd1, 0x8b, 0xd2, 0x08, 0xea, 0xba, 0xc9, 0xd2, 0x1e, + 0xf7, 0x3d, 0xd6, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, 0x8b, 0xfb, 0x10, + 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, 0x24, 0xad, 0x8b, + 0x05, 0x0e, 0xf7, 0x8e, 0xf8, 0x60, 0x15, 0xfb, 0x16, 0x30, 0x2b, 0xfb, + 0x1e, 0xfb, 0x1b, 0xe8, 0x26, 0xf7, 0x12, 0xf7, 0x12, 0xeb, 0xf5, 0xf7, + 0x1e, 0x1f, 0xf7, 0x17, 0x2f, 0xea, 0xfb, 0x14, 0x1e, 0x7e, 0x6f, 0x15, + 0xdf, 0xc6, 0x2b, 0xfb, 0x1d, 0xfb, 0x05, 0x5e, 0x47, 0x40, 0x1f, 0x64, + 0x8b, 0x66, 0xa3, 0x76, 0xb3, 0x6f, 0xbf, 0x7b, 0xd1, 0x8b, 0xd2, 0x08, + 0xea, 0xba, 0xc9, 0xd2, 0x1e, 0xf7, 0x29, 0xf7, 0x62, 0x15, 0x79, 0x65, + 0x7e, 0x7f, 0x74, 0x8b, 0x7d, 0x8b, 0x77, 0x91, 0x79, 0x94, 0x08, 0x73, + 0x97, 0x05, 0x73, 0x97, 0x73, 0x91, 0x75, 0x8b, 0x59, 0x8b, 0x67, 0x67, + 0x7c, 0x4a, 0x08, 0xa8, 0x06, 0x96, 0xaa, 0x9b, 0x9a, 0xa3, 0x8b, 0x96, + 0x8b, 0x9a, 0x87, 0x9a, 0x84, 0x08, 0xa2, 0x80, 0x05, 0xb3, 0x77, 0x9a, + 0x87, 0xa4, 0x8b, 0xc3, 0x8b, 0xa8, 0xa9, 0xa0, 0xd7, 0x08, 0x6e, 0x06, + 0x0e, 0xb6, 0xf7, 0xcf, 0xf7, 0xce, 0x15, 0x87, 0xf7, 0x1c, 0x80, 0x8b, + 0x89, 0x89, 0x05, 0x82, 0x84, 0x8a, 0x8a, 0x87, 0x8b, 0x85, 0x8b, 0x81, + 0x8d, 0x80, 0x90, 0x08, 0x75, 0x93, 0x75, 0x8f, 0x71, 0x8b, 0x3c, 0x8b, + 0x52, 0x58, 0x8b, 0x43, 0x8b, 0x53, 0xab, 0x63, 0xe0, 0x5b, 0x08, 0xc5, + 0x6a, 0x05, 0xae, 0x77, 0x9c, 0x73, 0x8b, 0x6c, 0x8b, 0x5f, 0x6b, 0x6f, + 0x58, 0x8b, 0x69, 0x8b, 0x6c, 0x98, 0x78, 0xa1, 0x76, 0xa4, 0x82, 0xa2, + 0x7e, 0xc4, 0x08, 0x7b, 0xfb, 0x30, 0x98, 0x06, 0x92, 0x95, 0x8f, 0x8d, + 0x97, 0x8b, 0x08, 0x94, 0x8b, 0x99, 0x89, 0xa2, 0x85, 0x08, 0xa7, 0x85, + 0xa6, 0x87, 0x9d, 0x8b, 0xd8, 0x8b, 0xcb, 0xc5, 0x8b, 0xd1, 0x8b, 0xbd, + 0x73, 0xac, 0x4f, 0xaf, 0x08, 0xfb, 0x00, 0xcb, 0x05, 0x6f, 0x9b, 0x7c, + 0xa4, 0x8b, 0xa6, 0x8b, 0xb3, 0xaa, 0xa7, 0xb9, 0x8b, 0xc4, 0x8b, 0xa9, + 0x69, 0xa2, 0x32, 0x08, 0x9a, 0x06, 0xae, 0xf7, 0xfc, 0x15, 0x69, 0x8b, + 0xfb, 0x0e, 0x24, 0xfb, 0x0d, 0xf2, 0x69, 0x8b, 0xf7, 0x10, 0xfb, 0x3b, + 0xc9, 0x8b, 0xf7, 0x11, 0xf7, 0x3b, 0x05, 0x0e, 0xf8, 0x73, 0xbd, 0x15, + 0x86, 0x06, 0x5d, 0x80, 0x96, 0xb9, 0x1f, 0xf7, 0xeb, 0xfb, 0x32, 0x07, + 0x7a, 0x07, 0xc9, 0x88, 0x97, 0x81, 0x8b, 0x59, 0x08, 0xfb, 0x7f, 0x07, + 0x8b, 0x6f, 0x86, 0x7d, 0x7d, 0x80, 0x70, 0x75, 0x6c, 0x7f, 0x6d, 0x8b, + 0x08, 0x64, 0x6b, 0xad, 0xb5, 0x1f, 0xf7, 0xda, 0xfb, 0x26, 0x7d, 0x07, + 0xbb, 0x88, 0x99, 0x7c, 0x8b, 0x5d, 0x08, 0xfb, 0x90, 0x07, 0x3c, 0xbb, + 0x58, 0xd4, 0x1e, 0xb0, 0x8b, 0xb2, 0x9b, 0xa6, 0xa6, 0x08, 0xb6, 0xb6, + 0x8b, 0x38, 0x8f, 0x89, 0x05, 0xbd, 0x9f, 0xaf, 0x96, 0xbe, 0x99, 0x08, + 0x99, 0x07, 0xfb, 0xf1, 0xf8, 0xd0, 0x15, 0x72, 0x74, 0x74, 0x71, 0x6f, + 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, + 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, + 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0xf8, 0x73, 0xbd, + 0x15, 0x86, 0x06, 0x5d, 0x80, 0x96, 0xb9, 0x1f, 0xf7, 0xeb, 0xfb, 0x32, + 0x07, 0x7a, 0x07, 0xc9, 0x88, 0x97, 0x81, 0x8b, 0x59, 0x08, 0xfb, 0x7f, + 0x07, 0x8b, 0x6f, 0x86, 0x7d, 0x7d, 0x80, 0x70, 0x75, 0x6c, 0x7f, 0x6d, + 0x8b, 0x08, 0x64, 0x6b, 0xad, 0xb5, 0x1f, 0xf7, 0xda, 0xfb, 0x26, 0x7d, + 0x07, 0xbb, 0x88, 0x99, 0x7c, 0x8b, 0x5d, 0x08, 0xfb, 0x90, 0x07, 0x3c, + 0xbb, 0x58, 0xd4, 0x1e, 0xb0, 0x8b, 0xb2, 0x9b, 0xa6, 0xa6, 0x08, 0xb6, + 0xb6, 0x8b, 0x38, 0x8f, 0x89, 0x05, 0xbd, 0x9f, 0xaf, 0x96, 0xbe, 0x99, + 0x08, 0x99, 0x07, 0xfb, 0x9a, 0xf8, 0x5d, 0x15, 0xf7, 0x2e, 0xec, 0x05, + 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, + 0x7c, 0x8b, 0x81, 0x86, 0x7a, 0x79, 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, + 0x8b, 0x05, 0x0e, 0xf8, 0x73, 0xbd, 0x15, 0x86, 0x06, 0x5d, 0x80, 0x96, + 0xb9, 0x1f, 0xf7, 0xeb, 0xfb, 0x32, 0x07, 0x7a, 0x07, 0xc9, 0x88, 0x97, + 0x81, 0x8b, 0x59, 0x08, 0xfb, 0x7f, 0x07, 0x8b, 0x6f, 0x86, 0x7d, 0x7d, + 0x80, 0x70, 0x75, 0x6c, 0x7f, 0x6d, 0x8b, 0x08, 0x64, 0x6b, 0xad, 0xb5, + 0x1f, 0xf7, 0xda, 0xfb, 0x26, 0x7d, 0x07, 0xbb, 0x88, 0x99, 0x7c, 0x8b, + 0x5d, 0x08, 0xfb, 0x90, 0x07, 0x3c, 0xbb, 0x58, 0xd4, 0x1e, 0xb0, 0x8b, + 0xb2, 0x9b, 0xa6, 0xa6, 0x08, 0xb6, 0xb6, 0x8b, 0x38, 0x8f, 0x89, 0x05, + 0xbd, 0x9f, 0xaf, 0x96, 0xbe, 0x99, 0x08, 0x99, 0x07, 0xfb, 0x42, 0xf8, + 0x5d, 0x15, 0xfb, 0x27, 0xf7, 0x28, 0x05, 0x79, 0x9d, 0x81, 0x90, 0x7c, + 0x8b, 0x76, 0x8b, 0x7e, 0x7f, 0x8b, 0x78, 0x8b, 0x7b, 0x96, 0x7c, 0x9e, + 0x7f, 0x08, 0xf7, 0x2e, 0x2a, 0xb3, 0x8b, 0x05, 0x0e, 0xf8, 0x73, 0xbd, + 0x15, 0x86, 0x06, 0x5d, 0x80, 0x96, 0xb9, 0x1f, 0xf7, 0xeb, 0xfb, 0x32, + 0x07, 0x7a, 0x07, 0xc9, 0x88, 0x97, 0x81, 0x8b, 0x59, 0x08, 0xfb, 0x7f, + 0x07, 0x8b, 0x6f, 0x86, 0x7d, 0x7d, 0x80, 0x70, 0x75, 0x6c, 0x7f, 0x6d, + 0x8b, 0x08, 0x64, 0x6b, 0xad, 0xb5, 0x1f, 0xf7, 0xda, 0xfb, 0x26, 0x7d, + 0x07, 0xbb, 0x88, 0x99, 0x7c, 0x8b, 0x5d, 0x08, 0xfb, 0x90, 0x07, 0x3c, + 0xbb, 0x58, 0xd4, 0x1e, 0xb0, 0x8b, 0xb2, 0x9b, 0xa6, 0xa6, 0x08, 0xb6, + 0xb6, 0x8b, 0x38, 0x8f, 0x89, 0x05, 0xbd, 0x9f, 0xaf, 0x96, 0xbe, 0x99, + 0x08, 0x99, 0x07, 0x35, 0xf8, 0x5d, 0x15, 0xfb, 0x11, 0xf7, 0x3b, 0x4d, + 0x8b, 0xfb, 0x10, 0xfb, 0x3b, 0xad, 0x8b, 0xf7, 0x0d, 0xf2, 0xf7, 0x0e, + 0x24, 0xad, 0x8b, 0x05, 0x0e, 0xf8, 0x6f, 0xf8, 0x56, 0x15, 0xfb, 0x1b, + 0x7c, 0x06, 0xab, 0x9b, 0x82, 0x7b, 0x1f, 0x8b, 0x87, 0x8a, 0x85, 0x88, + 0x84, 0x08, 0x2a, 0xfb, 0xa8, 0xfb, 0x07, 0xf7, 0x91, 0x05, 0x85, 0x99, + 0x87, 0x98, 0x8b, 0x96, 0x8b, 0x9d, 0x9a, 0x92, 0xb6, 0x8d, 0x08, 0x9a, + 0xfb, 0x62, 0x7d, 0x07, 0xa5, 0x87, 0x9c, 0x80, 0x93, 0x7a, 0x08, 0xf7, + 0x06, 0xfb, 0x8a, 0x8e, 0x83, 0x9a, 0x6d, 0x05, 0xa7, 0x59, 0x9b, 0x67, + 0x8b, 0x7c, 0x8b, 0x7c, 0x74, 0x4c, 0x7a, 0x6d, 0x7d, 0x71, 0x75, 0x78, + 0x7d, 0x8b, 0x85, 0x8b, 0x82, 0x8d, 0x81, 0x90, 0x78, 0x92, 0x7a, 0x8f, + 0x7a, 0x8b, 0x08, 0x74, 0x77, 0x77, 0x73, 0x6a, 0xab, 0x72, 0xb5, 0x1f, + 0xce, 0x8b, 0xbb, 0xc3, 0xc1, 0xf7, 0x24, 0x08, 0xf7, 0x2e, 0xf8, 0x2c, + 0x05, 0x98, 0xab, 0x96, 0x95, 0xa3, 0x8e, 0x08, 0x9a, 0x07, 0xfb, 0x96, + 0xc4, 0x15, 0xf7, 0x2e, 0xec, 0x05, 0xa0, 0x98, 0x94, 0x98, 0x8b, 0x9b, + 0x8b, 0x9f, 0x7e, 0x97, 0x75, 0x8b, 0x7c, 0x8b, 0x81, 0x86, 0x7a, 0x79, + 0x08, 0xfb, 0x27, 0xfb, 0x28, 0xb3, 0x8b, 0x05, 0x0e, 0xed, 0xf8, 0x36, + 0xf7, 0x1b, 0x15, 0x79, 0x8f, 0x05, 0x81, 0x59, 0x85, 0x7b, 0x7e, 0x7a, + 0x7d, 0x7a, 0x69, 0x82, 0x58, 0x8b, 0x08, 0xfb, 0x1e, 0x8b, 0xf7, 0xa1, + 0xf8, 0x29, 0x8b, 0x9a, 0xfb, 0xef, 0x8b, 0x88, 0xfb, 0x0a, 0x9d, 0x8b, + 0x05, 0x94, 0xd4, 0x9a, 0x9a, 0xc7, 0x8b, 0x08, 0xf7, 0x1e, 0x8b, 0xfb, + 0x9e, 0xfc, 0x29, 0x8b, 0x7c, 0xf8, 0x0d, 0x8b, 0x99, 0xf7, 0x1b, 0x05, + 0x63, 0xf8, 0xaf, 0x15, 0x69, 0x8b, 0xfb, 0x0e, 0x24, 0xfb, 0x0d, 0xf2, + 0x69, 0x8b, 0xf7, 0x10, 0xfb, 0x3b, 0xc9, 0x8b, 0xf7, 0x11, 0xf7, 0x3b, + 0x05, 0x0e, 0xf7, 0xa2, 0xf8, 0xd3, 0x15, 0xc6, 0x4f, 0xa2, 0x62, 0x9a, + 0x41, 0x58, 0xba, 0x70, 0x98, 0x5b, 0x8b, 0x08, 0xfb, 0x0c, 0x2f, 0x24, + 0xfb, 0x1a, 0xfb, 0x19, 0xe9, 0x27, 0xf7, 0x10, 0x1f, 0xc0, 0x8b, 0xb8, + 0x9d, 0xb0, 0xae, 0xc2, 0xbf, 0xad, 0xe9, 0x8b, 0xeb, 0x8b, 0xd1, 0x7b, + 0xd3, 0x6c, 0xca, 0x75, 0xb8, 0x79, 0xa3, 0x58, 0xbc, 0x08, 0xe6, 0xbb, + 0x6a, 0xa9, 0x2c, 0x59, 0x05, 0x58, 0xa9, 0x68, 0x96, 0x49, 0x91, 0x08, + 0x61, 0x74, 0x05, 0xbf, 0x82, 0xad, 0x7d, 0xba, 0x6a, 0x08, 0xfb, 0x0d, + 0x4b, 0xac, 0x6d, 0xf7, 0x0f, 0xcc, 0x05, 0x6a, 0xfb, 0x23, 0x15, 0xe0, + 0xc6, 0x2c, 0xfb, 0x1c, 0xfb, 0x07, 0x5f, 0x47, 0x3f, 0x1f, 0x64, 0x8b, + 0x66, 0xa3, 0x75, 0xb4, 0x6f, 0xc0, 0x7b, 0xd1, 0x8b, 0xd1, 0x08, 0xe8, + 0xbb, 0xca, 0xd1, 0x1e, 0x0e, 0x94, 0xf9, 0x03, 0x15, 0x91, 0x8c, 0x8f, + 0x8b, 0x92, 0x8b, 0x08, 0xb3, 0x94, 0x82, 0x61, 0x1f, 0xfd, 0x54, 0x07, + 0x8b, 0x57, 0x80, 0x80, 0x50, 0x86, 0x08, 0x79, 0xf7, 0x86, 0x07, 0x9d, + 0x07, 0x40, 0x8c, 0x7e, 0x96, 0x8b, 0xca, 0x08, 0xf7, 0x31, 0x07, 0xae, + 0x6a, 0xa3, 0x81, 0xb5, 0x8b, 0x08, 0xf7, 0x0a, 0xe7, 0xf7, 0x04, 0xf7, + 0x25, 0xf7, 0x10, 0x45, 0xe4, 0x2a, 0x1f, 0x54, 0x8b, 0x5f, 0x73, 0x5e, + 0x55, 0x08, 0x8b, 0xf7, 0xbe, 0x86, 0x8e, 0x05, 0x5b, 0x7a, 0x6f, 0x83, + 0x46, 0x78, 0x08, 0x7b, 0x07, 0xf7, 0x2a, 0xfb, 0xb5, 0x15, 0xa9, 0xc3, + 0xaf, 0xb9, 0xd5, 0xbc, 0x3f, 0xfb, 0x08, 0xfb, 0x03, 0x5a, 0x40, 0x43, + 0x5c, 0x52, 0xaf, 0xa9, 0x1e, 0xf7, 0x8a, 0x07, 0x0e, 0xf8, 0x6f, 0xf8, + 0x56, 0x15, 0xfb, 0x1b, 0x7c, 0x06, 0xab, 0x9b, 0x82, 0x7b, 0x1f, 0x8b, + 0x87, 0x8a, 0x85, 0x88, 0x84, 0x08, 0x2a, 0xfb, 0xa8, 0xfb, 0x07, 0xf7, + 0x91, 0x05, 0x85, 0x99, 0x87, 0x98, 0x8b, 0x96, 0x8b, 0x9d, 0x9a, 0x92, + 0xb6, 0x8d, 0x08, 0x9a, 0xfb, 0x62, 0x7d, 0x07, 0xa5, 0x87, 0x9c, 0x80, + 0x93, 0x7a, 0x08, 0xf7, 0x06, 0xfb, 0x8a, 0x8e, 0x83, 0x9a, 0x6d, 0x05, + 0xa7, 0x59, 0x9b, 0x67, 0x8b, 0x7c, 0x8b, 0x7c, 0x74, 0x4c, 0x7a, 0x6d, + 0x7d, 0x71, 0x75, 0x78, 0x7d, 0x8b, 0x85, 0x8b, 0x82, 0x8d, 0x81, 0x90, + 0x78, 0x92, 0x7a, 0x8f, 0x7a, 0x8b, 0x08, 0x74, 0x77, 0x77, 0x73, 0x6a, + 0xab, 0x72, 0xb5, 0x1f, 0xce, 0x8b, 0xbb, 0xc3, 0xc1, 0xf7, 0x24, 0x08, + 0xf7, 0x2e, 0xf8, 0x2c, 0x05, 0x98, 0xab, 0x96, 0x95, 0xa3, 0x8e, 0x08, + 0x9a, 0x07, 0xfb, 0xca, 0xf7, 0x40, 0x15, 0x72, 0x74, 0x74, 0x71, 0x6f, + 0xa0, 0x75, 0xa6, 0xa7, 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, + 0xf7, 0x5b, 0x16, 0x72, 0x74, 0x74, 0x71, 0x6f, 0xa0, 0x75, 0xa6, 0xa7, + 0xa2, 0xa1, 0xa6, 0xa6, 0x74, 0xa2, 0x6f, 0x1f, 0x0e, 0xf7, 0x29, 0xf8, + 0x1a, 0x15, 0x90, 0xc1, 0x93, 0xba, 0x95, 0xab, 0xa5, 0xd9, 0xbb, 0xb8, + 0xc4, 0x8b, 0xbc, 0x8b, 0xbe, 0x67, 0xa7, 0x55, 0x99, 0x6f, 0x94, 0x6a, + 0x91, 0x5f, 0x08, 0x9c, 0x8b, 0x05, 0x7b, 0xf7, 0x73, 0x79, 0x8b, 0x05, + 0x85, 0x6c, 0x84, 0x7e, 0x7f, 0x8b, 0x88, 0x8b, 0x85, 0x8e, 0x83, 0x90, + 0x08, 0x68, 0xa2, 0x67, 0x97, 0x69, 0x8b, 0xfb, 0x09, 0x8b, 0x29, 0xfb, + 0x08, 0x74, 0xfb, 0x3b, 0x08, 0x5c, 0x8b, 0x70, 0x62, 0xd1, 0x8b, 0x05, + 0x8a, 0x81, 0x8b, 0x83, 0x8b, 0x83, 0x8b, 0x7d, 0x8b, 0x81, 0x8c, 0x7e, + 0x08, 0x60, 0x8b, 0x70, 0x62, 0xd6, 0x8b, 0x05, 0xa5, 0xfb, 0x33, 0xe7, + 0x27, 0xf7, 0x0b, 0x8b, 0xd4, 0x8b, 0xd0, 0xaf, 0xb2, 0xc5, 0x08, 0xad, + 0x07, 0x69, 0x50, 0x4e, 0x65, 0x50, 0x8b, 0x2e, 0x8b, 0x49, 0xe3, 0x7d, + 0xf7, 0x20, 0x08, 0xf7, 0x12, 0x8b, 0xa5, 0xb4, 0xfb, 0x2f, 0x8b, 0x05, + 0x8a, 0x9c, 0x8b, 0x94, 0x8b, 0x8f, 0x8b, 0x90, 0x8b, 0x93, 0x8c, 0x9f, + 0x08, 0xf7, 0x57, 0x8b, 0xa6, 0xb4, 0x05, 0xfb, 0x70, 0x06, 0x0e, 0x5d, + 0xf7, 0x8c, 0xf7, 0xba, 0x15, 0x5d, 0x8e, 0x80, 0x92, 0x8b, 0xa5, 0x08, + 0x8b, 0xf7, 0xeb, 0x7d, 0x8e, 0xfb, 0x0a, 0x54, 0x8b, 0x74, 0x05, 0xb0, + 0x98, 0x8b, 0x8b, 0x91, 0x8b, 0x08, 0x91, 0x8d, 0x85, 0x75, 0x1f, 0xfb, + 0x95, 0x07, 0x8b, 0x74, 0x81, 0x85, 0x60, 0x88, 0x08, 0x73, 0xf7, 0x53, + 0xa3, 0x07, 0x0e, 0x5d, 0xf7, 0xbc, 0xf7, 0xf7, 0x15, 0x7a, 0x92, 0x05, + 0x7c, 0x75, 0x82, 0x86, 0x70, 0x8b, 0x08, 0xfb, 0x0d, 0x8b, 0xe1, 0xe0, + 0x05, 0xc8, 0xc7, 0xa2, 0xb4, 0x8b, 0xbc, 0x8b, 0xca, 0x56, 0xb6, 0x3d, + 0x8b, 0x63, 0x8b, 0x68, 0x7f, 0x74, 0x74, 0x76, 0x78, 0x81, 0x78, 0x7b, + 0x5d, 0x08, 0xa4, 0x7d, 0x05, 0xa1, 0xbb, 0xa6, 0xa1, 0xb0, 0x8b, 0xb3, + 0x8b, 0xac, 0x69, 0x8b, 0x61, 0x8b, 0x6d, 0x6c, 0x56, 0x59, 0x55, 0x08, + 0x29, 0x20, 0x8b, 0x74, 0xf7, 0x91, 0x8b, 0xb0, 0xe0, 0x05, 0x0e, 0x5d, + 0xe8, 0xf8, 0x60, 0x15, 0xa2, 0x8e, 0x05, 0x97, 0x8d, 0xa4, 0x84, 0x9b, + 0x82, 0xa6, 0x7c, 0x99, 0x72, 0x8b, 0x6c, 0x8b, 0x62, 0x70, 0x70, 0x62, + 0x8b, 0x78, 0x8b, 0x80, 0x8f, 0x75, 0x9b, 0x78, 0x99, 0x80, 0x90, 0x80, + 0x8b, 0x08, 0x77, 0x7c, 0x7b, 0x76, 0x6b, 0xaa, 0x79, 0xbf, 0xf7, 0x03, + 0xde, 0xc5, 0xd9, 0x1f, 0x8b, 0xbf, 0x6e, 0xb1, 0x51, 0xa2, 0x08, 0xb6, + 0xaa, 0x9c, 0xa2, 0x8b, 0xa7, 0x8b, 0xb9, 0x5b, 0xb0, 0x4f, 0x8b, 0x4e, + 0x8b, 0x64, 0x70, 0x68, 0x47, 0x08, 0xa4, 0x79, 0x05, 0xa9, 0xb6, 0x9f, + 0x99, 0xad, 0x8b, 0xaf, 0x8b, 0xa1, 0x79, 0x8b, 0x6c, 0x8b, 0x67, 0x71, + 0x75, 0x46, 0x73, 0x08, 0x6e, 0x07, 0x0e, 0x2b, 0xf7, 0x11, 0xf7, 0xca, + 0x15, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, + 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0x0e, 0x7e, 0xb2, 0xf7, 0x95, 0x15, + 0x4c, 0xf7, 0x8a, 0xca, 0xfb, 0x8a, 0x07, 0x0e, 0xc1, 0xf7, 0x5c, 0xf9, + 0x38, 0x15, 0x3b, 0x4c, 0x4c, 0x3b, 0x3c, 0xca, 0x4b, 0xd9, 0xdc, 0xcb, + 0xc9, 0xdb, 0xdc, 0x4c, 0xca, 0x3b, 0x1f, 0x69, 0x04, 0xc3, 0xbb, 0x59, + 0x50, 0x4f, 0x5c, 0x5a, 0x51, 0x53, 0x5c, 0xbd, 0xc6, 0xc6, 0xba, 0xbd, + 0xc4, 0x1f, 0x0e, 0xf7, 0x6e, 0xf8, 0xaa, 0xf7, 0x70, 0x15, 0xcd, 0xfc, + 0x8c, 0x49, 0xf8, 0x8c, 0x07, 0x0e, 0xf7, 0x6e, 0xf7, 0x7e, 0xf7, 0x91, + 0x15, 0xfb, 0x58, 0xfb, 0x59, 0xbb, 0x5b, 0xf7, 0x58, 0xf7, 0x59, 0xf7, + 0x59, 0xfb, 0x59, 0xbb, 0xbb, 0xfb, 0x59, 0xf7, 0x59, 0xf7, 0x59, 0xf7, + 0x58, 0x5b, 0xbb, 0xfb, 0x59, 0xfb, 0x59, 0xfb, 0x58, 0xf7, 0x59, 0x5b, + 0x5b, 0xf7, 0x58, 0xfb, 0x58, 0x05, 0x0e, 0xf7, 0x6e, 0xf8, 0xaa, 0xf7, + 0x70, 0x15, 0xcd, 0xfc, 0x8c, 0x49, 0xf8, 0x8c, 0x07, 0xfb, 0x90, 0xf7, + 0xbc, 0x15, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, + 0xa4, 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0xfc, 0x33, 0x04, 0x6d, 0x72, + 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, 0x71, + 0xa5, 0x6d, 0x1f, 0x0e, 0xf9, 0x0e, 0xf7, 0x82, 0xf9, 0x16, 0x15, 0xbd, + 0x06, 0xae, 0x8b, 0x9d, 0x78, 0x99, 0x5a, 0x08, 0x9f, 0xe3, 0xfb, 0xed, + 0x33, 0x9f, 0x06, 0x98, 0xbc, 0x9e, 0x9e, 0xaf, 0x8b, 0x08, 0xbc, 0xfb, + 0xca, 0x06, 0x8b, 0x5b, 0x8b, 0x8b, 0x59, 0x85, 0x08, 0x77, 0xf7, 0x3f, + 0x9f, 0x07, 0x59, 0x91, 0x8b, 0x8b, 0x8b, 0xbb, 0x08, 0xf7, 0xca, 0x07, + 0xf8, 0x3f, 0xfc, 0x16, 0x15, 0x96, 0x8b, 0xf7, 0x2e, 0xf7, 0xcc, 0x8b, + 0xfb, 0x80, 0x05, 0x8b, 0x6b, 0x8a, 0x82, 0x85, 0x87, 0x84, 0x87, 0x87, + 0x8a, 0x6c, 0x87, 0x08, 0x77, 0xf7, 0x3e, 0x9f, 0x07, 0x59, 0x91, 0x8b, + 0x8b, 0x8b, 0xbb, 0x08, 0xf7, 0x93, 0x07, 0x8b, 0xb2, 0x98, 0x98, 0xb6, + 0x8e, 0x08, 0x9f, 0x24, 0x07, 0xfb, 0x34, 0xfb, 0xc9, 0xfb, 0x2e, 0xf7, + 0xc9, 0xfb, 0x0d, 0x8b, 0x8b, 0x77, 0x05, 0xa9, 0x8a, 0xa5, 0x78, 0x98, + 0x6d, 0x08, 0xfb, 0x8d, 0x07, 0x8b, 0x5b, 0x81, 0x7f, 0x61, 0x86, 0x08, + 0x77, 0xf7, 0x17, 0x9f, 0x07, 0x60, 0x90, 0x81, 0x97, 0x8b, 0xbb, 0x08, + 0x8b, 0xf7, 0x73, 0xf7, 0x2b, 0xfb, 0xca, 0x05, 0x0e, 0xf7, 0x6e, 0xa9, + 0x16, 0xf8, 0x8c, 0xcd, 0xfc, 0x8c, 0x49, 0x06, 0xf7, 0x6f, 0xf7, 0xf0, + 0x15, 0xfb, 0x6f, 0x49, 0xf7, 0x6f, 0xfb, 0x34, 0xcd, 0xf7, 0x34, 0xf7, + 0x6f, 0xcd, 0xfb, 0x6f, 0xf7, 0x70, 0x49, 0xfb, 0x70, 0x06, 0x0e, 0xf8, + 0x28, 0xf8, 0xec, 0xf9, 0x38, 0x15, 0x5d, 0x8b, 0xfc, 0x59, 0xfd, 0x46, + 0xbc, 0x8b, 0x05, 0xf8, 0x56, 0xf9, 0x46, 0x05, 0xfc, 0x0e, 0xfc, 0x12, + 0x15, 0x5d, 0x8e, 0x80, 0x92, 0x8b, 0xa5, 0x08, 0x8b, 0xf7, 0xeb, 0x7d, + 0x8e, 0xfb, 0x0a, 0x54, 0x8b, 0x74, 0x05, 0xb0, 0x98, 0x8b, 0x8b, 0x91, + 0x8b, 0x08, 0x91, 0x8d, 0x85, 0x75, 0x1f, 0xfb, 0x95, 0x07, 0x8b, 0x74, + 0x81, 0x85, 0x60, 0x88, 0x08, 0x73, 0xf7, 0x53, 0xa3, 0x07, 0xf8, 0xa0, + 0xfb, 0x65, 0x15, 0x7a, 0x92, 0x05, 0x7c, 0x75, 0x82, 0x86, 0x70, 0x8b, + 0x08, 0xfb, 0x0d, 0x8b, 0xe1, 0xe0, 0x05, 0xc8, 0xc7, 0xa2, 0xb4, 0x8b, + 0xbc, 0x8b, 0xca, 0x56, 0xb6, 0x3d, 0x8b, 0x63, 0x8b, 0x68, 0x7f, 0x74, + 0x74, 0x76, 0x78, 0x81, 0x78, 0x7b, 0x5d, 0x08, 0xa4, 0x7d, 0x05, 0xa1, + 0xbb, 0xa6, 0xa1, 0xb0, 0x8b, 0xb3, 0x8b, 0xac, 0x69, 0x8b, 0x61, 0x8b, + 0x6d, 0x6c, 0x56, 0x59, 0x55, 0x08, 0x29, 0x20, 0x8b, 0x74, 0xf7, 0x91, + 0x8b, 0x05, 0xb0, 0xe0, 0x05, 0x0e, 0xf8, 0x28, 0xf9, 0x62, 0xf7, 0x27, + 0x15, 0x54, 0xf7, 0x96, 0x5c, 0x06, 0xfb, 0x5f, 0xfb, 0x9e, 0x8b, 0x5a, + 0xf7, 0x48, 0x8b, 0x8b, 0x31, 0xd1, 0x8b, 0x8b, 0xe5, 0xc2, 0x8b, 0x05, + 0xc4, 0x07, 0xfb, 0x11, 0x16, 0xfb, 0x1b, 0x8b, 0xf7, 0x1b, 0xf7, 0x47, + 0x8b, 0xfb, 0x47, 0x05, 0xb7, 0xf8, 0xa5, 0x15, 0x5d, 0x8b, 0x05, 0xfc, + 0x59, 0xfd, 0x46, 0xbc, 0x8b, 0xf8, 0x56, 0xf9, 0x46, 0x05, 0xfc, 0x2d, + 0xfc, 0x12, 0x15, 0x5d, 0x8e, 0x80, 0x92, 0x8b, 0xa5, 0x08, 0x8b, 0xf7, + 0xeb, 0x7d, 0x8e, 0xfb, 0x0a, 0x54, 0x8b, 0x74, 0x05, 0xb0, 0x98, 0x8b, + 0x8b, 0x91, 0x8b, 0x08, 0x91, 0x8d, 0x85, 0x75, 0x1f, 0xfb, 0x95, 0x07, + 0x8b, 0x74, 0x81, 0x85, 0x60, 0x88, 0x08, 0x73, 0xf7, 0x53, 0xa3, 0x07, + 0x0e, 0xf8, 0x28, 0xf9, 0x62, 0xf7, 0x27, 0x15, 0x54, 0xf7, 0x96, 0x5c, + 0x06, 0xfb, 0x5f, 0xfb, 0x9e, 0x8b, 0x5a, 0xf7, 0x48, 0x8b, 0x8b, 0x31, + 0xd1, 0x8b, 0x8b, 0xe5, 0xc2, 0x8b, 0x05, 0xc4, 0x07, 0xfb, 0x11, 0x16, + 0xfb, 0x1b, 0x8b, 0xf7, 0x1b, 0xf7, 0x47, 0x8b, 0xfb, 0x47, 0x05, 0xb7, + 0xf8, 0xa5, 0x15, 0x5d, 0x8b, 0xfc, 0x59, 0xfd, 0x46, 0xbc, 0x8b, 0x05, + 0xf8, 0x56, 0xf9, 0x46, 0x05, 0xfc, 0xb3, 0xfb, 0x6c, 0x15, 0xa2, 0x8e, + 0x05, 0x97, 0x8d, 0xa4, 0x84, 0x9b, 0x82, 0xa6, 0x7c, 0x99, 0x72, 0x8b, + 0x6c, 0x8b, 0x62, 0x70, 0x70, 0x62, 0x8b, 0x78, 0x8b, 0x80, 0x8f, 0x75, + 0x9b, 0x79, 0x99, 0x7f, 0x90, 0x80, 0x8b, 0x08, 0x77, 0x7c, 0x7b, 0x76, + 0x6b, 0xaa, 0x79, 0xbf, 0xf7, 0x03, 0xde, 0xc5, 0xd9, 0x1f, 0x8b, 0xbf, + 0x6e, 0xb1, 0x51, 0xa2, 0x08, 0xb7, 0xaa, 0x9c, 0xa2, 0x8b, 0xa7, 0x8b, + 0xb9, 0x5b, 0xb0, 0x4f, 0x8b, 0x4d, 0x8b, 0x64, 0x70, 0x67, 0x47, 0x08, + 0xa4, 0x79, 0x05, 0xab, 0xb7, 0x9e, 0x98, 0xb0, 0x8b, 0xad, 0x8b, 0xa1, + 0x78, 0x8b, 0x6d, 0x8b, 0x67, 0x71, 0x75, 0x45, 0x73, 0x08, 0x6e, 0x07, + 0x0e, 0xf8, 0x32, 0xf8, 0xa7, 0xf7, 0x8b, 0x15, 0x6d, 0x4d, 0x69, 0x73, + 0x4f, 0x8b, 0x08, 0x33, 0x57, 0xcc, 0xf7, 0x03, 0xf7, 0x04, 0xbd, 0xca, + 0xe4, 0x1f, 0xca, 0x8b, 0xaf, 0x6d, 0x94, 0x50, 0x08, 0x9c, 0xd1, 0x06, + 0x8b, 0x92, 0x86, 0x92, 0x82, 0x8e, 0x69, 0x99, 0x64, 0x93, 0x6a, 0x8b, + 0x08, 0xfb, 0x18, 0x32, 0x3a, 0xfb, 0x0c, 0xfb, 0x06, 0xdc, 0x3f, 0xf7, + 0x0d, 0x1f, 0xc4, 0x8b, 0xd9, 0x9c, 0x8e, 0x98, 0x08, 0x9c, 0xd7, 0x7b, + 0x8b, 0x05, 0xfb, 0x25, 0xf8, 0x41, 0x15, 0xfb, 0x58, 0xfb, 0x2c, 0xfb, + 0x2b, 0xfb, 0x57, 0xfb, 0x54, 0xf7, 0x2c, 0xfb, 0x2c, 0xf7, 0x53, 0xf7, + 0x53, 0xf7, 0x2a, 0xf7, 0x2c, 0xf7, 0x54, 0xf7, 0x53, 0xfb, 0x2b, 0xf7, + 0x2f, 0xfb, 0x4d, 0x1f, 0x8a, 0x61, 0x15, 0xf7, 0x2c, 0xf7, 0x16, 0xfb, + 0x20, 0xfb, 0x37, 0xfb, 0x39, 0xfb, 0x16, 0xfb, 0x1e, 0xfb, 0x30, 0xfb, + 0x31, 0xfb, 0x17, 0xf7, 0x1e, 0xf7, 0x38, 0xf7, 0x3c, 0xf7, 0x17, 0xf7, + 0x1c, 0xf7, 0x35, 0x1f, 0x0e, 0xf8, 0x32, 0xf7, 0x6f, 0xf8, 0x8d, 0x15, + 0xbc, 0x86, 0x8b, 0x8b, 0x8b, 0x5f, 0x08, 0xfb, 0x85, 0x07, 0x8b, 0x60, + 0x8b, 0x8b, 0x5a, 0x86, 0x08, 0x7c, 0xf7, 0x36, 0x9a, 0x07, 0x5a, 0x90, + 0x8b, 0x8b, 0x8b, 0xb6, 0x08, 0xee, 0xbb, 0x07, 0xb0, 0x53, 0x8f, 0x84, + 0x96, 0x77, 0xa7, 0x58, 0xa3, 0x6f, 0x9c, 0x8b, 0x08, 0xcb, 0x93, 0x06, + 0x73, 0x9f, 0x73, 0xa5, 0x6f, 0xb2, 0x08, 0x52, 0xda, 0x05, 0xbf, 0xa0, + 0xa6, 0xae, 0x8b, 0xbb, 0x08, 0xc3, 0x5e, 0xaf, 0x45, 0x1e, 0xfb, 0x45, + 0x7c, 0x06, 0xf7, 0x05, 0x87, 0x15, 0xb4, 0x06, 0xba, 0xa3, 0x70, 0x57, + 0x52, 0x72, 0x6b, 0x5f, 0x1f, 0x60, 0xf7, 0x3c, 0x06, 0xbc, 0xf7, 0x43, + 0x15, 0xfb, 0x53, 0xfb, 0x2c, 0xfb, 0x2d, 0xfb, 0x55, 0xfb, 0x54, 0xf7, + 0x2c, 0xfb, 0x2c, 0xf7, 0x53, 0xf7, 0x50, 0xf7, 0x2d, 0xf7, 0x2c, 0xf7, + 0x4f, 0xf7, 0x5a, 0xfb, 0x29, 0xf7, 0x2d, 0xfb, 0x54, 0x1f, 0x61, 0x04, + 0xf7, 0x32, 0xf7, 0x14, 0xfb, 0x1d, 0xfb, 0x3f, 0xfb, 0x34, 0xfb, 0x18, + 0xfb, 0x1e, 0xfb, 0x2e, 0xfb, 0x31, 0xfb, 0x17, 0xf7, 0x1e, 0xf7, 0x38, + 0xf7, 0x3a, 0xf7, 0x17, 0xf7, 0x1e, 0xf7, 0x31, 0x1f, 0x0e, 0x2b, 0x0e, + 0xf7, 0x6e, 0xf8, 0x68, 0xf7, 0x00, 0x15, 0xcd, 0xf7, 0xaa, 0xfc, 0x8c, + 0x49, 0xf8, 0x4a, 0xfb, 0x68, 0x06, 0x0e, 0xfb, 0x26, 0xce, 0x7d, 0x15, + 0xcd, 0xf7, 0xa8, 0x49, 0xfb, 0xa8, 0x06, 0xf8, 0x32, 0x04, 0xcd, 0xf7, + 0xa8, 0x49, 0xfb, 0xa8, 0x06, 0x0e, 0xf8, 0x42, 0xf8, 0x56, 0x15, 0x33, + 0xfb, 0xe3, 0x06, 0x73, 0x63, 0x63, 0x74, 0x5d, 0x8b, 0x08, 0x57, 0x6b, + 0xae, 0xc4, 0x1f, 0xf7, 0xc6, 0x33, 0xfc, 0x20, 0x07, 0x8b, 0x75, 0x89, + 0x78, 0x81, 0x53, 0x84, 0x63, 0x86, 0x5f, 0x8b, 0x76, 0x08, 0x5f, 0x9c, + 0x71, 0xa8, 0xaa, 0x9a, 0xa5, 0xbe, 0x1e, 0x8b, 0xa7, 0x86, 0xa7, 0x7e, + 0xbf, 0x7e, 0xbd, 0x89, 0x95, 0x87, 0xb0, 0xa9, 0x58, 0xaf, 0x74, 0xbe, + 0x8b, 0xc2, 0x8b, 0xb5, 0xa7, 0xb3, 0xc9, 0x08, 0x8d, 0x4d, 0xa2, 0x6f, + 0xbb, 0x8b, 0xb1, 0x8b, 0xa2, 0x99, 0xac, 0xb6, 0x08, 0x93, 0x07, 0x74, + 0x76, 0x7f, 0x84, 0x7c, 0x8b, 0x08, 0x75, 0x81, 0x9e, 0xb9, 0x1f, 0xf7, + 0xfa, 0x07, 0x0e, 0xf8, 0x88, 0x14, 0xf7, 0xee, 0x15, 0x7d, 0x99, 0xf8, + 0x56, 0x95, 0xf7, 0x5e, 0x99, 0x06, 0x1e, 0x0a, 0x03, 0x96, 0x25, 0xff, + 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xa9, 0x0a, 0xa9, 0x93, 0x90, 0x95, 0x92, + 0x98, 0x0c, 0x0c, 0xe0, 0x0b, 0xd9, 0x92, 0x91, 0x97, 0x91, 0x91, 0x0c, + 0x0d, 0x8b, 0x0c, 0x0e +}; +const unsigned int fonts_NimbusRomNo9L_Regu_cff_len = 25264; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-ReguItal.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-ReguItal.cff.c new file mode 100644 index 00000000000..57a724026e4 --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusRomNo9L-ReguItal.cff.c @@ -0,0 +1,2306 @@ +const unsigned char fonts_NimbusRomNo9L_ReguItal_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x17, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x52, 0x6f, 0x6d, 0x4e, 0x6f, 0x39, 0x4c, 0x2d, 0x52, + 0x65, 0x67, 0x75, 0x49, 0x74, 0x61, 0x6c, 0x00, 0x01, 0x02, 0x00, 0x01, + 0x00, 0x38, 0xf8, 0x1f, 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, + 0x22, 0x03, 0xf8, 0x18, 0x04, 0x1e, 0xe1, 0x5a, 0x5f, 0x0c, 0x02, 0x1d, + 0x00, 0x4c, 0x9d, 0x09, 0x0d, 0xfb, 0x3d, 0xfb, 0x6d, 0xfa, 0x86, 0xfa, + 0x1c, 0x05, 0x1c, 0x01, 0x05, 0x0f, 0x1c, 0x00, 0x00, 0x10, 0x1c, 0x02, + 0xd6, 0x11, 0x1c, 0x00, 0x2d, 0x1c, 0x6b, 0xc1, 0x12, 0x00, 0x08, 0x02, + 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, + 0x00, 0x5f, 0x00, 0x80, 0x00, 0x92, 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, + 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, + 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, + 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, + 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, + 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x52, + 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x4e, 0x6f, 0x39, 0x20, 0x4c, 0x20, 0x52, + 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x49, 0x74, 0x61, 0x6c, 0x69, + 0x63, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x52, 0x6f, 0x6d, 0x61, + 0x6e, 0x20, 0x4e, 0x6f, 0x39, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, + 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, + 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, + 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, + 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, + 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, + 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, + 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, + 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, + 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, + 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, + 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, + 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, + 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, + 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, + 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, + 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, + 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, + 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, + 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, + 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, + 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, + 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, + 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, + 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, + 0x00, 0xae, 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, + 0x00, 0xb4, 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, + 0x00, 0xb9, 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, + 0x00, 0xbc, 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, + 0x00, 0xc2, 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, + 0x00, 0xc8, 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, + 0x00, 0xd1, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, + 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, + 0x00, 0xd9, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, + 0x00, 0xdf, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, + 0x01, 0x87, 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, + 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, + 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, + 0x00, 0x97, 0x00, 0xa0, 0x00, 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x05, 0x00, 0x45, 0x00, 0x87, 0x00, 0xe4, 0x01, 0x89, 0x02, + 0x58, 0x03, 0x20, 0x03, 0x4d, 0x03, 0x8b, 0x03, 0xc8, 0x04, 0xa7, 0x04, + 0xc4, 0x04, 0xf0, 0x05, 0x02, 0x05, 0x18, 0x05, 0x2c, 0x05, 0x7f, 0x05, + 0xdf, 0x06, 0x3b, 0x06, 0xb7, 0x06, 0xec, 0x07, 0x41, 0x07, 0xaa, 0x07, + 0xd2, 0x08, 0x50, 0x08, 0xba, 0x08, 0xe7, 0x09, 0x29, 0x09, 0x47, 0x09, + 0x60, 0x09, 0x7d, 0x09, 0xe0, 0x0a, 0x9d, 0x0a, 0xfb, 0x0b, 0x96, 0x0b, + 0xf9, 0x0c, 0x71, 0x0d, 0x0b, 0x0d, 0x93, 0x0e, 0x26, 0x0e, 0xb1, 0x0e, + 0xf2, 0x0f, 0x4b, 0x0f, 0xe3, 0x10, 0x39, 0x10, 0xc0, 0x11, 0x2c, 0x11, + 0x88, 0x12, 0x09, 0x12, 0xb7, 0x13, 0x41, 0x13, 0xd3, 0x14, 0x2a, 0x14, + 0xb1, 0x14, 0xff, 0x15, 0x7c, 0x16, 0x0c, 0x16, 0x88, 0x16, 0xcf, 0x17, + 0x01, 0x17, 0x14, 0x17, 0x45, 0x17, 0x62, 0x17, 0x6f, 0x17, 0x9c, 0x18, + 0x29, 0x18, 0x9c, 0x18, 0xf1, 0x19, 0x86, 0x19, 0xe7, 0x1a, 0x66, 0x1b, + 0x24, 0x1b, 0xb5, 0x1c, 0x2a, 0x1c, 0xa0, 0x1d, 0x26, 0x1d, 0x83, 0x1e, + 0x51, 0x1e, 0xdb, 0x1f, 0x27, 0x1f, 0xc1, 0x20, 0x35, 0x20, 0x94, 0x21, + 0x0f, 0x21, 0x7d, 0x22, 0x07, 0x22, 0x70, 0x23, 0x1a, 0x23, 0xc9, 0x24, + 0x5e, 0x24, 0xc3, 0x25, 0x27, 0x25, 0x33, 0x25, 0x97, 0x25, 0xd7, 0x26, + 0x18, 0x26, 0xb2, 0x27, 0x51, 0x27, 0x66, 0x28, 0x04, 0x28, 0x91, 0x29, + 0x56, 0x29, 0xc1, 0x29, 0xe5, 0x2a, 0x3c, 0x2a, 0xd3, 0x2b, 0x1f, 0x2b, + 0x69, 0x2c, 0x52, 0x2d, 0x41, 0x2d, 0x52, 0x2d, 0xf8, 0x2f, 0x06, 0x2f, + 0x1e, 0x2f, 0xb5, 0x2f, 0xcd, 0x2f, 0xf9, 0x30, 0x4f, 0x30, 0xa6, 0x31, + 0x35, 0x31, 0x75, 0x32, 0x8c, 0x32, 0xf0, 0x33, 0x15, 0x33, 0x3a, 0x33, + 0x54, 0x33, 0x93, 0x33, 0xa5, 0x33, 0xd6, 0x33, 0xee, 0x34, 0x1a, 0x34, + 0x45, 0x34, 0x85, 0x34, 0xca, 0x34, 0xfb, 0x35, 0x15, 0x35, 0x28, 0x35, + 0xe7, 0x36, 0x74, 0x36, 0xdb, 0x37, 0x74, 0x38, 0x50, 0x38, 0x8a, 0x39, + 0x43, 0x39, 0xa3, 0x3a, 0x14, 0x3a, 0xb0, 0x3b, 0x69, 0x3c, 0x2a, 0x3c, + 0xb2, 0x3d, 0x33, 0x3d, 0xb4, 0x3e, 0x2a, 0x3e, 0xc6, 0x3f, 0x4d, 0x3f, + 0xee, 0x40, 0x79, 0x41, 0x3d, 0x41, 0xf9, 0x42, 0xb5, 0x43, 0x67, 0x43, + 0xd2, 0x44, 0x36, 0x44, 0x9a, 0x44, 0xf3, 0x45, 0x9c, 0x46, 0x23, 0x46, + 0xa0, 0x47, 0x1d, 0x47, 0x90, 0x48, 0x2a, 0x48, 0xd3, 0x49, 0x84, 0x4a, + 0x2d, 0x4a, 0xd6, 0x4b, 0x75, 0x4c, 0x13, 0x4c, 0x71, 0x4c, 0xff, 0x4d, + 0xa5, 0x4e, 0x5b, 0x4f, 0x09, 0x4f, 0xb7, 0x50, 0x5b, 0x51, 0x25, 0x51, + 0xda, 0x52, 0x6d, 0x52, 0xf8, 0x53, 0x7b, 0x53, 0xff, 0x54, 0x78, 0x55, + 0x01, 0x55, 0x83, 0x56, 0x05, 0x56, 0x7c, 0x57, 0x42, 0x57, 0xb8, 0x58, + 0x25, 0x58, 0x92, 0x58, 0xf5, 0x59, 0x7e, 0x5a, 0x0f, 0x5a, 0xc3, 0x5b, + 0x70, 0x5c, 0x1c, 0x5c, 0xbd, 0x5d, 0x74, 0x5d, 0xf1, 0x5e, 0x6d, 0x5f, + 0x05, 0x5f, 0xc5, 0x60, 0x5b, 0x60, 0xb6, 0x61, 0x0b, 0x61, 0x7b, 0x61, + 0x93, 0x61, 0xa5, 0x61, 0xd0, 0x61, 0xdf, 0x62, 0x10, 0x62, 0x49, 0x62, + 0xe4, 0x63, 0x0a, 0x63, 0xcd, 0x64, 0x61, 0x65, 0x13, 0x65, 0xb3, 0x66, + 0x61, 0x66, 0x63, 0x66, 0x76, 0x66, 0x8c, 0x67, 0x15, 0x34, 0x0e, 0x34, + 0x0e, 0x87, 0xf7, 0x1d, 0xf7, 0x45, 0x15, 0xc4, 0xf7, 0x2f, 0xa2, 0xc6, + 0xba, 0xf1, 0xa7, 0xc9, 0x95, 0xab, 0x8b, 0xa8, 0x8b, 0xac, 0x7d, 0x9d, + 0x71, 0x8b, 0x66, 0x8b, 0x78, 0x6a, 0x7d, 0x38, 0x73, 0xfb, 0x24, 0x84, + 0x66, 0x62, 0xfb, 0x51, 0x08, 0x9c, 0x87, 0x05, 0x5d, 0x39, 0x15, 0x70, + 0x72, 0x72, 0x70, 0x6c, 0xa1, 0x74, 0xa8, 0xa9, 0xa4, 0xa3, 0xa7, 0xa8, + 0x72, 0xa4, 0x6e, 0x1f, 0x0e, 0xde, 0xf7, 0xec, 0xf8, 0x39, 0x15, 0xc4, + 0xf7, 0x10, 0xaa, 0xd7, 0x8b, 0x9b, 0x8b, 0x9b, 0x7d, 0x98, 0x79, 0x8b, + 0x73, 0x8b, 0x72, 0x78, 0x86, 0x75, 0x85, 0x72, 0x82, 0x3e, 0x83, 0x25, + 0x08, 0xa0, 0x06, 0xfb, 0x47, 0x16, 0xc5, 0xf7, 0x12, 0xa9, 0xd5, 0x8b, + 0x9b, 0x8b, 0x9b, 0x7d, 0x98, 0x7a, 0x8b, 0x72, 0x8b, 0x72, 0x78, 0x86, + 0x75, 0x85, 0x72, 0x82, 0x3e, 0x83, 0x25, 0x08, 0xa0, 0x06, 0x0e, 0xf8, + 0x65, 0xf7, 0x9f, 0x15, 0x2c, 0x8b, 0xc1, 0xf7, 0x23, 0xf4, 0x8b, 0x96, + 0xc1, 0x2b, 0x8b, 0xdb, 0xf7, 0x68, 0x4e, 0x8b, 0x3b, 0xfb, 0x68, 0xfb, + 0x16, 0x8b, 0xdb, 0xf7, 0x68, 0x4e, 0x8b, 0x3b, 0xfb, 0x68, 0x22, 0x8b, + 0x80, 0x55, 0xeb, 0x8b, 0x05, 0x55, 0xfb, 0x23, 0x22, 0x8b, 0x80, 0x55, + 0xea, 0x8b, 0x3b, 0xfb, 0x69, 0xc9, 0x8b, 0xda, 0xf7, 0x69, 0xf7, 0x16, + 0x8b, 0x3b, 0xfb, 0x69, 0xc9, 0x8b, 0xda, 0xf7, 0x69, 0xf4, 0x8b, 0x96, + 0xc1, 0x05, 0x25, 0xf7, 0x23, 0x15, 0x55, 0xfb, 0x23, 0xfb, 0x16, 0x8b, + 0xc1, 0xf7, 0x23, 0xf7, 0x16, 0x8b, 0x05, 0x0e, 0xf8, 0x85, 0xf8, 0xf8, + 0x15, 0x6b, 0xa2, 0x61, 0x9c, 0x5c, 0x96, 0x08, 0x9b, 0xcf, 0x69, 0x8b, + 0x7a, 0x4c, 0x05, 0x40, 0x8b, 0x70, 0x86, 0x62, 0x73, 0x5c, 0x70, 0x6f, + 0x5c, 0x8b, 0x57, 0x8b, 0x66, 0x97, 0x6d, 0xa9, 0x67, 0xa0, 0x70, 0x9f, + 0x7a, 0xbf, 0x66, 0x08, 0x46, 0xfb, 0xbd, 0x05, 0x3d, 0x9e, 0x71, 0xb0, + 0x80, 0xf4, 0x08, 0x7b, 0x88, 0x70, 0xfb, 0x0f, 0x05, 0xaf, 0x6d, 0xbf, + 0x74, 0xc9, 0x7f, 0x08, 0x75, 0x30, 0xae, 0x8b, 0xa0, 0xe4, 0x05, 0xd4, + 0x8e, 0xad, 0x92, 0xb2, 0x9f, 0xc6, 0xa9, 0xae, 0xc7, 0x8b, 0xd1, 0x8b, + 0xda, 0x72, 0xaf, 0xfb, 0x09, 0xe6, 0x08, 0xc3, 0xf7, 0x81, 0x05, 0xc8, + 0x73, 0xa1, 0x68, 0x8d, 0x41, 0x08, 0x9a, 0x89, 0xa7, 0xf7, 0x06, 0x05, + 0xfb, 0x6b, 0xfb, 0x54, 0x15, 0x4d, 0xb8, 0x78, 0xa7, 0x8b, 0xb8, 0x8b, + 0xb8, 0xa4, 0xae, 0xb5, 0x9a, 0x9e, 0x92, 0x94, 0x8c, 0xb3, 0x8b, 0x08, + 0x55, 0xfb, 0x71, 0x05, 0x92, 0xfb, 0x06, 0x15, 0x91, 0x86, 0x05, 0xcf, + 0x53, 0x9c, 0x6e, 0x8b, 0x55, 0x8b, 0x38, 0x56, 0x5d, 0x21, 0x83, 0x08, + 0xcf, 0xf7, 0xad, 0x05, 0x0e, 0xf8, 0x84, 0xf9, 0x3f, 0xf8, 0x07, 0x15, + 0x21, 0xfb, 0x01, 0xfb, 0x0b, 0xfb, 0x08, 0x35, 0xb7, 0x59, 0xd7, 0x1f, + 0xb7, 0x8b, 0xb3, 0x9d, 0xab, 0xac, 0xc1, 0xc4, 0xab, 0xda, 0x8b, 0xd7, + 0x08, 0xce, 0x63, 0xb4, 0x48, 0x1e, 0x96, 0x6b, 0x15, 0xb2, 0xab, 0x67, + 0x5f, 0x1f, 0x8b, 0x4c, 0x6b, 0x3e, 0x5b, 0x58, 0x75, 0x73, 0x6e, 0x7d, + 0x6e, 0x8b, 0x62, 0x8b, 0x77, 0xa3, 0x8b, 0xba, 0x8b, 0xbb, 0xa8, 0xde, + 0xad, 0xbb, 0xa6, 0xb3, 0xa7, 0x9e, 0xab, 0x8b, 0x08, 0x62, 0xf7, 0xe5, + 0x15, 0x63, 0x06, 0x59, 0x5a, 0x5f, 0x78, 0x48, 0x8b, 0x6b, 0x8b, 0x72, + 0x91, 0x7f, 0x96, 0x08, 0x79, 0x9b, 0x05, 0x7d, 0x97, 0x6f, 0x94, 0x71, + 0x8b, 0x08, 0xfb, 0x02, 0xfb, 0x00, 0xfb, 0x0c, 0xfb, 0x0f, 0x42, 0xbf, + 0x52, 0xce, 0x1f, 0xbe, 0x8b, 0xbb, 0xa5, 0xb1, 0xbb, 0xb2, 0xbd, 0xa8, + 0xd7, 0x8b, 0xbf, 0x8b, 0x98, 0x89, 0x9b, 0x87, 0x9c, 0x8b, 0x8e, 0x8b, + 0x8b, 0x8a, 0x8e, 0x9f, 0x83, 0x9a, 0x89, 0xa6, 0x8b, 0xb9, 0x8b, 0xa3, + 0x92, 0xb5, 0xa2, 0x08, 0xfb, 0xf2, 0xfd, 0x06, 0xba, 0x8b, 0xf8, 0x16, + 0xf9, 0x45, 0x05, 0xfb, 0xb1, 0x3f, 0x15, 0x92, 0x75, 0x8d, 0x7e, 0x8b, + 0x7b, 0x08, 0xfb, 0x05, 0x3a, 0xfb, 0x05, 0x39, 0x67, 0x74, 0xa3, 0xb2, + 0xf6, 0xde, 0xf7, 0x1f, 0xca, 0x1e, 0x8f, 0x8b, 0x8f, 0x89, 0x92, 0x85, + 0x9b, 0x7e, 0x94, 0x87, 0xa6, 0x84, 0x08, 0x0e, 0xf8, 0x4d, 0xf8, 0xa6, + 0xf7, 0xf2, 0x15, 0x78, 0x07, 0xb2, 0x88, 0x96, 0x84, 0x8b, 0x75, 0x8b, + 0x69, 0x7b, 0x6e, 0x4c, 0x3f, 0x6b, 0xbc, 0x6c, 0xe1, 0x73, 0xf1, 0xc9, + 0xaa, 0xa8, 0x9e, 0xa6, 0xa3, 0x08, 0xae, 0xab, 0x9e, 0xae, 0x8b, 0xad, + 0x08, 0xc0, 0x5f, 0xb4, 0x51, 0x2d, 0x49, 0x36, 0xfb, 0x0d, 0x1e, 0x8b, + 0x82, 0x8c, 0x7b, 0x8e, 0x71, 0x8c, 0x85, 0x8c, 0x81, 0x8c, 0x7c, 0x24, + 0x5e, 0x5f, 0x73, 0x67, 0x6e, 0x5b, 0x63, 0x73, 0x5d, 0x8b, 0x55, 0x8b, + 0x2a, 0xd2, 0x4e, 0xf7, 0x03, 0x8b, 0xca, 0x8b, 0xac, 0x98, 0xf2, 0xcd, + 0x08, 0xb8, 0x52, 0xb2, 0x75, 0xc0, 0x8b, 0xbd, 0x8b, 0xaf, 0x9e, 0xb6, + 0xbc, 0x08, 0x80, 0x96, 0x05, 0x6e, 0x75, 0x79, 0x83, 0x74, 0x8b, 0x5c, + 0x8b, 0x68, 0xa6, 0x63, 0xce, 0xb1, 0xbf, 0xb1, 0xc0, 0x96, 0x9c, 0xbe, + 0xd6, 0x92, 0x91, 0xbd, 0x90, 0x08, 0x9c, 0x07, 0xfb, 0x4d, 0x06, 0xfb, + 0x59, 0x86, 0x15, 0xaf, 0xfb, 0x13, 0xae, 0x36, 0xad, 0x60, 0x5c, 0x64, + 0x60, 0x7a, 0x59, 0x8b, 0x42, 0x8b, 0x54, 0xc4, 0x8b, 0xd4, 0x08, 0x8b, + 0xd3, 0xca, 0xd2, 0xef, 0xb1, 0x08, 0xd8, 0xde, 0x15, 0x87, 0xa9, 0x8a, + 0x9f, 0x8b, 0xa5, 0x08, 0xe3, 0xa1, 0xb5, 0xb8, 0x1e, 0xab, 0x98, 0x7a, + 0x63, 0x1f, 0x8b, 0x5e, 0x7e, 0x6d, 0x6c, 0x6e, 0x7a, 0x7c, 0x89, 0x89, + 0x5f, 0x6f, 0x08, 0x0e, 0x87, 0xf7, 0x34, 0xf8, 0x48, 0x15, 0xdf, 0xb9, + 0xb9, 0xc4, 0x8b, 0xc3, 0x08, 0xb3, 0x72, 0xaa, 0x6a, 0x6e, 0x75, 0x77, + 0x70, 0x1e, 0x8b, 0x7a, 0x91, 0x80, 0x9e, 0x7a, 0x99, 0x7d, 0x91, 0x82, + 0x8b, 0x81, 0x8b, 0x71, 0x74, 0x70, 0x57, 0x68, 0x08, 0x94, 0x7a, 0x05, + 0x0e, 0x87, 0xf7, 0x33, 0xfb, 0x43, 0x15, 0x67, 0xf0, 0x7f, 0xca, 0x8b, + 0xeb, 0x8b, 0xf7, 0x0c, 0xa8, 0xf7, 0x24, 0xb9, 0xf7, 0x03, 0xab, 0xda, + 0xab, 0xba, 0xcc, 0xcf, 0x08, 0x7e, 0x9a, 0x05, 0xfb, 0x16, 0xfb, 0x0a, + 0x58, 0x49, 0x61, 0x23, 0x71, 0x4c, 0x80, 0x4d, 0x8b, 0x3f, 0x8b, 0x3e, + 0x97, 0x40, 0xa1, 0x46, 0x99, 0x60, 0x9a, 0x6c, 0xaf, 0x49, 0x08, 0x9d, + 0x91, 0x05, 0x0e, 0x87, 0xa8, 0xfb, 0x48, 0x15, 0xf7, 0x10, 0xf7, 0x00, + 0xbe, 0xcb, 0xb8, 0xf7, 0x01, 0xa7, 0xcd, 0x97, 0xca, 0x8b, 0xd5, 0x8b, + 0xc4, 0x83, 0xcb, 0x7d, 0xc7, 0x7a, 0xcf, 0x7c, 0xaf, 0x5e, 0xdb, 0x08, + 0x78, 0x86, 0x05, 0xad, 0x3a, 0x9a, 0x3a, 0x8b, 0x27, 0x8b, 0xfb, 0x13, + 0x69, 0xfb, 0x36, 0x59, 0x20, 0x6e, 0x4a, 0x6d, 0x61, 0x4e, 0x4b, 0x08, + 0x98, 0x7c, 0x05, 0x0e, 0xf7, 0xd3, 0xf8, 0x88, 0x15, 0x8b, 0xa1, 0x8f, + 0xa0, 0x97, 0xad, 0x93, 0xa5, 0x8e, 0x98, 0x8b, 0x96, 0x08, 0xa2, 0x7c, + 0x9b, 0x76, 0x75, 0x7e, 0x7c, 0x72, 0x1e, 0x8b, 0x82, 0x8d, 0x82, 0x92, + 0x76, 0x98, 0x5e, 0x8f, 0x74, 0x8b, 0x60, 0x64, 0xa1, 0x77, 0x9c, 0x6b, + 0xaf, 0x77, 0xa2, 0x80, 0x92, 0x7b, 0x8b, 0x77, 0x8b, 0x7c, 0x7c, 0x8b, + 0x77, 0x8b, 0x70, 0x9a, 0x80, 0xb9, 0x83, 0x08, 0xb0, 0x84, 0xab, 0x81, + 0xa3, 0x7c, 0x08, 0x97, 0x84, 0x05, 0x60, 0x71, 0x79, 0x84, 0x5d, 0x83, + 0x61, 0x84, 0x7a, 0x7e, 0x8b, 0x74, 0x8b, 0x77, 0x9b, 0x7a, 0x9e, 0x8b, + 0x9c, 0x8b, 0x9c, 0x96, 0x9b, 0x9f, 0xa6, 0xad, 0x99, 0x97, 0xaa, 0x9e, + 0x94, 0x90, 0x8e, 0x8d, 0x8e, 0x8e, 0x08, 0x8d, 0x7a, 0x8b, 0x84, 0x8b, + 0x86, 0x8b, 0x75, 0x86, 0x73, 0x7d, 0x66, 0x84, 0x77, 0x88, 0x7f, 0x8b, + 0x82, 0x08, 0x75, 0x9a, 0x7b, 0x9f, 0xa2, 0x9b, 0x9c, 0xa2, 0x1e, 0x8b, + 0x93, 0x89, 0x93, 0x85, 0x9d, 0x7c, 0xb5, 0x87, 0xa1, 0x8a, 0xc0, 0x08, + 0x92, 0x87, 0x05, 0xac, 0x78, 0xa2, 0x77, 0xa5, 0x6b, 0x9e, 0x73, 0x97, + 0x83, 0x9a, 0x8b, 0xa0, 0x8b, 0x9c, 0x9c, 0x8b, 0xa1, 0x8b, 0xa2, 0x7a, + 0x97, 0x5f, 0x92, 0x6f, 0x90, 0x74, 0x92, 0x7c, 0x93, 0x08, 0x66, 0x9e, + 0x05, 0xb6, 0xa6, 0x9c, 0x92, 0xba, 0x93, 0xb5, 0x92, 0x9a, 0x96, 0x8b, + 0xa5, 0x8b, 0xa1, 0x7b, 0x9a, 0x75, 0x8b, 0x7e, 0x8b, 0x83, 0x87, 0x7c, + 0x7a, 0x58, 0x54, 0x86, 0x87, 0x60, 0x6e, 0x08, 0xa6, 0x07, 0x0e, 0xf7, + 0xe6, 0xf7, 0xc5, 0xf7, 0xb2, 0x15, 0xfb, 0x6f, 0x49, 0xf7, 0x6f, 0xfb, + 0x70, 0xcd, 0xf7, 0x70, 0xf7, 0x6f, 0xcd, 0xfb, 0x6f, 0xf7, 0x70, 0x49, + 0xfb, 0x70, 0x06, 0x0e, 0x34, 0x90, 0xfb, 0x15, 0x15, 0xdf, 0xba, 0xb9, + 0xc3, 0x8b, 0xc3, 0x08, 0xb3, 0x72, 0xaa, 0x6a, 0x6e, 0x75, 0x77, 0x70, + 0x1e, 0x8b, 0x7a, 0x91, 0x80, 0x9e, 0x7a, 0x9a, 0x7d, 0x90, 0x83, 0x8b, + 0x81, 0x8b, 0x70, 0x74, 0x70, 0x57, 0x68, 0x08, 0x94, 0x7a, 0x05, 0x0e, + 0x87, 0xf7, 0xae, 0xf7, 0x93, 0x15, 0xfb, 0x6f, 0x8b, 0x7d, 0x4c, 0xf7, + 0x70, 0x8b, 0x98, 0xca, 0x05, 0x0e, 0x34, 0xdd, 0xef, 0x15, 0x6d, 0x72, + 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa7, 0xab, 0xa5, 0xa3, 0xa9, 0xaa, 0x71, + 0xa5, 0x6d, 0x1f, 0x0e, 0x50, 0xf7, 0xcd, 0xf9, 0x2e, 0x15, 0xfc, 0x0e, + 0xfd, 0x40, 0xd4, 0x8b, 0xf8, 0x0e, 0xf9, 0x40, 0x42, 0x8b, 0x05, 0x0e, + 0xf7, 0xe9, 0xf9, 0x38, 0x15, 0xfb, 0x31, 0xfb, 0x2c, 0xfb, 0x78, 0xfb, + 0x7f, 0xfb, 0x18, 0xcb, 0x33, 0xec, 0x1f, 0xb6, 0x8b, 0xb5, 0x9a, 0xb5, + 0xaa, 0xef, 0xd5, 0xd8, 0xf7, 0x3a, 0x8b, 0xf7, 0x24, 0x08, 0xf7, 0x32, + 0x50, 0xea, 0x2a, 0x1e, 0x84, 0x6f, 0x15, 0xc1, 0xa9, 0x5d, 0x3b, 0x1f, + 0x8b, 0xfb, 0x1a, 0x63, 0xfb, 0x39, 0x52, 0x25, 0x65, 0x49, 0x62, 0x69, + 0x5e, 0x8b, 0x55, 0x8b, 0x6b, 0xbd, 0x8b, 0xe0, 0x8b, 0xf5, 0xbf, 0xf7, + 0x5b, 0xbf, 0xe7, 0xaf, 0xcb, 0xb2, 0xaa, 0xb7, 0x8b, 0x08, 0x0e, 0xbc, + 0x16, 0xf7, 0xab, 0x9a, 0x7b, 0x06, 0x5a, 0x76, 0x95, 0xa1, 0x1f, 0x8b, + 0x94, 0x8f, 0x9d, 0x93, 0xa4, 0x8d, 0x93, 0x8d, 0x91, 0x8c, 0x8e, 0x08, + 0x8c, 0x90, 0xf7, 0x23, 0xf8, 0x9b, 0x05, 0x8f, 0x9a, 0x8d, 0x94, 0x8b, + 0x90, 0x8b, 0x8f, 0x89, 0x8e, 0x88, 0x8b, 0x8b, 0x8b, 0x89, 0x8b, 0x8a, + 0x8a, 0x08, 0x3c, 0x7c, 0x31, 0x79, 0x05, 0x89, 0x8b, 0x83, 0x89, 0x80, + 0x89, 0x08, 0x8b, 0x7c, 0xc4, 0x8d, 0x05, 0xa2, 0x8c, 0x9a, 0x7f, 0x8b, + 0x77, 0x8b, 0x85, 0x89, 0x81, 0x86, 0x79, 0x08, 0xfb, 0x1e, 0xfc, 0x80, + 0x05, 0x7f, 0x66, 0x76, 0x81, 0x3c, 0x84, 0x08, 0x7d, 0x07, 0x0e, 0xf8, + 0x24, 0xf7, 0x1f, 0x15, 0x73, 0x59, 0x76, 0x7e, 0x55, 0x8b, 0x08, 0xfb, + 0x52, 0x90, 0x06, 0xf7, 0x54, 0xf7, 0x54, 0x05, 0xf7, 0x09, 0xf7, 0x09, + 0xab, 0xbd, 0x8b, 0xcd, 0x8b, 0xeb, 0x44, 0xd5, 0x30, 0x8b, 0x68, 0x8b, + 0x65, 0x81, 0x6d, 0x7b, 0x58, 0x6f, 0x70, 0x69, 0x6e, 0x43, 0x08, 0xa0, + 0x84, 0x05, 0xb0, 0xcc, 0xb6, 0xa8, 0xc7, 0x8b, 0xd2, 0x8b, 0xc1, 0x57, + 0x8b, 0x45, 0x8b, 0x76, 0x88, 0x78, 0x85, 0x7e, 0x73, 0x55, 0x5e, 0x4c, + 0x49, 0x45, 0x08, 0xfb, 0x66, 0xfb, 0x74, 0x8b, 0x7a, 0xf7, 0xf7, 0x8b, + 0xbd, 0xf7, 0x18, 0x7a, 0x92, 0x05, 0x0e, 0xf7, 0x46, 0xf8, 0xcb, 0x15, + 0xae, 0xb9, 0xae, 0xa0, 0xb5, 0x8b, 0xc0, 0x8b, 0xaf, 0x66, 0x8b, 0x55, + 0x8b, 0x61, 0x76, 0x67, 0x5f, 0x6e, 0x61, 0x6e, 0x60, 0x7c, 0x32, 0x7c, + 0x08, 0x7b, 0x07, 0xc0, 0x8b, 0x98, 0x8a, 0xa5, 0x81, 0x08, 0xc8, 0x76, + 0xac, 0x54, 0x8b, 0x3c, 0x8b, 0x67, 0x83, 0x67, 0x7d, 0x73, 0x74, 0x63, + 0x5d, 0x6f, 0x63, 0x8b, 0x78, 0x8b, 0x74, 0x95, 0x6d, 0xa1, 0x6e, 0xa0, + 0x7b, 0x92, 0x78, 0x8b, 0x08, 0x6f, 0x7b, 0x7d, 0x72, 0x65, 0xb4, 0x76, + 0xd2, 0x1f, 0xc4, 0x8b, 0xbd, 0x97, 0xb6, 0xa4, 0xda, 0xb9, 0xbd, 0xdf, + 0x8b, 0xe4, 0x8b, 0xd3, 0x6e, 0xb9, 0x48, 0xaa, 0x08, 0x8e, 0x07, 0xf7, + 0x0d, 0xba, 0xae, 0xac, 0x8b, 0xcf, 0x8b, 0xd4, 0x4f, 0xc1, 0x3b, 0x8b, + 0x46, 0x8b, 0x4d, 0x63, 0x6a, 0x4b, 0x08, 0x9b, 0x86, 0x05, 0x0e, 0xf8, + 0x59, 0xf7, 0x85, 0x15, 0x2c, 0x8b, 0xf7, 0x0d, 0xf8, 0x47, 0x62, 0x8b, + 0xfc, 0x35, 0xfc, 0x43, 0x77, 0x48, 0xf7, 0x9a, 0x8b, 0x5a, 0xfb, 0x46, + 0xda, 0x8b, 0xb9, 0xf7, 0x44, 0xef, 0x8b, 0x99, 0xcc, 0x05, 0xfb, 0x44, + 0x16, 0xfb, 0x68, 0x8f, 0x06, 0xf7, 0xc4, 0xf7, 0xd2, 0x8f, 0x8b, 0x2b, + 0xfb, 0xd6, 0x05, 0x0e, 0xf7, 0x82, 0xf8, 0xe7, 0x15, 0xf7, 0x7a, 0x8b, + 0xa2, 0xd2, 0xfb, 0x94, 0x8b, 0x23, 0xfb, 0x6e, 0x8b, 0x7c, 0x05, 0xec, + 0x76, 0xac, 0x7f, 0xaf, 0x6e, 0xab, 0x71, 0xa0, 0x59, 0x8b, 0x56, 0x8b, + 0xfb, 0x01, 0x3a, 0x29, 0x31, 0x8b, 0x76, 0x8b, 0x79, 0x93, 0x6e, 0xa0, + 0x72, 0x9e, 0x7c, 0x92, 0x7c, 0x8b, 0x08, 0x73, 0x7a, 0x7b, 0x73, 0x68, + 0xb3, 0x75, 0xcd, 0xf7, 0x39, 0xf7, 0x19, 0xf7, 0x14, 0xf7, 0x33, 0x1f, + 0x8b, 0xc9, 0x74, 0xc0, 0x60, 0xb4, 0x66, 0xae, 0x67, 0x9b, 0x3a, 0x9f, + 0x08, 0xb2, 0xe3, 0x05, 0x0e, 0xf8, 0x9d, 0xf9, 0x42, 0x15, 0xfb, 0x1a, + 0x7c, 0x48, 0x72, 0x35, 0x4c, 0xfb, 0x13, 0x2d, 0x3e, 0xfb, 0x22, 0x8b, + 0xfb, 0x23, 0x08, 0xfb, 0x14, 0xd3, 0x38, 0xf7, 0x03, 0xf7, 0x1b, 0xf7, + 0x06, 0xf7, 0x13, 0xf7, 0x2b, 0xf1, 0x44, 0xd5, 0x28, 0x1e, 0x6f, 0x8b, + 0x6a, 0x83, 0x6f, 0x7e, 0x08, 0x87, 0x8d, 0x05, 0xd1, 0xf7, 0x13, 0xf7, + 0x1a, 0xf0, 0xf7, 0x0a, 0x99, 0x08, 0x9b, 0x07, 0xfb, 0x9a, 0xfb, 0xa7, + 0x15, 0xd1, 0xb7, 0x59, 0x3e, 0x1f, 0x8b, 0x47, 0x73, 0x3c, 0x66, 0x57, + 0x6c, 0x5e, 0x68, 0x76, 0x60, 0x8b, 0x4e, 0x8b, 0x67, 0xbc, 0x8b, 0xdd, + 0x8b, 0xce, 0x9f, 0xdf, 0xa5, 0xb7, 0xa7, 0xb9, 0xab, 0x9f, 0xba, 0x8b, + 0x08, 0x0e, 0xf8, 0xad, 0xf9, 0x24, 0x15, 0x85, 0x95, 0xfc, 0x0b, 0x8b, + 0x3a, 0xfb, 0x1c, 0x99, 0x82, 0x05, 0xbb, 0xc4, 0xa6, 0x9a, 0xc5, 0x8b, + 0x08, 0xf7, 0x72, 0x8b, 0x8d, 0x88, 0xfc, 0x03, 0xfc, 0xea, 0xd1, 0x8b, + 0xf8, 0x18, 0xf9, 0x2c, 0x05, 0x0e, 0xf7, 0xdd, 0xf8, 0x12, 0x15, 0xf7, + 0x0a, 0xb2, 0xb9, 0xb6, 0x8b, 0xd2, 0x08, 0xdd, 0x42, 0xc6, 0x25, 0x20, + 0x42, 0x4e, 0x32, 0x1e, 0x8b, 0x55, 0xa0, 0x64, 0xcd, 0x42, 0xfb, 0x12, + 0x62, 0x46, 0x45, 0x8b, 0x33, 0x8b, 0x70, 0x93, 0x6d, 0x9a, 0x72, 0xac, + 0x52, 0xc7, 0x6e, 0xde, 0x8b, 0x08, 0xf7, 0x0f, 0xe7, 0xd8, 0xf2, 0x1f, + 0x8b, 0xce, 0x6d, 0xc1, 0x36, 0xe3, 0x08, 0x39, 0x65, 0x15, 0xf7, 0x02, + 0xfb, 0x07, 0x97, 0x79, 0x8b, 0x53, 0x08, 0x3a, 0x51, 0x50, 0x3d, 0x3c, + 0x53, 0xc6, 0xdc, 0x1e, 0x8b, 0xd6, 0xbd, 0xd1, 0xd8, 0xae, 0x8f, 0x8d, + 0x8b, 0x8b, 0x9d, 0x92, 0x08, 0xcb, 0xc2, 0x15, 0x3d, 0xd4, 0x7a, 0xa5, + 0x8b, 0xb5, 0x08, 0xd1, 0xb2, 0xb6, 0xca, 0x1e, 0xcb, 0xb6, 0x5b, 0x45, + 0x1f, 0x8b, 0x56, 0x72, 0x65, 0x53, 0x6e, 0x08, 0x6a, 0x7b, 0x05, 0x0e, + 0xa2, 0x7a, 0x15, 0xf7, 0x1b, 0xa2, 0xce, 0xa6, 0xde, 0xcc, 0xf7, 0x08, + 0xe6, 0xcf, 0xf7, 0x1a, 0x8b, 0xf7, 0x1b, 0x08, 0xf7, 0x17, 0x43, 0xe2, + 0xfb, 0x01, 0xfb, 0x12, 0xfb, 0x08, 0xfb, 0x14, 0xfb, 0x20, 0x23, 0xc9, + 0x40, 0xe3, 0x1e, 0xb4, 0x8b, 0xaf, 0x97, 0xbf, 0xac, 0x08, 0x8f, 0x89, + 0x05, 0x7b, 0x5e, 0x59, 0x4a, 0x4d, 0x52, 0x43, 0x4e, 0x59, 0x71, 0x3c, + 0x7a, 0x08, 0x79, 0x07, 0xf7, 0xbb, 0xf9, 0x2f, 0x15, 0xc9, 0xb0, 0x5a, + 0x38, 0x1f, 0x8b, 0x3d, 0x72, 0x2e, 0x6d, 0x6e, 0x71, 0x71, 0x62, 0x7a, + 0x65, 0x8b, 0x4c, 0x8b, 0x66, 0xbe, 0x8b, 0xe3, 0x8b, 0xd5, 0xa8, 0xdb, + 0xb6, 0xb7, 0xa3, 0xa4, 0xaa, 0x98, 0xad, 0x8b, 0x08, 0x0e, 0x87, 0xf5, + 0xef, 0x15, 0x6c, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xab, 0xa4, + 0xa3, 0xa9, 0x1f, 0xaa, 0x72, 0xa5, 0x6d, 0x1e, 0xee, 0xf7, 0xe9, 0x15, + 0x6c, 0x73, 0x72, 0x6b, 0x6d, 0xa3, 0x73, 0xa9, 0xab, 0xa4, 0xa3, 0xa9, + 0x1f, 0xab, 0x72, 0xa4, 0x6c, 0x1e, 0x0e, 0x87, 0xaf, 0xfb, 0x15, 0x15, + 0xdf, 0xba, 0xb9, 0xc3, 0x8b, 0xc3, 0x08, 0xb3, 0x72, 0xaa, 0x6a, 0x6e, + 0x75, 0x77, 0x70, 0x1e, 0x8b, 0x7a, 0x91, 0x80, 0x9e, 0x7a, 0x9a, 0x7d, + 0x90, 0x83, 0x8b, 0x81, 0x8b, 0x70, 0x74, 0x70, 0x57, 0x68, 0x08, 0x94, + 0x7a, 0x05, 0xf7, 0x3d, 0xf8, 0xce, 0x15, 0x6c, 0x73, 0x72, 0x6b, 0x6d, + 0xa3, 0x73, 0xa9, 0xab, 0xa4, 0xa3, 0xa9, 0xab, 0x72, 0xa4, 0x6c, 0x1f, + 0x0e, 0xf7, 0xe6, 0xf8, 0xe4, 0x81, 0x15, 0x8b, 0xd3, 0xfc, 0x38, 0xf7, + 0x53, 0xf8, 0x38, 0xf7, 0x53, 0x8b, 0xd3, 0xfc, 0x90, 0xfb, 0x7a, 0x8b, + 0x49, 0xf8, 0x90, 0xfb, 0x7a, 0x05, 0x0e, 0xf7, 0xe6, 0xf8, 0xe2, 0xf8, + 0x16, 0x15, 0xfc, 0x8c, 0x49, 0xf8, 0x8c, 0xcd, 0x06, 0xfb, 0x5c, 0x04, + 0xfc, 0x8c, 0x49, 0xf8, 0x8c, 0xcd, 0x06, 0x0e, 0xf7, 0xe6, 0xdf, 0x81, + 0x15, 0xf8, 0x90, 0xf7, 0x7a, 0x8b, 0xcd, 0xfc, 0x90, 0xf7, 0x7a, 0x8b, + 0x43, 0xf8, 0x38, 0xfb, 0x53, 0xfc, 0x38, 0xfb, 0x53, 0x8b, 0x43, 0x05, + 0x0e, 0xf7, 0x6c, 0xf7, 0x42, 0x15, 0x92, 0xa8, 0x05, 0x99, 0xc3, 0xa9, + 0xb1, 0xd2, 0xc4, 0xf7, 0x06, 0xe8, 0x9f, 0xa6, 0x8b, 0xc8, 0x08, 0xd9, + 0x50, 0xbe, 0x32, 0x39, 0x51, 0x5e, 0x4b, 0x6d, 0x9a, 0x79, 0xa3, 0xa2, + 0x9c, 0x9a, 0x9f, 0x1e, 0x8b, 0x92, 0x89, 0x91, 0x86, 0x97, 0x85, 0x98, + 0x89, 0x91, 0x8b, 0x93, 0x08, 0xa9, 0xa6, 0x9d, 0xb6, 0xbe, 0xa8, 0x6c, + 0x55, 0x1e, 0x8b, 0x57, 0x75, 0x61, 0x4a, 0x44, 0x38, 0x2c, 0x7f, 0x75, + 0x7a, 0x28, 0x08, 0x9c, 0x89, 0x05, 0x6b, 0x3a, 0x15, 0x6e, 0x74, 0x73, + 0x6e, 0x6e, 0xa2, 0x74, 0xa9, 0xa6, 0xa4, 0xa4, 0xa6, 0x1f, 0xa8, 0x73, + 0xa3, 0x6e, 0x1e, 0x0e, 0xf8, 0xdb, 0xf8, 0xdf, 0xf8, 0x55, 0x15, 0x75, + 0xb4, 0x7d, 0x95, 0x68, 0x8b, 0x61, 0x8b, 0x62, 0x79, 0x6d, 0x6b, 0x58, + 0x57, 0x6c, 0x3e, 0x8b, 0x44, 0x8b, 0x4c, 0xb2, 0x5b, 0xbd, 0x8b, 0xb5, + 0x8b, 0xb8, 0xa5, 0xaf, 0xb8, 0x08, 0x91, 0x60, 0xaf, 0x6e, 0xba, 0x8b, + 0x08, 0xee, 0xe0, 0xf7, 0x02, 0xf7, 0x14, 0xf7, 0x37, 0xfb, 0x22, 0xf7, + 0x13, 0xfb, 0x4b, 0xfb, 0x5f, 0xfb, 0x34, 0xfb, 0x2e, 0xfb, 0x55, 0xfb, + 0x51, 0xf7, 0x34, 0xfb, 0x28, 0xf7, 0x60, 0x1f, 0xd2, 0x8b, 0xbe, 0x98, + 0xe9, 0xb7, 0x08, 0x7f, 0xa8, 0x05, 0x3d, 0x68, 0x5a, 0x7f, 0x4a, 0x8b, + 0x08, 0xfb, 0x3f, 0xfb, 0x0e, 0xf7, 0x0d, 0xf7, 0x3f, 0xf7, 0x4f, 0xf7, + 0x09, 0xf7, 0x1b, 0xf7, 0x37, 0xf7, 0x30, 0xf7, 0x15, 0xfb, 0x0e, 0xfb, + 0x26, 0x1f, 0x8b, 0x4f, 0x72, 0x49, 0x66, 0x64, 0x78, 0x78, 0x72, 0x7f, + 0x72, 0x8b, 0x73, 0x8b, 0x7e, 0x9a, 0x8b, 0xa6, 0x8b, 0x90, 0x8c, 0x94, + 0x8d, 0x92, 0x08, 0xcc, 0xf7, 0x90, 0x46, 0x8b, 0x05, 0x81, 0x66, 0x05, + 0x52, 0x92, 0x15, 0xa6, 0x89, 0x9a, 0x74, 0x89, 0x66, 0x85, 0xfb, 0x05, + 0x52, 0x27, 0x53, 0x8b, 0x66, 0x8b, 0x75, 0xab, 0x8b, 0xbf, 0x8b, 0xc0, + 0x9d, 0xbd, 0xac, 0xb1, 0x08, 0xa7, 0xab, 0xae, 0x9f, 0xa3, 0x89, 0x08, + 0x0e, 0xf7, 0xa6, 0xf8, 0xc8, 0x9b, 0x15, 0x52, 0x90, 0x85, 0x93, 0x7e, + 0xd4, 0x08, 0x2d, 0xf8, 0xca, 0x71, 0x8b, 0xfb, 0xb6, 0xfc, 0x88, 0x05, + 0x3c, 0xfb, 0x19, 0x81, 0x80, 0x63, 0x83, 0x08, 0x7b, 0xf7, 0x4f, 0x9b, + 0x07, 0x58, 0x90, 0x83, 0x90, 0x8b, 0xa4, 0x8b, 0x9e, 0x8e, 0x94, 0x9c, + 0xad, 0x08, 0xc4, 0xf7, 0x05, 0xf7, 0x70, 0x8b, 0x9f, 0xfb, 0x17, 0x05, + 0x8c, 0x82, 0x8c, 0x82, 0x8b, 0x83, 0x8b, 0x65, 0x7d, 0x82, 0x4b, 0x85, + 0x08, 0x7b, 0xf7, 0x8a, 0x9b, 0x07, 0xfc, 0x19, 0xf7, 0x8a, 0x15, 0xf7, + 0x2a, 0xf7, 0x98, 0xb7, 0xfb, 0x98, 0xfb, 0x56, 0x8b, 0x05, 0x0e, 0xf7, + 0xa6, 0x83, 0x16, 0xf7, 0xae, 0x06, 0xf7, 0x31, 0xf7, 0x00, 0xdd, 0xf7, + 0x0a, 0x1f, 0x8b, 0xb0, 0x7f, 0xae, 0x75, 0xa1, 0x77, 0xa2, 0x77, 0x97, + 0x57, 0xa1, 0xd2, 0x9c, 0xa8, 0x97, 0xab, 0xa7, 0x08, 0xa7, 0xa3, 0x9a, + 0xad, 0x8b, 0xb3, 0x08, 0xea, 0x44, 0xbf, 0xfb, 0x15, 0x1e, 0xfb, 0x96, + 0x7b, 0x06, 0xc9, 0x86, 0x9a, 0x83, 0x8b, 0x6f, 0x8b, 0x7c, 0x87, 0x72, + 0x84, 0x73, 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x79, 0x51, 0x84, 0x85, + 0x53, 0x81, 0x08, 0x7b, 0x07, 0xf7, 0x8a, 0xf7, 0xdf, 0x15, 0xcc, 0x8b, + 0xb5, 0x87, 0x9f, 0x83, 0xb4, 0x7a, 0xa4, 0x5f, 0x8b, 0x55, 0x08, 0xfb, + 0x00, 0x41, 0x49, 0xfb, 0x0e, 0x61, 0x75, 0x9a, 0xa6, 0x1e, 0x8b, 0x97, + 0x97, 0xbb, 0xa2, 0xdb, 0x08, 0x98, 0xb8, 0x91, 0xa2, 0x98, 0xbe, 0x08, + 0xd6, 0xf7, 0x9c, 0x15, 0x91, 0xa1, 0x97, 0x91, 0xb2, 0x8b, 0xdb, 0x8b, + 0xb0, 0x69, 0x8b, 0x41, 0x8b, 0x52, 0x73, 0x5f, 0x60, 0x73, 0x69, 0x77, + 0x5b, 0x84, 0x31, 0x8b, 0x08, 0xcc, 0xf7, 0x7c, 0x05, 0x0e, 0xf7, 0xde, + 0xf9, 0x20, 0xf8, 0x65, 0x15, 0xb0, 0xf7, 0x5b, 0x76, 0x8b, 0x05, 0x83, + 0x7b, 0x81, 0x85, 0x77, 0x8b, 0x83, 0x8b, 0x7f, 0x8d, 0x76, 0x90, 0x5e, + 0x96, 0x63, 0x91, 0x6b, 0x8b, 0x08, 0xfb, 0x69, 0xfb, 0x55, 0xfb, 0x5d, + 0xfb, 0x72, 0xfb, 0x2d, 0xf7, 0x00, 0xfb, 0x00, 0xf7, 0x2d, 0x1f, 0xf2, + 0x8b, 0xdb, 0xb7, 0xe5, 0xf4, 0x08, 0x7a, 0x99, 0x05, 0x31, 0x33, 0x51, + 0x6d, 0x39, 0x8b, 0xfb, 0x03, 0x8b, 0x4b, 0xd7, 0x8b, 0xf7, 0x15, 0x8b, + 0xf7, 0x0b, 0xbb, 0xf7, 0x0d, 0xd9, 0xdc, 0xbb, 0xbc, 0xca, 0xa7, 0xcd, + 0x8b, 0xe7, 0x8b, 0xbe, 0x55, 0x95, 0xfb, 0x00, 0x08, 0x9d, 0x88, 0x05, + 0x0e, 0xf8, 0x15, 0xf7, 0x16, 0xf9, 0x11, 0x15, 0xc9, 0x85, 0x9a, 0x83, + 0x8b, 0x70, 0x8b, 0x7c, 0x87, 0x73, 0x84, 0x72, 0x08, 0xfb, 0x0f, 0xfc, + 0x4e, 0x05, 0x79, 0x51, 0x84, 0x85, 0x53, 0x81, 0x08, 0x7b, 0xf7, 0x91, + 0x07, 0xf7, 0x09, 0x8b, 0xf6, 0xaa, 0xd8, 0xc3, 0xec, 0xd2, 0xc4, 0xf7, + 0x02, 0x8b, 0xf7, 0x08, 0x08, 0xf7, 0x38, 0xfb, 0x06, 0xf4, 0xfb, 0x46, + 0x1e, 0xfb, 0xaa, 0x7b, 0x06, 0xf7, 0x4b, 0x60, 0x15, 0x91, 0xa1, 0x9a, + 0x92, 0xb3, 0x8b, 0xc4, 0x8b, 0xbd, 0x7e, 0xab, 0x73, 0xbc, 0x67, 0xa6, + 0x4c, 0x8b, 0x3c, 0x8b, 0xfb, 0x00, 0x61, 0xfb, 0x04, 0x47, 0x47, 0x50, + 0x4f, 0x3a, 0x6d, 0x23, 0x8b, 0x5d, 0x8b, 0x78, 0x96, 0x8b, 0xa5, 0x08, + 0x8b, 0x98, 0x90, 0xa1, 0x9c, 0xc7, 0x08, 0xf7, 0x0d, 0xf8, 0x44, 0x05, + 0x0e, 0xf7, 0xa6, 0xf9, 0x0e, 0xf9, 0x21, 0x15, 0xfc, 0x85, 0x7b, 0x06, + 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x70, 0x8b, 0x80, 0x85, 0x68, 0x86, 0x79, + 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x7a, 0x52, 0x83, 0x84, 0x53, 0x81, + 0x08, 0x7b, 0xf8, 0x8f, 0x07, 0xc9, 0xf7, 0x36, 0x7b, 0x93, 0x05, 0x5c, + 0x4b, 0x71, 0x71, 0x60, 0x77, 0x66, 0x7a, 0x47, 0x81, 0x40, 0x8b, 0x53, + 0x8b, 0x73, 0x95, 0x8b, 0xa3, 0x8b, 0x96, 0x96, 0xba, 0xa4, 0xe3, 0x98, + 0xb7, 0x94, 0xac, 0x95, 0xb1, 0xae, 0x89, 0xaa, 0x8a, 0x97, 0x8b, 0x08, + 0xb2, 0x8c, 0xa7, 0x85, 0x96, 0x81, 0x90, 0x86, 0x8d, 0x82, 0x8b, 0x7a, + 0x8b, 0x7a, 0x89, 0x7e, 0x86, 0x75, 0x08, 0x9f, 0x86, 0xcf, 0xf7, 0x7c, + 0x79, 0x8f, 0x05, 0x65, 0x36, 0x82, 0x85, 0x30, 0x87, 0x7f, 0x8b, 0x6b, + 0x8a, 0x68, 0x8a, 0x08, 0xcd, 0xf7, 0x7d, 0x05, 0x91, 0xa1, 0x96, 0x8f, + 0xc3, 0x8b, 0xf7, 0x31, 0x8b, 0xae, 0x7e, 0x8b, 0x4f, 0x8b, 0x7e, 0x8a, + 0x7c, 0x8a, 0x7a, 0x08, 0xa0, 0x89, 0xaa, 0xf7, 0x2d, 0x05, 0x0e, 0xf7, + 0xa6, 0xf9, 0x19, 0xf9, 0x21, 0x15, 0xfc, 0x86, 0x7b, 0x06, 0xcc, 0x85, + 0x97, 0x85, 0x8b, 0x6e, 0x8b, 0x7c, 0x87, 0x72, 0x84, 0x73, 0x08, 0xfb, + 0x0f, 0xfc, 0x4e, 0x05, 0x79, 0x4f, 0x84, 0x85, 0x52, 0x83, 0x08, 0x7b, + 0xf7, 0x90, 0x9b, 0x07, 0x51, 0x8e, 0x79, 0x96, 0x8b, 0xa9, 0x8b, 0x93, + 0x8e, 0x9a, 0x91, 0xa1, 0x08, 0xc9, 0xf7, 0x73, 0x05, 0xb0, 0x89, 0xa1, + 0x8a, 0xa1, 0x8b, 0xb2, 0x8b, 0x92, 0x8a, 0x94, 0x87, 0x9a, 0x83, 0x92, + 0x7e, 0x8b, 0x77, 0x8b, 0x7b, 0x89, 0x7f, 0x85, 0x6c, 0x08, 0x9c, 0x86, + 0xd7, 0xf7, 0x7e, 0x79, 0x90, 0x05, 0x5e, 0x31, 0x88, 0x8a, 0xfb, 0x3c, + 0x89, 0x08, 0xcd, 0xf7, 0x7d, 0x05, 0x91, 0x9f, 0x99, 0x91, 0xb4, 0x8b, + 0xf7, 0x3c, 0x8b, 0xaf, 0x7e, 0x8b, 0x4d, 0x8b, 0x85, 0x8b, 0x86, 0x8a, + 0x7e, 0x8a, 0x85, 0x8b, 0x8a, 0x8a, 0x7f, 0x08, 0xa0, 0x89, 0xab, 0xf7, + 0x2d, 0x05, 0x0e, 0xf8, 0x15, 0xf9, 0x58, 0xf9, 0x2a, 0x15, 0x7c, 0x8f, + 0x05, 0x7a, 0x73, 0x7a, 0x81, 0x71, 0x8b, 0x81, 0x8b, 0x7f, 0x8e, 0x75, + 0x92, 0x59, 0x9b, 0x60, 0x93, 0x62, 0x8b, 0xfb, 0x67, 0x8b, 0xfb, 0x54, + 0xfb, 0x5c, 0x8b, 0xfb, 0x70, 0x8b, 0x47, 0xa8, 0x45, 0xba, 0x5b, 0xbe, + 0x58, 0xd4, 0x70, 0xe2, 0x8b, 0x08, 0xe3, 0x8b, 0xd3, 0x9e, 0xd8, 0xb6, + 0x08, 0xbc, 0xf7, 0x4f, 0x05, 0x9b, 0xc3, 0x9b, 0x97, 0xcc, 0x8f, 0x08, + 0x9b, 0xfb, 0x9e, 0x7b, 0x07, 0x97, 0x8a, 0x98, 0x89, 0x8f, 0x8b, 0xac, + 0x88, 0x9b, 0x81, 0x8b, 0x79, 0x8b, 0x75, 0x85, 0x6f, 0x75, 0x41, 0x75, + 0x43, 0x88, 0x83, 0x7f, 0x7f, 0x75, 0x75, 0x65, 0x7f, 0x5e, 0x8b, 0xfb, + 0x15, 0x8b, 0x42, 0xd5, 0x8b, 0xf7, 0x17, 0x08, 0x8b, 0xf7, 0x0f, 0xbc, + 0xf7, 0x13, 0xda, 0xdf, 0xb8, 0xba, 0xc9, 0xa6, 0xcd, 0x8b, 0xcc, 0x8b, + 0xc2, 0x70, 0xa9, 0x5d, 0x9b, 0x71, 0x92, 0x76, 0x90, 0x5f, 0x08, 0x9d, + 0x88, 0xbc, 0xf7, 0x59, 0x05, 0x0e, 0xf8, 0x15, 0xf9, 0x93, 0xf9, 0x21, + 0x15, 0xfb, 0x8b, 0x7b, 0x06, 0xc5, 0x84, 0x97, 0x83, 0x8b, 0x6f, 0x8b, + 0x7d, 0x87, 0x74, 0x84, 0x72, 0x08, 0x5d, 0xfb, 0x38, 0xfb, 0xb1, 0x8b, + 0xc1, 0xf7, 0x57, 0x05, 0x9a, 0xbe, 0xa5, 0x9e, 0xc7, 0x8f, 0x08, 0x9b, + 0xfb, 0xa5, 0x7b, 0x07, 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x6e, 0x8b, 0x7d, + 0x87, 0x74, 0x84, 0x72, 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x79, 0x51, + 0x84, 0x85, 0x53, 0x81, 0x08, 0x7b, 0xf7, 0x8a, 0x9b, 0x07, 0x4f, 0x93, + 0x80, 0x92, 0x8b, 0xa8, 0x8b, 0x92, 0x8c, 0x93, 0x8d, 0x92, 0x08, 0xcd, + 0xf7, 0x88, 0xf7, 0xb1, 0x8b, 0x4a, 0xfb, 0x80, 0x05, 0x7b, 0x57, 0x77, + 0x7c, 0x4a, 0x84, 0x08, 0x7b, 0xf7, 0xa5, 0x9b, 0x07, 0x4b, 0x91, 0x7d, + 0x93, 0x8b, 0xa7, 0x8b, 0x95, 0x8c, 0x91, 0x8d, 0x93, 0x08, 0xf7, 0x18, + 0xf8, 0x75, 0x05, 0x9c, 0xc5, 0x93, 0x91, 0xc4, 0x95, 0x08, 0x9b, 0x07, + 0x0e, 0x87, 0x83, 0x16, 0xf7, 0x88, 0x9b, 0x06, 0x52, 0x92, 0x80, 0x91, + 0x8b, 0xa7, 0x8b, 0x9e, 0x8d, 0x97, 0x94, 0xab, 0x08, 0xf7, 0x0f, 0xf8, + 0x4f, 0x05, 0x9d, 0xc5, 0x92, 0x91, 0xc4, 0x95, 0x08, 0x9b, 0xfb, 0x8b, + 0x7b, 0x07, 0xc5, 0x84, 0x97, 0x83, 0x8b, 0x6f, 0x8b, 0x7d, 0x87, 0x74, + 0x84, 0x72, 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x79, 0x51, 0x84, 0x85, + 0x53, 0x81, 0x08, 0x7b, 0x07, 0x0e, 0xf6, 0xf8, 0x7f, 0xf9, 0x21, 0x15, + 0xfb, 0x92, 0x7b, 0x06, 0xca, 0x85, 0x99, 0x83, 0x8b, 0x70, 0x8b, 0x7d, + 0x87, 0x75, 0x83, 0x6f, 0x08, 0xfb, 0x17, 0xfc, 0x65, 0x05, 0x80, 0x64, + 0x7d, 0x7c, 0x73, 0x8b, 0x73, 0x8b, 0x80, 0x98, 0x8b, 0xa6, 0x8b, 0x90, + 0x8b, 0x8f, 0x8c, 0x91, 0x08, 0x94, 0x07, 0xa4, 0x74, 0xa1, 0x72, 0x70, + 0x78, 0x75, 0x6b, 0x57, 0xba, 0x67, 0xd1, 0x1e, 0xbe, 0x8b, 0xb8, 0x9f, + 0xaa, 0xb0, 0xa6, 0xab, 0x9f, 0xb8, 0xa0, 0xd7, 0x08, 0xf2, 0xf8, 0x07, + 0x05, 0x9d, 0xc7, 0x92, 0x91, 0xc4, 0x93, 0x08, 0x9b, 0x07, 0x0e, 0xf7, + 0xde, 0xf9, 0x66, 0xf9, 0x21, 0x15, 0xfb, 0x72, 0x7b, 0x06, 0x97, 0x8a, + 0x96, 0x89, 0x8f, 0x8b, 0xa3, 0x89, 0x95, 0x85, 0x8b, 0x80, 0x8b, 0x73, + 0x54, 0x55, 0x32, 0x4d, 0x08, 0xfb, 0x2c, 0x21, 0xc0, 0xf7, 0x56, 0x05, + 0x9a, 0xbd, 0xa6, 0x9f, 0xc6, 0x8f, 0x08, 0x9b, 0xfb, 0xa5, 0x7b, 0x07, + 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x6e, 0x8b, 0x7d, 0x87, 0x74, 0x84, 0x72, + 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x79, 0x4f, 0x86, 0x86, 0x50, 0x82, + 0x08, 0x7b, 0xf7, 0x8c, 0x9b, 0x07, 0x4c, 0x92, 0x82, 0x91, 0x8b, 0xaa, + 0x8b, 0x95, 0x8d, 0x94, 0x91, 0x9f, 0x08, 0x91, 0xa0, 0xc9, 0xf7, 0x78, + 0xf7, 0x0d, 0xfb, 0x64, 0x05, 0xa3, 0x62, 0x99, 0x68, 0x8b, 0x78, 0x8b, + 0x7c, 0x7d, 0x83, 0x6b, 0x88, 0x86, 0x8b, 0x80, 0x8a, 0x7e, 0x89, 0x08, + 0x7b, 0xf7, 0xa7, 0x9b, 0x07, 0x4c, 0x91, 0x85, 0x8e, 0x6f, 0xba, 0x08, + 0xfb, 0x42, 0xf7, 0xc3, 0xf7, 0xc0, 0xf7, 0x76, 0x05, 0xa7, 0xa0, 0xa2, + 0x96, 0xa3, 0x8f, 0x08, 0x9b, 0x07, 0x0e, 0xf7, 0x6f, 0xf8, 0x27, 0xf9, + 0x21, 0x15, 0xfb, 0xa5, 0x7b, 0x06, 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x6e, + 0x8b, 0x7d, 0x87, 0x74, 0x84, 0x72, 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, + 0x79, 0x51, 0x84, 0x85, 0x53, 0x81, 0x08, 0x7b, 0xf8, 0x91, 0x07, 0xc5, + 0xf7, 0x47, 0x77, 0x91, 0x05, 0x68, 0x43, 0x70, 0x6b, 0x5f, 0x75, 0x68, + 0x7a, 0x62, 0x85, 0x34, 0x8b, 0x3f, 0x8b, 0x72, 0x93, 0x8b, 0xa5, 0x8b, + 0x92, 0x90, 0xa3, 0x90, 0x9e, 0x08, 0xf7, 0x0f, 0xf8, 0x4f, 0x05, 0x9a, + 0xbe, 0xa5, 0x9e, 0xc7, 0x8f, 0x08, 0x9b, 0x07, 0x0e, 0xf8, 0x84, 0xf9, + 0xfd, 0xf9, 0x21, 0x15, 0xfb, 0x3b, 0x8b, 0xfb, 0xe4, 0xfc, 0x81, 0x54, + 0xf8, 0x81, 0xfb, 0x49, 0x8b, 0x8b, 0x7b, 0x05, 0xbd, 0x88, 0xa3, 0x80, + 0x8b, 0x74, 0x8b, 0x83, 0x87, 0x7c, 0x85, 0x79, 0x89, 0x87, 0x88, 0x80, + 0x87, 0x7c, 0x8a, 0x88, 0x8a, 0x87, 0x8a, 0x87, 0x08, 0x21, 0xfc, 0x08, + 0x05, 0x6c, 0x23, 0x7c, 0x77, 0x57, 0x85, 0x08, 0x7b, 0xf7, 0x5a, 0x9b, + 0x07, 0x58, 0x8f, 0x77, 0x97, 0x8b, 0xa7, 0x8b, 0x95, 0x8f, 0xa5, 0x90, + 0x9c, 0x08, 0xf7, 0x0a, 0xf8, 0x45, 0xc8, 0xfc, 0xb6, 0x9c, 0x8b, 0xf8, + 0x0d, 0xf8, 0xc5, 0xfb, 0x15, 0xfc, 0x6a, 0x05, 0x7b, 0x56, 0x77, 0x7c, + 0x4a, 0x84, 0x08, 0x7b, 0xf7, 0xa5, 0x9b, 0x07, 0x47, 0x91, 0x82, 0x91, + 0x8b, 0xaa, 0x8b, 0x9c, 0x8d, 0x98, 0x94, 0xaa, 0x08, 0xf7, 0x0f, 0xf8, + 0x4f, 0x05, 0x9d, 0xc7, 0x90, 0x90, 0xc6, 0x94, 0x08, 0x9b, 0x07, 0x0e, + 0xf7, 0xde, 0xf9, 0x6b, 0xf9, 0x21, 0x15, 0xfb, 0x5b, 0x7b, 0x06, 0xc4, + 0x86, 0x98, 0x81, 0x8b, 0x67, 0x8b, 0x7f, 0x89, 0x7f, 0x84, 0x77, 0x8a, + 0x88, 0x8a, 0x87, 0x8b, 0x8a, 0x08, 0x25, 0xfc, 0x10, 0xfb, 0x64, 0xf8, + 0x87, 0xfb, 0x35, 0x8b, 0x8b, 0x7b, 0x05, 0xba, 0x87, 0xa0, 0x7e, 0x9d, + 0x64, 0x08, 0xfb, 0x0b, 0xfc, 0x35, 0x05, 0x65, 0xfb, 0x14, 0x83, 0x7f, + 0x52, 0x83, 0x08, 0x7b, 0xf7, 0x5a, 0x9b, 0x07, 0x58, 0x8f, 0x78, 0x96, + 0x8b, 0xa7, 0x8b, 0x98, 0x8e, 0x9f, 0x91, 0xa0, 0x08, 0xf7, 0x06, 0xf8, + 0x3a, 0x05, 0xf7, 0x7a, 0xfc, 0xba, 0x9d, 0x8b, 0xf7, 0x24, 0xf8, 0x8b, + 0x05, 0xb0, 0xf7, 0x15, 0x8f, 0x91, 0xca, 0x99, 0x08, 0x9b, 0x07, 0x0e, + 0xf8, 0x15, 0xf8, 0x6e, 0xf9, 0x2e, 0x15, 0x37, 0x8b, 0x31, 0x63, 0x3b, + 0x42, 0x26, 0x2e, 0x50, 0xfb, 0x0e, 0x8b, 0xfb, 0x09, 0x8b, 0xfb, 0x20, + 0xe6, 0x28, 0xf7, 0x13, 0x8b, 0xf7, 0x64, 0x8b, 0xf7, 0x5e, 0xf7, 0x66, + 0x96, 0xf7, 0x76, 0x92, 0xf7, 0x21, 0x29, 0xf6, 0xfb, 0x1a, 0x8b, 0x08, + 0x82, 0x6a, 0x15, 0xda, 0xbd, 0x51, 0x2d, 0x1f, 0x8b, 0xfb, 0x00, 0x5c, + 0xfb, 0x26, 0x4a, 0x2d, 0x54, 0x3c, 0x4d, 0x64, 0x45, 0x8b, 0x37, 0x8b, + 0x5d, 0xc8, 0x8b, 0xf7, 0x00, 0x8b, 0xe9, 0xbd, 0xf7, 0x29, 0xc7, 0xe2, + 0xc3, 0xdc, 0xc8, 0xb1, 0xd4, 0x8b, 0x08, 0x0e, 0xf7, 0xa6, 0xf7, 0x26, + 0xf9, 0x11, 0x15, 0xc4, 0x84, 0x99, 0x82, 0x8b, 0x71, 0x8b, 0x7d, 0x87, + 0x76, 0x7e, 0x5e, 0x08, 0xfb, 0x0a, 0xfc, 0x3d, 0x05, 0x79, 0x4f, 0x84, + 0x85, 0x52, 0x83, 0x08, 0x7b, 0xf7, 0x89, 0x9b, 0x07, 0x4c, 0x94, 0x86, + 0x8e, 0x8b, 0xad, 0x8b, 0x97, 0x8d, 0x95, 0x95, 0xaf, 0x08, 0xc0, 0xf7, + 0x55, 0x05, 0xa4, 0x85, 0xa5, 0x89, 0xb4, 0x8b, 0xdd, 0x8b, 0xce, 0x9c, + 0xb6, 0xaa, 0xbd, 0xb0, 0xa8, 0xc2, 0x8b, 0xc6, 0x08, 0xeb, 0x40, 0xc0, + 0xfb, 0x1c, 0x1e, 0xfb, 0x8c, 0x7b, 0x06, 0xf7, 0x44, 0x61, 0x15, 0x91, + 0xa0, 0x97, 0x92, 0xa7, 0x8b, 0xb2, 0x8b, 0xb1, 0x81, 0x9f, 0x7d, 0xa5, + 0x79, 0x96, 0x6d, 0x8b, 0x5c, 0x8b, 0x4a, 0x74, 0x5d, 0x5f, 0x71, 0x6c, + 0x7a, 0x64, 0x83, 0x4d, 0x8b, 0x7a, 0x8b, 0x83, 0x8c, 0x70, 0x8f, 0x08, + 0xd2, 0xf7, 0x8c, 0x05, 0x0e, 0xf8, 0x15, 0xf7, 0xab, 0x7b, 0x15, 0xd8, + 0x90, 0xb1, 0x95, 0xc3, 0xaa, 0xf7, 0x28, 0xde, 0xf0, 0xf7, 0x36, 0x8b, + 0xf7, 0x32, 0x8b, 0xf7, 0x1b, 0x2b, 0xed, 0xfb, 0x19, 0x8b, 0x3b, 0x8b, + 0x31, 0x62, 0x3b, 0x43, 0x26, 0x2d, 0x50, 0xfb, 0x0d, 0x8b, 0xfb, 0x09, + 0x8b, 0x39, 0xa9, 0x47, 0xc1, 0x61, 0x08, 0xa5, 0x76, 0xa1, 0x81, 0xb7, + 0x81, 0x30, 0x3b, 0x82, 0x83, 0x3e, 0x55, 0x08, 0x95, 0x7c, 0x05, 0xb1, + 0xa0, 0xb1, 0x95, 0xb2, 0x8b, 0x9f, 0x8b, 0xa8, 0x85, 0xb7, 0x7f, 0xc8, + 0x7a, 0xc1, 0x81, 0xb0, 0x8b, 0xc2, 0x8b, 0xd1, 0xa5, 0xbe, 0xb3, 0xa3, + 0x9d, 0x98, 0x99, 0xa5, 0xaf, 0x08, 0x7c, 0x96, 0x05, 0x53, 0x51, 0x62, + 0x78, 0x43, 0x8b, 0x71, 0x8b, 0x76, 0x8f, 0x3f, 0x9d, 0x57, 0x98, 0x5c, + 0x94, 0x85, 0x8a, 0x87, 0x8a, 0x89, 0x8b, 0x8b, 0x8b, 0x08, 0x72, 0x8b, + 0xc1, 0xc4, 0x05, 0xf7, 0x4e, 0xf9, 0x1d, 0x15, 0xdb, 0xbc, 0x51, 0x2c, + 0x1f, 0x8b, 0x21, 0x5c, 0xfb, 0x27, 0x4b, 0x2f, 0x54, 0x3c, 0x4d, 0x64, + 0x42, 0x8b, 0x3a, 0x8b, 0x5c, 0xc8, 0x8b, 0xf4, 0x8b, 0xea, 0xbc, 0xf7, + 0x29, 0xc8, 0xe2, 0xc3, 0xdc, 0xc8, 0xb1, 0xd4, 0x8b, 0x08, 0x0e, 0xf7, + 0xa6, 0xf8, 0xcb, 0x9b, 0x15, 0x5f, 0x8e, 0x77, 0x9c, 0x78, 0xbf, 0x08, + 0x2e, 0xf7, 0x89, 0x05, 0xd8, 0x9c, 0xac, 0x99, 0xaf, 0xab, 0xac, 0xa8, + 0x9d, 0xb2, 0x8b, 0xb8, 0x08, 0xe8, 0x41, 0xbe, 0xfb, 0x1a, 0x1e, 0xfb, + 0x8c, 0x7b, 0x06, 0xb5, 0x85, 0x90, 0x8a, 0x95, 0x84, 0x93, 0x86, 0x91, + 0x7f, 0x8b, 0x80, 0x8b, 0x7f, 0x86, 0x73, 0x84, 0x70, 0x08, 0xfb, 0x0f, + 0xfc, 0x4e, 0x05, 0x79, 0x50, 0x84, 0x85, 0x53, 0x82, 0x08, 0x7b, 0xf7, + 0x88, 0x9b, 0x07, 0x4e, 0x93, 0x84, 0x90, 0x8b, 0xac, 0x8b, 0x95, 0x8e, + 0x98, 0x94, 0xae, 0x08, 0xc3, 0xf7, 0x65, 0xcc, 0x86, 0xf7, 0x0f, 0xfb, + 0xd8, 0xf7, 0x28, 0x8b, 0x8b, 0x9b, 0x05, 0xfb, 0x97, 0xf8, 0xd7, 0x15, + 0x91, 0xa0, 0x98, 0x92, 0xab, 0x8b, 0x08, 0xde, 0xb4, 0x65, 0x41, 0x28, + 0x4b, 0x58, 0xfb, 0x11, 0x1f, 0x7b, 0x8b, 0x80, 0x8c, 0x73, 0x8f, 0x08, + 0xcc, 0xf7, 0x79, 0x05, 0x0e, 0xf8, 0x68, 0xf8, 0x68, 0x15, 0xb3, 0xf7, + 0x5b, 0x74, 0x8b, 0x05, 0x7d, 0x76, 0x82, 0x86, 0x75, 0x8b, 0x7f, 0x8b, + 0x80, 0x8e, 0x74, 0x93, 0x08, 0x75, 0x94, 0x6b, 0x90, 0x6c, 0x8b, 0x23, + 0x8b, 0x41, 0x46, 0x8b, 0x29, 0x8b, 0x55, 0x9a, 0x6e, 0xc7, 0x4b, 0x94, + 0x82, 0x98, 0x7d, 0x9c, 0x78, 0x9d, 0x78, 0x99, 0x7c, 0x92, 0x83, 0xba, + 0x5a, 0x98, 0x71, 0x8b, 0x60, 0x08, 0x40, 0x53, 0x51, 0x42, 0x38, 0x4c, + 0xd2, 0xea, 0x1e, 0x8b, 0x93, 0x8c, 0x93, 0x8c, 0x92, 0x08, 0x77, 0x8d, + 0x69, 0xfb, 0x73, 0x9d, 0x8b, 0x05, 0x92, 0xa2, 0x96, 0x95, 0x9f, 0x8b, + 0x96, 0x8b, 0x9a, 0x87, 0xa5, 0x82, 0xb9, 0x7a, 0xa6, 0x85, 0xaa, 0x8b, + 0xf7, 0x07, 0x8b, 0xe2, 0xe2, 0x8b, 0xf7, 0x05, 0x8b, 0xcc, 0x74, 0xb2, + 0x31, 0xe6, 0x31, 0xe6, 0x82, 0x99, 0x8b, 0xbc, 0x08, 0xca, 0xb5, 0xb2, + 0xcf, 0x1e, 0xb0, 0x8b, 0xaa, 0x7e, 0xa0, 0x73, 0xa1, 0x72, 0x93, 0x69, + 0x8d, 0x49, 0x08, 0x9d, 0x88, 0x05, 0x0e, 0xf7, 0x6f, 0xf9, 0x0d, 0xf9, + 0x21, 0x15, 0xfc, 0xa8, 0x8b, 0x61, 0xfb, 0x2e, 0x9d, 0x87, 0x05, 0xc0, + 0xf7, 0x00, 0xab, 0x9c, 0xf7, 0x2d, 0x89, 0x08, 0xfb, 0x24, 0xfc, 0xa4, + 0x05, 0x7b, 0x56, 0x73, 0x7b, 0x49, 0x86, 0x08, 0x7b, 0xf7, 0xb6, 0x9b, + 0x07, 0x7a, 0x8c, 0x7c, 0x8d, 0x85, 0x8b, 0x63, 0x8e, 0x7f, 0x94, 0x8b, + 0xa9, 0x8b, 0x98, 0x8e, 0x97, 0x94, 0xad, 0x08, 0xf7, 0x1f, 0xf8, 0x86, + 0xc2, 0x8b, 0x05, 0xd3, 0xab, 0x72, 0x53, 0x1f, 0x8b, 0x7e, 0x8a, 0x7c, + 0x89, 0x7a, 0x08, 0x9c, 0x89, 0xb7, 0xf7, 0x37, 0x05, 0x0e, 0xf8, 0x15, + 0xf9, 0x91, 0xf9, 0x21, 0x15, 0xfb, 0x5b, 0x7b, 0x06, 0xab, 0x88, 0x95, + 0x89, 0x97, 0x83, 0x95, 0x85, 0x92, 0x7d, 0x8b, 0x7e, 0x8b, 0x7b, 0x71, + 0x25, 0x5b, 0xfb, 0x3d, 0x87, 0x7e, 0x87, 0x7a, 0x86, 0x78, 0x79, 0x4a, + 0x7c, 0x63, 0x75, 0x69, 0x64, 0x4d, 0x55, 0x6c, 0x45, 0x8b, 0x08, 0x38, + 0x52, 0xbb, 0xd1, 0x1f, 0x8b, 0xad, 0xaa, 0xf7, 0x0d, 0xce, 0xf7, 0x7b, + 0x8d, 0x92, 0x8d, 0x92, 0x8c, 0x90, 0xa0, 0xd1, 0x9b, 0x99, 0xcf, 0x92, + 0x08, 0x9b, 0xfb, 0xa5, 0x7b, 0x07, 0xce, 0x85, 0x96, 0x85, 0x8b, 0x6e, + 0x8b, 0x7f, 0x88, 0x7b, 0x87, 0x7a, 0x08, 0x56, 0xfb, 0x54, 0x05, 0x6d, + 0xfb, 0x00, 0x7e, 0x4b, 0x8b, 0x63, 0x8b, 0x2b, 0xe7, 0x46, 0xf7, 0x12, + 0x8b, 0xf7, 0x17, 0x8b, 0xde, 0xd2, 0xb7, 0xf7, 0x2a, 0x08, 0xde, 0xf7, + 0xb1, 0x05, 0xb1, 0xf7, 0x16, 0x8f, 0x90, 0xc9, 0x99, 0x08, 0x9b, 0x07, + 0x0e, 0xf7, 0xa6, 0xf9, 0x44, 0xf9, 0x21, 0x15, 0xfb, 0x4e, 0x7b, 0x06, + 0xb8, 0x86, 0x9d, 0x81, 0x8b, 0x78, 0x8b, 0x78, 0x78, 0x60, 0x6a, 0x52, + 0x08, 0xfb, 0x62, 0xfb, 0xf8, 0x49, 0xf8, 0x4f, 0x05, 0x8a, 0x90, 0x8b, + 0x8f, 0x8b, 0x91, 0x8b, 0xad, 0x99, 0x95, 0xca, 0x92, 0x08, 0x9b, 0xfb, + 0x85, 0x7b, 0x07, 0xc3, 0x84, 0x8d, 0x88, 0xa0, 0xfb, 0x11, 0x08, 0xe0, + 0xfc, 0x9c, 0x9e, 0x8b, 0xf8, 0x09, 0xf8, 0xfb, 0x05, 0x9c, 0xa6, 0x9b, + 0x97, 0xa2, 0x8c, 0x08, 0x9b, 0x07, 0x0e, 0xf8, 0x84, 0xfa, 0x1e, 0xf9, + 0x21, 0x15, 0xfb, 0x4d, 0x7b, 0x06, 0xc1, 0x86, 0x96, 0x84, 0x8b, 0x6f, + 0x8b, 0x7b, 0x83, 0x72, 0x7e, 0x71, 0x08, 0xfb, 0x4f, 0xfc, 0x04, 0x63, + 0xf8, 0x26, 0x8a, 0x99, 0x05, 0x8b, 0xb4, 0x99, 0x98, 0xc1, 0x90, 0x08, + 0x9b, 0xfb, 0x82, 0x7b, 0x07, 0xc5, 0x89, 0x95, 0x84, 0x92, 0x5a, 0x08, + 0x94, 0x46, 0xfb, 0x40, 0xfb, 0xf0, 0x5f, 0xf8, 0x2a, 0x05, 0x8a, 0x90, + 0x8b, 0x92, 0x8b, 0x8d, 0x8b, 0xb2, 0x97, 0x94, 0xc8, 0x92, 0x08, 0x9b, + 0xfb, 0x80, 0x7b, 0x07, 0xac, 0x87, 0x94, 0x88, 0x94, 0x82, 0x97, 0x80, + 0x8f, 0x78, 0x97, 0x2f, 0x08, 0xc9, 0xfc, 0x99, 0x9e, 0x8b, 0xf7, 0x72, + 0xf8, 0x5a, 0x90, 0x8b, 0xbd, 0xfc, 0x5a, 0x9f, 0x8b, 0xf7, 0xc3, 0xf8, + 0xdb, 0x05, 0xa6, 0xbe, 0x95, 0x94, 0xb1, 0x97, 0x08, 0x9b, 0x07, 0x0e, + 0xf7, 0xa6, 0xf9, 0x23, 0xf9, 0x21, 0x15, 0xfb, 0x64, 0x7b, 0x06, 0xbc, + 0x85, 0x97, 0x84, 0x8b, 0x74, 0x8b, 0x7e, 0x85, 0x7f, 0x7d, 0x7b, 0x08, + 0xfb, 0x25, 0xfb, 0x3b, 0x50, 0xf7, 0x27, 0x05, 0x80, 0xa5, 0x87, 0x9c, + 0x8b, 0x98, 0x8b, 0xa4, 0x9b, 0x94, 0xc2, 0x92, 0x08, 0x9b, 0xfb, 0x9c, + 0x7b, 0x07, 0xc5, 0x86, 0x9a, 0x81, 0x9e, 0x5d, 0x08, 0xf5, 0xfb, 0x9b, + 0x05, 0x66, 0x61, 0x6a, 0x64, 0x7e, 0x7b, 0xfb, 0x1f, 0xfb, 0x38, 0x6f, + 0x72, 0x56, 0x80, 0x08, 0x7b, 0xf7, 0x6a, 0x9b, 0x07, 0x5b, 0x7a, 0x94, + 0xa4, 0x1f, 0x8b, 0x9a, 0x93, 0x9c, 0x98, 0x9a, 0x08, 0xf7, 0x2b, 0xf7, + 0x40, 0xce, 0xfb, 0x39, 0x05, 0x92, 0x79, 0x8f, 0x7b, 0x8b, 0x7c, 0x8b, + 0x6e, 0x81, 0x86, 0x49, 0x86, 0x08, 0x7b, 0xf7, 0xa5, 0x9b, 0x07, 0x45, + 0x93, 0x82, 0x91, 0x72, 0xc7, 0x08, 0x25, 0xf7, 0x96, 0xf7, 0x3d, 0xf7, + 0x56, 0x05, 0xbf, 0xc5, 0xa9, 0xa2, 0xb6, 0x99, 0x08, 0x9b, 0x07, 0x0e, + 0xf7, 0x6f, 0xe6, 0xf9, 0x11, 0x15, 0xc3, 0x83, 0x8e, 0x88, 0x9c, 0x54, + 0x08, 0xd8, 0xfb, 0xa1, 0x4e, 0xfb, 0x68, 0x05, 0x7a, 0x55, 0x75, 0x7b, + 0x49, 0x87, 0x08, 0x7b, 0xf7, 0xb5, 0x9b, 0x07, 0x7b, 0x8c, 0x7d, 0x8c, + 0x85, 0x8c, 0x64, 0x8d, 0x7d, 0x95, 0x8b, 0xa4, 0x8b, 0xa0, 0x92, 0xa9, + 0xa3, 0xd9, 0x8e, 0x94, 0x8d, 0x92, 0x8c, 0x8f, 0x08, 0xa8, 0xf0, 0xf7, + 0x6f, 0xf7, 0xa2, 0x05, 0xab, 0xb3, 0x93, 0x92, 0xa9, 0x99, 0x08, 0x9b, + 0xfb, 0x51, 0x7b, 0x07, 0x97, 0x8a, 0x96, 0x8a, 0x8f, 0x8a, 0xa8, 0x88, + 0x98, 0x83, 0x8b, 0x7a, 0x8b, 0x70, 0x5d, 0x4a, 0x23, 0xfb, 0x0d, 0x08, + 0x65, 0x5d, 0x05, 0x7f, 0xb7, 0x88, 0x98, 0x7b, 0xc0, 0x72, 0xe1, 0x80, + 0xb6, 0x8b, 0x9a, 0x8b, 0xa3, 0x97, 0x91, 0xc7, 0x91, 0x08, 0x9b, 0xfb, + 0x83, 0x7b, 0x07, 0x0e, 0xf7, 0x6f, 0xf8, 0xf2, 0xf9, 0x21, 0x15, 0xfc, + 0x7a, 0x8b, 0x5d, 0xfb, 0x26, 0x9e, 0x86, 0x05, 0xa0, 0xb7, 0x97, 0x9c, + 0x9e, 0x9c, 0xa8, 0xa3, 0xc0, 0x98, 0xd6, 0x8b, 0x08, 0xf7, 0x3f, 0x8b, + 0xfc, 0x73, 0xfc, 0xef, 0x8b, 0x7d, 0xf8, 0x8d, 0x8b, 0xc1, 0xf7, 0x3c, + 0x78, 0x8e, 0x05, 0x6b, 0x4b, 0x79, 0x73, 0x69, 0x78, 0x69, 0x77, 0x59, + 0x83, 0x39, 0x8b, 0x08, 0xfb, 0x35, 0x8b, 0xf8, 0x77, 0xf8, 0xef, 0x8b, + 0x99, 0x05, 0x0e, 0xbf, 0xf8, 0x14, 0xf9, 0x10, 0x15, 0x92, 0xa6, 0xfb, + 0x41, 0x8b, 0xfb, 0x59, 0xfd, 0xc4, 0xf7, 0x50, 0x8b, 0x92, 0xa6, 0x53, + 0x8b, 0x05, 0x6b, 0x7a, 0x94, 0x9e, 0x1f, 0x8b, 0x90, 0x8b, 0x8b, 0x8f, + 0x9b, 0x08, 0xf7, 0x34, 0xf9, 0x3a, 0x05, 0x91, 0xa5, 0x97, 0x94, 0xa8, + 0x8b, 0x08, 0xc9, 0x06, 0x0e, 0x50, 0x62, 0xf9, 0x2e, 0x15, 0xf7, 0xb5, + 0xfd, 0x40, 0xd2, 0x8b, 0xfb, 0xb4, 0xf9, 0x40, 0x43, 0x8b, 0x05, 0x0e, + 0xbf, 0x9e, 0xfb, 0x12, 0x15, 0x84, 0x70, 0xf7, 0x41, 0x8b, 0xf7, 0x59, + 0xf9, 0xc4, 0xfb, 0x51, 0x8b, 0x84, 0x70, 0xc4, 0x8b, 0x05, 0xab, 0x9c, + 0x82, 0x79, 0x1f, 0x8b, 0x87, 0x8b, 0x8a, 0x87, 0x7b, 0x08, 0xfb, 0x35, + 0xfd, 0x3a, 0x05, 0x84, 0x6e, 0x82, 0x84, 0x6d, 0x8b, 0x08, 0x4d, 0x06, + 0x0e, 0xe0, 0xcf, 0xf7, 0xc1, 0x15, 0xf7, 0x23, 0xf7, 0xb5, 0xf7, 0x23, + 0xfb, 0xb5, 0xcf, 0x8b, 0xfb, 0x49, 0xf8, 0x01, 0x4f, 0x8b, 0xfb, 0x49, + 0xfc, 0x01, 0xcf, 0x8b, 0x05, 0x0e, 0xf8, 0x88, 0xfb, 0x11, 0x15, 0xbd, + 0xfc, 0x88, 0x59, 0xf8, 0x88, 0x07, 0x0e, 0x87, 0xf7, 0xc1, 0xf9, 0x2e, + 0x15, 0x37, 0x5c, 0x5d, 0x53, 0x8b, 0x53, 0x08, 0x63, 0xa4, 0x6c, 0xac, + 0xa8, 0xa1, 0x9f, 0xa6, 0x1e, 0x8b, 0x9c, 0x85, 0x96, 0x78, 0x9c, 0x7c, + 0x99, 0x86, 0x93, 0x8b, 0x95, 0x8b, 0xa6, 0xa2, 0xa6, 0xbf, 0xae, 0x08, + 0x82, 0x9c, 0x05, 0x0e, 0xf8, 0x64, 0xf7, 0x02, 0x15, 0x7c, 0x7c, 0x85, + 0x86, 0x84, 0x83, 0x6d, 0x6c, 0x7e, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x85, + 0x91, 0x8b, 0x92, 0x8b, 0x9f, 0xb5, 0xf7, 0x3f, 0xba, 0xf7, 0x40, 0x8e, + 0x95, 0x8c, 0x8d, 0x8d, 0x94, 0x08, 0x84, 0x8e, 0x4e, 0x84, 0x88, 0x88, + 0x80, 0x5b, 0x05, 0x83, 0xb0, 0x6e, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x18, + 0xfb, 0x2e, 0xfb, 0x4b, 0xfb, 0x32, 0x45, 0xb1, 0x62, 0xcb, 0x1f, 0xd1, + 0x8b, 0xb6, 0xac, 0xe3, 0xf7, 0x10, 0x77, 0x3d, 0x88, 0x7e, 0x8b, 0x73, + 0x08, 0x6e, 0x97, 0x7f, 0xa7, 0x1e, 0xb3, 0x8b, 0xa4, 0x9e, 0xd5, 0xe6, + 0x08, 0x7f, 0x95, 0x05, 0xfb, 0x2f, 0xf7, 0xc9, 0x15, 0xad, 0x89, 0xa1, + 0x73, 0x8b, 0x68, 0x8b, 0x37, 0x59, 0xfb, 0x0a, 0x46, 0x41, 0x73, 0x70, + 0x69, 0x7a, 0x6e, 0x8b, 0x68, 0x8b, 0x74, 0xa8, 0x8b, 0xb9, 0x8b, 0xc1, + 0xb1, 0xf2, 0xb6, 0xc9, 0x08, 0xb3, 0xc5, 0xba, 0xab, 0xb3, 0x88, 0x08, + 0x0e, 0xf7, 0x02, 0xf9, 0x17, 0x15, 0xc6, 0x89, 0x91, 0x88, 0x8b, 0x75, + 0x8b, 0x82, 0x88, 0x7f, 0x85, 0x75, 0x89, 0x84, 0x89, 0x84, 0x8a, 0x86, + 0x08, 0x89, 0x84, 0xfb, 0x1c, 0xfc, 0x89, 0x8b, 0x87, 0x05, 0x74, 0xd8, + 0x6d, 0xc3, 0xf7, 0x2b, 0xf7, 0x3a, 0xf7, 0x43, 0xf7, 0x31, 0xd1, 0x5a, + 0xbd, 0x48, 0x1e, 0x45, 0x8b, 0x57, 0x62, 0x44, 0xfb, 0x02, 0x08, 0xf3, + 0xf8, 0x18, 0x86, 0x90, 0x05, 0x59, 0x82, 0x67, 0x85, 0x48, 0x83, 0x08, + 0x7a, 0x07, 0xf7, 0x64, 0xfb, 0x8f, 0x15, 0xb6, 0xa6, 0x6a, 0x56, 0x1f, + 0x8b, 0x49, 0x58, 0x20, 0x50, 0x4d, 0x66, 0x65, 0x60, 0x76, 0x60, 0x8b, + 0x6c, 0x8b, 0x7c, 0x96, 0x8b, 0xa2, 0x8b, 0xc7, 0xa9, 0xec, 0xb5, 0xd5, + 0xb7, 0xd8, 0xb8, 0xb1, 0xbb, 0x8b, 0x08, 0x0e, 0xf6, 0xf7, 0xf2, 0xf5, + 0x15, 0x54, 0x50, 0x64, 0x75, 0x5a, 0x8b, 0x52, 0x8b, 0x69, 0xb6, 0x8b, + 0xd2, 0x8b, 0xe0, 0xae, 0xe4, 0xc3, 0xc6, 0xa8, 0xa9, 0xb3, 0x9d, 0xb2, + 0x8b, 0xa2, 0x8b, 0x9a, 0x83, 0x8b, 0x7f, 0x8b, 0x86, 0x89, 0x86, 0x87, + 0x82, 0x08, 0x84, 0x7e, 0x89, 0x84, 0x8b, 0x82, 0x08, 0x73, 0x9a, 0x7d, + 0xa3, 0xa6, 0xa0, 0x9f, 0xa5, 0xb9, 0x5e, 0xae, 0x4f, 0xfb, 0x2a, 0xfb, + 0x20, 0xfb, 0x26, 0xfb, 0x30, 0x2c, 0xc1, 0x54, 0xe8, 0x1e, 0xd5, 0x8b, + 0xc2, 0xaa, 0xc7, 0xd7, 0x08, 0x7b, 0x95, 0x05, 0x0e, 0xf8, 0x63, 0xf7, + 0x03, 0x15, 0x55, 0x4d, 0x80, 0x82, 0x7a, 0x8b, 0x81, 0x8b, 0x83, 0x94, + 0x8b, 0x96, 0x8b, 0x99, 0xab, 0xf7, 0x0e, 0xac, 0xf7, 0x02, 0xa6, 0xe7, + 0xa0, 0xdb, 0xbe, 0xf7, 0x5c, 0x08, 0x86, 0x90, 0x05, 0x56, 0x80, 0x67, + 0x85, 0x4b, 0x85, 0x08, 0x7a, 0x07, 0xc2, 0x89, 0x92, 0x88, 0x8b, 0x76, + 0x8b, 0x7e, 0x8a, 0x85, 0x7d, 0x58, 0x08, 0x5f, 0xfb, 0x38, 0x05, 0x83, + 0xb5, 0x79, 0x9b, 0x64, 0x8b, 0x08, 0xfb, 0x16, 0xfb, 0x36, 0xfb, 0x50, + 0xfb, 0x2a, 0x44, 0xb3, 0x60, 0xcc, 0x1f, 0xcf, 0x8b, 0xb7, 0xab, 0xcf, + 0xef, 0x80, 0x58, 0x89, 0x7c, 0x8b, 0x74, 0x08, 0x70, 0x9c, 0x79, 0xa4, + 0x1e, 0xb5, 0x8b, 0xbf, 0xb4, 0xbf, 0xd4, 0x08, 0x7f, 0x95, 0x05, 0xfb, + 0x2c, 0xf7, 0xc7, 0x15, 0xa9, 0x89, 0x9a, 0x78, 0x8b, 0x67, 0x08, 0xfb, + 0x2c, 0x23, 0xfb, 0x40, 0x2f, 0x69, 0x73, 0xa6, 0xb2, 0x1e, 0x8b, 0xde, + 0xbd, 0xf7, 0x08, 0xcd, 0xd1, 0x08, 0xa7, 0xa8, 0xb0, 0x9e, 0xa7, 0x89, + 0x08, 0x0e, 0xf6, 0xf7, 0xfa, 0xf7, 0x01, 0x15, 0x43, 0x50, 0x6c, 0x7b, + 0x60, 0x8b, 0x52, 0x8b, 0x66, 0xaf, 0x8b, 0xc1, 0x8b, 0x9a, 0x8d, 0x9a, + 0x93, 0xab, 0x08, 0xa7, 0x8f, 0x05, 0xf7, 0x2a, 0xa0, 0xf5, 0xd7, 0x8b, + 0xe1, 0x08, 0xb5, 0x6d, 0xa5, 0x59, 0xfb, 0x24, 0xfb, 0x31, 0xfb, 0x39, + 0xfb, 0x2a, 0x3a, 0xc1, 0x53, 0xd9, 0x1e, 0xd2, 0x8b, 0xd8, 0xb4, 0xc6, + 0xce, 0x08, 0x7f, 0x97, 0x05, 0xfb, 0x62, 0xf7, 0x23, 0x15, 0xad, 0xe4, + 0xd5, 0xd8, 0xbe, 0x8b, 0xa0, 0x8b, 0x99, 0x7b, 0x8b, 0x74, 0x8b, 0x6c, + 0x78, 0x67, 0x6c, 0x6d, 0x66, 0x68, 0x65, 0x79, 0x35, 0x76, 0x08, 0x9c, + 0xb7, 0x05, 0x0e, 0x50, 0xae, 0xf8, 0x20, 0x15, 0xe5, 0x8b, 0x33, 0xfc, + 0x38, 0x05, 0x75, 0x20, 0x6a, 0x54, 0x61, 0x8b, 0x7f, 0x8b, 0x83, 0x92, + 0x8b, 0x94, 0x8b, 0x8e, 0x8c, 0x8e, 0x8e, 0x90, 0x8f, 0x91, 0x8c, 0x8f, + 0x8b, 0x91, 0x08, 0xa0, 0x79, 0x9c, 0x76, 0x76, 0x7b, 0x79, 0x74, 0x69, + 0xae, 0x70, 0xb7, 0x1e, 0xe4, 0x8b, 0xd1, 0xee, 0xb4, 0xf7, 0x4c, 0x08, + 0xd3, 0xf7, 0xd4, 0xf7, 0x01, 0x8b, 0x91, 0xab, 0xfb, 0x00, 0x8b, 0x05, + 0xa8, 0xf7, 0x31, 0xb0, 0xd2, 0xc3, 0x8b, 0x98, 0x8b, 0x94, 0x86, 0x8b, + 0x84, 0x8b, 0x88, 0x8a, 0x89, 0x88, 0x86, 0x87, 0x82, 0x89, 0x86, 0x8b, + 0x84, 0x08, 0x73, 0x9a, 0x7b, 0xa1, 0xa2, 0x9e, 0x9d, 0xa1, 0xb0, 0x66, + 0xa7, 0x5a, 0x1e, 0x5a, 0x8b, 0x64, 0x75, 0x67, 0x5c, 0x6d, 0x64, 0x77, + 0x5d, 0x6d, 0x2b, 0x08, 0x2f, 0x8b, 0x84, 0x6b, 0x05, 0x0e, 0xf8, 0x6c, + 0xf8, 0x29, 0x15, 0x4e, 0x06, 0x88, 0x8b, 0x86, 0x8d, 0x83, 0x91, 0x70, + 0x9d, 0x6a, 0x95, 0x65, 0x8b, 0xfb, 0x03, 0x8b, 0x31, 0x3e, 0x8b, 0x2d, + 0x8b, 0x57, 0xa1, 0x6d, 0xc4, 0x71, 0x50, 0x63, 0x79, 0x77, 0x8b, 0x73, + 0x8b, 0x7e, 0x93, 0x7f, 0x9e, 0x7d, 0x08, 0x28, 0x4a, 0x79, 0x77, 0x8b, + 0x5d, 0x08, 0x46, 0xcd, 0x5e, 0xf0, 0xf7, 0x12, 0xdf, 0xc6, 0xe2, 0x1e, + 0x8b, 0xca, 0x5b, 0xb7, 0x2c, 0xa4, 0x5f, 0x96, 0x71, 0x9b, 0x8b, 0x9a, + 0x8b, 0x9a, 0xa2, 0xa5, 0x98, 0x8b, 0x8d, 0x8b, 0x8d, 0x8b, 0x8e, 0x8a, + 0x93, 0x89, 0x99, 0x8a, 0x94, 0x8b, 0x08, 0xe6, 0xe9, 0xdc, 0xd9, 0x1f, + 0x8b, 0x9b, 0x88, 0x9f, 0x85, 0x9f, 0x08, 0xbd, 0x06, 0xb2, 0x07, 0xfb, + 0xd8, 0xfc, 0x0d, 0x15, 0x8c, 0x8b, 0x8d, 0x8a, 0x8d, 0x8a, 0x8e, 0x8a, + 0x95, 0x88, 0x9b, 0x86, 0xf5, 0x6a, 0xb0, 0x6f, 0x8b, 0x5d, 0x08, 0x55, + 0x51, 0x63, 0x3e, 0x3b, 0x5c, 0xb1, 0xcb, 0x1e, 0x8b, 0xa3, 0x91, 0x9c, + 0x9b, 0x9e, 0x08, 0x98, 0x9c, 0xb5, 0xac, 0x93, 0x8b, 0x08, 0xf7, 0x28, + 0xf8, 0x1b, 0x15, 0xb0, 0x9e, 0x73, 0x5c, 0x1f, 0x8b, 0x68, 0x7f, 0x5f, + 0x78, 0x69, 0x75, 0x62, 0x6c, 0x75, 0x69, 0x8b, 0x08, 0x65, 0x75, 0xa7, + 0xba, 0x1f, 0xe7, 0xc4, 0xdb, 0xcc, 0x1e, 0x0e, 0xf8, 0x65, 0xf7, 0x09, + 0x15, 0x55, 0x47, 0x7f, 0x80, 0x7b, 0x8b, 0x82, 0x8b, 0x84, 0x94, 0x8b, + 0x94, 0x8b, 0x95, 0x9b, 0xca, 0x9c, 0xbf, 0xa8, 0xea, 0x9e, 0xd5, 0x8b, + 0xa3, 0x8b, 0xb3, 0x70, 0xa6, 0x64, 0x8b, 0x4a, 0x8b, 0x44, 0x49, 0x2e, + 0xfb, 0x25, 0x08, 0xf7, 0x0c, 0xf8, 0x54, 0x86, 0x90, 0x05, 0x51, 0x7e, + 0x64, 0x84, 0x4f, 0x84, 0x08, 0x7c, 0xa5, 0x07, 0x8c, 0x8b, 0x8c, 0x8b, + 0x8c, 0x8c, 0x99, 0x91, 0xa3, 0x7a, 0x8b, 0x7d, 0x8b, 0x7d, 0x86, 0x72, + 0x82, 0x6e, 0x8a, 0x8a, 0x88, 0x7d, 0x85, 0x75, 0x08, 0xfb, 0x1b, 0xfc, + 0x94, 0xd6, 0x8b, 0x05, 0xb3, 0xf7, 0x2e, 0x98, 0xad, 0xb3, 0xc8, 0xbf, + 0xda, 0xcf, 0xc9, 0xae, 0x8b, 0x9a, 0x8b, 0x98, 0x7f, 0x8b, 0x7e, 0x8b, + 0x87, 0x88, 0x7e, 0x87, 0x7b, 0x08, 0x54, 0xfb, 0x63, 0x05, 0x7e, 0x5a, + 0x84, 0x6c, 0x8b, 0x7f, 0x08, 0x71, 0x9c, 0x7b, 0xa6, 0x1e, 0xbe, 0x8b, + 0xae, 0xa6, 0xc7, 0xe2, 0x08, 0x7e, 0x97, 0x05, 0x0e, 0x50, 0xf7, 0x72, + 0xf7, 0x06, 0x15, 0x73, 0x6b, 0x84, 0x83, 0x81, 0x80, 0x7a, 0x7a, 0x7c, + 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x83, 0x93, 0x8b, 0x92, 0x8b, 0x95, 0x8e, + 0x9a, 0x92, 0x9e, 0x8b, 0x8e, 0x8e, 0x92, 0x8d, 0x93, 0x08, 0x8b, 0x8d, + 0x8c, 0x8d, 0xe3, 0xf7, 0xd6, 0x88, 0x8d, 0x05, 0x26, 0x78, 0x77, 0x88, + 0x64, 0x88, 0x08, 0x7b, 0x07, 0xc0, 0x8a, 0x95, 0x88, 0x8b, 0x77, 0x8b, + 0x83, 0x88, 0x7b, 0x85, 0x77, 0x08, 0x5b, 0xfb, 0x45, 0x05, 0x7b, 0x51, + 0x85, 0x6c, 0x8b, 0x77, 0x8b, 0x66, 0x9b, 0x77, 0xa9, 0x8b, 0xb9, 0x8b, + 0xb0, 0xa9, 0xc4, 0xdf, 0x08, 0x7e, 0x96, 0x05, 0x83, 0xf8, 0xb0, 0x15, + 0x70, 0x77, 0x74, 0x6d, 0x6b, 0x9e, 0x76, 0xa8, 0xa5, 0xa2, 0xa2, 0xa7, + 0xa8, 0x74, 0xa5, 0x70, 0x1f, 0x0e, 0x50, 0xf7, 0x8a, 0xf8, 0x4b, 0x15, + 0x88, 0x8d, 0x05, 0x32, 0x7b, 0x59, 0x83, 0x6c, 0x8a, 0x08, 0x7b, 0xa6, + 0x07, 0x92, 0x8c, 0x05, 0x93, 0x8c, 0x9f, 0x85, 0x90, 0x87, 0x8f, 0x87, + 0x8e, 0x82, 0x8b, 0x81, 0x8b, 0x81, 0x86, 0x70, 0x80, 0x60, 0x08, 0x43, + 0xfb, 0xb8, 0x05, 0x69, 0xfb, 0x1d, 0x74, 0x5f, 0x63, 0x8b, 0x7f, 0x8b, + 0x85, 0x8f, 0x8b, 0x92, 0x8b, 0x8f, 0x8c, 0x8d, 0x8f, 0x90, 0x91, 0x93, + 0x8d, 0x90, 0x8b, 0x93, 0x08, 0xa0, 0x79, 0x9b, 0x74, 0x74, 0x7a, 0x79, + 0x73, 0x68, 0xac, 0x71, 0xb9, 0x1e, 0xe2, 0x8b, 0xc7, 0xd7, 0xb3, 0xf7, + 0x33, 0x08, 0xf3, 0xf8, 0x2f, 0x05, 0x77, 0xf7, 0x6b, 0x15, 0x70, 0x77, + 0x75, 0x6c, 0x6b, 0x9e, 0x76, 0xa8, 0xa5, 0xa2, 0xa2, 0xa7, 0xa8, 0x74, + 0xa5, 0x70, 0x1f, 0x0e, 0xf6, 0xf8, 0x32, 0xf7, 0x01, 0x15, 0x7c, 0x71, + 0x05, 0x79, 0x6c, 0x7f, 0x80, 0x7c, 0x8b, 0x76, 0x8b, 0x76, 0xac, 0x64, + 0xeb, 0x86, 0x98, 0x7c, 0xaf, 0x7a, 0xb2, 0xf7, 0x27, 0xf7, 0x17, 0xaa, + 0x9f, 0xba, 0x8e, 0x08, 0x9b, 0xfb, 0x4b, 0x7b, 0x9b, 0x07, 0xa4, 0x99, + 0x84, 0x80, 0x1f, 0x8b, 0x77, 0x59, 0x5a, 0x2e, 0x44, 0x7d, 0x80, 0x7f, + 0x81, 0x7a, 0x7f, 0x08, 0xf7, 0x0c, 0xf8, 0x5d, 0x86, 0x90, 0x05, 0x50, + 0x7e, 0x65, 0x84, 0x50, 0x84, 0x08, 0x7b, 0x07, 0xbb, 0x8c, 0x9e, 0x84, + 0x8c, 0x78, 0x89, 0x7a, 0x84, 0x70, 0x7e, 0x5d, 0x87, 0x7d, 0x88, 0x80, + 0x89, 0x83, 0x08, 0x89, 0x82, 0x05, 0xfb, 0x13, 0xfc, 0x77, 0xd6, 0x8b, + 0xbb, 0xf7, 0x48, 0xb5, 0xab, 0x05, 0x9b, 0x5f, 0xa5, 0x4e, 0x9d, 0x67, + 0x08, 0xab, 0x4c, 0x9d, 0x78, 0xa8, 0x8b, 0xb3, 0x8b, 0xa5, 0xa4, 0xb8, + 0xdf, 0x08, 0x7c, 0x96, 0x05, 0x0e, 0x50, 0xf7, 0x78, 0xf7, 0x0f, 0x15, + 0x82, 0x80, 0x82, 0x80, 0x82, 0x7f, 0x6b, 0x61, 0x78, 0x7c, 0x79, 0x8b, + 0x81, 0x8b, 0x86, 0x92, 0x8b, 0x96, 0x8b, 0x92, 0x8e, 0x97, 0x90, 0x9f, + 0x8c, 0x8e, 0x8c, 0x90, 0x8c, 0x8d, 0x08, 0xf7, 0x2b, 0xf8, 0xd7, 0x86, + 0x90, 0x05, 0x50, 0x7e, 0x65, 0x84, 0x50, 0x84, 0x08, 0x7b, 0x07, 0xbb, + 0x9f, 0x84, 0x7b, 0x1f, 0x8b, 0x88, 0x8a, 0x85, 0x88, 0x82, 0x08, 0xfb, + 0x1d, 0xfc, 0xa4, 0x05, 0x88, 0x80, 0x89, 0x81, 0x8b, 0x86, 0x8b, 0x67, + 0x9c, 0x77, 0xab, 0x8b, 0xbf, 0x8b, 0xae, 0xa8, 0xcc, 0xeb, 0x08, 0x7e, + 0x94, 0x05, 0x0e, 0xf8, 0x15, 0xf9, 0x45, 0xf7, 0x09, 0x15, 0x81, 0x7f, + 0x83, 0x81, 0x88, 0x87, 0x6f, 0x67, 0x76, 0x7a, 0x7c, 0x8b, 0x83, 0x8b, + 0x86, 0x91, 0x8b, 0x95, 0x8b, 0x90, 0x8f, 0x9b, 0x91, 0xa3, 0x08, 0xcf, + 0xf7, 0x8f, 0x05, 0x8c, 0x8f, 0x8d, 0x9d, 0x8b, 0x91, 0x8b, 0xaf, 0x72, + 0xa6, 0x69, 0x8b, 0x78, 0x8b, 0x77, 0x84, 0x73, 0x7c, 0x5a, 0x6b, 0x62, + 0x5b, 0x46, 0xfb, 0x02, 0xa4, 0xd7, 0x9a, 0xc4, 0x8b, 0x9e, 0x8b, 0xae, + 0x74, 0xa4, 0x69, 0x8b, 0x08, 0x4e, 0x8b, 0x45, 0x49, 0x2f, 0xfb, 0x25, + 0x08, 0xc5, 0xf7, 0x65, 0x88, 0x8d, 0x05, 0x53, 0x7f, 0x76, 0x87, 0x38, + 0x7c, 0x08, 0x7b, 0xa4, 0x07, 0xa5, 0x98, 0x84, 0x7c, 0x1f, 0x8b, 0x80, + 0x74, 0x30, 0x67, 0xfb, 0x13, 0x08, 0x74, 0x39, 0x88, 0x81, 0x7e, 0x58, + 0x08, 0xd6, 0x06, 0xbb, 0xf7, 0x33, 0x9a, 0xb0, 0xad, 0xbf, 0xc3, 0xe0, + 0xc7, 0xc3, 0xad, 0x8b, 0x98, 0x8b, 0x92, 0x82, 0x8b, 0x7b, 0x8b, 0x82, + 0x6b, 0xfb, 0x0d, 0x4c, 0xfb, 0x7e, 0x08, 0xd6, 0x06, 0xb3, 0xf7, 0x30, + 0x9f, 0xbd, 0xbe, 0xd2, 0xbc, 0xcf, 0xbd, 0xb7, 0xa8, 0x8b, 0x96, 0x8b, + 0x94, 0x81, 0x8b, 0x80, 0x8b, 0x86, 0x89, 0x7f, 0x86, 0x79, 0x08, 0x51, + 0xfb, 0x7a, 0x05, 0x82, 0x66, 0x87, 0x78, 0x8b, 0x81, 0x08, 0x6d, 0x99, + 0x7b, 0xa5, 0x1e, 0xba, 0x8b, 0xb7, 0xac, 0xc0, 0xd5, 0x08, 0x90, 0x92, + 0x05, 0x7c, 0x97, 0x05, 0x0e, 0xf8, 0x60, 0xf7, 0x09, 0x15, 0x76, 0x71, + 0x05, 0x6e, 0x66, 0x79, 0x7b, 0x7d, 0x8b, 0x83, 0x8b, 0x83, 0x93, 0x8b, + 0x93, 0x8b, 0x92, 0x8b, 0x8b, 0x99, 0xc3, 0x08, 0xc4, 0xf7, 0x62, 0x05, + 0x90, 0xa0, 0x8f, 0xa1, 0x8b, 0x99, 0x8b, 0xaf, 0x70, 0xa4, 0x64, 0x8b, + 0x4b, 0x8b, 0x4c, 0x4f, 0x24, 0xfb, 0x34, 0x08, 0xce, 0xf7, 0x6e, 0x88, + 0x8d, 0x05, 0x55, 0x80, 0x76, 0x87, 0x34, 0x7b, 0x08, 0x7b, 0x07, 0xbe, + 0x8a, 0x98, 0x85, 0x8b, 0x77, 0x8b, 0x85, 0x8a, 0x85, 0x8a, 0x86, 0x08, + 0x2b, 0xfb, 0xf2, 0xd6, 0x8b, 0x05, 0xba, 0xf7, 0x32, 0x94, 0xa1, 0xb7, + 0xcf, 0xc7, 0xe7, 0xbe, 0xbd, 0xb0, 0x8b, 0x9a, 0x8b, 0x94, 0x80, 0x8b, + 0x79, 0x8b, 0x7f, 0x85, 0x6a, 0x83, 0x6c, 0x08, 0x5f, 0xfb, 0x39, 0x05, + 0x7e, 0x58, 0x88, 0x7d, 0x8b, 0x81, 0x8b, 0x65, 0x99, 0x7b, 0xac, 0x8b, + 0xb8, 0x8b, 0xa5, 0xa0, 0xd0, 0xe7, 0x08, 0x7d, 0x98, 0x05, 0x0e, 0xf7, + 0xd9, 0xf8, 0x4d, 0x15, 0xfb, 0x2a, 0xfb, 0x28, 0xfb, 0x2f, 0xfb, 0x31, + 0x35, 0xc3, 0x55, 0xe6, 0x1f, 0xcd, 0x8b, 0xcb, 0xa9, 0xc5, 0xc4, 0xcd, + 0xcc, 0xb3, 0xe0, 0x8b, 0xd6, 0x08, 0xde, 0x51, 0xc4, 0x36, 0x1e, 0x7f, + 0x76, 0x15, 0xb6, 0xa7, 0x66, 0x52, 0x1f, 0x8b, 0x42, 0x6a, 0x27, 0x5f, + 0x4a, 0x66, 0x56, 0x65, 0x72, 0x60, 0x8b, 0x5c, 0x8b, 0x6c, 0xaf, 0x8b, + 0xc2, 0x8b, 0xd5, 0xa8, 0xe3, 0xbc, 0xd2, 0xb2, 0xc3, 0xb5, 0xa9, 0xb6, + 0x8b, 0x08, 0x0e, 0xc3, 0xf8, 0x28, 0x15, 0xa2, 0x06, 0x8b, 0x8b, 0x8d, + 0x8b, 0x8c, 0x8c, 0x98, 0x91, 0xa5, 0x78, 0x8b, 0x7c, 0x8b, 0x82, 0x67, + 0xfb, 0x22, 0x68, 0xfb, 0x18, 0x70, 0x27, 0x73, 0x2c, 0x84, 0x6e, 0x80, + 0x5d, 0x7e, 0x7f, 0x60, 0x8a, 0x08, 0x7b, 0xf7, 0x61, 0x9a, 0x07, 0x5c, + 0x7a, 0x94, 0xa0, 0x1f, 0x8b, 0x99, 0x9c, 0xd9, 0x9f, 0xd5, 0xa4, 0x7e, + 0x9d, 0x87, 0xa2, 0x8b, 0x08, 0xf7, 0x26, 0xf7, 0x2e, 0xf7, 0x3c, 0xf7, + 0x33, 0xd9, 0x5f, 0xba, 0x44, 0x1f, 0x4a, 0x8b, 0x5b, 0x6b, 0x51, 0x3a, + 0x08, 0xa8, 0xef, 0x8e, 0x94, 0x05, 0x8b, 0x8b, 0x8a, 0x8c, 0x8a, 0x8d, + 0x08, 0x89, 0x8c, 0x05, 0x8c, 0x8a, 0x8b, 0x8b, 0x1e, 0x89, 0x8a, 0xfb, + 0x2e, 0x75, 0x05, 0x8d, 0x7c, 0x05, 0xf7, 0x99, 0x85, 0x15, 0xb6, 0x89, + 0x9e, 0x71, 0x8b, 0x51, 0x8b, 0x49, 0x6e, 0x35, 0x60, 0x4d, 0x61, 0x50, + 0x5b, 0x6c, 0x57, 0x8b, 0x6f, 0x8b, 0x77, 0x9a, 0x8b, 0xa1, 0x8b, 0xad, + 0xaf, 0xf7, 0x17, 0xa8, 0xd5, 0xa6, 0xcf, 0xc5, 0xbc, 0xbd, 0x88, 0x08, + 0x0e, 0xf8, 0x1b, 0xfb, 0x53, 0x15, 0x7a, 0x06, 0x66, 0x8b, 0x76, 0x95, + 0x8c, 0x9e, 0x8b, 0x8e, 0x8c, 0x8f, 0x8c, 0x8f, 0x08, 0xf7, 0x38, 0xf8, + 0xd5, 0x42, 0x8b, 0x7c, 0x5c, 0x05, 0x7b, 0xb9, 0x77, 0x9b, 0x62, 0x8b, + 0x08, 0xfb, 0x18, 0xfb, 0x35, 0xfb, 0x4c, 0xfb, 0x2c, 0x44, 0xb2, 0x5e, + 0xca, 0x1f, 0xd2, 0x8b, 0xb9, 0xb0, 0xe4, 0xf7, 0x13, 0x08, 0x32, 0xfb, + 0xb9, 0x05, 0x7e, 0x63, 0x7b, 0x83, 0x4a, 0x86, 0x08, 0x7b, 0xf7, 0x85, + 0x9d, 0x07, 0x45, 0xf8, 0xf6, 0x15, 0xac, 0xa5, 0x70, 0x69, 0x1f, 0x8b, + 0x38, 0x47, 0xfb, 0x22, 0x47, 0x52, 0x71, 0x75, 0x70, 0x7f, 0x73, 0x8b, + 0x69, 0x8b, 0x75, 0xa9, 0x8b, 0xba, 0x8b, 0xd5, 0xbf, 0xf7, 0x03, 0xcc, + 0xcd, 0xaa, 0xaa, 0xac, 0x9d, 0xa8, 0x8b, 0x08, 0x0e, 0xbf, 0xf7, 0x0d, + 0x16, 0xbf, 0xf7, 0x3e, 0x9c, 0xb6, 0xb9, 0xd7, 0xac, 0xc3, 0xa7, 0xaa, + 0x9c, 0x8b, 0x91, 0x8b, 0x90, 0x87, 0x90, 0x81, 0x93, 0x7a, 0x93, 0x86, + 0x9f, 0x8b, 0x08, 0xa8, 0x9c, 0x9d, 0xaa, 0xaa, 0x78, 0xa0, 0x6f, 0x1f, + 0x74, 0x8b, 0x70, 0x7c, 0x71, 0x70, 0x62, 0x61, 0x63, 0x50, 0x7b, 0x63, + 0x08, 0x7d, 0x67, 0xc0, 0xf7, 0x6d, 0x88, 0x8d, 0x05, 0x42, 0x7e, 0x82, + 0x89, 0x42, 0x7f, 0x08, 0x7a, 0x07, 0xa3, 0x90, 0x8e, 0x8b, 0x92, 0x8b, + 0xa1, 0x8b, 0x98, 0x81, 0x8b, 0x79, 0x8b, 0x7d, 0x8b, 0x8b, 0x7b, 0x47, + 0x08, 0x3a, 0xfb, 0xb8, 0xd7, 0x8b, 0x05, 0x0e, 0xbf, 0xaf, 0xf7, 0x26, + 0x15, 0x77, 0xfb, 0x33, 0x9b, 0x8b, 0x05, 0x93, 0x9b, 0x91, 0x90, 0x95, + 0x8b, 0x96, 0x8b, 0x9d, 0x87, 0x9f, 0x86, 0x08, 0xa1, 0x84, 0x9c, 0x88, + 0x9b, 0x8b, 0xdf, 0x8b, 0xc7, 0xc1, 0x8b, 0xd7, 0x8b, 0xb1, 0x76, 0xb7, + 0x5c, 0xc5, 0x65, 0xba, 0x7b, 0xaa, 0x8b, 0xa6, 0x8b, 0xac, 0xa0, 0xa0, + 0xae, 0x8b, 0xbf, 0x8b, 0xa9, 0x66, 0x95, 0x3d, 0x08, 0x9b, 0x8b, 0x05, + 0x9f, 0xf7, 0x1f, 0x7d, 0x8b, 0x05, 0x83, 0x7d, 0x83, 0x87, 0x7d, 0x8b, + 0x84, 0x8b, 0x81, 0x8d, 0x78, 0x90, 0x08, 0x72, 0x93, 0x7c, 0x8d, 0x7b, + 0x8b, 0x42, 0x8b, 0x5b, 0x60, 0x8b, 0x48, 0x8b, 0x6b, 0xa0, 0x60, 0xb5, + 0x55, 0xb2, 0x58, 0x9c, 0x68, 0x8b, 0x6e, 0x8b, 0x5e, 0x6d, 0x6b, 0x5f, + 0x8b, 0x54, 0x8b, 0x6c, 0xb4, 0x7b, 0xea, 0x08, 0x7b, 0x06, 0x0e, 0x50, + 0xf7, 0xbc, 0xf8, 0x40, 0x15, 0x3b, 0x8b, 0xa7, 0xf2, 0x05, 0x8c, 0x8d, + 0x8b, 0x8d, 0x8b, 0x8c, 0x8b, 0x92, 0x88, 0x8e, 0x86, 0x8b, 0x85, 0x8b, + 0x88, 0x8a, 0x85, 0x83, 0x64, 0x58, 0x4d, 0x59, 0x6b, 0x82, 0x72, 0x83, + 0x84, 0x85, 0x8b, 0x80, 0x8b, 0x8a, 0x8b, 0x89, 0x8c, 0x88, 0x08, 0xd5, + 0x8b, 0x43, 0xfb, 0xa7, 0x05, 0x89, 0x82, 0x8a, 0x88, 0x88, 0x82, 0x82, + 0x6d, 0x83, 0x68, 0x8b, 0x83, 0x8b, 0x75, 0xa0, 0x7b, 0xa6, 0x8b, 0xb9, + 0x8b, 0xac, 0xa7, 0xca, 0xe8, 0x08, 0x7e, 0x92, 0x05, 0x5a, 0x4c, 0x7b, + 0x7b, 0x7b, 0x8b, 0x82, 0x8b, 0x85, 0x93, 0x8b, 0x97, 0x8b, 0x8c, 0x8b, + 0x8c, 0x8c, 0x8e, 0x08, 0xe3, 0xf7, 0xe1, 0xdf, 0x8b, 0x90, 0xab, 0x05, + 0x0e, 0xf8, 0x61, 0xf7, 0x09, 0x15, 0x57, 0x4a, 0x7c, 0x7d, 0x7b, 0x8b, + 0x84, 0x8b, 0x87, 0x91, 0x8b, 0x96, 0x8b, 0x91, 0x8b, 0x8b, 0x9e, 0xd3, + 0x08, 0xda, 0xf7, 0xbf, 0x41, 0x8b, 0x05, 0x52, 0xfb, 0x2f, 0x84, 0x7b, + 0x5d, 0x42, 0x08, 0x4f, 0x2c, 0x5a, 0x58, 0x6b, 0x8b, 0x7f, 0x8b, 0x82, + 0x95, 0x8b, 0x9a, 0x8b, 0x8f, 0x8b, 0x8d, 0x8c, 0x8e, 0x08, 0xe6, 0xf7, + 0xff, 0x88, 0x8d, 0x05, 0x52, 0x7e, 0x67, 0x84, 0x52, 0x84, 0x08, 0x7d, + 0x07, 0xb1, 0x8b, 0x8d, 0x8a, 0x94, 0x86, 0x91, 0x89, 0x90, 0x82, 0x8b, + 0x84, 0x8b, 0x83, 0x86, 0x72, 0x82, 0x69, 0x08, 0x66, 0xfb, 0x22, 0x05, + 0x79, 0x44, 0x84, 0x69, 0x8b, 0x79, 0x8b, 0x67, 0x9d, 0x78, 0xae, 0x8b, + 0xd2, 0x8b, 0xc0, 0xc1, 0xf7, 0x07, 0xf7, 0x55, 0x6e, 0x20, 0x7b, 0x46, + 0x8b, 0x76, 0x08, 0x6d, 0x9d, 0x79, 0xa9, 0x1e, 0xba, 0x8b, 0xa2, 0x9f, + 0xcf, 0xec, 0x08, 0x7d, 0x94, 0x05, 0x0e, 0xf6, 0xa0, 0xf8, 0x27, 0x15, + 0x96, 0x8c, 0x93, 0x8b, 0x96, 0x8b, 0xb2, 0x8b, 0x95, 0x7a, 0x99, 0x2f, + 0x95, 0x46, 0x97, 0xfb, 0x2b, 0x8b, 0x51, 0x8b, 0x6f, 0x8d, 0x84, 0x92, + 0x8b, 0xa4, 0x8b, 0xe8, 0xf5, 0xf1, 0xf7, 0x22, 0xae, 0xbd, 0xa5, 0xcc, + 0x8b, 0xb0, 0x08, 0xab, 0x71, 0xa6, 0x6d, 0x75, 0x7c, 0x7e, 0x76, 0x1e, + 0x8b, 0x7b, 0x91, 0x7f, 0x9d, 0x7b, 0x98, 0x7f, 0x90, 0x83, 0x8b, 0x81, + 0x8b, 0x5d, 0x49, 0xfb, 0x03, 0x44, 0x41, 0x08, 0x6c, 0x6b, 0x05, 0x84, + 0xf7, 0x21, 0x85, 0xbf, 0x7e, 0xd5, 0x77, 0xf1, 0x8b, 0x8d, 0x82, 0x8b, + 0x86, 0x8b, 0x84, 0x8a, 0x83, 0x88, 0x79, 0x86, 0x54, 0x81, 0x65, 0x85, + 0x08, 0x7e, 0x07, 0x0e, 0xf7, 0xde, 0x9b, 0xf8, 0x28, 0x15, 0x9f, 0x06, + 0x8c, 0x8b, 0x8e, 0x8b, 0x90, 0x8c, 0xa7, 0x8d, 0x95, 0x81, 0x92, 0x65, + 0x97, 0x52, 0x97, 0x21, 0x8e, 0x3c, 0x08, 0x8f, 0x33, 0x05, 0x8d, 0x64, + 0x8d, 0x83, 0x94, 0x8b, 0x96, 0x8b, 0x9c, 0xa4, 0xaf, 0xd0, 0x90, 0x96, + 0x9f, 0xae, 0xa9, 0xc0, 0x08, 0xe4, 0xf7, 0x30, 0xa8, 0xfb, 0xd3, 0x05, + 0x8d, 0x70, 0x8d, 0x88, 0x92, 0x8b, 0x93, 0x8b, 0x95, 0x95, 0xa6, 0xac, + 0x8c, 0x8c, 0x8f, 0x90, 0x8f, 0x90, 0xf7, 0x1c, 0xf7, 0x37, 0xd7, 0xf7, + 0x12, 0x8b, 0xcb, 0x08, 0xa9, 0x75, 0xa1, 0x6d, 0x73, 0x7c, 0x7e, 0x76, + 0x1e, 0x8b, 0x7e, 0x90, 0x83, 0x9b, 0x7c, 0x9b, 0x7c, 0x91, 0x81, 0x8b, + 0x7f, 0x8b, 0x60, 0x69, 0x55, 0xfb, 0x17, 0xfb, 0x37, 0x08, 0x6b, 0xf7, + 0xf4, 0x05, 0x96, 0x89, 0x8e, 0x85, 0x1e, 0x86, 0x8b, 0x88, 0x89, 0x86, + 0x83, 0x08, 0xfb, 0x54, 0xfb, 0xc4, 0x05, 0x88, 0xd1, 0x80, 0xf4, 0x80, + 0xd1, 0x08, 0x80, 0xc9, 0x89, 0x93, 0x7f, 0x8b, 0x85, 0x8b, 0x80, 0x88, + 0x7e, 0x87, 0x80, 0x87, 0x73, 0x87, 0x6a, 0x86, 0x87, 0x8b, 0x81, 0x89, + 0x7f, 0x89, 0x08, 0x7e, 0x07, 0x0e, 0xf6, 0xf8, 0x26, 0xf7, 0x03, 0x15, + 0x83, 0x82, 0x86, 0x85, 0x82, 0x7f, 0x74, 0x6d, 0x7f, 0x81, 0x80, 0x8b, + 0x7c, 0x8b, 0x82, 0x98, 0x84, 0xa7, 0x89, 0x93, 0x8a, 0x91, 0x8a, 0x8e, + 0x72, 0xf0, 0x80, 0xb9, 0x8b, 0x9a, 0xb7, 0xd8, 0xaf, 0xb7, 0x9d, 0x8b, + 0x08, 0x91, 0x8b, 0x93, 0x88, 0x95, 0x86, 0x97, 0x84, 0x92, 0x89, 0x93, + 0x8b, 0x08, 0xa0, 0x99, 0x9a, 0xa0, 0xa0, 0x7a, 0x9b, 0x73, 0x1f, 0x5f, + 0x8b, 0x65, 0x67, 0x46, 0x20, 0x08, 0x80, 0xc2, 0x05, 0x7d, 0xcf, 0x80, + 0x9f, 0x70, 0x8b, 0x75, 0x8b, 0x69, 0x82, 0x4e, 0x77, 0x08, 0x80, 0x87, + 0x8f, 0x7c, 0x05, 0xb1, 0x94, 0x94, 0x8d, 0x94, 0x8b, 0xa4, 0x8b, 0x91, + 0x82, 0x99, 0x4f, 0x08, 0xa8, 0xfb, 0x0f, 0x39, 0xfb, 0x09, 0x05, 0x77, + 0x6d, 0x77, 0x79, 0x80, 0x8b, 0x85, 0x8b, 0x81, 0x8e, 0x81, 0x91, 0x7e, + 0x92, 0x80, 0x8e, 0x83, 0x8b, 0x08, 0x78, 0x7c, 0x7c, 0x77, 0x71, 0x9f, + 0x7b, 0xa9, 0x1f, 0xaa, 0x8b, 0x97, 0x94, 0xbd, 0xc8, 0xa6, 0xab, 0xa0, + 0xa6, 0xb5, 0xc5, 0x08, 0xa9, 0xfb, 0x0c, 0x05, 0x98, 0x58, 0x98, 0x7b, + 0xab, 0x8b, 0xb1, 0x8b, 0xa5, 0xa3, 0xc5, 0xe5, 0x08, 0x7d, 0x93, 0x05, + 0x0e, 0xf6, 0x9a, 0xf8, 0x24, 0x15, 0x98, 0x8e, 0x92, 0x8c, 0x96, 0x8b, + 0xc4, 0x8b, 0x9a, 0x72, 0xb9, 0xfb, 0x40, 0x9c, 0x4a, 0xa3, 0xfb, 0x09, + 0x8b, 0x7a, 0x8b, 0x7b, 0x85, 0x7b, 0x7c, 0x79, 0x6c, 0x62, 0x77, 0x71, + 0x80, 0x7f, 0x76, 0x75, 0x7f, 0x83, 0x7e, 0x8b, 0x08, 0x85, 0x8b, 0x84, + 0x8e, 0x80, 0x93, 0x7c, 0x97, 0x80, 0x90, 0x80, 0x8b, 0x08, 0x75, 0x7a, + 0x7a, 0x75, 0x72, 0xa1, 0x78, 0xa8, 0x1f, 0xcb, 0x8b, 0xf7, 0x17, 0xf7, + 0x2a, 0xf7, 0x00, 0xf7, 0x5a, 0xcf, 0xf7, 0x0f, 0xa7, 0xd3, 0x8b, 0xbc, + 0x08, 0xa9, 0x72, 0xa4, 0x6d, 0x74, 0x7b, 0x7c, 0x75, 0x1e, 0x8b, 0x7c, + 0x93, 0x80, 0x9f, 0x7e, 0x9e, 0x80, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x63, + 0x66, 0x3d, 0x36, 0xfb, 0x21, 0x08, 0x77, 0xf7, 0x08, 0x05, 0x7c, 0xe3, + 0x53, 0xf7, 0x39, 0x7c, 0x8b, 0x08, 0x87, 0x06, 0x8a, 0x8a, 0x87, 0x8b, + 0x87, 0x8b, 0x82, 0x8a, 0x67, 0x85, 0x56, 0x81, 0x86, 0x8a, 0x7e, 0x88, + 0x7d, 0x89, 0x08, 0x7a, 0x07, 0x0e, 0xbf, 0xdc, 0xf7, 0xc9, 0x15, 0xa0, + 0xbd, 0x98, 0x94, 0xba, 0x8b, 0x08, 0xf7, 0x26, 0x8b, 0xfb, 0xca, 0xfc, + 0x08, 0x94, 0x82, 0x05, 0x9b, 0x98, 0x98, 0x90, 0x9c, 0x8b, 0xa3, 0x8b, + 0xac, 0x7e, 0xba, 0x6e, 0xbd, 0x6c, 0xad, 0x7e, 0xa7, 0x8b, 0x08, 0xbd, + 0xb7, 0xaf, 0xb3, 0xa0, 0x7d, 0x9a, 0x76, 0x77, 0x7d, 0x7e, 0x79, 0x1f, + 0x8b, 0x82, 0x8e, 0x81, 0x91, 0x80, 0x8e, 0x85, 0x8d, 0x85, 0x8b, 0x88, + 0x8b, 0x82, 0x80, 0x85, 0x7b, 0x8b, 0x72, 0x8b, 0x7f, 0x93, 0x6a, 0xb5, + 0x5f, 0xc4, 0x78, 0x98, 0x51, 0x98, 0x08, 0xf7, 0xb6, 0xf7, 0xec, 0x8b, + 0x96, 0xfb, 0xb0, 0x8b, 0x6c, 0xfb, 0x07, 0x9b, 0x87, 0x05, 0x0e, 0xca, + 0xf8, 0x2b, 0xf9, 0x43, 0x15, 0xfb, 0x05, 0x8b, 0x5e, 0x69, 0x6c, 0x21, + 0x08, 0x5b, 0xfb, 0x46, 0x05, 0x78, 0x42, 0x75, 0x73, 0x4b, 0x7a, 0xb2, + 0x7d, 0x98, 0x7d, 0x8b, 0x6e, 0x8b, 0x73, 0x7f, 0x56, 0x75, 0x3f, 0x08, + 0x75, 0x40, 0x81, 0x5d, 0x8b, 0x74, 0x8b, 0x54, 0xac, 0x77, 0xe7, 0x88, + 0x08, 0x8e, 0x96, 0x05, 0x65, 0x96, 0x7c, 0x9d, 0x8b, 0xb0, 0x8b, 0x9a, + 0x91, 0xa6, 0x9b, 0xc7, 0x08, 0xa5, 0xea, 0x9d, 0xd8, 0x8b, 0x9d, 0x8b, + 0xa6, 0x7b, 0x9e, 0x64, 0x9c, 0xcc, 0x9c, 0xa5, 0xa8, 0xa1, 0xde, 0x08, + 0xb8, 0xf7, 0x3c, 0x05, 0xa0, 0xda, 0xa5, 0xa8, 0xc9, 0x9b, 0x08, 0x8e, + 0x96, 0x05, 0x0e, 0x4d, 0xf4, 0x79, 0x15, 0xcd, 0xf9, 0x40, 0x49, 0xfd, + 0x40, 0x06, 0x0e, 0xca, 0xf7, 0x71, 0xf9, 0x38, 0x15, 0xb1, 0x80, 0x9a, + 0x78, 0x8b, 0x66, 0x8b, 0x7e, 0x84, 0x6c, 0x7c, 0x52, 0x08, 0x70, 0x2b, + 0x7a, 0x3f, 0x8b, 0x79, 0x8b, 0x70, 0x9b, 0x78, 0xb2, 0x7a, 0x49, 0x7a, + 0x72, 0x6e, 0x75, 0x38, 0x08, 0x5e, 0xfb, 0x3c, 0x05, 0x76, 0x3c, 0x71, + 0x6e, 0x4d, 0x7b, 0x08, 0x88, 0x80, 0x05, 0xf7, 0x04, 0x8b, 0xb9, 0xad, + 0xaa, 0xf5, 0x08, 0xbb, 0xf7, 0x46, 0x05, 0x9e, 0xd4, 0xa1, 0xa3, 0xcb, + 0x9c, 0x64, 0x99, 0x7e, 0x99, 0x8b, 0xa8, 0x8b, 0xa3, 0x96, 0xbf, 0xa2, + 0xd8, 0x08, 0xa0, 0xd5, 0x96, 0xbb, 0x8b, 0xa1, 0x8b, 0xc1, 0x69, 0xa0, + 0x30, 0x8e, 0x08, 0x88, 0x80, 0x05, 0x0e, 0xf7, 0x60, 0xf8, 0x54, 0xf7, + 0xc3, 0x15, 0x71, 0x64, 0x7a, 0x7f, 0x6c, 0x8b, 0x76, 0x8b, 0x76, 0x90, + 0x7a, 0x94, 0x32, 0xbb, 0x79, 0x91, 0x5e, 0x8b, 0x5d, 0x8b, 0x6c, 0x76, + 0x5d, 0x4b, 0x08, 0xc1, 0x6b, 0x05, 0xa5, 0xb2, 0x9c, 0x97, 0xaa, 0x8b, + 0xa0, 0x8b, 0xa0, 0x86, 0x9c, 0x82, 0xe4, 0x5b, 0x9d, 0x85, 0xb8, 0x8b, + 0xb9, 0x8b, 0xaa, 0xa0, 0xb9, 0xcb, 0x08, 0x55, 0xab, 0x05, 0x0e, 0xbf, + 0xf7, 0x74, 0xf7, 0xb1, 0x15, 0x56, 0xfb, 0x25, 0x67, 0x33, 0x65, 0x38, + 0x6f, 0x4d, 0x81, 0x6c, 0x8b, 0x6d, 0x8b, 0x69, 0x99, 0x7a, 0xa5, 0x8b, + 0xaf, 0x8b, 0x9f, 0xac, 0x99, 0xde, 0x9e, 0xf7, 0x0a, 0x9c, 0xe4, 0xaf, + 0xf7, 0x37, 0x08, 0x7a, 0x8f, 0x05, 0xb9, 0xf7, 0x51, 0x15, 0x6d, 0x72, + 0x73, 0x6f, 0x6e, 0xa4, 0x72, 0xa8, 0xa6, 0xa4, 0xa4, 0xa5, 0xab, 0x75, + 0xa2, 0x6e, 0x1f, 0x0e, 0xf8, 0x32, 0xf8, 0xc4, 0x15, 0x6d, 0x8b, 0x61, + 0xfb, 0x0c, 0x05, 0x57, 0x83, 0x72, 0x82, 0x66, 0x73, 0x2e, 0x4f, 0x51, + 0x28, 0x8b, 0x27, 0x8b, 0x55, 0x9e, 0x5f, 0xac, 0x72, 0x9a, 0x7f, 0x99, + 0x85, 0xa6, 0x85, 0x08, 0x5b, 0xfb, 0x1c, 0xaa, 0x8b, 0xba, 0xf7, 0x19, + 0x05, 0x90, 0x8a, 0x8d, 0x8b, 0x90, 0x8b, 0xd3, 0x8b, 0xc1, 0xab, 0xc7, + 0xd6, 0x08, 0x7b, 0x95, 0x05, 0x53, 0x50, 0x65, 0x75, 0x58, 0x8b, 0x81, + 0x8b, 0x85, 0x8c, 0x83, 0x8e, 0x08, 0xf7, 0x1d, 0xf8, 0x1b, 0x05, 0xa2, + 0x8a, 0x97, 0x84, 0x8b, 0x7f, 0x8b, 0x86, 0x89, 0x86, 0x87, 0x82, 0x84, + 0x7e, 0x89, 0x84, 0x8b, 0x82, 0x08, 0x73, 0x9a, 0x7d, 0xa3, 0xa7, 0x9f, + 0x9f, 0xa5, 0x1e, 0x8b, 0xa1, 0x7f, 0xa1, 0x79, 0x99, 0x78, 0x99, 0x7b, + 0x90, 0x68, 0x8e, 0x08, 0xb5, 0xf7, 0x0c, 0x05, 0xfb, 0x68, 0xfc, 0x9b, + 0x15, 0x70, 0xa2, 0x7f, 0xa9, 0x8b, 0xb8, 0x8b, 0xcb, 0xa0, 0xd3, 0xae, + 0xc0, 0xae, 0xbf, 0xa7, 0xa1, 0xbf, 0x9a, 0x08, 0xfb, 0x18, 0xfc, 0x0c, + 0x05, 0x0e, 0xf8, 0x20, 0xf7, 0xd3, 0x15, 0x92, 0xb5, 0xfb, 0x0f, 0x8b, + 0x05, 0xb5, 0xf7, 0x76, 0xa2, 0xc1, 0xc4, 0x8b, 0xa3, 0x8b, 0x96, 0x7e, + 0x90, 0x6c, 0x90, 0x68, 0x92, 0x82, 0xa3, 0x8b, 0x08, 0xa4, 0x99, 0x99, + 0xa6, 0xb8, 0x65, 0xaa, 0x54, 0x1f, 0x55, 0x8b, 0x59, 0x70, 0x65, 0x5a, + 0x59, 0x4a, 0x76, 0x54, 0x77, 0xfb, 0x05, 0x08, 0xfb, 0x02, 0x8b, 0x82, + 0x61, 0xf7, 0x05, 0x8b, 0x72, 0xfb, 0x60, 0x05, 0x63, 0x96, 0x8a, 0x8b, + 0x7c, 0x8b, 0x08, 0x54, 0x64, 0x6f, 0x63, 0x65, 0xa5, 0x71, 0xb2, 0x1f, + 0xae, 0x8b, 0xa1, 0x99, 0xb2, 0xbc, 0x08, 0xcb, 0x5a, 0xaa, 0x7d, 0xbc, + 0x8b, 0xce, 0x8b, 0xbd, 0xae, 0xa4, 0xc9, 0x08, 0x80, 0x94, 0x81, 0x84, + 0x05, 0x6f, 0x77, 0x75, 0x84, 0x6e, 0x8b, 0x61, 0x8b, 0x5c, 0x96, 0x44, + 0xa6, 0xb4, 0xe4, 0x91, 0x9b, 0xa5, 0xf7, 0x02, 0x08, 0xf7, 0x12, 0x06, + 0xfb, 0x8e, 0xfb, 0x8a, 0x15, 0x7f, 0x69, 0x6e, 0x74, 0x6d, 0x8b, 0x08, + 0x73, 0x78, 0x9b, 0xa0, 0xa6, 0xa1, 0x9d, 0xab, 0x1f, 0xa0, 0x8b, 0x94, + 0x87, 0xa9, 0x76, 0x08, 0x0e, 0xfb, 0x3e, 0xf7, 0xe5, 0xf9, 0x38, 0x15, + 0x58, 0x8b, 0xfc, 0x5b, 0xfd, 0x42, 0xbe, 0x8b, 0xf8, 0x5b, 0xf9, 0x42, + 0x05, 0x0e, 0xf8, 0x5c, 0xf7, 0x4a, 0x15, 0x97, 0xb3, 0xfb, 0x48, 0x8b, + 0xa3, 0xdd, 0x91, 0x93, 0xf7, 0x3e, 0x8b, 0x97, 0xb3, 0xfb, 0x2b, 0x8b, + 0xf7, 0x49, 0xf7, 0x74, 0x05, 0xab, 0xb3, 0x94, 0x92, 0xab, 0x99, 0x08, + 0x9b, 0xfb, 0x51, 0x7b, 0x07, 0x97, 0x8a, 0x95, 0x8a, 0x90, 0x8a, 0xa8, + 0x88, 0x98, 0x83, 0x8b, 0x7a, 0x8b, 0x6f, 0x5a, 0x48, 0xfb, 0x05, 0xfb, + 0x17, 0x82, 0x81, 0x87, 0x85, 0x7c, 0x7a, 0x08, 0x6e, 0xef, 0x05, 0x6f, + 0xeb, 0x80, 0xb6, 0x8b, 0x9a, 0x8b, 0xa4, 0x96, 0x90, 0xcb, 0x91, 0x08, + 0x9b, 0xfb, 0x83, 0x7b, 0x07, 0xcd, 0x83, 0x90, 0x87, 0x9c, 0x55, 0x08, + 0xca, 0xfb, 0x6f, 0xfb, 0x20, 0x8b, 0x7f, 0x63, 0xf7, 0x37, 0x8b, 0x8e, + 0x81, 0x74, 0x3b, 0xfb, 0x38, 0x8b, 0x7f, 0x63, 0xf7, 0x39, 0x8b, 0x70, + 0x2f, 0x05, 0x7a, 0x58, 0x6e, 0x78, 0x4c, 0x87, 0x08, 0x87, 0x7b, 0xf7, + 0xb1, 0x8b, 0x8b, 0x9b, 0x05, 0x7a, 0x8c, 0x7c, 0x8c, 0x85, 0x8c, 0x62, + 0x8d, 0x7e, 0x95, 0x8b, 0xa5, 0x8b, 0xa1, 0x91, 0xa3, 0xa4, 0xda, 0x08, + 0xf7, 0x48, 0x06, 0x0e, 0xf8, 0x56, 0xf8, 0x30, 0x15, 0xfb, 0x12, 0x06, + 0x9d, 0xf7, 0x21, 0x92, 0xac, 0x9b, 0xaa, 0x98, 0xa2, 0x9d, 0x98, 0xa1, + 0x8b, 0x97, 0x8b, 0x94, 0x85, 0x8b, 0x83, 0x8b, 0x89, 0x89, 0x86, 0x87, + 0x84, 0x86, 0x82, 0x89, 0x86, 0x8b, 0x85, 0x08, 0x76, 0x9e, 0x79, 0xa1, + 0xa2, 0x9c, 0x9f, 0xa6, 0xb3, 0x68, 0xa8, 0x5c, 0x1e, 0x63, 0x8b, 0x66, + 0x77, 0x6d, 0x66, 0x64, 0x5a, 0x78, 0x57, 0x78, 0xfb, 0x04, 0x08, 0xfb, + 0x01, 0x8b, 0x84, 0x6d, 0xf7, 0x04, 0x8b, 0x64, 0xfb, 0xeb, 0x05, 0x7f, + 0x25, 0x81, 0x5e, 0x7a, 0x71, 0x81, 0x7c, 0x7b, 0x81, 0x7a, 0x8b, 0x7f, + 0x8b, 0x82, 0x92, 0x8b, 0x94, 0x8b, 0x8f, 0x8d, 0x90, 0x8f, 0x92, 0x91, + 0x94, 0x8d, 0x92, 0x8b, 0x91, 0x08, 0x9f, 0x79, 0x9d, 0x75, 0x72, 0x78, + 0x77, 0x6e, 0x64, 0xab, 0x70, 0xba, 0x1e, 0xe1, 0x8b, 0xce, 0xef, 0xa1, + 0xf7, 0x35, 0x08, 0xb5, 0xf7, 0xc3, 0xf7, 0x0e, 0x8b, 0x92, 0xa9, 0x05, + 0x0e, 0xf7, 0x8d, 0xf8, 0x22, 0x15, 0x7a, 0x92, 0x78, 0x8f, 0x7a, 0x8b, + 0x51, 0x8b, 0x5b, 0x53, 0x8b, 0x48, 0x8b, 0x5c, 0xa3, 0x56, 0xba, 0x56, + 0x08, 0xd7, 0x34, 0x05, 0xb1, 0x60, 0x97, 0x73, 0x8b, 0x6d, 0x08, 0x56, + 0x61, 0x66, 0x4f, 0x1e, 0x66, 0x69, 0x9c, 0x9f, 0x1f, 0x8b, 0x91, 0x8f, + 0x8f, 0x96, 0x92, 0x9f, 0x98, 0x92, 0x96, 0x8b, 0xa1, 0x08, 0xa6, 0x79, + 0x9b, 0x6e, 0x68, 0x76, 0x76, 0x68, 0x4e, 0xc7, 0x5c, 0xd7, 0xe3, 0xcf, + 0xc6, 0xd9, 0x1e, 0x8b, 0xb3, 0x81, 0xa0, 0x56, 0xcf, 0x08, 0x8d, 0x8e, + 0x05, 0x97, 0x86, 0x92, 0x89, 0x99, 0x8b, 0xd1, 0x8b, 0xbb, 0xbe, 0x8b, + 0xd6, 0x8b, 0xb4, 0x7c, 0xb4, 0x71, 0xab, 0x08, 0xfb, 0x0f, 0xf7, 0x2a, + 0x05, 0x7a, 0x9f, 0x82, 0xa5, 0x8b, 0xa5, 0x08, 0xbe, 0xae, 0xab, 0xc4, + 0x1e, 0xad, 0xa5, 0x7d, 0x7a, 0x1f, 0x8b, 0x86, 0x87, 0x85, 0x82, 0x83, + 0x7c, 0x7e, 0x85, 0x80, 0x8b, 0x7d, 0x08, 0x71, 0x9e, 0x78, 0xa6, 0xab, + 0x9f, 0xa0, 0xad, 0xc5, 0x55, 0xb4, 0x3f, 0x35, 0x4e, 0x57, 0x42, 0x1e, + 0x8b, 0x5f, 0x9c, 0x68, 0xbd, 0x4e, 0x08, 0x89, 0x88, 0x05, 0x67, 0x81, + 0x15, 0xac, 0x8b, 0xae, 0x72, 0xb2, 0x58, 0xb6, 0x53, 0x99, 0x6d, 0x8b, + 0x69, 0x08, 0x65, 0x6d, 0x6a, 0x68, 0x51, 0x20, 0xf7, 0x16, 0xd2, 0x1e, + 0xb0, 0xa9, 0xa8, 0xaf, 0x1e, 0x0e, 0x75, 0xf2, 0x15, 0xbd, 0x59, 0xeb, + 0xed, 0x05, 0xb5, 0x6f, 0xb2, 0x7e, 0xb9, 0x8b, 0xba, 0x8b, 0xb2, 0x98, + 0xb2, 0xa7, 0x08, 0xed, 0x29, 0xbb, 0xbd, 0x2b, 0xeb, 0x05, 0xa7, 0xb6, + 0x96, 0xb0, 0x8b, 0xba, 0x8b, 0xba, 0x7f, 0xb0, 0x70, 0xb4, 0x08, 0xeb, + 0xed, 0x5b, 0xbb, 0x29, 0x2b, 0x05, 0x65, 0xa6, 0x64, 0x97, 0x5b, 0x8b, + 0x5c, 0x8b, 0x66, 0x80, 0x60, 0x6f, 0x08, 0x2b, 0xeb, 0x59, 0x5b, 0xed, + 0x29, 0x05, 0x6e, 0x63, 0x7f, 0x65, 0x8b, 0x5b, 0x8b, 0x5c, 0x97, 0x66, + 0xa8, 0x61, 0x08, 0x29, 0x2b, 0x05, 0xf7, 0xa7, 0xf8, 0x09, 0x15, 0xda, + 0xcc, 0x47, 0x39, 0x36, 0x4a, 0x48, 0x3a, 0x39, 0x49, 0xcf, 0xe0, 0xde, + 0xce, 0xcd, 0xde, 0x1f, 0x0e, 0xfb, 0x0f, 0xf7, 0x2d, 0xf8, 0x39, 0x15, + 0xc4, 0xf7, 0x10, 0xaa, 0xd7, 0x8b, 0x9b, 0x8b, 0x9b, 0x7d, 0x98, 0x79, + 0x8b, 0x73, 0x8b, 0x72, 0x78, 0x86, 0x75, 0x85, 0x72, 0x82, 0x3e, 0x83, + 0x25, 0x08, 0xa0, 0x06, 0x0e, 0xf7, 0x6f, 0xf7, 0xbc, 0xf9, 0x2e, 0x15, + 0x37, 0x5c, 0x5d, 0x53, 0x8b, 0x53, 0x08, 0x63, 0xa4, 0x6c, 0xac, 0xa8, + 0xa1, 0x9f, 0xa6, 0x1e, 0x8b, 0x9c, 0x85, 0x96, 0x78, 0x9c, 0x7c, 0x99, + 0x86, 0x93, 0x8b, 0x95, 0x8b, 0xa6, 0xa2, 0xa6, 0xbf, 0xae, 0x08, 0x82, + 0x9c, 0x05, 0xf7, 0x65, 0x16, 0x37, 0x5c, 0x5d, 0x53, 0x8b, 0x53, 0x08, + 0x63, 0xa4, 0x6c, 0xac, 0xa8, 0xa1, 0x9f, 0xa6, 0x1e, 0x8b, 0x9c, 0x85, + 0x96, 0x78, 0x9c, 0x7c, 0x99, 0x86, 0x93, 0x8b, 0x95, 0x8b, 0xa6, 0xa2, + 0xa6, 0xbf, 0xae, 0x08, 0x82, 0x9c, 0x05, 0x0e, 0xc0, 0xf7, 0x6c, 0x15, + 0x97, 0x79, 0xa0, 0x70, 0xad, 0x64, 0x94, 0x81, 0x91, 0x83, 0x91, 0x82, + 0xa5, 0x64, 0xa5, 0x6e, 0x94, 0x8b, 0x8f, 0x8b, 0x8e, 0x8e, 0x8b, 0x8f, + 0x8b, 0x95, 0x71, 0xc3, 0x67, 0xce, 0x08, 0x77, 0xb3, 0x05, 0xa7, 0xa9, + 0xa5, 0xa7, 0x96, 0x94, 0xc0, 0xbc, 0xb1, 0xba, 0x8b, 0x9a, 0x8b, 0x8f, + 0x88, 0x8f, 0x87, 0x8b, 0x85, 0x8b, 0x73, 0x78, 0x49, 0x51, 0x71, 0x74, + 0x83, 0x84, 0x52, 0x5f, 0x08, 0x67, 0x70, 0x8b, 0x82, 0x05, 0xf7, 0x36, + 0x16, 0x97, 0x79, 0xa0, 0x70, 0xad, 0x64, 0x94, 0x81, 0x91, 0x83, 0x91, + 0x82, 0xa5, 0x64, 0xa5, 0x6e, 0x94, 0x8b, 0x8f, 0x8b, 0x8e, 0x8e, 0x8b, + 0x8f, 0x8b, 0x95, 0x71, 0xc3, 0x67, 0xce, 0x88, 0x90, 0x83, 0x9c, 0x82, + 0x9d, 0x08, 0xa7, 0xa9, 0xa5, 0xa7, 0x96, 0x94, 0xc0, 0xbc, 0xb1, 0xba, + 0x8b, 0x9a, 0x8b, 0x8f, 0x88, 0x8f, 0x87, 0x8b, 0x85, 0x8b, 0x73, 0x78, + 0x49, 0x51, 0x71, 0x74, 0x83, 0x84, 0x52, 0x5f, 0x08, 0x67, 0x70, 0x8b, + 0x82, 0x05, 0x0e, 0x87, 0xbe, 0xf7, 0x6c, 0x15, 0x97, 0x79, 0xa0, 0x70, + 0xad, 0x64, 0x94, 0x81, 0x91, 0x83, 0x91, 0x82, 0xa5, 0x64, 0xa5, 0x6e, + 0x94, 0x8b, 0x8f, 0x8b, 0x8e, 0x8e, 0x8b, 0x8f, 0x8b, 0x95, 0x71, 0xc3, + 0x67, 0xce, 0x08, 0x77, 0xb3, 0x05, 0xa7, 0xa9, 0xa5, 0xa7, 0x96, 0x94, + 0xc0, 0xbc, 0xb1, 0xba, 0x8b, 0x9a, 0x8b, 0x8f, 0x88, 0x8f, 0x87, 0x8b, + 0x85, 0x8b, 0x73, 0x78, 0x49, 0x51, 0x71, 0x74, 0x83, 0x84, 0x52, 0x5f, + 0x08, 0x67, 0x70, 0x8b, 0x82, 0x05, 0x0e, 0x87, 0xf7, 0xae, 0xf7, 0x74, + 0x15, 0x7f, 0x9d, 0x75, 0xa6, 0x6a, 0xb2, 0x82, 0x95, 0x85, 0x94, 0x85, + 0x93, 0x71, 0xb2, 0x71, 0xa8, 0x82, 0x8b, 0x87, 0x8b, 0x88, 0x88, 0x8b, + 0x87, 0x8b, 0x81, 0xa5, 0x53, 0xaf, 0x48, 0x08, 0x9f, 0x63, 0x05, 0x6f, + 0x6c, 0x71, 0x70, 0x80, 0x82, 0x56, 0x5a, 0x65, 0x5c, 0x8b, 0x7c, 0x8b, + 0x87, 0x8e, 0x87, 0x8f, 0x8b, 0x91, 0x8b, 0xa5, 0xa0, 0xcb, 0xc3, 0xa5, + 0xa2, 0x95, 0x93, 0xe6, 0xd1, 0x08, 0x94, 0x07, 0x0e, 0xf7, 0x18, 0xf8, + 0x20, 0x15, 0x85, 0x7c, 0x75, 0x26, 0x64, 0xfb, 0x56, 0x6d, 0xfb, 0x29, + 0x7f, 0x5f, 0x7a, 0x6c, 0x79, 0x6b, 0x79, 0x7e, 0x73, 0x8b, 0x7c, 0x8b, + 0x86, 0x8f, 0x8b, 0x94, 0x8b, 0x8e, 0x8c, 0x8e, 0x8e, 0x90, 0x8f, 0x92, + 0x8c, 0x8f, 0x8b, 0x90, 0x08, 0xa0, 0x79, 0x9c, 0x76, 0x76, 0x7b, 0x79, + 0x75, 0x67, 0xac, 0x71, 0xb8, 0x1e, 0xe5, 0x8b, 0xd0, 0xed, 0xb5, 0xf7, + 0x4d, 0x08, 0xd3, 0xf7, 0xd4, 0xf7, 0x2f, 0x8b, 0x05, 0x96, 0x90, 0x88, + 0x84, 0x1f, 0x8b, 0x87, 0x87, 0x7b, 0x77, 0x44, 0x60, 0xfb, 0x2d, 0x78, + 0x3d, 0x8b, 0x74, 0x8b, 0x6e, 0x9e, 0x77, 0xa8, 0x8b, 0xb3, 0x8b, 0xaf, + 0xa7, 0xc3, 0xd8, 0x08, 0x7b, 0x94, 0x05, 0x86, 0x85, 0x86, 0x85, 0x89, + 0x88, 0x6f, 0x6a, 0x71, 0x76, 0x7f, 0x8b, 0x85, 0x8b, 0x86, 0x90, 0x8b, + 0x90, 0x8b, 0x92, 0xac, 0xf7, 0x11, 0xb2, 0xf7, 0x23, 0x92, 0xa5, 0x90, + 0x9a, 0x94, 0xb1, 0x08, 0x8d, 0x8f, 0x05, 0x8f, 0x9b, 0x8c, 0x92, 0x8b, + 0x90, 0x08, 0x86, 0x8e, 0x05, 0x87, 0x8b, 0x87, 0x8a, 0x81, 0x8a, 0x70, + 0x87, 0x70, 0x89, 0x70, 0x8b, 0x08, 0xfb, 0x2a, 0x06, 0xa9, 0xf4, 0x9a, + 0xb3, 0x9f, 0xaa, 0xa4, 0xb1, 0xa9, 0x9c, 0xb4, 0x8b, 0xa0, 0x8b, 0x98, + 0x85, 0x8b, 0x81, 0x8b, 0x88, 0x8a, 0x89, 0x87, 0x87, 0x85, 0x84, 0x89, + 0x85, 0x8b, 0x81, 0x08, 0x72, 0x9c, 0x7a, 0xa3, 0xa4, 0x9c, 0x9c, 0xa4, + 0xb4, 0x60, 0xa8, 0x4f, 0x1e, 0x53, 0x8b, 0x54, 0x73, 0x68, 0x64, 0x61, + 0x5c, 0x77, 0x62, 0x6c, 0x25, 0x08, 0x34, 0x8b, 0x84, 0x6b, 0xe2, 0x8b, + 0x05, 0x0e, 0xf8, 0x0b, 0xf8, 0x20, 0x15, 0x83, 0x65, 0x88, 0x80, 0x75, + 0x36, 0x69, 0xfb, 0x17, 0x7e, 0x4c, 0x8b, 0x70, 0x8b, 0x6d, 0x9e, 0x77, + 0xa8, 0x8b, 0xb5, 0x8b, 0xaa, 0xa3, 0xc6, 0xdc, 0x08, 0x7b, 0x94, 0x05, + 0x5e, 0x57, 0x78, 0x7a, 0x7d, 0x8b, 0x08, 0x85, 0x86, 0x90, 0x91, 0x1f, + 0x8c, 0x95, 0x05, 0xed, 0xf8, 0x2e, 0xbc, 0xf7, 0x61, 0x8b, 0x8c, 0x8b, + 0x90, 0x89, 0x8f, 0x88, 0x8b, 0x89, 0x8b, 0x88, 0x8a, 0x86, 0x89, 0x08, + 0x87, 0x8a, 0x87, 0x8a, 0x05, 0x7c, 0x85, 0x8b, 0x8b, 0x86, 0x8b, 0x86, + 0x8b, 0x7f, 0x8d, 0x7d, 0x8d, 0x08, 0x77, 0x8f, 0x73, 0x8e, 0x7a, 0x8b, + 0x53, 0x8b, 0x53, 0x72, 0x64, 0x61, 0x60, 0x5c, 0x76, 0x62, 0x6d, 0x28, + 0x08, 0x30, 0x8b, 0x85, 0x6b, 0xe4, 0x8b, 0x6f, 0xfb, 0x18, 0x05, 0x6a, + 0xfb, 0x4c, 0x6c, 0xfb, 0x19, 0x70, 0x44, 0x88, 0x83, 0x85, 0x80, 0x82, + 0x80, 0x7e, 0x79, 0x7d, 0x84, 0x78, 0x8b, 0x7c, 0x8b, 0x85, 0x8f, 0x8b, + 0x94, 0x8b, 0x8e, 0x8c, 0x8d, 0x8e, 0x90, 0x8f, 0x92, 0x8c, 0x90, 0x8b, + 0x90, 0x08, 0x9f, 0x79, 0x9c, 0x75, 0x77, 0x7b, 0x79, 0x75, 0x67, 0xac, + 0x71, 0xb8, 0x1e, 0xe5, 0x8b, 0xd2, 0xf0, 0xb5, 0xf7, 0x51, 0x08, 0xd0, + 0xf7, 0xca, 0x05, 0xf7, 0x3a, 0x06, 0xfb, 0x33, 0xab, 0x15, 0x90, 0x9f, + 0x05, 0xaf, 0xf7, 0x26, 0xbd, 0xcd, 0xd3, 0x8b, 0xa1, 0x8b, 0xa0, 0x80, + 0x8b, 0x80, 0x8b, 0x89, 0x8a, 0x88, 0x88, 0x87, 0x86, 0x83, 0x88, 0x84, + 0x8b, 0x85, 0x8b, 0x87, 0x8d, 0x84, 0x8e, 0x85, 0x8f, 0x84, 0x8d, 0x85, + 0x8a, 0x88, 0x08, 0x8a, 0x88, 0x67, 0xfb, 0x24, 0xfb, 0x3b, 0x8b, 0x05, + 0x0e, 0xf8, 0x8d, 0xf7, 0x87, 0x15, 0xfc, 0x8b, 0x8b, 0x83, 0x5d, 0xf8, + 0x8b, 0x8b, 0x93, 0xb9, 0x05, 0x0e, 0xf7, 0x47, 0xfb, 0x33, 0x15, 0xbb, + 0xf7, 0x66, 0x05, 0x9c, 0xd2, 0xb1, 0xed, 0xa5, 0xb1, 0x7f, 0xa1, 0x87, + 0x9f, 0x8b, 0xb5, 0x8b, 0xaa, 0x8d, 0x9e, 0x92, 0xad, 0xb7, 0x8b, 0xa0, + 0x87, 0xb3, 0x7a, 0x9e, 0x83, 0x93, 0x89, 0x96, 0x8b, 0x08, 0xa7, 0x9b, + 0x9b, 0xa5, 0xa6, 0x7b, 0x98, 0x6c, 0x1f, 0x7c, 0x8b, 0x82, 0x89, 0x74, + 0x81, 0x66, 0x7c, 0x81, 0x89, 0x60, 0x8a, 0x95, 0xbb, 0x93, 0x9e, 0xa8, + 0xba, 0x9e, 0xa7, 0x90, 0x99, 0x8b, 0x9d, 0x08, 0xa8, 0x7c, 0x9b, 0x70, + 0x6d, 0x7a, 0x77, 0x66, 0x1e, 0x8b, 0x81, 0x8c, 0x83, 0x8e, 0x7a, 0x8f, + 0x78, 0x8c, 0x7f, 0x8b, 0x81, 0x8b, 0x74, 0x89, 0x79, 0x83, 0x5e, 0x60, + 0x8c, 0x81, 0x8d, 0x66, 0x9a, 0x75, 0x94, 0x81, 0x8e, 0x7d, 0x8b, 0x08, + 0x6b, 0x7b, 0x7e, 0x70, 0x71, 0x9b, 0x7b, 0xa7, 0x1f, 0x96, 0x8b, 0x93, + 0x8d, 0x9f, 0x94, 0xb2, 0x9b, 0x9b, 0x8f, 0xb4, 0x8b, 0x7e, 0x41, 0x75, + 0x5c, 0x64, 0x60, 0x8b, 0x86, 0x8b, 0x85, 0x8d, 0x7b, 0x8d, 0x78, 0x8c, + 0x7f, 0x8b, 0x81, 0x8b, 0x56, 0x7e, 0x2d, 0x76, 0x22, 0x08, 0x77, 0x26, + 0xa1, 0x8b, 0x05, 0x0e, 0xf7, 0xae, 0xf8, 0x3f, 0x15, 0x78, 0x37, 0x77, + 0x60, 0x66, 0x67, 0x99, 0x56, 0x8d, 0x83, 0x8b, 0x76, 0x8b, 0x76, 0x87, + 0x6c, 0x84, 0x69, 0x08, 0x71, 0x06, 0x78, 0x8b, 0x7c, 0x8f, 0x6d, 0x98, + 0x73, 0x95, 0x7d, 0x8f, 0x7e, 0x8b, 0x08, 0x6f, 0x77, 0x79, 0x73, 0x73, + 0x9d, 0x7b, 0xa6, 0x1f, 0x99, 0x8b, 0x95, 0x8d, 0xa4, 0x95, 0xb2, 0x9a, + 0x98, 0x8d, 0xb2, 0x8c, 0x84, 0x60, 0x84, 0x79, 0x6e, 0x5c, 0x77, 0x6c, + 0x85, 0x7c, 0x8b, 0x79, 0x08, 0x6f, 0x9c, 0x79, 0xa3, 0xa5, 0xa1, 0xa4, + 0xa8, 0x1e, 0x8b, 0x91, 0x8a, 0x94, 0x89, 0x96, 0x87, 0xa2, 0x89, 0x9f, + 0x8b, 0x9e, 0x8b, 0xa3, 0x8e, 0x9f, 0x92, 0xab, 0xb2, 0x8a, 0x98, 0x89, + 0xb2, 0x7c, 0xa3, 0x82, 0x96, 0x88, 0x97, 0x8b, 0x08, 0xa8, 0x9d, 0x9b, + 0xa3, 0xa3, 0x77, 0x9d, 0x6f, 0x1f, 0x7e, 0x8b, 0x7d, 0x87, 0x73, 0x81, + 0x6d, 0x7e, 0x7c, 0x87, 0x78, 0x8b, 0x08, 0x78, 0x06, 0x9e, 0xdf, 0x9f, + 0xb6, 0xb0, 0xaf, 0x7f, 0xb5, 0x87, 0x9e, 0x8b, 0xa1, 0x8b, 0xa0, 0x8f, + 0xac, 0x92, 0xaa, 0x08, 0xa5, 0x06, 0x9e, 0x8b, 0x9a, 0x87, 0xa9, 0x7e, + 0xa3, 0x81, 0x99, 0x87, 0x97, 0x8b, 0x08, 0xa8, 0x9f, 0x9d, 0xa3, 0xa3, + 0x79, 0x9b, 0x70, 0x1f, 0x7d, 0x8b, 0x81, 0x88, 0x72, 0x82, 0x63, 0x7c, + 0x7f, 0x89, 0x64, 0x8a, 0x92, 0xb7, 0x92, 0x9d, 0xa8, 0xba, 0x9f, 0xa9, + 0x91, 0x9b, 0x8b, 0x9d, 0x08, 0xa6, 0x7a, 0x9d, 0x73, 0x71, 0x75, 0x72, + 0x6e, 0x1e, 0x8b, 0x85, 0x8c, 0x82, 0x8d, 0x80, 0x8f, 0x74, 0x8d, 0x76, + 0x8b, 0x79, 0x8b, 0x76, 0x89, 0x77, 0x84, 0x68, 0x64, 0x8c, 0x7f, 0x8d, + 0x63, 0x9a, 0x73, 0x94, 0x80, 0x8e, 0x7f, 0x8b, 0x08, 0x6e, 0x79, 0x7b, + 0x73, 0x73, 0x9f, 0x79, 0xa7, 0x1f, 0x98, 0x8b, 0x99, 0x8f, 0xa3, 0x95, + 0xa9, 0x98, 0x9a, 0x8f, 0x9e, 0x8b, 0x08, 0x9d, 0x06, 0x0e, 0x34, 0xf7, + 0x11, 0xf7, 0xca, 0x15, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, + 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0x0e, 0xf7, 0x4e, + 0xf8, 0xfc, 0xf9, 0x21, 0x15, 0xfb, 0x95, 0x06, 0x25, 0x8b, 0x4e, 0x75, + 0x5e, 0x55, 0x67, 0x60, 0x74, 0x47, 0x8b, 0x4c, 0x8b, 0x64, 0x9b, 0x6b, + 0xa8, 0x76, 0xa7, 0x78, 0xa4, 0x84, 0xc2, 0x89, 0x7f, 0x5f, 0x84, 0x74, + 0x80, 0x5e, 0x47, 0xfb, 0x94, 0x8b, 0x8b, 0x7e, 0x87, 0x08, 0x7f, 0x85, + 0x7b, 0x88, 0x5d, 0x87, 0x08, 0x86, 0x76, 0xf7, 0x28, 0x8b, 0xf7, 0x5c, + 0xf9, 0x87, 0xc5, 0x8b, 0xfb, 0x5c, 0xfd, 0x87, 0xf7, 0x28, 0x8b, 0x90, + 0xa0, 0x05, 0x81, 0x8c, 0x81, 0x8c, 0x88, 0x8b, 0x68, 0x8f, 0x7d, 0x91, + 0x8b, 0x99, 0x8b, 0x97, 0x8e, 0x97, 0x93, 0xa5, 0x8d, 0x92, 0x8c, 0x90, + 0x8c, 0x8e, 0x08, 0xf7, 0x30, 0xf8, 0xdd, 0x05, 0x99, 0xbb, 0x92, 0x90, + 0xd7, 0x90, 0x08, 0x91, 0xa0, 0x05, 0xfb, 0xfd, 0xfb, 0xf1, 0x15, 0x6f, + 0x8e, 0x7e, 0x8f, 0x7f, 0x97, 0x76, 0x9f, 0x7f, 0xa9, 0x8b, 0xac, 0x8b, + 0xc9, 0xa7, 0xd7, 0xb1, 0xb4, 0xa7, 0xaa, 0xa7, 0x98, 0xb6, 0x8e, 0x08, + 0x3c, 0xfb, 0xdc, 0x05, 0x0e, 0x98, 0xf7, 0x42, 0xf8, 0x61, 0x15, 0x40, + 0x50, 0x4f, 0x41, 0x3f, 0xc7, 0x4f, 0xd6, 0xd5, 0xc8, 0xc8, 0xd3, 0xd8, + 0x50, 0xc7, 0x3e, 0x1f, 0x0e, 0x87, 0xc0, 0xfb, 0x15, 0x15, 0xdf, 0xba, + 0xb9, 0xc3, 0x8b, 0xc3, 0x08, 0xb3, 0x72, 0xaa, 0x6a, 0x6e, 0x75, 0x77, + 0x70, 0x1e, 0x8b, 0x7a, 0x91, 0x80, 0x9e, 0x7a, 0x9a, 0x7d, 0x90, 0x83, + 0x8b, 0x81, 0x8b, 0x70, 0x74, 0x70, 0x57, 0x68, 0x08, 0x94, 0x7a, 0x05, + 0x0e, 0xf7, 0x6f, 0xcd, 0xfb, 0x15, 0x15, 0xdf, 0xba, 0xb9, 0xc3, 0x8b, + 0xc3, 0x08, 0xb3, 0x72, 0xaa, 0x6a, 0x6e, 0x75, 0x77, 0x70, 0x1e, 0x8b, + 0x7a, 0x91, 0x80, 0x9e, 0x7a, 0x9a, 0x7d, 0x90, 0x83, 0x8b, 0x81, 0x8b, + 0x70, 0x74, 0x70, 0x57, 0x68, 0x08, 0x94, 0x7a, 0x05, 0xf7, 0x65, 0x16, + 0xdf, 0xba, 0xb9, 0xc3, 0x8b, 0xc3, 0x08, 0xb3, 0x72, 0xaa, 0x6a, 0x6e, + 0x75, 0x77, 0x70, 0x1e, 0x8b, 0x7a, 0x91, 0x80, 0x9e, 0x7a, 0x9a, 0x7d, + 0x90, 0x83, 0x8b, 0x81, 0x8b, 0x70, 0x74, 0x70, 0x57, 0x68, 0x08, 0x94, + 0x7a, 0x05, 0x0e, 0xf7, 0x6f, 0xf7, 0x34, 0xf8, 0x48, 0x15, 0xdf, 0xb9, + 0xb9, 0xc4, 0x8b, 0xc3, 0x08, 0xb3, 0x72, 0xaa, 0x6a, 0x6e, 0x75, 0x77, + 0x70, 0x1e, 0x8b, 0x7a, 0x91, 0x80, 0x9e, 0x7a, 0x99, 0x7d, 0x91, 0x82, + 0x8b, 0x81, 0x8b, 0x71, 0x74, 0x70, 0x57, 0x68, 0x08, 0x94, 0x7a, 0x05, + 0xf7, 0x65, 0x16, 0xdf, 0xb9, 0xb9, 0xc4, 0x8b, 0xc3, 0x08, 0xb3, 0x72, + 0xaa, 0x6a, 0x6e, 0x75, 0x77, 0x70, 0x1e, 0x8b, 0x7a, 0x91, 0x80, 0x9e, + 0x7a, 0x99, 0x7d, 0x91, 0x82, 0x8b, 0x81, 0x8b, 0x71, 0x74, 0x70, 0x57, + 0x68, 0x08, 0x94, 0x7a, 0x05, 0x0e, 0xf8, 0x53, 0xf7, 0x74, 0x15, 0x7f, + 0x9d, 0x75, 0xa6, 0x6a, 0xb2, 0x82, 0x95, 0x85, 0x94, 0x85, 0x93, 0x71, + 0xb2, 0x71, 0xa8, 0x82, 0x8b, 0x87, 0x8b, 0x88, 0x88, 0x8b, 0x87, 0x8b, + 0x81, 0xa5, 0x53, 0xaf, 0x48, 0x08, 0x9f, 0x63, 0x05, 0x6f, 0x6c, 0x71, + 0x70, 0x80, 0x82, 0x56, 0x5a, 0x65, 0x5c, 0x8b, 0x7c, 0x8b, 0x87, 0x8e, + 0x87, 0x8f, 0x8b, 0x91, 0x8b, 0xa5, 0xa0, 0xcb, 0xc3, 0xa5, 0xa2, 0x95, + 0x93, 0xe6, 0xd1, 0x08, 0x94, 0x07, 0xfb, 0x36, 0x16, 0x7f, 0x9d, 0x75, + 0xa6, 0x6a, 0xb2, 0x82, 0x95, 0x85, 0x94, 0x85, 0x93, 0x71, 0xb2, 0x71, + 0xa8, 0x82, 0x8b, 0x87, 0x8b, 0x88, 0x88, 0x8b, 0x87, 0x8b, 0x81, 0xa5, + 0x53, 0xaf, 0x48, 0x08, 0x9f, 0x63, 0x05, 0x6f, 0x6c, 0x71, 0x70, 0x80, + 0x82, 0x56, 0x5a, 0x65, 0x5c, 0x8b, 0x7c, 0x8b, 0x87, 0x8e, 0x87, 0x8f, + 0x8b, 0x91, 0x8b, 0xa5, 0xa0, 0xcb, 0xc3, 0xa5, 0xa2, 0x95, 0x93, 0xe6, + 0xd1, 0x08, 0x94, 0x07, 0x0e, 0xf8, 0xbc, 0xf7, 0x04, 0xef, 0x15, 0x6d, + 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa7, 0xab, 0xa5, 0xa3, 0xa9, 0xaa, + 0x71, 0xa5, 0x6d, 0x1f, 0xf7, 0xbd, 0x16, 0x6d, 0x72, 0x71, 0x6c, 0x6e, + 0xa4, 0x72, 0xa7, 0xab, 0xa5, 0xa3, 0xa9, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, + 0xf7, 0xbd, 0x16, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa7, 0xab, + 0xa5, 0xa3, 0xa9, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0x0e, 0xf9, 0x2b, 0xf8, + 0xde, 0xf9, 0x56, 0x15, 0x5f, 0x06, 0x34, 0x36, 0x78, 0x7f, 0x56, 0x8b, + 0x5e, 0x8b, 0x76, 0x93, 0x66, 0xaa, 0x6f, 0xa1, 0x7f, 0x91, 0x75, 0x8b, + 0x08, 0x26, 0x2f, 0x26, 0xfb, 0x04, 0x3e, 0xbf, 0x4f, 0xce, 0xe3, 0xd9, + 0xf7, 0x03, 0xf7, 0x12, 0x1f, 0x8b, 0x97, 0x8b, 0x8d, 0x88, 0x98, 0x8b, + 0x8c, 0x8b, 0x8e, 0x8a, 0x8e, 0xb3, 0x7e, 0x91, 0x8a, 0x9e, 0x8b, 0xc8, + 0x8b, 0xac, 0x9a, 0xb0, 0xb6, 0x08, 0xfc, 0x1d, 0xfd, 0x27, 0xb9, 0x8b, + 0x05, 0xf8, 0x43, 0xf9, 0x68, 0x05, 0xfc, 0x0a, 0x53, 0x15, 0x8f, 0x8a, + 0x90, 0x88, 0x93, 0x83, 0x96, 0x80, 0x8f, 0x88, 0x92, 0x88, 0xaa, 0x7c, + 0x8f, 0x84, 0x8b, 0x6a, 0x8b, 0xfb, 0x06, 0x4e, 0x28, 0x44, 0x8b, 0x66, + 0x8b, 0x74, 0xab, 0x8d, 0xb9, 0x8e, 0xcb, 0xa6, 0xd3, 0xb0, 0xb7, 0x08, + 0x9b, 0x9f, 0xa5, 0x9f, 0x92, 0x8a, 0x08, 0xf7, 0xed, 0xfb, 0xd4, 0x15, + 0x29, 0x2e, 0x26, 0xfb, 0x00, 0x1f, 0x8b, 0x65, 0x94, 0x6e, 0x9d, 0x72, + 0xa1, 0x6e, 0xb1, 0x78, 0xad, 0x8b, 0x08, 0xe1, 0xd8, 0xf7, 0x02, 0xf7, + 0x0d, 0x1f, 0xd6, 0x69, 0xb6, 0x50, 0x1e, 0x94, 0x6f, 0x15, 0xae, 0xa5, + 0x65, 0x59, 0x1f, 0x8b, 0x59, 0x78, 0x4e, 0x6e, 0x61, 0x72, 0x68, 0x6e, + 0x79, 0x6a, 0x8b, 0x6a, 0x8b, 0x76, 0xa7, 0x8b, 0xb7, 0x8b, 0xb7, 0x9d, + 0xcb, 0xa4, 0xb8, 0xa5, 0xb9, 0xa8, 0xa2, 0xa9, 0x8b, 0x08, 0xf7, 0xf3, + 0xa7, 0x15, 0x29, 0x2e, 0x26, 0xfb, 0x00, 0x1f, 0x8b, 0x65, 0x94, 0x6e, + 0x9d, 0x72, 0xa1, 0x6e, 0xb1, 0x78, 0xad, 0x8b, 0x08, 0xe1, 0xd8, 0xf7, + 0x01, 0xf7, 0x0e, 0xd6, 0x69, 0xb6, 0x50, 0x1f, 0x94, 0x6f, 0x15, 0xae, + 0xa5, 0x66, 0x58, 0x1f, 0x8b, 0x59, 0x78, 0x4d, 0x6e, 0x62, 0x72, 0x68, + 0x6e, 0x79, 0x6a, 0x8b, 0x6b, 0x8b, 0x75, 0xa7, 0x8b, 0xb3, 0x8b, 0xd1, + 0xab, 0xe0, 0xb7, 0xba, 0x99, 0x9a, 0x9f, 0x94, 0x9d, 0x8b, 0x08, 0x0e, + 0xf7, 0xb0, 0xf7, 0xb1, 0x15, 0x84, 0x6e, 0x05, 0x7d, 0x53, 0x6d, 0x65, + 0x44, 0x52, 0xfb, 0x06, 0x2e, 0x77, 0x70, 0x8b, 0x4e, 0x08, 0x3d, 0xc5, + 0x58, 0xe4, 0xde, 0xc5, 0xb8, 0xcb, 0xa9, 0x7c, 0x9d, 0x73, 0x73, 0x7b, + 0x7c, 0x77, 0x1e, 0x8b, 0x83, 0x8d, 0x86, 0x90, 0x7f, 0x91, 0x7e, 0x8d, + 0x85, 0x8b, 0x83, 0x08, 0x6d, 0x70, 0x79, 0x60, 0x58, 0x6e, 0xa9, 0xc1, + 0x1e, 0x8b, 0xc0, 0xa1, 0xb5, 0xcc, 0xd2, 0xde, 0xea, 0x96, 0xa1, 0x9d, + 0xee, 0x08, 0x7a, 0x8d, 0x05, 0xa9, 0xf7, 0x50, 0x15, 0x6f, 0x73, 0x72, + 0x70, 0x6e, 0xa3, 0x73, 0xa8, 0xa8, 0xa2, 0xa2, 0xa9, 0x1f, 0xa8, 0x74, + 0xa2, 0x6d, 0x1e, 0x0e, 0x87, 0xf7, 0xac, 0xf8, 0x80, 0x15, 0xaa, 0x8b, + 0xfb, 0x08, 0xf7, 0x29, 0x05, 0x7e, 0x9b, 0x80, 0x92, 0x7c, 0x8b, 0x77, + 0x8b, 0x7c, 0x7c, 0x8b, 0x78, 0x8b, 0x7f, 0x91, 0x81, 0x98, 0x81, 0x08, + 0xf7, 0x20, 0x21, 0x05, 0x0e, 0x87, 0xf7, 0x48, 0xf8, 0x82, 0x15, 0xae, + 0x8b, 0xf7, 0x3f, 0xf5, 0x05, 0x97, 0x92, 0x90, 0x94, 0x8b, 0x97, 0x8b, + 0x9f, 0x7b, 0x9b, 0x77, 0x8b, 0x81, 0x8b, 0x83, 0x87, 0x84, 0x85, 0x08, + 0xfb, 0x36, 0xfb, 0x34, 0x05, 0x0e, 0x87, 0xf7, 0xbd, 0xf9, 0x29, 0x15, + 0x5a, 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, + 0x23, 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0x87, 0xf8, 0x23, 0xf9, + 0x04, 0x15, 0x80, 0x6a, 0x7e, 0x80, 0x70, 0x8b, 0x7c, 0x8b, 0x7a, 0x90, + 0x6d, 0x99, 0x08, 0x65, 0x9c, 0x71, 0x92, 0x75, 0x8b, 0x57, 0x8b, 0x6f, + 0x6e, 0x77, 0x3e, 0x08, 0xa8, 0x06, 0x95, 0xab, 0x9b, 0x9a, 0xa4, 0x8b, + 0x9c, 0x8b, 0xa3, 0x84, 0xc1, 0x75, 0x08, 0xa5, 0x81, 0x9e, 0x86, 0x97, + 0x8b, 0xbb, 0x8b, 0xac, 0xb0, 0x99, 0xce, 0x08, 0x6f, 0x06, 0x0e, 0x87, + 0xf8, 0x2f, 0xf8, 0xdb, 0x15, 0xfb, 0xc1, 0x8b, 0x80, 0x58, 0xf7, 0xc1, + 0x8b, 0x96, 0xbe, 0x05, 0x0e, 0x87, 0xf8, 0x19, 0xf9, 0x1e, 0x15, 0x72, + 0x4c, 0x5a, 0x67, 0x4e, 0x8b, 0x4b, 0x8b, 0x64, 0xb0, 0x86, 0xc9, 0x08, + 0x6e, 0x06, 0x8b, 0x52, 0x93, 0x6c, 0x9f, 0x71, 0xa2, 0x6e, 0xad, 0x7c, + 0xb8, 0x8b, 0xc0, 0x8b, 0xba, 0xa3, 0xac, 0xb8, 0x9f, 0xa5, 0x94, 0xa0, + 0x94, 0xb5, 0x08, 0x6e, 0x06, 0x0e, 0x87, 0xf7, 0x95, 0xf8, 0xf2, 0x15, + 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, + 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0x0e, 0x87, 0xf7, 0x31, 0xf8, 0xf2, 0x15, + 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, + 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0xf7, 0x5c, 0x16, 0x6f, 0x75, 0x75, 0x71, + 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, + 0x1f, 0x0e, 0x87, 0xf7, 0x92, 0xf9, 0x57, 0x15, 0x55, 0x5e, 0x5e, 0x55, + 0x53, 0xb7, 0x5f, 0xc3, 0xc2, 0xb8, 0xb8, 0xc1, 0xc2, 0x5d, 0xb8, 0x54, + 0x1f, 0x69, 0x04, 0xb0, 0xa9, 0x6d, 0x67, 0x66, 0x6e, 0x6f, 0x65, 0x67, + 0x6e, 0xa8, 0xb0, 0xae, 0xa9, 0xa9, 0xae, 0x1f, 0x0e, 0x87, 0xa0, 0x2b, + 0x15, 0x94, 0x83, 0x05, 0x99, 0x90, 0x93, 0x8d, 0x95, 0x8b, 0x08, 0xa6, + 0x9e, 0x79, 0x71, 0x71, 0x78, 0x7c, 0x69, 0x1f, 0x76, 0x8b, 0x7a, 0x8f, + 0x6d, 0x96, 0x08, 0x7a, 0x6e, 0x05, 0xb5, 0x7b, 0xa2, 0x86, 0xa7, 0x8b, + 0x08, 0xd0, 0xbd, 0xaf, 0xbd, 0xb4, 0x6b, 0xa6, 0x59, 0x1f, 0x83, 0x8b, + 0x84, 0x8a, 0x81, 0x89, 0x08, 0xb7, 0xcd, 0x65, 0x8b, 0x4f, 0x2b, 0x05, + 0x0e, 0x87, 0xe8, 0xf8, 0x82, 0x15, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, + 0x97, 0x92, 0x90, 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, + 0x81, 0x8b, 0x83, 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, + 0xf7, 0x3e, 0x16, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, 0x97, 0x92, 0x90, + 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, 0x81, 0x8b, 0x83, + 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, 0x0e, 0x87, 0xf7, + 0x4b, 0x41, 0x15, 0x70, 0x75, 0x72, 0x81, 0x6c, 0x8b, 0x69, 0x8b, 0x72, + 0xa0, 0x8b, 0xa9, 0x8b, 0xa9, 0x96, 0xa9, 0xa1, 0xae, 0x08, 0x73, 0x06, + 0x59, 0x65, 0x77, 0x6b, 0x8b, 0x5f, 0x8b, 0x57, 0xb6, 0x60, 0xbf, 0x8b, + 0xbb, 0x8b, 0xb5, 0xa5, 0xae, 0xbe, 0x08, 0x7a, 0x9d, 0x05, 0x0e, 0x87, + 0xf8, 0x3e, 0xf9, 0x29, 0x15, 0x67, 0x8b, 0xfb, 0x22, 0x22, 0x31, 0xf4, + 0x66, 0x8b, 0xeb, 0xfb, 0x3d, 0xb9, 0x8b, 0xf7, 0x37, 0xf7, 0x3d, 0x05, + 0x0e, 0xf8, 0xbc, 0xfa, 0x12, 0xf7, 0x87, 0x15, 0xfe, 0x10, 0x8b, 0x83, + 0x5d, 0xfa, 0x10, 0x8b, 0x93, 0xb9, 0x05, 0x0e, 0xf8, 0xbc, 0xf9, 0xce, + 0xf7, 0x3d, 0x15, 0x3f, 0xfb, 0x01, 0x55, 0x70, 0xfb, 0x2a, 0x8b, 0x08, + 0x6d, 0x06, 0x68, 0x7b, 0x94, 0x9f, 0x1f, 0x8b, 0x97, 0x98, 0xbb, 0xc5, + 0xf7, 0x62, 0x08, 0xb3, 0x06, 0xec, 0xa0, 0x82, 0x62, 0x1f, 0x8b, 0x7d, + 0x89, 0x7d, 0x87, 0x73, 0x08, 0x9c, 0x87, 0xd0, 0xf7, 0x7c, 0x79, 0x8f, + 0x05, 0x61, 0x30, 0x81, 0x86, 0xfb, 0x33, 0x8a, 0x08, 0xc8, 0xf7, 0x72, + 0x05, 0x94, 0xab, 0x93, 0x90, 0xba, 0x8b, 0xf7, 0x38, 0x8b, 0xa7, 0x7f, + 0x8b, 0x45, 0x8b, 0x85, 0x8b, 0x7a, 0x8a, 0x7e, 0x08, 0x9c, 0x89, 0xac, + 0xf7, 0x2d, 0xfc, 0x99, 0x8b, 0x8b, 0x7c, 0x05, 0x96, 0x8a, 0x96, 0x8a, + 0x8f, 0x8b, 0xa6, 0x89, 0x96, 0x83, 0x8b, 0x7b, 0x8b, 0x7f, 0x89, 0x87, + 0x6d, 0x66, 0x08, 0xfc, 0x05, 0xfc, 0x65, 0x05, 0x5b, 0x4f, 0x7f, 0x81, + 0x73, 0x85, 0x08, 0x7b, 0xf7, 0x4f, 0x9b, 0x07, 0x56, 0x91, 0x80, 0x91, + 0x8b, 0x9e, 0x8b, 0xa2, 0xb2, 0xc8, 0xc8, 0xd4, 0x8f, 0x8f, 0x95, 0x97, + 0x96, 0x99, 0x08, 0xf7, 0x52, 0x8b, 0x5a, 0xfb, 0x3e, 0x05, 0x7f, 0x66, + 0x84, 0x86, 0x4e, 0x85, 0x08, 0x7b, 0xf8, 0x86, 0x07, 0xcb, 0xf7, 0x38, + 0x79, 0x90, 0x05, 0xfc, 0xd5, 0xf1, 0x15, 0xf7, 0xa0, 0xf7, 0xea, 0x2c, + 0xfb, 0xea, 0xfb, 0x41, 0x8b, 0x05, 0x0e, 0x4e, 0xf7, 0xbf, 0xf9, 0x35, + 0x15, 0x89, 0x89, 0x84, 0x6d, 0x05, 0x86, 0xa3, 0x77, 0x96, 0x69, 0x8b, + 0x08, 0x33, 0x26, 0x20, 0x2e, 0x60, 0xa9, 0x70, 0xbb, 0x1f, 0xbc, 0x8b, + 0xa7, 0x9e, 0xbc, 0xcf, 0x7d, 0x68, 0x88, 0x81, 0x8b, 0x7b, 0x8b, 0x7b, + 0x97, 0x81, 0x9e, 0x8b, 0xa5, 0x8b, 0x9a, 0x96, 0xbc, 0xc2, 0x08, 0x84, + 0x95, 0x05, 0x85, 0x85, 0x85, 0x85, 0x89, 0x88, 0x81, 0x81, 0x80, 0x81, + 0x8a, 0x8b, 0x08, 0x85, 0x88, 0x05, 0x8a, 0x8a, 0x8a, 0x8b, 0x8a, 0x8b, + 0x89, 0x8b, 0x89, 0x8e, 0x8b, 0x8e, 0x8b, 0x8d, 0x8b, 0x8e, 0x8c, 0x8e, + 0x08, 0x8e, 0x9a, 0x05, 0x8f, 0xa0, 0x9c, 0xcd, 0xac, 0xf7, 0x08, 0x08, + 0x56, 0x89, 0x05, 0x5a, 0x7c, 0x15, 0x96, 0x89, 0x93, 0x7c, 0x8b, 0x76, + 0x8b, 0x6d, 0x75, 0x54, 0x71, 0x64, 0x72, 0x67, 0x6f, 0x77, 0x73, 0x8b, + 0x7c, 0x8b, 0x7d, 0x9f, 0x8b, 0x9f, 0x08, 0x8b, 0xd5, 0xdf, 0xf7, 0x03, + 0xbe, 0x84, 0x08, 0x0e, 0xf7, 0x6f, 0xf8, 0xaf, 0xf7, 0x4d, 0x15, 0x68, + 0x43, 0x70, 0x6b, 0x5f, 0x75, 0x68, 0x7a, 0x62, 0x85, 0x37, 0x8b, 0x3c, + 0x8b, 0x71, 0x93, 0x8b, 0xa5, 0x8b, 0x95, 0x96, 0xb8, 0xa6, 0xe8, 0x08, + 0xad, 0xf7, 0x0f, 0xf7, 0x22, 0xde, 0x99, 0xbc, 0xfb, 0x23, 0x36, 0xbc, + 0xf7, 0x43, 0x05, 0x9a, 0xbe, 0xa5, 0x9e, 0xc7, 0x8f, 0x08, 0x9b, 0xfb, + 0xa5, 0x7b, 0x07, 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x6e, 0x8b, 0x7d, 0x87, + 0x74, 0x84, 0x72, 0x08, 0x53, 0xfb, 0x5c, 0x28, 0x50, 0x7e, 0x5b, 0xee, + 0xc6, 0x55, 0xfb, 0x56, 0x05, 0x79, 0x51, 0x84, 0x85, 0x53, 0x81, 0x08, + 0x7b, 0xf8, 0x91, 0x07, 0xc5, 0xf7, 0x47, 0x77, 0x91, 0x05, 0x0e, 0xf8, + 0x15, 0xf9, 0x31, 0xf9, 0x66, 0x15, 0x5f, 0x8b, 0x57, 0x3d, 0x05, 0x66, + 0x9b, 0x6c, 0x91, 0x66, 0x8b, 0x3d, 0x8b, 0x31, 0x62, 0x3b, 0x43, 0x26, + 0x2e, 0x50, 0xfb, 0x0d, 0x8b, 0xfb, 0x09, 0x8b, 0x31, 0xa8, 0x4d, 0xcd, + 0x5b, 0x08, 0x35, 0xfb, 0x13, 0xb7, 0x8b, 0xd5, 0xf7, 0x00, 0x05, 0xb1, + 0x7c, 0xa4, 0x85, 0xaa, 0x8b, 0xf7, 0x66, 0x8b, 0xf7, 0x64, 0xf7, 0x73, + 0x8b, 0xf7, 0x76, 0x8b, 0xb9, 0x7f, 0xba, 0x75, 0xb1, 0x7c, 0xa4, 0x7f, + 0x98, 0x6a, 0xa5, 0x08, 0xcb, 0xeb, 0x05, 0xfc, 0x73, 0xfd, 0x1c, 0x15, + 0x79, 0xad, 0x84, 0xa9, 0x8b, 0xb1, 0x8b, 0xf2, 0xba, 0xf7, 0x24, 0xca, + 0xe6, 0xc2, 0xdb, 0xca, 0xb2, 0xd2, 0x8b, 0xac, 0x8b, 0xa3, 0x83, 0xa4, + 0x79, 0x08, 0xfb, 0xf8, 0xfc, 0xa9, 0x05, 0xf8, 0x10, 0xf8, 0x88, 0x15, + 0x9b, 0x6e, 0x93, 0x6c, 0x8b, 0x64, 0x8b, 0x25, 0x5a, 0xfb, 0x2b, 0x4d, + 0x31, 0x54, 0x3c, 0x4d, 0x65, 0x44, 0x8b, 0x69, 0x8b, 0x73, 0x93, 0x75, + 0xa0, 0x08, 0xf7, 0xf7, 0xf8, 0xa6, 0x05, 0x0e, 0xf8, 0xf3, 0xfa, 0x58, + 0xf9, 0x21, 0x15, 0xfc, 0x05, 0x06, 0x7e, 0x8b, 0x79, 0x8d, 0x74, 0x8e, + 0x08, 0x6c, 0x8f, 0x5d, 0x8f, 0x76, 0x8b, 0x08, 0xfb, 0x63, 0xfb, 0x4f, + 0xfb, 0x65, 0xfb, 0x7c, 0xfb, 0x19, 0xec, 0x27, 0xf7, 0x16, 0x1f, 0x9e, + 0x8b, 0xa7, 0x8c, 0xad, 0x8d, 0x08, 0xe8, 0x90, 0x8b, 0x8b, 0xb1, 0x8b, + 0x08, 0xf7, 0xee, 0x8b, 0xcc, 0xf7, 0x3a, 0x7b, 0x91, 0x05, 0x3b, 0xfb, + 0x02, 0x50, 0x6e, 0xfb, 0x25, 0x8b, 0x52, 0x8b, 0x79, 0x94, 0x8b, 0xa6, + 0x8b, 0x93, 0x8e, 0x9a, 0x93, 0xab, 0x08, 0x8d, 0x92, 0x05, 0x8c, 0x8e, + 0x8c, 0x8e, 0x8b, 0x8c, 0x08, 0xbf, 0xf7, 0x52, 0xc9, 0x88, 0x05, 0xda, + 0x88, 0x9a, 0x82, 0x8c, 0x5c, 0x89, 0x7a, 0x8a, 0x88, 0x88, 0x75, 0x08, + 0x9f, 0x89, 0xcd, 0xf7, 0x7a, 0x79, 0x8f, 0x05, 0x62, 0x31, 0x81, 0x86, + 0xfb, 0x27, 0x8b, 0x08, 0x7f, 0x8b, 0xcb, 0xf7, 0x77, 0x05, 0x92, 0xa3, + 0x94, 0x93, 0xa0, 0x8b, 0x08, 0xeb, 0x06, 0xd6, 0x8b, 0xa9, 0x7e, 0x94, + 0x68, 0x90, 0x7b, 0x8c, 0x7d, 0x8b, 0x64, 0x08, 0x9b, 0x8b, 0x05, 0xaa, + 0xf7, 0x2a, 0x05, 0xfc, 0x8e, 0xfc, 0x5a, 0x15, 0x76, 0x3f, 0x7e, 0x6c, + 0x73, 0x6e, 0x77, 0x72, 0x66, 0x7d, 0x61, 0x8b, 0x2c, 0x8b, 0x5a, 0xc7, + 0x8b, 0xf7, 0x0a, 0x8b, 0xf7, 0x24, 0xce, 0xf7, 0x35, 0xe7, 0xd7, 0xb3, + 0xad, 0xb8, 0x9c, 0xba, 0x8b, 0xc7, 0x8b, 0xb6, 0x6a, 0x8b, 0x5d, 0x08, + 0x8b, 0x7c, 0x8b, 0x8b, 0x77, 0x42, 0x08, 0x42, 0xfb, 0xa0, 0x05, 0x0e, + 0x70, 0xf7, 0x9d, 0xf9, 0x38, 0x15, 0x26, 0x2a, 0x2f, 0x2c, 0x59, 0xb1, + 0x6a, 0xc6, 0xed, 0xef, 0xe9, 0xe7, 0xbc, 0x63, 0xae, 0x52, 0x1f, 0x84, + 0x75, 0x15, 0xa0, 0x8a, 0x95, 0x7b, 0x8b, 0x6d, 0x8b, 0x57, 0x71, 0x4a, + 0x67, 0x65, 0x7e, 0x7e, 0x78, 0x82, 0x7a, 0x8b, 0x74, 0x8b, 0x7c, 0x9d, + 0x8b, 0xa7, 0x8b, 0xe0, 0xcb, 0xec, 0xc1, 0x87, 0x08, 0x0e, 0xf7, 0xde, + 0xf8, 0xe0, 0xf7, 0x05, 0x15, 0x50, 0x53, 0x63, 0x76, 0x60, 0x8b, 0x5d, + 0x8b, 0x73, 0xae, 0x8b, 0xcd, 0x8b, 0xa1, 0x8d, 0x96, 0x91, 0xa7, 0xf6, + 0xaa, 0xbb, 0x9d, 0xb1, 0xa4, 0xb5, 0xa7, 0xa0, 0xac, 0x8b, 0xb1, 0x8b, + 0xb6, 0x6c, 0xa6, 0x59, 0x8b, 0x08, 0x62, 0x8b, 0x69, 0x79, 0x5c, 0x5d, + 0x08, 0xa1, 0xc9, 0x44, 0x89, 0x78, 0x60, 0x05, 0x7b, 0xaf, 0x7b, 0x96, + 0x69, 0x8b, 0x08, 0xfb, 0x10, 0xfb, 0x30, 0xfb, 0x5c, 0xfb, 0x32, 0x1f, + 0x54, 0xae, 0x64, 0xbc, 0x1e, 0xcb, 0x8b, 0xb9, 0xb1, 0xe0, 0xf7, 0x10, + 0x87, 0x7b, 0x89, 0x81, 0x8b, 0x7d, 0x08, 0x44, 0xb7, 0x58, 0xca, 0x1e, + 0xca, 0x8b, 0xd7, 0xb7, 0xc3, 0xcf, 0x08, 0x81, 0x97, 0x05, 0xfb, 0xaf, + 0xf7, 0xc8, 0x15, 0xa6, 0x8a, 0x9d, 0x77, 0x8b, 0x6d, 0x8b, 0x35, 0x54, + 0xfb, 0x12, 0x43, 0x3d, 0x74, 0x72, 0x6c, 0x7b, 0x71, 0x8b, 0x74, 0x8b, + 0x7e, 0xa1, 0x8d, 0xb2, 0x08, 0x92, 0xf7, 0x26, 0xf7, 0x02, 0xf7, 0x47, + 0xda, 0x87, 0x08, 0xe0, 0xfb, 0x5a, 0x15, 0xa9, 0xe4, 0x9d, 0xad, 0xae, + 0xb1, 0x9f, 0x9f, 0xa2, 0x97, 0xa2, 0x8b, 0xa2, 0x8b, 0x97, 0x7e, 0x8b, + 0x73, 0x8b, 0x53, 0x58, 0x52, 0x42, 0x72, 0x7e, 0x86, 0x78, 0x86, 0x6f, + 0x83, 0x08, 0x0e, 0x50, 0xf7, 0x72, 0xf7, 0x06, 0x15, 0x73, 0x6b, 0x84, + 0x83, 0x81, 0x80, 0x7a, 0x7a, 0x7c, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x83, + 0x93, 0x8b, 0x92, 0x8b, 0x95, 0x8e, 0x9a, 0x92, 0x9e, 0x8b, 0x8e, 0x8e, + 0x92, 0x8d, 0x93, 0x08, 0x8b, 0x8d, 0x8c, 0x8d, 0xe3, 0xf7, 0xd6, 0x88, + 0x8d, 0x05, 0x26, 0x78, 0x77, 0x88, 0x64, 0x88, 0x08, 0x7b, 0x07, 0xc0, + 0x8a, 0x95, 0x88, 0x8b, 0x77, 0x8b, 0x83, 0x88, 0x7b, 0x85, 0x77, 0x08, + 0x5b, 0xfb, 0x45, 0x05, 0x7b, 0x51, 0x85, 0x6c, 0x8b, 0x77, 0x8b, 0x66, + 0x9b, 0x77, 0xa9, 0x8b, 0xb9, 0x8b, 0xb0, 0xa9, 0xc4, 0xdf, 0x08, 0x7e, + 0x96, 0x05, 0x0e, 0x50, 0xf7, 0x65, 0xf8, 0x2e, 0x15, 0xd1, 0xf7, 0xa0, + 0x86, 0x90, 0x05, 0x50, 0x7e, 0x65, 0x84, 0x50, 0x84, 0x08, 0x7b, 0x07, + 0xbc, 0x9e, 0x84, 0x7a, 0x1f, 0x8b, 0x83, 0x76, 0x38, 0x5f, 0xfb, 0x39, + 0x08, 0x43, 0x67, 0x7f, 0x5d, 0xd3, 0xaf, 0x05, 0x82, 0x69, 0x82, 0x6b, + 0x88, 0x81, 0x6e, 0x2a, 0x79, 0x40, 0x8b, 0x76, 0x8b, 0x66, 0x9c, 0x78, + 0xab, 0x8b, 0xbf, 0x8b, 0xad, 0xa8, 0xcc, 0xeb, 0x08, 0x7e, 0x94, 0x05, + 0x82, 0x80, 0x83, 0x80, 0x82, 0x7f, 0x6a, 0x61, 0x79, 0x7c, 0x79, 0x8b, + 0x81, 0x8b, 0x86, 0x91, 0x8b, 0x97, 0x8b, 0x92, 0x8e, 0x98, 0x90, 0x9e, + 0x8b, 0x8f, 0x8c, 0x8e, 0x8c, 0x8c, 0x08, 0x8b, 0x8d, 0xd0, 0xf7, 0x9d, + 0xed, 0xbd, 0x97, 0xb9, 0x29, 0x59, 0x05, 0x0e, 0xf8, 0x40, 0xf8, 0xbe, + 0x15, 0x69, 0x8b, 0x54, 0xfb, 0x06, 0x05, 0x84, 0x8c, 0x86, 0x8b, 0x87, + 0x8b, 0xfb, 0x25, 0x8b, 0xfb, 0x2a, 0xfb, 0x32, 0x8b, 0xfb, 0x2d, 0x8b, + 0x64, 0x98, 0x67, 0xa3, 0x72, 0x9a, 0x7b, 0x98, 0x83, 0xaa, 0x81, 0x08, + 0x4b, 0xfb, 0x17, 0xae, 0x8b, 0xc8, 0xf7, 0x12, 0x05, 0x91, 0x89, 0x90, + 0x8b, 0x94, 0x8b, 0xc9, 0x8b, 0xc7, 0xa6, 0xc4, 0xbf, 0xd1, 0xcc, 0xb7, + 0xe4, 0x8b, 0xd7, 0x8b, 0xa6, 0x83, 0xab, 0x7e, 0xa1, 0x79, 0xa9, 0x78, + 0x99, 0x62, 0x97, 0x08, 0xc5, 0xf7, 0x0b, 0x05, 0xfb, 0xb4, 0xfc, 0xa1, + 0x15, 0x78, 0x9e, 0x82, 0xa1, 0x8b, 0xa6, 0x8b, 0xea, 0xb8, 0xf7, 0x04, + 0xcd, 0xd1, 0xa6, 0xa8, 0xae, 0x9c, 0xac, 0x8b, 0x8d, 0x8b, 0x8e, 0x8a, + 0x90, 0x8a, 0x08, 0xfb, 0x50, 0xfc, 0x19, 0x05, 0xf7, 0x6d, 0xf8, 0x0d, + 0x15, 0x9e, 0x76, 0x94, 0x72, 0x8b, 0x68, 0x8b, 0x42, 0x6b, 0x27, 0x5e, + 0x4a, 0x66, 0x56, 0x65, 0x73, 0x5f, 0x8b, 0x82, 0x8b, 0x86, 0x8c, 0x83, + 0x8e, 0x08, 0xf7, 0x52, 0xf8, 0x1c, 0x05, 0x0e, 0xf7, 0xde, 0xf8, 0xe5, + 0xf4, 0x15, 0x3d, 0x4f, 0x6e, 0x7c, 0x65, 0x8b, 0x5f, 0x8b, 0x6c, 0xae, + 0x8b, 0xbc, 0x8b, 0xa0, 0x90, 0xad, 0x90, 0x9b, 0x8f, 0x97, 0x93, 0x8f, + 0xa3, 0x8d, 0xb6, 0x8f, 0xd5, 0xa8, 0xb3, 0xa7, 0xb7, 0xaa, 0xa5, 0xb3, + 0x8b, 0xb1, 0x08, 0xb5, 0x6d, 0xa5, 0x58, 0x1e, 0x55, 0x8b, 0x66, 0x79, + 0x47, 0x4d, 0x08, 0x7a, 0xbd, 0x61, 0xa9, 0x56, 0x8b, 0x08, 0xfb, 0x15, + 0xfb, 0x25, 0xfb, 0x36, 0xfb, 0x24, 0x37, 0xc8, 0x4d, 0xdf, 0x1f, 0xbe, + 0x8b, 0xaf, 0x9c, 0xbe, 0xbd, 0x08, 0xa3, 0x5e, 0xae, 0x74, 0xb8, 0x8b, + 0xca, 0x8b, 0xc7, 0xab, 0xd5, 0xd5, 0x08, 0x80, 0x96, 0x05, 0xfb, 0xc9, + 0xf7, 0xcd, 0x15, 0xaf, 0xa2, 0x71, 0x63, 0x1f, 0x8b, 0x69, 0x7f, 0x51, + 0x76, 0x44, 0x79, 0x50, 0x7d, 0x69, 0x76, 0x6d, 0x08, 0x70, 0x64, 0x70, + 0x79, 0x6a, 0x8b, 0x62, 0x8b, 0x71, 0xae, 0x8b, 0xc3, 0x8b, 0xed, 0xb8, + 0xf7, 0x08, 0xca, 0xd0, 0xa1, 0xa2, 0xa4, 0x97, 0xa5, 0x8b, 0x08, 0xf7, + 0x00, 0xfb, 0x5f, 0x15, 0xa5, 0xdf, 0x9e, 0xaf, 0xb2, 0xb5, 0xa2, 0xa4, + 0xa5, 0x99, 0xa0, 0x8b, 0xa0, 0x8b, 0x98, 0x7c, 0x8b, 0x73, 0x8b, 0x65, + 0x71, 0x60, 0x60, 0x6b, 0x08, 0x71, 0x78, 0x80, 0x87, 0x39, 0x71, 0x08, + 0x0e, 0xf7, 0xde, 0xf8, 0x14, 0x15, 0x93, 0x8e, 0x05, 0xf7, 0x02, 0xb4, + 0xb8, 0xba, 0x8b, 0xd4, 0x8b, 0xd9, 0x53, 0xc0, 0x38, 0x8b, 0xfb, 0x10, + 0x8b, 0x3e, 0xfb, 0x00, 0x51, 0xfb, 0x94, 0x08, 0x43, 0xfb, 0xd3, 0x05, + 0x6d, 0xfb, 0x1b, 0x70, 0x5f, 0x5a, 0x8b, 0x80, 0x8b, 0x84, 0x8e, 0x8b, + 0x90, 0x8b, 0x8e, 0x8c, 0x8e, 0x8e, 0x8f, 0x90, 0x93, 0x8e, 0x96, 0x8b, + 0x92, 0x08, 0xa0, 0x7a, 0x9a, 0x74, 0x73, 0x7c, 0x7b, 0x71, 0x66, 0xaa, + 0x72, 0xba, 0x1e, 0xdb, 0x8b, 0xd0, 0xdd, 0xaf, 0xf7, 0x1d, 0x08, 0xf7, + 0x03, 0xf8, 0x3e, 0x05, 0xb1, 0xf7, 0x24, 0xbc, 0xd5, 0xc5, 0x8b, 0x08, + 0xb3, 0xa1, 0x6f, 0x58, 0x20, 0x54, 0x42, 0x3a, 0x7e, 0x87, 0x88, 0x81, + 0x1f, 0x8b, 0x81, 0x91, 0x87, 0x9f, 0x8a, 0x08, 0xc2, 0x89, 0xa5, 0x68, + 0x8b, 0x45, 0x8b, 0x47, 0x78, 0x3a, 0x6f, 0x59, 0x77, 0x68, 0x72, 0x78, + 0x71, 0x8b, 0x82, 0x8b, 0x82, 0x91, 0x8b, 0x92, 0x8b, 0x8d, 0x8d, 0x90, + 0x8d, 0x8f, 0x91, 0x95, 0x8d, 0x93, 0x8b, 0x94, 0x08, 0xa3, 0x7c, 0x9b, + 0x74, 0x71, 0x79, 0x78, 0x6f, 0x64, 0xab, 0x70, 0xbb, 0x1e, 0xb9, 0x8b, + 0xbb, 0xa0, 0xae, 0xaf, 0xbe, 0xc0, 0xac, 0xd8, 0x8b, 0xd1, 0x8b, 0xb9, + 0x73, 0xb9, 0x68, 0xa3, 0x79, 0x97, 0x7b, 0x90, 0x6c, 0x8f, 0x08, 0x8e, + 0x07, 0x0e, 0xf7, 0xa6, 0xf8, 0xc8, 0x9b, 0x15, 0x52, 0x90, 0x85, 0x93, + 0x7e, 0xd4, 0x08, 0x2d, 0xf8, 0xca, 0x71, 0x8b, 0xfb, 0xb6, 0xfc, 0x88, + 0x05, 0x3c, 0xfb, 0x19, 0x81, 0x80, 0x63, 0x83, 0x08, 0x7b, 0xf7, 0x4f, + 0x9b, 0x07, 0x58, 0x90, 0x83, 0x90, 0x8b, 0xa4, 0x8b, 0x9e, 0x8e, 0x94, + 0x9c, 0xad, 0x08, 0xc4, 0xf7, 0x05, 0xf7, 0x70, 0x8b, 0x9f, 0xfb, 0x17, + 0x05, 0x8c, 0x82, 0x8c, 0x82, 0x8b, 0x83, 0x8b, 0x65, 0x7d, 0x82, 0x4b, + 0x85, 0x08, 0x7b, 0xf7, 0x8a, 0x9b, 0x07, 0xfc, 0x19, 0xf7, 0x8a, 0x15, + 0xf7, 0x2a, 0xf7, 0x98, 0xb7, 0xfb, 0x98, 0xfb, 0x56, 0x8b, 0x05, 0xf7, + 0x0d, 0xf8, 0xc0, 0x15, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, + 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0xf7, 0x5c, 0x16, + 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, + 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0x0e, 0xf7, 0xa6, 0xf8, 0xc8, 0x9b, 0x15, + 0x52, 0x90, 0x85, 0x93, 0x7e, 0xd4, 0x08, 0x2d, 0xf8, 0xca, 0x71, 0x8b, + 0xfb, 0xb6, 0xfc, 0x88, 0x05, 0x3c, 0xfb, 0x19, 0x81, 0x80, 0x63, 0x83, + 0x08, 0x7b, 0xf7, 0x4f, 0x9b, 0x07, 0x58, 0x90, 0x83, 0x90, 0x8b, 0xa4, + 0x8b, 0x9e, 0x8e, 0x94, 0x9c, 0xad, 0x08, 0xc4, 0xf7, 0x05, 0xf7, 0x70, + 0x8b, 0x9f, 0xfb, 0x17, 0x05, 0x8c, 0x82, 0x8c, 0x82, 0x8b, 0x83, 0x8b, + 0x65, 0x7d, 0x82, 0x4b, 0x85, 0x08, 0x7b, 0xf7, 0x8a, 0x9b, 0x07, 0xfc, + 0x19, 0xf7, 0x8a, 0x15, 0xf7, 0x2a, 0xf7, 0x98, 0xb7, 0xfb, 0x98, 0xfb, + 0x56, 0x8b, 0x05, 0xf7, 0x24, 0xf8, 0x50, 0x15, 0xae, 0x8b, 0xf7, 0x3f, + 0xf5, 0x05, 0x97, 0x92, 0x90, 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, + 0x77, 0x8b, 0x81, 0x8b, 0x83, 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, + 0x34, 0x05, 0x0e, 0xf7, 0xa6, 0xf8, 0xc8, 0x9b, 0x15, 0x52, 0x90, 0x85, + 0x93, 0x7e, 0xd4, 0x08, 0x2d, 0xf8, 0xca, 0x71, 0x8b, 0xfb, 0xb6, 0xfc, + 0x88, 0x05, 0x3c, 0xfb, 0x19, 0x81, 0x80, 0x63, 0x83, 0x08, 0x7b, 0xf7, + 0x4f, 0x9b, 0x07, 0x58, 0x90, 0x83, 0x90, 0x8b, 0xa4, 0x8b, 0x9e, 0x8e, + 0x94, 0x9c, 0xad, 0x08, 0xc4, 0xf7, 0x05, 0xf7, 0x70, 0x8b, 0x9f, 0xfb, + 0x17, 0x05, 0x8c, 0x82, 0x8c, 0x82, 0x8b, 0x83, 0x8b, 0x65, 0x7d, 0x82, + 0x4b, 0x85, 0x08, 0x7b, 0xf7, 0x8a, 0x9b, 0x07, 0xfc, 0x19, 0xf7, 0x8a, + 0x15, 0xf7, 0x2a, 0xf7, 0x98, 0xb7, 0xfb, 0x98, 0xfb, 0x56, 0x8b, 0x05, + 0xf7, 0x92, 0xf8, 0x4e, 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, 0x29, 0x05, + 0x7e, 0x9b, 0x80, 0x92, 0x7c, 0x8b, 0x77, 0x8b, 0x7c, 0x7c, 0x8b, 0x78, + 0x8b, 0x7f, 0x91, 0x81, 0x98, 0x81, 0x08, 0xf7, 0x20, 0x21, 0x05, 0x0e, + 0xf7, 0xa6, 0xf8, 0xc8, 0x9b, 0x15, 0x52, 0x90, 0x85, 0x93, 0x7e, 0xd4, + 0x08, 0x2d, 0xf8, 0xca, 0x71, 0x8b, 0xfb, 0xb6, 0xfc, 0x88, 0x05, 0x3c, + 0xfb, 0x19, 0x81, 0x80, 0x63, 0x83, 0x08, 0x7b, 0xf7, 0x4f, 0x9b, 0x07, + 0x58, 0x90, 0x83, 0x90, 0x8b, 0xa4, 0x8b, 0x9e, 0x8e, 0x94, 0x9c, 0xad, + 0x08, 0xc4, 0xf7, 0x05, 0xf7, 0x70, 0x8b, 0x9f, 0xfb, 0x17, 0x05, 0x8c, + 0x82, 0x8c, 0x82, 0x8b, 0x83, 0x8b, 0x65, 0x7d, 0x82, 0x4b, 0x85, 0x08, + 0x7b, 0xf7, 0x8a, 0x9b, 0x07, 0xfc, 0x19, 0xf7, 0x8a, 0x15, 0xf7, 0x2a, + 0xf7, 0x98, 0xb7, 0xfb, 0x98, 0xfb, 0x56, 0x8b, 0x05, 0xf7, 0x9e, 0xf8, + 0xf7, 0x15, 0x5a, 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, + 0xf3, 0xdd, 0x23, 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0xf7, 0xa6, + 0xf8, 0xc8, 0x9b, 0x15, 0x52, 0x90, 0x85, 0x93, 0x7e, 0xd4, 0x08, 0x2d, + 0xf8, 0xca, 0x71, 0x8b, 0xfb, 0xb6, 0xfc, 0x88, 0x05, 0x3c, 0xfb, 0x19, + 0x81, 0x80, 0x63, 0x83, 0x08, 0x7b, 0xf7, 0x4f, 0x9b, 0x07, 0x58, 0x90, + 0x83, 0x90, 0x8b, 0xa4, 0x8b, 0x9e, 0x8e, 0x94, 0x9c, 0xad, 0x08, 0xc4, + 0xf7, 0x05, 0xf7, 0x70, 0x8b, 0x9f, 0xfb, 0x17, 0x05, 0x8c, 0x82, 0x8c, + 0x82, 0x8b, 0x83, 0x8b, 0x65, 0x7d, 0x82, 0x4b, 0x85, 0x08, 0x7b, 0xf7, + 0x8a, 0x07, 0x9b, 0x07, 0xfc, 0x19, 0xf7, 0x8a, 0x15, 0xf7, 0x2a, 0xf7, + 0x98, 0xb7, 0xfb, 0x98, 0xfb, 0x56, 0x8b, 0x05, 0xf7, 0xff, 0xf8, 0xd2, + 0x15, 0x80, 0x6a, 0x7e, 0x80, 0x70, 0x8b, 0x7c, 0x8b, 0x7a, 0x90, 0x6d, + 0x99, 0x08, 0x65, 0x9c, 0x71, 0x92, 0x75, 0x8b, 0x57, 0x8b, 0x6f, 0x6e, + 0x77, 0x3e, 0x08, 0xa8, 0x06, 0x95, 0xab, 0x9b, 0x9a, 0xa4, 0x8b, 0x9c, + 0x8b, 0xa3, 0x84, 0xc1, 0x75, 0x08, 0xa5, 0x81, 0x9e, 0x86, 0x97, 0x8b, + 0xbb, 0x8b, 0xac, 0xb0, 0x99, 0xce, 0x08, 0x6f, 0x06, 0x0e, 0xf7, 0xa6, + 0xf8, 0xc8, 0x9b, 0x15, 0x52, 0x90, 0x85, 0x93, 0x7e, 0xd4, 0x08, 0x2d, + 0xf8, 0xca, 0x71, 0x8b, 0xfb, 0xb6, 0xfc, 0x88, 0x05, 0x3c, 0xfb, 0x19, + 0x81, 0x80, 0x63, 0x83, 0x08, 0x7b, 0xf7, 0x4f, 0x9b, 0x07, 0x58, 0x90, + 0x83, 0x90, 0x8b, 0xa4, 0x8b, 0x9e, 0x8e, 0x94, 0x9c, 0xad, 0x08, 0xc4, + 0xf7, 0x05, 0xf7, 0x70, 0x8b, 0x9f, 0xfb, 0x17, 0x05, 0x8c, 0x82, 0x8c, + 0x82, 0x8b, 0x83, 0x8b, 0x65, 0x7d, 0x82, 0x4b, 0x85, 0x08, 0x7b, 0xf7, + 0x8a, 0x9b, 0x07, 0xfc, 0x19, 0xf7, 0x8a, 0x15, 0xf7, 0x2a, 0xf7, 0x98, + 0xb7, 0xfb, 0x98, 0xfb, 0x56, 0x8b, 0x05, 0xf7, 0x69, 0xf9, 0x16, 0x15, + 0x55, 0x5e, 0x5e, 0x55, 0x53, 0xb7, 0x5f, 0xc3, 0xc2, 0xb8, 0xb8, 0xc1, + 0xc2, 0x5d, 0xb8, 0x54, 0x1f, 0x69, 0x04, 0xb0, 0xa9, 0x6d, 0x67, 0x66, + 0x6e, 0x6f, 0x65, 0x67, 0x6e, 0xa8, 0xb0, 0xae, 0xa9, 0xa9, 0xae, 0x1f, + 0x0e, 0xf7, 0xde, 0xf7, 0xa9, 0x7d, 0x15, 0x9d, 0x88, 0x9b, 0x8a, 0x9b, + 0x8b, 0xf2, 0x8b, 0xdb, 0xb7, 0xe5, 0xf4, 0x08, 0x7a, 0x99, 0x05, 0x31, + 0x33, 0x51, 0x6d, 0x39, 0x8b, 0xfb, 0x03, 0x8b, 0x4b, 0xd7, 0x8b, 0xf7, + 0x15, 0x8b, 0xf7, 0x0b, 0xbb, 0xf7, 0x0d, 0xd9, 0xdc, 0xbb, 0xbc, 0xca, + 0xa7, 0xcd, 0x8b, 0xe7, 0x8b, 0xbe, 0x55, 0x95, 0xfb, 0x00, 0x08, 0x9d, + 0x88, 0xb0, 0xf7, 0x5b, 0x76, 0x8b, 0x05, 0x83, 0x7b, 0x81, 0x85, 0x77, + 0x8b, 0x83, 0x8b, 0x7f, 0x8d, 0x76, 0x90, 0x5e, 0x96, 0x63, 0x91, 0x6b, + 0x8b, 0xfb, 0x69, 0x8b, 0xfb, 0x55, 0xfb, 0x5d, 0x8b, 0xfb, 0x72, 0x8b, + 0xfb, 0x0d, 0xd0, 0x2b, 0xf7, 0x01, 0x6b, 0x08, 0x53, 0x31, 0x94, 0x83, + 0x05, 0x99, 0x90, 0x93, 0x8d, 0x95, 0x8b, 0x08, 0xa6, 0x9e, 0x79, 0x71, + 0x71, 0x78, 0x7c, 0x69, 0x1f, 0x76, 0x8b, 0x79, 0x8f, 0x6e, 0x96, 0x08, + 0x7a, 0x6e, 0x05, 0xb5, 0x7b, 0xa2, 0x86, 0xa7, 0x8b, 0x08, 0xd0, 0xbd, + 0xaf, 0xbd, 0xb4, 0x6b, 0xa6, 0x59, 0x1f, 0x83, 0x8b, 0x84, 0x8a, 0x81, + 0x89, 0x08, 0xae, 0xbf, 0x05, 0x0e, 0xf8, 0x15, 0xbb, 0xf7, 0xda, 0x15, + 0xe5, 0x8b, 0x4a, 0xfb, 0x80, 0x05, 0x7a, 0x51, 0x83, 0x85, 0x53, 0x81, + 0x08, 0x7b, 0xf7, 0x91, 0x07, 0xf7, 0x09, 0x8b, 0xf6, 0xaa, 0xd8, 0xc3, + 0xec, 0xd2, 0xc4, 0xf7, 0x02, 0x8b, 0xf7, 0x08, 0x08, 0xf7, 0x38, 0xfb, + 0x06, 0xf4, 0xfb, 0x46, 0x1e, 0xfb, 0xaa, 0x7b, 0x06, 0xca, 0x85, 0x99, + 0x83, 0x8b, 0x70, 0x8b, 0x7b, 0x87, 0x73, 0x84, 0x73, 0x08, 0x5d, 0xfb, + 0x38, 0x31, 0x8b, 0x7f, 0x61, 0x05, 0xf7, 0xf7, 0xb5, 0x15, 0xfb, 0x2d, + 0x8b, 0xca, 0xf7, 0x76, 0x05, 0x91, 0xa1, 0x9b, 0x92, 0xb5, 0x8b, 0xc2, + 0x8b, 0xbc, 0x7e, 0xab, 0x73, 0xbc, 0x67, 0xa6, 0x4c, 0x8b, 0x3c, 0x8b, + 0xfb, 0x00, 0x61, 0xfb, 0x04, 0x47, 0x47, 0x50, 0x4f, 0x3a, 0x6d, 0x23, + 0x8b, 0x5d, 0x8b, 0x78, 0x96, 0x8b, 0xa5, 0x08, 0x8b, 0x97, 0x91, 0xa6, + 0x9b, 0xc3, 0x08, 0xb9, 0xf7, 0x38, 0xf7, 0x2d, 0x8b, 0x97, 0xb5, 0x05, + 0x0e, 0xf7, 0xa6, 0xf9, 0x0e, 0xf9, 0x21, 0x15, 0xfc, 0x85, 0x7b, 0x06, + 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x70, 0x8b, 0x80, 0x85, 0x68, 0x86, 0x79, + 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x7a, 0x52, 0x83, 0x84, 0x53, 0x81, + 0x08, 0x7b, 0xf8, 0x8f, 0x07, 0xc9, 0xf7, 0x36, 0x7b, 0x93, 0x05, 0x5c, + 0x4b, 0x71, 0x71, 0x60, 0x77, 0x66, 0x7a, 0x47, 0x81, 0x40, 0x8b, 0x53, + 0x8b, 0x73, 0x95, 0x8b, 0xa3, 0x8b, 0x96, 0x96, 0xba, 0xa4, 0xe3, 0x98, + 0xb7, 0x94, 0xac, 0x95, 0xb1, 0xae, 0x89, 0xaa, 0x8a, 0x97, 0x8b, 0x08, + 0xb2, 0x8c, 0xa7, 0x85, 0x96, 0x81, 0x90, 0x86, 0x8d, 0x82, 0x8b, 0x7a, + 0x8b, 0x7a, 0x89, 0x7e, 0x86, 0x75, 0x08, 0x9f, 0x86, 0xcf, 0xf7, 0x7c, + 0x79, 0x8f, 0x05, 0x65, 0x36, 0x82, 0x85, 0x30, 0x87, 0x7f, 0x8b, 0x6b, + 0x8a, 0x68, 0x8a, 0x08, 0xcd, 0xf7, 0x7d, 0x05, 0x91, 0xa1, 0x96, 0x8f, + 0xc3, 0x8b, 0xf7, 0x31, 0x8b, 0xae, 0x7e, 0x8b, 0x4f, 0x8b, 0x7e, 0x8a, + 0x7c, 0x8a, 0x7a, 0x08, 0xa0, 0x89, 0xaa, 0xf7, 0x2d, 0x05, 0xfb, 0xd1, + 0xf7, 0x39, 0x15, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, + 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0xf7, 0x5c, 0x16, 0x6f, + 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, + 0x74, 0xa3, 0x72, 0x1f, 0x0e, 0xf7, 0xa6, 0xf9, 0x0e, 0xf9, 0x21, 0x15, + 0xfc, 0x85, 0x7b, 0x06, 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x70, 0x8b, 0x80, + 0x85, 0x68, 0x86, 0x79, 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x7a, 0x52, + 0x83, 0x84, 0x53, 0x81, 0x08, 0x7b, 0xf8, 0x8f, 0x07, 0xc9, 0xf7, 0x36, + 0x7b, 0x93, 0x05, 0x5c, 0x4b, 0x71, 0x71, 0x60, 0x77, 0x66, 0x7a, 0x47, + 0x81, 0x40, 0x8b, 0x53, 0x8b, 0x73, 0x95, 0x8b, 0xa3, 0x8b, 0x96, 0x96, + 0xba, 0xa4, 0xe3, 0x98, 0xb7, 0x94, 0xac, 0x95, 0xb1, 0xae, 0x89, 0xaa, + 0x8a, 0x97, 0x8b, 0x08, 0xb2, 0x8c, 0xa7, 0x85, 0x96, 0x81, 0x90, 0x86, + 0x8d, 0x82, 0x8b, 0x7a, 0x8b, 0x7a, 0x89, 0x7e, 0x86, 0x75, 0x08, 0x9f, + 0x86, 0xcf, 0xf7, 0x7c, 0x79, 0x8f, 0x05, 0x65, 0x36, 0x82, 0x85, 0x30, + 0x87, 0x7f, 0x8b, 0x6b, 0x8a, 0x68, 0x8a, 0x08, 0xcd, 0xf7, 0x7d, 0x05, + 0x91, 0xa1, 0x96, 0x8f, 0xc3, 0x8b, 0xf7, 0x31, 0x8b, 0xae, 0x7e, 0x8b, + 0x4f, 0x8b, 0x7e, 0x8a, 0x7c, 0x8a, 0x7a, 0x08, 0xa0, 0x89, 0xaa, 0xf7, + 0x2d, 0x05, 0xfb, 0xba, 0xc0, 0x15, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, + 0x97, 0x92, 0x90, 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, + 0x81, 0x8b, 0x83, 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, + 0x0e, 0xf7, 0xa6, 0xf9, 0x0e, 0xf9, 0x21, 0x15, 0xfc, 0x85, 0x7b, 0x06, + 0xc9, 0x85, 0x9a, 0x83, 0x8b, 0x70, 0x8b, 0x80, 0x85, 0x68, 0x86, 0x79, + 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x7a, 0x52, 0x83, 0x84, 0x53, 0x81, + 0x08, 0x7b, 0xf8, 0x8f, 0x07, 0xc9, 0xf7, 0x36, 0x7b, 0x93, 0x05, 0x5c, + 0x4b, 0x71, 0x71, 0x60, 0x77, 0x66, 0x7a, 0x47, 0x81, 0x40, 0x8b, 0x53, + 0x8b, 0x73, 0x95, 0x8b, 0xa3, 0x8b, 0x96, 0x96, 0xba, 0xa4, 0xe3, 0x98, + 0xb7, 0x94, 0xac, 0x95, 0xb1, 0xae, 0x89, 0xaa, 0x8a, 0x97, 0x8b, 0x08, + 0xb2, 0x8c, 0xa7, 0x85, 0x96, 0x81, 0x90, 0x86, 0x8d, 0x82, 0x8b, 0x7a, + 0x8b, 0x7a, 0x89, 0x7e, 0x86, 0x75, 0x08, 0x9f, 0x86, 0xcf, 0xf7, 0x7c, + 0x79, 0x8f, 0x05, 0x65, 0x36, 0x82, 0x85, 0x30, 0x87, 0x7f, 0x8b, 0x6b, + 0x8a, 0x68, 0x8a, 0x08, 0xcd, 0xf7, 0x7d, 0x05, 0x91, 0xa1, 0x96, 0x8f, + 0xc3, 0x8b, 0xf7, 0x31, 0x8b, 0xae, 0x7e, 0x8b, 0x4f, 0x8b, 0x7e, 0x8a, + 0x7c, 0x8a, 0x7a, 0x08, 0xa0, 0x89, 0xaa, 0xf7, 0x2d, 0x05, 0xfb, 0x61, + 0xbe, 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, 0x29, 0x05, 0x7e, 0x9b, 0x80, + 0x92, 0x7c, 0x8b, 0x77, 0x8b, 0x7c, 0x7c, 0x8b, 0x78, 0x8b, 0x7f, 0x91, + 0x81, 0x98, 0x81, 0x08, 0xf7, 0x20, 0x21, 0x05, 0x0e, 0xf7, 0xa6, 0xf9, + 0x0e, 0xf9, 0x21, 0x15, 0xfc, 0x85, 0x7b, 0x06, 0xc9, 0x85, 0x9a, 0x83, + 0x8b, 0x70, 0x8b, 0x80, 0x85, 0x68, 0x86, 0x79, 0x08, 0xfb, 0x0f, 0xfc, + 0x4e, 0x05, 0x7a, 0x52, 0x83, 0x84, 0x53, 0x81, 0x08, 0x7b, 0xf8, 0x8f, + 0x07, 0xc9, 0xf7, 0x36, 0x7b, 0x93, 0x05, 0x5c, 0x4b, 0x71, 0x71, 0x60, + 0x77, 0x66, 0x7a, 0x47, 0x81, 0x40, 0x8b, 0x53, 0x8b, 0x73, 0x95, 0x8b, + 0xa3, 0x8b, 0x96, 0x96, 0xba, 0xa4, 0xe3, 0x98, 0xb7, 0x94, 0xac, 0x95, + 0xb1, 0xae, 0x89, 0xaa, 0x8a, 0x97, 0x8b, 0x08, 0xb2, 0x8c, 0xa7, 0x85, + 0x96, 0x81, 0x90, 0x86, 0x8d, 0x82, 0x8b, 0x7a, 0x8b, 0x7a, 0x89, 0x7e, + 0x86, 0x75, 0x08, 0x9f, 0x86, 0xcf, 0xf7, 0x7c, 0x79, 0x8f, 0x05, 0x65, + 0x36, 0x82, 0x85, 0x30, 0x87, 0x7f, 0x8b, 0x6b, 0x8a, 0x68, 0x8a, 0x08, + 0xcd, 0xf7, 0x7d, 0x05, 0x91, 0xa1, 0x96, 0x8f, 0xc3, 0x8b, 0xf7, 0x31, + 0x8b, 0xae, 0x7e, 0x8b, 0x4f, 0x8b, 0x7e, 0x8a, 0x7c, 0x8a, 0x7a, 0x08, + 0xa0, 0x89, 0xaa, 0xf7, 0x2d, 0x05, 0xfb, 0x37, 0xf7, 0x70, 0x15, 0x5a, + 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, 0x23, + 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0x87, 0x83, 0x16, 0xf7, 0x88, + 0x9b, 0x06, 0x52, 0x92, 0x80, 0x91, 0x8b, 0xa7, 0x8b, 0x9e, 0x8d, 0x97, + 0x94, 0xab, 0x08, 0xf7, 0x0f, 0xf8, 0x4f, 0x05, 0x9d, 0xc5, 0x92, 0x91, + 0xc4, 0x95, 0x08, 0x9b, 0xfb, 0x8b, 0x7b, 0x07, 0xc5, 0x84, 0x97, 0x83, + 0x8b, 0x6f, 0x8b, 0x7d, 0x87, 0x74, 0x84, 0x72, 0x08, 0xfb, 0x0f, 0xfc, + 0x4e, 0x05, 0x79, 0x51, 0x84, 0x85, 0x53, 0x81, 0x08, 0x7b, 0x07, 0xf7, + 0x57, 0xf9, 0xc6, 0x15, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, + 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0xf7, 0x5c, 0x16, + 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, + 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0x0e, 0x87, 0x83, 0x16, 0xf7, 0x88, 0x9b, + 0x06, 0x52, 0x92, 0x80, 0x91, 0x8b, 0xa7, 0x8b, 0x9e, 0x8d, 0x97, 0x94, + 0xab, 0x08, 0xf7, 0x0f, 0xf8, 0x4f, 0x05, 0x9d, 0xc5, 0x92, 0x91, 0xc4, + 0x95, 0x08, 0x9b, 0xfb, 0x8b, 0x7b, 0x07, 0xc5, 0x84, 0x97, 0x83, 0x8b, + 0x6f, 0x8b, 0x7d, 0x87, 0x74, 0x84, 0x72, 0x08, 0xfb, 0x0f, 0xfc, 0x4e, + 0x05, 0x79, 0x51, 0x84, 0x85, 0x53, 0x81, 0x08, 0x7b, 0x07, 0xf7, 0x50, + 0xf9, 0x56, 0x15, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, 0x97, 0x92, 0x90, + 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, 0x81, 0x8b, 0x83, + 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, 0x0e, 0x87, 0x83, + 0x16, 0xf7, 0x88, 0x9b, 0x06, 0x52, 0x92, 0x80, 0x91, 0x8b, 0xa7, 0x8b, + 0x9e, 0x8d, 0x97, 0x94, 0xab, 0x08, 0xf7, 0x0f, 0xf8, 0x4f, 0x05, 0x9d, + 0xc5, 0x92, 0x91, 0xc4, 0x95, 0x08, 0x9b, 0xfb, 0x8b, 0x7b, 0x07, 0xc5, + 0x84, 0x97, 0x83, 0x8b, 0x6f, 0x8b, 0x7d, 0x87, 0x74, 0x84, 0x72, 0x08, + 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x79, 0x51, 0x84, 0x85, 0x53, 0x81, 0x08, + 0x7b, 0x07, 0xf7, 0xde, 0xf9, 0x54, 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, + 0x29, 0x05, 0x7e, 0x9b, 0x7f, 0x92, 0x7d, 0x8b, 0x77, 0x8b, 0x7b, 0x7c, + 0x8b, 0x78, 0x8b, 0x7f, 0x91, 0x82, 0x99, 0x80, 0x08, 0xf7, 0x20, 0x21, + 0x05, 0x0e, 0x87, 0x83, 0x16, 0xf7, 0x88, 0x9b, 0x06, 0x52, 0x92, 0x80, + 0x91, 0x8b, 0xa7, 0x8b, 0x9e, 0x8d, 0x97, 0x94, 0xab, 0x08, 0xf7, 0x0f, + 0xf8, 0x4f, 0x05, 0x9d, 0xc5, 0x92, 0x91, 0xc4, 0x95, 0x08, 0x9b, 0xfb, + 0x8b, 0x7b, 0x07, 0xc5, 0x84, 0x97, 0x83, 0x8b, 0x6f, 0x8b, 0x7d, 0x87, + 0x74, 0x84, 0x72, 0x08, 0xfb, 0x0f, 0xfc, 0x4e, 0x05, 0x79, 0x51, 0x84, + 0x85, 0x53, 0x81, 0x08, 0x7b, 0x07, 0xf7, 0xed, 0xf9, 0xfd, 0x15, 0x5a, + 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, 0x23, + 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0xf7, 0xde, 0xf9, 0x6b, 0xf9, + 0x21, 0x15, 0xfb, 0x5b, 0x7b, 0x06, 0xc4, 0x86, 0x98, 0x81, 0x8b, 0x67, + 0x8b, 0x7f, 0x89, 0x7f, 0x84, 0x77, 0x8a, 0x88, 0x8a, 0x87, 0x8b, 0x8a, + 0x08, 0x25, 0xfc, 0x10, 0xfb, 0x64, 0xf8, 0x87, 0xfb, 0x35, 0x8b, 0x8b, + 0x7b, 0x05, 0xba, 0x87, 0xa0, 0x7e, 0x9d, 0x64, 0x08, 0xfb, 0x0b, 0xfc, + 0x35, 0x05, 0x65, 0xfb, 0x14, 0x83, 0x7f, 0x52, 0x83, 0x08, 0x7b, 0xf7, + 0x5a, 0x9b, 0x07, 0x58, 0x8f, 0x78, 0x96, 0x8b, 0xa7, 0x8b, 0x98, 0x8e, + 0x9f, 0x91, 0xa0, 0x08, 0xf7, 0x06, 0xf8, 0x3a, 0x05, 0xf7, 0x7a, 0xfc, + 0xba, 0x9d, 0x8b, 0xf7, 0x24, 0xf8, 0x8b, 0x05, 0xb0, 0xf7, 0x15, 0x8f, + 0x91, 0xca, 0x99, 0x08, 0x9b, 0x07, 0xfb, 0x20, 0xf7, 0x4b, 0x15, 0x80, + 0x6a, 0x7e, 0x80, 0x70, 0x8b, 0x7c, 0x8b, 0x7a, 0x90, 0x6d, 0x99, 0x08, + 0x65, 0x9c, 0x71, 0x92, 0x75, 0x8b, 0x57, 0x8b, 0x6f, 0x6e, 0x77, 0x3e, + 0x08, 0xa8, 0x06, 0x95, 0xab, 0x9b, 0x9a, 0xa4, 0x8b, 0x9c, 0x8b, 0xa3, + 0x84, 0xc1, 0x75, 0x08, 0xa5, 0x81, 0x9e, 0x86, 0x97, 0x8b, 0xbb, 0x8b, + 0xac, 0xb0, 0x99, 0xce, 0x08, 0x6f, 0x06, 0x0e, 0xf8, 0x15, 0xf8, 0x6e, + 0xf9, 0x2e, 0x15, 0x37, 0x8b, 0x31, 0x63, 0x3b, 0x42, 0x26, 0x2e, 0x50, + 0xfb, 0x0e, 0x8b, 0xfb, 0x09, 0x8b, 0xfb, 0x20, 0xe6, 0x28, 0xf7, 0x13, + 0x8b, 0xf7, 0x64, 0x8b, 0xf7, 0x5e, 0xf7, 0x66, 0x96, 0xf7, 0x76, 0x08, + 0x92, 0xf7, 0x21, 0x29, 0xf6, 0xfb, 0x1a, 0x8b, 0x08, 0x82, 0x6a, 0x15, + 0xda, 0xbd, 0x51, 0x2d, 0x1f, 0x8b, 0xfb, 0x00, 0x5c, 0xfb, 0x26, 0x4a, + 0x2d, 0x54, 0x3c, 0x4d, 0x64, 0x45, 0x8b, 0x37, 0x8b, 0x5d, 0xc8, 0x8b, + 0xf7, 0x00, 0x8b, 0xe9, 0xbd, 0xf7, 0x29, 0xc7, 0xe2, 0xc3, 0xdc, 0xc8, + 0xb1, 0xd4, 0x8b, 0x08, 0x30, 0xf7, 0x4d, 0x15, 0x6f, 0x75, 0x75, 0x71, + 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, + 0x1f, 0xf7, 0x5c, 0x16, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, + 0xa6, 0xa1, 0xa1, 0xa6, 0x1f, 0xa4, 0x74, 0xa3, 0x72, 0x1e, 0x0e, 0xf8, + 0x15, 0xf8, 0x6e, 0xf9, 0x2e, 0x15, 0x37, 0x8b, 0x31, 0x63, 0x3b, 0x42, + 0x26, 0x2e, 0x50, 0xfb, 0x0e, 0x8b, 0xfb, 0x09, 0x8b, 0xfb, 0x20, 0xe6, + 0x28, 0xf7, 0x13, 0x8b, 0xf7, 0x64, 0x8b, 0xf7, 0x5e, 0xf7, 0x66, 0x96, + 0xf7, 0x76, 0x92, 0xf7, 0x21, 0x29, 0xf6, 0xfb, 0x1a, 0x8b, 0x08, 0x82, + 0x6a, 0x15, 0xda, 0xbd, 0x51, 0x2d, 0x1f, 0x8b, 0xfb, 0x00, 0x5c, 0xfb, + 0x26, 0x4a, 0x2d, 0x54, 0x3c, 0x4d, 0x64, 0x45, 0x8b, 0x37, 0x8b, 0x5d, + 0xc8, 0x8b, 0xf7, 0x00, 0x8b, 0xe9, 0xbd, 0xf7, 0x29, 0xc7, 0xe2, 0xc3, + 0xdc, 0xc8, 0xb1, 0xd4, 0x8b, 0x08, 0x3f, 0xd4, 0x15, 0xae, 0x8b, 0xf7, + 0x3f, 0xf5, 0x05, 0x97, 0x93, 0x90, 0x93, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, + 0x9b, 0x76, 0x8b, 0x82, 0x8b, 0x82, 0x87, 0x85, 0x85, 0x08, 0xfb, 0x36, + 0xfb, 0x34, 0x05, 0x0e, 0xf8, 0x15, 0xf8, 0x6e, 0xf9, 0x2e, 0x15, 0x37, + 0x8b, 0x31, 0x63, 0x3b, 0x42, 0x26, 0x2e, 0x50, 0xfb, 0x0e, 0x8b, 0xfb, + 0x09, 0x8b, 0xfb, 0x20, 0xe6, 0x28, 0xf7, 0x13, 0x8b, 0xf7, 0x64, 0x8b, + 0xf7, 0x5e, 0xf7, 0x66, 0x96, 0xf7, 0x76, 0x92, 0xf7, 0x21, 0x29, 0xf6, + 0xfb, 0x1a, 0x8b, 0x08, 0x82, 0x6a, 0x15, 0xda, 0xbd, 0x51, 0x2d, 0x1f, + 0x8b, 0xfb, 0x00, 0x5c, 0xfb, 0x26, 0x4a, 0x2d, 0x54, 0x3c, 0x4d, 0x64, + 0x45, 0x8b, 0x37, 0x8b, 0x5d, 0xc8, 0x8b, 0xf7, 0x00, 0x8b, 0xe9, 0xbd, + 0xf7, 0x29, 0xc7, 0xe2, 0xc3, 0xdc, 0xc8, 0xb1, 0xd4, 0x8b, 0x08, 0xb2, + 0xd2, 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, 0x29, 0x05, 0x7e, 0x9b, 0x80, + 0x92, 0x7c, 0x8b, 0x77, 0x8b, 0x7c, 0x7c, 0x8b, 0x78, 0x8b, 0x7f, 0x91, + 0x81, 0x98, 0x81, 0x08, 0xf7, 0x20, 0x21, 0x05, 0x0e, 0xf8, 0x15, 0xf8, + 0x6e, 0xf9, 0x2e, 0x15, 0x37, 0x8b, 0x31, 0x63, 0x3b, 0x42, 0x26, 0x2e, + 0x50, 0xfb, 0x0e, 0x8b, 0xfb, 0x09, 0x8b, 0xfb, 0x20, 0xe6, 0x28, 0xf7, + 0x13, 0x8b, 0xf7, 0x64, 0x8b, 0xf7, 0x5e, 0xf7, 0x66, 0x96, 0xf7, 0x76, + 0x92, 0xf7, 0x21, 0x29, 0xf6, 0xfb, 0x1a, 0x8b, 0x08, 0x82, 0x6a, 0x15, + 0xda, 0xbd, 0x51, 0x2d, 0x1f, 0x8b, 0xfb, 0x00, 0x5c, 0xfb, 0x26, 0x4a, + 0x2d, 0x54, 0x3c, 0x4d, 0x64, 0x45, 0x8b, 0x37, 0x8b, 0x5d, 0xc8, 0x8b, + 0xf7, 0x00, 0x8b, 0xe9, 0xbd, 0xf7, 0x29, 0xc7, 0xe2, 0xc3, 0xdc, 0xc8, + 0xb1, 0xd4, 0x8b, 0x08, 0xc0, 0xf7, 0x84, 0x15, 0x5a, 0x8b, 0xfb, 0x31, + 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, 0x23, 0xaf, 0x8b, 0x33, + 0xf7, 0x3d, 0x05, 0x0e, 0xf8, 0x15, 0xf8, 0x6e, 0xf9, 0x2e, 0x15, 0x37, + 0x8b, 0x31, 0x63, 0x3b, 0x42, 0x26, 0x2e, 0x50, 0xfb, 0x0e, 0x8b, 0xfb, + 0x09, 0x8b, 0xfb, 0x20, 0xe6, 0x28, 0xf7, 0x13, 0x8b, 0xf7, 0x64, 0x8b, + 0xf7, 0x5e, 0xf7, 0x66, 0x96, 0xf7, 0x76, 0x08, 0x92, 0xf7, 0x21, 0x29, + 0xf6, 0xfb, 0x1a, 0x8b, 0x08, 0x82, 0x6a, 0x15, 0xda, 0xbd, 0x51, 0x2d, + 0x1f, 0x8b, 0xfb, 0x00, 0x5c, 0xfb, 0x26, 0x4a, 0x2d, 0x54, 0x3c, 0x4d, + 0x64, 0x45, 0x8b, 0x37, 0x8b, 0x5d, 0xc8, 0x8b, 0xf7, 0x00, 0x8b, 0xe9, + 0xbd, 0xf7, 0x29, 0xc7, 0xe2, 0xc3, 0xdc, 0xc8, 0xb1, 0xd4, 0x8b, 0x08, + 0xf7, 0x1f, 0xf7, 0x5f, 0x15, 0x80, 0x6a, 0x7e, 0x80, 0x70, 0x8b, 0x7c, + 0x8b, 0x7a, 0x90, 0x6d, 0x99, 0x08, 0x65, 0x9c, 0x71, 0x92, 0x75, 0x8b, + 0x57, 0x8b, 0x6f, 0x6e, 0x77, 0x3e, 0x08, 0xa8, 0x06, 0x95, 0xab, 0x9b, + 0x9a, 0xa4, 0x8b, 0x9c, 0x8b, 0xa3, 0x84, 0xc1, 0x75, 0x08, 0xa5, 0x81, + 0x9e, 0x86, 0x98, 0x8b, 0xba, 0x8b, 0xac, 0xb0, 0x99, 0xce, 0x08, 0x6f, + 0x06, 0x0e, 0xf8, 0x68, 0xf8, 0x68, 0x15, 0xb3, 0xf7, 0x5b, 0x74, 0x8b, + 0x05, 0x7d, 0x76, 0x82, 0x86, 0x75, 0x8b, 0x7f, 0x8b, 0x80, 0x8e, 0x74, + 0x93, 0x75, 0x94, 0x6b, 0x90, 0x6c, 0x8b, 0x23, 0x8b, 0x41, 0x46, 0x8b, + 0x29, 0x8b, 0x55, 0x9a, 0x6e, 0xc7, 0x4b, 0x94, 0x82, 0x98, 0x7d, 0x9c, + 0x78, 0x08, 0x9d, 0x78, 0x99, 0x7c, 0x92, 0x83, 0xba, 0x5a, 0x98, 0x71, + 0x8b, 0x60, 0x08, 0x40, 0x53, 0x51, 0x42, 0x38, 0x4c, 0xd2, 0xea, 0x1e, + 0x8b, 0x93, 0x8c, 0x93, 0x8c, 0x92, 0x08, 0x77, 0x8d, 0x69, 0xfb, 0x73, + 0x9d, 0x8b, 0x05, 0x92, 0xa2, 0x96, 0x95, 0x9f, 0x8b, 0x96, 0x8b, 0x9a, + 0x87, 0xa5, 0x82, 0xb9, 0x7a, 0xa6, 0x85, 0xaa, 0x8b, 0xf7, 0x07, 0x8b, + 0xe2, 0xe2, 0x8b, 0xf7, 0x05, 0x8b, 0xcc, 0x74, 0xb2, 0x31, 0xe6, 0x31, + 0xe6, 0x82, 0x99, 0x8b, 0xbc, 0x08, 0xca, 0xb5, 0xb2, 0xcf, 0x1e, 0xb0, + 0x8b, 0xaa, 0x7e, 0xa0, 0x73, 0xa1, 0x72, 0x93, 0x69, 0x8d, 0x49, 0x08, + 0x9d, 0x88, 0x05, 0xbf, 0xf8, 0x29, 0x15, 0x67, 0x8b, 0xfb, 0x22, 0x22, + 0x31, 0xf4, 0x66, 0x8b, 0xeb, 0xfb, 0x3d, 0xb9, 0x8b, 0xf7, 0x37, 0xf7, + 0x3d, 0x05, 0x0e, 0xf8, 0x15, 0xf9, 0x91, 0xf9, 0x21, 0x15, 0xfb, 0x5b, + 0x7b, 0x06, 0xab, 0x88, 0x95, 0x89, 0x97, 0x83, 0x95, 0x85, 0x92, 0x7d, + 0x8b, 0x7e, 0x8b, 0x7b, 0x71, 0x25, 0x5b, 0xfb, 0x3d, 0x87, 0x7e, 0x87, + 0x7a, 0x86, 0x78, 0x79, 0x4a, 0x7c, 0x63, 0x75, 0x69, 0x64, 0x4d, 0x55, + 0x6c, 0x45, 0x8b, 0x08, 0x38, 0x52, 0xbb, 0xd1, 0x1f, 0x8b, 0xad, 0xaa, + 0xf7, 0x0d, 0xce, 0xf7, 0x7b, 0x8d, 0x92, 0x8d, 0x92, 0x8c, 0x90, 0xa0, + 0xd1, 0x9b, 0x99, 0xcf, 0x92, 0x08, 0x9b, 0xfb, 0xa5, 0x7b, 0x07, 0xce, + 0x85, 0x96, 0x85, 0x8b, 0x6e, 0x8b, 0x7f, 0x88, 0x7b, 0x87, 0x7a, 0x08, + 0x56, 0xfb, 0x54, 0x05, 0x6d, 0xfb, 0x00, 0x7e, 0x4b, 0x8b, 0x63, 0x8b, + 0x2b, 0xe7, 0x46, 0xf7, 0x12, 0x8b, 0xf7, 0x17, 0x8b, 0xde, 0xd2, 0xb7, + 0xf7, 0x2a, 0x08, 0xde, 0xf7, 0xb1, 0x05, 0xb1, 0xf7, 0x16, 0x8f, 0x90, + 0xc9, 0x99, 0x08, 0x9b, 0x07, 0xfc, 0x07, 0xf7, 0x39, 0x15, 0x6f, 0x75, + 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, + 0xa3, 0x72, 0x1f, 0xf7, 0x5c, 0x16, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, + 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0x0e, + 0xf8, 0x15, 0xf9, 0x91, 0xf9, 0x21, 0x15, 0xfb, 0x5b, 0x7b, 0x06, 0xab, + 0x88, 0x95, 0x89, 0x97, 0x83, 0x95, 0x85, 0x92, 0x7d, 0x8b, 0x7e, 0x8b, + 0x7b, 0x71, 0x25, 0x5b, 0xfb, 0x3d, 0x87, 0x7e, 0x87, 0x7a, 0x86, 0x78, + 0x79, 0x4a, 0x7c, 0x63, 0x75, 0x69, 0x64, 0x4d, 0x55, 0x6c, 0x45, 0x8b, + 0x08, 0x38, 0x52, 0xbb, 0xd1, 0x1f, 0x8b, 0xad, 0xaa, 0xf7, 0x0d, 0xce, + 0xf7, 0x7b, 0x8d, 0x92, 0x8d, 0x92, 0x8c, 0x90, 0xa0, 0xd1, 0x9b, 0x99, + 0xcf, 0x92, 0x08, 0x9b, 0xfb, 0xa5, 0x7b, 0x07, 0xce, 0x85, 0x96, 0x85, + 0x8b, 0x6e, 0x8b, 0x7f, 0x88, 0x7b, 0x87, 0x7a, 0x08, 0x56, 0xfb, 0x54, + 0x05, 0x6d, 0xfb, 0x00, 0x7e, 0x4b, 0x8b, 0x63, 0x8b, 0x2b, 0xe7, 0x46, + 0xf7, 0x12, 0x8b, 0xf7, 0x17, 0x8b, 0xde, 0xd2, 0xb7, 0xf7, 0x2a, 0x08, + 0xde, 0xf7, 0xb1, 0x05, 0xb1, 0xf7, 0x16, 0x8f, 0x90, 0xc9, 0x99, 0x08, + 0x9b, 0x07, 0xfb, 0xf9, 0xc0, 0x15, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, + 0x97, 0x93, 0x90, 0x93, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x76, 0x8b, + 0x82, 0x8b, 0x82, 0x88, 0x85, 0x84, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, + 0x0e, 0xf8, 0x15, 0xf9, 0x91, 0xf9, 0x21, 0x15, 0xfb, 0x5b, 0x7b, 0x06, + 0xab, 0x88, 0x95, 0x89, 0x97, 0x83, 0x95, 0x85, 0x92, 0x7d, 0x8b, 0x7e, + 0x8b, 0x7b, 0x71, 0x25, 0x5b, 0xfb, 0x3d, 0x87, 0x7e, 0x87, 0x7a, 0x86, + 0x78, 0x79, 0x4a, 0x7c, 0x63, 0x75, 0x69, 0x64, 0x4d, 0x55, 0x6c, 0x45, + 0x8b, 0x08, 0x38, 0x52, 0xbb, 0xd1, 0x1f, 0x8b, 0xad, 0xaa, 0xf7, 0x0d, + 0xce, 0xf7, 0x7b, 0x8d, 0x92, 0x8d, 0x92, 0x8c, 0x90, 0xa0, 0xd1, 0x9b, + 0x99, 0xcf, 0x92, 0x08, 0x9b, 0xfb, 0xa5, 0x7b, 0x07, 0xce, 0x85, 0x96, + 0x85, 0x8b, 0x6e, 0x8b, 0x7f, 0x88, 0x7b, 0x87, 0x7a, 0x08, 0x56, 0xfb, + 0x54, 0x05, 0x6d, 0xfb, 0x00, 0x7e, 0x4b, 0x8b, 0x63, 0x8b, 0x2b, 0xe7, + 0x46, 0xf7, 0x12, 0x8b, 0xf7, 0x17, 0x8b, 0xde, 0xd2, 0xb7, 0xf7, 0x2a, + 0x08, 0xde, 0xf7, 0xb1, 0x05, 0xb1, 0xf7, 0x16, 0x8f, 0x90, 0xc9, 0x99, + 0x08, 0x9b, 0x07, 0xfb, 0x92, 0xbe, 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, + 0x29, 0x05, 0x7e, 0x9b, 0x80, 0x92, 0x7c, 0x8b, 0x77, 0x8b, 0x7c, 0x7c, + 0x8b, 0x78, 0x8b, 0x7f, 0x91, 0x81, 0x98, 0x81, 0x08, 0xf7, 0x20, 0x21, + 0x05, 0x0e, 0xf8, 0x15, 0xf9, 0x91, 0xf9, 0x21, 0x15, 0xfb, 0x5b, 0x7b, + 0x06, 0xab, 0x88, 0x95, 0x89, 0x97, 0x83, 0x95, 0x85, 0x92, 0x7d, 0x8b, + 0x7e, 0x8b, 0x7b, 0x71, 0x25, 0x5b, 0xfb, 0x3d, 0x87, 0x7e, 0x87, 0x7a, + 0x86, 0x78, 0x79, 0x4a, 0x7c, 0x63, 0x75, 0x69, 0x64, 0x4d, 0x55, 0x6c, + 0x45, 0x8b, 0x08, 0x38, 0x52, 0xbb, 0xd1, 0x1f, 0x8b, 0xad, 0xaa, 0xf7, + 0x0d, 0xce, 0xf7, 0x7b, 0x8d, 0x92, 0x8d, 0x92, 0x8c, 0x90, 0xa0, 0xd1, + 0x9b, 0x99, 0xcf, 0x92, 0x08, 0x9b, 0xfb, 0xa5, 0x7b, 0x07, 0xce, 0x85, + 0x96, 0x85, 0x8b, 0x6e, 0x8b, 0x7f, 0x88, 0x7b, 0x87, 0x7a, 0x08, 0x56, + 0xfb, 0x54, 0x05, 0x6d, 0xfb, 0x00, 0x7e, 0x4b, 0x8b, 0x63, 0x8b, 0x2b, + 0xe7, 0x46, 0xf7, 0x12, 0x8b, 0xf7, 0x17, 0x8b, 0xde, 0xd2, 0xb7, 0xf7, + 0x2a, 0x08, 0xde, 0xf7, 0xb1, 0x05, 0xb1, 0xf7, 0x16, 0x8f, 0x90, 0xc9, + 0x99, 0x08, 0x9b, 0x07, 0xfb, 0x81, 0xf7, 0x70, 0x15, 0x5a, 0x8b, 0xfb, + 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, 0x23, 0xaf, 0x8b, + 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0xf7, 0x6f, 0xe6, 0xf9, 0x11, 0x15, 0xc3, + 0x83, 0x8e, 0x88, 0x9c, 0x54, 0x08, 0xd8, 0xfb, 0xa1, 0x4e, 0xfb, 0x68, + 0x05, 0x7a, 0x55, 0x75, 0x7b, 0x49, 0x87, 0x08, 0x7b, 0xf7, 0xb5, 0x9b, + 0x07, 0x7b, 0x8c, 0x7d, 0x8c, 0x85, 0x8c, 0x64, 0x8d, 0x7d, 0x95, 0x8b, + 0xa4, 0x8b, 0xa0, 0x92, 0xa9, 0xa3, 0xd9, 0x8e, 0x94, 0x8d, 0x92, 0x8c, + 0x8f, 0x08, 0xa8, 0xf0, 0xf7, 0x6f, 0xf7, 0xa2, 0x05, 0xab, 0xb3, 0x93, + 0x92, 0xa9, 0x99, 0x08, 0x9b, 0xfb, 0x51, 0x7b, 0x07, 0x97, 0x8a, 0x96, + 0x8a, 0x8f, 0x8a, 0xa8, 0x88, 0x98, 0x83, 0x8b, 0x7a, 0x8b, 0x70, 0x5d, + 0x4a, 0x23, 0xfb, 0x0d, 0x08, 0x65, 0x5d, 0x05, 0x7f, 0xb7, 0x88, 0x98, + 0x7b, 0xc0, 0x72, 0xe1, 0x80, 0xb6, 0x8b, 0x9a, 0x8b, 0xa3, 0x97, 0x91, + 0xc7, 0x91, 0x08, 0x9b, 0xfb, 0x83, 0x7b, 0x07, 0xf7, 0x72, 0xd0, 0x15, + 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, 0x97, 0x93, 0x90, 0x93, 0x8b, 0x97, + 0x8b, 0x9f, 0x7b, 0x9b, 0x76, 0x8b, 0x82, 0x8b, 0x82, 0x87, 0x85, 0x85, + 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, 0x0e, 0xf7, 0x6f, 0xf8, 0xf2, 0xf9, + 0x21, 0x15, 0xfc, 0x7a, 0x8b, 0x5d, 0xfb, 0x26, 0x9e, 0x86, 0x05, 0xa0, + 0xb7, 0x97, 0x9c, 0x9e, 0x9c, 0xa8, 0xa3, 0xc0, 0x98, 0xd6, 0x8b, 0x08, + 0xf7, 0x3f, 0x8b, 0xfc, 0x73, 0xfc, 0xef, 0x8b, 0x7d, 0xf8, 0x8d, 0x8b, + 0xc1, 0xf7, 0x3c, 0x78, 0x8e, 0x05, 0x6b, 0x4b, 0x79, 0x73, 0x69, 0x78, + 0x69, 0x77, 0x59, 0x83, 0x39, 0x8b, 0x08, 0xfb, 0x35, 0x8b, 0xf8, 0x77, + 0xf8, 0xef, 0x8b, 0x99, 0x05, 0x51, 0xf7, 0x70, 0x15, 0x67, 0x8b, 0xfb, + 0x22, 0x22, 0x31, 0xf4, 0x66, 0x8b, 0xeb, 0xfb, 0x3d, 0xb9, 0x8b, 0xf7, + 0x37, 0xf7, 0x3d, 0x05, 0x0e, 0xf7, 0xa6, 0xf7, 0x26, 0xf9, 0x11, 0x15, + 0xc4, 0x84, 0x99, 0x83, 0x8b, 0x70, 0x8b, 0x7d, 0x87, 0x77, 0x7e, 0x5d, + 0x08, 0xfb, 0x0a, 0xfc, 0x3d, 0x05, 0x79, 0x4f, 0x84, 0x85, 0x52, 0x83, + 0x08, 0x7b, 0xf7, 0x89, 0x9b, 0x07, 0x4c, 0x94, 0x86, 0x8e, 0x8b, 0xad, + 0x8b, 0x97, 0x8e, 0x98, 0x94, 0xac, 0x08, 0x9c, 0xc7, 0x05, 0xa3, 0x84, + 0xa2, 0x88, 0xb5, 0x8b, 0xdf, 0x8b, 0xcf, 0x9c, 0xb6, 0xaa, 0xbd, 0xb0, + 0xa8, 0xc2, 0x8b, 0xc6, 0x08, 0xeb, 0x40, 0xc0, 0xfb, 0x1c, 0x1e, 0x53, + 0x8b, 0x9f, 0xd8, 0x05, 0x94, 0xa7, 0x98, 0x94, 0xb3, 0x90, 0x08, 0x9b, + 0xfb, 0x82, 0x7b, 0x07, 0xf7, 0x20, 0xfb, 0x46, 0x15, 0x91, 0xa0, 0x97, + 0x93, 0xa7, 0x8b, 0xb1, 0x8b, 0xb2, 0x81, 0x9f, 0x7d, 0xa5, 0x78, 0x96, + 0x6e, 0x8b, 0x5b, 0x8b, 0x4a, 0x74, 0x5d, 0x5f, 0x71, 0x6c, 0x7a, 0x64, + 0x83, 0x4d, 0x8b, 0x7a, 0x8b, 0x86, 0x8b, 0x6d, 0x90, 0x08, 0xd2, 0xf7, + 0x8c, 0x05, 0x0e, 0xf7, 0x6f, 0xe6, 0xf9, 0x11, 0x15, 0xc3, 0x83, 0x8e, + 0x88, 0x9c, 0x54, 0x08, 0xd8, 0xfb, 0xa1, 0x4e, 0xfb, 0x68, 0x05, 0x7a, + 0x55, 0x75, 0x7b, 0x49, 0x87, 0x08, 0x7b, 0xf7, 0xb5, 0x9b, 0x07, 0x7b, + 0x8c, 0x7d, 0x8c, 0x85, 0x8c, 0x64, 0x8d, 0x7d, 0x95, 0x8b, 0xa4, 0x8b, + 0xa0, 0x92, 0xa9, 0xa3, 0xd9, 0x8e, 0x94, 0x8d, 0x92, 0x8c, 0x8f, 0x08, + 0xa8, 0xf0, 0xf7, 0x6f, 0xf7, 0xa2, 0x05, 0xab, 0xb3, 0x93, 0x92, 0xa9, + 0x99, 0x08, 0x9b, 0xfb, 0x51, 0x7b, 0x07, 0x97, 0x8a, 0x96, 0x8a, 0x8f, + 0x8a, 0xa8, 0x88, 0x98, 0x83, 0x8b, 0x7a, 0x8b, 0x70, 0x5d, 0x4a, 0x23, + 0xfb, 0x0d, 0x08, 0x65, 0x5d, 0x05, 0x7f, 0xb7, 0x88, 0x98, 0x7b, 0xc0, + 0x72, 0xe1, 0x80, 0xb6, 0x8b, 0x9a, 0x8b, 0xa3, 0x97, 0x91, 0xc7, 0x91, + 0x08, 0x9b, 0xfb, 0x83, 0x7b, 0x07, 0xf7, 0x59, 0xf7, 0x49, 0x15, 0x6f, + 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, + 0x74, 0xa3, 0x72, 0x1f, 0xf7, 0x5c, 0x16, 0x6f, 0x75, 0x75, 0x71, 0x6f, + 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, + 0x0e, 0xf8, 0x64, 0xf7, 0x02, 0x15, 0x7c, 0x7c, 0x85, 0x86, 0x84, 0x83, + 0x6d, 0x6c, 0x7e, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x85, 0x91, 0x8b, 0x92, + 0x8b, 0x9f, 0xb5, 0xf7, 0x3f, 0xba, 0xf7, 0x40, 0x8e, 0x95, 0x8c, 0x8d, + 0x8d, 0x94, 0x08, 0x84, 0x8e, 0x4e, 0x84, 0x88, 0x88, 0x80, 0x5b, 0x05, + 0x83, 0xb0, 0x6e, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x18, 0xfb, 0x2e, 0xfb, + 0x4b, 0xfb, 0x32, 0x45, 0xb1, 0x62, 0xcb, 0x1f, 0xd1, 0x8b, 0xb6, 0xac, + 0xe3, 0xf7, 0x10, 0x77, 0x3d, 0x88, 0x7e, 0x8b, 0x73, 0x08, 0x6e, 0x97, + 0x7f, 0xa7, 0x1e, 0xb3, 0x8b, 0xa4, 0x9e, 0xd5, 0xe6, 0x08, 0x7f, 0x95, + 0x05, 0xfb, 0x2f, 0xf7, 0xc9, 0x15, 0xad, 0x89, 0xa1, 0x73, 0x8b, 0x68, + 0x8b, 0x37, 0x59, 0xfb, 0x0a, 0x46, 0x41, 0x73, 0x70, 0x69, 0x7a, 0x6e, + 0x8b, 0x68, 0x8b, 0x74, 0xa8, 0x8b, 0xb9, 0x8b, 0xc1, 0xb1, 0xf2, 0xb6, + 0xc9, 0x08, 0xb3, 0xc5, 0xba, 0xab, 0xb3, 0x88, 0x08, 0x47, 0xf7, 0x4f, + 0x15, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, + 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0xf7, 0x5c, 0x16, 0x6f, 0x75, 0x75, + 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, + 0x72, 0x1f, 0x0e, 0xf8, 0x64, 0xf7, 0x02, 0x15, 0x7c, 0x7c, 0x85, 0x86, + 0x84, 0x83, 0x6d, 0x6c, 0x7e, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x85, 0x91, + 0x8b, 0x92, 0x8b, 0x9f, 0xb5, 0xf7, 0x3f, 0xba, 0xf7, 0x40, 0x8e, 0x95, + 0x8c, 0x8d, 0x8d, 0x94, 0x08, 0x84, 0x8e, 0x4e, 0x84, 0x88, 0x88, 0x80, + 0x5b, 0x05, 0x83, 0xb0, 0x6e, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x18, 0xfb, + 0x2e, 0xfb, 0x4b, 0xfb, 0x32, 0x45, 0xb1, 0x62, 0xcb, 0x1f, 0xd1, 0x8b, + 0xb6, 0xac, 0xe3, 0xf7, 0x10, 0x77, 0x3d, 0x88, 0x7e, 0x8b, 0x73, 0x08, + 0x6e, 0x97, 0x7f, 0xa7, 0x1e, 0xb3, 0x8b, 0xa4, 0x9e, 0xd5, 0xe6, 0x08, + 0x7f, 0x95, 0x05, 0xfb, 0x2f, 0xf7, 0xc9, 0x15, 0xad, 0x89, 0xa1, 0x73, + 0x8b, 0x68, 0x8b, 0x37, 0x59, 0xfb, 0x0a, 0x46, 0x41, 0x73, 0x70, 0x69, + 0x7a, 0x6e, 0x8b, 0x68, 0x8b, 0x74, 0xa8, 0x8b, 0xb9, 0x8b, 0xc1, 0xb1, + 0xf2, 0xb6, 0xc9, 0x08, 0xb3, 0xc5, 0xba, 0xab, 0xb3, 0x88, 0x08, 0x5e, + 0xd6, 0x15, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, 0x97, 0x92, 0x90, 0x94, + 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, 0x81, 0x8b, 0x83, 0x87, + 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, 0x0e, 0xf8, 0x64, 0xf7, + 0x02, 0x15, 0x7c, 0x7c, 0x85, 0x86, 0x84, 0x83, 0x6d, 0x6c, 0x7e, 0x81, + 0x82, 0x8b, 0x83, 0x8b, 0x85, 0x91, 0x8b, 0x92, 0x8b, 0x9f, 0xb5, 0xf7, + 0x3f, 0xba, 0xf7, 0x40, 0x8e, 0x95, 0x8c, 0x8d, 0x8d, 0x94, 0x08, 0x84, + 0x8e, 0x4e, 0x84, 0x88, 0x88, 0x80, 0x5b, 0x05, 0x83, 0xb0, 0x6e, 0xa0, + 0x60, 0x8b, 0x08, 0xfb, 0x18, 0xfb, 0x2e, 0xfb, 0x4b, 0xfb, 0x32, 0x45, + 0xb1, 0x62, 0xcb, 0x1f, 0xd1, 0x8b, 0xb6, 0xac, 0xe3, 0xf7, 0x10, 0x77, + 0x3d, 0x88, 0x7e, 0x8b, 0x73, 0x08, 0x6e, 0x97, 0x7f, 0xa7, 0x1e, 0xb3, + 0x8b, 0xa4, 0x9e, 0xd5, 0xe6, 0x08, 0x7f, 0x95, 0x05, 0xfb, 0x2f, 0xf7, + 0xc9, 0x15, 0xad, 0x89, 0xa1, 0x73, 0x8b, 0x68, 0x8b, 0x37, 0x59, 0xfb, + 0x0a, 0x46, 0x41, 0x73, 0x70, 0x69, 0x7a, 0x6e, 0x8b, 0x68, 0x8b, 0x74, + 0xa8, 0x8b, 0xb9, 0x8b, 0xc1, 0xb1, 0xf2, 0xb6, 0xc9, 0x08, 0xb3, 0xc5, + 0xba, 0xab, 0xb3, 0x88, 0x08, 0xc2, 0xd4, 0x15, 0xaa, 0x8b, 0xfb, 0x08, + 0xf7, 0x29, 0x05, 0x7e, 0x9b, 0x7f, 0x92, 0x7d, 0x8b, 0x77, 0x8b, 0x7b, + 0x7c, 0x8b, 0x78, 0x8b, 0x7f, 0x91, 0x82, 0x99, 0x80, 0x08, 0xf7, 0x20, + 0x21, 0x05, 0x0e, 0xf8, 0x64, 0xf7, 0x02, 0x15, 0x7c, 0x7c, 0x85, 0x86, + 0x84, 0x83, 0x6d, 0x6c, 0x7e, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x85, 0x91, + 0x8b, 0x92, 0x8b, 0x9f, 0xb5, 0xf7, 0x3f, 0xba, 0xf7, 0x40, 0x8e, 0x95, + 0x8c, 0x8d, 0x8d, 0x94, 0x08, 0x84, 0x8e, 0x4e, 0x84, 0x88, 0x88, 0x80, + 0x5b, 0x05, 0x83, 0xb0, 0x6e, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x18, 0xfb, + 0x2e, 0xfb, 0x4b, 0xfb, 0x32, 0x45, 0xb1, 0x62, 0xcb, 0x1f, 0xd1, 0x8b, + 0xb6, 0xac, 0xe3, 0xf7, 0x10, 0x77, 0x3d, 0x88, 0x7e, 0x8b, 0x73, 0x08, + 0x6e, 0x97, 0x7f, 0xa7, 0x1e, 0xb3, 0x8b, 0xa4, 0x9e, 0xd5, 0xe6, 0x08, + 0x7f, 0x95, 0x05, 0xfb, 0x2f, 0xf7, 0xc9, 0x15, 0xad, 0x89, 0xa1, 0x73, + 0x8b, 0x68, 0x8b, 0x37, 0x59, 0xfb, 0x0a, 0x46, 0x41, 0x73, 0x70, 0x69, + 0x7a, 0x6e, 0x8b, 0x68, 0x8b, 0x74, 0xa8, 0x8b, 0xb9, 0x8b, 0xc1, 0xb1, + 0xf2, 0xb6, 0xc9, 0x08, 0xb3, 0xc5, 0xba, 0xab, 0xb3, 0x88, 0x08, 0xd3, + 0xf7, 0x86, 0x15, 0x5a, 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, + 0x1d, 0xf3, 0xdd, 0x23, 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0xf8, + 0x64, 0xf7, 0x02, 0x15, 0x7c, 0x7c, 0x85, 0x86, 0x84, 0x83, 0x6d, 0x6c, + 0x7e, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x85, 0x91, 0x8b, 0x92, 0x8b, 0x9f, + 0xb5, 0xf7, 0x3f, 0xba, 0xf7, 0x40, 0x8e, 0x95, 0x8c, 0x8d, 0x8d, 0x94, + 0x08, 0x84, 0x8e, 0x4e, 0x84, 0x88, 0x88, 0x80, 0x5b, 0x05, 0x83, 0xb0, + 0x6e, 0xa0, 0x60, 0x8b, 0x08, 0xfb, 0x18, 0xfb, 0x2e, 0xfb, 0x4b, 0xfb, + 0x32, 0x45, 0xb1, 0x62, 0xcb, 0x1f, 0xd1, 0x8b, 0xb6, 0xac, 0xe3, 0xf7, + 0x10, 0x77, 0x3d, 0x88, 0x7e, 0x8b, 0x73, 0x08, 0x6e, 0x97, 0x7f, 0xa7, + 0x1e, 0xb3, 0x8b, 0xa4, 0x9e, 0xd5, 0xe6, 0x08, 0x7f, 0x95, 0x05, 0xfb, + 0x2f, 0xf7, 0xc9, 0x15, 0xad, 0x89, 0xa1, 0x73, 0x8b, 0x68, 0x8b, 0x37, + 0x59, 0xfb, 0x0a, 0x46, 0x41, 0x73, 0x70, 0x69, 0x7a, 0x6e, 0x8b, 0x68, + 0x8b, 0x74, 0xa8, 0x8b, 0xb9, 0x8b, 0xc1, 0xb1, 0xf2, 0xb6, 0xc9, 0x08, + 0xb3, 0xc5, 0xba, 0xab, 0xb3, 0x88, 0x08, 0xf7, 0x42, 0xf7, 0x61, 0x15, + 0x80, 0x6a, 0x7e, 0x80, 0x70, 0x8b, 0x7c, 0x8b, 0x7a, 0x90, 0x6d, 0x99, + 0x08, 0x65, 0x9c, 0x71, 0x92, 0x75, 0x8b, 0x57, 0x8b, 0x6f, 0x6e, 0x77, + 0x3e, 0x08, 0xa8, 0x06, 0x95, 0xab, 0x9b, 0x9a, 0xa4, 0x8b, 0x9c, 0x8b, + 0xa3, 0x84, 0xc1, 0x75, 0x08, 0xa5, 0x81, 0x9e, 0x86, 0x97, 0x8b, 0xbb, + 0x8b, 0xac, 0xb0, 0x99, 0xce, 0x08, 0x6f, 0x06, 0x0e, 0xf8, 0x64, 0xf7, + 0x02, 0x15, 0x7c, 0x7c, 0x85, 0x86, 0x84, 0x83, 0x6d, 0x6c, 0x7e, 0x81, + 0x82, 0x8b, 0x83, 0x8b, 0x85, 0x91, 0x8b, 0x92, 0x8b, 0x9f, 0xb5, 0xf7, + 0x3f, 0xba, 0xf7, 0x40, 0x8e, 0x95, 0x8c, 0x8d, 0x8d, 0x94, 0x08, 0x84, + 0x8e, 0x4e, 0x84, 0x88, 0x88, 0x80, 0x5b, 0x05, 0x83, 0xb0, 0x6e, 0xa0, + 0x60, 0x8b, 0x08, 0xfb, 0x18, 0xfb, 0x2e, 0xfb, 0x4b, 0xfb, 0x32, 0x45, + 0xb1, 0x62, 0xcb, 0x1f, 0xd1, 0x8b, 0xb6, 0xac, 0xe3, 0xf7, 0x10, 0x77, + 0x3d, 0x88, 0x7e, 0x8b, 0x73, 0x08, 0x6e, 0x97, 0x7f, 0xa7, 0x1e, 0xb3, + 0x8b, 0xa4, 0x9e, 0xd5, 0xe6, 0x08, 0x7f, 0x95, 0x05, 0xfb, 0x2f, 0xf7, + 0xc9, 0x15, 0xad, 0x89, 0xa1, 0x73, 0x8b, 0x68, 0x8b, 0x37, 0x59, 0xfb, + 0x0a, 0x46, 0x41, 0x73, 0x70, 0x69, 0x7a, 0x6e, 0x8b, 0x68, 0x8b, 0x74, + 0xa8, 0x8b, 0xb9, 0x8b, 0xc1, 0xb1, 0xf2, 0xb6, 0xc9, 0x08, 0xb3, 0xc5, + 0xba, 0xab, 0xb3, 0x88, 0x08, 0xa8, 0xf7, 0xb4, 0x15, 0x54, 0x5e, 0x5e, + 0x55, 0x53, 0xb7, 0x5f, 0xc3, 0xc2, 0xb9, 0xb8, 0xc1, 0xc2, 0x5d, 0xb8, + 0x54, 0x1f, 0x69, 0x04, 0xb0, 0xa9, 0x6d, 0x67, 0x66, 0x6e, 0x6f, 0x64, + 0x67, 0x6e, 0xa8, 0xb0, 0xae, 0xa9, 0xa9, 0xaf, 0x1f, 0x0e, 0xf6, 0xf7, + 0x3c, 0x80, 0x15, 0x93, 0x06, 0xd7, 0x8b, 0xc1, 0xa9, 0xc7, 0xd8, 0x08, + 0x7b, 0x95, 0x05, 0x54, 0x50, 0x64, 0x75, 0x5a, 0x8b, 0x52, 0x8b, 0x69, + 0xb6, 0x8b, 0xd2, 0x8b, 0xe0, 0xae, 0xe5, 0xc3, 0xc5, 0xa8, 0xa9, 0xb3, + 0x9d, 0xb3, 0x8b, 0xa1, 0x8b, 0x9a, 0x83, 0x8b, 0x7f, 0x8b, 0x86, 0x89, + 0x86, 0x87, 0x82, 0x08, 0x84, 0x7e, 0x89, 0x84, 0x8b, 0x82, 0x08, 0x73, + 0x9a, 0x7d, 0xa3, 0xa6, 0xa0, 0x9f, 0xa5, 0xb9, 0x5e, 0xae, 0x4f, 0xfb, + 0x2a, 0xfb, 0x20, 0xfb, 0x26, 0xfb, 0x30, 0x1e, 0x8b, 0x3c, 0xaf, 0x59, + 0xce, 0x7b, 0x08, 0x53, 0x31, 0x94, 0x83, 0x05, 0x99, 0x90, 0x93, 0x8d, + 0x95, 0x8b, 0x08, 0xa6, 0x9e, 0x79, 0x71, 0x71, 0x78, 0x7c, 0x69, 0x1f, + 0x76, 0x8b, 0x79, 0x8f, 0x6e, 0x96, 0x08, 0x7a, 0x6e, 0x05, 0xb5, 0x7b, + 0xa2, 0x86, 0xa7, 0x8b, 0x08, 0xd0, 0xbd, 0xaf, 0xbd, 0xb4, 0x6b, 0xa6, + 0x59, 0x1f, 0x83, 0x8b, 0x84, 0x8a, 0x81, 0x89, 0x08, 0xb0, 0xc2, 0x05, + 0x0e, 0xf6, 0xf7, 0xfa, 0xf7, 0x01, 0x15, 0x43, 0x50, 0x6c, 0x7b, 0x60, + 0x8b, 0x52, 0x8b, 0x66, 0xaf, 0x8b, 0xc1, 0x8b, 0x9a, 0x8d, 0x9a, 0x93, + 0xab, 0x08, 0xa7, 0x8f, 0x05, 0xf7, 0x2a, 0xa0, 0xf5, 0xd7, 0x8b, 0xe1, + 0x08, 0xb5, 0x6d, 0xa5, 0x59, 0xfb, 0x24, 0xfb, 0x31, 0xfb, 0x39, 0xfb, + 0x2a, 0x3a, 0xc1, 0x53, 0xd9, 0x1e, 0xd2, 0x8b, 0xd8, 0xb4, 0xc6, 0xce, + 0x08, 0x7f, 0x97, 0x05, 0xfb, 0x62, 0xf7, 0x23, 0x15, 0xad, 0xe4, 0xd5, + 0xd8, 0xbe, 0x8b, 0xa0, 0x8b, 0x99, 0x7b, 0x8b, 0x74, 0x8b, 0x6c, 0x78, + 0x67, 0x6c, 0x6d, 0x66, 0x68, 0x65, 0x79, 0x35, 0x76, 0x08, 0x9c, 0xb7, + 0x05, 0xbe, 0xf7, 0xf6, 0x15, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, + 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0xf7, 0x5c, + 0x16, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, + 0xa6, 0x1f, 0xa4, 0x74, 0xa3, 0x72, 0x1e, 0x0e, 0xf6, 0xf7, 0xfa, 0xf7, + 0x01, 0x15, 0x43, 0x50, 0x6c, 0x7b, 0x60, 0x8b, 0x52, 0x8b, 0x66, 0xaf, + 0x8b, 0xc1, 0x8b, 0x9a, 0x8d, 0x9a, 0x93, 0xab, 0x08, 0xa7, 0x8f, 0x05, + 0xf7, 0x2a, 0xa0, 0xf5, 0xd7, 0x8b, 0xe1, 0x08, 0xb5, 0x6d, 0xa5, 0x59, + 0xfb, 0x24, 0xfb, 0x31, 0xfb, 0x39, 0xfb, 0x2a, 0x3a, 0xc1, 0x53, 0xd9, + 0x1e, 0xd2, 0x8b, 0xd8, 0xb4, 0xc6, 0xce, 0x08, 0x7f, 0x97, 0x05, 0xfb, + 0x62, 0xf7, 0x23, 0x15, 0xad, 0xe4, 0xd5, 0xd8, 0xbe, 0x8b, 0xa0, 0x8b, + 0x99, 0x7b, 0x8b, 0x74, 0x8b, 0x6c, 0x78, 0x67, 0x6c, 0x6d, 0x66, 0x68, + 0x65, 0x79, 0x35, 0x76, 0x08, 0x9c, 0xb7, 0x05, 0xdf, 0xf7, 0x86, 0x15, + 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, 0x97, 0x92, 0x90, 0x94, 0x8b, 0x97, + 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, 0x81, 0x8b, 0x83, 0x87, 0x84, 0x85, + 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, 0x0e, 0xf6, 0xf7, 0xfa, 0xf7, 0x01, + 0x15, 0x43, 0x50, 0x6c, 0x7b, 0x60, 0x8b, 0x52, 0x8b, 0x66, 0xaf, 0x8b, + 0xc1, 0x8b, 0x9a, 0x8d, 0x9a, 0x93, 0xab, 0x08, 0xa7, 0x8f, 0x05, 0xf7, + 0x2a, 0xa0, 0xf5, 0xd7, 0x8b, 0xe1, 0x08, 0xb5, 0x6d, 0xa5, 0x59, 0xfb, + 0x24, 0xfb, 0x31, 0xfb, 0x39, 0xfb, 0x2a, 0x3a, 0xc1, 0x53, 0xd9, 0x1e, + 0xd2, 0x8b, 0xd8, 0xb4, 0xc6, 0xce, 0x08, 0x7f, 0x97, 0x05, 0xfb, 0x62, + 0xf7, 0x23, 0x15, 0xad, 0xe4, 0xd5, 0xd8, 0xbe, 0x8b, 0xa0, 0x8b, 0x99, + 0x7b, 0x8b, 0x74, 0x8b, 0x6c, 0x78, 0x67, 0x6c, 0x6d, 0x66, 0x68, 0x65, + 0x79, 0x35, 0x76, 0x08, 0x9c, 0xb7, 0x05, 0xf7, 0x4c, 0xf7, 0x84, 0x15, + 0xaa, 0x8b, 0xfb, 0x08, 0xf7, 0x29, 0x05, 0x7e, 0x9b, 0x7f, 0x92, 0x7d, + 0x8b, 0x77, 0x8b, 0x7b, 0x7c, 0x8b, 0x78, 0x8b, 0x7f, 0x91, 0x82, 0x99, + 0x80, 0x08, 0xf7, 0x20, 0x21, 0x05, 0x0e, 0xf6, 0xf7, 0xfa, 0xf7, 0x01, + 0x15, 0x43, 0x50, 0x6c, 0x7b, 0x60, 0x8b, 0x52, 0x8b, 0x66, 0xaf, 0x8b, + 0xc1, 0x8b, 0x9a, 0x8d, 0x9a, 0x93, 0xab, 0x08, 0xa7, 0x8f, 0x05, 0xf7, + 0x2a, 0xa0, 0xf5, 0xd7, 0x8b, 0xe1, 0x08, 0xb5, 0x6d, 0xa5, 0x59, 0xfb, + 0x24, 0xfb, 0x31, 0xfb, 0x39, 0xfb, 0x2a, 0x3a, 0xc1, 0x53, 0xd9, 0x1e, + 0xd2, 0x8b, 0xd8, 0xb4, 0xc6, 0xce, 0x08, 0x7f, 0x97, 0x05, 0xfb, 0x62, + 0xf7, 0x23, 0x15, 0xad, 0xe4, 0xd5, 0xd8, 0xbe, 0x8b, 0xa0, 0x8b, 0x99, + 0x7b, 0x8b, 0x74, 0x8b, 0x6c, 0x78, 0x67, 0x6c, 0x6d, 0x66, 0x68, 0x65, + 0x79, 0x35, 0x76, 0x08, 0x9c, 0xb7, 0x05, 0xf7, 0x5d, 0xf8, 0x2d, 0x15, + 0x5a, 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, + 0x23, 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0x50, 0xf4, 0xf8, 0xf2, + 0x15, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, + 0xa6, 0x1f, 0xa4, 0x74, 0xa3, 0x72, 0x1e, 0xf7, 0x5c, 0x16, 0x6f, 0x75, + 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, + 0xa3, 0x72, 0x1f, 0x38, 0xfc, 0x80, 0x15, 0x73, 0x6b, 0x84, 0x83, 0x81, + 0x80, 0x7a, 0x7a, 0x7c, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x83, 0x93, 0x8b, + 0x92, 0x8b, 0x95, 0x8e, 0x9a, 0x92, 0x9e, 0x8b, 0x8e, 0x8e, 0x92, 0x8d, + 0x93, 0x08, 0x8b, 0x8d, 0x8c, 0x8d, 0xe3, 0xf7, 0xd6, 0x88, 0x8d, 0x05, + 0x26, 0x78, 0x77, 0x88, 0x64, 0x88, 0x08, 0x7b, 0x07, 0xc0, 0x8a, 0x95, + 0x88, 0x8b, 0x77, 0x8b, 0x83, 0x88, 0x7b, 0x85, 0x77, 0x08, 0x5b, 0xfb, + 0x45, 0x05, 0x7b, 0x51, 0x85, 0x6c, 0x8b, 0x77, 0x8b, 0x66, 0x9b, 0x77, + 0xa9, 0x8b, 0xb9, 0x8b, 0xb0, 0xa9, 0xc4, 0xdf, 0x08, 0x7e, 0x96, 0x05, + 0x0e, 0x50, 0xf7, 0x72, 0xf7, 0x06, 0x15, 0x73, 0x6b, 0x84, 0x83, 0x81, + 0x80, 0x7a, 0x7a, 0x7c, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x83, 0x93, 0x8b, + 0x92, 0x8b, 0x95, 0x8e, 0x9a, 0x92, 0x9e, 0x8b, 0x8e, 0x8e, 0x92, 0x8d, + 0x93, 0x08, 0x8b, 0x8d, 0x8c, 0x8d, 0xe3, 0xf7, 0xd6, 0x88, 0x8d, 0x05, + 0x26, 0x78, 0x77, 0x88, 0x64, 0x88, 0x08, 0x7b, 0x07, 0xc0, 0x8a, 0x95, + 0x88, 0x8b, 0x77, 0x8b, 0x83, 0x88, 0x7b, 0x85, 0x77, 0x08, 0x5b, 0xfb, + 0x45, 0x05, 0x7b, 0x51, 0x85, 0x6c, 0x8b, 0x77, 0x8b, 0x66, 0x9b, 0x77, + 0xa9, 0x8b, 0xb9, 0x8b, 0xb0, 0xa9, 0xc4, 0xdf, 0x08, 0x7e, 0x96, 0x05, + 0x32, 0xf8, 0x10, 0x15, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, 0x97, 0x92, + 0x90, 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, 0x81, 0x8b, + 0x83, 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, 0x0e, 0x50, + 0xf7, 0x72, 0xf7, 0x06, 0x15, 0x73, 0x6b, 0x84, 0x83, 0x81, 0x80, 0x7a, + 0x7a, 0x7c, 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x83, 0x93, 0x8b, 0x92, 0x8b, + 0x95, 0x8e, 0x9a, 0x92, 0x9e, 0x8b, 0x8e, 0x8e, 0x92, 0x8d, 0x93, 0x08, + 0x8b, 0x8d, 0x8c, 0x8d, 0xe3, 0xf7, 0xd6, 0x88, 0x8d, 0x05, 0x26, 0x78, + 0x77, 0x88, 0x64, 0x88, 0x08, 0x7b, 0x07, 0xc0, 0x8a, 0x95, 0x88, 0x8b, + 0x77, 0x8b, 0x83, 0x88, 0x7b, 0x85, 0x77, 0x08, 0x5b, 0xfb, 0x45, 0x05, + 0x7b, 0x51, 0x85, 0x6c, 0x8b, 0x77, 0x8b, 0x66, 0x9b, 0x77, 0xa9, 0x8b, + 0xb9, 0x8b, 0xb0, 0xa9, 0xc4, 0xdf, 0x08, 0x7e, 0x96, 0x05, 0xaa, 0xf8, + 0x0e, 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, 0x29, 0x05, 0x7e, 0x9b, 0x80, + 0x92, 0x7c, 0x8b, 0x77, 0x8b, 0x7c, 0x7c, 0x8b, 0x78, 0x8b, 0x7f, 0x91, + 0x81, 0x98, 0x81, 0x08, 0xf7, 0x20, 0x21, 0x05, 0x0e, 0x50, 0xf7, 0x72, + 0xf7, 0x06, 0x15, 0x73, 0x6b, 0x84, 0x83, 0x81, 0x80, 0x7a, 0x7a, 0x7c, + 0x81, 0x82, 0x8b, 0x83, 0x8b, 0x83, 0x93, 0x8b, 0x92, 0x8b, 0x95, 0x8e, + 0x9a, 0x92, 0x9e, 0x8b, 0x8e, 0x8e, 0x92, 0x8d, 0x93, 0x08, 0x8b, 0x8d, + 0x8c, 0x8d, 0xe3, 0xf7, 0xd6, 0x88, 0x8d, 0x05, 0x26, 0x78, 0x77, 0x88, + 0x64, 0x88, 0x08, 0x7b, 0x07, 0xc0, 0x8a, 0x95, 0x88, 0x8b, 0x77, 0x8b, + 0x83, 0x88, 0x7b, 0x85, 0x77, 0x08, 0x5b, 0xfb, 0x45, 0x05, 0x7b, 0x51, + 0x85, 0x6c, 0x8b, 0x77, 0x8b, 0x66, 0x9b, 0x77, 0xa9, 0x8b, 0xb9, 0x8b, + 0xb0, 0xa9, 0xc4, 0xdf, 0x08, 0x7e, 0x96, 0x05, 0x9d, 0xf8, 0xb7, 0x15, + 0x5a, 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, + 0x23, 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0xf8, 0x60, 0xf7, 0x09, + 0x15, 0x76, 0x71, 0x05, 0x6e, 0x66, 0x79, 0x7b, 0x7d, 0x8b, 0x83, 0x8b, + 0x83, 0x93, 0x8b, 0x93, 0x8b, 0x92, 0x8b, 0x8b, 0x99, 0xc3, 0x08, 0xc4, + 0xf7, 0x62, 0x05, 0x90, 0xa0, 0x8f, 0xa1, 0x8b, 0x99, 0x8b, 0xaf, 0x70, + 0xa4, 0x64, 0x8b, 0x4b, 0x8b, 0x4c, 0x4f, 0x24, 0xfb, 0x34, 0x08, 0xce, + 0xf7, 0x6e, 0x88, 0x8d, 0x05, 0x55, 0x80, 0x76, 0x87, 0x34, 0x7b, 0x08, + 0x7b, 0x07, 0xbe, 0x8a, 0x98, 0x85, 0x8b, 0x77, 0x8b, 0x85, 0x8a, 0x85, + 0x8a, 0x86, 0x08, 0x2b, 0xfb, 0xf2, 0xd6, 0x8b, 0x05, 0xba, 0xf7, 0x32, + 0x94, 0xa1, 0xb7, 0xcf, 0xc7, 0xe7, 0xbe, 0xbd, 0xb0, 0x8b, 0x9a, 0x8b, + 0x94, 0x80, 0x8b, 0x79, 0x8b, 0x7f, 0x85, 0x6a, 0x83, 0x6c, 0x08, 0x5f, + 0xfb, 0x39, 0x05, 0x7e, 0x58, 0x88, 0x7d, 0x8b, 0x81, 0x8b, 0x65, 0x99, + 0x7b, 0xac, 0x8b, 0xb8, 0x8b, 0xa5, 0xa0, 0xd0, 0xe7, 0x08, 0x7d, 0x98, + 0x05, 0x7f, 0xf8, 0x8f, 0x15, 0x80, 0x6a, 0x7e, 0x80, 0x70, 0x8b, 0x7c, + 0x8b, 0x7a, 0x90, 0x6d, 0x99, 0x08, 0x65, 0x9c, 0x71, 0x92, 0x75, 0x8b, + 0x57, 0x8b, 0x6f, 0x6e, 0x77, 0x3e, 0x08, 0xa8, 0x06, 0x95, 0xab, 0x9b, + 0x9a, 0xa4, 0x8b, 0x9c, 0x8b, 0xa3, 0x84, 0xc1, 0x75, 0x08, 0xa5, 0x81, + 0x9e, 0x86, 0x97, 0x8b, 0xbb, 0x8b, 0xac, 0xb0, 0x99, 0xce, 0x08, 0x6f, + 0x06, 0x0e, 0xf7, 0xd9, 0xf8, 0x4d, 0x15, 0xfb, 0x2a, 0xfb, 0x28, 0xfb, + 0x2f, 0xfb, 0x31, 0x35, 0xc3, 0x55, 0xe6, 0x1f, 0xcd, 0x8b, 0xcb, 0xa9, + 0xc5, 0xc4, 0xcd, 0xcc, 0xb3, 0xe0, 0x8b, 0xd6, 0x08, 0xde, 0x51, 0xc4, + 0x36, 0x1e, 0x7f, 0x76, 0x15, 0xb6, 0xa7, 0x66, 0x52, 0x1f, 0x8b, 0x42, + 0x6a, 0x27, 0x5f, 0x4a, 0x66, 0x56, 0x65, 0x72, 0x60, 0x8b, 0x5c, 0x8b, + 0x6c, 0xaf, 0x8b, 0xc2, 0x8b, 0xd5, 0xa8, 0xe3, 0xbc, 0xd2, 0xb2, 0xc3, + 0xb5, 0xa9, 0xb6, 0x8b, 0x08, 0x43, 0xf7, 0x4e, 0x15, 0x6f, 0x75, 0x75, + 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, + 0x72, 0x1f, 0xf7, 0x5c, 0x16, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, + 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0x1f, 0xa4, 0x74, 0xa3, 0x72, 0x1e, 0x0e, + 0xf7, 0xd9, 0xf8, 0x4d, 0x15, 0xfb, 0x2a, 0xfb, 0x28, 0xfb, 0x2f, 0xfb, + 0x31, 0x35, 0xc3, 0x55, 0xe6, 0x1f, 0xcd, 0x8b, 0xcb, 0xa9, 0xc5, 0xc4, + 0xcd, 0xcc, 0xb3, 0xe0, 0x8b, 0xd6, 0x08, 0xde, 0x51, 0xc4, 0x36, 0x1e, + 0x7f, 0x76, 0x15, 0xb6, 0xa7, 0x66, 0x52, 0x1f, 0x8b, 0x42, 0x6a, 0x27, + 0x5f, 0x4a, 0x66, 0x56, 0x65, 0x72, 0x60, 0x8b, 0x5c, 0x8b, 0x6c, 0xaf, + 0x8b, 0xc2, 0x8b, 0xd5, 0xa8, 0xe3, 0xbc, 0xd2, 0xb2, 0xc3, 0xb5, 0xa9, + 0xb6, 0x8b, 0x08, 0x5a, 0xd5, 0x15, 0xae, 0x8b, 0xf7, 0x3f, 0xf5, 0x05, + 0x97, 0x92, 0x90, 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, 0x9b, 0x77, 0x8b, + 0x81, 0x8b, 0x83, 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, 0xfb, 0x34, 0x05, + 0x0e, 0xf7, 0xd9, 0xf8, 0x4d, 0x15, 0xfb, 0x2a, 0xfb, 0x28, 0xfb, 0x2f, + 0xfb, 0x31, 0x35, 0xc3, 0x55, 0xe6, 0x1f, 0xcd, 0x8b, 0xcb, 0xa9, 0xc5, + 0xc4, 0xcd, 0xcc, 0xb3, 0xe0, 0x8b, 0xd6, 0x08, 0xde, 0x51, 0xc4, 0x36, + 0x1e, 0x7f, 0x76, 0x15, 0xb6, 0xa7, 0x66, 0x52, 0x1f, 0x8b, 0x42, 0x6a, + 0x27, 0x5f, 0x4a, 0x66, 0x56, 0x65, 0x72, 0x60, 0x8b, 0x5c, 0x8b, 0x6c, + 0xaf, 0x8b, 0xc2, 0x8b, 0xd5, 0xa8, 0xe3, 0xbc, 0xd2, 0xb2, 0xc3, 0xb5, + 0xa9, 0xb6, 0x8b, 0x08, 0xbe, 0xd3, 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, + 0x29, 0x05, 0x7e, 0x9b, 0x7f, 0x92, 0x7d, 0x8b, 0x77, 0x8b, 0x7b, 0x7c, + 0x8b, 0x78, 0x8b, 0x7f, 0x91, 0x82, 0x99, 0x80, 0x08, 0xf7, 0x20, 0x21, + 0x05, 0x0e, 0xf7, 0xd9, 0xf8, 0x4d, 0x15, 0xfb, 0x2a, 0xfb, 0x28, 0xfb, + 0x2f, 0xfb, 0x31, 0x35, 0xc3, 0x55, 0xe6, 0x1f, 0xcd, 0x8b, 0xcb, 0xa9, + 0xc5, 0xc4, 0xcd, 0xcc, 0xb3, 0xe0, 0x8b, 0xd6, 0x08, 0xde, 0x51, 0xc4, + 0x36, 0x1e, 0x7f, 0x76, 0x15, 0xb6, 0xa7, 0x66, 0x52, 0x1f, 0x8b, 0x42, + 0x6a, 0x27, 0x5f, 0x4a, 0x66, 0x56, 0x65, 0x72, 0x60, 0x8b, 0x5c, 0x8b, + 0x6c, 0xaf, 0x8b, 0xc2, 0x8b, 0xd5, 0xa8, 0xe3, 0xbc, 0xd2, 0xb2, 0xc3, + 0xb5, 0xa9, 0xb6, 0x8b, 0x08, 0xc4, 0xf7, 0x85, 0x15, 0x5a, 0x8b, 0xfb, + 0x31, 0xfb, 0x3d, 0xb2, 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, 0x23, 0xaf, 0x8b, + 0x33, 0xf7, 0x3d, 0x05, 0x0e, 0xf7, 0xd9, 0xf8, 0x4d, 0x15, 0xfb, 0x2a, + 0xfb, 0x28, 0xfb, 0x2f, 0xfb, 0x31, 0x35, 0xc3, 0x55, 0xe6, 0x1f, 0xcd, + 0x8b, 0xcb, 0xa9, 0xc5, 0xc4, 0xcd, 0xcc, 0xb3, 0xe0, 0x8b, 0xd6, 0x08, + 0xde, 0x51, 0xc4, 0x36, 0x1e, 0x7f, 0x76, 0x15, 0xb6, 0xa7, 0x66, 0x52, + 0x1f, 0x8b, 0x42, 0x6a, 0x27, 0x5f, 0x4a, 0x66, 0x56, 0x65, 0x72, 0x60, + 0x8b, 0x5c, 0x8b, 0x6c, 0xaf, 0x8b, 0xc2, 0x8b, 0xd5, 0xa8, 0xe3, 0xbc, + 0xd2, 0xb2, 0xc3, 0xb5, 0xa9, 0xb6, 0x8b, 0x08, 0xf7, 0x2f, 0xf7, 0x60, + 0x15, 0x80, 0x6a, 0x7e, 0x80, 0x70, 0x8b, 0x7c, 0x8b, 0x7a, 0x90, 0x6d, + 0x99, 0x08, 0x65, 0x9c, 0x71, 0x92, 0x75, 0x8b, 0x57, 0x8b, 0x6f, 0x6e, + 0x77, 0x3e, 0x08, 0xa8, 0x06, 0x95, 0xab, 0x9b, 0x9a, 0xa4, 0x8b, 0x9c, + 0x8b, 0xa3, 0x84, 0xc1, 0x75, 0x08, 0xa5, 0x81, 0x9e, 0x86, 0x97, 0x8b, + 0xbb, 0x8b, 0xac, 0xb0, 0x99, 0xce, 0x08, 0x6f, 0x06, 0x0e, 0xbf, 0xaf, + 0xf7, 0x26, 0x15, 0x77, 0xfb, 0x33, 0x9b, 0x8b, 0x05, 0x93, 0x9b, 0x91, + 0x90, 0x95, 0x8b, 0x96, 0x8b, 0x9d, 0x87, 0x9f, 0x86, 0x08, 0xa1, 0x84, + 0x9c, 0x88, 0x9b, 0x8b, 0xdf, 0x8b, 0xc7, 0xc1, 0x8b, 0xd7, 0x8b, 0xb1, + 0x76, 0xb7, 0x5c, 0xc5, 0x65, 0xba, 0x7b, 0xaa, 0x8b, 0xa6, 0x8b, 0xac, + 0xa0, 0xa0, 0xae, 0x8b, 0xbf, 0x8b, 0xa9, 0x66, 0x95, 0x3d, 0x08, 0x9b, + 0x8b, 0x9f, 0xf7, 0x1f, 0x7d, 0x8b, 0x05, 0x83, 0x7d, 0x83, 0x87, 0x7d, + 0x8b, 0x84, 0x8b, 0x81, 0x8d, 0x78, 0x90, 0x72, 0x93, 0x7c, 0x8d, 0x7b, + 0x8b, 0x42, 0x8b, 0x5b, 0x60, 0x8b, 0x48, 0x8b, 0x6b, 0xa0, 0x60, 0xb5, + 0x55, 0xb2, 0x58, 0x9c, 0x68, 0x8b, 0x6e, 0x08, 0x5e, 0x6d, 0x6b, 0x5f, + 0x1e, 0x54, 0x8b, 0x6c, 0xb4, 0x7b, 0xea, 0x08, 0x7b, 0x06, 0xf8, 0x36, + 0xf8, 0x97, 0x15, 0x67, 0x8b, 0xfb, 0x22, 0x22, 0x31, 0xf4, 0x66, 0x8b, + 0xeb, 0xfb, 0x3d, 0xb9, 0x8b, 0xf7, 0x37, 0xf7, 0x3d, 0x05, 0x0e, 0xf8, + 0x61, 0xf7, 0x09, 0x15, 0x57, 0x4a, 0x7c, 0x7d, 0x7b, 0x8b, 0x84, 0x8b, + 0x87, 0x91, 0x8b, 0x96, 0x8b, 0x91, 0x8b, 0x8b, 0x9e, 0xd3, 0x08, 0xda, + 0xf7, 0xbf, 0x41, 0x8b, 0x05, 0x52, 0xfb, 0x2f, 0x84, 0x7b, 0x5d, 0x42, + 0x08, 0x4f, 0x2c, 0x5a, 0x58, 0x6b, 0x8b, 0x7f, 0x8b, 0x82, 0x95, 0x8b, + 0x9a, 0x8b, 0x8f, 0x8b, 0x8d, 0x8c, 0x8e, 0x08, 0xe6, 0xf7, 0xff, 0x88, + 0x8d, 0x05, 0x52, 0x7e, 0x67, 0x84, 0x52, 0x84, 0x08, 0x7d, 0x07, 0xb1, + 0x8b, 0x8d, 0x8a, 0x94, 0x86, 0x91, 0x89, 0x90, 0x82, 0x8b, 0x84, 0x8b, + 0x83, 0x86, 0x72, 0x82, 0x69, 0x08, 0x66, 0xfb, 0x22, 0x05, 0x79, 0x44, + 0x84, 0x69, 0x8b, 0x79, 0x8b, 0x67, 0x9d, 0x78, 0xae, 0x8b, 0xd2, 0x8b, + 0xc0, 0xc2, 0xf7, 0x07, 0xf7, 0x54, 0x6e, 0x20, 0x7b, 0x46, 0x8b, 0x76, + 0x08, 0x6d, 0x9d, 0x79, 0xa9, 0x1e, 0xba, 0x8b, 0xa1, 0x9e, 0xd0, 0xed, + 0x08, 0x7d, 0x94, 0x05, 0xfb, 0x7a, 0xf8, 0x7d, 0x15, 0x6f, 0x75, 0x75, + 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, + 0x72, 0x1f, 0xf7, 0x5c, 0x16, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, + 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0x0e, 0xf8, + 0x61, 0xf7, 0x09, 0x15, 0x57, 0x4a, 0x7c, 0x7d, 0x7b, 0x8b, 0x84, 0x8b, + 0x87, 0x91, 0x8b, 0x96, 0x8b, 0x91, 0x8b, 0x8b, 0x9e, 0xd3, 0x08, 0xda, + 0xf7, 0xbf, 0x41, 0x8b, 0x05, 0x52, 0xfb, 0x2f, 0x84, 0x7b, 0x5d, 0x42, + 0x08, 0x4f, 0x2c, 0x5a, 0x58, 0x6b, 0x8b, 0x7f, 0x8b, 0x82, 0x95, 0x8b, + 0x9a, 0x8b, 0x8f, 0x8b, 0x8d, 0x8c, 0x8e, 0x08, 0xe6, 0xf7, 0xff, 0x88, + 0x8d, 0x05, 0x52, 0x7e, 0x67, 0x84, 0x52, 0x84, 0x08, 0x7d, 0x07, 0xb1, + 0x8b, 0x8d, 0x8a, 0x94, 0x86, 0x91, 0x89, 0x90, 0x82, 0x8b, 0x84, 0x8b, + 0x83, 0x86, 0x72, 0x82, 0x69, 0x08, 0x66, 0xfb, 0x22, 0x05, 0x79, 0x44, + 0x84, 0x69, 0x8b, 0x79, 0x8b, 0x67, 0x9d, 0x78, 0xae, 0x8b, 0xd2, 0x8b, + 0xc0, 0xc2, 0xf7, 0x07, 0xf7, 0x54, 0x6e, 0x20, 0x7b, 0x46, 0x8b, 0x76, + 0x08, 0x6d, 0x9d, 0x79, 0xa9, 0x1e, 0xba, 0x8b, 0xa1, 0x9e, 0xd0, 0xed, + 0x08, 0x7d, 0x94, 0x05, 0xfb, 0x63, 0xf8, 0x0d, 0x15, 0xae, 0x8b, 0xf7, + 0x3f, 0xf5, 0x05, 0x97, 0x92, 0x90, 0x94, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, + 0x9b, 0x77, 0x8b, 0x81, 0x8b, 0x83, 0x87, 0x84, 0x85, 0x08, 0xfb, 0x36, + 0xfb, 0x34, 0x05, 0x0e, 0xf8, 0x61, 0xf7, 0x09, 0x15, 0x57, 0x4a, 0x7c, + 0x7d, 0x7b, 0x8b, 0x84, 0x8b, 0x87, 0x91, 0x8b, 0x96, 0x8b, 0x91, 0x8b, + 0x8b, 0x9e, 0xd3, 0x08, 0xda, 0xf7, 0xbf, 0x41, 0x8b, 0x05, 0x52, 0xfb, + 0x2f, 0x84, 0x7b, 0x5d, 0x42, 0x08, 0x4f, 0x2c, 0x5a, 0x58, 0x6b, 0x8b, + 0x7f, 0x8b, 0x82, 0x95, 0x8b, 0x9a, 0x8b, 0x8f, 0x8b, 0x8d, 0x8c, 0x8e, + 0x08, 0xe6, 0xf7, 0xff, 0x88, 0x8d, 0x05, 0x52, 0x7e, 0x67, 0x84, 0x52, + 0x84, 0x08, 0x7d, 0x07, 0xb1, 0x8b, 0x8d, 0x8a, 0x94, 0x86, 0x91, 0x89, + 0x90, 0x82, 0x8b, 0x84, 0x8b, 0x83, 0x86, 0x72, 0x82, 0x69, 0x08, 0x66, + 0xfb, 0x22, 0x05, 0x79, 0x44, 0x84, 0x69, 0x8b, 0x79, 0x8b, 0x67, 0x9d, + 0x78, 0xae, 0x8b, 0xd2, 0x8b, 0xc0, 0xc1, 0xf7, 0x07, 0xf7, 0x55, 0x6e, + 0x20, 0x7b, 0x46, 0x8b, 0x76, 0x08, 0x6d, 0x9d, 0x79, 0xa9, 0x1e, 0xba, + 0x8b, 0xa2, 0x9f, 0xcf, 0xec, 0x08, 0x7d, 0x94, 0x05, 0x2a, 0xf8, 0x0b, + 0x15, 0xaa, 0x8b, 0xfb, 0x08, 0xf7, 0x29, 0x05, 0x7e, 0x9b, 0x7f, 0x92, + 0x7d, 0x8b, 0x77, 0x8b, 0x7b, 0x7c, 0x8b, 0x78, 0x8b, 0x7f, 0x91, 0x82, + 0x99, 0x80, 0x08, 0xf7, 0x20, 0x21, 0x05, 0x0e, 0xf8, 0x61, 0xf7, 0x09, + 0x15, 0x57, 0x4a, 0x7c, 0x7d, 0x7b, 0x8b, 0x84, 0x8b, 0x87, 0x91, 0x8b, + 0x96, 0x8b, 0x91, 0x8b, 0x8b, 0x9e, 0xd3, 0x08, 0xda, 0xf7, 0xbf, 0x41, + 0x8b, 0x05, 0x52, 0xfb, 0x2f, 0x84, 0x7b, 0x5d, 0x42, 0x08, 0x4f, 0x2c, + 0x5a, 0x58, 0x6b, 0x8b, 0x7f, 0x8b, 0x82, 0x95, 0x8b, 0x9a, 0x8b, 0x8f, + 0x8b, 0x8d, 0x8c, 0x8e, 0x08, 0xe6, 0xf7, 0xff, 0x88, 0x8d, 0x05, 0x52, + 0x7e, 0x67, 0x84, 0x52, 0x84, 0x08, 0x7d, 0x07, 0xb1, 0x8b, 0x8d, 0x8a, + 0x94, 0x86, 0x91, 0x89, 0x90, 0x82, 0x8b, 0x84, 0x8b, 0x83, 0x86, 0x72, + 0x82, 0x69, 0x08, 0x66, 0xfb, 0x22, 0x05, 0x79, 0x44, 0x84, 0x69, 0x8b, + 0x79, 0x8b, 0x67, 0x9d, 0x78, 0xae, 0x8b, 0xd2, 0x8b, 0xc0, 0xc1, 0xf7, + 0x07, 0xf7, 0x55, 0x6e, 0x20, 0x7b, 0x46, 0x8b, 0x76, 0x08, 0x6d, 0x9d, + 0x79, 0xa9, 0x1e, 0xba, 0x8b, 0xa2, 0x9f, 0xcf, 0xec, 0x08, 0x7d, 0x94, + 0x05, 0x22, 0xf8, 0xb4, 0x15, 0x5a, 0x8b, 0xfb, 0x31, 0xfb, 0x3d, 0xb2, + 0x8b, 0xf7, 0x1d, 0xf3, 0xdd, 0x23, 0xaf, 0x8b, 0x33, 0xf7, 0x3d, 0x05, + 0x0e, 0xf6, 0x9a, 0xf8, 0x24, 0x15, 0x98, 0x8e, 0x92, 0x8c, 0x96, 0x8b, + 0xc4, 0x8b, 0x9a, 0x72, 0xb9, 0xfb, 0x40, 0x9c, 0x4a, 0xa3, 0xfb, 0x09, + 0x8b, 0x7a, 0x8b, 0x7b, 0x85, 0x7b, 0x7c, 0x79, 0x6c, 0x62, 0x77, 0x71, + 0x80, 0x7f, 0x76, 0x75, 0x7f, 0x83, 0x7e, 0x8b, 0x08, 0x85, 0x8b, 0x84, + 0x8e, 0x80, 0x93, 0x7c, 0x97, 0x80, 0x90, 0x80, 0x8b, 0x08, 0x75, 0x7a, + 0x7a, 0x75, 0x72, 0xa1, 0x78, 0xa8, 0x1f, 0xcb, 0x8b, 0xf7, 0x17, 0xf7, + 0x2a, 0xf7, 0x00, 0xf7, 0x5a, 0xcf, 0xf7, 0x0f, 0xa7, 0xd3, 0x8b, 0xbc, + 0x08, 0xa9, 0x72, 0xa4, 0x6d, 0x74, 0x7b, 0x7c, 0x75, 0x1e, 0x8b, 0x7c, + 0x93, 0x80, 0x9f, 0x7e, 0x9e, 0x80, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x63, + 0x66, 0x3d, 0x36, 0xfb, 0x21, 0x08, 0x77, 0xf7, 0x08, 0x05, 0x7c, 0xe3, + 0x53, 0xf7, 0x39, 0x7c, 0x8b, 0x08, 0x87, 0x06, 0x8a, 0x8a, 0x87, 0x8b, + 0x87, 0x8b, 0x82, 0x8a, 0x67, 0x85, 0x56, 0x81, 0x86, 0x8a, 0x7e, 0x88, + 0x7d, 0x89, 0x08, 0x7a, 0x07, 0xf7, 0x71, 0xe9, 0x15, 0xae, 0x8b, 0xf7, + 0x3f, 0xf5, 0x05, 0x97, 0x93, 0x90, 0x93, 0x8b, 0x97, 0x8b, 0x9f, 0x7b, + 0x9b, 0x76, 0x8b, 0x82, 0x8b, 0x82, 0x87, 0x85, 0x85, 0x08, 0xfb, 0x36, + 0xfb, 0x34, 0x05, 0x0e, 0xbf, 0xdc, 0xf7, 0xc9, 0x15, 0xa0, 0xbd, 0x98, + 0x94, 0xba, 0x8b, 0x08, 0xf7, 0x26, 0x8b, 0xfb, 0xca, 0xfc, 0x08, 0x94, + 0x82, 0x05, 0x9b, 0x98, 0x98, 0x90, 0x9c, 0x8b, 0xa3, 0x8b, 0xac, 0x7e, + 0xba, 0x6e, 0xbd, 0x6c, 0xad, 0x7e, 0xa7, 0x8b, 0x08, 0xbd, 0xb7, 0xaf, + 0xb3, 0xa0, 0x7d, 0x9a, 0x76, 0x77, 0x7d, 0x7e, 0x79, 0x1f, 0x8b, 0x82, + 0x8e, 0x81, 0x91, 0x80, 0x8e, 0x85, 0x8d, 0x85, 0x8b, 0x88, 0x8b, 0x82, + 0x80, 0x85, 0x7b, 0x8b, 0x72, 0x8b, 0x7f, 0x93, 0x6a, 0xb5, 0x5f, 0xc4, + 0x78, 0x98, 0x51, 0x98, 0x08, 0xf7, 0xb6, 0xf7, 0xec, 0x8b, 0x96, 0xfb, + 0xb0, 0x8b, 0x6c, 0xfb, 0x07, 0x9b, 0x87, 0x05, 0xf7, 0xf5, 0xf7, 0xf4, + 0x15, 0x67, 0x8b, 0xfb, 0x22, 0x22, 0x31, 0xf4, 0x66, 0x8b, 0xeb, 0xfb, + 0x3d, 0xb9, 0x8b, 0xf7, 0x37, 0xf7, 0x3d, 0x05, 0x0e, 0xf7, 0xd8, 0xf8, + 0xcb, 0x15, 0xb3, 0x57, 0xa1, 0x56, 0x95, 0x46, 0x08, 0x89, 0x8a, 0x05, + 0x7a, 0xab, 0x6e, 0x9c, 0x65, 0x8b, 0x08, 0xfb, 0x1d, 0xfb, 0x26, 0xfb, + 0x35, 0xfb, 0x2b, 0x35, 0xc3, 0x55, 0xe6, 0xf7, 0x31, 0xf7, 0x1c, 0xf7, + 0x40, 0xf7, 0x5a, 0x1f, 0x8b, 0xe8, 0x72, 0xce, 0x4e, 0xd4, 0x08, 0xf0, + 0xb8, 0x6b, 0xa7, 0x28, 0x60, 0x05, 0x63, 0xac, 0x66, 0x9d, 0x5e, 0x95, + 0x08, 0x68, 0x7a, 0x05, 0xb5, 0x7a, 0xa5, 0x7a, 0xae, 0x6a, 0x08, 0xfb, + 0x0f, 0x55, 0xac, 0x6e, 0xf7, 0x09, 0xbe, 0x05, 0x80, 0xfb, 0x27, 0x15, + 0xb6, 0xa7, 0x66, 0x52, 0x1f, 0x8b, 0x42, 0x6a, 0x26, 0x5e, 0x4b, 0x67, + 0x56, 0x65, 0x72, 0x60, 0x8b, 0x5c, 0x8b, 0x6c, 0xb0, 0x8b, 0xc1, 0x8b, + 0xd5, 0xa9, 0xe3, 0xbb, 0xd2, 0xb2, 0xc3, 0xb5, 0xa9, 0xb6, 0x8b, 0x08, + 0x0e, 0xf7, 0x16, 0xfb, 0x52, 0x15, 0x5c, 0x7a, 0x93, 0xa2, 0x1f, 0x8b, + 0x98, 0x9d, 0xda, 0x9e, 0xd4, 0xa4, 0x7e, 0x9d, 0x87, 0xa2, 0x8b, 0x08, + 0xf7, 0x26, 0xf7, 0x2e, 0xf7, 0x3c, 0xf7, 0x32, 0xda, 0x60, 0xba, 0x42, + 0x1f, 0x4c, 0x8b, 0x56, 0x68, 0x5d, 0x42, 0x08, 0x89, 0x8d, 0x05, 0x95, + 0xaa, 0x9c, 0xce, 0xcb, 0xf7, 0x89, 0x08, 0x86, 0x90, 0x05, 0x5a, 0x82, + 0x67, 0x85, 0x48, 0x83, 0x08, 0x7a, 0x07, 0xc6, 0x89, 0x91, 0x88, 0x8b, + 0x75, 0x8b, 0x82, 0x89, 0x80, 0x84, 0x74, 0x89, 0x84, 0x89, 0x85, 0x8a, + 0x85, 0x83, 0x6b, 0x7d, 0x59, 0x5d, 0xfb, 0x3c, 0x08, 0xfb, 0x06, 0xfc, + 0x46, 0x05, 0x81, 0x5d, 0x7d, 0x7f, 0x60, 0x8a, 0x08, 0x7b, 0xf7, 0x61, + 0x9a, 0x07, 0xf7, 0x4f, 0xf8, 0xe0, 0x15, 0xb4, 0xa0, 0x6f, 0x51, 0x1f, + 0x8b, 0x49, 0x6e, 0x35, 0x60, 0x4d, 0x61, 0x50, 0x5b, 0x6c, 0x58, 0x8b, + 0x6e, 0x8b, 0x77, 0x9a, 0x8b, 0xa1, 0x8b, 0xad, 0xaf, 0xf7, 0x17, 0xa8, + 0xd5, 0xa6, 0xd0, 0xc1, 0xb8, 0xc1, 0x8b, 0x08, 0x0e, 0xf6, 0x9a, 0xf8, + 0x24, 0x15, 0x98, 0x8e, 0x92, 0x8c, 0x96, 0x8b, 0xc4, 0x8b, 0x9a, 0x72, + 0xb9, 0xfb, 0x40, 0x9c, 0x4a, 0xa3, 0xfb, 0x09, 0x8b, 0x7a, 0x8b, 0x7b, + 0x85, 0x7b, 0x7c, 0x79, 0x6c, 0x62, 0x77, 0x71, 0x80, 0x7f, 0x76, 0x75, + 0x7f, 0x83, 0x7e, 0x8b, 0x08, 0x85, 0x8b, 0x84, 0x8e, 0x80, 0x93, 0x7c, + 0x97, 0x80, 0x90, 0x80, 0x8b, 0x08, 0x75, 0x7a, 0x7a, 0x75, 0x72, 0xa1, + 0x78, 0xa8, 0x1f, 0xcb, 0x8b, 0xf7, 0x17, 0xf7, 0x2a, 0xf7, 0x00, 0xf7, + 0x5a, 0xcf, 0xf7, 0x0f, 0xa7, 0xd3, 0x8b, 0xbc, 0x08, 0xa9, 0x72, 0xa4, + 0x6d, 0x74, 0x7b, 0x7c, 0x75, 0x1e, 0x8b, 0x7c, 0x93, 0x80, 0x9f, 0x7e, + 0x9e, 0x80, 0x92, 0x82, 0x8b, 0x7d, 0x8b, 0x63, 0x66, 0x3d, 0x36, 0xfb, + 0x21, 0x08, 0x77, 0xf7, 0x08, 0x05, 0x7c, 0xe3, 0x53, 0xf7, 0x39, 0x7c, + 0x8b, 0x08, 0x87, 0x06, 0x8a, 0x8a, 0x87, 0x8b, 0x87, 0x8b, 0x82, 0x8a, + 0x67, 0x85, 0x56, 0x81, 0x86, 0x8a, 0x7e, 0x88, 0x7d, 0x89, 0x08, 0x7a, + 0x07, 0xf7, 0x46, 0xf7, 0x62, 0x15, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, + 0x75, 0xa6, 0xa6, 0xa1, 0xa1, 0xa6, 0xa4, 0x74, 0xa3, 0x72, 0x1f, 0xf7, + 0x5c, 0x16, 0x6f, 0x75, 0x75, 0x71, 0x6f, 0xa1, 0x75, 0xa6, 0xa6, 0xa1, + 0xa1, 0xa6, 0x1f, 0xa4, 0x74, 0xa3, 0x72, 0x1e, 0x0e, 0xf7, 0x9b, 0xf8, + 0x29, 0x15, 0xc0, 0xf7, 0x2c, 0xee, 0xf4, 0xe7, 0x8b, 0xc8, 0x8b, 0xad, + 0x5e, 0x8b, 0x39, 0x08, 0x8b, 0x78, 0x8a, 0x7c, 0x87, 0x77, 0x08, 0x9d, + 0x8b, 0xc0, 0xf7, 0x68, 0x78, 0x8b, 0x05, 0x80, 0x79, 0x7f, 0x80, 0x80, + 0x8b, 0x85, 0x8b, 0x84, 0x8d, 0x7e, 0x90, 0x08, 0x5b, 0x9e, 0x7f, 0x8e, + 0x6d, 0x8b, 0xfb, 0x12, 0x8b, 0xfb, 0x21, 0xfb, 0x0f, 0x4b, 0xfb, 0x39, + 0x08, 0x59, 0x8b, 0x6c, 0x62, 0xce, 0x8b, 0x05, 0x86, 0x79, 0x86, 0x78, + 0x87, 0x70, 0x08, 0x57, 0x8b, 0x6c, 0x62, 0xda, 0x8b, 0x8b, 0x7b, 0x05, + 0xfb, 0x24, 0xdd, 0x28, 0xf7, 0x0a, 0x1e, 0xce, 0x8b, 0xbd, 0xa1, 0xb5, + 0xbb, 0x08, 0x9c, 0xbc, 0x05, 0x5a, 0x4f, 0x5f, 0x72, 0x54, 0x8b, 0x38, + 0x8b, 0x57, 0xd5, 0x8b, 0xf7, 0x0a, 0x8b, 0x96, 0x8b, 0x93, 0x8c, 0x99, + 0x08, 0xf7, 0x22, 0x8b, 0xa9, 0xb4, 0xfb, 0x3b, 0x8b, 0x05, 0x90, 0xa3, + 0x8f, 0x9e, 0x91, 0xa0, 0x08, 0xf7, 0x5e, 0x8b, 0xa9, 0xb4, 0x05, 0xfb, + 0x6f, 0x06, 0x0e, 0x66, 0xf7, 0x74, 0xf7, 0xb3, 0x15, 0x65, 0x8c, 0x80, + 0x8f, 0x8b, 0x9a, 0x8b, 0x94, 0x92, 0xa6, 0x97, 0xb1, 0x08, 0xe1, 0xf7, + 0xa6, 0x05, 0x8e, 0x93, 0x8c, 0x91, 0x8b, 0x8d, 0x08, 0x8d, 0x88, 0x8e, + 0x89, 0x1e, 0x88, 0x06, 0x8b, 0x89, 0x8a, 0x8a, 0x1e, 0x82, 0x8b, 0x78, + 0x87, 0x70, 0x86, 0x75, 0x86, 0x7a, 0x89, 0x6c, 0x86, 0x08, 0x78, 0xad, + 0x07, 0x8e, 0x8c, 0x05, 0x93, 0x8d, 0x95, 0x81, 0x8b, 0x81, 0x8b, 0x87, + 0x8a, 0x86, 0x87, 0x7f, 0x08, 0x31, 0xfb, 0xb1, 0x05, 0x86, 0x7c, 0x7e, + 0x86, 0x5c, 0x86, 0x08, 0x7b, 0xf7, 0x49, 0x9b, 0x07, 0x0e, 0x66, 0xf7, + 0xb2, 0xf7, 0xfa, 0x15, 0x7b, 0x70, 0x7e, 0x84, 0x67, 0x8b, 0x08, 0xfb, + 0x00, 0x8b, 0x89, 0x90, 0xf7, 0x06, 0xf7, 0x02, 0x05, 0xe2, 0xdf, 0x97, + 0x9c, 0x8b, 0xae, 0x8b, 0xc2, 0x59, 0xb9, 0x4e, 0x8b, 0x6a, 0x8b, 0x69, + 0x7f, 0x72, 0x76, 0x78, 0x7b, 0x81, 0x7d, 0x7d, 0x6a, 0x08, 0x98, 0x83, + 0x05, 0xa8, 0xb1, 0xa4, 0x9a, 0xaf, 0x8b, 0xb6, 0x8b, 0xae, 0x6d, 0x8b, + 0x66, 0x8b, 0x6b, 0x6c, 0x5c, 0x4d, 0x4f, 0x08, 0xfb, 0x19, 0xfb, 0x16, + 0x8b, 0x79, 0xf7, 0x7b, 0x8b, 0xac, 0xda, 0x80, 0x93, 0x05, 0x0e, 0x66, + 0xf7, 0x29, 0xf8, 0xf4, 0x15, 0xa8, 0xa6, 0x9d, 0x94, 0xa5, 0x8b, 0xa7, + 0x8b, 0xa1, 0x75, 0x8b, 0x6d, 0x8b, 0x5e, 0x5c, 0x6c, 0x27, 0x79, 0x08, + 0x82, 0x07, 0xa6, 0x8b, 0x92, 0x8b, 0x97, 0x87, 0x08, 0xb5, 0x81, 0xa4, + 0x68, 0x8b, 0x5b, 0x8b, 0x56, 0x67, 0x63, 0x5b, 0x8b, 0x80, 0x8b, 0x7e, + 0x90, 0x78, 0x99, 0x7a, 0x96, 0x7e, 0x91, 0x83, 0x8b, 0x08, 0x7a, 0x7e, + 0x7e, 0x7c, 0x72, 0xa5, 0x7d, 0xba, 0xf7, 0x00, 0xd8, 0xcc, 0xe7, 0x1f, + 0x8b, 0xa5, 0x84, 0x9f, 0x7d, 0x9b, 0x82, 0x94, 0x8a, 0x8c, 0x6f, 0x99, + 0x08, 0x87, 0x8d, 0x05, 0xd8, 0xa6, 0xa3, 0xa0, 0x8b, 0xb2, 0x8b, 0xb6, + 0x62, 0xac, 0x55, 0x8b, 0x5e, 0x8b, 0x63, 0x74, 0x77, 0x65, 0x08, 0x95, + 0x84, 0x05, 0x0e, 0x34, 0xf7, 0x11, 0xf7, 0xca, 0x15, 0x6d, 0x72, 0x71, + 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, 0x71, 0xa5, + 0x6d, 0x1f, 0x0e, 0x87, 0xf7, 0xae, 0xf7, 0x93, 0x15, 0xfb, 0x6f, 0x8b, + 0x7d, 0x4c, 0xf7, 0x70, 0x8b, 0x98, 0xca, 0x05, 0x0e, 0xca, 0xf7, 0x88, + 0xf9, 0x38, 0x15, 0x3b, 0x4c, 0x4c, 0x3b, 0x3c, 0xca, 0x4b, 0xd9, 0xdd, + 0xca, 0xc9, 0xdc, 0xdb, 0x4c, 0xca, 0x3b, 0x1f, 0x69, 0x04, 0xc3, 0xbb, + 0x59, 0x50, 0x4f, 0x5c, 0x5a, 0x51, 0x53, 0x5c, 0xbd, 0xc6, 0xc6, 0xba, + 0xbd, 0xc4, 0x1f, 0x0e, 0xf7, 0xe6, 0xf8, 0xe2, 0xf7, 0x70, 0x15, 0xcd, + 0xfc, 0x8c, 0x49, 0xf8, 0x8c, 0x07, 0x0e, 0xf7, 0xe6, 0xf7, 0xb5, 0xf7, + 0x91, 0x15, 0xfb, 0x58, 0xfb, 0x59, 0xbb, 0x5b, 0xf7, 0x58, 0xf7, 0x59, + 0xf7, 0x59, 0xfb, 0x59, 0xbb, 0xbb, 0xfb, 0x59, 0xf7, 0x59, 0xf7, 0x59, + 0xf7, 0x58, 0x5b, 0xbb, 0xfb, 0x59, 0xfb, 0x59, 0xfb, 0x58, 0xf7, 0x59, + 0x5b, 0x5b, 0xf7, 0x58, 0xfb, 0x58, 0x05, 0x0e, 0xf7, 0xe6, 0xf8, 0xe2, + 0xf7, 0x70, 0x15, 0xcd, 0xfc, 0x8c, 0x49, 0xf8, 0x8c, 0x07, 0xfb, 0x90, + 0xfb, 0x0c, 0x15, 0x6d, 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa7, 0xab, + 0xa5, 0xa3, 0xa9, 0xaa, 0x71, 0xa5, 0x6d, 0x1f, 0xf8, 0x35, 0x04, 0x6d, + 0x72, 0x71, 0x6c, 0x6e, 0xa4, 0x72, 0xa8, 0xaa, 0xa5, 0xa4, 0xa8, 0xaa, + 0x71, 0xa5, 0x6d, 0x1f, 0x0e, 0xf9, 0x17, 0xf7, 0x82, 0xf9, 0x0d, 0x15, + 0xbd, 0x06, 0xae, 0x8b, 0x9d, 0x78, 0x99, 0x5a, 0x08, 0x9f, 0xe3, 0xfb, + 0xed, 0x33, 0x9f, 0x06, 0x98, 0xbc, 0x9e, 0x9e, 0xaf, 0x8b, 0x08, 0xbc, + 0xfb, 0xca, 0x06, 0x8b, 0x5b, 0x8b, 0x8b, 0x59, 0x85, 0x08, 0x77, 0xf7, + 0x3f, 0x9f, 0x07, 0x59, 0x91, 0x8b, 0x8b, 0x8b, 0xbb, 0x08, 0xf7, 0xca, + 0x07, 0xf8, 0x3f, 0xfc, 0x16, 0x15, 0x96, 0x8b, 0xf7, 0x2e, 0xf7, 0xcc, + 0x8b, 0xfb, 0x80, 0x05, 0x8b, 0x5b, 0x8b, 0x8b, 0x5a, 0x85, 0x08, 0x77, + 0xf7, 0x3e, 0x9f, 0x07, 0x59, 0x91, 0x8b, 0x8b, 0x8b, 0xbb, 0x08, 0xf7, + 0x93, 0x07, 0x8b, 0xb2, 0x98, 0x98, 0xb6, 0x8e, 0x08, 0x9f, 0x24, 0x07, + 0xfb, 0x34, 0xfb, 0xc9, 0xfb, 0x2e, 0xf7, 0xc9, 0xfb, 0x0d, 0x8b, 0x8b, + 0x77, 0x05, 0xa9, 0x8a, 0xa5, 0x78, 0x98, 0x6d, 0x08, 0xfb, 0x8d, 0x07, + 0x8b, 0x5b, 0x81, 0x7f, 0x61, 0x86, 0x08, 0x77, 0xf7, 0x17, 0x9f, 0x07, + 0x60, 0x90, 0x81, 0x97, 0x8b, 0xbb, 0x08, 0x8b, 0xf7, 0x73, 0xf7, 0x2b, + 0xfb, 0xca, 0x05, 0x0e, 0xf7, 0xe6, 0xe1, 0x16, 0xf8, 0x8c, 0xcd, 0xfc, + 0x8c, 0x49, 0x06, 0xf7, 0x6f, 0xf7, 0xf0, 0x15, 0xfb, 0x6f, 0x49, 0xf7, + 0x6f, 0xfb, 0x34, 0xcd, 0xf7, 0x34, 0xf7, 0x6f, 0xcd, 0xfb, 0x6f, 0xf7, + 0x70, 0x49, 0xfb, 0x70, 0x06, 0x0e, 0xf8, 0x31, 0xf9, 0x0f, 0xf9, 0x38, + 0x15, 0x58, 0x8b, 0xfc, 0x5b, 0xfd, 0x42, 0xbe, 0x8b, 0x05, 0xf8, 0x5b, + 0xf9, 0x42, 0x05, 0xfc, 0x38, 0xfc, 0x19, 0x15, 0x65, 0x8c, 0x80, 0x8f, + 0x8b, 0x9a, 0x8b, 0x93, 0x92, 0xa6, 0x97, 0xb2, 0x08, 0xe1, 0xf7, 0xa6, + 0x05, 0x8e, 0x98, 0x8b, 0x8b, 0x8b, 0x8e, 0x08, 0x8e, 0x89, 0x8d, 0x88, + 0x1e, 0x89, 0x06, 0x8b, 0x89, 0x8a, 0x8a, 0x1e, 0x81, 0x8b, 0x79, 0x87, + 0x70, 0x86, 0x74, 0x86, 0x7a, 0x89, 0x6d, 0x86, 0x08, 0x78, 0xaa, 0x07, + 0x91, 0x8c, 0x05, 0x94, 0x8d, 0x94, 0x82, 0x8b, 0x7f, 0x8b, 0x86, 0x8b, + 0x8b, 0x86, 0x7c, 0x08, 0x31, 0xfb, 0xb1, 0x05, 0x86, 0x7c, 0x7e, 0x86, + 0x5c, 0x86, 0x08, 0x7b, 0xf7, 0x49, 0x9b, 0x07, 0xf8, 0x84, 0xfb, 0x5c, + 0x15, 0x7b, 0x70, 0x7e, 0x84, 0x67, 0x8b, 0x08, 0xfb, 0x00, 0x8b, 0x89, + 0x90, 0xf7, 0x06, 0xf7, 0x02, 0x05, 0xe2, 0xdf, 0x97, 0x9c, 0x8b, 0xae, + 0x8b, 0xc2, 0x59, 0xba, 0x4f, 0x8b, 0x6a, 0x8b, 0x69, 0x7f, 0x71, 0x75, + 0x78, 0x7c, 0x81, 0x7c, 0x7d, 0x6a, 0x08, 0x98, 0x83, 0x05, 0xa8, 0xb1, + 0xa4, 0x9a, 0xaf, 0x8b, 0xb6, 0x8b, 0xae, 0x6d, 0x8b, 0x66, 0x8b, 0x6b, + 0x6b, 0x5c, 0x4e, 0x4f, 0x08, 0xfb, 0x19, 0xfb, 0x16, 0x8b, 0x79, 0xf7, + 0x7b, 0x8b, 0xac, 0xda, 0x05, 0x80, 0x93, 0x05, 0x0e, 0xf8, 0x31, 0xf9, + 0x5c, 0xf7, 0x27, 0x15, 0x54, 0x8b, 0xda, 0xf7, 0x97, 0x67, 0x8b, 0xfb, + 0xa3, 0xfb, 0x97, 0x7e, 0x61, 0xf7, 0x3c, 0x8b, 0x6b, 0x22, 0xca, 0x8b, + 0xa9, 0xf3, 0xc5, 0x8b, 0x05, 0x94, 0xb6, 0x05, 0x50, 0xf7, 0x4e, 0x15, + 0x4f, 0xfb, 0x4e, 0xfb, 0x15, 0x8b, 0xf7, 0x51, 0xf7, 0x4e, 0x05, 0x87, + 0xf7, 0xeb, 0x15, 0x58, 0x8b, 0xfc, 0x5b, 0xfd, 0x42, 0xbe, 0x8b, 0x05, + 0xf8, 0x5b, 0xf9, 0x42, 0x05, 0xfc, 0x47, 0xfc, 0x19, 0x15, 0x65, 0x8c, + 0x80, 0x8f, 0x8b, 0x9a, 0x8b, 0x94, 0x92, 0xa6, 0x97, 0xb1, 0x08, 0xe1, + 0xf7, 0xa6, 0x05, 0x8d, 0x90, 0x8c, 0x92, 0x8b, 0x8f, 0x8b, 0x8e, 0x89, + 0x8d, 0x88, 0x8b, 0x86, 0x8b, 0x6f, 0x86, 0x70, 0x86, 0x08, 0x45, 0x7f, + 0x8b, 0x78, 0xa9, 0x8b, 0x92, 0x8c, 0x05, 0x94, 0x8c, 0x94, 0x82, 0x8b, + 0x81, 0x8b, 0x87, 0x8a, 0x86, 0x87, 0x7f, 0x08, 0x31, 0xfb, 0xb1, 0x05, + 0x86, 0x7c, 0x7e, 0x86, 0x5c, 0x86, 0x08, 0x7b, 0xf7, 0x49, 0x9b, 0x07, + 0x0e, 0xf8, 0x31, 0xf9, 0x5c, 0xf7, 0x27, 0x15, 0x54, 0x8b, 0xda, 0xf7, + 0x97, 0x67, 0x8b, 0xfb, 0xa3, 0xfb, 0x97, 0x7e, 0x61, 0xf7, 0x3c, 0x8b, + 0x6b, 0x22, 0xca, 0x8b, 0xa9, 0xf3, 0xc5, 0x8b, 0x05, 0x94, 0xb6, 0x05, + 0x50, 0xf7, 0x4e, 0x15, 0x4f, 0xfb, 0x4e, 0xfb, 0x15, 0x8b, 0xf7, 0x51, + 0xf7, 0x4e, 0x05, 0x88, 0xf7, 0xeb, 0x15, 0x58, 0x8b, 0xfc, 0x5b, 0xfd, + 0x42, 0xbe, 0x8b, 0x05, 0xf8, 0x5b, 0xf9, 0x42, 0x05, 0xfc, 0x9d, 0x47, + 0x15, 0xa8, 0xa6, 0x9d, 0x94, 0xa5, 0x8b, 0xa7, 0x8b, 0xa1, 0x75, 0x8b, + 0x6d, 0x8b, 0x5e, 0x5c, 0x6c, 0x27, 0x79, 0x08, 0x82, 0x07, 0xa6, 0x8b, + 0x92, 0x8b, 0x97, 0x87, 0x08, 0xb5, 0x81, 0xa4, 0x68, 0x8b, 0x5b, 0x8b, + 0x56, 0x67, 0x63, 0x5b, 0x8b, 0x80, 0x8b, 0x7e, 0x90, 0x78, 0x99, 0x7a, + 0x96, 0x7e, 0x91, 0x83, 0x8b, 0x08, 0x7a, 0x7e, 0x7e, 0x7c, 0x72, 0xa5, + 0x7d, 0xba, 0xf7, 0x00, 0xd8, 0xcc, 0xe7, 0x1f, 0x8b, 0xa5, 0x84, 0x9f, + 0x7d, 0x9b, 0x82, 0x94, 0x8a, 0x8c, 0x6f, 0x99, 0x08, 0x87, 0x8d, 0x05, + 0xd8, 0xa6, 0xa3, 0xa0, 0x8b, 0xb2, 0x8b, 0xb6, 0x62, 0xac, 0x55, 0x8b, + 0x5e, 0x8b, 0x63, 0x74, 0x77, 0x65, 0x08, 0x95, 0x84, 0x05, 0x0e, 0xf8, + 0x3b, 0xf8, 0xa5, 0xf7, 0x84, 0x15, 0x6f, 0x50, 0x68, 0x72, 0x52, 0x8b, + 0x08, 0x31, 0x58, 0xca, 0xf7, 0x04, 0xf7, 0x03, 0xbc, 0xc8, 0xe5, 0x1f, + 0xc8, 0x8b, 0xae, 0x6e, 0x95, 0x50, 0x08, 0x9b, 0xd0, 0x06, 0x8b, 0x94, + 0x83, 0x93, 0x7e, 0x8f, 0x08, 0x87, 0x8c, 0x86, 0x8d, 0x05, 0x6b, 0x95, + 0x70, 0x90, 0x6c, 0x8b, 0x08, 0xfb, 0x15, 0x32, 0x39, 0xfb, 0x0a, 0xfb, + 0x06, 0xdc, 0x42, 0xf7, 0x12, 0x1f, 0xb0, 0x8b, 0xa5, 0x8f, 0xbd, 0x9a, + 0x99, 0x8f, 0x8e, 0x8d, 0x8d, 0x96, 0x08, 0x9a, 0xcf, 0x7b, 0x8b, 0x05, + 0xfb, 0x29, 0xf8, 0x3e, 0x15, 0xfb, 0x50, 0xfb, 0x2b, 0xfb, 0x2d, 0xfb, + 0x52, 0xfb, 0x52, 0xf7, 0x2b, 0xfb, 0x2b, 0xf7, 0x52, 0xf7, 0x4e, 0xf7, + 0x2b, 0xf7, 0x2b, 0xf7, 0x4d, 0xf7, 0x59, 0xfb, 0x27, 0xf7, 0x2b, 0xfb, + 0x54, 0x1f, 0x8c, 0x61, 0x15, 0xf7, 0x31, 0xf7, 0x12, 0xfb, 0x1c, 0xfb, + 0x3d, 0xfb, 0x33, 0xfb, 0x16, 0xfb, 0x1c, 0xfb, 0x2d, 0xfb, 0x2f, 0xfb, + 0x16, 0xf7, 0x1c, 0xf7, 0x37, 0xf7, 0x38, 0xf7, 0x16, 0xf7, 0x1d, 0xf7, + 0x2f, 0x1f, 0x0e, 0xf8, 0x3b, 0xf7, 0x71, 0xf8, 0x84, 0x15, 0xbb, 0x86, + 0x8b, 0x8b, 0x8b, 0x60, 0x08, 0xfb, 0x83, 0x07, 0x8b, 0x60, 0x8b, 0x8b, + 0x5b, 0x86, 0x08, 0x7c, 0xf7, 0x34, 0x9a, 0x07, 0x5b, 0x90, 0x8b, 0x8b, + 0x8b, 0xb6, 0x08, 0xed, 0xba, 0x07, 0xa3, 0x67, 0x95, 0x7b, 0x9c, 0x6d, + 0xae, 0x4f, 0x9c, 0x78, 0x9c, 0x8b, 0x08, 0xca, 0x94, 0x06, 0x77, 0x9a, + 0x73, 0xa6, 0x6c, 0xb5, 0x08, 0x52, 0xd9, 0x05, 0xbf, 0xa0, 0xa6, 0xae, + 0x8b, 0xba, 0x08, 0xc2, 0x5f, 0xaf, 0x45, 0x1e, 0xfb, 0x43, 0x7c, 0x06, + 0xf7, 0x04, 0x87, 0x15, 0xb4, 0x06, 0xb8, 0xa3, 0x70, 0x58, 0x52, 0x73, + 0x6b, 0x5f, 0x1f, 0x61, 0xf7, 0x3b, 0x06, 0xba, 0xf7, 0x42, 0x15, 0xfb, + 0x50, 0xfb, 0x2b, 0xfb, 0x2d, 0xfb, 0x52, 0xfb, 0x52, 0xf7, 0x2b, 0xfb, + 0x2b, 0xf7, 0x52, 0xf7, 0x4e, 0xf7, 0x2b, 0xf7, 0x2b, 0xf7, 0x4d, 0xf7, + 0x59, 0xfb, 0x27, 0xf7, 0x2b, 0xfb, 0x54, 0x1f, 0x8c, 0x61, 0x15, 0xf7, + 0x31, 0xf7, 0x12, 0xfb, 0x1c, 0xfb, 0x3d, 0xfb, 0x33, 0xfb, 0x16, 0xfb, + 0x1c, 0xfb, 0x2d, 0xfb, 0x2f, 0xfb, 0x16, 0xf7, 0x1c, 0xf7, 0x37, 0xf7, + 0x38, 0xf7, 0x16, 0xf7, 0x1d, 0xf7, 0x2f, 0x1f, 0x0e, 0x34, 0x0e, 0xf7, + 0xe6, 0xf8, 0xa0, 0xf7, 0x00, 0x15, 0xcd, 0xf7, 0xaa, 0xfc, 0x8c, 0x49, + 0xf8, 0x4a, 0xfb, 0x68, 0x06, 0x0e, 0x4d, 0xf4, 0x79, 0x15, 0xcd, 0xf7, + 0xa7, 0x49, 0xfb, 0xa7, 0x06, 0xf8, 0x2d, 0x04, 0xcd, 0xf7, 0xa7, 0x49, + 0xfb, 0xa7, 0x06, 0x0e, 0xf8, 0x85, 0xf8, 0x40, 0x15, 0x33, 0x8b, 0x42, + 0xfb, 0xcd, 0x05, 0x68, 0x5e, 0x5f, 0x72, 0x60, 0x8b, 0x61, 0x8b, 0x70, + 0xa6, 0x8b, 0xb5, 0x8b, 0x94, 0x8c, 0x99, 0x8d, 0x92, 0x08, 0xce, 0xf7, + 0xb0, 0x33, 0x8b, 0x36, 0xfc, 0x0a, 0x05, 0x85, 0x70, 0x81, 0x6f, 0x79, + 0x5e, 0x6d, 0x51, 0x83, 0x72, 0x8b, 0x68, 0x08, 0x6d, 0x96, 0x7c, 0xa2, + 0xb6, 0xa7, 0xc3, 0xe2, 0x1e, 0x8b, 0x94, 0x8b, 0x9c, 0x8a, 0x9b, 0x8a, + 0x9d, 0x8b, 0x98, 0x8b, 0x96, 0x8b, 0x9b, 0x8c, 0x96, 0x8c, 0xa0, 0x9e, + 0x57, 0xaa, 0x73, 0xc0, 0x8b, 0xc0, 0x8b, 0xbb, 0xa7, 0xc0, 0xc9, 0x88, + 0x7d, 0x8a, 0x84, 0x8b, 0x81, 0x08, 0x64, 0x9e, 0x77, 0xb1, 0x1e, 0xb2, + 0x8b, 0xa5, 0x99, 0xb5, 0xb6, 0x08, 0x8e, 0x94, 0x05, 0x72, 0x78, 0x7d, + 0x84, 0x7a, 0x8b, 0x7a, 0x8b, 0x82, 0x95, 0x8b, 0x9d, 0x8b, 0x95, 0x8b, + 0x8d, 0x91, 0xa1, 0x08, 0xd9, 0xf7, 0xe4, 0x05, 0x0e, 0xf8, 0x88, 0x14, + 0xf7, 0xe5, 0x15, 0x79, 0x9d, 0xf8, 0x44, 0x94, 0xf7, 0x68, 0x98, 0x06, + 0x1e, 0x0a, 0x03, 0x96, 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xa2, + 0x0a, 0x9e, 0x8f, 0x94, 0x91, 0x90, 0x8f, 0x91, 0x9b, 0x0c, 0x0c, 0xd9, + 0x0b, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00, 0x00 +}; +const unsigned int fonts_NimbusRomNo9L_ReguItal_cff_len = 27632; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusSanL-Bold.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusSanL-Bold.cff.c new file mode 100644 index 00000000000..13ccc3cb273 --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusSanL-Bold.cff.c @@ -0,0 +1,1460 @@ +const unsigned char fonts_NimbusSanL_Bold_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x10, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x53, 0x61, 0x6e, 0x4c, 0x2d, 0x42, 0x6f, 0x6c, 0x64, + 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x39, 0xf8, 0x1f, 0x00, 0xf8, 0x20, + 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, 0x14, 0x04, 0xfb, 0x2f, + 0x0c, 0x03, 0xd0, 0x0c, 0x04, 0x1d, 0x00, 0x4c, 0x9c, 0xe8, 0x0d, 0xfb, + 0x41, 0xfb, 0x7e, 0xfa, 0x7f, 0xfa, 0x49, 0x05, 0x1c, 0x00, 0xeb, 0x0f, + 0x1c, 0x00, 0x00, 0x10, 0x1c, 0x02, 0xbc, 0x11, 0x1c, 0x00, 0x30, 0x1c, + 0x44, 0x11, 0x12, 0x00, 0x08, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, + 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x5f, 0x00, 0x71, 0x00, 0x7e, + 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, + 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, + 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, + 0x6d, 0x62, 0x75, 0x73, 0x20, 0x53, 0x61, 0x6e, 0x73, 0x20, 0x4c, 0x20, + 0x42, 0x6f, 0x6c, 0x64, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x53, + 0x61, 0x6e, 0x73, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, + 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, + 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, + 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, + 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, + 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, + 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, + 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, + 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, + 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, + 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, + 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, + 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, + 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, + 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, + 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, + 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, + 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, + 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, + 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, + 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, + 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, + 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8c, + 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, + 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, 0xae, + 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, 0xb4, + 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, 0xb9, + 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, 0xbc, + 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, 0xc2, + 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xc8, + 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd1, + 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd6, + 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, 0xd9, + 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xdf, + 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, 0x87, + 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, 0xa1, + 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9b, + 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, 0x97, + 0x00, 0xa0, 0x00, 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x2c, 0x00, 0x59, 0x00, 0xb4, 0x01, 0x41, 0x01, 0xa8, 0x02, + 0x47, 0x02, 0x6d, 0x02, 0xa1, 0x02, 0xd5, 0x03, 0x02, 0x03, 0x22, 0x03, + 0x49, 0x03, 0x5a, 0x03, 0x6b, 0x03, 0x80, 0x03, 0xf1, 0x04, 0x0b, 0x04, + 0x59, 0x04, 0xcb, 0x04, 0xfe, 0x05, 0x4f, 0x05, 0xbb, 0x05, 0xe8, 0x06, + 0x57, 0x06, 0xbe, 0x06, 0xdb, 0x07, 0x11, 0x07, 0x32, 0x07, 0x4e, 0x07, + 0x6d, 0x07, 0xc1, 0x08, 0xa5, 0x08, 0xd5, 0x09, 0x32, 0x09, 0x89, 0x09, + 0xcc, 0x09, 0xec, 0x0a, 0x08, 0x0a, 0x6a, 0x0a, 0x8c, 0x0a, 0x9d, 0x0a, + 0xcd, 0x0a, 0xfc, 0x0b, 0x10, 0x0b, 0x44, 0x0b, 0x67, 0x0b, 0xc0, 0x0b, + 0xf4, 0x0c, 0x63, 0x0c, 0xd6, 0x0d, 0x47, 0x0d, 0x5f, 0x0d, 0x97, 0x0d, + 0xb6, 0x0d, 0xec, 0x0e, 0x20, 0x0e, 0x47, 0x0e, 0x6d, 0x0e, 0x84, 0x0e, + 0x98, 0x0e, 0xae, 0x0e, 0xcf, 0x0e, 0xdc, 0x0f, 0x03, 0x0f, 0x87, 0x0f, + 0xd1, 0x10, 0x1b, 0x10, 0x66, 0x10, 0xc9, 0x10, 0xfb, 0x11, 0x63, 0x11, + 0xa1, 0x11, 0xbe, 0x11, 0xf5, 0x12, 0x1f, 0x12, 0x30, 0x12, 0x7d, 0x12, + 0xad, 0x12, 0xe5, 0x13, 0x31, 0x13, 0x7e, 0x13, 0xad, 0x14, 0x25, 0x14, + 0x59, 0x14, 0x88, 0x14, 0xa6, 0x14, 0xd5, 0x15, 0x04, 0x15, 0x47, 0x15, + 0x6e, 0x15, 0xc9, 0x15, 0xd8, 0x16, 0x32, 0x16, 0x83, 0x16, 0xa7, 0x17, + 0x03, 0x17, 0xad, 0x17, 0xc2, 0x18, 0x05, 0x18, 0x6b, 0x19, 0x2a, 0x19, + 0x95, 0x19, 0xae, 0x19, 0xf7, 0x1a, 0x2b, 0x1a, 0x48, 0x1a, 0x66, 0x1a, + 0xb3, 0x1a, 0xf3, 0x1b, 0x00, 0x1b, 0x1f, 0x1b, 0x4f, 0x1b, 0x5f, 0x1b, + 0x8b, 0x1b, 0xa4, 0x1b, 0xca, 0x1c, 0x12, 0x1c, 0x5a, 0x1c, 0x8f, 0x1c, + 0xb8, 0x1d, 0x45, 0x1d, 0x99, 0x1d, 0xad, 0x1d, 0xc2, 0x1d, 0xdc, 0x1e, + 0x22, 0x1e, 0x31, 0x1e, 0x56, 0x1e, 0x67, 0x1e, 0x84, 0x1e, 0xb0, 0x1e, + 0xef, 0x1f, 0x14, 0x1f, 0x44, 0x1f, 0x5e, 0x1f, 0x6d, 0x1f, 0xac, 0x20, + 0x2e, 0x20, 0x5c, 0x20, 0xe2, 0x21, 0x45, 0x21, 0x7e, 0x22, 0x3d, 0x22, + 0x4e, 0x22, 0x73, 0x22, 0xee, 0x23, 0x8d, 0x23, 0xff, 0x24, 0x49, 0x24, + 0x8a, 0x24, 0xcc, 0x25, 0x13, 0x25, 0x85, 0x25, 0xdd, 0x26, 0x70, 0x26, + 0xca, 0x27, 0x05, 0x27, 0x37, 0x27, 0x68, 0x27, 0x9e, 0x27, 0xcb, 0x27, + 0xed, 0x28, 0x10, 0x28, 0x38, 0x28, 0x9e, 0x29, 0x10, 0x29, 0x7b, 0x29, + 0xe6, 0x2a, 0x55, 0x2a, 0xf2, 0x2b, 0x7a, 0x2b, 0xce, 0x2c, 0x16, 0x2c, + 0x60, 0x2c, 0xaf, 0x2c, 0xe7, 0x2d, 0x23, 0x2d, 0x62, 0x2d, 0xa6, 0x2e, + 0x45, 0x2e, 0xda, 0x2f, 0x70, 0x30, 0x0b, 0x30, 0xd1, 0x31, 0x7e, 0x32, + 0x07, 0x32, 0x83, 0x32, 0xf8, 0x33, 0x6c, 0x33, 0xe5, 0x34, 0x11, 0x34, + 0x33, 0x34, 0x56, 0x34, 0x7e, 0x34, 0xf1, 0x35, 0x44, 0x35, 0x8e, 0x35, + 0xd8, 0x36, 0x26, 0x36, 0xa2, 0x37, 0x31, 0x37, 0x7b, 0x37, 0xbb, 0x37, + 0xfc, 0x38, 0x42, 0x38, 0x96, 0x38, 0xd3, 0x39, 0x49, 0x39, 0x8f, 0x39, + 0xec, 0x3a, 0x6e, 0x3a, 0x87, 0x3a, 0xd8, 0x3b, 0x3f, 0x3b, 0x4f, 0x3b, + 0x60, 0x3b, 0x8c, 0x3b, 0x9c, 0x3b, 0xcc, 0x3b, 0xf6, 0x3c, 0x36, 0x3c, + 0x61, 0x3c, 0xda, 0x3d, 0x30, 0x3d, 0xd4, 0x3e, 0x62, 0x3e, 0xfd, 0x3f, + 0x00, 0x3f, 0x11, 0x3f, 0x2a, 0x3f, 0x7f, 0xfc, 0x1d, 0x0e, 0xfc, 0x1d, + 0x0e, 0xfb, 0xe6, 0xf7, 0x9a, 0xf9, 0x6a, 0x15, 0xfb, 0x2a, 0xfb, 0x66, + 0x06, 0xb4, 0xfb, 0xc9, 0xce, 0x8b, 0xb5, 0xf7, 0xc9, 0x8b, 0xf7, 0x66, + 0x05, 0xfc, 0xd8, 0x04, 0xfb, 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, 0x26, + 0x06, 0x0e, 0xfb, 0x59, 0xf7, 0x50, 0xf9, 0x6d, 0x15, 0xfb, 0x1e, 0xfb, + 0x16, 0x06, 0xb3, 0xfb, 0x15, 0xc3, 0x8b, 0xb5, 0xf7, 0x15, 0x8b, 0xf7, + 0x16, 0x05, 0xf7, 0x80, 0x16, 0xfb, 0x1e, 0xfb, 0x16, 0x06, 0xb3, 0xfb, + 0x15, 0xc3, 0x8b, 0xb5, 0xf7, 0x15, 0x8b, 0xf7, 0x16, 0x05, 0x0e, 0xf7, + 0x26, 0x6b, 0x15, 0xb3, 0xf7, 0x60, 0xf2, 0x8b, 0x63, 0xfb, 0x60, 0xf4, + 0x8b, 0xb3, 0xf7, 0x60, 0xf7, 0x0b, 0x8b, 0x8b, 0xee, 0x27, 0x8b, 0xaa, + 0xf7, 0x2d, 0xf7, 0x01, 0x8b, 0x8b, 0xee, 0x31, 0x8b, 0xad, 0xf7, 0x42, + 0x22, 0x8b, 0x69, 0xfb, 0x42, 0x05, 0x24, 0x8b, 0xad, 0xf7, 0x42, 0x22, + 0x8b, 0x69, 0xfb, 0x42, 0xfb, 0x0b, 0x8b, 0x8b, 0x28, 0xee, 0x8b, 0x6d, + 0xfb, 0x2d, 0x2a, 0x8b, 0x8b, 0x28, 0xd8, 0x8b, 0x63, 0xfb, 0x60, 0xf5, + 0x8b, 0x05, 0xc6, 0xf7, 0xc3, 0x15, 0xa9, 0xf7, 0x2d, 0xf2, 0x8b, 0x6d, + 0xfb, 0x2d, 0x24, 0x8b, 0x05, 0x0e, 0xf8, 0x99, 0xf8, 0x86, 0x15, 0x89, + 0xf7, 0x11, 0x3d, 0xda, 0xfb, 0x12, 0x92, 0x08, 0xc1, 0x47, 0x55, 0x07, + 0xfb, 0x15, 0x7f, 0x40, 0x42, 0x8b, 0xfb, 0x04, 0x8b, 0xfb, 0x03, 0xd0, + 0x44, 0xf7, 0x1b, 0x6c, 0x08, 0xfb, 0x69, 0x07, 0x53, 0x95, 0x6c, 0xb4, + 0x88, 0xd1, 0x08, 0xfb, 0x17, 0x82, 0x06, 0x8b, 0x42, 0xa9, 0x4f, 0xc3, + 0x63, 0xb1, 0x70, 0xb0, 0x7e, 0xc7, 0x85, 0x08, 0x22, 0xcf, 0xf4, 0x07, + 0xc2, 0x91, 0xb5, 0x99, 0xac, 0xa0, 0xc1, 0xae, 0xab, 0xcc, 0x8b, 0xd6, + 0x8b, 0xf7, 0x02, 0x4e, 0xc6, 0xfb, 0x2f, 0xb6, 0x08, 0xf7, 0x5d, 0x07, + 0xbe, 0x84, 0xa8, 0x61, 0x89, 0x4e, 0x08, 0xf7, 0x14, 0x06, 0xfb, 0xa6, + 0x44, 0x15, 0x53, 0x9d, 0x72, 0xa6, 0x8b, 0xb7, 0x8b, 0xbe, 0xa5, 0xa9, + 0xc2, 0x96, 0x08, 0xfb, 0x49, 0x07, 0xcf, 0xfb, 0x25, 0x15, 0xc3, 0x7a, + 0xa7, 0x69, 0x8b, 0x5b, 0x8b, 0x59, 0x6f, 0x6a, 0x53, 0x7d, 0x08, 0xf7, + 0x58, 0x07, 0x0e, 0xf7, 0x6e, 0xf7, 0x62, 0xf9, 0x51, 0x15, 0x26, 0x38, + 0x39, 0x27, 0x27, 0xde, 0x39, 0xf0, 0xef, 0xdf, 0xdd, 0xed, 0x1f, 0xf2, + 0x3a, 0xdc, 0x24, 0x1e, 0x28, 0x04, 0xba, 0xb1, 0x66, 0x5c, 0x5e, 0x64, + 0x65, 0x5d, 0x5c, 0x65, 0xb1, 0xb9, 0xb8, 0xb1, 0xb1, 0xba, 0x1f, 0xf8, + 0x24, 0xf6, 0x15, 0xfc, 0x20, 0xfd, 0x6d, 0xd8, 0x8b, 0xf8, 0x1f, 0xf9, + 0x6d, 0x3f, 0x8b, 0x05, 0xd4, 0xfb, 0xf9, 0x15, 0x26, 0x38, 0x39, 0x27, + 0x26, 0xde, 0x39, 0xf0, 0xef, 0xdf, 0xdd, 0xed, 0x1f, 0xf3, 0x3a, 0xdc, + 0x24, 0x1e, 0x28, 0x04, 0xba, 0xb1, 0x65, 0x5c, 0x5e, 0x64, 0x65, 0x5d, + 0x5c, 0x65, 0xb1, 0xb9, 0xb9, 0xb1, 0xb1, 0xba, 0x1f, 0x0e, 0xbe, 0xf8, + 0xa2, 0xf8, 0x09, 0x15, 0x81, 0x07, 0x8b, 0x60, 0x83, 0x6d, 0x75, 0x61, + 0x08, 0xfb, 0x08, 0xf7, 0x24, 0x05, 0xe4, 0xc8, 0xa7, 0xb6, 0x8b, 0xd3, + 0x08, 0xe8, 0x44, 0xc9, 0x20, 0x20, 0x39, 0x42, 0x2d, 0x1e, 0x8b, 0x66, + 0x99, 0x67, 0xa7, 0x6a, 0x08, 0xa7, 0x69, 0x05, 0x8d, 0x89, 0x8f, 0x86, + 0x91, 0x83, 0x08, 0xfb, 0x09, 0x4e, 0x63, 0x56, 0x8b, 0x2d, 0x8b, 0xfb, + 0x16, 0xea, 0x35, 0xf7, 0x22, 0x8b, 0xcf, 0x8b, 0xb9, 0x9d, 0xdc, 0xc8, + 0x08, 0xb9, 0x53, 0xf7, 0x35, 0x8b, 0xfb, 0x0f, 0xf7, 0x2e, 0x05, 0xb3, + 0xb9, 0xa5, 0xdc, 0x8d, 0xd7, 0x08, 0x8b, 0x90, 0x8b, 0x96, 0x05, 0xfb, + 0x05, 0x06, 0xfb, 0x8c, 0x55, 0x15, 0xf7, 0x1c, 0xfb, 0x3f, 0x05, 0x5c, + 0x67, 0x61, 0x78, 0x6c, 0x8b, 0x55, 0x8b, 0x57, 0xc4, 0x8b, 0xc7, 0x8b, + 0xac, 0x9b, 0xa8, 0xa6, 0x9d, 0x08, 0xba, 0xa8, 0x05, 0xb2, 0xf7, 0x2b, + 0x15, 0x59, 0xca, 0x86, 0x93, 0x8b, 0xa4, 0x08, 0xa7, 0xa3, 0x9f, 0xad, + 0xaf, 0xa0, 0x76, 0x66, 0x1e, 0x8b, 0x68, 0x77, 0x6e, 0x63, 0x75, 0x08, + 0x0e, 0xfc, 0x1d, 0xcd, 0xf9, 0x6d, 0x15, 0xfb, 0x11, 0xdb, 0x07, 0x8d, + 0x59, 0x71, 0x6e, 0x53, 0x81, 0x08, 0x5d, 0x07, 0xad, 0x8d, 0xab, 0x97, + 0xa3, 0x9f, 0xab, 0xa6, 0x98, 0xac, 0x8b, 0xc4, 0x08, 0xf7, 0x01, 0xfb, + 0x1b, 0x07, 0x0e, 0xfb, 0xe6, 0xf7, 0x5f, 0xf9, 0x6d, 0x15, 0xfb, 0x07, + 0xfb, 0x41, 0x5b, 0xfb, 0x1e, 0x8b, 0xfb, 0x2d, 0x8b, 0xfb, 0x2e, 0xbb, + 0xfb, 0x1e, 0xf7, 0x07, 0xfb, 0x41, 0x08, 0xef, 0x06, 0x21, 0xf7, 0x62, + 0x69, 0xf7, 0x04, 0x8b, 0xf7, 0x27, 0x8b, 0xf7, 0x26, 0xad, 0xf7, 0x06, + 0xf5, 0xf7, 0x60, 0x08, 0x27, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0x0e, 0xfb, + 0x5c, 0x15, 0xf7, 0x07, 0xf7, 0x41, 0xbb, 0xf7, 0x1e, 0x8b, 0xf7, 0x2d, + 0x8b, 0xf7, 0x2e, 0x5b, 0xf7, 0x1e, 0xfb, 0x07, 0xf7, 0x41, 0x08, 0x27, + 0x06, 0xf5, 0xfb, 0x62, 0xad, 0xfb, 0x04, 0x8b, 0xfb, 0x27, 0x8b, 0xfb, + 0x26, 0x69, 0xfb, 0x06, 0x21, 0xfb, 0x60, 0x08, 0xef, 0x06, 0x0e, 0xfb, + 0xae, 0xf7, 0x18, 0xf8, 0xb4, 0x15, 0x48, 0x2d, 0xc5, 0x60, 0xce, 0xe9, + 0xce, 0x2d, 0xc5, 0xb6, 0x48, 0xe9, 0xf7, 0x01, 0xae, 0x75, 0xd1, 0xfb, + 0x01, 0x67, 0x8b, 0xf7, 0x08, 0x43, 0x8b, 0x8b, 0xfb, 0x08, 0xfb, 0x01, + 0xaf, 0x75, 0x46, 0xf7, 0x01, 0x67, 0x05, 0x0e, 0x34, 0xf8, 0xa9, 0xf7, + 0xb7, 0x15, 0xfb, 0x4a, 0xf7, 0x4a, 0xfb, 0x0b, 0xfb, 0x4a, 0xfb, 0x4a, + 0xfb, 0x0b, 0xf7, 0x4a, 0xfb, 0x4a, 0xf7, 0x0b, 0xf7, 0x4a, 0xf7, 0x4a, + 0xf7, 0x0b, 0x06, 0x0e, 0xfc, 0x1d, 0xcb, 0xf7, 0x26, 0x15, 0xfb, 0x26, + 0xe1, 0x88, 0x07, 0x8b, 0x47, 0x70, 0x68, 0x50, 0x7f, 0x08, 0x53, 0x07, + 0xb4, 0x90, 0xa7, 0x96, 0xa6, 0xa0, 0xb3, 0xaa, 0x99, 0xb0, 0x8b, 0xd9, + 0x08, 0xf7, 0x1d, 0xfb, 0x2a, 0x07, 0x0e, 0xfb, 0xe6, 0xf7, 0xbe, 0xf7, + 0xea, 0x15, 0xfb, 0xa4, 0xfb, 0x1b, 0xf7, 0xa4, 0xf7, 0x1b, 0x06, 0x0e, + 0xfc, 0x1d, 0xf7, 0x6a, 0xf7, 0x26, 0x15, 0xfb, 0x2a, 0xfb, 0x26, 0xf7, + 0x2a, 0xf7, 0x26, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, 0x64, 0xf9, 0x5e, 0x15, + 0xfb, 0x62, 0xfd, 0x6c, 0xce, 0x8b, 0xf7, 0x62, 0xf9, 0x6c, 0x48, 0x8b, + 0x05, 0x0e, 0xf7, 0xa5, 0xf9, 0x68, 0x15, 0x3f, 0x8b, 0x4a, 0x6b, 0x60, + 0x50, 0x62, 0x54, 0x78, 0x30, 0x8b, 0xfb, 0x1d, 0x8b, 0xfb, 0x11, 0x9c, + 0x32, 0xac, 0x55, 0xb5, 0x48, 0xd0, 0x65, 0xde, 0x8b, 0xd8, 0x8b, 0xca, + 0xaa, 0xb7, 0xc7, 0xb3, 0xc1, 0x9f, 0xe7, 0x8b, 0xf7, 0x18, 0x08, 0x8b, + 0xf7, 0x16, 0x7b, 0xe3, 0x69, 0xc2, 0x61, 0xcf, 0x46, 0xb0, 0x38, 0x8b, + 0x08, 0xfb, 0x05, 0x04, 0xaf, 0x8b, 0xa8, 0x77, 0x9c, 0x66, 0x99, 0x6d, + 0x93, 0x3d, 0x8b, 0x2a, 0x8b, 0x3c, 0x83, 0x3b, 0x81, 0x6f, 0x7b, 0x61, + 0x6d, 0x74, 0x63, 0x8b, 0x66, 0x8b, 0x6f, 0x9e, 0x7a, 0xaf, 0x7d, 0xa9, + 0x83, 0xd6, 0x8b, 0xe9, 0x08, 0x8b, 0xde, 0x93, 0xdc, 0x95, 0xa8, 0x9b, + 0xb6, 0xa9, 0xa3, 0xb3, 0x8b, 0x08, 0x0e, 0xf7, 0x82, 0xf8, 0x7d, 0x15, + 0xfc, 0x7d, 0xf7, 0x20, 0xf9, 0x59, 0x2e, 0x07, 0x75, 0x37, 0x42, 0x60, + 0xfb, 0x0e, 0x8b, 0x08, 0x2e, 0xf7, 0x3e, 0x07, 0x0e, 0xf8, 0x94, 0xf7, + 0x11, 0x15, 0xfb, 0xc0, 0x06, 0x9d, 0xb1, 0xa1, 0x9f, 0xf3, 0xd7, 0xf7, + 0x0f, 0xe5, 0xaf, 0xc1, 0x8b, 0xeb, 0x08, 0xf7, 0x1d, 0x2d, 0xe3, 0xfb, + 0x29, 0xfb, 0x27, 0x35, 0x34, 0xfb, 0x2a, 0x1e, 0x8b, 0x85, 0x8b, 0x83, + 0x8c, 0x80, 0x08, 0xf7, 0x1a, 0xa2, 0x06, 0xda, 0xb0, 0xb9, 0xcb, 0xc9, + 0xb1, 0x60, 0x44, 0x1e, 0x8b, 0x3d, 0x72, 0x6c, 0xfb, 0x30, 0xfb, 0x03, + 0xfb, 0x0c, 0x39, 0x66, 0x4c, 0x84, 0xfb, 0x17, 0x08, 0xf8, 0x76, 0xf7, + 0x11, 0x06, 0x0e, 0xf7, 0x6d, 0xf7, 0xd1, 0x15, 0xbc, 0x8b, 0x94, 0x8a, + 0xa3, 0x85, 0xba, 0x7e, 0xa9, 0x62, 0x8b, 0x57, 0x8b, 0x4d, 0x5f, 0x5e, + 0x4e, 0x8b, 0x49, 0x8b, 0x67, 0xb1, 0x87, 0xd4, 0x08, 0xfb, 0x1c, 0x06, + 0x8c, 0xfb, 0x22, 0xe8, 0x32, 0xf7, 0x25, 0x8b, 0xf7, 0x2b, 0x8b, 0xec, + 0xe4, 0x8b, 0xf7, 0x1e, 0x8b, 0xde, 0x67, 0xc1, 0x3b, 0xb2, 0x08, 0xcd, + 0xb4, 0xa6, 0xb8, 0x8b, 0xcc, 0x8b, 0xf7, 0x0a, 0x33, 0xd6, 0xfb, 0x1d, + 0x8b, 0x3a, 0x8b, 0x47, 0x6f, 0x63, 0x57, 0x6f, 0x68, 0x7e, 0x5b, 0x8b, + 0x4c, 0x08, 0x7f, 0xf7, 0x16, 0x07, 0x8c, 0xb1, 0x8e, 0x9e, 0x92, 0x9d, + 0x98, 0xaa, 0xab, 0x9e, 0xb4, 0x8b, 0x08, 0xc3, 0xab, 0x69, 0x50, 0x44, + 0x62, 0x67, 0x38, 0x1f, 0x7f, 0x06, 0x2d, 0x07, 0x0e, 0xf8, 0x9e, 0xf7, + 0xa5, 0x15, 0x41, 0xf8, 0x48, 0xfb, 0x39, 0x06, 0xfb, 0x97, 0xfc, 0x46, + 0x8b, 0xfb, 0x0a, 0xf7, 0xb0, 0x8b, 0x8b, 0xfb, 0x31, 0xf7, 0x20, 0x8b, + 0x8b, 0xf7, 0x31, 0xd5, 0x8b, 0x8b, 0xf7, 0x08, 0x05, 0xfb, 0x6a, 0x16, + 0xfb, 0x4d, 0x8b, 0xf7, 0x4d, 0xf7, 0xc3, 0x8b, 0xfb, 0xc3, 0x05, 0x0e, + 0xf8, 0x7d, 0xf9, 0x59, 0x15, 0xfc, 0x0f, 0x8b, 0x4c, 0xfc, 0x1f, 0xf7, + 0x12, 0x8b, 0x05, 0x9a, 0xae, 0xab, 0x9e, 0xb6, 0x8b, 0x08, 0xd2, 0xb6, + 0x58, 0x35, 0x38, 0x5f, 0x58, 0x45, 0x1f, 0x4e, 0x8b, 0x69, 0xaa, 0x88, + 0xc4, 0x08, 0xfb, 0x1e, 0x06, 0x8d, 0xfb, 0x10, 0xe9, 0x37, 0xf7, 0x1e, + 0x8b, 0x08, 0xf7, 0x2c, 0xf3, 0xf3, 0xf7, 0x2d, 0xf7, 0x25, 0x31, 0xef, + 0xfb, 0x17, 0x1f, 0x5c, 0x8b, 0x68, 0x7f, 0x62, 0x6c, 0x08, 0xa2, 0xf7, + 0x28, 0xf7, 0xb9, 0x8b, 0x8b, 0xf7, 0x11, 0x05, 0x0e, 0xf8, 0x8f, 0xf8, + 0xb8, 0x15, 0x84, 0xb9, 0x82, 0xa2, 0x79, 0xa5, 0x66, 0xbe, 0x4a, 0xa9, + 0x3e, 0x8b, 0x33, 0x8b, 0x43, 0x64, 0x60, 0x44, 0x61, 0x46, 0x7a, 0x3c, + 0x8b, 0xfb, 0x15, 0x8b, 0xfb, 0x0e, 0x9a, 0x3f, 0xaf, 0x52, 0xb4, 0x49, + 0xd5, 0x64, 0xdf, 0x8b, 0x08, 0xf7, 0x21, 0xeb, 0xf5, 0xf7, 0x2e, 0xf7, + 0x1c, 0x37, 0xe9, 0xfb, 0x0e, 0x1f, 0x51, 0x8b, 0x64, 0x7a, 0x5f, 0x5d, + 0x8e, 0xd6, 0x8b, 0x8b, 0x91, 0xa9, 0x98, 0xcb, 0xb3, 0xb1, 0xc3, 0x8b, + 0xb8, 0x8b, 0xa3, 0x79, 0x9d, 0x5e, 0x08, 0xf7, 0x16, 0x06, 0xfb, 0x78, + 0xfb, 0x53, 0x15, 0xcc, 0xb5, 0x58, 0x3d, 0x3f, 0x5d, 0x54, 0x4d, 0x4b, + 0x5f, 0xc0, 0xd6, 0xd9, 0xb7, 0xc1, 0xcc, 0x1f, 0x0e, 0xf8, 0xa4, 0xf9, + 0x59, 0x15, 0xfc, 0x87, 0xfb, 0x11, 0xf7, 0xf5, 0x06, 0x60, 0x5d, 0x36, + 0xfb, 0x15, 0x6f, 0x4d, 0x5a, 0x24, 0x72, 0x2e, 0x78, 0xfb, 0x2b, 0x08, + 0xf7, 0x21, 0x06, 0x98, 0xf7, 0x74, 0xd4, 0xf7, 0x40, 0xf7, 0x3c, 0xf7, + 0x5f, 0x08, 0xf7, 0x02, 0x07, 0x0e, 0xf8, 0x2d, 0xf8, 0x16, 0x15, 0xa3, + 0x98, 0x96, 0x92, 0x96, 0x95, 0xa8, 0xa6, 0x9c, 0xb6, 0x8b, 0xb9, 0x08, + 0xf7, 0x03, 0x2b, 0xdc, 0xfb, 0x17, 0xfb, 0x18, 0x2b, 0x3a, 0xfb, 0x04, + 0x1e, 0x8b, 0x47, 0xa7, 0x60, 0xcb, 0x69, 0x08, 0x39, 0x5f, 0x69, 0x55, + 0x8b, 0x37, 0x08, 0xfb, 0x1a, 0xf2, 0x2e, 0xf7, 0x29, 0xf7, 0x28, 0xf2, + 0xe8, 0xf7, 0x1a, 0x1e, 0x8b, 0xdf, 0x69, 0xc1, 0x39, 0xb7, 0x08, 0xfb, + 0x1a, 0xf7, 0x75, 0x15, 0xc9, 0xb6, 0x65, 0x54, 0x55, 0x5f, 0x64, 0x4e, + 0x4d, 0x5f, 0xb2, 0xc2, 0x1f, 0xc1, 0xb6, 0xb1, 0xca, 0x1e, 0x89, 0xfb, + 0xad, 0x15, 0xd0, 0xb6, 0x5d, 0x41, 0x47, 0x5f, 0x5e, 0x47, 0x47, 0x60, + 0xb8, 0xd1, 0x1f, 0xd3, 0xb7, 0xb9, 0xce, 0x1e, 0x0e, 0xb1, 0xf7, 0x39, + 0x15, 0x8e, 0xfb, 0x01, 0xe7, 0x3b, 0xf7, 0x0e, 0x8b, 0xe6, 0x8b, 0xd0, + 0xb1, 0xb5, 0xd3, 0xb0, 0xca, 0xa1, 0xf6, 0x8b, 0xf7, 0x06, 0x8b, 0xf2, + 0x7a, 0xdd, 0x6b, 0xc0, 0x5e, 0xd7, 0x45, 0xb3, 0x36, 0x8b, 0x08, 0xfb, + 0x22, 0x2a, 0x25, 0xfb, 0x28, 0xfb, 0x26, 0xe1, 0x27, 0xf7, 0x12, 0x1f, + 0xaf, 0x8b, 0xad, 0x95, 0xa1, 0x9b, 0x98, 0x94, 0x93, 0x94, 0xa2, 0xa5, + 0x8b, 0xfb, 0x1b, 0x65, 0x48, 0x3c, 0x8b, 0x5a, 0x8b, 0x69, 0xa6, 0x88, + 0xb5, 0x08, 0xfb, 0x1b, 0x06, 0xf7, 0x75, 0xf8, 0x51, 0x15, 0xcf, 0xb5, + 0x56, 0x38, 0x3d, 0x5f, 0x57, 0x4b, 0x4b, 0x63, 0xbe, 0xdc, 0xdd, 0xb3, + 0xbf, 0xc9, 0x1f, 0x0e, 0xfb, 0xe6, 0xf7, 0x9b, 0xf7, 0x26, 0x15, 0xfb, + 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, 0x26, 0x06, 0xf8, 0x0a, 0x04, 0xfb, + 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, 0x26, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, + 0x05, 0xf7, 0x26, 0x15, 0xfb, 0x26, 0xe1, 0x88, 0x07, 0x8b, 0x47, 0x70, + 0x68, 0x50, 0x7f, 0x08, 0x53, 0x07, 0xb4, 0x90, 0xa7, 0x96, 0xa6, 0xa0, + 0xb3, 0xaa, 0x99, 0xb0, 0x8b, 0xd9, 0x08, 0xf7, 0x1d, 0xfb, 0x2a, 0x07, + 0xf7, 0x2a, 0xf8, 0x0a, 0x15, 0xfb, 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, + 0x26, 0x06, 0x0e, 0x34, 0xf8, 0xa5, 0xf8, 0x6e, 0x15, 0xfc, 0x7d, 0xfb, + 0x49, 0x8b, 0xfb, 0x0d, 0xf8, 0x7d, 0xfb, 0x4a, 0x8b, 0xf7, 0x03, 0xfc, + 0x12, 0xf7, 0x17, 0xf8, 0x12, 0xf7, 0x19, 0x8b, 0xf7, 0x01, 0x05, 0x0e, + 0x34, 0xf8, 0xaa, 0xf8, 0x2f, 0x15, 0xfc, 0x78, 0xfb, 0x0b, 0xf8, 0x78, + 0xf7, 0x0b, 0x06, 0xfb, 0x84, 0x04, 0xfc, 0x78, 0xfb, 0x0b, 0xf8, 0x78, + 0xf7, 0x0b, 0x06, 0x0e, 0x34, 0xb3, 0x81, 0x15, 0xf8, 0x7d, 0xf7, 0x49, + 0x8b, 0xf7, 0x0d, 0xfc, 0x7d, 0xf7, 0x4a, 0x8b, 0xfb, 0x03, 0xf8, 0x12, + 0xfb, 0x17, 0xfc, 0x12, 0xfb, 0x19, 0x8b, 0xfb, 0x01, 0x05, 0x0e, 0x4f, + 0xf8, 0x05, 0xf7, 0x5d, 0x15, 0x8b, 0xcd, 0x92, 0x96, 0xc7, 0xb5, 0xe8, + 0xcd, 0xa6, 0xb7, 0x8b, 0xdf, 0x8b, 0xf7, 0x1c, 0x25, 0xe9, 0xfb, 0x27, + 0x8b, 0x35, 0x8b, 0x48, 0x6d, 0x60, 0x50, 0x6a, 0x5f, 0x7e, 0x5b, 0x8a, + 0x39, 0x08, 0xf7, 0x1c, 0x8d, 0x06, 0x87, 0xdc, 0xbb, 0xc9, 0xcd, 0x8b, + 0xc7, 0x8b, 0xb8, 0x59, 0x8b, 0x4a, 0x8b, 0x5e, 0x7f, 0x78, 0x50, 0x5b, + 0x3c, 0x47, 0x74, 0x5e, 0x8e, 0x36, 0x08, 0xf7, 0x10, 0x06, 0x9b, 0x54, + 0x15, 0xfb, 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, 0x26, 0x06, 0x0e, 0xf7, + 0xc4, 0xf9, 0x18, 0xf8, 0x90, 0x15, 0x7b, 0x4d, 0x05, 0x73, 0xbd, 0x69, + 0xa1, 0x53, 0x8b, 0x47, 0x8b, 0x46, 0x68, 0x5e, 0x53, 0x5d, 0x52, 0x6f, + 0x3f, 0x8b, 0x48, 0x8b, 0x2c, 0xd4, 0x3f, 0xe6, 0x8b, 0xc2, 0x8b, 0xc3, + 0xa7, 0xb2, 0xba, 0x93, 0x72, 0x93, 0x81, 0x9f, 0x7d, 0x08, 0xa4, 0x7a, + 0xaa, 0x82, 0xac, 0x8b, 0xc7, 0x8b, 0xc7, 0xa9, 0xbb, 0xc1, 0xc2, 0xca, + 0xa6, 0xd0, 0x8b, 0xde, 0x8b, 0xf6, 0x68, 0xdf, 0x3f, 0xd5, 0x36, 0xdd, + 0xfb, 0x01, 0xb6, 0xfb, 0x12, 0x8b, 0xfb, 0x1c, 0x8b, 0xfb, 0x0a, 0x5a, + 0x2f, 0x2c, 0x08, 0x33, 0x30, 0x54, 0xfb, 0x16, 0x8b, 0xfb, 0x08, 0x8b, + 0xfb, 0x0b, 0xc2, 0xfb, 0x05, 0xeb, 0x40, 0xde, 0x4a, 0xeb, 0x6d, 0xf7, + 0x13, 0x8b, 0xe9, 0x8b, 0xd4, 0x99, 0xd1, 0xab, 0x08, 0x6f, 0xd4, 0x05, + 0x51, 0x71, 0x3e, 0x7c, 0x43, 0x8b, 0x30, 0x8b, 0x35, 0xa8, 0x48, 0xbf, + 0x3d, 0xc8, 0x63, 0xdf, 0x8b, 0xef, 0x8b, 0xef, 0xb1, 0xf0, 0xcc, 0xd6, + 0xd3, 0xde, 0xeb, 0xb6, 0xf7, 0x08, 0x8b, 0xed, 0x8b, 0xdc, 0x6d, 0xd1, + 0x4d, 0x08, 0xcd, 0x50, 0xab, 0x47, 0x8b, 0x3c, 0x8b, 0x51, 0x79, 0x52, + 0x6a, 0x5d, 0x6a, 0x5f, 0x61, 0x6f, 0x68, 0x8b, 0x6d, 0x8b, 0x78, 0x9e, + 0x8b, 0xa9, 0x8b, 0x97, 0x8b, 0x8b, 0x93, 0xa9, 0x08, 0xd9, 0xf7, 0xac, + 0x31, 0x8b, 0x05, 0xfb, 0x19, 0x4e, 0x15, 0xbf, 0xab, 0x64, 0x4c, 0x1f, + 0x8b, 0x58, 0x71, 0x48, 0x66, 0x60, 0x73, 0x6f, 0x68, 0x78, 0x6e, 0x8b, + 0x08, 0x59, 0x64, 0xba, 0xc7, 0xf1, 0xd9, 0xf0, 0xd9, 0x1f, 0x0e, 0xbe, + 0xf8, 0x89, 0xf7, 0x27, 0x15, 0xbb, 0xfb, 0x27, 0xf7, 0x2e, 0x8b, 0xfb, + 0x90, 0xf9, 0x6d, 0xfb, 0x3a, 0x8b, 0xfb, 0x97, 0xfd, 0x6d, 0xf7, 0x2d, + 0x8b, 0xbc, 0xf7, 0x27, 0xf7, 0xa5, 0x8b, 0x05, 0x62, 0xf7, 0x11, 0x15, + 0xfb, 0x52, 0x8b, 0xea, 0xf7, 0xb1, 0xea, 0xfb, 0xb1, 0x05, 0x0e, 0xbe, + 0xdd, 0x16, 0xf7, 0xdc, 0x06, 0xdf, 0x8b, 0xc3, 0x9b, 0xb7, 0xb0, 0xb7, + 0xb0, 0xa7, 0xc9, 0x8b, 0xc5, 0x8b, 0xd3, 0x64, 0xc4, 0x39, 0xbb, 0x08, + 0xd3, 0xb9, 0xa7, 0xb5, 0x8b, 0xc9, 0x8b, 0xbd, 0x72, 0xc0, 0x62, 0xaf, + 0x60, 0xb0, 0x58, 0x9b, 0x3d, 0x8b, 0x08, 0xfb, 0xd9, 0x06, 0xfd, 0x6d, + 0x07, 0xf7, 0x2a, 0xf8, 0xf0, 0x15, 0xf7, 0x37, 0x06, 0xd0, 0xb0, 0x6e, + 0x55, 0x56, 0x66, 0x6e, 0x46, 0x1f, 0xfb, 0x37, 0xf7, 0x39, 0x06, 0xfb, + 0xb6, 0x04, 0xf7, 0x47, 0x06, 0xd4, 0xb1, 0x6a, 0x4d, 0x4e, 0x65, 0x6a, + 0x42, 0x1f, 0xfb, 0x47, 0xf7, 0x51, 0x06, 0x0e, 0xbe, 0xf9, 0x3e, 0xf8, + 0x76, 0x15, 0x86, 0xca, 0x7e, 0xb3, 0x6c, 0xb4, 0x53, 0xd5, 0x31, 0xb4, + 0xfb, 0x01, 0x8b, 0x08, 0xfb, 0x62, 0xfb, 0x14, 0xfb, 0x27, 0xfb, 0x80, + 0xfb, 0x7e, 0xf7, 0x13, 0xfb, 0x27, 0xf7, 0x5f, 0x1f, 0xf7, 0x49, 0x8b, + 0xf7, 0x0d, 0xf4, 0x94, 0xf7, 0x3b, 0x08, 0xfb, 0x26, 0x06, 0x82, 0x2e, + 0x50, 0x56, 0x2e, 0x8b, 0x08, 0xfb, 0x08, 0x47, 0xe9, 0xf7, 0x33, 0xf7, + 0x35, 0xd2, 0xeb, 0xf7, 0x0a, 0x1f, 0xbf, 0x8b, 0xb6, 0x79, 0xa7, 0x68, + 0x9b, 0x77, 0x93, 0x78, 0x94, 0x64, 0x08, 0xf7, 0x23, 0x06, 0x0e, 0xbe, + 0xd8, 0x16, 0xf7, 0xb1, 0x06, 0xf7, 0x03, 0x8b, 0xd1, 0xa5, 0xbc, 0xc6, + 0xc5, 0xcf, 0xaa, 0xee, 0x8b, 0xf7, 0x05, 0x8b, 0xf7, 0x04, 0x6c, 0xee, + 0x51, 0xd0, 0x5a, 0xc6, 0x46, 0xa4, 0xfb, 0x04, 0x8b, 0x08, 0xfb, 0xb1, + 0xfd, 0x6d, 0x06, 0xf7, 0x2a, 0xf7, 0x11, 0x15, 0xf8, 0x73, 0xf7, 0x1b, + 0x07, 0xf7, 0x05, 0xc3, 0x3c, 0xfb, 0x35, 0xfb, 0x34, 0x53, 0x3c, 0xfb, + 0x05, 0x1f, 0xfb, 0x1b, 0x06, 0x0e, 0x87, 0xf7, 0x79, 0xf7, 0xce, 0x15, + 0xf7, 0xf1, 0xf7, 0x11, 0xfb, 0xf1, 0xf7, 0x39, 0xf8, 0x0d, 0xf7, 0x11, + 0xfc, 0xa3, 0xfd, 0x6d, 0xf8, 0xb5, 0xf7, 0x11, 0xfc, 0x1f, 0xf7, 0x51, + 0x06, 0x0e, 0x4f, 0xf7, 0x74, 0xf7, 0xce, 0x15, 0xf7, 0xd3, 0xf7, 0x11, + 0xfb, 0xd3, 0xf7, 0x39, 0xf7, 0xfe, 0xf7, 0x11, 0xfc, 0x94, 0xfd, 0x6d, + 0xf7, 0x2a, 0xf7, 0xce, 0x06, 0x0e, 0xf6, 0xf9, 0x5b, 0xf8, 0x1c, 0x15, + 0xfb, 0xb8, 0xfb, 0x11, 0xf7, 0x3a, 0x06, 0x87, 0x62, 0x81, 0x72, 0x75, + 0x71, 0x67, 0x5f, 0x54, 0x71, 0x51, 0x8b, 0x08, 0xfb, 0x0d, 0x34, 0xf5, + 0xf7, 0x2a, 0xf7, 0x31, 0xd8, 0xea, 0xf7, 0x13, 0x1f, 0xbf, 0x8b, 0xb7, + 0x7c, 0xac, 0x6e, 0xa0, 0x79, 0x96, 0x7a, 0x98, 0x65, 0x08, 0xf7, 0x21, + 0x06, 0x79, 0xf7, 0x2a, 0xfb, 0x0e, 0xea, 0xfb, 0x44, 0x8b, 0x08, 0xfb, + 0x66, 0xfb, 0x23, 0xfb, 0x2f, 0xfb, 0x77, 0xfb, 0x71, 0xf7, 0x24, 0xfb, + 0x35, 0xf7, 0x59, 0x1f, 0xed, 0x8b, 0xcd, 0xae, 0xc3, 0xdd, 0x08, 0x9d, + 0x2b, 0xe5, 0x8b, 0x8b, 0xf8, 0x1e, 0x05, 0x0e, 0xbe, 0xf8, 0x8f, 0xf7, + 0xdf, 0x15, 0xfb, 0xdf, 0x07, 0xf7, 0x2a, 0xf9, 0x6d, 0xfb, 0x2b, 0xfb, + 0xa5, 0xfb, 0xb4, 0xf7, 0xa5, 0xfb, 0x2a, 0xfd, 0x6d, 0xf7, 0x2a, 0xf7, + 0xdf, 0x06, 0xf7, 0xb5, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, 0x69, 0xf9, 0x6d, + 0x15, 0xfb, 0x2a, 0xfd, 0x6d, 0xf7, 0x2a, 0xf9, 0x6d, 0x06, 0x0e, 0xf7, + 0xe4, 0xf9, 0x6d, 0x15, 0xfc, 0xaf, 0x07, 0x54, 0x6e, 0x6d, 0x57, 0x52, + 0x73, 0xa7, 0xce, 0x1e, 0xd1, 0xfb, 0x2a, 0x43, 0x07, 0x8b, 0x3f, 0x9d, + 0x5c, 0xb6, 0x63, 0xb5, 0x65, 0xc3, 0x77, 0xd0, 0x8b, 0x08, 0xf7, 0x29, + 0xe0, 0xd8, 0xf7, 0x1c, 0x1f, 0xf8, 0xaf, 0xfb, 0x2a, 0x07, 0x0e, 0xbe, + 0xf7, 0x74, 0xf7, 0x88, 0x15, 0xd6, 0xd9, 0xf7, 0x83, 0xfb, 0xd6, 0xf7, + 0x47, 0x8b, 0xfb, 0xd6, 0xf8, 0x33, 0xf7, 0xb7, 0xf7, 0xce, 0xfb, 0x45, + 0x8b, 0xfb, 0xb1, 0xfb, 0xd4, 0x8b, 0xf7, 0xd4, 0xfb, 0x2a, 0x8b, 0x8b, + 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0x8b, 0xf7, 0x88, 0x05, 0x0e, 0x4f, 0xf7, + 0x7a, 0xf9, 0x6d, 0x15, 0xfb, 0x2a, 0xfd, 0x6d, 0xf8, 0x87, 0xf7, 0x11, + 0xfb, 0xf1, 0xf8, 0xf0, 0x06, 0x0e, 0xf7, 0x36, 0xf7, 0x6c, 0xf8, 0xcc, + 0x15, 0xf7, 0x17, 0xfc, 0xcc, 0xf7, 0x2a, 0x8b, 0xf7, 0x15, 0xf8, 0xcc, + 0x8b, 0xfc, 0xcc, 0xf7, 0x2a, 0x8b, 0x8b, 0xf9, 0x6d, 0xfb, 0x76, 0x8b, + 0xfb, 0x14, 0xfc, 0xd8, 0xfb, 0x18, 0xf8, 0xd8, 0xfb, 0x74, 0x8b, 0x8b, + 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0x8b, 0xf8, 0xcc, 0x05, 0x0e, 0xbe, 0xf8, + 0x93, 0x16, 0xf7, 0x2a, 0xf9, 0x6d, 0xfb, 0x2a, 0xfc, 0x84, 0x06, 0xfb, + 0xb5, 0xf8, 0x84, 0xfb, 0x2e, 0x8b, 0x8b, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, + 0x8b, 0xf8, 0x8c, 0xf7, 0xb9, 0xfc, 0x8c, 0x05, 0x0e, 0xf6, 0xf8, 0x1a, + 0xf9, 0x79, 0x15, 0x25, 0x8b, 0x37, 0x69, 0x4d, 0x48, 0x4a, 0x45, 0x66, + 0x25, 0x8b, 0xfb, 0x01, 0x8b, 0xfb, 0x01, 0xb0, 0x24, 0xcc, 0x46, 0xca, + 0x47, 0xdd, 0x6a, 0xf3, 0x8b, 0xf3, 0x8b, 0xdd, 0xac, 0xca, 0xcf, 0xca, + 0xce, 0xb2, 0xf5, 0x8b, 0xf2, 0x08, 0x8b, 0xf7, 0x06, 0x66, 0xf1, 0x4a, + 0xd1, 0x4b, 0xd0, 0x3a, 0xab, 0x22, 0x8b, 0x08, 0x8c, 0xfb, 0x14, 0x15, + 0xf7, 0x0f, 0xd9, 0x27, 0xfb, 0x32, 0xfb, 0x29, 0x3a, 0x26, 0xfb, 0x0c, + 0xfb, 0x0d, 0x3b, 0xf0, 0xf7, 0x2d, 0xf7, 0x2d, 0xdb, 0xf0, 0xf7, 0x0d, + 0x1f, 0x0e, 0x87, 0xf7, 0x76, 0xf7, 0x98, 0x15, 0xf7, 0x4f, 0x06, 0xf7, + 0x1a, 0xe1, 0xea, 0xf7, 0x28, 0xf7, 0x26, 0x38, 0xdb, 0xfb, 0x2c, 0x1f, + 0xfb, 0xd6, 0xfd, 0x6d, 0xf7, 0x2a, 0xf7, 0x98, 0x06, 0xf7, 0x11, 0x04, + 0xf7, 0x6f, 0xf7, 0x20, 0x07, 0xdb, 0xb0, 0x68, 0x40, 0x41, 0x66, 0x68, + 0x3b, 0x1f, 0xfb, 0x20, 0x06, 0x0e, 0xf6, 0xf9, 0x2d, 0xf2, 0x15, 0xbc, + 0xc7, 0xaa, 0xef, 0x8b, 0xed, 0x8b, 0xf6, 0x65, 0xf2, 0x4b, 0xd0, 0x4c, + 0xcf, 0x39, 0xac, 0x23, 0x8b, 0x23, 0x8b, 0x39, 0x6a, 0x4c, 0x47, 0x4b, + 0x46, 0x65, 0x24, 0x8b, 0xfb, 0x01, 0x8b, 0xfb, 0x01, 0xb1, 0x24, 0xcb, + 0x46, 0x08, 0xca, 0x47, 0xde, 0x6a, 0xf2, 0x8b, 0xd6, 0x8b, 0xc3, 0x9a, + 0xc5, 0xae, 0x08, 0xe1, 0x3a, 0xd7, 0xdc, 0x3b, 0xd7, 0x05, 0xfb, 0x4d, + 0xf7, 0x43, 0x15, 0x3f, 0x3a, 0xd8, 0x42, 0x05, 0x74, 0x7f, 0x6a, 0x84, + 0x6b, 0x8b, 0x08, 0xfb, 0x0c, 0x3b, 0xf0, 0xf7, 0x2d, 0xf7, 0x2d, 0xdb, + 0xf0, 0xf7, 0x0d, 0xf7, 0x0e, 0xda, 0x27, 0xfb, 0x2f, 0x1f, 0x8b, 0x4f, + 0x80, 0x55, 0x75, 0x5f, 0x08, 0x39, 0xd9, 0x05, 0x0e, 0xbe, 0xf7, 0x7a, + 0xf7, 0xb5, 0x15, 0xf7, 0x40, 0x06, 0xcc, 0xa7, 0x71, 0x4e, 0x1f, 0x8b, + 0x85, 0x8b, 0x81, 0x8a, 0x7e, 0x8a, 0x78, 0x8b, 0x79, 0x8b, 0x80, 0x8b, + 0x47, 0x8f, 0x75, 0x9e, 0x68, 0x08, 0xf7, 0x35, 0xa6, 0x06, 0x74, 0x98, + 0x82, 0x9a, 0x8b, 0xab, 0x87, 0xf7, 0x6b, 0x87, 0x95, 0x2e, 0xb3, 0xdd, + 0xab, 0xb4, 0xc6, 0x8b, 0xe4, 0x8b, 0xc5, 0x77, 0xc0, 0x68, 0xaf, 0x6a, + 0xad, 0x5d, 0x9b, 0x4d, 0x8b, 0x08, 0xfc, 0x1b, 0xfd, 0x6d, 0xf7, 0x2a, + 0xf7, 0xb5, 0x06, 0xf7, 0x11, 0x04, 0xf7, 0x52, 0xf7, 0x49, 0x07, 0xb6, + 0x8b, 0x9d, 0x87, 0x9d, 0x7c, 0x9d, 0x7c, 0x94, 0x72, 0x8b, 0x69, 0x8b, + 0x68, 0x81, 0x6f, 0x7a, 0x7c, 0x7b, 0x7d, 0x77, 0x86, 0x60, 0x8b, 0x08, + 0xfb, 0x49, 0x06, 0x0e, 0x87, 0xf8, 0xf3, 0xf8, 0x8f, 0x15, 0x8b, 0xce, + 0x7c, 0xb7, 0x67, 0xb3, 0x5a, 0xc1, 0x3a, 0xa8, 0x22, 0x8b, 0xfb, 0x43, + 0x8b, 0x26, 0x39, 0x8b, 0xfb, 0x22, 0x8b, 0xfb, 0x05, 0xc4, 0x54, 0xf7, + 0x28, 0x6f, 0x08, 0xf1, 0x77, 0x05, 0xef, 0x78, 0xb0, 0x6f, 0x8b, 0x50, + 0x8b, 0x4e, 0x53, 0x66, 0x30, 0x8b, 0x25, 0x8b, 0x52, 0xb6, 0x86, 0xd9, + 0x08, 0xfb, 0x26, 0x06, 0x94, 0xfb, 0x30, 0xf6, 0x36, 0xf7, 0x4e, 0x8b, + 0xf7, 0x50, 0x8b, 0xf7, 0x03, 0xe3, 0x8b, 0xf7, 0x28, 0x8b, 0xf7, 0x07, + 0x51, 0xc7, 0xfb, 0x1b, 0xa5, 0x08, 0xfb, 0x06, 0xa1, 0x05, 0x20, 0xa0, + 0x6c, 0xa0, 0x8b, 0xc0, 0x8b, 0xc2, 0xbc, 0xae, 0xd8, 0x8b, 0xea, 0x8b, + 0xc0, 0x63, 0x90, 0x41, 0x08, 0xf7, 0x20, 0x06, 0x0e, 0x4f, 0xf8, 0x15, + 0xf8, 0xf0, 0x15, 0xf7, 0x69, 0xf7, 0x11, 0xfc, 0xdc, 0xfb, 0x11, 0xf7, + 0x71, 0xfc, 0xf0, 0xf7, 0x2a, 0xf8, 0xf0, 0x06, 0x0e, 0xbe, 0xf8, 0x8c, + 0xf9, 0x6d, 0x15, 0xfc, 0x82, 0x07, 0x33, 0x5e, 0x61, 0x2d, 0x2d, 0x5e, + 0xb5, 0xe3, 0x1e, 0xf8, 0x82, 0xfb, 0x2a, 0xfc, 0x82, 0x07, 0x8b, 0x39, + 0xa1, 0x51, 0xbc, 0x5f, 0xc0, 0x5b, 0xd8, 0x71, 0xe3, 0x8b, 0xe3, 0x8b, + 0xd8, 0xa5, 0xc0, 0xbb, 0xbc, 0xb7, 0xa1, 0xc5, 0x8b, 0xdd, 0x08, 0xf8, + 0x82, 0xfb, 0x2a, 0x07, 0x0e, 0x87, 0xf8, 0x21, 0x16, 0xf7, 0x8e, 0xf9, + 0x6d, 0xfb, 0x2b, 0x8b, 0xfb, 0x33, 0xfc, 0xb9, 0xfb, 0x36, 0xf8, 0xb9, + 0xfb, 0x2b, 0x8b, 0xf7, 0x8a, 0xfd, 0x6d, 0xf7, 0x13, 0x8b, 0x05, 0x0e, + 0xf7, 0xa5, 0xf9, 0x6e, 0x16, 0xf7, 0x5e, 0xf9, 0x6d, 0xfb, 0x33, 0x8b, + 0xfb, 0x01, 0xfc, 0xb7, 0xfb, 0x0a, 0xf8, 0xb7, 0xfb, 0x28, 0x8b, 0xfb, + 0x05, 0xfc, 0xb6, 0xfb, 0x05, 0xf8, 0xb6, 0xfb, 0x33, 0x8b, 0xf7, 0x62, + 0xfd, 0x6d, 0xf7, 0x1b, 0x8b, 0xf7, 0x0b, 0xf8, 0xcd, 0xf7, 0x0e, 0xfc, + 0xcd, 0xf7, 0x1b, 0x8b, 0x05, 0x0e, 0x87, 0xf8, 0x37, 0xf8, 0x08, 0x15, + 0xf7, 0x75, 0xf7, 0xf9, 0xfb, 0x42, 0x8b, 0xfb, 0x1a, 0xfb, 0x84, 0xfb, + 0x14, 0xf7, 0x84, 0xfb, 0x46, 0x8b, 0xf7, 0x72, 0xfb, 0xfe, 0xfb, 0x7a, + 0xfc, 0x03, 0xf7, 0x42, 0x8b, 0xf7, 0x1f, 0xf7, 0x91, 0xf7, 0x20, 0xfb, + 0x91, 0xf7, 0x46, 0x8b, 0xfb, 0x7e, 0xf8, 0x08, 0x05, 0x0e, 0x87, 0xf8, + 0x37, 0xf7, 0xa2, 0x15, 0xf7, 0x7b, 0xf8, 0x5f, 0xfb, 0x3c, 0x8b, 0xfb, + 0x1f, 0xfb, 0xd6, 0xfb, 0x29, 0xf7, 0xd6, 0xfb, 0x3b, 0x8b, 0xf7, 0x86, + 0xfc, 0x5f, 0x8b, 0xfb, 0xa2, 0xf7, 0x2a, 0x8b, 0x8b, 0xf7, 0xa2, 0x05, + 0x0e, 0x4f, 0xf8, 0xd6, 0xf9, 0x6d, 0x15, 0xfc, 0xb8, 0xfb, 0x11, 0xf8, + 0x09, 0x06, 0xfc, 0x09, 0xfc, 0x73, 0x8b, 0xfb, 0x11, 0xf8, 0xb8, 0x8b, + 0x8b, 0xf7, 0x11, 0xfc, 0x08, 0x8b, 0xf8, 0x08, 0xf8, 0x73, 0x8b, 0xf7, + 0x11, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0xc8, 0xf9, 0x6d, 0x15, 0xfb, 0x86, + 0xfe, 0x35, 0xf7, 0x86, 0xf1, 0xfb, 0x04, 0xf9, 0x69, 0xf7, 0x04, 0xf1, + 0x06, 0x0e, 0xfc, 0x1d, 0xc2, 0xf9, 0x5e, 0x15, 0x48, 0x8b, 0xf7, 0x7e, + 0xfd, 0x6c, 0xce, 0x8b, 0xfb, 0x7e, 0xf9, 0x6c, 0x05, 0x0e, 0xfb, 0xe6, + 0x9d, 0xfb, 0x5c, 0x15, 0xf7, 0x86, 0xfa, 0x35, 0xfb, 0x86, 0x25, 0xf7, + 0x04, 0xfd, 0x69, 0xfb, 0x04, 0x25, 0x06, 0x0e, 0x34, 0xf8, 0x9e, 0xf7, + 0xa2, 0x15, 0xfb, 0x3f, 0xf8, 0x3d, 0xfb, 0x11, 0x8b, 0xfb, 0x39, 0xfc, + 0x3d, 0xf7, 0x04, 0x8b, 0xf7, 0x07, 0xf7, 0xc0, 0xf7, 0x0d, 0xfb, 0xc0, + 0xf7, 0x05, 0x8b, 0x05, 0x0e, 0xf8, 0xd6, 0xfb, 0x0c, 0x15, 0xfc, 0xec, + 0x46, 0xf8, 0xec, 0xd0, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, 0x5e, 0xf8, 0x69, + 0x15, 0xf7, 0x11, 0x3b, 0x07, 0x89, 0xbd, 0xa5, 0xa8, 0xc3, 0x95, 0x08, + 0xb9, 0x07, 0x69, 0x89, 0x6b, 0x7f, 0x73, 0x77, 0x6b, 0x70, 0x7e, 0x6a, + 0x8b, 0x52, 0x08, 0xfb, 0x01, 0xf7, 0x1b, 0x07, 0x0e, 0xf8, 0xa0, 0x9c, + 0x15, 0x72, 0xa2, 0x84, 0x9a, 0x8b, 0xa7, 0x08, 0xf7, 0xc0, 0x07, 0xf7, + 0x02, 0x40, 0xc3, 0xfb, 0x26, 0x1e, 0xfb, 0x26, 0x8b, 0x3f, 0x4d, 0x82, + 0xfb, 0x11, 0x08, 0xf7, 0x1b, 0x06, 0x92, 0xc3, 0xa2, 0x9d, 0xd0, 0x8b, + 0xc1, 0x8b, 0xa6, 0x79, 0x8b, 0x67, 0x8b, 0x79, 0x82, 0x7b, 0x7c, 0x83, + 0x78, 0x81, 0x8b, 0x8b, 0x46, 0x80, 0x08, 0x53, 0x81, 0x05, 0x20, 0x79, + 0x57, 0x54, 0x8b, 0x2a, 0x8b, 0x5d, 0x98, 0x65, 0xa4, 0x70, 0xaa, 0x6b, + 0xba, 0x78, 0xbb, 0x8b, 0xc7, 0x8b, 0xc2, 0xa5, 0xbc, 0xbe, 0x08, 0x8b, + 0x6f, 0x8e, 0x81, 0x98, 0x7b, 0x08, 0xf7, 0x2c, 0x06, 0x9c, 0x07, 0xfb, + 0x3d, 0xf7, 0x5c, 0x15, 0x3a, 0x63, 0x5d, 0x44, 0x5c, 0x6e, 0xa4, 0xb3, + 0x1e, 0x8b, 0xb5, 0xa1, 0x9f, 0xc5, 0x97, 0x08, 0xbb, 0x94, 0x05, 0xb0, + 0x92, 0x91, 0x8d, 0x9b, 0x93, 0x08, 0x65, 0x07, 0x0e, 0x4f, 0xc6, 0xf9, + 0x6d, 0x15, 0xfd, 0x6d, 0xf7, 0x20, 0xc2, 0x07, 0xad, 0x56, 0xba, 0x72, + 0xcf, 0x8b, 0xf7, 0x15, 0x8b, 0xed, 0xf7, 0x0f, 0x8b, 0xf7, 0x37, 0x8b, + 0xd4, 0x75, 0xd5, 0x67, 0xbf, 0x66, 0xc0, 0x49, 0xad, 0x49, 0x8b, 0x48, + 0x8b, 0x5b, 0x72, 0x69, 0x55, 0x08, 0xf7, 0x97, 0x07, 0xfb, 0x20, 0x06, + 0xf7, 0x96, 0xfb, 0xbd, 0x15, 0xd0, 0xbc, 0x45, 0x27, 0x29, 0x5a, 0x45, + 0x46, 0x44, 0x5c, 0xcf, 0xf2, 0xed, 0xbb, 0xd0, 0xd1, 0x1f, 0x0e, 0xf8, + 0x9e, 0xf7, 0xe6, 0x15, 0x81, 0xf7, 0x18, 0x33, 0xda, 0xfb, 0x1b, 0x8b, + 0x08, 0xfb, 0x35, 0x2d, 0x21, 0xfb, 0x4c, 0xfb, 0x46, 0xe8, 0x23, 0xf7, + 0x34, 0x1f, 0xf7, 0x17, 0x8b, 0xe6, 0xdc, 0x98, 0xf7, 0x15, 0x08, 0xfb, + 0x1a, 0x06, 0x79, 0x45, 0x6f, 0x70, 0x55, 0x8b, 0x44, 0x8b, 0x60, 0xcb, + 0x8b, 0xf4, 0x8b, 0xbe, 0x95, 0xbb, 0x9c, 0xab, 0x9b, 0xa9, 0xaa, 0x9b, + 0xb3, 0x8b, 0xc4, 0x8b, 0xa6, 0x70, 0x9b, 0x44, 0x08, 0xf7, 0x1a, 0x06, + 0x0e, 0x4f, 0xf8, 0x29, 0x16, 0xf7, 0x20, 0xf9, 0x6d, 0xfb, 0x20, 0xfb, + 0x97, 0x06, 0x68, 0xc1, 0x5c, 0xa4, 0x48, 0x8b, 0xfb, 0x15, 0x8b, 0x29, + 0xfb, 0x10, 0x8b, 0xfb, 0x37, 0x8b, 0x42, 0xa1, 0x41, 0xaf, 0x57, 0x08, + 0xb0, 0x57, 0xcd, 0x69, 0xcd, 0x8b, 0xce, 0x8b, 0xba, 0xa4, 0xae, 0xc0, + 0x08, 0x54, 0x07, 0xfb, 0x0a, 0xf8, 0x44, 0x15, 0xd2, 0xba, 0x46, 0x24, + 0x1f, 0x29, 0x5b, 0x47, 0x45, 0x45, 0x5b, 0xd0, 0xee, 0x1e, 0xef, 0xbb, + 0xd1, 0xd1, 0x1e, 0x0e, 0xf8, 0xa0, 0xf7, 0x76, 0x15, 0x8c, 0x97, 0x8b, + 0x90, 0x8b, 0x92, 0x8b, 0xc1, 0x83, 0xbd, 0x7e, 0xb1, 0x67, 0xed, 0x34, + 0xc6, 0xfb, 0x01, 0x8b, 0x08, 0xfb, 0x2f, 0x2c, 0xfb, 0x04, 0xfb, 0x49, + 0xfb, 0x41, 0xe9, 0x21, 0xf7, 0x2d, 0x1f, 0xf7, 0x0d, 0x8b, 0xed, 0xd0, + 0xaa, 0xf5, 0x08, 0xfb, 0x1e, 0x06, 0x7a, 0x60, 0x64, 0x72, 0x58, 0x8b, + 0x63, 0x8b, 0x6b, 0x9c, 0x77, 0xa9, 0x7e, 0x9f, 0x86, 0xa3, 0x89, 0xbe, + 0x08, 0xf7, 0xfe, 0x06, 0xfb, 0xfc, 0xe8, 0x15, 0x94, 0xdd, 0xae, 0xb4, + 0xc9, 0x8b, 0xae, 0x8b, 0xab, 0x7a, 0x9f, 0x6f, 0x98, 0x77, 0x91, 0x76, + 0x8e, 0x66, 0x08, 0xfb, 0x6b, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0xcd, 0xf8, + 0xa5, 0x15, 0x38, 0xc0, 0x06, 0xa7, 0x97, 0x99, 0xa5, 0x1e, 0x97, 0x8b, + 0x9b, 0x8a, 0x97, 0x89, 0x08, 0xf4, 0x07, 0x71, 0x8d, 0x68, 0x8c, 0x78, + 0x8b, 0x08, 0x2e, 0x5e, 0x5f, 0x30, 0x1f, 0x4a, 0x3f, 0x2e, 0xd7, 0xfc, + 0x48, 0xf7, 0x20, 0xf8, 0x48, 0xde, 0xe8, 0x07, 0x0e, 0x4f, 0xf8, 0x2c, + 0xf8, 0xb0, 0x15, 0x38, 0x07, 0x61, 0xcb, 0x5d, 0xa7, 0x4d, 0x8b, 0x08, + 0xfb, 0x14, 0x2b, 0xfb, 0x11, 0xfb, 0x3b, 0xfb, 0x3c, 0xe3, 0xfb, 0x04, + 0xf7, 0x19, 0x1f, 0xca, 0x8b, 0xb1, 0x9e, 0xbf, 0xc6, 0x08, 0x42, 0x07, + 0x4a, 0x5a, 0x5e, 0x45, 0x1e, 0x56, 0x8b, 0x68, 0xa1, 0x80, 0xb4, 0x08, + 0xfb, 0x25, 0x06, 0x8c, 0x61, 0x9b, 0x6e, 0xaf, 0x6d, 0xb6, 0x68, 0xc7, + 0x7a, 0xde, 0x8b, 0x08, 0xf7, 0x37, 0xe9, 0xd4, 0xf7, 0x13, 0x1f, 0xf8, + 0xc2, 0x07, 0xfb, 0x19, 0x06, 0xfb, 0x0c, 0xfb, 0x00, 0x15, 0xd1, 0xbf, + 0x42, 0x27, 0x29, 0x58, 0x48, 0x42, 0x49, 0x5d, 0xce, 0xed, 0x1f, 0xf1, + 0xb9, 0xd2, 0xcf, 0x1e, 0x0e, 0x4f, 0xce, 0xf9, 0x6d, 0x15, 0xfd, 0x6d, + 0xf7, 0x20, 0xf7, 0xd8, 0x07, 0xc9, 0xb8, 0xb7, 0xca, 0x1e, 0xa9, 0x8b, + 0xa3, 0x80, 0x9b, 0x75, 0x97, 0x79, 0x8f, 0x7d, 0x8b, 0x68, 0x08, 0xfb, + 0xde, 0xf7, 0x20, 0xf7, 0xfe, 0x07, 0x8b, 0xce, 0x79, 0xbb, 0x66, 0xaa, + 0x6c, 0xa5, 0x5e, 0x9a, 0x5e, 0x8b, 0x46, 0x8b, 0x59, 0x6f, 0x64, 0x50, + 0x08, 0xf7, 0x9f, 0xfb, 0x20, 0x07, 0x0e, 0xfc, 0x1d, 0xf7, 0x63, 0xf8, + 0xb0, 0x15, 0xfb, 0x20, 0xfc, 0xb0, 0xf7, 0x20, 0xf8, 0xb0, 0x06, 0xf7, + 0x51, 0x04, 0xfb, 0x20, 0xfb, 0x11, 0xf7, 0x20, 0xf7, 0x11, 0x06, 0x0e, + 0xfc, 0x1d, 0xf7, 0x66, 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0xfc, 0xef, 0x06, + 0x6c, 0x80, 0x80, 0x6d, 0x1e, 0x82, 0x8b, 0x85, 0x8c, 0x81, 0x8e, 0x08, + 0xfb, 0x04, 0x07, 0xa7, 0x88, 0xae, 0x89, 0x9f, 0x8b, 0x08, 0xe2, 0xaf, + 0xaf, 0xe3, 0x1f, 0xf9, 0x0e, 0x07, 0xf7, 0x51, 0x04, 0xfb, 0x20, 0xfb, + 0x11, 0xf7, 0x20, 0xf7, 0x11, 0x06, 0x0e, 0xf7, 0x5b, 0xf7, 0xde, 0x15, + 0xf8, 0x23, 0xfb, 0x20, 0xfd, 0x6d, 0xf7, 0x20, 0xf7, 0x45, 0x07, 0xc3, + 0xc8, 0xf7, 0x15, 0xfb, 0x82, 0xf7, 0x38, 0x8b, 0xfb, 0x59, 0xf7, 0xe4, + 0xf7, 0x4c, 0xf7, 0x60, 0xfb, 0x33, 0x8b, 0xfb, 0x45, 0xfb, 0x66, 0x05, + 0x0e, 0xfc, 0x1d, 0xf7, 0x63, 0xf9, 0x6d, 0x15, 0xfb, 0x20, 0xfd, 0x6d, + 0xf7, 0x20, 0xf9, 0x6d, 0x06, 0x0e, 0xf7, 0x6e, 0xc7, 0xf8, 0xb0, 0x15, + 0xfc, 0xb0, 0xf7, 0x20, 0xf7, 0xd8, 0x07, 0xcd, 0xaf, 0xb3, 0xc7, 0xba, + 0xa8, 0x70, 0x60, 0x1e, 0xfb, 0xfc, 0xf7, 0x20, 0xf7, 0xd8, 0x07, 0xcd, + 0xaf, 0xb3, 0xc7, 0xba, 0xa8, 0x70, 0x60, 0x1e, 0xfb, 0xfc, 0xf7, 0x20, + 0xf8, 0x12, 0x07, 0xf4, 0x4b, 0xc9, 0xfb, 0x00, 0x1e, 0x47, 0x8b, 0x5b, + 0x73, 0x61, 0x53, 0x71, 0xbe, 0x55, 0xa8, 0x48, 0x8b, 0x08, 0x4d, 0x8b, + 0x63, 0x76, 0x5d, 0x54, 0x08, 0xce, 0x07, 0xfb, 0x1f, 0x06, 0x0e, 0x4f, + 0xca, 0xf8, 0xb0, 0x15, 0xfc, 0xb0, 0xf7, 0x20, 0xf7, 0xd8, 0x07, 0xcb, + 0xb8, 0xb5, 0xcf, 0xc7, 0xa9, 0x6a, 0x4b, 0x1e, 0xfb, 0xe1, 0xf7, 0x20, + 0xf7, 0xfe, 0x07, 0xf7, 0x0b, 0x49, 0xcf, 0xfb, 0x07, 0x1e, 0x42, 0x8b, + 0x5a, 0x70, 0x63, 0x4f, 0x08, 0xd9, 0x07, 0xfb, 0x20, 0x06, 0x0e, 0x4f, + 0xf7, 0xc1, 0xf8, 0xb9, 0x15, 0xfb, 0x39, 0x26, 0xfb, 0x01, 0xfb, 0x45, + 0xfb, 0x46, 0xf0, 0xfb, 0x00, 0xf7, 0x3a, 0xf7, 0x38, 0xf2, 0xf7, 0x01, + 0xf7, 0x41, 0xf7, 0x4b, 0x28, 0xf6, 0xfb, 0x3d, 0x1f, 0x8c, 0xfb, 0x05, + 0x15, 0xd8, 0xbd, 0x46, 0x21, 0x26, 0x57, 0x45, 0x40, 0x3f, 0x58, 0xd1, + 0xf2, 0xf2, 0xbe, 0xd1, 0xd7, 0x1f, 0x0e, 0x4f, 0xf7, 0x5a, 0xf8, 0xb0, + 0x15, 0xfb, 0x20, 0xfd, 0x8a, 0xf7, 0x20, 0xf7, 0xae, 0x06, 0xad, 0x4f, + 0xbb, 0x6f, 0xcf, 0x8b, 0xf7, 0x16, 0x8b, 0xeb, 0xf7, 0x0e, 0x8b, 0xf7, + 0x38, 0x8b, 0xd7, 0x75, 0xd7, 0x67, 0xbd, 0x08, 0x67, 0xbe, 0x48, 0xad, + 0x4a, 0x8b, 0x47, 0x8b, 0x5b, 0x6e, 0x69, 0x4f, 0x08, 0xdb, 0x07, 0xf7, + 0x0a, 0xfb, 0x00, 0x15, 0xd2, 0xba, 0x46, 0x24, 0x29, 0x5a, 0x46, 0x46, + 0x45, 0x5b, 0xcf, 0xf0, 0x1f, 0xf0, 0xbb, 0xd0, 0xd1, 0x1e, 0x0e, 0x4f, + 0xf8, 0x28, 0xf8, 0xb0, 0x15, 0x3b, 0x07, 0x6a, 0xc6, 0x59, 0xa9, 0x48, + 0x8b, 0xfb, 0x16, 0x8b, 0x2b, 0xfb, 0x0e, 0x8b, 0xfb, 0x39, 0x8b, 0x3f, + 0xa1, 0x3f, 0xaf, 0x5a, 0xaf, 0x58, 0xce, 0x69, 0xcb, 0x8b, 0xcf, 0x8b, + 0xbd, 0xa8, 0xac, 0xc6, 0x08, 0xfb, 0xae, 0xf7, 0x20, 0x07, 0xf9, 0x8a, + 0x07, 0xfb, 0x20, 0x06, 0xfb, 0x0a, 0xfb, 0x00, 0x15, 0xd2, 0xba, 0x47, + 0x22, 0x29, 0x5b, 0x47, 0x45, 0x45, 0x5b, 0xcf, 0xf0, 0x1f, 0xf0, 0xbb, + 0xd0, 0xd1, 0x1e, 0x0e, 0xfb, 0xae, 0xca, 0xf8, 0xb0, 0x15, 0xfc, 0xb0, + 0xf7, 0x20, 0xf7, 0xb3, 0x07, 0xdd, 0xb4, 0xb4, 0xdd, 0x1e, 0x9a, 0x8b, + 0x95, 0x8a, 0x9e, 0x88, 0x08, 0xf7, 0x22, 0x07, 0x83, 0x8c, 0x86, 0x8b, + 0x87, 0x8b, 0x4b, 0x8b, 0x53, 0x61, 0x6d, 0x42, 0x08, 0xf5, 0x07, 0xfb, + 0x20, 0x06, 0x0e, 0xf8, 0x8d, 0xf8, 0x02, 0x15, 0x89, 0xf7, 0x06, 0x33, + 0xd0, 0xfb, 0x25, 0x8b, 0xfb, 0x1d, 0x8b, 0x36, 0x46, 0x8b, 0xfb, 0x03, + 0x8b, 0x67, 0x96, 0x6c, 0x9e, 0x76, 0x9e, 0x78, 0x9c, 0x82, 0xbf, 0x7a, + 0x08, 0xf7, 0x3b, 0x57, 0x05, 0xae, 0x80, 0x97, 0x80, 0x8b, 0x75, 0x8b, + 0x6a, 0x64, 0x77, 0x4a, 0x8b, 0x67, 0x8b, 0x6e, 0x92, 0x79, 0x97, 0x7c, + 0x96, 0x85, 0x96, 0x85, 0xa8, 0x08, 0xfb, 0x1d, 0x06, 0x8f, 0xfb, 0x0a, + 0xe2, 0x4d, 0xf7, 0x38, 0x8b, 0xd6, 0x8b, 0xc4, 0x9b, 0xb3, 0xab, 0xb3, + 0xab, 0xa3, 0xbd, 0x8b, 0xc0, 0x8b, 0xd1, 0x68, 0xb8, 0x44, 0xa0, 0x08, + 0xfb, 0x45, 0xbe, 0x05, 0x64, 0x97, 0x81, 0x93, 0x8b, 0xa1, 0x8b, 0xa9, + 0xab, 0x9f, 0xbc, 0x8b, 0xce, 0x8b, 0xac, 0x73, 0x8c, 0x5a, 0x08, 0xf7, + 0x1b, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0xc1, 0xf8, 0xa5, 0x15, 0x3d, 0xf7, + 0x25, 0xfb, 0x20, 0xfb, 0x25, 0x46, 0x2e, 0xd0, 0xfb, 0xe0, 0x06, 0x36, + 0xb8, 0x61, 0xe7, 0x1e, 0xaa, 0x8b, 0xa4, 0x8e, 0xa4, 0x93, 0x08, 0xed, + 0x07, 0x7d, 0x89, 0x83, 0x8a, 0x81, 0x8b, 0x08, 0x66, 0x82, 0x96, 0xbb, + 0x1f, 0xf7, 0xba, 0xd9, 0xe8, 0x07, 0x0e, 0x4f, 0xf8, 0xb1, 0x16, 0xf8, + 0xb0, 0xfb, 0x20, 0xfb, 0xe6, 0x07, 0x4b, 0x5e, 0x61, 0x47, 0x4f, 0x6d, + 0xab, 0xcc, 0x1e, 0xf7, 0xef, 0xfb, 0x20, 0xfc, 0x0c, 0x07, 0xfb, 0x0b, + 0xcd, 0x47, 0xf7, 0x07, 0x1e, 0xd4, 0x8b, 0xbc, 0xa6, 0xb3, 0xc7, 0x08, + 0x4b, 0x07, 0xf7, 0x20, 0x06, 0x0e, 0xf7, 0xf2, 0x16, 0xf7, 0x4e, 0xf8, + 0xb0, 0xfb, 0x28, 0x8b, 0xfb, 0x01, 0xfc, 0x1f, 0xfb, 0x09, 0xf8, 0x1f, + 0xfb, 0x28, 0x8b, 0xf7, 0x51, 0xfc, 0xb0, 0xf7, 0x27, 0x8b, 0x05, 0x0e, + 0xf6, 0xf8, 0xf9, 0x16, 0xf7, 0x2d, 0xf8, 0xb0, 0xfb, 0x25, 0x8b, 0x39, + 0xfc, 0x0e, 0x3a, 0xf8, 0x0e, 0xfb, 0x20, 0x8b, 0x39, 0xfc, 0x0e, 0x35, + 0xf8, 0x0e, 0xfb, 0x25, 0x8b, 0xf7, 0x2c, 0xfc, 0xb0, 0xf7, 0x24, 0x8b, + 0xe1, 0xf8, 0x11, 0xdc, 0xfc, 0x11, 0xf7, 0x25, 0x8b, 0x05, 0x0e, 0xf7, + 0xf7, 0xf7, 0xa4, 0x15, 0xf7, 0x44, 0xf7, 0xa0, 0xfb, 0x3c, 0x8b, 0x34, + 0xfb, 0x37, 0x33, 0xf7, 0x37, 0xfb, 0x3c, 0x8b, 0xf7, 0x44, 0xfb, 0xa0, + 0xfb, 0x48, 0xfb, 0xa4, 0xf7, 0x3c, 0x8b, 0xe7, 0xf7, 0x3c, 0xe6, 0xfb, + 0x3c, 0xf7, 0x3c, 0x8b, 0xfb, 0x48, 0xf7, 0xa4, 0x05, 0x0e, 0xf8, 0x1e, + 0xf8, 0xb0, 0x15, 0xfb, 0x04, 0xfc, 0x1d, 0xfb, 0x0b, 0xf8, 0x1d, 0xfb, + 0x2e, 0x8b, 0xf7, 0x5d, 0xfc, 0xc6, 0x8b, 0x8a, 0x8b, 0x88, 0x05, 0x58, + 0x65, 0x64, 0x5a, 0x1e, 0x80, 0x8b, 0x83, 0x8c, 0x79, 0x90, 0x08, 0x22, + 0x07, 0xa0, 0x88, 0x97, 0x8a, 0x9c, 0x8b, 0xae, 0x8b, 0xb5, 0x92, 0xa3, + 0x95, 0xb2, 0x9b, 0x9c, 0xa2, 0xa2, 0xcb, 0x08, 0xf7, 0x72, 0xf9, 0x13, + 0xfb, 0x24, 0x8b, 0x05, 0x0e, 0xfb, 0x3f, 0xf8, 0x5f, 0xf8, 0xb0, 0x15, + 0xfc, 0x38, 0xfb, 0x05, 0xf7, 0x8d, 0x06, 0xfb, 0x9f, 0xfb, 0xce, 0x8b, + 0xfb, 0x05, 0xf8, 0x53, 0x8b, 0x8b, 0xf7, 0x05, 0xfb, 0xa6, 0x8b, 0xf7, + 0x9d, 0xf7, 0xce, 0x8b, 0xf7, 0x05, 0x05, 0x0e, 0xfb, 0xae, 0xf7, 0xd1, + 0xf9, 0x6d, 0x15, 0x3f, 0x06, 0x43, 0x58, 0x51, 0x39, 0x1f, 0xfb, 0x67, + 0x07, 0x8b, 0x60, 0x77, 0x78, 0x5e, 0x8a, 0x08, 0x7f, 0x8b, 0x87, 0x8b, + 0x8b, 0x2f, 0x8f, 0x8a, 0x05, 0xa7, 0x8b, 0x92, 0x8a, 0x96, 0x87, 0xa2, + 0x80, 0x93, 0x7b, 0x8b, 0x63, 0x08, 0xfb, 0x66, 0x07, 0x39, 0xbe, 0x51, + 0xd3, 0x1e, 0xd7, 0xee, 0x66, 0x06, 0x69, 0x80, 0x9b, 0xbc, 0x1f, 0xf7, + 0x57, 0x07, 0x8b, 0xd4, 0x75, 0xa4, 0x40, 0x97, 0xd6, 0x96, 0xa1, 0xa4, + 0x8b, 0xd4, 0x08, 0xf7, 0x57, 0x07, 0xb3, 0x99, 0x9c, 0xaa, 0x1e, 0xb0, + 0xee, 0x06, 0x0e, 0xfc, 0x1b, 0xf7, 0x48, 0xf9, 0x6d, 0x15, 0x3b, 0xfe, + 0x35, 0xdb, 0xfa, 0x35, 0x06, 0x0e, 0xfb, 0xae, 0xd3, 0xfb, 0x5c, 0x15, + 0xd7, 0x06, 0xd3, 0xbe, 0xc5, 0xdd, 0x1f, 0xf7, 0x67, 0x07, 0x8b, 0xb6, + 0x9f, 0x9e, 0xb8, 0x8c, 0x08, 0x97, 0x8b, 0x8f, 0x8b, 0x8b, 0xe7, 0x87, + 0x8c, 0x05, 0x6f, 0x8b, 0x84, 0x8c, 0x80, 0x8f, 0x74, 0x96, 0x83, 0x9b, + 0x8b, 0xb3, 0x08, 0xf7, 0x66, 0x07, 0xdd, 0x58, 0xc5, 0x43, 0x1e, 0x3f, + 0x28, 0xb0, 0x06, 0xad, 0x96, 0x7b, 0x5a, 0x1f, 0xfb, 0x57, 0x07, 0x8b, + 0x42, 0xa1, 0x72, 0xd6, 0x7f, 0x40, 0x80, 0x75, 0x72, 0x8b, 0x42, 0x08, + 0xfb, 0x57, 0x07, 0x63, 0x7d, 0x7a, 0x6c, 0x1e, 0x66, 0x28, 0x06, 0x0e, + 0x34, 0xf8, 0x4d, 0xf7, 0xb4, 0x15, 0x8a, 0x70, 0x8a, 0x87, 0x88, 0x83, + 0x83, 0x79, 0x7b, 0x82, 0x73, 0x8b, 0x76, 0x8b, 0x7d, 0x91, 0x71, 0x9e, + 0x08, 0x52, 0xb5, 0x05, 0x73, 0x9c, 0x71, 0x93, 0x6a, 0x8b, 0x3c, 0x8b, + 0x60, 0x5b, 0x86, 0x2a, 0x08, 0xd9, 0x06, 0x8c, 0xa5, 0x8c, 0x8f, 0x8e, + 0x93, 0x93, 0x9d, 0x9b, 0x94, 0xa3, 0x8b, 0xa0, 0x8b, 0x9c, 0x84, 0xa2, + 0x7a, 0x08, 0xc4, 0x61, 0x05, 0xa5, 0x79, 0xa3, 0x83, 0xac, 0x8b, 0xdb, + 0x8b, 0xb4, 0xbb, 0x91, 0xed, 0x08, 0x3d, 0x06, 0x0e, 0xfb, 0xe6, 0xcd, + 0xfb, 0x4e, 0x15, 0xf7, 0x2a, 0xf7, 0x66, 0x06, 0x62, 0xf7, 0xc9, 0x48, + 0x8b, 0x61, 0xfb, 0xc9, 0x8b, 0xfb, 0x66, 0x05, 0xf8, 0xd8, 0x04, 0xf7, + 0x2a, 0xf7, 0x26, 0xfb, 0x2a, 0xfb, 0x26, 0x06, 0x0e, 0xf7, 0xc3, 0xf8, + 0x47, 0x15, 0xba, 0x84, 0xa4, 0x6f, 0x98, 0x4d, 0x08, 0xf7, 0x1a, 0x06, + 0x83, 0xf7, 0x10, 0x33, 0xe0, 0xfb, 0x0f, 0x8d, 0x08, 0xe0, 0x5f, 0x35, + 0x07, 0xfb, 0x25, 0x7c, 0x3d, 0x25, 0x8b, 0xfb, 0x40, 0x8b, 0xfb, 0x3a, + 0xdf, 0x21, 0xf7, 0x1f, 0x82, 0x08, 0x25, 0xb7, 0xf0, 0x07, 0xf7, 0x0b, + 0x90, 0xe4, 0xe0, 0x96, 0xf7, 0x0c, 0x08, 0xfb, 0x1a, 0x06, 0x7c, 0x4e, + 0x73, 0x6f, 0x5d, 0x84, 0x08, 0xf7, 0xec, 0x07, 0x5f, 0xfb, 0xe9, 0x15, + 0x55, 0x9b, 0x6e, 0xc4, 0x8b, 0xe8, 0x8b, 0xee, 0xa8, 0xc7, 0xc1, 0x99, + 0x08, 0xfb, 0xe7, 0x07, 0x0e, 0xf8, 0x0b, 0xf8, 0x07, 0x15, 0xfb, 0x1f, + 0x06, 0x85, 0x9a, 0x84, 0x9a, 0x7a, 0xae, 0x73, 0xbc, 0x88, 0x93, 0x8b, + 0x9f, 0x8b, 0xc0, 0xb4, 0xb1, 0xc4, 0x8b, 0xa9, 0x8b, 0xa6, 0x82, 0x9f, + 0x79, 0xa0, 0x79, 0x93, 0x79, 0x91, 0x5d, 0x08, 0x8c, 0x80, 0xf7, 0x18, + 0x8b, 0x05, 0x86, 0xc6, 0x83, 0xac, 0x7c, 0xa8, 0x67, 0xd2, 0x3d, 0xb2, + 0x23, 0x8b, 0x48, 0x8b, 0x54, 0x7a, 0x61, 0x6b, 0x5d, 0x66, 0x6f, 0x52, + 0x8b, 0x53, 0x8b, 0x5f, 0x93, 0x75, 0xb8, 0x3c, 0x08, 0x4f, 0x54, 0xe4, + 0x06, 0x9b, 0x64, 0x90, 0x76, 0x8b, 0x72, 0x8b, 0x51, 0x71, 0x67, 0x37, + 0x52, 0x08, 0xc2, 0x26, 0x05, 0xb7, 0xa1, 0xa6, 0x93, 0xb1, 0x8b, 0xa5, + 0x8b, 0xa3, 0x87, 0xbb, 0x7f, 0x08, 0xbd, 0x7f, 0xa1, 0x87, 0xa6, 0x8b, + 0xbc, 0x8b, 0xb3, 0x97, 0xc3, 0xac, 0x08, 0x62, 0xf7, 0x01, 0x05, 0x63, + 0x77, 0x6b, 0x82, 0x6a, 0x8b, 0x7a, 0x8b, 0x77, 0x8e, 0x71, 0x92, 0x08, + 0x64, 0x95, 0x83, 0x8c, 0x7a, 0x8b, 0x6e, 0x8b, 0x77, 0x84, 0x4c, 0x6d, + 0xe0, 0xce, 0xaa, 0xb9, 0x8b, 0xc5, 0x8b, 0x9f, 0x88, 0x98, 0x7f, 0xa5, + 0x08, 0xf7, 0x0e, 0x06, 0xc2, 0x07, 0x0e, 0xfc, 0x8c, 0xf7, 0x8e, 0xf9, + 0x5f, 0x15, 0xfc, 0x3b, 0xfd, 0x73, 0xe2, 0x8b, 0xf8, 0x3b, 0xf9, 0x73, + 0x34, 0x8b, 0x05, 0x0e, 0xf8, 0x85, 0xf7, 0xf3, 0x15, 0xfb, 0x1d, 0x8b, + 0xf7, 0x54, 0xf7, 0xf5, 0xfb, 0x1b, 0x8b, 0xfb, 0x1a, 0xfb, 0x92, 0xfb, + 0x1f, 0xf7, 0x92, 0xfb, 0x1f, 0x8b, 0xf7, 0x5f, 0xfb, 0xf5, 0xfb, 0x1e, + 0x8b, 0x8b, 0x50, 0xf7, 0x25, 0x8b, 0x8b, 0x56, 0xfb, 0x25, 0x8b, 0x8b, + 0x50, 0xf7, 0x25, 0x8b, 0x8b, 0xfb, 0x48, 0x05, 0xf7, 0x20, 0xf7, 0x48, + 0xf7, 0x22, 0xc6, 0xfb, 0x22, 0xc0, 0xf7, 0x22, 0xc6, 0x06, 0x0e, 0xf8, + 0x88, 0xf8, 0x74, 0x15, 0xfb, 0x0f, 0x8b, 0x92, 0xb4, 0x05, 0x97, 0xd3, + 0xa3, 0xae, 0xb3, 0x8b, 0x9b, 0x8b, 0x95, 0x88, 0xa8, 0x7e, 0x08, 0x9f, + 0xf7, 0x07, 0x05, 0x60, 0x98, 0x75, 0x8f, 0x6c, 0x8b, 0x22, 0x8b, 0x51, + 0x4c, 0x74, 0xfb, 0x22, 0x08, 0x80, 0x50, 0xfb, 0x1e, 0x8b, 0x8b, 0x2a, + 0xf7, 0x0f, 0x8b, 0x4f, 0xfc, 0x0c, 0x05, 0x7e, 0x38, 0x7a, 0x6f, 0x68, + 0x8b, 0x7b, 0x8b, 0x7b, 0x91, 0x72, 0x9a, 0x08, 0x73, 0xfb, 0x07, 0x05, + 0xaa, 0x7b, 0xa6, 0x85, 0xab, 0x8b, 0xbc, 0x8b, 0xb9, 0x9d, 0xa9, 0xa9, + 0xad, 0xad, 0xa0, 0xc1, 0x98, 0xe0, 0x08, 0xc6, 0xf8, 0x12, 0xf7, 0x1d, + 0x8b, 0x8b, 0xec, 0x05, 0x0e, 0xf8, 0x6d, 0xf8, 0xb4, 0x15, 0x89, 0xbc, + 0x84, 0xa5, 0x7a, 0xa7, 0x6c, 0xba, 0x4a, 0xa8, 0x3d, 0x8b, 0xfb, 0x0d, + 0x8b, 0x33, 0x43, 0x8b, 0x27, 0x8b, 0x6c, 0x95, 0x6a, 0x9c, 0x75, 0x91, + 0x82, 0x8e, 0x88, 0xa4, 0x72, 0x08, 0x44, 0x55, 0x76, 0x6a, 0x8b, 0x4f, + 0x8b, 0x54, 0xa7, 0x5c, 0xbe, 0x6d, 0x08, 0xf7, 0x3f, 0x27, 0x05, 0xb5, + 0x74, 0x8b, 0x8b, 0x95, 0x81, 0x96, 0x80, 0x92, 0x7b, 0x8b, 0x79, 0x8b, + 0x67, 0x6c, 0x72, 0x5e, 0x8b, 0x72, 0x8b, 0x74, 0x93, 0x7d, 0x99, 0x7e, + 0x97, 0x87, 0x99, 0x89, 0xab, 0x08, 0x95, 0xfb, 0x17, 0x07, 0x8c, 0xfb, + 0x19, 0xd2, 0x47, 0xf7, 0x1f, 0x8b, 0xf7, 0x16, 0x8b, 0xe3, 0xd8, 0x8b, + 0xf7, 0x06, 0x8b, 0xc4, 0x74, 0xb7, 0x5c, 0xac, 0x08, 0xce, 0xaa, 0xa6, + 0xb3, 0x8b, 0xce, 0x8b, 0xcf, 0x6c, 0xbb, 0x49, 0xb0, 0x08, 0xfb, 0x13, + 0xd1, 0x05, 0x44, 0xb2, 0x78, 0x9d, 0x8b, 0xa7, 0x8b, 0xaa, 0xa5, 0x9f, + 0xb1, 0x8b, 0xba, 0x8b, 0xa3, 0x73, 0x92, 0x56, 0x08, 0xf7, 0x13, 0x06, + 0xfb, 0x1c, 0xfb, 0x82, 0x15, 0xba, 0x72, 0x99, 0x7a, 0x8b, 0x6b, 0x8b, + 0x74, 0x7f, 0x79, 0x69, 0x73, 0x08, 0xfb, 0x27, 0xdb, 0x05, 0x63, 0xa1, + 0x7e, 0x9c, 0x8b, 0xaa, 0x8b, 0xa8, 0x97, 0x9d, 0xa9, 0x9d, 0x08, 0xf7, + 0x23, 0x3f, 0x05, 0x0e, 0xf8, 0x18, 0xf8, 0xa4, 0x15, 0x6e, 0x9d, 0x62, + 0x97, 0x66, 0x8b, 0x66, 0x8b, 0x62, 0x7f, 0x6c, 0x78, 0x08, 0x3e, 0xd8, + 0x46, 0x47, 0xda, 0x3c, 0x05, 0x78, 0x6d, 0x81, 0x66, 0x8b, 0x65, 0x8b, + 0x65, 0x93, 0x6f, 0xa1, 0x63, 0x08, 0x3d, 0x3e, 0xcf, 0x46, 0xda, 0xd9, + 0x05, 0xa5, 0x78, 0xb8, 0x7f, 0xb3, 0x8b, 0xaf, 0x8b, 0x9d, 0x90, 0xb9, + 0xa4, 0x08, 0xd6, 0x40, 0xd0, 0xcf, 0x3e, 0xd7, 0x05, 0x9f, 0xae, 0x94, + 0xad, 0x8b, 0xb2, 0x8b, 0xb1, 0x84, 0xa4, 0x77, 0xb3, 0x08, 0xd6, 0xd6, + 0x46, 0xd0, 0x42, 0x42, 0x05, 0xfb, 0x00, 0x47, 0x15, 0xc5, 0xbb, 0x5a, + 0x51, 0x4f, 0x5b, 0x5b, 0x50, 0x50, 0x5b, 0xbb, 0xc6, 0xc8, 0xbb, 0xba, + 0xc7, 0x1f, 0x0e, 0xfc, 0x45, 0xf7, 0x50, 0xf9, 0x6d, 0x15, 0xfb, 0x1e, + 0xfb, 0x16, 0x06, 0xb3, 0xfb, 0x15, 0xc3, 0x8b, 0xb5, 0xf7, 0x15, 0x8b, + 0xf7, 0x16, 0x05, 0x0e, 0xfb, 0x3f, 0xf7, 0x62, 0xf8, 0x69, 0x15, 0xf7, + 0x11, 0x3b, 0x07, 0x89, 0xbd, 0xa5, 0xa8, 0xc3, 0x95, 0x08, 0xb9, 0x07, + 0x69, 0x89, 0x6b, 0x7f, 0x73, 0x77, 0x6b, 0x70, 0x7e, 0x6a, 0x8b, 0x52, + 0x08, 0xfb, 0x01, 0xf7, 0x1b, 0x07, 0xf7, 0x77, 0x16, 0xf7, 0x11, 0x3b, + 0x07, 0x89, 0xbd, 0xa5, 0xa8, 0xc3, 0x95, 0x08, 0xb9, 0x07, 0x69, 0x89, + 0x6b, 0x7f, 0x73, 0x77, 0x6b, 0x70, 0x7e, 0x6a, 0x8b, 0x52, 0x08, 0xfb, + 0x01, 0xf7, 0x1b, 0x07, 0x0e, 0xe3, 0xf7, 0x6e, 0x15, 0xf7, 0x3b, 0xfb, + 0x26, 0x8b, 0xf7, 0x06, 0x26, 0xe4, 0xf0, 0xe4, 0x8b, 0xf7, 0x09, 0xfb, + 0x3b, 0xfb, 0x29, 0x8b, 0xfb, 0x06, 0x05, 0xf7, 0x69, 0x16, 0xf7, 0x3b, + 0xfb, 0x26, 0x8b, 0xf7, 0x06, 0x26, 0xe4, 0xf0, 0xe4, 0x8b, 0xf7, 0x09, + 0xfb, 0x3b, 0xfb, 0x29, 0x8b, 0xfb, 0x06, 0x05, 0x0e, 0xfb, 0xe6, 0xde, + 0xf7, 0x6e, 0x15, 0xf7, 0x3b, 0xfb, 0x26, 0x8b, 0xf7, 0x06, 0x26, 0xe4, + 0xf0, 0xe4, 0x8b, 0xf7, 0x09, 0xfb, 0x3b, 0xfb, 0x29, 0x8b, 0xfb, 0x06, + 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0x8b, 0xf7, 0xe3, 0x15, 0xfb, 0x3b, 0xf7, + 0x26, 0x8b, 0xfb, 0x06, 0xf0, 0x32, 0x26, 0x32, 0x8b, 0xfb, 0x09, 0xf7, + 0x3b, 0xf7, 0x28, 0x8b, 0xf7, 0x07, 0x05, 0x0e, 0x4f, 0xf8, 0xb8, 0xf8, + 0xb0, 0x15, 0xfb, 0x20, 0xfc, 0xb0, 0xf7, 0x20, 0x06, 0xf8, 0xb0, 0x07, + 0xf7, 0x51, 0x04, 0xfb, 0x20, 0xfb, 0x11, 0xf7, 0x20, 0xf7, 0x11, 0x06, + 0xfb, 0x84, 0xfb, 0x5c, 0x15, 0x38, 0xc0, 0x06, 0xa7, 0x97, 0x99, 0xa5, + 0x1e, 0x97, 0x8b, 0x9b, 0x8a, 0x97, 0x89, 0x08, 0xf4, 0x07, 0x71, 0x8d, + 0x68, 0x8c, 0x78, 0x8b, 0x08, 0x2e, 0x5e, 0x5f, 0x30, 0x1f, 0x4a, 0x3f, + 0x2e, 0xd7, 0xfc, 0x48, 0xf7, 0x20, 0xf8, 0x48, 0xde, 0x07, 0xe8, 0x07, + 0x0e, 0x4f, 0xf8, 0xb6, 0xf9, 0x6d, 0x15, 0xfb, 0x20, 0xfd, 0x6d, 0xf7, + 0x20, 0x06, 0xf9, 0x6d, 0x07, 0xfb, 0x7f, 0xfb, 0x5c, 0x15, 0x38, 0xc0, + 0x06, 0xa7, 0x97, 0x99, 0xa5, 0x1e, 0x97, 0x8b, 0x9b, 0x8a, 0x97, 0x89, + 0x08, 0xf4, 0x07, 0x71, 0x8d, 0x68, 0x8c, 0x78, 0x8b, 0x08, 0x2e, 0x5e, + 0x5f, 0x30, 0x1f, 0x4a, 0x3f, 0x2e, 0xd7, 0xfc, 0x48, 0xf7, 0x20, 0xf8, + 0x48, 0xde, 0xe8, 0x07, 0x0e, 0xf8, 0xc1, 0xf7, 0xcb, 0x15, 0xfc, 0xca, + 0x23, 0xf8, 0xca, 0xf3, 0x06, 0x0e, 0xf8, 0x9f, 0xf8, 0x79, 0x15, 0xfb, + 0x47, 0xf7, 0x74, 0xfb, 0x1a, 0xfb, 0x74, 0xfb, 0x47, 0xfb, 0x08, 0xf7, + 0x47, 0xfc, 0xc7, 0xf7, 0x1a, 0xf8, 0xc7, 0xf7, 0x47, 0xf7, 0x08, 0x06, + 0x0e, 0xf8, 0x9c, 0xf8, 0x79, 0x15, 0xfb, 0x47, 0xf7, 0x74, 0xfb, 0x1a, + 0xfb, 0x74, 0xfb, 0x47, 0xfb, 0x08, 0xf7, 0x47, 0xfb, 0x73, 0xfb, 0x47, + 0xfb, 0x08, 0xf7, 0x47, 0xfb, 0x74, 0xf7, 0x1a, 0xf7, 0x74, 0xf7, 0x47, + 0x06, 0xf7, 0x08, 0xfb, 0x47, 0xf7, 0x73, 0xf7, 0x47, 0xf7, 0x08, 0x07, + 0x0e, 0xfc, 0x1d, 0xcb, 0xf7, 0xb8, 0x15, 0xfb, 0x0f, 0xf7, 0x10, 0xf7, + 0x0f, 0xfb, 0x10, 0x07, 0x0e, 0xf8, 0xa5, 0xf9, 0x6d, 0x15, 0xfb, 0xc3, + 0x06, 0x4a, 0x8b, 0x57, 0x71, 0x64, 0x56, 0x6a, 0x5f, 0x79, 0x53, 0x8b, + 0x54, 0x8b, 0xfb, 0x14, 0xe0, 0x2d, 0xf7, 0x0f, 0x85, 0x08, 0xfc, 0x5e, + 0xed, 0xf9, 0xe4, 0xca, 0xfd, 0xe4, 0xed, 0xf9, 0xe4, 0xb6, 0xd3, 0x07, + 0x0e, 0xfb, 0xd5, 0xf7, 0x45, 0xf8, 0x3d, 0x15, 0x44, 0x53, 0x54, 0x45, + 0x46, 0xc3, 0x53, 0xd0, 0xd0, 0xc3, 0xc3, 0xd0, 0xcf, 0x53, 0xc4, 0x48, + 0x1f, 0x0e, 0xfc, 0x1d, 0xcd, 0xf7, 0x11, 0x15, 0xfb, 0x11, 0xdb, 0x07, + 0x8d, 0x59, 0x71, 0x6e, 0x53, 0x81, 0x08, 0x5d, 0x07, 0xad, 0x8d, 0xab, + 0x97, 0xa3, 0x9f, 0xab, 0xa6, 0x98, 0xac, 0x8b, 0xc4, 0x08, 0xf7, 0x01, + 0xfb, 0x1b, 0x07, 0x0e, 0xfb, 0x3f, 0xd3, 0xf7, 0x11, 0x15, 0xfb, 0x11, + 0xdb, 0x07, 0x8d, 0x59, 0x71, 0x6e, 0x53, 0x81, 0x08, 0x5d, 0x07, 0xad, + 0x8d, 0xab, 0x97, 0xa3, 0x9f, 0xab, 0xa6, 0x98, 0xac, 0x8b, 0xc4, 0x08, + 0xf7, 0x01, 0xfb, 0x1b, 0x07, 0xf7, 0x75, 0x16, 0xfb, 0x11, 0xdb, 0x07, + 0x8d, 0x59, 0x71, 0x6e, 0x53, 0x81, 0x08, 0x5d, 0x07, 0xad, 0x8d, 0xab, + 0x97, 0xa3, 0x9f, 0xab, 0xa6, 0x98, 0xac, 0x8b, 0xc4, 0x08, 0xf7, 0x01, + 0xfb, 0x1b, 0x07, 0x0e, 0xfb, 0x3f, 0xd4, 0xf9, 0x6d, 0x15, 0xfb, 0x11, + 0xdb, 0x07, 0x8d, 0x59, 0x71, 0x6e, 0x53, 0x81, 0x08, 0x5d, 0x07, 0xad, + 0x8d, 0xab, 0x97, 0xa3, 0x9f, 0xab, 0xa6, 0x98, 0xac, 0x8b, 0xc4, 0x08, + 0xf7, 0x01, 0xfb, 0x1b, 0x07, 0xf7, 0x7c, 0x16, 0xfb, 0x11, 0xdb, 0x07, + 0x8d, 0x59, 0x71, 0x6e, 0x53, 0x81, 0x08, 0x5d, 0x07, 0xad, 0x8d, 0xab, + 0x97, 0xa3, 0x9f, 0xab, 0xa6, 0x98, 0xac, 0x8b, 0xc4, 0x08, 0xf7, 0x01, + 0xfb, 0x1b, 0x07, 0x0e, 0xf7, 0x93, 0xf7, 0xe3, 0x15, 0xfb, 0x3b, 0xf7, + 0x26, 0x8b, 0xfb, 0x06, 0xf0, 0x32, 0x26, 0x32, 0x8b, 0xfb, 0x09, 0xf7, + 0x3b, 0xf7, 0x28, 0x8b, 0xf7, 0x07, 0x05, 0xf7, 0x63, 0x16, 0xfb, 0x3b, + 0xf7, 0x26, 0x8b, 0xfb, 0x06, 0xf0, 0x32, 0x26, 0x32, 0x8b, 0xfb, 0x09, + 0xf7, 0x3b, 0xf7, 0x28, 0x8b, 0xf7, 0x07, 0x05, 0x0e, 0xf7, 0xdd, 0xf7, + 0x86, 0xf7, 0x26, 0x15, 0xfb, 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, 0x26, + 0x06, 0xf7, 0xe1, 0x16, 0xfb, 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, 0x26, + 0x06, 0xf7, 0xe1, 0x16, 0xfb, 0x2a, 0xfb, 0x26, 0xf7, 0x2a, 0xf7, 0x26, + 0x06, 0x0e, 0xf7, 0xdd, 0xf7, 0x34, 0xf9, 0x77, 0x15, 0x39, 0x48, 0x48, + 0x3a, 0x3a, 0xce, 0x48, 0xde, 0xdc, 0xcf, 0xce, 0xda, 0xdf, 0x49, 0xcd, + 0x37, 0x1f, 0x3b, 0x04, 0xb3, 0xaa, 0x6c, 0x64, 0x65, 0x6b, 0x6c, 0x64, + 0x65, 0x6b, 0xaa, 0xb2, 0xb1, 0xab, 0xaa, 0xb1, 0x1f, 0xf7, 0xe4, 0xda, + 0x15, 0xfc, 0x38, 0xfd, 0x8b, 0xcd, 0x8b, 0xf8, 0x39, 0xf9, 0x8b, 0x48, + 0x8b, 0x05, 0x72, 0xfc, 0x64, 0x15, 0x39, 0x48, 0x48, 0x3a, 0x39, 0xce, + 0x49, 0xde, 0xdc, 0xcf, 0xcd, 0xdb, 0xdf, 0x49, 0xcd, 0x37, 0x1f, 0x3b, + 0x04, 0xb3, 0xaa, 0x6c, 0x64, 0x65, 0x6b, 0x6c, 0x65, 0x64, 0x6b, 0xaa, + 0xb2, 0xb1, 0xab, 0xaa, 0xb1, 0x1f, 0xf8, 0x05, 0xdb, 0x15, 0x39, 0x48, + 0x48, 0x3a, 0x39, 0xce, 0x49, 0xde, 0xdc, 0xcf, 0xcd, 0xdb, 0xdf, 0x49, + 0xcd, 0x37, 0x1f, 0x3b, 0x04, 0xb3, 0xaa, 0x6c, 0x64, 0x65, 0x6b, 0x6c, + 0x65, 0x64, 0x6b, 0xaa, 0xb2, 0xb1, 0xab, 0xaa, 0xb1, 0x1f, 0x0e, 0x4f, + 0xf7, 0x83, 0xf7, 0xe7, 0x15, 0x8b, 0x4a, 0x84, 0x7f, 0x4f, 0x61, 0x2d, + 0x49, 0x70, 0x5f, 0x8b, 0x37, 0x8b, 0xfb, 0x1c, 0xf1, 0x2d, 0xf7, 0x28, + 0x8b, 0xe1, 0x8b, 0xce, 0xa9, 0xb6, 0xc6, 0xac, 0xb7, 0x98, 0xbb, 0x8c, + 0xdd, 0x08, 0xfb, 0x1c, 0x89, 0x06, 0x8f, 0x3a, 0x5b, 0x4d, 0x48, 0x8b, + 0x4f, 0x8b, 0x5e, 0xbd, 0x8b, 0xcc, 0x8b, 0xb8, 0x97, 0x9e, 0xc6, 0xbb, + 0xdb, 0xcf, 0xa2, 0xb8, 0x88, 0xe0, 0x08, 0xfb, 0x10, 0x06, 0x7b, 0xc2, + 0x15, 0xf7, 0x2a, 0xf7, 0x26, 0xfb, 0x2a, 0xfb, 0x26, 0x06, 0x0e, 0xfb, + 0xe6, 0x9c, 0xf9, 0x89, 0x15, 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, + 0xf7, 0x2a, 0xfb, 0x12, 0x8b, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0xd1, 0xf9, + 0x89, 0x15, 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, + 0xf7, 0x2a, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0x08, 0xf9, 0x89, 0x15, 0xfb, + 0x00, 0xfb, 0x2a, 0xd7, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd9, 0x8b, 0x24, + 0xf7, 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0xae, 0xf9, 0x81, + 0x15, 0x88, 0x6b, 0x7f, 0x7b, 0x76, 0x8b, 0x84, 0x8b, 0x77, 0x8e, 0x84, + 0x8e, 0x08, 0x44, 0xa4, 0x05, 0x67, 0x98, 0x8a, 0x8b, 0x78, 0x8b, 0x54, + 0x8b, 0x68, 0x5d, 0x87, 0x3d, 0x08, 0xca, 0x06, 0x90, 0xab, 0x96, 0x98, + 0xa3, 0x8b, 0x94, 0x8b, 0x94, 0x89, 0x97, 0x87, 0x08, 0xd2, 0x71, 0x05, + 0xa0, 0x83, 0x9e, 0x87, 0x9a, 0x8b, 0xc6, 0x8b, 0xab, 0xb5, 0x8f, 0xe0, + 0x08, 0x4c, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0xcf, 0xf9, 0x63, 0x15, 0xfb, + 0xbf, 0x3c, 0xf7, 0xbf, 0xda, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0xbf, 0xf9, + 0x80, 0x15, 0x53, 0x06, 0x83, 0x5d, 0x74, 0x77, 0x5f, 0x8b, 0x5d, 0x8b, + 0x72, 0xa1, 0x85, 0xb7, 0x08, 0x53, 0x81, 0x06, 0x3f, 0xc4, 0x52, 0xd6, + 0xd6, 0xc4, 0xc4, 0xd6, 0x1e, 0x96, 0x07, 0x0e, 0xfb, 0xe6, 0xf7, 0x72, + 0xf9, 0x7b, 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, + 0x0e, 0xfb, 0xe6, 0xf7, 0x14, 0xf9, 0x7b, 0x15, 0xfb, 0x02, 0xfb, 0x0e, + 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, + 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0x3c, 0xf9, 0x96, + 0x15, 0x58, 0x63, 0x63, 0x59, 0x59, 0xb3, 0x63, 0xbd, 0xbc, 0xb4, 0xb3, + 0xbc, 0xbe, 0x64, 0xb3, 0x59, 0x1f, 0x5b, 0x04, 0xa2, 0x9d, 0x78, 0x74, + 0x74, 0x78, 0x78, 0x75, 0x73, 0x78, 0x9e, 0xa2, 0xa2, 0x9e, 0x9e, 0xa3, + 0x1f, 0x0e, 0xfb, 0xe6, 0xf7, 0x36, 0x16, 0x55, 0x21, 0x05, 0x9e, 0x94, + 0x95, 0x8e, 0x9f, 0x8b, 0x08, 0xaa, 0x9f, 0x7d, 0x76, 0x74, 0x72, 0x79, + 0x6b, 0x1f, 0x6f, 0x8b, 0x73, 0x92, 0x56, 0xa2, 0x08, 0x78, 0x57, 0x05, + 0xcc, 0x75, 0xa8, 0x85, 0xb7, 0x8b, 0x08, 0xde, 0xb9, 0xac, 0xc7, 0xb7, + 0x6e, 0xa6, 0x5c, 0x1f, 0x7c, 0x8b, 0x7f, 0x89, 0x7c, 0x86, 0x08, 0xa8, + 0xca, 0x60, 0x8b, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0x2c, 0xf9, 0x89, 0x15, + 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x27, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x27, + 0x05, 0xf7, 0x50, 0x16, 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x27, 0xd1, 0x8b, + 0xf7, 0x12, 0xf7, 0x27, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0x3d, 0x16, 0x3e, + 0x6f, 0x5c, 0x57, 0x8b, 0x50, 0x8b, 0x51, 0xc2, 0x66, 0xe4, 0x8b, 0xa7, + 0x8b, 0xa3, 0x8e, 0xa6, 0x92, 0x08, 0xba, 0x07, 0x79, 0x87, 0x78, 0x89, + 0x77, 0x8b, 0x56, 0x8b, 0x74, 0x9b, 0x8b, 0xad, 0x8b, 0xbe, 0xa3, 0xa8, + 0xe0, 0xc0, 0x08, 0x40, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0x6f, 0xf8, 0xf3, + 0x15, 0xf7, 0x00, 0xf7, 0x2a, 0x3f, 0x8b, 0x39, 0x2a, 0x39, 0xec, 0x3d, + 0x8b, 0xf2, 0xfb, 0x2a, 0xf6, 0x8b, 0x05, 0x0e, 0xf7, 0xdd, 0xfa, 0x7f, + 0xf7, 0xcb, 0x15, 0xfe, 0x86, 0x23, 0xfa, 0x86, 0xf3, 0x06, 0x0e, 0xf7, + 0xdd, 0xf8, 0x42, 0xf7, 0x2c, 0x15, 0xfb, 0x2c, 0xf8, 0xac, 0xf7, 0x11, + 0xfc, 0x16, 0xf7, 0x51, 0xf7, 0xe7, 0xf7, 0x11, 0xfb, 0xe7, 0xf7, 0x39, + 0xf8, 0x02, 0xf7, 0x11, 0xfd, 0x3e, 0x07, 0xfb, 0x9b, 0xfd, 0x6d, 0xf7, + 0x2d, 0x8b, 0xc0, 0xf7, 0x2c, 0xf7, 0x73, 0x8b, 0x05, 0xf7, 0x11, 0x04, + 0xfb, 0x49, 0x8b, 0xf7, 0x06, 0xf7, 0xdb, 0xce, 0x8b, 0x8b, 0xfb, 0xdb, + 0x05, 0x0e, 0xfb, 0xc1, 0xf7, 0xd5, 0xf7, 0xe8, 0x15, 0xfb, 0xb0, 0x3d, + 0xf7, 0xb0, 0xd9, 0x06, 0x93, 0xd1, 0x15, 0x7b, 0x99, 0x87, 0x94, 0x8b, + 0x9c, 0x08, 0xf7, 0x47, 0x07, 0xcd, 0x5e, 0xad, 0x33, 0x1e, 0x33, 0x8b, + 0x5d, 0x65, 0x8a, 0x41, 0x08, 0xd9, 0x06, 0x8f, 0xab, 0x9a, 0x97, 0xb3, + 0x8b, 0xab, 0x8b, 0x9c, 0x80, 0x8b, 0x77, 0x8b, 0x81, 0x85, 0x81, 0x82, + 0x87, 0x80, 0x85, 0x8b, 0x8b, 0x62, 0x84, 0x08, 0x69, 0x85, 0x05, 0x4a, + 0x80, 0x6d, 0x6a, 0x8b, 0x50, 0x8b, 0x50, 0xb2, 0x64, 0xc6, 0x8b, 0xaf, + 0x8b, 0xad, 0x9b, 0xa7, 0xa9, 0x8c, 0x7b, 0x8c, 0x85, 0x93, 0x81, 0x08, + 0xe7, 0x95, 0x06, 0x25, 0xf7, 0x0c, 0x15, 0x5b, 0x73, 0x6f, 0x61, 0x6e, + 0x7a, 0x9a, 0xa3, 0x1e, 0x8b, 0xa4, 0x98, 0x97, 0xae, 0x92, 0x08, 0xa8, + 0x91, 0x05, 0xa1, 0x8f, 0x8e, 0x8c, 0x95, 0x90, 0x08, 0x74, 0x07, 0x0e, + 0x4f, 0xf7, 0x7a, 0xf8, 0x3b, 0x15, 0xf7, 0xc6, 0xfb, 0x2a, 0xfc, 0x13, + 0x07, 0x3b, 0x53, 0x8b, 0x32, 0xdb, 0xc3, 0x8b, 0xfb, 0x95, 0xf8, 0x99, + 0x8b, 0x8b, 0xf7, 0x11, 0xfc, 0x03, 0x8b, 0x8b, 0xf7, 0x65, 0xf7, 0x39, + 0xf7, 0x05, 0x8b, 0xe3, 0xfb, 0x39, 0xfb, 0x04, 0x05, 0x0e, 0xf6, 0xf7, + 0x39, 0xbf, 0x15, 0xc5, 0x59, 0xd6, 0x72, 0xe5, 0x8b, 0xf3, 0x8b, 0xdd, + 0xac, 0xca, 0xcf, 0xcc, 0xcf, 0xb1, 0xf3, 0x8b, 0xf6, 0x8b, 0xe7, 0x6f, + 0xe8, 0x5d, 0xca, 0x08, 0xe4, 0xee, 0x57, 0xb8, 0x38, 0x2f, 0x05, 0x48, + 0xc6, 0x45, 0xa4, 0x2c, 0x8b, 0x22, 0x8b, 0x39, 0x6a, 0x4c, 0x47, 0x49, + 0x46, 0x66, 0x24, 0x8b, 0xfb, 0x01, 0x8b, 0x29, 0xa6, 0x36, 0xc2, 0x41, + 0x08, 0x35, 0x2c, 0xbe, 0x5d, 0x05, 0xde, 0xe6, 0x05, 0xf8, 0x26, 0xf8, + 0x51, 0x15, 0x9a, 0x63, 0x93, 0x5a, 0x8b, 0x5c, 0x8b, 0xfb, 0x2f, 0x3b, + 0x26, 0xfb, 0x0e, 0x8b, 0x57, 0x8b, 0x5a, 0x9d, 0x6c, 0xa9, 0x08, 0xf7, + 0xcb, 0xf7, 0xec, 0x05, 0xfb, 0xf5, 0xfb, 0xb4, 0x15, 0x78, 0xb5, 0x81, + 0xbd, 0x8b, 0xc2, 0x8b, 0xf7, 0x30, 0xda, 0xf0, 0xf7, 0x10, 0x8b, 0xc3, + 0x8b, 0xba, 0x78, 0xb0, 0x64, 0x08, 0xfb, 0xce, 0xfb, 0xee, 0x05, 0x0e, + 0xf7, 0xdd, 0xf9, 0x04, 0xf7, 0xce, 0x15, 0xf7, 0xbf, 0xf7, 0x11, 0xfb, + 0xbf, 0xf7, 0x39, 0xf7, 0xdb, 0xf7, 0x11, 0xfc, 0x6b, 0x57, 0x06, 0x5b, + 0xba, 0x64, 0x9c, 0x4b, 0x8b, 0x08, 0xfb, 0x46, 0xfb, 0x0f, 0xfb, 0x31, + 0xfb, 0x75, 0xfb, 0x73, 0xf7, 0x10, 0xfb, 0x33, 0xf7, 0x41, 0x1f, 0xcf, + 0x8b, 0xb1, 0x9f, 0xbc, 0xc9, 0x08, 0x50, 0xf8, 0x7e, 0xf7, 0x11, 0xfb, + 0xee, 0x07, 0xf7, 0x51, 0x07, 0xfb, 0x2a, 0xfb, 0x1c, 0x15, 0x6e, 0x58, + 0x67, 0x75, 0x55, 0x8b, 0x08, 0x21, 0x44, 0xf1, 0xf7, 0x2c, 0xf7, 0x2d, + 0xd2, 0xf0, 0xf6, 0x1f, 0xc1, 0x8b, 0xae, 0x75, 0xa8, 0x58, 0x08, 0xfb, + 0xfe, 0x07, 0x0e, 0xfb, 0xc6, 0xf7, 0xe2, 0xf7, 0xe8, 0x15, 0xfb, 0xc1, + 0x3d, 0xf7, 0xc1, 0xd9, 0x06, 0xfb, 0x2b, 0xf8, 0x19, 0x15, 0x28, 0x4e, + 0x4a, 0x20, 0x21, 0xc8, 0x4a, 0xee, 0xed, 0xc9, 0xcc, 0xf3, 0xf7, 0x02, + 0x50, 0xcb, 0x26, 0x1f, 0x47, 0x04, 0xb9, 0xa9, 0x61, 0x4c, 0x4f, 0x6c, + 0x61, 0x5e, 0x5e, 0x6c, 0xb5, 0xc9, 0xc8, 0xaa, 0xb5, 0xb8, 0x1f, 0x0e, + 0xf7, 0x6e, 0xf9, 0x5c, 0xf7, 0x2c, 0x15, 0x7f, 0x64, 0x5f, 0x6e, 0x5b, + 0x8b, 0x64, 0x8b, 0x68, 0x9d, 0x77, 0xaa, 0x7c, 0xa2, 0x86, 0xa3, 0x8b, + 0xb9, 0x08, 0xf7, 0xfe, 0x06, 0x8c, 0x97, 0x8b, 0x92, 0x8b, 0x90, 0x8b, + 0xc1, 0x83, 0xbe, 0x7e, 0xb0, 0x66, 0xee, 0x35, 0xc5, 0xfb, 0x04, 0x8b, + 0x4e, 0x8b, 0x56, 0x7a, 0x62, 0x6a, 0x08, 0x65, 0xac, 0x50, 0x9c, 0x3d, + 0x8b, 0xfb, 0x29, 0x8b, 0x3e, 0x4c, 0x89, 0xfb, 0x10, 0x08, 0xf7, 0x17, + 0x06, 0x92, 0xc1, 0xa4, 0x9f, 0xca, 0x8b, 0xc4, 0x8b, 0xa7, 0x7a, 0x8b, + 0x67, 0x8b, 0x7b, 0x82, 0x7b, 0x7c, 0x83, 0x78, 0x81, 0x8b, 0x8b, 0x46, + 0x80, 0x08, 0x53, 0x81, 0x05, 0xfb, 0x00, 0x79, 0x58, 0x54, 0x8b, 0x29, + 0x8b, 0x26, 0xcc, 0x4b, 0xf2, 0x8b, 0xdc, 0x8b, 0xc9, 0xab, 0xc9, 0xd4, + 0x08, 0xb5, 0x47, 0xd1, 0x67, 0xe3, 0x8b, 0xf7, 0x0d, 0x8b, 0xed, 0xcf, + 0xaa, 0xf6, 0x08, 0xfb, 0x1e, 0x06, 0xfb, 0xfa, 0xcb, 0x15, 0x39, 0x64, + 0x5e, 0x43, 0x5c, 0x6e, 0xa4, 0xb4, 0x1e, 0x8b, 0xb4, 0xa6, 0xa4, 0xc0, + 0x92, 0x08, 0xbb, 0x92, 0x05, 0xa9, 0x90, 0x97, 0x8f, 0x9c, 0x95, 0x08, + 0x65, 0x07, 0xf7, 0x21, 0xf2, 0x15, 0x91, 0xdc, 0xb0, 0xb5, 0xcb, 0x8b, + 0xcc, 0x8b, 0xb0, 0x61, 0x92, 0x3a, 0x08, 0xfb, 0x6c, 0x06, 0x0e, 0xfc, + 0x1d, 0xf7, 0x63, 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0xfc, 0xb0, 0xf7, 0x20, + 0xf8, 0xb0, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, 0x58, 0xf8, 0x4e, 0x15, 0xf7, + 0xb3, 0xfb, 0x20, 0xfb, 0xf8, 0x07, 0x53, 0x63, 0x8b, 0x3c, 0xc3, 0xb3, + 0x8b, 0xfb, 0xba, 0xf7, 0x20, 0x8b, 0x8b, 0xf7, 0xff, 0xc3, 0xb3, 0x8b, + 0xda, 0x53, 0x63, 0x05, 0x0e, 0x4f, 0xf7, 0x12, 0xae, 0x15, 0xb3, 0x67, + 0xd0, 0x75, 0xd2, 0x8b, 0xf7, 0x39, 0x8b, 0xf1, 0xf7, 0x01, 0x8b, 0xf7, + 0x45, 0x8b, 0xd3, 0x7c, 0xc5, 0x6b, 0xbd, 0x08, 0xd3, 0xd4, 0x60, 0xb4, + 0x47, 0x45, 0x05, 0x58, 0xb5, 0x51, 0x9f, 0x42, 0x8b, 0xfb, 0x3b, 0x8b, + 0x25, 0xfb, 0x00, 0x8b, 0xfb, 0x46, 0x8b, 0x40, 0x9b, 0x4f, 0xad, 0x5a, + 0x08, 0x40, 0x3e, 0xb6, 0x63, 0x05, 0xd3, 0xd4, 0x05, 0xf7, 0xbb, 0xf7, + 0xc1, 0x15, 0x93, 0x73, 0x8f, 0x72, 0x8b, 0x70, 0x8b, 0x28, 0x56, 0x44, + 0x41, 0x8b, 0x6a, 0x8b, 0x6e, 0x99, 0x73, 0xa7, 0x08, 0xf7, 0x5d, 0xf7, + 0x60, 0x05, 0xfb, 0x7b, 0xfb, 0x2c, 0x15, 0x82, 0xa2, 0x86, 0xa8, 0x8b, + 0xa9, 0x8b, 0xef, 0xbf, 0xd2, 0xd6, 0x8b, 0xae, 0x8b, 0xa5, 0x7e, 0xa7, + 0x69, 0x08, 0xfb, 0x5e, 0xfb, 0x62, 0x05, 0x0e, 0xf7, 0xa5, 0xf9, 0x9c, + 0xf7, 0x2c, 0x15, 0x7e, 0x63, 0x60, 0x6f, 0x5a, 0x8b, 0x63, 0x8b, 0x68, + 0x9d, 0x79, 0xa9, 0x7d, 0xa2, 0x85, 0xa4, 0x8a, 0xb9, 0x08, 0xf7, 0xfe, + 0x06, 0x8c, 0x97, 0x8b, 0x90, 0x8b, 0x92, 0x8b, 0xc1, 0x83, 0xbd, 0x7e, + 0xb1, 0x67, 0xed, 0x34, 0xc6, 0xfb, 0x03, 0x8b, 0x40, 0x8b, 0x4d, 0x71, + 0x60, 0x59, 0x08, 0x5a, 0xbe, 0x49, 0xa4, 0x3b, 0x8b, 0x08, 0xfb, 0x3a, + 0x26, 0xfb, 0x00, 0xfb, 0x46, 0xfb, 0x46, 0xf0, 0xfb, 0x00, 0xf7, 0x3a, + 0x1f, 0xdb, 0x8b, 0xcb, 0xa4, 0xbe, 0xbd, 0x08, 0xb6, 0x5a, 0xcb, 0x71, + 0xd3, 0x8b, 0xf7, 0x0d, 0x8b, 0xec, 0xd0, 0xab, 0xf5, 0x08, 0xfb, 0x1e, + 0x06, 0xfc, 0x7a, 0xf7, 0xb0, 0x15, 0xd8, 0xbd, 0x46, 0x21, 0x1f, 0x26, + 0x57, 0x45, 0x40, 0x3f, 0x58, 0xd1, 0xf2, 0xf2, 0xbe, 0xd1, 0xd7, 0x1e, + 0xf7, 0xa1, 0xfb, 0x09, 0x15, 0x8e, 0xab, 0x90, 0x9e, 0x94, 0x9d, 0x08, + 0x9c, 0xac, 0xae, 0xa0, 0xb1, 0x8b, 0xac, 0x8b, 0xac, 0x79, 0x9e, 0x70, + 0x98, 0x78, 0x91, 0x77, 0x8f, 0x64, 0x08, 0xfb, 0x6b, 0x06, 0x0e, 0x4f, + 0xf7, 0xb1, 0xf7, 0xf1, 0x15, 0x98, 0x06, 0xe0, 0xbf, 0x5c, 0x3f, 0x1f, + 0x8b, 0x44, 0x5b, 0x58, 0x46, 0x8a, 0x08, 0x77, 0x8a, 0x05, 0x89, 0x8b, + 0x86, 0x8b, 0x85, 0x8a, 0x08, 0xfb, 0x04, 0x07, 0xac, 0x87, 0x9c, 0x89, + 0xa1, 0x8b, 0xf7, 0x17, 0x8b, 0xe2, 0xf0, 0x8b, 0xf7, 0x2c, 0x8b, 0xc9, + 0x7c, 0xb1, 0x67, 0xae, 0x72, 0xa2, 0x77, 0x95, 0x69, 0x92, 0x08, 0xc4, + 0xa1, 0xa9, 0xba, 0x8b, 0xce, 0x8b, 0xf6, 0x2d, 0xd6, 0xfb, 0x1b, 0x8b, + 0x46, 0x8b, 0x48, 0x78, 0x64, 0x6c, 0x60, 0x69, 0x79, 0x5a, 0x8b, 0x3d, + 0x08, 0xfc, 0x9a, 0xf7, 0x20, 0xf8, 0xad, 0x07, 0xbd, 0xab, 0xa8, 0xc2, + 0xc8, 0xb0, 0x6c, 0x57, 0x1e, 0x8b, 0x55, 0x65, 0x69, 0x4f, 0x8a, 0x08, + 0x82, 0x06, 0x2c, 0x07, 0x0e, 0xbe, 0xf8, 0x89, 0xf7, 0x27, 0x15, 0xbb, + 0xfb, 0x27, 0xf7, 0x2e, 0x8b, 0xfb, 0x90, 0xf9, 0x6d, 0xfb, 0x3a, 0x8b, + 0xfb, 0x97, 0xfd, 0x6d, 0xf7, 0x2d, 0x8b, 0xbc, 0xf7, 0x27, 0xf7, 0xa5, + 0x8b, 0x05, 0x62, 0xf7, 0x11, 0x15, 0xfb, 0x52, 0x8b, 0xea, 0xf7, 0xb1, + 0xea, 0xfb, 0xb1, 0x05, 0xfb, 0x1a, 0xf9, 0x1e, 0x15, 0xfb, 0x02, 0xfb, + 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, + 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0x0e, 0xbe, 0xf8, 0x89, 0xf7, 0x27, + 0x15, 0xbb, 0xfb, 0x27, 0xf7, 0x2e, 0x8b, 0xfb, 0x90, 0xf9, 0x6d, 0xfb, + 0x3a, 0x8b, 0xfb, 0x97, 0xfd, 0x6d, 0xf7, 0x2d, 0x8b, 0xbc, 0xf7, 0x27, + 0xf7, 0xa5, 0x8b, 0x05, 0x62, 0xf7, 0x11, 0x15, 0xfb, 0x52, 0x8b, 0xea, + 0xf7, 0xb1, 0xea, 0xfb, 0xb1, 0x05, 0xbd, 0xf9, 0x2c, 0x15, 0xfb, 0x12, + 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, 0x0e, + 0xbe, 0xf8, 0x89, 0xf7, 0x27, 0x15, 0xbb, 0xfb, 0x27, 0xf7, 0x2e, 0x8b, + 0xfb, 0x90, 0xf9, 0x6d, 0xfb, 0x3a, 0x8b, 0xfb, 0x97, 0xfd, 0x6d, 0xf7, + 0x2d, 0x8b, 0xbc, 0xf7, 0x27, 0xf7, 0xa5, 0x8b, 0x05, 0x62, 0xf7, 0x11, + 0x15, 0xfb, 0x52, 0x8b, 0xea, 0xf7, 0xb1, 0xea, 0xfb, 0xb1, 0x05, 0xfb, + 0x83, 0xf9, 0x2c, 0x15, 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, + 0x2a, 0xfb, 0x12, 0x8b, 0x05, 0x0e, 0xbe, 0xf8, 0x89, 0xf7, 0x27, 0x15, + 0xbb, 0xfb, 0x27, 0xf7, 0x2e, 0x8b, 0xfb, 0x90, 0xf9, 0x6d, 0xfb, 0x3a, + 0x8b, 0xfb, 0x97, 0xfd, 0x6d, 0xf7, 0x2d, 0x8b, 0xbc, 0xf7, 0x27, 0xf7, + 0xa5, 0x8b, 0x05, 0x62, 0xf7, 0x11, 0x15, 0xfb, 0x52, 0x8b, 0xea, 0xf7, + 0xb1, 0xea, 0xfb, 0xb1, 0x05, 0xfb, 0x27, 0xf9, 0x2c, 0x15, 0xfb, 0x00, + 0xfb, 0x2a, 0xd8, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd8, 0x8b, 0x24, 0xf7, + 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0xbe, 0xf8, 0x89, 0xf7, 0x27, 0x15, 0xbb, + 0xfb, 0x27, 0xf7, 0x2e, 0x8b, 0xfb, 0x90, 0xf9, 0x6d, 0xfb, 0x3a, 0x8b, + 0xfb, 0x97, 0xfd, 0x6d, 0xf7, 0x2d, 0x8b, 0xbc, 0xf7, 0x27, 0x05, 0xf7, + 0xa5, 0x06, 0x62, 0xf7, 0x11, 0x15, 0xfb, 0x52, 0x8b, 0xea, 0xf7, 0xb1, + 0xea, 0xfb, 0xb1, 0x05, 0xa3, 0xf9, 0x24, 0x15, 0x87, 0x6b, 0x7f, 0x7b, + 0x77, 0x8b, 0x84, 0x8b, 0x77, 0x8f, 0x84, 0x8d, 0x08, 0x43, 0xa4, 0x05, + 0x6c, 0x97, 0x84, 0x8c, 0x7a, 0x8b, 0x53, 0x8b, 0x68, 0x5d, 0x88, 0x3d, + 0x08, 0xc9, 0x06, 0x90, 0xab, 0x97, 0x98, 0xa2, 0x8b, 0x95, 0x8b, 0x95, + 0x89, 0x96, 0x87, 0x08, 0xd2, 0x71, 0x05, 0x9f, 0x83, 0x9f, 0x87, 0x9a, + 0x8b, 0xc6, 0x8b, 0xaa, 0xb5, 0x90, 0xe0, 0x08, 0x4c, 0x06, 0x0e, 0xbe, + 0xf8, 0x89, 0xf7, 0x27, 0x15, 0xbb, 0xfb, 0x27, 0xf7, 0x2e, 0x8b, 0xfb, + 0x90, 0xf9, 0x6d, 0xfb, 0x3a, 0x8b, 0xfb, 0x97, 0xfd, 0x6d, 0xf7, 0x2d, + 0x8b, 0xbc, 0xf7, 0x27, 0xf7, 0xa5, 0x8b, 0x05, 0x62, 0xf7, 0x11, 0x15, + 0xfb, 0x52, 0x8b, 0xea, 0xf7, 0xb1, 0xea, 0xfb, 0xb1, 0x05, 0x2c, 0xf9, + 0x39, 0x15, 0x58, 0x63, 0x63, 0x59, 0x59, 0xb4, 0x63, 0xbd, 0xbc, 0xb4, + 0xb3, 0xbc, 0xbe, 0x64, 0xb3, 0x58, 0x1f, 0x5b, 0x04, 0xa3, 0x9d, 0x78, + 0x74, 0x74, 0x78, 0x78, 0x74, 0x74, 0x77, 0x9e, 0xa2, 0xa2, 0x9e, 0x9e, + 0xa3, 0x1f, 0x0e, 0xbe, 0xf8, 0x0f, 0x74, 0x15, 0xf7, 0x4a, 0x8f, 0xf7, + 0x08, 0xf2, 0x93, 0xf7, 0x39, 0x08, 0xfb, 0x26, 0x06, 0x82, 0x2e, 0x50, + 0x56, 0x2e, 0x8b, 0x08, 0xfb, 0x08, 0x47, 0xe9, 0xf7, 0x33, 0xf7, 0x35, + 0xd2, 0xeb, 0xf7, 0x0a, 0x1f, 0xbf, 0x8b, 0xb6, 0x79, 0xa7, 0x68, 0x9b, + 0x77, 0x93, 0x78, 0x94, 0x64, 0x08, 0xf7, 0x23, 0x06, 0x86, 0xca, 0x7e, + 0xb3, 0x6c, 0xb4, 0x53, 0xd5, 0x31, 0xb4, 0xfb, 0x01, 0x8b, 0xfb, 0x62, + 0x8b, 0xfb, 0x14, 0xfb, 0x27, 0x8b, 0xfb, 0x80, 0x8b, 0xfb, 0x14, 0xb1, + 0x23, 0xd4, 0x45, 0xbb, 0x5e, 0xb2, 0x79, 0xe8, 0x7b, 0x08, 0x60, 0x38, + 0x05, 0x9e, 0x94, 0x95, 0x8e, 0x9f, 0x8b, 0x08, 0xaa, 0x9f, 0x7d, 0x76, + 0x74, 0x72, 0x79, 0x6b, 0x1f, 0x6f, 0x8b, 0x73, 0x92, 0x56, 0xa2, 0x08, + 0x78, 0x57, 0x05, 0xcc, 0x75, 0xa8, 0x85, 0xb7, 0x8b, 0x08, 0xde, 0xb9, + 0xac, 0xc7, 0xb7, 0x6e, 0xa6, 0x5c, 0x1f, 0x7b, 0x8b, 0x7f, 0x89, 0x7d, + 0x86, 0x08, 0x9e, 0xb3, 0x05, 0x0e, 0xbe, 0xd8, 0xf7, 0xe7, 0x15, 0xfb, + 0xe7, 0xf7, 0xb1, 0x07, 0xf7, 0x06, 0x8b, 0xd0, 0xa4, 0xbb, 0xc7, 0xc2, + 0xd0, 0xac, 0xf2, 0x8b, 0xf7, 0x00, 0x8b, 0xf6, 0x6a, 0xf3, 0x54, 0xd0, + 0x5a, 0xc6, 0x48, 0xa4, 0xfb, 0x07, 0x8b, 0x08, 0xfb, 0xb1, 0xfb, 0xca, + 0x3e, 0x3b, 0xd8, 0x06, 0xf7, 0x2a, 0x16, 0xf7, 0x2a, 0xdb, 0xfb, 0x2a, + 0xf7, 0x4d, 0xf7, 0x1b, 0x06, 0xcc, 0x8b, 0xb1, 0x7b, 0xa5, 0x65, 0xaa, + 0x5f, 0x9a, 0x4d, 0x8b, 0x3b, 0x8b, 0x3c, 0x7c, 0x4d, 0x6c, 0x5f, 0x71, + 0x65, 0x65, 0x7b, 0x4a, 0x8b, 0x08, 0xfb, 0x1b, 0xf7, 0x6a, 0x06, 0x0e, + 0x87, 0xf7, 0x79, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0xf7, 0x11, 0xfb, 0xf1, + 0xf7, 0x39, 0xf8, 0x0d, 0xf7, 0x11, 0xfc, 0xa3, 0xfd, 0x6d, 0xf8, 0xb5, + 0xf7, 0x11, 0xfc, 0x1f, 0x06, 0xf7, 0x51, 0x07, 0xd9, 0xf8, 0xf4, 0x15, + 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0x06, 0xf7, 0x0e, 0x07, 0xf7, 0x4e, + 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0x0e, 0x87, + 0xf7, 0x79, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0xf7, 0x11, 0xfb, 0xf1, 0xf7, + 0x39, 0xf8, 0x0d, 0xf7, 0x11, 0xfc, 0xa3, 0xfd, 0x6d, 0xf8, 0xb5, 0xf7, + 0x11, 0xfc, 0x1f, 0xf7, 0x51, 0x06, 0xf7, 0x8f, 0xf9, 0x02, 0x15, 0xfb, + 0x12, 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, + 0x0e, 0x87, 0xf7, 0x79, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0xf7, 0x11, 0xfb, + 0xf1, 0xf7, 0x39, 0xf8, 0x0d, 0xf7, 0x11, 0xfc, 0xa3, 0xfd, 0x6d, 0xf8, + 0xb5, 0xf7, 0x11, 0xfc, 0x1f, 0xf7, 0x51, 0x06, 0x76, 0xf9, 0x02, 0x15, + 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, 0x2a, 0xfb, 0x12, 0x8b, + 0x05, 0x0e, 0x87, 0xf7, 0x79, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0xf7, 0x11, + 0xfb, 0xf1, 0xf7, 0x39, 0xf8, 0x0d, 0xf7, 0x11, 0xfc, 0xa3, 0xfd, 0x6d, + 0xf8, 0xb5, 0xf7, 0x11, 0xfc, 0x1f, 0xf7, 0x51, 0x06, 0xcb, 0xf9, 0x02, + 0x15, 0x20, 0xfb, 0x2a, 0xd7, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd9, 0x8b, + 0x24, 0xf7, 0x2a, 0xfb, 0x00, 0x8b, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0x69, + 0xf9, 0x6d, 0x15, 0xfb, 0x2a, 0xfd, 0x6d, 0xf7, 0x2a, 0x06, 0xf9, 0x6d, + 0x07, 0xfb, 0x04, 0xf7, 0x55, 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, + 0x06, 0xf7, 0x0e, 0x07, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, + 0x02, 0xf7, 0x0e, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, 0x69, 0xf9, 0x6d, 0x15, + 0xfb, 0x2a, 0xfd, 0x6d, 0xf7, 0x2a, 0xf9, 0x6d, 0x06, 0xd8, 0xf7, 0x63, + 0x15, 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, + 0x2a, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0x69, 0xf9, 0x6d, 0x15, 0xfb, 0x2a, + 0xfd, 0x6d, 0xf7, 0x2a, 0xf9, 0x6d, 0x06, 0xfb, 0x73, 0xf7, 0x63, 0x15, + 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, 0x2a, 0xfb, 0x12, 0x8b, + 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0x69, 0xf9, 0x6d, 0x15, 0xfb, 0x2a, 0xfd, + 0x6d, 0xf7, 0x2a, 0xf9, 0x6d, 0x06, 0xfb, 0x10, 0xf7, 0x63, 0x15, 0xfb, + 0x00, 0xfb, 0x2a, 0xd7, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd9, 0x8b, 0x24, + 0xf7, 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0xbe, 0xf8, 0x93, 0x16, 0xf7, 0x2a, + 0xf9, 0x6d, 0xfb, 0x2a, 0xfc, 0x84, 0x06, 0xfb, 0xb5, 0xf8, 0x84, 0xfb, + 0x2e, 0x8b, 0x8b, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0x8b, 0xf8, 0x8c, 0x05, + 0xf7, 0xb9, 0xfc, 0x8c, 0x05, 0x72, 0xfa, 0x34, 0x15, 0x87, 0x6b, 0x7f, + 0x7b, 0x76, 0x8b, 0x84, 0x8b, 0x78, 0x8f, 0x84, 0x8d, 0x08, 0x43, 0xa4, + 0x05, 0x6b, 0x97, 0x85, 0x8c, 0x7a, 0x8b, 0x53, 0x8b, 0x68, 0x5d, 0x87, + 0x3d, 0x08, 0xca, 0x06, 0x90, 0xab, 0x97, 0x98, 0xa2, 0x8b, 0x94, 0x8b, + 0x96, 0x89, 0x95, 0x87, 0x08, 0xd3, 0x71, 0x05, 0x9e, 0x83, 0xa0, 0x87, + 0x99, 0x8b, 0xc6, 0x8b, 0xab, 0xb5, 0x8f, 0xe0, 0x08, 0x4d, 0x06, 0x0e, + 0xf6, 0xf8, 0x1a, 0xf9, 0x79, 0x15, 0x25, 0x8b, 0x37, 0x69, 0x4d, 0x48, + 0x4a, 0x45, 0x66, 0x25, 0x8b, 0xfb, 0x01, 0x8b, 0xfb, 0x01, 0xb0, 0x24, + 0xcc, 0x46, 0xca, 0x47, 0xdd, 0x6a, 0xf3, 0x8b, 0xf3, 0x8b, 0xdd, 0xac, + 0xca, 0xcf, 0xca, 0xce, 0xb2, 0xf5, 0x8b, 0xf2, 0x08, 0x8b, 0xf7, 0x06, + 0x66, 0xf1, 0x4a, 0xd1, 0x4b, 0xd0, 0x3a, 0xab, 0x22, 0x8b, 0x08, 0x8c, + 0xfb, 0x14, 0x15, 0xf7, 0x0f, 0xd9, 0x27, 0xfb, 0x32, 0xfb, 0x29, 0x3a, + 0x26, 0xfb, 0x0c, 0xfb, 0x0d, 0x3b, 0xf0, 0xf7, 0x2d, 0xf7, 0x2d, 0xdb, + 0xf0, 0xf7, 0x0d, 0x1f, 0x65, 0xf7, 0xc9, 0x15, 0xfb, 0x02, 0xfb, 0x0e, + 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, + 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0x0e, 0xf6, 0xf8, 0x1a, 0xf9, 0x79, 0x15, + 0x25, 0x8b, 0x37, 0x69, 0x4d, 0x48, 0x4a, 0x45, 0x66, 0x25, 0x8b, 0xfb, + 0x01, 0x8b, 0xfb, 0x01, 0xb0, 0x24, 0xcc, 0x46, 0xca, 0x47, 0xdd, 0x6a, + 0xf3, 0x8b, 0xf3, 0x8b, 0xdd, 0xac, 0xca, 0xcf, 0xca, 0xce, 0xb2, 0xf5, + 0x8b, 0xf2, 0x08, 0x8b, 0xf7, 0x06, 0x66, 0xf1, 0x4a, 0xd1, 0x4b, 0xd0, + 0x3a, 0xab, 0x22, 0x8b, 0x08, 0x8c, 0xfb, 0x14, 0x15, 0xf7, 0x0f, 0xd9, + 0x27, 0xfb, 0x32, 0xfb, 0x29, 0x3a, 0x26, 0xfb, 0x0c, 0xfb, 0x0d, 0x3b, + 0xf0, 0xf7, 0x2d, 0xf7, 0x2d, 0xdb, 0xf0, 0xf7, 0x0d, 0x1f, 0xf7, 0x1f, + 0xf7, 0xd7, 0x15, 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, + 0x12, 0xf7, 0x2a, 0x05, 0x0e, 0xf6, 0xf8, 0x1a, 0xf9, 0x79, 0x15, 0x25, + 0x8b, 0x37, 0x69, 0x4d, 0x48, 0x4a, 0x45, 0x66, 0x25, 0x8b, 0xfb, 0x01, + 0x8b, 0xfb, 0x01, 0xb0, 0x24, 0xcc, 0x46, 0xca, 0x47, 0xdd, 0x6a, 0xf3, + 0x8b, 0xf3, 0x8b, 0xdd, 0xac, 0xca, 0xcf, 0xca, 0xce, 0xb2, 0xf5, 0x8b, + 0xf2, 0x08, 0x8b, 0xf7, 0x06, 0x66, 0xf1, 0x4a, 0xd1, 0x4b, 0xd0, 0x3a, + 0xab, 0x22, 0x8b, 0x08, 0x8c, 0xfb, 0x14, 0x15, 0xf7, 0x0f, 0xd9, 0x27, + 0xfb, 0x32, 0xfb, 0x29, 0x3a, 0x26, 0xfb, 0x0c, 0xfb, 0x0d, 0x3b, 0xf0, + 0xf7, 0x2d, 0xf7, 0x2d, 0xdb, 0xf0, 0xf7, 0x0d, 0x1f, 0xfb, 0x1d, 0xf7, + 0xd7, 0x15, 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, 0x2a, 0xfb, + 0x12, 0x8b, 0x05, 0x0e, 0xf6, 0xf8, 0x1a, 0xf9, 0x79, 0x15, 0x25, 0x8b, + 0x37, 0x69, 0x4d, 0x48, 0x4a, 0x45, 0x66, 0x25, 0x8b, 0xfb, 0x01, 0x8b, + 0xfb, 0x01, 0xb0, 0x24, 0xcc, 0x46, 0xca, 0x47, 0xdd, 0x6a, 0xf3, 0x8b, + 0xf3, 0x8b, 0xdd, 0xac, 0xca, 0xcf, 0xca, 0xce, 0xb2, 0xf5, 0x8b, 0xf2, + 0x08, 0x8b, 0xf7, 0x06, 0x66, 0xf1, 0x4a, 0xd1, 0x4b, 0xd0, 0x3a, 0xab, + 0x22, 0x8b, 0x08, 0x8c, 0xfb, 0x14, 0x15, 0xf7, 0x0f, 0xd9, 0x27, 0xfb, + 0x32, 0xfb, 0x29, 0x3a, 0x26, 0xfb, 0x0c, 0xfb, 0x0d, 0x3b, 0xf0, 0xf7, + 0x2d, 0xf7, 0x2d, 0xdb, 0xf0, 0xf7, 0x0d, 0x1f, 0x58, 0xf7, 0xd7, 0x15, + 0xfb, 0x00, 0xfb, 0x2a, 0xd7, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd9, 0x8b, + 0x24, 0xf7, 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0xf6, 0xf8, 0x1a, 0xf9, 0x79, + 0x15, 0x25, 0x8b, 0x37, 0x69, 0x4d, 0x48, 0x4a, 0x45, 0x66, 0x25, 0x8b, + 0xfb, 0x01, 0x8b, 0xfb, 0x01, 0xb0, 0x24, 0xcc, 0x46, 0xca, 0x47, 0xdd, + 0x6a, 0xf3, 0x8b, 0xf3, 0x8b, 0xdd, 0xac, 0xca, 0xcf, 0xca, 0xce, 0xb2, + 0xf5, 0x8b, 0xf2, 0x08, 0x8b, 0xf7, 0x06, 0x66, 0xf1, 0x4a, 0xd1, 0x08, + 0x4b, 0xd0, 0x3a, 0xab, 0x22, 0x8b, 0x08, 0x8c, 0xfb, 0x14, 0x15, 0xf7, + 0x0f, 0xd9, 0x27, 0xfb, 0x32, 0xfb, 0x29, 0x3a, 0x26, 0xfb, 0x0c, 0xfb, + 0x0d, 0x3b, 0xf0, 0xf7, 0x2d, 0xf7, 0x2d, 0xdb, 0xf0, 0xf7, 0x0d, 0x1f, + 0xf7, 0x0d, 0xf7, 0xcf, 0x15, 0x87, 0x6b, 0x7f, 0x7b, 0x77, 0x8b, 0x84, + 0x8b, 0x77, 0x8f, 0x84, 0x8d, 0x08, 0x44, 0xa4, 0x05, 0x6b, 0x97, 0x84, + 0x8c, 0x7a, 0x8b, 0x53, 0x8b, 0x68, 0x5d, 0x88, 0x3d, 0x08, 0xc9, 0x06, + 0x90, 0xab, 0x97, 0x98, 0xa3, 0x8b, 0x94, 0x8b, 0x95, 0x89, 0x96, 0x87, + 0x08, 0xd2, 0x71, 0x05, 0x9f, 0x83, 0x9f, 0x87, 0x9a, 0x8b, 0xc6, 0x8b, + 0xaa, 0xb5, 0x90, 0xe0, 0x08, 0x4c, 0x06, 0x0e, 0x87, 0xf8, 0xf3, 0xf8, + 0x8f, 0x15, 0x8b, 0xce, 0x7c, 0xb7, 0x67, 0xb3, 0x5a, 0xc1, 0x3a, 0xa8, + 0x22, 0x8b, 0xfb, 0x43, 0x8b, 0x26, 0x39, 0x8b, 0xfb, 0x22, 0x8b, 0xfb, + 0x05, 0xc4, 0x54, 0xf7, 0x28, 0x6f, 0x08, 0xf1, 0x77, 0x05, 0xef, 0x78, + 0xb0, 0x6f, 0x8b, 0x50, 0x8b, 0x4e, 0x53, 0x66, 0x30, 0x8b, 0x25, 0x8b, + 0x52, 0xb6, 0x86, 0xd9, 0x08, 0xfb, 0x26, 0x06, 0x94, 0xfb, 0x30, 0xf6, + 0x36, 0xf7, 0x4e, 0x8b, 0xf7, 0x50, 0x8b, 0xf7, 0x03, 0xe3, 0x8b, 0xf7, + 0x28, 0x8b, 0xf7, 0x07, 0x51, 0xc7, 0xfb, 0x1b, 0xa5, 0x08, 0xfb, 0x06, + 0xa1, 0x05, 0x20, 0xa0, 0x6c, 0xa0, 0x8b, 0xc0, 0x8b, 0xc2, 0xbc, 0xae, + 0xd8, 0x8b, 0xea, 0x8b, 0xc0, 0x63, 0x90, 0x41, 0x08, 0xf7, 0x20, 0x06, + 0xfb, 0x76, 0xf7, 0xab, 0x15, 0xf6, 0xf7, 0x2a, 0x3f, 0x8b, 0x39, 0x2a, + 0x39, 0xec, 0x3d, 0x8b, 0xf2, 0xfb, 0x2a, 0xf7, 0x00, 0x8b, 0x05, 0x0e, + 0xbe, 0xf8, 0x8c, 0xf9, 0x6d, 0x15, 0xfc, 0x82, 0x07, 0x33, 0x5e, 0x61, + 0x2d, 0x2d, 0x5e, 0xb5, 0xe3, 0x1e, 0xf8, 0x82, 0xfb, 0x2a, 0xfc, 0x82, + 0x07, 0x8b, 0x39, 0xa1, 0x51, 0xbc, 0x5f, 0xc0, 0x5b, 0xd8, 0x71, 0xe3, + 0x8b, 0xe3, 0x8b, 0xd8, 0xa5, 0xc0, 0xbb, 0xbc, 0xb7, 0xa1, 0xc5, 0x8b, + 0xdd, 0x08, 0xf8, 0x82, 0x07, 0xfb, 0x2a, 0x06, 0xfb, 0x45, 0xf7, 0x55, + 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0x06, 0xf7, 0x0e, 0x07, 0xf7, + 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0x0e, + 0xbe, 0xf8, 0x8c, 0xf9, 0x6d, 0x15, 0xfc, 0x82, 0x07, 0x33, 0x5e, 0x61, + 0x2d, 0x2d, 0x5e, 0xb5, 0xe3, 0x1e, 0xf8, 0x82, 0xfb, 0x2a, 0xfc, 0x82, + 0x07, 0x8b, 0x39, 0xa1, 0x51, 0xbc, 0x5f, 0xc0, 0x5b, 0xd8, 0x71, 0xe3, + 0x8b, 0xe3, 0x8b, 0xd8, 0xa5, 0xc0, 0xbb, 0xbc, 0xb7, 0xa1, 0xc5, 0x8b, + 0xdd, 0x08, 0xf8, 0x82, 0xfb, 0x2a, 0x07, 0xf7, 0x63, 0x04, 0xfb, 0x12, + 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, 0x0e, + 0xbe, 0xf8, 0x8c, 0xf9, 0x6d, 0x15, 0xfc, 0x82, 0x07, 0x33, 0x5e, 0x61, + 0x2d, 0x2d, 0x5e, 0xb5, 0xe3, 0x1e, 0xf8, 0x82, 0xfb, 0x2a, 0xfc, 0x82, + 0x07, 0x8b, 0x39, 0xa1, 0x51, 0xbc, 0x5f, 0xc0, 0x5b, 0xd8, 0x71, 0xe3, + 0x8b, 0xe3, 0x8b, 0xd8, 0xa5, 0xc0, 0xbb, 0xbc, 0xb7, 0xa1, 0xc5, 0x8b, + 0xdd, 0x08, 0xf8, 0x82, 0xfb, 0x2a, 0x07, 0xfb, 0xa8, 0xf7, 0x63, 0x15, + 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, 0x2a, 0xfb, 0x12, 0x8b, + 0x05, 0x0e, 0xbe, 0xf8, 0x8c, 0xf9, 0x6d, 0x15, 0xfc, 0x82, 0x07, 0x33, + 0x5e, 0x61, 0x2d, 0x2d, 0x5e, 0xb5, 0xe3, 0x1e, 0xf8, 0x82, 0xfb, 0x2a, + 0xfc, 0x82, 0x07, 0x8b, 0x39, 0xa1, 0x51, 0xbc, 0x5f, 0xc0, 0x5b, 0xd8, + 0x71, 0xe3, 0x8b, 0xe3, 0x8b, 0xd8, 0xa5, 0xc0, 0xbb, 0xbc, 0xb7, 0xa1, + 0xc5, 0x8b, 0xdd, 0x08, 0xf8, 0x82, 0xfb, 0x2a, 0x07, 0xfb, 0x52, 0xf7, + 0x63, 0x15, 0xfb, 0x00, 0xfb, 0x2a, 0xd7, 0x8b, 0xdd, 0xef, 0xdd, 0x27, + 0xd9, 0x8b, 0x24, 0xf7, 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0x87, 0xf8, 0x37, + 0xf7, 0xa2, 0x15, 0xf7, 0x7b, 0xf8, 0x5f, 0xfb, 0x3c, 0x8b, 0xfb, 0x1f, + 0xfb, 0xd6, 0xfb, 0x29, 0xf7, 0xd6, 0xfb, 0x3b, 0x8b, 0xf7, 0x86, 0xfc, + 0x5f, 0x8b, 0xfb, 0xa2, 0xf7, 0x2a, 0x8b, 0x8b, 0xf7, 0xa2, 0x05, 0xc8, + 0xf9, 0x2e, 0x15, 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, + 0x12, 0xf7, 0x2a, 0x05, 0x0e, 0x4f, 0xf8, 0xd6, 0xf9, 0x6d, 0x15, 0xfc, + 0xb8, 0xfb, 0x11, 0xf8, 0x09, 0x06, 0xfc, 0x09, 0xfc, 0x73, 0x8b, 0xfb, + 0x11, 0xf8, 0xb8, 0x8b, 0x8b, 0xf7, 0x11, 0xfc, 0x08, 0x8b, 0xf8, 0x08, + 0xf8, 0x73, 0x8b, 0xf7, 0x11, 0x05, 0xfb, 0x6f, 0xc4, 0x15, 0xf6, 0xf7, + 0x2a, 0x3f, 0x8b, 0x39, 0x2a, 0x39, 0xec, 0x3d, 0x8b, 0xf2, 0xfb, 0x2a, + 0xf7, 0x00, 0x8b, 0x05, 0x0e, 0x87, 0xf7, 0x76, 0xf7, 0x20, 0x15, 0xf7, + 0x4f, 0x06, 0xf7, 0x1b, 0xe0, 0xe8, 0xf7, 0x29, 0x1f, 0x8b, 0xd5, 0x77, + 0xc3, 0x61, 0xb4, 0x63, 0xb2, 0x58, 0x9c, 0x39, 0x8b, 0x08, 0xfb, 0x40, + 0xf7, 0x0c, 0xfb, 0x2a, 0xfd, 0x6d, 0xf7, 0x2a, 0xf7, 0x20, 0x06, 0xf7, + 0x11, 0x04, 0xf7, 0x6f, 0xf7, 0x20, 0x07, 0xdb, 0xb0, 0x68, 0x40, 0x41, + 0x66, 0x68, 0x3b, 0x1f, 0xfb, 0x20, 0x06, 0x0e, 0x87, 0xf8, 0x37, 0xf7, + 0xa2, 0x15, 0xf7, 0x7b, 0xf8, 0x5f, 0xfb, 0x3c, 0x8b, 0xfb, 0x1f, 0xfb, + 0xd6, 0x05, 0xfb, 0x29, 0xf7, 0xd6, 0xfb, 0x3b, 0x8b, 0x05, 0xf7, 0x86, + 0xfc, 0x5f, 0x8b, 0xfb, 0xa2, 0xf7, 0x2a, 0x8b, 0x05, 0xf7, 0xa2, 0x07, + 0xfb, 0x07, 0xf9, 0x20, 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0x06, + 0xf7, 0x0e, 0x07, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, + 0xf7, 0x0e, 0x06, 0x0e, 0xf8, 0xa0, 0x9c, 0x15, 0x72, 0xa2, 0x84, 0x9a, + 0x8b, 0xa7, 0x08, 0xf7, 0xc0, 0x07, 0xf7, 0x02, 0x40, 0xc3, 0xfb, 0x26, + 0x1e, 0xfb, 0x26, 0x8b, 0x3f, 0x4d, 0x82, 0xfb, 0x11, 0x08, 0xf7, 0x1b, + 0x06, 0x92, 0xc3, 0xa2, 0x9d, 0xd0, 0x8b, 0xc1, 0x8b, 0xa6, 0x79, 0x8b, + 0x67, 0x8b, 0x79, 0x82, 0x7b, 0x7c, 0x83, 0x78, 0x81, 0x8b, 0x8b, 0x46, + 0x80, 0x08, 0x53, 0x81, 0x05, 0x20, 0x79, 0x57, 0x54, 0x8b, 0x2a, 0x8b, + 0x5d, 0x98, 0x65, 0xa4, 0x70, 0xaa, 0x6b, 0xba, 0x78, 0xbb, 0x8b, 0xc7, + 0x8b, 0xc2, 0xa5, 0xbc, 0xbe, 0x08, 0x8b, 0x6f, 0x8e, 0x81, 0x98, 0x7b, + 0x08, 0xf7, 0x2c, 0x06, 0x9c, 0x07, 0xfb, 0x3d, 0xf7, 0x5c, 0x15, 0x3a, + 0x63, 0x5d, 0x44, 0x5c, 0x6e, 0xa4, 0xb3, 0x1e, 0x8b, 0xb5, 0xa1, 0x9f, + 0xc5, 0x97, 0x08, 0xbb, 0x94, 0x05, 0xb0, 0x92, 0x91, 0x8d, 0x9b, 0x93, + 0x08, 0x65, 0x07, 0xfb, 0x0d, 0xf8, 0xa2, 0x15, 0xfb, 0x02, 0xfb, 0x0e, + 0xf7, 0x02, 0x06, 0xf7, 0x0e, 0x07, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, + 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0x0e, 0xf8, 0xa0, 0x9c, 0x15, 0x72, + 0xa2, 0x84, 0x9a, 0x8b, 0xa7, 0x08, 0xf7, 0xc0, 0x07, 0xf7, 0x02, 0x40, + 0xc3, 0xfb, 0x26, 0x1e, 0xfb, 0x26, 0x8b, 0x3f, 0x4d, 0x82, 0xfb, 0x11, + 0x08, 0xf7, 0x1b, 0x06, 0x92, 0xc3, 0xa2, 0x9d, 0xd0, 0x8b, 0xc1, 0x8b, + 0xa6, 0x79, 0x8b, 0x67, 0x8b, 0x79, 0x82, 0x7b, 0x7c, 0x83, 0x78, 0x81, + 0x8b, 0x8b, 0x46, 0x80, 0x08, 0x53, 0x81, 0x05, 0x20, 0x79, 0x57, 0x54, + 0x8b, 0x2a, 0x8b, 0x5d, 0x98, 0x65, 0xa4, 0x70, 0xaa, 0x6b, 0xba, 0x78, + 0xbb, 0x8b, 0xc7, 0x8b, 0xc2, 0xa5, 0xbc, 0xbe, 0x08, 0x8b, 0x6f, 0x8e, + 0x81, 0x98, 0x7b, 0x08, 0xf7, 0x2c, 0x06, 0x9c, 0x07, 0xfb, 0x3d, 0xf7, + 0x5c, 0x15, 0x3a, 0x63, 0x5d, 0x44, 0x5c, 0x6e, 0xa4, 0xb3, 0x1e, 0x8b, + 0xb5, 0xa1, 0x9f, 0xc5, 0x97, 0x08, 0xbb, 0x94, 0x05, 0xb0, 0x92, 0x91, + 0x8d, 0x9b, 0x93, 0x08, 0x65, 0x07, 0xc3, 0xf8, 0xb0, 0x15, 0xfb, 0x12, + 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, 0x0e, + 0xf8, 0xa0, 0x9c, 0x15, 0x72, 0xa2, 0x84, 0x9a, 0x8b, 0xa7, 0x08, 0xf7, + 0xc0, 0x07, 0xf7, 0x02, 0x40, 0xc3, 0xfb, 0x26, 0x1e, 0xfb, 0x26, 0x8b, + 0x3f, 0x4d, 0x82, 0xfb, 0x11, 0x08, 0xf7, 0x1b, 0x06, 0x92, 0xc3, 0xa2, + 0x9d, 0xd0, 0x8b, 0xc1, 0x8b, 0xa6, 0x79, 0x8b, 0x67, 0x8b, 0x79, 0x82, + 0x7b, 0x7c, 0x83, 0x78, 0x81, 0x8b, 0x8b, 0x46, 0x80, 0x08, 0x53, 0x81, + 0x05, 0x20, 0x79, 0x57, 0x54, 0x8b, 0x2a, 0x8b, 0x5d, 0x98, 0x65, 0xa4, + 0x70, 0xaa, 0x6b, 0xba, 0x78, 0xbb, 0x8b, 0xc7, 0x8b, 0xc2, 0xa5, 0xbc, + 0xbe, 0x08, 0x8b, 0x6f, 0x8e, 0x81, 0x98, 0x7b, 0x08, 0xf7, 0x2c, 0x06, + 0x9c, 0x07, 0xfb, 0x3d, 0xf7, 0x5c, 0x15, 0x3a, 0x63, 0x5d, 0x44, 0x5c, + 0x6e, 0xa4, 0xb3, 0x1e, 0x8b, 0xb5, 0xa1, 0x9f, 0xc5, 0x97, 0x08, 0xbb, + 0x94, 0x05, 0xb0, 0x92, 0x91, 0x8d, 0x9b, 0x93, 0x08, 0x65, 0x07, 0xfb, + 0x73, 0xf8, 0xb0, 0x15, 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, + 0x2a, 0xfb, 0x12, 0x8b, 0x05, 0x0e, 0xf8, 0xa0, 0x9c, 0x15, 0x72, 0xa2, + 0x84, 0x9a, 0x8b, 0xa7, 0x08, 0xf7, 0xc0, 0x07, 0xf7, 0x02, 0x40, 0xc3, + 0xfb, 0x26, 0x1e, 0xfb, 0x26, 0x8b, 0x3f, 0x4d, 0x82, 0xfb, 0x11, 0x08, + 0xf7, 0x1b, 0x06, 0x92, 0xc3, 0xa2, 0x9d, 0xd0, 0x8b, 0xc1, 0x8b, 0xa6, + 0x79, 0x8b, 0x67, 0x8b, 0x79, 0x82, 0x7b, 0x7c, 0x83, 0x78, 0x81, 0x8b, + 0x8b, 0x46, 0x80, 0x08, 0x53, 0x81, 0x05, 0x20, 0x79, 0x57, 0x54, 0x8b, + 0x2a, 0x8b, 0x5d, 0x98, 0x65, 0xa4, 0x70, 0xaa, 0x6b, 0xba, 0x78, 0xbb, + 0x8b, 0xc7, 0x8b, 0xc2, 0xa5, 0xbc, 0xbe, 0x08, 0x8b, 0x6f, 0x8e, 0x81, + 0x98, 0x7b, 0x08, 0xf7, 0x2c, 0x06, 0x9c, 0x07, 0xfb, 0x3d, 0xf7, 0x5c, + 0x15, 0x3a, 0x63, 0x5d, 0x44, 0x5c, 0x6e, 0xa4, 0xb3, 0x1e, 0x8b, 0xb5, + 0xa1, 0x9f, 0xc5, 0x97, 0x08, 0xbb, 0x94, 0x05, 0xb0, 0x92, 0x91, 0x8d, + 0x9b, 0x93, 0x08, 0x65, 0x07, 0xfb, 0x1a, 0xf8, 0xb0, 0x15, 0xfb, 0x00, + 0xfb, 0x2a, 0xd7, 0x8b, 0xde, 0xef, 0xdc, 0x27, 0xd9, 0x8b, 0x24, 0xf7, + 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0xf8, 0xa0, 0x9c, 0x15, 0x72, 0xa2, 0x84, + 0x9a, 0x8b, 0xa7, 0x08, 0xf7, 0xc0, 0x07, 0xf7, 0x02, 0x40, 0xc3, 0xfb, + 0x26, 0x1e, 0xfb, 0x26, 0x8b, 0x3f, 0x4d, 0x82, 0xfb, 0x11, 0x08, 0xf7, + 0x1b, 0x06, 0x92, 0xc3, 0xa2, 0x9d, 0xd0, 0x8b, 0xc1, 0x8b, 0xa6, 0x79, + 0x8b, 0x67, 0x8b, 0x79, 0x82, 0x7b, 0x7c, 0x83, 0x78, 0x81, 0x8b, 0x8b, + 0x46, 0x80, 0x08, 0x53, 0x81, 0x05, 0x20, 0x79, 0x57, 0x54, 0x8b, 0x2a, + 0x8b, 0x5d, 0x98, 0x65, 0xa4, 0x70, 0xaa, 0x6b, 0xba, 0x78, 0xbb, 0x8b, + 0xc7, 0x8b, 0xc2, 0xa5, 0xbc, 0xbe, 0x08, 0x8b, 0x6f, 0x8e, 0x81, 0x98, + 0x7b, 0x08, 0xf7, 0x2c, 0x06, 0x9c, 0x07, 0xfb, 0x3d, 0xf7, 0x5c, 0x15, + 0x3a, 0x63, 0x5d, 0x44, 0x5c, 0x6e, 0xa4, 0xb3, 0x1e, 0x8b, 0xb5, 0xa1, + 0x9f, 0xc5, 0x97, 0x08, 0xbb, 0x94, 0x05, 0xb0, 0x92, 0x91, 0x8d, 0x9b, + 0x93, 0x08, 0x65, 0x07, 0xab, 0xf8, 0xa8, 0x15, 0x87, 0x6b, 0x7f, 0x7b, + 0x76, 0x8b, 0x84, 0x8b, 0x77, 0x8e, 0x85, 0x8e, 0x08, 0x43, 0xa4, 0x05, + 0x67, 0x98, 0x8a, 0x8b, 0x79, 0x8b, 0x53, 0x8b, 0x68, 0x5d, 0x87, 0x3d, + 0x08, 0xca, 0x06, 0x90, 0xab, 0x97, 0x98, 0xa2, 0x8b, 0x94, 0x8b, 0x95, + 0x89, 0x96, 0x87, 0x08, 0xd3, 0x71, 0x05, 0x9f, 0x83, 0x9e, 0x87, 0x9a, + 0x8b, 0xc6, 0x8b, 0xab, 0xb5, 0x8f, 0xe0, 0x08, 0x4d, 0x06, 0x0e, 0xf8, + 0xa0, 0x9c, 0x15, 0x72, 0xa2, 0x84, 0x9a, 0x8b, 0xa7, 0x08, 0xf7, 0xc0, + 0x07, 0xf7, 0x02, 0x40, 0xc3, 0xfb, 0x26, 0x1e, 0xfb, 0x26, 0x8b, 0x3f, + 0x4d, 0x82, 0xfb, 0x11, 0x08, 0xf7, 0x1b, 0x06, 0x92, 0xc3, 0xa2, 0x9d, + 0xd0, 0x8b, 0xc1, 0x8b, 0xa6, 0x79, 0x8b, 0x67, 0x8b, 0x79, 0x82, 0x7b, + 0x7c, 0x83, 0x78, 0x81, 0x8b, 0x8b, 0x46, 0x80, 0x08, 0x53, 0x81, 0x05, + 0x20, 0x79, 0x57, 0x54, 0x8b, 0x2a, 0x8b, 0x5d, 0x98, 0x65, 0xa4, 0x70, + 0xaa, 0x6b, 0xba, 0x78, 0xbb, 0x8b, 0xc7, 0x8b, 0xc2, 0xa5, 0xbc, 0xbe, + 0x08, 0x8b, 0x6f, 0x8e, 0x81, 0x98, 0x7b, 0x08, 0xf7, 0x2c, 0x06, 0x9c, + 0x07, 0xfb, 0x3d, 0xf7, 0x5c, 0x15, 0x3a, 0x63, 0x5d, 0x44, 0x5c, 0x6e, + 0xa4, 0xb3, 0x1e, 0x8b, 0xb5, 0xa1, 0x9f, 0xc5, 0x97, 0x08, 0xbb, 0x94, + 0x05, 0xb0, 0x92, 0x91, 0x8d, 0x9b, 0x93, 0x08, 0x65, 0x07, 0x39, 0xf8, + 0xbd, 0x15, 0x58, 0x63, 0x63, 0x59, 0x59, 0xb3, 0x63, 0xbd, 0x1f, 0xbc, + 0xb4, 0xb3, 0xbc, 0xbe, 0x64, 0xb3, 0x59, 0x1f, 0x5b, 0x04, 0xa2, 0x9d, + 0x78, 0x74, 0x74, 0x78, 0x78, 0x75, 0x73, 0x78, 0x9e, 0xa2, 0xa2, 0x9e, + 0x9e, 0xa3, 0x1f, 0x0e, 0xf7, 0xb7, 0x74, 0x15, 0xf7, 0x11, 0x8a, 0xea, + 0xe1, 0x96, 0xf7, 0x11, 0x08, 0xfb, 0x1a, 0x06, 0x7a, 0x46, 0x6e, 0x6f, + 0x56, 0x8b, 0x6d, 0x8b, 0x6c, 0x98, 0x7b, 0x9f, 0x74, 0xa7, 0x7c, 0xbf, + 0x8b, 0xc4, 0x8b, 0xbd, 0x95, 0xbb, 0x9c, 0xab, 0x9b, 0xa9, 0xaa, 0x9b, + 0xb3, 0x8b, 0xc4, 0x8b, 0xa6, 0x70, 0x9b, 0x44, 0x08, 0xf7, 0x1a, 0x06, + 0x81, 0xf7, 0x18, 0x33, 0xda, 0xfb, 0x1b, 0x8b, 0xfb, 0x35, 0x8b, 0x2d, + 0x21, 0x8b, 0xfb, 0x4c, 0x8b, 0xfb, 0x37, 0xd7, 0x28, 0xf7, 0x1e, 0x79, + 0x08, 0x60, 0x36, 0x05, 0x9e, 0x94, 0x96, 0x8e, 0x9f, 0x8b, 0x08, 0xaa, + 0x9f, 0x7d, 0x76, 0x74, 0x71, 0x79, 0x6b, 0x1f, 0x70, 0x8b, 0x71, 0x92, + 0x58, 0xa2, 0x08, 0x78, 0x57, 0x05, 0xc7, 0x76, 0xad, 0x84, 0xb7, 0x8b, + 0x08, 0xde, 0xb9, 0xac, 0xc7, 0xb7, 0x6e, 0xa6, 0x5b, 0x1f, 0x7c, 0x8b, + 0x7e, 0x89, 0x7e, 0x86, 0x08, 0x9c, 0xb3, 0x05, 0x0e, 0xf8, 0xa0, 0xf7, + 0x76, 0x15, 0x8c, 0x97, 0x8b, 0x90, 0x8b, 0x92, 0x8b, 0xc1, 0x83, 0xbd, + 0x7e, 0xb1, 0x67, 0xed, 0x34, 0xc6, 0xfb, 0x01, 0x8b, 0x08, 0xfb, 0x2f, + 0x2c, 0xfb, 0x04, 0xfb, 0x49, 0xfb, 0x41, 0xe9, 0x21, 0xf7, 0x2d, 0x1f, + 0xf7, 0x0d, 0x8b, 0xed, 0xd0, 0xaa, 0xf5, 0x08, 0xfb, 0x1e, 0x06, 0x7a, + 0x60, 0x64, 0x72, 0x58, 0x8b, 0x63, 0x8b, 0x6b, 0x9c, 0x77, 0xa9, 0x7e, + 0x9f, 0x86, 0xa3, 0x89, 0xbe, 0x08, 0xf7, 0xfe, 0x06, 0xfb, 0xfc, 0xe8, + 0x15, 0x94, 0xdd, 0xae, 0xb4, 0xc9, 0x8b, 0xae, 0x8b, 0xab, 0x7a, 0x9f, + 0x6f, 0x98, 0x77, 0x91, 0x76, 0x8e, 0x66, 0x08, 0xfb, 0x6b, 0x06, 0xd9, + 0xf8, 0x3c, 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, + 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, + 0x0e, 0xf8, 0xa0, 0xf7, 0x76, 0x15, 0x8c, 0x97, 0x8b, 0x90, 0x8b, 0x92, + 0x8b, 0xc1, 0x83, 0xbd, 0x7e, 0xb1, 0x67, 0xed, 0x34, 0xc6, 0xfb, 0x01, + 0x8b, 0x08, 0xfb, 0x2f, 0x2c, 0xfb, 0x04, 0xfb, 0x49, 0xfb, 0x41, 0xe9, + 0x21, 0xf7, 0x2d, 0x1f, 0xf7, 0x0d, 0x8b, 0xed, 0xd0, 0xaa, 0xf5, 0x08, + 0xfb, 0x1e, 0x06, 0x7a, 0x60, 0x64, 0x72, 0x58, 0x8b, 0x63, 0x8b, 0x6b, + 0x9c, 0x77, 0xa9, 0x7e, 0x9f, 0x86, 0xa3, 0x89, 0xbe, 0x08, 0xf7, 0xfe, + 0x06, 0xfb, 0xfc, 0xe8, 0x15, 0x94, 0xdd, 0xae, 0xb4, 0xc9, 0x8b, 0xae, + 0x8b, 0xab, 0x7a, 0x9f, 0x6f, 0x98, 0x77, 0x91, 0x76, 0x8e, 0x66, 0x08, + 0xfb, 0x6b, 0x06, 0xf7, 0x93, 0xf8, 0x4a, 0x15, 0xfb, 0x12, 0x8b, 0x45, + 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, 0x0e, 0xf8, 0xa0, + 0xf7, 0x76, 0x15, 0x8c, 0x97, 0x8b, 0x90, 0x8b, 0x92, 0x8b, 0xc1, 0x83, + 0xbd, 0x7e, 0xb1, 0x67, 0xed, 0x34, 0xc6, 0xfb, 0x01, 0x8b, 0x08, 0xfb, + 0x2f, 0x2c, 0xfb, 0x04, 0xfb, 0x49, 0xfb, 0x41, 0xe9, 0x21, 0xf7, 0x2d, + 0x1f, 0xf7, 0x0d, 0x8b, 0xed, 0xd0, 0xaa, 0xf5, 0x08, 0xfb, 0x1e, 0x06, + 0x7a, 0x60, 0x64, 0x72, 0x58, 0x8b, 0x63, 0x8b, 0x6b, 0x9c, 0x77, 0xa9, + 0x7e, 0x9f, 0x86, 0xa3, 0x89, 0xbe, 0x08, 0xf7, 0xfe, 0x06, 0xfb, 0xfc, + 0xe8, 0x15, 0x94, 0xdd, 0xae, 0xb4, 0xc9, 0x8b, 0xae, 0x8b, 0xab, 0x7a, + 0x9f, 0x6f, 0x98, 0x77, 0x91, 0x76, 0x8e, 0x66, 0x08, 0xfb, 0x6b, 0x06, + 0x6c, 0xf8, 0x4a, 0x15, 0xf7, 0x13, 0xfb, 0x2a, 0xd0, 0x8b, 0x46, 0xf7, + 0x2a, 0xfb, 0x13, 0x8b, 0x05, 0x0e, 0xf8, 0xa0, 0xf7, 0x76, 0x15, 0x8c, + 0x97, 0x8b, 0x90, 0x8b, 0x92, 0x8b, 0xc1, 0x83, 0xbd, 0x7e, 0xb1, 0x67, + 0xed, 0x34, 0xc6, 0xfb, 0x01, 0x8b, 0x08, 0xfb, 0x2f, 0x2c, 0xfb, 0x04, + 0xfb, 0x49, 0xfb, 0x41, 0xe9, 0x21, 0xf7, 0x2d, 0x1f, 0xf7, 0x0d, 0x8b, + 0xed, 0xd0, 0xaa, 0xf5, 0x08, 0xfb, 0x1e, 0x06, 0x7a, 0x60, 0x64, 0x72, + 0x58, 0x8b, 0x63, 0x8b, 0x6b, 0x9c, 0x77, 0xa9, 0x7e, 0x9f, 0x86, 0xa3, + 0x89, 0xbe, 0x08, 0xf7, 0xfe, 0x06, 0xfb, 0xfc, 0xe8, 0x15, 0x94, 0xdd, + 0xae, 0xb4, 0xc9, 0x8b, 0xae, 0x8b, 0xab, 0x7a, 0x9f, 0x6f, 0x98, 0x77, + 0x91, 0x76, 0x8e, 0x66, 0x08, 0xfb, 0x6b, 0x06, 0xcc, 0xf8, 0x4a, 0x15, + 0xfb, 0x00, 0xfb, 0x2a, 0xd7, 0x8b, 0xde, 0xef, 0xdc, 0x27, 0xd9, 0x8b, + 0x24, 0xf7, 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0x63, 0xf8, + 0xb0, 0x15, 0xfb, 0x20, 0xfc, 0xb0, 0xf7, 0x20, 0x06, 0xf8, 0xb0, 0x07, + 0x21, 0xf7, 0x5f, 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0x06, 0xf7, + 0x0e, 0x07, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, + 0x0e, 0x06, 0x0e, 0xfc, 0x1d, 0xf7, 0x63, 0xf8, 0xb0, 0x15, 0xfb, 0x20, + 0xfc, 0xb0, 0xf7, 0x20, 0xf8, 0xb0, 0x06, 0xde, 0xf7, 0x6d, 0x15, 0xfb, + 0x12, 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, + 0x0e, 0xfc, 0x1d, 0xf7, 0x63, 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0xfc, 0xb0, + 0xf7, 0x20, 0xf8, 0xb0, 0x06, 0xfb, 0x6d, 0xf7, 0x6d, 0x15, 0xf7, 0x12, + 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, 0x2a, 0xfb, 0x12, 0x8b, 0x05, 0x0e, + 0xfc, 0x1d, 0xf7, 0x63, 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0xfc, 0xb0, 0xf7, + 0x20, 0xf8, 0xb0, 0x06, 0xfb, 0x0a, 0xf7, 0x6d, 0x15, 0xfb, 0x00, 0xfb, + 0x2a, 0xd7, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd9, 0x8b, 0x24, 0xf7, 0x2a, + 0x20, 0x8b, 0x05, 0x0e, 0x4f, 0xca, 0xf8, 0xb0, 0x15, 0xfc, 0xb0, 0xf7, + 0x20, 0xf7, 0xd8, 0x07, 0xcb, 0xb8, 0xb5, 0xcf, 0xc7, 0xa9, 0x6a, 0x4b, + 0x1e, 0xfb, 0xe1, 0xf7, 0x20, 0xf7, 0xfe, 0x07, 0xf7, 0x0b, 0x49, 0xcf, + 0xfb, 0x07, 0x1e, 0x42, 0x8b, 0x5a, 0x70, 0x63, 0x4f, 0x08, 0xd9, 0x07, + 0xfb, 0x20, 0x06, 0xf7, 0xf5, 0xf7, 0x65, 0x15, 0x87, 0x6b, 0x7f, 0x7b, + 0x76, 0x8b, 0x84, 0x8b, 0x77, 0x8e, 0x85, 0x8e, 0x08, 0x43, 0xa4, 0x05, + 0x67, 0x98, 0x8a, 0x8b, 0x79, 0x8b, 0x53, 0x8b, 0x68, 0x5d, 0x87, 0x3d, + 0x08, 0xca, 0x06, 0x90, 0xab, 0x97, 0x98, 0xa2, 0x8b, 0x94, 0x8b, 0x95, + 0x89, 0x96, 0x87, 0x08, 0xd3, 0x71, 0x05, 0x9f, 0x83, 0x9e, 0x87, 0x9a, + 0x8b, 0xc6, 0x8b, 0xab, 0xb5, 0x8f, 0xe0, 0x08, 0x4d, 0x06, 0x0e, 0x4f, + 0xf7, 0xc1, 0xf8, 0xb9, 0x15, 0xfb, 0x39, 0x26, 0xfb, 0x01, 0xfb, 0x45, + 0xfb, 0x46, 0xf0, 0xfb, 0x00, 0xf7, 0x3a, 0xf7, 0x38, 0xf2, 0xf7, 0x01, + 0xf7, 0x41, 0x1f, 0xf7, 0x4b, 0x28, 0xf6, 0xfb, 0x3d, 0x1e, 0x8c, 0xfb, + 0x05, 0x15, 0xd8, 0xbd, 0x46, 0x21, 0x26, 0x57, 0x45, 0x40, 0x3f, 0x58, + 0xd1, 0xf2, 0xf2, 0xbe, 0xd1, 0xd7, 0x1f, 0x65, 0xf7, 0xc7, 0x15, 0xfb, + 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0x06, 0xf7, 0x0e, 0x07, 0xf7, 0x4e, 0x16, + 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, 0x0e, 0x4f, 0xf7, + 0xc1, 0xf8, 0xb9, 0x15, 0xfb, 0x39, 0x26, 0xfb, 0x01, 0xfb, 0x45, 0xfb, + 0x46, 0xf0, 0xfb, 0x00, 0xf7, 0x3a, 0xf7, 0x38, 0xf2, 0xf7, 0x01, 0xf7, + 0x41, 0xf7, 0x4b, 0x28, 0xf6, 0xfb, 0x3d, 0x1f, 0x8c, 0xfb, 0x05, 0x15, + 0xd8, 0xbd, 0x46, 0x21, 0x26, 0x57, 0x45, 0x40, 0x3f, 0x58, 0xd1, 0xf2, + 0xf2, 0xbe, 0xd1, 0xd7, 0x1f, 0xf7, 0x1f, 0xf7, 0xd5, 0x15, 0xfb, 0x12, + 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, 0x0e, + 0x4f, 0xf7, 0xc1, 0xf8, 0xb9, 0x15, 0xfb, 0x39, 0x26, 0xfb, 0x01, 0xfb, + 0x45, 0xfb, 0x46, 0xf0, 0xfb, 0x00, 0xf7, 0x3a, 0xf7, 0x38, 0xf2, 0xf7, + 0x01, 0xf7, 0x41, 0xf7, 0x4b, 0x28, 0xf6, 0xfb, 0x3d, 0x1f, 0x8c, 0xfb, + 0x05, 0x15, 0xd8, 0xbd, 0x46, 0x21, 0x26, 0x57, 0x45, 0x40, 0x3f, 0x58, + 0xd1, 0xf2, 0xf2, 0xbe, 0xd1, 0xd7, 0x1f, 0xfb, 0x1d, 0xf7, 0xd5, 0x15, + 0xf7, 0x12, 0xfb, 0x2a, 0xd1, 0x8b, 0x45, 0xf7, 0x2a, 0xfb, 0x12, 0x8b, + 0x05, 0x0e, 0x4f, 0xf7, 0xc1, 0xf8, 0xb9, 0x15, 0xfb, 0x39, 0x26, 0xfb, + 0x01, 0xfb, 0x45, 0xfb, 0x46, 0xf0, 0xfb, 0x00, 0xf7, 0x3a, 0xf7, 0x38, + 0xf2, 0xf7, 0x01, 0xf7, 0x41, 0xf7, 0x4b, 0x28, 0xf6, 0xfb, 0x3d, 0x1f, + 0x8c, 0xfb, 0x05, 0x15, 0xd8, 0xbd, 0x46, 0x21, 0x26, 0x57, 0x45, 0x40, + 0x3f, 0x58, 0xd1, 0xf2, 0xf2, 0xbe, 0xd1, 0xd7, 0x1f, 0x58, 0xf7, 0xd5, + 0x15, 0xfb, 0x00, 0xfb, 0x2a, 0xd7, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd9, + 0x8b, 0x24, 0xf7, 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0x4f, 0xf7, 0xc1, 0xf8, + 0xb9, 0x15, 0xfb, 0x39, 0x26, 0xfb, 0x01, 0xfb, 0x45, 0xfb, 0x46, 0xf0, + 0xfb, 0x00, 0xf7, 0x3a, 0xf7, 0x38, 0xf2, 0xf7, 0x01, 0xf7, 0x41, 0x1f, + 0xf7, 0x4b, 0x28, 0xf6, 0xfb, 0x3d, 0x1e, 0x8c, 0xfb, 0x05, 0x15, 0xd8, + 0xbd, 0x46, 0x21, 0x26, 0x57, 0x45, 0x40, 0x3f, 0x58, 0xd1, 0xf2, 0xf2, + 0xbe, 0xd1, 0xd7, 0x1f, 0xf7, 0x0a, 0xf7, 0xcd, 0x15, 0x87, 0x6b, 0x7f, + 0x7b, 0x77, 0x8b, 0x84, 0x8b, 0x76, 0x8e, 0x85, 0x8e, 0x08, 0x43, 0xa4, + 0x05, 0x67, 0x98, 0x8a, 0x8b, 0x79, 0x8b, 0x53, 0x8b, 0x68, 0x5d, 0x87, + 0x3d, 0x08, 0xca, 0x06, 0x90, 0xab, 0x97, 0x98, 0xa2, 0x8b, 0x95, 0x8b, + 0x94, 0x89, 0x97, 0x87, 0x08, 0xd2, 0x71, 0x05, 0x9f, 0x83, 0x9e, 0x87, + 0x9a, 0x8b, 0xc7, 0x8b, 0xaa, 0xb5, 0x8f, 0xe0, 0x08, 0x4d, 0x06, 0x0e, + 0xf8, 0x8d, 0xf8, 0x02, 0x15, 0x89, 0xf7, 0x06, 0x33, 0xd0, 0xfb, 0x25, + 0x8b, 0xfb, 0x1d, 0x8b, 0x36, 0x46, 0x8b, 0xfb, 0x03, 0x8b, 0x67, 0x96, + 0x6c, 0x9e, 0x76, 0x9e, 0x78, 0x9c, 0x82, 0xbf, 0x7a, 0x08, 0xf7, 0x3b, + 0x57, 0x05, 0xae, 0x80, 0x97, 0x80, 0x8b, 0x75, 0x8b, 0x6a, 0x64, 0x77, + 0x4a, 0x8b, 0x67, 0x8b, 0x6e, 0x92, 0x79, 0x97, 0x7c, 0x96, 0x85, 0x96, + 0x85, 0xa8, 0x08, 0xfb, 0x1d, 0x06, 0x8f, 0xfb, 0x0a, 0xe2, 0x4d, 0xf7, + 0x38, 0x8b, 0xd6, 0x8b, 0xc4, 0x9b, 0xb3, 0xab, 0xb3, 0xab, 0xa3, 0xbd, + 0x8b, 0xc0, 0x8b, 0xd1, 0x68, 0xb8, 0x44, 0xa0, 0x08, 0xfb, 0x45, 0xbe, + 0x05, 0x64, 0x97, 0x81, 0x93, 0x8b, 0xa1, 0x8b, 0xa9, 0xab, 0x9f, 0xbc, + 0x8b, 0xce, 0x8b, 0xac, 0x73, 0x8c, 0x5a, 0x08, 0xf7, 0x1b, 0x06, 0xfb, + 0x40, 0xf7, 0x85, 0x15, 0xf6, 0xf7, 0x2a, 0x3f, 0x8b, 0x39, 0x2a, 0x39, + 0xec, 0x3d, 0x8b, 0xf2, 0xfb, 0x2a, 0xf7, 0x00, 0x8b, 0x05, 0x0e, 0x4f, + 0xf8, 0xb1, 0x16, 0xf8, 0xb0, 0xfb, 0x20, 0xfb, 0xe6, 0x07, 0x4b, 0x5e, + 0x61, 0x47, 0x4f, 0x6d, 0xab, 0xcc, 0x1e, 0xf7, 0xef, 0xfb, 0x20, 0xfc, + 0x0c, 0x07, 0xfb, 0x0b, 0xcd, 0x47, 0xf7, 0x07, 0x1e, 0xd4, 0x8b, 0xbc, + 0xa6, 0xb3, 0xc7, 0x08, 0x4b, 0x07, 0xf7, 0x20, 0x06, 0xfb, 0xac, 0xf9, + 0x7b, 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0x06, 0xf7, 0x0e, 0x07, + 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, 0x06, + 0x0e, 0x4f, 0xf8, 0xb1, 0x16, 0xf8, 0xb0, 0xfb, 0x20, 0xfb, 0xe6, 0x07, + 0x4b, 0x5e, 0x61, 0x47, 0x4f, 0x6d, 0xab, 0xcc, 0x1e, 0xf7, 0xef, 0xfb, + 0x20, 0xfc, 0x0c, 0x07, 0xfb, 0x0b, 0xcd, 0x47, 0xf7, 0x07, 0x1e, 0xd4, + 0x8b, 0xbc, 0xa6, 0xb3, 0xc7, 0x08, 0x4b, 0x07, 0xf7, 0x20, 0x06, 0x24, + 0xf9, 0x89, 0x15, 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, + 0x12, 0xf7, 0x2a, 0x05, 0x0e, 0x4f, 0xf8, 0xb1, 0x16, 0xf8, 0xb0, 0xfb, + 0x20, 0xfb, 0xe6, 0x07, 0x4b, 0x5e, 0x61, 0x47, 0x4f, 0x6d, 0xab, 0xcc, + 0x1e, 0xf7, 0xef, 0xfb, 0x20, 0xfc, 0x0c, 0x07, 0xfb, 0x0b, 0xcd, 0x47, + 0xf7, 0x07, 0x1e, 0xd4, 0x8b, 0xbc, 0xa6, 0xb3, 0xc7, 0x08, 0x4b, 0x07, + 0xf7, 0x20, 0x06, 0xfc, 0x0e, 0xf9, 0x89, 0x15, 0xf7, 0x12, 0xfb, 0x2a, + 0xd1, 0x8b, 0x45, 0xf7, 0x2a, 0xfb, 0x12, 0x8b, 0x05, 0x0e, 0x4f, 0xf8, + 0xb1, 0x16, 0xf8, 0xb0, 0xfb, 0x20, 0xfb, 0xe6, 0x07, 0x4b, 0x5e, 0x61, + 0x47, 0x4f, 0x6d, 0xab, 0xcc, 0x1e, 0xf7, 0xef, 0xfb, 0x20, 0xfc, 0x0c, + 0x07, 0xfb, 0x0b, 0xcd, 0x47, 0xf7, 0x07, 0x1e, 0xd4, 0x8b, 0xbc, 0xa6, + 0xb3, 0xc7, 0x08, 0x4b, 0x07, 0xf7, 0x20, 0x06, 0xfb, 0xb9, 0xf9, 0x89, + 0x15, 0xfb, 0x00, 0xfb, 0x2a, 0xd8, 0x8b, 0xdd, 0xef, 0xdd, 0x27, 0xd8, + 0x8b, 0x24, 0xf7, 0x2a, 0x20, 0x8b, 0x05, 0x0e, 0xf8, 0x1e, 0xf8, 0xb0, + 0x15, 0xfb, 0x04, 0xfc, 0x1d, 0xfb, 0x0b, 0xf8, 0x1d, 0xfb, 0x2e, 0x8b, + 0xf7, 0x5d, 0xfc, 0xc6, 0x8b, 0x8a, 0x8b, 0x88, 0x05, 0x58, 0x65, 0x64, + 0x5a, 0x1e, 0x80, 0x8b, 0x83, 0x8c, 0x79, 0x90, 0x08, 0x22, 0x07, 0xa0, + 0x88, 0x97, 0x8a, 0x9c, 0x8b, 0xae, 0x8b, 0xb5, 0x92, 0xa3, 0x95, 0xb2, + 0x9b, 0x9c, 0xa2, 0xa2, 0xcb, 0x08, 0xf7, 0x72, 0xf9, 0x13, 0xfb, 0x24, + 0x8b, 0x05, 0x9d, 0xf7, 0x6d, 0x15, 0xfb, 0x12, 0x8b, 0x45, 0xfb, 0x2a, + 0xd1, 0x8b, 0xf7, 0x12, 0xf7, 0x2a, 0x05, 0x0e, 0xfb, 0x3f, 0xf8, 0x5f, + 0xf8, 0xb0, 0x15, 0xfc, 0x38, 0xfb, 0x05, 0xf7, 0x8d, 0x06, 0xfb, 0x9f, + 0xfb, 0xce, 0x8b, 0xfb, 0x05, 0xf8, 0x53, 0x8b, 0x8b, 0xf7, 0x05, 0xfb, + 0xa6, 0x8b, 0xf7, 0x9d, 0xf7, 0xce, 0x8b, 0xf7, 0x05, 0x05, 0xfb, 0x30, + 0xce, 0x15, 0xf6, 0xf7, 0x2a, 0x3f, 0x8b, 0x39, 0x2a, 0x39, 0xec, 0x3d, + 0x8b, 0xf2, 0xfb, 0x2a, 0xf7, 0x00, 0x8b, 0x05, 0x0e, 0x4f, 0xf8, 0x44, + 0xf9, 0x5a, 0x15, 0x58, 0xad, 0x34, 0x57, 0x05, 0x83, 0x8e, 0x85, 0x8e, + 0x8a, 0x8c, 0x5c, 0xa5, 0x88, 0x8d, 0x66, 0x99, 0x08, 0x48, 0x5c, 0x05, + 0xbc, 0x73, 0x99, 0x83, 0xa6, 0x7b, 0x08, 0x45, 0x5f, 0xb5, 0x66, 0xd8, + 0xb9, 0x05, 0xb1, 0x75, 0xa9, 0x6c, 0xa6, 0x60, 0x64, 0x9a, 0x77, 0x8f, + 0x71, 0x8b, 0x60, 0x8b, 0x5f, 0x7e, 0x64, 0x73, 0x3f, 0x5e, 0x66, 0x3e, + 0x8b, 0xfb, 0x02, 0x08, 0xfb, 0x48, 0xef, 0xfb, 0x00, 0xf7, 0x3b, 0xf7, + 0x3c, 0xee, 0xf7, 0x00, 0xf7, 0x4c, 0x1e, 0x8b, 0xf7, 0x3a, 0x45, 0xf7, + 0x0f, 0xfb, 0x2b, 0xf1, 0x08, 0xdf, 0xbd, 0x05, 0xfb, 0x16, 0xfb, 0xad, + 0x15, 0xd8, 0xbc, 0x48, 0x22, 0x27, 0x59, 0x48, 0x3f, 0x3f, 0x59, 0xce, + 0xf2, 0xf1, 0xbd, 0xce, 0xd7, 0x1f, 0x0e, 0x4f, 0xf7, 0x5a, 0xf9, 0x6d, + 0x15, 0xfb, 0x20, 0xfe, 0x47, 0xf7, 0x20, 0xf7, 0xae, 0x06, 0xad, 0x50, + 0xbb, 0x6f, 0xcf, 0x8b, 0x08, 0xf7, 0x16, 0xeb, 0xf7, 0x0e, 0xf7, 0x37, + 0xf7, 0x39, 0x2b, 0xf7, 0x0e, 0xfb, 0x16, 0x1f, 0x47, 0x8b, 0x5b, 0x6e, + 0x69, 0x4f, 0x08, 0xf7, 0xa1, 0x07, 0xf7, 0x0a, 0xfb, 0xbd, 0x15, 0xd2, + 0xba, 0x46, 0x24, 0x29, 0x5a, 0x47, 0x46, 0x45, 0x5b, 0xcf, 0xef, 0xf0, + 0xbb, 0xd0, 0xd1, 0x1f, 0x0e, 0xf8, 0x1e, 0xf8, 0xb0, 0x15, 0xfb, 0x04, + 0xfc, 0x1d, 0xfb, 0x0b, 0xf8, 0x1d, 0xfb, 0x2e, 0x8b, 0xf7, 0x5d, 0xfc, + 0xc6, 0x8b, 0x8a, 0x8b, 0x88, 0x05, 0x58, 0x65, 0x64, 0x5a, 0x1e, 0x80, + 0x8b, 0x83, 0x8c, 0x79, 0x90, 0x08, 0x22, 0x07, 0xa0, 0x88, 0x97, 0x8a, + 0x9c, 0x8b, 0xae, 0x8b, 0xb5, 0x92, 0xa3, 0x95, 0xb2, 0x9b, 0x9c, 0xa2, + 0xa2, 0xcb, 0x08, 0xf7, 0x72, 0xf9, 0x13, 0xfb, 0x24, 0x8b, 0x05, 0xfb, + 0x33, 0xf7, 0x5f, 0x15, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, + 0x06, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0xfb, 0x0e, 0xf7, 0x02, 0xf7, 0x0e, + 0x06, 0x0e, 0xa9, 0xf7, 0xd2, 0x15, 0x73, 0x47, 0xd3, 0x8b, 0x05, 0x98, + 0x4b, 0x9f, 0x57, 0xaa, 0x5d, 0xb8, 0x48, 0xde, 0x5f, 0xda, 0x8b, 0xb2, + 0x8b, 0xad, 0x93, 0xda, 0xa5, 0x08, 0xf7, 0x29, 0x07, 0x3d, 0x61, 0x6f, + 0x81, 0x63, 0x8b, 0x4f, 0x8b, 0x5b, 0xbe, 0x71, 0xe6, 0x08, 0xf7, 0x49, + 0x8b, 0xa4, 0xcf, 0xfb, 0x6d, 0x8b, 0x05, 0x89, 0x95, 0x8b, 0x92, 0x8b, + 0x95, 0x8b, 0x99, 0x8c, 0x96, 0x8d, 0x9b, 0x08, 0xf7, 0x84, 0x8b, 0xa3, + 0xcf, 0xfb, 0x8f, 0x8b, 0x05, 0xa3, 0xe7, 0xb8, 0xbb, 0xc9, 0x8b, 0xb8, + 0x8b, 0xb1, 0x7a, 0xca, 0x59, 0x08, 0xb8, 0xf7, 0x15, 0x05, 0x43, 0xc0, + 0x63, 0x9a, 0x45, 0x8b, 0xfb, 0x24, 0x8b, 0x22, 0x28, 0x66, 0xfb, 0x3f, + 0x08, 0x5b, 0x8b, 0x73, 0x47, 0xca, 0x8b, 0x05, 0x8a, 0x7f, 0x8b, 0x82, + 0x8b, 0x7f, 0x8b, 0x7f, 0x8b, 0x82, 0x8d, 0x7d, 0x08, 0x63, 0x06, 0x0e, + 0xfb, 0xe6, 0xf7, 0x22, 0xf8, 0xd1, 0x15, 0xfb, 0xb5, 0xea, 0xf8, 0x3d, + 0x4b, 0x07, 0x7d, 0x59, 0x5d, 0x72, 0x3d, 0x8b, 0x08, 0x4e, 0xf6, 0x07, + 0x0e, 0xfb, 0xe6, 0xf7, 0xd3, 0xf8, 0x01, 0x15, 0xfb, 0x4f, 0x06, 0x99, + 0x9c, 0x91, 0x92, 0x93, 0x91, 0x91, 0x90, 0xa1, 0x9b, 0xaa, 0xa1, 0xdb, + 0xc2, 0xa1, 0xaa, 0x8b, 0xc7, 0x08, 0xe1, 0x55, 0xbb, 0x2a, 0x27, 0x53, + 0x58, 0x2f, 0x1e, 0x8b, 0x88, 0x8b, 0x84, 0x8c, 0x83, 0x08, 0xe7, 0x06, + 0x8a, 0x92, 0x8a, 0x92, 0x8b, 0x8d, 0x08, 0xb8, 0xa1, 0xa5, 0xb1, 0xb1, + 0xa2, 0x73, 0x63, 0x1e, 0x8b, 0x5e, 0x7d, 0x7b, 0x28, 0x49, 0x3d, 0x59, + 0x74, 0x65, 0x88, 0x3a, 0x08, 0xf7, 0xca, 0xdc, 0x06, 0x0e, 0xfb, 0xe6, + 0xf7, 0x13, 0xf8, 0x6b, 0x15, 0x9b, 0x06, 0xc2, 0x8a, 0xa8, 0x76, 0x8b, + 0x62, 0x8b, 0x68, 0x71, 0x72, 0x67, 0x8b, 0x61, 0x8b, 0x77, 0xa0, 0x88, + 0xb8, 0x08, 0x2f, 0x06, 0x8c, 0x30, 0xc3, 0x57, 0xed, 0x8b, 0xeb, 0x8b, + 0xca, 0xc1, 0x8b, 0xdf, 0x8b, 0xba, 0x75, 0xae, 0x5f, 0xa0, 0x08, 0xad, + 0xa0, 0x9d, 0xa9, 0x8b, 0xb1, 0x8b, 0xd2, 0x52, 0xb9, 0x33, 0x8b, 0x57, + 0x8b, 0x60, 0x79, 0x72, 0x6c, 0x78, 0x73, 0x84, 0x73, 0x89, 0x59, 0x08, + 0xe3, 0x06, 0x8b, 0xa4, 0x8d, 0x96, 0x90, 0x95, 0x92, 0x9c, 0x9e, 0x96, + 0xa3, 0x8b, 0x08, 0xab, 0xa0, 0x76, 0x6a, 0x65, 0x71, 0x77, 0x5a, 0x1f, + 0x80, 0x06, 0x4d, 0x07, 0x0e, 0xfc, 0x1d, 0xcb, 0xf7, 0xb8, 0x15, 0xfb, + 0x0f, 0xf7, 0x10, 0xf7, 0x0f, 0xfb, 0x10, 0x07, 0x0e, 0xfb, 0xe6, 0xf7, + 0xbe, 0xf7, 0xea, 0x15, 0xfb, 0xa4, 0xfb, 0x1b, 0xf7, 0xa4, 0xf7, 0x1b, + 0x06, 0x0e, 0xfb, 0xa3, 0xf7, 0x5c, 0xf9, 0x42, 0x15, 0x37, 0x47, 0x47, + 0x38, 0x38, 0xcf, 0x46, 0xdd, 0xe0, 0xcf, 0xce, 0xe0, 0xde, 0x47, 0xcf, + 0x38, 0x1f, 0x4c, 0x04, 0xbb, 0xb3, 0x63, 0x5b, 0x59, 0x63, 0x64, 0x59, + 0x5c, 0x63, 0xb4, 0xba, 0xbc, 0xb3, 0xb3, 0xbc, 0x1f, 0x0e, 0x34, 0xf8, + 0xb4, 0xf7, 0xb7, 0x15, 0xfc, 0x8c, 0xfb, 0x0b, 0xf8, 0x8c, 0xf7, 0x0b, + 0x06, 0x0e, 0x34, 0xf8, 0x39, 0xf8, 0x50, 0x15, 0xfb, 0x15, 0xfb, 0x15, + 0xfb, 0x15, 0xf7, 0x15, 0x37, 0x36, 0xf7, 0x15, 0xfb, 0x14, 0xfb, 0x14, + 0xfb, 0x14, 0xdf, 0x37, 0xf7, 0x14, 0xf7, 0x14, 0xf7, 0x14, 0xfb, 0x15, + 0xdf, 0xdf, 0xfb, 0x14, 0xf7, 0x15, 0xf7, 0x15, 0xf7, 0x15, 0x37, 0xdf, + 0x05, 0x0e, 0x34, 0xf8, 0xaa, 0xf7, 0xb7, 0x15, 0xfc, 0x78, 0xfb, 0x0b, + 0xf8, 0x78, 0xf7, 0x0b, 0x06, 0xfb, 0xc4, 0xf7, 0x4b, 0x15, 0xfb, 0x0f, + 0xf7, 0x10, 0xf7, 0x0f, 0xfb, 0x10, 0x07, 0xfb, 0xfe, 0x04, 0xfb, 0x0f, + 0xf7, 0x10, 0xf7, 0x0f, 0xfb, 0x10, 0x07, 0x0e, 0xf7, 0xdd, 0xf7, 0xc3, + 0xf9, 0x1f, 0x15, 0xf7, 0x19, 0xd9, 0xfc, 0x01, 0x3d, 0xf7, 0x1d, 0xfc, + 0x0e, 0xea, 0xf8, 0x0e, 0x06, 0xf8, 0x58, 0xfc, 0x0e, 0x15, 0xde, 0xf7, + 0xf1, 0x8b, 0xfb, 0xf1, 0xe6, 0x8b, 0x8b, 0xf8, 0x5c, 0xfb, 0x1d, 0x8b, + 0x37, 0xfb, 0xf2, 0x35, 0xf7, 0xf2, 0xfb, 0x1d, 0x8b, 0x8b, 0xfc, 0x5c, + 0xe6, 0x8b, 0x8b, 0xf7, 0xf1, 0xe0, 0xfb, 0xf1, 0xe9, 0x8b, 0x05, 0x0e, + 0x34, 0xf8, 0xa3, 0xf2, 0x15, 0xfc, 0x6b, 0xfb, 0x0b, 0xf8, 0x6b, 0xf7, + 0x0b, 0x06, 0xf7, 0xdd, 0x04, 0xfb, 0x44, 0xf7, 0x44, 0xfb, 0x0b, 0xfb, + 0x44, 0xfb, 0x44, 0xfb, 0x0b, 0xf7, 0x44, 0xfb, 0x44, 0xf7, 0x0b, 0xf7, + 0x44, 0xf7, 0x44, 0xf7, 0x0b, 0x06, 0x0e, 0xf7, 0x37, 0xf7, 0x11, 0xf8, + 0xd1, 0x15, 0xfb, 0xb5, 0xea, 0xf8, 0x3d, 0x4b, 0x07, 0x7d, 0x59, 0x5d, + 0x72, 0x3d, 0x8b, 0x08, 0x4e, 0xf6, 0x07, 0xf8, 0x4c, 0xf7, 0x22, 0x15, + 0xfc, 0x3b, 0xfd, 0x73, 0xe2, 0x8b, 0xf8, 0x3b, 0xf9, 0x73, 0x34, 0x8b, + 0x05, 0xf7, 0x95, 0xfd, 0x0e, 0x15, 0xfb, 0x4f, 0x06, 0x99, 0x9c, 0x91, + 0x92, 0x93, 0x91, 0x91, 0x90, 0xa2, 0x9c, 0xa9, 0xa0, 0xdb, 0xc2, 0xa1, + 0xaa, 0x8b, 0xc7, 0x08, 0xe1, 0x55, 0xbb, 0x2a, 0x27, 0x53, 0x58, 0x2f, + 0x1e, 0x8b, 0x88, 0x8b, 0x84, 0x8c, 0x83, 0x08, 0xe7, 0x06, 0x8a, 0x92, + 0x8a, 0x92, 0x8b, 0x8d, 0x08, 0xb8, 0xa1, 0xa5, 0xb1, 0xb1, 0xa2, 0x73, + 0x63, 0x1e, 0x8b, 0x5e, 0x7d, 0x7b, 0x28, 0x49, 0x3d, 0x59, 0x74, 0x65, + 0x88, 0x3a, 0x08, 0xf7, 0xca, 0xdc, 0x06, 0x0e, 0xf7, 0x37, 0xf7, 0x0f, + 0xf8, 0xd1, 0x15, 0xfb, 0xb5, 0xea, 0xf8, 0x3d, 0x4b, 0x07, 0x7d, 0x59, + 0x5d, 0x72, 0x3d, 0x8b, 0x08, 0x4e, 0xf6, 0x07, 0xf8, 0x52, 0xf7, 0x22, + 0x15, 0xfc, 0x3b, 0xfd, 0x73, 0xe2, 0x8b, 0xf8, 0x3b, 0xf9, 0x73, 0x34, + 0x8b, 0x05, 0xf7, 0x95, 0xfc, 0xb7, 0x15, 0x5d, 0xf7, 0x95, 0xfb, 0x01, + 0x06, 0xfb, 0x39, 0xfb, 0x96, 0x8b, 0x41, 0xf7, 0x47, 0x8b, 0x8b, 0x2e, + 0xea, 0x8b, 0x8b, 0xe8, 0xb9, 0x8b, 0x8b, 0xd6, 0x05, 0xfb, 0x21, 0x16, + 0x21, 0x8b, 0xf5, 0xf7, 0x38, 0x8b, 0xfb, 0x38, 0x05, 0x0e, 0xf7, 0x37, + 0xf7, 0x0b, 0xf8, 0x6b, 0x15, 0x9b, 0x06, 0xc2, 0x8a, 0xa8, 0x76, 0x8b, + 0x62, 0x8b, 0x68, 0x71, 0x72, 0x67, 0x8b, 0x61, 0x8b, 0x77, 0xa0, 0x88, + 0xb8, 0x08, 0x2f, 0x06, 0x8c, 0x30, 0xc3, 0x57, 0xed, 0x8b, 0xeb, 0x8b, + 0xca, 0xc1, 0x8b, 0xdf, 0x8b, 0xba, 0x75, 0xae, 0x5f, 0xa0, 0x08, 0xad, + 0xa0, 0x9d, 0xa9, 0x8b, 0xb1, 0x8b, 0xd2, 0x52, 0xb9, 0x33, 0x8b, 0x57, + 0x8b, 0x60, 0x79, 0x72, 0x6c, 0x78, 0x73, 0x84, 0x73, 0x89, 0x59, 0x08, + 0xe3, 0x06, 0x8b, 0xa4, 0x8d, 0x96, 0x90, 0x95, 0x92, 0x9c, 0x9e, 0x96, + 0xa3, 0x8b, 0x08, 0xab, 0xa0, 0x76, 0x6a, 0x65, 0x71, 0x77, 0x5a, 0x1f, + 0x80, 0x06, 0x4d, 0x07, 0xf8, 0x7f, 0xf7, 0x88, 0x15, 0xfc, 0x3b, 0xfd, + 0x73, 0xe2, 0x8b, 0xf8, 0x3b, 0xf9, 0x73, 0x34, 0x8b, 0x05, 0xf7, 0x75, + 0xfc, 0xb7, 0x15, 0x5d, 0xf7, 0x95, 0xfb, 0x01, 0x06, 0xfb, 0x39, 0xfb, + 0x96, 0x8b, 0x41, 0xf7, 0x47, 0x8b, 0x8b, 0x2e, 0xea, 0x8b, 0x8b, 0xe8, + 0xb9, 0x8b, 0x8b, 0xd6, 0x05, 0xfb, 0x21, 0x16, 0x21, 0x8b, 0xf5, 0xf7, + 0x38, 0x8b, 0xfb, 0x38, 0x05, 0x0e, 0xcd, 0xf8, 0xbc, 0xf8, 0x43, 0x15, + 0x88, 0xb4, 0x83, 0xa3, 0x78, 0xa5, 0x69, 0xb8, 0x54, 0xa4, 0x49, 0x8b, + 0x08, 0xfb, 0x12, 0x3d, 0x32, 0xfb, 0x23, 0xfb, 0x22, 0xd9, 0x31, 0xf7, + 0x0f, 0x1f, 0xf7, 0x04, 0x8b, 0xd4, 0xcb, 0x90, 0xf4, 0x08, 0x2f, 0x06, + 0x86, 0x53, 0x69, 0x6d, 0x52, 0x8b, 0x08, 0x45, 0x62, 0xc2, 0xe8, 0xe9, + 0xb6, 0xc3, 0xd2, 0x1f, 0xc0, 0x8b, 0xa8, 0x73, 0x96, 0x55, 0x08, 0xe5, + 0x06, 0xfb, 0x4b, 0xf7, 0xcc, 0x15, 0xfb, 0x67, 0xfb, 0x40, 0xfb, 0x40, + 0xfb, 0x66, 0xfb, 0x65, 0xf7, 0x40, 0xfb, 0x42, 0xf7, 0x62, 0xf7, 0x6c, + 0xf7, 0x3f, 0xf7, 0x3d, 0xf7, 0x6a, 0xf7, 0x67, 0xfb, 0x40, 0xf7, 0x3f, + 0xfb, 0x66, 0x1f, 0x8a, 0x43, 0x15, 0xf7, 0x3c, 0xf7, 0x1d, 0xfb, 0x1f, + 0xfb, 0x3f, 0xfb, 0x41, 0xfb, 0x1c, 0xfb, 0x1e, 0xfb, 0x40, 0xfb, 0x38, + 0xfb, 0x1d, 0xf7, 0x22, 0xf7, 0x3d, 0xf7, 0x3f, 0xf7, 0x1d, 0xf7, 0x1f, + 0xf7, 0x3b, 0x1f, 0x0e, 0xcd, 0xf7, 0xb4, 0xf7, 0xcd, 0x15, 0xe7, 0x06, + 0xb5, 0x9e, 0x7c, 0x69, 0x1f, 0x7a, 0x07, 0x8a, 0x81, 0x8b, 0x83, 0x8b, + 0x83, 0x8b, 0x5f, 0x8d, 0x7d, 0x97, 0x74, 0x08, 0xf2, 0xa0, 0x06, 0x7c, + 0x93, 0x87, 0x92, 0x8b, 0x9e, 0x88, 0xf7, 0x14, 0x89, 0x92, 0x57, 0xa3, + 0xbc, 0xa3, 0xa0, 0xad, 0x8b, 0xbd, 0x08, 0xd7, 0x5e, 0xb8, 0x3f, 0x1e, + 0xfb, 0x82, 0xfc, 0x4f, 0xeb, 0xf7, 0x41, 0x06, 0xdc, 0x04, 0xf7, 0x00, + 0xf2, 0x07, 0xbb, 0x9b, 0x7e, 0x62, 0x62, 0x7b, 0x7e, 0x5b, 0x1f, 0x24, + 0x06, 0xdc, 0xf7, 0xf1, 0x15, 0xfb, 0x67, 0xfb, 0x40, 0xfb, 0x40, 0xfb, + 0x66, 0xfb, 0x65, 0xf7, 0x40, 0xfb, 0x42, 0xf7, 0x62, 0xf7, 0x6c, 0xf7, + 0x3f, 0xf7, 0x3d, 0xf7, 0x6a, 0xf7, 0x67, 0xfb, 0x40, 0xf7, 0x3f, 0xfb, + 0x66, 0x1f, 0x8a, 0x43, 0x15, 0xf7, 0x3c, 0xf7, 0x1d, 0xfb, 0x1f, 0xfb, + 0x3f, 0xfb, 0x41, 0xfb, 0x1c, 0xfb, 0x1e, 0xfb, 0x40, 0xfb, 0x38, 0xfb, + 0x1d, 0xf7, 0x22, 0xf7, 0x3d, 0xf7, 0x3f, 0xf7, 0x1d, 0xf7, 0x1f, 0xf7, + 0x3b, 0x1f, 0x0e, 0xfc, 0x1d, 0x0e, 0x34, 0xb3, 0xf8, 0x0b, 0x15, 0x3e, + 0xf8, 0x3f, 0xfb, 0x68, 0xd8, 0xf7, 0xb5, 0xfc, 0x8c, 0x07, 0x0e, 0xfc, + 0x1b, 0xf7, 0x48, 0xf9, 0x6d, 0x15, 0x3b, 0xfc, 0x19, 0xdb, 0xf8, 0x19, + 0x06, 0xfc, 0xb0, 0x04, 0x3b, 0xfc, 0x19, 0xdb, 0xf8, 0x19, 0x06, 0x0e, + 0x4f, 0xf7, 0x54, 0xfb, 0x70, 0x15, 0xf7, 0x7f, 0x07, 0xa7, 0x70, 0xaa, + 0x80, 0xb4, 0x8b, 0xb9, 0x8b, 0xaa, 0x99, 0xb2, 0xb3, 0x08, 0xa3, 0x63, + 0xa3, 0x7d, 0xba, 0x8b, 0xa7, 0x8b, 0x9e, 0x90, 0xa2, 0x97, 0x08, 0xe2, + 0x07, 0x81, 0x88, 0x87, 0x8a, 0x85, 0x8b, 0x08, 0x73, 0x85, 0x9a, 0xc5, + 0x1f, 0xf8, 0x1a, 0xfb, 0x20, 0xfb, 0xe6, 0x07, 0x4d, 0x61, 0x5f, 0x50, + 0x1e, 0x6f, 0x8b, 0x73, 0x97, 0x7d, 0xa0, 0x7d, 0x9f, 0x87, 0x9d, 0x8b, + 0xb2, 0x08, 0xf7, 0xe2, 0xfb, 0x20, 0xfd, 0x8c, 0x07, 0xf7, 0x1a, 0x06, + 0x0e, 0xf8, 0xc0, 0x14, 0xf9, 0x33, 0x15, 0x74, 0xa2, 0xf8, 0xb0, 0x94, + 0xf7, 0x48, 0x97, 0x63, 0xa2, 0x06, 0x1e, 0x0a, 0x03, 0x96, 0x25, 0xff, + 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xf7, 0x0a, 0x0a, 0xf5, 0x93, 0x8f, 0x94, + 0x0c, 0x0c, 0xf7, 0x21, 0x0b, 0xf7, 0x21, 0x95, 0x0c, 0x0d, 0x8b, 0x0c, + 0x0e, 0x00, 0x00, 0x00 +}; +const unsigned int fonts_NimbusSanL_Bold_cff_len = 17476; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusSanL-BoldItal.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusSanL-BoldItal.cff.c new file mode 100644 index 00000000000..f47aac6f240 --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusSanL-BoldItal.cff.c @@ -0,0 +1,1667 @@ +const unsigned char fonts_NimbusSanL_BoldItal_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x14, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x53, 0x61, 0x6e, 0x4c, 0x2d, 0x42, 0x6f, 0x6c, 0x64, + 0x49, 0x74, 0x61, 0x6c, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x3c, 0xf8, + 0x1f, 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, + 0x14, 0x04, 0x7f, 0x0c, 0x02, 0xfb, 0x03, 0x0c, 0x03, 0xd0, 0x0c, 0x04, + 0x1d, 0x00, 0x4c, 0x9c, 0xee, 0x0d, 0xfb, 0x45, 0xfb, 0x7d, 0xfa, 0xe7, + 0xfa, 0x4d, 0x05, 0x1c, 0x00, 0xf9, 0x0f, 0x1c, 0x00, 0x00, 0x10, 0x1c, + 0x02, 0xca, 0x11, 0x1c, 0x00, 0x2c, 0x1c, 0x4d, 0xd3, 0x12, 0x00, 0x08, + 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, + 0x1f, 0x00, 0x5f, 0x00, 0x78, 0x00, 0x85, 0x45, 0x75, 0x72, 0x6f, 0x6d, + 0x69, 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, + 0x65, 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, + 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, + 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, + 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, + 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, + 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, + 0x53, 0x61, 0x6e, 0x73, 0x20, 0x4c, 0x20, 0x42, 0x6f, 0x6c, 0x64, 0x20, + 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, + 0x20, 0x53, 0x61, 0x6e, 0x73, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, + 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, + 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, + 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, + 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, + 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, + 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, + 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, + 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, + 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, + 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, + 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, + 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, + 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, + 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, + 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, + 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, + 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, + 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, + 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, + 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, + 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, + 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, + 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, + 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, + 0x00, 0xae, 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, + 0x00, 0xb4, 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, + 0x00, 0xb9, 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, + 0x00, 0xbc, 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, + 0x00, 0xc2, 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, + 0x00, 0xc8, 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, + 0x00, 0xd1, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, + 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, + 0x00, 0xd9, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, + 0x00, 0xdf, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, + 0x01, 0x87, 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, + 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, + 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, + 0x00, 0x97, 0x00, 0xa0, 0x00, 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x07, 0x00, 0x33, 0x00, 0x62, 0x00, 0xbd, 0x01, 0x77, 0x01, + 0xea, 0x02, 0x80, 0x02, 0xa6, 0x02, 0xdc, 0x03, 0x15, 0x03, 0x40, 0x03, + 0x6c, 0x03, 0x93, 0x03, 0xa8, 0x03, 0xbd, 0x03, 0xd2, 0x04, 0x31, 0x04, + 0x52, 0x04, 0xab, 0x05, 0x2c, 0x05, 0x61, 0x05, 0xc2, 0x06, 0x30, 0x06, + 0x60, 0x06, 0xdb, 0x07, 0x4a, 0x07, 0x70, 0x07, 0xaa, 0x07, 0xcb, 0x07, + 0xf0, 0x08, 0x0f, 0x08, 0x77, 0x09, 0x5b, 0x09, 0x8b, 0x0a, 0x02, 0x0a, + 0x63, 0x0a, 0xaa, 0x0a, 0xd7, 0x0a, 0xfe, 0x0b, 0x6f, 0x0b, 0x9d, 0x0b, + 0xb4, 0x0b, 0xfc, 0x0c, 0x2c, 0x0c, 0x48, 0x0c, 0x7c, 0x0c, 0xa8, 0x0d, + 0x0a, 0x0d, 0x5b, 0x0d, 0xce, 0x0e, 0x61, 0x0e, 0xeb, 0x0f, 0x0d, 0x0f, + 0x57, 0x0f, 0x74, 0x0f, 0xa6, 0x0f, 0xd8, 0x0f, 0xfe, 0x10, 0x26, 0x10, + 0x47, 0x10, 0x5a, 0x10, 0x7a, 0x10, 0x99, 0x10, 0xa9, 0x10, 0xcf, 0x11, + 0x7f, 0x11, 0xcd, 0x12, 0x33, 0x12, 0x84, 0x12, 0xf6, 0x13, 0x36, 0x13, + 0xb3, 0x13, 0xfc, 0x14, 0x24, 0x14, 0x69, 0x14, 0x97, 0x14, 0xae, 0x15, + 0x20, 0x15, 0x68, 0x15, 0xb9, 0x16, 0x07, 0x16, 0x5a, 0x16, 0x91, 0x17, + 0x16, 0x17, 0x64, 0x17, 0xaa, 0x17, 0xc6, 0x17, 0xf7, 0x18, 0x28, 0x18, + 0x69, 0x18, 0x92, 0x19, 0x16, 0x19, 0x2b, 0x19, 0xae, 0x19, 0xf3, 0x1a, + 0x1e, 0x1a, 0x9b, 0x1b, 0x48, 0x1b, 0x5d, 0x1b, 0xa7, 0x1c, 0x0f, 0x1c, + 0xdf, 0x1d, 0x4a, 0x1d, 0x64, 0x1d, 0xab, 0x1d, 0xe2, 0x1e, 0x01, 0x1e, + 0x20, 0x1e, 0x86, 0x1e, 0xda, 0x1e, 0xeb, 0x1f, 0x18, 0x1f, 0x5c, 0x1f, + 0x6d, 0x1f, 0xa3, 0x1f, 0xbc, 0x1f, 0xe1, 0x20, 0x27, 0x20, 0x6e, 0x20, + 0xa5, 0x20, 0xda, 0x21, 0x6b, 0x21, 0xce, 0x21, 0xe2, 0x21, 0xf7, 0x22, + 0x12, 0x22, 0x5e, 0x22, 0x71, 0x22, 0x9d, 0x22, 0xb2, 0x22, 0xd7, 0x23, + 0x04, 0x23, 0x43, 0x23, 0x68, 0x23, 0xa5, 0x23, 0xc0, 0x23, 0xd3, 0x24, + 0x1e, 0x24, 0xc8, 0x24, 0xf8, 0x25, 0x8d, 0x26, 0x08, 0x26, 0x58, 0x27, + 0x2c, 0x27, 0x43, 0x27, 0x6a, 0x27, 0xf7, 0x28, 0x97, 0x29, 0x0e, 0x29, + 0x5f, 0x29, 0xa1, 0x29, 0xe2, 0x2a, 0x29, 0x2a, 0xa2, 0x2a, 0xfb, 0x2b, + 0x93, 0x2b, 0xf0, 0x2c, 0x3f, 0x2c, 0x7e, 0x2c, 0xbb, 0x2c, 0xff, 0x2d, + 0x37, 0x2d, 0x60, 0x2d, 0x88, 0x2d, 0xb6, 0x2e, 0x2c, 0x2e, 0xb0, 0x2f, + 0x24, 0x2f, 0x96, 0x30, 0x0f, 0x30, 0xb9, 0x31, 0x5b, 0x31, 0xc6, 0x32, + 0x21, 0x32, 0x7c, 0x32, 0xde, 0x33, 0x16, 0x33, 0x55, 0x33, 0xac, 0x33, + 0xf3, 0x34, 0xc5, 0x35, 0x87, 0x36, 0x48, 0x37, 0x10, 0x38, 0x09, 0x38, + 0xe2, 0x39, 0x85, 0x3a, 0x18, 0x3a, 0x9b, 0x3b, 0x1e, 0x3b, 0xa7, 0x3b, + 0xdf, 0x3c, 0x08, 0x3c, 0x30, 0x3c, 0x5e, 0x3c, 0xef, 0x3d, 0x62, 0x3d, + 0xc5, 0x3e, 0x26, 0x3e, 0x8d, 0x3f, 0x21, 0x3f, 0xbe, 0x40, 0x28, 0x40, + 0x82, 0x40, 0xdb, 0x41, 0x3a, 0x41, 0x8c, 0x41, 0xcb, 0x42, 0x5e, 0x42, + 0xac, 0x43, 0x0f, 0x43, 0x87, 0x43, 0xa6, 0x43, 0xf7, 0x44, 0x61, 0x44, + 0x72, 0x44, 0x87, 0x44, 0xb4, 0x44, 0xc8, 0x44, 0xf4, 0x45, 0x33, 0x45, + 0x7d, 0x45, 0xba, 0x46, 0x38, 0x46, 0x97, 0x47, 0x40, 0x47, 0xd5, 0x48, + 0x8e, 0x48, 0x91, 0x48, 0xab, 0x48, 0xce, 0x49, 0x33, 0xfc, 0x1d, 0x0e, + 0xfc, 0x1d, 0x0e, 0xfb, 0xe6, 0xf8, 0x35, 0xf9, 0x6a, 0x15, 0xfb, 0x2a, + 0x8b, 0x5e, 0xfb, 0x66, 0x73, 0xfb, 0xc9, 0xce, 0x8b, 0xf6, 0xf7, 0xc9, + 0xb8, 0xf7, 0x66, 0x05, 0xfb, 0x10, 0xfc, 0xd8, 0x15, 0xfb, 0x2a, 0x8b, + 0x6c, 0xfb, 0x26, 0xf7, 0x2a, 0x8b, 0xaa, 0xf7, 0x26, 0x05, 0x0e, 0xfb, + 0x59, 0xf7, 0xeb, 0xf9, 0x6d, 0x15, 0xfb, 0x1e, 0x8b, 0x6f, 0xfb, 0x16, + 0x98, 0xfb, 0x15, 0xc3, 0x8b, 0xd0, 0xf7, 0x15, 0xa7, 0xf7, 0x16, 0x05, + 0xf7, 0x80, 0x16, 0xfb, 0x1e, 0x8b, 0x6f, 0xfb, 0x16, 0x98, 0xfb, 0x15, + 0xc3, 0x8b, 0xd0, 0xf7, 0x15, 0xa7, 0xf7, 0x16, 0x05, 0x0e, 0xf7, 0x1e, + 0x6b, 0x15, 0xdf, 0xf7, 0x60, 0xf1, 0x8b, 0x38, 0xfb, 0x60, 0xf4, 0x8b, + 0xdf, 0xf7, 0x60, 0xf7, 0x0b, 0x8b, 0xa0, 0xef, 0x28, 0x8b, 0xc9, 0xf7, + 0x2c, 0xf5, 0x8b, 0xa0, 0xef, 0x34, 0x8b, 0xd3, 0xf7, 0x41, 0x21, 0x8b, + 0x44, 0xfb, 0x41, 0x05, 0x24, 0x8b, 0xd3, 0xf7, 0x41, 0x21, 0x8b, 0x44, + 0xfb, 0x41, 0xfb, 0x0a, 0x8b, 0x75, 0x27, 0xee, 0x8b, 0x4d, 0xfb, 0x2c, + 0x2a, 0x8b, 0x76, 0x27, 0xd8, 0x8b, 0x38, 0xfb, 0x60, 0xf4, 0x8b, 0x05, + 0xf7, 0x10, 0xf7, 0xc4, 0x15, 0xca, 0xf7, 0x2c, 0xf1, 0x8b, 0x4d, 0xfb, + 0x2c, 0x24, 0x8b, 0x05, 0x0e, 0xf9, 0x03, 0xf8, 0x86, 0x15, 0x8f, 0xa1, + 0x8c, 0x97, 0x8b, 0x9a, 0x8b, 0xbd, 0x79, 0xb7, 0x6b, 0xa7, 0x70, 0xa2, + 0x69, 0x97, 0x53, 0x90, 0x08, 0x97, 0xc1, 0x47, 0x8b, 0x80, 0x55, 0x05, + 0x57, 0x86, 0x68, 0x81, 0x65, 0x77, 0x3d, 0x63, 0x5a, 0x3d, 0x8b, 0x3a, + 0x8b, 0x30, 0xc1, 0x52, 0xf7, 0x03, 0x6f, 0x08, 0x5d, 0xfb, 0x69, 0x05, + 0x5f, 0x94, 0x76, 0xa7, 0x8b, 0xbe, 0x8b, 0x92, 0x8b, 0x92, 0x8c, 0x9e, + 0x08, 0xfb, 0x16, 0x06, 0x85, 0x72, 0x89, 0x7b, 0x8b, 0x79, 0x8b, 0x2a, + 0xcb, 0x4f, 0xf7, 0x08, 0x7f, 0x08, 0x74, 0x22, 0xcf, 0x8b, 0xa1, 0xf4, + 0x05, 0xc3, 0x91, 0xb7, 0x98, 0xb2, 0xa0, 0xd7, 0xb5, 0xbf, 0xe3, 0x8b, + 0xe3, 0x8b, 0xb9, 0x76, 0xb4, 0x65, 0xa8, 0x6f, 0xa0, 0x69, 0x9b, 0x54, + 0x9c, 0x08, 0xb6, 0xf7, 0x5d, 0x05, 0xaf, 0x85, 0xa1, 0x71, 0x8b, 0x65, + 0x8b, 0x7f, 0x8a, 0x82, 0x89, 0x78, 0x08, 0xf7, 0x14, 0x06, 0xfb, 0xb5, + 0x44, 0x15, 0x62, 0x9b, 0x76, 0xa4, 0x8b, 0xac, 0x8b, 0xad, 0x9e, 0xae, + 0xa7, 0x9e, 0x99, 0x95, 0x98, 0x8f, 0xa5, 0x90, 0x08, 0x65, 0xfb, 0x49, + 0x05, 0xb0, 0xfb, 0x25, 0x15, 0xb2, 0x7b, 0x9f, 0x6f, 0x8b, 0x63, 0x8b, + 0x53, 0x66, 0x62, 0x4b, 0x7c, 0x08, 0xb5, 0xf7, 0x58, 0x05, 0x0e, 0xf7, + 0x6e, 0xf9, 0x88, 0xf9, 0x59, 0x15, 0xfc, 0xba, 0xfd, 0x6d, 0xd7, 0x8b, + 0xf8, 0xbb, 0xf9, 0x6d, 0x05, 0x3e, 0x06, 0xfc, 0x28, 0x83, 0x15, 0xfb, + 0x07, 0xfb, 0x00, 0x21, 0xfb, 0x05, 0x38, 0xcc, 0x4d, 0xe1, 0xf7, 0x0a, + 0xf6, 0xf4, 0xf7, 0x07, 0xde, 0x4b, 0xc8, 0x32, 0x1f, 0x76, 0x29, 0x15, + 0xb5, 0xab, 0x6e, 0x65, 0x56, 0x5a, 0x5b, 0x55, 0x62, 0x6b, 0xa8, 0xb0, + 0xc0, 0xbc, 0xbc, 0xc0, 0x1f, 0xf8, 0x37, 0xfb, 0x97, 0x15, 0xfb, 0x07, + 0xfb, 0x00, 0x21, 0xfb, 0x05, 0x38, 0xcc, 0x4d, 0xe1, 0xf7, 0x0a, 0xf6, + 0xf4, 0xf7, 0x07, 0x1f, 0xde, 0x4b, 0xc8, 0x32, 0x1e, 0x76, 0x29, 0x15, + 0xb5, 0xab, 0x6e, 0x65, 0x56, 0x5a, 0x5b, 0x55, 0x62, 0x6b, 0xa8, 0xb0, + 0xc0, 0xbc, 0xbc, 0xc0, 0x1f, 0x0e, 0xbe, 0xf8, 0xf3, 0xf8, 0x09, 0x15, + 0x80, 0x52, 0x7c, 0x6d, 0x69, 0x6c, 0x08, 0x39, 0xf7, 0x1d, 0x05, 0xc1, + 0xab, 0xa9, 0xa1, 0xa1, 0xa4, 0xab, 0xb0, 0xa0, 0xbf, 0x8b, 0xb8, 0x08, + 0xd2, 0x4d, 0xba, 0x30, 0xfb, 0x0c, 0x22, 0x2e, 0x20, 0x1e, 0x8b, 0x6c, + 0x9c, 0x63, 0xaf, 0x58, 0x59, 0x74, 0x74, 0x7f, 0x6c, 0x75, 0x46, 0x5c, + 0x66, 0x49, 0x8b, 0x40, 0x8b, 0xfb, 0x04, 0xd5, 0x48, 0xf7, 0x10, 0x8b, + 0xd8, 0x8b, 0xb6, 0x9c, 0xe7, 0xcd, 0x08, 0xb0, 0x4f, 0xf7, 0x34, 0x8b, + 0x2d, 0xf7, 0x34, 0x05, 0xc6, 0xc0, 0xbb, 0xe2, 0x96, 0xd4, 0x08, 0xfb, + 0x05, 0x06, 0xfb, 0x98, 0x55, 0x15, 0xee, 0xfb, 0x3b, 0x05, 0x49, 0x5e, + 0x6c, 0x7d, 0x69, 0x8b, 0x5a, 0x8b, 0x63, 0xb5, 0x8b, 0xbf, 0x8b, 0xb9, + 0x9f, 0xa8, 0xbc, 0xa7, 0x08, 0xbf, 0xa8, 0x05, 0xd3, 0xf7, 0x2b, 0x15, + 0x6c, 0xc1, 0x86, 0x95, 0x8b, 0x9d, 0x08, 0xb0, 0xa6, 0xa5, 0xb1, 0xab, + 0x9e, 0x7b, 0x72, 0x1e, 0x8b, 0x62, 0x6f, 0x67, 0x57, 0x70, 0x08, 0x0e, + 0xfc, 0x1d, 0xf7, 0x70, 0xf9, 0x6d, 0x15, 0x70, 0xfb, 0x11, 0xdc, 0x8b, + 0x05, 0x82, 0x59, 0x6b, 0x6e, 0x51, 0x81, 0x08, 0x81, 0x5d, 0x05, 0xe9, + 0x92, 0xc9, 0xc3, 0x97, 0xe3, 0x08, 0xa2, 0xf7, 0x01, 0xfb, 0x1c, 0x8b, + 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0xfa, 0xf9, 0x6d, 0x15, 0xfb, 0x52, 0xfb, + 0x6f, 0x37, 0xfb, 0x4e, 0x8b, 0xfb, 0x5e, 0x8b, 0x2a, 0xa5, 0xfb, 0x00, + 0xbe, 0xfb, 0x09, 0x08, 0xef, 0x06, 0x5f, 0xf7, 0x24, 0x7d, 0xd7, 0x8b, + 0xe7, 0x8b, 0xf7, 0x19, 0xb0, 0xf7, 0x18, 0xd6, 0xf7, 0x1c, 0xaf, 0xcb, + 0xaf, 0xc2, 0xd2, 0xec, 0x08, 0x27, 0x06, 0x0e, 0xfb, 0xe6, 0xda, 0xfb, + 0x5c, 0x15, 0xc4, 0xcc, 0xc1, 0xd2, 0xaf, 0xc2, 0xdf, 0xf7, 0x18, 0xb9, + 0xf7, 0x25, 0x8b, 0xf7, 0x1e, 0x8b, 0xed, 0x72, 0xf3, 0x54, 0xf7, 0x0d, + 0x08, 0x27, 0x06, 0xba, 0xfb, 0x27, 0x99, 0x42, 0x8b, 0x2e, 0x8b, 0xfb, + 0x18, 0x66, 0xfb, 0x18, 0x3f, 0xfb, 0x1c, 0x67, 0x4b, 0x6b, 0x5b, 0x3e, + 0x23, 0x08, 0xef, 0x06, 0x0e, 0xfb, 0xae, 0xf7, 0x8a, 0xf8, 0xb4, 0x15, + 0x34, 0x2d, 0xbc, 0x60, 0xe2, 0xe9, 0xba, 0x2d, 0xce, 0xb6, 0x5c, 0xe9, + 0xf7, 0x08, 0xae, 0x84, 0xd1, 0xfb, 0x09, 0x67, 0xa4, 0xf7, 0x08, 0x43, + 0x8b, 0x73, 0xfb, 0x08, 0x26, 0xaf, 0x66, 0x46, 0xf0, 0x67, 0x05, 0x0e, + 0x34, 0xf8, 0xe8, 0xf7, 0xb8, 0x15, 0xfb, 0x4b, 0x8b, 0xb2, 0xf7, 0x49, + 0xfb, 0x0b, 0x8b, 0x64, 0xfb, 0x49, 0xfb, 0x4a, 0x8b, 0x72, 0xfb, 0x0c, + 0xf7, 0x4a, 0x8b, 0x64, 0xfb, 0x4a, 0xf7, 0x0b, 0x8b, 0xb2, 0xf7, 0x4a, + 0xf7, 0x4b, 0x8b, 0xa4, 0xf7, 0x0c, 0x05, 0x0e, 0xfc, 0x1d, 0xea, 0xf7, + 0x26, 0x15, 0x6c, 0xfb, 0x26, 0xe1, 0x8b, 0x05, 0x7e, 0x47, 0x67, 0x64, + 0x4d, 0x80, 0x08, 0x7f, 0x53, 0x05, 0xf7, 0x02, 0x9b, 0xc7, 0xc4, 0x9e, + 0xf7, 0x02, 0x08, 0xa8, 0xf7, 0x1d, 0xfb, 0x2a, 0x8b, 0x05, 0x0e, 0xfb, + 0xe6, 0xf8, 0x07, 0xf7, 0xea, 0x15, 0xfb, 0xa4, 0x8b, 0x6e, 0xfb, 0x1b, + 0xf7, 0xa4, 0x8b, 0xa8, 0xf7, 0x1b, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0x89, + 0xf7, 0x26, 0x15, 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0xf7, 0x2a, 0x8b, + 0xaa, 0xf7, 0x26, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0xfc, 0xf9, 0x5e, 0x15, + 0xfb, 0xfd, 0xfd, 0x6c, 0xce, 0x8b, 0xf7, 0xfd, 0xf9, 0x6c, 0x48, 0x8b, + 0x05, 0x0e, 0xf8, 0x39, 0xf9, 0x68, 0x15, 0xfb, 0x05, 0x8b, 0x2f, 0x4a, + 0x54, 0xfb, 0x0a, 0x61, 0x2f, 0x65, 0xfb, 0x40, 0x8b, 0x26, 0x8b, 0xfb, + 0x0f, 0xd3, 0x3f, 0xf7, 0x0a, 0x8b, 0xf7, 0x08, 0x8b, 0xe7, 0xcb, 0xc2, + 0xf7, 0x0b, 0xb5, 0xe6, 0xb1, 0xf7, 0x42, 0x8b, 0xf0, 0x8b, 0xf7, 0x0f, + 0x42, 0xd6, 0xfb, 0x0c, 0x8b, 0x08, 0x70, 0xfb, 0x04, 0x15, 0xba, 0xa9, + 0x6a, 0x58, 0x1f, 0x8b, 0x4d, 0x74, 0xfb, 0x1a, 0x70, 0x2c, 0x6f, 0x28, + 0x69, 0x64, 0x50, 0x8b, 0x5d, 0x8b, 0x6d, 0xac, 0x8b, 0xbe, 0x8b, 0xec, + 0xbc, 0xf7, 0x72, 0xac, 0xc0, 0xa3, 0xb1, 0xa8, 0x9e, 0xae, 0x8b, 0x08, + 0x0e, 0xf7, 0xea, 0xf8, 0x7d, 0x15, 0x23, 0xfc, 0x7d, 0xf7, 0x20, 0x8b, + 0xf7, 0x2b, 0xf9, 0x59, 0x2e, 0x8b, 0x05, 0x63, 0x37, 0x39, 0x60, 0xfb, + 0x0e, 0x8b, 0x08, 0x77, 0x2e, 0xf7, 0x3e, 0x8b, 0x05, 0x0e, 0xf8, 0xae, + 0xf7, 0x11, 0x15, 0xfb, 0xc0, 0x06, 0xa4, 0xb0, 0xa8, 0xa1, 0xf7, 0x0b, + 0xd6, 0xde, 0xbf, 0xb0, 0xa8, 0xab, 0xb1, 0xb5, 0xbd, 0xa2, 0xc8, 0x8b, + 0xca, 0x8b, 0xf7, 0x00, 0x3e, 0xcb, 0xfb, 0x16, 0x8b, 0xfb, 0x2f, 0x8b, + 0x25, 0x2d, 0x71, 0xfb, 0x3c, 0x08, 0xf7, 0x1a, 0x06, 0x98, 0xec, 0xb8, + 0xc0, 0xd0, 0x8b, 0xc1, 0x8b, 0xab, 0x6d, 0x8b, 0x59, 0x8b, 0x5d, 0x77, + 0x5b, 0x69, 0x69, 0x6c, 0x6a, 0x6a, 0x74, 0xfb, 0x06, 0x44, 0xfb, 0x1f, + 0x38, 0x5a, 0x4d, 0x68, 0xfb, 0x18, 0x08, 0xf8, 0x76, 0x8b, 0xa5, 0xf7, + 0x11, 0x05, 0x0e, 0xf7, 0xb0, 0xf7, 0xd1, 0x15, 0xbc, 0x8b, 0x94, 0x8a, + 0xa2, 0x85, 0xaf, 0x81, 0xa0, 0x6e, 0x8b, 0x62, 0x8b, 0x44, 0x54, 0x4f, + 0x48, 0x8b, 0x52, 0x8b, 0x6b, 0xa7, 0x8a, 0xbc, 0x08, 0x8b, 0xa1, 0x8a, + 0x95, 0xfb, 0x1c, 0x8b, 0x05, 0x87, 0x74, 0x89, 0x7c, 0x8b, 0x78, 0x8b, + 0xfb, 0x02, 0xd6, 0x4b, 0xf7, 0x16, 0x8b, 0xed, 0x8b, 0xda, 0xac, 0xbe, + 0xc9, 0xb3, 0xbd, 0xa4, 0xd2, 0x8b, 0xcb, 0x8b, 0xc1, 0x74, 0xb2, 0x5a, + 0xa9, 0x08, 0xdb, 0xbc, 0xb3, 0xcc, 0x8b, 0xda, 0x8b, 0xeb, 0x42, 0xc2, + 0xfb, 0x13, 0x8b, 0x36, 0x8b, 0x45, 0x70, 0x5d, 0x59, 0x66, 0x63, 0x79, + 0x60, 0x7c, 0x3d, 0x08, 0xf7, 0x15, 0x06, 0x94, 0xb2, 0x91, 0x9e, 0x95, + 0x9c, 0x9e, 0xab, 0xac, 0x9e, 0xb3, 0x8b, 0x08, 0xb8, 0xab, 0x6e, 0x62, + 0x3c, 0x50, 0x57, 0x31, 0x1f, 0x7f, 0x8b, 0x05, 0x77, 0x2d, 0x05, 0x0e, + 0xf8, 0xd8, 0xf7, 0xa5, 0x15, 0x41, 0x8b, 0xe8, 0xf8, 0x48, 0xfb, 0x39, + 0x8b, 0xfb, 0xf4, 0xfc, 0x46, 0x72, 0xfb, 0x0a, 0xf7, 0xb1, 0x8b, 0x69, + 0xfb, 0x31, 0xf7, 0x20, 0x8b, 0xad, 0xf7, 0x31, 0xd4, 0x8b, 0xa4, 0xf7, + 0x08, 0x05, 0xfb, 0x6a, 0x16, 0xfb, 0x4c, 0x8b, 0xf7, 0x8d, 0xf7, 0xc4, + 0x4a, 0xfb, 0xc4, 0x05, 0x0e, 0xf9, 0x15, 0xf9, 0x59, 0x15, 0xfc, 0x13, + 0x8b, 0xfb, 0x26, 0xfc, 0x1f, 0xf7, 0x12, 0x8b, 0x05, 0xa1, 0xad, 0xb0, + 0x9e, 0xb5, 0x8b, 0x08, 0xc5, 0xab, 0x6a, 0x51, 0x26, 0x4f, 0x3f, 0x3a, + 0x56, 0x68, 0xa4, 0xb2, 0x1f, 0x8b, 0x90, 0x8c, 0x93, 0x8c, 0x94, 0x08, + 0xfb, 0x1e, 0x06, 0x87, 0x77, 0x8a, 0x80, 0x8b, 0x7e, 0x8b, 0x28, 0xdb, + 0x4a, 0xf7, 0x0c, 0x8b, 0xf0, 0x8b, 0xe3, 0xb7, 0xc5, 0xdb, 0xb5, 0xc4, + 0xa3, 0xd4, 0x8b, 0xd0, 0x8b, 0xf7, 0x02, 0x48, 0xd0, 0xfb, 0x01, 0x8b, + 0x5c, 0x8b, 0x65, 0x7f, 0x5c, 0x6c, 0x08, 0xc1, 0xf7, 0x28, 0xf7, 0xbc, + 0x8b, 0xa6, 0xf7, 0x11, 0x05, 0x0e, 0xf9, 0x04, 0xf8, 0xb8, 0x15, 0x8c, + 0x94, 0x8b, 0x94, 0x8b, 0x90, 0x8b, 0xea, 0x46, 0xc5, 0xfb, 0x05, 0x8b, + 0x20, 0x8b, 0x35, 0x55, 0x4a, 0x21, 0x56, 0x34, 0x5c, 0xfb, 0x4c, 0x8b, + 0xfb, 0x0e, 0x8b, 0xfb, 0x0a, 0xd9, 0x3f, 0xf7, 0x0d, 0x8b, 0xe1, 0x8b, + 0xdb, 0xb3, 0xc0, 0xd2, 0x08, 0xb9, 0xc7, 0xa7, 0xdc, 0x8b, 0xd2, 0x8b, + 0xf3, 0x4c, 0xca, 0x22, 0x8b, 0x57, 0x8b, 0x5c, 0x79, 0x59, 0x65, 0x9c, + 0xc9, 0x8d, 0x92, 0x98, 0xab, 0xa7, 0xd1, 0xb0, 0xa9, 0xc4, 0x8b, 0xbb, + 0x8b, 0xa2, 0x79, 0x94, 0x5d, 0x08, 0xf7, 0x16, 0x06, 0xfb, 0xa4, 0xfb, + 0x55, 0x15, 0xbc, 0xac, 0x68, 0x58, 0x2e, 0x4f, 0x3e, 0x42, 0x58, 0x68, + 0xb0, 0xbf, 0xe5, 0xca, 0xd8, 0xd5, 0x1f, 0x0e, 0xf9, 0x3b, 0xf9, 0x59, + 0x15, 0xfc, 0x89, 0x8b, 0x70, 0xfb, 0x11, 0xf7, 0xf5, 0x8b, 0x05, 0xfb, + 0x57, 0xfb, 0x50, 0x29, 0xfb, 0x2e, 0x3b, 0xfb, 0x86, 0x08, 0xf7, 0x22, + 0x06, 0xc0, 0xf7, 0x53, 0xd9, 0xf7, 0x1d, 0xf7, 0x27, 0xf7, 0x37, 0x08, + 0xf4, 0xf7, 0x00, 0xa2, 0xf7, 0x02, 0x05, 0x0e, 0xf8, 0x7f, 0xf8, 0x16, + 0x15, 0xad, 0x9f, 0x9e, 0x98, 0x9b, 0x9c, 0xb1, 0xb0, 0xa1, 0xbc, 0x8b, + 0xbb, 0x08, 0xe6, 0x3a, 0xca, 0xfb, 0x09, 0xfb, 0x25, 0xfb, 0x0d, 0x23, + 0xfb, 0x11, 0x1e, 0x8b, 0x60, 0x9d, 0x6d, 0xba, 0x67, 0x59, 0x72, 0x71, + 0x79, 0x71, 0x6d, 0x08, 0x66, 0x5f, 0x75, 0x50, 0x8b, 0x54, 0x8b, 0xfb, + 0x01, 0xde, 0x46, 0xf7, 0x19, 0x8b, 0xde, 0x8b, 0xd7, 0xa8, 0xc1, 0xc0, + 0xc0, 0xbe, 0xac, 0xd6, 0x8b, 0xcf, 0x08, 0x8b, 0xc7, 0x74, 0xaf, 0x4e, + 0xb0, 0x08, 0x2e, 0xf7, 0x76, 0x15, 0xc2, 0xb0, 0x6e, 0x60, 0x4b, 0x52, + 0x58, 0x45, 0x58, 0x69, 0xa9, 0xb8, 0x1f, 0xca, 0xc0, 0xbc, 0xce, 0x1e, + 0x53, 0xfb, 0xae, 0x15, 0xc2, 0xae, 0x6b, 0x58, 0x35, 0x53, 0x4d, 0x3c, + 0x55, 0x63, 0xad, 0xba, 0x1f, 0xdf, 0xc8, 0xcd, 0xd9, 0x1e, 0x0e, 0xd3, + 0xf7, 0x39, 0x15, 0x88, 0x7b, 0x8a, 0x84, 0x8b, 0x81, 0x8b, 0x2f, 0xd4, + 0x4c, 0xf6, 0x8b, 0xf7, 0x02, 0x8b, 0xe4, 0xc1, 0xc7, 0xf3, 0xc8, 0xf5, + 0xb6, 0xf7, 0x31, 0x8b, 0xf7, 0x0d, 0x08, 0xf7, 0x10, 0x3d, 0xdc, 0xfb, + 0x0c, 0x1e, 0xfb, 0x38, 0xfb, 0x15, 0xfb, 0x22, 0xfb, 0x47, 0xfb, 0x00, + 0xcc, 0x48, 0xf3, 0x1f, 0xc3, 0x8b, 0xae, 0x9a, 0xc3, 0xbb, 0x80, 0x5b, + 0x80, 0x6a, 0x7f, 0x6f, 0x73, 0x56, 0x60, 0x6d, 0x59, 0x8b, 0x08, 0x5c, + 0x6b, 0xa1, 0xab, 0x1f, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, 0x90, 0x08, 0xfb, + 0x1b, 0x06, 0xf7, 0xd1, 0xf8, 0x53, 0x15, 0xc3, 0xaf, 0x67, 0x52, 0x2a, + 0x4b, 0x3d, 0x3b, 0x1f, 0x5a, 0x6c, 0xad, 0xc0, 0xf0, 0xc5, 0xdb, 0xd5, + 0x1f, 0x0e, 0xfb, 0xe6, 0xf7, 0xba, 0xf7, 0x26, 0x15, 0xfb, 0x2a, 0x8b, + 0x6c, 0xfb, 0x26, 0xf7, 0x2a, 0x8b, 0xaa, 0xf7, 0x26, 0x05, 0xdb, 0xf8, + 0x0a, 0x15, 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0xf7, 0x2a, 0x8b, 0xaa, + 0xf7, 0x26, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0x24, 0xf7, 0x26, 0x15, 0x6c, + 0xfb, 0x26, 0xe1, 0x8b, 0x05, 0x7e, 0x47, 0x67, 0x64, 0x4d, 0x80, 0x08, + 0x7f, 0x53, 0x05, 0xf7, 0x02, 0x9b, 0xc7, 0xc4, 0x9e, 0xf7, 0x02, 0x08, + 0xa8, 0xf7, 0x1d, 0xfb, 0x2a, 0x8b, 0x05, 0xf7, 0x7a, 0xf8, 0x0a, 0x15, + 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0xf7, 0x2a, 0x8b, 0xaa, 0xf7, 0x26, + 0x05, 0x0e, 0x34, 0xf9, 0x0a, 0xf8, 0x6e, 0x15, 0xfc, 0xa3, 0xfb, 0x49, + 0x71, 0xfb, 0x0d, 0xf8, 0x56, 0xfb, 0x4a, 0xa7, 0xf7, 0x17, 0xfb, 0xb8, + 0xf7, 0x03, 0xf7, 0xe8, 0xf7, 0x05, 0xa6, 0xf7, 0x15, 0x05, 0x0e, 0x34, + 0xf9, 0x02, 0xf8, 0x30, 0x15, 0xfc, 0x79, 0x8b, 0x72, 0xfb, 0x0c, 0xf8, + 0x79, 0x8b, 0xa4, 0xf7, 0x0c, 0x05, 0x58, 0xfb, 0x84, 0x15, 0xfc, 0x79, + 0x8b, 0x72, 0xfb, 0x0c, 0xf8, 0x79, 0x8b, 0xa4, 0xf7, 0x0c, 0x05, 0x0e, + 0x34, 0xb1, 0x81, 0x15, 0xf8, 0xa3, 0xf7, 0x49, 0xa5, 0xf7, 0x0d, 0xfc, + 0x56, 0xf7, 0x4a, 0x6f, 0xfb, 0x17, 0xf7, 0xb8, 0xfb, 0x03, 0xfb, 0xe8, + 0xfb, 0x05, 0x70, 0xfb, 0x15, 0x05, 0x0e, 0x4f, 0xf8, 0x32, 0xf7, 0x5d, + 0x15, 0x99, 0xcd, 0x94, 0x96, 0xcf, 0xb5, 0xc6, 0xaf, 0xb0, 0xa9, 0x9f, + 0xa6, 0xaa, 0xb2, 0x9f, 0xc7, 0x8b, 0xc1, 0x8b, 0xbf, 0x74, 0xbe, 0x63, + 0xaa, 0x68, 0xa8, 0x55, 0x9a, 0x4b, 0x8b, 0x37, 0x8b, 0x44, 0x6d, 0x56, + 0x52, 0x08, 0x64, 0x60, 0x75, 0x5a, 0x78, 0x37, 0x08, 0xf7, 0x1c, 0x06, + 0x9c, 0xe3, 0xbc, 0xbe, 0xcf, 0x8b, 0xc0, 0x8b, 0xb1, 0x67, 0x8b, 0x58, + 0x8b, 0x77, 0x85, 0x76, 0x80, 0x78, 0x7c, 0x71, 0x82, 0x82, 0x53, 0x64, + 0x2d, 0x49, 0x64, 0x53, 0x84, 0x3f, 0x08, 0xf7, 0x0e, 0x06, 0x8f, 0x54, + 0x15, 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0xf7, 0x2a, 0x8b, 0xaa, 0xf7, + 0x26, 0x05, 0x0e, 0xf7, 0xc4, 0xf9, 0x82, 0xf8, 0x90, 0x15, 0x70, 0x50, + 0x05, 0x77, 0xbd, 0x70, 0x9e, 0x59, 0x8b, 0x3d, 0x8b, 0x33, 0x5b, 0x46, + 0x3b, 0x53, 0x49, 0x69, 0x40, 0x8b, 0x4f, 0x8b, 0x3b, 0xc3, 0x53, 0xdc, + 0x8b, 0xc2, 0x8b, 0xc2, 0xa4, 0xbc, 0xbb, 0x08, 0x9a, 0x5d, 0xb0, 0x73, + 0xc3, 0x8b, 0xdd, 0x8b, 0xe1, 0xbd, 0xd2, 0xe2, 0xc5, 0xd2, 0xa9, 0xe0, + 0x8b, 0xe5, 0x8b, 0xcc, 0x75, 0xc7, 0x5e, 0xc1, 0x46, 0xe0, 0x29, 0xb5, + 0xfb, 0x14, 0x8b, 0xfb, 0x38, 0x8b, 0xfb, 0x31, 0x47, 0xfb, 0x06, 0xfb, + 0x0c, 0x08, 0x25, 0x20, 0x4f, 0xfb, 0x1f, 0x8b, 0xfb, 0x16, 0x8b, 0x36, + 0xad, 0x3a, 0xc8, 0x52, 0xcf, 0x4a, 0xe6, 0x6d, 0xf7, 0x12, 0x8b, 0xea, + 0x8b, 0xd7, 0x99, 0xd7, 0xaa, 0x08, 0x7f, 0xda, 0x05, 0x2d, 0x6d, 0x54, + 0x80, 0x4c, 0x8b, 0xfb, 0x46, 0x8b, 0xfb, 0x11, 0xf3, 0x8b, 0xf7, 0x26, + 0x8b, 0xe5, 0xb0, 0xf2, 0xc9, 0xe1, 0xe3, 0xf7, 0x0d, 0xf7, 0x16, 0xcd, + 0xf7, 0x2b, 0x8b, 0xf4, 0x8b, 0xd2, 0x6f, 0xc6, 0x4c, 0xb5, 0x5e, 0xa0, + 0x59, 0x8b, 0x58, 0x08, 0x8b, 0x4d, 0x71, 0x45, 0x60, 0x53, 0x5e, 0x51, + 0x50, 0x63, 0x61, 0x8b, 0x74, 0x8b, 0x7b, 0x99, 0x8b, 0xa0, 0x8b, 0x99, + 0x8d, 0x92, 0x9c, 0xac, 0x08, 0xf7, 0x1c, 0xf7, 0xac, 0x05, 0x31, 0x06, + 0xfb, 0x24, 0x4d, 0x15, 0xb2, 0x89, 0xa5, 0x6f, 0x8b, 0x63, 0x8b, 0x62, + 0x72, 0x51, 0x65, 0x59, 0x60, 0x51, 0x57, 0x6a, 0x5e, 0x8b, 0x63, 0x8b, + 0x70, 0xab, 0x8b, 0xba, 0x08, 0x8b, 0xf1, 0xf7, 0x0b, 0xf7, 0x1a, 0xe1, + 0x86, 0x08, 0x0e, 0xbe, 0xf8, 0xa8, 0xf7, 0x27, 0x15, 0x9d, 0xfb, 0x27, + 0xf7, 0x2d, 0x8b, 0x2a, 0xf9, 0x6d, 0xfb, 0x41, 0x8b, 0xfc, 0x2b, 0xfd, + 0x6d, 0xf7, 0x2d, 0x8b, 0xdc, 0xf7, 0x27, 0xf7, 0xa4, 0x8b, 0x05, 0x7d, + 0xf7, 0x11, 0x15, 0xfb, 0x51, 0x8b, 0xf7, 0x2e, 0xf7, 0xaf, 0xae, 0xfb, + 0xaf, 0x05, 0x0e, 0xbe, 0xdd, 0x16, 0xf7, 0xdc, 0x06, 0xef, 0x8b, 0xd0, + 0xa3, 0xc3, 0xc1, 0xbc, 0xbb, 0xab, 0xd1, 0x8b, 0xc6, 0x8b, 0xc2, 0x77, + 0xb1, 0x58, 0xb3, 0x08, 0xd7, 0xbd, 0xb4, 0xcb, 0x8b, 0xd0, 0x8b, 0xb2, + 0x7c, 0xb2, 0x71, 0xa6, 0x68, 0xaf, 0x59, 0x9c, 0x41, 0x8b, 0x08, 0xfb, + 0xd9, 0x8b, 0x05, 0xfb, 0x2f, 0xfd, 0x6d, 0x05, 0xf7, 0x87, 0xf8, 0x4b, + 0x15, 0xae, 0xf7, 0x39, 0xf7, 0x38, 0x8b, 0x05, 0xc9, 0xa6, 0x78, 0x60, + 0x1f, 0x8b, 0x72, 0x80, 0x70, 0x7a, 0x78, 0x75, 0x72, 0x75, 0x84, 0x57, + 0x8b, 0x08, 0xfb, 0x38, 0x06, 0x49, 0xfb, 0xce, 0x15, 0xb3, 0xf7, 0x51, + 0xf7, 0x46, 0x8b, 0x05, 0xc9, 0xa8, 0x75, 0x5c, 0x1f, 0x8b, 0x72, 0x82, + 0x6f, 0x7d, 0x76, 0x74, 0x69, 0x6f, 0x7f, 0x52, 0x8b, 0x08, 0xfb, 0x46, + 0x06, 0x0e, 0xbe, 0xf9, 0xa9, 0xf8, 0x76, 0x15, 0x8e, 0xa7, 0x8c, 0x96, + 0x8b, 0x96, 0x8b, 0xf7, 0x10, 0x22, 0xe0, 0xfb, 0x2f, 0x8b, 0xfb, 0x0f, + 0x8b, 0x20, 0x56, 0x3a, 0x26, 0x44, 0x33, 0x5f, 0xfb, 0x1b, 0x8b, 0xfb, + 0x15, 0x8b, 0xfb, 0x34, 0xf3, 0x29, 0xf7, 0x3f, 0x8b, 0xf7, 0x4a, 0x8b, + 0xf7, 0x1a, 0xf0, 0xb7, 0xf7, 0x3f, 0x08, 0xfb, 0x23, 0x06, 0x6e, 0x2f, + 0x44, 0x57, 0x2b, 0x8b, 0x2a, 0x8b, 0x59, 0xc1, 0x8b, 0xf4, 0x8b, 0xdd, + 0xa5, 0xe3, 0xb8, 0xd1, 0xba, 0xd5, 0xc9, 0xae, 0xdb, 0x8b, 0xc0, 0x8b, + 0xb4, 0x78, 0xa0, 0x69, 0x98, 0x77, 0x8f, 0x78, 0x8b, 0x64, 0x08, 0xf7, + 0x21, 0x06, 0x0e, 0xbe, 0xd8, 0x16, 0xf7, 0xb1, 0x06, 0xf7, 0x25, 0x8b, + 0xdf, 0xb2, 0xd4, 0xf0, 0xd2, 0xed, 0xb4, 0xf7, 0x0f, 0x8b, 0xf7, 0x0a, + 0x08, 0xf7, 0x43, 0x3d, 0xd6, 0xfb, 0x49, 0x1e, 0xfb, 0xb1, 0x8b, 0xfb, + 0x2f, 0xfd, 0x6d, 0x05, 0xf7, 0x45, 0xf7, 0x11, 0x15, 0xf0, 0xf8, 0x73, + 0xf7, 0x1b, 0x8b, 0x05, 0xe7, 0xb8, 0x5f, 0x30, 0x1f, 0x8b, 0x3c, 0x71, + 0x24, 0x69, 0x50, 0x60, 0x40, 0x5a, 0x6f, 0x34, 0x8b, 0x08, 0xfb, 0x1a, + 0x06, 0x0e, 0x87, 0xf7, 0xbc, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0x8b, 0xa5, + 0xf7, 0x11, 0xfb, 0xf1, 0x8b, 0xae, 0xf7, 0x39, 0xf8, 0x0e, 0x8b, 0xa6, + 0xf7, 0x11, 0xfc, 0xa4, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0xb5, 0x8b, + 0xa6, 0xf7, 0x11, 0xfc, 0x1f, 0x8b, 0xb3, 0xf7, 0x51, 0x05, 0x0e, 0x4f, + 0xf7, 0xb7, 0xf7, 0xce, 0x15, 0xf7, 0xd3, 0x8b, 0xa6, 0xf7, 0x11, 0xfb, + 0xd4, 0x8b, 0xae, 0xf7, 0x39, 0xf7, 0xfe, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, + 0x94, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xce, 0xf7, 0xce, + 0x05, 0x0e, 0xf6, 0xf9, 0xaf, 0xf8, 0x1c, 0x15, 0xfb, 0xb8, 0x8b, 0x70, + 0xfb, 0x11, 0xf7, 0x3a, 0x8b, 0x05, 0x7e, 0x62, 0x7d, 0x72, 0x70, 0x71, + 0x5e, 0x5e, 0x50, 0x72, 0x51, 0x8b, 0x29, 0x8b, 0x43, 0xd7, 0x8b, 0xf2, + 0x8b, 0xd2, 0xa5, 0xe6, 0xaf, 0xc2, 0xbb, 0xd5, 0xcf, 0xb1, 0xe0, 0x8b, + 0xea, 0x8b, 0xc4, 0x61, 0x93, 0x40, 0x08, 0xf7, 0x1e, 0x06, 0x8c, 0x99, + 0x8c, 0x96, 0x8b, 0x93, 0x8b, 0xf7, 0x12, 0xfb, 0x01, 0xe1, 0xfb, 0x37, + 0x8b, 0xfb, 0x0f, 0x8b, 0xfb, 0x01, 0x59, 0x39, 0x2c, 0x3d, 0x30, 0x5b, + 0xfb, 0x13, 0x8b, 0xfb, 0x08, 0x8b, 0xfb, 0x42, 0xf7, 0x04, 0xfb, 0x03, + 0xf7, 0x44, 0x8b, 0xe8, 0x8b, 0xcd, 0xab, 0xd5, 0xda, 0x08, 0x84, 0x31, + 0xe5, 0x8b, 0xdf, 0xf8, 0x1e, 0x05, 0x0e, 0xbe, 0xf8, 0xd5, 0xf7, 0xdf, + 0x15, 0x45, 0xfb, 0xdf, 0xf7, 0x2a, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0xfb, + 0x2b, 0x8b, 0x51, 0xfb, 0xa5, 0xfb, 0xb4, 0x8b, 0xc5, 0xf7, 0xa5, 0xfb, + 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xd1, 0xf7, 0xdf, + 0xf7, 0xb5, 0x8b, 0x05, 0x0e, 0xfc, 0x1d, 0xf8, 0x04, 0xf9, 0x6d, 0x15, + 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xf7, 0x2f, + 0xf9, 0x6d, 0x05, 0x0e, 0xf8, 0x7f, 0xf9, 0x6d, 0x15, 0xfb, 0x07, 0xfc, + 0xaf, 0x05, 0x80, 0x54, 0x68, 0x6d, 0x56, 0x8b, 0x64, 0x8b, 0x70, 0xa1, + 0x8b, 0xab, 0x8b, 0x95, 0x8c, 0x96, 0x8e, 0x98, 0x08, 0x9b, 0xd8, 0xfb, + 0x2a, 0x8b, 0x7c, 0x43, 0x05, 0x86, 0x75, 0x89, 0x75, 0x8b, 0x76, 0x8b, + 0x2a, 0xd2, 0x50, 0xf7, 0x09, 0x8b, 0xcd, 0x8b, 0xd1, 0x9d, 0xb6, 0xa7, + 0xbc, 0xab, 0xae, 0xc6, 0x9b, 0xd7, 0x08, 0xf7, 0x07, 0xf8, 0xaf, 0xfb, + 0x2a, 0x8b, 0x05, 0x0e, 0xbe, 0xf7, 0xa6, 0xf7, 0x7e, 0x15, 0xe6, 0xdb, + 0xf7, 0x41, 0xfb, 0xce, 0xf7, 0x47, 0x8b, 0xfb, 0x7f, 0xf8, 0x2e, 0xf7, + 0xfd, 0xf7, 0xd3, 0xfb, 0x46, 0x8b, 0xfb, 0xf6, 0xfb, 0xd4, 0xcf, 0xf7, + 0xd4, 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xbd, + 0xf7, 0x7e, 0x05, 0x0e, 0x4f, 0xf8, 0x15, 0xf9, 0x6d, 0x15, 0xfb, 0x2a, + 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0x87, 0x8b, 0xa6, 0xf7, 0x11, 0xfb, + 0xf1, 0x8b, 0xf7, 0x14, 0xf8, 0xf0, 0x05, 0x0e, 0xf7, 0x36, 0xf8, 0x85, + 0x16, 0xf7, 0xa1, 0xf8, 0xff, 0xfb, 0x18, 0xfc, 0xff, 0xf7, 0x22, 0x8b, + 0xf7, 0x2f, 0xf9, 0x6d, 0xfb, 0x6f, 0x8b, 0xfb, 0x92, 0xfc, 0xc4, 0x77, + 0xf8, 0xc4, 0xfb, 0x6d, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x22, 0x8b, + 0xf7, 0x18, 0xf8, 0xff, 0x92, 0xfc, 0xff, 0xf7, 0x2a, 0x8b, 0x05, 0x0e, + 0xbe, 0xf9, 0xc4, 0xf9, 0x6d, 0x15, 0xfb, 0x22, 0x8b, 0xfb, 0x01, 0xfc, + 0x97, 0xfb, 0x54, 0xf8, 0x97, 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, + 0xf7, 0x22, 0x8b, 0xf7, 0x03, 0xf8, 0x9f, 0xf7, 0x54, 0xfc, 0x9f, 0xf7, + 0x28, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x0e, 0xf6, 0xf8, 0xae, 0xf9, + 0x79, 0x15, 0xfb, 0x10, 0x8b, 0x26, 0x5b, 0x39, 0x28, 0x3d, 0x2f, 0x5c, + 0xfb, 0x12, 0x8b, 0xfb, 0x07, 0x8b, 0xfb, 0x43, 0xf7, 0x03, 0xfb, 0x01, + 0xf7, 0x46, 0x8b, 0xf7, 0x14, 0x8b, 0xeb, 0xb8, 0xe1, 0xf1, 0xd9, 0xe6, + 0xb8, 0xf7, 0x0e, 0x8b, 0xf7, 0x0a, 0x8b, 0xf7, 0x48, 0x20, 0xf5, 0xfb, + 0x4b, 0x8b, 0x08, 0x78, 0xfb, 0x14, 0x15, 0xef, 0xc7, 0x49, 0xfb, 0x02, + 0x1f, 0x8b, 0x3c, 0x70, 0x33, 0x60, 0x4f, 0x59, 0x45, 0x4c, 0x68, 0x3e, + 0x8b, 0x26, 0x8b, 0x4c, 0xcf, 0x8b, 0xf7, 0x01, 0x8b, 0xd9, 0xa7, 0xe3, + 0xb7, 0xc8, 0xbd, 0xcf, 0xcd, 0xaf, 0xd7, 0x8b, 0x08, 0x0e, 0x87, 0xf7, + 0xad, 0xf7, 0x98, 0x15, 0xf7, 0x4f, 0x06, 0xda, 0x8b, 0xc5, 0xa3, 0xc0, + 0xc4, 0xc1, 0xc4, 0xae, 0xe0, 0x8b, 0xd8, 0x8b, 0xbf, 0x74, 0xba, 0x62, + 0xaa, 0x67, 0xa7, 0x62, 0x96, 0x48, 0x8b, 0x08, 0xfb, 0xc8, 0x8b, 0xfb, + 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xc2, 0xf7, 0x98, 0x05, 0xa6, 0xf7, + 0x11, 0x15, 0xb9, 0xf7, 0x6f, 0xf7, 0x2e, 0x8b, 0x05, 0xc1, 0xaf, 0x6b, + 0x5c, 0x1f, 0x8b, 0x6e, 0x80, 0x64, 0x7c, 0x76, 0x73, 0x68, 0x69, 0x7b, + 0x56, 0x8b, 0x08, 0xfb, 0x2d, 0x06, 0x0e, 0xf6, 0xf9, 0x42, 0xf2, 0x15, + 0xe0, 0xdd, 0xc7, 0xf7, 0x25, 0x8b, 0xf7, 0x0f, 0x8b, 0xf7, 0x47, 0xfb, + 0x02, 0xf7, 0x01, 0xfb, 0x4b, 0x8b, 0xfb, 0x10, 0x8b, 0x28, 0x5c, 0x38, + 0x27, 0x3f, 0x31, 0x5c, 0xfb, 0x12, 0x8b, 0xfb, 0x08, 0x8b, 0xfb, 0x43, + 0xf7, 0x03, 0xfb, 0x02, 0xf7, 0x45, 0x8b, 0xd2, 0x8b, 0xc6, 0x9b, 0xc8, + 0xad, 0x08, 0xd0, 0x3a, 0xe8, 0xdc, 0x4b, 0xd7, 0x05, 0xfb, 0x27, 0xf7, + 0x43, 0x15, 0x2d, 0x3a, 0xc9, 0x42, 0x05, 0x72, 0x7f, 0x6b, 0x84, 0x6b, + 0x8b, 0x28, 0x8b, 0x4e, 0xcf, 0x8b, 0xf7, 0x01, 0x8b, 0xda, 0xa6, 0xe1, + 0xb7, 0xc8, 0xbd, 0xd1, 0xca, 0xae, 0xd7, 0x8b, 0xf2, 0x8b, 0xc8, 0x49, + 0x8b, 0xfb, 0x03, 0x8b, 0x39, 0x6b, 0x2b, 0x5d, 0x51, 0x08, 0x4a, 0xd9, + 0x05, 0x0e, 0xbe, 0xf7, 0xb7, 0xf7, 0xb5, 0x15, 0xf7, 0x40, 0x06, 0xc4, + 0xa7, 0x79, 0x66, 0x1f, 0x8b, 0x7f, 0x88, 0x7e, 0x82, 0x67, 0x08, 0x78, + 0x46, 0x84, 0x66, 0x8b, 0x71, 0x8b, 0x7f, 0x8d, 0x81, 0x91, 0x78, 0x08, + 0xf7, 0x33, 0x8b, 0x91, 0xa6, 0x05, 0x7e, 0x95, 0x86, 0x95, 0x8b, 0x99, + 0x8b, 0x91, 0x8c, 0x95, 0x8d, 0x95, 0x08, 0xa2, 0xf7, 0x0f, 0x90, 0xae, + 0x8b, 0xa4, 0x8b, 0xb1, 0x71, 0xa6, 0x57, 0x9c, 0xc0, 0xa5, 0xa5, 0x9c, + 0xa3, 0xa4, 0x08, 0xb2, 0xb3, 0xa4, 0xca, 0x8b, 0xc3, 0x8b, 0xb1, 0x7b, + 0xb2, 0x70, 0xa6, 0x6b, 0xab, 0x63, 0x99, 0x51, 0x8b, 0x08, 0xfc, 0x0d, + 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0x05, 0xc8, 0xf7, 0xb5, + 0x05, 0xa6, 0xf7, 0x11, 0x15, 0xb3, 0xf7, 0x52, 0xf7, 0x3c, 0x8b, 0x05, + 0xb9, 0x8b, 0xa2, 0x85, 0x9e, 0x7c, 0x99, 0x7e, 0x93, 0x7a, 0x8b, 0x78, + 0x8b, 0x6f, 0x7f, 0x6c, 0x79, 0x77, 0x71, 0x6e, 0x6c, 0x7f, 0x59, 0x8b, + 0x08, 0xfb, 0x49, 0x06, 0x0e, 0x87, 0xf9, 0x61, 0xf8, 0x8f, 0x15, 0x91, + 0xa7, 0x8d, 0x99, 0x8b, 0x9f, 0x8b, 0xf7, 0x00, 0x2e, 0xcb, 0xfb, 0x33, + 0x8b, 0x2a, 0x8b, 0x3f, 0x73, 0x52, 0x59, 0x52, 0x5a, 0x68, 0x40, 0x8b, + 0x44, 0x8b, 0x38, 0xbd, 0x5f, 0xf7, 0x0b, 0x73, 0x08, 0xed, 0x77, 0x05, + 0xe6, 0x79, 0xa8, 0x77, 0x8b, 0x5c, 0x08, 0x48, 0x48, 0x5f, 0x23, 0x30, + 0x57, 0xac, 0xc4, 0x1e, 0x8b, 0x90, 0x8c, 0x94, 0x8c, 0x94, 0x08, 0xfb, + 0x26, 0x06, 0x88, 0x77, 0x8a, 0x81, 0x8b, 0x7d, 0x8b, 0x56, 0x9f, 0x5d, + 0xaf, 0x6a, 0xbb, 0x5f, 0xd0, 0x76, 0xeb, 0x8b, 0xf7, 0x0e, 0x8b, 0xe8, + 0xae, 0xc5, 0xce, 0xb5, 0xba, 0xa6, 0xd4, 0x8b, 0xcd, 0x8b, 0xd8, 0x54, + 0xbf, 0x25, 0x9f, 0x08, 0xfb, 0x01, 0xa1, 0x05, 0x2d, 0x9e, 0x70, 0x9b, + 0x8b, 0xb1, 0x08, 0xcb, 0xc3, 0xb3, 0xe6, 0xe0, 0xba, 0x6e, 0x55, 0x1e, + 0x8b, 0x86, 0x8a, 0x82, 0x8a, 0x82, 0x08, 0xf7, 0x20, 0x06, 0x0e, 0x4f, + 0xf8, 0x96, 0xf8, 0xf0, 0x15, 0xf7, 0x68, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, + 0xdc, 0x8b, 0x70, 0xfb, 0x11, 0xf7, 0x72, 0x8b, 0xfb, 0x15, 0xfc, 0xf0, + 0xf7, 0x2a, 0x8b, 0xf7, 0x15, 0xf8, 0xf0, 0x05, 0x0e, 0xbe, 0xf9, 0x27, + 0xf9, 0x6d, 0x15, 0x22, 0xfc, 0x82, 0x05, 0x78, 0x31, 0x59, 0x63, 0x30, + 0x8b, 0x3d, 0x8b, 0x5e, 0xab, 0x8b, 0xc0, 0x8b, 0x9a, 0x8d, 0x99, 0x8e, + 0x9b, 0x08, 0xf4, 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x26, 0xfc, 0x6e, 0x05, + 0x84, 0x6a, 0x87, 0x6a, 0x8b, 0x75, 0x8b, 0xfb, 0x08, 0xeb, 0x41, 0xf7, + 0x2b, 0x8b, 0xe3, 0x8b, 0xdd, 0xa5, 0xc8, 0xbb, 0xc4, 0xb8, 0xab, 0xc3, + 0x9d, 0xde, 0x08, 0xf4, 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x05, 0x0e, 0x87, + 0xf8, 0x24, 0x16, 0xf8, 0x26, 0xf9, 0x6d, 0xfb, 0x2b, 0x8b, 0xfb, 0xa8, + 0xfc, 0xb9, 0x5e, 0xf8, 0xb9, 0xfb, 0x2b, 0x8b, 0xe9, 0xfd, 0x6d, 0xf7, + 0x13, 0x8b, 0x05, 0x0e, 0xf7, 0xa5, 0xf9, 0x6e, 0x16, 0xf7, 0xf9, 0xf9, + 0x6d, 0xfb, 0x33, 0x8b, 0xfb, 0x75, 0xfc, 0xb8, 0x8e, 0xf8, 0xb8, 0xfb, + 0x32, 0x8b, 0xfb, 0x74, 0xfc, 0xb6, 0x8e, 0xf8, 0xb6, 0xfb, 0x33, 0x8b, + 0xbe, 0xfd, 0x6d, 0xf7, 0x1b, 0x8b, 0xf7, 0x81, 0xf8, 0xbf, 0x8f, 0xfc, + 0xbf, 0xf7, 0x1b, 0x8b, 0x05, 0x0e, 0x87, 0xf8, 0x87, 0xf8, 0x08, 0x15, + 0xf7, 0xc3, 0xf7, 0xf9, 0xfb, 0x43, 0x8b, 0xfb, 0x4b, 0xfb, 0x80, 0x3c, + 0xf7, 0x80, 0xfb, 0x46, 0x8b, 0xf7, 0x25, 0xfb, 0xfe, 0xfb, 0xca, 0xfc, + 0x03, 0xf7, 0x43, 0x8b, 0xf7, 0x51, 0xf7, 0x8d, 0xe5, 0xfb, 0x8d, 0xf7, + 0x47, 0x8b, 0xfb, 0x30, 0xf8, 0x08, 0x05, 0x0e, 0x87, 0xf8, 0x71, 0xf7, + 0xa2, 0x15, 0xf7, 0xdc, 0xf8, 0x5f, 0xfb, 0x3b, 0x8b, 0xfb, 0x63, 0xfb, + 0xcf, 0x39, 0xf7, 0xcf, 0xfb, 0x3b, 0x8b, 0xf7, 0x25, 0xfc, 0x5f, 0x51, + 0xfb, 0xa2, 0xf7, 0x2a, 0x8b, 0xc5, 0xf7, 0xa2, 0x05, 0x0e, 0x4f, 0xf9, + 0x71, 0xf9, 0x6d, 0x15, 0xfc, 0xb8, 0x8b, 0x70, 0xfb, 0x11, 0xf8, 0x09, + 0x8b, 0xfc, 0x6e, 0xfc, 0x73, 0x70, 0xfb, 0x11, 0xf8, 0xb8, 0x8b, 0xa6, + 0xf7, 0x11, 0xfc, 0x09, 0x8b, 0xf8, 0x6e, 0xf8, 0x73, 0xa6, 0xf7, 0x11, + 0x05, 0x0e, 0xfb, 0xe6, 0xf8, 0x63, 0xf9, 0x6d, 0x15, 0xfb, 0x87, 0x8b, + 0xfb, 0x59, 0xfe, 0x35, 0xf7, 0x87, 0x8b, 0xa0, 0xef, 0xfb, 0x05, 0x8b, + 0xf7, 0x2e, 0xf9, 0x6d, 0xf7, 0x05, 0x8b, 0xa1, 0xef, 0x05, 0x0e, 0xfc, + 0x1d, 0xf7, 0x1e, 0xf9, 0x59, 0x15, 0xd3, 0xfd, 0x70, 0xd6, 0x8b, 0x42, + 0xf9, 0x70, 0x41, 0x8b, 0x05, 0x0e, 0xfb, 0xe6, 0x72, 0xfb, 0x5c, 0x15, + 0xf7, 0x87, 0x8b, 0xf7, 0x59, 0xfa, 0x35, 0xfb, 0x87, 0x8b, 0x76, 0x27, + 0xf7, 0x05, 0x8b, 0xfb, 0x2e, 0xfd, 0x6d, 0xfb, 0x05, 0x8b, 0x75, 0x27, + 0x05, 0x0e, 0x34, 0xf8, 0xd8, 0xf7, 0xa2, 0x15, 0x3a, 0xf8, 0x3d, 0xfb, + 0x11, 0x8b, 0xfb, 0x93, 0xfc, 0x3d, 0xf7, 0x04, 0x8b, 0xf7, 0x46, 0xf7, + 0xc0, 0xc5, 0xfb, 0xc0, 0xf7, 0x05, 0x8b, 0x05, 0x0e, 0xf8, 0xba, 0x3f, + 0x15, 0xfc, 0xec, 0x8b, 0x7c, 0x46, 0xf8, 0xec, 0x8b, 0x9a, 0xd0, 0x05, + 0x0e, 0xfc, 0x1d, 0xf7, 0xc2, 0xf8, 0x69, 0x15, 0xa6, 0xf7, 0x11, 0x3a, + 0x8b, 0x05, 0x94, 0xbd, 0xab, 0xa8, 0xc5, 0x95, 0x08, 0x95, 0xb9, 0x05, + 0x32, 0x84, 0x4b, 0x52, 0x7d, 0x34, 0x08, 0x74, 0xfb, 0x01, 0xf7, 0x1b, + 0x8b, 0x05, 0x0e, 0xf8, 0xa3, 0x9c, 0x15, 0x7c, 0x9c, 0x85, 0x98, 0x8b, + 0x9a, 0x8b, 0x91, 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xca, 0xf7, 0xc0, 0x05, + 0x8f, 0x9d, 0x8d, 0x9a, 0x8b, 0x97, 0x8b, 0xa8, 0x79, 0xae, 0x74, 0x9e, + 0x6b, 0xa5, 0x5a, 0x97, 0x45, 0x8b, 0xfb, 0x31, 0x8b, 0x3a, 0x52, 0x6f, + 0xfb, 0x16, 0x08, 0xf7, 0x17, 0x06, 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, 0x8b, + 0xbe, 0x8b, 0xa1, 0x7e, 0x8b, 0x6d, 0x8b, 0x76, 0x7d, 0x75, 0x77, 0x81, + 0x77, 0x80, 0x8b, 0x8b, 0x43, 0x81, 0x08, 0x51, 0x82, 0x05, 0x5b, 0x83, + 0x66, 0x7d, 0x6c, 0x75, 0x56, 0x65, 0x6a, 0x4e, 0x8b, 0x4f, 0x8b, 0x65, + 0x9d, 0x65, 0xa8, 0x73, 0xa4, 0x76, 0xad, 0x81, 0xb6, 0x8b, 0xc5, 0x8b, + 0xbc, 0xa2, 0xc7, 0xc1, 0x08, 0x88, 0x7c, 0x8b, 0x86, 0x8b, 0x84, 0x8b, + 0x81, 0x8d, 0x85, 0x90, 0x80, 0x08, 0xf7, 0x2d, 0x8b, 0x05, 0x8f, 0x9c, + 0x05, 0xfb, 0x13, 0xf7, 0x5c, 0x15, 0x79, 0x39, 0x5b, 0x5d, 0x47, 0x8b, + 0x5b, 0x8b, 0x72, 0x9c, 0x8b, 0xac, 0x8b, 0xba, 0xb0, 0xac, 0xcc, 0x96, + 0x08, 0xbd, 0x93, 0x9b, 0x8e, 0x05, 0x95, 0x8d, 0x92, 0x8c, 0x8f, 0x8c, + 0x96, 0x8d, 0x8e, 0x8c, 0x97, 0x92, 0x08, 0x83, 0x65, 0x05, 0x0e, 0x4f, + 0xf7, 0x6a, 0xf9, 0x6d, 0x15, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x20, 0x8b, + 0x97, 0xc2, 0x05, 0xa1, 0x56, 0xb6, 0x72, 0xce, 0x8b, 0x08, 0xf7, 0x2e, + 0xf7, 0x23, 0xf7, 0x43, 0xf7, 0x52, 0xf7, 0x11, 0x46, 0xdd, 0x21, 0x1f, + 0x47, 0x8b, 0x56, 0x72, 0x5e, 0x55, 0x08, 0xc2, 0xf7, 0x97, 0x05, 0xfb, + 0x20, 0x06, 0xf7, 0x57, 0xfb, 0xb8, 0x15, 0xc1, 0xad, 0x5e, 0x42, 0xfb, + 0x0e, 0x3f, 0xfb, 0x00, 0x36, 0x56, 0x68, 0xb8, 0xcf, 0xf7, 0x11, 0xd6, + 0xf7, 0x02, 0xe1, 0x1f, 0x0e, 0xf8, 0xe5, 0xf7, 0xe6, 0x15, 0x8e, 0xa3, + 0x8c, 0x94, 0x8b, 0x95, 0x8b, 0xb5, 0x7a, 0xb3, 0x6c, 0xaa, 0x65, 0xb1, + 0x5d, 0x9c, 0x48, 0x8b, 0x2d, 0x8b, 0x41, 0x6b, 0x57, 0x4c, 0x50, 0x45, + 0x61, 0xfb, 0x09, 0x8b, 0x2c, 0x8b, 0x59, 0x9d, 0x5a, 0xab, 0x68, 0x08, + 0xaf, 0x62, 0xc2, 0x77, 0xd5, 0x8b, 0xf7, 0x15, 0x8b, 0xed, 0xd7, 0xb5, + 0xf7, 0x1a, 0x08, 0xfb, 0x1a, 0x06, 0x6c, 0x44, 0x6a, 0x70, 0x55, 0x8b, + 0x4f, 0x8b, 0x6e, 0xad, 0x8b, 0xd0, 0x8b, 0xc0, 0x98, 0xc6, 0xa3, 0xbb, + 0xa7, 0xc6, 0xb0, 0xa5, 0xc2, 0x8b, 0xac, 0x8b, 0xa4, 0x7f, 0x98, 0x76, + 0x93, 0x7c, 0x8d, 0x7f, 0x8c, 0x64, 0x08, 0xf7, 0x1a, 0x06, 0x0e, 0x4f, + 0xf8, 0x29, 0x16, 0xf7, 0x20, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0xfb, 0x20, + 0x8b, 0x54, 0xfb, 0x97, 0x05, 0x74, 0xc1, 0x61, 0xa4, 0x47, 0x8b, 0x3a, + 0x8b, 0x39, 0x5d, 0x57, 0x40, 0x5a, 0x44, 0x6e, 0x31, 0x8b, 0x39, 0x08, + 0xfb, 0x12, 0xcf, 0x39, 0xf3, 0x1e, 0xce, 0x8b, 0xc0, 0xa4, 0xb9, 0xc0, + 0x08, 0x7f, 0x54, 0x05, 0x72, 0xf8, 0x49, 0x15, 0xc1, 0xad, 0x5f, 0x45, + 0x1f, 0xfb, 0x12, 0x41, 0xfb, 0x00, 0x36, 0x56, 0x69, 0xb8, 0xd3, 0x1e, + 0xf7, 0x0d, 0xd6, 0xf7, 0x02, 0xde, 0x1e, 0x0e, 0xf8, 0xd1, 0xf7, 0x76, + 0x15, 0x97, 0xb8, 0x91, 0xb5, 0x8b, 0xb1, 0x8b, 0xb9, 0x7a, 0xba, 0x6f, + 0xaf, 0x67, 0xb8, 0x51, 0xa3, 0x42, 0x8b, 0x3d, 0x8b, 0x3b, 0x6c, 0x5c, + 0x5a, 0x4b, 0x48, 0x5d, 0xfb, 0x09, 0x8b, 0x27, 0x8b, 0xfb, 0x10, 0xe1, + 0x37, 0xf7, 0x11, 0x8b, 0x08, 0xf7, 0x0d, 0x8b, 0xf0, 0xcb, 0xc2, 0xf7, + 0x03, 0x08, 0xfb, 0x1e, 0x06, 0x77, 0x65, 0x5f, 0x72, 0x5b, 0x8b, 0x52, + 0x8b, 0x65, 0xb0, 0x8b, 0xc2, 0x8b, 0x94, 0x8b, 0x93, 0x8e, 0xa7, 0x08, + 0xf7, 0xff, 0x06, 0xfb, 0x11, 0xe8, 0x15, 0xfb, 0x70, 0x06, 0x94, 0xab, + 0x93, 0x9d, 0x98, 0x9c, 0xa3, 0xab, 0xb3, 0x9e, 0xb3, 0x8b, 0xae, 0x8b, + 0xa8, 0x7a, 0x98, 0x6f, 0x92, 0x7c, 0x8d, 0x80, 0x8b, 0x6b, 0x08, 0x7c, + 0x07, 0x0e, 0xfb, 0xe6, 0xf8, 0x3d, 0xf8, 0xa5, 0x15, 0x38, 0x8b, 0x97, + 0xc0, 0x05, 0x91, 0xa8, 0x9a, 0x99, 0xa4, 0x8b, 0x95, 0x8b, 0x90, 0x8a, + 0xa6, 0x88, 0x08, 0xa1, 0xf4, 0x05, 0x61, 0x8d, 0x7a, 0x8c, 0x79, 0x8b, + 0x29, 0x8b, 0x56, 0x61, 0x77, 0x2e, 0x08, 0x7d, 0x4a, 0x3f, 0x8b, 0x77, + 0x2e, 0xd8, 0x8b, 0x2e, 0xfc, 0x48, 0xf7, 0x20, 0x8b, 0xe8, 0xf8, 0x48, + 0xdd, 0x8b, 0x9f, 0xe8, 0x05, 0x0e, 0x4f, 0xf8, 0x9f, 0xf8, 0xb0, 0x15, + 0x79, 0x38, 0x05, 0x70, 0xc9, 0x62, 0xa9, 0x50, 0x8b, 0x3f, 0x8b, 0x40, + 0x65, 0x56, 0x49, 0x51, 0x44, 0x66, 0xfb, 0x02, 0x8b, 0x2a, 0x8b, 0xfb, + 0x02, 0xd5, 0x3b, 0xf0, 0x8b, 0xc9, 0x8b, 0xb3, 0x9e, 0xcb, 0xc6, 0x08, + 0x7b, 0x42, 0x05, 0x7d, 0x4a, 0x50, 0x5e, 0x42, 0x8b, 0x08, 0x5a, 0x66, + 0xa1, 0xa8, 0x1f, 0x8c, 0x97, 0xfb, 0x24, 0x8b, 0x05, 0x89, 0x7f, 0x8a, + 0x80, 0x8b, 0x83, 0x8b, 0x65, 0xa5, 0x65, 0xb4, 0x77, 0xaf, 0x79, 0xb7, + 0x83, 0xc9, 0x8b, 0xf7, 0x3a, 0x8b, 0xf7, 0x01, 0xd3, 0xa6, 0xf7, 0x14, + 0x08, 0xf7, 0x0b, 0xf8, 0xc2, 0x05, 0xfb, 0x19, 0x06, 0xfb, 0x24, 0x24, + 0x15, 0xc3, 0xaf, 0x5b, 0x41, 0xfb, 0x0e, 0x3f, 0x23, 0x32, 0x57, 0x6b, + 0xb6, 0xd0, 0x1f, 0xf7, 0x0f, 0xd6, 0xf7, 0x05, 0xdd, 0x1e, 0x0e, 0x4f, + 0xf7, 0x72, 0xf9, 0x6d, 0x15, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x20, 0x8b, + 0xcc, 0xf7, 0xc4, 0x05, 0x9c, 0xdc, 0xc0, 0xbf, 0xcb, 0x8b, 0xba, 0x8b, + 0xa5, 0x70, 0x8b, 0x5a, 0x8b, 0x7e, 0x89, 0x7d, 0x87, 0x76, 0x08, 0x48, + 0xfb, 0xcd, 0xf7, 0x20, 0x8b, 0xd8, 0xf7, 0xfe, 0x05, 0x8f, 0x9e, 0x8d, + 0x9d, 0x8b, 0x9d, 0x8b, 0xda, 0x51, 0xc0, 0x34, 0x8b, 0x44, 0x8b, 0x53, + 0x6f, 0x56, 0x4c, 0x08, 0xc5, 0xf7, 0xa3, 0xfb, 0x20, 0x8b, 0x05, 0x0e, + 0xfc, 0x1d, 0xf7, 0xd6, 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x07, + 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0xf7, 0x07, 0xf8, 0xb0, 0x05, 0xb3, 0xf7, + 0x51, 0x15, 0xfb, 0x20, 0x8b, 0x70, 0xfb, 0x11, 0xf7, 0x20, 0x8b, 0xa6, + 0xf7, 0x11, 0x05, 0x0e, 0xfc, 0x1d, 0xf8, 0x01, 0xf9, 0x6d, 0x15, 0xfb, + 0x20, 0x8b, 0x70, 0xfb, 0x11, 0xf7, 0x20, 0x8b, 0xa6, 0xf7, 0x11, 0x05, + 0x63, 0xfb, 0x51, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x14, 0xfc, 0xee, 0x05, + 0x84, 0x6b, 0x7d, 0x7f, 0x6d, 0x8b, 0x7d, 0x8b, 0x84, 0x8c, 0x87, 0x8e, + 0x08, 0x73, 0xfb, 0x03, 0x05, 0x99, 0x87, 0x97, 0x8a, 0x9e, 0x8b, 0xf7, + 0x06, 0x8b, 0xc3, 0xb0, 0x9d, 0xe2, 0x08, 0xf7, 0x1b, 0xf9, 0x0e, 0x05, + 0x0e, 0xf7, 0xf6, 0xf9, 0x6d, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x2f, 0xfd, + 0x6d, 0xf7, 0x20, 0x8b, 0xb1, 0xf7, 0x45, 0xcf, 0xc9, 0xda, 0xfb, 0x83, + 0xf7, 0x38, 0x8b, 0xfb, 0x15, 0xf7, 0xe2, 0xf7, 0x7c, 0xf7, 0x62, 0xfb, + 0x33, 0x8b, 0xfb, 0x73, 0xfb, 0x66, 0xe0, 0xf8, 0x23, 0x05, 0x0e, 0xfc, + 0x1d, 0xf7, 0xfe, 0xf9, 0x6d, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x2f, 0xfd, + 0x6d, 0xf7, 0x20, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x0e, 0xf7, 0x6e, + 0xf7, 0x43, 0xf8, 0xb0, 0x15, 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, 0x8b, + 0xd0, 0xf7, 0xd8, 0x05, 0x9a, 0xd1, 0xb8, 0xb6, 0xc5, 0x8b, 0xb1, 0x8b, + 0xa4, 0x74, 0x8b, 0x68, 0x8b, 0x7f, 0x8a, 0x81, 0x89, 0x80, 0x08, 0x41, + 0xfb, 0xee, 0xf7, 0x20, 0x8b, 0xd0, 0xf7, 0xd8, 0x05, 0x9a, 0xd3, 0xb8, + 0xb4, 0xca, 0x8b, 0xb0, 0x8b, 0xa0, 0x77, 0x8b, 0x67, 0x8b, 0x7f, 0x89, + 0x7c, 0x88, 0x7d, 0x08, 0x43, 0xfb, 0xe8, 0xf7, 0x20, 0x8b, 0xd8, 0xf7, + 0xfe, 0x05, 0x91, 0xa8, 0x8d, 0x99, 0x8b, 0x9d, 0x8b, 0xda, 0x57, 0xba, + 0x31, 0x8b, 0x47, 0x8b, 0x55, 0x72, 0x54, 0x52, 0x7d, 0xbd, 0x5b, 0xab, + 0x4d, 0x8b, 0x4a, 0x8b, 0x5c, 0x72, 0x50, 0x4a, 0x08, 0x9c, 0xdc, 0x05, + 0xfb, 0x1f, 0x06, 0x0e, 0x4f, 0xf7, 0x46, 0xf8, 0xb0, 0x15, 0xfb, 0x07, + 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0xcc, 0xf7, 0xc4, 0x05, 0x9c, 0xdd, 0xc0, + 0xbe, 0xce, 0x8b, 0xbb, 0x8b, 0xa5, 0x70, 0x8b, 0x5b, 0x8b, 0x7e, 0x89, + 0x7d, 0x87, 0x75, 0x08, 0x48, 0xfb, 0xcd, 0xf7, 0x20, 0x8b, 0xd8, 0xf7, + 0xfe, 0x05, 0x8f, 0x9e, 0x8d, 0x9d, 0x8b, 0x9d, 0x8b, 0xdb, 0x51, 0xbf, + 0x32, 0x8b, 0x41, 0x8b, 0x55, 0x70, 0x55, 0x4b, 0x08, 0x9d, 0xdd, 0x05, + 0xfb, 0x20, 0x06, 0x0e, 0x4f, 0xf8, 0x31, 0xf8, 0xb9, 0x15, 0x24, 0x8b, + 0x31, 0x5f, 0x50, 0x3c, 0x5b, 0x4c, 0x6c, 0x27, 0x8b, 0x35, 0x8b, 0xfb, + 0x0e, 0xe0, 0x3d, 0xf7, 0x18, 0x8b, 0xf7, 0x00, 0x8b, 0xe2, 0xb5, 0xc8, + 0xdc, 0xba, 0xca, 0xab, 0xef, 0x8b, 0xe1, 0x8b, 0xf7, 0x10, 0x37, 0xd7, + 0xfb, 0x1d, 0x8b, 0x08, 0x75, 0xfb, 0x04, 0x15, 0xc8, 0xb2, 0x5d, 0x44, + 0x1f, 0x8b, 0x5a, 0x7d, 0x56, 0x73, 0x61, 0x6c, 0x53, 0x5d, 0x6c, 0x57, + 0x8b, 0x08, 0x4f, 0x64, 0xb8, 0xd2, 0xf7, 0x13, 0xd7, 0xf4, 0xe5, 0x1f, + 0x0e, 0x4f, 0xf7, 0xcc, 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x35, + 0xfd, 0x8a, 0xf7, 0x20, 0x8b, 0xc7, 0xf7, 0xae, 0x05, 0xa0, 0x4f, 0xb5, + 0x6f, 0xd1, 0x8b, 0x08, 0xf7, 0x35, 0xf7, 0x18, 0xf7, 0x39, 0xf7, 0x5d, + 0x1f, 0xf7, 0x13, 0x48, 0xdb, 0x21, 0x1e, 0x48, 0x8b, 0x53, 0x6d, 0x5d, + 0x50, 0x08, 0x9c, 0xdb, 0x05, 0xe9, 0x24, 0x15, 0xc1, 0xad, 0x5e, 0x46, + 0xfb, 0x13, 0x41, 0xfb, 0x00, 0x35, 0x56, 0x68, 0xb8, 0xcf, 0x1f, 0xf7, + 0x12, 0xd5, 0xf7, 0x02, 0xe1, 0x1e, 0x0e, 0x4f, 0xf8, 0x9b, 0xf8, 0xb0, + 0x15, 0x7a, 0x3b, 0x05, 0x77, 0xc7, 0x5f, 0xa8, 0x46, 0x8b, 0x38, 0x8b, + 0x3b, 0x5f, 0x55, 0x40, 0x59, 0x44, 0x6d, 0x2e, 0x8b, 0x35, 0x8b, 0xfb, + 0x0f, 0xd1, 0x3a, 0xf5, 0x8b, 0xcf, 0x8b, 0xc4, 0xa8, 0xb8, 0xc6, 0x08, + 0x4f, 0xfb, 0xae, 0xf7, 0x20, 0x8b, 0x05, 0xf7, 0x35, 0xf9, 0x8a, 0x05, + 0xfb, 0x20, 0x06, 0xfb, 0x22, 0x24, 0x15, 0xc1, 0xae, 0x5f, 0x46, 0xfb, + 0x13, 0x40, 0xfb, 0x01, 0x34, 0x55, 0x68, 0xb8, 0xd0, 0x1f, 0xf7, 0x11, + 0xd7, 0xf7, 0x02, 0xe1, 0x1e, 0x0e, 0xfb, 0xae, 0xf7, 0x46, 0xf8, 0xb0, + 0x15, 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0xc8, 0xf7, 0xb3, 0x05, + 0x9c, 0xdd, 0xbe, 0xb4, 0xdd, 0x8b, 0x9a, 0x8b, 0x95, 0x8a, 0x9d, 0x88, + 0x08, 0xa9, 0xf7, 0x22, 0x05, 0x83, 0x8c, 0x86, 0x8b, 0x87, 0x8b, 0x4b, + 0x8b, 0x4b, 0x61, 0x5c, 0x42, 0x08, 0xa2, 0xf5, 0x05, 0xfb, 0x20, 0x06, + 0x0e, 0xf8, 0xdc, 0xf8, 0x02, 0x15, 0x8f, 0x9d, 0x8c, 0x94, 0x8b, 0x96, + 0x8b, 0xe5, 0x3f, 0xc2, 0xfb, 0x12, 0x8b, 0x3c, 0x8b, 0x48, 0x76, 0x60, + 0x65, 0x60, 0x65, 0x6f, 0x52, 0x8b, 0x59, 0x8b, 0x53, 0xb4, 0x64, 0xe3, + 0x6e, 0x08, 0xda, 0x72, 0x05, 0xca, 0x77, 0x98, 0x82, 0x8b, 0x74, 0x8b, + 0x6b, 0x60, 0x74, 0x4e, 0x8b, 0x68, 0x8b, 0x6c, 0x93, 0x78, 0x99, 0x7d, + 0x97, 0x85, 0x96, 0x8a, 0xa2, 0x08, 0xfb, 0x1d, 0x06, 0x88, 0x7c, 0x8a, + 0x85, 0x8b, 0x82, 0x8b, 0x5e, 0xa8, 0x5c, 0xb7, 0x72, 0xb2, 0x74, 0xba, + 0x81, 0xc9, 0x8b, 0xf7, 0x3e, 0x8b, 0xf7, 0x00, 0xdd, 0x8b, 0xf7, 0x14, + 0x8b, 0xc7, 0x64, 0xb2, 0x38, 0xa4, 0x08, 0x2b, 0xa7, 0x05, 0x58, 0x9a, + 0x7d, 0x95, 0x8b, 0x9f, 0x08, 0xab, 0xae, 0xa0, 0xc0, 0x1e, 0xc2, 0xac, + 0x77, 0x6b, 0x1f, 0x8b, 0x85, 0x8a, 0x87, 0x89, 0x82, 0x08, 0xf7, 0x1b, + 0x06, 0x0e, 0xfb, 0xe6, 0xf8, 0x32, 0xf8, 0xa5, 0x15, 0x3d, 0x8b, 0xaa, + 0xf7, 0x25, 0xfb, 0x20, 0x8b, 0x6c, 0xfb, 0x25, 0x46, 0x8b, 0x77, 0x2e, + 0xd0, 0x8b, 0x45, 0xfb, 0xe0, 0x05, 0x88, 0x7d, 0x89, 0x7d, 0x8b, 0x7e, + 0x8b, 0x54, 0xb3, 0x6c, 0xd4, 0x8b, 0xac, 0x8b, 0xa3, 0x8e, 0xa7, 0x93, + 0x08, 0x9f, 0xed, 0x05, 0x7d, 0x89, 0x83, 0x8a, 0x80, 0x8b, 0x74, 0x8b, + 0x7c, 0x95, 0x8b, 0x9a, 0x8b, 0x90, 0x8d, 0x97, 0x8f, 0x9c, 0x08, 0xc9, + 0xf7, 0xba, 0xd9, 0x8b, 0x9f, 0xe8, 0x05, 0x0e, 0x4f, 0xf8, 0xb1, 0x16, + 0xf7, 0x07, 0xf8, 0xb0, 0xfb, 0x20, 0x8b, 0x47, 0xfb, 0xd2, 0x05, 0x7a, + 0x3a, 0x57, 0x57, 0x4a, 0x8b, 0x59, 0x8b, 0x71, 0xa5, 0x8b, 0xbc, 0x8b, + 0x99, 0x8d, 0x97, 0x8f, 0xa2, 0x08, 0xd1, 0xf7, 0xdb, 0xfb, 0x20, 0x8b, + 0x3b, 0xfc, 0x0c, 0x05, 0x87, 0x78, 0x89, 0x79, 0x8b, 0x79, 0x8b, 0x3b, + 0xc5, 0x57, 0xe3, 0x8b, 0xd5, 0x8b, 0xc1, 0xa6, 0xc1, 0xcb, 0x08, 0x7c, + 0x47, 0x05, 0xf7, 0x20, 0x06, 0x0e, 0xf7, 0xf2, 0x16, 0xf7, 0xc1, 0xf8, + 0xb0, 0xfb, 0x28, 0x8b, 0xfb, 0x58, 0xfc, 0x1f, 0x6d, 0xf8, 0x1f, 0xfb, + 0x28, 0x8b, 0xd5, 0xfc, 0xb0, 0xf7, 0x27, 0x8b, 0x05, 0x0e, 0xf6, 0xf8, + 0xfd, 0x16, 0xf7, 0x9c, 0xf8, 0xb0, 0xfb, 0x25, 0x8b, 0xfb, 0x37, 0xfc, + 0x0e, 0x8b, 0xf8, 0x0e, 0xfb, 0x24, 0x8b, 0xfb, 0x33, 0xfc, 0x0e, 0x86, + 0xf8, 0x0e, 0xfb, 0x25, 0x8b, 0xb0, 0xfc, 0xb0, 0xf7, 0x24, 0x8b, 0xf7, + 0x3a, 0xf8, 0x10, 0x90, 0xfc, 0x10, 0xf7, 0x25, 0x8b, 0x05, 0x0e, 0xf8, + 0x2f, 0xf7, 0xa6, 0x15, 0xf7, 0x81, 0xf7, 0x9e, 0xfb, 0x3c, 0x8b, 0xfb, + 0x0f, 0xfb, 0x37, 0x58, 0xf7, 0x37, 0xfb, 0x3c, 0x8b, 0xf7, 0x03, 0xfb, + 0x9e, 0xfb, 0x7d, 0xfb, 0xa6, 0xf7, 0x3c, 0x8b, 0xf7, 0x0f, 0xf7, 0x3c, + 0xc6, 0xfb, 0x3c, 0xf7, 0x3c, 0x8b, 0xfb, 0x0f, 0xf7, 0xa6, 0x05, 0x0e, + 0xf8, 0x91, 0xf8, 0xb0, 0x15, 0xfb, 0x57, 0xfc, 0x1d, 0x67, 0xf8, 0x1d, + 0xfb, 0x2e, 0x8b, 0xd7, 0xfc, 0xb0, 0x8c, 0x7c, 0x05, 0x52, 0x5f, 0x67, + 0x46, 0x1e, 0x7f, 0x8b, 0x86, 0x8b, 0x80, 0x8d, 0x08, 0x74, 0xfb, 0x01, + 0x05, 0x98, 0x88, 0x95, 0x8a, 0xa0, 0x8b, 0xb7, 0x8b, 0xb2, 0x91, 0xa9, + 0x96, 0xb6, 0x9c, 0xa1, 0xa1, 0xaf, 0xcc, 0x08, 0xf7, 0xfa, 0xf9, 0x12, + 0xfb, 0x24, 0x8b, 0x05, 0x0e, 0xfb, 0x3f, 0xf8, 0xd3, 0xf8, 0xb0, 0x15, + 0xfc, 0x39, 0x8b, 0x73, 0xfb, 0x05, 0xf7, 0x8d, 0x8b, 0xfb, 0xe2, 0xfb, + 0xce, 0x73, 0xfb, 0x05, 0xf8, 0x54, 0x8b, 0xa3, 0xf7, 0x05, 0xfb, 0xa6, + 0x8b, 0xf7, 0xe0, 0xf7, 0xce, 0xa3, 0xf7, 0x05, 0x05, 0x0e, 0xfb, 0xae, + 0xf8, 0x6c, 0xf9, 0x6d, 0x15, 0x3f, 0x06, 0x3c, 0x8b, 0x54, 0x59, 0x78, + 0x31, 0x08, 0x5e, 0xfb, 0x67, 0x05, 0x83, 0x61, 0x71, 0x76, 0x5f, 0x8b, + 0x08, 0x7f, 0x8b, 0x87, 0x8b, 0x77, 0x2f, 0x8f, 0x8a, 0x98, 0x8b, 0x05, + 0xad, 0x9f, 0x7d, 0x73, 0x1f, 0x8b, 0x85, 0x89, 0x7e, 0x88, 0x7c, 0x08, + 0x5e, 0xfb, 0x66, 0x05, 0x88, 0x7e, 0x8a, 0x7e, 0x8b, 0x7e, 0x08, 0x4f, + 0xb2, 0x62, 0xc5, 0x1e, 0xd8, 0x8b, 0xa0, 0xee, 0x68, 0x8b, 0x05, 0x72, + 0x7d, 0x94, 0x9b, 0x1f, 0x8b, 0x95, 0x8d, 0x98, 0x8e, 0x9c, 0x08, 0xb5, + 0xf7, 0x57, 0x05, 0x8e, 0x9a, 0x8d, 0x9b, 0x8b, 0x95, 0x8b, 0xa6, 0x7e, + 0xa0, 0x76, 0x94, 0x7f, 0x91, 0x83, 0x8d, 0x72, 0x8f, 0xd4, 0x93, 0xab, + 0xa8, 0x9b, 0xd3, 0x08, 0xb4, 0xf7, 0x57, 0x05, 0x95, 0xba, 0x95, 0x95, + 0xb0, 0x8b, 0x08, 0xb0, 0x8b, 0x05, 0xa0, 0xee, 0x05, 0x0e, 0xfc, 0x1b, + 0xf7, 0xe3, 0xf9, 0x6d, 0x15, 0x3b, 0x8b, 0xfb, 0x5a, 0xfe, 0x35, 0xdb, + 0x8b, 0xf7, 0x5a, 0xfa, 0x35, 0x05, 0x0e, 0xfb, 0xae, 0xa8, 0xfb, 0x5c, + 0x15, 0xd8, 0x06, 0xda, 0x8b, 0xc2, 0xbd, 0x9e, 0xe5, 0x08, 0xb8, 0xf7, + 0x67, 0x05, 0x93, 0xb5, 0xa5, 0xa0, 0xb7, 0x8b, 0x08, 0x98, 0x8b, 0x8f, + 0x8b, 0x9f, 0xe7, 0x87, 0x8c, 0x7d, 0x8b, 0x05, 0x69, 0x77, 0x99, 0xa3, + 0x1f, 0x8b, 0x91, 0x8d, 0x98, 0x8e, 0x9a, 0x08, 0xb8, 0xf7, 0x66, 0x05, + 0x8e, 0x98, 0x8c, 0x98, 0x8b, 0x98, 0x08, 0xc7, 0x64, 0xb4, 0x51, 0x1e, + 0x3d, 0x8b, 0x76, 0x28, 0xaf, 0x8b, 0x05, 0xa4, 0x99, 0x82, 0x7b, 0x1f, + 0x8b, 0x81, 0x89, 0x7e, 0x88, 0x7a, 0x08, 0x61, 0xfb, 0x57, 0x05, 0x88, + 0x7c, 0x89, 0x7b, 0x8b, 0x81, 0x8b, 0x70, 0x98, 0x76, 0xa0, 0x82, 0x97, + 0x85, 0x93, 0x89, 0xa4, 0x87, 0x42, 0x83, 0x6b, 0x6e, 0x7b, 0x43, 0x08, + 0x62, 0xfb, 0x57, 0x05, 0x81, 0x5c, 0x81, 0x81, 0x66, 0x8b, 0x08, 0x65, + 0x8b, 0x05, 0x76, 0x28, 0x05, 0x0e, 0x34, 0xf8, 0x8c, 0xf7, 0xb4, 0x15, + 0x7d, 0x58, 0x7c, 0x7c, 0x65, 0x8b, 0x75, 0x8b, 0x7e, 0x91, 0x76, 0x9e, + 0x08, 0x5a, 0xb5, 0x05, 0x77, 0x9c, 0x73, 0x93, 0x6b, 0x8b, 0x3b, 0x8b, + 0x56, 0x5b, 0x71, 0x2a, 0x08, 0xd9, 0x06, 0x98, 0xbd, 0x9b, 0x9a, 0xb1, + 0x8b, 0x9f, 0x8b, 0x9b, 0x84, 0x9f, 0x7a, 0x08, 0xbb, 0x61, 0x05, 0xa0, + 0x79, 0xa2, 0x83, 0xac, 0x8b, 0xdb, 0x8b, 0xc2, 0xbe, 0xa2, 0xea, 0x08, + 0x3e, 0x06, 0x0e, 0xfb, 0xe6, 0xa5, 0xfb, 0x4e, 0x15, 0xf7, 0x2a, 0x8b, + 0xb8, 0xf7, 0x66, 0xa3, 0xf7, 0xc9, 0x48, 0x8b, 0x20, 0xfb, 0xc9, 0x5e, + 0xfb, 0x66, 0x05, 0xf7, 0x10, 0xf8, 0xd8, 0x15, 0xf7, 0x2a, 0x8b, 0xaa, + 0xf7, 0x26, 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0x05, 0x0e, 0xf8, 0x2e, + 0xf8, 0x47, 0x15, 0xb1, 0x7f, 0x97, 0x72, 0x8b, 0x4f, 0x08, 0xf7, 0x1a, + 0x06, 0x8e, 0xa3, 0x8c, 0x94, 0x8b, 0x95, 0x8b, 0xcd, 0x5f, 0xc9, 0x4a, + 0xa5, 0x7b, 0x91, 0x7c, 0x8e, 0x73, 0x8e, 0x08, 0x9e, 0xe2, 0x49, 0x8b, + 0x78, 0x35, 0x05, 0x33, 0x84, 0x47, 0x65, 0x5a, 0x45, 0x59, 0x45, 0x69, + 0x20, 0x8b, 0x37, 0x8b, 0x3b, 0xb7, 0x44, 0xcf, 0x71, 0x9b, 0x84, 0x9c, + 0x87, 0xa3, 0x87, 0x08, 0x75, 0x23, 0xcd, 0x8b, 0xa0, 0xf1, 0x05, 0xf7, + 0x09, 0x91, 0xeb, 0xdc, 0xaf, 0xf7, 0x0e, 0x08, 0xfb, 0x1a, 0x06, 0x73, + 0x50, 0x71, 0x6e, 0x62, 0x81, 0x08, 0xd4, 0xf7, 0xee, 0x05, 0xfb, 0x1e, + 0xfb, 0xea, 0x15, 0x67, 0x9b, 0x7d, 0xa6, 0x8b, 0xc2, 0x8b, 0xd3, 0xa3, + 0xdc, 0xaf, 0xbc, 0x9a, 0xa0, 0xa0, 0x99, 0xa5, 0x92, 0x08, 0x43, 0xfb, + 0xea, 0x05, 0x0e, 0xf8, 0x5b, 0xf8, 0x07, 0x15, 0xfb, 0x1f, 0x06, 0x88, + 0x9a, 0x87, 0x9b, 0x82, 0xad, 0x80, 0xb2, 0x8a, 0x92, 0x8b, 0x99, 0x08, + 0xc4, 0xc0, 0xbd, 0xc8, 0xc9, 0xaa, 0x6c, 0x4d, 0x1e, 0x8b, 0x86, 0x8b, + 0x80, 0x8a, 0x81, 0x08, 0xf7, 0x17, 0x06, 0x8e, 0xa4, 0x8c, 0x98, 0x8b, + 0x9c, 0x8b, 0xf7, 0x08, 0x45, 0xc7, 0xfb, 0x1a, 0x8b, 0x3a, 0x8b, 0x47, + 0x72, 0x57, 0x5b, 0x5b, 0x5e, 0x6c, 0x4c, 0x8b, 0x53, 0x8b, 0x70, 0x90, + 0x78, 0xa0, 0x4e, 0x08, 0x4f, 0x8b, 0x7f, 0x54, 0xe4, 0x8b, 0x05, 0x8f, + 0x6f, 0x8c, 0x7f, 0x8b, 0x7c, 0x8b, 0x45, 0x63, 0x59, 0x23, 0x4e, 0x08, + 0xac, 0x26, 0x05, 0xbc, 0xa0, 0xa8, 0x92, 0xb0, 0x8b, 0xa6, 0x8b, 0xa2, + 0x87, 0xb8, 0x80, 0x08, 0xbc, 0x7f, 0x9f, 0x88, 0xa6, 0x8b, 0xbc, 0x8b, + 0xb5, 0x97, 0xcb, 0xac, 0x08, 0x79, 0xf7, 0x01, 0x05, 0x5e, 0x77, 0x6a, + 0x82, 0x67, 0x8b, 0x7b, 0x8b, 0x73, 0x8e, 0x71, 0x90, 0x08, 0x5d, 0x94, + 0x8a, 0x8b, 0x79, 0x8b, 0x6d, 0x8b, 0x7d, 0x87, 0x4b, 0x6e, 0xf7, 0x02, + 0xd8, 0xb4, 0xc3, 0x8b, 0xd2, 0x8b, 0x92, 0x8b, 0x91, 0x89, 0x98, 0x08, + 0xf7, 0x0e, 0x8b, 0x05, 0x97, 0xc2, 0x05, 0x0e, 0xfc, 0x8c, 0xf8, 0x28, + 0xf9, 0x5f, 0x15, 0xfc, 0xd9, 0xfd, 0x73, 0xe0, 0x8b, 0xf8, 0xd9, 0xf9, + 0x73, 0x36, 0x8b, 0x05, 0x0e, 0xf8, 0xd2, 0xf7, 0xf4, 0x15, 0xfb, 0x1f, + 0x8b, 0xf7, 0x9f, 0xf7, 0xf4, 0xfb, 0x1c, 0x8b, 0xfb, 0x4f, 0xfb, 0x92, + 0x36, 0xf7, 0x92, 0xfb, 0x1f, 0x8b, 0xf7, 0x14, 0xfb, 0xf4, 0xfb, 0x20, + 0x8b, 0x7f, 0x4f, 0xf7, 0x26, 0x8b, 0x80, 0x57, 0xfb, 0x26, 0x8b, 0x7e, + 0x4f, 0xf7, 0x26, 0x8b, 0x65, 0xfb, 0x48, 0x05, 0xf7, 0x20, 0x8b, 0xb1, + 0xf7, 0x48, 0xf7, 0x24, 0x8b, 0x98, 0xc7, 0xfb, 0x24, 0x8b, 0x96, 0xbf, + 0xf7, 0x24, 0x8b, 0x98, 0xc7, 0x05, 0x0e, 0xf8, 0xef, 0xf8, 0x77, 0x15, + 0xfb, 0x0f, 0x8b, 0x9a, 0xb4, 0x05, 0xa6, 0xd1, 0xac, 0xae, 0xb2, 0x8b, + 0x9b, 0x8b, 0x96, 0x88, 0xa4, 0x7e, 0x08, 0xb7, 0xf7, 0x06, 0x05, 0x63, + 0x98, 0x76, 0x8f, 0x6c, 0x8b, 0x22, 0x8b, 0x44, 0x4c, 0x55, 0xfb, 0x1f, + 0x08, 0x74, 0x50, 0xfb, 0x1e, 0x8b, 0x76, 0x27, 0xf7, 0x0f, 0x8b, 0xfb, + 0x1f, 0xfc, 0x0c, 0x05, 0x6c, 0x38, 0x74, 0x6f, 0x67, 0x8b, 0x7b, 0x8b, + 0x78, 0x93, 0x7a, 0x98, 0x08, 0x5a, 0xfb, 0x07, 0x05, 0xa8, 0x7b, 0xa4, + 0x85, 0xab, 0x8b, 0xbc, 0x8b, 0xbe, 0x9d, 0xae, 0xa9, 0xb5, 0xae, 0xab, + 0xc0, 0xaa, 0xe0, 0x08, 0xf7, 0x20, 0xf8, 0x12, 0xf7, 0x1d, 0x8b, 0xa0, + 0xef, 0x05, 0x0e, 0xf8, 0xe1, 0xf8, 0xb4, 0x15, 0x90, 0xa4, 0x8d, 0x96, + 0x8b, 0x99, 0x8b, 0xdc, 0x4b, 0xbb, 0x20, 0x8b, 0x42, 0x8b, 0x4a, 0x74, + 0x5f, 0x62, 0x62, 0x66, 0x73, 0x58, 0x8b, 0x5c, 0x8b, 0x64, 0x97, 0x6d, + 0xa5, 0x70, 0x56, 0x6a, 0x7d, 0x7f, 0x76, 0x73, 0x08, 0x71, 0x6d, 0x7e, + 0x65, 0x8b, 0x5f, 0x8b, 0x64, 0x9f, 0x67, 0xad, 0x74, 0x08, 0xf7, 0x2a, + 0x27, 0x05, 0xbd, 0x6c, 0x90, 0x85, 0x8b, 0x70, 0x08, 0x61, 0x64, 0x6b, + 0x58, 0x1e, 0x61, 0x74, 0x9e, 0xaf, 0x1f, 0x8b, 0x95, 0x8c, 0x92, 0x8d, + 0x9c, 0x08, 0xfb, 0x17, 0x06, 0x84, 0x71, 0x89, 0x7d, 0x8b, 0x78, 0x8b, + 0x34, 0xcf, 0x54, 0xf7, 0x00, 0x8b, 0xe3, 0x8b, 0xd3, 0xaa, 0xbc, 0xc6, + 0xae, 0xb3, 0x9f, 0xbf, 0x8b, 0xb9, 0x8b, 0xb4, 0x7c, 0xaa, 0x6a, 0xa6, + 0xbb, 0x9d, 0xa0, 0x98, 0xa1, 0xa5, 0x08, 0xa4, 0xa8, 0x99, 0xb5, 0x8b, + 0xbb, 0x8b, 0xbb, 0x76, 0xae, 0x5b, 0xa9, 0x08, 0xfb, 0x04, 0xd1, 0x05, + 0x59, 0xaa, 0x76, 0xa1, 0x8b, 0xa0, 0x08, 0xae, 0xab, 0xa6, 0xb6, 0x1e, + 0xb3, 0xa1, 0x76, 0x65, 0x1f, 0x8b, 0x87, 0x8b, 0x84, 0x8a, 0x84, 0x08, + 0xf7, 0x13, 0x06, 0xfb, 0xdf, 0xfb, 0xbd, 0x15, 0x6e, 0x9c, 0x81, 0x9a, + 0x8b, 0xa1, 0x8b, 0xad, 0x9d, 0xa6, 0xb1, 0x9f, 0x08, 0xf7, 0x13, 0x3f, + 0x05, 0xae, 0x76, 0x96, 0x7d, 0x8b, 0x73, 0x8b, 0x6a, 0x79, 0x75, 0x5c, + 0x75, 0x08, 0xfb, 0x11, 0xd8, 0x05, 0x0e, 0xf8, 0x89, 0xf8, 0xa4, 0x15, + 0x72, 0x9d, 0x66, 0x97, 0x68, 0x8b, 0x64, 0x8b, 0x5e, 0x7f, 0x69, 0x78, + 0x08, 0x4e, 0xd8, 0x38, 0x47, 0xc9, 0x3c, 0x05, 0x69, 0x61, 0x76, 0x54, + 0x8b, 0x59, 0x8b, 0x75, 0x8e, 0x79, 0x93, 0x73, 0x08, 0x2d, 0x3e, 0xc1, + 0x46, 0xe9, 0xd9, 0x05, 0xa0, 0x79, 0xb7, 0x7e, 0xb1, 0x8b, 0xb0, 0x8b, + 0xa2, 0x91, 0xbb, 0xa3, 0x08, 0xc6, 0x40, 0xde, 0xcf, 0x4f, 0xd7, 0x05, + 0xaf, 0xb9, 0x9f, 0xc1, 0x8b, 0xbe, 0x8b, 0x9e, 0x88, 0x9d, 0x84, 0xa2, + 0x08, 0xe6, 0xd6, 0x55, 0xd0, 0x32, 0x42, 0x05, 0xfb, 0x10, 0x47, 0x15, + 0xbd, 0xaf, 0x68, 0x59, 0x43, 0x52, 0x51, 0x44, 0x58, 0x68, 0xae, 0xbd, + 0xd4, 0xc3, 0xc4, 0xd3, 0x1f, 0x0e, 0xfc, 0x45, 0xf7, 0xeb, 0xf9, 0x6d, + 0x15, 0xfb, 0x1e, 0x8b, 0x6f, 0xfb, 0x16, 0x98, 0xfb, 0x15, 0xc2, 0x8b, + 0xd1, 0xf7, 0x15, 0xa7, 0xf7, 0x16, 0x05, 0x0e, 0xfb, 0x3f, 0xf7, 0xc6, + 0xf8, 0x69, 0x15, 0xa6, 0xf7, 0x11, 0x3a, 0x8b, 0x05, 0x94, 0xbd, 0xab, + 0xa8, 0xc5, 0x95, 0x08, 0x95, 0xb9, 0x05, 0x32, 0x84, 0x4b, 0x52, 0x7d, + 0x34, 0x08, 0x74, 0xfb, 0x01, 0xf7, 0x1b, 0x8b, 0x05, 0xf7, 0x77, 0x16, + 0xa6, 0xf7, 0x11, 0x3a, 0x8b, 0x05, 0x94, 0xbd, 0xab, 0xa8, 0xc5, 0x95, + 0x08, 0x95, 0xb9, 0x05, 0x32, 0x84, 0x4b, 0x52, 0x7d, 0x34, 0x08, 0x74, + 0xfb, 0x01, 0xf7, 0x1b, 0x8b, 0x05, 0x0e, 0xf7, 0x1b, 0xf7, 0x6e, 0x15, + 0xf7, 0x1c, 0xfb, 0x26, 0xa3, 0xf7, 0x06, 0x39, 0xe4, 0xf7, 0x0c, 0xe4, + 0xa4, 0xf7, 0x09, 0xfb, 0x5b, 0xfb, 0x29, 0x73, 0xfb, 0x06, 0x05, 0xf7, + 0x69, 0x16, 0xf7, 0x1c, 0xfb, 0x26, 0xa3, 0xf7, 0x06, 0x39, 0xe4, 0xf7, + 0x0c, 0xe4, 0xa4, 0xf7, 0x09, 0xfb, 0x5b, 0xfb, 0x29, 0x73, 0xfb, 0x06, + 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0x14, 0xf7, 0x6e, 0x15, 0xf7, 0x1c, 0xfb, + 0x26, 0xa3, 0xf7, 0x06, 0x39, 0xe4, 0xf7, 0x0c, 0xe4, 0xa4, 0xf7, 0x09, + 0xfb, 0x5b, 0xfb, 0x29, 0x73, 0xfb, 0x06, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, + 0xd3, 0xf7, 0xe3, 0x15, 0xfb, 0x1c, 0xf7, 0x26, 0x73, 0xfb, 0x06, 0xdd, + 0x32, 0xfb, 0x0c, 0x32, 0x72, 0xfb, 0x09, 0xf7, 0x5b, 0xf7, 0x28, 0xa3, + 0xf7, 0x07, 0x05, 0x0e, 0x4f, 0xf9, 0x2b, 0xf8, 0xb0, 0x15, 0xfb, 0x20, + 0x8b, 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0x05, 0xf7, 0x07, 0xf8, + 0xb0, 0x05, 0xb3, 0xf7, 0x51, 0x15, 0xfb, 0x20, 0x8b, 0x70, 0xfb, 0x11, + 0xf7, 0x20, 0x8b, 0xa6, 0xf7, 0x11, 0x05, 0xfb, 0xaf, 0xfb, 0x5c, 0x15, + 0x38, 0x8b, 0x97, 0xc0, 0x05, 0x91, 0xa8, 0x9a, 0x99, 0xa4, 0x8b, 0x95, + 0x8b, 0x90, 0x8a, 0xa6, 0x88, 0x08, 0xa1, 0xf4, 0x05, 0x61, 0x8d, 0x7a, + 0x8c, 0x79, 0x8b, 0x29, 0x8b, 0x56, 0x61, 0x77, 0x2e, 0x08, 0x7d, 0x4a, + 0x3f, 0x8b, 0x77, 0x2e, 0xd8, 0x8b, 0x2e, 0xfc, 0x48, 0xf7, 0x20, 0x8b, + 0xe8, 0xf8, 0x48, 0xdd, 0x8b, 0x05, 0x9f, 0xe8, 0x05, 0x0e, 0x4f, 0xf9, + 0x51, 0xf9, 0x6d, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, + 0x20, 0x8b, 0x05, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0xfb, 0xaa, 0xfb, 0x5c, + 0x15, 0x38, 0x8b, 0x97, 0xc0, 0x05, 0x91, 0xa8, 0x9a, 0x99, 0xa4, 0x8b, + 0x95, 0x8b, 0x90, 0x8a, 0xa6, 0x88, 0x08, 0xa1, 0xf4, 0x05, 0x61, 0x8d, + 0x7a, 0x8c, 0x79, 0x8b, 0x29, 0x8b, 0x56, 0x61, 0x77, 0x2e, 0x08, 0x7d, + 0x4a, 0x3f, 0x8b, 0x77, 0x2e, 0xd8, 0x8b, 0x2e, 0xfc, 0x48, 0xf7, 0x20, + 0x8b, 0xe8, 0xf8, 0x48, 0xdd, 0x8b, 0x9f, 0xe8, 0x05, 0x0e, 0xf9, 0x04, + 0xf7, 0xcb, 0x15, 0xfc, 0xcb, 0x8b, 0x75, 0x23, 0xf8, 0xcb, 0x8b, 0xa1, + 0xf3, 0x05, 0x0e, 0xf9, 0x06, 0xf8, 0x79, 0x15, 0xfb, 0x47, 0x8b, 0xba, + 0xf7, 0x74, 0xfb, 0x19, 0x8b, 0x5b, 0xfb, 0x74, 0xfb, 0x47, 0x8b, 0x72, + 0xfb, 0x08, 0xf7, 0x47, 0x8b, 0xfb, 0x0b, 0xfc, 0xc7, 0xf7, 0x1a, 0x8b, + 0xf7, 0x0b, 0xf8, 0xc7, 0xf7, 0x47, 0x8b, 0xa4, 0xf7, 0x08, 0x05, 0x0e, + 0xf9, 0x03, 0xf8, 0x79, 0x15, 0xfb, 0x47, 0x8b, 0xbb, 0xf7, 0x74, 0xfb, + 0x1a, 0x8b, 0x5b, 0xfb, 0x74, 0xfb, 0x46, 0x8b, 0x72, 0xfb, 0x08, 0xf7, + 0x47, 0x8b, 0x5b, 0xfb, 0x73, 0xfb, 0x46, 0x8b, 0x72, 0xfb, 0x08, 0xf7, + 0x47, 0x8b, 0x5b, 0xfb, 0x74, 0xf7, 0x1a, 0x8b, 0xbb, 0xf7, 0x74, 0xf7, + 0x46, 0x8b, 0x05, 0xa4, 0xf7, 0x08, 0xfb, 0x47, 0x8b, 0xbb, 0xf7, 0x73, + 0xf7, 0x46, 0x8b, 0xa4, 0xf7, 0x08, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0xa2, + 0xf7, 0xae, 0x15, 0x22, 0x8b, 0x75, 0x27, 0xf4, 0x8b, 0xa1, 0xef, 0x05, + 0x0e, 0xf9, 0x40, 0xf9, 0x6d, 0x15, 0xfb, 0xc2, 0x06, 0x4a, 0x8b, 0x52, + 0x71, 0x59, 0x55, 0x52, 0x4e, 0x6b, 0x3f, 0x8b, 0x3e, 0x8b, 0x29, 0xca, + 0x4a, 0xef, 0x86, 0x08, 0x2a, 0xfc, 0x5e, 0xed, 0x8b, 0xf7, 0x48, 0xf9, + 0xe3, 0xc9, 0x8b, 0xfb, 0x48, 0xfd, 0xe3, 0xed, 0x8b, 0xf7, 0x48, 0xf9, + 0xe3, 0xb7, 0x8b, 0x9a, 0xd4, 0x05, 0x0e, 0xfb, 0xd5, 0xf7, 0x96, 0xf8, + 0x3d, 0x15, 0x3e, 0x45, 0x46, 0x3e, 0x4f, 0xb8, 0x5f, 0xc8, 0xd9, 0xd3, + 0xd2, 0xd6, 0xc6, 0x5c, 0xb8, 0x4d, 0x1f, 0x0e, 0xfc, 0x1d, 0xe7, 0xf7, + 0x11, 0x15, 0x70, 0xfb, 0x11, 0xdc, 0x8b, 0x05, 0x82, 0x59, 0x6b, 0x6e, + 0x51, 0x81, 0x08, 0x81, 0x5d, 0x05, 0xe9, 0x92, 0xc9, 0xc3, 0x97, 0xe3, + 0x08, 0xa2, 0xf7, 0x01, 0xfb, 0x1c, 0x8b, 0x05, 0x0e, 0xfb, 0x3f, 0xe7, + 0xf7, 0x11, 0x15, 0x70, 0xfb, 0x11, 0xdc, 0x8b, 0x05, 0x82, 0x59, 0x6b, + 0x6e, 0x51, 0x81, 0x08, 0x81, 0x5d, 0x05, 0xe4, 0x92, 0xcb, 0xc4, 0x99, + 0xe2, 0x08, 0xa2, 0xf7, 0x01, 0xfb, 0x1b, 0x8b, 0x05, 0xf7, 0x7f, 0x16, + 0x70, 0xfb, 0x11, 0xdc, 0x8b, 0x05, 0x82, 0x59, 0x6b, 0x6e, 0x51, 0x81, + 0x08, 0x81, 0x5d, 0x05, 0xe4, 0x92, 0xcb, 0xc4, 0x99, 0xe2, 0x08, 0xa2, + 0xf7, 0x01, 0xfb, 0x1b, 0x8b, 0x05, 0x0e, 0xfb, 0x3f, 0xf7, 0x78, 0xf9, + 0x6d, 0x15, 0x70, 0xfb, 0x11, 0xdc, 0x8b, 0x05, 0x82, 0x59, 0x6b, 0x6e, + 0x51, 0x81, 0x08, 0x81, 0x5d, 0x05, 0xe4, 0x92, 0xcb, 0xc4, 0x99, 0xe2, + 0x08, 0xa2, 0xf7, 0x01, 0xfb, 0x1b, 0x8b, 0x05, 0xf7, 0x7c, 0x16, 0x70, + 0xfb, 0x11, 0xdc, 0x8b, 0x05, 0x82, 0x59, 0x6b, 0x6e, 0x51, 0x81, 0x08, + 0x81, 0x5d, 0x05, 0xe4, 0x92, 0xcb, 0xc4, 0x99, 0xe2, 0x08, 0xa2, 0xf7, + 0x01, 0xfb, 0x1b, 0x8b, 0x05, 0x0e, 0xf7, 0xda, 0xf7, 0xe3, 0x15, 0xfb, + 0x1c, 0xf7, 0x26, 0x73, 0xfb, 0x06, 0xdd, 0x32, 0xfb, 0x0c, 0x32, 0x72, + 0xfb, 0x09, 0xf7, 0x5b, 0xf7, 0x28, 0xa3, 0xf7, 0x07, 0x05, 0xf7, 0x63, + 0x16, 0xfb, 0x1c, 0xf7, 0x26, 0x73, 0xfb, 0x06, 0xdd, 0x32, 0xfb, 0x0c, + 0x32, 0x72, 0xfb, 0x09, 0xf7, 0x5b, 0xf7, 0x28, 0xa3, 0xf7, 0x07, 0x05, + 0x0e, 0xf7, 0xdd, 0xf7, 0xa5, 0xf7, 0x26, 0x15, 0xfb, 0x2a, 0x8b, 0x6c, + 0xfb, 0x26, 0xf7, 0x2a, 0x8b, 0xaa, 0xf7, 0x26, 0x05, 0xf7, 0xe1, 0x16, + 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0xf7, 0x2a, 0x8b, 0xaa, 0xf7, 0x26, + 0x05, 0xf7, 0xe1, 0x16, 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0xf7, 0x2a, + 0x8b, 0xaa, 0xf7, 0x26, 0x05, 0x0e, 0xf7, 0xdd, 0xf9, 0x22, 0xf9, 0x76, + 0x15, 0xfc, 0xda, 0xfd, 0x8b, 0xcd, 0x8b, 0xf8, 0xdb, 0xf9, 0x8b, 0x05, + 0x48, 0x06, 0xfb, 0xe6, 0x8c, 0x15, 0x2d, 0x33, 0x35, 0x2e, 0x48, 0xc0, + 0x59, 0xd1, 0xeb, 0xe2, 0xe0, 0xe9, 0xcf, 0x57, 0xbc, 0x43, 0x1f, 0x7a, + 0x3d, 0x15, 0xae, 0xa5, 0x73, 0x6a, 0x60, 0x62, 0x63, 0x5f, 0x68, 0x71, + 0xa3, 0xa9, 0xb8, 0xb4, 0xb4, 0xb7, 0x1f, 0xf7, 0x79, 0xfc, 0x15, 0x15, + 0x2d, 0x34, 0x35, 0x2e, 0x48, 0xbf, 0x59, 0xd1, 0xeb, 0xe2, 0xe1, 0xe8, + 0xcf, 0x57, 0xbc, 0x43, 0x1f, 0x7b, 0x3d, 0x15, 0xad, 0xa5, 0x73, 0x6a, + 0x60, 0x62, 0x63, 0x5f, 0x69, 0x71, 0xa3, 0xa9, 0xb8, 0xb4, 0xb4, 0xb7, + 0x1f, 0xf8, 0x15, 0xd9, 0x15, 0x2d, 0x34, 0x35, 0x2e, 0x48, 0xbf, 0x59, + 0xd1, 0xeb, 0xe2, 0xe1, 0xe8, 0xcf, 0x57, 0xbc, 0x43, 0x1f, 0x7b, 0x3d, + 0x15, 0xad, 0xa5, 0x73, 0x6a, 0x60, 0x62, 0x63, 0x5f, 0x69, 0x71, 0xa3, + 0xa9, 0xb8, 0xb4, 0xb4, 0xb7, 0x1f, 0x0e, 0x4f, 0xf7, 0xca, 0xf7, 0xe7, + 0x15, 0x7d, 0x49, 0x82, 0x7f, 0x47, 0x62, 0x43, 0x5e, 0x67, 0x6c, 0x75, + 0x67, 0x74, 0x64, 0x7d, 0x58, 0x8b, 0x5f, 0x8b, 0xfb, 0x01, 0xde, 0x46, + 0xf7, 0x19, 0x8b, 0xdf, 0x8b, 0xd2, 0xa9, 0xc0, 0xc4, 0xb2, 0xb6, 0xa1, + 0xbc, 0x9e, 0xdf, 0x08, 0xfb, 0x1c, 0x06, 0x7b, 0x34, 0x59, 0x57, 0x48, + 0x8b, 0x55, 0x8b, 0x65, 0xaf, 0x8b, 0xbe, 0x8b, 0x9f, 0x91, 0xa0, 0x95, + 0x9e, 0x9a, 0xa5, 0x95, 0x94, 0xc3, 0xb2, 0xe9, 0xcd, 0xb2, 0xc2, 0x92, + 0xd8, 0x08, 0xfb, 0x0e, 0x06, 0x87, 0xc2, 0x15, 0xf7, 0x2a, 0x8b, 0xaa, + 0xf7, 0x26, 0xfb, 0x2a, 0x8b, 0x6c, 0xfb, 0x26, 0x05, 0x0e, 0xfb, 0xe6, + 0xf7, 0x43, 0xf9, 0x89, 0x15, 0xf0, 0xfb, 0x2a, 0xca, 0x8b, 0x5e, 0xf7, + 0x2a, 0xfb, 0x0b, 0x8b, 0x05, 0x0e, 0xfb, 0xe6, 0xf8, 0x6f, 0xf9, 0x89, + 0x15, 0xfb, 0x12, 0x8b, 0x25, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x32, 0xf7, + 0x2a, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0xa6, 0xf9, 0x89, 0x15, 0xfb, 0x1f, + 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, 0xd9, 0x8b, 0x44, 0xf7, + 0x27, 0xfb, 0x00, 0x8b, 0x05, 0x0e, 0xfb, 0xe6, 0xf8, 0x52, 0xf9, 0x7c, + 0x15, 0x7d, 0x69, 0x7a, 0x7a, 0x74, 0x8b, 0x7f, 0x8b, 0x89, 0x8c, 0x78, + 0x94, 0x08, 0x59, 0xa0, 0x05, 0x6b, 0x99, 0x7d, 0x8e, 0x72, 0x8b, 0x55, + 0x8b, 0x5f, 0x61, 0x74, 0x40, 0x08, 0xc1, 0x06, 0x9c, 0xac, 0x9b, 0x9a, + 0x9d, 0x8b, 0x93, 0x8b, 0xa0, 0x84, 0x9a, 0x84, 0x08, 0xbd, 0x72, 0x05, + 0x98, 0x85, 0xa0, 0x86, 0x9c, 0x8b, 0xab, 0x8b, 0xae, 0x9a, 0xa4, 0xa5, + 0x9e, 0x9f, 0x96, 0xa1, 0x96, 0xb2, 0x08, 0x55, 0x06, 0x0e, 0xfb, 0xe6, + 0xf8, 0x67, 0xf9, 0x66, 0x15, 0xfb, 0xc0, 0x8b, 0x7a, 0x3b, 0xf7, 0xc0, + 0x8b, 0x9c, 0xdb, 0x05, 0x0e, 0xfb, 0xe6, 0xf8, 0x31, 0xf9, 0x86, 0x15, + 0x7a, 0x60, 0x68, 0x75, 0x58, 0x8b, 0x08, 0x5c, 0x70, 0xa0, 0xaf, 0x1f, + 0x93, 0x61, 0x07, 0x86, 0x79, 0x8a, 0x82, 0x8b, 0x7f, 0x8b, 0x4d, 0xb6, + 0x61, 0xca, 0x8b, 0xda, 0x8b, 0xcf, 0xc8, 0x99, 0xdd, 0x08, 0x61, 0x06, + 0x0e, 0xfb, 0xe6, 0xf8, 0x0d, 0xf9, 0x79, 0x15, 0xfb, 0x02, 0x8b, 0x71, + 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0x0e, 0xfb, 0xe6, + 0xf7, 0xaf, 0xf9, 0x79, 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, + 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, + 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0x0e, 0xfb, + 0xe6, 0xf7, 0xda, 0xf9, 0x99, 0x15, 0x51, 0x55, 0x57, 0x52, 0x62, 0xa9, + 0x6d, 0xb5, 0xc5, 0xc1, 0xbf, 0xc4, 0xb4, 0x6d, 0xa9, 0x61, 0x1f, 0x81, + 0x59, 0x15, 0x9e, 0x99, 0x7e, 0x79, 0x72, 0x72, 0x73, 0x70, 0x77, 0x7d, + 0x99, 0x9d, 0xa4, 0xa5, 0xa2, 0xa6, 0x1f, 0x0e, 0xfb, 0xe6, 0xf7, 0x2e, + 0x16, 0x47, 0x21, 0x05, 0xa3, 0x95, 0x97, 0x8e, 0x9c, 0x8b, 0x08, 0xa5, + 0x9d, 0x7e, 0x77, 0x73, 0x6d, 0x77, 0x65, 0x1f, 0x6f, 0x8b, 0x74, 0x92, + 0x5c, 0xa2, 0x08, 0x6d, 0x58, 0x05, 0xc3, 0x75, 0xab, 0x84, 0xb8, 0x8b, + 0x08, 0xe5, 0xc7, 0xb5, 0xcc, 0xaf, 0x73, 0xa0, 0x63, 0x1f, 0x7c, 0x8b, + 0x7f, 0x89, 0x7b, 0x87, 0x08, 0xb4, 0xc9, 0x59, 0x8b, 0x05, 0x0e, 0xfb, + 0xe6, 0xf7, 0xca, 0xf9, 0x89, 0x15, 0xfb, 0x12, 0x8b, 0x25, 0xfb, 0x27, + 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x27, 0x05, 0xf7, 0x50, 0x16, 0xfb, 0x12, + 0x8b, 0x25, 0xfb, 0x27, 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x27, 0x05, 0x0e, + 0xfb, 0xe6, 0xf7, 0x42, 0x16, 0x62, 0x7a, 0x78, 0x82, 0x73, 0x7a, 0x61, + 0x6e, 0x72, 0x60, 0x8b, 0x61, 0x8b, 0x5c, 0xbe, 0x6e, 0xde, 0x8b, 0xa3, + 0x8b, 0xa0, 0x8e, 0xab, 0x91, 0x08, 0x95, 0xbf, 0x05, 0x77, 0x84, 0x72, + 0x87, 0x71, 0x8b, 0x6a, 0x8b, 0x7a, 0x99, 0x8b, 0xa5, 0x8b, 0xa2, 0x96, + 0xa4, 0xa2, 0xa8, 0x9e, 0xa3, 0x91, 0x8f, 0xcd, 0xb1, 0x08, 0x41, 0x06, + 0x0e, 0xfb, 0xe6, 0xf7, 0xee, 0xf8, 0xf6, 0x15, 0xf7, 0x1f, 0xf7, 0x27, + 0x3f, 0x8b, 0x24, 0x2a, 0x4e, 0xec, 0x3d, 0x8b, 0xd2, 0xfb, 0x27, 0xf7, + 0x00, 0x8b, 0x05, 0x0e, 0xf7, 0xdd, 0xfa, 0xc2, 0xf7, 0xcb, 0x15, 0xfe, + 0x87, 0x8b, 0x75, 0x23, 0xfa, 0x87, 0x8b, 0xa1, 0xf3, 0x05, 0x0e, 0xf7, + 0xdd, 0xf8, 0x64, 0xf7, 0x2c, 0x15, 0x6b, 0xfb, 0x2c, 0xf8, 0xac, 0x8b, + 0xa6, 0xf7, 0x11, 0xfc, 0x16, 0x8b, 0xb3, 0xf7, 0x51, 0xf7, 0xe7, 0x8b, + 0xa5, 0xf7, 0x11, 0xfb, 0xe7, 0x8b, 0xaf, 0xf7, 0x39, 0xf8, 0x03, 0x8b, + 0xa5, 0xf7, 0x11, 0xfd, 0x3f, 0x8b, 0xfc, 0x38, 0xfd, 0x6d, 0xf7, 0x33, + 0x8b, 0xe0, 0xf7, 0x2c, 0x05, 0xf7, 0x6f, 0x06, 0xa6, 0xf7, 0x11, 0x15, + 0xfb, 0x49, 0x8b, 0xf7, 0x4d, 0xf7, 0xdb, 0xcd, 0x8b, 0x45, 0xfb, 0xdb, + 0x05, 0x0e, 0xfb, 0xc1, 0xf8, 0x20, 0xf7, 0xea, 0x15, 0xfb, 0xaf, 0x8b, + 0x7a, 0x3b, 0xf7, 0xb0, 0x8b, 0x05, 0x9b, 0xdb, 0x05, 0xa3, 0xce, 0x15, + 0x83, 0x95, 0x87, 0x94, 0x8b, 0x93, 0x8b, 0x90, 0x8b, 0x8e, 0x8c, 0x90, + 0x08, 0xb2, 0xf7, 0x48, 0x05, 0x8d, 0x96, 0x8c, 0x94, 0x8b, 0x93, 0x8b, + 0xb8, 0x60, 0xa6, 0x44, 0x8b, 0x31, 0x8b, 0x55, 0x66, 0x7a, 0x40, 0x08, + 0xda, 0x06, 0x95, 0xab, 0x9e, 0x97, 0xb1, 0x8b, 0xaa, 0x8b, 0x98, 0x83, + 0x8b, 0x7a, 0x8b, 0x7e, 0x83, 0x7e, 0x7f, 0x85, 0x7e, 0x85, 0x8b, 0x8b, + 0x60, 0x85, 0x08, 0x69, 0x85, 0x05, 0x41, 0x80, 0x5b, 0x5a, 0x8b, 0x4c, + 0x8b, 0x5b, 0xab, 0x6d, 0xbe, 0x8b, 0xb3, 0x8b, 0xaa, 0x99, 0xaf, 0xab, + 0x08, 0x89, 0x81, 0x8b, 0x89, 0x8b, 0x87, 0x8b, 0x85, 0x8c, 0x87, 0x8e, + 0x85, 0x08, 0xe7, 0x8b, 0x8d, 0x95, 0x05, 0x3f, 0xf7, 0x0c, 0x15, 0x81, + 0x5b, 0x6d, 0x6f, 0x62, 0x8b, 0x70, 0x8b, 0x7c, 0x96, 0x8b, 0x9e, 0x8b, + 0xa7, 0xa1, 0x9f, 0xb1, 0x91, 0x08, 0xa9, 0x91, 0x95, 0x8c, 0x05, 0x91, + 0x8c, 0x8f, 0x8c, 0x8d, 0x8b, 0x92, 0x8d, 0x8d, 0x8c, 0x92, 0x8e, 0x08, + 0x86, 0x74, 0x05, 0x0e, 0x4f, 0xf7, 0xe6, 0xf8, 0x39, 0x15, 0xcc, 0xf7, + 0xc8, 0xfb, 0x2a, 0x8b, 0x3c, 0xfc, 0x09, 0x27, 0x4e, 0x77, 0x2d, 0xef, + 0xc8, 0x53, 0xfb, 0x9a, 0xf8, 0x87, 0x8b, 0xa6, 0xf7, 0x11, 0xfb, 0xf1, + 0x8b, 0xb6, 0xf7, 0x5e, 0xf7, 0x4f, 0xf7, 0x02, 0x9f, 0xe9, 0xfb, 0x4f, + 0xfb, 0x02, 0x05, 0x0e, 0xf6, 0xf7, 0x49, 0xc3, 0x15, 0xba, 0x57, 0xd5, + 0x70, 0xe8, 0x8b, 0xf7, 0x10, 0x8b, 0xf5, 0xbd, 0xdd, 0xeb, 0xd9, 0xe7, + 0xba, 0xf7, 0x10, 0x8b, 0xf7, 0x05, 0x8b, 0xc5, 0x80, 0xbd, 0x74, 0xba, + 0x08, 0xf7, 0x00, 0xec, 0x61, 0xb8, 0x26, 0x31, 0x05, 0x59, 0xc2, 0x43, + 0xa6, 0x2d, 0x8b, 0xfb, 0x11, 0x8b, 0x22, 0x5a, 0x38, 0x2a, 0x3e, 0x2f, + 0x5b, 0xfb, 0x12, 0x8b, 0xfb, 0x06, 0x8b, 0x50, 0x98, 0x55, 0xa2, 0x5f, + 0x08, 0xfb, 0x03, 0x28, 0xb4, 0x5d, 0x05, 0xf5, 0xea, 0x05, 0xf8, 0x85, + 0xf8, 0x50, 0x15, 0x8f, 0x75, 0x8c, 0x79, 0x8b, 0x76, 0x8b, 0x3a, 0x70, + 0x34, 0x5e, 0x4e, 0x59, 0x45, 0x4b, 0x68, 0x3f, 0x8b, 0x55, 0x8b, 0x5f, + 0x9d, 0x6e, 0xad, 0x08, 0xf8, 0x14, 0xf7, 0xeb, 0x05, 0xfc, 0x32, 0xfb, + 0xb3, 0x15, 0x87, 0xa1, 0x89, 0xa2, 0x8b, 0xa2, 0x8b, 0xd9, 0xa7, 0xe4, + 0xb7, 0xc8, 0xbc, 0xcf, 0xcd, 0xaf, 0xd7, 0x8b, 0xc3, 0x8b, 0xb6, 0x78, + 0xa9, 0x66, 0x08, 0xfc, 0x16, 0xfb, 0xec, 0x05, 0x0e, 0xf7, 0xdd, 0xf9, + 0x48, 0xf7, 0xce, 0x15, 0xf7, 0xbe, 0x8b, 0xa6, 0xf7, 0x11, 0xfb, 0xbe, + 0x8b, 0xae, 0xf7, 0x39, 0xf7, 0xda, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, 0x6b, + 0x8b, 0x80, 0x57, 0x05, 0x66, 0xb9, 0x63, 0x9d, 0x49, 0x8b, 0x2d, 0x8b, + 0x36, 0x62, 0x42, 0x3a, 0x37, 0x2f, 0x53, 0xfb, 0x2a, 0x8b, 0xfb, 0x18, + 0x8b, 0xfb, 0x35, 0xea, 0x20, 0xf7, 0x21, 0x8b, 0xce, 0x8b, 0xb7, 0xa1, + 0xc3, 0xc7, 0x08, 0x7f, 0x50, 0xf8, 0x7e, 0x8b, 0xa5, 0xf7, 0x11, 0xfb, + 0xed, 0x8b, 0x05, 0xb3, 0xf7, 0x51, 0x05, 0xfb, 0x47, 0xfb, 0x1c, 0x15, + 0x64, 0x57, 0x65, 0x76, 0x56, 0x8b, 0x30, 0x8b, 0x56, 0xca, 0x8b, 0xf5, + 0x8b, 0xd1, 0x9f, 0xd7, 0xad, 0xc9, 0xba, 0xe1, 0xcb, 0xb8, 0xd9, 0x8b, + 0xc3, 0x8b, 0xac, 0x75, 0x9e, 0x58, 0x08, 0x3e, 0xfb, 0xfe, 0x05, 0x0e, + 0xfb, 0xc6, 0xf8, 0x2e, 0xf7, 0xea, 0x15, 0xfb, 0xc1, 0x8b, 0x7a, 0x3b, + 0xf7, 0xc1, 0x8b, 0x9c, 0xdb, 0x05, 0x44, 0xf8, 0x17, 0x15, 0x4e, 0x8b, + 0x54, 0x70, 0x68, 0x5c, 0x6e, 0x65, 0x78, 0x50, 0x8b, 0x57, 0x8b, 0x41, + 0xbd, 0x5d, 0xda, 0x8b, 0xcb, 0x8b, 0xc0, 0xa4, 0xb0, 0xbc, 0xa8, 0xb0, + 0x9e, 0xc8, 0x8b, 0xbf, 0x8b, 0xd5, 0x59, 0xb8, 0x39, 0x8b, 0x08, 0x7e, + 0x47, 0x15, 0xae, 0xa2, 0x6f, 0x60, 0x3f, 0x5e, 0x4a, 0x55, 0x68, 0x74, + 0xa7, 0xb6, 0xd8, 0xb8, 0xcb, 0xc1, 0x1f, 0x0e, 0xf7, 0x6e, 0xf9, 0x82, + 0xf7, 0x2c, 0x15, 0x77, 0x65, 0x5e, 0x72, 0x5a, 0x8b, 0x52, 0x8b, 0x64, + 0xae, 0x8b, 0xbe, 0x8b, 0x99, 0x8c, 0x96, 0x91, 0xa5, 0x08, 0xf7, 0xfe, + 0x06, 0x97, 0xb8, 0x91, 0xb5, 0x8b, 0xb1, 0x8b, 0xb9, 0x7a, 0xbb, 0x6e, + 0xae, 0x67, 0xb8, 0x53, 0xa3, 0x44, 0x8b, 0x50, 0x8b, 0x4f, 0x79, 0x5d, + 0x6c, 0x6b, 0xac, 0x57, 0x9b, 0x3e, 0x8b, 0x31, 0x8b, 0x45, 0x76, 0x5e, + 0x63, 0x08, 0x6a, 0x6e, 0x7a, 0x69, 0x7e, 0x4c, 0x08, 0xf7, 0x17, 0x06, + 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, 0x8b, 0xbe, 0x8b, 0xa1, 0x7e, 0x8b, 0x6d, + 0x8b, 0x76, 0x7d, 0x75, 0x77, 0x81, 0x76, 0x80, 0x8b, 0x8b, 0x43, 0x81, + 0x08, 0x52, 0x82, 0x05, 0x5b, 0x83, 0x66, 0x7d, 0x6b, 0x74, 0x56, 0x65, + 0x6b, 0x4f, 0x8b, 0x4d, 0x8b, 0x3a, 0xc5, 0x5b, 0xec, 0x8b, 0xe7, 0x8b, + 0xc1, 0xa4, 0xd1, 0xd6, 0xa7, 0x4b, 0xcc, 0x67, 0xe3, 0x8b, 0xf7, 0x0c, + 0x8b, 0xf7, 0x01, 0xcf, 0xc0, 0xf6, 0x08, 0xfb, 0x1e, 0x06, 0xfb, 0xee, + 0xcb, 0x15, 0x79, 0x39, 0x5b, 0x5e, 0x45, 0x8b, 0x5d, 0x8b, 0x72, 0x9c, + 0x8b, 0xac, 0x8b, 0xba, 0xb0, 0xac, 0xcc, 0x96, 0x08, 0xbd, 0x93, 0x9b, + 0x8e, 0x05, 0x95, 0x8c, 0x92, 0x8d, 0x8f, 0x8b, 0x96, 0x8e, 0x8e, 0x8c, + 0x97, 0x91, 0x08, 0x83, 0x65, 0x05, 0xf8, 0x10, 0xf2, 0x15, 0xfb, 0x6c, + 0x06, 0xa0, 0xd8, 0xb9, 0xb4, 0xcb, 0x8b, 0x08, 0xc1, 0xaa, 0x6a, 0x51, + 0x1f, 0x70, 0x07, 0x0e, 0xfc, 0x1d, 0xf7, 0xd6, 0xf8, 0xb0, 0x15, 0xfb, + 0x20, 0x8b, 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0xf7, 0x07, 0xf8, + 0xb0, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0xbc, 0xf8, 0x47, 0x15, 0xca, 0xf7, + 0xba, 0xfb, 0x20, 0x8b, 0x3f, 0xfb, 0xf5, 0x3f, 0x5c, 0x7a, 0x38, 0xd7, + 0xbb, 0x4d, 0xfb, 0xba, 0xf7, 0x20, 0x8b, 0xd6, 0xf7, 0xf5, 0xd7, 0xb8, + 0x9c, 0xdd, 0x3f, 0x5e, 0x05, 0x0e, 0x4f, 0xf7, 0x1b, 0xaf, 0x15, 0xb3, + 0x65, 0xc5, 0x76, 0xd2, 0x8b, 0xf1, 0x8b, 0xe5, 0xb7, 0xc7, 0xda, 0xba, + 0xc8, 0xac, 0xf1, 0x8b, 0xdc, 0x8b, 0xae, 0x85, 0xab, 0x7f, 0xa8, 0x08, + 0xe6, 0xd7, 0x69, 0xb4, 0x36, 0x44, 0x05, 0x64, 0xb4, 0x4e, 0xa1, 0x42, + 0x8b, 0x24, 0x8b, 0x31, 0x5f, 0x4f, 0x3c, 0x5b, 0x4c, 0x6b, 0x27, 0x8b, + 0x36, 0x8b, 0x68, 0x92, 0x6a, 0x99, 0x6d, 0x08, 0x2e, 0x3d, 0xad, 0x63, + 0x05, 0xe4, 0xd5, 0x05, 0xf7, 0xfa, 0xf7, 0xc0, 0x15, 0x8c, 0x84, 0x8b, + 0x86, 0x8b, 0x88, 0x8b, 0x65, 0x82, 0x5f, 0x7b, 0x67, 0x6d, 0x43, 0x57, + 0x61, 0x50, 0x8b, 0x69, 0x8b, 0x6c, 0x9a, 0x7a, 0xa4, 0x08, 0xf7, 0x8b, + 0xf7, 0x63, 0x05, 0xfb, 0x9d, 0xfb, 0x2d, 0x15, 0x8a, 0x96, 0x8b, 0x90, + 0x8b, 0x94, 0x8b, 0xb8, 0x9a, 0xc3, 0xa2, 0xb4, 0xaa, 0xc3, 0xb9, 0xaa, + 0xc0, 0x8b, 0xae, 0x8b, 0xa9, 0x7b, 0x9d, 0x6e, 0x08, 0xfb, 0x8e, 0xfb, + 0x65, 0x05, 0x0e, 0xf7, 0xa5, 0xf9, 0xbd, 0xf7, 0x2c, 0x15, 0x77, 0x65, + 0x5e, 0x72, 0x5a, 0x8b, 0x52, 0x8b, 0x64, 0xae, 0x8b, 0xbd, 0x8b, 0x99, + 0x8c, 0x97, 0x91, 0xa5, 0x08, 0xf7, 0xfe, 0x06, 0x97, 0xb8, 0x91, 0xb5, + 0x8b, 0xb1, 0x8b, 0xb9, 0x7a, 0xba, 0x6f, 0xaf, 0x67, 0xb8, 0x52, 0xa3, + 0x45, 0x8b, 0x40, 0x8b, 0x41, 0x70, 0x5d, 0x5e, 0x69, 0xb8, 0x48, 0xa6, + 0x3c, 0x8b, 0x25, 0x8b, 0x31, 0x5f, 0x4f, 0x3c, 0x08, 0x5b, 0x4c, 0x6b, + 0x27, 0x8b, 0x34, 0x8b, 0xfb, 0x0f, 0xde, 0x3f, 0xf7, 0x1a, 0x8b, 0xdc, + 0x8b, 0xd8, 0xa6, 0xbf, 0xb9, 0xa7, 0x5f, 0xcd, 0x6e, 0xd5, 0x8b, 0xf7, + 0x0b, 0x8b, 0xf7, 0x01, 0xcf, 0xc0, 0xf6, 0x08, 0xfb, 0x1e, 0x06, 0xfc, + 0x41, 0xf7, 0xb1, 0x15, 0xc8, 0xb2, 0x5d, 0x44, 0x1f, 0x8b, 0x5a, 0x7d, + 0x56, 0x73, 0x61, 0x6c, 0x53, 0x5d, 0x6c, 0x57, 0x8b, 0x08, 0x4f, 0x64, + 0xb9, 0xd1, 0xf7, 0x13, 0xd7, 0xf4, 0xe5, 0x1f, 0xf8, 0x63, 0xfb, 0x0a, + 0x15, 0xfb, 0x6c, 0x06, 0xa0, 0xd8, 0xb9, 0xb4, 0xcb, 0x8b, 0x08, 0xc1, + 0xaa, 0x6a, 0x52, 0x1f, 0x6f, 0x07, 0x0e, 0x4f, 0xf7, 0xfb, 0xf7, 0xf1, + 0x15, 0x9a, 0x06, 0xd6, 0xb1, 0x6a, 0x4a, 0x1f, 0x8b, 0x5f, 0x77, 0x5f, + 0x69, 0x6d, 0x6c, 0x70, 0x6f, 0x82, 0x54, 0x8a, 0x08, 0x7d, 0x8b, 0x73, + 0xfb, 0x04, 0x05, 0xab, 0x86, 0x9b, 0x89, 0x9f, 0x8b, 0xe5, 0x8b, 0xdb, + 0xb8, 0xc2, 0xdc, 0xac, 0xbd, 0xa2, 0xd1, 0x8b, 0xc1, 0x8b, 0xd2, 0x67, + 0xbc, 0x4d, 0x99, 0x08, 0xd5, 0xa5, 0xbb, 0xce, 0x8b, 0xd9, 0x8b, 0xe3, + 0x3b, 0xc6, 0xfb, 0x0e, 0x8b, 0xfb, 0x20, 0x8b, 0x23, 0x48, 0x75, 0x23, + 0x08, 0xfb, 0x0b, 0xfc, 0xc2, 0xf7, 0x20, 0x8b, 0xf7, 0x06, 0xf8, 0xad, + 0x05, 0x96, 0xc0, 0xae, 0xa6, 0xc2, 0x8b, 0xc2, 0x8b, 0xad, 0x73, 0x8b, + 0x62, 0x8b, 0x6d, 0x7b, 0x6b, 0x73, 0x78, 0x75, 0x79, 0x6e, 0x82, 0x62, + 0x8b, 0x08, 0x77, 0x2c, 0x05, 0x0e, 0xbe, 0xf8, 0xa8, 0xf7, 0x27, 0x15, + 0x9d, 0xfb, 0x27, 0xf7, 0x2d, 0x8b, 0x2a, 0xf9, 0x6d, 0xfb, 0x41, 0x8b, + 0xfc, 0x2b, 0xfd, 0x6d, 0xf7, 0x2d, 0x8b, 0xdc, 0xf7, 0x27, 0xf7, 0xa4, + 0x8b, 0x05, 0x7d, 0xf7, 0x11, 0x15, 0xfb, 0x51, 0x8b, 0xf7, 0x2e, 0xf7, + 0xaf, 0xae, 0xfb, 0xaf, 0x05, 0x8f, 0xf9, 0x1c, 0x15, 0xfb, 0x02, 0x8b, + 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xf7, 0x4e, + 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, + 0x0c, 0x05, 0x0e, 0xbe, 0xf8, 0xa8, 0xf7, 0x27, 0x15, 0x9d, 0xfb, 0x27, + 0xf7, 0x2d, 0x8b, 0x2a, 0xf9, 0x6d, 0xfb, 0x41, 0x8b, 0xfc, 0x2b, 0xfd, + 0x6d, 0xf7, 0x2d, 0x8b, 0xdc, 0xf7, 0x27, 0xf7, 0xa4, 0x8b, 0x05, 0x7d, + 0xf7, 0x11, 0x15, 0xfb, 0x51, 0x8b, 0xf7, 0x2e, 0xf7, 0xaf, 0xae, 0xfb, + 0xaf, 0x05, 0xf7, 0x58, 0xf9, 0x2c, 0x15, 0xfb, 0x12, 0x8b, 0x25, 0xfb, + 0x2a, 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x2a, 0x05, 0x0e, 0xbe, 0xf8, 0xa8, + 0xf7, 0x27, 0x15, 0x9d, 0xfb, 0x27, 0xf7, 0x2d, 0x8b, 0x2a, 0xf9, 0x6d, + 0xfb, 0x41, 0x8b, 0xfc, 0x2b, 0xfd, 0x6d, 0xf7, 0x2d, 0x8b, 0xdc, 0xf7, + 0x27, 0xf7, 0xa4, 0x8b, 0x05, 0x7d, 0xf7, 0x11, 0x15, 0xfb, 0x51, 0x8b, + 0xf7, 0x2e, 0xf7, 0xaf, 0xae, 0xfb, 0xaf, 0x05, 0xfb, 0x03, 0xf9, 0x2c, + 0x15, 0xf0, 0xfb, 0x2a, 0xca, 0x8b, 0x5e, 0xf7, 0x2a, 0xfb, 0x0b, 0x8b, + 0x05, 0x0e, 0xbe, 0xf8, 0xa8, 0xf7, 0x27, 0x15, 0x9d, 0xfb, 0x27, 0xf7, + 0x2d, 0x8b, 0x2a, 0xf9, 0x6d, 0xfb, 0x41, 0x8b, 0xfc, 0x2b, 0xfd, 0x6d, + 0xf7, 0x2d, 0x8b, 0xdc, 0xf7, 0x27, 0xf7, 0xa4, 0x8b, 0x05, 0x7d, 0xf7, + 0x11, 0x15, 0xfb, 0x51, 0x8b, 0xf7, 0x2e, 0xf7, 0xaf, 0xae, 0xfb, 0xaf, + 0x05, 0x84, 0xf9, 0x2c, 0x15, 0xfb, 0x1f, 0xfb, 0x27, 0xd7, 0x8b, 0xf2, + 0xec, 0xc8, 0x2a, 0xd9, 0x8b, 0x44, 0xf7, 0x27, 0xfb, 0x00, 0x8b, 0x05, + 0x0e, 0xbe, 0xf8, 0xa8, 0xf7, 0x27, 0x15, 0x9d, 0xfb, 0x27, 0xf7, 0x2d, + 0x8b, 0x2a, 0xf9, 0x6d, 0xfb, 0x41, 0x8b, 0xfc, 0x2b, 0xfd, 0x6d, 0xf7, + 0x2d, 0x8b, 0xdc, 0xf7, 0x27, 0x05, 0xf7, 0xa4, 0x06, 0x7d, 0xf7, 0x11, + 0x15, 0xfb, 0x51, 0x8b, 0xf7, 0x2e, 0xf7, 0xaf, 0xae, 0xfb, 0xaf, 0x05, + 0xf7, 0x3b, 0xf9, 0x1f, 0x15, 0x7d, 0x69, 0x79, 0x7b, 0x75, 0x8b, 0x7f, + 0x8b, 0x88, 0x8c, 0x79, 0x93, 0x08, 0x59, 0xa0, 0x05, 0x67, 0x9b, 0x82, + 0x8d, 0x71, 0x8b, 0x54, 0x8b, 0x61, 0x61, 0x73, 0x3f, 0x08, 0xc1, 0x06, + 0x9c, 0xad, 0x9b, 0x9a, 0x9d, 0x8b, 0x93, 0x8b, 0x9e, 0x85, 0x9c, 0x82, + 0x08, 0xbd, 0x72, 0x05, 0x98, 0x85, 0xa0, 0x86, 0x9c, 0x8b, 0xab, 0x8b, + 0xae, 0x9a, 0xa4, 0xa5, 0x9e, 0x9f, 0x96, 0xa0, 0x96, 0xb3, 0x08, 0x55, + 0x06, 0x0e, 0xbe, 0xf8, 0xa8, 0xf7, 0x27, 0x15, 0x9d, 0xfb, 0x27, 0xf7, + 0x2d, 0x8b, 0x2a, 0xf9, 0x6d, 0xfb, 0x41, 0x8b, 0xfc, 0x2b, 0xfd, 0x6d, + 0xf7, 0x2d, 0x8b, 0xdc, 0xf7, 0x27, 0xf7, 0xa4, 0x8b, 0x05, 0x7d, 0xf7, + 0x11, 0x15, 0xfb, 0x51, 0x8b, 0xf7, 0x2e, 0xf7, 0xaf, 0xae, 0xfb, 0xaf, + 0x05, 0xb9, 0xf9, 0x3d, 0x15, 0x51, 0x55, 0x57, 0x52, 0x62, 0xaa, 0x6d, + 0xb4, 0xc6, 0xc1, 0xbf, 0xc4, 0xb4, 0x6c, 0xa9, 0x61, 0x1f, 0x81, 0x59, + 0x15, 0x9f, 0x99, 0x7e, 0x79, 0x72, 0x71, 0x73, 0x71, 0x77, 0x7c, 0x99, + 0x9d, 0xa4, 0xa5, 0xa2, 0xa6, 0x1f, 0x0e, 0xbe, 0xf8, 0x19, 0x74, 0x15, + 0xf7, 0x44, 0x8c, 0xf7, 0x1c, 0xf3, 0xb4, 0xf7, 0x3b, 0x08, 0xfb, 0x23, + 0x06, 0x6e, 0x2f, 0x44, 0x57, 0x2b, 0x8b, 0x2a, 0x8b, 0x59, 0xc1, 0x8b, + 0xf5, 0x8b, 0xdd, 0xa5, 0xe2, 0xb8, 0xd1, 0xba, 0xd5, 0xc9, 0xae, 0xdb, + 0x8b, 0xc0, 0x8b, 0xb4, 0x78, 0xa0, 0x69, 0x98, 0x77, 0x8f, 0x78, 0x8b, + 0x64, 0x08, 0xf7, 0x21, 0x06, 0x8e, 0xa5, 0x8c, 0x97, 0x8b, 0x96, 0x8b, + 0xf7, 0x11, 0x22, 0xe0, 0xfb, 0x2f, 0x8b, 0xfb, 0x0f, 0x8b, 0x20, 0x56, + 0x3a, 0x25, 0x44, 0x34, 0x5f, 0xfb, 0x1c, 0x8b, 0xfb, 0x14, 0x8b, 0xfb, + 0x25, 0xe7, 0x26, 0xf7, 0x21, 0x80, 0x08, 0x54, 0x37, 0x05, 0xa4, 0x95, + 0x97, 0x8e, 0x9c, 0x8b, 0x08, 0xa5, 0x9d, 0x7e, 0x77, 0x73, 0x6d, 0x77, + 0x65, 0x1f, 0x6f, 0x8b, 0x74, 0x92, 0x5b, 0xa2, 0x08, 0x6d, 0x58, 0x05, + 0xc4, 0x75, 0xab, 0x84, 0xb7, 0x8b, 0x08, 0xe6, 0xc7, 0xb5, 0xcc, 0xaf, + 0x73, 0xa0, 0x63, 0x1f, 0x7c, 0x8b, 0x7d, 0x89, 0x7d, 0x86, 0x08, 0xa5, + 0xb3, 0x05, 0x0e, 0xbe, 0xf7, 0x2a, 0xf7, 0xe9, 0x15, 0x42, 0xfb, 0xe9, + 0xf7, 0xb1, 0x8b, 0x05, 0xf7, 0x25, 0x8b, 0xdf, 0xb2, 0xd4, 0xf0, 0xd2, + 0xed, 0xb4, 0xf7, 0x0f, 0x8b, 0xf7, 0x0a, 0x08, 0xf7, 0x43, 0x3d, 0xd6, + 0xfb, 0x49, 0x1e, 0xfb, 0xb1, 0x8b, 0x49, 0xfb, 0xc8, 0x3f, 0x8b, 0x7a, + 0x3b, 0xd8, 0x8b, 0x05, 0xf7, 0x2a, 0x16, 0xf7, 0x41, 0x8b, 0x9c, 0xdb, + 0xfb, 0x42, 0x8b, 0xb2, 0xf7, 0x4b, 0xf7, 0x1b, 0x8b, 0x05, 0xe7, 0xb8, + 0x5f, 0x30, 0x1f, 0x8b, 0x3c, 0x71, 0x24, 0x69, 0x50, 0x60, 0x40, 0x5a, + 0x6f, 0x34, 0x8b, 0x08, 0xfb, 0x1a, 0x8b, 0xb9, 0xf7, 0x6c, 0x05, 0x0e, + 0x87, 0xf7, 0xbc, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0x8b, 0xa5, 0xf7, 0x11, + 0xfb, 0xf1, 0x8b, 0xae, 0xf7, 0x39, 0xf8, 0x0e, 0x8b, 0xa6, 0xf7, 0x11, + 0xfc, 0xa4, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0xb5, 0x8b, 0xa6, 0xf7, + 0x11, 0xfc, 0x1f, 0x8b, 0xb3, 0xf7, 0x51, 0x05, 0xf7, 0x62, 0xf8, 0xf2, + 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, + 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, + 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0x0e, 0x87, 0xf7, 0xbc, 0xf7, 0xce, + 0x15, 0xf7, 0xf1, 0x8b, 0xa5, 0xf7, 0x11, 0xfb, 0xf1, 0x8b, 0xae, 0xf7, + 0x39, 0xf8, 0x0e, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, 0xa4, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0xf8, 0xb5, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, 0x1f, 0x8b, 0xb3, + 0xf7, 0x51, 0x05, 0xf8, 0x0f, 0xf9, 0x02, 0x15, 0xfb, 0x12, 0x8b, 0x25, + 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x2a, 0x05, 0x0e, 0x87, 0xf7, + 0xbc, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0x8b, 0xa5, 0xf7, 0x11, 0xfb, 0xf1, + 0x8b, 0xae, 0xf7, 0x39, 0xf8, 0x0e, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, 0xa4, + 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0xb5, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, + 0x1f, 0x8b, 0xb3, 0xf7, 0x51, 0x05, 0xf3, 0xf9, 0x02, 0x15, 0xf0, 0xfb, + 0x2a, 0xca, 0x8b, 0x5e, 0xf7, 0x2a, 0xfb, 0x0b, 0x8b, 0x05, 0x0e, 0x87, + 0xf7, 0xbc, 0xf7, 0xce, 0x15, 0xf7, 0xf1, 0x8b, 0xa5, 0xf7, 0x11, 0xfb, + 0xf1, 0x8b, 0xae, 0xf7, 0x39, 0xf8, 0x0e, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, + 0xa4, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0xb5, 0x8b, 0xa6, 0xf7, 0x11, + 0xfc, 0x1f, 0x8b, 0xb3, 0xf7, 0x51, 0x05, 0xf7, 0x5a, 0xf9, 0x02, 0x15, + 0xfb, 0x1f, 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, 0xd9, 0x8b, + 0x43, 0xf7, 0x27, 0x20, 0x8b, 0x05, 0x0e, 0xfc, 0x1d, 0xf8, 0x04, 0xf9, + 0x6d, 0x15, 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, + 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x44, 0xf7, 0x53, 0x15, 0xfb, 0x02, 0x8b, + 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xf7, 0x4e, + 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, + 0x0c, 0x05, 0x0e, 0xfc, 0x1d, 0xf8, 0x04, 0xf9, 0x6d, 0x15, 0xfb, 0x2a, + 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, + 0x05, 0xf7, 0x0d, 0xf7, 0x63, 0x15, 0xfb, 0x12, 0x8b, 0x25, 0xfb, 0x2a, + 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x2a, 0x05, 0x0e, 0xfc, 0x1d, 0xf8, 0x04, + 0xf9, 0x6d, 0x15, 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, + 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0xfb, 0x4f, 0xf7, 0x63, 0x15, 0xf0, + 0xfb, 0x2a, 0xca, 0x8b, 0x5f, 0xf7, 0x2a, 0xfb, 0x0c, 0x8b, 0x05, 0x0e, + 0xfc, 0x1d, 0xf8, 0x04, 0xf9, 0x6d, 0x15, 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x3b, 0xf7, + 0x63, 0x15, 0xfb, 0x1f, 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, + 0xd9, 0x8b, 0x44, 0xf7, 0x27, 0xfb, 0x00, 0x8b, 0x05, 0x0e, 0xbe, 0xf9, + 0xc4, 0xf9, 0x6d, 0x15, 0xfb, 0x22, 0x8b, 0xfb, 0x01, 0xfc, 0x97, 0xfb, + 0x54, 0xf8, 0x97, 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x22, + 0x8b, 0xf7, 0x03, 0xf8, 0x9f, 0xf7, 0x54, 0xfc, 0x9f, 0xf7, 0x28, 0x8b, + 0x05, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0xfb, 0x19, 0xf7, 0x56, 0x15, 0x7d, + 0x69, 0x79, 0x7b, 0x74, 0x8b, 0x80, 0x8b, 0x88, 0x8c, 0x79, 0x93, 0x08, + 0x59, 0xa0, 0x05, 0x67, 0x9b, 0x82, 0x8d, 0x71, 0x8b, 0x54, 0x8b, 0x60, + 0x61, 0x74, 0x3f, 0x08, 0xc1, 0x06, 0x9c, 0xad, 0x9b, 0x9a, 0x9d, 0x8b, + 0x93, 0x8b, 0x9e, 0x85, 0x9c, 0x82, 0x08, 0xbd, 0x72, 0x05, 0x98, 0x85, + 0xa0, 0x86, 0x9c, 0x8b, 0xab, 0x8b, 0xae, 0x9a, 0xa4, 0xa5, 0x9e, 0x9f, + 0x96, 0xa0, 0x96, 0xb3, 0x08, 0x55, 0x06, 0x0e, 0xf6, 0xf8, 0xba, 0xfa, + 0x2c, 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, + 0xf7, 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, + 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xfb, 0x5a, 0xfb, 0x47, 0x15, + 0xfb, 0x10, 0x8b, 0x26, 0x5b, 0x39, 0x28, 0x3d, 0x2f, 0x5c, 0xfb, 0x12, + 0x8b, 0xfb, 0x07, 0x8b, 0xfb, 0x43, 0xf7, 0x03, 0xfb, 0x01, 0xf7, 0x46, + 0x8b, 0xf7, 0x14, 0x8b, 0xeb, 0xb8, 0xe1, 0xf1, 0xd9, 0xe6, 0xb8, 0xf7, + 0x0e, 0x8b, 0xf7, 0x09, 0x8b, 0xf7, 0x49, 0x20, 0xf5, 0xfb, 0x4b, 0x8b, + 0x08, 0x78, 0xfb, 0x14, 0x15, 0xef, 0xc7, 0x49, 0xfb, 0x02, 0x1f, 0x8b, + 0x3c, 0x70, 0x33, 0x60, 0x4f, 0x59, 0x45, 0x4c, 0x68, 0x3e, 0x8b, 0x26, + 0x8b, 0x4c, 0xcf, 0x8b, 0xf7, 0x01, 0x8b, 0xd9, 0xa7, 0xe3, 0xb7, 0xc8, + 0xbd, 0xcf, 0xcd, 0xaf, 0xd7, 0x8b, 0x08, 0x0e, 0xf6, 0xf9, 0x70, 0xfa, + 0x3c, 0x15, 0xfb, 0x13, 0x8b, 0x26, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x32, + 0xf7, 0x2a, 0x05, 0xfb, 0x56, 0xfb, 0x57, 0x15, 0xfb, 0x10, 0x8b, 0x26, + 0x5b, 0x39, 0x28, 0x3d, 0x2f, 0x5c, 0xfb, 0x12, 0x8b, 0xfb, 0x07, 0x8b, + 0xfb, 0x43, 0xf7, 0x03, 0xfb, 0x01, 0xf7, 0x46, 0x8b, 0xf7, 0x14, 0x8b, + 0xeb, 0xb8, 0xe1, 0xf1, 0xd9, 0xe6, 0xb8, 0xf7, 0x0e, 0x8b, 0xf7, 0x09, + 0x8b, 0xf7, 0x49, 0x20, 0xf5, 0xfb, 0x4b, 0x8b, 0x08, 0x78, 0xfb, 0x14, + 0x15, 0xef, 0xc7, 0x49, 0xfb, 0x02, 0x1f, 0x8b, 0x3c, 0x70, 0x33, 0x60, + 0x4f, 0x59, 0x45, 0x4c, 0x68, 0x3e, 0x8b, 0x26, 0x8b, 0x4c, 0xcf, 0x8b, + 0xf7, 0x01, 0x8b, 0xd9, 0xa7, 0xe3, 0xb7, 0xc8, 0xbd, 0xcf, 0xcd, 0xaf, + 0xd7, 0x8b, 0x08, 0x0e, 0xf6, 0xf8, 0x56, 0xfa, 0x3c, 0x15, 0xef, 0xfb, + 0x2a, 0xcb, 0x8b, 0x5e, 0xf7, 0x2a, 0xfb, 0x0b, 0x8b, 0x05, 0xe3, 0xfb, + 0x57, 0x15, 0xfb, 0x10, 0x8b, 0x26, 0x5b, 0x39, 0x28, 0x3d, 0x2f, 0x5c, + 0xfb, 0x12, 0x8b, 0xfb, 0x07, 0x8b, 0xfb, 0x43, 0xf7, 0x03, 0xfb, 0x01, + 0xf7, 0x46, 0x8b, 0xf7, 0x14, 0x8b, 0xeb, 0xb8, 0xe1, 0xf1, 0xd9, 0xe6, + 0xb8, 0xf7, 0x0e, 0x8b, 0xf7, 0x09, 0x8b, 0xf7, 0x49, 0x20, 0xf5, 0xfb, + 0x4b, 0x8b, 0x08, 0x78, 0xfb, 0x14, 0x15, 0xef, 0xc7, 0x49, 0xfb, 0x02, + 0x1f, 0x8b, 0x3c, 0x70, 0x33, 0x60, 0x4f, 0x59, 0x45, 0x4c, 0x68, 0x3e, + 0x8b, 0x26, 0x8b, 0x4c, 0xcf, 0x8b, 0xf7, 0x01, 0x8b, 0xd9, 0xa7, 0xe3, + 0xb7, 0xc8, 0xbd, 0xcf, 0xcd, 0xaf, 0xd7, 0x8b, 0x08, 0x0e, 0xf6, 0xf8, + 0xb1, 0xfa, 0x3c, 0x15, 0xfb, 0x1f, 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, + 0xc8, 0x2a, 0xd9, 0x8b, 0x44, 0xf7, 0x27, 0xfb, 0x00, 0x8b, 0x05, 0x88, + 0xfb, 0x57, 0x15, 0xfb, 0x10, 0x8b, 0x26, 0x5b, 0x39, 0x28, 0x3d, 0x2f, + 0x5c, 0xfb, 0x12, 0x8b, 0xfb, 0x07, 0x8b, 0xfb, 0x43, 0xf7, 0x03, 0xfb, + 0x01, 0xf7, 0x46, 0x8b, 0xf7, 0x14, 0x8b, 0xeb, 0xb8, 0xe1, 0xf1, 0xd9, + 0xe6, 0xb8, 0xf7, 0x0e, 0x8b, 0xf7, 0x09, 0x8b, 0xf7, 0x49, 0x20, 0xf5, + 0xfb, 0x4b, 0x8b, 0x08, 0x78, 0xfb, 0x14, 0x15, 0xef, 0xc7, 0x49, 0xfb, + 0x02, 0x1f, 0x8b, 0x3c, 0x70, 0x33, 0x60, 0x4f, 0x59, 0x45, 0x4c, 0x68, + 0x3e, 0x8b, 0x26, 0x8b, 0x4c, 0xcf, 0x8b, 0xf7, 0x01, 0x8b, 0xd9, 0xa7, + 0xe3, 0xb7, 0xc8, 0xbd, 0xcf, 0xcd, 0xaf, 0xd7, 0x8b, 0x08, 0x0e, 0xf6, + 0xf8, 0xae, 0xf9, 0x79, 0x15, 0xfb, 0x10, 0x8b, 0x26, 0x5b, 0x39, 0x28, + 0x3d, 0x2f, 0x5c, 0xfb, 0x12, 0x8b, 0xfb, 0x07, 0x8b, 0xfb, 0x43, 0xf7, + 0x03, 0xfb, 0x01, 0xf7, 0x46, 0x8b, 0xf7, 0x14, 0x8b, 0xeb, 0xb8, 0xe1, + 0xf1, 0xd9, 0xe6, 0xb8, 0xf7, 0x0e, 0x8b, 0xf7, 0x09, 0x08, 0xf7, 0x49, + 0x20, 0xf5, 0xfb, 0x4b, 0x1e, 0x78, 0xfb, 0x14, 0x15, 0xef, 0xc7, 0x49, + 0xfb, 0x02, 0x1f, 0x8b, 0x3c, 0x70, 0x33, 0x60, 0x4f, 0x59, 0x45, 0x4c, + 0x68, 0x3e, 0x8b, 0x26, 0x8b, 0x4c, 0xcf, 0x8b, 0xf7, 0x01, 0x8b, 0xd9, + 0xa7, 0xe3, 0xb7, 0xc8, 0xbd, 0xcf, 0xcd, 0xaf, 0xd7, 0x8b, 0x08, 0xf7, + 0x57, 0xf7, 0xca, 0x15, 0x7e, 0x69, 0x79, 0x7b, 0x74, 0x8b, 0x80, 0x8b, + 0x88, 0x8c, 0x78, 0x93, 0x08, 0x59, 0xa0, 0x05, 0x67, 0x9b, 0x83, 0x8d, + 0x71, 0x8b, 0x54, 0x8b, 0x60, 0x61, 0x74, 0x3f, 0x08, 0xc1, 0x06, 0x9b, + 0xac, 0x9b, 0x9b, 0x9d, 0x8b, 0x93, 0x8b, 0x9e, 0x85, 0x9c, 0x82, 0x08, + 0xbe, 0x72, 0x05, 0x97, 0x85, 0xa1, 0x86, 0x9b, 0x8b, 0xac, 0x8b, 0xad, + 0x9a, 0xa5, 0xa5, 0x9e, 0x9f, 0x95, 0xa0, 0x97, 0xb3, 0x08, 0x54, 0x06, + 0x0e, 0x87, 0xf8, 0xad, 0xf9, 0xa9, 0x15, 0xf7, 0x1f, 0xf7, 0x27, 0x3f, + 0x8b, 0x24, 0x2a, 0x4e, 0xec, 0x3d, 0x8b, 0xd2, 0xfb, 0x27, 0x05, 0xf7, + 0x00, 0x06, 0xf7, 0x48, 0xfb, 0xae, 0x15, 0x91, 0xa7, 0x8d, 0x99, 0x8b, + 0x9f, 0x8b, 0xf7, 0x00, 0x2d, 0xcb, 0xfb, 0x32, 0x8b, 0x2a, 0x8b, 0x3f, + 0x73, 0x52, 0x59, 0x52, 0x5a, 0x68, 0x40, 0x8b, 0x44, 0x8b, 0x38, 0xbd, + 0x5f, 0xf7, 0x0b, 0x73, 0x08, 0xed, 0x77, 0x05, 0xe6, 0x79, 0xa8, 0x76, + 0x8b, 0x5d, 0x08, 0x48, 0x48, 0x5f, 0x23, 0x30, 0x57, 0xac, 0xc5, 0x1e, + 0x8b, 0x8f, 0x8c, 0x94, 0x8c, 0x94, 0x08, 0xfb, 0x26, 0x06, 0x88, 0x77, + 0x8a, 0x81, 0x8b, 0x7d, 0x8b, 0x57, 0x9f, 0x5c, 0xaf, 0x6a, 0xbb, 0x5f, + 0xd0, 0x76, 0xeb, 0x8b, 0xf7, 0x0e, 0x8b, 0xe8, 0xae, 0xc5, 0xce, 0xb5, + 0xba, 0xa6, 0xd4, 0x8b, 0xcd, 0x8b, 0xd8, 0x54, 0xbf, 0x25, 0x9f, 0x08, + 0xfb, 0x01, 0xa1, 0x05, 0x2d, 0x9e, 0x70, 0x9b, 0x8b, 0xb1, 0x08, 0xcb, + 0xc3, 0xb3, 0xe6, 0xe0, 0xba, 0x6e, 0x55, 0x1e, 0x8b, 0x86, 0x8a, 0x82, + 0x8a, 0x82, 0x08, 0xf7, 0x20, 0x06, 0x0e, 0xbe, 0xf8, 0x9b, 0xfa, 0x2c, + 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, + 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, + 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0x5d, 0xfb, 0x53, 0x15, 0x22, 0xfc, + 0x82, 0x05, 0x78, 0x31, 0x59, 0x63, 0x30, 0x8b, 0x3d, 0x8b, 0x5e, 0xab, + 0x8b, 0xc0, 0x8b, 0x9a, 0x8d, 0x99, 0x8e, 0x9b, 0x08, 0xf4, 0xf8, 0x82, + 0xfb, 0x2a, 0x8b, 0x26, 0xfc, 0x6e, 0x05, 0x84, 0x69, 0x87, 0x6c, 0x8b, + 0x75, 0x8b, 0xfb, 0x09, 0xeb, 0x41, 0xf7, 0x2b, 0x8b, 0xe3, 0x8b, 0xdd, + 0xa5, 0xc8, 0xbb, 0xc4, 0xb8, 0xab, 0xc3, 0x9d, 0xde, 0x08, 0xf4, 0xf8, + 0x82, 0xfb, 0x2a, 0x8b, 0x05, 0x0e, 0xbe, 0xf9, 0x48, 0xfa, 0x3c, 0x15, + 0xfb, 0x12, 0x8b, 0x25, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x2a, + 0x05, 0x6a, 0xfb, 0x63, 0x15, 0x22, 0xfc, 0x82, 0x05, 0x78, 0x31, 0x59, + 0x63, 0x30, 0x8b, 0x3d, 0x8b, 0x5e, 0xab, 0x8b, 0xc0, 0x8b, 0x9a, 0x8d, + 0x99, 0x8e, 0x9b, 0x08, 0xf4, 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x26, 0xfc, + 0x6e, 0x05, 0x84, 0x69, 0x87, 0x6c, 0x8b, 0x75, 0x8b, 0xfb, 0x09, 0xeb, + 0x41, 0xf7, 0x2b, 0x8b, 0xe3, 0x8b, 0xdd, 0xa5, 0xc8, 0xbb, 0xc4, 0xb8, + 0xab, 0xc3, 0x9d, 0xde, 0x08, 0xf4, 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x05, + 0x0e, 0xbe, 0xf8, 0x42, 0xfa, 0x3c, 0x15, 0xf0, 0xfb, 0x2a, 0xca, 0x8b, + 0x5e, 0xf7, 0x2a, 0xfb, 0x0b, 0x8b, 0x05, 0xf7, 0x79, 0xfb, 0x63, 0x15, + 0x22, 0xfc, 0x82, 0x05, 0x78, 0x31, 0x59, 0x63, 0x30, 0x8b, 0x3d, 0x8b, + 0x5e, 0xab, 0x8b, 0xc0, 0x8b, 0x9a, 0x8d, 0x99, 0x8e, 0x9b, 0x08, 0xf4, + 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x26, 0xfc, 0x6e, 0x05, 0x84, 0x69, 0x87, + 0x6c, 0x8b, 0x75, 0x8b, 0xfb, 0x09, 0xeb, 0x41, 0xf7, 0x2b, 0x8b, 0xe3, + 0x8b, 0xdd, 0xa5, 0xc8, 0xbb, 0xc4, 0xb8, 0xab, 0xc3, 0x9d, 0xde, 0x08, + 0xf4, 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x05, 0x0e, 0xbe, 0xf8, 0x98, 0xfa, + 0x3c, 0x15, 0xfb, 0x1f, 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, + 0xd9, 0x8b, 0x44, 0xf7, 0x27, 0xfb, 0x00, 0x8b, 0x05, 0xf7, 0x23, 0xfb, + 0x63, 0x15, 0x22, 0xfc, 0x82, 0x05, 0x78, 0x31, 0x59, 0x63, 0x30, 0x8b, + 0x3d, 0x8b, 0x5e, 0xab, 0x8b, 0xc0, 0x8b, 0x9a, 0x8d, 0x99, 0x8e, 0x9b, + 0x08, 0xf4, 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x26, 0xfc, 0x6e, 0x05, 0x84, + 0x69, 0x87, 0x6c, 0x8b, 0x75, 0x8b, 0xfb, 0x09, 0xeb, 0x41, 0xf7, 0x2b, + 0x8b, 0xe3, 0x8b, 0xdd, 0xa5, 0xc8, 0xbb, 0xc4, 0xb8, 0xab, 0xc3, 0x9d, + 0xde, 0x08, 0xf4, 0xf8, 0x82, 0xfb, 0x2a, 0x8b, 0x05, 0x0e, 0x87, 0xf8, + 0x71, 0xf7, 0xa2, 0x15, 0xf7, 0xdc, 0xf8, 0x5f, 0xfb, 0x3b, 0x8b, 0xfb, + 0x63, 0xfb, 0xcf, 0x39, 0xf7, 0xcf, 0xfb, 0x3b, 0x8b, 0xf7, 0x25, 0xfc, + 0x5f, 0x51, 0xfb, 0xa2, 0xf7, 0x2a, 0x8b, 0xc5, 0xf7, 0xa2, 0x05, 0xf7, + 0x53, 0xf9, 0x2e, 0x15, 0xfb, 0x12, 0x8b, 0x25, 0xfb, 0x2a, 0xd1, 0x8b, + 0xf7, 0x32, 0xf7, 0x2a, 0x05, 0x0e, 0x4f, 0xf9, 0x71, 0xf9, 0x6d, 0x15, + 0xfc, 0xb8, 0x8b, 0x70, 0xfb, 0x11, 0xf8, 0x09, 0x8b, 0xfc, 0x6e, 0xfc, + 0x73, 0x70, 0xfb, 0x11, 0xf8, 0xb8, 0x8b, 0xa6, 0xf7, 0x11, 0xfc, 0x09, + 0x8b, 0xf8, 0x6e, 0xf8, 0x73, 0xa6, 0xf7, 0x11, 0x05, 0xfb, 0x66, 0xc7, + 0x15, 0xf7, 0x1f, 0xf7, 0x27, 0x3e, 0x8b, 0x25, 0x2a, 0x4e, 0xec, 0x3d, + 0x8b, 0xd2, 0xfb, 0x27, 0xf7, 0x00, 0x8b, 0x05, 0x0e, 0x87, 0xf7, 0x94, + 0xf7, 0x20, 0x15, 0xf7, 0x4f, 0x06, 0xda, 0x8b, 0xc4, 0xa3, 0xc1, 0xc4, + 0xc1, 0xc4, 0xad, 0xe0, 0x8b, 0xd8, 0x8b, 0xbf, 0x74, 0xba, 0x62, 0xaa, + 0x67, 0xa7, 0x62, 0x96, 0x49, 0x8b, 0x08, 0xfb, 0x33, 0x8b, 0xa5, 0xf7, + 0x0c, 0xfb, 0x2a, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf7, 0x2a, 0x8b, 0xa9, + 0xf7, 0x20, 0x05, 0xa5, 0xf7, 0x11, 0x15, 0xba, 0xf7, 0x6f, 0xf7, 0x2d, + 0x8b, 0x05, 0xc1, 0xaf, 0x6b, 0x5c, 0x1f, 0x8b, 0x6e, 0x80, 0x64, 0x7d, + 0x76, 0x72, 0x68, 0x69, 0x7b, 0x56, 0x8b, 0x08, 0xfb, 0x2d, 0x06, 0x0e, + 0x87, 0xf8, 0x71, 0xf7, 0xa2, 0x15, 0xf7, 0xdc, 0xf8, 0x5f, 0xfb, 0x3b, + 0x8b, 0xfb, 0x63, 0xfb, 0xcf, 0x39, 0xf7, 0xcf, 0xfb, 0x3b, 0x8b, 0xf7, + 0x25, 0xfc, 0x5f, 0x51, 0xfb, 0xa2, 0xf7, 0x2a, 0x8b, 0xc5, 0xf7, 0xa2, + 0x05, 0x9d, 0xf9, 0x1e, 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, + 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, + 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0x0e, 0xf8, + 0x1f, 0xf9, 0x79, 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x02, + 0x8b, 0x05, 0xa5, 0xf7, 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, + 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0x55, 0xfd, + 0x68, 0x15, 0x7c, 0x9c, 0x85, 0x98, 0x8b, 0x9a, 0x8b, 0x91, 0x8c, 0x92, + 0x8d, 0x93, 0x08, 0xca, 0xf7, 0xc0, 0x05, 0x8f, 0x9d, 0x8d, 0x9a, 0x8b, + 0x97, 0x8b, 0xa8, 0x79, 0xae, 0x74, 0x9e, 0x6b, 0xa5, 0x5a, 0x97, 0x45, + 0x8b, 0xfb, 0x31, 0x8b, 0x3a, 0x52, 0x6f, 0xfb, 0x16, 0x08, 0xf7, 0x17, + 0x06, 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, 0x8b, 0xbe, 0x8b, 0xa1, 0x7e, 0x8b, + 0x6d, 0x8b, 0x76, 0x7d, 0x75, 0x77, 0x81, 0x77, 0x80, 0x8b, 0x8b, 0x43, + 0x81, 0x08, 0x51, 0x82, 0x05, 0x5b, 0x83, 0x66, 0x7d, 0x6c, 0x75, 0x56, + 0x65, 0x6a, 0x4e, 0x8b, 0x4f, 0x8b, 0x65, 0x9d, 0x65, 0xa8, 0x73, 0xa4, + 0x76, 0xad, 0x81, 0xb6, 0x8b, 0xc5, 0x8b, 0xbc, 0xa2, 0xc7, 0xc1, 0x08, + 0x88, 0x7c, 0x8b, 0x86, 0x8b, 0x84, 0x8b, 0x81, 0x8d, 0x85, 0x90, 0x80, + 0x08, 0xf7, 0x2d, 0x8b, 0x8f, 0x9c, 0x05, 0xfb, 0x13, 0xf7, 0x5c, 0x15, + 0x79, 0x39, 0x5b, 0x5d, 0x47, 0x8b, 0x5b, 0x8b, 0x72, 0x9c, 0x8b, 0xac, + 0x8b, 0xba, 0xb0, 0xac, 0xcc, 0x96, 0x08, 0xbd, 0x93, 0x9b, 0x8e, 0x05, + 0x95, 0x8d, 0x92, 0x8c, 0x8f, 0x8c, 0x96, 0x8d, 0x8e, 0x8c, 0x97, 0x92, + 0x08, 0x83, 0x65, 0x05, 0x0e, 0xf8, 0xdf, 0xf9, 0x89, 0x15, 0xfb, 0x12, + 0x8b, 0x25, 0xfb, 0x2a, 0xd1, 0x8b, 0x05, 0xf7, 0x32, 0xf7, 0x2a, 0x05, + 0x4f, 0xfd, 0x78, 0x15, 0x7c, 0x9c, 0x85, 0x98, 0x8b, 0x9a, 0x8b, 0x91, + 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xca, 0xf7, 0xc0, 0x05, 0x8f, 0x9d, 0x8d, + 0x9a, 0x8b, 0x97, 0x8b, 0xa8, 0x79, 0xae, 0x74, 0x9e, 0x6b, 0xa5, 0x5a, + 0x97, 0x45, 0x8b, 0xfb, 0x31, 0x8b, 0x3a, 0x52, 0x6f, 0xfb, 0x16, 0x08, + 0xf7, 0x17, 0x06, 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, 0x8b, 0xbe, 0x8b, 0xa1, + 0x7e, 0x8b, 0x6d, 0x8b, 0x76, 0x7d, 0x75, 0x77, 0x81, 0x77, 0x80, 0x8b, + 0x8b, 0x43, 0x81, 0x08, 0x51, 0x82, 0x05, 0x5b, 0x83, 0x66, 0x7d, 0x6c, + 0x75, 0x56, 0x65, 0x6a, 0x4e, 0x8b, 0x4f, 0x8b, 0x65, 0x9d, 0x65, 0xa8, + 0x73, 0xa4, 0x76, 0xad, 0x81, 0xb6, 0x8b, 0xc5, 0x8b, 0xbc, 0xa2, 0xc7, + 0xc1, 0x08, 0x88, 0x7c, 0x8b, 0x86, 0x8b, 0x84, 0x8b, 0x81, 0x8d, 0x85, + 0x90, 0x80, 0x08, 0xf7, 0x2d, 0x8b, 0x8f, 0x9c, 0x05, 0xfb, 0x13, 0xf7, + 0x5c, 0x15, 0x79, 0x39, 0x5b, 0x5d, 0x47, 0x8b, 0x5b, 0x8b, 0x72, 0x9c, + 0x8b, 0xac, 0x8b, 0xba, 0xb0, 0xac, 0xcc, 0x96, 0x08, 0xbd, 0x93, 0x9b, + 0x8e, 0x05, 0x95, 0x8d, 0x92, 0x8c, 0x8f, 0x8c, 0x96, 0x8d, 0x8e, 0x8c, + 0x97, 0x92, 0x08, 0x83, 0x65, 0x05, 0x0e, 0xf7, 0xc3, 0xf9, 0x89, 0x15, + 0xf0, 0xfb, 0x2a, 0xca, 0x8b, 0x5e, 0xf7, 0x2a, 0x05, 0xfb, 0x0b, 0x06, + 0xf7, 0x74, 0xfd, 0x78, 0x15, 0x7c, 0x9c, 0x85, 0x98, 0x8b, 0x9a, 0x8b, + 0x91, 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xca, 0xf7, 0xc0, 0x05, 0x8f, 0x9d, + 0x8d, 0x9a, 0x8b, 0x97, 0x8b, 0xa8, 0x79, 0xae, 0x74, 0x9e, 0x6b, 0xa5, + 0x5a, 0x97, 0x45, 0x8b, 0xfb, 0x31, 0x8b, 0x3a, 0x52, 0x6f, 0xfb, 0x16, + 0x08, 0xf7, 0x17, 0x06, 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, 0x8b, 0xbe, 0x8b, + 0xa1, 0x7e, 0x8b, 0x6d, 0x8b, 0x76, 0x7d, 0x75, 0x77, 0x81, 0x77, 0x80, + 0x8b, 0x8b, 0x43, 0x81, 0x08, 0x51, 0x82, 0x05, 0x5b, 0x83, 0x66, 0x7d, + 0x6c, 0x75, 0x56, 0x65, 0x6a, 0x4e, 0x8b, 0x4f, 0x8b, 0x65, 0x9d, 0x65, + 0xa8, 0x73, 0xa4, 0x76, 0xad, 0x81, 0xb6, 0x8b, 0xc5, 0x8b, 0xbc, 0xa2, + 0xc7, 0xc1, 0x08, 0x88, 0x7c, 0x8b, 0x86, 0x8b, 0x84, 0x8b, 0x81, 0x8d, + 0x85, 0x90, 0x80, 0x08, 0xf7, 0x2d, 0x8b, 0x8f, 0x9c, 0x05, 0xfb, 0x13, + 0xf7, 0x5c, 0x15, 0x79, 0x39, 0x5b, 0x5d, 0x47, 0x8b, 0x5b, 0x8b, 0x72, + 0x9c, 0x8b, 0xac, 0x8b, 0xba, 0xb0, 0xac, 0xcc, 0x96, 0x08, 0xbd, 0x93, + 0x9b, 0x8e, 0x05, 0x95, 0x8d, 0x92, 0x8c, 0x8f, 0x8c, 0x96, 0x8d, 0x8e, + 0x8c, 0x97, 0x92, 0x08, 0x83, 0x65, 0x05, 0x0e, 0xf8, 0x16, 0xf9, 0x89, + 0x15, 0xfb, 0x1f, 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, 0xd9, + 0x8b, 0x44, 0xf7, 0x27, 0x05, 0xfb, 0x00, 0x06, 0xf7, 0x21, 0xfd, 0x78, + 0x15, 0x7c, 0x9c, 0x85, 0x98, 0x8b, 0x9a, 0x8b, 0x91, 0x8c, 0x92, 0x8d, + 0x93, 0x08, 0xca, 0xf7, 0xc0, 0x05, 0x8f, 0x9d, 0x8d, 0x9a, 0x8b, 0x97, + 0x8b, 0xa8, 0x79, 0xae, 0x74, 0x9e, 0x6b, 0xa5, 0x5a, 0x97, 0x45, 0x8b, + 0xfb, 0x31, 0x8b, 0x3a, 0x52, 0x6f, 0xfb, 0x16, 0x08, 0xf7, 0x17, 0x06, + 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, 0x8b, 0xbe, 0x8b, 0xa1, 0x7e, 0x8b, 0x6d, + 0x8b, 0x76, 0x7d, 0x75, 0x77, 0x81, 0x77, 0x80, 0x8b, 0x8b, 0x43, 0x81, + 0x08, 0x51, 0x82, 0x05, 0x5b, 0x83, 0x66, 0x7d, 0x6c, 0x75, 0x56, 0x65, + 0x6a, 0x4e, 0x8b, 0x4f, 0x8b, 0x65, 0x9d, 0x65, 0xa8, 0x73, 0xa4, 0x76, + 0xad, 0x81, 0xb6, 0x8b, 0xc5, 0x8b, 0xbc, 0xa2, 0xc7, 0xc1, 0x08, 0x88, + 0x7c, 0x8b, 0x86, 0x8b, 0x84, 0x8b, 0x81, 0x8d, 0x85, 0x90, 0x80, 0x08, + 0xf7, 0x2d, 0x8b, 0x8f, 0x9c, 0x05, 0xfb, 0x13, 0xf7, 0x5c, 0x15, 0x79, + 0x39, 0x5b, 0x5d, 0x47, 0x8b, 0x5b, 0x8b, 0x72, 0x9c, 0x8b, 0xac, 0x8b, + 0xba, 0xb0, 0xac, 0xcc, 0x96, 0x08, 0xbd, 0x93, 0x9b, 0x8e, 0x05, 0x95, + 0x8d, 0x92, 0x8c, 0x8f, 0x8c, 0x96, 0x8d, 0x8e, 0x8c, 0x97, 0x92, 0x08, + 0x83, 0x65, 0x05, 0x0e, 0xf8, 0xa3, 0x9c, 0x15, 0x7c, 0x9c, 0x85, 0x98, + 0x8b, 0x9a, 0x8b, 0x91, 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xca, 0xf7, 0xc0, + 0x05, 0x8f, 0x9d, 0x8d, 0x9a, 0x8b, 0x97, 0x8b, 0xa8, 0x79, 0xae, 0x74, + 0x9e, 0x6b, 0xa5, 0x5a, 0x97, 0x45, 0x8b, 0xfb, 0x31, 0x8b, 0x3a, 0x52, + 0x6f, 0xfb, 0x16, 0x08, 0xf7, 0x17, 0x06, 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, + 0x8b, 0xbe, 0x8b, 0xa1, 0x7e, 0x8b, 0x6d, 0x8b, 0x76, 0x7d, 0x75, 0x77, + 0x81, 0x77, 0x80, 0x8b, 0x8b, 0x43, 0x81, 0x08, 0x51, 0x82, 0x05, 0x5b, + 0x83, 0x66, 0x7d, 0x6c, 0x75, 0x56, 0x65, 0x6a, 0x4e, 0x8b, 0x4f, 0x8b, + 0x65, 0x9d, 0x65, 0xa8, 0x73, 0xa4, 0x76, 0xad, 0x81, 0xb6, 0x8b, 0xc5, + 0x8b, 0xbc, 0xa2, 0xc7, 0xc1, 0x08, 0x88, 0x7c, 0x8b, 0x86, 0x8b, 0x84, + 0x8b, 0x81, 0x8d, 0x85, 0x90, 0x80, 0x08, 0xf7, 0x2d, 0x8b, 0x05, 0x8f, + 0x9c, 0x05, 0xfb, 0x13, 0xf7, 0x5c, 0x15, 0x79, 0x39, 0x5b, 0x5d, 0x47, + 0x8b, 0x5b, 0x8b, 0x72, 0x9c, 0x8b, 0xac, 0x8b, 0xba, 0xb0, 0xac, 0xcc, + 0x96, 0x08, 0xbd, 0x93, 0x9b, 0x8e, 0x05, 0x95, 0x8d, 0x92, 0x8c, 0x8f, + 0x8c, 0x96, 0x8d, 0x8e, 0x8c, 0x97, 0x92, 0x08, 0x83, 0x65, 0x05, 0xf7, + 0x32, 0xf8, 0xa3, 0x15, 0x7d, 0x69, 0x7a, 0x7a, 0x74, 0x8b, 0x7f, 0x8b, + 0x89, 0x8c, 0x78, 0x94, 0x08, 0x59, 0xa0, 0x05, 0x6b, 0x99, 0x7d, 0x8e, + 0x72, 0x8b, 0x55, 0x8b, 0x5f, 0x61, 0x74, 0x40, 0x08, 0xc1, 0x06, 0x9c, + 0xac, 0x9b, 0x9a, 0x9d, 0x8b, 0x93, 0x8b, 0xa0, 0x84, 0x9a, 0x84, 0x08, + 0xbd, 0x72, 0x05, 0x98, 0x85, 0xa0, 0x86, 0x9c, 0x8b, 0xab, 0x8b, 0xae, + 0x9a, 0xa4, 0xa5, 0x9e, 0x9f, 0x96, 0xa1, 0x96, 0xb2, 0x08, 0x55, 0x06, + 0x0e, 0xf8, 0xa3, 0x9c, 0x15, 0x7c, 0x9c, 0x85, 0x98, 0x8b, 0x9a, 0x8b, + 0x91, 0x8c, 0x92, 0x8d, 0x93, 0x08, 0xca, 0xf7, 0xc0, 0x05, 0x8f, 0x9d, + 0x8d, 0x9a, 0x8b, 0x97, 0x8b, 0xa8, 0x79, 0xae, 0x74, 0x9e, 0x6b, 0xa5, + 0x5a, 0x97, 0x45, 0x8b, 0xfb, 0x31, 0x8b, 0x3a, 0x52, 0x6f, 0xfb, 0x16, + 0x08, 0xf7, 0x17, 0x06, 0x9c, 0xc2, 0xaa, 0x9f, 0xcb, 0x8b, 0xbe, 0x8b, + 0xa1, 0x7e, 0x8b, 0x6d, 0x8b, 0x76, 0x7d, 0x75, 0x77, 0x81, 0x77, 0x80, + 0x8b, 0x8b, 0x43, 0x81, 0x08, 0x51, 0x82, 0x05, 0x5b, 0x83, 0x66, 0x7d, + 0x6c, 0x75, 0x56, 0x65, 0x6a, 0x4e, 0x8b, 0x4f, 0x8b, 0x65, 0x9d, 0x65, + 0xa8, 0x73, 0xa4, 0x76, 0xad, 0x81, 0xb6, 0x8b, 0xc5, 0x8b, 0xbc, 0xa2, + 0xc7, 0xc1, 0x08, 0x88, 0x7c, 0x8b, 0x86, 0x8b, 0x84, 0x8b, 0x81, 0x8d, + 0x85, 0x90, 0x80, 0x08, 0xf7, 0x2d, 0x8b, 0x05, 0x8f, 0x9c, 0x05, 0xfb, + 0x13, 0xf7, 0x5c, 0x15, 0x79, 0x39, 0x5b, 0x5d, 0x47, 0x8b, 0x5b, 0x8b, + 0x72, 0x9c, 0x8b, 0xac, 0x8b, 0xba, 0xb0, 0xac, 0xcc, 0x96, 0x08, 0xbd, + 0x93, 0x9b, 0x8e, 0x05, 0x95, 0x8d, 0x92, 0x8c, 0x8f, 0x8c, 0x96, 0x8d, + 0x8e, 0x8c, 0x97, 0x92, 0x08, 0x83, 0x65, 0x05, 0xb4, 0xf8, 0xc0, 0x15, + 0x51, 0x55, 0x57, 0x52, 0x62, 0xa9, 0x6d, 0xb5, 0xc5, 0xc1, 0xbf, 0xc4, + 0xb4, 0x6d, 0xa9, 0x61, 0x1f, 0x81, 0x59, 0x15, 0x9e, 0x99, 0x7e, 0x79, + 0x72, 0x72, 0x73, 0x70, 0x77, 0x7d, 0x99, 0x9d, 0xa4, 0xa5, 0xa2, 0xa6, + 0x1f, 0x0e, 0xf7, 0xb4, 0x74, 0x15, 0x8c, 0x06, 0xbc, 0x87, 0xd4, 0xa2, + 0xb8, 0xad, 0xbd, 0xb1, 0xac, 0xbc, 0xa1, 0xd1, 0x08, 0xfb, 0x1a, 0x06, + 0x6c, 0x44, 0x6a, 0x70, 0x55, 0x8b, 0x4f, 0x8b, 0x6e, 0xad, 0x8b, 0xd0, + 0x8b, 0xc0, 0x98, 0xc6, 0xa3, 0xbb, 0xa7, 0xc6, 0xb0, 0xa5, 0xc2, 0x8b, + 0xac, 0x8b, 0xa4, 0x7f, 0x98, 0x76, 0x93, 0x7c, 0x8d, 0x7f, 0x8c, 0x64, + 0x08, 0xf7, 0x1a, 0x06, 0x8e, 0xa3, 0x8c, 0x94, 0x8b, 0x95, 0x8b, 0xb5, + 0x7a, 0xb3, 0x6c, 0xaa, 0x65, 0xb1, 0x5d, 0x9c, 0x48, 0x8b, 0x2d, 0x8b, + 0x41, 0x6b, 0x56, 0x4c, 0x51, 0x45, 0x61, 0xfb, 0x09, 0x8b, 0x2d, 0x8b, + 0x43, 0xaf, 0x48, 0xc2, 0x6d, 0x08, 0x9e, 0x81, 0x9d, 0x85, 0xaf, 0x84, + 0x08, 0x52, 0x34, 0x05, 0xa4, 0x95, 0x97, 0x8e, 0x9c, 0x8b, 0x08, 0xa5, + 0x9d, 0x7e, 0x77, 0x73, 0x6d, 0x77, 0x65, 0x1f, 0x6f, 0x8b, 0x73, 0x92, + 0x5c, 0xa3, 0x08, 0x6d, 0x57, 0x05, 0xc3, 0x75, 0xac, 0x84, 0xb7, 0x8b, + 0x08, 0xe6, 0xc7, 0xb5, 0xcc, 0xaf, 0x73, 0xa0, 0x63, 0x1f, 0x7b, 0x8b, + 0x7f, 0x89, 0x7c, 0x87, 0x08, 0xa5, 0xb2, 0x05, 0x0e, 0xf8, 0x1c, 0xf9, + 0x79, 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x03, 0x8b, 0xa4, + 0xf7, 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, + 0xf7, 0x03, 0x8b, 0xa4, 0xf7, 0x0c, 0x05, 0x86, 0xfc, 0x97, 0x15, 0x97, + 0xb9, 0x91, 0xb3, 0x8b, 0xb1, 0x8b, 0xb9, 0x7a, 0xbb, 0x6f, 0xaf, 0x67, + 0xb8, 0x51, 0xa3, 0x42, 0x8b, 0x3d, 0x8b, 0x3b, 0x6c, 0x5c, 0x5a, 0x4b, + 0x48, 0x5d, 0xfb, 0x09, 0x8b, 0x27, 0x8b, 0xfb, 0x10, 0xe1, 0x37, 0xf7, + 0x11, 0x8b, 0x08, 0xf7, 0x0d, 0x8b, 0xf0, 0xcb, 0xc2, 0xf7, 0x03, 0x08, + 0xfb, 0x1e, 0x06, 0x78, 0x65, 0x5e, 0x72, 0x5b, 0x8b, 0x52, 0x8b, 0x65, + 0xb0, 0x8b, 0xc2, 0x8b, 0x94, 0x8b, 0x92, 0x8e, 0xa8, 0x08, 0xf7, 0xff, + 0x06, 0xfb, 0x11, 0xe8, 0x15, 0xfb, 0x70, 0x06, 0x94, 0xab, 0x93, 0x9d, + 0x98, 0x9c, 0xa3, 0xab, 0xb3, 0x9e, 0xb3, 0x8b, 0xae, 0x8b, 0xa8, 0x7a, + 0x98, 0x6f, 0x92, 0x7c, 0x8d, 0x7f, 0x8b, 0x69, 0x08, 0x7f, 0x07, 0x0e, + 0xf8, 0xc6, 0xf9, 0x89, 0x15, 0xfb, 0x12, 0x8b, 0x25, 0xfb, 0x2a, 0xd1, + 0x8b, 0xf7, 0x32, 0xf7, 0x2a, 0x05, 0x96, 0xfc, 0xa7, 0x15, 0x97, 0xb9, + 0x91, 0xb3, 0x8b, 0xb1, 0x8b, 0xb9, 0x7a, 0xbb, 0x6f, 0xaf, 0x67, 0xb8, + 0x51, 0xa3, 0x42, 0x8b, 0x3d, 0x8b, 0x3b, 0x6c, 0x5c, 0x5a, 0x4b, 0x48, + 0x5d, 0xfb, 0x09, 0x8b, 0x27, 0x8b, 0xfb, 0x10, 0xe1, 0x37, 0xf7, 0x11, + 0x8b, 0x08, 0xf7, 0x0d, 0x8b, 0xf0, 0xcb, 0xc2, 0xf7, 0x03, 0x08, 0xfb, + 0x1e, 0x06, 0x78, 0x65, 0x5e, 0x72, 0x5b, 0x8b, 0x52, 0x8b, 0x65, 0xb0, + 0x8b, 0xc2, 0x8b, 0x94, 0x8b, 0x92, 0x8e, 0xa8, 0x08, 0xf7, 0xff, 0x06, + 0xfb, 0x11, 0xe8, 0x15, 0xfb, 0x70, 0x06, 0x94, 0xab, 0x93, 0x9d, 0x98, + 0x9c, 0xa3, 0xab, 0xb3, 0x9e, 0xb3, 0x8b, 0xae, 0x8b, 0xa8, 0x7a, 0x98, + 0x6f, 0x92, 0x7c, 0x8d, 0x7f, 0x8b, 0x69, 0x08, 0x7f, 0x07, 0x0e, 0xf7, + 0xbd, 0xf9, 0x89, 0x15, 0xf0, 0xfb, 0x2a, 0xca, 0x8b, 0x5e, 0xf7, 0x2a, + 0xfb, 0x0b, 0x8b, 0x05, 0xf7, 0xa8, 0xfc, 0xa7, 0x15, 0x97, 0xb9, 0x91, + 0xb3, 0x8b, 0xb1, 0x8b, 0xb9, 0x7a, 0xbb, 0x6f, 0xaf, 0x67, 0xb8, 0x51, + 0xa3, 0x42, 0x8b, 0x3d, 0x8b, 0x3b, 0x6c, 0x5c, 0x5a, 0x4b, 0x48, 0x5d, + 0xfb, 0x09, 0x8b, 0x27, 0x8b, 0xfb, 0x10, 0xe1, 0x37, 0xf7, 0x11, 0x8b, + 0x08, 0xf7, 0x0d, 0x8b, 0xf0, 0xcb, 0xc2, 0xf7, 0x03, 0x08, 0xfb, 0x1e, + 0x06, 0x78, 0x65, 0x5e, 0x72, 0x5b, 0x8b, 0x52, 0x8b, 0x65, 0xb0, 0x8b, + 0xc2, 0x8b, 0x94, 0x8b, 0x92, 0x8e, 0xa8, 0x08, 0xf7, 0xff, 0x06, 0xfb, + 0x11, 0xe8, 0x15, 0xfb, 0x70, 0x06, 0x94, 0xab, 0x93, 0x9d, 0x98, 0x9c, + 0xa3, 0xab, 0xb3, 0x9e, 0xb3, 0x8b, 0xae, 0x8b, 0xa8, 0x7a, 0x98, 0x6f, + 0x92, 0x7c, 0x8d, 0x7f, 0x8b, 0x69, 0x08, 0x7f, 0x07, 0x0e, 0xf8, 0x0e, + 0xf9, 0x89, 0x15, 0xfb, 0x20, 0xfb, 0x27, 0xd8, 0x8b, 0xf2, 0xec, 0xc8, + 0x2a, 0xd8, 0x8b, 0x44, 0xf7, 0x27, 0x20, 0x8b, 0x05, 0xf7, 0x57, 0xfc, + 0xa7, 0x15, 0x97, 0xb9, 0x91, 0xb3, 0x8b, 0xb1, 0x8b, 0xb9, 0x7a, 0xbb, + 0x6f, 0xaf, 0x67, 0xb8, 0x51, 0xa3, 0x42, 0x8b, 0x3d, 0x8b, 0x3b, 0x6c, + 0x5c, 0x5a, 0x4b, 0x48, 0x5d, 0xfb, 0x09, 0x8b, 0x27, 0x8b, 0xfb, 0x10, + 0xe1, 0x37, 0xf7, 0x11, 0x8b, 0x08, 0xf7, 0x0d, 0x8b, 0xf0, 0xcb, 0xc2, + 0xf7, 0x03, 0x08, 0xfb, 0x1e, 0x06, 0x78, 0x65, 0x5e, 0x72, 0x5b, 0x8b, + 0x52, 0x8b, 0x65, 0xb0, 0x8b, 0xc2, 0x8b, 0x94, 0x8b, 0x92, 0x8e, 0xa8, + 0x08, 0xf7, 0xff, 0x06, 0xfb, 0x11, 0xe8, 0x15, 0xfb, 0x70, 0x06, 0x94, + 0xab, 0x93, 0x9d, 0x98, 0x9c, 0xa3, 0xab, 0xb3, 0x9e, 0xb3, 0x8b, 0xae, + 0x8b, 0xa8, 0x7a, 0x98, 0x6f, 0x92, 0x7c, 0x8d, 0x7f, 0x8b, 0x69, 0x08, + 0x7f, 0x07, 0x0e, 0xfc, 0x1d, 0xf7, 0xd6, 0xf8, 0xb0, 0x15, 0xfb, 0x20, + 0x8b, 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0xf7, 0x07, 0xf8, 0xb0, + 0x05, 0x49, 0xf7, 0x5d, 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, + 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, + 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0x0e, 0xfc, + 0x1d, 0xf7, 0xd6, 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x07, 0xfc, + 0xb0, 0xf7, 0x20, 0x8b, 0xf7, 0x07, 0xf8, 0xb0, 0x05, 0xf7, 0x12, 0xf7, + 0x6d, 0x15, 0xfb, 0x12, 0x8b, 0x25, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x32, + 0xf7, 0x2a, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0xd6, 0xf8, 0xb0, 0x15, 0xfb, + 0x20, 0x8b, 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0xf7, 0x07, 0xf8, + 0xb0, 0x05, 0xfb, 0x43, 0xf7, 0x6d, 0x15, 0xf0, 0xfb, 0x2a, 0xca, 0x8b, + 0x5e, 0xf7, 0x2a, 0xfb, 0x0b, 0x8b, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0xd6, + 0xf8, 0xb0, 0x15, 0xfb, 0x20, 0x8b, 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, + 0x8b, 0xf7, 0x07, 0xf8, 0xb0, 0x05, 0x40, 0xf7, 0x6d, 0x15, 0xfb, 0x1f, + 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, 0xd9, 0x8b, 0x44, 0xf7, + 0x27, 0xfb, 0x00, 0x8b, 0x05, 0x0e, 0x4f, 0xf7, 0x46, 0xf8, 0xb0, 0x15, + 0xfb, 0x07, 0xfc, 0xb0, 0xf7, 0x20, 0x8b, 0xcc, 0xf7, 0xc4, 0x05, 0x9c, + 0xdd, 0xc0, 0xbe, 0xce, 0x8b, 0xbb, 0x8b, 0xa5, 0x70, 0x8b, 0x5b, 0x8b, + 0x7e, 0x89, 0x7d, 0x87, 0x75, 0x08, 0x48, 0xfb, 0xcd, 0xf7, 0x20, 0x8b, + 0xd8, 0xf7, 0xfe, 0x05, 0x8f, 0x9e, 0x8d, 0x9d, 0x8b, 0x9d, 0x8b, 0xdb, + 0x51, 0xbf, 0x32, 0x8b, 0x41, 0x8b, 0x55, 0x70, 0x55, 0x4b, 0x08, 0x9d, + 0xdd, 0x05, 0xfb, 0x20, 0x06, 0xf8, 0x32, 0xf7, 0x60, 0x15, 0x7d, 0x69, + 0x7a, 0x7a, 0x74, 0x8b, 0x7f, 0x8b, 0x89, 0x8c, 0x78, 0x94, 0x08, 0x59, + 0xa0, 0x05, 0x6b, 0x99, 0x7d, 0x8e, 0x72, 0x8b, 0x55, 0x8b, 0x5f, 0x61, + 0x74, 0x40, 0x08, 0xc1, 0x06, 0x9c, 0xac, 0x9b, 0x9a, 0x9d, 0x8b, 0x93, + 0x8b, 0xa0, 0x84, 0x9a, 0x84, 0x08, 0xbd, 0x72, 0x05, 0x98, 0x85, 0xa0, + 0x86, 0x9c, 0x8b, 0xab, 0x8b, 0xae, 0x9a, 0xa4, 0xa5, 0x9e, 0x9f, 0x96, + 0xa1, 0x96, 0xb2, 0x08, 0x55, 0x06, 0x0e, 0x4f, 0xf8, 0x39, 0xf9, 0x79, + 0x15, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, + 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, + 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xfb, 0x56, 0xfb, 0x54, 0x15, 0x24, + 0x8b, 0x31, 0x5f, 0x50, 0x3c, 0x5b, 0x4c, 0x6c, 0x27, 0x8b, 0x35, 0x8b, + 0xfb, 0x0e, 0xe0, 0x3d, 0xf7, 0x18, 0x8b, 0xf7, 0x00, 0x8b, 0xe2, 0xb5, + 0xc8, 0xdc, 0xba, 0xca, 0xab, 0xef, 0x8b, 0xe1, 0x8b, 0xf7, 0x10, 0x37, + 0xd7, 0xfb, 0x1d, 0x8b, 0x08, 0x75, 0xfb, 0x04, 0x15, 0xc8, 0xb2, 0x5d, + 0x44, 0x1f, 0x8b, 0x5a, 0x7d, 0x56, 0x73, 0x61, 0x6c, 0x53, 0x5d, 0x6c, + 0x57, 0x8b, 0x08, 0x4f, 0x64, 0xb9, 0xd1, 0xf7, 0x13, 0xd7, 0xf4, 0xe5, + 0x1f, 0x0e, 0x4f, 0xf8, 0xeb, 0xf9, 0x89, 0x15, 0xfb, 0x12, 0x8b, 0x25, + 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x2a, 0x05, 0xfb, 0x4e, 0xfb, + 0x64, 0x15, 0x24, 0x8b, 0x31, 0x5f, 0x50, 0x3c, 0x5b, 0x4c, 0x6c, 0x27, + 0x8b, 0x35, 0x8b, 0xfb, 0x0e, 0xe0, 0x3d, 0xf7, 0x18, 0x8b, 0xf7, 0x00, + 0x8b, 0xe2, 0xb5, 0xc8, 0xdc, 0xba, 0xca, 0xab, 0xef, 0x8b, 0xe1, 0x8b, + 0xf7, 0x10, 0x37, 0xd7, 0xfb, 0x1d, 0x8b, 0x08, 0x75, 0xfb, 0x04, 0x15, + 0xc8, 0xb2, 0x5d, 0x44, 0x1f, 0x8b, 0x5a, 0x7d, 0x56, 0x73, 0x61, 0x6c, + 0x53, 0x5d, 0x6c, 0x57, 0x8b, 0x08, 0x4f, 0x64, 0xb9, 0xd1, 0xf7, 0x13, + 0xd7, 0xf4, 0xe5, 0x1f, 0x0e, 0x4f, 0xf7, 0xdb, 0xf9, 0x89, 0x15, 0xf0, + 0xfb, 0x2a, 0xca, 0x8b, 0x5f, 0xf7, 0x2a, 0xfb, 0x0c, 0x8b, 0x05, 0xe1, + 0xfb, 0x64, 0x15, 0x24, 0x8b, 0x31, 0x5f, 0x50, 0x3c, 0x5b, 0x4c, 0x6c, + 0x27, 0x8b, 0x35, 0x8b, 0xfb, 0x0e, 0xe0, 0x3d, 0xf7, 0x18, 0x8b, 0xf7, + 0x00, 0x8b, 0xe2, 0xb5, 0xc8, 0xdc, 0xba, 0xca, 0xab, 0xef, 0x8b, 0xe1, + 0x8b, 0xf7, 0x10, 0x37, 0xd7, 0xfb, 0x1d, 0x8b, 0x08, 0x75, 0xfb, 0x04, + 0x15, 0xc8, 0xb2, 0x5d, 0x44, 0x1f, 0x8b, 0x5a, 0x7d, 0x56, 0x73, 0x61, + 0x6c, 0x53, 0x5d, 0x6c, 0x57, 0x8b, 0x08, 0x4f, 0x64, 0xb9, 0xd1, 0xf7, + 0x13, 0xd7, 0xf4, 0xe5, 0x1f, 0x0e, 0x4f, 0xf8, 0x33, 0xf9, 0x89, 0x15, + 0xfb, 0x1f, 0xfb, 0x27, 0xd7, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, 0xd9, 0x8b, + 0x43, 0xf7, 0x27, 0x20, 0x8b, 0x05, 0x89, 0xfb, 0x64, 0x15, 0x24, 0x8b, + 0x31, 0x5f, 0x50, 0x3c, 0x5b, 0x4c, 0x6c, 0x27, 0x8b, 0x35, 0x8b, 0xfb, + 0x0e, 0xe0, 0x3d, 0xf7, 0x18, 0x8b, 0xf7, 0x00, 0x8b, 0xe2, 0xb5, 0xc8, + 0xdc, 0xba, 0xca, 0xab, 0xef, 0x8b, 0xe1, 0x8b, 0xf7, 0x10, 0x37, 0xd7, + 0xfb, 0x1d, 0x8b, 0x08, 0x75, 0xfb, 0x04, 0x15, 0xc8, 0xb2, 0x5d, 0x44, + 0x1f, 0x8b, 0x5a, 0x7d, 0x56, 0x73, 0x61, 0x6c, 0x53, 0x5d, 0x6c, 0x57, + 0x8b, 0x08, 0x4f, 0x64, 0xb9, 0xd1, 0xf7, 0x13, 0xd7, 0xf4, 0xe5, 0x1f, + 0x0e, 0x4f, 0xf8, 0x31, 0xf8, 0xb9, 0x15, 0x24, 0x8b, 0x31, 0x5f, 0x50, + 0x3c, 0x5b, 0x4c, 0x6c, 0x27, 0x8b, 0x35, 0x8b, 0xfb, 0x0e, 0xe0, 0x3d, + 0xf7, 0x18, 0x8b, 0xf7, 0x00, 0x8b, 0xe2, 0xb5, 0xc8, 0xdc, 0xba, 0xca, + 0xab, 0xef, 0x8b, 0xe1, 0x08, 0xf7, 0x10, 0x37, 0xd7, 0xfb, 0x1d, 0x1e, + 0x75, 0xfb, 0x04, 0x15, 0xc8, 0xb2, 0x5d, 0x44, 0x1f, 0x8b, 0x5a, 0x7d, + 0x56, 0x73, 0x61, 0x6c, 0x53, 0x5d, 0x6c, 0x57, 0x8b, 0x08, 0x4f, 0x64, + 0xb9, 0xd1, 0xf7, 0x13, 0xd7, 0xf4, 0xe5, 0x1f, 0xf7, 0x56, 0xf7, 0xc7, + 0x15, 0x76, 0x69, 0x76, 0x7a, 0x74, 0x8b, 0x80, 0x8b, 0x88, 0x8c, 0x7a, + 0x94, 0x08, 0x5e, 0xa0, 0x05, 0x6a, 0x9a, 0x82, 0x8e, 0x72, 0x8b, 0x54, + 0x8b, 0x57, 0x61, 0x64, 0x3f, 0x08, 0xc1, 0x06, 0xa2, 0xac, 0x9e, 0x9a, + 0x9d, 0x8b, 0x93, 0x8b, 0xa0, 0x84, 0x98, 0x84, 0x08, 0xb8, 0x72, 0x05, + 0x96, 0x85, 0x9f, 0x86, 0x9c, 0x8b, 0x08, 0xcb, 0x8b, 0xc5, 0xb8, 0xb0, + 0xd8, 0x08, 0x55, 0x06, 0x0e, 0xf8, 0x5e, 0xf8, 0xf6, 0x15, 0xf7, 0x1f, + 0xf7, 0x27, 0x3f, 0x8b, 0x24, 0x2a, 0x4e, 0xec, 0x3d, 0x8b, 0xd2, 0xfb, + 0x27, 0x05, 0xf7, 0x00, 0x06, 0xf7, 0x12, 0xfb, 0x88, 0x15, 0x8f, 0x9d, + 0x8c, 0x94, 0x8b, 0x96, 0x8b, 0xe5, 0x3f, 0xc2, 0xfb, 0x12, 0x8b, 0x3c, + 0x8b, 0x48, 0x76, 0x60, 0x65, 0x60, 0x65, 0x6f, 0x52, 0x8b, 0x59, 0x8b, + 0x52, 0xb4, 0x65, 0xe3, 0x6e, 0x08, 0xda, 0x72, 0x05, 0xca, 0x77, 0x98, + 0x82, 0x8b, 0x74, 0x8b, 0x6b, 0x60, 0x74, 0x4e, 0x8b, 0x68, 0x8b, 0x6c, + 0x93, 0x78, 0x99, 0x7d, 0x97, 0x85, 0x96, 0x8a, 0xa2, 0x08, 0xfb, 0x1d, + 0x06, 0x88, 0x7d, 0x8a, 0x84, 0x8b, 0x83, 0x8b, 0x5d, 0xa8, 0x5c, 0xb7, + 0x72, 0xb2, 0x74, 0xba, 0x81, 0xc9, 0x8b, 0xf7, 0x3d, 0x8b, 0xf7, 0x01, + 0xdd, 0x8b, 0xf7, 0x14, 0x8b, 0xc7, 0x64, 0xb2, 0x38, 0xa4, 0x08, 0x2b, + 0xa7, 0x05, 0x58, 0x9a, 0x7d, 0x95, 0x8b, 0x9f, 0x08, 0xab, 0xae, 0xa0, + 0xc0, 0x1e, 0xc2, 0xac, 0x77, 0x6a, 0x1f, 0x8b, 0x86, 0x8a, 0x87, 0x89, + 0x82, 0x08, 0xf7, 0x1b, 0x06, 0x0e, 0x4f, 0xf8, 0x38, 0xf9, 0x79, 0x15, + 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, 0x03, 0x8b, 0x05, 0xa4, 0xf7, + 0x0c, 0x05, 0xf7, 0x4e, 0x16, 0xfb, 0x02, 0x8b, 0x71, 0xfb, 0x0c, 0xf7, + 0x03, 0x8b, 0xa4, 0xf7, 0x0c, 0x05, 0x4a, 0xfd, 0x79, 0x15, 0xf7, 0x07, + 0xf8, 0xb0, 0xfb, 0x20, 0x8b, 0x47, 0xfb, 0xd2, 0x05, 0x7a, 0x3a, 0x57, + 0x57, 0x4a, 0x8b, 0x59, 0x8b, 0x71, 0xa5, 0x8b, 0xbc, 0x8b, 0x9a, 0x8c, + 0x95, 0x91, 0xa3, 0x08, 0xd0, 0xf7, 0xdb, 0xfb, 0x20, 0x8b, 0x3b, 0xfc, + 0x0c, 0x05, 0x87, 0x78, 0x89, 0x79, 0x8b, 0x79, 0x8b, 0x3b, 0xc5, 0x57, + 0xe3, 0x8b, 0xd4, 0x8b, 0xc2, 0xa6, 0xc1, 0xcb, 0x08, 0x7c, 0x47, 0xf7, + 0x20, 0x8b, 0x05, 0x0e, 0x4f, 0xf8, 0xdf, 0xf9, 0x89, 0x15, 0xfb, 0x13, + 0x8b, 0x26, 0xfb, 0x2a, 0xd1, 0x8b, 0x05, 0xf7, 0x32, 0xf7, 0x2a, 0x05, + 0x5d, 0xfd, 0x89, 0x15, 0xf7, 0x07, 0xf8, 0xb0, 0xfb, 0x20, 0x8b, 0x47, + 0xfb, 0xd2, 0x05, 0x7a, 0x3a, 0x57, 0x57, 0x4a, 0x8b, 0x59, 0x8b, 0x71, + 0xa5, 0x8b, 0xbc, 0x8b, 0x9a, 0x8c, 0x95, 0x91, 0xa3, 0x08, 0xd0, 0xf7, + 0xdb, 0xfb, 0x20, 0x8b, 0x3b, 0xfc, 0x0c, 0x05, 0x87, 0x78, 0x89, 0x79, + 0x8b, 0x79, 0x8b, 0x3b, 0xc5, 0x57, 0xe3, 0x8b, 0xd4, 0x8b, 0xc2, 0xa6, + 0xc1, 0xcb, 0x08, 0x7c, 0x47, 0xf7, 0x20, 0x8b, 0x05, 0x0e, 0x4f, 0xf7, + 0xd9, 0xf9, 0x89, 0x15, 0xef, 0xfb, 0x2a, 0xcb, 0x8b, 0x5e, 0xf7, 0x2a, + 0x05, 0xfb, 0x0b, 0x06, 0xf7, 0x6c, 0xfd, 0x89, 0x15, 0xf7, 0x07, 0xf8, + 0xb0, 0xfb, 0x20, 0x8b, 0x47, 0xfb, 0xd2, 0x05, 0x7a, 0x3a, 0x57, 0x57, + 0x4a, 0x8b, 0x59, 0x8b, 0x71, 0xa5, 0x8b, 0xbc, 0x8b, 0x9a, 0x8c, 0x95, + 0x91, 0xa3, 0x08, 0xd0, 0xf7, 0xdb, 0xfb, 0x20, 0x8b, 0x3b, 0xfc, 0x0c, + 0x05, 0x87, 0x78, 0x89, 0x79, 0x8b, 0x79, 0x8b, 0x3b, 0xc5, 0x57, 0xe3, + 0x8b, 0xd4, 0x8b, 0xc2, 0xa6, 0xc1, 0xcb, 0x08, 0x7c, 0x47, 0xf7, 0x20, + 0x8b, 0x05, 0x0e, 0x4f, 0xf8, 0x2a, 0xf9, 0x89, 0x15, 0xfb, 0x20, 0xfb, + 0x27, 0xd8, 0x8b, 0xf2, 0xec, 0xc8, 0x2a, 0xd8, 0x8b, 0x44, 0xf7, 0x27, + 0x05, 0x20, 0x06, 0xf7, 0x1b, 0xfd, 0x89, 0x15, 0xf7, 0x07, 0xf8, 0xb0, + 0xfb, 0x20, 0x8b, 0x47, 0xfb, 0xd2, 0x05, 0x7a, 0x3a, 0x57, 0x57, 0x4a, + 0x8b, 0x59, 0x8b, 0x71, 0xa5, 0x8b, 0xbc, 0x8b, 0x9a, 0x8c, 0x95, 0x91, + 0xa3, 0x08, 0xd0, 0xf7, 0xdb, 0xfb, 0x20, 0x8b, 0x3b, 0xfc, 0x0c, 0x05, + 0x87, 0x78, 0x89, 0x79, 0x8b, 0x79, 0x8b, 0x3b, 0xc5, 0x57, 0xe3, 0x8b, + 0xd4, 0x8b, 0xc2, 0xa6, 0xc1, 0xcb, 0x08, 0x7c, 0x47, 0xf7, 0x20, 0x8b, + 0x05, 0x0e, 0xf8, 0x91, 0xf8, 0xb0, 0x15, 0xfb, 0x57, 0xfc, 0x1d, 0x67, + 0xf8, 0x1d, 0xfb, 0x2e, 0x8b, 0xd7, 0xfc, 0xb0, 0x8c, 0x7c, 0x05, 0x52, + 0x5f, 0x67, 0x46, 0x1e, 0x7f, 0x8b, 0x86, 0x8b, 0x80, 0x8d, 0x08, 0x74, + 0xfb, 0x01, 0x05, 0x99, 0x88, 0x94, 0x8a, 0xa1, 0x8b, 0xb6, 0x8b, 0xb2, + 0x91, 0xa8, 0x96, 0xb7, 0x9c, 0xa1, 0xa1, 0xaf, 0xcc, 0x08, 0xf7, 0xfa, + 0xf9, 0x12, 0xfb, 0x24, 0x8b, 0x05, 0xc4, 0xf7, 0x6d, 0x15, 0xfb, 0x12, + 0x8b, 0x25, 0xfb, 0x2a, 0xd1, 0x8b, 0xf7, 0x32, 0xf7, 0x2a, 0x05, 0x0e, + 0xfb, 0x3f, 0xf8, 0xd3, 0xf8, 0xb0, 0x15, 0xfc, 0x39, 0x8b, 0x73, 0xfb, + 0x05, 0xf7, 0x8d, 0x8b, 0xfb, 0xe2, 0xfb, 0xce, 0x73, 0xfb, 0x05, 0xf8, + 0x54, 0x8b, 0xa3, 0xf7, 0x05, 0xfb, 0xa6, 0x8b, 0xf7, 0xe0, 0xf7, 0xce, + 0xa3, 0xf7, 0x05, 0x05, 0xfb, 0x21, 0xd1, 0x15, 0xf7, 0x20, 0xf7, 0x27, + 0x3e, 0x8b, 0x24, 0x2a, 0x4f, 0xec, 0x3d, 0x8b, 0xd2, 0xfb, 0x27, 0xf6, + 0x8b, 0x05, 0x0e, 0x4f, 0xf7, 0xf7, 0xf8, 0xf5, 0x15, 0xb1, 0x70, 0xae, + 0x65, 0xa3, 0x62, 0x65, 0xa0, 0x77, 0x91, 0x6b, 0x8b, 0x45, 0x8b, 0x48, + 0x6d, 0x5e, 0x58, 0x50, 0x48, 0x65, 0x21, 0x8b, 0x29, 0x8b, 0xfb, 0x12, + 0xde, 0x40, 0xf7, 0x1f, 0x8b, 0xf3, 0x8b, 0xe1, 0xb4, 0xc5, 0xda, 0x08, + 0xbf, 0xd0, 0xa7, 0xe3, 0x8b, 0xe6, 0x8b, 0xf7, 0x14, 0x5a, 0xe0, 0xfb, + 0x16, 0xeb, 0x08, 0xe8, 0xb4, 0x60, 0xb6, 0x23, 0x5e, 0x05, 0x85, 0x8f, + 0x86, 0x8d, 0x89, 0x8d, 0x5d, 0xa6, 0x89, 0x8c, 0x69, 0x9a, 0x08, 0x45, + 0x59, 0x05, 0xb1, 0x73, 0x91, 0x87, 0xa5, 0x79, 0x08, 0x33, 0x62, 0xb4, + 0x60, 0xec, 0xb8, 0x05, 0xab, 0xfb, 0x46, 0x15, 0xa3, 0x8b, 0xa6, 0x82, + 0x9f, 0x7d, 0xa2, 0x79, 0x95, 0x73, 0x8b, 0x63, 0x8b, 0xfb, 0x1c, 0x44, + 0x26, 0x2d, 0x8b, 0x73, 0x8b, 0x73, 0x94, 0x78, 0x9a, 0x75, 0x9e, 0x81, + 0xa8, 0x8b, 0xb8, 0x8b, 0xbd, 0x98, 0xc0, 0xa3, 0xb5, 0x08, 0xa8, 0xbf, + 0xb6, 0xa7, 0xbe, 0x8b, 0x08, 0x0e, 0x4f, 0xf7, 0xf4, 0xf9, 0x6d, 0x15, + 0xfb, 0x20, 0x8b, 0xfb, 0x5d, 0xfe, 0x47, 0xf7, 0x20, 0x8b, 0xc7, 0xf7, + 0xae, 0x05, 0xa0, 0x50, 0xb5, 0x6f, 0xd1, 0x8b, 0x08, 0xf7, 0x35, 0xf7, + 0x18, 0xf7, 0x39, 0xf7, 0x5d, 0xf7, 0x11, 0x47, 0xdc, 0x22, 0x1f, 0x48, + 0x8b, 0x53, 0x6d, 0x5d, 0x50, 0x08, 0xc4, 0xf7, 0xa1, 0x05, 0xc1, 0xfb, + 0xb8, 0x15, 0xc0, 0xae, 0x5e, 0x46, 0xfb, 0x12, 0x41, 0xfb, 0x00, 0x35, + 0x56, 0x68, 0xb8, 0xcf, 0xf7, 0x11, 0xd5, 0xf7, 0x02, 0xe1, 0x1f, 0x0e, + 0xf8, 0x91, 0xf8, 0xb0, 0x15, 0xfb, 0x57, 0xfc, 0x1d, 0x67, 0xf8, 0x1d, + 0xfb, 0x2e, 0x8b, 0xd7, 0xfc, 0xb0, 0x8c, 0x7c, 0x05, 0x52, 0x5f, 0x67, + 0x46, 0x1e, 0x7f, 0x8b, 0x86, 0x8b, 0x80, 0x8d, 0x08, 0x74, 0xfb, 0x01, + 0x05, 0x99, 0x88, 0x94, 0x8a, 0xa1, 0x8b, 0xb6, 0x8b, 0xb2, 0x91, 0xa8, + 0x96, 0xb7, 0x9c, 0xa1, 0xa1, 0xaf, 0xcc, 0x08, 0xf7, 0xfa, 0xf9, 0x12, + 0xfb, 0x24, 0x8b, 0x05, 0xfb, 0x04, 0xf7, 0x5d, 0x15, 0xfb, 0x03, 0x8b, + 0x72, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, 0x0c, 0x05, 0xf7, 0x4e, + 0x16, 0xfb, 0x03, 0x8b, 0x72, 0xfb, 0x0c, 0xf7, 0x02, 0x8b, 0xa5, 0xf7, + 0x0c, 0x05, 0x0e, 0xc7, 0xf7, 0xd2, 0x15, 0x64, 0x47, 0xd4, 0x8b, 0x05, + 0x8c, 0x47, 0x93, 0x5a, 0x9f, 0x5e, 0xa9, 0x4a, 0xd5, 0x5d, 0xd9, 0x8b, + 0xb3, 0x8b, 0xad, 0x92, 0xe2, 0xa6, 0x08, 0xaa, 0xf7, 0x29, 0x05, 0x34, + 0x61, 0x6e, 0x81, 0x62, 0x8b, 0x4f, 0x8b, 0x67, 0xbd, 0x84, 0xe7, 0x08, + 0xf7, 0x49, 0x8b, 0xb1, 0xcf, 0xfb, 0x6d, 0x8b, 0x05, 0x8f, 0xa1, 0x8f, + 0x9e, 0x93, 0xa6, 0x08, 0xf7, 0x84, 0x8b, 0xb2, 0xcf, 0xfb, 0x8f, 0x8b, + 0x05, 0xb5, 0xe6, 0xc4, 0xbc, 0xca, 0x8b, 0xb7, 0x8b, 0xae, 0x79, 0xbe, + 0x5a, 0x08, 0xd4, 0xf7, 0x15, 0x05, 0x4d, 0xc1, 0x67, 0x99, 0x44, 0x8b, + 0xfb, 0x23, 0x8b, 0xfb, 0x11, 0x28, 0x41, 0xfb, 0x3f, 0x08, 0x5b, 0x8b, + 0x64, 0x47, 0xcb, 0x8b, 0x05, 0x83, 0x6f, 0x89, 0x80, 0x86, 0x6e, 0x08, + 0x64, 0x06, 0x0e, 0xfb, 0xe6, 0xf7, 0x64, 0xf8, 0xd1, 0x15, 0x4d, 0xfb, + 0xb5, 0xe9, 0x8b, 0xe5, 0xf8, 0x3d, 0x4c, 0x8b, 0x05, 0x73, 0x59, 0x59, + 0x72, 0x3d, 0x8b, 0x08, 0x7e, 0x4e, 0xf5, 0x8b, 0x05, 0x0e, 0xfb, 0xe6, + 0xf8, 0x1c, 0xf8, 0x00, 0x15, 0xfb, 0x4c, 0x06, 0x99, 0x9d, 0x9e, 0x99, + 0xcf, 0xb4, 0xbf, 0xaa, 0xa2, 0x9d, 0x9f, 0xa1, 0xa5, 0xaa, 0x99, 0xaf, + 0x8b, 0xb1, 0x8b, 0xcd, 0x5a, 0xb2, 0x37, 0x8b, 0x28, 0x8b, 0x4c, 0x52, + 0x7b, 0x23, 0x08, 0xe6, 0x06, 0x91, 0xc5, 0xa5, 0xaa, 0xb6, 0x8b, 0xac, + 0x8b, 0x9e, 0x7a, 0x8b, 0x6e, 0x8b, 0x71, 0x7f, 0x70, 0x77, 0x78, 0x77, + 0x78, 0x77, 0x7d, 0x45, 0x62, 0x34, 0x59, 0x6b, 0x64, 0x76, 0x3a, 0x08, + 0xf7, 0xc6, 0x8b, 0x9c, 0xdb, 0x05, 0x0e, 0xfb, 0xe6, 0xf7, 0x75, 0xf8, + 0x6b, 0x15, 0x98, 0x06, 0xc1, 0x8a, 0xa1, 0x7d, 0x8b, 0x69, 0x08, 0x63, + 0x6a, 0x6a, 0x63, 0x66, 0x78, 0x9b, 0xaa, 0x1e, 0x8b, 0x91, 0x8b, 0x8f, + 0x8d, 0x93, 0x08, 0x30, 0x06, 0x88, 0x7b, 0x8a, 0x83, 0x8b, 0x7f, 0x08, + 0x47, 0xbb, 0x64, 0xde, 0xf7, 0x01, 0xd6, 0xd0, 0xee, 0x1e, 0x8b, 0xab, + 0x7d, 0xa2, 0x6e, 0x9d, 0x08, 0xba, 0xa8, 0xa3, 0xb1, 0x8b, 0xb9, 0x8b, + 0xc6, 0x5c, 0xad, 0x3a, 0x8b, 0x28, 0x8b, 0x56, 0x5e, 0x77, 0x25, 0x08, + 0xe2, 0x06, 0x97, 0xc3, 0x9d, 0x9e, 0xb1, 0x8b, 0x08, 0xa6, 0x9d, 0x7b, + 0x73, 0x5e, 0x69, 0x6f, 0x56, 0x1f, 0x8a, 0x8b, 0x86, 0x8b, 0x87, 0x8c, + 0x08, 0x7e, 0x4c, 0x05, 0x0e, 0xfc, 0x1d, 0xf7, 0xa2, 0xf7, 0xae, 0x15, + 0x22, 0x8b, 0x75, 0x27, 0xf4, 0x8b, 0xa1, 0xef, 0x05, 0x0e, 0xfb, 0xe6, + 0xf8, 0x07, 0xf7, 0xea, 0x15, 0xfb, 0xa4, 0x8b, 0x6e, 0xfb, 0x1b, 0xf7, + 0xa4, 0x8b, 0xa8, 0xf7, 0x1b, 0x05, 0x0e, 0xfb, 0xa3, 0xf7, 0x78, 0xf9, + 0x42, 0x15, 0x38, 0x47, 0x47, 0x38, 0x38, 0xcf, 0x46, 0xdd, 0xe0, 0xcf, + 0xce, 0xe0, 0xde, 0x47, 0xcf, 0x37, 0x1f, 0x8c, 0x4c, 0x15, 0xbb, 0xb3, + 0x63, 0x5b, 0x59, 0x63, 0x64, 0x59, 0x5c, 0x63, 0xb4, 0xba, 0xbc, 0xb3, + 0xb3, 0xbc, 0x1f, 0x0e, 0x34, 0xf8, 0xf2, 0xf7, 0xb8, 0x15, 0xfc, 0x8c, + 0x8b, 0x72, 0xfb, 0x0c, 0xf8, 0x8c, 0x8b, 0xa4, 0xf7, 0x0c, 0x05, 0x0e, + 0x34, 0xf8, 0x98, 0xf8, 0x50, 0x15, 0xfb, 0x31, 0xfb, 0x15, 0x26, 0xf7, + 0x15, 0x25, 0x36, 0xf0, 0xfb, 0x14, 0xfb, 0x2f, 0xfb, 0x14, 0xcd, 0x37, + 0xf7, 0x2f, 0xf7, 0x14, 0xf0, 0xfb, 0x15, 0xf1, 0xdf, 0x26, 0xf7, 0x15, + 0xf7, 0x31, 0xf7, 0x15, 0x49, 0xdf, 0x05, 0x0e, 0x34, 0xf8, 0xf2, 0xf7, + 0xb8, 0x15, 0xfc, 0x8c, 0x8b, 0x72, 0xfb, 0x0c, 0xf8, 0x8c, 0x8b, 0xa4, + 0xf7, 0x0c, 0x05, 0xfb, 0xb4, 0xfb, 0x3c, 0x15, 0x64, 0x66, 0x67, 0x64, + 0x6f, 0xa0, 0x76, 0xa8, 0xb2, 0xb0, 0xaf, 0xb0, 0xa9, 0x76, 0xa0, 0x6e, + 0x1f, 0xd3, 0xf7, 0xe6, 0x15, 0x64, 0x66, 0x66, 0x65, 0x6f, 0xa0, 0x76, + 0xa7, 0xb3, 0xb0, 0xaf, 0xb0, 0xa9, 0x76, 0xa0, 0x6e, 0x1f, 0x0e, 0xf7, + 0xdd, 0xf8, 0x51, 0xf9, 0x1d, 0x15, 0xf7, 0x19, 0x8b, 0x9c, 0xdb, 0xfc, + 0x01, 0x8b, 0x7a, 0x3b, 0xf7, 0x1d, 0x8b, 0x3b, 0xfc, 0x0c, 0xea, 0x8b, + 0xdb, 0xf8, 0x0c, 0x05, 0xf8, 0x07, 0xfc, 0x0c, 0x15, 0xf7, 0x31, 0xf7, + 0xf1, 0x41, 0xfb, 0xf1, 0xe6, 0x8b, 0xec, 0xf8, 0x5c, 0xfb, 0x1d, 0x8b, + 0xfb, 0x32, 0xfb, 0xf3, 0x80, 0xf7, 0xf3, 0xfb, 0x1e, 0x8b, 0x2a, 0xfc, + 0x5c, 0xe6, 0x8b, 0xd6, 0xf7, 0xf1, 0x95, 0xfb, 0xf1, 0xe9, 0x8b, 0x05, + 0x0e, 0x34, 0xf9, 0x0a, 0xf8, 0x58, 0x15, 0xfb, 0x4b, 0x8b, 0xb2, 0xf7, + 0x49, 0xfb, 0x0b, 0x8b, 0x64, 0xfb, 0x49, 0xfb, 0x4a, 0x8b, 0x72, 0xfb, + 0x0c, 0xf7, 0x4a, 0x8b, 0x68, 0xfb, 0x36, 0xf7, 0x0b, 0x8b, 0xae, 0xf7, + 0x36, 0xf7, 0x4b, 0x8b, 0xa4, 0xf7, 0x0c, 0x05, 0x44, 0xfb, 0xe1, 0x15, + 0xfc, 0x78, 0x8b, 0x72, 0xfb, 0x0b, 0xf8, 0x78, 0x8b, 0xa4, 0xf7, 0x0b, + 0x05, 0x0e, 0xf7, 0x37, 0xef, 0xf8, 0xd1, 0x15, 0x4d, 0xfb, 0xb5, 0xe9, + 0x8b, 0xe5, 0xf8, 0x3d, 0x4c, 0x8b, 0x05, 0x73, 0x59, 0x59, 0x72, 0x3d, + 0x8b, 0x08, 0x7e, 0x4e, 0xf5, 0x8b, 0x05, 0xf8, 0x9e, 0xf7, 0x22, 0x15, + 0xfc, 0xd9, 0xfd, 0x73, 0xe0, 0x8b, 0xf8, 0xd9, 0xf9, 0x73, 0x36, 0x8b, + 0x05, 0xf7, 0x34, 0xfd, 0x0f, 0x15, 0xfb, 0x4c, 0x06, 0x99, 0x9d, 0x9e, + 0x99, 0xcf, 0xb4, 0xbf, 0xaa, 0xa2, 0x9d, 0x9f, 0xa1, 0xa5, 0xaa, 0x99, + 0xaf, 0x8b, 0xb1, 0x8b, 0xcd, 0x5a, 0xb2, 0x37, 0x8b, 0x28, 0x8b, 0x4c, + 0x52, 0x7b, 0x23, 0x08, 0xe6, 0x06, 0x91, 0xc5, 0xa5, 0xaa, 0xb6, 0x8b, + 0xac, 0x8b, 0x9e, 0x7a, 0x8b, 0x6e, 0x8b, 0x71, 0x7f, 0x70, 0x77, 0x78, + 0x77, 0x78, 0x77, 0x7d, 0x45, 0x62, 0x34, 0x59, 0x6b, 0x64, 0x76, 0x3a, + 0x08, 0xf7, 0xc6, 0x8b, 0x9c, 0xdb, 0x05, 0x0e, 0xf7, 0x37, 0xf7, 0x09, + 0xf8, 0xd1, 0x15, 0x4d, 0xfb, 0xb5, 0xe9, 0x8b, 0xe5, 0xf8, 0x3d, 0x4c, + 0x8b, 0x05, 0x73, 0x59, 0x59, 0x72, 0x3d, 0x8b, 0x08, 0x7e, 0x4e, 0xf5, + 0x8b, 0x05, 0xf8, 0xa8, 0xf7, 0x22, 0x15, 0xfc, 0xd9, 0xfd, 0x73, 0xe0, + 0x8b, 0xf8, 0xd9, 0xf9, 0x73, 0x36, 0x8b, 0x05, 0xf7, 0x43, 0xfc, 0xb9, + 0x15, 0x5d, 0x8b, 0xc2, 0xf7, 0x97, 0xfb, 0x00, 0x8b, 0xfb, 0x6d, 0xfb, + 0x98, 0x7b, 0x43, 0xf7, 0x45, 0x8b, 0x77, 0x2e, 0xe9, 0x8b, 0x9e, 0xe8, + 0xb9, 0x8b, 0x9b, 0xd4, 0x05, 0xfb, 0x1f, 0x16, 0x22, 0x8b, 0xf7, 0x20, + 0xf7, 0x3a, 0x68, 0xfb, 0x3a, 0x05, 0x0e, 0xf7, 0x37, 0xe4, 0xf8, 0x6b, + 0x15, 0x98, 0x06, 0xc1, 0x8a, 0xa1, 0x7d, 0x8b, 0x69, 0x08, 0x63, 0x6a, + 0x6a, 0x63, 0x66, 0x78, 0x9b, 0xaa, 0x1e, 0x8b, 0x91, 0x8b, 0x8f, 0x8d, + 0x93, 0x08, 0x30, 0x06, 0x88, 0x7b, 0x8a, 0x83, 0x8b, 0x7f, 0x08, 0x47, + 0xbb, 0x64, 0xde, 0xf7, 0x01, 0xd6, 0xd0, 0xee, 0x1e, 0x8b, 0xab, 0x7d, + 0xa2, 0x6e, 0x9d, 0x08, 0xba, 0xa8, 0xa3, 0xb1, 0x8b, 0xb9, 0x8b, 0xc6, + 0x5c, 0xad, 0x3a, 0x8b, 0x28, 0x8b, 0x56, 0x5e, 0x77, 0x25, 0x08, 0xe2, + 0x06, 0x97, 0xc3, 0x9d, 0x9e, 0xb1, 0x8b, 0x08, 0xa6, 0x9d, 0x7b, 0x73, + 0x5e, 0x69, 0x6f, 0x56, 0x1f, 0x8a, 0x8b, 0x86, 0x8b, 0x87, 0x8c, 0x08, + 0x7e, 0x4c, 0x05, 0xf8, 0xe0, 0xf7, 0x88, 0x15, 0xfc, 0xd9, 0xfd, 0x73, + 0xe0, 0x8b, 0xf8, 0xd9, 0xf9, 0x73, 0x36, 0x8b, 0x05, 0xf7, 0x2f, 0xfc, + 0xb9, 0x15, 0x5d, 0x8b, 0xc2, 0xf7, 0x97, 0xfb, 0x00, 0x8b, 0xfb, 0x6d, + 0xfb, 0x98, 0x7b, 0x43, 0xf7, 0x45, 0x8b, 0x77, 0x2e, 0xe9, 0x8b, 0x9e, + 0xe8, 0xb9, 0x8b, 0x9b, 0xd4, 0x05, 0xfb, 0x1f, 0x16, 0x22, 0x8b, 0xf7, + 0x20, 0xf7, 0x3a, 0x68, 0xfb, 0x3a, 0x05, 0x0e, 0xcd, 0xf9, 0x18, 0xf8, + 0x43, 0x15, 0x8d, 0x9c, 0x8c, 0x93, 0x8b, 0x93, 0x8b, 0xd8, 0x4e, 0xbe, + 0x2e, 0x8b, 0x3f, 0x8b, 0x48, 0x6a, 0x5b, 0x4e, 0x60, 0x55, 0x70, 0x39, + 0x8b, 0x40, 0x8b, 0x29, 0xc7, 0x4e, 0xed, 0x8b, 0xf7, 0x06, 0x8b, 0xe1, + 0xcb, 0xa7, 0xf4, 0x08, 0x2f, 0x06, 0x79, 0x53, 0x63, 0x6d, 0x52, 0x8b, + 0x54, 0x8b, 0x6c, 0xac, 0x8b, 0xc8, 0x8b, 0xbb, 0x9b, 0xc2, 0xa4, 0xb1, + 0xa8, 0xb5, 0xb0, 0xa0, 0xb9, 0x8b, 0x08, 0xc0, 0xa2, 0x73, 0x55, 0x1f, + 0xe5, 0x06, 0xfb, 0x06, 0xf7, 0xcc, 0x15, 0xfb, 0x8a, 0xfb, 0x7a, 0xfb, + 0x73, 0xfb, 0x83, 0xfb, 0x43, 0xf7, 0x16, 0xfb, 0x14, 0xf7, 0x44, 0xf7, + 0x8b, 0xf7, 0x7a, 0xf7, 0x73, 0xf7, 0x83, 0xf7, 0x43, 0xfb, 0x16, 0xf7, + 0x14, 0xfb, 0x45, 0x1f, 0x7b, 0x43, 0x15, 0xf7, 0x20, 0xf2, 0x24, 0xfb, + 0x21, 0xfb, 0x57, 0xfb, 0x4c, 0xfb, 0x4a, 0xfb, 0x58, 0xfb, 0x20, 0x24, + 0xf3, 0xf7, 0x21, 0xf7, 0x56, 0xf7, 0x4c, 0xf7, 0x4a, 0xf7, 0x58, 0x1f, + 0x0e, 0xcd, 0xf7, 0xf8, 0xf7, 0xcd, 0x15, 0xe6, 0x06, 0xaf, 0x9c, 0x80, + 0x73, 0x1f, 0x8b, 0x85, 0x89, 0x83, 0x87, 0x7a, 0x82, 0x69, 0x86, 0x6d, + 0x8b, 0x7c, 0x8b, 0x82, 0x8c, 0x85, 0x8f, 0x7e, 0x08, 0xf1, 0x8b, 0x90, + 0xa0, 0x05, 0x82, 0x91, 0x88, 0x91, 0x8b, 0x94, 0x08, 0x8c, 0x98, 0x05, + 0x97, 0xd2, 0x8e, 0xa0, 0x8b, 0x9c, 0x8b, 0xa1, 0x80, 0x99, 0x6f, 0x98, + 0x08, 0xcb, 0xa8, 0xac, 0xba, 0x8b, 0xcb, 0x08, 0xc6, 0x6a, 0xa9, 0x49, + 0x1e, 0xfb, 0x82, 0x8b, 0x2d, 0xfc, 0x4e, 0xeb, 0x8b, 0x05, 0xb0, 0xf7, + 0x41, 0x05, 0x9c, 0xdc, 0x15, 0xa2, 0xf7, 0x00, 0xf1, 0x8b, 0x05, 0xb3, + 0x9a, 0x82, 0x73, 0x1f, 0x8b, 0x78, 0x84, 0x73, 0x82, 0x80, 0x80, 0x7c, + 0x79, 0x85, 0x6a, 0x8b, 0x08, 0x25, 0x06, 0xf7, 0x31, 0xf7, 0xf1, 0x15, + 0xfb, 0x8a, 0xfb, 0x79, 0xfb, 0x73, 0xfb, 0x83, 0xfb, 0x43, 0xf7, 0x16, + 0xfb, 0x14, 0xf7, 0x44, 0xf7, 0x8b, 0xf7, 0x79, 0xf7, 0x73, 0xf7, 0x83, + 0xf7, 0x43, 0xfb, 0x15, 0xf7, 0x14, 0xfb, 0x46, 0x1f, 0x7b, 0x43, 0x15, + 0xf7, 0x20, 0xf2, 0x24, 0xfb, 0x21, 0xfb, 0x57, 0xfb, 0x4b, 0xfb, 0x4a, + 0xfb, 0x59, 0xfb, 0x20, 0x25, 0xf3, 0xf7, 0x21, 0xf7, 0x56, 0xf7, 0x4b, + 0xf7, 0x4a, 0xf7, 0x58, 0x1f, 0x0e, 0xfc, 0x1d, 0x0e, 0x34, 0xf7, 0x14, + 0xf8, 0x0c, 0x15, 0x72, 0xfb, 0x0c, 0xf8, 0x15, 0x8b, 0x67, 0xfb, 0x3e, + 0xf7, 0x0b, 0x8b, 0xc8, 0xf7, 0xb6, 0xfc, 0x8c, 0x8b, 0x05, 0x0e, 0xfc, + 0x1b, 0xf7, 0xe3, 0xf9, 0x6d, 0x15, 0x3b, 0x8b, 0x38, 0xfc, 0x19, 0xdb, + 0x8b, 0xde, 0xf8, 0x19, 0x05, 0xfb, 0x07, 0xfc, 0xb0, 0x15, 0x3b, 0x8b, + 0x38, 0xfc, 0x19, 0xdb, 0x8b, 0xde, 0xf8, 0x19, 0x05, 0x0e, 0x4f, 0xf7, + 0x26, 0xfb, 0x70, 0x15, 0xbd, 0xf7, 0x7f, 0x05, 0xa4, 0x6f, 0xa4, 0x81, + 0xb8, 0x8b, 0xc4, 0x8b, 0xaf, 0x99, 0xbb, 0xb4, 0x9b, 0x62, 0xa0, 0x7d, + 0xb9, 0x8b, 0xa7, 0x8b, 0x9f, 0x90, 0xa5, 0x98, 0x08, 0x9d, 0xe1, 0x05, + 0x81, 0x88, 0x87, 0x8a, 0x84, 0x8b, 0x7e, 0x8b, 0x83, 0x93, 0x8b, 0x9a, + 0x8b, 0x96, 0x8e, 0x9d, 0x8f, 0xa0, 0x08, 0xde, 0xf8, 0x1a, 0xfb, 0x20, + 0x8b, 0x43, 0xfb, 0xe6, 0x05, 0x7e, 0x4c, 0x57, 0x63, 0x48, 0x8b, 0x5c, + 0x8b, 0x6e, 0xa3, 0x8b, 0xb1, 0x8b, 0x94, 0x8e, 0x9d, 0x8f, 0x9e, 0x08, + 0xd2, 0xf7, 0xe1, 0xfb, 0x20, 0x8b, 0xfb, 0x36, 0xfd, 0x8c, 0xf7, 0x1b, + 0x8b, 0x05, 0x0e, 0xf8, 0xc0, 0x14, 0xf9, 0x33, 0x15, 0x74, 0xa2, 0xf8, + 0xb0, 0x94, 0xf7, 0x48, 0x97, 0x63, 0xa2, 0x06, 0x1e, 0x0a, 0x03, 0x96, + 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xf7, 0x05, 0x0a, 0xf3, 0x94, + 0x99, 0x0c, 0x0c, 0xf7, 0x25, 0x0b, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00 +}; +const unsigned int fonts_NimbusSanL_BoldItal_cff_len = 19968; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusSanL-Regu.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusSanL-Regu.cff.c new file mode 100644 index 00000000000..e7d738ad783 --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusSanL-Regu.cff.c @@ -0,0 +1,1387 @@ +const unsigned char fonts_NimbusSanL_Regu_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x10, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x53, 0x61, 0x6e, 0x4c, 0x2d, 0x52, 0x65, 0x67, 0x75, + 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x36, 0xf8, 0x1f, 0x00, 0xf8, 0x20, + 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, 0x18, 0x04, 0xfb, 0x2b, + 0x0c, 0x03, 0x1d, 0x00, 0x4c, 0x9c, 0xe6, 0x0d, 0xfb, 0x42, 0xfb, 0x70, + 0xfa, 0x7d, 0xfa, 0x4d, 0x05, 0x1c, 0x00, 0xeb, 0x0f, 0x1c, 0x00, 0x00, + 0x10, 0x1c, 0x02, 0xbc, 0x11, 0x1c, 0x00, 0x2e, 0x1c, 0x40, 0xb2, 0x12, + 0x00, 0x08, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, + 0x1b, 0x00, 0x1f, 0x00, 0x5f, 0x00, 0x74, 0x00, 0x81, 0x45, 0x75, 0x72, + 0x6f, 0x6d, 0x69, 0x64, 0x64, 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, + 0x70, 0x68, 0x65, 0x6e, 0x6e, 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, + 0x2e, 0x30, 0x35, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, + 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, + 0x62, 0x79, 0x20, 0x28, 0x55, 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, + 0x65, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, + 0x73, 0x20, 0x53, 0x61, 0x6e, 0x73, 0x20, 0x4c, 0x20, 0x52, 0x65, 0x67, + 0x75, 0x6c, 0x61, 0x72, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x53, + 0x61, 0x6e, 0x73, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, + 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, + 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, + 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, + 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, + 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, + 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, + 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, + 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, + 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, + 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, + 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, + 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, + 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, + 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, + 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, + 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, + 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, + 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, + 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, + 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, + 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, + 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8c, + 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, + 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, 0x00, 0xae, + 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, 0x00, 0xb4, + 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, 0x00, 0xb9, + 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, 0x00, 0xbc, + 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, 0x00, 0xc2, + 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xc8, + 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd1, + 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd6, + 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, 0x00, 0xd9, + 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, 0x00, 0xdf, + 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, 0x01, 0x87, + 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, 0x00, 0xa1, + 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, 0x00, 0x9b, + 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, 0x00, 0x97, + 0x00, 0xa0, 0x00, 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, + 0x05, 0x00, 0x25, 0x00, 0x50, 0x00, 0xb2, 0x01, 0x4b, 0x01, 0xb2, 0x02, + 0x44, 0x02, 0x60, 0x02, 0x91, 0x02, 0xc1, 0x02, 0xeb, 0x03, 0x08, 0x03, + 0x23, 0x03, 0x31, 0x03, 0x3c, 0x03, 0x50, 0x03, 0x98, 0x03, 0xb2, 0x04, + 0x0e, 0x04, 0x80, 0x04, 0xab, 0x04, 0xfd, 0x05, 0x5f, 0x05, 0x85, 0x05, + 0xed, 0x06, 0x4e, 0x06, 0x61, 0x06, 0x87, 0x06, 0xa5, 0x06, 0xbe, 0x06, + 0xdd, 0x07, 0x30, 0x07, 0xef, 0x08, 0x1f, 0x08, 0x9d, 0x08, 0xfd, 0x09, + 0x33, 0x09, 0x51, 0x09, 0x6b, 0x09, 0xd0, 0x09, 0xef, 0x09, 0xfd, 0x0a, + 0x2f, 0x0a, 0x5f, 0x0a, 0x70, 0x0a, 0x9f, 0x0a, 0xc3, 0x0b, 0x13, 0x0b, + 0x4d, 0x0b, 0xb5, 0x0c, 0x12, 0x0c, 0x90, 0x0c, 0xa6, 0x0c, 0xdc, 0x0c, + 0xf9, 0x0d, 0x2a, 0x0d, 0x5f, 0x0d, 0x86, 0x0d, 0xa9, 0x0d, 0xbd, 0x0d, + 0xd0, 0x0d, 0xe3, 0x0e, 0x02, 0x0e, 0x0f, 0x0e, 0x2c, 0x0e, 0xb8, 0x0e, + 0xfd, 0x0f, 0x46, 0x0f, 0x8e, 0x0f, 0xea, 0x10, 0x1a, 0x10, 0x95, 0x10, + 0xc8, 0x10, 0xe0, 0x11, 0x10, 0x11, 0x39, 0x11, 0x47, 0x11, 0x8f, 0x11, + 0xb9, 0x11, 0xf0, 0x12, 0x38, 0x12, 0x7e, 0x12, 0xaa, 0x13, 0x14, 0x13, + 0x46, 0x13, 0x6f, 0x13, 0x8c, 0x13, 0xb7, 0x13, 0xe8, 0x14, 0x2a, 0x14, + 0x4d, 0x14, 0x9a, 0x14, 0xa7, 0x14, 0xf3, 0x15, 0x40, 0x15, 0x61, 0x15, + 0xbe, 0x16, 0x5a, 0x16, 0x6f, 0x16, 0xb2, 0x17, 0x1b, 0x17, 0xce, 0x18, + 0x3b, 0x18, 0x52, 0x18, 0x88, 0x18, 0xb6, 0x18, 0xcf, 0x18, 0xeb, 0x19, + 0x30, 0x19, 0x6f, 0x19, 0x7c, 0x19, 0x97, 0x19, 0xc1, 0x19, 0xd1, 0x19, + 0xfe, 0x1a, 0x16, 0x1a, 0x31, 0x1a, 0x65, 0x1a, 0x9a, 0x1a, 0xcd, 0x1a, + 0xe9, 0x1b, 0x77, 0x1b, 0xcc, 0x1b, 0xe0, 0x1b, 0xf4, 0x1c, 0x0c, 0x1c, + 0x4b, 0x1c, 0x59, 0x1c, 0x83, 0x1c, 0x8f, 0x1c, 0xa3, 0x1c, 0xce, 0x1d, + 0x10, 0x1d, 0x33, 0x1d, 0x68, 0x1d, 0x80, 0x1d, 0x8f, 0x1d, 0xc9, 0x1e, + 0x4f, 0x1e, 0x7a, 0x1e, 0xfd, 0x1f, 0x70, 0x1f, 0xaa, 0x20, 0x6b, 0x20, + 0x79, 0x20, 0x9b, 0x21, 0x18, 0x21, 0xa1, 0x22, 0x09, 0x22, 0x4b, 0x22, + 0x8c, 0x22, 0xce, 0x23, 0x14, 0x23, 0x80, 0x23, 0xd9, 0x24, 0x75, 0x24, + 0xb8, 0x24, 0xe8, 0x25, 0x18, 0x25, 0x48, 0x25, 0x7c, 0x25, 0x9d, 0x25, + 0xbc, 0x25, 0xdb, 0x25, 0xfe, 0x26, 0x5f, 0x26, 0xc0, 0x27, 0x21, 0x27, + 0x82, 0x27, 0xe7, 0x28, 0x73, 0x29, 0x07, 0x29, 0x48, 0x29, 0x89, 0x29, + 0xca, 0x2a, 0x0f, 0x2a, 0x47, 0x2a, 0x7f, 0x2a, 0xb5, 0x2a, 0xee, 0x2b, + 0x8d, 0x2c, 0x2a, 0x2c, 0xc8, 0x2d, 0x6a, 0x2e, 0x32, 0x2e, 0xe7, 0x2f, + 0x71, 0x2f, 0xdf, 0x30, 0x4d, 0x30, 0xbb, 0x31, 0x2d, 0x31, 0x4f, 0x31, + 0x6e, 0x31, 0x8d, 0x31, 0xb0, 0x32, 0x17, 0x32, 0x5f, 0x32, 0xa7, 0x32, + 0xef, 0x33, 0x3b, 0x33, 0xaf, 0x34, 0x2f, 0x34, 0x6c, 0x34, 0xa7, 0x34, + 0xe2, 0x35, 0x21, 0x35, 0x75, 0x35, 0xad, 0x36, 0x1f, 0x36, 0x65, 0x36, + 0xb9, 0x37, 0x3b, 0x37, 0x57, 0x37, 0xa7, 0x38, 0x06, 0x38, 0x16, 0x38, + 0x24, 0x38, 0x4f, 0x38, 0x5e, 0x38, 0x8f, 0x38, 0xb0, 0x38, 0xf2, 0x39, + 0x19, 0x39, 0x97, 0x39, 0xec, 0x3a, 0x84, 0x3b, 0x19, 0x3b, 0xb1, 0x3b, + 0xb3, 0x3b, 0xc5, 0x3b, 0xdc, 0x3c, 0x20, 0x7c, 0x0e, 0x7c, 0x0e, 0x7c, + 0xf7, 0x64, 0xf9, 0x6d, 0x15, 0x38, 0xfb, 0xe6, 0x06, 0xa1, 0xfb, 0x73, + 0xb2, 0x8b, 0xa1, 0xf7, 0x73, 0x05, 0xf7, 0xe6, 0x07, 0xfd, 0x05, 0x04, + 0x37, 0x23, 0xdf, 0x06, 0xf3, 0x07, 0x0e, 0xc9, 0xbf, 0xf9, 0x59, 0x15, + 0x8b, 0xfb, 0x03, 0xa6, 0xfb, 0x1a, 0xb2, 0x8b, 0xa6, 0xf7, 0x1a, 0x8b, + 0xf7, 0x03, 0x2e, 0x8b, 0x05, 0xf7, 0x34, 0x16, 0x8b, 0xfb, 0x03, 0xa6, + 0xfb, 0x1a, 0xb2, 0x8b, 0xa6, 0xf7, 0x1a, 0x8b, 0xf7, 0x03, 0x2e, 0x8b, + 0x05, 0x0e, 0xf8, 0x79, 0xf9, 0x4d, 0x15, 0x3e, 0x8b, 0x68, 0xfb, 0x58, + 0xfb, 0x11, 0x8b, 0xaf, 0xf7, 0x58, 0x3f, 0x8b, 0x67, 0xfb, 0x58, 0xfb, + 0x0d, 0x8b, 0x8b, 0x47, 0xf7, 0x00, 0x8b, 0x6c, 0xfb, 0x42, 0xfb, 0x06, + 0x8b, 0x8b, 0x47, 0xf0, 0x8b, 0x65, 0xfb, 0x67, 0xd7, 0x8b, 0x05, 0xb2, + 0xf7, 0x67, 0xf7, 0x10, 0x8b, 0x65, 0xfb, 0x67, 0xd7, 0x8b, 0xb2, 0xf7, + 0x67, 0xf7, 0x09, 0x8b, 0x8b, 0xcf, 0x22, 0x8b, 0xaa, 0xf7, 0x42, 0xf5, + 0x8b, 0x8b, 0xcf, 0x2e, 0x8b, 0xaf, 0xf7, 0x58, 0x05, 0xfb, 0x11, 0xfb, + 0x9c, 0x15, 0x6c, 0xfb, 0x42, 0xfb, 0x11, 0x8b, 0xab, 0xf7, 0x42, 0xf7, + 0x10, 0x8b, 0x05, 0x0e, 0xf7, 0x87, 0xf9, 0x96, 0x15, 0x55, 0x07, 0xfb, + 0x14, 0x7b, 0x46, 0x45, 0x8b, 0xfb, 0x06, 0x8b, 0x4c, 0xa3, 0x5a, 0xba, + 0x69, 0xa5, 0x78, 0xa6, 0x80, 0xd4, 0x75, 0x08, 0xfb, 0xa4, 0x07, 0x5e, + 0x91, 0x65, 0x9f, 0x74, 0xaa, 0x7c, 0xa2, 0x87, 0x9c, 0x85, 0xcc, 0x08, + 0x3c, 0x06, 0x84, 0xfb, 0x1f, 0xd7, 0x38, 0xf7, 0x21, 0x82, 0x08, 0x24, + 0xc6, 0xf2, 0x07, 0xc1, 0x8f, 0xb0, 0x96, 0xac, 0x9f, 0xc5, 0xaf, 0xad, + 0xd0, 0x8b, 0xd9, 0x8b, 0xd2, 0x70, 0xbd, 0x51, 0xac, 0x71, 0x9a, 0x7e, + 0x90, 0x2f, 0xa7, 0x08, 0xf7, 0x8d, 0x07, 0xce, 0x88, 0xba, 0x58, 0x8c, + 0x42, 0x08, 0xda, 0x06, 0x8b, 0xf7, 0x06, 0x42, 0xd5, 0xfb, 0x0d, 0x94, + 0x08, 0xc1, 0x50, 0x07, 0xfc, 0x01, 0x04, 0x3c, 0xa0, 0x66, 0xb2, 0x8b, + 0xc8, 0x8b, 0xcd, 0xb5, 0xb6, 0xd5, 0x95, 0x08, 0xfb, 0x84, 0x07, 0xc6, + 0x2b, 0x15, 0xf1, 0x6d, 0xab, 0x6d, 0x8b, 0x49, 0x8b, 0x64, 0x7c, 0x68, + 0x70, 0x71, 0x73, 0x74, 0x72, 0x82, 0x60, 0x86, 0x08, 0xf7, 0x9b, 0x07, + 0x0e, 0xf8, 0xe8, 0xf7, 0x5b, 0xf9, 0x41, 0x15, 0x2e, 0x3e, 0x3e, 0x2d, + 0x2d, 0xd8, 0x3e, 0xe9, 0xe8, 0xd8, 0xd8, 0xe7, 0x1f, 0xec, 0x40, 0xd7, + 0x2b, 0x1e, 0x45, 0x04, 0xc4, 0xb8, 0x5e, 0x52, 0x54, 0x5d, 0x5e, 0x54, + 0x53, 0x5d, 0xb9, 0xc2, 0xc3, 0xb9, 0xb8, 0xc2, 0x1f, 0xf8, 0x2e, 0xe9, + 0x15, 0xfc, 0x1f, 0xfd, 0x6d, 0xcd, 0x8b, 0xf8, 0x1f, 0xf9, 0x6d, 0x49, + 0x8b, 0x05, 0xda, 0xfc, 0x17, 0x15, 0x2e, 0x3e, 0x3e, 0x2e, 0x1f, 0x2d, + 0xd8, 0x3e, 0xe9, 0xe7, 0xd9, 0xd8, 0xe7, 0xeb, 0x40, 0xd7, 0x2b, 0x1e, + 0x45, 0x04, 0xc4, 0xb8, 0x5e, 0x52, 0x55, 0x5d, 0x5e, 0x54, 0x53, 0x5d, + 0xb8, 0xc3, 0xc2, 0xb9, 0xb8, 0xc2, 0x1f, 0x0e, 0xf8, 0x0a, 0xf8, 0x81, + 0xf7, 0xe2, 0x15, 0x8c, 0x67, 0x7f, 0x5b, 0x77, 0x68, 0x08, 0xfb, 0x19, + 0xf7, 0x37, 0x05, 0xf3, 0xc6, 0xad, 0xb6, 0x8b, 0xd3, 0x08, 0xe7, 0x47, + 0xcc, 0x2c, 0x2c, 0x3f, 0x46, 0x33, 0x1e, 0x8b, 0x5c, 0x9e, 0x65, 0xc9, + 0x3d, 0x08, 0xfb, 0x10, 0x43, 0x65, 0x59, 0x8b, 0x30, 0x8b, 0xfb, 0x0c, + 0xdd, 0x3c, 0xf7, 0x0f, 0x8b, 0xbc, 0x8b, 0xba, 0x98, 0xaf, 0xa2, 0xa0, + 0x98, 0x9d, 0x9a, 0xb1, 0xb0, 0x08, 0xc9, 0x3d, 0xf7, 0x01, 0x8b, 0xfb, + 0x0e, 0xf7, 0x2b, 0x05, 0xb0, 0xc4, 0xa0, 0xcd, 0x8b, 0xc7, 0x08, 0x3b, + 0x06, 0xfb, 0x64, 0xec, 0x15, 0x4e, 0xd1, 0x82, 0x9c, 0x8b, 0xae, 0x08, + 0xbf, 0xad, 0xad, 0xbf, 0xbd, 0xb0, 0x67, 0x5a, 0x1e, 0x8b, 0x5e, 0x72, + 0x6e, 0x3d, 0x5a, 0x08, 0xf7, 0x19, 0xfb, 0xba, 0x15, 0x53, 0x50, 0x60, + 0x74, 0x57, 0x8b, 0x43, 0x8b, 0x50, 0xc5, 0x8b, 0xd1, 0x8b, 0xc3, 0xaa, + 0xb3, 0xe6, 0xc5, 0x08, 0xf7, 0x34, 0xfb, 0x5c, 0x05, 0x0e, 0x44, 0xcc, + 0xf9, 0x6d, 0x15, 0x23, 0xbb, 0x07, 0x8c, 0x51, 0x7d, 0x70, 0x68, 0x86, + 0x08, 0x65, 0x07, 0xc7, 0x90, 0xac, 0xb9, 0x8b, 0xdb, 0x08, 0xf0, 0x2e, + 0x07, 0x0e, 0xb3, 0xf7, 0x80, 0xf9, 0x6d, 0x15, 0x27, 0xfb, 0x17, 0x4c, + 0xfb, 0x4a, 0x8b, 0xfb, 0x31, 0x8b, 0xfb, 0x32, 0xca, 0xfb, 0x4a, 0xef, + 0xfb, 0x17, 0x08, 0xc2, 0x06, 0x33, 0xf7, 0x23, 0x5a, 0xf7, 0x3c, 0x8b, + 0xf7, 0x34, 0x8b, 0xf7, 0x33, 0xbc, 0xf7, 0x3d, 0xe3, 0xf7, 0x22, 0x08, + 0x54, 0x06, 0x0e, 0xb3, 0xe8, 0xfb, 0x68, 0x15, 0xef, 0xf7, 0x17, 0xca, + 0xf7, 0x4a, 0x8b, 0xf7, 0x31, 0x8b, 0xf7, 0x32, 0x4c, 0xf7, 0x4a, 0x27, + 0xf7, 0x17, 0x08, 0x54, 0x06, 0xe3, 0xfb, 0x23, 0xbc, 0xfb, 0x3c, 0x8b, + 0xfb, 0x34, 0x8b, 0xfb, 0x33, 0x5a, 0xfb, 0x3d, 0x33, 0xfb, 0x22, 0x08, + 0xc2, 0x06, 0x0e, 0xeb, 0xf7, 0x34, 0xf9, 0x6d, 0x15, 0x90, 0xfb, 0x04, + 0x21, 0xb1, 0x78, 0x50, 0xf7, 0x00, 0x6d, 0x46, 0x32, 0xbd, 0x67, 0xca, + 0xe8, 0xc9, 0x2e, 0xbe, 0xaf, 0x45, 0xe4, 0xf7, 0x00, 0xa9, 0x78, 0xc6, + 0x21, 0x65, 0x90, 0xf7, 0x04, 0x4c, 0x8b, 0x05, 0x0e, 0xf7, 0xb7, 0xf8, + 0xaa, 0xf7, 0x9f, 0x15, 0xfb, 0x63, 0xf7, 0x63, 0x45, 0xfb, 0x63, 0xfb, + 0x63, 0x45, 0xf7, 0x63, 0xfb, 0x63, 0xd1, 0xf7, 0x63, 0xf7, 0x63, 0xd1, + 0x06, 0x0e, 0x7c, 0xe2, 0xf3, 0x15, 0x23, 0xc7, 0x79, 0x07, 0x8b, 0x46, + 0x7e, 0x77, 0x5c, 0x89, 0x08, 0x65, 0x07, 0xd1, 0xae, 0xb8, 0xe1, 0x1f, + 0xf7, 0x0c, 0x22, 0x07, 0x0e, 0xb3, 0xf7, 0xb0, 0xf7, 0xcc, 0x15, 0xfb, + 0x82, 0x43, 0xf7, 0x82, 0xd3, 0x06, 0x0e, 0x7c, 0xf7, 0x53, 0xf3, 0x15, + 0x23, 0x23, 0xf3, 0xf3, 0x06, 0x0e, 0x7c, 0xf7, 0x79, 0xf9, 0x6d, 0x15, + 0xfb, 0x81, 0xfd, 0x81, 0xc2, 0x8b, 0xf7, 0x81, 0xf9, 0x81, 0x54, 0x8b, + 0x05, 0x0e, 0xf7, 0xa7, 0xf9, 0x59, 0x15, 0x49, 0x8b, 0x4f, 0x6e, 0x66, + 0x5a, 0x5d, 0x4d, 0x74, 0x2c, 0x8b, 0xfb, 0x17, 0x08, 0xfb, 0x83, 0xdb, + 0xfb, 0x13, 0xf7, 0x2c, 0xf7, 0x2a, 0xdd, 0xf7, 0x13, 0xf7, 0x7d, 0x1e, + 0x8b, 0xf7, 0x1e, 0x75, 0xe7, 0x5c, 0xcb, 0x66, 0xbd, 0x50, 0xa7, 0x48, + 0x8b, 0x08, 0x3d, 0x04, 0xea, 0xba, 0x2b, 0xfb, 0x52, 0xfb, 0x5d, 0x5d, + 0x2d, 0x29, 0x2e, 0x5c, 0xed, 0xf7, 0x56, 0xf7, 0x56, 0xba, 0xea, 0xea, + 0x1f, 0x0e, 0xf7, 0x97, 0xf8, 0x8d, 0x15, 0xfc, 0x8d, 0xe3, 0xf9, 0x59, + 0x51, 0x07, 0x6c, 0xfb, 0x01, 0x77, 0x7c, 0xfb, 0x1c, 0x7a, 0x08, 0x4c, + 0xf7, 0x31, 0x07, 0x0e, 0xf8, 0x8e, 0xe2, 0x15, 0xfc, 0x09, 0x06, 0x94, + 0xc5, 0xab, 0xb0, 0xe2, 0xbe, 0x08, 0xef, 0xc1, 0x05, 0xee, 0xc1, 0xbe, + 0xd4, 0x8b, 0xe2, 0x8b, 0xc6, 0x73, 0xc2, 0x61, 0xb1, 0x61, 0xb1, 0x57, + 0x9d, 0x48, 0x8b, 0x31, 0x8b, 0x48, 0x6b, 0x64, 0x4f, 0x72, 0x65, 0x80, + 0x5f, 0x89, 0x43, 0x08, 0xe3, 0x06, 0x8e, 0xbb, 0x91, 0xa8, 0x97, 0xa2, + 0xa2, 0xb6, 0xb9, 0xa5, 0xc0, 0x8b, 0xdb, 0x8b, 0xc7, 0x52, 0x8b, 0x3f, + 0x8b, 0x53, 0x6a, 0x5b, 0x4c, 0x67, 0x08, 0x2f, 0x57, 0x05, 0xfb, 0x28, + 0x37, 0x60, 0x48, 0x83, 0xfb, 0x30, 0x08, 0xf8, 0x6c, 0xe2, 0x06, 0x0e, + 0xf7, 0x71, 0xf7, 0xd9, 0x15, 0x96, 0x8b, 0xb0, 0x8c, 0x05, 0xec, 0xbd, + 0x5f, 0x36, 0x32, 0x54, 0x56, 0x2f, 0x1f, 0x2b, 0x8b, 0x5c, 0xbb, 0x85, + 0xf2, 0x08, 0x33, 0x06, 0x8f, 0x52, 0x95, 0x66, 0x9c, 0x6b, 0xaf, 0x47, + 0xd1, 0x68, 0xec, 0x8b, 0xf7, 0x26, 0x8b, 0xe9, 0xe2, 0x8b, 0xf7, 0x1a, + 0x8b, 0xe5, 0x68, 0xbd, 0x36, 0xa8, 0x08, 0xcd, 0xa5, 0xac, 0xbd, 0x8b, + 0xd2, 0x8b, 0xf7, 0x0e, 0x3a, 0xd4, 0xfb, 0x1b, 0x8b, 0xfb, 0x23, 0x8b, + 0x3f, 0x3d, 0x88, 0xfb, 0x2b, 0x08, 0xe3, 0x06, 0x8c, 0xb6, 0x8f, 0xa3, + 0x96, 0xa1, 0x9f, 0xb2, 0xb7, 0xa3, 0xc2, 0x8b, 0xd9, 0x8b, 0xba, 0x5d, + 0x8b, 0x40, 0x8b, 0x59, 0x79, 0x6d, 0x64, 0x7b, 0x73, 0x81, 0x6c, 0x87, + 0x4d, 0x8a, 0x08, 0x40, 0x07, 0x0e, 0xf7, 0xdb, 0xf7, 0x3e, 0x15, 0xfb, + 0x3e, 0xe3, 0x07, 0xf7, 0x3e, 0xf4, 0xda, 0x22, 0x07, 0xf8, 0x60, 0x4a, + 0x07, 0xfb, 0xd6, 0xfc, 0x52, 0x05, 0x2e, 0x07, 0xf7, 0xbf, 0x06, 0xda, + 0x04, 0xfb, 0x72, 0x8b, 0xf7, 0x72, 0xf7, 0xca, 0x8b, 0xfb, 0xca, 0x05, + 0x0e, 0xf8, 0x70, 0xf9, 0x59, 0x15, 0xfc, 0x02, 0x8b, 0x56, 0xfc, 0x16, + 0xdc, 0x8b, 0x05, 0xb4, 0xbc, 0xad, 0x9c, 0xc2, 0x8b, 0x08, 0xea, 0xc7, + 0x4a, 0x22, 0x25, 0x50, 0x4d, 0x2b, 0x1f, 0x3e, 0x8b, 0x5c, 0xb2, 0x76, + 0xdb, 0x08, 0x33, 0x06, 0x97, 0x51, 0x95, 0x6f, 0xa0, 0x71, 0xb3, 0x55, + 0xd3, 0x6c, 0xdb, 0x8b, 0x08, 0xf7, 0x23, 0xef, 0xf3, 0xf7, 0x2a, 0xf7, + 0x20, 0x2e, 0xeb, 0xfb, 0x1c, 0x1f, 0x59, 0x8b, 0x63, 0x7e, 0x62, 0x6d, + 0x08, 0xa7, 0xf7, 0x5a, 0xf7, 0xbb, 0x8b, 0x8b, 0xe2, 0x05, 0x0e, 0xf8, + 0x86, 0xf8, 0xa0, 0x15, 0x7a, 0xf7, 0x08, 0x3f, 0xd0, 0xfb, 0x00, 0x8b, + 0x3d, 0x8b, 0x45, 0x65, 0x61, 0x4c, 0x5f, 0x46, 0x77, 0x34, 0x8b, 0xfb, + 0x15, 0x8b, 0xfb, 0x0b, 0x9d, 0x3f, 0xb5, 0x4c, 0xb1, 0x52, 0xc9, 0x6c, + 0xd9, 0x8b, 0x08, 0xf7, 0x1b, 0xec, 0xef, 0xf7, 0x1f, 0xf7, 0x18, 0x31, + 0xe8, 0xfb, 0x13, 0x1f, 0x45, 0x8b, 0x54, 0x70, 0x65, 0x57, 0x8c, 0xf7, + 0x41, 0xc3, 0xeb, 0xf0, 0x8b, 0xc9, 0x8b, 0xb6, 0x64, 0x99, 0x47, 0x08, + 0xe3, 0x06, 0xfb, 0x69, 0xfb, 0x35, 0x15, 0xe0, 0xc0, 0x50, 0x2c, 0x32, + 0x4f, 0x4a, 0x3a, 0x39, 0x4d, 0xcf, 0xe6, 0xe3, 0xc7, 0xc8, 0xe2, 0x1f, + 0x0e, 0xf8, 0x9c, 0xf9, 0x59, 0x15, 0xfc, 0x6e, 0x34, 0xf8, 0x13, 0x06, + 0xfb, 0x3d, 0xfb, 0x85, 0x46, 0xfb, 0x28, 0x56, 0xfb, 0x7d, 0x08, 0xe9, + 0x06, 0xb2, 0xf7, 0x77, 0xe4, 0xf7, 0x57, 0xf7, 0x34, 0xf7, 0x69, 0x08, + 0xd5, 0x07, 0x0e, 0xf8, 0x1b, 0xf8, 0x09, 0x15, 0xd4, 0xb7, 0xa3, 0xaf, + 0x8b, 0xce, 0x08, 0xf7, 0x03, 0x34, 0xd9, 0xfb, 0x12, 0xfb, 0x11, 0x33, + 0x3d, 0xfb, 0x03, 0x1e, 0x8b, 0x49, 0xa3, 0x67, 0xd3, 0x5e, 0x08, 0x3a, + 0x64, 0x63, 0x50, 0x8b, 0x3d, 0x08, 0xfb, 0x16, 0xed, 0x31, 0xf7, 0x20, + 0xf7, 0x20, 0xed, 0xe5, 0xf7, 0x15, 0x1e, 0x8b, 0xda, 0x63, 0xc6, 0x39, + 0xb2, 0x08, 0xfb, 0x08, 0xf7, 0x96, 0x15, 0xd6, 0xbb, 0x5f, 0x46, 0x49, + 0x5a, 0x5f, 0x41, 0x41, 0x5a, 0xb7, 0xce, 0x1f, 0xcf, 0xbc, 0xb7, 0xd5, + 0x1e, 0xfb, 0xbd, 0x04, 0xe3, 0xc7, 0x53, 0x38, 0x37, 0x4f, 0x53, 0x31, + 0x35, 0x4f, 0xc4, 0xde, 0x1f, 0xde, 0xc7, 0xc3, 0xe3, 0x1e, 0x0e, 0xc0, + 0xf7, 0x36, 0x15, 0x9c, 0xfb, 0x08, 0xd7, 0x46, 0xf7, 0x00, 0x8b, 0xd9, + 0x8b, 0xd2, 0xb1, 0xb4, 0xca, 0xb8, 0xd0, 0x9f, 0xe2, 0x8b, 0xf7, 0x15, + 0x8b, 0xf7, 0x0b, 0x79, 0xd7, 0x61, 0xca, 0x64, 0xc4, 0x4d, 0xaa, 0x3d, + 0x8b, 0x08, 0xfb, 0x1b, 0x2a, 0x27, 0xfb, 0x1f, 0xfb, 0x18, 0xe5, 0x2e, + 0xf7, 0x14, 0x1f, 0xce, 0x8b, 0xbc, 0xa3, 0xb9, 0xc2, 0x8a, 0xfb, 0x41, + 0x53, 0x2b, 0x26, 0x8b, 0x4d, 0x8b, 0x60, 0xb2, 0x7d, 0xcf, 0x08, 0x33, + 0x06, 0xf7, 0x6c, 0xf8, 0x6a, 0x15, 0xdd, 0xc9, 0x47, 0x2f, 0x34, 0x4e, + 0x4d, 0x35, 0x36, 0x56, 0xc6, 0xea, 0xe5, 0xc7, 0xcc, 0xdc, 0x1f, 0x0e, + 0x7c, 0xf7, 0x6a, 0xf3, 0x15, 0x23, 0x23, 0xf3, 0xf3, 0x06, 0xf8, 0x38, + 0x04, 0x23, 0x23, 0xf3, 0xf3, 0x06, 0x0e, 0x7c, 0xf7, 0x6b, 0xf8, 0xa0, + 0x15, 0x23, 0x23, 0xf3, 0xf3, 0x06, 0x22, 0xfc, 0x38, 0x15, 0x23, 0xc7, + 0x79, 0x07, 0x8b, 0x46, 0x7e, 0x77, 0x5c, 0x89, 0x08, 0x65, 0x07, 0xd1, + 0xae, 0xb8, 0xe1, 0x1f, 0xf7, 0x0c, 0x22, 0x07, 0x0e, 0xf7, 0xb7, 0xb8, + 0xf7, 0x5a, 0x15, 0xf8, 0x7d, 0xfb, 0x63, 0x8b, 0xda, 0xfc, 0x1e, 0xf7, + 0x38, 0xf8, 0x1e, 0xf7, 0x35, 0x8b, 0xda, 0xfc, 0x7d, 0xfb, 0x63, 0x8b, + 0x46, 0x05, 0x0e, 0xf7, 0xb7, 0xf8, 0xaa, 0xf7, 0xf5, 0x15, 0xfc, 0x78, + 0x45, 0xf8, 0x78, 0xd1, 0x06, 0xfb, 0x40, 0x04, 0xfc, 0x78, 0x45, 0xf8, + 0x78, 0xd1, 0x06, 0x0e, 0xf7, 0xb7, 0xf8, 0xaf, 0xf7, 0x9f, 0x15, 0xfc, + 0x7d, 0xf7, 0x63, 0x8b, 0x3c, 0xf8, 0x1e, 0xfb, 0x38, 0xfc, 0x1e, 0xfb, + 0x35, 0x8b, 0x3c, 0xf8, 0x7d, 0xf7, 0x63, 0x8b, 0xd0, 0x05, 0x0e, 0xf7, + 0xde, 0xf7, 0x5b, 0x15, 0xba, 0x07, 0x8b, 0xb7, 0x96, 0x9c, 0xcf, 0xca, + 0xd6, 0xcf, 0xa4, 0xb8, 0x8b, 0xcd, 0x08, 0xf7, 0x09, 0x38, 0xd6, 0xfb, + 0x16, 0xfb, 0x24, 0x40, 0x3b, 0xfb, 0x2e, 0x1e, 0xe0, 0x06, 0x8b, 0xb9, + 0x90, 0xa7, 0x97, 0xa3, 0x9e, 0xb0, 0xb3, 0xa0, 0xc0, 0x8b, 0xd8, 0x8b, + 0xbe, 0x5d, 0x8b, 0x47, 0x8b, 0x5d, 0x75, 0x64, 0x56, 0x5c, 0x50, 0x56, + 0x8b, 0x8b, 0x7a, 0x74, 0x76, 0x6f, 0x84, 0x74, 0x8b, 0x67, 0x08, 0x54, + 0xe5, 0x07, 0x2c, 0x04, 0x31, 0x23, 0xe5, 0xf3, 0x06, 0x0e, 0xf9, 0x66, + 0xf9, 0x2d, 0xf8, 0x89, 0x15, 0x75, 0x49, 0x05, 0x72, 0xc4, 0x61, 0xa9, + 0x54, 0x8b, 0x08, 0xfb, 0x1a, 0xfb, 0x0f, 0xfb, 0x18, 0xfb, 0x25, 0x23, + 0xd1, 0x3c, 0xe8, 0x1f, 0xc0, 0x8b, 0xb6, 0xa1, 0xb9, 0xbd, 0x08, 0x94, + 0x58, 0xb1, 0x71, 0xca, 0x8b, 0xd5, 0x8b, 0xc8, 0xa8, 0xbe, 0xc7, 0xc2, + 0xcb, 0xaa, 0xdc, 0x8b, 0xd9, 0x8b, 0xf7, 0x5f, 0xfb, 0x55, 0xf7, 0x3d, + 0xfb, 0x7d, 0x8b, 0xfb, 0x0b, 0x8b, 0xfb, 0x12, 0x5a, 0x33, 0x3b, 0x29, + 0x32, 0x4f, 0xfb, 0x1a, 0x8b, 0xfb, 0x17, 0x08, 0xfb, 0x72, 0xf7, 0x5e, + 0xfb, 0x46, 0xf7, 0x91, 0x1e, 0xd5, 0x8b, 0xdb, 0x9a, 0xd3, 0xa6, 0x08, + 0x6f, 0xce, 0x05, 0x39, 0x74, 0x52, 0x82, 0x55, 0x8b, 0x08, 0xfb, 0x68, + 0xfb, 0x37, 0xf7, 0x27, 0xf7, 0x53, 0xf7, 0x66, 0xf7, 0x4a, 0xf7, 0x49, + 0xf7, 0x67, 0xf7, 0x53, 0xf7, 0x35, 0xfb, 0x20, 0xfb, 0x3b, 0xfb, 0x09, + 0x38, 0xfb, 0x05, 0x36, 0x70, 0x74, 0x9f, 0xa3, 0x1f, 0x8b, 0x94, 0x8f, + 0x9d, 0x93, 0xa2, 0x08, 0xe5, 0xf7, 0xac, 0x05, 0x38, 0x06, 0xfb, 0x2a, + 0x60, 0x15, 0xc3, 0x8b, 0xb4, 0x61, 0x88, 0x55, 0x89, 0x59, 0x70, 0x37, + 0x72, 0x66, 0x08, 0x6f, 0x62, 0x66, 0x73, 0x66, 0x8b, 0x08, 0x54, 0x5f, + 0xbf, 0xcd, 0xf7, 0x04, 0xd8, 0xf1, 0xdf, 0x1f, 0x0e, 0xf8, 0x0a, 0xf8, + 0x6e, 0xf7, 0x6f, 0x15, 0xd6, 0xfb, 0x6f, 0xf3, 0x8b, 0xfb, 0x94, 0xf9, + 0x6d, 0xfb, 0x0c, 0x8b, 0xfb, 0x98, 0xfd, 0x6d, 0xee, 0x8b, 0xd8, 0xf7, + 0x6f, 0xf7, 0xad, 0x8b, 0x05, 0x71, 0xd9, 0x15, 0xfb, 0x7c, 0x8b, 0xf7, + 0x0c, 0xf7, 0xe0, 0xf7, 0x04, 0xfb, 0xe0, 0x05, 0x0e, 0xf8, 0x0a, 0xda, + 0x16, 0xf7, 0xdd, 0x06, 0xd0, 0x8b, 0xbe, 0x9e, 0xb2, 0xb5, 0xaf, 0xb1, + 0x9f, 0xbf, 0x8b, 0xc4, 0x8b, 0xe3, 0x63, 0xc0, 0x2e, 0xaf, 0x08, 0xcd, + 0xaa, 0xae, 0xc1, 0x8b, 0xd5, 0x8b, 0xc0, 0x77, 0xba, 0x65, 0xad, 0x65, + 0xae, 0x59, 0x9b, 0x45, 0x8b, 0x08, 0xfb, 0xbc, 0x06, 0xfd, 0x6d, 0x07, + 0xe8, 0xf8, 0x33, 0x15, 0xf7, 0x7c, 0xf7, 0x48, 0x07, 0xbf, 0x8b, 0xa8, + 0x84, 0xa4, 0x78, 0xa5, 0x77, 0x99, 0x6d, 0x8b, 0x63, 0x8b, 0x64, 0x7d, + 0x6c, 0x71, 0x77, 0x72, 0x78, 0x6e, 0x84, 0x57, 0x8b, 0x08, 0xfb, 0x48, + 0x06, 0xfb, 0xe1, 0x04, 0xf7, 0x8f, 0xf7, 0x77, 0x07, 0xb8, 0x8b, 0xa9, + 0x80, 0xa1, 0x73, 0x08, 0xa1, 0x74, 0x97, 0x6b, 0x8b, 0x67, 0x8b, 0x68, + 0x7f, 0x6b, 0x75, 0x74, 0x75, 0x73, 0x6d, 0x80, 0x5e, 0x8b, 0x08, 0xfb, + 0x77, 0x06, 0x0e, 0xf8, 0x41, 0xf9, 0x2a, 0xf8, 0x8b, 0x15, 0x6e, 0xf7, + 0x34, 0x2f, 0xd9, 0xfb, 0x34, 0x8b, 0x29, 0x8b, 0x3c, 0x6c, 0x55, 0x4f, + 0x49, 0x43, 0x67, 0x23, 0x8b, 0xfb, 0x0a, 0x8b, 0xfb, 0x0c, 0xb0, 0x24, + 0xd0, 0x44, 0xc3, 0x51, 0xd3, 0x70, 0xea, 0x8b, 0xf7, 0x46, 0x8b, 0xef, + 0xeb, 0xa1, 0xf7, 0x55, 0x08, 0x2b, 0x06, 0x83, 0x59, 0x81, 0x69, 0x7c, + 0x6e, 0x6d, 0x4f, 0x4d, 0x69, 0x3d, 0x8b, 0x08, 0xfb, 0x25, 0x2f, 0xf7, + 0x08, 0xf7, 0x4a, 0xf7, 0x4f, 0xe3, 0xf7, 0x07, 0xf7, 0x21, 0x1f, 0xc6, + 0x8b, 0xc2, 0x79, 0xa9, 0x6f, 0xa6, 0x72, 0x9a, 0x6c, 0x96, 0x55, 0x08, + 0xea, 0x06, 0x0e, 0xf8, 0x41, 0xe4, 0x16, 0xf7, 0xad, 0x06, 0xf7, 0x4c, + 0xf7, 0x05, 0xf7, 0x1e, 0xf7, 0x77, 0xf7, 0x76, 0xfb, 0x04, 0xf7, 0x1e, + 0xfb, 0x4d, 0x1f, 0xfb, 0xad, 0xfd, 0x6d, 0x06, 0xe8, 0xdd, 0x15, 0xf8, + 0xc9, 0xf7, 0x40, 0x07, 0xf7, 0x24, 0xd7, 0x2a, 0xfb, 0x4e, 0xfb, 0x4c, + 0x3f, 0x29, 0xfb, 0x24, 0x1f, 0xfb, 0x40, 0x06, 0x0e, 0xf8, 0x0a, 0xf7, + 0x4b, 0xf7, 0xe0, 0x15, 0xf8, 0x21, 0xdd, 0xfc, 0x21, 0xf7, 0x7d, 0xf8, + 0x30, 0xdd, 0xfc, 0x8d, 0xfd, 0x6d, 0xf8, 0x9f, 0xdd, 0xfc, 0x42, 0xf7, + 0x8e, 0x06, 0x0e, 0xf7, 0xd2, 0xf7, 0x4b, 0xf7, 0xe0, 0x15, 0xf7, 0xf0, + 0xdd, 0xfb, 0xf0, 0xf7, 0x7d, 0xf8, 0x20, 0xdd, 0xfc, 0x7d, 0xfd, 0x6d, + 0xe8, 0xf7, 0xe0, 0x06, 0x0e, 0xf8, 0x79, 0xf9, 0x59, 0xf8, 0x15, 0x15, + 0xfb, 0xc4, 0x39, 0xf7, 0x72, 0x77, 0x06, 0xfb, 0x16, 0x2b, 0x2d, 0xfb, + 0x19, 0x1e, 0x41, 0x8b, 0x48, 0xa6, 0x60, 0xba, 0x5b, 0xbf, 0x6e, 0xe2, + 0x8b, 0xe5, 0x8b, 0xf7, 0x47, 0xf1, 0xf7, 0x0a, 0xf7, 0x2e, 0x8b, 0xf7, + 0x03, 0x8b, 0xdb, 0x52, 0x9f, 0x2d, 0x08, 0xea, 0x06, 0x71, 0xf7, 0x28, + 0xfb, 0x04, 0xe0, 0xfb, 0x3b, 0x8b, 0x32, 0x8b, 0x43, 0x74, 0x52, 0x5c, + 0x37, 0x45, 0x5b, 0xfb, 0x05, 0x8b, 0xfb, 0x17, 0x8b, 0xfb, 0x74, 0xf7, + 0x1d, 0xfb, 0x30, 0xf7, 0x59, 0x8b, 0xee, 0x8b, 0xda, 0xb0, 0xd2, 0xda, + 0x08, 0xa2, 0x2a, 0xc6, 0x8b, 0x8b, 0xf8, 0x19, 0x05, 0x0e, 0xf8, 0x41, + 0xf8, 0xbb, 0xf7, 0xe0, 0x15, 0xfb, 0xe0, 0xe8, 0xf9, 0x6d, 0x2e, 0xfb, + 0xcf, 0xfc, 0x0b, 0xf7, 0xcf, 0x07, 0x2e, 0xfd, 0x6d, 0xe9, 0xf7, 0xe0, + 0x06, 0xf8, 0x0a, 0x06, 0x0e, 0x7c, 0xf7, 0x56, 0xf9, 0x6d, 0x15, 0x2d, + 0xfd, 0x6d, 0xe9, 0xf9, 0x6d, 0x06, 0x0e, 0xf7, 0x63, 0xf7, 0xe1, 0xf9, + 0x6d, 0x15, 0xfc, 0x95, 0x07, 0x8b, 0x51, 0x85, 0x6a, 0x7a, 0x72, 0x79, + 0x6f, 0x69, 0x7a, 0x66, 0x8b, 0x08, 0x45, 0x64, 0xba, 0xe0, 0x1f, 0xba, + 0x2c, 0x4b, 0x07, 0xfb, 0x0a, 0xd9, 0x40, 0xf7, 0x11, 0xf7, 0x13, 0xda, + 0xda, 0xf7, 0x12, 0x1e, 0xf8, 0xb7, 0x2e, 0x07, 0x0e, 0xf8, 0x0a, 0xf7, + 0x40, 0xf7, 0x93, 0x15, 0xf7, 0x0b, 0xf7, 0x0b, 0xf7, 0x95, 0xfc, 0x0a, + 0xf7, 0x02, 0x8b, 0xfb, 0xc0, 0xf8, 0x44, 0xf7, 0xbd, 0xf7, 0xbd, 0xfb, + 0x0c, 0x8b, 0xfb, 0xff, 0xfc, 0x05, 0x8b, 0xf8, 0x05, 0x2e, 0x8b, 0x8b, + 0xfd, 0x6d, 0xe8, 0x8b, 0x8b, 0xf7, 0x93, 0x05, 0x0e, 0xf7, 0x41, 0xf9, + 0x6d, 0x15, 0x2e, 0xfd, 0x6d, 0xf8, 0x59, 0xdd, 0xfb, 0xfc, 0xf9, 0x1b, + 0x06, 0x0e, 0xf8, 0xb0, 0xf8, 0x68, 0x16, 0xf7, 0x61, 0xf8, 0xf7, 0x8b, + 0xfc, 0xf7, 0xe3, 0x8b, 0x8b, 0xf9, 0x6d, 0xfb, 0x15, 0x8b, 0xfb, 0x68, + 0xfd, 0x0f, 0xfb, 0x6c, 0xf9, 0x0f, 0xfb, 0x15, 0x8b, 0x8b, 0xfd, 0x6d, + 0xe3, 0x8b, 0x8b, 0xf8, 0xf7, 0xf7, 0x63, 0xfc, 0xf7, 0xed, 0x8b, 0x05, + 0x0e, 0xf8, 0x41, 0xf9, 0x1a, 0xf9, 0x6d, 0x15, 0x33, 0xfc, 0xe8, 0x06, + 0xfc, 0x11, 0xf8, 0xe8, 0x26, 0x8b, 0x8b, 0xfd, 0x6d, 0xe3, 0x8b, 0x8b, + 0xf8, 0xe3, 0xf8, 0x0d, 0xfc, 0xe3, 0xf4, 0x8b, 0x8b, 0xf9, 0x6d, 0x05, + 0x0e, 0xf8, 0x79, 0xf8, 0x19, 0xf9, 0x79, 0x15, 0xfb, 0x65, 0xfb, 0x22, + 0xfb, 0x2e, 0xfb, 0x78, 0xfb, 0x78, 0xf7, 0x22, 0xfb, 0x2e, 0xf7, 0x66, + 0x1f, 0xe3, 0x8b, 0xda, 0xa6, 0xc6, 0xbd, 0xda, 0xce, 0xba, 0xf7, 0x05, + 0x8b, 0xf7, 0x0b, 0x08, 0xf7, 0x7f, 0xfb, 0x1f, 0xf7, 0x2d, 0xfb, 0x6a, + 0x1e, 0x39, 0x04, 0xf7, 0x32, 0xf1, 0xfb, 0x0c, 0xfb, 0x4c, 0xfb, 0x44, + 0x22, 0xfb, 0x0c, 0xfb, 0x2e, 0xfb, 0x2f, 0x23, 0xf7, 0x0c, 0xf7, 0x48, + 0xf7, 0x48, 0xf3, 0xf7, 0x0c, 0xf7, 0x2e, 0x1f, 0x0e, 0xf8, 0x0a, 0xf7, + 0x4c, 0xf7, 0xc9, 0x15, 0xf7, 0x79, 0x06, 0xc4, 0x8b, 0xb8, 0x9c, 0xb2, + 0xae, 0xb7, 0xb3, 0x9e, 0xba, 0x8b, 0xce, 0x08, 0xf7, 0x1d, 0x3a, 0xd8, + 0xfb, 0x24, 0x1e, 0xfb, 0xc1, 0xfd, 0x6d, 0xe8, 0xf7, 0xc9, 0x06, 0xdd, + 0x04, 0xf7, 0x94, 0xf7, 0x56, 0x07, 0xe4, 0xc0, 0x5b, 0x3b, 0x3b, 0x56, + 0x5b, 0x32, 0x1f, 0xfb, 0x56, 0x06, 0x0e, 0xf8, 0x79, 0xf9, 0x71, 0x8a, + 0x15, 0x2d, 0xd8, 0x05, 0xd0, 0xd7, 0xad, 0xe9, 0x8b, 0xf7, 0x07, 0x08, + 0xf7, 0x76, 0xfb, 0x22, 0xf7, 0x2e, 0xfb, 0x66, 0xfb, 0x66, 0xfb, 0x22, + 0xfb, 0x2e, 0xfb, 0x78, 0xfb, 0x78, 0xf7, 0x22, 0xfb, 0x2e, 0xf7, 0x66, + 0x1e, 0xd3, 0x8b, 0xc7, 0x9b, 0xc6, 0xae, 0x08, 0xf4, 0x34, 0xba, 0xc5, + 0x05, 0xfb, 0x90, 0xf7, 0x62, 0x15, 0x5d, 0x53, 0xd5, 0x4d, 0x05, 0x60, + 0x77, 0x6a, 0x83, 0x5f, 0x8b, 0x08, 0xfb, 0x2f, 0x24, 0xf7, 0x0c, 0xf7, + 0x48, 0xf7, 0x48, 0xf3, 0xf7, 0x0c, 0xf7, 0x2f, 0xf7, 0x2f, 0xf3, 0xfb, + 0x0c, 0xfb, 0x47, 0x1f, 0x8b, 0x2d, 0x72, 0x42, 0x55, 0x4e, 0x08, 0x32, + 0xd4, 0x05, 0x0e, 0xf8, 0x41, 0xf7, 0x4e, 0xf7, 0xce, 0x15, 0xf7, 0x84, + 0x06, 0xde, 0xb0, 0x63, 0x31, 0x1f, 0x8a, 0x4a, 0x05, 0x8b, 0x5e, 0x93, + 0x5f, 0x98, 0x6d, 0x08, 0xf7, 0x05, 0xa2, 0x06, 0x68, 0xa3, 0x84, 0xa5, + 0x89, 0xec, 0x8a, 0xf7, 0x0c, 0x78, 0xaf, 0x3c, 0xad, 0xdd, 0xb3, 0xac, + 0xbe, 0x8b, 0xde, 0x08, 0xf7, 0x12, 0x3c, 0xd0, 0xfb, 0x23, 0x1e, 0xfb, + 0xe4, 0xfd, 0x6d, 0xe8, 0xf7, 0xce, 0x06, 0xdd, 0x04, 0xf7, 0x8f, 0xf7, + 0x75, 0x07, 0xbf, 0x8b, 0xa9, 0x83, 0xa2, 0x77, 0xa4, 0x76, 0x98, 0x6a, + 0x8b, 0x5f, 0x08, 0x35, 0x5f, 0x64, 0x28, 0x1e, 0xfb, 0x75, 0x06, 0x0e, + 0xf8, 0x0a, 0xf8, 0xe8, 0xf8, 0x97, 0x15, 0x8a, 0xf7, 0x23, 0x29, 0xde, + 0xfb, 0x3c, 0x8b, 0xfb, 0x34, 0x8b, 0x28, 0x39, 0x8b, 0xfb, 0x18, 0x8b, + 0x32, 0xba, 0x53, 0xeb, 0x72, 0x08, 0xf7, 0x49, 0x5b, 0x05, 0xe7, 0x73, + 0xb5, 0x66, 0x8b, 0x52, 0x8b, 0x64, 0x76, 0x63, 0x6c, 0x75, 0x6e, 0x77, + 0x5d, 0x80, 0x50, 0x8b, 0x3c, 0x8b, 0x55, 0x9e, 0x68, 0xb5, 0x70, 0xab, + 0x7f, 0xae, 0x8c, 0xb8, 0x08, 0x33, 0x06, 0x8c, 0x48, 0x98, 0x5f, 0xa8, + 0x63, 0xbd, 0x47, 0xdf, 0x67, 0xf7, 0x03, 0x8b, 0xe2, 0x8b, 0xd2, 0x9f, + 0xba, 0xaf, 0xbc, 0xb2, 0xaa, 0xcc, 0x8b, 0xca, 0x8b, 0xe5, 0x53, 0xcd, + 0x28, 0xa6, 0x08, 0xfb, 0x4b, 0xbc, 0x05, 0x33, 0xa3, 0x6b, 0xa7, 0x8b, + 0xc3, 0x8b, 0xd5, 0xcc, 0xbc, 0xed, 0x8b, 0xf7, 0x08, 0x8b, 0xcc, 0x56, + 0x8c, 0x2c, 0x08, 0xe3, 0x06, 0x0e, 0xf7, 0xd2, 0xf7, 0xf6, 0xf9, 0x1b, + 0x15, 0xf7, 0x83, 0xdd, 0xfc, 0xd0, 0x39, 0xf7, 0x84, 0xfd, 0x1b, 0xe8, + 0xf9, 0x1b, 0x06, 0x0e, 0xf8, 0x41, 0xf8, 0xbc, 0xf9, 0x6d, 0x15, 0xfc, + 0x94, 0x07, 0x29, 0x44, 0x4f, 0xfb, 0x09, 0x1e, 0x55, 0x8b, 0x5f, 0x98, + 0x68, 0xa4, 0x67, 0xa7, 0x7a, 0xb0, 0x8b, 0xc2, 0x08, 0xf8, 0x94, 0x2e, + 0xfc, 0x94, 0x07, 0xfb, 0x28, 0xf5, 0x2f, 0xf7, 0x41, 0xf7, 0x3f, 0xf7, + 0x02, 0xe9, 0xf7, 0x26, 0x1e, 0xf8, 0x94, 0x2e, 0x07, 0x0e, 0xf8, 0x0a, + 0xf8, 0x1c, 0x16, 0xf7, 0x91, 0xf9, 0x6d, 0x28, 0x8b, 0xfb, 0x5e, 0xfc, + 0xfd, 0xfb, 0x6a, 0xf8, 0xfd, 0x27, 0x8b, 0xf7, 0x9a, 0xfd, 0x6d, 0xef, + 0x8b, 0x05, 0x0e, 0xf9, 0x1f, 0xf9, 0x7c, 0x16, 0xf7, 0x4d, 0xf9, 0x6d, + 0x23, 0x8b, 0xfb, 0x1a, 0xfc, 0xe4, 0xfb, 0x3a, 0xf8, 0xe4, 0x27, 0x8b, + 0xfb, 0x36, 0xfc, 0xe4, 0xfb, 0x1d, 0xf8, 0xe4, 0x23, 0x8b, 0xf7, 0x4f, + 0xfd, 0x6d, 0xf1, 0x8b, 0xf7, 0x37, 0xf8, 0xeb, 0xf7, 0x3c, 0xfc, 0xeb, + 0xf1, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0x1b, 0xf8, 0x0a, 0x15, 0xf7, + 0x8a, 0xf7, 0xf7, 0xfb, 0x03, 0x8b, 0xfb, 0x50, 0xfb, 0xb2, 0xfb, 0x4f, + 0xf7, 0xb2, 0xfb, 0x05, 0x8b, 0xf7, 0x86, 0xfb, 0xf7, 0xfb, 0x96, 0xfc, + 0x0a, 0xf7, 0x05, 0x8b, 0xf7, 0x5c, 0xf7, 0xc4, 0xf7, 0x5b, 0xfb, 0xc4, + 0xf7, 0x07, 0x8b, 0xfb, 0x96, 0xf8, 0x0a, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, + 0x17, 0xf7, 0xb2, 0x15, 0xf7, 0xa6, 0xf8, 0x4f, 0xfb, 0x03, 0x8b, 0xfb, + 0x64, 0xfb, 0xf7, 0xfb, 0x6a, 0xf7, 0xf7, 0xfb, 0x07, 0x8b, 0xf7, 0xad, + 0xfc, 0x4f, 0x8b, 0xfb, 0xb2, 0xe8, 0x8b, 0x8b, 0xf7, 0xb2, 0x05, 0x0e, + 0xf7, 0xd2, 0xf8, 0xd9, 0xf9, 0x6d, 0x15, 0xfc, 0xa1, 0x39, 0xf8, 0x2e, + 0x06, 0xfc, 0x4a, 0xfc, 0xc9, 0x8b, 0x39, 0xf8, 0xbf, 0x8b, 0x8b, 0xdd, + 0xfc, 0x4a, 0x8b, 0xf8, 0x48, 0xf8, 0xc7, 0x8b, 0xdf, 0x05, 0x0e, 0x7c, + 0xf7, 0x8e, 0xf9, 0x6d, 0x15, 0xfb, 0x4e, 0xfe, 0x41, 0xf7, 0x4e, 0xd3, + 0x24, 0xf9, 0xb1, 0xf2, 0xd3, 0x06, 0x0e, 0x7c, 0xba, 0xf9, 0x6d, 0x15, + 0x54, 0x8b, 0xf7, 0x81, 0xfd, 0x81, 0xc2, 0x8b, 0xfb, 0x81, 0xf9, 0x81, + 0x05, 0x0e, 0x7c, 0xa2, 0xfb, 0x68, 0x15, 0xf7, 0x4e, 0xfa, 0x41, 0xfb, + 0x4e, 0x43, 0xf2, 0xfd, 0xb1, 0x24, 0x43, 0x06, 0x0e, 0xf7, 0x44, 0xf7, + 0x59, 0xf9, 0x59, 0x15, 0xfb, 0x2d, 0xfc, 0x10, 0xd0, 0x8b, 0xf7, 0x0d, + 0xf7, 0xc0, 0xf7, 0x0e, 0xfb, 0xc0, 0xd0, 0x8b, 0xfb, 0x2f, 0xf8, 0x10, + 0x42, 0x8b, 0x05, 0x0e, 0xf8, 0xd6, 0xfb, 0x12, 0x15, 0xfc, 0xec, 0x59, + 0xf8, 0xec, 0xbd, 0x06, 0x0e, 0x44, 0xf7, 0x32, 0xf8, 0x71, 0x15, 0xf3, + 0x5b, 0x07, 0x8a, 0xc4, 0x9a, 0xa7, 0xad, 0x90, 0x08, 0xb1, 0x07, 0x4f, + 0x86, 0x6a, 0x5c, 0x8b, 0x3c, 0x08, 0x26, 0xe8, 0x07, 0x0e, 0xf8, 0xab, + 0xbc, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x86, 0x8b, 0x08, 0x6e, 0x7b, 0x9a, + 0xa5, 0x1f, 0xf7, 0xc8, 0x07, 0xe8, 0x47, 0xbd, 0xfb, 0x15, 0x1e, 0x3f, + 0x8b, 0x4c, 0x75, 0x68, 0x64, 0x73, 0x70, 0x81, 0x6d, 0x89, 0x57, 0x08, + 0xdf, 0x06, 0x92, 0xcb, 0xb1, 0xa8, 0xd9, 0x8b, 0x08, 0xd6, 0xb5, 0x6f, + 0x59, 0x1f, 0x75, 0x07, 0x8b, 0x68, 0x76, 0x7c, 0x49, 0x83, 0xfb, 0x0a, + 0x7c, 0x79, 0x87, 0x6b, 0x7e, 0x4e, 0x72, 0x6c, 0x5c, 0x8b, 0x47, 0x8b, + 0x2c, 0xcd, 0x4f, 0xf5, 0x8b, 0xcd, 0x8b, 0xc0, 0xa2, 0xc6, 0xc1, 0x91, + 0x56, 0xa5, 0x73, 0xc1, 0x8b, 0x08, 0x9c, 0x8b, 0x98, 0x8d, 0xa6, 0x92, + 0x08, 0xca, 0x07, 0xfb, 0x26, 0xf7, 0x08, 0x15, 0x8b, 0x6f, 0x83, 0x7a, + 0x72, 0x74, 0x69, 0x6c, 0x62, 0x7b, 0x5a, 0x8b, 0x4a, 0x8b, 0x65, 0xaa, + 0x8b, 0xc0, 0x8b, 0xc2, 0xb0, 0xa7, 0xe4, 0x98, 0xe3, 0x97, 0x9d, 0x8f, + 0xa7, 0x98, 0x08, 0x2d, 0x07, 0x0e, 0xc1, 0xf9, 0x6d, 0x15, 0xfd, 0x6d, + 0xd6, 0xce, 0x07, 0xb3, 0x4e, 0xc0, 0x6e, 0xd4, 0x8b, 0x08, 0xf7, 0x1e, + 0xe5, 0xf7, 0x05, 0xf7, 0x42, 0xf7, 0x3e, 0x35, 0xf4, 0xfb, 0x1e, 0x1f, + 0x43, 0x8b, 0x58, 0x70, 0x64, 0x50, 0x08, 0xf7, 0xa8, 0x07, 0x38, 0x06, + 0xf7, 0x79, 0xfb, 0xa0, 0x15, 0xe8, 0xc7, 0x3a, 0xfb, 0x11, 0xfb, 0x0b, + 0x4d, 0x3a, 0x30, 0x33, 0x51, 0xdb, 0xf7, 0x0f, 0xf7, 0x0f, 0xc5, 0xdb, + 0xe3, 0x1f, 0x0e, 0xf7, 0x63, 0xf8, 0x6b, 0xf7, 0xf0, 0x15, 0x87, 0xbe, + 0x80, 0xac, 0x77, 0xa8, 0x67, 0xbc, 0x4c, 0xa8, 0x42, 0x8b, 0x08, 0xfb, + 0x21, 0x2f, 0xfb, 0x04, 0xfb, 0x42, 0xfb, 0x3d, 0xe5, 0x20, 0xf7, 0x22, + 0x1f, 0xf7, 0x11, 0x8b, 0xda, 0xd6, 0x95, 0xf7, 0x14, 0x08, 0x37, 0x06, + 0x7d, 0x37, 0x60, 0x61, 0x44, 0x8b, 0x08, 0x2f, 0x54, 0xd6, 0xf7, 0x10, + 0xf7, 0x17, 0xc1, 0xd9, 0xe6, 0x1f, 0xd1, 0x8b, 0xb7, 0x62, 0x95, 0x42, + 0x08, 0xdf, 0x06, 0x0e, 0xf8, 0x83, 0xf9, 0x6d, 0x15, 0x38, 0xfb, 0xa3, + 0x06, 0x68, 0xc0, 0x53, 0xa7, 0x45, 0x8b, 0x08, 0xfb, 0x1c, 0x32, 0xfb, + 0x01, 0xfb, 0x3b, 0xfb, 0x45, 0xe2, 0xfb, 0x01, 0xf7, 0x21, 0x1f, 0xd3, + 0x8b, 0xbd, 0xa6, 0xb8, 0xcc, 0x08, 0x46, 0xd5, 0x07, 0xf9, 0x6d, 0x07, + 0xfb, 0x7a, 0xfb, 0xa0, 0x15, 0xe5, 0xc4, 0x3b, 0xfb, 0x11, 0x1f, 0xfb, + 0x0d, 0x51, 0x3b, 0x33, 0x2f, 0x4e, 0xdc, 0xf7, 0x0e, 0xf7, 0x0e, 0xc8, + 0xdc, 0xe6, 0x1e, 0x0e, 0xf8, 0x95, 0xf7, 0x7e, 0x15, 0x8b, 0xdb, 0x85, + 0xbb, 0x7c, 0xb2, 0x69, 0xe1, 0x3b, 0xbf, 0x29, 0x8b, 0x08, 0xfb, 0x26, + 0x2d, 0xfb, 0x04, 0xfb, 0x40, 0xfb, 0x40, 0xe6, 0x21, 0xf7, 0x27, 0x1f, + 0xf7, 0x0c, 0x8b, 0xde, 0xcf, 0xa0, 0xf7, 0x06, 0x08, 0x37, 0x06, 0x74, + 0x46, 0x5c, 0x67, 0x48, 0x8b, 0x56, 0x8b, 0x5e, 0xa3, 0x6f, 0xb7, 0x77, + 0xa9, 0x84, 0xa9, 0x8a, 0xbf, 0x08, 0xf8, 0x16, 0x06, 0xfc, 0x14, 0xcf, + 0x15, 0x92, 0xec, 0xc6, 0xca, 0xdf, 0x8b, 0xdd, 0x8b, 0xca, 0x47, 0x8b, + 0x35, 0x8b, 0x89, 0x8b, 0x89, 0x8a, 0x89, 0x08, 0xfb, 0xba, 0x06, 0x0e, + 0x7c, 0xf7, 0x96, 0xf8, 0xa0, 0x15, 0x34, 0xdd, 0x06, 0xae, 0x9f, 0x9d, + 0xb1, 0x1e, 0x92, 0x8b, 0x8e, 0x8b, 0x9e, 0x8a, 0x08, 0xd0, 0x07, 0x78, + 0x8f, 0x80, 0x8c, 0x7a, 0x8b, 0x08, 0x3e, 0x5d, 0x5f, 0x40, 0x1f, 0x32, + 0x45, 0x47, 0xd1, 0xfc, 0x5c, 0xde, 0xf8, 0x5c, 0xe2, 0xcf, 0x07, 0x0e, + 0xf8, 0x30, 0xf8, 0xa0, 0x15, 0x3f, 0x07, 0x61, 0xc9, 0x58, 0xa8, 0x48, + 0x8b, 0xfb, 0x19, 0x8b, 0x31, 0xfb, 0x08, 0x8b, 0xfb, 0x3e, 0x8b, 0x35, + 0xa2, 0x45, 0xb6, 0x59, 0xb2, 0x5f, 0xc3, 0x71, 0xc2, 0x8b, 0xcd, 0x8b, + 0xb9, 0xa7, 0xba, 0xcd, 0x08, 0x70, 0x07, 0x8b, 0x44, 0x82, 0x60, 0x76, + 0x6e, 0x75, 0x6c, 0x60, 0x79, 0x58, 0x8b, 0x65, 0x8b, 0x69, 0x95, 0x74, + 0x9d, 0x78, 0x9a, 0x83, 0x99, 0x86, 0xaa, 0x08, 0x36, 0x06, 0x94, 0x28, + 0xd8, 0x50, 0xf7, 0x0f, 0x8b, 0xd9, 0x8b, 0xce, 0xa4, 0xad, 0xb5, 0xb3, + 0xbb, 0x9a, 0xcd, 0x8b, 0xf7, 0x0f, 0x08, 0xf8, 0x4a, 0x07, 0x3e, 0x06, + 0xfb, 0x2b, 0x4d, 0x15, 0xe5, 0xc0, 0x3f, 0xfb, 0x17, 0xfb, 0x11, 0x55, + 0x3f, 0x33, 0x30, 0x54, 0xd8, 0xf7, 0x13, 0x1f, 0xf7, 0x12, 0xc3, 0xd9, + 0xe4, 0x1e, 0x0e, 0xd1, 0xf9, 0x6d, 0x15, 0xfd, 0x6d, 0xde, 0xf7, 0xb5, + 0x07, 0xf6, 0xc3, 0xd1, 0xe1, 0x1e, 0xa6, 0x8b, 0xa6, 0x82, 0x9f, 0x7c, + 0xa3, 0x7a, 0x95, 0x72, 0x8b, 0x66, 0x08, 0xfb, 0xff, 0xde, 0xf8, 0x20, + 0x07, 0xe3, 0x4c, 0xc2, 0x25, 0x1e, 0x41, 0x8b, 0x5e, 0x74, 0x5a, 0x4b, + 0x08, 0xf7, 0xa9, 0x38, 0x07, 0x0e, 0x44, 0xf7, 0x2a, 0xf8, 0xa0, 0x15, + 0x38, 0xfc, 0xa0, 0xde, 0x06, 0xf8, 0xa0, 0x07, 0xf7, 0x61, 0x04, 0x37, + 0x22, 0xdf, 0x06, 0xf4, 0x07, 0x0e, 0x44, 0xd1, 0xf8, 0xa0, 0x15, 0xfc, + 0xec, 0x07, 0x57, 0x7a, 0x7a, 0x58, 0x1e, 0x88, 0x8b, 0x8b, 0x8b, 0x7a, + 0x8c, 0x08, 0x44, 0x07, 0x95, 0x89, 0x90, 0x8a, 0x98, 0x8b, 0x08, 0xe9, + 0xbc, 0xb1, 0xd2, 0x1f, 0xf9, 0x0d, 0x38, 0x07, 0xde, 0xf7, 0x61, 0x15, + 0x38, 0x22, 0xde, 0xf4, 0x06, 0x0e, 0xf7, 0x63, 0xf7, 0x21, 0xf9, 0x6d, + 0x15, 0x38, 0xfd, 0x6d, 0xde, 0xf7, 0x60, 0x06, 0xdc, 0xdb, 0xf7, 0x45, + 0xfb, 0xb0, 0xf2, 0x8b, 0xfb, 0x6a, 0xf7, 0xeb, 0xf7, 0x4a, 0xf7, 0x49, + 0x20, 0x8b, 0xfb, 0x72, 0xfb, 0x72, 0x8b, 0xf8, 0x3f, 0x05, 0x0e, 0x44, + 0xf7, 0x2c, 0xf9, 0x6d, 0x15, 0x37, 0xfd, 0x6d, 0xdf, 0xf9, 0x6d, 0x06, + 0x0e, 0xf8, 0xb0, 0xd1, 0xf8, 0xa0, 0x15, 0xfc, 0xa0, 0xdf, 0xf7, 0xdd, + 0x07, 0xd7, 0xc2, 0xc8, 0xcf, 0xc9, 0xae, 0x65, 0x48, 0x1e, 0xfb, 0xfd, + 0xdf, 0xf7, 0xdd, 0x07, 0xd7, 0xc2, 0xc8, 0xcf, 0xc8, 0xaf, 0x64, 0x49, + 0x1e, 0xfb, 0xfd, 0xdf, 0xf8, 0x1d, 0x07, 0xe9, 0x55, 0xbf, 0x29, 0x1e, + 0x45, 0x8b, 0x61, 0x76, 0x5a, 0x50, 0x6c, 0xc3, 0x61, 0xa3, 0x47, 0x8b, + 0x08, 0x45, 0x8b, 0x5d, 0x71, 0x5e, 0x4c, 0x08, 0xd5, 0x07, 0x3e, 0x06, + 0x0e, 0xd1, 0xf8, 0xa0, 0x15, 0xfc, 0xa0, 0xdf, 0xf7, 0xb5, 0x07, 0xf6, + 0xc3, 0xd1, 0xe1, 0xcd, 0xb5, 0x63, 0x4c, 0x1e, 0xfb, 0xff, 0xde, 0xf8, + 0x20, 0x07, 0xe2, 0x4a, 0xc3, 0x26, 0x1e, 0x3d, 0x8b, 0x59, 0x6d, 0x5d, + 0x42, 0x08, 0xe3, 0x07, 0x3e, 0x06, 0x0e, 0xf7, 0xa4, 0xf8, 0xaf, 0x15, + 0xfb, 0x27, 0x32, 0x22, 0xfb, 0x44, 0xfb, 0x44, 0xe3, 0x22, 0xf7, 0x29, + 0xf7, 0x27, 0xe5, 0xf4, 0xf7, 0x40, 0xf7, 0x49, 0x34, 0xf3, 0xfb, 0x2b, + 0x1f, 0x8c, 0x3e, 0x15, 0xe9, 0xc3, 0x3e, 0xfb, 0x16, 0xfb, 0x0f, 0x51, + 0x3d, 0x2f, 0x2e, 0x52, 0xd8, 0xf7, 0x13, 0xf7, 0x12, 0xc4, 0xd9, 0xe8, + 0x1f, 0x0e, 0xc1, 0xfb, 0x6e, 0x15, 0xdf, 0xf7, 0xa5, 0x06, 0xb7, 0x55, + 0xbc, 0x73, 0xcf, 0x8b, 0x08, 0xf7, 0x1b, 0xe4, 0xf7, 0x01, 0xf7, 0x3b, + 0xf7, 0x44, 0x35, 0xf7, 0x02, 0xfb, 0x1f, 0x1f, 0x44, 0x8b, 0x52, 0x6b, + 0x64, 0x4d, 0x08, 0xda, 0x07, 0x3e, 0x06, 0xfd, 0x7a, 0x07, 0xf7, 0x7a, + 0xf9, 0x3b, 0x15, 0xe7, 0xc7, 0x3a, 0xfb, 0x11, 0xfb, 0x0b, 0x4e, 0x3a, + 0x30, 0x33, 0x51, 0xdb, 0xf7, 0x0f, 0x1f, 0xf7, 0x0f, 0xc5, 0xdb, 0xe3, + 0x1e, 0x0e, 0xf8, 0x83, 0xfb, 0x6e, 0x15, 0xf9, 0x7a, 0x41, 0x45, 0x07, + 0x64, 0xc2, 0x50, 0xa9, 0x46, 0x8b, 0x08, 0xfb, 0x1e, 0x31, 0xfb, 0x05, + 0xfb, 0x42, 0xfb, 0x3e, 0xe1, 0x22, 0xf7, 0x1e, 0x1f, 0xd4, 0x8b, 0xbd, + 0xa5, 0xb2, 0xc4, 0x08, 0xfb, 0xaa, 0x07, 0xde, 0x06, 0xfb, 0x79, 0xf9, + 0x3b, 0x15, 0xe4, 0xc4, 0x3b, 0xfb, 0x12, 0xfb, 0x0c, 0x51, 0x3b, 0x33, + 0x2f, 0x4e, 0xdc, 0xf7, 0x0e, 0xf7, 0x0d, 0xc8, 0xdd, 0xe7, 0x1f, 0x0e, + 0xb3, 0xd0, 0xf8, 0xa0, 0x15, 0xfc, 0xa0, 0xdf, 0xf7, 0xa4, 0x07, 0x8b, + 0xd6, 0x9e, 0xbc, 0xb3, 0xa8, 0xa5, 0x9e, 0xa4, 0x91, 0xc5, 0x8c, 0x08, + 0xe0, 0x07, 0x7d, 0x8d, 0x84, 0x8c, 0x80, 0x8b, 0x55, 0x8b, 0x62, 0x6b, + 0x5b, 0x3d, 0x08, 0xea, 0x07, 0x3e, 0x06, 0x0e, 0xf7, 0x63, 0xf8, 0x4a, + 0xf8, 0x0e, 0x15, 0x8a, 0xf2, 0x47, 0xc5, 0xfb, 0x0d, 0x8b, 0xfb, 0x0e, + 0x8b, 0x3c, 0x4c, 0x8b, 0x2a, 0x8b, 0x39, 0xb5, 0x64, 0xf7, 0x10, 0x6d, + 0x08, 0xd9, 0x78, 0x05, 0xc5, 0x7d, 0xa2, 0x76, 0x8b, 0x65, 0x8b, 0x5a, + 0x5a, 0x6a, 0x42, 0x8b, 0x5e, 0x8b, 0x65, 0x98, 0x76, 0xa1, 0x7e, 0x9a, + 0x85, 0x9a, 0x86, 0xb0, 0x08, 0x33, 0x06, 0x8f, 0xfb, 0x0d, 0xcf, 0x51, + 0xf7, 0x1d, 0x8b, 0xf7, 0x18, 0x8b, 0xdf, 0xcc, 0x8b, 0xf0, 0x8b, 0xd9, + 0x5f, 0xb6, 0x23, 0xa4, 0x08, 0x3b, 0x9e, 0x05, 0x47, 0x9b, 0x6e, 0xa1, + 0x8b, 0xb0, 0x8b, 0xbb, 0xb6, 0xaa, 0xcf, 0x8b, 0xce, 0x8b, 0xaf, 0x6e, + 0x8d, 0x54, 0x08, 0xe3, 0x06, 0x0e, 0x7c, 0xf7, 0x92, 0xf8, 0xa0, 0x15, + 0x35, 0xf7, 0x24, 0x38, 0xfb, 0x24, 0x44, 0x47, 0xd2, 0xfc, 0x20, 0x06, + 0x56, 0xaf, 0x6d, 0xcc, 0x1e, 0x9f, 0x8b, 0x9f, 0x8d, 0xa7, 0x90, 0x08, + 0xd1, 0x07, 0x80, 0x88, 0x7e, 0x8a, 0x7b, 0x8b, 0x08, 0x67, 0x81, 0x95, + 0xb0, 0x1f, 0xf7, 0xfb, 0xe1, 0xcf, 0x07, 0x0e, 0xf8, 0x76, 0x16, 0xf8, + 0xa0, 0x38, 0xfb, 0xbd, 0x07, 0x20, 0x53, 0x45, 0x34, 0x49, 0x61, 0xb3, + 0xca, 0x1e, 0xf8, 0x07, 0x38, 0xfc, 0x28, 0x07, 0x34, 0xcc, 0x53, 0xf1, + 0x1e, 0xd8, 0x8b, 0xbc, 0xa6, 0xbc, 0xd0, 0x08, 0x42, 0x07, 0xd6, 0x06, + 0x0e, 0xf7, 0x63, 0xf7, 0xb1, 0x16, 0xf7, 0x5d, 0xf8, 0xa0, 0x2d, 0x8b, + 0xfb, 0x28, 0xfc, 0x3d, 0xfb, 0x20, 0xf8, 0x3d, 0x2d, 0x8b, 0xf7, 0x4c, + 0xfc, 0xa0, 0xe6, 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf8, 0xbe, 0x16, 0xf7, + 0x2e, 0xf8, 0xa0, 0x2d, 0x8b, 0x23, 0xfc, 0x2c, 0x24, 0xf8, 0x2c, 0x25, + 0x8b, 0x27, 0xfc, 0x2c, 0x20, 0xf8, 0x2c, 0x2f, 0x8b, 0xf7, 0x2c, 0xfc, + 0xa0, 0xe9, 0x8b, 0xf0, 0xf8, 0x2f, 0xf5, 0xfc, 0x2f, 0xea, 0x8b, 0x05, + 0x0e, 0xf7, 0x63, 0xf7, 0xb8, 0xf7, 0xa3, 0x15, 0xf7, 0x44, 0xf7, 0x91, + 0x2d, 0x8b, 0xfb, 0x12, 0xfb, 0x52, 0xfb, 0x12, 0xf7, 0x52, 0x2c, 0x8b, + 0xf7, 0x43, 0xfb, 0x95, 0xfb, 0x4d, 0xfb, 0x9f, 0xea, 0x8b, 0xf7, 0x19, + 0xf7, 0x5d, 0xf7, 0x17, 0xfb, 0x5d, 0xec, 0x8b, 0xfb, 0x49, 0xf7, 0xa3, + 0x05, 0x0e, 0xf7, 0x63, 0xf8, 0x18, 0xf8, 0xa0, 0x15, 0xfb, 0x25, 0xfc, + 0x2c, 0xfb, 0x1a, 0xf8, 0x2c, 0x32, 0x8b, 0xf7, 0x45, 0xfc, 0xa2, 0x6b, + 0x38, 0x05, 0x7e, 0x66, 0x78, 0x7d, 0x68, 0x8b, 0x7f, 0x8b, 0x7d, 0x8d, + 0x79, 0x8f, 0x08, 0x40, 0x07, 0x9c, 0x82, 0x9c, 0x87, 0xa1, 0x8b, 0xa6, + 0x8b, 0xa8, 0x94, 0xa1, 0x9b, 0xa5, 0x9e, 0x9a, 0xa1, 0x9b, 0xb5, 0x08, + 0xf7, 0x7d, 0xf9, 0x0e, 0x31, 0x8b, 0x05, 0x0e, 0xf7, 0x63, 0xf8, 0x4f, + 0xf8, 0xa0, 0x15, 0xfc, 0x1b, 0x42, 0xf7, 0xb8, 0x06, 0xfb, 0xcd, 0xfc, + 0x0c, 0x8b, 0x40, 0xf8, 0x3e, 0x8b, 0x8b, 0xd4, 0xfb, 0xd9, 0x8b, 0xf7, + 0xcb, 0xf8, 0x0d, 0x8b, 0xd5, 0x05, 0x0e, 0xb4, 0xf7, 0xa8, 0xf9, 0x6d, + 0x15, 0x5d, 0x06, 0x46, 0x63, 0x5b, 0x38, 0x1f, 0xfb, 0x3b, 0x07, 0x8b, + 0x2e, 0x78, 0x6a, 0x50, 0x7f, 0x08, 0x46, 0x07, 0xc6, 0x7f, 0x9e, 0x69, + 0x8b, 0x2f, 0x08, 0xfb, 0x3b, 0x07, 0x38, 0xb3, 0x5b, 0xd0, 0x1e, 0xb9, + 0xcc, 0x7c, 0x06, 0x5a, 0x7d, 0x9a, 0xbf, 0x1f, 0xf7, 0x49, 0x07, 0x8b, + 0xde, 0x71, 0xbc, 0x53, 0xa5, 0xc8, 0xa3, 0xa0, 0xb4, 0x8b, 0xe7, 0x08, + 0xf7, 0x49, 0x07, 0xbf, 0x99, 0x9a, 0xbc, 0x1e, 0x9a, 0xcc, 0x06, 0x0e, + 0x6a, 0xef, 0xf9, 0x6d, 0x15, 0xfe, 0x41, 0xc7, 0xfa, 0x41, 0x4f, 0x07, + 0x0e, 0xb4, 0xa8, 0xfb, 0x68, 0x15, 0xba, 0x06, 0xd1, 0xb3, 0xbb, 0xde, + 0x1f, 0xf7, 0x3b, 0x07, 0x8b, 0xe7, 0x9e, 0xad, 0xc4, 0x97, 0x08, 0xd0, + 0x07, 0x52, 0x97, 0x78, 0xad, 0x8b, 0xe7, 0x08, 0xf7, 0x3b, 0x07, 0xde, + 0x63, 0xbb, 0x45, 0x1e, 0x5c, 0x4a, 0x9b, 0x06, 0xbd, 0x99, 0x7c, 0x57, + 0x1f, 0xfb, 0x49, 0x07, 0x8b, 0x39, 0xa5, 0x59, 0xc3, 0x71, 0x53, 0x72, + 0x71, 0x5a, 0x8b, 0x38, 0x08, 0xfb, 0x49, 0x07, 0x57, 0x7d, 0x7c, 0x59, + 0x1e, 0x7b, 0x4a, 0x06, 0x0e, 0xf7, 0xb7, 0xf8, 0x5b, 0xf8, 0x2f, 0x15, + 0x8c, 0x56, 0x7c, 0x75, 0x66, 0x8b, 0x7d, 0x8b, 0x7b, 0x90, 0x77, 0x97, + 0x08, 0xfb, 0x09, 0xd0, 0x05, 0x7a, 0x95, 0x78, 0x91, 0x79, 0x8b, 0x4a, + 0x8b, 0x65, 0x58, 0x86, 0x2d, 0x08, 0xc0, 0x06, 0x8d, 0xa2, 0x8d, 0x95, + 0x8f, 0x95, 0x95, 0xa1, 0x9c, 0x98, 0x9d, 0x8b, 0x95, 0x8b, 0xa2, 0x83, + 0x95, 0x85, 0x08, 0xed, 0x4c, 0x05, 0xa5, 0x7b, 0xa9, 0x81, 0xa4, 0x8b, + 0x08, 0xcb, 0xb4, 0xbd, 0xd8, 0x1f, 0x9b, 0x56, 0x07, 0x0e, 0xb3, 0xf7, + 0x0e, 0xfb, 0x61, 0x15, 0xde, 0xf7, 0xe6, 0x06, 0x75, 0xf7, 0x73, 0x64, + 0x8b, 0x75, 0xfb, 0x73, 0x05, 0xfb, 0xe6, 0x07, 0x8a, 0xf9, 0x05, 0x15, + 0xdf, 0xf3, 0x37, 0x06, 0x23, 0x07, 0x0e, 0xf7, 0xcc, 0xf8, 0x62, 0x15, + 0xc8, 0x86, 0xb3, 0x61, 0x92, 0x48, 0x08, 0xdf, 0x06, 0x85, 0xf7, 0x06, + 0x46, 0xd0, 0xfb, 0x09, 0x93, 0x08, 0xe4, 0x61, 0x31, 0x07, 0xfb, 0x1b, + 0x7d, 0x38, 0xfb, 0x00, 0x8b, 0xfb, 0x37, 0x8b, 0xfb, 0x33, 0xde, 0x23, + 0xf7, 0x1b, 0x7f, 0x08, 0x29, 0xb5, 0xec, 0x07, 0xf7, 0x08, 0x91, 0xd6, + 0xd8, 0x92, 0xf7, 0x0c, 0x08, 0x37, 0x06, 0x7f, 0x3c, 0x65, 0x62, 0x4b, + 0x84, 0x08, 0xf8, 0x2d, 0x07, 0x61, 0xfc, 0x2b, 0x15, 0x38, 0x98, 0x5b, + 0xd3, 0x8b, 0xf7, 0x05, 0x8b, 0xf7, 0x0d, 0xb8, 0xd2, 0xe1, 0x9b, 0x08, + 0xfc, 0x2a, 0x07, 0x0e, 0xf8, 0x02, 0xf8, 0x0c, 0x15, 0xfb, 0x34, 0x06, + 0x85, 0x97, 0x84, 0x98, 0x88, 0x8e, 0x66, 0xcc, 0x85, 0x9c, 0x8b, 0xb0, + 0x8b, 0xd8, 0xc3, 0xbe, 0xe0, 0x8b, 0xe2, 0x8b, 0xb9, 0x58, 0x8e, 0x24, + 0x08, 0xe3, 0x06, 0x8a, 0xc8, 0x83, 0xb2, 0x78, 0xac, 0x67, 0xc9, 0x44, + 0xb0, 0x36, 0x8b, 0xfb, 0x1a, 0x8b, 0x23, 0x2e, 0x8b, 0xfb, 0x0d, 0x8b, + 0x5f, 0x92, 0x78, 0xb9, 0x3f, 0x08, 0x3a, 0x54, 0xf7, 0x02, 0x06, 0x9a, + 0x72, 0x94, 0x6f, 0x8b, 0x72, 0x8b, 0x4e, 0x6a, 0x58, 0x2f, 0x3c, 0x08, + 0xbb, 0x49, 0x05, 0xb1, 0xa4, 0xaf, 0x97, 0xae, 0x8b, 0xa0, 0x8b, 0xa3, + 0x87, 0xa0, 0x84, 0x08, 0xde, 0x6e, 0xa5, 0x85, 0xb0, 0x8b, 0xbf, 0x8b, + 0xb2, 0x9c, 0xb3, 0xb2, 0x08, 0x61, 0xcd, 0x05, 0x6e, 0x77, 0x6f, 0x81, + 0x71, 0x8b, 0x79, 0x8b, 0x77, 0x8f, 0x62, 0x97, 0x08, 0x65, 0x97, 0x79, + 0x8e, 0x71, 0x8b, 0x60, 0x8b, 0x63, 0x7e, 0x64, 0x71, 0xe5, 0xe6, 0xa7, + 0xb9, 0x8b, 0xbf, 0x8b, 0x9e, 0x86, 0xa2, 0x81, 0xa8, 0x08, 0xf7, 0x1c, + 0x06, 0xc2, 0x07, 0x0e, 0xfb, 0x12, 0xf7, 0xaa, 0xf9, 0x59, 0x15, 0xfc, + 0x58, 0xfd, 0x6d, 0xc5, 0x8b, 0xf8, 0x58, 0xf9, 0x6d, 0x51, 0x8b, 0x05, + 0x0e, 0xf8, 0x83, 0xf7, 0xf6, 0x15, 0xfb, 0x2b, 0x8b, 0x05, 0xf7, 0x5d, + 0xf7, 0xf7, 0x36, 0x8b, 0xfb, 0x47, 0xfb, 0xd6, 0xfb, 0x4d, 0xf7, 0xd6, + 0x36, 0x8b, 0x05, 0xf7, 0x61, 0xfb, 0xf7, 0xfb, 0x2b, 0x8b, 0x8b, 0x58, + 0xf7, 0x40, 0x8b, 0x8b, 0x3e, 0xfb, 0x40, 0x8b, 0x8b, 0x58, 0xf7, 0x40, + 0x8b, 0x05, 0xfb, 0x43, 0xe3, 0x07, 0xf7, 0x43, 0xf7, 0x3e, 0xbe, 0xfb, + 0x3e, 0xd8, 0xf7, 0x3e, 0x07, 0xbe, 0x07, 0x0e, 0xf8, 0x67, 0xf8, 0x62, + 0x15, 0xfb, 0x05, 0x8b, 0x97, 0xd1, 0x05, 0x9a, 0xdd, 0xab, 0xb7, 0xba, + 0x8b, 0x9a, 0x8b, 0x97, 0x87, 0xa4, 0x7d, 0x08, 0xa9, 0xda, 0x05, 0x6d, + 0x98, 0x74, 0x91, 0x71, 0x8b, 0x63, 0x8b, 0x60, 0x79, 0x6b, 0x6d, 0x6d, + 0x6e, 0x77, 0x64, 0x80, 0x53, 0x08, 0x75, 0x23, 0xfb, 0x11, 0x8b, 0x8b, + 0x45, 0xf7, 0x05, 0x8b, 0x3d, 0xfc, 0x31, 0x05, 0x7c, 0x3e, 0x6d, 0x67, + 0x58, 0x8b, 0x77, 0x8b, 0x7d, 0x90, 0x7a, 0x96, 0x08, 0x7a, 0x37, 0x05, + 0x98, 0x84, 0x9d, 0x88, 0xa3, 0x8b, 0xbd, 0x8b, 0xbe, 0xa1, 0xad, 0xae, + 0xab, 0xac, 0x9f, 0xba, 0x98, 0xd1, 0x08, 0xd6, 0xf8, 0x21, 0xf7, 0x12, + 0x8b, 0x8b, 0xd1, 0x05, 0x0e, 0xf8, 0x64, 0xf8, 0xa0, 0x15, 0x8b, 0x93, + 0x8b, 0x9f, 0x05, 0xf5, 0x44, 0xd2, 0x23, 0x23, 0x3a, 0x42, 0x2f, 0x1e, + 0x8b, 0x65, 0x98, 0x6f, 0xaa, 0x67, 0x08, 0x41, 0x64, 0x6c, 0x5e, 0x8b, + 0x49, 0x8b, 0x4a, 0xa6, 0x5c, 0xcc, 0x5e, 0x08, 0xf7, 0x3e, 0xfb, 0x09, + 0x05, 0xb2, 0x70, 0x9b, 0x71, 0x8b, 0x68, 0x8b, 0x58, 0x64, 0x68, 0x52, + 0x8b, 0x67, 0x8b, 0x6e, 0x9a, 0x78, 0xa8, 0x7d, 0x9e, 0x87, 0x9f, 0x8b, + 0xb2, 0x08, 0x36, 0x06, 0x8b, 0x5c, 0x8d, 0x7f, 0x94, 0x70, 0xa3, 0x45, + 0xce, 0x60, 0xdf, 0x8b, 0xf6, 0x8b, 0xdb, 0xd3, 0x8b, 0xeb, 0x8b, 0xb6, + 0x7e, 0xa9, 0x63, 0xb8, 0x08, 0xd3, 0xa6, 0xb0, 0xc0, 0x8b, 0xd7, 0x8b, + 0xd3, 0x6f, 0xb6, 0x3a, 0xbf, 0x08, 0xfb, 0x26, 0xe9, 0x05, 0x61, 0xa7, + 0x7c, 0x9f, 0x8b, 0xa8, 0x08, 0xbc, 0xb1, 0xaf, 0xbe, 0x1e, 0xc6, 0xb1, + 0x63, 0x4d, 0x1f, 0x8b, 0x7a, 0x8b, 0x82, 0x05, 0xdf, 0x06, 0xfb, 0xa8, + 0xfb, 0xbb, 0x15, 0x56, 0xb2, 0x7e, 0x9f, 0x8b, 0xb3, 0x8b, 0xb3, 0x9e, + 0xa6, 0xbf, 0xad, 0x08, 0xf7, 0x35, 0xfb, 0x01, 0x05, 0xbc, 0x69, 0xa3, + 0x66, 0x8b, 0x62, 0x8b, 0x63, 0x71, 0x66, 0x5c, 0x72, 0x08, 0xfb, 0x3a, + 0xf7, 0x0f, 0x05, 0x0e, 0xf8, 0x79, 0xf7, 0x52, 0x15, 0x55, 0xc1, 0x05, + 0x9e, 0xaa, 0x95, 0xab, 0x8b, 0xad, 0x8b, 0xab, 0x81, 0xaf, 0x7b, 0xa4, + 0x08, 0xc2, 0xc2, 0x52, 0xc5, 0x50, 0x56, 0x05, 0x71, 0x9d, 0x68, 0x95, + 0x66, 0x8b, 0x67, 0x8b, 0x6b, 0x82, 0x6e, 0x7a, 0x08, 0x54, 0xc2, 0x53, + 0x56, 0xc1, 0x54, 0x05, 0x77, 0x6f, 0x7f, 0x65, 0x8b, 0x67, 0x8b, 0x67, + 0x97, 0x64, 0x9f, 0x70, 0x08, 0x5b, 0x5a, 0xc3, 0x52, 0xbe, 0xbe, 0x05, + 0xa5, 0x7b, 0xae, 0x82, 0xac, 0x8b, 0xb2, 0x8b, 0xad, 0x95, 0xa6, 0x9f, + 0x08, 0xc0, 0x56, 0xc5, 0xc1, 0x05, 0xfb, 0x67, 0xf7, 0x93, 0x15, 0xc7, + 0xba, 0x5c, 0x50, 0x53, 0x5a, 0x5c, 0x52, 0x50, 0x5b, 0xba, 0xc4, 0xc5, + 0xbb, 0xba, 0xc5, 0x1f, 0x0e, 0x25, 0xbb, 0xf9, 0x59, 0x15, 0x8b, 0xfb, + 0x03, 0xa6, 0xfb, 0x1a, 0xb3, 0x8b, 0xa6, 0xf7, 0x1a, 0x8b, 0xf7, 0x03, + 0x2d, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, 0x21, 0xf8, 0x71, 0x15, 0xf3, 0x5b, + 0x07, 0x8a, 0xc4, 0x9a, 0xa7, 0xad, 0x90, 0x08, 0xb1, 0x07, 0x4f, 0x86, + 0x6a, 0x5c, 0x8b, 0x3c, 0x08, 0x26, 0xe8, 0x07, 0xf7, 0x32, 0x16, 0xf3, + 0x5b, 0x07, 0x8a, 0xc4, 0x9a, 0xa7, 0xad, 0x90, 0x08, 0xb1, 0x07, 0x4f, + 0x86, 0x6a, 0x5c, 0x8b, 0x3c, 0x08, 0x26, 0xe8, 0x07, 0x0e, 0xed, 0xf7, + 0x77, 0x15, 0xf7, 0x2c, 0xfb, 0x0d, 0x8b, 0xde, 0x21, 0xde, 0xf5, 0xde, + 0x8b, 0xde, 0xfb, 0x2c, 0xfb, 0x0e, 0x8b, 0x32, 0x05, 0xf7, 0x61, 0x16, + 0xf7, 0x2c, 0xfb, 0x0d, 0x8b, 0xde, 0x21, 0xde, 0xf5, 0xde, 0x8b, 0xde, + 0xfb, 0x2c, 0xfb, 0x0e, 0x8b, 0x32, 0x05, 0x0e, 0xb3, 0xe6, 0xf7, 0x77, + 0x15, 0xf7, 0x2c, 0xfb, 0x0d, 0x8b, 0xde, 0x21, 0xde, 0xf5, 0xde, 0x8b, + 0xde, 0xfb, 0x2c, 0xfb, 0x0e, 0x8b, 0x32, 0x05, 0x0e, 0xb3, 0xf7, 0x83, + 0xf7, 0xd1, 0x15, 0xfb, 0x2e, 0xf7, 0x0d, 0x8b, 0x38, 0xf7, 0x00, 0x38, + 0xfb, 0x00, 0x38, 0x8b, 0x38, 0xf7, 0x2e, 0xf7, 0x0e, 0x8b, 0xe4, 0x05, + 0x0e, 0xf7, 0x63, 0xf7, 0x90, 0xf8, 0xa0, 0x15, 0x34, 0xdd, 0x06, 0xae, + 0x9f, 0x9d, 0xb1, 0x1e, 0x92, 0x8b, 0x8e, 0x8b, 0x9e, 0x8a, 0x08, 0xd0, + 0x07, 0x78, 0x8f, 0x80, 0x8c, 0x7a, 0x8b, 0x08, 0x3e, 0x5d, 0x5f, 0x40, + 0x1f, 0x32, 0x45, 0x47, 0xd1, 0xfc, 0x5c, 0xde, 0xf8, 0x5c, 0xe2, 0x07, + 0xcf, 0x07, 0xf7, 0x4c, 0x16, 0x38, 0xfc, 0xa0, 0xde, 0xf8, 0xa0, 0x06, + 0xf7, 0x61, 0x04, 0x38, 0x22, 0xde, 0x06, 0xf4, 0x07, 0x0e, 0xf7, 0x63, + 0xf7, 0x95, 0xf8, 0xa0, 0x15, 0x34, 0xdd, 0x06, 0xae, 0x9f, 0x9d, 0xb1, + 0x1e, 0x92, 0x8b, 0x8e, 0x8b, 0x9e, 0x8a, 0x08, 0xd0, 0x07, 0x78, 0x8f, + 0x80, 0x8c, 0x7a, 0x8b, 0x08, 0x3e, 0x5d, 0x5f, 0x40, 0x1f, 0x32, 0x45, + 0x47, 0xd1, 0xfc, 0x5c, 0xde, 0xf8, 0x5c, 0xe2, 0x07, 0xcf, 0x07, 0xf7, + 0x41, 0xf7, 0x61, 0x15, 0x38, 0xfd, 0x6d, 0xde, 0x06, 0xf9, 0x6d, 0x07, + 0x0e, 0xf8, 0xc5, 0xf7, 0xcc, 0x15, 0xfc, 0xca, 0x43, 0xf8, 0xca, 0xd3, + 0x06, 0x0e, 0xf8, 0x95, 0xf8, 0x8a, 0x15, 0xfb, 0x56, 0xf7, 0x63, 0x33, + 0xfb, 0x63, 0xfb, 0x55, 0x39, 0xf7, 0x55, 0xfc, 0xe9, 0xe3, 0xf8, 0xe9, + 0xf7, 0x56, 0xdd, 0x06, 0x0e, 0xf8, 0x95, 0xf8, 0x8a, 0x15, 0xfb, 0x56, + 0xf7, 0x63, 0x33, 0xfb, 0x63, 0xfb, 0x55, 0x39, 0xf7, 0x55, 0xfb, 0xc7, + 0xfb, 0x55, 0x39, 0xf7, 0x55, 0xfb, 0x64, 0xe3, 0xf7, 0x64, 0xf7, 0x56, + 0x06, 0xdd, 0xfb, 0x56, 0xf7, 0xc7, 0xf7, 0x56, 0xdd, 0x07, 0x0e, 0x7c, + 0xf7, 0x67, 0xf8, 0x3f, 0x15, 0xfb, 0x10, 0xfb, 0x11, 0xf7, 0x10, 0xf7, + 0x11, 0x06, 0x0e, 0xf7, 0x88, 0xf8, 0x9e, 0xf9, 0x6d, 0x15, 0xfb, 0x8e, + 0x06, 0xfb, 0x12, 0x29, 0x22, 0xfb, 0x1b, 0x1f, 0x8b, 0x41, 0xa9, 0x46, + 0xbf, 0x60, 0xae, 0x6e, 0xae, 0x7f, 0xc2, 0x88, 0x08, 0xfc, 0x48, 0xcb, + 0xf9, 0xde, 0xdd, 0xfd, 0xde, 0xcb, 0xf9, 0xde, 0xc4, 0xcb, 0x07, 0x0e, + 0xc4, 0xf7, 0x43, 0xf8, 0x6a, 0x15, 0x46, 0x53, 0x53, 0x46, 0x46, 0xc3, + 0x53, 0xd0, 0xcf, 0xc4, 0xc3, 0xce, 0xd2, 0x54, 0xc3, 0x45, 0x1f, 0x0e, + 0x44, 0xcc, 0xf3, 0x15, 0x23, 0xbb, 0x07, 0x8d, 0x51, 0x7c, 0x70, 0x67, + 0x86, 0x08, 0x65, 0x07, 0xc8, 0x90, 0xac, 0xb9, 0x8b, 0xdb, 0x08, 0xf0, + 0x2e, 0x07, 0x0e, 0xb3, 0xba, 0xf3, 0x15, 0x23, 0xbb, 0x07, 0x8c, 0x51, + 0x7d, 0x70, 0x68, 0x86, 0x08, 0x65, 0x07, 0xc7, 0x90, 0xac, 0xb9, 0x8b, + 0xdb, 0x08, 0xf0, 0x2e, 0x07, 0xf7, 0x34, 0x16, 0x23, 0xbb, 0x07, 0x8c, + 0x51, 0x7d, 0x70, 0x68, 0x86, 0x08, 0x65, 0x07, 0xc7, 0x90, 0xac, 0xb9, + 0x8b, 0xdb, 0x08, 0xf0, 0x2e, 0x07, 0x0e, 0xb3, 0xbc, 0xf9, 0x59, 0x15, + 0x23, 0xbb, 0x07, 0x8c, 0x51, 0x7d, 0x70, 0x68, 0x86, 0x08, 0x65, 0x07, + 0xc7, 0x90, 0xac, 0xb9, 0x8b, 0xdb, 0x08, 0xf0, 0x2e, 0x07, 0xf7, 0x34, + 0x16, 0x23, 0xbb, 0x07, 0x8c, 0x51, 0x7d, 0x70, 0x68, 0x86, 0x08, 0x65, + 0x07, 0xc7, 0x90, 0xac, 0xb9, 0x8b, 0xdb, 0x08, 0xf0, 0x2e, 0x07, 0x0e, + 0xf7, 0x90, 0xf7, 0xd1, 0x15, 0xfb, 0x2e, 0xf7, 0x0d, 0x8b, 0x38, 0xf7, + 0x00, 0x38, 0xfb, 0x00, 0x38, 0x8b, 0x38, 0xf7, 0x2e, 0xf7, 0x0e, 0x8b, + 0xe4, 0x05, 0xf7, 0x5b, 0x16, 0xfb, 0x2e, 0xf7, 0x0d, 0x8b, 0x38, 0xf7, + 0x00, 0x38, 0xfb, 0x00, 0x38, 0x8b, 0x38, 0xf7, 0x2e, 0xf7, 0x0e, 0x8b, + 0xe4, 0x05, 0x0e, 0xf9, 0x57, 0xf7, 0x6f, 0xf3, 0x15, 0x23, 0x23, 0xf3, + 0xf3, 0x06, 0xf7, 0xe1, 0x16, 0x23, 0x23, 0xf3, 0xf3, 0x06, 0xf7, 0xe1, + 0x16, 0x23, 0x23, 0xf3, 0xf3, 0x06, 0x0e, 0xf9, 0x57, 0xf7, 0x32, 0xf9, + 0x6c, 0x15, 0x39, 0x48, 0x47, 0x39, 0x38, 0xce, 0x47, 0xde, 0xdc, 0xcf, + 0xcf, 0xdc, 0x1f, 0xe0, 0x49, 0xce, 0x37, 0x1e, 0x4f, 0x04, 0xbe, 0xb3, + 0x63, 0x58, 0x5a, 0x62, 0x62, 0x5a, 0x59, 0x62, 0xb4, 0xbd, 0xbc, 0xb4, + 0xb4, 0xbc, 0x1f, 0xf7, 0xe2, 0xd1, 0x15, 0xfc, 0x1f, 0xfd, 0x8a, 0xcd, + 0x8b, 0xf8, 0x1f, 0xf9, 0x8a, 0x05, 0x49, 0x06, 0x82, 0xfc, 0x5f, 0x15, + 0x39, 0x48, 0x47, 0x39, 0x38, 0xce, 0x47, 0xde, 0xdc, 0xcf, 0xcf, 0xdc, + 0xe0, 0x49, 0xce, 0x37, 0x1f, 0x4f, 0x04, 0xbe, 0xb3, 0x63, 0x58, 0x5a, + 0x62, 0x62, 0x59, 0x5a, 0x62, 0xb4, 0xbd, 0xbc, 0xb4, 0xb4, 0xbc, 0x1f, + 0xf7, 0xfc, 0xc7, 0x15, 0x39, 0x48, 0x47, 0x39, 0x38, 0xce, 0x47, 0xde, + 0xdc, 0xcf, 0xcf, 0xdc, 0xe0, 0x49, 0xce, 0x37, 0x1f, 0x4f, 0x04, 0xbe, + 0xb3, 0x63, 0x58, 0x5a, 0x62, 0x62, 0x59, 0x5a, 0x62, 0xb4, 0xbd, 0xbc, + 0xb4, 0xb4, 0xbc, 0x1f, 0x0e, 0xf7, 0xd2, 0xf7, 0xa7, 0xf7, 0xd9, 0x15, + 0x5c, 0x07, 0x8b, 0x5e, 0x81, 0x7b, 0x45, 0x4c, 0x40, 0x47, 0x72, 0x5f, + 0x8b, 0x48, 0x08, 0xfb, 0x09, 0xde, 0x40, 0xf7, 0x17, 0xf7, 0x24, 0xd6, + 0xdb, 0xf7, 0x2e, 0x1e, 0x36, 0x06, 0x8b, 0x5d, 0x86, 0x6f, 0x7f, 0x73, + 0x78, 0x66, 0x63, 0x76, 0x56, 0x8b, 0x3e, 0x8b, 0x57, 0xb9, 0x8b, 0xcf, + 0x8b, 0xb9, 0xa1, 0xb2, 0xc0, 0xba, 0xc6, 0xc0, 0x8b, 0x8b, 0x9d, 0xa2, + 0xa0, 0xa7, 0x92, 0xa2, 0x8b, 0xaf, 0x08, 0xc2, 0x31, 0x07, 0xea, 0x04, + 0xe5, 0xf3, 0x31, 0x23, 0x06, 0x0e, 0xb3, 0xf7, 0x1b, 0xf9, 0x78, 0x15, + 0xfb, 0x05, 0x8b, 0xf7, 0x29, 0xfb, 0x28, 0xc7, 0x8b, 0x2b, 0xf7, 0x28, + 0x05, 0x0e, 0xb3, 0xf7, 0x50, 0xf9, 0x78, 0x15, 0x2b, 0xfb, 0x28, 0xc7, + 0x8b, 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, + 0x08, 0xf9, 0x79, 0x15, 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdc, + 0x2b, 0xca, 0x8b, 0x2b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, + 0x99, 0xf9, 0x61, 0x15, 0x83, 0x72, 0x7f, 0x80, 0x7a, 0x8b, 0x7f, 0x8b, + 0x71, 0x92, 0x72, 0x95, 0x08, 0x62, 0x9c, 0x83, 0x8d, 0x76, 0x8b, 0x5e, + 0x8b, 0x6d, 0x67, 0x80, 0x48, 0x08, 0xc5, 0x06, 0x91, 0xa2, 0x97, 0x99, + 0x9a, 0x8b, 0x96, 0x8b, 0x99, 0x87, 0xa3, 0x82, 0x08, 0xc1, 0x76, 0x97, + 0x87, 0x9e, 0x8b, 0xbc, 0x8b, 0xa9, 0xae, 0x95, 0xd0, 0x08, 0x51, 0x06, + 0x0e, 0xb3, 0xf7, 0xc2, 0xf9, 0x51, 0x15, 0xfb, 0xa6, 0x45, 0xf7, 0xa6, + 0xd1, 0x06, 0x0e, 0xb3, 0x9a, 0xf9, 0x70, 0x15, 0x8c, 0x64, 0x91, 0x78, + 0x99, 0x77, 0xa6, 0x66, 0xb8, 0x77, 0xc3, 0x8b, 0xe8, 0x8b, 0xbf, 0xb9, + 0x92, 0xe4, 0x08, 0x50, 0x06, 0x87, 0x61, 0x6a, 0x73, 0x55, 0x8b, 0x52, + 0x8b, 0x6d, 0xa1, 0x86, 0xb7, 0x08, 0x50, 0x06, 0x0e, 0xb3, 0xf7, 0x6f, + 0xf9, 0x60, 0x15, 0x23, 0x23, 0xf3, 0xf3, 0x06, 0x0e, 0xb3, 0xf7, 0x1a, + 0xf9, 0x5f, 0x15, 0x23, 0x24, 0xf3, 0xf2, 0x06, 0xf7, 0x36, 0x16, 0x23, + 0x24, 0xf3, 0xf2, 0x06, 0x0e, 0xb3, 0xf7, 0x3b, 0xf9, 0x86, 0x15, 0x5b, + 0x63, 0x63, 0x5c, 0x5b, 0xb3, 0x63, 0xbb, 0xbb, 0xb3, 0xb2, 0xbb, 0xbc, + 0x64, 0xb2, 0x5a, 0x1f, 0x5f, 0x04, 0xa4, 0x9e, 0x78, 0x72, 0x74, 0x77, + 0x77, 0x73, 0x73, 0x77, 0x9f, 0xa3, 0xa2, 0x9f, 0x9f, 0xa3, 0x1f, 0x0e, + 0xb3, 0xf7, 0x39, 0x16, 0x61, 0x2f, 0x97, 0x84, 0x05, 0x97, 0x91, 0x92, + 0x8d, 0x97, 0x8b, 0x08, 0xa8, 0x9c, 0x7d, 0x74, 0x71, 0x74, 0x78, 0x6c, + 0x1f, 0x71, 0x8b, 0x7a, 0x91, 0x5d, 0xa2, 0x08, 0x82, 0x8f, 0x76, 0x63, + 0x05, 0xc9, 0x70, 0xa3, 0x84, 0xb2, 0x8b, 0x08, 0xd7, 0xba, 0xaf, 0xc4, + 0xb6, 0x6e, 0xa3, 0x59, 0x1f, 0x83, 0x8b, 0x84, 0x8b, 0x7e, 0x89, 0x08, + 0xa2, 0xc3, 0x65, 0x8b, 0x05, 0x0e, 0xb3, 0xc8, 0xf9, 0x78, 0x15, 0x2b, + 0xfb, 0x2a, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x2a, 0xfb, 0x05, 0x8b, 0x05, + 0xf7, 0x42, 0x16, 0x2b, 0xfb, 0x2a, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x2a, + 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, 0x2e, 0x16, 0x4e, 0x75, 0x67, + 0x62, 0x8b, 0x5b, 0x8b, 0x64, 0xa0, 0x71, 0xb5, 0x7b, 0xa1, 0x83, 0xa4, + 0x86, 0xa1, 0x8b, 0x9e, 0x8b, 0xac, 0x90, 0xa3, 0x90, 0x08, 0xb8, 0x07, + 0x79, 0x84, 0x76, 0x88, 0x73, 0x8b, 0x5c, 0x8b, 0x72, 0x9e, 0x8b, 0xae, + 0x8b, 0xb5, 0xa0, 0xa2, 0xd4, 0xb4, 0x08, 0x45, 0x06, 0x0e, 0xb3, 0xf7, + 0x66, 0xf8, 0xe3, 0x15, 0xeb, 0xf7, 0x2a, 0x4b, 0x8b, 0x3c, 0x2b, 0x3a, + 0xeb, 0x4c, 0x8b, 0xeb, 0xfb, 0x2a, 0xea, 0x8b, 0x05, 0x0e, 0xf9, 0x57, + 0xfa, 0x7d, 0xf7, 0xcc, 0x15, 0xfe, 0x86, 0x43, 0xfa, 0x86, 0xd3, 0x06, + 0x0e, 0xf9, 0x57, 0xf8, 0x68, 0xf7, 0x6a, 0x15, 0xfb, 0x6a, 0xf8, 0x76, + 0xdd, 0xfc, 0x19, 0xf7, 0x8e, 0xf7, 0xf4, 0xdd, 0xfb, 0xf4, 0xf7, 0x7d, + 0xf8, 0x07, 0xdd, 0xfd, 0x02, 0x07, 0xfb, 0xbf, 0xfd, 0x6d, 0xf2, 0x8b, + 0xe0, 0xf7, 0x6a, 0xf7, 0xa1, 0x8b, 0x05, 0xdd, 0x04, 0xfb, 0x82, 0x8b, + 0xf7, 0x1e, 0xf7, 0xf3, 0xef, 0x8b, 0x8b, 0xfb, 0xf3, 0x05, 0x0e, 0xd8, + 0xf7, 0xd4, 0xf7, 0xf6, 0x15, 0xfb, 0xa9, 0x58, 0xf7, 0xa9, 0x06, 0xbe, + 0x07, 0x98, 0xea, 0x15, 0x87, 0x89, 0x88, 0x8a, 0x88, 0x8b, 0x08, 0x7c, + 0x83, 0x93, 0x9a, 0x1f, 0xf7, 0x47, 0x07, 0xca, 0x62, 0xaa, 0x3a, 0x1e, + 0x39, 0x8b, 0x5e, 0x66, 0x89, 0x44, 0x08, 0xc6, 0x06, 0x92, 0xb6, 0x9b, + 0x98, 0xb8, 0x8b, 0x08, 0xb6, 0xa3, 0x7b, 0x6f, 0x1f, 0x7e, 0x07, 0x8b, + 0x75, 0x80, 0x83, 0x65, 0x88, 0x61, 0x88, 0x62, 0x83, 0x7a, 0x84, 0x66, + 0x7b, 0x77, 0x6e, 0x8b, 0x61, 0x08, 0x50, 0xb3, 0x66, 0xcb, 0x1e, 0xb2, + 0x8b, 0xac, 0x99, 0xac, 0xa8, 0x08, 0x91, 0x6c, 0x9b, 0x7f, 0xac, 0x8b, + 0x97, 0x8b, 0x92, 0x8c, 0x98, 0x90, 0x08, 0xb7, 0x07, 0x31, 0xcf, 0x15, + 0x68, 0x61, 0x6c, 0x5a, 0x67, 0x76, 0x9c, 0xa9, 0x1e, 0x8b, 0xab, 0x9f, + 0x9a, 0xbf, 0x92, 0xbc, 0x93, 0x98, 0x8d, 0x99, 0x91, 0x08, 0x58, 0x07, + 0x0e, 0xf7, 0x41, 0xf8, 0x2a, 0x15, 0xf7, 0xd7, 0x2e, 0xfc, 0x09, 0x07, + 0x3b, 0x53, 0x8b, 0x3e, 0xdb, 0xc4, 0x8b, 0xfb, 0xac, 0xf8, 0x6c, 0x8b, + 0x8b, 0xdd, 0xfc, 0x0f, 0x8b, 0x8b, 0xf7, 0x8b, 0xf7, 0x3f, 0xf7, 0x0e, + 0x8b, 0xd7, 0xfb, 0x3f, 0xfb, 0x0d, 0x05, 0x0e, 0xf8, 0x79, 0xa9, 0x9e, + 0x15, 0xb2, 0x67, 0xd8, 0xdf, 0x05, 0xcd, 0x4e, 0xd9, 0x6e, 0xec, 0x8b, + 0xf7, 0x66, 0x8b, 0xf7, 0x22, 0xf7, 0x2e, 0x8b, 0xf7, 0x77, 0x8b, 0xf1, + 0x6d, 0xe9, 0x55, 0xcf, 0x08, 0xe4, 0xec, 0x63, 0xaf, 0x34, 0x2c, 0x05, + 0x4d, 0xc1, 0x3e, 0xa6, 0x30, 0x8b, 0xfb, 0x66, 0x8b, 0xfb, 0x22, 0xfb, + 0x2e, 0x8b, 0xfb, 0x77, 0x8b, 0x2a, 0xa5, 0x36, 0xbd, 0x45, 0x08, 0x3a, + 0x32, 0x05, 0xf7, 0x24, 0xf7, 0x31, 0x15, 0x6d, 0xbf, 0x7b, 0xca, 0x8b, + 0xd0, 0x8b, 0xf7, 0x47, 0xf3, 0xf7, 0x0c, 0xf7, 0x2f, 0x8b, 0xcc, 0x8b, + 0xc5, 0x75, 0xbb, 0x61, 0x08, 0xfc, 0x14, 0xfc, 0x37, 0x05, 0xf8, 0x37, + 0xf8, 0x0e, 0x15, 0xae, 0x55, 0x9d, 0x48, 0x8b, 0x40, 0x8b, 0xfb, 0x47, + 0x23, 0xfb, 0x0c, 0xfb, 0x2f, 0x8b, 0x44, 0x8b, 0x4e, 0xa4, 0x5a, 0xbc, + 0x08, 0xf8, 0x17, 0xf8, 0x39, 0x05, 0x0e, 0xf9, 0x57, 0xf8, 0xfe, 0xf7, + 0xdb, 0x15, 0xf7, 0xdc, 0xdd, 0xfb, 0xdc, 0xf7, 0x82, 0xf7, 0xe4, 0xdd, + 0xfc, 0x41, 0x3f, 0x06, 0x61, 0xc7, 0x50, 0xa7, 0x39, 0x8b, 0x42, 0x8b, + 0x41, 0x6e, 0x5a, 0x5a, 0x47, 0x48, 0x68, 0x23, 0x8b, 0xfb, 0x1c, 0x8b, + 0xfb, 0x10, 0xa7, 0x2f, 0xc6, 0x47, 0xbf, 0x4f, 0xd5, 0x6b, 0xe0, 0x8b, + 0xdc, 0x8b, 0xc4, 0xa8, 0xb9, 0xcc, 0x08, 0x41, 0xf8, 0x46, 0xdd, 0xfb, + 0xe9, 0x07, 0xf7, 0x89, 0x07, 0x2e, 0xfb, 0x25, 0x15, 0x63, 0x3a, 0x4f, + 0x64, 0x37, 0x8b, 0x49, 0x8b, 0x56, 0xa6, 0x68, 0xbe, 0x67, 0xc1, 0x7c, + 0xcc, 0x8b, 0xf0, 0x8b, 0xf1, 0x9a, 0xcc, 0xaf, 0xc1, 0xae, 0xbe, 0xc0, + 0xa6, 0xce, 0x8b, 0xdf, 0x8b, 0xc6, 0x64, 0xb3, 0x3a, 0x08, 0xfb, 0xf9, + 0x07, 0x0e, 0xd3, 0xf7, 0xce, 0xf7, 0xf6, 0x15, 0xfb, 0x9b, 0x58, 0xf7, + 0x9b, 0xbe, 0x06, 0xfb, 0x18, 0xf8, 0x18, 0x15, 0x31, 0x57, 0x4c, 0xfb, + 0x00, 0xfb, 0x01, 0xbf, 0x4c, 0xe5, 0xe4, 0xc0, 0xca, 0xf5, 0xf7, 0x04, + 0x58, 0xc9, 0x30, 0x1f, 0x57, 0x04, 0xc0, 0xaa, 0x5e, 0x3f, 0x42, 0x6b, + 0x5e, 0x57, 0x57, 0x6b, 0xb8, 0xd6, 0xd5, 0xab, 0xb8, 0xbf, 0x1f, 0x0e, + 0xf8, 0xe8, 0xf9, 0x83, 0xf7, 0x33, 0x15, 0x73, 0x46, 0x5c, 0x67, 0x48, + 0x8b, 0x56, 0x8b, 0x5e, 0xa3, 0x6f, 0xb7, 0x77, 0xa9, 0x84, 0xa9, 0x8a, + 0xbf, 0x08, 0xf8, 0x16, 0x06, 0x8b, 0xdb, 0x85, 0xbb, 0x7c, 0xb2, 0x69, + 0xe0, 0x3b, 0xc0, 0x2a, 0x8b, 0x43, 0x8b, 0x4a, 0x6c, 0x67, 0x58, 0x6c, + 0xc1, 0x50, 0xa7, 0x36, 0x8b, 0x41, 0x8b, 0x4c, 0x75, 0x68, 0x64, 0x73, + 0x70, 0x81, 0x6d, 0x89, 0x57, 0x08, 0xdf, 0x06, 0x92, 0xcb, 0xb1, 0xa8, + 0xd8, 0x8b, 0x08, 0xd8, 0xb4, 0x70, 0x58, 0x1f, 0x75, 0x07, 0x8b, 0x64, + 0x78, 0x7d, 0x47, 0x85, 0x37, 0x84, 0x58, 0x81, 0x6b, 0x7d, 0x4d, 0x71, + 0x6c, 0x5d, 0x8b, 0x47, 0x08, 0x2d, 0xcd, 0x4e, 0xf1, 0x1e, 0xd9, 0x8b, + 0xca, 0xab, 0xd6, 0xd9, 0x92, 0x7f, 0x8f, 0x84, 0x90, 0x83, 0x08, 0xae, + 0x57, 0xcd, 0x6c, 0xd8, 0x8b, 0xf7, 0x0a, 0x8b, 0xdf, 0xcf, 0xa0, 0xf7, + 0x06, 0x08, 0x37, 0x06, 0xfc, 0x06, 0x89, 0x15, 0x8b, 0x78, 0x78, 0x70, + 0x6d, 0x74, 0x6a, 0x72, 0x65, 0x7e, 0x63, 0x8b, 0x4d, 0x8b, 0x65, 0xab, + 0x8b, 0xbf, 0x8b, 0xc2, 0xaf, 0xa6, 0xe5, 0x98, 0xe4, 0x98, 0x9c, 0x8f, + 0xa7, 0x97, 0x08, 0x26, 0x07, 0xdb, 0xf7, 0x25, 0x15, 0x92, 0xec, 0xc6, + 0xca, 0xdf, 0x8b, 0x08, 0xe0, 0xc6, 0x4a, 0x2c, 0x1f, 0xfb, 0xba, 0x06, + 0x0e, 0x7c, 0xf7, 0x46, 0xf8, 0xa0, 0x15, 0x37, 0xfc, 0xa0, 0xdf, 0xf8, + 0xa0, 0x06, 0x0e, 0x44, 0xf7, 0x26, 0xf8, 0x39, 0x15, 0xf7, 0xc8, 0x38, + 0xfb, 0xf4, 0x07, 0x4c, 0x59, 0x8b, 0x4b, 0xca, 0xbd, 0x8b, 0xfb, 0xcd, + 0xde, 0x8b, 0x8b, 0xf7, 0xf9, 0xcd, 0xbe, 0x8b, 0xcb, 0x49, 0x58, 0x05, + 0x0e, 0xf7, 0xd2, 0xf8, 0xa5, 0xf8, 0x93, 0x15, 0x6b, 0xa7, 0x51, 0x4a, + 0x05, 0x5e, 0xb8, 0x57, 0x9f, 0x46, 0x8b, 0xfb, 0x28, 0x8b, 0x32, 0x22, + 0x8b, 0xfb, 0x44, 0x8b, 0x3d, 0x9a, 0x50, 0xac, 0x5a, 0x08, 0x49, 0x41, + 0xab, 0x6f, 0xc8, 0xd0, 0x05, 0xb3, 0x62, 0xc3, 0x76, 0xce, 0x8b, 0xf7, + 0x28, 0x8b, 0xe3, 0xf4, 0x8b, 0xf7, 0x44, 0x8b, 0xd7, 0x7d, 0xc3, 0x6d, + 0xbd, 0x08, 0xca, 0xd2, 0x05, 0xfb, 0x10, 0xfb, 0x20, 0x15, 0x97, 0x6c, + 0x91, 0x65, 0x8b, 0x5f, 0x8b, 0xfb, 0x12, 0x52, 0x3d, 0x2e, 0x8b, 0x61, + 0x8b, 0x68, 0x9b, 0x6e, 0xab, 0x08, 0xf7, 0x82, 0xf7, 0xa1, 0x05, 0xfb, + 0x99, 0xfb, 0x7a, 0x15, 0x7d, 0xac, 0x84, 0xb0, 0x8b, 0xba, 0x8b, 0xf7, + 0x12, 0xc4, 0xd9, 0xe8, 0x8b, 0xb7, 0x8b, 0xb3, 0x78, 0xa5, 0x6a, 0x08, + 0xfb, 0x83, 0xfb, 0xa1, 0x05, 0x0e, 0xf9, 0x1f, 0xf9, 0xb8, 0xf7, 0x33, + 0x15, 0x74, 0x46, 0x5c, 0x67, 0x48, 0x8b, 0x56, 0x8b, 0x5e, 0xa3, 0x6f, + 0xb7, 0x77, 0xa9, 0x84, 0xa9, 0x8a, 0xbf, 0x08, 0xf8, 0x16, 0x06, 0x8b, + 0xdb, 0x85, 0xbb, 0x7c, 0xb2, 0x69, 0xe1, 0x3b, 0xbf, 0x29, 0x8b, 0x3a, + 0x8b, 0x44, 0x64, 0x62, 0x48, 0x63, 0xd1, 0x48, 0xaf, 0x32, 0x8b, 0x08, + 0xfb, 0x2b, 0x35, 0x26, 0xfb, 0x47, 0xfb, 0x48, 0xe1, 0x25, 0xf7, 0x2b, + 0x1f, 0xe3, 0x8b, 0xcb, 0xad, 0xb5, 0xd0, 0xb3, 0x49, 0xd0, 0x66, 0xe0, + 0x8b, 0xf7, 0x0b, 0x8b, 0xde, 0xcf, 0xa0, 0xf7, 0x06, 0x08, 0x37, 0x06, + 0xfc, 0xa3, 0xf7, 0xc3, 0x15, 0xe9, 0xc3, 0x3e, 0xfb, 0x15, 0xfb, 0x11, + 0x51, 0x3e, 0x2f, 0x2e, 0x52, 0xd8, 0xf7, 0x14, 0xf7, 0x12, 0xc4, 0xd8, + 0xe8, 0x1f, 0xf7, 0x82, 0xfb, 0x34, 0x15, 0x92, 0xec, 0xc6, 0xca, 0xdf, + 0x8b, 0x08, 0xe0, 0xc6, 0x4a, 0x2c, 0x1f, 0xfb, 0xba, 0x06, 0x0e, 0xf7, + 0xd2, 0xf7, 0xc2, 0xf7, 0xf1, 0x15, 0xc5, 0x8b, 0x8d, 0x8a, 0xa5, 0x86, + 0xc4, 0x7e, 0xad, 0x5a, 0x8b, 0x47, 0x08, 0x32, 0x50, 0x4d, 0x35, 0x1e, + 0x6f, 0x8b, 0x83, 0x8b, 0x8b, 0x3d, 0x05, 0x9c, 0x88, 0x95, 0x8a, 0x9c, + 0x8b, 0xf7, 0x1d, 0x8b, 0xe2, 0xe7, 0x8b, 0xf7, 0x27, 0x8b, 0xe8, 0x60, + 0xc3, 0x2a, 0xac, 0x08, 0xd5, 0xa6, 0xae, 0xb9, 0x8b, 0xd2, 0x8b, 0xf7, + 0x02, 0x3b, 0xd5, 0xfb, 0x0a, 0x8b, 0x4e, 0x8b, 0x52, 0x77, 0x62, 0x68, + 0x67, 0x6b, 0x7b, 0x62, 0x8b, 0x4c, 0x08, 0xfc, 0xae, 0xde, 0xf8, 0xae, + 0x07, 0xd0, 0xbb, 0xb7, 0xd4, 0xd0, 0xbc, 0x5e, 0x4b, 0x4a, 0x52, 0x5d, + 0x3b, 0x1e, 0x82, 0x06, 0x39, 0x07, 0x0e, 0xf8, 0x0a, 0xf8, 0x6e, 0xf7, + 0x6f, 0x15, 0xd6, 0xfb, 0x6f, 0xf3, 0x8b, 0xfb, 0x94, 0xf9, 0x6d, 0xfb, + 0x0c, 0x8b, 0xfb, 0x98, 0xfd, 0x6d, 0xee, 0x8b, 0xd8, 0xf7, 0x6f, 0xf7, + 0xad, 0x8b, 0x05, 0x71, 0xd9, 0x15, 0xfb, 0x7c, 0x8b, 0xf7, 0x0c, 0xf7, + 0xe0, 0xf7, 0x04, 0xfb, 0xe0, 0x05, 0xfb, 0x22, 0xf8, 0xfd, 0x15, 0x23, + 0x24, 0xf3, 0xf2, 0x06, 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, 0x06, + 0x0e, 0xf8, 0x0a, 0xf8, 0x6e, 0xf7, 0x6f, 0x15, 0xd6, 0xfb, 0x6f, 0xf3, + 0x8b, 0xfb, 0x94, 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfb, 0x98, 0xfd, 0x6d, + 0xee, 0x8b, 0xd8, 0xf7, 0x6f, 0xf7, 0xad, 0x8b, 0x05, 0x71, 0xd9, 0x15, + 0xfb, 0x7c, 0x8b, 0xf7, 0x0c, 0xf7, 0xe0, 0xf7, 0x04, 0xfb, 0xe0, 0x05, + 0x3d, 0xf9, 0x16, 0x15, 0x2b, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, + 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0x6e, 0xf7, 0x6f, + 0x15, 0xd6, 0xfb, 0x6f, 0xf3, 0x8b, 0xfb, 0x94, 0xf9, 0x6d, 0xfb, 0x0c, + 0x8b, 0xfb, 0x98, 0xfd, 0x6d, 0xee, 0x8b, 0xd8, 0xf7, 0x6f, 0xf7, 0xad, + 0x8b, 0x05, 0x71, 0xd9, 0x15, 0xfb, 0x7c, 0x8b, 0xf7, 0x0c, 0xf7, 0xe0, + 0xf7, 0x04, 0xfb, 0xe0, 0x05, 0xfb, 0x25, 0xf9, 0x16, 0x15, 0xfb, 0x04, + 0x8b, 0xf7, 0x28, 0xfb, 0x28, 0xc8, 0x8b, 0x2a, 0xf7, 0x28, 0x05, 0x0e, + 0xf8, 0x0a, 0xf8, 0x6e, 0xf7, 0x6f, 0x15, 0xd6, 0xfb, 0x6f, 0xf3, 0x8b, + 0xfb, 0x94, 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfb, 0x98, 0xfd, 0x6d, 0xee, + 0x8b, 0xd8, 0xf7, 0x6f, 0xf7, 0xad, 0x8b, 0x05, 0x71, 0xd9, 0x15, 0xfb, + 0x7c, 0x8b, 0xf7, 0x0c, 0xf7, 0xe0, 0xf7, 0x04, 0xfb, 0xe0, 0x05, 0xfb, + 0x34, 0xf9, 0x17, 0x15, 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdb, + 0x2b, 0xcb, 0x8b, 0x2a, 0xf7, 0x2a, 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, + 0xf8, 0x6e, 0xf7, 0x6f, 0x15, 0xd6, 0xfb, 0x6f, 0xf3, 0x8b, 0xfb, 0x94, + 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfb, 0x98, 0xfd, 0x6d, 0xee, 0x8b, 0xd8, + 0xf7, 0x6f, 0x05, 0xf7, 0xad, 0x06, 0x71, 0xd9, 0x15, 0xfb, 0x7c, 0x8b, + 0xf7, 0x0c, 0xf7, 0xe0, 0xf7, 0x04, 0xfb, 0xe0, 0x05, 0x7d, 0xf8, 0xff, + 0x15, 0x83, 0x72, 0x80, 0x7f, 0x79, 0x8b, 0x7f, 0x8b, 0x70, 0x92, 0x73, + 0x96, 0x08, 0x61, 0x9c, 0x84, 0x8d, 0x76, 0x8b, 0x5f, 0x8b, 0x6c, 0x66, + 0x80, 0x49, 0x08, 0xc5, 0x06, 0x91, 0xa2, 0x97, 0x99, 0x9a, 0x8b, 0x96, + 0x8b, 0x99, 0x87, 0xa3, 0x82, 0x08, 0xc1, 0x76, 0x97, 0x87, 0x9e, 0x8b, + 0xbc, 0x8b, 0xa9, 0xae, 0x95, 0xd0, 0x08, 0x51, 0x06, 0x0e, 0xf8, 0x0a, + 0xf8, 0x6e, 0xf7, 0x6f, 0x15, 0xd6, 0xfb, 0x6f, 0xf3, 0x8b, 0xfb, 0x94, + 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfb, 0x98, 0xfd, 0x6d, 0xee, 0x8b, 0xd8, + 0xf7, 0x6f, 0xf7, 0xad, 0x8b, 0x05, 0x71, 0xd9, 0x15, 0xfb, 0x7c, 0x8b, + 0xf7, 0x0c, 0xf7, 0xe0, 0xf7, 0x04, 0xfb, 0xe0, 0x05, 0xfb, 0x05, 0xf9, + 0x24, 0x15, 0x5b, 0x63, 0x63, 0x5c, 0x5b, 0xb3, 0x63, 0xbb, 0xbb, 0xb3, + 0xb2, 0xbb, 0xbc, 0x64, 0xb2, 0x5a, 0x1f, 0x5f, 0x04, 0xa4, 0x9e, 0x78, + 0x72, 0x74, 0x77, 0x77, 0x73, 0x73, 0x77, 0x9f, 0xa3, 0xa2, 0x9f, 0x9f, + 0xa3, 0x1f, 0x0e, 0xf8, 0x41, 0xf8, 0x0f, 0x74, 0x15, 0xf7, 0x44, 0x8b, + 0xef, 0xed, 0xa1, 0xf7, 0x53, 0x08, 0x2b, 0x06, 0x83, 0x59, 0x81, 0x69, + 0x7c, 0x6d, 0x6d, 0x4f, 0x4d, 0x69, 0x3d, 0x8b, 0x08, 0xfb, 0x25, 0x2f, + 0xf7, 0x08, 0xf7, 0x4b, 0xf7, 0x4f, 0xe3, 0xf7, 0x07, 0xf7, 0x22, 0x1f, + 0xc5, 0x8b, 0xc2, 0x79, 0xa9, 0x6f, 0xa6, 0x72, 0x9a, 0x6c, 0x96, 0x55, + 0x08, 0xea, 0x06, 0x6e, 0xf7, 0x34, 0x2f, 0xd9, 0xfb, 0x34, 0x8b, 0x29, + 0x8b, 0x3c, 0x6c, 0x55, 0x4f, 0x49, 0x43, 0x67, 0x22, 0x8b, 0xfb, 0x09, + 0x8b, 0xfb, 0x22, 0xc0, 0xfb, 0x0c, 0xe6, 0x4a, 0xb6, 0x6d, 0xa9, 0x80, + 0xd7, 0x80, 0x08, 0x6c, 0x46, 0x96, 0x84, 0x05, 0x97, 0x91, 0x92, 0x8d, + 0x97, 0x8b, 0x08, 0xa8, 0x9c, 0x7d, 0x74, 0x71, 0x74, 0x78, 0x6c, 0x1f, + 0x72, 0x8b, 0x78, 0x91, 0x5e, 0xa2, 0x08, 0x82, 0x8f, 0x76, 0x63, 0x05, + 0xc8, 0x70, 0xa5, 0x84, 0xb1, 0x8b, 0x08, 0xd7, 0xba, 0xaf, 0xc4, 0xb6, + 0x6e, 0xa3, 0x59, 0x1f, 0x83, 0x8b, 0x84, 0x8b, 0x7e, 0x89, 0x08, 0x98, + 0xac, 0x05, 0x0e, 0xf8, 0x41, 0xe4, 0xf7, 0xe7, 0x15, 0xfb, 0xe7, 0xf7, + 0xae, 0x07, 0xf7, 0x4c, 0xf7, 0x04, 0xf7, 0x1e, 0xf7, 0x77, 0xf7, 0x76, + 0xfb, 0x04, 0xf7, 0x1e, 0xfb, 0x4c, 0x1f, 0xfb, 0xae, 0xfb, 0xd7, 0x46, + 0x48, 0xd0, 0x06, 0xe8, 0x16, 0xf7, 0x3f, 0xce, 0xfb, 0x3f, 0xf7, 0x85, + 0xf7, 0x41, 0x06, 0xf7, 0x23, 0xd7, 0x2a, 0xfb, 0x4d, 0xfb, 0x4e, 0x3f, + 0x2a, 0xfb, 0x23, 0x1f, 0xfb, 0x41, 0xf7, 0x95, 0x06, 0x0e, 0xf8, 0x0a, + 0xf7, 0x4b, 0xf7, 0xe0, 0x15, 0xf8, 0x21, 0xdd, 0xfc, 0x21, 0xf7, 0x7d, + 0xf8, 0x30, 0xdd, 0xfc, 0x8d, 0xfd, 0x6d, 0xf8, 0x9f, 0xdd, 0xfc, 0x42, + 0xf7, 0x8e, 0x06, 0xf7, 0x18, 0xf8, 0xda, 0x15, 0x23, 0x24, 0xf3, 0xf2, + 0x06, 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, 0x06, 0x0e, 0xf8, 0x0a, + 0xf7, 0x4b, 0xf7, 0xe0, 0x15, 0xf8, 0x21, 0xdd, 0xfc, 0x21, 0xf7, 0x7d, + 0xf8, 0x30, 0xdd, 0xfc, 0x8d, 0xfd, 0x6d, 0xf8, 0x9f, 0xdd, 0xfc, 0x42, + 0xf7, 0x8e, 0x06, 0xf7, 0x4c, 0xf8, 0xf3, 0x15, 0x2a, 0xfb, 0x28, 0xc7, + 0x8b, 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, + 0xf7, 0x4b, 0xf7, 0xe0, 0x15, 0xf8, 0x21, 0xdd, 0xfc, 0x21, 0xf7, 0x7d, + 0xf8, 0x30, 0xdd, 0xfc, 0x8d, 0xfd, 0x6d, 0xf8, 0x9f, 0xdd, 0xfc, 0x42, + 0xf7, 0x8e, 0x06, 0xf7, 0x1d, 0xf8, 0xf3, 0x15, 0xfb, 0x05, 0x8b, 0xf7, + 0x29, 0xfb, 0x28, 0xc7, 0x8b, 0x2b, 0xf7, 0x28, 0x05, 0x0e, 0xf8, 0x0a, + 0xf7, 0x4b, 0xf7, 0xe0, 0x15, 0xf8, 0x21, 0xdd, 0xfc, 0x21, 0xf7, 0x7d, + 0xf8, 0x30, 0xdd, 0xfc, 0x8d, 0xfd, 0x6d, 0xf8, 0x9f, 0xdd, 0xfc, 0x42, + 0xf7, 0x8e, 0x06, 0xf7, 0x06, 0xf8, 0xf4, 0x15, 0x2b, 0xfb, 0x2a, 0xcc, + 0x8b, 0xda, 0xeb, 0xdb, 0x2b, 0xca, 0x8b, 0x2b, 0xf7, 0x2a, 0x2c, 0x8b, + 0x05, 0x0e, 0x7c, 0xf7, 0x55, 0xf9, 0x6d, 0x15, 0x2e, 0xfd, 0x6d, 0xe8, + 0x06, 0xf9, 0x6d, 0x07, 0x3b, 0xf7, 0x46, 0x15, 0x23, 0x24, 0xf3, 0x06, + 0xf2, 0x07, 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, 0x06, 0x0e, 0x7c, + 0xf7, 0x55, 0xf9, 0x6d, 0x15, 0x2e, 0xfd, 0x6d, 0xe8, 0xf9, 0x6d, 0x06, + 0x71, 0xf7, 0x66, 0x15, 0x2b, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, + 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0x7c, 0xf7, 0x55, 0xf9, 0x6d, 0x15, + 0x2e, 0xfd, 0x6d, 0xe8, 0xf9, 0x6d, 0x06, 0x3c, 0xf7, 0x66, 0x15, 0xfb, + 0x05, 0x8b, 0xf7, 0x29, 0xfb, 0x28, 0xc7, 0x8b, 0x2b, 0xf7, 0x28, 0x05, + 0x0e, 0x7c, 0xf7, 0x55, 0xf9, 0x6d, 0x15, 0x2e, 0xfd, 0x6d, 0xe8, 0xf9, + 0x6d, 0x06, 0x29, 0xf7, 0x67, 0x15, 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, + 0xeb, 0xdc, 0x2b, 0xca, 0x8b, 0x2b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0x0e, + 0xf8, 0x41, 0xf9, 0x1a, 0xf9, 0x6d, 0x15, 0x33, 0xfc, 0xe8, 0x06, 0xfc, + 0x11, 0xf8, 0xe8, 0x26, 0x8b, 0x8b, 0xfd, 0x6d, 0xe3, 0x8b, 0x8b, 0xf8, + 0xe3, 0xf8, 0x0c, 0xfc, 0xe3, 0xf5, 0x8b, 0x05, 0xf9, 0x6d, 0x07, 0xfb, + 0x47, 0xf7, 0x4f, 0x15, 0x83, 0x72, 0x7f, 0x7f, 0x7a, 0x8b, 0x7e, 0x8b, + 0x71, 0x92, 0x73, 0x96, 0x08, 0x61, 0x9c, 0x83, 0x8d, 0x77, 0x8b, 0x5f, + 0x8b, 0x6c, 0x66, 0x80, 0x49, 0x08, 0xc4, 0x06, 0x92, 0xa2, 0x97, 0x99, + 0x99, 0x8b, 0x96, 0x8b, 0x9a, 0x87, 0xa2, 0x82, 0x08, 0xc2, 0x76, 0x97, + 0x87, 0x9d, 0x8b, 0xbd, 0x8b, 0xa9, 0xae, 0x95, 0xd0, 0x08, 0x51, 0x06, + 0x0e, 0xf8, 0x79, 0xf8, 0x19, 0xf9, 0x79, 0x15, 0xfb, 0x65, 0xfb, 0x22, + 0xfb, 0x2e, 0xfb, 0x78, 0xfb, 0x78, 0xf7, 0x22, 0xfb, 0x2e, 0xf7, 0x66, + 0x1f, 0xe3, 0x8b, 0xda, 0xa6, 0xc6, 0xbd, 0xda, 0xce, 0xba, 0xf7, 0x05, + 0x8b, 0xf7, 0x0b, 0x08, 0xf7, 0x7f, 0xfb, 0x1f, 0xf7, 0x2d, 0xfb, 0x6a, + 0x1e, 0x39, 0x04, 0xf7, 0x32, 0xf1, 0xfb, 0x0c, 0xfb, 0x4c, 0xfb, 0x44, + 0x22, 0xfb, 0x0c, 0xfb, 0x2e, 0xfb, 0x2f, 0x23, 0xf7, 0x0c, 0xf7, 0x48, + 0xf7, 0x48, 0xf3, 0xf7, 0x0c, 0xf7, 0x2e, 0x1f, 0x6f, 0xf7, 0x93, 0x15, + 0x23, 0x24, 0xf3, 0xf2, 0x06, 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, + 0x06, 0x0e, 0xf8, 0x79, 0xf8, 0x19, 0xf9, 0x79, 0x15, 0xfb, 0x65, 0xfb, + 0x22, 0xfb, 0x2e, 0xfb, 0x78, 0xfb, 0x78, 0xf7, 0x22, 0xfb, 0x2e, 0xf7, + 0x66, 0x1f, 0xe3, 0x8b, 0xda, 0xa6, 0xc6, 0xbd, 0xda, 0xce, 0xba, 0xf7, + 0x05, 0x8b, 0xf7, 0x0b, 0x08, 0xf7, 0x7f, 0xfb, 0x1f, 0xf7, 0x2d, 0xfb, + 0x6a, 0x1e, 0x39, 0x04, 0xf7, 0x32, 0xf1, 0xfb, 0x0c, 0xfb, 0x4c, 0xfb, + 0x44, 0x22, 0xfb, 0x0c, 0xfb, 0x2e, 0xfb, 0x2f, 0x23, 0xf7, 0x0c, 0xf7, + 0x48, 0xf7, 0x48, 0xf3, 0xf7, 0x0c, 0xf7, 0x2e, 0x1f, 0xa9, 0xf7, 0xac, + 0x15, 0x2a, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x04, + 0x8b, 0x05, 0x0e, 0xf8, 0x79, 0xf8, 0x19, 0xf9, 0x79, 0x15, 0xfb, 0x65, + 0xfb, 0x22, 0xfb, 0x2e, 0xfb, 0x78, 0xfb, 0x78, 0xf7, 0x22, 0xfb, 0x2e, + 0xf7, 0x66, 0x1f, 0xe3, 0x8b, 0xda, 0xa6, 0xc6, 0xbd, 0xda, 0xce, 0xba, + 0xf7, 0x05, 0x8b, 0xf7, 0x0b, 0x08, 0xf7, 0x7f, 0xfb, 0x1f, 0xf7, 0x2d, + 0xfb, 0x6a, 0x1e, 0x39, 0x04, 0xf7, 0x32, 0xf1, 0xfb, 0x0c, 0xfb, 0x4c, + 0xfb, 0x44, 0x22, 0xfb, 0x0c, 0xfb, 0x2e, 0xfb, 0x2f, 0x23, 0xf7, 0x0c, + 0xf7, 0x48, 0xf7, 0x48, 0xf3, 0xf7, 0x0c, 0xf7, 0x2e, 0x1f, 0x6c, 0xf7, + 0xac, 0x15, 0xfb, 0x04, 0x8b, 0xf7, 0x28, 0xfb, 0x28, 0xc8, 0x8b, 0x2a, + 0xf7, 0x28, 0x05, 0x0e, 0xf8, 0x79, 0xf8, 0x19, 0xf9, 0x79, 0x15, 0xfb, + 0x65, 0xfb, 0x22, 0xfb, 0x2e, 0xfb, 0x78, 0xfb, 0x78, 0xf7, 0x22, 0xfb, + 0x2e, 0xf7, 0x66, 0x1f, 0xe3, 0x8b, 0xda, 0xa6, 0xc6, 0xbd, 0xda, 0xce, + 0xba, 0xf7, 0x05, 0x8b, 0xf7, 0x0b, 0x08, 0xf7, 0x7f, 0xfb, 0x1f, 0xf7, + 0x2d, 0xfb, 0x6a, 0x1e, 0x39, 0x04, 0xf7, 0x32, 0xf1, 0xfb, 0x0c, 0xfb, + 0x4c, 0xfb, 0x44, 0x22, 0xfb, 0x0c, 0xfb, 0x2e, 0xfb, 0x2f, 0x23, 0xf7, + 0x0c, 0xf7, 0x48, 0xf7, 0x48, 0xf3, 0xf7, 0x0c, 0xf7, 0x2e, 0x1f, 0x5d, + 0xf7, 0xad, 0x15, 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdb, 0x2b, + 0xcb, 0x8b, 0x2a, 0xf7, 0x2a, 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0x79, 0xf8, + 0x19, 0xf9, 0x79, 0x15, 0xfb, 0x65, 0xfb, 0x22, 0xfb, 0x2e, 0xfb, 0x78, + 0xfb, 0x78, 0xf7, 0x22, 0xfb, 0x2e, 0xf7, 0x66, 0x1f, 0xe3, 0x8b, 0xda, + 0xa6, 0xc6, 0xbd, 0xda, 0xce, 0xba, 0xf7, 0x05, 0x8b, 0xf7, 0x0b, 0x08, + 0xf7, 0x7f, 0xfb, 0x1f, 0xf7, 0x2d, 0xfb, 0x6a, 0x1e, 0x39, 0x04, 0xf7, + 0x32, 0xf1, 0xfb, 0x0c, 0xfb, 0x4c, 0xfb, 0x44, 0x22, 0xfb, 0x0c, 0xfb, + 0x2e, 0xfb, 0x2f, 0x23, 0xf7, 0x0c, 0xf7, 0x48, 0xf7, 0x48, 0xf3, 0xf7, + 0x0c, 0xf7, 0x2e, 0x1f, 0xf3, 0xf7, 0x95, 0x15, 0x83, 0x72, 0x7f, 0x7f, + 0x79, 0x8b, 0x7f, 0x8b, 0x70, 0x92, 0x73, 0x96, 0x08, 0x62, 0x9c, 0x83, + 0x8d, 0x76, 0x8b, 0x5f, 0x8b, 0x6c, 0x66, 0x80, 0x49, 0x08, 0xc5, 0x06, + 0x91, 0xa2, 0x98, 0x99, 0x99, 0x8b, 0x96, 0x8b, 0x99, 0x87, 0xa3, 0x82, + 0x08, 0xc1, 0x76, 0x98, 0x87, 0x9d, 0x8b, 0xbc, 0x8b, 0xaa, 0xae, 0x94, + 0xd0, 0x08, 0x52, 0x06, 0x0e, 0xf8, 0x0a, 0xf8, 0xe8, 0xf8, 0x97, 0x15, + 0x8a, 0xf7, 0x23, 0x29, 0xde, 0xfb, 0x3c, 0x8b, 0xfb, 0x34, 0x8b, 0x28, + 0x39, 0x8b, 0xfb, 0x18, 0x8b, 0x32, 0xba, 0x53, 0xeb, 0x72, 0x08, 0xf7, + 0x49, 0x5b, 0x05, 0xe7, 0x73, 0xb5, 0x66, 0x8b, 0x52, 0x8b, 0x64, 0x76, + 0x63, 0x6c, 0x75, 0x6e, 0x77, 0x5d, 0x80, 0x50, 0x8b, 0x3c, 0x8b, 0x55, + 0x9e, 0x68, 0xb5, 0x70, 0xab, 0x7f, 0xae, 0x8c, 0xb8, 0x08, 0x33, 0x06, + 0x8c, 0x48, 0x98, 0x5f, 0xa8, 0x63, 0xbd, 0x47, 0xdf, 0x67, 0xf7, 0x03, + 0x8b, 0xe2, 0x8b, 0xd2, 0x9f, 0xba, 0xaf, 0xbc, 0xb2, 0xaa, 0xcc, 0x8b, + 0xca, 0x8b, 0xe5, 0x53, 0xcd, 0x28, 0xa6, 0x08, 0xfb, 0x4b, 0xbc, 0x05, + 0x33, 0xa3, 0x6b, 0xa7, 0x8b, 0xc3, 0x8b, 0xd5, 0xcc, 0xbc, 0xed, 0x8b, + 0xf7, 0x08, 0x8b, 0xcc, 0x56, 0x8c, 0x2c, 0x08, 0xe3, 0x06, 0xfb, 0x6c, + 0xf7, 0xa7, 0x15, 0xeb, 0xf7, 0x2a, 0x4b, 0x8b, 0x3c, 0x2b, 0x3b, 0xeb, + 0x4b, 0x8b, 0xec, 0xfb, 0x2a, 0xe9, 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf8, + 0xbc, 0xf9, 0x6d, 0x15, 0xfc, 0x94, 0x07, 0x29, 0x44, 0x4f, 0xfb, 0x08, + 0xfb, 0x08, 0x44, 0xc7, 0xed, 0x1e, 0xf8, 0x94, 0x2e, 0xfc, 0x94, 0x07, + 0xfb, 0x26, 0xf7, 0x02, 0x2d, 0xf7, 0x3e, 0xf7, 0x3e, 0xf7, 0x02, 0xe9, + 0xf7, 0x26, 0x1e, 0xf8, 0x94, 0x2e, 0x07, 0xfb, 0x6c, 0xf7, 0x4d, 0x15, + 0x23, 0x24, 0xf3, 0xf2, 0x06, 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, + 0x06, 0x0e, 0xf8, 0x41, 0xf8, 0xbc, 0xf9, 0x6d, 0x15, 0xfc, 0x94, 0x07, + 0x29, 0x44, 0x4f, 0xfb, 0x08, 0xfb, 0x08, 0x44, 0xc7, 0xed, 0x1e, 0xf8, + 0x94, 0x2e, 0xfc, 0x94, 0x07, 0xfb, 0x26, 0xf7, 0x02, 0x2d, 0xf7, 0x3e, + 0xf7, 0x3f, 0xf7, 0x01, 0xe9, 0xf7, 0x26, 0x1e, 0xf8, 0x94, 0x2e, 0x07, + 0xfb, 0x39, 0xf7, 0x66, 0x15, 0x2b, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x29, + 0xf7, 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf8, 0xbc, 0xf9, + 0x6d, 0x15, 0xfc, 0x94, 0x07, 0x29, 0x44, 0x4f, 0xfb, 0x08, 0xfb, 0x08, + 0x44, 0xc7, 0xed, 0x1e, 0xf8, 0x94, 0x2e, 0xfc, 0x94, 0x07, 0xfb, 0x26, + 0xf7, 0x02, 0x2d, 0xf7, 0x3e, 0xf7, 0x3e, 0xf7, 0x02, 0xe9, 0xf7, 0x26, + 0x1e, 0xf8, 0x94, 0x2e, 0x07, 0xfb, 0x6f, 0xf7, 0x66, 0x15, 0xfb, 0x04, + 0x8b, 0xf7, 0x28, 0xfb, 0x28, 0xc8, 0x8b, 0x2a, 0xf7, 0x28, 0x05, 0x0e, + 0xf8, 0x41, 0xf8, 0xbc, 0xf9, 0x6d, 0x15, 0xfc, 0x94, 0x07, 0x29, 0x44, + 0x4f, 0xfb, 0x08, 0xfb, 0x08, 0x44, 0xc7, 0xed, 0x1e, 0xf8, 0x94, 0x2e, + 0xfc, 0x94, 0x07, 0xfb, 0x26, 0xf7, 0x02, 0x2d, 0xf7, 0x3e, 0xf7, 0x3e, + 0xf7, 0x02, 0xe9, 0xf7, 0x26, 0x1e, 0xf8, 0x94, 0x2e, 0x07, 0xfb, 0x7e, + 0xf7, 0x67, 0x15, 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdb, 0x2b, + 0xcb, 0x8b, 0x2a, 0xf7, 0x2a, 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, + 0x17, 0xf7, 0xb2, 0x15, 0xf7, 0xa6, 0xf8, 0x4f, 0xfb, 0x03, 0x8b, 0xfb, + 0x64, 0xfb, 0xf7, 0xfb, 0x69, 0xf7, 0xf7, 0xfb, 0x07, 0x8b, 0xf7, 0xac, + 0xfc, 0x4f, 0x8b, 0xfb, 0xb2, 0xe8, 0x8b, 0x8b, 0xf7, 0xb2, 0x05, 0x76, + 0xf9, 0x21, 0x15, 0x2b, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x28, + 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xf7, 0xd2, 0xf8, 0xd9, 0xf9, 0x6d, 0x15, + 0xfc, 0xa1, 0x39, 0xf8, 0x2e, 0x06, 0xfc, 0x4a, 0xfc, 0xc9, 0x8b, 0x39, + 0xf8, 0xbf, 0x8b, 0x8b, 0xdd, 0xfc, 0x4a, 0x8b, 0xf8, 0x48, 0xf8, 0xc7, + 0x8b, 0xdf, 0x05, 0xfb, 0x6b, 0xc8, 0x15, 0xeb, 0xf7, 0x2a, 0x4b, 0x8b, + 0x3c, 0x2b, 0x3b, 0xeb, 0x4b, 0x8b, 0xec, 0xfb, 0x2a, 0xe9, 0x8b, 0x05, + 0x0e, 0xf8, 0x0a, 0xf7, 0x4d, 0xf7, 0x51, 0x15, 0xf7, 0x79, 0x06, 0xf7, + 0x0b, 0xdf, 0xe1, 0xf7, 0x0e, 0xf7, 0x18, 0x36, 0xdb, 0xfb, 0x1f, 0x1f, + 0xfb, 0x64, 0xf7, 0x0c, 0x2e, 0xfd, 0x6d, 0xe8, 0xf7, 0x51, 0x06, 0xdd, + 0x04, 0xf7, 0x94, 0xf7, 0x56, 0x07, 0xe2, 0xbe, 0x5b, 0x3b, 0x3b, 0x58, + 0x5b, 0x34, 0x1f, 0xfb, 0x56, 0x06, 0x0e, 0xf8, 0x0a, 0xf8, 0x17, 0xf7, + 0xb2, 0x15, 0xf7, 0xa6, 0xf8, 0x4f, 0xfb, 0x03, 0x8b, 0xfb, 0x64, 0xfb, + 0xf7, 0xfb, 0x6a, 0xf7, 0xf7, 0xfb, 0x07, 0x8b, 0xf7, 0xad, 0xfc, 0x4f, + 0x8b, 0xfb, 0xb2, 0xe8, 0x8b, 0x05, 0xf7, 0xb2, 0x07, 0x40, 0xf9, 0x08, + 0x15, 0x23, 0x24, 0xf3, 0x06, 0xf2, 0x07, 0xf7, 0x36, 0x16, 0x23, 0x24, + 0xf3, 0xf2, 0x06, 0x0e, 0xf8, 0xab, 0xbc, 0x15, 0x82, 0x89, 0x87, 0x8b, + 0x86, 0x8b, 0x08, 0x6e, 0x7b, 0x9a, 0xa5, 0x1f, 0xf7, 0xc8, 0x07, 0xe8, + 0x47, 0xbd, 0xfb, 0x15, 0x1e, 0x3f, 0x8b, 0x4c, 0x75, 0x68, 0x64, 0x73, + 0x70, 0x81, 0x6d, 0x89, 0x57, 0x08, 0xdf, 0x06, 0x92, 0xcb, 0xb1, 0xa8, + 0xd9, 0x8b, 0x08, 0xd6, 0xb5, 0x6f, 0x59, 0x1f, 0x75, 0x07, 0x8b, 0x68, + 0x76, 0x7c, 0x49, 0x83, 0xfb, 0x0a, 0x7c, 0x79, 0x87, 0x6b, 0x7e, 0x4e, + 0x72, 0x6c, 0x5c, 0x8b, 0x47, 0x8b, 0x2c, 0xcd, 0x4f, 0xf5, 0x8b, 0xcd, + 0x8b, 0xc0, 0xa2, 0xc6, 0xc1, 0x91, 0x56, 0xa5, 0x73, 0xc1, 0x8b, 0x08, + 0x9c, 0x8b, 0x98, 0x8d, 0xa6, 0x92, 0x08, 0xca, 0x07, 0xfb, 0x26, 0xf7, + 0x08, 0x15, 0x8b, 0x6f, 0x83, 0x7a, 0x72, 0x74, 0x69, 0x6c, 0x62, 0x7b, + 0x5a, 0x8b, 0x4a, 0x8b, 0x65, 0xaa, 0x8b, 0xc0, 0x8b, 0xc2, 0xb0, 0xa7, + 0xe4, 0x98, 0xe3, 0x97, 0x9d, 0x8f, 0xa7, 0x98, 0x08, 0x2d, 0x07, 0xfb, + 0x25, 0xf8, 0xba, 0x15, 0x23, 0x24, 0xf3, 0xf2, 0x06, 0xf7, 0x36, 0x16, + 0x23, 0x24, 0xf3, 0x06, 0xf2, 0x07, 0x0e, 0xf8, 0xab, 0xbc, 0x15, 0x82, + 0x89, 0x87, 0x8b, 0x86, 0x8b, 0x08, 0x6e, 0x7b, 0x9a, 0xa5, 0x1f, 0xf7, + 0xc8, 0x07, 0xe8, 0x47, 0xbd, 0xfb, 0x15, 0x1e, 0x3f, 0x8b, 0x4c, 0x75, + 0x68, 0x64, 0x73, 0x70, 0x81, 0x6d, 0x89, 0x57, 0x08, 0xdf, 0x06, 0x92, + 0xcb, 0xb1, 0xa8, 0xd9, 0x8b, 0x08, 0xd6, 0xb5, 0x6f, 0x59, 0x1f, 0x75, + 0x07, 0x8b, 0x68, 0x76, 0x7c, 0x49, 0x83, 0xfb, 0x0a, 0x7c, 0x79, 0x87, + 0x6b, 0x7e, 0x4e, 0x72, 0x6c, 0x5c, 0x8b, 0x47, 0x8b, 0x2c, 0xcd, 0x4f, + 0xf5, 0x8b, 0xcd, 0x8b, 0xc0, 0xa2, 0xc6, 0xc1, 0x91, 0x56, 0xa5, 0x73, + 0xc1, 0x8b, 0x08, 0x9c, 0x8b, 0x98, 0x8d, 0xa6, 0x92, 0x08, 0xca, 0x07, + 0xfb, 0x26, 0xf7, 0x08, 0x15, 0x8b, 0x6f, 0x83, 0x7a, 0x72, 0x74, 0x69, + 0x6c, 0x62, 0x7b, 0x5a, 0x8b, 0x4a, 0x8b, 0x65, 0xaa, 0x8b, 0xc0, 0x8b, + 0xc2, 0xb0, 0xa7, 0xe4, 0x98, 0xe3, 0x97, 0x9d, 0x8f, 0xa7, 0x98, 0x08, + 0x2d, 0x07, 0x36, 0xf8, 0xd3, 0x15, 0x2a, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, + 0x29, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x0e, 0xf8, 0xab, 0xbc, 0x15, + 0x82, 0x89, 0x87, 0x8b, 0x86, 0x8b, 0x08, 0x6e, 0x7b, 0x9a, 0xa5, 0x1f, + 0xf7, 0xc8, 0x07, 0xe8, 0x47, 0xbd, 0xfb, 0x15, 0x1e, 0x3f, 0x8b, 0x4c, + 0x75, 0x68, 0x64, 0x73, 0x70, 0x81, 0x6d, 0x89, 0x57, 0x08, 0xdf, 0x06, + 0x92, 0xcb, 0xb1, 0xa8, 0xd9, 0x8b, 0x08, 0xd6, 0xb5, 0x6f, 0x59, 0x1f, + 0x75, 0x07, 0x8b, 0x68, 0x76, 0x7c, 0x49, 0x83, 0xfb, 0x0a, 0x7c, 0x79, + 0x87, 0x6b, 0x7e, 0x4e, 0x72, 0x6c, 0x5c, 0x8b, 0x47, 0x8b, 0x2c, 0xcd, + 0x4f, 0xf5, 0x8b, 0xcd, 0x8b, 0xc0, 0xa2, 0xc6, 0xc1, 0x91, 0x56, 0xa5, + 0x73, 0xc1, 0x8b, 0x08, 0x9c, 0x8b, 0x98, 0x8d, 0xa6, 0x92, 0x08, 0xca, + 0x07, 0xfb, 0x26, 0xf7, 0x08, 0x15, 0x8b, 0x6f, 0x83, 0x7a, 0x72, 0x74, + 0x69, 0x6c, 0x62, 0x7b, 0x5a, 0x8b, 0x4a, 0x8b, 0x65, 0xaa, 0x8b, 0xc0, + 0x8b, 0xc2, 0xb0, 0xa7, 0xe4, 0x98, 0xe3, 0x97, 0x9d, 0x8f, 0xa7, 0x98, + 0x08, 0x2d, 0x07, 0xfb, 0x1f, 0xf8, 0xd3, 0x15, 0xfb, 0x05, 0x8b, 0xf7, + 0x29, 0xfb, 0x28, 0xc7, 0x8b, 0x2b, 0xf7, 0x28, 0x05, 0x0e, 0xf8, 0xab, + 0xbc, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x86, 0x8b, 0x08, 0x6e, 0x7b, 0x9a, + 0xa5, 0x1f, 0xf7, 0xc8, 0x07, 0xe8, 0x47, 0xbd, 0xfb, 0x15, 0x1e, 0x3f, + 0x8b, 0x4c, 0x75, 0x68, 0x64, 0x73, 0x70, 0x81, 0x6d, 0x89, 0x57, 0x08, + 0xdf, 0x06, 0x92, 0xcb, 0xb1, 0xa8, 0xd9, 0x8b, 0x08, 0xd6, 0xb5, 0x6f, + 0x59, 0x1f, 0x75, 0x07, 0x8b, 0x68, 0x76, 0x7c, 0x49, 0x83, 0xfb, 0x0a, + 0x7c, 0x79, 0x87, 0x6b, 0x7e, 0x4e, 0x72, 0x6c, 0x5c, 0x8b, 0x47, 0x8b, + 0x2c, 0xcd, 0x4f, 0xf5, 0x8b, 0xcd, 0x8b, 0xc0, 0xa2, 0xc6, 0xc1, 0x91, + 0x56, 0xa5, 0x73, 0xc1, 0x8b, 0x08, 0x9c, 0x8b, 0x98, 0x8d, 0xa6, 0x92, + 0x08, 0xca, 0x07, 0xfb, 0x26, 0xf7, 0x08, 0x15, 0x8b, 0x6f, 0x83, 0x7a, + 0x72, 0x74, 0x69, 0x6c, 0x62, 0x7b, 0x5a, 0x8b, 0x4a, 0x8b, 0x65, 0xaa, + 0x8b, 0xc0, 0x8b, 0xc2, 0xb0, 0xa7, 0xe4, 0x98, 0xe3, 0x97, 0x9d, 0x8f, + 0xa7, 0x98, 0x08, 0x2d, 0x07, 0xfb, 0x35, 0xf8, 0xd4, 0x15, 0x2b, 0xfb, + 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdb, 0x2b, 0xcb, 0x8b, 0x2a, 0xf7, 0x2a, + 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0xab, 0xbc, 0x15, 0x82, 0x89, 0x87, 0x8b, + 0x86, 0x8b, 0x08, 0x6e, 0x7b, 0x9a, 0xa5, 0x1f, 0xf7, 0xc8, 0x07, 0xe8, + 0x47, 0xbd, 0xfb, 0x15, 0x1e, 0x3f, 0x8b, 0x4c, 0x75, 0x68, 0x64, 0x73, + 0x70, 0x81, 0x6d, 0x89, 0x57, 0x08, 0xdf, 0x06, 0x92, 0xcb, 0xb1, 0xa8, + 0xd9, 0x8b, 0x08, 0xd6, 0xb5, 0x6f, 0x59, 0x1f, 0x75, 0x07, 0x8b, 0x68, + 0x76, 0x7c, 0x49, 0x83, 0xfb, 0x0a, 0x7c, 0x79, 0x87, 0x6b, 0x7e, 0x4e, + 0x72, 0x6c, 0x5c, 0x8b, 0x47, 0x8b, 0x2c, 0xcd, 0x4f, 0xf5, 0x8b, 0xcd, + 0x8b, 0xc0, 0xa2, 0xc6, 0xc1, 0x91, 0x56, 0xa5, 0x73, 0xc1, 0x8b, 0x08, + 0x9c, 0x8b, 0x98, 0x8d, 0xa6, 0x92, 0x08, 0xca, 0x07, 0xfb, 0x26, 0xf7, + 0x08, 0x15, 0x8b, 0x6f, 0x83, 0x7a, 0x72, 0x74, 0x69, 0x6c, 0x62, 0x7b, + 0x5a, 0x8b, 0x4a, 0x8b, 0x65, 0xaa, 0x8b, 0xc0, 0x8b, 0xc2, 0xb0, 0xa7, + 0xe4, 0x98, 0xe3, 0x97, 0x9d, 0x8f, 0xa7, 0x98, 0x08, 0x2d, 0x07, 0x7d, + 0xf8, 0xbc, 0x15, 0x82, 0x72, 0x80, 0x80, 0x79, 0x8b, 0x7f, 0x8b, 0x71, + 0x92, 0x72, 0x95, 0x08, 0x63, 0x9c, 0x82, 0x8d, 0x76, 0x8b, 0x5f, 0x8b, + 0x6c, 0x67, 0x80, 0x48, 0x08, 0xc5, 0x06, 0x91, 0xa2, 0x97, 0x99, 0x9a, + 0x8b, 0x96, 0x8b, 0x99, 0x87, 0xa3, 0x82, 0x08, 0xc1, 0x76, 0x98, 0x87, + 0x9d, 0x8b, 0xbc, 0x8b, 0xa9, 0xae, 0x95, 0xd0, 0x08, 0x52, 0x06, 0x0e, + 0xf8, 0xab, 0xbc, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x86, 0x8b, 0x08, 0x6e, + 0x7b, 0x9a, 0xa5, 0x1f, 0xf7, 0xc8, 0x07, 0xe8, 0x47, 0xbd, 0xfb, 0x15, + 0x1e, 0x3f, 0x8b, 0x4c, 0x75, 0x68, 0x64, 0x73, 0x70, 0x81, 0x6d, 0x89, + 0x57, 0x08, 0xdf, 0x06, 0x92, 0xcb, 0xb1, 0xa8, 0xd9, 0x8b, 0x08, 0xd6, + 0xb5, 0x6f, 0x59, 0x1f, 0x75, 0x07, 0x8b, 0x68, 0x76, 0x7c, 0x49, 0x83, + 0xfb, 0x0a, 0x7c, 0x79, 0x87, 0x6b, 0x7e, 0x4e, 0x72, 0x6c, 0x5c, 0x8b, + 0x47, 0x8b, 0x2c, 0xcd, 0x4f, 0xf5, 0x8b, 0xcd, 0x8b, 0xc0, 0xa2, 0xc6, + 0xc1, 0x91, 0x56, 0xa5, 0x73, 0xc1, 0x8b, 0x08, 0x9c, 0x8b, 0x98, 0x8d, + 0xa6, 0x92, 0x08, 0xca, 0x07, 0xfb, 0x26, 0xf7, 0x08, 0x15, 0x8b, 0x6f, + 0x83, 0x7a, 0x72, 0x74, 0x69, 0x6c, 0x62, 0x7b, 0x5a, 0x8b, 0x4a, 0x8b, + 0x65, 0xaa, 0x8b, 0xc0, 0x8b, 0xc2, 0xb0, 0xa7, 0xe4, 0x98, 0xe3, 0x97, + 0x9d, 0x8f, 0xa7, 0x98, 0x08, 0x2d, 0x07, 0xfb, 0x06, 0xf8, 0xe1, 0x15, + 0x5b, 0x63, 0x63, 0x5c, 0x5b, 0xb3, 0x63, 0xbb, 0xbb, 0xb3, 0xb2, 0xbb, + 0xbc, 0x64, 0xb2, 0x5a, 0x1f, 0x5f, 0x04, 0xa4, 0x9e, 0x78, 0x72, 0x74, + 0x77, 0x77, 0x73, 0x73, 0x77, 0x9f, 0xa3, 0xa2, 0x9f, 0x9f, 0xa3, 0x1f, + 0x0e, 0xf7, 0x63, 0xf7, 0x9c, 0x74, 0x15, 0xf7, 0x0f, 0x8b, 0xde, 0xd9, + 0x92, 0xf7, 0x11, 0x08, 0x37, 0x06, 0x7d, 0x37, 0x60, 0x60, 0x44, 0x8b, + 0x08, 0x2f, 0x54, 0xd6, 0xf7, 0x10, 0xf7, 0x18, 0xc1, 0xd9, 0xe6, 0x1f, + 0xd1, 0x8b, 0xb7, 0x62, 0x95, 0x42, 0x08, 0xdf, 0x06, 0x87, 0xbe, 0x80, + 0xac, 0x77, 0xa8, 0x67, 0xbc, 0x4c, 0xa8, 0x42, 0x8b, 0xfb, 0x21, 0x8b, + 0x2f, 0xfb, 0x04, 0x8b, 0xfb, 0x42, 0x8b, 0x22, 0xaf, 0x35, 0xcc, 0x5d, + 0xa6, 0x77, 0xa2, 0x82, 0xb6, 0x83, 0x08, 0x6c, 0x44, 0x97, 0x84, 0x05, + 0x97, 0x91, 0x92, 0x8d, 0x97, 0x8b, 0x08, 0xa8, 0x9c, 0x7d, 0x74, 0x71, + 0x74, 0x78, 0x6c, 0x1f, 0x72, 0x8b, 0x77, 0x91, 0x5f, 0xa2, 0x08, 0x82, + 0x8f, 0x76, 0x62, 0x05, 0xcb, 0x70, 0xa1, 0x85, 0xb2, 0x8b, 0x08, 0xd7, + 0xba, 0xaf, 0xc4, 0xb5, 0x6e, 0xa4, 0x59, 0x1f, 0x83, 0x8b, 0x85, 0x8b, + 0x7d, 0x89, 0x08, 0x98, 0xac, 0x05, 0x0e, 0xf8, 0x95, 0xf7, 0x7e, 0x15, + 0x8b, 0xdb, 0x85, 0xbb, 0x7c, 0xb2, 0x69, 0xe1, 0x3b, 0xbf, 0x29, 0x8b, + 0x08, 0xfb, 0x26, 0x2d, 0xfb, 0x04, 0xfb, 0x40, 0xfb, 0x40, 0xe6, 0x21, + 0xf7, 0x27, 0x1f, 0xf7, 0x0c, 0x8b, 0xde, 0xcf, 0xa0, 0xf7, 0x06, 0x08, + 0x37, 0x06, 0x74, 0x46, 0x5c, 0x67, 0x48, 0x8b, 0x56, 0x8b, 0x5e, 0xa3, + 0x6f, 0xb7, 0x77, 0xa9, 0x84, 0xa9, 0x8a, 0xbf, 0x08, 0xf8, 0x16, 0x06, + 0xfc, 0x14, 0xcf, 0x15, 0x92, 0xec, 0xc6, 0xca, 0xdf, 0x8b, 0xdd, 0x8b, + 0xca, 0x47, 0x8b, 0x35, 0x8b, 0x89, 0x8b, 0x89, 0x8a, 0x89, 0x08, 0xfb, + 0xba, 0x06, 0xf7, 0x14, 0xf8, 0x31, 0x15, 0x23, 0x24, 0xf3, 0xf2, 0x06, + 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, 0x06, 0x0e, 0xf8, 0x95, 0xf7, + 0x7e, 0x15, 0x8b, 0xdb, 0x85, 0xbb, 0x7c, 0xb2, 0x69, 0xe1, 0x3b, 0xbf, + 0x29, 0x8b, 0x08, 0xfb, 0x26, 0x2d, 0xfb, 0x04, 0xfb, 0x40, 0xfb, 0x40, + 0xe6, 0x21, 0xf7, 0x27, 0x1f, 0xf7, 0x0c, 0x8b, 0xde, 0xcf, 0xa0, 0xf7, + 0x06, 0x08, 0x37, 0x06, 0x74, 0x46, 0x5c, 0x67, 0x48, 0x8b, 0x56, 0x8b, + 0x5e, 0xa3, 0x6f, 0xb7, 0x77, 0xa9, 0x84, 0xa9, 0x8a, 0xbf, 0x08, 0xf8, + 0x16, 0x06, 0xfc, 0x14, 0xcf, 0x15, 0x92, 0xec, 0xc6, 0xca, 0xdf, 0x8b, + 0xdd, 0x8b, 0xca, 0x47, 0x8b, 0x35, 0x8b, 0x89, 0x8b, 0x89, 0x8a, 0x89, + 0x08, 0xfb, 0xba, 0x06, 0xf7, 0x47, 0xf8, 0x4a, 0x15, 0x2b, 0xfb, 0x28, + 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xf8, + 0x95, 0xf7, 0x7e, 0x15, 0x8b, 0xdb, 0x85, 0xbb, 0x7c, 0xb2, 0x69, 0xe1, + 0x3b, 0xbf, 0x29, 0x8b, 0x08, 0xfb, 0x26, 0x2d, 0xfb, 0x04, 0xfb, 0x40, + 0xfb, 0x40, 0xe6, 0x21, 0xf7, 0x27, 0x1f, 0xf7, 0x0c, 0x8b, 0xde, 0xcf, + 0xa0, 0xf7, 0x06, 0x08, 0x37, 0x06, 0x74, 0x46, 0x5c, 0x67, 0x48, 0x8b, + 0x56, 0x8b, 0x5e, 0xa3, 0x6f, 0xb7, 0x77, 0xa9, 0x84, 0xa9, 0x8a, 0xbf, + 0x08, 0xf8, 0x16, 0x06, 0xfc, 0x14, 0xcf, 0x15, 0x92, 0xec, 0xc6, 0xca, + 0xdf, 0x8b, 0xdd, 0x8b, 0xca, 0x47, 0x8b, 0x35, 0x8b, 0x89, 0x8b, 0x89, + 0x8a, 0x89, 0x08, 0xfb, 0xba, 0x06, 0xf7, 0x0e, 0xf8, 0x4a, 0x15, 0xfb, + 0x04, 0x8b, 0xf7, 0x29, 0xfb, 0x28, 0xc7, 0x8b, 0x2a, 0xf7, 0x28, 0x05, + 0x0e, 0xf8, 0x95, 0xf7, 0x7e, 0x15, 0x8b, 0xdb, 0x85, 0xbb, 0x7c, 0xb2, + 0x69, 0xe1, 0x3b, 0xbf, 0x29, 0x8b, 0x08, 0xfb, 0x26, 0x2d, 0xfb, 0x04, + 0xfb, 0x40, 0xfb, 0x40, 0xe6, 0x21, 0xf7, 0x27, 0x1f, 0xf7, 0x0c, 0x8b, + 0xde, 0xcf, 0xa0, 0xf7, 0x06, 0x08, 0x37, 0x06, 0x74, 0x46, 0x5c, 0x67, + 0x48, 0x8b, 0x56, 0x8b, 0x5e, 0xa3, 0x6f, 0xb7, 0x77, 0xa9, 0x84, 0xa9, + 0x8a, 0xbf, 0x08, 0xf8, 0x16, 0x06, 0xfc, 0x14, 0xcf, 0x15, 0x92, 0xec, + 0xc6, 0xca, 0xdf, 0x8b, 0xdd, 0x8b, 0xca, 0x47, 0x8b, 0x35, 0x8b, 0x89, + 0x8b, 0x89, 0x8a, 0x89, 0x08, 0xfb, 0xba, 0x06, 0xf7, 0x02, 0xf8, 0x4b, + 0x15, 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdc, 0x2b, 0xca, 0x8b, + 0x2b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0x0e, 0x7c, 0xf7, 0x45, 0xf8, 0xa0, + 0x15, 0x38, 0x06, 0xfc, 0xa0, 0xde, 0x07, 0xf8, 0xa0, 0x07, 0x45, 0xf7, + 0x4d, 0x15, 0x23, 0x24, 0xf3, 0x06, 0xf2, 0x07, 0xf7, 0x36, 0x16, 0x23, + 0x24, 0xf3, 0xf2, 0x06, 0x0e, 0x7c, 0xf7, 0x45, 0xf8, 0xa0, 0x15, 0x38, + 0xfc, 0xa0, 0xde, 0xf8, 0xa0, 0x06, 0x7b, 0xf7, 0x6c, 0x15, 0x2b, 0xfb, + 0x28, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, + 0x7c, 0xf7, 0x45, 0xf8, 0xa0, 0x15, 0x38, 0xfc, 0xa0, 0xde, 0xf8, 0xa0, + 0x06, 0x46, 0xf7, 0x6c, 0x15, 0xfb, 0x05, 0x8b, 0xf7, 0x29, 0xfb, 0x28, + 0xc7, 0x8b, 0x2b, 0xf7, 0x28, 0x05, 0x0e, 0x7c, 0xf7, 0x45, 0xf8, 0xa0, + 0x15, 0x38, 0xfc, 0xa0, 0xde, 0xf8, 0xa0, 0x06, 0x33, 0xf7, 0x6d, 0x15, + 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdc, 0x2b, 0xca, 0x8b, 0x2b, + 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0x0e, 0xd1, 0xf8, 0xa0, 0x15, 0xfc, 0xa0, + 0xdf, 0xf7, 0xb5, 0x07, 0xf6, 0xc3, 0xd1, 0xe1, 0xcd, 0xb5, 0x63, 0x4c, + 0x1e, 0xfb, 0xff, 0xde, 0xf8, 0x20, 0x07, 0xe2, 0x4a, 0xc3, 0x26, 0x1e, + 0x3d, 0x8b, 0x59, 0x6d, 0x5d, 0x42, 0x08, 0xe3, 0x07, 0x3e, 0x06, 0xf7, + 0xc8, 0xf7, 0x55, 0x15, 0x82, 0x72, 0x80, 0x80, 0x79, 0x8b, 0x7f, 0x8b, + 0x71, 0x92, 0x72, 0x95, 0x08, 0x63, 0x9c, 0x83, 0x8d, 0x75, 0x8b, 0x5f, + 0x8b, 0x6d, 0x67, 0x80, 0x48, 0x08, 0xc4, 0x06, 0x92, 0xa2, 0x97, 0x99, + 0x99, 0x8b, 0x96, 0x8b, 0x99, 0x87, 0xa3, 0x82, 0x08, 0xc1, 0x76, 0x98, + 0x87, 0x9d, 0x8b, 0xbd, 0x8b, 0xa8, 0xae, 0x96, 0xd0, 0x08, 0x51, 0x06, + 0x0e, 0xf7, 0xa4, 0xf8, 0xaf, 0x15, 0xfb, 0x27, 0x32, 0x22, 0xfb, 0x44, + 0xfb, 0x44, 0xe3, 0x22, 0xf7, 0x29, 0xf7, 0x27, 0xe5, 0xf4, 0xf7, 0x40, + 0xf7, 0x49, 0x34, 0xf3, 0xfb, 0x2b, 0x1f, 0x8c, 0x3e, 0x15, 0xe9, 0xc3, + 0x3e, 0xfb, 0x16, 0xfb, 0x0f, 0x51, 0x3d, 0x2f, 0x2e, 0x52, 0xd8, 0xf7, + 0x13, 0xf7, 0x12, 0xc4, 0xd9, 0xe8, 0x1f, 0x6e, 0xf7, 0x91, 0x15, 0x23, + 0x24, 0xf3, 0xf2, 0x06, 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, 0x06, + 0x0e, 0xf7, 0xa4, 0xf8, 0xaf, 0x15, 0xfb, 0x27, 0x32, 0x22, 0xfb, 0x44, + 0xfb, 0x44, 0xe3, 0x22, 0xf7, 0x29, 0xf7, 0x27, 0xe5, 0xf4, 0xf7, 0x40, + 0xf7, 0x49, 0x34, 0xf3, 0xfb, 0x2b, 0x1f, 0x8c, 0x3e, 0x15, 0xe9, 0xc3, + 0x3e, 0xfb, 0x16, 0xfb, 0x0f, 0x51, 0x3d, 0x2f, 0x2e, 0x52, 0xd8, 0xf7, + 0x13, 0xf7, 0x12, 0xc4, 0xd9, 0xe8, 0x1f, 0xa4, 0xf7, 0xaa, 0x15, 0x2b, + 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x05, 0x8b, 0x05, + 0x0e, 0xf7, 0xa4, 0xf8, 0xaf, 0x15, 0xfb, 0x27, 0x32, 0x22, 0xfb, 0x44, + 0xfb, 0x44, 0xe3, 0x22, 0xf7, 0x29, 0xf7, 0x27, 0xe5, 0xf4, 0xf7, 0x40, + 0xf7, 0x49, 0x34, 0xf3, 0xfb, 0x2b, 0x1f, 0x8c, 0x3e, 0x15, 0xe9, 0xc3, + 0x3e, 0xfb, 0x16, 0xfb, 0x0f, 0x51, 0x3d, 0x2f, 0x2e, 0x52, 0xd8, 0xf7, + 0x13, 0xf7, 0x12, 0xc4, 0xd9, 0xe8, 0x1f, 0x6f, 0xf7, 0xaa, 0x15, 0xfb, + 0x05, 0x8b, 0xf7, 0x29, 0xfb, 0x28, 0xc7, 0x8b, 0x2b, 0xf7, 0x28, 0x05, + 0x0e, 0xf7, 0xa4, 0xf8, 0xaf, 0x15, 0xfb, 0x27, 0x32, 0x22, 0xfb, 0x44, + 0xfb, 0x44, 0xe3, 0x22, 0xf7, 0x29, 0xf7, 0x27, 0xe5, 0xf4, 0xf7, 0x40, + 0xf7, 0x49, 0x34, 0xf3, 0xfb, 0x2b, 0x1f, 0x8c, 0x3e, 0x15, 0xe9, 0xc3, + 0x3e, 0xfb, 0x16, 0xfb, 0x0f, 0x51, 0x3d, 0x2f, 0x2e, 0x52, 0xd8, 0xf7, + 0x13, 0xf7, 0x12, 0xc4, 0xd9, 0xe8, 0x1f, 0x5c, 0xf7, 0xab, 0x15, 0x2b, + 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, 0xdb, 0x2b, 0xcb, 0x8b, 0x2a, 0xf7, + 0x2a, 0x2d, 0x8b, 0x05, 0x0e, 0xf7, 0xa4, 0xf8, 0xaf, 0x15, 0xfb, 0x27, + 0x32, 0x22, 0xfb, 0x44, 0xfb, 0x44, 0xe3, 0x22, 0xf7, 0x29, 0xf7, 0x27, + 0xe5, 0xf4, 0xf7, 0x40, 0x1f, 0xf7, 0x49, 0x34, 0xf3, 0xfb, 0x2b, 0x1e, + 0x8c, 0x3e, 0x15, 0xe9, 0xc3, 0x3e, 0xfb, 0x16, 0xfb, 0x0f, 0x51, 0x3d, + 0x2f, 0x2e, 0x52, 0xd8, 0xf7, 0x13, 0xf7, 0x12, 0xc4, 0xd9, 0xe8, 0x1f, + 0xf2, 0xf7, 0x93, 0x15, 0x82, 0x72, 0x80, 0x80, 0x79, 0x8b, 0x7f, 0x8b, + 0x71, 0x92, 0x72, 0x95, 0x08, 0x63, 0x9c, 0x83, 0x8d, 0x75, 0x8b, 0x5f, + 0x8b, 0x6c, 0x67, 0x80, 0x48, 0x08, 0xc5, 0x06, 0x91, 0xa2, 0x98, 0x99, + 0x99, 0x8b, 0x96, 0x8b, 0x99, 0x87, 0xa3, 0x82, 0x08, 0xc1, 0x76, 0x98, + 0x87, 0x9d, 0x8b, 0xbc, 0x8b, 0xa9, 0xae, 0x95, 0xd0, 0x08, 0x52, 0x06, + 0x0e, 0xf7, 0x63, 0xf8, 0x4a, 0xf8, 0x0e, 0x15, 0x8a, 0xf2, 0x47, 0xc5, + 0xfb, 0x0d, 0x8b, 0xfb, 0x0e, 0x8b, 0x3c, 0x4c, 0x8b, 0x2a, 0x8b, 0x39, + 0xb5, 0x64, 0xf7, 0x10, 0x6d, 0x08, 0xd9, 0x78, 0x05, 0xc5, 0x7d, 0xa2, + 0x76, 0x8b, 0x65, 0x8b, 0x5a, 0x5a, 0x6a, 0x42, 0x8b, 0x5e, 0x8b, 0x65, + 0x98, 0x76, 0xa1, 0x7e, 0x9a, 0x85, 0x9a, 0x86, 0xb0, 0x08, 0x33, 0x06, + 0x8f, 0xfb, 0x0d, 0xcf, 0x51, 0xf7, 0x1d, 0x8b, 0xf7, 0x18, 0x8b, 0xdf, + 0xcc, 0x8b, 0xf0, 0x8b, 0xd9, 0x5f, 0xb6, 0x23, 0xa4, 0x08, 0x3b, 0x9e, + 0x05, 0x47, 0x9b, 0x6e, 0xa1, 0x8b, 0xb0, 0x8b, 0xbb, 0xb6, 0xaa, 0xcf, + 0x8b, 0xce, 0x8b, 0xaf, 0x6e, 0x8d, 0x54, 0x08, 0xe3, 0x06, 0xfb, 0x24, + 0xf7, 0x69, 0x15, 0xeb, 0xf7, 0x2a, 0x4b, 0x8b, 0x3c, 0x2b, 0x3a, 0xeb, + 0x4c, 0x8b, 0xeb, 0xfb, 0x2a, 0xea, 0x8b, 0x05, 0x0e, 0xf8, 0x76, 0x16, + 0xf8, 0xa0, 0x38, 0xfb, 0xbd, 0x07, 0x20, 0x53, 0x45, 0x34, 0x49, 0x61, + 0xb3, 0xca, 0x1e, 0xf8, 0x07, 0x38, 0xfc, 0x28, 0x07, 0x34, 0xcc, 0x53, + 0xf1, 0x1e, 0xd8, 0x8b, 0xbc, 0xa6, 0xbc, 0xd0, 0x08, 0x42, 0x07, 0xd6, + 0x06, 0xfb, 0x81, 0xf9, 0x5f, 0x15, 0x23, 0x24, 0xf3, 0x06, 0xf2, 0x07, + 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0x06, 0xf2, 0x07, 0x0e, 0xf8, 0x76, + 0x16, 0xf8, 0xa0, 0x38, 0xfb, 0xbd, 0x07, 0x20, 0x53, 0x45, 0x34, 0x49, + 0x61, 0xb3, 0xca, 0x1e, 0xf8, 0x07, 0x38, 0xfc, 0x28, 0x07, 0x34, 0xcc, + 0x53, 0xf1, 0x1e, 0xd8, 0x8b, 0xbc, 0xa6, 0xbc, 0xd0, 0x08, 0x42, 0x07, + 0xd6, 0x06, 0xfb, 0x4e, 0xf9, 0x78, 0x15, 0x2b, 0xfb, 0x28, 0xc7, 0x8b, + 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xf8, 0x76, 0x16, + 0xf8, 0xa0, 0x38, 0xfb, 0xbd, 0x07, 0x20, 0x53, 0x45, 0x34, 0x49, 0x61, + 0xb3, 0xca, 0x1e, 0xf8, 0x07, 0x38, 0xfc, 0x28, 0x07, 0x34, 0xcc, 0x53, + 0xf1, 0x1e, 0xd8, 0x8b, 0xbc, 0xa6, 0xbc, 0xd0, 0x08, 0x42, 0x07, 0xd6, + 0x06, 0xfb, 0x83, 0xf9, 0x78, 0x15, 0xfb, 0x05, 0x8b, 0xf7, 0x29, 0xfb, + 0x28, 0xc7, 0x8b, 0x2b, 0xf7, 0x28, 0x05, 0x0e, 0xf8, 0x76, 0x16, 0xf8, + 0xa0, 0x38, 0xfb, 0xbd, 0x07, 0x20, 0x53, 0x45, 0x34, 0x49, 0x61, 0xb3, + 0xca, 0x1e, 0xf8, 0x07, 0x38, 0xfc, 0x28, 0x07, 0x34, 0xcc, 0x53, 0xf1, + 0x1e, 0xd8, 0x8b, 0xbc, 0xa6, 0xbc, 0xd0, 0x08, 0x42, 0x07, 0xd6, 0x06, + 0xfb, 0x93, 0xf9, 0x79, 0x15, 0x2b, 0xfb, 0x2a, 0xcb, 0x8b, 0xda, 0xeb, + 0xdc, 0x2b, 0xca, 0x8b, 0x2b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0x0e, 0xf7, + 0x63, 0xf8, 0x18, 0xf8, 0xa0, 0x15, 0xfb, 0x25, 0xfc, 0x2c, 0xfb, 0x1a, + 0xf8, 0x2c, 0x32, 0x8b, 0xf7, 0x45, 0xfc, 0xa2, 0x6b, 0x38, 0x05, 0x7e, + 0x66, 0x78, 0x7d, 0x68, 0x8b, 0x7f, 0x8b, 0x7d, 0x8d, 0x79, 0x8f, 0x08, + 0x40, 0x07, 0x9c, 0x82, 0x9c, 0x87, 0xa1, 0x8b, 0xa6, 0x8b, 0xa8, 0x94, + 0xa1, 0x9b, 0xa5, 0x9e, 0x9a, 0xa1, 0x9b, 0xb5, 0x08, 0xf7, 0x7d, 0xf9, + 0x0e, 0x31, 0x8b, 0x05, 0xfb, 0x09, 0xf7, 0x6c, 0x15, 0x2b, 0xfb, 0x28, + 0xc7, 0x8b, 0xf7, 0x29, 0xf7, 0x28, 0xfb, 0x05, 0x8b, 0x05, 0x0e, 0xf7, + 0x63, 0xf8, 0x4f, 0xf8, 0xa0, 0x15, 0xfc, 0x1b, 0x42, 0xf7, 0xb8, 0x06, + 0xfb, 0xcd, 0xfc, 0x0c, 0x8b, 0x40, 0xf8, 0x3e, 0x8b, 0x8b, 0xd4, 0xfb, + 0xd9, 0x8b, 0xf7, 0xcb, 0xf8, 0x0d, 0x8b, 0xd5, 0x05, 0xfb, 0x25, 0xce, + 0x15, 0xeb, 0xf7, 0x2a, 0x4b, 0x8b, 0x3c, 0x2b, 0x3b, 0xeb, 0x4b, 0x8b, + 0xec, 0xfb, 0x2a, 0xe9, 0x8b, 0x05, 0x0e, 0xf7, 0x6f, 0xf8, 0xf9, 0x15, + 0xbf, 0x5f, 0x96, 0x81, 0xae, 0x68, 0x6d, 0x95, 0x7d, 0x8e, 0x78, 0x8b, + 0x63, 0x8b, 0x63, 0x7f, 0x69, 0x74, 0x46, 0x5f, 0x68, 0x38, 0x8b, 0xfb, + 0x09, 0x08, 0xfb, 0x47, 0xe1, 0x25, 0xf7, 0x2b, 0xf7, 0x2b, 0xe1, 0xf1, + 0xf7, 0x48, 0x1e, 0x8b, 0xe7, 0x76, 0xcf, 0x58, 0xd9, 0x65, 0xc4, 0x66, + 0xb1, 0x43, 0xc2, 0x08, 0xe5, 0xb4, 0x63, 0xb0, 0x2a, 0x5e, 0x05, 0x48, + 0xb6, 0x7e, 0x92, 0x6c, 0x98, 0x08, 0x5f, 0x5f, 0x05, 0xb6, 0x73, 0x98, + 0x83, 0xa5, 0x77, 0x08, 0x36, 0x63, 0xaf, 0x64, 0xec, 0xb8, 0x05, 0xc1, + 0xfb, 0x2b, 0x15, 0xe9, 0xc3, 0x3e, 0xfb, 0x16, 0xfb, 0x0f, 0x51, 0x3d, + 0x2f, 0x2e, 0x52, 0xd9, 0xf7, 0x12, 0xf7, 0x12, 0xc4, 0xd9, 0xe8, 0x1f, + 0x0e, 0xc2, 0xfb, 0x6e, 0x15, 0xde, 0xf7, 0xa5, 0x06, 0xb7, 0x55, 0xbc, + 0x73, 0xcf, 0x8b, 0x08, 0xf7, 0x1b, 0xe4, 0xf7, 0x01, 0xf7, 0x3b, 0xf7, + 0x42, 0x33, 0xf7, 0x04, 0xfb, 0x1c, 0x1f, 0x48, 0x8b, 0x51, 0x6e, 0x67, + 0x58, 0x08, 0xf7, 0x93, 0x38, 0xfe, 0x38, 0x07, 0xf7, 0x79, 0xf9, 0x3b, + 0x15, 0xe7, 0xc7, 0x3a, 0xfb, 0x11, 0xfb, 0x0b, 0x4e, 0x3a, 0x30, 0x33, + 0x51, 0xdb, 0xf7, 0x0f, 0xf7, 0x0f, 0xc5, 0xdb, 0xe3, 0x1f, 0x0e, 0xf7, + 0x63, 0xf8, 0x18, 0xf8, 0xa0, 0x15, 0xfb, 0x25, 0xfc, 0x2c, 0xfb, 0x1a, + 0xf8, 0x2c, 0x32, 0x8b, 0xf7, 0x45, 0xfc, 0xa2, 0x6b, 0x38, 0x05, 0x7e, + 0x66, 0x78, 0x7d, 0x68, 0x8b, 0x7f, 0x8b, 0x7d, 0x8d, 0x79, 0x8f, 0x08, + 0x40, 0x07, 0x9c, 0x82, 0x9c, 0x87, 0xa1, 0x8b, 0xa6, 0x8b, 0xa8, 0x94, + 0xa1, 0x9b, 0xa5, 0x9e, 0x9a, 0xa1, 0x9b, 0xb5, 0x08, 0xf7, 0x7d, 0xf9, + 0x0e, 0x31, 0x8b, 0x05, 0xfb, 0x3f, 0xf7, 0x53, 0x15, 0x23, 0x24, 0xf3, + 0xf2, 0x06, 0xf7, 0x36, 0x16, 0x23, 0x24, 0xf3, 0xf2, 0x06, 0x0e, 0xda, + 0xf7, 0xcd, 0x15, 0x54, 0x8b, 0x75, 0x50, 0xde, 0x8b, 0x05, 0x97, 0x47, + 0x9f, 0x52, 0xa9, 0x5a, 0xb2, 0x4b, 0xd6, 0x64, 0xdf, 0x8b, 0xc7, 0x8b, + 0xc2, 0x9b, 0xbe, 0xaa, 0x08, 0xe8, 0x07, 0x3a, 0x5b, 0x67, 0x7d, 0x5a, + 0x8b, 0x34, 0x8b, 0x52, 0xce, 0x72, 0xf7, 0x18, 0x08, 0xf7, 0x6a, 0x8b, + 0xa3, 0xc6, 0xfb, 0x8a, 0x8b, 0x05, 0x8a, 0x9a, 0x8b, 0x93, 0x8b, 0x92, + 0x8b, 0x96, 0x8b, 0x94, 0x8d, 0x9b, 0x08, 0xf7, 0xa2, 0x8b, 0xa2, 0xc6, + 0xfb, 0xb0, 0x8b, 0x05, 0xa7, 0xf7, 0x19, 0xbf, 0xc9, 0xe1, 0x8b, 0xc0, + 0x8b, 0xb4, 0x7a, 0xd4, 0x55, 0x08, 0xab, 0xdb, 0x05, 0x49, 0xba, 0x52, + 0x9f, 0x46, 0x8b, 0x35, 0x8b, 0x4a, 0x6a, 0x5c, 0x47, 0x69, 0x59, 0x75, + 0x53, 0x81, 0x4b, 0x08, 0x4c, 0x8b, 0x75, 0x50, 0xda, 0x8b, 0x05, 0x89, + 0x78, 0x8b, 0x81, 0x8b, 0x7f, 0x08, 0x72, 0x07, 0x0e, 0xb3, 0xf7, 0x2e, + 0xf8, 0xd8, 0x15, 0xfb, 0xbc, 0xc9, 0xf8, 0x3d, 0x60, 0x07, 0x7a, 0x4b, + 0x7d, 0x80, 0x43, 0x84, 0x08, 0x7c, 0x8a, 0x8b, 0x5d, 0xee, 0x8b, 0x05, + 0x0e, 0xb3, 0xf7, 0xcf, 0xf7, 0xea, 0x15, 0xfb, 0x79, 0x06, 0x97, 0xb1, + 0x9d, 0x9e, 0xb6, 0xa2, 0x08, 0xca, 0xab, 0x05, 0xca, 0xaa, 0xac, 0xb8, + 0x8b, 0xc0, 0x8b, 0xd5, 0x4f, 0xbf, 0x35, 0x8b, 0x28, 0x8b, 0x5a, 0x5a, + 0x88, 0x24, 0x08, 0xc9, 0x06, 0x8d, 0xaa, 0x8e, 0x9b, 0x93, 0x98, 0x99, + 0xa3, 0xa7, 0x9a, 0xab, 0x8b, 0xbb, 0x8b, 0xb0, 0x6b, 0x8b, 0x60, 0x8b, + 0x6c, 0x77, 0x70, 0x64, 0x76, 0x08, 0x51, 0x6c, 0x05, 0x2b, 0x58, 0x71, + 0x64, 0x86, 0x2a, 0x08, 0xf7, 0xc4, 0xc5, 0x06, 0x0e, 0xb3, 0xf7, 0x14, + 0xf8, 0x70, 0x15, 0xae, 0x8b, 0x9b, 0x8b, 0x9a, 0x89, 0xae, 0x85, 0xa2, + 0x6f, 0x8b, 0x67, 0x8b, 0x58, 0x69, 0x6d, 0x53, 0x8b, 0x4f, 0x8b, 0x6f, + 0xa6, 0x88, 0xc9, 0x08, 0x4d, 0x06, 0x31, 0xc2, 0x57, 0xeb, 0xe9, 0xc8, + 0xc0, 0xdc, 0x1e, 0x8b, 0xbe, 0x74, 0xac, 0x5b, 0x9b, 0x08, 0xb0, 0x9c, + 0x9f, 0xa8, 0x8b, 0xb2, 0x8b, 0xd5, 0x56, 0xb9, 0x35, 0x8b, 0x2e, 0x8b, + 0x5a, 0x5b, 0x89, 0x2d, 0x08, 0xca, 0x06, 0x8b, 0xa7, 0x8d, 0x98, 0x92, + 0x98, 0x97, 0xa1, 0xa6, 0x98, 0xac, 0x8b, 0x08, 0xba, 0xa8, 0x71, 0x61, + 0x5c, 0x73, 0x7d, 0x35, 0x1f, 0x58, 0x07, 0x0e, 0x7c, 0xf7, 0x67, 0xf8, + 0x3f, 0x15, 0xfb, 0x10, 0xfb, 0x11, 0xf7, 0x10, 0xf7, 0x11, 0x06, 0x0e, + 0xb3, 0xf7, 0xb0, 0xf7, 0xcc, 0x15, 0xfb, 0x82, 0x43, 0xf7, 0x82, 0xd3, + 0x06, 0x0e, 0xf6, 0xf7, 0x5c, 0xf9, 0x42, 0x15, 0x37, 0x47, 0x47, 0x38, + 0x38, 0xcf, 0x46, 0xdd, 0xe0, 0xcf, 0xce, 0xe0, 0xde, 0x47, 0xcf, 0x38, + 0x1f, 0x52, 0x04, 0xbf, 0xb5, 0x61, 0x57, 0x56, 0x61, 0x61, 0x55, 0x59, + 0x60, 0xb6, 0xbf, 0xbe, 0xb6, 0xb6, 0xbf, 0x1f, 0x0e, 0xf7, 0xb7, 0xf8, + 0xb4, 0xf7, 0x9f, 0x15, 0xfc, 0x8c, 0x45, 0xf8, 0x8c, 0xd1, 0x06, 0x0e, + 0xf7, 0xb7, 0xf8, 0x4a, 0xf8, 0x3f, 0x15, 0xfb, 0x27, 0xfb, 0x26, 0xfb, + 0x26, 0xf7, 0x25, 0x5a, 0x5a, 0xf7, 0x26, 0xfb, 0x26, 0xfb, 0x27, 0xfb, + 0x27, 0xbd, 0x5a, 0xf7, 0x26, 0xf7, 0x26, 0xf7, 0x27, 0xfb, 0x27, 0xbd, + 0xbd, 0xfb, 0x27, 0xf7, 0x27, 0xf7, 0x26, 0xf7, 0x26, 0x5a, 0xbd, 0x05, + 0x0e, 0xf7, 0xb7, 0xf8, 0xaa, 0xf7, 0xa3, 0x15, 0xfc, 0x78, 0x45, 0xf8, + 0x78, 0xd1, 0x06, 0xfb, 0x52, 0xfb, 0x3b, 0x15, 0x23, 0x23, 0xf3, 0xf3, + 0x06, 0xf8, 0x04, 0x04, 0x23, 0x23, 0xf3, 0xf3, 0x06, 0x0e, 0xf9, 0x57, + 0xf7, 0xb1, 0xf9, 0x36, 0x15, 0xf7, 0x2d, 0xc2, 0xfc, 0x0b, 0x54, 0xf7, + 0x2e, 0xfc, 0x12, 0xcf, 0xf8, 0x12, 0x06, 0xf8, 0x63, 0xfc, 0x12, 0x15, + 0xf7, 0x0f, 0xf7, 0xe9, 0x8b, 0xfb, 0xe9, 0xce, 0x8b, 0x8b, 0xf8, 0x49, + 0x30, 0x8b, 0xfb, 0x17, 0xfb, 0xfe, 0xfb, 0x18, 0xf7, 0xfe, 0x2d, 0x8b, + 0x8b, 0xfc, 0x49, 0xce, 0x8b, 0x8b, 0xf7, 0xe9, 0xf7, 0x0d, 0xfb, 0xe9, + 0xd1, 0x8b, 0x05, 0x0e, 0xf7, 0xb7, 0xf8, 0xaa, 0xf8, 0x34, 0x15, 0xfb, + 0x63, 0xf7, 0x63, 0x45, 0xfb, 0x63, 0xfb, 0x63, 0x45, 0xf7, 0x63, 0xfb, + 0x63, 0xd1, 0xf7, 0x63, 0xf7, 0x63, 0xd1, 0x06, 0xfb, 0xf9, 0x04, 0xfc, + 0x78, 0x45, 0xf8, 0x78, 0xd1, 0x06, 0x0e, 0xf8, 0xb1, 0xf7, 0x1b, 0xf8, + 0xd8, 0x15, 0xfb, 0xbc, 0xc9, 0xf8, 0x3d, 0x60, 0x07, 0x7a, 0x4b, 0x7d, + 0x80, 0x43, 0x84, 0x08, 0x7c, 0x8a, 0x8b, 0x5d, 0x05, 0xee, 0x06, 0xf8, + 0x5f, 0xf7, 0x15, 0x15, 0xfc, 0x58, 0xfd, 0x6d, 0xc5, 0x8b, 0xf8, 0x58, + 0xf9, 0x6d, 0x51, 0x8b, 0x05, 0xf7, 0x72, 0xfd, 0x1f, 0x15, 0xfb, 0x79, + 0x06, 0x97, 0xb1, 0x9d, 0x9e, 0xb6, 0xa2, 0x08, 0xca, 0xab, 0x05, 0xca, + 0xaa, 0xac, 0xb8, 0x8b, 0xc0, 0x8b, 0xd5, 0x4f, 0xbf, 0x35, 0x8b, 0x28, + 0x8b, 0x5a, 0x5a, 0x88, 0x24, 0x08, 0xc9, 0x06, 0x8d, 0xaa, 0x8e, 0x9b, + 0x93, 0x98, 0x99, 0xa3, 0xa7, 0x9a, 0xab, 0x8b, 0xbb, 0x8b, 0xb0, 0x6b, + 0x8b, 0x60, 0x8b, 0x6c, 0x77, 0x70, 0x64, 0x76, 0x08, 0x51, 0x6c, 0x05, + 0x2b, 0x58, 0x71, 0x64, 0x86, 0x2a, 0x08, 0xf7, 0xc4, 0x06, 0xc5, 0x07, + 0x0e, 0xf8, 0xb1, 0xf7, 0x1a, 0xf8, 0xd8, 0x15, 0xfb, 0xbc, 0xc9, 0xf8, + 0x3d, 0x60, 0x07, 0x7a, 0x4b, 0x7d, 0x80, 0x43, 0x84, 0x08, 0x7c, 0x8a, + 0x8b, 0x5d, 0x05, 0xee, 0x06, 0xf8, 0x77, 0xf7, 0x15, 0x15, 0xfc, 0x58, + 0xfd, 0x6d, 0xc5, 0x8b, 0xf8, 0x58, 0xf9, 0x6d, 0x51, 0x8b, 0x05, 0xd8, + 0xfc, 0xf5, 0x15, 0x27, 0xc9, 0x07, 0xef, 0xce, 0xc0, 0x48, 0xf7, 0xa4, + 0x5d, 0x07, 0xfb, 0x60, 0xfb, 0x9e, 0x8b, 0x50, 0x05, 0xf7, 0x50, 0x06, + 0xc0, 0x04, 0xfb, 0x15, 0x8b, 0xf7, 0x15, 0xf7, 0x3e, 0x8b, 0xfb, 0x3e, + 0x05, 0x0e, 0xf8, 0xb1, 0xf7, 0x0b, 0xf8, 0x70, 0x15, 0xae, 0x8b, 0x9b, + 0x8b, 0x9a, 0x89, 0xae, 0x85, 0xa2, 0x6f, 0x8b, 0x67, 0x8b, 0x58, 0x69, + 0x6d, 0x53, 0x8b, 0x4f, 0x8b, 0x6f, 0xa6, 0x88, 0xc9, 0x08, 0x4d, 0x06, + 0x31, 0xc2, 0x57, 0xeb, 0xe9, 0xc8, 0xc0, 0xdc, 0x1e, 0x8b, 0xbe, 0x74, + 0xac, 0x5b, 0x9b, 0x08, 0xb0, 0x9c, 0x9f, 0xa8, 0x8b, 0xb2, 0x8b, 0xd5, + 0x56, 0xb9, 0x35, 0x8b, 0x2e, 0x8b, 0x5a, 0x5b, 0x89, 0x2d, 0x08, 0xca, + 0x06, 0x8b, 0xa7, 0x8d, 0x98, 0x92, 0x98, 0x97, 0xa1, 0xa6, 0x98, 0xac, + 0x8b, 0x08, 0xba, 0xa8, 0x71, 0x61, 0x5c, 0x73, 0x7d, 0x35, 0x1f, 0x58, + 0x07, 0xf8, 0x9a, 0xf7, 0x7d, 0x15, 0xfc, 0x58, 0xfd, 0x6d, 0xc5, 0x8b, + 0xf8, 0x58, 0xf9, 0x6d, 0x05, 0x51, 0x06, 0xce, 0xfc, 0xf5, 0x15, 0x27, + 0xc9, 0x07, 0xef, 0xce, 0xc0, 0x48, 0xf7, 0xa4, 0x5d, 0x07, 0xfb, 0x60, + 0xfb, 0x9e, 0x8b, 0x50, 0x05, 0xf7, 0x50, 0x06, 0xc0, 0x04, 0xfb, 0x15, + 0x8b, 0xf7, 0x15, 0xf7, 0x3e, 0x8b, 0xfb, 0x3e, 0x05, 0x0e, 0xf8, 0x50, + 0xf8, 0xb4, 0xf8, 0x49, 0x15, 0x73, 0xf5, 0x56, 0xbc, 0x32, 0x8b, 0x08, + 0xfb, 0x0a, 0x3c, 0x2c, 0xfb, 0x20, 0xfb, 0x1c, 0xda, 0x2c, 0xf7, 0x07, + 0x1f, 0xc4, 0x8b, 0xb9, 0xa2, 0xac, 0xba, 0x9e, 0xa7, 0x95, 0xa7, 0x97, + 0xc7, 0x08, 0x44, 0x06, 0x7e, 0x3a, 0x66, 0x60, 0x53, 0x8b, 0x6b, 0x8b, + 0x67, 0x9d, 0x76, 0xa7, 0x74, 0xa8, 0x7e, 0xb7, 0x8b, 0xbe, 0x8b, 0xf4, + 0xbc, 0xce, 0xd7, 0x8b, 0xc0, 0x8b, 0xa7, 0x70, 0x9c, 0x49, 0x08, 0xd2, + 0x06, 0xfb, 0x43, 0xf7, 0xc5, 0x15, 0xfb, 0x67, 0xfb, 0x3f, 0xfb, 0x3f, + 0xfb, 0x67, 0xfb, 0x64, 0xf7, 0x40, 0xfb, 0x42, 0xf7, 0x61, 0xf7, 0x6c, + 0xf7, 0x3f, 0xf7, 0x3d, 0xf7, 0x6a, 0xf7, 0x66, 0xfb, 0x3f, 0xf7, 0x3f, + 0xfb, 0x67, 0x1f, 0x4d, 0x04, 0xf7, 0x41, 0xf7, 0x21, 0xfb, 0x24, 0xfb, + 0x43, 0xfb, 0x47, 0xfb, 0x20, 0xfb, 0x22, 0xfb, 0x46, 0xfb, 0x3d, 0xfb, + 0x21, 0xf7, 0x26, 0xf7, 0x42, 0xf7, 0x44, 0xf7, 0x21, 0xf7, 0x24, 0xf7, + 0x41, 0x1f, 0x0e, 0xf8, 0x50, 0xf7, 0xa4, 0xf7, 0xd9, 0x15, 0xf7, 0x1a, + 0x06, 0xb8, 0x9e, 0x77, 0x5b, 0x1f, 0x8a, 0x63, 0x05, 0x8b, 0x6f, 0x91, + 0x6f, 0x94, 0x76, 0x08, 0xda, 0xa4, 0x06, 0x79, 0x98, 0x87, 0x97, 0x8a, + 0xc5, 0x8a, 0xd2, 0x84, 0x9c, 0x66, 0xa3, 0xb4, 0xa9, 0x98, 0xa2, 0x8b, + 0xb9, 0x08, 0xe0, 0x5d, 0xb4, 0x2c, 0x1e, 0xfb, 0x62, 0xfc, 0x51, 0xd1, + 0xf7, 0x4d, 0x06, 0xca, 0x04, 0xf7, 0x1a, 0xf7, 0x15, 0x07, 0xc0, 0xa1, + 0x77, 0x5c, 0x5d, 0x74, 0x76, 0x57, 0x1f, 0xfb, 0x15, 0x06, 0xec, 0xf7, + 0xf6, 0x15, 0xfb, 0x67, 0xfb, 0x3f, 0xfb, 0x3f, 0xfb, 0x67, 0xfb, 0x64, + 0xf7, 0x40, 0xfb, 0x42, 0xf7, 0x61, 0xf7, 0x6c, 0xf7, 0x3f, 0xf7, 0x3d, + 0xf7, 0x6a, 0xf7, 0x66, 0xfb, 0x3f, 0xf7, 0x3f, 0xfb, 0x67, 0x1f, 0x4d, + 0x04, 0xf7, 0x41, 0xf7, 0x21, 0xfb, 0x24, 0xfb, 0x43, 0xfb, 0x47, 0xfb, + 0x20, 0xfb, 0x22, 0xfb, 0x46, 0xfb, 0x3d, 0xfb, 0x21, 0xf7, 0x26, 0xf7, + 0x42, 0xf7, 0x44, 0xf7, 0x21, 0xf7, 0x24, 0xf7, 0x41, 0x1f, 0x0e, 0x7c, + 0x0e, 0xf7, 0xb7, 0xb3, 0xf8, 0x0b, 0x15, 0x45, 0xf8, 0x46, 0xfb, 0x6f, + 0xd1, 0xf7, 0xb5, 0xfc, 0x8c, 0x07, 0x0e, 0x6a, 0xef, 0xf9, 0x6d, 0x15, + 0xfc, 0x25, 0xc7, 0xf8, 0x25, 0x4f, 0x07, 0xfc, 0xb0, 0x04, 0xfc, 0x25, + 0xc7, 0xf8, 0x25, 0x4f, 0x07, 0x0e, 0xf8, 0xb4, 0xbc, 0x15, 0x81, 0x89, + 0x87, 0x8b, 0x87, 0x8b, 0x08, 0x6e, 0x7b, 0x99, 0xa6, 0x1f, 0xf8, 0x48, + 0x38, 0xfb, 0xbd, 0x07, 0x20, 0x53, 0x45, 0x34, 0x4a, 0x61, 0xb3, 0xca, + 0x1e, 0xf8, 0x07, 0x38, 0xfd, 0x7c, 0xde, 0xf7, 0x73, 0x07, 0xa4, 0x79, + 0xa8, 0x83, 0xaf, 0x8b, 0xcf, 0x8b, 0xc3, 0xa7, 0xb2, 0xc2, 0x8d, 0x52, + 0xa6, 0x71, 0xc4, 0x8b, 0x9d, 0x8b, 0x98, 0x8d, 0xa5, 0x92, 0x08, 0xca, + 0x07, 0x0e, 0xf8, 0xc0, 0x14, 0xf7, 0xb9, 0x15, 0x74, 0xa2, 0xf8, 0xa0, + 0x9a, 0xf7, 0x52, 0x97, 0x54, 0xa2, 0x06, 0x1e, 0x0a, 0x03, 0x96, 0x25, + 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xd9, 0x0a, 0xd0, 0x90, 0x8f, 0x90, + 0x0c, 0x0c, 0xe0, 0x0b, 0xd9, 0x92, 0x94, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e +}; +const unsigned int fonts_NimbusSanL_Regu_cff_len = 16608; diff --git a/rosapps/smartpdf/fitz/fonts/NimbusSanL-ReguItal.cff.c b/rosapps/smartpdf/fitz/fonts/NimbusSanL-ReguItal.cff.c new file mode 100644 index 00000000000..150e065911e --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/NimbusSanL-ReguItal.cff.c @@ -0,0 +1,1683 @@ +const unsigned char fonts_NimbusSanL_ReguItal_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x14, 0x4e, 0x69, 0x6d, + 0x62, 0x75, 0x73, 0x53, 0x61, 0x6e, 0x4c, 0x2d, 0x52, 0x65, 0x67, 0x75, + 0x49, 0x74, 0x61, 0x6c, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x39, 0xf8, + 0x1f, 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, 0x03, 0xf8, + 0x18, 0x04, 0x7f, 0x0c, 0x02, 0xfb, 0x2b, 0x0c, 0x03, 0x1d, 0x00, 0x4c, + 0x9c, 0xec, 0x0d, 0xfb, 0x46, 0xfb, 0x70, 0xfa, 0xe8, 0xfa, 0x4d, 0x05, + 0x1c, 0x00, 0xf9, 0x0f, 0x1c, 0x00, 0x00, 0x10, 0x1c, 0x02, 0xca, 0x11, + 0x1c, 0x00, 0x2b, 0x1c, 0x4e, 0x93, 0x12, 0x00, 0x08, 0x02, 0x00, 0x01, + 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x5f, + 0x00, 0x7b, 0x00, 0x88, 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, 0x64, 0x64, + 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x6e, + 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, 0x43, 0x6f, + 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, 0x52, 0x57, + 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, 0x28, 0x55, + 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, + 0x6e, 0x74, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x20, 0x53, 0x61, 0x6e, + 0x73, 0x20, 0x4c, 0x20, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, + 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x69, 0x6d, 0x62, 0x75, 0x73, + 0x20, 0x53, 0x61, 0x6e, 0x73, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, + 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, + 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, + 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, + 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, + 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, + 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, + 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, + 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, + 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, + 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, + 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, + 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, + 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, + 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, + 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, + 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, + 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, + 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, + 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, + 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, + 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, + 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, + 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x91, + 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, 0xab, + 0x00, 0xae, 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0x9a, + 0x00, 0xb4, 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, 0xb6, + 0x00, 0xb9, 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, 0xbe, + 0x00, 0xbc, 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc4, + 0x00, 0xc2, 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, 0xca, + 0x00, 0xc8, 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, 0xce, + 0x00, 0xd1, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd3, + 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, 0xdb, + 0x00, 0xd9, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, 0xe1, + 0x00, 0xdf, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, 0xe3, + 0x01, 0x87, 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, 0x89, + 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, 0x9c, + 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, 0x8a, + 0x00, 0x97, 0x00, 0xa0, 0x00, 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x57, 0x00, 0xb9, 0x01, 0x76, 0x01, + 0xe5, 0x02, 0x7c, 0x02, 0x9e, 0x02, 0xcd, 0x03, 0x00, 0x03, 0x2a, 0x03, + 0x53, 0x03, 0x75, 0x03, 0x87, 0x03, 0x96, 0x03, 0xaa, 0x04, 0x09, 0x04, + 0x2b, 0x04, 0x87, 0x05, 0x13, 0x05, 0x44, 0x05, 0xa1, 0x06, 0x1d, 0x06, + 0x49, 0x06, 0xda, 0x07, 0x4f, 0x07, 0x6b, 0x07, 0x9c, 0x07, 0xba, 0x07, + 0xdc, 0x07, 0xfb, 0x08, 0x52, 0x09, 0x35, 0x09, 0x64, 0x09, 0xdc, 0x0a, + 0x44, 0x0a, 0x92, 0x0a, 0xbd, 0x0a, 0xe2, 0x0b, 0x66, 0x0b, 0x91, 0x0b, + 0xa5, 0x0b, 0xf4, 0x0c, 0x25, 0x0c, 0x3e, 0x0c, 0x6f, 0x0c, 0x98, 0x0d, + 0x0d, 0x0d, 0x57, 0x0d, 0xd7, 0x0e, 0x62, 0x0f, 0x07, 0x0f, 0x27, 0x0f, + 0x75, 0x0f, 0x90, 0x0f, 0xbd, 0x0f, 0xf2, 0x10, 0x19, 0x10, 0x3e, 0x10, + 0x5c, 0x10, 0x6e, 0x10, 0x8b, 0x10, 0xa8, 0x10, 0xb9, 0x10, 0xdb, 0x11, + 0x91, 0x11, 0xfd, 0x12, 0x6a, 0x12, 0xcc, 0x13, 0x37, 0x13, 0x75, 0x14, + 0x08, 0x14, 0x4e, 0x14, 0x6f, 0x14, 0xae, 0x14, 0xdc, 0x14, 0xf0, 0x15, + 0x64, 0x15, 0xa9, 0x16, 0x06, 0x16, 0x6b, 0x16, 0xcf, 0x16, 0xfe, 0x17, + 0x8e, 0x17, 0xda, 0x18, 0x1d, 0x18, 0x38, 0x18, 0x65, 0x18, 0x94, 0x18, + 0xcf, 0x18, 0xf4, 0x19, 0x70, 0x19, 0x84, 0x19, 0xff, 0x1a, 0x4b, 0x1a, + 0x70, 0x1a, 0xf3, 0x1b, 0xad, 0x1b, 0xc2, 0x1c, 0x0a, 0x1c, 0x6b, 0x1d, + 0x3e, 0x1d, 0xb3, 0x1d, 0xcb, 0x1e, 0x0b, 0x1e, 0x3c, 0x1e, 0x57, 0x1e, + 0x72, 0x1e, 0xd0, 0x1f, 0x23, 0x1f, 0x34, 0x1f, 0x5d, 0x1f, 0x9b, 0x1f, + 0xab, 0x1f, 0xe0, 0x1f, 0xf8, 0x20, 0x18, 0x20, 0x56, 0x20, 0x96, 0x20, + 0xc7, 0x20, 0xef, 0x21, 0x81, 0x21, 0xe0, 0x21, 0xf3, 0x22, 0x08, 0x22, + 0x21, 0x22, 0x6c, 0x22, 0x7e, 0x22, 0xb3, 0x22, 0xc3, 0x22, 0xdf, 0x23, + 0x0b, 0x23, 0x4d, 0x23, 0x73, 0x23, 0xb5, 0x23, 0xce, 0x23, 0xe1, 0x24, + 0x28, 0x24, 0xee, 0x25, 0x1b, 0x25, 0xac, 0x26, 0x25, 0x26, 0x7b, 0x27, + 0x5f, 0x27, 0x73, 0x27, 0x97, 0x28, 0x26, 0x28, 0xd5, 0x29, 0x4b, 0x29, + 0x93, 0x29, 0xd4, 0x2a, 0x13, 0x2a, 0x58, 0x2a, 0xd0, 0x2b, 0x28, 0x2b, + 0xc7, 0x2c, 0x2a, 0x2c, 0x6f, 0x2c, 0xad, 0x2c, 0xe9, 0x2d, 0x2b, 0x2d, + 0x58, 0x2d, 0x7e, 0x2d, 0xa2, 0x2d, 0xcc, 0x2e, 0x3f, 0x2e, 0xce, 0x2f, + 0x55, 0x2f, 0xda, 0x30, 0x65, 0x31, 0x24, 0x31, 0xe0, 0x32, 0x47, 0x32, + 0xa8, 0x33, 0x07, 0x33, 0x6c, 0x33, 0xa6, 0x33, 0xe1, 0x34, 0x30, 0x34, + 0x70, 0x35, 0x40, 0x36, 0x09, 0x36, 0xd1, 0x37, 0x9f, 0x38, 0x97, 0x39, + 0x77, 0x3a, 0x1b, 0x3a, 0x9f, 0x3b, 0x1c, 0x3b, 0x98, 0x3c, 0x1a, 0x3c, + 0x47, 0x3c, 0x6d, 0x3c, 0x91, 0x3c, 0xbb, 0x3d, 0x49, 0x3d, 0xc0, 0x3e, + 0x2f, 0x3e, 0x9c, 0x3f, 0x0f, 0x3f, 0xb5, 0x40, 0x5a, 0x40, 0xb9, 0x41, + 0x10, 0x41, 0x66, 0x41, 0xc1, 0x42, 0x16, 0x42, 0x51, 0x42, 0xf3, 0x43, + 0x51, 0x43, 0xae, 0x44, 0x2b, 0x44, 0x49, 0x44, 0x96, 0x45, 0x0d, 0x45, + 0x1d, 0x45, 0x2f, 0x45, 0x5b, 0x45, 0x6e, 0x45, 0x9f, 0x45, 0xdf, 0x46, + 0x27, 0x46, 0x5f, 0x46, 0xda, 0x47, 0x38, 0x47, 0xef, 0x48, 0x84, 0x49, + 0x4b, 0x49, 0x4d, 0x49, 0x66, 0x49, 0x88, 0x49, 0xf3, 0x7c, 0x0e, 0x7c, + 0x0e, 0x7c, 0xf7, 0xff, 0xf9, 0x6d, 0x15, 0x37, 0x8b, 0x41, 0xfb, 0xf2, + 0x74, 0xfb, 0x67, 0xb3, 0x8b, 0xce, 0xf7, 0x67, 0xd5, 0xf7, 0xf2, 0x05, + 0xfb, 0x19, 0xfd, 0x06, 0x15, 0x37, 0x8b, 0x75, 0x24, 0xdf, 0x8b, 0xa1, + 0xf2, 0x05, 0x0e, 0xc9, 0xf7, 0x5e, 0xf9, 0x59, 0x15, 0x73, 0xfb, 0x03, + 0x8a, 0xfb, 0x1a, 0xb3, 0x8b, 0xc2, 0xf7, 0x1a, 0xa3, 0xf7, 0x03, 0x2d, + 0x8b, 0x05, 0xf7, 0x33, 0x16, 0x73, 0xfb, 0x03, 0x8a, 0xfb, 0x1a, 0xb3, + 0x8b, 0xc2, 0xf7, 0x1a, 0xa3, 0xf7, 0x03, 0x2d, 0x8b, 0x05, 0x0e, 0xf9, + 0x0c, 0xf9, 0x4d, 0x15, 0x3f, 0x8b, 0x3e, 0xfb, 0x56, 0xfb, 0x10, 0x8b, + 0xd7, 0xf7, 0x56, 0x3f, 0x8b, 0x3e, 0xfb, 0x56, 0xfb, 0x0d, 0x8b, 0x7e, + 0x4b, 0xf7, 0x01, 0x8b, 0x42, 0xfb, 0x4c, 0xfb, 0x04, 0x8b, 0x7d, 0x4b, + 0xf0, 0x8b, 0x38, 0xfb, 0x67, 0xd7, 0x8b, 0x05, 0xde, 0xf7, 0x67, 0xf7, + 0x11, 0x8b, 0x38, 0xfb, 0x67, 0xd7, 0x8b, 0xde, 0xf7, 0x67, 0xf7, 0x0a, + 0x8b, 0x99, 0xcb, 0x20, 0x8b, 0xd4, 0xf7, 0x4c, 0xf4, 0x8b, 0x99, 0xcb, + 0x2d, 0x8b, 0xd8, 0xf7, 0x56, 0x05, 0xfb, 0x46, 0xfb, 0x96, 0x15, 0x42, + 0xfb, 0x4c, 0xfb, 0x11, 0x8b, 0xd5, 0xf7, 0x4c, 0xf7, 0x10, 0x8b, 0x05, + 0x0e, 0xf8, 0x2b, 0xf9, 0x96, 0x15, 0x80, 0x55, 0x05, 0x47, 0x86, 0x4e, + 0x73, 0x63, 0x66, 0x5e, 0x62, 0x6d, 0x41, 0x8b, 0x49, 0x8b, 0x63, 0x9a, + 0x6a, 0xa9, 0x71, 0xa0, 0x79, 0xa0, 0x82, 0xd3, 0x72, 0x08, 0x51, 0xfb, + 0xa4, 0x05, 0x42, 0xa0, 0x6f, 0xa7, 0x8b, 0xc2, 0x8b, 0x94, 0x8c, 0x9e, + 0x8d, 0x9e, 0x08, 0x8c, 0x96, 0x3c, 0x8b, 0x05, 0x85, 0x69, 0x89, 0x7a, + 0x8b, 0x74, 0x8b, 0x30, 0xc0, 0x5b, 0xf7, 0x09, 0x79, 0x08, 0x75, 0x24, + 0xc6, 0x8b, 0xa1, 0xf2, 0x05, 0xd4, 0x8d, 0xcd, 0xa3, 0xb7, 0xb3, 0xbe, + 0xb8, 0xac, 0xdb, 0x8b, 0xd6, 0x8b, 0xbb, 0x7a, 0xaa, 0x63, 0xa6, 0x73, + 0x9b, 0x7c, 0x92, 0x39, 0xa4, 0x08, 0xc0, 0xf7, 0x8d, 0x05, 0xc2, 0x88, + 0xae, 0x67, 0x8b, 0x57, 0x8b, 0x87, 0x8b, 0x83, 0x8a, 0x82, 0x08, 0x8a, + 0x7c, 0xda, 0x8b, 0x05, 0x90, 0x9f, 0x8c, 0x95, 0x8b, 0x9b, 0x8b, 0xe5, + 0x51, 0xc3, 0x27, 0x90, 0x08, 0x96, 0xc1, 0x05, 0x50, 0x06, 0x3e, 0xfc, + 0x01, 0x15, 0x46, 0xa0, 0x71, 0xa5, 0x8b, 0xbc, 0x8b, 0xae, 0x9d, 0xb4, + 0xa5, 0xa4, 0xa5, 0xa4, 0xad, 0x9a, 0xb5, 0x8e, 0x08, 0x58, 0xfb, 0x84, + 0x05, 0xb1, 0x2b, 0x15, 0xdc, 0x73, 0xa7, 0x71, 0x8b, 0x5b, 0x8b, 0x2a, + 0x4f, 0x4f, 0x22, 0x83, 0x08, 0xc3, 0xf7, 0x9b, 0x05, 0x0e, 0xf8, 0xe8, + 0xf9, 0x8b, 0xf9, 0x59, 0x15, 0xfc, 0xba, 0xfd, 0x6d, 0xcd, 0x8b, 0xf8, + 0xba, 0xf9, 0x6d, 0x05, 0x49, 0x06, 0xfc, 0x32, 0x70, 0x15, 0xfb, 0x00, + 0x24, 0x28, 0x22, 0x3f, 0xc5, 0x53, 0xd9, 0xf7, 0x04, 0xf0, 0xed, 0xf7, + 0x00, 0xd4, 0x4f, 0xc4, 0x3d, 0x1f, 0x7b, 0x49, 0x15, 0xbd, 0xad, 0x6a, + 0x5a, 0x4d, 0x4d, 0x4f, 0x4a, 0x5c, 0x68, 0xae, 0xba, 0xca, 0xc8, 0xc6, + 0xcb, 0x1f, 0xf8, 0x40, 0xfb, 0xbc, 0x15, 0xfb, 0x00, 0x24, 0x28, 0x22, + 0x1f, 0x3f, 0xc5, 0x53, 0xd9, 0xf7, 0x04, 0xf0, 0xed, 0xf7, 0x00, 0xd4, + 0x4f, 0xc4, 0x3d, 0x1e, 0x7b, 0x49, 0x15, 0xbd, 0xad, 0x6a, 0x5a, 0x4d, + 0x4d, 0x4f, 0x4a, 0x5c, 0x68, 0xae, 0xba, 0xca, 0xc8, 0xc6, 0xcb, 0x1f, + 0x0e, 0xf8, 0x0a, 0xf8, 0xc9, 0xf7, 0xe2, 0x15, 0x7f, 0x5a, 0x7b, 0x6a, + 0x6b, 0x66, 0x08, 0x29, 0xf7, 0x37, 0x05, 0xf7, 0x10, 0xc3, 0xc4, 0xcd, + 0x8b, 0xe2, 0x08, 0xd6, 0x57, 0xba, 0x3a, 0xfb, 0x01, 0x28, 0x32, 0x2a, + 0x1e, 0x8b, 0x74, 0x90, 0x74, 0x94, 0x75, 0x08, 0x9d, 0x61, 0x05, 0x8d, + 0x87, 0x8e, 0x83, 0x8f, 0x80, 0x64, 0x75, 0x6f, 0x79, 0x71, 0x79, 0x40, + 0x54, 0x66, 0x47, 0x8b, 0x3a, 0x8b, 0x2e, 0xcc, 0x51, 0xf4, 0x8b, 0xdb, + 0x8b, 0xc5, 0xa5, 0xe6, 0xd6, 0x08, 0xb9, 0x3d, 0xf5, 0x8b, 0x31, 0xf7, + 0x2b, 0x05, 0xbc, 0xbe, 0xb2, 0xd2, 0x97, 0xc8, 0x08, 0x3c, 0x06, 0xfb, + 0x50, 0xef, 0x15, 0x62, 0xc5, 0x85, 0x98, 0x8b, 0xa7, 0x08, 0xc6, 0xba, + 0xba, 0xc6, 0xb6, 0xa5, 0x72, 0x63, 0x1e, 0x8b, 0x54, 0x67, 0x64, 0x2f, + 0x5d, 0x08, 0xd2, 0xfb, 0xbd, 0x15, 0x42, 0x4e, 0x5d, 0x75, 0x5a, 0x8b, + 0x48, 0x8b, 0x61, 0xb3, 0x8b, 0xcc, 0x8b, 0xcc, 0xb9, 0xbf, 0xf7, 0x04, + 0xc7, 0x08, 0xf7, 0x0b, 0xfb, 0x5b, 0x05, 0x0e, 0x44, 0xf7, 0x6b, 0xf9, + 0x58, 0x15, 0x75, 0x24, 0xbb, 0x8b, 0x05, 0x81, 0x52, 0x76, 0x6f, 0x67, + 0x86, 0x08, 0x83, 0x65, 0x05, 0xc8, 0x8f, 0xb7, 0xbb, 0x9c, 0xda, 0x08, + 0xa0, 0xef, 0x2d, 0x8b, 0x05, 0x0e, 0xb3, 0xf8, 0x1b, 0xf9, 0x6d, 0x15, + 0xfb, 0x42, 0xfb, 0x4a, 0x23, 0xfb, 0x78, 0x8b, 0xfb, 0x5f, 0x8b, 0xfb, + 0x0b, 0xa8, 0xfb, 0x10, 0xbc, 0x35, 0x08, 0xc2, 0x06, 0x66, 0xeb, 0x79, + 0xe9, 0x8b, 0xf1, 0x8b, 0xf7, 0x72, 0xe2, 0xf7, 0x72, 0xf7, 0x3c, 0xf7, + 0x62, 0x08, 0x54, 0x06, 0x0e, 0xb3, 0xbb, 0xfb, 0x69, 0x15, 0xca, 0xcd, + 0xc6, 0xda, 0xb9, 0xde, 0xd5, 0xf7, 0x19, 0xae, 0xf7, 0x13, 0x8b, 0xf7, + 0x18, 0x8b, 0xf7, 0x05, 0x6d, 0xf7, 0x12, 0x5c, 0xde, 0x08, 0x54, 0x06, + 0xb1, 0x2a, 0x9c, 0x2d, 0x8b, 0x20, 0x8b, 0xfb, 0x6c, 0x32, 0xfb, 0x75, + 0xfb, 0x3a, 0xfb, 0x5f, 0x08, 0xc2, 0x06, 0x0e, 0xeb, 0xf7, 0xd3, 0xf9, + 0x6d, 0x15, 0x77, 0xfb, 0x04, 0x27, 0xb3, 0x6d, 0x50, 0xf3, 0x6c, 0x2f, + 0x33, 0xba, 0x63, 0xdc, 0xea, 0xb7, 0x2b, 0xc5, 0xb0, 0x56, 0xe6, 0xf7, + 0x05, 0xa6, 0x82, 0xc9, 0xfb, 0x02, 0x65, 0xa8, 0xf7, 0x04, 0x4d, 0x8b, + 0x05, 0x0e, 0xf7, 0xb7, 0xf8, 0xe3, 0xf7, 0xa1, 0x15, 0xfb, 0x63, 0x8b, + 0xb7, 0xf7, 0x60, 0x45, 0x8b, 0x5f, 0xfb, 0x60, 0xfb, 0x63, 0x8b, 0x7c, + 0x43, 0xf7, 0x63, 0x8b, 0x5f, 0xfb, 0x64, 0xd1, 0x8b, 0xb7, 0xf7, 0x64, + 0xf7, 0x63, 0x8b, 0x9a, 0xd3, 0x05, 0x0e, 0x7c, 0xf7, 0x01, 0xf2, 0x15, + 0x75, 0x24, 0xc6, 0x8b, 0x05, 0x7d, 0x39, 0x76, 0x70, 0x5b, 0x8b, 0x08, + 0x83, 0x65, 0x05, 0xcd, 0x88, 0xbd, 0xbc, 0x9c, 0xe0, 0x08, 0xa5, 0xf7, + 0x0b, 0x22, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, 0xf3, 0xf7, 0xcc, 0x15, 0xfb, + 0x83, 0x8b, 0x7c, 0x43, 0xf7, 0x83, 0x8b, 0x9a, 0xd3, 0x05, 0x0e, 0x7c, + 0xf7, 0x69, 0xf2, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, 0xf2, + 0x05, 0x0e, 0x7c, 0xf8, 0x0f, 0xf9, 0x6d, 0x15, 0xfc, 0x1b, 0xfd, 0x81, + 0xc2, 0x8b, 0xf8, 0x1b, 0xf9, 0x81, 0x54, 0x8b, 0x05, 0x0e, 0xf8, 0x36, + 0xf9, 0x59, 0x15, 0x38, 0x8b, 0x46, 0x63, 0x53, 0x39, 0x4c, 0x2f, 0x5a, + 0xfb, 0x48, 0x8b, 0xfb, 0x25, 0x8b, 0x4e, 0x9d, 0x56, 0xab, 0x6c, 0xaa, + 0x6d, 0xbc, 0x79, 0xbb, 0x8b, 0xe1, 0x8b, 0xcd, 0xb1, 0xc5, 0xdf, 0xcb, + 0xe7, 0xbb, 0xf7, 0x48, 0x8b, 0xf7, 0x23, 0x08, 0xf7, 0x0e, 0x48, 0xd4, + 0xfb, 0x05, 0x1e, 0x7f, 0x3e, 0x15, 0xcc, 0xb2, 0x5c, 0x3a, 0x1f, 0x8b, + 0x2d, 0x6a, 0xfb, 0x2c, 0x65, 0x3b, 0x63, 0x35, 0x5c, 0x65, 0x4a, 0x8b, + 0x4c, 0x8b, 0x65, 0xbb, 0x8b, 0xda, 0x8b, 0xea, 0xab, 0xf7, 0x2a, 0xb1, + 0xde, 0xb2, 0xde, 0xbb, 0xb3, 0xca, 0x8b, 0x08, 0x0e, 0xf8, 0x03, 0xf8, + 0x8d, 0x15, 0xfb, 0x00, 0xfc, 0x8d, 0xe3, 0x8b, 0xf7, 0x2b, 0xf9, 0x59, + 0x51, 0x8b, 0x05, 0x55, 0xfb, 0x00, 0x76, 0x7e, 0xfb, 0x24, 0x77, 0x08, + 0x7e, 0x4c, 0xf7, 0x33, 0x8b, 0x05, 0x0e, 0xf8, 0xa0, 0xe2, 0x15, 0xfc, + 0x0d, 0x06, 0x9c, 0xbc, 0xc2, 0xbc, 0xe6, 0xb8, 0x08, 0xf7, 0x04, 0xc4, + 0x05, 0xf7, 0x19, 0xce, 0xcc, 0xde, 0x8b, 0xef, 0x8b, 0xb7, 0x7c, 0xb5, + 0x70, 0xa9, 0x69, 0xb1, 0x5b, 0x9d, 0x47, 0x8b, 0xfb, 0x2e, 0x8b, 0x33, + 0x3e, 0x64, 0xfb, 0x3d, 0x08, 0xe3, 0x06, 0x97, 0xb8, 0x97, 0xa9, 0x9d, + 0xa4, 0xaa, 0xb7, 0xbd, 0xa4, 0xc5, 0x8b, 0xd1, 0x8b, 0xb9, 0x60, 0x8b, + 0x4b, 0x8b, 0x4b, 0x5b, 0x4f, 0x38, 0x61, 0x08, 0x23, 0x57, 0x05, 0xfb, + 0x41, 0x2f, 0x5d, 0x55, 0x5f, 0xfb, 0x35, 0x08, 0xf8, 0x6b, 0x8b, 0x9e, + 0xe2, 0x05, 0x0e, 0xf7, 0xb6, 0xf7, 0xd9, 0x15, 0xa0, 0x8d, 0x95, 0x8b, + 0x99, 0x8b, 0x08, 0xde, 0xbc, 0x69, 0x52, 0xfb, 0x00, 0x3d, 0x41, 0xfb, + 0x04, 0x44, 0x5c, 0xb2, 0xc8, 0x1f, 0x8b, 0x93, 0x8c, 0x9a, 0x8d, 0x9b, + 0x08, 0x8d, 0x98, 0x33, 0x8b, 0x05, 0x87, 0x6d, 0x8a, 0x7d, 0x8b, 0x79, + 0x8b, 0xfb, 0x00, 0xcf, 0x50, 0xf7, 0x11, 0x8b, 0xe5, 0x8b, 0xd7, 0xa9, + 0xbe, 0xc3, 0xb9, 0xbc, 0xa7, 0xd3, 0x8b, 0xcc, 0x8b, 0xc4, 0x75, 0xac, + 0x53, 0xa7, 0x08, 0xe0, 0xbb, 0xb0, 0xc6, 0x8b, 0xe4, 0x8b, 0xe3, 0x43, + 0xc5, 0xfb, 0x02, 0x8b, 0x38, 0x8b, 0x45, 0x6d, 0x5a, 0x54, 0x6e, 0x69, + 0x79, 0x65, 0x78, 0x43, 0x08, 0xe3, 0x06, 0x95, 0xb7, 0x94, 0xa3, 0x9a, + 0x9f, 0xa9, 0xb4, 0xbb, 0xa2, 0xc3, 0x8b, 0xcc, 0x8b, 0xb4, 0x6a, 0x8b, + 0x55, 0x8b, 0x65, 0x7e, 0x66, 0x76, 0x74, 0x70, 0x6c, 0x56, 0x7b, 0x42, + 0x8b, 0x08, 0x85, 0x8b, 0x7f, 0x8b, 0x05, 0x7b, 0x40, 0x05, 0x0e, 0xf7, + 0xfe, 0xf7, 0x3e, 0x15, 0x67, 0xfb, 0x3e, 0xe3, 0x8b, 0xaf, 0xf7, 0x3e, + 0xf5, 0x8b, 0x9c, 0xd9, 0x21, 0x8b, 0xed, 0xf8, 0x61, 0x49, 0x8b, 0xfc, + 0x34, 0xfc, 0x53, 0x77, 0x2f, 0xf7, 0xbf, 0x8b, 0x05, 0x9c, 0xd9, 0x15, + 0xfb, 0x71, 0x8b, 0xf7, 0xb2, 0xf7, 0xc8, 0x4a, 0xfb, 0xc8, 0x05, 0x0e, + 0xf9, 0x09, 0xf9, 0x59, 0x15, 0xfc, 0x06, 0x8b, 0xfb, 0x1b, 0xfc, 0x16, + 0xdb, 0x8b, 0x05, 0xc8, 0xc1, 0xa9, 0x98, 0xc5, 0x8b, 0x08, 0xdb, 0xb9, + 0x5f, 0x3e, 0xfb, 0x10, 0x38, 0x30, 0xfb, 0x05, 0x1f, 0x3c, 0x8b, 0x60, + 0xb3, 0x88, 0xdb, 0x08, 0x33, 0x7f, 0x06, 0x81, 0x07, 0x8b, 0x50, 0x99, + 0x65, 0xae, 0x6e, 0xb1, 0x6b, 0xbf, 0x7a, 0xc9, 0x8b, 0xe8, 0x8b, 0xd6, + 0xb1, 0xc6, 0xd9, 0xb7, 0xc3, 0xa4, 0xd6, 0x8b, 0xd2, 0x8b, 0xf3, 0x42, + 0xcf, 0xfb, 0x05, 0x8b, 0x5b, 0x8b, 0x60, 0x7e, 0x5a, 0x6d, 0x08, 0xd1, + 0xf7, 0x5a, 0xf7, 0xc0, 0x8b, 0x9d, 0xe2, 0x05, 0x0e, 0xf8, 0xf6, 0xf8, + 0xa0, 0x15, 0x8c, 0x96, 0x8b, 0x95, 0x8b, 0x91, 0x8b, 0xeb, 0x46, 0xc9, + 0x20, 0x8b, 0x2d, 0x8b, 0x3b, 0x59, 0x4c, 0x28, 0x51, 0x30, 0x5c, 0xfb, + 0x45, 0x8b, 0xfb, 0x11, 0x8b, 0xfb, 0x08, 0xd6, 0x41, 0xf7, 0x0a, 0x8b, + 0xe0, 0x8b, 0xd4, 0xb0, 0xc2, 0xd3, 0x08, 0xb4, 0xc0, 0xa5, 0xd2, 0x8b, + 0xc8, 0x8b, 0xf2, 0x44, 0xcf, 0x20, 0x8b, 0x49, 0x8b, 0x53, 0x70, 0x52, + 0x52, 0xa8, 0xf7, 0x3d, 0xdd, 0xf4, 0xf0, 0x8b, 0xa2, 0x8b, 0x9f, 0x86, + 0x9c, 0x80, 0xa2, 0x7c, 0x93, 0x7f, 0x91, 0x6d, 0x08, 0x90, 0x6e, 0x8b, + 0x8b, 0x8b, 0x8a, 0x8b, 0x8a, 0x8b, 0x89, 0x8a, 0x89, 0x08, 0xe3, 0x06, + 0xfb, 0x8a, 0xfb, 0x33, 0x15, 0xcf, 0xb9, 0x5f, 0x4a, 0xfb, 0x04, 0x3b, + 0x31, 0x28, 0x46, 0x5a, 0xbc, 0xd2, 0x1f, 0xf5, 0xdc, 0xe0, 0xf1, 0x1e, + 0x0e, 0xf9, 0x33, 0xf9, 0x59, 0x15, 0xfc, 0x6f, 0x8b, 0x78, 0x34, 0xf8, + 0x13, 0x8b, 0x05, 0xfb, 0x75, 0xfb, 0x91, 0xfb, 0x00, 0xfb, 0x32, 0x31, + 0xfb, 0x67, 0x08, 0xed, 0x06, 0xce, 0xf7, 0x51, 0xf7, 0x49, 0xf7, 0xa3, + 0xf7, 0x3f, 0xf7, 0x3c, 0x08, 0x9c, 0xdc, 0x05, 0x0e, 0xf7, 0x7d, 0xf8, + 0x09, 0x15, 0x22, 0x5b, 0x55, 0x3d, 0x8b, 0x25, 0x8b, 0x25, 0xdc, 0x49, + 0xf7, 0x12, 0x8b, 0xdf, 0x8b, 0xd2, 0xab, 0xc3, 0xca, 0xb6, 0xbb, 0xa4, + 0xc9, 0x8b, 0xc4, 0x8b, 0xc5, 0x70, 0xb7, 0x53, 0xab, 0x93, 0x90, 0x90, + 0x8e, 0x8e, 0x8d, 0x08, 0xb4, 0xa4, 0x95, 0x93, 0x9b, 0x9f, 0x08, 0xa6, + 0xad, 0x9c, 0xbb, 0x8b, 0xb6, 0x8b, 0xae, 0x7d, 0xae, 0x73, 0xa5, 0x6a, + 0xae, 0x5b, 0x9c, 0x4b, 0x8b, 0x3e, 0x8b, 0x50, 0x73, 0x58, 0x56, 0x61, + 0x61, 0x74, 0x54, 0x8b, 0x54, 0x8b, 0x5f, 0x95, 0x78, 0xb5, 0x69, 0x08, + 0x97, 0x81, 0x05, 0xf7, 0x42, 0xf7, 0x97, 0x15, 0xcf, 0xb4, 0x6a, 0x55, + 0x1f, 0x8b, 0x6e, 0x7e, 0x69, 0x77, 0x73, 0x6f, 0x69, 0x64, 0x7b, 0x57, + 0x8b, 0x08, 0x48, 0x63, 0xaa, 0xbf, 0xdd, 0xca, 0xc6, 0xe2, 0x1f, 0x4c, + 0xfb, 0xbe, 0x15, 0xd9, 0xbd, 0x61, 0x49, 0x2a, 0x3b, 0x40, 0x22, 0x41, + 0x58, 0xb6, 0xca, 0x1f, 0xec, 0xdc, 0xd8, 0xf0, 0x1e, 0x0e, 0xdf, 0xf7, + 0x36, 0x15, 0x8a, 0x80, 0x8b, 0x81, 0x8b, 0x85, 0x8b, 0x2b, 0xd0, 0x4d, + 0xf5, 0x8b, 0xc8, 0x8b, 0xc4, 0xa1, 0xbf, 0xb7, 0xcc, 0xc1, 0xaf, 0xcb, + 0xa7, 0xf4, 0xa4, 0xe8, 0x9c, 0xf4, 0x8b, 0xc8, 0x8b, 0xba, 0x79, 0xbc, + 0x6d, 0xac, 0x08, 0x69, 0xaf, 0x58, 0x9e, 0x4d, 0x8b, 0x31, 0x8b, 0x41, + 0x65, 0x59, 0x44, 0x61, 0x4f, 0x75, 0x4b, 0x8b, 0x50, 0x8b, 0x21, 0xd0, + 0x48, 0xf7, 0x00, 0x8b, 0xb6, 0x8b, 0xba, 0x98, 0xab, 0xa1, 0x98, 0x94, + 0x98, 0x96, 0xa9, 0xa4, 0x08, 0x63, 0xfb, 0x48, 0x45, 0x31, 0x26, 0x8b, + 0x08, 0x4b, 0x68, 0xb2, 0xd0, 0x1f, 0x34, 0x06, 0xf7, 0xc8, 0xf8, 0x6a, + 0x15, 0xcf, 0xbe, 0x58, 0x48, 0x21, 0x38, 0x34, 0x26, 0x44, 0x61, 0xb6, + 0xd3, 0xf6, 0xdc, 0xe4, 0xec, 0x1f, 0x0e, 0x7c, 0xf7, 0x80, 0xf2, 0x15, + 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0xe5, 0xf8, 0x39, + 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0x0e, 0x7c, + 0xf7, 0xd9, 0xf8, 0xa0, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, + 0xf2, 0x05, 0xfb, 0x55, 0xfc, 0x39, 0x15, 0x75, 0x24, 0xc6, 0x8b, 0x05, + 0x7d, 0x39, 0x76, 0x70, 0x5b, 0x8b, 0x08, 0x83, 0x65, 0x05, 0xcd, 0x88, + 0xbd, 0xbc, 0x9c, 0xe0, 0x08, 0xa5, 0xf7, 0x0b, 0x22, 0x8b, 0x05, 0x0e, + 0xf7, 0xb7, 0xe2, 0xf7, 0x5a, 0x15, 0xf8, 0x51, 0xfb, 0x63, 0x9c, 0xd8, + 0xfb, 0xf5, 0xf7, 0x37, 0xf8, 0x3a, 0xf7, 0x38, 0x9c, 0xda, 0xfc, 0xa9, + 0xfb, 0x63, 0x7c, 0x46, 0x05, 0x0e, 0xf7, 0xb7, 0xf8, 0xf5, 0xf7, 0xf7, + 0x15, 0xfc, 0x78, 0x8b, 0x7d, 0x43, 0xf8, 0x77, 0x8b, 0x9a, 0xd3, 0x05, + 0x66, 0xfb, 0x40, 0x15, 0xfc, 0x77, 0x8b, 0x7c, 0x43, 0xf8, 0x78, 0x8b, + 0x99, 0xd3, 0x05, 0x0e, 0xf7, 0xb7, 0xf8, 0xe8, 0xf7, 0x9f, 0x15, 0xfc, + 0x51, 0xf7, 0x63, 0x7a, 0x3e, 0xf7, 0xf5, 0xfb, 0x37, 0xfc, 0x3a, 0xfb, + 0x38, 0x7a, 0x3c, 0xf8, 0xa9, 0xf7, 0x63, 0x9a, 0xd0, 0x05, 0x0e, 0xf8, + 0x07, 0xf7, 0x5b, 0x15, 0x95, 0xba, 0x05, 0x99, 0xbd, 0x9b, 0x9e, 0xd5, + 0xc2, 0xf2, 0xd9, 0xb5, 0xcc, 0x8b, 0xd8, 0x8b, 0xb8, 0x75, 0xb7, 0x67, + 0xa7, 0x6e, 0xa2, 0x61, 0x96, 0x57, 0x8b, 0xfb, 0x24, 0x8b, 0x31, 0x3b, + 0x6c, 0xfb, 0x2e, 0x08, 0xe0, 0x06, 0xa1, 0xf7, 0x01, 0xbb, 0xbb, 0xe3, + 0x8b, 0xca, 0x8b, 0xb7, 0x68, 0x8b, 0x58, 0x8b, 0x52, 0x6f, 0x61, 0x3e, + 0x4d, 0x20, 0x37, 0x7c, 0x79, 0x7d, 0x4e, 0x08, 0x7f, 0x54, 0xe5, 0x8b, + 0x05, 0x77, 0x2b, 0x15, 0x31, 0x8b, 0x75, 0x24, 0xe5, 0x8b, 0xa1, 0xf2, + 0x05, 0x0e, 0xf9, 0x66, 0xf9, 0x97, 0xf8, 0x89, 0x15, 0x67, 0x49, 0x05, + 0x7f, 0xc6, 0x65, 0xa9, 0x50, 0x8b, 0x08, 0xfb, 0x29, 0xfb, 0x3b, 0xfb, + 0x3f, 0xfb, 0x2c, 0x37, 0xc1, 0x54, 0xdc, 0x1f, 0xba, 0x8b, 0xb0, 0x9b, + 0xc0, 0xb7, 0x8d, 0x8d, 0x91, 0x90, 0x92, 0x90, 0x08, 0x8b, 0x82, 0x8b, + 0x86, 0x05, 0x8b, 0x7b, 0x97, 0x75, 0x99, 0x82, 0x08, 0x9a, 0x81, 0xa6, + 0x85, 0xaa, 0x8b, 0xe7, 0x8b, 0xf7, 0x02, 0xc4, 0xc8, 0xda, 0xba, 0xc7, + 0xa9, 0xea, 0x8b, 0xe1, 0x8b, 0xf7, 0x45, 0xfb, 0x2a, 0xf7, 0x16, 0xfb, + 0x61, 0x8b, 0xfb, 0x32, 0x8b, 0xfb, 0x34, 0x48, 0xfb, 0x03, 0xfb, 0x03, + 0xfb, 0x00, 0xfb, 0x01, 0x4b, 0xfb, 0x21, 0x8b, 0xfb, 0x17, 0x08, 0x8b, + 0x3d, 0xa3, 0x49, 0xbc, 0x54, 0xd2, 0x3c, 0xf7, 0x00, 0x5d, 0xf7, 0x07, + 0x8b, 0xdc, 0x8b, 0xe5, 0x9a, 0xd5, 0xa6, 0x08, 0x7e, 0xce, 0x05, 0x33, + 0x74, 0x54, 0x82, 0x4e, 0x8b, 0x08, 0xfb, 0x4b, 0xfb, 0x10, 0xf4, 0xf7, + 0x30, 0xf7, 0x7f, 0xf7, 0x89, 0xf7, 0x7d, 0xf7, 0x8b, 0xf7, 0x3d, 0xf7, + 0x10, 0x21, 0xfb, 0x24, 0xfb, 0x1a, 0xfb, 0x0f, 0xfb, 0x2d, 0xfb, 0x01, + 0x75, 0x78, 0x9c, 0x9e, 0x1f, 0x8b, 0x94, 0x92, 0x9c, 0x9c, 0xab, 0x08, + 0xf7, 0x29, 0xf7, 0xac, 0x05, 0x39, 0x06, 0xfb, 0x31, 0x5d, 0x15, 0xb7, + 0xa3, 0x74, 0x61, 0x1f, 0x8b, 0x5f, 0x6c, 0x40, 0x60, 0x4f, 0x08, 0x64, + 0x53, 0x5c, 0x6c, 0x5f, 0x8b, 0x5f, 0x8b, 0x6b, 0xaf, 0x8b, 0xbd, 0x8b, + 0xbd, 0xa7, 0xcd, 0xb6, 0xbd, 0xb6, 0xbe, 0xbd, 0xa7, 0xbb, 0x8b, 0x08, + 0x0e, 0xf8, 0x0a, 0xf8, 0xa0, 0xf7, 0x6f, 0x15, 0xa6, 0xfb, 0x6f, 0xf1, + 0x8b, 0x26, 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfc, 0x33, 0xfd, 0x6d, 0xee, + 0x8b, 0xf7, 0x0f, 0xf7, 0x6f, 0xf7, 0xb1, 0x8b, 0x05, 0x81, 0xd9, 0x15, + 0xfb, 0x7b, 0x8b, 0xf7, 0x53, 0xf7, 0xe1, 0xb3, 0xfb, 0xe1, 0x05, 0x0e, + 0xf8, 0x0a, 0xda, 0x16, 0xf7, 0xde, 0x06, 0xdd, 0x8b, 0xca, 0xa7, 0xc0, + 0xc6, 0xb6, 0xba, 0xa1, 0xc6, 0x8b, 0xcc, 0x8b, 0xc8, 0x70, 0xae, 0x45, + 0xa9, 0x08, 0xe2, 0xb2, 0xbc, 0xd3, 0x8b, 0xe4, 0x8b, 0xb1, 0x80, 0xa8, + 0x72, 0xa6, 0x69, 0xaf, 0x61, 0x9a, 0x46, 0x8b, 0x08, 0xfb, 0xbc, 0x8b, + 0x05, 0xfb, 0x2f, 0xfd, 0x6d, 0x05, 0xf7, 0x4a, 0xf8, 0x33, 0x15, 0xbd, + 0xf7, 0x7c, 0xf7, 0x48, 0x8b, 0x05, 0xe0, 0xb2, 0x70, 0x50, 0x1f, 0x8b, + 0x66, 0x7d, 0x66, 0x73, 0x71, 0x6d, 0x6b, 0x63, 0x7d, 0x49, 0x8b, 0x08, + 0xfb, 0x48, 0x06, 0x44, 0xfb, 0xe1, 0x15, 0xc1, 0xf7, 0x8f, 0xf7, 0x76, + 0x8b, 0x05, 0xd0, 0xb0, 0x6b, 0x50, 0x1f, 0x8b, 0x65, 0x7f, 0x68, 0x75, + 0x6d, 0x6c, 0x63, 0x65, 0x7a, 0x53, 0x8b, 0x08, 0xfb, 0x77, 0x06, 0x0e, + 0xf8, 0x41, 0xf9, 0x96, 0xf8, 0x8b, 0x15, 0x88, 0xc6, 0x81, 0xb1, 0x78, + 0xad, 0x62, 0xd1, 0x44, 0xb0, 0x2d, 0x8b, 0xfb, 0x09, 0x8b, 0x2a, 0x5c, + 0x3d, 0x2d, 0x3c, 0x2c, 0x5a, 0xfb, 0x1e, 0x8b, 0xfb, 0x11, 0x8b, 0x45, + 0x9f, 0x4c, 0xb0, 0x5c, 0xb9, 0x51, 0xca, 0x70, 0xe4, 0x8b, 0x08, 0xf5, + 0x8b, 0xe7, 0xb2, 0xcc, 0xd2, 0xb2, 0xb6, 0xab, 0xc2, 0xad, 0xdc, 0x08, + 0x29, 0x06, 0x72, 0x52, 0x7b, 0x6d, 0x79, 0x73, 0x61, 0x4f, 0x3f, 0x66, + 0x3c, 0x8b, 0x23, 0x8b, 0x46, 0xdc, 0x8b, 0xf7, 0x0d, 0x8b, 0xe6, 0xa9, + 0xef, 0xbe, 0xd7, 0xc8, 0xe5, 0xd4, 0xb6, 0xe7, 0x8b, 0xf0, 0x8b, 0xbd, + 0x5a, 0x93, 0xfb, 0x00, 0x08, 0xeb, 0x06, 0x0e, 0xf8, 0x41, 0xe4, 0x16, + 0xf7, 0xae, 0x06, 0xf7, 0x00, 0x8b, 0xe6, 0xb8, 0xd4, 0xe4, 0xcf, 0xde, + 0xbb, 0xf7, 0x26, 0x8b, 0xf7, 0x11, 0x8b, 0xd4, 0x6d, 0xd5, 0x5c, 0xb5, + 0x65, 0xad, 0x56, 0x9d, 0x4a, 0x8b, 0x08, 0xfb, 0xae, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0x05, 0xf7, 0x03, 0xdd, 0x15, 0xf7, 0x0d, 0xf8, 0xc9, 0xf7, + 0x3f, 0x8b, 0x05, 0xf6, 0xcb, 0x4c, 0x23, 0x1f, 0x8b, 0x2f, 0x6b, 0xfb, + 0x0c, 0x63, 0x4c, 0x57, 0x3b, 0x3f, 0x60, 0x30, 0x8b, 0x08, 0xfb, 0x40, + 0x06, 0x0e, 0xf8, 0x0a, 0xf7, 0x93, 0xf7, 0xe0, 0x15, 0xf8, 0x1f, 0x8b, + 0x9d, 0xdd, 0xfc, 0x20, 0x8b, 0xbd, 0xf7, 0x7d, 0xf8, 0x30, 0x8b, 0x9c, + 0xdd, 0xfc, 0x8e, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0x9f, 0x8b, 0x9c, + 0xdd, 0xfc, 0x41, 0x8b, 0xc1, 0xf7, 0x8e, 0x05, 0x0e, 0xf7, 0xd2, 0xf7, + 0x93, 0xf7, 0xe0, 0x15, 0xf7, 0xef, 0x8b, 0x9c, 0xdd, 0xfb, 0xef, 0x8b, + 0xbd, 0xf7, 0x7d, 0xf8, 0x1f, 0x8b, 0x9c, 0xdd, 0xfc, 0x7d, 0x8b, 0xfb, + 0x2f, 0xfd, 0x6d, 0xe9, 0x8b, 0xd2, 0xf7, 0xe0, 0x05, 0x0e, 0xf8, 0x79, + 0xf9, 0xad, 0xf8, 0x15, 0x15, 0xfb, 0xc4, 0x8b, 0x79, 0x39, 0xf7, 0x72, + 0x8b, 0x85, 0x71, 0x05, 0x7c, 0x49, 0x6e, 0x5d, 0x58, 0x61, 0x55, 0x5f, + 0x51, 0x76, 0x46, 0x8b, 0x41, 0x8b, 0x4b, 0xa7, 0x6c, 0xb9, 0x74, 0xae, + 0x7d, 0xc0, 0x8b, 0xc4, 0x8b, 0xe3, 0xae, 0xf2, 0xc0, 0xd1, 0xc8, 0xda, + 0xe1, 0xb6, 0xec, 0x8b, 0x08, 0xc8, 0x8b, 0xbd, 0x79, 0xac, 0x68, 0xa5, + 0x71, 0x95, 0x70, 0x8c, 0x5d, 0x08, 0xe6, 0x92, 0x06, 0x8b, 0x8f, 0x8b, + 0x91, 0x05, 0xf7, 0x19, 0x2a, 0xde, 0xfb, 0x31, 0x1e, 0xfb, 0x08, 0x8b, + 0x29, 0x63, 0x3d, 0x3d, 0x2b, 0x2b, 0x51, 0xfb, 0x1c, 0x8b, 0xfb, 0x16, + 0x8b, 0x2d, 0xad, 0x35, 0xc3, 0x5e, 0xb9, 0x65, 0xcc, 0x76, 0xcf, 0x8b, + 0xcc, 0x8b, 0xd0, 0x9d, 0xc1, 0xaa, 0xa3, 0x99, 0x9e, 0x99, 0xb1, 0xab, + 0x08, 0x8f, 0x31, 0xc6, 0x8b, 0xde, 0xf8, 0x19, 0x05, 0x0e, 0xf8, 0x41, + 0xf9, 0x01, 0xf7, 0xe0, 0x15, 0x44, 0xfb, 0xe0, 0xe9, 0x8b, 0xf7, 0x2f, + 0xf9, 0x6d, 0x2d, 0x8b, 0x48, 0xfb, 0xcf, 0xfc, 0x09, 0x8b, 0xce, 0xf7, + 0xcf, 0x2d, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xe9, 0x8b, 0xd2, 0xf7, 0xe0, + 0xf8, 0x09, 0x8b, 0x05, 0x0e, 0x7c, 0xf7, 0xf1, 0xf9, 0x6d, 0x15, 0x2d, + 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xe9, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, + 0x0e, 0xf7, 0x63, 0xf8, 0x7b, 0xf9, 0x6d, 0x15, 0xfb, 0x01, 0xfc, 0x95, + 0x05, 0x7f, 0x53, 0x7e, 0x6a, 0x75, 0x72, 0x73, 0x70, 0x66, 0x7a, 0x66, + 0x8b, 0x55, 0x8b, 0x67, 0xaa, 0x8b, 0xb8, 0x8b, 0x96, 0x8c, 0x96, 0x8e, + 0x97, 0x08, 0x99, 0xcd, 0x2d, 0x8b, 0x7d, 0x4b, 0x05, 0x87, 0x7a, 0x89, + 0x7a, 0x8b, 0x7d, 0x8b, 0x60, 0xa0, 0x61, 0xad, 0x6f, 0xa7, 0x75, 0xad, + 0x81, 0xbc, 0x8b, 0xf7, 0x18, 0x8b, 0xe7, 0xd5, 0xa7, 0xf7, 0x17, 0x08, + 0xf7, 0x08, 0xf8, 0xb7, 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf7, 0x76, + 0xf7, 0x8d, 0x15, 0xf7, 0x2e, 0xf7, 0x13, 0xf7, 0x3c, 0xfc, 0x0c, 0xf7, + 0x02, 0x8b, 0xfb, 0x62, 0xf8, 0x43, 0xf7, 0xfd, 0xf7, 0xbe, 0xfb, 0x0c, + 0x8b, 0xfc, 0x50, 0xfc, 0x09, 0xda, 0xf8, 0x09, 0x2d, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0xe9, 0x8b, 0xc0, 0xf7, 0x8d, 0x05, 0x0e, 0xf7, 0xdd, 0xf9, + 0x6d, 0x15, 0x2d, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0x5a, 0x8b, 0x9c, + 0xdd, 0xfb, 0xfc, 0x8b, 0xf7, 0x1e, 0xf9, 0x1b, 0x05, 0x0e, 0xf8, 0xb0, + 0xf8, 0x67, 0x16, 0xf7, 0xe2, 0xf8, 0xf1, 0xfb, 0x15, 0xfc, 0xf1, 0xe4, + 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0xfb, 0x17, 0x8b, 0xfb, 0xee, 0xfd, 0x07, + 0x3b, 0xf9, 0x07, 0xfb, 0x15, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xe4, 0x8b, + 0xf7, 0x15, 0xf8, 0xf1, 0xd8, 0xfc, 0xf1, 0xec, 0x8b, 0x05, 0x0e, 0xf8, + 0x41, 0xf9, 0xb5, 0xf9, 0x6d, 0x15, 0x32, 0x8b, 0xfb, 0x13, 0xfc, 0xea, + 0xfb, 0x8e, 0xf8, 0xea, 0x23, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xe4, 0x8b, + 0xf7, 0x12, 0xf8, 0xe3, 0xf7, 0x8d, 0xfc, 0xe3, 0xf5, 0x8b, 0xf7, 0x2f, + 0xf9, 0x6d, 0x05, 0x0e, 0xf8, 0x79, 0xf8, 0xad, 0xf9, 0x79, 0x15, 0xfb, + 0x05, 0x8b, 0x2a, 0x61, 0x3a, 0x36, 0x32, 0x2f, 0x56, 0xfb, 0x18, 0x8b, + 0xfb, 0x13, 0x8b, 0x35, 0xa6, 0x3e, 0xb9, 0x5d, 0xbb, 0x5b, 0xdc, 0x6e, + 0xe0, 0x8b, 0xe9, 0x8b, 0xe0, 0xa6, 0xcc, 0xbd, 0xf7, 0x09, 0xe5, 0xd7, + 0xf7, 0x36, 0x8b, 0xf7, 0x32, 0x08, 0x8b, 0xda, 0x6f, 0xd7, 0x5f, 0xb8, + 0x5a, 0xbc, 0x3c, 0xa7, 0x30, 0x8b, 0x08, 0x7f, 0x3a, 0x15, 0xcf, 0x8b, + 0xcb, 0x6f, 0xad, 0x5f, 0xa6, 0x68, 0x99, 0x5b, 0x8b, 0x50, 0x8b, 0x30, + 0x6b, 0x29, 0x56, 0x43, 0x51, 0x3a, 0x33, 0x5d, 0x2a, 0x8b, 0x4a, 0x8b, + 0x4c, 0xa7, 0x68, 0xb7, 0x70, 0xad, 0x7d, 0xbc, 0x8b, 0xc5, 0x08, 0x8b, + 0xe7, 0xaa, 0xec, 0xc0, 0xd4, 0xc5, 0xdb, 0xe4, 0xba, 0xe9, 0x8b, 0x08, + 0x0e, 0xf8, 0x0a, 0xf7, 0x8f, 0xf7, 0xc9, 0x15, 0xf7, 0x78, 0x06, 0xca, + 0x8b, 0xba, 0x9b, 0xb8, 0xaf, 0xca, 0xbd, 0xaf, 0xd7, 0x8b, 0xdc, 0x08, + 0xf5, 0x4c, 0xc2, 0xfb, 0x0e, 0x1e, 0xfb, 0xc2, 0x8b, 0xfb, 0x2f, 0xfd, + 0x6d, 0xe9, 0x8b, 0xcd, 0xf7, 0xc9, 0x05, 0x9c, 0xdd, 0x15, 0xc2, 0xf7, + 0x94, 0xf7, 0x56, 0x8b, 0x05, 0xd9, 0xb5, 0x69, 0x4c, 0x1f, 0x8b, 0x68, + 0x7f, 0x6a, 0x74, 0x6d, 0x6a, 0x61, 0x60, 0x78, 0x4b, 0x8b, 0x08, 0xfb, + 0x56, 0x06, 0x0e, 0xf8, 0x79, 0xf9, 0x71, 0x8a, 0x15, 0x3d, 0xd8, 0x05, + 0xf7, 0x02, 0xee, 0xca, 0xf7, 0x1d, 0x8b, 0xf7, 0x24, 0x8b, 0xde, 0x70, + 0xd9, 0x5d, 0xba, 0x5b, 0xbb, 0x3a, 0xa8, 0x32, 0x8b, 0x32, 0x8b, 0x3d, + 0x71, 0x46, 0x58, 0xfb, 0x0b, 0x32, 0x3d, 0xfb, 0x32, 0x8b, 0xfb, 0x2d, + 0x8b, 0xfb, 0x48, 0xf5, 0x20, 0xf7, 0x48, 0x8b, 0x08, 0xd8, 0x8b, 0xb9, + 0x97, 0xd4, 0xb2, 0x08, 0xe2, 0x34, 0xc7, 0xc5, 0x05, 0xfb, 0x65, 0xf7, + 0x62, 0x15, 0x51, 0x53, 0xc9, 0x4d, 0x05, 0x5a, 0x75, 0x6e, 0x84, 0x62, + 0x8b, 0xfb, 0x17, 0x8b, 0x3d, 0xdb, 0x8b, 0xf7, 0x1a, 0x8b, 0xe6, 0xab, + 0xed, 0xc0, 0xd3, 0xc4, 0xdb, 0xe4, 0xba, 0xe9, 0x8b, 0xcf, 0x8b, 0xca, + 0x70, 0xae, 0x5e, 0xa6, 0x68, 0x99, 0x5b, 0x8b, 0x50, 0x08, 0x8b, 0xfb, + 0x0b, 0x5c, 0xfb, 0x03, 0x34, 0x37, 0x08, 0x41, 0xd4, 0x05, 0x0e, 0xf8, + 0x41, 0xf7, 0x92, 0xf7, 0xce, 0x15, 0xf7, 0x83, 0x06, 0xcc, 0xaf, 0x71, + 0x5a, 0x1f, 0x8b, 0x7a, 0x88, 0x76, 0x86, 0x75, 0x08, 0x73, 0x27, 0x8b, + 0x8b, 0x8b, 0x6b, 0x8b, 0x7c, 0x8c, 0x80, 0x8e, 0x76, 0x08, 0xf7, 0x05, + 0x8b, 0x90, 0xa2, 0x05, 0x7e, 0x97, 0x83, 0x9e, 0x8b, 0xa1, 0x8b, 0x97, + 0x8d, 0x9c, 0x8f, 0xa0, 0x08, 0x98, 0xcf, 0x93, 0xbf, 0x8b, 0x9d, 0x8b, + 0xb7, 0x7e, 0xa0, 0x5c, 0xaa, 0xb2, 0xa1, 0x9b, 0x96, 0x9d, 0x9b, 0x08, + 0xb3, 0xb0, 0xa6, 0xce, 0x8b, 0xc9, 0x08, 0xf5, 0x51, 0xbb, 0xfb, 0x14, + 0x1e, 0xfb, 0xe4, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xe9, 0x8b, 0x05, 0xce, + 0xf7, 0xce, 0x05, 0x9c, 0xdd, 0x15, 0xc1, 0xf7, 0x8f, 0xf7, 0x7a, 0x8b, + 0x05, 0xc0, 0x8b, 0xa5, 0x84, 0x9e, 0x76, 0x98, 0x7d, 0x93, 0x74, 0x8b, + 0x73, 0x8b, 0x66, 0x7c, 0x5f, 0x75, 0x6f, 0x6e, 0x67, 0x61, 0x7a, 0x4b, + 0x8b, 0x08, 0xfb, 0x7b, 0x06, 0x0e, 0xf8, 0x0a, 0xf9, 0x56, 0xf8, 0x97, + 0x15, 0x91, 0xa7, 0x8d, 0x98, 0x8b, 0x9a, 0x8b, 0xb6, 0x76, 0xb9, 0x6a, + 0xa8, 0x62, 0xaf, 0x56, 0x9b, 0x3d, 0x8b, 0x24, 0x8b, 0x3a, 0x6e, 0x55, + 0x53, 0x62, 0x61, 0x6c, 0x44, 0x8b, 0x58, 0x8b, 0x4c, 0xb7, 0x56, 0xce, + 0x78, 0x08, 0xf7, 0x3f, 0x5b, 0x05, 0xdb, 0x74, 0xac, 0x6e, 0x8b, 0x5b, + 0x8b, 0x6c, 0x78, 0x65, 0x6f, 0x71, 0x62, 0x66, 0x50, 0x78, 0x3b, 0x8b, + 0xfb, 0x05, 0x8b, 0x57, 0xb5, 0x8b, 0xe6, 0x8b, 0x98, 0x8c, 0x94, 0x8e, + 0x9e, 0x08, 0x34, 0x06, 0x84, 0x71, 0x89, 0x7b, 0x8b, 0x76, 0x8b, 0xfb, + 0x0c, 0xe5, 0x43, 0xf7, 0x2b, 0x8b, 0xf4, 0x8b, 0xe3, 0xa8, 0xc6, 0xc2, + 0xbe, 0xba, 0xaf, 0xd4, 0x8b, 0xc3, 0x8b, 0xa5, 0x82, 0xa7, 0x7c, 0xa3, + 0x75, 0xae, 0x6e, 0x9f, 0x5c, 0x98, 0x08, 0xfb, 0x40, 0xbc, 0x05, 0x3e, + 0xa1, 0x73, 0x9f, 0x8b, 0xb7, 0x8b, 0xae, 0x9a, 0xaa, 0xa8, 0xa6, 0xb0, + 0xac, 0xbc, 0x9b, 0xcd, 0x8b, 0xc3, 0x8b, 0xb5, 0x80, 0xa1, 0x77, 0x9e, + 0x7a, 0x98, 0x6b, 0x8b, 0x6e, 0x8b, 0x82, 0x8a, 0x84, 0x88, 0x77, 0x08, + 0xe3, 0x06, 0x0e, 0xf7, 0xd2, 0xf8, 0x81, 0xf9, 0x1b, 0x15, 0xf7, 0x82, + 0x8b, 0x9c, 0xdd, 0xfc, 0xd1, 0x8b, 0x7a, 0x39, 0xf7, 0x85, 0x8b, 0xfb, + 0x1e, 0xfd, 0x1b, 0xe9, 0x8b, 0xf7, 0x1e, 0xf9, 0x1b, 0x05, 0x0e, 0xf8, + 0x41, 0xf9, 0x56, 0xf9, 0x6d, 0x15, 0xfb, 0x01, 0xfc, 0x94, 0x05, 0x76, + 0x28, 0x39, 0x4f, 0xfb, 0x05, 0x8b, 0x2b, 0x8b, 0x4a, 0xb9, 0x8b, 0xd0, + 0x8b, 0x99, 0x8d, 0x99, 0x8e, 0x9b, 0x08, 0xf7, 0x01, 0xf8, 0x94, 0x2d, + 0x8b, 0x25, 0xfc, 0x72, 0x05, 0x84, 0x6a, 0x84, 0x5b, 0x8b, 0x7c, 0x8b, + 0x62, 0xa2, 0x59, 0xab, 0x6e, 0xb4, 0x66, 0xcd, 0x76, 0xd8, 0x8b, 0xf7, + 0x3c, 0x8b, 0xf7, 0x15, 0xe9, 0xaa, 0xf7, 0x26, 0x08, 0xf7, 0x01, 0xf8, + 0x94, 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0x1c, 0x16, 0xf8, 0x2c, + 0xf9, 0x6d, 0x28, 0x8b, 0xfb, 0xe4, 0xfc, 0xfd, 0x38, 0xf8, 0xfd, 0x2a, + 0x8b, 0xf6, 0xfd, 0x6d, 0xef, 0x8b, 0x05, 0x0e, 0xf9, 0x1f, 0xf9, 0x7c, + 0x16, 0xf7, 0xe8, 0xf9, 0x6d, 0x23, 0x8b, 0xfb, 0x9b, 0xfc, 0xe4, 0x62, + 0xf8, 0xe4, 0x2b, 0x8b, 0xfb, 0xb4, 0xfc, 0xe4, 0x7c, 0xf8, 0xe4, 0x27, + 0x8b, 0xab, 0xfd, 0x6d, 0xf1, 0x8b, 0xf7, 0xb6, 0xf8, 0xe4, 0xb4, 0xfc, + 0xe4, 0xf1, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0x6b, 0xf8, 0x0a, 0x15, + 0xf7, 0xd7, 0xf7, 0xf7, 0xfb, 0x06, 0x8b, 0xfb, 0x8c, 0xfb, 0xb1, 0xfb, + 0x11, 0xf7, 0xb1, 0xfb, 0x05, 0x8b, 0xf7, 0x3b, 0xfb, 0xf7, 0xfb, 0xe7, + 0xfc, 0x0a, 0xf7, 0x07, 0x8b, 0xf7, 0x9c, 0xf7, 0xc4, 0xf7, 0x1a, 0xfb, + 0xc4, 0xf7, 0x07, 0x8b, 0xfb, 0x47, 0xf8, 0x0a, 0x05, 0x0e, 0xf8, 0x0a, + 0xf8, 0x54, 0xf7, 0xb2, 0x15, 0xf8, 0x04, 0xf8, 0x4f, 0xfb, 0x03, 0x8b, + 0xfb, 0xb5, 0xfb, 0xf9, 0xfb, 0x1c, 0xf7, 0xf9, 0xfb, 0x04, 0x8b, 0xf7, + 0x4e, 0xfc, 0x4f, 0x4e, 0xfb, 0xb2, 0xe9, 0x8b, 0xc8, 0xf7, 0xb2, 0x05, + 0x0e, 0xf7, 0xd2, 0xf9, 0x75, 0xf9, 0x6d, 0x15, 0xfc, 0xa1, 0x8b, 0x7a, + 0x39, 0xf8, 0x2a, 0x8b, 0xfc, 0xbf, 0xfc, 0xc7, 0x79, 0x37, 0xf8, 0xc0, + 0x8b, 0x9c, 0xdd, 0xfc, 0x4a, 0x8b, 0xf8, 0xc0, 0xf8, 0xc7, 0x9d, 0xdf, + 0x05, 0x0e, 0x7c, 0xf8, 0x29, 0xf9, 0x6d, 0x15, 0xfb, 0x4e, 0x8b, 0xfb, + 0x5c, 0xfe, 0x42, 0xf7, 0x4e, 0x8b, 0x9a, 0xd3, 0x25, 0x8b, 0xf7, 0x3e, + 0xf9, 0xb2, 0xf1, 0x8b, 0x9a, 0xd3, 0x05, 0x0e, 0x7c, 0xf7, 0x27, 0xf9, + 0x6d, 0x15, 0xd9, 0xfd, 0x81, 0xc2, 0x8b, 0x3d, 0xf9, 0x81, 0x54, 0x8b, + 0x05, 0x0e, 0x7c, 0x74, 0xfb, 0x69, 0x15, 0xf7, 0x4f, 0x8b, 0xf7, 0x5c, + 0xfa, 0x42, 0xfb, 0x4f, 0x8b, 0x7c, 0x43, 0xf2, 0x8b, 0xfb, 0x3e, 0xfd, + 0xb2, 0x24, 0x8b, 0x7c, 0x43, 0x05, 0x0e, 0xf7, 0x44, 0xf7, 0xf1, 0xf9, + 0x59, 0x15, 0xfb, 0x7e, 0xfc, 0x10, 0xd3, 0x8b, 0xf7, 0x4a, 0xf7, 0xbf, + 0xc5, 0xfb, 0xbf, 0xd0, 0x8b, 0x41, 0xf8, 0x10, 0x42, 0x8b, 0x05, 0x0e, + 0xf8, 0xbb, 0xfb, 0x12, 0x15, 0xfc, 0xeb, 0x8b, 0x80, 0x59, 0xf8, 0xeb, + 0x8b, 0x96, 0xbd, 0x05, 0x0e, 0x44, 0xf7, 0x94, 0xf8, 0x71, 0x15, 0xa1, + 0xf2, 0x5c, 0x8b, 0x05, 0x96, 0xc7, 0x9f, 0xa5, 0xb1, 0x8f, 0x08, 0x93, + 0xb2, 0x05, 0x4d, 0x87, 0x5f, 0x5c, 0x79, 0x3a, 0x08, 0x76, 0x27, 0xe8, + 0x8b, 0x05, 0x0e, 0xf8, 0xbc, 0xbe, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x87, + 0x8b, 0x71, 0x8b, 0x7f, 0x94, 0x8b, 0x9f, 0x8b, 0x8f, 0x8b, 0x8e, 0x8c, + 0x8e, 0x08, 0xcb, 0xf7, 0xc1, 0x05, 0x91, 0xa6, 0x8b, 0x8b, 0x8b, 0x95, + 0x8b, 0xcf, 0x46, 0xb8, 0x22, 0x8b, 0xfb, 0x1f, 0x8b, 0x36, 0x50, 0x78, + 0xfb, 0x03, 0x08, 0xdf, 0x06, 0x94, 0xa7, 0x92, 0x99, 0x99, 0x99, 0xa1, + 0xa1, 0xb5, 0x9a, 0xb6, 0x8b, 0xc7, 0x8b, 0xb9, 0x70, 0x8b, 0x66, 0x8b, + 0x87, 0x8a, 0x84, 0x8a, 0x83, 0x08, 0x88, 0x79, 0x05, 0x82, 0x62, 0x78, + 0x80, 0x42, 0x84, 0xfb, 0x1a, 0x7f, 0x61, 0x81, 0x5a, 0x6c, 0x57, 0x6a, + 0x6d, 0x56, 0x8b, 0x51, 0x8b, 0x3b, 0xc1, 0x5b, 0xe5, 0x8b, 0xae, 0x8b, + 0xb5, 0x92, 0xaf, 0x98, 0xab, 0x96, 0x9a, 0x95, 0xb4, 0xaf, 0x08, 0x8b, + 0x84, 0x8b, 0x87, 0x05, 0x62, 0xa7, 0x72, 0xbb, 0x1e, 0x96, 0x8b, 0x8e, + 0x8b, 0xa4, 0x91, 0x8d, 0x8c, 0x91, 0x8c, 0x91, 0x8c, 0x08, 0x98, 0xcc, + 0x05, 0xfb, 0x0d, 0xf7, 0x05, 0x15, 0x7e, 0x4d, 0x33, 0x56, 0x33, 0x8b, + 0x52, 0x8b, 0x6b, 0xa3, 0x8b, 0xb5, 0x8b, 0xac, 0x9e, 0xac, 0xa9, 0x9d, + 0xa3, 0x9a, 0xa9, 0x93, 0xbc, 0x92, 0xe9, 0x98, 0x93, 0x8c, 0xb7, 0x9a, + 0x08, 0x77, 0x2d, 0x05, 0x0e, 0xf7, 0x65, 0xf9, 0x6d, 0x15, 0xfb, 0x2f, + 0xfd, 0x6d, 0xd6, 0x8b, 0x9c, 0xd9, 0x05, 0x98, 0x6c, 0x94, 0x7d, 0x9a, + 0x7c, 0x08, 0xa5, 0x71, 0xb4, 0x7c, 0xb7, 0x8b, 0xce, 0x8b, 0xd2, 0xaa, + 0xb8, 0xba, 0xce, 0xd2, 0xb7, 0xf7, 0x06, 0x8b, 0xf2, 0x8b, 0xf7, 0x04, + 0x3f, 0xdf, 0x26, 0x8b, 0x63, 0x8b, 0x5e, 0x7f, 0x6d, 0x79, 0x7a, 0x80, + 0x7e, 0x80, 0x6c, 0x6a, 0x08, 0xc5, 0xf7, 0xa7, 0x05, 0x37, 0x06, 0xf7, + 0x42, 0xfb, 0x9f, 0x15, 0xd4, 0xb7, 0x57, 0x35, 0x1f, 0x8b, 0x52, 0x7a, + 0x4b, 0x6e, 0x5b, 0x62, 0x47, 0x57, 0x6a, 0x4a, 0x8b, 0x47, 0x8b, 0x60, + 0xbd, 0x8b, 0xda, 0x8b, 0xc9, 0x9d, 0xcf, 0xa7, 0xbb, 0xb2, 0xcd, 0xc0, + 0xae, 0xc7, 0x8b, 0x08, 0x0e, 0xf7, 0x63, 0xf8, 0xbb, 0xf7, 0xf0, 0x15, + 0x8c, 0x9a, 0x05, 0x8c, 0x9a, 0x8c, 0x96, 0x8b, 0x8e, 0x8b, 0xac, 0x79, + 0xb3, 0x71, 0xa6, 0x6c, 0xab, 0x62, 0x9a, 0x52, 0x8b, 0x31, 0x8b, 0x3a, + 0x65, 0x56, 0x46, 0x5c, 0x4e, 0x69, 0xfb, 0x01, 0x8b, 0x2f, 0x8b, 0x5c, + 0x9b, 0x5a, 0xa7, 0x68, 0x08, 0xad, 0x60, 0xb8, 0x78, 0xcb, 0x8b, 0xdd, + 0x8b, 0xd0, 0xa8, 0xb9, 0xc1, 0xa5, 0xa9, 0x9b, 0xad, 0x9b, 0xc3, 0x08, + 0x37, 0x06, 0x6d, 0x39, 0x54, 0x5f, 0x43, 0x8b, 0x46, 0x8b, 0x5f, 0xbc, + 0x8b, 0xd9, 0x8b, 0xcb, 0xa0, 0xd7, 0xac, 0xbf, 0xb0, 0xc6, 0xbd, 0xa9, + 0xc8, 0x8b, 0xca, 0x8b, 0xb2, 0x68, 0x8b, 0x52, 0x8b, 0x85, 0x8b, 0x84, + 0x8a, 0x82, 0x08, 0xdf, 0x06, 0x0e, 0xf9, 0x1e, 0xf9, 0x6d, 0x15, 0x37, + 0x8b, 0x4f, 0xfb, 0xad, 0x05, 0x6b, 0xcc, 0x63, 0xa5, 0x44, 0x8b, 0x08, + 0xfb, 0x3a, 0xfb, 0x10, 0xfb, 0x32, 0xfb, 0x67, 0xfb, 0x09, 0xce, 0x3f, + 0xf3, 0x1f, 0xb6, 0x8b, 0xb9, 0x99, 0xb3, 0xa3, 0xa9, 0x9d, 0x98, 0x9a, + 0x99, 0xa7, 0x08, 0x7b, 0x3f, 0xdc, 0x8b, 0x05, 0xf7, 0x2f, 0xf9, 0x6d, + 0x05, 0xfb, 0xbb, 0xfb, 0x9f, 0x15, 0xd5, 0xb7, 0x59, 0x36, 0x1f, 0x8b, + 0x50, 0x7b, 0x4e, 0x6d, 0x57, 0x08, 0x64, 0x48, 0x5a, 0x69, 0x4e, 0x8b, + 0x41, 0x8b, 0x60, 0xbd, 0x8b, 0xe1, 0x8b, 0xc3, 0x9c, 0xcb, 0xa6, 0xbe, + 0xb1, 0xd0, 0xbb, 0xab, 0xcb, 0x8b, 0x08, 0x0e, 0xf8, 0xc7, 0xf7, 0x7e, + 0x15, 0x8e, 0x9c, 0x05, 0x94, 0xbb, 0x90, 0xb5, 0x8b, 0xa6, 0x8b, 0xeb, + 0x38, 0xd6, 0xfb, 0x00, 0x8b, 0x34, 0x8b, 0x37, 0x62, 0x59, 0x48, 0x5c, + 0x4c, 0x66, 0xfb, 0x06, 0x8b, 0x3a, 0x8b, 0x55, 0xa2, 0x54, 0xb2, 0x66, + 0xae, 0x69, 0xb7, 0x7b, 0xc4, 0x8b, 0x08, 0xf7, 0x0c, 0x8b, 0xf2, 0xd5, + 0xaa, 0xf7, 0x00, 0x08, 0x37, 0x06, 0x67, 0x46, 0x56, 0x67, 0x48, 0x8b, + 0x3c, 0x8b, 0x5e, 0xbc, 0x8b, 0xe0, 0x8b, 0xa0, 0x8c, 0x95, 0x8f, 0x9a, + 0x08, 0xf8, 0x16, 0x06, 0xfc, 0x04, 0xd3, 0x15, 0xa5, 0xe7, 0xd5, 0xcb, + 0xdc, 0x8b, 0xd2, 0x8b, 0xb8, 0x5b, 0x8b, 0x40, 0x8b, 0x81, 0x8a, 0x84, + 0x89, 0x7b, 0x08, 0xfb, 0xba, 0x06, 0x0e, 0x7c, 0xf8, 0x06, 0xf8, 0xa0, + 0x15, 0x35, 0x8b, 0x9a, 0xd0, 0x05, 0x96, 0xbd, 0x9d, 0x9c, 0xb6, 0x8b, + 0x92, 0x8b, 0x91, 0x8b, 0x99, 0x89, 0x08, 0x9a, 0xd0, 0x05, 0x79, 0x8f, + 0x80, 0x8c, 0x7b, 0x8b, 0x3e, 0x8b, 0x53, 0x5e, 0x7b, 0x41, 0x08, 0x78, + 0x32, 0x45, 0x8b, 0x7d, 0x48, 0xd1, 0x8b, 0x2a, 0xfc, 0x5d, 0xdf, 0x8b, + 0xec, 0xf8, 0x5d, 0xe1, 0x8b, 0x99, 0xce, 0x05, 0x0e, 0xf8, 0xa1, 0xf8, + 0xa0, 0x15, 0x7a, 0x3d, 0x05, 0x7c, 0xac, 0x81, 0x99, 0x75, 0x9b, 0x08, + 0x71, 0x9e, 0x6b, 0x96, 0x69, 0x8b, 0x3e, 0x8b, 0x3d, 0x65, 0x5a, 0x4d, + 0x56, 0x49, 0x65, 0xfb, 0x05, 0x8b, 0x2f, 0x8b, 0xfb, 0x01, 0xd2, 0x3f, + 0xf1, 0x8b, 0xca, 0x8b, 0xc6, 0xa6, 0xbd, 0xc0, 0x08, 0x87, 0x78, 0x05, + 0x6e, 0xfb, 0x1c, 0x55, 0x55, 0x21, 0x8b, 0x08, 0x47, 0x63, 0xa6, 0xb8, + 0x1f, 0x8b, 0x91, 0x8b, 0x93, 0x37, 0x8b, 0x8a, 0x7e, 0x05, 0x8a, 0x83, + 0x8b, 0x85, 0x8b, 0x87, 0x8b, 0x3e, 0xd1, 0x59, 0xf6, 0x8b, 0xda, 0x8b, + 0xd2, 0xa3, 0xb8, 0xb6, 0xbd, 0xbb, 0xa6, 0xc8, 0xa6, 0xf7, 0x13, 0x08, + 0xe8, 0xf8, 0x4b, 0x05, 0x3f, 0x06, 0xfb, 0x36, 0x4d, 0x15, 0xcb, 0xb5, + 0x5b, 0x40, 0x1f, 0x8b, 0x4d, 0x79, 0x41, 0x6f, 0x5a, 0x6a, 0x4e, 0x50, + 0x65, 0x4f, 0x8b, 0x48, 0x8b, 0x61, 0xbd, 0x8b, 0xda, 0x8b, 0xc7, 0x9c, + 0xcb, 0xa8, 0xbf, 0x08, 0xaf, 0xcc, 0xc3, 0xb0, 0xca, 0x8b, 0x08, 0x0e, + 0xf7, 0x75, 0xf9, 0x6d, 0x15, 0xfb, 0x2f, 0xfd, 0x6d, 0xdf, 0x8b, 0xc8, + 0xf7, 0xb5, 0x05, 0xa3, 0xf7, 0x02, 0xd1, 0xcf, 0xe6, 0x8b, 0xbe, 0x8b, + 0xad, 0x69, 0x8b, 0x58, 0x8b, 0x7f, 0x8b, 0x8b, 0x85, 0x70, 0x08, 0x42, + 0xfb, 0xeb, 0xdf, 0x8b, 0xdb, 0xf8, 0x0c, 0x05, 0x8e, 0x98, 0x8c, 0x97, + 0x8b, 0x97, 0x8b, 0xda, 0x58, 0xba, 0x37, 0x8b, 0x40, 0x8b, 0x5a, 0x76, + 0x4c, 0x50, 0x08, 0xc4, 0xf7, 0xa2, 0x37, 0x8b, 0x05, 0x0e, 0x44, 0xf7, + 0x99, 0xf8, 0xa0, 0x15, 0x37, 0x8b, 0xfb, 0x03, 0xfc, 0xa0, 0xdf, 0x8b, + 0xf7, 0x03, 0xf8, 0xa0, 0x05, 0xb7, 0xf7, 0x61, 0x15, 0x37, 0x8b, 0x75, + 0x24, 0xdf, 0x8b, 0xa1, 0xf2, 0x05, 0x0e, 0x44, 0xf7, 0x48, 0xf8, 0xa0, + 0x15, 0xfb, 0x13, 0xfc, 0xec, 0x05, 0x7f, 0x53, 0x7c, 0x7d, 0x58, 0x8b, + 0x86, 0x8b, 0x89, 0x8b, 0x79, 0x8d, 0x08, 0x7c, 0x44, 0x05, 0x92, 0x89, + 0x8e, 0x8a, 0x94, 0x8b, 0xf7, 0x07, 0x8b, 0xb6, 0xa6, 0x9d, 0xdd, 0x08, + 0xf7, 0x1a, 0xf9, 0x0d, 0x37, 0x8b, 0x05, 0xf7, 0x14, 0xf7, 0x61, 0x15, + 0x37, 0x8b, 0x75, 0x24, 0xdf, 0x8b, 0xa1, 0xf2, 0x05, 0x0e, 0xf7, 0x63, + 0xf7, 0xbd, 0xf9, 0x6d, 0x15, 0x37, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xdf, + 0x8b, 0xb6, 0xf7, 0x5f, 0xf6, 0xe3, 0xf7, 0x06, 0xfb, 0xb7, 0xeb, 0x8b, + 0xfb, 0x20, 0xf7, 0xeb, 0xf7, 0x72, 0xf7, 0x49, 0xfb, 0x00, 0x8b, 0xfb, + 0xa1, 0xfb, 0x6e, 0xe5, 0xf8, 0x3b, 0x05, 0x0e, 0x44, 0xf7, 0xc7, 0xf9, + 0x6d, 0x15, 0x37, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xdf, 0x8b, 0xf7, 0x2f, + 0xf9, 0x6d, 0x05, 0x0e, 0xf8, 0xb0, 0xf7, 0x4a, 0xf8, 0xa0, 0x15, 0xfb, + 0x03, 0xfc, 0xa0, 0xdf, 0x8b, 0xd1, 0xf7, 0xdd, 0x05, 0x9b, 0xd7, 0xcf, + 0xc9, 0xce, 0x8b, 0xbc, 0x8b, 0xac, 0x6f, 0x8b, 0x62, 0x8b, 0x80, 0x8a, + 0x7e, 0x88, 0x7e, 0x08, 0x3e, 0xfb, 0xfd, 0xdf, 0x8b, 0xd1, 0xf7, 0xdd, + 0x05, 0x9b, 0xd9, 0xd0, 0xc7, 0xd3, 0x8b, 0xba, 0x8b, 0xa8, 0x6e, 0x8b, + 0x5b, 0x8b, 0x7c, 0x8b, 0x8b, 0x82, 0x69, 0x08, 0x43, 0xfb, 0xe9, 0xdf, + 0x8b, 0xda, 0xf8, 0x09, 0x05, 0x8e, 0x96, 0x8e, 0xac, 0x8b, 0x96, 0x8b, + 0xa5, 0x7f, 0xa7, 0x77, 0xa2, 0x75, 0xa3, 0x70, 0x95, 0x5d, 0x8b, 0x4a, + 0x8b, 0x52, 0x71, 0x50, 0x52, 0x7b, 0xc3, 0x64, 0xa6, 0x49, 0x8b, 0x47, + 0x8b, 0x5d, 0x77, 0x4b, 0x4f, 0x08, 0x98, 0xcc, 0x05, 0x3f, 0x06, 0x0e, + 0xf7, 0x49, 0xf8, 0xa0, 0x15, 0xfb, 0x03, 0xfc, 0xa0, 0xdf, 0x8b, 0xc8, + 0xf7, 0xb5, 0x05, 0xa3, 0xf7, 0x02, 0xd1, 0xcf, 0xe5, 0x8b, 0xbd, 0x8b, + 0xb0, 0x68, 0x8b, 0x5d, 0x8b, 0x85, 0x89, 0x7c, 0x87, 0x7b, 0x08, 0x41, + 0xfb, 0xf1, 0xdf, 0x8b, 0xdb, 0xf8, 0x0c, 0x05, 0x8e, 0x98, 0x8c, 0x97, + 0x8b, 0x98, 0x8b, 0xd7, 0x56, 0xbc, 0x38, 0x8b, 0x3f, 0x8b, 0x49, 0x70, + 0x57, 0x56, 0x08, 0x98, 0xcc, 0x05, 0x3f, 0x06, 0x0e, 0xf8, 0x14, 0xf8, + 0xaf, 0x15, 0x2e, 0x8b, 0x39, 0x61, 0x58, 0x41, 0x5e, 0x4b, 0x6a, 0xfb, + 0x02, 0x8b, 0x36, 0x8b, 0xfb, 0x03, 0xd8, 0x3f, 0xf7, 0x04, 0x8b, 0xeb, + 0x8b, 0xd7, 0xb2, 0xc3, 0xd8, 0xb9, 0xca, 0xac, 0xf7, 0x01, 0x8b, 0xe2, + 0x8b, 0xc0, 0x77, 0xbe, 0x68, 0xad, 0x08, 0x69, 0xac, 0x5e, 0x9b, 0x51, + 0x8b, 0x08, 0x7e, 0x3e, 0x15, 0xd5, 0xb6, 0x5b, 0x3a, 0x1f, 0x8b, 0x50, + 0x7a, 0x4a, 0x70, 0x59, 0x65, 0x46, 0x55, 0x67, 0x46, 0x8b, 0x44, 0x8b, + 0x5f, 0xbd, 0x8b, 0xdb, 0x8b, 0xc4, 0x9c, 0xcd, 0xa6, 0xbd, 0xb0, 0xcf, + 0xc3, 0xb0, 0xcd, 0x8b, 0x08, 0x0e, 0x92, 0xfb, 0x69, 0x15, 0xdf, 0x8b, + 0xc7, 0xf7, 0xad, 0x05, 0xaa, 0x4a, 0xb4, 0x71, 0xd2, 0x8b, 0xd9, 0x8b, + 0xd6, 0xaf, 0xbe, 0xca, 0xc1, 0xcd, 0xad, 0xf3, 0x8b, 0xed, 0x8b, 0xf7, + 0x0c, 0x48, 0xd6, 0x20, 0x8b, 0x5f, 0x8b, 0x5f, 0x7e, 0x63, 0x71, 0x6b, + 0x77, 0x7f, 0x7e, 0x7e, 0x70, 0x08, 0x9d, 0xdf, 0x3a, 0x8b, 0x05, 0xfb, + 0x31, 0xfd, 0x75, 0x05, 0xf8, 0x08, 0xf9, 0x37, 0x15, 0xd6, 0xb7, 0x57, + 0x35, 0x1f, 0x8b, 0x55, 0x7a, 0x4a, 0x70, 0x59, 0x66, 0x47, 0x59, 0x6a, + 0x4a, 0x8b, 0x42, 0x8b, 0x5d, 0xbd, 0x8b, 0xdb, 0x8b, 0xc7, 0x9c, 0xcc, + 0xa9, 0xbf, 0x08, 0xb0, 0xce, 0xbd, 0xad, 0xc9, 0x8b, 0x08, 0x0e, 0xf8, + 0x56, 0xfb, 0x69, 0x15, 0xf7, 0x31, 0xf9, 0x75, 0x40, 0x8b, 0x78, 0x35, + 0x05, 0x74, 0xcc, 0x58, 0xaf, 0x42, 0x8b, 0x47, 0x8b, 0x44, 0x6d, 0x5e, + 0x5b, 0x48, 0x44, 0x5f, 0xfb, 0x06, 0x8b, 0x24, 0x8b, 0xfb, 0x04, 0xd7, + 0x37, 0xf0, 0x8b, 0xb3, 0x8b, 0xb9, 0x97, 0xa8, 0x9d, 0x9b, 0x95, 0x97, + 0x96, 0xad, 0xad, 0x08, 0x50, 0xfb, 0xa7, 0x05, 0xdf, 0x06, 0x35, 0xf9, + 0x37, 0x15, 0xce, 0xb6, 0x59, 0x3c, 0x1f, 0x8b, 0x4d, 0x79, 0x47, 0x6f, + 0x5b, 0x63, 0x49, 0x57, 0x68, 0x4f, 0x8b, 0x44, 0x8b, 0x5d, 0xbf, 0x8b, + 0xdb, 0x8b, 0xc5, 0x9e, 0xd3, 0xa6, 0xb8, 0xb2, 0xcd, 0xc3, 0xae, 0xcb, + 0x8b, 0x08, 0x0e, 0xb3, 0xf7, 0x48, 0xf8, 0xa0, 0x15, 0xfb, 0x03, 0xfc, + 0xa0, 0xdf, 0x8b, 0xc5, 0xf7, 0xa4, 0x05, 0xa5, 0xf7, 0x0e, 0xd2, 0xc8, + 0xf7, 0x02, 0x87, 0x08, 0x9d, 0xe0, 0x05, 0x7e, 0x8d, 0x83, 0x8c, 0x80, + 0x8b, 0x51, 0x8b, 0x5e, 0x71, 0x4d, 0x44, 0x08, 0x9c, 0xdd, 0x05, 0x3f, + 0x06, 0x0e, 0xf7, 0x63, 0xf8, 0x96, 0xf8, 0x0e, 0x15, 0x90, 0xa0, 0x8c, + 0x94, 0x8b, 0x98, 0x8b, 0xd1, 0x48, 0xbb, 0x2a, 0x8b, 0x44, 0x8b, 0x4e, + 0x76, 0x62, 0x64, 0x67, 0x68, 0x73, 0x57, 0x8b, 0x5c, 0x8b, 0x4e, 0xae, + 0x6e, 0xf2, 0x70, 0x08, 0xd5, 0x78, 0x05, 0xac, 0x82, 0x9a, 0x85, 0x94, + 0x80, 0x08, 0x92, 0x82, 0x91, 0x7c, 0x8b, 0x82, 0x8b, 0x79, 0x7b, 0x6c, + 0x7b, 0x7e, 0x72, 0x76, 0x60, 0x7e, 0x60, 0x8b, 0x46, 0x8b, 0x64, 0xa6, + 0x8b, 0xbd, 0x8b, 0x91, 0x8c, 0x94, 0x8c, 0x95, 0x08, 0x32, 0x06, 0x86, + 0x74, 0x8a, 0x7f, 0x8b, 0x7b, 0x08, 0x3b, 0xd1, 0x5b, 0xf7, 0x08, 0xf7, + 0x29, 0xec, 0xd8, 0xf7, 0x0b, 0x1e, 0x8b, 0xc8, 0x6a, 0xab, 0x33, 0xa1, + 0x08, 0x3f, 0x9e, 0x05, 0x53, 0x99, 0x6e, 0x9f, 0x8b, 0xa5, 0x8b, 0x9f, + 0x97, 0xa4, 0x9d, 0x9c, 0xa3, 0xa2, 0xa9, 0x95, 0xb7, 0x8b, 0xc6, 0x8b, + 0xac, 0x74, 0x8b, 0x64, 0x8b, 0x84, 0x8b, 0x84, 0x8a, 0x83, 0x08, 0xdf, + 0x06, 0x0e, 0x7c, 0xf8, 0x02, 0xf8, 0xa0, 0x15, 0x32, 0x8b, 0xaa, 0xf7, + 0x24, 0x37, 0x8b, 0x6c, 0xfb, 0x24, 0x44, 0x8b, 0x7d, 0x48, 0xd2, 0x8b, + 0x3c, 0xfc, 0x06, 0x05, 0x89, 0x81, 0x8a, 0x80, 0x8b, 0x81, 0x8b, 0x5a, + 0xad, 0x6d, 0xc2, 0x8b, 0x9f, 0x8b, 0xaa, 0x8e, 0x99, 0x8f, 0x08, 0x9b, + 0xd4, 0x05, 0x6c, 0x84, 0x86, 0x8a, 0x7f, 0x8b, 0x75, 0x8b, 0x7d, 0x96, + 0x8b, 0x9b, 0x8b, 0x8e, 0x8c, 0x90, 0x8c, 0x91, 0x08, 0xd9, 0xf8, 0x03, + 0xe4, 0x8b, 0x99, 0xce, 0x05, 0x0e, 0xf8, 0x77, 0x16, 0xf7, 0x03, 0xf8, + 0xa0, 0x37, 0x8b, 0x4c, 0xfb, 0xbd, 0x05, 0x74, 0xfb, 0x00, 0x44, 0x45, + 0x36, 0x8b, 0x55, 0x8b, 0x68, 0xa9, 0x8b, 0xba, 0x8b, 0x93, 0x8c, 0x94, + 0x8d, 0x95, 0x08, 0xda, 0xf8, 0x07, 0x37, 0x8b, 0x35, 0xfc, 0x28, 0x05, + 0x89, 0x81, 0x8a, 0x80, 0x8b, 0x7e, 0x8b, 0x47, 0xbf, 0x62, 0xe1, 0x8b, + 0xd9, 0x8b, 0xc4, 0xa3, 0xc5, 0xc3, 0x08, 0x7f, 0x52, 0x05, 0xd7, 0x06, + 0x0e, 0xf7, 0x63, 0xf7, 0xb3, 0x16, 0xf7, 0xcb, 0xf8, 0xa0, 0x30, 0x8b, + 0xfb, 0x88, 0xfc, 0x3a, 0x5a, 0xf8, 0x3a, 0x2f, 0x8b, 0xd5, 0xfc, 0xa0, + 0xe6, 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf8, 0xc0, 0x16, 0xf7, 0x9c, 0xf8, + 0xa0, 0x30, 0x8b, 0xfb, 0x58, 0xfc, 0x2c, 0x80, 0xf8, 0x2c, 0x22, 0x8b, + 0xfb, 0x51, 0xfc, 0x2c, 0x78, 0xf8, 0x2c, 0x30, 0x8b, 0xb3, 0xfc, 0xa0, + 0xeb, 0x8b, 0xf7, 0x57, 0xf8, 0x36, 0x97, 0xfc, 0x36, 0xea, 0x8b, 0x05, + 0x0e, 0xf7, 0x63, 0xf7, 0xf2, 0xf7, 0x9f, 0x15, 0xf7, 0x7d, 0xf7, 0x95, + 0x2a, 0x8b, 0xfb, 0x3b, 0xfb, 0x54, 0x33, 0xf7, 0x54, 0x2e, 0x8b, 0xf7, + 0x0a, 0xfb, 0x95, 0xfb, 0x83, 0xfb, 0x9f, 0xed, 0x8b, 0xf7, 0x42, 0xf7, + 0x5c, 0xe5, 0xfb, 0x5c, 0xe9, 0x8b, 0xfb, 0x0f, 0xf7, 0x9f, 0x05, 0x0e, + 0xf7, 0x63, 0xf8, 0x89, 0xf8, 0xa0, 0x15, 0xfb, 0x7d, 0xfc, 0x2b, 0x5d, + 0xf8, 0x2b, 0x31, 0x8b, 0xcf, 0xfc, 0xa4, 0x57, 0x3a, 0x05, 0x70, 0x61, + 0x7b, 0x81, 0x66, 0x8b, 0x81, 0x8b, 0x84, 0x8c, 0x70, 0x8e, 0x08, 0x7b, + 0x40, 0x05, 0x9d, 0x83, 0x97, 0x89, 0x9e, 0x8b, 0xd2, 0x8b, 0xbe, 0xad, + 0xb6, 0xd5, 0x08, 0xf8, 0x04, 0xf9, 0x0e, 0x32, 0x8b, 0x05, 0x0e, 0xf7, + 0x63, 0xf8, 0xc1, 0xf8, 0xa0, 0x15, 0xfc, 0x1c, 0x8b, 0x7c, 0x43, 0xf7, + 0xba, 0x8b, 0xfc, 0x1f, 0xfc, 0x0e, 0x79, 0x41, 0xf8, 0x3f, 0x8b, 0x9a, + 0xd3, 0xfb, 0xda, 0x8b, 0xf8, 0x1c, 0xf8, 0x0d, 0x9d, 0xd6, 0x05, 0x0e, + 0xb4, 0xf8, 0x43, 0xf9, 0x6d, 0x15, 0x5c, 0x06, 0x67, 0x8b, 0x6b, 0x7d, + 0x71, 0x6f, 0x75, 0x73, 0x81, 0x75, 0x81, 0x5f, 0x08, 0x67, 0xfb, 0x3a, + 0x05, 0x79, 0x32, 0x6d, 0x64, 0x51, 0x81, 0x08, 0x7c, 0x46, 0x05, 0xb0, + 0x85, 0x9f, 0x72, 0x8b, 0x63, 0x8b, 0x7b, 0x88, 0x73, 0x85, 0x70, 0x08, + 0x68, 0xfb, 0x3a, 0x05, 0x87, 0x79, 0x89, 0x77, 0x8b, 0x7b, 0x08, 0x59, + 0xab, 0x6e, 0xc1, 0x1e, 0xba, 0x8b, 0x99, 0xcd, 0x7b, 0x8b, 0x05, 0x65, + 0x7b, 0x95, 0xa3, 0x1f, 0x8b, 0x95, 0x8c, 0x96, 0x8e, 0x97, 0x08, 0xb2, + 0xf7, 0x49, 0x05, 0x8f, 0x9e, 0x8d, 0x9f, 0x8b, 0xa1, 0x8b, 0xbe, 0x80, + 0xa1, 0x66, 0xa3, 0xc3, 0xaa, 0xb1, 0xc2, 0x99, 0xd2, 0x08, 0xb2, 0xf7, + 0x49, 0x05, 0x96, 0xbf, 0x9c, 0x9a, 0xbd, 0x8b, 0x08, 0x9b, 0x8b, 0x05, + 0x99, 0xcc, 0x05, 0x0e, 0x6a, 0xf7, 0x93, 0xf9, 0x6d, 0x15, 0xfb, 0x5d, + 0xfe, 0x41, 0xc7, 0x8b, 0xf7, 0x5d, 0xfa, 0x41, 0x4f, 0x8b, 0x05, 0x0e, + 0xb4, 0x7b, 0xfb, 0x69, 0x15, 0xba, 0x06, 0xb8, 0x8b, 0xa3, 0x95, 0xa6, + 0xab, 0x9f, 0xa2, 0x96, 0xa4, 0x94, 0xb5, 0x08, 0xaf, 0xf7, 0x3a, 0x05, + 0x99, 0xdf, 0xad, 0xb8, 0xc5, 0x94, 0x08, 0x9a, 0xd1, 0x05, 0x66, 0x91, + 0x77, 0xa2, 0x8b, 0xb0, 0x8b, 0x9f, 0x8e, 0xa1, 0x91, 0xa9, 0x08, 0xae, + 0xf7, 0x3a, 0x05, 0x8f, 0x9e, 0x8d, 0x9c, 0x8b, 0x99, 0x08, 0xbc, 0x68, + 0xac, 0x58, 0x1e, 0x5c, 0x8b, 0x7d, 0x4a, 0x9b, 0x8b, 0x05, 0xb1, 0x9b, + 0x81, 0x73, 0x1f, 0x8b, 0x81, 0x8a, 0x80, 0x88, 0x7f, 0x08, 0x64, 0xfb, + 0x49, 0x05, 0x87, 0x78, 0x89, 0x79, 0x8b, 0x7a, 0x8b, 0x60, 0x9a, 0x6a, + 0xac, 0x6e, 0x49, 0x6c, 0x72, 0x67, 0x7a, 0x31, 0x08, 0x64, 0xfb, 0x49, + 0x05, 0x80, 0x57, 0x7a, 0x7c, 0x59, 0x8b, 0x08, 0x7b, 0x8b, 0x05, 0x7d, + 0x4a, 0x05, 0x0e, 0xf7, 0xb7, 0xf8, 0xb2, 0xf8, 0x2f, 0x15, 0x80, 0x58, + 0x76, 0x73, 0x68, 0x8b, 0x7c, 0x8b, 0x7d, 0x90, 0x79, 0x97, 0x08, 0x25, + 0xd0, 0x05, 0x7c, 0x95, 0x79, 0x91, 0x79, 0x8b, 0x4b, 0x8b, 0x5a, 0x58, + 0x72, 0x2d, 0x08, 0xbf, 0x06, 0x9b, 0xbf, 0xa3, 0xa6, 0xaa, 0x8b, 0x95, + 0x8b, 0x9d, 0x84, 0x96, 0x83, 0x08, 0xe0, 0x4c, 0x05, 0xa1, 0x7b, 0xa7, + 0x81, 0xa3, 0x8b, 0xb1, 0x8b, 0xb2, 0xa0, 0xa4, 0xad, 0x9d, 0xa3, 0x94, + 0xa2, 0x92, 0xb4, 0x08, 0x57, 0x06, 0x0e, 0xb3, 0xd7, 0xfb, 0x61, 0x15, + 0xdf, 0x8b, 0xd5, 0xf7, 0xf2, 0xa2, 0xf7, 0x67, 0x63, 0x8b, 0x48, 0xfb, + 0x67, 0x41, 0xfb, 0xf2, 0x05, 0xf7, 0x1b, 0xf9, 0x06, 0x15, 0xdf, 0x8b, + 0xa1, 0xf2, 0x37, 0x8b, 0x75, 0x24, 0x05, 0x0e, 0xf8, 0x2b, 0xf8, 0x63, + 0x15, 0x97, 0x89, 0x05, 0xc0, 0x82, 0xa6, 0x6d, 0x8b, 0x58, 0x8b, 0x85, + 0x8b, 0x83, 0x8a, 0x82, 0x08, 0xdf, 0x8b, 0x8c, 0x9a, 0x05, 0x8c, 0x9a, + 0x8c, 0x96, 0x8b, 0x8e, 0x8b, 0xc3, 0x60, 0xc6, 0x52, 0xa0, 0x77, 0x92, + 0x7a, 0x8e, 0x72, 0x8b, 0x08, 0x9e, 0xe5, 0x63, 0x8b, 0x78, 0x31, 0x05, + 0x44, 0x84, 0x59, 0x76, 0x5b, 0x60, 0x43, 0x4a, 0x5d, 0xfb, 0x08, 0x8b, + 0xfb, 0x07, 0x8b, 0x20, 0xcc, 0x40, 0xf2, 0x80, 0x08, 0x76, 0x29, 0xb3, + 0x8b, 0xa0, 0xec, 0x05, 0xf7, 0x1a, 0x93, 0xd7, 0xcb, 0xae, 0xf7, 0x17, + 0x08, 0x37, 0x06, 0x6c, 0x39, 0x60, 0x66, 0x44, 0x83, 0x08, 0xe2, 0xf8, + 0x2e, 0x05, 0xfb, 0x12, 0xfc, 0x2b, 0x15, 0x4f, 0x93, 0x66, 0xbc, 0x8b, + 0xd1, 0x8b, 0xe1, 0xb0, 0xe8, 0xc2, 0xc0, 0xa5, 0xa4, 0xa5, 0x98, 0xb1, + 0x92, 0x08, 0x36, 0xfc, 0x28, 0x05, 0x0e, 0xf8, 0x53, 0xf8, 0x0c, 0x15, + 0xfb, 0x34, 0x06, 0x87, 0x98, 0x87, 0x99, 0x8a, 0x8c, 0x75, 0xc9, 0x8b, + 0x8b, 0x8b, 0xa5, 0x08, 0xe5, 0xd4, 0xd1, 0xea, 0xd2, 0xb8, 0x65, 0x4f, + 0x1e, 0x8b, 0x79, 0x89, 0x7e, 0x84, 0x71, 0x08, 0xe3, 0x06, 0x92, 0xb5, + 0x8d, 0x9d, 0x8b, 0xa1, 0x08, 0xe5, 0x40, 0xc7, 0xfb, 0x03, 0xfb, 0x27, + 0xfb, 0x1b, 0xfb, 0x0b, 0xfb, 0x16, 0x1e, 0x8b, 0x72, 0x8f, 0x7a, 0x9c, + 0x63, 0x8f, 0x83, 0x8e, 0x83, 0x8d, 0x85, 0x08, 0x38, 0x8b, 0x7f, 0x54, + 0xf7, 0x05, 0x8b, 0x05, 0x94, 0x6e, 0x8c, 0x85, 0x8b, 0x7c, 0x8b, 0x44, + 0x52, 0x44, 0xfb, 0x09, 0x3e, 0x08, 0xb0, 0x49, 0x05, 0xb9, 0xa5, 0xae, + 0x96, 0xb0, 0x8b, 0xa2, 0x8b, 0x9f, 0x87, 0x9f, 0x84, 0xce, 0x71, 0xaf, + 0x82, 0xaf, 0x8b, 0xbb, 0x8b, 0xbe, 0x9e, 0xb6, 0xae, 0x08, 0x72, 0xd1, + 0x05, 0x61, 0x73, 0x76, 0x84, 0x6c, 0x8b, 0x70, 0x8b, 0x6d, 0x91, 0x5e, + 0x9a, 0x74, 0x93, 0x83, 0x8c, 0x75, 0x8b, 0x64, 0x8b, 0x65, 0x80, 0x53, + 0x6f, 0x9c, 0x98, 0x95, 0x92, 0x91, 0x90, 0xd4, 0xc1, 0x9e, 0xa0, 0xa1, + 0xbc, 0x08, 0x96, 0xa3, 0x92, 0xa9, 0x8b, 0x9e, 0x8b, 0x8f, 0x8a, 0x95, + 0x8a, 0x98, 0x08, 0x8a, 0x96, 0xf7, 0x1d, 0x8b, 0x05, 0x97, 0xc2, 0x05, + 0x0e, 0xfb, 0x12, 0xf8, 0x40, 0xf9, 0x59, 0x15, 0xfc, 0xf2, 0xfd, 0x6d, + 0xc5, 0x8b, 0xf8, 0xf2, 0xf9, 0x6d, 0x51, 0x8b, 0x05, 0x0e, 0xf8, 0xd1, + 0xf7, 0xf6, 0x15, 0xfb, 0x2e, 0x8b, 0xf7, 0xa9, 0xf7, 0xf7, 0x36, 0x8b, + 0xfb, 0x8c, 0xfb, 0xd6, 0xfb, 0x08, 0xf7, 0xd6, 0x36, 0x8b, 0xf7, 0x16, + 0xfb, 0xf7, 0xfb, 0x2e, 0x8b, 0x80, 0x58, 0xf7, 0x43, 0x8b, 0x7a, 0x3e, + 0xfb, 0x42, 0x8b, 0x80, 0x58, 0xf7, 0x42, 0x8b, 0x66, 0xfb, 0x43, 0x05, + 0xe3, 0x8b, 0xb0, 0xf7, 0x43, 0xf7, 0x41, 0x8b, 0x95, 0xbe, 0xfb, 0x40, + 0x8b, 0x9c, 0xd8, 0xf7, 0x40, 0x8b, 0x96, 0xbe, 0x05, 0x0e, 0xf8, 0xcb, + 0xf8, 0x64, 0x15, 0xfb, 0x05, 0x8b, 0xa6, 0xd0, 0x05, 0xab, 0xdf, 0xb5, + 0xb7, 0xba, 0x8b, 0x9c, 0x8b, 0x97, 0x86, 0x9e, 0x7c, 0x08, 0xb9, 0xd9, + 0x05, 0x72, 0x98, 0x73, 0x91, 0x71, 0x8b, 0x35, 0x8b, 0x37, 0x47, 0x60, + 0x24, 0x08, 0x60, 0x24, 0xfb, 0x11, 0x8b, 0x7c, 0x43, 0xf7, 0x04, 0x8b, + 0xfb, 0x39, 0xfc, 0x31, 0x05, 0x6c, 0x3d, 0x65, 0x67, 0x59, 0x8b, 0x77, + 0x8b, 0x7e, 0x90, 0x7a, 0x99, 0x08, 0x68, 0x35, 0x05, 0x9c, 0x84, 0x98, + 0x88, 0xa1, 0x8b, 0xf7, 0x05, 0x8b, 0xd9, 0xcd, 0xc3, 0xf7, 0x21, 0x08, + 0xf7, 0x32, 0xf8, 0x21, 0xf7, 0x13, 0x8b, 0x9a, 0xd3, 0x05, 0x0e, 0xf8, + 0xd3, 0xf8, 0xa0, 0x15, 0x8c, 0x90, 0x8c, 0x8e, 0x8b, 0x8c, 0x96, 0xaf, + 0x8c, 0x8f, 0x8b, 0xa0, 0x08, 0xda, 0x4c, 0xc3, 0x31, 0xfb, 0x04, 0x24, + 0x30, 0x29, 0x1e, 0x8b, 0x6d, 0x93, 0x73, 0x9d, 0x74, 0x4f, 0x6b, 0x7f, + 0x83, 0x74, 0x71, 0x6f, 0x6b, 0x77, 0x59, 0x8b, 0x62, 0x8b, 0x61, 0x9c, + 0x6c, 0xb9, 0x64, 0x08, 0xf7, 0x25, 0xfb, 0x10, 0x05, 0xa7, 0x73, 0x95, + 0x78, 0x8b, 0x6e, 0x08, 0x54, 0x58, 0x5c, 0x4e, 0x1e, 0x59, 0x66, 0xab, + 0xb8, 0x1f, 0x8b, 0x98, 0x8d, 0x96, 0x91, 0xa0, 0x08, 0x36, 0x06, 0x83, + 0x70, 0x88, 0x7e, 0x8b, 0x76, 0x8b, 0x38, 0xcb, 0x54, 0xed, 0x8b, 0xcb, + 0x8b, 0xc6, 0xa5, 0xb2, 0xb8, 0xae, 0xb1, 0x9f, 0xba, 0x8b, 0xb4, 0x8b, + 0xad, 0x83, 0xa2, 0x75, 0xa9, 0xb3, 0x98, 0xab, 0x9f, 0xa2, 0xa6, 0x08, + 0xa9, 0xae, 0xa1, 0xc4, 0x8b, 0xb7, 0x8b, 0xa7, 0x83, 0xa4, 0x7b, 0xa1, + 0x81, 0x97, 0x82, 0x94, 0x69, 0xa6, 0x08, 0xfb, 0x13, 0xf0, 0x05, 0x69, + 0xa6, 0x83, 0x97, 0x8b, 0xa2, 0x08, 0xbf, 0xbc, 0xba, 0xc3, 0x1e, 0xbd, + 0xac, 0x6d, 0x5c, 0x1f, 0x8b, 0x7b, 0x88, 0x7c, 0x84, 0x77, 0x08, 0xdf, + 0x06, 0xfb, 0xe7, 0xfb, 0xbb, 0x15, 0x69, 0xa8, 0x81, 0x9e, 0x8b, 0xab, + 0x8b, 0xbb, 0xa4, 0xaa, 0xd1, 0xb3, 0x08, 0xf7, 0x17, 0x21, 0x05, 0xab, + 0x71, 0xa0, 0x68, 0x8b, 0x6d, 0x8b, 0x5b, 0x6a, 0x61, 0x4b, 0x6a, 0x08, + 0xfb, 0x1e, 0xf7, 0x0d, 0x05, 0x0e, 0xf8, 0xa2, 0xf7, 0x53, 0x15, 0x60, + 0xc1, 0x05, 0xa9, 0xa8, 0xa3, 0xc7, 0x8b, 0xba, 0x8b, 0xa4, 0x87, 0x9b, + 0x82, 0x9b, 0x08, 0xd0, 0xc3, 0x5c, 0xc5, 0x47, 0x53, 0x05, 0x77, 0x9d, + 0x67, 0x96, 0x66, 0x8b, 0x69, 0x8b, 0x62, 0x80, 0x70, 0x7b, 0x08, 0x5e, + 0xc5, 0x49, 0x53, 0xb5, 0x54, 0x88, 0x87, 0x05, 0x6c, 0x62, 0x8b, 0x8b, + 0x82, 0x75, 0x81, 0x73, 0x86, 0x71, 0x8b, 0x74, 0x8b, 0x73, 0x90, 0x73, + 0x94, 0x7a, 0x08, 0x4f, 0x5a, 0xb7, 0x51, 0xcc, 0xbf, 0x05, 0x9e, 0x7b, + 0xab, 0x82, 0xb2, 0x8b, 0xb2, 0x8b, 0xb1, 0x96, 0xa7, 0x9e, 0x08, 0xb5, + 0x56, 0xd1, 0xc1, 0x05, 0xfb, 0x31, 0xf7, 0x95, 0x15, 0xbd, 0xb2, 0x66, + 0x5c, 0x4a, 0x4b, 0x4d, 0x46, 0x58, 0x64, 0xb0, 0xbc, 0xcc, 0xcc, 0xc7, + 0xd0, 0x1f, 0x0e, 0x25, 0xf7, 0x5a, 0xf9, 0x59, 0x15, 0x73, 0xfb, 0x03, + 0x8a, 0xfb, 0x1a, 0xb3, 0x8b, 0xc2, 0xf7, 0x1a, 0xa3, 0xf7, 0x03, 0x2d, + 0x8b, 0x05, 0x0e, 0xb3, 0xf7, 0x83, 0xf8, 0x71, 0x15, 0xa1, 0xf2, 0x5c, + 0x8b, 0x05, 0x95, 0xc5, 0xa0, 0xa6, 0xae, 0x90, 0x08, 0x93, 0xb2, 0x05, + 0x4f, 0x86, 0x5f, 0x5b, 0x7a, 0x3c, 0x08, 0x76, 0x27, 0xe8, 0x8b, 0x05, + 0xf7, 0x35, 0x16, 0xa1, 0xf2, 0x5b, 0x8b, 0x05, 0x96, 0xc5, 0x9f, 0xa6, + 0xaf, 0x90, 0x08, 0x93, 0xb2, 0x05, 0x4f, 0x86, 0x5f, 0x5b, 0x7a, 0x3c, + 0x08, 0x76, 0x27, 0xe8, 0x8b, 0x05, 0x0e, 0xf7, 0x27, 0xf7, 0x77, 0x15, + 0xf7, 0x11, 0xfb, 0x0d, 0x9d, 0xdd, 0x35, 0xde, 0xf7, 0x0d, 0xdf, 0x9d, + 0xde, 0xfb, 0x45, 0xfb, 0x0e, 0x78, 0x32, 0x05, 0xf7, 0x61, 0x16, 0xf7, + 0x11, 0xfb, 0x0d, 0x9d, 0xdd, 0x35, 0xde, 0xf7, 0x0d, 0xdf, 0x9d, 0xde, + 0xfb, 0x45, 0xfb, 0x0e, 0x78, 0x32, 0x05, 0x0e, 0xb3, 0xf7, 0x20, 0xf7, + 0x77, 0x15, 0xf7, 0x11, 0xfb, 0x0d, 0x9d, 0xdd, 0x35, 0xde, 0xf7, 0x0d, + 0xdf, 0x9d, 0xde, 0xfb, 0x45, 0xfb, 0x0e, 0x78, 0x32, 0x05, 0x0e, 0xb3, + 0xf7, 0xc7, 0xf7, 0xd1, 0x15, 0xfb, 0x13, 0xf7, 0x0d, 0x79, 0x39, 0xe3, + 0x38, 0xfb, 0x0f, 0x37, 0x79, 0x38, 0xf7, 0x47, 0xf7, 0x0e, 0x9e, 0xe4, + 0x05, 0x0e, 0xf7, 0x63, 0xf8, 0x00, 0xf8, 0xa0, 0x15, 0x35, 0x8b, 0x9a, + 0xd0, 0x05, 0x96, 0xbd, 0x9d, 0x9c, 0xb6, 0x8b, 0x91, 0x8b, 0x91, 0x8b, + 0x9a, 0x89, 0x08, 0x9a, 0xd0, 0x05, 0x79, 0x8f, 0x80, 0x8c, 0x7b, 0x8b, + 0x3e, 0x8b, 0x53, 0x5e, 0x7b, 0x41, 0x08, 0x78, 0x32, 0x45, 0x8b, 0x7d, + 0x48, 0xd1, 0x8b, 0x2a, 0xfc, 0x5d, 0xdf, 0x8b, 0xec, 0xf8, 0x5d, 0xe1, + 0x8b, 0x05, 0x99, 0xce, 0x05, 0xf7, 0x4b, 0x16, 0x37, 0x8b, 0xfb, 0x03, + 0xfc, 0xa0, 0xdf, 0x8b, 0xf7, 0x03, 0xf8, 0xa0, 0x05, 0xb7, 0xf7, 0x61, + 0x15, 0x37, 0x8b, 0x75, 0x24, 0xdf, 0x8b, 0x05, 0xa1, 0xf2, 0x05, 0x0e, + 0xf7, 0x63, 0xf8, 0x05, 0xf8, 0xa0, 0x15, 0x35, 0x8b, 0x9a, 0xd0, 0x05, + 0x96, 0xbd, 0x9d, 0x9c, 0xb6, 0x8b, 0x92, 0x8b, 0x91, 0x8b, 0x99, 0x89, + 0x08, 0x9a, 0xd0, 0x05, 0x79, 0x8f, 0x80, 0x8c, 0x7b, 0x8b, 0x3e, 0x8b, + 0x53, 0x5e, 0x7b, 0x41, 0x08, 0x78, 0x32, 0x45, 0x8b, 0x7d, 0x48, 0xd1, + 0x8b, 0x2a, 0xfc, 0x5d, 0xdf, 0x8b, 0xec, 0xf8, 0x5d, 0xe1, 0x8b, 0x05, + 0x99, 0xce, 0x05, 0xf7, 0x6c, 0xf7, 0x61, 0x15, 0x37, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0xdf, 0x8b, 0x05, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x0e, 0xf9, + 0x08, 0xf7, 0xcc, 0x15, 0xfc, 0xcb, 0x8b, 0x7c, 0x43, 0xf8, 0xcb, 0x8b, + 0x9a, 0xd3, 0x05, 0x0e, 0xf9, 0x00, 0xf8, 0x89, 0x15, 0xfb, 0x56, 0x8b, + 0xb7, 0xf7, 0x64, 0x33, 0x8b, 0x5f, 0xfb, 0x64, 0xfb, 0x56, 0x8b, 0x7a, + 0x3a, 0xf7, 0x55, 0x8b, 0xfb, 0x12, 0xfc, 0xe9, 0xe3, 0x8b, 0xf7, 0x12, + 0xf8, 0xe9, 0xf7, 0x57, 0x8b, 0x9c, 0xdc, 0x05, 0x0e, 0xf9, 0x00, 0xf8, + 0x89, 0x15, 0xfb, 0x53, 0x8b, 0xb7, 0xf7, 0x64, 0x33, 0x8b, 0x5f, 0xfb, + 0x64, 0xfb, 0x52, 0x8b, 0x7a, 0x3a, 0xf7, 0x52, 0x8b, 0x49, 0xfb, 0xc8, + 0xfb, 0x52, 0x8b, 0x7a, 0x3a, 0xf7, 0x52, 0x8b, 0x5f, 0xfb, 0x64, 0xe3, + 0x8b, 0xb7, 0xf7, 0x64, 0xf7, 0x53, 0x8b, 0x05, 0x9c, 0xdc, 0xfb, 0x53, + 0x8b, 0xcd, 0xf7, 0xc8, 0xf7, 0x53, 0x8b, 0x9c, 0xdc, 0x05, 0x0e, 0x7c, + 0xf7, 0xb9, 0xf7, 0xbb, 0x15, 0x22, 0x8b, 0x75, 0x24, 0xf4, 0x8b, 0xa1, + 0xf2, 0x05, 0x0e, 0xf7, 0x88, 0xf9, 0x39, 0xf9, 0x6d, 0x15, 0xfb, 0x8e, + 0x06, 0xfb, 0x26, 0xfb, 0x1c, 0xfb, 0x21, 0xfb, 0x2c, 0x1f, 0x8b, 0x20, + 0xc9, 0x48, 0xf2, 0x88, 0x08, 0x2e, 0xfc, 0x49, 0xcb, 0x8b, 0xf7, 0x47, + 0xf9, 0xdf, 0xde, 0x8b, 0xfb, 0x47, 0xfd, 0xdf, 0xcb, 0x8b, 0xf7, 0x47, + 0xf9, 0xdf, 0xc3, 0x8b, 0x99, 0xcb, 0x05, 0x0e, 0xc4, 0xf7, 0xa6, 0xf8, + 0x6a, 0x15, 0x3b, 0x41, 0x42, 0x3c, 0x54, 0xb7, 0x60, 0xc3, 0xdc, 0xd6, + 0xd4, 0xda, 0xc5, 0x61, 0xb3, 0x4f, 0x1f, 0x0e, 0x44, 0xe1, 0xf2, 0x15, + 0x75, 0x24, 0xbb, 0x8b, 0x05, 0x81, 0x52, 0x76, 0x6f, 0x67, 0x86, 0x08, + 0x83, 0x65, 0x05, 0xc8, 0x8f, 0xb7, 0xbb, 0x9c, 0xda, 0x08, 0xa0, 0xef, + 0x2d, 0x8b, 0x05, 0x0e, 0xb3, 0xd0, 0xf2, 0x15, 0x75, 0x24, 0xbb, 0x8b, + 0x05, 0x81, 0x52, 0x76, 0x6f, 0x67, 0x86, 0x08, 0x83, 0x65, 0x05, 0xc8, + 0x8f, 0xb7, 0xbb, 0x9c, 0xda, 0x08, 0xa0, 0xef, 0x2d, 0x8b, 0x05, 0xf7, + 0x33, 0x16, 0x75, 0x24, 0xbb, 0x8b, 0x05, 0x81, 0x52, 0x76, 0x6f, 0x67, + 0x86, 0x08, 0x83, 0x65, 0x05, 0xc8, 0x8f, 0xb7, 0xbb, 0x9c, 0xda, 0x08, + 0xa0, 0xef, 0x2d, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, 0x5b, 0xf9, 0x58, 0x15, + 0x75, 0x24, 0xbb, 0x8b, 0x05, 0x81, 0x52, 0x76, 0x6f, 0x67, 0x86, 0x08, + 0x83, 0x65, 0x05, 0xc8, 0x8f, 0xb7, 0xbb, 0x9c, 0xda, 0x08, 0xa0, 0xef, + 0x2d, 0x8b, 0x05, 0xf7, 0x33, 0x16, 0x75, 0x24, 0xbb, 0x8b, 0x05, 0x81, + 0x52, 0x76, 0x6f, 0x67, 0x86, 0x08, 0x83, 0x65, 0x05, 0xc8, 0x8f, 0xb7, + 0xbb, 0x9c, 0xda, 0x08, 0xa0, 0xef, 0x2d, 0x8b, 0x05, 0x0e, 0xf7, 0xd3, + 0xf7, 0xd1, 0x15, 0xfb, 0x13, 0xf7, 0x0d, 0x79, 0x39, 0xe3, 0x38, 0xfb, + 0x0f, 0x37, 0x79, 0x38, 0xf7, 0x47, 0xf7, 0x0e, 0x9e, 0xe4, 0x05, 0xf7, + 0x5b, 0x16, 0xfb, 0x13, 0xf7, 0x0d, 0x79, 0x39, 0xe3, 0x38, 0xfb, 0x0f, + 0x37, 0x79, 0x38, 0xf7, 0x47, 0xf7, 0x0e, 0x9e, 0xe4, 0x05, 0x0e, 0xf9, + 0x57, 0xf7, 0x85, 0xf2, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, + 0xf2, 0x05, 0xf7, 0xe1, 0x16, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, + 0xf2, 0x05, 0xf7, 0xe1, 0x16, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, + 0xf2, 0x05, 0x0e, 0xf9, 0x57, 0xf9, 0x1d, 0xf9, 0x76, 0x15, 0xfc, 0xc0, + 0xfd, 0x8a, 0xcd, 0x8b, 0xf8, 0xc0, 0xf9, 0x8a, 0x05, 0x49, 0x06, 0xfb, + 0xe3, 0x7e, 0x15, 0x2b, 0x31, 0x34, 0x2f, 0x49, 0xbf, 0x59, 0xce, 0xef, + 0xe2, 0xe0, 0xec, 0x1f, 0xcc, 0x58, 0xbb, 0x46, 0x1e, 0x7f, 0x54, 0x15, + 0xb3, 0xab, 0x6c, 0x64, 0x4e, 0x57, 0x55, 0x4f, 0x60, 0x6c, 0xa9, 0xb4, + 0xc7, 0xc0, 0xc1, 0xc8, 0x1f, 0xf7, 0x85, 0xfc, 0x1e, 0x15, 0x2b, 0x31, + 0x34, 0x2f, 0x49, 0xbf, 0x59, 0xce, 0xef, 0xe2, 0xe0, 0xec, 0xcc, 0x58, + 0xbb, 0x46, 0x1f, 0x7f, 0x54, 0x15, 0xb3, 0xab, 0x6c, 0x64, 0x4e, 0x57, + 0x55, 0x4f, 0x60, 0x6c, 0xa9, 0xb4, 0xc7, 0xc0, 0xc1, 0xc8, 0x1f, 0xf8, + 0x09, 0xc2, 0x15, 0x2b, 0x31, 0x34, 0x2f, 0x49, 0xbf, 0x59, 0xce, 0xef, + 0xe2, 0xe0, 0xec, 0xcc, 0x58, 0xbb, 0x46, 0x1f, 0x7f, 0x54, 0x15, 0xb3, + 0xab, 0x6c, 0x64, 0x4e, 0x57, 0x55, 0x4f, 0x60, 0x6c, 0xa9, 0xb4, 0xc7, + 0xc0, 0xc1, 0xc8, 0x1f, 0x0e, 0xf7, 0xd2, 0xf7, 0xec, 0xf7, 0xd9, 0x15, + 0x81, 0x5c, 0x05, 0x7d, 0x59, 0x7b, 0x78, 0x41, 0x54, 0x5b, 0x66, 0x72, + 0x74, 0x77, 0x71, 0x6b, 0x61, 0x78, 0x57, 0x8b, 0x5d, 0x8b, 0x6b, 0x98, + 0x6a, 0xa1, 0x72, 0xac, 0x65, 0xb8, 0x7a, 0xce, 0x8b, 0xf7, 0x24, 0x8b, + 0xe5, 0xda, 0xaa, 0xf7, 0x2f, 0x08, 0x36, 0x06, 0x75, 0xfb, 0x01, 0x5b, + 0x5b, 0x33, 0x8b, 0x4a, 0x8b, 0x61, 0xad, 0x8b, 0xc0, 0x8b, 0xc1, 0xab, + 0xbc, 0xd3, 0xc4, 0xf4, 0xdb, 0x9d, 0xa1, 0x99, 0xc8, 0x08, 0x97, 0xc2, + 0x31, 0x8b, 0x05, 0x9f, 0xeb, 0x15, 0xe5, 0x8b, 0xa1, 0xf2, 0x31, 0x8b, + 0x75, 0x24, 0x05, 0x0e, 0xb3, 0xf7, 0xb1, 0xf9, 0x78, 0x15, 0x21, 0x8b, + 0xf7, 0x11, 0xfb, 0x28, 0xc0, 0x8b, 0x43, 0xf7, 0x28, 0x05, 0x0e, 0xb3, + 0xf7, 0xee, 0xf9, 0x78, 0x15, 0xfb, 0x14, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, + 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, 0xa6, 0xf9, + 0x79, 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, 0xf3, 0xee, 0xc3, 0x28, + 0xca, 0x8b, 0x4b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0x0e, 0xb3, 0xf8, 0x36, + 0xf9, 0x63, 0x15, 0x79, 0x6e, 0x81, 0x83, 0x77, 0x8b, 0x81, 0x8b, 0x70, + 0x91, 0x71, 0x94, 0x08, 0x64, 0x98, 0x7a, 0x8f, 0x7a, 0x8b, 0x72, 0x8b, + 0x6c, 0x7c, 0x7b, 0x76, 0x7f, 0x7c, 0x83, 0x7a, 0x7f, 0x68, 0x08, 0xc0, + 0x06, 0x8e, 0x8f, 0x8d, 0x8e, 0x8d, 0x8d, 0x97, 0x9d, 0x97, 0x91, 0x9e, + 0x8b, 0x91, 0x8b, 0x95, 0x89, 0x96, 0x87, 0x08, 0xcb, 0x75, 0x9c, 0x87, + 0xa1, 0x8b, 0xb8, 0x8b, 0xb5, 0xb5, 0xa0, 0xcc, 0x08, 0x56, 0x06, 0x0e, + 0xb3, 0xf8, 0x56, 0xf9, 0x4c, 0x15, 0xfb, 0xa7, 0x8b, 0x7c, 0x46, 0xf7, + 0xa7, 0x8b, 0x9a, 0xd0, 0x05, 0x0e, 0xb3, 0xf7, 0x3e, 0xf9, 0x6d, 0x15, + 0x87, 0x78, 0x8a, 0x83, 0x8b, 0x82, 0x8b, 0x50, 0xbf, 0x63, 0xd6, 0x8b, + 0xbc, 0x8b, 0xbe, 0x9e, 0xac, 0xa9, 0xa3, 0xa0, 0x96, 0xa0, 0x96, 0xb7, + 0x08, 0x53, 0x06, 0x81, 0x63, 0x62, 0x74, 0x50, 0x8b, 0x08, 0x5a, 0x6a, + 0x9f, 0xa9, 0x1f, 0x8b, 0x90, 0x8b, 0x93, 0x56, 0x8b, 0x05, 0x0e, 0xb3, + 0xf8, 0x06, 0xf9, 0x5f, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, + 0xf2, 0x05, 0x0e, 0xb3, 0xf7, 0xb1, 0xf9, 0x5f, 0x15, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0x0e, 0xb3, 0xf7, 0xd8, 0xf9, 0x86, + 0x15, 0x55, 0x55, 0x57, 0x56, 0x64, 0xaa, 0x6c, 0xb3, 0xc4, 0xbf, 0xbf, + 0xc3, 0xb1, 0x6c, 0xa8, 0x62, 0x1f, 0x84, 0x5f, 0x15, 0x9e, 0x9a, 0x7c, + 0x77, 0x71, 0x70, 0x71, 0x70, 0x77, 0x7c, 0x99, 0xa0, 0xa5, 0xa6, 0xa5, + 0xa7, 0x1f, 0x0e, 0xb3, 0xf7, 0x39, 0x16, 0x59, 0x2f, 0x98, 0x85, 0x92, + 0x8c, 0x05, 0x9b, 0x8e, 0x8b, 0x8b, 0x8f, 0x8b, 0x08, 0x9c, 0x99, 0x81, + 0x7f, 0x6b, 0x71, 0x74, 0x66, 0x1f, 0x6f, 0x8b, 0x72, 0x93, 0x62, 0xa0, + 0x08, 0x6f, 0x65, 0x05, 0xbe, 0x71, 0xa8, 0x83, 0xb1, 0x8b, 0x08, 0xdf, + 0xc8, 0xb9, 0xca, 0xa7, 0x6d, 0xa2, 0x66, 0x1f, 0x87, 0x8b, 0x87, 0x8b, + 0x7e, 0x89, 0x08, 0xa9, 0xc3, 0x62, 0x8b, 0x05, 0x0e, 0xb3, 0xf7, 0x6f, + 0xf9, 0x78, 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, + 0x2a, 0xfb, 0x04, 0x8b, 0x05, 0xf7, 0x42, 0x16, 0xfb, 0x14, 0xfb, 0x2a, + 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x2a, 0xfb, 0x04, 0x8b, 0x05, 0x0e, 0xb3, + 0xf7, 0x39, 0x16, 0x68, 0x7e, 0x7a, 0x82, 0x78, 0x7f, 0x65, 0x72, 0x76, + 0x69, 0x8b, 0x66, 0x8b, 0x5c, 0xbc, 0x6f, 0xe0, 0x8b, 0xa7, 0x8b, 0x9e, + 0x8e, 0xa0, 0x92, 0x08, 0x94, 0xb8, 0x05, 0x79, 0x85, 0x72, 0x87, 0x70, + 0x8b, 0x64, 0x8b, 0x70, 0x9d, 0x8b, 0xa5, 0x8b, 0x9b, 0x92, 0x9e, 0x98, + 0x9a, 0x9c, 0x9f, 0x9a, 0x95, 0xbd, 0xa4, 0x95, 0x90, 0x93, 0x8e, 0x8f, + 0x8e, 0x08, 0x46, 0x06, 0x0e, 0xb3, 0xf7, 0xe3, 0xf8, 0xe4, 0x15, 0xf7, + 0x14, 0xf7, 0x28, 0x4b, 0x8b, 0x23, 0x29, 0x53, 0xed, 0x4c, 0x8b, 0xcb, + 0xfb, 0x28, 0xea, 0x8b, 0x05, 0x0e, 0xf9, 0x57, 0xfa, 0xc0, 0xf7, 0xcc, + 0x15, 0xfe, 0x87, 0x8b, 0x7c, 0x43, 0xfa, 0x87, 0x8b, 0x9a, 0xd3, 0x05, + 0x0e, 0xf9, 0x57, 0xf8, 0x95, 0xf7, 0x6a, 0x15, 0x5e, 0xfb, 0x6a, 0xf8, + 0x76, 0x8b, 0x9c, 0xdd, 0xfc, 0x18, 0x8b, 0xc0, 0xf7, 0x8e, 0xf7, 0xf3, + 0x8b, 0x9d, 0xdd, 0xfb, 0xf3, 0x8b, 0xbc, 0xf7, 0x7d, 0xf8, 0x07, 0x8b, + 0x9c, 0xdd, 0xfd, 0x02, 0x8b, 0xfc, 0x5a, 0xfd, 0x6d, 0xf2, 0x8b, 0xf7, + 0x16, 0xf7, 0x6a, 0x05, 0xf7, 0xa1, 0x06, 0x9d, 0xdc, 0x15, 0xfb, 0x82, + 0x8b, 0xf7, 0x68, 0xf7, 0xf4, 0xef, 0x8b, 0x41, 0xfb, 0xf4, 0x05, 0x0e, + 0xd8, 0xf8, 0x2a, 0xf7, 0xf6, 0x15, 0xfb, 0xb4, 0x8b, 0x80, 0x58, 0xf7, + 0xb4, 0x8b, 0x96, 0xbe, 0x05, 0xa5, 0xea, 0x15, 0x83, 0x8a, 0x05, 0x87, + 0x8a, 0x88, 0x8b, 0x89, 0x8b, 0x82, 0x8b, 0x83, 0x92, 0x8b, 0x92, 0x8b, + 0x8d, 0x8b, 0x8d, 0x8c, 0x8e, 0x08, 0xb4, 0xf7, 0x52, 0x05, 0x8c, 0x8e, + 0x8b, 0x93, 0x8b, 0x92, 0x8b, 0xb4, 0x63, 0xa4, 0x4b, 0x8b, 0x57, 0x8b, + 0x61, 0x7e, 0x72, 0x73, 0x7b, 0x7c, 0x85, 0x7e, 0x7f, 0x60, 0x08, 0xc3, + 0x06, 0x90, 0x9b, 0x8f, 0x93, 0x95, 0x96, 0x96, 0x98, 0xa5, 0x94, 0xa3, + 0x8b, 0xa1, 0x8b, 0xa2, 0x85, 0x91, 0x85, 0x95, 0x7f, 0x8c, 0x88, 0x8b, + 0x83, 0x8b, 0x86, 0x8a, 0x86, 0x8a, 0x86, 0x08, 0x89, 0x83, 0x05, 0x84, + 0x72, 0x84, 0x88, 0x5f, 0x86, 0x3c, 0x83, 0x71, 0x85, 0x6e, 0x79, 0x6b, + 0x77, 0x79, 0x6b, 0x8b, 0x66, 0x8b, 0x58, 0xad, 0x6e, 0xc8, 0x8b, 0xb4, + 0x8b, 0xb1, 0x9a, 0xa9, 0xa7, 0x8e, 0x6f, 0x9b, 0x7c, 0xa7, 0x8b, 0x08, + 0x92, 0x8b, 0x8d, 0x8b, 0x9c, 0x8f, 0x8c, 0x8b, 0x8f, 0x8c, 0x90, 0x8c, + 0x08, 0x94, 0xb7, 0x05, 0x3c, 0xcd, 0x15, 0x85, 0x6b, 0x56, 0x69, 0x5e, + 0x8b, 0x68, 0x8b, 0x79, 0x97, 0x8b, 0xa4, 0x8b, 0x9c, 0x97, 0x9f, 0x9b, + 0x95, 0x9d, 0x96, 0x98, 0x8e, 0xc4, 0x93, 0xa3, 0x8e, 0x95, 0x8d, 0x9c, + 0x91, 0x08, 0x81, 0x58, 0x05, 0x0e, 0xf7, 0x99, 0xf7, 0xcf, 0x15, 0xf7, + 0x58, 0xf7, 0x0a, 0x9c, 0xda, 0xfb, 0x58, 0xfb, 0x0a, 0xd2, 0xf7, 0xe3, + 0x2d, 0x8b, 0x3b, 0xfc, 0x0a, 0x38, 0x58, 0x7a, 0x3c, 0xde, 0xbe, 0x51, + 0xfb, 0xa8, 0xf8, 0x58, 0x8b, 0x9d, 0xdd, 0xfb, 0xfb, 0x8b, 0xbd, 0xf7, + 0x7d, 0x05, 0x0e, 0xf8, 0x79, 0xab, 0x9a, 0x15, 0xae, 0x64, 0xe6, 0xdc, + 0x05, 0xbe, 0x57, 0xd7, 0x6f, 0xe8, 0x8b, 0xe4, 0x8b, 0xde, 0xa6, 0xcf, + 0xbd, 0xf7, 0x08, 0xe1, 0xd9, 0xf7, 0x39, 0x8b, 0xf7, 0x32, 0x8b, 0xc3, + 0x7f, 0xbe, 0x72, 0xb6, 0x08, 0xe7, 0xde, 0x68, 0xb2, 0x34, 0x3d, 0x05, + 0x5f, 0xbf, 0x36, 0xab, 0x2a, 0x8b, 0xfb, 0x04, 0x8b, 0x29, 0x60, 0x3b, + 0x37, 0x34, 0x2f, 0x55, 0xfb, 0x18, 0x8b, 0xfb, 0x0e, 0x8b, 0x4c, 0x99, + 0x4b, 0xa3, 0x62, 0x08, 0x2d, 0x36, 0x05, 0xf7, 0x3e, 0xf7, 0x2d, 0x15, + 0x7e, 0xa9, 0x86, 0xa6, 0x8b, 0xb3, 0x8b, 0xf7, 0x71, 0xf7, 0x23, 0xf7, + 0x42, 0xf7, 0x49, 0x8b, 0xce, 0x8b, 0xc8, 0x72, 0xaf, 0x60, 0x08, 0xfc, + 0x6a, 0xfc, 0x3c, 0x05, 0xf8, 0x86, 0xf8, 0x0e, 0x15, 0x95, 0x72, 0x91, + 0x67, 0x8b, 0x61, 0x8b, 0x33, 0x6b, 0x28, 0x57, 0x44, 0x51, 0x3c, 0x31, + 0x5b, 0x2e, 0x8b, 0x49, 0x8b, 0x4e, 0xa4, 0x69, 0xb3, 0x08, 0xf8, 0x6a, + 0xf8, 0x3b, 0x05, 0x0e, 0xf9, 0x57, 0xf9, 0x43, 0xf7, 0xdb, 0x15, 0xf7, + 0xda, 0x8b, 0x9d, 0xdd, 0xfb, 0xdb, 0x8b, 0xbe, 0xf7, 0x82, 0xf7, 0xe4, + 0x8b, 0x9c, 0xdd, 0xfc, 0x42, 0x8b, 0x7b, 0x3f, 0x05, 0x6c, 0xc8, 0x57, + 0xa6, 0x38, 0x8b, 0x2f, 0x8b, 0x27, 0x5b, 0x46, 0x3e, 0x3e, 0x34, 0x52, + 0xfb, 0x3e, 0x8b, 0xfb, 0x20, 0x8b, 0xfb, 0x26, 0xe7, 0x2b, 0xf7, 0x1f, + 0x8b, 0xe2, 0x8b, 0xca, 0xa9, 0xc4, 0xd1, 0x08, 0x7b, 0x3e, 0xf8, 0x46, + 0x8b, 0x9c, 0xdd, 0xfb, 0xe8, 0x8b, 0x05, 0xc0, 0xf7, 0x89, 0x05, 0xfb, + 0x11, 0xfb, 0x25, 0x15, 0x52, 0x38, 0x46, 0x62, 0x37, 0x8b, 0x2b, 0x8b, + 0x50, 0xc9, 0x8b, 0xf1, 0x8b, 0xeb, 0xab, 0xf7, 0x1c, 0xb3, 0xd0, 0xbe, + 0xe5, 0xd4, 0xba, 0xe2, 0x8b, 0xe3, 0x8b, 0xbe, 0x64, 0x9e, 0x39, 0x08, + 0x3f, 0xfb, 0xf9, 0x05, 0x0e, 0xd3, 0xf8, 0x18, 0xf7, 0xf6, 0x15, 0xfb, + 0x9b, 0x8b, 0x80, 0x58, 0xf7, 0x9b, 0x8b, 0x96, 0xbe, 0x05, 0x57, 0xf8, + 0x18, 0x15, 0x54, 0x8b, 0x57, 0x71, 0x6b, 0x5f, 0x6f, 0x66, 0x77, 0x45, + 0x8b, 0x53, 0x8b, 0x4a, 0xb9, 0x5e, 0xce, 0x8b, 0xc6, 0x8b, 0xbc, 0xa4, + 0xad, 0xb9, 0xa6, 0xb1, 0xa0, 0xcf, 0x8b, 0xbe, 0x8b, 0xac, 0x7c, 0xb0, + 0x77, 0x9e, 0x08, 0x79, 0x9b, 0x6d, 0x95, 0x6a, 0x8b, 0x08, 0x82, 0x57, + 0x15, 0xb3, 0xa4, 0x6f, 0x5e, 0x2e, 0x58, 0x42, 0x4a, 0x61, 0x72, 0xa6, + 0xba, 0xe8, 0xbf, 0xd3, 0xcd, 0x1f, 0x0e, 0xf8, 0xe8, 0xf7, 0x75, 0xf8, + 0x05, 0x15, 0xa0, 0xcd, 0xb4, 0xa6, 0xda, 0x8b, 0xcb, 0x8b, 0xb3, 0x75, + 0x8b, 0x68, 0x8b, 0x85, 0x8a, 0x85, 0x8a, 0x84, 0x08, 0x86, 0x72, 0x05, + 0x81, 0x60, 0x79, 0x80, 0x43, 0x84, 0xfb, 0x15, 0x80, 0x60, 0x81, 0x59, + 0x6d, 0x58, 0x6b, 0x6c, 0x55, 0x8b, 0x51, 0x8b, 0x3d, 0xc2, 0x59, 0xe2, + 0x8b, 0xe2, 0x8b, 0xe2, 0xb0, 0xce, 0xcc, 0x08, 0xb2, 0x45, 0xc2, 0x6b, + 0xdb, 0x8b, 0xf7, 0x0d, 0x8b, 0xf1, 0xd4, 0xab, 0xf7, 0x01, 0x08, 0x37, + 0x06, 0x67, 0x46, 0x56, 0x67, 0x49, 0x8b, 0x68, 0x8b, 0x70, 0x93, 0x77, + 0x9c, 0x71, 0xa1, 0x7a, 0xad, 0x8b, 0xa7, 0x08, 0x8b, 0x91, 0x8b, 0x97, + 0x05, 0x8b, 0xa2, 0x8c, 0x97, 0x8f, 0x9d, 0x08, 0xf8, 0x16, 0x8b, 0x8e, + 0x9c, 0x05, 0x94, 0xbb, 0x90, 0xb6, 0x8b, 0xa7, 0x8b, 0xe7, 0x36, 0xd8, + 0x25, 0x8b, 0x47, 0x8b, 0x46, 0x72, 0x5e, 0x63, 0x88, 0x92, 0x89, 0x8d, + 0x78, 0x9b, 0x67, 0xa8, 0x68, 0x96, 0x4b, 0x8b, 0x38, 0x8b, 0x46, 0x75, + 0x62, 0x64, 0x08, 0x73, 0x73, 0x7e, 0x70, 0x7b, 0x51, 0x08, 0xdf, 0x06, + 0xf7, 0x58, 0xfb, 0x61, 0x15, 0x7e, 0x4f, 0x34, 0x54, 0x37, 0x8b, 0x51, + 0x8b, 0x6b, 0xa2, 0x8b, 0xb6, 0x8b, 0xac, 0x9e, 0xab, 0xa9, 0x9e, 0xa3, + 0x9a, 0xa6, 0x93, 0xbf, 0x92, 0xee, 0x99, 0x91, 0x8c, 0xb0, 0x98, 0x08, + 0x77, 0x2e, 0x05, 0xf7, 0x01, 0xf7, 0x22, 0x15, 0xaa, 0xed, 0xcf, 0xc5, + 0xde, 0x8b, 0xd2, 0x8b, 0xb7, 0x5b, 0x8b, 0x40, 0x8b, 0x80, 0x8a, 0x84, + 0x89, 0x7c, 0x08, 0xfb, 0xba, 0x06, 0x0e, 0x7c, 0xf7, 0xb6, 0xf8, 0xa3, + 0x15, 0x37, 0x8b, 0xfb, 0x04, 0xfc, 0xa3, 0xdf, 0x8b, 0xf7, 0x04, 0xf8, + 0xa3, 0x05, 0x0e, 0x44, 0xf7, 0x83, 0xf8, 0x32, 0x15, 0xce, 0xf7, 0xcf, + 0x37, 0x8b, 0x42, 0xfb, 0xef, 0x42, 0x5e, 0x7d, 0x48, 0xd3, 0xb7, 0x48, + 0xfb, 0xce, 0xdf, 0x8b, 0xd5, 0xf7, 0xef, 0xd4, 0xb5, 0x99, 0xce, 0x42, + 0x61, 0x05, 0x0e, 0xf7, 0xd2, 0x9e, 0x89, 0x15, 0xa5, 0x6f, 0xd9, 0xd2, + 0x05, 0xa9, 0x61, 0xc0, 0x75, 0xcf, 0x8b, 0xe6, 0x8b, 0xd9, 0xb3, 0xc2, + 0xd7, 0xb9, 0xcb, 0xac, 0xf7, 0x00, 0x8b, 0xe4, 0x8b, 0xa8, 0x85, 0xa4, + 0x7e, 0xa8, 0x08, 0xdc, 0xd5, 0x71, 0xa9, 0x3f, 0x46, 0x05, 0x6a, 0xb8, + 0x59, 0xa1, 0x44, 0x8b, 0x2f, 0x8b, 0x3b, 0x62, 0x57, 0x40, 0x5e, 0x4b, + 0x6a, 0xfb, 0x03, 0x8b, 0x37, 0x8b, 0x6c, 0x91, 0x70, 0x9a, 0x6b, 0x08, + 0x38, 0x3f, 0x05, 0xf7, 0x30, 0xf7, 0x23, 0x15, 0x86, 0x9a, 0x8a, 0x92, + 0x8b, 0x9c, 0x8b, 0xc9, 0x9b, 0xcb, 0xa7, 0xbe, 0xaf, 0xcf, 0xc3, 0xb0, + 0xcb, 0x8b, 0xb9, 0x8b, 0xaf, 0x79, 0x9e, 0x69, 0x08, 0xfb, 0xbb, 0xfb, + 0xa1, 0x05, 0xf7, 0xc9, 0xf7, 0x79, 0x15, 0x8f, 0x77, 0x8c, 0x80, 0x8b, + 0x80, 0x8b, 0x5b, 0x78, 0x3f, 0x73, 0x5e, 0x67, 0x49, 0x52, 0x64, 0x4b, + 0x8b, 0x5f, 0x8b, 0x67, 0x9c, 0x78, 0xaa, 0x08, 0xf7, 0xba, 0xf7, 0xa0, + 0x05, 0x0e, 0xf9, 0x1f, 0xf9, 0xda, 0xf7, 0x33, 0x15, 0x67, 0x46, 0x56, + 0x67, 0x49, 0x8b, 0x3d, 0x8b, 0x5a, 0xbb, 0x8b, 0xd5, 0x8b, 0x9f, 0x8d, + 0x97, 0x90, 0xa5, 0x08, 0xf8, 0x16, 0x8b, 0x8e, 0x9c, 0x05, 0x94, 0xbb, + 0x90, 0xb5, 0x8b, 0xa6, 0x8b, 0xeb, 0x38, 0xd6, 0xfb, 0x00, 0x8b, 0x39, + 0x8b, 0x2f, 0x5f, 0x60, 0x50, 0x6e, 0xce, 0x50, 0xaf, 0x37, 0x8b, 0x2d, + 0x8b, 0x3b, 0x61, 0x59, 0x40, 0x5e, 0x47, 0x6b, 0xfb, 0x00, 0x8b, 0x3a, + 0x08, 0x8b, 0x56, 0x9f, 0x58, 0xad, 0x68, 0xab, 0x6a, 0xb9, 0x7b, 0xc5, + 0x8b, 0xe2, 0x8b, 0xda, 0xb3, 0xbd, 0xce, 0x90, 0x7f, 0x8e, 0x85, 0x94, + 0x80, 0xb5, 0x55, 0xbb, 0x73, 0xd0, 0x8b, 0xf7, 0x0d, 0x8b, 0xf1, 0xd4, + 0xab, 0xf7, 0x01, 0x08, 0x37, 0x06, 0xfc, 0x67, 0xf7, 0xc3, 0x15, 0xd3, + 0xb7, 0x5b, 0x3b, 0x1f, 0x8b, 0x50, 0x7b, 0x47, 0x71, 0x5b, 0x66, 0x48, + 0x52, 0x65, 0x49, 0x8b, 0x08, 0x46, 0x60, 0xbc, 0xd9, 0xf7, 0x31, 0xe3, + 0xf7, 0x10, 0xf7, 0x02, 0x1f, 0xf7, 0x66, 0xfb, 0x30, 0x15, 0xa5, 0xe7, + 0xd6, 0xcb, 0xdd, 0x8b, 0xd0, 0x8b, 0xb8, 0x5b, 0x8b, 0x3f, 0x8b, 0x81, + 0x8a, 0x83, 0x89, 0x7d, 0x08, 0xfb, 0xba, 0x06, 0x0e, 0xf7, 0xd2, 0xf8, + 0x0c, 0xf7, 0xf1, 0x15, 0xa0, 0x8b, 0x95, 0x8b, 0x05, 0xdf, 0xb3, 0x6b, + 0x49, 0x20, 0x38, 0x35, 0x23, 0x1f, 0x88, 0x8b, 0x84, 0x8b, 0x82, 0x8c, + 0x08, 0x81, 0x8b, 0x7a, 0x3d, 0x05, 0x93, 0x88, 0x90, 0x8a, 0x98, 0x8b, + 0xed, 0x8b, 0xd6, 0xad, 0xc2, 0xd2, 0xb3, 0xbf, 0xa6, 0xd8, 0x8b, 0xce, + 0x8b, 0xc6, 0x70, 0xb4, 0x52, 0xa4, 0x08, 0xd8, 0xad, 0xb6, 0xcc, 0x8b, + 0xdb, 0x8b, 0xe6, 0x46, 0xc3, 0xfb, 0x05, 0x8b, 0x50, 0x8b, 0x5c, 0x7b, + 0x5d, 0x66, 0x5d, 0x66, 0x76, 0x68, 0x7d, 0x49, 0x08, 0xfb, 0x06, 0xfc, + 0xae, 0xdf, 0x8b, 0xf7, 0x06, 0xf8, 0xae, 0x05, 0x9b, 0xd5, 0xbe, 0xb3, + 0xd8, 0x8b, 0xc9, 0x8b, 0xb0, 0x6a, 0x8b, 0x55, 0x8b, 0x3e, 0x40, 0x51, + 0x29, 0x8c, 0x08, 0x79, 0x39, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0xa0, 0xf7, + 0x6f, 0x15, 0xa6, 0xfb, 0x6f, 0xf1, 0x8b, 0x26, 0xf9, 0x6d, 0xfb, 0x0c, + 0x8b, 0xfc, 0x33, 0xfd, 0x6d, 0xee, 0x8b, 0xf7, 0x0f, 0xf7, 0x6f, 0xf7, + 0xb1, 0x8b, 0x05, 0x81, 0xd9, 0x15, 0xfb, 0x7b, 0x8b, 0xf7, 0x53, 0xf7, + 0xe1, 0xb3, 0xfb, 0xe1, 0x05, 0x7e, 0xf8, 0xfd, 0x15, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0xa0, 0xf7, + 0x6f, 0x15, 0xa6, 0xfb, 0x6f, 0xf1, 0x8b, 0x26, 0xf9, 0x6d, 0xfb, 0x0c, + 0x8b, 0xfc, 0x33, 0xfd, 0x6d, 0xee, 0x8b, 0xf7, 0x0f, 0xf7, 0x6f, 0xf7, + 0xb1, 0x8b, 0x05, 0x81, 0xd9, 0x15, 0xfb, 0x7b, 0x8b, 0xf7, 0x53, 0xf7, + 0xe1, 0xb3, 0xfb, 0xe1, 0x05, 0xb4, 0xf9, 0x16, 0x15, 0xfb, 0x14, 0xfb, + 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x0e, + 0xf8, 0x0a, 0xf8, 0xa0, 0xf7, 0x6f, 0x15, 0xa6, 0xfb, 0x6f, 0xf1, 0x8b, + 0x26, 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfc, 0x33, 0xfd, 0x6d, 0xee, 0x8b, + 0xf7, 0x0f, 0xf7, 0x6f, 0xf7, 0xb1, 0x8b, 0x05, 0x81, 0xd9, 0x15, 0xfb, + 0x7b, 0x8b, 0xf7, 0x53, 0xf7, 0xe1, 0xb3, 0xfb, 0xe1, 0x05, 0x6c, 0xf9, + 0x16, 0x15, 0x21, 0x8b, 0xf7, 0x10, 0xfb, 0x28, 0xc1, 0x8b, 0x43, 0xf7, + 0x28, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0xa0, 0xf7, 0x6f, 0x15, 0xa6, 0xfb, + 0x6f, 0xf1, 0x8b, 0x26, 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfc, 0x33, 0xfd, + 0x6d, 0xee, 0x8b, 0xf7, 0x0f, 0xf7, 0x6f, 0xf7, 0xb1, 0x8b, 0x05, 0x81, + 0xd9, 0x15, 0xfb, 0x7b, 0x8b, 0xf7, 0x53, 0xf7, 0xe1, 0xb3, 0xfb, 0xe1, + 0x05, 0x6f, 0xf9, 0x17, 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, 0xf2, + 0xee, 0xc3, 0x28, 0xcb, 0x8b, 0x4a, 0xf7, 0x2a, 0x2d, 0x8b, 0x05, 0x0e, + 0xf8, 0x0a, 0xf8, 0xa0, 0xf7, 0x6f, 0x15, 0xa6, 0xfb, 0x6f, 0xf1, 0x8b, + 0x26, 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfc, 0x33, 0xfd, 0x6d, 0xee, 0x8b, + 0xf7, 0x0f, 0xf7, 0x6f, 0x05, 0xf7, 0xb1, 0x06, 0x81, 0xd9, 0x15, 0xfb, + 0x7b, 0x8b, 0xf7, 0x53, 0xf7, 0xe1, 0xb3, 0xfb, 0xe1, 0x05, 0xf7, 0x05, + 0xf9, 0x01, 0x15, 0x79, 0x6e, 0x81, 0x83, 0x77, 0x8b, 0x81, 0x8b, 0x70, + 0x91, 0x71, 0x94, 0x08, 0x64, 0x98, 0x7a, 0x8f, 0x7a, 0x8b, 0x72, 0x8b, + 0x6c, 0x7c, 0x7b, 0x76, 0x7f, 0x7c, 0x83, 0x7a, 0x7f, 0x68, 0x08, 0xc0, + 0x06, 0x8e, 0x8f, 0x8d, 0x8e, 0x8d, 0x8d, 0x97, 0x9d, 0x97, 0x91, 0x9e, + 0x8b, 0x91, 0x8b, 0x95, 0x89, 0x96, 0x87, 0x08, 0xcb, 0x75, 0x9c, 0x87, + 0xa1, 0x8b, 0xb8, 0x8b, 0xb5, 0xb5, 0xa0, 0xcc, 0x08, 0x56, 0x06, 0x0e, + 0xf8, 0x0a, 0xf8, 0xa0, 0xf7, 0x6f, 0x15, 0xa6, 0xfb, 0x6f, 0xf1, 0x8b, + 0x26, 0xf9, 0x6d, 0xfb, 0x0c, 0x8b, 0xfc, 0x33, 0xfd, 0x6d, 0xee, 0x8b, + 0xf7, 0x0f, 0xf7, 0x6f, 0xf7, 0xb1, 0x8b, 0x05, 0x81, 0xd9, 0x15, 0xfb, + 0x7b, 0x8b, 0xf7, 0x53, 0xf7, 0xe1, 0xb3, 0xfb, 0xe1, 0x05, 0x9e, 0xf9, + 0x24, 0x15, 0x55, 0x55, 0x57, 0x56, 0x64, 0xaa, 0x6c, 0xb3, 0xc4, 0xbf, + 0xbf, 0xc3, 0xb1, 0x6c, 0xa8, 0x62, 0x1f, 0x84, 0x5f, 0x15, 0x9e, 0x9a, + 0x7c, 0x77, 0x71, 0x70, 0x71, 0x70, 0x77, 0x7c, 0x99, 0xa0, 0xa5, 0xa6, + 0xa5, 0xa7, 0x1f, 0x0e, 0xf8, 0x41, 0xf8, 0x04, 0x74, 0x15, 0xf7, 0x42, + 0x8d, 0xf7, 0x06, 0xe4, 0xda, 0xf7, 0x5a, 0x08, 0x29, 0x06, 0x72, 0x52, + 0x7b, 0x6d, 0x79, 0x73, 0x61, 0x4f, 0x3f, 0x66, 0x3c, 0x8b, 0x23, 0x8b, + 0x46, 0xdc, 0x8b, 0xf7, 0x0d, 0x8b, 0xe6, 0xa9, 0xef, 0xbe, 0xd7, 0xc8, + 0xe5, 0xd4, 0xb6, 0xe7, 0x8b, 0xf0, 0x8b, 0xbd, 0x5a, 0x93, 0xfb, 0x00, + 0x08, 0xeb, 0x06, 0x88, 0xc6, 0x81, 0xb1, 0x78, 0xad, 0x62, 0xd1, 0x44, + 0xb0, 0x2d, 0x8b, 0xfb, 0x09, 0x8b, 0x2a, 0x5c, 0x3d, 0x2d, 0x3c, 0x2c, + 0x5a, 0xfb, 0x1e, 0x8b, 0xfb, 0x11, 0x8b, 0x35, 0xa9, 0x40, 0xc2, 0x5a, + 0xae, 0x6c, 0xa8, 0x7f, 0xce, 0x81, 0x08, 0x65, 0x44, 0x98, 0x85, 0x92, + 0x8c, 0x05, 0x9a, 0x8e, 0x8b, 0x8b, 0x90, 0x8b, 0x08, 0x9c, 0x99, 0x81, + 0x7f, 0x6b, 0x71, 0x74, 0x66, 0x1f, 0x6f, 0x8b, 0x71, 0x93, 0x63, 0xa0, + 0x08, 0x6f, 0x65, 0x05, 0xbe, 0x71, 0xa8, 0x83, 0xb1, 0x8b, 0x08, 0xdf, + 0xc8, 0xb9, 0xca, 0xa7, 0x6d, 0xa2, 0x66, 0x1f, 0x86, 0x8b, 0x88, 0x8b, + 0x7e, 0x89, 0x08, 0x9c, 0xac, 0x05, 0x0e, 0xf8, 0x41, 0xf7, 0x35, 0xf7, + 0xe9, 0x15, 0x43, 0xfb, 0xe9, 0xf7, 0xae, 0x8b, 0x05, 0xf7, 0x00, 0x8b, + 0xe6, 0xb8, 0xd4, 0xe4, 0xcf, 0xde, 0xbb, 0xf7, 0x26, 0x8b, 0xf7, 0x11, + 0x8b, 0xd4, 0x6d, 0xd5, 0x5c, 0xb5, 0x65, 0xad, 0x56, 0x9d, 0x4a, 0x8b, + 0x08, 0xfb, 0xae, 0x8b, 0x47, 0xfb, 0xd5, 0x45, 0x8b, 0x7e, 0x48, 0xcf, + 0x8b, 0x05, 0xe9, 0x16, 0xf7, 0x3b, 0x8b, 0x99, 0xce, 0xfb, 0x3a, 0x8b, + 0xbe, 0xf7, 0x83, 0xf7, 0x3f, 0x8b, 0x05, 0xf6, 0xcb, 0x4d, 0x22, 0x1f, + 0x8b, 0x30, 0x6b, 0xfb, 0x0d, 0x63, 0x4c, 0x57, 0x3b, 0x3f, 0x60, 0x30, + 0x8b, 0x08, 0xfb, 0x40, 0x8b, 0xc2, 0xf7, 0x97, 0x05, 0x0e, 0xf8, 0x0a, + 0xf8, 0x8d, 0xfa, 0x26, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, + 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, + 0xf2, 0x05, 0xfc, 0x2f, 0xfc, 0xda, 0x15, 0xf8, 0x1f, 0x8b, 0x9d, 0xdd, + 0xfc, 0x20, 0x8b, 0xbd, 0xf7, 0x7d, 0xf8, 0x30, 0x8b, 0x9c, 0xdd, 0xfc, + 0x8e, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0x9f, 0x8b, 0x9c, 0xdd, 0xfc, + 0x41, 0x8b, 0xc1, 0xf7, 0x8e, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0xda, 0xfa, + 0x3f, 0x15, 0xfb, 0x14, 0xfb, 0x28, 0xc8, 0x8b, 0xf7, 0x47, 0xf7, 0x28, + 0xfb, 0x04, 0x8b, 0x05, 0xfb, 0xdb, 0xfc, 0xf3, 0x15, 0xf8, 0x1f, 0x8b, + 0x9d, 0xdd, 0xfc, 0x20, 0x8b, 0xbd, 0xf7, 0x7d, 0xf8, 0x30, 0x8b, 0x9c, + 0xdd, 0xfc, 0x8e, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0x9f, 0x8b, 0x9c, + 0xdd, 0xfc, 0x41, 0x8b, 0xc1, 0xf7, 0x8e, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, + 0x84, 0xfa, 0x3f, 0x15, 0x20, 0x8b, 0xf7, 0x11, 0xfb, 0x28, 0xc0, 0x8b, + 0x44, 0xf7, 0x28, 0x05, 0xfb, 0x85, 0xfc, 0xf3, 0x15, 0xf8, 0x1f, 0x8b, + 0x9d, 0xdd, 0xfc, 0x20, 0x8b, 0xbd, 0xf7, 0x7d, 0xf8, 0x30, 0x8b, 0x9c, + 0xdd, 0xfc, 0x8e, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xf8, 0x9f, 0x8b, 0x9c, + 0xdd, 0xfc, 0x41, 0x8b, 0xc1, 0xf7, 0x8e, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, + 0x83, 0xfa, 0x40, 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, 0xf3, 0xee, + 0xc3, 0x28, 0xca, 0x8b, 0x4b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0xfb, 0x84, + 0xfc, 0xf4, 0x15, 0xf8, 0x1f, 0x8b, 0x9d, 0xdd, 0xfc, 0x20, 0x8b, 0xbd, + 0xf7, 0x7d, 0xf8, 0x30, 0x8b, 0x9c, 0xdd, 0xfc, 0x8e, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0xf8, 0x9f, 0x8b, 0x9c, 0xdd, 0xfc, 0x41, 0x8b, 0xc1, 0xf7, + 0x8e, 0x05, 0x0e, 0x7c, 0xf7, 0xf1, 0xf9, 0x6d, 0x15, 0x2d, 0x8b, 0xfb, + 0x2f, 0xfd, 0x6d, 0xe9, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x60, 0xf7, + 0x46, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0xf7, + 0x35, 0x16, 0x23, 0x8b, 0x75, 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0x0e, + 0x7c, 0xf7, 0xf1, 0xf9, 0x6d, 0x15, 0x2d, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, + 0xe9, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x9d, 0xf7, 0x66, 0x15, 0xfb, + 0x14, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, + 0x05, 0x0e, 0x7c, 0xf7, 0xf1, 0xf9, 0x6d, 0x15, 0x2d, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0xe9, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x60, 0xf7, 0x66, + 0x15, 0x21, 0x8b, 0xf7, 0x11, 0xfb, 0x28, 0xc0, 0x8b, 0x43, 0xf7, 0x28, + 0x05, 0x0e, 0x7c, 0xf7, 0xf1, 0xf9, 0x6d, 0x15, 0x2d, 0x8b, 0xfb, 0x2f, + 0xfd, 0x6d, 0xe9, 0x8b, 0xf7, 0x2f, 0xf9, 0x6d, 0x05, 0x55, 0xf7, 0x67, + 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, 0xf3, 0xee, 0xc3, 0x28, 0xca, + 0x8b, 0x4b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf9, 0xb5, + 0xf9, 0x6d, 0x15, 0x32, 0x8b, 0xfb, 0x13, 0xfc, 0xea, 0xfb, 0x8e, 0xf8, + 0xea, 0x23, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xe4, 0x8b, 0xf7, 0x12, 0xf8, + 0xe3, 0xf7, 0x8d, 0xfc, 0xe3, 0xf5, 0x8b, 0x05, 0xf7, 0x2f, 0xf9, 0x6d, + 0x05, 0xfb, 0x18, 0xf7, 0x51, 0x15, 0x79, 0x6e, 0x81, 0x83, 0x77, 0x8b, + 0x81, 0x8b, 0x70, 0x91, 0x71, 0x94, 0x08, 0x64, 0x98, 0x7b, 0x8f, 0x79, + 0x8b, 0x72, 0x8b, 0x6d, 0x7c, 0x7a, 0x76, 0x7f, 0x7c, 0x83, 0x7a, 0x7f, + 0x68, 0x08, 0xc1, 0x06, 0x8e, 0x8f, 0x8d, 0x8e, 0x8c, 0x8d, 0x97, 0x9d, + 0x97, 0x91, 0x9e, 0x8b, 0x91, 0x8b, 0x96, 0x89, 0x95, 0x87, 0x08, 0xcb, + 0x75, 0x9d, 0x87, 0xa0, 0x8b, 0xb8, 0x8b, 0xb5, 0xb5, 0xa0, 0xcc, 0x08, + 0x56, 0x06, 0x0e, 0xf8, 0x79, 0xf8, 0xba, 0xfa, 0x26, 0x15, 0x23, 0x8b, + 0x75, 0x24, 0xf2, 0x8b, 0xa2, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, + 0x75, 0x24, 0xf2, 0x8b, 0xa2, 0xf2, 0x05, 0xfb, 0x42, 0xfb, 0x41, 0x15, + 0xfb, 0x05, 0x8b, 0x2a, 0x61, 0x3a, 0x36, 0x32, 0x2f, 0x56, 0xfb, 0x18, + 0x8b, 0xfb, 0x13, 0x8b, 0x35, 0xa6, 0x3e, 0xb9, 0x5d, 0xbb, 0x5b, 0xdc, + 0x6e, 0xe0, 0x8b, 0xe9, 0x8b, 0xdd, 0xa5, 0xcf, 0xbe, 0xf7, 0x07, 0xe1, + 0xd9, 0xf7, 0x3a, 0x8b, 0xf7, 0x32, 0x08, 0x8b, 0xda, 0x70, 0xd7, 0x5e, + 0xb8, 0x5a, 0xbc, 0x3c, 0xa7, 0x30, 0x8b, 0x08, 0x7f, 0x3a, 0x15, 0xcf, + 0x8b, 0xcb, 0x6f, 0xad, 0x5f, 0xa6, 0x68, 0x99, 0x5b, 0x8b, 0x50, 0x8b, + 0x30, 0x6b, 0x29, 0x56, 0x43, 0x51, 0x3a, 0x33, 0x5d, 0x2a, 0x8b, 0x4a, + 0x8b, 0x4c, 0xa7, 0x68, 0xb7, 0x70, 0xad, 0x7d, 0xbc, 0x8b, 0xc5, 0x08, + 0x8b, 0xe7, 0xaa, 0xec, 0xc0, 0xd4, 0xc5, 0xdb, 0xe4, 0xba, 0xe9, 0x8b, + 0x08, 0x0e, 0xf8, 0x79, 0xf9, 0x01, 0xfa, 0x3f, 0x15, 0xfb, 0x14, 0xfb, + 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x37, + 0xfb, 0x5a, 0x15, 0xfb, 0x05, 0x8b, 0x2a, 0x61, 0x3a, 0x36, 0x32, 0x2f, + 0x56, 0xfb, 0x18, 0x8b, 0xfb, 0x13, 0x8b, 0x35, 0xa6, 0x3e, 0xb9, 0x5d, + 0xbb, 0x5b, 0xdc, 0x6e, 0xe0, 0x8b, 0xe9, 0x8b, 0xdd, 0xa5, 0xcf, 0xbe, + 0xf7, 0x07, 0xe1, 0xd9, 0xf7, 0x3a, 0x8b, 0xf7, 0x32, 0x08, 0x8b, 0xda, + 0x70, 0xd7, 0x5e, 0xb8, 0x5a, 0xbc, 0x3c, 0xa7, 0x30, 0x8b, 0x08, 0x7f, + 0x3a, 0x15, 0xcf, 0x8b, 0xcb, 0x6f, 0xad, 0x5f, 0xa6, 0x68, 0x99, 0x5b, + 0x8b, 0x50, 0x8b, 0x30, 0x6b, 0x29, 0x56, 0x43, 0x51, 0x3a, 0x33, 0x5d, + 0x2a, 0x8b, 0x4a, 0x8b, 0x4c, 0xa7, 0x68, 0xb7, 0x70, 0xad, 0x7d, 0xbc, + 0x8b, 0xc5, 0x08, 0x8b, 0xe7, 0xaa, 0xec, 0xc0, 0xd4, 0xc5, 0xdb, 0xe4, + 0xba, 0xe9, 0x8b, 0x08, 0x0e, 0xf8, 0x79, 0xf8, 0xae, 0xfa, 0x3f, 0x15, + 0x21, 0x8b, 0xf7, 0x10, 0xfb, 0x28, 0xc1, 0x8b, 0x43, 0xf7, 0x28, 0x05, + 0x8a, 0xfb, 0x5a, 0x15, 0xfb, 0x05, 0x8b, 0x2a, 0x61, 0x3a, 0x36, 0x32, + 0x2f, 0x56, 0xfb, 0x18, 0x8b, 0xfb, 0x13, 0x8b, 0x35, 0xa6, 0x3e, 0xb9, + 0x5d, 0xbb, 0x5b, 0xdc, 0x6e, 0xe0, 0x8b, 0xe9, 0x8b, 0xdd, 0xa5, 0xcf, + 0xbe, 0xf7, 0x07, 0xe1, 0xd9, 0xf7, 0x3a, 0x8b, 0xf7, 0x32, 0x08, 0x8b, + 0xda, 0x70, 0xd7, 0x5e, 0xb8, 0x5a, 0xbc, 0x3c, 0xa7, 0x30, 0x8b, 0x08, + 0x7f, 0x3a, 0x15, 0xcf, 0x8b, 0xcb, 0x6f, 0xad, 0x5f, 0xa6, 0x68, 0x99, + 0x5b, 0x8b, 0x50, 0x8b, 0x30, 0x6b, 0x29, 0x56, 0x43, 0x51, 0x3a, 0x33, + 0x5d, 0x2a, 0x8b, 0x4a, 0x8b, 0x4c, 0xa7, 0x68, 0xb7, 0x70, 0xad, 0x7d, + 0xbc, 0x8b, 0xc5, 0x08, 0x8b, 0xe7, 0xaa, 0xec, 0xc0, 0xd4, 0xc5, 0xdb, + 0xe4, 0xba, 0xe9, 0x8b, 0x08, 0x0e, 0xf8, 0x79, 0xf8, 0xae, 0xfa, 0x40, + 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, 0xf2, 0xee, 0xc3, 0x28, 0xcb, + 0x8b, 0x4a, 0xf7, 0x2a, 0x2d, 0x8b, 0x05, 0x8a, 0xfb, 0x5b, 0x15, 0xfb, + 0x05, 0x8b, 0x2a, 0x61, 0x3a, 0x36, 0x32, 0x2f, 0x56, 0xfb, 0x18, 0x8b, + 0xfb, 0x13, 0x8b, 0x35, 0xa6, 0x3e, 0xb9, 0x5d, 0xbb, 0x5b, 0xdc, 0x6e, + 0xe0, 0x8b, 0xe9, 0x8b, 0xdd, 0xa5, 0xcf, 0xbe, 0xf7, 0x07, 0xe1, 0xd9, + 0xf7, 0x3a, 0x8b, 0xf7, 0x32, 0x08, 0x8b, 0xda, 0x70, 0xd7, 0x5e, 0xb8, + 0x5a, 0xbc, 0x3c, 0xa7, 0x30, 0x8b, 0x08, 0x7f, 0x3a, 0x15, 0xcf, 0x8b, + 0xcb, 0x6f, 0xad, 0x5f, 0xa6, 0x68, 0x99, 0x5b, 0x8b, 0x50, 0x8b, 0x30, + 0x6b, 0x29, 0x56, 0x43, 0x51, 0x3a, 0x33, 0x5d, 0x2a, 0x8b, 0x4a, 0x8b, + 0x4c, 0xa7, 0x68, 0xb7, 0x70, 0xad, 0x7d, 0xbc, 0x8b, 0xc5, 0x08, 0x8b, + 0xe7, 0xaa, 0xec, 0xc0, 0xd4, 0xc5, 0xdb, 0xe4, 0xba, 0xe9, 0x8b, 0x08, + 0x0e, 0xf8, 0x79, 0xf8, 0xad, 0xf9, 0x79, 0x15, 0xfb, 0x05, 0x8b, 0x2a, + 0x61, 0x3a, 0x36, 0x32, 0x2f, 0x56, 0xfb, 0x18, 0x8b, 0xfb, 0x13, 0x8b, + 0x35, 0xa6, 0x3e, 0xb9, 0x5d, 0xbb, 0x5b, 0xdc, 0x6e, 0xe0, 0x8b, 0xe9, + 0x8b, 0xdd, 0xa5, 0xcf, 0xbe, 0xf7, 0x07, 0xe1, 0xd9, 0xf7, 0x3a, 0x8b, + 0xf7, 0x32, 0x08, 0x8b, 0xda, 0x70, 0xd7, 0x5e, 0xb8, 0x08, 0x5a, 0xbc, + 0x3c, 0xa7, 0x30, 0x8b, 0x08, 0x7f, 0x3a, 0x15, 0xcf, 0x8b, 0xcb, 0x6f, + 0xad, 0x5f, 0xa6, 0x68, 0x99, 0x5b, 0x8b, 0x50, 0x8b, 0x30, 0x6b, 0x29, + 0x56, 0x43, 0x51, 0x3a, 0x33, 0x5d, 0x2a, 0x8b, 0x4a, 0x8b, 0x4c, 0xa7, + 0x68, 0xb7, 0x70, 0xad, 0x7d, 0xbc, 0x8b, 0xc5, 0x08, 0x8b, 0xe7, 0xaa, + 0xec, 0xc0, 0xd4, 0xc5, 0xdb, 0xe4, 0xba, 0xe9, 0x8b, 0x08, 0xf7, 0x3c, + 0xf7, 0x96, 0x15, 0x79, 0x6e, 0x81, 0x83, 0x78, 0x8b, 0x80, 0x8b, 0x70, + 0x91, 0x71, 0x94, 0x08, 0x64, 0x98, 0x7b, 0x8f, 0x7a, 0x8b, 0x71, 0x8b, + 0x6d, 0x7c, 0x7a, 0x76, 0x80, 0x7c, 0x83, 0x7b, 0x7f, 0x67, 0x08, 0xc0, + 0x06, 0x8e, 0x8f, 0x8d, 0x8e, 0x8c, 0x8d, 0x98, 0x9d, 0x96, 0x91, 0x9f, + 0x8b, 0x90, 0x8b, 0x96, 0x89, 0x95, 0x87, 0x08, 0xcc, 0x75, 0x9c, 0x87, + 0xa1, 0x8b, 0xb7, 0x8b, 0xb6, 0xb5, 0xa0, 0xcc, 0x08, 0x55, 0x06, 0x0e, + 0xf8, 0x0a, 0xf8, 0xb7, 0xf9, 0xab, 0x15, 0xf7, 0x14, 0xf7, 0x28, 0x4b, + 0x8b, 0x23, 0x29, 0x53, 0xed, 0x4c, 0x8b, 0xcb, 0xfb, 0x28, 0x05, 0xea, + 0x06, 0xf7, 0x33, 0xfb, 0xa8, 0x15, 0x91, 0xa7, 0x8d, 0x97, 0x8b, 0x9b, + 0x8b, 0xb6, 0x76, 0xb9, 0x6a, 0xa8, 0x62, 0xaf, 0x56, 0x9b, 0x3d, 0x8b, + 0x24, 0x8b, 0x3a, 0x6e, 0x55, 0x53, 0x62, 0x61, 0x6c, 0x44, 0x8b, 0x58, + 0x8b, 0x4c, 0xb7, 0x56, 0xce, 0x78, 0x08, 0xf7, 0x3f, 0x5b, 0x05, 0xdb, + 0x74, 0xac, 0x6e, 0x8b, 0x5b, 0x8b, 0x6d, 0x78, 0x64, 0x6f, 0x71, 0x62, + 0x66, 0x50, 0x78, 0x3b, 0x8b, 0xfb, 0x05, 0x8b, 0x57, 0xb5, 0x8b, 0xe6, + 0x8b, 0x98, 0x8c, 0x94, 0x8e, 0x9e, 0x08, 0x34, 0x06, 0x84, 0x71, 0x89, + 0x7b, 0x8b, 0x76, 0x8b, 0xfb, 0x0c, 0xe5, 0x43, 0xf7, 0x2b, 0x8b, 0xf4, + 0x8b, 0xe3, 0xa8, 0xc6, 0xc2, 0xbe, 0xba, 0xaf, 0xd4, 0x8b, 0xc3, 0x8b, + 0xa5, 0x82, 0xa7, 0x7c, 0xa3, 0x75, 0xae, 0x6e, 0x9f, 0x5c, 0x98, 0x08, + 0xfb, 0x40, 0xbc, 0x05, 0x3e, 0xa1, 0x73, 0x9f, 0x8b, 0xb7, 0x8b, 0xae, + 0x9a, 0xaa, 0xa8, 0xa6, 0xb0, 0xac, 0xbc, 0x9b, 0xcd, 0x8b, 0xc3, 0x8b, + 0xb5, 0x80, 0xa1, 0x77, 0x9e, 0x7a, 0x98, 0x6a, 0x8b, 0x6f, 0x8b, 0x83, + 0x8a, 0x83, 0x88, 0x77, 0x08, 0xe3, 0x06, 0x0e, 0xf8, 0x41, 0xf8, 0xa8, + 0xfa, 0x26, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf2, 0x8b, 0xa2, 0xf2, 0x05, + 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, 0x24, 0xf2, 0x8b, 0xa2, 0xf2, 0x05, + 0x98, 0xfb, 0x4d, 0x15, 0xfb, 0x01, 0xfc, 0x94, 0x05, 0x76, 0x28, 0x39, + 0x4f, 0xfb, 0x05, 0x8b, 0x2b, 0x8b, 0x4a, 0xb9, 0x8b, 0xd1, 0x8b, 0x98, + 0x8d, 0x9a, 0x8e, 0x9a, 0x08, 0xf7, 0x01, 0xf8, 0x94, 0x2d, 0x8b, 0x25, + 0xfc, 0x72, 0x05, 0x84, 0x69, 0x84, 0x5d, 0x8b, 0x7b, 0x8b, 0x62, 0xa2, + 0x59, 0xab, 0x6e, 0xb4, 0x66, 0xcd, 0x76, 0xd8, 0x8b, 0xf7, 0x3c, 0x8b, + 0xf7, 0x15, 0xe9, 0xaa, 0xf7, 0x26, 0x08, 0xf7, 0x01, 0xf8, 0x94, 0x2d, + 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf8, 0xe3, 0xfa, 0x3f, 0x15, 0xfb, 0x14, + 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, + 0xf7, 0x07, 0xfb, 0x66, 0x15, 0xfb, 0x01, 0xfc, 0x94, 0x05, 0x76, 0x28, + 0x39, 0x4f, 0xfb, 0x05, 0x8b, 0x2b, 0x8b, 0x4a, 0xb9, 0x8b, 0xd1, 0x8b, + 0x98, 0x8d, 0x9a, 0x8e, 0x9a, 0x08, 0xf7, 0x01, 0xf8, 0x94, 0x2d, 0x8b, + 0x25, 0xfc, 0x72, 0x05, 0x84, 0x69, 0x84, 0x5d, 0x8b, 0x7b, 0x8b, 0x62, + 0xa2, 0x59, 0xab, 0x6e, 0xb4, 0x66, 0xcd, 0x76, 0xd8, 0x8b, 0xf7, 0x3c, + 0x8b, 0xf7, 0x15, 0xe9, 0xaa, 0xf7, 0x26, 0x08, 0xf7, 0x01, 0xf8, 0x94, + 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf8, 0x96, 0xfa, 0x3f, 0x15, 0x21, + 0x8b, 0xf7, 0x10, 0xfb, 0x28, 0xc1, 0x8b, 0x43, 0xf7, 0x28, 0x05, 0xf7, + 0x54, 0xfb, 0x66, 0x15, 0xfb, 0x01, 0xfc, 0x94, 0x05, 0x76, 0x28, 0x39, + 0x4f, 0xfb, 0x05, 0x8b, 0x2b, 0x8b, 0x4a, 0xb9, 0x8b, 0xd1, 0x8b, 0x98, + 0x8d, 0x9a, 0x8e, 0x9a, 0x08, 0xf7, 0x01, 0xf8, 0x94, 0x2d, 0x8b, 0x25, + 0xfc, 0x72, 0x05, 0x84, 0x69, 0x84, 0x5d, 0x8b, 0x7b, 0x8b, 0x62, 0xa2, + 0x59, 0xab, 0x6e, 0xb4, 0x66, 0xcd, 0x76, 0xd8, 0x8b, 0xf7, 0x3c, 0x8b, + 0xf7, 0x15, 0xe9, 0xaa, 0xf7, 0x26, 0x08, 0xf7, 0x01, 0xf8, 0x94, 0x2d, + 0x8b, 0x05, 0x0e, 0xf8, 0x41, 0xf8, 0x99, 0xfa, 0x40, 0x15, 0xfb, 0x14, + 0xfb, 0x2a, 0xcb, 0x8b, 0xf2, 0xee, 0xc3, 0x28, 0xcb, 0x8b, 0x4a, 0xf7, + 0x2a, 0x2d, 0x8b, 0x05, 0xf7, 0x51, 0xfb, 0x67, 0x15, 0xfb, 0x01, 0xfc, + 0x94, 0x05, 0x76, 0x28, 0x39, 0x4f, 0xfb, 0x05, 0x8b, 0x2b, 0x8b, 0x4a, + 0xb9, 0x8b, 0xd1, 0x8b, 0x98, 0x8d, 0x9a, 0x8e, 0x9a, 0x08, 0xf7, 0x01, + 0xf8, 0x94, 0x2d, 0x8b, 0x25, 0xfc, 0x72, 0x05, 0x84, 0x69, 0x84, 0x5d, + 0x8b, 0x7b, 0x8b, 0x62, 0xa2, 0x59, 0xab, 0x6e, 0xb4, 0x66, 0xcd, 0x76, + 0xd8, 0x8b, 0xf7, 0x3c, 0x8b, 0xf7, 0x15, 0xe9, 0xaa, 0xf7, 0x26, 0x08, + 0xf7, 0x01, 0xf8, 0x94, 0x2d, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf8, 0xc8, + 0xfa, 0x3f, 0x15, 0xfb, 0x14, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, + 0x28, 0xfb, 0x04, 0x8b, 0x05, 0xfb, 0x08, 0xfd, 0x21, 0x15, 0xf8, 0x04, + 0xf8, 0x4f, 0xfb, 0x03, 0x8b, 0xfb, 0xb5, 0xfb, 0xf9, 0xfb, 0x1c, 0xf7, + 0xf9, 0xfb, 0x04, 0x8b, 0xf7, 0x4e, 0xfc, 0x4f, 0x4e, 0xfb, 0xb2, 0xe9, + 0x8b, 0xc8, 0xf7, 0xb2, 0x05, 0x0e, 0xf7, 0xd2, 0xf9, 0x75, 0xf9, 0x6d, + 0x15, 0xfc, 0xa1, 0x8b, 0x7a, 0x39, 0xf8, 0x2a, 0x8b, 0xfc, 0xbf, 0xfc, + 0xc7, 0x79, 0x37, 0xf8, 0xc0, 0x8b, 0x9c, 0xdd, 0xfc, 0x4a, 0x8b, 0xf8, + 0xc0, 0xf8, 0xc7, 0x9d, 0xdf, 0x05, 0xfb, 0x62, 0xc9, 0x15, 0xf7, 0x14, + 0xf7, 0x28, 0x4b, 0x8b, 0x23, 0x29, 0x53, 0xed, 0x4c, 0x8b, 0xcb, 0xfb, + 0x28, 0xea, 0x8b, 0x05, 0x0e, 0xf8, 0x0a, 0xf7, 0x76, 0xf7, 0x53, 0x15, + 0xf7, 0x78, 0x06, 0xca, 0x8b, 0xba, 0x9b, 0xb8, 0xaf, 0xca, 0xbd, 0xaf, + 0xd7, 0x8b, 0xdc, 0x08, 0xf5, 0x4c, 0xc2, 0xfb, 0x0e, 0x1e, 0xfb, 0x64, + 0x8b, 0xa4, 0xf7, 0x0a, 0x2d, 0x8b, 0xfb, 0x2f, 0xfd, 0x6d, 0xe9, 0x8b, + 0xb4, 0xf7, 0x53, 0x05, 0x9c, 0xdd, 0x15, 0xc1, 0xf7, 0x94, 0xf7, 0x57, + 0x8b, 0x05, 0xd9, 0xb5, 0x69, 0x4c, 0x1f, 0x8b, 0x68, 0x7f, 0x6a, 0x74, + 0x6d, 0x6a, 0x61, 0x60, 0x78, 0x4b, 0x8b, 0x08, 0xfb, 0x56, 0x06, 0x0e, + 0xf8, 0x0a, 0xf8, 0x54, 0xf7, 0xb2, 0x15, 0xf8, 0x04, 0xf8, 0x4f, 0xfb, + 0x03, 0x8b, 0xfb, 0xb5, 0xfb, 0xf9, 0xfb, 0x1c, 0xf7, 0xf9, 0xfb, 0x04, + 0x8b, 0xf7, 0x4e, 0xfc, 0x4f, 0x4e, 0xfb, 0xb2, 0xe9, 0x8b, 0xc8, 0xf7, + 0xb2, 0x05, 0xc3, 0xf9, 0x08, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf2, 0x8b, + 0xa2, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, 0x24, 0xf2, 0x8b, + 0xa2, 0xf2, 0x05, 0x0e, 0xf8, 0x27, 0xf9, 0x5f, 0x15, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0x7f, 0xfd, 0x2c, 0x15, 0x82, 0x89, + 0x87, 0x8b, 0x87, 0x8b, 0x71, 0x8b, 0x7f, 0x94, 0x8b, 0x9f, 0x8b, 0x8e, + 0x8b, 0x8f, 0x8c, 0x8e, 0x08, 0xcb, 0xf7, 0xc1, 0x05, 0x91, 0xa6, 0x8b, + 0x8b, 0x8b, 0x95, 0x8b, 0xcf, 0x46, 0xb8, 0x22, 0x8b, 0xfb, 0x1f, 0x8b, + 0x36, 0x50, 0x78, 0xfb, 0x03, 0x08, 0xdf, 0x06, 0x94, 0xa7, 0x92, 0x99, + 0x99, 0x99, 0xa1, 0xa2, 0xb5, 0x99, 0xb6, 0x8b, 0xc7, 0x8b, 0xb9, 0x70, + 0x8b, 0x66, 0x8b, 0x86, 0x8a, 0x85, 0x8a, 0x83, 0x08, 0x88, 0x79, 0x05, + 0x82, 0x62, 0x78, 0x80, 0x42, 0x84, 0xfb, 0x1a, 0x7f, 0x61, 0x81, 0x5a, + 0x6c, 0x57, 0x6a, 0x6d, 0x56, 0x8b, 0x51, 0x8b, 0x3b, 0xc1, 0x5b, 0xe5, + 0x8b, 0xae, 0x8b, 0xb5, 0x92, 0xaf, 0x98, 0xab, 0x96, 0x9a, 0x95, 0xb4, + 0xaf, 0x08, 0x8b, 0x84, 0x8b, 0x87, 0x05, 0x62, 0xa7, 0x72, 0xbb, 0x1e, + 0x96, 0x8b, 0x8f, 0x8b, 0xa3, 0x91, 0x8d, 0x8c, 0x91, 0x8c, 0x91, 0x8c, + 0x08, 0x98, 0xcc, 0x05, 0xfb, 0x0d, 0xf7, 0x05, 0x15, 0x7e, 0x4d, 0x33, + 0x56, 0x33, 0x8b, 0x52, 0x8b, 0x6b, 0xa3, 0x8b, 0xb5, 0x8b, 0xac, 0x9e, + 0xac, 0xa9, 0x9d, 0xa4, 0x9a, 0xa8, 0x93, 0xbc, 0x92, 0xe9, 0x98, 0x93, + 0x8c, 0xb7, 0x9a, 0x08, 0x77, 0x2d, 0x05, 0x0e, 0xf8, 0x5e, 0xf9, 0x78, + 0x15, 0xfb, 0x14, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x28, 0xfb, + 0x04, 0x8b, 0x05, 0xe9, 0xfd, 0x45, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x87, + 0x8b, 0x71, 0x8b, 0x7f, 0x94, 0x8b, 0x9f, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, + 0x8e, 0x08, 0xcb, 0xf7, 0xc1, 0x05, 0x91, 0xa6, 0x8b, 0x8b, 0x8b, 0x95, + 0x8b, 0xcf, 0x46, 0xb8, 0x22, 0x8b, 0xfb, 0x1f, 0x8b, 0x36, 0x50, 0x78, + 0xfb, 0x03, 0x08, 0xdf, 0x06, 0x94, 0xa7, 0x92, 0x99, 0x99, 0x99, 0xa1, + 0xa2, 0xb5, 0x99, 0xb6, 0x8b, 0xc7, 0x8b, 0xb9, 0x70, 0x8b, 0x66, 0x8b, + 0x86, 0x8a, 0x85, 0x8a, 0x83, 0x08, 0x88, 0x79, 0x05, 0x82, 0x62, 0x78, + 0x80, 0x42, 0x84, 0xfb, 0x1a, 0x7f, 0x61, 0x81, 0x5a, 0x6c, 0x57, 0x6a, + 0x6d, 0x56, 0x8b, 0x51, 0x8b, 0x3b, 0xc1, 0x5b, 0xe5, 0x8b, 0xae, 0x8b, + 0xb5, 0x92, 0xaf, 0x98, 0xab, 0x96, 0x9a, 0x95, 0xb4, 0xaf, 0x08, 0x8b, + 0x84, 0x8b, 0x87, 0x05, 0x62, 0xa7, 0x72, 0xbb, 0x1e, 0x96, 0x8b, 0x8f, + 0x8b, 0xa3, 0x91, 0x8d, 0x8c, 0x91, 0x8c, 0x91, 0x8c, 0x08, 0x98, 0xcc, + 0x05, 0xfb, 0x0d, 0xf7, 0x05, 0x15, 0x7e, 0x4d, 0x33, 0x56, 0x33, 0x8b, + 0x52, 0x8b, 0x6b, 0xa3, 0x8b, 0xb5, 0x8b, 0xac, 0x9e, 0xac, 0xa9, 0x9d, + 0xa4, 0x9a, 0xa8, 0x93, 0xbc, 0x92, 0xe9, 0x98, 0x93, 0x8c, 0xb7, 0x9a, + 0x08, 0x77, 0x2d, 0x05, 0x0e, 0xf8, 0x1c, 0xf9, 0x78, 0x15, 0x20, 0x8b, + 0xf7, 0x11, 0xfb, 0x28, 0xc0, 0x8b, 0x44, 0xf7, 0x28, 0x05, 0xf7, 0x34, + 0xfd, 0x45, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x87, 0x8b, 0x71, 0x8b, 0x7f, + 0x94, 0x8b, 0x9f, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, 0x8e, 0x08, 0xcb, 0xf7, + 0xc1, 0x05, 0x91, 0xa6, 0x8b, 0x8b, 0x8b, 0x95, 0x8b, 0xcf, 0x46, 0xb8, + 0x22, 0x8b, 0xfb, 0x1f, 0x8b, 0x36, 0x50, 0x78, 0xfb, 0x03, 0x08, 0xdf, + 0x06, 0x94, 0xa7, 0x92, 0x99, 0x99, 0x99, 0xa1, 0xa2, 0xb5, 0x99, 0xb6, + 0x8b, 0xc7, 0x8b, 0xb9, 0x70, 0x8b, 0x66, 0x8b, 0x86, 0x8a, 0x85, 0x8a, + 0x83, 0x08, 0x88, 0x79, 0x05, 0x82, 0x62, 0x78, 0x80, 0x42, 0x84, 0xfb, + 0x1a, 0x7f, 0x61, 0x81, 0x5a, 0x6c, 0x57, 0x6a, 0x6d, 0x56, 0x8b, 0x51, + 0x8b, 0x3b, 0xc1, 0x5b, 0xe5, 0x8b, 0xae, 0x8b, 0xb5, 0x92, 0xaf, 0x98, + 0xab, 0x96, 0x9a, 0x95, 0xb4, 0xaf, 0x08, 0x8b, 0x84, 0x8b, 0x87, 0x05, + 0x62, 0xa7, 0x72, 0xbb, 0x1e, 0x96, 0x8b, 0x8f, 0x8b, 0xa3, 0x91, 0x8d, + 0x8c, 0x91, 0x8c, 0x91, 0x8c, 0x08, 0x98, 0xcc, 0x05, 0xfb, 0x0d, 0xf7, + 0x05, 0x15, 0x7e, 0x4d, 0x33, 0x56, 0x33, 0x8b, 0x52, 0x8b, 0x6b, 0xa3, + 0x8b, 0xb5, 0x8b, 0xac, 0x9e, 0xac, 0xa9, 0x9d, 0xa4, 0x9a, 0xa8, 0x93, + 0xbc, 0x92, 0xe9, 0x98, 0x93, 0x8c, 0xb7, 0x9a, 0x08, 0x77, 0x2d, 0x05, + 0x0e, 0xf8, 0x1d, 0xf9, 0x79, 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, + 0xf3, 0xee, 0xc3, 0x28, 0xca, 0x8b, 0x4b, 0xf7, 0x2a, 0x2c, 0x8b, 0x05, + 0xf7, 0x33, 0xfd, 0x46, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x87, 0x8b, 0x71, + 0x8b, 0x7f, 0x94, 0x8b, 0x9f, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, 0x8e, 0x08, + 0xcb, 0xf7, 0xc1, 0x05, 0x91, 0xa6, 0x8b, 0x8b, 0x8b, 0x95, 0x8b, 0xcf, + 0x46, 0xb8, 0x22, 0x8b, 0xfb, 0x1f, 0x8b, 0x36, 0x50, 0x78, 0xfb, 0x03, + 0x08, 0xdf, 0x06, 0x94, 0xa7, 0x92, 0x99, 0x99, 0x99, 0xa1, 0xa2, 0xb5, + 0x99, 0xb6, 0x8b, 0xc7, 0x8b, 0xb9, 0x70, 0x8b, 0x66, 0x8b, 0x86, 0x8a, + 0x85, 0x8a, 0x83, 0x08, 0x88, 0x79, 0x05, 0x82, 0x62, 0x78, 0x80, 0x42, + 0x84, 0xfb, 0x1a, 0x7f, 0x61, 0x81, 0x5a, 0x6c, 0x57, 0x6a, 0x6d, 0x56, + 0x8b, 0x51, 0x8b, 0x3b, 0xc1, 0x5b, 0xe5, 0x8b, 0xae, 0x8b, 0xb5, 0x92, + 0xaf, 0x98, 0xab, 0x96, 0x9a, 0x95, 0xb4, 0xaf, 0x08, 0x8b, 0x84, 0x8b, + 0x87, 0x05, 0x62, 0xa7, 0x72, 0xbb, 0x1e, 0x96, 0x8b, 0x8f, 0x8b, 0xa3, + 0x91, 0x8d, 0x8c, 0x91, 0x8c, 0x91, 0x8c, 0x08, 0x98, 0xcc, 0x05, 0xfb, + 0x0d, 0xf7, 0x05, 0x15, 0x7e, 0x4d, 0x33, 0x56, 0x33, 0x8b, 0x52, 0x8b, + 0x6b, 0xa3, 0x8b, 0xb5, 0x8b, 0xac, 0x9e, 0xac, 0xa9, 0x9d, 0xa4, 0x9a, + 0xa8, 0x93, 0xbc, 0x92, 0xe9, 0x98, 0x93, 0x8c, 0xb7, 0x9a, 0x08, 0x77, + 0x2d, 0x05, 0x0e, 0xf8, 0xbc, 0xbe, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x87, + 0x8b, 0x71, 0x8b, 0x7f, 0x94, 0x8b, 0x9f, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, + 0x8e, 0x08, 0xcb, 0xf7, 0xc1, 0x05, 0x91, 0xa6, 0x8b, 0x8b, 0x8b, 0x95, + 0x8b, 0xcf, 0x46, 0xb8, 0x22, 0x8b, 0xfb, 0x1f, 0x8b, 0x36, 0x50, 0x78, + 0xfb, 0x03, 0x08, 0xdf, 0x06, 0x94, 0xa7, 0x92, 0x99, 0x99, 0x99, 0xa1, + 0xa2, 0xb5, 0x99, 0xb6, 0x8b, 0xc7, 0x8b, 0xb9, 0x70, 0x8b, 0x66, 0x8b, + 0x85, 0x8a, 0x85, 0x8a, 0x84, 0x08, 0x88, 0x79, 0x05, 0x82, 0x62, 0x79, + 0x80, 0x41, 0x84, 0xfb, 0x1a, 0x7f, 0x61, 0x81, 0x5a, 0x6c, 0x57, 0x6a, + 0x6d, 0x56, 0x8b, 0x51, 0x8b, 0x3b, 0xc1, 0x5b, 0xe5, 0x8b, 0xae, 0x8b, + 0xb5, 0x92, 0xaf, 0x98, 0xab, 0x96, 0x9a, 0x95, 0xb4, 0xaf, 0x08, 0x8b, + 0x84, 0x8b, 0x87, 0x05, 0x62, 0xa7, 0x72, 0xbb, 0x1e, 0x97, 0x8b, 0x8f, + 0x8c, 0xa2, 0x90, 0x8d, 0x8b, 0x91, 0x8d, 0x91, 0x8c, 0x08, 0x98, 0xcc, + 0x05, 0xfb, 0x0d, 0xf7, 0x05, 0x15, 0x7e, 0x4d, 0x33, 0x56, 0x33, 0x8b, + 0x52, 0x8b, 0x6b, 0xa3, 0x8b, 0xb5, 0x8b, 0xac, 0x9e, 0xac, 0xa9, 0x9d, + 0xa4, 0x9a, 0xa8, 0x93, 0xbc, 0x92, 0xe9, 0x98, 0x93, 0x8c, 0xb7, 0x9a, + 0x08, 0x77, 0x2d, 0x05, 0xee, 0xf8, 0xbf, 0x15, 0x7a, 0x6f, 0x80, 0x82, + 0x77, 0x8b, 0x81, 0x8b, 0x70, 0x91, 0x71, 0x94, 0x08, 0x64, 0x98, 0x7a, + 0x8f, 0x7a, 0x8b, 0x72, 0x8b, 0x6d, 0x7c, 0x7a, 0x76, 0x7f, 0x7c, 0x84, + 0x7b, 0x7e, 0x67, 0x08, 0xc0, 0x06, 0x9f, 0xa7, 0x93, 0x90, 0xa1, 0x8b, + 0x91, 0x8b, 0x96, 0x89, 0x95, 0x87, 0x08, 0xcb, 0x75, 0x9d, 0x87, 0xa0, + 0x8b, 0xb8, 0x8b, 0xb6, 0xb6, 0x9f, 0xcb, 0x08, 0x56, 0x06, 0x0e, 0xf8, + 0xbc, 0xbe, 0x15, 0x82, 0x89, 0x87, 0x8b, 0x87, 0x8b, 0x71, 0x8b, 0x7f, + 0x94, 0x8b, 0x9f, 0x8b, 0x8e, 0x8b, 0x8f, 0x8c, 0x8e, 0x08, 0xcb, 0xf7, + 0xc1, 0x05, 0x91, 0xa6, 0x8b, 0x8b, 0x8b, 0x95, 0x8b, 0xcf, 0x46, 0xb8, + 0x22, 0x8b, 0xfb, 0x1f, 0x8b, 0x36, 0x50, 0x78, 0xfb, 0x03, 0x08, 0xdf, + 0x06, 0x94, 0xa7, 0x92, 0x99, 0x99, 0x99, 0xa1, 0xa2, 0xb5, 0x99, 0xb6, + 0x8b, 0xc7, 0x8b, 0xb9, 0x70, 0x8b, 0x66, 0x8b, 0x86, 0x8a, 0x85, 0x8a, + 0x83, 0x08, 0x88, 0x79, 0x05, 0x82, 0x62, 0x78, 0x80, 0x42, 0x84, 0xfb, + 0x1a, 0x7f, 0x61, 0x81, 0x5a, 0x6c, 0x57, 0x6a, 0x6d, 0x56, 0x8b, 0x51, + 0x8b, 0x3b, 0xc1, 0x5b, 0xe5, 0x8b, 0xae, 0x8b, 0xb5, 0x92, 0xaf, 0x98, + 0xab, 0x96, 0x9a, 0x95, 0xb4, 0xaf, 0x08, 0x8b, 0x84, 0x8b, 0x87, 0x05, + 0x62, 0xa7, 0x72, 0xbb, 0x1e, 0x96, 0x8b, 0x8f, 0x8b, 0xa3, 0x91, 0x8d, + 0x8c, 0x91, 0x8c, 0x91, 0x8c, 0x08, 0x98, 0xcc, 0x05, 0xfb, 0x0d, 0xf7, + 0x05, 0x15, 0x7e, 0x4d, 0x33, 0x56, 0x33, 0x8b, 0x52, 0x8b, 0x6b, 0xa3, + 0x8b, 0xb5, 0x8b, 0xac, 0x9e, 0xac, 0xa9, 0x9d, 0xa4, 0x9a, 0xa8, 0x93, + 0xbc, 0x92, 0xe9, 0x98, 0x93, 0x8c, 0xb7, 0x9a, 0x08, 0x77, 0x2d, 0x05, + 0x95, 0xf8, 0xe2, 0x15, 0x55, 0x55, 0x57, 0x56, 0x64, 0xaa, 0x6c, 0xb3, + 0x1f, 0xc4, 0xbf, 0xbf, 0xc3, 0xb1, 0x6c, 0xa8, 0x62, 0x1f, 0x84, 0x5f, + 0x15, 0x9e, 0x9a, 0x7c, 0x77, 0x71, 0x70, 0x71, 0x70, 0x77, 0x7c, 0x99, + 0xa0, 0xa5, 0xa6, 0xa5, 0xa7, 0x1f, 0x0e, 0xf7, 0x63, 0xf7, 0xa3, 0x74, + 0x15, 0xf7, 0x15, 0x8f, 0xe1, 0xd1, 0xab, 0xf7, 0x15, 0x08, 0x37, 0x06, + 0x6d, 0x39, 0x54, 0x5f, 0x43, 0x8b, 0x46, 0x8b, 0x5f, 0xbc, 0x8b, 0xd9, + 0x8b, 0xcb, 0xa0, 0xd7, 0xac, 0xbf, 0xb0, 0xc6, 0xbd, 0xa9, 0xc8, 0x8b, + 0xca, 0x8b, 0xb2, 0x68, 0x8b, 0x52, 0x8b, 0x85, 0x8b, 0x84, 0x8a, 0x82, + 0x08, 0xdf, 0x8b, 0x8c, 0x9a, 0x05, 0x8c, 0x9b, 0x8c, 0x96, 0x8b, 0x8e, + 0x8b, 0xab, 0x79, 0xb3, 0x71, 0xa6, 0x6c, 0xab, 0x62, 0x9a, 0x52, 0x8b, + 0x31, 0x8b, 0x3a, 0x65, 0x56, 0x46, 0x5c, 0x4e, 0x69, 0xfb, 0x01, 0x8b, + 0x2f, 0x8b, 0x51, 0xa3, 0x52, 0xb2, 0x67, 0x08, 0xa3, 0x74, 0x9f, 0x82, + 0xba, 0x82, 0x08, 0x65, 0x45, 0x98, 0x85, 0x92, 0x8c, 0x05, 0x9a, 0x8e, + 0x8b, 0x8b, 0x90, 0x8b, 0x08, 0x9b, 0x9a, 0x81, 0x7f, 0x6b, 0x71, 0x74, + 0x66, 0x1f, 0x6f, 0x8b, 0x72, 0x93, 0x62, 0xa0, 0x08, 0x6f, 0x65, 0x05, + 0xbe, 0x71, 0xa8, 0x83, 0xb1, 0x8b, 0x08, 0xdf, 0xc8, 0xb9, 0xca, 0xa7, + 0x6d, 0xa2, 0x66, 0x1f, 0x87, 0x8b, 0x87, 0x8b, 0x7e, 0x89, 0x08, 0x9d, + 0xac, 0x05, 0x0e, 0xf8, 0x24, 0xf9, 0x5f, 0x15, 0x23, 0x8b, 0x75, 0x24, + 0xf2, 0x8b, 0xa2, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, 0x24, + 0xf2, 0x8b, 0xa2, 0xf2, 0x05, 0x8d, 0xfc, 0x75, 0x15, 0x8e, 0x9c, 0x05, + 0x94, 0xba, 0x90, 0xb5, 0x8b, 0xa6, 0x8b, 0xec, 0x38, 0xd6, 0xfb, 0x00, + 0x8b, 0x34, 0x8b, 0x37, 0x62, 0x59, 0x48, 0x5c, 0x4c, 0x66, 0xfb, 0x06, + 0x8b, 0x3a, 0x8b, 0x55, 0xa2, 0x54, 0xb2, 0x66, 0xae, 0x69, 0xb7, 0x7b, + 0xc4, 0x8b, 0x08, 0xf7, 0x0c, 0x8b, 0xf2, 0xd5, 0xaa, 0xf7, 0x00, 0x08, + 0x37, 0x06, 0x67, 0x46, 0x55, 0x67, 0x49, 0x8b, 0x3c, 0x8b, 0x5e, 0xbc, + 0x8b, 0xdf, 0x8b, 0xa1, 0x8c, 0x95, 0x8f, 0x9a, 0x08, 0xf8, 0x16, 0x06, + 0xfc, 0x04, 0xd3, 0x15, 0xa5, 0xe6, 0xd5, 0xcc, 0xdc, 0x8b, 0xd2, 0x8b, + 0xb8, 0x5b, 0x8b, 0x40, 0x8b, 0x81, 0x8a, 0x84, 0x89, 0x7b, 0x08, 0xfb, + 0xba, 0x06, 0x0e, 0xf8, 0x68, 0xf9, 0x78, 0x15, 0xfb, 0x14, 0xfb, 0x28, + 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0xea, 0xfc, + 0x8e, 0x15, 0x8e, 0x9c, 0x05, 0x94, 0xba, 0x90, 0xb5, 0x8b, 0xa6, 0x8b, + 0xec, 0x38, 0xd6, 0xfb, 0x00, 0x8b, 0x34, 0x8b, 0x37, 0x62, 0x59, 0x48, + 0x5c, 0x4c, 0x66, 0xfb, 0x06, 0x8b, 0x3a, 0x8b, 0x55, 0xa2, 0x54, 0xb2, + 0x66, 0xae, 0x69, 0xb7, 0x7b, 0xc4, 0x8b, 0x08, 0xf7, 0x0c, 0x8b, 0xf2, + 0xd5, 0xaa, 0xf7, 0x00, 0x08, 0x37, 0x06, 0x67, 0x46, 0x55, 0x67, 0x49, + 0x8b, 0x3c, 0x8b, 0x5e, 0xbc, 0x8b, 0xdf, 0x8b, 0xa1, 0x8c, 0x95, 0x8f, + 0x9a, 0x08, 0xf8, 0x16, 0x06, 0xfc, 0x04, 0xd3, 0x15, 0xa5, 0xe6, 0xd5, + 0xcc, 0xdc, 0x8b, 0xd2, 0x8b, 0xb8, 0x5b, 0x8b, 0x40, 0x8b, 0x81, 0x8a, + 0x84, 0x89, 0x7b, 0x08, 0xfb, 0xba, 0x06, 0x0e, 0xf8, 0x14, 0xf9, 0x78, + 0x15, 0x21, 0x8b, 0xf7, 0x10, 0xfb, 0x28, 0xc1, 0x8b, 0x43, 0xf7, 0x28, + 0x05, 0xf7, 0x47, 0xfc, 0x8e, 0x15, 0x8e, 0x9c, 0x05, 0x94, 0xba, 0x90, + 0xb5, 0x8b, 0xa6, 0x8b, 0xec, 0x38, 0xd6, 0xfb, 0x00, 0x8b, 0x34, 0x8b, + 0x37, 0x62, 0x59, 0x48, 0x5c, 0x4c, 0x66, 0xfb, 0x06, 0x8b, 0x3a, 0x8b, + 0x55, 0xa2, 0x54, 0xb2, 0x66, 0xae, 0x69, 0xb7, 0x7b, 0xc4, 0x8b, 0x08, + 0xf7, 0x0c, 0x8b, 0xf2, 0xd5, 0xaa, 0xf7, 0x00, 0x08, 0x37, 0x06, 0x67, + 0x46, 0x55, 0x67, 0x49, 0x8b, 0x3c, 0x8b, 0x5e, 0xbc, 0x8b, 0xdf, 0x8b, + 0xa1, 0x8c, 0x95, 0x8f, 0x9a, 0x08, 0xf8, 0x16, 0x06, 0xfc, 0x04, 0xd3, + 0x15, 0xa5, 0xe6, 0xd5, 0xcc, 0xdc, 0x8b, 0xd2, 0x8b, 0xb8, 0x5b, 0x8b, + 0x40, 0x8b, 0x81, 0x8a, 0x84, 0x89, 0x7b, 0x08, 0xfb, 0xba, 0x06, 0x0e, + 0xf8, 0x19, 0xf9, 0x79, 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, 0xf2, + 0xee, 0xc3, 0x28, 0xcb, 0x8b, 0x4a, 0xf7, 0x2a, 0x2d, 0x8b, 0x05, 0xf7, + 0x42, 0xfc, 0x8f, 0x15, 0x8e, 0x9c, 0x05, 0x94, 0xba, 0x90, 0xb5, 0x8b, + 0xa6, 0x8b, 0xec, 0x38, 0xd6, 0xfb, 0x00, 0x8b, 0x34, 0x8b, 0x37, 0x62, + 0x59, 0x48, 0x5c, 0x4c, 0x66, 0xfb, 0x06, 0x8b, 0x3a, 0x8b, 0x55, 0xa2, + 0x54, 0xb2, 0x66, 0xae, 0x69, 0xb7, 0x7b, 0xc4, 0x8b, 0x08, 0xf7, 0x0c, + 0x8b, 0xf2, 0xd5, 0xaa, 0xf7, 0x00, 0x08, 0x37, 0x06, 0x67, 0x46, 0x55, + 0x67, 0x49, 0x8b, 0x3c, 0x8b, 0x5e, 0xbc, 0x8b, 0xdf, 0x8b, 0xa1, 0x8c, + 0x95, 0x8f, 0x9a, 0x08, 0xf8, 0x16, 0x06, 0xfc, 0x04, 0xd3, 0x15, 0xa5, + 0xe6, 0xd5, 0xcc, 0xdc, 0x8b, 0xd2, 0x8b, 0xb8, 0x5b, 0x8b, 0x40, 0x8b, + 0x81, 0x8a, 0x84, 0x89, 0x7b, 0x08, 0xfb, 0xba, 0x06, 0x0e, 0x7c, 0xf7, + 0xb6, 0xf8, 0xa3, 0x15, 0x37, 0x8b, 0xfb, 0x04, 0xfc, 0xa3, 0xdf, 0x8b, + 0xf7, 0x04, 0xf8, 0xa3, 0x05, 0x6b, 0xf7, 0x49, 0x15, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, + 0x24, 0xf3, 0x8b, 0xa1, 0xf2, 0x05, 0x0e, 0x7c, 0xf7, 0xb6, 0xf8, 0xa3, + 0x15, 0x37, 0x8b, 0xfb, 0x04, 0xfc, 0xa3, 0xdf, 0x8b, 0xf7, 0x04, 0xf8, + 0xa3, 0x05, 0xa8, 0xf7, 0x69, 0x15, 0xfb, 0x14, 0xfb, 0x28, 0xc7, 0x8b, + 0xf7, 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x0e, 0x7c, 0xf7, 0xb6, + 0xf8, 0xa3, 0x15, 0x37, 0x8b, 0xfb, 0x04, 0xfc, 0xa3, 0xdf, 0x8b, 0xf7, + 0x04, 0xf8, 0xa3, 0x05, 0x6b, 0xf7, 0x69, 0x15, 0x21, 0x8b, 0xf7, 0x11, + 0xfb, 0x28, 0xc0, 0x8b, 0x43, 0xf7, 0x28, 0x05, 0x0e, 0x7c, 0xf7, 0xb6, + 0xf8, 0xa3, 0x15, 0x37, 0x8b, 0xfb, 0x04, 0xfc, 0xa3, 0xdf, 0x8b, 0xf7, + 0x04, 0xf8, 0xa3, 0x05, 0x60, 0xf7, 0x6a, 0x15, 0xfb, 0x14, 0xfb, 0x2a, + 0xcb, 0x8b, 0xf3, 0xee, 0xc3, 0x28, 0xca, 0x8b, 0x4b, 0xf7, 0x2a, 0x2c, + 0x8b, 0x05, 0x0e, 0xf7, 0x49, 0xf8, 0xa0, 0x15, 0xfb, 0x03, 0xfc, 0xa0, + 0xdf, 0x8b, 0xc8, 0xf7, 0xb5, 0x05, 0xa3, 0xf7, 0x02, 0xd1, 0xcf, 0xe5, + 0x8b, 0xbd, 0x8b, 0xb0, 0x68, 0x8b, 0x5d, 0x8b, 0x85, 0x89, 0x7c, 0x87, + 0x7b, 0x08, 0x41, 0xfb, 0xf1, 0xdf, 0x8b, 0xdb, 0xf8, 0x0c, 0x05, 0x8e, + 0x98, 0x8c, 0x97, 0x8b, 0x98, 0x8b, 0xd7, 0x56, 0xbc, 0x38, 0x8b, 0x3f, + 0x8b, 0x49, 0x70, 0x57, 0x56, 0x08, 0x98, 0xcc, 0x05, 0x3f, 0x06, 0xf7, + 0xf6, 0xf7, 0x57, 0x15, 0x79, 0x6e, 0x81, 0x83, 0x78, 0x8b, 0x80, 0x8b, + 0x71, 0x91, 0x70, 0x94, 0x08, 0x64, 0x98, 0x7b, 0x8f, 0x7a, 0x8b, 0x71, + 0x8b, 0x6d, 0x7c, 0x7a, 0x76, 0x80, 0x7c, 0x83, 0x7b, 0x7f, 0x67, 0x08, + 0xc0, 0x06, 0x8e, 0x8f, 0x8d, 0x8e, 0x8c, 0x8d, 0x98, 0x9c, 0x96, 0x92, + 0x9f, 0x8b, 0x90, 0x8b, 0x96, 0x89, 0x95, 0x87, 0x08, 0xcc, 0x75, 0x9c, + 0x87, 0xa1, 0x8b, 0xb7, 0x8b, 0xb6, 0xb6, 0xa0, 0xcb, 0x08, 0x55, 0x06, + 0x0e, 0xf8, 0x1f, 0xf9, 0x5f, 0x15, 0x23, 0x8b, 0x75, 0x24, 0xf2, 0x8b, + 0xa2, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, 0x24, 0xf2, 0x8b, + 0xa2, 0xf2, 0x05, 0xfb, 0x40, 0xfb, 0x44, 0x15, 0x2e, 0x8b, 0x39, 0x61, + 0x58, 0x41, 0x5e, 0x4b, 0x6a, 0xfb, 0x02, 0x8b, 0x36, 0x8b, 0xfb, 0x03, + 0xd8, 0x3f, 0xf7, 0x04, 0x8b, 0xeb, 0x8b, 0xd7, 0xb2, 0xc3, 0xd8, 0xb9, + 0xca, 0xac, 0xf7, 0x01, 0x8b, 0xe2, 0x8b, 0xc0, 0x76, 0xbe, 0x69, 0xad, + 0x08, 0x69, 0xac, 0x5e, 0x9b, 0x51, 0x8b, 0x08, 0x7e, 0x3e, 0x15, 0xd5, + 0xb6, 0x5b, 0x3a, 0x1f, 0x8b, 0x51, 0x7a, 0x49, 0x70, 0x59, 0x65, 0x46, + 0x55, 0x67, 0x46, 0x8b, 0x44, 0x8b, 0x5f, 0xbd, 0x8b, 0xdb, 0x8b, 0xc4, + 0x9c, 0xcd, 0xa6, 0xbd, 0xb0, 0xcf, 0xc3, 0xb0, 0xcd, 0x8b, 0x08, 0x0e, + 0xf8, 0x64, 0xf9, 0x78, 0x15, 0xfb, 0x14, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, + 0x48, 0xf7, 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x3b, 0xfb, 0x5d, 0x15, 0x2e, + 0x8b, 0x39, 0x61, 0x58, 0x41, 0x5e, 0x4b, 0x6a, 0xfb, 0x02, 0x8b, 0x36, + 0x8b, 0xfb, 0x03, 0xd8, 0x3f, 0xf7, 0x04, 0x8b, 0xeb, 0x8b, 0xd7, 0xb2, + 0xc3, 0xd8, 0xb9, 0xca, 0xac, 0xf7, 0x01, 0x8b, 0xe2, 0x8b, 0xc0, 0x76, + 0xbe, 0x69, 0xad, 0x08, 0x69, 0xac, 0x5e, 0x9b, 0x51, 0x8b, 0x08, 0x7e, + 0x3e, 0x15, 0xd5, 0xb6, 0x5b, 0x3a, 0x1f, 0x8b, 0x51, 0x7a, 0x49, 0x70, + 0x59, 0x65, 0x46, 0x55, 0x67, 0x46, 0x8b, 0x44, 0x8b, 0x5f, 0xbd, 0x8b, + 0xdb, 0x8b, 0xc4, 0x9c, 0xcd, 0xa6, 0xbd, 0xb0, 0xcf, 0xc3, 0xb0, 0xcd, + 0x8b, 0x08, 0x0e, 0xf8, 0x10, 0xf9, 0x78, 0x15, 0x21, 0x8b, 0xf7, 0x10, + 0xfb, 0x28, 0xc1, 0x8b, 0x43, 0xf7, 0x28, 0x05, 0x8f, 0xfb, 0x5d, 0x15, + 0x2e, 0x8b, 0x39, 0x61, 0x58, 0x41, 0x5e, 0x4b, 0x6a, 0xfb, 0x02, 0x8b, + 0x36, 0x8b, 0xfb, 0x03, 0xd8, 0x3f, 0xf7, 0x04, 0x8b, 0xeb, 0x8b, 0xd7, + 0xb2, 0xc3, 0xd8, 0xb9, 0xca, 0xac, 0xf7, 0x01, 0x8b, 0xe2, 0x8b, 0xc0, + 0x76, 0xbe, 0x69, 0xad, 0x08, 0x69, 0xac, 0x5e, 0x9b, 0x51, 0x8b, 0x08, + 0x7e, 0x3e, 0x15, 0xd5, 0xb6, 0x5b, 0x3a, 0x1f, 0x8b, 0x51, 0x7a, 0x49, + 0x70, 0x59, 0x65, 0x46, 0x55, 0x67, 0x46, 0x8b, 0x44, 0x8b, 0x5f, 0xbd, + 0x8b, 0xdb, 0x8b, 0xc4, 0x9c, 0xcd, 0xa6, 0xbd, 0xb0, 0xcf, 0xc3, 0xb0, + 0xcd, 0x8b, 0x08, 0x0e, 0xf8, 0x13, 0xf9, 0x79, 0x15, 0xfb, 0x14, 0xfb, + 0x2a, 0xcb, 0x8b, 0xf2, 0xee, 0xc3, 0x28, 0xcb, 0x8b, 0x4a, 0xf7, 0x2a, + 0x2d, 0x8b, 0x05, 0x8c, 0xfb, 0x5e, 0x15, 0x2e, 0x8b, 0x39, 0x61, 0x58, + 0x41, 0x5e, 0x4b, 0x6a, 0xfb, 0x02, 0x8b, 0x36, 0x8b, 0xfb, 0x03, 0xd8, + 0x3f, 0xf7, 0x04, 0x8b, 0xeb, 0x8b, 0xd7, 0xb2, 0xc3, 0xd8, 0xb9, 0xca, + 0xac, 0xf7, 0x01, 0x8b, 0xe2, 0x8b, 0xc0, 0x76, 0xbe, 0x69, 0xad, 0x08, + 0x69, 0xac, 0x5e, 0x9b, 0x51, 0x8b, 0x08, 0x7e, 0x3e, 0x15, 0xd5, 0xb6, + 0x5b, 0x3a, 0x1f, 0x8b, 0x51, 0x7a, 0x49, 0x70, 0x59, 0x65, 0x46, 0x55, + 0x67, 0x46, 0x8b, 0x44, 0x8b, 0x5f, 0xbd, 0x8b, 0xdb, 0x8b, 0xc4, 0x9c, + 0xcd, 0xa6, 0xbd, 0xb0, 0xcf, 0xc3, 0xb0, 0xcd, 0x8b, 0x08, 0x0e, 0xf8, + 0x14, 0xf8, 0xaf, 0x15, 0x2e, 0x8b, 0x3a, 0x61, 0x57, 0x41, 0x5e, 0x4b, + 0x6a, 0xfb, 0x02, 0x8b, 0x36, 0x8b, 0xfb, 0x03, 0xd8, 0x3f, 0xf7, 0x04, + 0x8b, 0xeb, 0x8b, 0xd7, 0xb2, 0xc3, 0xd8, 0xb9, 0xca, 0xac, 0xf7, 0x01, + 0x8b, 0xe2, 0x8b, 0xc0, 0x77, 0xbe, 0x68, 0xad, 0x08, 0x69, 0xac, 0x5e, + 0x9b, 0x51, 0x8b, 0x08, 0x7e, 0x3e, 0x15, 0xd4, 0xb7, 0x5b, 0x3a, 0x1f, + 0x8b, 0x50, 0x7b, 0x4a, 0x6f, 0x59, 0x65, 0x46, 0x55, 0x67, 0x46, 0x8b, + 0x44, 0x8b, 0x5f, 0xbd, 0x8b, 0xdb, 0x8b, 0xc4, 0x9c, 0xcd, 0xa6, 0xbd, + 0xb0, 0xce, 0xc4, 0xb1, 0xcc, 0x8b, 0x08, 0xf7, 0x33, 0xf7, 0x95, 0x15, + 0x79, 0x6e, 0x81, 0x83, 0x77, 0x8b, 0x81, 0x8b, 0x6f, 0x92, 0x72, 0x93, + 0x08, 0x64, 0x98, 0x7b, 0x8f, 0x79, 0x8b, 0x72, 0x8b, 0x6c, 0x7c, 0x7b, + 0x76, 0x7f, 0x7c, 0x84, 0x7c, 0x7e, 0x66, 0x08, 0xc0, 0x06, 0x8e, 0x8f, + 0x8d, 0x8e, 0x8d, 0x8d, 0x97, 0x9d, 0x97, 0x91, 0x9e, 0x8b, 0x91, 0x8b, + 0x95, 0x89, 0x96, 0x87, 0x08, 0xcb, 0x75, 0x9c, 0x87, 0xa1, 0x8b, 0xb8, + 0x8b, 0xb6, 0xb6, 0x9f, 0xcb, 0x08, 0x56, 0x06, 0x0e, 0xf7, 0x63, 0xf8, + 0x37, 0xf8, 0xe4, 0x15, 0xf7, 0x14, 0xf7, 0x28, 0x4b, 0x8b, 0x23, 0x29, + 0x53, 0xed, 0x4c, 0x8b, 0xcb, 0xfb, 0x28, 0x05, 0xea, 0x06, 0xea, 0xfb, + 0x6a, 0x15, 0x90, 0x9f, 0x8d, 0x95, 0x8b, 0x98, 0x8b, 0xd1, 0x48, 0xbb, + 0x29, 0x8b, 0x45, 0x8b, 0x4d, 0x76, 0x62, 0x64, 0x67, 0x68, 0x73, 0x57, + 0x8b, 0x5c, 0x8b, 0x4e, 0xae, 0x6e, 0xf2, 0x70, 0x08, 0xd5, 0x78, 0x05, + 0xad, 0x82, 0x9a, 0x85, 0x94, 0x80, 0x92, 0x83, 0x91, 0x7b, 0x8b, 0x82, + 0x8b, 0x79, 0x7b, 0x6c, 0x7b, 0x7e, 0x72, 0x76, 0x5f, 0x7e, 0x60, 0x8b, + 0x08, 0x46, 0x64, 0xa6, 0xbd, 0x1f, 0x8b, 0x91, 0x8c, 0x94, 0x8c, 0x95, + 0x08, 0x32, 0x06, 0x87, 0x74, 0x89, 0x7f, 0x8b, 0x7b, 0x08, 0x3b, 0xd1, + 0x5b, 0xf7, 0x09, 0xf7, 0x29, 0xec, 0xd9, 0xf7, 0x0a, 0x1e, 0x8b, 0xc8, + 0x6a, 0xab, 0x32, 0xa1, 0x08, 0x40, 0x9e, 0x05, 0x52, 0x99, 0x6e, 0x9f, + 0x8b, 0xa5, 0x8b, 0x9f, 0x97, 0xa4, 0x9d, 0x9c, 0xa3, 0xa2, 0xa9, 0x95, + 0xb8, 0x8b, 0x08, 0xc5, 0xac, 0x75, 0x63, 0x1f, 0x8b, 0x85, 0x8b, 0x86, + 0x8b, 0x80, 0xde, 0x8b, 0x05, 0x0e, 0xf8, 0x1e, 0xf9, 0x5f, 0x15, 0x23, + 0x8b, 0x75, 0x24, 0xf2, 0x8b, 0x05, 0xa2, 0xf2, 0x05, 0xf7, 0x35, 0x16, + 0x23, 0x8b, 0x75, 0x24, 0xf2, 0x8b, 0xa2, 0xf2, 0x05, 0x43, 0xfd, 0x5f, + 0x15, 0xf7, 0x03, 0xf8, 0xa0, 0x37, 0x8b, 0x4c, 0xfb, 0xbd, 0x05, 0x74, + 0xfb, 0x00, 0x44, 0x45, 0x36, 0x8b, 0x55, 0x8b, 0x68, 0xa9, 0x8b, 0xba, + 0x8b, 0x93, 0x8c, 0x94, 0x8d, 0x95, 0x08, 0xda, 0xf8, 0x07, 0x37, 0x8b, + 0x35, 0xfc, 0x28, 0x05, 0x89, 0x81, 0x8a, 0x80, 0x8b, 0x7e, 0x8b, 0x47, + 0xbf, 0x62, 0xe1, 0x8b, 0xd9, 0x8b, 0xc4, 0xa3, 0xc5, 0xc3, 0x08, 0x7f, + 0x52, 0xd7, 0x8b, 0x05, 0x0e, 0xf8, 0x63, 0xf9, 0x78, 0x15, 0xfb, 0x14, + 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, 0x28, 0x05, 0xfb, 0x04, 0x06, + 0x9f, 0xfd, 0x78, 0x15, 0xf7, 0x03, 0xf8, 0xa0, 0x37, 0x8b, 0x4c, 0xfb, + 0xbd, 0x05, 0x74, 0xfb, 0x00, 0x44, 0x45, 0x36, 0x8b, 0x55, 0x8b, 0x68, + 0xa9, 0x8b, 0xba, 0x8b, 0x93, 0x8c, 0x94, 0x8d, 0x95, 0x08, 0xda, 0xf8, + 0x07, 0x37, 0x8b, 0x35, 0xfc, 0x28, 0x05, 0x89, 0x81, 0x8a, 0x80, 0x8b, + 0x7e, 0x8b, 0x47, 0xbf, 0x62, 0xe1, 0x8b, 0xd9, 0x8b, 0xc4, 0xa3, 0xc5, + 0xc3, 0x08, 0x7f, 0x52, 0xd7, 0x8b, 0x05, 0x0e, 0xf8, 0x0c, 0xf9, 0x78, + 0x15, 0x21, 0x8b, 0xf7, 0x11, 0xfb, 0x28, 0xc0, 0x8b, 0x05, 0x43, 0xf7, + 0x28, 0x05, 0xf6, 0xfd, 0x78, 0x15, 0xf7, 0x03, 0xf8, 0xa0, 0x37, 0x8b, + 0x4c, 0xfb, 0xbd, 0x05, 0x74, 0xfb, 0x00, 0x44, 0x45, 0x36, 0x8b, 0x55, + 0x8b, 0x68, 0xa9, 0x8b, 0xba, 0x8b, 0x93, 0x8c, 0x94, 0x8d, 0x95, 0x08, + 0xda, 0xf8, 0x07, 0x37, 0x8b, 0x35, 0xfc, 0x28, 0x05, 0x89, 0x81, 0x8a, + 0x80, 0x8b, 0x7e, 0x8b, 0x47, 0xbf, 0x62, 0xe1, 0x8b, 0xd9, 0x8b, 0xc4, + 0xa3, 0xc5, 0xc3, 0x08, 0x7f, 0x52, 0xd7, 0x8b, 0x05, 0x0e, 0xf8, 0x10, + 0xf9, 0x79, 0x15, 0xfb, 0x14, 0xfb, 0x2a, 0xcb, 0x8b, 0xf2, 0xee, 0xc3, + 0x28, 0xcb, 0x8b, 0x4a, 0xf7, 0x2a, 0x05, 0x2d, 0x06, 0xf2, 0xfd, 0x79, + 0x15, 0xf7, 0x03, 0xf8, 0xa0, 0x37, 0x8b, 0x4c, 0xfb, 0xbd, 0x05, 0x74, + 0xfb, 0x00, 0x44, 0x45, 0x36, 0x8b, 0x55, 0x8b, 0x68, 0xa9, 0x8b, 0xba, + 0x8b, 0x93, 0x8c, 0x94, 0x8d, 0x95, 0x08, 0xda, 0xf8, 0x07, 0x37, 0x8b, + 0x35, 0xfc, 0x28, 0x05, 0x89, 0x81, 0x8a, 0x80, 0x8b, 0x7e, 0x8b, 0x47, + 0xbf, 0x62, 0xe1, 0x8b, 0xd9, 0x8b, 0xc4, 0xa3, 0xc5, 0xc3, 0x08, 0x7f, + 0x52, 0xd7, 0x8b, 0x05, 0x0e, 0xf7, 0x63, 0xf8, 0x89, 0xf8, 0xa0, 0x15, + 0xfb, 0x7d, 0xfc, 0x2b, 0x5d, 0xf8, 0x2b, 0x31, 0x8b, 0xcf, 0xfc, 0xa4, + 0x57, 0x3a, 0x05, 0x70, 0x61, 0x7d, 0x82, 0x67, 0x8b, 0x08, 0x7f, 0x8b, + 0x81, 0x8b, 0x05, 0x89, 0x8b, 0x85, 0x8c, 0x82, 0x8c, 0x08, 0x83, 0x8c, + 0x7b, 0x40, 0x05, 0x9d, 0x83, 0x97, 0x89, 0x9f, 0x8b, 0xd1, 0x8b, 0xbd, + 0xac, 0xb7, 0xd6, 0x08, 0xf8, 0x04, 0xf9, 0x0e, 0x32, 0x8b, 0x05, 0x48, + 0xf7, 0x6c, 0x15, 0xfb, 0x14, 0xfb, 0x28, 0xc7, 0x8b, 0xf7, 0x48, 0xf7, + 0x28, 0xfb, 0x04, 0x8b, 0x05, 0x0e, 0xf7, 0x63, 0xf8, 0xc1, 0xf8, 0xa0, + 0x15, 0xfc, 0x1c, 0x8b, 0x7c, 0x43, 0xf7, 0xba, 0x8b, 0xfc, 0x1f, 0xfc, + 0x0e, 0x79, 0x41, 0xf8, 0x3f, 0x8b, 0x9a, 0xd3, 0xfb, 0xda, 0x8b, 0xf8, + 0x1c, 0xf8, 0x0d, 0x9d, 0xd6, 0x05, 0xfb, 0x1e, 0xcf, 0x15, 0xf7, 0x15, + 0xf7, 0x28, 0x4a, 0x8b, 0x24, 0x29, 0x53, 0xed, 0x4c, 0x8b, 0xcb, 0xfb, + 0x28, 0xe9, 0x8b, 0x05, 0x0e, 0xf7, 0x8f, 0xf8, 0xc8, 0x15, 0xef, 0xb8, + 0x05, 0xaf, 0x6a, 0x9b, 0x7a, 0xab, 0x61, 0x6f, 0x99, 0x7f, 0x8e, 0x71, + 0x8b, 0x36, 0x8b, 0x3d, 0x62, 0x5b, 0x45, 0x5e, 0x4a, 0x6a, 0xfb, 0x02, + 0x8b, 0x37, 0x8b, 0x56, 0xa0, 0x58, 0xad, 0x69, 0xac, 0x6b, 0xba, 0x7a, + 0xc5, 0x8b, 0x08, 0xe6, 0x8b, 0xda, 0xb3, 0xc1, 0xd7, 0xb8, 0xc9, 0xad, + 0xf7, 0x02, 0x8b, 0xdd, 0x8b, 0xf6, 0x58, 0xeb, 0x22, 0xe5, 0x08, 0xea, + 0xb4, 0x64, 0xb1, 0x28, 0x60, 0x05, 0x87, 0x8e, 0x88, 0x8d, 0x8a, 0x8b, + 0x7f, 0x94, 0x7f, 0x93, 0x7e, 0x94, 0x87, 0x8e, 0x7f, 0x93, 0x78, 0x96, + 0x08, 0x75, 0x99, 0x61, 0x5e, 0x05, 0x97, 0x82, 0x97, 0x83, 0x8f, 0x89, + 0x9a, 0x81, 0x95, 0x85, 0x8d, 0x89, 0x8e, 0x89, 0x93, 0x84, 0x94, 0x83, + 0x08, 0x32, 0x62, 0xab, 0x64, 0x05, 0xf7, 0x0c, 0x25, 0x15, 0xd5, 0xb6, + 0x5b, 0x3a, 0x1f, 0x8b, 0x50, 0x7a, 0x4a, 0x70, 0x59, 0x65, 0x46, 0x55, + 0x67, 0x46, 0x8b, 0x44, 0x8b, 0x5f, 0xbd, 0x8b, 0xdb, 0x8b, 0xc4, 0x9c, + 0xcd, 0xa6, 0xbd, 0xb0, 0xcf, 0xc3, 0xb0, 0xcd, 0x8b, 0x08, 0x0e, 0x92, + 0xfb, 0x69, 0x15, 0xdf, 0x8b, 0xc7, 0xf7, 0xad, 0x05, 0xaa, 0x4a, 0xb4, + 0x71, 0xd2, 0x8b, 0xd9, 0x8b, 0xd6, 0xaf, 0xbe, 0xca, 0xc1, 0xcd, 0xad, + 0xf3, 0x8b, 0xed, 0x8b, 0xf7, 0x0c, 0x48, 0xd6, 0x20, 0x8b, 0x3f, 0x8b, + 0x3f, 0x62, 0x6d, 0x51, 0x08, 0xc8, 0xf7, 0xb5, 0x37, 0x8b, 0xfb, 0x5c, + 0xfe, 0x42, 0x05, 0xf8, 0x08, 0xf9, 0x37, 0x15, 0xd6, 0xb7, 0x57, 0x35, + 0x1f, 0x8b, 0x55, 0x7a, 0x4a, 0x70, 0x59, 0x66, 0x47, 0x59, 0x6a, 0x4a, + 0x8b, 0x42, 0x8b, 0x5d, 0xbd, 0x8b, 0xdb, 0x8b, 0xc7, 0x9c, 0xcc, 0xa9, + 0xbf, 0xb0, 0xce, 0xbd, 0xad, 0xc9, 0x8b, 0x08, 0x0e, 0xf7, 0x63, 0xf8, + 0x89, 0xf8, 0xa0, 0x15, 0xfb, 0x7d, 0xfc, 0x2b, 0x5d, 0xf8, 0x2b, 0x31, + 0x8b, 0xcf, 0xfc, 0xa4, 0x57, 0x3a, 0x05, 0x70, 0x61, 0x7d, 0x82, 0x67, + 0x8b, 0x08, 0x7f, 0x8b, 0x81, 0x8b, 0x05, 0x89, 0x8b, 0x85, 0x8c, 0x82, + 0x8c, 0x08, 0x83, 0x8c, 0x7b, 0x40, 0x05, 0x9d, 0x83, 0x97, 0x89, 0x9f, + 0x8b, 0xd1, 0x8b, 0xbd, 0xac, 0xb7, 0xd6, 0x08, 0xf8, 0x04, 0xf9, 0x0e, + 0x32, 0x8b, 0x05, 0xfb, 0x15, 0xf7, 0x53, 0x15, 0x23, 0x8b, 0x75, 0x24, + 0xf2, 0x8b, 0xa2, 0xf2, 0x05, 0xf7, 0x35, 0x16, 0x23, 0x8b, 0x75, 0x24, + 0xf2, 0x8b, 0xa2, 0xf2, 0x05, 0x0e, 0xba, 0xf7, 0xcd, 0x15, 0x68, 0x50, + 0xdf, 0x8b, 0x05, 0x8a, 0x80, 0x8b, 0x7c, 0x8b, 0x88, 0x8b, 0xfb, 0x37, + 0xcf, 0x37, 0xf7, 0x17, 0x8b, 0xc9, 0x8b, 0xc6, 0x9a, 0xc4, 0xaa, 0x08, + 0x9f, 0xe8, 0x05, 0x30, 0x5b, 0x64, 0x7e, 0x5a, 0x8b, 0x08, 0x37, 0x60, + 0xc9, 0xf7, 0x0e, 0x1f, 0x99, 0xf7, 0x6b, 0x07, 0xaf, 0xc6, 0xfb, 0x8a, + 0x8b, 0x05, 0x8e, 0xa0, 0x91, 0xa6, 0x91, 0x9d, 0x08, 0xf7, 0xa2, 0x8b, + 0xaf, 0xc6, 0xfb, 0xb1, 0x8b, 0x05, 0xc7, 0xf7, 0x1d, 0xc9, 0xc5, 0xe2, + 0x8b, 0xbf, 0x8b, 0xb1, 0x79, 0xc8, 0x56, 0x08, 0xbc, 0xdb, 0x05, 0x53, + 0xba, 0x56, 0x9f, 0x46, 0x8b, 0x35, 0x8b, 0x42, 0x69, 0x4f, 0x48, 0x5f, + 0x5a, 0x6a, 0x53, 0x72, 0x4a, 0x08, 0x4c, 0x8b, 0x68, 0x50, 0xda, 0x8b, + 0x05, 0x84, 0x74, 0x85, 0x72, 0x88, 0x79, 0x08, 0x54, 0x06, 0x0e, 0xb3, + 0xf7, 0xa6, 0xf8, 0xd8, 0x15, 0x4c, 0xfb, 0xbc, 0xcb, 0x8b, 0xe5, 0xf8, + 0x3d, 0x5f, 0x8b, 0x05, 0x6a, 0x4a, 0x81, 0x85, 0x30, 0x7f, 0x08, 0x81, + 0x5d, 0xec, 0x8b, 0x05, 0x0e, 0xb3, 0xf8, 0x14, 0xf7, 0xec, 0x15, 0xfb, + 0x7b, 0x06, 0x9e, 0xaa, 0xa1, 0x9c, 0xc1, 0xa6, 0x08, 0xcf, 0xac, 0x05, + 0xde, 0xb4, 0xb4, 0xbd, 0x8b, 0xc7, 0x8b, 0xcc, 0x5b, 0xb4, 0x40, 0x8b, + 0x28, 0x8b, 0x54, 0x5c, 0x73, 0x20, 0x08, 0xca, 0x06, 0x9c, 0xd0, 0xab, + 0xa9, 0xc3, 0x8b, 0xb4, 0x8b, 0xa6, 0x73, 0x8b, 0x67, 0x8b, 0x68, 0x6f, + 0x69, 0x5c, 0x75, 0x08, 0x4c, 0x6c, 0x05, 0xfb, 0x02, 0x53, 0x70, 0x6c, + 0x6f, 0x26, 0x08, 0xf7, 0xc0, 0x8b, 0x97, 0xc7, 0x05, 0x0e, 0xb3, 0xf7, + 0x78, 0xf8, 0x6e, 0x15, 0x9b, 0x8c, 0x93, 0x8b, 0x92, 0x8b, 0x08, 0xbc, + 0xa8, 0x79, 0x6b, 0x4f, 0x5f, 0x63, 0x4a, 0x62, 0x70, 0xa1, 0xad, 0x1f, + 0x8b, 0x91, 0x8b, 0x91, 0x8c, 0x94, 0x08, 0x8c, 0x97, 0x4b, 0x8b, 0x05, + 0x89, 0x75, 0x8a, 0x82, 0x8b, 0x81, 0x08, 0x49, 0xb7, 0x66, 0xdb, 0xf3, + 0xda, 0xd1, 0xe9, 0x1e, 0x8b, 0xac, 0x7e, 0xa1, 0x6c, 0x9a, 0x08, 0xbd, + 0xaa, 0x9e, 0xab, 0x8b, 0xbe, 0x8b, 0xc2, 0x5d, 0xaf, 0x44, 0x8b, 0x57, + 0x8b, 0x5f, 0x79, 0x6c, 0x69, 0x77, 0x76, 0x81, 0x74, 0x7e, 0x5b, 0x08, + 0xca, 0x06, 0x92, 0xaa, 0x90, 0x97, 0x94, 0x96, 0x9c, 0xa2, 0xa6, 0x97, + 0xab, 0x8b, 0x08, 0xb1, 0xa3, 0x79, 0x6d, 0x55, 0x69, 0x72, 0x42, 0x1f, + 0x87, 0x8b, 0x7f, 0x8b, 0x05, 0x80, 0x56, 0x05, 0x0e, 0x7c, 0xf7, 0xb9, + 0xf7, 0xbb, 0x15, 0x22, 0x8b, 0x75, 0x24, 0xf4, 0x8b, 0xa1, 0xf2, 0x05, + 0x0e, 0xb3, 0xf7, 0xf3, 0xf7, 0xcc, 0x15, 0xfb, 0x83, 0x8b, 0x7c, 0x43, + 0xf7, 0x83, 0x8b, 0x9a, 0xd3, 0x05, 0x0e, 0xf6, 0xf7, 0x88, 0xf9, 0x42, + 0x15, 0x38, 0x47, 0x47, 0x38, 0x38, 0xcf, 0x46, 0xdd, 0xe0, 0xcf, 0xce, + 0xe0, 0xde, 0x47, 0xcf, 0x37, 0x1f, 0x8c, 0x60, 0x15, 0xc5, 0xbb, 0x5a, + 0x50, 0x4e, 0x5b, 0x5b, 0x4f, 0x52, 0x5b, 0xbd, 0xc6, 0xc6, 0xbb, 0xbc, + 0xc6, 0x1f, 0x0e, 0xf7, 0xb7, 0xf8, 0xed, 0xf7, 0xa1, 0x15, 0xfc, 0x8d, + 0x8b, 0x7c, 0x43, 0xf8, 0x8d, 0x8b, 0x9a, 0xd3, 0x05, 0x0e, 0xf7, 0xb7, + 0xf8, 0xa5, 0xf8, 0x3f, 0x15, 0xfb, 0x46, 0xfb, 0x26, 0xfb, 0x07, 0xf7, + 0x25, 0x4f, 0x5a, 0xf7, 0x07, 0xfb, 0x26, 0xfb, 0x46, 0xfb, 0x27, 0xb2, + 0x5a, 0xf7, 0x46, 0xf7, 0x26, 0xf7, 0x08, 0xfb, 0x27, 0xc8, 0xbd, 0xfb, + 0x09, 0xf7, 0x27, 0xf7, 0x46, 0xf7, 0x26, 0x64, 0xbd, 0x05, 0x0e, 0xf7, + 0xb7, 0xf8, 0xe3, 0xf7, 0xa1, 0x15, 0xfc, 0x78, 0x8b, 0x7c, 0x43, 0xf8, + 0x78, 0x8b, 0x05, 0x9a, 0xd3, 0x05, 0xfb, 0xb2, 0xfb, 0x39, 0x15, 0x6f, + 0x73, 0x73, 0x6f, 0x6f, 0xa3, 0x73, 0xa7, 0xa7, 0xa3, 0xa3, 0xa6, 0xa9, + 0x74, 0xa2, 0x6e, 0x1f, 0xd5, 0xf7, 0xfa, 0x15, 0x6e, 0x74, 0x74, 0x6e, + 0x6f, 0xa3, 0x73, 0xa7, 0xa7, 0xa3, 0xa3, 0xa6, 0x1f, 0xa9, 0x74, 0xa2, + 0x6e, 0x1e, 0x0e, 0xf9, 0x57, 0xf8, 0x42, 0xf9, 0x36, 0x15, 0xf7, 0x2d, + 0x8b, 0x96, 0xc2, 0xfc, 0x0a, 0x8b, 0x7f, 0x54, 0xf7, 0x2e, 0x8b, 0x3a, + 0xfc, 0x12, 0xcf, 0x8b, 0xdc, 0xf8, 0x12, 0x05, 0xf8, 0x14, 0xfc, 0x12, + 0x15, 0xf7, 0x57, 0xf7, 0xe9, 0x42, 0xfb, 0xe9, 0xce, 0x8b, 0xe8, 0xf8, + 0x49, 0x31, 0x8b, 0xfb, 0x65, 0xfb, 0xfe, 0x54, 0xf7, 0xfe, 0x2d, 0x8b, + 0x2e, 0xfc, 0x49, 0xce, 0x8b, 0xd4, 0xf7, 0xe9, 0xbb, 0xfb, 0xe9, 0xd2, + 0x8b, 0x05, 0x0e, 0xf7, 0xb7, 0xf9, 0x05, 0xf8, 0x41, 0x15, 0xfb, 0x63, + 0x8b, 0xb7, 0xf7, 0x60, 0x44, 0x8b, 0x60, 0xfb, 0x60, 0xfb, 0x63, 0x8b, + 0x7c, 0x43, 0xf7, 0x63, 0x8b, 0x5e, 0xfb, 0x64, 0xd2, 0x8b, 0xb7, 0xf7, + 0x64, 0xf7, 0x63, 0x8b, 0x9a, 0xd3, 0x05, 0x3f, 0xfb, 0xf9, 0x15, 0xfc, + 0x78, 0x8b, 0x7c, 0x43, 0xf8, 0x78, 0x8b, 0x9a, 0xd3, 0x05, 0x0e, 0xf8, + 0xb1, 0xf7, 0x8a, 0xf8, 0xd8, 0x15, 0x4c, 0xfb, 0xbc, 0xcb, 0x8b, 0xe5, + 0xf8, 0x3d, 0x5f, 0x8b, 0x05, 0x6a, 0x4a, 0x81, 0x85, 0x30, 0x7f, 0x08, + 0x81, 0x5d, 0xec, 0x8b, 0x05, 0xf8, 0x8e, 0xf7, 0x15, 0x15, 0xfc, 0xf2, + 0xfd, 0x6d, 0xc5, 0x8b, 0xf8, 0xf2, 0xf9, 0x6d, 0x51, 0x8b, 0x05, 0xf0, + 0xfd, 0x1d, 0x15, 0xfb, 0x7b, 0x06, 0x9e, 0xaa, 0xa1, 0x9c, 0xc1, 0xa6, + 0x08, 0xcf, 0xac, 0x05, 0xde, 0xb4, 0xb4, 0xbd, 0x8b, 0xc7, 0x8b, 0xcc, + 0x5b, 0xb4, 0x40, 0x8b, 0x28, 0x8b, 0x54, 0x5c, 0x73, 0x20, 0x08, 0xca, + 0x06, 0x9c, 0xd0, 0xab, 0xa9, 0xc3, 0x8b, 0xb4, 0x8b, 0xa6, 0x73, 0x8b, + 0x67, 0x8b, 0x68, 0x6f, 0x69, 0x5c, 0x75, 0x08, 0x4c, 0x6c, 0x05, 0xfb, + 0x02, 0x53, 0x70, 0x6c, 0x6f, 0x26, 0x08, 0xf7, 0xc0, 0x8b, 0x97, 0xc7, + 0x05, 0x0e, 0xf8, 0xb1, 0xf7, 0x56, 0xf8, 0xd8, 0x15, 0x4c, 0xfb, 0xbc, + 0xcb, 0x8b, 0xe5, 0xf8, 0x3d, 0x5f, 0x8b, 0x05, 0x6a, 0x4a, 0x81, 0x85, + 0x30, 0x7f, 0x08, 0x81, 0x5d, 0xec, 0x8b, 0x05, 0xf8, 0x98, 0xf7, 0x15, + 0x15, 0xfc, 0xf2, 0xfd, 0x6d, 0xc5, 0x8b, 0xf8, 0xf2, 0xf9, 0x6d, 0x51, + 0x8b, 0x05, 0x77, 0xfc, 0xf5, 0x15, 0x76, 0x27, 0xca, 0x8b, 0xa0, 0xef, + 0xcc, 0x8b, 0x97, 0xc2, 0x4a, 0x8b, 0xc4, 0xf7, 0xa2, 0x5c, 0x8b, 0xfb, + 0x94, 0xfb, 0x9d, 0x7e, 0x4f, 0xf7, 0x4c, 0x8b, 0x05, 0x97, 0xc2, 0x15, + 0xfb, 0x0e, 0x8b, 0xf7, 0x30, 0xf7, 0x35, 0x69, 0xfb, 0x35, 0x05, 0x0e, + 0xf8, 0xb1, 0xf7, 0x2b, 0xf8, 0x6e, 0x15, 0x9b, 0x8c, 0x93, 0x8b, 0x92, + 0x8b, 0x08, 0xbc, 0xa8, 0x79, 0x6b, 0x4f, 0x5f, 0x63, 0x4a, 0x62, 0x70, + 0xa1, 0xad, 0x1f, 0x8b, 0x91, 0x8b, 0x91, 0x8c, 0x94, 0x08, 0x8c, 0x97, + 0x4b, 0x8b, 0x05, 0x89, 0x75, 0x8a, 0x82, 0x8b, 0x81, 0x08, 0x49, 0xb7, + 0x66, 0xdb, 0xf3, 0xda, 0xd1, 0xe9, 0x1e, 0x8b, 0xac, 0x7e, 0xa1, 0x6c, + 0x9a, 0x08, 0xbd, 0xaa, 0x9e, 0xab, 0x8b, 0xbe, 0x8b, 0xc2, 0x5d, 0xaf, + 0x44, 0x8b, 0x57, 0x8b, 0x5f, 0x79, 0x6c, 0x69, 0x77, 0x76, 0x81, 0x74, + 0x7e, 0x5b, 0x08, 0xca, 0x06, 0x92, 0xaa, 0x90, 0x97, 0x94, 0x96, 0x9c, + 0xa2, 0xa6, 0x97, 0xab, 0x8b, 0x08, 0xb1, 0xa3, 0x79, 0x6d, 0x55, 0x69, + 0x72, 0x42, 0x1f, 0x87, 0x8b, 0x7f, 0x8b, 0x05, 0x80, 0x56, 0x05, 0xf8, + 0xda, 0xf7, 0x7f, 0x15, 0xfc, 0xf2, 0xfd, 0x6d, 0xc5, 0x8b, 0xf8, 0xf2, + 0xf9, 0x6d, 0x51, 0x8b, 0x05, 0x63, 0xfc, 0xf5, 0x15, 0x76, 0x27, 0xca, + 0x8b, 0xa0, 0xef, 0xcc, 0x8b, 0x97, 0xc2, 0x4a, 0x8b, 0xc4, 0xf7, 0xa2, + 0x5c, 0x8b, 0xfb, 0x94, 0xfb, 0x9d, 0x7e, 0x4f, 0xf7, 0x4c, 0x8b, 0x05, + 0x97, 0xc2, 0x15, 0xfb, 0x0e, 0x8b, 0xf7, 0x30, 0xf7, 0x35, 0x69, 0xfb, + 0x35, 0x05, 0x0e, 0xf8, 0x50, 0xf9, 0x11, 0xf8, 0x49, 0x15, 0x89, 0xf5, + 0x61, 0xbc, 0x31, 0x8b, 0x47, 0x8b, 0x4e, 0x6d, 0x5b, 0x53, 0x5b, 0x51, + 0x6e, 0x3a, 0x8b, 0x40, 0x8b, 0x24, 0xc4, 0x4c, 0xe9, 0x8b, 0xc6, 0x8b, + 0xbd, 0xa2, 0xb6, 0xba, 0xa5, 0xa7, 0x9b, 0xa6, 0xa3, 0xc8, 0x08, 0x44, + 0x06, 0x6d, 0x3a, 0x5d, 0x60, 0x54, 0x8b, 0x52, 0x8b, 0x65, 0xb9, 0x8b, + 0xce, 0x8b, 0xc0, 0x9c, 0xc6, 0xa7, 0xb6, 0xab, 0xbb, 0xb5, 0xa5, 0xbb, + 0x8b, 0xbf, 0x8b, 0xa2, 0x70, 0x8e, 0x49, 0x08, 0xd2, 0x06, 0x20, 0xf7, + 0xc5, 0x15, 0xfb, 0x8a, 0xfb, 0x79, 0xfb, 0x72, 0xfb, 0x83, 0xfb, 0x43, + 0xf7, 0x15, 0xfb, 0x14, 0xf7, 0x45, 0xf7, 0x8a, 0xf7, 0x79, 0xf7, 0x72, + 0xf7, 0x84, 0xf7, 0x42, 0xfb, 0x15, 0xf7, 0x14, 0xfb, 0x45, 0x1f, 0x7d, + 0x4d, 0x15, 0xf7, 0x24, 0xf5, 0x20, 0xfb, 0x25, 0xfb, 0x5d, 0xfb, 0x51, + 0xfb, 0x4f, 0xfb, 0x5e, 0xfb, 0x24, 0x21, 0xf6, 0xf7, 0x26, 0xf7, 0x5c, + 0xf7, 0x51, 0xf7, 0x4f, 0xf7, 0x5e, 0x1f, 0x0e, 0xf8, 0x50, 0xf7, 0xe9, + 0xf7, 0xd9, 0x15, 0xf7, 0x1a, 0x06, 0xaf, 0x9d, 0x7e, 0x70, 0x1f, 0x8b, + 0x82, 0x89, 0x7f, 0x89, 0x80, 0x08, 0x7d, 0x53, 0x8a, 0x88, 0x8b, 0x71, + 0x8b, 0x81, 0x8c, 0x85, 0x8e, 0x7f, 0x08, 0xd9, 0x8b, 0x90, 0xa4, 0x05, + 0x82, 0x93, 0x88, 0x92, 0x8b, 0x99, 0x8b, 0x96, 0x8d, 0x96, 0x90, 0xab, + 0x08, 0x91, 0xa8, 0x8d, 0x9c, 0x8b, 0x95, 0x8b, 0xa6, 0x85, 0x96, 0x74, + 0x9d, 0xae, 0xa0, 0x9a, 0x99, 0x97, 0xa2, 0x08, 0x96, 0xa1, 0x92, 0xa9, + 0x8b, 0xa5, 0x08, 0xc8, 0x65, 0xa7, 0x3a, 0x1e, 0xfb, 0x62, 0x8b, 0x2d, + 0xfc, 0x51, 0xd1, 0x8b, 0x05, 0xb2, 0xf7, 0x4d, 0x05, 0x99, 0xca, 0x15, + 0xa7, 0xf7, 0x1a, 0xf7, 0x15, 0x8b, 0x05, 0xb7, 0x9e, 0x7e, 0x6a, 0x1f, + 0x8b, 0x76, 0x83, 0x73, 0x80, 0x7c, 0x7b, 0x77, 0x76, 0x83, 0x68, 0x8b, + 0x08, 0xfb, 0x15, 0x06, 0xf7, 0x43, 0xf7, 0xf6, 0x15, 0xfb, 0x8a, 0xfb, + 0x79, 0xfb, 0x72, 0xfb, 0x83, 0xfb, 0x43, 0xf7, 0x15, 0xfb, 0x14, 0xf7, + 0x45, 0xf7, 0x8a, 0xf7, 0x79, 0xf7, 0x72, 0xf7, 0x84, 0xf7, 0x42, 0xfb, + 0x15, 0xf7, 0x14, 0xfb, 0x45, 0x1f, 0x7d, 0x4d, 0x15, 0xf7, 0x24, 0xf5, + 0x20, 0xfb, 0x25, 0xfb, 0x5d, 0xfb, 0x51, 0xfb, 0x4f, 0xfb, 0x5e, 0xfb, + 0x24, 0x21, 0xf6, 0xf7, 0x26, 0xf7, 0x5c, 0xf7, 0x51, 0xf7, 0x4f, 0xf7, + 0x5e, 0x1f, 0x0e, 0x7c, 0x0e, 0xf7, 0xb7, 0xf7, 0x06, 0xf8, 0x0d, 0x15, + 0x7c, 0x43, 0xf8, 0x47, 0x8b, 0x5d, 0xfb, 0x6f, 0xd1, 0x8b, 0xc8, 0xf7, + 0xb7, 0xfc, 0x8d, 0x8b, 0x05, 0x0e, 0x6a, 0xf7, 0x93, 0xf9, 0x6d, 0x15, + 0x35, 0xfc, 0x25, 0xc7, 0x8b, 0xe1, 0xf8, 0x25, 0x4f, 0x8b, 0x05, 0xfb, + 0x07, 0xfc, 0xb0, 0x15, 0x35, 0xfc, 0x25, 0xc7, 0x8b, 0xe1, 0xf8, 0x25, + 0x4f, 0x8b, 0x05, 0x0e, 0xf8, 0xbe, 0xbc, 0x15, 0x83, 0x89, 0x88, 0x8a, + 0x85, 0x8b, 0x72, 0x8b, 0x7e, 0x96, 0x8b, 0x9f, 0x8b, 0x8f, 0x8b, 0x8f, + 0x8c, 0x8e, 0x08, 0xe8, 0xf8, 0x48, 0x37, 0x8b, 0x4c, 0xfb, 0xbd, 0x05, + 0x74, 0x20, 0x44, 0x45, 0x35, 0x8b, 0x56, 0x8b, 0x6a, 0xa9, 0x8b, 0xbd, + 0x8b, 0x96, 0x8c, 0x94, 0x8d, 0x95, 0x08, 0xd8, 0xf8, 0x00, 0x37, 0x8b, + 0xfb, 0x32, 0xfd, 0x7c, 0xdf, 0x8b, 0xbb, 0xf7, 0x76, 0x05, 0xa0, 0x76, + 0xa2, 0x83, 0xb0, 0x8b, 0xd0, 0x8b, 0xc7, 0xa6, 0xc1, 0xc3, 0x89, 0x83, + 0x8a, 0x84, 0x8b, 0x87, 0x8b, 0x5d, 0xa0, 0x79, 0xc1, 0x8b, 0x98, 0x8b, + 0x91, 0x8c, 0xa1, 0x90, 0x8d, 0x8c, 0x90, 0x8c, 0x91, 0x8c, 0x08, 0x99, + 0xca, 0x05, 0x0e, 0xf8, 0xc0, 0x14, 0xf7, 0xb9, 0x15, 0x74, 0xa2, 0xf8, + 0xa0, 0x9a, 0xf7, 0x52, 0x97, 0x54, 0xa2, 0x06, 0x1e, 0x0a, 0x03, 0x96, + 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xd9, 0x0a, 0xcf, 0x90, 0x90, + 0x90, 0x0c, 0x0c, 0xe3, 0x0b, 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00, 0x00 +}; +const unsigned int fonts_NimbusSanL_ReguItal_cff_len = 20160; diff --git a/rosapps/smartpdf/fitz/fonts/StandardSymL.cff.c b/rosapps/smartpdf/fitz/fonts/StandardSymL.cff.c new file mode 100644 index 00000000000..8bcb17200bf --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/StandardSymL.cff.c @@ -0,0 +1,1582 @@ +const unsigned char fonts_StandardSymL_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x0d, 0x53, 0x74, 0x61, + 0x6e, 0x64, 0x61, 0x72, 0x64, 0x53, 0x79, 0x6d, 0x4c, 0x00, 0x01, 0x02, + 0x00, 0x01, 0x00, 0x39, 0xf8, 0xac, 0x00, 0xf8, 0xad, 0x01, 0xf8, 0xae, + 0x02, 0xf8, 0xaf, 0x03, 0xf8, 0x18, 0x04, 0xfb, 0x79, 0x0c, 0x03, 0xb9, + 0x0c, 0x04, 0x1d, 0x00, 0x4c, 0x9e, 0x9b, 0x0d, 0xfb, 0x48, 0xfb, 0xb9, + 0xfa, 0xd6, 0xfa, 0x86, 0x05, 0x1c, 0x06, 0x6b, 0x0f, 0x1c, 0x07, 0xe6, + 0x10, 0x1c, 0x08, 0xa5, 0x11, 0x1c, 0x00, 0x20, 0x1c, 0x49, 0xdd, 0x12, + 0x00, 0x95, 0x02, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x1d, 0x00, + 0x29, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x3e, 0x00, 0x43, 0x00, + 0x4a, 0x00, 0x4d, 0x00, 0x52, 0x00, 0x55, 0x00, 0x59, 0x00, 0x5f, 0x00, + 0x64, 0x00, 0x6a, 0x00, 0x6c, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x77, 0x00, + 0x7c, 0x00, 0x7f, 0x00, 0x84, 0x00, 0x87, 0x00, 0x8e, 0x00, 0x94, 0x00, + 0x99, 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa2, 0x00, 0xab, 0x00, 0xb8, 0x00, + 0xc1, 0x00, 0xc6, 0x00, 0xca, 0x00, 0xcd, 0x00, 0xd2, 0x00, 0xd9, 0x00, + 0xdc, 0x00, 0xe1, 0x00, 0xe4, 0x00, 0xe8, 0x00, 0xec, 0x00, 0xf1, 0x00, + 0xf7, 0x00, 0xf9, 0x01, 0x00, 0x01, 0x02, 0x01, 0x07, 0x01, 0x0a, 0x01, + 0x0f, 0x01, 0x12, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x24, 0x01, 0x26, 0x01, + 0x29, 0x01, 0x2d, 0x01, 0x34, 0x01, 0x38, 0x01, 0x40, 0x01, 0x46, 0x01, + 0x4f, 0x01, 0x57, 0x01, 0x5b, 0x01, 0x62, 0x01, 0x67, 0x01, 0x6c, 0x01, + 0x75, 0x01, 0x7e, 0x01, 0x85, 0x01, 0x8f, 0x01, 0x98, 0x01, 0x9e, 0x01, + 0xaa, 0x01, 0xb6, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd4, 0x01, 0xdf, 0x01, + 0xea, 0x01, 0xf6, 0x02, 0x04, 0x02, 0x09, 0x02, 0x11, 0x02, 0x19, 0x02, + 0x24, 0x02, 0x32, 0x02, 0x3c, 0x02, 0x44, 0x02, 0x50, 0x02, 0x55, 0x02, + 0x63, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x86, 0x02, 0x92, 0x02, 0x99, 0x02, + 0xa3, 0x02, 0xa8, 0x02, 0xb0, 0x02, 0xbd, 0x02, 0xcb, 0x02, 0xd9, 0x02, + 0xe0, 0x02, 0xe7, 0x02, 0xee, 0x02, 0xf8, 0x03, 0x01, 0x03, 0x0d, 0x03, + 0x19, 0x03, 0x23, 0x03, 0x30, 0x03, 0x3c, 0x03, 0x43, 0x03, 0x4c, 0x03, + 0x58, 0x03, 0x65, 0x03, 0x72, 0x03, 0x7b, 0x03, 0x86, 0x03, 0x91, 0x03, + 0x9c, 0x03, 0xa9, 0x03, 0xb6, 0x03, 0xc3, 0x03, 0xce, 0x03, 0xda, 0x03, + 0xe5, 0x03, 0xec, 0x03, 0xf6, 0x03, 0xfe, 0x04, 0x08, 0x04, 0x12, 0x04, + 0x1c, 0x04, 0x28, 0x04, 0x34, 0x04, 0x40, 0x04, 0x4e, 0x04, 0x5c, 0x04, + 0x6a, 0x04, 0x76, 0x04, 0x83, 0x04, 0x8f, 0x04, 0x96, 0x04, 0xc3, 0x04, + 0xd5, 0x04, 0xe7, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x75, 0x63, 0x68, 0x74, 0x68, 0x61, 0x74, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x69, 0x73, 0x6b, 0x6d, 0x61, 0x74, 0x68, 0x63, 0x6f, 0x6e, 0x67, 0x72, + 0x75, 0x65, 0x6e, 0x74, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x42, 0x65, 0x74, + 0x61, 0x43, 0x68, 0x69, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x45, 0x70, 0x73, + 0x69, 0x6c, 0x6f, 0x6e, 0x50, 0x68, 0x69, 0x47, 0x61, 0x6d, 0x6d, 0x61, + 0x45, 0x74, 0x61, 0x49, 0x6f, 0x74, 0x61, 0x74, 0x68, 0x65, 0x74, 0x61, + 0x31, 0x4b, 0x61, 0x70, 0x70, 0x61, 0x4c, 0x61, 0x6d, 0x62, 0x64, 0x61, + 0x4d, 0x75, 0x4e, 0x75, 0x4f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x50, + 0x69, 0x54, 0x68, 0x65, 0x74, 0x61, 0x52, 0x68, 0x6f, 0x53, 0x69, 0x67, + 0x6d, 0x61, 0x54, 0x61, 0x75, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, + 0x73, 0x69, 0x67, 0x6d, 0x61, 0x31, 0x4f, 0x6d, 0x65, 0x67, 0x61, 0x58, + 0x69, 0x50, 0x73, 0x69, 0x5a, 0x65, 0x74, 0x61, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x70, 0x65, 0x72, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x72, 0x61, 0x64, 0x69, 0x63, 0x61, + 0x6c, 0x65, 0x78, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x65, 0x74, 0x61, + 0x63, 0x68, 0x69, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x65, 0x70, 0x73, 0x69, + 0x6c, 0x6f, 0x6e, 0x70, 0x68, 0x69, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x65, + 0x74, 0x61, 0x69, 0x6f, 0x74, 0x61, 0x70, 0x68, 0x69, 0x31, 0x6b, 0x61, + 0x70, 0x70, 0x61, 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x6e, 0x75, 0x6f, + 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x70, 0x69, 0x74, 0x68, 0x65, 0x74, + 0x61, 0x72, 0x68, 0x6f, 0x73, 0x69, 0x67, 0x6d, 0x61, 0x74, 0x61, 0x75, + 0x75, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x6f, 0x6d, 0x65, 0x67, 0x61, + 0x31, 0x6f, 0x6d, 0x65, 0x67, 0x61, 0x78, 0x69, 0x70, 0x73, 0x69, 0x7a, + 0x65, 0x74, 0x61, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x45, 0x75, + 0x72, 0x6f, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x31, 0x6d, 0x69, + 0x6e, 0x75, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x65, 0x71, 0x75, 0x61, + 0x6c, 0x69, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x63, 0x6c, 0x75, + 0x62, 0x64, 0x69, 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x68, 0x65, 0x61, 0x72, + 0x74, 0x73, 0x70, 0x61, 0x64, 0x65, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x62, + 0x6f, 0x74, 0x68, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x6c, 0x65, 0x66, 0x74, + 0x61, 0x72, 0x72, 0x6f, 0x77, 0x75, 0x70, 0x61, 0x72, 0x72, 0x6f, 0x77, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x6f, + 0x77, 0x6e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x67, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x72, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x70, + 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x64, 0x69, 0x66, 0x66, 0x6e, 0x6f, 0x74, 0x65, 0x71, + 0x75, 0x61, 0x6c, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, + 0x63, 0x65, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x65, 0x71, 0x75, 0x61, + 0x6c, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x61, 0x72, 0x72, 0x6f, 0x77, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x78, + 0x63, 0x61, 0x72, 0x72, 0x69, 0x61, 0x67, 0x65, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x61, 0x6c, 0x65, 0x70, 0x68, 0x49, 0x66, 0x72, 0x61, 0x6b, + 0x74, 0x75, 0x72, 0x52, 0x66, 0x72, 0x61, 0x6b, 0x74, 0x75, 0x72, 0x77, + 0x65, 0x69, 0x65, 0x72, 0x73, 0x74, 0x72, 0x61, 0x73, 0x73, 0x63, 0x69, + 0x72, 0x63, 0x6c, 0x65, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, + 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x70, 0x6c, 0x75, 0x73, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x73, 0x65, 0x74, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x75, 0x70, 0x65, 0x72, 0x73, 0x65, + 0x74, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x78, 0x73, 0x75, 0x70, 0x65, 0x72, + 0x73, 0x65, 0x74, 0x6e, 0x6f, 0x74, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, + 0x72, 0x65, 0x66, 0x6c, 0x65, 0x78, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x67, 0x72, + 0x61, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x69, 0x66, 0x63, 0x6f, 0x70, 0x79, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x65, 0x72, 0x69, 0x66, 0x74, 0x72, 0x61, + 0x64, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x65, 0x72, 0x69, 0x66, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x72, 0x61, 0x64, 0x69, 0x63, 0x61, + 0x6c, 0x64, 0x6f, 0x74, 0x6d, 0x61, 0x74, 0x68, 0x6c, 0x6f, 0x67, 0x69, + 0x63, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, + 0x6c, 0x6f, 0x72, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x62, + 0x6f, 0x74, 0x68, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x6c, + 0x65, 0x66, 0x74, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x75, + 0x70, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x64, 0x6f, + 0x77, 0x6e, 0x6c, 0x6f, 0x7a, 0x65, 0x6e, 0x67, 0x65, 0x61, 0x6e, 0x67, + 0x6c, 0x65, 0x6c, 0x65, 0x66, 0x74, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x73, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x61, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x64, 0x65, + 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x61, 0x6e, 0x73, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x6c, 0x65, + 0x66, 0x74, 0x74, 0x70, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x6c, 0x65, 0x66, + 0x74, 0x65, 0x78, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x6c, 0x65, 0x66, 0x74, + 0x62, 0x74, 0x62, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x6c, 0x65, 0x66, + 0x74, 0x74, 0x70, 0x62, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x6c, 0x65, + 0x66, 0x74, 0x65, 0x78, 0x62, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x6c, + 0x65, 0x66, 0x74, 0x62, 0x74, 0x62, 0x72, 0x61, 0x63, 0x65, 0x6c, 0x65, + 0x66, 0x74, 0x74, 0x70, 0x62, 0x72, 0x61, 0x63, 0x65, 0x6c, 0x65, 0x66, + 0x74, 0x6d, 0x69, 0x64, 0x62, 0x72, 0x61, 0x63, 0x65, 0x6c, 0x65, 0x66, + 0x74, 0x62, 0x74, 0x62, 0x72, 0x61, 0x63, 0x65, 0x65, 0x78, 0x61, 0x6e, + 0x67, 0x6c, 0x65, 0x72, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x6c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, + 0x74, 0x70, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 0x65, 0x78, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 0x62, 0x74, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x72, 0x69, 0x67, 0x68, 0x74, 0x74, 0x70, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x72, 0x69, 0x67, 0x68, 0x74, 0x65, 0x78, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x72, 0x69, 0x67, 0x68, 0x74, 0x62, 0x74, 0x62, 0x72, + 0x61, 0x63, 0x6b, 0x65, 0x74, 0x72, 0x69, 0x67, 0x68, 0x74, 0x74, 0x70, + 0x62, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x65, 0x78, 0x62, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x62, 0x74, 0x62, 0x72, 0x61, 0x63, 0x65, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x74, 0x70, 0x62, 0x72, 0x61, 0x63, 0x65, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x6d, 0x69, 0x64, 0x62, 0x72, 0x61, 0x63, 0x65, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x62, 0x74, 0x30, 0x30, 0x31, 0x2e, 0x30, 0x30, 0x35, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x55, 0x52, + 0x57, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, + 0x39, 0x37, 0x20, 0x62, 0x79, 0x20, 0x55, 0x52, 0x57, 0x53, 0x74, 0x61, + 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x73, 0x20, 0x4c, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, + 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x20, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0x01, 0x87, 0x00, 0x04, 0x01, 0x88, 0x00, 0x06, + 0x00, 0x07, 0x01, 0x89, 0x00, 0x09, 0x00, 0x0a, 0x01, 0x8a, 0x00, 0x0c, + 0x00, 0x0d, 0x00, 0xa6, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, + 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, + 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, + 0x00, 0x1f, 0x00, 0x20, 0x01, 0x8b, 0x01, 0x8c, 0x01, 0x8d, 0x01, 0x8e, + 0x01, 0x8f, 0x01, 0x90, 0x01, 0x91, 0x01, 0x92, 0x01, 0x93, 0x01, 0x94, + 0x01, 0x95, 0x01, 0x96, 0x01, 0x97, 0x01, 0x98, 0x01, 0x99, 0x01, 0x9a, + 0x01, 0x9b, 0x01, 0x9c, 0x01, 0x9d, 0x01, 0x9e, 0x01, 0x9f, 0x01, 0xa0, + 0x01, 0xa1, 0x01, 0xa2, 0x01, 0xa3, 0x01, 0xa4, 0x01, 0xa5, 0x00, 0x3c, + 0x01, 0xa6, 0x00, 0x3e, 0x01, 0xa7, 0x00, 0x40, 0x01, 0xa8, 0x01, 0xa9, + 0x01, 0xaa, 0x01, 0xab, 0x01, 0xac, 0x01, 0xad, 0x01, 0xae, 0x01, 0xaf, + 0x01, 0xb0, 0x01, 0xb1, 0x01, 0xb2, 0x01, 0xb3, 0x01, 0xb4, 0x00, 0x98, + 0x01, 0xb5, 0x01, 0xb6, 0x01, 0xb7, 0x01, 0xb8, 0x01, 0xb9, 0x01, 0xba, + 0x01, 0xbb, 0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, 0x01, 0xbf, 0x01, 0xc0, + 0x01, 0xc1, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x01, 0xc2, 0x01, 0xc3, + 0x01, 0xc4, 0x01, 0xc5, 0x01, 0xc6, 0x00, 0x63, 0x01, 0xc7, 0x00, 0x65, + 0x01, 0xc8, 0x01, 0xc9, 0x01, 0xca, 0x01, 0xcb, 0x01, 0xcc, 0x01, 0xcd, + 0x01, 0xce, 0x01, 0xcf, 0x01, 0xd0, 0x00, 0xa1, 0x00, 0x9c, 0x01, 0xd1, + 0x01, 0xd2, 0x00, 0xa8, 0x01, 0xd3, 0x01, 0xd4, 0x00, 0x74, 0x00, 0x9f, + 0x01, 0xd5, 0x01, 0xd6, 0x01, 0xd7, 0x00, 0x79, 0x01, 0xd8, 0x01, 0xd9, + 0x01, 0xda, 0x01, 0xdb, 0x01, 0xdc, 0x01, 0xdd, 0x01, 0xde, 0x01, 0xdf, + 0x01, 0xe0, 0x01, 0xe1, 0x01, 0xe2, 0x01, 0xe3, 0x01, 0xe4, 0x01, 0xe5, + 0x01, 0xe6, 0x01, 0xe7, 0x01, 0xe8, 0x01, 0xe9, 0x01, 0xea, 0x01, 0xeb, + 0x01, 0xec, 0x01, 0xed, 0x01, 0xee, 0x01, 0xef, 0x01, 0xf0, 0x01, 0xf1, + 0x01, 0xf2, 0x00, 0x97, 0x01, 0xf3, 0x01, 0xf4, 0x01, 0xf5, 0x01, 0xf6, + 0x01, 0xf7, 0x01, 0xf8, 0x01, 0xf9, 0x01, 0xfa, 0x01, 0xfb, 0x01, 0xfc, + 0x01, 0xfd, 0x01, 0xfe, 0x01, 0xff, 0x02, 0x00, 0x02, 0x01, 0x02, 0x02, + 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, + 0x02, 0x09, 0x02, 0x0a, 0x02, 0x0b, 0x02, 0x0c, 0x02, 0x0d, 0x02, 0x0e, + 0x02, 0x0f, 0x02, 0x10, 0x02, 0x11, 0x02, 0x12, 0x02, 0x13, 0x02, 0x14, + 0x02, 0x15, 0x02, 0x16, 0x02, 0x17, 0x00, 0xbd, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, + 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, + 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, + 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, + 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, + 0xed, 0xee, 0xef, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, 0xbe, 0x02, 0x00, 0x01, 0x00, 0x04, + 0x00, 0x07, 0x00, 0x44, 0x00, 0x74, 0x00, 0xd6, 0x00, 0xf2, 0x01, 0xb3, + 0x02, 0x79, 0x02, 0xd2, 0x03, 0x1a, 0x03, 0x61, 0x04, 0x55, 0x04, 0x70, + 0x04, 0xa0, 0x04, 0xac, 0x04, 0xc4, 0x04, 0xd9, 0x05, 0x1c, 0x05, 0x5a, + 0x05, 0xb4, 0x06, 0x26, 0x06, 0x50, 0x06, 0xaf, 0x07, 0x1d, 0x07, 0x4f, + 0x07, 0xbd, 0x08, 0x26, 0x08, 0x52, 0x08, 0x98, 0x08, 0xb5, 0x08, 0xcc, + 0x08, 0xe8, 0x09, 0x4d, 0x09, 0xa6, 0x0a, 0x02, 0x0a, 0x95, 0x0b, 0x1f, + 0x0b, 0x3e, 0x0b, 0xb7, 0x0c, 0x4d, 0x0c, 0x9f, 0x0d, 0x3f, 0x0d, 0x8f, + 0x0e, 0x47, 0x0e, 0xee, 0x0f, 0x3a, 0x0f, 0xc8, 0x10, 0x3c, 0x10, 0x91, + 0x11, 0x14, 0x11, 0x99, 0x12, 0x25, 0x12, 0x64, 0x12, 0xb1, 0x13, 0x24, + 0x13, 0xa4, 0x14, 0x30, 0x14, 0xac, 0x15, 0x52, 0x15, 0x90, 0x15, 0xb1, + 0x15, 0xf6, 0x16, 0x16, 0x16, 0x2b, 0x16, 0x39, 0x16, 0x48, 0x16, 0xd4, + 0x17, 0x65, 0x17, 0xde, 0x18, 0x5b, 0x18, 0xfa, 0x19, 0x83, 0x19, 0xea, + 0x1a, 0x4c, 0x1a, 0x98, 0x1b, 0x0a, 0x1b, 0x89, 0x1b, 0xfd, 0x1c, 0x73, + 0x1c, 0xce, 0x1d, 0x11, 0x1d, 0x94, 0x1e, 0x18, 0x1e, 0x8b, 0x1e, 0xdf, + 0x1f, 0x45, 0x1f, 0xbe, 0x20, 0x72, 0x21, 0x06, 0x21, 0xe7, 0x22, 0x63, + 0x22, 0xfa, 0x23, 0x75, 0x23, 0x83, 0x23, 0xfd, 0x24, 0x43, 0x24, 0xca, + 0x25, 0x4c, 0x25, 0x71, 0x25, 0x97, 0x25, 0xaa, 0x26, 0x1b, 0x26, 0xab, + 0x27, 0x3f, 0x27, 0x56, 0x27, 0xa7, 0x28, 0x03, 0x28, 0x57, 0x28, 0x89, + 0x28, 0xb8, 0x28, 0xe9, 0x29, 0x19, 0x29, 0x46, 0x29, 0x6b, 0x29, 0xb1, + 0x29, 0xd9, 0x2a, 0x08, 0x2a, 0x85, 0x2b, 0x04, 0x2b, 0x1d, 0x2b, 0x54, + 0x2b, 0x92, 0x2b, 0xb3, 0x2c, 0x36, 0x2c, 0x76, 0x2c, 0x84, 0x2c, 0x92, + 0x2c, 0xaf, 0x2d, 0x66, 0x2e, 0x2c, 0x2f, 0x3f, 0x30, 0x0d, 0x30, 0x86, + 0x30, 0xea, 0x31, 0x6f, 0x31, 0xaf, 0x31, 0xf0, 0x32, 0x4c, 0x32, 0xb2, + 0x33, 0x27, 0x33, 0x86, 0x33, 0xef, 0x34, 0x4e, 0x34, 0xc6, 0x34, 0xdd, + 0x34, 0xff, 0x35, 0xb5, 0x36, 0x4e, 0x36, 0xe5, 0x37, 0x77, 0x37, 0x96, + 0x37, 0xaf, 0x37, 0xc0, 0x37, 0xde, 0x37, 0xf9, 0x38, 0x8f, 0x38, 0xeb, + 0x39, 0x42, 0x39, 0xa9, 0x3a, 0x00, 0x3a, 0x2f, 0x3a, 0x4c, 0x3a, 0xe6, + 0x3b, 0x6d, 0x3b, 0xae, 0x3b, 0xed, 0x3c, 0x1f, 0x3c, 0x2c, 0x3c, 0x5e, + 0x3c, 0x6e, 0x3c, 0x7b, 0x3c, 0x8c, 0x3c, 0xb8, 0x3d, 0x02, 0x3d, 0x2f, + 0x3d, 0x3e, 0x3d, 0x5a, 0x3d, 0xd2, 0x3e, 0x17, 0x3e, 0x24, 0x3e, 0x6a, + 0x3e, 0x9f, 0x3e, 0xae, 0x3e, 0xe1, 0x3e, 0xf3, 0x3f, 0x02, 0x3f, 0x15, + 0x3f, 0x41, 0x3f, 0x8b, 0x3f, 0xb8, 0xfc, 0x45, 0x0e, 0xfc, 0x45, 0x0e, + 0xfb, 0xf2, 0xf7, 0x41, 0xf7, 0x4e, 0x15, 0xa2, 0x8b, 0xaf, 0xf7, 0xf8, + 0x05, 0x92, 0xcc, 0x8b, 0x8b, 0x8b, 0x98, 0x08, 0xb4, 0x76, 0xa4, 0x68, + 0x67, 0x78, 0x72, 0x5d, 0x1e, 0x8b, 0x7c, 0x8b, 0x86, 0x91, 0x57, 0x08, + 0xb2, 0xfb, 0xf9, 0x05, 0x97, 0x35, 0x15, 0x6c, 0x71, 0x72, 0x6c, 0x6c, + 0xa4, 0x71, 0xaa, 0xaa, 0xa4, 0xa5, 0xaa, 0xa9, 0x71, 0xa5, 0x6e, 0x1f, + 0x0e, 0xa9, 0xf9, 0x3d, 0xf9, 0x35, 0x15, 0x56, 0x8b, 0x39, 0xfb, 0x56, + 0xfc, 0x0e, 0x8b, 0x36, 0xf7, 0x56, 0x57, 0x8b, 0xf7, 0xc3, 0xfd, 0x35, + 0xc4, 0x8b, 0xf7, 0xb6, 0xf9, 0x35, 0x05, 0xfc, 0x7e, 0xfb, 0x87, 0x15, + 0xf7, 0xe2, 0x8b, 0xfb, 0x36, 0xfc, 0x01, 0xfb, 0x40, 0xf8, 0x01, 0x05, + 0x0e, 0xfb, 0x4b, 0xf8, 0x5e, 0xf7, 0x95, 0x15, 0x2d, 0x8b, 0x9e, 0xf7, + 0x16, 0xed, 0x8b, 0x05, 0xbf, 0x31, 0x07, 0xa7, 0xf7, 0x54, 0x54, 0x8b, + 0x6f, 0xfb, 0x54, 0xfb, 0x12, 0x8b, 0xa7, 0xf7, 0x54, 0x56, 0x8b, 0x05, + 0x6e, 0xfb, 0x54, 0xfb, 0x03, 0x8b, 0x05, 0x55, 0xf0, 0x07, 0x7a, 0xfb, + 0x14, 0xfb, 0x01, 0x8b, 0x8b, 0x57, 0xf0, 0x8b, 0x6c, 0xfb, 0x61, 0xc3, + 0x8b, 0xa8, 0xf7, 0x61, 0xf7, 0x12, 0x8b, 0x6d, 0xfb, 0x61, 0xc2, 0x8b, + 0xa9, 0xf7, 0x61, 0xf1, 0x8b, 0x05, 0xbf, 0x07, 0xfb, 0x16, 0xf7, 0x16, + 0x15, 0x78, 0xfb, 0x16, 0xfb, 0x11, 0x8b, 0x9d, 0xf7, 0x16, 0x05, 0xf7, + 0x12, 0x06, 0x0e, 0xf8, 0x72, 0xf9, 0x35, 0x15, 0xfc, 0x59, 0x58, 0xf8, + 0x22, 0xfb, 0x89, 0xfb, 0xf5, 0x5a, 0xf7, 0xf5, 0xfb, 0xab, 0xfc, 0x22, + 0x5a, 0xf8, 0x59, 0xf9, 0x35, 0x06, 0x0e, 0xf7, 0x2a, 0xf7, 0x7b, 0x16, + 0xf8, 0x37, 0xf9, 0x35, 0x56, 0x8b, 0x05, 0x72, 0x60, 0x54, 0x70, 0x4e, + 0x8b, 0x6c, 0x8b, 0x78, 0x92, 0x68, 0xa3, 0x08, 0x62, 0xa7, 0x79, 0x92, + 0x6d, 0x8b, 0x08, 0xfb, 0x01, 0xfb, 0x02, 0xfb, 0x0d, 0xfb, 0x0d, 0x3e, + 0xbc, 0x58, 0xd6, 0xf7, 0x00, 0xec, 0xf7, 0x0a, 0xf7, 0x17, 0x1f, 0x8b, + 0x9a, 0x8a, 0x92, 0x87, 0x9c, 0x9e, 0x84, 0xa6, 0x87, 0xa4, 0x8b, 0xad, + 0x8b, 0xa8, 0x93, 0xb2, 0x9e, 0x08, 0xfc, 0x13, 0xfc, 0xef, 0x05, 0xc1, + 0x06, 0xf7, 0x14, 0xf8, 0xe7, 0x15, 0x8f, 0x82, 0x8c, 0x83, 0x8b, 0x75, + 0x8b, 0x4d, 0x79, 0x56, 0x65, 0x5e, 0x6c, 0x65, 0x63, 0x74, 0x68, 0x8b, + 0x08, 0x65, 0x73, 0xa2, 0xaf, 0xea, 0xe2, 0xf7, 0x26, 0xc4, 0x1f, 0x8f, + 0x8b, 0x8e, 0x8b, 0x91, 0x8a, 0x9d, 0x78, 0x92, 0x86, 0xb0, 0x7c, 0x08, + 0xf7, 0xbf, 0xfb, 0x7f, 0x15, 0xfb, 0x07, 0xfb, 0x03, 0xfb, 0x0d, 0xfb, + 0x11, 0x44, 0xbf, 0x59, 0xd4, 0x1f, 0xbf, 0x8b, 0xb6, 0xa0, 0xb1, 0xb7, + 0xbd, 0xc5, 0xaa, 0xd5, 0x8b, 0xcb, 0x08, 0xca, 0x5e, 0xb6, 0x47, 0x1e, + 0x97, 0x67, 0x15, 0xb2, 0xa9, 0x6b, 0x60, 0x1f, 0x8b, 0x52, 0x6f, 0x47, + 0x61, 0x5d, 0x70, 0x6d, 0x61, 0x78, 0x67, 0x8b, 0x08, 0x69, 0x76, 0xa2, + 0xb1, 0xf3, 0xe4, 0xf7, 0x16, 0xd3, 0x1f, 0x0e, 0xea, 0xf8, 0x84, 0xf8, + 0x3e, 0x15, 0x77, 0x07, 0xb9, 0x88, 0x9d, 0x7e, 0x8b, 0x6c, 0x8b, 0x61, + 0x63, 0x3c, 0x57, 0x50, 0x6b, 0xad, 0x4e, 0xeb, 0x68, 0xd4, 0xaf, 0x9c, + 0xa0, 0x97, 0x9f, 0x99, 0xbd, 0xae, 0xa6, 0xba, 0x8b, 0xbb, 0x08, 0xd0, + 0x53, 0xbe, 0x3f, 0x37, 0x41, 0x44, 0x38, 0x1e, 0x8b, 0x5f, 0x98, 0x58, + 0xa3, 0x54, 0x48, 0x67, 0x7c, 0x82, 0x79, 0x7f, 0x48, 0x5b, 0x6a, 0x54, + 0x8b, 0x4a, 0x8b, 0x2b, 0xd2, 0x4c, 0xf6, 0x8b, 0xdb, 0x8b, 0xd2, 0xa9, + 0xc7, 0xc8, 0x08, 0xc0, 0x4f, 0xc7, 0x6c, 0xc7, 0x8b, 0xc5, 0x8b, 0xb7, + 0xac, 0xb8, 0xdb, 0x08, 0x7b, 0x98, 0x05, 0x6e, 0x64, 0x71, 0x7b, 0x6c, + 0x8b, 0x56, 0x8b, 0x5a, 0xa8, 0x56, 0xca, 0xa4, 0xa9, 0xa1, 0xaa, 0xa1, + 0xb0, 0x08, 0xbf, 0xe4, 0x05, 0x95, 0x9b, 0x93, 0x96, 0x93, 0x94, 0x9b, + 0x9d, 0xa3, 0x95, 0xad, 0x90, 0x08, 0x9f, 0x07, 0xfb, 0x6e, 0x06, 0xfb, + 0x40, 0x7e, 0x15, 0x74, 0xb9, 0x7b, 0xc3, 0x8b, 0xb0, 0x08, 0xc1, 0xa8, + 0xaf, 0xb8, 0xba, 0xac, 0x67, 0x59, 0x1e, 0x8b, 0x5a, 0x6d, 0x5b, 0x59, + 0x6f, 0x80, 0x84, 0x87, 0x89, 0x77, 0x82, 0x08, 0x47, 0x41, 0x15, 0xbd, + 0x29, 0xb9, 0x42, 0xbf, 0x4b, 0x63, 0x61, 0x5d, 0x75, 0x5b, 0x8b, 0x42, + 0x8b, 0x50, 0xcb, 0x8b, 0xda, 0x08, 0x8b, 0xcb, 0xb7, 0xc4, 0xd5, 0xae, + 0x08, 0x0e, 0xfb, 0x88, 0xbb, 0x91, 0x15, 0xad, 0x7d, 0xa5, 0x86, 0xaf, + 0x8b, 0xd2, 0x8b, 0xc8, 0xa3, 0xbf, 0xbb, 0xc1, 0xbe, 0xab, 0xd0, 0x8b, + 0xcd, 0x8b, 0xf7, 0x1c, 0xfb, 0x11, 0xf7, 0x0e, 0xfb, 0x20, 0x8b, 0x75, + 0x8b, 0x7a, 0x88, 0x6c, 0x83, 0x08, 0x66, 0x07, 0x9e, 0x8c, 0x94, 0x8c, + 0x94, 0x8b, 0xc7, 0x8b, 0xc5, 0x76, 0xae, 0x68, 0xaf, 0x67, 0x9c, 0x66, + 0x93, 0x50, 0x08, 0xfb, 0x6e, 0x5b, 0xf7, 0x6e, 0x06, 0x83, 0x53, 0x7c, + 0x6a, 0x6b, 0x67, 0x68, 0x65, 0x50, 0x73, 0x4f, 0x8b, 0x74, 0x8b, 0x75, + 0x8e, 0x6f, 0x91, 0x08, 0x66, 0x07, 0x0e, 0xfb, 0xf2, 0xf7, 0xc0, 0xfb, + 0x2f, 0x15, 0x69, 0xa2, 0x7b, 0x9a, 0x77, 0xa5, 0x55, 0xd3, 0x6c, 0xf7, + 0x11, 0x8b, 0xf7, 0x28, 0x8b, 0xf7, 0x1b, 0xa5, 0xf7, 0x0c, 0xb9, 0xd3, + 0xa1, 0xad, 0x9e, 0x9e, 0xb5, 0xa8, 0x08, 0x7e, 0x9c, 0x05, 0x5d, 0x73, + 0x77, 0x7d, 0x71, 0x73, 0x31, 0x38, 0x57, 0xfb, 0x1b, 0x8b, 0xfb, 0x26, + 0x8b, 0xfb, 0x1d, 0xb8, 0xfb, 0x12, 0xdc, 0x37, 0xa9, 0x6a, 0xa3, 0x7a, + 0xc1, 0x6e, 0x08, 0x98, 0x9c, 0x05, 0x0e, 0xfb, 0xf2, 0xb6, 0xfb, 0x40, + 0x15, 0xb9, 0xa4, 0x9f, 0x98, 0xa5, 0xa3, 0xe4, 0xde, 0xc0, 0xf7, 0x1b, + 0x8b, 0xf7, 0x26, 0x8b, 0xf7, 0x1d, 0x5d, 0xf7, 0x12, 0x3b, 0xe0, 0x6d, + 0xab, 0x73, 0x9d, 0x55, 0xa7, 0x08, 0x7e, 0x7a, 0x05, 0xae, 0x73, 0x9a, + 0x7d, 0x9f, 0x71, 0xc1, 0x43, 0xaa, 0xfb, 0x11, 0x8b, 0xfb, 0x28, 0x8b, + 0xfb, 0x1b, 0x71, 0xfb, 0x0b, 0x5d, 0x43, 0x74, 0x68, 0x78, 0x77, 0x62, + 0x6f, 0x08, 0x98, 0x7a, 0x05, 0x0e, 0xfb, 0x4b, 0xf7, 0x8a, 0xf8, 0xb6, + 0x15, 0x74, 0x7c, 0x7c, 0x76, 0x1f, 0x8b, 0x81, 0x8d, 0x83, 0x92, 0x74, + 0x9c, 0x54, 0x8d, 0x82, 0x8b, 0x77, 0x8b, 0x7d, 0x87, 0x83, 0x84, 0x8b, + 0x7a, 0x8b, 0x79, 0x9a, 0x5f, 0xbd, 0x74, 0xa5, 0x7f, 0x93, 0x7d, 0x8b, + 0x7a, 0x8b, 0x7c, 0x77, 0x8b, 0x76, 0x08, 0x8b, 0x73, 0x98, 0x82, 0xb6, + 0x81, 0xba, 0x80, 0x8b, 0x8b, 0x96, 0x87, 0x08, 0xa2, 0x81, 0x96, 0x83, + 0x8b, 0x83, 0x8b, 0x7e, 0x70, 0x7d, 0x64, 0x82, 0x75, 0x86, 0x7b, 0x88, + 0x83, 0x88, 0x73, 0x85, 0x7f, 0x7e, 0x8b, 0x79, 0x8b, 0x75, 0x9a, 0x77, + 0x9c, 0x8b, 0x99, 0x8b, 0x97, 0x93, 0xa2, 0xa5, 0x08, 0xb8, 0xbd, 0x9c, + 0x99, 0x9c, 0x8b, 0x08, 0x92, 0x8f, 0x83, 0x7d, 0x1f, 0x8b, 0x7c, 0x88, + 0x79, 0x83, 0x73, 0x7a, 0x54, 0x8b, 0x8b, 0x8b, 0x7f, 0x08, 0x76, 0x9b, + 0x7c, 0xa1, 0xa1, 0x9b, 0x9a, 0xa0, 0x1e, 0x8b, 0x95, 0x89, 0x95, 0x84, + 0xa0, 0x79, 0xc0, 0x89, 0x95, 0x8b, 0xa0, 0x8b, 0x98, 0x8f, 0x93, 0x93, + 0x8b, 0x9b, 0x8b, 0x9e, 0x7c, 0xb7, 0x5a, 0xa2, 0x71, 0x97, 0x83, 0x99, + 0x8b, 0x9b, 0x8b, 0x9b, 0x9f, 0x8b, 0xa1, 0x08, 0x8b, 0xa1, 0x7d, 0x96, + 0x61, 0x94, 0x5c, 0x96, 0x8b, 0x8b, 0x7f, 0x8f, 0x08, 0x75, 0x95, 0x7f, + 0x93, 0x8b, 0x94, 0x8b, 0x9a, 0xa4, 0x96, 0xcf, 0x9a, 0xb6, 0x94, 0x98, + 0x95, 0x8b, 0xa2, 0x8b, 0xa1, 0x7c, 0x9f, 0x7a, 0x8b, 0x7d, 0x8b, 0x7e, + 0x82, 0x75, 0x72, 0x5f, 0x5a, 0x78, 0x7b, 0x7b, 0x8b, 0x08, 0x83, 0x87, + 0x93, 0x99, 0x1f, 0x8b, 0x9c, 0x8f, 0x9e, 0x94, 0xa7, 0x9a, 0xb7, 0x8c, + 0x90, 0x8b, 0x97, 0x08, 0xa0, 0x7b, 0x9a, 0x75, 0x1e, 0x0e, 0xf7, 0xc2, + 0xf8, 0xa9, 0x15, 0x54, 0xfb, 0x83, 0xfb, 0x81, 0x54, 0xf7, 0x81, 0xfb, + 0x83, 0xc2, 0xf7, 0x83, 0xf7, 0x81, 0xc2, 0xfb, 0x81, 0xf7, 0x83, 0x06, + 0x0e, 0xfc, 0x45, 0xc3, 0xfb, 0x0c, 0x15, 0xb0, 0x8f, 0x9d, 0x92, 0xa6, + 0x9f, 0xb2, 0xa8, 0x9c, 0xab, 0x8b, 0xb6, 0x08, 0xbc, 0x69, 0xb1, 0x60, + 0x6d, 0x73, 0x72, 0x6b, 0x6b, 0xa3, 0x71, 0xa8, 0x1e, 0x94, 0x8b, 0x91, + 0x8c, 0x9a, 0x8f, 0x8d, 0x61, 0x60, 0x5e, 0x5a, 0x82, 0x08, 0x7b, 0x07, + 0x0e, 0x96, 0xf7, 0xba, 0x15, 0x54, 0xf8, 0xa0, 0xc2, 0xfc, 0xa0, 0x07, + 0x0e, 0xfc, 0x45, 0xf7, 0x12, 0xef, 0x15, 0x6c, 0x71, 0x72, 0x6c, 0x6c, + 0xa4, 0x71, 0xaa, 0xaa, 0xa4, 0xa5, 0xaa, 0xa9, 0x71, 0xa5, 0x6e, 0x1f, + 0x0e, 0xfc, 0x29, 0xf7, 0x92, 0xf9, 0x35, 0x15, 0x53, 0x8b, 0xfb, 0x5a, + 0xfd, 0x35, 0xc3, 0x8b, 0xf7, 0x5a, 0xf9, 0x35, 0x05, 0x0e, 0xfb, 0x4b, + 0xf7, 0x90, 0xf9, 0x42, 0x15, 0x34, 0x8b, 0x4c, 0x5e, 0x63, 0x2f, 0x70, + 0x4e, 0x7f, 0x47, 0x8b, 0x37, 0x08, 0xfb, 0x68, 0xe3, 0xfb, 0x1d, 0xf7, + 0x1c, 0xf7, 0x1c, 0xe3, 0xf7, 0x1d, 0xf7, 0x68, 0xf7, 0x65, 0x33, 0xf7, + 0x21, 0xfb, 0x17, 0x1e, 0x89, 0x67, 0x15, 0xe1, 0xb2, 0x2a, 0xfb, 0x6a, + 0xfb, 0x6c, 0x64, 0x2c, 0x33, 0x31, 0x64, 0xe9, 0xf7, 0x6e, 0xf7, 0x6e, + 0xb2, 0xe7, 0xe7, 0x1f, 0x0e, 0xfb, 0x4b, 0xf7, 0x09, 0xf8, 0xc3, 0x15, + 0xac, 0x99, 0x9c, 0x90, 0x97, 0x8b, 0x97, 0x8b, 0x97, 0x84, 0x8f, 0x81, + 0x90, 0x7d, 0x8b, 0x8b, 0x8c, 0x4c, 0x08, 0xfb, 0xea, 0x07, 0x8b, 0x2b, + 0x7e, 0x7b, 0x38, 0x87, 0x08, 0x71, 0xf7, 0xa5, 0xa5, 0x07, 0x37, 0x91, + 0x80, 0x98, 0x8b, 0xec, 0x08, 0xf8, 0xa7, 0x79, 0x07, 0x66, 0x74, 0x64, + 0x76, 0x37, 0x62, 0x08, 0x6e, 0x07, 0x0e, 0xfb, 0x4b, 0xa4, 0x16, 0xf8, + 0x20, 0x8b, 0xc1, 0xf7, 0x1a, 0x72, 0x8b, 0x05, 0x6c, 0x56, 0x79, 0x83, + 0x34, 0x8b, 0x08, 0xfb, 0x54, 0x06, 0xf7, 0x60, 0xf7, 0x5b, 0xd4, 0xf7, + 0x05, 0x8b, 0xf7, 0x0a, 0x8b, 0xf5, 0x41, 0xd8, 0x25, 0x8b, 0x58, 0x8b, + 0x60, 0x77, 0x69, 0x62, 0x6f, 0x6a, 0x7f, 0x6c, 0x81, 0x4e, 0x08, 0x9c, + 0x06, 0x96, 0xac, 0x93, 0x9a, 0x99, 0x9c, 0xa3, 0xa8, 0xb0, 0x9c, 0xae, + 0x8b, 0xd1, 0x8b, 0xc8, 0x46, 0x8b, 0x3c, 0x8b, 0x2c, 0x43, 0xfb, 0x12, + 0xfb, 0x12, 0xfb, 0x13, 0x08, 0x40, 0x3e, 0x73, 0x73, 0x8b, 0x7d, 0x05, + 0x0e, 0xfb, 0x4b, 0xf7, 0x50, 0xf7, 0xfd, 0x15, 0x72, 0x94, 0x07, 0xc0, + 0x8b, 0xad, 0x7d, 0xa9, 0x69, 0xa8, 0x6a, 0x9a, 0x62, 0x8b, 0x5d, 0x8b, + 0x3c, 0x5a, 0x53, 0x44, 0x8b, 0x63, 0x8b, 0x74, 0x93, 0x62, 0xa9, 0x6e, + 0xa0, 0x7c, 0x92, 0x7c, 0x8b, 0x08, 0x77, 0x7b, 0x7a, 0x77, 0x64, 0xd0, + 0x67, 0xd9, 0xf7, 0x1d, 0xf7, 0x04, 0xf3, 0xf7, 0x15, 0x1f, 0x8b, 0xd6, + 0x69, 0xbe, 0x3e, 0xb3, 0x08, 0xcf, 0xc0, 0xa7, 0xb9, 0x8b, 0xc6, 0x8b, + 0xdb, 0x49, 0xc9, 0x35, 0x8b, 0x36, 0x8b, 0x56, 0x60, 0x69, 0x29, 0x08, + 0x9a, 0x82, 0x05, 0xb0, 0xc8, 0xad, 0xa2, 0xc0, 0x8b, 0xca, 0x8b, 0xb8, + 0x5c, 0x8b, 0x49, 0x8b, 0x67, 0x7d, 0x68, 0x70, 0x70, 0x70, 0x70, 0x5f, + 0x76, 0x6b, 0x8b, 0x08, 0x80, 0x06, 0x0e, 0xfb, 0x4b, 0xf7, 0xb4, 0x16, + 0xdd, 0xf7, 0x4b, 0xee, 0xcb, 0x28, 0xf8, 0x45, 0x58, 0x06, 0xfb, 0xc3, + 0xfc, 0x45, 0x8b, 0x4b, 0xf7, 0xa4, 0x8b, 0x8b, 0xfb, 0x4b, 0x05, 0xf8, + 0xc0, 0x04, 0xfb, 0xc9, 0xfb, 0x6e, 0x07, 0xf7, 0x6e, 0xf7, 0xc9, 0x05, + 0x0e, 0xfb, 0x4b, 0xf8, 0x22, 0xf8, 0xe8, 0x15, 0xb8, 0xea, 0x7c, 0x93, + 0x05, 0x7b, 0x76, 0x81, 0x86, 0x73, 0x8b, 0x08, 0xfb, 0x4e, 0x8b, 0xfb, + 0x07, 0xfb, 0x9a, 0x05, 0xc7, 0x8a, 0xb1, 0x81, 0xb8, 0x73, 0xd8, 0x62, + 0xb8, 0x47, 0x8b, 0x41, 0x8b, 0x39, 0x50, 0x48, 0x43, 0x8b, 0x6d, 0x8b, + 0x6b, 0x96, 0x6e, 0x9e, 0x66, 0xa4, 0x86, 0x8d, 0x7c, 0x8b, 0x08, 0x78, + 0x7c, 0x7b, 0x77, 0x61, 0xc8, 0x67, 0xd3, 0xf7, 0x18, 0xf7, 0x06, 0xf7, + 0x06, 0xf7, 0x18, 0x1f, 0x8b, 0xd5, 0x6a, 0xd0, 0x4f, 0xbc, 0x64, 0xab, + 0x65, 0x9c, 0x3a, 0xa0, 0x08, 0xb7, 0xf0, 0xf7, 0x59, 0x8b, 0x05, 0x0e, + 0xfb, 0x4b, 0xf8, 0x45, 0xf9, 0x41, 0x15, 0x32, 0x8b, 0x5e, 0x81, 0x4f, + 0x67, 0xfb, 0x0e, 0x43, 0x3a, 0xfb, 0x29, 0x8b, 0xfb, 0x2d, 0x08, 0xfb, + 0x33, 0xe8, 0xfb, 0x0b, 0xf7, 0x0f, 0xf7, 0x0a, 0xed, 0xf2, 0xf7, 0x12, + 0xf7, 0x0b, 0x39, 0xdf, 0xfb, 0x07, 0x1e, 0x5e, 0x8b, 0x61, 0x7e, 0x5f, + 0x6e, 0xb1, 0xf7, 0x3a, 0xf7, 0x08, 0xf7, 0x06, 0xf7, 0x1f, 0x95, 0x08, + 0x9d, 0x07, 0xfb, 0xc3, 0xfb, 0xf2, 0x15, 0xbd, 0xa7, 0xa5, 0x93, 0xaf, + 0x8b, 0xbd, 0x8b, 0xad, 0x76, 0xa2, 0x5b, 0x9f, 0x63, 0x96, 0x5a, 0x8b, + 0x5c, 0x08, 0x34, 0x5f, 0x53, 0x47, 0x33, 0x53, 0xe6, 0xf7, 0x23, 0x1e, + 0x8b, 0xa4, 0x8d, 0xaa, 0x8e, 0x9a, 0x8c, 0x8f, 0x8b, 0x8b, 0x8b, 0x8e, + 0x08, 0x0e, 0xfb, 0x4b, 0xf8, 0x54, 0xf9, 0x35, 0x15, 0xfb, 0xfe, 0x8b, + 0x4d, 0xfb, 0x38, 0xa9, 0x8b, 0x05, 0x9a, 0xab, 0x9f, 0xa5, 0x9e, 0x97, + 0x9d, 0x97, 0x92, 0x8c, 0xd3, 0x8b, 0x08, 0xf7, 0x2f, 0x8b, 0xfb, 0x66, + 0xfc, 0xdb, 0x05, 0xa5, 0x85, 0x8f, 0x8a, 0xa6, 0x82, 0x08, 0xf7, 0x85, + 0xf9, 0x3c, 0x05, 0x0e, 0xfb, 0x4b, 0xf7, 0x58, 0xf7, 0xe2, 0x15, 0x25, + 0x49, 0x63, 0x56, 0x8b, 0x44, 0x08, 0x30, 0xdc, 0x49, 0xf7, 0x05, 0xf7, + 0x03, 0xdc, 0xd2, 0xec, 0x1e, 0x8b, 0xd2, 0x65, 0xc1, 0xfb, 0x02, 0xe2, + 0x08, 0xe6, 0xbe, 0xb6, 0xc0, 0x8b, 0xc7, 0x08, 0xe1, 0x3b, 0xd0, 0x26, + 0x23, 0x3c, 0x46, 0x31, 0x1e, 0x8b, 0x49, 0xaa, 0x5f, 0xf2, 0x38, 0x08, + 0xa7, 0x77, 0x15, 0xf7, 0x0e, 0x21, 0xa1, 0x6d, 0x8b, 0x53, 0x08, 0x53, + 0x5b, 0x62, 0x4a, 0x3e, 0x5c, 0xbd, 0xdd, 0x1e, 0x8b, 0xc6, 0xa6, 0xb8, + 0xcd, 0xc0, 0x08, 0xb5, 0xd5, 0x15, 0x2c, 0xcf, 0x66, 0xb9, 0x8b, 0xbe, + 0x08, 0xc0, 0xbd, 0xb7, 0xc7, 0xcd, 0xbb, 0x58, 0x46, 0x1e, 0x8b, 0x52, + 0x73, 0x66, 0x47, 0x5b, 0x08, 0x0e, 0xfb, 0x4b, 0xb9, 0x7f, 0x15, 0x9a, + 0x8a, 0x97, 0x8b, 0x92, 0x8b, 0xe3, 0x8b, 0xe5, 0xb2, 0xd0, 0xcd, 0xdd, + 0xdc, 0xbe, 0xf7, 0x0e, 0x8b, 0xf7, 0x07, 0x8b, 0xca, 0x7a, 0xcc, 0x6c, + 0xbf, 0x66, 0xc8, 0x4d, 0xae, 0x42, 0x8b, 0x08, 0xfb, 0x0c, 0x32, 0x29, + 0xfb, 0x17, 0xfb, 0x0d, 0xda, 0x38, 0xf7, 0x06, 0x1f, 0xb4, 0x8b, 0xa8, + 0x94, 0xc5, 0xa8, 0x5a, 0xfb, 0x3d, 0xfb, 0x0d, 0xfb, 0x04, 0xfb, 0x1c, + 0x89, 0x08, 0x77, 0x07, 0xf7, 0xd0, 0xf7, 0xeb, 0x15, 0x56, 0x72, 0x6f, + 0x83, 0x6a, 0x8b, 0x08, 0x3f, 0x5d, 0xd9, 0xf7, 0x14, 0xe3, 0xb7, 0xc6, + 0xcd, 0xdc, 0xc2, 0x32, 0xfb, 0x18, 0x1f, 0x8b, 0x68, 0x89, 0x73, 0x83, + 0x63, 0x08, 0x0e, 0xfc, 0x29, 0xf7, 0x1e, 0xef, 0x15, 0x6c, 0x71, 0x72, + 0x6c, 0x6c, 0xa4, 0x71, 0xaa, 0xaa, 0xa4, 0xa5, 0xaa, 0xa9, 0x71, 0xa5, + 0x6e, 0x1f, 0xf7, 0xff, 0x04, 0x6c, 0x71, 0x72, 0x6c, 0x6c, 0xa4, 0x71, + 0xaa, 0xaa, 0xa4, 0xa5, 0xaa, 0xa9, 0x72, 0xa5, 0x6d, 0x1f, 0x0e, 0xfc, + 0x29, 0xf7, 0x30, 0xf8, 0x63, 0x15, 0x6b, 0x72, 0x72, 0x6c, 0x6b, 0xa4, + 0x72, 0xaa, 0xaa, 0xa4, 0xa4, 0xab, 0xaa, 0x72, 0xa4, 0x6d, 0x1f, 0x42, + 0xfc, 0xdb, 0x15, 0xb0, 0x8f, 0x9d, 0x92, 0xa6, 0x9f, 0xb2, 0xa8, 0x9c, + 0xab, 0x8b, 0xb6, 0x08, 0xbc, 0x69, 0xb1, 0x60, 0x6d, 0x73, 0x72, 0x6b, + 0x6b, 0xa3, 0x71, 0xa8, 0x1e, 0x94, 0x8b, 0x91, 0x8c, 0x9a, 0x8f, 0x8d, + 0x61, 0x60, 0x5e, 0x5a, 0x82, 0x08, 0x7b, 0x07, 0x0e, 0xf8, 0x9f, 0xf8, + 0x9e, 0x15, 0xfc, 0x85, 0xfb, 0x7e, 0x8b, 0x54, 0xf8, 0x85, 0xfb, 0x7d, + 0x8b, 0xc9, 0xfc, 0x36, 0xf7, 0x5b, 0xf8, 0x36, 0xf7, 0x5b, 0x8b, 0xc9, + 0x05, 0x0e, 0xf8, 0xad, 0xf8, 0x1b, 0x15, 0xfc, 0xa2, 0x54, 0xf8, 0xa2, + 0xc2, 0x06, 0xfb, 0x56, 0x04, 0xfc, 0xa2, 0x54, 0xf8, 0xa2, 0xc2, 0x06, + 0x0e, 0xa5, 0xf8, 0x9e, 0x15, 0x8b, 0x4d, 0xf8, 0x36, 0xfb, 0x5b, 0xfc, + 0x36, 0xfb, 0x5b, 0x8b, 0x4d, 0xf8, 0x85, 0xf7, 0x7d, 0x8b, 0xc2, 0xfc, + 0x85, 0xf7, 0x7e, 0x05, 0x0e, 0xfb, 0x83, 0xf7, 0x87, 0xf7, 0x44, 0x15, + 0x8c, 0xc9, 0x9b, 0xb8, 0xb1, 0xba, 0xc8, 0xce, 0x8b, 0x8b, 0x9b, 0xa3, + 0xa4, 0xb0, 0x97, 0xb1, 0x8b, 0xb3, 0x08, 0xe3, 0x44, 0xc9, 0x25, 0x2e, + 0x3f, 0x4d, 0x3d, 0x60, 0xa3, 0x6b, 0xaa, 0xa3, 0x9e, 0x9d, 0xa2, 0x1e, + 0x8b, 0x96, 0x87, 0x96, 0x82, 0x97, 0x7a, 0xa3, 0x89, 0x8e, 0x8b, 0x99, + 0x08, 0xb0, 0xb0, 0xa8, 0xbb, 0xc7, 0xaf, 0x5d, 0x40, 0x1e, 0x8b, 0x5e, + 0x85, 0x77, 0x5e, 0x31, 0x66, 0x40, 0x85, 0x70, 0x89, 0x28, 0x08, 0xa1, + 0x06, 0x88, 0x3e, 0x15, 0x6b, 0x72, 0x72, 0x6c, 0x6c, 0xa4, 0x72, 0xaa, + 0xaa, 0xa4, 0xa4, 0xaa, 0xa9, 0x72, 0xa5, 0x6d, 0x1f, 0x0e, 0xf8, 0xad, + 0xf7, 0x89, 0x15, 0xfc, 0xa2, 0x54, 0xf8, 0xa2, 0x06, 0xc2, 0x07, 0xfb, + 0x52, 0x04, 0xfc, 0xa2, 0x54, 0xf8, 0xa2, 0xc2, 0x06, 0x5b, 0xf8, 0x38, + 0x15, 0x5d, 0x57, 0x77, 0x7f, 0x64, 0x8b, 0x79, 0x8b, 0x7c, 0x8f, 0x49, + 0x9f, 0x08, 0x42, 0xa2, 0x73, 0x90, 0x6f, 0x8b, 0x52, 0x8b, 0x5c, 0x70, + 0x64, 0x52, 0x08, 0xb6, 0x69, 0x05, 0xb8, 0xc0, 0x9b, 0x95, 0xb1, 0x8b, + 0x9d, 0x8b, 0x96, 0x89, 0xae, 0x81, 0x08, 0xec, 0x6d, 0x05, 0xa0, 0x84, + 0xa2, 0x88, 0xa0, 0x8b, 0xcc, 0x8b, 0xbb, 0xa8, 0xaa, 0xc4, 0x08, 0x63, + 0xac, 0x05, 0x0e, 0xb2, 0xf7, 0xf5, 0xf9, 0x35, 0x15, 0x80, 0x8b, 0xfb, + 0x74, 0xfc, 0xa7, 0x05, 0x61, 0x29, 0x84, 0x84, 0x4a, 0x80, 0x08, 0x71, + 0xf7, 0x56, 0xa5, 0x07, 0x65, 0x8d, 0x7a, 0x98, 0x8b, 0xa5, 0x8b, 0x9b, + 0x90, 0x9b, 0x9d, 0xb6, 0x08, 0xa9, 0xd3, 0xf7, 0x87, 0x8b, 0xaa, 0x43, + 0x05, 0xa2, 0x56, 0x8c, 0x86, 0x8b, 0x7a, 0x8b, 0x72, 0x7d, 0x7f, 0x69, + 0x87, 0x08, 0x71, 0xf7, 0x82, 0xa5, 0x07, 0x54, 0x98, 0x89, 0x8d, 0x5e, + 0xf0, 0x08, 0xfb, 0x79, 0xf8, 0xa7, 0x05, 0x68, 0xfb, 0x40, 0x15, 0xf7, + 0x00, 0xfb, 0x8a, 0xfb, 0x6a, 0x8b, 0xf5, 0xf7, 0x8a, 0x05, 0x0e, 0x7b, + 0xa8, 0xf9, 0x1b, 0x15, 0x8e, 0x06, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x78, + 0x96, 0x79, 0x8e, 0x7c, 0x8b, 0x57, 0x08, 0xfc, 0x19, 0x07, 0x8b, 0x57, + 0x88, 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, + 0x06, 0x71, 0xf7, 0xda, 0x07, 0xc5, 0x8b, 0xb7, 0x93, 0xae, 0x9d, 0xca, + 0xab, 0xb0, 0xc5, 0x8b, 0xcf, 0x8b, 0xc4, 0x70, 0xb8, 0x58, 0xa9, 0x70, + 0x9b, 0x74, 0x93, 0x59, 0x95, 0x08, 0xe3, 0x9a, 0xc2, 0xc2, 0x8b, 0xd5, + 0x8b, 0xcc, 0x69, 0xc2, 0x4f, 0xab, 0x66, 0x9e, 0x5d, 0x93, 0x3d, 0x8b, + 0x08, 0xfb, 0xa5, 0x06, 0x71, 0x07, 0xf7, 0x55, 0xfb, 0xa9, 0x15, 0xf7, + 0x8f, 0x07, 0x98, 0x8b, 0x8b, 0xc9, 0x1e, 0xc0, 0x8b, 0xa3, 0x88, 0xa1, + 0x82, 0xb6, 0x7a, 0xa7, 0x5d, 0x8b, 0x56, 0x08, 0x37, 0x4d, 0x57, 0x28, + 0x1e, 0x44, 0x06, 0x65, 0x04, 0xd1, 0x06, 0xf7, 0x08, 0xc8, 0x58, 0x2c, + 0x2b, 0x4f, 0x59, 0xfb, 0x07, 0x4e, 0x80, 0x8d, 0x99, 0x1f, 0xf7, 0xa8, + 0x07, 0x0e, 0xb2, 0xf8, 0x15, 0x16, 0xf7, 0xd3, 0xa5, 0x06, 0x3c, 0x90, + 0x6c, 0xa0, 0x56, 0xe4, 0x08, 0xfb, 0x22, 0xf7, 0x79, 0xf7, 0x0c, 0xf7, + 0x35, 0x05, 0xcc, 0xe4, 0xb0, 0xa2, 0xde, 0x8f, 0x08, 0xa5, 0xfb, 0x8f, + 0x71, 0x99, 0x07, 0xae, 0x9a, 0x81, 0x75, 0x1f, 0x8b, 0x7d, 0x7f, 0x78, + 0x65, 0x59, 0x08, 0x2d, 0xfb, 0x10, 0x3d, 0xf7, 0x0f, 0x05, 0x6d, 0xbb, + 0x82, 0x9d, 0x8b, 0x99, 0x08, 0xa2, 0x9e, 0x98, 0xac, 0x1e, 0xa0, 0xa5, + 0xfb, 0xd9, 0x71, 0x06, 0xdd, 0x86, 0xaa, 0x76, 0xc2, 0x31, 0x08, 0xf7, + 0x1c, 0xfb, 0x66, 0xfb, 0x20, 0xfb, 0x48, 0x05, 0x4a, 0x34, 0x6a, 0x75, + 0x3c, 0x85, 0x08, 0x71, 0xf7, 0x8c, 0xa5, 0x7d, 0x07, 0x69, 0x7c, 0x95, + 0xa0, 0x1f, 0x8b, 0x9a, 0x8b, 0x8b, 0xbe, 0xd0, 0x08, 0xf0, 0xf7, 0x1e, + 0xe6, 0xfb, 0x1e, 0x05, 0xa3, 0x67, 0x9a, 0x6c, 0x8b, 0x7d, 0x08, 0x75, + 0x77, 0x7f, 0x66, 0x1e, 0x7b, 0x71, 0x06, 0x0e, 0x44, 0x91, 0x16, 0xf8, + 0xee, 0x8b, 0xfb, 0xad, 0xf9, 0x44, 0xfb, 0xd5, 0xfd, 0x44, 0x05, 0xd2, + 0xbe, 0x15, 0xf7, 0x69, 0xf8, 0x5e, 0xf7, 0x51, 0xfc, 0x5e, 0xfc, 0x26, + 0x8b, 0x05, 0x0e, 0x43, 0xab, 0xf9, 0x1b, 0x15, 0x8e, 0x06, 0xac, 0x8b, + 0xa6, 0x7f, 0x99, 0x78, 0x96, 0x7a, 0x8e, 0x7b, 0x8b, 0x57, 0x08, 0xfc, + 0x19, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, + 0x6a, 0x8b, 0x08, 0x88, 0x06, 0x71, 0xf8, 0xa8, 0x07, 0xc0, 0xf7, 0x41, + 0x70, 0x8b, 0x05, 0x62, 0x23, 0x62, 0x6f, 0xfb, 0x03, 0x8b, 0x08, 0xfb, + 0x16, 0x06, 0x67, 0x85, 0x92, 0xb7, 0x1f, 0xf7, 0x81, 0xf7, 0x22, 0x07, + 0xe1, 0x8b, 0x9f, 0x7a, 0x8e, 0x3b, 0x08, 0xa4, 0xf7, 0x82, 0x72, 0x86, + 0x06, 0x8b, 0x74, 0x84, 0x6d, 0x82, 0x7e, 0x7c, 0x76, 0x73, 0x83, 0x55, + 0x8b, 0x08, 0xfb, 0x22, 0xf7, 0x9a, 0xf7, 0x39, 0x06, 0xe3, 0x8b, 0xb2, + 0x69, 0x98, 0x34, 0x08, 0xa5, 0x8b, 0x81, 0xf7, 0x36, 0xfc, 0x96, 0x8b, + 0x05, 0x71, 0x07, 0x0e, 0xdb, 0xf7, 0x82, 0x16, 0xf7, 0xb7, 0xa5, 0x06, + 0x43, 0x8c, 0x71, 0xa7, 0x8d, 0xd5, 0xc4, 0x8b, 0xa3, 0x8e, 0xb1, 0x93, + 0xf7, 0x08, 0xa6, 0xd4, 0xd6, 0x8b, 0xe9, 0x8b, 0xee, 0x40, 0xd8, 0xfb, + 0x0c, 0xa5, 0x68, 0x92, 0x6b, 0x8e, 0x5d, 0x8c, 0x8a, 0xd0, 0xa6, 0xa7, + 0xd1, 0x8c, 0x08, 0xa5, 0xfb, 0xb7, 0x71, 0x07, 0xd2, 0x8a, 0xa6, 0x70, + 0x8a, 0x45, 0x5c, 0x8a, 0x6b, 0x88, 0x68, 0x84, 0xfb, 0x0c, 0x71, 0x40, + 0x3e, 0x8b, 0x28, 0x8b, 0x2d, 0xd4, 0x40, 0xf7, 0x08, 0x70, 0xb1, 0x83, + 0xa3, 0x88, 0xc5, 0x8b, 0x8d, 0x41, 0x71, 0x6f, 0x42, 0x8a, 0x08, 0x71, + 0x07, 0xec, 0xf7, 0x3b, 0x15, 0xfb, 0x1b, 0x93, 0x49, 0xc5, 0x8b, 0xf7, + 0x02, 0x8b, 0xc7, 0xa2, 0xb5, 0xbb, 0xaa, 0xae, 0xa0, 0xac, 0x95, 0xc9, + 0x90, 0x08, 0xfb, 0xed, 0x07, 0xed, 0xf7, 0xed, 0x15, 0xf7, 0x1a, 0x83, + 0xcd, 0x51, 0x8b, 0xfb, 0x02, 0x8b, 0x4f, 0x74, 0x61, 0x5b, 0x6c, 0x68, + 0x76, 0x6a, 0x82, 0x4e, 0x85, 0x08, 0xf7, 0xed, 0x07, 0x0e, 0x3b, 0xf7, + 0x6d, 0xf9, 0x0c, 0x15, 0xf7, 0x76, 0x06, 0xe3, 0x8b, 0xb2, 0x69, 0x98, + 0x34, 0x08, 0xa5, 0x8b, 0x81, 0xf7, 0x36, 0xfc, 0xd3, 0x8b, 0x8b, 0x71, + 0x8e, 0x8b, 0x05, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x78, 0x96, 0x7a, 0x8e, + 0x7b, 0x8b, 0x57, 0x08, 0xfc, 0x19, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, + 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0xf7, 0xc1, + 0xa5, 0x81, 0x06, 0x66, 0x8b, 0x6a, 0x97, 0x7d, 0x9e, 0x80, 0x9b, 0x88, + 0x9b, 0x8b, 0xc0, 0x08, 0xf8, 0x7e, 0x07, 0x0e, 0xb2, 0xf7, 0x7c, 0xf8, + 0x00, 0x15, 0xf7, 0x3b, 0x07, 0x8b, 0xbf, 0x8e, 0x9b, 0x96, 0x9c, 0x99, + 0x9e, 0xa6, 0x97, 0xac, 0x8b, 0x08, 0x8e, 0xa5, 0xfb, 0xb0, 0x71, 0x8e, + 0x06, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x78, 0x96, 0x7a, 0x8e, 0x7b, 0x8b, + 0x57, 0x08, 0xfc, 0x19, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, 0x7d, + 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0xf7, 0xb0, 0xa5, 0x88, + 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9c, 0x88, 0x9b, 0x8b, + 0xbf, 0x08, 0xf7, 0x48, 0xf7, 0xc4, 0xfb, 0x48, 0x07, 0x8b, 0x57, 0x88, + 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, + 0xf7, 0xb0, 0xa5, 0x88, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, + 0x9c, 0x88, 0x9b, 0x8b, 0xbf, 0x08, 0xf8, 0x19, 0x07, 0x8b, 0xbf, 0x8e, + 0x9b, 0x96, 0x9c, 0x99, 0x9e, 0xa6, 0x97, 0xac, 0x8b, 0x08, 0x8e, 0xa5, + 0xfb, 0xb0, 0x71, 0x8e, 0x06, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x78, 0x96, + 0x7a, 0x8e, 0x7b, 0x8b, 0x57, 0x08, 0xfb, 0x3b, 0xfb, 0xc4, 0x07, 0x0e, + 0xfb, 0xf2, 0xab, 0xf9, 0x1b, 0x15, 0x8e, 0x06, 0xac, 0x8b, 0xa6, 0x7f, + 0x99, 0x78, 0x96, 0x7a, 0x8e, 0x7b, 0x8b, 0x57, 0x08, 0xfc, 0x19, 0x07, + 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, + 0x08, 0x88, 0x71, 0xf7, 0xb0, 0xa5, 0x88, 0x06, 0x6a, 0x8b, 0x70, 0x97, + 0x7d, 0x9e, 0x80, 0x9c, 0x88, 0x9b, 0x8b, 0xbf, 0x08, 0xf8, 0x19, 0x07, + 0x8b, 0xbf, 0x8e, 0x9b, 0x96, 0x9c, 0x99, 0x9e, 0xa6, 0x97, 0xac, 0x8b, + 0x08, 0x8e, 0xa5, 0xfb, 0xb0, 0x71, 0x06, 0x0e, 0x57, 0xf9, 0x03, 0xf7, + 0xde, 0x15, 0x78, 0x90, 0x81, 0x8e, 0x88, 0x8c, 0x76, 0x92, 0x7d, 0x91, + 0x83, 0x8d, 0x7e, 0xf7, 0x27, 0x7c, 0xbe, 0x5c, 0xc9, 0x67, 0xba, 0x61, + 0xa4, 0x60, 0x8b, 0x4e, 0x8b, 0x5e, 0x5a, 0x8b, 0x47, 0x8b, 0x2d, 0xdb, + 0x35, 0xf7, 0x24, 0x4f, 0x08, 0x8c, 0x5c, 0x05, 0xfb, 0x32, 0x50, 0x26, + 0x30, 0x1e, 0x68, 0x8b, 0x6a, 0x9d, 0x7c, 0xa7, 0x81, 0x9f, 0x83, 0xb0, + 0x8b, 0xa6, 0x8b, 0x9e, 0x8e, 0xad, 0x90, 0xb8, 0x08, 0x96, 0xea, 0x8b, + 0x8e, 0x8b, 0x9f, 0x8b, 0xc1, 0x63, 0xb3, 0x54, 0x8b, 0x65, 0x8b, 0x71, + 0x7b, 0x71, 0x64, 0x7e, 0x78, 0x87, 0x82, 0x78, 0x59, 0x08, 0xa6, 0x06, + 0xa8, 0xc0, 0x96, 0x97, 0xa0, 0x8b, 0xa5, 0x8b, 0x9e, 0x79, 0x8b, 0x72, + 0x8b, 0x83, 0x8a, 0x7d, 0x89, 0x7d, 0x08, 0x7d, 0xfb, 0x00, 0x89, 0x76, + 0x8b, 0x67, 0x8b, 0x28, 0xcd, 0x4a, 0xf0, 0x8b, 0xf6, 0x8b, 0xd5, 0xc0, + 0xb2, 0xf3, 0x9f, 0xbf, 0x93, 0xba, 0x8c, 0xc3, 0xa9, 0x7e, 0xa4, 0x80, + 0x9f, 0x83, 0x08, 0xca, 0x07, 0xfb, 0x2d, 0xbf, 0x15, 0xfb, 0x05, 0xb6, + 0x3e, 0xdb, 0x8b, 0xd7, 0x8b, 0xb3, 0xa5, 0xa8, 0xaf, 0x8b, 0xb2, 0x8b, + 0xab, 0x6c, 0xa2, 0x50, 0x9a, 0x67, 0x92, 0x65, 0x97, 0x23, 0x08, 0x0e, + 0xb2, 0xf7, 0x78, 0xf8, 0xa7, 0x15, 0x8b, 0xbf, 0x8e, 0x9a, 0x96, 0x9d, + 0x99, 0x9e, 0xa6, 0x97, 0xac, 0x8b, 0x08, 0x8e, 0xa5, 0xfb, 0xb0, 0x71, + 0x8e, 0x06, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x78, 0x96, 0x79, 0x8e, 0x7c, + 0x8b, 0x57, 0x08, 0xfc, 0x19, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, + 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0xf7, 0xb0, 0xa5, + 0x88, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9c, 0x88, 0x9b, + 0x8b, 0xbf, 0x08, 0x8b, 0xf7, 0x22, 0xb3, 0xac, 0x05, 0xbe, 0x59, 0x98, + 0x7c, 0xe5, 0x21, 0xbb, 0x52, 0x9a, 0x74, 0x8b, 0x7b, 0x08, 0x7a, 0x7d, + 0x84, 0x6c, 0x1e, 0x6a, 0x71, 0xf7, 0xcf, 0xa5, 0x06, 0x4f, 0x90, 0x6a, + 0xa1, 0x4b, 0xd9, 0x08, 0xfb, 0x72, 0xf7, 0x94, 0xb6, 0xb5, 0x05, 0xf7, + 0x0a, 0xf7, 0x13, 0xb4, 0xb5, 0xa3, 0x9e, 0xa4, 0x9f, 0xad, 0x95, 0xb4, + 0x8b, 0x08, 0x94, 0xa5, 0xfb, 0xa3, 0x71, 0x06, 0xb7, 0x8a, 0x91, 0x8b, + 0x95, 0x87, 0x97, 0x87, 0x93, 0x82, 0x8b, 0x82, 0x8b, 0x73, 0xfb, 0x1c, + 0xfb, 0x29, 0xfb, 0x0f, 0xfb, 0x03, 0x08, 0xf7, 0x57, 0x07, 0x0e, 0x8e, + 0xf7, 0xce, 0xf8, 0x89, 0x15, 0xf7, 0x2c, 0xfb, 0xfb, 0x05, 0xa2, 0x56, + 0x8c, 0x86, 0x8b, 0x7a, 0x8b, 0x72, 0x7d, 0x7f, 0x69, 0x87, 0x08, 0x71, + 0xf7, 0x82, 0xa5, 0x07, 0x54, 0x98, 0x89, 0x8d, 0x5e, 0xf0, 0x08, 0xfb, + 0x7f, 0xf8, 0xb6, 0xfb, 0x79, 0xfc, 0xb6, 0x05, 0x62, 0x2c, 0x84, 0x83, + 0x4f, 0x7e, 0x08, 0x71, 0xf7, 0x50, 0xa5, 0x07, 0x65, 0x8d, 0x7a, 0x98, + 0x8b, 0xa5, 0x8b, 0x9b, 0x90, 0x9b, 0x9d, 0xb6, 0x08, 0xf7, 0x2c, 0xf7, + 0xfb, 0x05, 0x0e, 0xf7, 0x62, 0xf8, 0x3c, 0x8c, 0x15, 0xf7, 0xa2, 0xf8, + 0xb0, 0x8b, 0xfc, 0x23, 0x05, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, 0x7d, + 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0xf7, 0xb0, 0xa5, 0x88, + 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9c, 0x88, 0x9b, 0x8b, + 0xbf, 0x08, 0xf8, 0x19, 0x07, 0x8b, 0xbf, 0x8e, 0x9b, 0x96, 0x9c, 0x99, + 0x9e, 0xa7, 0x97, 0xab, 0x8b, 0x08, 0x8e, 0xa5, 0xfb, 0x42, 0x06, 0xfb, + 0x91, 0xfc, 0x8b, 0xfb, 0x89, 0xf8, 0x8b, 0xfb, 0x4f, 0x8b, 0x8b, 0x71, + 0x8e, 0x8b, 0x05, 0xad, 0x8b, 0xa5, 0x7f, 0x99, 0x78, 0x96, 0x79, 0x8e, + 0x7c, 0x8b, 0x57, 0x08, 0xfc, 0x19, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, + 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0xf7, 0x76, + 0xa5, 0x88, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9c, 0x88, + 0x9b, 0x8b, 0xbf, 0x08, 0x8b, 0xf8, 0x23, 0xf7, 0x99, 0xfc, 0xb0, 0x05, + 0x0e, 0xb2, 0xa9, 0xf9, 0x1b, 0x15, 0x8f, 0x06, 0xac, 0x8b, 0xa6, 0x7f, + 0x99, 0x78, 0x96, 0x7a, 0x8e, 0x7c, 0x8b, 0x57, 0x08, 0xfc, 0x1a, 0x07, + 0x8b, 0x53, 0x89, 0x81, 0x7f, 0x78, 0x7d, 0x77, 0x71, 0x80, 0x69, 0x8b, + 0x08, 0x86, 0x71, 0xf7, 0x79, 0xa5, 0x86, 0x06, 0x6a, 0x8b, 0x70, 0x97, + 0x7d, 0x9e, 0x80, 0x9c, 0x88, 0x9b, 0x8b, 0xbf, 0x08, 0x8b, 0xf8, 0x1a, + 0xf8, 0x37, 0xfc, 0xa8, 0xb8, 0x8b, 0x8b, 0xf8, 0xa7, 0x05, 0x8b, 0xc0, + 0x8d, 0x9a, 0x97, 0x9c, 0x99, 0x9e, 0xa6, 0x97, 0xaa, 0x8b, 0x08, 0x90, + 0xa5, 0xfb, 0x74, 0x71, 0x8e, 0x06, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x78, + 0x97, 0x7a, 0x8d, 0x7c, 0x8b, 0x56, 0x08, 0x8b, 0xfc, 0x07, 0xfc, 0x22, + 0xf8, 0x95, 0xfb, 0x33, 0x8b, 0x8b, 0x71, 0x05, 0x0e, 0xb2, 0xf8, 0x12, + 0xf9, 0x42, 0x15, 0xfb, 0x5c, 0xfb, 0x21, 0xfb, 0x25, 0xfb, 0x61, 0xfb, + 0x5e, 0xf7, 0x22, 0xfb, 0x27, 0xf7, 0x57, 0xf7, 0x57, 0xf7, 0x22, 0xf7, + 0x27, 0xf7, 0x5e, 0xf7, 0x5d, 0xfb, 0x22, 0xf7, 0x29, 0xfb, 0x53, 0x1f, + 0x81, 0x64, 0x15, 0xb8, 0x8b, 0xb9, 0x7a, 0xae, 0x6d, 0xcb, 0x56, 0xae, + 0x2a, 0x8b, 0xfb, 0x0e, 0x8b, 0xfb, 0x05, 0x6c, 0x2e, 0x54, 0x59, 0x6c, + 0x6e, 0x5b, 0x7a, 0x5a, 0x8b, 0x08, 0xfb, 0x1b, 0x32, 0xf7, 0x11, 0xf7, + 0x51, 0xf7, 0x55, 0xda, 0xf7, 0x06, 0xf7, 0x1a, 0x1f, 0x0e, 0xe0, 0xa4, + 0xf9, 0x1b, 0x15, 0x8e, 0x06, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x77, 0x96, + 0x7a, 0x8e, 0x7c, 0x8b, 0x57, 0x08, 0xfc, 0x19, 0x07, 0x8b, 0x57, 0x88, + 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, + 0xf7, 0xb0, 0xa5, 0x88, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, + 0x9c, 0x88, 0x9b, 0x8b, 0xbf, 0x08, 0xf8, 0x0e, 0x07, 0xf7, 0x04, 0x8b, + 0x8b, 0xf7, 0x53, 0xf7, 0x1e, 0x90, 0x87, 0xfb, 0x00, 0x1e, 0xfc, 0x0e, + 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, + 0x8b, 0x08, 0x88, 0x71, 0xf7, 0xb0, 0xa5, 0x88, 0x06, 0x6a, 0x8b, 0x70, + 0x97, 0x7d, 0x9e, 0x80, 0x9c, 0x88, 0x9b, 0x8b, 0xbf, 0x08, 0xf8, 0x19, + 0x07, 0x8b, 0xbf, 0x8e, 0x9a, 0x96, 0x9c, 0x99, 0x9f, 0xa6, 0x97, 0xac, + 0x8b, 0x08, 0x8e, 0xa5, 0xfd, 0x64, 0x71, 0x06, 0x0e, 0xc5, 0xf8, 0x8d, + 0xf8, 0x5d, 0x15, 0x73, 0x06, 0x86, 0x4e, 0x7a, 0x7d, 0x4a, 0x8b, 0x08, + 0x69, 0x06, 0x4d, 0x8b, 0x79, 0x9b, 0x87, 0xc6, 0x08, 0x73, 0xfb, 0x7a, + 0xa3, 0x06, 0x90, 0xc9, 0x9b, 0x99, 0xcd, 0x8b, 0x08, 0xac, 0x06, 0xcc, + 0x8b, 0x9b, 0x7d, 0x8f, 0x4d, 0x08, 0xa3, 0xf7, 0x7a, 0x06, 0xfb, 0x0f, + 0xf7, 0x79, 0x15, 0xfb, 0x5c, 0xfb, 0x21, 0xfb, 0x25, 0xfb, 0x61, 0xfb, + 0x5e, 0xf7, 0x22, 0xfb, 0x27, 0xf7, 0x57, 0xf7, 0x57, 0xf7, 0x22, 0xf7, + 0x27, 0xf7, 0x5e, 0xf7, 0x5d, 0xfb, 0x22, 0xf7, 0x29, 0xfb, 0x53, 0x1f, + 0x81, 0x64, 0x15, 0xb8, 0x8b, 0xb9, 0x7a, 0xae, 0x6d, 0xcb, 0x56, 0xae, + 0x2a, 0x8b, 0xfb, 0x0e, 0x8b, 0xfb, 0x05, 0x6c, 0x2e, 0x54, 0x59, 0x6c, + 0x6e, 0x5b, 0x7a, 0x5a, 0x8b, 0x08, 0xfb, 0x1b, 0x32, 0xf7, 0x11, 0xf7, + 0x51, 0xf7, 0x55, 0xda, 0xf7, 0x06, 0xf7, 0x1a, 0x1f, 0x0e, 0xfb, 0x13, + 0xa7, 0xf9, 0x1b, 0x15, 0x8e, 0x06, 0xac, 0x8b, 0xa6, 0x7f, 0x99, 0x78, + 0x96, 0x7a, 0x8e, 0x7b, 0x8b, 0x57, 0x08, 0xfc, 0x19, 0x07, 0x8b, 0x57, + 0x88, 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, + 0x71, 0xf7, 0xc9, 0xa5, 0x7c, 0x06, 0x65, 0x8b, 0x69, 0x97, 0x7d, 0x9e, + 0x7f, 0x9a, 0x88, 0x9c, 0x8b, 0xc0, 0x08, 0xf7, 0x41, 0x07, 0xac, 0x84, + 0xb7, 0x86, 0xab, 0x8b, 0xd2, 0x8b, 0xc8, 0x9b, 0xb0, 0xa9, 0xb3, 0xaa, + 0xa3, 0xc1, 0x8b, 0xc4, 0x8b, 0xd4, 0x64, 0xc6, 0x48, 0xa8, 0x64, 0x9d, + 0x6c, 0x8e, 0xfb, 0x05, 0x8b, 0x08, 0xfb, 0x8a, 0x71, 0x06, 0xf7, 0x55, + 0x68, 0x15, 0x9e, 0x92, 0x8d, 0xd6, 0x1e, 0xab, 0x8b, 0xa2, 0x87, 0x9e, + 0x83, 0xb8, 0x77, 0xa5, 0x5c, 0x8b, 0x4f, 0x8b, 0x59, 0x79, 0x60, 0x6c, + 0x71, 0x74, 0x78, 0x6d, 0x82, 0x5f, 0x8b, 0x73, 0x8b, 0x77, 0x8e, 0x66, + 0x94, 0x08, 0xf7, 0x91, 0x07, 0x0e, 0x30, 0xf7, 0x3b, 0xf9, 0x0c, 0x15, + 0xf7, 0x3d, 0x06, 0xf7, 0x08, 0x8b, 0xaa, 0x74, 0x9c, 0x28, 0x08, 0xa5, + 0x8b, 0x81, 0xf7, 0x37, 0xfc, 0x82, 0x8b, 0xf7, 0x6e, 0xfb, 0xf5, 0xfb, + 0x7f, 0xfb, 0xd4, 0xf8, 0xa6, 0x8b, 0xc1, 0xf7, 0x48, 0x71, 0x8b, 0x05, + 0x6b, 0x3b, 0x6d, 0x7a, 0xfb, 0x08, 0x8b, 0x08, 0xfb, 0x9f, 0x8b, 0xf7, + 0x67, 0xf7, 0xb2, 0xfb, 0x36, 0xf7, 0x9b, 0x05, 0x0e, 0x43, 0xf7, 0xa1, + 0xf9, 0x08, 0x15, 0xfc, 0x7a, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, + 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x77, 0x71, 0xf7, 0xd2, 0xa5, + 0x77, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9d, 0x88, 0x99, + 0x8b, 0xc0, 0x08, 0xf8, 0x7a, 0xd5, 0x07, 0xec, 0x8b, 0xaa, 0x71, 0x94, + 0x34, 0x08, 0xa4, 0x8b, 0x80, 0xf7, 0x32, 0xfc, 0xbc, 0x8b, 0x80, 0xfb, + 0x32, 0xa5, 0x8b, 0x05, 0x92, 0xe0, 0xaf, 0xa7, 0xf1, 0x8b, 0x08, 0xcc, + 0x06, 0x0e, 0x92, 0xf8, 0x20, 0xf7, 0xb7, 0x15, 0xf7, 0x26, 0xf7, 0x85, + 0x05, 0xbd, 0xe0, 0xa6, 0xa0, 0xd6, 0x94, 0x08, 0xa5, 0xfb, 0x79, 0x71, + 0x96, 0x07, 0xb3, 0x9a, 0x81, 0x73, 0x1f, 0x8b, 0x7a, 0x7e, 0x6b, 0x76, + 0x6b, 0x08, 0xfb, 0x09, 0xfb, 0x4d, 0xfb, 0x06, 0xf7, 0x4d, 0x05, 0x6f, + 0xb7, 0x81, 0xa2, 0x8b, 0x9a, 0x08, 0xa1, 0x9e, 0x96, 0xae, 0x1e, 0x9e, + 0xa5, 0xfb, 0xc9, 0x71, 0x06, 0xda, 0x82, 0xa5, 0x78, 0xbe, 0x34, 0x08, + 0xf7, 0x26, 0xfb, 0x85, 0x8b, 0xfb, 0x29, 0x05, 0x8b, 0x57, 0x88, 0x7b, + 0x80, 0x7a, 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0xf7, + 0xb0, 0xa5, 0x88, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9c, + 0x88, 0x9b, 0x8b, 0xbf, 0x08, 0xf7, 0x29, 0x07, 0x0e, 0xfb, 0x88, 0xf7, + 0x83, 0xf8, 0x45, 0x15, 0x94, 0x8b, 0x9b, 0x89, 0x99, 0x88, 0xcc, 0x7f, + 0x8c, 0x8b, 0x9b, 0x8b, 0x08, 0xae, 0xa0, 0x99, 0xa4, 0xae, 0x5e, 0xa2, + 0x47, 0xfb, 0x21, 0xfb, 0x0e, 0xfb, 0x20, 0xfb, 0x38, 0xfb, 0x0f, 0xd5, + 0x2e, 0xec, 0x1f, 0x9a, 0x8b, 0xd1, 0x8e, 0x9e, 0x8c, 0x08, 0x95, 0x8c, + 0x95, 0x8b, 0x8f, 0x8b, 0x08, 0xad, 0x9e, 0x79, 0x69, 0x60, 0x6f, 0x69, + 0x67, 0x1f, 0x85, 0x8b, 0x85, 0x8c, 0x86, 0x8d, 0x66, 0x98, 0x81, 0x8d, + 0x79, 0x8b, 0x08, 0x69, 0x75, 0x7a, 0x6e, 0x69, 0xb0, 0x6e, 0xb7, 0xe4, + 0xd7, 0xe0, 0xef, 0x1f, 0x8b, 0xb8, 0x7a, 0xb3, 0x6e, 0xa6, 0x75, 0x9f, + 0x75, 0x92, 0x65, 0x8b, 0x7e, 0x8b, 0x7c, 0x8b, 0x7c, 0x8a, 0x08, 0x75, + 0x89, 0x5e, 0x89, 0x88, 0x8b, 0x08, 0x4c, 0x5a, 0xca, 0xdc, 0x1f, 0xf1, + 0xd4, 0xe5, 0xde, 0x1e, 0x0e, 0xe0, 0xf7, 0xda, 0x16, 0x79, 0xf7, 0x2f, + 0x05, 0x3d, 0xb7, 0x59, 0xe4, 0x8b, 0xe9, 0x8b, 0xbf, 0x9a, 0xc6, 0xa5, + 0xba, 0xaf, 0xcc, 0xc7, 0xb0, 0xcf, 0x8b, 0xcf, 0x8b, 0xc7, 0x66, 0xaf, + 0x4a, 0xa5, 0x5c, 0x9a, 0x50, 0x8b, 0x57, 0x8b, 0x2d, 0x59, 0x32, 0x3d, + 0x5f, 0x08, 0x79, 0xfb, 0x2f, 0xf7, 0xb8, 0x8b, 0x8b, 0xf7, 0x2d, 0x73, + 0x8b, 0x05, 0x84, 0x5f, 0x75, 0x78, 0x63, 0x8b, 0x08, 0xfb, 0x26, 0x8b, + 0x8e, 0xb1, 0x05, 0xae, 0x98, 0xa0, 0x95, 0xa3, 0x9a, 0xd7, 0xbc, 0xb9, + 0xdc, 0x8b, 0xe1, 0x8b, 0xcd, 0x6e, 0xd5, 0x5b, 0xc3, 0x4e, 0xd1, 0x37, + 0xb1, 0x2c, 0x8b, 0x2c, 0x8b, 0x37, 0x65, 0x4e, 0x45, 0x5b, 0x53, 0x6e, + 0x41, 0x8b, 0x49, 0x08, 0x8b, 0x35, 0xb9, 0x3a, 0xd7, 0x5a, 0xa2, 0x7c, + 0xa0, 0x81, 0xaf, 0x7e, 0x08, 0x8e, 0x65, 0xfb, 0x26, 0x8b, 0x05, 0x63, + 0x8b, 0x75, 0x9e, 0x84, 0xb7, 0x08, 0x73, 0xfb, 0x2d, 0xf7, 0xb8, 0x06, + 0x0e, 0x65, 0xf8, 0xc4, 0xf9, 0x35, 0x15, 0xfc, 0x76, 0x8b, 0x81, 0xfb, + 0x3c, 0xa5, 0x8b, 0x05, 0x97, 0xd3, 0x9b, 0x97, 0xe0, 0x8b, 0x08, 0xf7, + 0x75, 0x06, 0xde, 0x8b, 0x9b, 0x7e, 0x98, 0x44, 0x08, 0xa5, 0x8b, 0x81, + 0xf7, 0x3c, 0x05, 0x96, 0xfc, 0x81, 0x15, 0x72, 0x39, 0x73, 0x7d, 0xfb, + 0x10, 0x8b, 0x08, 0xfb, 0x40, 0x06, 0xfb, 0x04, 0x8b, 0x74, 0x99, 0x72, + 0xdd, 0x08, 0x71, 0x8b, 0xb1, 0xfb, 0x48, 0xf8, 0x76, 0x8b, 0xb2, 0xf7, + 0x48, 0x6f, 0x8b, 0x05, 0xfb, 0x11, 0xf7, 0xa9, 0x15, 0x73, 0x06, 0x86, + 0x4e, 0x7a, 0x7d, 0x4a, 0x8b, 0x08, 0x69, 0x06, 0x4d, 0x8b, 0x79, 0x9b, + 0x87, 0xc6, 0x08, 0x73, 0xfb, 0x7a, 0xa3, 0x06, 0x90, 0xc9, 0x9b, 0x99, + 0xcd, 0x8b, 0x08, 0xac, 0x06, 0xcc, 0x8b, 0x9b, 0x7d, 0x8f, 0x4d, 0x08, + 0xa3, 0xf7, 0x7a, 0x06, 0x0e, 0xf7, 0x04, 0xf8, 0x52, 0xf7, 0xa3, 0x15, + 0xdc, 0x8a, 0xc2, 0x94, 0xb5, 0xa0, 0xcf, 0xab, 0xb1, 0xc9, 0x8b, 0xda, + 0x08, 0x89, 0xdf, 0x05, 0x8b, 0xd5, 0x97, 0xa2, 0xb4, 0x94, 0x08, 0xa2, + 0x07, 0xfb, 0x09, 0x82, 0x63, 0x5b, 0x84, 0xfb, 0x1f, 0x86, 0xfb, 0x00, + 0x83, 0x76, 0x61, 0x6d, 0x74, 0x7c, 0x69, 0x85, 0x50, 0x8c, 0x08, 0xf7, + 0x70, 0x07, 0x8b, 0xe5, 0x9d, 0xa2, 0xd7, 0x8e, 0x08, 0xa5, 0xfb, 0xb0, + 0x71, 0x07, 0xd6, 0x88, 0x9d, 0x74, 0x8b, 0x31, 0x08, 0xfb, 0x70, 0x07, + 0x5a, 0x8a, 0x69, 0x90, 0x76, 0x95, 0x58, 0xa8, 0x81, 0xa2, 0x86, 0xf7, + 0x05, 0x84, 0xf7, 0x1f, 0x63, 0xbb, 0xfb, 0x09, 0x94, 0x08, 0x74, 0x07, + 0xb4, 0x82, 0x97, 0x74, 0x8b, 0x41, 0x08, 0x89, 0x37, 0x05, 0x8b, 0x45, + 0xa9, 0x52, 0xc2, 0x68, 0xb8, 0x6f, 0xc7, 0x7e, 0xe8, 0x8c, 0x08, 0xfb, + 0x06, 0x07, 0x8b, 0x50, 0x85, 0x6e, 0x7c, 0x7a, 0x80, 0x7e, 0x6b, 0x80, + 0x72, 0x8b, 0x08, 0x78, 0x6f, 0xf7, 0xcd, 0xa7, 0x78, 0x06, 0x72, 0x8b, + 0x6b, 0x96, 0x80, 0x98, 0x7c, 0x9c, 0x85, 0xa8, 0x8b, 0xc6, 0x08, 0xf7, + 0x06, 0x07, 0x0e, 0x43, 0xf8, 0xfe, 0xf9, 0x35, 0x15, 0xfc, 0x8a, 0x8b, + 0x7a, 0xfb, 0x44, 0xa5, 0x8b, 0x05, 0x98, 0xf7, 0x03, 0xa5, 0xa1, 0xf7, + 0x0b, 0x8b, 0x08, 0xf7, 0x4a, 0x8b, 0xfc, 0x39, 0xfd, 0x0a, 0xf8, 0xbf, + 0x8b, 0xb0, 0xf7, 0x3f, 0x71, 0x8b, 0x05, 0x81, 0x61, 0x7a, 0x6e, 0x6f, + 0x72, 0x6f, 0x72, 0x67, 0x82, 0x49, 0x8b, 0x08, 0xfb, 0x7a, 0x8b, 0xf8, + 0x3b, 0xf9, 0x0c, 0x05, 0x0e, 0xfb, 0xf2, 0xf7, 0xbf, 0xfb, 0x39, 0x15, + 0xad, 0x24, 0x07, 0x7a, 0x85, 0x91, 0x9c, 0x1f, 0xf9, 0x62, 0x07, 0xa4, + 0x8f, 0x8f, 0xa2, 0x1e, 0xee, 0xad, 0xfb, 0x69, 0xfd, 0xda, 0xf7, 0x69, + 0x06, 0x0e, 0xf7, 0x48, 0xf7, 0x76, 0xf7, 0x04, 0x15, 0x68, 0x6f, 0x6f, + 0x69, 0x68, 0xa7, 0x6f, 0xad, 0xad, 0xa7, 0xa7, 0xae, 0xac, 0x6f, 0xa8, + 0x6a, 0x1f, 0xf7, 0x60, 0xf7, 0xd5, 0x15, 0x68, 0x6f, 0x6f, 0x69, 0x68, + 0xa7, 0x6f, 0xad, 0xad, 0xa7, 0xa7, 0xae, 0xac, 0x6f, 0xa8, 0x6a, 0x1f, + 0xf7, 0x66, 0xfb, 0xd5, 0x15, 0x68, 0x6f, 0x6f, 0x69, 0x68, 0xa7, 0x6f, + 0xad, 0xad, 0xa7, 0xa7, 0xae, 0xac, 0x6f, 0xa8, 0x6a, 0x1f, 0x0e, 0xfb, + 0xf2, 0xac, 0xfb, 0x39, 0x15, 0xf7, 0x69, 0xf9, 0xda, 0xfb, 0x69, 0x69, + 0xee, 0x06, 0xa2, 0x8f, 0x86, 0x73, 0x1f, 0xfd, 0x5e, 0x07, 0x75, 0x86, + 0x86, 0x73, 0x1e, 0x2a, 0x69, 0x06, 0x0e, 0x72, 0xf7, 0xfd, 0xf9, 0x35, + 0x15, 0x54, 0xfc, 0xfd, 0xfb, 0xb7, 0x53, 0xf9, 0x11, 0xc3, 0xfb, 0xb7, + 0xf8, 0xfd, 0x06, 0x0e, 0xfb, 0x4b, 0x89, 0xfb, 0x62, 0x15, 0x5d, 0xf8, + 0x8c, 0xb9, 0xfc, 0x8c, 0x07, 0x0e, 0xfb, 0x4b, 0xf8, 0x74, 0xfa, 0x25, + 0x15, 0x53, 0xf8, 0xf6, 0xc3, 0xfc, 0xf6, 0x07, 0x0e, 0x57, 0xf8, 0x84, + 0xf8, 0x88, 0x15, 0x4e, 0xfb, 0x40, 0x05, 0x71, 0xf7, 0x0d, 0x4e, 0xcb, + 0x30, 0x8b, 0x5d, 0x8b, 0x5a, 0x78, 0x66, 0x6b, 0x53, 0x5c, 0x6f, 0x43, + 0x8b, 0x28, 0x8b, 0xfb, 0x33, 0xda, 0x29, 0xf7, 0x16, 0x8b, 0xe3, 0x8b, + 0xcc, 0xb8, 0xb4, 0xe4, 0x90, 0x78, 0x92, 0x79, 0x96, 0x72, 0x08, 0xa5, + 0x53, 0x9c, 0x7b, 0xab, 0x8b, 0xac, 0x8b, 0xa2, 0xa0, 0x98, 0xb5, 0x92, + 0xa2, 0x8e, 0xa1, 0x8c, 0xc3, 0x08, 0x71, 0x06, 0x89, 0x58, 0x78, 0x66, + 0x72, 0x8b, 0x6a, 0x8b, 0x6a, 0xc0, 0x7f, 0xd0, 0x08, 0xf7, 0x05, 0xf7, + 0xcf, 0x05, 0x32, 0x06, 0x31, 0xfb, 0x97, 0x15, 0x74, 0x4a, 0x05, 0x68, + 0x25, 0x63, 0x5a, 0x59, 0x8b, 0x6c, 0x8b, 0x6c, 0x9f, 0x7b, 0xa8, 0x75, + 0xb4, 0x7f, 0xca, 0x8b, 0xd3, 0x8b, 0xd3, 0x99, 0xc8, 0xa5, 0xb7, 0x9d, + 0xa8, 0xa2, 0x99, 0xaa, 0x8b, 0xd2, 0x8b, 0xb9, 0x52, 0x9f, 0xfb, 0x06, + 0x08, 0x96, 0x51, 0x05, 0x0e, 0xda, 0x4d, 0x15, 0x8b, 0x56, 0x83, 0x46, + 0x81, 0x65, 0x08, 0xdd, 0x06, 0x98, 0xa2, 0x8e, 0xa6, 0x8b, 0xd9, 0x08, + 0xf7, 0x1c, 0x07, 0xc0, 0x63, 0xb7, 0x7c, 0xc5, 0x8b, 0xf7, 0x0b, 0x8b, + 0xdd, 0xe3, 0x8b, 0xf7, 0x15, 0x8b, 0xf6, 0x56, 0xd6, 0xfb, 0x02, 0xba, + 0x08, 0xd7, 0xb4, 0xaf, 0xb9, 0x8b, 0xc4, 0x08, 0xe4, 0x32, 0xd5, 0x20, + 0xfb, 0x00, 0x3a, 0x44, 0x2c, 0x1e, 0xfd, 0x10, 0x07, 0xdb, 0xf9, 0x1a, + 0x15, 0xd1, 0xb5, 0xbc, 0xc6, 0xca, 0xb8, 0x51, 0x3b, 0x56, 0x6f, 0x52, + 0x71, 0x1e, 0x88, 0x8b, 0x88, 0x8b, 0x7b, 0x8f, 0x7c, 0x8e, 0x83, 0x8c, + 0x83, 0x8b, 0x08, 0x73, 0x78, 0x7b, 0x78, 0x78, 0x9d, 0x7f, 0xa5, 0x1f, + 0x91, 0x8b, 0x90, 0x8c, 0x95, 0x8d, 0x97, 0x8e, 0x95, 0x8c, 0x93, 0x8b, + 0x98, 0x8b, 0x92, 0x89, 0x91, 0x85, 0x08, 0xb8, 0x61, 0xa6, 0x3f, 0x8b, + 0x39, 0x8b, 0x27, 0x5f, 0x50, 0x41, 0x8b, 0x59, 0x8b, 0x59, 0xa2, 0x69, + 0xb2, 0x08, 0xf8, 0x79, 0x07, 0x0e, 0xf8, 0x1b, 0xf8, 0x88, 0x15, 0xfb, + 0x15, 0xfb, 0x82, 0x67, 0xf7, 0x2a, 0x05, 0x7c, 0xca, 0x65, 0xb1, 0x5a, + 0x8b, 0x4f, 0x8b, 0x61, 0x48, 0x81, 0xfb, 0x03, 0x08, 0xa6, 0x06, 0x92, + 0xc7, 0xa9, 0xb2, 0xb0, 0x8b, 0xa3, 0x8b, 0xa5, 0x7b, 0x9b, 0x73, 0x93, + 0x7e, 0x94, 0x74, 0x91, 0x70, 0x08, 0xa9, 0xfb, 0x10, 0xfb, 0x6e, 0xfc, + 0x22, 0xf5, 0x8b, 0xf7, 0x22, 0xf7, 0x9c, 0x9b, 0x34, 0x05, 0x9a, 0x40, + 0x8e, 0x7d, 0x92, 0x77, 0xa0, 0x53, 0xad, 0x6c, 0xb4, 0x8b, 0xaf, 0x8b, + 0xaf, 0xa5, 0xa1, 0xb2, 0x9c, 0xaa, 0x94, 0xb0, 0x8e, 0xbf, 0x08, 0x73, + 0x06, 0x81, 0x68, 0x87, 0x81, 0x84, 0x81, 0x7d, 0x73, 0x73, 0x7e, 0x71, + 0x8b, 0x5c, 0x8b, 0x72, 0xb4, 0x6d, 0xf7, 0x10, 0x08, 0x78, 0xda, 0xf7, + 0x5f, 0xf8, 0x09, 0x23, 0x8b, 0x05, 0x0e, 0xfb, 0x51, 0xf7, 0x94, 0xf8, + 0x50, 0x15, 0x57, 0x7b, 0x6d, 0x7e, 0x6d, 0x77, 0x49, 0x5e, 0x65, 0x45, + 0x8b, 0x40, 0x08, 0xfb, 0x0b, 0xea, 0x28, 0xf7, 0x07, 0xf7, 0x11, 0xf5, + 0xf7, 0x05, 0xf7, 0x18, 0x1e, 0x8b, 0xcb, 0x75, 0xc9, 0x62, 0xbc, 0x68, + 0xb5, 0x7b, 0x97, 0x31, 0xc1, 0x08, 0x2e, 0xc4, 0x67, 0xae, 0x8b, 0xab, + 0x8b, 0xac, 0xab, 0xa5, 0xb2, 0x8b, 0xaf, 0x8b, 0xa1, 0x80, 0xb0, 0x65, + 0xb4, 0x61, 0x99, 0x82, 0xa4, 0x8b, 0x08, 0xa6, 0x9f, 0x9e, 0xa3, 0xc1, + 0x34, 0xb8, 0x22, 0x2d, 0x52, 0x65, 0x4e, 0x1f, 0x8b, 0x67, 0x9b, 0x6e, + 0xb7, 0x62, 0x08, 0xed, 0x30, 0x05, 0xa7, 0x71, 0x15, 0xce, 0x4c, 0xab, + 0x45, 0x8b, 0x35, 0x08, 0x29, 0x5c, 0x48, 0x45, 0x1e, 0x45, 0x5b, 0xd9, + 0xf7, 0x07, 0x1f, 0x8b, 0xf7, 0x00, 0xb8, 0xcb, 0xe6, 0x9e, 0x08, 0x0e, + 0xfb, 0x88, 0xf8, 0x27, 0xf7, 0x11, 0x15, 0x76, 0x4c, 0x66, 0x72, 0x43, + 0x8b, 0x5b, 0x8b, 0x63, 0x97, 0x6f, 0xa3, 0x77, 0x9d, 0x83, 0x9f, 0x8b, + 0xab, 0x8b, 0xc6, 0xad, 0xb1, 0xc0, 0x8b, 0x95, 0x8b, 0x94, 0x8a, 0x95, + 0x89, 0x98, 0x88, 0x97, 0x89, 0x95, 0x8b, 0x08, 0xa9, 0xa1, 0x99, 0x9d, + 0x9b, 0x7f, 0x93, 0x74, 0x1f, 0x83, 0x8b, 0x83, 0x8b, 0x79, 0x89, 0x6a, + 0x88, 0x83, 0x8a, 0x82, 0x8b, 0x08, 0x58, 0x6a, 0xae, 0xc1, 0xc6, 0xb5, + 0xbb, 0xbf, 0x1f, 0xaf, 0x8b, 0xa2, 0x7b, 0x96, 0x6b, 0x90, 0x7c, 0x8e, + 0x83, 0x8c, 0x89, 0x96, 0x75, 0x9c, 0x7f, 0x9f, 0x8b, 0x08, 0xa5, 0xa1, + 0xa1, 0xa7, 0xc0, 0x47, 0xb2, 0x2e, 0x1f, 0x4c, 0x8b, 0x5d, 0x7d, 0x64, + 0x6c, 0x67, 0x6f, 0x7a, 0x6c, 0x8b, 0x66, 0x8b, 0x6a, 0x9a, 0x6d, 0xa4, + 0x78, 0x99, 0x82, 0x94, 0x86, 0xaa, 0x7c, 0x63, 0x7d, 0x78, 0x80, 0x79, + 0x77, 0x08, 0x78, 0x76, 0x7f, 0x6c, 0x8b, 0x6e, 0x8b, 0x35, 0xe3, 0x4d, + 0xf7, 0x10, 0x8b, 0xf7, 0x03, 0x8b, 0xc9, 0xb4, 0x9f, 0xe3, 0x08, 0x73, + 0x94, 0x05, 0x0e, 0xfb, 0x36, 0xf7, 0xab, 0x84, 0x15, 0xf7, 0x0f, 0x9c, + 0xe3, 0xf7, 0x04, 0x8b, 0xf7, 0x21, 0x8b, 0xf7, 0x1d, 0x37, 0xee, 0xfb, + 0x13, 0x94, 0x08, 0xdb, 0x07, 0x8b, 0xb0, 0x8c, 0x9e, 0x8d, 0xa2, 0x08, + 0x5c, 0x9e, 0x05, 0x8d, 0x73, 0x8c, 0x72, 0x8b, 0x63, 0x08, 0x32, 0x07, + 0xfb, 0x0c, 0x7d, 0x30, 0xfb, 0x06, 0x8b, 0xfb, 0x1e, 0x8b, 0xfb, 0x1f, + 0xe1, 0x25, 0xf7, 0x11, 0x81, 0x08, 0x26, 0x07, 0x8b, 0x5e, 0x8a, 0x6f, + 0x89, 0x6f, 0x08, 0xba, 0x80, 0x05, 0x89, 0xac, 0x8b, 0x8e, 0x8a, 0xb7, + 0x08, 0x8b, 0xa6, 0x8b, 0xf7, 0x00, 0x05, 0x62, 0xb3, 0x15, 0x6f, 0x96, + 0x77, 0x9b, 0x7c, 0xa2, 0x6b, 0xbc, 0x78, 0xd7, 0x8b, 0xda, 0x8b, 0xf7, + 0x05, 0xb6, 0xd1, 0xd2, 0x8e, 0x08, 0xfc, 0x4c, 0x07, 0xb4, 0xf8, 0x45, + 0x15, 0xd2, 0x71, 0xb6, 0x2c, 0x8b, 0xfb, 0x13, 0x8b, 0xfb, 0x0a, 0x62, + 0x47, 0x42, 0x87, 0x08, 0xf8, 0x4a, 0x07, 0x0e, 0xfb, 0xa4, 0xf8, 0x0d, + 0xf8, 0x88, 0x15, 0xfb, 0x03, 0xfb, 0xec, 0x6d, 0xf7, 0x2e, 0x05, 0x6d, + 0xf7, 0x2d, 0x6b, 0xbd, 0x48, 0x8b, 0x6d, 0x8b, 0x70, 0x7d, 0x7b, 0x74, + 0x75, 0x6c, 0x86, 0x72, 0x89, 0x37, 0x08, 0x7e, 0xa1, 0x07, 0x8d, 0xa6, + 0x8d, 0x9a, 0x8f, 0x99, 0x96, 0xab, 0xa3, 0x9f, 0xa8, 0x8b, 0xa6, 0x8b, + 0x9e, 0x7a, 0x9e, 0x62, 0xa3, 0x57, 0xa5, 0x30, 0x95, 0x41, 0x08, 0x97, + 0x38, 0x05, 0x88, 0x81, 0x80, 0x6b, 0x78, 0x55, 0x77, 0x54, 0x85, 0x6e, + 0x8b, 0x69, 0x08, 0x5c, 0xa0, 0x6c, 0xab, 0xb4, 0xa6, 0xbe, 0xdb, 0x1e, + 0x8b, 0xaa, 0x86, 0xbb, 0x7f, 0xd6, 0x08, 0xf7, 0x5f, 0xf8, 0x46, 0x20, + 0x8b, 0x05, 0x0e, 0x3b, 0xf7, 0x0b, 0x16, 0xe3, 0xf8, 0x00, 0x06, 0xaf, + 0xc1, 0xae, 0xa4, 0xb7, 0x8b, 0x08, 0xc4, 0xae, 0x64, 0x4b, 0x1f, 0xfc, + 0x4b, 0x07, 0x8b, 0x69, 0x91, 0x65, 0x99, 0x58, 0x08, 0xe8, 0x06, 0x7b, + 0xbc, 0x85, 0xa5, 0x8b, 0xa4, 0x08, 0xf8, 0x7f, 0x07, 0xde, 0x4f, 0xc8, + 0x38, 0x1e, 0x50, 0x8b, 0x61, 0x70, 0x55, 0x40, 0x86, 0xa9, 0x86, 0x98, + 0x82, 0x99, 0x08, 0x7a, 0xa2, 0x6e, 0x99, 0x6d, 0x8b, 0x63, 0x8b, 0x65, + 0x72, 0x78, 0x63, 0x80, 0x73, 0x87, 0x76, 0x8b, 0x66, 0x08, 0xa3, 0x06, + 0x91, 0xc9, 0x99, 0xa8, 0xa3, 0x8b, 0x08, 0xa9, 0xa1, 0x64, 0x55, 0x1f, + 0x8a, 0xfb, 0xf8, 0x05, 0x0e, 0xfb, 0xf6, 0xf7, 0x43, 0xf8, 0x95, 0x15, + 0x62, 0x79, 0x3d, 0x73, 0x53, 0x80, 0x08, 0x72, 0x07, 0x9e, 0x8d, 0x97, + 0x8c, 0x93, 0x8b, 0x08, 0xb2, 0x95, 0x7b, 0x4a, 0x1f, 0xfb, 0x85, 0x07, + 0x8b, 0x56, 0x90, 0x75, 0x9a, 0x77, 0x9b, 0x75, 0xa6, 0x7f, 0xa7, 0x8b, + 0xb1, 0x8b, 0xaf, 0x9f, 0xa1, 0xaa, 0x97, 0x9d, 0x91, 0x9d, 0x93, 0xac, + 0x08, 0x6f, 0x8c, 0x05, 0x81, 0x5a, 0x7d, 0x77, 0x72, 0x8b, 0x6a, 0x8b, + 0x7a, 0xaa, 0x8c, 0xc8, 0x08, 0xf8, 0x12, 0x07, 0x0e, 0x3b, 0xf7, 0x8e, + 0xf8, 0x90, 0x15, 0xfb, 0x12, 0x84, 0x33, 0x2a, 0x8b, 0xfb, 0x1a, 0x8b, + 0xfb, 0x27, 0xf5, 0xfb, 0x07, 0xf7, 0x20, 0x84, 0x08, 0xfb, 0x73, 0xce, + 0xf7, 0x73, 0x07, 0xf7, 0x16, 0x8e, 0xf7, 0x00, 0xf7, 0x0d, 0x8b, 0xf7, + 0x23, 0x08, 0xf7, 0x16, 0x32, 0xf7, 0x07, 0x27, 0x1e, 0x3f, 0x5a, 0x4c, + 0x2b, 0x1f, 0x8b, 0x8b, 0x8b, 0x7e, 0x8c, 0x73, 0x08, 0x93, 0xfb, 0xa5, + 0x05, 0x35, 0x97, 0x59, 0xe2, 0x8b, 0xf7, 0x20, 0x8b, 0xf7, 0x01, 0xad, + 0xcd, 0xd1, 0xa6, 0x08, 0xa2, 0x07, 0xe2, 0xfb, 0x5f, 0x15, 0x8a, 0x98, + 0x8b, 0x95, 0x8b, 0x8d, 0x08, 0xd0, 0x9e, 0xb0, 0xad, 0xc2, 0xc2, 0x26, + 0x27, 0x1e, 0x8b, 0xfb, 0x01, 0x4f, 0x3e, 0x31, 0x84, 0x08, 0x7f, 0xf7, + 0x9b, 0x05, 0x0e, 0xf7, 0x59, 0xf7, 0xb6, 0x15, 0xf7, 0x73, 0x07, 0x6c, + 0x79, 0x58, 0x7a, 0x39, 0x79, 0x08, 0x72, 0x07, 0x9d, 0x8d, 0x96, 0x8c, + 0x93, 0x8b, 0x08, 0xb3, 0x94, 0x7b, 0x4a, 0x1f, 0xfb, 0xf9, 0xd9, 0xf7, + 0x8e, 0x07, 0xf7, 0x25, 0xfb, 0x44, 0x05, 0xa1, 0x6f, 0x8c, 0x8a, 0x8b, + 0x84, 0x8b, 0x7f, 0x84, 0x87, 0x6b, 0x89, 0x08, 0x86, 0x77, 0xf7, 0x81, + 0xa3, 0x82, 0x06, 0x78, 0x8b, 0x7d, 0x8f, 0x7a, 0x95, 0x7d, 0x93, 0x8b, + 0x8b, 0x55, 0xcc, 0x08, 0xfb, 0x2f, 0xf7, 0x57, 0xb7, 0xb4, 0x05, 0xd0, + 0xcb, 0x9e, 0x99, 0x9d, 0x8b, 0x94, 0x8b, 0x91, 0x88, 0x9d, 0x7d, 0x9b, + 0x7e, 0x92, 0x88, 0x9b, 0x8b, 0x08, 0xac, 0xa6, 0xa3, 0xa8, 0xac, 0x6c, + 0xa2, 0x5f, 0x1f, 0x73, 0x8b, 0x75, 0x84, 0x74, 0x7c, 0x68, 0x75, 0x3b, + 0x46, 0x58, 0x58, 0x08, 0x78, 0x79, 0x6b, 0x6e, 0x05, 0x0e, 0xd6, 0xf8, + 0xce, 0x15, 0x92, 0xc4, 0xa8, 0xac, 0xb8, 0x8b, 0xab, 0x8b, 0xa6, 0x72, + 0x9a, 0x5e, 0x92, 0x77, 0x94, 0x6a, 0x94, 0x65, 0x08, 0xfb, 0x7b, 0xfc, + 0x87, 0xe9, 0x8b, 0xf7, 0x3e, 0xf7, 0xfa, 0x05, 0xab, 0xfb, 0x57, 0x9b, + 0x44, 0x9d, 0x64, 0xa1, 0x60, 0xab, 0x74, 0xb0, 0x8b, 0xb2, 0x8b, 0xaa, + 0xa3, 0x9c, 0xb7, 0x96, 0xa6, 0x8f, 0xa6, 0x8c, 0xba, 0x08, 0x76, 0x06, + 0x83, 0x57, 0x74, 0x6e, 0x67, 0x8b, 0x6d, 0x8b, 0x71, 0x9e, 0x7b, 0xae, + 0x7e, 0xa5, 0x84, 0xa5, 0x7d, 0xd5, 0x08, 0x70, 0xf7, 0x15, 0x05, 0x8a, + 0x8e, 0x8a, 0x92, 0x89, 0x95, 0x74, 0xf7, 0x15, 0x67, 0xf7, 0x0e, 0x73, + 0xaf, 0x75, 0xab, 0x6d, 0x9c, 0x6a, 0x8b, 0x4e, 0x8b, 0x6b, 0x57, 0x80, + 0xfb, 0x0a, 0x08, 0xa3, 0x06, 0x0e, 0x20, 0xf8, 0x4e, 0xf8, 0x88, 0x15, + 0x32, 0x8b, 0x8c, 0xfc, 0x05, 0x05, 0x67, 0x58, 0x69, 0x75, 0x61, 0x8b, + 0x08, 0x51, 0x69, 0xb4, 0xd1, 0x1f, 0xf7, 0xdf, 0x33, 0xfc, 0x74, 0x07, + 0x8b, 0x76, 0x87, 0x72, 0x84, 0x6d, 0x7a, 0x4d, 0x8a, 0x85, 0x8b, 0x74, + 0x08, 0x61, 0xa0, 0x6d, 0xa8, 0xa8, 0x9f, 0xa9, 0xb7, 0x1e, 0x8b, 0xa0, + 0x88, 0x98, 0x7b, 0xc5, 0x81, 0xaf, 0x89, 0x95, 0x8b, 0xa7, 0x08, 0x97, + 0x07, 0xb5, 0x68, 0xa2, 0x80, 0xad, 0x8b, 0xbd, 0x8b, 0xbe, 0xaa, 0xc0, + 0xc9, 0x93, 0x6b, 0x90, 0x7f, 0x95, 0x7c, 0x08, 0x9a, 0x76, 0xa6, 0x7e, + 0xa8, 0x8b, 0xc9, 0x8b, 0xb6, 0xb7, 0x99, 0xd8, 0x08, 0x70, 0x8c, 0x05, + 0x87, 0x65, 0x76, 0x6d, 0x74, 0x8b, 0x08, 0x6d, 0x77, 0xaf, 0xc1, 0x1f, + 0xf8, 0x05, 0x07, 0x0e, 0xfb, 0x36, 0x82, 0xf8, 0x5f, 0x15, 0xc4, 0x8a, + 0x8d, 0x89, 0xa3, 0x4f, 0x08, 0xf7, 0x35, 0xfc, 0x2d, 0xa9, 0x8b, 0x05, + 0xa0, 0xc2, 0x8c, 0x8d, 0xa5, 0xbe, 0x92, 0x99, 0x91, 0x99, 0x91, 0x98, + 0x08, 0xc6, 0xf7, 0x02, 0x05, 0xc7, 0xf7, 0x03, 0xa3, 0xc7, 0x8b, 0xaf, + 0x08, 0xac, 0x71, 0xa6, 0x6b, 0x6f, 0x72, 0x71, 0x6d, 0x1e, 0x8b, 0x85, + 0x8c, 0x88, 0x94, 0x5c, 0x90, 0x72, 0x8d, 0x7c, 0x8b, 0x80, 0x8b, 0x71, + 0x83, 0x72, 0x73, 0x5f, 0x08, 0x46, 0xfb, 0x1a, 0xfb, 0x2f, 0xf8, 0x1c, + 0x05, 0x5e, 0x7c, 0x63, 0x83, 0x5a, 0x89, 0x08, 0x6e, 0x07, 0x0e, 0xf7, + 0xa8, 0xf8, 0x95, 0x15, 0xfb, 0x1d, 0x23, 0xfb, 0x0a, 0xfb, 0x2e, 0xfb, + 0x26, 0xec, 0xfb, 0x00, 0xf7, 0x16, 0xf7, 0x1a, 0xf4, 0xf7, 0x0d, 0xf7, + 0x2f, 0xf7, 0x24, 0x2b, 0xf5, 0xfb, 0x15, 0x1f, 0x75, 0x66, 0x15, 0xe3, + 0xc8, 0x20, 0xfb, 0x2c, 0xfb, 0x0e, 0x5f, 0x44, 0x40, 0x1f, 0x65, 0x8b, + 0x64, 0xa1, 0x75, 0xad, 0x6b, 0xbc, 0x78, 0xd9, 0x8b, 0xd9, 0x08, 0xf7, + 0x0d, 0xb7, 0xd1, 0xd7, 0x1e, 0x0e, 0xa9, 0xf7, 0xf0, 0x15, 0xac, 0xbf, + 0x9c, 0x96, 0xbb, 0x8b, 0x08, 0xb9, 0x8b, 0x71, 0xfb, 0x72, 0x05, 0x87, + 0x6f, 0x7e, 0x75, 0x69, 0x6c, 0x6c, 0x6f, 0x82, 0x7b, 0x8b, 0x75, 0x8b, + 0x6d, 0xa3, 0x72, 0xaa, 0x8b, 0xaa, 0x8b, 0xa3, 0xa2, 0x98, 0xb6, 0x94, + 0xa5, 0x99, 0xf1, 0x94, 0xf0, 0x08, 0x97, 0xf7, 0x15, 0xf7, 0x01, 0x8b, + 0x05, 0x7f, 0x3c, 0x82, 0xfb, 0x00, 0x8b, 0x52, 0x8b, 0xfb, 0x04, 0xb1, + 0x47, 0xc8, 0x8b, 0xb2, 0x8b, 0xae, 0xa6, 0xa3, 0xba, 0x99, 0xa7, 0x8f, + 0x9e, 0x8e, 0xbd, 0x08, 0x73, 0x06, 0x86, 0x5b, 0x78, 0x72, 0x6a, 0x8b, + 0x77, 0x8b, 0x76, 0x99, 0x80, 0xa0, 0x82, 0x9d, 0x88, 0x9b, 0x8b, 0xac, + 0x8b, 0xd7, 0x90, 0xe8, 0x92, 0xc2, 0x08, 0xf7, 0x12, 0xe4, 0xfb, 0xf2, + 0x06, 0x55, 0x8b, 0x78, 0x84, 0x6e, 0x6f, 0x6f, 0x6f, 0x7b, 0x6e, 0x7a, + 0x4f, 0x08, 0x9f, 0x06, 0x0e, 0xfb, 0x36, 0xf7, 0x9c, 0xf9, 0x42, 0x15, + 0x64, 0x8b, 0x63, 0x7b, 0x66, 0x6c, 0x47, 0x54, 0x66, 0xfb, 0x00, 0x8b, + 0xfb, 0x20, 0x8b, 0xfb, 0x17, 0xac, 0x24, 0xc6, 0x52, 0xb2, 0x66, 0xba, + 0x76, 0xb6, 0x8b, 0xb2, 0x8b, 0xb2, 0x9b, 0xb1, 0xaa, 0xce, 0xc2, 0xb1, + 0xf6, 0x8b, 0xf7, 0x1b, 0x08, 0x8b, 0xf7, 0x1d, 0x6b, 0xf1, 0x4f, 0xc5, + 0x64, 0xb0, 0x5d, 0xa0, 0x5f, 0x8b, 0x08, 0xf7, 0x0a, 0xfc, 0x0a, 0x15, + 0x89, 0xfb, 0x06, 0x7f, 0x4a, 0x6e, 0x56, 0x79, 0x6c, 0x6b, 0x74, 0x72, + 0x8b, 0x71, 0x8b, 0x6b, 0xa3, 0x7a, 0xa9, 0x6e, 0xc0, 0x7f, 0xcc, 0x89, + 0xf7, 0x06, 0x08, 0xf7, 0x80, 0x06, 0xfb, 0x80, 0xc3, 0x15, 0x8d, 0xf7, + 0x01, 0x98, 0xcd, 0xa7, 0xbf, 0x9c, 0xa9, 0xac, 0xa3, 0xa4, 0x8b, 0xa4, + 0x8b, 0xac, 0x73, 0x9c, 0x6d, 0xa7, 0x57, 0x98, 0x49, 0x8d, 0xfb, 0x01, + 0x08, 0xfb, 0x80, 0x06, 0x0e, 0xf7, 0x2a, 0xb9, 0x15, 0xa5, 0x65, 0xb4, + 0x76, 0xbd, 0x8b, 0x08, 0xf7, 0x0b, 0xf3, 0xf7, 0x16, 0xf7, 0x2a, 0xf7, + 0x22, 0x30, 0xf3, 0xfb, 0x11, 0x1f, 0x6a, 0x8b, 0x76, 0x86, 0x72, 0x7d, + 0x65, 0x76, 0x69, 0x6e, 0x71, 0x6b, 0x6f, 0x68, 0x82, 0x69, 0x8b, 0x44, + 0x08, 0xfc, 0x1c, 0x07, 0x8b, 0x63, 0x89, 0x74, 0x83, 0x66, 0x08, 0xe9, + 0x06, 0x90, 0xad, 0x8b, 0x8d, 0x8c, 0xda, 0x08, 0xf7, 0x2b, 0x07, 0x85, + 0xf7, 0xa8, 0x15, 0x9a, 0x07, 0x8b, 0xb1, 0x91, 0xa2, 0x9d, 0xa2, 0x9b, + 0xa0, 0x9d, 0x96, 0xa1, 0x8b, 0x08, 0xe9, 0xdb, 0xfb, 0x01, 0xfb, 0x13, + 0xfb, 0x00, 0x53, 0x42, 0x39, 0x1f, 0x62, 0x8b, 0x61, 0xa8, 0x78, 0xb3, + 0x85, 0x97, 0x8a, 0x92, 0x8a, 0xaa, 0x08, 0x85, 0xf7, 0x3b, 0x05, 0x0e, + 0x3b, 0xf8, 0xe0, 0xf8, 0x31, 0x15, 0xe2, 0xfb, 0x77, 0x07, 0x3c, 0x8b, + 0x55, 0x82, 0x5d, 0x77, 0x2a, 0x5f, 0x54, 0x3d, 0x8b, 0x2e, 0x8b, 0x4a, + 0xa4, 0x49, 0xb9, 0x57, 0xbf, 0x4f, 0xc4, 0x71, 0xda, 0x8b, 0xcf, 0x8b, + 0xc5, 0xa0, 0xb9, 0xb4, 0xb8, 0xb4, 0xa6, 0xc4, 0x8b, 0xc1, 0x08, 0x8b, + 0xd7, 0x51, 0xd6, 0x21, 0xc8, 0x08, 0xf7, 0x6f, 0x06, 0xfb, 0x9e, 0x16, + 0xe1, 0x32, 0x9e, 0x65, 0x8b, 0x39, 0x08, 0x23, 0x59, 0x45, 0x41, 0x2f, + 0x3f, 0xf0, 0xf7, 0x0f, 0xeb, 0xc9, 0xca, 0xe9, 0x1e, 0xaa, 0x06, 0x0e, + 0xfb, 0x88, 0xaf, 0xf7, 0xc9, 0x15, 0x96, 0xa9, 0x98, 0xa4, 0x9a, 0x9e, + 0x99, 0x9c, 0x98, 0x90, 0xa6, 0x8b, 0x08, 0xd4, 0x06, 0x7c, 0xfb, 0x02, + 0x85, 0x40, 0x8b, 0x4d, 0x8b, 0x20, 0xb0, 0x4b, 0xc9, 0x8b, 0xb3, 0x8b, + 0xb3, 0xa8, 0x9b, 0xb4, 0x97, 0xa8, 0x8f, 0xa7, 0x8d, 0xba, 0x08, 0x72, + 0x06, 0x83, 0x52, 0x7d, 0x77, 0x6c, 0x8b, 0x5f, 0x8b, 0x69, 0xb5, 0x8b, + 0xc1, 0x8b, 0x9b, 0x8d, 0xaa, 0x8e, 0xae, 0x8c, 0x95, 0x8d, 0xa9, 0x8d, + 0xab, 0x8e, 0xb1, 0x8b, 0x95, 0x8e, 0xa2, 0x08, 0xf7, 0x38, 0xea, 0xfb, + 0x77, 0x06, 0x57, 0x8b, 0x6c, 0x7e, 0x6b, 0x68, 0x6b, 0x68, 0x7a, 0x65, + 0x7a, 0x45, 0x08, 0xa5, 0x06, 0x0e, 0x20, 0xb0, 0xf8, 0x00, 0x15, 0x98, + 0xb8, 0xa1, 0xa3, 0xa7, 0x8b, 0xa7, 0x8b, 0x94, 0x76, 0x8c, 0x43, 0x08, + 0x8e, 0xfb, 0x36, 0x05, 0x8d, 0xfb, 0x0c, 0xca, 0x44, 0xf4, 0x8b, 0xcd, + 0x8b, 0xc5, 0xa4, 0xb0, 0xb5, 0xb2, 0xba, 0xa3, 0xd5, 0x8b, 0xd6, 0x8b, + 0xd1, 0x75, 0xcb, 0x64, 0xb9, 0x6b, 0xb0, 0x6b, 0x9f, 0x48, 0xa5, 0x08, + 0x83, 0x72, 0x05, 0xb3, 0x75, 0x9d, 0x7d, 0x9b, 0x74, 0xa7, 0x65, 0x9b, + 0x50, 0x8b, 0x4a, 0x8b, 0x4f, 0x7e, 0x4e, 0x73, 0x59, 0x76, 0x60, 0x6c, + 0x73, 0x64, 0x8b, 0x52, 0x8b, 0x62, 0xc7, 0x8a, 0xe1, 0x08, 0x88, 0xf7, + 0x44, 0x05, 0x8a, 0xf7, 0x08, 0x70, 0xb9, 0x4b, 0x8b, 0x6a, 0x8b, 0x71, + 0x7e, 0x78, 0x70, 0x7a, 0x74, 0x85, 0x7e, 0x79, 0x51, 0x89, 0x87, 0x8a, + 0x86, 0x89, 0x85, 0x08, 0xa9, 0x06, 0x0e, 0xa9, 0xf9, 0x33, 0xf8, 0x81, + 0x15, 0xe5, 0xfc, 0x88, 0x07, 0x66, 0x8b, 0x77, 0x84, 0x6e, 0x74, 0x69, + 0x6f, 0x75, 0x69, 0x7a, 0x59, 0x08, 0x9c, 0x06, 0xba, 0xb2, 0xaf, 0x97, + 0xd3, 0x8c, 0x2b, 0x70, 0x4c, 0x23, 0x8b, 0xfb, 0x18, 0x8b, 0xfb, 0x1d, + 0xd9, 0x21, 0xf1, 0x8b, 0xc8, 0x8b, 0xb9, 0xac, 0xad, 0xcf, 0xad, 0x47, + 0xb9, 0x6a, 0xc8, 0x8b, 0xf1, 0x8b, 0xd9, 0xf5, 0x8b, 0xf7, 0x1d, 0x08, + 0x8b, 0xf7, 0x19, 0x4b, 0xf4, 0x2a, 0xa4, 0x08, 0xf7, 0x39, 0x06, 0xfb, + 0x98, 0x16, 0xb0, 0x80, 0xa1, 0x7f, 0xa1, 0x76, 0xb6, 0x63, 0xa5, 0x3a, + 0x8b, 0x31, 0x8b, 0x4a, 0x7f, 0x4d, 0x78, 0x67, 0x7f, 0x74, 0x72, 0x7c, + 0x70, 0x8b, 0x6b, 0x8b, 0x6c, 0xa1, 0x7c, 0xac, 0x82, 0x9e, 0x88, 0x99, + 0x85, 0xad, 0x08, 0xa3, 0xcf, 0x91, 0xaa, 0x8b, 0xbc, 0x08, 0xd0, 0x77, + 0xb5, 0x69, 0x69, 0x77, 0x61, 0x46, 0x1e, 0x8b, 0x5a, 0x91, 0x6c, 0xa3, + 0x47, 0x85, 0x69, 0x88, 0x7d, 0x82, 0x78, 0x7c, 0x6a, 0x6c, 0x75, 0x6b, + 0x8b, 0x70, 0x8b, 0x72, 0x9a, 0x7f, 0xa2, 0x78, 0xaf, 0x7f, 0xca, 0x8b, + 0xcb, 0x8b, 0xdd, 0xa2, 0xda, 0xb0, 0xb4, 0x08, 0xa2, 0xa4, 0xa4, 0x9a, + 0xb5, 0x98, 0x08, 0xf7, 0x16, 0x06, 0x0e, 0x8e, 0xf8, 0x40, 0xf8, 0x7b, + 0x15, 0xb0, 0x81, 0xa1, 0x7f, 0xa1, 0x77, 0xb6, 0x63, 0xa5, 0x3c, 0x8b, + 0x33, 0x8b, 0x4b, 0x7f, 0x4c, 0x78, 0x67, 0x7f, 0x74, 0x72, 0x7c, 0x71, + 0x8b, 0x59, 0x8b, 0x6a, 0xb4, 0x7d, 0xdc, 0xa3, 0xce, 0x91, 0xab, 0x8b, + 0xbc, 0x08, 0xd0, 0x77, 0xb5, 0x69, 0x69, 0x77, 0x61, 0x46, 0x1e, 0x8b, + 0x5a, 0x91, 0x6b, 0xa3, 0x48, 0x7d, 0x3b, 0x6a, 0x61, 0x59, 0x8b, 0x71, + 0x8b, 0x72, 0x9a, 0x7f, 0xa2, 0x78, 0xaf, 0x7f, 0xc9, 0x8b, 0xcc, 0x8b, + 0xdc, 0xa2, 0xd7, 0xb0, 0xb4, 0xa2, 0xa4, 0xa4, 0x99, 0xb5, 0x97, 0x08, + 0xa5, 0x07, 0x55, 0x8a, 0x68, 0x85, 0x6c, 0x7e, 0x38, 0x67, 0x56, 0x25, + 0x8b, 0xfb, 0x10, 0x8b, 0xfb, 0x1e, 0xd9, 0x21, 0xf1, 0x8b, 0xc7, 0x8b, + 0xba, 0xac, 0xad, 0xcf, 0xad, 0x47, 0xba, 0x6a, 0xc7, 0x8b, 0xf1, 0x8b, + 0xd9, 0xf5, 0x8b, 0xf7, 0x1e, 0x08, 0x8b, 0xf7, 0x0a, 0x5a, 0xee, 0x3e, + 0xb3, 0x6b, 0x9c, 0x65, 0x92, 0x4f, 0x8c, 0x08, 0x71, 0x07, 0x0e, 0xfb, + 0x52, 0xf7, 0x41, 0xf9, 0x90, 0x15, 0x82, 0x8c, 0x83, 0x8c, 0x86, 0x8b, + 0x5e, 0x8b, 0x64, 0x67, 0x8b, 0x62, 0x8b, 0x66, 0xa0, 0x75, 0xbb, 0x7d, + 0x08, 0x73, 0x73, 0x7e, 0x6d, 0x8b, 0x6a, 0x8b, 0x65, 0x9b, 0x6b, 0xb1, + 0x67, 0x69, 0x71, 0x7a, 0x7c, 0x7a, 0x77, 0x67, 0x61, 0x75, 0x4e, 0x8b, + 0x51, 0x8b, 0x3c, 0xb4, 0x42, 0xc7, 0x6d, 0xab, 0x7b, 0xb2, 0x85, 0xc8, + 0x8b, 0x08, 0x9d, 0x8b, 0xa0, 0x8c, 0xbb, 0x8d, 0xb2, 0x8d, 0xaa, 0x6e, + 0x8b, 0x64, 0x8b, 0x65, 0x70, 0x6f, 0x66, 0x8b, 0x86, 0x8b, 0x78, 0x8d, + 0x77, 0x8f, 0x74, 0x8e, 0x82, 0x8c, 0x82, 0x8b, 0x08, 0x72, 0x7a, 0x7a, + 0x72, 0x69, 0xad, 0x73, 0xbc, 0x1f, 0xba, 0x8b, 0xaf, 0x9f, 0xac, 0xb6, + 0xa7, 0xb1, 0x9b, 0xb9, 0x8b, 0xb9, 0x8b, 0xb8, 0x7a, 0xae, 0x6b, 0xa3, + 0x08, 0x74, 0x9d, 0x75, 0x90, 0x5e, 0x8b, 0x08, 0x34, 0x06, 0x60, 0x8b, + 0x69, 0x8f, 0x79, 0x93, 0x60, 0x9e, 0x6e, 0xba, 0x8b, 0xbf, 0x8b, 0xd2, + 0xb6, 0xc7, 0xdf, 0xbb, 0xa7, 0x81, 0x9f, 0x88, 0xaa, 0x8b, 0x08, 0xda, + 0xbb, 0xa0, 0xae, 0xa2, 0x71, 0x98, 0x5f, 0x1f, 0x64, 0x8b, 0x67, 0x80, + 0x45, 0x6c, 0x60, 0xaa, 0x7d, 0x9f, 0x8b, 0xab, 0x8b, 0xaa, 0x9e, 0xa9, + 0xb0, 0xa7, 0xbd, 0x8d, 0xad, 0x91, 0xa6, 0x99, 0xad, 0x9c, 0xa1, 0xa4, + 0x8b, 0xa2, 0x8b, 0x9e, 0x7b, 0x96, 0x6f, 0x8b, 0x08, 0x66, 0x8b, 0x61, + 0x74, 0x4c, 0x52, 0x08, 0x6b, 0x8c, 0x76, 0x9e, 0x8b, 0xa5, 0x8b, 0xa1, + 0x9c, 0x9a, 0xae, 0x95, 0x08, 0x9d, 0x07, 0x0e, 0x8e, 0xf8, 0x19, 0xf8, + 0x88, 0x15, 0x4a, 0xfc, 0x60, 0x06, 0x49, 0x9a, 0x70, 0xb3, 0x84, 0xe8, + 0x08, 0x79, 0xf7, 0x3d, 0x05, 0x86, 0xbd, 0x86, 0x9e, 0x7b, 0xa5, 0x74, + 0xb0, 0x62, 0xa3, 0x63, 0x8b, 0x79, 0x8b, 0x7c, 0x88, 0x6c, 0x81, 0x08, + 0x78, 0x07, 0xcc, 0x80, 0x95, 0x80, 0x94, 0x44, 0x08, 0x99, 0xfb, 0x37, + 0x05, 0x95, 0xfb, 0x0a, 0xe2, 0x2e, 0xf7, 0x09, 0x7a, 0x08, 0xfb, 0x6f, + 0xcc, 0xf7, 0x6f, 0x07, 0xf7, 0x09, 0x9c, 0xe2, 0xe8, 0x95, 0xf7, 0x0a, + 0x08, 0x99, 0xf7, 0x37, 0x05, 0x93, 0xd0, 0x95, 0x97, 0xcd, 0x97, 0x08, + 0x9e, 0x07, 0x6c, 0x95, 0x7c, 0x8e, 0x79, 0x8b, 0x67, 0x8b, 0x64, 0x76, + 0x74, 0x6c, 0x78, 0x70, 0x83, 0x74, 0x86, 0x55, 0x08, 0x79, 0xfb, 0x3d, + 0x05, 0x84, 0x2e, 0x70, 0x63, 0x49, 0x7c, 0x08, 0xf8, 0x60, 0x07, 0x0e, + 0xfb, 0x51, 0xf7, 0x6b, 0xf9, 0x88, 0x15, 0x47, 0x86, 0x5e, 0x65, 0x8b, + 0x56, 0x8b, 0x64, 0xa2, 0x78, 0xcd, 0x7b, 0x08, 0x2d, 0xfb, 0x13, 0x66, + 0x28, 0x8b, 0xfb, 0x16, 0x8b, 0x29, 0xa1, 0x54, 0xc5, 0x5e, 0xac, 0x71, + 0xae, 0x7f, 0xb4, 0x8b, 0x91, 0x8b, 0x92, 0x8b, 0x95, 0x8c, 0x08, 0xb6, + 0x8d, 0xa5, 0x8c, 0x93, 0x8b, 0x08, 0xba, 0xa8, 0x73, 0x64, 0x65, 0x6b, + 0x68, 0x69, 0x1f, 0x86, 0x8b, 0x85, 0x8c, 0x85, 0x8c, 0x4e, 0x9b, 0x8b, + 0x8b, 0x80, 0x8b, 0x08, 0x6c, 0x72, 0x76, 0x71, 0x6b, 0xaf, 0x74, 0xbe, + 0xec, 0xd0, 0xd5, 0xf2, 0xe8, 0x4e, 0xbe, 0xfb, 0x04, 0x1f, 0x76, 0x8b, + 0x7f, 0x8b, 0x7f, 0x8a, 0x05, 0x78, 0x06, 0x43, 0x5b, 0xc9, 0xe8, 0x1f, + 0x8b, 0xf7, 0x0c, 0xc7, 0xf7, 0x1e, 0xdf, 0xd6, 0xed, 0x96, 0xdd, 0xbe, + 0x8b, 0xbe, 0x8b, 0x9d, 0x7b, 0x99, 0x75, 0x8b, 0x67, 0x8b, 0x54, 0x68, + 0x31, 0x3a, 0x08, 0x67, 0x96, 0x7a, 0x9e, 0x8b, 0xa8, 0x8b, 0xa6, 0x9d, + 0xa0, 0xae, 0x99, 0x08, 0x9f, 0x07, 0x0e, 0xfb, 0x5f, 0xf7, 0x9f, 0xf8, + 0xc0, 0x15, 0x8b, 0xb8, 0x93, 0x9a, 0xab, 0x9a, 0xa2, 0x95, 0xa1, 0x90, + 0xb7, 0x8e, 0x08, 0xa3, 0x07, 0x2a, 0x8b, 0x73, 0x88, 0x68, 0x7c, 0x62, + 0x79, 0x77, 0x6b, 0x8b, 0x5b, 0x08, 0xfb, 0x46, 0x07, 0x8b, 0x68, 0x84, + 0x7d, 0x72, 0x7c, 0x73, 0x7d, 0x7c, 0x87, 0x59, 0x83, 0x08, 0x73, 0x07, + 0xb9, 0x85, 0x9b, 0x87, 0xa3, 0x7f, 0xa6, 0x7d, 0x93, 0x7c, 0x8b, 0x64, + 0x08, 0xfb, 0x69, 0x07, 0x8b, 0x53, 0x9e, 0x68, 0xb3, 0x7a, 0xae, 0x7b, + 0xa4, 0x88, 0xee, 0x8b, 0x08, 0xa3, 0x07, 0x69, 0x8c, 0x70, 0x90, 0x75, + 0x94, 0x65, 0x9a, 0x82, 0x9a, 0x8b, 0xbb, 0x08, 0xf7, 0x69, 0x07, 0x8b, + 0xb2, 0x7d, 0xa9, 0x6f, 0x9b, 0x75, 0x98, 0x7b, 0x91, 0x5d, 0x93, 0xeb, + 0x9d, 0xa9, 0xa5, 0x8b, 0xca, 0x08, 0xf7, 0x40, 0x07, 0x0e, 0xfc, 0x77, + 0xcc, 0xf9, 0x35, 0x15, 0xfd, 0xe6, 0xd1, 0xf9, 0xe6, 0x45, 0x07, 0x0e, + 0xfb, 0x5f, 0xf7, 0x65, 0x5b, 0x15, 0x8b, 0x5d, 0x82, 0x7c, 0x69, 0x7c, + 0x74, 0x81, 0x6f, 0x85, 0x67, 0x8a, 0x08, 0x73, 0x07, 0xf0, 0x8b, 0xa2, + 0x8e, 0xae, 0x9b, 0xb3, 0x9c, 0x9e, 0xae, 0x8b, 0xc3, 0x08, 0xf7, 0x69, + 0x07, 0x8b, 0xb2, 0x93, 0x9a, 0xa6, 0x99, 0xa3, 0x97, 0x9b, 0x8f, 0xb9, + 0x91, 0x08, 0xa3, 0x07, 0x59, 0x93, 0x7c, 0x8f, 0x73, 0x99, 0x72, 0x9a, + 0x84, 0x99, 0x8b, 0xae, 0x08, 0xf7, 0x46, 0x07, 0x8b, 0xbb, 0x77, 0xab, + 0x62, 0x9d, 0x68, 0x9a, 0x72, 0x8e, 0x2b, 0x8b, 0x08, 0x73, 0x07, 0xb5, + 0x88, 0xa0, 0x87, 0xa1, 0x82, 0xae, 0x7c, 0x94, 0x7b, 0x8b, 0x5d, 0x08, + 0xfb, 0x40, 0x07, 0x8b, 0x4c, 0xa9, 0x71, 0xeb, 0x79, 0x5d, 0x83, 0x7b, + 0x85, 0x75, 0x7e, 0x6f, 0x7b, 0x7d, 0x6d, 0x8b, 0x64, 0x08, 0xfb, 0x69, + 0x07, 0x0e, 0xf8, 0x7d, 0xf7, 0xd9, 0x15, 0x5e, 0x57, 0x76, 0x7f, 0x64, + 0x8b, 0x79, 0x8b, 0x7e, 0x8e, 0x47, 0xa1, 0x08, 0x42, 0xa2, 0x73, 0x90, + 0x6f, 0x8b, 0x52, 0x8b, 0x5c, 0x6f, 0x64, 0x52, 0x08, 0xb6, 0x6a, 0x05, + 0xb8, 0xc0, 0x9b, 0x95, 0xb1, 0x8b, 0x9d, 0x8b, 0x95, 0x89, 0xaf, 0x80, + 0xbb, 0x7d, 0x8b, 0x8b, 0xbc, 0x7b, 0x08, 0xa1, 0x84, 0xa1, 0x88, 0xa0, + 0x8b, 0xcc, 0x8b, 0xbb, 0xa8, 0xaa, 0xc4, 0x08, 0x63, 0xac, 0x05, 0x0e, + 0xda, 0xc0, 0xf7, 0xfd, 0x15, 0xe9, 0x06, 0x89, 0x7c, 0x8b, 0x86, 0x8b, + 0x84, 0x8b, 0x85, 0x8b, 0x84, 0x8d, 0x7c, 0x08, 0x46, 0x8b, 0x73, 0x52, + 0xf1, 0x8b, 0x05, 0xb5, 0xfb, 0x2b, 0xf7, 0x17, 0x25, 0xf7, 0x2e, 0x8b, + 0xd9, 0x8b, 0xd0, 0xa4, 0xcf, 0xc0, 0x08, 0xdb, 0x07, 0x54, 0x4a, 0x3e, + 0x67, 0x37, 0x8b, 0xfb, 0x0d, 0x8b, 0xfb, 0x04, 0xdd, 0x69, 0xf7, 0x06, + 0x08, 0xf8, 0x09, 0x8b, 0xa3, 0xc4, 0xfc, 0x2d, 0x8b, 0x05, 0x8a, 0x9a, + 0x8b, 0x91, 0x8b, 0x92, 0x8b, 0x92, 0x8b, 0x91, 0x8c, 0x99, 0x08, 0xf8, + 0x44, 0x8b, 0xa2, 0xc4, 0x40, 0x8b, 0xfc, 0x04, 0x8b, 0x05, 0xaf, 0xf7, + 0x08, 0xf7, 0x01, 0xdb, 0xf7, 0x0f, 0x8b, 0xdf, 0x8b, 0xd5, 0x68, 0xc4, + 0x49, 0x08, 0xa3, 0xc4, 0x05, 0x46, 0xcf, 0x3b, 0xac, 0x31, 0x8b, 0xfb, + 0x2e, 0x8b, 0xfb, 0x17, 0x25, 0x61, 0xfb, 0x2b, 0x08, 0x3c, 0x8b, 0x73, + 0x52, 0x05, 0x0e, 0x4c, 0x95, 0xf9, 0x17, 0x15, 0xa2, 0x8e, 0x95, 0x8c, + 0x99, 0x8b, 0xd9, 0x8b, 0xc4, 0x5e, 0xa3, 0x39, 0x9b, 0x51, 0x95, 0x3e, + 0x8b, 0x40, 0x08, 0xfb, 0x3c, 0x07, 0x8b, 0x56, 0x88, 0x7d, 0x80, 0x79, + 0x7d, 0x78, 0x70, 0x7f, 0x6a, 0x8b, 0x08, 0x86, 0x71, 0xf7, 0xb3, 0xa5, + 0x86, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9d, 0x88, 0x99, + 0x8b, 0xc0, 0x08, 0xf7, 0x40, 0x07, 0xf7, 0x46, 0xb8, 0xf7, 0x10, 0xcd, + 0x1e, 0x98, 0x8b, 0x90, 0x87, 0x9d, 0x76, 0xa1, 0x6f, 0x99, 0x83, 0xa3, + 0x8b, 0x08, 0xb0, 0xa2, 0xa2, 0xb0, 0x1f, 0xb7, 0x69, 0xa7, 0x55, 0x1e, + 0x41, 0x8b, 0x4c, 0x5f, 0x69, 0x41, 0x74, 0x58, 0x84, 0x6d, 0x7d, 0xfb, + 0x09, 0x89, 0xda, 0x85, 0xc4, 0x80, 0xb4, 0x08, 0x74, 0xdf, 0x37, 0xc1, + 0x20, 0x8b, 0x70, 0x8b, 0x79, 0x89, 0x6c, 0x82, 0x08, 0x97, 0x6b, 0x05, + 0x0e, 0xfc, 0x48, 0xa6, 0xf8, 0x7a, 0x15, 0x9a, 0x81, 0xf7, 0x3a, 0xf7, + 0x41, 0x05, 0x9a, 0x9c, 0x90, 0x94, 0x8b, 0x99, 0x8b, 0xa3, 0x70, 0xa1, + 0x6e, 0x8b, 0x79, 0x8b, 0x80, 0x81, 0x7d, 0x6e, 0x08, 0x25, 0xfb, 0x66, + 0x05, 0x0e, 0xf8, 0xa2, 0xc2, 0x15, 0xfc, 0x85, 0x54, 0xf8, 0x85, 0xc2, + 0x06, 0xf8, 0xdc, 0x04, 0xfc, 0x85, 0xfb, 0x7e, 0x8b, 0x54, 0xf8, 0x85, + 0xfb, 0x7d, 0x8b, 0xc9, 0xfc, 0x36, 0xf7, 0x5b, 0xf8, 0x36, 0xf7, 0x5b, + 0x8b, 0xc9, 0x05, 0x0e, 0xfc, 0x98, 0xfb, 0x48, 0x16, 0xbc, 0x8b, 0xf8, + 0x6b, 0xf9, 0x35, 0x59, 0x8b, 0xfc, 0x6a, 0xfd, 0x35, 0x05, 0x0e, 0xa9, + 0xf7, 0xf9, 0xf7, 0x77, 0x15, 0xc5, 0x44, 0xd1, 0x62, 0xca, 0x8b, 0x08, + 0xde, 0xc4, 0xc8, 0xe5, 0xe3, 0x50, 0xc7, 0x35, 0x1f, 0x48, 0x8b, 0x4b, + 0x64, 0x54, 0x43, 0x52, 0xd3, 0x49, 0xb2, 0x4c, 0x8b, 0x08, 0x37, 0x4e, + 0x4c, 0x33, 0x34, 0xc5, 0x4e, 0xde, 0x1f, 0xc4, 0x8b, 0xc4, 0xa6, 0xb9, + 0xbd, 0x08, 0xa9, 0xae, 0x05, 0xad, 0xb0, 0x15, 0xb6, 0xc7, 0xc6, 0xb1, + 0xc0, 0x8b, 0x08, 0xc1, 0xb1, 0x62, 0x52, 0x50, 0x68, 0x65, 0x55, 0x1f, + 0x56, 0x8b, 0x68, 0xa1, 0x45, 0xd6, 0x08, 0x48, 0x8d, 0x15, 0x5b, 0x4d, + 0x4e, 0x66, 0x57, 0x8b, 0x08, 0x57, 0x68, 0xb4, 0xc5, 0xc4, 0xb0, 0xb2, + 0xc1, 0x1f, 0xbb, 0x8b, 0xb8, 0x71, 0xc4, 0x4d, 0x8f, 0x87, 0x8b, 0x8b, + 0x8e, 0x87, 0x08, 0x0e, 0xfb, 0x4b, 0xf7, 0x08, 0xf8, 0x3a, 0x15, 0x81, + 0x6b, 0xf7, 0x00, 0x8b, 0x05, 0x7f, 0x33, 0x82, 0x36, 0x81, 0x22, 0x7e, + 0xfb, 0x29, 0x82, 0x5b, 0x76, 0x69, 0x7f, 0x79, 0x79, 0x80, 0x7a, 0x8b, + 0x80, 0x8b, 0x84, 0x8f, 0x8b, 0x92, 0x8b, 0x8e, 0x8c, 0x8e, 0x8d, 0x8e, + 0x95, 0x9c, 0x8d, 0x90, 0x8b, 0x97, 0x08, 0x9f, 0x7b, 0x9a, 0x75, 0x6e, + 0x76, 0x76, 0x6f, 0x65, 0xae, 0x6f, 0xba, 0x1e, 0xd3, 0x8b, 0xbb, 0xc2, + 0xae, 0xf7, 0x0e, 0xa6, 0xea, 0x95, 0xc5, 0xa6, 0xf7, 0x7e, 0x08, 0xf7, + 0x0b, 0x8b, 0x95, 0xab, 0xfb, 0x11, 0x8b, 0x05, 0x9d, 0xf7, 0x20, 0x8f, + 0xa3, 0x97, 0xa7, 0x98, 0xaa, 0x9e, 0x9b, 0xa2, 0x8b, 0x97, 0x8b, 0x93, + 0x86, 0x8b, 0x83, 0x8b, 0x89, 0x8a, 0x88, 0x8a, 0x89, 0x82, 0x79, 0x8a, + 0x88, 0x8b, 0x83, 0x08, 0x75, 0x9c, 0x7c, 0xa3, 0xa7, 0xa0, 0xa0, 0xa7, + 0xaf, 0x65, 0xa6, 0x59, 0x1e, 0x2a, 0x8b, 0x53, 0x3a, 0x69, 0xfb, 0x4c, + 0x08, 0x24, 0x06, 0x0e, 0xd1, 0xf8, 0x4b, 0x71, 0x15, 0x6c, 0xb9, 0x84, + 0xa1, 0x8b, 0xbe, 0x8b, 0xa8, 0x90, 0x9b, 0x93, 0x8b, 0x91, 0x8b, 0x91, + 0x86, 0xa5, 0x71, 0xae, 0x67, 0xa9, 0x7d, 0xb1, 0x8b, 0x08, 0xcb, 0xb4, + 0xb9, 0xd4, 0xda, 0x5e, 0xc3, 0x4b, 0x1f, 0x72, 0x8b, 0x6f, 0x82, 0x6f, + 0x79, 0x6d, 0x79, 0x88, 0x89, 0x80, 0x8b, 0x08, 0x81, 0x86, 0x90, 0x95, + 0x1f, 0x8b, 0x96, 0x8f, 0x90, 0xa8, 0x9e, 0xb5, 0xa9, 0xa2, 0xb2, 0x8b, + 0xb5, 0x08, 0xcd, 0x4f, 0xc0, 0x3f, 0x3f, 0x4f, 0x56, 0x49, 0x1e, 0x8b, + 0x61, 0xa2, 0x64, 0xb5, 0x6d, 0xa8, 0x78, 0x8f, 0x86, 0x8b, 0x80, 0x8b, + 0x81, 0x86, 0x86, 0x81, 0x8b, 0x84, 0x8b, 0x82, 0x8e, 0x83, 0x8f, 0x58, + 0xac, 0x78, 0x92, 0x6c, 0x8b, 0x08, 0x4b, 0x5e, 0x53, 0x3c, 0x42, 0xb4, + 0x5d, 0xcb, 0x1f, 0xb2, 0x8b, 0xa8, 0x99, 0xaf, 0xaf, 0xa5, 0xa6, 0x90, + 0x8f, 0x93, 0x8b, 0x08, 0x92, 0x90, 0x7b, 0x6f, 0x1f, 0x8b, 0x57, 0x84, + 0x75, 0x6b, 0x5d, 0x08, 0xf7, 0x18, 0x06, 0x0e, 0xd1, 0xf8, 0x0a, 0x67, + 0x15, 0xf7, 0x76, 0xf7, 0xb9, 0xfb, 0x76, 0xf7, 0xb9, 0xfb, 0x7c, 0xfb, + 0xb9, 0xf7, 0x7c, 0xfb, 0xb9, 0x05, 0x0e, 0xd1, 0xf8, 0x0a, 0x6a, 0x15, + 0xc1, 0xd7, 0x05, 0x94, 0x99, 0x9c, 0xa2, 0xa0, 0xa5, 0xe8, 0xf7, 0x0c, + 0x8b, 0x8b, 0x9e, 0xa8, 0xa8, 0xb7, 0x9a, 0xb9, 0x8b, 0xbb, 0x8b, 0xdb, + 0x5c, 0xc2, 0x48, 0x8b, 0x50, 0x8b, 0x65, 0x6c, 0x70, 0x43, 0x84, 0x78, + 0x87, 0x86, 0x83, 0x8b, 0x08, 0x83, 0x8b, 0x87, 0x90, 0x84, 0x9e, 0x70, + 0xd3, 0x66, 0xaa, 0x4f, 0x8b, 0x47, 0x8b, 0x5d, 0x54, 0x8b, 0x3b, 0x8b, + 0x48, 0xa0, 0x5d, 0xd1, 0x32, 0xd2, 0x2f, 0x94, 0x80, 0xab, 0x5e, 0x08, + 0xc1, 0x3f, 0x05, 0x0e, 0xd1, 0xf8, 0x48, 0x67, 0x15, 0x6d, 0xb6, 0x84, + 0xa2, 0x8b, 0xc4, 0x8b, 0xa1, 0x8f, 0x97, 0x93, 0x8b, 0x8f, 0x8b, 0x8d, + 0x89, 0x99, 0x74, 0xa0, 0x68, 0xa7, 0x7b, 0xb1, 0x8b, 0xca, 0x8b, 0xbb, + 0xbf, 0x8b, 0xce, 0x8b, 0xbb, 0x76, 0xbd, 0x58, 0xd2, 0x08, 0xfb, 0x4e, + 0xf7, 0x96, 0xfb, 0x4e, 0xfb, 0x96, 0x05, 0x58, 0x44, 0x76, 0x59, 0x8b, + 0x5b, 0x8b, 0x48, 0xbc, 0x57, 0xca, 0x8b, 0xb1, 0x8b, 0xa7, 0x9c, 0xa0, + 0xad, 0x98, 0xa1, 0x8e, 0x8e, 0x90, 0x8b, 0x92, 0x8b, 0x8f, 0x7e, 0x8b, + 0x76, 0x8b, 0x52, 0x84, 0x74, 0x6c, 0x60, 0x08, 0xf7, 0x16, 0x06, 0x0e, + 0xf7, 0xfb, 0xf7, 0x23, 0xf7, 0xa8, 0x15, 0xd0, 0xd6, 0xc7, 0xd1, 0xb4, + 0xc0, 0x08, 0x65, 0xb1, 0x05, 0x25, 0xfb, 0x0c, 0x4b, 0x48, 0x36, 0x3e, + 0xdf, 0x3f, 0xcc, 0x46, 0xf1, 0xfb, 0x0b, 0x08, 0xb1, 0xb1, 0x05, 0x62, + 0xc0, 0x4f, 0xd2, 0x46, 0xd5, 0x08, 0xf9, 0x8e, 0x06, 0x46, 0x40, 0x4f, + 0x45, 0x62, 0x56, 0x08, 0xb1, 0x65, 0x05, 0xf1, 0xf7, 0x0b, 0xcc, 0xd0, + 0xdf, 0xd7, 0x36, 0xd8, 0x4b, 0xce, 0x25, 0xf7, 0x0c, 0x08, 0x65, 0x65, + 0x05, 0xb4, 0x56, 0xc7, 0x45, 0xd0, 0x40, 0x08, 0xfd, 0x8e, 0x06, 0x0e, + 0xf7, 0xc4, 0xfa, 0x42, 0xf7, 0x70, 0x15, 0xc3, 0xfd, 0xaa, 0x07, 0xcf, + 0xd5, 0xc7, 0xd1, 0xb4, 0xc0, 0x08, 0x65, 0xb1, 0x05, 0x28, 0xfb, 0x08, + 0x34, 0x2f, 0x4a, 0x54, 0xcb, 0x54, 0xe3, 0x2f, 0xee, 0xfb, 0x08, 0x08, + 0xb1, 0xb1, 0x05, 0x62, 0xc0, 0x4f, 0xd1, 0x47, 0xd5, 0x08, 0xf9, 0xaa, + 0x06, 0x0e, 0x3b, 0xde, 0xf9, 0x01, 0x15, 0xc0, 0xb4, 0xd0, 0xc6, 0xd6, + 0xd0, 0x08, 0xfd, 0xaa, 0xc3, 0xf9, 0xaa, 0x07, 0xd6, 0x46, 0xd0, 0x50, + 0xc0, 0x62, 0x08, 0xb1, 0xb1, 0x05, 0xfb, 0x05, 0xeb, 0x2a, 0xe8, 0x56, + 0xc9, 0x56, 0x4d, 0x2a, 0x2e, 0xfb, 0x05, 0x2b, 0x08, 0xb1, 0x65, 0x05, + 0x0e, 0xf7, 0xc4, 0xf9, 0xdb, 0xf7, 0x70, 0x15, 0x47, 0x41, 0x4f, 0x45, + 0x62, 0x56, 0x08, 0xb1, 0x65, 0x05, 0xee, 0xf7, 0x08, 0xe3, 0xe7, 0xcb, + 0xc2, 0x4b, 0xc2, 0x33, 0xe7, 0x28, 0xf7, 0x08, 0x08, 0x65, 0x65, 0x05, + 0xb4, 0x56, 0xc7, 0x45, 0xcf, 0x41, 0x08, 0xfd, 0xaa, 0x53, 0xf9, 0xaa, + 0x06, 0x0e, 0x3b, 0xf8, 0xa9, 0xf7, 0x9f, 0x15, 0x56, 0x62, 0x46, 0x50, + 0x40, 0x46, 0x08, 0xf9, 0xaa, 0x53, 0xfd, 0xaa, 0x07, 0x40, 0xd0, 0x46, + 0xc6, 0x56, 0xb4, 0x08, 0x65, 0x65, 0x05, 0xf7, 0x05, 0x2b, 0xec, 0x2e, + 0xc0, 0x4d, 0xc0, 0xc9, 0xec, 0xe8, 0xf7, 0x05, 0xeb, 0x08, 0x65, 0xb1, + 0x05, 0x0e, 0xfb, 0xaf, 0xf7, 0x5f, 0xf9, 0x42, 0x15, 0x36, 0x47, 0x48, + 0x36, 0x35, 0xcd, 0x47, 0xdf, 0xdf, 0xcd, 0xce, 0xe1, 0xe1, 0x4b, 0xce, + 0x38, 0x1f, 0x8a, 0x52, 0x15, 0xbd, 0xb4, 0x60, 0x56, 0x55, 0x62, 0x61, + 0x57, 0x58, 0x60, 0xb6, 0xc0, 0xc0, 0xb5, 0xb6, 0xc1, 0x1f, 0x0e, 0x96, + 0xc2, 0x15, 0x54, 0xf8, 0xa0, 0xc2, 0xfc, 0xa0, 0x07, 0xf7, 0xb7, 0xf8, + 0xf3, 0x15, 0x54, 0xfb, 0x83, 0xfb, 0x81, 0x54, 0xf7, 0x81, 0xfb, 0x83, + 0xc2, 0xf7, 0x83, 0xf7, 0x81, 0xc2, 0xfb, 0x81, 0xf7, 0x83, 0x06, 0x0e, + 0xfb, 0xa4, 0x9f, 0xf8, 0x7a, 0x15, 0x9a, 0x81, 0xf7, 0x3a, 0xf7, 0x41, + 0x05, 0x9a, 0x9c, 0x90, 0x94, 0x8b, 0x99, 0x8b, 0xa3, 0x70, 0xa1, 0x6e, + 0x8b, 0x79, 0x8b, 0x80, 0x81, 0x7d, 0x6e, 0x08, 0x25, 0xfb, 0x66, 0x05, + 0xf7, 0x54, 0x16, 0x9a, 0x81, 0xf7, 0x3a, 0xf7, 0x41, 0x05, 0x9a, 0x9c, + 0x90, 0x94, 0x8b, 0x99, 0x8b, 0xa3, 0x70, 0xa1, 0x6e, 0x8b, 0x79, 0x8b, + 0x80, 0x81, 0x7d, 0x6e, 0x08, 0x25, 0xfb, 0x66, 0x05, 0x0e, 0xf8, 0xa2, + 0xc2, 0x15, 0xfc, 0x85, 0x54, 0xf8, 0x85, 0xc2, 0x06, 0xfc, 0x85, 0xf8, + 0xdc, 0x15, 0x8b, 0x4d, 0xf8, 0x36, 0xfb, 0x5b, 0xfc, 0x36, 0xfb, 0x5b, + 0x8b, 0x4d, 0xf8, 0x85, 0xf7, 0x7d, 0x8b, 0xc2, 0xfc, 0x85, 0xf7, 0x7e, + 0x05, 0x0e, 0xf7, 0x80, 0xf7, 0x9f, 0x15, 0xfb, 0x6f, 0xfb, 0x70, 0xb2, + 0x65, 0xf7, 0x6f, 0xf7, 0x6f, 0xf7, 0x6f, 0xfb, 0x6f, 0xb2, 0xb1, 0xfb, + 0x6f, 0xf7, 0x70, 0xf7, 0x6f, 0xf7, 0x6f, 0x64, 0xb2, 0xfb, 0x6f, 0xfb, + 0x70, 0xfb, 0x6f, 0xf7, 0x70, 0x64, 0x64, 0xf7, 0x6f, 0xfb, 0x6f, 0x05, + 0x0e, 0xa9, 0xf9, 0x13, 0xf8, 0x31, 0x15, 0xfb, 0x10, 0x8e, 0x5f, 0x77, + 0x35, 0x2c, 0x81, 0x98, 0x85, 0x93, 0x7c, 0x9a, 0x53, 0xc1, 0x5b, 0xa1, + 0x4f, 0x8b, 0x08, 0x2d, 0x46, 0x4c, 0x35, 0x34, 0xd0, 0x4c, 0xe9, 0x1f, + 0xc7, 0x8b, 0xbb, 0xa2, 0xc3, 0xc0, 0x9a, 0x9a, 0x91, 0x93, 0x95, 0x99, + 0xd3, 0x37, 0xc3, 0x6e, 0xe7, 0x8b, 0x08, 0xad, 0x8b, 0x82, 0xbf, 0x05, + 0x3d, 0x88, 0x46, 0xab, 0x4a, 0xd0, 0xcc, 0xcf, 0xd1, 0xab, 0xd8, 0x88, + 0x08, 0x94, 0xbf, 0x05, 0xfb, 0xb4, 0xfb, 0x29, 0x15, 0x51, 0x46, 0x5a, + 0x6e, 0x53, 0x8b, 0x74, 0x8b, 0x74, 0x92, 0x76, 0x97, 0x6d, 0x9c, 0x7d, + 0xa5, 0x8b, 0xaf, 0x8b, 0xaa, 0x97, 0xa4, 0xa1, 0x9b, 0xa1, 0x9b, 0xa7, + 0x94, 0xa6, 0x8b, 0xbf, 0x8b, 0xc4, 0x6b, 0xba, 0x52, 0x08, 0x8f, 0x86, + 0x8b, 0x8b, 0x8e, 0x88, 0x08, 0x0e, 0xfb, 0x51, 0xf6, 0xf9, 0x36, 0x15, + 0xb8, 0xa2, 0xac, 0x94, 0xad, 0x8b, 0xf0, 0x8b, 0xc6, 0x2c, 0x8b, 0xfb, + 0x37, 0x8b, 0x6e, 0x89, 0x74, 0x86, 0x59, 0x4b, 0xbd, 0x67, 0x9b, 0x58, + 0x8b, 0x5a, 0x8b, 0x62, 0x79, 0x67, 0x64, 0x5f, 0x5d, 0x72, 0x4c, 0x8b, + 0x4d, 0x08, 0xfb, 0x00, 0xde, 0x35, 0xf3, 0x1e, 0xd0, 0x8b, 0xc6, 0xac, + 0xb5, 0xc8, 0xb9, 0xcf, 0xac, 0xf7, 0x1a, 0x8b, 0xf7, 0x08, 0x8b, 0xf7, + 0x5c, 0xfb, 0x07, 0xf7, 0x2b, 0xfb, 0x2c, 0x8b, 0x64, 0x8b, 0x68, 0x83, + 0x54, 0x77, 0x08, 0xb4, 0x58, 0x05, 0xf7, 0x97, 0xfb, 0xfe, 0x15, 0x7b, + 0xfb, 0x03, 0x81, 0x60, 0x71, 0x58, 0x71, 0x56, 0x60, 0x6a, 0x5f, 0x8b, + 0x08, 0x55, 0x69, 0xc0, 0xe0, 0xf7, 0x06, 0xce, 0xe9, 0xdc, 0x1f, 0xad, + 0x8b, 0xa9, 0x7d, 0xab, 0x6a, 0x90, 0x87, 0x8b, 0x8b, 0x8f, 0x87, 0x08, + 0x0e, 0xfb, 0x73, 0xf7, 0x7d, 0xf8, 0x9a, 0x15, 0x25, 0x3a, 0x3b, 0x27, + 0x25, 0xdb, 0x3a, 0xef, 0xef, 0xdb, 0xdb, 0xf1, 0xef, 0x3b, 0xdc, 0x2a, + 0x1f, 0x0e, 0xf7, 0xa6, 0xf7, 0x12, 0x15, 0x68, 0x6f, 0x70, 0x69, 0x68, + 0xa7, 0x6f, 0xad, 0xad, 0xa7, 0xa7, 0xad, 0xad, 0x6f, 0xa7, 0x6a, 0x1f, + 0xf8, 0x23, 0x04, 0x68, 0x6f, 0x6f, 0x6a, 0x68, 0xa7, 0x6f, 0xad, 0xad, + 0xa7, 0xa7, 0xad, 0xad, 0x6f, 0xa7, 0x6a, 0x1f, 0xfb, 0x9c, 0xfb, 0x7b, + 0x15, 0x54, 0xf8, 0xa2, 0xc2, 0xfc, 0xa2, 0x07, 0x0e, 0xf7, 0x4f, 0xf7, + 0x22, 0x15, 0x43, 0xfb, 0x23, 0xb9, 0x73, 0xe0, 0xf7, 0x3b, 0xf7, 0xba, + 0x8b, 0x8b, 0xc2, 0xfb, 0x9f, 0x8b, 0xd2, 0xf7, 0x1f, 0xf7, 0x58, 0x8b, + 0x8b, 0xc2, 0xfb, 0x3d, 0x8b, 0xcf, 0xf7, 0x1a, 0x5c, 0xa3, 0x3b, 0xfb, + 0x32, 0xfb, 0xbd, 0x8b, 0x8b, 0x54, 0x05, 0xf7, 0xa2, 0x8b, 0x45, 0xfb, + 0x1f, 0xfb, 0x5c, 0x8b, 0x8b, 0x54, 0xf7, 0x40, 0x8b, 0x05, 0x0e, 0xf8, + 0xae, 0xf7, 0xba, 0x15, 0xfc, 0xa0, 0x54, 0xf8, 0xa0, 0xc2, 0x06, 0xfb, + 0x2c, 0x04, 0xfc, 0xa0, 0x54, 0xf8, 0xa0, 0xc2, 0x06, 0xf7, 0xc4, 0x04, + 0xfc, 0xa0, 0x54, 0xf8, 0xa0, 0xc2, 0x06, 0x0e, 0xf8, 0x7d, 0xf7, 0x8f, + 0x15, 0x5e, 0x57, 0x76, 0x7f, 0x64, 0x8b, 0x79, 0x8b, 0x7d, 0x8f, 0x48, + 0x9f, 0x08, 0x42, 0xa2, 0x73, 0x90, 0x6f, 0x8b, 0x50, 0x8b, 0x5c, 0x70, + 0x63, 0x52, 0x08, 0xb6, 0x69, 0x05, 0xb9, 0xc0, 0x9c, 0x95, 0xb2, 0x8b, + 0x9d, 0x8b, 0x96, 0x89, 0xae, 0x81, 0x08, 0xec, 0x6d, 0x05, 0xa0, 0x84, + 0xa2, 0x88, 0xa0, 0x8b, 0xcb, 0x8b, 0xba, 0xa8, 0xaa, 0xc3, 0x08, 0x65, + 0xad, 0x05, 0xf7, 0x31, 0x04, 0x5d, 0x57, 0x77, 0x7f, 0x64, 0x8b, 0x79, + 0x8b, 0x7d, 0x8f, 0x48, 0x9f, 0x08, 0x42, 0xa2, 0x73, 0x90, 0x6f, 0x8b, + 0x50, 0x8b, 0x5c, 0x70, 0x63, 0x52, 0x08, 0xb6, 0x69, 0x05, 0xb9, 0xc0, + 0x9c, 0x95, 0xb2, 0x8b, 0x9d, 0x8b, 0x96, 0x89, 0xae, 0x81, 0x08, 0xec, + 0x6d, 0x05, 0xa0, 0x84, 0xa2, 0x88, 0xa0, 0x8b, 0xcb, 0x8b, 0xba, 0xa8, + 0xaa, 0xc4, 0x08, 0x65, 0xac, 0x05, 0x0e, 0xf7, 0xd1, 0xf7, 0x3c, 0xef, + 0x15, 0x6c, 0x71, 0x72, 0x6c, 0x6c, 0xa4, 0x71, 0xaa, 0xaa, 0xa4, 0xa5, + 0xaa, 0xa9, 0x71, 0xa5, 0x6e, 0x1f, 0xf7, 0xe1, 0x16, 0x6c, 0x71, 0x72, + 0x6c, 0x6c, 0xa4, 0x71, 0xaa, 0xaa, 0xa4, 0xa5, 0xaa, 0xa9, 0x71, 0xa5, + 0x6e, 0x1f, 0xf7, 0xe1, 0x16, 0x6c, 0x71, 0x72, 0x6c, 0x6c, 0xa4, 0x71, + 0xaa, 0xaa, 0xa4, 0xa5, 0xaa, 0xa9, 0x71, 0xa5, 0x6e, 0x1f, 0x0e, 0x3b, + 0xf7, 0xe4, 0xfa, 0x86, 0x15, 0x53, 0xfe, 0xfe, 0xc3, 0xfa, 0xfe, 0x06, + 0x0e, 0xf7, 0xd1, 0x4f, 0xf7, 0x70, 0x15, 0xfa, 0xea, 0xc3, 0xfe, 0xea, + 0x53, 0x06, 0x0e, 0x72, 0xf8, 0xee, 0xcf, 0x15, 0xf8, 0xc5, 0x54, 0xfc, + 0x8d, 0xfb, 0xfe, 0xdf, 0x07, 0xfb, 0x3e, 0xfb, 0x04, 0xf7, 0x3e, 0xfb, + 0x04, 0x8b, 0xdf, 0xf8, 0x35, 0x8b, 0x05, 0x0e, 0xf7, 0x20, 0xf8, 0x6c, + 0xf7, 0xd3, 0x15, 0xfb, 0xac, 0xf7, 0xf7, 0x05, 0x80, 0x74, 0x85, 0x74, + 0x8b, 0x74, 0x8b, 0x76, 0x92, 0x7b, 0xa3, 0x6e, 0x08, 0xd7, 0x2c, 0x4d, + 0xfb, 0x07, 0x05, 0x76, 0x65, 0x81, 0x6e, 0x8b, 0x76, 0x8b, 0x75, 0x95, + 0x72, 0xa1, 0x66, 0xa8, 0x5c, 0x8b, 0x8b, 0x8b, 0x7e, 0x08, 0x78, 0x7d, + 0x80, 0x72, 0x1e, 0x78, 0x48, 0xe5, 0x06, 0xb8, 0x8b, 0xa8, 0x8f, 0x9a, + 0x92, 0x9f, 0x96, 0x96, 0xa4, 0x8b, 0xad, 0x8b, 0xb6, 0x81, 0xa1, 0x50, + 0xdb, 0x66, 0xbd, 0x7d, 0xa9, 0x8b, 0xab, 0x8b, 0xa0, 0x8f, 0x97, 0xa0, + 0xb2, 0x08, 0xf7, 0xda, 0xfc, 0x2e, 0x05, 0x97, 0xa2, 0x90, 0x9f, 0x8b, + 0xa0, 0x8b, 0xa3, 0x82, 0x9e, 0x6f, 0xae, 0x08, 0x61, 0xc0, 0x05, 0x64, + 0xbc, 0x7f, 0xa5, 0x8b, 0xad, 0x8b, 0x9e, 0x92, 0xa8, 0x94, 0xa2, 0x08, + 0xbb, 0xf7, 0x08, 0xa3, 0x8b, 0x05, 0xa3, 0x8b, 0x95, 0x82, 0x91, 0x6e, + 0x95, 0xac, 0x8f, 0xa8, 0x8b, 0xaa, 0x08, 0xc4, 0x78, 0xa1, 0x5b, 0x1e, + 0x41, 0x06, 0x60, 0x7d, 0x97, 0xaf, 0x1f, 0x9b, 0x07, 0x6b, 0x6a, 0x7c, + 0x67, 0x8b, 0x5f, 0x8b, 0x6e, 0x94, 0x70, 0x9a, 0x7d, 0x96, 0x80, 0x9a, + 0x87, 0xad, 0x8b, 0x08, 0xb7, 0x8b, 0x42, 0xfb, 0x40, 0x05, 0x0e, 0x8e, + 0x95, 0xc9, 0x15, 0x9d, 0x78, 0xa6, 0x97, 0x05, 0x98, 0x90, 0x98, 0x8e, + 0x94, 0x8b, 0x97, 0x8b, 0x93, 0x88, 0xa2, 0x7f, 0x08, 0xf7, 0x36, 0x32, + 0x05, 0x9c, 0x83, 0x98, 0x86, 0x95, 0x8b, 0x9e, 0x8b, 0xad, 0x9d, 0xc3, + 0xb2, 0x08, 0xbb, 0xae, 0x05, 0xc4, 0xb2, 0xa8, 0xbc, 0x8b, 0xc3, 0x8b, + 0xa2, 0x86, 0x9f, 0x81, 0x9e, 0x08, 0x35, 0xf7, 0x35, 0x05, 0x77, 0xaf, + 0x81, 0xa9, 0x8b, 0xa0, 0x8b, 0x9b, 0x93, 0x9c, 0x9c, 0x9e, 0x08, 0xe7, + 0xf6, 0x05, 0xfb, 0x0f, 0xca, 0x47, 0xa1, 0x3b, 0x8b, 0xfb, 0x1c, 0x8b, + 0x27, 0x34, 0x8b, 0xfb, 0x0b, 0x8b, 0x4e, 0xa8, 0x52, 0xbb, 0x6c, 0xaa, + 0x77, 0xaa, 0x83, 0xc6, 0x88, 0x08, 0x8d, 0xa5, 0x05, 0x5f, 0x8e, 0x74, + 0x91, 0x74, 0x98, 0x60, 0xa4, 0x71, 0xb9, 0x8b, 0xbe, 0x8b, 0xd5, 0xcb, + 0xbf, 0xe5, 0x8b, 0xc5, 0x8b, 0xb5, 0x7f, 0xf7, 0x07, 0x59, 0x08, 0x4a, + 0x3f, 0x05, 0x76, 0x72, 0x82, 0x74, 0x8b, 0x6e, 0x8b, 0x72, 0x92, 0x73, + 0x9a, 0x70, 0x08, 0xde, 0xfb, 0x2c, 0x05, 0x9a, 0x70, 0x93, 0x71, 0x8b, + 0x73, 0x8b, 0x70, 0x81, 0x75, 0x78, 0x7b, 0x76, 0x7a, 0x68, 0x7f, 0x6f, + 0x8b, 0x7b, 0x8b, 0x80, 0x8f, 0x74, 0x97, 0x08, 0xfb, 0x27, 0xd9, 0x05, + 0x7b, 0x93, 0x7f, 0x8f, 0x80, 0x8b, 0x7f, 0x8b, 0x7d, 0x87, 0x7d, 0x81, + 0x08, 0x26, 0x4d, 0x05, 0x0e, 0xf7, 0x04, 0xd4, 0xac, 0x15, 0x9e, 0x7b, + 0x05, 0xa1, 0x98, 0x97, 0x90, 0x98, 0x8b, 0x9a, 0x8b, 0x9a, 0x83, 0xa4, + 0x77, 0x8f, 0x88, 0x97, 0x82, 0x98, 0x80, 0xc0, 0xa9, 0xc4, 0xbe, 0xba, + 0xc5, 0xb6, 0xc4, 0x98, 0xb9, 0x8b, 0xec, 0x08, 0x8c, 0xd2, 0x05, 0x8b, + 0xb7, 0x84, 0xd4, 0x7f, 0xdc, 0x08, 0xcc, 0xb5, 0x05, 0x98, 0x93, 0x96, + 0x8f, 0x95, 0x8b, 0x9b, 0x8b, 0x97, 0x85, 0x9f, 0x79, 0x08, 0xdf, 0x3f, + 0xfb, 0x54, 0xfb, 0x19, 0x98, 0x75, 0x94, 0x8b, 0x05, 0x9c, 0x8b, 0x98, + 0x83, 0x94, 0x7b, 0x97, 0x75, 0x99, 0x52, 0x93, 0x4b, 0x08, 0x9e, 0xfb, + 0x44, 0x97, 0x6d, 0xcd, 0x6b, 0x08, 0xf7, 0x02, 0xe3, 0x7a, 0xa2, 0x05, + 0x76, 0x83, 0x82, 0x88, 0x83, 0x8b, 0x78, 0x8b, 0x82, 0x99, 0x87, 0xaa, + 0x6f, 0xf7, 0x53, 0x77, 0xc9, 0x56, 0xd0, 0x08, 0xf7, 0x49, 0xf7, 0x15, + 0xfb, 0x2f, 0xf7, 0x1a, 0x05, 0x7e, 0x95, 0x84, 0x8f, 0x83, 0x8b, 0x81, + 0x8b, 0x84, 0x87, 0x78, 0x7e, 0x08, 0xfb, 0x13, 0x2f, 0x05, 0x65, 0xd8, + 0x5b, 0xaa, 0x39, 0x8b, 0xfb, 0x0e, 0x8b, 0x31, 0x36, 0x8b, 0xfb, 0x06, + 0x8b, 0x69, 0x94, 0x6b, 0x9c, 0x72, 0x9a, 0x74, 0x99, 0x80, 0xb0, 0x79, + 0x08, 0xbb, 0x73, 0x05, 0xa7, 0x7d, 0x96, 0x81, 0x8b, 0x7f, 0x8b, 0x82, + 0x86, 0x84, 0x7d, 0x80, 0x08, 0xa4, 0x78, 0xaf, 0xc1, 0x05, 0x92, 0x95, + 0x8f, 0x97, 0x8b, 0x95, 0x8b, 0xa0, 0x7b, 0x9f, 0x6f, 0x99, 0x08, 0x55, + 0xa7, 0x05, 0x5d, 0xa2, 0x7b, 0x95, 0x81, 0x95, 0x7b, 0x9c, 0x82, 0xa1, + 0x8b, 0xa3, 0x8b, 0xc9, 0xc4, 0xbe, 0xd2, 0x8b, 0xc2, 0x8b, 0xb7, 0x70, + 0xa1, 0x5a, 0x9a, 0x69, 0x98, 0x33, 0x8b, 0x40, 0x08, 0x8c, 0x51, 0x05, + 0x87, 0xfb, 0x25, 0x7d, 0x52, 0x5b, 0x44, 0x08, 0x42, 0xbe, 0x05, 0x83, + 0x90, 0x85, 0x8e, 0x87, 0x8b, 0x86, 0x8b, 0x85, 0x88, 0x83, 0x84, 0x08, + 0x2f, 0x3a, 0x05, 0x0e, 0xf7, 0xc4, 0xf8, 0x6b, 0xf8, 0xd2, 0x15, 0x2c, + 0x4b, 0x67, 0x6e, 0x66, 0x5e, 0x55, 0x4a, 0x70, 0x4b, 0x8b, 0x4d, 0x8b, + 0x65, 0x92, 0x70, 0xa5, 0x52, 0x66, 0x5c, 0x7d, 0x77, 0x7f, 0x75, 0x76, + 0x65, 0x7f, 0x5f, 0x8b, 0x65, 0x8b, 0x6d, 0x96, 0x6c, 0x9e, 0x74, 0x08, + 0xa1, 0x6e, 0xa6, 0x7f, 0xb1, 0x8b, 0xd4, 0x8b, 0xb9, 0xcc, 0x8b, 0xf2, + 0x8b, 0xc5, 0x7e, 0xb9, 0x5a, 0xf7, 0x09, 0xf7, 0x2d, 0xf7, 0x59, 0xf5, + 0xe0, 0xe7, 0x8b, 0xc3, 0x8b, 0xac, 0x66, 0x8b, 0x49, 0x8b, 0x4c, 0x6e, + 0x38, 0x5d, 0x44, 0x08, 0x58, 0x3d, 0x53, 0x63, 0x4e, 0x8b, 0x6a, 0x8b, + 0x70, 0xa7, 0x8b, 0xad, 0x8b, 0x94, 0x8d, 0x97, 0x8e, 0x99, 0x08, 0x9a, + 0x8a, 0x05, 0xa7, 0xa2, 0xa1, 0xa4, 0xa2, 0x7b, 0x9b, 0x75, 0x66, 0x6e, + 0x5f, 0x54, 0x43, 0xb9, 0x5d, 0xd2, 0x1f, 0xd9, 0x8b, 0xe3, 0xc1, 0xc6, + 0xde, 0xca, 0xe4, 0xa7, 0xd2, 0x8b, 0xd2, 0x8b, 0xe3, 0x4f, 0xc1, 0x28, + 0x8b, 0x3a, 0x8b, 0x44, 0x68, 0x30, 0x35, 0x64, 0x67, 0x78, 0x75, 0x32, + 0xfb, 0x03, 0x83, 0xa9, 0x87, 0xa5, 0x8b, 0xa6, 0x08, 0x8b, 0xbf, 0x9a, + 0xba, 0xaa, 0xba, 0xab, 0xba, 0xa5, 0xa5, 0xce, 0xbc, 0x08, 0x82, 0x9b, + 0x05, 0xfb, 0x5e, 0xfc, 0x71, 0x15, 0xba, 0x2f, 0x9d, 0x57, 0x8b, 0x5c, + 0x08, 0x59, 0x75, 0x6e, 0x65, 0x5d, 0x71, 0xaf, 0xcc, 0x1e, 0x8b, 0xc5, + 0x9b, 0xb3, 0xbe, 0xd2, 0x08, 0x0e, 0xe0, 0xf7, 0x61, 0xf8, 0x7e, 0x15, + 0xf7, 0x24, 0xfb, 0x21, 0xfb, 0x24, 0xfb, 0x24, 0xb2, 0x65, 0xf7, 0x24, + 0xf7, 0x24, 0xf7, 0x21, 0xfb, 0x24, 0xb1, 0xb1, 0xfb, 0x21, 0xf7, 0x24, + 0xf7, 0x21, 0xf7, 0x21, 0x65, 0xb2, 0xfb, 0x21, 0xfb, 0x21, 0xfb, 0x24, + 0xf7, 0x21, 0x64, 0x64, 0x05, 0xf7, 0x4e, 0xf7, 0x5d, 0x15, 0xfb, 0x54, + 0xfb, 0x30, 0xfb, 0x2f, 0xfb, 0x53, 0xfb, 0x51, 0xf7, 0x30, 0xfb, 0x30, + 0xf7, 0x50, 0xf7, 0x51, 0xf7, 0x31, 0xf7, 0x31, 0xf7, 0x4f, 0xf7, 0x50, + 0xfb, 0x30, 0xf7, 0x33, 0xfb, 0x4e, 0x1f, 0x51, 0x04, 0xf7, 0x31, 0xf7, + 0x16, 0xfb, 0x16, 0xfb, 0x31, 0xfb, 0x33, 0xfb, 0x16, 0xfb, 0x15, 0xfb, + 0x34, 0xfb, 0x33, 0xfb, 0x16, 0xf7, 0x14, 0xf7, 0x32, 0xf7, 0x36, 0xf7, + 0x15, 0xf7, 0x13, 0xf7, 0x37, 0x1f, 0x0e, 0xe0, 0xf7, 0xfc, 0xf8, 0xde, + 0x15, 0xfb, 0x6a, 0xfb, 0x64, 0x54, 0xf7, 0x64, 0xfb, 0x6a, 0xc3, 0xf7, + 0x6a, 0xf7, 0x64, 0xc2, 0xfb, 0x64, 0xf7, 0x6a, 0x53, 0x07, 0xab, 0xf2, + 0x15, 0xfb, 0x57, 0xfb, 0x2e, 0xfb, 0x2c, 0xfb, 0x56, 0xfb, 0x52, 0xf7, + 0x2e, 0xfb, 0x2d, 0xf7, 0x54, 0xf7, 0x52, 0xf7, 0x2e, 0xf7, 0x2e, 0xf7, + 0x53, 0xf7, 0x50, 0xfb, 0x2e, 0xf7, 0x30, 0xfb, 0x4f, 0x1f, 0x8c, 0x56, + 0x15, 0xf7, 0x2f, 0xf7, 0x15, 0xfb, 0x19, 0xfb, 0x34, 0xfb, 0x33, 0xfb, + 0x16, 0xfb, 0x17, 0xfb, 0x33, 0xfb, 0x33, 0xfb, 0x16, 0xf7, 0x17, 0xf7, + 0x35, 0xf7, 0x36, 0xf7, 0x16, 0xf7, 0x15, 0xf7, 0x38, 0x1f, 0x0e, 0xf7, + 0x20, 0xb2, 0x98, 0x15, 0xb0, 0x66, 0xef, 0xef, 0x05, 0xcd, 0x52, 0xe1, + 0x6b, 0xe3, 0x8b, 0xf7, 0x5d, 0x8b, 0xf7, 0x38, 0xf7, 0x38, 0x8b, 0xf7, + 0x5d, 0x8b, 0xe3, 0x6d, 0xdc, 0x50, 0xd2, 0x08, 0xe4, 0xe4, 0x66, 0xb0, + 0x31, 0x31, 0x05, 0x46, 0xc6, 0x3a, 0xa9, 0x33, 0x8b, 0xfb, 0x5d, 0x8b, + 0xfb, 0x38, 0xfb, 0x38, 0x8b, 0xfb, 0x5d, 0x8b, 0x33, 0xab, 0x36, 0xc4, + 0x4a, 0x08, 0x26, 0x26, 0x05, 0xf7, 0x20, 0xf7, 0x20, 0x15, 0x5b, 0xc6, + 0x72, 0xce, 0x8b, 0xd4, 0x8b, 0xf7, 0x3e, 0xf7, 0x1f, 0xf7, 0x1f, 0xf7, + 0x3f, 0x8b, 0xd4, 0x8b, 0xd3, 0x71, 0xc1, 0x5d, 0x08, 0xfc, 0x48, 0xfc, + 0x48, 0x05, 0xf8, 0x6d, 0xf8, 0x23, 0x15, 0xba, 0x55, 0xa6, 0x42, 0x8b, + 0x42, 0x8b, 0xfb, 0x3e, 0xfb, 0x1f, 0xfb, 0x1f, 0xfb, 0x3f, 0x8b, 0x42, + 0x8b, 0x43, 0xa5, 0x54, 0xba, 0x08, 0xf8, 0x48, 0xf8, 0x48, 0x05, 0x0e, + 0xe0, 0xf9, 0x70, 0x16, 0xf7, 0x44, 0x07, 0x8a, 0xe4, 0x79, 0xc7, 0x5f, + 0xc2, 0x4a, 0xdd, 0x27, 0xb8, 0xfb, 0x0a, 0x8b, 0x08, 0xfb, 0x5d, 0xfb, + 0x25, 0xfb, 0x18, 0xfb, 0x49, 0x1f, 0xfb, 0x56, 0xc4, 0x07, 0x8c, 0xf7, + 0x5f, 0x05, 0xf7, 0x20, 0xf7, 0x11, 0xf6, 0xf7, 0x37, 0x1e, 0xe4, 0x8b, + 0xe0, 0x69, 0xc0, 0x51, 0xb9, 0x5a, 0x9b, 0x5c, 0x8b, 0x3d, 0x08, 0xfb, + 0x4c, 0xc4, 0x07, 0x0e, 0xe0, 0xb3, 0xf8, 0x7d, 0x15, 0xfb, 0x44, 0x07, + 0x8c, 0x32, 0x9d, 0x4f, 0xb7, 0x54, 0xcc, 0x39, 0xef, 0x5e, 0xf7, 0x0a, + 0x8b, 0xf7, 0x5d, 0x8b, 0xf7, 0x24, 0xf7, 0x17, 0x8c, 0xf7, 0x4a, 0x08, + 0xf7, 0x56, 0x52, 0xfb, 0x5f, 0x07, 0x8a, 0xfb, 0x20, 0xfb, 0x11, 0x20, + 0xfb, 0x37, 0x8b, 0x31, 0x8b, 0x37, 0xad, 0x56, 0xc5, 0x5d, 0xbc, 0x7b, + 0xba, 0x8b, 0xd9, 0x08, 0xf7, 0x4c, 0x52, 0x07, 0x0e, 0xa9, 0x9f, 0x16, + 0xf7, 0xc6, 0x06, 0xd0, 0x8b, 0xab, 0x8b, 0x9c, 0x8d, 0xbf, 0x8e, 0xb2, + 0x96, 0xa8, 0x9d, 0xce, 0xb7, 0xb5, 0xd7, 0x8b, 0xdc, 0x8b, 0xbc, 0x7c, + 0xbb, 0x6f, 0xb3, 0x67, 0xbe, 0x5d, 0xa9, 0x4f, 0x95, 0x69, 0x91, 0x78, + 0x8c, 0xfb, 0x01, 0x8b, 0x08, 0xfb, 0xc6, 0x53, 0xf7, 0xc8, 0x06, 0xc6, + 0x8b, 0xaa, 0x8b, 0x9a, 0x8a, 0xba, 0x87, 0xaf, 0x82, 0xa2, 0x7d, 0xbd, + 0x6b, 0xa9, 0x53, 0x8b, 0x4c, 0x8b, 0x63, 0x7f, 0x65, 0x74, 0x6d, 0x71, + 0x66, 0x6a, 0x78, 0x5a, 0x82, 0x6a, 0x86, 0x79, 0x8a, 0x2a, 0x8b, 0x08, + 0xfb, 0xc8, 0x53, 0x06, 0x0e, 0xa9, 0x9f, 0x46, 0x15, 0x53, 0xf9, 0x1c, + 0xc3, 0xfd, 0x1c, 0x07, 0xd0, 0x04, 0xf7, 0xc6, 0x06, 0xd0, 0x8b, 0xab, + 0x8b, 0x9c, 0x8d, 0xbf, 0x8e, 0xb2, 0x96, 0xa8, 0x9d, 0xce, 0xb7, 0xb5, + 0xd7, 0x8b, 0xdc, 0x8b, 0xbc, 0x7c, 0xbb, 0x6f, 0xb3, 0x67, 0xbe, 0x5d, + 0xa9, 0x4f, 0x95, 0x69, 0x91, 0x78, 0x8c, 0xfb, 0x01, 0x8b, 0x08, 0xfb, + 0xc6, 0x53, 0xf7, 0xc8, 0x06, 0xc6, 0x8b, 0xaa, 0x8b, 0x9a, 0x8a, 0xba, + 0x87, 0xaf, 0x82, 0xa2, 0x7d, 0xbd, 0x6b, 0xa9, 0x53, 0x8b, 0x4c, 0x8b, + 0x63, 0x7f, 0x65, 0x74, 0x6d, 0x71, 0x66, 0x6a, 0x78, 0x5a, 0x82, 0x6a, + 0x86, 0x79, 0x8a, 0x2a, 0x8b, 0x08, 0xfb, 0xc8, 0x53, 0x06, 0x0e, 0xa9, + 0xf8, 0xae, 0xf8, 0x6a, 0x15, 0xab, 0xd1, 0x59, 0x8b, 0x6b, 0x45, 0x23, + 0x8b, 0x05, 0x46, 0x8b, 0x6b, 0x8b, 0x7a, 0x89, 0x57, 0x88, 0x64, 0x80, + 0x6d, 0x79, 0x48, 0x5f, 0x61, 0x3f, 0x8b, 0x3a, 0x8b, 0x41, 0xae, 0x44, + 0xc6, 0x5e, 0xb0, 0x6f, 0xb3, 0x7f, 0xce, 0x87, 0x08, 0x6a, 0x44, 0xbd, + 0x8b, 0xab, 0xd1, 0xf8, 0x03, 0x8b, 0x8b, 0xc3, 0xfb, 0xe9, 0x8b, 0xf7, + 0x38, 0xf7, 0xfa, 0xf7, 0x45, 0x8b, 0x8b, 0xc3, 0xfb, 0x2c, 0x8b, 0x05, + 0xfb, 0x83, 0xfc, 0x31, 0x15, 0x53, 0x8c, 0x5f, 0x94, 0x6f, 0x9c, 0x5a, + 0xab, 0x6c, 0xc4, 0x8b, 0xc9, 0x8b, 0xb2, 0x97, 0xb2, 0xa2, 0xa9, 0xa6, + 0xb0, 0xab, 0x9e, 0xbd, 0x94, 0xab, 0x90, 0x9d, 0x8c, 0xec, 0x8b, 0x08, + 0xdc, 0x8b, 0xfb, 0x38, 0xfb, 0xf9, 0x05, 0x0e, 0xa9, 0xf9, 0x46, 0xf8, + 0x6a, 0x15, 0xfb, 0xc6, 0x06, 0x46, 0x8b, 0x6b, 0x8b, 0x7a, 0x89, 0x57, + 0x88, 0x64, 0x80, 0x6e, 0x79, 0x48, 0x5f, 0x61, 0x3f, 0x8b, 0x3a, 0x8b, + 0x5a, 0x9a, 0x5b, 0xa7, 0x63, 0xaf, 0x58, 0xb9, 0x6d, 0xc7, 0x81, 0xad, + 0x85, 0x9e, 0x8a, 0xf7, 0x01, 0x8b, 0x08, 0xf7, 0xc6, 0xc3, 0xfb, 0xc8, + 0x06, 0x50, 0x8b, 0x6c, 0x8b, 0x7c, 0x8c, 0x5d, 0x8f, 0x66, 0x94, 0x74, + 0x99, 0x59, 0xab, 0x6d, 0xc4, 0x8b, 0xc9, 0x8b, 0xb3, 0x97, 0xb1, 0xa2, + 0xa9, 0xa6, 0xb0, 0xab, 0x9e, 0xbc, 0x94, 0xac, 0x90, 0x9d, 0x8c, 0xec, + 0x8b, 0x08, 0xf7, 0xc8, 0xc3, 0x06, 0x0e, 0xa9, 0xb0, 0x46, 0x15, 0x53, + 0xf9, 0x1c, 0xc3, 0xfd, 0x1c, 0x07, 0xf9, 0x21, 0xf8, 0xaf, 0x15, 0xfb, + 0xc6, 0x06, 0x46, 0x8b, 0x6b, 0x8b, 0x7a, 0x89, 0x57, 0x88, 0x64, 0x80, + 0x6e, 0x79, 0x48, 0x5f, 0x61, 0x3f, 0x8b, 0x3a, 0x8b, 0x5a, 0x9a, 0x5b, + 0xa7, 0x63, 0xaf, 0x58, 0xb9, 0x6d, 0xc7, 0x81, 0xad, 0x85, 0x9e, 0x8a, + 0xf7, 0x01, 0x8b, 0x08, 0xf7, 0xc6, 0xc3, 0xfb, 0xc8, 0x06, 0x50, 0x8b, + 0x6c, 0x8b, 0x7c, 0x8c, 0x5d, 0x8f, 0x66, 0x94, 0x74, 0x99, 0x59, 0xab, + 0x6d, 0xc4, 0x8b, 0xc9, 0x8b, 0xb3, 0x97, 0xb1, 0xa2, 0xa9, 0xa6, 0xb0, + 0xab, 0x9e, 0xbc, 0x94, 0xac, 0x90, 0x9d, 0x8c, 0xec, 0x8b, 0x08, 0xf7, + 0xc8, 0xc3, 0x06, 0x0e, 0xa9, 0xf0, 0xf7, 0x9b, 0x15, 0x95, 0xc9, 0xb3, + 0xc0, 0xbd, 0x9d, 0xb5, 0x9b, 0xa2, 0x8d, 0xf7, 0x10, 0x8b, 0x08, 0xf7, + 0x07, 0xc3, 0xfb, 0x05, 0x06, 0x47, 0x8b, 0x6a, 0x8b, 0x7a, 0x89, 0x57, + 0x88, 0x64, 0x80, 0x6e, 0x79, 0x48, 0x5f, 0x61, 0x3f, 0x8b, 0x3a, 0x8b, + 0x5a, 0x9a, 0x5b, 0xa7, 0x63, 0xaf, 0x58, 0xb9, 0x6d, 0xc7, 0x81, 0xad, + 0x85, 0x9e, 0x8a, 0xf7, 0x01, 0x8b, 0x08, 0xf7, 0x05, 0xc3, 0xfb, 0x07, + 0x06, 0x3a, 0x8b, 0x76, 0x8c, 0x73, 0x8d, 0x55, 0x92, 0x6d, 0x97, 0x6e, + 0xa8, 0x70, 0xa5, 0x7b, 0xad, 0x84, 0xb3, 0x08, 0xf8, 0x28, 0xc3, 0xfc, + 0x28, 0x06, 0x0e, 0xa9, 0xf8, 0x13, 0xf8, 0x32, 0x15, 0xf7, 0x0e, 0xc3, + 0x2d, 0x06, 0xaa, 0xc8, 0x5c, 0xa3, 0x60, 0x36, 0x05, 0x20, 0x8a, 0x7d, + 0x8a, 0x5f, 0x7b, 0x3a, 0x6d, 0x4e, 0x2f, 0x8b, 0x2c, 0x8b, 0x40, 0xac, + 0x48, 0xc7, 0x5c, 0x08, 0x63, 0x3b, 0xb9, 0x73, 0xb2, 0xd9, 0x05, 0xb9, + 0x79, 0xa4, 0x89, 0xf7, 0x1e, 0x8b, 0x08, 0xf7, 0x05, 0xc3, 0xfb, 0x07, + 0x06, 0xfb, 0x0a, 0x8b, 0x72, 0x8d, 0x65, 0x98, 0x08, 0xd0, 0xf7, 0x1c, + 0xf7, 0x77, 0x8b, 0x8b, 0xc3, 0xfb, 0x5b, 0x8b, 0xd8, 0xf7, 0x2b, 0x05, + 0xfb, 0x1b, 0xfb, 0x2b, 0x15, 0xfb, 0x27, 0x06, 0xa0, 0xf6, 0xcf, 0xb9, + 0xf7, 0x1a, 0x89, 0x08, 0x3f, 0xfb, 0x2b, 0x05, 0x37, 0xfb, 0x3b, 0x15, + 0x69, 0xa6, 0x75, 0xb1, 0x84, 0xb9, 0x08, 0xf7, 0x0b, 0x8b, 0x53, 0xfb, + 0x03, 0x05, 0x0e, 0xe0, 0xa5, 0x16, 0xf9, 0x37, 0x8a, 0x8d, 0xc5, 0xfc, + 0xaa, 0x8b, 0xf8, 0xcd, 0xf8, 0xd3, 0x5e, 0xb3, 0xfd, 0x2f, 0xfd, 0x34, + 0x05, 0x0e, 0xa9, 0xf9, 0x3d, 0xf9, 0x43, 0x15, 0xfd, 0x19, 0x8b, 0xf7, + 0xc3, 0xfd, 0x43, 0xf7, 0xea, 0xf9, 0x43, 0x05, 0x44, 0x58, 0x15, 0xfb, + 0x7e, 0xfc, 0x5e, 0xfb, 0x67, 0xf8, 0x5f, 0xf8, 0x51, 0x8a, 0x05, 0x0e, + 0xf6, 0xf8, 0x8a, 0xf7, 0x32, 0x15, 0xee, 0x9d, 0x06, 0x71, 0x8d, 0x80, + 0x92, 0x72, 0xa8, 0x08, 0x22, 0xf7, 0x13, 0x05, 0xca, 0x94, 0xb2, 0xb1, + 0x8b, 0xbf, 0x8b, 0xb3, 0x76, 0xab, 0x65, 0x9c, 0x72, 0x96, 0x71, 0x8f, + 0x55, 0x8b, 0x08, 0xfb, 0x32, 0x79, 0x06, 0xb9, 0x88, 0x92, 0x84, 0x8b, + 0x66, 0x08, 0xfb, 0x93, 0x07, 0x8b, 0x65, 0x84, 0x84, 0x5d, 0x88, 0x08, + 0x79, 0xf7, 0x42, 0x9d, 0x07, 0x5e, 0x8e, 0x84, 0x92, 0x8b, 0xb1, 0x08, + 0xf7, 0x01, 0xa5, 0x07, 0xf7, 0x20, 0xfb, 0x43, 0x05, 0xfb, 0x3a, 0xf7, + 0xe2, 0x15, 0xa0, 0x8d, 0x8c, 0xae, 0xc9, 0xa8, 0x73, 0x58, 0x54, 0x6a, + 0x74, 0x3c, 0x1e, 0x87, 0x8b, 0x86, 0x8b, 0x84, 0x8c, 0x08, 0xf7, 0x16, + 0x07, 0xc5, 0xf7, 0x5a, 0x15, 0xfb, 0x51, 0xfb, 0x2f, 0xfb, 0x32, 0xfb, + 0x55, 0xfb, 0x56, 0xf7, 0x2f, 0xfb, 0x32, 0xf7, 0x52, 0xf7, 0x50, 0xf7, + 0x31, 0xf7, 0x32, 0xf7, 0x51, 0xf7, 0x5b, 0xfb, 0x2c, 0xf7, 0x31, 0xfb, + 0x56, 0x1f, 0x5e, 0x04, 0xf7, 0x39, 0xf7, 0x16, 0xfb, 0x1d, 0xfb, 0x41, + 0xfb, 0x3a, 0xfb, 0x1a, 0xfb, 0x1d, 0xfb, 0x34, 0xfb, 0x36, 0xfb, 0x18, + 0xf7, 0x1e, 0xf7, 0x3c, 0xf7, 0x3d, 0xf7, 0x18, 0xf7, 0x1e, 0xf7, 0x35, + 0x1f, 0x0e, 0xf6, 0xf8, 0xc2, 0xf8, 0x27, 0x15, 0x86, 0xf7, 0x1c, 0x77, + 0x8b, 0x05, 0x83, 0x79, 0x88, 0x88, 0x80, 0x8b, 0x87, 0x8b, 0x82, 0x8d, + 0x84, 0x8e, 0x6e, 0x96, 0x70, 0x90, 0x6e, 0x8b, 0x08, 0xfb, 0x0d, 0x36, + 0x37, 0xfb, 0x0c, 0xfb, 0x09, 0xdd, 0x3b, 0xf7, 0x0e, 0x1f, 0xcb, 0x8b, + 0xbd, 0xa2, 0xbb, 0xbf, 0x08, 0x7c, 0x9b, 0x05, 0x5c, 0x60, 0x67, 0x7c, + 0x56, 0x8b, 0x08, 0x35, 0x56, 0xcb, 0xf3, 0xf4, 0xbe, 0xcb, 0xdf, 0x1f, + 0xcc, 0x8b, 0xb6, 0x67, 0x9c, 0x46, 0x08, 0xa1, 0x06, 0xfb, 0x37, 0xf7, + 0xb3, 0x15, 0xfb, 0x51, 0xfb, 0x2f, 0xfb, 0x32, 0xfb, 0x55, 0xfb, 0x56, + 0xf7, 0x2f, 0xfb, 0x32, 0xf7, 0x52, 0xf7, 0x50, 0xf7, 0x31, 0xf7, 0x32, + 0xf7, 0x51, 0xf7, 0x5b, 0xfb, 0x2c, 0xf7, 0x31, 0xfb, 0x56, 0x1f, 0x5e, + 0x04, 0xf7, 0x39, 0xf7, 0x16, 0xfb, 0x1d, 0xfb, 0x41, 0xfb, 0x3a, 0xfb, + 0x1a, 0xfb, 0x1d, 0xfb, 0x34, 0xfb, 0x36, 0xfb, 0x18, 0xf7, 0x1e, 0xf7, + 0x3c, 0xf7, 0x3d, 0xf7, 0x18, 0xf7, 0x1e, 0xf7, 0x35, 0x1f, 0x0e, 0xf7, + 0x63, 0xf9, 0xeb, 0xf9, 0x35, 0x15, 0xfb, 0x1a, 0x8b, 0xfb, 0x0a, 0xfb, + 0xb7, 0xfb, 0x0b, 0xf7, 0xb7, 0xfb, 0x0c, 0x8b, 0x8b, 0x75, 0x05, 0xb4, + 0x8b, 0x8b, 0x7a, 0x1f, 0xfb, 0xc3, 0x07, 0x8b, 0x68, 0x86, 0x87, 0x5f, + 0x8a, 0x08, 0x75, 0xf7, 0x1b, 0xa1, 0x07, 0x65, 0x8c, 0x82, 0x92, 0x8b, + 0xaa, 0x08, 0x8b, 0xf7, 0xa1, 0xf7, 0x18, 0xfb, 0xde, 0xa1, 0x8b, 0xf7, + 0x1f, 0xf7, 0xee, 0x8b, 0xfb, 0xb6, 0x05, 0x8b, 0x71, 0x80, 0x84, 0x62, + 0x8a, 0x08, 0x75, 0xf7, 0x3e, 0xa1, 0x07, 0x61, 0x8e, 0x84, 0x90, 0x8b, + 0xa5, 0x08, 0xf7, 0xc9, 0x07, 0x99, 0x91, 0x8e, 0xa6, 0x1e, 0x9b, 0xa1, + 0x06, 0xfc, 0x94, 0x16, 0xfb, 0xd9, 0xfb, 0x02, 0x9f, 0x06, 0x90, 0xc8, + 0x99, 0x95, 0xdd, 0x8e, 0x08, 0x91, 0xfb, 0xce, 0x06, 0x6f, 0x83, 0x87, + 0x54, 0x1e, 0x75, 0xf7, 0x55, 0xa1, 0x07, 0x53, 0x8b, 0x85, 0x8e, 0x8c, + 0xa6, 0x08, 0xf7, 0xd0, 0x8d, 0x07, 0xe1, 0x8b, 0x9b, 0x80, 0x8d, 0x4c, + 0x08, 0xa2, 0xf7, 0x02, 0x06, 0x0e, 0xf7, 0x20, 0xa4, 0xfb, 0x10, 0x15, + 0xf7, 0xb6, 0xa5, 0x88, 0x06, 0x6a, 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, + 0x9c, 0x88, 0x9b, 0x8b, 0xbf, 0x08, 0xf8, 0xd3, 0x07, 0x8b, 0xca, 0x8f, + 0xa0, 0x99, 0x98, 0x9d, 0x9c, 0x98, 0x8c, 0xf7, 0x20, 0x8b, 0xf7, 0x22, + 0x8b, 0x98, 0x8a, 0x9d, 0x7a, 0x99, 0x7e, 0x8f, 0x76, 0x8b, 0x4c, 0x08, + 0xfc, 0xd3, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, + 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0xf7, 0xb6, 0xa5, 0x88, 0x06, 0x6a, + 0x8b, 0x70, 0x97, 0x7d, 0x9e, 0x80, 0x9c, 0x88, 0x9b, 0x8b, 0xbf, 0x08, + 0xf8, 0xe3, 0x07, 0x8b, 0xbf, 0x8e, 0x9a, 0x96, 0x9d, 0x99, 0x9e, 0xa6, + 0x97, 0xac, 0x8b, 0x08, 0x8e, 0xa5, 0xfd, 0x9e, 0x71, 0x8e, 0x06, 0xac, + 0x8b, 0xa6, 0x7f, 0x99, 0x78, 0x96, 0x79, 0x8e, 0x7c, 0x8b, 0x57, 0x08, + 0xfc, 0xe3, 0x07, 0x8b, 0x57, 0x88, 0x7b, 0x80, 0x7a, 0x7d, 0x78, 0x70, + 0x7f, 0x6a, 0x8b, 0x08, 0x88, 0x71, 0x06, 0x0e, 0xf7, 0xff, 0x68, 0x15, + 0xf7, 0x2c, 0xfa, 0x43, 0x68, 0x90, 0xfb, 0x13, 0xfd, 0xaa, 0xfb, 0x59, + 0xf8, 0x21, 0xfb, 0x26, 0x44, 0x9b, 0x68, 0xea, 0xba, 0xf7, 0x86, 0xfc, + 0x84, 0x05, 0x0e, 0xfc, 0x45, 0xf7, 0x0c, 0xf7, 0xcb, 0x15, 0x6f, 0x74, + 0x74, 0x6f, 0x6f, 0xa1, 0x74, 0xa7, 0xa6, 0xa2, 0xa2, 0xa7, 0xa7, 0x74, + 0xa2, 0x71, 0x1f, 0x0e, 0xa9, 0x9a, 0xf8, 0x03, 0x15, 0x4f, 0xf8, 0xf2, + 0xfb, 0x9f, 0xc6, 0xf7, 0xdb, 0xfd, 0x2d, 0x07, 0x0e, 0x3b, 0xf7, 0xc4, + 0xf8, 0x70, 0x15, 0xfb, 0xad, 0xfc, 0x53, 0xb9, 0x6d, 0xf7, 0x7e, 0xf8, + 0x07, 0x05, 0xf7, 0x7e, 0xfc, 0x06, 0xb9, 0xab, 0x05, 0xfb, 0xab, 0xf8, + 0x50, 0x05, 0x0e, 0x3b, 0xf7, 0xc3, 0x8a, 0x15, 0xf7, 0xa7, 0xf8, 0x53, + 0x5d, 0xa9, 0xfb, 0x78, 0xfc, 0x06, 0xfb, 0x78, 0xf8, 0x05, 0x5d, 0x6b, + 0xf7, 0xa5, 0xfc, 0x50, 0x05, 0x0e, 0xf7, 0xfb, 0xf7, 0x85, 0xf8, 0x0b, + 0x15, 0x9d, 0x9f, 0x98, 0x9b, 0x96, 0x99, 0x9e, 0xa4, 0x97, 0x9a, 0x90, + 0x92, 0x08, 0x60, 0xad, 0x05, 0x44, 0x30, 0x27, 0x22, 0x3d, 0x49, 0xdb, + 0x47, 0xec, 0x24, 0xd3, 0x2f, 0x08, 0xb6, 0xad, 0x05, 0x88, 0x8f, 0x88, + 0x8f, 0x88, 0x8e, 0x62, 0xc1, 0x8a, 0x8c, 0x70, 0xaa, 0x08, 0xf8, 0xcc, + 0x06, 0x79, 0x77, 0x7f, 0x7c, 0x7f, 0x7c, 0x78, 0x72, 0x7f, 0x7b, 0x86, + 0x85, 0x08, 0xb6, 0x69, 0x05, 0xd3, 0xe7, 0xec, 0xf2, 0xdb, 0xcf, 0x3d, + 0xcd, 0x27, 0xf4, 0x44, 0xe6, 0x08, 0x60, 0x69, 0x94, 0x7f, 0x05, 0x94, + 0x80, 0x94, 0x7f, 0x94, 0x7f, 0x08, 0x97, 0x7c, 0x05, 0x96, 0x7f, 0x90, + 0x84, 0x99, 0x7b, 0x08, 0xfc, 0xcc, 0x06, 0x5b, 0x54, 0x15, 0xf9, 0x2c, + 0x06, 0xb4, 0x61, 0xa3, 0x74, 0x99, 0x80, 0x7b, 0x7d, 0x79, 0x7a, 0x5e, + 0x5d, 0x08, 0xfd, 0x2c, 0x06, 0x5e, 0xb8, 0x78, 0x9e, 0x7c, 0x98, 0x9a, + 0x97, 0x92, 0x92, 0x9d, 0x9d, 0x08, 0xab, 0xaa, 0x92, 0x93, 0x05, 0x0e, + 0xf7, 0xc4, 0xfa, 0x3f, 0xf7, 0xd4, 0x15, 0xc2, 0xfd, 0x4b, 0x07, 0x9d, + 0x9f, 0x98, 0x9b, 0x96, 0x99, 0x9e, 0xa4, 0x97, 0x9a, 0x90, 0x92, 0x08, + 0x60, 0xad, 0x05, 0x50, 0x3d, 0xfb, 0x07, 0xfb, 0x0d, 0x40, 0x4c, 0xda, + 0x48, 0xed, 0x23, 0xd3, 0x2f, 0x08, 0xb6, 0xad, 0x05, 0x88, 0x8f, 0x88, + 0x8f, 0x88, 0x8e, 0x61, 0xc1, 0x8b, 0x8c, 0x70, 0xaa, 0x08, 0xf9, 0x4b, + 0xc2, 0xfd, 0x7a, 0x06, 0x88, 0x8d, 0x89, 0x8e, 0x89, 0x8d, 0x08, 0x5e, + 0xb7, 0x05, 0x81, 0x95, 0x86, 0x90, 0x7e, 0x96, 0x9c, 0x9a, 0x95, 0x94, + 0xc0, 0xc0, 0x08, 0xf9, 0x7a, 0x8a, 0x05, 0x0e, 0x3b, 0xf8, 0x10, 0xf9, + 0x7a, 0x15, 0xfd, 0x7a, 0xc2, 0xf9, 0x4b, 0x07, 0xbd, 0x61, 0xae, 0x70, + 0x98, 0x81, 0xad, 0xb6, 0x05, 0x3e, 0xc5, 0xfb, 0x10, 0xf7, 0x0a, 0x4c, + 0xd5, 0x48, 0x3c, 0x22, 0x28, 0x2f, 0x43, 0x08, 0xad, 0x60, 0x98, 0x95, + 0x05, 0xc1, 0xb5, 0x8b, 0x8b, 0xaa, 0xa6, 0x08, 0xfd, 0x4b, 0xc2, 0xf9, + 0x7a, 0x07, 0x8d, 0x8e, 0x8d, 0x8d, 0x8e, 0x8d, 0x08, 0x98, 0x98, 0x05, + 0x91, 0x92, 0x92, 0x91, 0x92, 0x92, 0x9c, 0x9c, 0x92, 0x93, 0x98, 0x9a, + 0x98, 0x7d, 0x91, 0x84, 0x9e, 0x78, 0x08, 0xb2, 0x63, 0x05, 0x0e, 0xf7, + 0xc4, 0xb8, 0xf7, 0x3b, 0x15, 0x54, 0xf9, 0x4b, 0x07, 0x79, 0x77, 0x7f, + 0x7c, 0x7f, 0x7c, 0x78, 0x72, 0x7f, 0x7b, 0x86, 0x85, 0x08, 0xb6, 0x69, + 0x05, 0xd3, 0xe8, 0xe8, 0xec, 0xdf, 0xd4, 0x38, 0xd2, 0x2c, 0xee, 0x44, + 0xe7, 0x08, 0x60, 0x69, 0x94, 0x7f, 0x05, 0x94, 0x80, 0x94, 0x7f, 0x94, + 0x7f, 0x08, 0x97, 0x7c, 0x05, 0x96, 0x7f, 0x90, 0x84, 0x99, 0x7b, 0x08, + 0xfd, 0x4b, 0x54, 0x06, 0xf9, 0x7a, 0x8c, 0x92, 0x84, 0xac, 0x6a, 0x05, + 0x9c, 0x7a, 0x93, 0x83, 0x9a, 0x7f, 0x7b, 0x7d, 0x82, 0x82, 0x7c, 0x7c, + 0x80, 0x7f, 0x80, 0x81, 0x81, 0x80, 0x89, 0x8a, 0x89, 0x88, 0x87, 0x88, + 0x08, 0xfd, 0x7a, 0x8c, 0x05, 0x0e, 0x3b, 0xf7, 0x7b, 0xf7, 0x3b, 0x15, + 0xf9, 0x7a, 0x54, 0xfd, 0x4b, 0x07, 0x59, 0xb5, 0x68, 0xa6, 0x05, 0x86, + 0x8f, 0x88, 0x8e, 0x86, 0x8e, 0x08, 0x69, 0x60, 0x05, 0xda, 0x50, 0xf7, + 0x0e, 0xfb, 0x08, 0xca, 0x40, 0xcd, 0xd9, 0xf7, 0x01, 0xf2, 0xe4, 0xd0, + 0x08, 0x69, 0xb6, 0x05, 0x87, 0x88, 0x87, 0x87, 0x86, 0x88, 0x55, 0x61, + 0x8b, 0x8b, 0x6c, 0x70, 0x08, 0xf9, 0x4b, 0x54, 0xfd, 0x7a, 0x07, 0x84, + 0x84, 0x6a, 0x6a, 0x05, 0x7a, 0x7a, 0x84, 0x83, 0x7e, 0x7c, 0x7e, 0x99, + 0x85, 0x92, 0x78, 0x9e, 0x08, 0x64, 0xb3, 0x05, 0x0e, 0xfb, 0x51, 0xf7, + 0x65, 0x16, 0xc7, 0x8a, 0xf7, 0x59, 0xf8, 0x0b, 0xfb, 0x51, 0xf8, 0x02, + 0x4c, 0x8b, 0xfb, 0x58, 0xfb, 0xff, 0xf7, 0x53, 0xfc, 0x0d, 0x05, 0xaa, + 0xc5, 0x15, 0xfb, 0x33, 0xf7, 0xd2, 0xf7, 0x38, 0xf7, 0xc7, 0xf7, 0x31, + 0xfb, 0xca, 0xfb, 0x36, 0xfb, 0xcf, 0x05, 0x0e, 0xfb, 0xf6, 0xf7, 0x92, + 0xf9, 0x89, 0x15, 0xfb, 0x79, 0xfc, 0x5a, 0xf7, 0x79, 0xfc, 0x5b, 0xbf, + 0xa4, 0xfb, 0x6b, 0xf8, 0x42, 0xf7, 0x6b, 0xf8, 0x42, 0x57, 0xa3, 0x05, + 0x0e, 0xf6, 0xf7, 0x8d, 0xf8, 0xa3, 0x15, 0xfc, 0x1a, 0xbe, 0xf7, 0x3c, + 0xe2, 0x07, 0xde, 0x8b, 0x9d, 0x7b, 0x90, 0x3e, 0x8d, 0x58, 0x8d, 0x7d, + 0x91, 0x81, 0x08, 0xbd, 0x06, 0x85, 0x97, 0x89, 0x97, 0x89, 0xb2, 0x89, + 0xdf, 0x7f, 0xa2, 0x59, 0x9d, 0xb8, 0x9e, 0xa2, 0xab, 0x8b, 0xb7, 0x8b, + 0xb1, 0x7a, 0xab, 0x6b, 0x9d, 0x76, 0x99, 0x70, 0x90, 0x62, 0x8b, 0x08, + 0xfb, 0x34, 0x06, 0xbe, 0x62, 0x15, 0xed, 0x06, 0xce, 0xab, 0x74, 0x5c, + 0x5a, 0x69, 0x74, 0x43, 0x1f, 0x30, 0xf7, 0x22, 0x06, 0xef, 0xf7, 0x55, + 0x15, 0xfb, 0x58, 0xfb, 0x2e, 0xfb, 0x2d, 0xfb, 0x55, 0xfb, 0x52, 0xf7, + 0x2f, 0xfb, 0x2f, 0xf7, 0x52, 0xf7, 0x52, 0xf7, 0x2f, 0xf7, 0x2f, 0xf7, + 0x52, 0xf7, 0x51, 0xfb, 0x2e, 0xf7, 0x31, 0xfb, 0x4e, 0x1f, 0x8a, 0x65, + 0x15, 0xf7, 0x37, 0xf7, 0x1c, 0xfb, 0x20, 0xfb, 0x3c, 0xfb, 0x3d, 0xfb, + 0x1c, 0xfb, 0x1e, 0xfb, 0x3b, 0xfb, 0x3a, 0xfb, 0x1d, 0xf7, 0x1e, 0xf7, + 0x3d, 0xf7, 0x40, 0xf7, 0x1b, 0xf7, 0x1c, 0xf7, 0x40, 0x1f, 0x0e, 0xf6, + 0xf8, 0xa3, 0xf7, 0xbc, 0x15, 0x81, 0x3e, 0x5c, 0x5e, 0x42, 0x8b, 0x08, + 0x37, 0x53, 0xcb, 0xeb, 0xec, 0xc4, 0xcc, 0xdf, 0x1f, 0xcc, 0x8b, 0xba, + 0x68, 0x97, 0x50, 0x08, 0xbc, 0x06, 0x84, 0xda, 0x42, 0xc5, 0x30, 0x8b, + 0x08, 0xfb, 0x07, 0x3c, 0x37, 0xfb, 0x0d, 0xfb, 0x0c, 0xd8, 0x38, 0xf7, + 0x06, 0x1f, 0xf0, 0x8b, 0xd2, 0xcd, 0x93, 0xee, 0x08, 0x59, 0x06, 0xfb, + 0x14, 0xf8, 0x13, 0x15, 0xfb, 0x57, 0xfb, 0x2f, 0xfb, 0x2d, 0xfb, 0x55, + 0xfb, 0x52, 0xf7, 0x30, 0xfb, 0x2f, 0xf7, 0x51, 0xf7, 0x52, 0xf7, 0x2f, + 0xf7, 0x2f, 0xf7, 0x52, 0xf7, 0x51, 0xfb, 0x2f, 0xf7, 0x31, 0xfb, 0x4d, + 0x1f, 0x8a, 0x65, 0x15, 0xf7, 0x37, 0xf7, 0x1c, 0xfb, 0x20, 0xfb, 0x3c, + 0xfb, 0x3d, 0xfb, 0x1c, 0xfb, 0x1e, 0xfb, 0x3b, 0xfb, 0x3a, 0xfb, 0x1d, + 0xf7, 0x1e, 0xf7, 0x3d, 0xf7, 0x40, 0xf7, 0x1c, 0xf7, 0x1c, 0xf7, 0x3f, + 0x1f, 0x0e, 0xf2, 0xf8, 0xad, 0xf7, 0xa9, 0x15, 0xf7, 0x19, 0xf7, 0xee, + 0x8b, 0xfb, 0xee, 0xc2, 0x8b, 0x8b, 0xf8, 0x20, 0x32, 0x8b, 0xfb, 0x08, + 0xfb, 0xb7, 0xfb, 0x02, 0xf7, 0xb7, 0x31, 0x8b, 0x8b, 0xfc, 0x20, 0xc2, + 0x8b, 0x8b, 0xf7, 0xee, 0xf7, 0x15, 0xfb, 0xee, 0xac, 0x8b, 0x05, 0xfb, + 0xf9, 0xf7, 0xee, 0x15, 0xf7, 0x02, 0xbd, 0xfb, 0xb1, 0x59, 0xf7, 0x04, + 0xfb, 0xee, 0xca, 0xf7, 0xee, 0x06, 0x0e, 0xa9, 0xf7, 0x44, 0xf9, 0x5b, + 0x15, 0xf7, 0xa0, 0x06, 0xf7, 0x07, 0x8b, 0xa9, 0x74, 0x9c, 0x26, 0x08, + 0xa5, 0x8b, 0x81, 0xf7, 0x39, 0xfc, 0xeb, 0x8b, 0xf7, 0x7d, 0xfc, 0x67, + 0xfb, 0x86, 0xfc, 0x2c, 0xf9, 0x07, 0x8b, 0xc1, 0xf7, 0x66, 0x71, 0x8b, + 0x05, 0x6b, 0x3a, 0x6d, 0x7a, 0xfb, 0x08, 0x8b, 0x08, 0xfb, 0xdc, 0x8b, + 0xf7, 0x5d, 0xf7, 0xf4, 0xfb, 0x50, 0xf8, 0x06, 0x05, 0x0e, 0xfb, 0xbf, + 0xb3, 0xfb, 0xb9, 0x15, 0xbf, 0xf8, 0x43, 0x06, 0x8b, 0xf7, 0x66, 0xc8, + 0xf7, 0x7d, 0xe5, 0xf7, 0x1c, 0xc6, 0xe3, 0xce, 0xd0, 0xce, 0xb4, 0x08, + 0x7d, 0x96, 0x05, 0x2f, 0x59, 0x57, 0x62, 0x59, 0x50, 0xfb, 0x0a, 0xfb, + 0x20, 0x45, 0xfb, 0x77, 0x8b, 0xfb, 0x85, 0x08, 0xfc, 0x61, 0x07, 0x0e, + 0xfb, 0xbf, 0xb3, 0x3c, 0x15, 0xbf, 0xfa, 0x80, 0x57, 0xfe, 0x80, 0x06, + 0x0e, 0xfb, 0xbf, 0xb3, 0xfa, 0x32, 0x15, 0xfc, 0x61, 0x07, 0x8b, 0xfb, + 0x73, 0xc7, 0xfb, 0x68, 0xf3, 0xfb, 0x23, 0xc1, 0x41, 0xc1, 0x5e, 0xf7, + 0x02, 0x4e, 0x08, 0x99, 0x96, 0x05, 0x3c, 0xc1, 0x57, 0xbe, 0x5c, 0xcd, + 0x23, 0xf7, 0x27, 0x4d, 0xf7, 0x75, 0x8b, 0xf7, 0x7e, 0x08, 0xf8, 0x43, + 0x57, 0x07, 0x0e, 0xfb, 0xbf, 0x3b, 0x04, 0xc2, 0xfa, 0x4b, 0xf7, 0xb2, + 0xc2, 0xfb, 0xe9, 0xfe, 0x82, 0x06, 0x0e, 0xfb, 0xbf, 0xfa, 0x31, 0x04, + 0xfe, 0x86, 0xc2, 0xfa, 0x86, 0x54, 0x07, 0x0e, 0xfb, 0xbf, 0xfa, 0x32, + 0x04, 0xfe, 0x82, 0xf7, 0xe8, 0xc2, 0xfb, 0xb1, 0xfa, 0x4b, 0x54, 0x07, + 0x0e, 0xfb, 0x51, 0xf7, 0x93, 0x40, 0x15, 0xf9, 0x4a, 0x07, 0x8b, 0xf7, + 0x05, 0x9a, 0xc5, 0xb4, 0xb7, 0xac, 0xad, 0xb3, 0xa1, 0xc2, 0x99, 0x08, + 0xa1, 0x07, 0x45, 0x7f, 0x6d, 0x82, 0x66, 0x74, 0x42, 0x5e, 0x6f, 0x46, + 0x8b, 0xfb, 0x17, 0x08, 0xfd, 0x5c, 0xc1, 0x07, 0x0e, 0xfb, 0x51, 0xf7, + 0x93, 0xfa, 0x3b, 0x15, 0x55, 0xfb, 0x84, 0x06, 0x8b, 0x34, 0x7d, 0x5a, + 0x69, 0x67, 0x69, 0x68, 0x64, 0x7a, 0x49, 0x81, 0x08, 0x4e, 0x07, 0xc8, + 0x82, 0xad, 0x7d, 0xac, 0x6e, 0xb6, 0x66, 0x9b, 0x59, 0x8b, 0x2c, 0x08, + 0xfb, 0x8f, 0xc1, 0xf7, 0xa4, 0x07, 0x8b, 0xdc, 0x7e, 0xb8, 0x68, 0xb6, + 0x6e, 0xaf, 0x6a, 0x9d, 0x44, 0xa0, 0xcb, 0x9c, 0xaa, 0x9b, 0xa7, 0xa9, + 0xb5, 0xb6, 0x9b, 0xbd, 0x8b, 0xe2, 0x08, 0xf7, 0x99, 0x07, 0x0e, 0xfb, + 0x51, 0xf7, 0x93, 0xfa, 0x32, 0x15, 0x55, 0xfd, 0x57, 0x06, 0x8b, 0xfb, + 0x17, 0xa7, 0x46, 0xd4, 0x5e, 0xb0, 0x74, 0xa9, 0x82, 0xd1, 0x7f, 0x08, + 0xa1, 0x07, 0x59, 0x98, 0x66, 0x9e, 0x6b, 0xa8, 0x5b, 0xb9, 0x7a, 0xc4, + 0x8b, 0xf7, 0x0d, 0x08, 0xf9, 0x45, 0x07, 0x0e, 0xfb, 0x51, 0xf7, 0x5d, + 0xfa, 0x31, 0x15, 0xfe, 0x80, 0xc1, 0xfa, 0x80, 0x55, 0x07, 0x0e, 0xfb, + 0xf6, 0xd4, 0xf9, 0x89, 0x15, 0x57, 0x73, 0xf7, 0x6b, 0xfc, 0x42, 0xfb, + 0x6b, 0xfc, 0x42, 0xbf, 0x72, 0xf7, 0x79, 0xf8, 0x5b, 0xfb, 0x79, 0xf8, + 0x5a, 0x05, 0x0e, 0xfc, 0x2d, 0xf7, 0x48, 0xf8, 0xd4, 0x15, 0x8b, 0xd6, + 0x8a, 0xb6, 0x88, 0xbf, 0x89, 0xa7, 0x8a, 0xa6, 0x8b, 0x99, 0x8b, 0xb3, + 0x96, 0xa2, 0x9d, 0x8b, 0x90, 0x8b, 0x91, 0x88, 0x8d, 0x88, 0x9b, 0x70, + 0x93, 0x85, 0x9c, 0x8b, 0x08, 0x9e, 0x9b, 0x99, 0x9d, 0xa6, 0x73, 0x9d, + 0x67, 0x1f, 0x5f, 0x8b, 0x68, 0x6e, 0x7d, 0x5a, 0x7c, 0x55, 0x81, 0x25, + 0x8b, 0x22, 0x08, 0xfb, 0xed, 0x07, 0x8b, 0x47, 0x8c, 0x5c, 0x8e, 0x55, + 0x8d, 0x6d, 0x8c, 0x6f, 0x8b, 0x7a, 0x8b, 0x68, 0x7f, 0x74, 0x78, 0x8b, + 0x83, 0x8b, 0x84, 0x90, 0x85, 0x98, 0x82, 0x9b, 0x83, 0x91, 0x7d, 0x8b, + 0x08, 0x78, 0x7b, 0x7c, 0x79, 0x71, 0xa4, 0x79, 0xae, 0x1f, 0xb8, 0x8b, + 0xad, 0xa8, 0x99, 0xbc, 0x9a, 0xc1, 0x95, 0xf0, 0x8b, 0xf5, 0x08, 0xf7, + 0xec, 0x07, 0x0e, 0x8e, 0xf7, 0xe0, 0x38, 0x15, 0xde, 0xf8, 0x68, 0x06, + 0x8b, 0xf7, 0x42, 0xab, 0xf7, 0x32, 0xbe, 0xda, 0xa9, 0xb9, 0xae, 0xa6, + 0xaa, 0x8b, 0x8f, 0x8b, 0x8f, 0x8a, 0x92, 0x89, 0x7c, 0x7e, 0x85, 0x80, + 0x8b, 0x7a, 0x08, 0x6d, 0xa6, 0x73, 0xad, 0xb1, 0xa7, 0xa9, 0xb4, 0xb9, + 0x67, 0xad, 0x5b, 0x1e, 0x50, 0x8b, 0x49, 0x5b, 0x51, 0x37, 0x3d, 0xfb, + 0x06, 0x65, 0xfb, 0x29, 0x8b, 0xfb, 0x56, 0x08, 0xfc, 0x34, 0x07, 0x0e, + 0x8e, 0xf7, 0xe0, 0x33, 0x15, 0xde, 0xfa, 0xbb, 0x38, 0xfe, 0xbb, 0x06, + 0x0e, 0x8e, 0xf8, 0x33, 0xfa, 0x2d, 0x15, 0x38, 0xfc, 0x65, 0x06, 0x8b, + 0xfb, 0x42, 0x6b, 0xfb, 0x32, 0x58, 0x3c, 0x6d, 0x5d, 0x68, 0x70, 0x6c, + 0x8b, 0x87, 0x8b, 0x87, 0x8c, 0x84, 0x8d, 0x9a, 0x98, 0x91, 0x96, 0x8b, + 0x9c, 0x08, 0xa9, 0x70, 0xa3, 0x69, 0x69, 0x72, 0x6d, 0x62, 0x5d, 0xac, + 0x69, 0xb8, 0x1e, 0xc5, 0x8b, 0xcd, 0xbb, 0xc5, 0xdf, 0xd9, 0xf7, 0x06, + 0xb1, 0xf7, 0x29, 0x8b, 0xf7, 0x56, 0x08, 0xf8, 0x31, 0x07, 0x0e, 0xfb, + 0xbf, 0xf8, 0x56, 0xfb, 0xb9, 0x15, 0xf8, 0x61, 0x07, 0x8b, 0xf7, 0x73, + 0x4e, 0xf7, 0x6a, 0x24, 0xf7, 0x21, 0x54, 0xd6, 0x51, 0xbb, 0x22, 0xc4, + 0x08, 0x7d, 0x80, 0x05, 0xf7, 0x00, 0x49, 0xf5, 0xfb, 0x1a, 0xbf, 0xfb, + 0x1c, 0xbd, 0xfb, 0x16, 0xa7, 0xfb, 0x34, 0x8b, 0xfb, 0x2b, 0x08, 0xfc, + 0x43, 0xbf, 0x07, 0x0e, 0xfb, 0xbf, 0xf8, 0x56, 0xfa, 0x3b, 0x15, 0x57, + 0xfe, 0x81, 0xbf, 0xfa, 0x81, 0x06, 0x0e, 0xfb, 0xbf, 0xf8, 0x56, 0xfa, + 0x32, 0x15, 0x57, 0xfc, 0x43, 0x06, 0x8b, 0xfb, 0x72, 0x52, 0xfb, 0x6f, + 0x2e, 0xfb, 0x1f, 0x51, 0x34, 0x49, 0x48, 0x45, 0x60, 0x08, 0x99, 0x80, + 0x05, 0xe3, 0xba, 0xc2, 0xb6, 0xbe, 0xc7, 0xf7, 0x0a, 0xf7, 0x20, 0xd1, + 0xf7, 0x77, 0x8b, 0xf7, 0x85, 0x08, 0xf8, 0x61, 0x07, 0x0e, 0xfb, 0xbf, + 0xf7, 0xfc, 0x3b, 0x15, 0xfa, 0x82, 0xfb, 0xe6, 0x54, 0xf7, 0xaf, 0xfe, + 0x4b, 0xc2, 0x07, 0x0e, 0xfb, 0xbf, 0xf7, 0xc5, 0xfa, 0x31, 0x15, 0xfe, + 0x86, 0xc2, 0xfa, 0x86, 0x54, 0x07, 0x0e, 0xfb, 0xbf, 0xf7, 0xfc, 0xfa, + 0x32, 0x15, 0x54, 0xfe, 0x4b, 0xfb, 0xb1, 0x54, 0xf7, 0xe8, 0xfa, 0x82, + 0x06, 0x0e, 0xfb, 0x51, 0xf7, 0x5d, 0x40, 0x15, 0xc1, 0xf9, 0x5c, 0x06, + 0x8b, 0xf7, 0x17, 0x6f, 0xd0, 0x42, 0xb8, 0x66, 0xa2, 0x6d, 0x94, 0x45, + 0x97, 0x08, 0x75, 0x07, 0xbd, 0x7e, 0xb0, 0x78, 0xab, 0x6e, 0xbb, 0x5d, + 0x9c, 0x52, 0x8b, 0xfb, 0x0d, 0x08, 0xfd, 0x4a, 0x07, 0x0e, 0xfb, 0x51, + 0xf7, 0x5d, 0xfa, 0x3b, 0x15, 0xfb, 0x99, 0x07, 0x8b, 0x3b, 0x98, 0x5d, + 0xaf, 0x60, 0xa8, 0x67, 0xad, 0x78, 0xd1, 0x78, 0x4b, 0x78, 0x6c, 0x7b, + 0x6e, 0x6e, 0x61, 0x60, 0x7b, 0x58, 0x8b, 0x35, 0x08, 0xfb, 0xa4, 0xc1, + 0xf7, 0x8f, 0x07, 0x8b, 0xe7, 0x97, 0xb6, 0xaf, 0xb0, 0xac, 0xae, 0xb2, + 0x9c, 0xce, 0x95, 0x08, 0xc8, 0x07, 0x4e, 0x94, 0x69, 0x98, 0x69, 0xa9, + 0x5f, 0xb1, 0x7d, 0xb7, 0x8b, 0xef, 0x08, 0xf7, 0x84, 0x55, 0x07, 0x0e, + 0xfb, 0x51, 0xf7, 0x5d, 0xfa, 0x32, 0x15, 0xfd, 0x45, 0x07, 0x8b, 0xfb, + 0x05, 0x7c, 0x51, 0x62, 0x5f, 0x6a, 0x69, 0x63, 0x75, 0x54, 0x7d, 0x08, + 0x75, 0x07, 0xd1, 0x97, 0xa9, 0x94, 0xb0, 0xa2, 0xd4, 0xb8, 0xa7, 0xd0, + 0x8b, 0xf7, 0x17, 0x08, 0xf9, 0x57, 0x55, 0x07, 0x0e, 0xf8, 0xb9, 0x14, + 0xf9, 0x3f, 0x15, 0xf9, 0x35, 0x9f, 0x06, 0x1e, 0x0a, 0x03, 0x96, 0x25, + 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0x8b, 0x0a, 0x0c, 0x0c, 0x8b, 0x0b, + 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00, 0x00, 0x00 +}; +const unsigned int fonts_StandardSymL_cff_len = 18944; diff --git a/rosapps/smartpdf/fitz/fonts/URWChanceryL-MediItal.cff.c b/rosapps/smartpdf/fitz/fonts/URWChanceryL-MediItal.cff.c new file mode 100644 index 00000000000..fa2a1b43ede --- /dev/null +++ b/rosapps/smartpdf/fitz/fonts/URWChanceryL-MediItal.cff.c @@ -0,0 +1,2873 @@ +const unsigned char fonts_URWChanceryL_MediItal_cff[] = { + 0x01, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x01, 0x16, 0x55, 0x52, 0x57, + 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x79, 0x4c, 0x2d, 0x4d, 0x65, + 0x64, 0x69, 0x49, 0x74, 0x61, 0x6c, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, + 0x43, 0xf8, 0x1f, 0x00, 0xf8, 0x20, 0x01, 0xf8, 0x21, 0x02, 0xf8, 0x22, + 0x03, 0xf8, 0x17, 0x04, 0x7d, 0x0c, 0x02, 0xfb, 0x0c, 0x0c, 0x03, 0x1d, + 0x00, 0x4c, 0x9f, 0x87, 0x0d, 0xfb, 0x19, 0xfb, 0x9e, 0xfa, 0xca, 0xf9, + 0xc9, 0x05, 0x1d, 0x00, 0x00, 0x01, 0x06, 0x0f, 0x1d, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x1d, 0x00, 0x00, 0x02, 0xd7, 0x11, 0x1d, 0x00, 0x00, 0x00, + 0x2c, 0x1d, 0x00, 0x00, 0x86, 0x55, 0x12, 0x00, 0x08, 0x02, 0x00, 0x01, + 0x00, 0x05, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x5f, + 0x00, 0x7b, 0x00, 0x89, 0x45, 0x75, 0x72, 0x6f, 0x6d, 0x69, 0x64, 0x64, + 0x6f, 0x74, 0x73, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x6e, + 0x62, 0x73, 0x70, 0x61, 0x63, 0x65, 0x31, 0x2e, 0x30, 0x35, 0x43, 0x6f, + 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x55, 0x52, 0x57, + 0x29, 0x2b, 0x2b, 0x2c, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x62, 0x79, 0x20, 0x28, 0x55, + 0x52, 0x57, 0x29, 0x2b, 0x2b, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x20, 0x26, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, + 0x6e, 0x74, 0x55, 0x52, 0x57, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, + 0x72, 0x79, 0x20, 0x4c, 0x20, 0x4d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x20, + 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x55, 0x52, 0x57, 0x20, 0x43, 0x68, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x79, 0x20, 0x4c, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, + 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, + 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, + 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, + 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, + 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, + 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, + 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, + 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, + 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, + 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, + 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, + 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, + 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, + 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, + 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, + 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, + 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, + 0x7f, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, + 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, + 0x8b, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0x90, 0x00, + 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0xad, 0x00, + 0xab, 0x00, 0xae, 0x00, 0xac, 0x00, 0xb0, 0x00, 0xaf, 0x00, 0xb1, 0x00, + 0x9a, 0x00, 0xb4, 0x00, 0xb2, 0x00, 0xb5, 0x00, 0xb3, 0x00, 0xb8, 0x00, + 0xb6, 0x00, 0xb9, 0x00, 0xb7, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xbb, 0x00, + 0xbe, 0x00, 0xbc, 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc1, 0x00, + 0xc4, 0x00, 0xc2, 0x00, 0xc5, 0x00, 0xc7, 0x00, 0x9d, 0x00, 0xc6, 0x00, + 0xca, 0x00, 0xc8, 0x00, 0xcb, 0x00, 0xc9, 0x00, 0xcd, 0x00, 0xcc, 0x00, + 0xce, 0x00, 0xd1, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd0, 0x00, 0xd5, 0x00, + 0xd3, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xd8, 0x00, + 0xdb, 0x00, 0xd9, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xde, 0x00, + 0xe1, 0x00, 0xdf, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xa7, 0x00, 0xa2, 0x00, + 0xe3, 0x01, 0x87, 0x00, 0x96, 0x00, 0xa4, 0x00, 0xa9, 0x01, 0x88, 0x01, + 0x89, 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x99, 0x00, + 0x9c, 0x00, 0x9b, 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xaa, 0x00, 0xa5, 0x01, + 0x8a, 0x00, 0x97, 0x00, 0xa0, 0x00, 0x98, 0x00, 0xe9, 0x02, 0x00, 0x01, + 0x00, 0x03, 0x00, 0x05, 0x00, 0x68, 0x00, 0x87, 0x01, 0x66, 0x02, 0x33, + 0x02, 0xee, 0x03, 0xc4, 0x03, 0xf1, 0x04, 0x36, 0x04, 0x80, 0x04, 0xbd, + 0x04, 0xda, 0x04, 0xf8, 0x05, 0x21, 0x05, 0x52, 0x05, 0x88, 0x05, 0xde, + 0x06, 0x46, 0x06, 0xd0, 0x07, 0x4a, 0x07, 0xe0, 0x08, 0x5c, 0x08, 0xce, + 0x09, 0x29, 0x09, 0xc0, 0x0a, 0x2b, 0x0a, 0x9e, 0x0a, 0xf8, 0x0b, 0x16, + 0x0b, 0x2f, 0x0b, 0x4d, 0x0b, 0xd2, 0x0c, 0xc7, 0x0d, 0xa8, 0x0e, 0x73, + 0x0e, 0xbd, 0x0f, 0x51, 0x10, 0x20, 0x10, 0xb1, 0x11, 0x48, 0x12, 0x3a, + 0x12, 0x8c, 0x13, 0x02, 0x13, 0xdc, 0x14, 0x61, 0x15, 0x71, 0x16, 0x54, + 0x16, 0xaa, 0x17, 0x4c, 0x17, 0xdb, 0x18, 0xb2, 0x19, 0x18, 0x19, 0xa0, + 0x1a, 0x67, 0x1a, 0xf2, 0x1b, 0xa6, 0x1c, 0x64, 0x1c, 0xef, 0x1d, 0xac, + 0x1d, 0xef, 0x1e, 0x02, 0x1e, 0x4b, 0x1e, 0x66, 0x1e, 0x72, 0x1e, 0xa1, + 0x1f, 0x3f, 0x1f, 0xdd, 0x20, 0x35, 0x20, 0xe0, 0x21, 0x45, 0x21, 0xfb, + 0x22, 0xb9, 0x23, 0x4c, 0x23, 0xee, 0x24, 0x87, 0x25, 0x34, 0x25, 0xa3, + 0x26, 0x66, 0x26, 0xfb, 0x27, 0x4c, 0x27, 0xfe, 0x28, 0xb1, 0x29, 0x0f, + 0x29, 0x84, 0x2a, 0x08, 0x2a, 0xb0, 0x2b, 0x46, 0x2c, 0x23, 0x2c, 0xc8, + 0x2d, 0x62, 0x2e, 0x03, 0x2e, 0x78, 0x2e, 0x87, 0x2e, 0xfa, 0x2f, 0x42, + 0x2f, 0x9e, 0x30, 0x58, 0x30, 0xf9, 0x31, 0x3c, 0x32, 0x03, 0x32, 0xb8, + 0x33, 0x58, 0x33, 0xc4, 0x33, 0xd7, 0x34, 0x31, 0x34, 0xb7, 0x34, 0xf2, + 0x35, 0x20, 0x36, 0x0b, 0x36, 0xf8, 0x37, 0x26, 0x37, 0x71, 0x37, 0xd8, + 0x37, 0xf0, 0x38, 0x4f, 0x38, 0x68, 0x38, 0x95, 0x38, 0xf1, 0x39, 0x40, + 0x39, 0xa9, 0x3a, 0x39, 0x3b, 0x3c, 0x3b, 0xbe, 0x3b, 0xe0, 0x3b, 0xf7, + 0x3c, 0x44, 0x3c, 0x88, 0x3c, 0xad, 0x3c, 0xdf, 0x3d, 0x0e, 0x3d, 0x6f, + 0x3d, 0x9b, 0x3d, 0xcb, 0x3e, 0x1e, 0x3e, 0x54, 0x3e, 0x99, 0x3e, 0xd1, + 0x3f, 0xb8, 0x40, 0x69, 0x41, 0x41, 0x41, 0xe4, 0x42, 0xb4, 0x43, 0x04, + 0x43, 0xe8, 0x44, 0x4e, 0x45, 0x04, 0x45, 0xa7, 0x46, 0x4d, 0x47, 0x25, + 0x48, 0x65, 0x49, 0x5f, 0x4a, 0x64, 0x4b, 0x96, 0x4c, 0xb9, 0x4d, 0xc4, + 0x4e, 0x37, 0x4f, 0x09, 0x50, 0x37, 0x51, 0x1a, 0x52, 0x13, 0x53, 0x3d, + 0x53, 0xe0, 0x54, 0x4b, 0x54, 0xbb, 0x55, 0x5d, 0x56, 0x83, 0x57, 0x32, + 0x57, 0x9b, 0x58, 0x18, 0x58, 0xb9, 0x59, 0x50, 0x59, 0xf6, 0x5b, 0x1b, + 0x5b, 0xf5, 0x5c, 0xe0, 0x5d, 0xf3, 0x5e, 0x97, 0x5f, 0xbe, 0x60, 0x6c, + 0x61, 0x53, 0x62, 0x50, 0x63, 0x05, 0x63, 0xca, 0x64, 0xb2, 0x65, 0x92, + 0x66, 0x5c, 0x66, 0xeb, 0x67, 0xb0, 0x68, 0x2a, 0x68, 0xc5, 0x69, 0x72, + 0x6a, 0x36, 0x6a, 0xb1, 0x6b, 0x3c, 0x6b, 0xf1, 0x6c, 0xc8, 0x6d, 0x78, + 0x6d, 0xdc, 0x6e, 0x4f, 0x6e, 0xe2, 0x6f, 0x76, 0x70, 0x2e, 0x71, 0x35, + 0x71, 0xf2, 0x72, 0xbf, 0x73, 0xb1, 0x74, 0x60, 0x75, 0x45, 0x75, 0xd0, + 0x76, 0x84, 0x77, 0x74, 0x78, 0x0e, 0x78, 0x5e, 0x78, 0xda, 0x79, 0x55, + 0x79, 0x6d, 0x79, 0x96, 0x79, 0xc2, 0x79, 0xd1, 0x7a, 0x02, 0x7a, 0x3b, + 0x7b, 0x68, 0x7b, 0x91, 0x7c, 0xa6, 0x7d, 0xea, 0x7f, 0x59, 0x80, 0x03, + 0x80, 0xd5, 0x80, 0xd7, 0x80, 0xe9, 0x81, 0x02, 0x81, 0xa8, 0x2e, 0x0e, + 0x2e, 0x0e, 0x6a, 0xf7, 0x68, 0xdb, 0x15, 0x81, 0x9b, 0x05, 0x88, 0x90, + 0x84, 0x96, 0x82, 0x9b, 0x87, 0x88, 0x86, 0x87, 0x86, 0x86, 0x83, 0x85, + 0x83, 0x84, 0x83, 0x84, 0x08, 0x82, 0x84, 0x70, 0x76, 0x05, 0x94, 0x74, + 0x9e, 0x6c, 0x9e, 0x74, 0xb0, 0xa6, 0x94, 0x92, 0xa7, 0xa8, 0x88, 0x8f, + 0x87, 0x91, 0x88, 0x90, 0x08, 0x83, 0x96, 0x05, 0xb9, 0xf8, 0x65, 0x15, + 0x75, 0x38, 0x7a, 0x49, 0x51, 0xfb, 0x84, 0xa0, 0x97, 0x8c, 0x8b, 0xac, + 0xa0, 0x91, 0x9b, 0x90, 0x9b, 0x90, 0x9a, 0x95, 0xa4, 0x94, 0xa6, 0x93, + 0xa9, 0x96, 0xac, 0x96, 0xac, 0x95, 0xad, 0x08, 0xc3, 0xf7, 0x3d, 0x62, + 0x78, 0x5b, 0x74, 0x05, 0x0e, 0x2e, 0xf7, 0x3e, 0xf8, 0x29, 0x15, 0xa8, + 0x97, 0xc7, 0xf7, 0x42, 0x62, 0x8b, 0x5b, 0xfb, 0x4e, 0x05, 0xd5, 0x16, + 0xa8, 0x97, 0xc7, 0xf7, 0x42, 0x62, 0x8b, 0x5b, 0xfb, 0x4e, 0x05, 0x0e, + 0xf7, 0x6b, 0xb3, 0x15, 0xb8, 0xf7, 0x26, 0xf3, 0x93, 0x05, 0x84, 0x7a, + 0x86, 0x7b, 0x89, 0x88, 0x08, 0x75, 0x4a, 0x05, 0x8a, 0x86, 0x80, 0x6c, + 0x78, 0x51, 0x08, 0xdf, 0xb4, 0x05, 0x97, 0xb8, 0xa3, 0xda, 0x97, 0xae, + 0x08, 0xe6, 0x92, 0xa5, 0xab, 0x22, 0x8b, 0x05, 0x93, 0xa6, 0x8b, 0x8c, + 0x97, 0xaf, 0x08, 0xa0, 0xd1, 0xe3, 0x92, 0xa5, 0xac, 0x27, 0x8b, 0x05, + 0x90, 0x98, 0x94, 0xa6, 0x98, 0xb2, 0x96, 0xad, 0x96, 0xaa, 0x91, 0x9e, + 0x08, 0x46, 0x70, 0x05, 0x7b, 0x58, 0x8a, 0x86, 0x85, 0x7a, 0x85, 0x7a, + 0x89, 0x84, 0x85, 0x7c, 0x88, 0x83, 0x88, 0x83, 0x89, 0x83, 0x08, 0x20, + 0x89, 0xa6, 0xd9, 0x05, 0x9a, 0xba, 0x8c, 0x8e, 0x98, 0xb0, 0x08, 0x47, + 0x70, 0x72, 0x3f, 0x05, 0x86, 0x7e, 0x87, 0x7d, 0x87, 0x7f, 0x8a, 0x87, + 0x87, 0x81, 0x88, 0x80, 0x08, 0x25, 0x89, 0x05, 0x84, 0x83, 0x83, 0x80, + 0x8a, 0x8b, 0x7d, 0x78, 0x80, 0x7d, 0x84, 0x80, 0x08, 0xf7, 0x17, 0x95, + 0x05, 0x88, 0x7e, 0x88, 0x82, 0x89, 0x87, 0x08, 0x86, 0x7e, 0x05, 0x87, + 0x7d, 0x85, 0x7a, 0x84, 0x76, 0x8b, 0x8b, 0x87, 0x7e, 0x87, 0x80, 0x08, + 0x22, 0x06, 0x79, 0x74, 0x84, 0x81, 0x75, 0x68, 0x08, 0xf7, 0x17, 0x97, + 0x05, 0x79, 0x52, 0x78, 0x55, 0x71, 0x43, 0x08, 0xdf, 0xb4, 0x05, 0xc8, + 0xf7, 0x5a, 0x15, 0xb2, 0xf7, 0x0d, 0xf6, 0x93, 0x05, 0x84, 0x78, 0x83, + 0x73, 0x83, 0x74, 0x87, 0x7e, 0x87, 0x7f, 0x87, 0x7f, 0x89, 0x83, 0x87, + 0x81, 0x88, 0x83, 0x08, 0x25, 0x06, 0x0e, 0xc7, 0x90, 0x15, 0xb2, 0x7e, + 0xa7, 0x85, 0xaa, 0x8b, 0x93, 0x8b, 0x96, 0x8c, 0x99, 0x8c, 0x7c, 0x4b, + 0x80, 0x60, 0x84, 0x72, 0x92, 0x8e, 0x91, 0x8d, 0x8d, 0x8b, 0x08, 0x9a, + 0x90, 0x05, 0x8c, 0x8c, 0x90, 0x8d, 0x91, 0x8d, 0x98, 0xcb, 0x94, 0xb5, + 0x8f, 0x9d, 0xf1, 0xb9, 0xd2, 0xe3, 0x8b, 0xdc, 0x8b, 0xba, 0x75, 0xa8, + 0x43, 0xba, 0x08, 0xbd, 0xf7, 0x5e, 0x05, 0xa2, 0x8a, 0xa1, 0x7c, 0x9e, + 0x6f, 0x08, 0xb5, 0xbf, 0x05, 0x77, 0xa4, 0x75, 0x96, 0x6e, 0x8b, 0x85, + 0x8b, 0x82, 0x8b, 0x82, 0x8a, 0x93, 0xae, 0x8b, 0x8b, 0x9b, 0xc9, 0x08, + 0x61, 0x7e, 0x05, 0x89, 0x7d, 0x85, 0x6d, 0x82, 0x5b, 0x32, 0x6d, 0x49, + 0x3a, 0x8b, 0x3d, 0x8b, 0x70, 0x97, 0x71, 0xa0, 0x75, 0x97, 0x7f, 0x92, + 0x85, 0xaa, 0x72, 0x78, 0x41, 0x85, 0x72, 0x6e, 0xfb, 0x0f, 0x65, 0x8d, + 0x6f, 0x92, 0x6b, 0x9c, 0x08, 0x5c, 0x4d, 0x05, 0xf7, 0x6c, 0xf7, 0x5f, + 0x15, 0x94, 0xb0, 0x05, 0xba, 0x68, 0x95, 0x7c, 0x8b, 0x6a, 0x8b, 0x6c, + 0x7d, 0x6c, 0x72, 0x74, 0x79, 0x79, 0x7c, 0x84, 0x6a, 0x81, 0x08, 0xa4, + 0xf5, 0x99, 0xc7, 0x05, 0x8f, 0xf7, 0x20, 0x15, 0x6a, 0xa4, 0x7d, 0xa4, + 0x8b, 0xac, 0x8b, 0xa6, 0x99, 0xaa, 0xa0, 0x9e, 0x99, 0x98, 0x98, 0x91, + 0xa8, 0x94, 0x88, 0x7c, 0x88, 0x81, 0x8b, 0x88, 0x08, 0x76, 0x33, 0x05, + 0x85, 0x73, 0x86, 0x74, 0x85, 0x72, 0x08, 0x0e, 0xf8, 0x03, 0xf9, 0x0b, + 0xf7, 0xf1, 0x15, 0x5c, 0x8b, 0x56, 0x6f, 0x6d, 0x62, 0x69, 0x5c, 0x75, + 0x46, 0x8b, 0x4d, 0x8b, 0x42, 0xa5, 0x67, 0xbf, 0x8b, 0xbf, 0x8b, 0xb9, + 0xa8, 0xa9, 0xbe, 0xa8, 0xbd, 0xa0, 0xd9, 0x8b, 0xc8, 0x08, 0xc3, 0x72, + 0xaa, 0x5e, 0x1e, 0x6a, 0x6b, 0x15, 0xa8, 0x9c, 0x6f, 0x5b, 0xfb, 0x03, + 0x5e, 0xfb, 0x02, 0x5d, 0x6c, 0x77, 0xae, 0xc0, 0x1f, 0x8b, 0xb2, 0x94, + 0xbe, 0x98, 0xb2, 0x9d, 0xc1, 0xa3, 0xa5, 0xab, 0x8b, 0x08, 0xfc, 0x03, + 0xfb, 0xd1, 0x15, 0xa3, 0x8a, 0x91, 0x8a, 0x9a, 0x89, 0xe0, 0xf7, 0x29, + 0xf7, 0x5e, 0xf7, 0xdd, 0xd2, 0xf2, 0x7a, 0x8d, 0x84, 0x8c, 0x78, 0x8f, + 0x08, 0x20, 0xfb, 0x4c, 0xfb, 0x02, 0xfb, 0x46, 0xfb, 0x23, 0xfb, 0x72, + 0x08, 0xf7, 0x09, 0xf8, 0xdc, 0x15, 0x5c, 0x8b, 0x56, 0x6e, 0x6d, 0x62, + 0x69, 0x5d, 0x75, 0x45, 0x8b, 0x4d, 0x8b, 0x42, 0xa5, 0x67, 0xbf, 0x8b, + 0xbe, 0x8b, 0xb9, 0xa8, 0xa9, 0xbe, 0xa9, 0xbe, 0x9f, 0xd8, 0x8b, 0xc9, + 0x8b, 0xc3, 0x72, 0xaa, 0x5f, 0x8b, 0x08, 0x6a, 0x6b, 0x15, 0xa7, 0x9c, + 0x6f, 0x5c, 0xfb, 0x04, 0x5e, 0xfb, 0x03, 0x5d, 0x6d, 0x77, 0xae, 0xc0, + 0x1f, 0x8b, 0xb1, 0x94, 0xc0, 0x98, 0xb2, 0x9c, 0xc0, 0xa4, 0xa6, 0xab, + 0x8b, 0x08, 0x0e, 0xf8, 0x67, 0xf9, 0xd8, 0xf8, 0x87, 0x15, 0x84, 0x6c, + 0x7a, 0x5e, 0x81, 0x7a, 0x7d, 0x74, 0x87, 0x8a, 0x39, 0x88, 0x08, 0x93, + 0xac, 0x05, 0x70, 0x7f, 0x81, 0x85, 0x71, 0x7c, 0x82, 0x8a, 0x86, 0x8b, + 0x88, 0x8b, 0x08, 0x5c, 0x8c, 0x05, 0x38, 0x8b, 0x74, 0x6c, 0x55, 0xfb, + 0x4a, 0x08, 0xa2, 0x85, 0x05, 0xb2, 0xf7, 0x0b, 0xae, 0xb1, 0xd5, 0x8b, + 0x92, 0x8b, 0x97, 0x8b, 0x96, 0x8a, 0x7a, 0x36, 0x7b, 0x5c, 0x6f, 0x60, + 0x61, 0x49, 0x3d, 0x63, 0x32, 0x8b, 0x2e, 0x8b, 0x4c, 0xbb, 0x8b, 0xd2, + 0x8b, 0xaf, 0x9b, 0xa0, 0xc0, 0xac, 0x08, 0xf7, 0x1b, 0xe0, 0xd0, 0xb6, + 0x8e, 0x8e, 0xd2, 0xbc, 0xaa, 0xb4, 0x8b, 0xb9, 0x8b, 0x9c, 0x87, 0x96, + 0x7d, 0x9d, 0x08, 0x44, 0x61, 0x05, 0x94, 0x75, 0x8e, 0x80, 0x8b, 0x7d, + 0x8b, 0x62, 0x77, 0x73, 0x4d, 0x67, 0x08, 0x7f, 0xaf, 0x77, 0x9d, 0x6b, + 0x8b, 0x72, 0x8b, 0x6f, 0x80, 0x67, 0x71, 0x59, 0x69, 0x73, 0x72, 0x77, + 0x67, 0x6d, 0x53, 0x78, 0x49, 0x8b, 0x59, 0x8b, 0x36, 0xcc, 0x5a, 0xf7, + 0x05, 0x8b, 0xf6, 0x8b, 0xee, 0xb8, 0xdf, 0xe3, 0x08, 0xc2, 0xc4, 0x9d, + 0xae, 0xa9, 0xf7, 0x00, 0xd8, 0x8d, 0x98, 0x8d, 0x98, 0x97, 0x9d, 0x9b, + 0xa6, 0xcc, 0x9a, 0xcb, 0x08, 0x78, 0xa1, 0x05, 0xfd, 0x10, 0xfb, 0x99, + 0x15, 0x99, 0xbb, 0x90, 0x98, 0x98, 0xa0, 0xa0, 0xac, 0xa8, 0xa0, 0xa2, + 0x8b, 0xa2, 0x8b, 0x98, 0x7c, 0x92, 0x68, 0x08, 0xfb, 0x28, 0x35, 0x05, + 0x0e, 0x42, 0xf7, 0x94, 0xf7, 0xfa, 0x15, 0xe3, 0xf5, 0x99, 0xa3, 0x8b, + 0xb9, 0x8b, 0x98, 0x8a, 0x95, 0x86, 0xa0, 0x08, 0x79, 0x81, 0x05, 0x7c, + 0x83, 0x7c, 0x82, 0x7b, 0x83, 0x91, 0x71, 0x8d, 0x81, 0x8b, 0x7e, 0x8b, + 0x69, 0x7e, 0x73, 0x54, 0x45, 0x08, 0xa7, 0x83, 0x05, 0x0e, 0x56, 0xf8, + 0x28, 0xf9, 0x2b, 0x15, 0x88, 0x8d, 0x8a, 0x8c, 0x86, 0x8d, 0x08, 0x81, + 0x06, 0x44, 0x49, 0x5f, 0x4f, 0x5c, 0x2d, 0x48, 0xfb, 0x1a, 0x63, 0xfb, + 0x3a, 0x8b, 0xfb, 0x26, 0x8b, 0x4d, 0x95, 0x5f, 0xa6, 0x4e, 0xb1, 0x93, + 0x91, 0x8c, 0x9e, 0x93, 0x71, 0xd9, 0x83, 0xc0, 0x8b, 0xde, 0x8b, 0xf7, + 0x07, 0xa2, 0xf7, 0x0f, 0xb6, 0xf6, 0x08, 0xb6, 0xf7, 0x01, 0xb6, 0xcc, + 0xd9, 0xd5, 0x08, 0x83, 0x8f, 0x05, 0x0e, 0x2e, 0xa7, 0xfb, 0x37, 0x15, + 0x8c, 0x8a, 0x8d, 0x8a, 0x8e, 0x8a, 0x08, 0x95, 0x06, 0xd1, 0xcc, 0xb7, + 0xc7, 0xbb, 0xea, 0xce, 0xf7, 0x19, 0xb3, 0xf7, 0x3c, 0x8b, 0xf7, 0x24, + 0x8b, 0xc7, 0x81, 0xb8, 0x71, 0xca, 0x65, 0x83, 0x85, 0x89, 0x77, 0x84, + 0xa5, 0x3c, 0x93, 0x58, 0x8b, 0x39, 0x8b, 0xfb, 0x09, 0x74, 0xfb, 0x0f, + 0x60, 0x20, 0x08, 0x5f, 0xfb, 0x02, 0x60, 0x4a, 0x3e, 0x42, 0x8e, 0x8a, + 0x8d, 0x89, 0x8c, 0x8b, 0x08, 0x90, 0x88, 0x05, 0x0e, 0xf6, 0xf7, 0x70, + 0xf8, 0x6b, 0x15, 0x9e, 0x6d, 0xed, 0xc2, 0x91, 0x85, 0x64, 0xfb, 0x05, + 0xb7, 0x8b, 0xa6, 0xf7, 0x04, 0x96, 0x8f, 0xc7, 0x45, 0xad, 0xa8, 0x41, + 0xce, 0x8e, 0x98, 0xf2, 0xba, 0x7d, 0xac, 0x2d, 0x59, 0x84, 0x92, 0x05, + 0xae, 0xf7, 0x00, 0x60, 0x8b, 0x72, 0xfb, 0x01, 0x82, 0x88, 0x4f, 0xcf, + 0x6b, 0x6d, 0xd0, 0x4d, 0x84, 0x75, 0x22, 0x5b, 0x05, 0x0e, 0xf7, 0x63, + 0xf7, 0xe3, 0xf7, 0x54, 0x15, 0xf7, 0x46, 0xc1, 0xfb, 0x46, 0xf7, 0x46, + 0x55, 0xfb, 0x46, 0xfb, 0x46, 0x55, 0xf7, 0x46, 0xfb, 0x46, 0xc1, 0xf7, + 0x46, 0x06, 0x0e, 0x2e, 0xc4, 0x29, 0x15, 0xf7, 0x09, 0xf0, 0x9d, 0xa9, + 0xa2, 0xf7, 0x20, 0x67, 0x80, 0x8a, 0x8a, 0x68, 0x81, 0x82, 0xfb, 0x04, + 0x6f, 0x51, 0x3f, 0x47, 0x08, 0xa6, 0x80, 0x05, 0x0e, 0x6a, 0xf7, 0x10, + 0xf7, 0x41, 0x15, 0xe3, 0x8d, 0x05, 0x94, 0x8b, 0x93, 0x8b, 0xa5, 0x89, + 0x99, 0xa2, 0x9a, 0xa0, 0x9b, 0x9e, 0x08, 0x30, 0x8c, 0x05, 0x7d, 0x8b, + 0x82, 0x8b, 0x74, 0x8a, 0x7d, 0x7d, 0x7a, 0x75, 0x7a, 0x70, 0x08, 0x94, + 0x06, 0x0e, 0x2e, 0xf7, 0x1a, 0xe4, 0x15, 0x70, 0x76, 0x05, 0x93, 0x75, + 0x9f, 0x6b, 0x9e, 0x74, 0xb1, 0xa7, 0x94, 0x92, 0xa6, 0xa7, 0x7f, 0x9c, + 0x81, 0x9b, 0x8a, 0x8c, 0x84, 0x96, 0x86, 0x93, 0x7f, 0xa0, 0x88, 0x88, + 0x86, 0x87, 0x85, 0x86, 0x83, 0x85, 0x83, 0x84, 0x83, 0x84, 0x08, 0x82, + 0x84, 0x05, 0x0e, 0xa6, 0x9d, 0xfb, 0x3d, 0x15, 0x94, 0x8b, 0x8c, 0x8b, + 0x96, 0x8a, 0xf7, 0xe0, 0xf8, 0xd5, 0xf7, 0x16, 0xf7, 0x72, 0xad, 0xb9, + 0x08, 0x85, 0x84, 0x8c, 0x8b, 0x1f, 0x7a, 0x8c, 0x05, 0x89, 0x8b, 0x87, + 0x8c, 0x84, 0x8c, 0x4f, 0xfb, 0x03, 0x80, 0x78, 0xfb, 0xcc, 0xfc, 0xa6, + 0x08, 0xfb, 0x07, 0xfb, 0x4e, 0xa3, 0x89, 0x05, 0x0e, 0xf8, 0x10, 0xf8, + 0xd4, 0x15, 0x43, 0x8b, 0x3a, 0x59, 0x5a, 0x41, 0x5c, 0x43, 0x66, 0xfb, + 0x15, 0x8b, 0x2d, 0x8b, 0xfb, 0x00, 0xb3, 0x53, 0xd7, 0x8b, 0xe1, 0x8b, + 0xd9, 0xc0, 0xb9, 0xe5, 0xb3, 0xd7, 0xa8, 0xf7, 0x0c, 0x8b, 0xdf, 0x8b, + 0xf5, 0x66, 0xc1, 0x43, 0x8b, 0x08, 0x5a, 0x61, 0x15, 0xb8, 0xa5, 0x56, + 0x2b, 0x1f, 0x8b, 0x3b, 0x76, 0x24, 0x6b, 0x3e, 0x72, 0x4e, 0x6a, 0x69, + 0x69, 0x8b, 0x5f, 0x8b, 0x6b, 0xc4, 0x8b, 0xdb, 0x8b, 0xc2, 0x9e, 0xf7, + 0x04, 0x9f, 0xcc, 0xa6, 0xe5, 0xb1, 0xb8, 0xb9, 0x8b, 0x08, 0x0e, 0xdd, + 0x16, 0xca, 0x8b, 0xf7, 0x01, 0x8c, 0xf7, 0x07, 0x8a, 0xb4, 0x8b, 0xa3, + 0xa6, 0x05, 0x6d, 0x8c, 0x55, 0x91, 0x78, 0x8f, 0x7b, 0x8f, 0x81, 0x96, + 0x8b, 0x9a, 0x8b, 0x96, 0x8d, 0x9a, 0x90, 0x9b, 0x8e, 0x97, 0x95, 0xb9, + 0x9a, 0xd1, 0xb6, 0xf7, 0x51, 0xa2, 0xea, 0x9b, 0xc7, 0x08, 0x69, 0x79, + 0x05, 0x46, 0x66, 0x89, 0x8a, 0x6b, 0x7c, 0x78, 0x82, 0x6a, 0x7d, 0x5d, + 0x76, 0x08, 0xa9, 0x7c, 0x05, 0xa3, 0x93, 0x97, 0x90, 0x9d, 0x92, 0x08, + 0xa9, 0x97, 0x05, 0x8f, 0x8d, 0x94, 0x8e, 0x9a, 0x90, 0x08, 0x2c, 0xfc, + 0x2d, 0x05, 0x81, 0x61, 0x8a, 0x89, 0x6b, 0x87, 0x61, 0x86, 0x70, 0x88, + 0x80, 0x89, 0x08, 0x6e, 0x70, 0x05, 0x0e, 0xbe, 0x7a, 0x15, 0xb6, 0xba, + 0x97, 0x93, 0xa4, 0x8b, 0x95, 0x8b, 0x98, 0x89, 0x9b, 0x87, 0x08, 0xd5, + 0x7a, 0xed, 0x79, 0x9b, 0x8b, 0x93, 0x8b, 0x90, 0x8c, 0x95, 0x8f, 0x08, + 0xe3, 0xf7, 0x18, 0x83, 0xa2, 0x05, 0x4b, 0x3a, 0x84, 0x84, 0x70, 0x8b, + 0x86, 0x8b, 0x84, 0x8c, 0x82, 0x8d, 0x46, 0x97, 0x4f, 0x94, 0x59, 0x93, + 0x08, 0xf7, 0x0f, 0xf7, 0x06, 0xe4, 0xde, 0xbd, 0xba, 0x05, 0xa8, 0xb7, + 0x97, 0xad, 0x8b, 0xb7, 0x8b, 0xcb, 0x62, 0xb4, 0x4d, 0x8b, 0x58, 0x8b, + 0x56, 0x78, 0x62, 0x69, 0x67, 0x6f, 0x78, 0x67, 0x8b, 0x62, 0x8b, 0x83, + 0x8c, 0x86, 0x8d, 0x80, 0x08, 0xd2, 0x83, 0x05, 0x82, 0xa6, 0x88, 0x99, + 0x8b, 0x9d, 0x08, 0xc2, 0xac, 0xaf, 0xbd, 0xba, 0xad, 0x62, 0x52, 0x1e, + 0x8b, 0x6c, 0x81, 0x68, 0x7b, 0x72, 0x76, 0x69, 0x72, 0x70, 0x3e, 0x43, + 0xfb, 0x15, 0xfb, 0x0d, 0x7c, 0x7c, 0x5a, 0x4d, 0x08, 0x8f, 0x6e, 0x05, + 0x0e, 0xaf, 0xa5, 0x15, 0xb5, 0x74, 0xac, 0x82, 0xb6, 0x8b, 0xf7, 0x23, + 0x8b, 0xf7, 0x28, 0xf7, 0x1c, 0x8b, 0xf7, 0x16, 0x8b, 0xaa, 0x7d, 0xa7, + 0x74, 0x9b, 0x7b, 0x96, 0x7c, 0x90, 0x68, 0x90, 0x08, 0xd9, 0xc5, 0x05, + 0xa6, 0xac, 0x96, 0xa5, 0x8b, 0xa9, 0x8b, 0xb6, 0x69, 0xa8, 0x59, 0x8b, + 0x7d, 0x8b, 0x7f, 0x89, 0x71, 0x84, 0x7f, 0x84, 0x7f, 0x84, 0x87, 0x89, + 0x08, 0x61, 0x6e, 0x05, 0x87, 0x88, 0x7f, 0x83, 0x7e, 0x82, 0x08, 0x72, + 0x07, 0xb1, 0xa5, 0xb3, 0x9b, 0xa3, 0x8b, 0xab, 0x8b, 0xa3, 0x72, 0x8b, + 0x69, 0x8b, 0x4e, 0x50, 0x5b, 0xfb, 0x1f, 0x56, 0x08, 0x88, 0x71, 0x05, + 0xda, 0xa9, 0x8f, 0x8c, 0xa0, 0x8b, 0x08, 0xbc, 0xae, 0x63, 0x53, 0x2f, + 0x45, 0x3f, 0x35, 0x1f, 0x67, 0x8b, 0x78, 0x91, 0x40, 0xac, 0x08, 0x5d, + 0x58, 0x05, 0x0e, 0xf7, 0x87, 0x7d, 0x15, 0x94, 0x84, 0x8d, 0x89, 0x95, + 0x89, 0xa7, 0x97, 0xac, 0x97, 0xa1, 0x91, 0x08, 0x8d, 0x92, 0x05, 0x82, + 0x9a, 0x89, 0x93, 0x8b, 0x99, 0x8b, 0xa0, 0x8f, 0xa1, 0x98, 0xc7, 0x08, + 0x9d, 0x8b, 0xa3, 0x8b, 0x9b, 0x8b, 0xb0, 0xbf, 0x05, 0x7b, 0x8a, 0x7f, + 0x8b, 0x83, 0x8b, 0x86, 0x8b, 0x8b, 0x8b, 0x61, 0x8c, 0x95, 0xb5, 0x9c, + 0xd8, 0xa4, 0xf7, 0x03, 0x9f, 0xe7, 0x8e, 0x98, 0x98, 0xb9, 0x79, 0x83, + 0x74, 0x80, 0x6e, 0x7c, 0x83, 0x81, 0x83, 0x82, 0x83, 0x82, 0x08, 0x3d, + 0x33, 0x05, 0x73, 0x70, 0x6f, 0x6a, 0x6c, 0x64, 0x08, 0x38, 0x25, 0x05, + 0x70, 0x69, 0x88, 0x86, 0x79, 0x63, 0xa5, 0x8a, 0xf7, 0x15, 0x88, 0xa5, + 0x8b, 0x91, 0x8b, 0x95, 0x8b, 0x9e, 0x8c, 0x08, 0x61, 0xfb, 0x3a, 0x05, + 0xa7, 0xf7, 0x6e, 0x15, 0x5a, 0x8c, 0x05, 0x82, 0x8b, 0x78, 0x8c, 0x74, + 0x8c, 0x08, 0x6b, 0x8c, 0x05, 0xb0, 0xbf, 0x9c, 0x9f, 0xf7, 0x40, 0xf7, + 0x64, 0x08, 0x48, 0xfb, 0xb0, 0x70, 0x8b, 0x05, 0x0e, 0xce, 0x95, 0x15, + 0xad, 0x7f, 0xaa, 0x85, 0xac, 0x8b, 0xc6, 0x8b, 0xc6, 0xa5, 0xca, 0xc0, + 0xcb, 0xc1, 0xab, 0xc3, 0x8b, 0xc6, 0x8b, 0xdb, 0x53, 0xbd, 0x33, 0x8b, + 0x77, 0x8b, 0x7d, 0x89, 0x6f, 0x85, 0x9b, 0xad, 0x94, 0xa0, 0x90, 0x98, + 0x08, 0x91, 0x98, 0x90, 0x97, 0x90, 0x98, 0x8c, 0x8e, 0x91, 0x99, 0x8e, + 0x92, 0xab, 0x88, 0x99, 0x8a, 0xa5, 0x8b, 0xcd, 0x8b, 0xa4, 0x93, 0xaa, + 0xab, 0xa1, 0xa1, 0xaa, 0xad, 0x9c, 0x9e, 0x08, 0x94, 0xb0, 0x05, 0x45, + 0x4a, 0x6c, 0x7c, 0x45, 0x8b, 0x6c, 0x8b, 0x60, 0x8e, 0x5d, 0x91, 0x74, + 0x43, 0x84, 0x79, 0x41, 0xfb, 0x4e, 0x08, 0x95, 0x81, 0x05, 0xac, 0x9d, + 0xa1, 0x92, 0xa5, 0x8b, 0x08, 0xc6, 0xb8, 0x5e, 0x50, 0x2e, 0x4a, 0x48, + 0x32, 0x1f, 0x6b, 0x8b, 0x73, 0x91, 0x64, 0x9e, 0x08, 0x5a, 0x50, 0x05, + 0x0e, 0xf8, 0xa8, 0xf8, 0xcf, 0x15, 0x6f, 0x96, 0x7d, 0x8e, 0x73, 0x8b, + 0x3b, 0x8b, 0x3c, 0x63, 0x44, 0x40, 0x37, 0x31, 0x52, 0xfb, 0x1a, 0x8b, + 0xfb, 0x00, 0x08, 0x2f, 0xb7, 0x55, 0xd5, 0xf7, 0x12, 0xf7, 0x0b, 0xed, + 0xf3, 0xd2, 0x5a, 0xbc, 0x46, 0x1e, 0x73, 0x8b, 0x77, 0x87, 0x70, 0x80, + 0x08, 0x6e, 0x7a, 0x6e, 0x79, 0x05, 0x86, 0x88, 0x80, 0x85, 0x7b, 0x82, + 0x9b, 0xd9, 0x9c, 0xb9, 0xa7, 0xbb, 0xb9, 0xd8, 0xcd, 0xbb, 0xc8, 0x8b, + 0xa6, 0x8b, 0xa1, 0x83, 0xa6, 0x77, 0x08, 0xb6, 0xc3, 0x05, 0xfb, 0xf8, + 0xfb, 0xfb, 0x15, 0xba, 0xac, 0xa8, 0x97, 0xaf, 0x8b, 0x08, 0xc1, 0xb2, + 0x5f, 0x4f, 0x4a, 0x58, 0x52, 0x51, 0x4d, 0x65, 0xbf, 0xdf, 0x1f, 0x8b, + 0x99, 0x8c, 0x96, 0x8e, 0x9f, 0x08, 0x0e, 0xf7, 0x97, 0x95, 0x15, 0x86, + 0xab, 0x89, 0x9a, 0x8b, 0x9e, 0x8b, 0xdd, 0xa6, 0xba, 0xf7, 0x4b, 0xf7, + 0x84, 0xb6, 0xc4, 0x90, 0x93, 0xaa, 0xba, 0x58, 0x87, 0x53, 0x8a, 0x46, + 0x8b, 0xfb, 0x01, 0x8b, 0x8a, 0x8b, 0x86, 0xc6, 0x08, 0x7c, 0x8b, 0x81, + 0x71, 0x05, 0x78, 0x57, 0x8a, 0x8a, 0x7e, 0x63, 0x08, 0x8e, 0x85, 0x05, + 0xad, 0x89, 0x9b, 0x8a, 0xa5, 0x8b, 0xbd, 0x8b, 0xcb, 0x8e, 0xdd, 0x91, + 0xfb, 0x56, 0xfb, 0x83, 0x62, 0x53, 0x4f, 0xfb, 0x00, 0x85, 0x76, 0x8a, + 0x80, 0x8b, 0x78, 0x8b, 0x7c, 0x8c, 0x7e, 0x8e, 0x6f, 0x08, 0xe5, 0xa7, + 0x05, 0x0e, 0xf7, 0x8f, 0xf7, 0xbe, 0x15, 0x63, 0x72, 0x8a, 0x8a, 0x45, + 0x64, 0x5e, 0x5e, 0x77, 0x5f, 0x8b, 0x57, 0x8b, 0x4f, 0xb8, 0x61, 0xca, + 0x8b, 0xbd, 0x8b, 0xd2, 0xa3, 0xbd, 0xad, 0xbe, 0xae, 0xac, 0xc5, 0x8b, + 0xc3, 0x8b, 0x9f, 0x85, 0x9d, 0x7f, 0x9d, 0x08, 0x81, 0x9b, 0x88, 0x8d, + 0x5e, 0xaf, 0x88, 0x8d, 0x82, 0x93, 0x81, 0x93, 0xb2, 0xa1, 0x95, 0x90, + 0xbf, 0xaf, 0x08, 0xb3, 0xb7, 0x98, 0xa6, 0x8b, 0xae, 0x08, 0xb9, 0x67, + 0xab, 0x57, 0x21, 0x29, 0x3b, 0x35, 0x1e, 0x8b, 0x66, 0x98, 0x6e, 0xaf, + 0x61, 0x08, 0x9f, 0x79, 0x15, 0xa9, 0x6e, 0x8f, 0x87, 0x95, 0x80, 0xa5, + 0x71, 0x95, 0x73, 0x8b, 0x6a, 0x08, 0x4b, 0x53, 0x4d, 0x51, 0x5d, 0x6e, + 0xb1, 0xc6, 0x1e, 0x8b, 0xc7, 0xa9, 0xbc, 0xc3, 0xad, 0x08, 0x91, 0x8e, + 0x91, 0x8e, 0x96, 0x92, 0x08, 0xbc, 0xc8, 0x15, 0x70, 0xa9, 0x7d, 0xaa, + 0x8b, 0xad, 0x08, 0xc3, 0xb3, 0xbb, 0xb9, 0x1e, 0xaa, 0xa0, 0x71, 0x67, + 0x1f, 0x8b, 0x54, 0x67, 0x59, 0x4e, 0x6b, 0x08, 0x0e, 0xb5, 0x9a, 0x15, + 0xaf, 0x7a, 0xa5, 0x85, 0xad, 0x8b, 0xe5, 0x8b, 0xf6, 0xca, 0xc8, 0xe4, + 0xbb, 0xd0, 0xaf, 0xf7, 0x0d, 0x8b, 0xe7, 0x8b, 0xea, 0x64, 0xc2, 0x48, + 0x8b, 0x59, 0x8b, 0x4e, 0x74, 0x57, 0x65, 0x52, 0x60, 0x6d, 0x57, 0x8b, + 0x53, 0x08, 0x43, 0xbb, 0x59, 0xce, 0x1e, 0xaf, 0x8b, 0xa0, 0x94, 0xef, + 0xc8, 0x7e, 0x3f, 0x80, 0x65, 0x77, 0x63, 0x63, 0x3e, 0x51, 0x5e, 0x4e, + 0x8b, 0x6c, 0x8b, 0x70, 0x93, 0x5e, 0xa3, 0x08, 0x5b, 0x56, 0x05, 0xf7, + 0xfa, 0xf7, 0xe2, 0x15, 0x63, 0x6b, 0x62, 0x79, 0x69, 0x8b, 0x08, 0x5b, + 0x67, 0xb7, 0xc6, 0xd5, 0xb7, 0xc0, 0xca, 0xc5, 0xb0, 0x59, 0x3c, 0x1f, + 0x8b, 0x7f, 0x8a, 0x7d, 0x89, 0x72, 0x08, 0x0e, 0x56, 0xf7, 0x6b, 0xf7, + 0xa4, 0x15, 0x91, 0x90, 0x90, 0x8f, 0x8e, 0x8d, 0x9d, 0x9a, 0x96, 0x94, + 0x8f, 0x8e, 0x08, 0xa6, 0xa0, 0x05, 0x82, 0xa3, 0x79, 0xa8, 0x77, 0xa3, + 0x69, 0x74, 0x7c, 0x7f, 0x6f, 0x70, 0x8f, 0x85, 0x91, 0x82, 0x8c, 0x8a, + 0x90, 0x85, 0x8f, 0x85, 0x8f, 0x85, 0x8c, 0x8a, 0x91, 0x81, 0x92, 0x82, + 0x08, 0x97, 0x77, 0x05, 0xfb, 0x09, 0xfb, 0x60, 0x15, 0x93, 0x75, 0x9f, + 0x6b, 0x9e, 0x74, 0xb1, 0xa6, 0x95, 0x93, 0xa8, 0xa7, 0x88, 0x90, 0x87, + 0x90, 0x87, 0x90, 0x88, 0x8f, 0x89, 0x8f, 0x88, 0x8e, 0x86, 0x93, 0x8a, + 0x8c, 0x86, 0x92, 0x08, 0x77, 0xab, 0x05, 0x84, 0x85, 0x86, 0x87, 0x89, + 0x89, 0x79, 0x7d, 0x80, 0x82, 0x87, 0x87, 0x83, 0x85, 0x7e, 0x81, 0x85, + 0x86, 0x08, 0x0e, 0x42, 0xf7, 0xa9, 0xf7, 0xdf, 0x15, 0x82, 0xa3, 0x79, + 0xa9, 0x77, 0xa2, 0x6a, 0x74, 0x7e, 0x80, 0x6f, 0x6f, 0x90, 0x84, 0x8e, + 0x86, 0x8e, 0x87, 0x08, 0x9c, 0x71, 0x05, 0x8e, 0x85, 0x8b, 0x8b, 0x9b, + 0x71, 0x8f, 0x8f, 0x90, 0x8e, 0x90, 0x8f, 0x9d, 0x9a, 0x96, 0x94, 0x8f, + 0x8e, 0x94, 0x93, 0x8f, 0x8e, 0x99, 0x95, 0x08, 0xfb, 0x71, 0xfc, 0x41, + 0x15, 0xf7, 0x09, 0xf0, 0x9d, 0xa9, 0xa2, 0xf7, 0x20, 0x80, 0x87, 0x80, + 0x88, 0x80, 0x88, 0x81, 0x88, 0x7a, 0x85, 0x7f, 0x88, 0x82, 0xfb, 0x04, + 0x6f, 0x51, 0x3f, 0x47, 0x08, 0xa6, 0x80, 0x05, 0x0e, 0xf7, 0x63, 0xf8, + 0xc1, 0xc2, 0x15, 0xfc, 0x03, 0xf7, 0x3e, 0xf8, 0x03, 0xf7, 0x3f, 0x8b, + 0xc0, 0xfc, 0x49, 0xfb, 0x5c, 0x8b, 0x5c, 0xf8, 0x49, 0xfb, 0x5c, 0x8b, + 0xc0, 0x05, 0x0e, 0xf7, 0x63, 0xf8, 0x9a, 0xf7, 0x36, 0x15, 0xfc, 0x2e, + 0x55, 0xf8, 0x2e, 0xc1, 0x06, 0xf7, 0x3c, 0x04, 0xfc, 0x2e, 0x55, 0xf8, + 0x2e, 0xc1, 0x06, 0x0e, 0xf7, 0x63, 0xf7, 0x0b, 0xc2, 0x15, 0x8b, 0x56, + 0xf8, 0x49, 0xf7, 0x5c, 0x8b, 0xba, 0xfc, 0x49, 0xf7, 0x5c, 0x8b, 0x56, + 0xf8, 0x02, 0xfb, 0x3f, 0xfc, 0x02, 0xfb, 0x3e, 0x05, 0x0e, 0xce, 0xf7, + 0x52, 0xf7, 0x08, 0x15, 0x79, 0x7c, 0x80, 0x82, 0x87, 0x88, 0x08, 0x70, + 0x76, 0x05, 0x94, 0x74, 0x9e, 0x6c, 0x9e, 0x74, 0xaf, 0xa5, 0x95, 0x93, + 0xa7, 0xa8, 0x88, 0x90, 0x87, 0x90, 0x87, 0x90, 0x08, 0x7a, 0xa6, 0x05, + 0x85, 0x95, 0x83, 0x97, 0x86, 0x95, 0x08, 0x7d, 0x7f, 0x05, 0xa8, 0xc6, + 0x15, 0x92, 0xdf, 0x9b, 0xad, 0xac, 0x8a, 0xd1, 0x91, 0x9e, 0x90, 0xb0, + 0xa1, 0xc5, 0xac, 0xb1, 0xcc, 0x8b, 0xcd, 0x8b, 0xc4, 0x5e, 0xaf, 0x43, + 0x8b, 0x4a, 0x8b, 0x5f, 0x7b, 0x5e, 0x62, 0x92, 0x73, 0x8f, 0x82, 0x95, + 0x6f, 0x08, 0xa9, 0xc3, 0xb2, 0xa9, 0xb6, 0x8b, 0xac, 0x8b, 0xa2, 0x70, + 0x8b, 0x64, 0x8b, 0x68, 0x7c, 0x66, 0x72, 0x6d, 0x6e, 0x6a, 0x6a, 0x7c, + 0x5c, 0x8b, 0x7d, 0x8b, 0x81, 0x8c, 0x75, 0x90, 0x08, 0x79, 0x7c, 0x05, + 0x82, 0x42, 0x89, 0x7c, 0x85, 0x42, 0x08, 0xad, 0x96, 0x05, 0x0e, 0xf8, + 0x17, 0xf8, 0xca, 0xc2, 0x15, 0x34, 0x6b, 0x29, 0x78, 0x37, 0x8b, 0x36, + 0x8b, 0x5f, 0xb8, 0x8b, 0xdf, 0x8b, 0xcf, 0x98, 0xd6, 0xa1, 0xcc, 0xab, + 0xea, 0xbb, 0xc2, 0xd6, 0xab, 0xc4, 0xa2, 0xd5, 0x99, 0xd4, 0x8b, 0xe6, + 0x8b, 0xb9, 0x67, 0x8b, 0x41, 0x08, 0x8b, 0x5d, 0x7b, 0x4b, 0x6c, 0x43, + 0x6f, 0x48, 0x67, 0x67, 0x64, 0x8b, 0x80, 0x8b, 0x86, 0x92, 0x8b, 0x9a, + 0x8b, 0x9f, 0xa0, 0xf4, 0xa8, 0xf7, 0x0b, 0x9a, 0x9d, 0x8e, 0x8e, 0x95, + 0x96, 0x62, 0x94, 0x6a, 0x8f, 0x65, 0x8b, 0x08, 0x65, 0x8b, 0x7d, 0x87, + 0x72, 0x7c, 0x6d, 0x77, 0x60, 0x6c, 0x83, 0x82, 0x68, 0x66, 0x68, 0xfb, + 0x09, 0x8b, 0x3d, 0x8b, 0x60, 0x9b, 0x6e, 0xa2, 0x8b, 0x9f, 0x8b, 0xa5, + 0x9b, 0xf7, 0x07, 0xdf, 0x88, 0x76, 0x84, 0x56, 0x8b, 0x85, 0x08, 0x7e, + 0x90, 0x85, 0x96, 0x1e, 0xb9, 0x8b, 0xef, 0xca, 0xb5, 0xc2, 0xc8, 0xdd, + 0xb2, 0xef, 0x8b, 0xd8, 0x8b, 0xbb, 0x73, 0xb2, 0x63, 0x9b, 0x6d, 0x97, + 0x64, 0x91, 0x53, 0x8b, 0xfb, 0x38, 0x8b, 0xfb, 0x13, 0x5a, 0x41, 0x2f, + 0x4d, 0x3d, 0x5c, 0xfb, 0x2b, 0x8b, 0xfb, 0x0c, 0x08, 0x8b, 0x5c, 0x9a, + 0x64, 0xa5, 0x76, 0xa2, 0x78, 0xab, 0x84, 0xc4, 0x8b, 0xf7, 0x06, 0x8b, + 0xe6, 0x9e, 0xf7, 0x09, 0xba, 0x08, 0x80, 0x9f, 0x05, 0x32, 0xf7, 0x41, + 0x15, 0x48, 0x59, 0x6d, 0x79, 0x7a, 0x8b, 0x7b, 0x8b, 0x82, 0x9d, 0x8b, + 0xaa, 0x8b, 0xba, 0x98, 0xc4, 0xa1, 0xbf, 0xa0, 0xbb, 0x9f, 0xa0, 0xa8, + 0x8b, 0x9a, 0x8b, 0xb2, 0x86, 0xa4, 0x85, 0x7d, 0x52, 0x86, 0x78, 0x86, + 0x79, 0x08, 0x8a, 0x84, 0x85, 0x71, 0x84, 0x67, 0x88, 0x80, 0x89, 0x80, + 0x89, 0x81, 0x08, 0x0e, 0xf7, 0xc7, 0xa2, 0x94, 0x15, 0xa2, 0x84, 0x97, + 0x89, 0x9d, 0x8b, 0xcf, 0x8b, 0xb9, 0xae, 0xf7, 0x18, 0xf7, 0x2b, 0xda, + 0x8b, 0xc6, 0x8a, 0xb2, 0x88, 0x89, 0x7f, 0x89, 0x7f, 0x8a, 0x7f, 0x89, + 0x7e, 0x88, 0x78, 0x88, 0x76, 0x89, 0x78, 0x88, 0x78, 0x8a, 0x88, 0x08, + 0x88, 0x7a, 0x89, 0x7b, 0x8b, 0x81, 0x08, 0x7f, 0x95, 0x81, 0x98, 0x1e, + 0x92, 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0xbb, 0x94, 0xbb, 0x94, 0xbb, 0x93, + 0x08, 0x9b, 0xa3, 0x05, 0x81, 0x8a, 0x81, 0x8a, 0x88, 0x8b, 0x6c, 0x88, + 0x86, 0x8b, 0x7c, 0x8b, 0x64, 0x8b, 0x7f, 0x95, 0x8b, 0xae, 0x8b, 0xca, + 0xb3, 0xf7, 0xb0, 0xaa, 0xf7, 0x30, 0x08, 0x7d, 0x95, 0x05, 0x87, 0x87, + 0x87, 0x87, 0x88, 0x87, 0x7b, 0x7b, 0x82, 0x87, 0x7a, 0x8b, 0x7f, 0x8b, + 0x87, 0x8b, 0x62, 0x92, 0x5d, 0x92, 0x72, 0x8e, 0x77, 0x8b, 0x5d, 0x8b, + 0x5b, 0x74, 0x5c, 0x5d, 0x56, 0x58, 0x74, 0x5e, 0x8b, 0x56, 0x08, 0x8b, + 0x74, 0x8e, 0x7b, 0x96, 0x6e, 0x08, 0xd5, 0xb3, 0x05, 0x7b, 0xba, 0x86, + 0xa2, 0x8b, 0xa2, 0x8b, 0xc4, 0xb6, 0xad, 0xd4, 0x8b, 0x96, 0x8b, 0x97, + 0x8a, 0x99, 0x8a, 0x08, 0xb3, 0x86, 0x9a, 0x8a, 0x05, 0x9c, 0x89, 0x93, + 0x8b, 0xa6, 0x89, 0x08, 0xfb, 0x41, 0xfb, 0x74, 0x05, 0x61, 0x55, 0x49, + 0x3e, 0x71, 0x72, 0x08, 0x63, 0x64, 0x6d, 0x7d, 0x5d, 0x8b, 0x7a, 0x8b, + 0x82, 0x8c, 0x79, 0x91, 0x08, 0x65, 0x45, 0x05, 0xf7, 0xde, 0xf7, 0x6e, + 0x15, 0xf7, 0x55, 0xf7, 0x91, 0x62, 0xfb, 0x91, 0xfb, 0x2c, 0x8b, 0x05, + 0x0e, 0xf7, 0xb3, 0xe5, 0x8c, 0x15, 0xa5, 0x8b, 0x8c, 0x8b, 0xaa, 0x8a, + 0x08, 0xad, 0x8b, 0xae, 0x8b, 0x05, 0xd1, 0x89, 0x8b, 0x8b, 0x9b, 0x8b, + 0xcf, 0x8b, 0xbf, 0x98, 0xce, 0xad, 0xe5, 0xb8, 0xb7, 0xc5, 0x8b, 0xd3, + 0x8b, 0xaa, 0x7c, 0xa8, 0x72, 0x9e, 0x76, 0x9b, 0x75, 0x91, 0x5b, 0x90, + 0x08, 0xee, 0xb8, 0xbd, 0xc2, 0x8b, 0xcb, 0x08, 0xcd, 0x55, 0xa8, 0xfb, + 0x0f, 0x1e, 0x7b, 0x8b, 0x93, 0xaa, 0x3a, 0x68, 0x05, 0x35, 0x7e, 0x5b, + 0x7c, 0x5d, 0x70, 0x3b, 0x5a, 0x62, 0x45, 0x8b, 0x33, 0x8b, 0x77, 0x8d, + 0x7c, 0x90, 0x6d, 0x08, 0xdb, 0xb0, 0x05, 0x82, 0xb7, 0x8a, 0x96, 0x8b, + 0x9e, 0x8b, 0xcf, 0xa0, 0xb5, 0xbe, 0xac, 0xb3, 0xa5, 0xb3, 0x97, 0xca, + 0x8f, 0x08, 0x41, 0xfb, 0xbc, 0x05, 0x61, 0xfb, 0x41, 0x7a, 0x75, 0x2a, + 0x81, 0x08, 0x5c, 0x5b, 0x05, 0xf7, 0xb2, 0xf7, 0xb7, 0x15, 0x9f, 0x8d, + 0x94, 0x8b, 0x95, 0x8b, 0xd8, 0x8b, 0xb8, 0x68, 0x8b, 0x4d, 0x8b, 0x65, + 0x7b, 0x5f, 0x72, 0x6f, 0x70, 0x6c, 0x63, 0x7b, 0x59, 0x8b, 0x72, 0x8b, + 0x6e, 0x8e, 0x2d, 0x95, 0xed, 0xe2, 0x9b, 0xa3, 0xa0, 0xe5, 0x08, 0x95, + 0xb1, 0x05, 0xcd, 0xf7, 0x9d, 0x15, 0xbc, 0x8a, 0x96, 0x89, 0x99, 0x84, + 0xa3, 0x7f, 0x9a, 0x6e, 0x8b, 0x6b, 0x8b, 0x5c, 0x74, 0x5b, 0x68, 0x71, + 0x6d, 0x74, 0x6d, 0x82, 0x55, 0x8a, 0x08, 0xc6, 0xf7, 0x81, 0x05, 0x0e, + 0xf7, 0x63, 0xf8, 0xa5, 0xca, 0x15, 0x2f, 0x4c, 0x47, 0x71, 0x45, 0x8b, + 0x08, 0x3c, 0x59, 0xc7, 0xea, 0xf7, 0x64, 0xf7, 0x27, 0xf7, 0x63, 0xf7, + 0x28, 0x1f, 0xc7, 0x8b, 0xa9, 0x66, 0x91, 0x3c, 0x08, 0xd5, 0xca, 0x05, + 0x82, 0xd0, 0x67, 0xaa, 0x43, 0x8b, 0x34, 0x8b, 0x26, 0x58, 0x33, 0x33, + 0x2a, 0x2a, 0x52, 0xfb, 0x19, 0x8b, 0xfb, 0x16, 0x8b, 0x24, 0xc4, 0x4d, + 0xeb, 0x8b, 0xe1, 0x8b, 0xf7, 0x01, 0xb4, 0xe1, 0xcc, 0x08, 0x92, 0xa9, + 0x05, 0x0e, 0xf8, 0x17, 0xe1, 0x16, 0xf7, 0x13, 0x06, 0xf7, 0x39, 0x8b, + 0xb3, 0x8e, 0xc0, 0x9e, 0xdb, 0xa6, 0xdd, 0xbf, 0xb2, 0xbb, 0xbe, 0xca, + 0xaf, 0xf4, 0x8b, 0xe0, 0x8b, 0xd0, 0x67, 0xbf, 0x47, 0xa9, 0x60, 0x9e, + 0x58, 0x93, 0x2a, 0x91, 0x08, 0x92, 0xa7, 0x43, 0x6d, 0x05, 0x39, 0x7d, + 0x57, 0x79, 0x56, 0x69, 0x36, 0x54, 0x62, 0x48, 0x8b, 0x36, 0x8b, 0x78, + 0x8c, 0x7f, 0x91, 0x71, 0x08, 0xdd, 0xb0, 0x05, 0x85, 0xa5, 0x8a, 0x97, + 0x8b, 0x9d, 0x8b, 0xf7, 0x0b, 0xd5, 0xd1, 0xf7, 0x20, 0x99, 0x08, 0x40, + 0xfb, 0xbe, 0x05, 0x64, 0xfb, 0x3b, 0x71, 0x6c, 0xfb, 0x00, 0x83, 0x08, + 0x5b, 0x5d, 0x05, 0xf8, 0x06, 0xf8, 0xbf, 0x15, 0xd4, 0x88, 0xad, 0x85, + 0xaa, 0x7b, 0xbc, 0x71, 0xa8, 0x54, 0x8b, 0x48, 0x8b, 0x35, 0x6a, 0x20, + 0x5e, 0x52, 0x5a, 0x4c, 0x50, 0x73, 0x24, 0x8b, 0x08, 0x7c, 0x8b, 0xfb, + 0x14, 0x8f, 0x05, 0xf7, 0x08, 0xf7, 0x00, 0x8b, 0x8b, 0xb8, 0xf7, 0x49, + 0x08, 0xc2, 0xf7, 0x6d, 0x05, 0x0e, 0xf7, 0xc7, 0xf7, 0xfe, 0xf7, 0xc7, + 0x15, 0xc4, 0xf7, 0x77, 0xaa, 0x8b, 0x05, 0xb5, 0x8d, 0xaa, 0x8c, 0x91, + 0x8b, 0xb2, 0x8b, 0x92, 0x84, 0xa6, 0x49, 0x08, 0xcd, 0xcd, 0x05, 0x88, + 0xa1, 0x83, 0x96, 0x7a, 0x91, 0x08, 0xfb, 0x6a, 0x87, 0x91, 0xa0, 0x45, + 0x76, 0x05, 0x2b, 0x8a, 0x4e, 0x78, 0x52, 0x5e, 0x59, 0x63, 0x75, 0x63, + 0x8b, 0x57, 0x8b, 0x71, 0x8f, 0x77, 0x99, 0x68, 0x08, 0xd3, 0xbb, 0x05, + 0x82, 0xab, 0x87, 0xa5, 0x8b, 0xa4, 0x8b, 0xd9, 0xc3, 0xab, 0xf7, 0x1c, + 0x8f, 0x08, 0x53, 0xfb, 0x75, 0x05, 0x7a, 0x7a, 0x86, 0x85, 0x7a, 0x77, + 0x08, 0xa7, 0x06, 0x87, 0x7c, 0x88, 0x7e, 0x87, 0x7f, 0x65, 0xfb, 0x2e, + 0x80, 0x7a, 0x39, 0x77, 0x08, 0x65, 0x6a, 0x05, 0xa7, 0x8a, 0xa0, 0x8b, + 0x92, 0x8b, 0x08, 0xe5, 0x8a, 0x05, 0xa9, 0x8b, 0xa6, 0x8a, 0xa2, 0x8a, + 0x08, 0xf7, 0x0d, 0x87, 0x8c, 0x8b, 0xb6, 0x8b, 0xbf, 0x8b, 0x99, 0x91, + 0xb8, 0xb4, 0xb9, 0xb4, 0x9c, 0xa3, 0x8b, 0xa2, 0x8b, 0x90, 0x8a, 0x93, + 0x88, 0x95, 0x08, 0x3f, 0x6f, 0x05, 0x8e, 0x76, 0x8c, 0x83, 0x8b, 0x82, + 0x08, 0x65, 0x7e, 0x86, 0x2b, 0x1e, 0xfb, 0x98, 0x06, 0xec, 0xe4, 0x8c, + 0x8d, 0xaf, 0xf7, 0x1d, 0xbe, 0x8e, 0x91, 0x8b, 0xa3, 0x8d, 0xa1, 0x8c, + 0x9a, 0x8c, 0x91, 0x8b, 0x8f, 0x8c, 0x96, 0x8b, 0x97, 0x8c, 0x9d, 0x98, + 0x8d, 0x8d, 0x9d, 0x99, 0x08, 0xfb, 0x47, 0x06, 0x0e, 0xf7, 0x9f, 0xf8, + 0x48, 0xf7, 0xb9, 0x15, 0xcb, 0xf7, 0x95, 0xf7, 0x34, 0x87, 0x05, 0x98, + 0x96, 0xa8, 0xa1, 0xa0, 0x98, 0x90, 0x97, 0x8c, 0x8d, 0x8f, 0x99, 0x61, + 0x71, 0x68, 0x82, 0x53, 0x8b, 0x08, 0xfb, 0x1a, 0x8c, 0x05, 0xfb, 0x00, + 0x8b, 0x4c, 0x7b, 0x54, 0x64, 0x53, 0x62, 0x69, 0x45, 0x8b, 0x42, 0x8b, + 0x73, 0x8e, 0x7a, 0x95, 0x67, 0x08, 0xdf, 0xb1, 0x05, 0x7b, 0xba, 0x87, + 0xa1, 0x8b, 0xa9, 0x8b, 0xe5, 0xc6, 0xc3, 0xe8, 0x8b, 0x97, 0x8b, 0x9c, + 0x8a, 0x9e, 0x89, 0x08, 0x4b, 0xfb, 0x95, 0x67, 0x5d, 0xa4, 0x8b, 0x70, + 0x20, 0x05, 0x63, 0xfb, 0x34, 0x73, 0x6f, 0x2c, 0x8b, 0x7e, 0x8b, 0x7a, + 0x8c, 0x66, 0x8c, 0x08, 0x64, 0x4a, 0x05, 0xa0, 0x89, 0x9d, 0x8a, 0x96, + 0x8b, 0xc7, 0x8b, 0xb6, 0x9e, 0xcd, 0xc1, 0xd4, 0xc6, 0xa5, 0xb6, 0xa3, + 0xea, 0x08, 0xa3, 0xeb, 0x05, 0xc4, 0x8e, 0xba, 0x8e, 0x8e, 0x8c, 0xa7, + 0x8f, 0x93, 0x90, 0xa4, 0xa4, 0x08, 0xfb, 0x32, 0x06, 0x0e, 0xf7, 0xc7, + 0xf8, 0xda, 0xf7, 0x84, 0x15, 0xa0, 0x8b, 0xb9, 0xa7, 0x05, 0x63, 0x8e, + 0x2f, 0x8d, 0x2e, 0x8b, 0x08, 0x4e, 0x6c, 0x8b, 0x83, 0x05, 0xbd, 0x8e, + 0xbc, 0x8d, 0xba, 0x8c, 0x08, 0x67, 0xfb, 0x24, 0x05, 0x61, 0x63, 0x4f, + 0x70, 0x5d, 0x8b, 0x08, 0x41, 0x5d, 0xc5, 0xe6, 0xf7, 0x57, 0xf7, 0x18, + 0xf7, 0x4a, 0xf7, 0x20, 0x1f, 0xb4, 0x8b, 0xae, 0x7a, 0x9e, 0x6d, 0x98, + 0x77, 0x90, 0x7a, 0x91, 0x61, 0x08, 0xd5, 0xde, 0x05, 0x78, 0xc4, 0x66, + 0xa1, 0x3f, 0x8b, 0xfb, 0x01, 0x8b, 0x28, 0x5e, 0x3b, 0x35, 0x3a, 0x34, + 0x58, 0xfb, 0x0f, 0x8b, 0x22, 0x8b, 0x2a, 0xc0, 0x4f, 0xe1, 0x8b, 0xc9, + 0x8b, 0xc0, 0x9b, 0xe4, 0xb8, 0x7c, 0x4f, 0x79, 0x4a, 0x82, 0x75, 0x08, + 0x77, 0x55, 0x6e, 0x75, 0x56, 0x8b, 0x6e, 0x8b, 0x5a, 0x8f, 0x6d, 0x90, + 0x08, 0x61, 0x49, 0x05, 0xaf, 0x87, 0x9b, 0x8a, 0x9f, 0x8b, 0xdb, 0x8b, + 0xcf, 0xaf, 0xcd, 0xd8, 0xb6, 0xbc, 0x9d, 0xb5, 0xa8, 0xf7, 0x08, 0x08, + 0xb2, 0xf7, 0x30, 0x05, 0x0e, 0xf8, 0x03, 0xf8, 0x1c, 0xf7, 0xd6, 0x15, + 0x91, 0xa0, 0x9b, 0xc7, 0xa5, 0xed, 0x8c, 0x8f, 0x8e, 0x99, 0x8f, 0x9e, + 0x08, 0xb2, 0xac, 0x05, 0x71, 0x8c, 0x79, 0x8c, 0x7d, 0x8b, 0x29, 0x8b, + 0x47, 0x79, 0x55, 0x63, 0x55, 0x63, 0x73, 0x5d, 0x8b, 0x4c, 0x8b, 0x7c, + 0x8d, 0x80, 0x92, 0x73, 0x08, 0xd6, 0xa4, 0x05, 0x82, 0xab, 0x88, 0x9a, + 0x8b, 0xa1, 0x8b, 0xc2, 0xa2, 0xb4, 0xb4, 0x9c, 0xa3, 0x95, 0xa3, 0x8e, + 0xc9, 0x8b, 0x7c, 0x59, 0x8a, 0x88, 0x62, 0xfb, 0x37, 0x08, 0x67, 0x65, + 0xa5, 0x89, 0x05, 0x5b, 0xfb, 0x4e, 0x75, 0x70, 0x20, 0x8b, 0x7d, 0x8b, + 0x7e, 0x8b, 0x71, 0x8d, 0x08, 0x5c, 0x4a, 0x05, 0xa1, 0x88, 0x95, 0x8a, + 0x9c, 0x8b, 0xab, 0x8b, 0xa4, 0x8e, 0x9f, 0x92, 0xa9, 0x94, 0xbe, 0xb3, + 0xbf, 0xc1, 0xc0, 0xc2, 0x8e, 0x91, 0xac, 0xf3, 0xf7, 0x10, 0x93, 0xaf, + 0x8d, 0xc3, 0x8c, 0x86, 0x76, 0x87, 0x7d, 0x8a, 0x85, 0x08, 0x61, 0xfb, + 0x2f, 0x7b, 0x48, 0x8b, 0x7b, 0x08, 0x80, 0x95, 0x81, 0x97, 0x1e, 0x92, + 0x8b, 0x95, 0x8d, 0x96, 0x8e, 0xa5, 0x92, 0x90, 0x8c, 0xf7, 0x0c, 0xa1, + 0x08, 0x9d, 0xa4, 0x05, 0x55, 0x86, 0x7b, 0x8a, 0x73, 0x8b, 0x76, 0x8b, + 0x7f, 0x95, 0x8b, 0x9c, 0x8b, 0xaa, 0x8b, 0x8b, 0xbc, 0xf7, 0x51, 0x9d, + 0xd0, 0xaf, 0xf7, 0x15, 0x9b, 0xbd, 0xa1, 0xd1, 0x9c, 0x9d, 0xb5, 0x8b, + 0x9f, 0x8b, 0x96, 0x89, 0xa1, 0x83, 0x08, 0xad, 0xc2, 0x05, 0x78, 0x91, + 0x83, 0x8c, 0x79, 0x8b, 0x61, 0x8b, 0x5f, 0x6f, 0x4a, 0x46, 0x63, 0x60, + 0x7d, 0x71, 0x7a, 0x4d, 0x08, 0x70, 0x2a, 0x05, 0x8b, 0x8a, 0x86, 0x7a, + 0x87, 0x7e, 0x08, 0xfb, 0x69, 0x06, 0x0e, 0xce, 0xdc, 0x16, 0xcc, 0x8c, + 0x8b, 0x8b, 0x99, 0x8b, 0x08, 0xf7, 0x30, 0x8a, 0xaf, 0xa4, 0x2e, 0x92, + 0x05, 0x9e, 0xe3, 0xca, 0xf7, 0x8e, 0xba, 0xf7, 0x40, 0x08, 0xc5, 0x91, + 0xae, 0xa4, 0x69, 0x8b, 0x05, 0x25, 0x8a, 0x8b, 0x8b, 0x7a, 0x8b, 0x7b, + 0x8b, 0x87, 0x8b, 0x52, 0x8c, 0x08, 0x68, 0x72, 0xe5, 0x85, 0x05, 0x83, + 0x66, 0x85, 0x72, 0x8a, 0x86, 0x08, 0x76, 0x39, 0x05, 0x4c, 0xfb, 0x8b, + 0x80, 0x5f, 0x86, 0x7a, 0x89, 0x85, 0x85, 0x74, 0x84, 0x73, 0x08, 0x50, + 0x84, 0x67, 0x72, 0x05, 0x0e, 0xe2, 0xf7, 0x96, 0xf7, 0xea, 0x15, 0x85, + 0xad, 0x89, 0x9b, 0x8b, 0xa1, 0x08, 0xd9, 0xb4, 0xb5, 0xd8, 0x1e, 0x9a, + 0x8b, 0x54, 0xfb, 0x70, 0x05, 0x78, 0x7b, 0x88, 0x88, 0x79, 0x79, 0x9a, + 0x81, 0x8f, 0x86, 0x90, 0x7d, 0x08, 0x7f, 0x63, 0x05, 0x6c, 0xfb, 0x06, + 0x8b, 0x8b, 0x88, 0x83, 0x7f, 0x65, 0x7c, 0x6a, 0x7c, 0x78, 0x6f, 0x66, + 0x64, 0x78, 0x5a, 0x8b, 0x77, 0x8b, 0x7c, 0x8d, 0x6b, 0x93, 0x08, 0x63, + 0x48, 0x05, 0x9e, 0x87, 0x94, 0x8a, 0x9b, 0x8b, 0xc9, 0x8b, 0xb6, 0xa0, + 0xe9, 0xd5, 0xdf, 0xce, 0x93, 0x98, 0xa9, 0xf7, 0x0d, 0x08, 0xe7, 0xf8, + 0x05, 0xac, 0xa8, 0x05, 0x2d, 0x8b, 0x5d, 0x85, 0x60, 0x7b, 0x34, 0x69, + 0x5b, 0x49, 0x8b, 0x35, 0x8b, 0x77, 0x8d, 0x80, 0x92, 0x71, 0x08, 0xd7, + 0xae, 0x05, 0x0e, 0xf7, 0xef, 0xf9, 0xdc, 0x5b, 0x15, 0x64, 0x54, 0x75, + 0x7a, 0x69, 0x8b, 0x68, 0x8b, 0x68, 0xa8, 0x6e, 0xc0, 0x6e, 0xc1, 0x7d, + 0xad, 0x58, 0xf7, 0x23, 0x08, 0x53, 0xf7, 0x2d, 0x05, 0xf7, 0x31, 0xf7, + 0x19, 0xb3, 0xa5, 0xb7, 0x8b, 0x9d, 0x8b, 0x98, 0x88, 0xa7, 0x7f, 0x08, + 0xb0, 0xd5, 0x05, 0x72, 0x95, 0x7e, 0x8e, 0x79, 0x8b, 0x6b, 0x8b, 0x76, + 0x81, 0x5d, 0x65, 0x08, 0xfb, 0x66, 0xfb, 0x40, 0x05, 0x88, 0x88, 0x7f, + 0x82, 0x7a, 0x7e, 0x08, 0xbf, 0xf7, 0x65, 0x05, 0xa8, 0x93, 0x93, 0x90, + 0x9a, 0x9d, 0x08, 0x5e, 0x8e, 0x76, 0x8c, 0x72, 0x8b, 0x3c, 0x8b, 0x4b, + 0x80, 0x5f, 0x76, 0x40, 0x66, 0x62, 0x50, 0x8b, 0x43, 0x8b, 0x71, 0x8f, + 0x7c, 0x98, 0x69, 0x08, 0xdd, 0xae, 0x05, 0x7b, 0xb2, 0x85, 0xa4, 0x8b, + 0xaa, 0x8b, 0xd1, 0xbd, 0xb1, 0xe8, 0x8b, 0x96, 0x8b, 0x9b, 0x8a, 0xa0, + 0x89, 0x85, 0x71, 0x80, 0x62, 0x7e, 0x53, 0x6c, 0xfb, 0x11, 0x7d, 0x57, + 0x7b, 0x5d, 0x64, 0xfb, 0x03, 0x66, 0x67, 0x3e, 0x8b, 0x08, 0x65, 0x8b, + 0x5f, 0x60, 0xf7, 0x1d, 0x8b, 0x05, 0xe3, 0x8b, 0x8d, 0x8c, 0xcf, 0xb5, + 0x08, 0xfb, 0x0d, 0x06, 0xf7, 0x0e, 0xf7, 0x0e, 0x9b, 0xa5, 0xab, 0xf7, + 0x11, 0x8d, 0x84, 0x8e, 0x84, 0x8d, 0x83, 0x91, 0x7a, 0x8b, 0x8a, 0x97, + 0x66, 0x08, 0x9d, 0x4f, 0x05, 0xb6, 0xfb, 0x20, 0xa9, 0x46, 0xaf, 0x62, + 0xb7, 0x59, 0xc8, 0x71, 0xd5, 0x8b, 0xac, 0x8b, 0x9d, 0x8e, 0xb0, 0x99, + 0x08, 0x80, 0xdd, 0x05, 0x0e, 0xf7, 0x9f, 0xf8, 0xa8, 0xf8, 0xd2, 0x15, + 0x77, 0x8d, 0x81, 0x8c, 0x7d, 0x8b, 0x78, 0x8b, 0x7a, 0x89, 0x7a, 0x87, + 0x70, 0x84, 0x5b, 0x69, 0x63, 0x63, 0x5a, 0x59, 0x7a, 0x5d, 0x64, 0xfb, + 0x4e, 0x70, 0xfb, 0x14, 0x71, 0x66, 0x4c, 0x8b, 0x83, 0x8b, 0x7f, 0x8b, + 0x80, 0x8c, 0x08, 0x7d, 0x7d, 0x85, 0x84, 0x7c, 0x78, 0xbb, 0x8d, 0xa4, + 0x8c, 0xa4, 0x8b, 0xa5, 0x8b, 0xbe, 0x89, 0xd7, 0x88, 0x08, 0xf7, 0x38, + 0x83, 0x92, 0x8b, 0xa5, 0x8b, 0xbf, 0x8b, 0xa1, 0x96, 0x9d, 0xb0, 0x97, + 0xa2, 0xaa, 0xd0, 0x9a, 0xb1, 0x08, 0x80, 0x9e, 0x05, 0x4a, 0xfb, 0x1d, + 0x80, 0x85, 0xfb, 0x40, 0x8c, 0x08, 0xfb, 0x51, 0x8b, 0xa6, 0xa5, 0x05, + 0xc0, 0xbc, 0x92, 0x98, 0xa4, 0xf3, 0xa8, 0xf7, 0x10, 0x99, 0xc2, 0x98, + 0xb2, 0x9a, 0xb5, 0xa5, 0x9e, 0xb5, 0x8b, 0x98, 0x8b, 0x94, 0x8b, 0xb0, + 0x89, 0x08, 0xb2, 0xc3, 0x05, 0x0e, 0xf8, 0xa3, 0xc5, 0x16, 0x9d, 0x8a, + 0x9a, 0x8b, 0x95, 0x8b, 0xd9, 0x8b, 0xbf, 0xa2, 0xb6, 0xc0, 0xab, 0xb4, + 0x97, 0xa4, 0xa3, 0xdd, 0x96, 0xb3, 0xb0, 0xf7, 0x1c, 0x9c, 0xd0, 0xae, + 0xfb, 0xfd, 0x8c, 0x83, 0x8d, 0x3b, 0x08, 0xbc, 0xb1, 0x05, 0xae, 0xd6, + 0xce, 0xf3, 0xf7, 0x39, 0xf7, 0x7f, 0x08, 0x81, 0x5f, 0x05, 0x88, 0x7c, + 0x83, 0x6d, 0x7f, 0x5f, 0x51, 0xfb, 0x6c, 0x7f, 0x5d, 0x89, 0x86, 0x83, + 0x74, 0x86, 0x76, 0x8b, 0x7d, 0x08, 0x7d, 0x96, 0x7f, 0x98, 0x1e, 0x90, + 0x8b, 0x91, 0x8c, 0x93, 0x8c, 0x95, 0x8d, 0xc6, 0x95, 0xa4, 0x8f, 0x08, + 0xba, 0x91, 0x05, 0x8e, 0x8c, 0x93, 0x8c, 0x98, 0x8d, 0x08, 0xa0, 0xa4, + 0x05, 0x7a, 0x8a, 0x7b, 0x8a, 0x86, 0x8a, 0x7a, 0x8a, 0x7b, 0x8a, 0x83, + 0x8b, 0x6b, 0x8b, 0x79, 0x9a, 0x8b, 0xa4, 0x8b, 0xa5, 0x8c, 0x91, 0xa5, + 0xf5, 0xb6, 0xf7, 0x42, 0x8e, 0x97, 0x9e, 0xcf, 0xb3, 0xf7, 0x1f, 0x90, + 0x96, 0xa5, 0x8b, 0x08, 0x94, 0x8b, 0x98, 0x8a, 0x98, 0x88, 0x8e, 0x8a, + 0x97, 0x89, 0x97, 0x89, 0x08, 0xb4, 0xc3, 0x05, 0x79, 0x90, 0x81, 0x8c, + 0x7f, 0x8b, 0x71, 0x8b, 0x75, 0x83, 0x67, 0x76, 0x53, 0x6b, 0x81, 0x82, + 0x67, 0x58, 0x08, 0xfb, 0x1b, 0xfb, 0x50, 0xfb, 0x05, 0xfb, 0x38, 0x72, + 0x67, 0x05, 0x7e, 0xf7, 0x2c, 0x71, 0xf7, 0x71, 0x7e, 0xd1, 0x08, 0x6c, + 0x72, 0x05, 0x65, 0x90, 0x78, 0x8c, 0x73, 0x8b, 0x48, 0x8b, 0x63, 0x7a, + 0x5c, 0x5a, 0x55, 0x55, 0x6b, 0x4b, 0x8b, 0x58, 0x8b, 0x6e, 0x91, 0x71, + 0x9c, 0x66, 0x08, 0xd7, 0xc0, 0x05, 0x73, 0xbf, 0x83, 0xa4, 0x8b, 0xa8, + 0x8b, 0xcc, 0xbc, 0xaf, 0xe2, 0x8b, 0xa2, 0x8b, 0x9b, 0x8a, 0xac, 0x86, + 0x5f, 0xfb, 0x47, 0x55, 0xfb, 0x4f, 0x79, 0x6b, 0x08, 0x78, 0x68, 0x72, + 0x7c, 0x60, 0x8b, 0x7a, 0x8b, 0x8b, 0x8b, 0x52, 0x90, 0x08, 0x5d, 0x46, + 0x05, 0x0e, 0xf8, 0x17, 0xb3, 0x16, 0xa6, 0x89, 0x99, 0x8a, 0x99, 0x8b, + 0xb6, 0x8b, 0xa6, 0x91, 0xa5, 0x9b, 0xbc, 0xa8, 0xbd, 0xd3, 0xab, 0xdf, + 0x9b, 0xb6, 0x91, 0xa1, 0xb6, 0xf7, 0x41, 0x08, 0xb0, 0xfb, 0x2f, 0x05, + 0xa8, 0xfb, 0x10, 0xa3, 0x42, 0xad, 0x47, 0xc8, 0xfb, 0x10, 0xe3, 0x4e, + 0xf7, 0x0a, 0x8b, 0xbe, 0x8b, 0xaf, 0x94, 0xb8, 0xa5, 0x08, 0x73, 0xe4, + 0x05, 0x7d, 0x6a, 0x84, 0x7d, 0x7e, 0x7c, 0x79, 0x75, 0x72, 0x7e, 0x72, + 0x8b, 0x4c, 0x8b, 0x51, 0xbc, 0x58, 0xec, 0x9c, 0xe1, 0x94, 0xb2, 0xa4, + 0xf4, 0xb6, 0xf7, 0x42, 0xa1, 0xd3, 0xab, 0xcd, 0xa0, 0xb5, 0xa3, 0x9b, + 0xb9, 0x8b, 0x08, 0x92, 0x8b, 0x91, 0x8b, 0x99, 0x89, 0x08, 0xb0, 0xce, + 0x05, 0x7f, 0x8c, 0x80, 0x8c, 0x83, 0x8b, 0x61, 0x8b, 0x5e, 0x6e, 0x57, + 0x4e, 0x5b, 0x53, 0x79, 0x58, 0x5a, 0xfb, 0x6c, 0x81, 0x5c, 0x80, 0x5c, + 0x80, 0x5b, 0x8a, 0x86, 0x86, 0x76, 0x82, 0x6c, 0x5b, 0xeb, 0x7e, 0xb2, + 0x21, 0xf8, 0x20, 0x08, 0x69, 0x6c, 0x05, 0x73, 0x8d, 0x7e, 0x8c, 0x79, + 0x8b, 0x4f, 0x8b, 0x67, 0x80, 0x67, 0x6f, 0x4b, 0x59, 0x5f, 0x43, 0x8b, + 0x54, 0x8b, 0x72, 0x92, 0x71, 0x9d, 0x66, 0x08, 0xd0, 0xba, 0x05, 0x72, + 0xc0, 0x84, 0xa2, 0x8b, 0xa4, 0x8b, 0xa9, 0x9c, 0xa6, 0xa7, 0x9a, 0xa3, + 0x98, 0xa3, 0x8f, 0xb8, 0x8b, 0xa0, 0x8b, 0x9d, 0x8b, 0xb1, 0x89, 0x5c, + 0xfb, 0x5d, 0x65, 0xfb, 0x12, 0x6a, 0x50, 0x76, 0x66, 0x75, 0x80, 0x56, + 0x8b, 0x08, 0x78, 0x8b, 0x7c, 0x8c, 0x6f, 0x8e, 0x08, 0x5b, 0x46, 0x05, + 0x0e, 0xf7, 0xb3, 0xf8, 0x7b, 0xf8, 0xe3, 0x15, 0x38, 0x8b, 0x21, 0x61, + 0x46, 0x50, 0x3b, 0x45, 0x5e, 0xfb, 0x03, 0x8b, 0xfb, 0x12, 0x8b, 0xfb, + 0x14, 0xc6, 0x47, 0xf7, 0x03, 0x8b, 0xe6, 0x8b, 0xef, 0xb6, 0xd6, 0xd3, + 0xd3, 0xd1, 0xb3, 0xf3, 0x8b, 0xf7, 0x0c, 0x8b, 0xf7, 0x12, 0x51, 0xd0, + 0x20, 0x8b, 0x08, 0x51, 0x64, 0x15, 0xe4, 0xbf, 0x45, 0xfb, 0x08, 0x1f, + 0x8b, 0x3f, 0x76, 0x35, 0x6b, 0x52, 0x60, 0x3f, 0x47, 0x5f, 0x41, 0x8b, + 0x08, 0x2f, 0x55, 0xd3, 0xf7, 0x0f, 0xf7, 0x4d, 0xf6, 0xf7, 0x25, 0xf7, + 0x1c, 0x1f, 0x0e, 0xf7, 0x77, 0xd9, 0xb5, 0x15, 0x62, 0x62, 0xd1, 0x8b, + 0x05, 0xf7, 0xa4, 0x8b, 0x8e, 0x8b, 0xde, 0xb3, 0x08, 0x8d, 0x94, 0x05, + 0x53, 0x85, 0x73, 0x8a, 0x33, 0x8a, 0x8e, 0x98, 0x8e, 0x98, 0x8e, 0x97, + 0x8f, 0x9c, 0x8f, 0x9c, 0x90, 0xa4, 0x98, 0xc1, 0x8c, 0x91, 0x96, 0xb4, + 0xcd, 0x8f, 0xc2, 0x9b, 0xc8, 0xac, 0xd3, 0xb2, 0xb8, 0xd1, 0x8b, 0xd5, + 0x08, 0xcf, 0x53, 0xac, 0xfb, 0x07, 0x1e, 0x81, 0x8b, 0x80, 0x8b, 0x74, + 0x8a, 0x08, 0x91, 0xa4, 0x48, 0x69, 0x05, 0x3c, 0x83, 0x5e, 0x7d, 0x5a, + 0x6e, 0x3c, 0x5b, 0x60, 0x47, 0x8b, 0x3c, 0x8b, 0x6e, 0x8f, 0x77, 0x98, + 0x6b, 0x08, 0xd6, 0xb8, 0x05, 0x7f, 0xae, 0x88, 0x9b, 0x8b, 0xa3, 0x8b, + 0xc0, 0xa2, 0xbe, 0xb0, 0xa8, 0xad, 0xa5, 0xad, 0x97, 0xcd, 0x92, 0x68, + 0xfb, 0x31, 0x58, 0xfb, 0x63, 0x65, 0xfb, 0x18, 0x08, 0xfb, 0x23, 0x06, + 0xf7, 0xec, 0xf8, 0x8c, 0x15, 0x9a, 0x8c, 0x9b, 0x8c, 0x93, 0x8b, 0x08, + 0xca, 0xad, 0x6c, 0x51, 0x21, 0x44, 0x3d, 0x2b, 0x1f, 0x80, 0x8b, 0x83, + 0x8c, 0x7b, 0x8e, 0x08, 0xcd, 0xf7, 0x9f, 0x05, 0x0e, 0xf7, 0xb3, 0xf9, + 0xb6, 0x6e, 0x15, 0x81, 0x43, 0x66, 0x62, 0x55, 0x8b, 0x4a, 0x8b, 0x35, + 0xbb, 0xfb, 0x1a, 0xf7, 0x04, 0xdf, 0xb5, 0xb0, 0xa6, 0xaf, 0xbb, 0xc1, + 0xd2, 0xa6, 0xe2, 0x8b, 0xee, 0x8b, 0xd2, 0x7e, 0xb7, 0x6b, 0xaf, 0x70, + 0xaa, 0x64, 0x9c, 0x5d, 0x8b, 0x08, 0x30, 0x8b, 0x20, 0x62, 0x45, 0x4e, + 0x3d, 0x46, 0x5c, 0xfb, 0x06, 0x8b, 0xfb, 0x0b, 0x8b, 0xfb, 0x18, 0xc7, + 0x47, 0xf7, 0x08, 0x8b, 0x9d, 0x8b, 0x98, 0x8c, 0xa6, 0x90, 0xb3, 0x65, + 0xac, 0x6e, 0xb5, 0x6a, 0xdb, 0x4c, 0xb9, 0x76, 0xc4, 0x8b, 0x08, 0xd2, + 0x8b, 0xd4, 0xb1, 0xd2, 0xd6, 0x08, 0x5a, 0xbc, 0x05, 0xfc, 0x43, 0xdf, + 0x15, 0x70, 0x76, 0x7f, 0x86, 0x77, 0x8b, 0x08, 0x40, 0x58, 0xd8, 0xf7, + 0x04, 0xf7, 0x4d, 0xf7, 0x00, 0xf7, 0x28, 0xf7, 0x1c, 0xe4, 0xc0, 0x45, + 0xfb, 0x09, 0x1f, 0x8b, 0x45, 0x77, 0x34, 0x6d, 0x54, 0x6b, 0x4f, 0x6b, + 0x6f, 0x4a, 0x6f, 0x08, 0x75, 0x9e, 0x05, 0x0e, 0xf7, 0xb3, 0xb1, 0x8c, + 0x15, 0xc0, 0x8a, 0x8b, 0x8b, 0x91, 0x8b, 0xbf, 0x8b, 0xe5, 0x8d, 0xa9, + 0x8d, 0x08, 0xd5, 0xb1, 0x05, 0x66, 0x8c, 0x82, 0x8b, 0x35, 0x8d, 0xf7, + 0x05, 0xf7, 0x05, 0x91, 0x94, 0xab, 0xf7, 0x13, 0x8c, 0x8c, 0x8c, 0x8b, + 0x8b, 0x8b, 0x96, 0x8c, 0x91, 0x82, 0x91, 0x72, 0xb1, 0xfb, 0x3b, 0xac, + 0x2c, 0xb4, 0x4e, 0xb6, 0x4b, 0xc6, 0x6c, 0xda, 0x8b, 0x08, 0xc3, 0x8b, + 0xad, 0x97, 0xc3, 0xb4, 0x08, 0x5a, 0xc8, 0x05, 0x6b, 0x50, 0x6f, 0x74, + 0x64, 0x8b, 0x5c, 0x8b, 0x5e, 0xbd, 0x62, 0xee, 0x71, 0xc9, 0x6c, 0xe8, + 0x62, 0xf7, 0x16, 0xc4, 0x9d, 0xa2, 0x96, 0xaa, 0x9f, 0xba, 0xab, 0xa6, + 0xb9, 0x8b, 0xbb, 0x8b, 0xc9, 0x59, 0xad, 0x30, 0x8b, 0x08, 0x7f, 0x8b, + 0x72, 0x8a, 0x76, 0x8a, 0x08, 0x93, 0xab, 0x30, 0x60, 0x05, 0xfb, 0x38, + 0x6f, 0x34, 0x3f, 0x8b, 0xfb, 0x09, 0x8b, 0x71, 0x8e, 0x7a, 0x96, 0x66, + 0x08, 0xdf, 0xb6, 0x05, 0x83, 0xad, 0x88, 0x9c, 0x8b, 0xa2, 0x8b, 0xbb, + 0x9a, 0xb1, 0xaa, 0xa8, 0xa7, 0xa4, 0xa7, 0x96, 0xcb, 0x93, 0x08, 0x82, + 0x67, 0x05, 0x87, 0x7b, 0x85, 0x74, 0x84, 0x6c, 0x08, 0x59, 0xfb, 0x5a, + 0x05, 0x61, 0xfb, 0x3d, 0x70, 0x71, 0xfb, 0x16, 0x8c, 0x08, 0x64, 0x5f, + 0x05, 0xf8, 0x18, 0xf8, 0xba, 0x15, 0xaa, 0x06, 0xc9, 0xa5, 0x74, 0x54, + 0x1f, 0x8b, 0x59, 0x70, 0x5b, 0x61, 0x71, 0x6d, 0x79, 0x73, 0x84, 0x55, + 0x84, 0x08, 0xc5, 0xf7, 0x7e, 0x05, 0x0e, 0xf7, 0x27, 0xb7, 0xf1, 0x15, + 0x5f, 0x23, 0x05, 0xae, 0x5c, 0xba, 0x75, 0xcc, 0x8b, 0xf7, 0x2d, 0x8b, + 0xf7, 0x2a, 0xf7, 0x11, 0x8b, 0xf7, 0x13, 0x8b, 0xb4, 0x7b, 0xa0, 0x41, + 0xc5, 0x42, 0xc4, 0x7f, 0x9c, 0x8b, 0xb6, 0x8b, 0xcc, 0xbc, 0xc3, 0xc6, + 0x8b, 0xb5, 0x8b, 0x9a, 0x79, 0x96, 0x4b, 0x08, 0xcd, 0xba, 0x05, 0x85, + 0xc2, 0x6d, 0xa6, 0x56, 0x8b, 0x24, 0x8b, 0xfb, 0x09, 0xfb, 0x06, 0x8b, + 0x28, 0x8b, 0x5e, 0xa0, 0x6a, 0xc5, 0x5e, 0xcf, 0x55, 0x9d, 0x70, 0x8b, + 0x5d, 0x8b, 0x3d, 0x40, 0x46, 0x34, 0x8b, 0x60, 0x8b, 0x5f, 0x9e, 0x70, + 0xa9, 0x08, 0x76, 0xa2, 0x83, 0xa0, 0x83, 0xb7, 0x08, 0x7b, 0x80, 0x05, + 0x0e, 0xf7, 0x4f, 0xf7, 0x34, 0x16, 0xf7, 0x85, 0x8b, 0x9a, 0x8d, 0xdc, + 0xb8, 0x08, 0x8d, 0x93, 0x05, 0x5f, 0x85, 0x4b, 0x87, 0x55, 0x8b, 0x83, + 0x8b, 0x7a, 0x8c, 0x76, 0x8c, 0xd8, 0xcc, 0xa4, 0xaf, 0x9c, 0xd7, 0x08, + 0xd9, 0xf7, 0xcd, 0x05, 0xf7, 0x17, 0x80, 0x8c, 0x8b, 0x9f, 0x8b, 0xba, + 0x8b, 0x92, 0x94, 0xa3, 0xee, 0x08, 0x7e, 0x9a, 0x05, 0x62, 0x45, 0x86, + 0x86, 0x67, 0x8b, 0x82, 0x8b, 0x74, 0x8c, 0x6c, 0x8c, 0x08, 0xfb, 0x27, + 0x92, 0x79, 0x8c, 0x6b, 0x8b, 0xfb, 0x43, 0x8b, 0xfb, 0x16, 0x2c, 0x8b, + 0xfb, 0x14, 0x8b, 0x6b, 0x92, 0x6f, 0x9d, 0x68, 0x08, 0xd6, 0xbc, 0x05, + 0x78, 0xbc, 0x87, 0x9a, 0x8b, 0xa7, 0x8b, 0xc3, 0xa5, 0xb6, 0xbc, 0xa2, + 0xa4, 0x97, 0xb0, 0x90, 0xc0, 0x8b, 0xa0, 0x8b, 0x9f, 0x8a, 0xbd, 0x87, + 0x08, 0x3a, 0xfb, 0xda, 0x05, 0x67, 0xfb, 0x27, 0x78, 0x72, 0x36, 0x87, + 0x08, 0x68, 0x64, 0x05, 0x0e, 0xf8, 0x3f, 0xf9, 0x02, 0xf8, 0xa9, 0x15, + 0x93, 0x8c, 0x92, 0x8b, 0x8e, 0x8b, 0x98, 0x8b, 0x8b, 0x8b, 0xac, 0x89, + 0x88, 0x80, 0x88, 0x7f, 0x89, 0x80, 0x88, 0x7e, 0x83, 0x69, 0x7d, 0x55, + 0x08, 0x4f, 0xfb, 0x86, 0x05, 0x89, 0x84, 0x85, 0x73, 0x82, 0x6a, 0x38, + 0x5f, 0x61, 0x7d, 0x57, 0x8b, 0x53, 0x8b, 0x66, 0xb8, 0x8b, 0xd1, 0x8b, + 0xf7, 0x04, 0xd2, 0xf7, 0x41, 0xf1, 0xf7, 0x1d, 0x08, 0x85, 0x93, 0x05, + 0x7e, 0x87, 0x8a, 0x8a, 0x7a, 0x83, 0x08, 0x81, 0x87, 0x05, 0x4b, 0x95, + 0x86, 0x8c, 0x74, 0x8b, 0x5b, 0x8b, 0x64, 0x7f, 0x6a, 0x71, 0x4b, 0x59, + 0x63, 0x49, 0x8b, 0x54, 0x8b, 0x70, 0x93, 0x71, 0xa0, 0x5f, 0x08, 0xce, + 0xc1, 0x05, 0x72, 0xbb, 0x82, 0xa4, 0x8b, 0xa5, 0x8b, 0xc2, 0xbd, 0xb4, + 0xcc, 0x8b, 0xa9, 0x8b, 0xa0, 0x87, 0xb6, 0x7c, 0xfb, 0x07, 0xfb, 0x49, + 0x5b, 0xfb, 0x07, 0x8b, 0x30, 0x8b, 0x42, 0xb7, 0x5a, 0xcd, 0x8b, 0xc2, + 0x8b, 0xcb, 0x9e, 0xf7, 0x0d, 0xbf, 0x08, 0x85, 0x6e, 0x89, 0x7e, 0x8b, + 0x83, 0x08, 0x7d, 0x95, 0x83, 0x9d, 0x1e, 0xa7, 0x8b, 0xc2, 0x93, 0xd0, + 0x9b, 0x08, 0xa0, 0xa4, 0x05, 0x6c, 0x88, 0x78, 0x8a, 0x75, 0x8b, 0x70, + 0x8b, 0x81, 0x95, 0x8b, 0xa3, 0x8b, 0xb8, 0xbe, 0xf7, 0x6b, 0xd0, 0xf7, + 0x8d, 0x57, 0x83, 0x84, 0x8a, 0x45, 0x84, 0x08, 0x70, 0x72, 0x05, 0x0e, + 0xf7, 0xdb, 0xf8, 0x3c, 0xf8, 0xaf, 0x15, 0xa3, 0x96, 0x91, 0x8f, 0x9a, + 0x97, 0x5b, 0x90, 0x74, 0x8d, 0x6c, 0x8b, 0x3d, 0x8b, 0x5a, 0x7c, 0x5a, + 0x66, 0x54, 0x61, 0x6b, 0x4f, 0x8b, 0x50, 0x8b, 0x71, 0x90, 0x78, 0x98, + 0x6b, 0x08, 0xd7, 0xb5, 0x05, 0x7e, 0xad, 0x87, 0x9d, 0x8b, 0xa7, 0x8b, + 0xd8, 0xbe, 0xc2, 0xd2, 0x8b, 0x97, 0x8b, 0x99, 0x8a, 0x9c, 0x89, 0x71, + 0xfb, 0x5e, 0x64, 0xfb, 0x9c, 0x7b, 0x3b, 0xa7, 0x90, 0x8f, 0x8c, 0xb5, + 0x95, 0xaf, 0xb4, 0x92, 0x92, 0xcc, 0xcf, 0x08, 0xf7, 0x30, 0xf7, 0x34, + 0xdb, 0xe3, 0xb5, 0xc3, 0xc3, 0xd7, 0xa7, 0xcd, 0x8b, 0xc2, 0x8b, 0x9d, + 0x89, 0x94, 0x84, 0x9f, 0x77, 0x97, 0x83, 0x8e, 0x73, 0x8d, 0x70, 0x7f, + 0x80, 0x83, 0x74, 0x77, 0xa5, 0x75, 0x94, 0x77, 0x8b, 0x69, 0x08, 0x8b, + 0x56, 0x69, 0x41, 0x52, 0x40, 0x55, 0x45, 0x63, 0x61, 0xfb, 0x48, 0xfb, + 0x43, 0x08, 0xce, 0xf8, 0x5f, 0x05, 0x0e, 0xf8, 0xcb, 0xf7, 0xdc, 0x8e, + 0x15, 0xf7, 0xc0, 0xf8, 0x4d, 0x05, 0x89, 0xfb, 0x0c, 0x80, 0xfb, 0x8e, + 0x82, 0x30, 0x08, 0xcb, 0xa0, 0x05, 0xad, 0xbf, 0x97, 0x9c, 0xcb, 0xda, + 0xf7, 0x51, 0xf7, 0x7c, 0xcd, 0xf7, 0x06, 0x8b, 0xed, 0x8b, 0xa6, 0x87, + 0x9b, 0x80, 0xa1, 0x7d, 0x93, 0x88, 0x8c, 0x74, 0x92, 0x6f, 0x7e, 0x7f, + 0x84, 0x73, 0x76, 0xa6, 0x6f, 0x95, 0x71, 0x8b, 0x62, 0x08, 0x8b, 0x5f, + 0x7a, 0x54, 0x6c, 0x4e, 0x64, 0x40, 0x54, 0x40, 0xfb, 0x0d, 0xfb, 0x21, + 0x8e, 0xb9, 0x8d, 0xaa, 0x8b, 0x96, 0x08, 0x91, 0xf7, 0x21, 0x05, 0x8d, + 0xbb, 0x8e, 0xc6, 0x8f, 0xd0, 0x8d, 0xa5, 0x8d, 0xa5, 0x8c, 0xa5, 0x08, + 0x51, 0x74, 0x05, 0x5d, 0x3d, 0xfb, 0x42, 0xfb, 0x96, 0x40, 0x25, 0x96, + 0xdc, 0xb2, 0xf7, 0x70, 0xa3, 0xf7, 0x0c, 0xa0, 0x92, 0x97, 0x92, 0x9e, + 0x9d, 0xfb, 0x56, 0x89, 0x7f, 0x8b, 0x67, 0x7f, 0x35, 0x6f, 0x53, 0x46, + 0x8b, 0x3c, 0x8b, 0x6a, 0x93, 0x6f, 0x9c, 0x6e, 0x08, 0xd6, 0xba, 0x05, + 0x74, 0xae, 0x81, 0xa8, 0x8b, 0xad, 0x8b, 0xb4, 0x9f, 0xaa, 0xb0, 0x98, + 0xa3, 0x94, 0xa3, 0x8d, 0xd6, 0x8c, 0x80, 0x36, 0x74, 0xfb, 0x22, 0x55, + 0xfb, 0xd1, 0x08, 0xcc, 0x9f, 0x05, 0x0e, 0xf7, 0x8b, 0x8b, 0x04, 0xa2, + 0x88, 0x96, 0x8a, 0x96, 0x8b, 0xa8, 0x8b, 0xab, 0x91, 0xa0, 0x95, 0xaa, + 0x9a, 0xa6, 0xa6, 0xc4, 0xd5, 0x08, 0xc7, 0xd8, 0xb5, 0xc0, 0xb5, 0xfb, + 0x62, 0x05, 0x95, 0x56, 0x91, 0x7f, 0x9b, 0x8b, 0x93, 0x8b, 0x97, 0x8d, + 0x99, 0x8f, 0x92, 0x8c, 0x9f, 0x8f, 0xa9, 0x90, 0x95, 0x8d, 0xa6, 0x90, + 0xb6, 0x93, 0x08, 0x9c, 0xa2, 0x05, 0x80, 0x8a, 0x81, 0x8a, 0x88, 0x8b, + 0x79, 0x89, 0x7b, 0x8a, 0x81, 0x8b, 0x65, 0x8b, 0x73, 0x99, 0x7e, 0xa8, + 0x7b, 0xb1, 0x80, 0xb6, 0x70, 0xf7, 0x16, 0x08, 0x82, 0xb8, 0xd9, 0xe9, + 0x05, 0xb7, 0xc1, 0xa7, 0x9f, 0xab, 0x8b, 0x99, 0x8b, 0x97, 0x87, 0x9d, + 0x80, 0x08, 0xb8, 0xd2, 0x05, 0x77, 0x9b, 0x7d, 0x90, 0x75, 0x8b, 0x60, + 0x8b, 0x6c, 0x77, 0x5d, 0x4f, 0x08, 0x26, 0xfb, 0x12, 0x67, 0xf7, 0x4a, + 0x05, 0x88, 0x9a, 0x85, 0x91, 0x80, 0x8b, 0x7c, 0x8b, 0x5d, 0x80, 0x2d, + 0x71, 0x08, 0x74, 0x6e, 0x05, 0x96, 0x8d, 0x95, 0x8d, 0x8e, 0x8c, 0xb2, + 0x93, 0x8d, 0x8b, 0x97, 0x8b, 0xa8, 0x8b, 0x9a, 0x7d, 0x95, 0x6a, 0x9c, + 0x4f, 0x99, 0x51, 0x96, 0x4e, 0x3d, 0x26, 0x54, 0x47, 0x77, 0x77, 0x70, + 0x70, 0x72, 0x82, 0x5b, 0x8b, 0x08, 0x82, 0x8b, 0x85, 0x8b, 0x7b, 0x8d, + 0x08, 0x5a, 0x40, 0x05, 0x0e, 0xf7, 0x8b, 0xaa, 0xfb, 0x2a, 0x15, 0x9f, + 0x89, 0x94, 0x8b, 0x9c, 0x8b, 0xe6, 0x8b, 0xb8, 0x94, 0xb5, 0xa7, 0xbc, + 0xab, 0xc1, 0xdf, 0xef, 0xf7, 0x5d, 0xf3, 0xf7, 0x65, 0x97, 0xa2, 0xa6, + 0xb2, 0xa9, 0xb5, 0xa2, 0x9b, 0xaa, 0x8b, 0x9b, 0x8b, 0x96, 0x88, 0xa2, + 0x82, 0x08, 0xa7, 0xd4, 0x05, 0x7c, 0x98, 0x83, 0x8e, 0x7a, 0x8b, 0x3b, + 0x8b, 0x4e, 0x3b, 0xfb, 0x18, 0xfb, 0xa7, 0x94, 0xc0, 0x8d, 0xa3, 0x8b, + 0xac, 0x08, 0xf7, 0x17, 0x56, 0xdd, 0x36, 0xfb, 0x0c, 0xfb, 0x1b, 0xfb, + 0x12, 0xfb, 0x06, 0x1e, 0x8b, 0x6d, 0x92, 0x6d, 0x99, 0x6c, 0x08, 0xd7, + 0xbb, 0x05, 0x7c, 0xba, 0x86, 0xa3, 0x8b, 0xa9, 0x08, 0xd1, 0xbb, 0xc2, + 0xc8, 0xe4, 0xc2, 0x26, 0xfb, 0x37, 0x1e, 0x8b, 0x58, 0x85, 0x64, 0x7e, + 0x66, 0x78, 0x58, 0x74, 0x5d, 0x70, 0x65, 0x66, 0x57, 0x5b, 0x76, 0x35, + 0x8b, 0x7c, 0x8b, 0x7c, 0x8c, 0x60, 0x8e, 0x08, 0x68, 0x41, 0x05, 0x0e, + 0xf7, 0xc7, 0xf8, 0xd9, 0xf7, 0x77, 0x15, 0x8f, 0x84, 0x90, 0x83, 0x8f, + 0x85, 0x9b, 0x6f, 0x8f, 0x7f, 0x8b, 0x74, 0x8b, 0x56, 0x6c, 0x71, 0x49, + 0x8b, 0x65, 0x8b, 0x63, 0x8d, 0x4a, 0x91, 0x37, 0x93, 0x77, 0x8c, 0x6d, + 0x8b, 0x08, 0x7a, 0x8b, 0x78, 0x8b, 0x6b, 0x86, 0xdc, 0xdf, 0xf7, 0x24, + 0xf7, 0x27, 0xf7, 0x96, 0xf7, 0x99, 0x8b, 0xa8, 0x05, 0x68, 0x6d, 0x6f, + 0x80, 0x66, 0x8b, 0x7d, 0x8b, 0x6f, 0x8d, 0x65, 0x8f, 0x2a, 0x94, 0x8b, + 0x8b, 0x71, 0x8e, 0x08, 0x59, 0x90, 0x8b, 0x8b, 0x83, 0x8b, 0x75, 0x8b, + 0x85, 0x86, 0x7b, 0x6a, 0x08, 0x49, 0xfb, 0x24, 0x9c, 0x72, 0x05, 0xd1, + 0xf7, 0x0f, 0x90, 0x92, 0xaa, 0x8b, 0x92, 0x8b, 0x95, 0x8a, 0x95, 0x8a, + 0x08, 0xb3, 0x86, 0xa6, 0x89, 0xae, 0x8b, 0xba, 0x8b, 0x9f, 0x8d, 0xbc, + 0x93, 0x08, 0xfb, 0xe7, 0xfb, 0xe7, 0x05, 0x3e, 0x40, 0x59, 0x5a, 0x73, + 0x76, 0x08, 0x66, 0x07, 0xac, 0xa3, 0xa2, 0x93, 0xb0, 0x8b, 0xa5, 0x8b, + 0xae, 0x89, 0xb1, 0x87, 0x08, 0xf7, 0x0e, 0x7e, 0xec, 0x83, 0xa3, 0x8b, + 0xa7, 0x8b, 0xa3, 0x94, 0x9e, 0x9d, 0x97, 0x97, 0x94, 0x95, 0xa7, 0xaf, + 0x08, 0xa2, 0xa8, 0x05, 0xa9, 0xaf, 0x91, 0x9a, 0x8b, 0xad, 0x8b, 0xa7, + 0x86, 0xa2, 0x7c, 0xae, 0x08, 0x40, 0x5e, 0x05, 0x0e, 0x42, 0xf7, 0x03, + 0xfb, 0x38, 0x15, 0xa3, 0x8a, 0x96, 0x8b, 0x96, 0x8b, 0x08, 0x96, 0x8b, + 0xae, 0xa5, 0x38, 0x90, 0xf7, 0x21, 0xf8, 0xbd, 0x05, 0x9c, 0xcf, 0x9c, + 0xca, 0xa4, 0xdf, 0x08, 0xbc, 0x91, 0xae, 0xa4, 0x64, 0x8b, 0x2a, 0x8b, + 0x05, 0x73, 0x27, 0x7a, 0x49, 0x78, 0x46, 0x08, 0x56, 0xfb, 0x51, 0x5c, + 0xfb, 0x48, 0x4e, 0xfb, 0x76, 0x05, 0xa4, 0x8c, 0x90, 0x8b, 0x97, 0x8b, + 0x08, 0xa1, 0x06, 0x0e, 0xf7, 0x3b, 0xf8, 0x78, 0x16, 0xfb, 0x85, 0xf8, + 0xd7, 0x51, 0x8b, 0xf7, 0x85, 0xfc, 0xd7, 0xc5, 0x8b, 0x05, 0x0e, 0x92, + 0xf7, 0xe4, 0xf9, 0x2d, 0x15, 0x78, 0x8b, 0x51, 0x8b, 0x68, 0x72, 0xe0, + 0x86, 0x05, 0x88, 0x82, 0x85, 0x72, 0x80, 0x5f, 0x08, 0x48, 0xfb, 0x9f, + 0x33, 0xfb, 0xe1, 0x05, 0x83, 0x6c, 0x82, 0x6d, 0x82, 0x6d, 0x08, 0x58, + 0x85, 0x69, 0x72, 0x05, 0x9c, 0x8c, 0x9a, 0x8b, 0x93, 0x8b, 0x08, 0xec, + 0x8a, 0x05, 0xa3, 0xef, 0x9b, 0xcd, 0x9f, 0xd1, 0x08, 0xef, 0xf8, 0x05, + 0x05, 0x92, 0xa8, 0x91, 0x9f, 0xbb, 0xf7, 0x44, 0x08, 0x5e, 0x06, 0x0e, + 0xf7, 0x63, 0xf8, 0x6c, 0xf8, 0x53, 0x15, 0x21, 0xf7, 0x7e, 0x5b, 0x8b, + 0x21, 0xfb, 0x7e, 0xbe, 0x8b, 0xda, 0xf7, 0x3f, 0xda, 0xfb, 0x3f, 0xbe, + 0x8b, 0x05, 0x0e, 0xf7, 0x4f, 0x2c, 0x04, 0x59, 0xf8, 0x88, 0xbd, 0xfc, + 0x88, 0x07, 0x0e, 0x42, 0xf7, 0xbe, 0xf8, 0x60, 0x15, 0x82, 0xa5, 0x88, + 0x9c, 0x8b, 0x9c, 0x8b, 0xb3, 0x9a, 0xa4, 0xca, 0xc7, 0x08, 0x9f, 0x9f, + 0x71, 0x96, 0x05, 0x6e, 0x70, 0x6f, 0x70, 0x73, 0x70, 0x67, 0x63, 0x7f, + 0x72, 0x8b, 0x69, 0x8b, 0x79, 0x8f, 0x74, 0x91, 0x77, 0x08, 0xc6, 0xa4, + 0x05, 0x0e, 0xf6, 0xf8, 0x80, 0xf7, 0x16, 0x15, 0x40, 0x59, 0x7c, 0x82, + 0x81, 0x8b, 0x84, 0x8b, 0x86, 0x93, 0x8b, 0x97, 0x8b, 0xa5, 0xa3, 0xf7, + 0x02, 0xaf, 0xf7, 0x19, 0x96, 0x9a, 0x8d, 0x8e, 0x9b, 0x9d, 0x5b, 0x96, + 0x68, 0x8f, 0x60, 0x8b, 0x62, 0x8b, 0x78, 0x87, 0x71, 0x7b, 0x08, 0x67, + 0x76, 0x61, 0x6c, 0x7e, 0x7d, 0x66, 0x61, 0x61, 0xfb, 0x1b, 0x8b, 0x3a, + 0x8b, 0x5b, 0x9b, 0x6b, 0xa4, 0x8b, 0xa1, 0x8b, 0xac, 0x9f, 0xf7, 0x11, + 0xe5, 0x81, 0x5d, 0x86, 0x6c, 0x8b, 0x7f, 0x8b, 0x7e, 0x91, 0x83, 0x95, + 0x8b, 0x08, 0x97, 0x8b, 0x8b, 0x8b, 0xdb, 0xbe, 0xa8, 0x9e, 0xa2, 0x9b, + 0xb1, 0xa7, 0x08, 0x8c, 0xa8, 0x05, 0xfb, 0x57, 0x85, 0x15, 0x50, 0x60, + 0x6d, 0x7a, 0x79, 0x8b, 0x7b, 0x8b, 0x81, 0x9d, 0x8b, 0xab, 0x8b, 0xbd, + 0x9b, 0xcf, 0xa4, 0xc4, 0xa3, 0xc2, 0xa1, 0xa0, 0xad, 0x8b, 0x9d, 0x8b, + 0xaa, 0x86, 0xaf, 0x83, 0x77, 0x3f, 0x84, 0x74, 0x8a, 0x86, 0x08, 0x85, + 0x72, 0x86, 0x72, 0x85, 0x71, 0x8a, 0x86, 0x88, 0x7f, 0x86, 0x79, 0x08, + 0x78, 0x7e, 0x05, 0x0e, 0xf6, 0xec, 0x7a, 0x15, 0xab, 0xa6, 0x05, 0xa7, + 0x81, 0xa0, 0x86, 0x9e, 0x8b, 0x9f, 0x8b, 0x9d, 0x91, 0xa5, 0x9b, 0xa0, + 0x99, 0xa2, 0x98, 0xa3, 0x99, 0xae, 0x9e, 0xa1, 0xa1, 0x9c, 0xab, 0xab, + 0xc4, 0xa3, 0xe3, 0x8b, 0xc6, 0x8b, 0xb9, 0x74, 0xa9, 0x67, 0x8b, 0x08, + 0x6a, 0x8b, 0x6f, 0x7c, 0x27, 0x44, 0x91, 0xa2, 0x8e, 0x9b, 0x8d, 0x92, + 0xa1, 0xf7, 0x00, 0x8b, 0x8b, 0x8e, 0x94, 0x93, 0xab, 0x9a, 0xb2, 0x96, + 0x9e, 0x9c, 0xa8, 0x9d, 0x94, 0xb1, 0x8b, 0x08, 0xa7, 0x8b, 0x9a, 0x8b, + 0xb4, 0xc5, 0x05, 0x7d, 0x8d, 0x76, 0x8c, 0x81, 0x8b, 0x67, 0x8b, 0x79, + 0x80, 0x37, 0x46, 0x47, 0x54, 0x8b, 0x8b, 0x68, 0xfb, 0x30, 0x08, 0x52, + 0xfb, 0x8b, 0x05, 0x79, 0x3d, 0x89, 0x81, 0x7b, 0x4b, 0x08, 0x95, 0x87, + 0x05, 0xf7, 0x18, 0xf7, 0xc1, 0x15, 0xc4, 0xb5, 0xae, 0x9d, 0xa2, 0x8b, + 0x9f, 0x8b, 0x98, 0x78, 0x8b, 0x6d, 0x8b, 0x63, 0x7f, 0x4f, 0x7a, 0x60, + 0x70, 0x48, 0x68, 0x6a, 0x5f, 0x8b, 0x77, 0x8b, 0x77, 0x91, 0x71, 0x98, + 0x08, 0xc0, 0xf7, 0x69, 0x05, 0x0e, 0xa6, 0xf8, 0x13, 0xf7, 0x13, 0x15, + 0x3e, 0x54, 0x56, 0x6f, 0x6b, 0x8b, 0x67, 0x8b, 0x76, 0xa7, 0x8b, 0xbb, + 0x8b, 0xbb, 0x97, 0xcb, 0x9e, 0xba, 0x9f, 0xc0, 0xa5, 0xa6, 0xa8, 0x8b, + 0xa3, 0x8b, 0x98, 0x78, 0x90, 0x5f, 0x08, 0xc5, 0xad, 0x05, 0x8c, 0x90, + 0x8b, 0x90, 0x8b, 0x8c, 0x8b, 0xb6, 0x75, 0xa6, 0x68, 0x8b, 0x79, 0x8b, + 0x80, 0x87, 0x67, 0x73, 0x40, 0x5c, 0x7b, 0x7c, 0x75, 0x62, 0x6f, 0x55, + 0x76, 0x36, 0x8b, 0x4d, 0x8b, 0x51, 0xa6, 0x69, 0xb9, 0x8b, 0x08, 0xbb, + 0x8b, 0xdd, 0xb3, 0xe6, 0xcf, 0x08, 0x8d, 0xab, 0x05, 0x0e, 0xf8, 0x85, + 0xf7, 0x17, 0x15, 0x7e, 0x83, 0x81, 0x84, 0x86, 0x88, 0x54, 0x65, 0x6f, + 0x7b, 0x82, 0x8b, 0x83, 0x8b, 0x85, 0x96, 0x8b, 0x9a, 0x8b, 0xac, 0xdf, + 0xf7, 0xfe, 0xa0, 0xc9, 0xa1, 0xc7, 0xa1, 0xa2, 0xaf, 0x8b, 0x98, 0x8b, + 0x95, 0x89, 0xa2, 0x85, 0x08, 0xae, 0xc3, 0x05, 0x7c, 0x8e, 0x83, 0x8c, + 0x82, 0x8b, 0x73, 0x8b, 0x7e, 0x87, 0x74, 0x7e, 0x72, 0x7d, 0x69, 0x71, + 0x6f, 0x71, 0x5a, 0x5c, 0x88, 0x84, 0x71, 0x24, 0x8a, 0x87, 0x88, 0x7e, + 0x87, 0x7c, 0x79, 0x8f, 0x7c, 0x8d, 0x83, 0x8b, 0x08, 0x6c, 0x8b, 0x35, + 0x55, 0x63, 0x5f, 0x69, 0x64, 0x5e, 0xfb, 0x21, 0x8b, 0x46, 0x8b, 0x65, + 0x9f, 0x64, 0x9d, 0x8b, 0x9e, 0x8b, 0xb7, 0xa6, 0xf4, 0xd7, 0x86, 0x72, + 0x88, 0x6e, 0x8b, 0x79, 0x8b, 0x77, 0x93, 0x80, 0x99, 0x8b, 0x08, 0x9b, + 0x8b, 0xe2, 0xc0, 0xde, 0xc7, 0x08, 0x8f, 0xaa, 0x05, 0xfb, 0x58, 0x87, + 0x15, 0x36, 0x4f, 0x75, 0x7e, 0x7d, 0x8b, 0x7d, 0x8b, 0x84, 0x9a, 0x8b, + 0xa8, 0x8b, 0xac, 0x91, 0xb1, 0x97, 0xb7, 0xa8, 0xf0, 0xb2, 0xbd, 0xbe, + 0x8b, 0x9d, 0x8b, 0x98, 0x84, 0xa0, 0x77, 0x08, 0x5c, 0xfb, 0x66, 0x05, + 0x0e, 0xa6, 0xf8, 0x10, 0xf7, 0x1d, 0x15, 0x40, 0x4a, 0x5b, 0x6f, 0x65, + 0x8b, 0x72, 0x8b, 0x76, 0x9c, 0x84, 0xa5, 0x87, 0x9b, 0x8a, 0x96, 0x8b, + 0xa8, 0xb8, 0xa7, 0xa9, 0xa0, 0xc6, 0xb7, 0xc1, 0xb4, 0xa0, 0xac, 0x8b, + 0xb8, 0x8b, 0xae, 0x75, 0xa0, 0x68, 0x8b, 0x08, 0x75, 0x8b, 0x7b, 0x86, + 0x74, 0x7e, 0x65, 0x75, 0x69, 0x70, 0x76, 0x73, 0x65, 0x5d, 0x69, 0xfb, + 0x02, 0x8b, 0x3a, 0x8b, 0x50, 0xaa, 0x66, 0xbe, 0x8b, 0xc6, 0x8b, 0xd4, + 0xb5, 0xda, 0xda, 0x08, 0xa8, 0x07, 0xfb, 0x6c, 0xb5, 0x15, 0x9c, 0xf6, + 0xb9, 0xde, 0xb6, 0x8b, 0x9c, 0x8b, 0x96, 0x7a, 0x8b, 0x73, 0x8b, 0x59, + 0x70, 0x6d, 0x20, 0x46, 0x08, 0x0e, 0x92, 0xf7, 0xf2, 0xf7, 0xcc, 0x15, + 0x8e, 0x8b, 0x91, 0x8b, 0x96, 0x8a, 0x08, 0xb4, 0xab, 0x05, 0x57, 0x8c, + 0x8b, 0x8b, 0x80, 0x8b, 0x7f, 0x8b, 0x8b, 0x8b, 0x5c, 0x8a, 0xcc, 0xf7, + 0x92, 0x9a, 0xaa, 0xc6, 0x8b, 0x9c, 0x8b, 0x98, 0x89, 0xb0, 0x85, 0x08, + 0xb9, 0xc1, 0x05, 0x77, 0x90, 0x83, 0x8c, 0x77, 0x8b, 0x4f, 0x8b, 0x61, + 0x75, 0x48, 0x4a, 0x53, 0x55, 0x7e, 0x6d, 0x64, 0xfb, 0x3a, 0x81, 0x8c, + 0x86, 0x8b, 0x86, 0x8b, 0x08, 0x5a, 0x89, 0x05, 0x89, 0x8b, 0x86, 0x8b, + 0x83, 0x8c, 0x85, 0x87, 0x85, 0x87, 0x89, 0x8a, 0x08, 0x75, 0x7f, 0x05, + 0x87, 0x89, 0x83, 0x87, 0x83, 0x86, 0x08, 0xa4, 0x8b, 0xd1, 0x8a, 0x05, + 0x91, 0x8b, 0x96, 0x8b, 0x9f, 0x8c, 0x7b, 0x4e, 0x85, 0x70, 0x78, 0x34, + 0x4f, 0xfb, 0xa7, 0x74, 0x5e, 0x36, 0x8b, 0x7d, 0x8b, 0x7f, 0x8c, 0x70, + 0x8f, 0x81, 0x7c, 0x88, 0x86, 0x84, 0x82, 0x83, 0x80, 0x82, 0x80, 0x83, + 0x7f, 0x08, 0xa1, 0x88, 0x96, 0x8a, 0x9b, 0x8b, 0xac, 0x8b, 0xa5, 0x90, + 0x9b, 0x94, 0xa8, 0x9b, 0xbe, 0xbc, 0xa6, 0xae, 0xaa, 0xb5, 0xaf, 0xe1, + 0xa2, 0xe6, 0xb6, 0xf7, 0x37, 0x96, 0xb4, 0x90, 0x9f, 0x94, 0x8a, 0x8f, + 0x8b, 0x8f, 0x8b, 0x08, 0xbf, 0x8d, 0x05, 0x0e, 0xe2, 0xf8, 0x21, 0xf7, + 0x6f, 0x15, 0x8f, 0xa1, 0x90, 0x9e, 0x8f, 0x9b, 0x08, 0x9a, 0xc3, 0x05, + 0x8d, 0x94, 0x8d, 0x92, 0x8c, 0x91, 0x9d, 0x90, 0x8c, 0x8b, 0xab, 0xbe, + 0x39, 0x89, 0x74, 0x8b, 0x80, 0x8b, 0x4e, 0x8a, 0x7a, 0x88, 0x6d, 0x79, + 0x5b, 0x6d, 0x69, 0x6f, 0x76, 0x70, 0x6d, 0x64, 0x67, 0xfb, 0x0d, 0x8b, + 0x4e, 0x08, 0x8b, 0x72, 0x91, 0x79, 0x9b, 0x75, 0x08, 0xfb, 0x07, 0x28, + 0x05, 0x59, 0x5f, 0x74, 0x6a, 0x8b, 0x6f, 0x8b, 0x66, 0xb7, 0x76, 0xd7, + 0x8b, 0xe7, 0x8b, 0xd3, 0xa5, 0xce, 0xc5, 0xb6, 0xb0, 0x95, 0xa0, 0xa0, + 0xee, 0x08, 0xbd, 0xf7, 0x75, 0x05, 0xfb, 0x17, 0xfb, 0xa6, 0x15, 0x7e, + 0x4f, 0x82, 0x74, 0x79, 0x78, 0x75, 0x72, 0x62, 0x7e, 0x50, 0x8b, 0x4a, + 0x8b, 0x68, 0x9d, 0x8b, 0xab, 0x8b, 0xb4, 0xa6, 0xa4, 0xf7, 0xaa, 0xf7, + 0x69, 0x08, 0x60, 0xfb, 0x51, 0x05, 0xf7, 0x09, 0xf8, 0x2e, 0x15, 0xab, + 0x06, 0x86, 0x87, 0x85, 0x86, 0x86, 0x88, 0x6b, 0x74, 0x84, 0x82, 0x82, + 0x73, 0x82, 0x6e, 0x80, 0x64, 0x7e, 0x5a, 0x77, 0x7e, 0x73, 0x79, 0x37, + 0x4c, 0x79, 0x9d, 0x84, 0x9b, 0x8b, 0xa3, 0x8b, 0xad, 0xa3, 0xe2, 0xa0, + 0xbb, 0x08, 0x9f, 0xb4, 0xa0, 0x95, 0xd4, 0x8b, 0x92, 0x8b, 0x97, 0x8b, + 0x98, 0x8c, 0x08, 0xa6, 0x06, 0x0e, 0xd6, 0x82, 0x15, 0xd2, 0xa8, 0xc6, + 0xf7, 0x7d, 0x05, 0x95, 0x92, 0x97, 0x92, 0x8d, 0x8c, 0xd0, 0xb7, 0xb5, + 0xa1, 0x96, 0x8b, 0x92, 0x8b, 0x90, 0x84, 0x8b, 0x82, 0x8b, 0x7f, 0x87, + 0x78, 0x7d, 0x55, 0x6c, 0xfb, 0x0c, 0x7f, 0x51, 0x8b, 0x70, 0x08, 0x8b, + 0x7f, 0x8f, 0x7f, 0x96, 0x78, 0xc2, 0xa7, 0xd3, 0xb9, 0xc2, 0xb3, 0x08, + 0x92, 0xa8, 0x05, 0x36, 0x59, 0x7d, 0x84, 0x7e, 0x8b, 0x82, 0x8b, 0x85, + 0x95, 0x8b, 0x9b, 0x8b, 0x9f, 0x91, 0xa8, 0x9c, 0xcc, 0xab, 0xf7, 0x0a, + 0x9b, 0xc8, 0x8b, 0x8f, 0x8b, 0x95, 0x83, 0x92, 0x7e, 0x8b, 0x76, 0x8b, + 0x46, 0x65, 0xfb, 0x11, 0x3a, 0x08, 0xad, 0xf7, 0x1a, 0x05, 0xa3, 0xed, + 0x95, 0xaa, 0x98, 0xa4, 0x99, 0xa7, 0xa0, 0x98, 0xa6, 0x8b, 0x98, 0x8b, + 0x93, 0x8a, 0xb2, 0x83, 0x08, 0xb6, 0xc8, 0x05, 0x79, 0x8f, 0x83, 0x8c, + 0x7c, 0x8b, 0x54, 0x8b, 0x6e, 0x7c, 0x42, 0x4b, 0x57, 0x5d, 0x83, 0x7a, + 0x6c, 0xfb, 0x18, 0x08, 0x2b, 0xfc, 0x31, 0x05, 0x0e, 0x42, 0xf7, 0x86, + 0xf8, 0x82, 0x15, 0xa8, 0xa5, 0x8d, 0x8d, 0xad, 0xa5, 0x85, 0x97, 0x86, + 0x93, 0x89, 0x8e, 0x85, 0x97, 0x8a, 0x8c, 0x83, 0x9e, 0x89, 0x8f, 0x89, + 0x8f, 0x89, 0x90, 0x86, 0x87, 0x85, 0x87, 0x88, 0x88, 0x87, 0x87, 0x83, + 0x85, 0x81, 0x83, 0x08, 0x86, 0x87, 0x84, 0x86, 0x82, 0x85, 0x87, 0x88, + 0x87, 0x88, 0x87, 0x89, 0x92, 0x75, 0x94, 0x7b, 0xa1, 0x6b, 0x08, 0xd0, + 0xfc, 0x0e, 0x15, 0x2c, 0x58, 0x89, 0x8a, 0x7e, 0x8b, 0x80, 0x8b, 0x84, + 0x96, 0x8b, 0x9c, 0x8b, 0x95, 0x8e, 0x9e, 0x91, 0xa1, 0xbe, 0xf7, 0x66, + 0x95, 0xb3, 0x8b, 0x93, 0x8b, 0x91, 0x86, 0x8f, 0x84, 0x8b, 0x7a, 0x8b, + 0x50, 0x6a, 0x39, 0x54, 0x08, 0x89, 0x6f, 0x05, 0xc6, 0xab, 0x90, 0x8d, + 0x94, 0x8b, 0x93, 0x8b, 0x8f, 0x85, 0x8b, 0x7f, 0x8b, 0x7e, 0x88, 0x7d, + 0x7c, 0x52, 0x5c, 0xfb, 0x43, 0x8b, 0x8b, 0x8b, 0x72, 0x8b, 0x73, 0x95, + 0x7b, 0x99, 0x8b, 0x9c, 0x8b, 0xa6, 0x98, 0xc0, 0xad, 0x08, 0x9e, 0x97, + 0x9e, 0x97, 0x9e, 0x98, 0x94, 0x90, 0x94, 0x91, 0x95, 0x91, 0x08, 0x8f, + 0xa7, 0x05, 0x0e, 0x2e, 0xf7, 0xc3, 0xf8, 0xb8, 0x15, 0x87, 0x91, 0x88, + 0x91, 0x8a, 0x8e, 0x85, 0x95, 0x87, 0x92, 0x89, 0x8e, 0x08, 0x82, 0x9f, + 0x86, 0x98, 0x85, 0x87, 0x83, 0x84, 0x05, 0x87, 0x88, 0x86, 0x87, 0x87, + 0x87, 0x82, 0x84, 0x89, 0x8a, 0x84, 0x86, 0x84, 0x85, 0x88, 0x89, 0x7d, + 0x82, 0x92, 0x75, 0x96, 0x77, 0x9f, 0x6f, 0xa3, 0xa1, 0x92, 0x91, 0x99, + 0x96, 0x08, 0x9f, 0x9a, 0x05, 0xfc, 0x48, 0xfd, 0xa9, 0x15, 0xa0, 0x86, + 0x95, 0x8a, 0x9d, 0x8b, 0xbc, 0x8b, 0xa4, 0x98, 0xbe, 0xbc, 0xe6, 0xe4, + 0x8e, 0x92, 0xc2, 0xf7, 0x6c, 0xc2, 0xf7, 0x71, 0x95, 0xb3, 0x8b, 0x96, + 0x8b, 0x92, 0x84, 0x90, 0x83, 0x8b, 0x7b, 0x8b, 0x8a, 0x8b, 0xfb, 0x21, + 0x33, 0x08, 0x89, 0x6e, 0x05, 0x9a, 0x93, 0x90, 0x8d, 0x9a, 0x94, 0xa2, + 0x98, 0x91, 0x8e, 0x92, 0x8b, 0x91, 0x8b, 0x91, 0x85, 0x8b, 0x85, 0x8b, + 0x7e, 0x73, 0xfb, 0x00, 0x74, 0x30, 0x48, 0xfb, 0x9e, 0x7f, 0x73, 0x46, + 0x8b, 0x7e, 0x8b, 0x89, 0x8b, 0x64, 0x8f, 0x08, 0x5c, 0x4f, 0x05, 0x0e, + 0xe2, 0x80, 0x15, 0x96, 0x8f, 0x95, 0x8f, 0x8e, 0x8c, 0x91, 0x8d, 0x95, + 0x8e, 0x96, 0x8f, 0x8e, 0x8c, 0x94, 0x8e, 0x95, 0x8e, 0x08, 0xb2, 0xf7, + 0x46, 0xa2, 0x99, 0xc3, 0xfb, 0x16, 0x05, 0xb6, 0x25, 0xa5, 0x62, 0xb4, + 0x6b, 0xb6, 0x6a, 0xc9, 0x76, 0xc0, 0x8b, 0xb9, 0x8b, 0xac, 0x95, 0xa9, + 0xa4, 0x08, 0x77, 0xd3, 0x05, 0x6b, 0x55, 0x6e, 0x76, 0x61, 0x8b, 0x60, + 0x8b, 0x60, 0xad, 0x69, 0xc8, 0x77, 0xb1, 0x8b, 0x8b, 0xfb, 0x06, 0xf7, + 0x85, 0x08, 0xce, 0xc8, 0x05, 0xb2, 0xae, 0x97, 0x92, 0x9e, 0x8b, 0x9c, + 0x8b, 0x97, 0x83, 0x9b, 0x76, 0x08, 0xbe, 0xd7, 0x05, 0x78, 0x9a, 0x7c, + 0x90, 0x75, 0x8b, 0x71, 0x8b, 0x79, 0x82, 0x6d, 0x6f, 0x6b, 0x6d, 0x8a, + 0x89, 0x81, 0x82, 0x08, 0xfb, 0x15, 0xfb, 0x07, 0xb1, 0xf7, 0x2d, 0x05, + 0xab, 0xf7, 0x18, 0x96, 0xab, 0x9c, 0xa7, 0x9d, 0xa8, 0xa5, 0x99, 0xad, + 0x8b, 0x95, 0x8b, 0x92, 0x8a, 0x9d, 0x88, 0x08, 0xb3, 0xc5, 0x05, 0x7e, + 0x8d, 0x84, 0x8c, 0x82, 0x8b, 0x67, 0x8b, 0x73, 0x83, 0x6c, 0x74, 0x4b, + 0x5e, 0x5e, 0x5f, 0x7e, 0x6e, 0x81, 0x75, 0x78, 0x49, 0x7e, 0x51, 0x08, + 0x32, 0xfc, 0x1b, 0x05, 0x0e, 0x42, 0xf7, 0xc7, 0xf7, 0x15, 0x15, 0x7d, + 0x83, 0x82, 0x85, 0x87, 0x89, 0x43, 0x5e, 0x83, 0x87, 0x7d, 0x8b, 0x08, + 0x82, 0x82, 0x97, 0x99, 0x1f, 0x8b, 0x94, 0x8b, 0x94, 0x05, 0x8b, 0x9d, + 0xb8, 0xf7, 0x56, 0xb0, 0xf7, 0x21, 0xb2, 0xf7, 0x27, 0x94, 0x9d, 0xb7, + 0x8b, 0x98, 0x8b, 0x95, 0x8a, 0xa5, 0x85, 0x08, 0xb6, 0xc0, 0x05, 0x76, + 0x90, 0x80, 0x8c, 0x7e, 0x8b, 0x63, 0x8b, 0x6b, 0x7b, 0x5b, 0x60, 0x5f, + 0x63, 0x80, 0x7c, 0x7e, 0x67, 0x83, 0x73, 0x75, 0x3a, 0x81, 0x5f, 0x08, + 0x43, 0xfb, 0xcd, 0x05, 0x8a, 0x85, 0x8a, 0x85, 0x8b, 0x85, 0x08, 0x6d, + 0x9c, 0x6c, 0x9b, 0x1e, 0x91, 0x8b, 0x8e, 0x8b, 0x05, 0x95, 0x8b, 0xb5, + 0xa8, 0xf7, 0x12, 0xe6, 0x08, 0xa1, 0x07, 0x0e, 0xf7, 0xc7, 0xf7, 0x37, + 0x9c, 0x15, 0xcb, 0xf7, 0x87, 0x05, 0xce, 0xb8, 0xb4, 0xa3, 0x98, 0x8b, + 0x93, 0x8b, 0x90, 0x82, 0x8b, 0x7e, 0x8b, 0x6d, 0x65, 0xfb, 0x2c, 0x61, + 0xfb, 0x1b, 0x08, 0xd7, 0xa6, 0xc9, 0xf7, 0x8e, 0x05, 0xc5, 0xb0, 0xc1, + 0xa9, 0x97, 0x8b, 0x93, 0x8b, 0x90, 0x84, 0x8b, 0x7f, 0x8b, 0x75, 0x82, + 0x62, 0x70, 0x20, 0x7b, 0x4d, 0x86, 0x72, 0x8b, 0x74, 0x8b, 0x76, 0x91, + 0x80, 0x9d, 0x7e, 0xc6, 0xa8, 0xbd, 0xab, 0xc8, 0xbb, 0x08, 0xa2, 0x07, + 0x81, 0x86, 0x80, 0x84, 0x7e, 0x82, 0x67, 0x74, 0x7a, 0x83, 0x7f, 0x8b, + 0x80, 0x8b, 0x84, 0x95, 0x8b, 0x9c, 0x8b, 0xa1, 0x98, 0xc4, 0x9f, 0xd1, + 0xa9, 0xf2, 0x93, 0xab, 0x8b, 0x9a, 0x8b, 0x95, 0x85, 0x90, 0x81, 0x8b, + 0x08, 0x79, 0x8b, 0x4d, 0x6b, 0xfb, 0x0e, 0x43, 0x8e, 0x96, 0x8c, 0x93, + 0x8c, 0x8f, 0x97, 0xbd, 0x8e, 0x99, 0x8b, 0x91, 0x8b, 0x92, 0x86, 0x8f, + 0x83, 0x8b, 0x7c, 0x8b, 0x57, 0x6f, 0x27, 0x4b, 0x08, 0x6b, 0x77, 0x05, + 0x9d, 0xd4, 0x8f, 0x9d, 0x8b, 0x92, 0x8b, 0x93, 0x85, 0x91, 0x82, 0x8b, + 0x7f, 0x8b, 0x3c, 0x60, 0x4a, 0x62, 0x08, 0x84, 0x6f, 0x05, 0xc2, 0xa6, + 0x93, 0x8e, 0x96, 0x8b, 0x94, 0x8b, 0x91, 0x83, 0x8b, 0x80, 0x8b, 0x7b, + 0x67, 0xfb, 0x28, 0x61, 0xfb, 0x30, 0x08, 0xd2, 0xa6, 0x05, 0x0e, 0xf7, + 0x27, 0xf7, 0x38, 0x9e, 0x15, 0xc6, 0xf7, 0x7f, 0x05, 0xf7, 0x11, 0xda, + 0x8e, 0x8c, 0x99, 0x8b, 0x92, 0x8b, 0x8f, 0x86, 0x8b, 0x83, 0x8b, 0x7c, + 0x83, 0x65, 0x6e, 0xfb, 0x06, 0x75, 0x32, 0x87, 0x7a, 0x8b, 0x78, 0x8b, + 0x7d, 0x8f, 0x7e, 0x96, 0x79, 0xb9, 0xa0, 0xd0, 0xb6, 0xd1, 0xbf, 0x08, + 0x92, 0xa7, 0x05, 0x27, 0x52, 0x87, 0x89, 0x81, 0x8b, 0x81, 0x8b, 0x85, + 0x96, 0x8b, 0x9b, 0x8b, 0xa0, 0x92, 0xac, 0x9e, 0xd0, 0xba, 0xf7, 0x3c, + 0x8b, 0x8b, 0x8b, 0x92, 0x8b, 0x96, 0x84, 0x91, 0x7e, 0x8b, 0x7c, 0x8b, + 0x75, 0x82, 0x67, 0x74, 0x08, 0xfb, 0x1d, 0x36, 0x05, 0x94, 0xac, 0x9a, + 0xca, 0x8b, 0x93, 0x8b, 0x92, 0x85, 0x91, 0x84, 0x8b, 0x80, 0x8b, 0x43, + 0x66, 0x41, 0x5f, 0x08, 0x85, 0x71, 0x05, 0xcb, 0xa8, 0x8f, 0x8c, 0x94, + 0x8b, 0x92, 0x8b, 0x90, 0x85, 0x8b, 0x83, 0x8b, 0x76, 0x78, 0x38, 0x72, + 0x30, 0x08, 0x74, 0x3a, 0x05, 0x89, 0x84, 0x86, 0x78, 0x84, 0x6f, 0x08, + 0xd6, 0xa8, 0x05, 0x0e, 0xe2, 0xf7, 0xfb, 0xf8, 0x2f, 0x15, 0x63, 0x8b, + 0x4b, 0x6e, 0x50, 0x5f, 0x4b, 0x5b, 0x5e, 0x23, 0x8b, 0x28, 0x8b, 0x4e, + 0xad, 0x64, 0xc0, 0x8b, 0xa7, 0x8b, 0xa7, 0x95, 0xb9, 0xa3, 0xbd, 0xa7, + 0xac, 0xa4, 0x9d, 0xa3, 0xb3, 0xc1, 0xab, 0xed, 0x8b, 0xd0, 0x08, 0xc1, + 0x66, 0xb1, 0x56, 0x1e, 0x57, 0x5c, 0x15, 0xb3, 0xa4, 0x64, 0x4f, 0x1f, + 0x8b, 0x61, 0x7d, 0x57, 0x72, 0x5a, 0x6f, 0x52, 0x67, 0x6c, 0x65, 0x8b, + 0x08, 0x62, 0x71, 0xb0, 0xc4, 0xf7, 0x08, 0xd4, 0xf7, 0x0c, 0xd1, 0x1f, + 0x0e, 0xa1, 0xfb, 0x69, 0x15, 0x6d, 0x6b, 0x05, 0xa8, 0x8a, 0xf7, 0x03, + 0x89, 0xa9, 0x8b, 0x93, 0x8b, 0x99, 0x8b, 0xa4, 0x8c, 0x08, 0xaa, 0xa4, + 0xfb, 0x04, 0x91, 0xbb, 0xf7, 0x69, 0x05, 0x9f, 0x87, 0x96, 0x8a, 0x9c, + 0x8b, 0xb7, 0x8b, 0xa3, 0x94, 0xb3, 0xab, 0xbe, 0xb2, 0x9e, 0x9d, 0x98, + 0x9d, 0xae, 0xbe, 0xab, 0xf6, 0x8b, 0xcc, 0x8b, 0xbb, 0x76, 0xab, 0x6a, + 0x8b, 0x73, 0x8b, 0x69, 0x7c, 0x62, 0x6d, 0x08, 0x39, 0x50, 0x05, 0x8e, + 0x96, 0x8d, 0x96, 0x8d, 0x91, 0x94, 0xb1, 0x90, 0xa0, 0x8b, 0x8f, 0x8b, + 0x91, 0x84, 0x92, 0x84, 0x8b, 0x81, 0x8b, 0x3a, 0x60, 0x41, 0x5f, 0x08, + 0x85, 0x71, 0x05, 0x98, 0x90, 0x97, 0x90, 0x8f, 0x8d, 0xa8, 0x98, 0x91, + 0x8d, 0x93, 0x8b, 0x97, 0x8b, 0x92, 0x81, 0x8b, 0x79, 0x8b, 0x67, 0x4f, + 0xfb, 0x98, 0x53, 0xfb, 0x68, 0x08, 0x67, 0x89, 0x05, 0xf7, 0x3f, 0xf7, + 0xab, 0x15, 0x99, 0xce, 0x98, 0xc2, 0x95, 0xb6, 0x8c, 0x90, 0x8e, 0x98, + 0x8f, 0x9d, 0xde, 0xc7, 0xa9, 0x9c, 0xa5, 0x8b, 0x9f, 0x8b, 0x98, 0x75, + 0x8b, 0x6a, 0x8b, 0x5e, 0x7d, 0x53, 0x72, 0x54, 0x70, 0x50, 0x69, 0x6d, + 0x62, 0x8b, 0x08, 0x72, 0x8b, 0x70, 0x93, 0x73, 0x99, 0x08, 0x0e, 0xe2, + 0xf7, 0x37, 0xfb, 0x67, 0x15, 0x6a, 0x6a, 0x05, 0xbc, 0x88, 0xd1, 0x89, + 0xbe, 0x8b, 0x99, 0x8b, 0xa4, 0x8c, 0xaa, 0x8c, 0x08, 0xaa, 0xa3, 0x29, + 0x91, 0x05, 0x8e, 0x9c, 0x8f, 0x9b, 0x8e, 0x9b, 0x08, 0xa4, 0xf6, 0xda, + 0xf7, 0xe9, 0xa0, 0xd8, 0xba, 0xb7, 0x05, 0x86, 0x8c, 0x86, 0x8d, 0x8a, + 0x8b, 0x08, 0x7e, 0x8f, 0x05, 0x8a, 0x8b, 0x87, 0x8c, 0x86, 0x8c, 0x08, + 0x9f, 0xcd, 0x81, 0x8e, 0x05, 0x6e, 0x6c, 0x7a, 0x7a, 0x72, 0x76, 0x81, + 0x8c, 0x81, 0x8b, 0x87, 0x8b, 0x6a, 0x8b, 0x66, 0x86, 0x7a, 0x85, 0x72, + 0x81, 0x52, 0x63, 0x6d, 0x6e, 0x66, 0x67, 0x60, 0xfb, 0x1c, 0x8b, 0x3a, + 0x8b, 0x65, 0xa3, 0x60, 0xa0, 0x8b, 0x08, 0x9a, 0x8b, 0xb9, 0xa6, 0xdc, + 0xc6, 0x9d, 0x98, 0x96, 0x93, 0x8f, 0x8d, 0x86, 0x79, 0x88, 0x7e, 0x8a, + 0x89, 0x76, 0x2d, 0x7d, 0x51, 0x85, 0x73, 0x08, 0x72, 0x29, 0x73, 0x8b, + 0x72, 0x8b, 0x77, 0x8b, 0x05, 0xf7, 0x2e, 0xf7, 0xf0, 0x15, 0x2b, 0x4d, + 0x79, 0x80, 0x7e, 0x8b, 0x79, 0x8b, 0x7e, 0xa2, 0x8b, 0xa9, 0x8b, 0xb2, + 0x96, 0xbe, 0x9f, 0xca, 0xa3, 0xd1, 0x9f, 0x9a, 0xd8, 0x8b, 0xa0, 0x8b, + 0x97, 0x8a, 0xa5, 0x88, 0x08, 0x56, 0xfb, 0x6a, 0x05, 0x0e, 0x7e, 0xe5, + 0x81, 0x15, 0xd8, 0xa8, 0xd6, 0xf7, 0xb1, 0x05, 0xad, 0xa4, 0xa2, 0x95, + 0xa6, 0x8b, 0xa1, 0x8b, 0x98, 0x83, 0x9d, 0x74, 0x08, 0xa9, 0xea, 0x05, + 0x78, 0x91, 0x83, 0x8d, 0x81, 0x8b, 0x79, 0x8b, 0x76, 0x82, 0x70, 0x78, + 0x08, 0x50, 0x60, 0x05, 0x8c, 0x93, 0x8d, 0x90, 0x8b, 0x8e, 0x93, 0xac, + 0x8c, 0x91, 0x8b, 0x90, 0x8b, 0x91, 0x85, 0x90, 0x84, 0x8b, 0x7e, 0x8b, + 0x33, 0x60, 0x4e, 0x66, 0x08, 0x88, 0x70, 0x05, 0xc1, 0xa7, 0x91, 0x8d, + 0x97, 0x8b, 0x98, 0x8b, 0x91, 0x84, 0x8b, 0x7d, 0x8b, 0x7d, 0x81, 0x5c, + 0x7f, 0x60, 0x08, 0x4f, 0xfb, 0x6f, 0x05, 0x0e, 0x92, 0xb6, 0xde, 0x15, + 0x8a, 0x82, 0x8a, 0x83, 0x8b, 0x85, 0x8b, 0x60, 0xa9, 0x6d, 0xb7, 0x8b, + 0xaa, 0x8b, 0xb6, 0x98, 0xab, 0x9d, 0xc6, 0xad, 0xaf, 0xbe, 0x8b, 0xbd, + 0x8b, 0xb0, 0x84, 0x93, 0x53, 0xae, 0x69, 0xa1, 0x7d, 0x9e, 0x8b, 0xa5, + 0x08, 0xad, 0xa8, 0xa9, 0xad, 0x1e, 0xa2, 0x8b, 0x9c, 0x80, 0xa1, 0x6f, + 0xad, 0xac, 0x8b, 0x8b, 0x98, 0x9e, 0x77, 0xa3, 0x78, 0x95, 0x6f, 0x8b, + 0x42, 0x8b, 0x2d, 0x34, 0x8b, 0x49, 0x8b, 0x6c, 0x9b, 0x73, 0xb1, 0x70, + 0xbd, 0x68, 0x92, 0x82, 0x8b, 0x72, 0x08, 0x67, 0x5d, 0x61, 0x64, 0x1e, + 0x75, 0x8b, 0x7a, 0x97, 0x81, 0xa1, 0x84, 0x9a, 0x89, 0x9a, 0x8a, 0xad, + 0x80, 0x83, 0x83, 0x86, 0x87, 0x88, 0x83, 0x86, 0x82, 0x86, 0x82, 0x85, + 0x08, 0x79, 0x7f, 0x05, 0x0e, 0x92, 0xf7, 0xff, 0xf7, 0x12, 0x15, 0x3f, + 0x5e, 0x6b, 0x7a, 0x7d, 0x8b, 0x7e, 0x8b, 0x7b, 0xa5, 0x8b, 0xa0, 0x8b, + 0x99, 0x9c, 0xd8, 0xa5, 0xf4, 0x99, 0x8c, 0x95, 0x8b, 0x90, 0x8b, 0x08, + 0xb3, 0x8c, 0x05, 0x8f, 0x8b, 0x95, 0x8c, 0x9b, 0x8d, 0x08, 0xb1, 0xa8, + 0xfb, 0x14, 0x8b, 0xb3, 0xf7, 0x36, 0x05, 0x78, 0x81, 0x83, 0x88, 0x7c, + 0x84, 0x84, 0x87, 0x83, 0x88, 0x83, 0x87, 0x87, 0x89, 0x86, 0x89, 0x86, + 0x89, 0x08, 0x6f, 0xfb, 0x11, 0x05, 0x82, 0x8a, 0x85, 0x8b, 0x88, 0x8b, + 0x08, 0x73, 0x06, 0x89, 0x8b, 0x86, 0x8b, 0x83, 0x8a, 0x80, 0x84, 0x8a, + 0x8b, 0x7a, 0x7d, 0x88, 0x89, 0x86, 0x87, 0x84, 0x86, 0x08, 0xa3, 0x8b, + 0xb9, 0x8b, 0xa1, 0x8b, 0x05, 0x56, 0xfb, 0x72, 0x8b, 0x8b, 0x8b, 0x6c, + 0x8b, 0x6b, 0xa0, 0x68, 0x9e, 0x8b, 0xa1, 0x8b, 0xcf, 0xb5, 0xeb, 0xd3, + 0x08, 0x8d, 0xa4, 0x05, 0x0e, 0xf7, 0x27, 0xdd, 0xf7, 0xc0, 0x15, 0xb5, + 0xa0, 0x9e, 0x93, 0x97, 0x8b, 0x93, 0x8b, 0x91, 0x83, 0x8b, 0x80, 0x8b, + 0x7e, 0x81, 0x60, 0x79, 0x47, 0x72, 0x2e, 0x85, 0x6f, 0x8b, 0x6e, 0x8b, + 0x6f, 0x97, 0x76, 0x9b, 0x8b, 0x9a, 0x8b, 0x9d, 0x94, 0xbd, 0xac, 0x08, + 0xf2, 0xce, 0x05, 0x83, 0x6b, 0x85, 0x67, 0x8b, 0x79, 0x8b, 0x7e, 0x93, + 0x81, 0x95, 0x8b, 0x9f, 0x8b, 0xea, 0xc3, 0xcf, 0xbe, 0x08, 0x92, 0xa9, + 0x05, 0x3d, 0x5d, 0x71, 0x7d, 0x80, 0x8b, 0x84, 0x8b, 0x87, 0x93, 0x8b, + 0x9b, 0x8b, 0xbe, 0xb0, 0xf7, 0x29, 0xb6, 0xf7, 0x13, 0x7e, 0x84, 0x82, + 0x86, 0x87, 0x89, 0x7f, 0x85, 0x7f, 0x85, 0x7e, 0x85, 0x88, 0x8a, 0x85, + 0x88, 0x80, 0x85, 0x08, 0x85, 0x74, 0x77, 0x3b, 0x6a, 0xfb, 0x1e, 0x3e, + 0x56, 0x68, 0x77, 0x7f, 0x8b, 0x80, 0x8b, 0x83, 0x99, 0x8b, 0x9e, 0x8b, + 0xa2, 0x93, 0xb3, 0x9c, 0xcb, 0x96, 0xb3, 0x92, 0xa7, 0x8e, 0x99, 0x94, + 0xb0, 0x92, 0xa5, 0x8d, 0x92, 0x08, 0x8e, 0x96, 0x8d, 0x94, 0x8b, 0x92, + 0x8b, 0x93, 0x86, 0x90, 0x84, 0x8b, 0x81, 0x8b, 0x42, 0x64, 0x43, 0x5e, + 0x08, 0x84, 0x70, 0x05, 0x0e, 0xf3, 0xf7, 0x6b, 0x15, 0x90, 0x9a, 0x90, + 0x99, 0x8c, 0x90, 0xa1, 0xca, 0x92, 0x91, 0xc1, 0x8a, 0xb3, 0x8c, 0x96, + 0x8c, 0xa3, 0x90, 0x51, 0x4a, 0x7a, 0x76, 0x7d, 0x74, 0x6e, 0x5b, 0x7a, + 0x52, 0x8b, 0x5a, 0x8b, 0x5d, 0xa0, 0x6f, 0xac, 0x8b, 0x08, 0xda, 0x8b, + 0xf3, 0xde, 0xd0, 0xf7, 0x0a, 0xb2, 0xcd, 0xa6, 0xdb, 0x8b, 0xbc, 0x8b, + 0xa2, 0x84, 0x9a, 0x78, 0x9b, 0x73, 0x84, 0x7f, 0x86, 0x6c, 0x7c, 0x97, + 0x70, 0x8f, 0x7b, 0x8b, 0x71, 0x8b, 0x4e, 0x79, 0x4b, 0x69, 0x51, 0x08, + 0x64, 0x49, 0x54, 0x5b, 0x66, 0x8b, 0x75, 0x8b, 0x79, 0xa5, 0x8b, 0xad, + 0x8b, 0xb9, 0x9b, 0xc2, 0xa7, 0xbe, 0x9f, 0xae, 0x9e, 0xa5, 0xba, 0xc1, + 0x8c, 0x8e, 0x8b, 0x8e, 0x8b, 0x8c, 0x8b, 0x8e, 0x8b, 0x8c, 0x89, 0x92, + 0x08, 0x81, 0x06, 0x80, 0x7e, 0x80, 0x88, 0x6b, 0x8b, 0x08, 0x73, 0x06, + 0x4d, 0x8e, 0x81, 0x8b, 0x83, 0x8b, 0x78, 0x8b, 0x81, 0x88, 0x85, 0x83, + 0x7e, 0x7b, 0x7b, 0x61, 0x77, 0x44, 0x08, 0x9c, 0x76, 0x05, 0x0e, 0xf8, + 0x03, 0xf3, 0xf7, 0x64, 0x15, 0x9e, 0xbb, 0x90, 0x98, 0x92, 0x98, 0x9b, + 0xa5, 0x9d, 0x97, 0xa4, 0x8b, 0x90, 0x8b, 0x98, 0x8b, 0x9a, 0x8a, 0x08, + 0x93, 0x8a, 0x94, 0x8b, 0x94, 0x8b, 0xa0, 0x8b, 0x92, 0x8c, 0x9d, 0x92, + 0x08, 0x69, 0x65, 0x05, 0x60, 0x5c, 0x7d, 0x79, 0x79, 0x6a, 0x71, 0x5c, + 0x7b, 0x56, 0x8b, 0x61, 0x8b, 0x67, 0xa1, 0x72, 0xab, 0x8b, 0xbf, 0x8b, + 0xc6, 0xb5, 0xde, 0xe9, 0x80, 0x6a, 0x87, 0x77, 0x8b, 0x71, 0x08, 0x67, + 0x9f, 0x76, 0xad, 0xf7, 0x12, 0xf7, 0x58, 0xf7, 0x88, 0xf7, 0x32, 0x1e, + 0x8b, 0xa6, 0x83, 0x9c, 0x7a, 0x96, 0x72, 0x84, 0x82, 0x88, 0x67, 0x7b, + 0x95, 0x71, 0x8e, 0x7a, 0x8b, 0x70, 0x8b, 0x49, 0x72, 0x3d, 0x62, 0x4b, + 0x68, 0x55, 0x58, 0x61, 0x6c, 0x8b, 0x77, 0x8b, 0x7d, 0x9e, 0x8b, 0xa6, + 0x08, 0x8b, 0xb6, 0x9a, 0xbf, 0xcd, 0xf7, 0x5a, 0x70, 0x82, 0x80, 0x88, + 0x67, 0x82, 0x85, 0x78, 0x87, 0x7d, 0x88, 0x82, 0x67, 0xfb, 0x0c, 0x81, + 0x75, 0x6c, 0x63, 0x08, 0x65, 0x59, 0x55, 0x64, 0x6c, 0x8b, 0x7a, 0x8b, + 0x81, 0x9c, 0x8b, 0xa6, 0x8b, 0xb6, 0x9c, 0xc3, 0xa7, 0xbe, 0xa4, 0xb6, + 0xa1, 0xa7, 0xc3, 0xc3, 0x08, 0x95, 0x07, 0x8b, 0x8d, 0x8b, 0x8d, 0x8a, + 0x8f, 0x08, 0x80, 0x06, 0x7b, 0x7f, 0x83, 0x89, 0x7a, 0x8b, 0x6e, 0x8b, + 0x4f, 0x8c, 0x72, 0x8c, 0x08, 0x80, 0x8c, 0x82, 0x8b, 0x84, 0x8b, 0x7a, + 0x8b, 0x80, 0x88, 0x85, 0x84, 0x7c, 0x7c, 0x77, 0x5d, 0x74, 0x41, 0x08, + 0x9c, 0x73, 0x05, 0x0e, 0xf6, 0xf2, 0x72, 0x15, 0x8d, 0x8a, 0x8d, 0x8b, + 0x8c, 0x8b, 0x8d, 0x8a, 0x8d, 0x8b, 0x8b, 0x8b, 0x8d, 0x8b, 0x8e, 0x8c, + 0x8e, 0x8c, 0xa0, 0xe3, 0xb6, 0xcd, 0xd4, 0xc6, 0x97, 0xfb, 0x2f, 0x90, + 0x65, 0x9a, 0x5d, 0xa1, 0x48, 0xcc, 0x61, 0xde, 0x8b, 0x08, 0xc3, 0x8b, + 0xae, 0x99, 0xac, 0xad, 0x08, 0x64, 0xba, 0x05, 0x70, 0x5b, 0x70, 0x77, + 0x67, 0x8b, 0x5b, 0x8b, 0x6a, 0xb3, 0x76, 0xde, 0x81, 0xb2, 0x83, 0xbe, + 0x75, 0xf7, 0x31, 0xdf, 0xd9, 0xad, 0xa3, 0xa6, 0x8b, 0x96, 0x8b, 0x95, + 0x89, 0xa0, 0x82, 0x08, 0xa1, 0xd1, 0x05, 0x7c, 0x95, 0x84, 0x8e, 0x7e, + 0x8b, 0x7f, 0x8b, 0x82, 0x89, 0x7a, 0x83, 0x6f, 0x72, 0x86, 0x86, 0x65, + 0x66, 0x08, 0x45, 0x48, 0x05, 0x87, 0xb0, 0x85, 0xb0, 0x88, 0x99, 0x08, + 0x82, 0xb4, 0x7d, 0x9a, 0x6b, 0x8b, 0x6c, 0x8b, 0x6e, 0x7a, 0x46, 0x4f, + 0x08, 0x89, 0x70, 0x05, 0xc7, 0xb3, 0x90, 0x8d, 0x9f, 0x8b, 0xac, 0x8b, + 0x97, 0x71, 0x9a, 0x22, 0x08, 0x66, 0x6d, 0x05, 0x37, 0x4b, 0x8a, 0x8b, + 0x78, 0x79, 0x79, 0x78, 0x84, 0x7d, 0x7a, 0x5d, 0x08, 0xac, 0x57, 0x05, + 0x0e, 0xe2, 0x96, 0xfb, 0x85, 0x15, 0xaa, 0x87, 0xb7, 0x88, 0xae, 0x8b, + 0xd1, 0x8b, 0xb3, 0x9e, 0xc4, 0xc8, 0xc5, 0xc9, 0x8f, 0x96, 0xae, 0xf7, + 0x37, 0xae, 0xf7, 0x35, 0x9e, 0xd6, 0xad, 0xf7, 0x03, 0x7e, 0x84, 0x80, + 0x85, 0x87, 0x89, 0x08, 0x68, 0x7a, 0x05, 0x86, 0x88, 0x83, 0x88, 0x82, + 0x86, 0x08, 0x4e, 0xfb, 0x87, 0x05, 0x27, 0x4d, 0x86, 0x88, 0x7a, 0x8b, + 0x7e, 0x8b, 0x82, 0x99, 0x8b, 0x9d, 0x8b, 0xa1, 0x94, 0xb9, 0x9e, 0xd2, + 0xa4, 0xee, 0x99, 0xc3, 0x8b, 0x94, 0x8b, 0x92, 0x86, 0x90, 0x85, 0x8b, + 0x80, 0x8b, 0x4b, 0x69, 0x37, 0x59, 0x08, 0x88, 0x70, 0x05, 0xba, 0xa3, + 0x96, 0x90, 0x96, 0x8b, 0x95, 0x8b, 0x90, 0x85, 0x8b, 0x82, 0x8b, 0x79, + 0x84, 0x6d, 0x73, 0x33, 0x73, 0x34, 0x86, 0x75, 0x8b, 0x71, 0x8b, 0x6b, + 0x9a, 0x73, 0x9f, 0x8b, 0x9e, 0x8b, 0xdb, 0xbb, 0xe4, 0xcb, 0x08, 0x65, + 0xfb, 0x4b, 0x8b, 0x8b, 0x7f, 0x66, 0x7b, 0x58, 0x6b, 0x78, 0x4a, 0x8b, + 0x6e, 0x8b, 0x75, 0x8f, 0x50, 0x99, 0x08, 0x63, 0x47, 0x05, 0x0e, 0xb9, + 0xb0, 0x15, 0x8b, 0x86, 0x8c, 0x86, 0x8d, 0x82, 0x9e, 0x97, 0x93, 0x90, + 0xa0, 0x97, 0x99, 0x86, 0x98, 0x87, 0x90, 0x8a, 0x8c, 0x8b, 0xb9, 0x7b, + 0x9f, 0x83, 0xc1, 0x78, 0xa9, 0x84, 0xa3, 0x8b, 0xae, 0x8b, 0xa4, 0x99, + 0xbb, 0xba, 0x08, 0xb4, 0xb2, 0x9a, 0xa3, 0x8b, 0xa4, 0x8b, 0x98, 0x88, + 0x95, 0x80, 0xa1, 0x82, 0x85, 0x82, 0x85, 0x81, 0x85, 0x7e, 0x83, 0x89, + 0x8a, 0x7b, 0x7f, 0x94, 0x77, 0x8d, 0x82, 0x8b, 0x7f, 0x8b, 0x6b, 0x71, + 0x72, 0x6b, 0x8b, 0x08, 0x68, 0x8b, 0x6f, 0x94, 0xfb, 0x09, 0xbf, 0x08, + 0xb6, 0xb5, 0xf7, 0x77, 0xf7, 0x6e, 0xaf, 0xb0, 0x8b, 0x92, 0x05, 0x8c, + 0x91, 0x8b, 0x90, 0x8b, 0x8d, 0x08, 0x8f, 0x07, 0x62, 0x6f, 0x84, 0x89, + 0x57, 0x8b, 0x73, 0x8b, 0x29, 0x8d, 0x7c, 0x8c, 0x08, 0x83, 0x06, 0x6f, + 0x8b, 0x89, 0x89, 0x5b, 0xfb, 0x14, 0x08, 0x9d, 0x78, 0x99, 0xa8, 0x05, + 0xa0, 0xba, 0x95, 0x93, 0xb6, 0x8d, 0x08, 0xd0, 0x8c, 0x05, 0xa5, 0x8c, + 0x8c, 0x8b, 0xa0, 0x90, 0x33, 0x36, 0x23, 0x2c, 0xfb, 0x1d, 0xfb, 0x0c, + 0x08, 0x85, 0x07, 0x0e, 0x42, 0xf7, 0xde, 0xf8, 0xb6, 0x15, 0x99, 0xc5, + 0x9f, 0xa7, 0xaf, 0x94, 0x08, 0x90, 0x9f, 0x05, 0x3f, 0x8b, 0x6a, 0x6f, + 0x75, 0x38, 0x08, 0x54, 0xfb, 0x62, 0x05, 0x7f, 0x5c, 0x72, 0x74, 0x58, + 0x7f, 0x08, 0x86, 0x77, 0x05, 0xa9, 0x81, 0x9d, 0x74, 0x8b, 0x6f, 0x8b, + 0x85, 0x8a, 0x87, 0x86, 0x78, 0x08, 0x54, 0xfb, 0x62, 0x05, 0x87, 0x7c, + 0x87, 0x6f, 0x8b, 0x7e, 0x8b, 0x79, 0x94, 0x7b, 0x9b, 0x81, 0x99, 0x83, + 0x9a, 0x88, 0xae, 0x8b, 0x08, 0x90, 0x9f, 0x05, 0x6e, 0x94, 0x83, 0x97, + 0x8b, 0xaa, 0x8b, 0x9b, 0x8b, 0x8b, 0x94, 0xa5, 0x08, 0xc0, 0xf7, 0x5d, + 0x05, 0x90, 0x9b, 0x8d, 0x99, 0x8b, 0x95, 0x8b, 0xab, 0x7f, 0x9b, 0x6b, + 0x98, 0xc0, 0x9c, 0xa4, 0xa5, 0x97, 0xbf, 0x08, 0xc0, 0xf7, 0x5c, 0x05, + 0x0e, 0xf7, 0x63, 0xf7, 0xff, 0xf9, 0x66, 0x15, 0x5a, 0xfd, 0x66, 0xbc, + 0xf9, 0x66, 0x06, 0x0e, 0x42, 0xde, 0x58, 0x15, 0x7e, 0x51, 0x77, 0x6f, + 0x68, 0x83, 0x08, 0x86, 0x77, 0x05, 0xd6, 0x8a, 0xab, 0xa7, 0xa1, 0xdf, + 0x08, 0xc2, 0xf7, 0x62, 0x05, 0x97, 0xba, 0xa4, 0xa2, 0xbe, 0x96, 0x08, + 0x90, 0x9f, 0x05, 0x6d, 0x96, 0x79, 0xa1, 0x8b, 0xa7, 0x8b, 0x92, 0x8c, + 0x8f, 0x90, 0x9e, 0x08, 0xc2, 0xf7, 0x62, 0x05, 0x8f, 0x9a, 0x8f, 0xa6, + 0x8b, 0x98, 0x8b, 0x9e, 0x82, 0x9b, 0x7b, 0x94, 0x7d, 0x94, 0x7c, 0x8d, + 0x68, 0x8c, 0x08, 0x86, 0x77, 0x05, 0xa8, 0x81, 0x93, 0x80, 0x8b, 0x6c, + 0x8b, 0x7b, 0x8b, 0x8b, 0x82, 0x70, 0x08, 0x56, 0xfb, 0x5c, 0x05, 0x86, + 0x7a, 0x89, 0x7e, 0x8b, 0x81, 0x8b, 0x6b, 0x97, 0x7b, 0xab, 0x7d, 0x56, + 0x7b, 0x72, 0x70, 0x7f, 0x58, 0x08, 0x56, 0xfb, 0x5d, 0x05, 0x0e, 0xf7, + 0x63, 0xf8, 0x80, 0xf7, 0xaa, 0x15, 0x6c, 0x61, 0x72, 0x79, 0x6e, 0x8b, + 0x7a, 0x8b, 0x77, 0x91, 0x68, 0x99, 0x08, 0x52, 0xa3, 0x05, 0x74, 0x95, + 0x71, 0x91, 0x79, 0x8b, 0x5a, 0x8b, 0x69, 0x72, 0x61, 0x49, 0x08, 0xaf, + 0x75, 0x05, 0xb1, 0xbd, 0x9b, 0x96, 0xac, 0x8b, 0x9d, 0x8b, 0x9d, 0x86, + 0xa9, 0x7f, 0x08, 0xba, 0x77, 0x05, 0xa4, 0x81, 0xb1, 0x83, 0xa2, 0x8b, + 0xb5, 0x8b, 0xbb, 0xad, 0xa7, 0xbc, 0x08, 0x69, 0xa3, 0x05, 0x0e, 0x6a, + 0xf7, 0xbb, 0xf7, 0xe0, 0x15, 0x82, 0xa2, 0x78, 0xaa, 0x78, 0xa2, 0x66, + 0x71, 0x82, 0x83, 0x6f, 0x6f, 0x8e, 0x85, 0x8f, 0x86, 0x8e, 0x86, 0x98, + 0x79, 0x8b, 0x8b, 0x90, 0x83, 0x8f, 0x83, 0x8d, 0x89, 0x98, 0x75, 0x92, + 0x91, 0x90, 0x8e, 0x8d, 0x8d, 0x08, 0x9d, 0x9a, 0x96, 0x94, 0x8f, 0x8e, + 0x94, 0x92, 0x8f, 0x8f, 0x99, 0x95, 0x08, 0xfb, 0x13, 0xfb, 0x47, 0x15, + 0x81, 0x6e, 0x82, 0x6e, 0x82, 0x6e, 0x85, 0x7a, 0x59, 0xfb, 0x2d, 0x70, + 0x39, 0x08, 0xe4, 0xb5, 0x05, 0xa1, 0xde, 0x9c, 0xcd, 0xc5, 0xf7, 0x84, + 0x08, 0x54, 0x6a, 0x77, 0x50, 0x05, 0x0e, 0xf8, 0x34, 0xf7, 0x56, 0x15, + 0x42, 0x50, 0x6e, 0x7c, 0x5b, 0x87, 0xa4, 0xf7, 0x08, 0xb2, 0xf7, 0x31, + 0x9f, 0xd3, 0xa1, 0x84, 0x94, 0x75, 0x8b, 0x62, 0x08, 0xd3, 0xb9, 0x05, + 0x7f, 0xb3, 0x72, 0xa0, 0x67, 0x8b, 0x86, 0x8b, 0x81, 0x8a, 0x82, 0x8a, + 0xa3, 0xee, 0x8d, 0x8f, 0x9a, 0xbf, 0x08, 0x77, 0x82, 0x05, 0x84, 0x89, + 0x88, 0x89, 0x81, 0x88, 0x88, 0x7a, 0x88, 0x7c, 0x8a, 0x86, 0x8a, 0x85, + 0x86, 0x73, 0x83, 0x69, 0x89, 0x84, 0x87, 0x7a, 0x87, 0x77, 0x57, 0x76, + 0x6f, 0x77, 0x6b, 0x65, 0x56, 0x4f, 0x69, 0x30, 0x8b, 0x3d, 0x08, 0x8b, + 0x3e, 0xa8, 0x68, 0xcd, 0x89, 0x85, 0x75, 0x87, 0x7d, 0x89, 0x85, 0x08, + 0x6d, 0x25, 0x05, 0x91, 0x8e, 0x90, 0x8e, 0x91, 0x8f, 0x92, 0x8e, 0x91, + 0x8f, 0x91, 0x8e, 0x8d, 0x8c, 0x91, 0x8f, 0x92, 0x8f, 0x8f, 0x9f, 0x8d, + 0x98, 0x8d, 0x91, 0x8e, 0x9a, 0x8e, 0x9a, 0x8f, 0x9a, 0x8c, 0x91, 0x8d, + 0x98, 0x8f, 0x9d, 0x08, 0xb8, 0x94, 0xcc, 0xac, 0xba, 0xb1, 0x08, 0x8e, + 0xb3, 0x05, 0xfb, 0x49, 0x42, 0x15, 0x73, 0x9a, 0x7f, 0xaa, 0x8b, 0xb8, + 0x8b, 0xc6, 0x9d, 0xd6, 0xa3, 0xb6, 0xa2, 0xb3, 0xa1, 0x9f, 0xac, 0x98, + 0x08, 0x61, 0xfb, 0x3c, 0x05, 0x75, 0x2b, 0x89, 0x81, 0x79, 0x48, 0x08, + 0x0e, 0xf7, 0x5c, 0xf7, 0xbd, 0x15, 0x67, 0xfb, 0x3e, 0x8a, 0x86, 0x76, + 0x67, 0x7b, 0x74, 0x73, 0x7e, 0x6e, 0x8b, 0x6f, 0x6e, 0x7a, 0x76, 0x73, + 0x6a, 0x08, 0x96, 0x77, 0x05, 0xb0, 0xba, 0x9e, 0x94, 0xc5, 0x8b, 0x08, + 0xf7, 0x35, 0x86, 0x05, 0x9a, 0x8b, 0xa2, 0x8d, 0xa4, 0x8e, 0xa9, 0xb8, + 0xa5, 0xc2, 0x9d, 0xc4, 0x08, 0x78, 0x93, 0x05, 0x7e, 0x69, 0x70, 0x60, + 0x79, 0x7c, 0x75, 0x7c, 0x81, 0x8a, 0x2a, 0x8b, 0x61, 0x8a, 0x7e, 0x8a, + 0x6f, 0x87, 0xd9, 0xc1, 0xaa, 0xc2, 0xa7, 0xf7, 0x1a, 0x08, 0xf7, 0x03, + 0x8b, 0xa9, 0xaf, 0x05, 0x6f, 0x8a, 0x75, 0x8b, 0x7e, 0x8b, 0x7a, 0x8b, + 0x76, 0x8b, 0x6c, 0x8c, 0x96, 0xba, 0x92, 0xa6, 0x9d, 0xcd, 0x97, 0xb5, + 0x93, 0x96, 0x9e, 0x8b, 0x99, 0x8b, 0x95, 0x89, 0x9f, 0x82, 0x08, 0xac, + 0xc4, 0x05, 0x7a, 0x90, 0x82, 0x8c, 0x7a, 0x8b, 0x61, 0x8b, 0x7e, 0x81, + 0x55, 0x45, 0x61, 0x55, 0x83, 0x79, 0x72, 0x2e, 0x82, 0x8b, 0x82, 0x8b, + 0x89, 0x8a, 0x08, 0x72, 0x06, 0x86, 0x8b, 0x81, 0x8b, 0x80, 0x8c, 0x08, + 0x71, 0x67, 0xe3, 0x8b, 0x05, 0x0e, 0xfb, 0x91, 0x23, 0x87, 0x15, 0xa2, + 0x8a, 0x96, 0x8b, 0x05, 0xb6, 0xdb, 0x92, 0x96, 0xda, 0xf7, 0x17, 0x08, + 0xee, 0xf7, 0x3b, 0x05, 0xcc, 0xf7, 0x02, 0x92, 0x97, 0xbd, 0xd5, 0x85, + 0x8c, 0x86, 0x8b, 0x89, 0x8b, 0x82, 0x8c, 0x86, 0x8c, 0x89, 0x8b, 0x89, + 0x8b, 0x85, 0x8c, 0x85, 0x8c, 0x64, 0x44, 0x80, 0x78, 0x28, 0xfb, 0x3a, + 0xfb, 0x25, 0xfb, 0x87, 0x84, 0x7f, 0x58, 0x3e, 0x08, 0x96, 0x8a, 0x05, + 0x0e, 0xf7, 0x91, 0xf7, 0x4e, 0x15, 0x84, 0x4c, 0x79, 0x48, 0x70, 0x4c, + 0x74, 0x58, 0x6b, 0x75, 0x56, 0x8b, 0x7b, 0x8b, 0x89, 0x8b, 0x58, 0x90, + 0x08, 0x68, 0x40, 0x05, 0x9d, 0x89, 0x93, 0x8b, 0x9a, 0x8b, 0xe5, 0x8b, + 0xb4, 0x9e, 0xae, 0xc4, 0xab, 0xc2, 0x8b, 0x8b, 0xdd, 0xf7, 0x66, 0x08, + 0xf7, 0x2e, 0x95, 0xad, 0xa4, 0xfb, 0x3e, 0x8b, 0xad, 0xd0, 0xf7, 0x2a, + 0x94, 0xa8, 0xa6, 0xfb, 0x35, 0x8b, 0x05, 0xa5, 0xc0, 0xac, 0xc7, 0xa2, + 0xab, 0xa8, 0xb4, 0xa2, 0x9b, 0xab, 0x8b, 0x9a, 0x8b, 0x96, 0x88, 0xa2, + 0x82, 0x08, 0xa7, 0xd4, 0x05, 0x7c, 0x98, 0x83, 0x8e, 0x7a, 0x8b, 0x3b, + 0x8b, 0x4f, 0x3e, 0xfb, 0x19, 0xfb, 0xaa, 0x94, 0xc0, 0x8d, 0xa3, 0x8b, + 0xae, 0x08, 0xf7, 0x16, 0x61, 0xdc, 0x48, 0x23, 0xfb, 0x0b, 0xfb, 0x13, + 0xfb, 0x04, 0x1e, 0x8b, 0x6c, 0x92, 0x6d, 0x99, 0x6c, 0x08, 0xd7, 0xbb, + 0x05, 0x7c, 0xbb, 0x86, 0xa2, 0x8b, 0xaa, 0x8b, 0xd0, 0xae, 0xc2, 0xb7, + 0x8b, 0xc4, 0x8b, 0xb4, 0x43, 0x96, 0xfb, 0x0d, 0x08, 0x29, 0x06, 0x7c, + 0x79, 0x85, 0x83, 0x7b, 0x74, 0x08, 0xf7, 0x1e, 0x95, 0x05, 0x8c, 0x7a, + 0x8b, 0x86, 0x8b, 0x82, 0x8b, 0x83, 0x8b, 0x87, 0x8a, 0x77, 0x08, 0xfb, + 0x20, 0x06, 0x81, 0x80, 0x89, 0x87, 0x85, 0x84, 0x85, 0x83, 0x8a, 0x8a, + 0x7f, 0x79, 0x08, 0xf7, 0x41, 0x96, 0x05, 0x0e, 0xf8, 0x73, 0xf8, 0x16, + 0x15, 0x72, 0x8c, 0x78, 0x8b, 0x7d, 0x8b, 0x88, 0x8b, 0x72, 0x8b, 0x5d, + 0x8a, 0xa2, 0xef, 0x9e, 0xca, 0x9d, 0xaf, 0x9c, 0xac, 0x9c, 0x97, 0xac, + 0x8b, 0x9f, 0x8b, 0x99, 0x89, 0xab, 0x83, 0x08, 0xba, 0xc2, 0x05, 0x73, + 0x90, 0x7f, 0x8d, 0x79, 0x8b, 0x55, 0x8b, 0x5d, 0x73, 0x4a, 0x4a, 0x59, + 0x5a, 0x7a, 0x65, 0x6f, 0xfb, 0x0c, 0x08, 0x72, 0x8a, 0x73, 0x8b, 0x05, + 0x84, 0x8b, 0x80, 0x8b, 0x7d, 0x8c, 0x81, 0x85, 0x85, 0x88, 0x88, 0x89, + 0x85, 0x87, 0x85, 0x87, 0x85, 0x86, 0x89, 0x8a, 0x85, 0x87, 0x83, 0x86, + 0x08, 0xc6, 0x8b, 0xcd, 0x8b, 0x05, 0x81, 0x60, 0x84, 0x6d, 0x88, 0x7d, + 0x53, 0xfb, 0x90, 0x7d, 0x53, 0x73, 0x47, 0x79, 0x58, 0x6d, 0x75, 0x57, + 0x8b, 0x7e, 0x8b, 0x80, 0x8c, 0x6c, 0x8d, 0x85, 0x82, 0x87, 0x85, 0x89, + 0x89, 0x85, 0x82, 0x85, 0x83, 0x84, 0x83, 0x08, 0x89, 0x88, 0x87, 0x84, + 0x84, 0x82, 0xa2, 0x88, 0x96, 0x8a, 0x9d, 0x8b, 0xbf, 0x8b, 0x9f, 0x92, + 0xb1, 0xac, 0xcf, 0xc6, 0xa8, 0xb9, 0xaf, 0xf2, 0xa1, 0xcd, 0x91, 0xa0, + 0xcb, 0xf7, 0x9b, 0xa0, 0x8c, 0x9b, 0x8b, 0x95, 0x8b, 0x08, 0x97, 0x8b, + 0x9b, 0x8b, 0xa1, 0x8a, 0x08, 0xb7, 0xad, 0x05, 0x0e, 0xf6, 0xca, 0xfb, + 0x28, 0x15, 0xad, 0x7f, 0x9d, 0x87, 0xa4, 0x8b, 0xbc, 0x8b, 0xab, 0x9b, + 0xb3, 0xb9, 0xb0, 0xb5, 0x9f, 0xb1, 0x94, 0xb8, 0xc2, 0xc4, 0xa6, 0xc4, + 0x8b, 0xc3, 0x8b, 0xb7, 0x79, 0xb3, 0x5e, 0xc3, 0x53, 0xd1, 0x87, 0x92, + 0x8b, 0xa5, 0x08, 0xb6, 0xb2, 0xb8, 0xb0, 0x1e, 0xa2, 0x8b, 0x98, 0x80, + 0x96, 0x6b, 0x08, 0xc2, 0xd3, 0x05, 0x76, 0x9c, 0x7a, 0x91, 0x73, 0x8b, + 0x4f, 0x8b, 0x47, 0x54, 0x67, 0x3c, 0x3d, 0x40, 0x65, 0x4b, 0x8b, 0x4f, + 0x8b, 0x61, 0xa1, 0x5a, 0xb3, 0x57, 0xd6, 0x2e, 0x91, 0x81, 0x8b, 0x74, + 0x8b, 0x79, 0x7e, 0x71, 0x7a, 0x7a, 0x08, 0x7d, 0x7e, 0x79, 0x84, 0x74, + 0x8b, 0x77, 0x8b, 0x80, 0x8e, 0x60, 0x9c, 0x08, 0x60, 0x4e, 0x05, 0xf7, + 0x98, 0xf7, 0x55, 0x15, 0x80, 0xaf, 0x81, 0x9b, 0x67, 0xb8, 0x47, 0xdf, + 0x7d, 0xa5, 0x8b, 0xb8, 0x8b, 0xb2, 0x98, 0xab, 0xab, 0xb4, 0x8a, 0x83, + 0x8b, 0x84, 0x8b, 0x88, 0x8b, 0x61, 0x91, 0x7f, 0xcd, 0x33, 0xb5, 0x53, + 0x97, 0x70, 0x8b, 0x69, 0x08, 0x8b, 0x6e, 0x82, 0x72, 0x75, 0x6a, 0x08, + 0x0e, 0xf8, 0x44, 0xf7, 0x31, 0x15, 0xad, 0xb5, 0x97, 0xad, 0x8b, 0xc0, + 0x8b, 0xc0, 0x7f, 0xad, 0x69, 0xb5, 0x08, 0xbb, 0xba, 0x67, 0xb0, 0x5b, + 0x5c, 0x05, 0x60, 0xae, 0x66, 0x98, 0x58, 0x8b, 0x58, 0x8b, 0x66, 0x7e, + 0x60, 0x68, 0x08, 0x5b, 0xba, 0x67, 0x66, 0xbb, 0x5c, 0x05, 0x6a, 0x62, + 0x7e, 0x67, 0x8b, 0x57, 0x8b, 0x57, 0x98, 0x67, 0xac, 0x62, 0x08, 0x5b, + 0x5c, 0xaf, 0x66, 0xbb, 0xba, 0x05, 0xb6, 0x68, 0xb0, 0x7e, 0xbe, 0x8b, + 0xbe, 0x8b, 0xb0, 0x98, 0xb6, 0xae, 0x08, 0xbb, 0x5c, 0xaf, 0xb0, 0x5b, + 0xba, 0x05, 0xfb, 0x3b, 0xf7, 0xb5, 0x15, 0xe4, 0xd2, 0x44, 0x32, 0x32, + 0x44, 0x44, 0x31, 0x33, 0x45, 0xd3, 0xe6, 0xe1, 0xd3, 0xd2, 0xe2, 0x1f, + 0x0e, 0xfb, 0x2d, 0xf7, 0x3e, 0xf8, 0x29, 0x15, 0xa8, 0x97, 0xc7, 0xf7, + 0x42, 0x62, 0x8b, 0x5b, 0xfb, 0x4e, 0x05, 0x0e, 0xa6, 0xf8, 0x32, 0xf8, + 0x60, 0x15, 0x82, 0xa7, 0x88, 0x99, 0x8b, 0x9c, 0x8b, 0xb5, 0x99, 0xa2, + 0xcb, 0xc8, 0x08, 0x9f, 0x9f, 0x71, 0x96, 0x05, 0x6e, 0x70, 0x70, 0x71, + 0x72, 0x6f, 0x67, 0x63, 0x7f, 0x72, 0x8b, 0x69, 0x8b, 0x79, 0x8f, 0x75, + 0x91, 0x76, 0x08, 0xc6, 0xa4, 0x05, 0xfb, 0x08, 0x16, 0x82, 0xa7, 0x88, + 0x99, 0x8b, 0x9b, 0x8b, 0xb6, 0x99, 0xa2, 0xcb, 0xc8, 0x08, 0x9f, 0x9f, + 0x71, 0x96, 0x05, 0x6e, 0x70, 0x70, 0x70, 0x72, 0x70, 0x67, 0x64, 0x7f, + 0x71, 0x8b, 0x6b, 0x8b, 0x76, 0x8e, 0x77, 0x92, 0x75, 0x08, 0xc6, 0xa4, + 0x05, 0x0e, 0xa6, 0xf8, 0x1d, 0xf8, 0x31, 0x15, 0x2c, 0xfb, 0x03, 0x5a, + 0x4f, 0x05, 0x87, 0x86, 0x7f, 0x7e, 0x7a, 0x78, 0x08, 0x90, 0x77, 0x05, + 0x8d, 0x84, 0x8f, 0x7e, 0x90, 0x76, 0x08, 0xa7, 0xfb, 0x00, 0x05, 0x8d, + 0x83, 0x8f, 0x7c, 0x90, 0x75, 0x91, 0x90, 0x91, 0x90, 0x8d, 0x8c, 0x8d, + 0x8d, 0x91, 0x8f, 0x93, 0x91, 0x8d, 0x8c, 0x90, 0x8f, 0x90, 0x8e, 0x83, + 0xc6, 0x7b, 0xdb, 0x7d, 0xbf, 0xe8, 0xf7, 0x0d, 0x92, 0x95, 0xa8, 0xb6, + 0x08, 0x80, 0xa5, 0x05, 0xfb, 0x61, 0xfc, 0x20, 0x15, 0x92, 0x90, 0x05, + 0x82, 0xce, 0x7d, 0xcf, 0x7c, 0xc3, 0x08, 0xce, 0xe2, 0x05, 0xa9, 0xb2, + 0x94, 0x98, 0xa2, 0xae, 0x08, 0x80, 0xa5, 0xfb, 0x24, 0xfb, 0x3f, 0x05, + 0x87, 0x86, 0x7f, 0x7e, 0x7a, 0x78, 0x08, 0xc3, 0xfb, 0x6a, 0x05, 0x91, + 0x90, 0x90, 0x90, 0x8d, 0x8c, 0x8e, 0x8d, 0x90, 0x8f, 0x93, 0x91, 0x08, + 0x90, 0x8e, 0x05, 0x0e, 0x42, 0xf7, 0xa6, 0xf8, 0x31, 0x15, 0x50, 0x45, + 0x05, 0x73, 0x70, 0x6f, 0x69, 0x6b, 0x63, 0x87, 0x86, 0x7f, 0x7e, 0x7a, + 0x78, 0x08, 0xc1, 0xfb, 0x6a, 0x05, 0x91, 0x90, 0x91, 0x90, 0x8d, 0x8c, + 0x8d, 0x8d, 0x91, 0x8f, 0x93, 0x91, 0x8e, 0x8d, 0x8f, 0x8e, 0x90, 0x8e, + 0x81, 0xcf, 0x7d, 0xd2, 0x7d, 0xbf, 0x08, 0xce, 0xe2, 0xc9, 0xe2, 0x80, + 0xa5, 0x05, 0x0e, 0x56, 0xea, 0x88, 0x15, 0xc9, 0xd0, 0xe6, 0xf1, 0xaf, + 0xb0, 0x7d, 0xb7, 0x05, 0x7d, 0xbf, 0x81, 0xab, 0x87, 0x98, 0x08, 0x73, + 0xd8, 0x05, 0x7a, 0x7e, 0x86, 0x86, 0x77, 0x75, 0x9e, 0x37, 0x94, 0x66, + 0x9e, 0x4d, 0x3d, 0x2b, 0x6c, 0x63, 0x6f, 0x64, 0x08, 0x94, 0x6f, 0x05, + 0x0e, 0xf7, 0x63, 0xf7, 0xdb, 0xf7, 0xcb, 0x15, 0x9e, 0x8b, 0x93, 0x8c, + 0x9e, 0x92, 0xa0, 0x93, 0x92, 0x8d, 0x91, 0x8b, 0x95, 0x8b, 0x92, 0x85, + 0x8b, 0x82, 0x8b, 0x80, 0x78, 0x39, 0x79, 0x4b, 0x73, 0x33, 0x87, 0x7a, + 0x8b, 0x75, 0x8b, 0x71, 0x95, 0x7b, 0x9b, 0x8b, 0x08, 0x9c, 0x8b, 0x9d, + 0x94, 0xc5, 0xb1, 0x9b, 0x96, 0x93, 0x91, 0xc8, 0xb1, 0x08, 0x8f, 0xa9, + 0x05, 0x5a, 0x6d, 0x5a, 0x72, 0x82, 0x8b, 0x80, 0x8b, 0x83, 0x97, 0x8b, + 0x9b, 0x8b, 0x99, 0x94, 0xb6, 0xa2, 0xe6, 0xae, 0xf7, 0x24, 0x8d, 0x92, + 0x8b, 0x95, 0x8b, 0x90, 0x87, 0x8f, 0x84, 0x8b, 0x7d, 0x8b, 0x6d, 0x80, + 0x6c, 0x7a, 0x08, 0x56, 0x6e, 0x78, 0x83, 0x7b, 0x8b, 0x08, 0x55, 0x06, + 0xc6, 0xf7, 0x88, 0xa0, 0xb6, 0xc4, 0x8b, 0xb0, 0x8b, 0xa7, 0x7d, 0xbf, + 0x61, 0x08, 0xd1, 0xdd, 0x05, 0x52, 0x9b, 0x68, 0x91, 0x66, 0x8b, 0x57, + 0x8b, 0x5c, 0x71, 0x4b, 0x4d, 0x55, 0x56, 0x78, 0x60, 0x69, 0xfb, 0x2c, + 0x60, 0x8a, 0x86, 0x8b, 0x6b, 0x8b, 0x81, 0x85, 0x76, 0x81, 0x6d, 0x7b, + 0x08, 0xf7, 0x19, 0x8a, 0x05, 0x6e, 0xfb, 0x1f, 0x61, 0xfb, 0x49, 0x81, + 0x6b, 0x6a, 0xfb, 0x05, 0x70, 0x6c, 0x4a, 0x8b, 0x7c, 0x8b, 0x7f, 0x8c, + 0x73, 0x8f, 0x86, 0x83, 0x87, 0x87, 0x86, 0x84, 0x86, 0x83, 0x85, 0x83, + 0x85, 0x83, 0x85, 0x83, 0x86, 0x85, 0x87, 0x85, 0x08, 0x9f, 0x88, 0x93, + 0x8a, 0x9b, 0x8b, 0xca, 0x8b, 0x9f, 0x94, 0xc2, 0xc1, 0xb5, 0xb3, 0x9b, + 0xa0, 0x9e, 0xb2, 0xad, 0xd0, 0x97, 0xb1, 0xc5, 0xf7, 0x7b, 0x92, 0xa5, + 0x90, 0xa0, 0x8e, 0x95, 0x08, 0xc0, 0x06, 0x0e, 0xf7, 0x63, 0xf7, 0xfd, + 0xf7, 0xca, 0x15, 0xb6, 0xac, 0x05, 0x79, 0x8c, 0x80, 0x8b, 0x87, 0x8b, + 0x08, 0x53, 0x8a, 0x6a, 0x8b, 0x05, 0xcc, 0xf7, 0xa7, 0x9b, 0xa3, 0xf7, + 0x07, 0x8b, 0xa6, 0x8b, 0x9f, 0x8a, 0xb2, 0x87, 0x36, 0x49, 0x8a, 0x88, + 0x60, 0xfb, 0x4f, 0x08, 0x44, 0xfb, 0xcd, 0x05, 0x89, 0x86, 0x8b, 0x86, + 0x8b, 0x82, 0x8b, 0x6a, 0x9d, 0x6e, 0x9e, 0x8b, 0x95, 0x8b, 0x92, 0x8e, + 0xa4, 0x9d, 0xae, 0xa2, 0xd5, 0xc0, 0xab, 0xa3, 0x08, 0x89, 0xa2, 0x05, + 0x83, 0x85, 0x82, 0x86, 0x82, 0x85, 0x50, 0x65, 0x75, 0x7f, 0x7f, 0x8b, + 0x7f, 0x8b, 0x84, 0x98, 0x8b, 0xa1, 0x8b, 0xb5, 0xd6, 0xf7, 0xcb, 0xb3, + 0xf7, 0x11, 0x97, 0xb0, 0x9b, 0x9a, 0xa6, 0x8b, 0x99, 0x8b, 0x95, 0x89, + 0xa9, 0x85, 0x08, 0xb7, 0xbf, 0x05, 0x41, 0x96, 0x5c, 0x8f, 0x54, 0x8b, + 0x2c, 0x8b, 0x5f, 0x78, 0x3c, 0x3f, 0x54, 0x56, 0x7c, 0x68, 0x65, 0xfb, + 0x36, 0x59, 0x8b, 0x88, 0x8b, 0x6d, 0x8a, 0x83, 0x87, 0x86, 0x89, 0x89, + 0x89, 0x08, 0x75, 0x7e, 0x77, 0x80, 0xbd, 0x8b, 0xdd, 0x8b, 0x7f, 0x5d, + 0x05, 0x87, 0x7b, 0x81, 0x5e, 0x7c, 0x48, 0x4c, 0xfb, 0xac, 0x76, 0x63, + 0x39, 0x8b, 0x7e, 0x8b, 0x80, 0x8c, 0x6f, 0x8e, 0x08, 0x5d, 0x4d, 0x05, + 0xa1, 0x88, 0x95, 0x8a, 0x9b, 0x8b, 0xad, 0x8b, 0xa5, 0x90, 0x9b, 0x94, + 0xa6, 0x9a, 0xc0, 0xbd, 0xa5, 0xae, 0xaa, 0xb4, 0xaf, 0xe3, 0xa2, 0xe4, + 0x99, 0xc0, 0x99, 0xc0, 0x98, 0xc0, 0x8d, 0x91, 0x92, 0xa6, 0x93, 0xab, + 0x08, 0x9b, 0x8c, 0x97, 0x8b, 0x93, 0x8b, 0x8f, 0x8b, 0x95, 0x8b, 0x9a, + 0x8a, 0x08, 0xa2, 0x06, 0x0e, 0xf7, 0x4f, 0xd3, 0xf7, 0x41, 0x15, 0xf7, + 0xa7, 0x8e, 0x05, 0x9b, 0x8b, 0x8b, 0x8b, 0xf7, 0x3e, 0x88, 0x99, 0xa3, + 0x9a, 0xa0, 0x9b, 0x9d, 0x08, 0x30, 0x8b, 0xfb, 0x57, 0x8c, 0x05, 0x7e, + 0x8b, 0x25, 0x8b, 0x29, 0x8a, 0x7e, 0x7e, 0x78, 0x73, 0x7b, 0x71, 0x08, + 0xb4, 0x06, 0x0e, 0xf7, 0x27, 0xf7, 0x6d, 0x22, 0x15, 0xa5, 0xf7, 0x04, + 0xb2, 0xf7, 0x30, 0xbe, 0xf7, 0x5b, 0x08, 0xf7, 0x39, 0x96, 0xaa, 0xa6, + 0xfb, 0x4e, 0x8b, 0x05, 0x8f, 0x9c, 0x93, 0xa9, 0x91, 0xa0, 0x08, 0xa2, + 0xde, 0x05, 0x8c, 0x92, 0x91, 0x9e, 0x92, 0xa8, 0x08, 0x51, 0x6f, 0x05, + 0x7d, 0x4c, 0x85, 0x75, 0x73, 0x2e, 0x08, 0xfb, 0x33, 0x06, 0x7e, 0x7d, + 0x8a, 0x8a, 0x7e, 0x79, 0x08, 0x7f, 0x7a, 0xf7, 0x50, 0x97, 0xfb, 0x1e, + 0xfc, 0x88, 0xd0, 0xac, 0x05, 0x0e, 0xf7, 0x3b, 0xf7, 0x85, 0x22, 0x15, + 0x98, 0xc8, 0x8c, 0x8e, 0x9f, 0xe0, 0x08, 0xaa, 0xf7, 0x16, 0xf7, 0x19, + 0x92, 0xab, 0xa6, 0xfb, 0x30, 0x8d, 0x05, 0x9f, 0xda, 0x8d, 0x95, 0xa5, + 0xe4, 0x08, 0xf7, 0x1a, 0x97, 0xab, 0xa5, 0xfb, 0x31, 0x8b, 0xba, 0xf7, + 0x49, 0x52, 0x70, 0x65, 0xfb, 0x2e, 0xfb, 0x1d, 0x8b, 0x05, 0x77, 0x70, + 0x87, 0x86, 0x80, 0x79, 0x08, 0xf7, 0x36, 0x97, 0x05, 0x87, 0x7c, 0x88, + 0x80, 0x8a, 0x88, 0x08, 0x76, 0x3a, 0x78, 0x47, 0xfb, 0x19, 0x8b, 0x05, + 0x7c, 0x7a, 0x87, 0x84, 0x7b, 0x71, 0x08, 0xf7, 0x31, 0x94, 0x62, 0xfb, + 0x29, 0x05, 0x77, 0x3f, 0x85, 0x76, 0x79, 0x4f, 0x08, 0xd2, 0xab, 0x05, + 0x0e, 0x2e, 0xf7, 0x3d, 0xf7, 0xa9, 0x15, 0x69, 0x70, 0x70, 0x6a, 0x6a, + 0xa6, 0x6f, 0xac, 0xad, 0xa6, 0xa6, 0xad, 0xac, 0x70, 0xa6, 0x6a, 0x1f, + 0x0e, 0xf7, 0x4f, 0xf8, 0x7f, 0xf8, 0xa6, 0x15, 0xf7, 0x19, 0xa0, 0xa5, + 0xae, 0xfb, 0x0e, 0x86, 0x05, 0x32, 0x87, 0x5a, 0x89, 0x85, 0x8b, 0x63, + 0x87, 0x5f, 0x81, 0x70, 0x7f, 0x40, 0x69, 0x62, 0x4f, 0x8b, 0x3d, 0x8b, + 0x2a, 0xc3, 0x54, 0xf7, 0x13, 0x6e, 0x08, 0x6f, 0xfb, 0x07, 0x05, 0x69, + 0xfb, 0x29, 0x85, 0x77, 0x6f, 0x5b, 0x78, 0x6a, 0x6d, 0x76, 0x6e, 0x8b, + 0x6f, 0x8b, 0x71, 0x9a, 0x69, 0xad, 0x08, 0x5a, 0x4c, 0x05, 0xa6, 0x6f, + 0xac, 0x7c, 0xae, 0x8b, 0xd1, 0x8b, 0xe6, 0xdd, 0xbf, 0xf7, 0x01, 0xa2, + 0xbc, 0x8b, 0x8b, 0xbb, 0xf7, 0x62, 0x08, 0xde, 0xf7, 0xdf, 0x05, 0x0e, + 0xf7, 0xb3, 0xf8, 0x22, 0xf8, 0xc1, 0x15, 0x2d, 0x3f, 0x3f, 0x2d, 0x2f, + 0xd8, 0x3d, 0xe6, 0xeb, 0xd7, 0xd6, 0xeb, 0xe8, 0x3f, 0xd7, 0x2d, 0x1f, + 0x0e, 0xfb, 0x19, 0xcf, 0xfb, 0x01, 0x15, 0xe3, 0xf4, 0x99, 0xa4, 0x8b, + 0xb9, 0x8b, 0x98, 0x8a, 0x95, 0x86, 0xa0, 0x08, 0x79, 0x81, 0x05, 0x71, + 0x7d, 0x7c, 0x83, 0x86, 0x88, 0x91, 0x72, 0x8d, 0x81, 0x8b, 0x7d, 0x8b, + 0x69, 0x7f, 0x74, 0x53, 0x44, 0x08, 0xa7, 0x83, 0x05, 0x0e, 0x6a, 0xf7, + 0x4c, 0xfb, 0x01, 0x15, 0xe5, 0xf7, 0x01, 0x97, 0xa0, 0x8b, 0xb9, 0x8b, + 0x99, 0x8a, 0x95, 0x85, 0x9f, 0x84, 0x87, 0x84, 0x87, 0x87, 0x89, 0x78, + 0x81, 0x7c, 0x83, 0x80, 0x84, 0x91, 0x72, 0x8d, 0x80, 0x8b, 0x7e, 0x8b, + 0x6a, 0x7e, 0x73, 0x53, 0x44, 0x08, 0xa8, 0x83, 0x05, 0xfb, 0x07, 0x16, + 0xe6, 0xf7, 0x02, 0x96, 0x9f, 0x8b, 0xba, 0x8b, 0x98, 0x8a, 0x95, 0x86, + 0x9f, 0x82, 0x86, 0x84, 0x87, 0x89, 0x8a, 0x76, 0x80, 0x7c, 0x83, 0x81, + 0x85, 0x91, 0x70, 0x8d, 0x81, 0x8b, 0x7f, 0x8b, 0x6a, 0x7e, 0x72, 0x54, + 0x45, 0x08, 0xa7, 0x83, 0x05, 0x0e, 0xba, 0xf8, 0x07, 0xf8, 0x5a, 0x15, + 0xe4, 0xf5, 0x98, 0xa2, 0x8b, 0xba, 0x8b, 0x98, 0x8a, 0x95, 0x86, 0x9f, + 0x81, 0x86, 0x76, 0x7f, 0x6a, 0x79, 0x91, 0x71, 0x8d, 0x81, 0x8b, 0x7e, + 0x8b, 0x6a, 0x7e, 0x72, 0x54, 0x45, 0x08, 0xa7, 0x84, 0x05, 0xfb, 0x07, + 0x16, 0xe5, 0xf7, 0x00, 0x97, 0xa0, 0x8b, 0xba, 0x8b, 0x98, 0x8a, 0x95, + 0x86, 0x9f, 0x08, 0x79, 0x81, 0x5d, 0x72, 0x05, 0x91, 0x71, 0x8d, 0x81, + 0x8b, 0x7e, 0x8b, 0x6a, 0x7d, 0x70, 0x55, 0x47, 0x08, 0xa7, 0x84, 0x05, + 0x0e, 0xce, 0xf7, 0x6d, 0x88, 0x15, 0xaa, 0xae, 0xc8, 0xce, 0x92, 0x92, + 0x08, 0xc2, 0xc9, 0xaf, 0xb0, 0x7d, 0xb7, 0x05, 0x7c, 0xbd, 0x7a, 0xc5, + 0x75, 0xcd, 0x7a, 0x7e, 0x87, 0x87, 0x76, 0x74, 0x9c, 0x40, 0x98, 0x58, + 0x9c, 0x52, 0x3d, 0x29, 0x6d, 0x65, 0x6f, 0x64, 0x08, 0x94, 0x6f, 0x05, + 0xfb, 0x0d, 0x16, 0x9c, 0x9f, 0xa0, 0xa1, 0xa4, 0xa6, 0x08, 0xe6, 0xf1, + 0x05, 0x90, 0x8f, 0x97, 0x98, 0x9e, 0x9f, 0x84, 0xa1, 0x86, 0x9b, 0x8a, + 0x91, 0x7c, 0xbe, 0x81, 0xab, 0x86, 0x99, 0x08, 0x73, 0xd8, 0x05, 0x7a, + 0x7e, 0x87, 0x87, 0x76, 0x74, 0x9c, 0x3e, 0x9a, 0x53, 0x9a, 0x59, 0x3c, + 0x29, 0x6a, 0x62, 0x72, 0x67, 0x08, 0x94, 0x6f, 0x05, 0x0e, 0xf9, 0x43, + 0xf7, 0x19, 0xe4, 0x15, 0x70, 0x76, 0x05, 0x93, 0x75, 0x9f, 0x6b, 0x9e, + 0x74, 0xb0, 0xa6, 0x95, 0x94, 0xa6, 0xa6, 0x7f, 0x9d, 0x81, 0x9a, 0x8a, + 0x8c, 0x08, 0x73, 0xb3, 0x05, 0x88, 0x88, 0x86, 0x87, 0x85, 0x86, 0x83, + 0x85, 0x83, 0x84, 0x83, 0x84, 0x08, 0x82, 0x84, 0x05, 0xf7, 0xe1, 0x16, + 0x70, 0x76, 0x05, 0x93, 0x75, 0x9f, 0x6b, 0x9e, 0x74, 0xb0, 0xa6, 0x95, + 0x94, 0xa6, 0xa6, 0x83, 0x96, 0x84, 0x96, 0x83, 0x97, 0x08, 0x73, 0xb3, + 0x05, 0x85, 0x86, 0x85, 0x86, 0x89, 0x89, 0x83, 0x85, 0x83, 0x84, 0x83, + 0x84, 0x08, 0x82, 0x84, 0x05, 0xf8, 0x34, 0x77, 0x15, 0x87, 0x92, 0x87, + 0x91, 0x87, 0x91, 0x08, 0x73, 0xb3, 0x05, 0x85, 0x86, 0x85, 0x86, 0x89, + 0x89, 0x86, 0x87, 0x86, 0x87, 0x87, 0x87, 0x82, 0x85, 0x85, 0x85, 0x87, + 0x88, 0x08, 0x70, 0x76, 0x05, 0x93, 0x75, 0x9f, 0x6b, 0x9e, 0x74, 0xb0, + 0xa6, 0x95, 0x94, 0xa6, 0xa6, 0x08, 0x80, 0x9a, 0x05, 0x0e, 0xf9, 0x1b, + 0xfa, 0x1d, 0xf7, 0xf1, 0x15, 0x5c, 0x8b, 0x56, 0x6f, 0x6d, 0x62, 0x69, + 0x5c, 0x75, 0x46, 0x8b, 0x4d, 0x8b, 0x42, 0xa5, 0x67, 0xbf, 0x8b, 0xbf, + 0x8b, 0xb9, 0xa8, 0xa9, 0xbe, 0xa8, 0xbc, 0xa0, 0xda, 0x8b, 0xc7, 0x08, + 0xc4, 0x72, 0xaa, 0x5e, 0x1e, 0x6a, 0x6b, 0x15, 0xa8, 0x9c, 0x70, 0x5b, + 0xfb, 0x04, 0x5e, 0xfb, 0x02, 0x5d, 0x6c, 0x77, 0xae, 0xc0, 0x1f, 0x8b, + 0xb2, 0x94, 0xbe, 0x98, 0xb2, 0x9d, 0xc0, 0xa3, 0xa6, 0xab, 0x8b, 0x08, + 0xfb, 0x86, 0xab, 0x15, 0x5c, 0x8b, 0x56, 0x6f, 0x6d, 0x62, 0x69, 0x5c, + 0x75, 0x46, 0x8b, 0x4d, 0x8b, 0x42, 0xa5, 0x67, 0xbf, 0x8b, 0xbf, 0x8b, + 0xb9, 0xa8, 0xa9, 0xbe, 0xa8, 0xbd, 0xa0, 0xd9, 0x8b, 0xc8, 0x8b, 0xc3, + 0x72, 0xaa, 0x5e, 0x8b, 0x08, 0x6a, 0x6b, 0x15, 0xa8, 0x9c, 0x6f, 0x5b, + 0xfb, 0x03, 0x5e, 0xfb, 0x02, 0x5d, 0x6c, 0x77, 0xae, 0xc0, 0x1f, 0x8b, + 0xb2, 0x94, 0xbe, 0x98, 0xb2, 0x9d, 0xc1, 0xa3, 0xa5, 0xab, 0x8b, 0x08, + 0xfc, 0x02, 0xfb, 0xd1, 0x15, 0xa3, 0x8a, 0x91, 0x8a, 0x9a, 0x89, 0xdc, + 0xf7, 0x23, 0xf7, 0x63, 0xf7, 0xe5, 0xd1, 0xf0, 0x7a, 0x8d, 0x84, 0x8c, + 0x78, 0x8f, 0x08, 0x25, 0xfb, 0x44, 0xfb, 0x05, 0xfb, 0x4c, 0xfb, 0x25, + 0xfb, 0x74, 0x08, 0xf7, 0x09, 0xf8, 0xdc, 0x15, 0x5c, 0x8b, 0x56, 0x6e, + 0x6d, 0x62, 0x69, 0x5d, 0x75, 0x45, 0x8b, 0x4d, 0x8b, 0x42, 0xa5, 0x67, + 0xbf, 0x8b, 0xbe, 0x8b, 0xb9, 0xa8, 0xa9, 0xbe, 0xa9, 0xbe, 0x9f, 0xd8, + 0x8b, 0xc9, 0x8b, 0xc3, 0x72, 0xaa, 0x5f, 0x8b, 0x08, 0x6a, 0x6b, 0x15, + 0xa7, 0x9c, 0x6f, 0x5c, 0xfb, 0x04, 0x5e, 0xfb, 0x03, 0x5d, 0x6d, 0x77, + 0xae, 0xc0, 0x1f, 0x8b, 0xb1, 0x94, 0xc0, 0x98, 0xb2, 0x9c, 0xc0, 0xa4, + 0xa6, 0xab, 0x8b, 0x08, 0x0e, 0xe2, 0xf8, 0x01, 0xf7, 0xb0, 0x15, 0xa3, + 0x9f, 0x94, 0x92, 0xa6, 0xa0, 0x05, 0x82, 0xa3, 0x78, 0xaa, 0x78, 0xa1, + 0x67, 0x71, 0x81, 0x83, 0x6f, 0x6f, 0x8e, 0x86, 0x8f, 0x85, 0x8f, 0x86, + 0x08, 0x9c, 0x71, 0x05, 0x91, 0x80, 0x92, 0x80, 0x91, 0x81, 0x08, 0x99, + 0x96, 0x05, 0x6d, 0x51, 0x15, 0x84, 0x37, 0x7b, 0x69, 0x6a, 0x8c, 0x45, + 0x85, 0x78, 0x86, 0x66, 0x75, 0x51, 0x6a, 0x65, 0x4a, 0x8b, 0x49, 0x8b, + 0x52, 0xb8, 0x67, 0xd3, 0x8b, 0xcc, 0x8b, 0xb7, 0x9b, 0xb8, 0xb4, 0x84, + 0xa3, 0x87, 0x94, 0x81, 0xa7, 0x08, 0x6d, 0x53, 0x64, 0x6d, 0x60, 0x8b, + 0x6a, 0x8b, 0x74, 0xa6, 0x8b, 0xb2, 0x8b, 0xae, 0x9a, 0xb0, 0xa4, 0xa9, + 0xa8, 0xac, 0xac, 0x9a, 0xb9, 0x8b, 0x99, 0x8b, 0x96, 0x8a, 0xa1, 0x86, + 0x08, 0x9d, 0x9a, 0x05, 0x94, 0xd3, 0x8d, 0x9a, 0x91, 0xd5, 0x08, 0x69, + 0x80, 0x05, 0x0e, 0x2e, 0xf7, 0x5f, 0xf9, 0x1a, 0x15, 0x7a, 0x82, 0x7e, + 0x84, 0x05, 0x9f, 0x66, 0x9c, 0x6a, 0xb9, 0x27, 0x95, 0x8d, 0x8e, 0x8b, + 0x97, 0x8f, 0x74, 0xd9, 0x84, 0xa2, 0x6b, 0xe3, 0x08, 0x7b, 0x82, 0x05, + 0x0e, 0x7e, 0xf7, 0x79, 0xf8, 0x60, 0x15, 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, + 0xd9, 0x08, 0x5e, 0xa1, 0xfb, 0x1e, 0xfb, 0x51, 0xa3, 0x85, 0x05, 0x0e, + 0xa6, 0xf7, 0x4e, 0xf8, 0x69, 0x15, 0x8c, 0x82, 0xdc, 0xd5, 0x05, 0xa4, + 0xa1, 0x9a, 0x97, 0xac, 0xa5, 0x08, 0x96, 0x4b, 0x05, 0x90, 0x68, 0x8e, + 0x73, 0x8c, 0x80, 0x9e, 0x96, 0x8f, 0x8e, 0x98, 0x91, 0x88, 0xa9, 0x89, + 0xa9, 0x88, 0xa8, 0x8a, 0x96, 0x8a, 0xa0, 0x87, 0xc0, 0x86, 0x8c, 0x86, + 0x8c, 0x88, 0x8b, 0x89, 0x8b, 0x87, 0x8a, 0x83, 0x8a, 0x08, 0x5f, 0x65, + 0x76, 0x78, 0xfb, 0x00, 0xfb, 0x01, 0x8c, 0x87, 0x8c, 0x87, 0x8b, 0x8a, + 0x08, 0x8c, 0x81, 0x05, 0x0e, 0xf7, 0x58, 0xf8, 0x82, 0x15, 0xb0, 0xba, + 0x9a, 0x97, 0xa4, 0x8b, 0x99, 0x8b, 0x9a, 0x86, 0xa0, 0x7f, 0xbd, 0x6f, + 0x97, 0x86, 0xa2, 0x8b, 0xaa, 0x8b, 0x9f, 0x9b, 0xc1, 0xce, 0x08, 0x81, + 0x9d, 0x05, 0x71, 0x73, 0x89, 0x89, 0x83, 0x85, 0x7d, 0x81, 0x73, 0x82, + 0x7c, 0x8b, 0x7e, 0x8b, 0x74, 0x93, 0x75, 0x97, 0x65, 0xa1, 0x81, 0x8e, + 0x77, 0x8b, 0x6b, 0x8b, 0x73, 0x77, 0x5a, 0x49, 0x08, 0x98, 0x79, 0x05, + 0x0e, 0xf7, 0x4b, 0xf8, 0x9c, 0x15, 0xf7, 0xb8, 0x06, 0x9a, 0x9f, 0x98, + 0x9b, 0x97, 0x97, 0x08, 0xfb, 0xb5, 0x06, 0x86, 0x85, 0x86, 0x86, 0x8a, + 0x89, 0x87, 0x88, 0x88, 0x87, 0x87, 0x87, 0x08, 0x7f, 0x7c, 0x82, 0x82, + 0x05, 0x0e, 0xf7, 0x4b, 0xf8, 0xf5, 0x15, 0x93, 0x70, 0x91, 0x7d, 0x95, + 0x7b, 0xa5, 0x63, 0xb8, 0x73, 0xbd, 0x8b, 0xe2, 0x8b, 0xd7, 0xbe, 0xa4, + 0xd5, 0x08, 0x7c, 0x95, 0x05, 0x7d, 0x71, 0x82, 0x80, 0x77, 0x7e, 0x70, + 0x79, 0x5a, 0x7e, 0x61, 0x8b, 0x4a, 0x8b, 0x66, 0xa0, 0x69, 0xc3, 0x08, + 0x76, 0x81, 0x05, 0x0e, 0x2e, 0xf7, 0x88, 0xf8, 0x7d, 0x15, 0xac, 0xa9, + 0x05, 0x91, 0x8f, 0x8e, 0x8e, 0xa2, 0x9d, 0x79, 0xa8, 0x8a, 0x8e, 0x81, + 0xa2, 0x8a, 0x8f, 0x89, 0x90, 0x89, 0x8f, 0x85, 0x86, 0x87, 0x88, 0x87, + 0x88, 0x70, 0x74, 0x89, 0x8a, 0x71, 0x79, 0x93, 0x73, 0x92, 0x7f, 0xa2, + 0x69, 0x08, 0x0e, 0xba, 0xf7, 0xf6, 0xf8, 0x7d, 0x15, 0xa1, 0xa0, 0x8e, + 0x8e, 0x93, 0x91, 0x08, 0xab, 0xa4, 0x05, 0x7f, 0x9e, 0x87, 0x92, 0x87, + 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x81, 0xa4, 0x87, 0x88, 0x87, 0x88, 0x85, + 0x86, 0x7a, 0x7d, 0x81, 0x83, 0x87, 0x88, 0x84, 0x86, 0x86, 0x88, 0x7f, + 0x82, 0x93, 0x74, 0x93, 0x7b, 0xa1, 0x6c, 0x08, 0xfb, 0x19, 0x16, 0xac, + 0xa9, 0x05, 0x91, 0x8f, 0x8f, 0x8e, 0xa1, 0x9d, 0x80, 0x9e, 0x87, 0x92, + 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x80, 0xa4, 0x86, 0x87, 0x87, 0x87, + 0x86, 0x88, 0x71, 0x75, 0x88, 0x89, 0x71, 0x79, 0x93, 0x74, 0x93, 0x7d, + 0xa1, 0x6a, 0x08, 0x0e, 0x7e, 0xf7, 0xe9, 0xf9, 0x14, 0x15, 0x4a, 0x5b, + 0x5a, 0x48, 0x63, 0xa3, 0x74, 0xb5, 0xc9, 0xc0, 0xc1, 0xca, 0xb2, 0x71, + 0xa2, 0x61, 0x1f, 0x7d, 0x75, 0x15, 0xa1, 0x98, 0x78, 0x6b, 0x5d, 0x71, + 0x65, 0x6c, 0x77, 0x7d, 0xa1, 0xa9, 0xbb, 0xa3, 0xae, 0xab, 0x1f, 0x0e, + 0x7e, 0xf7, 0x6c, 0x16, 0x68, 0x8b, 0x3e, 0x2f, 0x05, 0xa0, 0x7b, 0x91, + 0x83, 0x8b, 0x7d, 0x8b, 0x7e, 0x85, 0x83, 0x76, 0x7b, 0x74, 0x78, 0x80, + 0x86, 0x6e, 0x83, 0x08, 0x9a, 0x7e, 0x05, 0xe0, 0xa0, 0xbf, 0xb5, 0x8b, + 0xba, 0x8b, 0x9d, 0x82, 0x99, 0x7c, 0x91, 0x08, 0xba, 0xcb, 0x05, 0x0e, + 0xe2, 0xf7, 0xab, 0xf8, 0x64, 0x15, 0x93, 0x89, 0x8d, 0x8b, 0x97, 0x89, + 0x93, 0x94, 0x94, 0x95, 0x94, 0x94, 0xb6, 0xbb, 0x9c, 0x9f, 0x9c, 0x9d, + 0x08, 0xc6, 0xc9, 0x62, 0x9e, 0x4a, 0x33, 0x3d, 0x24, 0x05, 0xbd, 0xf7, + 0x53, 0x15, 0x58, 0x47, 0x81, 0x7e, 0x85, 0x84, 0x08, 0x58, 0x48, 0x05, + 0x87, 0x87, 0x81, 0x7e, 0x7d, 0x78, 0x98, 0x88, 0x8c, 0x8b, 0x93, 0x8a, + 0x94, 0x94, 0x94, 0x95, 0x93, 0x94, 0x08, 0xd8, 0xe1, 0xc6, 0xc9, 0x05, + 0x87, 0x8d, 0x85, 0x8e, 0x8a, 0x8b, 0x08, 0x70, 0x99, 0x05, 0x0e, 0x6a, + 0xf7, 0x23, 0x16, 0x4e, 0x67, 0x73, 0x6f, 0x8b, 0x66, 0x8b, 0x6c, 0xa0, + 0x76, 0xab, 0x8b, 0xb2, 0x8b, 0xad, 0xa2, 0xab, 0xbb, 0x08, 0x7e, 0x90, + 0x05, 0x76, 0x75, 0x7f, 0x84, 0x7b, 0x8b, 0x76, 0x8b, 0x79, 0x9b, 0x8b, + 0x9d, 0x8b, 0x99, 0x95, 0x99, 0xa4, 0xa0, 0x94, 0x92, 0x94, 0x93, 0x94, + 0x93, 0x08, 0x69, 0x06, 0x0e, 0xa6, 0xf8, 0x50, 0xf9, 0x19, 0x15, 0x8a, + 0x95, 0x05, 0x82, 0x83, 0x7f, 0x81, 0x83, 0x82, 0x4c, 0x51, 0x85, 0x86, + 0x53, 0x5e, 0x83, 0xb4, 0x8b, 0x8f, 0x7f, 0xe5, 0x7d, 0x82, 0x8b, 0x8b, + 0x76, 0x7f, 0x8f, 0x57, 0x90, 0x51, 0x8f, 0x4c, 0x90, 0x89, 0x90, 0x8a, + 0x8e, 0x8b, 0x08, 0x8d, 0x8b, 0x8e, 0x8c, 0x94, 0x8d, 0xb9, 0xb2, 0xa5, + 0xa3, 0xf0, 0xf1, 0x8a, 0x90, 0x8a, 0x8e, 0x8b, 0x8d, 0x08, 0x8a, 0x94, + 0x05, 0x0e, 0xf9, 0x43, 0xf8, 0xd0, 0xf7, 0x43, 0x15, 0xe0, 0x8b, 0xf7, + 0x14, 0x8a, 0xf7, 0x8c, 0x8a, 0x05, 0x98, 0xa1, 0x9f, 0xa6, 0x97, 0x98, + 0x08, 0xfb, 0x4d, 0x8b, 0xfb, 0xe8, 0x8c, 0x05, 0x55, 0x8b, 0xfb, 0x52, + 0x8b, 0xfb, 0x7a, 0x8a, 0x7b, 0x7b, 0x7c, 0x77, 0x7a, 0x71, 0xf5, 0x8a, + 0x9a, 0x8b, 0xd7, 0x8b, 0x08, 0xf7, 0xec, 0x8e, 0x05, 0x0e, 0xf8, 0x3f, + 0xf8, 0x89, 0xf7, 0xa3, 0x15, 0xe2, 0x8c, 0x05, 0x96, 0x8b, 0x96, 0x8b, + 0xa6, 0x8a, 0x9e, 0x96, 0x92, 0x90, 0x9b, 0x9a, 0x08, 0xfb, 0x3e, 0x8b, + 0xc4, 0xf7, 0x7a, 0x05, 0x98, 0x8c, 0x98, 0x8c, 0x8f, 0x8b, 0x9f, 0x8c, + 0x99, 0x8c, 0x8f, 0x8b, 0x9a, 0x8c, 0x98, 0x8c, 0x94, 0x8b, 0xb1, 0x8b, + 0x95, 0x7c, 0x90, 0x4d, 0x08, 0xd2, 0xce, 0x05, 0x8a, 0xa4, 0x86, 0x95, + 0x7e, 0x93, 0x6e, 0x8a, 0x87, 0x8b, 0x66, 0x8a, 0x36, 0x88, 0x5d, 0x8a, + 0x57, 0x8b, 0x65, 0x8b, 0x8a, 0x8b, 0x2d, 0x91, 0x7e, 0x84, 0x88, 0x89, + 0x7b, 0x7d, 0xc0, 0x84, 0x9c, 0x88, 0xb3, 0x81, 0x08, 0xfb, 0xcd, 0xfb, + 0xf2, 0x05, 0x61, 0x59, 0x5d, 0x53, 0x68, 0x5d, 0x8c, 0x7e, 0x8c, 0x85, + 0x90, 0x80, 0xaf, 0x8c, 0x9b, 0x8d, 0xb3, 0x92, 0x88, 0x9b, 0x8a, 0x93, + 0x8b, 0x93, 0x8b, 0xa5, 0x8c, 0x8c, 0xbd, 0xd2, 0xbb, 0xce, 0x8e, 0x8e, + 0xbf, 0xcc, 0x08, 0xf7, 0x27, 0x8b, 0x52, 0xfb, 0x7a, 0x05, 0x81, 0x89, + 0x84, 0x89, 0x88, 0x8a, 0x80, 0x89, 0x81, 0x8a, 0x81, 0x89, 0x88, 0x8a, + 0x84, 0x89, 0x81, 0x89, 0x08, 0x6e, 0x73, 0x05, 0xd2, 0x8d, 0xaf, 0x8b, + 0xd0, 0x8b, 0xea, 0x8b, 0x8b, 0x8b, 0xf7, 0x39, 0x89, 0xa3, 0xb6, 0x96, + 0x9f, 0xc3, 0xf7, 0x06, 0x08, 0x7d, 0xa5, 0x05, 0xfb, 0x01, 0xfb, 0x34, + 0x83, 0x86, 0xfb, 0x36, 0x8b, 0x7c, 0x8b, 0x78, 0x8b, 0x70, 0x8c, 0x08, + 0xc4, 0xf7, 0x7a, 0x05, 0x7d, 0xf7, 0x80, 0x15, 0x58, 0xfb, 0x60, 0x05, + 0x50, 0x8c, 0x75, 0x8c, 0x60, 0x8e, 0x08, 0xf7, 0x43, 0xf7, 0x5b, 0x05, + 0x0e, 0x56, 0xf7, 0xd8, 0xf8, 0x3f, 0x15, 0x7a, 0x7c, 0x6a, 0x75, 0x86, + 0x8b, 0x88, 0x8b, 0x87, 0x90, 0x8b, 0x90, 0x8b, 0x98, 0x9e, 0xdd, 0x99, + 0xc0, 0x8e, 0x8f, 0x8d, 0x8e, 0x8c, 0x8c, 0x08, 0x90, 0x90, 0x05, 0x8c, + 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x78, 0x91, 0x6f, 0x8e, 0x6e, 0x8b, 0x7a, + 0x8b, 0x84, 0x89, 0x7d, 0x81, 0x78, 0x7f, 0x6f, 0x77, 0x87, 0x87, 0x76, + 0x76, 0x73, 0x40, 0x8b, 0x60, 0x8b, 0x6f, 0x94, 0x7a, 0x99, 0x8b, 0x08, + 0x95, 0x8b, 0x9d, 0x96, 0xba, 0xac, 0x91, 0x8f, 0x91, 0x8f, 0x91, 0x90, + 0x8b, 0x86, 0x8a, 0x86, 0x8a, 0x8a, 0x8a, 0x81, 0x8a, 0x85, 0x8a, 0x8a, + 0x8a, 0x84, 0x8a, 0x85, 0x8b, 0x88, 0x8b, 0x82, 0x8e, 0x87, 0x91, 0x8b, + 0x08, 0x9a, 0x8b, 0xa6, 0x9b, 0xca, 0xb8, 0x08, 0xa1, 0x07, 0x27, 0x16, + 0x63, 0x70, 0x7a, 0x81, 0x84, 0x8b, 0x85, 0x8b, 0x85, 0x95, 0x8b, 0x96, + 0x8b, 0xa4, 0x91, 0xa7, 0x95, 0xa8, 0x99, 0xb1, 0x97, 0x98, 0xa0, 0x8b, + 0x96, 0x8b, 0xa0, 0x88, 0x92, 0x88, 0x08, 0x74, 0x2d, 0x05, 0x8b, 0x89, + 0x8a, 0x85, 0x89, 0x82, 0x08, 0xfb, 0x23, 0xfb, 0x42, 0x15, 0xf7, 0x4e, + 0x8b, 0x94, 0xae, 0xfb, 0x4c, 0x8b, 0x80, 0x68, 0x05, 0x0e, 0xf7, 0x9f, + 0xf8, 0xa8, 0xf8, 0xd2, 0x15, 0x77, 0x8d, 0x81, 0x8c, 0x7d, 0x8b, 0x78, + 0x8b, 0x7a, 0x89, 0x7a, 0x87, 0x70, 0x84, 0x5b, 0x69, 0x63, 0x63, 0x5c, + 0x5b, 0x7f, 0x6d, 0x6b, 0xfb, 0x22, 0x7f, 0x86, 0x83, 0x87, 0x87, 0x8a, + 0x08, 0x67, 0x79, 0x05, 0x88, 0x89, 0x83, 0x88, 0x7e, 0x86, 0x86, 0x83, + 0x85, 0x84, 0x85, 0x83, 0x08, 0x76, 0x6b, 0x05, 0x9b, 0x94, 0x99, 0x92, + 0x90, 0x8e, 0x90, 0x8d, 0x9a, 0x92, 0xa1, 0x94, 0x90, 0x8e, 0x9a, 0x92, + 0x9b, 0x92, 0x89, 0x82, 0x89, 0x80, 0x8a, 0x88, 0x6e, 0xfb, 0x17, 0x73, + 0x69, 0x4c, 0x8b, 0x83, 0x8b, 0x7f, 0x8b, 0x80, 0x8c, 0x08, 0x7d, 0x7d, + 0x85, 0x84, 0x7c, 0x78, 0xbb, 0x8d, 0xa4, 0x8c, 0xa4, 0x8b, 0xa5, 0x8b, + 0xbe, 0x89, 0xd7, 0x88, 0x08, 0xf7, 0x38, 0x83, 0x92, 0x8b, 0xa5, 0x8b, + 0xbf, 0x8b, 0xa1, 0x96, 0x9d, 0xb0, 0x97, 0xa2, 0xaa, 0xd0, 0x9a, 0xb1, + 0x08, 0x80, 0x9e, 0x05, 0x4a, 0xfb, 0x1d, 0x80, 0x85, 0xfb, 0x40, 0x8c, + 0x08, 0xfb, 0x55, 0x8b, 0xa6, 0xa5, 0x05, 0xbf, 0xba, 0x97, 0xa2, 0xa2, + 0xf4, 0x9b, 0x91, 0x9b, 0x93, 0x8c, 0x8c, 0x08, 0xb0, 0x9d, 0x05, 0x8e, + 0x8d, 0x98, 0x90, 0x9f, 0x93, 0x08, 0xc6, 0xa5, 0x9b, 0xbb, 0x05, 0x3d, + 0x63, 0x87, 0x89, 0x5c, 0x77, 0x74, 0x81, 0x7d, 0x85, 0x86, 0x88, 0x98, + 0xc4, 0xa0, 0xdc, 0x95, 0xa9, 0x9a, 0xb5, 0xa5, 0x9e, 0xb6, 0x8b, 0x9a, + 0x8b, 0x95, 0x8b, 0xb0, 0x89, 0x08, 0xb2, 0xc3, 0x05, 0x0e, 0xf7, 0xef, + 0xf9, 0x54, 0xf9, 0x30, 0x15, 0x88, 0x96, 0x88, 0x96, 0x2c, 0xfb, 0x0b, + 0x05, 0x6f, 0x99, 0x74, 0x91, 0x6d, 0x8b, 0x32, 0x8b, 0x24, 0x63, 0x45, + 0x4d, 0x3a, 0x45, 0x5e, 0xfb, 0x02, 0x8b, 0xfb, 0x13, 0x8b, 0x43, 0x9a, + 0x5e, 0xb1, 0x64, 0x5f, 0x51, 0x83, 0x80, 0x72, 0x63, 0x8e, 0x74, 0x8d, + 0x84, 0x91, 0x78, 0x08, 0xc7, 0xe7, 0x8c, 0x8d, 0xac, 0xb8, 0xad, 0x7c, + 0x9f, 0x86, 0xac, 0x8b, 0xe8, 0x8b, 0xee, 0xb5, 0xd7, 0xd4, 0xd3, 0xd1, + 0xb3, 0xf3, 0x8b, 0xf7, 0x0c, 0x8b, 0xd5, 0x7b, 0xb8, 0x64, 0xb3, 0x08, + 0xdb, 0xf0, 0x88, 0x97, 0x05, 0xfc, 0x63, 0xfc, 0xcd, 0x15, 0x7a, 0xaa, + 0x83, 0xb4, 0x8b, 0xbe, 0x8b, 0xf7, 0x4c, 0xf6, 0xf7, 0x26, 0xf7, 0x1b, + 0x8b, 0xb4, 0x8b, 0xac, 0x7d, 0xa4, 0x6f, 0x08, 0xfb, 0x37, 0xfb, 0x68, + 0xfb, 0x2d, 0xfb, 0x5b, 0x05, 0xf7, 0xe1, 0xf8, 0x17, 0x15, 0x9d, 0x6a, + 0x93, 0x65, 0x8b, 0x5a, 0x8b, 0x3f, 0x76, 0x35, 0x6b, 0x52, 0x60, 0x3f, + 0x47, 0x5f, 0x41, 0x8b, 0x63, 0x8b, 0x68, 0x9a, 0x71, 0xa7, 0x08, 0xf7, + 0xcd, 0xf8, 0x34, 0x05, 0x0e, 0xf8, 0x8f, 0xf9, 0xea, 0xf7, 0x61, 0x15, + 0x28, 0xfb, 0x2b, 0x75, 0x7b, 0xfb, 0x06, 0x8b, 0x6a, 0x8b, 0x74, 0x8c, + 0x5b, 0x8f, 0x08, 0xc3, 0xf7, 0x76, 0x05, 0x9c, 0x8c, 0x8d, 0x8b, 0x92, + 0x8c, 0x08, 0x9d, 0x8c, 0x05, 0x9d, 0x8c, 0xa2, 0x8c, 0xa7, 0x8d, 0x08, + 0xa1, 0x8c, 0x05, 0xa3, 0x96, 0x8e, 0x8d, 0xa1, 0x9b, 0x08, 0xfb, 0x42, + 0x8b, 0xc5, 0xf7, 0x7d, 0x05, 0xbb, 0x8c, 0x8f, 0x8b, 0x9d, 0x8c, 0x96, + 0x8c, 0x96, 0x8b, 0x92, 0x8b, 0xb5, 0x8b, 0x99, 0x78, 0x91, 0x49, 0x08, + 0xcc, 0xc9, 0x05, 0x8b, 0xa6, 0x87, 0x99, 0x7c, 0x99, 0x08, 0xfb, 0x12, + 0x89, 0x05, 0x75, 0x8b, 0x41, 0x8f, 0x6a, 0x8e, 0x08, 0x33, 0x94, 0x88, + 0x8b, 0x72, 0x8b, 0x37, 0x8b, 0x34, 0x63, 0x48, 0x44, 0x3b, 0x37, 0x56, + 0xfb, 0x12, 0x8b, 0xfb, 0x01, 0x8b, 0x20, 0xcc, 0x4b, 0xf7, 0x00, 0x8b, + 0xa1, 0x8b, 0xad, 0x8d, 0xb0, 0x8e, 0x08, 0xd7, 0x92, 0xdc, 0x8f, 0xc3, + 0x8b, 0xa5, 0x8b, 0xc6, 0x8a, 0x9f, 0x8a, 0x08, 0xc5, 0x88, 0x05, 0x8e, + 0x8b, 0x96, 0x8b, 0x9b, 0x8a, 0xbb, 0xe4, 0xaa, 0xc7, 0x9a, 0xaa, 0x08, + 0x7b, 0xa7, 0x05, 0xfc, 0x2d, 0xfb, 0x28, 0x15, 0x5b, 0x6f, 0x71, 0x83, + 0x66, 0x8b, 0x32, 0x8b, 0x55, 0xc8, 0x8b, 0xf0, 0x8b, 0xdb, 0xa9, 0xf0, + 0xb9, 0xd4, 0xbc, 0xd9, 0xca, 0xb3, 0xd6, 0x8b, 0xb5, 0x8b, 0xa6, 0x80, + 0xaf, 0x6a, 0x08, 0xfb, 0x06, 0xfc, 0x5a, 0x05, 0x0e, 0x56, 0xf7, 0xa5, + 0xf8, 0xd6, 0x15, 0x75, 0x8b, 0x68, 0x7b, 0x6a, 0x73, 0x67, 0x70, 0x72, + 0x52, 0x8b, 0x54, 0x8b, 0x6a, 0x9e, 0x75, 0xa8, 0x8b, 0xa9, 0x8b, 0xca, + 0xad, 0x9f, 0xa6, 0xa1, 0xa9, 0x9d, 0xc1, 0x8b, 0xb1, 0x8b, 0xa9, 0x76, + 0xa0, 0x6e, 0x8b, 0x08, 0x6e, 0x6b, 0x15, 0x9f, 0x97, 0x78, 0x6d, 0x52, + 0x63, 0x4b, 0x69, 0x77, 0x7e, 0x9d, 0xa7, 0xc8, 0xb1, 0xca, 0xb0, 0x1f, + 0xfb, 0x26, 0xfb, 0xb9, 0x15, 0xf7, 0x3e, 0x8b, 0x97, 0xae, 0xfb, 0x40, + 0x8b, 0x81, 0x68, 0x05, 0x0e, 0xf7, 0x77, 0xf8, 0xe0, 0xf7, 0x1c, 0x15, + 0x3d, 0x47, 0x61, 0x73, 0x64, 0x8b, 0x67, 0x8b, 0x74, 0xab, 0x8b, 0xbe, + 0x8b, 0x8f, 0x8b, 0x91, 0x8c, 0x92, 0xf7, 0x48, 0xf7, 0x0b, 0xa8, 0xa8, + 0x8b, 0xc5, 0x8b, 0xb3, 0x78, 0xa0, 0x64, 0x8b, 0x70, 0x8b, 0x6d, 0x7e, + 0x60, 0x6d, 0x08, 0x94, 0xa4, 0x05, 0x91, 0x99, 0x8e, 0x95, 0x8c, 0x8e, + 0x8c, 0x8e, 0x8f, 0x92, 0x8e, 0x93, 0x87, 0x8c, 0x88, 0x8c, 0x89, 0x8b, + 0x8a, 0x8b, 0x8a, 0x8b, 0x89, 0x8a, 0x08, 0x85, 0x8a, 0x05, 0x86, 0x85, + 0x86, 0x84, 0x8a, 0x89, 0x88, 0x87, 0x84, 0x80, 0x80, 0x7b, 0x88, 0x87, + 0x88, 0x86, 0x88, 0x86, 0x75, 0xa4, 0x7b, 0x93, 0x74, 0x8b, 0x6f, 0x8b, + 0x71, 0x80, 0x61, 0x6f, 0x53, 0x66, 0x7c, 0x7c, 0x79, 0x6a, 0x08, 0x6c, + 0x52, 0x72, 0x29, 0x8b, 0x4a, 0x8b, 0x60, 0x9b, 0x66, 0x9e, 0x8b, 0xa2, + 0x8b, 0xb3, 0xa3, 0xf7, 0x06, 0xdf, 0x8a, 0x82, 0x8b, 0x86, 0x8b, 0x82, + 0x8b, 0x59, 0xab, 0x68, 0xba, 0x8b, 0xc6, 0x8b, 0xc6, 0xac, 0xe8, 0xde, + 0x08, 0xac, 0x07, 0xfb, 0xc2, 0x7a, 0x15, 0x4a, 0x5d, 0x7a, 0x82, 0x7d, + 0x8b, 0x7a, 0x8b, 0x82, 0xa0, 0x8b, 0xb3, 0x8b, 0xaf, 0x97, 0xc2, 0x9c, + 0xb9, 0xa5, 0xd0, 0xa9, 0xac, 0xb0, 0x8b, 0xa8, 0x8b, 0x9e, 0x7c, 0x9d, + 0x65, 0x74, 0x4d, 0x80, 0x63, 0x7c, 0x3d, 0x08, 0x7a, 0x7f, 0x05, 0xe3, + 0xc5, 0x15, 0x9e, 0xf7, 0x06, 0xb6, 0xd9, 0xb7, 0x8b, 0x9c, 0x8b, 0x96, + 0x7b, 0x8b, 0x70, 0x8b, 0x6e, 0x80, 0x74, 0x72, 0x73, 0x7b, 0x7c, 0x84, + 0x85, 0x40, 0x57, 0x08, 0x0e, 0x42, 0xf7, 0xcb, 0xf7, 0x08, 0x15, 0x2c, + 0x58, 0x89, 0x8a, 0x7e, 0x8b, 0x80, 0x8b, 0x84, 0x96, 0x8b, 0x9c, 0x8b, + 0x95, 0x8e, 0x9e, 0x91, 0xa1, 0xbe, 0xf7, 0x66, 0x95, 0xb3, 0x8b, 0x93, + 0x8b, 0x91, 0x86, 0x8f, 0x84, 0x8b, 0x7a, 0x8b, 0x50, 0x6a, 0x39, 0x54, + 0x08, 0x89, 0x6f, 0x05, 0xc6, 0xab, 0x90, 0x8d, 0x94, 0x8b, 0x93, 0x8b, + 0x8f, 0x85, 0x8b, 0x7f, 0x8b, 0x7e, 0x88, 0x7d, 0x7c, 0x52, 0x5c, 0xfb, + 0x43, 0x8b, 0x8b, 0x8b, 0x72, 0x8b, 0x73, 0x95, 0x7b, 0x99, 0x8b, 0x9c, + 0x8b, 0xa5, 0x98, 0xbf, 0xad, 0x08, 0x9e, 0x97, 0x9e, 0x97, 0x9e, 0x98, + 0x95, 0x91, 0x93, 0x90, 0x94, 0x91, 0x08, 0x92, 0xa7, 0x05, 0x0e, 0x7e, + 0xf7, 0x5b, 0xf7, 0xbc, 0x15, 0x56, 0xfb, 0x7a, 0x05, 0x8a, 0x84, 0x8a, + 0x84, 0x8b, 0x86, 0x8b, 0x7c, 0x91, 0x79, 0x93, 0x7d, 0x08, 0x91, 0x82, + 0x93, 0x87, 0x95, 0x8b, 0x95, 0x8b, 0x92, 0x8e, 0xa3, 0x9b, 0x08, 0xf7, + 0x21, 0xf0, 0x8b, 0xa1, 0x05, 0x7f, 0x84, 0x80, 0x84, 0x87, 0x89, 0x4d, + 0x64, 0x77, 0x81, 0x7f, 0x8b, 0x80, 0x8b, 0x84, 0x99, 0x8b, 0xa0, 0x8b, + 0x9f, 0x91, 0xab, 0xa0, 0xe2, 0x90, 0x9f, 0x91, 0xa4, 0x92, 0xab, 0x08, + 0xf7, 0x11, 0xc9, 0x9c, 0xb5, 0x63, 0x77, 0x5a, 0x76, 0x05, 0x8a, 0x8a, + 0x75, 0x81, 0x77, 0x82, 0x9c, 0xd1, 0xa1, 0xdb, 0x9f, 0xcb, 0x98, 0xb2, + 0x9b, 0x9a, 0xaa, 0x8b, 0x99, 0x8b, 0x96, 0x89, 0xa3, 0x86, 0x08, 0xb6, + 0xc0, 0x05, 0x76, 0x90, 0x81, 0x8c, 0x7c, 0x8b, 0x63, 0x8b, 0x6d, 0x7c, + 0x5a, 0x5f, 0x5d, 0x61, 0x82, 0x80, 0x7f, 0x66, 0x7f, 0x68, 0x7b, 0x50, + 0x7e, 0x53, 0x08, 0x81, 0x60, 0x05, 0x80, 0x85, 0x84, 0x87, 0x88, 0x8a, + 0x7f, 0x85, 0x7f, 0x86, 0x80, 0x86, 0x08, 0x70, 0x7e, 0x05, 0x78, 0x6f, + 0x87, 0x86, 0x7c, 0x79, 0x9d, 0x93, 0x97, 0x90, 0x90, 0x8d, 0x08, 0xb7, + 0xa0, 0x05, 0x8f, 0x8d, 0x95, 0x90, 0x96, 0x90, 0x08, 0x93, 0x8e, 0x05, + 0x0e, 0xf7, 0x04, 0xfb, 0x28, 0x15, 0x9b, 0xab, 0x90, 0x93, 0x99, 0xab, + 0x91, 0x98, 0x92, 0x98, 0x91, 0x99, 0x08, 0x96, 0xa1, 0x92, 0x8b, 0x05, + 0xb2, 0x8b, 0xae, 0x99, 0xc7, 0xb3, 0xbe, 0xad, 0x97, 0x97, 0xa1, 0xb2, + 0xae, 0xca, 0x9e, 0xce, 0x8b, 0xc5, 0x8b, 0xbd, 0x7b, 0xa4, 0x61, 0x9e, + 0x96, 0x9f, 0x97, 0x9f, 0x97, 0x9f, 0x08, 0xac, 0xc2, 0x78, 0xa4, 0x3f, + 0xfb, 0x1b, 0x05, 0x69, 0x8a, 0x77, 0x85, 0x65, 0x77, 0x47, 0x67, 0x64, + 0x6c, 0x74, 0x63, 0x69, 0x52, 0x77, 0x46, 0x8b, 0x4c, 0x8b, 0x58, 0x98, + 0x72, 0xb0, 0x77, 0x08, 0x55, 0x22, 0x9f, 0x67, 0x05, 0xd0, 0xf7, 0x68, + 0x15, 0x82, 0xa3, 0x87, 0x9b, 0x8b, 0x9f, 0x8b, 0xba, 0x9b, 0xc8, 0xa4, + 0xbb, 0xa8, 0xc3, 0xb2, 0xa9, 0xb6, 0x8b, 0x91, 0x8b, 0x91, 0x8a, 0x95, + 0x88, 0x08, 0xfb, 0x35, 0xfb, 0xbe, 0x05, 0xa1, 0x73, 0x15, 0xa5, 0xbf, + 0xc2, 0xf3, 0xdd, 0xf7, 0x2c, 0x05, 0x96, 0x75, 0x8e, 0x7e, 0x8b, 0x70, + 0x8b, 0x4b, 0x75, 0x3e, 0x6b, 0x58, 0x72, 0x65, 0x67, 0x73, 0x6b, 0x8b, + 0x81, 0x8b, 0x83, 0x8d, 0x7f, 0x91, 0x08, 0x0e, 0xf7, 0x8b, 0xf8, 0xee, + 0xf7, 0x1a, 0x15, 0x78, 0x7c, 0x05, 0x43, 0x50, 0x6c, 0x7b, 0x65, 0x8b, + 0x08, 0x69, 0x73, 0xaa, 0xb8, 0x1f, 0x8c, 0xa3, 0x05, 0xe6, 0xc8, 0xb0, + 0xa4, 0x99, 0x96, 0xba, 0xb0, 0xa0, 0xad, 0x8b, 0xb5, 0x8b, 0xae, 0x75, + 0xa1, 0x69, 0x8b, 0x65, 0x8b, 0x69, 0x7a, 0x55, 0x5d, 0x83, 0xb8, 0x79, + 0x9d, 0x67, 0x8b, 0x62, 0x8b, 0x2a, 0x58, 0x5f, 0x5e, 0x08, 0x5f, 0x5e, + 0x66, 0x25, 0x8b, 0x3d, 0x08, 0x4d, 0xaa, 0x62, 0xb9, 0x1e, 0xb6, 0x8b, + 0xb0, 0x9d, 0xce, 0xc0, 0x08, 0x98, 0x58, 0x9f, 0x77, 0xb5, 0x8b, 0xc9, + 0x8b, 0xc0, 0xa7, 0xef, 0xe3, 0x08, 0xaa, 0x07, 0xfb, 0xc0, 0xf7, 0x75, + 0x15, 0xa8, 0x9b, 0x74, 0x60, 0x1f, 0x8b, 0x6e, 0x7c, 0x3d, 0x7f, 0x66, + 0x75, 0x49, 0x61, 0x5f, 0x62, 0x8b, 0x08, 0x6e, 0x76, 0xb3, 0xc2, 0x1f, + 0xf6, 0xd3, 0xf7, 0x0a, 0xcc, 0x1e, 0xe0, 0xfb, 0x4b, 0x15, 0x96, 0xc5, + 0x97, 0xb4, 0x9b, 0xaa, 0x9e, 0xb1, 0xa4, 0xa4, 0x9e, 0x8b, 0x9d, 0x8b, + 0x96, 0x7b, 0x8b, 0x73, 0x8b, 0x63, 0x7b, 0x74, 0x48, 0x55, 0x76, 0x79, + 0x8a, 0x8a, 0x71, 0x7a, 0x08, 0x0e, 0xf6, 0xd9, 0x55, 0x15, 0x76, 0x2b, + 0x6d, 0x62, 0x5d, 0x8b, 0x7b, 0x8b, 0x7c, 0x8e, 0x62, 0x98, 0x87, 0x83, + 0x87, 0x84, 0x87, 0x84, 0x89, 0x87, 0x86, 0x82, 0x83, 0x7d, 0x8a, 0x88, + 0x87, 0x83, 0x87, 0x83, 0xa5, 0x87, 0x97, 0x8a, 0x98, 0x8b, 0x08, 0xba, + 0x8b, 0xb1, 0x9c, 0xb3, 0xb1, 0xce, 0xcd, 0xa8, 0xce, 0xb9, 0xf7, 0x60, + 0xe1, 0xf8, 0x11, 0x8b, 0x8b, 0x94, 0xa1, 0xa4, 0xc4, 0xb2, 0xad, 0xb3, + 0x8b, 0xa9, 0x8b, 0x9f, 0x73, 0x8b, 0x67, 0x8b, 0x71, 0x81, 0x6b, 0x75, + 0x65, 0x08, 0x7f, 0x74, 0x59, 0x44, 0x75, 0x71, 0x71, 0x6b, 0x86, 0x81, + 0x8b, 0x77, 0x8b, 0x71, 0x95, 0x7a, 0xb3, 0x5f, 0xa7, 0x6c, 0x96, 0x76, + 0x8b, 0x72, 0x8b, 0x5d, 0x5f, 0x66, 0x54, 0x8b, 0x73, 0x8b, 0x78, 0x8e, + 0x73, 0x92, 0x08, 0x85, 0x80, 0x87, 0x84, 0x89, 0x88, 0x86, 0x84, 0x86, + 0x84, 0x87, 0x84, 0x8a, 0x8a, 0x84, 0x80, 0x85, 0x81, 0xa1, 0x89, 0x96, + 0x8a, 0x9b, 0x8b, 0xca, 0x8b, 0xae, 0x95, 0xa8, 0xa6, 0xc0, 0xbb, 0xad, + 0xc6, 0x8b, 0xb8, 0x08, 0x8b, 0xa5, 0x80, 0xa7, 0x75, 0xa5, 0x65, 0xba, + 0x88, 0x90, 0x8b, 0xa0, 0x8b, 0xa0, 0x94, 0x9f, 0xa7, 0xb2, 0xe3, 0xf7, + 0x0f, 0x9b, 0xa9, 0x8b, 0xb3, 0x8b, 0xb2, 0x6e, 0xa9, 0x64, 0x8b, 0x4a, + 0x8b, 0x3e, 0x5e, 0x5b, 0x48, 0x08, 0x6a, 0x5e, 0x7a, 0x61, 0x79, 0x38, + 0x6f, 0x7e, 0x82, 0x85, 0x77, 0x79, 0xa4, 0x7b, 0x94, 0x7a, 0x8b, 0x6c, + 0x08, 0x3c, 0xfb, 0xf3, 0x05, 0x0e, 0xf7, 0xc7, 0xa2, 0x94, 0x15, 0xa2, + 0x84, 0x97, 0x89, 0x9d, 0x8b, 0xcf, 0x8b, 0xb9, 0xae, 0xf7, 0x18, 0xf7, + 0x2b, 0xda, 0x8b, 0xc6, 0x8a, 0xb2, 0x88, 0x89, 0x7f, 0x89, 0x7f, 0x8a, + 0x7f, 0x89, 0x7e, 0x88, 0x78, 0x88, 0x76, 0x89, 0x78, 0x88, 0x78, 0x8a, + 0x88, 0x08, 0x88, 0x7a, 0x89, 0x7b, 0x8b, 0x81, 0x08, 0x7f, 0x95, 0x81, + 0x98, 0x1e, 0x92, 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0xbb, 0x94, 0xbb, 0x94, + 0xbb, 0x93, 0x08, 0x9b, 0xa3, 0x05, 0x81, 0x8a, 0x81, 0x8a, 0x88, 0x8b, + 0x6c, 0x88, 0x86, 0x8b, 0x7c, 0x8b, 0x64, 0x8b, 0x7f, 0x95, 0x8b, 0xae, + 0x8b, 0xca, 0xb3, 0xf7, 0xb0, 0xaa, 0xf7, 0x30, 0x08, 0x7d, 0x95, 0x05, + 0x87, 0x87, 0x87, 0x87, 0x88, 0x87, 0x7b, 0x7b, 0x82, 0x87, 0x7a, 0x8b, + 0x7f, 0x8b, 0x87, 0x8b, 0x62, 0x92, 0x5d, 0x92, 0x72, 0x8e, 0x77, 0x8b, + 0x5d, 0x8b, 0x5b, 0x74, 0x5c, 0x5d, 0x56, 0x58, 0x74, 0x5e, 0x8b, 0x56, + 0x08, 0x8b, 0x74, 0x8e, 0x7b, 0x96, 0x6e, 0x08, 0xd5, 0xb3, 0x05, 0x7b, + 0xba, 0x86, 0xa2, 0x8b, 0xa2, 0x8b, 0xc4, 0xb6, 0xad, 0xd4, 0x8b, 0x96, + 0x8b, 0x97, 0x8a, 0x99, 0x8a, 0x08, 0xb3, 0x86, 0x9a, 0x8a, 0x05, 0x9c, + 0x89, 0x93, 0x8b, 0xa6, 0x89, 0x08, 0xfb, 0x41, 0xfb, 0x74, 0x05, 0x61, + 0x55, 0x49, 0x3e, 0x71, 0x72, 0x08, 0x63, 0x64, 0x6d, 0x7d, 0x5d, 0x8b, + 0x7a, 0x8b, 0x82, 0x8c, 0x79, 0x91, 0x08, 0x65, 0x45, 0x05, 0xf7, 0xde, + 0xf7, 0x6e, 0x15, 0xf7, 0x55, 0xf7, 0x91, 0x62, 0xfb, 0x91, 0xfb, 0x2c, + 0x8b, 0x05, 0xf7, 0xad, 0xf8, 0x3b, 0x15, 0xa1, 0xa0, 0x8e, 0x8e, 0x93, + 0x91, 0x08, 0xab, 0xa4, 0x05, 0x7f, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, + 0x91, 0x8a, 0x8e, 0x81, 0xa4, 0x86, 0x87, 0x84, 0x86, 0x89, 0x89, 0x7a, + 0x7d, 0x81, 0x83, 0x87, 0x88, 0x84, 0x86, 0x86, 0x88, 0x7f, 0x82, 0x93, + 0x74, 0x93, 0x7b, 0xa1, 0x6c, 0x08, 0xfb, 0x19, 0x16, 0xac, 0xa9, 0x05, + 0x91, 0x90, 0x8f, 0x8d, 0xa1, 0x9d, 0x80, 0x9e, 0x87, 0x92, 0x87, 0x93, + 0x88, 0x91, 0x8a, 0x8e, 0x80, 0xa4, 0x86, 0x87, 0x87, 0x87, 0x86, 0x88, + 0x71, 0x75, 0x88, 0x89, 0x71, 0x79, 0x93, 0x74, 0x93, 0x7d, 0xa1, 0x6a, + 0x08, 0x0e, 0xf7, 0xc7, 0xa2, 0x94, 0x15, 0xa2, 0x84, 0x97, 0x89, 0x9d, + 0x8b, 0xcf, 0x8b, 0xb9, 0xae, 0xf7, 0x18, 0xf7, 0x2b, 0xda, 0x8b, 0xc6, + 0x8a, 0xb2, 0x88, 0x89, 0x7f, 0x89, 0x7f, 0x8a, 0x7f, 0x89, 0x7e, 0x88, + 0x78, 0x88, 0x76, 0x89, 0x78, 0x88, 0x78, 0x8a, 0x88, 0x08, 0x88, 0x7a, + 0x89, 0x7b, 0x8b, 0x81, 0x08, 0x7f, 0x95, 0x81, 0x98, 0x1e, 0x92, 0x8b, + 0x95, 0x8c, 0x97, 0x8e, 0xbb, 0x94, 0xbb, 0x94, 0xbb, 0x93, 0x08, 0x9b, + 0xa3, 0x05, 0x81, 0x8a, 0x81, 0x8a, 0x88, 0x8b, 0x6c, 0x88, 0x86, 0x8b, + 0x7c, 0x8b, 0x64, 0x8b, 0x7f, 0x95, 0x8b, 0xae, 0x8b, 0xca, 0xb3, 0xf7, + 0xb0, 0xaa, 0xf7, 0x30, 0x08, 0x7d, 0x95, 0x05, 0x87, 0x87, 0x87, 0x87, + 0x88, 0x87, 0x7b, 0x7b, 0x82, 0x87, 0x7a, 0x8b, 0x7f, 0x8b, 0x87, 0x8b, + 0x62, 0x92, 0x5d, 0x92, 0x72, 0x8e, 0x77, 0x8b, 0x5d, 0x8b, 0x5b, 0x74, + 0x5c, 0x5d, 0x56, 0x58, 0x74, 0x5e, 0x8b, 0x56, 0x08, 0x8b, 0x74, 0x8e, + 0x7b, 0x96, 0x6e, 0x08, 0xd5, 0xb3, 0x05, 0x7b, 0xba, 0x86, 0xa2, 0x8b, + 0xa2, 0x8b, 0xc4, 0xb6, 0xad, 0xd4, 0x8b, 0x96, 0x8b, 0x97, 0x8a, 0x99, + 0x8a, 0x08, 0xb3, 0x86, 0x9a, 0x8a, 0x05, 0x9c, 0x89, 0x93, 0x8b, 0xa6, + 0x89, 0x08, 0xfb, 0x41, 0xfb, 0x74, 0x05, 0x61, 0x55, 0x49, 0x3e, 0x71, + 0x72, 0x08, 0x63, 0x64, 0x6d, 0x7d, 0x5d, 0x8b, 0x7a, 0x8b, 0x82, 0x8c, + 0x79, 0x91, 0x08, 0x65, 0x45, 0x05, 0xf7, 0xde, 0xf7, 0x6e, 0x15, 0xf7, + 0x55, 0xf7, 0x91, 0x62, 0xfb, 0x91, 0xfb, 0x2c, 0x8b, 0x05, 0xf7, 0x43, + 0xf8, 0x22, 0x15, 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, 0xda, 0x08, 0x5e, 0xa0, + 0x05, 0x51, 0x3a, 0x5d, 0x4c, 0x69, 0x5f, 0x08, 0xa3, 0x84, 0x05, 0x0e, + 0xf7, 0xc7, 0xa2, 0x94, 0x15, 0xa2, 0x84, 0x97, 0x89, 0x9d, 0x8b, 0xcf, + 0x8b, 0xb9, 0xae, 0xf7, 0x18, 0xf7, 0x2b, 0xda, 0x8b, 0xc6, 0x8a, 0xb2, + 0x88, 0x89, 0x7f, 0x89, 0x7f, 0x8a, 0x7f, 0x89, 0x7e, 0x88, 0x78, 0x88, + 0x76, 0x89, 0x78, 0x88, 0x78, 0x8a, 0x88, 0x08, 0x88, 0x7a, 0x89, 0x7b, + 0x8b, 0x81, 0x08, 0x7f, 0x95, 0x81, 0x98, 0x1e, 0x92, 0x8b, 0x95, 0x8c, + 0x97, 0x8e, 0xbb, 0x94, 0xbb, 0x94, 0xbb, 0x93, 0x08, 0x9b, 0xa3, 0x05, + 0x81, 0x8a, 0x81, 0x8a, 0x88, 0x8b, 0x6c, 0x88, 0x86, 0x8b, 0x7c, 0x8b, + 0x64, 0x8b, 0x7f, 0x95, 0x8b, 0xae, 0x8b, 0xca, 0xb3, 0xf7, 0xb0, 0xaa, + 0xf7, 0x30, 0x08, 0x7d, 0x95, 0x05, 0x87, 0x87, 0x87, 0x87, 0x88, 0x87, + 0x7b, 0x7b, 0x82, 0x87, 0x7a, 0x8b, 0x7f, 0x8b, 0x87, 0x8b, 0x62, 0x92, + 0x5d, 0x92, 0x72, 0x8e, 0x77, 0x8b, 0x5d, 0x8b, 0x5b, 0x74, 0x5c, 0x5d, + 0x56, 0x58, 0x74, 0x5e, 0x8b, 0x56, 0x08, 0x8b, 0x74, 0x8e, 0x7b, 0x96, + 0x6e, 0x08, 0xd5, 0xb3, 0x05, 0x7b, 0xba, 0x86, 0xa2, 0x8b, 0xa2, 0x8b, + 0xc4, 0xb6, 0xad, 0xd4, 0x8b, 0x96, 0x8b, 0x97, 0x8a, 0x99, 0x8a, 0x08, + 0xb3, 0x86, 0x9a, 0x8a, 0x05, 0x9c, 0x89, 0x93, 0x8b, 0xa6, 0x89, 0x08, + 0xfb, 0x41, 0xfb, 0x74, 0x05, 0x61, 0x55, 0x49, 0x3e, 0x71, 0x72, 0x08, + 0x63, 0x64, 0x6d, 0x7d, 0x5d, 0x8b, 0x7a, 0x8b, 0x82, 0x8c, 0x79, 0x91, + 0x08, 0x65, 0x45, 0x05, 0xf7, 0xde, 0xf7, 0x6e, 0x15, 0xf7, 0x55, 0xf7, + 0x91, 0x62, 0xfb, 0x91, 0xfb, 0x2c, 0x8b, 0x05, 0xf7, 0x41, 0xf8, 0xdd, + 0x15, 0x7a, 0x82, 0x05, 0x89, 0x8a, 0x87, 0x88, 0x84, 0x88, 0x9f, 0x66, + 0x9c, 0x6a, 0xb9, 0x26, 0x95, 0x8d, 0x8e, 0x8c, 0x97, 0x8e, 0x74, 0xda, + 0x84, 0xa2, 0x6b, 0xe2, 0x08, 0x7b, 0x83, 0x05, 0x0e, 0xf7, 0xc7, 0xa2, + 0x94, 0x15, 0xa2, 0x84, 0x97, 0x89, 0x9d, 0x8b, 0xcf, 0x8b, 0xb9, 0xae, + 0xf7, 0x18, 0xf7, 0x2b, 0xda, 0x8b, 0xc6, 0x8a, 0xb2, 0x88, 0x89, 0x7f, + 0x89, 0x7f, 0x8a, 0x7f, 0x89, 0x7e, 0x88, 0x78, 0x88, 0x76, 0x89, 0x78, + 0x88, 0x78, 0x8a, 0x88, 0x08, 0x88, 0x7a, 0x89, 0x7b, 0x8b, 0x81, 0x08, + 0x7f, 0x95, 0x81, 0x98, 0x1e, 0x92, 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0xbb, + 0x94, 0xbb, 0x94, 0xbb, 0x93, 0x08, 0x9b, 0xa3, 0x05, 0x81, 0x8a, 0x81, + 0x8a, 0x88, 0x8b, 0x6c, 0x88, 0x86, 0x8b, 0x7c, 0x8b, 0x64, 0x8b, 0x7f, + 0x95, 0x8b, 0xae, 0x8b, 0xca, 0xb3, 0xf7, 0xb0, 0xaa, 0xf7, 0x30, 0x08, + 0x7d, 0x95, 0x05, 0x87, 0x87, 0x87, 0x87, 0x88, 0x87, 0x7b, 0x7b, 0x82, + 0x87, 0x7a, 0x8b, 0x7f, 0x8b, 0x87, 0x8b, 0x62, 0x92, 0x5d, 0x92, 0x72, + 0x8e, 0x77, 0x8b, 0x5d, 0x8b, 0x5b, 0x74, 0x5c, 0x5d, 0x56, 0x58, 0x74, + 0x5e, 0x8b, 0x56, 0x08, 0x8b, 0x74, 0x8e, 0x7b, 0x96, 0x6e, 0x08, 0xd5, + 0xb3, 0x05, 0x7b, 0xba, 0x86, 0xa2, 0x8b, 0xa2, 0x8b, 0xc4, 0xb6, 0xad, + 0xd4, 0x8b, 0x96, 0x8b, 0x97, 0x8a, 0x99, 0x8a, 0x08, 0xb3, 0x86, 0x9a, + 0x8a, 0x05, 0x9c, 0x89, 0x93, 0x8b, 0xa6, 0x89, 0x08, 0xfb, 0x41, 0xfb, + 0x74, 0x05, 0x61, 0x55, 0x49, 0x3e, 0x71, 0x72, 0x08, 0x63, 0x64, 0x6d, + 0x7d, 0x5d, 0x8b, 0x7a, 0x8b, 0x82, 0x8c, 0x79, 0x91, 0x08, 0x65, 0x45, + 0x05, 0xf7, 0xde, 0xf7, 0x6e, 0x15, 0xf7, 0x55, 0xf7, 0x91, 0x62, 0xfb, + 0x91, 0xfb, 0x2c, 0x8b, 0x05, 0xeb, 0xf8, 0x2b, 0x15, 0x8c, 0x8a, 0x8b, + 0x87, 0x8c, 0x87, 0x08, 0xdc, 0xd5, 0x05, 0xa4, 0xa1, 0x99, 0x97, 0xac, + 0xa5, 0x91, 0x6d, 0x8f, 0x75, 0x8c, 0x7f, 0x08, 0x91, 0x5c, 0x8f, 0x74, + 0x05, 0x9d, 0x96, 0x90, 0x8e, 0x97, 0x91, 0x89, 0xa5, 0x88, 0xae, 0x89, + 0xa7, 0x8a, 0x96, 0x89, 0xa0, 0x87, 0xc0, 0x86, 0x8c, 0x86, 0x8c, 0x88, + 0x8b, 0x89, 0x8b, 0x88, 0x8a, 0x82, 0x8a, 0x5f, 0x65, 0x77, 0x78, 0xfb, + 0x01, 0xfb, 0x01, 0x08, 0x8c, 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8c, + 0x81, 0x05, 0x0e, 0xf7, 0xc7, 0xa2, 0x94, 0x15, 0xa2, 0x84, 0x97, 0x89, + 0x9d, 0x8b, 0xcf, 0x8b, 0xb9, 0xae, 0xf7, 0x18, 0xf7, 0x2b, 0xda, 0x8b, + 0xc6, 0x8a, 0xb2, 0x88, 0x89, 0x7f, 0x89, 0x7f, 0x8a, 0x7f, 0x89, 0x7e, + 0x88, 0x78, 0x88, 0x76, 0x89, 0x78, 0x88, 0x78, 0x8a, 0x88, 0x08, 0x88, + 0x7a, 0x89, 0x7b, 0x8b, 0x81, 0x08, 0x7f, 0x95, 0x81, 0x98, 0x1e, 0x92, + 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0xbb, 0x94, 0xbb, 0x94, 0xbb, 0x93, 0x08, + 0x9b, 0xa3, 0x05, 0x81, 0x8a, 0x81, 0x8a, 0x88, 0x8b, 0x6c, 0x88, 0x86, + 0x8b, 0x7c, 0x8b, 0x64, 0x8b, 0x7f, 0x95, 0x8b, 0xae, 0x8b, 0xca, 0xb3, + 0xf7, 0xb0, 0xaa, 0xf7, 0x30, 0x08, 0x7d, 0x95, 0x05, 0x87, 0x87, 0x87, + 0x87, 0x88, 0x87, 0x7b, 0x7b, 0x82, 0x87, 0x7a, 0x8b, 0x7f, 0x8b, 0x87, + 0x8b, 0x62, 0x92, 0x5d, 0x92, 0x72, 0x8e, 0x77, 0x8b, 0x5d, 0x8b, 0x5b, + 0x74, 0x5c, 0x5d, 0x56, 0x58, 0x74, 0x5e, 0x8b, 0x56, 0x08, 0x8b, 0x74, + 0x8e, 0x7b, 0x96, 0x6e, 0x08, 0xd5, 0xb3, 0x05, 0x7b, 0xba, 0x86, 0xa2, + 0x8b, 0xa2, 0x8b, 0xc4, 0xb6, 0xad, 0xd4, 0x8b, 0x96, 0x8b, 0x97, 0x8a, + 0x99, 0x8a, 0x08, 0xb3, 0x86, 0x9a, 0x8a, 0x05, 0x9c, 0x89, 0x93, 0x8b, + 0xa6, 0x89, 0x08, 0xfb, 0x41, 0xfb, 0x74, 0x05, 0x61, 0x55, 0x49, 0x3e, + 0x71, 0x72, 0x08, 0x63, 0x64, 0x6d, 0x7d, 0x5d, 0x8b, 0x7a, 0x8b, 0x82, + 0x8c, 0x79, 0x91, 0x08, 0x65, 0x45, 0x05, 0xf7, 0xde, 0xf7, 0x6e, 0x15, + 0xf7, 0x55, 0xf7, 0x91, 0x62, 0xfb, 0x91, 0xfb, 0x2c, 0x8b, 0x05, 0xde, + 0xf8, 0x40, 0x15, 0xb0, 0xbb, 0x9a, 0x97, 0xa4, 0x8b, 0x99, 0x8b, 0x9a, + 0x86, 0xa0, 0x7f, 0xbe, 0x6e, 0x96, 0x86, 0xa2, 0x8b, 0xaa, 0x8b, 0x9f, + 0x9b, 0xc1, 0xcf, 0x08, 0x81, 0x9c, 0x05, 0x71, 0x73, 0x89, 0x89, 0x83, + 0x85, 0x7c, 0x81, 0x74, 0x82, 0x7c, 0x8b, 0x7e, 0x8b, 0x74, 0x93, 0x75, + 0x98, 0x65, 0xa0, 0x81, 0x8f, 0x77, 0x8b, 0x6b, 0x8b, 0x73, 0x77, 0x5a, + 0x48, 0x08, 0x98, 0x79, 0x05, 0x0e, 0xf7, 0xc7, 0xa2, 0x94, 0x15, 0xa2, + 0x84, 0x97, 0x89, 0x9d, 0x8b, 0xcf, 0x8b, 0xb9, 0xae, 0xf7, 0x18, 0xf7, + 0x2b, 0xda, 0x8b, 0xc6, 0x8a, 0xb2, 0x88, 0x89, 0x7f, 0x89, 0x7f, 0x8a, + 0x7f, 0x89, 0x7e, 0x88, 0x78, 0x88, 0x76, 0x89, 0x78, 0x88, 0x78, 0x8a, + 0x88, 0x08, 0x88, 0x7a, 0x89, 0x7b, 0x8b, 0x81, 0x08, 0x7f, 0x95, 0x81, + 0x98, 0x1e, 0x92, 0x8b, 0x95, 0x8c, 0x97, 0x8e, 0xbb, 0x94, 0xbb, 0x94, + 0xbb, 0x93, 0x08, 0x9b, 0xa3, 0x05, 0x81, 0x8a, 0x81, 0x8a, 0x88, 0x8b, + 0x6c, 0x88, 0x86, 0x8b, 0x7c, 0x8b, 0x64, 0x8b, 0x7f, 0x95, 0x8b, 0xae, + 0x8b, 0xca, 0xb3, 0xf7, 0xb0, 0xaa, 0xf7, 0x30, 0x08, 0x7d, 0x95, 0x05, + 0x87, 0x87, 0x87, 0x87, 0x88, 0x87, 0x7b, 0x7b, 0x82, 0x87, 0x7a, 0x8b, + 0x7f, 0x8b, 0x87, 0x8b, 0x62, 0x92, 0x5d, 0x92, 0x72, 0x8e, 0x77, 0x8b, + 0x5d, 0x8b, 0x5b, 0x74, 0x5c, 0x5d, 0x56, 0x58, 0x74, 0x5e, 0x8b, 0x56, + 0x08, 0x8b, 0x74, 0x8e, 0x7b, 0x96, 0x6e, 0x08, 0xd5, 0xb3, 0x05, 0x7b, + 0xba, 0x86, 0xa2, 0x8b, 0xa2, 0x8b, 0xc4, 0xb6, 0xad, 0xd4, 0x8b, 0x96, + 0x8b, 0x97, 0x8a, 0x99, 0x8a, 0x08, 0xb3, 0x86, 0x9a, 0x8a, 0x05, 0x9c, + 0x89, 0x93, 0x8b, 0xa6, 0x89, 0x08, 0xfb, 0x41, 0xfb, 0x74, 0x05, 0x61, + 0x55, 0x49, 0x3e, 0x71, 0x72, 0x08, 0x63, 0x64, 0x6d, 0x7d, 0x5d, 0x8b, + 0x7a, 0x8b, 0x82, 0x8c, 0x79, 0x91, 0x08, 0x65, 0x45, 0x05, 0xf7, 0xde, + 0xf7, 0x6e, 0x15, 0xf7, 0x55, 0xf7, 0x91, 0x62, 0xfb, 0x91, 0xfb, 0x2c, + 0x8b, 0x05, 0xf7, 0x95, 0xf8, 0xd3, 0x15, 0x4a, 0x5b, 0x5a, 0x48, 0x63, + 0xa3, 0x74, 0xb5, 0xc9, 0xc0, 0xc1, 0xca, 0xb2, 0x71, 0xa2, 0x61, 0x1f, + 0x7d, 0x75, 0x15, 0xa1, 0x98, 0x78, 0x6b, 0x5d, 0x71, 0x65, 0x6c, 0x77, + 0x7d, 0xa0, 0xaa, 0xbb, 0xa3, 0xae, 0xab, 0x1f, 0x0e, 0xf7, 0x63, 0xf7, + 0xa8, 0x44, 0x15, 0xd7, 0x93, 0xf6, 0xb8, 0xca, 0xbe, 0x08, 0x92, 0xa9, + 0x05, 0x2f, 0x4c, 0x47, 0x71, 0x45, 0x8b, 0x08, 0x3c, 0x59, 0xc7, 0xea, + 0xf7, 0x64, 0xf7, 0x27, 0xf7, 0x63, 0xf7, 0x28, 0x1f, 0xc7, 0x8b, 0xa9, + 0x66, 0x91, 0x3c, 0x08, 0xd5, 0xca, 0x05, 0x82, 0xd0, 0x67, 0xaa, 0x43, + 0x8b, 0x34, 0x8b, 0x26, 0x58, 0x33, 0x33, 0x2a, 0x2a, 0x52, 0xfb, 0x19, + 0x8b, 0xfb, 0x16, 0x8b, 0x25, 0xc1, 0x4f, 0xea, 0x88, 0x08, 0x4f, 0x43, + 0x05, 0xa0, 0x7b, 0x91, 0x82, 0x8b, 0x7d, 0x8b, 0x7f, 0x85, 0x83, 0x76, + 0x7a, 0x74, 0x79, 0x80, 0x86, 0x6e, 0x83, 0x08, 0x9a, 0x7d, 0x05, 0xe0, + 0xa1, 0xbf, 0xb4, 0x8b, 0xba, 0x8b, 0x9e, 0x82, 0x99, 0x7c, 0x90, 0x08, + 0xad, 0xba, 0x05, 0x0e, 0xf8, 0x17, 0xf7, 0xc7, 0xf7, 0x90, 0x15, 0x64, + 0xfb, 0x3b, 0x71, 0x6c, 0xfb, 0x00, 0x83, 0x08, 0x5b, 0x5d, 0xf7, 0x13, + 0x8b, 0x05, 0xf7, 0x38, 0x8b, 0xb4, 0x8e, 0xc0, 0x9e, 0xdb, 0xa6, 0xdd, + 0xbf, 0xb2, 0xbb, 0xbe, 0xca, 0xaf, 0xf4, 0x8b, 0xe1, 0x8b, 0xd0, 0x67, + 0xbf, 0x47, 0xa8, 0x60, 0x9e, 0x58, 0x94, 0x2a, 0x90, 0x08, 0x92, 0xa8, + 0x43, 0x6c, 0x05, 0x39, 0x7e, 0x57, 0x79, 0x56, 0x69, 0x35, 0x54, 0x63, + 0x48, 0x8b, 0x34, 0x8b, 0x78, 0x8d, 0x7f, 0x90, 0x72, 0x08, 0xdd, 0xb0, + 0x05, 0x85, 0xa5, 0x8a, 0x96, 0x8b, 0x9e, 0x8b, 0xf7, 0x0c, 0xd5, 0xd1, + 0xf7, 0x20, 0x99, 0x08, 0x50, 0xfb, 0x7d, 0x05, 0x6c, 0x8c, 0x8a, 0x8b, + 0x7b, 0x8c, 0x84, 0x85, 0x87, 0x87, 0x89, 0x89, 0x83, 0x87, 0x84, 0x87, + 0x83, 0x86, 0x89, 0x8a, 0x82, 0x85, 0x82, 0x85, 0xa5, 0x8c, 0x9e, 0x8c, + 0x98, 0x8b, 0x8f, 0x8b, 0x8b, 0x8b, 0xad, 0x8a, 0x08, 0x83, 0x6c, 0x05, + 0xf7, 0x6e, 0xaa, 0x15, 0xb5, 0xb0, 0x05, 0x6d, 0x8b, 0x83, 0x8b, 0x73, + 0x8a, 0x78, 0x8a, 0x8b, 0x8b, 0x57, 0x8b, 0x08, 0x65, 0x8b, 0xc7, 0xf7, + 0x81, 0x05, 0xd4, 0x89, 0xad, 0x85, 0xaa, 0x7a, 0xbc, 0x72, 0xa8, 0x53, + 0x8b, 0x48, 0x8b, 0x34, 0x6a, 0x21, 0x5e, 0x52, 0x5a, 0x4c, 0x50, 0x73, + 0x24, 0x8b, 0x08, 0x7c, 0x8b, 0xfb, 0x14, 0x8f, 0x05, 0xf7, 0x00, 0xef, + 0x92, 0x97, 0xac, 0xf7, 0x0e, 0x08, 0xf7, 0x1d, 0x06, 0x0e, 0xf7, 0xc7, + 0xf7, 0xfe, 0xf7, 0xc7, 0x15, 0xc4, 0xf7, 0x77, 0xaa, 0x8b, 0x05, 0xb5, + 0x8d, 0xaa, 0x8c, 0x91, 0x8b, 0xb2, 0x8b, 0x92, 0x84, 0xa6, 0x49, 0x08, + 0xcd, 0xcd, 0x05, 0x88, 0xa1, 0x83, 0x96, 0x7a, 0x91, 0x08, 0xfb, 0x6a, + 0x87, 0x91, 0xa0, 0x45, 0x76, 0x05, 0x2b, 0x8a, 0x4e, 0x78, 0x52, 0x5e, + 0x59, 0x63, 0x75, 0x63, 0x8b, 0x57, 0x8b, 0x71, 0x8f, 0x77, 0x99, 0x68, + 0x08, 0xd3, 0xbb, 0x05, 0x82, 0xab, 0x87, 0xa5, 0x8b, 0xa4, 0x8b, 0xd9, + 0xc3, 0xab, 0xf7, 0x1c, 0x8f, 0x08, 0x53, 0xfb, 0x75, 0x05, 0x7a, 0x7a, + 0x86, 0x85, 0x7a, 0x77, 0x08, 0xa7, 0x06, 0x87, 0x7c, 0x88, 0x7e, 0x87, + 0x7f, 0x65, 0xfb, 0x2e, 0x80, 0x7a, 0x39, 0x77, 0x08, 0x65, 0x6a, 0x05, + 0xa7, 0x8a, 0xa0, 0x8b, 0x92, 0x8b, 0x08, 0xe5, 0x8a, 0x05, 0xa9, 0x8b, + 0xa6, 0x8a, 0xa2, 0x8a, 0x08, 0xf7, 0x0d, 0x87, 0x8c, 0x8b, 0xb6, 0x8b, + 0xbf, 0x8b, 0x99, 0x91, 0xb8, 0xb4, 0xb9, 0xb4, 0x9c, 0xa3, 0x8b, 0xa2, + 0x8b, 0x90, 0x8a, 0x93, 0x88, 0x95, 0x08, 0x3f, 0x6f, 0x05, 0x8e, 0x76, + 0x8c, 0x83, 0x8b, 0x82, 0x08, 0x65, 0x7e, 0x86, 0x2b, 0x1e, 0xfb, 0x98, + 0x06, 0xec, 0xe4, 0x8c, 0x8d, 0xaf, 0xf7, 0x1d, 0xbe, 0x8e, 0x91, 0x8b, + 0xa3, 0x8d, 0xa1, 0x8c, 0x9a, 0x8c, 0x91, 0x8b, 0x8f, 0x8c, 0x96, 0x8b, + 0x97, 0x8c, 0x9d, 0x98, 0x8d, 0x8d, 0x9d, 0x99, 0x08, 0xfb, 0x47, 0x06, + 0xf7, 0x4d, 0xf7, 0xeb, 0x15, 0xa1, 0xa0, 0x8e, 0x8e, 0x93, 0x91, 0x08, + 0xab, 0xa4, 0x05, 0x7f, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, 0x8a, + 0x8e, 0x81, 0xa4, 0x87, 0x88, 0x87, 0x88, 0x85, 0x86, 0x7a, 0x7d, 0x81, + 0x83, 0x87, 0x88, 0x84, 0x86, 0x86, 0x88, 0x7f, 0x82, 0x93, 0x74, 0x93, + 0x7b, 0xa1, 0x6c, 0x08, 0xfb, 0x19, 0x16, 0xac, 0xa9, 0x05, 0x91, 0x90, + 0x8f, 0x8d, 0xa1, 0x9d, 0x80, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, + 0x8a, 0x8e, 0x80, 0xa4, 0x86, 0x87, 0x87, 0x87, 0x86, 0x88, 0x71, 0x75, + 0x88, 0x89, 0x71, 0x79, 0x93, 0x74, 0x93, 0x7d, 0xa1, 0x6a, 0x08, 0x0e, + 0xf7, 0xc7, 0xf7, 0xfe, 0xf7, 0xc7, 0x15, 0xc4, 0xf7, 0x77, 0xaa, 0x8b, + 0x05, 0xb5, 0x8d, 0xaa, 0x8c, 0x91, 0x8b, 0xb2, 0x8b, 0x92, 0x84, 0xa6, + 0x49, 0x08, 0xcd, 0xcd, 0x05, 0x88, 0xa1, 0x83, 0x96, 0x7a, 0x91, 0x08, + 0xfb, 0x6a, 0x87, 0x91, 0xa0, 0x45, 0x76, 0x05, 0x2b, 0x8a, 0x4e, 0x78, + 0x52, 0x5e, 0x59, 0x63, 0x75, 0x63, 0x8b, 0x57, 0x8b, 0x71, 0x8f, 0x77, + 0x99, 0x68, 0x08, 0xd3, 0xbb, 0x05, 0x82, 0xab, 0x87, 0xa5, 0x8b, 0xa4, + 0x8b, 0xd9, 0xc3, 0xab, 0xf7, 0x1c, 0x8f, 0x08, 0x53, 0xfb, 0x75, 0x05, + 0x7a, 0x7a, 0x86, 0x85, 0x7a, 0x77, 0x08, 0xa7, 0x06, 0x87, 0x7c, 0x88, + 0x7e, 0x87, 0x7f, 0x65, 0xfb, 0x2e, 0x80, 0x7a, 0x39, 0x77, 0x08, 0x65, + 0x6a, 0x05, 0xa7, 0x8a, 0xa0, 0x8b, 0x92, 0x8b, 0x08, 0xe5, 0x8a, 0x05, + 0xa9, 0x8b, 0xa6, 0x8a, 0xa2, 0x8a, 0x08, 0xf7, 0x0d, 0x87, 0x8c, 0x8b, + 0xb6, 0x8b, 0xbf, 0x8b, 0x99, 0x91, 0xb8, 0xb4, 0xb9, 0xb4, 0x9c, 0xa3, + 0x8b, 0xa2, 0x8b, 0x90, 0x8a, 0x93, 0x88, 0x95, 0x08, 0x3f, 0x6f, 0x05, + 0x8e, 0x76, 0x8c, 0x83, 0x8b, 0x82, 0x08, 0x65, 0x7e, 0x86, 0x2b, 0x1e, + 0xfb, 0x98, 0x06, 0xec, 0xe4, 0x8c, 0x8d, 0xaf, 0xf7, 0x1d, 0xbe, 0x8e, + 0x91, 0x8b, 0xa3, 0x8d, 0xa1, 0x8c, 0x9a, 0x8c, 0x91, 0x8b, 0x8f, 0x8c, + 0x96, 0x8b, 0x97, 0x8c, 0x9d, 0x98, 0x8d, 0x8d, 0x9d, 0x99, 0x08, 0xfb, + 0x47, 0x06, 0xde, 0xf7, 0xd2, 0x15, 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, 0xda, + 0x08, 0x5f, 0xa0, 0xfb, 0x1f, 0xfb, 0x50, 0xa3, 0x84, 0x05, 0x0e, 0xf7, + 0xc7, 0xf7, 0xfe, 0xf7, 0xc7, 0x15, 0xc4, 0xf7, 0x77, 0xaa, 0x8b, 0x05, + 0xb5, 0x8d, 0xaa, 0x8c, 0x91, 0x8b, 0xb2, 0x8b, 0x92, 0x84, 0xa6, 0x49, + 0x08, 0xcd, 0xcd, 0x05, 0x88, 0xa1, 0x83, 0x96, 0x7a, 0x91, 0x08, 0xfb, + 0x6a, 0x87, 0x91, 0xa0, 0x45, 0x76, 0x05, 0x2b, 0x8a, 0x4e, 0x78, 0x52, + 0x5e, 0x59, 0x63, 0x75, 0x63, 0x8b, 0x57, 0x8b, 0x71, 0x8f, 0x77, 0x99, + 0x68, 0x08, 0xd3, 0xbb, 0x05, 0x82, 0xab, 0x87, 0xa5, 0x8b, 0xa4, 0x8b, + 0xd9, 0xc3, 0xab, 0xf7, 0x1c, 0x8f, 0x08, 0x53, 0xfb, 0x75, 0x05, 0x7a, + 0x7a, 0x86, 0x85, 0x7a, 0x77, 0x08, 0xa7, 0x06, 0x87, 0x7c, 0x88, 0x7e, + 0x87, 0x7f, 0x65, 0xfb, 0x2e, 0x80, 0x7a, 0x39, 0x77, 0x08, 0x65, 0x6a, + 0x05, 0xa7, 0x8a, 0xa0, 0x8b, 0x92, 0x8b, 0x08, 0xe5, 0x8a, 0x05, 0xa9, + 0x8b, 0xa6, 0x8a, 0xa2, 0x8a, 0x08, 0xf7, 0x0d, 0x87, 0x8c, 0x8b, 0xb6, + 0x8b, 0xbf, 0x8b, 0x99, 0x91, 0xb8, 0xb4, 0xb9, 0xb4, 0x9c, 0xa3, 0x8b, + 0xa2, 0x8b, 0x90, 0x8a, 0x93, 0x88, 0x95, 0x08, 0x3f, 0x6f, 0x05, 0x8e, + 0x76, 0x8c, 0x83, 0x8b, 0x82, 0x08, 0x65, 0x7e, 0x86, 0x2b, 0x1e, 0xfb, + 0x98, 0x06, 0xec, 0xe4, 0x8c, 0x8d, 0xaf, 0xf7, 0x1d, 0xbe, 0x8e, 0x91, + 0x8b, 0xa3, 0x8d, 0xa1, 0x8c, 0x9a, 0x8c, 0x91, 0x8b, 0x8f, 0x8c, 0x96, + 0x8b, 0x97, 0x8c, 0x9d, 0x98, 0x8d, 0x8d, 0x9d, 0x99, 0x08, 0xfb, 0x47, + 0x06, 0xf7, 0x10, 0xf7, 0xd2, 0x15, 0x94, 0x8d, 0x8f, 0x8c, 0x97, 0x8e, + 0x74, 0xda, 0x84, 0xa2, 0x6b, 0xe2, 0x87, 0x89, 0x84, 0x88, 0x86, 0x88, + 0x82, 0x86, 0x85, 0x88, 0x89, 0x8a, 0x89, 0x8a, 0x85, 0x88, 0x86, 0x88, + 0x9f, 0x66, 0x9b, 0x6a, 0xba, 0x26, 0x08, 0x0e, 0xf7, 0xc7, 0xf7, 0xfe, + 0xf7, 0xc7, 0x15, 0xc4, 0xf7, 0x77, 0xaa, 0x8b, 0x05, 0xb5, 0x8d, 0xaa, + 0x8c, 0x91, 0x8b, 0xb2, 0x8b, 0x92, 0x84, 0xa6, 0x49, 0x08, 0xcd, 0xcd, + 0x05, 0x88, 0xa1, 0x83, 0x96, 0x7a, 0x91, 0x08, 0xfb, 0x6a, 0x87, 0x91, + 0xa0, 0x45, 0x76, 0x05, 0x2b, 0x8a, 0x4e, 0x78, 0x52, 0x5e, 0x59, 0x63, + 0x75, 0x63, 0x8b, 0x57, 0x8b, 0x71, 0x8f, 0x77, 0x99, 0x68, 0x08, 0xd3, + 0xbb, 0x05, 0x82, 0xab, 0x87, 0xa5, 0x8b, 0xa4, 0x8b, 0xd9, 0xc3, 0xab, + 0xf7, 0x1c, 0x8f, 0x08, 0x53, 0xfb, 0x75, 0x05, 0x7a, 0x7a, 0x86, 0x85, + 0x7a, 0x77, 0x08, 0xa7, 0x06, 0x87, 0x7c, 0x88, 0x7e, 0x87, 0x7f, 0x65, + 0xfb, 0x2e, 0x80, 0x7a, 0x39, 0x77, 0x08, 0x65, 0x6a, 0x05, 0xa7, 0x8a, + 0xa0, 0x8b, 0x92, 0x8b, 0x08, 0xe5, 0x8a, 0x05, 0xa9, 0x8b, 0xa6, 0x8a, + 0xa2, 0x8a, 0x08, 0xf7, 0x0d, 0x87, 0x8c, 0x8b, 0xb6, 0x8b, 0xbf, 0x8b, + 0x99, 0x91, 0xb8, 0xb4, 0xb9, 0xb4, 0x9c, 0xa3, 0x8b, 0xa2, 0x8b, 0x90, + 0x8a, 0x93, 0x88, 0x95, 0x08, 0x3f, 0x6f, 0x05, 0x8e, 0x76, 0x8c, 0x83, + 0x8b, 0x82, 0x08, 0x65, 0x7e, 0x86, 0x2b, 0x1e, 0xfb, 0x98, 0x06, 0xec, + 0xe4, 0x8c, 0x8d, 0xaf, 0xf7, 0x1d, 0xbe, 0x8e, 0x91, 0x8b, 0xa3, 0x8d, + 0xa1, 0x8c, 0x9a, 0x8c, 0x91, 0x8b, 0x8f, 0x8c, 0x96, 0x8b, 0x97, 0x8c, + 0x9d, 0x98, 0x8d, 0x8d, 0x9d, 0x99, 0x08, 0xfb, 0x47, 0x06, 0xf7, 0x68, + 0xf8, 0x07, 0x15, 0x86, 0xc3, 0x05, 0x8a, 0x96, 0x89, 0xa0, 0x88, 0xc0, + 0x85, 0x8c, 0x87, 0x8c, 0x88, 0x8b, 0x89, 0x8b, 0x87, 0x8a, 0x83, 0x8a, + 0x5e, 0x65, 0x77, 0x78, 0xfb, 0x00, 0xfb, 0x01, 0x8c, 0x87, 0x8b, 0x87, + 0x8c, 0x8a, 0x8b, 0x8a, 0x8b, 0x88, 0x8c, 0x85, 0x08, 0x8b, 0x8a, 0x8b, + 0x87, 0x8c, 0x87, 0x08, 0xdc, 0xd5, 0x05, 0xa4, 0xa1, 0x9a, 0x97, 0xac, + 0xa5, 0x90, 0x6d, 0x8f, 0x75, 0x8c, 0x7f, 0x8e, 0x7b, 0x8d, 0x7c, 0x8d, + 0x7b, 0x8c, 0x85, 0x8b, 0x85, 0x8d, 0x80, 0x9d, 0x96, 0x90, 0x8e, 0x98, + 0x91, 0x08, 0x88, 0xac, 0x05, 0x0e, 0xce, 0xdc, 0x16, 0xcc, 0x8c, 0x8b, + 0x8b, 0x99, 0x8b, 0x08, 0xf7, 0x30, 0x8a, 0xaf, 0xa4, 0x2e, 0x92, 0x05, + 0x9d, 0xe0, 0xd1, 0xf7, 0xab, 0xb4, 0xf7, 0x26, 0x08, 0xc5, 0x91, 0xae, + 0xa4, 0x69, 0x8b, 0x05, 0x25, 0x8a, 0x8b, 0x8b, 0x7a, 0x8b, 0x7b, 0x8b, + 0x87, 0x8b, 0x52, 0x8c, 0x08, 0x68, 0x72, 0xe5, 0x85, 0x05, 0x83, 0x66, + 0x85, 0x72, 0x8a, 0x86, 0x08, 0x76, 0x39, 0x3c, 0xfb, 0xc8, 0x7c, 0x56, + 0x51, 0x84, 0x66, 0x72, 0x05, 0xf8, 0x02, 0xf9, 0x99, 0x15, 0x82, 0x84, + 0x87, 0x87, 0x8a, 0x8b, 0x6f, 0x74, 0x89, 0x89, 0x72, 0x7a, 0x93, 0x74, + 0x92, 0x7d, 0xa2, 0x6a, 0xa2, 0xa0, 0x8f, 0x8f, 0x91, 0x90, 0x8e, 0x8d, + 0x92, 0x91, 0x96, 0x93, 0x8e, 0x8d, 0x8f, 0x8f, 0x8f, 0x8e, 0x08, 0x7a, + 0xa7, 0x89, 0x8e, 0x81, 0xa3, 0x08, 0x86, 0x98, 0x05, 0x28, 0x47, 0x15, + 0x7a, 0xa7, 0x8a, 0x8e, 0x81, 0xa3, 0x08, 0x85, 0x98, 0x7d, 0x80, 0x05, + 0x71, 0x75, 0x87, 0x88, 0x72, 0x7a, 0x93, 0x73, 0x92, 0x80, 0xa2, 0x68, + 0x97, 0x96, 0x92, 0x91, 0x8d, 0x8e, 0x08, 0xac, 0xa5, 0x96, 0x94, 0x05, + 0x0e, 0xce, 0xdc, 0x16, 0xcc, 0x8c, 0x8b, 0x8b, 0x99, 0x8b, 0x08, 0xf7, + 0x30, 0x8a, 0xaf, 0xa4, 0x2e, 0x92, 0x05, 0x9e, 0xe3, 0xca, 0xf7, 0x8e, + 0xba, 0xf7, 0x40, 0x08, 0xc5, 0x91, 0xae, 0xa4, 0x69, 0x8b, 0x05, 0x25, + 0x8a, 0x8b, 0x8b, 0x7a, 0x8b, 0x7b, 0x8b, 0x87, 0x8b, 0x52, 0x8c, 0x08, + 0x68, 0x72, 0xe5, 0x85, 0x05, 0x83, 0x66, 0x85, 0x72, 0x8a, 0x86, 0x08, + 0x76, 0x39, 0x05, 0x4c, 0xfb, 0x8b, 0x80, 0x5f, 0x86, 0x7a, 0x89, 0x85, + 0x85, 0x74, 0x84, 0x73, 0x08, 0x50, 0x84, 0x67, 0x72, 0x05, 0xf7, 0x7b, + 0xf9, 0x05, 0x15, 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, 0xda, 0x08, 0x5e, 0xa0, + 0x05, 0x51, 0x3a, 0x5d, 0x4c, 0x69, 0x5f, 0x08, 0xa3, 0x84, 0x05, 0x0e, + 0xce, 0xdc, 0x16, 0xcc, 0x8c, 0x8b, 0x8b, 0x99, 0x8b, 0x08, 0xf7, 0x30, + 0x8a, 0xaf, 0xa4, 0x2e, 0x92, 0x05, 0x9d, 0xe0, 0xd1, 0xf7, 0xab, 0xb4, + 0xf7, 0x26, 0x08, 0xc5, 0x91, 0xae, 0xa4, 0x69, 0x8b, 0x05, 0x25, 0x8a, + 0x8b, 0x8b, 0x7a, 0x8b, 0x7b, 0x8b, 0x87, 0x8b, 0x52, 0x8c, 0x08, 0x68, + 0x72, 0xe5, 0x85, 0x05, 0x83, 0x66, 0x85, 0x72, 0x8a, 0x86, 0x08, 0x76, + 0x39, 0x3c, 0xfb, 0xc8, 0x7c, 0x56, 0x51, 0x84, 0x66, 0x72, 0x05, 0xf7, + 0x73, 0xf9, 0xb0, 0x15, 0xa1, 0x63, 0x94, 0x79, 0xbf, 0xfb, 0x05, 0x95, + 0x8d, 0x8e, 0x8c, 0x97, 0x8e, 0x74, 0xda, 0x84, 0xa2, 0x6b, 0xe2, 0x86, + 0x88, 0x85, 0x88, 0x86, 0x89, 0x82, 0x86, 0x86, 0x88, 0x88, 0x8a, 0x08, + 0x7e, 0x84, 0x05, 0x0e, 0xce, 0xdc, 0x16, 0xcc, 0x8c, 0x8b, 0x8b, 0x99, + 0x8b, 0x08, 0xf7, 0x30, 0x8a, 0xaf, 0xa4, 0x2e, 0x92, 0x05, 0x9e, 0xe3, + 0xca, 0xf7, 0x8e, 0xba, 0xf7, 0x40, 0x08, 0xc5, 0x91, 0xae, 0xa4, 0x69, + 0x8b, 0x05, 0x25, 0x8a, 0x8b, 0x8b, 0x7a, 0x8b, 0x7b, 0x8b, 0x87, 0x8b, + 0x52, 0x8c, 0x08, 0x68, 0x72, 0xe5, 0x85, 0x05, 0x83, 0x66, 0x85, 0x72, + 0x8a, 0x86, 0x08, 0x76, 0x39, 0x05, 0x4c, 0xfb, 0x8b, 0x80, 0x5f, 0x86, + 0x7a, 0x89, 0x85, 0x85, 0x74, 0x84, 0x73, 0x08, 0x50, 0x84, 0x67, 0x72, + 0x05, 0xf7, 0x57, 0xf9, 0x0e, 0x15, 0x8c, 0x82, 0xdc, 0xd5, 0x05, 0xa4, + 0xa1, 0x9a, 0x97, 0xac, 0xa5, 0x08, 0x96, 0x4b, 0x91, 0x5c, 0x05, 0x8c, + 0x85, 0x8c, 0x85, 0x8c, 0x80, 0x9e, 0x96, 0x8f, 0x8e, 0x98, 0x91, 0x08, + 0x88, 0xac, 0x05, 0x8a, 0x9e, 0x89, 0x9d, 0x89, 0x9e, 0x8a, 0x96, 0x8a, + 0xa0, 0x87, 0xc0, 0x86, 0x8c, 0x86, 0x8c, 0x88, 0x8b, 0x89, 0x8b, 0x87, + 0x8a, 0x83, 0x8a, 0x5f, 0x65, 0x76, 0x78, 0xfb, 0x00, 0xfb, 0x01, 0x8c, + 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8c, 0x81, 0x05, 0x0e, 0xf8, 0x17, + 0xb3, 0x16, 0xa6, 0x89, 0x99, 0x8a, 0x99, 0x8b, 0xb6, 0x8b, 0xa6, 0x91, + 0xa5, 0x9b, 0xbc, 0xa8, 0xbd, 0xd3, 0xab, 0xdf, 0x9b, 0xb6, 0x91, 0xa1, + 0xb6, 0xf7, 0x41, 0x08, 0xb0, 0xfb, 0x2f, 0x05, 0xa8, 0xfb, 0x10, 0xa3, + 0x42, 0xad, 0x47, 0xc8, 0xfb, 0x10, 0xe3, 0x4e, 0xf7, 0x0a, 0x8b, 0xbe, + 0x8b, 0xaf, 0x94, 0xb8, 0xa5, 0x08, 0x73, 0xe4, 0x05, 0x7d, 0x6a, 0x84, + 0x7d, 0x7e, 0x7c, 0x79, 0x75, 0x72, 0x7e, 0x72, 0x8b, 0x4c, 0x8b, 0x51, + 0xbc, 0x58, 0xec, 0x9c, 0xe1, 0x94, 0xb2, 0xa4, 0xf4, 0xb6, 0xf7, 0x42, + 0xa1, 0xd3, 0xab, 0xcd, 0xa0, 0xb5, 0xa3, 0x9b, 0xb9, 0x8b, 0x08, 0x92, + 0x8b, 0x91, 0x8b, 0x99, 0x89, 0x08, 0xb0, 0xce, 0x05, 0x7f, 0x8c, 0x80, + 0x8c, 0x83, 0x8b, 0x61, 0x8b, 0x5e, 0x6e, 0x57, 0x4e, 0x5b, 0x53, 0x79, + 0x58, 0x5a, 0xfb, 0x6c, 0x81, 0x5c, 0x80, 0x5c, 0x80, 0x5b, 0x8a, 0x86, + 0x86, 0x76, 0x82, 0x6c, 0x5b, 0xeb, 0x7e, 0xb2, 0x21, 0xf8, 0x20, 0x08, + 0x69, 0x6c, 0x05, 0x73, 0x8d, 0x7e, 0x8c, 0x79, 0x8b, 0x4f, 0x8b, 0x67, + 0x80, 0x67, 0x6f, 0x4b, 0x59, 0x5f, 0x43, 0x8b, 0x54, 0x8b, 0x72, 0x92, + 0x71, 0x9d, 0x66, 0x08, 0xd0, 0xba, 0x05, 0x72, 0xc0, 0x84, 0xa2, 0x8b, + 0xa4, 0x8b, 0xa9, 0x9c, 0xa6, 0xa7, 0x9a, 0xa3, 0x98, 0xa3, 0x8f, 0xb8, + 0x8b, 0xa0, 0x8b, 0x9d, 0x8b, 0xb1, 0x89, 0x5c, 0xfb, 0x5d, 0x65, 0xfb, + 0x12, 0x6a, 0x50, 0x76, 0x66, 0x75, 0x80, 0x56, 0x8b, 0x08, 0x78, 0x8b, + 0x7c, 0x8c, 0x6f, 0x8e, 0x08, 0x5b, 0x46, 0x05, 0xf8, 0x3e, 0xf9, 0x23, + 0x15, 0xb0, 0xbb, 0x9a, 0x97, 0xa4, 0x8b, 0x99, 0x8b, 0x99, 0x86, 0xa0, + 0x7f, 0xbe, 0x6e, 0x97, 0x86, 0xa2, 0x8b, 0xa9, 0x8b, 0x9f, 0x9b, 0xc2, + 0xcf, 0x08, 0x80, 0x9c, 0x05, 0x72, 0x73, 0x89, 0x89, 0x83, 0x85, 0x7c, + 0x81, 0x73, 0x82, 0x7c, 0x8b, 0x7e, 0x8b, 0x75, 0x93, 0x75, 0x98, 0x64, + 0xa0, 0x82, 0x8f, 0x77, 0x8b, 0x6b, 0x8b, 0x72, 0x77, 0x5b, 0x48, 0x08, + 0x98, 0x79, 0x05, 0x0e, 0xf7, 0xb3, 0xf8, 0x7b, 0xf8, 0xe3, 0x15, 0x38, + 0x8b, 0x21, 0x61, 0x46, 0x50, 0x3b, 0x45, 0x5e, 0xfb, 0x03, 0x8b, 0xfb, + 0x12, 0x8b, 0xfb, 0x14, 0xc6, 0x47, 0xf7, 0x03, 0x8b, 0xe6, 0x8b, 0xef, + 0xb6, 0xd6, 0xd3, 0xd3, 0xd1, 0xb3, 0xf3, 0x8b, 0xf7, 0x0c, 0x8b, 0xf7, + 0x12, 0x51, 0xd0, 0x20, 0x8b, 0x08, 0x51, 0x64, 0x15, 0xe4, 0xbf, 0x45, + 0xfb, 0x08, 0x1f, 0x8b, 0x3f, 0x76, 0x36, 0x6b, 0x51, 0x60, 0x3f, 0x47, + 0x5f, 0x41, 0x8b, 0x08, 0x2f, 0x55, 0xd3, 0xf7, 0x0f, 0xf7, 0x4d, 0xf6, + 0xf7, 0x25, 0xf7, 0x1c, 0x1f, 0xf7, 0x00, 0xed, 0x15, 0xa1, 0xa0, 0x8f, + 0x8e, 0x92, 0x91, 0x90, 0x90, 0x8f, 0x8d, 0xa2, 0x9d, 0x80, 0x9d, 0x87, + 0x93, 0x86, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x81, 0xa4, 0x85, 0x86, 0x86, + 0x88, 0x88, 0x88, 0x6e, 0x73, 0x8b, 0x8b, 0x71, 0x79, 0x08, 0x93, 0x74, + 0x93, 0x7b, 0xa1, 0x6c, 0x08, 0xfb, 0x19, 0x16, 0xac, 0xa9, 0x05, 0x91, + 0x90, 0x90, 0x8e, 0xa0, 0x9c, 0x81, 0x9d, 0x86, 0x93, 0x87, 0x93, 0x08, + 0x7c, 0xad, 0x05, 0x87, 0x88, 0x84, 0x85, 0x88, 0x89, 0x71, 0x75, 0x88, + 0x89, 0x71, 0x79, 0x93, 0x73, 0x92, 0x7e, 0xa2, 0x6a, 0x08, 0x0e, 0xf7, + 0xb3, 0xf8, 0x7b, 0xf8, 0xe3, 0x15, 0x38, 0x8b, 0x21, 0x61, 0x46, 0x50, + 0x3b, 0x45, 0x5e, 0xfb, 0x03, 0x8b, 0xfb, 0x12, 0x8b, 0xfb, 0x14, 0xc6, + 0x47, 0xf7, 0x03, 0x8b, 0xe6, 0x8b, 0xef, 0xb6, 0xd6, 0xd3, 0xd3, 0xd1, + 0xb3, 0xf3, 0x8b, 0xf7, 0x0d, 0x8b, 0xf7, 0x11, 0x51, 0xd0, 0x20, 0x8b, + 0x08, 0x51, 0x64, 0x15, 0xe4, 0xbf, 0x45, 0xfb, 0x08, 0x1f, 0x8b, 0x3f, + 0x76, 0x36, 0x6b, 0x51, 0x60, 0x3f, 0x47, 0x5f, 0x41, 0x8b, 0x08, 0x2f, + 0x55, 0xd3, 0xf7, 0x0f, 0xf7, 0x4d, 0xf6, 0xf7, 0x25, 0xf7, 0x1c, 0x1f, + 0x8e, 0xd4, 0x15, 0xca, 0xd4, 0x9d, 0xa0, 0xda, 0xdb, 0x08, 0x5e, 0xa0, + 0xfb, 0x1e, 0xfb, 0x50, 0xa2, 0x84, 0x05, 0x0e, 0xf7, 0xb3, 0xf8, 0x7b, + 0xf8, 0xe3, 0x15, 0x38, 0x8b, 0x21, 0x61, 0x46, 0x50, 0x3b, 0x45, 0x5e, + 0xfb, 0x03, 0x8b, 0xfb, 0x12, 0x8b, 0xfb, 0x14, 0xc6, 0x47, 0xf7, 0x03, + 0x8b, 0xe6, 0x8b, 0xef, 0xb6, 0xd6, 0xd3, 0xd3, 0xd1, 0xb3, 0xf3, 0x8b, + 0xf7, 0x0c, 0x8b, 0xf7, 0x12, 0x51, 0xd0, 0x20, 0x8b, 0x08, 0x51, 0x64, + 0x15, 0xe4, 0xbf, 0x45, 0xfb, 0x08, 0x1f, 0x8b, 0x3f, 0x76, 0x36, 0x6b, + 0x51, 0x60, 0x3f, 0x47, 0x5f, 0x41, 0x8b, 0x08, 0x2f, 0x55, 0xd3, 0xf7, + 0x0f, 0xf7, 0x4d, 0xf6, 0xf7, 0x25, 0xf7, 0x1c, 0x1f, 0x6a, 0xf7, 0x88, + 0x15, 0xa1, 0x63, 0x94, 0x79, 0xbf, 0xfb, 0x05, 0x95, 0x8d, 0x8e, 0x8c, + 0x97, 0x8e, 0x74, 0xda, 0x84, 0xa2, 0x6b, 0xe2, 0x86, 0x88, 0x85, 0x88, + 0x86, 0x89, 0x88, 0x89, 0x82, 0x86, 0x86, 0x89, 0x08, 0x7e, 0x84, 0x05, + 0x0e, 0xf7, 0xb3, 0xf8, 0x7b, 0xf8, 0xe3, 0x15, 0x38, 0x8b, 0x21, 0x61, + 0x46, 0x50, 0x3b, 0x45, 0x5e, 0xfb, 0x03, 0x8b, 0xfb, 0x12, 0x8b, 0xfb, + 0x14, 0xc6, 0x47, 0xf7, 0x03, 0x8b, 0xe6, 0x8b, 0xef, 0xb6, 0xd6, 0xd3, + 0xd3, 0xd1, 0xb3, 0xf3, 0x8b, 0xf7, 0x0c, 0x8b, 0xf7, 0x12, 0x51, 0xd0, + 0x20, 0x8b, 0x08, 0x51, 0x64, 0x15, 0xe4, 0xbf, 0x45, 0xfb, 0x08, 0x1f, + 0x8b, 0x3f, 0x76, 0x36, 0x6b, 0x51, 0x60, 0x3f, 0x47, 0x5f, 0x41, 0x8b, + 0x08, 0x2f, 0x55, 0xd3, 0xf7, 0x0f, 0xf7, 0x4d, 0xf6, 0xf7, 0x25, 0xf7, + 0x1c, 0x1f, 0xf4, 0xeb, 0x15, 0x8f, 0x74, 0x05, 0x9d, 0x96, 0x90, 0x8e, + 0x97, 0x91, 0x83, 0xe7, 0x8a, 0x96, 0x86, 0xd2, 0x86, 0x8c, 0x86, 0x8c, + 0x88, 0x8b, 0x89, 0x8b, 0x88, 0x8a, 0x82, 0x8a, 0x60, 0x67, 0x6d, 0x6d, + 0x27, 0x27, 0x8c, 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8b, 0x8a, 0x8c, + 0x87, 0x8c, 0x86, 0x8b, 0x8a, 0x8b, 0x87, 0x8c, 0x87, 0x08, 0xdc, 0xd5, + 0x05, 0xa3, 0xa0, 0x9a, 0x98, 0xac, 0xa5, 0x91, 0x6e, 0x8e, 0x75, 0x8d, + 0x7e, 0x08, 0x91, 0x5c, 0x05, 0x0e, 0xf7, 0xb3, 0xf8, 0x7b, 0xf8, 0xe3, + 0x15, 0x38, 0x8b, 0x21, 0x61, 0x46, 0x50, 0x3b, 0x45, 0x5e, 0xfb, 0x03, + 0x8b, 0xfb, 0x12, 0x8b, 0xfb, 0x14, 0xc6, 0x47, 0xf7, 0x03, 0x8b, 0xe6, + 0x8b, 0xef, 0xb6, 0xd6, 0xd3, 0xd3, 0xd1, 0xb3, 0xf3, 0x8b, 0xf7, 0x0c, + 0x8b, 0xf7, 0x12, 0x51, 0xd0, 0x20, 0x8b, 0x08, 0x51, 0x64, 0x15, 0xe4, + 0xbf, 0x45, 0xfb, 0x08, 0x1f, 0x8b, 0x3f, 0x76, 0x36, 0x6b, 0x51, 0x60, + 0x3f, 0x47, 0x5f, 0x41, 0x8b, 0x08, 0x2f, 0x55, 0xd3, 0xf7, 0x0f, 0xf7, + 0x4d, 0xf6, 0xf7, 0x25, 0xf7, 0x1c, 0x1f, 0x47, 0xf2, 0x15, 0xb0, 0xbb, + 0x9a, 0x97, 0xa4, 0x8b, 0x99, 0x8b, 0x9a, 0x86, 0xa0, 0x7f, 0xbe, 0x6e, + 0x96, 0x86, 0xa2, 0x8b, 0xaa, 0x8b, 0x9f, 0x9b, 0xc1, 0xcf, 0x08, 0x81, + 0x9c, 0x05, 0x71, 0x73, 0x89, 0x89, 0x83, 0x85, 0x7c, 0x81, 0x74, 0x82, + 0x7c, 0x8b, 0x7e, 0x8b, 0x74, 0x93, 0x75, 0x98, 0x65, 0xa0, 0x81, 0x8f, + 0x77, 0x8b, 0x6b, 0x8b, 0x73, 0x77, 0x5a, 0x48, 0x08, 0x98, 0x79, 0x05, + 0x0e, 0xf7, 0x27, 0xb7, 0xf1, 0x15, 0x5f, 0x23, 0x05, 0xae, 0x5c, 0xba, + 0x75, 0xcc, 0x8b, 0xf7, 0x2d, 0x8b, 0xf7, 0x2a, 0xf7, 0x11, 0x8b, 0xf7, + 0x13, 0x8b, 0xb4, 0x7b, 0xa0, 0x41, 0xc5, 0x42, 0xc4, 0x7f, 0x9c, 0x8b, + 0xb6, 0x8b, 0xcc, 0xbc, 0xc3, 0xc6, 0x8b, 0xb5, 0x8b, 0x9a, 0x79, 0x96, + 0x4b, 0x08, 0xcd, 0xba, 0x05, 0x85, 0xc2, 0x6d, 0xa6, 0x56, 0x8b, 0x24, + 0x8b, 0xfb, 0x09, 0xfb, 0x06, 0x8b, 0x28, 0x8b, 0x5e, 0xa0, 0x6a, 0xc5, + 0x5e, 0xcf, 0x55, 0x9d, 0x70, 0x8b, 0x5d, 0x8b, 0x3d, 0x40, 0x46, 0x34, + 0x8b, 0x60, 0x8b, 0x5f, 0x9e, 0x70, 0xa9, 0x08, 0x76, 0xa2, 0x83, 0xa0, + 0x83, 0xb7, 0x08, 0x7b, 0x80, 0x05, 0xf8, 0xc4, 0xf9, 0x59, 0x15, 0x8a, + 0x95, 0x05, 0x82, 0x84, 0x7f, 0x80, 0x83, 0x82, 0x4c, 0x52, 0x85, 0x85, + 0x53, 0x5f, 0x83, 0xb3, 0x8b, 0x90, 0x7f, 0xe4, 0x08, 0x68, 0x76, 0x05, + 0x8f, 0x57, 0x90, 0x52, 0x8f, 0x4b, 0x90, 0x89, 0x90, 0x8a, 0x8e, 0x8b, + 0x8d, 0x8b, 0x8e, 0x8c, 0x94, 0x8d, 0xb9, 0xb2, 0xa5, 0xa4, 0xf0, 0xf1, + 0x8a, 0x8f, 0x8a, 0x8e, 0x8b, 0x8d, 0x08, 0x8a, 0x94, 0x05, 0x0e, 0xf8, + 0x3f, 0xf9, 0x02, 0xf8, 0xa9, 0x15, 0x93, 0x8c, 0x92, 0x8b, 0x8e, 0x8b, + 0x98, 0x8b, 0x8b, 0x8b, 0xac, 0x89, 0x88, 0x80, 0x88, 0x7f, 0x89, 0x80, + 0x88, 0x7e, 0x83, 0x69, 0x7d, 0x55, 0x08, 0x4f, 0xfb, 0x86, 0x05, 0x89, + 0x84, 0x85, 0x73, 0x82, 0x6a, 0x38, 0x5f, 0x61, 0x7d, 0x57, 0x8b, 0x53, + 0x8b, 0x66, 0xb8, 0x8b, 0xd1, 0x8b, 0xf7, 0x04, 0xd2, 0xf7, 0x40, 0xf1, + 0xf7, 0x1e, 0x08, 0x85, 0x93, 0x05, 0x7e, 0x87, 0x8a, 0x8a, 0x7a, 0x83, + 0x08, 0x81, 0x87, 0x05, 0x4b, 0x95, 0x86, 0x8c, 0x74, 0x8b, 0x5b, 0x8b, + 0x64, 0x7f, 0x6a, 0x71, 0x4b, 0x59, 0x63, 0x49, 0x8b, 0x54, 0x8b, 0x70, + 0x93, 0x71, 0xa0, 0x5f, 0x08, 0xce, 0xc1, 0x05, 0x72, 0xbb, 0x82, 0xa4, + 0x8b, 0xa5, 0x8b, 0xc2, 0xbd, 0xb4, 0xcd, 0x8b, 0xa8, 0x8b, 0xa0, 0x87, + 0xb6, 0x7c, 0xfb, 0x07, 0xfb, 0x49, 0x5b, 0xfb, 0x07, 0x8b, 0x30, 0x8b, + 0x42, 0xb7, 0x5a, 0xcd, 0x8b, 0xc2, 0x8b, 0xca, 0x9e, 0xf7, 0x0e, 0xbf, + 0x08, 0x85, 0x6d, 0x89, 0x80, 0x8b, 0x83, 0x08, 0x7c, 0x94, 0x83, 0x9e, + 0x1e, 0xa7, 0x8b, 0xc2, 0x93, 0xd0, 0x9b, 0x08, 0xa0, 0xa4, 0x05, 0x6c, + 0x88, 0x78, 0x8a, 0x75, 0x8b, 0x70, 0x8b, 0x81, 0x95, 0x8b, 0xa3, 0x8b, + 0xb8, 0xbe, 0xf7, 0x6b, 0xd0, 0xf7, 0x8d, 0x57, 0x83, 0x84, 0x8a, 0x45, + 0x84, 0x08, 0x70, 0x72, 0x05, 0xb8, 0xf7, 0x09, 0x15, 0xa1, 0xa0, 0x8e, + 0x8e, 0x93, 0x91, 0x08, 0xab, 0xa4, 0x05, 0x7f, 0x9e, 0x87, 0x92, 0x87, + 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x81, 0xa4, 0x86, 0x87, 0x84, 0x86, 0x89, + 0x89, 0x7a, 0x7d, 0x81, 0x83, 0x87, 0x88, 0x84, 0x86, 0x86, 0x88, 0x7f, + 0x82, 0x93, 0x74, 0x93, 0x7b, 0xa1, 0x6c, 0x08, 0xfb, 0x19, 0x16, 0xac, + 0xa9, 0x05, 0x91, 0x90, 0x8f, 0x8d, 0xa1, 0x9d, 0x80, 0x9e, 0x87, 0x92, + 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x80, 0xa4, 0x86, 0x87, 0x87, 0x87, + 0x86, 0x88, 0x71, 0x75, 0x88, 0x89, 0x71, 0x79, 0x93, 0x74, 0x93, 0x7d, + 0xa1, 0x6a, 0x08, 0x0e, 0xf8, 0x3f, 0xf9, 0x02, 0xf8, 0xa9, 0x15, 0x93, + 0x8c, 0x92, 0x8b, 0x8e, 0x8b, 0x98, 0x8b, 0x8b, 0x8b, 0xac, 0x89, 0x88, + 0x80, 0x88, 0x7f, 0x89, 0x80, 0x88, 0x7e, 0x83, 0x69, 0x7d, 0x55, 0x08, + 0x4f, 0xfb, 0x86, 0x05, 0x89, 0x84, 0x85, 0x73, 0x82, 0x6a, 0x38, 0x5f, + 0x61, 0x7d, 0x57, 0x8b, 0x53, 0x8b, 0x66, 0xb8, 0x8b, 0xd1, 0x8b, 0xf7, + 0x04, 0xd2, 0xf7, 0x40, 0xf1, 0xf7, 0x1e, 0x08, 0x85, 0x93, 0x05, 0x7e, + 0x87, 0x8a, 0x8a, 0x7a, 0x83, 0x08, 0x81, 0x87, 0x05, 0x4b, 0x95, 0x86, + 0x8c, 0x74, 0x8b, 0x5b, 0x8b, 0x64, 0x7f, 0x6a, 0x71, 0x4b, 0x59, 0x63, + 0x49, 0x8b, 0x54, 0x8b, 0x70, 0x93, 0x71, 0xa0, 0x5f, 0x08, 0xce, 0xc1, + 0x05, 0x72, 0xbb, 0x82, 0xa4, 0x8b, 0xa5, 0x8b, 0xc2, 0xbd, 0xb4, 0xcd, + 0x8b, 0xa8, 0x8b, 0xa0, 0x87, 0xb6, 0x7c, 0xfb, 0x07, 0xfb, 0x49, 0x5b, + 0xfb, 0x07, 0x8b, 0x30, 0x8b, 0x42, 0xb7, 0x5a, 0xcd, 0x8b, 0xc2, 0x8b, + 0xca, 0x9e, 0xf7, 0x0e, 0xbf, 0x08, 0x85, 0x6d, 0x89, 0x80, 0x8b, 0x83, + 0x08, 0x7c, 0x94, 0x83, 0x9e, 0x1e, 0xa7, 0x8b, 0xc2, 0x93, 0xd0, 0x9b, + 0x08, 0xa0, 0xa4, 0x05, 0x6c, 0x88, 0x78, 0x8a, 0x75, 0x8b, 0x70, 0x8b, + 0x81, 0x95, 0x8b, 0xa3, 0x8b, 0xb8, 0xbe, 0xf7, 0x6b, 0xd0, 0xf7, 0x8d, + 0x57, 0x83, 0x84, 0x8a, 0x45, 0x84, 0x08, 0x70, 0x72, 0x05, 0x52, 0xe7, + 0x15, 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, 0xda, 0x08, 0x5f, 0xa0, 0xfb, 0x1f, + 0xfb, 0x50, 0xa3, 0x84, 0x05, 0x0e, 0xf8, 0x3f, 0xf9, 0x02, 0xf8, 0xa9, + 0x15, 0x93, 0x8c, 0x92, 0x8b, 0x8e, 0x8b, 0x98, 0x8b, 0x8b, 0x8b, 0xac, + 0x89, 0x88, 0x80, 0x88, 0x7f, 0x89, 0x80, 0x88, 0x7e, 0x83, 0x69, 0x7d, + 0x55, 0x08, 0x4f, 0xfb, 0x86, 0x05, 0x89, 0x84, 0x85, 0x73, 0x82, 0x6a, + 0x38, 0x5f, 0x61, 0x7d, 0x57, 0x8b, 0x53, 0x8b, 0x66, 0xb8, 0x8b, 0xd1, + 0x8b, 0xf7, 0x04, 0xd2, 0xf7, 0x40, 0xf1, 0xf7, 0x1e, 0x08, 0x85, 0x93, + 0x05, 0x7e, 0x87, 0x8a, 0x8a, 0x7a, 0x83, 0x08, 0x81, 0x87, 0x05, 0x4b, + 0x95, 0x86, 0x8c, 0x74, 0x8b, 0x5b, 0x8b, 0x64, 0x7f, 0x6a, 0x71, 0x4b, + 0x59, 0x63, 0x49, 0x8b, 0x54, 0x8b, 0x70, 0x93, 0x71, 0xa0, 0x5f, 0x08, + 0xce, 0xc1, 0x05, 0x72, 0xbb, 0x82, 0xa4, 0x8b, 0xa5, 0x8b, 0xc2, 0xbd, + 0xb4, 0xcd, 0x8b, 0xa8, 0x8b, 0xa0, 0x87, 0xb6, 0x7c, 0xfb, 0x07, 0xfb, + 0x49, 0x5b, 0xfb, 0x07, 0x8b, 0x30, 0x8b, 0x42, 0xb7, 0x5a, 0xcd, 0x8b, + 0xc2, 0x8b, 0xca, 0x9e, 0xf7, 0x0e, 0xbf, 0x08, 0x85, 0x6d, 0x89, 0x80, + 0x8b, 0x83, 0x08, 0x7c, 0x94, 0x83, 0x9e, 0x1e, 0xa7, 0x8b, 0xc2, 0x93, + 0xd0, 0x9b, 0x08, 0xa0, 0xa4, 0x05, 0x6c, 0x88, 0x78, 0x8a, 0x75, 0x8b, + 0x70, 0x8b, 0x81, 0x95, 0x8b, 0xa3, 0x8b, 0xb8, 0xbe, 0xf7, 0x6b, 0xd0, + 0xf7, 0x8d, 0x57, 0x83, 0x84, 0x8a, 0x45, 0x84, 0x08, 0x70, 0x72, 0x05, + 0x49, 0xf7, 0xab, 0x15, 0x82, 0x86, 0x85, 0x88, 0x89, 0x8a, 0x08, 0x7e, + 0x84, 0x05, 0xa0, 0x65, 0x99, 0x6f, 0xbb, 0x22, 0x95, 0x8d, 0x8e, 0x8c, + 0x97, 0x8e, 0x77, 0xd2, 0x7e, 0xb1, 0x6e, 0xdb, 0x08, 0x7b, 0x83, 0x05, + 0x0e, 0xf8, 0x3f, 0xf9, 0x02, 0xf8, 0xa9, 0x15, 0x93, 0x8c, 0x92, 0x8b, + 0x8e, 0x8b, 0x98, 0x8b, 0x8b, 0x8b, 0xac, 0x89, 0x88, 0x80, 0x88, 0x7f, + 0x89, 0x80, 0x88, 0x7e, 0x83, 0x69, 0x7d, 0x55, 0x08, 0x4f, 0xfb, 0x86, + 0x05, 0x89, 0x84, 0x85, 0x73, 0x82, 0x6a, 0x38, 0x5f, 0x61, 0x7d, 0x57, + 0x8b, 0x53, 0x8b, 0x66, 0xb8, 0x8b, 0xd1, 0x8b, 0xf7, 0x04, 0xd2, 0xf7, + 0x40, 0xf1, 0xf7, 0x1e, 0x08, 0x85, 0x93, 0x05, 0x7e, 0x87, 0x8a, 0x8a, + 0x7a, 0x83, 0x08, 0x81, 0x87, 0x05, 0x4b, 0x95, 0x86, 0x8c, 0x74, 0x8b, + 0x5b, 0x8b, 0x64, 0x7f, 0x6a, 0x71, 0x4b, 0x59, 0x63, 0x49, 0x8b, 0x54, + 0x8b, 0x70, 0x93, 0x71, 0xa0, 0x5f, 0x08, 0xce, 0xc1, 0x05, 0x72, 0xbb, + 0x82, 0xa4, 0x8b, 0xa5, 0x8b, 0xc2, 0xbd, 0xb4, 0xcd, 0x8b, 0xa8, 0x8b, + 0xa0, 0x87, 0xb6, 0x7c, 0xfb, 0x07, 0xfb, 0x49, 0x5b, 0xfb, 0x07, 0x8b, + 0x30, 0x8b, 0x42, 0xb7, 0x5a, 0xcd, 0x8b, 0xc2, 0x8b, 0xca, 0x9e, 0xf7, + 0x0e, 0xbf, 0x08, 0x85, 0x6d, 0x89, 0x80, 0x8b, 0x83, 0x08, 0x7c, 0x94, + 0x83, 0x9e, 0x1e, 0xa7, 0x8b, 0xc2, 0x93, 0xd0, 0x9b, 0x08, 0xa0, 0xa4, + 0x05, 0x6c, 0x88, 0x78, 0x8a, 0x75, 0x8b, 0x70, 0x8b, 0x81, 0x95, 0x8b, + 0xa3, 0x8b, 0xb8, 0xbe, 0xf7, 0x6b, 0xd0, 0xf7, 0x8d, 0x57, 0x83, 0x84, + 0x8a, 0x45, 0x84, 0x08, 0x70, 0x72, 0x05, 0xfb, 0x23, 0xf0, 0x15, 0x8c, + 0x82, 0xdc, 0xd5, 0x05, 0xa4, 0xa1, 0x9a, 0x97, 0xac, 0xa5, 0x08, 0x96, + 0x4b, 0x91, 0x5c, 0x05, 0x8c, 0x85, 0x8c, 0x85, 0x8c, 0x80, 0x9e, 0x96, + 0x8f, 0x8e, 0x98, 0x91, 0x89, 0xa5, 0x88, 0xae, 0x88, 0xa7, 0x8a, 0x96, + 0x8a, 0xa0, 0x87, 0xc0, 0x86, 0x8c, 0x86, 0x8c, 0x88, 0x8b, 0x89, 0x8b, + 0x87, 0x8a, 0x83, 0x8a, 0x08, 0x5f, 0x65, 0x76, 0x78, 0xfb, 0x00, 0xfb, + 0x01, 0x8c, 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8c, 0x81, 0x05, 0x0e, + 0xf7, 0x8b, 0xaa, 0xfb, 0x2a, 0x15, 0x9f, 0x89, 0x94, 0x8b, 0x9c, 0x8b, + 0xe6, 0x8b, 0xb8, 0x94, 0xb5, 0xa7, 0xbc, 0xab, 0xc1, 0xdf, 0xef, 0xf7, + 0x5d, 0xf3, 0xf7, 0x65, 0x97, 0xa2, 0xa6, 0xb2, 0xa9, 0xb5, 0xa2, 0x9b, + 0xaa, 0x8b, 0x9b, 0x8b, 0x96, 0x88, 0xa2, 0x82, 0x08, 0xa7, 0xd4, 0x05, + 0x7c, 0x98, 0x83, 0x8e, 0x7a, 0x8b, 0x3b, 0x8b, 0x4e, 0x3b, 0xfb, 0x18, + 0xfb, 0xa7, 0x94, 0xc0, 0x8d, 0xa3, 0x8b, 0xac, 0x08, 0xf7, 0x17, 0x56, + 0xdd, 0x36, 0xfb, 0x0c, 0xfb, 0x1b, 0xfb, 0x12, 0xfb, 0x06, 0x1e, 0x8b, + 0x6d, 0x92, 0x6d, 0x99, 0x6c, 0x08, 0xd7, 0xbb, 0x05, 0x7c, 0xba, 0x86, + 0xa3, 0x8b, 0xa9, 0x08, 0xd1, 0xbb, 0xc2, 0xc8, 0xe4, 0xc2, 0x26, 0xfb, + 0x37, 0x1e, 0x8b, 0x58, 0x85, 0x64, 0x7e, 0x66, 0x78, 0x58, 0x74, 0x5d, + 0x70, 0x65, 0x66, 0x57, 0x5b, 0x76, 0x35, 0x8b, 0x7c, 0x8b, 0x7c, 0x8c, + 0x60, 0x8e, 0x08, 0x68, 0x41, 0x05, 0xf8, 0x7f, 0xf9, 0x9b, 0x15, 0xc9, + 0xd4, 0x9f, 0xa1, 0xd8, 0xda, 0x08, 0x5e, 0xa0, 0x05, 0x51, 0x3a, 0x5d, + 0x4c, 0x69, 0x5f, 0x08, 0xa3, 0x84, 0x05, 0x0e, 0xf7, 0xc7, 0xf8, 0xd9, + 0xf7, 0x77, 0x15, 0x8f, 0x84, 0x90, 0x83, 0x8f, 0x85, 0x9b, 0x6f, 0x8f, + 0x7f, 0x8b, 0x74, 0x8b, 0x56, 0x6c, 0x71, 0x49, 0x8b, 0x65, 0x8b, 0x63, + 0x8d, 0x4a, 0x91, 0x37, 0x93, 0x77, 0x8c, 0x6d, 0x8b, 0x08, 0x7a, 0x8b, + 0x78, 0x8b, 0x6b, 0x86, 0xdc, 0xdf, 0xf7, 0x24, 0xf7, 0x27, 0xf7, 0x96, + 0xf7, 0x99, 0x8b, 0xa8, 0x05, 0x68, 0x6d, 0x6f, 0x80, 0x66, 0x8b, 0x7d, + 0x8b, 0x6f, 0x8d, 0x65, 0x8f, 0x2a, 0x94, 0x8b, 0x8b, 0x71, 0x8e, 0x08, + 0x59, 0x90, 0x8b, 0x8b, 0x83, 0x8b, 0x75, 0x8b, 0x85, 0x86, 0x7b, 0x6a, + 0x08, 0x49, 0xfb, 0x24, 0x9c, 0x72, 0x05, 0xd1, 0xf7, 0x0f, 0x90, 0x92, + 0xaa, 0x8b, 0x92, 0x8b, 0x95, 0x8a, 0x95, 0x8a, 0x08, 0xb3, 0x86, 0xa6, + 0x89, 0xae, 0x8b, 0xba, 0x8b, 0x9f, 0x8d, 0xbc, 0x93, 0x08, 0xfb, 0xe7, + 0xfb, 0xe7, 0x05, 0x3e, 0x40, 0x59, 0x5a, 0x73, 0x76, 0x08, 0x66, 0x07, + 0xac, 0xa3, 0xa2, 0x93, 0xb0, 0x8b, 0xa5, 0x8b, 0xae, 0x89, 0xb1, 0x87, + 0x08, 0xf7, 0x0e, 0x7e, 0xec, 0x83, 0xa3, 0x8b, 0xa7, 0x8b, 0xa3, 0x94, + 0x9e, 0x9d, 0x97, 0x97, 0x94, 0x95, 0xa7, 0xaf, 0x08, 0xa2, 0xa8, 0x05, + 0xa9, 0xaf, 0x91, 0x9a, 0x8b, 0xad, 0x8b, 0xa7, 0x86, 0xa2, 0x7c, 0xae, + 0x08, 0x40, 0x5e, 0x05, 0xc6, 0xf8, 0xca, 0x15, 0x89, 0x93, 0x8b, 0x8c, + 0x8a, 0x94, 0x08, 0x8a, 0x95, 0x05, 0x7d, 0x7e, 0x81, 0x82, 0x86, 0x87, + 0x08, 0x57, 0x5b, 0x05, 0x85, 0x87, 0x86, 0x86, 0x85, 0x85, 0x08, 0x53, + 0x5e, 0x05, 0x89, 0x96, 0x8a, 0x95, 0x8a, 0x8e, 0x08, 0x84, 0xb3, 0x05, + 0x8b, 0x8d, 0x88, 0x9d, 0x88, 0xa6, 0x8b, 0x8e, 0x89, 0x95, 0x8a, 0x95, + 0x85, 0x87, 0x86, 0x88, 0x89, 0x8a, 0x08, 0x7f, 0x84, 0x05, 0x85, 0x88, + 0x88, 0x89, 0x8a, 0x8a, 0x8d, 0x72, 0x90, 0x52, 0x91, 0x30, 0x90, 0x89, + 0x8f, 0x8a, 0x8e, 0x8b, 0x8c, 0x8b, 0x8d, 0x8b, 0x8e, 0x8c, 0x8c, 0x8b, + 0x8f, 0x8c, 0x8f, 0x8c, 0xaa, 0xa4, 0x97, 0x97, 0xaf, 0xae, 0x08, 0xe9, + 0xe9, 0x05, 0x0e, 0xf7, 0x77, 0xf7, 0xe9, 0xf8, 0xaa, 0x15, 0x7b, 0x47, + 0x05, 0xfb, 0x3c, 0x77, 0xfb, 0x01, 0x2b, 0x8b, 0xfb, 0x14, 0x8b, 0x70, + 0x8e, 0x7a, 0x98, 0x66, 0x08, 0xd5, 0xb8, 0x05, 0x81, 0xb0, 0x88, 0x9c, + 0x8b, 0xa1, 0x8b, 0xc0, 0xa2, 0xbd, 0xaf, 0xa7, 0xad, 0xa5, 0xad, 0x96, + 0xcc, 0x92, 0x75, 0x28, 0x66, 0xfb, 0x29, 0x63, 0xfb, 0x27, 0x08, 0xfb, + 0x1f, 0x8b, 0x61, 0x62, 0xd1, 0x8b, 0x05, 0xf7, 0x93, 0x8b, 0x97, 0x8c, + 0xe0, 0xb3, 0x08, 0x8e, 0x94, 0x05, 0x54, 0x84, 0x74, 0x8a, 0x31, 0x8a, + 0x93, 0xa8, 0x8f, 0x9a, 0x96, 0xbb, 0xd0, 0x90, 0xc1, 0x9b, 0xc8, 0xac, + 0xd4, 0xb2, 0xb8, 0xd1, 0x8b, 0xd5, 0x8b, 0xcd, 0x51, 0xad, 0xfb, 0x06, + 0x8b, 0x8a, 0x8b, 0x7b, 0x8b, 0x6e, 0x8a, 0x08, 0x9c, 0xcc, 0x05, 0xe6, + 0x8e, 0xa1, 0x90, 0xcf, 0xab, 0x08, 0x8e, 0x95, 0x05, 0x54, 0x84, 0x58, + 0x88, 0x4d, 0x8b, 0x08, 0xfb, 0x73, 0x8b, 0x61, 0x62, 0xf1, 0x8b, 0x05, + 0xd1, 0x06, 0xc0, 0x2f, 0x15, 0x9a, 0x8c, 0x92, 0x8b, 0x9c, 0x8b, 0x08, + 0xcb, 0xae, 0x6b, 0x52, 0x21, 0x43, 0x3c, 0x29, 0x1f, 0x7f, 0x8b, 0x84, + 0x8c, 0x7b, 0x8f, 0x08, 0xce, 0xf7, 0xa0, 0x05, 0x0e, 0xf7, 0x8b, 0xaa, + 0xfb, 0x2a, 0x15, 0x9f, 0x89, 0x94, 0x8b, 0x9c, 0x8b, 0xf7, 0x3a, 0x8b, + 0xba, 0xab, 0xe8, 0xf7, 0x46, 0x08, 0xf0, 0xf7, 0x58, 0x05, 0xcc, 0xf7, + 0x17, 0x8e, 0x92, 0xad, 0xc4, 0xac, 0xc4, 0xaa, 0xa4, 0xae, 0x8b, 0x9b, + 0x8b, 0x96, 0x88, 0xa2, 0x82, 0x08, 0xa7, 0xd4, 0x05, 0x7c, 0x98, 0x83, + 0x8e, 0x7a, 0x8b, 0x3b, 0x8b, 0x4d, 0x3b, 0xfb, 0x17, 0xfb, 0xa7, 0x94, + 0xbf, 0x8d, 0xa3, 0x8b, 0xad, 0x08, 0xf7, 0x17, 0x56, 0xdd, 0x36, 0xfb, + 0x0d, 0xfb, 0x1a, 0xfb, 0x12, 0xfb, 0x06, 0x1e, 0x8b, 0x6d, 0x92, 0x6c, + 0x99, 0x6d, 0x08, 0xd7, 0xbb, 0x05, 0x7c, 0xbb, 0x86, 0xa2, 0x8b, 0xa9, + 0x08, 0xd1, 0xbb, 0xc2, 0xc8, 0xe4, 0xc2, 0x26, 0xfb, 0x37, 0x1e, 0x8b, + 0x58, 0x85, 0x64, 0x7e, 0x66, 0x78, 0x58, 0x74, 0x5d, 0x70, 0x65, 0x66, + 0x56, 0x5b, 0x77, 0x35, 0x8b, 0x7c, 0x8b, 0x7c, 0x8c, 0x60, 0x8e, 0x08, + 0x68, 0x41, 0x05, 0xf8, 0xc0, 0xf9, 0xb4, 0x15, 0xa2, 0xa0, 0x8e, 0x8e, + 0x92, 0x91, 0x91, 0x90, 0x8e, 0x8d, 0xa2, 0x9d, 0x7a, 0xa6, 0x89, 0x8f, + 0x81, 0xa3, 0x89, 0x90, 0x89, 0x8f, 0x8a, 0x8f, 0x87, 0x88, 0x87, 0x88, + 0x85, 0x86, 0x70, 0x74, 0x8a, 0x8b, 0x70, 0x78, 0x08, 0x93, 0x74, 0x93, + 0x7b, 0xa1, 0x6c, 0x08, 0xfb, 0x08, 0xf7, 0x04, 0x15, 0x72, 0x76, 0x88, + 0x88, 0x70, 0x79, 0x93, 0x74, 0x93, 0x7d, 0xa1, 0x6a, 0x08, 0xac, 0xa9, + 0x05, 0x92, 0x90, 0x8f, 0x8e, 0xa0, 0x9c, 0x7b, 0xa6, 0x89, 0x8f, 0x81, + 0xa3, 0x89, 0x90, 0x89, 0x8f, 0x89, 0x8f, 0x08, 0x7d, 0x80, 0x05, 0x0e, + 0xf6, 0xf8, 0x80, 0xf7, 0x16, 0x15, 0x40, 0x59, 0x7c, 0x82, 0x81, 0x8b, + 0x84, 0x8b, 0x86, 0x93, 0x8b, 0x97, 0x8b, 0xa5, 0xa3, 0xf7, 0x02, 0xaf, + 0xf7, 0x19, 0x96, 0x9a, 0x8d, 0x8e, 0x9b, 0x9d, 0x5b, 0x96, 0x68, 0x8f, + 0x60, 0x8b, 0x62, 0x8b, 0x78, 0x87, 0x71, 0x7b, 0x08, 0x67, 0x76, 0x61, + 0x6c, 0x7e, 0x7d, 0x66, 0x61, 0x61, 0xfb, 0x1b, 0x8b, 0x3a, 0x8b, 0x5b, + 0x9b, 0x6b, 0xa4, 0x8b, 0xa1, 0x8b, 0xac, 0x9f, 0xf7, 0x11, 0xe5, 0x81, + 0x5d, 0x86, 0x6c, 0x8b, 0x7f, 0x8b, 0x7e, 0x91, 0x83, 0x95, 0x8b, 0x08, + 0x97, 0x8b, 0x8b, 0x8b, 0xdb, 0xbe, 0xa8, 0x9e, 0xa2, 0x9b, 0xb1, 0xa7, + 0x08, 0x8c, 0xa8, 0x05, 0xfb, 0x57, 0x85, 0x15, 0x50, 0x60, 0x6d, 0x7a, + 0x79, 0x8b, 0x7b, 0x8b, 0x81, 0x9d, 0x8b, 0xab, 0x8b, 0xbd, 0x9b, 0xcf, + 0xa4, 0xc4, 0xa3, 0xc2, 0xa1, 0xa0, 0xad, 0x8b, 0x9d, 0x8b, 0xaa, 0x86, + 0xaf, 0x83, 0x77, 0x3f, 0x84, 0x74, 0x8a, 0x86, 0x08, 0x85, 0x72, 0x86, + 0x72, 0x85, 0x71, 0x8a, 0x86, 0x88, 0x7f, 0x86, 0x79, 0x08, 0x78, 0x7e, + 0x05, 0xf7, 0x13, 0xf8, 0x01, 0x15, 0xa1, 0xa0, 0x8e, 0x8e, 0x93, 0x91, + 0x08, 0xab, 0xa4, 0x05, 0x7f, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, + 0x8a, 0x8e, 0x81, 0xa4, 0x87, 0x88, 0x87, 0x88, 0x85, 0x86, 0x7a, 0x7d, + 0x81, 0x83, 0x87, 0x88, 0x84, 0x86, 0x86, 0x88, 0x7f, 0x82, 0x93, 0x74, + 0x93, 0x7b, 0xa1, 0x6c, 0x08, 0xfb, 0x19, 0x16, 0xac, 0xa9, 0x05, 0x91, + 0x8f, 0x8f, 0x8e, 0xa1, 0x9d, 0x80, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, + 0x91, 0x8a, 0x8e, 0x80, 0xa4, 0x87, 0x87, 0x86, 0x88, 0x86, 0x87, 0x70, + 0x74, 0x8a, 0x8a, 0x70, 0x79, 0x93, 0x74, 0x92, 0x7e, 0xa2, 0x69, 0x08, + 0x0e, 0xf6, 0xf8, 0x80, 0xf7, 0x16, 0x15, 0x40, 0x59, 0x7c, 0x82, 0x81, + 0x8b, 0x84, 0x8b, 0x86, 0x93, 0x8b, 0x97, 0x8b, 0xa5, 0xa3, 0xf7, 0x02, + 0xaf, 0xf7, 0x19, 0x96, 0x9a, 0x8d, 0x8e, 0x9b, 0x9d, 0x5b, 0x96, 0x68, + 0x8f, 0x60, 0x8b, 0x62, 0x8b, 0x78, 0x87, 0x71, 0x7b, 0x08, 0x67, 0x76, + 0x61, 0x6c, 0x7e, 0x7d, 0x65, 0x61, 0x62, 0xfb, 0x1b, 0x8b, 0x3a, 0x8b, + 0x5b, 0x9b, 0x6b, 0xa4, 0x8b, 0xa1, 0x8b, 0xac, 0x9f, 0xf7, 0x11, 0xe5, + 0x81, 0x5d, 0x86, 0x6c, 0x8b, 0x7f, 0x8b, 0x7e, 0x91, 0x83, 0x95, 0x8b, + 0x08, 0x97, 0x8b, 0x8b, 0x8b, 0xdb, 0xbe, 0xa8, 0x9e, 0xa2, 0x9b, 0xb1, + 0xa7, 0x08, 0x8c, 0xa8, 0x05, 0xfb, 0x44, 0x92, 0x15, 0x85, 0x86, 0x84, + 0x86, 0x85, 0x88, 0x50, 0x60, 0x6d, 0x7a, 0x79, 0x8b, 0x7b, 0x8b, 0x81, + 0x9d, 0x8b, 0xab, 0x8b, 0xbd, 0x9b, 0xcf, 0xa4, 0xc4, 0xa3, 0xc2, 0xa1, + 0xa0, 0xad, 0x8b, 0x9d, 0x8b, 0xaa, 0x86, 0xaf, 0x83, 0x08, 0x77, 0x3f, + 0x84, 0x74, 0x8a, 0x86, 0x85, 0x72, 0x86, 0x72, 0x85, 0x71, 0x8a, 0x86, + 0x88, 0x7f, 0x86, 0x79, 0x08, 0x91, 0xf7, 0xd7, 0x15, 0xc9, 0xd4, 0x9f, + 0xa1, 0xd8, 0xd9, 0x08, 0x5f, 0xa1, 0xfb, 0x1f, 0xfb, 0x51, 0xa3, 0x85, + 0x05, 0x0e, 0xf6, 0xf8, 0x80, 0xf7, 0x16, 0x15, 0x40, 0x59, 0x7c, 0x82, + 0x81, 0x8b, 0x84, 0x8b, 0x86, 0x93, 0x8b, 0x97, 0x8b, 0xa5, 0xa3, 0xf7, + 0x02, 0xaf, 0xf7, 0x19, 0x96, 0x9a, 0x8d, 0x8e, 0x9b, 0x9d, 0x5b, 0x96, + 0x68, 0x8f, 0x60, 0x8b, 0x62, 0x8b, 0x78, 0x87, 0x71, 0x7b, 0x08, 0x67, + 0x76, 0x61, 0x6c, 0x7e, 0x7d, 0x65, 0x61, 0x62, 0xfb, 0x1b, 0x8b, 0x3a, + 0x8b, 0x5b, 0x9b, 0x6b, 0xa4, 0x8b, 0xa1, 0x8b, 0xac, 0x9f, 0xf7, 0x11, + 0xe5, 0x81, 0x5d, 0x86, 0x6c, 0x8b, 0x7f, 0x8b, 0x7e, 0x91, 0x83, 0x95, + 0x8b, 0x08, 0x97, 0x8b, 0x8b, 0x8b, 0xdb, 0xbe, 0xa8, 0x9e, 0xa2, 0x9b, + 0xb1, 0xa7, 0x08, 0x8c, 0xa8, 0x05, 0xfb, 0x44, 0x92, 0x15, 0x85, 0x86, + 0x84, 0x86, 0x85, 0x88, 0x50, 0x60, 0x6d, 0x7a, 0x79, 0x8b, 0x7b, 0x8b, + 0x81, 0x9d, 0x8b, 0xab, 0x8b, 0xbd, 0x9b, 0xcf, 0xa4, 0xc4, 0xa3, 0xc2, + 0xa1, 0xa0, 0xad, 0x8b, 0x9d, 0x8b, 0xaa, 0x86, 0xaf, 0x83, 0x08, 0x77, + 0x3f, 0x84, 0x74, 0x8a, 0x86, 0x85, 0x72, 0x86, 0x72, 0x85, 0x71, 0x8a, + 0x86, 0x88, 0x7f, 0x86, 0x79, 0x08, 0x92, 0xf8, 0x91, 0x15, 0x83, 0x87, + 0x85, 0x88, 0x88, 0x89, 0x08, 0x7e, 0x84, 0x05, 0x9f, 0x68, 0x9b, 0x69, + 0xba, 0x26, 0x95, 0x8d, 0x8e, 0x8b, 0x97, 0x8f, 0x74, 0xd9, 0x84, 0xa2, + 0x6b, 0xe3, 0x08, 0x7b, 0x82, 0x05, 0x0e, 0xf6, 0xf8, 0x80, 0xf7, 0x16, + 0x15, 0x40, 0x59, 0x7c, 0x82, 0x81, 0x8b, 0x84, 0x8b, 0x86, 0x93, 0x8b, + 0x97, 0x8b, 0xa5, 0xa3, 0xf7, 0x02, 0xaf, 0xf7, 0x19, 0x96, 0x9a, 0x8d, + 0x8e, 0x9b, 0x9d, 0x5b, 0x96, 0x68, 0x8f, 0x60, 0x8b, 0x62, 0x8b, 0x78, + 0x87, 0x71, 0x7b, 0x08, 0x67, 0x76, 0x61, 0x6c, 0x7e, 0x7d, 0x65, 0x61, + 0x62, 0xfb, 0x1b, 0x8b, 0x3a, 0x8b, 0x5b, 0x9b, 0x6b, 0xa4, 0x8b, 0xa1, + 0x8b, 0xac, 0x9f, 0xf7, 0x11, 0xe5, 0x81, 0x5d, 0x86, 0x6c, 0x8b, 0x7f, + 0x8b, 0x7e, 0x91, 0x83, 0x95, 0x8b, 0x08, 0x97, 0x8b, 0x8b, 0x8b, 0xdb, + 0xbe, 0xa8, 0x9e, 0xa2, 0x9b, 0xb1, 0xa7, 0x08, 0x8c, 0xa8, 0x05, 0xfb, + 0x44, 0x92, 0x15, 0x85, 0x86, 0x84, 0x86, 0x85, 0x88, 0x50, 0x60, 0x6d, + 0x7a, 0x79, 0x8b, 0x7b, 0x8b, 0x81, 0x9d, 0x8b, 0xab, 0x8b, 0xbd, 0x9b, + 0xcf, 0xa4, 0xc4, 0xa3, 0xc2, 0xa1, 0xa0, 0xad, 0x8b, 0x9d, 0x8b, 0xaa, + 0x86, 0xaf, 0x83, 0x08, 0x77, 0x3f, 0x84, 0x74, 0x8a, 0x86, 0x85, 0x72, + 0x86, 0x72, 0x85, 0x71, 0x8a, 0x86, 0x88, 0x7f, 0x86, 0x79, 0x08, 0x45, + 0xf7, 0xe0, 0x15, 0x8c, 0x82, 0x05, 0xa7, 0xa4, 0xa6, 0xa3, 0xa5, 0xa4, + 0x08, 0xd4, 0xc7, 0x05, 0x93, 0x60, 0x8c, 0x82, 0x8d, 0x7f, 0x08, 0x91, + 0x5c, 0x8e, 0x74, 0x05, 0x9e, 0x96, 0x8f, 0x8e, 0x98, 0x91, 0x85, 0xd0, + 0x86, 0xc4, 0x88, 0xbb, 0x86, 0x8c, 0x86, 0x8c, 0x88, 0x8b, 0x89, 0x8b, + 0x87, 0x8a, 0x83, 0x8a, 0x5e, 0x65, 0x79, 0x7a, 0xfb, 0x02, 0xfb, 0x03, + 0x8c, 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8c, 0x81, 0x05, 0x0e, 0xf6, + 0xf8, 0x80, 0xf7, 0x16, 0x15, 0x40, 0x59, 0x7c, 0x82, 0x81, 0x8b, 0x84, + 0x8b, 0x86, 0x93, 0x8b, 0x97, 0x8b, 0xa5, 0xa3, 0xf7, 0x02, 0xaf, 0xf7, + 0x19, 0x96, 0x9a, 0x8d, 0x8e, 0x9b, 0x9d, 0x5b, 0x96, 0x68, 0x8f, 0x60, + 0x8b, 0x62, 0x8b, 0x78, 0x87, 0x71, 0x7b, 0x08, 0x67, 0x76, 0x61, 0x6c, + 0x7e, 0x7d, 0x66, 0x61, 0x61, 0xfb, 0x1b, 0x8b, 0x3a, 0x8b, 0x5b, 0x9b, + 0x6b, 0xa4, 0x8b, 0xa1, 0x8b, 0xac, 0x9f, 0xf7, 0x11, 0xe5, 0x80, 0x59, + 0x87, 0x71, 0x8b, 0x7e, 0x8b, 0x7e, 0x91, 0x83, 0x95, 0x8b, 0x08, 0x97, + 0x8b, 0x8b, 0x8b, 0xdb, 0xbe, 0xa7, 0x9e, 0xa3, 0x9b, 0xb1, 0xa7, 0x08, + 0x8c, 0xa8, 0x05, 0xfb, 0x57, 0x85, 0x15, 0x50, 0x60, 0x6d, 0x7a, 0x79, + 0x8b, 0x7b, 0x8b, 0x81, 0x9d, 0x8b, 0xab, 0x8b, 0xbd, 0x9b, 0xcf, 0xa4, + 0xc4, 0xa3, 0xc2, 0xa1, 0xa0, 0xad, 0x8b, 0x9d, 0x8b, 0xaa, 0x86, 0xaf, + 0x83, 0x77, 0x3f, 0x84, 0x74, 0x8a, 0x86, 0x08, 0x85, 0x72, 0x86, 0x72, + 0x85, 0x71, 0x8a, 0x86, 0x88, 0x7f, 0x86, 0x79, 0x08, 0x78, 0x7e, 0x05, + 0x26, 0xf8, 0x06, 0x15, 0xb0, 0xba, 0x9a, 0x97, 0xa4, 0x8b, 0x99, 0x8b, + 0x9a, 0x86, 0xa0, 0x7f, 0xbd, 0x6f, 0x97, 0x86, 0xa2, 0x8b, 0xaa, 0x8b, + 0x9f, 0x9b, 0xc1, 0xce, 0x08, 0x81, 0x9d, 0x05, 0x71, 0x73, 0x89, 0x89, + 0x83, 0x85, 0x7d, 0x81, 0x73, 0x82, 0x7c, 0x8b, 0x7e, 0x8b, 0x74, 0x93, + 0x75, 0x97, 0x65, 0xa1, 0x81, 0x8e, 0x77, 0x8b, 0x6b, 0x8b, 0x73, 0x77, + 0x5a, 0x49, 0x08, 0x98, 0x79, 0x05, 0x0e, 0xf6, 0xf8, 0x80, 0xf7, 0x16, + 0x15, 0x40, 0x59, 0x7c, 0x82, 0x81, 0x8b, 0x84, 0x8b, 0x86, 0x93, 0x8b, + 0x97, 0x8b, 0xa5, 0xa3, 0xf7, 0x02, 0xaf, 0xf7, 0x19, 0x96, 0x9a, 0x8d, + 0x8e, 0x9b, 0x9d, 0x5b, 0x96, 0x68, 0x8f, 0x60, 0x8b, 0x62, 0x8b, 0x78, + 0x87, 0x71, 0x7b, 0x08, 0x67, 0x76, 0x61, 0x6c, 0x7e, 0x7d, 0x65, 0x61, + 0x62, 0xfb, 0x1b, 0x8b, 0x3a, 0x8b, 0x5b, 0x9b, 0x6b, 0xa4, 0x8b, 0xa1, + 0x8b, 0xac, 0x9f, 0xf7, 0x11, 0xe5, 0x81, 0x5d, 0x86, 0x6c, 0x8b, 0x7f, + 0x8b, 0x7e, 0x91, 0x83, 0x95, 0x8b, 0x08, 0x97, 0x8b, 0x8b, 0x8b, 0xdb, + 0xbe, 0xa8, 0x9e, 0xa2, 0x9b, 0xb1, 0xa7, 0x08, 0x8c, 0xa8, 0x05, 0xfb, + 0x44, 0x92, 0x15, 0x85, 0x86, 0x84, 0x86, 0x85, 0x88, 0x50, 0x60, 0x6d, + 0x7a, 0x79, 0x8b, 0x7b, 0x8b, 0x81, 0x9d, 0x8b, 0xab, 0x8b, 0xbd, 0x9b, + 0xcf, 0xa4, 0xc4, 0xa3, 0xc2, 0xa1, 0xa0, 0xad, 0x8b, 0x9d, 0x8b, 0xaa, + 0x86, 0xaf, 0x83, 0x08, 0x77, 0x3f, 0x84, 0x74, 0x8a, 0x86, 0x85, 0x72, + 0x86, 0x72, 0x85, 0x71, 0x8a, 0x86, 0x88, 0x7f, 0x86, 0x79, 0x08, 0xd9, + 0xf8, 0x8b, 0x15, 0x4a, 0x5b, 0x5a, 0x48, 0x63, 0xa3, 0x74, 0xb5, 0xc9, + 0xc0, 0xc1, 0xca, 0xb2, 0x71, 0xa2, 0x61, 0x1f, 0x7d, 0x75, 0x15, 0xa1, + 0x98, 0x78, 0x6b, 0x5d, 0x71, 0x65, 0x6c, 0x77, 0x7d, 0xa0, 0xaa, 0xbb, + 0xa3, 0xae, 0xab, 0x1f, 0x0e, 0xa6, 0xf7, 0x7a, 0x88, 0x15, 0x99, 0x95, + 0x95, 0x91, 0x8e, 0x8d, 0x9f, 0x96, 0x9f, 0x97, 0x9e, 0x97, 0x92, 0x8e, + 0x91, 0x8f, 0x90, 0x8f, 0x08, 0xbb, 0xad, 0x8c, 0xab, 0x05, 0x3f, 0x54, + 0x55, 0x6f, 0x6b, 0x8b, 0x67, 0x8b, 0x76, 0xa7, 0x8b, 0xbb, 0x8b, 0xbb, + 0x97, 0xcb, 0x9e, 0xba, 0xa0, 0xc0, 0xa4, 0xa6, 0xa8, 0x8b, 0xa3, 0x8b, + 0x98, 0x78, 0x91, 0x5f, 0x08, 0xc4, 0xad, 0x05, 0x8c, 0x90, 0x8b, 0x90, + 0x8b, 0x8c, 0x8b, 0xb6, 0x75, 0xa6, 0x68, 0x8b, 0x79, 0x8b, 0x80, 0x87, + 0x67, 0x73, 0x41, 0x5c, 0x7a, 0x7c, 0x75, 0x62, 0x6f, 0x55, 0x76, 0x36, + 0x8b, 0x4d, 0x8b, 0x4e, 0xa6, 0x6c, 0xbe, 0x8b, 0x08, 0x94, 0x8b, 0x91, + 0x8c, 0x96, 0x8e, 0x08, 0x46, 0x38, 0x05, 0xa0, 0x7b, 0x91, 0x83, 0x8b, + 0x7d, 0x8b, 0x73, 0x63, 0x6c, 0x5b, 0x7d, 0x08, 0x9a, 0x7e, 0x05, 0xe0, + 0xa2, 0xbd, 0xb3, 0x8b, 0xba, 0x8b, 0x9e, 0x82, 0x99, 0x7a, 0x90, 0x08, + 0xb8, 0xc8, 0x05, 0x0e, 0xa6, 0xf8, 0x10, 0xf7, 0x1d, 0x15, 0x33, 0x42, + 0x68, 0x77, 0x64, 0x8b, 0x67, 0x8b, 0x76, 0xa9, 0x8b, 0xc0, 0x8b, 0x8c, + 0x8b, 0x93, 0x8c, 0x92, 0xda, 0xc0, 0x9b, 0x96, 0xb0, 0xa8, 0xc0, 0xb3, + 0xa1, 0xad, 0x8b, 0xb6, 0x8b, 0xaf, 0x76, 0xa1, 0x69, 0x8b, 0x08, 0x75, + 0x8b, 0x7b, 0x86, 0x73, 0x7e, 0x69, 0x78, 0x64, 0x6c, 0x77, 0x74, 0x64, + 0x5b, 0x6a, 0x20, 0x8b, 0x3a, 0x8b, 0x4f, 0xaa, 0x66, 0xbe, 0x8b, 0xc6, + 0x8b, 0xce, 0xb1, 0xe0, 0xde, 0x08, 0xa8, 0x07, 0xfb, 0x6c, 0xb5, 0x15, + 0x9f, 0xf7, 0x06, 0xb5, 0xd7, 0xb6, 0x8b, 0x9c, 0x8b, 0x96, 0x7a, 0x8b, + 0x73, 0x8b, 0x59, 0x74, 0x71, 0xfb, 0x02, 0x42, 0x08, 0xf7, 0x48, 0xf7, + 0xca, 0x15, 0xa1, 0xa0, 0x8e, 0x8e, 0x93, 0x91, 0x08, 0xab, 0xa4, 0x05, + 0x7f, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x81, 0xa4, + 0x88, 0x89, 0x86, 0x87, 0x85, 0x86, 0x7a, 0x7d, 0x81, 0x83, 0x87, 0x88, + 0x84, 0x86, 0x86, 0x87, 0x7f, 0x83, 0x93, 0x74, 0x94, 0x7b, 0xa0, 0x6c, + 0x08, 0xfb, 0x19, 0x16, 0xac, 0xa9, 0x05, 0x91, 0x8f, 0x8f, 0x8e, 0xa1, + 0x9d, 0x80, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x80, + 0xa4, 0x86, 0x87, 0x87, 0x87, 0x86, 0x88, 0x71, 0x75, 0x88, 0x89, 0x71, + 0x79, 0x93, 0x74, 0x93, 0x7d, 0xa1, 0x6a, 0x08, 0x0e, 0xa6, 0xf8, 0x10, + 0xf7, 0x1d, 0x15, 0x33, 0x42, 0x68, 0x77, 0x64, 0x8b, 0x67, 0x8b, 0x76, + 0xa9, 0x8b, 0xc0, 0x8b, 0x8c, 0x8b, 0x93, 0x8c, 0x92, 0xda, 0xc0, 0x9b, + 0x96, 0xb0, 0xa8, 0xc0, 0xb3, 0xa1, 0xad, 0x8b, 0xb6, 0x8b, 0xaf, 0x76, + 0xa1, 0x69, 0x8b, 0x08, 0x75, 0x8b, 0x7b, 0x86, 0x73, 0x7e, 0x69, 0x78, + 0x64, 0x6c, 0x77, 0x74, 0x64, 0x5b, 0x6a, 0x20, 0x8b, 0x3a, 0x8b, 0x4f, + 0xaa, 0x66, 0xbe, 0x8b, 0xc6, 0x8b, 0xce, 0xb1, 0xe0, 0xde, 0x08, 0xa8, + 0x07, 0xfb, 0x6c, 0xb5, 0x15, 0x9f, 0xf7, 0x06, 0xb5, 0xd7, 0xb6, 0x8b, + 0x9c, 0x8b, 0x96, 0x7a, 0x8b, 0x73, 0x8b, 0x59, 0x74, 0x71, 0xfb, 0x02, + 0x42, 0x08, 0xe0, 0xf7, 0xad, 0x15, 0xca, 0xd5, 0x9e, 0xa0, 0xd8, 0xd9, + 0x08, 0x5e, 0xa1, 0xfb, 0x1e, 0xfb, 0x51, 0xa3, 0x85, 0x05, 0x0e, 0xa6, + 0xf8, 0x10, 0xf7, 0x1d, 0x15, 0x40, 0x4a, 0x5b, 0x6f, 0x65, 0x8b, 0x72, + 0x8b, 0x76, 0x9c, 0x84, 0xa5, 0x87, 0x9b, 0x8a, 0x96, 0x8b, 0xa8, 0xb8, + 0xa7, 0xa9, 0xa0, 0xc6, 0xb7, 0xc1, 0xb4, 0xa0, 0xac, 0x8b, 0xb8, 0x8b, + 0xae, 0x75, 0xa0, 0x68, 0x8b, 0x08, 0x75, 0x8b, 0x7b, 0x86, 0x74, 0x7e, + 0x65, 0x75, 0x69, 0x70, 0x76, 0x73, 0x65, 0x5d, 0x69, 0xfb, 0x02, 0x8b, + 0x3a, 0x8b, 0x50, 0xaa, 0x66, 0xbe, 0x8b, 0xc6, 0x8b, 0xd4, 0xb5, 0xda, + 0xda, 0x08, 0xa8, 0x07, 0xfb, 0x6c, 0xb5, 0x15, 0x9c, 0xf6, 0xb9, 0xde, + 0xb6, 0x8b, 0x9c, 0x8b, 0x96, 0x7a, 0x8b, 0x73, 0x8b, 0x59, 0x70, 0x6d, + 0x20, 0x46, 0x08, 0xf7, 0x3f, 0xf7, 0xb2, 0x15, 0x8c, 0x8b, 0x8d, 0x8b, + 0x8e, 0x8c, 0x7a, 0xc6, 0x88, 0x94, 0x81, 0xa9, 0x08, 0x6b, 0xe6, 0x05, + 0x84, 0x86, 0x82, 0x87, 0x8b, 0x8b, 0x85, 0x88, 0x86, 0x88, 0x85, 0x89, + 0x89, 0x8a, 0x87, 0x88, 0x84, 0x87, 0x9f, 0x68, 0xa7, 0x52, 0xae, 0x3d, + 0x08, 0x8f, 0x90, 0x8c, 0x8c, 0x1f, 0x95, 0x8e, 0x05, 0x0e, 0xa6, 0xf8, + 0x10, 0xf7, 0x1d, 0x15, 0x33, 0x42, 0x68, 0x77, 0x64, 0x8b, 0x67, 0x8b, + 0x76, 0xa9, 0x8b, 0xc0, 0x8b, 0x8c, 0x8b, 0x93, 0x8c, 0x92, 0xda, 0xc0, + 0x9b, 0x96, 0xb0, 0xa8, 0xc0, 0xb3, 0xa1, 0xad, 0x8b, 0xb6, 0x8b, 0xaf, + 0x76, 0xa1, 0x69, 0x8b, 0x08, 0x75, 0x8b, 0x7b, 0x86, 0x73, 0x7e, 0x69, + 0x78, 0x64, 0x6c, 0x77, 0x74, 0x64, 0x5b, 0x6a, 0x20, 0x8b, 0x3a, 0x8b, + 0x4f, 0xaa, 0x66, 0xbe, 0x8b, 0xc6, 0x8b, 0xce, 0xb1, 0xe0, 0xde, 0x08, + 0xa8, 0x07, 0xfb, 0x6c, 0xb5, 0x15, 0x9f, 0xf7, 0x06, 0xb5, 0xd7, 0xb6, + 0x8b, 0x9c, 0x8b, 0x96, 0x7a, 0x8b, 0x73, 0x8b, 0x59, 0x74, 0x71, 0xfb, + 0x02, 0x42, 0x08, 0xa1, 0xf7, 0xb6, 0x15, 0x8c, 0x82, 0xdc, 0xd5, 0x05, + 0xa4, 0xa1, 0x9a, 0x97, 0xac, 0xa5, 0x08, 0x96, 0x4b, 0x05, 0x90, 0x68, + 0x8e, 0x73, 0x8c, 0x80, 0x9e, 0x96, 0x8f, 0x8e, 0x98, 0x91, 0x08, 0x83, + 0xe4, 0x05, 0x8a, 0x96, 0x8a, 0xa0, 0x87, 0xc0, 0x86, 0x8c, 0x86, 0x8c, + 0x88, 0x8b, 0x89, 0x8b, 0x87, 0x8a, 0x83, 0x8a, 0x5f, 0x66, 0x76, 0x77, + 0xfb, 0x00, 0xfb, 0x01, 0x8c, 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8c, + 0x81, 0x05, 0x0e, 0x42, 0xf7, 0xcb, 0xf7, 0x08, 0x15, 0x2c, 0x58, 0x89, + 0x8a, 0x7e, 0x8b, 0x80, 0x8b, 0x84, 0x96, 0x8b, 0x9c, 0x8b, 0x95, 0x8e, + 0x9e, 0x91, 0xa1, 0xbe, 0xf7, 0x66, 0x95, 0xb3, 0x8b, 0x93, 0x8b, 0x91, + 0x86, 0x8f, 0x84, 0x8b, 0x7a, 0x8b, 0x50, 0x6a, 0x39, 0x54, 0x08, 0x89, + 0x6f, 0x05, 0xc6, 0xab, 0x90, 0x8d, 0x94, 0x8b, 0x93, 0x8b, 0x8f, 0x85, + 0x8b, 0x7f, 0x8b, 0x7e, 0x88, 0x7d, 0x7c, 0x52, 0x5c, 0xfb, 0x43, 0x8b, + 0x8b, 0x8b, 0x72, 0x8b, 0x73, 0x95, 0x7b, 0x99, 0x8b, 0x9c, 0x8b, 0xa5, + 0x98, 0xbf, 0xad, 0x08, 0x9e, 0x97, 0x9e, 0x97, 0x9e, 0x98, 0x95, 0x91, + 0x93, 0x90, 0x94, 0x91, 0x08, 0x92, 0xa7, 0x05, 0x7a, 0xf8, 0x09, 0x15, + 0xa1, 0xa0, 0x8e, 0x8e, 0x93, 0x91, 0x08, 0xab, 0xa4, 0x05, 0x7f, 0x9e, + 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x81, 0xa4, 0x87, 0x88, + 0x87, 0x88, 0x85, 0x86, 0x7a, 0x7d, 0x81, 0x83, 0x87, 0x88, 0x84, 0x86, + 0x86, 0x88, 0x7f, 0x82, 0x93, 0x74, 0x93, 0x7b, 0xa1, 0x6c, 0x08, 0xfb, + 0x19, 0x16, 0xac, 0xa9, 0x05, 0x91, 0x8f, 0x8f, 0x8e, 0xa1, 0x9d, 0x80, + 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x80, 0xa4, 0x86, + 0x87, 0x87, 0x87, 0x86, 0x88, 0x71, 0x75, 0x88, 0x89, 0x71, 0x79, 0x93, + 0x74, 0x93, 0x7d, 0xa1, 0x6a, 0x08, 0x0e, 0x42, 0xf7, 0xcb, 0xf7, 0x08, + 0x15, 0x2c, 0x58, 0x89, 0x8a, 0x7e, 0x8b, 0x80, 0x8b, 0x84, 0x96, 0x8b, + 0x9c, 0x8b, 0x95, 0x8e, 0x9e, 0x91, 0xa1, 0xbe, 0xf7, 0x66, 0x95, 0xb3, + 0x8b, 0x93, 0x8b, 0x91, 0x86, 0x8f, 0x84, 0x8b, 0x7a, 0x8b, 0x50, 0x6a, + 0x39, 0x54, 0x08, 0x89, 0x6f, 0x05, 0xc6, 0xab, 0x90, 0x8d, 0x94, 0x8b, + 0x93, 0x8b, 0x8f, 0x85, 0x8b, 0x7f, 0x8b, 0x7e, 0x88, 0x7d, 0x7c, 0x52, + 0x5c, 0xfb, 0x43, 0x8b, 0x8b, 0x8b, 0x72, 0x8b, 0x73, 0x95, 0x7b, 0x99, + 0x8b, 0x9c, 0x8b, 0xa5, 0x98, 0xbf, 0xad, 0x08, 0x9e, 0x97, 0x9e, 0x97, + 0x9e, 0x98, 0x95, 0x91, 0x93, 0x90, 0x94, 0x91, 0x08, 0x92, 0xa7, 0x05, + 0xfb, 0x04, 0xf7, 0xec, 0x15, 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, 0xd9, 0x08, + 0x5e, 0xa1, 0xfb, 0x1e, 0xfb, 0x51, 0xa3, 0x85, 0x05, 0x0e, 0x42, 0xf7, + 0xcb, 0xf7, 0x08, 0x15, 0x2c, 0x58, 0x89, 0x8a, 0x7e, 0x8b, 0x80, 0x8b, + 0x84, 0x96, 0x8b, 0x9c, 0x8b, 0x95, 0x8e, 0x9e, 0x91, 0xa1, 0xbe, 0xf7, + 0x66, 0x95, 0xb3, 0x8b, 0x93, 0x8b, 0x91, 0x86, 0x8f, 0x84, 0x8b, 0x7a, + 0x8b, 0x50, 0x6a, 0x39, 0x54, 0x08, 0x89, 0x6f, 0x05, 0xc6, 0xab, 0x90, + 0x8d, 0x94, 0x8b, 0x93, 0x8b, 0x8f, 0x85, 0x8b, 0x7f, 0x8b, 0x7e, 0x88, + 0x7d, 0x7c, 0x52, 0x5c, 0xfb, 0x43, 0x8b, 0x8b, 0x8b, 0x72, 0x8b, 0x73, + 0x95, 0x7b, 0x99, 0x8b, 0x9c, 0x8b, 0xa5, 0x98, 0xbf, 0xad, 0x08, 0x9e, + 0x97, 0x9e, 0x97, 0x9e, 0x98, 0x95, 0x91, 0x93, 0x90, 0x94, 0x91, 0x08, + 0x92, 0xa7, 0x05, 0xfb, 0x06, 0xf8, 0xa6, 0x15, 0x89, 0x8a, 0x85, 0x88, + 0x82, 0x86, 0x08, 0x7e, 0x84, 0x05, 0x9f, 0x66, 0x9c, 0x6a, 0xb9, 0x27, + 0x95, 0x8d, 0x8e, 0x8b, 0x97, 0x8f, 0x74, 0xd9, 0x84, 0xa2, 0x6b, 0xe3, + 0x08, 0x7b, 0x82, 0x05, 0x0e, 0x42, 0xf7, 0xcb, 0xf7, 0x08, 0x15, 0x2c, + 0x58, 0x89, 0x8a, 0x7e, 0x8b, 0x80, 0x8b, 0x84, 0x96, 0x8b, 0x9c, 0x8b, + 0x95, 0x8e, 0x9e, 0x91, 0xa1, 0xbe, 0xf7, 0x66, 0x95, 0xb3, 0x8b, 0x93, + 0x8b, 0x91, 0x86, 0x8f, 0x84, 0x8b, 0x7a, 0x8b, 0x50, 0x6a, 0x39, 0x54, + 0x08, 0x89, 0x6f, 0x05, 0xc6, 0xab, 0x90, 0x8d, 0x94, 0x8b, 0x93, 0x8b, + 0x8f, 0x85, 0x8b, 0x7f, 0x8b, 0x7e, 0x88, 0x7d, 0x7c, 0x52, 0x5c, 0xfb, + 0x43, 0x8b, 0x8b, 0x8b, 0x72, 0x8b, 0x73, 0x95, 0x7b, 0x99, 0x8b, 0x9c, + 0x8b, 0xa5, 0x98, 0xbf, 0xad, 0x08, 0x9e, 0x97, 0x9e, 0x97, 0x9e, 0x98, + 0x95, 0x91, 0x93, 0x90, 0x94, 0x91, 0x08, 0x92, 0xa7, 0x05, 0xfb, 0x43, + 0xf7, 0xf5, 0x15, 0x8c, 0x82, 0x05, 0xa9, 0xa8, 0xa5, 0xa3, 0xa4, 0xa0, + 0xa4, 0xa1, 0x9a, 0x97, 0xac, 0xa5, 0x08, 0x96, 0x4b, 0x05, 0x90, 0x68, + 0x8e, 0x73, 0x8c, 0x80, 0x9e, 0x96, 0x8f, 0x8e, 0x98, 0x91, 0x88, 0xa9, + 0x89, 0xa9, 0x88, 0xa8, 0x8a, 0x96, 0x8a, 0xa0, 0x87, 0xc0, 0x86, 0x8c, + 0x86, 0x8c, 0x88, 0x8b, 0x89, 0x8b, 0x87, 0x8a, 0x83, 0x8a, 0x08, 0x5f, + 0x65, 0x76, 0x78, 0xfb, 0x00, 0xfb, 0x01, 0x8c, 0x87, 0x8c, 0x87, 0x8b, + 0x8a, 0x08, 0x8c, 0x81, 0x05, 0x0e, 0xf7, 0x27, 0xf7, 0x38, 0x9e, 0x15, + 0xc6, 0xf7, 0x7f, 0x05, 0xf7, 0x11, 0xda, 0x8e, 0x8c, 0x99, 0x8b, 0x92, + 0x8b, 0x8f, 0x86, 0x8b, 0x83, 0x8b, 0x7c, 0x83, 0x65, 0x6e, 0xfb, 0x06, + 0x75, 0x32, 0x87, 0x7a, 0x8b, 0x78, 0x8b, 0x7d, 0x8f, 0x7e, 0x96, 0x79, + 0xb9, 0xa0, 0xd0, 0xb6, 0xd1, 0xbf, 0x08, 0x92, 0xa7, 0x05, 0x27, 0x52, + 0x87, 0x89, 0x81, 0x8b, 0x81, 0x8b, 0x85, 0x96, 0x8b, 0x9b, 0x8b, 0xa0, + 0x92, 0xac, 0x9e, 0xd0, 0xba, 0xf7, 0x3c, 0x8b, 0x8b, 0x8b, 0x92, 0x8b, + 0x96, 0x84, 0x91, 0x7e, 0x8b, 0x7c, 0x8b, 0x75, 0x82, 0x67, 0x74, 0x08, + 0xfb, 0x1d, 0x36, 0x05, 0x94, 0xac, 0x9a, 0xca, 0x8b, 0x93, 0x8b, 0x92, + 0x85, 0x91, 0x84, 0x8b, 0x80, 0x8b, 0x43, 0x66, 0x41, 0x5f, 0x08, 0x85, + 0x71, 0x05, 0xcb, 0xa8, 0x8f, 0x8c, 0x94, 0x8b, 0x92, 0x8b, 0x90, 0x85, + 0x8b, 0x83, 0x8b, 0x76, 0x78, 0x38, 0x72, 0x30, 0x08, 0x74, 0x3a, 0x05, + 0x89, 0x84, 0x86, 0x78, 0x84, 0x6f, 0x08, 0xd6, 0xa8, 0x05, 0xb5, 0xf8, + 0x6f, 0x15, 0xb0, 0xba, 0x9a, 0x97, 0xa4, 0x8b, 0x99, 0x8b, 0x9a, 0x86, + 0xa0, 0x7f, 0xbd, 0x6f, 0x97, 0x86, 0xa2, 0x8b, 0xaa, 0x8b, 0x9f, 0x9b, + 0xc1, 0xce, 0x08, 0x81, 0x9d, 0x05, 0x71, 0x73, 0x89, 0x89, 0x83, 0x85, + 0x7d, 0x81, 0x73, 0x82, 0x7c, 0x8b, 0x7e, 0x8b, 0x74, 0x93, 0x75, 0x97, + 0x65, 0xa1, 0x81, 0x8e, 0x77, 0x8b, 0x6b, 0x8b, 0x73, 0x77, 0x5a, 0x49, + 0x08, 0x98, 0x79, 0x05, 0x0e, 0xe2, 0xf7, 0xfb, 0xf8, 0x2f, 0x15, 0x63, + 0x8b, 0x4b, 0x6e, 0x50, 0x5f, 0x4b, 0x5b, 0x5e, 0x23, 0x8b, 0x28, 0x8b, + 0x4e, 0xad, 0x64, 0xc0, 0x8b, 0xa7, 0x8b, 0xa7, 0x95, 0xb9, 0xa3, 0xbd, + 0xa7, 0xac, 0xa4, 0x9d, 0xa3, 0xb3, 0xc1, 0xab, 0xed, 0x8b, 0xd0, 0x08, + 0xc1, 0x66, 0xb1, 0x56, 0x1e, 0x57, 0x5c, 0x15, 0xb3, 0xa4, 0x64, 0x4f, + 0x1f, 0x8b, 0x61, 0x7d, 0x57, 0x72, 0x5a, 0x6f, 0x52, 0x67, 0x6c, 0x65, + 0x8b, 0x08, 0x62, 0x71, 0xb0, 0xc4, 0xf7, 0x08, 0xd4, 0xf7, 0x0c, 0xd1, + 0x1f, 0xf7, 0x22, 0xf7, 0x48, 0x15, 0x7f, 0x9e, 0x87, 0x92, 0x87, 0x93, + 0x88, 0x91, 0x8a, 0x8e, 0x80, 0xa4, 0x86, 0x86, 0x86, 0x87, 0x88, 0x89, + 0x83, 0x85, 0x84, 0x85, 0x84, 0x84, 0x08, 0x82, 0x85, 0x05, 0x84, 0x86, + 0x86, 0x88, 0x7f, 0x82, 0x93, 0x74, 0x93, 0x7b, 0xa1, 0x6c, 0x08, 0xac, + 0xa9, 0xab, 0xa4, 0x05, 0xfb, 0x5a, 0x54, 0x15, 0xac, 0xa9, 0x05, 0x91, + 0x8f, 0x8f, 0x8e, 0xa1, 0x9d, 0x80, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, + 0x91, 0x8a, 0x8e, 0x80, 0xa4, 0x87, 0x87, 0x86, 0x88, 0x86, 0x87, 0x70, + 0x74, 0x8a, 0x8a, 0x70, 0x79, 0x93, 0x74, 0x93, 0x7d, 0xa1, 0x6a, 0x08, + 0x0e, 0xe2, 0xf7, 0xfb, 0xf8, 0x2f, 0x15, 0x63, 0x8b, 0x4b, 0x6e, 0x50, + 0x5f, 0x4b, 0x5b, 0x5e, 0x23, 0x8b, 0x28, 0x8b, 0x4e, 0xad, 0x64, 0xc0, + 0x8b, 0xa7, 0x8b, 0xa7, 0x95, 0xb9, 0xa3, 0xbd, 0xa7, 0xac, 0xa4, 0x9d, + 0xa3, 0xb3, 0xc1, 0xab, 0xed, 0x8b, 0xd0, 0x08, 0xc1, 0x66, 0xb1, 0x56, + 0x1e, 0x57, 0x5c, 0x15, 0xb3, 0xa4, 0x64, 0x4f, 0x1f, 0x8b, 0x61, 0x7d, + 0x57, 0x72, 0x5a, 0x6f, 0x52, 0x67, 0x6c, 0x65, 0x8b, 0x08, 0x62, 0x71, + 0xb0, 0xc4, 0xf7, 0x08, 0xd4, 0xf7, 0x0c, 0xd1, 0x1f, 0x7a, 0xeb, 0x15, + 0xc8, 0xd3, 0xa1, 0xa4, 0xd7, 0xd7, 0x08, 0x5e, 0xa1, 0xfb, 0x1e, 0xfb, + 0x51, 0xa3, 0x85, 0x05, 0x0e, 0xe2, 0xf7, 0xfb, 0xf8, 0x2f, 0x15, 0x63, + 0x8b, 0x4b, 0x6e, 0x50, 0x5f, 0x4b, 0x5b, 0x5e, 0x23, 0x8b, 0x28, 0x8b, + 0x4e, 0xad, 0x64, 0xc0, 0x8b, 0xa7, 0x8b, 0xa7, 0x95, 0xb9, 0xa3, 0xbd, + 0xa7, 0xac, 0xa4, 0x9d, 0xa3, 0xb3, 0xc1, 0xab, 0xed, 0x8b, 0xd0, 0x08, + 0xc1, 0x66, 0xb1, 0x56, 0x1e, 0x57, 0x5c, 0x15, 0xb3, 0xa4, 0x64, 0x4f, + 0x1f, 0x8b, 0x61, 0x7d, 0x57, 0x72, 0x5a, 0x6f, 0x52, 0x67, 0x6c, 0x65, + 0x8b, 0x08, 0x62, 0x71, 0xb0, 0xc4, 0xf7, 0x08, 0xd4, 0xf7, 0x0c, 0xd1, + 0x1f, 0xbc, 0xeb, 0x15, 0x95, 0x8d, 0x8e, 0x8b, 0x97, 0x8f, 0x74, 0xd9, + 0x84, 0xa2, 0x6b, 0xe3, 0x84, 0x87, 0x83, 0x87, 0x83, 0x87, 0x81, 0x85, + 0x8a, 0x8b, 0x7f, 0x84, 0xa0, 0x66, 0x9b, 0x69, 0xb9, 0x28, 0x08, 0x0e, + 0xe2, 0xf7, 0xfb, 0xf8, 0x2f, 0x15, 0x63, 0x8b, 0x4b, 0x6e, 0x50, 0x5f, + 0x4b, 0x5b, 0x5e, 0x23, 0x8b, 0x28, 0x8b, 0x4e, 0xad, 0x64, 0xc0, 0x8b, + 0xa7, 0x8b, 0xa7, 0x95, 0xb9, 0xa3, 0xbd, 0xa7, 0xac, 0xa4, 0x9d, 0xa3, + 0xb3, 0xc1, 0xab, 0xed, 0x8b, 0xd0, 0x08, 0xc1, 0x66, 0xb1, 0x56, 0x1e, + 0x57, 0x5c, 0x15, 0xb3, 0xa4, 0x64, 0x4f, 0x1f, 0x8b, 0x61, 0x7d, 0x57, + 0x72, 0x5a, 0x6f, 0x52, 0x67, 0x6c, 0x65, 0x8b, 0x08, 0x62, 0x71, 0xb0, + 0xc4, 0xf7, 0x08, 0xd4, 0xf7, 0x0c, 0xd1, 0x1f, 0x42, 0xf4, 0x15, 0x8c, + 0x82, 0xdc, 0xd5, 0xd4, 0xc7, 0x96, 0x4b, 0x91, 0x5c, 0x05, 0x8c, 0x86, + 0x8c, 0x84, 0x8c, 0x80, 0x9d, 0x96, 0x90, 0x8e, 0x98, 0x91, 0x08, 0x83, + 0xe4, 0x05, 0x8a, 0x96, 0x8a, 0xa0, 0x87, 0xc0, 0x86, 0x8c, 0x86, 0x8c, + 0x88, 0x8b, 0x89, 0x8b, 0x87, 0x8a, 0x83, 0x8a, 0x5d, 0x64, 0x7a, 0x7a, + 0xfb, 0x02, 0xfb, 0x02, 0x8c, 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8c, + 0x81, 0x05, 0x0e, 0xe2, 0xf7, 0xfb, 0xf8, 0x2f, 0x15, 0x63, 0x8b, 0x4b, + 0x6e, 0x50, 0x5f, 0x4b, 0x5b, 0x5e, 0x23, 0x8b, 0x28, 0x8b, 0x4e, 0xad, + 0x64, 0xc0, 0x8b, 0xa7, 0x8b, 0xa7, 0x95, 0xb9, 0xa3, 0xbd, 0xa7, 0xac, + 0xa4, 0x9d, 0xa3, 0xb3, 0xc1, 0xab, 0xed, 0x8b, 0xd0, 0x08, 0xc1, 0x66, + 0xb1, 0x56, 0x1e, 0x57, 0x5c, 0x15, 0xb3, 0xa4, 0x64, 0x4f, 0x1f, 0x8b, + 0x61, 0x7d, 0x57, 0x72, 0x5a, 0x6f, 0x52, 0x67, 0x6c, 0x65, 0x8b, 0x08, + 0x62, 0x71, 0xb0, 0xc4, 0xf7, 0x08, 0xd4, 0xf7, 0x0c, 0xd1, 0x1f, 0xfb, + 0x17, 0xf7, 0x16, 0x15, 0xb0, 0xba, 0x9a, 0x97, 0xa4, 0x8b, 0x99, 0x8b, + 0x9a, 0x86, 0xa0, 0x7f, 0xbd, 0x6f, 0x97, 0x86, 0xa2, 0x8b, 0xaa, 0x8b, + 0x9f, 0x9b, 0xc1, 0xce, 0x08, 0x81, 0x9d, 0x05, 0x71, 0x73, 0x89, 0x89, + 0x83, 0x85, 0x7d, 0x81, 0x73, 0x82, 0x7c, 0x8b, 0x7e, 0x8b, 0x74, 0x93, + 0x75, 0x97, 0x65, 0xa1, 0x81, 0x8e, 0x77, 0x8b, 0x6b, 0x8b, 0x73, 0x77, + 0x5a, 0x49, 0x08, 0x98, 0x79, 0x05, 0x0e, 0x92, 0xb6, 0xde, 0x15, 0x8a, + 0x82, 0x8a, 0x83, 0x8b, 0x85, 0x8b, 0x60, 0xa9, 0x6d, 0xb7, 0x8b, 0xaa, + 0x8b, 0xb6, 0x97, 0xab, 0x9e, 0xc6, 0xad, 0xaf, 0xbe, 0x8b, 0xbd, 0x8b, + 0xb0, 0x84, 0x93, 0x53, 0xae, 0x69, 0xa1, 0x7d, 0x9e, 0x8b, 0xa5, 0x08, + 0xad, 0xa8, 0xa9, 0xad, 0x1e, 0xa2, 0x8b, 0x9c, 0x80, 0xa1, 0x6f, 0xad, + 0xac, 0x8b, 0x8b, 0x98, 0x9e, 0x78, 0xa3, 0x77, 0x95, 0x6f, 0x8b, 0x42, + 0x8b, 0x2d, 0x34, 0x8b, 0x49, 0x8b, 0x6c, 0x9b, 0x73, 0xb1, 0x70, 0xbd, + 0x68, 0x92, 0x82, 0x8b, 0x72, 0x08, 0x67, 0x5d, 0x61, 0x64, 0x1e, 0x75, + 0x8b, 0x7a, 0x97, 0x81, 0xa1, 0x84, 0x9a, 0x89, 0x99, 0x8a, 0xae, 0x80, + 0x83, 0x83, 0x86, 0x87, 0x88, 0x83, 0x86, 0x82, 0x86, 0x82, 0x85, 0x08, + 0x79, 0x7f, 0x05, 0xf8, 0x43, 0xf8, 0xc6, 0x15, 0x8a, 0x95, 0x05, 0x81, + 0x82, 0x81, 0x82, 0x82, 0x82, 0x4c, 0x51, 0x84, 0x85, 0x54, 0x5f, 0x83, + 0xb4, 0x8b, 0x8f, 0x7f, 0xe5, 0x7e, 0x82, 0x8a, 0x8b, 0x76, 0x7f, 0x8f, + 0x57, 0x90, 0x51, 0x8f, 0x4c, 0x90, 0x89, 0x90, 0x8a, 0x8e, 0x8b, 0x08, + 0x8d, 0x8b, 0x8e, 0x8c, 0x94, 0x8d, 0xb9, 0xb1, 0xa5, 0xa4, 0xf0, 0xf1, + 0x8a, 0x90, 0x8a, 0x8e, 0x8b, 0x8d, 0x08, 0x8a, 0x94, 0x05, 0x0e, 0xf7, + 0x27, 0xdd, 0xf7, 0xc0, 0x15, 0xb5, 0xa0, 0x9e, 0x93, 0x97, 0x8b, 0x93, + 0x8b, 0x91, 0x83, 0x8b, 0x80, 0x8b, 0x7e, 0x81, 0x60, 0x79, 0x47, 0x72, + 0x2e, 0x85, 0x6f, 0x8b, 0x6e, 0x8b, 0x6f, 0x97, 0x76, 0x9b, 0x8b, 0x9a, + 0x8b, 0x9d, 0x94, 0xbd, 0xac, 0x08, 0xf2, 0xce, 0x05, 0x83, 0x6b, 0x85, + 0x67, 0x8b, 0x79, 0x8b, 0x7e, 0x93, 0x81, 0x95, 0x8b, 0x9f, 0x8b, 0xea, + 0xc3, 0xcf, 0xbe, 0x08, 0x92, 0xa9, 0x05, 0x3d, 0x5d, 0x71, 0x7d, 0x80, + 0x8b, 0x84, 0x8b, 0x87, 0x93, 0x8b, 0x9b, 0x8b, 0xbe, 0xb0, 0xf7, 0x29, + 0xb6, 0xf7, 0x13, 0x7e, 0x84, 0x82, 0x86, 0x87, 0x89, 0x7f, 0x85, 0x7f, + 0x85, 0x7e, 0x85, 0x88, 0x8a, 0x85, 0x88, 0x80, 0x85, 0x08, 0x85, 0x74, + 0x77, 0x3b, 0x6a, 0xfb, 0x1e, 0x3e, 0x56, 0x68, 0x77, 0x7f, 0x8b, 0x80, + 0x8b, 0x83, 0x99, 0x8b, 0x9e, 0x8b, 0xa2, 0x93, 0xb3, 0x9c, 0xcb, 0x96, + 0xb3, 0x92, 0xa7, 0x8e, 0x99, 0x94, 0xb0, 0x92, 0xa5, 0x8d, 0x92, 0x08, + 0x8e, 0x96, 0x8d, 0x94, 0x8b, 0x92, 0x8b, 0x93, 0x86, 0x90, 0x84, 0x8b, + 0x81, 0x8b, 0x42, 0x64, 0x43, 0x5e, 0x08, 0x84, 0x70, 0x05, 0xf7, 0xe0, + 0xf7, 0x51, 0x15, 0xa1, 0xa0, 0x8e, 0x8e, 0x93, 0x91, 0x08, 0xab, 0xa4, + 0x05, 0x7f, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, 0x81, + 0xa4, 0x87, 0x88, 0x87, 0x88, 0x85, 0x86, 0x7a, 0x7d, 0x81, 0x83, 0x87, + 0x88, 0x84, 0x86, 0x86, 0x88, 0x7f, 0x82, 0x93, 0x74, 0x93, 0x7b, 0xa1, + 0x6c, 0x08, 0xfb, 0x19, 0x16, 0xac, 0xa9, 0x05, 0x91, 0x8f, 0x8f, 0x8e, + 0xa1, 0x9d, 0x80, 0x9e, 0x87, 0x92, 0x87, 0x93, 0x88, 0x91, 0x8a, 0x8e, + 0x80, 0xa4, 0x86, 0x87, 0x87, 0x87, 0x86, 0x88, 0x71, 0x75, 0x88, 0x89, + 0x71, 0x79, 0x93, 0x74, 0x93, 0x7d, 0xa1, 0x6a, 0x08, 0x0e, 0xf7, 0x27, + 0xdd, 0xf7, 0xc0, 0x15, 0xb5, 0xa0, 0x9e, 0x93, 0x97, 0x8b, 0x93, 0x8b, + 0x91, 0x83, 0x8b, 0x80, 0x8b, 0x7e, 0x81, 0x60, 0x79, 0x47, 0x72, 0x2e, + 0x85, 0x6f, 0x8b, 0x6e, 0x8b, 0x6f, 0x97, 0x76, 0x9b, 0x8b, 0x9a, 0x8b, + 0x9d, 0x94, 0xbd, 0xac, 0x08, 0xf2, 0xce, 0x05, 0x83, 0x6b, 0x85, 0x67, + 0x8b, 0x79, 0x8b, 0x7e, 0x93, 0x81, 0x95, 0x8b, 0x9f, 0x8b, 0xea, 0xc3, + 0xcf, 0xbe, 0x08, 0x92, 0xa9, 0x05, 0x3d, 0x5d, 0x71, 0x7d, 0x80, 0x8b, + 0x84, 0x8b, 0x87, 0x93, 0x8b, 0x9b, 0x8b, 0xbe, 0xb0, 0xf7, 0x29, 0xb6, + 0xf7, 0x13, 0x7e, 0x84, 0x82, 0x86, 0x87, 0x89, 0x7f, 0x85, 0x7f, 0x85, + 0x7e, 0x85, 0x88, 0x8a, 0x85, 0x88, 0x80, 0x85, 0x08, 0x85, 0x74, 0x77, + 0x3b, 0x6a, 0xfb, 0x1e, 0x3e, 0x56, 0x68, 0x77, 0x7f, 0x8b, 0x80, 0x8b, + 0x83, 0x99, 0x8b, 0x9e, 0x8b, 0xa2, 0x93, 0xb3, 0x9c, 0xcb, 0x96, 0xb3, + 0x92, 0xa7, 0x8e, 0x99, 0x94, 0xb0, 0x92, 0xa5, 0x8d, 0x92, 0x08, 0x8e, + 0x96, 0x8d, 0x94, 0x8b, 0x92, 0x8b, 0x93, 0x86, 0x90, 0x84, 0x8b, 0x81, + 0x8b, 0x42, 0x64, 0x43, 0x5e, 0x08, 0x84, 0x70, 0x05, 0xf7, 0x81, 0xf7, + 0x34, 0x15, 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, 0xd9, 0x08, 0x5e, 0xa1, 0xfb, + 0x1e, 0xfb, 0x51, 0xa3, 0x85, 0x05, 0x0e, 0xf7, 0x27, 0xdd, 0xf7, 0xc0, + 0x15, 0xb5, 0xa0, 0x9e, 0x93, 0x97, 0x8b, 0x93, 0x8b, 0x91, 0x83, 0x8b, + 0x80, 0x8b, 0x7e, 0x81, 0x60, 0x79, 0x47, 0x72, 0x2e, 0x85, 0x6f, 0x8b, + 0x6e, 0x8b, 0x6f, 0x97, 0x76, 0x9b, 0x8b, 0x9a, 0x8b, 0x9d, 0x94, 0xbd, + 0xac, 0x08, 0xf2, 0xce, 0x05, 0x83, 0x6b, 0x85, 0x67, 0x8b, 0x79, 0x8b, + 0x7e, 0x93, 0x81, 0x95, 0x8b, 0x9f, 0x8b, 0xea, 0xc3, 0xcf, 0xbe, 0x08, + 0x92, 0xa9, 0x05, 0x3d, 0x5d, 0x71, 0x7d, 0x80, 0x8b, 0x84, 0x8b, 0x87, + 0x93, 0x8b, 0x9b, 0x8b, 0xbe, 0xb0, 0xf7, 0x29, 0xb6, 0xf7, 0x13, 0x7e, + 0x84, 0x82, 0x86, 0x87, 0x89, 0x7f, 0x85, 0x7f, 0x85, 0x7e, 0x85, 0x88, + 0x8a, 0x85, 0x88, 0x80, 0x85, 0x08, 0x85, 0x74, 0x77, 0x3b, 0x6a, 0xfb, + 0x1e, 0x3e, 0x56, 0x68, 0x77, 0x7f, 0x8b, 0x80, 0x8b, 0x83, 0x99, 0x8b, + 0x9e, 0x8b, 0xa2, 0x93, 0xb3, 0x9c, 0xcb, 0x96, 0xb3, 0x92, 0xa7, 0x8e, + 0x99, 0x94, 0xb0, 0x92, 0xa5, 0x8d, 0x92, 0x08, 0x8e, 0x96, 0x8d, 0x94, + 0x8b, 0x92, 0x8b, 0x93, 0x86, 0x90, 0x84, 0x8b, 0x81, 0x8b, 0x42, 0x64, + 0x43, 0x5e, 0x08, 0x84, 0x70, 0x05, 0xf7, 0x71, 0xf7, 0xee, 0x15, 0x82, + 0x87, 0x85, 0x87, 0x89, 0x8a, 0x08, 0x7e, 0x84, 0x05, 0x9f, 0x66, 0x9c, + 0x6a, 0xb9, 0x27, 0x95, 0x8d, 0x8e, 0x8b, 0x97, 0x8f, 0x74, 0xd9, 0x84, + 0xa2, 0x6b, 0xe3, 0x08, 0x7b, 0x82, 0x05, 0x0e, 0xf7, 0x27, 0xdd, 0xf7, + 0xc0, 0x15, 0xb5, 0xa0, 0x9e, 0x93, 0x97, 0x8b, 0x93, 0x8b, 0x91, 0x83, + 0x8b, 0x80, 0x8b, 0x7e, 0x81, 0x60, 0x79, 0x47, 0x72, 0x2e, 0x85, 0x6f, + 0x8b, 0x6e, 0x8b, 0x6f, 0x97, 0x76, 0x9b, 0x8b, 0x9a, 0x8b, 0x9d, 0x94, + 0xbd, 0xac, 0x08, 0xf2, 0xce, 0x05, 0x83, 0x6b, 0x85, 0x67, 0x8b, 0x79, + 0x8b, 0x7e, 0x93, 0x81, 0x95, 0x8b, 0x9f, 0x8b, 0xea, 0xc3, 0xcf, 0xbe, + 0x08, 0x92, 0xa9, 0x05, 0x3d, 0x5d, 0x71, 0x7d, 0x80, 0x8b, 0x84, 0x8b, + 0x87, 0x93, 0x8b, 0x9b, 0x8b, 0xbe, 0xb0, 0xf7, 0x29, 0xb6, 0xf7, 0x13, + 0x7e, 0x84, 0x82, 0x86, 0x87, 0x89, 0x7f, 0x85, 0x7f, 0x85, 0x7e, 0x85, + 0x88, 0x8a, 0x85, 0x88, 0x80, 0x85, 0x08, 0x85, 0x74, 0x77, 0x3b, 0x6a, + 0xfb, 0x1e, 0x3e, 0x56, 0x68, 0x77, 0x7f, 0x8b, 0x80, 0x8b, 0x83, 0x99, + 0x8b, 0x9e, 0x8b, 0xa2, 0x93, 0xb3, 0x9c, 0xcb, 0x96, 0xb3, 0x92, 0xa7, + 0x8e, 0x99, 0x94, 0xb0, 0x92, 0xa5, 0x8d, 0x92, 0x08, 0x8e, 0x96, 0x8d, + 0x94, 0x8b, 0x92, 0x8b, 0x93, 0x86, 0x90, 0x84, 0x8b, 0x81, 0x8b, 0x42, + 0x64, 0x43, 0x5e, 0x08, 0x84, 0x70, 0x05, 0xf7, 0x38, 0xf7, 0x3d, 0x15, + 0x8c, 0x82, 0xdc, 0xd5, 0x05, 0xa4, 0xa1, 0x9a, 0x97, 0xac, 0xa5, 0x08, + 0x96, 0x4b, 0x91, 0x5c, 0x05, 0x8c, 0x86, 0x8c, 0x84, 0x8c, 0x80, 0x9e, + 0x96, 0x8f, 0x8e, 0x98, 0x91, 0x08, 0x83, 0xe4, 0x05, 0x8a, 0x96, 0x8a, + 0xa0, 0x87, 0xc0, 0x86, 0x8c, 0x86, 0x8c, 0x88, 0x8b, 0x89, 0x8b, 0x87, + 0x8a, 0x83, 0x8a, 0x5f, 0x65, 0x76, 0x78, 0xfb, 0x00, 0xfb, 0x01, 0x8c, + 0x87, 0x8c, 0x87, 0x8b, 0x8a, 0x08, 0x8c, 0x81, 0x05, 0x0e, 0xe2, 0x96, + 0xfb, 0x85, 0x15, 0xaa, 0x87, 0xb7, 0x88, 0xae, 0x8b, 0xd1, 0x8b, 0xb3, + 0x9e, 0xc4, 0xc8, 0xc5, 0xc9, 0x8f, 0x96, 0xae, 0xf7, 0x37, 0xae, 0xf7, + 0x35, 0x9e, 0xd6, 0xad, 0xf7, 0x03, 0x7e, 0x84, 0x80, 0x85, 0x87, 0x89, + 0x08, 0x68, 0x7a, 0x05, 0x86, 0x88, 0x83, 0x88, 0x82, 0x86, 0x08, 0x4e, + 0xfb, 0x87, 0x05, 0x27, 0x4d, 0x86, 0x88, 0x7a, 0x8b, 0x7e, 0x8b, 0x82, + 0x99, 0x8b, 0x9d, 0x8b, 0xa1, 0x94, 0xb9, 0x9e, 0xd2, 0xa4, 0xee, 0x99, + 0xc3, 0x8b, 0x94, 0x8b, 0x92, 0x86, 0x90, 0x85, 0x8b, 0x80, 0x8b, 0x4b, + 0x69, 0x37, 0x59, 0x08, 0x88, 0x70, 0x05, 0xba, 0xa3, 0x96, 0x90, 0x96, + 0x8b, 0x95, 0x8b, 0x90, 0x85, 0x8b, 0x82, 0x8b, 0x79, 0x84, 0x6d, 0x73, + 0x33, 0x73, 0x34, 0x86, 0x75, 0x8b, 0x71, 0x8b, 0x6b, 0x9a, 0x73, 0x9f, + 0x8b, 0x9e, 0x8b, 0xdb, 0xbb, 0xe4, 0xcb, 0x08, 0x65, 0xfb, 0x4b, 0x8b, + 0x8b, 0x7f, 0x66, 0x7b, 0x58, 0x6b, 0x78, 0x4a, 0x8b, 0x6e, 0x8b, 0x75, + 0x8f, 0x50, 0x99, 0x08, 0x63, 0x47, 0x05, 0xf7, 0xc8, 0xf9, 0x51, 0x15, + 0xc9, 0xd4, 0x9f, 0xa1, 0xd8, 0xd9, 0x08, 0x5e, 0xa1, 0xfb, 0x1e, 0xfb, + 0x51, 0xa3, 0x85, 0x05, 0x0e, 0xb9, 0xb0, 0x15, 0x8b, 0x86, 0x8c, 0x86, + 0x8d, 0x82, 0x9e, 0x97, 0x93, 0x90, 0xa0, 0x97, 0x99, 0x86, 0x98, 0x87, + 0x90, 0x8a, 0xae, 0x7f, 0x99, 0x86, 0x9d, 0x84, 0xc1, 0x78, 0xa9, 0x84, + 0xa3, 0x8b, 0xae, 0x8b, 0xa4, 0x99, 0xbb, 0xba, 0x08, 0xb4, 0xb2, 0x9a, + 0xa3, 0x8b, 0xa4, 0x8b, 0x97, 0x88, 0x96, 0x80, 0xa1, 0x08, 0x78, 0x7f, + 0x05, 0x76, 0x7d, 0x8a, 0x8b, 0x79, 0x7e, 0x94, 0x77, 0x8d, 0x82, 0x8b, + 0x7f, 0x8b, 0x6b, 0x71, 0x72, 0x6b, 0x8b, 0x68, 0x8b, 0x6f, 0x94, 0xfb, + 0x09, 0xbf, 0x08, 0xb6, 0xb5, 0xf7, 0x77, 0xf7, 0x6e, 0xaf, 0xb0, 0x8b, + 0x92, 0x8c, 0x98, 0x8b, 0x8f, 0x05, 0x62, 0x6f, 0x84, 0x89, 0x57, 0x8b, + 0x80, 0x8b, 0x7f, 0x8b, 0x79, 0x8c, 0x08, 0x4f, 0x8c, 0x05, 0x7a, 0x8b, + 0x7a, 0x8b, 0x89, 0x8c, 0x08, 0x83, 0x06, 0x6f, 0x8b, 0x89, 0x88, 0x5b, + 0xfb, 0x13, 0x08, 0x9d, 0x78, 0x99, 0xa8, 0x05, 0xa0, 0xba, 0x96, 0x93, + 0xb5, 0x8d, 0x08, 0xd0, 0x8c, 0x05, 0xa5, 0x8c, 0x8c, 0x8b, 0xa0, 0x90, + 0x2f, 0x32, 0x27, 0x30, 0xfb, 0x1d, 0xfb, 0x0c, 0x08, 0x85, 0x07, 0xf8, + 0x72, 0xf8, 0xf4, 0x15, 0x8a, 0x95, 0x6e, 0x70, 0x05, 0x4b, 0x50, 0x88, + 0x89, 0x51, 0x5c, 0x84, 0xb0, 0x88, 0x9e, 0x81, 0xda, 0x82, 0x85, 0x87, + 0x89, 0x87, 0x88, 0x08, 0x79, 0x81, 0x05, 0x8f, 0x57, 0x90, 0x51, 0x8f, + 0x4c, 0x90, 0x89, 0x90, 0x8a, 0x8e, 0x8b, 0x8d, 0x8b, 0x8e, 0x8c, 0x94, + 0x8d, 0xb8, 0xb1, 0xab, 0xa9, 0xeb, 0xec, 0x8a, 0x90, 0x8a, 0x8e, 0x8b, + 0x8d, 0x08, 0x8a, 0x94, 0x05, 0x0e, 0xe2, 0xf7, 0x65, 0xf9, 0x1f, 0x15, + 0xb4, 0x79, 0x9b, 0x80, 0xb0, 0x6b, 0x08, 0xfb, 0x25, 0x4d, 0xaa, 0x77, + 0xf7, 0x1e, 0xc7, 0x05, 0xaf, 0x5f, 0xa7, 0x40, 0x8e, 0x4f, 0x7a, 0x9b, + 0x82, 0x8e, 0x73, 0x8b, 0x70, 0x8b, 0x74, 0x82, 0x65, 0x74, 0x59, 0x6c, + 0x65, 0x6e, 0x7b, 0x75, 0x66, 0x5c, 0x6f, 0x2f, 0x8b, 0x44, 0x8b, 0x51, + 0xae, 0x64, 0xbe, 0x8b, 0x08, 0xb6, 0x8b, 0xe0, 0xb2, 0xbf, 0xb7, 0xc3, + 0xbb, 0xbc, 0xf7, 0x18, 0x8b, 0xf4, 0x8b, 0xe8, 0x6d, 0xd8, 0x4f, 0xc8, + 0x08, 0xf7, 0x51, 0xe0, 0x6e, 0x9d, 0xfb, 0x4e, 0x3b, 0x05, 0x73, 0x9f, + 0x61, 0xa1, 0x5f, 0x9c, 0x08, 0x74, 0x7a, 0x05, 0xeb, 0xfb, 0xb2, 0x15, + 0x9d, 0x8b, 0xa1, 0x7d, 0x98, 0x77, 0x96, 0x7b, 0x8f, 0x79, 0x8b, 0x71, + 0x8b, 0x5a, 0x7e, 0x5a, 0x71, 0x58, 0x6e, 0x51, 0x68, 0x6d, 0x65, 0x8b, + 0x08, 0x62, 0x70, 0xb0, 0xc3, 0xf7, 0x06, 0xd4, 0xf7, 0x10, 0xcf, 0x1f, + 0x0e, 0x9b, 0xfb, 0x70, 0x15, 0x73, 0x72, 0x05, 0xcd, 0x89, 0xcf, 0x8a, + 0xb0, 0x8b, 0x08, 0xba, 0x8b, 0xab, 0xa3, 0xfb, 0x07, 0x93, 0x05, 0x94, + 0xb7, 0x92, 0xaa, 0x92, 0xaa, 0x90, 0xa0, 0x90, 0xa0, 0x91, 0xa1, 0x8c, + 0x92, 0x8f, 0x9a, 0x90, 0xa0, 0xa1, 0x87, 0x96, 0x8a, 0x99, 0x8b, 0xb6, + 0x8b, 0xa7, 0x95, 0xb1, 0xaa, 0xbe, 0xb2, 0x9e, 0x9d, 0x98, 0x9d, 0x08, + 0xae, 0xbd, 0xab, 0xf6, 0x8b, 0xcd, 0x8b, 0xbb, 0x75, 0xab, 0x68, 0x8b, + 0x73, 0x8b, 0x6c, 0x7d, 0x61, 0x6c, 0x08, 0x3b, 0x51, 0xbb, 0xf7, 0x5c, + 0x05, 0xa8, 0xf2, 0x97, 0x9c, 0xb2, 0x8b, 0x9a, 0x8b, 0x97, 0x89, 0xa5, + 0x86, 0x08, 0xb6, 0xc0, 0x05, 0x74, 0x90, 0x81, 0x8c, 0x7c, 0x8b, 0x61, + 0x8b, 0x6e, 0x7c, 0x5a, 0x5f, 0x5d, 0x61, 0x81, 0x7e, 0x7f, 0x68, 0x80, + 0x6b, 0x7f, 0x5f, 0x7c, 0x43, 0x3d, 0xfb, 0xf7, 0x73, 0x28, 0x63, 0xfb, + 0x25, 0x08, 0x63, 0x87, 0x05, 0xf7, 0x45, 0xf7, 0xb2, 0x15, 0xac, 0xf7, + 0x25, 0x8c, 0x93, 0x97, 0xbc, 0xda, 0xc6, 0xaa, 0x9c, 0xa7, 0x8b, 0x9f, + 0x8b, 0x98, 0x75, 0x8b, 0x68, 0x8b, 0x60, 0x7c, 0x52, 0x72, 0x56, 0x71, + 0x51, 0x66, 0x6b, 0x63, 0x8b, 0x75, 0x8b, 0x72, 0x93, 0x70, 0x99, 0x08, + 0x0e, 0xe2, 0x96, 0xfb, 0x85, 0x15, 0xab, 0x87, 0xb6, 0x88, 0xaf, 0x8b, + 0xd0, 0x8b, 0xb3, 0x9f, 0xc4, 0xc7, 0xc5, 0xc9, 0x8f, 0x96, 0xae, 0xf7, + 0x37, 0xad, 0xf7, 0x31, 0xa0, 0xde, 0xac, 0xf6, 0x7e, 0x84, 0x80, 0x85, + 0x87, 0x89, 0x80, 0x85, 0x7e, 0x85, 0x80, 0x86, 0x08, 0x86, 0x88, 0x83, + 0x88, 0x82, 0x86, 0x08, 0x4e, 0xfb, 0x87, 0x05, 0x28, 0x4d, 0x85, 0x88, + 0x7a, 0x8b, 0x7e, 0x8b, 0x82, 0x98, 0x8b, 0x9e, 0x8b, 0xa1, 0x95, 0xbb, + 0x9c, 0xd0, 0xa4, 0xe9, 0x9a, 0xc8, 0x8b, 0x94, 0x8b, 0x92, 0x86, 0x90, + 0x85, 0x8b, 0x80, 0x8b, 0x4c, 0x6a, 0x36, 0x58, 0x08, 0x88, 0x70, 0x05, + 0xba, 0xa4, 0x96, 0x8f, 0x96, 0x8b, 0x95, 0x8b, 0x90, 0x85, 0x8b, 0x82, + 0x8b, 0x79, 0x84, 0x6e, 0x73, 0x32, 0x72, 0x32, 0x87, 0x77, 0x8b, 0x71, + 0x8b, 0x6b, 0x9a, 0x73, 0x9f, 0x8b, 0x9e, 0x8b, 0xdb, 0xba, 0xe4, 0xcc, + 0x08, 0x84, 0x68, 0x85, 0x6f, 0x86, 0x76, 0x79, 0x32, 0x88, 0x80, 0x80, + 0x67, 0x7b, 0x58, 0x6b, 0x78, 0x4a, 0x8b, 0x6e, 0x8b, 0x75, 0x8f, 0x50, + 0x99, 0x08, 0x63, 0x47, 0x05, 0xf8, 0x20, 0xf9, 0x6e, 0x15, 0xa2, 0xa0, + 0x8e, 0x8e, 0x92, 0x91, 0x91, 0x8f, 0x8f, 0x8e, 0xa1, 0x9d, 0x79, 0xa9, + 0x8b, 0x8c, 0x7b, 0xb0, 0x87, 0x88, 0x87, 0x87, 0x85, 0x87, 0x70, 0x74, + 0x8a, 0x8b, 0x70, 0x78, 0x93, 0x74, 0x94, 0x7b, 0xa0, 0x6c, 0x08, 0xfb, + 0x07, 0xf7, 0x04, 0x15, 0x71, 0x76, 0x88, 0x88, 0x70, 0x79, 0x94, 0x74, + 0x92, 0x7d, 0xa2, 0x6a, 0x08, 0xac, 0xa9, 0x05, 0x91, 0x90, 0x8f, 0x8e, + 0xa1, 0x9c, 0x79, 0xa9, 0x8a, 0x8c, 0x7b, 0xb0, 0x08, 0x7e, 0x80, 0x05, + 0x0e, 0xb8, 0xf7, 0x51, 0x15, 0x84, 0x67, 0x88, 0x6e, 0x8b, 0x6d, 0x8b, + 0x22, 0xbe, 0x4d, 0xe0, 0x8b, 0xd9, 0x8b, 0xed, 0xb4, 0xd7, 0xcc, 0x08, + 0x93, 0xa9, 0x05, 0x3a, 0x4c, 0x50, 0x71, 0x4e, 0x8b, 0x46, 0x8b, 0x5f, + 0xc7, 0x8b, 0xea, 0x8b, 0x9e, 0x8c, 0xa0, 0x8e, 0xa4, 0x08, 0xf7, 0x24, + 0x95, 0xb2, 0xa8, 0xfb, 0x44, 0x8b, 0x05, 0x8f, 0xa0, 0x8f, 0x9b, 0x91, + 0x9d, 0x08, 0xf7, 0x62, 0x99, 0xac, 0xa4, 0xfb, 0x77, 0x8b, 0x05, 0xbe, + 0xf7, 0x19, 0xdf, 0xdf, 0xdd, 0x8b, 0xbf, 0x8b, 0xa6, 0x66, 0x90, 0x3c, + 0x08, 0xd4, 0xca, 0x05, 0x88, 0xab, 0x86, 0x9b, 0x7f, 0x9a, 0x7a, 0xa2, + 0x6b, 0x99, 0x67, 0x8b, 0xfb, 0x09, 0x8b, 0xfb, 0x22, 0xfb, 0x05, 0x41, + 0xfb, 0x2b, 0x08, 0x4d, 0x06, 0x7f, 0x7d, 0x8a, 0x8a, 0x7d, 0x78, 0x88, + 0x86, 0x87, 0x86, 0x88, 0x87, 0x08, 0xdc, 0x90, 0x05, 0x84, 0x78, 0x86, + 0x7c, 0x86, 0x7a, 0x08, 0x5e, 0x06, 0x81, 0x80, 0x88, 0x87, 0x86, 0x84, + 0x84, 0x83, 0x8b, 0x8a, 0x7e, 0x79, 0x08, 0xd4, 0x90, 0x05, 0x0e, 0x5a, + 0xe1, 0xf7, 0x6d, 0x15, 0x9d, 0x8b, 0x91, 0x8b, 0xdf, 0x8d, 0x08, 0xd5, + 0x89, 0xa6, 0x8b, 0x9e, 0xa6, 0x05, 0x4a, 0x8d, 0x7b, 0x8e, 0x8b, 0x98, + 0x8b, 0x98, 0xbf, 0xf7, 0x79, 0x9d, 0xcb, 0x80, 0x86, 0x89, 0x8a, 0x7d, + 0x84, 0x52, 0x6c, 0x7e, 0x85, 0x51, 0x73, 0x08, 0xa2, 0x7b, 0x05, 0xa2, + 0x96, 0x96, 0x8f, 0xab, 0x97, 0x08, 0x55, 0xfb, 0x7f, 0x05, 0x86, 0x78, + 0x8b, 0x8a, 0x79, 0x8a, 0x6f, 0x88, 0x88, 0x8b, 0x87, 0x8b, 0x08, 0x80, + 0x89, 0x87, 0x8b, 0x73, 0x70, 0x05, 0x0e, 0x5a, 0xde, 0xf7, 0x62, 0x15, + 0xa8, 0xa9, 0x93, 0x91, 0x99, 0x8b, 0x91, 0x8b, 0x93, 0x8a, 0x94, 0x89, + 0xb9, 0x80, 0xc7, 0x80, 0x95, 0x8b, 0x90, 0x8b, 0x8e, 0x8c, 0x93, 0x8e, + 0x08, 0xcc, 0xdd, 0x7f, 0x9c, 0x05, 0x5b, 0x57, 0x85, 0x87, 0x7c, 0x8b, + 0x87, 0x8b, 0x87, 0x8c, 0x85, 0x8c, 0x4f, 0x98, 0x81, 0x8d, 0x74, 0x8d, + 0x08, 0x9b, 0x9a, 0xe9, 0xdb, 0x05, 0xaf, 0xa7, 0x92, 0x93, 0x98, 0xa2, + 0x98, 0xa1, 0x90, 0x9d, 0x8b, 0x9f, 0x08, 0xb2, 0x6f, 0xa5, 0x61, 0x45, + 0x4f, 0x5e, 0x58, 0x1e, 0x8b, 0x86, 0x8b, 0x88, 0x8d, 0x83, 0x08, 0xbc, + 0x85, 0x05, 0x85, 0xa0, 0x89, 0x93, 0x8b, 0x96, 0x08, 0xa7, 0x9f, 0x9d, + 0xab, 0xaa, 0xa1, 0x75, 0x6d, 0x1e, 0x8b, 0x64, 0x7a, 0x73, 0x3f, 0x49, + 0x3c, 0x47, 0x7c, 0x7c, 0x6c, 0x66, 0x08, 0x8e, 0x74, 0x05, 0x0e, 0x5a, + 0xd0, 0xf7, 0x7d, 0x15, 0xac, 0x7a, 0x9b, 0x87, 0xab, 0x8b, 0xeb, 0x8b, + 0xe5, 0xd7, 0x8b, 0xdd, 0x8b, 0x9d, 0x85, 0x99, 0x7d, 0x96, 0x82, 0x93, + 0x71, 0x95, 0x81, 0x8b, 0x08, 0x87, 0x8b, 0x90, 0x8f, 0x05, 0x94, 0x91, + 0x93, 0x90, 0xa3, 0x9a, 0x08, 0xa1, 0xa0, 0x93, 0x99, 0x8b, 0x9f, 0x8b, + 0xa6, 0x72, 0x9d, 0x67, 0x8b, 0x81, 0x8b, 0x82, 0x8a, 0x7a, 0x87, 0x76, + 0x7e, 0x76, 0x7d, 0x77, 0x7d, 0x08, 0x8b, 0x77, 0x9a, 0x94, 0x05, 0xa6, + 0x9b, 0x97, 0x8f, 0x9a, 0x8b, 0xa0, 0x8b, 0x9c, 0x7d, 0x8b, 0x79, 0x8b, + 0x68, 0x61, 0x6d, 0x31, 0x6c, 0x08, 0x86, 0x75, 0x8f, 0x8c, 0x05, 0xb3, + 0x97, 0x95, 0x8d, 0x99, 0x8b, 0x08, 0xb0, 0xa4, 0x76, 0x6e, 0x57, 0x60, + 0x60, 0x56, 0x1f, 0x72, 0x8b, 0x78, 0x90, 0x60, 0x9e, 0x08, 0x6b, 0x68, + 0x05, 0x0e, 0x2e, 0xf7, 0x3d, 0xf7, 0xa9, 0x15, 0x69, 0x70, 0x70, 0x6a, + 0x6a, 0xa6, 0x6f, 0xac, 0xad, 0xa6, 0xa6, 0xad, 0xac, 0x70, 0xa6, 0x6a, + 0x1f, 0x0e, 0x6a, 0xf7, 0x10, 0xf7, 0x41, 0x15, 0xe3, 0x8d, 0x05, 0x94, + 0x8b, 0x93, 0x8b, 0xa5, 0x89, 0x99, 0xa2, 0x9a, 0xa0, 0x9b, 0x9e, 0x08, + 0x30, 0x8c, 0x05, 0x7d, 0x8b, 0x82, 0x8b, 0x74, 0x8a, 0x7d, 0x7d, 0x7a, + 0x75, 0x7a, 0x70, 0x08, 0x94, 0x06, 0x0e, 0xe2, 0xf7, 0xcd, 0xf8, 0xd4, + 0x15, 0x46, 0x55, 0x55, 0x47, 0x45, 0xc0, 0x55, 0xce, 0xce, 0xc0, 0xc1, + 0xd0, 0xd0, 0x58, 0xc1, 0x49, 0x1f, 0x89, 0x5d, 0x15, 0xb3, 0xac, 0x68, + 0x61, 0x60, 0x6a, 0x69, 0x62, 0x62, 0x69, 0xae, 0xb5, 0xb6, 0xad, 0xad, + 0xb5, 0x1f, 0x0e, 0xf7, 0x63, 0xf8, 0xc3, 0xf7, 0x8a, 0x15, 0xfc, 0x8c, + 0x55, 0xf8, 0x8c, 0xc1, 0x06, 0x0e, 0xf7, 0x63, 0xf7, 0xc8, 0xf7, 0x95, + 0x15, 0xfb, 0x3b, 0xf7, 0x3b, 0x65, 0x65, 0xf7, 0x3b, 0xfb, 0x3b, 0xfb, + 0x3b, 0xfb, 0x3b, 0xb1, 0x65, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xfb, + 0x3b, 0xb1, 0xb1, 0xfb, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0xf7, 0x3b, 0x65, + 0xb1, 0xfb, 0x3b, 0xfb, 0x3b, 0x05, 0x0e, 0xf7, 0x63, 0xf7, 0xc9, 0xf7, + 0x0c, 0x15, 0x68, 0x6f, 0x70, 0x69, 0x68, 0xa7, 0x6f, 0xad, 0xad, 0xa7, + 0xa7, 0xad, 0xad, 0x6f, 0xa7, 0x6a, 0x1f, 0xf7, 0xd7, 0x04, 0x68, 0x6f, + 0x6f, 0x6a, 0x68, 0xa7, 0x6f, 0xad, 0xad, 0xa7, 0xa7, 0xad, 0xad, 0x6f, + 0xa7, 0x6a, 0x1f, 0xf7, 0x60, 0xfb, 0x59, 0x15, 0xfc, 0x2e, 0x55, 0xf8, + 0x2e, 0xc1, 0x06, 0x0e, 0xf9, 0x43, 0xf8, 0x0c, 0xf8, 0xb4, 0x15, 0x9c, + 0x8c, 0x92, 0x8c, 0x91, 0x8b, 0xb0, 0x8b, 0x96, 0x88, 0x91, 0x82, 0x92, + 0x7f, 0x90, 0x77, 0x95, 0x59, 0x08, 0xa6, 0x99, 0x05, 0x85, 0xf7, 0x06, + 0x05, 0x5f, 0x83, 0x66, 0x88, 0x50, 0x8b, 0x08, 0x3e, 0x8b, 0x45, 0x8f, + 0x6d, 0x92, 0x08, 0x76, 0xfb, 0x13, 0xa9, 0x93, 0x90, 0x97, 0x05, 0xa3, + 0xcf, 0x90, 0x91, 0xa5, 0x8b, 0x97, 0x8b, 0xa3, 0x8a, 0xa0, 0x89, 0x85, + 0xfb, 0x11, 0x82, 0xfb, 0x0c, 0x83, 0x53, 0x08, 0x4e, 0x87, 0x77, 0x73, + 0x05, 0xa3, 0x8c, 0xa0, 0x8c, 0x94, 0x8b, 0xb5, 0x8b, 0xd5, 0x8a, 0xa9, + 0x89, 0x08, 0xa0, 0xa2, 0x40, 0x91, 0x05, 0xa1, 0xf7, 0xc1, 0x05, 0xf9, + 0x36, 0xfb, 0xbe, 0x15, 0x81, 0x06, 0x53, 0x8c, 0x86, 0x90, 0x8b, 0xbb, + 0x8b, 0xaa, 0x93, 0xf7, 0x2a, 0x8e, 0xad, 0x8e, 0xa8, 0x92, 0x91, 0xaa, + 0x8c, 0x08, 0x9c, 0xa4, 0x05, 0x66, 0x89, 0x7f, 0x8a, 0x53, 0x8b, 0x75, + 0x64, 0x80, 0x79, 0x78, 0x6d, 0x59, 0x3c, 0x73, 0x61, 0x68, 0x43, 0x08, + 0x64, 0xe1, 0x50, 0xf7, 0x14, 0x05, 0x78, 0xb4, 0x88, 0x92, 0x7e, 0xa0, + 0x80, 0x8a, 0x80, 0x8b, 0x87, 0x8b, 0x08, 0x6a, 0x8a, 0x71, 0x89, 0x05, + 0x87, 0x8b, 0x84, 0x8b, 0x7f, 0x8a, 0x08, 0x75, 0x75, 0x05, 0xb6, 0x8a, + 0x97, 0x89, 0x96, 0x87, 0x96, 0x86, 0x93, 0x7d, 0x8b, 0x7c, 0x8b, 0x72, + 0x73, 0xfb, 0x54, 0x81, 0x5a, 0x08, 0x5a, 0x87, 0x7a, 0x74, 0x05, 0xa6, + 0x8d, 0x98, 0x8b, 0x98, 0x8b, 0x08, 0xa6, 0x06, 0xa0, 0x8a, 0x9f, 0x8a, + 0x8e, 0x8b, 0x08, 0xa3, 0x8b, 0xa1, 0xa2, 0x05, 0x78, 0x8c, 0x70, 0x8c, + 0x77, 0x8d, 0x8a, 0x91, 0x8b, 0x91, 0x8b, 0x8d, 0x8b, 0xa0, 0x8e, 0xc5, + 0x8f, 0xb2, 0x08, 0x95, 0xf7, 0x0d, 0x05, 0xbc, 0x21, 0xa4, 0x54, 0x8d, + 0x86, 0xa9, 0x4a, 0x91, 0x7d, 0x99, 0x66, 0x08, 0x90, 0x8d, 0x05, 0x9c, + 0x94, 0x8b, 0x8b, 0x9a, 0x8f, 0x9f, 0xcd, 0xc0, 0xf3, 0xcf, 0xf7, 0x00, + 0x83, 0xfb, 0x07, 0x85, 0x2c, 0x87, 0x41, 0x08, 0x98, 0x7f, 0xf7, 0x04, + 0x9a, 0x9a, 0xa0, 0x05, 0x0e, 0xf7, 0x63, 0xf7, 0xe3, 0xf7, 0xa8, 0x15, + 0xf7, 0x46, 0xc1, 0xfb, 0x46, 0xf7, 0x46, 0x55, 0xfb, 0x46, 0xfb, 0x46, + 0x55, 0xf7, 0x46, 0xfb, 0x46, 0xc1, 0xf7, 0x46, 0x06, 0xfb, 0x7c, 0xfb, + 0xa8, 0x15, 0xf8, 0x2e, 0xc1, 0xfc, 0x2e, 0x55, 0x06, 0x0e, 0xf7, 0xef, + 0xf7, 0x63, 0x87, 0x15, 0xa2, 0x8a, 0x96, 0x8b, 0x05, 0xb6, 0xdb, 0x92, + 0x96, 0xda, 0xf7, 0x17, 0x08, 0xee, 0xf7, 0x3b, 0x05, 0xcc, 0xf7, 0x02, + 0x92, 0x97, 0xbd, 0xd5, 0x85, 0x8c, 0x86, 0x8b, 0x89, 0x8b, 0x82, 0x8c, + 0x86, 0x8c, 0x89, 0x8b, 0x89, 0x8b, 0x85, 0x8c, 0x85, 0x8c, 0x64, 0x44, + 0x80, 0x78, 0x28, 0xfb, 0x3a, 0xfb, 0x25, 0xfb, 0x87, 0x84, 0x7f, 0x58, + 0x3e, 0x08, 0x96, 0x8a, 0x05, 0xfb, 0x03, 0xf7, 0x71, 0x15, 0x9d, 0x8b, + 0x91, 0x8b, 0xdf, 0x8d, 0x08, 0xd5, 0x89, 0xa6, 0x8b, 0x9e, 0xa6, 0x05, + 0x4a, 0x8d, 0x7b, 0x8e, 0x8b, 0x98, 0x8b, 0x98, 0xbf, 0xf7, 0x79, 0x9d, + 0xcb, 0x80, 0x86, 0x89, 0x8a, 0x7d, 0x84, 0x52, 0x6c, 0x7e, 0x85, 0x51, + 0x73, 0x08, 0xa2, 0x7b, 0x05, 0xa2, 0x96, 0x96, 0x8f, 0xab, 0x97, 0x08, + 0x55, 0xfb, 0x7f, 0x05, 0x86, 0x78, 0x8b, 0x8a, 0x79, 0x8a, 0x6f, 0x88, + 0x88, 0x8b, 0x87, 0x8b, 0x08, 0x80, 0x89, 0x87, 0x8b, 0x73, 0x70, 0x05, + 0xf7, 0xb8, 0xfb, 0x77, 0x15, 0xa8, 0xa9, 0x93, 0x91, 0x99, 0x8b, 0x91, + 0x8b, 0x93, 0x8a, 0x94, 0x89, 0x08, 0xb9, 0x80, 0xc7, 0x80, 0x95, 0x8b, + 0x90, 0x8b, 0x8e, 0x8c, 0x93, 0x8e, 0x08, 0xcc, 0xdd, 0x7f, 0x9c, 0x05, + 0x5b, 0x57, 0x85, 0x87, 0x7c, 0x8b, 0x87, 0x8b, 0x87, 0x8c, 0x85, 0x8c, + 0x4f, 0x98, 0x81, 0x8d, 0x74, 0x8d, 0x08, 0x9b, 0x9a, 0xbe, 0xb6, 0x05, + 0x9b, 0x99, 0xa5, 0xa2, 0x8c, 0x8b, 0xaf, 0xa7, 0x92, 0x93, 0x98, 0xa2, + 0x98, 0xa1, 0x90, 0x9d, 0x8b, 0x9f, 0x08, 0xb2, 0x6f, 0xa5, 0x61, 0x45, + 0x4f, 0x5e, 0x58, 0x1e, 0x8b, 0x86, 0x8b, 0x88, 0x8d, 0x83, 0x08, 0xbc, + 0x85, 0x05, 0x85, 0xa0, 0x89, 0x93, 0x8b, 0x96, 0x08, 0xa7, 0x9f, 0x9d, + 0xab, 0xaa, 0xa1, 0x75, 0x6d, 0x1e, 0x8b, 0x64, 0x7a, 0x73, 0x3f, 0x49, + 0x3c, 0x47, 0x7c, 0x7c, 0x6c, 0x66, 0x08, 0x8e, 0x74, 0x05, 0x0e, 0xf7, + 0xef, 0xf8, 0x9e, 0x82, 0x15, 0x96, 0x85, 0x05, 0x92, 0x8e, 0x91, 0x8d, + 0x8d, 0x8c, 0x92, 0x8e, 0x8f, 0x8d, 0x8c, 0x8b, 0x08, 0x98, 0x8f, 0x05, + 0x8e, 0x8c, 0x90, 0x8d, 0x93, 0x8f, 0x86, 0x9a, 0x89, 0x91, 0x8b, 0x94, + 0x8b, 0x92, 0x8f, 0xa3, 0x8e, 0x97, 0x08, 0x8d, 0x95, 0x96, 0x8b, 0xa3, + 0x8b, 0xa5, 0xae, 0x05, 0x80, 0x8b, 0x86, 0x8b, 0x88, 0x8c, 0x08, 0x81, + 0x8b, 0x7d, 0x8a, 0x82, 0x8b, 0x93, 0xae, 0x05, 0x97, 0xbd, 0x8e, 0x9c, + 0x8d, 0x94, 0x90, 0x9e, 0x8f, 0x9e, 0x8f, 0x9e, 0x8c, 0x8e, 0x8f, 0x9c, + 0x8f, 0x9b, 0x08, 0x91, 0xa2, 0x05, 0x84, 0x89, 0x7f, 0x85, 0x7c, 0x84, + 0x08, 0x7e, 0x84, 0x05, 0x83, 0x82, 0x85, 0x85, 0x8a, 0x89, 0x7a, 0x7b, + 0x7b, 0x7a, 0x7a, 0x7a, 0x84, 0x85, 0x72, 0x6e, 0x6e, 0x66, 0x08, 0x5e, + 0x53, 0x05, 0x80, 0x7e, 0x85, 0x80, 0x82, 0x76, 0x92, 0x8c, 0x90, 0x8b, + 0x8e, 0x8b, 0x8d, 0x8b, 0x90, 0x8b, 0x93, 0x8a, 0x08, 0xdd, 0x8b, 0xa4, + 0x8b, 0x05, 0x73, 0x28, 0x05, 0x4d, 0xf7, 0x1a, 0x15, 0x96, 0x9b, 0x05, + 0xa9, 0xb0, 0x9f, 0xa4, 0xab, 0xae, 0x08, 0xb1, 0xb6, 0x89, 0x82, 0x05, + 0x87, 0x7c, 0x7e, 0x52, 0x79, 0x40, 0x08, 0x2d, 0x06, 0xfb, 0x89, 0xfb, + 0x15, 0x15, 0xa2, 0x8a, 0x96, 0x8b, 0x05, 0xb6, 0xdb, 0x92, 0x96, 0xda, + 0xf7, 0x17, 0x08, 0xee, 0xf7, 0x3b, 0x05, 0xcc, 0xf7, 0x02, 0x92, 0x97, + 0xbd, 0xd5, 0x85, 0x8c, 0x86, 0x8b, 0x89, 0x8b, 0x82, 0x8c, 0x86, 0x8c, + 0x89, 0x8b, 0x89, 0x8b, 0x85, 0x8c, 0x85, 0x8c, 0x64, 0x44, 0x80, 0x78, + 0x28, 0xfb, 0x3a, 0xfb, 0x25, 0xfb, 0x87, 0x84, 0x7f, 0x58, 0x3e, 0x08, + 0x96, 0x8a, 0x05, 0xfb, 0x0b, 0xf7, 0x71, 0x15, 0x9d, 0x8b, 0x91, 0x8b, + 0xdf, 0x8d, 0x08, 0xd5, 0x89, 0xa6, 0x8b, 0x9e, 0xa6, 0x05, 0x4a, 0x8d, + 0x7b, 0x8e, 0x8b, 0x98, 0x8b, 0x98, 0xbf, 0xf7, 0x79, 0x9d, 0xcb, 0x80, + 0x86, 0x89, 0x8a, 0x7d, 0x84, 0x52, 0x6c, 0x7e, 0x85, 0x51, 0x73, 0x08, + 0xa2, 0x7b, 0x05, 0xa2, 0x96, 0x96, 0x8f, 0xab, 0x97, 0x08, 0x55, 0xfb, + 0x7f, 0x05, 0x86, 0x78, 0x8b, 0x8a, 0x79, 0x8a, 0x6f, 0x88, 0x88, 0x8b, + 0x87, 0x8b, 0x08, 0x80, 0x89, 0x87, 0x8b, 0x73, 0x70, 0x05, 0x0e, 0xf7, + 0xef, 0xf8, 0xa8, 0x82, 0x15, 0x96, 0x85, 0x05, 0x92, 0x8e, 0x91, 0x8d, + 0x8d, 0x8c, 0x92, 0x8e, 0x8f, 0x8d, 0x8c, 0x8b, 0x08, 0x98, 0x8f, 0x05, + 0x8e, 0x8c, 0x90, 0x8d, 0x93, 0x8f, 0x86, 0x9a, 0x89, 0x91, 0x8b, 0x94, + 0x8b, 0x92, 0x8f, 0xa3, 0x8e, 0x97, 0x08, 0x8d, 0x95, 0x96, 0x8b, 0xa3, + 0x8b, 0xa5, 0xae, 0x05, 0x80, 0x8b, 0x86, 0x8b, 0x88, 0x8c, 0x08, 0x81, + 0x8b, 0x7d, 0x8a, 0x82, 0x8b, 0x93, 0xae, 0x05, 0x97, 0xbd, 0x8e, 0x9c, + 0x8d, 0x94, 0x90, 0x9e, 0x8f, 0x9e, 0x8f, 0x9e, 0x8c, 0x8e, 0x8f, 0x9c, + 0x8f, 0x9b, 0x08, 0x91, 0xa2, 0x05, 0x84, 0x89, 0x7f, 0x85, 0x7c, 0x84, + 0x08, 0x7e, 0x84, 0x05, 0x83, 0x82, 0x85, 0x85, 0x8a, 0x89, 0x7a, 0x7b, + 0x7b, 0x7a, 0x7a, 0x7a, 0x84, 0x85, 0x72, 0x6e, 0x6e, 0x66, 0x08, 0x5e, + 0x53, 0x05, 0x80, 0x7e, 0x85, 0x80, 0x82, 0x76, 0x92, 0x8c, 0x90, 0x8b, + 0x8e, 0x8b, 0x8d, 0x8b, 0x90, 0x8b, 0x93, 0x8a, 0x08, 0xdd, 0x8b, 0xa4, + 0x8b, 0x05, 0x73, 0x28, 0x05, 0x4d, 0xf7, 0x1a, 0x15, 0x96, 0x9b, 0x05, + 0xa9, 0xb0, 0x9f, 0xa4, 0xab, 0xae, 0x08, 0xb1, 0xb6, 0x89, 0x82, 0x05, + 0x87, 0x7c, 0x7e, 0x52, 0x79, 0x40, 0x08, 0x2d, 0x06, 0xfb, 0x89, 0xfb, + 0x15, 0x15, 0xa2, 0x8a, 0x96, 0x8b, 0x05, 0xb6, 0xdb, 0x92, 0x96, 0xda, + 0xf7, 0x17, 0x08, 0xee, 0xf7, 0x3b, 0x05, 0xcc, 0xf7, 0x02, 0x92, 0x97, + 0xbd, 0xd5, 0x85, 0x8c, 0x86, 0x8b, 0x89, 0x8b, 0x82, 0x8c, 0x86, 0x8c, + 0x89, 0x8b, 0x89, 0x8b, 0x85, 0x8c, 0x85, 0x8c, 0x64, 0x44, 0x80, 0x78, + 0x28, 0xfb, 0x3a, 0xfb, 0x25, 0xfb, 0x87, 0x84, 0x7f, 0x58, 0x3e, 0x08, + 0x96, 0x8a, 0x05, 0xfb, 0x26, 0xf7, 0x81, 0x15, 0xac, 0x7a, 0x9b, 0x87, + 0xab, 0x8b, 0xeb, 0x8b, 0xe5, 0xd7, 0x8b, 0xdd, 0x8b, 0x9d, 0x85, 0x99, + 0x7d, 0x96, 0x82, 0x93, 0x71, 0x95, 0x81, 0x8b, 0x08, 0x87, 0x8b, 0x90, + 0x8f, 0x05, 0x94, 0x91, 0x93, 0x90, 0xa3, 0x9a, 0x08, 0xa1, 0xa0, 0x93, + 0x99, 0x8b, 0x9f, 0x8b, 0xa6, 0x72, 0x9d, 0x67, 0x8b, 0x81, 0x8b, 0x82, + 0x8a, 0x7a, 0x87, 0x76, 0x7e, 0x76, 0x7d, 0x77, 0x7d, 0x08, 0x8b, 0x77, + 0x9a, 0x94, 0x05, 0xa6, 0x9b, 0x97, 0x8f, 0x9a, 0x8b, 0xa0, 0x8b, 0x9c, + 0x7d, 0x8b, 0x79, 0x8b, 0x68, 0x61, 0x6d, 0x31, 0x6c, 0x08, 0x86, 0x75, + 0x8f, 0x8c, 0x05, 0xb3, 0x97, 0x95, 0x8d, 0x99, 0x8b, 0x08, 0xb0, 0xa4, + 0x76, 0x6e, 0x57, 0x60, 0x60, 0x56, 0x1f, 0x72, 0x8b, 0x78, 0x90, 0x60, + 0x9e, 0x08, 0x6b, 0x68, 0x05, 0x0e, 0xf8, 0x3f, 0xf9, 0x1f, 0xf7, 0x67, + 0x15, 0x45, 0x6e, 0x60, 0x80, 0x5c, 0x8b, 0x60, 0x8b, 0x6f, 0x99, 0x76, + 0xa9, 0x75, 0xaa, 0x7f, 0xb3, 0x8b, 0xb5, 0x8b, 0xb8, 0x99, 0xbb, 0xa2, + 0xab, 0xa0, 0xa8, 0xaf, 0x9c, 0xb1, 0x8b, 0xc3, 0x8b, 0xb1, 0x69, 0x8b, + 0x59, 0x08, 0x8b, 0x85, 0x8b, 0x82, 0x8a, 0x83, 0x08, 0x92, 0x87, 0xc2, + 0xcc, 0x05, 0x7d, 0xb9, 0x58, 0xa6, 0x42, 0x8b, 0x47, 0x8b, 0x50, 0x76, + 0x68, 0x66, 0x66, 0x65, 0x75, 0x4c, 0x8b, 0x4a, 0x8b, 0x23, 0xc8, 0x46, + 0xe8, 0x8b, 0xbb, 0x8b, 0xd3, 0x9d, 0xcd, 0xa7, 0x08, 0x9d, 0xaf, 0x05, + 0xfb, 0x36, 0xf8, 0x5d, 0x15, 0xfb, 0x58, 0xfb, 0x31, 0xfb, 0x2d, 0xfb, + 0x53, 0xfb, 0x56, 0xf7, 0x2f, 0xfb, 0x30, 0xf7, 0x54, 0xf7, 0x53, 0xf7, + 0x30, 0xf7, 0x30, 0xf7, 0x53, 0xf7, 0x51, 0xfb, 0x2f, 0xf7, 0x32, 0xfb, + 0x4e, 0x1f, 0x8c, 0x61, 0x15, 0xf7, 0x35, 0xf7, 0x1c, 0xfb, 0x1f, 0xfb, + 0x3a, 0xfb, 0x3c, 0xfb, 0x1c, 0xfb, 0x1d, 0xfb, 0x3a, 0xfb, 0x3c, 0xfb, + 0x1a, 0xf7, 0x1d, 0xf7, 0x3f, 0x1f, 0x8b, 0xd4, 0xa7, 0xd4, 0xbd, 0xc2, + 0xc7, 0xce, 0xd8, 0xad, 0xe7, 0x8b, 0x08, 0x0e, 0xf8, 0x3f, 0xf8, 0x31, + 0xf7, 0xcb, 0x15, 0xa0, 0x87, 0x90, 0x8b, 0x9a, 0x8b, 0x08, 0xf7, 0x03, + 0xfb, 0x23, 0x05, 0x9e, 0x72, 0x98, 0x82, 0x9c, 0x8b, 0x8f, 0x8b, 0x90, + 0x8b, 0x91, 0x8c, 0x08, 0xd7, 0x93, 0x9b, 0x9f, 0x05, 0x4a, 0x8f, 0x89, + 0x8d, 0x4f, 0xd0, 0x08, 0x3c, 0xe8, 0x05, 0xd1, 0x9f, 0xb5, 0xb5, 0x8b, + 0xbc, 0x8b, 0xbe, 0x6c, 0xa2, 0x43, 0x8c, 0x08, 0xfb, 0x64, 0x8c, 0x72, + 0x6f, 0xd1, 0x87, 0x05, 0x83, 0xfb, 0x0c, 0x82, 0x24, 0x81, 0x35, 0x08, + 0x5d, 0x89, 0x78, 0x6d, 0x05, 0xc8, 0x8a, 0xad, 0x8a, 0xbc, 0x8a, 0x08, + 0xab, 0x8b, 0xa5, 0xa8, 0x47, 0x8f, 0x95, 0xf7, 0x20, 0x05, 0x99, 0xf7, + 0x3d, 0x15, 0x93, 0x8c, 0x8b, 0x8b, 0x98, 0x8b, 0x08, 0x99, 0x06, 0xd0, + 0xa8, 0x7a, 0x62, 0x59, 0x5b, 0x66, 0x4c, 0x1f, 0x83, 0x8b, 0x7e, 0x8c, + 0x7f, 0x8c, 0x08, 0x96, 0xf7, 0x22, 0x05, 0xc7, 0xf7, 0x50, 0x15, 0xfb, + 0x58, 0xfb, 0x30, 0xfb, 0x2d, 0xfb, 0x53, 0xfb, 0x56, 0xf7, 0x2e, 0xfb, + 0x30, 0xf7, 0x54, 0xf7, 0x54, 0xf7, 0x2f, 0xf7, 0x30, 0xf7, 0x53, 0xf7, + 0x51, 0xfb, 0x2f, 0xf7, 0x32, 0xfb, 0x4e, 0x1f, 0x8c, 0x61, 0x15, 0xf7, + 0x35, 0xf7, 0x1c, 0xfb, 0x1f, 0xfb, 0x3a, 0xfb, 0x3c, 0xfb, 0x1b, 0xfb, + 0x1d, 0xfb, 0x3b, 0xfb, 0x3b, 0xfb, 0x1a, 0xf7, 0x1d, 0xf7, 0x3f, 0x1f, + 0x8b, 0xd4, 0xa7, 0xd4, 0xbc, 0xc2, 0xc8, 0xce, 0xd7, 0xad, 0xe7, 0x8b, + 0x08, 0x0e, 0x2e, 0x0e, 0xf7, 0x63, 0xc2, 0xf7, 0xce, 0x15, 0x54, 0xf8, + 0x55, 0xfb, 0x7e, 0xc2, 0xf7, 0xb5, 0xfc, 0x8c, 0x07, 0x0e, 0xf7, 0x63, + 0xf7, 0xff, 0xf9, 0x66, 0x15, 0x5a, 0xfb, 0xba, 0xbc, 0xf7, 0xba, 0x06, + 0xfc, 0x40, 0x04, 0x5a, 0xfb, 0xba, 0xbc, 0xf7, 0xba, 0x06, 0x0e, 0xf7, + 0x27, 0xf8, 0x9a, 0xf7, 0x10, 0x15, 0x3c, 0x5c, 0x72, 0x7e, 0x81, 0x8b, + 0x83, 0x8b, 0x87, 0x93, 0x8b, 0x9b, 0x8b, 0xbe, 0xb0, 0xf7, 0x29, 0xb6, + 0xf7, 0x13, 0x7e, 0x84, 0x82, 0x86, 0x87, 0x89, 0x7f, 0x85, 0x7f, 0x85, + 0x7e, 0x85, 0x88, 0x8a, 0x85, 0x88, 0x80, 0x85, 0x08, 0x50, 0xfb, 0x85, + 0x05, 0x40, 0x57, 0x66, 0x76, 0x7f, 0x8b, 0x80, 0x8b, 0x83, 0x99, 0x8b, + 0x9e, 0x8b, 0xa2, 0x93, 0xb3, 0x9c, 0xcb, 0x96, 0xb3, 0x92, 0xa7, 0x8e, + 0x99, 0x94, 0xb0, 0x92, 0xa5, 0x8d, 0x92, 0x8e, 0x96, 0x8d, 0x94, 0x8b, + 0x92, 0x08, 0x93, 0x86, 0x90, 0x84, 0x1e, 0x80, 0x8b, 0x3e, 0x61, 0x48, + 0x61, 0x08, 0x84, 0x70, 0x05, 0xb5, 0xa0, 0x9e, 0x93, 0x97, 0x8b, 0x93, + 0x8b, 0x91, 0x83, 0x8b, 0x80, 0x8b, 0x81, 0x81, 0x5c, 0x74, 0x2c, 0x57, + 0xfb, 0x6d, 0x79, 0x53, 0x58, 0x24, 0x08, 0xef, 0xb5, 0x05, 0x91, 0xc0, + 0x95, 0xc8, 0x98, 0xbd, 0x9a, 0x90, 0xd4, 0xb7, 0xe7, 0xc6, 0x83, 0x6b, + 0x85, 0x67, 0x8b, 0x79, 0x8b, 0x7e, 0x93, 0x81, 0x95, 0x8b, 0x9f, 0x8b, + 0xea, 0xc3, 0xcf, 0xbe, 0x08, 0x92, 0xa9, 0x05, 0x0e, 0xf8, 0x4c, 0x14, + 0xf7, 0xcd, 0x15, 0x7e, 0x98, 0xf8, 0x1b, 0x9f, 0xf7, 0x36, 0x9d, 0x06, + 0x1e, 0x0a, 0x03, 0x96, 0x25, 0xff, 0x0c, 0x09, 0x8b, 0x0c, 0x0a, 0xbb, + 0x0a, 0xac, 0x91, 0x94, 0x90, 0x8e, 0x92, 0x90, 0x0c, 0x0c, 0xd9, 0x0b, + 0x0c, 0x0d, 0x8b, 0x0c, 0x0e, 0x00, 0x00, 0x00 +}; +const unsigned int fonts_URWChanceryL_MediItal_cff_len = 34436; diff --git a/rosapps/smartpdf/fitz/include/fitz-base.h b/rosapps/smartpdf/fitz/include/fitz-base.h new file mode 100644 index 00000000000..d6bfb8395d5 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz-base.h @@ -0,0 +1,22 @@ +#ifdef _FITZ_BASE_H_ +#error "fitz-base.h must only be included once" +#endif +#define _FITZ_BASE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "fitz/base_sysdep.h" +#include "fitz/base_cpudep.h" +#include "fitz/base_runtime.h" +#include "fitz/base_math.h" +#include "fitz/base_geom.h" +#include "fitz/base_hash.h" +#include "fitz/base_pixmap.h" + +#ifdef __cplusplus +} +#endif diff --git a/rosapps/smartpdf/fitz/include/fitz-draw.h b/rosapps/smartpdf/fitz/include/fitz-draw.h new file mode 100644 index 00000000000..2f23826adb4 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz-draw.h @@ -0,0 +1,27 @@ +/* + * Rasterizer + */ + +#ifdef _FITZ_DRAW_H_ +#error "fitz-draw.h must only be included once" +#endif +#define _FITZ_DRAW_H_ + +#ifndef _FITZ_BASE_H_ +#error "fitz-base.h must be included before fitz-draw.h" +#endif + +#ifndef _FITZ_WORLD_H_ +#error "fitz-world.h must be included before fitz-draw.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fitz/draw_path.h" +#include "fitz/draw_misc.h" + +#ifdef __cplusplus +} +#endif diff --git a/rosapps/smartpdf/fitz/include/fitz-stream.h b/rosapps/smartpdf/fitz/include/fitz-stream.h new file mode 100644 index 00000000000..cb30a22fa2f --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz-stream.h @@ -0,0 +1,26 @@ +/* + * Streams and dynamic objects + */ + +#ifdef _FITZ_STREAM_H_ +#error "fitz-stream.h must only be included once" +#endif +#define _FITZ_STREAM_H_ + +#ifndef _FITZ_BASE_H_ +#error "fitz-base.h must be included before fitz-stream.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fitz/stm_crypt.h" +#include "fitz/stm_object.h" +#include "fitz/stm_buffer.h" +#include "fitz/stm_filter.h" +#include "fitz/stm_stream.h" + +#ifdef __cplusplus +} +#endif diff --git a/rosapps/smartpdf/fitz/include/fitz-world.h b/rosapps/smartpdf/fitz/include/fitz-world.h new file mode 100644 index 00000000000..86604982c36 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz-world.h @@ -0,0 +1,28 @@ +/* + * The World -- fitz resources and trees + */ + +#ifdef _FITZ_WORLD_H_ +#error "fitz-world.h must only be included once" +#endif +#define _FITZ_WORLD_H_ + +#ifndef _FITZ_BASE_H_ +#error "fitz-base.h must be included before fitz-world.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fitz/wld_font.h" +#include "fitz/wld_color.h" +#include "fitz/wld_image.h" +#include "fitz/wld_shade.h" +#include "fitz/wld_tree.h" +#include "fitz/wld_path.h" +#include "fitz/wld_text.h" + +#ifdef __cplusplus +} +#endif diff --git a/rosapps/smartpdf/fitz/include/fitz.h b/rosapps/smartpdf/fitz/include/fitz.h new file mode 100644 index 00000000000..47e7eeb8170 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz.h @@ -0,0 +1,10 @@ +#ifdef _FITZ_H_ +#error "fitz.h must only be included once" +#endif +#define _FITZ_H_ + +#include "fitz-base.h" +#include "fitz-stream.h" +#include "fitz-world.h" +#include "fitz-draw.h" + diff --git a/rosapps/smartpdf/fitz/include/fitz/base_cpudep.h b/rosapps/smartpdf/fitz/include/fitz/base_cpudep.h new file mode 100644 index 00000000000..261c3c79a1d --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/base_cpudep.h @@ -0,0 +1,26 @@ +#if defined(ARCH_X86) || defined(ARCH_X86_64) +# define HAVE_CPUDEP +# define HAVE_MMX (1<<0) +# define HAVE_MMXEXT (1<<1) +# define HAVE_SSE (1<<2) +# define HAVE_SSE2 (1<<3) +# define HAVE_SSE3 (1<<4) +# define HAVE_3DNOW (1<<5) +# define HAVE_AMD64 (1<<6) + +#elif defined (ARCH_PPC) +# define HAVE_CPUDEP +# define HAVE_ALTIVEC (1<<7) + +#elif defined (ARCH_SPARC) +# define HAVE_CPUDEP +# define HAVE_VIS (1<<8) + +#endif + +/* call this before using fitz */ +extern void fz_cpudetect(); + +/* treat as constant! */ +extern unsigned fz_cpuflags; + diff --git a/rosapps/smartpdf/fitz/include/fitz/base_geom.h b/rosapps/smartpdf/fitz/include/fitz/base_geom.h new file mode 100644 index 00000000000..13290007d67 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/base_geom.h @@ -0,0 +1,65 @@ +typedef struct fz_matrix_s fz_matrix; +typedef struct fz_point_s fz_point; +typedef struct fz_rect_s fz_rect; +typedef struct fz_ipoint_s fz_ipoint; +typedef struct fz_irect_s fz_irect; + +extern fz_rect fz_emptyrect; +extern fz_rect fz_infiniterect; + +#define fz_isemptyrect(r) ((r).x0 == (r).x1) +#define fz_isinfiniterect(r) ((r).x0 > (r).x1) + +/* + / a b 0 \ + | c d 0 | + \ e f 1 / +*/ +struct fz_matrix_s +{ + float a, b, c, d, e, f; +}; + +struct fz_point_s +{ + float x, y; +}; + +struct fz_rect_s +{ + float x0, y0; + float x1, y1; +}; + +struct fz_ipoint_s +{ + int x, y; +}; + +struct fz_irect_s +{ + int x0, y0; + int x1, y1; +}; + +void fz_invert3x3(float *dst, float *m); + +fz_matrix fz_concat(fz_matrix one, fz_matrix two); +fz_matrix fz_identity(void); +fz_matrix fz_scale(float sx, float sy); +fz_matrix fz_rotate(float theta); +fz_matrix fz_translate(float tx, float ty); +fz_matrix fz_invertmatrix(fz_matrix m); +int fz_isrectilinear(fz_matrix m); +float fz_matrixexpansion(fz_matrix m); + +fz_rect fz_intersectrects(fz_rect a, fz_rect b); +fz_rect fz_mergerects(fz_rect a, fz_rect b); + +fz_irect fz_roundrect(fz_rect r); +fz_irect fz_intersectirects(fz_irect a, fz_irect b); +fz_irect fz_mergeirects(fz_irect a, fz_irect b); + +fz_point fz_transformpoint(fz_matrix m, fz_point p); +fz_rect fz_transformaabb(fz_matrix m, fz_rect r); + diff --git a/rosapps/smartpdf/fitz/include/fitz/base_hash.h b/rosapps/smartpdf/fitz/include/fitz/base_hash.h new file mode 100644 index 00000000000..5d2ec1b5a01 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/base_hash.h @@ -0,0 +1,20 @@ +/* + * Generic hash-table with fixed-length keys. + */ + +typedef struct fz_hashtable_s fz_hashtable; + +fz_error *fz_newhash(fz_hashtable **tablep, int initialsize, int keylen); +fz_error *fz_resizehash(fz_hashtable *table, int newsize); +void fz_debughash(fz_hashtable *table); +void fz_emptyhash(fz_hashtable *table); +void fz_drophash(fz_hashtable *table); + +void *fz_hashfind(fz_hashtable *table, void *key); +fz_error *fz_hashinsert(fz_hashtable *table, void *key, void *val); +fz_error *fz_hashremove(fz_hashtable *table, void *key); + +int fz_hashlen(fz_hashtable *table); +void *fz_hashgetkey(fz_hashtable *table, int idx); +void *fz_hashgetval(fz_hashtable *table, int idx); + diff --git a/rosapps/smartpdf/fitz/include/fitz/base_math.h b/rosapps/smartpdf/fitz/include/fitz/base_math.h new file mode 100644 index 00000000000..4dee81fc907 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/base_math.h @@ -0,0 +1,29 @@ +/* multiply 8-bit fixpoint (0..1) so that 0*0==0 and 255*255==255 */ +#define fz_mul255(a,b) (((a) * ((b) + 1)) >> 8) +#define fz_floor(x) floor(x) +#define fz_ceil(x) ceil(x) + +/* divide and floor towards -inf */ +static inline int fz_idiv(int a, int b) +{ + return a < 0 ? (a - b + 1) / b : a / b; +} + +/* from python */ +static inline void fz_idivmod(int x, int y, int *d, int *m) +{ + int xdivy = x / y; + int xmody = x - xdivy * y; + /* If the signs of x and y differ, and the remainder is non-0, + * C89 doesn't define whether xdivy is now the floor or the + * ceiling of the infinitely precise quotient. We want the floor, + * and we have it iff the remainder's sign matches y's. + */ + if (xmody && ((y ^ xmody) < 0)) { + xmody += y; + xdivy --; + } + *d = xdivy; + *m = xmody; +} + diff --git a/rosapps/smartpdf/fitz/include/fitz/base_pixmap.h b/rosapps/smartpdf/fitz/include/fitz/base_pixmap.h new file mode 100644 index 00000000000..9a0f2b43eaf --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/base_pixmap.h @@ -0,0 +1,26 @@ +/* TODO: move this into draw module */ +/* +pixmaps have n components per pixel. the first is always alpha. +premultiplied alpha when rendering, but non-premultiplied for colorspace +conversions and rescaling. +*/ + +typedef struct fz_pixmap_s fz_pixmap; +typedef unsigned char fz_sample; + +struct fz_pixmap_s +{ + int x, y, w, h, n; + fz_sample *samples; +}; + +fz_error *fz_newpixmapwithrect(fz_pixmap **mapp, fz_irect bbox, int n); +fz_error *fz_newpixmap(fz_pixmap **mapp, int x, int y, int w, int h, int n); +fz_error *fz_newpixmapcopy(fz_pixmap **pixp, fz_pixmap *old); + +void fz_debugpixmap(fz_pixmap *map); +void fz_clearpixmap(fz_pixmap *map); +void fz_droppixmap(fz_pixmap *map); + +fz_error *fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom); + diff --git a/rosapps/smartpdf/fitz/include/fitz/base_runtime.h b/rosapps/smartpdf/fitz/include/fitz/base_runtime.h new file mode 100644 index 00000000000..651eee8c383 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/base_runtime.h @@ -0,0 +1,79 @@ +#undef nil +#define nil ((void*)0) + +#undef offsetof +#define offsetof(s, m) (unsigned long)(&(((s*)0)->m)) + +#undef nelem +#define nelem(x) (sizeof(x)/sizeof((x)[0])) + +#undef ABS +#define ABS(x) ( (x) < 0 ? -(x) : (x) ) + +#undef MAX +#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) + +#undef MIN +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) + +#undef CLAMP +#define CLAMP(x,a,b) ( (x) > (b) ? (b) : ( (x) < (a) ? (a) : (x) ) ) + +#define MAX4(a,b,c,d) MAX(MAX(a,b), MAX(c,d)) +#define MIN4(a,b,c,d) MIN(MIN(a,b), MIN(c,d)) + +#define STRIDE(n, bcp) (((bpc) * (n) + 7) / 8) + +/* plan9 stuff for utf-8 and path munging */ +int chartorune(int *rune, char *str); +int runetochar(char *str, int *rune); +int runelen(long c); +int runenlen(int *r, int nrune); +int fullrune(char *str, int n); +char *cleanname(char *name); + +typedef struct fz_error_s fz_error; + +struct fz_error_s +{ + int refs; + char msg[184]; + char file[32]; + char func[32]; + int line; +}; + +#define fz_outofmem (&fz_koutofmem) +extern fz_error fz_koutofmem; + +#ifdef _WIN32 +#define fz_throw(...) fz_throw0(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) +#elif HAVE_C99 +#define fz_throw(...) fz_throw0(__func__, __FILE__, __LINE__, __VA_ARGS__) +#else +#define fz_throw fz_throw1 +#endif +fz_error *fz_throw0(const char *func, const char *file, int line, char *fmt, ...); +fz_error *fz_throw1(char *fmt, ...); + +void fz_warn(char *fmt, ...); +void fz_droperror(fz_error *eo); + +typedef struct fz_memorycontext_s fz_memorycontext; + +struct fz_memorycontext_s +{ + void * (*malloc)(fz_memorycontext *, int); + void * (*realloc)(fz_memorycontext *, void *, int); + void (*free)(fz_memorycontext *, void *); +}; + +fz_memorycontext *fz_currentmemorycontext(void); +void fz_setmemorycontext(fz_memorycontext *memorycontext); + +void *fz_malloc(int n); +void *fz_realloc(void *p, int n); +void fz_free(void *p); + +char *fz_strdup(char *s); + diff --git a/rosapps/smartpdf/fitz/include/fitz/base_sysdep.h b/rosapps/smartpdf/fitz/include/fitz/base_sysdep.h new file mode 100644 index 00000000000..1136536743e --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/base_sysdep.h @@ -0,0 +1,109 @@ +/* + * Include the basic standard libc headers. + */ + +#include +#include +#include +#include + +#include /* INT_MIN, MAX ... */ +#include /* DBL_EPSILON */ +#include + +#include +#include /* O_RDONLY & co */ + +/* not supposed to be here, but printf debugging sorta needs it */ +#include + +#ifdef _WIN32 +# define vsnprintf _vsnprintf +# include +#else +# include +#endif + +#ifdef HAVE_C99 + #define FZ_FLEX +#else + #define FZ_FLEX 1 + #define restrict + + #ifdef _MSC_VER + #ifndef NDEBUG + /*#define inline __inline*/ + /*#define inline*/ + #else + /*#define inline __inline*/ + #endif + #define FORCEINLINE __forceinline + #else + #ifdef __GNUC__ + #undef inline + #undef FORCEINLINE + #endif + #define inline __inline__ + #define FORCEINLINE __inline__ + #endif +#endif + +#ifndef va_copy +#define va_copy(a,b) (a) = (b) +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* + * Extras! Extras! Get them while they're hot! + */ + +#ifdef NEED_MATH +#ifdef __GNUC__ +#undef M_E +#undef M_LOG2E +#undef M_LOG10E +#undef M_LN2 +#undef M_LN10 +#undef M_PI +#undef M_PI_2 +#undef M_PI_4 +#undef M_1_PI +#undef M_2_PI +#undef M_1_SQRTPI +#undef M_2_SQRTPI +#undef M_SQRT2 +#undef M_SQRT_2 +#endif +#define M_E 2.71828182845904523536 +#define M_LOG2E 1.44269504088896340736 +#define M_LOG10E 0.434294481903251827651 +#define M_LN2 0.693147180559945309417 +#define M_LN10 2.30258509299404568402 +#define M_PI (float)3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#define M_PI_4 0.785398163397448309616 +#define M_1_PI 0.318309886183790671538 +#define M_2_PI 0.636619772367581343076 +#define M_1_SQRTPI 0.564189583547756286948 +#define M_2_SQRTPI 1.12837916709551257390 +#define M_SQRT2 1.41421356237309504880 +#define M_SQRT_2 0.707106781186547524401 +#endif + +#ifdef NEED_STRLCPY +extern int strlcpy(char *dst, const char *src, int n); +extern int strlcat(char *dst, const char *src, int n); +#endif + +#ifdef NEED_STRSEP +extern char *strsep(char **stringp, const char *delim); +#endif + +#ifdef NEED_GETOPT +extern int getopt(int nargc, char * const * nargv, const char *ostr); +extern int opterr, optind, optopt; +extern char *optarg; +#endif diff --git a/rosapps/smartpdf/fitz/include/fitz/draw_misc.h b/rosapps/smartpdf/fitz/include/fitz/draw_misc.h new file mode 100644 index 00000000000..cb78b57c9af --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/draw_misc.h @@ -0,0 +1,83 @@ +typedef struct fz_renderer_s fz_renderer; + +#define FZ_BYTE unsigned char + +#define FZ_PSRC \ + unsigned char *src, int srcw, int srch +#define FZ_PDST \ + unsigned char *dst0, int dstw +#define FZ_PCTM \ + int u0, int v0, int fa, int fb, int fc, int fd, int w0, int h + +/* + * Function pointers -- they can be replaced by cpu-optimized versions + */ + +extern void (*fz_duff_non)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_nimcn)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_nimon)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_4o4)(FZ_BYTE*,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_1i1c1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_4i1c4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_1i1o1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int); +extern void (*fz_duff_4i1o4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int); + +extern void (*fz_path_1c1)(FZ_BYTE*,int,int,FZ_BYTE*); +extern void (*fz_path_1o1)(FZ_BYTE*,int,int,FZ_BYTE*); +extern void (*fz_path_w3i1o4)(FZ_BYTE*,FZ_BYTE*,int,int,FZ_BYTE*); + +extern void (*fz_text_1c1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int); +extern void (*fz_text_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int); +extern void (*fz_text_w3i1o4)(FZ_BYTE*,FZ_BYTE*,int,FZ_BYTE*,int,int,int); + +extern void (*fz_img_ncn)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM); +extern void (*fz_img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM); +extern void (*fz_img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM); +extern void (*fz_img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM); +extern void (*fz_img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM); +extern void (*fz_img_w3i1o4)(FZ_BYTE*,FZ_PSRC,FZ_PDST,FZ_PCTM); + +extern void (*fz_decodetile)(fz_pixmap *pix, int skip, float *decode); +extern void (*fz_loadtile1)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad); +extern void (*fz_loadtile2)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad); +extern void (*fz_loadtile4)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad); +extern void (*fz_loadtile8)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad); + +extern void (*fz_srown)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom, int n); +extern void (*fz_srow1)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); +extern void (*fz_srow2)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); +extern void (*fz_srow4)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); +extern void (*fz_srow5)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); + +extern void (*fz_scoln)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom, int n); +extern void (*fz_scol1)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); +extern void (*fz_scol2)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); +extern void (*fz_scol4)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); +extern void (*fz_scol5)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom); + +#undef FZ_BYTE + +struct fz_renderer_s +{ + int maskonly; + fz_colorspace *model; + fz_glyphcache *cache; + fz_gel *gel; + fz_ael *ael; + + fz_irect clip; + fz_pixmap *dest; + fz_pixmap *over; + unsigned char rgb[3]; + int flag; +}; + +extern void fz_accelerate(); + +fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem); +void fz_droprenderer(fz_renderer *gc); +fz_error *fz_rendertree(fz_pixmap **out, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, fz_irect bbox, int white); +fz_error *fz_rendertreeover(fz_renderer *gc, fz_pixmap *dest, fz_tree *tree, fz_matrix ctm); + + diff --git a/rosapps/smartpdf/fitz/include/fitz/draw_path.h b/rosapps/smartpdf/fitz/include/fitz/draw_path.h new file mode 100644 index 00000000000..0be71e9e868 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/draw_path.h @@ -0,0 +1,46 @@ +typedef struct fz_edge_s fz_edge; +typedef struct fz_gel_s fz_gel; +typedef struct fz_ael_s fz_ael; + +struct fz_edge_s +{ + int x, e, h, y; + int adjup, adjdown; + int xmove; + int xdir, ydir; /* -1 or +1 */ +}; + +struct fz_gel_s +{ + int hs, vs; + int xmin, xmax; + int ymin, ymax; + int cap; + int len; + fz_edge *edges; +}; + +struct fz_ael_s +{ + int cap; + int len; + fz_edge **edges; +}; + +fz_error *fz_newgel(fz_gel **gelp); +fz_error *fz_insertgel(fz_gel *gel, float x0, float y0, float x1, float y1); +fz_irect fz_boundgel(fz_gel *gel); +void fz_resetgel(fz_gel *gel, int hs, int vs); +void fz_sortgel(fz_gel *gel); +void fz_dropgel(fz_gel *gel); + +fz_error *fz_newael(fz_ael **aelp); +void fz_dropael(fz_ael *ael); + +fz_error *fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, + fz_irect clip, fz_pixmap *pix, unsigned char *rgb, int over); + +fz_error *fz_fillpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness); +fz_error *fz_strokepath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness); +fz_error *fz_dashpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness); + diff --git a/rosapps/smartpdf/fitz/include/fitz/stm_buffer.h b/rosapps/smartpdf/fitz/include/fitz/stm_buffer.h new file mode 100644 index 00000000000..1a6f34ad57d --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/stm_buffer.h @@ -0,0 +1,41 @@ +/* + * Data buffers for streams and filters. + * + * bp is the pointer to the allocated memory + * rp is read-position (*in->rp++ to read data) + * wp is write-position (*out->wp++ to write data) + * ep is the sentinel + * + * Only the data between rp and wp is valid data. + * + * Writers set eof to true at the end. + * Readers look at eof. + * + * A buffer owns the memory it has allocated, unless ownsdata is false, + * in which case the creator of the buffer owns it. + */ + +typedef struct fz_buffer_s fz_buffer; + +#define FZ_BUFSIZE (8 * 1024) + +struct fz_buffer_s +{ + int refs; + int ownsdata; + unsigned char *bp; + unsigned char *rp; + unsigned char *wp; + unsigned char *ep; + int eof; +}; + +fz_error *fz_newbuffer(fz_buffer **bufp, int size); +fz_error *fz_newbufferwithmemory(fz_buffer **bufp, unsigned char *data, int size); + +fz_error *fz_rewindbuffer(fz_buffer *buf); +fz_error *fz_growbuffer(fz_buffer *buf); + +fz_buffer *fz_keepbuffer(fz_buffer *buf); +void fz_dropbuffer(fz_buffer *buf); + diff --git a/rosapps/smartpdf/fitz/include/fitz/stm_crypt.h b/rosapps/smartpdf/fitz/include/fitz/stm_crypt.h new file mode 100644 index 00000000000..4e0bc725572 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/stm_crypt.h @@ -0,0 +1,43 @@ +/* + * Basic crypto functions. + * Independent of the rest of fitz. + * For further encapsulation in filters, or not. + */ + +/* crc-32 checksum */ + +unsigned long fz_crc32(unsigned long crc, unsigned char *buf, int len); + +/* md5 digests */ + +typedef struct fz_md5_s fz_md5; + +struct fz_md5_s +{ + unsigned long state[4]; + unsigned long count[2]; + unsigned char buffer[64]; +}; + +void fz_md5init(fz_md5 *state); +void fz_md5update(fz_md5 *state, unsigned char *input, unsigned inlen); +void fz_md5final(fz_md5 *state, unsigned char digest[16]); + +/* arc4 crypto */ + +typedef struct fz_arc4_s fz_arc4; + +struct fz_arc4_s +{ + unsigned x; + unsigned y; + unsigned char state[256]; +}; + +void fz_arc4init(fz_arc4 *state, unsigned char *key, unsigned len); +unsigned char fz_arc4next(fz_arc4 *state); +void fz_arc4encrypt(fz_arc4 *state, unsigned char *dest, unsigned char *src, unsigned len); + +/* TODO: sha1 */ +/* TODO: aes */ + diff --git a/rosapps/smartpdf/fitz/include/fitz/stm_filter.h b/rosapps/smartpdf/fitz/include/fitz/stm_filter.h new file mode 100644 index 00000000000..f8902f98815 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/stm_filter.h @@ -0,0 +1,95 @@ +/* + * Data filters for encryption, compression and decompression. + * + * A filter has one method, process, that takes an input and an output buffer. + * + * It returns one of three statuses: + * ioneedin -- input buffer exhausted, please give me more data (wp-rp) + * ioneedout -- output buffer exhausted, please provide more space (ep-wp) + * iodone -- finished, please never call me again. ever! + * or... + * any other error object -- oops, something blew up. + * + * To make using the filter easier, three variables are updated: + * produced -- if we actually produced any new data + * consumed -- like above + * count -- number of bytes produced in total since the beginning + * + * Most filters take fz_obj as a way to specify parameters. + * In most cases, this is a dictionary that contains the same keys + * that the corresponding PDF filter would expect. + * + * The pipeline filter is special, and needs some care when chaining + * and unchaining new filters. + */ + +typedef struct fz_filter_s fz_filter; + +#define fz_ioneedin (&fz_kioneedin) +#define fz_ioneedout (&fz_kioneedout) +#define fz_iodone (&fz_kiodone) + +extern fz_error fz_kioneedin; +extern fz_error fz_kioneedout; +extern fz_error fz_kiodone; + +/* + * Evil looking macro to create an initialize a filter struct. + */ + +#define FZ_NEWFILTER(TYPE,VAR,NAME) \ + fz_error * fz_process ## NAME (fz_filter*,fz_buffer*,fz_buffer*); \ + void fz_drop ## NAME (fz_filter*); \ + TYPE *VAR; \ + *fp = fz_malloc(sizeof(TYPE)); \ + if (!*fp) return fz_outofmem; \ + (*fp)->refs = 1; \ + (*fp)->process = fz_process ## NAME ; \ + (*fp)->drop = fz_drop ## NAME ; \ + (*fp)->consumed = 0; \ + (*fp)->produced = 0; \ + (*fp)->count = 0; \ + VAR = (TYPE*) *fp + +struct fz_filter_s +{ + int refs; + fz_error* (*process)(fz_filter *filter, fz_buffer *in, fz_buffer *out); + void (*drop)(fz_filter *filter); + int consumed; + int produced; + int count; +}; + +fz_error *fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out); +fz_filter *fz_keepfilter(fz_filter *f); +void fz_dropfilter(fz_filter *f); + +fz_error *fz_newpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail); +fz_error *fz_chainpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail, fz_buffer *buf); +void fz_unchainpipeline(fz_filter *pipe, fz_filter **oldfp, fz_buffer **oldbp); + +/* stop and reverse! special case needed for postscript only */ +void fz_pushbackahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out, int n); + +fz_error *fz_newnullfilter(fz_filter **fp, int len); +fz_error *fz_newarc4filter(fz_filter **fp, unsigned char *key, unsigned keylen); +fz_error *fz_newa85d(fz_filter **filterp, fz_obj *param); +fz_error *fz_newa85e(fz_filter **filterp, fz_obj *param); +fz_error *fz_newahxd(fz_filter **filterp, fz_obj *param); +fz_error *fz_newahxe(fz_filter **filterp, fz_obj *param); +fz_error *fz_newrld(fz_filter **filterp, fz_obj *param); +fz_error *fz_newrle(fz_filter **filterp, fz_obj *param); +fz_error *fz_newdctd(fz_filter **filterp, fz_obj *param); +fz_error *fz_newdcte(fz_filter **filterp, fz_obj *param); +fz_error *fz_newfaxd(fz_filter **filterp, fz_obj *param); +fz_error *fz_newfaxe(fz_filter **filterp, fz_obj *param); +fz_error *fz_newflated(fz_filter **filterp, fz_obj *param); +fz_error *fz_newflatee(fz_filter **filterp, fz_obj *param); +fz_error *fz_newlzwd(fz_filter **filterp, fz_obj *param); +fz_error *fz_newlzwe(fz_filter **filterp, fz_obj *param); +fz_error *fz_newpredictd(fz_filter **filterp, fz_obj *param); +fz_error *fz_newpredicte(fz_filter **filterp, fz_obj *param); +fz_error *fz_newjbig2d(fz_filter **filterp, fz_obj *param); +fz_error *fz_newjpxd(fz_filter **filterp, fz_obj *param); + diff --git a/rosapps/smartpdf/fitz/include/fitz/stm_object.h b/rosapps/smartpdf/fitz/include/fitz/stm_object.h new file mode 100644 index 00000000000..fe9c12e5f25 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/stm_object.h @@ -0,0 +1,132 @@ +/* + * Dynamic objects. + * The same type of objects as found in PDF and PostScript. + * Used by the filter library and the mupdf parser. + */ + +typedef struct fz_obj_s fz_obj; +typedef struct fz_keyval_s fz_keyval; + +typedef enum fz_objkind_e +{ + FZ_NULL, + FZ_BOOL, + FZ_INT, + FZ_REAL, + FZ_STRING, + FZ_NAME, + FZ_ARRAY, + FZ_DICT, + FZ_INDIRECT, + FZ_POINTER +} fz_objkind; + +struct fz_keyval_s +{ + fz_obj *k; + fz_obj *v; +}; + +struct fz_obj_s +{ + unsigned short refs; + char kind; /* fz_objkind takes 4 bytes :( */ + union + { + int b; + int i; + float f; + struct { + unsigned short len; + char buf[1]; + } s; + char n[1]; + struct { + int len; + int cap; + fz_obj **items; + } a; + struct { + char sorted; + int len; + int cap; + fz_keyval *items; + } d; + struct { + int oid; + int gid; + } r; + void *p; + } u; +}; + +fz_error *fz_newnull(fz_obj **op); +fz_error *fz_newbool(fz_obj **op, int b); +fz_error *fz_newint(fz_obj **op, int i); +fz_error *fz_newreal(fz_obj **op, float f); +fz_error *fz_newname(fz_obj **op, char *str); +fz_error *fz_newstring(fz_obj **op, char *str, int len); +fz_error *fz_newindirect(fz_obj **op, int oid, int gid); +fz_error *fz_newpointer(fz_obj **op, void *p); + +fz_error *fz_newarray(fz_obj **op, int initialcap); +fz_error *fz_newdict(fz_obj **op, int initialcap); +fz_error *fz_copyarray(fz_obj **op, fz_obj *array); +fz_error *fz_copydict(fz_obj **op, fz_obj *dict); +fz_error *fz_deepcopyarray(fz_obj **op, fz_obj *array); +fz_error *fz_deepcopydict(fz_obj **op, fz_obj *dict); + +fz_obj *fz_keepobj(fz_obj *obj); +void fz_dropobj(fz_obj *obj); + +/* type queries */ +int fz_isnull(fz_obj *obj); +int fz_isbool(fz_obj *obj); +int fz_isint(fz_obj *obj); +int fz_isreal(fz_obj *obj); +int fz_isname(fz_obj *obj); +int fz_isstring(fz_obj *obj); +int fz_isarray(fz_obj *obj); +int fz_isdict(fz_obj *obj); +int fz_isindirect(fz_obj *obj); +int fz_ispointer(fz_obj *obj); + +int fz_objcmp(fz_obj *a, fz_obj *b); + +/* silent failure, no error reporting */ +int fz_tobool(fz_obj *obj); +int fz_toint(fz_obj *obj); +float fz_toreal(fz_obj *obj); +char *fz_toname(fz_obj *obj); +char *fz_tostrbuf(fz_obj *obj); +int fz_tostrlen(fz_obj *obj); +int fz_tonum(fz_obj *obj); +int fz_togen(fz_obj *obj); +void *fz_topointer(fz_obj *obj); + +fz_error *fz_newnamefromstring(fz_obj **op, fz_obj *str); + +int fz_arraylen(fz_obj *array); +fz_obj *fz_arrayget(fz_obj *array, int i); +fz_error *fz_arrayput(fz_obj *array, int i, fz_obj *obj); +fz_error *fz_arraypush(fz_obj *array, fz_obj *obj); + +int fz_dictlen(fz_obj *dict); +fz_obj *fz_dictgetkey(fz_obj *dict, int idx); +fz_obj *fz_dictgetval(fz_obj *dict, int idx); +fz_obj *fz_dictget(fz_obj *dict, fz_obj *key); +fz_obj *fz_dictgets(fz_obj *dict, char *key); +fz_obj *fz_dictgetsa(fz_obj *dict, char *key, char *abbrev); +fz_error *fz_dictput(fz_obj *dict, fz_obj *key, fz_obj *val); +fz_error *fz_dictputs(fz_obj *dict, char *key, fz_obj *val); +fz_error *fz_dictdel(fz_obj *dict, fz_obj *key); +fz_error *fz_dictdels(fz_obj *dict, char *key); +void fz_sortdict(fz_obj *dict); + +int fz_sprintobj(char *s, int n, fz_obj *obj, int tight); +void fz_debugobj(fz_obj *obj); + +fz_error *fz_parseobj(fz_obj **objp, char *s); +fz_error *fz_packobj(fz_obj **objp, char *fmt, ...); +fz_error *fz_unpackobj(fz_obj *obj, char *fmt, ...); + diff --git a/rosapps/smartpdf/fitz/include/fitz/stm_stream.h b/rosapps/smartpdf/fitz/include/fitz/stm_stream.h new file mode 100644 index 00000000000..66e9d320761 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/stm_stream.h @@ -0,0 +1,103 @@ +/* + * Stream API for Fitz. + * Read and write data to and from files, memory buffers and filters. + */ + +typedef struct fz_stream_s fz_stream; + +enum { FZ_SFILE, FZ_SBUFFER, FZ_SFILTER }; +enum { FZ_SREAD, FZ_SWRITE }; + +struct fz_stream_s +{ + int refs; + int kind; + int mode; + int dead; + fz_buffer *buffer; + fz_filter *filter; + fz_stream *chain; + fz_error *error; + int file; +}; + +/* + * Various stream creation functions. + */ + +/* open() and creat() & co */ +fz_error *fz_openrfile(fz_stream **stmp, char *filename); +fz_error *fz_openwfile(fz_stream **stmp, char *filename); +fz_error *fz_openafile(fz_stream **stmp, char *filename); + +/* write to memory buffers! */ +fz_error *fz_openrmemory(fz_stream **stmp, char *buf, int len); +fz_error *fz_openrbuffer(fz_stream **stmp, fz_buffer *buf); +fz_error *fz_openwbuffer(fz_stream **stmp, fz_buffer *buf); + +/* almost like fork() exec() pipe() */ +fz_error *fz_openrfilter(fz_stream **stmp, fz_filter *flt, fz_stream *chain); +fz_error *fz_openwfilter(fz_stream **stmp, fz_filter *flt, fz_stream *chain); + +/* + * Functions that are common to both input and output streams. + */ + +fz_error *fz_ioerror(fz_stream *stm); + +fz_stream *fz_keepstream(fz_stream *stm); +void fz_dropstream(fz_stream *stm); + +int fz_tell(fz_stream *stm); +int fz_seek(fz_stream *stm, int offset, int whence); + +/* + * Input stream functions. + * Return EOF (-1) on errors. + */ + +int fz_rtell(fz_stream *stm); +int fz_rseek(fz_stream *stm, int offset, int whence); + +int fz_makedata(fz_stream *stm); +int fz_read(fz_stream *stm, unsigned char *buf, int len); + +int fz_readall(fz_buffer **bufp, fz_stream *stm); +int fz_readline(fz_stream *stm, char *buf, int max); + +int fz_readbytex(fz_stream *stm); +int fz_peekbytex(fz_stream *stm); + +#ifdef DEBUG +#define fz_readbyte fz_readbytex +#define fz_peekbyte fz_peekbytex +#else + +#define FZ_READBYTE(XXX) { \ + fz_buffer *buf = stm->buffer; \ + if (buf->rp == buf->wp) \ + if (fz_makedata(stm) < 0) \ + return EOF; \ + return buf->rp < buf->wp ? XXX : EOF ; \ +} + +static inline int fz_readbyte(fz_stream *stm) FZ_READBYTE(*buf->rp++) +static inline int fz_peekbyte(fz_stream *stm) FZ_READBYTE(*buf->rp) + +#endif + +/* + * Output stream functions. + * Return N or 0 on success, -1 on failure. + */ + +int fz_wtell(fz_stream *stm); +int fz_wseek(fz_stream *stm, int offset, int whence); + +int fz_write(fz_stream *stm, unsigned char *buf, int n); +int fz_flush(fz_stream *stm); + +int fz_printstr(fz_stream *stm, char *s); +int fz_printobj(fz_stream *stm, fz_obj *obj, int tight); +int fz_print(fz_stream *stm, char *fmt, ...); + diff --git a/rosapps/smartpdf/fitz/include/fitz/wld_color.h b/rosapps/smartpdf/fitz/include/fitz/wld_color.h new file mode 100644 index 00000000000..f6fae48c687 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/wld_color.h @@ -0,0 +1,40 @@ +typedef struct fz_colorspace_s fz_colorspace; +typedef struct fz_colorcube_s fz_colorcube; +typedef struct fz_colorcube1_s fz_colorcube1; +typedef struct fz_colorcube3_s fz_colorcube3; +typedef struct fz_colorcube4_s fz_colorcube4; + +enum { FZ_MAXCOLORS = 32 }; + +struct fz_colorspace_s +{ + int refs; + char name[16]; + int n; + void (*convpixmap)(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp); + void (*convcolor)(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv); + void (*toxyz)(fz_colorspace *, float *src, float *xyz); + void (*fromxyz)(fz_colorspace *, float *xyz, float *dst); + void (*drop)(fz_colorspace *); +}; + +struct fz_colorcube1_s { unsigned char v[17]; }; +struct fz_colorcube3_s { unsigned char v[17][17][17]; }; +struct fz_colorcube4_s { unsigned char v[17][17][17][17]; }; + +struct fz_colorcube_s +{ + fz_colorspace *src; + fz_colorspace *dst; + void **subcube; /* dst->n * colorcube(src->n) */ +}; + +fz_colorspace *fz_keepcolorspace(fz_colorspace *cs); +void fz_dropcolorspace(fz_colorspace *cs); + +void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv); +void fz_convertpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv); + +void fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv); +void fz_stdconvpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv); + diff --git a/rosapps/smartpdf/fitz/include/fitz/wld_font.h b/rosapps/smartpdf/fitz/include/fitz/wld_font.h new file mode 100644 index 00000000000..27217c6cee0 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/wld_font.h @@ -0,0 +1,68 @@ +typedef struct fz_font_s fz_font; +typedef struct fz_hmtx_s fz_hmtx; +typedef struct fz_vmtx_s fz_vmtx; +typedef struct fz_glyph_s fz_glyph; +typedef struct fz_glyphcache_s fz_glyphcache; + +struct fz_hmtx_s +{ + unsigned short lo; + unsigned short hi; + int w; /* type3 fonts can be big! */ +}; + +struct fz_vmtx_s +{ + unsigned short lo; + unsigned short hi; + short x; + short y; + short w; +}; + +struct fz_font_s +{ + int refs; + char name[32]; + + fz_error* (*render)(fz_glyph*, fz_font*, int, fz_matrix); + void (*drop)(fz_font *); + + int wmode; + fz_irect bbox; + + int nhmtx, hmtxcap; + fz_hmtx dhmtx; + fz_hmtx *hmtx; + + int nvmtx, vmtxcap; + fz_vmtx dvmtx; + fz_vmtx *vmtx; +}; + +struct fz_glyph_s +{ + int x, y, w, h; + unsigned char *samples; +}; + +void fz_initfont(fz_font *font, char *name); +fz_font *fz_keepfont(fz_font *font); +void fz_dropfont(fz_font *font); +void fz_debugfont(fz_font *font); +void fz_setfontwmode(fz_font *font, int wmode); +void fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax); +void fz_setdefaulthmtx(fz_font *font, int w); +void fz_setdefaultvmtx(fz_font *font, int y, int w); +fz_error *fz_addhmtx(fz_font *font, int lo, int hi, int w); +fz_error *fz_addvmtx(fz_font *font, int lo, int hi, int x, int y, int w); +fz_error *fz_endhmtx(fz_font *font); +fz_error *fz_endvmtx(fz_font *font); +fz_hmtx fz_gethmtx(fz_font *font, int cid); +fz_vmtx fz_getvmtx(fz_font *font, int cid); + +fz_error *fz_newglyphcache(fz_glyphcache **arenap, int slots, int size); +fz_error *fz_renderglyph(fz_glyphcache*, fz_glyph*, fz_font*, int, fz_matrix); +void fz_debugglyphcache(fz_glyphcache *); +void fz_dropglyphcache(fz_glyphcache *); + diff --git a/rosapps/smartpdf/fitz/include/fitz/wld_image.h b/rosapps/smartpdf/fitz/include/fitz/wld_image.h new file mode 100644 index 00000000000..89d180ba508 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/wld_image.h @@ -0,0 +1,16 @@ +typedef struct fz_image_s fz_image; + +/* loadtile will fill a pixmap with the pixel samples. non-premultiplied alpha. */ + +struct fz_image_s +{ + int refs; + fz_error* (*loadtile)(fz_image*,fz_pixmap*); + void (*drop)(fz_image*); + fz_colorspace *cs; + int w, h, n, a; +}; + +fz_image *fz_keepimage(fz_image *img); +void fz_dropimage(fz_image *img); + diff --git a/rosapps/smartpdf/fitz/include/fitz/wld_path.h b/rosapps/smartpdf/fitz/include/fitz/wld_path.h new file mode 100644 index 00000000000..6a7c55b776d --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/wld_path.h @@ -0,0 +1,83 @@ +/* + * Vector path nodes in the display tree. + * They can be stroked and dashed, or be filled. + * They have a fill rule (nonzero or evenodd). + * + * When rendering, they are flattened, stroked and dashed straight + * into the Global Edge List. + * + * TODO flatten, stroke and dash into another path + * TODO set operations on flat paths (union, intersect, difference) + * TODO decide whether dashing should be part of the tree and renderer, + * or if it is something the client has to do (with a util function). + */ + +typedef struct fz_stroke_s fz_stroke; +typedef struct fz_dash_s fz_dash; +typedef union fz_pathel_s fz_pathel; + +typedef enum fz_pathkind_e +{ + FZ_STROKE, + FZ_FILL, + FZ_EOFILL +} fz_pathkind; + +typedef enum fz_pathelkind_e +{ + FZ_MOVETO, + FZ_LINETO, + FZ_CURVETO, + FZ_CLOSEPATH +} fz_pathelkind; + +struct fz_stroke_s +{ + int linecap; + int linejoin; + float linewidth; + float miterlimit; +}; + +struct fz_dash_s +{ + int len; + float phase; + float array[FZ_FLEX]; +}; + +union fz_pathel_s +{ + fz_pathelkind k; + float v; +}; + +struct fz_pathnode_s +{ + fz_node super; + fz_pathkind paint; + fz_dash *dash; + int linecap; + int linejoin; + float linewidth; + float miterlimit; + int len, cap; + fz_pathel *els; +}; + +fz_error *fz_newpathnode(fz_pathnode **pathp); +fz_error *fz_clonepathnode(fz_pathnode **pathp, fz_pathnode *oldpath); +fz_error *fz_moveto(fz_pathnode*, float x, float y); +fz_error *fz_lineto(fz_pathnode*, float x, float y); +fz_error *fz_curveto(fz_pathnode*, float, float, float, float, float, float); +fz_error *fz_curvetov(fz_pathnode*, float, float, float, float); +fz_error *fz_curvetoy(fz_pathnode*, float, float, float, float); +fz_error *fz_closepath(fz_pathnode*); +fz_error *fz_endpath(fz_pathnode*, fz_pathkind paint, fz_stroke *stroke, fz_dash *dash); + +fz_rect fz_boundpathnode(fz_pathnode *node, fz_matrix ctm); +void fz_debugpathnode(fz_pathnode *node); + +fz_error *fz_newdash(fz_dash **dashp, float phase, int len, float *array); +void fz_dropdash(fz_dash *dash); + diff --git a/rosapps/smartpdf/fitz/include/fitz/wld_shade.h b/rosapps/smartpdf/fitz/include/fitz/wld_shade.h new file mode 100644 index 00000000000..1b7c81c590d --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/wld_shade.h @@ -0,0 +1,29 @@ +typedef struct fz_shade_s fz_shade; + +struct fz_shade_s +{ + int refs; + + fz_rect bbox; /* can be fz_infiniterect */ + fz_colorspace *cs; + + /* used by build.c -- not used in drawshade.c */ + fz_matrix matrix; /* matrix from pattern dict */ + int usebackground; /* background color for fills but not 'sh' */ + float background[FZ_MAXCOLORS]; + + int usefunction; + float function[256][FZ_MAXCOLORS]; + + int meshlen; + int meshcap; + float *mesh; /* [x y t] or [x y c1 ... cn] * 3 * meshlen */ +}; + + +fz_shade *fz_keepshade(fz_shade *shade); +void fz_dropshade(fz_shade *shade); + +fz_rect fz_boundshade(fz_shade *shade, fz_matrix ctm); +fz_error *fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp); + diff --git a/rosapps/smartpdf/fitz/include/fitz/wld_text.h b/rosapps/smartpdf/fitz/include/fitz/wld_text.h new file mode 100644 index 00000000000..619aae8358c --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/wld_text.h @@ -0,0 +1,44 @@ +/* + * Fitz display tree text node. + * + * The text node is an optimization to reference glyphs in a font resource + * and specifying an individual transform matrix for each one. + * + * The trm field contains the a, b, c and d coefficients. + * The e and f coefficients come from the individual elements, + * together they form the transform matrix for the glyph. + * + * Glyphs are referenced by glyph ID. + * The Unicode text equivalent is kept in a separate array + * with indexes into the glyph array. + * + +TODO the unicode textels + +struct fz_textgid_s { float e, f; int gid; }; +struct fz_textucs_s { int idx; int ucs; }; + + */ + +typedef struct fz_textel_s fz_textel; + +struct fz_textel_s +{ + float x, y; + int cid; +}; + +struct fz_textnode_s +{ + fz_node super; + fz_font *font; + fz_matrix trm; + int len, cap; + fz_textel *els; +}; + +fz_error *fz_newtextnode(fz_textnode **textp, fz_font *face); +fz_error *fz_clonetextnode(fz_textnode **textp, fz_textnode *oldtext); +fz_error *fz_addtext(fz_textnode *text, int g, float x, float y); +fz_error *fz_endtext(fz_textnode *text); + diff --git a/rosapps/smartpdf/fitz/include/fitz/wld_tree.h b/rosapps/smartpdf/fitz/include/fitz/wld_tree.h new file mode 100644 index 00000000000..324b8098c5d --- /dev/null +++ b/rosapps/smartpdf/fitz/include/fitz/wld_tree.h @@ -0,0 +1,183 @@ +/* + * The display tree is at the center of attention in Fitz. + * The tree and most of its minor nodes. + * Paths and text nodes are found elsewhere. + */ + +typedef struct fz_tree_s fz_tree; +typedef struct fz_node_s fz_node; + +struct fz_tree_s +{ + int refs; + fz_node *root; + fz_node *head; +}; + +/* tree operations */ +fz_error *fz_newtree(fz_tree **treep); +fz_tree *fz_keeptree(fz_tree *tree); +void fz_droptree(fz_tree *tree); + +fz_rect fz_boundtree(fz_tree *tree, fz_matrix ctm); +void fz_debugtree(fz_tree *tree); +void fz_insertnodefirst(fz_node *parent, fz_node *child); +void fz_insertnodelast(fz_node *parent, fz_node *child); +void fz_insertnodeafter(fz_node *prev, fz_node *child); +void fz_removenode(fz_node *child); + +fz_error *fz_optimizetree(fz_tree *tree); + +/* node types */ + +typedef struct fz_transformnode_s fz_transformnode; +typedef struct fz_overnode_s fz_overnode; +typedef struct fz_masknode_s fz_masknode; +typedef struct fz_blendnode_s fz_blendnode; +typedef struct fz_pathnode_s fz_pathnode; +typedef struct fz_textnode_s fz_textnode; +typedef struct fz_solidnode_s fz_solidnode; +typedef struct fz_imagenode_s fz_imagenode; +typedef struct fz_shadenode_s fz_shadenode; +typedef struct fz_linknode_s fz_linknode; +typedef struct fz_metanode_s fz_metanode; + +typedef enum fz_nodekind_e +{ + FZ_NTRANSFORM, + FZ_NOVER, + FZ_NMASK, + FZ_NBLEND, + FZ_NPATH, + FZ_NTEXT, + FZ_NCOLOR, + FZ_NIMAGE, + FZ_NSHADE, + FZ_NLINK, + FZ_NMETA +} fz_nodekind; + +typedef enum fz_blendkind_e +{ + /* PDF 1.4 -- standard separable */ + FZ_BNORMAL, + FZ_BMULTIPLY, + FZ_BSCREEN, + FZ_BOVERLAY, + FZ_BDARKEN, + FZ_BLIGHTEN, + FZ_BCOLORDODGE, + FZ_BCOLORBURN, + FZ_BHARDLIGHT, + FZ_BSOFTLIGHT, + FZ_BDIFFERENCE, + FZ_BEXCLUSION, + + /* PDF 1.4 -- standard non-separable */ + FZ_BHUE, + FZ_BSATURATION, + FZ_BCOLOR, + FZ_BLUMINOSITY, + + FZ_BOVERPRINT, + FZ_BRASTEROP +} fz_blendkind; + +struct fz_node_s +{ + fz_nodekind kind; + fz_node *parent; + fz_node *first; + fz_node *last; + fz_node *next; +}; + +struct fz_transformnode_s +{ + fz_node super; + fz_matrix m; +}; + +struct fz_overnode_s +{ + fz_node super; +}; + +struct fz_masknode_s +{ + fz_node super; +}; + +struct fz_blendnode_s +{ + fz_node super; + fz_colorspace *cs; + fz_blendkind mode; + int isolated; + int knockout; +}; + +struct fz_solidnode_s +{ + fz_node super; + fz_colorspace *cs; + int n; + float samples[FZ_FLEX]; +}; + +struct fz_linknode_s +{ + fz_node super; + fz_tree *tree; +}; + +struct fz_metanode_s +{ + fz_node super; + char *name; + void *dict; +}; + +struct fz_imagenode_s +{ + fz_node super; + fz_image *image; +}; + +struct fz_shadenode_s +{ + fz_node super; + fz_shade *shade; +}; + +/* common to all nodes */ +void fz_initnode(fz_node *node, fz_nodekind kind); +fz_rect fz_boundnode(fz_node *node, fz_matrix ctm); +void fz_dropnode(fz_node *node); + +/* branch nodes */ +fz_error *fz_newmetanode(fz_node **nodep, char *name, void *dict); +fz_error *fz_newovernode(fz_node **nodep); +fz_error *fz_newmasknode(fz_node **nodep); +fz_error *fz_newblendnode(fz_node **nodep, fz_colorspace *cs, fz_blendkind b, int k, int i); +fz_error *fz_newtransformnode(fz_node **nodep, fz_matrix m); + +int fz_istransformnode(fz_node *node); +int fz_isovernode(fz_node *node); +int fz_ismasknode(fz_node *node); +int fz_isblendnode(fz_node *node); +int fz_ismetanode(fz_node *node); + +/* leaf nodes */ +fz_error *fz_newlinknode(fz_node **nodep, fz_tree *subtree); +fz_error *fz_newsolidnode(fz_node **nodep, fz_colorspace *cs, int n, float *v); +fz_error *fz_newimagenode(fz_node **nodep, fz_image *image); +fz_error *fz_newshadenode(fz_node **nodep, fz_shade *shade); + +int fz_islinknode(fz_node *node); +int fz_issolidnode(fz_node *node); +int fz_ispathnode(fz_node *node); +int fz_istextnode(fz_node *node); +int fz_isimagenode(fz_node *node); +int fz_isshadenode(fz_node *node); + diff --git a/rosapps/smartpdf/fitz/include/mupdf.h b/rosapps/smartpdf/fitz/include/mupdf.h new file mode 100644 index 00000000000..dc7b0e61a42 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf.h @@ -0,0 +1,39 @@ +#ifdef _MUPDF_H_ +#error "mupdf.h must only be included once" +#endif +#define _MUPDF_H_ + +#ifndef _FITZ_BASE_H_ +#error "fitz-base.h must be included before mupdf.h" +#endif + +#ifndef _FITZ_STREAM_H_ +#error "fitz-stream.h must be included before mupdf.h" +#endif + +#ifndef _FITZ_WORLD_H_ +#error "fitz-world.h must be included before mupdf.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void pdf_logxref(char *fmt, ...); +void pdf_logrsrc(char *fmt, ...); +void pdf_logfont(char *fmt, ...); +void pdf_logimage(char *fmt, ...); +void pdf_logshade(char *fmt, ...); +void pdf_logpage(char *fmt, ...); + +#include "mupdf/syntax.h" +#include "mupdf/xref.h" +#include "mupdf/rsrc.h" +#include "mupdf/content.h" +#include "mupdf/annot.h" +#include "mupdf/page.h" + +#ifdef __cplusplus +} +#endif + diff --git a/rosapps/smartpdf/fitz/include/mupdf/annot.h b/rosapps/smartpdf/fitz/include/mupdf/annot.h new file mode 100644 index 00000000000..a44a79394e8 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf/annot.h @@ -0,0 +1,69 @@ +/* + * Interactive features + */ + +typedef struct pdf_link_s pdf_link; +typedef struct pdf_comment_s pdf_comment; +typedef struct pdf_widget_s pdf_widget; +typedef struct pdf_outline_s pdf_outline; + +typedef enum pdf_linkkind_e +{ + PDF_LGOTO, + PDF_LURI, + PDF_LUNKNOWN +} pdf_linkkind; + +struct pdf_link_s +{ + pdf_linkkind kind; + fz_rect rect; + fz_obj *dest; + pdf_link *next; +}; + +typedef enum pdf_commentkind_e +{ + PDF_CTEXT, + PDF_CFREETEXT, + PDF_CLINE, + PDF_CSQUARE, + PDF_CCIRCLE, + PDF_CPOLYGON, + PDF_CPOLYLINE, + PDF_CMARKUP, + PDF_CCARET, + PDF_CSTAMP, + PDF_CINK +} pdf_commentkind; + +struct pdf_comment_s +{ + pdf_commentkind kind; + fz_rect rect; + fz_rect popup; + fz_obj *contents; + pdf_comment *next; +}; + +struct pdf_outline_s +{ + char *title; + pdf_link *link; + pdf_outline *child; + pdf_outline *next; +}; + +fz_error *pdf_loadnametree(fz_obj **dictp, pdf_xref *xref, fz_obj *root); +fz_error *pdf_loadnametrees(pdf_xref *xref); + +fz_error *pdf_newlink(pdf_link**, fz_rect rect, fz_obj *dest, pdf_linkkind kind); +fz_error *pdf_loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict); +void pdf_droplink(pdf_link *link); + +fz_error *pdf_loadoutline(pdf_outline **outlinep, pdf_xref *xref); +void pdf_debugoutline(pdf_outline *outline, int level); +void pdf_dropoutline(pdf_outline *outline); + +fz_error *pdf_loadannots(pdf_comment **, pdf_link **, pdf_xref *, fz_obj *annots); + diff --git a/rosapps/smartpdf/fitz/include/mupdf/base14.h b/rosapps/smartpdf/fitz/include/mupdf/base14.h new file mode 100644 index 00000000000..aee2d1145cb --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf/base14.h @@ -0,0 +1,30 @@ +extern const unsigned char fonts_Dingbats_cff[]; +extern const unsigned int fonts_Dingbats_cff_len; +extern const unsigned char fonts_NimbusMonL_Bold_cff[]; +extern const unsigned int fonts_NimbusMonL_Bold_cff_len; +extern const unsigned char fonts_NimbusMonL_BoldObli_cff[]; +extern const unsigned int fonts_NimbusMonL_BoldObli_cff_len; +extern const unsigned char fonts_NimbusMonL_Regu_cff[]; +extern const unsigned int fonts_NimbusMonL_Regu_cff_len; +extern const unsigned char fonts_NimbusMonL_ReguObli_cff[]; +extern const unsigned int fonts_NimbusMonL_ReguObli_cff_len; +extern const unsigned char fonts_NimbusRomNo9L_Medi_cff[]; +extern const unsigned int fonts_NimbusRomNo9L_Medi_cff_len; +extern const unsigned char fonts_NimbusRomNo9L_MediItal_cff[]; +extern const unsigned int fonts_NimbusRomNo9L_MediItal_cff_len; +extern const unsigned char fonts_NimbusRomNo9L_Regu_cff[]; +extern const unsigned int fonts_NimbusRomNo9L_Regu_cff_len; +extern const unsigned char fonts_NimbusRomNo9L_ReguItal_cff[]; +extern const unsigned int fonts_NimbusRomNo9L_ReguItal_cff_len; +extern const unsigned char fonts_NimbusSanL_Bold_cff[]; +extern const unsigned int fonts_NimbusSanL_Bold_cff_len; +extern const unsigned char fonts_NimbusSanL_BoldItal_cff[]; +extern const unsigned int fonts_NimbusSanL_BoldItal_cff_len; +extern const unsigned char fonts_NimbusSanL_Regu_cff[]; +extern const unsigned int fonts_NimbusSanL_Regu_cff_len; +extern const unsigned char fonts_NimbusSanL_ReguItal_cff[]; +extern const unsigned int fonts_NimbusSanL_ReguItal_cff_len; +extern const unsigned char fonts_StandardSymL_cff[]; +extern const unsigned int fonts_StandardSymL_cff_len; +extern const unsigned char fonts_URWChanceryL_MediItal_cff[]; +extern const unsigned int fonts_URWChanceryL_MediItal_cff_len; diff --git a/rosapps/smartpdf/fitz/include/mupdf/content.h b/rosapps/smartpdf/fitz/include/mupdf/content.h new file mode 100644 index 00000000000..ad6b824db6c --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf/content.h @@ -0,0 +1,110 @@ +/* + * content stream parsing + */ + +typedef struct pdf_material_s pdf_material; +typedef struct pdf_gstate_s pdf_gstate; +typedef struct pdf_csi_s pdf_csi; + +enum +{ + PDF_MFILL, + PDF_MSTROKE +}; + +enum +{ + PDF_MNONE, + PDF_MCOLOR, + PDF_MLAB, + PDF_MINDEXED, + PDF_MPATTERN, + PDF_MSHADE +}; + +struct pdf_material_s +{ + int kind; + fz_colorspace *cs; + float v[32]; + pdf_indexed *indexed; + pdf_pattern *pattern; + fz_shade *shade; +}; + +struct pdf_gstate_s +{ + /* path stroking */ + float linewidth; + int linecap; + int linejoin; + float miterlimit; + float dashphase; + int dashlen; + float dashlist[32]; + + /* materials */ + pdf_material stroke; + pdf_material fill; + + /* text state */ + float charspace; + float wordspace; + float scale; + float leading; + pdf_font *font; + float size; + int render; + float rise; + + /* tree construction state */ + fz_node *head; +}; + +struct pdf_csi_s +{ + pdf_gstate gstate[32]; + int gtop; + fz_obj *stack[32]; + int top; + int xbalance; + fz_obj *array; + + /* path object state */ + fz_pathnode *path; + int clip; + + /* text object state */ + fz_node *textclip; + fz_textnode *text; + fz_matrix tlm; + fz_matrix tm; + int textmode; + + fz_tree *tree; +}; + +/* build.c */ +void pdf_initgstate(pdf_gstate *gs); +fz_error *pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs); +fz_error *pdf_setcolor(pdf_csi *csi, int what, float *v); +fz_error *pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v); +fz_error *pdf_setshade(pdf_csi *csi, int what, fz_shade *shade); + +fz_error *pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path); +fz_error *pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int evenodd); +fz_error *pdf_addfillshape(pdf_gstate *gs, fz_node *shape); +fz_error *pdf_addstrokeshape(pdf_gstate *gs, fz_node *shape); +fz_error *pdf_addclipmask(pdf_gstate *gs, fz_node *shape); +fz_error *pdf_addtransform(pdf_gstate *gs, fz_node *transform); +fz_error *pdf_addshade(pdf_gstate *gs, fz_shade *shade); +fz_error *pdf_showpath(pdf_csi*, int close, int fill, int stroke, int evenodd); +fz_error *pdf_showtext(pdf_csi*, fz_obj *text); +fz_error *pdf_flushtext(pdf_csi*); +fz_error *pdf_showimage(pdf_csi*, pdf_image *img); + +/* interpret.c */ +fz_error *pdf_newcsi(pdf_csi **csip, int maskonly); +fz_error *pdf_runcsi(pdf_csi *, pdf_xref *xref, fz_obj *rdb, fz_stream *); +void pdf_dropcsi(pdf_csi *csi); + diff --git a/rosapps/smartpdf/fitz/include/mupdf/page.h b/rosapps/smartpdf/fitz/include/mupdf/page.h new file mode 100644 index 00000000000..21fa68cc490 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf/page.h @@ -0,0 +1,58 @@ +/* + * Page tree, pages and related objects + */ + +typedef struct pdf_pagetree_s pdf_pagetree; +typedef struct pdf_page_s pdf_page; +typedef struct pdf_textline_s pdf_textline; +typedef struct pdf_textchar_s pdf_textchar; + +struct pdf_pagetree_s +{ + int count; + int cursor; + fz_obj **pref; + fz_obj **pobj; +}; + +struct pdf_page_s +{ + fz_rect mediabox; + int rotate; + fz_obj *resources; + fz_tree *tree; + pdf_comment *comments; + pdf_link *links; +}; + +struct pdf_textchar_s +{ + fz_irect bbox; + int c; +}; + +struct pdf_textline_s +{ + int len, cap; + pdf_textchar *text; + pdf_textline *next; +}; + +/* pagetree.c */ +fz_error *pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref); +int pdf_getpagecount(pdf_pagetree *pages); +fz_obj *pdf_getpageobject(pdf_pagetree *pages, int p); +void pdf_debugpagetree(pdf_pagetree *pages); +void pdf_droppagetree(pdf_pagetree *pages); + +/* page.c */ +fz_error *pdf_getpageinfo(pdf_xref *xref, fz_obj *dict, fz_rect *bboxp, int *rotatep); +fz_error *pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *ref); +void pdf_droppage(pdf_page *page); + +/* unicode.c */ +fz_error *pdf_loadtextfromtree(pdf_textline **linep, fz_tree *tree, fz_matrix ctm); +void pdf_debugtextline(pdf_textline *line); +fz_error *pdf_newtextline(pdf_textline **linep); +void pdf_droptextline(pdf_textline *line); + diff --git a/rosapps/smartpdf/fitz/include/mupdf/rsrc.h b/rosapps/smartpdf/fitz/include/mupdf/rsrc.h new file mode 100644 index 00000000000..9d1e4595430 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf/rsrc.h @@ -0,0 +1,242 @@ +/* + * Resource store + */ + +typedef struct pdf_store_s pdf_store; + +typedef enum pdf_itemkind_e +{ + PDF_KCOLORSPACE, + PDF_KFUNCTION, + PDF_KXOBJECT, + PDF_KIMAGE, + PDF_KPATTERN, + PDF_KSHADE, + PDF_KCMAP, + PDF_KFONT +} pdf_itemkind; + +fz_error *pdf_newstore(pdf_store **storep); +void pdf_emptystore(pdf_store *store); +void pdf_dropstore(pdf_store *store); + +fz_error *pdf_storeitem(pdf_store *store, pdf_itemkind tag, fz_obj *key, void *val); +void *pdf_finditem(pdf_store *store, pdf_itemkind tag, fz_obj *key); + +fz_error *pdf_loadresources(fz_obj **rdb, pdf_xref *xref, fz_obj *orig); + +/* + * Functions + */ + +typedef struct pdf_function_s pdf_function; + +fz_error *pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *ref); +fz_error *pdf_evalfunction(pdf_function *func, float *in, int inlen, float *out, int outlen); +pdf_function *pdf_keepfunction(pdf_function *func); +void pdf_dropfunction(pdf_function *func); + +/* + * ColorSpace + */ + +typedef struct pdf_indexed_s pdf_indexed; + +struct pdf_indexed_s +{ + fz_colorspace super; /* hmmm... */ + fz_colorspace *base; + int high; + unsigned char *lookup; +}; + +extern fz_colorspace *pdf_devicegray; +extern fz_colorspace *pdf_devicergb; +extern fz_colorspace *pdf_devicecmyk; +extern fz_colorspace *pdf_devicelab; +extern fz_colorspace *pdf_devicepattern; + +void pdf_convcolor(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv); +void pdf_convpixmap(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp); + +fz_error *pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj); + +/* + * Pattern + */ + +typedef struct pdf_pattern_s pdf_pattern; + +struct pdf_pattern_s +{ + int refs; + int ismask; + float xstep; + float ystep; + fz_matrix matrix; + fz_rect bbox; + fz_tree *tree; +}; + +fz_error *pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); +pdf_pattern *pdf_keeppattern(pdf_pattern *pat); +void pdf_droppattern(pdf_pattern *pat); + +/* + * Shading + */ + +void pdf_setmeshvalue(float *mesh, int i, float x, float y, float t); +fz_error *pdf_loadshadefunction(fz_shade *shade, pdf_xref *xref, fz_obj *dict, float t0, float t1); +fz_error *pdf_loadtype1shade(fz_shade *, pdf_xref *, fz_obj *dict, fz_obj *ref); +fz_error *pdf_loadtype2shade(fz_shade *, pdf_xref *, fz_obj *dict, fz_obj *ref); +fz_error *pdf_loadtype3shade(fz_shade *, pdf_xref *, fz_obj *dict, fz_obj *ref); +fz_error *pdf_loadtype4shade(fz_shade *, pdf_xref *, fz_obj *dict, fz_obj *ref); +fz_error *pdf_loadtype5shade(fz_shade *, pdf_xref *, fz_obj *dict, fz_obj *ref); +fz_error *pdf_loadtype6shade(fz_shade *, pdf_xref *, fz_obj *dict, fz_obj *ref); +fz_error *pdf_loadtype7shade(fz_shade *, pdf_xref *, fz_obj *dict, fz_obj *ref); +fz_error *pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *obj, fz_obj *ref); + +/* + * XObject + */ + +typedef struct pdf_xobject_s pdf_xobject; + +struct pdf_xobject_s +{ + int refs; + fz_matrix matrix; + fz_rect bbox; + fz_obj *resources; + fz_buffer *contents; +}; + +fz_error *pdf_loadxobject(pdf_xobject **xobjp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); +pdf_xobject *pdf_keepxobject(pdf_xobject *xobj); +void pdf_dropxobject(pdf_xobject *xobj); + +/* + * Image + */ + +typedef struct pdf_image_s pdf_image; + +struct pdf_image_s +{ + fz_image super; + fz_image *mask; /* explicit mask with subimage */ + int usecolorkey; /* explicit color-keyed masking */ + int colorkey[FZ_MAXCOLORS * 2]; + pdf_indexed *indexed; + float decode[32]; + int bpc; + int stride; + fz_buffer *samples; +}; + +fz_error *pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file); +fz_error *pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); +fz_error *pdf_loadtile(fz_image *image, fz_pixmap *tile); + +/* + * CMap + */ + +typedef struct pdf_cmap_s pdf_cmap; + +fz_error *pdf_newcmap(pdf_cmap **cmapp); +pdf_cmap *pdf_keepcmap(pdf_cmap *cmap); +void pdf_dropcmap(pdf_cmap *cmap); + +void pdf_debugcmap(pdf_cmap *cmap); +int pdf_getwmode(pdf_cmap *cmap); +pdf_cmap *fz_getusecmap(pdf_cmap *cmap); +void fz_setwmode(pdf_cmap *cmap, int wmode); +void fz_setusecmap(pdf_cmap *cmap, pdf_cmap *usecmap); + +fz_error *pdf_addcodespace(pdf_cmap *cmap, unsigned lo, unsigned hi, int n); + +fz_error *pdf_maprangetotable(pdf_cmap *cmap, int low, int *map, int len); +fz_error *pdf_maprangetorange(pdf_cmap *cmap, int srclo, int srchi, int dstlo); +fz_error *pdf_maponetomany(pdf_cmap *cmap, int one, int *many, int len); +fz_error *pdf_sortcmap(pdf_cmap *cmap); + +int pdf_lookupcmap(pdf_cmap *cmap, int cpt); +unsigned char *pdf_decodecmap(pdf_cmap *cmap, unsigned char *s, int *cpt); + +fz_error *pdf_parsecmap(pdf_cmap **cmapp, fz_stream *file); +fz_error *pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *ref); +fz_error *pdf_loadsystemcmap(pdf_cmap **cmapp, char *name); +fz_error *pdf_newidentitycmap(pdf_cmap **cmapp, int wmode, int bytes); + +/* + * Font + */ + +void pdf_loadencoding(char **estrings, char *encoding); +int pdf_lookupagl(char *name, int *ucsbuf, int ucscap); + +extern const unsigned short pdf_docencoding[256]; +extern const char * const pdf_macroman[256]; +extern const char * const pdf_macexpert[256]; +extern const char * const pdf_winansi[256]; +extern const char * const pdf_standard[256]; +extern const char * const pdf_expert[256]; +extern const char * const pdf_symbol[256]; +extern const char * const pdf_zapfdingbats[256]; + +typedef struct pdf_font_s pdf_font; + +struct pdf_font_s +{ + fz_font super; + + /* FontDescriptor */ + int flags; + float italicangle; + float ascent; + float descent; + float capheight; + float xheight; + float missingwidth; + + /* Encoding (CMap) */ + pdf_cmap *encoding; + pdf_cmap *tottfcmap; + int ncidtogid; + unsigned short *cidtogid; + + /* ToUnicode */ + pdf_cmap *tounicode; + int ncidtoucs; + unsigned short *cidtoucs; + + /* Freetype */ + int substitute; + void *ftface; + char *filename; + fz_buffer *fontdata; + + /* Type3 data */ + fz_matrix matrix; + fz_tree *charprocs[256]; +}; + +/* unicode.c */ +fz_error *pdf_loadtounicode(pdf_font *font, pdf_xref *xref, char **strings, char *collection, fz_obj *cmapstm); + +/* fontfile.c */ +fz_error *pdf_loadbuiltinfont(pdf_font *font, char *basefont); +fz_error *pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref); +fz_error *pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection); +fz_error *pdf_loadsubstitutefont(pdf_font *font, int fdflags, char *collection); + +/* type3.c */ +fz_error *pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); + +/* font.c */ +fz_error *pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection); +fz_error *pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); +void pdf_dropfont(pdf_font *font); + diff --git a/rosapps/smartpdf/fitz/include/mupdf/syntax.h b/rosapps/smartpdf/fitz/include/mupdf/syntax.h new file mode 100644 index 00000000000..5c3dc59ff28 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf/syntax.h @@ -0,0 +1,74 @@ +/* + * tokenizer and low-level object parser + */ + +enum +{ + PDF_TERROR, PDF_TEOF, + PDF_TOARRAY, PDF_TCARRAY, + PDF_TODICT, PDF_TCDICT, + PDF_TOBRACE, PDF_TCBRACE, + PDF_TNAME, PDF_TINT, PDF_TREAL, PDF_TSTRING, PDF_TKEYWORD, + PDF_TR, PDF_TTRUE, PDF_TFALSE, PDF_TNULL, + PDF_TOBJ, PDF_TENDOBJ, + PDF_TSTREAM, PDF_TENDSTREAM, + PDF_TXREF, PDF_TTRAILER, PDF_TSTARTXREF, + PDF_NTOKENS +}; + +/* lex.c */ +int pdf_lex(fz_stream *f, unsigned char *buf, int n, int *len); + +/* parse.c */ +fz_error *pdf_parsearray(fz_obj **op, fz_stream *f, char *buf, int cap); +fz_error *pdf_parsedict(fz_obj **op, fz_stream *f, char *buf, int cap); +fz_error *pdf_parsestmobj(fz_obj **op, fz_stream *f, char *buf, int cap); +fz_error *pdf_parseindobj(fz_obj **op, fz_stream *f, char *buf, int cap, int *oid, int *gid, int *stmofs); + +fz_rect pdf_torect(fz_obj *array); +fz_matrix pdf_tomatrix(fz_obj *array); +fz_error *pdf_toutf8(char **dstp, fz_obj *src); +fz_error *pdf_toucs2(unsigned short **dstp, fz_obj *src); + +/* + * Encryption + */ + +/* Permission bits on pdf_crypt_s->p field */ +#define PDF_PERM_PRINT (1<<2) // bit 3 +#define PDF_PERM_CHANGE (1<<3) // bit 4 +#define PDF_PERM_COPY (1<<4) // bit 5 +#define PDF_PERM_NOTES (1<<5) // bit 6 +#define PDF_PERM_FILL_FORM (1<<8) // bit 9 +#define PDF_PERM_ACCESSIBILITY (1<<9) // bit 10 +#define PDF_PERM_ASSEMBLE (1<<10) // bit 11 +#define PDF_PERM_HIGH_RES_PRINT (1<<11) // bit 12 +#define PDF_DEFAULT_PERM_FLAGS 0xfffc + +typedef struct pdf_crypt_s pdf_crypt; + +struct pdf_crypt_s +{ + unsigned char o[32]; + unsigned char u[32]; + unsigned int p; + int r; + int n; + + fz_obj *encrypt; + fz_obj *id; + + unsigned char key[16]; + int keylen; +}; + +/* crypt.c */ +fz_error *pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id); +fz_error *pdf_newencrypt(pdf_crypt **cp, char *userpw, char *ownerpw, int p, int n, fz_obj *id); +fz_error *pdf_setpassword(pdf_crypt *crypt, char *pw); +fz_error *pdf_setuserpassword(pdf_crypt *crypt, char *pw, int pwlen); +fz_error *pdf_setownerpassword(pdf_crypt *crypt, char *pw, int pwlen); +fz_error *pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gid); +void pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid); +void pdf_dropcrypt(pdf_crypt *crypt); + diff --git a/rosapps/smartpdf/fitz/include/mupdf/xref.h b/rosapps/smartpdf/fitz/include/mupdf/xref.h new file mode 100644 index 00000000000..3143719df7f --- /dev/null +++ b/rosapps/smartpdf/fitz/include/mupdf/xref.h @@ -0,0 +1,76 @@ +/* + * xref and object / stream api + */ + +typedef struct pdf_xrefentry_s pdf_xrefentry; +typedef struct pdf_xref_s pdf_xref; + +struct pdf_xref_s +{ + fz_stream *file; + float version; + int startxref; + pdf_crypt *crypt; + + fz_obj *trailer; /* TODO split this into root/info/encrypt/id */ + fz_obj *root; /* resolved catalog dict */ + fz_obj *info; /* resolved info dict */ + fz_obj *dests; /* flattened dests nametree */ + + int len; + int cap; + pdf_xrefentry *table; + + struct pdf_store_s *store; + struct pdf_pagetree_s *pages; + struct pdf_outline_s *outlines; +}; + +struct pdf_xrefentry_s +{ + unsigned int ofs; /* file offset / objstm object number */ + unsigned short gen; /* generation / objstm index */ + char type; /* 0=unset (f)ree i(n)use (o)bjstm (d)elete (a)dd */ + char mark; /* for garbage collection etc */ + fz_buffer *stmbuf; /* in-memory stream */ + int stmofs; /* on-disk stream */ + fz_obj *obj; /* stored/cached object */ +}; + +fz_error *pdf_newxref(pdf_xref **); +fz_error *pdf_repairxref(pdf_xref *, char *filename); +fz_error *pdf_loadxref(pdf_xref *, char *filename); +fz_error *pdf_initxref(pdf_xref *); + +fz_error *pdf_openpdf(pdf_xref **, char *filename); +fz_error *pdf_updatexref(pdf_xref *, char *filename); +fz_error *pdf_savexref(pdf_xref *, char *filename, pdf_crypt *encrypt); + +void pdf_debugxref(pdf_xref *); +void pdf_flushxref(pdf_xref *, int force); +void pdf_closexref(pdf_xref *); + +fz_error *pdf_allocobject(pdf_xref *, int *oidp, int *genp); +fz_error *pdf_deleteobject(pdf_xref *, int oid, int gen); +fz_error *pdf_updateobject(pdf_xref *, int oid, int gen, fz_obj *obj); +fz_error *pdf_updatestream(pdf_xref *, int oid, int gen, fz_buffer *stm); + +fz_error *pdf_cacheobject(pdf_xref *, int oid, int gen); +fz_error *pdf_loadobject(fz_obj **objp, pdf_xref *, int oid, int gen); +fz_error *pdf_loadindirect(fz_obj **objp, pdf_xref *, fz_obj *ref); +fz_error *pdf_resolve(fz_obj **reforobj, pdf_xref *); + +int pdf_isstream(pdf_xref *xref, int oid, int gen); +fz_error *pdf_buildinlinefilter(fz_filter **filterp, fz_obj *stmobj); +fz_error *pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen); +fz_error *pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen); +fz_error *pdf_openrawstream(fz_stream **stmp, pdf_xref *, int oid, int gen); +fz_error *pdf_openstream(fz_stream **stmp, pdf_xref *, int oid, int gen); + +fz_error *pdf_garbagecollect(pdf_xref *xref); +fz_error *pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *old); + +/* private */ +fz_error *pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap); +fz_error *pdf_decryptxref(pdf_xref *xref); + diff --git a/rosapps/smartpdf/fitz/include/pdfapp.h b/rosapps/smartpdf/fitz/include/pdfapp.h new file mode 100644 index 00000000000..4792adda5e1 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/pdfapp.h @@ -0,0 +1,75 @@ +/* + * Utility object for handling a pdf application / view + * Takes care of PDF loading and displaying and navigation, + * uses a number of callbacks to the GUI app. + */ + +typedef struct pdfapp_s pdfapp_t; + +enum { ARROW, HAND, WAIT }; + +extern void winwarn(pdfapp_t*, char *s); +extern void winerror(pdfapp_t*, char *s); +extern void wintitle(pdfapp_t*, char *title); +extern void winresize(pdfapp_t*, int w, int h); +extern void winconvert(pdfapp_t*, fz_pixmap *image); +extern void winrepaint(pdfapp_t*); +extern char* winpassword(pdfapp_t*, char *filename); +extern void winopenuri(pdfapp_t*, char *s); +extern void wincursor(pdfapp_t*, int curs); +extern void windocopy(pdfapp_t*); + +struct pdfapp_s +{ + /* current document params */ + char *filename; + char *doctitle; + pdf_xref *xref; + pdf_outline *outline; + pdf_pagetree *pages; + fz_renderer *rast; + + /* current view params */ + float zoom; + int rotate; + fz_pixmap *image; + + /* current page params */ + int pageno; + pdf_page *page; + + /* snapback history */ + int hist[256]; + int histlen; + + /* window system sizes */ + int winw, winh; + int scrw, scrh; + int shrinkwrap; + + /* event handling state */ + char number[256]; + int numberlen; + + int ispanning; + int panx, pany; + + int iscopying; + int selx, sely; + fz_irect selr; + + /* client context storage */ + void *userdata; +}; + +void pdfapp_init(pdfapp_t *app); +void pdfapp_open(pdfapp_t *app, char *filename); +void pdfapp_close(pdfapp_t *app); + +char *pdfapp_usage(pdfapp_t *app); + +void pdfapp_onkey(pdfapp_t *app, int c); +void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state); +void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen); +void pdfapp_onresize(pdfapp_t *app, int w, int h); + diff --git a/rosapps/smartpdf/fitz/include/samus.h b/rosapps/smartpdf/fitz/include/samus.h new file mode 100644 index 00000000000..a7b394823d6 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/samus.h @@ -0,0 +1,25 @@ +#ifdef _SAMUS_H_ +#error "samus.h must only be included once" +#endif +#define _SAMUS_H_ + +#ifndef _FITZ_BASE_H_ +#error "fitz-base.h must be included before mupdf.h" +#endif + +#ifndef _FITZ_STREAM_H_ +#error "fitz-stream.h must be included before mupdf.h" +#endif + +#ifndef _FITZ_WORLD_H_ +#error "fitz-world.h must be included before mupdf.h" +#endif + +#include "samus/misc.h" +#include "samus/zip.h" +#include "samus/xml.h" +#include "samus/pack.h" + +#include "samus/names.h" +#include "samus/fixdoc.h" + diff --git a/rosapps/smartpdf/fitz/include/samus/fixdoc.h b/rosapps/smartpdf/fitz/include/samus/fixdoc.h new file mode 100644 index 00000000000..1b0caad1415 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/samus/fixdoc.h @@ -0,0 +1,13 @@ +/* + * FixedDocumentSequence -- the list of pages + */ + +typedef struct sa_fixdocseq_s sa_fixdocseq; + +fz_error *sa_loadfixdocseq(sa_fixdocseq **seqp, sa_package *pack, char *part); +void sa_debugfixdocseq(sa_fixdocseq *seq); +void sa_dropfixdocseq(sa_fixdocseq *seq); + +int sa_getpagecount(sa_fixdocseq *seq); +char *sa_getpagepart(sa_fixdocseq *seq, int idx); + diff --git a/rosapps/smartpdf/fitz/include/samus/misc.h b/rosapps/smartpdf/fitz/include/samus/misc.h new file mode 100644 index 00000000000..50170a0433b --- /dev/null +++ b/rosapps/smartpdf/fitz/include/samus/misc.h @@ -0,0 +1,7 @@ +/* + * Misc utility functions that Samus needs. + */ + +char *sa_resolvepath(char *dst, char *base, char *part, int dstlen); +int sa_strcmp(char *s0, char *s1); + diff --git a/rosapps/smartpdf/fitz/include/samus/names.h b/rosapps/smartpdf/fitz/include/samus/names.h new file mode 100644 index 00000000000..03a0e505927 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/samus/names.h @@ -0,0 +1,96 @@ +/* + * Various long string constants + */ + +/* + * XML Namespaces + */ + +#define SA_NS_CONTENTTYPES \ + "http://schemas.microsoft.com/metro/2005/02/content-types" +#define SA_NS_COREPROPERTIES \ + "http://schemas.microsoft.com/metro/2005/02/md/core-properties" +#define SA_NS_SIGNATURES \ + "http://schemas.microsoft.com/metro/2005/02/digsig" +#define SA_NS_RELATIONSHIPS \ + "http://schemas.microsoft.com/metro/2005/02/relationships" +#define SA_NS_VERSIONING \ + "http://schemas.microsoft.com/winfx/markup-compatibility/2005" + +#define SA_NS_DISCARDCONTROL \ + "http://schemas.microsoft.com/metro/2005/02/rp/discard-control" +#define SA_NS_FIXEDDOCUMENT \ + "http://schemas.microsoft.com/metro/2005/02/rp" +#define SA_NS_FIXEDDOCUMENTSEQUENCE \ + "http://schemas.microsoft.com/metro/2005/02/rp" +#define SA_NS_FIXEDPAGE \ + "http://schemas.microsoft.com/metro/2005/02/rp" +#define SA_NS_PRINTSCHEMAFRAMEWORK \ + "http://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" +#define SA_NS_PRINTSCHEMAKEYWORDS \ + "http://schemas.microsoft.com/windows/2003/08/printing/printschemakeywords" +#define SA_NS_RESOURCEDICTIONARY \ + "http://schemas.microsoft.com/metro/2005/02/rp/resourcedictionary-key" + +/* + * Content types + */ + +#define SA_TYPE_COREPROPERTIES \ + "application/vnd.ms-metro.core-properties+xml" +#define SA_TYPE_CERTIFICATE \ + "application/vnd.ms-metro.ds-certificate" +#define SA_TYPE_ORIGIN \ + "application/vnd.ms-metro.ds-origin" +#define SA_TYPE_SIGNATURE \ + "application/vnd.ms-metro.ds-xmlsignature+xml" +#define SA_TYPE_RELATIONSHIPS \ + "application/vnd.ms-metro.relationships+xml" + +#define SA_TYPE_FIXEDDOCUMENT \ + "application/vnd.ms-metro.rp-fixeddocument+xml" +#define SA_TYPE_FIXEDDOCUMENTSEQUENCE \ + "application/vnd.ms-metro.rp-fixeddocumentsequence+xml" +#define SA_TYPE_FIXEDPAGE \ + "application/vnd.ms-metro.rp-fixedpage+xml" +#define SA_TYPE_FONT \ + "application/vnd.ms-opentype" +#define SA_TYPE_OBFUSCATEDFONT \ + "application/vnd.ms-metro.obfuscated-opentype" +#define SA_TYPE_PRINTTICKET \ + "application/vnd.ms-printing.printticket+xml" +#define SA_TYPE_JPEGIMAGE \ + "image/jpeg" +#define SA_TYPE_PNGIMAGE \ + "image/png" +#define SA_TYPE_TIFFIMAGE \ + "image/tiff" + +/* + * Relationship types + */ + +#define SA_REL_COREPROPERTIES \ + "http://schemas.microsoft.com/metro/2005/02/md/core-properties" +#define SA_REL_SIGNATURE \ + "http://schemas.microsoft.com/metro/2005/02/ds/signature" +#define SA_REL_CERTIFICATE \ + "http://schemas.microsoft.com/metro/2005/02/ds/certificate" +#define SA_REL_ORIGIN \ + "http://schemas.microsoft.com/metro/2005/02/ds/origin" +#define SA_REL_THUMBNAIL \ + "http://schemas.microsoft.com/metro/2005/02/md/thumbnail" + +#define SA_REL_ANNOTATIONS \ + "http://schemas.microsoft.com/metro/2005/02/rp/annotations" +#define SA_REL_DISCARDCONTROL \ + "http://schemas.microsoft.com/metro/2005/02/rp/discard-control" +#define SA_REL_PRINTTICKET \ + "http://schemas.microsoft.com/metro/2005/02/rp/printticket" +#define SA_REL_FIXEDREPRESENTATION \ + "http://schemas.microsoft.com/metro/2005/02/rp/fixedrepresentation" +#define SA_REL_REQUIREDRESOURCE \ + "http://schemas.microsoft.com/metro/2005/02/rp/required-resource" +#define SA_REL_RESTRICTEDFONT \ + "http://schemas.microsoft.com/metro/2005/02/rp/restricted-font" + diff --git a/rosapps/smartpdf/fitz/include/samus/pack.h b/rosapps/smartpdf/fitz/include/samus/pack.h new file mode 100644 index 00000000000..cdacc21776d --- /dev/null +++ b/rosapps/smartpdf/fitz/include/samus/pack.h @@ -0,0 +1,28 @@ +/* + * Metro Package and Parts + */ + +typedef struct sa_package_s sa_package; +typedef struct sa_relation_s sa_relation; + +struct sa_relation_s +{ + int external; + char *target; + char *id; + char *type; + sa_relation *next; +}; + +fz_error *sa_openpackage(sa_package **packp, char *filename); +void sa_debugpackage(sa_package *pack); +void sa_closepackage(sa_package *pack); + +fz_error *sa_openpart(fz_stream **stmp, sa_package *pack, char *partname); + +char *sa_typepart(sa_package *pack, char *partname); + +fz_error *sa_loadrelations(sa_relation **relsp, sa_package *pack, char *partname); +void sa_debugrelations(sa_relation *rels); +void sa_droprelations(sa_relation *rels); + diff --git a/rosapps/smartpdf/fitz/include/samus/xml.h b/rosapps/smartpdf/fitz/include/samus/xml.h new file mode 100644 index 00000000000..b72fbe565d1 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/samus/xml.h @@ -0,0 +1,20 @@ +/* + * A simple XML parsing API based on Inferno's. + * Under the surface this one uses expat and in-memory objects, + * but that should not be visible through the API. + */ + +typedef struct sa_xmlparser_s sa_xmlparser; +typedef struct sa_xmlitem_s sa_xmlitem; + +fz_error *sa_openxml(sa_xmlparser **spp, fz_stream *file, int ns); +void sa_debugxml(sa_xmlitem *item, int level); +void sa_closexml(sa_xmlparser *sp); + +sa_xmlitem *sa_xmlnext(sa_xmlparser *sp); +void sa_xmldown(sa_xmlparser *sp); +void sa_xmlup(sa_xmlparser *sp); + +char *sa_xmlname(sa_xmlitem *item); +char *sa_xmlatt(sa_xmlitem *item, char *att); + diff --git a/rosapps/smartpdf/fitz/include/samus/zip.h b/rosapps/smartpdf/fitz/include/samus/zip.h new file mode 100644 index 00000000000..e06e1e90435 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/samus/zip.h @@ -0,0 +1,12 @@ +/* + * ZIP archive + */ + +typedef struct sa_zip_s sa_zip; + +fz_error *sa_openzip(sa_zip **zipp, char *filename); +void sa_debugzip(sa_zip *zip); +void sa_closezip(sa_zip *zip); +int sa_accesszipentry(sa_zip *zip, char *name); +fz_error *sa_openzipentry(fz_stream **stmp, sa_zip *zip, char *name); + diff --git a/rosapps/smartpdf/fitz/include/win_os.h b/rosapps/smartpdf/fitz/include/win_os.h new file mode 100644 index 00000000000..d80bbdb27e7 --- /dev/null +++ b/rosapps/smartpdf/fitz/include/win_os.h @@ -0,0 +1,12 @@ +#ifndef _WIN_OS_H_ +#define _WIN_OS_H_ + +#ifdef WIN32 +#ifdef inline +#undef inline +#endif +#define inline _inline +#endif + + +#endif diff --git a/rosapps/smartpdf/fitz/mupdf/glyphlist.txt b/rosapps/smartpdf/fitz/mupdf/glyphlist.txt new file mode 100644 index 00000000000..a1a22702a8e --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/glyphlist.txt @@ -0,0 +1,4291 @@ +# Name: Adobe Glyph List +# Table version: 2.0 +# Date: September 20, 2002 +# +# See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html +# +# Format: Semicolon-delimited fields: +# (1) glyph name +# (2) Unicode scalar value +A;0041 +AE;00C6 +AEacute;01FC +AEmacron;01E2 +AEsmall;F7E6 +Aacute;00C1 +Aacutesmall;F7E1 +Abreve;0102 +Abreveacute;1EAE +Abrevecyrillic;04D0 +Abrevedotbelow;1EB6 +Abrevegrave;1EB0 +Abrevehookabove;1EB2 +Abrevetilde;1EB4 +Acaron;01CD +Acircle;24B6 +Acircumflex;00C2 +Acircumflexacute;1EA4 +Acircumflexdotbelow;1EAC +Acircumflexgrave;1EA6 +Acircumflexhookabove;1EA8 +Acircumflexsmall;F7E2 +Acircumflextilde;1EAA +Acute;F6C9 +Acutesmall;F7B4 +Acyrillic;0410 +Adblgrave;0200 +Adieresis;00C4 +Adieresiscyrillic;04D2 +Adieresismacron;01DE +Adieresissmall;F7E4 +Adotbelow;1EA0 +Adotmacron;01E0 +Agrave;00C0 +Agravesmall;F7E0 +Ahookabove;1EA2 +Aiecyrillic;04D4 +Ainvertedbreve;0202 +Alpha;0391 +Alphatonos;0386 +Amacron;0100 +Amonospace;FF21 +Aogonek;0104 +Aring;00C5 +Aringacute;01FA +Aringbelow;1E00 +Aringsmall;F7E5 +Asmall;F761 +Atilde;00C3 +Atildesmall;F7E3 +Aybarmenian;0531 +B;0042 +Bcircle;24B7 +Bdotaccent;1E02 +Bdotbelow;1E04 +Becyrillic;0411 +Benarmenian;0532 +Beta;0392 +Bhook;0181 +Blinebelow;1E06 +Bmonospace;FF22 +Brevesmall;F6F4 +Bsmall;F762 +Btopbar;0182 +C;0043 +Caarmenian;053E +Cacute;0106 +Caron;F6CA +Caronsmall;F6F5 +Ccaron;010C +Ccedilla;00C7 +Ccedillaacute;1E08 +Ccedillasmall;F7E7 +Ccircle;24B8 +Ccircumflex;0108 +Cdot;010A +Cdotaccent;010A +Cedillasmall;F7B8 +Chaarmenian;0549 +Cheabkhasiancyrillic;04BC +Checyrillic;0427 +Chedescenderabkhasiancyrillic;04BE +Chedescendercyrillic;04B6 +Chedieresiscyrillic;04F4 +Cheharmenian;0543 +Chekhakassiancyrillic;04CB +Cheverticalstrokecyrillic;04B8 +Chi;03A7 +Chook;0187 +Circumflexsmall;F6F6 +Cmonospace;FF23 +Coarmenian;0551 +Csmall;F763 +D;0044 +DZ;01F1 +DZcaron;01C4 +Daarmenian;0534 +Dafrican;0189 +Dcaron;010E +Dcedilla;1E10 +Dcircle;24B9 +Dcircumflexbelow;1E12 +Dcroat;0110 +Ddotaccent;1E0A +Ddotbelow;1E0C +Decyrillic;0414 +Deicoptic;03EE +Delta;2206 +Deltagreek;0394 +Dhook;018A +Dieresis;F6CB +DieresisAcute;F6CC +DieresisGrave;F6CD +Dieresissmall;F7A8 +Digammagreek;03DC +Djecyrillic;0402 +Dlinebelow;1E0E +Dmonospace;FF24 +Dotaccentsmall;F6F7 +Dslash;0110 +Dsmall;F764 +Dtopbar;018B +Dz;01F2 +Dzcaron;01C5 +Dzeabkhasiancyrillic;04E0 +Dzecyrillic;0405 +Dzhecyrillic;040F +E;0045 +Eacute;00C9 +Eacutesmall;F7E9 +Ebreve;0114 +Ecaron;011A +Ecedillabreve;1E1C +Echarmenian;0535 +Ecircle;24BA +Ecircumflex;00CA +Ecircumflexacute;1EBE +Ecircumflexbelow;1E18 +Ecircumflexdotbelow;1EC6 +Ecircumflexgrave;1EC0 +Ecircumflexhookabove;1EC2 +Ecircumflexsmall;F7EA +Ecircumflextilde;1EC4 +Ecyrillic;0404 +Edblgrave;0204 +Edieresis;00CB +Edieresissmall;F7EB +Edot;0116 +Edotaccent;0116 +Edotbelow;1EB8 +Efcyrillic;0424 +Egrave;00C8 +Egravesmall;F7E8 +Eharmenian;0537 +Ehookabove;1EBA +Eightroman;2167 +Einvertedbreve;0206 +Eiotifiedcyrillic;0464 +Elcyrillic;041B +Elevenroman;216A +Emacron;0112 +Emacronacute;1E16 +Emacrongrave;1E14 +Emcyrillic;041C +Emonospace;FF25 +Encyrillic;041D +Endescendercyrillic;04A2 +Eng;014A +Enghecyrillic;04A4 +Enhookcyrillic;04C7 +Eogonek;0118 +Eopen;0190 +Epsilon;0395 +Epsilontonos;0388 +Ercyrillic;0420 +Ereversed;018E +Ereversedcyrillic;042D +Escyrillic;0421 +Esdescendercyrillic;04AA +Esh;01A9 +Esmall;F765 +Eta;0397 +Etarmenian;0538 +Etatonos;0389 +Eth;00D0 +Ethsmall;F7F0 +Etilde;1EBC +Etildebelow;1E1A +Euro;20AC +Ezh;01B7 +Ezhcaron;01EE +Ezhreversed;01B8 +F;0046 +Fcircle;24BB +Fdotaccent;1E1E +Feharmenian;0556 +Feicoptic;03E4 +Fhook;0191 +Fitacyrillic;0472 +Fiveroman;2164 +Fmonospace;FF26 +Fourroman;2163 +Fsmall;F766 +G;0047 +GBsquare;3387 +Gacute;01F4 +Gamma;0393 +Gammaafrican;0194 +Gangiacoptic;03EA +Gbreve;011E +Gcaron;01E6 +Gcedilla;0122 +Gcircle;24BC +Gcircumflex;011C +Gcommaaccent;0122 +Gdot;0120 +Gdotaccent;0120 +Gecyrillic;0413 +Ghadarmenian;0542 +Ghemiddlehookcyrillic;0494 +Ghestrokecyrillic;0492 +Gheupturncyrillic;0490 +Ghook;0193 +Gimarmenian;0533 +Gjecyrillic;0403 +Gmacron;1E20 +Gmonospace;FF27 +Grave;F6CE +Gravesmall;F760 +Gsmall;F767 +Gsmallhook;029B +Gstroke;01E4 +H;0048 +H18533;25CF +H18543;25AA +H18551;25AB +H22073;25A1 +HPsquare;33CB +Haabkhasiancyrillic;04A8 +Hadescendercyrillic;04B2 +Hardsigncyrillic;042A +Hbar;0126 +Hbrevebelow;1E2A +Hcedilla;1E28 +Hcircle;24BD +Hcircumflex;0124 +Hdieresis;1E26 +Hdotaccent;1E22 +Hdotbelow;1E24 +Hmonospace;FF28 +Hoarmenian;0540 +Horicoptic;03E8 +Hsmall;F768 +Hungarumlaut;F6CF +Hungarumlautsmall;F6F8 +Hzsquare;3390 +I;0049 +IAcyrillic;042F +IJ;0132 +IUcyrillic;042E +Iacute;00CD +Iacutesmall;F7ED +Ibreve;012C +Icaron;01CF +Icircle;24BE +Icircumflex;00CE +Icircumflexsmall;F7EE +Icyrillic;0406 +Idblgrave;0208 +Idieresis;00CF +Idieresisacute;1E2E +Idieresiscyrillic;04E4 +Idieresissmall;F7EF +Idot;0130 +Idotaccent;0130 +Idotbelow;1ECA +Iebrevecyrillic;04D6 +Iecyrillic;0415 +Ifraktur;2111 +Igrave;00CC +Igravesmall;F7EC +Ihookabove;1EC8 +Iicyrillic;0418 +Iinvertedbreve;020A +Iishortcyrillic;0419 +Imacron;012A +Imacroncyrillic;04E2 +Imonospace;FF29 +Iniarmenian;053B +Iocyrillic;0401 +Iogonek;012E +Iota;0399 +Iotaafrican;0196 +Iotadieresis;03AA +Iotatonos;038A +Ismall;F769 +Istroke;0197 +Itilde;0128 +Itildebelow;1E2C +Izhitsacyrillic;0474 +Izhitsadblgravecyrillic;0476 +J;004A +Jaarmenian;0541 +Jcircle;24BF +Jcircumflex;0134 +Jecyrillic;0408 +Jheharmenian;054B +Jmonospace;FF2A +Jsmall;F76A +K;004B +KBsquare;3385 +KKsquare;33CD +Kabashkircyrillic;04A0 +Kacute;1E30 +Kacyrillic;041A +Kadescendercyrillic;049A +Kahookcyrillic;04C3 +Kappa;039A +Kastrokecyrillic;049E +Kaverticalstrokecyrillic;049C +Kcaron;01E8 +Kcedilla;0136 +Kcircle;24C0 +Kcommaaccent;0136 +Kdotbelow;1E32 +Keharmenian;0554 +Kenarmenian;053F +Khacyrillic;0425 +Kheicoptic;03E6 +Khook;0198 +Kjecyrillic;040C +Klinebelow;1E34 +Kmonospace;FF2B +Koppacyrillic;0480 +Koppagreek;03DE +Ksicyrillic;046E +Ksmall;F76B +L;004C +LJ;01C7 +LL;F6BF +Lacute;0139 +Lambda;039B +Lcaron;013D +Lcedilla;013B +Lcircle;24C1 +Lcircumflexbelow;1E3C +Lcommaaccent;013B +Ldot;013F +Ldotaccent;013F +Ldotbelow;1E36 +Ldotbelowmacron;1E38 +Liwnarmenian;053C +Lj;01C8 +Ljecyrillic;0409 +Llinebelow;1E3A +Lmonospace;FF2C +Lslash;0141 +Lslashsmall;F6F9 +Lsmall;F76C +M;004D +MBsquare;3386 +Macron;F6D0 +Macronsmall;F7AF +Macute;1E3E +Mcircle;24C2 +Mdotaccent;1E40 +Mdotbelow;1E42 +Menarmenian;0544 +Mmonospace;FF2D +Msmall;F76D +Mturned;019C +Mu;039C +N;004E +NJ;01CA +Nacute;0143 +Ncaron;0147 +Ncedilla;0145 +Ncircle;24C3 +Ncircumflexbelow;1E4A +Ncommaaccent;0145 +Ndotaccent;1E44 +Ndotbelow;1E46 +Nhookleft;019D +Nineroman;2168 +Nj;01CB +Njecyrillic;040A +Nlinebelow;1E48 +Nmonospace;FF2E +Nowarmenian;0546 +Nsmall;F76E +Ntilde;00D1 +Ntildesmall;F7F1 +Nu;039D +O;004F +OE;0152 +OEsmall;F6FA +Oacute;00D3 +Oacutesmall;F7F3 +Obarredcyrillic;04E8 +Obarreddieresiscyrillic;04EA +Obreve;014E +Ocaron;01D1 +Ocenteredtilde;019F +Ocircle;24C4 +Ocircumflex;00D4 +Ocircumflexacute;1ED0 +Ocircumflexdotbelow;1ED8 +Ocircumflexgrave;1ED2 +Ocircumflexhookabove;1ED4 +Ocircumflexsmall;F7F4 +Ocircumflextilde;1ED6 +Ocyrillic;041E +Odblacute;0150 +Odblgrave;020C +Odieresis;00D6 +Odieresiscyrillic;04E6 +Odieresissmall;F7F6 +Odotbelow;1ECC +Ogoneksmall;F6FB +Ograve;00D2 +Ogravesmall;F7F2 +Oharmenian;0555 +Ohm;2126 +Ohookabove;1ECE +Ohorn;01A0 +Ohornacute;1EDA +Ohorndotbelow;1EE2 +Ohorngrave;1EDC +Ohornhookabove;1EDE +Ohorntilde;1EE0 +Ohungarumlaut;0150 +Oi;01A2 +Oinvertedbreve;020E +Omacron;014C +Omacronacute;1E52 +Omacrongrave;1E50 +Omega;2126 +Omegacyrillic;0460 +Omegagreek;03A9 +Omegaroundcyrillic;047A +Omegatitlocyrillic;047C +Omegatonos;038F +Omicron;039F +Omicrontonos;038C +Omonospace;FF2F +Oneroman;2160 +Oogonek;01EA +Oogonekmacron;01EC +Oopen;0186 +Oslash;00D8 +Oslashacute;01FE +Oslashsmall;F7F8 +Osmall;F76F +Ostrokeacute;01FE +Otcyrillic;047E +Otilde;00D5 +Otildeacute;1E4C +Otildedieresis;1E4E +Otildesmall;F7F5 +P;0050 +Pacute;1E54 +Pcircle;24C5 +Pdotaccent;1E56 +Pecyrillic;041F +Peharmenian;054A +Pemiddlehookcyrillic;04A6 +Phi;03A6 +Phook;01A4 +Pi;03A0 +Piwrarmenian;0553 +Pmonospace;FF30 +Psi;03A8 +Psicyrillic;0470 +Psmall;F770 +Q;0051 +Qcircle;24C6 +Qmonospace;FF31 +Qsmall;F771 +R;0052 +Raarmenian;054C +Racute;0154 +Rcaron;0158 +Rcedilla;0156 +Rcircle;24C7 +Rcommaaccent;0156 +Rdblgrave;0210 +Rdotaccent;1E58 +Rdotbelow;1E5A +Rdotbelowmacron;1E5C +Reharmenian;0550 +Rfraktur;211C +Rho;03A1 +Ringsmall;F6FC +Rinvertedbreve;0212 +Rlinebelow;1E5E +Rmonospace;FF32 +Rsmall;F772 +Rsmallinverted;0281 +Rsmallinvertedsuperior;02B6 +S;0053 +SF010000;250C +SF020000;2514 +SF030000;2510 +SF040000;2518 +SF050000;253C +SF060000;252C +SF070000;2534 +SF080000;251C +SF090000;2524 +SF100000;2500 +SF110000;2502 +SF190000;2561 +SF200000;2562 +SF210000;2556 +SF220000;2555 +SF230000;2563 +SF240000;2551 +SF250000;2557 +SF260000;255D +SF270000;255C +SF280000;255B +SF360000;255E +SF370000;255F +SF380000;255A +SF390000;2554 +SF400000;2569 +SF410000;2566 +SF420000;2560 +SF430000;2550 +SF440000;256C +SF450000;2567 +SF460000;2568 +SF470000;2564 +SF480000;2565 +SF490000;2559 +SF500000;2558 +SF510000;2552 +SF520000;2553 +SF530000;256B +SF540000;256A +Sacute;015A +Sacutedotaccent;1E64 +Sampigreek;03E0 +Scaron;0160 +Scarondotaccent;1E66 +Scaronsmall;F6FD +Scedilla;015E +Schwa;018F +Schwacyrillic;04D8 +Schwadieresiscyrillic;04DA +Scircle;24C8 +Scircumflex;015C +Scommaaccent;0218 +Sdotaccent;1E60 +Sdotbelow;1E62 +Sdotbelowdotaccent;1E68 +Seharmenian;054D +Sevenroman;2166 +Shaarmenian;0547 +Shacyrillic;0428 +Shchacyrillic;0429 +Sheicoptic;03E2 +Shhacyrillic;04BA +Shimacoptic;03EC +Sigma;03A3 +Sixroman;2165 +Smonospace;FF33 +Softsigncyrillic;042C +Ssmall;F773 +Stigmagreek;03DA +T;0054 +Tau;03A4 +Tbar;0166 +Tcaron;0164 +Tcedilla;0162 +Tcircle;24C9 +Tcircumflexbelow;1E70 +Tcommaaccent;0162 +Tdotaccent;1E6A +Tdotbelow;1E6C +Tecyrillic;0422 +Tedescendercyrillic;04AC +Tenroman;2169 +Tetsecyrillic;04B4 +Theta;0398 +Thook;01AC +Thorn;00DE +Thornsmall;F7FE +Threeroman;2162 +Tildesmall;F6FE +Tiwnarmenian;054F +Tlinebelow;1E6E +Tmonospace;FF34 +Toarmenian;0539 +Tonefive;01BC +Tonesix;0184 +Tonetwo;01A7 +Tretroflexhook;01AE +Tsecyrillic;0426 +Tshecyrillic;040B +Tsmall;F774 +Twelveroman;216B +Tworoman;2161 +U;0055 +Uacute;00DA +Uacutesmall;F7FA +Ubreve;016C +Ucaron;01D3 +Ucircle;24CA +Ucircumflex;00DB +Ucircumflexbelow;1E76 +Ucircumflexsmall;F7FB +Ucyrillic;0423 +Udblacute;0170 +Udblgrave;0214 +Udieresis;00DC +Udieresisacute;01D7 +Udieresisbelow;1E72 +Udieresiscaron;01D9 +Udieresiscyrillic;04F0 +Udieresisgrave;01DB +Udieresismacron;01D5 +Udieresissmall;F7FC +Udotbelow;1EE4 +Ugrave;00D9 +Ugravesmall;F7F9 +Uhookabove;1EE6 +Uhorn;01AF +Uhornacute;1EE8 +Uhorndotbelow;1EF0 +Uhorngrave;1EEA +Uhornhookabove;1EEC +Uhorntilde;1EEE +Uhungarumlaut;0170 +Uhungarumlautcyrillic;04F2 +Uinvertedbreve;0216 +Ukcyrillic;0478 +Umacron;016A +Umacroncyrillic;04EE +Umacrondieresis;1E7A +Umonospace;FF35 +Uogonek;0172 +Upsilon;03A5 +Upsilon1;03D2 +Upsilonacutehooksymbolgreek;03D3 +Upsilonafrican;01B1 +Upsilondieresis;03AB +Upsilondieresishooksymbolgreek;03D4 +Upsilonhooksymbol;03D2 +Upsilontonos;038E +Uring;016E +Ushortcyrillic;040E +Usmall;F775 +Ustraightcyrillic;04AE +Ustraightstrokecyrillic;04B0 +Utilde;0168 +Utildeacute;1E78 +Utildebelow;1E74 +V;0056 +Vcircle;24CB +Vdotbelow;1E7E +Vecyrillic;0412 +Vewarmenian;054E +Vhook;01B2 +Vmonospace;FF36 +Voarmenian;0548 +Vsmall;F776 +Vtilde;1E7C +W;0057 +Wacute;1E82 +Wcircle;24CC +Wcircumflex;0174 +Wdieresis;1E84 +Wdotaccent;1E86 +Wdotbelow;1E88 +Wgrave;1E80 +Wmonospace;FF37 +Wsmall;F777 +X;0058 +Xcircle;24CD +Xdieresis;1E8C +Xdotaccent;1E8A +Xeharmenian;053D +Xi;039E +Xmonospace;FF38 +Xsmall;F778 +Y;0059 +Yacute;00DD +Yacutesmall;F7FD +Yatcyrillic;0462 +Ycircle;24CE +Ycircumflex;0176 +Ydieresis;0178 +Ydieresissmall;F7FF +Ydotaccent;1E8E +Ydotbelow;1EF4 +Yericyrillic;042B +Yerudieresiscyrillic;04F8 +Ygrave;1EF2 +Yhook;01B3 +Yhookabove;1EF6 +Yiarmenian;0545 +Yicyrillic;0407 +Yiwnarmenian;0552 +Ymonospace;FF39 +Ysmall;F779 +Ytilde;1EF8 +Yusbigcyrillic;046A +Yusbigiotifiedcyrillic;046C +Yuslittlecyrillic;0466 +Yuslittleiotifiedcyrillic;0468 +Z;005A +Zaarmenian;0536 +Zacute;0179 +Zcaron;017D +Zcaronsmall;F6FF +Zcircle;24CF +Zcircumflex;1E90 +Zdot;017B +Zdotaccent;017B +Zdotbelow;1E92 +Zecyrillic;0417 +Zedescendercyrillic;0498 +Zedieresiscyrillic;04DE +Zeta;0396 +Zhearmenian;053A +Zhebrevecyrillic;04C1 +Zhecyrillic;0416 +Zhedescendercyrillic;0496 +Zhedieresiscyrillic;04DC +Zlinebelow;1E94 +Zmonospace;FF3A +Zsmall;F77A +Zstroke;01B5 +a;0061 +aabengali;0986 +aacute;00E1 +aadeva;0906 +aagujarati;0A86 +aagurmukhi;0A06 +aamatragurmukhi;0A3E +aarusquare;3303 +aavowelsignbengali;09BE +aavowelsigndeva;093E +aavowelsigngujarati;0ABE +abbreviationmarkarmenian;055F +abbreviationsigndeva;0970 +abengali;0985 +abopomofo;311A +abreve;0103 +abreveacute;1EAF +abrevecyrillic;04D1 +abrevedotbelow;1EB7 +abrevegrave;1EB1 +abrevehookabove;1EB3 +abrevetilde;1EB5 +acaron;01CE +acircle;24D0 +acircumflex;00E2 +acircumflexacute;1EA5 +acircumflexdotbelow;1EAD +acircumflexgrave;1EA7 +acircumflexhookabove;1EA9 +acircumflextilde;1EAB +acute;00B4 +acutebelowcmb;0317 +acutecmb;0301 +acutecomb;0301 +acutedeva;0954 +acutelowmod;02CF +acutetonecmb;0341 +acyrillic;0430 +adblgrave;0201 +addakgurmukhi;0A71 +adeva;0905 +adieresis;00E4 +adieresiscyrillic;04D3 +adieresismacron;01DF +adotbelow;1EA1 +adotmacron;01E1 +ae;00E6 +aeacute;01FD +aekorean;3150 +aemacron;01E3 +afii00208;2015 +afii08941;20A4 +afii10017;0410 +afii10018;0411 +afii10019;0412 +afii10020;0413 +afii10021;0414 +afii10022;0415 +afii10023;0401 +afii10024;0416 +afii10025;0417 +afii10026;0418 +afii10027;0419 +afii10028;041A +afii10029;041B +afii10030;041C +afii10031;041D +afii10032;041E +afii10033;041F +afii10034;0420 +afii10035;0421 +afii10036;0422 +afii10037;0423 +afii10038;0424 +afii10039;0425 +afii10040;0426 +afii10041;0427 +afii10042;0428 +afii10043;0429 +afii10044;042A +afii10045;042B +afii10046;042C +afii10047;042D +afii10048;042E +afii10049;042F +afii10050;0490 +afii10051;0402 +afii10052;0403 +afii10053;0404 +afii10054;0405 +afii10055;0406 +afii10056;0407 +afii10057;0408 +afii10058;0409 +afii10059;040A +afii10060;040B +afii10061;040C +afii10062;040E +afii10063;F6C4 +afii10064;F6C5 +afii10065;0430 +afii10066;0431 +afii10067;0432 +afii10068;0433 +afii10069;0434 +afii10070;0435 +afii10071;0451 +afii10072;0436 +afii10073;0437 +afii10074;0438 +afii10075;0439 +afii10076;043A +afii10077;043B +afii10078;043C +afii10079;043D +afii10080;043E +afii10081;043F +afii10082;0440 +afii10083;0441 +afii10084;0442 +afii10085;0443 +afii10086;0444 +afii10087;0445 +afii10088;0446 +afii10089;0447 +afii10090;0448 +afii10091;0449 +afii10092;044A +afii10093;044B +afii10094;044C +afii10095;044D +afii10096;044E +afii10097;044F +afii10098;0491 +afii10099;0452 +afii10100;0453 +afii10101;0454 +afii10102;0455 +afii10103;0456 +afii10104;0457 +afii10105;0458 +afii10106;0459 +afii10107;045A +afii10108;045B +afii10109;045C +afii10110;045E +afii10145;040F +afii10146;0462 +afii10147;0472 +afii10148;0474 +afii10192;F6C6 +afii10193;045F +afii10194;0463 +afii10195;0473 +afii10196;0475 +afii10831;F6C7 +afii10832;F6C8 +afii10846;04D9 +afii299;200E +afii300;200F +afii301;200D +afii57381;066A +afii57388;060C +afii57392;0660 +afii57393;0661 +afii57394;0662 +afii57395;0663 +afii57396;0664 +afii57397;0665 +afii57398;0666 +afii57399;0667 +afii57400;0668 +afii57401;0669 +afii57403;061B +afii57407;061F +afii57409;0621 +afii57410;0622 +afii57411;0623 +afii57412;0624 +afii57413;0625 +afii57414;0626 +afii57415;0627 +afii57416;0628 +afii57417;0629 +afii57418;062A +afii57419;062B +afii57420;062C +afii57421;062D +afii57422;062E +afii57423;062F +afii57424;0630 +afii57425;0631 +afii57426;0632 +afii57427;0633 +afii57428;0634 +afii57429;0635 +afii57430;0636 +afii57431;0637 +afii57432;0638 +afii57433;0639 +afii57434;063A +afii57440;0640 +afii57441;0641 +afii57442;0642 +afii57443;0643 +afii57444;0644 +afii57445;0645 +afii57446;0646 +afii57448;0648 +afii57449;0649 +afii57450;064A +afii57451;064B +afii57452;064C +afii57453;064D +afii57454;064E +afii57455;064F +afii57456;0650 +afii57457;0651 +afii57458;0652 +afii57470;0647 +afii57505;06A4 +afii57506;067E +afii57507;0686 +afii57508;0698 +afii57509;06AF +afii57511;0679 +afii57512;0688 +afii57513;0691 +afii57514;06BA +afii57519;06D2 +afii57534;06D5 +afii57636;20AA +afii57645;05BE +afii57658;05C3 +afii57664;05D0 +afii57665;05D1 +afii57666;05D2 +afii57667;05D3 +afii57668;05D4 +afii57669;05D5 +afii57670;05D6 +afii57671;05D7 +afii57672;05D8 +afii57673;05D9 +afii57674;05DA +afii57675;05DB +afii57676;05DC +afii57677;05DD +afii57678;05DE +afii57679;05DF +afii57680;05E0 +afii57681;05E1 +afii57682;05E2 +afii57683;05E3 +afii57684;05E4 +afii57685;05E5 +afii57686;05E6 +afii57687;05E7 +afii57688;05E8 +afii57689;05E9 +afii57690;05EA +afii57694;FB2A +afii57695;FB2B +afii57700;FB4B +afii57705;FB1F +afii57716;05F0 +afii57717;05F1 +afii57718;05F2 +afii57723;FB35 +afii57793;05B4 +afii57794;05B5 +afii57795;05B6 +afii57796;05BB +afii57797;05B8 +afii57798;05B7 +afii57799;05B0 +afii57800;05B2 +afii57801;05B1 +afii57802;05B3 +afii57803;05C2 +afii57804;05C1 +afii57806;05B9 +afii57807;05BC +afii57839;05BD +afii57841;05BF +afii57842;05C0 +afii57929;02BC +afii61248;2105 +afii61289;2113 +afii61352;2116 +afii61573;202C +afii61574;202D +afii61575;202E +afii61664;200C +afii63167;066D +afii64937;02BD +agrave;00E0 +agujarati;0A85 +agurmukhi;0A05 +ahiragana;3042 +ahookabove;1EA3 +aibengali;0990 +aibopomofo;311E +aideva;0910 +aiecyrillic;04D5 +aigujarati;0A90 +aigurmukhi;0A10 +aimatragurmukhi;0A48 +ainarabic;0639 +ainfinalarabic;FECA +aininitialarabic;FECB +ainmedialarabic;FECC +ainvertedbreve;0203 +aivowelsignbengali;09C8 +aivowelsigndeva;0948 +aivowelsigngujarati;0AC8 +akatakana;30A2 +akatakanahalfwidth;FF71 +akorean;314F +alef;05D0 +alefarabic;0627 +alefdageshhebrew;FB30 +aleffinalarabic;FE8E +alefhamzaabovearabic;0623 +alefhamzaabovefinalarabic;FE84 +alefhamzabelowarabic;0625 +alefhamzabelowfinalarabic;FE88 +alefhebrew;05D0 +aleflamedhebrew;FB4F +alefmaddaabovearabic;0622 +alefmaddaabovefinalarabic;FE82 +alefmaksuraarabic;0649 +alefmaksurafinalarabic;FEF0 +alefmaksurainitialarabic;FEF3 +alefmaksuramedialarabic;FEF4 +alefpatahhebrew;FB2E +alefqamatshebrew;FB2F +aleph;2135 +allequal;224C +alpha;03B1 +alphatonos;03AC +amacron;0101 +amonospace;FF41 +ampersand;0026 +ampersandmonospace;FF06 +ampersandsmall;F726 +amsquare;33C2 +anbopomofo;3122 +angbopomofo;3124 +angkhankhuthai;0E5A +angle;2220 +anglebracketleft;3008 +anglebracketleftvertical;FE3F +anglebracketright;3009 +anglebracketrightvertical;FE40 +angleleft;2329 +angleright;232A +angstrom;212B +anoteleia;0387 +anudattadeva;0952 +anusvarabengali;0982 +anusvaradeva;0902 +anusvaragujarati;0A82 +aogonek;0105 +apaatosquare;3300 +aparen;249C +apostrophearmenian;055A +apostrophemod;02BC +apple;F8FF +approaches;2250 +approxequal;2248 +approxequalorimage;2252 +approximatelyequal;2245 +araeaekorean;318E +araeakorean;318D +arc;2312 +arighthalfring;1E9A +aring;00E5 +aringacute;01FB +aringbelow;1E01 +arrowboth;2194 +arrowdashdown;21E3 +arrowdashleft;21E0 +arrowdashright;21E2 +arrowdashup;21E1 +arrowdblboth;21D4 +arrowdbldown;21D3 +arrowdblleft;21D0 +arrowdblright;21D2 +arrowdblup;21D1 +arrowdown;2193 +arrowdownleft;2199 +arrowdownright;2198 +arrowdownwhite;21E9 +arrowheaddownmod;02C5 +arrowheadleftmod;02C2 +arrowheadrightmod;02C3 +arrowheadupmod;02C4 +arrowhorizex;F8E7 +arrowleft;2190 +arrowleftdbl;21D0 +arrowleftdblstroke;21CD +arrowleftoverright;21C6 +arrowleftwhite;21E6 +arrowright;2192 +arrowrightdblstroke;21CF +arrowrightheavy;279E +arrowrightoverleft;21C4 +arrowrightwhite;21E8 +arrowtableft;21E4 +arrowtabright;21E5 +arrowup;2191 +arrowupdn;2195 +arrowupdnbse;21A8 +arrowupdownbase;21A8 +arrowupleft;2196 +arrowupleftofdown;21C5 +arrowupright;2197 +arrowupwhite;21E7 +arrowvertex;F8E6 +asciicircum;005E +asciicircummonospace;FF3E +asciitilde;007E +asciitildemonospace;FF5E +ascript;0251 +ascriptturned;0252 +asmallhiragana;3041 +asmallkatakana;30A1 +asmallkatakanahalfwidth;FF67 +asterisk;002A +asteriskaltonearabic;066D +asteriskarabic;066D +asteriskmath;2217 +asteriskmonospace;FF0A +asterisksmall;FE61 +asterism;2042 +asuperior;F6E9 +asymptoticallyequal;2243 +at;0040 +atilde;00E3 +atmonospace;FF20 +atsmall;FE6B +aturned;0250 +aubengali;0994 +aubopomofo;3120 +audeva;0914 +augujarati;0A94 +augurmukhi;0A14 +aulengthmarkbengali;09D7 +aumatragurmukhi;0A4C +auvowelsignbengali;09CC +auvowelsigndeva;094C +auvowelsigngujarati;0ACC +avagrahadeva;093D +aybarmenian;0561 +ayin;05E2 +ayinaltonehebrew;FB20 +ayinhebrew;05E2 +b;0062 +babengali;09AC +backslash;005C +backslashmonospace;FF3C +badeva;092C +bagujarati;0AAC +bagurmukhi;0A2C +bahiragana;3070 +bahtthai;0E3F +bakatakana;30D0 +bar;007C +barmonospace;FF5C +bbopomofo;3105 +bcircle;24D1 +bdotaccent;1E03 +bdotbelow;1E05 +beamedsixteenthnotes;266C +because;2235 +becyrillic;0431 +beharabic;0628 +behfinalarabic;FE90 +behinitialarabic;FE91 +behiragana;3079 +behmedialarabic;FE92 +behmeeminitialarabic;FC9F +behmeemisolatedarabic;FC08 +behnoonfinalarabic;FC6D +bekatakana;30D9 +benarmenian;0562 +bet;05D1 +beta;03B2 +betasymbolgreek;03D0 +betdagesh;FB31 +betdageshhebrew;FB31 +bethebrew;05D1 +betrafehebrew;FB4C +bhabengali;09AD +bhadeva;092D +bhagujarati;0AAD +bhagurmukhi;0A2D +bhook;0253 +bihiragana;3073 +bikatakana;30D3 +bilabialclick;0298 +bindigurmukhi;0A02 +birusquare;3331 +blackcircle;25CF +blackdiamond;25C6 +blackdownpointingtriangle;25BC +blackleftpointingpointer;25C4 +blackleftpointingtriangle;25C0 +blacklenticularbracketleft;3010 +blacklenticularbracketleftvertical;FE3B +blacklenticularbracketright;3011 +blacklenticularbracketrightvertical;FE3C +blacklowerlefttriangle;25E3 +blacklowerrighttriangle;25E2 +blackrectangle;25AC +blackrightpointingpointer;25BA +blackrightpointingtriangle;25B6 +blacksmallsquare;25AA +blacksmilingface;263B +blacksquare;25A0 +blackstar;2605 +blackupperlefttriangle;25E4 +blackupperrighttriangle;25E5 +blackuppointingsmalltriangle;25B4 +blackuppointingtriangle;25B2 +blank;2423 +blinebelow;1E07 +block;2588 +bmonospace;FF42 +bobaimaithai;0E1A +bohiragana;307C +bokatakana;30DC +bparen;249D +bqsquare;33C3 +braceex;F8F4 +braceleft;007B +braceleftbt;F8F3 +braceleftmid;F8F2 +braceleftmonospace;FF5B +braceleftsmall;FE5B +bracelefttp;F8F1 +braceleftvertical;FE37 +braceright;007D +bracerightbt;F8FE +bracerightmid;F8FD +bracerightmonospace;FF5D +bracerightsmall;FE5C +bracerighttp;F8FC +bracerightvertical;FE38 +bracketleft;005B +bracketleftbt;F8F0 +bracketleftex;F8EF +bracketleftmonospace;FF3B +bracketlefttp;F8EE +bracketright;005D +bracketrightbt;F8FB +bracketrightex;F8FA +bracketrightmonospace;FF3D +bracketrighttp;F8F9 +breve;02D8 +brevebelowcmb;032E +brevecmb;0306 +breveinvertedbelowcmb;032F +breveinvertedcmb;0311 +breveinverteddoublecmb;0361 +bridgebelowcmb;032A +bridgeinvertedbelowcmb;033A +brokenbar;00A6 +bstroke;0180 +bsuperior;F6EA +btopbar;0183 +buhiragana;3076 +bukatakana;30D6 +bullet;2022 +bulletinverse;25D8 +bulletoperator;2219 +bullseye;25CE +c;0063 +caarmenian;056E +cabengali;099A +cacute;0107 +cadeva;091A +cagujarati;0A9A +cagurmukhi;0A1A +calsquare;3388 +candrabindubengali;0981 +candrabinducmb;0310 +candrabindudeva;0901 +candrabindugujarati;0A81 +capslock;21EA +careof;2105 +caron;02C7 +caronbelowcmb;032C +caroncmb;030C +carriagereturn;21B5 +cbopomofo;3118 +ccaron;010D +ccedilla;00E7 +ccedillaacute;1E09 +ccircle;24D2 +ccircumflex;0109 +ccurl;0255 +cdot;010B +cdotaccent;010B +cdsquare;33C5 +cedilla;00B8 +cedillacmb;0327 +cent;00A2 +centigrade;2103 +centinferior;F6DF +centmonospace;FFE0 +centoldstyle;F7A2 +centsuperior;F6E0 +chaarmenian;0579 +chabengali;099B +chadeva;091B +chagujarati;0A9B +chagurmukhi;0A1B +chbopomofo;3114 +cheabkhasiancyrillic;04BD +checkmark;2713 +checyrillic;0447 +chedescenderabkhasiancyrillic;04BF +chedescendercyrillic;04B7 +chedieresiscyrillic;04F5 +cheharmenian;0573 +chekhakassiancyrillic;04CC +cheverticalstrokecyrillic;04B9 +chi;03C7 +chieuchacirclekorean;3277 +chieuchaparenkorean;3217 +chieuchcirclekorean;3269 +chieuchkorean;314A +chieuchparenkorean;3209 +chochangthai;0E0A +chochanthai;0E08 +chochingthai;0E09 +chochoethai;0E0C +chook;0188 +cieucacirclekorean;3276 +cieucaparenkorean;3216 +cieuccirclekorean;3268 +cieuckorean;3148 +cieucparenkorean;3208 +cieucuparenkorean;321C +circle;25CB +circlemultiply;2297 +circleot;2299 +circleplus;2295 +circlepostalmark;3036 +circlewithlefthalfblack;25D0 +circlewithrighthalfblack;25D1 +circumflex;02C6 +circumflexbelowcmb;032D +circumflexcmb;0302 +clear;2327 +clickalveolar;01C2 +clickdental;01C0 +clicklateral;01C1 +clickretroflex;01C3 +club;2663 +clubsuitblack;2663 +clubsuitwhite;2667 +cmcubedsquare;33A4 +cmonospace;FF43 +cmsquaredsquare;33A0 +coarmenian;0581 +colon;003A +colonmonetary;20A1 +colonmonospace;FF1A +colonsign;20A1 +colonsmall;FE55 +colontriangularhalfmod;02D1 +colontriangularmod;02D0 +comma;002C +commaabovecmb;0313 +commaaboverightcmb;0315 +commaaccent;F6C3 +commaarabic;060C +commaarmenian;055D +commainferior;F6E1 +commamonospace;FF0C +commareversedabovecmb;0314 +commareversedmod;02BD +commasmall;FE50 +commasuperior;F6E2 +commaturnedabovecmb;0312 +commaturnedmod;02BB +compass;263C +congruent;2245 +contourintegral;222E +control;2303 +controlACK;0006 +controlBEL;0007 +controlBS;0008 +controlCAN;0018 +controlCR;000D +controlDC1;0011 +controlDC2;0012 +controlDC3;0013 +controlDC4;0014 +controlDEL;007F +controlDLE;0010 +controlEM;0019 +controlENQ;0005 +controlEOT;0004 +controlESC;001B +controlETB;0017 +controlETX;0003 +controlFF;000C +controlFS;001C +controlGS;001D +controlHT;0009 +controlLF;000A +controlNAK;0015 +controlRS;001E +controlSI;000F +controlSO;000E +controlSOT;0002 +controlSTX;0001 +controlSUB;001A +controlSYN;0016 +controlUS;001F +controlVT;000B +copyright;00A9 +copyrightsans;F8E9 +copyrightserif;F6D9 +cornerbracketleft;300C +cornerbracketlefthalfwidth;FF62 +cornerbracketleftvertical;FE41 +cornerbracketright;300D +cornerbracketrighthalfwidth;FF63 +cornerbracketrightvertical;FE42 +corporationsquare;337F +cosquare;33C7 +coverkgsquare;33C6 +cparen;249E +cruzeiro;20A2 +cstretched;0297 +curlyand;22CF +curlyor;22CE +currency;00A4 +cyrBreve;F6D1 +cyrFlex;F6D2 +cyrbreve;F6D4 +cyrflex;F6D5 +d;0064 +daarmenian;0564 +dabengali;09A6 +dadarabic;0636 +dadeva;0926 +dadfinalarabic;FEBE +dadinitialarabic;FEBF +dadmedialarabic;FEC0 +dagesh;05BC +dageshhebrew;05BC +dagger;2020 +daggerdbl;2021 +dagujarati;0AA6 +dagurmukhi;0A26 +dahiragana;3060 +dakatakana;30C0 +dalarabic;062F +dalet;05D3 +daletdagesh;FB33 +daletdageshhebrew;FB33 +dalethatafpatah;05D3 05B2 +dalethatafpatahhebrew;05D3 05B2 +dalethatafsegol;05D3 05B1 +dalethatafsegolhebrew;05D3 05B1 +dalethebrew;05D3 +dalethiriq;05D3 05B4 +dalethiriqhebrew;05D3 05B4 +daletholam;05D3 05B9 +daletholamhebrew;05D3 05B9 +daletpatah;05D3 05B7 +daletpatahhebrew;05D3 05B7 +daletqamats;05D3 05B8 +daletqamatshebrew;05D3 05B8 +daletqubuts;05D3 05BB +daletqubutshebrew;05D3 05BB +daletsegol;05D3 05B6 +daletsegolhebrew;05D3 05B6 +daletsheva;05D3 05B0 +daletshevahebrew;05D3 05B0 +dalettsere;05D3 05B5 +dalettserehebrew;05D3 05B5 +dalfinalarabic;FEAA +dammaarabic;064F +dammalowarabic;064F +dammatanaltonearabic;064C +dammatanarabic;064C +danda;0964 +dargahebrew;05A7 +dargalefthebrew;05A7 +dasiapneumatacyrilliccmb;0485 +dblGrave;F6D3 +dblanglebracketleft;300A +dblanglebracketleftvertical;FE3D +dblanglebracketright;300B +dblanglebracketrightvertical;FE3E +dblarchinvertedbelowcmb;032B +dblarrowleft;21D4 +dblarrowright;21D2 +dbldanda;0965 +dblgrave;F6D6 +dblgravecmb;030F +dblintegral;222C +dbllowline;2017 +dbllowlinecmb;0333 +dbloverlinecmb;033F +dblprimemod;02BA +dblverticalbar;2016 +dblverticallineabovecmb;030E +dbopomofo;3109 +dbsquare;33C8 +dcaron;010F +dcedilla;1E11 +dcircle;24D3 +dcircumflexbelow;1E13 +dcroat;0111 +ddabengali;09A1 +ddadeva;0921 +ddagujarati;0AA1 +ddagurmukhi;0A21 +ddalarabic;0688 +ddalfinalarabic;FB89 +dddhadeva;095C +ddhabengali;09A2 +ddhadeva;0922 +ddhagujarati;0AA2 +ddhagurmukhi;0A22 +ddotaccent;1E0B +ddotbelow;1E0D +decimalseparatorarabic;066B +decimalseparatorpersian;066B +decyrillic;0434 +degree;00B0 +dehihebrew;05AD +dehiragana;3067 +deicoptic;03EF +dekatakana;30C7 +deleteleft;232B +deleteright;2326 +delta;03B4 +deltaturned;018D +denominatorminusonenumeratorbengali;09F8 +dezh;02A4 +dhabengali;09A7 +dhadeva;0927 +dhagujarati;0AA7 +dhagurmukhi;0A27 +dhook;0257 +dialytikatonos;0385 +dialytikatonoscmb;0344 +diamond;2666 +diamondsuitwhite;2662 +dieresis;00A8 +dieresisacute;F6D7 +dieresisbelowcmb;0324 +dieresiscmb;0308 +dieresisgrave;F6D8 +dieresistonos;0385 +dihiragana;3062 +dikatakana;30C2 +dittomark;3003 +divide;00F7 +divides;2223 +divisionslash;2215 +djecyrillic;0452 +dkshade;2593 +dlinebelow;1E0F +dlsquare;3397 +dmacron;0111 +dmonospace;FF44 +dnblock;2584 +dochadathai;0E0E +dodekthai;0E14 +dohiragana;3069 +dokatakana;30C9 +dollar;0024 +dollarinferior;F6E3 +dollarmonospace;FF04 +dollaroldstyle;F724 +dollarsmall;FE69 +dollarsuperior;F6E4 +dong;20AB +dorusquare;3326 +dotaccent;02D9 +dotaccentcmb;0307 +dotbelowcmb;0323 +dotbelowcomb;0323 +dotkatakana;30FB +dotlessi;0131 +dotlessj;F6BE +dotlessjstrokehook;0284 +dotmath;22C5 +dottedcircle;25CC +doubleyodpatah;FB1F +doubleyodpatahhebrew;FB1F +downtackbelowcmb;031E +downtackmod;02D5 +dparen;249F +dsuperior;F6EB +dtail;0256 +dtopbar;018C +duhiragana;3065 +dukatakana;30C5 +dz;01F3 +dzaltone;02A3 +dzcaron;01C6 +dzcurl;02A5 +dzeabkhasiancyrillic;04E1 +dzecyrillic;0455 +dzhecyrillic;045F +e;0065 +eacute;00E9 +earth;2641 +ebengali;098F +ebopomofo;311C +ebreve;0115 +ecandradeva;090D +ecandragujarati;0A8D +ecandravowelsigndeva;0945 +ecandravowelsigngujarati;0AC5 +ecaron;011B +ecedillabreve;1E1D +echarmenian;0565 +echyiwnarmenian;0587 +ecircle;24D4 +ecircumflex;00EA +ecircumflexacute;1EBF +ecircumflexbelow;1E19 +ecircumflexdotbelow;1EC7 +ecircumflexgrave;1EC1 +ecircumflexhookabove;1EC3 +ecircumflextilde;1EC5 +ecyrillic;0454 +edblgrave;0205 +edeva;090F +edieresis;00EB +edot;0117 +edotaccent;0117 +edotbelow;1EB9 +eegurmukhi;0A0F +eematragurmukhi;0A47 +efcyrillic;0444 +egrave;00E8 +egujarati;0A8F +eharmenian;0567 +ehbopomofo;311D +ehiragana;3048 +ehookabove;1EBB +eibopomofo;311F +eight;0038 +eightarabic;0668 +eightbengali;09EE +eightcircle;2467 +eightcircleinversesansserif;2791 +eightdeva;096E +eighteencircle;2471 +eighteenparen;2485 +eighteenperiod;2499 +eightgujarati;0AEE +eightgurmukhi;0A6E +eighthackarabic;0668 +eighthangzhou;3028 +eighthnotebeamed;266B +eightideographicparen;3227 +eightinferior;2088 +eightmonospace;FF18 +eightoldstyle;F738 +eightparen;247B +eightperiod;248F +eightpersian;06F8 +eightroman;2177 +eightsuperior;2078 +eightthai;0E58 +einvertedbreve;0207 +eiotifiedcyrillic;0465 +ekatakana;30A8 +ekatakanahalfwidth;FF74 +ekonkargurmukhi;0A74 +ekorean;3154 +elcyrillic;043B +element;2208 +elevencircle;246A +elevenparen;247E +elevenperiod;2492 +elevenroman;217A +ellipsis;2026 +ellipsisvertical;22EE +emacron;0113 +emacronacute;1E17 +emacrongrave;1E15 +emcyrillic;043C +emdash;2014 +emdashvertical;FE31 +emonospace;FF45 +emphasismarkarmenian;055B +emptyset;2205 +enbopomofo;3123 +encyrillic;043D +endash;2013 +endashvertical;FE32 +endescendercyrillic;04A3 +eng;014B +engbopomofo;3125 +enghecyrillic;04A5 +enhookcyrillic;04C8 +enspace;2002 +eogonek;0119 +eokorean;3153 +eopen;025B +eopenclosed;029A +eopenreversed;025C +eopenreversedclosed;025E +eopenreversedhook;025D +eparen;24A0 +epsilon;03B5 +epsilontonos;03AD +equal;003D +equalmonospace;FF1D +equalsmall;FE66 +equalsuperior;207C +equivalence;2261 +erbopomofo;3126 +ercyrillic;0440 +ereversed;0258 +ereversedcyrillic;044D +escyrillic;0441 +esdescendercyrillic;04AB +esh;0283 +eshcurl;0286 +eshortdeva;090E +eshortvowelsigndeva;0946 +eshreversedloop;01AA +eshsquatreversed;0285 +esmallhiragana;3047 +esmallkatakana;30A7 +esmallkatakanahalfwidth;FF6A +estimated;212E +esuperior;F6EC +eta;03B7 +etarmenian;0568 +etatonos;03AE +eth;00F0 +etilde;1EBD +etildebelow;1E1B +etnahtafoukhhebrew;0591 +etnahtafoukhlefthebrew;0591 +etnahtahebrew;0591 +etnahtalefthebrew;0591 +eturned;01DD +eukorean;3161 +euro;20AC +evowelsignbengali;09C7 +evowelsigndeva;0947 +evowelsigngujarati;0AC7 +exclam;0021 +exclamarmenian;055C +exclamdbl;203C +exclamdown;00A1 +exclamdownsmall;F7A1 +exclammonospace;FF01 +exclamsmall;F721 +existential;2203 +ezh;0292 +ezhcaron;01EF +ezhcurl;0293 +ezhreversed;01B9 +ezhtail;01BA +f;0066 +fadeva;095E +fagurmukhi;0A5E +fahrenheit;2109 +fathaarabic;064E +fathalowarabic;064E +fathatanarabic;064B +fbopomofo;3108 +fcircle;24D5 +fdotaccent;1E1F +feharabic;0641 +feharmenian;0586 +fehfinalarabic;FED2 +fehinitialarabic;FED3 +fehmedialarabic;FED4 +feicoptic;03E5 +female;2640 +ff;FB00 +ffi;FB03 +ffl;FB04 +fi;FB01 +fifteencircle;246E +fifteenparen;2482 +fifteenperiod;2496 +figuredash;2012 +filledbox;25A0 +filledrect;25AC +finalkaf;05DA +finalkafdagesh;FB3A +finalkafdageshhebrew;FB3A +finalkafhebrew;05DA +finalkafqamats;05DA 05B8 +finalkafqamatshebrew;05DA 05B8 +finalkafsheva;05DA 05B0 +finalkafshevahebrew;05DA 05B0 +finalmem;05DD +finalmemhebrew;05DD +finalnun;05DF +finalnunhebrew;05DF +finalpe;05E3 +finalpehebrew;05E3 +finaltsadi;05E5 +finaltsadihebrew;05E5 +firsttonechinese;02C9 +fisheye;25C9 +fitacyrillic;0473 +five;0035 +fivearabic;0665 +fivebengali;09EB +fivecircle;2464 +fivecircleinversesansserif;278E +fivedeva;096B +fiveeighths;215D +fivegujarati;0AEB +fivegurmukhi;0A6B +fivehackarabic;0665 +fivehangzhou;3025 +fiveideographicparen;3224 +fiveinferior;2085 +fivemonospace;FF15 +fiveoldstyle;F735 +fiveparen;2478 +fiveperiod;248C +fivepersian;06F5 +fiveroman;2174 +fivesuperior;2075 +fivethai;0E55 +fl;FB02 +florin;0192 +fmonospace;FF46 +fmsquare;3399 +fofanthai;0E1F +fofathai;0E1D +fongmanthai;0E4F +forall;2200 +four;0034 +fourarabic;0664 +fourbengali;09EA +fourcircle;2463 +fourcircleinversesansserif;278D +fourdeva;096A +fourgujarati;0AEA +fourgurmukhi;0A6A +fourhackarabic;0664 +fourhangzhou;3024 +fourideographicparen;3223 +fourinferior;2084 +fourmonospace;FF14 +fournumeratorbengali;09F7 +fouroldstyle;F734 +fourparen;2477 +fourperiod;248B +fourpersian;06F4 +fourroman;2173 +foursuperior;2074 +fourteencircle;246D +fourteenparen;2481 +fourteenperiod;2495 +fourthai;0E54 +fourthtonechinese;02CB +fparen;24A1 +fraction;2044 +franc;20A3 +g;0067 +gabengali;0997 +gacute;01F5 +gadeva;0917 +gafarabic;06AF +gaffinalarabic;FB93 +gafinitialarabic;FB94 +gafmedialarabic;FB95 +gagujarati;0A97 +gagurmukhi;0A17 +gahiragana;304C +gakatakana;30AC +gamma;03B3 +gammalatinsmall;0263 +gammasuperior;02E0 +gangiacoptic;03EB +gbopomofo;310D +gbreve;011F +gcaron;01E7 +gcedilla;0123 +gcircle;24D6 +gcircumflex;011D +gcommaaccent;0123 +gdot;0121 +gdotaccent;0121 +gecyrillic;0433 +gehiragana;3052 +gekatakana;30B2 +geometricallyequal;2251 +gereshaccenthebrew;059C +gereshhebrew;05F3 +gereshmuqdamhebrew;059D +germandbls;00DF +gershayimaccenthebrew;059E +gershayimhebrew;05F4 +getamark;3013 +ghabengali;0998 +ghadarmenian;0572 +ghadeva;0918 +ghagujarati;0A98 +ghagurmukhi;0A18 +ghainarabic;063A +ghainfinalarabic;FECE +ghaininitialarabic;FECF +ghainmedialarabic;FED0 +ghemiddlehookcyrillic;0495 +ghestrokecyrillic;0493 +gheupturncyrillic;0491 +ghhadeva;095A +ghhagurmukhi;0A5A +ghook;0260 +ghzsquare;3393 +gihiragana;304E +gikatakana;30AE +gimarmenian;0563 +gimel;05D2 +gimeldagesh;FB32 +gimeldageshhebrew;FB32 +gimelhebrew;05D2 +gjecyrillic;0453 +glottalinvertedstroke;01BE +glottalstop;0294 +glottalstopinverted;0296 +glottalstopmod;02C0 +glottalstopreversed;0295 +glottalstopreversedmod;02C1 +glottalstopreversedsuperior;02E4 +glottalstopstroke;02A1 +glottalstopstrokereversed;02A2 +gmacron;1E21 +gmonospace;FF47 +gohiragana;3054 +gokatakana;30B4 +gparen;24A2 +gpasquare;33AC +gradient;2207 +grave;0060 +gravebelowcmb;0316 +gravecmb;0300 +gravecomb;0300 +gravedeva;0953 +gravelowmod;02CE +gravemonospace;FF40 +gravetonecmb;0340 +greater;003E +greaterequal;2265 +greaterequalorless;22DB +greatermonospace;FF1E +greaterorequivalent;2273 +greaterorless;2277 +greateroverequal;2267 +greatersmall;FE65 +gscript;0261 +gstroke;01E5 +guhiragana;3050 +guillemotleft;00AB +guillemotright;00BB +guilsinglleft;2039 +guilsinglright;203A +gukatakana;30B0 +guramusquare;3318 +gysquare;33C9 +h;0068 +haabkhasiancyrillic;04A9 +haaltonearabic;06C1 +habengali;09B9 +hadescendercyrillic;04B3 +hadeva;0939 +hagujarati;0AB9 +hagurmukhi;0A39 +haharabic;062D +hahfinalarabic;FEA2 +hahinitialarabic;FEA3 +hahiragana;306F +hahmedialarabic;FEA4 +haitusquare;332A +hakatakana;30CF +hakatakanahalfwidth;FF8A +halantgurmukhi;0A4D +hamzaarabic;0621 +hamzadammaarabic;0621 064F +hamzadammatanarabic;0621 064C +hamzafathaarabic;0621 064E +hamzafathatanarabic;0621 064B +hamzalowarabic;0621 +hamzalowkasraarabic;0621 0650 +hamzalowkasratanarabic;0621 064D +hamzasukunarabic;0621 0652 +hangulfiller;3164 +hardsigncyrillic;044A +harpoonleftbarbup;21BC +harpoonrightbarbup;21C0 +hasquare;33CA +hatafpatah;05B2 +hatafpatah16;05B2 +hatafpatah23;05B2 +hatafpatah2f;05B2 +hatafpatahhebrew;05B2 +hatafpatahnarrowhebrew;05B2 +hatafpatahquarterhebrew;05B2 +hatafpatahwidehebrew;05B2 +hatafqamats;05B3 +hatafqamats1b;05B3 +hatafqamats28;05B3 +hatafqamats34;05B3 +hatafqamatshebrew;05B3 +hatafqamatsnarrowhebrew;05B3 +hatafqamatsquarterhebrew;05B3 +hatafqamatswidehebrew;05B3 +hatafsegol;05B1 +hatafsegol17;05B1 +hatafsegol24;05B1 +hatafsegol30;05B1 +hatafsegolhebrew;05B1 +hatafsegolnarrowhebrew;05B1 +hatafsegolquarterhebrew;05B1 +hatafsegolwidehebrew;05B1 +hbar;0127 +hbopomofo;310F +hbrevebelow;1E2B +hcedilla;1E29 +hcircle;24D7 +hcircumflex;0125 +hdieresis;1E27 +hdotaccent;1E23 +hdotbelow;1E25 +he;05D4 +heart;2665 +heartsuitblack;2665 +heartsuitwhite;2661 +hedagesh;FB34 +hedageshhebrew;FB34 +hehaltonearabic;06C1 +heharabic;0647 +hehebrew;05D4 +hehfinalaltonearabic;FBA7 +hehfinalalttwoarabic;FEEA +hehfinalarabic;FEEA +hehhamzaabovefinalarabic;FBA5 +hehhamzaaboveisolatedarabic;FBA4 +hehinitialaltonearabic;FBA8 +hehinitialarabic;FEEB +hehiragana;3078 +hehmedialaltonearabic;FBA9 +hehmedialarabic;FEEC +heiseierasquare;337B +hekatakana;30D8 +hekatakanahalfwidth;FF8D +hekutaarusquare;3336 +henghook;0267 +herutusquare;3339 +het;05D7 +hethebrew;05D7 +hhook;0266 +hhooksuperior;02B1 +hieuhacirclekorean;327B +hieuhaparenkorean;321B +hieuhcirclekorean;326D +hieuhkorean;314E +hieuhparenkorean;320D +hihiragana;3072 +hikatakana;30D2 +hikatakanahalfwidth;FF8B +hiriq;05B4 +hiriq14;05B4 +hiriq21;05B4 +hiriq2d;05B4 +hiriqhebrew;05B4 +hiriqnarrowhebrew;05B4 +hiriqquarterhebrew;05B4 +hiriqwidehebrew;05B4 +hlinebelow;1E96 +hmonospace;FF48 +hoarmenian;0570 +hohipthai;0E2B +hohiragana;307B +hokatakana;30DB +hokatakanahalfwidth;FF8E +holam;05B9 +holam19;05B9 +holam26;05B9 +holam32;05B9 +holamhebrew;05B9 +holamnarrowhebrew;05B9 +holamquarterhebrew;05B9 +holamwidehebrew;05B9 +honokhukthai;0E2E +hookabovecomb;0309 +hookcmb;0309 +hookpalatalizedbelowcmb;0321 +hookretroflexbelowcmb;0322 +hoonsquare;3342 +horicoptic;03E9 +horizontalbar;2015 +horncmb;031B +hotsprings;2668 +house;2302 +hparen;24A3 +hsuperior;02B0 +hturned;0265 +huhiragana;3075 +huiitosquare;3333 +hukatakana;30D5 +hukatakanahalfwidth;FF8C +hungarumlaut;02DD +hungarumlautcmb;030B +hv;0195 +hyphen;002D +hypheninferior;F6E5 +hyphenmonospace;FF0D +hyphensmall;FE63 +hyphensuperior;F6E6 +hyphentwo;2010 +i;0069 +iacute;00ED +iacyrillic;044F +ibengali;0987 +ibopomofo;3127 +ibreve;012D +icaron;01D0 +icircle;24D8 +icircumflex;00EE +icyrillic;0456 +idblgrave;0209 +ideographearthcircle;328F +ideographfirecircle;328B +ideographicallianceparen;323F +ideographiccallparen;323A +ideographiccentrecircle;32A5 +ideographicclose;3006 +ideographiccomma;3001 +ideographiccommaleft;FF64 +ideographiccongratulationparen;3237 +ideographiccorrectcircle;32A3 +ideographicearthparen;322F +ideographicenterpriseparen;323D +ideographicexcellentcircle;329D +ideographicfestivalparen;3240 +ideographicfinancialcircle;3296 +ideographicfinancialparen;3236 +ideographicfireparen;322B +ideographichaveparen;3232 +ideographichighcircle;32A4 +ideographiciterationmark;3005 +ideographiclaborcircle;3298 +ideographiclaborparen;3238 +ideographicleftcircle;32A7 +ideographiclowcircle;32A6 +ideographicmedicinecircle;32A9 +ideographicmetalparen;322E +ideographicmoonparen;322A +ideographicnameparen;3234 +ideographicperiod;3002 +ideographicprintcircle;329E +ideographicreachparen;3243 +ideographicrepresentparen;3239 +ideographicresourceparen;323E +ideographicrightcircle;32A8 +ideographicsecretcircle;3299 +ideographicselfparen;3242 +ideographicsocietyparen;3233 +ideographicspace;3000 +ideographicspecialparen;3235 +ideographicstockparen;3231 +ideographicstudyparen;323B +ideographicsunparen;3230 +ideographicsuperviseparen;323C +ideographicwaterparen;322C +ideographicwoodparen;322D +ideographiczero;3007 +ideographmetalcircle;328E +ideographmooncircle;328A +ideographnamecircle;3294 +ideographsuncircle;3290 +ideographwatercircle;328C +ideographwoodcircle;328D +ideva;0907 +idieresis;00EF +idieresisacute;1E2F +idieresiscyrillic;04E5 +idotbelow;1ECB +iebrevecyrillic;04D7 +iecyrillic;0435 +ieungacirclekorean;3275 +ieungaparenkorean;3215 +ieungcirclekorean;3267 +ieungkorean;3147 +ieungparenkorean;3207 +igrave;00EC +igujarati;0A87 +igurmukhi;0A07 +ihiragana;3044 +ihookabove;1EC9 +iibengali;0988 +iicyrillic;0438 +iideva;0908 +iigujarati;0A88 +iigurmukhi;0A08 +iimatragurmukhi;0A40 +iinvertedbreve;020B +iishortcyrillic;0439 +iivowelsignbengali;09C0 +iivowelsigndeva;0940 +iivowelsigngujarati;0AC0 +ij;0133 +ikatakana;30A4 +ikatakanahalfwidth;FF72 +ikorean;3163 +ilde;02DC +iluyhebrew;05AC +imacron;012B +imacroncyrillic;04E3 +imageorapproximatelyequal;2253 +imatragurmukhi;0A3F +imonospace;FF49 +increment;2206 +infinity;221E +iniarmenian;056B +integral;222B +integralbottom;2321 +integralbt;2321 +integralex;F8F5 +integraltop;2320 +integraltp;2320 +intersection;2229 +intisquare;3305 +invbullet;25D8 +invcircle;25D9 +invsmileface;263B +iocyrillic;0451 +iogonek;012F +iota;03B9 +iotadieresis;03CA +iotadieresistonos;0390 +iotalatin;0269 +iotatonos;03AF +iparen;24A4 +irigurmukhi;0A72 +ismallhiragana;3043 +ismallkatakana;30A3 +ismallkatakanahalfwidth;FF68 +issharbengali;09FA +istroke;0268 +isuperior;F6ED +iterationhiragana;309D +iterationkatakana;30FD +itilde;0129 +itildebelow;1E2D +iubopomofo;3129 +iucyrillic;044E +ivowelsignbengali;09BF +ivowelsigndeva;093F +ivowelsigngujarati;0ABF +izhitsacyrillic;0475 +izhitsadblgravecyrillic;0477 +j;006A +jaarmenian;0571 +jabengali;099C +jadeva;091C +jagujarati;0A9C +jagurmukhi;0A1C +jbopomofo;3110 +jcaron;01F0 +jcircle;24D9 +jcircumflex;0135 +jcrossedtail;029D +jdotlessstroke;025F +jecyrillic;0458 +jeemarabic;062C +jeemfinalarabic;FE9E +jeeminitialarabic;FE9F +jeemmedialarabic;FEA0 +jeharabic;0698 +jehfinalarabic;FB8B +jhabengali;099D +jhadeva;091D +jhagujarati;0A9D +jhagurmukhi;0A1D +jheharmenian;057B +jis;3004 +jmonospace;FF4A +jparen;24A5 +jsuperior;02B2 +k;006B +kabashkircyrillic;04A1 +kabengali;0995 +kacute;1E31 +kacyrillic;043A +kadescendercyrillic;049B +kadeva;0915 +kaf;05DB +kafarabic;0643 +kafdagesh;FB3B +kafdageshhebrew;FB3B +kaffinalarabic;FEDA +kafhebrew;05DB +kafinitialarabic;FEDB +kafmedialarabic;FEDC +kafrafehebrew;FB4D +kagujarati;0A95 +kagurmukhi;0A15 +kahiragana;304B +kahookcyrillic;04C4 +kakatakana;30AB +kakatakanahalfwidth;FF76 +kappa;03BA +kappasymbolgreek;03F0 +kapyeounmieumkorean;3171 +kapyeounphieuphkorean;3184 +kapyeounpieupkorean;3178 +kapyeounssangpieupkorean;3179 +karoriisquare;330D +kashidaautoarabic;0640 +kashidaautonosidebearingarabic;0640 +kasmallkatakana;30F5 +kasquare;3384 +kasraarabic;0650 +kasratanarabic;064D +kastrokecyrillic;049F +katahiraprolongmarkhalfwidth;FF70 +kaverticalstrokecyrillic;049D +kbopomofo;310E +kcalsquare;3389 +kcaron;01E9 +kcedilla;0137 +kcircle;24DA +kcommaaccent;0137 +kdotbelow;1E33 +keharmenian;0584 +kehiragana;3051 +kekatakana;30B1 +kekatakanahalfwidth;FF79 +kenarmenian;056F +kesmallkatakana;30F6 +kgreenlandic;0138 +khabengali;0996 +khacyrillic;0445 +khadeva;0916 +khagujarati;0A96 +khagurmukhi;0A16 +khaharabic;062E +khahfinalarabic;FEA6 +khahinitialarabic;FEA7 +khahmedialarabic;FEA8 +kheicoptic;03E7 +khhadeva;0959 +khhagurmukhi;0A59 +khieukhacirclekorean;3278 +khieukhaparenkorean;3218 +khieukhcirclekorean;326A +khieukhkorean;314B +khieukhparenkorean;320A +khokhaithai;0E02 +khokhonthai;0E05 +khokhuatthai;0E03 +khokhwaithai;0E04 +khomutthai;0E5B +khook;0199 +khorakhangthai;0E06 +khzsquare;3391 +kihiragana;304D +kikatakana;30AD +kikatakanahalfwidth;FF77 +kiroguramusquare;3315 +kiromeetorusquare;3316 +kirosquare;3314 +kiyeokacirclekorean;326E +kiyeokaparenkorean;320E +kiyeokcirclekorean;3260 +kiyeokkorean;3131 +kiyeokparenkorean;3200 +kiyeoksioskorean;3133 +kjecyrillic;045C +klinebelow;1E35 +klsquare;3398 +kmcubedsquare;33A6 +kmonospace;FF4B +kmsquaredsquare;33A2 +kohiragana;3053 +kohmsquare;33C0 +kokaithai;0E01 +kokatakana;30B3 +kokatakanahalfwidth;FF7A +kooposquare;331E +koppacyrillic;0481 +koreanstandardsymbol;327F +koroniscmb;0343 +kparen;24A6 +kpasquare;33AA +ksicyrillic;046F +ktsquare;33CF +kturned;029E +kuhiragana;304F +kukatakana;30AF +kukatakanahalfwidth;FF78 +kvsquare;33B8 +kwsquare;33BE +l;006C +labengali;09B2 +lacute;013A +ladeva;0932 +lagujarati;0AB2 +lagurmukhi;0A32 +lakkhangyaothai;0E45 +lamaleffinalarabic;FEFC +lamalefhamzaabovefinalarabic;FEF8 +lamalefhamzaaboveisolatedarabic;FEF7 +lamalefhamzabelowfinalarabic;FEFA +lamalefhamzabelowisolatedarabic;FEF9 +lamalefisolatedarabic;FEFB +lamalefmaddaabovefinalarabic;FEF6 +lamalefmaddaaboveisolatedarabic;FEF5 +lamarabic;0644 +lambda;03BB +lambdastroke;019B +lamed;05DC +lameddagesh;FB3C +lameddageshhebrew;FB3C +lamedhebrew;05DC +lamedholam;05DC 05B9 +lamedholamdagesh;05DC 05B9 05BC +lamedholamdageshhebrew;05DC 05B9 05BC +lamedholamhebrew;05DC 05B9 +lamfinalarabic;FEDE +lamhahinitialarabic;FCCA +laminitialarabic;FEDF +lamjeeminitialarabic;FCC9 +lamkhahinitialarabic;FCCB +lamlamhehisolatedarabic;FDF2 +lammedialarabic;FEE0 +lammeemhahinitialarabic;FD88 +lammeeminitialarabic;FCCC +lammeemjeeminitialarabic;FEDF FEE4 FEA0 +lammeemkhahinitialarabic;FEDF FEE4 FEA8 +largecircle;25EF +lbar;019A +lbelt;026C +lbopomofo;310C +lcaron;013E +lcedilla;013C +lcircle;24DB +lcircumflexbelow;1E3D +lcommaaccent;013C +ldot;0140 +ldotaccent;0140 +ldotbelow;1E37 +ldotbelowmacron;1E39 +leftangleabovecmb;031A +lefttackbelowcmb;0318 +less;003C +lessequal;2264 +lessequalorgreater;22DA +lessmonospace;FF1C +lessorequivalent;2272 +lessorgreater;2276 +lessoverequal;2266 +lesssmall;FE64 +lezh;026E +lfblock;258C +lhookretroflex;026D +lira;20A4 +liwnarmenian;056C +lj;01C9 +ljecyrillic;0459 +ll;F6C0 +lladeva;0933 +llagujarati;0AB3 +llinebelow;1E3B +llladeva;0934 +llvocalicbengali;09E1 +llvocalicdeva;0961 +llvocalicvowelsignbengali;09E3 +llvocalicvowelsigndeva;0963 +lmiddletilde;026B +lmonospace;FF4C +lmsquare;33D0 +lochulathai;0E2C +logicaland;2227 +logicalnot;00AC +logicalnotreversed;2310 +logicalor;2228 +lolingthai;0E25 +longs;017F +lowlinecenterline;FE4E +lowlinecmb;0332 +lowlinedashed;FE4D +lozenge;25CA +lparen;24A7 +lslash;0142 +lsquare;2113 +lsuperior;F6EE +ltshade;2591 +luthai;0E26 +lvocalicbengali;098C +lvocalicdeva;090C +lvocalicvowelsignbengali;09E2 +lvocalicvowelsigndeva;0962 +lxsquare;33D3 +m;006D +mabengali;09AE +macron;00AF +macronbelowcmb;0331 +macroncmb;0304 +macronlowmod;02CD +macronmonospace;FFE3 +macute;1E3F +madeva;092E +magujarati;0AAE +magurmukhi;0A2E +mahapakhhebrew;05A4 +mahapakhlefthebrew;05A4 +mahiragana;307E +maichattawalowleftthai;F895 +maichattawalowrightthai;F894 +maichattawathai;0E4B +maichattawaupperleftthai;F893 +maieklowleftthai;F88C +maieklowrightthai;F88B +maiekthai;0E48 +maiekupperleftthai;F88A +maihanakatleftthai;F884 +maihanakatthai;0E31 +maitaikhuleftthai;F889 +maitaikhuthai;0E47 +maitholowleftthai;F88F +maitholowrightthai;F88E +maithothai;0E49 +maithoupperleftthai;F88D +maitrilowleftthai;F892 +maitrilowrightthai;F891 +maitrithai;0E4A +maitriupperleftthai;F890 +maiyamokthai;0E46 +makatakana;30DE +makatakanahalfwidth;FF8F +male;2642 +mansyonsquare;3347 +maqafhebrew;05BE +mars;2642 +masoracirclehebrew;05AF +masquare;3383 +mbopomofo;3107 +mbsquare;33D4 +mcircle;24DC +mcubedsquare;33A5 +mdotaccent;1E41 +mdotbelow;1E43 +meemarabic;0645 +meemfinalarabic;FEE2 +meeminitialarabic;FEE3 +meemmedialarabic;FEE4 +meemmeeminitialarabic;FCD1 +meemmeemisolatedarabic;FC48 +meetorusquare;334D +mehiragana;3081 +meizierasquare;337E +mekatakana;30E1 +mekatakanahalfwidth;FF92 +mem;05DE +memdagesh;FB3E +memdageshhebrew;FB3E +memhebrew;05DE +menarmenian;0574 +merkhahebrew;05A5 +merkhakefulahebrew;05A6 +merkhakefulalefthebrew;05A6 +merkhalefthebrew;05A5 +mhook;0271 +mhzsquare;3392 +middledotkatakanahalfwidth;FF65 +middot;00B7 +mieumacirclekorean;3272 +mieumaparenkorean;3212 +mieumcirclekorean;3264 +mieumkorean;3141 +mieumpansioskorean;3170 +mieumparenkorean;3204 +mieumpieupkorean;316E +mieumsioskorean;316F +mihiragana;307F +mikatakana;30DF +mikatakanahalfwidth;FF90 +minus;2212 +minusbelowcmb;0320 +minuscircle;2296 +minusmod;02D7 +minusplus;2213 +minute;2032 +miribaarusquare;334A +mirisquare;3349 +mlonglegturned;0270 +mlsquare;3396 +mmcubedsquare;33A3 +mmonospace;FF4D +mmsquaredsquare;339F +mohiragana;3082 +mohmsquare;33C1 +mokatakana;30E2 +mokatakanahalfwidth;FF93 +molsquare;33D6 +momathai;0E21 +moverssquare;33A7 +moverssquaredsquare;33A8 +mparen;24A8 +mpasquare;33AB +mssquare;33B3 +msuperior;F6EF +mturned;026F +mu;00B5 +mu1;00B5 +muasquare;3382 +muchgreater;226B +muchless;226A +mufsquare;338C +mugreek;03BC +mugsquare;338D +muhiragana;3080 +mukatakana;30E0 +mukatakanahalfwidth;FF91 +mulsquare;3395 +multiply;00D7 +mumsquare;339B +munahhebrew;05A3 +munahlefthebrew;05A3 +musicalnote;266A +musicalnotedbl;266B +musicflatsign;266D +musicsharpsign;266F +mussquare;33B2 +muvsquare;33B6 +muwsquare;33BC +mvmegasquare;33B9 +mvsquare;33B7 +mwmegasquare;33BF +mwsquare;33BD +n;006E +nabengali;09A8 +nabla;2207 +nacute;0144 +nadeva;0928 +nagujarati;0AA8 +nagurmukhi;0A28 +nahiragana;306A +nakatakana;30CA +nakatakanahalfwidth;FF85 +napostrophe;0149 +nasquare;3381 +nbopomofo;310B +nbspace;00A0 +ncaron;0148 +ncedilla;0146 +ncircle;24DD +ncircumflexbelow;1E4B +ncommaaccent;0146 +ndotaccent;1E45 +ndotbelow;1E47 +nehiragana;306D +nekatakana;30CD +nekatakanahalfwidth;FF88 +newsheqelsign;20AA +nfsquare;338B +ngabengali;0999 +ngadeva;0919 +ngagujarati;0A99 +ngagurmukhi;0A19 +ngonguthai;0E07 +nhiragana;3093 +nhookleft;0272 +nhookretroflex;0273 +nieunacirclekorean;326F +nieunaparenkorean;320F +nieuncieuckorean;3135 +nieuncirclekorean;3261 +nieunhieuhkorean;3136 +nieunkorean;3134 +nieunpansioskorean;3168 +nieunparenkorean;3201 +nieunsioskorean;3167 +nieuntikeutkorean;3166 +nihiragana;306B +nikatakana;30CB +nikatakanahalfwidth;FF86 +nikhahitleftthai;F899 +nikhahitthai;0E4D +nine;0039 +ninearabic;0669 +ninebengali;09EF +ninecircle;2468 +ninecircleinversesansserif;2792 +ninedeva;096F +ninegujarati;0AEF +ninegurmukhi;0A6F +ninehackarabic;0669 +ninehangzhou;3029 +nineideographicparen;3228 +nineinferior;2089 +ninemonospace;FF19 +nineoldstyle;F739 +nineparen;247C +nineperiod;2490 +ninepersian;06F9 +nineroman;2178 +ninesuperior;2079 +nineteencircle;2472 +nineteenparen;2486 +nineteenperiod;249A +ninethai;0E59 +nj;01CC +njecyrillic;045A +nkatakana;30F3 +nkatakanahalfwidth;FF9D +nlegrightlong;019E +nlinebelow;1E49 +nmonospace;FF4E +nmsquare;339A +nnabengali;09A3 +nnadeva;0923 +nnagujarati;0AA3 +nnagurmukhi;0A23 +nnnadeva;0929 +nohiragana;306E +nokatakana;30CE +nokatakanahalfwidth;FF89 +nonbreakingspace;00A0 +nonenthai;0E13 +nonuthai;0E19 +noonarabic;0646 +noonfinalarabic;FEE6 +noonghunnaarabic;06BA +noonghunnafinalarabic;FB9F +noonhehinitialarabic;FEE7 FEEC +nooninitialarabic;FEE7 +noonjeeminitialarabic;FCD2 +noonjeemisolatedarabic;FC4B +noonmedialarabic;FEE8 +noonmeeminitialarabic;FCD5 +noonmeemisolatedarabic;FC4E +noonnoonfinalarabic;FC8D +notcontains;220C +notelement;2209 +notelementof;2209 +notequal;2260 +notgreater;226F +notgreaternorequal;2271 +notgreaternorless;2279 +notidentical;2262 +notless;226E +notlessnorequal;2270 +notparallel;2226 +notprecedes;2280 +notsubset;2284 +notsucceeds;2281 +notsuperset;2285 +nowarmenian;0576 +nparen;24A9 +nssquare;33B1 +nsuperior;207F +ntilde;00F1 +nu;03BD +nuhiragana;306C +nukatakana;30CC +nukatakanahalfwidth;FF87 +nuktabengali;09BC +nuktadeva;093C +nuktagujarati;0ABC +nuktagurmukhi;0A3C +numbersign;0023 +numbersignmonospace;FF03 +numbersignsmall;FE5F +numeralsigngreek;0374 +numeralsignlowergreek;0375 +numero;2116 +nun;05E0 +nundagesh;FB40 +nundageshhebrew;FB40 +nunhebrew;05E0 +nvsquare;33B5 +nwsquare;33BB +nyabengali;099E +nyadeva;091E +nyagujarati;0A9E +nyagurmukhi;0A1E +o;006F +oacute;00F3 +oangthai;0E2D +obarred;0275 +obarredcyrillic;04E9 +obarreddieresiscyrillic;04EB +obengali;0993 +obopomofo;311B +obreve;014F +ocandradeva;0911 +ocandragujarati;0A91 +ocandravowelsigndeva;0949 +ocandravowelsigngujarati;0AC9 +ocaron;01D2 +ocircle;24DE +ocircumflex;00F4 +ocircumflexacute;1ED1 +ocircumflexdotbelow;1ED9 +ocircumflexgrave;1ED3 +ocircumflexhookabove;1ED5 +ocircumflextilde;1ED7 +ocyrillic;043E +odblacute;0151 +odblgrave;020D +odeva;0913 +odieresis;00F6 +odieresiscyrillic;04E7 +odotbelow;1ECD +oe;0153 +oekorean;315A +ogonek;02DB +ogonekcmb;0328 +ograve;00F2 +ogujarati;0A93 +oharmenian;0585 +ohiragana;304A +ohookabove;1ECF +ohorn;01A1 +ohornacute;1EDB +ohorndotbelow;1EE3 +ohorngrave;1EDD +ohornhookabove;1EDF +ohorntilde;1EE1 +ohungarumlaut;0151 +oi;01A3 +oinvertedbreve;020F +okatakana;30AA +okatakanahalfwidth;FF75 +okorean;3157 +olehebrew;05AB +omacron;014D +omacronacute;1E53 +omacrongrave;1E51 +omdeva;0950 +omega;03C9 +omega1;03D6 +omegacyrillic;0461 +omegalatinclosed;0277 +omegaroundcyrillic;047B +omegatitlocyrillic;047D +omegatonos;03CE +omgujarati;0AD0 +omicron;03BF +omicrontonos;03CC +omonospace;FF4F +one;0031 +onearabic;0661 +onebengali;09E7 +onecircle;2460 +onecircleinversesansserif;278A +onedeva;0967 +onedotenleader;2024 +oneeighth;215B +onefitted;F6DC +onegujarati;0AE7 +onegurmukhi;0A67 +onehackarabic;0661 +onehalf;00BD +onehangzhou;3021 +oneideographicparen;3220 +oneinferior;2081 +onemonospace;FF11 +onenumeratorbengali;09F4 +oneoldstyle;F731 +oneparen;2474 +oneperiod;2488 +onepersian;06F1 +onequarter;00BC +oneroman;2170 +onesuperior;00B9 +onethai;0E51 +onethird;2153 +oogonek;01EB +oogonekmacron;01ED +oogurmukhi;0A13 +oomatragurmukhi;0A4B +oopen;0254 +oparen;24AA +openbullet;25E6 +option;2325 +ordfeminine;00AA +ordmasculine;00BA +orthogonal;221F +oshortdeva;0912 +oshortvowelsigndeva;094A +oslash;00F8 +oslashacute;01FF +osmallhiragana;3049 +osmallkatakana;30A9 +osmallkatakanahalfwidth;FF6B +ostrokeacute;01FF +osuperior;F6F0 +otcyrillic;047F +otilde;00F5 +otildeacute;1E4D +otildedieresis;1E4F +oubopomofo;3121 +overline;203E +overlinecenterline;FE4A +overlinecmb;0305 +overlinedashed;FE49 +overlinedblwavy;FE4C +overlinewavy;FE4B +overscore;00AF +ovowelsignbengali;09CB +ovowelsigndeva;094B +ovowelsigngujarati;0ACB +p;0070 +paampssquare;3380 +paasentosquare;332B +pabengali;09AA +pacute;1E55 +padeva;092A +pagedown;21DF +pageup;21DE +pagujarati;0AAA +pagurmukhi;0A2A +pahiragana;3071 +paiyannoithai;0E2F +pakatakana;30D1 +palatalizationcyrilliccmb;0484 +palochkacyrillic;04C0 +pansioskorean;317F +paragraph;00B6 +parallel;2225 +parenleft;0028 +parenleftaltonearabic;FD3E +parenleftbt;F8ED +parenleftex;F8EC +parenleftinferior;208D +parenleftmonospace;FF08 +parenleftsmall;FE59 +parenleftsuperior;207D +parenlefttp;F8EB +parenleftvertical;FE35 +parenright;0029 +parenrightaltonearabic;FD3F +parenrightbt;F8F8 +parenrightex;F8F7 +parenrightinferior;208E +parenrightmonospace;FF09 +parenrightsmall;FE5A +parenrightsuperior;207E +parenrighttp;F8F6 +parenrightvertical;FE36 +partialdiff;2202 +paseqhebrew;05C0 +pashtahebrew;0599 +pasquare;33A9 +patah;05B7 +patah11;05B7 +patah1d;05B7 +patah2a;05B7 +patahhebrew;05B7 +patahnarrowhebrew;05B7 +patahquarterhebrew;05B7 +patahwidehebrew;05B7 +pazerhebrew;05A1 +pbopomofo;3106 +pcircle;24DF +pdotaccent;1E57 +pe;05E4 +pecyrillic;043F +pedagesh;FB44 +pedageshhebrew;FB44 +peezisquare;333B +pefinaldageshhebrew;FB43 +peharabic;067E +peharmenian;057A +pehebrew;05E4 +pehfinalarabic;FB57 +pehinitialarabic;FB58 +pehiragana;307A +pehmedialarabic;FB59 +pekatakana;30DA +pemiddlehookcyrillic;04A7 +perafehebrew;FB4E +percent;0025 +percentarabic;066A +percentmonospace;FF05 +percentsmall;FE6A +period;002E +periodarmenian;0589 +periodcentered;00B7 +periodhalfwidth;FF61 +periodinferior;F6E7 +periodmonospace;FF0E +periodsmall;FE52 +periodsuperior;F6E8 +perispomenigreekcmb;0342 +perpendicular;22A5 +perthousand;2030 +peseta;20A7 +pfsquare;338A +phabengali;09AB +phadeva;092B +phagujarati;0AAB +phagurmukhi;0A2B +phi;03C6 +phi1;03D5 +phieuphacirclekorean;327A +phieuphaparenkorean;321A +phieuphcirclekorean;326C +phieuphkorean;314D +phieuphparenkorean;320C +philatin;0278 +phinthuthai;0E3A +phisymbolgreek;03D5 +phook;01A5 +phophanthai;0E1E +phophungthai;0E1C +phosamphaothai;0E20 +pi;03C0 +pieupacirclekorean;3273 +pieupaparenkorean;3213 +pieupcieuckorean;3176 +pieupcirclekorean;3265 +pieupkiyeokkorean;3172 +pieupkorean;3142 +pieupparenkorean;3205 +pieupsioskiyeokkorean;3174 +pieupsioskorean;3144 +pieupsiostikeutkorean;3175 +pieupthieuthkorean;3177 +pieuptikeutkorean;3173 +pihiragana;3074 +pikatakana;30D4 +pisymbolgreek;03D6 +piwrarmenian;0583 +plus;002B +plusbelowcmb;031F +pluscircle;2295 +plusminus;00B1 +plusmod;02D6 +plusmonospace;FF0B +plussmall;FE62 +plussuperior;207A +pmonospace;FF50 +pmsquare;33D8 +pohiragana;307D +pointingindexdownwhite;261F +pointingindexleftwhite;261C +pointingindexrightwhite;261E +pointingindexupwhite;261D +pokatakana;30DD +poplathai;0E1B +postalmark;3012 +postalmarkface;3020 +pparen;24AB +precedes;227A +prescription;211E +primemod;02B9 +primereversed;2035 +product;220F +projective;2305 +prolongedkana;30FC +propellor;2318 +propersubset;2282 +propersuperset;2283 +proportion;2237 +proportional;221D +psi;03C8 +psicyrillic;0471 +psilipneumatacyrilliccmb;0486 +pssquare;33B0 +puhiragana;3077 +pukatakana;30D7 +pvsquare;33B4 +pwsquare;33BA +q;0071 +qadeva;0958 +qadmahebrew;05A8 +qafarabic;0642 +qaffinalarabic;FED6 +qafinitialarabic;FED7 +qafmedialarabic;FED8 +qamats;05B8 +qamats10;05B8 +qamats1a;05B8 +qamats1c;05B8 +qamats27;05B8 +qamats29;05B8 +qamats33;05B8 +qamatsde;05B8 +qamatshebrew;05B8 +qamatsnarrowhebrew;05B8 +qamatsqatanhebrew;05B8 +qamatsqatannarrowhebrew;05B8 +qamatsqatanquarterhebrew;05B8 +qamatsqatanwidehebrew;05B8 +qamatsquarterhebrew;05B8 +qamatswidehebrew;05B8 +qarneyparahebrew;059F +qbopomofo;3111 +qcircle;24E0 +qhook;02A0 +qmonospace;FF51 +qof;05E7 +qofdagesh;FB47 +qofdageshhebrew;FB47 +qofhatafpatah;05E7 05B2 +qofhatafpatahhebrew;05E7 05B2 +qofhatafsegol;05E7 05B1 +qofhatafsegolhebrew;05E7 05B1 +qofhebrew;05E7 +qofhiriq;05E7 05B4 +qofhiriqhebrew;05E7 05B4 +qofholam;05E7 05B9 +qofholamhebrew;05E7 05B9 +qofpatah;05E7 05B7 +qofpatahhebrew;05E7 05B7 +qofqamats;05E7 05B8 +qofqamatshebrew;05E7 05B8 +qofqubuts;05E7 05BB +qofqubutshebrew;05E7 05BB +qofsegol;05E7 05B6 +qofsegolhebrew;05E7 05B6 +qofsheva;05E7 05B0 +qofshevahebrew;05E7 05B0 +qoftsere;05E7 05B5 +qoftserehebrew;05E7 05B5 +qparen;24AC +quarternote;2669 +qubuts;05BB +qubuts18;05BB +qubuts25;05BB +qubuts31;05BB +qubutshebrew;05BB +qubutsnarrowhebrew;05BB +qubutsquarterhebrew;05BB +qubutswidehebrew;05BB +question;003F +questionarabic;061F +questionarmenian;055E +questiondown;00BF +questiondownsmall;F7BF +questiongreek;037E +questionmonospace;FF1F +questionsmall;F73F +quotedbl;0022 +quotedblbase;201E +quotedblleft;201C +quotedblmonospace;FF02 +quotedblprime;301E +quotedblprimereversed;301D +quotedblright;201D +quoteleft;2018 +quoteleftreversed;201B +quotereversed;201B +quoteright;2019 +quoterightn;0149 +quotesinglbase;201A +quotesingle;0027 +quotesinglemonospace;FF07 +r;0072 +raarmenian;057C +rabengali;09B0 +racute;0155 +radeva;0930 +radical;221A +radicalex;F8E5 +radoverssquare;33AE +radoverssquaredsquare;33AF +radsquare;33AD +rafe;05BF +rafehebrew;05BF +ragujarati;0AB0 +ragurmukhi;0A30 +rahiragana;3089 +rakatakana;30E9 +rakatakanahalfwidth;FF97 +ralowerdiagonalbengali;09F1 +ramiddlediagonalbengali;09F0 +ramshorn;0264 +ratio;2236 +rbopomofo;3116 +rcaron;0159 +rcedilla;0157 +rcircle;24E1 +rcommaaccent;0157 +rdblgrave;0211 +rdotaccent;1E59 +rdotbelow;1E5B +rdotbelowmacron;1E5D +referencemark;203B +reflexsubset;2286 +reflexsuperset;2287 +registered;00AE +registersans;F8E8 +registerserif;F6DA +reharabic;0631 +reharmenian;0580 +rehfinalarabic;FEAE +rehiragana;308C +rehyehaleflamarabic;0631 FEF3 FE8E 0644 +rekatakana;30EC +rekatakanahalfwidth;FF9A +resh;05E8 +reshdageshhebrew;FB48 +reshhatafpatah;05E8 05B2 +reshhatafpatahhebrew;05E8 05B2 +reshhatafsegol;05E8 05B1 +reshhatafsegolhebrew;05E8 05B1 +reshhebrew;05E8 +reshhiriq;05E8 05B4 +reshhiriqhebrew;05E8 05B4 +reshholam;05E8 05B9 +reshholamhebrew;05E8 05B9 +reshpatah;05E8 05B7 +reshpatahhebrew;05E8 05B7 +reshqamats;05E8 05B8 +reshqamatshebrew;05E8 05B8 +reshqubuts;05E8 05BB +reshqubutshebrew;05E8 05BB +reshsegol;05E8 05B6 +reshsegolhebrew;05E8 05B6 +reshsheva;05E8 05B0 +reshshevahebrew;05E8 05B0 +reshtsere;05E8 05B5 +reshtserehebrew;05E8 05B5 +reversedtilde;223D +reviahebrew;0597 +reviamugrashhebrew;0597 +revlogicalnot;2310 +rfishhook;027E +rfishhookreversed;027F +rhabengali;09DD +rhadeva;095D +rho;03C1 +rhook;027D +rhookturned;027B +rhookturnedsuperior;02B5 +rhosymbolgreek;03F1 +rhotichookmod;02DE +rieulacirclekorean;3271 +rieulaparenkorean;3211 +rieulcirclekorean;3263 +rieulhieuhkorean;3140 +rieulkiyeokkorean;313A +rieulkiyeoksioskorean;3169 +rieulkorean;3139 +rieulmieumkorean;313B +rieulpansioskorean;316C +rieulparenkorean;3203 +rieulphieuphkorean;313F +rieulpieupkorean;313C +rieulpieupsioskorean;316B +rieulsioskorean;313D +rieulthieuthkorean;313E +rieultikeutkorean;316A +rieulyeorinhieuhkorean;316D +rightangle;221F +righttackbelowcmb;0319 +righttriangle;22BF +rihiragana;308A +rikatakana;30EA +rikatakanahalfwidth;FF98 +ring;02DA +ringbelowcmb;0325 +ringcmb;030A +ringhalfleft;02BF +ringhalfleftarmenian;0559 +ringhalfleftbelowcmb;031C +ringhalfleftcentered;02D3 +ringhalfright;02BE +ringhalfrightbelowcmb;0339 +ringhalfrightcentered;02D2 +rinvertedbreve;0213 +rittorusquare;3351 +rlinebelow;1E5F +rlongleg;027C +rlonglegturned;027A +rmonospace;FF52 +rohiragana;308D +rokatakana;30ED +rokatakanahalfwidth;FF9B +roruathai;0E23 +rparen;24AD +rrabengali;09DC +rradeva;0931 +rragurmukhi;0A5C +rreharabic;0691 +rrehfinalarabic;FB8D +rrvocalicbengali;09E0 +rrvocalicdeva;0960 +rrvocalicgujarati;0AE0 +rrvocalicvowelsignbengali;09C4 +rrvocalicvowelsigndeva;0944 +rrvocalicvowelsigngujarati;0AC4 +rsuperior;F6F1 +rtblock;2590 +rturned;0279 +rturnedsuperior;02B4 +ruhiragana;308B +rukatakana;30EB +rukatakanahalfwidth;FF99 +rupeemarkbengali;09F2 +rupeesignbengali;09F3 +rupiah;F6DD +ruthai;0E24 +rvocalicbengali;098B +rvocalicdeva;090B +rvocalicgujarati;0A8B +rvocalicvowelsignbengali;09C3 +rvocalicvowelsigndeva;0943 +rvocalicvowelsigngujarati;0AC3 +s;0073 +sabengali;09B8 +sacute;015B +sacutedotaccent;1E65 +sadarabic;0635 +sadeva;0938 +sadfinalarabic;FEBA +sadinitialarabic;FEBB +sadmedialarabic;FEBC +sagujarati;0AB8 +sagurmukhi;0A38 +sahiragana;3055 +sakatakana;30B5 +sakatakanahalfwidth;FF7B +sallallahoualayhewasallamarabic;FDFA +samekh;05E1 +samekhdagesh;FB41 +samekhdageshhebrew;FB41 +samekhhebrew;05E1 +saraaathai;0E32 +saraaethai;0E41 +saraaimaimalaithai;0E44 +saraaimaimuanthai;0E43 +saraamthai;0E33 +saraathai;0E30 +saraethai;0E40 +saraiileftthai;F886 +saraiithai;0E35 +saraileftthai;F885 +saraithai;0E34 +saraothai;0E42 +saraueeleftthai;F888 +saraueethai;0E37 +saraueleftthai;F887 +sarauethai;0E36 +sarauthai;0E38 +sarauuthai;0E39 +sbopomofo;3119 +scaron;0161 +scarondotaccent;1E67 +scedilla;015F +schwa;0259 +schwacyrillic;04D9 +schwadieresiscyrillic;04DB +schwahook;025A +scircle;24E2 +scircumflex;015D +scommaaccent;0219 +sdotaccent;1E61 +sdotbelow;1E63 +sdotbelowdotaccent;1E69 +seagullbelowcmb;033C +second;2033 +secondtonechinese;02CA +section;00A7 +seenarabic;0633 +seenfinalarabic;FEB2 +seeninitialarabic;FEB3 +seenmedialarabic;FEB4 +segol;05B6 +segol13;05B6 +segol1f;05B6 +segol2c;05B6 +segolhebrew;05B6 +segolnarrowhebrew;05B6 +segolquarterhebrew;05B6 +segoltahebrew;0592 +segolwidehebrew;05B6 +seharmenian;057D +sehiragana;305B +sekatakana;30BB +sekatakanahalfwidth;FF7E +semicolon;003B +semicolonarabic;061B +semicolonmonospace;FF1B +semicolonsmall;FE54 +semivoicedmarkkana;309C +semivoicedmarkkanahalfwidth;FF9F +sentisquare;3322 +sentosquare;3323 +seven;0037 +sevenarabic;0667 +sevenbengali;09ED +sevencircle;2466 +sevencircleinversesansserif;2790 +sevendeva;096D +seveneighths;215E +sevengujarati;0AED +sevengurmukhi;0A6D +sevenhackarabic;0667 +sevenhangzhou;3027 +sevenideographicparen;3226 +seveninferior;2087 +sevenmonospace;FF17 +sevenoldstyle;F737 +sevenparen;247A +sevenperiod;248E +sevenpersian;06F7 +sevenroman;2176 +sevensuperior;2077 +seventeencircle;2470 +seventeenparen;2484 +seventeenperiod;2498 +seventhai;0E57 +sfthyphen;00AD +shaarmenian;0577 +shabengali;09B6 +shacyrillic;0448 +shaddaarabic;0651 +shaddadammaarabic;FC61 +shaddadammatanarabic;FC5E +shaddafathaarabic;FC60 +shaddafathatanarabic;0651 064B +shaddakasraarabic;FC62 +shaddakasratanarabic;FC5F +shade;2592 +shadedark;2593 +shadelight;2591 +shademedium;2592 +shadeva;0936 +shagujarati;0AB6 +shagurmukhi;0A36 +shalshelethebrew;0593 +shbopomofo;3115 +shchacyrillic;0449 +sheenarabic;0634 +sheenfinalarabic;FEB6 +sheeninitialarabic;FEB7 +sheenmedialarabic;FEB8 +sheicoptic;03E3 +sheqel;20AA +sheqelhebrew;20AA +sheva;05B0 +sheva115;05B0 +sheva15;05B0 +sheva22;05B0 +sheva2e;05B0 +shevahebrew;05B0 +shevanarrowhebrew;05B0 +shevaquarterhebrew;05B0 +shevawidehebrew;05B0 +shhacyrillic;04BB +shimacoptic;03ED +shin;05E9 +shindagesh;FB49 +shindageshhebrew;FB49 +shindageshshindot;FB2C +shindageshshindothebrew;FB2C +shindageshsindot;FB2D +shindageshsindothebrew;FB2D +shindothebrew;05C1 +shinhebrew;05E9 +shinshindot;FB2A +shinshindothebrew;FB2A +shinsindot;FB2B +shinsindothebrew;FB2B +shook;0282 +sigma;03C3 +sigma1;03C2 +sigmafinal;03C2 +sigmalunatesymbolgreek;03F2 +sihiragana;3057 +sikatakana;30B7 +sikatakanahalfwidth;FF7C +siluqhebrew;05BD +siluqlefthebrew;05BD +similar;223C +sindothebrew;05C2 +siosacirclekorean;3274 +siosaparenkorean;3214 +sioscieuckorean;317E +sioscirclekorean;3266 +sioskiyeokkorean;317A +sioskorean;3145 +siosnieunkorean;317B +siosparenkorean;3206 +siospieupkorean;317D +siostikeutkorean;317C +six;0036 +sixarabic;0666 +sixbengali;09EC +sixcircle;2465 +sixcircleinversesansserif;278F +sixdeva;096C +sixgujarati;0AEC +sixgurmukhi;0A6C +sixhackarabic;0666 +sixhangzhou;3026 +sixideographicparen;3225 +sixinferior;2086 +sixmonospace;FF16 +sixoldstyle;F736 +sixparen;2479 +sixperiod;248D +sixpersian;06F6 +sixroman;2175 +sixsuperior;2076 +sixteencircle;246F +sixteencurrencydenominatorbengali;09F9 +sixteenparen;2483 +sixteenperiod;2497 +sixthai;0E56 +slash;002F +slashmonospace;FF0F +slong;017F +slongdotaccent;1E9B +smileface;263A +smonospace;FF53 +sofpasuqhebrew;05C3 +softhyphen;00AD +softsigncyrillic;044C +sohiragana;305D +sokatakana;30BD +sokatakanahalfwidth;FF7F +soliduslongoverlaycmb;0338 +solidusshortoverlaycmb;0337 +sorusithai;0E29 +sosalathai;0E28 +sosothai;0E0B +sosuathai;0E2A +space;0020 +spacehackarabic;0020 +spade;2660 +spadesuitblack;2660 +spadesuitwhite;2664 +sparen;24AE +squarebelowcmb;033B +squarecc;33C4 +squarecm;339D +squarediagonalcrosshatchfill;25A9 +squarehorizontalfill;25A4 +squarekg;338F +squarekm;339E +squarekmcapital;33CE +squareln;33D1 +squarelog;33D2 +squaremg;338E +squaremil;33D5 +squaremm;339C +squaremsquared;33A1 +squareorthogonalcrosshatchfill;25A6 +squareupperlefttolowerrightfill;25A7 +squareupperrighttolowerleftfill;25A8 +squareverticalfill;25A5 +squarewhitewithsmallblack;25A3 +srsquare;33DB +ssabengali;09B7 +ssadeva;0937 +ssagujarati;0AB7 +ssangcieuckorean;3149 +ssanghieuhkorean;3185 +ssangieungkorean;3180 +ssangkiyeokkorean;3132 +ssangnieunkorean;3165 +ssangpieupkorean;3143 +ssangsioskorean;3146 +ssangtikeutkorean;3138 +ssuperior;F6F2 +sterling;00A3 +sterlingmonospace;FFE1 +strokelongoverlaycmb;0336 +strokeshortoverlaycmb;0335 +subset;2282 +subsetnotequal;228A +subsetorequal;2286 +succeeds;227B +suchthat;220B +suhiragana;3059 +sukatakana;30B9 +sukatakanahalfwidth;FF7D +sukunarabic;0652 +summation;2211 +sun;263C +superset;2283 +supersetnotequal;228B +supersetorequal;2287 +svsquare;33DC +syouwaerasquare;337C +t;0074 +tabengali;09A4 +tackdown;22A4 +tackleft;22A3 +tadeva;0924 +tagujarati;0AA4 +tagurmukhi;0A24 +taharabic;0637 +tahfinalarabic;FEC2 +tahinitialarabic;FEC3 +tahiragana;305F +tahmedialarabic;FEC4 +taisyouerasquare;337D +takatakana;30BF +takatakanahalfwidth;FF80 +tatweelarabic;0640 +tau;03C4 +tav;05EA +tavdages;FB4A +tavdagesh;FB4A +tavdageshhebrew;FB4A +tavhebrew;05EA +tbar;0167 +tbopomofo;310A +tcaron;0165 +tccurl;02A8 +tcedilla;0163 +tcheharabic;0686 +tchehfinalarabic;FB7B +tchehinitialarabic;FB7C +tchehmedialarabic;FB7D +tchehmeeminitialarabic;FB7C FEE4 +tcircle;24E3 +tcircumflexbelow;1E71 +tcommaaccent;0163 +tdieresis;1E97 +tdotaccent;1E6B +tdotbelow;1E6D +tecyrillic;0442 +tedescendercyrillic;04AD +teharabic;062A +tehfinalarabic;FE96 +tehhahinitialarabic;FCA2 +tehhahisolatedarabic;FC0C +tehinitialarabic;FE97 +tehiragana;3066 +tehjeeminitialarabic;FCA1 +tehjeemisolatedarabic;FC0B +tehmarbutaarabic;0629 +tehmarbutafinalarabic;FE94 +tehmedialarabic;FE98 +tehmeeminitialarabic;FCA4 +tehmeemisolatedarabic;FC0E +tehnoonfinalarabic;FC73 +tekatakana;30C6 +tekatakanahalfwidth;FF83 +telephone;2121 +telephoneblack;260E +telishagedolahebrew;05A0 +telishaqetanahebrew;05A9 +tencircle;2469 +tenideographicparen;3229 +tenparen;247D +tenperiod;2491 +tenroman;2179 +tesh;02A7 +tet;05D8 +tetdagesh;FB38 +tetdageshhebrew;FB38 +tethebrew;05D8 +tetsecyrillic;04B5 +tevirhebrew;059B +tevirlefthebrew;059B +thabengali;09A5 +thadeva;0925 +thagujarati;0AA5 +thagurmukhi;0A25 +thalarabic;0630 +thalfinalarabic;FEAC +thanthakhatlowleftthai;F898 +thanthakhatlowrightthai;F897 +thanthakhatthai;0E4C +thanthakhatupperleftthai;F896 +theharabic;062B +thehfinalarabic;FE9A +thehinitialarabic;FE9B +thehmedialarabic;FE9C +thereexists;2203 +therefore;2234 +theta;03B8 +theta1;03D1 +thetasymbolgreek;03D1 +thieuthacirclekorean;3279 +thieuthaparenkorean;3219 +thieuthcirclekorean;326B +thieuthkorean;314C +thieuthparenkorean;320B +thirteencircle;246C +thirteenparen;2480 +thirteenperiod;2494 +thonangmonthothai;0E11 +thook;01AD +thophuthaothai;0E12 +thorn;00FE +thothahanthai;0E17 +thothanthai;0E10 +thothongthai;0E18 +thothungthai;0E16 +thousandcyrillic;0482 +thousandsseparatorarabic;066C +thousandsseparatorpersian;066C +three;0033 +threearabic;0663 +threebengali;09E9 +threecircle;2462 +threecircleinversesansserif;278C +threedeva;0969 +threeeighths;215C +threegujarati;0AE9 +threegurmukhi;0A69 +threehackarabic;0663 +threehangzhou;3023 +threeideographicparen;3222 +threeinferior;2083 +threemonospace;FF13 +threenumeratorbengali;09F6 +threeoldstyle;F733 +threeparen;2476 +threeperiod;248A +threepersian;06F3 +threequarters;00BE +threequartersemdash;F6DE +threeroman;2172 +threesuperior;00B3 +threethai;0E53 +thzsquare;3394 +tihiragana;3061 +tikatakana;30C1 +tikatakanahalfwidth;FF81 +tikeutacirclekorean;3270 +tikeutaparenkorean;3210 +tikeutcirclekorean;3262 +tikeutkorean;3137 +tikeutparenkorean;3202 +tilde;02DC +tildebelowcmb;0330 +tildecmb;0303 +tildecomb;0303 +tildedoublecmb;0360 +tildeoperator;223C +tildeoverlaycmb;0334 +tildeverticalcmb;033E +timescircle;2297 +tipehahebrew;0596 +tipehalefthebrew;0596 +tippigurmukhi;0A70 +titlocyrilliccmb;0483 +tiwnarmenian;057F +tlinebelow;1E6F +tmonospace;FF54 +toarmenian;0569 +tohiragana;3068 +tokatakana;30C8 +tokatakanahalfwidth;FF84 +tonebarextrahighmod;02E5 +tonebarextralowmod;02E9 +tonebarhighmod;02E6 +tonebarlowmod;02E8 +tonebarmidmod;02E7 +tonefive;01BD +tonesix;0185 +tonetwo;01A8 +tonos;0384 +tonsquare;3327 +topatakthai;0E0F +tortoiseshellbracketleft;3014 +tortoiseshellbracketleftsmall;FE5D +tortoiseshellbracketleftvertical;FE39 +tortoiseshellbracketright;3015 +tortoiseshellbracketrightsmall;FE5E +tortoiseshellbracketrightvertical;FE3A +totaothai;0E15 +tpalatalhook;01AB +tparen;24AF +trademark;2122 +trademarksans;F8EA +trademarkserif;F6DB +tretroflexhook;0288 +triagdn;25BC +triaglf;25C4 +triagrt;25BA +triagup;25B2 +ts;02A6 +tsadi;05E6 +tsadidagesh;FB46 +tsadidageshhebrew;FB46 +tsadihebrew;05E6 +tsecyrillic;0446 +tsere;05B5 +tsere12;05B5 +tsere1e;05B5 +tsere2b;05B5 +tserehebrew;05B5 +tserenarrowhebrew;05B5 +tserequarterhebrew;05B5 +tserewidehebrew;05B5 +tshecyrillic;045B +tsuperior;F6F3 +ttabengali;099F +ttadeva;091F +ttagujarati;0A9F +ttagurmukhi;0A1F +tteharabic;0679 +ttehfinalarabic;FB67 +ttehinitialarabic;FB68 +ttehmedialarabic;FB69 +tthabengali;09A0 +tthadeva;0920 +tthagujarati;0AA0 +tthagurmukhi;0A20 +tturned;0287 +tuhiragana;3064 +tukatakana;30C4 +tukatakanahalfwidth;FF82 +tusmallhiragana;3063 +tusmallkatakana;30C3 +tusmallkatakanahalfwidth;FF6F +twelvecircle;246B +twelveparen;247F +twelveperiod;2493 +twelveroman;217B +twentycircle;2473 +twentyhangzhou;5344 +twentyparen;2487 +twentyperiod;249B +two;0032 +twoarabic;0662 +twobengali;09E8 +twocircle;2461 +twocircleinversesansserif;278B +twodeva;0968 +twodotenleader;2025 +twodotleader;2025 +twodotleadervertical;FE30 +twogujarati;0AE8 +twogurmukhi;0A68 +twohackarabic;0662 +twohangzhou;3022 +twoideographicparen;3221 +twoinferior;2082 +twomonospace;FF12 +twonumeratorbengali;09F5 +twooldstyle;F732 +twoparen;2475 +twoperiod;2489 +twopersian;06F2 +tworoman;2171 +twostroke;01BB +twosuperior;00B2 +twothai;0E52 +twothirds;2154 +u;0075 +uacute;00FA +ubar;0289 +ubengali;0989 +ubopomofo;3128 +ubreve;016D +ucaron;01D4 +ucircle;24E4 +ucircumflex;00FB +ucircumflexbelow;1E77 +ucyrillic;0443 +udattadeva;0951 +udblacute;0171 +udblgrave;0215 +udeva;0909 +udieresis;00FC +udieresisacute;01D8 +udieresisbelow;1E73 +udieresiscaron;01DA +udieresiscyrillic;04F1 +udieresisgrave;01DC +udieresismacron;01D6 +udotbelow;1EE5 +ugrave;00F9 +ugujarati;0A89 +ugurmukhi;0A09 +uhiragana;3046 +uhookabove;1EE7 +uhorn;01B0 +uhornacute;1EE9 +uhorndotbelow;1EF1 +uhorngrave;1EEB +uhornhookabove;1EED +uhorntilde;1EEF +uhungarumlaut;0171 +uhungarumlautcyrillic;04F3 +uinvertedbreve;0217 +ukatakana;30A6 +ukatakanahalfwidth;FF73 +ukcyrillic;0479 +ukorean;315C +umacron;016B +umacroncyrillic;04EF +umacrondieresis;1E7B +umatragurmukhi;0A41 +umonospace;FF55 +underscore;005F +underscoredbl;2017 +underscoremonospace;FF3F +underscorevertical;FE33 +underscorewavy;FE4F +union;222A +universal;2200 +uogonek;0173 +uparen;24B0 +upblock;2580 +upperdothebrew;05C4 +upsilon;03C5 +upsilondieresis;03CB +upsilondieresistonos;03B0 +upsilonlatin;028A +upsilontonos;03CD +uptackbelowcmb;031D +uptackmod;02D4 +uragurmukhi;0A73 +uring;016F +ushortcyrillic;045E +usmallhiragana;3045 +usmallkatakana;30A5 +usmallkatakanahalfwidth;FF69 +ustraightcyrillic;04AF +ustraightstrokecyrillic;04B1 +utilde;0169 +utildeacute;1E79 +utildebelow;1E75 +uubengali;098A +uudeva;090A +uugujarati;0A8A +uugurmukhi;0A0A +uumatragurmukhi;0A42 +uuvowelsignbengali;09C2 +uuvowelsigndeva;0942 +uuvowelsigngujarati;0AC2 +uvowelsignbengali;09C1 +uvowelsigndeva;0941 +uvowelsigngujarati;0AC1 +v;0076 +vadeva;0935 +vagujarati;0AB5 +vagurmukhi;0A35 +vakatakana;30F7 +vav;05D5 +vavdagesh;FB35 +vavdagesh65;FB35 +vavdageshhebrew;FB35 +vavhebrew;05D5 +vavholam;FB4B +vavholamhebrew;FB4B +vavvavhebrew;05F0 +vavyodhebrew;05F1 +vcircle;24E5 +vdotbelow;1E7F +vecyrillic;0432 +veharabic;06A4 +vehfinalarabic;FB6B +vehinitialarabic;FB6C +vehmedialarabic;FB6D +vekatakana;30F9 +venus;2640 +verticalbar;007C +verticallineabovecmb;030D +verticallinebelowcmb;0329 +verticallinelowmod;02CC +verticallinemod;02C8 +vewarmenian;057E +vhook;028B +vikatakana;30F8 +viramabengali;09CD +viramadeva;094D +viramagujarati;0ACD +visargabengali;0983 +visargadeva;0903 +visargagujarati;0A83 +vmonospace;FF56 +voarmenian;0578 +voicediterationhiragana;309E +voicediterationkatakana;30FE +voicedmarkkana;309B +voicedmarkkanahalfwidth;FF9E +vokatakana;30FA +vparen;24B1 +vtilde;1E7D +vturned;028C +vuhiragana;3094 +vukatakana;30F4 +w;0077 +wacute;1E83 +waekorean;3159 +wahiragana;308F +wakatakana;30EF +wakatakanahalfwidth;FF9C +wakorean;3158 +wasmallhiragana;308E +wasmallkatakana;30EE +wattosquare;3357 +wavedash;301C +wavyunderscorevertical;FE34 +wawarabic;0648 +wawfinalarabic;FEEE +wawhamzaabovearabic;0624 +wawhamzaabovefinalarabic;FE86 +wbsquare;33DD +wcircle;24E6 +wcircumflex;0175 +wdieresis;1E85 +wdotaccent;1E87 +wdotbelow;1E89 +wehiragana;3091 +weierstrass;2118 +wekatakana;30F1 +wekorean;315E +weokorean;315D +wgrave;1E81 +whitebullet;25E6 +whitecircle;25CB +whitecircleinverse;25D9 +whitecornerbracketleft;300E +whitecornerbracketleftvertical;FE43 +whitecornerbracketright;300F +whitecornerbracketrightvertical;FE44 +whitediamond;25C7 +whitediamondcontainingblacksmalldiamond;25C8 +whitedownpointingsmalltriangle;25BF +whitedownpointingtriangle;25BD +whiteleftpointingsmalltriangle;25C3 +whiteleftpointingtriangle;25C1 +whitelenticularbracketleft;3016 +whitelenticularbracketright;3017 +whiterightpointingsmalltriangle;25B9 +whiterightpointingtriangle;25B7 +whitesmallsquare;25AB +whitesmilingface;263A +whitesquare;25A1 +whitestar;2606 +whitetelephone;260F +whitetortoiseshellbracketleft;3018 +whitetortoiseshellbracketright;3019 +whiteuppointingsmalltriangle;25B5 +whiteuppointingtriangle;25B3 +wihiragana;3090 +wikatakana;30F0 +wikorean;315F +wmonospace;FF57 +wohiragana;3092 +wokatakana;30F2 +wokatakanahalfwidth;FF66 +won;20A9 +wonmonospace;FFE6 +wowaenthai;0E27 +wparen;24B2 +wring;1E98 +wsuperior;02B7 +wturned;028D +wynn;01BF +x;0078 +xabovecmb;033D +xbopomofo;3112 +xcircle;24E7 +xdieresis;1E8D +xdotaccent;1E8B +xeharmenian;056D +xi;03BE +xmonospace;FF58 +xparen;24B3 +xsuperior;02E3 +y;0079 +yaadosquare;334E +yabengali;09AF +yacute;00FD +yadeva;092F +yaekorean;3152 +yagujarati;0AAF +yagurmukhi;0A2F +yahiragana;3084 +yakatakana;30E4 +yakatakanahalfwidth;FF94 +yakorean;3151 +yamakkanthai;0E4E +yasmallhiragana;3083 +yasmallkatakana;30E3 +yasmallkatakanahalfwidth;FF6C +yatcyrillic;0463 +ycircle;24E8 +ycircumflex;0177 +ydieresis;00FF +ydotaccent;1E8F +ydotbelow;1EF5 +yeharabic;064A +yehbarreearabic;06D2 +yehbarreefinalarabic;FBAF +yehfinalarabic;FEF2 +yehhamzaabovearabic;0626 +yehhamzaabovefinalarabic;FE8A +yehhamzaaboveinitialarabic;FE8B +yehhamzaabovemedialarabic;FE8C +yehinitialarabic;FEF3 +yehmedialarabic;FEF4 +yehmeeminitialarabic;FCDD +yehmeemisolatedarabic;FC58 +yehnoonfinalarabic;FC94 +yehthreedotsbelowarabic;06D1 +yekorean;3156 +yen;00A5 +yenmonospace;FFE5 +yeokorean;3155 +yeorinhieuhkorean;3186 +yerahbenyomohebrew;05AA +yerahbenyomolefthebrew;05AA +yericyrillic;044B +yerudieresiscyrillic;04F9 +yesieungkorean;3181 +yesieungpansioskorean;3183 +yesieungsioskorean;3182 +yetivhebrew;059A +ygrave;1EF3 +yhook;01B4 +yhookabove;1EF7 +yiarmenian;0575 +yicyrillic;0457 +yikorean;3162 +yinyang;262F +yiwnarmenian;0582 +ymonospace;FF59 +yod;05D9 +yoddagesh;FB39 +yoddageshhebrew;FB39 +yodhebrew;05D9 +yodyodhebrew;05F2 +yodyodpatahhebrew;FB1F +yohiragana;3088 +yoikorean;3189 +yokatakana;30E8 +yokatakanahalfwidth;FF96 +yokorean;315B +yosmallhiragana;3087 +yosmallkatakana;30E7 +yosmallkatakanahalfwidth;FF6E +yotgreek;03F3 +yoyaekorean;3188 +yoyakorean;3187 +yoyakthai;0E22 +yoyingthai;0E0D +yparen;24B4 +ypogegrammeni;037A +ypogegrammenigreekcmb;0345 +yr;01A6 +yring;1E99 +ysuperior;02B8 +ytilde;1EF9 +yturned;028E +yuhiragana;3086 +yuikorean;318C +yukatakana;30E6 +yukatakanahalfwidth;FF95 +yukorean;3160 +yusbigcyrillic;046B +yusbigiotifiedcyrillic;046D +yuslittlecyrillic;0467 +yuslittleiotifiedcyrillic;0469 +yusmallhiragana;3085 +yusmallkatakana;30E5 +yusmallkatakanahalfwidth;FF6D +yuyekorean;318B +yuyeokorean;318A +yyabengali;09DF +yyadeva;095F +z;007A +zaarmenian;0566 +zacute;017A +zadeva;095B +zagurmukhi;0A5B +zaharabic;0638 +zahfinalarabic;FEC6 +zahinitialarabic;FEC7 +zahiragana;3056 +zahmedialarabic;FEC8 +zainarabic;0632 +zainfinalarabic;FEB0 +zakatakana;30B6 +zaqefgadolhebrew;0595 +zaqefqatanhebrew;0594 +zarqahebrew;0598 +zayin;05D6 +zayindagesh;FB36 +zayindageshhebrew;FB36 +zayinhebrew;05D6 +zbopomofo;3117 +zcaron;017E +zcircle;24E9 +zcircumflex;1E91 +zcurl;0291 +zdot;017C +zdotaccent;017C +zdotbelow;1E93 +zecyrillic;0437 +zedescendercyrillic;0499 +zedieresiscyrillic;04DF +zehiragana;305C +zekatakana;30BC +zero;0030 +zeroarabic;0660 +zerobengali;09E6 +zerodeva;0966 +zerogujarati;0AE6 +zerogurmukhi;0A66 +zerohackarabic;0660 +zeroinferior;2080 +zeromonospace;FF10 +zerooldstyle;F730 +zeropersian;06F0 +zerosuperior;2070 +zerothai;0E50 +zerowidthjoiner;FEFF +zerowidthnonjoiner;200C +zerowidthspace;200B +zeta;03B6 +zhbopomofo;3113 +zhearmenian;056A +zhebrevecyrillic;04C2 +zhecyrillic;0436 +zhedescendercyrillic;0497 +zhedieresiscyrillic;04DD +zihiragana;3058 +zikatakana;30B8 +zinorhebrew;05AE +zlinebelow;1E95 +zmonospace;FF5A +zohiragana;305E +zokatakana;30BE +zparen;24B5 +zretroflexhook;0290 +zstroke;01B6 +zuhiragana;305A +zukatakana;30BA +#--end diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_annot.c b/rosapps/smartpdf/fitz/mupdf/pdf_annot.c new file mode 100644 index 00000000000..28eec3a4efd --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_annot.c @@ -0,0 +1,210 @@ +#include +#include + +static fz_error * +loadcomment(pdf_comment **commentp, pdf_xref *xref, fz_obj *dict) +{ + return nil; +} + +fz_error * +pdf_newlink(pdf_link **linkp, fz_rect bbox, fz_obj *dest, pdf_linkkind kind) +{ + pdf_link *link; + + link = fz_malloc(sizeof(pdf_link)); + if (!link) + return fz_outofmem; + + link->rect = bbox; + link->dest = fz_keepobj(dest); + link->kind = kind; + link->next = nil; + + *linkp = link; + return nil; +} + +void +pdf_droplink(pdf_link *link) +{ + if (link->next) + pdf_droplink(link->next); + if (link->dest) + fz_dropobj(link->dest); + fz_free(link); +} + +static fz_obj * +resolvedest(pdf_xref *xref, fz_obj *dest) +{ + if (fz_isname(dest)) + { + dest = fz_dictget(xref->dests, dest); + if (dest) + pdf_resolve(&dest, xref); /* XXX */ + return resolvedest(xref, dest); + } + + else if (fz_isstring(dest)) + { + dest = fz_dictget(xref->dests, dest); + if (dest) + pdf_resolve(&dest, xref); /* XXX */ + return resolvedest(xref, dest); + } + + else if (fz_isarray(dest)) + { + return fz_arrayget(dest, 0); + } + + else if (fz_isdict(dest)) + { + dest = fz_dictgets(dest, "D"); + return resolvedest(xref, dest); + } + + else if (fz_isindirect(dest)) + return dest; + + return nil; +} + +fz_error * +pdf_loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict) +{ + fz_error *error; + pdf_link *link; + fz_obj *dest; + fz_obj *action; + fz_obj *obj; + fz_rect bbox; + pdf_linkkind kind; + + pdf_logpage("load link {\n"); + + link = nil; + dest = nil; + + obj = fz_dictgets(dict, "Rect"); + if (obj) + { + bbox = pdf_torect(obj); + pdf_logpage("rect [%g %g %g %g]\n", + bbox.x0, bbox.y0, + bbox.x1, bbox.y1); + } + else + bbox = fz_emptyrect; + + obj = fz_dictgets(dict, "Dest"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + dest = resolvedest(xref, obj); + pdf_logpage("dest %d %d R\n", fz_tonum(dest), fz_togen(dest)); + fz_dropobj(obj); + } + + kind = PDF_LUNKNOWN; + action = fz_dictgets(dict, "A"); + if (action) + { + error = pdf_resolve(&action, xref); + if (error) + return error; + + obj = fz_dictgets(action, "S"); + if (!strcmp(fz_toname(obj), "GoTo")) + { + kind = PDF_LGOTO; + dest = resolvedest(xref, fz_dictgets(action, "D")); + pdf_logpage("action goto %d %d R\n", fz_tonum(dest), fz_togen(dest)); + } + else if (!strcmp(fz_toname(obj), "URI")) + { + kind = PDF_LURI; + dest = fz_dictgets(action, "URI"); + pdf_logpage("action uri %s\n", fz_tostrbuf(dest)); + } + else + pdf_logpage("action ... ?\n"); + + fz_dropobj(action); + } + + pdf_logpage("}\n"); + + if (dest) + { + error = pdf_newlink(&link, bbox, dest, kind); + if (error) + return error; + *linkp = link; + } + + return nil; +} + +fz_error * +pdf_loadannots(pdf_comment **cp, pdf_link **lp, pdf_xref *xref, fz_obj *annots) +{ + fz_error *error; + pdf_comment *comment; + pdf_link *link; + fz_obj *subtype; + fz_obj *obj; + int i; + + comment = nil; + link = nil; + + pdf_logpage("load annotations {\n"); + + for (i = 0; i < fz_arraylen(annots); i++) + { + obj = fz_arrayget(annots, i); + error = pdf_resolve(&obj, xref); + if (error) + goto cleanup; + + subtype = fz_dictgets(obj, "Subtype"); + if (!strcmp(fz_toname(subtype), "Link")) + { + pdf_link *temp = nil; + + error = pdf_loadlink(&temp, xref, obj); + fz_dropobj(obj); + if (error) + goto cleanup; + + if (temp) + { + temp->next = link; + link = temp; + } + } + else + { + error = loadcomment(&comment, xref, obj); + fz_dropobj(obj); + if (error) + goto cleanup; + } + } + + pdf_logpage("}\n"); + + *cp = comment; + *lp = link; + return nil; + +cleanup: + if (link) + pdf_droplink(link); + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_build.c b/rosapps/smartpdf/fitz/mupdf/pdf_build.c new file mode 100644 index 00000000000..5caafe3f300 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_build.c @@ -0,0 +1,803 @@ +#include +#include + +void +pdf_initgstate(pdf_gstate *gs) +{ + gs->linewidth = 1.0; + gs->linecap = 0; + gs->linejoin = 0; + gs->miterlimit = 10; + gs->dashphase = 0; + gs->dashlen = 0; + memset(gs->dashlist, 0, sizeof(gs->dashlist)); + + gs->stroke.kind = PDF_MCOLOR; + gs->stroke.cs = fz_keepcolorspace(pdf_devicegray); + gs->stroke.v[0] = 0; + gs->stroke.indexed = nil; + gs->stroke.pattern = nil; + gs->stroke.shade = nil; + + gs->fill.kind = PDF_MCOLOR; + gs->fill.cs = fz_keepcolorspace(pdf_devicegray); + gs->fill.v[0] = 0; + gs->fill.indexed = nil; + gs->fill.pattern = nil; + gs->fill.shade = nil; + + gs->charspace = 0; + gs->wordspace = 0; + gs->scale = 1; + gs->leading = 0; + gs->font = nil; + gs->size = -1; + gs->render = 0; + gs->rise = 0; + + gs->head = nil; +} + +fz_error * +pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs) +{ + pdf_gstate *gs = csi->gstate + csi->gtop; + fz_error *error; + pdf_material *mat; + + error = pdf_flushtext(csi); + if (error) + return error; + + mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; + + fz_dropcolorspace(mat->cs); + + mat->kind = PDF_MCOLOR; + mat->cs = fz_keepcolorspace(cs); + + mat->v[0] = 0; /* FIXME: default color */ + mat->v[1] = 0; /* FIXME: default color */ + mat->v[2] = 0; /* FIXME: default color */ + mat->v[3] = 1; /* FIXME: default color */ + + if (!strcmp(cs->name, "Indexed")) + { + mat->kind = PDF_MINDEXED; + mat->indexed = (pdf_indexed*)cs; + mat->cs = mat->indexed->base; + } + + if (!strcmp(cs->name, "Lab")) + mat->kind = PDF_MLAB; + + return nil; +} + +fz_error * +pdf_setcolor(pdf_csi *csi, int what, float *v) +{ + pdf_gstate *gs = csi->gstate + csi->gtop; + fz_error *error; + pdf_indexed *ind; + pdf_material *mat; + int i, k; + + error = pdf_flushtext(csi); + if (error) + return error; + + mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; + + switch (mat->kind) + { + case PDF_MPATTERN: + if (!strcmp(mat->cs->name, "Lab")) + goto Llab; + if (!strcmp(mat->cs->name, "Indexed")) + goto Lindexed; + /* fall through */ + + case PDF_MCOLOR: + for (i = 0; i < mat->cs->n; i++) + mat->v[i] = v[i]; + break; + + case PDF_MLAB: +Llab: + mat->v[0] = v[0] / 100.0; + mat->v[1] = (v[1] + 100) / 200.0; + mat->v[2] = (v[2] + 100) / 200.0; + break; + + case PDF_MINDEXED: +Lindexed: + ind = mat->indexed; + i = CLAMP(v[0], 0, ind->high); + for (k = 0; k < ind->base->n; k++) + mat->v[k] = ind->lookup[ind->base->n * i + k] / 255.0; + break; + + default: + return fz_throw("syntaxerror: color not compatible with material"); + } + + return nil; +} + +fz_error * +pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v) +{ + pdf_gstate *gs = csi->gstate + csi->gtop; + fz_error *error; + pdf_material *mat; + + error = pdf_flushtext(csi); + if (error) + return error; + + if (what == PDF_MFILL) + mat = &gs->fill; + else + mat = &gs->stroke; + + // TODO: this possibly drops a pattern too many times resulting in droping pattern + // used in other places, so don't drop it (better leak than crash). + // It's possible that overzeleaus dropping happens in some other place +#if 0 + if (mat->pattern) + pdf_droppattern(mat->pattern); +#endif + + mat->kind = PDF_MPATTERN; + if (pat) + mat->pattern = pdf_keeppattern(pat); + else + mat->pattern = nil; + + if (v) + return pdf_setcolor(csi, what, v); + + return nil; +} + +fz_error * +pdf_setshade(pdf_csi *csi, int what, fz_shade *shade) +{ + pdf_gstate *gs = csi->gstate + csi->gtop; + fz_error *error; + pdf_material *mat; + + error = pdf_flushtext(csi); + if (error) + return error; + + mat = what == PDF_MFILL ? &gs->fill : &gs->stroke; + + if (mat->shade) + fz_dropshade(mat->shade); + + mat->kind = PDF_MSHADE; + mat->shade = fz_keepshade(shade); + + return nil; +} + +fz_error * +pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path) +{ + fz_error *error; + fz_stroke stroke; + fz_dash *dash; + + stroke.linecap = gs->linecap; + stroke.linejoin = gs->linejoin; + stroke.linewidth = gs->linewidth; + stroke.miterlimit = gs->miterlimit; + + if (gs->dashlen) + { + error = fz_newdash(&dash, gs->dashphase, gs->dashlen, gs->dashlist); + if (error) + return error; + } + else + dash = nil; + + error = fz_endpath(path, FZ_STROKE, &stroke, dash); + if (error) { + fz_dropdash(dash); + return error; + } + + return nil; +} + +fz_error * +pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int eofill) +{ + return fz_endpath(path, eofill ? FZ_EOFILL : FZ_FILL, nil, nil); +} + +static fz_error * +addcolorshape(pdf_gstate *gs, fz_node *shape, fz_colorspace *cs, float *v) +{ + fz_error *error; + fz_node *mask; + fz_node *solid; + + error = fz_newmasknode(&mask); + if (error) return error; + + error = fz_newsolidnode(&solid, cs, cs->n, v); + if (error) return error; + + fz_insertnodelast(mask, shape); + fz_insertnodelast(mask, solid); + fz_insertnodelast(gs->head, mask); + + return nil; +} + +static fz_error * +addinvisibleshape(pdf_gstate *gs, fz_node *shape) +{ + fz_error *error; + fz_node *mask; + fz_pathnode *path; + + error = fz_newmasknode(&mask); + if (error) return error; + + error = fz_newpathnode(&path); + if (error) return error; + error = fz_endpath(path, FZ_FILL, nil, nil); + if (error) return error; + + fz_insertnodelast(mask, (fz_node*)path); + fz_insertnodelast(mask, shape); + fz_insertnodelast(gs->head, mask); + + return nil; +} + +static fz_matrix getmatrix(fz_node *node) +{ + if (node->parent) + { + fz_matrix ptm = getmatrix(node->parent); + if (fz_istransformnode(node)) + return fz_concat(((fz_transformnode*)node)->m, ptm); + return ptm; + } + if (fz_istransformnode(node)) + return ((fz_transformnode*)node)->m; + return fz_identity(); +} + +static fz_error * +addpatternshape(pdf_gstate *gs, fz_node *shape, + pdf_pattern *pat, fz_colorspace *cs, float *v) +{ + fz_error *error; + fz_node *xform; + fz_node *over; + fz_node *mask; + fz_node *meta; + fz_node *link; + fz_matrix ctm; + fz_matrix inv; + fz_matrix ptm; + fz_rect bbox; + fz_obj *dict; + int x, y, x0, y0, x1, y1; + + /* patterns are painted in user space */ + ctm = getmatrix(gs->head); + inv = fz_invertmatrix(ctm); + + error = fz_newmasknode(&mask); + if (error) return error; + + ptm = fz_concat(pat->matrix, fz_invertmatrix(ctm)); + error = fz_newtransformnode(&xform, ptm); + if (error) return error; + + error = fz_packobj(&dict, "<< /Tree %p /XStep %f /YStep %f " + " /Matrix[%f %f %f %f %f %f] >>", + pat->tree, pat->xstep, pat->ystep, + pat->matrix.a, pat->matrix.b, + pat->matrix.c, pat->matrix.d, + pat->matrix.e, pat->matrix.f); + if (error) return error; + + error = fz_newmetanode(&meta, "Pattern", dict); + if (error) return error; + + error = fz_newovernode(&over); + if (error) return error; + + fz_insertnodelast(mask, shape); + fz_insertnodelast(mask, meta); + fz_insertnodelast(meta, xform); + fz_insertnodelast(xform, over); + + /* get bbox of shape in pattern space for stamping */ + ptm = fz_concat(ctm, fz_invertmatrix(pat->matrix)); + bbox = fz_boundnode(shape, ptm); + + /* expand bbox by pattern bbox */ + bbox.x0 += pat->bbox.x0; + bbox.y0 += pat->bbox.y0; + bbox.x1 += pat->bbox.x1; + bbox.y1 += pat->bbox.y1; + + x0 = fz_floor(bbox.x0 / pat->xstep); + y0 = fz_floor(bbox.y0 / pat->ystep); + x1 = fz_ceil(bbox.x1 / pat->xstep); + y1 = fz_ceil(bbox.y1 / pat->ystep); + + for (y = y0; y <= y1; y++) + { + for (x = x0; x <= x1; x++) + { + ptm = fz_translate(x * pat->xstep, y * pat->ystep); + error = fz_newtransformnode(&xform, ptm); + if (error) return error; + error = fz_newlinknode(&link, pat->tree); + if (error) return error; + fz_insertnodelast(xform, link); + fz_insertnodelast(over, xform); + } + } + + if (pat->ismask) + return addcolorshape(gs, mask, cs, v); + + fz_insertnodelast(gs->head, mask); + return nil; +} + +fz_error * +pdf_addshade(pdf_gstate *gs, fz_shade *shade) +{ + fz_error *error; + fz_node *node; + + error = fz_newshadenode(&node, shade); + if (error) return error; + + fz_insertnodelast(gs->head, node); + + return nil; +} + +static fz_error * +addshadeshape(pdf_gstate *gs, fz_node *shape, fz_shade *shade) +{ + fz_error *error; + fz_node *mask; + fz_node *color; + fz_node *xform; + fz_node *over; + fz_node *bgnd; + fz_matrix ctm; + fz_matrix inv; + + ctm = getmatrix(gs->head); + inv = fz_invertmatrix(ctm); + + error = fz_newtransformnode(&xform, inv); + if (error) return error; + + error = fz_newmasknode(&mask); + if (error) return error; + + error = fz_newshadenode(&color, shade); + if (error) return error; + + if (shade->usebackground) + { + error = fz_newovernode(&over); + if (error) return error; + + error = fz_newsolidnode(&bgnd, shade->cs, shade->cs->n, shade->background); + if (error) return error; + + fz_insertnodelast(mask, shape); + fz_insertnodelast(over, bgnd); + fz_insertnodelast(over, color); + fz_insertnodelast(xform, over); + fz_insertnodelast(mask, xform); + fz_insertnodelast(gs->head, mask); + } + else + { + fz_insertnodelast(mask, shape); + fz_insertnodelast(xform, color); + fz_insertnodelast(mask, xform); + fz_insertnodelast(gs->head, mask); + } + + return nil; +} + +fz_error * +pdf_addfillshape(pdf_gstate *gs, fz_node *shape) +{ + switch (gs->fill.kind) + { + case PDF_MNONE: + fz_insertnodelast(gs->head, shape); + return nil; + case PDF_MCOLOR: + case PDF_MLAB: + case PDF_MINDEXED: + return addcolorshape(gs, shape, gs->fill.cs, gs->fill.v); + case PDF_MPATTERN: + // this is a work-around to make http://kpdf.kde.org/stuff/nytimes-firefox-final.pdf + // not crash see http://blog.kowalczyk.info/forum_sumatra/topic.php?TopicId=287&Posts=0 + if (gs->fill.pattern) + return addpatternshape(gs, shape, gs->fill.pattern, gs->fill.cs, gs->fill.v); + else + return nil; + case PDF_MSHADE: + return addshadeshape(gs, shape, gs->fill.shade); + default: + return fz_throw("unimplemented material"); + } +} + +fz_error * +pdf_addstrokeshape(pdf_gstate *gs, fz_node *shape) +{ + switch (gs->stroke.kind) + { + case PDF_MNONE: + fz_insertnodelast(gs->head, shape); + return nil; + case PDF_MCOLOR: + case PDF_MLAB: + case PDF_MINDEXED: + return addcolorshape(gs, shape, gs->stroke.cs, gs->stroke.v); + case PDF_MPATTERN: + return addpatternshape(gs, shape, gs->stroke.pattern, gs->stroke.cs, gs->stroke.v); + case PDF_MSHADE: + return addshadeshape(gs, shape, gs->stroke.shade); + default: + return fz_throw("unimplemented material"); + } +} + +fz_error * +pdf_addclipmask(pdf_gstate *gs, fz_node *shape) +{ + fz_error *error; + fz_node *mask; + fz_node *over; + + error = fz_newmasknode(&mask); + if (error) return error; + + error = fz_newovernode(&over); + if (error) return error; + + fz_insertnodelast(mask, shape); + fz_insertnodelast(mask, over); + fz_insertnodelast(gs->head, mask); + gs->head = over; + + return nil; +} + +fz_error * +pdf_addtransform(pdf_gstate *gs, fz_node *transform) +{ + fz_error *error; + fz_node *over; + + error = fz_newovernode(&over); + if (error) return error; + + fz_insertnodelast(gs->head, transform); + fz_insertnodelast(transform, over); + gs->head = over; + + return nil; +} + +fz_error * +pdf_showimage(pdf_csi *csi, pdf_image *img) +{ + fz_error *error; + fz_node *mask; + fz_node *color; + fz_node *shape; + + error = fz_newimagenode(&color, (fz_image*)img); + if (error) + return error; + + if (img->super.n == 0 && img->super.a == 1) + { + error = pdf_addfillshape(csi->gstate + csi->gtop, color); + if (error) { + fz_dropnode(color); + return error; + } + } + else + { + if (img->mask) + { + error = fz_newimagenode(&shape, (fz_image*)img->mask); + if (error) return error; + error = fz_newmasknode(&mask); + if (error) return error; + fz_insertnodelast(mask, shape); + fz_insertnodelast(mask, color); + fz_insertnodelast(csi->gstate[csi->gtop].head, mask); + } + else + { + fz_insertnodelast(csi->gstate[csi->gtop].head, color); + } + } + + return nil; +} + +fz_error * +pdf_showpath(pdf_csi *csi, + int doclose, int dofill, int dostroke, int evenodd) +{ + pdf_gstate *gstate = csi->gstate + csi->gtop; + fz_error *error; + fz_pathnode *spath; + fz_pathnode *fpath; + + if (doclose) + { + error = fz_closepath(csi->path); + if (error) return error; + } + + if (dofill && dostroke) + { + fpath = csi->path; + error = fz_clonepathnode(&spath, fpath); + if (error) return error; + } + else + { + spath = fpath = csi->path; + } + + if (dofill) + { + error = pdf_buildfillpath(gstate, fpath, evenodd); + if (error) return error; + error = pdf_addfillshape(gstate, (fz_node*)fpath); + if (error) return error; + } + + if (dostroke) + { + error = pdf_buildstrokepath(gstate, spath); + if (error) return error; + error = pdf_addstrokeshape(gstate, (fz_node*)spath); + if (error) return error; + } + + if (csi->clip) + { + fz_pathnode *clip; + error = fz_clonepathnode(&clip, csi->path); + if (error) return error; + error = fz_endpath(clip, FZ_FILL, nil, nil); + if (error) return error; + error = pdf_addclipmask(gstate, (fz_node*)clip); + if (error) return error; + csi->clip = 0; + } + + if (!dofill && !dostroke) + { + fz_dropnode((fz_node*)csi->path); + } + + csi->path = nil; + + error = fz_newpathnode(&csi->path); + if (error) return error; + + return nil; +} + +fz_error * +pdf_flushtext(pdf_csi *csi) +{ + pdf_gstate *gstate = csi->gstate + csi->gtop; + fz_error *error; + + if (csi->text) + { + switch (csi->textmode) + { + case 0: /* fill */ + case 1: /* stroke */ + case 2: /* stroke + fill */ + error = pdf_addfillshape(gstate, (fz_node*)csi->text); + if (error) + return error; + break; + + case 3: /* invisible */ + error = addinvisibleshape(gstate, (fz_node*)csi->text); + if (error) + return error; + break; + + case 4: /* fill + clip */ + case 5: /* stroke + clip */ + case 6: /* stroke + fill + clip */ + { + fz_textnode *temp; + error = fz_clonetextnode(&temp, csi->text); + if (error) + return error; + error = pdf_addfillshape(gstate, (fz_node*)temp); + if (error) + return error; + } + /* fall through */ + + case 7: /* invisible clip */ + if (!csi->textclip) + { + error = fz_newovernode(&csi->textclip); + if (error) + return error; + } + fz_insertnodelast(csi->textclip, (fz_node*)csi->text); + break; + } + + csi->text = nil; + } + + return nil; +} + +fz_error * +showglyph(pdf_csi *csi, int cid) +{ + pdf_gstate *gstate = csi->gstate + csi->gtop; + pdf_font *font = gstate->font; + fz_error *error; + fz_matrix tsm, trm; + float w0, w1, tx, ty; + fz_hmtx h; + fz_vmtx v; + + tsm.a = gstate->size * gstate->scale; + tsm.b = 0; + tsm.c = 0; + tsm.d = gstate->size; + tsm.e = 0; + tsm.f = gstate->rise; + + if (font->super.wmode == 1) + { + v = fz_getvmtx((fz_font*)font, cid); + tsm.e -= v.x * gstate->size / 1000.0; + tsm.f -= v.y * gstate->size / 1000.0; + } + + trm = fz_concat(tsm, csi->tm); + + /* flush buffered text if face or matrix or rendermode has changed */ + if (!csi->text || + ((fz_font*)font) != csi->text->font || + fabs(trm.a - csi->text->trm.a) > FLT_EPSILON || + fabs(trm.b - csi->text->trm.b) > FLT_EPSILON || + fabs(trm.c - csi->text->trm.c) > FLT_EPSILON || + fabs(trm.d - csi->text->trm.d) > FLT_EPSILON || + gstate->render != csi->textmode) + { + error = pdf_flushtext(csi); + if (error) return error; + + error = fz_newtextnode(&csi->text, (fz_font*)font); + if (error) return error; + + csi->text->trm = trm; + csi->text->trm.e = 0; + csi->text->trm.f = 0; + csi->textmode = gstate->render; + } + + /* add glyph to textobject */ + error = fz_addtext(csi->text, cid, trm.e, trm.f); + if (error) + return error; + + if (font->super.wmode == 0) + { + h = fz_gethmtx((fz_font*)font, cid); + w0 = h.w / 1000.0; + tx = (w0 * gstate->size + gstate->charspace) * gstate->scale; + csi->tm = fz_concat(fz_translate(tx, 0), csi->tm); + } + else + { + w1 = v.w / 1000.0; + ty = w1 * gstate->size + gstate->charspace; + csi->tm = fz_concat(fz_translate(0, ty), csi->tm); + } + + return nil; +} + +void +showspace(pdf_csi *csi, float tadj) +{ + pdf_gstate *gstate = csi->gstate + csi->gtop; + pdf_font *font = gstate->font; + if (font->super.wmode == 0) + csi->tm = fz_concat(fz_translate(tadj * gstate->scale, 0), csi->tm); + else + csi->tm = fz_concat(fz_translate(0, tadj), csi->tm); +} + +fz_error * +pdf_showtext(pdf_csi *csi, fz_obj *text) +{ + pdf_gstate *gstate = csi->gstate + csi->gtop; + pdf_font *font = gstate->font; + fz_error *error; + unsigned char *buf; + unsigned char *end; + int i, len; + int cpt, cid; + + if (fz_isarray(text)) + { + for (i = 0; i < fz_arraylen(text); i++) + { + fz_obj *item = fz_arrayget(text, i); + if (fz_isstring(item)) + { + error = pdf_showtext(csi, item); + if (error) return error; + } + else + { + showspace(csi, - fz_toreal(item) * gstate->size / 1000.0); + } + } + return nil; + } + + buf = fz_tostrbuf(text); + len = fz_tostrlen(text); + end = buf + len; + + while (buf < end) + { + buf = pdf_decodecmap(font->encoding, buf, &cpt); + cid = pdf_lookupcmap(font->encoding, cpt); + if (cid == -1) + cid = 0; + + error = showglyph(csi, cid); + if (error) + return error; + + if (cpt == 32) + showspace(csi, gstate->wordspace); + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_cmap.c b/rosapps/smartpdf/fitz/mupdf/pdf_cmap.c new file mode 100644 index 00000000000..4729322ff2b --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_cmap.c @@ -0,0 +1,1166 @@ +/* + * The CMap data structure here is constructed on the fly by + * adding simple range-to-range mappings. Then the data structure + * is optimized to contain both range-to-range and range-to-table + * lookups. + * + * Any one-to-many mappings are inserted as one-to-table + * lookups in the beginning, and are not affected by the optimization + * stage. + * + * There is a special function to add a 256-length range-to-table mapping. + * The ranges do not have to be added in order. + * + * This code can be a lot simpler if we don't care about wasting memory, + * or can trust the parser to give us optimal mappings. + */ + +#include "fitz.h" +#include "mupdf.h" + +typedef struct pdf_range_s pdf_range; + +enum { MAXCODESPACE = 10 }; +enum { SINGLE, RANGE, TABLE, MULTI }; + +struct pdf_range_s +{ + int low; + int high; + int flag; /* what kind of lookup is this */ + int offset; /* either range-delta or table-index */ +}; + +static int +cmprange(const void *va, const void *vb) +{ + return ((const pdf_range*)va)->low - ((const pdf_range*)vb)->low; +} + +struct pdf_cmap_s +{ + int refs; + char cmapname[32]; + + char usecmapname[32]; + pdf_cmap *usecmap; + + int wmode; + + int ncspace; + struct { + int n; + unsigned char lo[4]; + unsigned char hi[4]; + } cspace[MAXCODESPACE]; + + int rlen, rcap; + pdf_range *ranges; + + int tlen, tcap; + int *table; +}; + +/* + * Allocate, destroy and simple parameters. + */ + +fz_error * +pdf_newcmap(pdf_cmap **cmapp) +{ + pdf_cmap *cmap; + + cmap = *cmapp = fz_malloc(sizeof(pdf_cmap)); + if (!cmap) + return fz_outofmem; + + cmap->refs = 1; + strcpy(cmap->cmapname, ""); + + strcpy(cmap->usecmapname, ""); + cmap->usecmap = nil; + + cmap->wmode = 0; + + cmap->ncspace = 0; + + cmap->rlen = 0; + cmap->rcap = 0; + cmap->ranges = nil; + + cmap->tlen = 0; + cmap->tcap = 0; + cmap->table = nil; + + return nil; +} + +pdf_cmap * +pdf_keepcmap(pdf_cmap *cmap) +{ + cmap->refs ++; + return cmap; +} + +void +pdf_dropcmap(pdf_cmap *cmap) +{ + if (--cmap->refs == 0) + { + if (cmap->usecmap) + pdf_dropcmap(cmap->usecmap); + fz_free(cmap->ranges); + fz_free(cmap->table); + fz_free(cmap); + } +} + +pdf_cmap * +pdf_getusecmap(pdf_cmap *cmap) +{ + return cmap->usecmap; +} + +void +pdf_setusecmap(pdf_cmap *cmap, pdf_cmap *usecmap) +{ + int i; + + if (cmap->usecmap) + pdf_dropcmap(cmap->usecmap); + cmap->usecmap = pdf_keepcmap(usecmap); + + if (cmap->ncspace == 0) + { + cmap->ncspace = usecmap->ncspace; + for (i = 0; i < usecmap->ncspace; i++) + cmap->cspace[i] = usecmap->cspace[i]; + } +} + +int +pdf_getwmode(pdf_cmap *cmap) +{ + return cmap->wmode; +} + +void +pdf_setwmode(pdf_cmap *cmap, int wmode) +{ + cmap->wmode = wmode; +} + +void +pdf_debugcmap(pdf_cmap *cmap) +{ + int i, k, n; + + printf("cmap $%p /%s {\n", cmap, cmap->cmapname); + + if (cmap->usecmapname[0]) + printf(" usecmap /%s\n", cmap->usecmapname); + if (cmap->usecmap) + printf(" usecmap $%p\n", cmap->usecmap); + + printf(" wmode %d\n", cmap->wmode); + + printf(" codespaces {\n"); + for (i = 0; i < cmap->ncspace; i++) + { + printf(" <"); + for (k = 0; k < cmap->cspace[i].n; k++) + printf("%02x", cmap->cspace[i].lo[k]); + printf("> <"); + for (k = 0; k < cmap->cspace[i].n; k++) + printf("%02x", cmap->cspace[i].hi[k]); + printf(">\n"); + } + printf(" }\n"); + + printf(" ranges (%d,%d) {\n", cmap->rlen, cmap->tlen); + for (i = 0; i < cmap->rlen; i++) + { + pdf_range *r = &cmap->ranges[i]; + printf(" <%04x> <%04x> ", r->low, r->high); + if (r->flag == TABLE) + { + printf("[ "); + for (k = 0; k < r->high - r->low + 1; k++) + printf("%d ", cmap->table[r->offset + k]); + printf("]\n"); + } + else if (r->flag == MULTI) + { + printf("< "); + n = cmap->table[r->offset]; + for (k = 0; k < n; k++) + printf("%04x ", cmap->table[r->offset + 1 + k]); + printf(">\n"); + } + else + printf("%d\n", r->offset); + } + printf(" }\n}\n"); +} + +/* + * Add a codespacerange section. + * These ranges are used by pdf_decodecmap to decode + * multi-byte encoded strings. + */ +fz_error * +pdf_addcodespace(pdf_cmap *cmap, unsigned lo, unsigned hi, int n) +{ + int i; + + if (cmap->ncspace + 1 == MAXCODESPACE) + return fz_throw("rangelimit: too many code space ranges"); + + cmap->cspace[cmap->ncspace].n = n; + + for (i = 0; i < n; i++) + { + int o = (n - i - 1) * 8; + cmap->cspace[cmap->ncspace].lo[i] = (lo >> o) & 0xFF; + cmap->cspace[cmap->ncspace].hi[i] = (hi >> o) & 0xFF; + } + + cmap->ncspace ++; + + return nil; +} + +/* + * Add an integer to the table. + */ +static fz_error * +addtable(pdf_cmap *cmap, int value) +{ + if (cmap->tlen + 1 > cmap->tcap) + { + int newcap = cmap->tcap == 0 ? 256 : cmap->tcap * 2; + int *newtable = fz_realloc(cmap->table, newcap * sizeof(int)); + if (!newtable) + return fz_outofmem; + cmap->tcap = newcap; + cmap->table = newtable; + } + + cmap->table[cmap->tlen++] = value; + + return nil; +} + +/* + * Add a range. + */ +static fz_error * +addrange(pdf_cmap *cmap, int low, int high, int flag, int offset) +{ + if (cmap->rlen + 1 > cmap->rcap) + { + pdf_range *newranges; + int newcap = cmap->rcap == 0 ? 256 : cmap->rcap * 2; + newranges = fz_realloc(cmap->ranges, newcap * sizeof(pdf_range)); + if (!newranges) + return fz_outofmem; + cmap->rcap = newcap; + cmap->ranges = newranges; + } + + cmap->ranges[cmap->rlen].low = low; + cmap->ranges[cmap->rlen].high = high; + cmap->ranges[cmap->rlen].flag = flag; + cmap->ranges[cmap->rlen].offset = offset; + cmap->rlen ++; + + return nil; +} + +/* + * Add a range-to-table mapping. + */ +fz_error * +pdf_maprangetotable(pdf_cmap *cmap, int low, int *table, int len) +{ + fz_error *error; + int offset; + int high; + int i; + + high = low + len; + offset = cmap->tlen; + + for (i = 0; i < len; i++) + { + error = addtable(cmap, table[i]); + if (error) + return error; + } + + return addrange(cmap, low, high, TABLE, offset); +} + +/* + * Add a range of contiguous one-to-one mappings (ie 1..5 maps to 21..25) + */ +fz_error * +pdf_maprangetorange(pdf_cmap *cmap, int low, int high, int offset) +{ + return addrange(cmap, low, high, high - low == 0 ? SINGLE : RANGE, offset); +} + +/* + * Add a single one-to-many mapping. + */ +fz_error * +pdf_maponetomany(pdf_cmap *cmap, int low, int *values, int len) +{ + fz_error *error; + int offset; + int i; + + if (len == 1) + return addrange(cmap, low, low, SINGLE, values[0]); + + offset = cmap->tlen; + + error = addtable(cmap, len); + if (error) + return error; + + for (i = 0; i < len; i++) + { + addtable(cmap, values[i]); + if (error) + return error; + } + + return addrange(cmap, low, low, MULTI, offset); +} + +/* + * Sort the input ranges. + * Merge contiguous input ranges to range-to-range if the output is contiguos. + * Merge contiguous input ranges to range-to-table if the output is random. + */ +fz_error * +pdf_sortcmap(pdf_cmap *cmap) +{ + fz_error *error; + pdf_range *newranges; + int *newtable; + pdf_range *a; /* last written range on output */ + pdf_range *b; /* current range examined on input */ + + qsort(cmap->ranges, cmap->rlen, sizeof(pdf_range), cmprange); + + a = cmap->ranges; + b = cmap->ranges + 1; + + while (b < cmap->ranges + cmap->rlen) + { + /* ignore one-to-many mappings */ + if (b->flag == MULTI) + { + *(++a) = *b; + } + + /* input contiguous */ + else if (a->high + 1 == b->low) + { + /* output contiguous */ + if (a->high - a->low + a->offset + 1 == b->offset) + { + /* SR -> R and SS -> R and RR -> R and RS -> R */ + if (a->flag == SINGLE || a->flag == RANGE) + { + a->flag = RANGE; + a->high = b->high; + } + + /* LS -> L */ + else if (a->flag == TABLE && b->flag == SINGLE) + { + a->high = b->high; + error = addtable(cmap, b->offset); + if (error) + return error; + } + + /* LR -> LR */ + else if (a->flag == TABLE && b->flag == RANGE) + { + *(++a) = *b; + } + + /* XX -> XX */ + else + { + *(++a) = *b; + } + } + + /* output separated */ + else + { + /* SS -> L */ + if (a->flag == SINGLE && b->flag == SINGLE) + { + a->flag = TABLE; + a->high = b->high; + + error = addtable(cmap, a->offset); + if (error) + return error; + + error = addtable(cmap, b->offset); + if (error) + return error; + + a->offset = cmap->tlen - 2; + } + + /* LS -> L */ + else if (a->flag == TABLE && b->flag == SINGLE) + { + a->high = b->high; + error = addtable(cmap, b->offset); + if (error) + return error; + } + + /* XX -> XX */ + else + { + *(++a) = *b; + } + } + } + + /* input separated: XX -> XX */ + else + { + *(++a) = *b; + } + + b ++; + } + + cmap->rlen = a - cmap->ranges + 1; + + assert(cmap->rlen > 0); + + newranges = fz_realloc(cmap->ranges, cmap->rlen * sizeof(pdf_range)); + if (!newranges) + return fz_outofmem; + cmap->rcap = cmap->rlen; + cmap->ranges = newranges; + + if (cmap->tlen) + { + newtable = fz_realloc(cmap->table, cmap->tlen * sizeof(int)); + if (!newtable) + return fz_outofmem; + cmap->tcap = cmap->tlen; + cmap->table = newtable; + } + + return nil; +} + +/* + * Lookup the mapping of a codepoint. + */ +int +pdf_lookupcmap(pdf_cmap *cmap, int cpt) +{ + int l = 0; + int r = cmap->rlen - 1; + int m; + + while (l <= r) + { + m = (l + r) >> 1; + if (cpt < cmap->ranges[m].low) + r = m - 1; + else if (cpt > cmap->ranges[m].high) + l = m + 1; + else + { + int i = cpt - cmap->ranges[m].low + cmap->ranges[m].offset; + if (cmap->ranges[m].flag == TABLE) + return cmap->table[i]; + if (cmap->ranges[m].flag == MULTI) + return -1; + return i; + } + } + + if (cmap->usecmap) + return pdf_lookupcmap(cmap->usecmap, cpt); + + return -1; +} + +/* + * Use the codespace ranges to extract a codepoint from a + * multi-byte encoded string. + */ +unsigned char * +pdf_decodecmap(pdf_cmap *cmap, unsigned char *buf, int *cpt) +{ + int i, k; + + for (k = 0; k < cmap->ncspace; k++) + { + unsigned char *lo = cmap->cspace[k].lo; + unsigned char *hi = cmap->cspace[k].hi; + int n = cmap->cspace[k].n; + int c = 0; + + for (i = 0; i < n; i++) + { + if (lo[i] <= buf[i] && buf[i] <= hi[i]) + c = (c << 8) | buf[i]; + else + break; + } + + if (i == n) { + *cpt = c; + return buf + n; + } + } + + *cpt = 0; + return buf + 1; +} + +/* + * CMap parser + */ + +enum +{ + TUSECMAP = PDF_NTOKENS, + TBEGINCODESPACERANGE, + TENDCODESPACERANGE, + TBEGINBFCHAR, + TENDBFCHAR, + TBEGINBFRANGE, + TENDBFRANGE, + TBEGINCIDCHAR, + TENDCIDCHAR, + TBEGINCIDRANGE, + TENDCIDRANGE +}; + +static int tokenfromkeyword(char *key) +{ + if (!strcmp(key, "usecmap")) return TUSECMAP; + if (!strcmp(key, "begincodespacerange")) return TBEGINCODESPACERANGE; + if (!strcmp(key, "endcodespacerange")) return TENDCODESPACERANGE; + if (!strcmp(key, "beginbfchar")) return TBEGINBFCHAR; + if (!strcmp(key, "endbfchar")) return TENDBFCHAR; + if (!strcmp(key, "beginbfrange")) return TBEGINBFRANGE; + if (!strcmp(key, "endbfrange")) return TENDBFRANGE; + if (!strcmp(key, "begincidchar")) return TBEGINCIDCHAR; + if (!strcmp(key, "endcidchar")) return TENDCIDCHAR; + if (!strcmp(key, "begincidrange")) return TBEGINCIDRANGE; + if (!strcmp(key, "endcidrange")) return TENDCIDRANGE; + return PDF_TKEYWORD; +} + +static int codefromstring(unsigned char *buf, int len) +{ + int a = 0; + while (len--) + a = (a << 8) | *buf++; + return a; +} + +static int mylex(fz_stream *file, char *buf, int n, int *sl) +{ + int token = pdf_lex(file, buf, n, sl); + if (token == PDF_TKEYWORD) + token = tokenfromkeyword(buf); + return token; +} + +static fz_error *parsecmapname(pdf_cmap *cmap, fz_stream *file) +{ + char buf[256]; + int token; + int len; + + token = mylex(file, buf, sizeof buf, &len); + if (token == PDF_TNAME) { + strlcpy(cmap->cmapname, buf, sizeof(cmap->cmapname)); + return nil; + } + + return fz_throw("syntaxerror in CMap after /CMapName"); +} + +static fz_error *parsewmode(pdf_cmap *cmap, fz_stream *file) +{ + char buf[256]; + int token; + int len; + + token = mylex(file, buf, sizeof buf, &len); + if (token == PDF_TINT) { + pdf_setwmode(cmap, atoi(buf)); + return nil; + } + + return fz_throw("syntaxerror in CMap after /WMode"); +} + +static fz_error *parsecodespacerange(pdf_cmap *cmap, fz_stream *file) +{ + char buf[256]; + int token; + int len; + fz_error *error; + int lo, hi; + + while (1) + { + token = mylex(file, buf, sizeof buf, &len); + + if (token == TENDCODESPACERANGE) + return nil; + + else if (token == PDF_TSTRING) + { + lo = codefromstring(buf, len); + token = mylex(file, buf, sizeof buf, &len); + if (token == PDF_TSTRING) + { + hi = codefromstring(buf, len); + error = pdf_addcodespace(cmap, lo, hi, len); + if (error) + return error; + } + else break; + } + + else break; + } + + return fz_throw("syntaxerror in CMap codespacerange section"); +} + +static fz_error *parsecidrange(pdf_cmap *cmap, fz_stream *file) +{ + char buf[256]; + int token; + int len; + fz_error *error; + int lo, hi, dst; + + while (1) + { + token = mylex(file, buf, sizeof buf, &len); + + if (token == TENDCIDRANGE) + return nil; + + else if (token != PDF_TSTRING) + goto cleanup; + + lo = codefromstring(buf, len); + + token = mylex(file, buf, sizeof buf, &len); + if (token != PDF_TSTRING) + goto cleanup; + + hi = codefromstring(buf, len); + + token = mylex(file, buf, sizeof buf, &len); + if (token != PDF_TINT) + goto cleanup; + + dst = atoi(buf); + + error = pdf_maprangetorange(cmap, lo, hi, dst); + if (error) + return error; + } + +cleanup: + return fz_throw("syntaxerror in CMap cidrange section"); +} + +static fz_error *parsecidchar(pdf_cmap *cmap, fz_stream *file) +{ + char buf[256]; + int token; + int len; + fz_error *error; + int src, dst; + + while (1) + { + token = mylex(file, buf, sizeof buf, &len); + + if (token == TENDCIDCHAR) + return nil; + + else if (token != PDF_TSTRING) + goto cleanup; + + src = codefromstring(buf, len); + + token = mylex(file, buf, sizeof buf, &len); + if (token != PDF_TINT) + goto cleanup; + + dst = atoi(buf); + + error = pdf_maprangetorange(cmap, src, src, dst); + if (error) + return error; + } + +cleanup: + return fz_throw("syntaxerror in CMap cidchar section"); +} + +static fz_error *parsebfrangearray(pdf_cmap *cmap, fz_stream *file, int lo, int hi) +{ + char buf[256]; + int token; + int len; + fz_error *error; + int dst[256]; + int i; + + while (1) + { + token = mylex(file, buf, sizeof buf, &len); + /* Note: does not handle [ /Name /Name ... ] */ + + if (token == PDF_TCARRAY) + return nil; + + else if (token != PDF_TSTRING) + return fz_throw("syntaxerror in CMap bfrange array section"); + + if (len / 2) + { + for (i = 0; i < len / 2; i++) + dst[i] = codefromstring(buf + i * 2, 2); + + error = pdf_maponetomany(cmap, lo, dst, len / 2); + if (error) + return error; + } + + lo ++; + } +} + +static fz_error *parsebfrange(pdf_cmap *cmap, fz_stream *file) +{ + char buf[256]; + int token; + int len; + fz_error *error; + int lo, hi, dst; + + while (1) + { + token = mylex(file, buf, sizeof buf, &len); + + if (token == TENDBFRANGE) + return nil; + + else if (token != PDF_TSTRING) + goto cleanup; + + lo = codefromstring(buf, len); + + token = mylex(file, buf, sizeof buf, &len); + if (token != PDF_TSTRING) + goto cleanup; + + hi = codefromstring(buf, len); + + token = mylex(file, buf, sizeof buf, &len); + + if (token == PDF_TSTRING) + { + if (len == 2) + { + dst = codefromstring(buf, len); + error = pdf_maprangetorange(cmap, lo, hi, dst); + if (error) + return error; + } + else + { + int dststr[256]; + int i; + + if (len / 2) + { + for (i = 0; i < len / 2; i++) + dststr[i] = codefromstring(buf + i * 2, 2); + + while (lo <= hi) + { + dststr[i-1] ++; + error = pdf_maponetomany(cmap, lo, dststr, i); + if (error) + return error; + lo ++; + } + } + } + } + + else if (token == PDF_TOARRAY) + { + error = parsebfrangearray(cmap, file, lo, hi); + if (error) + return error; + } + + else + { + goto cleanup; + } + } + +cleanup: + return fz_throw("syntaxerror in CMap bfrange section"); +} + +static fz_error *parsebfchar(pdf_cmap *cmap, fz_stream *file) +{ + char buf[256]; + int token; + int len; + fz_error *error; + int dst[256]; + int src; + int i; + + while (1) + { + token = mylex(file, buf, sizeof buf, &len); + + if (token == TENDBFCHAR) + return nil; + + else if (token != PDF_TSTRING) + goto cleanup; + + src = codefromstring(buf, len); + + token = mylex(file, buf, sizeof buf, &len); + /* Note: does not handle /dstName */ + if (token != PDF_TSTRING) + goto cleanup; + + if (len / 2) + { + for (i = 0; i < len / 2; i++) + dst[i] = codefromstring(buf + i * 2, 2); + + error = pdf_maponetomany(cmap, src, dst, i); + if (error) + return error; + } + } + +cleanup: + return fz_throw("syntaxerror in CMap bfchar section"); +} + +fz_error * +pdf_parsecmap(pdf_cmap **cmapp, fz_stream *file) +{ + fz_error *error; + pdf_cmap *cmap; + char key[64]; + char buf[256]; + int token; + int len; + + error = pdf_newcmap(&cmap); + if (error) + return error; + + strcpy(key, ".notdef"); + + while (1) + { + token = mylex(file, buf, sizeof buf, &len); + + if (token == PDF_TEOF) + break; + + else if (token == PDF_TERROR) + { + error = fz_throw("syntaxerror in CMap"); + goto cleanup; + } + + else if (token == PDF_TNAME) + { + if (!strcmp(buf, "CMapName")) + { + error = parsecmapname(cmap, file); + if (error) + goto cleanup; + } + else if (!strcmp(buf, "WMode")) + { + error = parsewmode(cmap, file); + if (error) + goto cleanup; + } + else + strlcpy(key, buf, sizeof key); + } + + else if (token == TUSECMAP) + { + strlcpy(cmap->usecmapname, key, sizeof(cmap->usecmapname)); + } + + else if (token == TBEGINCODESPACERANGE) + { + error = parsecodespacerange(cmap, file); + if (error) + goto cleanup; + } + + else if (token == TBEGINBFCHAR) + { + error = parsebfchar(cmap, file); + if (error) + goto cleanup; + } + + else if (token == TBEGINCIDCHAR) + { + error = parsecidchar(cmap, file); + if (error) + goto cleanup; + } + + else if (token == TBEGINBFRANGE) + { + error = parsebfrange(cmap, file); + if (error) + goto cleanup; + } + + else if (token == TBEGINCIDRANGE) + { + error = parsecidrange(cmap, file); + if (error) + goto cleanup; + } + + /* ignore everything else */ + } + + error = pdf_sortcmap(cmap); + if (error) + goto cleanup; + + *cmapp = cmap; + return nil; + +cleanup: + pdf_dropcmap(cmap); + return error; +} + +/* + * Load CMap stream in PDF file + */ +fz_error * +pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref) +{ + fz_obj *stmobj = stmref; + fz_error *error = nil; + fz_stream *file; + pdf_cmap *cmap = nil; + pdf_cmap *usecmap; + fz_obj *wmode; + fz_obj *obj; + + if ((*cmapp = pdf_finditem(xref->store, PDF_KCMAP, stmref))) + { + pdf_keepcmap(*cmapp); + return nil; + } + + pdf_logfont("load embedded cmap %d %d {\n", fz_tonum(stmref), fz_togen(stmref)); + + error = pdf_resolve(&stmobj, xref); + if (error) + return error; + + error = pdf_openstream(&file, xref, fz_tonum(stmref), fz_togen(stmref)); + if (error) + goto cleanup; + + error = pdf_parsecmap(&cmap, file); + if (error) + goto cleanup; + + fz_dropstream(file); + + wmode = fz_dictgets(stmobj, "WMode"); + if (fz_isint(wmode)) + { + pdf_logfont("wmode %d\n", wmode); + pdf_setwmode(cmap, fz_toint(wmode)); + } + + obj = fz_dictgets(stmobj, "UseCMap"); + if (fz_isname(obj)) + { + pdf_logfont("usecmap /%s\n", fz_toname(obj)); + error = pdf_loadsystemcmap(&usecmap, fz_toname(obj)); + if (error) + goto cleanup; + pdf_setusecmap(cmap, usecmap); + pdf_dropcmap(usecmap); + } + else if (fz_isindirect(obj)) + { + pdf_logfont("usecmap %d %d R\n", fz_tonum(obj), fz_togen(obj)); + error = pdf_loadembeddedcmap(&usecmap, xref, obj); + if (error) + goto cleanup; + pdf_setusecmap(cmap, usecmap); + pdf_dropcmap(usecmap); + } + + pdf_logfont("}\n"); + + error = pdf_storeitem(xref->store, PDF_KCMAP, stmref, cmap); + if (error) + goto cleanup; + + fz_dropobj(stmobj); + + *cmapp = cmap; + return nil; + +cleanup: + if (cmap) + pdf_dropcmap(cmap); + fz_dropobj(stmobj); + return error; +} + +/* + * Load predefined CMap from system + */ +fz_error * +pdf_loadsystemcmap(pdf_cmap **cmapp, char *name) +{ + fz_error *error = nil; + fz_stream *file; + char *cmapdir; + char *usecmapname; + pdf_cmap *usecmap; + pdf_cmap *cmap; + char path[1024]; + + cmap = nil; + file = nil; + + pdf_logfont("load system cmap %s {\n", name); + + cmapdir = getenv("CMAPDIR"); + if (!cmapdir) + return fz_throw("ioerror: CMAPDIR environment not set"); + + strlcpy(path, cmapdir, sizeof path); + strlcat(path, "/", sizeof path); + strlcat(path, name, sizeof path); + + error = fz_openrfile(&file, path); + if (error) + goto cleanup; + + error = pdf_parsecmap(&cmap, file); + if (error) + goto cleanup; + + fz_dropstream(file); + + usecmapname = cmap->usecmapname; + if (usecmapname[0]) + { + pdf_logfont("usecmap %s\n", usecmapname); + error = pdf_loadsystemcmap(&usecmap, usecmapname); + if (error) + goto cleanup; + pdf_setusecmap(cmap, usecmap); + pdf_dropcmap(usecmap); + } + + pdf_logfont("}\n"); + + *cmapp = cmap; + return nil; + +cleanup: + if (cmap) + pdf_dropcmap(cmap); + if (file) + fz_dropstream(file); + return error; +} + +/* + * Create an Identity-* CMap (for both 1 and 2-byte encodings) + */ +fz_error * +pdf_newidentitycmap(pdf_cmap **cmapp, int wmode, int bytes) +{ + fz_error *error; + pdf_cmap *cmap; + + error = pdf_newcmap(&cmap); + if (error) + return error; + + sprintf(cmap->cmapname, "Identity-%c", wmode ? 'V' : 'H'); + + error = pdf_addcodespace(cmap, 0x0000, 0xffff, bytes); + if (error) { + pdf_dropcmap(cmap); + return error; + } + + error = pdf_maprangetorange(cmap, 0x0000, 0xffff, 0); + if (error) { + pdf_dropcmap(cmap); + return error; + } + + error = pdf_sortcmap(cmap); + if (error) { + pdf_dropcmap(cmap); + return error; + } + + pdf_setwmode(cmap, wmode); + + *cmapp = cmap; + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_colorspace1.c b/rosapps/smartpdf/fitz/mupdf/pdf_colorspace1.c new file mode 100644 index 00000000000..e98beaa1a0f --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_colorspace1.c @@ -0,0 +1,755 @@ +#include +#include + +#define noUSECAL + +static void initcs(fz_colorspace *cs, char *name, int n, + void(*to)(fz_colorspace*,float*,float*), + void(*from)(fz_colorspace*,float*,float*), + void(*drop)(fz_colorspace*)) +{ + strlcpy(cs->name, name, sizeof cs->name); + cs->refs = 1; + cs->convpixmap = pdf_convpixmap; + cs->convcolor = pdf_convcolor; + cs->toxyz = to; + cs->fromxyz = from; + cs->drop = drop; + cs->n = n; +} + +/* + * CalGray + */ + +struct calgray +{ + fz_colorspace super; + float white[3]; + float black[3]; + float gamma; +}; + +static void graytoxyz(fz_colorspace *fzcs, float *gray, float *xyz) +{ + struct calgray *cs = (struct calgray *) fzcs; + xyz[0] = pow(gray[0], cs->gamma) * cs->white[0]; + xyz[1] = pow(gray[0], cs->gamma) * cs->white[1]; + xyz[2] = pow(gray[0], cs->gamma) * cs->white[2]; +} + +static void xyztogray(fz_colorspace *fzcs, float *xyz, float *gray) +{ + struct calgray *cs = (struct calgray *) fzcs; + float r = pow(xyz[0], 1.0 / cs->gamma) / cs->white[0]; + float g = pow(xyz[1], 1.0 / cs->gamma) / cs->white[1]; + float b = pow(xyz[2], 1.0 / cs->gamma) / cs->white[2]; + gray[0] = r * 0.3 + g * 0.59 + b * 0.11; +} + +/* + * CalRGB + */ + +struct calrgb +{ + fz_colorspace super; + float white[3]; + float black[3]; + float gamma[3]; + float matrix[9]; + float invmat[9]; +}; + +static void rgbtoxyz(fz_colorspace *fzcs, float *rgb, float *xyz) +{ + struct calrgb *cs = (struct calrgb *) fzcs; + float a = pow(rgb[0], cs->gamma[0]) * cs->white[0]; + float b = pow(rgb[1], cs->gamma[1]) * cs->white[1]; + float c = pow(rgb[2], cs->gamma[2]) * cs->white[2]; + xyz[0] = a * cs->matrix[0] + b * cs->matrix[1] + c * cs->matrix[2]; + xyz[1] = a * cs->matrix[3] + b * cs->matrix[4] + c * cs->matrix[5]; + xyz[2] = a * cs->matrix[6] + b * cs->matrix[7] + c * cs->matrix[8]; +} + +static void xyztorgb(fz_colorspace *fzcs, float *xyz, float *rgb) +{ + struct calrgb *cs = (struct calrgb *) fzcs; + float a = xyz[0] * cs->invmat[0] + xyz[1] * cs->invmat[1] + xyz[2] * cs->invmat[2]; + float b = xyz[0] * cs->invmat[3] + xyz[1] * cs->invmat[4] + xyz[2] * cs->invmat[5]; + float c = xyz[0] * cs->invmat[6] + xyz[1] * cs->invmat[7] + xyz[2] * cs->invmat[8]; + rgb[0] = pow(a, 1.0 / cs->gamma[0]) / cs->white[0]; + rgb[1] = pow(b, 1.0 / cs->gamma[1]) / cs->white[1]; + rgb[2] = pow(c, 1.0 / cs->gamma[2]) / cs->white[2]; +} + +/* + * DeviceCMYK piggybacks on DeviceRGB + */ + +static void devicecmyktoxyz(fz_colorspace *cs, float *cmyk, float *xyz) +{ + float rgb[3]; + rgb[0] = 1.0 - MIN(1.0, cmyk[0] + cmyk[3]); + rgb[1] = 1.0 - MIN(1.0, cmyk[1] + cmyk[3]); + rgb[2] = 1.0 - MIN(1.0, cmyk[2] + cmyk[3]); + rgbtoxyz(pdf_devicergb, rgb, xyz); +} + +static void xyztodevicecmyk(fz_colorspace *cs, float *xyz, float *cmyk) +{ + float rgb[3]; + float c, m, y, k; + xyztorgb(pdf_devicergb, xyz, rgb); + c = 1.0 - rgb[0]; + m = 1.0 - rgb[0]; + y = 1.0 - rgb[0]; + k = MIN(c, MIN(m, y)); + cmyk[0] = c - k; + cmyk[1] = m - k; + cmyk[2] = y - k; + cmyk[3] = k; +} + +/* + * CIE Lab + */ + +struct cielab +{ + fz_colorspace super; + float white[3]; + float black[3]; + float range[4]; +}; + +static inline float fung(float x) +{ + if (x >= 6.0 / 29.0) + return x * x * x; + return (108.0 / 841.0) * (x - (4.0 / 29.0)); +} + +static inline float invg(float x) +{ + if (x > 0.008856) + return pow(x, 1.0 / 3.0); + return (7.787 * x) + (16.0 / 116.0); +} + +static void labtoxyz(fz_colorspace *fzcs, float *lab, float *xyz) +{ + struct cielab *cs = (struct cielab *) fzcs; + float lstar, astar, bstar, l, m, n; + float tmp[3]; + tmp[0] = lab[0] * 100; + tmp[1] = lab[1] * 200 - 100; + tmp[2] = lab[2] * 200 - 100; + lstar = tmp[0]; + astar = MAX(MIN(tmp[1], cs->range[1]), cs->range[0]); + bstar = MAX(MIN(tmp[2], cs->range[3]), cs->range[2]); + l = (lstar + 16.0) / 116.0 + astar / 500.0; + m = (lstar + 16.0) / 116.0; + n = (lstar + 16.0) / 116.0 - bstar / 200.0; + xyz[0] = fung(l) * cs->white[0]; + xyz[1] = fung(m) * cs->white[1]; + xyz[2] = fung(n) * cs->white[2]; +} + +static void xyztolab(fz_colorspace *fzcs, float *xyz, float *lab) +{ + struct cielab *cs = (struct cielab *) fzcs; + float tmp[3]; + float yyn = xyz[1] / cs->white[1]; + if (yyn < 0.008856) + tmp[0] = 116.0 * yyn * (1.0 / 3.0) - 16.0; + else + tmp[0] = 903.3 * yyn; + tmp[1] = 500 * (invg(xyz[0]/cs->white[0]) - invg(xyz[1]/cs->white[1])); + tmp[2] = 200 * (invg(xyz[1]/cs->white[1]) - invg(xyz[2]/cs->white[2])); + lab[0] = tmp[0] / 100.0; + lab[1] = (tmp[1] + 100) / 200.0; + lab[2] = (tmp[2] + 100) / 200.0; +} + +/* + * Define global Device* colorspaces as Cal* + */ + +static struct calgray kdevicegray = +{ + { -1, "DeviceGray", 1, pdf_convpixmap, pdf_convcolor, graytoxyz, xyztogray, nil }, + { 1.0000, 1.0000, 1.0000 }, + { 0.0000, 0.0000, 0.0000 }, + 1.0000 +}; + +static struct calrgb kdevicergb = +{ + { -1, "DeviceRGB", 3, pdf_convpixmap, pdf_convcolor, rgbtoxyz, xyztorgb, nil }, + { 1.0000, 1.0000, 1.0000 }, + { 0.0000, 0.0000, 0.0000 }, + { 1.0000, 1.0000, 1.0000 }, + { 1,0,0, 0,1,0, 0,0,1 }, + { 1,0,0, 0,1,0, 0,0,1 }, +}; + +static fz_colorspace kdevicecmyk = +{ + -1, "DeviceCMYK", 4, pdf_convpixmap, pdf_convcolor, devicecmyktoxyz, xyztodevicecmyk, nil +}; + +static struct cielab kdevicelab = +{ + { -1, "Lab", 3, fz_stdconvpixmap, fz_stdconvcolor, labtoxyz, xyztolab, nil }, + { 1.0000, 1.0000, 1.0000 }, + { 0.0000, 0.0000, 0.0000 }, + { -100, 100, -100, 100 }, +}; + +static fz_colorspace kdevicepattern = +{ + -1, "Pattern", 0, nil, nil, nil, nil, nil +}; + +fz_colorspace *pdf_devicegray = &kdevicegray.super; +fz_colorspace *pdf_devicergb = &kdevicergb.super; +fz_colorspace *pdf_devicecmyk = &kdevicecmyk; +fz_colorspace *pdf_devicelab = &kdevicelab.super; +fz_colorspace *pdf_devicepattern = &kdevicepattern; + +/* + * Colorspace parsing + */ + +#ifdef USECAL + +static fz_error * +loadcalgray(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict) +{ + fz_error *error; + struct calgray *cs; + fz_obj *tmp; + + error = pdf_resolve(&dict, xref); + if (error) + return error; + + cs = fz_malloc(sizeof(struct calgray)); + if (!cs) + return fz_outofmem; + + pdf_logrsrc("load CalGray\n"); + + initcs((fz_colorspace*)cs, "CalGray", 1, graytoxyz, xyztogray, nil); + + cs->white[0] = 1.0; + cs->white[1] = 1.0; + cs->white[2] = 1.0; + + cs->black[0] = 0.0; + cs->black[1] = 0.0; + cs->black[2] = 0.0; + + cs->gamma = 1.0; + + tmp = fz_dictgets(dict, "WhitePoint"); + if (fz_isarray(tmp)) + { + cs->white[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->white[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->white[2] = fz_toreal(fz_arrayget(tmp, 2)); + } + + tmp = fz_dictgets(dict, "BlackPoint"); + if (fz_isarray(tmp)) + { + cs->black[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->black[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->black[2] = fz_toreal(fz_arrayget(tmp, 2)); + } + + tmp = fz_dictgets(dict, "Gamma"); + if (fz_isreal(tmp)) + cs->gamma = fz_toreal(tmp); + + fz_dropobj(dict); + + *csp = (fz_colorspace*) cs; + return nil; +} + +static fz_error * +loadcalrgb(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict) +{ + fz_error *error; + struct calrgb *cs; + fz_obj *tmp; + int i; + + error = pdf_resolve(&dict, xref); + if (error) + return error; + + cs = fz_malloc(sizeof(struct calrgb)); + if (!cs) + return fz_outofmem; + + pdf_logrsrc("load CalRGB\n"); + + initcs((fz_colorspace*)cs, "CalRGB", 3, rgbtoxyz, xyztorgb, nil); + + cs->white[0] = 1.0; + cs->white[1] = 1.0; + cs->white[2] = 1.0; + + cs->black[0] = 0.0; + cs->black[1] = 0.0; + cs->black[2] = 0.0; + + cs->gamma[0] = 1.0; + cs->gamma[1] = 1.0; + cs->gamma[2] = 1.0; + + cs->matrix[0] = 1.0; cs->matrix[1] = 0.0; cs->matrix[2] = 0.0; + cs->matrix[3] = 0.0; cs->matrix[4] = 1.0; cs->matrix[5] = 0.0; + cs->matrix[6] = 0.0; cs->matrix[7] = 0.0; cs->matrix[8] = 1.0; + + tmp = fz_dictgets(dict, "WhitePoint"); + if (fz_isarray(tmp)) + { + cs->white[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->white[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->white[2] = fz_toreal(fz_arrayget(tmp, 2)); + } + + tmp = fz_dictgets(dict, "BlackPoint"); + if (fz_isarray(tmp)) + { + cs->black[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->black[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->black[2] = fz_toreal(fz_arrayget(tmp, 2)); + } + + tmp = fz_dictgets(dict, "Gamma"); + if (fz_isarray(tmp)) + { + cs->gamma[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->gamma[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->gamma[2] = fz_toreal(fz_arrayget(tmp, 2)); + } + + tmp = fz_dictgets(dict, "Matrix"); + if (fz_isarray(tmp)) + { + for (i = 0; i < 9; i++) + cs->matrix[i] = fz_toreal(fz_arrayget(tmp, i)); + } + + fz_invert3x3(cs->invmat, cs->matrix); + + fz_dropobj(dict); + + *csp = (fz_colorspace*) cs; + return nil; +} + +static fz_error * +loadlab(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict) +{ + fz_error *error; + struct cielab *cs; + fz_obj *tmp; + + error = pdf_resolve(&dict, xref); + if (error) + return error; + + cs = fz_malloc(sizeof(struct cielab)); + if (!cs) + return fz_outofmem; + + pdf_logrsrc("load Lab\n"); + + initcs((fz_colorspace*)cs, "Lab", 3, labtoxyz, xyztolab, nil); + + cs->white[0] = 1.0; + cs->white[1] = 1.0; + cs->white[2] = 1.0; + + cs->black[0] = 0.0; + cs->black[1] = 0.0; + cs->black[2] = 0.0; + + cs->range[0] = -100; + cs->range[1] = 100; + cs->range[2] = -100; + cs->range[3] = 100; + + tmp = fz_dictgets(dict, "WhitePoint"); + if (fz_isarray(tmp)) + { + cs->white[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->white[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->white[2] = fz_toreal(fz_arrayget(tmp, 2)); + } + + tmp = fz_dictgets(dict, "BlackPoint"); + if (fz_isarray(tmp)) + { + cs->black[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->black[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->black[2] = fz_toreal(fz_arrayget(tmp, 2)); + } + + tmp = fz_dictgets(dict, "Range"); + if (fz_isarray(tmp)) + { + cs->range[0] = fz_toreal(fz_arrayget(tmp, 0)); + cs->range[1] = fz_toreal(fz_arrayget(tmp, 1)); + cs->range[2] = fz_toreal(fz_arrayget(tmp, 2)); + cs->range[3] = fz_toreal(fz_arrayget(tmp, 3)); + } + + fz_dropobj(dict); + + *csp = (fz_colorspace*) cs; + return nil; +} + +#endif + +/* + * ICCBased + */ + +static fz_error * +loadiccbased(fz_colorspace **csp, pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + fz_obj *dict; + int n; + + pdf_logrsrc("load ICCBased\n"); + + error = pdf_loadindirect(&dict, xref, ref); + if (error) + return error; + + n = fz_toint(fz_dictgets(dict, "N")); + + fz_dropobj(dict); + + switch (n) + { + case 1: *csp = pdf_devicegray; return nil; + case 3: *csp = pdf_devicergb; return nil; + case 4: *csp = pdf_devicecmyk; return nil; + } + + return fz_throw("syntaxerror: ICCBased must have 1, 3 or 4 components"); +} + +/* + * Separation and DeviceN + */ + +struct separation +{ + fz_colorspace super; + fz_colorspace *base; + pdf_function *tint; +}; + +static void separationtoxyz(fz_colorspace *fzcs, float *sep, float *xyz) +{ + struct separation *cs = (struct separation *)fzcs; + fz_error *error; + float alt[FZ_MAXCOLORS]; + + error = pdf_evalfunction(cs->tint, sep, fzcs->n, alt, cs->base->n); + if (error) + { + fz_warn("separation: %s", error->msg); + fz_droperror(error); + xyz[0] = 0; + xyz[1] = 0; + xyz[2] = 0; + return; + } + + cs->base->toxyz(cs->base, alt, xyz); +} + +static void +dropseparation(fz_colorspace *fzcs) +{ + struct separation *cs = (struct separation *)fzcs; + fz_dropcolorspace(cs->base); + pdf_dropfunction(cs->tint); +} + +static fz_error * +loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) +{ + fz_error *error; + struct separation *cs; + fz_obj *nameobj = fz_arrayget(array, 1); + fz_obj *baseobj = fz_arrayget(array, 2); + fz_obj *tintobj = fz_arrayget(array, 3); + fz_colorspace *base; + pdf_function *tint; + int n; + + pdf_logrsrc("load Separation {\n"); + + if (fz_isarray(nameobj)) + n = fz_arraylen(nameobj); + else + n = 1; + + pdf_logrsrc("n = %d\n", n); + + error = pdf_resolve(&baseobj, xref); + if (error) + return error; + error = pdf_loadcolorspace(&base, xref, baseobj); + fz_dropobj(baseobj); + if (error) + return error; + + error = pdf_loadfunction(&tint, xref, tintobj); + if (error) + { + fz_dropcolorspace(base); + return error; + } + + cs = fz_malloc(sizeof(struct separation)); + if (!cs) + { + pdf_dropfunction(tint); + fz_dropcolorspace(base); + return fz_outofmem; + } + + initcs((fz_colorspace*)cs, + n == 1 ? "Separation" : "DeviceN", n, + separationtoxyz, nil, dropseparation); + + cs->base = base; + cs->tint = tint; + + pdf_logrsrc("}\n"); + + *csp = (fz_colorspace*)cs; + return nil; +} + +/* + * Indexed + */ + +#if 0 +static void +indexedtoxyz(fz_colorspace *fzcs, float *ind, float *xyz) +{ + pdf_indexed *cs = (pdf_indexed *)fzcs; + float alt[FZ_MAXCOLORS]; + int i, k; + i = ind[0] * 255; + i = CLAMP(i, 0, cs->high); + for (k = 0; k < cs->base->n; k++) + alt[k] = cs->lookup[i * cs->base->n + k] / 255.0; + cs->base->toxyz(cs->base, alt, xyz); +} +#endif + +static void +dropindexed(fz_colorspace *fzcs) +{ + pdf_indexed *cs = (pdf_indexed *)fzcs; + if (cs->base) fz_dropcolorspace(cs->base); + if (cs->lookup) fz_free(cs->lookup); +} + +static fz_error * +loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) +{ + fz_error *error; + pdf_indexed *cs; + fz_obj *baseobj = fz_arrayget(array, 1); + fz_obj *highobj = fz_arrayget(array, 2); + fz_obj *lookup = fz_arrayget(array, 3); + fz_colorspace *base; + int n; + + pdf_logrsrc("load Indexed {\n"); + + error = pdf_resolve(&baseobj, xref); + if (error) + return error; + error = pdf_loadcolorspace(&base, xref, baseobj); + fz_dropobj(baseobj); + if (error) + return error; + + pdf_logrsrc("base %s\n", base->name); + + cs = fz_malloc(sizeof(pdf_indexed)); + if (!cs) + { + fz_dropcolorspace(base); + return fz_outofmem; + } + + initcs((fz_colorspace*)cs, "Indexed", 1, nil, nil, dropindexed); + + cs->base = base; + cs->high = fz_toint(highobj); + + n = base->n * (cs->high + 1); + + cs->lookup = fz_malloc(n); + if (!cs->lookup) + { + fz_dropcolorspace((fz_colorspace*)cs); + return fz_outofmem; + } + + if (fz_isstring(lookup) && fz_tostrlen(lookup) == n) + { + unsigned char *buf; + int i; + + pdf_logrsrc("string lookup\n"); + + buf = fz_tostrbuf(lookup); + for (i = 0; i < n; i++) + cs->lookup[i] = buf[i]; + } + + if (fz_isindirect(lookup)) + { + fz_buffer *buf; + int i; + + pdf_logrsrc("stream lookup\n"); + + error = pdf_loadstream(&buf, xref, fz_tonum(lookup), fz_togen(lookup)); + if (error) + { + fz_dropcolorspace((fz_colorspace*)cs); + return error; + } + + for (i = 0; i < n && i < (buf->wp - buf->rp); i++) + cs->lookup[i] = buf->rp[i]; + + fz_dropbuffer(buf); + } + + pdf_logrsrc("}\n"); + + *csp = (fz_colorspace*)cs; + return nil; +} + +/* + * Parse and create colorspace from PDF object. + */ + +fz_error * +pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj) +{ + if (fz_isname(obj)) + { + if (!strcmp(fz_toname(obj), "DeviceGray")) + *csp = pdf_devicegray; + else if (!strcmp(fz_toname(obj), "DeviceRGB")) + *csp = pdf_devicergb; + else if (!strcmp(fz_toname(obj), "DeviceCMYK")) + *csp = pdf_devicecmyk; + else if (!strcmp(fz_toname(obj), "G")) + *csp = pdf_devicegray; + else if (!strcmp(fz_toname(obj), "RGB")) + *csp = pdf_devicergb; + else if (!strcmp(fz_toname(obj), "CMYK")) + *csp = pdf_devicecmyk; + else if (!strcmp(fz_toname(obj), "Pattern")) + *csp = pdf_devicepattern; + else + return fz_throw("unknown colorspace: %s", fz_toname(obj)); + return nil; + } + + else if (fz_isarray(obj)) + { + fz_obj *name = fz_arrayget(obj, 0); + + if (fz_isname(name)) + { + if (!strcmp(fz_toname(name), "CalCMYK")) + *csp = pdf_devicecmyk; + +#ifdef USECAL + else if (!strcmp(fz_toname(name), "CalGray")) + return loadcalgray(csp, xref, fz_arrayget(obj, 1)); + else if (!strcmp(fz_toname(name), "CalRGB")) + return loadcalrgb(csp, xref, fz_arrayget(obj, 1)); + else if (!strcmp(fz_toname(name), "Lab")) + return loadlab(csp, xref, fz_arrayget(obj, 1)); +#else + else if (!strcmp(fz_toname(name), "CalGray")) + *csp = pdf_devicegray; + else if (!strcmp(fz_toname(name), "CalRGB")) + *csp = pdf_devicergb; + else if (!strcmp(fz_toname(name), "Lab")) + *csp = pdf_devicelab; +#endif + + else if (!strcmp(fz_toname(name), "ICCBased")) + return loadiccbased(csp, xref, fz_arrayget(obj, 1)); + + else if (!strcmp(fz_toname(name), "Indexed")) + return loadindexed(csp, xref, obj); + + else if (!strcmp(fz_toname(name), "I")) + return loadindexed(csp, xref, obj); + + else if (!strcmp(fz_toname(name), "Separation")) + return loadseparation(csp, xref, obj); + + else if (!strcmp(fz_toname(name), "DeviceN")) + return loadseparation(csp, xref, obj); + + /* load base colorspace instead */ + else if (!strcmp(fz_toname(name), "Pattern")) + { + fz_error *error; + + obj = fz_arrayget(obj, 1); + if (!obj) + { + *csp = pdf_devicepattern; + return nil; + } + + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = pdf_loadcolorspace(csp, xref, obj); + fz_dropobj(obj); + return error; + } + + else + return fz_throw("syntaxerror: unknown colorspace %s", fz_toname(name)); + + return nil; + } + } + + return fz_throw("syntaxerror: could not parse color space"); +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_colorspace2.c b/rosapps/smartpdf/fitz/mupdf/pdf_colorspace2.c new file mode 100644 index 00000000000..d414a125aac --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_colorspace2.c @@ -0,0 +1,201 @@ +#include +#include + +/* + * Optimized color conversions for Device colorspaces + */ + +static void fastgraytorgb(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[1]; + d[3] = s[1]; + s += 2; + d += 4; + } +} + +static void fastgraytocmyk(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = 0; + d[2] = 0; + d[3] = 0; + d[4] = s[1]; + s += 2; + d += 5; + } +} + +static void fastrgbtogray(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = ((s[1]+1) * 77 + (s[2]+1) * 150 + (s[3]+1) * 28) >> 8; + s += 4; + d += 2; + } +} + +static void fastrgbtocmyk(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + unsigned char c = 255 - s[1]; + unsigned char m = 255 - s[2]; + unsigned char y = 255 - s[3]; + unsigned char k = MIN(c, MIN(y, m)); + d[0] = s[0]; + d[1] = c - k; + d[2] = m - k; + d[3] = y - k; + d[4] = k; + s += 4; + d += 5; + } +} + +static void fastcmyktogray(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + unsigned char c = fz_mul255(s[1], 77); + unsigned char m = fz_mul255(s[2], 150); + unsigned char y = fz_mul255(s[3], 28); + d[0] = s[0]; + d[1] = 255 - MIN(c + m + y + s[4], 255); + s += 5; + d += 2; + } +} + +static void fastcmyktorgb(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + int n = src->w * src->h; + while (n--) + { + d[0] = s[0]; + d[1] = 255 - MIN(s[1] + s[4], 255); + d[2] = 255 - MIN(s[2] + s[4], 255); + d[3] = 255 - MIN(s[3] + s[4], 255); + s += 5; + d += 4; + } +} + +void pdf_convpixmap(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp) +{ + if (ss == pdf_devicegray) + { + if (ds == pdf_devicergb) fastgraytorgb(sp, dp); + else if (ds == pdf_devicecmyk) fastgraytocmyk(sp, dp); + else fz_stdconvpixmap(ss, sp, ds, dp); + } + + else if (ss == pdf_devicergb) + { + if (ds == pdf_devicegray) fastrgbtogray(sp, dp); + else if (ds == pdf_devicecmyk) fastrgbtocmyk(sp, dp); + else fz_stdconvpixmap(ss, sp, ds, dp); + + } + + else if (ss == pdf_devicecmyk) + { + if (ds == pdf_devicegray) fastcmyktogray(sp, dp); + else if (ds == pdf_devicergb) fastcmyktorgb(sp, dp); + else fz_stdconvpixmap(ss, sp, ds, dp); + } + + else fz_stdconvpixmap(ss, sp, ds, dp); +} + +void pdf_convcolor(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv) +{ + + if (ss == pdf_devicegray) + { + if (ds == pdf_devicergb) + { + dv[0] = sv[0]; + dv[1] = sv[0]; + dv[2] = sv[0]; + } + else if (ds == pdf_devicecmyk) + { + dv[0] = 0; + dv[1] = 0; + dv[2] = 0; + dv[3] = sv[0]; + } + else + fz_stdconvcolor(ss, sv, ds, dv); + } + + else if (ss == pdf_devicergb) + { + if (ds == pdf_devicegray) + { + dv[0] = sv[0] * 0.3 + sv[1] * 0.59 + sv[2] * 0.11; + } + else if (ds == pdf_devicecmyk) + { + float c = 1.0 - sv[1]; + float m = 1.0 - sv[2]; + float y = 1.0 - sv[3]; + float k = MIN(c, MIN(y, m)); + dv[0] = c - k; + dv[1] = m - k; + dv[2] = y - k; + dv[3] = k; + } + else + fz_stdconvcolor(ss, sv, ds, dv); + } + + else if (ss == pdf_devicecmyk) + { + if (ds == pdf_devicegray) + { + float c = sv[1] * 0.3; + float m = sv[2] * 0.59; + float y = sv[2] * 0.11; + dv[0] = 1.0 - MIN(c + m + y + sv[3], 1.0); + } + else if (ds == pdf_devicergb) + { + dv[0] = 1.0 - MIN(sv[0] + sv[3], 1.0); + dv[1] = 1.0 - MIN(sv[1] + sv[3], 1.0); + dv[2] = 1.0 - MIN(sv[2] + sv[3], 1.0); + } + else + fz_stdconvcolor(ss, sv, ds, dv); + } + + else + fz_stdconvcolor(ss, sv, ds, dv); +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_crypt.c b/rosapps/smartpdf/fitz/mupdf/pdf_crypt.c new file mode 100644 index 00000000000..4af8e9fe38d --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_crypt.c @@ -0,0 +1,451 @@ +#include "fitz.h" +#include "mupdf.h" + +static const unsigned char padding[32] = +{ + 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, + 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, + 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, + 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a +}; + +static void voodoo50(unsigned char *buf, int n) +{ + fz_md5 md5; + int i; + + for (i = 0; i < 50; i++) + { + fz_md5init(&md5); + fz_md5update(&md5, buf, n); + fz_md5final(&md5, buf); + } +} + +static void voodoo19(unsigned char *data, int ndata, unsigned char *key, int nkey) +{ + fz_arc4 arc4; + unsigned char keybuf[16]; + int i, k; + + for (i = 1; i <= 19; i++) + { + for (k = 0; k < nkey; k++) + keybuf[k] = key[k] ^ (unsigned char)i; + fz_arc4init(&arc4, keybuf, nkey); + fz_arc4encrypt(&arc4, data, data, ndata); + } +} + +static void padpassword(unsigned char *buf, char *pw, int pwlen) +{ + if (pwlen > 32) + pwlen = 32; + memcpy(buf, pw, pwlen); + memcpy(buf + pwlen, padding, 32 - pwlen); +} + +/* + * Create crypt object for decrypting given the + * Encoding dictionary and file ID + */ +fz_error * +pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id) +{ + pdf_crypt *crypt = nil; + fz_obj *obj; + int m; + + obj = fz_dictgets(enc, "V"); + m = 0; + if (fz_isint(obj)) + m = fz_toint(obj); + if (m != 1 && m != 2) + return fz_throw("unsupported encryption: %d", m); + + crypt = fz_malloc(sizeof(pdf_crypt)); + if (!crypt) + return fz_outofmem; + + crypt->encrypt = fz_keepobj(enc); + crypt->id = nil; + + obj = fz_dictgets(enc, "O"); + if (!fz_isstring(obj) || fz_tostrlen(obj) != 32) + goto cleanup; + memcpy(crypt->o, fz_tostrbuf(obj), 32); + + obj = fz_dictgets(enc, "U"); + if (!fz_isstring(obj) || fz_tostrlen(obj) != 32) + goto cleanup; + memcpy(crypt->u, fz_tostrbuf(obj), 32); + + obj = fz_dictgets(enc, "P"); + if (!fz_isint(obj)) + goto cleanup; + crypt->p = fz_toint(obj); + + obj = fz_dictgets(enc, "Length"); + if (fz_isint(obj)) + crypt->n = fz_toint(obj) / 8; + else + crypt->n = 40 / 8; + if (crypt->n < 5) goto cleanup; + if (crypt->n > 16) goto cleanup; + + obj = fz_dictgets(enc, "R"); + if (!fz_isint(obj)) + goto cleanup; + crypt->r = fz_toint(obj); + if (crypt->r != 2 && crypt->r != 3) + goto cleanup; + if (crypt->r == 2 && crypt->n != 5) + goto cleanup; + + if (!fz_isarray(id) || fz_arraylen(id) != 2) + goto cleanup; + obj = fz_arrayget(id, 0); + if (!fz_isstring(obj)) + goto cleanup; + crypt->id = fz_keepobj(obj); + + crypt->keylen = crypt->n + 5; + if (crypt->keylen > 16) + crypt->keylen = 16; + + memset(crypt->key, 0, 16); + + *cp = crypt; + return nil; + +cleanup: + pdf_dropcrypt(crypt); + return fz_throw("corrupt encryption dictionary"); +} + +void +pdf_dropcrypt(pdf_crypt *crypt) +{ + if (crypt->encrypt) fz_dropobj(crypt->encrypt); + if (crypt->id) fz_dropobj(crypt->id); + fz_free(crypt); +} + +static void +createobjkey(pdf_crypt *crypt, unsigned oid, unsigned gid, unsigned char *key) +{ + unsigned char message[5]; + fz_md5 md5; + + /* Algorithm 3.1 Encryption of data using an encryption key */ + + fz_md5init(&md5); + + fz_md5update(&md5, crypt->key, crypt->n); + + message[0] = oid & 0xFF; + message[1] = (oid >> 8) & 0xFF; + message[2] = (oid >> 16) & 0xFF; + + message[3] = gid & 0xFF; + message[4] = (gid >> 8) & 0xFF; + + fz_md5update(&md5, message, 5); + + fz_md5final(&md5, key); +} + +/* + * Algorithm 3.2 Computing an encryption key + */ +static void +createkey(pdf_crypt *crypt, char *userpw, int pwlen) +{ + unsigned char buf[32]; + fz_md5 md5; + + /* Step 1 + 2 */ + fz_md5init(&md5); + padpassword(buf, userpw, pwlen); + fz_md5update(&md5, buf, 32); + + /* Step 3 */ + fz_md5update(&md5, crypt->o, 32); + + /* Step 4 */ + buf[0] = crypt->p & 0xFF; + buf[1] = (crypt->p >> 8) & 0xFF; + buf[2] = (crypt->p >> 16) & 0xFF; + buf[3] = (crypt->p >> 24) & 0xFF; + fz_md5update(&md5, buf, 4); + + /* Step 5 */ + fz_md5update(&md5, fz_tostrbuf(crypt->id), fz_tostrlen(crypt->id)); + fz_md5final(&md5, crypt->key); + + /* Step 6 (rev 3 only) */ + if (crypt->r == 3) + voodoo50(crypt->key, crypt->n); + + /* Step 7: key is in crypt->key */ +} + +/* + * Algorithm 3.3 Computing the O value + */ +static void +createowner(pdf_crypt *crypt, char *userpw, char *ownerpw) +{ + unsigned char buf[32]; + unsigned char key[16]; + fz_arc4 arc4; + fz_md5 md5; + + /* Step 1 + 2 */ + if (strlen(ownerpw) == 0) + ownerpw = userpw; + padpassword(buf, ownerpw, strlen(ownerpw)); + fz_md5init(&md5); + fz_md5update(&md5, buf, 32); + fz_md5final(&md5, key); + + /* Step 3 (rev 3 only) */ + if (crypt->r == 3) + voodoo50(key, crypt->n); + + /* Step 4 */ + fz_arc4init(&arc4, key, crypt->n); + + /* Step 5 */ + padpassword(buf, userpw, strlen(ownerpw)); + + /* Step 6 */ + fz_arc4encrypt(&arc4, buf, buf, 32); + + /* Step 7 (rev 3 only) */ + if (crypt->r == 3) + voodoo19(buf, 32, key, crypt->n); + + /* Step 8 */ + memcpy(crypt->o, buf, 32); +} + +/* + * Algorithm 3.4 Computing the U value (rev 2) + * Algorithm 3.5 Computing the U value (rev 3) + */ +static void +createuser(pdf_crypt *crypt, char *userpw, int pwlen) +{ + unsigned char key[16]; + fz_arc4 arc4; + fz_md5 md5; + + if (crypt->r == 2) + { + createkey(crypt, userpw, pwlen); + fz_arc4init(&arc4, crypt->key, crypt->n); + fz_arc4encrypt(&arc4, crypt->u, (unsigned char *)padding, 32); + } + + if (crypt->r == 3) + { + /* Step 1 */ + createkey(crypt, userpw, pwlen); + + /* Step 2 */ + fz_md5init(&md5); + fz_md5update(&md5, (unsigned char *)padding, 32); + + /* Step 3 */ + fz_md5update(&md5, fz_tostrbuf(crypt->id), fz_tostrlen(crypt->id)); + fz_md5final(&md5, key); + + /* Step 4 */ + fz_arc4init(&arc4, crypt->key, crypt->n); + fz_arc4encrypt(&arc4, key, key, 16); + + /* Step 5 */ + voodoo19(key, 16, crypt->key, crypt->n); + + /* Step 6 */ + memcpy(crypt->u, key, 16); + memset(crypt->u + 16, 0, 16); + } +} + +/* + * Create crypt object for encrypting, given passwords, + * permissions, and file ID + */ +fz_error * +pdf_newencrypt(pdf_crypt **cp, char *userpw, char *ownerpw, int p, int n, fz_obj *id) +{ + fz_error *error; + pdf_crypt *crypt; + + crypt = fz_malloc(sizeof(pdf_crypt)); + if (!crypt) + return fz_outofmem; + + crypt->encrypt = nil; + crypt->id = fz_keepobj(fz_arrayget(id, 0)); + crypt->p = p; + crypt->n = MIN(MAX(n / 8, 5), 16); + crypt->keylen = MIN(crypt->n + 5, 16); + crypt->r = crypt->n == 5 ? 2 : 3; + + createowner(crypt, userpw, ownerpw); + createuser(crypt, userpw, strlen(userpw)); + + error = fz_packobj(&crypt->encrypt, + "<< /Filter /Standard " + "/V %i /R %i " + "/O %# /U %# " + "/P %i " + "/Length %i >>", + crypt->r == 2 ? 1 : 2, + crypt->r, + crypt->o, 32, + crypt->u, 32, + crypt->p, + crypt->n * 8); + if (error) + { + pdf_dropcrypt(crypt); + return error; + } + + *cp = crypt; + return nil; +} + +/* + * Algorithm 3.6 Checking the user password + */ + +fz_error * +pdf_setpassword(pdf_crypt *crypt, char *pw) +{ + fz_error *error = pdf_setuserpassword(crypt, pw, strlen(pw)); + if (error) + { + fz_droperror(error); + error = pdf_setownerpassword(crypt, pw, strlen(pw)); + } + return error; +} + +fz_error * +pdf_setuserpassword(pdf_crypt *crypt, char *userpw, int pwlen) +{ + unsigned char saved[32]; + unsigned char test[32]; + + memcpy(saved, crypt->u, 32); + createuser(crypt, userpw, pwlen); + memcpy(test, crypt->u, 32); + memcpy(crypt->u, saved, 32); + + if (memcmp(test, saved, crypt->r == 3 ? 16 : 32) != 0) + return fz_throw("invalid password"); + + return nil; +} + +fz_error * +pdf_setownerpassword(pdf_crypt *crypt, char *ownerpw, int pwlen) +{ + unsigned char buf[32]; + unsigned char key[16]; + fz_arc4 arc4; + fz_md5 md5; + + /* Step 1 + 2 */ + padpassword(buf, ownerpw, pwlen); + fz_md5init(&md5); + fz_md5update(&md5, buf, 32); + fz_md5final(&md5, key); + + /* Step 3 (rev 3 only) */ + if (crypt->r == 3) + voodoo50(key, crypt->n); + + /* Step 4 */ + fz_arc4init(&arc4, key, crypt->n); + + if (crypt->r == 2) + { + fz_arc4encrypt(&arc4, buf, crypt->o, 32); + } + + if (crypt->r == 3) + { + unsigned char keyxor[16]; + int i; + int k; + + memcpy(buf, crypt->o, 32); + + for(i = 19; i >= 0; --i) + { + for(k = 0; k < crypt->keylen; ++k) + keyxor[k] = key[k] ^ i; + fz_arc4init(&arc4, keyxor, crypt->keylen); + fz_arc4encrypt(&arc4, buf, buf, 32); + } + } + + return pdf_setuserpassword(crypt, buf, 32); +} + +/* + * Recursively (and destructively!) de/encrypt all strings in obj + */ +void +pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid) +{ + fz_arc4 arc4; + unsigned char key[16]; + unsigned char *s; + int i, n; + + if (fz_isstring(obj)) + { + s = fz_tostrbuf(obj); + n = fz_tostrlen(obj); + createobjkey(crypt, oid, gid, key); + fz_arc4init(&arc4, key, crypt->keylen); + fz_arc4encrypt(&arc4, s, s, n); + } + + else if (fz_isarray(obj)) + { + n = fz_arraylen(obj); + for (i = 0; i < n; i++) + { + pdf_cryptobj(crypt, fz_arrayget(obj, i), oid, gid); + } + } + + else if (fz_isdict(obj)) + { + n = fz_dictlen(obj); + for (i = 0; i < n; i++) + { + pdf_cryptobj(crypt, fz_dictgetval(obj, i), oid, gid); + } + } +} + +/* + * Create filter suitable for de/encrypting a stream + */ +fz_error * +pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gid) +{ + unsigned char key[16]; + createobjkey(crypt, oid, gid, key); + return fz_newarc4filter(fp, key, crypt->keylen); +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_debug.c b/rosapps/smartpdf/fitz/mupdf/pdf_debug.c new file mode 100644 index 00000000000..4704794bfaf --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_debug.c @@ -0,0 +1,92 @@ +#include +#include + +/* + * Enable logging by setting environment variable MULOG to: + * (a)ll or a combination of + * (x)ref (r)src (f)ont (i)mage (s)hade (p)age + * + * eg. MULOG=fis ./x11pdf mytestfile.pdf + */ + +enum +{ + PDF_LXREF = 1, + PDF_LRSRC = 2, + PDF_LFONT = 4, + PDF_LIMAGE = 8, + PDF_LSHADE = 16, + PDF_LPAGE = 32 +}; + +static inline void pdflog(int tag, char *name, char *fmt, va_list ap) +{ + static int flags = 128; + static int level = 0; + static int push = 1; + int i; + + if (flags == 128) + { + char *s = getenv("MULOG"); + flags = 0; + if (s) + { + if (strstr(s, "a")) + flags |= 0xffff; + if (strstr(s, "x")) + flags |= PDF_LXREF; + if (strstr(s, "r")) + flags |= PDF_LRSRC; + if (strstr(s, "f")) + flags |= PDF_LFONT; + if (strstr(s, "i")) + flags |= PDF_LIMAGE; + if (strstr(s, "s")) + flags |= PDF_LSHADE; + if (strstr(s, "p")) + flags |= PDF_LPAGE; + } + } + + if (!(flags & tag)) + return; + + if (strchr(fmt, '}')) + level --; + + if (push) + { + printf("%s: ", name); + for (i = 0; i < level; i++) + printf(" "); + } + + vprintf(fmt, ap); + + if (strchr(fmt, '{')) + level ++; + + push = strchr(fmt, '\n') != 0; + + fflush(stdout); +} + +void pdf_logxref(char *fmt, ...) +{va_list ap;va_start(ap,fmt);pdflog(PDF_LXREF,"xref",fmt,ap);va_end(ap);} + +void pdf_logrsrc(char *fmt, ...) +{va_list ap;va_start(ap,fmt);pdflog(PDF_LRSRC,"rsrc",fmt,ap);va_end(ap);} + +void pdf_logfont(char *fmt, ...) +{va_list ap;va_start(ap,fmt);pdflog(PDF_LFONT,"font",fmt,ap);va_end(ap);} + +void pdf_logimage(char *fmt, ...) +{va_list ap;va_start(ap,fmt);pdflog(PDF_LIMAGE,"imag",fmt,ap);va_end(ap);} + +void pdf_logshade(char *fmt, ...) +{va_list ap;va_start(ap,fmt);pdflog(PDF_LSHADE,"shad",fmt,ap);va_end(ap);} + +void pdf_logpage(char *fmt, ...) +{va_list ap;va_start(ap,fmt);pdflog(PDF_LPAGE,"page",fmt,ap);va_end(ap);} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_doctor.c b/rosapps/smartpdf/fitz/mupdf/pdf_doctor.c new file mode 100644 index 00000000000..81d749e130b --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_doctor.c @@ -0,0 +1,267 @@ +#include +#include + +/* + * Sweep and mark reachable objects + */ + +static fz_error *sweepref(pdf_xref *xref, fz_obj *ref); + +static fz_error * +sweepobj(pdf_xref *xref, fz_obj *obj) +{ + fz_error *error; + int i; + + if (fz_isdict(obj)) + { + for (i = 0; i < fz_dictlen(obj); i++) + { + error = sweepobj(xref, fz_dictgetval(obj, i)); + if (error) + return error; + } + } + + if (fz_isarray(obj)) + { + for (i = 0; i < fz_arraylen(obj); i++) + { + error = sweepobj(xref, fz_arrayget(obj, i)); + if (error) + return error; + } + } + + if (fz_isindirect(obj)) + return sweepref(xref, obj); + + return nil; +} + +static fz_error * +sweepref(pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + fz_obj *obj; + int oid; + + oid = fz_tonum(ref); + + if (oid < 0 || oid >= xref->len) + return fz_throw("rangecheck: object number out of range"); + + if (xref->table[oid].mark) + return nil; + + xref->table[oid].mark = 1; + + error = pdf_loadindirect(&obj, xref, ref); + if (error) + return error; + + error = sweepobj(xref, obj); + fz_dropobj(obj); + return error; +} + +/* + * Garbage collect objects not reachable from + * the trailer dictionary + */ + +fz_error * +pdf_garbagecollect(pdf_xref *xref) +{ + fz_error *error; + int i, g; + + pdf_logxref("garbage collect {\n"); + + for (i = 0; i < xref->len; i++) + xref->table[i].mark = 0; + + error = sweepobj(xref, xref->trailer); + if (error) + return error; + + for (i = 0; i < xref->len; i++) + { + pdf_xrefentry *x = xref->table + i; + g = x->gen; + if (x->type == 'o') + g = 0; + if (!x->mark && x->type != 'f' && x->type != 'd') + pdf_deleteobject(xref, i, g); + } + + pdf_logxref("}\n"); + + return nil; +} + +/* + * Transplant (copy) objects and streams from one file to another + */ + +struct pair +{ + int soid, sgen; + int doid, dgen; +}; + +static fz_error * +remaprefs(fz_obj **newp, fz_obj *old, struct pair *map, int n) +{ + fz_error *error; + int i, o, g; + fz_obj *tmp, *key; + + if (fz_isindirect(old)) + { + o = fz_tonum(old); + g = fz_togen(old); + for (i = 0; i < n; i++) + if (map[i].soid == o && map[i].sgen == g) + return fz_newindirect(newp, map[i].doid, map[i].dgen); + } + + else if (fz_isarray(old)) + { + error = fz_newarray(newp, fz_arraylen(old)); + if (error) + return error; + for (i = 0; i < fz_arraylen(old); i++) + { + tmp = fz_arrayget(old, i); + error = remaprefs(&tmp, tmp, map, n); + if (error) + goto cleanup; + error = fz_arraypush(*newp, tmp); + fz_dropobj(tmp); + if (error) + goto cleanup; + } + } + + else if (fz_isdict(old)) + { + error = fz_newdict(newp, fz_dictlen(old)); + if (error) + return error; + for (i = 0; i < fz_dictlen(old); i++) + { + key = fz_dictgetkey(old, i); + tmp = fz_dictgetval(old, i); + error = remaprefs(&tmp, tmp, map, n); + if (error) + goto cleanup; + error = fz_dictput(*newp, key, tmp); + fz_dropobj(tmp); + if (error) + goto cleanup; + } + } + + else + { + *newp = fz_keepobj(old); + } + + return nil; + +cleanup: + fz_dropobj(*newp); + return error; +} + +/* + * Recursively copy objects from src to dst xref. + * Start with root object in src xref. + * Put the dst copy of root into newp. + */ +fz_error * +pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root) +{ + fz_error *error; + struct pair *map; + fz_obj *old, *new; + fz_buffer *stm; + int i, n; + + pdf_logxref("transplant {\n"); + + for (i = 0; i < src->len; i++) + src->table[i].mark = 0; + + error = sweepobj(src, root); + if (error) + return error; + + for (n = 0, i = 0; i < src->len; i++) + if (src->table[i].mark) + n++; + + pdf_logxref("marked %d\n", n); + + map = fz_malloc(sizeof(struct pair) * n); + if (!map) + return fz_outofmem; + + for (n = 0, i = 0; i < src->len; i++) + { + if (src->table[i].mark) + { + map[n].soid = i; + map[n].sgen = src->table[i].gen; + if (src->table[i].type == 'o') + map[n].sgen = 0; + error = pdf_allocobject(dst, &map[n].doid, &map[n].dgen); + if (error) + goto cleanup; + n++; + } + } + + error = remaprefs(newp, root, map, n); + if (error) + goto cleanup; + + for (i = 0; i < n; i++) + { + pdf_logxref("copyfrom %d %d to %d %d\n", + map[i].soid, map[i].sgen, + map[i].doid, map[i].dgen); + + error = pdf_loadobject(&old, src, map[i].soid, map[i].sgen); + if (error) + goto cleanup; + + if (pdf_isstream(src, map[i].soid, map[i].sgen)) + { + error = pdf_loadrawstream(&stm, src, map[i].soid, map[i].sgen); + if (error) + goto cleanup; + pdf_updatestream(dst, map[i].doid, map[i].dgen, stm); + fz_dropbuffer(stm); + } + + error = remaprefs(&new, old, map, n); + fz_dropobj(old); + if (error) + goto cleanup; + + pdf_updateobject(dst, map[i].doid, map[i].dgen, new); + fz_dropobj(new); + } + + pdf_logxref("}\n"); + + fz_free(map); + return nil; + +cleanup: + fz_free(map); + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_font.c b/rosapps/smartpdf/fitz/mupdf/pdf_font.c new file mode 100644 index 00000000000..4b5c8d71d39 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_font.c @@ -0,0 +1,1039 @@ +#include +#include + +#define noHINT + +#include +#include FT_FREETYPE_H +#include FT_XFREE86_H + +static char *basefontnames[14][7] = +{ + { "Courier", "CourierNew", "CourierNewPSMT", 0 }, + { "Courier-Bold", "CourierNew,Bold", "Courier,Bold", + "CourierNewPS-BoldMT", "CourierNew-Bold", 0 }, + { "Courier-Oblique", "CourierNew,Italic", "Courier,Italic", + "CourierNewPS-ItalicMT", "CourierNew-Italic", 0 }, + { "Courier-BoldOblique", "CourierNew,BoldItalic", "Courier,BoldItalic", + "CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", 0 }, + { "Helvetica", "ArialMT", "Arial", 0 }, + { "Helvetica-Bold", "Arial-BoldMT", "Arial,Bold", "Arial-Bold", + "Helvetica,Bold", 0 }, + { "Helvetica-Oblique", "Arial-ItalicMT", "Arial,Italic", "Arial-Italic", + "Helvetica,Italic", "Helvetica-Italic", 0 }, + { "Helvetica-BoldOblique", "Arial-BoldItalicMT", + "Arial,BoldItalic", "Arial-BoldItalic", + "Helvetica,BoldItalic", "Helvetica-BoldItalic", 0 }, + { "Times-Roman", "TimesNewRomanPSMT", "TimesNewRoman", + "TimesNewRomanPS", 0 }, + { "Times-Bold", "TimesNewRomanPS-BoldMT", "TimesNewRoman,Bold", + "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", 0 }, + { "Times-Italic", "TimesNewRomanPS-ItalicMT", "TimesNewRoman,Italic", + "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", 0 }, + { "Times-BoldItalic", "TimesNewRomanPS-BoldItalicMT", + "TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalic", + "TimesNewRoman-BoldItalic", 0 }, + { "Symbol", 0 }, + { "ZapfDingbats", 0 } +}; + +/* + * FreeType and Rendering glue + */ + +enum { UNKNOWN, TYPE1, TRUETYPE, CID }; + +static int ftkind(FT_Face face) +{ + const char *kind = FT_Get_X11_Font_Format(face); + pdf_logfont("ft font format %s\n", kind); + if (!strcmp(kind, "TrueType")) + return TRUETYPE; + if (!strcmp(kind, "Type 1")) + return TYPE1; + if (!strcmp(kind, "CFF")) + return TYPE1; + if (!strcmp(kind, "CID Type 1")) + return TYPE1; + return UNKNOWN; +} + +static inline int ftcidtogid(pdf_font *font, int cid) +{ + if (font->tottfcmap) + { + cid = pdf_lookupcmap(font->tottfcmap, cid); + return FT_Get_Char_Index(font->ftface, cid); + } + + if (font->cidtogid) + return font->cidtogid[cid]; + + return cid; +} + +static int ftwidth(pdf_font *font, int cid) +{ + int e; + + cid = ftcidtogid(font, cid); + + e = FT_Load_Glyph(font->ftface, cid, + FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM); + if (e) + return 0; + return ((FT_Face)font->ftface)->glyph->advance.x; +} + +static fz_error * +ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm) +{ + pdf_font *font = (pdf_font*)fzfont; + FT_Face face = font->ftface; + FT_Matrix m; + FT_Vector v; + FT_Error fterr; + float scale; + int gid; + int x, y; + + gid = ftcidtogid(font, cid); + + if (font->substitute && fzfont->wmode == 0) + { + fz_hmtx subw; + int realw; + + FT_Set_Char_Size(face, 1000, 1000, 72, 72); + + fterr = FT_Load_Glyph(font->ftface, gid, + FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM); + if (fterr) + return fz_throw("freetype failed to load glyph: 0x%x", fterr); + + realw = ((FT_Face)font->ftface)->glyph->advance.x; + subw = fz_gethmtx(fzfont, cid); + if (realw) + scale = (float) subw.w / realw; + else + scale = 1.0; + + trm = fz_concat(fz_scale(scale, 1.0), trm); + } + + glyph->w = 0; + glyph->h = 0; + glyph->x = 0; + glyph->y = 0; + glyph->samples = nil; + + /* freetype mutilates complex glyphs if they are loaded + * with FT_Set_Char_Size 1.0. it rounds the coordinates + * before applying transformation. to get more precision in + * freetype, we shift part of the scale in the matrix + * into FT_Set_Char_Size instead + */ + +#ifdef HINT + scale = fz_matrixexpansion(trm); + m.xx = trm.a * 65536 / scale; + m.yx = trm.b * 65536 / scale; + m.xy = trm.c * 65536 / scale; + m.yy = trm.d * 65536 / scale; + v.x = 0; + v.y = 0; + + FT_Set_Char_Size(face, 64 * scale, 64 * scale, 72, 72); + FT_Set_Transform(face, &m, &v); + + fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP); + if (fterr) + fz_warn("freetype load glyph: 0x%x", fterr); + +#else + + m.xx = trm.a * 64; /* should be 65536 */ + m.yx = trm.b * 64; + m.xy = trm.c * 64; + m.yy = trm.d * 64; + v.x = trm.e * 64; + v.y = trm.f * 64; + + FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */ + FT_Set_Transform(face, &m, &v); + + fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING); + if (fterr) + fz_warn("freetype load glyph: 0x%x", fterr); + +#endif + + fterr = FT_Render_Glyph(face->glyph, ft_render_mode_normal); + if (fterr) + fz_warn("freetype render glyph: 0x%x", fterr); + + glyph->w = face->glyph->bitmap.width; + glyph->h = face->glyph->bitmap.rows; + glyph->x = face->glyph->bitmap_left; + glyph->y = face->glyph->bitmap_top - glyph->h; + glyph->samples = face->glyph->bitmap.buffer; + + for (y = 0; y < glyph->h / 2; y++) + { + for (x = 0; x < glyph->w; x++) + { + unsigned char a = glyph->samples[y * glyph->w + x ]; + unsigned char b = glyph->samples[(glyph->h - y - 1) * glyph->w + x]; + glyph->samples[y * glyph->w + x ] = b; + glyph->samples[(glyph->h - y - 1) * glyph->w + x] = a; + } + } + + return nil; +} + +/* + * Basic encoding tables + */ + +static char *cleanfontname(char *fontname) +{ + int i, k; + for (i = 0; i < 14; i++) + for (k = 0; basefontnames[i][k]; k++) + if (!strcmp(basefontnames[i][k], fontname)) + return basefontnames[i][0]; + return fontname; +} + +static int mrecode(char *name) +{ + int i; + for (i = 0; i < 256; i++) + if (pdf_macroman[i] && !strcmp(name, pdf_macroman[i])) + return i; + return -1; +} + +/* + * Create and destroy + */ + +static void ftdropfont(fz_font *font) +{ + pdf_font *pfont = (pdf_font*)font; + if (pfont->encoding) + pdf_dropcmap(pfont->encoding); + if (pfont->tottfcmap) + pdf_dropcmap(pfont->tottfcmap); + if (pfont->tounicode) + pdf_dropcmap(pfont->tounicode); + fz_free(pfont->cidtogid); + fz_free(pfont->cidtoucs); + if (pfont->ftface) + FT_Done_Face((FT_Face)pfont->ftface); + if (pfont->fontdata) + fz_dropbuffer(pfont->fontdata); +} + +pdf_font * +pdf_newfont(char *name) +{ + pdf_font *font; + int i; + + font = fz_malloc(sizeof (pdf_font)); + if (!font) + return nil; + + fz_initfont((fz_font*)font, name); + font->super.render = ftrender; + font->super.drop = (void(*)(fz_font*)) ftdropfont; + + font->ftface = nil; + font->substitute = 0; + + font->flags = 0; + font->italicangle = 0; + font->ascent = 0; + font->descent = 0; + font->capheight = 0; + font->xheight = 0; + font->missingwidth = 0; + + font->encoding = nil; + font->tottfcmap = 0; + font->ncidtogid = 0; + font->cidtogid = nil; + + font->tounicode = nil; + font->ncidtoucs = 0; + font->cidtoucs = nil; + + font->filename = nil; + font->fontdata = nil; + + for (i = 0; i < 256; i++) + font->charprocs[i] = nil; + + return font; +} + +/* + * Simple fonts (Type1 and TrueType) + */ + +static fz_error * +loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + fz_obj *descriptor = nil; + fz_obj *encoding = nil; + fz_obj *widths = nil; + unsigned short *etable = nil; + pdf_font *font; + fz_irect bbox; + FT_Face face; + FT_CharMap cmap; + int kind; + int symbolic; + + char *basefont; + char *fontname; + char *estrings[256]; + char ebuffer[256][32]; + int i, k, n, e; + + basefont = fz_toname(fz_dictgets(dict, "BaseFont")); + fontname = cleanfontname(basefont); + + /* + * Load font file + */ + + font = pdf_newfont(fontname); + if (!font) + return fz_outofmem; + + pdf_logfont("load simple font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font); + pdf_logfont("basefont0 %s\n", basefont); + pdf_logfont("basefont1 %s\n", fontname); + + descriptor = fz_dictgets(dict, "FontDescriptor"); + if (descriptor && basefont == fontname) + error = pdf_loadfontdescriptor(font, xref, descriptor, nil); + else + error = pdf_loadbuiltinfont(font, fontname); + if (error) + goto cleanup; + + face = font->ftface; + kind = ftkind(face); + + pdf_logfont("ft name '%s' '%s'\n", face->family_name, face->style_name); + + bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM; + bbox.y0 = (face->bbox.yMin * 1000) / face->units_per_EM; + bbox.x1 = (face->bbox.xMax * 1000) / face->units_per_EM; + bbox.y1 = (face->bbox.yMax * 1000) / face->units_per_EM; + + pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); + + if (bbox.x0 == bbox.x1) + fz_setfontbbox((fz_font*)font, -1000, -1000, 2000, 2000); + else + fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); + + /* + * Encoding + */ + + symbolic = font->flags & 4; + + if (face->num_charmaps > 0) + cmap = face->charmaps[0]; + else + cmap = nil; + + for (i = 0; i < face->num_charmaps; i++) + { + FT_CharMap test = face->charmaps[i]; + + if (kind == TYPE1) + { + if (test->platform_id == 7) + cmap = test; + } + + if (kind == TRUETYPE) + { + if (test->platform_id == 1 && test->encoding_id == 0) + cmap = test; + if (test->platform_id == 3 && test->encoding_id == 1) + cmap = test; + } + } + + if (cmap) + { + e = FT_Set_Charmap(face, cmap); + if (e) + { + error = fz_throw("freetype could not set cmap: 0x%x", e); + goto cleanup; + } + } + else + fz_warn("freetype could not find any cmaps"); + + etable = fz_malloc(sizeof(unsigned short) * 256); + if (!etable) + goto cleanup; + + for (i = 0; i < 256; i++) + { + estrings[i] = nil; + etable[i] = 0; + } + + encoding = fz_dictgets(dict, "Encoding"); + if (encoding && !(kind == TRUETYPE && symbolic)) + { + error = pdf_resolve(&encoding, xref); + if (error) + goto cleanup; + + if (fz_isname(encoding)) + pdf_loadencoding(estrings, fz_toname(encoding)); + + if (fz_isdict(encoding)) + { + fz_obj *base, *diff, *item; + + base = fz_dictgets(encoding, "BaseEncoding"); + if (fz_isname(base)) + pdf_loadencoding(estrings, fz_toname(base)); + + diff = fz_dictgets(encoding, "Differences"); + if (fz_isarray(diff)) + { + n = fz_arraylen(diff); + k = 0; + for (i = 0; i < n; i++) + { + item = fz_arrayget(diff, i); + if (fz_isint(item)) + k = fz_toint(item); + if (fz_isname(item)) + estrings[k++] = fz_toname(item); + if (k < 0) k = 0; + if (k > 255) k = 255; + } + } + } + + if (kind == TYPE1) + { + pdf_logfont("encode type1/cff by strings\n"); + for (i = 0; i < 256; i++) + if (estrings[i]) + etable[i] = FT_Get_Name_Index(face, estrings[i]); + else + etable[i] = FT_Get_Char_Index(face, i); + } + + if (kind == TRUETYPE) + { + /* Unicode cmap */ + if (face->charmap->platform_id == 3) + { + pdf_logfont("encode truetype via unicode\n"); + for (i = 0; i < 256; i++) + if (estrings[i]) + { + int aglbuf[256]; + int aglnum; + aglnum = pdf_lookupagl(estrings[i], aglbuf, nelem(aglbuf)); + if (aglnum != 1) + etable[i] = FT_Get_Name_Index(face, estrings[i]); + else + etable[i] = FT_Get_Char_Index(face, aglbuf[0]); + } + else + etable[i] = FT_Get_Char_Index(face, i); + } + + /* MacRoman cmap */ + else if (face->charmap->platform_id == 1) + { + pdf_logfont("encode truetype via macroman\n"); + for (i = 0; i < 256; i++) + if (estrings[i]) + { + k = mrecode(estrings[i]); + if (k <= 0) + etable[i] = FT_Get_Name_Index(face, estrings[i]); + else + etable[i] = FT_Get_Char_Index(face, k); + } + else + etable[i] = FT_Get_Char_Index(face, i); + } + + /* Symbolic cmap */ + else + { + pdf_logfont("encode truetype symbolic\n"); + for (i = 0; i < 256; i++) + { + etable[i] = FT_Get_Char_Index(face, i); + FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); + if (ebuffer[i][0]) + estrings[i] = ebuffer[i]; + } + } + } + + fz_dropobj(encoding); + } + + else + { + pdf_logfont("encode builtin\n"); + for (i = 0; i < 256; i++) + { + etable[i] = FT_Get_Char_Index(face, i); + FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); + if (ebuffer[i][0]) + estrings[i] = ebuffer[i]; + } + } + + error = pdf_newidentitycmap(&font->encoding, 0, 1); + if (error) + goto cleanup; + + font->ncidtogid = 256; + font->cidtogid = etable; + + error = pdf_loadtounicode(font, xref, + estrings, nil, fz_dictgets(dict, "ToUnicode")); + if (error) + goto cleanup; + + /* + * Widths + */ + + fz_setdefaulthmtx((fz_font*)font, font->missingwidth); + + widths = fz_dictgets(dict, "Widths"); + if (widths) + { + int first, last; + + error = pdf_resolve(&widths, xref); + if (error) + goto cleanup; + + first = fz_toint(fz_dictgets(dict, "FirstChar")); + last = fz_toint(fz_dictgets(dict, "LastChar")); + + if (first < 0 || last > 255 || first > last) + first = last = 0; + + for (i = 0; i < last - first + 1; i++) + { + int wid = fz_toint(fz_arrayget(widths, i)); + error = fz_addhmtx((fz_font*)font, i + first, i + first, wid); + if (error) + goto cleanup; + } + + fz_dropobj(widths); + } + else + { + FT_Set_Char_Size(face, 1000, 1000, 72, 72); + for (i = 0; i < 256; i++) + { + error = fz_addhmtx((fz_font*)font, i, i, ftwidth(font, i)); + if (error) + goto cleanup; + } + } + + error = fz_endhmtx((fz_font*)font); + if (error) + goto cleanup; + + pdf_logfont("}\n"); + + *fontp = font; + return nil; + +cleanup: + fz_free(etable); + if (widths) + fz_dropobj(widths); + fz_dropfont((fz_font*)font); + return error; +} + +/* + * CID Fonts + */ + +static fz_error * +loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj *encoding, fz_obj *tounicode) +{ + fz_error *error; + fz_obj *widths = nil; + fz_obj *descriptor; + pdf_font *font; + FT_Face face; + fz_irect bbox; + int kind; + char collection[256]; + char *basefont; + int i, k; + + /* + * Get font name and CID collection + */ + + basefont = fz_toname(fz_dictgets(dict, "BaseFont")); + + { + fz_obj *cidinfo; + fz_obj *obj; + char tmpstr[64]; + int tmplen; + + cidinfo = fz_dictgets(dict, "CIDSystemInfo"); + + error = pdf_resolve(&cidinfo, xref); + if (error) + return error; + + obj = fz_dictgets(cidinfo, "Registry"); + tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj)); + memcpy(tmpstr, fz_tostrbuf(obj), tmplen); + tmpstr[tmplen] = '\0'; + strlcpy(collection, tmpstr, sizeof collection); + + strlcat(collection, "-", sizeof collection); + + obj = fz_dictgets(cidinfo, "Ordering"); + tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj)); + memcpy(tmpstr, fz_tostrbuf(obj), tmplen); + tmpstr[tmplen] = '\0'; + strlcat(collection, tmpstr, sizeof collection); + + fz_dropobj(cidinfo); + } + + /* + * Load font file + */ + + font = pdf_newfont(basefont); + if (!font) + return fz_outofmem; + + pdf_logfont("load cid font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font); + pdf_logfont("basefont %s\n", basefont); + pdf_logfont("collection %s\n", collection); + + descriptor = fz_dictgets(dict, "FontDescriptor"); + if (descriptor) + error = pdf_loadfontdescriptor(font, xref, descriptor, collection); + else + error = fz_throw("syntaxerror: missing font descriptor"); + if (error) + goto cleanup; + + face = font->ftface; + kind = ftkind(face); + + bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM; + bbox.y0 = (face->bbox.yMin * 1000) / face->units_per_EM; + bbox.x1 = (face->bbox.xMax * 1000) / face->units_per_EM; + bbox.y1 = (face->bbox.yMax * 1000) / face->units_per_EM; + + pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); + + if (bbox.x0 == bbox.x1) + fz_setfontbbox((fz_font*)font, -1000, -1000, 2000, 2000); + else + fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); + + /* + * Encoding + */ + + if (fz_isname(encoding)) + { + pdf_logfont("encoding /%s\n", fz_toname(encoding)); + if (!strcmp(fz_toname(encoding), "Identity-H")) + error = pdf_newidentitycmap(&font->encoding, 0, 2); + else if (!strcmp(fz_toname(encoding), "Identity-V")) + error = pdf_newidentitycmap(&font->encoding, 1, 2); + else + error = pdf_loadsystemcmap(&font->encoding, fz_toname(encoding)); + } + else if (fz_isindirect(encoding)) + { + pdf_logfont("encoding %d %d R\n", fz_tonum(encoding), fz_togen(encoding)); + error = pdf_loadembeddedcmap(&font->encoding, xref, encoding); + } + else + { + error = fz_throw("syntaxerror: font missing encoding"); + } + if (error) + goto cleanup; + + fz_setfontwmode((fz_font*)font, pdf_getwmode(font->encoding)); + pdf_logfont("wmode %d\n", pdf_getwmode(font->encoding)); + + if (kind == TRUETYPE) + { + fz_obj *cidtogidmap; + + cidtogidmap = fz_dictgets(dict, "CIDToGIDMap"); + if (fz_isindirect(cidtogidmap)) + { + unsigned short *map; + fz_buffer *buf; + int len; + + pdf_logfont("cidtogidmap stream\n"); + + error = pdf_loadstream(&buf, xref, fz_tonum(cidtogidmap), fz_togen(cidtogidmap)); + if (error) + goto cleanup; + + len = (buf->wp - buf->rp) / 2; + + map = fz_malloc(len * sizeof(unsigned short)); + if (!map) { + fz_dropbuffer(buf); + error = fz_outofmem; + goto cleanup; + } + + for (i = 0; i < len; i++) + map[i] = (buf->rp[i * 2] << 8) + buf->rp[i * 2 + 1]; + + font->ncidtogid = len; + font->cidtogid = map; + + fz_dropbuffer(buf); + } + + /* if truetype font is external, cidtogidmap should not be identity */ + /* so we map from cid to unicode and then map that through the (3 1) */ + /* unicode cmap to get a glyph id */ + else if (font->substitute) + { + int e; + + pdf_logfont("emulate ttf cidfont\n"); + + e = FT_Select_Charmap(face, ft_encoding_unicode); + if (e) + return fz_throw("fonterror: no unicode cmap when emulating CID font"); + + if (!strcmp(collection, "Adobe-CNS1")) + error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-CNS1-UCS2"); + else if (!strcmp(collection, "Adobe-GB1")) + error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-GB1-UCS2"); + else if (!strcmp(collection, "Adobe-Japan1")) + error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Japan1-UCS2"); + else if (!strcmp(collection, "Adobe-Japan2")) + error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Japan2-UCS2"); + else if (!strcmp(collection, "Adobe-Korea1")) + error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Korea1-UCS2"); + else + error = nil; + + if (error) + return error; + } + } + + error = pdf_loadtounicode(font, xref, nil, collection, tounicode); + if (error) + goto cleanup; + + /* + * Horizontal + */ + + fz_setdefaulthmtx((fz_font*)font, fz_toint(fz_dictgets(dict, "DW"))); + + widths = fz_dictgets(dict, "W"); + if (widths) + { + int c0, c1, w; + fz_obj *obj; + + error = pdf_resolve(&widths, xref); + if (error) + goto cleanup; + + for (i = 0; i < fz_arraylen(widths); ) + { + c0 = fz_toint(fz_arrayget(widths, i)); + obj = fz_arrayget(widths, i + 1); + if (fz_isarray(obj)) + { + for (k = 0; k < fz_arraylen(obj); k++) + { + w = fz_toint(fz_arrayget(obj, k)); + error = fz_addhmtx((fz_font*)font, c0 + k, c0 + k, w); + if (error) + goto cleanup; + } + i += 2; + } + else + { + c1 = fz_toint(obj); + w = fz_toint(fz_arrayget(widths, i + 2)); + error = fz_addhmtx((fz_font*)font, c0, c1, w); + if (error) + goto cleanup; + i += 3; + } + } + + fz_dropobj(widths); + } + + error = fz_endhmtx((fz_font*)font); + if (error) + goto cleanup; + + /* + * Vertical + */ + + if (pdf_getwmode(font->encoding) == 1) + { + fz_obj *obj; + int dw2y = 880; + int dw2w = -1000; + + obj = fz_dictgets(dict, "DW2"); + if (obj) + { + dw2y = fz_toint(fz_arrayget(obj, 0)); + dw2w = fz_toint(fz_arrayget(obj, 1)); + } + + fz_setdefaultvmtx((fz_font*)font, dw2y, dw2w); + + widths = fz_dictgets(dict, "W2"); + if (widths) + { + int c0, c1, w, x, y, k; + + error = pdf_resolve(&widths, xref); + if (error) + goto cleanup; + + for (i = 0; i < fz_arraylen(widths); ) + { + c0 = fz_toint(fz_arrayget(widths, i)); + obj = fz_arrayget(widths, i + 1); + if (fz_isarray(obj)) + { + for (k = 0; k < fz_arraylen(obj); k += 3) + { + w = fz_toint(fz_arrayget(obj, k + 0)); + x = fz_toint(fz_arrayget(obj, k + 1)); + y = fz_toint(fz_arrayget(obj, k + 2)); + error = fz_addvmtx((fz_font*)font, c0 + k, c0 + k, x, y, w); + if (error) + goto cleanup; + } + i += 2; + } + else + { + c1 = fz_toint(obj); + w = fz_toint(fz_arrayget(widths, i + 2)); + x = fz_toint(fz_arrayget(widths, i + 3)); + y = fz_toint(fz_arrayget(widths, i + 4)); + error = fz_addvmtx((fz_font*)font, c0, c1, x, y, w); + if (error) + goto cleanup; + i += 5; + } + } + + fz_dropobj(widths); + } + + error = fz_endvmtx((fz_font*)font); + if (error) + goto cleanup; + } + + pdf_logfont("}\n"); + + *fontp = font; + return nil; + +cleanup: + if (widths) + fz_dropobj(widths); + fz_dropfont((fz_font*)font); + return error; +} + +static fz_error * +loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + fz_obj *dfonts; + fz_obj *dfont; + fz_obj *subtype; + fz_obj *encoding; + fz_obj *tounicode; + + dfonts = fz_dictgets(dict, "DescendantFonts"); + error = pdf_resolve(&dfonts, xref); + if (error) + return error; + + dfont = fz_arrayget(dfonts, 0); + error = pdf_resolve(&dfont, xref); + if (error) + return fz_dropobj(dfonts), error; + + subtype = fz_dictgets(dfont, "Subtype"); + encoding = fz_dictgets(dict, "Encoding"); + tounicode = fz_dictgets(dict, "ToUnicode"); + + if (!strcmp(fz_toname(subtype), "CIDFontType0")) + error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode); + else if (!strcmp(fz_toname(subtype), "CIDFontType2")) + error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode); + else + error = fz_throw("syntaxerror: unknown cid font type"); + + fz_dropobj(dfont); + fz_dropobj(dfonts); + + if (error) + return error; + + return nil; +} + +/* + * FontDescriptor + */ + +fz_error * +pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection) +{ + fz_error *error; + fz_obj *obj1, *obj2, *obj3, *obj; + fz_rect bbox; + char *fontname; + + error = pdf_resolve(&desc, xref); + if (error) + return error; + + pdf_logfont("load fontdescriptor {\n"); + + fontname = fz_toname(fz_dictgets(desc, "FontName")); + + pdf_logfont("fontname %s\n", fontname); + + font->flags = fz_toint(fz_dictgets(desc, "Flags")); + font->italicangle = fz_toreal(fz_dictgets(desc, "ItalicAngle")); + font->ascent = fz_toreal(fz_dictgets(desc, "Ascent")); + font->descent = fz_toreal(fz_dictgets(desc, "Descent")); + font->capheight = fz_toreal(fz_dictgets(desc, "CapHeight")); + font->xheight = fz_toreal(fz_dictgets(desc, "XHeight")); + font->missingwidth = fz_toreal(fz_dictgets(desc, "MissingWidth")); + + bbox = pdf_torect(fz_dictgets(desc, "FontBBox")); + pdf_logfont("bbox [%g %g %g %g]\n", + bbox.x0, bbox.y0, + bbox.x1, bbox.y1); + + pdf_logfont("flags %d\n", font->flags); + + obj1 = fz_dictgets(desc, "FontFile"); + obj2 = fz_dictgets(desc, "FontFile2"); + obj3 = fz_dictgets(desc, "FontFile3"); + obj = obj1 ? obj1 : obj2 ? obj2 : obj3; + + if (getenv("NOFONT")) + obj = nil; + + if (fz_isindirect(obj)) + { + error = pdf_loadembeddedfont(font, xref, obj); + if (error) + goto cleanup; + } + else + { + error = pdf_loadsystemfont(font, fontname, collection); + if (error) + goto cleanup; + } + + fz_dropobj(desc); + + pdf_logfont("}\n"); + + return nil; + +cleanup: + fz_dropobj(desc); + return error; +} + +fz_error * +pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + char *subtype; + + if ((*fontp = pdf_finditem(xref->store, PDF_KFONT, ref))) + { + fz_keepfont((fz_font*)*fontp); + return nil; + } + + subtype = fz_toname(fz_dictgets(dict, "Subtype")); + if (!strcmp(subtype, "Type0")) + error = loadtype0(fontp, xref, dict, ref); + else if (!strcmp(subtype, "Type1") || !strcmp(subtype, "MMType1")) + error = loadsimplefont(fontp, xref, dict, ref); + else if (!strcmp(subtype, "TrueType")) + error = loadsimplefont(fontp, xref, dict, ref); + else if (!strcmp(subtype, "Type3")) + error = pdf_loadtype3font(fontp, xref, dict, ref); + else + error = fz_throw("unimplemented: %s fonts", subtype); + + if (error) + return error; + + error = pdf_storeitem(xref->store, PDF_KFONT, ref, *fontp); + if (error) + return error; + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_fontagl.c b/rosapps/smartpdf/fitz/mupdf/pdf_fontagl.c new file mode 100644 index 00000000000..55517090153 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_fontagl.c @@ -0,0 +1,4647 @@ +/* Adobe Glyph List -- autogenerated so do not touch */ + +static const struct { char *name; short num; short ofs; } aglidx[4281] = { +{"A",1,0}, +{"AE",1,1}, +{"AEacute",1,2}, +{"AEmacron",1,3}, +{"AEsmall",1,4}, +{"Aacute",1,5}, +{"Aacutesmall",1,6}, +{"Abreve",1,7}, +{"Abreveacute",1,8}, +{"Abrevecyrillic",1,9}, +{"Abrevedotbelow",1,10}, +{"Abrevegrave",1,11}, +{"Abrevehookabove",1,12}, +{"Abrevetilde",1,13}, +{"Acaron",1,14}, +{"Acircle",1,15}, +{"Acircumflex",1,16}, +{"Acircumflexacute",1,17}, +{"Acircumflexdotbelow",1,18}, +{"Acircumflexgrave",1,19}, +{"Acircumflexhookabove",1,20}, +{"Acircumflexsmall",1,21}, +{"Acircumflextilde",1,22}, +{"Acute",1,23}, +{"Acutesmall",1,24}, +{"Acyrillic",1,25}, +{"Adblgrave",1,26}, +{"Adieresis",1,27}, +{"Adieresiscyrillic",1,28}, +{"Adieresismacron",1,29}, +{"Adieresissmall",1,30}, +{"Adotbelow",1,31}, +{"Adotmacron",1,32}, +{"Agrave",1,33}, +{"Agravesmall",1,34}, +{"Ahookabove",1,35}, +{"Aiecyrillic",1,36}, +{"Ainvertedbreve",1,37}, +{"Alpha",1,38}, +{"Alphatonos",1,39}, +{"Amacron",1,40}, +{"Amonospace",1,41}, +{"Aogonek",1,42}, +{"Aring",1,43}, +{"Aringacute",1,44}, +{"Aringbelow",1,45}, +{"Aringsmall",1,46}, +{"Asmall",1,47}, +{"Atilde",1,48}, +{"Atildesmall",1,49}, +{"Aybarmenian",1,50}, +{"B",1,51}, +{"Bcircle",1,52}, +{"Bdotaccent",1,53}, +{"Bdotbelow",1,54}, +{"Becyrillic",1,55}, +{"Benarmenian",1,56}, +{"Beta",1,57}, +{"Bhook",1,58}, +{"Blinebelow",1,59}, +{"Bmonospace",1,60}, +{"Brevesmall",1,61}, +{"Bsmall",1,62}, +{"Btopbar",1,63}, +{"C",1,64}, +{"Caarmenian",1,65}, +{"Cacute",1,66}, +{"Caron",1,67}, +{"Caronsmall",1,68}, +{"Ccaron",1,69}, +{"Ccedilla",1,70}, +{"Ccedillaacute",1,71}, +{"Ccedillasmall",1,72}, +{"Ccircle",1,73}, +{"Ccircumflex",1,74}, +{"Cdot",1,75}, +{"Cdotaccent",1,76}, +{"Cedillasmall",1,77}, +{"Chaarmenian",1,78}, +{"Cheabkhasiancyrillic",1,79}, +{"Checyrillic",1,80}, +{"Chedescenderabkhasiancyrillic",1,81}, +{"Chedescendercyrillic",1,82}, +{"Chedieresiscyrillic",1,83}, +{"Cheharmenian",1,84}, +{"Chekhakassiancyrillic",1,85}, +{"Cheverticalstrokecyrillic",1,86}, +{"Chi",1,87}, +{"Chook",1,88}, +{"Circumflexsmall",1,89}, +{"Cmonospace",1,90}, +{"Coarmenian",1,91}, +{"Csmall",1,92}, +{"D",1,93}, +{"DZ",1,94}, +{"DZcaron",1,95}, +{"Daarmenian",1,96}, +{"Dafrican",1,97}, +{"Dcaron",1,98}, +{"Dcedilla",1,99}, +{"Dcircle",1,100}, +{"Dcircumflexbelow",1,101}, +{"Dcroat",1,102}, +{"Ddotaccent",1,103}, +{"Ddotbelow",1,104}, +{"Decyrillic",1,105}, +{"Deicoptic",1,106}, +{"Delta",1,107}, +{"Deltagreek",1,108}, +{"Dhook",1,109}, +{"Dieresis",1,110}, +{"DieresisAcute",1,111}, +{"DieresisGrave",1,112}, +{"Dieresissmall",1,113}, +{"Digammagreek",1,114}, +{"Djecyrillic",1,115}, +{"Dlinebelow",1,116}, +{"Dmonospace",1,117}, +{"Dotaccentsmall",1,118}, +{"Dslash",1,119}, +{"Dsmall",1,120}, +{"Dtopbar",1,121}, +{"Dz",1,122}, +{"Dzcaron",1,123}, +{"Dzeabkhasiancyrillic",1,124}, +{"Dzecyrillic",1,125}, +{"Dzhecyrillic",1,126}, +{"E",1,127}, +{"Eacute",1,128}, +{"Eacutesmall",1,129}, +{"Ebreve",1,130}, +{"Ecaron",1,131}, +{"Ecedillabreve",1,132}, +{"Echarmenian",1,133}, +{"Ecircle",1,134}, +{"Ecircumflex",1,135}, +{"Ecircumflexacute",1,136}, +{"Ecircumflexbelow",1,137}, +{"Ecircumflexdotbelow",1,138}, +{"Ecircumflexgrave",1,139}, +{"Ecircumflexhookabove",1,140}, +{"Ecircumflexsmall",1,141}, +{"Ecircumflextilde",1,142}, +{"Ecyrillic",1,143}, +{"Edblgrave",1,144}, +{"Edieresis",1,145}, +{"Edieresissmall",1,146}, +{"Edot",1,147}, +{"Edotaccent",1,148}, +{"Edotbelow",1,149}, +{"Efcyrillic",1,150}, +{"Egrave",1,151}, +{"Egravesmall",1,152}, +{"Eharmenian",1,153}, +{"Ehookabove",1,154}, +{"Eightroman",1,155}, +{"Einvertedbreve",1,156}, +{"Eiotifiedcyrillic",1,157}, +{"Elcyrillic",1,158}, +{"Elevenroman",1,159}, +{"Emacron",1,160}, +{"Emacronacute",1,161}, +{"Emacrongrave",1,162}, +{"Emcyrillic",1,163}, +{"Emonospace",1,164}, +{"Encyrillic",1,165}, +{"Endescendercyrillic",1,166}, +{"Eng",1,167}, +{"Enghecyrillic",1,168}, +{"Enhookcyrillic",1,169}, +{"Eogonek",1,170}, +{"Eopen",1,171}, +{"Epsilon",1,172}, +{"Epsilontonos",1,173}, +{"Ercyrillic",1,174}, +{"Ereversed",1,175}, +{"Ereversedcyrillic",1,176}, +{"Escyrillic",1,177}, +{"Esdescendercyrillic",1,178}, +{"Esh",1,179}, +{"Esmall",1,180}, +{"Eta",1,181}, +{"Etarmenian",1,182}, +{"Etatonos",1,183}, +{"Eth",1,184}, +{"Ethsmall",1,185}, +{"Etilde",1,186}, +{"Etildebelow",1,187}, +{"Euro",1,188}, +{"Ezh",1,189}, +{"Ezhcaron",1,190}, +{"Ezhreversed",1,191}, +{"F",1,192}, +{"Fcircle",1,193}, +{"Fdotaccent",1,194}, +{"Feharmenian",1,195}, +{"Feicoptic",1,196}, +{"Fhook",1,197}, +{"Fitacyrillic",1,198}, +{"Fiveroman",1,199}, +{"Fmonospace",1,200}, +{"Fourroman",1,201}, +{"Fsmall",1,202}, +{"G",1,203}, +{"GBsquare",1,204}, +{"Gacute",1,205}, +{"Gamma",1,206}, +{"Gammaafrican",1,207}, +{"Gangiacoptic",1,208}, +{"Gbreve",1,209}, +{"Gcaron",1,210}, +{"Gcedilla",1,211}, +{"Gcircle",1,212}, +{"Gcircumflex",1,213}, +{"Gcommaaccent",1,214}, +{"Gdot",1,215}, +{"Gdotaccent",1,216}, +{"Gecyrillic",1,217}, +{"Ghadarmenian",1,218}, +{"Ghemiddlehookcyrillic",1,219}, +{"Ghestrokecyrillic",1,220}, +{"Gheupturncyrillic",1,221}, +{"Ghook",1,222}, +{"Gimarmenian",1,223}, +{"Gjecyrillic",1,224}, +{"Gmacron",1,225}, +{"Gmonospace",1,226}, +{"Grave",1,227}, +{"Gravesmall",1,228}, +{"Gsmall",1,229}, +{"Gsmallhook",1,230}, +{"Gstroke",1,231}, +{"H",1,232}, +{"H18533",1,233}, +{"H18543",1,234}, +{"H18551",1,235}, +{"H22073",1,236}, +{"HPsquare",1,237}, +{"Haabkhasiancyrillic",1,238}, +{"Hadescendercyrillic",1,239}, +{"Hardsigncyrillic",1,240}, +{"Hbar",1,241}, +{"Hbrevebelow",1,242}, +{"Hcedilla",1,243}, +{"Hcircle",1,244}, +{"Hcircumflex",1,245}, +{"Hdieresis",1,246}, +{"Hdotaccent",1,247}, +{"Hdotbelow",1,248}, +{"Hmonospace",1,249}, +{"Hoarmenian",1,250}, +{"Horicoptic",1,251}, +{"Hsmall",1,252}, +{"Hungarumlaut",1,253}, +{"Hungarumlautsmall",1,254}, +{"Hzsquare",1,255}, +{"I",1,256}, +{"IAcyrillic",1,257}, +{"IJ",1,258}, +{"IUcyrillic",1,259}, +{"Iacute",1,260}, +{"Iacutesmall",1,261}, +{"Ibreve",1,262}, +{"Icaron",1,263}, +{"Icircle",1,264}, +{"Icircumflex",1,265}, +{"Icircumflexsmall",1,266}, +{"Icyrillic",1,267}, +{"Idblgrave",1,268}, +{"Idieresis",1,269}, +{"Idieresisacute",1,270}, +{"Idieresiscyrillic",1,271}, +{"Idieresissmall",1,272}, +{"Idot",1,273}, +{"Idotaccent",1,274}, +{"Idotbelow",1,275}, +{"Iebrevecyrillic",1,276}, +{"Iecyrillic",1,277}, +{"Ifraktur",1,278}, +{"Igrave",1,279}, +{"Igravesmall",1,280}, +{"Ihookabove",1,281}, +{"Iicyrillic",1,282}, +{"Iinvertedbreve",1,283}, +{"Iishortcyrillic",1,284}, +{"Imacron",1,285}, +{"Imacroncyrillic",1,286}, +{"Imonospace",1,287}, +{"Iniarmenian",1,288}, +{"Iocyrillic",1,289}, +{"Iogonek",1,290}, +{"Iota",1,291}, +{"Iotaafrican",1,292}, +{"Iotadieresis",1,293}, +{"Iotatonos",1,294}, +{"Ismall",1,295}, +{"Istroke",1,296}, +{"Itilde",1,297}, +{"Itildebelow",1,298}, +{"Izhitsacyrillic",1,299}, +{"Izhitsadblgravecyrillic",1,300}, +{"J",1,301}, +{"Jaarmenian",1,302}, +{"Jcircle",1,303}, +{"Jcircumflex",1,304}, +{"Jecyrillic",1,305}, +{"Jheharmenian",1,306}, +{"Jmonospace",1,307}, +{"Jsmall",1,308}, +{"K",1,309}, +{"KBsquare",1,310}, +{"KKsquare",1,311}, +{"Kabashkircyrillic",1,312}, +{"Kacute",1,313}, +{"Kacyrillic",1,314}, +{"Kadescendercyrillic",1,315}, +{"Kahookcyrillic",1,316}, +{"Kappa",1,317}, +{"Kastrokecyrillic",1,318}, +{"Kaverticalstrokecyrillic",1,319}, +{"Kcaron",1,320}, +{"Kcedilla",1,321}, +{"Kcircle",1,322}, +{"Kcommaaccent",1,323}, +{"Kdotbelow",1,324}, +{"Keharmenian",1,325}, +{"Kenarmenian",1,326}, +{"Khacyrillic",1,327}, +{"Kheicoptic",1,328}, +{"Khook",1,329}, +{"Kjecyrillic",1,330}, +{"Klinebelow",1,331}, +{"Kmonospace",1,332}, +{"Koppacyrillic",1,333}, +{"Koppagreek",1,334}, +{"Ksicyrillic",1,335}, +{"Ksmall",1,336}, +{"L",1,337}, +{"LJ",1,338}, +{"LL",1,339}, +{"Lacute",1,340}, +{"Lambda",1,341}, +{"Lcaron",1,342}, +{"Lcedilla",1,343}, +{"Lcircle",1,344}, +{"Lcircumflexbelow",1,345}, +{"Lcommaaccent",1,346}, +{"Ldot",1,347}, +{"Ldotaccent",1,348}, +{"Ldotbelow",1,349}, +{"Ldotbelowmacron",1,350}, +{"Liwnarmenian",1,351}, +{"Lj",1,352}, +{"Ljecyrillic",1,353}, +{"Llinebelow",1,354}, +{"Lmonospace",1,355}, +{"Lslash",1,356}, +{"Lslashsmall",1,357}, +{"Lsmall",1,358}, +{"M",1,359}, +{"MBsquare",1,360}, +{"Macron",1,361}, +{"Macronsmall",1,362}, +{"Macute",1,363}, +{"Mcircle",1,364}, +{"Mdotaccent",1,365}, +{"Mdotbelow",1,366}, +{"Menarmenian",1,367}, +{"Mmonospace",1,368}, +{"Msmall",1,369}, +{"Mturned",1,370}, +{"Mu",1,371}, +{"N",1,372}, +{"NJ",1,373}, +{"Nacute",1,374}, +{"Ncaron",1,375}, +{"Ncedilla",1,376}, +{"Ncircle",1,377}, +{"Ncircumflexbelow",1,378}, +{"Ncommaaccent",1,379}, +{"Ndotaccent",1,380}, +{"Ndotbelow",1,381}, +{"Nhookleft",1,382}, +{"Nineroman",1,383}, +{"Nj",1,384}, +{"Njecyrillic",1,385}, +{"Nlinebelow",1,386}, +{"Nmonospace",1,387}, +{"Nowarmenian",1,388}, +{"Nsmall",1,389}, +{"Ntilde",1,390}, +{"Ntildesmall",1,391}, +{"Nu",1,392}, +{"O",1,393}, +{"OE",1,394}, +{"OEsmall",1,395}, +{"Oacute",1,396}, +{"Oacutesmall",1,397}, +{"Obarredcyrillic",1,398}, +{"Obarreddieresiscyrillic",1,399}, +{"Obreve",1,400}, +{"Ocaron",1,401}, +{"Ocenteredtilde",1,402}, +{"Ocircle",1,403}, +{"Ocircumflex",1,404}, +{"Ocircumflexacute",1,405}, +{"Ocircumflexdotbelow",1,406}, +{"Ocircumflexgrave",1,407}, +{"Ocircumflexhookabove",1,408}, +{"Ocircumflexsmall",1,409}, +{"Ocircumflextilde",1,410}, +{"Ocyrillic",1,411}, +{"Odblacute",1,412}, +{"Odblgrave",1,413}, +{"Odieresis",1,414}, +{"Odieresiscyrillic",1,415}, +{"Odieresissmall",1,416}, +{"Odotbelow",1,417}, +{"Ogoneksmall",1,418}, +{"Ograve",1,419}, +{"Ogravesmall",1,420}, +{"Oharmenian",1,421}, +{"Ohm",1,422}, +{"Ohookabove",1,423}, +{"Ohorn",1,424}, +{"Ohornacute",1,425}, +{"Ohorndotbelow",1,426}, +{"Ohorngrave",1,427}, +{"Ohornhookabove",1,428}, +{"Ohorntilde",1,429}, +{"Ohungarumlaut",1,430}, +{"Oi",1,431}, +{"Oinvertedbreve",1,432}, +{"Omacron",1,433}, +{"Omacronacute",1,434}, +{"Omacrongrave",1,435}, +{"Omega",1,436}, +{"Omegacyrillic",1,437}, +{"Omegagreek",1,438}, +{"Omegaroundcyrillic",1,439}, +{"Omegatitlocyrillic",1,440}, +{"Omegatonos",1,441}, +{"Omicron",1,442}, +{"Omicrontonos",1,443}, +{"Omonospace",1,444}, +{"Oneroman",1,445}, +{"Oogonek",1,446}, +{"Oogonekmacron",1,447}, +{"Oopen",1,448}, +{"Oslash",1,449}, +{"Oslashacute",1,450}, +{"Oslashsmall",1,451}, +{"Osmall",1,452}, +{"Ostrokeacute",1,453}, +{"Otcyrillic",1,454}, +{"Otilde",1,455}, +{"Otildeacute",1,456}, +{"Otildedieresis",1,457}, +{"Otildesmall",1,458}, +{"P",1,459}, +{"Pacute",1,460}, +{"Pcircle",1,461}, +{"Pdotaccent",1,462}, +{"Pecyrillic",1,463}, +{"Peharmenian",1,464}, +{"Pemiddlehookcyrillic",1,465}, +{"Phi",1,466}, +{"Phook",1,467}, +{"Pi",1,468}, +{"Piwrarmenian",1,469}, +{"Pmonospace",1,470}, +{"Psi",1,471}, +{"Psicyrillic",1,472}, +{"Psmall",1,473}, +{"Q",1,474}, +{"Qcircle",1,475}, +{"Qmonospace",1,476}, +{"Qsmall",1,477}, +{"R",1,478}, +{"Raarmenian",1,479}, +{"Racute",1,480}, +{"Rcaron",1,481}, +{"Rcedilla",1,482}, +{"Rcircle",1,483}, +{"Rcommaaccent",1,484}, +{"Rdblgrave",1,485}, +{"Rdotaccent",1,486}, +{"Rdotbelow",1,487}, +{"Rdotbelowmacron",1,488}, +{"Reharmenian",1,489}, +{"Rfraktur",1,490}, +{"Rho",1,491}, +{"Ringsmall",1,492}, +{"Rinvertedbreve",1,493}, +{"Rlinebelow",1,494}, +{"Rmonospace",1,495}, +{"Rsmall",1,496}, +{"Rsmallinverted",1,497}, +{"Rsmallinvertedsuperior",1,498}, +{"S",1,499}, +{"SF010000",1,500}, +{"SF020000",1,501}, +{"SF030000",1,502}, +{"SF040000",1,503}, +{"SF050000",1,504}, +{"SF060000",1,505}, +{"SF070000",1,506}, +{"SF080000",1,507}, +{"SF090000",1,508}, +{"SF100000",1,509}, +{"SF110000",1,510}, +{"SF190000",1,511}, +{"SF200000",1,512}, +{"SF210000",1,513}, +{"SF220000",1,514}, +{"SF230000",1,515}, +{"SF240000",1,516}, +{"SF250000",1,517}, +{"SF260000",1,518}, +{"SF270000",1,519}, +{"SF280000",1,520}, +{"SF360000",1,521}, +{"SF370000",1,522}, +{"SF380000",1,523}, +{"SF390000",1,524}, +{"SF400000",1,525}, +{"SF410000",1,526}, +{"SF420000",1,527}, +{"SF430000",1,528}, +{"SF440000",1,529}, +{"SF450000",1,530}, +{"SF460000",1,531}, +{"SF470000",1,532}, +{"SF480000",1,533}, +{"SF490000",1,534}, +{"SF500000",1,535}, +{"SF510000",1,536}, +{"SF520000",1,537}, +{"SF530000",1,538}, +{"SF540000",1,539}, +{"Sacute",1,540}, +{"Sacutedotaccent",1,541}, +{"Sampigreek",1,542}, +{"Scaron",1,543}, +{"Scarondotaccent",1,544}, +{"Scaronsmall",1,545}, +{"Scedilla",1,546}, +{"Schwa",1,547}, +{"Schwacyrillic",1,548}, +{"Schwadieresiscyrillic",1,549}, +{"Scircle",1,550}, +{"Scircumflex",1,551}, +{"Scommaaccent",1,552}, +{"Sdotaccent",1,553}, +{"Sdotbelow",1,554}, +{"Sdotbelowdotaccent",1,555}, +{"Seharmenian",1,556}, +{"Sevenroman",1,557}, +{"Shaarmenian",1,558}, +{"Shacyrillic",1,559}, +{"Shchacyrillic",1,560}, +{"Sheicoptic",1,561}, +{"Shhacyrillic",1,562}, +{"Shimacoptic",1,563}, +{"Sigma",1,564}, +{"Sixroman",1,565}, +{"Smonospace",1,566}, +{"Softsigncyrillic",1,567}, +{"Ssmall",1,568}, +{"Stigmagreek",1,569}, +{"T",1,570}, +{"Tau",1,571}, +{"Tbar",1,572}, +{"Tcaron",1,573}, +{"Tcedilla",1,574}, +{"Tcircle",1,575}, +{"Tcircumflexbelow",1,576}, +{"Tcommaaccent",1,577}, +{"Tdotaccent",1,578}, +{"Tdotbelow",1,579}, +{"Tecyrillic",1,580}, +{"Tedescendercyrillic",1,581}, +{"Tenroman",1,582}, +{"Tetsecyrillic",1,583}, +{"Theta",1,584}, +{"Thook",1,585}, +{"Thorn",1,586}, +{"Thornsmall",1,587}, +{"Threeroman",1,588}, +{"Tildesmall",1,589}, +{"Tiwnarmenian",1,590}, +{"Tlinebelow",1,591}, +{"Tmonospace",1,592}, +{"Toarmenian",1,593}, +{"Tonefive",1,594}, +{"Tonesix",1,595}, +{"Tonetwo",1,596}, +{"Tretroflexhook",1,597}, +{"Tsecyrillic",1,598}, +{"Tshecyrillic",1,599}, +{"Tsmall",1,600}, +{"Twelveroman",1,601}, +{"Tworoman",1,602}, +{"U",1,603}, +{"Uacute",1,604}, +{"Uacutesmall",1,605}, +{"Ubreve",1,606}, +{"Ucaron",1,607}, +{"Ucircle",1,608}, +{"Ucircumflex",1,609}, +{"Ucircumflexbelow",1,610}, +{"Ucircumflexsmall",1,611}, +{"Ucyrillic",1,612}, +{"Udblacute",1,613}, +{"Udblgrave",1,614}, +{"Udieresis",1,615}, +{"Udieresisacute",1,616}, +{"Udieresisbelow",1,617}, +{"Udieresiscaron",1,618}, +{"Udieresiscyrillic",1,619}, +{"Udieresisgrave",1,620}, +{"Udieresismacron",1,621}, +{"Udieresissmall",1,622}, +{"Udotbelow",1,623}, +{"Ugrave",1,624}, +{"Ugravesmall",1,625}, +{"Uhookabove",1,626}, +{"Uhorn",1,627}, +{"Uhornacute",1,628}, +{"Uhorndotbelow",1,629}, +{"Uhorngrave",1,630}, +{"Uhornhookabove",1,631}, +{"Uhorntilde",1,632}, +{"Uhungarumlaut",1,633}, +{"Uhungarumlautcyrillic",1,634}, +{"Uinvertedbreve",1,635}, +{"Ukcyrillic",1,636}, +{"Umacron",1,637}, +{"Umacroncyrillic",1,638}, +{"Umacrondieresis",1,639}, +{"Umonospace",1,640}, +{"Uogonek",1,641}, +{"Upsilon",1,642}, +{"Upsilon1",1,643}, +{"Upsilonacutehooksymbolgreek",1,644}, +{"Upsilonafrican",1,645}, +{"Upsilondieresis",1,646}, +{"Upsilondieresishooksymbolgreek",1,647}, +{"Upsilonhooksymbol",1,648}, +{"Upsilontonos",1,649}, +{"Uring",1,650}, +{"Ushortcyrillic",1,651}, +{"Usmall",1,652}, +{"Ustraightcyrillic",1,653}, +{"Ustraightstrokecyrillic",1,654}, +{"Utilde",1,655}, +{"Utildeacute",1,656}, +{"Utildebelow",1,657}, +{"V",1,658}, +{"Vcircle",1,659}, +{"Vdotbelow",1,660}, +{"Vecyrillic",1,661}, +{"Vewarmenian",1,662}, +{"Vhook",1,663}, +{"Vmonospace",1,664}, +{"Voarmenian",1,665}, +{"Vsmall",1,666}, +{"Vtilde",1,667}, +{"W",1,668}, +{"Wacute",1,669}, +{"Wcircle",1,670}, +{"Wcircumflex",1,671}, +{"Wdieresis",1,672}, +{"Wdotaccent",1,673}, +{"Wdotbelow",1,674}, +{"Wgrave",1,675}, +{"Wmonospace",1,676}, +{"Wsmall",1,677}, +{"X",1,678}, +{"Xcircle",1,679}, +{"Xdieresis",1,680}, +{"Xdotaccent",1,681}, +{"Xeharmenian",1,682}, +{"Xi",1,683}, +{"Xmonospace",1,684}, +{"Xsmall",1,685}, +{"Y",1,686}, +{"Yacute",1,687}, +{"Yacutesmall",1,688}, +{"Yatcyrillic",1,689}, +{"Ycircle",1,690}, +{"Ycircumflex",1,691}, +{"Ydieresis",1,692}, +{"Ydieresissmall",1,693}, +{"Ydotaccent",1,694}, +{"Ydotbelow",1,695}, +{"Yericyrillic",1,696}, +{"Yerudieresiscyrillic",1,697}, +{"Ygrave",1,698}, +{"Yhook",1,699}, +{"Yhookabove",1,700}, +{"Yiarmenian",1,701}, +{"Yicyrillic",1,702}, +{"Yiwnarmenian",1,703}, +{"Ymonospace",1,704}, +{"Ysmall",1,705}, +{"Ytilde",1,706}, +{"Yusbigcyrillic",1,707}, +{"Yusbigiotifiedcyrillic",1,708}, +{"Yuslittlecyrillic",1,709}, +{"Yuslittleiotifiedcyrillic",1,710}, +{"Z",1,711}, +{"Zaarmenian",1,712}, +{"Zacute",1,713}, +{"Zcaron",1,714}, +{"Zcaronsmall",1,715}, +{"Zcircle",1,716}, +{"Zcircumflex",1,717}, +{"Zdot",1,718}, +{"Zdotaccent",1,719}, +{"Zdotbelow",1,720}, +{"Zecyrillic",1,721}, +{"Zedescendercyrillic",1,722}, +{"Zedieresiscyrillic",1,723}, +{"Zeta",1,724}, +{"Zhearmenian",1,725}, +{"Zhebrevecyrillic",1,726}, +{"Zhecyrillic",1,727}, +{"Zhedescendercyrillic",1,728}, +{"Zhedieresiscyrillic",1,729}, +{"Zlinebelow",1,730}, +{"Zmonospace",1,731}, +{"Zsmall",1,732}, +{"Zstroke",1,733}, +{"a",1,734}, +{"aabengali",1,735}, +{"aacute",1,736}, +{"aadeva",1,737}, +{"aagujarati",1,738}, +{"aagurmukhi",1,739}, +{"aamatragurmukhi",1,740}, +{"aarusquare",1,741}, +{"aavowelsignbengali",1,742}, +{"aavowelsigndeva",1,743}, +{"aavowelsigngujarati",1,744}, +{"abbreviationmarkarmenian",1,745}, +{"abbreviationsigndeva",1,746}, +{"abengali",1,747}, +{"abopomofo",1,748}, +{"abreve",1,749}, +{"abreveacute",1,750}, +{"abrevecyrillic",1,751}, +{"abrevedotbelow",1,752}, +{"abrevegrave",1,753}, +{"abrevehookabove",1,754}, +{"abrevetilde",1,755}, +{"acaron",1,756}, +{"acircle",1,757}, +{"acircumflex",1,758}, +{"acircumflexacute",1,759}, +{"acircumflexdotbelow",1,760}, +{"acircumflexgrave",1,761}, +{"acircumflexhookabove",1,762}, +{"acircumflextilde",1,763}, +{"acute",1,764}, +{"acutebelowcmb",1,765}, +{"acutecmb",1,766}, +{"acutecomb",1,767}, +{"acutedeva",1,768}, +{"acutelowmod",1,769}, +{"acutetonecmb",1,770}, +{"acyrillic",1,771}, +{"adblgrave",1,772}, +{"addakgurmukhi",1,773}, +{"adeva",1,774}, +{"adieresis",1,775}, +{"adieresiscyrillic",1,776}, +{"adieresismacron",1,777}, +{"adotbelow",1,778}, +{"adotmacron",1,779}, +{"ae",1,780}, +{"aeacute",1,781}, +{"aekorean",1,782}, +{"aemacron",1,783}, +{"afii00208",1,784}, +{"afii08941",1,785}, +{"afii10017",1,786}, +{"afii10018",1,787}, +{"afii10019",1,788}, +{"afii10020",1,789}, +{"afii10021",1,790}, +{"afii10022",1,791}, +{"afii10023",1,792}, +{"afii10024",1,793}, +{"afii10025",1,794}, +{"afii10026",1,795}, +{"afii10027",1,796}, +{"afii10028",1,797}, +{"afii10029",1,798}, +{"afii10030",1,799}, +{"afii10031",1,800}, +{"afii10032",1,801}, +{"afii10033",1,802}, +{"afii10034",1,803}, +{"afii10035",1,804}, +{"afii10036",1,805}, +{"afii10037",1,806}, +{"afii10038",1,807}, +{"afii10039",1,808}, +{"afii10040",1,809}, +{"afii10041",1,810}, +{"afii10042",1,811}, +{"afii10043",1,812}, +{"afii10044",1,813}, +{"afii10045",1,814}, +{"afii10046",1,815}, +{"afii10047",1,816}, +{"afii10048",1,817}, +{"afii10049",1,818}, +{"afii10050",1,819}, +{"afii10051",1,820}, +{"afii10052",1,821}, +{"afii10053",1,822}, +{"afii10054",1,823}, +{"afii10055",1,824}, +{"afii10056",1,825}, +{"afii10057",1,826}, +{"afii10058",1,827}, +{"afii10059",1,828}, +{"afii10060",1,829}, +{"afii10061",1,830}, +{"afii10062",1,831}, +{"afii10063",1,832}, +{"afii10064",1,833}, +{"afii10065",1,834}, +{"afii10066",1,835}, +{"afii10067",1,836}, +{"afii10068",1,837}, +{"afii10069",1,838}, +{"afii10070",1,839}, +{"afii10071",1,840}, +{"afii10072",1,841}, +{"afii10073",1,842}, +{"afii10074",1,843}, +{"afii10075",1,844}, +{"afii10076",1,845}, +{"afii10077",1,846}, +{"afii10078",1,847}, +{"afii10079",1,848}, +{"afii10080",1,849}, +{"afii10081",1,850}, +{"afii10082",1,851}, +{"afii10083",1,852}, +{"afii10084",1,853}, +{"afii10085",1,854}, +{"afii10086",1,855}, +{"afii10087",1,856}, +{"afii10088",1,857}, +{"afii10089",1,858}, +{"afii10090",1,859}, +{"afii10091",1,860}, +{"afii10092",1,861}, +{"afii10093",1,862}, +{"afii10094",1,863}, +{"afii10095",1,864}, +{"afii10096",1,865}, +{"afii10097",1,866}, +{"afii10098",1,867}, +{"afii10099",1,868}, +{"afii10100",1,869}, +{"afii10101",1,870}, +{"afii10102",1,871}, +{"afii10103",1,872}, +{"afii10104",1,873}, +{"afii10105",1,874}, +{"afii10106",1,875}, +{"afii10107",1,876}, +{"afii10108",1,877}, +{"afii10109",1,878}, +{"afii10110",1,879}, +{"afii10145",1,880}, +{"afii10146",1,881}, +{"afii10147",1,882}, +{"afii10148",1,883}, +{"afii10192",1,884}, +{"afii10193",1,885}, +{"afii10194",1,886}, +{"afii10195",1,887}, +{"afii10196",1,888}, +{"afii10831",1,889}, +{"afii10832",1,890}, +{"afii10846",1,891}, +{"afii299",1,892}, +{"afii300",1,893}, +{"afii301",1,894}, +{"afii57381",1,895}, +{"afii57388",1,896}, +{"afii57392",1,897}, +{"afii57393",1,898}, +{"afii57394",1,899}, +{"afii57395",1,900}, +{"afii57396",1,901}, +{"afii57397",1,902}, +{"afii57398",1,903}, +{"afii57399",1,904}, +{"afii57400",1,905}, +{"afii57401",1,906}, +{"afii57403",1,907}, +{"afii57407",1,908}, +{"afii57409",1,909}, +{"afii57410",1,910}, +{"afii57411",1,911}, +{"afii57412",1,912}, +{"afii57413",1,913}, +{"afii57414",1,914}, +{"afii57415",1,915}, +{"afii57416",1,916}, +{"afii57417",1,917}, +{"afii57418",1,918}, +{"afii57419",1,919}, +{"afii57420",1,920}, +{"afii57421",1,921}, +{"afii57422",1,922}, +{"afii57423",1,923}, +{"afii57424",1,924}, +{"afii57425",1,925}, +{"afii57426",1,926}, +{"afii57427",1,927}, +{"afii57428",1,928}, +{"afii57429",1,929}, +{"afii57430",1,930}, +{"afii57431",1,931}, +{"afii57432",1,932}, +{"afii57433",1,933}, +{"afii57434",1,934}, +{"afii57440",1,935}, +{"afii57441",1,936}, +{"afii57442",1,937}, +{"afii57443",1,938}, +{"afii57444",1,939}, +{"afii57445",1,940}, +{"afii57446",1,941}, +{"afii57448",1,942}, +{"afii57449",1,943}, +{"afii57450",1,944}, +{"afii57451",1,945}, +{"afii57452",1,946}, +{"afii57453",1,947}, +{"afii57454",1,948}, +{"afii57455",1,949}, +{"afii57456",1,950}, +{"afii57457",1,951}, +{"afii57458",1,952}, +{"afii57470",1,953}, +{"afii57505",1,954}, +{"afii57506",1,955}, +{"afii57507",1,956}, +{"afii57508",1,957}, +{"afii57509",1,958}, +{"afii57511",1,959}, +{"afii57512",1,960}, +{"afii57513",1,961}, +{"afii57514",1,962}, +{"afii57519",1,963}, +{"afii57534",1,964}, +{"afii57636",1,965}, +{"afii57645",1,966}, +{"afii57658",1,967}, +{"afii57664",1,968}, +{"afii57665",1,969}, +{"afii57666",1,970}, +{"afii57667",1,971}, +{"afii57668",1,972}, +{"afii57669",1,973}, +{"afii57670",1,974}, +{"afii57671",1,975}, +{"afii57672",1,976}, +{"afii57673",1,977}, +{"afii57674",1,978}, +{"afii57675",1,979}, +{"afii57676",1,980}, +{"afii57677",1,981}, +{"afii57678",1,982}, +{"afii57679",1,983}, +{"afii57680",1,984}, +{"afii57681",1,985}, +{"afii57682",1,986}, +{"afii57683",1,987}, +{"afii57684",1,988}, +{"afii57685",1,989}, +{"afii57686",1,990}, +{"afii57687",1,991}, +{"afii57688",1,992}, +{"afii57689",1,993}, +{"afii57690",1,994}, +{"afii57694",1,995}, +{"afii57695",1,996}, +{"afii57700",1,997}, +{"afii57705",1,998}, +{"afii57716",1,999}, +{"afii57717",1,1000}, +{"afii57718",1,1001}, +{"afii57723",1,1002}, +{"afii57793",1,1003}, +{"afii57794",1,1004}, +{"afii57795",1,1005}, +{"afii57796",1,1006}, +{"afii57797",1,1007}, +{"afii57798",1,1008}, +{"afii57799",1,1009}, +{"afii57800",1,1010}, +{"afii57801",1,1011}, +{"afii57802",1,1012}, +{"afii57803",1,1013}, +{"afii57804",1,1014}, +{"afii57806",1,1015}, +{"afii57807",1,1016}, +{"afii57839",1,1017}, +{"afii57841",1,1018}, +{"afii57842",1,1019}, +{"afii57929",1,1020}, +{"afii61248",1,1021}, +{"afii61289",1,1022}, +{"afii61352",1,1023}, +{"afii61573",1,1024}, +{"afii61574",1,1025}, +{"afii61575",1,1026}, +{"afii61664",1,1027}, +{"afii63167",1,1028}, +{"afii64937",1,1029}, +{"agrave",1,1030}, +{"agujarati",1,1031}, +{"agurmukhi",1,1032}, +{"ahiragana",1,1033}, +{"ahookabove",1,1034}, +{"aibengali",1,1035}, +{"aibopomofo",1,1036}, +{"aideva",1,1037}, +{"aiecyrillic",1,1038}, +{"aigujarati",1,1039}, +{"aigurmukhi",1,1040}, +{"aimatragurmukhi",1,1041}, +{"ainarabic",1,1042}, +{"ainfinalarabic",1,1043}, +{"aininitialarabic",1,1044}, +{"ainmedialarabic",1,1045}, +{"ainvertedbreve",1,1046}, +{"aivowelsignbengali",1,1047}, +{"aivowelsigndeva",1,1048}, +{"aivowelsigngujarati",1,1049}, +{"akatakana",1,1050}, +{"akatakanahalfwidth",1,1051}, +{"akorean",1,1052}, +{"alef",1,1053}, +{"alefarabic",1,1054}, +{"alefdageshhebrew",1,1055}, +{"aleffinalarabic",1,1056}, +{"alefhamzaabovearabic",1,1057}, +{"alefhamzaabovefinalarabic",1,1058}, +{"alefhamzabelowarabic",1,1059}, +{"alefhamzabelowfinalarabic",1,1060}, +{"alefhebrew",1,1061}, +{"aleflamedhebrew",1,1062}, +{"alefmaddaabovearabic",1,1063}, +{"alefmaddaabovefinalarabic",1,1064}, +{"alefmaksuraarabic",1,1065}, +{"alefmaksurafinalarabic",1,1066}, +{"alefmaksurainitialarabic",1,1067}, +{"alefmaksuramedialarabic",1,1068}, +{"alefpatahhebrew",1,1069}, +{"alefqamatshebrew",1,1070}, +{"aleph",1,1071}, +{"allequal",1,1072}, +{"alpha",1,1073}, +{"alphatonos",1,1074}, +{"amacron",1,1075}, +{"amonospace",1,1076}, +{"ampersand",1,1077}, +{"ampersandmonospace",1,1078}, +{"ampersandsmall",1,1079}, +{"amsquare",1,1080}, +{"anbopomofo",1,1081}, +{"angbopomofo",1,1082}, +{"angkhankhuthai",1,1083}, +{"angle",1,1084}, +{"anglebracketleft",1,1085}, +{"anglebracketleftvertical",1,1086}, +{"anglebracketright",1,1087}, +{"anglebracketrightvertical",1,1088}, +{"angleleft",1,1089}, +{"angleright",1,1090}, +{"angstrom",1,1091}, +{"anoteleia",1,1092}, +{"anudattadeva",1,1093}, +{"anusvarabengali",1,1094}, +{"anusvaradeva",1,1095}, +{"anusvaragujarati",1,1096}, +{"aogonek",1,1097}, +{"apaatosquare",1,1098}, +{"aparen",1,1099}, +{"apostrophearmenian",1,1100}, +{"apostrophemod",1,1101}, +{"apple",1,1102}, +{"approaches",1,1103}, +{"approxequal",1,1104}, +{"approxequalorimage",1,1105}, +{"approximatelyequal",1,1106}, +{"araeaekorean",1,1107}, +{"araeakorean",1,1108}, +{"arc",1,1109}, +{"arighthalfring",1,1110}, +{"aring",1,1111}, +{"aringacute",1,1112}, +{"aringbelow",1,1113}, +{"arrowboth",1,1114}, +{"arrowdashdown",1,1115}, +{"arrowdashleft",1,1116}, +{"arrowdashright",1,1117}, +{"arrowdashup",1,1118}, +{"arrowdblboth",1,1119}, +{"arrowdbldown",1,1120}, +{"arrowdblleft",1,1121}, +{"arrowdblright",1,1122}, +{"arrowdblup",1,1123}, +{"arrowdown",1,1124}, +{"arrowdownleft",1,1125}, +{"arrowdownright",1,1126}, +{"arrowdownwhite",1,1127}, +{"arrowheaddownmod",1,1128}, +{"arrowheadleftmod",1,1129}, +{"arrowheadrightmod",1,1130}, +{"arrowheadupmod",1,1131}, +{"arrowhorizex",1,1132}, +{"arrowleft",1,1133}, +{"arrowleftdbl",1,1134}, +{"arrowleftdblstroke",1,1135}, +{"arrowleftoverright",1,1136}, +{"arrowleftwhite",1,1137}, +{"arrowright",1,1138}, +{"arrowrightdblstroke",1,1139}, +{"arrowrightheavy",1,1140}, +{"arrowrightoverleft",1,1141}, +{"arrowrightwhite",1,1142}, +{"arrowtableft",1,1143}, +{"arrowtabright",1,1144}, +{"arrowup",1,1145}, +{"arrowupdn",1,1146}, +{"arrowupdnbse",1,1147}, +{"arrowupdownbase",1,1148}, +{"arrowupleft",1,1149}, +{"arrowupleftofdown",1,1150}, +{"arrowupright",1,1151}, +{"arrowupwhite",1,1152}, +{"arrowvertex",1,1153}, +{"asciicircum",1,1154}, +{"asciicircummonospace",1,1155}, +{"asciitilde",1,1156}, +{"asciitildemonospace",1,1157}, +{"ascript",1,1158}, +{"ascriptturned",1,1159}, +{"asmallhiragana",1,1160}, +{"asmallkatakana",1,1161}, +{"asmallkatakanahalfwidth",1,1162}, +{"asterisk",1,1163}, +{"asteriskaltonearabic",1,1164}, +{"asteriskarabic",1,1165}, +{"asteriskmath",1,1166}, +{"asteriskmonospace",1,1167}, +{"asterisksmall",1,1168}, +{"asterism",1,1169}, +{"asuperior",1,1170}, +{"asymptoticallyequal",1,1171}, +{"at",1,1172}, +{"atilde",1,1173}, +{"atmonospace",1,1174}, +{"atsmall",1,1175}, +{"aturned",1,1176}, +{"aubengali",1,1177}, +{"aubopomofo",1,1178}, +{"audeva",1,1179}, +{"augujarati",1,1180}, +{"augurmukhi",1,1181}, +{"aulengthmarkbengali",1,1182}, +{"aumatragurmukhi",1,1183}, +{"auvowelsignbengali",1,1184}, +{"auvowelsigndeva",1,1185}, +{"auvowelsigngujarati",1,1186}, +{"avagrahadeva",1,1187}, +{"aybarmenian",1,1188}, +{"ayin",1,1189}, +{"ayinaltonehebrew",1,1190}, +{"ayinhebrew",1,1191}, +{"b",1,1192}, +{"babengali",1,1193}, +{"backslash",1,1194}, +{"backslashmonospace",1,1195}, +{"badeva",1,1196}, +{"bagujarati",1,1197}, +{"bagurmukhi",1,1198}, +{"bahiragana",1,1199}, +{"bahtthai",1,1200}, +{"bakatakana",1,1201}, +{"bar",1,1202}, +{"barmonospace",1,1203}, +{"bbopomofo",1,1204}, +{"bcircle",1,1205}, +{"bdotaccent",1,1206}, +{"bdotbelow",1,1207}, +{"beamedsixteenthnotes",1,1208}, +{"because",1,1209}, +{"becyrillic",1,1210}, +{"beharabic",1,1211}, +{"behfinalarabic",1,1212}, +{"behinitialarabic",1,1213}, +{"behiragana",1,1214}, +{"behmedialarabic",1,1215}, +{"behmeeminitialarabic",1,1216}, +{"behmeemisolatedarabic",1,1217}, +{"behnoonfinalarabic",1,1218}, +{"bekatakana",1,1219}, +{"benarmenian",1,1220}, +{"bet",1,1221}, +{"beta",1,1222}, +{"betasymbolgreek",1,1223}, +{"betdagesh",1,1224}, +{"betdageshhebrew",1,1225}, +{"bethebrew",1,1226}, +{"betrafehebrew",1,1227}, +{"bhabengali",1,1228}, +{"bhadeva",1,1229}, +{"bhagujarati",1,1230}, +{"bhagurmukhi",1,1231}, +{"bhook",1,1232}, +{"bihiragana",1,1233}, +{"bikatakana",1,1234}, +{"bilabialclick",1,1235}, +{"bindigurmukhi",1,1236}, +{"birusquare",1,1237}, +{"blackcircle",1,1238}, +{"blackdiamond",1,1239}, +{"blackdownpointingtriangle",1,1240}, +{"blackleftpointingpointer",1,1241}, +{"blackleftpointingtriangle",1,1242}, +{"blacklenticularbracketleft",1,1243}, +{"blacklenticularbracketleftvertical",1,1244}, +{"blacklenticularbracketright",1,1245}, +{"blacklenticularbracketrightvertical",1,1246}, +{"blacklowerlefttriangle",1,1247}, +{"blacklowerrighttriangle",1,1248}, +{"blackrectangle",1,1249}, +{"blackrightpointingpointer",1,1250}, +{"blackrightpointingtriangle",1,1251}, +{"blacksmallsquare",1,1252}, +{"blacksmilingface",1,1253}, +{"blacksquare",1,1254}, +{"blackstar",1,1255}, +{"blackupperlefttriangle",1,1256}, +{"blackupperrighttriangle",1,1257}, +{"blackuppointingsmalltriangle",1,1258}, +{"blackuppointingtriangle",1,1259}, +{"blank",1,1260}, +{"blinebelow",1,1261}, +{"block",1,1262}, +{"bmonospace",1,1263}, +{"bobaimaithai",1,1264}, +{"bohiragana",1,1265}, +{"bokatakana",1,1266}, +{"bparen",1,1267}, +{"bqsquare",1,1268}, +{"braceex",1,1269}, +{"braceleft",1,1270}, +{"braceleftbt",1,1271}, +{"braceleftmid",1,1272}, +{"braceleftmonospace",1,1273}, +{"braceleftsmall",1,1274}, +{"bracelefttp",1,1275}, +{"braceleftvertical",1,1276}, +{"braceright",1,1277}, +{"bracerightbt",1,1278}, +{"bracerightmid",1,1279}, +{"bracerightmonospace",1,1280}, +{"bracerightsmall",1,1281}, +{"bracerighttp",1,1282}, +{"bracerightvertical",1,1283}, +{"bracketleft",1,1284}, +{"bracketleftbt",1,1285}, +{"bracketleftex",1,1286}, +{"bracketleftmonospace",1,1287}, +{"bracketlefttp",1,1288}, +{"bracketright",1,1289}, +{"bracketrightbt",1,1290}, +{"bracketrightex",1,1291}, +{"bracketrightmonospace",1,1292}, +{"bracketrighttp",1,1293}, +{"breve",1,1294}, +{"brevebelowcmb",1,1295}, +{"brevecmb",1,1296}, +{"breveinvertedbelowcmb",1,1297}, +{"breveinvertedcmb",1,1298}, +{"breveinverteddoublecmb",1,1299}, +{"bridgebelowcmb",1,1300}, +{"bridgeinvertedbelowcmb",1,1301}, +{"brokenbar",1,1302}, +{"bstroke",1,1303}, +{"bsuperior",1,1304}, +{"btopbar",1,1305}, +{"buhiragana",1,1306}, +{"bukatakana",1,1307}, +{"bullet",1,1308}, +{"bulletinverse",1,1309}, +{"bulletoperator",1,1310}, +{"bullseye",1,1311}, +{"c",1,1312}, +{"caarmenian",1,1313}, +{"cabengali",1,1314}, +{"cacute",1,1315}, +{"cadeva",1,1316}, +{"cagujarati",1,1317}, +{"cagurmukhi",1,1318}, +{"calsquare",1,1319}, +{"candrabindubengali",1,1320}, +{"candrabinducmb",1,1321}, +{"candrabindudeva",1,1322}, +{"candrabindugujarati",1,1323}, +{"capslock",1,1324}, +{"careof",1,1325}, +{"caron",1,1326}, +{"caronbelowcmb",1,1327}, +{"caroncmb",1,1328}, +{"carriagereturn",1,1329}, +{"cbopomofo",1,1330}, +{"ccaron",1,1331}, +{"ccedilla",1,1332}, +{"ccedillaacute",1,1333}, +{"ccircle",1,1334}, +{"ccircumflex",1,1335}, +{"ccurl",1,1336}, +{"cdot",1,1337}, +{"cdotaccent",1,1338}, +{"cdsquare",1,1339}, +{"cedilla",1,1340}, +{"cedillacmb",1,1341}, +{"cent",1,1342}, +{"centigrade",1,1343}, +{"centinferior",1,1344}, +{"centmonospace",1,1345}, +{"centoldstyle",1,1346}, +{"centsuperior",1,1347}, +{"chaarmenian",1,1348}, +{"chabengali",1,1349}, +{"chadeva",1,1350}, +{"chagujarati",1,1351}, +{"chagurmukhi",1,1352}, +{"chbopomofo",1,1353}, +{"cheabkhasiancyrillic",1,1354}, +{"checkmark",1,1355}, +{"checyrillic",1,1356}, +{"chedescenderabkhasiancyrillic",1,1357}, +{"chedescendercyrillic",1,1358}, +{"chedieresiscyrillic",1,1359}, +{"cheharmenian",1,1360}, +{"chekhakassiancyrillic",1,1361}, +{"cheverticalstrokecyrillic",1,1362}, +{"chi",1,1363}, +{"chieuchacirclekorean",1,1364}, +{"chieuchaparenkorean",1,1365}, +{"chieuchcirclekorean",1,1366}, +{"chieuchkorean",1,1367}, +{"chieuchparenkorean",1,1368}, +{"chochangthai",1,1369}, +{"chochanthai",1,1370}, +{"chochingthai",1,1371}, +{"chochoethai",1,1372}, +{"chook",1,1373}, +{"cieucacirclekorean",1,1374}, +{"cieucaparenkorean",1,1375}, +{"cieuccirclekorean",1,1376}, +{"cieuckorean",1,1377}, +{"cieucparenkorean",1,1378}, +{"cieucuparenkorean",1,1379}, +{"circle",1,1380}, +{"circlemultiply",1,1381}, +{"circleot",1,1382}, +{"circleplus",1,1383}, +{"circlepostalmark",1,1384}, +{"circlewithlefthalfblack",1,1385}, +{"circlewithrighthalfblack",1,1386}, +{"circumflex",1,1387}, +{"circumflexbelowcmb",1,1388}, +{"circumflexcmb",1,1389}, +{"clear",1,1390}, +{"clickalveolar",1,1391}, +{"clickdental",1,1392}, +{"clicklateral",1,1393}, +{"clickretroflex",1,1394}, +{"club",1,1395}, +{"clubsuitblack",1,1396}, +{"clubsuitwhite",1,1397}, +{"cmcubedsquare",1,1398}, +{"cmonospace",1,1399}, +{"cmsquaredsquare",1,1400}, +{"coarmenian",1,1401}, +{"colon",1,1402}, +{"colonmonetary",1,1403}, +{"colonmonospace",1,1404}, +{"colonsign",1,1405}, +{"colonsmall",1,1406}, +{"colontriangularhalfmod",1,1407}, +{"colontriangularmod",1,1408}, +{"comma",1,1409}, +{"commaabovecmb",1,1410}, +{"commaaboverightcmb",1,1411}, +{"commaaccent",1,1412}, +{"commaarabic",1,1413}, +{"commaarmenian",1,1414}, +{"commainferior",1,1415}, +{"commamonospace",1,1416}, +{"commareversedabovecmb",1,1417}, +{"commareversedmod",1,1418}, +{"commasmall",1,1419}, +{"commasuperior",1,1420}, +{"commaturnedabovecmb",1,1421}, +{"commaturnedmod",1,1422}, +{"compass",1,1423}, +{"congruent",1,1424}, +{"contourintegral",1,1425}, +{"control",1,1426}, +{"controlACK",1,1427}, +{"controlBEL",1,1428}, +{"controlBS",1,1429}, +{"controlCAN",1,1430}, +{"controlCR",1,1431}, +{"controlDC1",1,1432}, +{"controlDC2",1,1433}, +{"controlDC3",1,1434}, +{"controlDC4",1,1435}, +{"controlDEL",1,1436}, +{"controlDLE",1,1437}, +{"controlEM",1,1438}, +{"controlENQ",1,1439}, +{"controlEOT",1,1440}, +{"controlESC",1,1441}, +{"controlETB",1,1442}, +{"controlETX",1,1443}, +{"controlFF",1,1444}, +{"controlFS",1,1445}, +{"controlGS",1,1446}, +{"controlHT",1,1447}, +{"controlLF",1,1448}, +{"controlNAK",1,1449}, +{"controlRS",1,1450}, +{"controlSI",1,1451}, +{"controlSO",1,1452}, +{"controlSOT",1,1453}, +{"controlSTX",1,1454}, +{"controlSUB",1,1455}, +{"controlSYN",1,1456}, +{"controlUS",1,1457}, +{"controlVT",1,1458}, +{"copyright",1,1459}, +{"copyrightsans",1,1460}, +{"copyrightserif",1,1461}, +{"cornerbracketleft",1,1462}, +{"cornerbracketlefthalfwidth",1,1463}, +{"cornerbracketleftvertical",1,1464}, +{"cornerbracketright",1,1465}, +{"cornerbracketrighthalfwidth",1,1466}, +{"cornerbracketrightvertical",1,1467}, +{"corporationsquare",1,1468}, +{"cosquare",1,1469}, +{"coverkgsquare",1,1470}, +{"cparen",1,1471}, +{"cruzeiro",1,1472}, +{"cstretched",1,1473}, +{"curlyand",1,1474}, +{"curlyor",1,1475}, +{"currency",1,1476}, +{"cyrBreve",1,1477}, +{"cyrFlex",1,1478}, +{"cyrbreve",1,1479}, +{"cyrflex",1,1480}, +{"d",1,1481}, +{"daarmenian",1,1482}, +{"dabengali",1,1483}, +{"dadarabic",1,1484}, +{"dadeva",1,1485}, +{"dadfinalarabic",1,1486}, +{"dadinitialarabic",1,1487}, +{"dadmedialarabic",1,1488}, +{"dagesh",1,1489}, +{"dageshhebrew",1,1490}, +{"dagger",1,1491}, +{"daggerdbl",1,1492}, +{"dagujarati",1,1493}, +{"dagurmukhi",1,1494}, +{"dahiragana",1,1495}, +{"dakatakana",1,1496}, +{"dalarabic",1,1497}, +{"dalet",1,1498}, +{"daletdagesh",1,1499}, +{"daletdageshhebrew",1,1500}, +{"dalethatafpatah",2,1501}, +{"dalethatafpatahhebrew",2,1503}, +{"dalethatafsegol",2,1505}, +{"dalethatafsegolhebrew",2,1507}, +{"dalethebrew",1,1509}, +{"dalethiriq",2,1510}, +{"dalethiriqhebrew",2,1512}, +{"daletholam",2,1514}, +{"daletholamhebrew",2,1516}, +{"daletpatah",2,1518}, +{"daletpatahhebrew",2,1520}, +{"daletqamats",2,1522}, +{"daletqamatshebrew",2,1524}, +{"daletqubuts",2,1526}, +{"daletqubutshebrew",2,1528}, +{"daletsegol",2,1530}, +{"daletsegolhebrew",2,1532}, +{"daletsheva",2,1534}, +{"daletshevahebrew",2,1536}, +{"dalettsere",2,1538}, +{"dalettserehebrew",2,1540}, +{"dalfinalarabic",1,1542}, +{"dammaarabic",1,1543}, +{"dammalowarabic",1,1544}, +{"dammatanaltonearabic",1,1545}, +{"dammatanarabic",1,1546}, +{"danda",1,1547}, +{"dargahebrew",1,1548}, +{"dargalefthebrew",1,1549}, +{"dasiapneumatacyrilliccmb",1,1550}, +{"dblGrave",1,1551}, +{"dblanglebracketleft",1,1552}, +{"dblanglebracketleftvertical",1,1553}, +{"dblanglebracketright",1,1554}, +{"dblanglebracketrightvertical",1,1555}, +{"dblarchinvertedbelowcmb",1,1556}, +{"dblarrowleft",1,1557}, +{"dblarrowright",1,1558}, +{"dbldanda",1,1559}, +{"dblgrave",1,1560}, +{"dblgravecmb",1,1561}, +{"dblintegral",1,1562}, +{"dbllowline",1,1563}, +{"dbllowlinecmb",1,1564}, +{"dbloverlinecmb",1,1565}, +{"dblprimemod",1,1566}, +{"dblverticalbar",1,1567}, +{"dblverticallineabovecmb",1,1568}, +{"dbopomofo",1,1569}, +{"dbsquare",1,1570}, +{"dcaron",1,1571}, +{"dcedilla",1,1572}, +{"dcircle",1,1573}, +{"dcircumflexbelow",1,1574}, +{"dcroat",1,1575}, +{"ddabengali",1,1576}, +{"ddadeva",1,1577}, +{"ddagujarati",1,1578}, +{"ddagurmukhi",1,1579}, +{"ddalarabic",1,1580}, +{"ddalfinalarabic",1,1581}, +{"dddhadeva",1,1582}, +{"ddhabengali",1,1583}, +{"ddhadeva",1,1584}, +{"ddhagujarati",1,1585}, +{"ddhagurmukhi",1,1586}, +{"ddotaccent",1,1587}, +{"ddotbelow",1,1588}, +{"decimalseparatorarabic",1,1589}, +{"decimalseparatorpersian",1,1590}, +{"decyrillic",1,1591}, +{"degree",1,1592}, +{"dehihebrew",1,1593}, +{"dehiragana",1,1594}, +{"deicoptic",1,1595}, +{"dekatakana",1,1596}, +{"deleteleft",1,1597}, +{"deleteright",1,1598}, +{"delta",1,1599}, +{"deltaturned",1,1600}, +{"denominatorminusonenumeratorbengali",1,1601}, +{"dezh",1,1602}, +{"dhabengali",1,1603}, +{"dhadeva",1,1604}, +{"dhagujarati",1,1605}, +{"dhagurmukhi",1,1606}, +{"dhook",1,1607}, +{"dialytikatonos",1,1608}, +{"dialytikatonoscmb",1,1609}, +{"diamond",1,1610}, +{"diamondsuitwhite",1,1611}, +{"dieresis",1,1612}, +{"dieresisacute",1,1613}, +{"dieresisbelowcmb",1,1614}, +{"dieresiscmb",1,1615}, +{"dieresisgrave",1,1616}, +{"dieresistonos",1,1617}, +{"dihiragana",1,1618}, +{"dikatakana",1,1619}, +{"dittomark",1,1620}, +{"divide",1,1621}, +{"divides",1,1622}, +{"divisionslash",1,1623}, +{"djecyrillic",1,1624}, +{"dkshade",1,1625}, +{"dlinebelow",1,1626}, +{"dlsquare",1,1627}, +{"dmacron",1,1628}, +{"dmonospace",1,1629}, +{"dnblock",1,1630}, +{"dochadathai",1,1631}, +{"dodekthai",1,1632}, +{"dohiragana",1,1633}, +{"dokatakana",1,1634}, +{"dollar",1,1635}, +{"dollarinferior",1,1636}, +{"dollarmonospace",1,1637}, +{"dollaroldstyle",1,1638}, +{"dollarsmall",1,1639}, +{"dollarsuperior",1,1640}, +{"dong",1,1641}, +{"dorusquare",1,1642}, +{"dotaccent",1,1643}, +{"dotaccentcmb",1,1644}, +{"dotbelowcmb",1,1645}, +{"dotbelowcomb",1,1646}, +{"dotkatakana",1,1647}, +{"dotlessi",1,1648}, +{"dotlessj",1,1649}, +{"dotlessjstrokehook",1,1650}, +{"dotmath",1,1651}, +{"dottedcircle",1,1652}, +{"doubleyodpatah",1,1653}, +{"doubleyodpatahhebrew",1,1654}, +{"downtackbelowcmb",1,1655}, +{"downtackmod",1,1656}, +{"dparen",1,1657}, +{"dsuperior",1,1658}, +{"dtail",1,1659}, +{"dtopbar",1,1660}, +{"duhiragana",1,1661}, +{"dukatakana",1,1662}, +{"dz",1,1663}, +{"dzaltone",1,1664}, +{"dzcaron",1,1665}, +{"dzcurl",1,1666}, +{"dzeabkhasiancyrillic",1,1667}, +{"dzecyrillic",1,1668}, +{"dzhecyrillic",1,1669}, +{"e",1,1670}, +{"eacute",1,1671}, +{"earth",1,1672}, +{"ebengali",1,1673}, +{"ebopomofo",1,1674}, +{"ebreve",1,1675}, +{"ecandradeva",1,1676}, +{"ecandragujarati",1,1677}, +{"ecandravowelsigndeva",1,1678}, +{"ecandravowelsigngujarati",1,1679}, +{"ecaron",1,1680}, +{"ecedillabreve",1,1681}, +{"echarmenian",1,1682}, +{"echyiwnarmenian",1,1683}, +{"ecircle",1,1684}, +{"ecircumflex",1,1685}, +{"ecircumflexacute",1,1686}, +{"ecircumflexbelow",1,1687}, +{"ecircumflexdotbelow",1,1688}, +{"ecircumflexgrave",1,1689}, +{"ecircumflexhookabove",1,1690}, +{"ecircumflextilde",1,1691}, +{"ecyrillic",1,1692}, +{"edblgrave",1,1693}, +{"edeva",1,1694}, +{"edieresis",1,1695}, +{"edot",1,1696}, +{"edotaccent",1,1697}, +{"edotbelow",1,1698}, +{"eegurmukhi",1,1699}, +{"eematragurmukhi",1,1700}, +{"efcyrillic",1,1701}, +{"egrave",1,1702}, +{"egujarati",1,1703}, +{"eharmenian",1,1704}, +{"ehbopomofo",1,1705}, +{"ehiragana",1,1706}, +{"ehookabove",1,1707}, +{"eibopomofo",1,1708}, +{"eight",1,1709}, +{"eightarabic",1,1710}, +{"eightbengali",1,1711}, +{"eightcircle",1,1712}, +{"eightcircleinversesansserif",1,1713}, +{"eightdeva",1,1714}, +{"eighteencircle",1,1715}, +{"eighteenparen",1,1716}, +{"eighteenperiod",1,1717}, +{"eightgujarati",1,1718}, +{"eightgurmukhi",1,1719}, +{"eighthackarabic",1,1720}, +{"eighthangzhou",1,1721}, +{"eighthnotebeamed",1,1722}, +{"eightideographicparen",1,1723}, +{"eightinferior",1,1724}, +{"eightmonospace",1,1725}, +{"eightoldstyle",1,1726}, +{"eightparen",1,1727}, +{"eightperiod",1,1728}, +{"eightpersian",1,1729}, +{"eightroman",1,1730}, +{"eightsuperior",1,1731}, +{"eightthai",1,1732}, +{"einvertedbreve",1,1733}, +{"eiotifiedcyrillic",1,1734}, +{"ekatakana",1,1735}, +{"ekatakanahalfwidth",1,1736}, +{"ekonkargurmukhi",1,1737}, +{"ekorean",1,1738}, +{"elcyrillic",1,1739}, +{"element",1,1740}, +{"elevencircle",1,1741}, +{"elevenparen",1,1742}, +{"elevenperiod",1,1743}, +{"elevenroman",1,1744}, +{"ellipsis",1,1745}, +{"ellipsisvertical",1,1746}, +{"emacron",1,1747}, +{"emacronacute",1,1748}, +{"emacrongrave",1,1749}, +{"emcyrillic",1,1750}, +{"emdash",1,1751}, +{"emdashvertical",1,1752}, +{"emonospace",1,1753}, +{"emphasismarkarmenian",1,1754}, +{"emptyset",1,1755}, +{"enbopomofo",1,1756}, +{"encyrillic",1,1757}, +{"endash",1,1758}, +{"endashvertical",1,1759}, +{"endescendercyrillic",1,1760}, +{"eng",1,1761}, +{"engbopomofo",1,1762}, +{"enghecyrillic",1,1763}, +{"enhookcyrillic",1,1764}, +{"enspace",1,1765}, +{"eogonek",1,1766}, +{"eokorean",1,1767}, +{"eopen",1,1768}, +{"eopenclosed",1,1769}, +{"eopenreversed",1,1770}, +{"eopenreversedclosed",1,1771}, +{"eopenreversedhook",1,1772}, +{"eparen",1,1773}, +{"epsilon",1,1774}, +{"epsilontonos",1,1775}, +{"equal",1,1776}, +{"equalmonospace",1,1777}, +{"equalsmall",1,1778}, +{"equalsuperior",1,1779}, +{"equivalence",1,1780}, +{"erbopomofo",1,1781}, +{"ercyrillic",1,1782}, +{"ereversed",1,1783}, +{"ereversedcyrillic",1,1784}, +{"escyrillic",1,1785}, +{"esdescendercyrillic",1,1786}, +{"esh",1,1787}, +{"eshcurl",1,1788}, +{"eshortdeva",1,1789}, +{"eshortvowelsigndeva",1,1790}, +{"eshreversedloop",1,1791}, +{"eshsquatreversed",1,1792}, +{"esmallhiragana",1,1793}, +{"esmallkatakana",1,1794}, +{"esmallkatakanahalfwidth",1,1795}, +{"estimated",1,1796}, +{"esuperior",1,1797}, +{"eta",1,1798}, +{"etarmenian",1,1799}, +{"etatonos",1,1800}, +{"eth",1,1801}, +{"etilde",1,1802}, +{"etildebelow",1,1803}, +{"etnahtafoukhhebrew",1,1804}, +{"etnahtafoukhlefthebrew",1,1805}, +{"etnahtahebrew",1,1806}, +{"etnahtalefthebrew",1,1807}, +{"eturned",1,1808}, +{"eukorean",1,1809}, +{"euro",1,1810}, +{"evowelsignbengali",1,1811}, +{"evowelsigndeva",1,1812}, +{"evowelsigngujarati",1,1813}, +{"exclam",1,1814}, +{"exclamarmenian",1,1815}, +{"exclamdbl",1,1816}, +{"exclamdown",1,1817}, +{"exclamdownsmall",1,1818}, +{"exclammonospace",1,1819}, +{"exclamsmall",1,1820}, +{"existential",1,1821}, +{"ezh",1,1822}, +{"ezhcaron",1,1823}, +{"ezhcurl",1,1824}, +{"ezhreversed",1,1825}, +{"ezhtail",1,1826}, +{"f",1,1827}, +{"fadeva",1,1828}, +{"fagurmukhi",1,1829}, +{"fahrenheit",1,1830}, +{"fathaarabic",1,1831}, +{"fathalowarabic",1,1832}, +{"fathatanarabic",1,1833}, +{"fbopomofo",1,1834}, +{"fcircle",1,1835}, +{"fdotaccent",1,1836}, +{"feharabic",1,1837}, +{"feharmenian",1,1838}, +{"fehfinalarabic",1,1839}, +{"fehinitialarabic",1,1840}, +{"fehmedialarabic",1,1841}, +{"feicoptic",1,1842}, +{"female",1,1843}, +{"ff",1,1844}, +{"ffi",1,1845}, +{"ffl",1,1846}, +{"fi",1,1847}, +{"fifteencircle",1,1848}, +{"fifteenparen",1,1849}, +{"fifteenperiod",1,1850}, +{"figuredash",1,1851}, +{"filledbox",1,1852}, +{"filledrect",1,1853}, +{"finalkaf",1,1854}, +{"finalkafdagesh",1,1855}, +{"finalkafdageshhebrew",1,1856}, +{"finalkafhebrew",1,1857}, +{"finalkafqamats",2,1858}, +{"finalkafqamatshebrew",2,1860}, +{"finalkafsheva",2,1862}, +{"finalkafshevahebrew",2,1864}, +{"finalmem",1,1866}, +{"finalmemhebrew",1,1867}, +{"finalnun",1,1868}, +{"finalnunhebrew",1,1869}, +{"finalpe",1,1870}, +{"finalpehebrew",1,1871}, +{"finaltsadi",1,1872}, +{"finaltsadihebrew",1,1873}, +{"firsttonechinese",1,1874}, +{"fisheye",1,1875}, +{"fitacyrillic",1,1876}, +{"five",1,1877}, +{"fivearabic",1,1878}, +{"fivebengali",1,1879}, +{"fivecircle",1,1880}, +{"fivecircleinversesansserif",1,1881}, +{"fivedeva",1,1882}, +{"fiveeighths",1,1883}, +{"fivegujarati",1,1884}, +{"fivegurmukhi",1,1885}, +{"fivehackarabic",1,1886}, +{"fivehangzhou",1,1887}, +{"fiveideographicparen",1,1888}, +{"fiveinferior",1,1889}, +{"fivemonospace",1,1890}, +{"fiveoldstyle",1,1891}, +{"fiveparen",1,1892}, +{"fiveperiod",1,1893}, +{"fivepersian",1,1894}, +{"fiveroman",1,1895}, +{"fivesuperior",1,1896}, +{"fivethai",1,1897}, +{"fl",1,1898}, +{"florin",1,1899}, +{"fmonospace",1,1900}, +{"fmsquare",1,1901}, +{"fofanthai",1,1902}, +{"fofathai",1,1903}, +{"fongmanthai",1,1904}, +{"forall",1,1905}, +{"four",1,1906}, +{"fourarabic",1,1907}, +{"fourbengali",1,1908}, +{"fourcircle",1,1909}, +{"fourcircleinversesansserif",1,1910}, +{"fourdeva",1,1911}, +{"fourgujarati",1,1912}, +{"fourgurmukhi",1,1913}, +{"fourhackarabic",1,1914}, +{"fourhangzhou",1,1915}, +{"fourideographicparen",1,1916}, +{"fourinferior",1,1917}, +{"fourmonospace",1,1918}, +{"fournumeratorbengali",1,1919}, +{"fouroldstyle",1,1920}, +{"fourparen",1,1921}, +{"fourperiod",1,1922}, +{"fourpersian",1,1923}, +{"fourroman",1,1924}, +{"foursuperior",1,1925}, +{"fourteencircle",1,1926}, +{"fourteenparen",1,1927}, +{"fourteenperiod",1,1928}, +{"fourthai",1,1929}, +{"fourthtonechinese",1,1930}, +{"fparen",1,1931}, +{"fraction",1,1932}, +{"franc",1,1933}, +{"g",1,1934}, +{"gabengali",1,1935}, +{"gacute",1,1936}, +{"gadeva",1,1937}, +{"gafarabic",1,1938}, +{"gaffinalarabic",1,1939}, +{"gafinitialarabic",1,1940}, +{"gafmedialarabic",1,1941}, +{"gagujarati",1,1942}, +{"gagurmukhi",1,1943}, +{"gahiragana",1,1944}, +{"gakatakana",1,1945}, +{"gamma",1,1946}, +{"gammalatinsmall",1,1947}, +{"gammasuperior",1,1948}, +{"gangiacoptic",1,1949}, +{"gbopomofo",1,1950}, +{"gbreve",1,1951}, +{"gcaron",1,1952}, +{"gcedilla",1,1953}, +{"gcircle",1,1954}, +{"gcircumflex",1,1955}, +{"gcommaaccent",1,1956}, +{"gdot",1,1957}, +{"gdotaccent",1,1958}, +{"gecyrillic",1,1959}, +{"gehiragana",1,1960}, +{"gekatakana",1,1961}, +{"geometricallyequal",1,1962}, +{"gereshaccenthebrew",1,1963}, +{"gereshhebrew",1,1964}, +{"gereshmuqdamhebrew",1,1965}, +{"germandbls",1,1966}, +{"gershayimaccenthebrew",1,1967}, +{"gershayimhebrew",1,1968}, +{"getamark",1,1969}, +{"ghabengali",1,1970}, +{"ghadarmenian",1,1971}, +{"ghadeva",1,1972}, +{"ghagujarati",1,1973}, +{"ghagurmukhi",1,1974}, +{"ghainarabic",1,1975}, +{"ghainfinalarabic",1,1976}, +{"ghaininitialarabic",1,1977}, +{"ghainmedialarabic",1,1978}, +{"ghemiddlehookcyrillic",1,1979}, +{"ghestrokecyrillic",1,1980}, +{"gheupturncyrillic",1,1981}, +{"ghhadeva",1,1982}, +{"ghhagurmukhi",1,1983}, +{"ghook",1,1984}, +{"ghzsquare",1,1985}, +{"gihiragana",1,1986}, +{"gikatakana",1,1987}, +{"gimarmenian",1,1988}, +{"gimel",1,1989}, +{"gimeldagesh",1,1990}, +{"gimeldageshhebrew",1,1991}, +{"gimelhebrew",1,1992}, +{"gjecyrillic",1,1993}, +{"glottalinvertedstroke",1,1994}, +{"glottalstop",1,1995}, +{"glottalstopinverted",1,1996}, +{"glottalstopmod",1,1997}, +{"glottalstopreversed",1,1998}, +{"glottalstopreversedmod",1,1999}, +{"glottalstopreversedsuperior",1,2000}, +{"glottalstopstroke",1,2001}, +{"glottalstopstrokereversed",1,2002}, +{"gmacron",1,2003}, +{"gmonospace",1,2004}, +{"gohiragana",1,2005}, +{"gokatakana",1,2006}, +{"gparen",1,2007}, +{"gpasquare",1,2008}, +{"gradient",1,2009}, +{"grave",1,2010}, +{"gravebelowcmb",1,2011}, +{"gravecmb",1,2012}, +{"gravecomb",1,2013}, +{"gravedeva",1,2014}, +{"gravelowmod",1,2015}, +{"gravemonospace",1,2016}, +{"gravetonecmb",1,2017}, +{"greater",1,2018}, +{"greaterequal",1,2019}, +{"greaterequalorless",1,2020}, +{"greatermonospace",1,2021}, +{"greaterorequivalent",1,2022}, +{"greaterorless",1,2023}, +{"greateroverequal",1,2024}, +{"greatersmall",1,2025}, +{"gscript",1,2026}, +{"gstroke",1,2027}, +{"guhiragana",1,2028}, +{"guillemotleft",1,2029}, +{"guillemotright",1,2030}, +{"guilsinglleft",1,2031}, +{"guilsinglright",1,2032}, +{"gukatakana",1,2033}, +{"guramusquare",1,2034}, +{"gysquare",1,2035}, +{"h",1,2036}, +{"haabkhasiancyrillic",1,2037}, +{"haaltonearabic",1,2038}, +{"habengali",1,2039}, +{"hadescendercyrillic",1,2040}, +{"hadeva",1,2041}, +{"hagujarati",1,2042}, +{"hagurmukhi",1,2043}, +{"haharabic",1,2044}, +{"hahfinalarabic",1,2045}, +{"hahinitialarabic",1,2046}, +{"hahiragana",1,2047}, +{"hahmedialarabic",1,2048}, +{"haitusquare",1,2049}, +{"hakatakana",1,2050}, +{"hakatakanahalfwidth",1,2051}, +{"halantgurmukhi",1,2052}, +{"hamzaarabic",1,2053}, +{"hamzadammaarabic",2,2054}, +{"hamzadammatanarabic",2,2056}, +{"hamzafathaarabic",2,2058}, +{"hamzafathatanarabic",2,2060}, +{"hamzalowarabic",1,2062}, +{"hamzalowkasraarabic",2,2063}, +{"hamzalowkasratanarabic",2,2065}, +{"hamzasukunarabic",2,2067}, +{"hangulfiller",1,2069}, +{"hardsigncyrillic",1,2070}, +{"harpoonleftbarbup",1,2071}, +{"harpoonrightbarbup",1,2072}, +{"hasquare",1,2073}, +{"hatafpatah",1,2074}, +{"hatafpatah16",1,2075}, +{"hatafpatah23",1,2076}, +{"hatafpatah2f",1,2077}, +{"hatafpatahhebrew",1,2078}, +{"hatafpatahnarrowhebrew",1,2079}, +{"hatafpatahquarterhebrew",1,2080}, +{"hatafpatahwidehebrew",1,2081}, +{"hatafqamats",1,2082}, +{"hatafqamats1b",1,2083}, +{"hatafqamats28",1,2084}, +{"hatafqamats34",1,2085}, +{"hatafqamatshebrew",1,2086}, +{"hatafqamatsnarrowhebrew",1,2087}, +{"hatafqamatsquarterhebrew",1,2088}, +{"hatafqamatswidehebrew",1,2089}, +{"hatafsegol",1,2090}, +{"hatafsegol17",1,2091}, +{"hatafsegol24",1,2092}, +{"hatafsegol30",1,2093}, +{"hatafsegolhebrew",1,2094}, +{"hatafsegolnarrowhebrew",1,2095}, +{"hatafsegolquarterhebrew",1,2096}, +{"hatafsegolwidehebrew",1,2097}, +{"hbar",1,2098}, +{"hbopomofo",1,2099}, +{"hbrevebelow",1,2100}, +{"hcedilla",1,2101}, +{"hcircle",1,2102}, +{"hcircumflex",1,2103}, +{"hdieresis",1,2104}, +{"hdotaccent",1,2105}, +{"hdotbelow",1,2106}, +{"he",1,2107}, +{"heart",1,2108}, +{"heartsuitblack",1,2109}, +{"heartsuitwhite",1,2110}, +{"hedagesh",1,2111}, +{"hedageshhebrew",1,2112}, +{"hehaltonearabic",1,2113}, +{"heharabic",1,2114}, +{"hehebrew",1,2115}, +{"hehfinalaltonearabic",1,2116}, +{"hehfinalalttwoarabic",1,2117}, +{"hehfinalarabic",1,2118}, +{"hehhamzaabovefinalarabic",1,2119}, +{"hehhamzaaboveisolatedarabic",1,2120}, +{"hehinitialaltonearabic",1,2121}, +{"hehinitialarabic",1,2122}, +{"hehiragana",1,2123}, +{"hehmedialaltonearabic",1,2124}, +{"hehmedialarabic",1,2125}, +{"heiseierasquare",1,2126}, +{"hekatakana",1,2127}, +{"hekatakanahalfwidth",1,2128}, +{"hekutaarusquare",1,2129}, +{"henghook",1,2130}, +{"herutusquare",1,2131}, +{"het",1,2132}, +{"hethebrew",1,2133}, +{"hhook",1,2134}, +{"hhooksuperior",1,2135}, +{"hieuhacirclekorean",1,2136}, +{"hieuhaparenkorean",1,2137}, +{"hieuhcirclekorean",1,2138}, +{"hieuhkorean",1,2139}, +{"hieuhparenkorean",1,2140}, +{"hihiragana",1,2141}, +{"hikatakana",1,2142}, +{"hikatakanahalfwidth",1,2143}, +{"hiriq",1,2144}, +{"hiriq14",1,2145}, +{"hiriq21",1,2146}, +{"hiriq2d",1,2147}, +{"hiriqhebrew",1,2148}, +{"hiriqnarrowhebrew",1,2149}, +{"hiriqquarterhebrew",1,2150}, +{"hiriqwidehebrew",1,2151}, +{"hlinebelow",1,2152}, +{"hmonospace",1,2153}, +{"hoarmenian",1,2154}, +{"hohipthai",1,2155}, +{"hohiragana",1,2156}, +{"hokatakana",1,2157}, +{"hokatakanahalfwidth",1,2158}, +{"holam",1,2159}, +{"holam19",1,2160}, +{"holam26",1,2161}, +{"holam32",1,2162}, +{"holamhebrew",1,2163}, +{"holamnarrowhebrew",1,2164}, +{"holamquarterhebrew",1,2165}, +{"holamwidehebrew",1,2166}, +{"honokhukthai",1,2167}, +{"hookabovecomb",1,2168}, +{"hookcmb",1,2169}, +{"hookpalatalizedbelowcmb",1,2170}, +{"hookretroflexbelowcmb",1,2171}, +{"hoonsquare",1,2172}, +{"horicoptic",1,2173}, +{"horizontalbar",1,2174}, +{"horncmb",1,2175}, +{"hotsprings",1,2176}, +{"house",1,2177}, +{"hparen",1,2178}, +{"hsuperior",1,2179}, +{"hturned",1,2180}, +{"huhiragana",1,2181}, +{"huiitosquare",1,2182}, +{"hukatakana",1,2183}, +{"hukatakanahalfwidth",1,2184}, +{"hungarumlaut",1,2185}, +{"hungarumlautcmb",1,2186}, +{"hv",1,2187}, +{"hyphen",1,2188}, +{"hypheninferior",1,2189}, +{"hyphenmonospace",1,2190}, +{"hyphensmall",1,2191}, +{"hyphensuperior",1,2192}, +{"hyphentwo",1,2193}, +{"i",1,2194}, +{"iacute",1,2195}, +{"iacyrillic",1,2196}, +{"ibengali",1,2197}, +{"ibopomofo",1,2198}, +{"ibreve",1,2199}, +{"icaron",1,2200}, +{"icircle",1,2201}, +{"icircumflex",1,2202}, +{"icyrillic",1,2203}, +{"idblgrave",1,2204}, +{"ideographearthcircle",1,2205}, +{"ideographfirecircle",1,2206}, +{"ideographicallianceparen",1,2207}, +{"ideographiccallparen",1,2208}, +{"ideographiccentrecircle",1,2209}, +{"ideographicclose",1,2210}, +{"ideographiccomma",1,2211}, +{"ideographiccommaleft",1,2212}, +{"ideographiccongratulationparen",1,2213}, +{"ideographiccorrectcircle",1,2214}, +{"ideographicearthparen",1,2215}, +{"ideographicenterpriseparen",1,2216}, +{"ideographicexcellentcircle",1,2217}, +{"ideographicfestivalparen",1,2218}, +{"ideographicfinancialcircle",1,2219}, +{"ideographicfinancialparen",1,2220}, +{"ideographicfireparen",1,2221}, +{"ideographichaveparen",1,2222}, +{"ideographichighcircle",1,2223}, +{"ideographiciterationmark",1,2224}, +{"ideographiclaborcircle",1,2225}, +{"ideographiclaborparen",1,2226}, +{"ideographicleftcircle",1,2227}, +{"ideographiclowcircle",1,2228}, +{"ideographicmedicinecircle",1,2229}, +{"ideographicmetalparen",1,2230}, +{"ideographicmoonparen",1,2231}, +{"ideographicnameparen",1,2232}, +{"ideographicperiod",1,2233}, +{"ideographicprintcircle",1,2234}, +{"ideographicreachparen",1,2235}, +{"ideographicrepresentparen",1,2236}, +{"ideographicresourceparen",1,2237}, +{"ideographicrightcircle",1,2238}, +{"ideographicsecretcircle",1,2239}, +{"ideographicselfparen",1,2240}, +{"ideographicsocietyparen",1,2241}, +{"ideographicspace",1,2242}, +{"ideographicspecialparen",1,2243}, +{"ideographicstockparen",1,2244}, +{"ideographicstudyparen",1,2245}, +{"ideographicsunparen",1,2246}, +{"ideographicsuperviseparen",1,2247}, +{"ideographicwaterparen",1,2248}, +{"ideographicwoodparen",1,2249}, +{"ideographiczero",1,2250}, +{"ideographmetalcircle",1,2251}, +{"ideographmooncircle",1,2252}, +{"ideographnamecircle",1,2253}, +{"ideographsuncircle",1,2254}, +{"ideographwatercircle",1,2255}, +{"ideographwoodcircle",1,2256}, +{"ideva",1,2257}, +{"idieresis",1,2258}, +{"idieresisacute",1,2259}, +{"idieresiscyrillic",1,2260}, +{"idotbelow",1,2261}, +{"iebrevecyrillic",1,2262}, +{"iecyrillic",1,2263}, +{"ieungacirclekorean",1,2264}, +{"ieungaparenkorean",1,2265}, +{"ieungcirclekorean",1,2266}, +{"ieungkorean",1,2267}, +{"ieungparenkorean",1,2268}, +{"igrave",1,2269}, +{"igujarati",1,2270}, +{"igurmukhi",1,2271}, +{"ihiragana",1,2272}, +{"ihookabove",1,2273}, +{"iibengali",1,2274}, +{"iicyrillic",1,2275}, +{"iideva",1,2276}, +{"iigujarati",1,2277}, +{"iigurmukhi",1,2278}, +{"iimatragurmukhi",1,2279}, +{"iinvertedbreve",1,2280}, +{"iishortcyrillic",1,2281}, +{"iivowelsignbengali",1,2282}, +{"iivowelsigndeva",1,2283}, +{"iivowelsigngujarati",1,2284}, +{"ij",1,2285}, +{"ikatakana",1,2286}, +{"ikatakanahalfwidth",1,2287}, +{"ikorean",1,2288}, +{"ilde",1,2289}, +{"iluyhebrew",1,2290}, +{"imacron",1,2291}, +{"imacroncyrillic",1,2292}, +{"imageorapproximatelyequal",1,2293}, +{"imatragurmukhi",1,2294}, +{"imonospace",1,2295}, +{"increment",1,2296}, +{"infinity",1,2297}, +{"iniarmenian",1,2298}, +{"integral",1,2299}, +{"integralbottom",1,2300}, +{"integralbt",1,2301}, +{"integralex",1,2302}, +{"integraltop",1,2303}, +{"integraltp",1,2304}, +{"intersection",1,2305}, +{"intisquare",1,2306}, +{"invbullet",1,2307}, +{"invcircle",1,2308}, +{"invsmileface",1,2309}, +{"iocyrillic",1,2310}, +{"iogonek",1,2311}, +{"iota",1,2312}, +{"iotadieresis",1,2313}, +{"iotadieresistonos",1,2314}, +{"iotalatin",1,2315}, +{"iotatonos",1,2316}, +{"iparen",1,2317}, +{"irigurmukhi",1,2318}, +{"ismallhiragana",1,2319}, +{"ismallkatakana",1,2320}, +{"ismallkatakanahalfwidth",1,2321}, +{"issharbengali",1,2322}, +{"istroke",1,2323}, +{"isuperior",1,2324}, +{"iterationhiragana",1,2325}, +{"iterationkatakana",1,2326}, +{"itilde",1,2327}, +{"itildebelow",1,2328}, +{"iubopomofo",1,2329}, +{"iucyrillic",1,2330}, +{"ivowelsignbengali",1,2331}, +{"ivowelsigndeva",1,2332}, +{"ivowelsigngujarati",1,2333}, +{"izhitsacyrillic",1,2334}, +{"izhitsadblgravecyrillic",1,2335}, +{"j",1,2336}, +{"jaarmenian",1,2337}, +{"jabengali",1,2338}, +{"jadeva",1,2339}, +{"jagujarati",1,2340}, +{"jagurmukhi",1,2341}, +{"jbopomofo",1,2342}, +{"jcaron",1,2343}, +{"jcircle",1,2344}, +{"jcircumflex",1,2345}, +{"jcrossedtail",1,2346}, +{"jdotlessstroke",1,2347}, +{"jecyrillic",1,2348}, +{"jeemarabic",1,2349}, +{"jeemfinalarabic",1,2350}, +{"jeeminitialarabic",1,2351}, +{"jeemmedialarabic",1,2352}, +{"jeharabic",1,2353}, +{"jehfinalarabic",1,2354}, +{"jhabengali",1,2355}, +{"jhadeva",1,2356}, +{"jhagujarati",1,2357}, +{"jhagurmukhi",1,2358}, +{"jheharmenian",1,2359}, +{"jis",1,2360}, +{"jmonospace",1,2361}, +{"jparen",1,2362}, +{"jsuperior",1,2363}, +{"k",1,2364}, +{"kabashkircyrillic",1,2365}, +{"kabengali",1,2366}, +{"kacute",1,2367}, +{"kacyrillic",1,2368}, +{"kadescendercyrillic",1,2369}, +{"kadeva",1,2370}, +{"kaf",1,2371}, +{"kafarabic",1,2372}, +{"kafdagesh",1,2373}, +{"kafdageshhebrew",1,2374}, +{"kaffinalarabic",1,2375}, +{"kafhebrew",1,2376}, +{"kafinitialarabic",1,2377}, +{"kafmedialarabic",1,2378}, +{"kafrafehebrew",1,2379}, +{"kagujarati",1,2380}, +{"kagurmukhi",1,2381}, +{"kahiragana",1,2382}, +{"kahookcyrillic",1,2383}, +{"kakatakana",1,2384}, +{"kakatakanahalfwidth",1,2385}, +{"kappa",1,2386}, +{"kappasymbolgreek",1,2387}, +{"kapyeounmieumkorean",1,2388}, +{"kapyeounphieuphkorean",1,2389}, +{"kapyeounpieupkorean",1,2390}, +{"kapyeounssangpieupkorean",1,2391}, +{"karoriisquare",1,2392}, +{"kashidaautoarabic",1,2393}, +{"kashidaautonosidebearingarabic",1,2394}, +{"kasmallkatakana",1,2395}, +{"kasquare",1,2396}, +{"kasraarabic",1,2397}, +{"kasratanarabic",1,2398}, +{"kastrokecyrillic",1,2399}, +{"katahiraprolongmarkhalfwidth",1,2400}, +{"kaverticalstrokecyrillic",1,2401}, +{"kbopomofo",1,2402}, +{"kcalsquare",1,2403}, +{"kcaron",1,2404}, +{"kcedilla",1,2405}, +{"kcircle",1,2406}, +{"kcommaaccent",1,2407}, +{"kdotbelow",1,2408}, +{"keharmenian",1,2409}, +{"kehiragana",1,2410}, +{"kekatakana",1,2411}, +{"kekatakanahalfwidth",1,2412}, +{"kenarmenian",1,2413}, +{"kesmallkatakana",1,2414}, +{"kgreenlandic",1,2415}, +{"khabengali",1,2416}, +{"khacyrillic",1,2417}, +{"khadeva",1,2418}, +{"khagujarati",1,2419}, +{"khagurmukhi",1,2420}, +{"khaharabic",1,2421}, +{"khahfinalarabic",1,2422}, +{"khahinitialarabic",1,2423}, +{"khahmedialarabic",1,2424}, +{"kheicoptic",1,2425}, +{"khhadeva",1,2426}, +{"khhagurmukhi",1,2427}, +{"khieukhacirclekorean",1,2428}, +{"khieukhaparenkorean",1,2429}, +{"khieukhcirclekorean",1,2430}, +{"khieukhkorean",1,2431}, +{"khieukhparenkorean",1,2432}, +{"khokhaithai",1,2433}, +{"khokhonthai",1,2434}, +{"khokhuatthai",1,2435}, +{"khokhwaithai",1,2436}, +{"khomutthai",1,2437}, +{"khook",1,2438}, +{"khorakhangthai",1,2439}, +{"khzsquare",1,2440}, +{"kihiragana",1,2441}, +{"kikatakana",1,2442}, +{"kikatakanahalfwidth",1,2443}, +{"kiroguramusquare",1,2444}, +{"kiromeetorusquare",1,2445}, +{"kirosquare",1,2446}, +{"kiyeokacirclekorean",1,2447}, +{"kiyeokaparenkorean",1,2448}, +{"kiyeokcirclekorean",1,2449}, +{"kiyeokkorean",1,2450}, +{"kiyeokparenkorean",1,2451}, +{"kiyeoksioskorean",1,2452}, +{"kjecyrillic",1,2453}, +{"klinebelow",1,2454}, +{"klsquare",1,2455}, +{"kmcubedsquare",1,2456}, +{"kmonospace",1,2457}, +{"kmsquaredsquare",1,2458}, +{"kohiragana",1,2459}, +{"kohmsquare",1,2460}, +{"kokaithai",1,2461}, +{"kokatakana",1,2462}, +{"kokatakanahalfwidth",1,2463}, +{"kooposquare",1,2464}, +{"koppacyrillic",1,2465}, +{"koreanstandardsymbol",1,2466}, +{"koroniscmb",1,2467}, +{"kparen",1,2468}, +{"kpasquare",1,2469}, +{"ksicyrillic",1,2470}, +{"ktsquare",1,2471}, +{"kturned",1,2472}, +{"kuhiragana",1,2473}, +{"kukatakana",1,2474}, +{"kukatakanahalfwidth",1,2475}, +{"kvsquare",1,2476}, +{"kwsquare",1,2477}, +{"l",1,2478}, +{"labengali",1,2479}, +{"lacute",1,2480}, +{"ladeva",1,2481}, +{"lagujarati",1,2482}, +{"lagurmukhi",1,2483}, +{"lakkhangyaothai",1,2484}, +{"lamaleffinalarabic",1,2485}, +{"lamalefhamzaabovefinalarabic",1,2486}, +{"lamalefhamzaaboveisolatedarabic",1,2487}, +{"lamalefhamzabelowfinalarabic",1,2488}, +{"lamalefhamzabelowisolatedarabic",1,2489}, +{"lamalefisolatedarabic",1,2490}, +{"lamalefmaddaabovefinalarabic",1,2491}, +{"lamalefmaddaaboveisolatedarabic",1,2492}, +{"lamarabic",1,2493}, +{"lambda",1,2494}, +{"lambdastroke",1,2495}, +{"lamed",1,2496}, +{"lameddagesh",1,2497}, +{"lameddageshhebrew",1,2498}, +{"lamedhebrew",1,2499}, +{"lamedholam",2,2500}, +{"lamedholamdagesh",3,2502}, +{"lamedholamdageshhebrew",3,2505}, +{"lamedholamhebrew",2,2508}, +{"lamfinalarabic",1,2510}, +{"lamhahinitialarabic",1,2511}, +{"laminitialarabic",1,2512}, +{"lamjeeminitialarabic",1,2513}, +{"lamkhahinitialarabic",1,2514}, +{"lamlamhehisolatedarabic",1,2515}, +{"lammedialarabic",1,2516}, +{"lammeemhahinitialarabic",1,2517}, +{"lammeeminitialarabic",1,2518}, +{"lammeemjeeminitialarabic",3,2519}, +{"lammeemkhahinitialarabic",3,2522}, +{"largecircle",1,2525}, +{"lbar",1,2526}, +{"lbelt",1,2527}, +{"lbopomofo",1,2528}, +{"lcaron",1,2529}, +{"lcedilla",1,2530}, +{"lcircle",1,2531}, +{"lcircumflexbelow",1,2532}, +{"lcommaaccent",1,2533}, +{"ldot",1,2534}, +{"ldotaccent",1,2535}, +{"ldotbelow",1,2536}, +{"ldotbelowmacron",1,2537}, +{"leftangleabovecmb",1,2538}, +{"lefttackbelowcmb",1,2539}, +{"less",1,2540}, +{"lessequal",1,2541}, +{"lessequalorgreater",1,2542}, +{"lessmonospace",1,2543}, +{"lessorequivalent",1,2544}, +{"lessorgreater",1,2545}, +{"lessoverequal",1,2546}, +{"lesssmall",1,2547}, +{"lezh",1,2548}, +{"lfblock",1,2549}, +{"lhookretroflex",1,2550}, +{"lira",1,2551}, +{"liwnarmenian",1,2552}, +{"lj",1,2553}, +{"ljecyrillic",1,2554}, +{"ll",1,2555}, +{"lladeva",1,2556}, +{"llagujarati",1,2557}, +{"llinebelow",1,2558}, +{"llladeva",1,2559}, +{"llvocalicbengali",1,2560}, +{"llvocalicdeva",1,2561}, +{"llvocalicvowelsignbengali",1,2562}, +{"llvocalicvowelsigndeva",1,2563}, +{"lmiddletilde",1,2564}, +{"lmonospace",1,2565}, +{"lmsquare",1,2566}, +{"lochulathai",1,2567}, +{"logicaland",1,2568}, +{"logicalnot",1,2569}, +{"logicalnotreversed",1,2570}, +{"logicalor",1,2571}, +{"lolingthai",1,2572}, +{"longs",1,2573}, +{"lowlinecenterline",1,2574}, +{"lowlinecmb",1,2575}, +{"lowlinedashed",1,2576}, +{"lozenge",1,2577}, +{"lparen",1,2578}, +{"lslash",1,2579}, +{"lsquare",1,2580}, +{"lsuperior",1,2581}, +{"ltshade",1,2582}, +{"luthai",1,2583}, +{"lvocalicbengali",1,2584}, +{"lvocalicdeva",1,2585}, +{"lvocalicvowelsignbengali",1,2586}, +{"lvocalicvowelsigndeva",1,2587}, +{"lxsquare",1,2588}, +{"m",1,2589}, +{"mabengali",1,2590}, +{"macron",1,2591}, +{"macronbelowcmb",1,2592}, +{"macroncmb",1,2593}, +{"macronlowmod",1,2594}, +{"macronmonospace",1,2595}, +{"macute",1,2596}, +{"madeva",1,2597}, +{"magujarati",1,2598}, +{"magurmukhi",1,2599}, +{"mahapakhhebrew",1,2600}, +{"mahapakhlefthebrew",1,2601}, +{"mahiragana",1,2602}, +{"maichattawalowleftthai",1,2603}, +{"maichattawalowrightthai",1,2604}, +{"maichattawathai",1,2605}, +{"maichattawaupperleftthai",1,2606}, +{"maieklowleftthai",1,2607}, +{"maieklowrightthai",1,2608}, +{"maiekthai",1,2609}, +{"maiekupperleftthai",1,2610}, +{"maihanakatleftthai",1,2611}, +{"maihanakatthai",1,2612}, +{"maitaikhuleftthai",1,2613}, +{"maitaikhuthai",1,2614}, +{"maitholowleftthai",1,2615}, +{"maitholowrightthai",1,2616}, +{"maithothai",1,2617}, +{"maithoupperleftthai",1,2618}, +{"maitrilowleftthai",1,2619}, +{"maitrilowrightthai",1,2620}, +{"maitrithai",1,2621}, +{"maitriupperleftthai",1,2622}, +{"maiyamokthai",1,2623}, +{"makatakana",1,2624}, +{"makatakanahalfwidth",1,2625}, +{"male",1,2626}, +{"mansyonsquare",1,2627}, +{"maqafhebrew",1,2628}, +{"mars",1,2629}, +{"masoracirclehebrew",1,2630}, +{"masquare",1,2631}, +{"mbopomofo",1,2632}, +{"mbsquare",1,2633}, +{"mcircle",1,2634}, +{"mcubedsquare",1,2635}, +{"mdotaccent",1,2636}, +{"mdotbelow",1,2637}, +{"meemarabic",1,2638}, +{"meemfinalarabic",1,2639}, +{"meeminitialarabic",1,2640}, +{"meemmedialarabic",1,2641}, +{"meemmeeminitialarabic",1,2642}, +{"meemmeemisolatedarabic",1,2643}, +{"meetorusquare",1,2644}, +{"mehiragana",1,2645}, +{"meizierasquare",1,2646}, +{"mekatakana",1,2647}, +{"mekatakanahalfwidth",1,2648}, +{"mem",1,2649}, +{"memdagesh",1,2650}, +{"memdageshhebrew",1,2651}, +{"memhebrew",1,2652}, +{"menarmenian",1,2653}, +{"merkhahebrew",1,2654}, +{"merkhakefulahebrew",1,2655}, +{"merkhakefulalefthebrew",1,2656}, +{"merkhalefthebrew",1,2657}, +{"mhook",1,2658}, +{"mhzsquare",1,2659}, +{"middledotkatakanahalfwidth",1,2660}, +{"middot",1,2661}, +{"mieumacirclekorean",1,2662}, +{"mieumaparenkorean",1,2663}, +{"mieumcirclekorean",1,2664}, +{"mieumkorean",1,2665}, +{"mieumpansioskorean",1,2666}, +{"mieumparenkorean",1,2667}, +{"mieumpieupkorean",1,2668}, +{"mieumsioskorean",1,2669}, +{"mihiragana",1,2670}, +{"mikatakana",1,2671}, +{"mikatakanahalfwidth",1,2672}, +{"minus",1,2673}, +{"minusbelowcmb",1,2674}, +{"minuscircle",1,2675}, +{"minusmod",1,2676}, +{"minusplus",1,2677}, +{"minute",1,2678}, +{"miribaarusquare",1,2679}, +{"mirisquare",1,2680}, +{"mlonglegturned",1,2681}, +{"mlsquare",1,2682}, +{"mmcubedsquare",1,2683}, +{"mmonospace",1,2684}, +{"mmsquaredsquare",1,2685}, +{"mohiragana",1,2686}, +{"mohmsquare",1,2687}, +{"mokatakana",1,2688}, +{"mokatakanahalfwidth",1,2689}, +{"molsquare",1,2690}, +{"momathai",1,2691}, +{"moverssquare",1,2692}, +{"moverssquaredsquare",1,2693}, +{"mparen",1,2694}, +{"mpasquare",1,2695}, +{"mssquare",1,2696}, +{"msuperior",1,2697}, +{"mturned",1,2698}, +{"mu",1,2699}, +{"mu1",1,2700}, +{"muasquare",1,2701}, +{"muchgreater",1,2702}, +{"muchless",1,2703}, +{"mufsquare",1,2704}, +{"mugreek",1,2705}, +{"mugsquare",1,2706}, +{"muhiragana",1,2707}, +{"mukatakana",1,2708}, +{"mukatakanahalfwidth",1,2709}, +{"mulsquare",1,2710}, +{"multiply",1,2711}, +{"mumsquare",1,2712}, +{"munahhebrew",1,2713}, +{"munahlefthebrew",1,2714}, +{"musicalnote",1,2715}, +{"musicalnotedbl",1,2716}, +{"musicflatsign",1,2717}, +{"musicsharpsign",1,2718}, +{"mussquare",1,2719}, +{"muvsquare",1,2720}, +{"muwsquare",1,2721}, +{"mvmegasquare",1,2722}, +{"mvsquare",1,2723}, +{"mwmegasquare",1,2724}, +{"mwsquare",1,2725}, +{"n",1,2726}, +{"nabengali",1,2727}, +{"nabla",1,2728}, +{"nacute",1,2729}, +{"nadeva",1,2730}, +{"nagujarati",1,2731}, +{"nagurmukhi",1,2732}, +{"nahiragana",1,2733}, +{"nakatakana",1,2734}, +{"nakatakanahalfwidth",1,2735}, +{"napostrophe",1,2736}, +{"nasquare",1,2737}, +{"nbopomofo",1,2738}, +{"nbspace",1,2739}, +{"ncaron",1,2740}, +{"ncedilla",1,2741}, +{"ncircle",1,2742}, +{"ncircumflexbelow",1,2743}, +{"ncommaaccent",1,2744}, +{"ndotaccent",1,2745}, +{"ndotbelow",1,2746}, +{"nehiragana",1,2747}, +{"nekatakana",1,2748}, +{"nekatakanahalfwidth",1,2749}, +{"newsheqelsign",1,2750}, +{"nfsquare",1,2751}, +{"ngabengali",1,2752}, +{"ngadeva",1,2753}, +{"ngagujarati",1,2754}, +{"ngagurmukhi",1,2755}, +{"ngonguthai",1,2756}, +{"nhiragana",1,2757}, +{"nhookleft",1,2758}, +{"nhookretroflex",1,2759}, +{"nieunacirclekorean",1,2760}, +{"nieunaparenkorean",1,2761}, +{"nieuncieuckorean",1,2762}, +{"nieuncirclekorean",1,2763}, +{"nieunhieuhkorean",1,2764}, +{"nieunkorean",1,2765}, +{"nieunpansioskorean",1,2766}, +{"nieunparenkorean",1,2767}, +{"nieunsioskorean",1,2768}, +{"nieuntikeutkorean",1,2769}, +{"nihiragana",1,2770}, +{"nikatakana",1,2771}, +{"nikatakanahalfwidth",1,2772}, +{"nikhahitleftthai",1,2773}, +{"nikhahitthai",1,2774}, +{"nine",1,2775}, +{"ninearabic",1,2776}, +{"ninebengali",1,2777}, +{"ninecircle",1,2778}, +{"ninecircleinversesansserif",1,2779}, +{"ninedeva",1,2780}, +{"ninegujarati",1,2781}, +{"ninegurmukhi",1,2782}, +{"ninehackarabic",1,2783}, +{"ninehangzhou",1,2784}, +{"nineideographicparen",1,2785}, +{"nineinferior",1,2786}, +{"ninemonospace",1,2787}, +{"nineoldstyle",1,2788}, +{"nineparen",1,2789}, +{"nineperiod",1,2790}, +{"ninepersian",1,2791}, +{"nineroman",1,2792}, +{"ninesuperior",1,2793}, +{"nineteencircle",1,2794}, +{"nineteenparen",1,2795}, +{"nineteenperiod",1,2796}, +{"ninethai",1,2797}, +{"nj",1,2798}, +{"njecyrillic",1,2799}, +{"nkatakana",1,2800}, +{"nkatakanahalfwidth",1,2801}, +{"nlegrightlong",1,2802}, +{"nlinebelow",1,2803}, +{"nmonospace",1,2804}, +{"nmsquare",1,2805}, +{"nnabengali",1,2806}, +{"nnadeva",1,2807}, +{"nnagujarati",1,2808}, +{"nnagurmukhi",1,2809}, +{"nnnadeva",1,2810}, +{"nohiragana",1,2811}, +{"nokatakana",1,2812}, +{"nokatakanahalfwidth",1,2813}, +{"nonbreakingspace",1,2814}, +{"nonenthai",1,2815}, +{"nonuthai",1,2816}, +{"noonarabic",1,2817}, +{"noonfinalarabic",1,2818}, +{"noonghunnaarabic",1,2819}, +{"noonghunnafinalarabic",1,2820}, +{"noonhehinitialarabic",2,2821}, +{"nooninitialarabic",1,2823}, +{"noonjeeminitialarabic",1,2824}, +{"noonjeemisolatedarabic",1,2825}, +{"noonmedialarabic",1,2826}, +{"noonmeeminitialarabic",1,2827}, +{"noonmeemisolatedarabic",1,2828}, +{"noonnoonfinalarabic",1,2829}, +{"notcontains",1,2830}, +{"notelement",1,2831}, +{"notelementof",1,2832}, +{"notequal",1,2833}, +{"notgreater",1,2834}, +{"notgreaternorequal",1,2835}, +{"notgreaternorless",1,2836}, +{"notidentical",1,2837}, +{"notless",1,2838}, +{"notlessnorequal",1,2839}, +{"notparallel",1,2840}, +{"notprecedes",1,2841}, +{"notsubset",1,2842}, +{"notsucceeds",1,2843}, +{"notsuperset",1,2844}, +{"nowarmenian",1,2845}, +{"nparen",1,2846}, +{"nssquare",1,2847}, +{"nsuperior",1,2848}, +{"ntilde",1,2849}, +{"nu",1,2850}, +{"nuhiragana",1,2851}, +{"nukatakana",1,2852}, +{"nukatakanahalfwidth",1,2853}, +{"nuktabengali",1,2854}, +{"nuktadeva",1,2855}, +{"nuktagujarati",1,2856}, +{"nuktagurmukhi",1,2857}, +{"numbersign",1,2858}, +{"numbersignmonospace",1,2859}, +{"numbersignsmall",1,2860}, +{"numeralsigngreek",1,2861}, +{"numeralsignlowergreek",1,2862}, +{"numero",1,2863}, +{"nun",1,2864}, +{"nundagesh",1,2865}, +{"nundageshhebrew",1,2866}, +{"nunhebrew",1,2867}, +{"nvsquare",1,2868}, +{"nwsquare",1,2869}, +{"nyabengali",1,2870}, +{"nyadeva",1,2871}, +{"nyagujarati",1,2872}, +{"nyagurmukhi",1,2873}, +{"o",1,2874}, +{"oacute",1,2875}, +{"oangthai",1,2876}, +{"obarred",1,2877}, +{"obarredcyrillic",1,2878}, +{"obarreddieresiscyrillic",1,2879}, +{"obengali",1,2880}, +{"obopomofo",1,2881}, +{"obreve",1,2882}, +{"ocandradeva",1,2883}, +{"ocandragujarati",1,2884}, +{"ocandravowelsigndeva",1,2885}, +{"ocandravowelsigngujarati",1,2886}, +{"ocaron",1,2887}, +{"ocircle",1,2888}, +{"ocircumflex",1,2889}, +{"ocircumflexacute",1,2890}, +{"ocircumflexdotbelow",1,2891}, +{"ocircumflexgrave",1,2892}, +{"ocircumflexhookabove",1,2893}, +{"ocircumflextilde",1,2894}, +{"ocyrillic",1,2895}, +{"odblacute",1,2896}, +{"odblgrave",1,2897}, +{"odeva",1,2898}, +{"odieresis",1,2899}, +{"odieresiscyrillic",1,2900}, +{"odotbelow",1,2901}, +{"oe",1,2902}, +{"oekorean",1,2903}, +{"ogonek",1,2904}, +{"ogonekcmb",1,2905}, +{"ograve",1,2906}, +{"ogujarati",1,2907}, +{"oharmenian",1,2908}, +{"ohiragana",1,2909}, +{"ohookabove",1,2910}, +{"ohorn",1,2911}, +{"ohornacute",1,2912}, +{"ohorndotbelow",1,2913}, +{"ohorngrave",1,2914}, +{"ohornhookabove",1,2915}, +{"ohorntilde",1,2916}, +{"ohungarumlaut",1,2917}, +{"oi",1,2918}, +{"oinvertedbreve",1,2919}, +{"okatakana",1,2920}, +{"okatakanahalfwidth",1,2921}, +{"okorean",1,2922}, +{"olehebrew",1,2923}, +{"omacron",1,2924}, +{"omacronacute",1,2925}, +{"omacrongrave",1,2926}, +{"omdeva",1,2927}, +{"omega",1,2928}, +{"omega1",1,2929}, +{"omegacyrillic",1,2930}, +{"omegalatinclosed",1,2931}, +{"omegaroundcyrillic",1,2932}, +{"omegatitlocyrillic",1,2933}, +{"omegatonos",1,2934}, +{"omgujarati",1,2935}, +{"omicron",1,2936}, +{"omicrontonos",1,2937}, +{"omonospace",1,2938}, +{"one",1,2939}, +{"onearabic",1,2940}, +{"onebengali",1,2941}, +{"onecircle",1,2942}, +{"onecircleinversesansserif",1,2943}, +{"onedeva",1,2944}, +{"onedotenleader",1,2945}, +{"oneeighth",1,2946}, +{"onefitted",1,2947}, +{"onegujarati",1,2948}, +{"onegurmukhi",1,2949}, +{"onehackarabic",1,2950}, +{"onehalf",1,2951}, +{"onehangzhou",1,2952}, +{"oneideographicparen",1,2953}, +{"oneinferior",1,2954}, +{"onemonospace",1,2955}, +{"onenumeratorbengali",1,2956}, +{"oneoldstyle",1,2957}, +{"oneparen",1,2958}, +{"oneperiod",1,2959}, +{"onepersian",1,2960}, +{"onequarter",1,2961}, +{"oneroman",1,2962}, +{"onesuperior",1,2963}, +{"onethai",1,2964}, +{"onethird",1,2965}, +{"oogonek",1,2966}, +{"oogonekmacron",1,2967}, +{"oogurmukhi",1,2968}, +{"oomatragurmukhi",1,2969}, +{"oopen",1,2970}, +{"oparen",1,2971}, +{"openbullet",1,2972}, +{"option",1,2973}, +{"ordfeminine",1,2974}, +{"ordmasculine",1,2975}, +{"orthogonal",1,2976}, +{"oshortdeva",1,2977}, +{"oshortvowelsigndeva",1,2978}, +{"oslash",1,2979}, +{"oslashacute",1,2980}, +{"osmallhiragana",1,2981}, +{"osmallkatakana",1,2982}, +{"osmallkatakanahalfwidth",1,2983}, +{"ostrokeacute",1,2984}, +{"osuperior",1,2985}, +{"otcyrillic",1,2986}, +{"otilde",1,2987}, +{"otildeacute",1,2988}, +{"otildedieresis",1,2989}, +{"oubopomofo",1,2990}, +{"overline",1,2991}, +{"overlinecenterline",1,2992}, +{"overlinecmb",1,2993}, +{"overlinedashed",1,2994}, +{"overlinedblwavy",1,2995}, +{"overlinewavy",1,2996}, +{"overscore",1,2997}, +{"ovowelsignbengali",1,2998}, +{"ovowelsigndeva",1,2999}, +{"ovowelsigngujarati",1,3000}, +{"p",1,3001}, +{"paampssquare",1,3002}, +{"paasentosquare",1,3003}, +{"pabengali",1,3004}, +{"pacute",1,3005}, +{"padeva",1,3006}, +{"pagedown",1,3007}, +{"pageup",1,3008}, +{"pagujarati",1,3009}, +{"pagurmukhi",1,3010}, +{"pahiragana",1,3011}, +{"paiyannoithai",1,3012}, +{"pakatakana",1,3013}, +{"palatalizationcyrilliccmb",1,3014}, +{"palochkacyrillic",1,3015}, +{"pansioskorean",1,3016}, +{"paragraph",1,3017}, +{"parallel",1,3018}, +{"parenleft",1,3019}, +{"parenleftaltonearabic",1,3020}, +{"parenleftbt",1,3021}, +{"parenleftex",1,3022}, +{"parenleftinferior",1,3023}, +{"parenleftmonospace",1,3024}, +{"parenleftsmall",1,3025}, +{"parenleftsuperior",1,3026}, +{"parenlefttp",1,3027}, +{"parenleftvertical",1,3028}, +{"parenright",1,3029}, +{"parenrightaltonearabic",1,3030}, +{"parenrightbt",1,3031}, +{"parenrightex",1,3032}, +{"parenrightinferior",1,3033}, +{"parenrightmonospace",1,3034}, +{"parenrightsmall",1,3035}, +{"parenrightsuperior",1,3036}, +{"parenrighttp",1,3037}, +{"parenrightvertical",1,3038}, +{"partialdiff",1,3039}, +{"paseqhebrew",1,3040}, +{"pashtahebrew",1,3041}, +{"pasquare",1,3042}, +{"patah",1,3043}, +{"patah11",1,3044}, +{"patah1d",1,3045}, +{"patah2a",1,3046}, +{"patahhebrew",1,3047}, +{"patahnarrowhebrew",1,3048}, +{"patahquarterhebrew",1,3049}, +{"patahwidehebrew",1,3050}, +{"pazerhebrew",1,3051}, +{"pbopomofo",1,3052}, +{"pcircle",1,3053}, +{"pdotaccent",1,3054}, +{"pe",1,3055}, +{"pecyrillic",1,3056}, +{"pedagesh",1,3057}, +{"pedageshhebrew",1,3058}, +{"peezisquare",1,3059}, +{"pefinaldageshhebrew",1,3060}, +{"peharabic",1,3061}, +{"peharmenian",1,3062}, +{"pehebrew",1,3063}, +{"pehfinalarabic",1,3064}, +{"pehinitialarabic",1,3065}, +{"pehiragana",1,3066}, +{"pehmedialarabic",1,3067}, +{"pekatakana",1,3068}, +{"pemiddlehookcyrillic",1,3069}, +{"perafehebrew",1,3070}, +{"percent",1,3071}, +{"percentarabic",1,3072}, +{"percentmonospace",1,3073}, +{"percentsmall",1,3074}, +{"period",1,3075}, +{"periodarmenian",1,3076}, +{"periodcentered",1,3077}, +{"periodhalfwidth",1,3078}, +{"periodinferior",1,3079}, +{"periodmonospace",1,3080}, +{"periodsmall",1,3081}, +{"periodsuperior",1,3082}, +{"perispomenigreekcmb",1,3083}, +{"perpendicular",1,3084}, +{"perthousand",1,3085}, +{"peseta",1,3086}, +{"pfsquare",1,3087}, +{"phabengali",1,3088}, +{"phadeva",1,3089}, +{"phagujarati",1,3090}, +{"phagurmukhi",1,3091}, +{"phi",1,3092}, +{"phi1",1,3093}, +{"phieuphacirclekorean",1,3094}, +{"phieuphaparenkorean",1,3095}, +{"phieuphcirclekorean",1,3096}, +{"phieuphkorean",1,3097}, +{"phieuphparenkorean",1,3098}, +{"philatin",1,3099}, +{"phinthuthai",1,3100}, +{"phisymbolgreek",1,3101}, +{"phook",1,3102}, +{"phophanthai",1,3103}, +{"phophungthai",1,3104}, +{"phosamphaothai",1,3105}, +{"pi",1,3106}, +{"pieupacirclekorean",1,3107}, +{"pieupaparenkorean",1,3108}, +{"pieupcieuckorean",1,3109}, +{"pieupcirclekorean",1,3110}, +{"pieupkiyeokkorean",1,3111}, +{"pieupkorean",1,3112}, +{"pieupparenkorean",1,3113}, +{"pieupsioskiyeokkorean",1,3114}, +{"pieupsioskorean",1,3115}, +{"pieupsiostikeutkorean",1,3116}, +{"pieupthieuthkorean",1,3117}, +{"pieuptikeutkorean",1,3118}, +{"pihiragana",1,3119}, +{"pikatakana",1,3120}, +{"pisymbolgreek",1,3121}, +{"piwrarmenian",1,3122}, +{"plus",1,3123}, +{"plusbelowcmb",1,3124}, +{"pluscircle",1,3125}, +{"plusminus",1,3126}, +{"plusmod",1,3127}, +{"plusmonospace",1,3128}, +{"plussmall",1,3129}, +{"plussuperior",1,3130}, +{"pmonospace",1,3131}, +{"pmsquare",1,3132}, +{"pohiragana",1,3133}, +{"pointingindexdownwhite",1,3134}, +{"pointingindexleftwhite",1,3135}, +{"pointingindexrightwhite",1,3136}, +{"pointingindexupwhite",1,3137}, +{"pokatakana",1,3138}, +{"poplathai",1,3139}, +{"postalmark",1,3140}, +{"postalmarkface",1,3141}, +{"pparen",1,3142}, +{"precedes",1,3143}, +{"prescription",1,3144}, +{"primemod",1,3145}, +{"primereversed",1,3146}, +{"product",1,3147}, +{"projective",1,3148}, +{"prolongedkana",1,3149}, +{"propellor",1,3150}, +{"propersubset",1,3151}, +{"propersuperset",1,3152}, +{"proportion",1,3153}, +{"proportional",1,3154}, +{"psi",1,3155}, +{"psicyrillic",1,3156}, +{"psilipneumatacyrilliccmb",1,3157}, +{"pssquare",1,3158}, +{"puhiragana",1,3159}, +{"pukatakana",1,3160}, +{"pvsquare",1,3161}, +{"pwsquare",1,3162}, +{"q",1,3163}, +{"qadeva",1,3164}, +{"qadmahebrew",1,3165}, +{"qafarabic",1,3166}, +{"qaffinalarabic",1,3167}, +{"qafinitialarabic",1,3168}, +{"qafmedialarabic",1,3169}, +{"qamats",1,3170}, +{"qamats10",1,3171}, +{"qamats1a",1,3172}, +{"qamats1c",1,3173}, +{"qamats27",1,3174}, +{"qamats29",1,3175}, +{"qamats33",1,3176}, +{"qamatsde",1,3177}, +{"qamatshebrew",1,3178}, +{"qamatsnarrowhebrew",1,3179}, +{"qamatsqatanhebrew",1,3180}, +{"qamatsqatannarrowhebrew",1,3181}, +{"qamatsqatanquarterhebrew",1,3182}, +{"qamatsqatanwidehebrew",1,3183}, +{"qamatsquarterhebrew",1,3184}, +{"qamatswidehebrew",1,3185}, +{"qarneyparahebrew",1,3186}, +{"qbopomofo",1,3187}, +{"qcircle",1,3188}, +{"qhook",1,3189}, +{"qmonospace",1,3190}, +{"qof",1,3191}, +{"qofdagesh",1,3192}, +{"qofdageshhebrew",1,3193}, +{"qofhatafpatah",2,3194}, +{"qofhatafpatahhebrew",2,3196}, +{"qofhatafsegol",2,3198}, +{"qofhatafsegolhebrew",2,3200}, +{"qofhebrew",1,3202}, +{"qofhiriq",2,3203}, +{"qofhiriqhebrew",2,3205}, +{"qofholam",2,3207}, +{"qofholamhebrew",2,3209}, +{"qofpatah",2,3211}, +{"qofpatahhebrew",2,3213}, +{"qofqamats",2,3215}, +{"qofqamatshebrew",2,3217}, +{"qofqubuts",2,3219}, +{"qofqubutshebrew",2,3221}, +{"qofsegol",2,3223}, +{"qofsegolhebrew",2,3225}, +{"qofsheva",2,3227}, +{"qofshevahebrew",2,3229}, +{"qoftsere",2,3231}, +{"qoftserehebrew",2,3233}, +{"qparen",1,3235}, +{"quarternote",1,3236}, +{"qubuts",1,3237}, +{"qubuts18",1,3238}, +{"qubuts25",1,3239}, +{"qubuts31",1,3240}, +{"qubutshebrew",1,3241}, +{"qubutsnarrowhebrew",1,3242}, +{"qubutsquarterhebrew",1,3243}, +{"qubutswidehebrew",1,3244}, +{"question",1,3245}, +{"questionarabic",1,3246}, +{"questionarmenian",1,3247}, +{"questiondown",1,3248}, +{"questiondownsmall",1,3249}, +{"questiongreek",1,3250}, +{"questionmonospace",1,3251}, +{"questionsmall",1,3252}, +{"quotedbl",1,3253}, +{"quotedblbase",1,3254}, +{"quotedblleft",1,3255}, +{"quotedblmonospace",1,3256}, +{"quotedblprime",1,3257}, +{"quotedblprimereversed",1,3258}, +{"quotedblright",1,3259}, +{"quoteleft",1,3260}, +{"quoteleftreversed",1,3261}, +{"quotereversed",1,3262}, +{"quoteright",1,3263}, +{"quoterightn",1,3264}, +{"quotesinglbase",1,3265}, +{"quotesingle",1,3266}, +{"quotesinglemonospace",1,3267}, +{"r",1,3268}, +{"raarmenian",1,3269}, +{"rabengali",1,3270}, +{"racute",1,3271}, +{"radeva",1,3272}, +{"radical",1,3273}, +{"radicalex",1,3274}, +{"radoverssquare",1,3275}, +{"radoverssquaredsquare",1,3276}, +{"radsquare",1,3277}, +{"rafe",1,3278}, +{"rafehebrew",1,3279}, +{"ragujarati",1,3280}, +{"ragurmukhi",1,3281}, +{"rahiragana",1,3282}, +{"rakatakana",1,3283}, +{"rakatakanahalfwidth",1,3284}, +{"ralowerdiagonalbengali",1,3285}, +{"ramiddlediagonalbengali",1,3286}, +{"ramshorn",1,3287}, +{"ratio",1,3288}, +{"rbopomofo",1,3289}, +{"rcaron",1,3290}, +{"rcedilla",1,3291}, +{"rcircle",1,3292}, +{"rcommaaccent",1,3293}, +{"rdblgrave",1,3294}, +{"rdotaccent",1,3295}, +{"rdotbelow",1,3296}, +{"rdotbelowmacron",1,3297}, +{"referencemark",1,3298}, +{"reflexsubset",1,3299}, +{"reflexsuperset",1,3300}, +{"registered",1,3301}, +{"registersans",1,3302}, +{"registerserif",1,3303}, +{"reharabic",1,3304}, +{"reharmenian",1,3305}, +{"rehfinalarabic",1,3306}, +{"rehiragana",1,3307}, +{"rehyehaleflamarabic",4,3308}, +{"rekatakana",1,3312}, +{"rekatakanahalfwidth",1,3313}, +{"resh",1,3314}, +{"reshdageshhebrew",1,3315}, +{"reshhatafpatah",2,3316}, +{"reshhatafpatahhebrew",2,3318}, +{"reshhatafsegol",2,3320}, +{"reshhatafsegolhebrew",2,3322}, +{"reshhebrew",1,3324}, +{"reshhiriq",2,3325}, +{"reshhiriqhebrew",2,3327}, +{"reshholam",2,3329}, +{"reshholamhebrew",2,3331}, +{"reshpatah",2,3333}, +{"reshpatahhebrew",2,3335}, +{"reshqamats",2,3337}, +{"reshqamatshebrew",2,3339}, +{"reshqubuts",2,3341}, +{"reshqubutshebrew",2,3343}, +{"reshsegol",2,3345}, +{"reshsegolhebrew",2,3347}, +{"reshsheva",2,3349}, +{"reshshevahebrew",2,3351}, +{"reshtsere",2,3353}, +{"reshtserehebrew",2,3355}, +{"reversedtilde",1,3357}, +{"reviahebrew",1,3358}, +{"reviamugrashhebrew",1,3359}, +{"revlogicalnot",1,3360}, +{"rfishhook",1,3361}, +{"rfishhookreversed",1,3362}, +{"rhabengali",1,3363}, +{"rhadeva",1,3364}, +{"rho",1,3365}, +{"rhook",1,3366}, +{"rhookturned",1,3367}, +{"rhookturnedsuperior",1,3368}, +{"rhosymbolgreek",1,3369}, +{"rhotichookmod",1,3370}, +{"rieulacirclekorean",1,3371}, +{"rieulaparenkorean",1,3372}, +{"rieulcirclekorean",1,3373}, +{"rieulhieuhkorean",1,3374}, +{"rieulkiyeokkorean",1,3375}, +{"rieulkiyeoksioskorean",1,3376}, +{"rieulkorean",1,3377}, +{"rieulmieumkorean",1,3378}, +{"rieulpansioskorean",1,3379}, +{"rieulparenkorean",1,3380}, +{"rieulphieuphkorean",1,3381}, +{"rieulpieupkorean",1,3382}, +{"rieulpieupsioskorean",1,3383}, +{"rieulsioskorean",1,3384}, +{"rieulthieuthkorean",1,3385}, +{"rieultikeutkorean",1,3386}, +{"rieulyeorinhieuhkorean",1,3387}, +{"rightangle",1,3388}, +{"righttackbelowcmb",1,3389}, +{"righttriangle",1,3390}, +{"rihiragana",1,3391}, +{"rikatakana",1,3392}, +{"rikatakanahalfwidth",1,3393}, +{"ring",1,3394}, +{"ringbelowcmb",1,3395}, +{"ringcmb",1,3396}, +{"ringhalfleft",1,3397}, +{"ringhalfleftarmenian",1,3398}, +{"ringhalfleftbelowcmb",1,3399}, +{"ringhalfleftcentered",1,3400}, +{"ringhalfright",1,3401}, +{"ringhalfrightbelowcmb",1,3402}, +{"ringhalfrightcentered",1,3403}, +{"rinvertedbreve",1,3404}, +{"rittorusquare",1,3405}, +{"rlinebelow",1,3406}, +{"rlongleg",1,3407}, +{"rlonglegturned",1,3408}, +{"rmonospace",1,3409}, +{"rohiragana",1,3410}, +{"rokatakana",1,3411}, +{"rokatakanahalfwidth",1,3412}, +{"roruathai",1,3413}, +{"rparen",1,3414}, +{"rrabengali",1,3415}, +{"rradeva",1,3416}, +{"rragurmukhi",1,3417}, +{"rreharabic",1,3418}, +{"rrehfinalarabic",1,3419}, +{"rrvocalicbengali",1,3420}, +{"rrvocalicdeva",1,3421}, +{"rrvocalicgujarati",1,3422}, +{"rrvocalicvowelsignbengali",1,3423}, +{"rrvocalicvowelsigndeva",1,3424}, +{"rrvocalicvowelsigngujarati",1,3425}, +{"rsuperior",1,3426}, +{"rtblock",1,3427}, +{"rturned",1,3428}, +{"rturnedsuperior",1,3429}, +{"ruhiragana",1,3430}, +{"rukatakana",1,3431}, +{"rukatakanahalfwidth",1,3432}, +{"rupeemarkbengali",1,3433}, +{"rupeesignbengali",1,3434}, +{"rupiah",1,3435}, +{"ruthai",1,3436}, +{"rvocalicbengali",1,3437}, +{"rvocalicdeva",1,3438}, +{"rvocalicgujarati",1,3439}, +{"rvocalicvowelsignbengali",1,3440}, +{"rvocalicvowelsigndeva",1,3441}, +{"rvocalicvowelsigngujarati",1,3442}, +{"s",1,3443}, +{"sabengali",1,3444}, +{"sacute",1,3445}, +{"sacutedotaccent",1,3446}, +{"sadarabic",1,3447}, +{"sadeva",1,3448}, +{"sadfinalarabic",1,3449}, +{"sadinitialarabic",1,3450}, +{"sadmedialarabic",1,3451}, +{"sagujarati",1,3452}, +{"sagurmukhi",1,3453}, +{"sahiragana",1,3454}, +{"sakatakana",1,3455}, +{"sakatakanahalfwidth",1,3456}, +{"sallallahoualayhewasallamarabic",1,3457}, +{"samekh",1,3458}, +{"samekhdagesh",1,3459}, +{"samekhdageshhebrew",1,3460}, +{"samekhhebrew",1,3461}, +{"saraaathai",1,3462}, +{"saraaethai",1,3463}, +{"saraaimaimalaithai",1,3464}, +{"saraaimaimuanthai",1,3465}, +{"saraamthai",1,3466}, +{"saraathai",1,3467}, +{"saraethai",1,3468}, +{"saraiileftthai",1,3469}, +{"saraiithai",1,3470}, +{"saraileftthai",1,3471}, +{"saraithai",1,3472}, +{"saraothai",1,3473}, +{"saraueeleftthai",1,3474}, +{"saraueethai",1,3475}, +{"saraueleftthai",1,3476}, +{"sarauethai",1,3477}, +{"sarauthai",1,3478}, +{"sarauuthai",1,3479}, +{"sbopomofo",1,3480}, +{"scaron",1,3481}, +{"scarondotaccent",1,3482}, +{"scedilla",1,3483}, +{"schwa",1,3484}, +{"schwacyrillic",1,3485}, +{"schwadieresiscyrillic",1,3486}, +{"schwahook",1,3487}, +{"scircle",1,3488}, +{"scircumflex",1,3489}, +{"scommaaccent",1,3490}, +{"sdotaccent",1,3491}, +{"sdotbelow",1,3492}, +{"sdotbelowdotaccent",1,3493}, +{"seagullbelowcmb",1,3494}, +{"second",1,3495}, +{"secondtonechinese",1,3496}, +{"section",1,3497}, +{"seenarabic",1,3498}, +{"seenfinalarabic",1,3499}, +{"seeninitialarabic",1,3500}, +{"seenmedialarabic",1,3501}, +{"segol",1,3502}, +{"segol13",1,3503}, +{"segol1f",1,3504}, +{"segol2c",1,3505}, +{"segolhebrew",1,3506}, +{"segolnarrowhebrew",1,3507}, +{"segolquarterhebrew",1,3508}, +{"segoltahebrew",1,3509}, +{"segolwidehebrew",1,3510}, +{"seharmenian",1,3511}, +{"sehiragana",1,3512}, +{"sekatakana",1,3513}, +{"sekatakanahalfwidth",1,3514}, +{"semicolon",1,3515}, +{"semicolonarabic",1,3516}, +{"semicolonmonospace",1,3517}, +{"semicolonsmall",1,3518}, +{"semivoicedmarkkana",1,3519}, +{"semivoicedmarkkanahalfwidth",1,3520}, +{"sentisquare",1,3521}, +{"sentosquare",1,3522}, +{"seven",1,3523}, +{"sevenarabic",1,3524}, +{"sevenbengali",1,3525}, +{"sevencircle",1,3526}, +{"sevencircleinversesansserif",1,3527}, +{"sevendeva",1,3528}, +{"seveneighths",1,3529}, +{"sevengujarati",1,3530}, +{"sevengurmukhi",1,3531}, +{"sevenhackarabic",1,3532}, +{"sevenhangzhou",1,3533}, +{"sevenideographicparen",1,3534}, +{"seveninferior",1,3535}, +{"sevenmonospace",1,3536}, +{"sevenoldstyle",1,3537}, +{"sevenparen",1,3538}, +{"sevenperiod",1,3539}, +{"sevenpersian",1,3540}, +{"sevenroman",1,3541}, +{"sevensuperior",1,3542}, +{"seventeencircle",1,3543}, +{"seventeenparen",1,3544}, +{"seventeenperiod",1,3545}, +{"seventhai",1,3546}, +{"sfthyphen",1,3547}, +{"shaarmenian",1,3548}, +{"shabengali",1,3549}, +{"shacyrillic",1,3550}, +{"shaddaarabic",1,3551}, +{"shaddadammaarabic",1,3552}, +{"shaddadammatanarabic",1,3553}, +{"shaddafathaarabic",1,3554}, +{"shaddafathatanarabic",2,3555}, +{"shaddakasraarabic",1,3557}, +{"shaddakasratanarabic",1,3558}, +{"shade",1,3559}, +{"shadedark",1,3560}, +{"shadelight",1,3561}, +{"shademedium",1,3562}, +{"shadeva",1,3563}, +{"shagujarati",1,3564}, +{"shagurmukhi",1,3565}, +{"shalshelethebrew",1,3566}, +{"shbopomofo",1,3567}, +{"shchacyrillic",1,3568}, +{"sheenarabic",1,3569}, +{"sheenfinalarabic",1,3570}, +{"sheeninitialarabic",1,3571}, +{"sheenmedialarabic",1,3572}, +{"sheicoptic",1,3573}, +{"sheqel",1,3574}, +{"sheqelhebrew",1,3575}, +{"sheva",1,3576}, +{"sheva115",1,3577}, +{"sheva15",1,3578}, +{"sheva22",1,3579}, +{"sheva2e",1,3580}, +{"shevahebrew",1,3581}, +{"shevanarrowhebrew",1,3582}, +{"shevaquarterhebrew",1,3583}, +{"shevawidehebrew",1,3584}, +{"shhacyrillic",1,3585}, +{"shimacoptic",1,3586}, +{"shin",1,3587}, +{"shindagesh",1,3588}, +{"shindageshhebrew",1,3589}, +{"shindageshshindot",1,3590}, +{"shindageshshindothebrew",1,3591}, +{"shindageshsindot",1,3592}, +{"shindageshsindothebrew",1,3593}, +{"shindothebrew",1,3594}, +{"shinhebrew",1,3595}, +{"shinshindot",1,3596}, +{"shinshindothebrew",1,3597}, +{"shinsindot",1,3598}, +{"shinsindothebrew",1,3599}, +{"shook",1,3600}, +{"sigma",1,3601}, +{"sigma1",1,3602}, +{"sigmafinal",1,3603}, +{"sigmalunatesymbolgreek",1,3604}, +{"sihiragana",1,3605}, +{"sikatakana",1,3606}, +{"sikatakanahalfwidth",1,3607}, +{"siluqhebrew",1,3608}, +{"siluqlefthebrew",1,3609}, +{"similar",1,3610}, +{"sindothebrew",1,3611}, +{"siosacirclekorean",1,3612}, +{"siosaparenkorean",1,3613}, +{"sioscieuckorean",1,3614}, +{"sioscirclekorean",1,3615}, +{"sioskiyeokkorean",1,3616}, +{"sioskorean",1,3617}, +{"siosnieunkorean",1,3618}, +{"siosparenkorean",1,3619}, +{"siospieupkorean",1,3620}, +{"siostikeutkorean",1,3621}, +{"six",1,3622}, +{"sixarabic",1,3623}, +{"sixbengali",1,3624}, +{"sixcircle",1,3625}, +{"sixcircleinversesansserif",1,3626}, +{"sixdeva",1,3627}, +{"sixgujarati",1,3628}, +{"sixgurmukhi",1,3629}, +{"sixhackarabic",1,3630}, +{"sixhangzhou",1,3631}, +{"sixideographicparen",1,3632}, +{"sixinferior",1,3633}, +{"sixmonospace",1,3634}, +{"sixoldstyle",1,3635}, +{"sixparen",1,3636}, +{"sixperiod",1,3637}, +{"sixpersian",1,3638}, +{"sixroman",1,3639}, +{"sixsuperior",1,3640}, +{"sixteencircle",1,3641}, +{"sixteencurrencydenominatorbengali",1,3642}, +{"sixteenparen",1,3643}, +{"sixteenperiod",1,3644}, +{"sixthai",1,3645}, +{"slash",1,3646}, +{"slashmonospace",1,3647}, +{"slong",1,3648}, +{"slongdotaccent",1,3649}, +{"smileface",1,3650}, +{"smonospace",1,3651}, +{"sofpasuqhebrew",1,3652}, +{"softhyphen",1,3653}, +{"softsigncyrillic",1,3654}, +{"sohiragana",1,3655}, +{"sokatakana",1,3656}, +{"sokatakanahalfwidth",1,3657}, +{"soliduslongoverlaycmb",1,3658}, +{"solidusshortoverlaycmb",1,3659}, +{"sorusithai",1,3660}, +{"sosalathai",1,3661}, +{"sosothai",1,3662}, +{"sosuathai",1,3663}, +{"space",1,3664}, +{"spacehackarabic",1,3665}, +{"spade",1,3666}, +{"spadesuitblack",1,3667}, +{"spadesuitwhite",1,3668}, +{"sparen",1,3669}, +{"squarebelowcmb",1,3670}, +{"squarecc",1,3671}, +{"squarecm",1,3672}, +{"squarediagonalcrosshatchfill",1,3673}, +{"squarehorizontalfill",1,3674}, +{"squarekg",1,3675}, +{"squarekm",1,3676}, +{"squarekmcapital",1,3677}, +{"squareln",1,3678}, +{"squarelog",1,3679}, +{"squaremg",1,3680}, +{"squaremil",1,3681}, +{"squaremm",1,3682}, +{"squaremsquared",1,3683}, +{"squareorthogonalcrosshatchfill",1,3684}, +{"squareupperlefttolowerrightfill",1,3685}, +{"squareupperrighttolowerleftfill",1,3686}, +{"squareverticalfill",1,3687}, +{"squarewhitewithsmallblack",1,3688}, +{"srsquare",1,3689}, +{"ssabengali",1,3690}, +{"ssadeva",1,3691}, +{"ssagujarati",1,3692}, +{"ssangcieuckorean",1,3693}, +{"ssanghieuhkorean",1,3694}, +{"ssangieungkorean",1,3695}, +{"ssangkiyeokkorean",1,3696}, +{"ssangnieunkorean",1,3697}, +{"ssangpieupkorean",1,3698}, +{"ssangsioskorean",1,3699}, +{"ssangtikeutkorean",1,3700}, +{"ssuperior",1,3701}, +{"sterling",1,3702}, +{"sterlingmonospace",1,3703}, +{"strokelongoverlaycmb",1,3704}, +{"strokeshortoverlaycmb",1,3705}, +{"subset",1,3706}, +{"subsetnotequal",1,3707}, +{"subsetorequal",1,3708}, +{"succeeds",1,3709}, +{"suchthat",1,3710}, +{"suhiragana",1,3711}, +{"sukatakana",1,3712}, +{"sukatakanahalfwidth",1,3713}, +{"sukunarabic",1,3714}, +{"summation",1,3715}, +{"sun",1,3716}, +{"superset",1,3717}, +{"supersetnotequal",1,3718}, +{"supersetorequal",1,3719}, +{"svsquare",1,3720}, +{"syouwaerasquare",1,3721}, +{"t",1,3722}, +{"tabengali",1,3723}, +{"tackdown",1,3724}, +{"tackleft",1,3725}, +{"tadeva",1,3726}, +{"tagujarati",1,3727}, +{"tagurmukhi",1,3728}, +{"taharabic",1,3729}, +{"tahfinalarabic",1,3730}, +{"tahinitialarabic",1,3731}, +{"tahiragana",1,3732}, +{"tahmedialarabic",1,3733}, +{"taisyouerasquare",1,3734}, +{"takatakana",1,3735}, +{"takatakanahalfwidth",1,3736}, +{"tatweelarabic",1,3737}, +{"tau",1,3738}, +{"tav",1,3739}, +{"tavdages",1,3740}, +{"tavdagesh",1,3741}, +{"tavdageshhebrew",1,3742}, +{"tavhebrew",1,3743}, +{"tbar",1,3744}, +{"tbopomofo",1,3745}, +{"tcaron",1,3746}, +{"tccurl",1,3747}, +{"tcedilla",1,3748}, +{"tcheharabic",1,3749}, +{"tchehfinalarabic",1,3750}, +{"tchehinitialarabic",1,3751}, +{"tchehmedialarabic",1,3752}, +{"tchehmeeminitialarabic",2,3753}, +{"tcircle",1,3755}, +{"tcircumflexbelow",1,3756}, +{"tcommaaccent",1,3757}, +{"tdieresis",1,3758}, +{"tdotaccent",1,3759}, +{"tdotbelow",1,3760}, +{"tecyrillic",1,3761}, +{"tedescendercyrillic",1,3762}, +{"teharabic",1,3763}, +{"tehfinalarabic",1,3764}, +{"tehhahinitialarabic",1,3765}, +{"tehhahisolatedarabic",1,3766}, +{"tehinitialarabic",1,3767}, +{"tehiragana",1,3768}, +{"tehjeeminitialarabic",1,3769}, +{"tehjeemisolatedarabic",1,3770}, +{"tehmarbutaarabic",1,3771}, +{"tehmarbutafinalarabic",1,3772}, +{"tehmedialarabic",1,3773}, +{"tehmeeminitialarabic",1,3774}, +{"tehmeemisolatedarabic",1,3775}, +{"tehnoonfinalarabic",1,3776}, +{"tekatakana",1,3777}, +{"tekatakanahalfwidth",1,3778}, +{"telephone",1,3779}, +{"telephoneblack",1,3780}, +{"telishagedolahebrew",1,3781}, +{"telishaqetanahebrew",1,3782}, +{"tencircle",1,3783}, +{"tenideographicparen",1,3784}, +{"tenparen",1,3785}, +{"tenperiod",1,3786}, +{"tenroman",1,3787}, +{"tesh",1,3788}, +{"tet",1,3789}, +{"tetdagesh",1,3790}, +{"tetdageshhebrew",1,3791}, +{"tethebrew",1,3792}, +{"tetsecyrillic",1,3793}, +{"tevirhebrew",1,3794}, +{"tevirlefthebrew",1,3795}, +{"thabengali",1,3796}, +{"thadeva",1,3797}, +{"thagujarati",1,3798}, +{"thagurmukhi",1,3799}, +{"thalarabic",1,3800}, +{"thalfinalarabic",1,3801}, +{"thanthakhatlowleftthai",1,3802}, +{"thanthakhatlowrightthai",1,3803}, +{"thanthakhatthai",1,3804}, +{"thanthakhatupperleftthai",1,3805}, +{"theharabic",1,3806}, +{"thehfinalarabic",1,3807}, +{"thehinitialarabic",1,3808}, +{"thehmedialarabic",1,3809}, +{"thereexists",1,3810}, +{"therefore",1,3811}, +{"theta",1,3812}, +{"theta1",1,3813}, +{"thetasymbolgreek",1,3814}, +{"thieuthacirclekorean",1,3815}, +{"thieuthaparenkorean",1,3816}, +{"thieuthcirclekorean",1,3817}, +{"thieuthkorean",1,3818}, +{"thieuthparenkorean",1,3819}, +{"thirteencircle",1,3820}, +{"thirteenparen",1,3821}, +{"thirteenperiod",1,3822}, +{"thonangmonthothai",1,3823}, +{"thook",1,3824}, +{"thophuthaothai",1,3825}, +{"thorn",1,3826}, +{"thothahanthai",1,3827}, +{"thothanthai",1,3828}, +{"thothongthai",1,3829}, +{"thothungthai",1,3830}, +{"thousandcyrillic",1,3831}, +{"thousandsseparatorarabic",1,3832}, +{"thousandsseparatorpersian",1,3833}, +{"three",1,3834}, +{"threearabic",1,3835}, +{"threebengali",1,3836}, +{"threecircle",1,3837}, +{"threecircleinversesansserif",1,3838}, +{"threedeva",1,3839}, +{"threeeighths",1,3840}, +{"threegujarati",1,3841}, +{"threegurmukhi",1,3842}, +{"threehackarabic",1,3843}, +{"threehangzhou",1,3844}, +{"threeideographicparen",1,3845}, +{"threeinferior",1,3846}, +{"threemonospace",1,3847}, +{"threenumeratorbengali",1,3848}, +{"threeoldstyle",1,3849}, +{"threeparen",1,3850}, +{"threeperiod",1,3851}, +{"threepersian",1,3852}, +{"threequarters",1,3853}, +{"threequartersemdash",1,3854}, +{"threeroman",1,3855}, +{"threesuperior",1,3856}, +{"threethai",1,3857}, +{"thzsquare",1,3858}, +{"tihiragana",1,3859}, +{"tikatakana",1,3860}, +{"tikatakanahalfwidth",1,3861}, +{"tikeutacirclekorean",1,3862}, +{"tikeutaparenkorean",1,3863}, +{"tikeutcirclekorean",1,3864}, +{"tikeutkorean",1,3865}, +{"tikeutparenkorean",1,3866}, +{"tilde",1,3867}, +{"tildebelowcmb",1,3868}, +{"tildecmb",1,3869}, +{"tildecomb",1,3870}, +{"tildedoublecmb",1,3871}, +{"tildeoperator",1,3872}, +{"tildeoverlaycmb",1,3873}, +{"tildeverticalcmb",1,3874}, +{"timescircle",1,3875}, +{"tipehahebrew",1,3876}, +{"tipehalefthebrew",1,3877}, +{"tippigurmukhi",1,3878}, +{"titlocyrilliccmb",1,3879}, +{"tiwnarmenian",1,3880}, +{"tlinebelow",1,3881}, +{"tmonospace",1,3882}, +{"toarmenian",1,3883}, +{"tohiragana",1,3884}, +{"tokatakana",1,3885}, +{"tokatakanahalfwidth",1,3886}, +{"tonebarextrahighmod",1,3887}, +{"tonebarextralowmod",1,3888}, +{"tonebarhighmod",1,3889}, +{"tonebarlowmod",1,3890}, +{"tonebarmidmod",1,3891}, +{"tonefive",1,3892}, +{"tonesix",1,3893}, +{"tonetwo",1,3894}, +{"tonos",1,3895}, +{"tonsquare",1,3896}, +{"topatakthai",1,3897}, +{"tortoiseshellbracketleft",1,3898}, +{"tortoiseshellbracketleftsmall",1,3899}, +{"tortoiseshellbracketleftvertical",1,3900}, +{"tortoiseshellbracketright",1,3901}, +{"tortoiseshellbracketrightsmall",1,3902}, +{"tortoiseshellbracketrightvertical",1,3903}, +{"totaothai",1,3904}, +{"tpalatalhook",1,3905}, +{"tparen",1,3906}, +{"trademark",1,3907}, +{"trademarksans",1,3908}, +{"trademarkserif",1,3909}, +{"tretroflexhook",1,3910}, +{"triagdn",1,3911}, +{"triaglf",1,3912}, +{"triagrt",1,3913}, +{"triagup",1,3914}, +{"ts",1,3915}, +{"tsadi",1,3916}, +{"tsadidagesh",1,3917}, +{"tsadidageshhebrew",1,3918}, +{"tsadihebrew",1,3919}, +{"tsecyrillic",1,3920}, +{"tsere",1,3921}, +{"tsere12",1,3922}, +{"tsere1e",1,3923}, +{"tsere2b",1,3924}, +{"tserehebrew",1,3925}, +{"tserenarrowhebrew",1,3926}, +{"tserequarterhebrew",1,3927}, +{"tserewidehebrew",1,3928}, +{"tshecyrillic",1,3929}, +{"tsuperior",1,3930}, +{"ttabengali",1,3931}, +{"ttadeva",1,3932}, +{"ttagujarati",1,3933}, +{"ttagurmukhi",1,3934}, +{"tteharabic",1,3935}, +{"ttehfinalarabic",1,3936}, +{"ttehinitialarabic",1,3937}, +{"ttehmedialarabic",1,3938}, +{"tthabengali",1,3939}, +{"tthadeva",1,3940}, +{"tthagujarati",1,3941}, +{"tthagurmukhi",1,3942}, +{"tturned",1,3943}, +{"tuhiragana",1,3944}, +{"tukatakana",1,3945}, +{"tukatakanahalfwidth",1,3946}, +{"tusmallhiragana",1,3947}, +{"tusmallkatakana",1,3948}, +{"tusmallkatakanahalfwidth",1,3949}, +{"twelvecircle",1,3950}, +{"twelveparen",1,3951}, +{"twelveperiod",1,3952}, +{"twelveroman",1,3953}, +{"twentycircle",1,3954}, +{"twentyhangzhou",1,3955}, +{"twentyparen",1,3956}, +{"twentyperiod",1,3957}, +{"two",1,3958}, +{"twoarabic",1,3959}, +{"twobengali",1,3960}, +{"twocircle",1,3961}, +{"twocircleinversesansserif",1,3962}, +{"twodeva",1,3963}, +{"twodotenleader",1,3964}, +{"twodotleader",1,3965}, +{"twodotleadervertical",1,3966}, +{"twogujarati",1,3967}, +{"twogurmukhi",1,3968}, +{"twohackarabic",1,3969}, +{"twohangzhou",1,3970}, +{"twoideographicparen",1,3971}, +{"twoinferior",1,3972}, +{"twomonospace",1,3973}, +{"twonumeratorbengali",1,3974}, +{"twooldstyle",1,3975}, +{"twoparen",1,3976}, +{"twoperiod",1,3977}, +{"twopersian",1,3978}, +{"tworoman",1,3979}, +{"twostroke",1,3980}, +{"twosuperior",1,3981}, +{"twothai",1,3982}, +{"twothirds",1,3983}, +{"u",1,3984}, +{"uacute",1,3985}, +{"ubar",1,3986}, +{"ubengali",1,3987}, +{"ubopomofo",1,3988}, +{"ubreve",1,3989}, +{"ucaron",1,3990}, +{"ucircle",1,3991}, +{"ucircumflex",1,3992}, +{"ucircumflexbelow",1,3993}, +{"ucyrillic",1,3994}, +{"udattadeva",1,3995}, +{"udblacute",1,3996}, +{"udblgrave",1,3997}, +{"udeva",1,3998}, +{"udieresis",1,3999}, +{"udieresisacute",1,4000}, +{"udieresisbelow",1,4001}, +{"udieresiscaron",1,4002}, +{"udieresiscyrillic",1,4003}, +{"udieresisgrave",1,4004}, +{"udieresismacron",1,4005}, +{"udotbelow",1,4006}, +{"ugrave",1,4007}, +{"ugujarati",1,4008}, +{"ugurmukhi",1,4009}, +{"uhiragana",1,4010}, +{"uhookabove",1,4011}, +{"uhorn",1,4012}, +{"uhornacute",1,4013}, +{"uhorndotbelow",1,4014}, +{"uhorngrave",1,4015}, +{"uhornhookabove",1,4016}, +{"uhorntilde",1,4017}, +{"uhungarumlaut",1,4018}, +{"uhungarumlautcyrillic",1,4019}, +{"uinvertedbreve",1,4020}, +{"ukatakana",1,4021}, +{"ukatakanahalfwidth",1,4022}, +{"ukcyrillic",1,4023}, +{"ukorean",1,4024}, +{"umacron",1,4025}, +{"umacroncyrillic",1,4026}, +{"umacrondieresis",1,4027}, +{"umatragurmukhi",1,4028}, +{"umonospace",1,4029}, +{"underscore",1,4030}, +{"underscoredbl",1,4031}, +{"underscoremonospace",1,4032}, +{"underscorevertical",1,4033}, +{"underscorewavy",1,4034}, +{"union",1,4035}, +{"universal",1,4036}, +{"uogonek",1,4037}, +{"uparen",1,4038}, +{"upblock",1,4039}, +{"upperdothebrew",1,4040}, +{"upsilon",1,4041}, +{"upsilondieresis",1,4042}, +{"upsilondieresistonos",1,4043}, +{"upsilonlatin",1,4044}, +{"upsilontonos",1,4045}, +{"uptackbelowcmb",1,4046}, +{"uptackmod",1,4047}, +{"uragurmukhi",1,4048}, +{"uring",1,4049}, +{"ushortcyrillic",1,4050}, +{"usmallhiragana",1,4051}, +{"usmallkatakana",1,4052}, +{"usmallkatakanahalfwidth",1,4053}, +{"ustraightcyrillic",1,4054}, +{"ustraightstrokecyrillic",1,4055}, +{"utilde",1,4056}, +{"utildeacute",1,4057}, +{"utildebelow",1,4058}, +{"uubengali",1,4059}, +{"uudeva",1,4060}, +{"uugujarati",1,4061}, +{"uugurmukhi",1,4062}, +{"uumatragurmukhi",1,4063}, +{"uuvowelsignbengali",1,4064}, +{"uuvowelsigndeva",1,4065}, +{"uuvowelsigngujarati",1,4066}, +{"uvowelsignbengali",1,4067}, +{"uvowelsigndeva",1,4068}, +{"uvowelsigngujarati",1,4069}, +{"v",1,4070}, +{"vadeva",1,4071}, +{"vagujarati",1,4072}, +{"vagurmukhi",1,4073}, +{"vakatakana",1,4074}, +{"vav",1,4075}, +{"vavdagesh",1,4076}, +{"vavdagesh65",1,4077}, +{"vavdageshhebrew",1,4078}, +{"vavhebrew",1,4079}, +{"vavholam",1,4080}, +{"vavholamhebrew",1,4081}, +{"vavvavhebrew",1,4082}, +{"vavyodhebrew",1,4083}, +{"vcircle",1,4084}, +{"vdotbelow",1,4085}, +{"vecyrillic",1,4086}, +{"veharabic",1,4087}, +{"vehfinalarabic",1,4088}, +{"vehinitialarabic",1,4089}, +{"vehmedialarabic",1,4090}, +{"vekatakana",1,4091}, +{"venus",1,4092}, +{"verticalbar",1,4093}, +{"verticallineabovecmb",1,4094}, +{"verticallinebelowcmb",1,4095}, +{"verticallinelowmod",1,4096}, +{"verticallinemod",1,4097}, +{"vewarmenian",1,4098}, +{"vhook",1,4099}, +{"vikatakana",1,4100}, +{"viramabengali",1,4101}, +{"viramadeva",1,4102}, +{"viramagujarati",1,4103}, +{"visargabengali",1,4104}, +{"visargadeva",1,4105}, +{"visargagujarati",1,4106}, +{"vmonospace",1,4107}, +{"voarmenian",1,4108}, +{"voicediterationhiragana",1,4109}, +{"voicediterationkatakana",1,4110}, +{"voicedmarkkana",1,4111}, +{"voicedmarkkanahalfwidth",1,4112}, +{"vokatakana",1,4113}, +{"vparen",1,4114}, +{"vtilde",1,4115}, +{"vturned",1,4116}, +{"vuhiragana",1,4117}, +{"vukatakana",1,4118}, +{"w",1,4119}, +{"wacute",1,4120}, +{"waekorean",1,4121}, +{"wahiragana",1,4122}, +{"wakatakana",1,4123}, +{"wakatakanahalfwidth",1,4124}, +{"wakorean",1,4125}, +{"wasmallhiragana",1,4126}, +{"wasmallkatakana",1,4127}, +{"wattosquare",1,4128}, +{"wavedash",1,4129}, +{"wavyunderscorevertical",1,4130}, +{"wawarabic",1,4131}, +{"wawfinalarabic",1,4132}, +{"wawhamzaabovearabic",1,4133}, +{"wawhamzaabovefinalarabic",1,4134}, +{"wbsquare",1,4135}, +{"wcircle",1,4136}, +{"wcircumflex",1,4137}, +{"wdieresis",1,4138}, +{"wdotaccent",1,4139}, +{"wdotbelow",1,4140}, +{"wehiragana",1,4141}, +{"weierstrass",1,4142}, +{"wekatakana",1,4143}, +{"wekorean",1,4144}, +{"weokorean",1,4145}, +{"wgrave",1,4146}, +{"whitebullet",1,4147}, +{"whitecircle",1,4148}, +{"whitecircleinverse",1,4149}, +{"whitecornerbracketleft",1,4150}, +{"whitecornerbracketleftvertical",1,4151}, +{"whitecornerbracketright",1,4152}, +{"whitecornerbracketrightvertical",1,4153}, +{"whitediamond",1,4154}, +{"whitediamondcontainingblacksmalldiamond",1,4155}, +{"whitedownpointingsmalltriangle",1,4156}, +{"whitedownpointingtriangle",1,4157}, +{"whiteleftpointingsmalltriangle",1,4158}, +{"whiteleftpointingtriangle",1,4159}, +{"whitelenticularbracketleft",1,4160}, +{"whitelenticularbracketright",1,4161}, +{"whiterightpointingsmalltriangle",1,4162}, +{"whiterightpointingtriangle",1,4163}, +{"whitesmallsquare",1,4164}, +{"whitesmilingface",1,4165}, +{"whitesquare",1,4166}, +{"whitestar",1,4167}, +{"whitetelephone",1,4168}, +{"whitetortoiseshellbracketleft",1,4169}, +{"whitetortoiseshellbracketright",1,4170}, +{"whiteuppointingsmalltriangle",1,4171}, +{"whiteuppointingtriangle",1,4172}, +{"wihiragana",1,4173}, +{"wikatakana",1,4174}, +{"wikorean",1,4175}, +{"wmonospace",1,4176}, +{"wohiragana",1,4177}, +{"wokatakana",1,4178}, +{"wokatakanahalfwidth",1,4179}, +{"won",1,4180}, +{"wonmonospace",1,4181}, +{"wowaenthai",1,4182}, +{"wparen",1,4183}, +{"wring",1,4184}, +{"wsuperior",1,4185}, +{"wturned",1,4186}, +{"wynn",1,4187}, +{"x",1,4188}, +{"xabovecmb",1,4189}, +{"xbopomofo",1,4190}, +{"xcircle",1,4191}, +{"xdieresis",1,4192}, +{"xdotaccent",1,4193}, +{"xeharmenian",1,4194}, +{"xi",1,4195}, +{"xmonospace",1,4196}, +{"xparen",1,4197}, +{"xsuperior",1,4198}, +{"y",1,4199}, +{"yaadosquare",1,4200}, +{"yabengali",1,4201}, +{"yacute",1,4202}, +{"yadeva",1,4203}, +{"yaekorean",1,4204}, +{"yagujarati",1,4205}, +{"yagurmukhi",1,4206}, +{"yahiragana",1,4207}, +{"yakatakana",1,4208}, +{"yakatakanahalfwidth",1,4209}, +{"yakorean",1,4210}, +{"yamakkanthai",1,4211}, +{"yasmallhiragana",1,4212}, +{"yasmallkatakana",1,4213}, +{"yasmallkatakanahalfwidth",1,4214}, +{"yatcyrillic",1,4215}, +{"ycircle",1,4216}, +{"ycircumflex",1,4217}, +{"ydieresis",1,4218}, +{"ydotaccent",1,4219}, +{"ydotbelow",1,4220}, +{"yeharabic",1,4221}, +{"yehbarreearabic",1,4222}, +{"yehbarreefinalarabic",1,4223}, +{"yehfinalarabic",1,4224}, +{"yehhamzaabovearabic",1,4225}, +{"yehhamzaabovefinalarabic",1,4226}, +{"yehhamzaaboveinitialarabic",1,4227}, +{"yehhamzaabovemedialarabic",1,4228}, +{"yehinitialarabic",1,4229}, +{"yehmedialarabic",1,4230}, +{"yehmeeminitialarabic",1,4231}, +{"yehmeemisolatedarabic",1,4232}, +{"yehnoonfinalarabic",1,4233}, +{"yehthreedotsbelowarabic",1,4234}, +{"yekorean",1,4235}, +{"yen",1,4236}, +{"yenmonospace",1,4237}, +{"yeokorean",1,4238}, +{"yeorinhieuhkorean",1,4239}, +{"yerahbenyomohebrew",1,4240}, +{"yerahbenyomolefthebrew",1,4241}, +{"yericyrillic",1,4242}, +{"yerudieresiscyrillic",1,4243}, +{"yesieungkorean",1,4244}, +{"yesieungpansioskorean",1,4245}, +{"yesieungsioskorean",1,4246}, +{"yetivhebrew",1,4247}, +{"ygrave",1,4248}, +{"yhook",1,4249}, +{"yhookabove",1,4250}, +{"yiarmenian",1,4251}, +{"yicyrillic",1,4252}, +{"yikorean",1,4253}, +{"yinyang",1,4254}, +{"yiwnarmenian",1,4255}, +{"ymonospace",1,4256}, +{"yod",1,4257}, +{"yoddagesh",1,4258}, +{"yoddageshhebrew",1,4259}, +{"yodhebrew",1,4260}, +{"yodyodhebrew",1,4261}, +{"yodyodpatahhebrew",1,4262}, +{"yohiragana",1,4263}, +{"yoikorean",1,4264}, +{"yokatakana",1,4265}, +{"yokatakanahalfwidth",1,4266}, +{"yokorean",1,4267}, +{"yosmallhiragana",1,4268}, +{"yosmallkatakana",1,4269}, +{"yosmallkatakanahalfwidth",1,4270}, +{"yotgreek",1,4271}, +{"yoyaekorean",1,4272}, +{"yoyakorean",1,4273}, +{"yoyakthai",1,4274}, +{"yoyingthai",1,4275}, +{"yparen",1,4276}, +{"ypogegrammeni",1,4277}, +{"ypogegrammenigreekcmb",1,4278}, +{"yr",1,4279}, +{"yring",1,4280}, +{"ysuperior",1,4281}, +{"ytilde",1,4282}, +{"yturned",1,4283}, +{"yuhiragana",1,4284}, +{"yuikorean",1,4285}, +{"yukatakana",1,4286}, +{"yukatakanahalfwidth",1,4287}, +{"yukorean",1,4288}, +{"yusbigcyrillic",1,4289}, +{"yusbigiotifiedcyrillic",1,4290}, +{"yuslittlecyrillic",1,4291}, +{"yuslittleiotifiedcyrillic",1,4292}, +{"yusmallhiragana",1,4293}, +{"yusmallkatakana",1,4294}, +{"yusmallkatakanahalfwidth",1,4295}, +{"yuyekorean",1,4296}, +{"yuyeokorean",1,4297}, +{"yyabengali",1,4298}, +{"yyadeva",1,4299}, +{"z",1,4300}, +{"zaarmenian",1,4301}, +{"zacute",1,4302}, +{"zadeva",1,4303}, +{"zagurmukhi",1,4304}, +{"zaharabic",1,4305}, +{"zahfinalarabic",1,4306}, +{"zahinitialarabic",1,4307}, +{"zahiragana",1,4308}, +{"zahmedialarabic",1,4309}, +{"zainarabic",1,4310}, +{"zainfinalarabic",1,4311}, +{"zakatakana",1,4312}, +{"zaqefgadolhebrew",1,4313}, +{"zaqefqatanhebrew",1,4314}, +{"zarqahebrew",1,4315}, +{"zayin",1,4316}, +{"zayindagesh",1,4317}, +{"zayindageshhebrew",1,4318}, +{"zayinhebrew",1,4319}, +{"zbopomofo",1,4320}, +{"zcaron",1,4321}, +{"zcircle",1,4322}, +{"zcircumflex",1,4323}, +{"zcurl",1,4324}, +{"zdot",1,4325}, +{"zdotaccent",1,4326}, +{"zdotbelow",1,4327}, +{"zecyrillic",1,4328}, +{"zedescendercyrillic",1,4329}, +{"zedieresiscyrillic",1,4330}, +{"zehiragana",1,4331}, +{"zekatakana",1,4332}, +{"zero",1,4333}, +{"zeroarabic",1,4334}, +{"zerobengali",1,4335}, +{"zerodeva",1,4336}, +{"zerogujarati",1,4337}, +{"zerogurmukhi",1,4338}, +{"zerohackarabic",1,4339}, +{"zeroinferior",1,4340}, +{"zeromonospace",1,4341}, +{"zerooldstyle",1,4342}, +{"zeropersian",1,4343}, +{"zerosuperior",1,4344}, +{"zerothai",1,4345}, +{"zerowidthjoiner",1,4346}, +{"zerowidthnonjoiner",1,4347}, +{"zerowidthspace",1,4348}, +{"zeta",1,4349}, +{"zhbopomofo",1,4350}, +{"zhearmenian",1,4351}, +{"zhebrevecyrillic",1,4352}, +{"zhecyrillic",1,4353}, +{"zhedescendercyrillic",1,4354}, +{"zhedieresiscyrillic",1,4355}, +{"zihiragana",1,4356}, +{"zikatakana",1,4357}, +{"zinorhebrew",1,4358}, +{"zlinebelow",1,4359}, +{"zmonospace",1,4360}, +{"zohiragana",1,4361}, +{"zokatakana",1,4362}, +{"zparen",1,4363}, +{"zretroflexhook",1,4364}, +{"zstroke",1,4365}, +{"zuhiragana",1,4366}, +{"zukatakana",1,4367}, +}; + +static const unsigned short agldat[4368] = { +65,198,508,482,63462,193,63457,258,7854,1232,7862,7856,7858,7860,461,9398,194, +7844,7852,7846,7848,63458,7850,63177,63412,1040,512,196,1234,478,63460,7840, +480,192,63456,7842,1236,514,913,902,256,65313,260,197,506,7680,63461,63329, +195,63459,1329,66,9399,7682,7684,1041,1330,914,385,7686,65314,63220,63330,386, +67,1342,262,63178,63221,268,199,7688,63463,9400,264,266,266,63416,1353,1212, +1063,1214,1206,1268,1347,1227,1208,935,391,63222,65315,1361,63331,68,497,452, +1332,393,270,7696,9401,7698,272,7690,7692,1044,1006,8710,916,394,63179,63180, +63181,63400,988,1026,7694,65316,63223,272,63332,395,498,453,1248,1029,1039,69, +201,63465,276,282,7708,1333,9402,202,7870,7704,7878,7872,7874,63466,7876,1028, +516,203,63467,278,278,7864,1060,200,63464,1335,7866,8551,518,1124,1051,8554, +274,7702,7700,1052,65317,1053,1186,330,1188,1223,280,400,917,904,1056,398, +1069,1057,1194,425,63333,919,1336,905,208,63472,7868,7706,8364,439,494,440,70, +9403,7710,1366,996,401,1138,8548,65318,8547,63334,71,13191,500,915,404,1002, +286,486,290,9404,284,290,288,288,1043,1346,1172,1170,1168,403,1331,1027,7712, +65319,63182,63328,63335,667,484,72,9679,9642,9643,9633,13259,1192,1202,1066, +294,7722,7720,9405,292,7718,7714,7716,65320,1344,1000,63336,63183,63224,13200, +73,1071,306,1070,205,63469,300,463,9406,206,63470,1030,520,207,7726,1252, +63471,304,304,7882,1238,1045,8465,204,63468,7880,1048,522,1049,298,1250,65321, +1339,1025,302,921,406,938,906,63337,407,296,7724,1140,1142,74,1345,9407,308, +1032,1355,65322,63338,75,13189,13261,1184,7728,1050,1178,1219,922,1182,1180, +488,310,9408,310,7730,1364,1343,1061,998,408,1036,7732,65323,1152,990,1134, +63339,76,455,63167,313,923,317,315,9409,7740,315,319,319,7734,7736,1340,456, +1033,7738,65324,321,63225,63340,77,13190,63184,63407,7742,9410,7744,7746,1348, +65325,63341,412,924,78,458,323,327,325,9411,7754,325,7748,7750,413,8552,459, +1034,7752,65326,1350,63342,209,63473,925,79,338,63226,211,63475,1256,1258,334, +465,415,9412,212,7888,7896,7890,7892,63476,7894,1054,336,524,214,1254,63478, +7884,63227,210,63474,1365,8486,7886,416,7898,7906,7900,7902,7904,336,418,526, +332,7762,7760,8486,1120,937,1146,1148,911,927,908,65327,8544,490,492,390,216, +510,63480,63343,510,1150,213,7756,7758,63477,80,7764,9413,7766,1055,1354,1190, +934,420,928,1363,65328,936,1136,63344,81,9414,65329,63345,82,1356,340,344,342, +9415,342,528,7768,7770,7772,1360,8476,929,63228,530,7774,65330,63346,641,694, +83,9484,9492,9488,9496,9532,9516,9524,9500,9508,9472,9474,9569,9570,9558,9557, +9571,9553,9559,9565,9564,9563,9566,9567,9562,9556,9577,9574,9568,9552,9580, +9575,9576,9572,9573,9561,9560,9554,9555,9579,9578,346,7780,992,352,7782,63229, +350,399,1240,1242,9416,348,536,7776,7778,7784,1357,8550,1351,1064,1065,994, +1210,1004,931,8549,65331,1068,63347,986,84,932,358,356,354,9417,7792,354,7786, +7788,1058,1196,8553,1204,920,428,222,63486,8546,63230,1359,7790,65332,1337, +444,388,423,430,1062,1035,63348,8555,8545,85,218,63482,364,467,9418,219,7798, +63483,1059,368,532,220,471,7794,473,1264,475,469,63484,7908,217,63481,7910, +431,7912,7920,7914,7916,7918,368,1266,534,1144,362,1262,7802,65333,370,933, +978,979,433,939,980,978,910,366,1038,63349,1198,1200,360,7800,7796,86,9419, +7806,1042,1358,434,65334,1352,63350,7804,87,7810,9420,372,7812,7814,7816,7808, +65335,63351,88,9421,7820,7818,1341,926,65336,63352,89,221,63485,1122,9422,374, +376,63487,7822,7924,1067,1272,7922,435,7926,1349,1031,1362,65337,63353,7928, +1130,1132,1126,1128,90,1334,377,381,63231,9423,7824,379,379,7826,1047,1176, +1246,918,1338,1217,1046,1174,1244,7828,65338,63354,437,97,2438,225,2310,2694, +2566,2622,13059,2494,2366,2750,1375,2416,2437,12570,259,7855,1233,7863,7857, +7859,7861,462,9424,226,7845,7853,7847,7849,7851,180,791,769,769,2388,719,833, +1072,513,2673,2309,228,1235,479,7841,481,230,509,12624,483,8213,8356,1040, +1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054, +1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069, +1070,1071,1168,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1038, +63172,63173,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083, +1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098, +1099,1100,1101,1102,1103,1169,1106,1107,1108,1109,1110,1111,1112,1113,1114, +1115,1116,1118,1039,1122,1138,1140,63174,1119,1123,1139,1141,63175,63176,1241, +8206,8207,8205,1642,1548,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641, +1563,1567,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581, +1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1600,1601, +1602,1603,1604,1605,1606,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617, +1618,1607,1700,1662,1670,1688,1711,1657,1672,1681,1722,1746,1749,8362,1470, +1475,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501, +1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,64298,64299, +64331,64287,1520,1521,1522,64309,1460,1461,1462,1467,1464,1463,1456,1458,1457, +1459,1474,1473,1465,1468,1469,1471,1472,700,8453,8467,8470,8236,8237,8238, +8204,1645,701,224,2693,2565,12354,7843,2448,12574,2320,1237,2704,2576,2632, +1593,65226,65227,65228,515,2504,2376,2760,12450,65393,12623,1488,1575,64304, +65166,1571,65156,1573,65160,1488,64335,1570,65154,1609,65264,65267,65268, +64302,64303,8501,8780,945,940,257,65345,38,65286,63270,13250,12578,12580,3674, +8736,12296,65087,12297,65088,9001,9002,8491,903,2386,2434,2306,2690,261,13056, +9372,1370,700,63743,8784,8776,8786,8773,12686,12685,8978,7834,229,507,7681, +8596,8675,8672,8674,8673,8660,8659,8656,8658,8657,8595,8601,8600,8681,709,706, +707,708,63719,8592,8656,8653,8646,8678,8594,8655,10142,8644,8680,8676,8677, +8593,8597,8616,8616,8598,8645,8599,8679,63718,94,65342,126,65374,593,594, +12353,12449,65383,42,1645,1645,8727,65290,65121,8258,63209,8771,64,227,65312, +65131,592,2452,12576,2324,2708,2580,2519,2636,2508,2380,2764,2365,1377,1506, +64288,1506,98,2476,92,65340,2348,2732,2604,12400,3647,12496,124,65372,12549, +9425,7683,7685,9836,8757,1073,1576,65168,65169,12409,65170,64671,64520,64621, +12505,1378,1489,946,976,64305,64305,1489,64332,2477,2349,2733,2605,595,12403, +12499,664,2562,13105,9679,9670,9660,9668,9664,12304,65083,12305,65084,9699, +9698,9644,9658,9654,9642,9787,9632,9733,9700,9701,9652,9650,9251,7687,9608, +65346,3610,12412,12508,9373,13251,63732,123,63731,63730,65371,65115,63729, +65079,125,63742,63741,65373,65116,63740,65080,91,63728,63727,65339,63726,93, +63739,63738,65341,63737,728,814,774,815,785,865,810,826,166,384,63210,387, +12406,12502,8226,9688,8729,9678,99,1390,2458,263,2330,2714,2586,13192,2433, +784,2305,2689,8682,8453,711,812,780,8629,12568,269,231,7689,9426,265,597,267, +267,13253,184,807,162,8451,63199,65504,63394,63200,1401,2459,2331,2715,2587, +12564,1213,10003,1095,1215,1207,1269,1395,1228,1209,967,12919,12823,12905, +12618,12809,3594,3592,3593,3596,392,12918,12822,12904,12616,12808,12828,9675, +8855,8857,8853,12342,9680,9681,710,813,770,8999,450,448,449,451,9827,9827, +9831,13220,65347,13216,1409,58,8353,65306,8353,65109,721,720,44,787,789,63171, +1548,1373,63201,65292,788,701,65104,63202,786,699,9788,8773,8750,8963,6,7,8, +24,13,17,18,19,20,127,16,25,5,4,27,23,3,12,28,29,9,10,21,30,15,14,2,1,26,22, +31,11,169,63721,63193,12300,65378,65089,12301,65379,65090,13183,13255,13254, +9374,8354,663,8911,8910,164,63185,63186,63188,63189,100,1380,2470,1590,2342, +65214,65215,65216,1468,1468,8224,8225,2726,2598,12384,12480,1583,1491,64307, +64307,1491,1458,1491,1458,1491,1457,1491,1457,1491,1491,1460,1491,1460,1491, +1465,1491,1465,1491,1463,1491,1463,1491,1464,1491,1464,1491,1467,1491,1467, +1491,1462,1491,1462,1491,1456,1491,1456,1491,1461,1491,1461,65194,1615,1615, +1612,1612,2404,1447,1447,1157,63187,12298,65085,12299,65086,811,8660,8658, +2405,63190,783,8748,8215,819,831,698,8214,782,12553,13256,271,7697,9427,7699, +273,2465,2337,2721,2593,1672,64393,2396,2466,2338,2722,2594,7691,7693,1643, +1643,1076,176,1453,12391,1007,12487,9003,8998,948,397,2552,676,2471,2343,2727, +2599,599,901,836,9830,9826,168,63191,804,776,63192,901,12386,12482,12291,247, +8739,8725,1106,9619,7695,13207,273,65348,9604,3598,3604,12393,12489,36,63203, +65284,63268,65129,63204,8363,13094,729,775,803,803,12539,305,63166,644,8901, +9676,64287,64287,798,725,9375,63211,598,396,12389,12485,499,675,454,677,1249, +1109,1119,101,233,9793,2447,12572,277,2317,2701,2373,2757,283,7709,1381,1415, +9428,234,7871,7705,7879,7873,7875,7877,1108,517,2319,235,279,279,7865,2575, +2631,1092,232,2703,1383,12573,12360,7867,12575,56,1640,2542,9319,10129,2414, +9329,9349,9369,2798,2670,1640,12328,9835,12839,8328,65304,63288,9339,9359, +1784,8567,8312,3672,519,1125,12456,65396,2676,12628,1083,8712,9322,9342,9362, +8570,8230,8942,275,7703,7701,1084,8212,65073,65349,1371,8709,12579,1085,8211, +65074,1187,331,12581,1189,1224,8194,281,12627,603,666,604,606,605,9376,949, +941,61,65309,65126,8316,8801,12582,1088,600,1101,1089,1195,643,646,2318,2374, +426,645,12359,12455,65386,8494,63212,951,1384,942,240,7869,7707,1425,1425, +1425,1425,477,12641,8364,2503,2375,2759,33,1372,8252,161,63393,65281,63265, +8707,658,495,659,441,442,102,2398,2654,8457,1614,1614,1611,12552,9429,7711, +1601,1414,65234,65235,65236,997,9792,64256,64259,64260,64257,9326,9346,9366, +8210,9632,9644,1498,64314,64314,1498,1498,1464,1498,1464,1498,1456,1498,1456, +1501,1501,1503,1503,1507,1507,1509,1509,713,9673,1139,53,1637,2539,9316,10126, +2411,8541,2795,2667,1637,12325,12836,8325,65301,63285,9336,9356,1781,8564, +8309,3669,64258,402,65350,13209,3615,3613,3663,8704,52,1636,2538,9315,10125, +2410,2794,2666,1636,12324,12835,8324,65300,2551,63284,9335,9355,1780,8563, +8308,9325,9345,9365,3668,715,9377,8260,8355,103,2455,501,2327,1711,64403, +64404,64405,2711,2583,12364,12460,947,611,736,1003,12557,287,487,291,9430,285, +291,289,289,1075,12370,12466,8785,1436,1523,1437,223,1438,1524,12307,2456, +1394,2328,2712,2584,1594,65230,65231,65232,1173,1171,1169,2394,2650,608,13203, +12366,12462,1379,1490,64306,64306,1490,1107,446,660,662,704,661,705,740,673, +674,7713,65351,12372,12468,9378,13228,8711,96,790,768,768,2387,718,65344,832, +62,8805,8923,65310,8819,8823,8807,65125,609,485,12368,171,187,8249,8250,12464, +13080,13257,104,1193,1729,2489,1203,2361,2745,2617,1581,65186,65187,12399, +65188,13098,12495,65418,2637,1569,1569,1615,1569,1612,1569,1614,1569,1611, +1569,1569,1616,1569,1613,1569,1618,12644,1098,8636,8640,13258,1458,1458,1458, +1458,1458,1458,1458,1458,1459,1459,1459,1459,1459,1459,1459,1459,1457,1457, +1457,1457,1457,1457,1457,1457,295,12559,7723,7721,9431,293,7719,7715,7717, +1492,9829,9829,9825,64308,64308,1729,1607,1492,64423,65258,65258,64421,64420, +64424,65259,12408,64425,65260,13179,12504,65421,13110,615,13113,1495,1495,614, +689,12923,12827,12909,12622,12813,12402,12498,65419,1460,1460,1460,1460,1460, +1460,1460,1460,7830,65352,1392,3627,12411,12507,65422,1465,1465,1465,1465, +1465,1465,1465,1465,3630,777,777,801,802,13122,1001,8213,795,9832,8962,9379, +688,613,12405,13107,12501,65420,733,779,405,45,63205,65293,65123,63206,8208, +105,237,1103,2439,12583,301,464,9432,238,1110,521,12943,12939,12863,12858, +12965,12294,12289,65380,12855,12963,12847,12861,12957,12864,12950,12854,12843, +12850,12964,12293,12952,12856,12967,12966,12969,12846,12842,12852,12290,12958, +12867,12857,12862,12968,12953,12866,12851,12288,12853,12849,12859,12848,12860, +12844,12845,12295,12942,12938,12948,12944,12940,12941,2311,239,7727,1253,7883, +1239,1077,12917,12821,12903,12615,12807,236,2695,2567,12356,7881,2440,1080, +2312,2696,2568,2624,523,1081,2496,2368,2752,307,12452,65394,12643,732,1452, +299,1251,8787,2623,65353,8710,8734,1387,8747,8993,8993,63733,8992,8992,8745, +13061,9688,9689,9787,1105,303,953,970,912,617,943,9380,2674,12355,12451,65384, +2554,616,63213,12445,12541,297,7725,12585,1102,2495,2367,2751,1141,1143,106, +1393,2460,2332,2716,2588,12560,496,9433,309,669,607,1112,1580,65182,65183, +65184,1688,64395,2461,2333,2717,2589,1403,12292,65354,9381,690,107,1185,2453, +7729,1082,1179,2325,1499,1603,64315,64315,65242,1499,65243,65244,64333,2709, +2581,12363,1220,12459,65398,954,1008,12657,12676,12664,12665,13069,1600,1600, +12533,13188,1616,1613,1183,65392,1181,12558,13193,489,311,9434,311,7731,1412, +12369,12465,65401,1391,12534,312,2454,1093,2326,2710,2582,1582,65190,65191, +65192,999,2393,2649,12920,12824,12906,12619,12810,3586,3589,3587,3588,3675, +409,3590,13201,12365,12461,65399,13077,13078,13076,12910,12814,12896,12593, +12800,12595,1116,7733,13208,13222,65355,13218,12371,13248,3585,12467,65402, +13086,1153,12927,835,9382,13226,1135,13263,670,12367,12463,65400,13240,13246, +108,2482,314,2354,2738,2610,3653,65276,65272,65271,65274,65273,65275,65270, +65269,1604,955,411,1500,64316,64316,1500,1500,1465,1500,1465,1468,1500,1465, +1468,1500,1465,65246,64714,65247,64713,64715,65010,65248,64904,64716,65247, +65252,65184,65247,65252,65192,9711,410,620,12556,318,316,9435,7741,316,320, +320,7735,7737,794,792,60,8804,8922,65308,8818,8822,8806,65124,622,9612,621, +8356,1388,457,1113,63168,2355,2739,7739,2356,2529,2401,2531,2403,619,65356, +13264,3628,8743,172,8976,8744,3621,383,65102,818,65101,9674,9383,322,8467, +63214,9617,3622,2444,2316,2530,2402,13267,109,2478,175,817,772,717,65507,7743, +2350,2734,2606,1444,1444,12414,63637,63636,3659,63635,63628,63627,3656,63626, +63620,3633,63625,3655,63631,63630,3657,63629,63634,63633,3658,63632,3654, +12510,65423,9794,13127,1470,9794,1455,13187,12551,13268,9436,13221,7745,7747, +1605,65250,65251,65252,64721,64584,13133,12417,13182,12513,65426,1502,64318, +64318,1502,1396,1445,1446,1446,1445,625,13202,65381,183,12914,12818,12900, +12609,12656,12804,12654,12655,12415,12511,65424,8722,800,8854,727,8723,8242, +13130,13129,624,13206,13219,65357,13215,12418,13249,12514,65427,13270,3617, +13223,13224,9384,13227,13235,63215,623,181,181,13186,8811,8810,13196,956, +13197,12416,12512,65425,13205,215,13211,1443,1443,9834,9835,9837,9839,13234, +13238,13244,13241,13239,13247,13245,110,2472,8711,324,2344,2728,2600,12394, +12490,65413,329,13185,12555,160,328,326,9437,7755,326,7749,7751,12397,12493, +65416,8362,13195,2457,2329,2713,2585,3591,12435,626,627,12911,12815,12597, +12897,12598,12596,12648,12801,12647,12646,12395,12491,65414,63641,3661,57, +1641,2543,9320,10130,2415,2799,2671,1641,12329,12840,8329,65305,63289,9340, +9360,1785,8568,8313,9330,9350,9370,3673,460,1114,12531,65437,414,7753,65358, +13210,2467,2339,2723,2595,2345,12398,12494,65417,160,3603,3609,1606,65254, +1722,64415,65255,65260,65255,64722,64587,65256,64725,64590,64653,8716,8713, +8713,8800,8815,8817,8825,8802,8814,8816,8742,8832,8836,8833,8837,1398,9385, +13233,8319,241,957,12396,12492,65415,2492,2364,2748,2620,35,65283,65119,884, +885,8470,1504,64320,64320,1504,13237,13243,2462,2334,2718,2590,111,243,3629, +629,1257,1259,2451,12571,335,2321,2705,2377,2761,466,9438,244,7889,7897,7891, +7893,7895,1086,337,525,2323,246,1255,7885,339,12634,731,808,242,2707,1413, +12362,7887,417,7899,7907,7901,7903,7905,337,419,527,12458,65397,12631,1451, +333,7763,7761,2384,969,982,1121,631,1147,1149,974,2768,959,972,65359,49,1633, +2535,9312,10122,2407,8228,8539,63196,2791,2663,1633,189,12321,12832,8321, +65297,2548,63281,9332,9352,1777,188,8560,185,3665,8531,491,493,2579,2635,596, +9386,9702,8997,170,186,8735,2322,2378,248,511,12361,12457,65387,511,63216, +1151,245,7757,7759,12577,8254,65098,773,65097,65100,65099,175,2507,2379,2763, +112,13184,13099,2474,7765,2346,8671,8670,2730,2602,12401,3631,12497,1156,1216, +12671,182,8741,40,64830,63725,63724,8333,65288,65113,8317,63723,65077,41, +64831,63736,63735,8334,65289,65114,8318,63734,65078,8706,1472,1433,13225,1463, +1463,1463,1463,1463,1463,1463,1463,1441,12550,9439,7767,1508,1087,64324,64324, +13115,64323,1662,1402,1508,64343,64344,12410,64345,12506,1191,64334,37,1642, +65285,65130,46,1417,183,65377,63207,65294,65106,63208,834,8869,8240,8359, +13194,2475,2347,2731,2603,966,981,12922,12826,12908,12621,12812,632,3642,981, +421,3614,3612,3616,960,12915,12819,12662,12901,12658,12610,12805,12660,12612, +12661,12663,12659,12404,12500,982,1411,43,799,8853,177,726,65291,65122,8314, +65360,13272,12413,9759,9756,9758,9757,12509,3611,12306,12320,9387,8826,8478, +697,8245,8719,8965,12540,8984,8834,8835,8759,8733,968,1137,1158,13232,12407, +12503,13236,13242,113,2392,1448,1602,65238,65239,65240,1464,1464,1464,1464, +1464,1464,1464,1464,1464,1464,1464,1464,1464,1464,1464,1464,1439,12561,9440, +672,65361,1511,64327,64327,1511,1458,1511,1458,1511,1457,1511,1457,1511,1511, +1460,1511,1460,1511,1465,1511,1465,1511,1463,1511,1463,1511,1464,1511,1464, +1511,1467,1511,1467,1511,1462,1511,1462,1511,1456,1511,1456,1511,1461,1511, +1461,9388,9833,1467,1467,1467,1467,1467,1467,1467,1467,63,1567,1374,191,63423, +894,65311,63295,34,8222,8220,65282,12318,12317,8221,8216,8219,8219,8217,329, +8218,39,65287,114,1404,2480,341,2352,8730,63717,13230,13231,13229,1471,1471, +2736,2608,12425,12521,65431,2545,2544,612,8758,12566,345,343,9441,343,529, +7769,7771,7773,8251,8838,8839,174,63720,63194,1585,1408,65198,12428,1585, +65267,65166,1604,12524,65434,1512,64328,1512,1458,1512,1458,1512,1457,1512, +1457,1512,1512,1460,1512,1460,1512,1465,1512,1465,1512,1463,1512,1463,1512, +1464,1512,1464,1512,1467,1512,1467,1512,1462,1512,1462,1512,1456,1512,1456, +1512,1461,1512,1461,8765,1431,1431,8976,638,639,2525,2397,961,637,635,693, +1009,734,12913,12817,12899,12608,12602,12649,12601,12603,12652,12803,12607, +12604,12651,12605,12606,12650,12653,8735,793,8895,12426,12522,65432,730,805, +778,703,1369,796,723,702,825,722,531,13137,7775,636,634,65362,12429,12525, +65435,3619,9389,2524,2353,2652,1681,64397,2528,2400,2784,2500,2372,2756,63217, +9616,633,692,12427,12523,65433,2546,2547,63197,3620,2443,2315,2699,2499,2371, +2755,115,2488,347,7781,1589,2360,65210,65211,65212,2744,2616,12373,12469, +65403,65018,1505,64321,64321,1505,3634,3649,3652,3651,3635,3632,3648,63622, +3637,63621,3636,3650,63624,3639,63623,3638,3640,3641,12569,353,7783,351,601, +1241,1243,602,9442,349,537,7777,7779,7785,828,8243,714,167,1587,65202,65203, +65204,1462,1462,1462,1462,1462,1462,1462,1426,1462,1405,12379,12475,65406,59, +1563,65307,65108,12444,65439,13090,13091,55,1639,2541,9318,10128,2413,8542, +2797,2669,1639,12327,12838,8327,65303,63287,9338,9358,1783,8566,8311,9328, +9348,9368,3671,173,1399,2486,1096,1617,64609,64606,64608,1617,1611,64610, +64607,9618,9619,9617,9618,2358,2742,2614,1427,12565,1097,1588,65206,65207, +65208,995,8362,8362,1456,1456,1456,1456,1456,1456,1456,1456,1456,1211,1005, +1513,64329,64329,64300,64300,64301,64301,1473,1513,64298,64298,64299,64299, +642,963,962,962,1010,12375,12471,65404,1469,1469,8764,1474,12916,12820,12670, +12902,12666,12613,12667,12806,12669,12668,54,1638,2540,9317,10127,2412,2796, +2668,1638,12326,12837,8326,65302,63286,9337,9357,1782,8565,8310,9327,2553, +9347,9367,3670,47,65295,383,7835,9786,65363,1475,173,1100,12381,12477,65407, +824,823,3625,3624,3595,3626,32,32,9824,9824,9828,9390,827,13252,13213,9641, +9636,13199,13214,13262,13265,13266,13198,13269,13212,13217,9638,9639,9640, +9637,9635,13275,2487,2359,2743,12617,12677,12672,12594,12645,12611,12614, +12600,63218,163,65505,822,821,8834,8842,8838,8827,8715,12377,12473,65405,1618, +8721,9788,8835,8843,8839,13276,13180,116,2468,8868,8867,2340,2724,2596,1591, +65218,65219,12383,65220,13181,12479,65408,1600,964,1514,64330,64330,64330, +1514,359,12554,357,680,355,1670,64379,64380,64381,64380,65252,9443,7793,355, +7831,7787,7789,1090,1197,1578,65174,64674,64524,65175,12390,64673,64523,1577, +65172,65176,64676,64526,64627,12486,65411,8481,9742,1440,1449,9321,12841,9341, +9361,8569,679,1496,64312,64312,1496,1205,1435,1435,2469,2341,2725,2597,1584, +65196,63640,63639,3660,63638,1579,65178,65179,65180,8707,8756,952,977,977, +12921,12825,12907,12620,12811,9324,9344,9364,3601,429,3602,254,3607,3600,3608, +3606,1154,1644,1644,51,1635,2537,9314,10124,2409,8540,2793,2665,1635,12323, +12834,8323,65299,2550,63283,9334,9354,1779,190,63198,8562,179,3667,13204, +12385,12481,65409,12912,12816,12898,12599,12802,732,816,771,771,864,8764,820, +830,8855,1430,1430,2672,1155,1407,7791,65364,1385,12392,12488,65412,741,745, +742,744,743,445,389,424,900,13095,3599,12308,65117,65081,12309,65118,65082, +3605,427,9391,8482,63722,63195,648,9660,9668,9658,9650,678,1510,64326,64326, +1510,1094,1461,1461,1461,1461,1461,1461,1461,1461,1115,63219,2463,2335,2719, +2591,1657,64359,64360,64361,2464,2336,2720,2592,647,12388,12484,65410,12387, +12483,65391,9323,9343,9363,8571,9331,21316,9351,9371,50,1634,2536,9313,10123, +2408,8229,8229,65072,2792,2664,1634,12322,12833,8322,65298,2549,63282,9333, +9353,1778,8561,443,178,3666,8532,117,250,649,2441,12584,365,468,9444,251,7799, +1091,2385,369,533,2313,252,472,7795,474,1265,476,470,7909,249,2697,2569,12358, +7911,432,7913,7921,7915,7917,7919,369,1267,535,12454,65395,1145,12636,363, +1263,7803,2625,65365,95,8215,65343,65075,65103,8746,8704,371,9392,9600,1476, +965,971,944,650,973,797,724,2675,367,1118,12357,12453,65385,1199,1201,361, +7801,7797,2442,2314,2698,2570,2626,2498,2370,2754,2497,2369,2753,118,2357, +2741,2613,12535,1493,64309,64309,64309,1493,64331,64331,1520,1521,9445,7807, +1074,1700,64363,64364,64365,12537,9792,124,781,809,716,712,1406,651,12536, +2509,2381,2765,2435,2307,2691,65366,1400,12446,12542,12443,65438,12538,9393, +7805,652,12436,12532,119,7811,12633,12431,12527,65436,12632,12430,12526,13143, +12316,65076,1608,65262,1572,65158,13277,9446,373,7813,7815,7817,12433,8472, +12529,12638,12637,7809,9702,9675,9689,12302,65091,12303,65092,9671,9672,9663, +9661,9667,9665,12310,12311,9657,9655,9643,9786,9633,9734,9743,12312,12313, +9653,9651,12432,12528,12639,65367,12434,12530,65382,8361,65510,3623,9394,7832, +695,653,447,120,829,12562,9447,7821,7819,1389,958,65368,9395,739,121,13134, +2479,253,2351,12626,2735,2607,12420,12516,65428,12625,3662,12419,12515,65388, +1123,9448,375,255,7823,7925,1610,1746,64431,65266,1574,65162,65163,65164, +65267,65268,64733,64600,64660,1745,12630,165,65509,12629,12678,1450,1450,1099, +1273,12673,12675,12674,1434,7923,436,7927,1397,1111,12642,9775,1410,65369, +1497,64313,64313,1497,1522,64287,12424,12681,12520,65430,12635,12423,12519, +65390,1011,12680,12679,3618,3597,9396,890,837,422,7833,696,7929,654,12422, +12684,12518,65429,12640,1131,1133,1127,1129,12421,12517,65389,12683,12682, +2527,2399,122,1382,378,2395,2651,1592,65222,65223,12374,65224,1586,65200, +12470,1429,1428,1432,1494,64310,64310,1494,12567,382,9449,7825,657,380,380, +7827,1079,1177,1247,12380,12476,48,1632,2534,2406,2790,2662,1632,8320,65296, +63280,1776,8304,3664,65279,8204,8203,950,12563,1386,1218,1078,1175,1245,12376, +12472,1454,7829,65370,12382,12478,9397,656,438,12378,12474, +}; + + +#include "fitz.h" +#include "mupdf.h" + +int pdf_lookupagl(char *name, int *ucsbuf, int ucscap) +{ + char buf[256]; + int ucslen = 0; + char *p; + char *s; + int i; + + strlcpy(buf, name, sizeof buf); + + /* kill anything after first period */ + p = strchr(buf, '.'); + if (p) + p[0] = 0; + + /* split into components separated by underscore */ + p = buf; + s = strsep(&p, "_"); + while (s) + { + int l = 0; + int r = nelem(aglidx) - 1; + + while (l <= r) + { + int m = (l + r) >> 1; + int c = strcmp(s, aglidx[m].name); + if (c < 0) + r = m - 1; + else if (c > 0) + l = m + 1; + else + { + for (i = 0; i < aglidx[m].num; i++) + ucsbuf[ucslen++] = agldat[aglidx[m].ofs + i]; + goto next; + } + } + + if (strstr(s, "uni") == s) + { + char tmp[5]; + s += 3; + while (s[0]) + { + strlcpy(tmp, s, 5); + ucsbuf[ucslen++] = strtol(tmp, 0, 16); + s += MIN(strlen(s), 4); + } + } + + else if (strstr(s, "u") == s) + ucsbuf[ucslen++] = strtol(s + 1, 0, 16); + +next: + s = strsep(&p, "_"); + } + + return ucslen; +} + + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_fontenc.c b/rosapps/smartpdf/fitz/mupdf/pdf_fontenc.c new file mode 100644 index 00000000000..d37266759ee --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_fontenc.c @@ -0,0 +1,375 @@ +/* + * Built-in font tables + */ + +#include +#include + +#define _notdef 0 + +void pdf_loadencoding(char **estrings, char *encoding) +{ + char **bstrings = nil; + int i; + + if (!strcmp(encoding, "MacRomanEncoding")) + bstrings = (char**) pdf_macroman; + if (!strcmp(encoding, "MacExpertEncoding")) + bstrings = (char**) pdf_macexpert; + if (!strcmp(encoding, "WinAnsiEncoding")) + bstrings = (char**) pdf_winansi; + + if (bstrings) + for (i = 0; i < 256; i++) + estrings[i] = bstrings[i]; +} + +const unsigned short pdf_docencoding[256] = +{ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, + 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, + 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, + 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, + 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, + 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +const char * const pdf_macroman[256] = { _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, + "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", + "ampersand", "quotesingle", "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", + "grave", "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, + "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", + "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", + "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", + "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", + "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", + "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", + "section", "bullet", "paragraph", "germandbls", "registered", + "copyright", "trademark", "acute", "dieresis", _notdef, "AE", + "Oslash", _notdef, "plusminus", _notdef, _notdef, "yen", "mu", + _notdef, _notdef, _notdef, _notdef, _notdef, "ordfeminine", + "ordmasculine", _notdef, "ae", "oslash", "questiondown", "exclamdown", + "logicalnot", _notdef, "florin", _notdef, _notdef, "guillemotleft", + "guillemotright", "ellipsis", "space", "Agrave", "Atilde", "Otilde", + "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", + "quoteleft", "quoteright", "divide", _notdef, "ydieresis", + "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", + "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", + "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", + "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", + "Oacute", "Ocircumflex", _notdef, "Ograve", "Uacute", "Ucircumflex", + "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", + "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron" }; + +const char * const pdf_macexpert[256] = { _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, + "space", "exclamsmall", "Hungarumlautsmall", "centoldstyle", + "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", + "parenleftsuperior", "parenrightsuperior", "twodotenleader", + "onedotenleader", "comma", "hyphen", "period", "fraction", + "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", + "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", + "eightoldstyle", "nineoldstyle", "colon", "semicolon", _notdef, + "threequartersemdash", _notdef, "questionsmall", _notdef, + _notdef, _notdef, _notdef, "Ethsmall", _notdef, _notdef, + "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", + "fiveeighths", "seveneighths", "onethird", "twothirds", _notdef, + _notdef, _notdef, _notdef, _notdef, _notdef, "ff", "fi", + "fl", "ffi", "ffl", "parenleftinferior", _notdef, "parenrightinferior", + "Circumflexsmall", "hypheninferior", "Gravesmall", "Asmall", "Bsmall", + "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", + "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", + "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", + "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", + "Tildesmall", _notdef, _notdef, "asuperior", "centsuperior", + _notdef, _notdef, _notdef, _notdef, "Aacutesmall", + "Agravesmall", "Acircumflexsmall", "Adieresissmall", "Atildesmall", + "Aringsmall", "Ccedillasmall", "Eacutesmall", "Egravesmall", + "Ecircumflexsmall", "Edieresissmall", "Iacutesmall", "Igravesmall", + "Icircumflexsmall", "Idieresissmall", "Ntildesmall", "Oacutesmall", + "Ogravesmall", "Ocircumflexsmall", "Odieresissmall", "Otildesmall", + "Uacutesmall", "Ugravesmall", "Ucircumflexsmall", "Udieresissmall", + _notdef, "eightsuperior", "fourinferior", "threeinferior", + "sixinferior", "eightinferior", "seveninferior", "Scaronsmall", + _notdef, "centinferior", "twoinferior", _notdef, "Dieresissmall", + _notdef, "Caronsmall", "osuperior", "fiveinferior", _notdef, + "commainferior", "periodinferior", "Yacutesmall", _notdef, + "dollarinferior", _notdef, _notdef, "Thornsmall", _notdef, + "nineinferior", "zeroinferior", "Zcaronsmall", "AEsmall", "Oslashsmall", + "questiondownsmall", "oneinferior", "Lslashsmall", _notdef, + _notdef, _notdef, _notdef, _notdef, _notdef, "Cedillasmall", + _notdef, _notdef, _notdef, _notdef, _notdef, "OEsmall", + "figuredash", "hyphensuperior", _notdef, _notdef, _notdef, + _notdef, "exclamdownsmall", _notdef, "Ydieresissmall", _notdef, + "onesuperior", "twosuperior", "threesuperior", "foursuperior", + "fivesuperior", "sixsuperior", "sevensuperior", "ninesuperior", + "zerosuperior", _notdef, "esuperior", "rsuperior", "tsuperior", + _notdef, _notdef, "isuperior", "ssuperior", "dsuperior", + _notdef, _notdef, _notdef, _notdef, _notdef, "lsuperior", + "Ogoneksmall", "Brevesmall", "Macronsmall", "bsuperior", "nsuperior", + "msuperior", "commasuperior", "periodsuperior", "Dotaccentsmall", + "Ringsmall", _notdef, _notdef, _notdef, _notdef }; + +const char * const pdf_winansi[256] = { _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, "space", + "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", + "quotesingle", "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", "grave", + "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", "bullet", "Euro", + "bullet", "quotesinglbase", "florin", "quotedblbase", "ellipsis", + "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", + "guilsinglleft", "OE", "bullet", "Zcaron", "bullet", "bullet", + "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", + "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", + "oe", "bullet", "zcaron", "Ydieresis", "space", "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" }; + +#if 0 + +const char * const pdf_standard[256] = { _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, + "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, + _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, "exclamdown", "cent", "sterling", + "fraction", "yen", "florin", "section", "currency", "quotesingle", + "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", + "fi", "fl", _notdef, "endash", "dagger", "daggerdbl", "periodcentered", + _notdef, "paragraph", "bullet", "quotesinglbase", "quotedblbase", + "quotedblright", "guillemotright", "ellipsis", "perthousand", + _notdef, "questiondown", _notdef, "grave", "acute", "circumflex", + "tilde", "macron", "breve", "dotaccent", "dieresis", _notdef, + "ring", "cedilla", _notdef, "hungarumlaut", "ogonek", "caron", + "emdash", _notdef, _notdef, _notdef, _notdef, _notdef, + _notdef, _notdef, _notdef, _notdef, _notdef, _notdef, + _notdef, _notdef, _notdef, _notdef, _notdef, "AE", + _notdef, "ordfeminine", _notdef, _notdef, _notdef, _notdef, + "Lslash", "Oslash", "OE", "ordmasculine", _notdef, _notdef, + _notdef, _notdef, _notdef, "ae", _notdef, _notdef, + _notdef, "dotlessi", _notdef, _notdef, "lslash", "oslash", + "oe", "germandbls", _notdef, _notdef, _notdef, _notdef }; + +const char * const pdf_expert[256] = { _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, "space", + "exclamsmall", "Hungarumlautsmall", _notdef, "dollaroldstyle", + "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", + "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", + "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", + "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", + "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", + "colon", "semicolon", "commasuperior", "threequartersemdash", + "periodsuperior", "questionsmall", _notdef, "asuperior", "bsuperior", + "centsuperior", "dsuperior", "esuperior", _notdef, _notdef, + _notdef, "isuperior", _notdef, _notdef, "lsuperior", "msuperior", + "nsuperior", "osuperior", _notdef, _notdef, "rsuperior", + "ssuperior", "tsuperior", _notdef, "ff", "fi", "fl", "ffi", "ffl", + "parenleftinferior", _notdef, "parenrightinferior", "Circumflexsmall", + "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", + "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", + "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", + "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", + "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", + "Tildesmall", _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, "exclamdownsmall", + "centoldstyle", "Lslashsmall", _notdef, _notdef, "Scaronsmall", + "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", _notdef, + "Dotaccentsmall", _notdef, _notdef, "Macronsmall", _notdef, + _notdef, "figuredash", "hypheninferior", _notdef, _notdef, + "Ogoneksmall", "Ringsmall", "Cedillasmall", _notdef, _notdef, + _notdef, "onequarter", "onehalf", "threequarters", "questiondownsmall", + "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", + "twothirds", _notdef, _notdef, "zerosuperior", "onesuperior", + "twosuperior", "threesuperior", "foursuperior", "fivesuperior", + "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", + "zeroinferior", "oneinferior", "twoinferior", "threeinferior", + "fourinferior", "fiveinferior", "sixinferior", "seveninferior", + "eightinferior", "nineinferior", "centinferior", "dollarinferior", + "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", + "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", + "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", + "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", + "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", + "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", + "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", + "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", + "Thornsmall", "Ydieresissmall" }; + +const char * const pdf_symbol[256] = { _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, "space", + "exclam", "universal", "numbersign", "existential", "percent", + "ampersand", "suchthat", "parenleft", "parenright", "asteriskmath", + "plus", "comma", "minus", "period", "slash", "zero", "one", "two", + "three", "four", "five", "six", "seven", "eight", "nine", "colon", + "semicolon", "less", "equal", "greater", "question", "congruent", + "Alpha", "Beta", "Chi", "Delta", "Epsilon", "Phi", "Gamma", "Eta", + "Iota", "theta1", "Kappa", "Lambda", "Mu", "Nu", "Omicron", "Pi", + "Theta", "Rho", "Sigma", "Tau", "Upsilon", "sigma1", "Omega", "Xi", + "Psi", "Zeta", "bracketleft", "therefore", "bracketright", + "perpendicular", "underscore", "radicalex", "alpha", "beta", "chi", + "delta", "epsilon", "phi", "gamma", "eta", "iota", "phi1", "kappa", + "lambda", "mu", "nu", "omicron", "pi", "theta", "rho", "sigma", + "tau", "upsilon", "omega1", "omega", "xi", "psi", "zeta", "braceleft", + "bar", "braceright", "similar", _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, "Upsilon1", "minute", "lessequal", "fraction", "infinity", + "florin", "club", "diamond", "heart", "spade", "arrowboth", + "arrowleft", "arrowup", "arrowright", "arrowdown", "degree", + "plusminus", "second", "greaterequal", "multiply", "proportional", + "partialdiff", "bullet", "divide", "notequal", "equivalence", + "approxequal", "ellipsis", "arrowvertex", "arrowhorizex", + "carriagereturn", "aleph", "Ifraktur", "Rfraktur", "weierstrass", + "circlemultiply", "circleplus", "emptyset", "intersection", "union", + "propersuperset", "reflexsuperset", "notsubset", "propersubset", + "reflexsubset", "element", "notelement", "angle", "gradient", + "registerserif", "copyrightserif", "trademarkserif", "product", + "radical", "dotmath", "logicalnot", "logicaland", "logicalor", + "arrowdblboth", "arrowdblleft", "arrowdblup", "arrowdblright", + "arrowdbldown", "lozenge", "angleleft", "registersans", "copyrightsans", + "trademarksans", "summation", "parenlefttp", "parenleftex", + "parenleftbt", "bracketlefttp", "bracketleftex", "bracketleftbt", + "bracelefttp", "braceleftmid", "braceleftbt", "braceex", _notdef, + "angleright", "integral", "integraltp", "integralex", "integralbt", + "parenrighttp", "parenrightex", "parenrightbt", "bracketrighttp", + "bracketrightex", "bracketrightbt", "bracerighttp", "bracerightmid", + "bracerightbt", _notdef }; + +const char * const pdf_zapfdingbats[256] = { _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, + "space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", "a118", + "a117", "a11", "a12", "a13", "a14", "a15", "a16", "a105", "a17", + "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", + "a27", "a28", "a6", "a7", "a8", "a9", "a10", "a29", "a30", "a31", + "a32", "a33", "a34", "a35", "a36", "a37", "a38", "a39", "a40", + "a41", "a42", "a43", "a44", "a45", "a46", "a47", "a48", "a49", + "a50", "a51", "a52", "a53", "a54", "a55", "a56", "a57", "a58", + "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66", "a67", + "a68", "a69", "a70", "a71", "a72", "a73", "a74", "a203", "a75", + "a204", "a76", "a77", "a78", "a79", "a81", "a82", "a83", "a84", + "a97", "a98", "a99", "a100", _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, "a101", "a102", "a103", "a104", "a106", "a107", "a108", + "a112", "a111", "a110", "a109", "a120", "a121", "a122", "a123", + "a124", "a125", "a126", "a127", "a128", "a129", "a130", "a131", + "a132", "a133", "a134", "a135", "a136", "a137", "a138", "a139", + "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147", + "a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", + "a156", "a157", "a158", "a159", "a160", "a161", "a163", "a164", + "a196", "a165", "a192", "a166", "a167", "a168", "a169", "a170", + "a171", "a172", "a173", "a162", "a174", "a175", "a176", "a177", + "a178", "a179", "a193", "a180", "a199", "a181", "a200", "a182", + _notdef, "a201", "a183", "a184", "a197", "a185", "a194", "a198", + "a186", "a195", "a187", "a188", "a189", "a190", "a191", _notdef }; + +#endif + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_fontfile.c b/rosapps/smartpdf/fitz/mupdf/pdf_fontfile.c new file mode 100644 index 00000000000..d373de963fd --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_fontfile.c @@ -0,0 +1,420 @@ +#include +#include + +#include + +#include +#include FT_FREETYPE_H + +static FT_Library ftlib = nil; + +#ifdef WIN32 +#include +static int path_exists(const char *path) +{ + if (0 == _access(path, 04)) + return 1; + return 0; +} + +fz_error *initfontlibs_ms(void) +{ + return nil; +} +void deinitfontlibs_ms(void) +{ + if (!ftlib) + return; + FT_Done_FreeType(ftlib); + ftlib = nil; +} +#else +static int path_exists(const char *path) +{ + if (access(path, R_OK) == 0) + return 1; + return 0; +} +#endif + +enum +{ + FD_FIXED = 1 << 0, + FD_SERIF = 1 << 1, + FD_SYMBOLIC = 1 << 2, + FD_SCRIPT = 1 << 3, + FD_NONSYMBOLIC = 1 << 5, + FD_ITALIC = 1 << 6, + FD_ALLCAP = 1 << 16, + FD_SMALLCAP = 1 << 17, + FD_FORCEBOLD = 1 << 18 +}; + +static const struct +{ + const char *name; + const unsigned char *cff; + const unsigned int *len; +} basefonts[15] = +{ + { "Courier", + fonts_NimbusMonL_Regu_cff, + &fonts_NimbusMonL_Regu_cff_len }, + { "Courier-Bold", + fonts_NimbusMonL_Bold_cff, + &fonts_NimbusMonL_Bold_cff_len }, + { "Courier-Oblique", + fonts_NimbusMonL_ReguObli_cff, + &fonts_NimbusMonL_ReguObli_cff_len }, + { "Courier-BoldOblique", + fonts_NimbusMonL_BoldObli_cff, + &fonts_NimbusMonL_BoldObli_cff_len }, + { "Helvetica", + fonts_NimbusSanL_Regu_cff, + &fonts_NimbusSanL_Regu_cff_len }, + { "Helvetica-Bold", + fonts_NimbusSanL_Bold_cff, + &fonts_NimbusSanL_Bold_cff_len }, + { "Helvetica-Oblique", + fonts_NimbusSanL_ReguItal_cff, + &fonts_NimbusSanL_ReguItal_cff_len }, + { "Helvetica-BoldOblique", + fonts_NimbusSanL_BoldItal_cff, + &fonts_NimbusSanL_BoldItal_cff_len }, + { "Times-Roman", + fonts_NimbusRomNo9L_Regu_cff, + &fonts_NimbusRomNo9L_Regu_cff_len }, + { "Times-Bold", + fonts_NimbusRomNo9L_Medi_cff, + &fonts_NimbusRomNo9L_Medi_cff_len }, + { "Times-Italic", + fonts_NimbusRomNo9L_ReguItal_cff, + &fonts_NimbusRomNo9L_ReguItal_cff_len }, + { "Times-BoldItalic", + fonts_NimbusRomNo9L_MediItal_cff, + &fonts_NimbusRomNo9L_MediItal_cff_len }, + { "Symbol", + fonts_StandardSymL_cff, + &fonts_StandardSymL_cff_len }, + { "ZapfDingbats", + fonts_Dingbats_cff, + &fonts_Dingbats_cff_len }, + { "Chancery", + fonts_URWChanceryL_MediItal_cff, + &fonts_URWChanceryL_MediItal_cff_len } +}; + +enum { CNS, GB, Japan, Korea }; +enum { MINCHO, GOTHIC }; + +struct subent { int csi; int kind; char *name; }; + +static const struct subent fontsubs[] = +{ + { CNS, MINCHO, "bkai00mp.ttf" }, + { CNS, GOTHIC, "bsmi00lp.ttf" }, + { CNS, MINCHO, "\345\204\267\345\256\213 Pro.ttf" }, /* LiSong Pro */ + { CNS, GOTHIC, "\345\204\267\351\273\221 Pro.ttf" }, /* LiHei Pro */ + { CNS, MINCHO, "simsun.ttc" }, + { CNS, GOTHIC, "simhei.ttf" }, + + { GB, MINCHO, "gkai00mp.ttf" }, + { GB, GOTHIC, "gbsn00lp.ttf" }, + { GB, MINCHO, "\345\215\216\346\226\207\345\256\213\344\275\223.ttf" }, /* STSong */ + { GB, GOTHIC, "\345\215\216\346\226\207\346\245\267\344\275\223.ttf" }, /* STHeiti */ + { GB, MINCHO, "mingliu.ttc" }, + { GB, GOTHIC, "mingliu.ttc" }, + + { Japan, MINCHO, "kochi-mincho.ttf" }, + { Japan, GOTHIC, "kochi-gothic.ttf" }, + { Japan, MINCHO, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\346\230\216\346\234\235 Pro W3.otf" }, + { Japan, GOTHIC, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\350\247\222\343\202\263\343\202\231 Pro W3.otf" }, + { Japan, MINCHO, "msmincho.ttc" }, + { Japan, GOTHIC, "msgothic.ttc" }, + + { Korea, MINCHO, "batang.ttf" }, + { Korea, GOTHIC, "dotum.ttf" }, + { Korea, MINCHO, "AppleMyungjo.dfont" }, + { Korea, GOTHIC, "AppleGothic.dfont" }, + { Korea, MINCHO, "batang.ttc" }, + { Korea, GOTHIC, "dotum.ttc" }, +}; + +static fz_error *initfontlibs(void) +{ + int fterr; + int maj, min, pat; + + if (ftlib) + return nil; + + fterr = FT_Init_FreeType(&ftlib); + if (fterr) + return fz_throw("freetype failed initialisation: 0x%x", fterr); + + FT_Library_Version(ftlib, &maj, &min, &pat); + if (maj == 2 && min == 1 && pat < 7) + return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat); + + return nil; +} + +fz_error * +pdf_loadbuiltinfont(pdf_font *font, char *fontname) +{ + fz_error *error; + unsigned char *data; + unsigned int len; + FT_Error e; + int i; + + error = initfontlibs(); + if (error) + return error; + + for (i = 0; i < 15; i++) + if (!strcmp(fontname, basefonts[i].name)) + goto found; + + return fz_throw("font not found: %s", fontname); + +found: + pdf_logfont("load builtin font %s\n", fontname); + + data = (unsigned char *) basefonts[i].cff; + len = *basefonts[i].len; + + e = FT_New_Memory_Face(ftlib, data, len, 0, (FT_Face*)&font->ftface); + if (e) + return fz_throw("freetype: could not load font: 0x%x", e); + + return nil; +} + +static int +findcidfont(char *filename, char *path, int pathlen) +{ + static const char *dirs[] = + { + "$/.fonts", + "$/Library/Fonts", + "/usr/X11R6/lib/X11/fonts/TTF", + "/usr/X11R6/lib/X11/fonts/TrueType", + "/usr/share/fonts/arphic", + "/usr/share/fonts/baekmuk", + "/usr/share/fonts/kochi", + "/System/Library/Fonts", + "/Library/Fonts", + nil + }; + + char **dirp; + char *home; + char *dir; + + dir = getenv("FONTDIR"); + if (dir) + { + strlcpy(path, dir, pathlen); + strlcat(path, "/", pathlen); + strlcat(path, filename, pathlen); + if (path_exists(path)) + return 1; + } + + dir = getenv("WINDIR"); + if (dir) + { + strlcpy(path, dir, pathlen); + strlcat(path, "/Fonts/", pathlen); + strlcat(path, filename, pathlen); + if (path_exists(path)) + return 1; + } + + home = getenv("HOME"); + if (!home) + home = "/"; + + for (dirp = (char**)dirs; *dirp; dirp++) + { + dir = *dirp; + if (dir[0] == '$') + { + strlcpy(path, home, pathlen); + strlcat(path, "/", pathlen); + strlcat(path, dir + 1, pathlen); + } + else + { + strlcpy(path, dir, pathlen); + } + strlcat(path, "/", pathlen); + strlcat(path, filename, pathlen); + if (path_exists(path)) + return 1; + } + + return 0; +} + +static fz_error * +loadcidfont(pdf_font *font, int csi, int kind) +{ + char path[1024]; + int e; + int i; + + for (i = 0; i < nelem(fontsubs); i++) + { + if (fontsubs[i].csi == csi && fontsubs[i].kind == kind) + { + if (findcidfont(fontsubs[i].name, path, sizeof path)) + { + pdf_logfont("load system font '%s'\n", fontsubs[i].name); + e = FT_New_Face(ftlib, path, 0, (FT_Face*)&font->ftface); + if (e) + return fz_throw("freetype: could not load font: 0x%x", e); + return nil; + } + } + } + + return fz_throw("could not find cid font file"); +} + +fz_error * +pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection) +{ + fz_error *error; + char *name; + + int isbold = 0; + int isitalic = 0; + int isserif = 0; + int isscript = 0; + int isfixed = 0; + + error = initfontlibs(); + if (error) + return error; + + font->substitute = 1; + + if (strstr(fontname, "Bold")) + isbold = 1; + if (strstr(fontname, "Italic")) + isitalic = 1; + if (strstr(fontname, "Oblique")) + isitalic = 1; + + if (font->flags & FD_FIXED) + isfixed = 1; + if (font->flags & FD_SERIF) + isserif = 1; + if (font->flags & FD_ITALIC) + isitalic = 1; + if (font->flags & FD_SCRIPT) + isscript = 1; + if (font->flags & FD_FORCEBOLD) + isbold = 1; + + pdf_logfont("fixed-%d serif-%d italic-%d script-%d bold-%d\n", + isfixed, isserif, isitalic, isscript, isbold); + + if (collection) + { + int kind; + + if (isserif) + kind = MINCHO; + else + kind = GOTHIC; + + if (!strcmp(collection, "Adobe-CNS1")) + return loadcidfont(font, CNS, kind); + else if (!strcmp(collection, "Adobe-GB1")) + return loadcidfont(font, GB, kind); + else if (!strcmp(collection, "Adobe-Japan1")) + return loadcidfont(font, Japan, kind); + else if (!strcmp(collection, "Adobe-Japan2")) + return loadcidfont(font, Japan, kind); + else if (!strcmp(collection, "Adobe-Korea1")) + return loadcidfont(font, Korea, kind); + + fz_warn("unknown cid collection: %s", collection); + } + + if (isscript) + name = "Chancery"; + + else if (isfixed) + { + if (isitalic) { + if (isbold) name = "Courier-BoldOblique"; + else name = "Courier-Oblique"; + } + else { + if (isbold) name = "Courier-Bold"; + else name = "Courier"; + } + } + + else if (isserif) + { + if (isitalic) { + if (isbold) name = "Times-BoldItalic"; + else name = "Times-Italic"; + } + else { + if (isbold) name = "Times-Bold"; + else name = "Times-Roman"; + } + } + + else + { + if (isitalic) { + if (isbold) name = "Helvetica-BoldOblique"; + else name = "Helvetica-Oblique"; + } + else { + if (isbold) name = "Helvetica-Bold"; + else name = "Helvetica"; + } + } + + return pdf_loadbuiltinfont(font, name); +} + +fz_error * +pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref) +{ + fz_error *error; + int fterr; + FT_Face face; + fz_buffer *buf; + + error = initfontlibs(); + if (error) + return error; + + pdf_logfont("load embedded font\n"); + + error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref)); + if (error) + return error; + + fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face); + + if (fterr) { + fz_free(buf); + return fz_throw("freetype could not load embedded font: 0x%x", fterr); + } + + font->ftface = face; + font->fontdata = buf; + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_fontfilefc.c b/rosapps/smartpdf/fitz/mupdf/pdf_fontfilefc.c new file mode 100644 index 00000000000..b4a92929e83 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_fontfilefc.c @@ -0,0 +1,295 @@ +#include +#include + +#ifdef WIN32 +#error Compile "fontfilems.c" instead +#endif + +#include +#include FT_FREETYPE_H +#include + +static FT_Library ftlib = nil; +static FcConfig *fclib = nil; + +enum +{ + FD_FIXED = 1 << 0, + FD_SERIF = 1 << 1, + FD_SYMBOLIC = 1 << 2, + FD_SCRIPT = 1 << 3, + FD_NONSYMBOLIC = 1 << 5, + FD_ITALIC = 1 << 6, + FD_ALLCAP = 1 << 16, + FD_SMALLCAP = 1 << 17, + FD_FORCEBOLD = 1 << 18 +}; + +static char *basenames[14] = +{ + "Courier", + "Courier-Bold", + "Courier-Oblique", + "Courier-BoldOblique", + "Helvetica", + "Helvetica-Bold", + "Helvetica-Oblique", + "Helvetica-BoldOblique", + "Times-Roman", + "Times-Bold", + "Times-Italic", + "Times-BoldItalic", + "Symbol", + "ZapfDingbats" +}; + +static char *basepatterns[14] = +{ + "Nimbus Mono L,Courier,Courier New:style=Regular,Roman", + "Nimbus Mono L,Courier,Courier New:style=Bold", + "Nimbus Mono L,Courier,Courier New:style=Oblique,Italic", + "Nimbus Mono L,Courier,Courier New:style=BoldOblique,BoldItalic", + "Nimbus Sans L,Helvetica,Arial:style=Regular,Roman", + "Nimbus Sans L,Helvetica,Arial:style=Bold", + "Nimbus Sans L,Helvetica,Arial:style=Oblique,Italic", + "Nimbus Sans L,Helvetica,Arial:style=BoldOblique,BoldItalic", + "Nimbus Roman No9 L,Times,Times New Roman:style=Regular,Roman", + "Nimbus Roman No9 L,Times,Times New Roman:style=Bold,Medium", + "Nimbus Roman No9 L,Times,Times New Roman:style=Italic,Regular Italic", + "Nimbus Roman No9 L,Times,Times New Roman:style=BoldItalic,Medium Italic", + "Standard Symbols L,Symbol", + "Zapf Dingbats,Dingbats" +}; + +static fz_error *initfontlibs(void) +{ + int fterr; + int maj, min, pat; + + if (ftlib) + return nil; + + fterr = FT_Init_FreeType(&ftlib); + if (fterr) + return fz_throw("freetype failed initialisation: 0x%x", fterr); + + FT_Library_Version(ftlib, &maj, &min, &pat); + if (maj == 2 && min == 1 && pat < 7) + return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat); + + fclib = FcInitLoadConfigAndFonts(); + if (!fclib) + return fz_throw("fontconfig failed initialisation"); + + return nil; +} + +fz_error * +pdf_loadbuiltinfont(pdf_font *font, char *basefont) +{ + fz_error *error; + FcResult fcerr; + int fterr; + + FcPattern *searchpat; + FcPattern *matchpat; + FT_Face face; + char *pattern; + char *file; + int index; + int i; + + error = initfontlibs(); + if (error) + return error; + + pattern = basefont; + for (i = 0; i < 14; i++) + if (!strcmp(basefont, basenames[i])) + pattern = basepatterns[i]; + + pdf_logfont("load builtin %s\n", pattern); + + fcerr = FcResultMatch; + searchpat = FcNameParse(pattern); + FcDefaultSubstitute(searchpat); + FcConfigSubstitute(fclib, searchpat, FcMatchPattern); + + matchpat = FcFontMatch(fclib, searchpat, &fcerr); + if (fcerr != FcResultMatch) + return fz_throw("fontconfig could not find font %s", pattern); + + fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file); + if (fcerr != FcResultMatch) + return fz_throw("fontconfig could not find font %s", pattern); + + index = 0; + fcerr = FcPatternGetInteger(matchpat, FC_INDEX, 0, &index); + + pdf_logfont("load font file %s %d\n", file, index); + + fterr = FT_New_Face(ftlib, file, index, &face); + if (fterr) + return fz_throw("freetype could not load font file '%s': 0x%x", file, fterr); + + FcPatternDestroy(matchpat); + FcPatternDestroy(searchpat); + + font->ftface = face; + + return nil; +} + +fz_error * +pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection) +{ + fz_error *error; + FcResult fcerr; + int fterr; + + char fontname[200]; + FcPattern *searchpat; + FcPattern *matchpat; + FT_Face face; + char *style; + char *file; + int index; + + error = initfontlibs(); + if (error) + return error; + + /* parse windows-style font name descriptors Font,Style */ + /* TODO: reliable way to split style from Font-Style type names */ + strlcpy(fontname, basefont, sizeof fontname); + style = strchr(fontname, ','); + if (style) + *style++ = 0; + + searchpat = FcPatternCreate(); + if (!searchpat) + return fz_outofmem; + + error = fz_outofmem; + + if (!FcPatternAddString(searchpat, FC_FAMILY, fontname)) + goto cleanup; + + if (collection) + { + if (!strcmp(collection, "Adobe-GB1")) + if (!FcPatternAddString(searchpat, FC_LANG, "zh-TW")) + goto cleanup; + if (!strcmp(collection, "Adobe-CNS1")) + if (!FcPatternAddString(searchpat, FC_LANG, "zh-CN")) + goto cleanup; + if (!strcmp(collection, "Adobe-Japan1")) + if (!FcPatternAddString(searchpat, FC_LANG, "ja")) + goto cleanup; + if (!strcmp(collection, "Adobe-Japan2")) + if (!FcPatternAddString(searchpat, FC_LANG, "ja")) + goto cleanup; + if (!strcmp(collection, "Adobe-Korea1")) + if (!FcPatternAddString(searchpat, FC_LANG, "ko")) + goto cleanup; + } + + if (style) + if (!FcPatternAddString(searchpat, FC_STYLE, style)) + goto cleanup; + + if (font->flags & FD_SERIF) + FcPatternAddString(searchpat, FC_FAMILY, "serif"); + else + FcPatternAddString(searchpat, FC_FAMILY, "sans-serif"); + if (font->flags & FD_ITALIC) + FcPatternAddString(searchpat, FC_STYLE, "Italic"); + if (font->flags & FD_FORCEBOLD) + FcPatternAddString(searchpat, FC_STYLE, "Bold"); + + if (!FcPatternAddBool(searchpat, FC_OUTLINE, 1)) + goto cleanup; + + file = FcNameUnparse(searchpat); + pdf_logfont("fontconfig0 %s\n", file); + free(file); + + fcerr = FcResultMatch; +/* FcDefaultSubstitute(searchpat); */ + FcConfigSubstitute(fclib, searchpat, FcMatchPattern); + + file = FcNameUnparse(searchpat); + pdf_logfont("fontconfig1 %s\n", file); + free(file); + + matchpat = FcFontMatch(fclib, searchpat, &fcerr); + if (fcerr != FcResultMatch) + return fz_throw("fontconfig could not find font %s", basefont); + + fcerr = FcPatternGetString(matchpat, FC_FAMILY, 0, (FcChar8**)&file); + if (file && strcmp(fontname, file)) + font->substitute = 1; + + fcerr = FcPatternGetString(matchpat, FC_STYLE, 0, (FcChar8**)&file); + if (file && style && strcmp(style, file)) + font->substitute = 1; + + fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file); + if (fcerr != FcResultMatch) + return fz_throw("fontconfig could not find font %s", basefont); + + index = 0; + fcerr = FcPatternGetInteger(matchpat, FC_INDEX, 0, &index); + + pdf_logfont("load font file %s %d\n", file, index); + + fterr = FT_New_Face(ftlib, file, index, &face); + if (fterr) { + FcPatternDestroy(matchpat); + FcPatternDestroy(searchpat); + return fz_throw("freetype could not load font file '%s': 0x%x", file, fterr); + } + + FcPatternDestroy(matchpat); + FcPatternDestroy(searchpat); + + font->ftface = face; + + return nil; + +cleanup: + FcPatternDestroy(searchpat); + return error; +} + +fz_error * +pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref) +{ + fz_error *error; + int fterr; + FT_Face face; + fz_buffer *buf; + + error = initfontlibs(); + if (error) + return error; + + pdf_logfont("load embedded font\n"); + + error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref)); + if (error) + return error; + + fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face); + + if (fterr) { + fz_free(buf); + return fz_throw("freetype could not load embedded font: 0x%x", fterr); + } + + font->ftface = face; + font->fontdata = buf; + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_fontfilems.c b/rosapps/smartpdf/fitz/mupdf/pdf_fontfilems.c new file mode 100644 index 00000000000..93a4ff1956e --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_fontfilems.c @@ -0,0 +1,806 @@ +#include +#include + +#include + +#include +#include FT_FREETYPE_H + +#define SAFE_FZ_READ(file, buf, size)\ + byteread = fz_read((file), (char*)(buf), (size));\ + if(byteread<0) err = fz_ioerror(file);\ + if(byteread != (size)) err = fz_throw("ioerror");\ + if(err) goto cleanup; + +#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0]) + +#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) +#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) + +#define PLATFORM_UNICODE 0 +#define PLATFORM_MACINTOSH 1 +#define PLATFORM_ISO 2 +#define PLATFORM_MICROSOFT 3 + +#define UNI_ENC_UNI_1 0 +#define UNI_ENC_UNI_1_1 1 +#define UNI_ENC_ISO 2 +#define UNI_ENC_UNI_2_BMP 3 +#define UNI_ENC_UNI_2_FULL_REPERTOIRE 4 + +#define MAC_ROMAN 0 +#define MAC_JAPANESE 1 +#define MAC_CHINESE_TRADITIONAL 2 +#define MAC_KOREAN 3 +#define MAC_CHINESE_SIMPLIFIED 25 + +#define MS_ENC_SYMBOL 0 +#define MS_ENC_UNI_BMP 1 +#define MS_ENC_SHIFTJIS 2 +#define MS_ENC_PRC 3 +#define MS_ENC_BIG5 4 +#define MS_ENC_WANSUNG 5 +#define MS_ENC_JOHAB 6 +#define MS_ENC_UNI_FULL_REPETOIRE 10 + +#define TTC_VERSION1 0x00010000 +#define TTC_VERSION2 0x00020000 + +typedef struct pdf_fontmapMS_s pdf_fontmapMS; +typedef struct pdf_fontlistMS_s pdf_fontlistMS; + +struct pdf_fontmapMS_s +{ + char fontface[128]; + char fontpath[MAX_PATH+1]; + int index; +}; + +struct pdf_fontlistMS_s +{ + pdf_fontmapMS *fontmap; + int len; + int cap; +}; + +typedef struct _tagTT_OFFSET_TABLE +{ + USHORT uMajorVersion; + USHORT uMinorVersion; + USHORT uNumOfTables; + USHORT uSearchRange; + USHORT uEntrySelector; + USHORT uRangeShift; +} TT_OFFSET_TABLE; + +typedef struct _tagTT_TABLE_DIRECTORY +{ + char szTag[4]; //table name + ULONG uCheckSum; //Check sum + ULONG uOffset; //Offset from beginning of file + ULONG uLength; //length of the table in bytes +} TT_TABLE_DIRECTORY; + +typedef struct _tagTT_NAME_TABLE_HEADER +{ + USHORT uFSelector; //format selector. Always 0 + USHORT uNRCount; //Name Records count + USHORT uStorageOffset; //Offset for strings storage, from start of the table +} TT_NAME_TABLE_HEADER; + +typedef struct _tagTT_NAME_RECORD +{ + USHORT uPlatformID; + USHORT uEncodingID; + USHORT uLanguageID; + USHORT uNameID; + USHORT uStringLength; + USHORT uStringOffset; //from start of storage area +} TT_NAME_RECORD; + +typedef struct _tagFONT_COLLECTION +{ + char Tag[4]; + ULONG Version; + ULONG NumFonts; +}FONT_COLLECTION; + +static char *basenames[13] = +{ + "Courier", + "Courier-Bold", + "Courier-Oblique", + "Courier-BoldOblique", + "Helvetica", + "Helvetica-Bold", + "Helvetica-Oblique", + "Helvetica-BoldOblique", + "Times-Roman", + "Times-Bold", + "Times-Italic", + "Times-BoldItalic", + "Symbol", +}; + +static char *basepatterns[13] = +{ + "CourierNewPSMT", + "CourierNewPS-BoldMT", + "CourierNewPS-ItalicMT", + "CourierNewPS-BoldItalicMT", + "ArialMT", + "Arial-BoldMT", + "Arial-ItalicMT", + "Arial-BoldItalicMT", + "TimesNewRomanPSMT", + "TimesNewRomanPS-BoldMT", + "TimesNewRomanPS-ItalicMT", + "TimesNewRomanPS-BoldItalicMT", + "SymbolMT" +}; + +static pdf_fontlistMS fontlistMS = +{ + NULL, + 0, + 0, +}; + +static int +compare(const void *elem1, const void *elem2) +{ + pdf_fontmapMS *val1 = (pdf_fontmapMS *)elem1; + pdf_fontmapMS *val2 = (pdf_fontmapMS *)elem2; + + if(val1->fontface[0] == 0) + return 1; + if(val2->fontface[0] == 0) + return -1; + + return stricmp(val1->fontface, val2->fontface); +} + +static void * +localbsearch (const void *key, const void *base, size_t num, + size_t width, int (*compare)(const void *, const void *)) +{ + char *lo = (char *)base; + char *hi = (char *)base + (num - 1) * width; + char *mid; + unsigned int half; + int result; + + while (lo <= hi) + if (half = num / 2) + { + mid = lo + (num & 1 ? half : (half - 1)) * width; + if (!(result = (*compare)(key,mid))) + return(mid); + else if (result < 0) + { + hi = mid - width; + num = num & 1 ? half : half-1; + } + else { + lo = mid + width; + num = half; + } + } + else if (num) + return((*compare)(key,lo) ? 0 : lo); + else + break; + + return(0); +} + +static void +removeredundancy(pdf_fontlistMS *fl) +{ + int i; + int roffset = 0; + int redundancy_count = 0; + + qsort(fl->fontmap,fl->len,sizeof(pdf_fontmapMS),compare); + for(i = 0; i < fl->len - 1; ++i) + { + if(strcmp(fl->fontmap[i].fontface,fl->fontmap[i+1].fontface) == 0) + { + fl->fontmap[i].fontface[0] = 0; + ++redundancy_count; + } + } + qsort(fl->fontmap,fl->len,sizeof(pdf_fontmapMS),compare); + fl->len -= redundancy_count; +#ifndef NDEBUG + for(i = 0; i < fl->len; ++i) + fprintf(stdout,"%s , %s , %d\n",fl->fontmap[i].fontface, + fl->fontmap[i].fontpath,fl->fontmap[i].index); +#endif +} + +static fz_error * +swapword(char* pbyte, int nLen) +{ + int i; + char tmp; + int nMax; + + if(nLen%2) + return fz_throw("fonterror"); + + nMax = nLen / 2; + for(i = 0; i < nLen; ++i) { + tmp = pbyte[i*2]; + pbyte[i*2] = pbyte[i*2+1]; + pbyte[i*2+1] = tmp; + } + return 0; +} + +/* pSouce and PDest can be same */ +static fz_error * +decodeunicodeBMP(char* source, int sourcelen,char* dest, int destlen) +{ + wchar_t tmp[1024*2]; + int converted; + memset(tmp,0,sizeof(tmp)); + memcpy(tmp,source,sourcelen); + swapword((char*)tmp,sourcelen); + + converted = WideCharToMultiByte(CP_ACP, 0, tmp, + -1, dest, destlen, NULL, NULL); + + if(converted == 0) + return fz_throw("fonterror"); + + return 0; +} + +static fz_error * +decodeunicodeplatform(char* source, int sourcelen,char* dest, int destlen, int enctype) +{ + fz_error *err = nil; + switch(enctype) + { + case UNI_ENC_UNI_1: + case UNI_ENC_UNI_2_BMP: + err = decodeunicodeBMP(source,sourcelen,dest,destlen); + break; + case UNI_ENC_UNI_2_FULL_REPERTOIRE: + case UNI_ENC_UNI_1_1: + case UNI_ENC_ISO: + default: + err = fz_throw("fonterror : unsupported encoding"); + break; + } + return err; +} + +static fz_error * +decodemacintoshplatform(char* source, int sourcelen,char* dest, int destlen, int enctype) +{ + fz_error *err = nil; + switch(enctype) + { + case MAC_ROMAN: + if(sourcelen + 1 > destlen) + err = fz_throw("fonterror : short buf lenth"); + else + { + memcpy(source,dest,sourcelen); + dest[sourcelen] = 0; + } + break; + default: + err = fz_throw("fonterror : unsupported encoding"); + break; + } + return err; +} + +static fz_error * +decodemicrosoftplatform(char* source, int sourcelen,char* dest, int destlen, int enctype) +{ + fz_error *err = nil; + switch(enctype) + { + case MS_ENC_SYMBOL: + case MS_ENC_UNI_BMP: + err = decodeunicodeBMP(source,sourcelen,dest,destlen); + break; + default: + err = fz_throw("fonterror : unsupported encoding"); + break; + } + return err; +} + +static fz_error * +growfontlist(pdf_fontlistMS *fl) +{ + int newcap; + pdf_fontmapMS *newitems; + + if(fl->cap == 0) + newcap = 32; + else + newcap = fl->cap * 2; + + newitems = fz_realloc(fl->fontmap, sizeof(pdf_fontmapMS) * newcap); + if (!newitems) + return fz_outofmem; + + memset(newitems + fl->cap, 0, + sizeof(struct fz_keyval_s) * (newcap - fl->cap)); + + fl->fontmap = newitems; + fl->cap = newcap; + + return nil; +} + +static fz_error * +insertmapping(pdf_fontlistMS *fl, char *facename, char *path, int index) +{ + fz_error *err; + + if(fl->len == fl->cap) { + err = growfontlist(fl); + if(err) return err; + } + + if(fl->len >= fl->cap) + return fz_throw("fonterror : fontlist overflow"); + + strlcpy(fl->fontmap[fl->len].fontface, facename, + sizeof(fl->fontmap[0].fontface)); + strlcpy(fl->fontmap[fl->len].fontpath, path, + sizeof(fl->fontmap[0].fontpath)); + fl->fontmap[fl->len].index = index; + + ++fl->len; + + return nil; +} + +static fz_error * +parseTTF(fz_stream *file, int offset, int index, char *path) +{ + fz_error *err = nil; + int byteread; + + TT_OFFSET_TABLE ttOffsetTable; + TT_TABLE_DIRECTORY tblDir; + TT_NAME_TABLE_HEADER ttNTHeader; + TT_NAME_RECORD ttRecord; + + char szTemp[4096]; + int found; + int i; + + fz_seek(file,offset,0); + SAFE_FZ_READ(file, &ttOffsetTable, sizeof(TT_OFFSET_TABLE)); + + ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables); + ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion); + ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion); + + //check is this is a true type font and the version is 1.0 + if(ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0) + return fz_throw("fonterror : invalid font version"); + + found = 0; + + for(i = 0; i< ttOffsetTable.uNumOfTables; i++) + { + SAFE_FZ_READ(file,&tblDir,sizeof(TT_TABLE_DIRECTORY)); + + memcpy(szTemp, tblDir.szTag, 4); + szTemp[4] = 0; + + if (stricmp(szTemp, "name") == 0) + { + found = 1; + tblDir.uLength = SWAPLONG(tblDir.uLength); + tblDir.uOffset = SWAPLONG(tblDir.uOffset); + break; + } + else if (szTemp[0] == 0) + { + break; + } + } + + if (found) + { + fz_seek(file,tblDir.uOffset,0); + + SAFE_FZ_READ(file,&ttNTHeader,sizeof(TT_NAME_TABLE_HEADER)); + + ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount); + ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset); + + offset = tblDir.uOffset + sizeof(TT_NAME_TABLE_HEADER); + + for(i = 0; i < ttNTHeader.uNRCount && err == nil; ++i) + { + fz_seek(file, offset + sizeof(TT_NAME_RECORD)*i, 0); + SAFE_FZ_READ(file,&ttRecord,sizeof(TT_NAME_RECORD)); + + ttRecord.uNameID = SWAPWORD(ttRecord.uNameID); + ttRecord.uLanguageID = SWAPWORD(ttRecord.uLanguageID); + + // Full Name + if(ttRecord.uNameID == 6) + { + ttRecord.uPlatformID = SWAPWORD(ttRecord.uPlatformID); + ttRecord.uEncodingID = SWAPWORD(ttRecord.uEncodingID); + ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength); + ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset); + + fz_seek(file, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, 0); + SAFE_FZ_READ(file, szTemp, ttRecord.uStringLength); + + switch(ttRecord.uPlatformID) + { + case PLATFORM_UNICODE: + err = decodeunicodeplatform(szTemp, ttRecord.uStringLength, + szTemp, sizeof(szTemp), ttRecord.uEncodingID); + break; + case PLATFORM_MACINTOSH: + err = decodemacintoshplatform(szTemp, ttRecord.uStringLength, + szTemp, sizeof(szTemp), ttRecord.uEncodingID); + break; + case PLATFORM_ISO: + err = fz_throw("fonterror : unsupported platform"); + break; + case PLATFORM_MICROSOFT: + err = decodemicrosoftplatform(szTemp, ttRecord.uStringLength, + szTemp, sizeof(szTemp), ttRecord.uEncodingID); + break; + } + + if(err == nil) + err = insertmapping(&fontlistMS, szTemp, path, index); + } + } + } + +cleanup: + return err; +} + +static fz_error * +parseTTFs(char *path) +{ + fz_error *err = nil; + fz_stream *file = nil; + + err = fz_openrfile(&file, path); + if(err) + goto cleanup; + + err = parseTTF(file,0,0,path); + if(err) + goto cleanup; + +cleanup: + if(file) + fz_dropstream(file); + + return err; +} + +static fz_error * +parseTTCs(char *path) +{ + fz_error *err = nil; + int byteread; + fz_stream *file = nil; + FONT_COLLECTION fontcollectioin; + ULONG i; + + err = fz_openrfile(&file, path); + if(err) + goto cleanup; + + SAFE_FZ_READ(file, &fontcollectioin, sizeof(FONT_COLLECTION)); + if(memcmp(fontcollectioin.Tag,"ttcf",sizeof(fontcollectioin.Tag)) == 0) + { + fontcollectioin.Version = SWAPLONG(fontcollectioin.Version); + fontcollectioin.NumFonts = SWAPLONG(fontcollectioin.NumFonts); + if( fontcollectioin.Version == TTC_VERSION1 || + fontcollectioin.Version == TTC_VERSION2 ) + { + ULONG *offsettable = fz_malloc(sizeof(ULONG)*fontcollectioin.NumFonts); + if(offsettable == nil) + { + err = fz_outofmem; + goto cleanup; + } + + SAFE_FZ_READ(file, offsettable, sizeof(ULONG)*fontcollectioin.NumFonts); + for(i = 0; i < fontcollectioin.NumFonts; ++i) + { + offsettable[i] = SWAPLONG(offsettable[i]); + parseTTF(file,offsettable[i],i,path); + } + fz_free(offsettable); + } + else + { + err = fz_throw("fonterror : invalid version"); + goto cleanup; + } + } + else + { + err = fz_throw("fonterror: wrong format"); + goto cleanup; + } + + +cleanup: + if(file) + fz_dropstream(file); + + return err; +} + +static fz_error* +pdf_createfontlistMS() +{ + char szFontDir[MAX_PATH*2]; + char szSearch[MAX_PATH*2]; + char szFile[MAX_PATH*2]; + BOOL fFinished; + HANDLE hList; + WIN32_FIND_DATA FileData; + fz_error *err; + + if (fontlistMS.len != 0) + return nil; + + GetWindowsDirectory(szFontDir, sizeof(szFontDir)); + + // Get the proper directory path + strcat(szFontDir,"\\Fonts\\"); + sprintf(szSearch,"%s*.tt?",szFontDir); + // Get the first file + hList = FindFirstFile(szSearch, &FileData); + if (hList == INVALID_HANDLE_VALUE) + { + /* Don't complain about missing directories */ + if (errno == ENOENT) + return fz_throw("fonterror : can't find system fonts dir"); + return fz_throw("ioerror"); + } + // Traverse through the directory structure + fFinished = FALSE; + while (!fFinished) + { + if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + // Get the full path for sub directory + sprintf(szFile,"%s%s", szFontDir, FileData.cFileName); + if (szFile[strlen(szFile)-1] == 'c' || szFile[strlen(szFile)-1] == 'C') + { + err = parseTTCs(szFile); + // ignore error parsing a given font file + } + else if (szFile[strlen(szFile)-1] == 'f'|| szFile[strlen(szFile)-1] == 'F') + { + err = parseTTFs(szFile); + // ignore error parsing a given font file + } + } + + if (!FindNextFile(hList, &FileData)) + { + if (GetLastError() == ERROR_NO_MORE_FILES) + { + fFinished = TRUE; + } + } + } + + removeredundancy(&fontlistMS); + return nil; +} + +void +pdf_destoryfontlistMS() +{ + if (fontlistMS.fontmap != nil) + fz_free(fontlistMS.fontmap); + + fontlistMS.len = 0; + fontlistMS.cap = 0; +} + +#if 0 /* This is for testing if localbsearch() fails unexpectedly */ +pdf_fontmapMS * +findlinear(pdf_fontlistMS *list, pdf_fontmapMS *item) +{ + int i, len; + pdf_fontmapMS *curritem = list->fontmap; + + len = list->len; + for (i = 0; i < len; i++) + { + if (0 == stricmp(curritem->fontface, item->fontface)) + return curritem; + ++curritem; + } + return 0; +} +#endif + +fz_error * +pdf_lookupfontMS(char *fontname, char **fontpath, int *index) +{ + pdf_fontmapMS fontmap; + pdf_fontmapMS *found = nil; + char *pattern; + int i; + + if (fontlistMS.len == 0) + return fz_throw("fonterror : no fonts in the system"); + + pattern = fontname; + for (i = 0; i < ARRAY_SIZE(basenames); i++) + { + if (0 == strcmp(fontname, basenames[i])) + { + pattern = basepatterns[i]; + break; + } + } + + strlcpy(fontmap.fontface,pattern,sizeof(fontmap.fontface)); + found = localbsearch(&fontmap, fontlistMS.fontmap, fontlistMS.len, sizeof(pdf_fontmapMS),compare); + +#if 0 + if (!found) + found = findlinear(&fontlistMS, &fontmap); +#endif + + if (found) + { + *fontpath = found->fontpath; + *index = found->index; + } + else + { + *fontpath = fontlistMS.fontmap[0].fontpath; + *index = fontlistMS.fontmap[0].index; + } + + return nil; +} + +static FT_Library ftlib = nil; + +static fz_error *initfontlibs(void) +{ + int fterr; + int maj, min, pat; + fz_error *err; + + if (ftlib) + return nil; + + fterr = FT_Init_FreeType(&ftlib); + if (fterr) + return fz_throw("freetype failed initialisation: 0x%x", fterr); + + FT_Library_Version(ftlib, &maj, &min, &pat); + if (maj == 2 && min == 1 && pat < 7) + return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat); + + err = pdf_createfontlistMS(); + if(err) + return err; + + return nil; +} + +fz_error *initfontlibs_ms(void) +{ + return initfontlibs(); +} + +void deinitfontlibs_ms(void) +{ + pdf_destoryfontlistMS(); + FT_Done_FreeType(ftlib); + ftlib = nil; +} + +fz_error * +pdf_loadbuiltinfont(pdf_font *font, char *basefont) +{ + fz_error *error; + int fterr; + + FT_Face face; + char *file; + int index; + + error = initfontlibs(); + if (error) + return error; + + error = pdf_lookupfontMS(basefont,&file,&index); + if(error) + return error; + + fterr = FT_New_Face(ftlib, file, index, &face); + if (fterr) + return fz_throw("freetype could not load font file '%s': 0x%x", file, fterr); + + font->ftface = face; + + return nil; +} + +fz_error * +pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection) +{ + fz_error *error; + int fterr; + FT_Face face; + char *file; + int index; + + error = initfontlibs(); + if (error) + return error; + + error = pdf_lookupfontMS(basefont,&file,&index); + if(error) + goto cleanup; + + fterr = FT_New_Face(ftlib, file, index, &face); + if (fterr) { + return fz_throw("freetype could not load font file '%s': 0x%x", file, fterr); + } + + font->ftface = face; + + return nil; + +cleanup: + return error; +} + +fz_error * +pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref) +{ + fz_error *error; + int fterr; + FT_Face face; + fz_buffer *buf; + + error = initfontlibs(); + if (error) + return error; + + error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref)); + if (error) + return error; + + fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face); + + if (fterr) { + fz_free(buf); + return fz_throw("freetype could not load embedded font: 0x%x", fterr); + } + + font->ftface = face; + font->fontdata = buf; + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_function.c b/rosapps/smartpdf/fitz/mupdf/pdf_function.c new file mode 100644 index 00000000000..fd241e7c8bf --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_function.c @@ -0,0 +1,1556 @@ +#include +#include + +/* this mess is seokgyo's */ + +enum +{ + MAXN = FZ_MAXCOLORS, + MAXM = FZ_MAXCOLORS, + MAXK = 32 +}; + +typedef struct psobj_s psobj; + +enum +{ + SAMPLE = 0, + EXPONENTIAL = 2, + STITCHING = 3, + POSTSCRIPT = 4 +}; + +struct pdf_function_s +{ + int refs; + int type; /* 0=sample 2=exponential 3=stitching 4=postscript */ + int m; /* number of input values */ + int n; /* number of output values */ + float domain[MAXM][2]; /* even index : min value, odd index : max value */ + float range[MAXN][2]; /* even index : min value, odd index : max value */ + int hasrange; + + union + { + struct { + unsigned short bps; + int size[MAXM]; + float encode[MAXM][2]; + float decode[MAXN][2]; + int *samples; + } sa; + + struct { + float n; + float c0[MAXN]; + float c1[MAXN]; + } e; + + struct { + int k; + pdf_function *funcs[MAXK]; + float bounds[MAXK-1]; + float encode[MAXK][2]; + } st; + + struct { + psobj *code; + int cap; + } p; + } u; +}; + +#define RADIAN 57.2957795 + +#define LERP(x, xmin, xmax, ymin, ymax) \ + (ymin) + ((x) - (xmin)) * ((ymax) - (ymin)) / ((xmax) - (xmin)) + +#define SAFE_PUSHINT(st, a) {error = pspushint(st, a); if (error) goto cleanup;} +#define SAFE_PUSHREAL(st, a) {error = pspushreal(st, a); if (error) goto cleanup;} +#define SAFE_PUSHBOOL(st, a) {error = pspushbool(st, a); if (error) goto cleanup;} +#define SAFE_POPINT(st, a) {error = pspopint(st, a); if (error) goto cleanup;} +#define SAFE_POPNUM(st, a) {error = pspopnum(st, a); if (error) goto cleanup;} +#define SAFE_POPBOOL(st, a) {error = pspopbool(st, a); if (error) goto cleanup;} +#define SAFE_POP(st) {error = pspop(st); if (error) goto cleanup;} +#define SAFE_INDEX(st, i) {error = psindex(st, i); if (error) goto cleanup;} +#define SAFE_COPY(st, n) {error = pscopy(st, n); if (error) goto cleanup;} + +enum { PSBOOL, PSINT, PSREAL, PSOPERATOR, PSBLOCK }; + +enum +{ + PSOABS, PSOADD, PSOAND, PSOATAN, PSOBITSHIFT, PSOCEILING, + PSOCOPY, PSOCOS, PSOCVI, PSOCVR, PSODIV, PSODUP, PSOEQ, + PSOEXCH, PSOEXP, PSOFALSE, PSOFLOOR, PSOGE, PSOGT, PSOIDIV, + PSOINDEX, PSOLE, PSOLN, PSOLOG, PSOLT, PSOMOD, PSOMUL, + PSONE, PSONEG, PSONOT, PSOOR, PSOPOP, PSOROLL, PSOROUND, + PSOSIN, PSOSQRT, PSOSUB, PSOTRUE, PSOTRUNCATE, PSOXOR, + PSOIF, PSOIFELSE, PSORETURN +}; + +static char *psopnames[] = +{ + "abs", "add", "and", "atan", "bitshift", "ceiling", "copy", + "cos", "cvi", "cvr", "div", "dup", "eq", "exch", "exp", + "false", "floor", "ge", "gt", "idiv", "index", "le", "ln", + "log", "lt", "mod", "mul", "ne", "neg", "not", "or", "pop", + "roll", "round", "sin", "sqrt", "sub", "true", "truncate", + "xor", /* "if", "ifelse", "return" */ +}; + +struct psobj_s +{ + int type; + union + { + int b; /* boolean (stack only) */ + int i; /* integer (stack and code) */ + float f; /* real (stack and code) */ + int op; /* operator (code only) */ + int block; /* if/ifelse block pointer (code only) */ + } u; +}; + +/* + * PostScript calculator + */ + +enum { PSSTACKSIZE = 100 }; + +#define fz_stackoverflow fz_throw("rangecheck: stackoverflow in calculator") +#define fz_stackunderflow fz_throw("rangecheck: stackunderflow in calculator") +#define fz_stacktypemismatch fz_throw("typecheck: postscript calculator") + +typedef struct psstack_s psstack; + +struct psstack_s +{ + psobj stack[PSSTACKSIZE]; + int sp; +}; + +static void +psinitstack(psstack *st) +{ + memset(st->stack, 0, sizeof(st->stack)); + st->sp = PSSTACKSIZE; +} + +static int +pscheckoverflow(psstack *st, int n) +{ + return st->sp >= n; +} + +static int +pscheckunderflow(psstack *st) +{ + return st->sp != PSSTACKSIZE; +} + +static int +pschecktype(psstack *st, unsigned short t1, unsigned short t2) +{ + return (st->stack[st->sp].type == t1 || + st->stack[st->sp].type == t2); +} + +static fz_error * +pspushbool(psstack *st, int booln) +{ + if (pscheckoverflow(st, 1)) + { + st->stack[--st->sp].type = PSBOOL; + st->stack[st->sp].u.b = booln; + } + else + return fz_stackoverflow; + return nil; +} + +static fz_error * +pspushint(psstack *st, int intg) +{ + if (pscheckoverflow(st, 1)) + { + st->stack[--st->sp].type = PSINT; + st->stack[st->sp].u.i = intg; + } + else + return fz_stackoverflow; + return nil; +} + +static fz_error * +pspushreal(psstack *st, float real) +{ + if (pscheckoverflow(st, 1)) + { + st->stack[--st->sp].type = PSREAL; + st->stack[st->sp].u.f = real; + } + else + return fz_stackoverflow; + return nil; +} + +static fz_error * +pspopbool(psstack *st, int *booln) +{ + if (pscheckunderflow(st) && pschecktype(st, PSBOOL, PSBOOL)) + { + *booln = st->stack[st->sp++].u.b; + } + else if (pscheckunderflow(st)) + return fz_stackunderflow; + else + return fz_stacktypemismatch; + return nil; +} + +static fz_error * +pspopint(psstack *st, int *intg) +{ + if (pscheckunderflow(st) && pschecktype(st, PSINT, PSINT)) + { + *intg = st->stack[st->sp++].u.i; + } + else if (pscheckunderflow(st)) + return fz_stackunderflow; + else + return fz_stacktypemismatch; + return nil; +} + +static fz_error * +pspopnum(psstack *st, float *real) +{ + if (pscheckunderflow(st) && pschecktype(st, PSINT, PSREAL)) + { + float ret; + ret = (st->stack[st->sp].type == PSINT) ? + (float) st->stack[st->sp].u.i : st->stack[st->sp].u.f; + ++st->sp; + *real = ret; + } + else if (pscheckunderflow(st)) + return fz_stackunderflow; + else + return fz_stacktypemismatch; + return nil; +} + +static int +pstopisint(psstack *st) +{ + return st->sp < PSSTACKSIZE && st->stack[st->sp].type == PSINT; +} + +static int +pstoptwoareints(psstack *st) +{ + return st->sp < PSSTACKSIZE - 1 && + st->stack[st->sp].type == PSINT && + st->stack[st->sp + 1].type == PSINT; +} + +static int +pstopisreal(psstack *st) +{ + return st->sp < PSSTACKSIZE && st->stack[st->sp].type == PSREAL; +} + +static int +pstoptwoarenums(psstack *st) +{ + return st->sp < PSSTACKSIZE - 1 && + (st->stack[st->sp].type == PSINT || st->stack[st->sp].type == PSREAL) && + (st->stack[st->sp + 1].type == PSINT || st->stack[st->sp + 1].type == PSREAL); +} + +static fz_error * +pscopy(psstack *st, int n) +{ + int i; + + if (!pscheckoverflow(st, n)) + return fz_stackoverflow; + + for (i = st->sp + n - 1; i <= st->sp; ++i) + { + st->stack[i - n] = st->stack[i]; + } + st->sp -= n; + + return nil; +} + +static void +psroll(psstack *st, int n, int j) +{ + psobj obj; + int i, k; + + if (j >= 0) + { + j %= n; + } + else + { + j = -j % n; + if (j != 0) + { + j = n - j; + } + } + if (n <= 0 || j == 0) + { + return; + } + for (i = 0; i < j; ++i) + { + obj = st->stack[st->sp]; + for (k = st->sp; k < st->sp + n - 1; ++k) + { + st->stack[k] = st->stack[k + 1]; + } + st->stack[st->sp + n - 1] = obj; + } +} + +static fz_error * +psindex(psstack *st, int i) +{ + if (!pscheckoverflow(st, 1)) + { + return fz_stackoverflow; + } + --st->sp; + st->stack[st->sp] = st->stack[st->sp + 1 + i]; + return nil; +} + +static fz_error * +pspop(psstack *st) +{ + if (!pscheckoverflow(st, 1)) + { + return fz_stackoverflow; + } + ++st->sp; + return nil; +} + +static fz_error * +resizecode(pdf_function *func, int newsize) +{ + if (newsize >= func->u.p.cap) + { + int newcodecap = func->u.p.cap + 64; + psobj *newcode; + newcode = fz_realloc(func->u.p.code, newcodecap * sizeof(psobj)); + if (!newcode) + return fz_outofmem; + func->u.p.cap = newcodecap; + func->u.p.code = newcode; + } + return nil; +} + +static fz_error * +parsecode(pdf_function *func, fz_stream *stream, int *codeptr) +{ + fz_error *error = nil; + char buf[64]; + int buflen = sizeof(buf) / sizeof(buf[0]); + int len; + int token; + int opptr, elseptr; + int a, b, mid, cmp; + + memset(buf, 0, sizeof(buf)); + + while (1) + { + token = pdf_lex(stream, buf, buflen, &len); + + if (token == PDF_TERROR || token == PDF_TEOF) + goto cleanup; + + switch(token) + { + case PDF_TINT: + resizecode(func, *codeptr); + func->u.p.code[*codeptr].type = PSINT; + func->u.p.code[*codeptr].u.i = atoi(buf); + ++*codeptr; + break; + + case PDF_TREAL: + resizecode(func, *codeptr); + func->u.p.code[*codeptr].type = PSREAL; + func->u.p.code[*codeptr].u.f = atof(buf); + ++*codeptr; + break; + + case PDF_TOBRACE: + opptr = *codeptr; + *codeptr += 3; + resizecode(func, opptr + 2); + error = parsecode(func, stream, codeptr); + if (error) goto cleanup; + + token = pdf_lex(stream, buf, buflen, &len); + + if (token == PDF_TEOF || token == PDF_TERROR) + goto cleanup; + + if (token == PDF_TOBRACE) { + elseptr = *codeptr; + error = parsecode(func, stream, codeptr); + if (error) goto cleanup; + token = pdf_lex(stream, buf, buflen, &len); + if (token == PDF_TERROR || token == PDF_TEOF) + goto cleanup; + } + else + elseptr = -1; + + if (token == PDF_TKEYWORD) { + if (!strcmp(buf, "if")) { + if (elseptr >= 0) + goto cleanup; + func->u.p.code[opptr].type = PSOPERATOR; + func->u.p.code[opptr].u.op = PSOIF; + func->u.p.code[opptr+2].type = PSBLOCK; + func->u.p.code[opptr+2].u.block = *codeptr; + } + else if (!strcmp(buf, "ifelse")) { + if (elseptr < 0) + goto cleanup; + func->u.p.code[opptr].type = PSOPERATOR; + func->u.p.code[opptr].u.op = PSOIFELSE; + func->u.p.code[opptr+1].type = PSBLOCK; + func->u.p.code[opptr+1].u.block = elseptr; + func->u.p.code[opptr+2].type = PSBLOCK; + func->u.p.code[opptr+2].u.block = *codeptr; + } + else + goto cleanup; + } + else + goto cleanup; + break; + + case PDF_TCBRACE: + resizecode(func, *codeptr); + func->u.p.code[*codeptr].type = PSOPERATOR; + func->u.p.code[*codeptr].u.op = PSORETURN; + ++*codeptr; + return nil; + + case PDF_TKEYWORD: + a = -1; + b = sizeof(psopnames) / sizeof(psopnames[0]); + /* invariant: psopnames[a] < op < psopnames[b] */ + while (b - a > 1) { + mid = (a + b) / 2; + cmp = strcmp(buf, psopnames[mid]); + if (cmp > 0) { + a = mid; + } else if (cmp < 0) { + b = mid; + } else { + a = b = mid; + } + } + if (cmp != 0) + goto cleanup; + + resizecode(func, *codeptr); + func->u.p.code[*codeptr].type = PSOPERATOR; + func->u.p.code[*codeptr].u.op = a; + ++*codeptr; + break; + + default: + goto cleanup; + } + } + return nil; + +cleanup: + if (error) return error; + return fz_throw("syntaxerror: postscript calculator"); +} + +static fz_error * +loadpostscriptfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gen) +{ + fz_error *error = nil; + fz_stream *stream; + int codeptr; + + pdf_logrsrc("load postscript function %d %d\n", oid, gen); + + error = pdf_openstream(&stream, xref, oid, gen); + if (error) goto cleanup; + + if (fz_readbyte(stream) != '{') + goto cleanup; + + func->u.p.code = nil; + func->u.p.cap = 0; + + + codeptr = 0; + error = parsecode(func, stream, &codeptr); + if (error) goto cleanup; + + fz_dropstream(stream); + + return nil; + +cleanup: + fz_dropstream(stream); + if (error) return error; + return fz_throw("syntaxerror: postscript calculator"); +} + +static fz_error * +evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr) +{ + fz_error *error = nil; + int i1, i2; + float r1, r2; + int b1, b2; + + while (1) + { + switch (func->u.p.code[codeptr].type) + { + case PSINT: + SAFE_PUSHINT(st, func->u.p.code[codeptr++].u.i); + break; + + case PSREAL: + SAFE_PUSHREAL(st, func->u.p.code[codeptr++].u.f); + break; + + case PSOPERATOR: + switch (func->u.p.code[codeptr++].u.op) + { + case PSOABS: + if (pstopisint(st)) { + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, abs(i1)); + } else { + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, fabs(r1)); + } + break; + + case PSOADD: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, i1 + i2); + } else { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, r1 + r2); + } + break; + + case PSOAND: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, i1 & i2); + } else { + SAFE_POPBOOL(st, &b2); + SAFE_POPBOOL(st, &b1); + SAFE_PUSHBOOL(st, b1 && b2); + } + break; + + case PSOATAN: + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, atan2(r1, r2)*RADIAN); + break; + + case PSOBITSHIFT: + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + if (i2 > 0) { + SAFE_PUSHINT(st, i1 << i2); + } else if (i2 < 0) { + SAFE_PUSHINT(st, (int)((unsigned int)i1 >> i2)); + } else { + SAFE_PUSHINT(st, i1); + } + break; + + case PSOCEILING: + if (!pstopisint(st)) { + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, ceil(r1)); + } + break; + + case PSOCOPY: + SAFE_POPINT(st, &i1); + SAFE_COPY(st, i1); + break; + + case PSOCOS: + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, cos(r1/RADIAN)); + break; + + case PSOCVI: + if (!pstopisint(st)) { + SAFE_POPNUM(st, &r1); + SAFE_PUSHINT(st, (int)r1); + } + break; + + case PSOCVR: + if (!pstopisreal(st)) { + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, r1); + } + break; + + case PSODIV: + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, r1 / r2); + break; + + case PSODUP: + SAFE_COPY(st, 1); + break; + + case PSOEQ: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHBOOL(st, i1 == i2); + } else if (pstoptwoarenums(st)) { + SAFE_POPNUM(st, &r1); + SAFE_POPNUM(st, &r1); + SAFE_PUSHBOOL(st, r1 == r2); + } else { + SAFE_POPBOOL(st, &b2); + SAFE_POPBOOL(st, &b2); + SAFE_PUSHBOOL(st, b1 == b2); + } + break; + + case PSOEXCH: + psroll(st, 2, 1); + break; + + case PSOEXP: + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, pow(r1, r2)); + break; + + case PSOFALSE: + SAFE_PUSHBOOL(st, 0); + break; + + case PSOFLOOR: + if (!pstopisint(st)) { + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, floor(r1)); + } + break; + + case PSOGE: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHBOOL(st, i1 >= i2); + } else { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHBOOL(st, r1 >= r2); + } + break; + + case PSOGT: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHBOOL(st, i1 > i2); + } else { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHBOOL(st, r1 > r2); + } + break; + + case PSOIDIV: + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, i1 / i2); + break; + + case PSOINDEX: + SAFE_POPINT(st, &i1); + SAFE_INDEX(st, i1); + break; + + case PSOLE: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHBOOL(st, i1 <= i2); + } else { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHBOOL(st, r1 <= r2); + } + break; + + case PSOLN: + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, log(r1)); + break; + + case PSOLOG: + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, log10(r1)); + break; + + case PSOLT: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHBOOL(st, i1 < i2); + } else { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHBOOL(st, r1 < r2); + } + break; + + case PSOMOD: + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, i1 % i2); + break; + + case PSOMUL: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + /*~ should check for out-of-range, and push a real instead */ + SAFE_PUSHINT(st, i1 * i2); + } else { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, r1 * r2); + } + break; + + case PSONE: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHBOOL(st, i1 != i2); + } else if (pstoptwoarenums(st)) { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHBOOL(st, r1 != r2); + } else { + SAFE_POPBOOL(st, &b2); + SAFE_POPBOOL(st, &b1); + SAFE_PUSHBOOL(st, b1 != b2); + } + break; + + case PSONEG: + if (pstopisint(st)) { + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, -i1); + } else { + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, -r1); + } + break; + + case PSONOT: + if (pstopisint(st)) { + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, ~i1); + } else { + SAFE_POPBOOL(st, &b1); + SAFE_PUSHBOOL(st, !b1); + } + break; + + case PSOOR: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, i1 | i2); + } else { + SAFE_POPBOOL(st, &b2); + SAFE_POPBOOL(st, &b1); + SAFE_PUSHBOOL(st, b1 || b2); + } + break; + + case PSOPOP: + SAFE_POP(st); + break; + + case PSOROLL: + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + psroll(st, i1, i2); + break; + + case PSOROUND: + if (!pstopisint(st)) { + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, (r1 >= 0) ? floor(r1 + 0.5) : ceil(r1 - 0.5)); + } + break; + + case PSOSIN: + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, sin(r1/RADIAN)); + break; + + case PSOSQRT: + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, sqrt(r1)); + break; + + case PSOSUB: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, i1 - i2); + } else { + SAFE_POPNUM(st, &r2); + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, r1 - r2); + } + break; + + case PSOTRUE: + SAFE_PUSHBOOL(st, 1); + break; + + case PSOTRUNCATE: + if (!pstopisint(st)) { + SAFE_POPNUM(st, &r1); + SAFE_PUSHREAL(st, (r1 >= 0) ? floor(r1) : ceil(r1)); + } + break; + + case PSOXOR: + if (pstoptwoareints(st)) { + SAFE_POPINT(st, &i2); + SAFE_POPINT(st, &i1); + SAFE_PUSHINT(st, i1 ^ i2); + } else { + SAFE_POPBOOL(st, &b2); + SAFE_POPBOOL(st, &b1); + SAFE_PUSHBOOL(st, b1 ^ b2); + } + break; + + case PSOIF: + SAFE_POPBOOL(st, &b1); + if (b1) { + evalpostscriptfunc(func, st, codeptr + 2); + } + codeptr = func->u.p.code[codeptr + 1].u.block; + break; + + case PSOIFELSE: + SAFE_POPBOOL(st, &b1); + if (b1) { + evalpostscriptfunc(func, st, codeptr + 2); + } else { + evalpostscriptfunc(func, st, func->u.p.code[codeptr].u.block); + } + codeptr = func->u.p.code[codeptr + 1].u.block; + break; + + case PSORETURN: + return nil; + } + break; + + default: + return fz_throw("syntaxerror: postscript calculator"); + break; + } + } + +cleanup: + return error; +} + +/* + * Sample function + */ + +static int bps_supported[] = { 1, 2, 4, 8, 12, 16, 24, 32 }; + +static fz_error * +loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gen) +{ + fz_error *error = nil; + fz_stream *stream; + fz_obj *obj; + int samplecount; + int bps; + int i; + + pdf_logrsrc("sampled function {\n", oid, gen); + + func->u.sa.samples = nil; + + obj = fz_dictgets(dict, "Size"); + if (!fz_isarray(obj) || fz_arraylen(obj) != func->m) + goto cleanup0; + for (i = 0; i < func->m; ++i) + func->u.sa.size[i] = fz_toint(fz_arrayget(obj, i)); + + obj = fz_dictgets(dict, "BitsPerSample"); + if (!fz_isint(obj)) + goto cleanup0; + func->u.sa.bps = bps = fz_toint(obj); + + pdf_logrsrc("bsp %d\n", bps); + + for (i = 0; i < nelem(bps_supported); ++i) + if (bps == bps_supported[i]) + break; + if (i == nelem(bps_supported)) + goto cleanup0; + + obj = fz_dictgets(dict, "Encode"); + if (fz_isarray(obj)) + { + if (fz_arraylen(obj) != func->m * 2) + goto cleanup0; + for (i = 0; i < func->m; ++i) + { + func->u.sa.encode[i][0] = fz_toreal(fz_arrayget(obj, i*2+0)); + func->u.sa.encode[i][1] = fz_toreal(fz_arrayget(obj, i*2+1)); + } + } + else + { + for (i = 0; i < func->m; ++i) + { + func->u.sa.encode[i][0] = 0; + func->u.sa.encode[i][1] = func->u.sa.size[i] - 1; + } + } + + obj = fz_dictgets(dict, "Decode"); + if (fz_isarray(obj)) + { + if (fz_arraylen(obj) != func->n * 2) + goto cleanup0; + for (i = 0; i < func->n; ++i) + { + func->u.sa.decode[i][0] = fz_toreal(fz_arrayget(obj, i*2+0)); + func->u.sa.decode[i][1] = fz_toreal(fz_arrayget(obj, i*2+1)); + } + } + else + { + for (i = 0; i < func->n; ++i) + { + func->u.sa.decode[i][0] = func->range[i][0]; + func->u.sa.decode[i][1] = func->range[i][1]; + } + } + + for (i = 0, samplecount = func->n; i < func->m; ++i) + samplecount *= func->u.sa.size[i]; + + pdf_logrsrc("samplecount %d\n", samplecount); + + func->u.sa.samples = fz_malloc(samplecount * sizeof(int)); + if (!func->u.sa.samples) + { + error = fz_outofmem; + goto cleanup0; + } + + error = pdf_openstream(&stream, xref, oid, gen); + if (error) + goto cleanup0; + + /* read samples */ + { + unsigned int bitmask = (1 << bps) - 1; + unsigned int buf = 0; + int bits = 0; + int s; + + for (i = 0; i < samplecount; ++i) + { + if (fz_peekbyte(stream) == EOF) + { + error = fz_throw("syntaxerror: too few samples in function"); + goto cleanup1; + } + + if (bps == 8) { + s = fz_readbyte(stream); + } + else if (samplecount == 16) { + s = fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); + } + else if (samplecount == 32) { + s = fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); + } + else { + while (bits < bps) + { + buf = (buf << 8) | (fz_readbyte(stream) & 0xff); + bits += 8; + } + s = (buf >> (bits - bps)) & bitmask; + bits -= bps; + } + + func->u.sa.samples[i] = s; + } + } + + fz_dropstream(stream); + + pdf_logrsrc("}\n"); + + return nil; + +cleanup1: + fz_dropstream(stream); +cleanup0: + if (error) return error; + return fz_throw("syntaxerror: sample function"); +} + +static fz_error * +evalsamplefunc(pdf_function *func, float *in, float *out) +{ + float x; + int e[2][MAXM]; + float efrac[MAXM]; + float static0[1 << 4]; + float static1[1 << 4]; + float *s0 = static0; + float *s1 = static1; + int i, j, k; + int idx; + + /* encode input coordinates */ + for (i = 0; i < func->m; i++) + { + x = CLAMP(in[i], func->domain[i][0], func->domain[i][1]); + x = LERP(x, func->domain[i][0], func->domain[i][1], + func->u.sa.encode[i][0], func->u.sa.encode[i][1]); + x = CLAMP(x, 0, func->u.sa.size[i] - 1); + e[0][i] = floor(x); + e[1][i] = ceil(x); + efrac[i] = x - floor(x); + } + + if (func->m > 4) + { + s0 = fz_malloc((1 << func->m) * 2 * sizeof(float)); + s1 = s0 + (1 << func->m); + if (!s0) + return fz_outofmem; + } + + /* FIXME i think this is wrong... test with 2 samples it gets wrong idxs */ + for (i = 0; i < func->n; i++) + { + /* pull 2^m values out of the sample array */ + for (j = 0; j < (1 << func->m); ++j) + { + idx = 0; + for (k = func->m - 1; k >= 0; --k) + idx = idx * func->u.sa.size[k] + e[(j >> k) & 1][k]; + idx = idx * func->n + i; + s0[j] = func->u.sa.samples[idx]; + } + + /* do m sets of interpolations */ + for (j = 0; j < func->m; ++j) + { + for (k = 0; k < (1 << (func->m - j)); k += 2) + s1[k >> 1] = (1 - efrac[j]) * s0[k] + efrac[j] * s0[k+1]; + memcpy(s0, s1, (1 << (func->m - j - 1)) * sizeof(float)); + } + + /* decode output values */ + out[i] = LERP(s0[0], 0, (1 << func->u.sa.bps) - 1, + func->u.sa.decode[i][0], func->u.sa.decode[i][1]); + out[i] = CLAMP(out[i], func->range[i][0], func->range[i][1]); + } + + if (func->m > 4) + fz_free(s0); + + return nil; +} + +/* + * Exponential function + */ + +static fz_error * +loadexponentialfunc(pdf_function *func, fz_obj *dict) +{ + fz_error *error = nil; + fz_obj *obj; + int i; + + pdf_logrsrc("exponential function {\n"); + + if (func->m != 1) + goto cleanup; + + obj = fz_dictgets(dict, "N"); + if (!fz_isint(obj) && !fz_isreal(obj)) + goto cleanup; + func->u.e.n = fz_toreal(obj); + pdf_logrsrc("n %g\n", func->u.e.n); + + obj = fz_dictgets(dict, "C0"); + if (fz_isarray(obj)) + { + func->n = fz_arraylen(obj); + for (i = 0; i < func->n; ++i) + func->u.e.c0[i] = fz_toreal(fz_arrayget(obj, i)); + pdf_logrsrc("c0 %d\n", func->n); + } + else + { + func->n = 1; + func->u.e.c0[0] = 0; + } + + obj = fz_dictgets(dict, "C1"); + if (fz_isarray(obj)) + { + if (fz_arraylen(obj) != func->n) + goto cleanup; + for (i = 0; i < func->n; ++i) + func->u.e.c1[i] = fz_toreal(fz_arrayget(obj, i)); + pdf_logrsrc("c1 %d\n", func->n); + } + else + { + if (func->n != 1) + goto cleanup; + func->u.e.c1[0] = 1; + } + + pdf_logrsrc("}\n"); + + return nil; + +cleanup: + if (error) return error; + return fz_throw("syntaxerror: exponential function"); +} + +static fz_error * +evalexponentialfunc(pdf_function *func, float in, float *out) +{ + fz_error *error = nil; + float x = in; + float tmp; + int i; + + x = CLAMP(x, func->domain[0][0], func->domain[0][1]); + + /* constraint */ + if (func->u.e.n != (int)func->u.e.n && x < 0) + goto cleanup; + if (func->u.e.n < 0 && x == 0) + goto cleanup; + + tmp = pow(x, func->u.e.n); + for (i = 0; i < func->n; ++i) + { + out[i] = func->u.e.c0[i] + tmp * (func->u.e.c1[i] - func->u.e.c0[i]); + if (func->hasrange) + out[i] = CLAMP(out[i], func->range[i][0], func->range[i][1]); + } + + return nil; + +cleanup: + if (error) return error; + return fz_throw("rangecheck: exponential function"); +} + +/* + * Stitching function + */ + +static fz_error * +loadstitchingfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict) +{ + pdf_function **funcs = func->u.st.funcs; + fz_error *error = nil; + fz_obj *obj; + fz_obj *sub; + fz_obj *num; + int k; + int i; + + pdf_logrsrc("stitching {\n"); + + func->u.st.k = 0; + + if (func->m != 1) + goto cleanup; + + obj = fz_dictgets(dict, "Functions"); + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + + k = fz_arraylen(obj); + func->u.st.k = k; + + pdf_logrsrc("k %d\n", func->u.st.k); + assert(k < MAXK); + + for (i = 0; i < k; ++i) + { + sub = fz_arrayget(obj, i); + error = pdf_loadfunction(funcs + i, xref, sub); + if (error) + goto cleanup; + if (funcs[i]->m != 1 || funcs[i]->n != funcs[0]->n) + goto cleanup; + } + + if (!func->n) + func->n = funcs[0]->n; + else if (func->n != funcs[0]->n) + goto cleanup; + + fz_dropobj(obj); + } + + obj = fz_dictgets(dict, "Bounds"); + { + error = pdf_resolve(&obj, xref); + if (error) + goto cleanup; + + if (!fz_isarray(obj) || fz_arraylen(obj) != k - 1) + goto cleanup; + + for (i = 0; i < k-1; ++i) + { + num = fz_arrayget(obj, i); + if (!fz_isint(num) && !fz_isreal(num)) + goto cleanup; + func->u.st.bounds[i] = fz_toreal(num); + if (i && func->u.st.bounds[i-1] >= func->u.st.bounds[i]) + goto cleanup; + } + + if (k != 1 && + (func->domain[0][0] >= func->u.st.bounds[0] || + func->domain[0][1] <= func->u.st.bounds[k-2])) + goto cleanup; + + fz_dropobj(obj); + } + + obj = fz_dictgets(dict, "Encode"); + { + error = pdf_resolve(&obj, xref); + if (!fz_isarray(obj) || fz_arraylen(obj) != k * 2) + goto cleanup; + for (i = 0; i < k; ++i) + { + func->u.st.encode[i][0] = fz_toreal(fz_arrayget(obj, i*2+0)); + func->u.st.encode[i][1] = fz_toreal(fz_arrayget(obj, i*2+1)); + } + fz_dropobj(obj); + } + + pdf_logrsrc("}\n"); + + return nil; + +cleanup: + fz_dropobj(obj); + if (error) + return error; + return fz_throw("syntaxerror: stitching function"); +} + +static fz_error* +evalstitchingfunc(pdf_function *func, float in, float *out) +{ + fz_error *error = nil; + float low, high; + int k = func->u.st.k; + float *bounds = func->u.st.bounds; + int i; + + in = CLAMP(in, func->domain[0][0], func->domain[0][1]); + + for (i = 0; i < k - 1; ++i) + { + if (in < bounds[i]) + break; + } + + if (i == 0 && k == 1) + { + low = func->domain[0][0]; + high = func->domain[0][1]; + } + else if (i == 0) + { + low = func->domain[0][0]; + high = bounds[0]; + } + else if (i == k - 1) + { + low = bounds[k-2]; + high = func->domain[0][1]; + } + else + { + low = bounds[i-1]; + high = bounds[i]; + } + + in = LERP(in, low, high, func->u.st.encode[i][0], func->u.st.encode[i][1]); + + error = pdf_evalfunction(func->u.st.funcs[i], &in, 1, out, func->n); + if (error) + return error; + + return nil; +} + +/* + * Common + */ + +pdf_function * +pdf_keepfunction(pdf_function *func) +{ + func->refs ++; + return func; +} + +void +pdf_dropfunction(pdf_function *func) +{ + int i; + if (--func->refs == 0) + { + switch(func->type) + { + case SAMPLE: + fz_free(func->u.sa.samples); + break; + case EXPONENTIAL: + break; + case STITCHING: + for (i = 0; i < func->u.st.k; ++i) + pdf_dropfunction(func->u.st.funcs[i]); + break; + case POSTSCRIPT: + fz_free(func->u.p.code); + break; + } + fz_free(func); + } +} + +fz_error * +pdf_loadfunction(pdf_function **funcp, pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + pdf_function *func; + fz_obj *dict; + fz_obj *obj; + int i; + + if ((*funcp = pdf_finditem(xref->store, PDF_KFUNCTION, ref))) + { + pdf_keepfunction(*funcp); + return nil; + } + + pdf_logrsrc("load function %d %d {\n", fz_tonum(ref), fz_togen(ref)); + + func = fz_malloc(sizeof(pdf_function)); + if (!func) + return fz_outofmem; + + func->refs = 1; + + dict = ref; + error = pdf_resolve(&dict, xref); + if (error) + { + fz_free(func); + goto cleanup; + } + + obj = fz_dictgets(dict, "FunctionType"); + func->type = fz_toint(obj); + + pdf_logrsrc("type %d\n", func->type); + + /* required for all */ + obj = fz_dictgets(dict, "Domain"); + func->m = fz_arraylen(obj) / 2; + for (i = 0; i < func->m; i++) + { + func->domain[i][0] = fz_toreal(fz_arrayget(obj, i * 2 + 0)); + func->domain[i][1] = fz_toreal(fz_arrayget(obj, i * 2 + 1)); + } + pdf_logrsrc("domain %d\n", func->m); + + /* required for type0 and type4, optional otherwise */ + obj = fz_dictgets(dict, "Range"); + if (fz_isarray(obj)) + { + func->hasrange = 1; + func->n = fz_arraylen(obj) / 2; + for (i = 0; i < func->n; i++) + { + func->range[i][0] = fz_toreal(fz_arrayget(obj, i * 2 + 0)); + func->range[i][1] = fz_toreal(fz_arrayget(obj, i * 2 + 1)); + } + pdf_logrsrc("range %d\n", func->n); + } + else + { + func->hasrange = 0; + func->n = 0; + } + + assert(func->m < MAXM); + assert(func->n < MAXN); + + switch(func->type) + { + case SAMPLE: + error = loadsamplefunc(func, xref, dict, fz_tonum(ref), fz_togen(ref)); + if (error) + goto cleanup; + break; + + case EXPONENTIAL: + error = loadexponentialfunc(func, dict); + if (error) + goto cleanup; + break; + + case STITCHING: + error = loadstitchingfunc(func, xref, dict); + if (error) + goto cleanup; + break; + + case POSTSCRIPT: + error = loadpostscriptfunc(func, xref, dict, fz_tonum(ref), fz_togen(ref)); + if (error) + goto cleanup; + break; + + default: + error = fz_throw("syntaxerror: unknown function type"); + goto cleanup; + } + + fz_dropobj(dict); + + pdf_logrsrc("}\n"); + + error = pdf_storeitem(xref->store, PDF_KFUNCTION, ref, func); + if (error) + goto cleanup; + + *funcp = func; + return nil; + +cleanup: + fz_dropobj(dict); + pdf_dropfunction(func); + return error; +} + +fz_error * +pdf_evalfunction(pdf_function *func, float *in, int inlen, float *out, int outlen) +{ + fz_error *error = nil; + int i; + + if (func->m != inlen || func->n != outlen) + return fz_throw("rangecheck: function argument count mismatch"); + + switch(func->type) + { + case SAMPLE: + return evalsamplefunc(func, in, out); + case EXPONENTIAL: + return evalexponentialfunc(func, *in, out); + case STITCHING: + return evalstitchingfunc(func, *in, out); + + case POSTSCRIPT: + { + psstack st; + psinitstack(&st); + + for (i = 0; i < func->m; ++i) + SAFE_PUSHREAL(&st, in[i]); + + error = evalpostscriptfunc(func, &st, 0); + if (error) + return error; + + for (i = func->n - 1; i >= 0; --i) + { + SAFE_POPNUM(&st, out+i); + out[i] = CLAMP(out[i], func->range[i][0], func->range[i][1]); + } + } + return nil; + } + +cleanup: + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_image.c b/rosapps/smartpdf/fitz/mupdf/pdf_image.c new file mode 100644 index 00000000000..d2efcc6cc98 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_image.c @@ -0,0 +1,538 @@ +/* + * TODO: this needs serious cleaning up, and error checking. + */ + +#include "fitz.h" +#include "mupdf.h" + +void pdf_dropimage(fz_image *fzimg) +{ + pdf_image *img = (pdf_image*)fzimg; + fz_dropbuffer(img->samples); + if (img->mask) + fz_dropimage(img->mask); +} + +fz_error * +pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, + fz_obj *rdb, fz_obj *dict, fz_stream *file) +{ + fz_error *error; + pdf_image *img; + fz_filter *filter; + fz_obj *f; + fz_obj *cs; + fz_obj *d; + int ismask; + int i; + + img = fz_malloc(sizeof(pdf_image)); + if (!img) + return fz_outofmem; + + pdf_logimage("load inline image %p {\n", img); + + img->super.refs = 1; + img->super.loadtile = pdf_loadtile; + img->super.drop = pdf_dropimage; + img->super.n = 0; + img->super.a = 0; + img->indexed = nil; + img->usecolorkey = 0; + img->mask = nil; + + img->super.w = fz_toint(fz_dictgetsa(dict, "Width", "W")); + img->super.h = fz_toint(fz_dictgetsa(dict, "Height", "H")); + img->bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC")); + ismask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM")); + d = fz_dictgetsa(dict, "Decode", "D"); + cs = fz_dictgetsa(dict, "ColorSpace", "CS"); + + pdf_logimage("size %dx%d %d\n", img->super.w, img->super.h, img->bpc); + + if (ismask) + { + pdf_logimage("is mask\n"); + img->super.cs = nil; + img->super.n = 0; + img->super.a = 1; + img->bpc = 1; + } + + if (cs) + { + img->super.cs = nil; + + if (fz_isname(cs)) + { + fz_obj *csd = fz_dictgets(rdb, "ColorSpace"); + if (csd) + { + fz_obj *cso = fz_dictget(csd, cs); + img->super.cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, cso); + if (img->super.cs) + fz_keepcolorspace(img->super.cs); + } + } + + if (!img->super.cs) + { + /* XXX danger! danger! does this resolve? */ + error = pdf_loadcolorspace(&img->super.cs, xref, cs); + if (error) + return error; + } + + if (!strcmp(img->super.cs->name, "Indexed")) + { + pdf_logimage("indexed\n"); + img->indexed = (pdf_indexed*)img->super.cs; + img->super.cs = img->indexed->base; + } + + pdf_logimage("colorspace %s\n", img->super.cs->name); + + img->super.n = img->super.cs->n; + img->super.a = 0; + } + + if (fz_isarray(d)) + { + pdf_logimage("decode array\n"); + if (img->indexed) + for (i = 0; i < 2; i++) + img->decode[i] = fz_toreal(fz_arrayget(d, i)); + else + for (i = 0; i < (img->super.n + img->super.a) * 2; i++) + img->decode[i] = fz_toreal(fz_arrayget(d, i)); + } + else + { + if (img->indexed) + for (i = 0; i < 2; i++) + img->decode[i] = i & 1 ? (1 << img->bpc) - 1 : 0; + else + for (i = 0; i < (img->super.n + img->super.a) * 2; i++) + img->decode[i] = i & 1; + } + + if (img->indexed) + img->stride = (img->super.w * img->bpc + 7) / 8; + else + img->stride = (img->super.w * (img->super.n + img->super.a) * img->bpc + 7) / 8; + + /* load image data */ + + f = fz_dictgetsa(dict, "Filter", "F"); + if (f) + { + fz_stream *tempfile; + + error = pdf_buildinlinefilter(&filter, dict); + if (error) + return error; + + if (filter == nil) + goto thereisnofilter; + + error = fz_openrfilter(&tempfile, filter, file); + if (error) + return error; + + i = fz_readall(&img->samples, tempfile); + if (i < 0) + return fz_ioerror(tempfile); + + fz_dropfilter(filter); + fz_dropstream(tempfile); + } + else + { +thereisnofilter: + error = fz_newbuffer(&img->samples, img->super.h * img->stride); + if (error) + return error; + + i = fz_read(file, img->samples->bp, img->super.h * img->stride); + if (i < 0) + return fz_ioerror(file); + + img->samples->wp += img->super.h * img->stride; + } + + /* 0 means opaque and 1 means transparent, so we invert to get alpha */ + if (ismask) + { + unsigned char *p; + for (p = img->samples->bp; p < img->samples->ep; p++) + *p = ~*p; + } + + pdf_logimage("}\n"); + + *imgp = img; + return nil; +} + +static void +loadcolorkey(int *colorkey, int bpc, int indexed, fz_obj *obj) +{ + int scale = 1; + int i; + + pdf_logimage("keyed mask\n"); + + if (!indexed) + { + switch (bpc) + { + case 1: scale = 255; break; + case 2: scale = 85; break; + case 4: scale = 17; break; + case 8: scale = 1; break; + } + } + + for (i = 0; i < fz_arraylen(obj); i++) + colorkey[i] = fz_toint(fz_arrayget(obj, i)) * scale; +} + +/* TODO error cleanup */ +fz_error * +pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + pdf_image *img; + pdf_image *mask; + int ismask; + fz_obj *obj; + fz_obj *sub; + int i; + + int w, h, bpc; + int n = 0; + int a = 0; + int usecolorkey = 0; + fz_colorspace *cs = nil; + pdf_indexed *indexed = nil; + int stride; + + if ((*imgp = pdf_finditem(xref->store, PDF_KIMAGE, ref))) + { + fz_keepimage((fz_image*)*imgp); + return nil; + } + + img = fz_malloc(sizeof(pdf_image)); + if (!img) + return fz_outofmem; + + pdf_logimage("load image %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), img); + + /* + * Dimensions, BPC and ColorSpace + */ + + w = fz_toint(fz_dictgets(dict, "Width")); + h = fz_toint(fz_dictgets(dict, "Height")); + bpc = fz_toint(fz_dictgets(dict, "BitsPerComponent")); + + pdf_logimage("size %dx%d %d\n", w, h, bpc); + + cs = nil; + obj = fz_dictgets(dict, "ColorSpace"); + if (obj) + { + cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj); + if (cs) + fz_keepcolorspace(cs); + else + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + + error = pdf_loadcolorspace(&cs, xref, obj); + if (error) + return error; + + fz_dropobj(obj); + } + + if (!strcmp(cs->name, "Indexed")) + { + pdf_logimage("indexed\n"); + indexed = (pdf_indexed*)cs; + cs = indexed->base; + } + n = cs->n; + a = 0; + + pdf_logimage("colorspace %s\n", cs->name); + } + + /* + * ImageMask, Mask and SoftMask + */ + + mask = nil; + + ismask = fz_tobool(fz_dictgets(dict, "ImageMask")); + if (ismask) + { + pdf_logimage("is mask\n"); + bpc = 1; + n = 0; + a = 1; + } + + obj = fz_dictgets(dict, "SMask"); + if (fz_isindirect(obj)) + { + pdf_logimage("has soft mask\n"); + + error = pdf_loadindirect(&sub, xref, obj); + if (error) + return error; + + error = pdf_loadimage(&mask, xref, sub, obj); + fz_dropobj(sub); + if (error) + return error; + + if (mask->super.cs != pdf_devicegray) + return fz_throw("syntaxerror: SMask must be DeviceGray"); + + mask->super.cs = 0; + mask->super.n = 0; + mask->super.a = 1; + } + + obj = fz_dictgets(dict, "Mask"); + if (fz_isindirect(obj)) + { + error = pdf_loadindirect(&sub, xref, obj); + if (error) + return error; + if (fz_isarray(sub)) + { + usecolorkey = 1; + loadcolorkey(img->colorkey, bpc, indexed != nil, sub); + } + else + { + pdf_logimage("has mask\n"); + error = pdf_loadimage(&mask, xref, sub, obj); + if (error) + return error; + } + fz_dropobj(sub); + } + else if (fz_isarray(obj)) + { + usecolorkey = 1; + loadcolorkey(img->colorkey, bpc, indexed != nil, obj); + } + + /* + * Decode + */ + + obj = fz_dictgets(dict, "Decode"); + if (fz_isarray(obj)) + { + pdf_logimage("decode array\n"); + if (indexed) + for (i = 0; i < 2; i++) + img->decode[i] = fz_toreal(fz_arrayget(obj, i)); + else + for (i = 0; i < (n + a) * 2; i++) + img->decode[i] = fz_toreal(fz_arrayget(obj, i)); + } + else + { + if (indexed) + for (i = 0; i < 2; i++) + img->decode[i] = i & 1 ? (1 << bpc) - 1 : 0; + else + for (i = 0; i < (n + a) * 2; i++) + img->decode[i] = i & 1; + } + + /* + * Load samples + */ + + if (indexed) + stride = (w * bpc + 7) / 8; + else + stride = (w * (n + a) * bpc + 7) / 8; + + error = pdf_loadstream(&img->samples, xref, fz_tonum(ref), fz_togen(ref)); + if (error) + { + /* TODO: colorspace? */ + fz_free(img); + return error; + } + + if (img->samples->wp - img->samples->bp < stride * h) + { + /* TODO: colorspace? */ + fz_dropbuffer(img->samples); + fz_free(img); + return fz_throw("syntaxerror: truncated image data"); + } + + /* 0 means opaque and 1 means transparent, so we invert to get alpha */ + if (ismask) + { + unsigned char *p; + for (p = img->samples->bp; p < img->samples->ep; p++) + *p = ~*p; + } + + /* + * Create image object + */ + img->super.refs = 1; + img->super.loadtile = pdf_loadtile; + img->super.drop = pdf_dropimage; + img->super.cs = cs; + img->super.w = w; + img->super.h = h; + img->super.n = n; + img->super.a = a; + img->indexed = indexed; + img->stride = stride; + img->bpc = bpc; + img->mask = (fz_image*)mask; + img->usecolorkey = usecolorkey; + + pdf_logimage("}\n"); + + error = pdf_storeitem(xref->store, PDF_KIMAGE, ref, img); + if (error) + { + fz_dropimage((fz_image*)img); + return error; + } + + *imgp = img; + return nil; +} + +static void +maskcolorkey(fz_pixmap *pix, int *colorkey) +{ + unsigned char *p = pix->samples; + int i, k, t; + for (i = 0; i < pix->w * pix->h; i++) + { + t = 1; + for (k = 1; k < pix->n; k++) + if (p[k] < colorkey[k * 2 - 2] || p[k] > colorkey[k * 2 - 1]) + t = 0; + if (t) + for (k = 0; k < pix->n; k++) + p[k] = 0; + p += pix->n; + } +} + +static void +maskcolorkeyindexed(fz_pixmap *ind, fz_pixmap *pix, int *colorkey) +{ + unsigned char *s = ind->samples; + unsigned char *d = pix->samples; + int i, k; + for (i = 0; i < pix->w * pix->h; i++) + { + if (s[0] >= colorkey[0] && s[0] <= colorkey[1]) + for (k = 0; k < pix->n; k++) + d[k] = 0; + d[0] = 255; + s += ind->n; + d += pix->n; + } +} + +fz_error * +pdf_loadtile(fz_image *img, fz_pixmap *tile) +{ + pdf_image *src = (pdf_image*)img; + void (*tilefunc)(unsigned char*,int,unsigned char*, int, int, int, int); + fz_error *error; + + assert(tile->n == img->n + 1); + assert(tile->x >= 0); + assert(tile->y >= 0); + assert(tile->x + tile->w <= img->w); + assert(tile->y + tile->h <= img->h); + + switch (src->bpc) + { + case 1: tilefunc = fz_loadtile1; break; + case 2: tilefunc = fz_loadtile2; break; + case 4: tilefunc = fz_loadtile4; break; + case 8: tilefunc = fz_loadtile8; break; + default: + return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc); + } + + if (src->indexed) + { + fz_pixmap *tmp; + int x, y, k, i; + int bpcfact = 1; + + error = fz_newpixmap(&tmp, tile->x, tile->y, tile->w, tile->h, 1); + if (error) + return error; + + switch (src->bpc) + { + case 1: bpcfact = 255; break; + case 2: bpcfact = 85; break; + case 4: bpcfact = 17; break; + case 8: bpcfact = 1; break; + } + + tilefunc(src->samples->rp, src->stride, + tmp->samples, tmp->w, + tmp->w, tmp->h, 0); + + for (y = 0; y < tile->h; y++) + { + for (x = 0; x < tile->w; x++) + { + tile->samples[(y * tile->w + x) * tile->n] = 255; + i = tmp->samples[y * tile->w + x] / bpcfact; + i = CLAMP(i, 0, src->indexed->high); + for (k = 0; k < src->indexed->base->n; k++) + { + tile->samples[(y * tile->w + x) * tile->n + k + 1] = + src->indexed->lookup[i * src->indexed->base->n + k]; + } + } + } + + if (src->usecolorkey) + maskcolorkeyindexed(tmp, tile, src->colorkey); + + fz_droppixmap(tmp); + } + + else + { + tilefunc(src->samples->rp, src->stride, + tile->samples, tile->w * tile->n, + img->w * (img->n + img->a), img->h, img->a ? 0 : img->n); + if (src->usecolorkey) + maskcolorkey(tile, src->colorkey); + fz_decodetile(tile, !img->a, src->decode); + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_interpret.c b/rosapps/smartpdf/fitz/mupdf/pdf_interpret.c new file mode 100644 index 00000000000..ad9ab10c6ae --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_interpret.c @@ -0,0 +1,1207 @@ +#include +#include + +fz_error * +pdf_newcsi(pdf_csi **csip, int maskonly) +{ + fz_error *error; + pdf_csi *csi; + fz_node *node; + + csi = *csip = fz_malloc(sizeof(pdf_csi)); + if (!csi) + return fz_outofmem; + + pdf_initgstate(&csi->gstate[0]); + + csi->gtop = 0; + csi->top = 0; + csi->array = nil; + csi->xbalance = 0; + + error = fz_newpathnode(&csi->path); + if (error) { + fz_free(csi); + return error; + } + + error = fz_newtree(&csi->tree); + if (error) { + fz_dropnode((fz_node*)csi->path); + fz_free(csi); + return error; + } + + error = fz_newovernode(&node); + csi->tree->root = node; + csi->gstate[0].head = node; + + if (maskonly) + { + csi->gstate[0].fill.kind = PDF_MNONE; + csi->gstate[0].stroke.kind = PDF_MNONE; + } + + csi->clip = 0; + + csi->textclip = nil; + csi->textmode = 0; + csi->text = nil; + csi->tm = fz_identity(); + csi->tlm = fz_identity(); + + return nil; +} + +static void +clearstack(pdf_csi *csi) +{ + int i; + for (i = 0; i < csi->top; i++) + fz_dropobj(csi->stack[i]); + csi->top = 0; +} + +static fz_error * +gsave(pdf_csi *csi) +{ + if (csi->gtop == 31) + return fz_throw("gstate overflow in content stream"); + + memcpy(&csi->gstate[csi->gtop + 1], &csi->gstate[csi->gtop], sizeof(pdf_gstate)); + + csi->gtop ++; + + if (csi->gstate[csi->gtop].fill.cs) + fz_keepcolorspace(csi->gstate[csi->gtop].fill.cs); + if (csi->gstate[csi->gtop].stroke.cs) + fz_keepcolorspace(csi->gstate[csi->gtop].stroke.cs); + + return nil; +} + +static fz_error * +grestore(pdf_csi *csi) +{ + if (csi->gtop == 0) + return fz_throw("gstate underflow in content stream"); + + if (csi->gstate[csi->gtop].fill.cs) + fz_dropcolorspace(csi->gstate[csi->gtop].fill.cs); + if (csi->gstate[csi->gtop].stroke.cs) + fz_dropcolorspace(csi->gstate[csi->gtop].stroke.cs); + + csi->gtop --; + + return nil; +} + +void +pdf_dropcsi(pdf_csi *csi) +{ + while (csi->gtop) + grestore(csi); + + if (csi->gstate[csi->gtop].fill.cs) + fz_dropcolorspace(csi->gstate[csi->gtop].fill.cs); + if (csi->gstate[csi->gtop].stroke.cs) + fz_dropcolorspace(csi->gstate[csi->gtop].stroke.cs); + + if (csi->path) fz_dropnode((fz_node*)csi->path); + if (csi->clip) fz_dropnode((fz_node*)csi->clip); + if (csi->textclip) fz_dropnode((fz_node*)csi->textclip); + if (csi->text) fz_dropnode((fz_node*)csi->text); + if (csi->array) fz_dropobj(csi->array); + + clearstack(csi); + + fz_free(csi); +} + +/* + * Do some magic to call the xobject subroutine. + * Push gstate, set transform, clip, run, pop gstate. + */ + +static fz_error * +runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj) +{ + fz_error *error; + fz_node *transform; + fz_stream *file; + + /* gsave */ + error = gsave(csi); + if (error) + return error; + + /* push transform */ + + error = fz_newtransformnode(&transform, xobj->matrix); + if (error) + return error; + + error = pdf_addtransform(csi->gstate + csi->gtop, transform); + if (error) + { + fz_dropnode(transform); + return error; + } + + /* run contents */ + + xobj->contents->rp = xobj->contents->bp; + + error = fz_openrbuffer(&file, xobj->contents); + if (error) + return error; + + error = pdf_runcsi(csi, xref, xobj->resources, file); + + fz_dropstream(file); + + if (error) + return error; + + /* grestore */ + error = grestore(csi); + if (error) + return error; + + return nil; +} + +/* + * Decode inline image and insert into page. + */ + +static fz_error * +runinlineimage(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_stream *file, fz_obj *dict) +{ + fz_error *error; + pdf_image *img = NULL; + char buf[256]; + int token; + int len; + + error = pdf_loadinlineimage(&img, xref, rdb, dict, file); + if (error) + return error; + + token = pdf_lex(file, buf, sizeof buf, &len); + if (token != PDF_TKEYWORD || strcmp("EI", buf)) + fz_warn("syntaxerror: corrupt inline image"); + + error = pdf_showimage(csi, img); + fz_dropimage((fz_image*)img); + return error; +} + +/* + * Set gstate params from an ExtGState dictionary. + */ + +static fz_error * +runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate) +{ + int i, k; + + for (i = 0; i < fz_dictlen(extgstate); i++) + { + fz_obj *key = fz_dictgetkey(extgstate, i); + fz_obj *val = fz_dictgetval(extgstate, i); + char *s = fz_toname(key); + + if (!strcmp(s, "Font")) + { + if (fz_isarray(val) && fz_arraylen(val) == 2) + { + gstate->font = pdf_finditem(xref->store, PDF_KFONT, fz_arrayget(val, 0)); + if (!gstate->font) + return fz_throw("syntaxerror: missing font resource"); + gstate->size = fz_toreal(fz_arrayget(val, 1)); + } + else + return fz_throw("syntaxerror in ExtGState/Font"); + } + + else if (!strcmp(s, "LW")) + gstate->linewidth = fz_toreal(val); + else if (!strcmp(s, "LC")) + gstate->linecap = fz_toint(val); + else if (!strcmp(s, "LJ")) + gstate->linejoin = fz_toint(val); + else if (!strcmp(s, "ML")) + gstate->miterlimit = fz_toreal(val); + + else if (!strcmp(s, "D")) + { + if (fz_isarray(val) && fz_arraylen(val) == 2) + { + fz_obj *dashes = fz_arrayget(val, 0); + gstate->dashlen = MAX(fz_arraylen(dashes), 32); + for (k = 0; k < gstate->dashlen; k++) + gstate->dashlist[k] = fz_toreal(fz_arrayget(dashes, k)); + gstate->dashphase = fz_toreal(fz_arrayget(val, 1)); + } + else + return fz_throw("syntaxerror in ExtGState/D"); + } + } + + return nil; +} + +/* + * The meat of the interpreter... + */ + +static fz_error * +runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf) +{ + pdf_gstate *gstate = csi->gstate + csi->gtop; + fz_error *error; + float a, b, c, d, e, f; + float x, y, w, h; + fz_matrix m; + float v[FZ_MAXCOLORS]; + int what; + int i; + + if (strlen(buf) > 1) + { + if (!strcmp(buf, "BX")) + { + if (csi->top != 0) + goto syntaxerror; + csi->xbalance ++; + } + + else if (!strcmp(buf, "EX")) + { + if (csi->top != 0) + goto syntaxerror; + csi->xbalance --; + } + + else if (!strcmp(buf, "MP")) + { + if (csi->top != 1) + goto syntaxerror; + } + + else if (!strcmp(buf, "DP")) + { + if (csi->top != 2) + goto syntaxerror; + } + + else if (!strcmp(buf, "BMC")) + { + if (csi->top != 1) + goto syntaxerror; + } + + else if (!strcmp(buf, "BDC")) + { + if (csi->top != 2) + goto syntaxerror; + } + + else if (!strcmp(buf, "EMC")) + { + if (csi->top != 0) + goto syntaxerror; + } + + else if (!strcmp(buf, "cm")) + { + fz_matrix m; + fz_node *transform; + + if (csi->top != 6) + goto syntaxerror; + + m.a = fz_toreal(csi->stack[0]); + m.b = fz_toreal(csi->stack[1]); + m.c = fz_toreal(csi->stack[2]); + m.d = fz_toreal(csi->stack[3]); + m.e = fz_toreal(csi->stack[4]); + m.f = fz_toreal(csi->stack[5]); + + error = fz_newtransformnode(&transform, m); + if (error) return error; + error = pdf_addtransform(gstate, transform); + if (error) + { + fz_dropnode(transform); + return error; + } + } + + else if (!strcmp(buf, "ri")) + { + if (csi->top != 1) + goto syntaxerror; + } + + else if (!strcmp(buf, "gs")) + { + fz_obj *dict; + fz_obj *obj; + + if (csi->top != 1) + goto syntaxerror; + + dict = fz_dictgets(rdb, "ExtGState"); + if (!dict) + return fz_throw("syntaxerror: missing extgstate resource"); + + obj = fz_dictget(dict, csi->stack[0]); + if (!obj) + return fz_throw("syntaxerror: missing extgstate resource"); + + runextgstate(gstate, xref, obj); + } + + else if (!strcmp(buf, "re")) + { + if (csi->top != 4) + goto syntaxerror; + x = fz_toreal(csi->stack[0]); + y = fz_toreal(csi->stack[1]); + w = fz_toreal(csi->stack[2]); + h = fz_toreal(csi->stack[3]); + error = fz_moveto(csi->path, x, y); + if (error) return error; + error = fz_lineto(csi->path, x + w, y); + if (error) return error; + error = fz_lineto(csi->path, x + w, y + h); + if (error) return error; + error = fz_lineto(csi->path, x, y + h); + if (error) return error; + error = fz_closepath(csi->path); + if (error) return error; + } + + else if (!strcmp(buf, "f*")) + { + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 0, 1, 0, 1); + if (error) return error; + } + + else if (!strcmp(buf, "B*")) + { + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 0, 1, 1, 1); + if (error) return error; + } + + else if (!strcmp(buf, "b*")) + { + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 1, 1, 1, 1); + if (error) return error; + } + + else if (!strcmp(buf, "W*")) + { + if (csi->top != 0) + goto syntaxerror; + csi->clip = 1; + } + + else if (!strcmp(buf, "cs")) + { + what = PDF_MFILL; + goto Lsetcolorspace; + } + + else if (!strcmp(buf, "CS")) + { + fz_colorspace *cs; + fz_obj *obj; + + what = PDF_MSTROKE; + +Lsetcolorspace: + if (csi->top != 1) + goto syntaxerror; + + obj = csi->stack[0]; + + if (!strcmp(fz_toname(obj), "Pattern")) + { + error = pdf_setpattern(csi, what, nil, nil); + if (error) return error; + } + + else + { + if (!strcmp(fz_toname(obj), "DeviceGray")) + cs = pdf_devicegray; + else if (!strcmp(fz_toname(obj), "DeviceRGB")) + cs = pdf_devicergb; + else if (!strcmp(fz_toname(obj), "DeviceCMYK")) + cs = pdf_devicecmyk; + else + { + fz_obj *dict = fz_dictgets(rdb, "ColorSpace"); + if (!dict) + return fz_throw("syntaxerror: missing colorspace resource"); + obj = fz_dictget(dict, obj); + if (!obj) + return fz_throw("syntaxerror: missing colorspace resource"); + + cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj); + if (!cs) + return fz_throw("syntaxerror: missing colorspace resource"); + } + + error = pdf_setcolorspace(csi, what, cs); + if (error) return error; + } + } + + else if (!strcmp(buf, "sc") || !strcmp(buf, "scn")) + { + what = PDF_MFILL; + goto Lsetcolor; + } + + else if (!strcmp(buf, "SC") || !strcmp(buf, "SCN")) + { + pdf_material *mat; + pdf_pattern *pat; + fz_shade *shd; + fz_obj *dict; + fz_obj *obj; + + what = PDF_MSTROKE; + +Lsetcolor: + mat = what == PDF_MSTROKE ? &gstate->stroke : &gstate->fill; + + if (fz_isname(csi->stack[csi->top - 1])) + mat->kind = PDF_MPATTERN; + + switch (mat->kind) + { + case PDF_MNONE: + return fz_throw("syntaxerror: cannot set color in mask objects"); + + case PDF_MINDEXED: + if (csi->top != 1) + goto syntaxerror; + v[0] = fz_toreal(csi->stack[0]); + error = pdf_setcolor(csi, what, v); + if (error) return error; + break; + + case PDF_MCOLOR: + case PDF_MLAB: + if (csi->top != mat->cs->n) + goto syntaxerror; + for (i = 0; i < csi->top; i++) + v[i] = fz_toreal(csi->stack[i]); + error = pdf_setcolor(csi, what, v); + if (error) return error; + break; + + case PDF_MPATTERN: + for (i = 0; i < csi->top - 1; i++) + v[i] = fz_toreal(csi->stack[i]); + + dict = fz_dictgets(rdb, "Pattern"); + if (!dict) + return fz_throw("syntaxerror: missing pattern resource"); + + obj = fz_dictget(dict, csi->stack[csi->top - 1]); + if (!obj) + return fz_throw("syntaxerror: missing pattern resource"); + + pat = pdf_finditem(xref->store, PDF_KPATTERN, obj); + if (pat) + { + error = pdf_setpattern(csi, what, pat, csi->top == 1 ? nil : v); + if (error) return error; + } + + shd = pdf_finditem(xref->store, PDF_KSHADE, obj); + if (shd) + { + error = pdf_setshade(csi, what, shd); + if (error) return error; + } + + if (!pat && !shd) + return fz_throw("syntaxerror: missing pattern resource"); + + break; + + case PDF_MSHADE: + return fz_throw("syntaxerror: cannot set color in shade objects"); + } + } + + else if (!strcmp(buf, "rg")) + { + if (csi->top != 3) + goto syntaxerror; + + v[0] = fz_toreal(csi->stack[0]); + v[1] = fz_toreal(csi->stack[1]); + v[2] = fz_toreal(csi->stack[2]); + + error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicergb); + if (error) return error; + error = pdf_setcolor(csi, PDF_MFILL, v); + if (error) return error; + } + + else if (!strcmp(buf, "RG")) + { + if (csi->top != 3) + goto syntaxerror; + + v[0] = fz_toreal(csi->stack[0]); + v[1] = fz_toreal(csi->stack[1]); + v[2] = fz_toreal(csi->stack[2]); + + error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicergb); + if (error) return error; + error = pdf_setcolor(csi, PDF_MSTROKE, v); + if (error) return error; + } + + else if (!strcmp(buf, "BT")) + { + if (csi->top != 0) + goto syntaxerror; + csi->tm = fz_identity(); + csi->tlm = fz_identity(); + } + + else if (!strcmp(buf, "ET")) + { + if (csi->top != 0) + goto syntaxerror; + + error = pdf_flushtext(csi); + if (error) + return error; + + if (csi->textclip) + { + error = pdf_addclipmask(gstate, csi->textclip); + if (error) return error; + csi->textclip = nil; + } + } + + else if (!strcmp(buf, "Tc")) + { + if (csi->top != 1) + goto syntaxerror; + gstate->charspace = fz_toreal(csi->stack[0]); + } + + else if (!strcmp(buf, "Tw")) + { + if (csi->top != 1) + goto syntaxerror; + gstate->wordspace = fz_toreal(csi->stack[0]); + } + + else if (!strcmp(buf, "Tz")) + { + if (csi->top != 1) + goto syntaxerror; + + error = pdf_flushtext(csi); + if (error) return error; + + gstate->scale = fz_toreal(csi->stack[0]) / 100.0; + } + + else if (!strcmp(buf, "TL")) + { + if (csi->top != 1) + goto syntaxerror; + gstate->leading = fz_toreal(csi->stack[0]); + } + + else if (!strcmp(buf, "Tf")) + { + fz_obj *dict; + fz_obj *obj; + + if (csi->top != 2) + goto syntaxerror; + + dict = fz_dictgets(rdb, "Font"); + if (!dict) + return fz_throw("syntaxerror: missing font resource"); + + obj = fz_dictget(dict, csi->stack[0]); + if (!obj) + return fz_throw("syntaxerror: missing font resource"); + + gstate->font = pdf_finditem(xref->store, PDF_KFONT, obj); + if (!gstate->font) + return fz_throw("syntaxerror: missing font resource"); + + gstate->size = fz_toreal(csi->stack[1]); + } + + else if (!strcmp(buf, "Tr")) + { + if (csi->top != 1) + goto syntaxerror; + gstate->render = fz_toint(csi->stack[0]); + } + + else if (!strcmp(buf, "Ts")) + { + if (csi->top != 1) + goto syntaxerror; + gstate->rise = fz_toreal(csi->stack[0]); + } + + else if (!strcmp(buf, "Td")) + { + if (csi->top != 2) + goto syntaxerror; + m = fz_translate(fz_toreal(csi->stack[0]), fz_toreal(csi->stack[1])); + csi->tlm = fz_concat(m, csi->tlm); + csi->tm = csi->tlm; + } + + else if (!strcmp(buf, "TD")) + { + if (csi->top != 2) + goto syntaxerror; + gstate->leading = -fz_toreal(csi->stack[1]); + m = fz_translate(fz_toreal(csi->stack[0]), fz_toreal(csi->stack[1])); + csi->tlm = fz_concat(m, csi->tlm); + csi->tm = csi->tlm; + } + + else if (!strcmp(buf, "Tm")) + { + if (csi->top != 6) + goto syntaxerror; + + error = pdf_flushtext(csi); + if (error) return error; + + csi->tm.a = fz_toreal(csi->stack[0]); + csi->tm.b = fz_toreal(csi->stack[1]); + csi->tm.c = fz_toreal(csi->stack[2]); + csi->tm.d = fz_toreal(csi->stack[3]); + csi->tm.e = fz_toreal(csi->stack[4]); + csi->tm.f = fz_toreal(csi->stack[5]); + csi->tlm = csi->tm; + } + + else if (!strcmp(buf, "T*")) + { + if (csi->top != 0) + goto syntaxerror; + m = fz_translate(0, -gstate->leading); + csi->tlm = fz_concat(m, csi->tlm); + csi->tm = csi->tlm; + } + + else if (!strcmp(buf, "Tj")) + { + if (csi->top != 1) + goto syntaxerror; + error = pdf_showtext(csi, csi->stack[0]); + if (error) return error; + } + + else if (!strcmp(buf, "TJ")) + { + if (csi->top != 1) + goto syntaxerror; + error = pdf_showtext(csi, csi->stack[0]); + if (error) return error; + } + + else if (!strcmp(buf, "Do")) + { + fz_obj *dict; + fz_obj *obj; + pdf_image *img; + pdf_xobject *xobj; + + if (csi->top != 1) + goto syntaxerror; + + dict = fz_dictgets(rdb, "XObject"); + if (!dict) +{ +fz_debugobj(rdb); + return fz_throw("syntaxerror: missing xobject resource"); +} + + obj = fz_dictget(dict, csi->stack[0]); + if (!obj) + return fz_throw("syntaxerror: missing xobject resource"); + + img = pdf_finditem(xref->store, PDF_KIMAGE, obj); + xobj = pdf_finditem(xref->store, PDF_KXOBJECT, obj); + + if (!img && !xobj) + return fz_throw("syntaxerror: missing xobject resource"); + + if (img) + { + error = pdf_showimage(csi, img); + if (error) + return error; + } + + if (xobj) + { + clearstack(csi); + error = runxobject(csi, xref, xobj); + if (error) + return error; + } + } + + else if (!strcmp(buf, "sh")) + { + fz_obj *dict; + fz_obj *obj; + fz_shade *shd; + + if (csi->top != 1) + goto syntaxerror; + + dict = fz_dictgets(rdb, "Shading"); + if (!dict) + return fz_throw("syntaxerror: missing shading resource"); + + obj = fz_dictget(dict, csi->stack[csi->top - 1]); + if (!obj) + return fz_throw("syntaxerror: missing shading resource"); + + shd = pdf_finditem(xref->store, PDF_KSHADE, obj); + if (!shd) + return fz_throw("syntaxerror: missing shading resource"); + + error = pdf_addshade(gstate, shd); + if (error) return error; + } + + else if (!strcmp(buf, "d0")) + { + fz_warn("unimplemented: d0 charprocs"); + } + + else if (!strcmp(buf, "d1")) + { + } + + else + if (!csi->xbalance) goto syntaxerror; + } + + else switch (buf[0]) + { + + case 'q': + if (csi->top != 0) + goto syntaxerror; + error = gsave(csi); + if (error) + return error; + break; + + case 'Q': + if (csi->top != 0) + goto syntaxerror; + error = grestore(csi); + if (error) + return error; + break; + + case 'w': + if (csi->top != 1) + goto syntaxerror; + gstate->linewidth = fz_toreal(csi->stack[0]); + break; + + case 'J': + if (csi->top != 1) + goto syntaxerror; + gstate->linecap = fz_toint(csi->stack[0]); + break; + + case 'j': + if (csi->top != 1) + goto syntaxerror; + gstate->linejoin = fz_toint(csi->stack[0]); + break; + + case 'M': + if (csi->top != 1) + goto syntaxerror; + gstate->miterlimit = fz_toreal(csi->stack[0]); + break; + + case 'd': + if (csi->top != 2) + goto syntaxerror; + { + int i; + fz_obj *array = csi->stack[0]; + gstate->dashlen = fz_arraylen(array); + if (gstate->dashlen > 32) + return fz_throw("rangecheck: too large dash pattern"); + for (i = 0; i < gstate->dashlen; i++) + gstate->dashlist[i] = fz_toreal(fz_arrayget(array, i)); + gstate->dashphase = fz_toreal(csi->stack[1]); + } + break; + + case 'i': + if (csi->top != 1) + goto syntaxerror; + /* flatness */ + break; + + case 'm': + if (csi->top != 2) + goto syntaxerror; + a = fz_toreal(csi->stack[0]); + b = fz_toreal(csi->stack[1]); + return fz_moveto(csi->path, a, b); + + case 'l': + if (csi->top != 2) + goto syntaxerror; + a = fz_toreal(csi->stack[0]); + b = fz_toreal(csi->stack[1]); + return fz_lineto(csi->path, a, b); + + case 'c': + if (csi->top != 6) + goto syntaxerror; + a = fz_toreal(csi->stack[0]); + b = fz_toreal(csi->stack[1]); + c = fz_toreal(csi->stack[2]); + d = fz_toreal(csi->stack[3]); + e = fz_toreal(csi->stack[4]); + f = fz_toreal(csi->stack[5]); + return fz_curveto(csi->path, a, b, c, d, e, f); + + case 'v': + if (csi->top != 4) + goto syntaxerror; + a = fz_toreal(csi->stack[0]); + b = fz_toreal(csi->stack[1]); + c = fz_toreal(csi->stack[2]); + d = fz_toreal(csi->stack[3]); + return fz_curvetov(csi->path, a, b, c, d); + + case 'y': + if (csi->top != 4) + goto syntaxerror; + a = fz_toreal(csi->stack[0]); + b = fz_toreal(csi->stack[1]); + c = fz_toreal(csi->stack[2]); + d = fz_toreal(csi->stack[3]); + return fz_curvetoy(csi->path, a, b, c, d); + + case 'h': + if (csi->top != 0) + goto syntaxerror; + return fz_closepath(csi->path); + + case 'S': + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 0, 0, 1, 0); + if (error) return error; + break; + + case 's': + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 1, 0, 1, 0); + if (error) return error; + break; + + case 'F': + case 'f': + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 0, 1, 0, 0); + if (error) return error; + break; + + case 'B': + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 0, 1, 1, 0); + if (error) return error; + break; + + case 'b': + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 1, 1, 1, 0); + if (error) return error; + break; + + case 'n': + if (csi->top != 0) + goto syntaxerror; + error = pdf_showpath(csi, 0, 0, 0, 0); + if (error) return error; + break; + + case 'W': + if (csi->top != 0) + goto syntaxerror; + csi->clip = 1; + break; + + case 'g': + if (csi->top != 1) + goto syntaxerror; + + v[0] = fz_toreal(csi->stack[0]); + error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicegray); + if (error) return error; + error = pdf_setcolor(csi, PDF_MFILL, v); + if (error) return error; + break; + + case 'G': + if (csi->top != 1) + goto syntaxerror; + + v[0] = fz_toreal(csi->stack[0]); + error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicegray); + if (error) return error; + error = pdf_setcolor(csi, PDF_MSTROKE, v); + if (error) return error; + break; + + case 'k': + if (csi->top != 4) + goto syntaxerror; + + v[0] = fz_toreal(csi->stack[0]); + v[1] = fz_toreal(csi->stack[1]); + v[2] = fz_toreal(csi->stack[2]); + v[3] = fz_toreal(csi->stack[3]); + + error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicecmyk); + if (error) return error; + error = pdf_setcolor(csi, PDF_MFILL, v); + if (error) return error; + break; + + case 'K': + if (csi->top != 4) + goto syntaxerror; + + v[0] = fz_toreal(csi->stack[0]); + v[1] = fz_toreal(csi->stack[1]); + v[2] = fz_toreal(csi->stack[2]); + v[3] = fz_toreal(csi->stack[3]); + + error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicecmyk); + if (error) return error; + error = pdf_setcolor(csi, PDF_MSTROKE, v); + if (error) return error; + break; + + case '\'': + if (csi->top != 1) + goto syntaxerror; + + m = fz_translate(0, -gstate->leading); + csi->tlm = fz_concat(m, csi->tlm); + csi->tm = csi->tlm; + + error = pdf_showtext(csi, csi->stack[0]); + if (error) return error; + break; + + case '"': + if (csi->top != 3) + goto syntaxerror; + + gstate->wordspace = fz_toreal(csi->stack[0]); + gstate->charspace = fz_toreal(csi->stack[1]); + + m = fz_translate(0, -gstate->leading); + csi->tlm = fz_concat(m, csi->tlm); + csi->tm = csi->tlm; + + error = pdf_showtext(csi, csi->stack[2]); + if (error) return error; + break; + + default: + if (!csi->xbalance) goto syntaxerror; + } + + return nil; + +syntaxerror: + return fz_throw("syntaxerror in content stream: '%s'", buf); +} + +fz_error * +pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_stream *file) +{ + fz_error *error; + char buf[65536]; + int token, len; + fz_obj *obj; + + while (1) + { + if (csi->top == 31) + return fz_throw("stack overflow in content stream"); + + token = pdf_lex(file, buf, sizeof buf, &len); + + if (csi->array) + { + if (token == PDF_TCARRAY) + { + csi->stack[csi->top] = csi->array; + csi->array = nil; + csi->top ++; + } + else if (token == PDF_TINT || token == PDF_TREAL) + { + error = fz_newreal(&obj, atof(buf)); + if (error) return error; + error = fz_arraypush(csi->array, obj); + fz_dropobj(obj); + if (error) return error; + } + else if (token == PDF_TSTRING) + { + error = fz_newstring(&obj, buf, len); + if (error) return error; + error = fz_arraypush(csi->array, obj); + fz_dropobj(obj); + if (error) return error; + } + else if (token == PDF_TEOF) + { + return nil; + } + else + { + clearstack(csi); + return fz_throw("syntaxerror in content stream"); + } + } + + else switch (token) + { + case PDF_TEOF: + return nil; + + /* optimize text-object array parsing */ + case PDF_TOARRAY: + error = fz_newarray(&csi->array, 8); + if (error) return error; + break; + + case PDF_TODICT: + error = pdf_parsedict(&csi->stack[csi->top], file, buf, sizeof buf); + if (error) return error; + csi->top ++; + break; + + case PDF_TNAME: + error = fz_newname(&csi->stack[csi->top], buf); + if (error) return error; + csi->top ++; + break; + + case PDF_TINT: + error = fz_newint(&csi->stack[csi->top], atoi(buf)); + if (error) return error; + csi->top ++; + break; + + case PDF_TREAL: + error = fz_newreal(&csi->stack[csi->top], atof(buf)); + if (error) return error; + csi->top ++; + break; + + case PDF_TSTRING: + error = fz_newstring(&csi->stack[csi->top], buf, len); + if (error) return error; + csi->top ++; + break; + + case PDF_TTRUE: + error = fz_newbool(&csi->stack[csi->top], 1); + if (error) return error; + csi->top ++; + break; + + case PDF_TFALSE: + error = fz_newbool(&csi->stack[csi->top], 0); + if (error) return error; + csi->top ++; + break; + + case PDF_TNULL: + error = fz_newnull(&csi->stack[csi->top]); + if (error) return error; + csi->top ++; + break; + + case PDF_TKEYWORD: + if (!strcmp(buf, "BI")) + { + fz_obj *obj; + + error = pdf_parsedict(&obj, file, buf, sizeof buf); + if (error) + return error; + + /* read whitespace after ID keyword */ + fz_readbyte(file); + + error = runinlineimage(csi, xref, rdb, file, obj); + fz_dropobj(obj); + if (error) + return error; + } + else + { + error = runkeyword(csi, xref, rdb, buf); + if (error) return error; + clearstack(csi); + } + break; + + default: + clearstack(csi); + return fz_throw("syntaxerror in content stream"); + } + } +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_lex.c b/rosapps/smartpdf/fitz/mupdf/pdf_lex.c new file mode 100644 index 00000000000..115cd0f81d6 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_lex.c @@ -0,0 +1,350 @@ +#include +#include + +static inline int iswhite(int ch) +{ + return ch == '\000' || + ch == '\011' || + ch == '\012' || + ch == '\014' || + ch == '\015' || + ch == '\040'; +} + +static inline int isdelim(int ch) +{ + return ch == '(' || ch == ')' || + ch == '<' || ch == '>' || + ch == '[' || ch == ']' || + ch == '{' || ch == '}' || + ch == '/' || + ch == '%'; +} + +static inline int isregular(int ch) +{ + return !isdelim(ch) && !iswhite(ch) && ch != EOF; +} + +static inline int isnumber(int ch) +{ + return ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9'); +} + +static inline int ishex(int ch) +{ + return (ch >= '0' && ch <= '9') || + (ch >= 'A' && ch <= 'F') || + (ch >= 'a' && ch <= 'f'); +} + +static inline int fromhex(int ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 0xA; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 0xA; + return 0; +} + +static inline void +lexwhite(fz_stream *f) +{ + int c; + while (1) + { + c = fz_peekbyte(f); + if (!iswhite(c)) + break; + fz_readbyte(f); + } +} + +static inline void +lexcomment(fz_stream *f) +{ + int c; + while (1) + { + c = fz_readbyte(f); + if (c == '\012') break; + if (c == '\015') break; + if (c == EOF) break; + } +} + +static void +lexnumber(fz_stream *f, unsigned char *s, int n) +{ + while (n > 1) + { + if (!isnumber(fz_peekbyte(f))) + break; + *s++ = fz_readbyte(f); + n--; + } + *s = '\0'; +} + +static void +lexname(fz_stream *f, unsigned char *s, int n) +{ + unsigned char *p = s; + unsigned char *q = s; + + while (n > 1) + { + if (!isregular(fz_peekbyte(f))) + break; + *s++ = fz_readbyte(f); + n--; + } + *s = '\0'; + + while (*p) + { + if (p[0] == '#' && p[1] != 0 && p[2] != 0) + { + *q++ = fromhex(p[1]) * 16 + fromhex(p[2]); + p += 3; + } + else + *q++ = *p++; + } + *q = '\0'; +} + +static int +lexstring(fz_stream *f, unsigned char *buf, int n) +{ + unsigned char *s = buf; + unsigned char *e = buf + n; + int bal = 1; + int oct; + int c; + + while (s < e) + { + c = fz_readbyte(f); + if (c == '(') + { + bal++; + *s++ = c; + } + else if (c == ')') + { + bal --; + if (bal == 0) + break; + *s++ = c; + } + else if (c == '\\') + { + c = fz_readbyte(f); + if (c == 'n') *s++ = '\n'; + else if (c == 'r') *s++ = '\r'; + else if (c == 't') *s++ = '\t'; + else if (c == 'b') *s++ = '\b'; + else if (c == 'f') *s++ = '\f'; + else if (c == '(') *s++ = '('; + else if (c == ')') *s++ = ')'; + else if (c == '\\') *s++ = '\\'; + + else if (c >= '0' && c <= '9') + { + oct = c - '0'; + c = fz_peekbyte(f); + if (c >= '0' && c <= '9') + { + fz_readbyte(f); + oct = oct * 8 + (c - '0'); + c = fz_peekbyte(f); + if (c >= '0' && c <= '9') + { + fz_readbyte(f); + oct = oct * 8 + (c - '0'); + } + } + *s++ = oct; + } + + else if (c == '\n') + ; + else if (c == '\r') + { + c = fz_peekbyte(f); + if (c == '\n') + fz_readbyte(f); + } + else *s++ = c; + } + else + { + *s++ = c; + } + } + + return s - buf; +} + +static int +lexhexstring(fz_stream *f, unsigned char *buf, int n) +{ + unsigned char *s = buf; + unsigned char *e = buf + n; + int a = 0, x = 0; + int c; + + while (s < e) + { + c = fz_readbyte(f); + if (c == '>') + break; + else if (iswhite(c)) + continue; + else if (ishex(c)) + { + if (x) + { + *s++ = a * 16 + fromhex(c); + x = !x; + } + else + { + a = fromhex(c); + x = !x; + } + } + else + break; + } + + return s - buf; +} + +static int +tokenfromkeyword(char *key) +{ + if (!strcmp(key, "R")) return PDF_TR; + if (!strcmp(key, "true")) return PDF_TTRUE; + if (!strcmp(key, "false")) return PDF_TFALSE; + if (!strcmp(key, "null")) return PDF_TNULL; + + if (!strcmp(key, "obj")) return PDF_TOBJ; + if (!strcmp(key, "endobj")) return PDF_TENDOBJ; + if (!strcmp(key, "stream")) return PDF_TSTREAM; + if (!strcmp(key, "endstream")) return PDF_TENDSTREAM; + + if (!strcmp(key, "xref")) return PDF_TXREF; + if (!strcmp(key, "trailer")) return PDF_TTRAILER; + if (!strcmp(key, "startxref")) return PDF_TSTARTXREF; + + return PDF_TKEYWORD; +} + +int +pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl) +{ + int c; + + while (1) + { + c = fz_peekbyte(f); + + if (c == EOF) + return PDF_TEOF; + + else if (iswhite(c)) + lexwhite(f); + + else if (c == '%') + lexcomment(f); + + + else if (c == '/') + { + fz_readbyte(f); + lexname(f, buf, n); + *sl = strlen(buf); + return PDF_TNAME; + } + + else if (c == '(') + { + fz_readbyte(f); + *sl = lexstring(f, buf, n); + return PDF_TSTRING; + } + + else if (c == '<') + { + fz_readbyte(f); + c = fz_peekbyte(f); + if (c == '<') + { + fz_readbyte(f); + return PDF_TODICT; + } + else + { + *sl = lexhexstring(f, buf, n); + return PDF_TSTRING; + } + } + + else if (c == '>') + { + fz_readbyte(f); + c = fz_readbyte(f); + if (c == '>') + return PDF_TCDICT; + return PDF_TERROR; + } + + else if (c == '[') + { + fz_readbyte(f); + return PDF_TOARRAY; + } + + else if (c == ']') + { + fz_readbyte(f); + return PDF_TCARRAY; + } + + else if (c == '{') + { + fz_readbyte(f); + return PDF_TOBRACE; + } + + else if (c == '}') + { + fz_readbyte(f); + return PDF_TCBRACE; + } + + else if (isnumber(c)) + { + lexnumber(f, buf, n); + *sl = strlen(buf); + if (strchr(buf, '.')) + return PDF_TREAL; + return PDF_TINT; + } + + else if (isregular(c)) + { + lexname(f, buf, n); + *sl = strlen(buf); + return tokenfromkeyword(buf); + } + + else + return PDF_TERROR; + } +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_nametree.c b/rosapps/smartpdf/fitz/mupdf/pdf_nametree.c new file mode 100644 index 00000000000..706c0e500ed --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_nametree.c @@ -0,0 +1,134 @@ +#include +#include + +static fz_error * +loadnametreenode(fz_obj *tree, pdf_xref *xref, fz_obj *node) +{ + fz_error *error; + fz_obj *names; + fz_obj *kids; + fz_obj *key; + fz_obj *val; + int i, len; + + error = pdf_resolve(&node, xref); + if (error) + return error; + + names = fz_dictgets(node, "Names"); + if (names) + { + error = pdf_resolve(&names, xref); + if (error) + goto cleanup; + + len = fz_arraylen(names) / 2; + + for (i = 0; i < len; ++i) + { + key = fz_arrayget(names, i * 2 + 0); + val = fz_arrayget(names, i * 2 + 1); + error = fz_dictput(tree, key, val); + if (error) + { + fz_dropobj(names); + goto cleanup; + } + } + + fz_dropobj(names); + } + + kids = fz_dictgets(node, "Kids"); + if (kids) + { + error = pdf_resolve(&kids, xref); + if (error) + goto cleanup; + + len = fz_arraylen(kids); + for (i = 0; i < len; ++i) + { + error = loadnametreenode(tree, xref, fz_arrayget(kids, i)); + if (error) + { + fz_dropobj(kids); + goto cleanup; + } + } + + fz_dropobj(kids); + } + + fz_dropobj(node); + return nil; + +cleanup: + fz_dropobj(node); + return error; +} + +fz_error * +pdf_loadnametree(fz_obj **dictp, pdf_xref *xref, fz_obj *root) +{ + fz_error *error; + fz_obj *tree; + + error = fz_newdict(&tree, 128); + if (error) + return error; + + error = loadnametreenode(tree, xref, root); + if (error) + { + fz_dropobj(tree); + return error; + } + + fz_sortdict(tree); + + *dictp = tree; + return nil; +} + +fz_error * +pdf_loadnametrees(pdf_xref *xref) +{ + fz_error *error; + fz_obj *names; + fz_obj *dests; + + /* PDF 1.1 */ + dests = fz_dictgets(xref->root, "Dests"); + if (dests) + { + error = pdf_resolve(&dests, xref); + if (error) + return error; + xref->dests = dests; + return nil; + } + + /* PDF 1.2 */ + names = fz_dictgets(xref->root, "Names"); + if (names) + { + error = pdf_resolve(&names, xref); + if (error) + return error; + dests = fz_dictgets(names, "Dests"); + if (dests) + { + error = pdf_loadnametree(&xref->dests, xref, dests); + if (error) + { + fz_dropobj(names); + return error; + } + } + fz_dropobj(names); + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_open.c b/rosapps/smartpdf/fitz/mupdf/pdf_open.c new file mode 100644 index 00000000000..b06a290174f --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_open.c @@ -0,0 +1,595 @@ +#include +#include + +static inline int iswhite(int ch) +{ + return ch == '\000' || ch == '\011' || ch == '\012' || + ch == '\014' || ch == '\015' || ch == '\040'; +} + +/* + * magic version tag and startxref + */ + +static fz_error * +loadversion(pdf_xref *xref) +{ + char buf[20]; + int n; + + n = fz_seek(xref->file, 0, 0); + if (n < 0) + return fz_ioerror(xref->file); + + fz_readline(xref->file, buf, sizeof buf); + if (memcmp(buf, "%PDF-", 5) != 0) + return fz_throw("syntaxerror: corrupt version marker"); + + xref->version = atof(buf + 5); + + pdf_logxref("version %g\n", xref->version); + + return nil; +} + +static fz_error * +readstartxref(pdf_xref *xref) +{ + char buf[1024]; + int t, n; + int i; + + t = fz_seek(xref->file, 0, 2); + if (t == -1) + return fz_ioerror(xref->file); + + t = fz_seek(xref->file, MAX(0, t - ((int)sizeof buf)), 0); + if (t == -1) + return fz_ioerror(xref->file); + + n = fz_read(xref->file, buf, sizeof buf); + if (n == -1) + return fz_ioerror(xref->file); + + for (i = n - 9; i >= 0; i--) + { + if (memcmp(buf + i, "startxref", 9) == 0) + { + i += 9; + while (iswhite(buf[i]) && i < n) + i ++; + xref->startxref = atoi(buf + i); + return nil; + } + } + + return fz_throw("syntaxerror: could not find startxref"); +} + +#define WHITE_SPACE_CHARS " \n\t\r" + +static const char *str_find_char(const char *txt, char c) +{ + while (*txt != c) { + if (0 == *txt) + return NULL; + ++txt; + } + return txt; +} + +static int str_contains(const char *str, char c) +{ + const char *pos = str_find_char(str, c); + if (!pos) + return 0; + return 1; +} + +static void str_strip_right(char *txt, const char *to_strip) +{ + char * new_end; + char c; + if (!txt || !to_strip) + return; + if (0 == *txt) + return; + /* point at the last character in the string */ + new_end = txt + strlen(txt) - 1; + for (;;) { + c = *new_end; + if (!str_contains(to_strip, c)) + break; + if (txt == new_end) + break; + --new_end; + } + if (str_contains(to_strip, *new_end)) + new_end[0] = 0; + else + new_end[1] = 0; +} + +static void str_strip_ws_right(char *txt) +{ + str_strip_right(txt, WHITE_SPACE_CHARS); +} + + +/* + * trailer dictionary + */ + +static fz_error * +readoldtrailer(pdf_xref *xref, char *buf, int cap) +{ + int ofs, len; + char *s; + int n; + int t; + int c; + + pdf_logxref("load old xref format trailer\n"); + + fz_readline(xref->file, buf, cap); + str_strip_ws_right(buf); + if (strcmp(buf, "xref") != 0) + return fz_throw("ioerror: missing xref"); + + while (1) + { + c = fz_peekbyte(xref->file); + if (!(c >= '0' && c <= '9')) + break; + + n = fz_readline(xref->file, buf, cap); + if (n < 0) + return fz_ioerror(xref->file); + + s = buf; + ofs = atoi(strsep(&s, " ")); + len = atoi(strsep(&s, " ")); + + /* broken pdfs where the section is not on a separate line */ + if (s && *s != '\0') + fz_seek(xref->file, -(n + buf - s + 2), 1); + + t = fz_tell(xref->file); + if (t < 0) + return fz_ioerror(xref->file); + + n = fz_seek(xref->file, t + 20 * len, 0); + if (n < 0) + return fz_ioerror(xref->file); + } + + t = pdf_lex(xref->file, buf, cap, &n); + if (t != PDF_TTRAILER) + return fz_throw("syntaxerror: expected trailer"); + + t = pdf_lex(xref->file, buf, cap, &n); + if (t != PDF_TODICT) + return fz_throw("syntaxerror: expected trailer dictionary"); + + return pdf_parsedict(&xref->trailer, xref->file, buf, cap); +} + +static fz_error * +readnewtrailer(pdf_xref *xref, char *buf, int cap) +{ + pdf_logxref("load new xref format trailer\n"); + return pdf_parseindobj(&xref->trailer, xref->file, buf, cap, nil, nil, nil); +} + +static fz_error * +readtrailer(pdf_xref *xref, char *buf, int cap) +{ + int n; + int c; + + n = fz_seek(xref->file, xref->startxref, 0); + if (n < 0) + return fz_ioerror(xref->file); + + c = fz_peekbyte(xref->file); + if (c == 'x') + return readoldtrailer(xref, buf, cap); + else if (c >= '0' && c <= '9') + return readnewtrailer(xref, buf, cap); + + return fz_throw("syntaxerror: could not find xref"); +} + +/* + * xref tables + */ + +static fz_error * +readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) +{ + int ofs, len; + char *s; + int n; + int t; + int i; + int c; + + pdf_logxref("load old xref format\n"); + + fz_readline(xref->file, buf, cap); + str_strip_ws_right(buf); + if (strcmp(buf, "xref") != 0) + return fz_throw("syntaxerror: expected xref"); + + while (1) + { + c = fz_peekbyte(xref->file); + if (!(c >= '0' && c <= '9')) + break; + + n = fz_readline(xref->file, buf, cap); + if (n < 0) + return fz_ioerror(xref->file); + + s = buf; + ofs = atoi(strsep(&s, " ")); + len = atoi(strsep(&s, " ")); + + /* broken pdfs where the section is not on a separate line */ + if (s && *s != '\0') + { + fz_warn("syntaxerror: broken xref section"); + fz_seek(xref->file, -(n + buf - s + 2), 1); + } + + for (i = 0; i < len; i++) + { + n = fz_read(xref->file, buf, 20); + if (n < 0) + return fz_ioerror(xref->file); + if (n != 20) + return fz_throw("syntaxerror: truncated xref table"); + if (!xref->table[ofs + i].type) + { + s = buf; + xref->table[ofs + i].ofs = atoi(s); + xref->table[ofs + i].gen = atoi(s + 11); + xref->table[ofs + i].type = s[17]; + } + } + } + + t = pdf_lex(xref->file, buf, cap, &n); + if (t != PDF_TTRAILER) + return fz_throw("syntaxerror: expected trailer"); + t = pdf_lex(xref->file, buf, cap, &n); + if (t != PDF_TODICT) + return fz_throw("syntaxerror: expected trailer dictionary"); + + return pdf_parsedict(trailerp, xref->file, buf, cap); +} + +static fz_error * +readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) +{ + fz_error *error; + fz_stream *stm; + fz_obj *trailer; + fz_obj *obj; + int oid, gen, stmofs; + int size, w0, w1, w2, i0, i1; + int i, n; + + pdf_logxref("load new xref format\n"); + + error = pdf_parseindobj(&trailer, xref->file, buf, cap, &oid, &gen, &stmofs); + if (error) + return error; + + if (oid < 0 || oid >= xref->len) { + error = fz_throw("rangecheck: object id out of range"); + goto cleanup; + } + + xref->table[oid].type = 'n'; + xref->table[oid].gen = gen; + xref->table[oid].obj = fz_keepobj(trailer); + xref->table[oid].stmofs = stmofs; + + obj = fz_dictgets(trailer, "Size"); + if (!obj) { + error = fz_throw("syntaxerror: xref stream missing Size entry"); + goto cleanup; + } + size = fz_toint(obj); + + obj = fz_dictgets(trailer, "W"); + if (!obj) { + error = fz_throw("syntaxerror: xref stream missing W entry"); + goto cleanup; + } + w0 = fz_toint(fz_arrayget(obj, 0)); + w1 = fz_toint(fz_arrayget(obj, 1)); + w2 = fz_toint(fz_arrayget(obj, 2)); + + obj = fz_dictgets(trailer, "Index"); + if (obj) { + i0 = fz_toint(fz_arrayget(obj, 0)); + i1 = fz_toint(fz_arrayget(obj, 1)); + } + else { + i0 = 0; + i1 = size; + } + + if (i0 < 0 || i1 > xref->len) { + error = fz_throw("syntaxerror: xref stream has too many entries"); + goto cleanup; + } + + error = pdf_openstream(&stm, xref, oid, gen); + if (error) + goto cleanup; + + for (i = i0; i < i0 + i1; i++) + { + int a = 0; + int b = 0; + int c = 0; + + if (fz_peekbyte(stm) == EOF) + { + error = fz_throw("syntaxerror: truncated xref stream"); + fz_dropstream(stm); + goto cleanup; + } + + for (n = 0; n < w0; n++) + a = (a << 8) + fz_readbyte(stm); + for (n = 0; n < w1; n++) + b = (b << 8) + fz_readbyte(stm); + for (n = 0; n < w2; n++) + c = (c << 8) + fz_readbyte(stm); + + if (!xref->table[i].type) + { + int t = w0 ? a : 1; + xref->table[i].type = t == 0 ? 'f' : t == 1 ? 'n' : t == 2 ? 'o' : 0; + xref->table[i].ofs = w2 ? b : 0; + xref->table[i].gen = w1 ? c : 0; + } + } + + fz_dropstream(stm); + + *trailerp = trailer; + + return nil; + +cleanup: + fz_dropobj(trailer); + return error; +} + +static fz_error * +readxref(fz_obj **trailerp, pdf_xref *xref, int ofs, char *buf, int cap) +{ + int n; + int c; + + n = fz_seek(xref->file, ofs, 0); + if (n < 0) + return fz_ioerror(xref->file); + + c = fz_peekbyte(xref->file); + if (c == 'x') + return readoldxref(trailerp, xref, buf, cap); + else if (c >= '0' && c <= '9') + return readnewxref(trailerp, xref, buf, cap); + + return fz_throw("syntaxerror: expected xref"); +} + +static fz_error * +readxrefsections(pdf_xref *xref, int ofs, char *buf, int cap) +{ + fz_error *error; + fz_obj *trailer; + fz_obj *prev; + fz_obj *xrefstm; + + error = readxref(&trailer, xref, ofs, buf, cap); + if (error) + return error; + + /* FIXME: do we overwrite free entries properly? */ + xrefstm = fz_dictgets(trailer, "XrefStm"); + if (xrefstm) + { + pdf_logxref("load xrefstm\n"); + error = readxrefsections(xref, fz_toint(xrefstm), buf, cap); + if (error) + goto cleanup; + } + + prev = fz_dictgets(trailer, "Prev"); + if (prev) + { + pdf_logxref("load prev\n"); + error = readxrefsections(xref, fz_toint(prev), buf, cap); + if (error) + goto cleanup; + } + + fz_dropobj(trailer); + return nil; + +cleanup: + fz_dropobj(trailer); + return error; +} + +/* + * compressed object streams + */ + +fz_error * +pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap) +{ + fz_error *error; + fz_stream *stm; + fz_obj *objstm; + int *oidbuf; + int *ofsbuf; + + fz_obj *obj; + int first; + int count; + int i, n, t; + + pdf_logxref("loadobjstm %d %d\n", oid, gen); + + error = pdf_loadobject(&objstm, xref, oid, gen); + if (error) + return error; + + count = fz_toint(fz_dictgets(objstm, "N")); + first = fz_toint(fz_dictgets(objstm, "First")); + + pdf_logxref(" count %d\n", count); + + oidbuf = fz_malloc(count * sizeof(int)); + if (!oidbuf) { error = fz_outofmem; goto cleanupobj; } + + ofsbuf = fz_malloc(count * sizeof(int)); + if (!ofsbuf) { error = fz_outofmem; goto cleanupoid; } + + error = pdf_openstream(&stm, xref, oid, gen); + if (error) + goto cleanupofs; + + for (i = 0; i < count; i++) + { + t = pdf_lex(stm, buf, cap, &n); + if (t != PDF_TINT) + { + error = fz_throw("syntaxerror: corrupt object stream"); + goto cleanupstm; + } + oidbuf[i] = atoi(buf); + + t = pdf_lex(stm, buf, cap, &n); + if (t != PDF_TINT) + { + error = fz_throw("syntaxerror: corrupt object stream"); + goto cleanupstm; + } + ofsbuf[i] = atoi(buf); + } + + n = fz_seek(stm, first, 0); + if (n < 0) + { + error = fz_ioerror(stm); + goto cleanupstm; + } + + for (i = 0; i < count; i++) + { + /* FIXME: seek to first + ofsbuf[i] */ + + error = pdf_parsestmobj(&obj, stm, buf, cap); + if (error) + goto cleanupstm; + + if (oidbuf[i] < 1 || oidbuf[i] >= xref->len) + { + error = fz_throw("rangecheck: object number out of range"); + goto cleanupstm; + } + + if (xref->table[oidbuf[i]].obj) + fz_dropobj(xref->table[oidbuf[i]].obj); + xref->table[oidbuf[i]].obj = obj; + } + + fz_dropstream(stm); + fz_free(ofsbuf); + fz_free(oidbuf); + fz_dropobj(objstm); + return nil; + +cleanupstm: + fz_dropstream(stm); +cleanupofs: + fz_free(ofsbuf); +cleanupoid: + fz_free(oidbuf); +cleanupobj: + fz_dropobj(objstm); + return error; +} + +/* + * open and load xref tables from pdf + */ + +fz_error * +pdf_loadxref(pdf_xref *xref, char *filename) +{ + fz_error *error; + fz_obj *size; + int i; + + char buf[65536]; /* yeowch! */ + + pdf_logxref("loadxref '%s' %p\n", filename, xref); + + error = fz_openrfile(&xref->file, filename); + if (error) + return error; + + error = loadversion(xref); + if (error) + return error; + + error = readstartxref(xref); + if (error) + return error; + + error = readtrailer(xref, buf, sizeof buf); + if (error) + return error; + + size = fz_dictgets(xref->trailer, "Size"); + if (!size) + return fz_throw("syntaxerror: trailer missing Size entry"); + + pdf_logxref(" size %d\n", fz_toint(size)); + + assert(xref->table == nil); + + xref->cap = fz_toint(size); + xref->len = fz_toint(size); + xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry)); + if (!xref->table) + return fz_outofmem; + + for (i = 0; i < xref->len; i++) + { + xref->table[i].ofs = 0; + xref->table[i].gen = 0; + xref->table[i].type = 0; + xref->table[i].mark = 0; + xref->table[i].stmbuf = nil; + xref->table[i].stmofs = 0; + xref->table[i].obj = nil; + } + + error = readxrefsections(xref, xref->startxref, buf, sizeof buf); + if (error) + return error; + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_outline.c b/rosapps/smartpdf/fitz/mupdf/pdf_outline.c new file mode 100644 index 00000000000..c41d96f5810 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_outline.c @@ -0,0 +1,142 @@ +#include +#include + +static fz_error * +loadoutline(pdf_outline **nodep, pdf_xref *xref, fz_obj *dict) +{ + fz_error *error; + pdf_outline *node; + fz_obj *obj; + + node = fz_malloc(sizeof(pdf_outline)); + node->title = ""; + node->link = nil; + node->child = nil; + node->next = nil; + + pdf_logpage("load outline {\n"); + + obj = fz_dictgets(dict, "Title"); + if (obj) + { + error = pdf_toutf8(&node->title, obj); + if (error) + return error; + pdf_logpage("title %s\n", node->title); + } + + if (fz_dictgets(dict, "Dest") || fz_dictgets(dict, "A")) + { + error = pdf_loadlink(&node->link, xref, dict); + if (error) + return error; + } + + obj = fz_dictgets(dict, "First"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = loadoutline(&node->child, xref, obj); + fz_dropobj(obj); + if (error) + return error; + } + + pdf_logpage("}\n"); + + obj = fz_dictgets(dict, "Next"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = loadoutline(&node->next, xref, obj); + fz_dropobj(obj); + if (error) + return error; + } + + *nodep = node; + return nil; +} + +fz_error * +pdf_loadoutline(pdf_outline **nodep, pdf_xref *xref) +{ + fz_error *error; + pdf_outline *node; + fz_obj *obj; + fz_obj *first; + + pdf_logpage("load outlines {\n"); + + node = nil; + + obj = fz_dictgets(xref->root, "Outlines"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + + first = fz_dictgets(obj, "First"); + if (first) + { + error = pdf_resolve(&first, xref); + fz_dropobj(obj); + if (error) + return error; + error = loadoutline(&node, xref, first); + fz_dropobj(first); + if (error) + return error; + } + else + fz_dropobj(obj); + } + + pdf_logpage("}\n"); + + *nodep = node; + return nil; +} + +void +pdf_dropoutline(pdf_outline *outline) +{ + if (outline->child) + pdf_dropoutline(outline->child); + if (outline->next) + pdf_dropoutline(outline->next); + pdf_droplink(outline->link); + fz_free(outline->title); + fz_free(outline); +} + +void +pdf_debugoutline(pdf_outline *outline, int level) +{ + int i; + while (outline) + { + for (i = 0; i < level; i++) + putchar(' '); + + printf("%s ", outline->title); + + if (outline->link) + fz_debugobj(outline->link->dest); + else + printf(""); + + printf("\n"); + + if (outline->child) + pdf_debugoutline(outline->child, level + 2); + + outline = outline->next; + } +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_page.c b/rosapps/smartpdf/fitz/mupdf/pdf_page.c new file mode 100644 index 00000000000..9f674a1d3fa --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_page.c @@ -0,0 +1,290 @@ +#include +#include + +static fz_error * +runone(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) +{ + fz_error *error; + fz_stream *stm; + + pdf_logpage("simple content stream\n"); + + error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref)); + if (error) + return error; + + error = pdf_runcsi(csi, xref, rdb, stm); + + fz_dropstream(stm); + + return error; +} + +/* we need to combine all sub-streams into one for pdf_runcsi + * to deal with split dictionaries etc. + */ +static fz_error * +runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) +{ + fz_error *error; + fz_stream *file; + fz_buffer *big; + fz_buffer *one; + fz_obj *stm; + int n; + int i; + + pdf_logpage("multiple content streams: %d\n", fz_arraylen(list)); + + error = fz_newbuffer(&big, 32 * 1024); + if (error) + return error; + + error = fz_openwbuffer(&file, big); + if (error) + goto cleanup0; + + for (i = 0; i < fz_arraylen(list); i++) + { + /* TODO dont use loadstream here */ + + stm = fz_arrayget(list, i); + error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm)); + if (error) + goto cleanup1; + + n = fz_write(file, one->rp, one->wp - one->rp); + + fz_dropbuffer(one); + + if (n == -1) + { + error = fz_ioerror(file); + goto cleanup1; + } + + fz_printstr(file, " "); + } + + fz_dropstream(file); + + error = fz_openrbuffer(&file, big); + if (error) + goto cleanup0; + + error = pdf_runcsi(csi, xref, rdb, file); + + fz_dropstream(file); + fz_dropbuffer(big); + + return error; + +cleanup1: + fz_dropstream(file); +cleanup0: + fz_dropbuffer(big); + return error; +} + +static fz_error * +loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref) +{ + fz_error *error; + fz_obj *obj; + pdf_csi *csi; + + error = pdf_newcsi(&csi, 0); + if (error) + return error; + + if (fz_isindirect(ref)) + { + error = pdf_loadindirect(&obj, xref, ref); + if (error) + return error; + + if (fz_isarray(obj)) + { + if (fz_arraylen(obj) == 1) + error = runone(csi, xref, rdb, fz_arrayget(obj, 0)); + else + error = runmany(csi, xref, rdb, obj); + } + else + error = runone(csi, xref, rdb, ref); + + fz_dropobj(obj); + if (error) + goto cleanup; + } + + else if (fz_isarray(ref)) + { + if (fz_arraylen(ref) == 1) + error = runone(csi, xref, rdb, fz_arrayget(ref, 0)); + else + error = runmany(csi, xref, rdb, ref); + } + + *treep = csi->tree; + csi->tree = nil; + error = nil; + +cleanup: + pdf_dropcsi(csi); + return error; +} + +fz_error *pdf_getpageinfo(pdf_xref *xref, fz_obj *dict, fz_rect *bboxp, int *rotatep) +{ + fz_rect bbox; + int rotate; + fz_obj *obj; + fz_error *error; + + obj = fz_dictgets(dict, "CropBox"); + if (!obj) + obj = fz_dictgets(dict, "MediaBox"); + + if (fz_isindirect(obj)) { + fz_obj* obj2; + error = pdf_loadindirect(&obj2, xref, obj); + if (error) + return error; + obj = obj2; + } + + if (!fz_isarray(obj)) + return fz_throw("syntaxerror: Page missing MediaBox"); + bbox = pdf_torect(obj); + + pdf_logpage("bbox [%g %g %g %g]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); + + obj = fz_dictgets(dict, "Rotate"); + rotate = 0; + if (fz_isint(obj)) + rotate = fz_toint(obj); + + pdf_logpage("rotate %d\n", rotate); + + if (bboxp) + *bboxp = bbox; + if (rotatep) + *rotatep = rotate; + return nil; +} + +fz_error * +pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict) +{ + fz_error *error; + fz_obj *obj; + pdf_page *page; + fz_obj *rdb; + pdf_comment *comments = nil; + pdf_link *links = nil; + fz_tree *tree; + fz_rect bbox; + int rotate; + + pdf_logpage("load page {\n"); + + /* + * Sort out page media + */ + error = pdf_getpageinfo(xref, dict, &bbox, &rotate); + if (error) + return error; + + /* + * Load annotations + */ + + obj = fz_dictgets(dict, "Annots"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = pdf_loadannots(&comments, &links, xref, obj); + fz_dropobj(obj); + if (error) + return error; + } + + /* + * Load resources + */ + + obj = fz_dictgets(dict, "Resources"); + if (!obj) + return fz_throw("syntaxerror: Page missing Resources"); + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = pdf_loadresources(&rdb, xref, obj); + fz_dropobj(obj); + if (error) + return error; + + /* + * Interpret content stream to build display tree + */ + + obj = fz_dictgets(dict, "Contents"); + + error = loadpagecontents(&tree, xref, rdb, obj); + if (error) { + fz_dropobj(rdb); + return error; + } + + pdf_logpage("optimize tree\n"); + error = fz_optimizetree(tree); + if (error) { + fz_dropobj(rdb); + return error; + } + + /* + * Create page object + */ + + page = *pagep = fz_malloc(sizeof(pdf_page)); + if (!page) { + fz_droptree(tree); + fz_dropobj(rdb); + return fz_outofmem; + } + + page->mediabox.x0 = MIN(bbox.x0, bbox.x1); + page->mediabox.y0 = MIN(bbox.y0, bbox.y1); + page->mediabox.x1 = MAX(bbox.x0, bbox.x1); + page->mediabox.y1 = MAX(bbox.y0, bbox.y1); + page->rotate = rotate; + page->resources = rdb; + page->tree = tree; + + page->comments = comments; + page->links = links; + + pdf_logpage("} %p\n", page); + + return nil; +} + +void +pdf_droppage(pdf_page *page) +{ + pdf_logpage("drop page %p\n", page); +/* + if (page->comments) + pdf_dropcomment(page->comments); +*/ + if (page->links) + pdf_droplink(page->links); + fz_dropobj(page->resources); + fz_droptree(page->tree); + fz_free(page); +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_pagetree.c b/rosapps/smartpdf/fitz/mupdf/pdf_pagetree.c new file mode 100644 index 00000000000..e6fc947ba0e --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_pagetree.c @@ -0,0 +1,224 @@ +#include +#include + +struct stuff +{ + fz_obj *resources; + fz_obj *mediabox; + fz_obj *cropbox; + fz_obj *rotate; +}; + +static fz_error * +loadpagetree(pdf_xref *xref, pdf_pagetree *pages, + struct stuff inherit, fz_obj *obj, fz_obj *ref) +{ + fz_error *error; + fz_obj *type; + fz_obj *kids; + fz_obj *kref, *kobj; + fz_obj *inh; + int i; + + type = fz_dictgets(obj, "Type"); + + if (strcmp(fz_toname(type), "Page") == 0) + { + if (inherit.resources && !fz_dictgets(obj, "Resources")) + { + pdf_logpage("inherit resources (%d)\n", pages->cursor); + error = fz_dictputs(obj, "Resources", inherit.resources); + if (error) return error; + } + + if (inherit.mediabox && !fz_dictgets(obj, "MediaBox")) + { + pdf_logpage("inherit mediabox (%d)\n", pages->cursor); + error = fz_dictputs(obj, "MediaBox", inherit.mediabox); + if (error) return error; + } + + if (inherit.cropbox && !fz_dictgets(obj, "CropBox")) + { + pdf_logpage("inherit cropbox (%d)\n", pages->cursor); + error = fz_dictputs(obj, "CropBox", inherit.cropbox); + if (error) return error; + } + + if (inherit.rotate && !fz_dictgets(obj, "Rotate")) + { + pdf_logpage("inherit rotate (%d)\n", pages->cursor); + error = fz_dictputs(obj, "Rotate", inherit.rotate); + if (error) return error; + } + + pages->pref[pages->cursor] = fz_keepobj(ref); + pages->pobj[pages->cursor] = fz_keepobj(obj); + pages->cursor ++; + } + + else if (strcmp(fz_toname(type), "Pages") == 0) + { + inh = fz_dictgets(obj, "Resources"); + if (inh) inherit.resources = inh; + + inh = fz_dictgets(obj, "MediaBox"); + if (inh) inherit.mediabox = inh; + + inh = fz_dictgets(obj, "CropBox"); + if (inh) inherit.cropbox = inh; + + inh = fz_dictgets(obj, "Rotate"); + if (inh) inherit.rotate = inh; + + kids = fz_dictgets(obj, "Kids"); + error = pdf_resolve(&kids, xref); + if (error) + return error; + + pdf_logpage("subtree %d {\n", fz_arraylen(kids)); + + for (i = 0; i < fz_arraylen(kids); i++) + { + kref = fz_arrayget(kids, i); + + error = pdf_loadindirect(&kobj, xref, kref); + if (error) { fz_dropobj(kids); return error; } + + if (kobj == obj) + { + /* prevent infinite recursion possible in maliciously crafted PDFs */ + fz_dropobj(kids); + return fz_throw("corrupted pdf file"); + } + else + { + error = loadpagetree(xref, pages, inherit, kobj, kref); + fz_dropobj(kobj); + if (error) { fz_dropobj(kids); return error; } + } + } + + fz_dropobj(kids); + + pdf_logpage("}\n"); + } + + return nil; +} + +void +pdf_debugpagetree(pdf_pagetree *pages) +{ + int i; + printf("<<\n /Type /Pages\n /Count %d\n /Kids [\n", pages->count); + for (i = 0; i < pages->count; i++) { + printf(" "); + fz_debugobj(pages->pref[i]); + printf("\t%% page %d\n", i + 1); + } + printf(" ]\n>>\n"); +} + +fz_error * +pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref) +{ + fz_error *error; + struct stuff inherit; + pdf_pagetree *p = nil; + fz_obj *catalog = nil; + fz_obj *pages = nil; + fz_obj *trailer; + fz_obj *ref; + int count; + + inherit.resources = nil; + inherit.mediabox = nil; + inherit.cropbox = nil; + inherit.rotate = nil; + + trailer = xref->trailer; + + ref = fz_dictgets(trailer, "Root"); + error = pdf_loadindirect(&catalog, xref, ref); + if (error) goto cleanup; + + ref = fz_dictgets(catalog, "Pages"); + error = pdf_loadindirect(&pages, xref, ref); + if (error) goto cleanup; + + ref = fz_dictgets(pages, "Count"); + count = fz_toint(ref); + + p = fz_malloc(sizeof(pdf_pagetree)); + if (!p) { error = fz_outofmem; goto cleanup; } + + pdf_logpage("load pagetree %p {\n", p); + pdf_logpage("count %d\n", count); + + p->pref = nil; + p->pobj = nil; + p->count = count; + p->cursor = 0; + + p->pref = fz_malloc(sizeof(fz_obj*) * count); + if (!p->pref) { error = fz_outofmem; goto cleanup; } + + p->pobj = fz_malloc(sizeof(fz_obj*) * count); + if (!p->pobj) { error = fz_outofmem; goto cleanup; } + + error = loadpagetree(xref, p, inherit, pages, ref); + if (error) goto cleanup; + + fz_dropobj(pages); + fz_dropobj(catalog); + + pdf_logpage("}\n", count); + + *pp = p; + return nil; + +cleanup: + if (pages) fz_dropobj(pages); + if (catalog) fz_dropobj(catalog); + if (p) { + fz_free(p->pref); + fz_free(p->pobj); + fz_free(p); + } + return error; +} + +int +pdf_getpagecount(pdf_pagetree *pages) +{ + return pages->count; +} + +fz_obj * +pdf_getpageobject(pdf_pagetree *pages, int p) +{ + if (p < 0 || p >= pages->count) + return nil; + return pages->pobj[p]; +} + +void +pdf_droppagetree(pdf_pagetree *pages) +{ + int i; + + pdf_logpage("drop pagetree %p\n", pages); + + for (i = 0; i < pages->count; i++) { + if (pages->pref[i]) + fz_dropobj(pages->pref[i]); + if (pages->pobj[i]) + fz_dropobj(pages->pobj[i]); + } + + fz_free(pages->pref); + fz_free(pages->pobj); + fz_free(pages); +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_parse.c b/rosapps/smartpdf/fitz/mupdf/pdf_parse.c new file mode 100644 index 00000000000..e46a14eef7f --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_parse.c @@ -0,0 +1,423 @@ +#include +#include + +fz_rect pdf_torect(fz_obj *array) +{ + fz_rect r; + float a = fz_toreal(fz_arrayget(array, 0)); + float b = fz_toreal(fz_arrayget(array, 1)); + float c = fz_toreal(fz_arrayget(array, 2)); + float d = fz_toreal(fz_arrayget(array, 3)); + r.x0 = MIN(a, c); + r.y0 = MIN(b, d); + r.x1 = MAX(a, c); + r.y1 = MAX(b, d); + return r; +} + +fz_matrix pdf_tomatrix(fz_obj *array) +{ + fz_matrix m; + m.a = fz_toreal(fz_arrayget(array, 0)); + m.b = fz_toreal(fz_arrayget(array, 1)); + m.c = fz_toreal(fz_arrayget(array, 2)); + m.d = fz_toreal(fz_arrayget(array, 3)); + m.e = fz_toreal(fz_arrayget(array, 4)); + m.f = fz_toreal(fz_arrayget(array, 5)); + return m; +} + +fz_error * +pdf_toutf8(char **dstp, fz_obj *src) +{ + unsigned char *srcptr = fz_tostrbuf(src); + char *dstptr; + int srclen = fz_tostrlen(src); + int dstlen = 0; + int ucs; + int i; + + if (srclen > 2 && srcptr[0] == 254 && srcptr[1] == 255) + { + for (i = 2; i < srclen; i += 2) + { + ucs = (srcptr[i] << 8) | srcptr[i+1]; + dstlen += runelen(ucs); + } + + dstptr = *dstp = fz_malloc(dstlen + 1); + if (!dstptr) + return fz_outofmem; + + for (i = 2; i < srclen; i += 2) + { + ucs = (srcptr[i] << 8) | srcptr[i+1]; + dstptr += runetochar(dstptr, &ucs); + } + } + + else + { + for (i = 0; i < srclen; i++) + dstlen += runelen(pdf_docencoding[srcptr[i]]); + + dstptr = *dstp = fz_malloc(dstlen + 1); + if (!dstptr) + return fz_outofmem; + + for (i = 0; i < srclen; i++) + { + ucs = pdf_docencoding[srcptr[i]]; + dstptr += runetochar(dstptr, &ucs); + } + } + + *dstptr = '\0'; + return nil; +} + +fz_error * +pdf_toucs2(unsigned short **dstp, fz_obj *src) +{ + unsigned char *srcptr = fz_tostrbuf(src); + unsigned short *dstptr; + int srclen = fz_tostrlen(src); + int i; + + if (srclen > 2 && srcptr[0] == 254 && srcptr[1] == 255) + { + dstptr = *dstp = fz_malloc(((srclen - 2) / 2 + 1) * sizeof(short)); + if (!dstptr) + return fz_outofmem; + for (i = 2; i < srclen; i += 2) + *dstptr++ = (srcptr[i] << 8) | srcptr[i+1]; + } + + else + { + dstptr = *dstp = fz_malloc((srclen + 1) * sizeof(short)); + if (!dstptr) + return fz_outofmem; + for (i = 0; i < srclen; i++) + *dstptr++ = pdf_docencoding[srcptr[i]]; + } + + *dstptr = '\0'; + return nil; +} + +fz_error * +pdf_parsearray(fz_obj **op, fz_stream *file, char *buf, int cap) +{ + fz_error *error = nil; + fz_obj *ary = nil; + fz_obj *obj = nil; + int a = 0, b = 0, n = 0; + int tok, len; + + error = fz_newarray(op, 4); + if (error) return error; + ary = *op; + + while (1) + { + tok = pdf_lex(file, buf, cap, &len); + + if (tok != PDF_TINT && tok != PDF_TR) + { + if (n > 0) + { + error = fz_newint(&obj, a); + if (error) goto cleanup; + error = fz_arraypush(ary, obj); + if (error) goto cleanup; + fz_dropobj(obj); + obj = nil; + } + if (n > 1) + { + error = fz_newint(&obj, b); + if (error) goto cleanup; + error = fz_arraypush(ary, obj); + if (error) goto cleanup; + fz_dropobj(obj); + obj = nil; + } + n = 0; + } + + if (tok == PDF_TINT && n == 2) + { + error = fz_newint(&obj, a); + if (error) goto cleanup; + error = fz_arraypush(ary, obj); + if (error) goto cleanup; + fz_dropobj(obj); + obj = nil; + a = b; + n --; + } + + switch (tok) + { + case PDF_TCARRAY: + return nil; + case PDF_TINT: + if (n == 0) + a = atoi(buf); + if (n == 1) + b = atoi(buf); + n ++; + break; + case PDF_TR: + if (n != 2) + goto cleanup; + error = fz_newindirect(&obj, a, b); + if (error) goto cleanup; + n = 0; + break; + case PDF_TOARRAY: error = pdf_parsearray(&obj, file, buf, cap); break; + case PDF_TODICT: error = pdf_parsedict(&obj, file, buf, cap); break; + case PDF_TNAME: error = fz_newname(&obj, buf); break; + case PDF_TREAL: error = fz_newreal(&obj, atof(buf)); break; + case PDF_TSTRING: error = fz_newstring(&obj, buf, len); break; + case PDF_TTRUE: error = fz_newbool(&obj, 1); break; + case PDF_TFALSE: error = fz_newbool(&obj, 0); break; + case PDF_TNULL: error = fz_newnull(&obj); break; + default: goto cleanup; + } + if (error) goto cleanup; + + if (obj) + { + error = fz_arraypush(ary, obj); + if (error) goto cleanup; + fz_dropobj(obj); + } + + obj = nil; + } + +cleanup: + if (obj) fz_dropobj(obj); + if (ary) fz_dropobj(ary); + if (error) return error; + return fz_throw("syntaxerror: corrupt array"); +} + +fz_error * +pdf_parsedict(fz_obj **op, fz_stream *file, char *buf, int cap) +{ + fz_error *error = nil; + fz_obj *dict = nil; + fz_obj *key = nil; + fz_obj *val = nil; + int tok, len; + int a, b; + + error = fz_newdict(op, 8); + if (error) return error; + dict = *op; + + while (1) + { + tok = pdf_lex(file, buf, cap, &len); + +skip: + if (tok == PDF_TCDICT) + return nil; + + /* for BI .. ID .. EI in content streams */ + if (tok == PDF_TKEYWORD && !strcmp(buf, "ID")) + return nil; + + if (tok != PDF_TNAME) + goto cleanup; + + error = fz_newname(&key, buf); + if (error) + goto cleanup; + + tok = pdf_lex(file, buf, cap, &len); + + switch (tok) + { + case PDF_TOARRAY: error = pdf_parsearray(&val, file, buf, cap); break; + case PDF_TODICT: error = pdf_parsedict(&val, file, buf, cap); break; + case PDF_TNAME: error = fz_newname(&val, buf); break; + case PDF_TREAL: error = fz_newreal(&val, atof(buf)); break; + case PDF_TSTRING: error = fz_newstring(&val, buf, len); break; + case PDF_TTRUE: error = fz_newbool(&val, 1); break; + case PDF_TFALSE: error = fz_newbool(&val, 0); break; + case PDF_TNULL: error = fz_newnull(&val); break; + case PDF_TINT: + a = atoi(buf); + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TCDICT || tok == PDF_TNAME || + (tok == PDF_TKEYWORD && !strcmp(buf, "ID"))) + { + error = fz_newint(&val, a); + if (error) goto cleanup; + error = fz_dictput(dict, key, val); + if (error) + goto cleanup; + fz_dropobj(val); + fz_dropobj(key); + key = val = nil; + goto skip; + } + if (tok == PDF_TINT) + { + b = atoi(buf); + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TR) + { + error = fz_newindirect(&val, a, b); + break; + } + } + goto cleanup; + default: + goto cleanup; + } + + if (error) + goto cleanup; + + error = fz_dictput(dict, key, val); + if (error) + goto cleanup; + + fz_dropobj(val); + fz_dropobj(key); + key = val = nil; + } + +cleanup: + if (key) + fz_dropobj(key); + if (val) + fz_dropobj(val); + if (dict) + fz_dropobj(dict); + *op = nil; + if (error) return error; + return fz_throw("syntaxerror: corrupt dictionary"); +} + +fz_error * +pdf_parsestmobj(fz_obj **op, fz_stream *file, char *buf, int cap) +{ + int tok, len; + + tok = pdf_lex(file, buf, cap, &len); + + switch (tok) + { + case PDF_TOARRAY: return pdf_parsearray(op, file, buf, cap); + case PDF_TODICT: return pdf_parsedict(op, file, buf, cap); + case PDF_TNAME: return fz_newname(op, buf); + case PDF_TREAL: return fz_newreal(op, atof(buf)); + case PDF_TSTRING: return fz_newstring(op, buf, len); + case PDF_TTRUE: return fz_newbool(op, 1); + case PDF_TFALSE: return fz_newbool(op, 0); + case PDF_TNULL: return fz_newnull(op); + case PDF_TINT: return fz_newint(op, atoi(buf)); + } + + return fz_throw("syntaxerror: corrupt object stream"); +} + +fz_error * +pdf_parseindobj(fz_obj **op, fz_stream *file, char *buf, int cap, + int *ooid, int *ogid, int *ostmofs) +{ + fz_error *error = nil; + fz_obj *obj = nil; + int oid = 0, gid = 0, stmofs; + int tok, len; + int a, b; + + tok = pdf_lex(file, buf, cap, &len); + if (tok != PDF_TINT) + goto cleanup; + oid = atoi(buf); + + tok = pdf_lex(file, buf, cap, &len); + if (tok != PDF_TINT) + goto cleanup; + gid = atoi(buf); + + tok = pdf_lex(file, buf, cap, &len); + if (tok != PDF_TOBJ) + goto cleanup; + + tok = pdf_lex(file, buf, cap, &len); + switch (tok) + { + case PDF_TOARRAY: error = pdf_parsearray(&obj, file, buf, cap); break; + case PDF_TODICT: error = pdf_parsedict(&obj, file, buf, cap); break; + case PDF_TNAME: error = fz_newname(&obj, buf); break; + case PDF_TREAL: error = fz_newreal(&obj, atof(buf)); break; + case PDF_TSTRING: error = fz_newstring(&obj, buf, len); break; + case PDF_TTRUE: error = fz_newbool(&obj, 1); break; + case PDF_TFALSE: error = fz_newbool(&obj, 0); break; + case PDF_TNULL: error = fz_newnull(&obj); break; + case PDF_TINT: + a = atoi(buf); + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TSTREAM || tok == PDF_TENDOBJ) + { + error = fz_newint(&obj, a); + if (error) goto cleanup; + goto skip; + } + if (tok == PDF_TINT) + { + b = atoi(buf); + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TR) + { + error = fz_newindirect(&obj, a, b); + break; + } + } + goto cleanup; + default: + goto cleanup; + } + if (error) goto cleanup; + + tok = pdf_lex(file, buf, cap, &len); + +skip: + if (tok == PDF_TSTREAM) + { + int c = fz_readbyte(file); + if (c == '\r') + { + c = fz_peekbyte(file); + if (c != '\n') + fz_warn("syntaxerror: DOS format line ending after stream keyword (%d %d)\n", oid, gid); + else + c = fz_readbyte(file); + } + stmofs = fz_tell(file); + } + else if (tok == PDF_TENDOBJ) + stmofs = 0; + else + goto cleanup; + + if (ooid) *ooid = oid; + if (ogid) *ogid = gid; + if (ostmofs) *ostmofs = stmofs; + *op = obj; + return nil; + +cleanup: + if (obj) fz_dropobj(obj); + if (error) return error; + return fz_throw("syntaxerror: corrupt indirect object (%d %d)", oid, gid); +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_pattern.c b/rosapps/smartpdf/fitz/mupdf/pdf_pattern.c new file mode 100644 index 00000000000..dc7bc55e42b --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_pattern.c @@ -0,0 +1,142 @@ +#include +#include + +pdf_pattern * +pdf_keeppattern(pdf_pattern *pat) +{ + assert(pat->refs > 0); + pat->refs ++; + return pat; +} + +void +pdf_droppattern(pdf_pattern *pat) +{ + assert(pat->refs > 0); + if (--pat->refs == 0) + { + if (pat->tree) + fz_droptree(pat->tree); + fz_free(pat); + } +} + +fz_error * +pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref) +{ + fz_error *error; + pdf_pattern *pat; + fz_stream *stm; + fz_obj *resources; + fz_obj *obj; + pdf_csi *csi; + + *patp = pdf_finditem(xref->store, PDF_KPATTERN, stmref); + if (*patp) + { + pdf_keeppattern(*patp); + return nil; + } + + pdf_logrsrc("load pattern %d %d {\n", fz_tonum(stmref), fz_togen(stmref)); + + pat = fz_malloc(sizeof(pdf_pattern)); + if (!pat) + return fz_outofmem; + + pat->refs = 1; + pat->tree = nil; + pat->ismask = fz_toint(fz_dictgets(dict, "PaintType")) == 2; + pat->xstep = fz_toreal(fz_dictgets(dict, "XStep")); + pat->ystep = fz_toreal(fz_dictgets(dict, "YStep")); + + pdf_logrsrc("mask %d\n", pat->ismask); + pdf_logrsrc("xstep %g\n", pat->xstep); + pdf_logrsrc("ystep %g\n", pat->ystep); + + obj = fz_dictgets(dict, "BBox"); + pat->bbox = pdf_torect(obj); + + pdf_logrsrc("bbox [%g %g %g %g]\n", + pat->bbox.x0, pat->bbox.y0, + pat->bbox.x1, pat->bbox.y1); + + obj = fz_dictgets(dict, "Matrix"); + if (obj) + pat->matrix = pdf_tomatrix(obj); + else + pat->matrix = fz_identity(); + + pdf_logrsrc("matrix [%g %g %g %g %g %g]\n", + pat->matrix.a, pat->matrix.b, + pat->matrix.c, pat->matrix.d, + pat->matrix.e, pat->matrix.f); + + /* + * Resources + */ + + obj = fz_dictgets(dict, "Resources"); + if (!obj) { + error = fz_throw("syntaxerror: Pattern missing Resources"); + goto cleanup; + } + + error = pdf_resolve(&obj, xref); + if (error) + goto cleanup; + + error = pdf_loadresources(&resources, xref, obj); + + fz_dropobj(obj); + + if (error) + goto cleanup; + + /* + * Content stream + */ + + pdf_logrsrc("content stream\n"); + + error = pdf_newcsi(&csi, pat->ismask); + if (error) + goto cleanup; + + error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref)); + if (error) + goto cleanup2; + + error = pdf_runcsi(csi, xref, resources, stm); + + fz_dropstream(stm); + + if (error) + goto cleanup2; + + pat->tree = csi->tree; + csi->tree = nil; + + pdf_dropcsi(csi); + + fz_dropobj(resources); + + pdf_logrsrc("optimize tree\n"); + fz_optimizetree(pat->tree); + + pdf_logrsrc("}\n"); + + error = pdf_storeitem(xref->store, PDF_KPATTERN, stmref, pat); + if (error) + goto cleanup; + + *patp = pat; + return nil; + +cleanup2: + pdf_dropcsi(csi); +cleanup: + pdf_droppattern(pat); + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_repair.c b/rosapps/smartpdf/fitz/mupdf/pdf_repair.c new file mode 100644 index 00000000000..72e969192bb --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_repair.c @@ -0,0 +1,304 @@ +#include +#include + +/* + * open pdf and scan objects to reconstruct xref table + */ + +struct entry +{ + int oid; + int gen; + int ofs; + int stmofs; + int stmlen; +}; + +static fz_error * +parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen, + int *isroot, int *isinfo) +{ + fz_error *error; + fz_obj *dict = nil; + fz_obj *length; + fz_obj *filter; + fz_obj *type; + int tok, len; + + *stmlen = -1; + *isroot = 0; + *isinfo = 0; + + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TODICT) + { + error = pdf_parsedict(&dict, file, buf, cap); + if (error) + return error; + } + + if (fz_isdict(dict)) + { + type = fz_dictgets(dict, "Type"); + if (fz_isname(type) && !strcmp(fz_toname(type), "Catalog")) + *isroot = 1; + + filter = fz_dictgets(dict, "Filter"); + if (fz_isname(filter) && !strcmp(fz_toname(filter), "Standard")) + return fz_throw("cannot repair encrypted files"); + + if (fz_dictgets(dict, "Producer")) + if (fz_dictgets(dict, "Creator")) + if (fz_dictgets(dict, "Title")) + *isinfo = 1; + } + + while ( tok != PDF_TSTREAM && + tok != PDF_TENDOBJ && + tok != PDF_TERROR && + tok != PDF_TEOF ) + tok = pdf_lex(file, buf, cap, &len); + + if (tok == PDF_TSTREAM) + { + int c = fz_readbyte(file); + if (c == '\r') { + c = fz_peekbyte(file); + if (c == '\n') + fz_readbyte(file); + } + + *stmofs = fz_tell(file); + + length = fz_dictgets(dict, "Length"); + if (fz_isint(length)) + { + fz_seek(file, *stmofs + fz_toint(length), 0); + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TENDSTREAM) + goto atobjend; + fz_seek(file, *stmofs, 0); + } + + fz_read(file, buf, 9); + while (memcmp(buf, "endstream", 9) != 0) + { + c = fz_readbyte(file); + if (c == EOF) + break; + memmove(buf, buf + 1, 8); + buf[8] = c; + } + + *stmlen = fz_tell(file) - *stmofs - 9; + +atobjend: + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TENDOBJ) + ; + } + + if (dict) + fz_dropobj(dict); + + return nil; +} + +fz_error * +pdf_repairxref(pdf_xref *xref, char *filename) +{ + fz_error *error; + fz_stream *file; + + struct entry *list = nil; + int listlen; + int listcap; + int maxoid = 0; + + char buf[65536]; + + int oid = 0; + int gen = 0; + int tmpofs, oidofs = 0, genofs = 0; + int isroot, rootoid = 0, rootgen = 0; + int isinfo, infooid = 0, infogen = 0; + int stmofs, stmlen; + int tok, len; + int next; + int i; + + error = fz_openrfile(&file, filename); + if (error) + return error; + + pdf_logxref("repairxref '%s' %p\n", filename, xref); + + xref->file = file; + + /* TODO: extract version */ + + listlen = 0; + listcap = 1024; + list = fz_malloc(listcap * sizeof(struct entry)); + if (!list) + goto cleanup; + + while (1) + { + tmpofs = fz_tell(file); + + tok = pdf_lex(file, buf, sizeof buf, &len); + if (tok == PDF_TINT) + { + oidofs = genofs; + oid = gen; + genofs = tmpofs; + gen = atoi(buf); + } + + if (tok == PDF_TOBJ) + { + error = parseobj(file, buf, sizeof buf, &stmofs, &stmlen, &isroot, &isinfo); + if (error) + goto cleanup; + + if (isroot) { + pdf_logxref("found catalog: %d %d\n", oid, gen); + rootoid = oid; + rootgen = gen; + } + + if (isinfo) { + pdf_logxref("found info: %d %d\n", oid, gen); + infooid = oid; + infogen = gen; + } + + if (listlen + 1 == listcap) + { + struct entry *newlist; + listcap = listcap * 2; + newlist = fz_realloc(list, listcap * sizeof(struct entry)); + if (!newlist) { + error = fz_outofmem; + goto cleanup; + } + list = newlist; + } + + list[listlen].oid = oid; + list[listlen].gen = gen; + list[listlen].ofs = oidofs; + list[listlen].stmofs = stmofs; + list[listlen].stmlen = stmlen; + listlen ++; + + if (oid > maxoid) + maxoid = oid; + } + + if (tok == PDF_TERROR) + fz_readbyte(file); + + if (tok == PDF_TEOF) + break; + } + + if (rootoid == 0) + { + error = fz_throw("syntaxerror: could not find catalog"); + goto cleanup; + } + + error = fz_packobj(&xref->trailer, + "<< /Size %i /Root %r >>", + maxoid + 1, rootoid, rootgen); + if (error) + goto cleanup; + + xref->len = maxoid + 1; + xref->cap = xref->len; + xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry)); + if (!xref->table) + { + error = fz_outofmem; + goto cleanup; + } + + xref->table[0].type = 'f'; + xref->table[0].mark = 0; + xref->table[0].ofs = 0; + xref->table[0].gen = 65535; + xref->table[0].stmbuf = nil; + xref->table[0].stmofs = 0; + xref->table[0].obj = nil; + + for (i = 1; i < xref->len; i++) + { + xref->table[i].type = 'f'; + xref->table[i].mark = 0; + xref->table[i].ofs = 0; + xref->table[i].gen = 0; + xref->table[i].stmbuf = nil; + xref->table[i].stmofs = 0; + xref->table[i].obj = nil; + } + + for (i = 0; i < listlen; i++) + { + xref->table[list[i].oid].type = 'n'; + xref->table[list[i].oid].ofs = list[i].ofs; + xref->table[list[i].oid].gen = list[i].gen; + xref->table[list[i].oid].mark = 0; + + xref->table[list[i].oid].stmofs = list[i].stmofs; + + /* corrected stream length */ + if (list[i].stmlen >= 0) + { + fz_obj *dict, *length; + + pdf_logxref("correct stream length %d %d = %d\n", + list[i].oid, list[i].gen, list[i].stmlen); + + error = pdf_loadobject(&dict, xref, list[i].oid, list[i].gen); + if (error) + goto cleanup; + + error = fz_newint(&length, list[i].stmlen); + if (error) + goto cleanup; + error = fz_dictputs(dict, "Length", length); + if (error) + goto cleanup; + + pdf_updateobject(xref, list[i].oid, list[i].gen, dict); + + fz_dropobj(dict); + } + } + + next = 0; + for (i = xref->len - 1; i >= 0; i--) + { + if (xref->table[i].type == 'f') + { + xref->table[i].ofs = next; + if (xref->table[i].gen < 65535) + xref->table[i].gen ++; + next = i; + } + } + + fz_free(list); + + return nil; + +cleanup: + assert(1 == file->refs); + fz_dropstream(file); + xref->file = NULL; + fz_free(list); + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_resources.c b/rosapps/smartpdf/fitz/mupdf/pdf_resources.c new file mode 100644 index 00000000000..a46f46865bc --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_resources.c @@ -0,0 +1,385 @@ +#include +#include + +/* + +Go through resource dictionary and resolve some levels of +indirect references so we end up with a stylized structure. +The resources referenced are all pre-loaded which inserts +them into the resource store for later lookup when interpreting +content streams. + +All resources except colorspaces are automatically inserted +in the resource store when they are parsed. For colorspaces +named in resource dictionaries, we have to insert them ourselves +since we cannot take the risk of having to resolve objects +while in the middle of parsing a content stream. + +<< + /Font << + /F0 1 0 R + /F1 2 0 R + /F2 3 0 R + >> + /ExtGState << + /Gs0 << ... /Font 1 0 R ... >> + /Gs1 << ... >> + >> + /ColorSpace << + /Cs0 5 0 R + /Cs1 [ /ICCBased 5 0 R ] + /Cs2 [ /CalRGB << ... >> ] + /CsX [ /Pattern /DeviceRGB ] + >> + /Pattern << + /Pat0 20 0 R + >> + /Shading << + /Sh0 30 0 R + >> + /XObject << + /Im0 10 0 R + /Fm0 11 0 R + >> +>> + +*/ + +static fz_error * +preloadcolorspace(pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + fz_colorspace *colorspace; + fz_obj *obj = ref; + + if (pdf_finditem(xref->store, PDF_KCOLORSPACE, ref)) + return nil; + + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = pdf_loadcolorspace(&colorspace, xref, obj); + fz_dropobj(obj); + if (error) + return error; + + pdf_logrsrc("rsrc colorspace %s\n", colorspace->name); + + error = pdf_storeitem(xref->store, PDF_KCOLORSPACE, ref, colorspace); + if (error) + { + fz_dropcolorspace(colorspace); + return error; + } + + return nil; +} + +static fz_error * +preloadpattern(pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + pdf_pattern *pattern; + fz_shade *shade; + fz_obj *type; + fz_obj *obj = ref; + + error = pdf_resolve(&obj, xref); + if (error) + return error; + + type = fz_dictgets(obj, "PatternType"); + + if (fz_toint(type) == 1) + { + error = pdf_loadpattern(&pattern, xref, obj, ref); + fz_dropobj(obj); + return error; + } + + else if (fz_toint(type) == 2) + { + error = pdf_loadshade(&shade, xref, obj, ref); + fz_dropobj(obj); + return error; + } + + else + { + fz_dropobj(obj); + return fz_throw("syntaxerror: unknown Pattern type"); + } +} + +static fz_error * +preloadshading(pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + fz_shade *shade; + fz_obj *obj = ref; + error = pdf_resolve(&obj, xref); + if (error) return error; + error = pdf_loadshade(&shade, xref, obj, ref); + fz_dropobj(obj); + return error; +} + +extern void pdf_dropimage(fz_image *fzimg); + +static fz_error * +preloadxobject(pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + pdf_xobject *xobject; + pdf_image *image; + fz_obj *obj = ref; + fz_obj *subtype; + + error = pdf_resolve(&obj, xref); + if (error) + return error; + + subtype = fz_dictgets(obj, "Subtype"); + + if (!strcmp(fz_toname(subtype), "Form")) + { + error = pdf_loadxobject(&xobject, xref, obj, ref); + fz_dropobj(obj); + return error; + } + else if (!strcmp(fz_toname(subtype), "Image")) + { + error = pdf_loadimage(&image, xref, obj, ref); + fz_dropobj(obj); + if (image) + fz_dropimage((fz_image*)image); + return error; + } + else + { + fz_dropobj(obj); + return fz_throw("syntaxerror: unknown XObject subtype"); + } +} + +static fz_error * +preloadfont(pdf_xref *xref, fz_obj *ref) +{ + fz_error *error; + pdf_font *font; + fz_obj *obj = ref; + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = pdf_loadfont(&font, xref, obj, ref); + fz_dropobj(obj); + if (!error) + fz_dropfont((fz_font*)font); + return error; +} + +static fz_error * +scanfonts(pdf_xref *xref, fz_obj *rdb) +{ + fz_error *error; + fz_obj *dict; + fz_obj *obj; + int i; + + dict = fz_dictgets(rdb, "ExtGState"); + if (dict) + { + for (i = 0; i < fz_dictlen(dict); i++) + { + obj = fz_dictgetval(dict, i); + obj = fz_dictgets(obj, "Font"); + if (obj) + { + pdf_logrsrc("extgstate font\n"); + error = preloadfont(xref, fz_arrayget(obj, 0)); + if (error) + return error; + } + } + } + + dict = fz_dictgets(rdb, "Font"); + if (dict) + { + for (i = 0; i < fz_dictlen(dict); i++) + { + obj = fz_dictgetval(dict, i); + error = preloadfont(xref, obj); + if (error) + return error; + } + } + + return nil; +} + +static fz_error * +copyresolved(fz_obj **outp, pdf_xref *xref, fz_obj *dict) +{ + fz_error *error; + fz_obj *key, *val, *obj; + fz_obj *copy; + int i; + + error = fz_newdict(©, fz_dictlen(dict)); + if (error) + return error; + + for (i = 0; i < fz_dictlen(dict); i++) + { + key = fz_dictgetkey(dict, i); + val = fz_dictgetval(dict, i); + + if (fz_isindirect(val)) + { + error = pdf_loadindirect(&obj, xref, val); + if (error) + goto cleanup; + error = fz_dictput(copy, key, obj); + fz_dropobj(obj); + if (error) + goto cleanup; + } + else + { + error = fz_dictput(copy, key, val); + if (error) + goto cleanup; + } + } + + *outp = copy; + return nil; + +cleanup: + fz_dropobj(copy); + return error; +} + +fz_error * +pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig) +{ + fz_error *error; + fz_obj *copy; + fz_obj *old; + fz_obj *new; + fz_obj *dict; + fz_obj *obj; + int i; + + /* + * We need a store for resources. + */ + + if (!xref->store) + { + error = pdf_newstore(&xref->store); + if (error) + return error; + } + + pdf_logrsrc("load resources {\n"); + + /* + * Resolve indirect objects + */ + + error = copyresolved(©, xref, orig); + if (error) + return error; + + old = fz_dictgets(copy, "ExtGState"); + if (old) + { + error = copyresolved(&new, xref, old); + if (error) + goto cleanup; + error = fz_dictputs(copy, "ExtGState", new); + fz_dropobj(new); + if (error) + goto cleanup; + } + + /* + * Load ColorSpace objects + */ + + dict = fz_dictgets(copy, "ColorSpace"); + if (dict) + { + for (i = 0; i < fz_dictlen(dict); i++) + { + obj = fz_dictgetval(dict, i); + error = preloadcolorspace(xref, obj); + if (error) + return error; + } + } + + /* + * Load Patterns (and Shadings) + */ + + dict = fz_dictgets(copy, "Pattern"); + if (dict) + { + for (i = 0; i < fz_dictlen(dict); i++) + { + obj = fz_dictgetval(dict, i); + error = preloadpattern(xref, obj); + if (error) + return error; + } + } + + dict = fz_dictgets(copy, "Shading"); + if (dict) + { + for (i = 0; i < fz_dictlen(dict); i++) + { + obj = fz_dictgetval(dict, i); + error = preloadshading(xref, obj); + if (error) + return error; + } + } + + /* + * Load XObjects and Images + */ + + dict = fz_dictgets(copy, "XObject"); + if (dict) + { + for (i = 0; i < fz_dictlen(dict); i++) + { + obj = fz_dictgetval(dict, i); + error = preloadxobject(xref, obj); + if (error) + return error; + } + } + + /* + * Load Font objects + */ + + error = scanfonts(xref, copy); + if (error) + goto cleanup; + + pdf_logrsrc("}\n"); + + *rdbp = copy; + return nil; + +cleanup: + fz_dropobj(copy); + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_save.c b/rosapps/smartpdf/fitz/mupdf/pdf_save.c new file mode 100644 index 00000000000..0bcb8ac18d6 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_save.c @@ -0,0 +1,326 @@ +#include +#include + +#define TIGHT 1 + +static fz_error * +writestream(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) +{ + fz_error *error; + fz_stream *dststm; + fz_stream *srcstm; + unsigned char buf[4096]; + fz_filter *ef; + int n; + + fz_print(out, "stream\n"); + + if (encrypt) + { + error = pdf_cryptstream(&ef, encrypt, oid, gen); + if (error) + return error; + + error = fz_openrfilter(&dststm, ef, out); + fz_dropfilter(ef); + if (error) + return error; + } + else + { + dststm = fz_keepstream(out); + } + + error = pdf_openrawstream(&srcstm, xref, oid, gen); + if (error) + goto cleanupdst; + + while (1) + { + n = fz_read(srcstm, buf, sizeof buf); + if (n == 0) + break; + if (n < 0) + { + error = fz_ioerror(srcstm); + goto cleanupsrc; + } + + n = fz_write(dststm, buf, n); + if (n < 0) + { + error = fz_ioerror(dststm); + goto cleanupsrc; + } + } + + fz_dropstream(srcstm); + fz_dropstream(dststm); + + fz_print(out, "endstream\n"); + + return nil; + +cleanupsrc: + fz_dropstream(srcstm); +cleanupdst: + fz_dropstream(dststm); + return error; +} + +static fz_error * +writeobject(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) +{ + pdf_xrefentry *x = xref->table + oid; + fz_error *error; + + error = pdf_cacheobject(xref, oid, gen); + if (error) + return error; + + if (encrypt) + pdf_cryptobj(encrypt, x->obj, oid, gen); + + fz_print(out, "%d %d obj\n", oid, gen); + fz_printobj(out, x->obj, TIGHT); + fz_print(out, "\n"); + + if (encrypt) + pdf_cryptobj(encrypt, x->obj, oid, gen); + + if (pdf_isstream(xref, oid, gen)) + { + error = writestream(out, xref, encrypt, oid, gen); + if (error) + return error; + } + + fz_print(out, "endobj\n\n"); + + return nil; +} + +static int countmodified(pdf_xref *xref, int oid) +{ + int i; + for (i = oid; i < xref->len; i++) + if (xref->table[i].type != 'a' && xref->table[i].type != 'd') + return i - oid; + return i - oid; +} + +fz_error * +pdf_updatexref(pdf_xref *xref, char *path) +{ + fz_error *error; + fz_stream *out; + int oid; + int i, n; + int startxref; + fz_obj *obj; + + pdf_logxref("updatexref '%s' %p\n", path, xref); + + error = fz_openafile(&out, path); + if (error) + return error; + + fz_print(out, "\n"); + + for (oid = 0; oid < xref->len; oid++) + { + if (xref->table[oid].type == 'a') + { + xref->table[oid].ofs = fz_tell(out); + error = writeobject(out, xref, xref->crypt, oid, xref->table[oid].gen); + if (error) + goto cleanup; + } + } + + /* always write out entry 0 in appended xref sections */ + xref->table[0].type = 'd'; + + startxref = fz_tell(out); + fz_print(out, "xref\n"); + + oid = 0; + while (oid < xref->len) + { + n = countmodified(xref, oid); + + pdf_logxref(" section %d +%d\n", oid, n); + + fz_print(out, "%d %d\n", oid, n); + + for (i = 0; i < n; i++) + { + if (xref->table[oid + i].type == 'd') + xref->table[oid + i].type = 'f'; + if (xref->table[oid + i].type == 'a') + xref->table[oid + i].type = 'n'; + + fz_print(out, "%010d %05d %c \n", + xref->table[oid + i].ofs, + xref->table[oid + i].gen, + xref->table[oid + i].type); + } + + oid += n; + while (oid < xref->len && + xref->table[oid].type != 'a' && + xref->table[oid].type != 'd') + oid ++; + } + + fz_print(out, "\n"); + + fz_print(out, "trailer\n<<\n /Size %d\n /Prev %d", xref->len, xref->startxref); + + obj = fz_dictgets(xref->trailer, "Root"); + fz_print(out,"\n /Root %d %d R", fz_tonum(obj), fz_togen(obj)); + + obj = fz_dictgets(xref->trailer, "Info"); + if (obj) + fz_print(out,"\n /Info %d %d R", fz_tonum(obj), fz_togen(obj)); + + obj = fz_dictgets(xref->trailer, "Encrypt"); + if (obj) { + fz_print(out,"\n /Encrypt "); + fz_printobj(out, obj, TIGHT); + } + + obj = fz_dictgets(xref->trailer, "ID"); + if (obj) { + fz_print(out,"\n /ID "); + fz_printobj(out, obj, TIGHT); + } + + fz_print(out, "\n>>\n\n"); + + fz_print(out, "startxref\n"); + fz_print(out, "%d\n", startxref); + fz_print(out, "%%%%EOF\n"); + + xref->startxref = startxref; + + fz_dropstream(out); + return nil; + +cleanup: + fz_dropstream(out); + return error; +} + +fz_error * +pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt) +{ + fz_error *error; + fz_stream *out; + int oid; + int startxref; + int *ofsbuf; + fz_obj *obj; + int eoid, egen; + + pdf_logxref("savexref '%s' %p\n", path, xref); + + /* need to add encryption object for acrobat < 6 */ + if (encrypt) + { + pdf_logxref("make encryption dict\n"); + + error = pdf_allocobject(xref, &eoid, &egen); + if (error) + return error; + + pdf_cryptobj(encrypt, encrypt->encrypt, eoid, egen); + + error = pdf_updateobject(xref, eoid, egen, encrypt->encrypt); + if (error) + return error; + } + + ofsbuf = fz_malloc(sizeof(int) * xref->len); + if (!ofsbuf) + return fz_outofmem; + + error = fz_openwfile(&out, path); + if (error) + { + fz_free(ofsbuf); + return error; + } + + fz_print(out, "%%PDF-%1.1f\n", xref->version); + fz_print(out, "%%\342\343\317\323\n\n"); + + for (oid = 0; oid < xref->len; oid++) + { + pdf_xrefentry *x = xref->table + oid; + if (x->type == 'n' || x->type == 'o' || x->type == 'a') + { + ofsbuf[oid] = fz_tell(out); + error = writeobject(out, xref, encrypt, oid, x->type == 'o' ? 0 : x->gen); + if (error) + goto cleanup; + } + else + { + ofsbuf[oid] = x->ofs; + } + } + + startxref = fz_tell(out); + fz_print(out, "xref\n"); + fz_print(out, "0 %d\n", xref->len); + + for (oid = 0; oid < xref->len; oid++) + { + int gen = xref->table[oid].gen; + int type = xref->table[oid].type; + if (type == 'o') + gen = 0; + if (type == 'a' || type == 'o') + type = 'n'; + if (type == 'd') + type = 'f'; + fz_print(out, "%010d %05d %c \n", ofsbuf[oid], gen, type); + } + + fz_print(out, "\n"); + + fz_print(out, "trailer\n<<\n /Size %d", xref->len); + obj = fz_dictgets(xref->trailer, "Root"); + fz_print(out, "\n /Root %d %d R", fz_tonum(obj), fz_togen(obj)); + obj = fz_dictgets(xref->trailer, "Info"); + if (obj) + fz_print(out, "\n /Info %d %d R", fz_tonum(obj), fz_togen(obj)); + if (encrypt) + { + fz_print(out, "\n /Encrypt %d %d R", eoid, egen); + fz_print(out, "\n /ID ["); + fz_printobj(out, encrypt->id, 1); + fz_printobj(out, encrypt->id, 1); + fz_print(out, "]"); + + pdf_cryptobj(encrypt, encrypt->encrypt, eoid, egen); + } + fz_print(out, "\n>>\n\n"); + + fz_print(out, "startxref\n"); + fz_print(out, "%d\n", startxref); + fz_print(out, "%%%%EOF\n"); + + xref->startxref = startxref; + + if(ofsbuf) fz_free(ofsbuf); + fz_dropstream(out); + return nil; + +cleanup: + if(ofsbuf) fz_free(ofsbuf); + fz_dropstream(out); + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_shade.c b/rosapps/smartpdf/fitz/mupdf/pdf_shade.c new file mode 100644 index 00000000000..7da1824adfb --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_shade.c @@ -0,0 +1,230 @@ +#include +#include + +fz_error * +pdf_loadshadefunction(fz_shade *shade, pdf_xref *xref, fz_obj *shading, float t0, float t1) +{ + fz_error *error; + float t; + fz_obj *obj; + pdf_function *func; + int i; + + obj = fz_dictgets(shading, "Function"); + if (obj) + { + shade->usefunction = 1; + + error = pdf_loadfunction(&func, xref, obj); + if (error) + return error; + + for (i = 0; i < 256; ++i) + { + t = t0 + (i / 256.0) * (t1 - t0); + error = pdf_evalfunction(func, &t, 1, shade->function[i], shade->cs->n); + if (error) + { + pdf_dropfunction(func); + return error; + } + } + + pdf_dropfunction(func); + } + + return nil; +} + +void +pdf_setmeshvalue(float *mesh, int i, float x, float y, float t) +{ + mesh[i*3+0] = x; + mesh[i*3+1] = y; + mesh[i*3+2] = t; +} + +static fz_error * +loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_matrix matrix) +{ + fz_error *error; + fz_shade *shade; + fz_obj *obj; + int type; + int i; + + pdf_logshade("load shade dict %d %d {\n", fz_tonum(ref), fz_togen(ref)); + + shade = fz_malloc(sizeof(fz_shade)); + if (!shade) + return fz_outofmem; + + shade->refs = 1; + shade->usebackground = 0; + shade->usefunction = 0; + shade->matrix = matrix; + shade->bbox = fz_infiniterect; + + shade->meshlen = 0; + shade->meshcap = 0; + shade->mesh = nil; + + obj = fz_dictgets(dict, "ShadingType"); + type = fz_toint(obj); + pdf_logshade("type %d\n", type); + + /* TODO: flatten indexed... */ + obj = fz_dictgets(dict, "ColorSpace"); + if (obj) + { + shade->cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj); + if (shade->cs) + fz_keepcolorspace(shade->cs); + else + { + error = pdf_resolve(&obj, xref); + if (error) + return error; + error = pdf_loadcolorspace(&shade->cs, xref, obj); + if (error) + return error; + fz_dropobj(obj); + } + } + pdf_logshade("colorspace %s\n", shade->cs->name); + + obj = fz_dictgets(dict, "Background"); + if (obj) + { + pdf_logshade("background\n"); + shade->usebackground = 1; + for (i = 0; i < shade->cs->n; i++) + shade->background[i] = fz_toreal(fz_arrayget(obj, i)); + } + + obj = fz_dictgets(dict, "BBox"); + if (fz_isarray(obj)) + { + shade->bbox = pdf_torect(obj); + pdf_logshade("bbox [%g %g %g %g]\n", + shade->bbox.x0, shade->bbox.y0, + shade->bbox.x1, shade->bbox.y1); + } + + switch(type) + { + case 1: + error = pdf_loadtype1shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 2: + error = pdf_loadtype2shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 3: + error = pdf_loadtype3shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 4: + error = pdf_loadtype4shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 5: + error = pdf_loadtype5shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 6: + error = pdf_loadtype6shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 7: + error = pdf_loadtype7shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + default: + fz_warn("syntaxerror: unknown shading type: %d", type); + break; + }; + + pdf_logshade("}\n"); + + *shadep = shade; + return nil; + +cleanup: + fz_dropshade(shade); + return error; +} + +fz_error * +pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + fz_matrix mat; + fz_obj *obj; + fz_obj *shd; + + if ((*shadep = pdf_finditem(xref->store, PDF_KSHADE, ref))) + return nil; + + /* + * Type 2 pattern dictionary + */ + if (fz_dictgets(dict, "PatternType")) + { + pdf_logshade("load shade pattern %d %d {\n", fz_tonum(ref), fz_togen(ref)); + + obj = fz_dictgets(dict, "Matrix"); + if (obj) + { + mat = pdf_tomatrix(obj); + pdf_logshade("matrix [%g %g %g %g %g %g]\n", + mat.a, mat.b, mat.c, mat.d, mat.e, mat.f); + } + else + { + mat = fz_identity(); + } + + obj = fz_dictgets(dict, "ExtGState"); + if (obj) + { + pdf_logshade("extgstate ...\n"); + } + + obj = fz_dictgets(dict, "Shading"); + if (!obj) + return fz_throw("syntaxerror: missing shading dictionary"); + + shd = obj; + error = pdf_resolve(&shd, xref); + if (error) + return error; + error = loadshadedict(shadep, xref, shd, obj, mat); + fz_dropobj(shd); + if (error) + return error; + + pdf_logshade("}\n"); + } + + /* + * Naked shading dictionary + */ + else + { + error = loadshadedict(shadep, xref, dict, ref, fz_identity()); + if (error) + return error; + } + + error = pdf_storeitem(xref->store, PDF_KSHADE, ref, *shadep); + if (error) + { + fz_dropshade(*shadep); + return error; + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_shade1.c b/rosapps/smartpdf/fitz/mupdf/pdf_shade1.c new file mode 100644 index 00000000000..46bee5d7c32 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_shade1.c @@ -0,0 +1,369 @@ +#include +#include + +/* this mess is jeong's */ + +#define BIGNUM 32000 + +#define NSEGS 32 +#define MAX_RAD_SEGS 36 + +fz_error * +pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + fz_obj *obj; + fz_matrix matrix; + pdf_function *func; + + int xx, yy; + float x, y; + float xn, yn; + float x0, y0, x1, y1; + int n; + + pdf_logshade("load type1 shade {\n"); + + obj = fz_dictgets(dict, "Domain"); + if (obj) { + x0 = fz_toreal(fz_arrayget(obj, 0)); + x1 = fz_toreal(fz_arrayget(obj, 1)); + y0 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + } + else { + x0 = 0; + x1 = 1.0; + y0 = 0; + y1 = 1.0; + } + + pdf_logshade("domain %g %g %g %g\n", x0, x1, y0, y1); + + obj = fz_dictgets(dict, "Matrix"); + if (obj) + { + matrix = pdf_tomatrix(obj); + pdf_logshade("matrix [%g %g %g %g %g %g]\n", + matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f); + } + else + matrix = fz_identity(); + + obj = fz_dictgets(dict, "Function"); + error = pdf_loadfunction(&func, xref, obj); + if (error) + return error; + + shade->usefunction = 0; + + if (error) + return error; + + shade->meshlen = NSEGS * NSEGS * 2; + shade->mesh = fz_malloc(sizeof(float) * (2 + shade->cs->n) * 3 * shade->meshlen); + if (!shade->mesh) + return fz_outofmem; + + n = 0; + for (yy = 0; yy < NSEGS; ++yy) + { + y = y0 + (y1 - y0) * yy / (float)NSEGS; + yn = y0 + (y1 - y0) * (yy + 1) / (float)NSEGS; + for (xx = 0; xx < NSEGS; ++xx) + { + x = x0 + (x1 - x0) * (xx / (float)NSEGS); + xn = x0 + (x1 - x0) * (xx + 1) / (float)NSEGS; + +#define ADD_VERTEX(xx, yy) \ + {\ + fz_point p;\ + float cp[2], cv[FZ_MAXCOLORS];\ + int c;\ + p.x = xx;\ + p.y = yy;\ + p = fz_transformpoint(matrix, p);\ + shade->mesh[n++] = p.x;\ + shade->mesh[n++] = p.y;\ + \ + cp[0] = xx;\ + cp[1] = yy;\ + error = pdf_evalfunction(func, cp, 2, cv, shade->cs->n);\ + \ + for (c = 0; c < shade->cs->n; ++c) {\ + shade->mesh[n++] = cv[c];\ + }\ + }\ + + ADD_VERTEX(x, y); + ADD_VERTEX(xn, y); + ADD_VERTEX(xn, yn); + + ADD_VERTEX(x, y); + ADD_VERTEX(xn, yn); + ADD_VERTEX(x, yn); + } + } + + pdf_logshade("}\n"); + + return nil; +} + +fz_error * +pdf_loadtype2shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_point p1, p2, p3, p4; + fz_point ep1, ep2, ep3, ep4; + float x0, y0, x1, y1; + float t0, t1; + int e0, e1; + fz_obj *obj; + float theta; + float dist; + int n; + + pdf_logshade("load type2 shade {\n"); + + obj = fz_dictgets(dict, "Coords"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + y0 = fz_toreal(fz_arrayget(obj, 1)); + x1 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + + pdf_logshade("coords %g %g %g %g\n", x0, y0, x1, y1); + + obj = fz_dictgets(dict, "Domain"); + if (obj) { + t0 = fz_toreal(fz_arrayget(obj, 0)); + t1 = fz_toreal(fz_arrayget(obj, 1)); + } else { + t0 = 0.; + t1 = 1.; + } + + obj = fz_dictgets(dict, "Extend"); + if (obj) { + e0 = fz_tobool(fz_arrayget(obj, 0)); + e1 = fz_tobool(fz_arrayget(obj, 1)); + } else { + e0 = 0; + e1 = 0; + } + + pdf_logshade("domain %g %g\n", t0, t1); + pdf_logshade("extend %d %d\n", e0, e1); + + pdf_loadshadefunction(shade, xref, dict, t0, t1); + + shade->meshlen = 2 + e0 * 2 + e1 * 2; + shade->mesh = fz_malloc(sizeof(float) * 3*3 * shade->meshlen); + if (!shade->mesh) + return fz_outofmem; + + theta = atan2(y1 - y0, x1 - x0); + theta += M_PI / 2.0; + + pdf_logshade("theta=%g\n", theta); + + dist = hypot(x1 - x0, y1 - y0); + + p1.x = x0 + BIGNUM * cos(theta); + p1.y = y0 + BIGNUM * sin(theta); + p2.x = x1 + BIGNUM * cos(theta); + p2.y = y1 + BIGNUM * sin(theta); + p3.x = x0 - BIGNUM * cos(theta); + p3.y = y0 - BIGNUM * sin(theta); + p4.x = x1 - BIGNUM * cos(theta); + p4.y = y1 - BIGNUM * sin(theta); + + ep1.x = p1.x - (x1 - x0) / dist * BIGNUM; + ep1.y = p1.y - (y1 - y0) / dist * BIGNUM; + ep2.x = p2.x + (x1 - x0) / dist * BIGNUM; + ep2.y = p2.y + (y1 - y0) / dist * BIGNUM; + ep3.x = p3.x - (x1 - x0) / dist * BIGNUM; + ep3.y = p3.y - (y1 - y0) / dist * BIGNUM; + ep4.x = p4.x + (x1 - x0) / dist * BIGNUM; + ep4.y = p4.y + (y1 - y0) / dist * BIGNUM; + + pdf_logshade("p1 %g %g\n", p1.x, p1.y); + pdf_logshade("p2 %g %g\n", p2.x, p2.y); + pdf_logshade("p3 %g %g\n", p3.x, p3.y); + pdf_logshade("p4 %g %g\n", p4.x, p4.y); + + n = 0; + + pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); + + if (e0) { + pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); + pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); + pdf_setmeshvalue(shade->mesh, n++, ep3.x, ep3.y, 0); + } + + if (e1) { + pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, ep2.x, ep2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); + } + + pdf_logshade("}\n"); + + return nil; +} + +static int +buildannulusmesh(float* mesh, int pos, + float x0, float y0, float r0, float x1, float y1, float r1, + float c0, float c1, int nomesh) +{ + int n = pos * 3; + float dist = hypot(x1 - x0, y1 - y0); + float step; + float theta; + int i; + + if (dist != 0) + theta = asin((r1 - r0) / dist) + M_PI/2.0 + atan2(y1 - y0, x1 - x0); + else + theta = 0; + + if (!(theta >= 0 && theta <= M_PI)) + theta = 0; + + step = M_PI * 2.f / (float)MAX_RAD_SEGS; + + for (i = 0; i < MAX_RAD_SEGS; theta -= step, ++i) + { + fz_point pt1, pt2, pt3, pt4; + + pt1.x = cos (theta) * r1 + x1; + pt1.y = sin (theta) * r1 + y1; + pt2.x = cos (theta) * r0 + x0; + pt2.y = sin (theta) * r0 + y0; + pt3.x = cos (theta+step) * r1 + x1; + pt3.y = sin (theta+step) * r1 + y1; + pt4.x = cos (theta+step) * r0 + x0; + pt4.y = sin (theta+step) * r0 + y0; + + if (r0 > 0) { + if (!nomesh) { + pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1); + pdf_setmeshvalue(mesh, n++, pt2.x, pt2.y, c0); + pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0); + } + pos++; + } + + if (r1 > 0) { + if (!nomesh) { + pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1); + pdf_setmeshvalue(mesh, n++, pt3.x, pt3.y, c1); + pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0); + } + pos++; + } + } + + return pos; +} + +fz_error * +pdf_loadtype3shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_obj *obj; + float x0, y0, r0, x1, y1, r1; + float t0, t1; + int e0, e1; + float ex0, ey0, er0; + float ex1, ey1, er1; + float rs; + int i; + + pdf_logshade("load type3 shade {\n"); + + obj = fz_dictgets(shading, "Coords"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + y0 = fz_toreal(fz_arrayget(obj, 1)); + r0 = fz_toreal(fz_arrayget(obj, 2)); + x1 = fz_toreal(fz_arrayget(obj, 3)); + y1 = fz_toreal(fz_arrayget(obj, 4)); + r1 = fz_toreal(fz_arrayget(obj, 5)); + + pdf_logshade("coords %g %g %g %g %g %g\n", x0, y0, r0, x1, y1, r1); + + obj = fz_dictgets(shading, "Domain"); + if (obj) { + t0 = fz_toreal(fz_arrayget(obj, 0)); + t1 = fz_toreal(fz_arrayget(obj, 1)); + } else { + t0 = 0.; + t1 = 1.; + } + + obj = fz_dictgets(shading, "Extend"); + if (obj) { + e0 = fz_tobool(fz_arrayget(obj, 0)); + e1 = fz_tobool(fz_arrayget(obj, 1)); + } else { + e0 = 0; + e1 = 0; + } + + pdf_logshade("domain %g %g\n", t0, t1); + pdf_logshade("extend %d %d\n", e0, e1); + + pdf_loadshadefunction(shade, xref, shading, t0, t1); + + if (r0 < r1) + rs = r0 / (r0 - r1); + else + rs = -BIGNUM; + + ex0 = x0 + (x1 - x0) * rs; + ey0 = y0 + (y1 - y0) * rs; + er0 = r0 + (r1 - r0) * rs; + + if (r0 > r1) + rs = r1 / (r1 - r0); + else + rs = -BIGNUM; + + ex1 = x1 + (x0 - x1) * rs; + ey1 = y1 + (y0 - y1) * rs; + er1 = r1 + (r0 - r1) * rs; + + for (i=0; i<2; ++i) + { + int pos = 0; + if (e0) + pos = buildannulusmesh(shade->mesh, pos, ex0, ey0, er0, x0, y0, r0, 0, 0, 1-i); + pos = buildannulusmesh(shade->mesh, pos, x0, y0, r0, x1, y1, r1, 0, 1., 1-i); + if (e1) + pos = buildannulusmesh(shade->mesh, pos, x1, y1, r1, ex1, ey1, er1, 1., 1., 1-i); + + if (i == 0) + { + shade->meshlen = pos; + shade->mesh = fz_malloc(sizeof(float) * 9 * shade->meshlen); + if (!shade->mesh) + return fz_outofmem; + } + } + + pdf_logshade("}\n"); + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_shade4.c b/rosapps/smartpdf/fitz/mupdf/pdf_shade4.c new file mode 100644 index 00000000000..ddd42efdef9 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_shade4.c @@ -0,0 +1,795 @@ +#include +#include + +/* this mess is jeong's */ + +typedef struct pdf_tensorpatch_s pdf_tensorpatch; +struct pdf_tensorpatch_s { + fz_point pole[4][4]; + float color[4][FZ_MAXCOLORS]; +}; + +fz_error * +pdf_loadtype4shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_error *error; + fz_obj *obj; + int bpcoord; + int bpcomp; + int bpflag; + int ncomp; + float x0, x1, y0, y1; + float c0[FZ_MAXCOLORS]; + float c1[FZ_MAXCOLORS]; + int i, z; + int bitspervertex; + int bytepervertex; + fz_buffer *buf; + int n; + int j; + float cval[16]; + + int flag; + unsigned int t; + float x, y; + + error = nil; + + ncomp = shade->cs->n; + bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); + bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); + bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); + + obj = fz_dictgets(shading, "Decode"); + if (fz_isarray(obj)) + { + pdf_logshade("decode array\n"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + x1 = fz_toreal(fz_arrayget(obj, 1)); + y0 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + for (i=0; i < fz_arraylen(obj) / 2; ++i) { + c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); + c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); + } + } + else { + error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Function"); + if (obj) { + ncomp = 1; + pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); + } + + bitspervertex = bpflag + bpcoord * 2 + bpcomp * ncomp; + bytepervertex = (bitspervertex+7) / 8; + + error = pdf_loadstream(&buf, xref, fz_tonum(ref), fz_togen(ref)); + if (error) goto cleanup; + + shade->usefunction = 0; + + + n = 2 + shade->cs->n; + j = 0; + for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z) + { + flag = *buf->rp++; + + t = *buf->rp++; + t = (t << 8) + *buf->rp++; + t = (t << 8) + *buf->rp++; + x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1)); + + t = *buf->rp++; + t = (t << 8) + *buf->rp++; + t = (t << 8) + *buf->rp++; + y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1)); + + for (i=0; i < ncomp; ++i) { + t = *buf->rp++; + t = (t << 8) + *buf->rp++; + } + + if (flag == 0) { + j += n; + } + if (flag == 1 || flag == 2) { + j += 3 * n; + } + } + buf->rp = buf->bp; + + shade->mesh = (float*) malloc(sizeof(float) * j); + /* 8, 24, 16 only */ + j = 0; + for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z) + { + flag = *buf->rp++; + + t = *buf->rp++; + t = (t << 8) + *buf->rp++; + t = (t << 8) + *buf->rp++; + x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1)); + + t = *buf->rp++; + t = (t << 8) + *buf->rp++; + t = (t << 8) + *buf->rp++; + y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1)); + + for (i=0; i < ncomp; ++i) { + t = *buf->rp++; + t = (t << 8) + *buf->rp++; + cval[i] = t / (double)(pow(2, 16) - 1); + } + + if (flag == 0) { + shade->mesh[j++] = x; + shade->mesh[j++] = y; + for (i=0; i < ncomp; ++i) { + shade->mesh[j++] = cval[i]; + } + } + if (flag == 1) { + memcpy(&(shade->mesh[j]), &(shade->mesh[j - 2 * n]), n * sizeof(float)); + memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float)); + j+= 2 * n; + shade->mesh[j++] = x; + shade->mesh[j++] = y; + for (i=0; i < ncomp; ++i) { + shade->mesh[j++] = cval[i]; + } + } + if (flag == 2) { + memcpy(&(shade->mesh[j]), &(shade->mesh[j - 3 * n]), n * sizeof(float)); + memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float)); + j+= 2 * n; + shade->mesh[j++] = x; + shade->mesh[j++] = y; + for (i=0; i < ncomp; ++i) { + shade->mesh[j++] = cval[i]; + } + } + } + shade->meshlen = j / n / 3; + + fz_dropbuffer(buf); + +cleanup: + + return nil; +} + +static int +getdata(fz_stream *stream, int bps) +{ + unsigned int bitmask = (1 << bps) - 1; + unsigned int buf = 0; + int bits = 0; + int s; + + while (bits < bps) + { + buf = (buf << 8) | (fz_readbyte(stream) & 0xff); + bits += 8; + } + s = buf >> (bits - bps); + if (bps < 32) + s = s & bitmask; + bits -= bps; + + return s; +} + +fz_error * +pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_error *error; + fz_stream *stream; + fz_obj *obj; + + int bpcoord; + int bpcomp; + int vpr, vpc; + int ncomp; + + float x0, x1, y0, y1; + + float c0[FZ_MAXCOLORS]; + float c1[FZ_MAXCOLORS]; + + int i, n, j; + int p, q; + unsigned int t; + + float *x, *y, *c[FZ_MAXCOLORS]; + + error = nil; + + ncomp = shade->cs->n; + bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); + bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); + vpr = fz_toint(fz_dictgets(shading, "VerticesPerRow")); + if (vpr < 2) { + error = fz_throw("VerticesPerRow must be greater than or equal to 2"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Decode"); + if (fz_isarray(obj)) + { + pdf_logshade("decode array\n"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + x1 = fz_toreal(fz_arrayget(obj, 1)); + y0 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + for (i=0; i < fz_arraylen(obj) / 2; ++i) { + c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); + c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); + } + } + else { + error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Function"); + if (obj) { + ncomp = 1; + pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); + shade->usefunction = 1; + } + else + shade->usefunction = 0; + + n = 2 + shade->cs->n; + j = 0; + +#define BIGNUM 1024 + + x = fz_malloc(sizeof(float) * vpr * BIGNUM); + y = fz_malloc(sizeof(float) * vpr * BIGNUM); + for (i = 0; i < ncomp; ++i) { + c[i] = fz_malloc(sizeof(float) * vpr * BIGNUM); + } + q = 0; + + error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); + if (error) goto cleanup; + + while (fz_peekbyte(stream) != EOF) + { + for (p = 0; p < vpr; ++p) { + int idx; + idx = q * vpr + p; + + t = getdata(stream, bpcoord); + x[idx] = x0 + (t * (x1 - x0) / ((float)pow(2, bpcoord) - 1)); + t = getdata(stream, bpcoord); + y[idx] = y0 + (t * (y1 - y0) / ((float)pow(2, bpcoord) - 1)); + + for (i=0; i < ncomp; ++i) { + t = getdata(stream, bpcomp); + c[i][idx] = c0[i] + (t * (c1[i] - c0[i]) / (float)(pow(2, bpcomp) - 1)); + } + } + q++; + } + + fz_dropstream(stream); + +#define ADD_VERTEX(idx) \ + {\ + int z;\ + shade->mesh[j++] = x[idx];\ + shade->mesh[j++] = y[idx];\ + for (z = 0; z < shade->cs->n; ++z) {\ + shade->mesh[j++] = c[z][idx];\ + }\ + }\ + + vpc = q; + + shade->meshcap = 0; + shade->mesh = fz_malloc(sizeof(float) * 1024); + if (!shade) { + error = fz_outofmem; + goto cleanup; + } + + j = 0; + for (p = 0; p < vpr-1; ++p) { + for (q = 0; q < vpc-1; ++q) { + ADD_VERTEX(q * vpr + p); + ADD_VERTEX(q * vpr + p + 1); + ADD_VERTEX((q + 1) * vpr + p + 1); + + ADD_VERTEX(q * vpr + p); + ADD_VERTEX((q + 1) * vpr + p + 1); + ADD_VERTEX((q + 1) * vpr + p); + } + } + + shade->meshlen = j / n / 3; + + fz_free(x); + fz_free(y); + for (i = 0; i < ncomp; ++i) { + fz_free(c[i]); + } + + +cleanup: + + return nil; +} + +#define SEGMENTATION_DEPTH 2 + +static inline void copyvert(float *dst, float *src, int n) +{ + while (n--) + *dst++ = *src++; +} + + +static inline void copycolor(float *c, const float *s) +{ + int i; + for (i = 0; ipole[1][1].x = lcp1(p->pole[0][1].x, p->pole[3][1].x) + + lcp1(p->pole[1][0].x, p->pole[1][3].x) - + lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x), + lcp1(p->pole[3][0].x, p->pole[3][3].x)); + p->pole[1][2].x = lcp1(p->pole[0][2].x, p->pole[3][2].x) + + lcp2(p->pole[1][0].x, p->pole[1][3].x) - + lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x), + lcp2(p->pole[3][0].x, p->pole[3][3].x)); + p->pole[2][1].x = lcp2(p->pole[0][1].x, p->pole[3][1].x) + + lcp1(p->pole[2][0].x, p->pole[2][3].x) - + lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x), + lcp1(p->pole[3][0].x, p->pole[3][3].x)); + p->pole[2][2].x = lcp2(p->pole[0][2].x, p->pole[3][2].x) + + lcp2(p->pole[2][0].x, p->pole[2][3].x) - + lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x), + lcp2(p->pole[3][0].x, p->pole[3][3].x)); + + p->pole[1][1].y = lcp1(p->pole[0][1].y, p->pole[3][1].y) + + lcp1(p->pole[1][0].y, p->pole[1][3].y) - + lcp1(lcp1(p->pole[0][0].y, p->pole[0][3].y), + lcp1(p->pole[3][0].y, p->pole[3][3].y)); + p->pole[1][2].y = lcp1(p->pole[0][2].y, p->pole[3][2].y) + + lcp2(p->pole[1][0].y, p->pole[1][3].y) - + lcp1(lcp2(p->pole[0][0].y, p->pole[0][3].y), + lcp2(p->pole[3][0].y, p->pole[3][3].y)); + p->pole[2][1].y = lcp2(p->pole[0][1].y, p->pole[3][1].y) + + lcp1(p->pole[2][0].y, p->pole[2][3].y) - + lcp2(lcp1(p->pole[0][0].y, p->pole[0][3].y), + lcp1(p->pole[3][0].y, p->pole[3][3].y)); + p->pole[2][2].y = lcp2(p->pole[0][2].y, p->pole[3][2].y) + + lcp2(p->pole[2][0].y, p->pole[2][3].y) - + lcp2(lcp2(p->pole[0][0].y, p->pole[0][3].y), + lcp2(p->pole[3][0].y, p->pole[3][3].y)); + +#undef lcp1 +#undef lcp2 +} + +static void +split_curve_s(const fz_point *pole, fz_point *q0, fz_point *q1, int pole_step) +{ +#define midpoint(a,b)\ + ((a)/2.0f + (b)/2.0f) // to avoid overflow + float x12 = midpoint(pole[1 * pole_step].x, pole[2 * pole_step].x); + float y12 = midpoint(pole[1 * pole_step].y, pole[2 * pole_step].y); + + q0[1 * pole_step].x = midpoint(pole[0 * pole_step].x, pole[1 * pole_step].x); + q0[1 * pole_step].y = midpoint(pole[0 * pole_step].y, pole[1 * pole_step].y); + q1[2 * pole_step].x = midpoint(pole[2 * pole_step].x, pole[3 * pole_step].x); + q1[2 * pole_step].y = midpoint(pole[2 * pole_step].y, pole[3 * pole_step].y); + q0[2 * pole_step].x = midpoint(q0[1 * pole_step].x, x12); + q0[2 * pole_step].y = midpoint(q0[1 * pole_step].y, y12); + q1[1 * pole_step].x = midpoint(x12, q1[2 * pole_step].x); + q1[1 * pole_step].y = midpoint(y12, q1[2 * pole_step].y); + q0[0 * pole_step].x = pole[0 * pole_step].x; + q0[0 * pole_step].y = pole[0 * pole_step].y; + q0[3 * pole_step].x = q1[0 * pole_step].x = midpoint(q0[2 * pole_step].x, q1[1 * pole_step].x); + q0[3 * pole_step].y = q1[0 * pole_step].y = midpoint(q0[2 * pole_step].y, q1[1 * pole_step].y); + q1[3 * pole_step].x = pole[3 * pole_step].x; + q1[3 * pole_step].y = pole[3 * pole_step].y; +#undef midpoint +} + +static inline void +split_patch(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p) +{ + split_curve_s(&p->pole[0][0], &s0->pole[0][0], &s1->pole[0][0], 4); + split_curve_s(&p->pole[0][1], &s0->pole[0][1], &s1->pole[0][1], 4); + split_curve_s(&p->pole[0][2], &s0->pole[0][2], &s1->pole[0][2], 4); + split_curve_s(&p->pole[0][3], &s0->pole[0][3], &s1->pole[0][3], 4); + + copycolor(s0->color[0], p->color[0]); + midcolor(s0->color[1], p->color[0], p->color[1]); + midcolor(s0->color[2], p->color[2], p->color[3]); + copycolor(s0->color[3], p->color[3]); + + copycolor(s1->color[0], s0->color[1]); + copycolor(s1->color[1], p->color[1]); + copycolor(s1->color[2], p->color[2]); + copycolor(s1->color[3], s0->color[2]); +} + +static inline void +split_stripe(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p) + +{ + split_curve_s(p->pole[0], s0->pole[0], s1->pole[0], 1); + split_curve_s(p->pole[1], s0->pole[1], s1->pole[1], 1); + split_curve_s(p->pole[2], s0->pole[2], s1->pole[2], 1); + split_curve_s(p->pole[3], s0->pole[3], s1->pole[3], 1); + + copycolor(s0->color[0], p->color[0]); + copycolor(s0->color[1], p->color[1]); + midcolor(s0->color[2], p->color[1], p->color[2]); + midcolor(s0->color[3], p->color[0], p->color[3]); + + copycolor(s1->color[0], s0->color[3]); + copycolor(s1->color[1], s0->color[2]); + copycolor(s1->color[2], p->color[2]); + copycolor(s1->color[3], p->color[3]); +} + +static fz_error * +growshademesh(fz_shade *shade, int amount) +{ + float *newmesh; + int newcap; + + newcap = shade->meshcap + amount; + newmesh = fz_realloc(shade->mesh, sizeof(float) * newcap); + if (!newmesh) + return fz_outofmem; + + shade->mesh = newmesh; + shade->meshcap = newcap; + + return nil; +} + +static inline int setvertex(float *mesh, fz_point pt, float *color, int ptr, int ncomp) +{ + int i; + + mesh[ptr++] = pt.x; + mesh[ptr++] = pt.y; + for (i=0; i < ncomp; ++i) { + mesh[ptr++] = color[i]; + } + + return ptr; +} + +static int +triangulatepatch(pdf_tensorpatch p, fz_shade *shade, int ptr, int ncomp) +{ + fz_error* error; + + ptr = setvertex(shade->mesh, p.pole[0][0], p.color[0], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[3][0], p.color[1], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[3][3], p.color[2], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[0][0], p.color[0], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[3][3], p.color[2], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[0][3], p.color[3], ptr, ncomp); + + if (shade->meshcap - 1024 < ptr) { + error = growshademesh(shade, 1024); + if (error) goto cleanup; + } + + return ptr; + +cleanup: + // error handling + return -1; +} + +static int +drawstripe(pdf_tensorpatch patch, fz_shade *shade, int ptr, int ncomp, int depth) +{ + pdf_tensorpatch s0, s1; + + split_stripe(&s0, &s1, &patch); + + depth++; + + if (depth >= SEGMENTATION_DEPTH) + { + ptr = triangulatepatch(s0, shade, ptr, ncomp); + ptr = triangulatepatch(s1, shade, ptr, ncomp); + } + else { + ptr = drawstripe(s0, shade, ptr, ncomp, depth); + ptr = drawstripe(s1, shade, ptr, ncomp, depth); + } + + return ptr; +} + +static int +drawpatch(pdf_tensorpatch patch, fz_shade *shade, int ptr, int ncomp, int depth) +{ + pdf_tensorpatch s0, s1; + + split_patch(&s0, &s1, &patch); + depth++; + + if (depth > SEGMENTATION_DEPTH) + { + ptr = drawstripe(s0, shade, ptr, ncomp, 0); + ptr = drawstripe(s1, shade, ptr, ncomp, 0); + } + else { + ptr = drawpatch(s0, shade, ptr, ncomp, depth); + ptr = drawpatch(s1, shade, ptr, ncomp, depth); + } + + return ptr; +} + +fz_error * +pdf_loadtype6shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_error *error; + fz_stream *stream; + fz_obj *obj; + + int bpcoord; + int bpcomp; + int bpflag; + int ncomp; + + fz_point p0, p1; + + float c0[FZ_MAXCOLORS]; + float c1[FZ_MAXCOLORS]; + + int i, n, j; + unsigned int t; + + int flag; + fz_point p[12]; + + pdf_tensorpatch patch; + + error = nil; + + ncomp = shade->cs->n; + bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); + bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); + bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); + + obj = fz_dictgets(shading, "Decode"); + if (fz_isarray(obj)) + { + pdf_logshade("decode array\n"); + p0.x = fz_toreal(fz_arrayget(obj, 0)); + p1.x = fz_toreal(fz_arrayget(obj, 1)); + p0.y = fz_toreal(fz_arrayget(obj, 2)); + p1.y = fz_toreal(fz_arrayget(obj, 3)); + for (i=0; i < fz_arraylen(obj) / 2; ++i) { + c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); + c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); + } + } + else { + error = fz_throw("syntaxerror: No Decode key in Type 6 Shade"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Function"); + if (obj) { + ncomp = 1; + pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); + shade->usefunction = 1; + } + else + shade->usefunction = 0; + + shade->meshcap = 0; + shade->mesh = nil; + error = growshademesh(shade, 1024); + if (error) goto cleanup; + + n = 2 + shade->cs->n; + j = 0; + + error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); + if (error) goto cleanup; + + while (fz_peekbyte(stream) != EOF) + { + flag = getdata(stream, bpflag); + + for (i = 0; i < 12; ++i) { + t = getdata(stream, bpcoord); + p[i].x = (float)(p0.x + (t * (p1.x - p0.x) / (pow(2, bpcoord) - 1.))); + t = getdata(stream, bpcoord); + p[i].y = (float)(p0.y + (t * (p1.y - p0.y) / (pow(2, bpcoord) - 1.))); + } + + for (i = 0; i < 4; ++i) { + int k; + for (k=0; k < ncomp; ++k) { + t = getdata(stream, bpcomp); + patch.color[i][k] = + c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); + } + } + + patch.pole[0][0] = p[0]; + patch.pole[1][0] = p[1]; + patch.pole[2][0] = p[2]; + patch.pole[3][0] = p[3]; + patch.pole[3][1] = p[4]; + patch.pole[3][2] = p[5]; + patch.pole[3][3] = p[6]; + patch.pole[2][3] = p[7]; + patch.pole[1][3] = p[8]; + patch.pole[0][3] = p[9]; + patch.pole[0][2] = p[10]; + patch.pole[0][1] = p[11]; + filltensorinterior(&patch); + + j = drawpatch(patch, shade, j, ncomp, 0); + } + + fz_dropstream(stream); + + shade->meshlen = j / n / 3; + +cleanup: + + return nil; +} + +fz_error * +pdf_loadtype7shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_error *error; + fz_stream *stream; + fz_obj *obj; + + int bpcoord; + int bpcomp; + int bpflag; + int ncomp; + + float x0, x1, y0, y1; + + float c0[FZ_MAXCOLORS]; + float c1[FZ_MAXCOLORS]; + + int i, n, j; + unsigned int t; + + int flag; + fz_point p[16]; + pdf_tensorpatch patch; + + error = nil; + + ncomp = shade->cs->n; + bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); + bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); + bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); + + obj = fz_dictgets(shading, "Decode"); + if (fz_isarray(obj)) + { + pdf_logshade("decode array\n"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + x1 = fz_toreal(fz_arrayget(obj, 1)); + y0 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + for (i=0; i < fz_arraylen(obj) / 2; ++i) { + c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); + c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); + } + } + else { + error = fz_throw("syntaxerror: No Decode key in Type 6 Shade"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Function"); + if (obj) { + ncomp = 1; + pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); + shade->usefunction = 1; + } + else + shade->usefunction = 0; + + shade->meshcap = 0; + shade->mesh = nil; + error = growshademesh(shade, 1024); + if (error) goto cleanup; + + n = 2 + shade->cs->n; + j = 0; + + error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); + if (error) goto cleanup; + + while (fz_peekbyte(stream) != EOF) + { + flag = getdata(stream, bpflag); + + for (i = 0; i < 16; ++i) { + t = getdata(stream, bpcoord); + p[i].x = x0 + (t * (x1 - x0) / (pow(2, bpcoord) - 1.)); + t = getdata(stream, bpcoord); + p[i].y = y0 + (t * (y1 - y0) / (pow(2, bpcoord) - 1.)); + } + + for (i = 0; i < 4; ++i) { + int k; + for (k=0; k < ncomp; ++k) { + t = getdata(stream, bpcomp); + patch.color[i][k] = + c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); + } + } + + patch.pole[0][0] = p[0]; + patch.pole[0][1] = p[1]; + patch.pole[0][2] = p[2]; + patch.pole[0][3] = p[3]; + patch.pole[1][3] = p[4]; + patch.pole[2][3] = p[5]; + patch.pole[3][3] = p[6]; + patch.pole[3][2] = p[7]; + patch.pole[3][1] = p[8]; + patch.pole[3][0] = p[9]; + patch.pole[2][0] = p[10]; + patch.pole[1][0] = p[11]; + patch.pole[1][1] = p[12]; + patch.pole[1][2] = p[13]; + patch.pole[2][2] = p[14]; + patch.pole[2][1] = p[15]; + + j = drawpatch(patch, shade, j, ncomp, 0); + } + + fz_dropstream(stream); + + shade->meshlen = j / n / 3; + +cleanup: + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_store.c b/rosapps/smartpdf/fitz/mupdf/pdf_store.c new file mode 100644 index 00000000000..ee59fb671f9 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_store.c @@ -0,0 +1,183 @@ +#include +#include + +typedef struct pdf_item_s pdf_item; + +struct pdf_item_s +{ + pdf_itemkind kind; + fz_obj *key; + void *val; + pdf_item *next; +}; + +struct refkey +{ + pdf_itemkind kind; + int oid; + int gen; +}; + +struct pdf_store_s +{ + fz_hashtable *hash; /* hash for oid/gen keys */ + pdf_item *root; /* linked list for everything else */ +}; + +fz_error * +pdf_newstore(pdf_store **storep) +{ + fz_error *error; + pdf_store *store; + + store = fz_malloc(sizeof(pdf_store)); + if (!store) + return fz_outofmem; + + error = fz_newhash(&store->hash, 4096, sizeof(struct refkey)); + if (error) + { + fz_free(store); + return error; + } + + store->root = nil; + + *storep = store; + return nil; +} + +static void dropitem(pdf_itemkind kind, void *val) +{ + switch (kind) + { + case PDF_KCOLORSPACE: fz_dropcolorspace(val); break; + case PDF_KFUNCTION: pdf_dropfunction(val); break; + case PDF_KXOBJECT: pdf_dropxobject(val); break; + case PDF_KIMAGE: fz_dropimage(val); break; + case PDF_KPATTERN: pdf_droppattern(val); break; + case PDF_KSHADE: fz_dropshade(val); break; + case PDF_KCMAP: pdf_dropcmap(val); break; + case PDF_KFONT: fz_dropfont(val); break; + } +} + +void +pdf_emptystore(pdf_store *store) +{ + pdf_item *item; + pdf_item *next; + struct refkey *key; + void *val; + int i; + + for (i = 0; i < fz_hashlen(store->hash); i++) + { + key = fz_hashgetkey(store->hash, i); + val = fz_hashgetval(store->hash, i); + if (val) + dropitem(key->kind, val); + } + fz_emptyhash(store->hash); + + for (item = store->root; item; item = next) + { + next = item->next; + fz_dropobj(item->key); + dropitem(item->kind, item->val); + fz_free(item); + } + + store->root = nil; +} + +void +pdf_dropstore(pdf_store *store) +{ + pdf_emptystore(store); + fz_drophash(store->hash); + fz_free(store); +} + +fz_error * +pdf_storeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key, void *val) +{ + fz_error *error; + + switch (kind) + { + case PDF_KCOLORSPACE: fz_keepcolorspace(val); break; + case PDF_KFUNCTION: pdf_keepfunction(val); break; + case PDF_KXOBJECT: pdf_keepxobject(val); break; + case PDF_KIMAGE: fz_keepimage(val); break; + case PDF_KPATTERN: + pdf_keeppattern(val); + break; + case PDF_KSHADE: fz_keepshade(val); break; + case PDF_KCMAP: pdf_keepcmap(val); break; + case PDF_KFONT: fz_keepfont(val); break; + } + + if (fz_isindirect(key)) + { + struct refkey item; + + pdf_logrsrc("store item %d: %d %d R = %p\n", kind, fz_tonum(key), fz_togen(key), val); + + item.kind = kind; + item.oid = fz_tonum(key); + item.gen = fz_togen(key); + + error = fz_hashinsert(store->hash, &item, val); + if (error) + return error; + } + + else + { + pdf_item *item; + + item = fz_malloc(sizeof(pdf_item)); + if (!item) + return fz_outofmem; + + pdf_logrsrc("store item %d: ... = %p\n", kind, val); + + item->kind = kind; + item->key = fz_keepobj(key); + item->val = val; + + item->next = store->root; + store->root = item; + } + + return nil; +} + +void * +pdf_finditem(pdf_store *store, pdf_itemkind kind, fz_obj *key) +{ + pdf_item *item; + struct refkey refkey; + + if (key == nil) + return nil; + + if (fz_isindirect(key)) + { + refkey.kind = kind; + refkey.oid = fz_tonum(key); + refkey.gen = fz_togen(key); + return fz_hashfind(store->hash, &refkey); + } + + else + { + for (item = store->root; item; item = item->next) + if (item->kind == kind && !fz_objcmp(item->key, key)) + return item->val; + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_stream.c b/rosapps/smartpdf/fitz/mupdf/pdf_stream.c new file mode 100644 index 00000000000..0947c83ebd3 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_stream.c @@ -0,0 +1,492 @@ +#include "fitz.h" +#include "mupdf.h" + +/* + * Check if an object is a stream or not. + */ +int +pdf_isstream(pdf_xref *xref, int oid, int gen) +{ + fz_error *error; + + if (oid < 0 || oid >= xref->len) + return 0; + + error = pdf_cacheobject(xref, oid, gen); + if (error) { + fz_warn("%s", error->msg); + fz_droperror(error); + return 0; + } + + return xref->table[oid].stmbuf || xref->table[oid].stmofs; +} + +/* + * Create a filter given a name and param dictionary. + */ +static fz_error * +buildonefilter(fz_filter **fp, fz_obj *f, fz_obj *p) +{ + fz_filter *decompress; + fz_filter *predict; + fz_error *error; + char *s; + + s = fz_toname(f); + + if (!strcmp(s, "ASCIIHexDecode") || !strcmp(s, "AHx")) + return fz_newahxd(fp, p); + + if (!strcmp(s, "ASCII85Decode") || !strcmp(s, "A85")) + return fz_newa85d(fp, p); + + if (!strcmp(s, "CCITTFaxDecode") || !strcmp(s, "CCF")) + return fz_newfaxd(fp, p); + + if (!strcmp(s, "DCTDecode") || !strcmp(s, "DCT")) + return fz_newdctd(fp, p); + + if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL")) + return fz_newrld(fp, p); + + if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl")) + { + if (fz_isdict(p)) + { + fz_obj *obj = fz_dictgets(p, "Predictor"); + if (obj) + { + error = fz_newflated(&decompress, p); + if (error) + return error; + + error = fz_newpredictd(&predict, p); + if (error) + { + fz_dropfilter(decompress); + return error; + } + + error = fz_newpipeline(fp, decompress, predict); + fz_dropfilter(decompress); + fz_dropfilter(predict); + return error; + } + } + return fz_newflated(fp, p); + } + + if (!strcmp(s, "LZWDecode") || !strcmp(s, "LZW")) + { + if (fz_isdict(p)) + { + fz_obj *obj = fz_dictgets(p, "Predictor"); + if (obj) + { + error = fz_newlzwd(&decompress, p); + if (error) + return error; + + error = fz_newpredictd(&predict, p); + if (error) + { + fz_dropfilter(decompress); + return error; + } + + error = fz_newpipeline(fp, decompress, predict); + fz_dropfilter(decompress); + fz_dropfilter(predict); + return error; + } + } + return fz_newlzwd(fp, p); + } + +#ifdef HAVE_JBIG2DEC + if (!strcmp(s, "JBIG2Decode")) + { + /* TODO: extract and feed JBIG2Global */ + return fz_newjbig2d(fp, p); + } +#endif + +#ifdef HAVE_JASPER + if (!strcmp(s, "JPXDecode")) + return fz_newjpxd(fp, p); +#endif + + return fz_throw("syntaxerror: unknown filter: %s", s); +} + +/* + * Build a chain of filters given filter names and param dicts. + * If head is given, start filter chain with it. + * Assume ownership of head. + */ +static fz_error * +buildfilterchain(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps) +{ + fz_error *error; + fz_filter *newhead; + fz_filter *tail; + fz_obj *f; + fz_obj *p; + int i; + + for (i = 0; i < fz_arraylen(fs); i++) + { + f = fz_arrayget(fs, i); + if (fz_isarray(ps)) + p = fz_arrayget(ps, i); + else + p = nil; + + error = buildonefilter(&tail, f, p); + if (error) + return error; + + if (head) + { + error = fz_newpipeline(&newhead, head, tail); + fz_dropfilter(head); + fz_dropfilter(tail); + if (error) + { + fz_dropfilter(newhead); + return error; + } + head = newhead; + } + else + head = tail; + } + + *filterp = head; + return nil; +} + +/* + * Build a filter for reading raw stream data. + * This is a null filter to constrain reading to the + * stream length, followed by a decryption filter. + */ +static fz_error * +buildrawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen) +{ + fz_error *error; + fz_filter *base; + fz_obj *stmlen; + int len; + + stmlen = fz_dictgets(stmobj, "Length"); + error = pdf_resolve(&stmlen, xref); + if (error) + return error; + len = fz_toint(stmlen); + fz_dropobj(stmlen); + + error = fz_newnullfilter(&base, len); + if (error) + return error; + + if (xref->crypt) + { + fz_filter *crypt; + fz_filter *pipe; + + error = pdf_cryptstream(&crypt, xref->crypt, oid, gen); + if (error) + { + fz_dropfilter(base); + return error; + } + + error = fz_newpipeline(&pipe, base, crypt); + fz_dropfilter(base); + fz_dropfilter(crypt); + if (error) + return error; + + *filterp = pipe; + } + else + { + *filterp = base; + } + + return nil; +} + +/* + * Construct a filter to decode a stream, without + * constraining to stream length, and without decryption. + */ +fz_error * +pdf_buildinlinefilter(fz_filter **filterp, fz_obj *stmobj) +{ + fz_obj *filters; + fz_obj *params; + + filters = fz_dictgetsa(stmobj, "Filter", "F"); + params = fz_dictgetsa(stmobj, "DecodeParms", "DP"); + + *filterp = nil; + + if (filters) + { + if (fz_isname(filters)) + return buildonefilter(filterp, filters, params); + else if (fz_arraylen(filters) > 0) + return buildfilterchain(filterp, nil, filters, params); + } + + /* uh oh, no filter */ + + return nil; +} + +/* + * Construct a filter to decode a stream, constraining + * to stream length and decrypting. + */ +static fz_error * +pdf_buildfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen) +{ + fz_error *error; + fz_filter *base, *pipe, *tmp; + fz_obj *filters; + fz_obj *params; + + error = buildrawfilter(&base, xref, stmobj, oid, gen); + if (error) + return error; + + filters = fz_dictgetsa(stmobj, "Filter", "F"); + params = fz_dictgetsa(stmobj, "DecodeParms", "DP"); + + if (filters) + { + error = pdf_resolve(&filters, xref); + if (error) + goto cleanup0; + + if (params) + { + error = pdf_resolve(¶ms, xref); + if (error) + goto cleanup1; + } + + if (fz_isname(filters)) + { + error = buildonefilter(&tmp, filters, params); + if (error) + goto cleanup2; + + error = fz_newpipeline(&pipe, base, tmp); + fz_dropfilter(base); + fz_dropfilter(tmp); + if (error) + goto cleanup2; + } + else + { + error = buildfilterchain(&pipe, base, filters, params); + if (error) + goto cleanup2; + } + + if (params) + fz_dropobj(params); + + fz_dropobj(filters); + + *filterp = pipe; + } + else + { + *filterp = base; + } + + return nil; + +cleanup2: + if (params) + fz_dropobj(params); +cleanup1: + fz_dropobj(filters); +cleanup0: + fz_dropfilter(base); + return error; +} + +/* + * Open a stream for reading the raw (compressed but decrypted) data. + * Using xref->file while this is open is a bad idea. + */ +fz_error * +pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) +{ + pdf_xrefentry *x; + fz_error *error; + fz_filter *filter; + int n; + + if (oid < 0 || oid >= xref->len) + return fz_throw("rangecheck: object id out of range"); + + x = xref->table + oid; + + error = pdf_cacheobject(xref, oid, gen); + if (error) + return error; + + if (x->stmbuf) + { + return fz_openrbuffer(stmp, x->stmbuf); + } + + if (x->stmofs) + { + error = buildrawfilter(&filter, xref, x->obj, oid, gen); + if (error) + return error; + + n = fz_seek(xref->file, x->stmofs, 0); + if (n == -1) + { + fz_dropfilter(filter); + return fz_ioerror(xref->file); + } + + error = fz_openrfilter(stmp, filter, xref->file); + + fz_dropfilter(filter); + + if (error) + return error; + + return nil; + } + + return fz_throw("syntaxerror: object is not a stream"); +} + +/* + * Open a stream for reading uncompressed data. + * Put the opened file in xref->stream. + * Using xref->file while a stream is open is a Bad idea. + */ +fz_error * +pdf_openstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) +{ + pdf_xrefentry *x; + fz_error *error; + fz_stream *rawstm; + fz_filter *filter; + int n; + + if (oid < 0 || oid >= xref->len) + return fz_throw("rangecheck: object id out of range"); + + x = xref->table + oid; + + error = pdf_cacheobject(xref, oid, gen); + if (error) + return error; + + if (x->stmbuf) + { + error = pdf_buildfilter(&filter, xref, x->obj, oid, gen); + if (error) + return error; + + error = fz_openrbuffer(&rawstm, x->stmbuf); + if (error) + { + fz_dropfilter(filter); + return error; + } + + error = fz_openrfilter(stmp, filter, rawstm); + fz_dropfilter(filter); + fz_dropstream(rawstm); + return error; + } + + if (x->stmofs) + { + error = pdf_buildfilter(&filter, xref, x->obj, oid, gen); + if (error) + return error; + + n = fz_seek(xref->file, x->stmofs, 0); + if (n == -1) + { + fz_dropfilter(filter); + return fz_ioerror(xref->file); + } + + error = fz_openrfilter(stmp, filter, xref->file); + fz_dropfilter(filter); + if (error) + return error; + + return nil; + } + + return fz_throw("syntaxerror: object is not a stream"); +} + +/* + * Load raw (compressed but decrypted) contents of a stream into buf. + */ +fz_error * +pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen) +{ + fz_error *error; + fz_stream *stm; + int n; + + error = pdf_openrawstream(&stm, xref, oid, gen); + if (error) + return error; + + n = fz_readall(bufp, stm); + if (n < 0) + error = fz_ioerror(stm); + else + error = nil; + + fz_dropstream(stm); + + return error; +} + +/* + * Load uncompressed contents of a stream into buf. + */ +fz_error * +pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen) +{ + fz_error *error; + fz_stream *stm; + int n; + + error = pdf_openstream(&stm, xref, oid, gen); + if (error) + return error; + + n = fz_readall(bufp, stm); + if (n < 0) + error = fz_ioerror(stm); + else + error = nil; + + fz_dropstream(stm); + + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_type3.c b/rosapps/smartpdf/fitz/mupdf/pdf_type3.c new file mode 100644 index 00000000000..c2ede330f4c --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_type3.c @@ -0,0 +1,311 @@ +#include +#include + +#define GCMEM (4 * 1024) + +extern pdf_font *pdf_newfont(char *name); + +static void +t3dropfont(fz_font *font) +{ + int i; + pdf_font *pfont = (pdf_font*)font; + if (pfont->encoding) + pdf_dropcmap(pfont->encoding); + for (i = 0; i < 256; i++) + if (pfont->charprocs[i]) + fz_droptree(pfont->charprocs[i]); +} + +static fz_error * +t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm) +{ + pdf_font *font = (pdf_font*)fzfont; + fz_error *error; + fz_renderer *gc; + fz_tree *tree; + fz_pixmap *pixmap; + fz_matrix ctm; + fz_irect bbox; + + if (cid < 0 || cid > 255) + return fz_throw("rangecheck: glyph out of range"); + + tree = font->charprocs[cid]; + if (!tree) + { + glyph->w = 0; + glyph->h = 0; + return nil; + } + + ctm = fz_concat(font->matrix, trm); + bbox = fz_roundrect(fz_boundtree(tree, ctm)); + + error = fz_newrenderer(&gc, pdf_devicegray, 1, GCMEM); + if (error) + return error; + error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0); + fz_droprenderer(gc); + if (error) + return error; + + assert(pixmap->n == 1); + + glyph->x = pixmap->x; + glyph->y = pixmap->y; + glyph->w = pixmap->w; + glyph->h = pixmap->h; + glyph->samples = pixmap->samples; + + return nil; +} + +static fz_error * +loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) +{ + fz_error *error; + pdf_csi *csi; + fz_stream *stm; + + error = pdf_newcsi(&csi, 1); + + error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref)); + if (error) + return error; + + error = pdf_runcsi(csi, xref, rdb, stm); + + fz_dropstream(stm); + + *treep = csi->tree; + csi->tree = nil; + + pdf_dropcsi(csi); + + return error; +} + +fz_error * +pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + char buf[256]; + char *estrings[256]; + pdf_font *font; + fz_obj *encoding; + fz_obj *widths; + fz_obj *resources; + fz_obj *charprocs; + fz_obj *obj; + int first, last; + int i, k, n; + fz_rect bbox; + + obj = fz_dictgets(dict, "Name"); + if (obj) + strlcpy(buf, fz_toname(obj), sizeof buf); + else + sprintf(buf, "Unnamed-T3"); + + font = pdf_newfont(buf); + if (!font) + return fz_outofmem; + + pdf_logfont("load type3 font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font); + pdf_logfont("name %s\n", buf); + + font->super.render = t3render; + font->super.drop = (void(*)(fz_font*)) t3dropfont; + + obj = fz_dictgets(dict, "FontMatrix"); + font->matrix = pdf_tomatrix(obj); + + pdf_logfont("matrix [%g %g %g %g %g %g]\n", + font->matrix.a, font->matrix.b, + font->matrix.c, font->matrix.d, + font->matrix.e, font->matrix.f); + + obj = fz_dictgets(dict, "FontBBox"); + bbox = pdf_torect(obj); + + pdf_logfont("bbox [%g %g %g %g]\n", + bbox.x0, bbox.y0, + bbox.x1, bbox.y1); + + bbox = fz_transformaabb(font->matrix, bbox); + bbox.x0 = fz_floor(bbox.x0 * 1000); + bbox.y0 = fz_floor(bbox.y0 * 1000); + bbox.x1 = fz_ceil(bbox.x1 * 1000); + bbox.y1 = fz_ceil(bbox.y1 * 1000); + fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); + + /* + * Encoding + */ + + for (i = 0; i < 256; i++) + estrings[i] = nil; + + encoding = fz_dictgets(dict, "Encoding"); + if (!encoding) { + error = fz_throw("syntaxerror: Type3 font missing Encoding"); + goto cleanup; + } + + error = pdf_resolve(&encoding, xref); + if (error) + goto cleanup; + + if (fz_isname(obj)) + pdf_loadencoding(estrings, fz_toname(encoding)); + + if (fz_isdict(encoding)) + { + fz_obj *base, *diff, *item; + + base = fz_dictgets(encoding, "BaseEncoding"); + if (fz_isname(base)) + pdf_loadencoding(estrings, fz_toname(base)); + + diff = fz_dictgets(encoding, "Differences"); + if (fz_isarray(diff)) + { + n = fz_arraylen(diff); + k = 0; + for (i = 0; i < n; i++) + { + item = fz_arrayget(diff, i); + if (fz_isint(item)) + k = fz_toint(item); + if (fz_isname(item)) + estrings[k++] = fz_toname(item); + if (k < 0) k = 0; + if (k > 255) k = 255; + } + } + } + + fz_dropobj(encoding); + + error = pdf_newidentitycmap(&font->encoding, 0, 1); + if (error) + goto cleanup; + + error = pdf_loadtounicode(font, xref, + estrings, nil, fz_dictgets(dict, "ToUnicode")); + if (error) + goto cleanup; + + /* + * Widths + */ + + fz_setdefaulthmtx((fz_font*)font, 0); + + first = fz_toint(fz_dictgets(dict, "FirstChar")); + last = fz_toint(fz_dictgets(dict, "LastChar")); + + widths = fz_dictgets(dict, "Widths"); + if (!widths) { + error = fz_throw("syntaxerror: Type3 font missing Widths"); + goto cleanup; + } + + error = pdf_resolve(&widths, xref); + if (error) + goto cleanup; + + for (i = first; i <= last; i++) + { + float w = fz_toreal(fz_arrayget(widths, i - first)); + w = font->matrix.a * w * 1000.0; + error = fz_addhmtx((fz_font*)font, i, i, w); + if (error) { + fz_dropobj(widths); + goto cleanup; + } + } + + fz_dropobj(widths); + + error = fz_endhmtx((fz_font*)font); + if (error) + goto cleanup; + + /* + * Resources + */ + + resources = nil; + + obj = fz_dictgets(dict, "Resources"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + goto cleanup; + + error = pdf_loadresources(&resources, xref, obj); + + fz_dropobj(obj); + + if (error) + goto cleanup; + } + else + pdf_logfont("no resource dict!\n"); + + /* + * CharProcs + */ + + charprocs = fz_dictgets(dict, "CharProcs"); + if (!charprocs) + { + error = fz_throw("syntaxerror: Type3 font missing CharProcs"); + goto cleanup2; + } + + error = pdf_resolve(&charprocs, xref); + if (error) + goto cleanup2; + + for (i = 0; i < 256; i++) + { + if (estrings[i]) + { + obj = fz_dictgets(charprocs, estrings[i]); + if (obj) + { + pdf_logfont("load charproc %s {\n", estrings[i]); + error = loadcharproc(&font->charprocs[i], xref, resources, obj); + if (error) + goto cleanup2; + + error = fz_optimizetree(font->charprocs[i]); + if (error) + goto cleanup2; + + pdf_logfont("}\n"); + } + } + } + + fz_dropobj(charprocs); + if (resources) + fz_dropobj(resources); + + pdf_logfont("}\n"); + + *fontp = font; + return nil; + +cleanup2: + if (resources) + fz_dropobj(resources); +cleanup: + fz_dropfont((fz_font*)font); + return error; +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_unicode.c b/rosapps/smartpdf/fitz/mupdf/pdf_unicode.c new file mode 100644 index 00000000000..7affd1b971d --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_unicode.c @@ -0,0 +1,318 @@ +#include +#include + +/* + * ToUnicode map for fonts + */ + +fz_error * +pdf_loadtounicode(pdf_font *font, pdf_xref *xref, + char **strings, char *collection, fz_obj *cmapstm) +{ + fz_error *error; + pdf_cmap *cmap; + int cid; + int ucs; + int i; + + if (fz_isindirect(cmapstm)) + { + pdf_logfont("tounicode embedded cmap\n"); + + error = pdf_loadembeddedcmap(&cmap, xref, cmapstm); + if (error) + return error; + + error = pdf_newcmap(&font->tounicode); + if (error) + goto cleanup; + + for (i = 0; i < (strings ? 256 : 65536); i++) + { + cid = pdf_lookupcmap(font->encoding, i); + if (cid > 0) + { + ucs = pdf_lookupcmap(cmap, i); + if (ucs > 0) + { + error = pdf_maprangetorange(font->tounicode, cid, cid, ucs); + if (error) + goto cleanup; + } + } + } + + error = pdf_sortcmap(font->tounicode); + if (error) + goto cleanup; + + cleanup: + pdf_dropcmap(cmap); + return error; + } + + else if (collection) + { + pdf_logfont("tounicode cid collection\n"); + + if (!strcmp(collection, "Adobe-CNS1")) + return pdf_loadsystemcmap(&font->tounicode, "Adobe-CNS1-UCS2"); + else if (!strcmp(collection, "Adobe-GB1")) + return pdf_loadsystemcmap(&font->tounicode, "Adobe-GB1-UCS2"); + else if (!strcmp(collection, "Adobe-Japan1")) + return pdf_loadsystemcmap(&font->tounicode, "Adobe-Japan1-UCS2"); + else if (!strcmp(collection, "Adobe-Japan2")) + return pdf_loadsystemcmap(&font->tounicode, "Adobe-Japan2-UCS2"); + else if (!strcmp(collection, "Adobe-Korea1")) + return pdf_loadsystemcmap(&font->tounicode, "Adobe-Korea1-UCS2"); + } + + if (strings) + { + pdf_logfont("tounicode strings\n"); + + /* TODO use tounicode cmap here ... for one-to-many mappings */ + + font->ncidtoucs = 256; + font->cidtoucs = fz_malloc(256 * sizeof(unsigned short)); + if (!font->cidtoucs) + return fz_outofmem; + + for (i = 0; i < 256; i++) + { + if (strings[i]) + { + int aglbuf[256]; + int aglnum; + aglnum = pdf_lookupagl(strings[i], aglbuf, nelem(aglbuf)); + if (aglnum > 0) + font->cidtoucs[i] = aglbuf[0]; + else + font->cidtoucs[i] = '?'; + } + else + font->cidtoucs[i] = '?'; + } + + return nil; + } + + pdf_logfont("tounicode impossible"); + return nil; +} + +/* + * Extract lines of text from display tree + */ + +fz_error * +pdf_newtextline(pdf_textline **linep) +{ + pdf_textline *line; + line = *linep = fz_malloc(sizeof(pdf_textline)); + if (!line) + return fz_outofmem; + line->len = 0; + line->cap = 0; + line->text = nil; + line->next = nil; + return nil; +} + +void +pdf_droptextline(pdf_textline *line) +{ + if (line->next) + pdf_droptextline(line->next); + fz_free(line->text); + fz_free(line); +} + +static fz_error * +addtextchar(pdf_textline *line, fz_irect bbox, int c) +{ + pdf_textchar *newtext; + int newcap; + + if (line->len + 1 >= line->cap) + { + newcap = line->cap ? line->cap * 2 : 80; + newtext = fz_realloc(line->text, sizeof(pdf_textchar) * newcap); + if (!newtext) + return fz_outofmem; + line->cap = newcap; + line->text = newtext; + } + + line->text[line->len].bbox = bbox; + line->text[line->len].c = c; + line->len ++; + + return nil; +} + +/* XXX global! not reentrant! */ +static fz_point oldpt = { 0, 0 }; + +static fz_error * +extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm) +{ + fz_error *error; + + if (fz_istextnode(node)) + { + fz_textnode *text = (fz_textnode*)node; + pdf_font *font = (pdf_font*)text->font; + fz_matrix inv = fz_invertmatrix(text->trm); + fz_matrix tm = text->trm; + fz_matrix trm; + float dx, dy, t; + fz_point p; + fz_point vx; + fz_point vy; + fz_vmtx v; + fz_hmtx h; + int i, g; + int x, y; + fz_irect box; + int c; + + for (i = 0; i < text->len; i++) + { + g = text->els[i].cid; + + tm.e = text->els[i].x; + tm.f = text->els[i].y; + trm = fz_concat(tm, ctm); + x = trm.e; + y = trm.f; + trm.e = 0; + trm.f = 0; + + p.x = text->els[i].x; + p.y = text->els[i].y; + p = fz_transformpoint(inv, p); + dx = oldpt.x - p.x; + dy = oldpt.y - p.y; + oldpt = p; + + if (text->font->wmode == 0) + { + h = fz_gethmtx(text->font, g); + oldpt.x += h.w * 0.001; + + vx.x = h.w * 0.001; vx.y = 0; + vy.x = 0; vy.y = 1; + } + else + { + v = fz_getvmtx(text->font, g); + oldpt.y += v.w * 0.001; + t = dy; dy = dx; dx = t; + + vx.x = 0.5; vx.y = 0; + vy.x = 0; vy.y = v.w * 0.001; + } + + if (fabs(dy) > 0.2) + { + pdf_textline *newline; + error = pdf_newtextline(&newline); + if (error) + return error; + (*line)->next = newline; + *line = newline; + } + else if (fabs(dx) > 0.2) + { + box.x0 = x; box.x1 = x; + box.y0 = y; box.y1 = y; + error = addtextchar(*line, box, ' '); + if (error) + return error; + } + + vx = fz_transformpoint(trm, vx); + vy = fz_transformpoint(trm, vy); + box.x0 = MIN(0, MIN(vx.x, vy.x)) + x; + box.x1 = MAX(0, MAX(vx.x, vy.x)) + x; + box.y0 = MIN(0, MIN(vx.y, vy.y)) + y; + box.y1 = MAX(0, MAX(vx.y, vy.y)) + y; + + if (font->tounicode) + c = pdf_lookupcmap(font->tounicode, g); + else if (g < font->ncidtoucs) + c = font->cidtoucs[g]; + else + c = g; + + error = addtextchar(*line, box, c); + if (error) + return error; + } + } + + if (fz_istransformnode(node)) + ctm = fz_concat(((fz_transformnode*)node)->m, ctm); + + for (node = node->first; node; node = node->next) + { + error = extracttext(line, node, ctm); + if (error) + return error; + } + + return nil; +} + +fz_error * +pdf_loadtextfromtree(pdf_textline **outp, fz_tree *tree, fz_matrix ctm) +{ + pdf_textline *root; + pdf_textline *line; + fz_error *error; + + oldpt.x = -1; + oldpt.y = -1; + + error = pdf_newtextline(&root); + if (error) + return error; + + line = root; + + error = extracttext(&line, tree->root, ctm); + if (error) + { + pdf_droptextline(root); + return error; + } + + *outp = root; + return nil; +} + +void +pdf_debugtextline(pdf_textline *line) +{ + char buf[10]; + int c, n, k, i; + + for (i = 0; i < line->len; i++) + { + c = line->text[i].c; + if (c < 128) + putchar(c); + else + { + n = runetochar(buf, &c); + for (k = 0; k < n; k++) + putchar(buf[k]); + } + } + putchar('\n'); + + if (line->next) + pdf_debugtextline(line->next); +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_xobject.c b/rosapps/smartpdf/fitz/mupdf/pdf_xobject.c new file mode 100644 index 00000000000..0819f04b8a6 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_xobject.c @@ -0,0 +1,102 @@ +#include +#include + +fz_error * +pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + pdf_xobject *form; + fz_obj *obj; + + if ((*formp = pdf_finditem(xref->store, PDF_KXOBJECT, ref))) + { + pdf_keepxobject(*formp); + return nil; + } + + form = fz_malloc(sizeof(pdf_xobject)); + if (!form) + return fz_outofmem; + + form->refs = 1; + form->resources = nil; + form->contents = nil; + + pdf_logrsrc("load xobject %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), form); + + obj = fz_dictgets(dict, "BBox"); + form->bbox = pdf_torect(obj); + + pdf_logrsrc("bbox [%g %g %g %g]\n", + form->bbox.x0, form->bbox.y0, + form->bbox.x1, form->bbox.y1); + + obj = fz_dictgets(dict, "Matrix"); + if (obj) + form->matrix = pdf_tomatrix(obj); + else + form->matrix = fz_identity(); + + pdf_logrsrc("matrix [%g %g %g %g %g %g]\n", + form->matrix.a, form->matrix.b, + form->matrix.c, form->matrix.d, + form->matrix.e, form->matrix.f); + + obj = fz_dictgets(dict, "Resources"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + { + pdf_dropxobject(form); + return error; + } + error = pdf_loadresources(&form->resources, xref, obj); + fz_dropobj(obj); + if (error) + { + pdf_dropxobject(form); + return error; + } + } + + error = pdf_loadstream(&form->contents, xref, fz_tonum(ref), fz_togen(ref)); + if (error) + { + pdf_dropxobject(form); + return error; + } + + pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp); + + pdf_logrsrc("}\n"); + + error = pdf_storeitem(xref->store, PDF_KXOBJECT, ref, form); + if (error) + { + pdf_dropxobject(form); + return error; + } + + *formp = form; + return nil; +} + +pdf_xobject * +pdf_keepxobject(pdf_xobject *xobj) +{ + xobj->refs ++; + return xobj; +} + +void +pdf_dropxobject(pdf_xobject *xobj) +{ + if (--xobj->refs == 0) + { + if (xobj->contents) fz_dropbuffer(xobj->contents); + if (xobj->resources) fz_dropobj(xobj->resources); + fz_free(xobj); + } +} + diff --git a/rosapps/smartpdf/fitz/mupdf/pdf_xref.c b/rosapps/smartpdf/fitz/mupdf/pdf_xref.c new file mode 100644 index 00000000000..44338474485 --- /dev/null +++ b/rosapps/smartpdf/fitz/mupdf/pdf_xref.c @@ -0,0 +1,455 @@ +#include +#include + +/* + * create xref structure. + * needs to be initialized by initxref, openxref or repairxref. + */ + +fz_error * +pdf_newxref(pdf_xref **xrefp) +{ + pdf_xref *xref; + + xref = fz_malloc(sizeof(pdf_xref)); + if (!xref) + return fz_outofmem; + memset(xref, 0, sizeof(pdf_xref)); + + pdf_logxref("newxref %p\n", xref); + + xref->file = nil; + xref->version = 1.3f; + xref->startxref = 0; + xref->crypt = nil; + + xref->trailer = nil; + xref->root = nil; + xref->info = nil; + xref->dests = nil; + xref->store = nil; + + xref->cap = 0; + xref->len = 0; + xref->table = nil; + + xref->store = nil; /* you need to create this if you want to render */ + + *xrefp = xref; + return nil; +} + +void +pdf_closexref(pdf_xref *xref) +{ + pdf_logxref("closexref %p\n", xref); + + if (xref->store) + fz_warn("someone forgot to empty the store before freeing xref!"); + + if (xref->table) + { + pdf_flushxref(xref, 1); + fz_free(xref->table); + } + + if (xref->file) + fz_dropstream(xref->file); + + if (xref->crypt) + pdf_dropcrypt(xref->crypt); + if (xref->trailer) + fz_dropobj(xref->trailer); + if (xref->root) + fz_dropobj(xref->root); + if (xref->info) + fz_dropobj(xref->info); + if (xref->dests) + fz_dropobj(xref->dests); + + fz_free(xref); +} + +fz_error * +pdf_initxref(pdf_xref *xref) +{ + xref->table = fz_malloc(sizeof(pdf_xrefentry) * 128); + if (!xref->table) + return fz_outofmem; + + xref->cap = 128; + xref->len = 1; + + xref->table[0].type = 'f'; + xref->table[0].mark = 0; + xref->table[0].ofs = 0; + xref->table[0].gen = 65535; + xref->table[0].stmbuf = nil; + xref->table[0].stmofs = 0; + xref->table[0].obj = nil; + + return nil; +} + +void +pdf_flushxref(pdf_xref *xref, int force) +{ + int i; + + pdf_logxref("flushxref %p (%d)\n", xref, force); + + for (i = 0; i < xref->len; i++) + { + if (force) + { + if (xref->table[i].stmbuf) + { + fz_dropbuffer(xref->table[i].stmbuf); + xref->table[i].stmbuf = nil; + } + if (xref->table[i].obj) + { + fz_dropobj(xref->table[i].obj); + xref->table[i].obj = nil; + } + } + else + { + if (xref->table[i].stmbuf && xref->table[i].stmbuf->refs == 1) + { + fz_dropbuffer(xref->table[i].stmbuf); + xref->table[i].stmbuf = nil; + } + if (xref->table[i].obj && xref->table[i].obj->refs == 1) + { + fz_dropobj(xref->table[i].obj); + xref->table[i].obj = nil; + } + } + } +} + +void +pdf_debugxref(pdf_xref *xref) +{ + int i; + printf("xref\n0 %d\n", xref->len); + for (i = 0; i < xref->len; i++) + { + printf("%010d %05d %c | %d %c%c\n", + xref->table[i].ofs, + xref->table[i].gen, + xref->table[i].type, + xref->table[i].obj ? xref->table[i].obj->refs : 0, + xref->table[i].stmofs ? 'f' : '-', + xref->table[i].stmbuf ? 'b' : '-'); + } +} + +/* ICKY! */ +fz_error * +pdf_decryptxref(pdf_xref *xref) +{ + fz_error *error; + fz_obj *encrypt; + fz_obj *id; + + encrypt = fz_dictgets(xref->trailer, "Encrypt"); + id = fz_dictgets(xref->trailer, "ID"); + + if (encrypt && id) + { + error = pdf_resolve(&encrypt, xref); + if (error) + return error; + + if (fz_isnull(encrypt)) + { + fz_dropobj(encrypt); + return nil; + } + + error = pdf_resolve(&id, xref); + if (error) + { + fz_dropobj(encrypt); + return error; + } + + error = pdf_newdecrypt(&xref->crypt, encrypt, id); + fz_dropobj(encrypt); + fz_dropobj(id); + return error; + } + + return nil; +} + +/* + * mutate objects + */ + +static int findprev(pdf_xref *xref, int oid) +{ + int prev; + for (prev = oid - 1; prev >= 0; prev--) + if (xref->table[prev].type == 'f' || xref->table[prev].type == 'd') + return prev; + return 0; +} + +static int findnext(pdf_xref *xref, int oid) +{ + int next; + for (next = oid + 1; next < xref->len; next++) + if (xref->table[next].type == 'f' || xref->table[next].type == 'd') + return next; + return 0; +} + +fz_error * +pdf_allocobject(pdf_xref *xref, int *oidp, int *genp) +{ + pdf_xrefentry *x; + int prev, next; + int oid = 0; + + pdf_logxref("allocobj"); + + while (1) + { + x = xref->table + oid; + + if (x->type == 'f' || x->type == 'd') + { + if (x->gen < 65535) + { + *oidp = oid; + *genp = x->gen; + + pdf_logxref(" reuse %d %d\n", *oidp, *genp); + + x->type = 'a'; + x->ofs = 0; + + prev = findprev(xref, oid); + next = findnext(xref, oid); + xref->table[prev].type = 'd'; + xref->table[prev].ofs = next; + + return nil; + } + } + + oid = x->ofs; + + if (oid == 0) + break; + } + + if (xref->len + 1 >= xref->cap) + { + int newcap = xref->cap + 256; + pdf_xrefentry *newtable; + + newtable = fz_realloc(xref->table, sizeof(pdf_xrefentry) * newcap); + if (!newtable) + return fz_outofmem; + + xref->table = newtable; + xref->cap = newcap; + } + + oid = xref->len ++; + + xref->table[oid].type = 'a'; + xref->table[oid].mark = 0; + xref->table[oid].ofs = 0; + xref->table[oid].gen = 0; + xref->table[oid].stmbuf = nil; + xref->table[oid].stmofs = 0; + xref->table[oid].obj = nil; + + *oidp = oid; + *genp = 0; + + pdf_logxref(" %d %d\n", *oidp, *genp); + + prev = findprev(xref, oid); + next = findnext(xref, oid); + xref->table[prev].type = 'd'; + xref->table[prev].ofs = next; + + return nil; +} + +fz_error * +pdf_deleteobject(pdf_xref *xref, int oid, int gen) +{ + pdf_xrefentry *x; + int prev; + + if (oid < 0 || oid >= xref->len) + return fz_throw("rangecheck: object number out of range: %d", oid); + + pdf_logxref("deleteobj %d %d\n", oid, gen); + + x = xref->table + oid; + + x->type = 'd'; + x->ofs = findnext(xref, oid); + x->gen ++; + + if (x->stmbuf) + fz_dropbuffer(x->stmbuf); + x->stmbuf = nil; + + if (x->obj) + fz_dropobj(x->obj); + x->obj = nil; + + prev = findprev(xref, oid); + xref->table[prev].type = 'd'; + xref->table[prev].ofs = oid; + + return nil; +} + +fz_error * +pdf_updateobject(pdf_xref *xref, int oid, int gen, fz_obj *obj) +{ + pdf_xrefentry *x; + + if (oid < 0 || oid >= xref->len) + return fz_throw("rangecheck: object number out of range: %d", oid); + + pdf_logxref("updateobj %d %d (%p)\n", oid, gen, obj); + + x = xref->table + oid; + + if (x->obj) + fz_dropobj(x->obj); + x->obj = fz_keepobj(obj); + + if (x->type == 'f' || x->type == 'd') + { + int prev = findprev(xref, oid); + int next = findnext(xref, oid); + xref->table[prev].type = 'd'; + xref->table[prev].ofs = next; + } + + x->type = 'a'; + + return nil; +} + +fz_error * +pdf_updatestream(pdf_xref *xref, int oid, int gen, fz_buffer *stm) +{ + pdf_xrefentry *x; + + if (oid < 0 || oid >= xref->len) + return fz_throw("rangecheck: object number out of range: %d", oid); + + pdf_logxref("updatestm %d %d (%p)\n", oid, gen, stm); + + x = xref->table + oid; + + if (x->stmbuf) + fz_dropbuffer(x->stmbuf); + x->stmbuf = fz_keepbuffer(stm); + + return nil; +} + +/* + * object loading + */ + +fz_error * +pdf_cacheobject(pdf_xref *xref, int oid, int gen) +{ + char buf[65536]; /* yeowch! */ + + fz_error *error; + pdf_xrefentry *x; + int roid, rgen; + int n; + + if (oid < 0 || oid >= xref->len) + return fz_throw("rangecheck: object number out of range: %d", oid); + + x = &xref->table[oid]; + + if (x->obj) + return nil; + + if (x->type == 'f' || x->type == 'd') + { + error = fz_newnull(&x->obj); + if (error) + return error; + return nil; + } + + if (x->type == 'n') + { + n = fz_seek(xref->file, x->ofs, 0); + if (n < 0) + return fz_ioerror(xref->file); + + error = pdf_parseindobj(&x->obj, xref->file, buf, sizeof buf, &roid, &rgen, &x->stmofs); + if (error) + return error; + + if (roid != oid || rgen != gen) + return fz_throw("syntaxerror: found wrong object"); + + if (xref->crypt) + pdf_cryptobj(xref->crypt, x->obj, oid, gen); + } + + else if (x->type == 'o') + { + if (!x->obj) + { + error = pdf_loadobjstm(xref, x->ofs, 0, buf, sizeof buf); + if (error) + return error; + } + } + + return nil; +} + +fz_error * +pdf_loadobject(fz_obj **objp, pdf_xref *xref, int oid, int gen) +{ + fz_error *error; + + error = pdf_cacheobject(xref, oid, gen); + if (error) + return error; + + *objp = fz_keepobj(xref->table[oid].obj); + + return nil; +} + +fz_error * +pdf_loadindirect(fz_obj **objp, pdf_xref *xref, fz_obj *ref) +{ + assert(ref != nil); + return pdf_loadobject(objp, xref, fz_tonum(ref), fz_togen(ref)); +} + +fz_error * +pdf_resolve(fz_obj **objp, pdf_xref *xref) +{ + if (fz_isindirect(*objp)) + return pdf_loadindirect(objp, xref, *objp); + fz_keepobj(*objp); + return nil; +} + diff --git a/rosapps/smartpdf/fitz/raster/archppc.c b/rosapps/smartpdf/fitz/raster/archppc.c new file mode 100644 index 00000000000..30dbd7807c5 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/archppc.c @@ -0,0 +1,67 @@ +/* + * PowerPC specific render optims live here + */ + +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef unsigned char byte; + +#ifdef HAVE_ALTIVEC + +static void srow1ppc(byte *src, byte *dst, int w, int denom) +{ + int x, left; + int sum; + + left = 0; + sum = 0; + + for (x = 0; x < w; x++) + { + sum += *src++; + if (++left == denom) + { + left = 0; + *dst++ = sum / denom; + sum = 0; + } + } + + if (left) + *dst++ = sum / left; +} + +static void scol1ppc(byte *src, byte *dst, int w, int denom) +{ + int x, y; + unsigned char *s; + int sum; + + for (x = 0; x < w; x++) + { + s = src + x; + sum = 0; + for (y = 0; y < denom; y++) + sum += s[y * w]; + *dst++ = sum / denom; + } +} + +#endif /* HAVE_ALTIVEC */ + +#if defined (ARCH_PPC) +void +fz_accelerate(void) +{ +# ifdef HAVE_ALTIVEC + if (fz_cpuflags & HAVE_ALTIVEC) + { + fz_srow1 = srow1ppc; + fz_scol1 = scol1ppc; + } +# endif +} +#endif + diff --git a/rosapps/smartpdf/fitz/raster/archsparc.c b/rosapps/smartpdf/fitz/raster/archsparc.c new file mode 100644 index 00000000000..b78e5a4d40c --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/archsparc.c @@ -0,0 +1,23 @@ +/* +SPARC specific render optims live here +*/ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +#ifdef HAVE_VIS + +#endif + +#if defined (ARCH_SPARC) +void +fz_accelerate(void) +{ +# ifdef HAVE_VIS + if (fz_cpuflags & HAVE_VIS) + { + } +# endif +} +#endif + diff --git a/rosapps/smartpdf/fitz/raster/archx86.c b/rosapps/smartpdf/fitz/raster/archx86.c new file mode 100644 index 00000000000..089edf0241d --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/archx86.c @@ -0,0 +1,229 @@ +/* + * x86 specific render optims live here + */ + +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef unsigned char byte; + +/* always surround cpu specific code with HAVE_XXX */ +#ifdef HAVE_MMX + +/* -mmmx for gcc >= 3.4 enables the mmx intrinsic functions, icc and VC + shouldn't require anything */ +#include + +static void duff_4i1o4mmx(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h) +{ + /* + rendering all pages of + x11pdf ~/doc/OpenGL/Presentations/CEDEC2003_Venus_and_Vulcan.pdf + % cumulative self self total + time seconds seconds calls ms/call ms/call name + 30.50 20.04 20.04 261 76.76 76.76 duff_4i1o4 + 21.67 22.02 10.95 221 49.55 49.55 duff_4i1o4mmx + */ + __m64 mzero = _mm_setzero_si64(); + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + + unsigned *s = (unsigned *)sp; + unsigned *d = (unsigned *)dp; + + int w = w0; + + /* TODO: unroll and process two pixels/iteration */ + while (w--) + { + int ts = *s++; + int ma = *mp++ + 1; + int sa = ((ts & 0xff) * ma) >> 8; + int ssa = 256 - sa; + + __m64 d0 = _mm_cvtsi32_si64(*d); + __m64 s0 = _mm_cvtsi32_si64(ts); + + /* 4 x 9 bit alpha value */ + __m64 mma = _mm_set1_pi16(ma); + __m64 mssa = _mm_set1_pi16(ssa); + + /* unpack 0000argb => a0r0g0b0 */ + __m64 d1 = _mm_unpacklo_pi8(d0, mzero); + __m64 s1 = _mm_unpacklo_pi8(s0, mzero); + + /* s1 * ma => a0r0g0b0 */ + __m64 msma = _mm_mullo_pi16(s1, mma); + /* d1 * mssa */ + __m64 mdssa = _mm_mullo_pi16(d1, mssa); + + __m64 res0 = _mm_add_pi16(msma, mdssa); + /* TODO: is it possible to get rid of the shift? */ + __m64 res1 = _mm_srli_pi16(res0, 8); + + /* pack */ + __m64 res2 = _mm_packs_pu16(res1, mzero); + + *d++ = _mm_cvtsi64_si32(res2); + } + + sp0 += sw; + mp0 += mw; + dp0 += dw; + } + + _mm_empty(); +} + +static inline unsigned +getargb(unsigned *s, int w, int h, int u, int v) +{ + if (u < 0 | u >= w | v < 0 | v >= h) return 0; + return s[w * v + u]; +} + +static void img_4o4mmx(FZ_PSRC, FZ_PDST, FZ_PCTM) +{ + /* since mmx does not have an unsigned multiply instruction we use + 17.15 fixed point */ + u0 <<= 1; v0 <<= 1; + fa <<= 1; fb <<= 1; + fc <<= 1; fd <<= 1; + + while (h--) + { + unsigned *s = (unsigned *)src; + unsigned *d = (unsigned *)dst0; + int u = u0; + int v = v0; + int w = w0; + + __m64 mzero = _mm_setzero_si64(); + __m64 m256 = _mm_set1_pi16(256); + __m64 malphamask = _mm_cvtsi32_si64(0xff); + + while (w--) + { + int iu = u >> 17; + int iv = v >> 17; + + int fu = u & 0x7fff; + int fv = v & 0x7fff; + + int atedge = + iu < 0 | iu >= (srcw - 1) | + iv < 0 | iv >= (srch - 1); + + __m64 ms0s1; + __m64 ms2s3; + + if (atedge) + { + unsigned s0, s1, s2, s3; + + /* edge cases use scalar loads */ + s0 = getargb(s, srcw, srch, iu + 0, iv + 0); + s1 = getargb(s, srcw, srch, iu + 1, iv + 0); + s2 = getargb(s, srcw, srch, iu + 0, iv + 1); + s3 = getargb(s, srcw, srch, iu + 1, iv + 1); + + /* move to mmx registers */ + ms0s1 = _mm_set_pi32(s0, s1); + ms2s3 = _mm_set_pi32(s2, s3); + } + else + { + __m64 *m0s = (__m64*)(s + srcw * (iv + 0) + iu); + __m64 *m2s = (__m64*)(s + srcw * (iv + 1) + iu); + + /* faster vector loads for interior */ + ms0s1 = *m0s; + ms2s3 = *m2s; + } + + /* unpack src into 4x16bit vectors */ + __m64 ms0 = _mm_unpackhi_pi8(ms0s1, mzero); + __m64 ms1 = _mm_unpacklo_pi8(ms0s1, mzero); + __m64 ms2 = _mm_unpackhi_pi8(ms2s3, mzero); + __m64 ms3 = _mm_unpacklo_pi8(ms2s3, mzero); + + /* lerp fu */ + + __m64 mfu = _mm_set1_pi16(fu); + + /* t2 = (s1 - s0) * fu + s0 */ + __m64 t0 = _mm_sub_pi16(ms1, ms0); + __m64 t1 = _mm_mulhi_pi16(t0, mfu); + __m64 t2 = _mm_add_pi16(t1, ms0); + + /* t3 = (s3 - s2) * fu + s2 */ + __m64 t3 = _mm_sub_pi16(ms3, ms2); + __m64 t4 = _mm_mulhi_pi16(t3, mfu); + __m64 t5 = _mm_add_pi16(t4, ms2); + + /* lerp fv */ + + __m64 mfv = _mm_set1_pi16(fv); + + /* t8 = (t5 - t2) * fv + t2 */ + __m64 t6 = _mm_sub_pi16(t5, t2); + __m64 t7 = _mm_mulhi_pi16(t6, mfv); + __m64 t8 = _mm_add_pi16(t7, t2); + + /* load and prepare dst */ + __m64 d0 = _mm_cvtsi32_si64(*d); + + __m64 d1 = _mm_unpacklo_pi8(d0, mzero); + + /* get src alpha */ + + /* splat alpha */ + __m64 a0001 = _mm_and_si64(malphamask, t8); + __m64 a0011 = _mm_unpacklo_pi16(a0001, a0001); + __m64 a1111 = _mm_unpacklo_pi16(a0011, a0011); + + /* 255+1 - sa */ + __m64 sna = _mm_sub_pi16(m256, a1111); + + /* blend src with dst */ + __m64 d2 = _mm_mullo_pi16(d1, sna); + __m64 d3 = _mm_srli_pi16(d2, 8); + __m64 d4 = _mm_add_pi16(t8, d3); + + /* pack and store new dst */ + __m64 d5 = _mm_packs_pu16(d4, mzero); + + *d++ = _mm_cvtsi64_si32(d5); + + u += fa; + v += fb; + } + + dst0 += dstw; + u0 += fc; + v0 += fd; + } + + _mm_empty(); +} + +#endif /* HAVE_MMX */ + +#if defined (ARCH_X86) || defined(ARCH_X86_64) +void +fz_accelerate(void) +{ +# ifdef HAVE_MMX + if (fz_cpuflags & HAVE_MMX) + { + fz_duff_4i1o4 = duff_4i1o4mmx; + fz_img_4o4 = img_4o4mmx; + } +# endif +} +#endif + diff --git a/rosapps/smartpdf/fitz/raster/glyphcache.c b/rosapps/smartpdf/fitz/raster/glyphcache.c new file mode 100644 index 00000000000..6a71e9b4198 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/glyphcache.c @@ -0,0 +1,390 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef struct fz_hash_s fz_hash; +typedef struct fz_key_s fz_key; +typedef struct fz_val_s fz_val; + +struct fz_glyphcache_s +{ + int slots; + int size; + fz_hash *hash; + fz_val *lru; + unsigned char *buffer; + int load; + int used; +}; + +struct fz_key_s +{ + void *fid; + int a, b; + int c, d; + unsigned short cid; + unsigned char e, f; +}; + +struct fz_hash_s +{ + fz_key key; + fz_val *val; +}; + +struct fz_val_s +{ + fz_hash *ent; + unsigned char *samples; + short w, h, x, y; + int uses; +}; + +static unsigned int hashkey(fz_key *key) +{ + unsigned char *s = (unsigned char*)key; + unsigned int hash = 0; + unsigned int i; + for (i = 0; i < sizeof(fz_key); i++) + { + hash += s[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; +} + +fz_error * +fz_newglyphcache(fz_glyphcache **arenap, int slots, int size) +{ + fz_glyphcache *arena; + + arena = *arenap = fz_malloc(sizeof(fz_glyphcache)); + if (!arena) + return fz_outofmem; + + arena->slots = slots; + arena->size = size; + + arena->hash = nil; + arena->lru = nil; + arena->buffer = nil; + + arena->hash = fz_malloc(sizeof(fz_hash) * slots); + if (!arena->hash) + goto cleanup; + + arena->lru = fz_malloc(sizeof(fz_val) * slots); + if (!arena->lru) + goto cleanup; + + arena->buffer = fz_malloc(size); + if (!arena->buffer) + goto cleanup; + + memset(arena->hash, 0, sizeof(fz_hash) * slots); + memset(arena->lru, 0, sizeof(fz_val) * slots); + memset(arena->buffer, 0, size); + arena->load = 0; + arena->used = 0; + + return nil; + +cleanup: + fz_free(arena->hash); + fz_free(arena->lru); + fz_free(arena->buffer); + fz_free(arena); + return fz_outofmem; +} + +void +fz_dropglyphcache(fz_glyphcache *arena) +{ + fz_free(arena->hash); + fz_free(arena->lru); + fz_free(arena->buffer); + fz_free(arena); +} + +static int hokay = 0; +static int hcoll = 0; +static int hdist = 0; +static int coos = 0; +static int covf = 0; + +static int ghits = 0; +static int gmisses = 0; + +static fz_val * +hashfind(fz_glyphcache *arena, fz_key *key) +{ + fz_hash *tab = arena->hash; + int pos = hashkey(key) % arena->slots; + + while (1) + { + if (!tab[pos].val) + return nil; + + if (memcmp(key, &tab[pos].key, sizeof (fz_key)) == 0) + return tab[pos].val; + + pos = pos + 1; + if (pos == arena->slots) + pos = 0; + } +} + +static void +hashinsert(fz_glyphcache *arena, fz_key *key, fz_val *val) +{ + fz_hash *tab = arena->hash; + int pos = hashkey(key) % arena->slots; +int didcoll = 0; + + while (1) + { + if (!tab[pos].val) + { + tab[pos].key = *key; + tab[pos].val = val; + tab[pos].val->ent = &tab[pos]; +if (didcoll) hcoll ++; else hokay ++; hdist += didcoll; + return; + } + + pos = pos + 1; + if (pos == arena->slots) + pos = 0; +didcoll ++; + } +} + +static void +hashremove(fz_glyphcache *arena, fz_key *key) +{ + fz_hash *tab = arena->hash; + unsigned int pos = hashkey(key) % arena->slots; + unsigned int hole; + unsigned int look; + unsigned int code; + + while (1) + { + if (!tab[pos].val) + return; /* boo hoo! tried to remove non-existant key */ + + if (memcmp(key, &tab[pos].key, sizeof (fz_key)) == 0) + { + tab[pos].val = nil; + + hole = pos; + look = hole + 1; + if (look == arena->slots) + look = 0; + + while (tab[look].val) + { + code = (hashkey(&tab[look].key) % arena->slots); + if ((code <= hole && hole < look) || + (look < code && code <= hole) || + (hole < look && look < code)) + { + tab[hole] = tab[look]; + tab[hole].val->ent = &tab[hole]; + tab[look].val = nil; + hole = look; + } + + look = look + 1; + if (look == arena->slots) + look = 0; + } + + return; + } + + pos = pos + 1; + if (pos == arena->slots) + pos = 0; + } +} + +void +fz_debugglyphcache(fz_glyphcache *arena) +{ + printf("cache load %d / %d (%d / %d bytes)\n", + arena->load, arena->slots, arena->used, arena->size); + printf("no-colliders: %d colliders: %d\n", hokay, hcoll); + printf("avg dist: %d / %d: %g\n", hdist, hcoll, (double)hdist / hcoll); + printf("out-of-space evicts: %d\n", coos); + printf("out-of-hash evicts: %d\n", covf); + printf("hits = %d misses = %d ratio = %g\n", ghits, gmisses, (float)ghits / (ghits + gmisses)); +/* + int i; + for (i = 0; i < arena->slots; i++) + { + if (!arena->hash[i].val) + printf("glyph % 4d: empty\n", i); + else { + fz_key *k = &arena->hash[i].key; + fz_val *b = arena->hash[i].val; + printf("glyph % 4d: %p %d [%g %g %g %g + %d %d] " + "-> [%dx%d %d,%d]\n", i, + k->fid, k->cid, + k->a / 65536.0, + k->b / 65536.0, + k->c / 65536.0, + k->d / 65536.0, + k->e, k->f, + b->w, b->h, b->x, b->y); + } + } + + for (i = 0; i < arena->load; i++) + printf("lru %04d: glyph %d (%d)\n", i, + arena->lru[i].ent - arena->hash, arena->lru[i].uses); +*/ +} + +static void +bubble(fz_glyphcache *arena, int i) +{ + fz_val tmp; + + if (i == 0 || arena->load < 2) + return; + + tmp = arena->lru[i - 1]; + arena->lru[i - 1] = arena->lru[i]; + arena->lru[i] = tmp; + + arena->lru[i - 1].ent->val = &arena->lru[i - 1]; + arena->lru[i].ent->val = &arena->lru[i]; +} + +static void +evictlast(fz_glyphcache *arena) +{ + fz_val *lru = arena->lru; + unsigned char *s, *e; + int i, k; + fz_key key; + + if (arena->load == 0) + return; + + k = arena->load - 1; + s = lru[k].samples; + e = s + lru[k].w * lru[k].h; + + /* pack buffer to fill hole */ + memmove(s, e, arena->buffer + arena->used - e); + memset(arena->buffer + arena->used - (e - s), 0, e - s); + arena->used -= e - s; + + /* update lru pointers */ + for (i = 0; i < k; i++) /* XXX this is DOG slow! XXX */ + if (lru[i].samples >= e) + lru[i].samples -= e - s; + + /* remove hash entry */ + key = lru[k].ent->key; + hashremove(arena, &key); + + arena->load --; +} + +static void +evictall(fz_glyphcache *arena) +{ + //printf("zap!\n"); + memset(arena->hash, 0, sizeof(fz_hash) * arena->slots); + memset(arena->lru, 0, sizeof(fz_val) * arena->slots); + memset(arena->buffer, 0, arena->size); + arena->load = 0; + arena->used = 0; +} + +fz_error * +fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz_matrix ctm) +{ + fz_error *error; + fz_key key; + fz_val *val; + int size; + + key.fid = font; + key.cid = cid; + key.a = ctm.a * 65536; + key.b = ctm.b * 65536; + key.c = ctm.c * 65536; + key.d = ctm.d * 65536; + key.e = (ctm.e - fz_floor(ctm.e)) * 256; + key.f = (ctm.f - fz_floor(ctm.f)) * 256; + + val = hashfind(arena, &key); + if (val) + { + val->uses ++; + glyph->w = val->w; + glyph->h = val->h; + glyph->x = val->x; + glyph->y = val->y; + glyph->samples = val->samples; + + bubble(arena, val - arena->lru); + + ghits++; + + return nil; + } + + gmisses++; + + ctm.e = fz_floor(ctm.e) + key.e / 256.0; + ctm.f = fz_floor(ctm.f) + key.f / 256.0; + + error = font->render(glyph, font, cid, ctm); + if (error) + return error; + + size = glyph->w * glyph->h; + + if (size > arena->size / 6) + return nil; + + while (arena->load > arena->slots * 75 / 100) + { + covf ++; + evictall(arena); + } + + while (arena->used + size >= arena->size) + { + coos ++; + evictall(arena); + } + + val = &arena->lru[arena->load++]; + val->uses = 0; + val->w = glyph->w; + val->h = glyph->h; + val->x = glyph->x; + val->y = glyph->y; + val->samples = arena->buffer + arena->used; + + arena->used += size; + + memcpy(val->samples, glyph->samples, glyph->w * glyph->h); + glyph->samples = val->samples; + + hashinsert(arena, &key, val); + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/raster/imagedraw.c b/rosapps/smartpdf/fitz/raster/imagedraw.c new file mode 100644 index 00000000000..fe721466184 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/imagedraw.c @@ -0,0 +1,240 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef unsigned char byte; + +#define lerp(a,b,t) (a + (((b - a) * t) >> 16)) + +static inline byte getcomp(byte *s, int w, int h, int u, int v, int n, int k) +{ + if (u < 0 || u >= w) return 0; + if (v < 0 || v >= h) return 0; + return s[(w * v + u) * n + k]; +} + +static inline int samplecomp(byte *s, int w, int h, int u, int v, int n, int k) +{ + int ui = u >> 16; + int vi = v >> 16; + int ud = u & 0xFFFF; + int vd = v & 0xFFFF; + int a = getcomp(s, w, h, ui, vi, n, k); + int b = getcomp(s, w, h, ui+1, vi, n, k); + int c = getcomp(s, w, h, ui, vi+1, n, k); + int d = getcomp(s, w, h, ui+1, vi+1, n, k); + int ab = lerp(a, b, ud); + int cd = lerp(c, d, ud); + return lerp(ab, cd, vd); +} + +static inline byte getmask(byte *s, int w, int h, int u, int v) +{ + if (u < 0 || u >= w) return 0; + if (v < 0 || v >= h) return 0; + return s[w * v + u]; +} + +static inline int samplemask(byte *s, int w, int h, int u, int v) +{ + int ui = u >> 16; + int vi = v >> 16; + int ud = u & 0xFFFF; + int vd = v & 0xFFFF; + int a = getmask(s, w, h, ui, vi); + int b = getmask(s, w, h, ui+1, vi); + int c = getmask(s, w, h, ui, vi+1); + int d = getmask(s, w, h, ui+1, vi+1); + int ab = lerp(a, b, ud); + int cd = lerp(c, d, ud); + return lerp(ab, cd, vd); +} + +static FORCEINLINE void lerpargb(byte *dst, byte *a, byte *b, int t) +{ + dst[0] = lerp(a[0], b[0], t); + dst[1] = lerp(a[1], b[1], t); + dst[2] = lerp(a[2], b[2], t); + dst[3] = lerp(a[3], b[3], t); +} + +static FORCEINLINE byte *getargb(byte *s, int w, int h, int u, int v) +{ + static byte zero[4] = { 0, 0, 0, 0 }; + if (u < 0 || u >= w) return zero; + if (v < 0 || v >= h) return zero; + return s + ((w * v + u) << 2); +} + +static FORCEINLINE void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd) +{ + byte ab[4]; + byte cd[4]; + int ui = u >> 16; + int vi = v >> 16; + int ud = u & 0xFFFF; + int vd = v & 0xFFFF; + byte *a = getargb(s, w, h, ui, vi); + byte *b = getargb(s, w, h, ui+1, vi); + byte *c = getargb(s, w, h, ui, vi+1); + byte *d = getargb(s, w, h, ui+1, vi+1); + lerpargb(ab, a, b, ud); + lerpargb(cd, c, d, ud); + lerpargb(abcd, ab, cd, vd); +} + +static void img_ncn(FZ_PSRC, int srcn, FZ_PDST, FZ_PCTM) +{ + int k; + while (h--) + { + byte *dstp = dst0; + int u = u0; + int v = v0; + int w = w0; + while (w--) + { + for (k = 0; k < srcn; k++) + { + dstp[k] = samplecomp(src, srcw, srch, u, v, srcn, k); + dstp += srcn; + u += fa; + v += fb; + } + } + dst0 += dstw; + u0 += fc; + v0 += fd; + } +} + +static void img_1c1(FZ_PSRC, FZ_PDST, FZ_PCTM) +{ + while (h--) + { + byte *dstp = dst0; + int u = u0; + int v = v0; + int w = w0; + while (w--) + { + dstp[0] = samplemask(src, srcw, srch, u, v); + dstp ++; + u += fa; + v += fb; + } + dst0 += dstw; + u0 += fc; + v0 += fd; + } +} + +static void img_4c4(FZ_PSRC, FZ_PDST, FZ_PCTM) +{ + while (h--) + { + byte *dstp = dst0; + int u = u0; + int v = v0; + int w = w0; + while (w--) + { + sampleargb(src, srcw, srch, u, v, dstp); + dstp += 4; + u += fa; + v += fb; + } + dst0 += dstw; + u0 += fc; + v0 += fd; + } +} + +static void img_1o1(FZ_PSRC, FZ_PDST, FZ_PCTM) +{ + byte srca; + while (h--) + { + byte *dstp = dst0; + int u = u0; + int v = v0; + int w = w0; + while (w--) + { + srca = samplemask(src, srcw, srch, u, v); + dstp[0] = srca + fz_mul255(dstp[0], 255 - srca); + dstp ++; + u += fa; + v += fb; + } + dst0 += dstw; + u0 += fc; + v0 += fd; + } +} + +static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM) +{ + byte argb[4]; + byte ssa; + while (h--) + { + byte *dstp = dst0; + int u = u0; + int v = v0; + int w = w0; + while (w--) + { + sampleargb(src, srcw, srch, u, v, argb); + ssa = 255 - argb[0]; + dstp[0] = argb[0] + fz_mul255(dstp[0], ssa); + dstp[1] = argb[1] + fz_mul255(dstp[1], ssa); + dstp[2] = argb[2] + fz_mul255(dstp[2], ssa); + dstp[3] = argb[3] + fz_mul255(dstp[3], ssa); + dstp += 4; + u += fa; + v += fb; + } + dst0 += dstw; + u0 += fc; + v0 += fd; + } +} + +static void img_w3i1o4(byte *rgb, FZ_PSRC, FZ_PDST, FZ_PCTM) +{ + byte rgb0 = rgb[0]; + byte rgb1 = rgb[1]; + byte rgb2 = rgb[2]; + byte sa, ssa; + while (h--) + { + byte *dstp = dst0; + int u = u0; + int v = v0; + int w = w0; + while (w--) + { + sa = samplemask(src, srcw, srch, u, v); + ssa = 255 - sa; + dstp[0] = sa + fz_mul255(dstp[0], ssa); + dstp[1] = rgb0 + fz_mul255((short)dstp[1] - rgb0, ssa); + dstp[2] = rgb1 + fz_mul255((short)dstp[2] - rgb1, ssa); + dstp[3] = rgb2 + fz_mul255((short)dstp[3] - rgb2, ssa); + dstp += 4; + u += fa; + v += fb; + } + dst0 += dstw; + u0 += fc; + v0 += fd; + } +} + +void (*fz_img_ncn)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM) = img_ncn; +void (*fz_img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_1c1; +void (*fz_img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_4c4; +void (*fz_img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_1o1; +void (*fz_img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_4o4; +void (*fz_img_w3i1o4)(byte*,FZ_PSRC,FZ_PDST,FZ_PCTM) = img_w3i1o4; + diff --git a/rosapps/smartpdf/fitz/raster/imagescale.c b/rosapps/smartpdf/fitz/raster/imagescale.c new file mode 100644 index 00000000000..9118a3ebca3 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/imagescale.c @@ -0,0 +1,370 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef unsigned char byte; + +static FORCEINLINE void srown(byte * restrict src, byte * restrict dst, unsigned w, unsigned denom, unsigned n) +{ + unsigned x, left, k; + unsigned sum[FZ_MAXCOLORS]; + + left = 0; + for (k = 0; k < n; k++) + sum[k] = 0; + + for (x = 0; x < w; x++) + { + for (k = 0; k < n; k++) + sum[k] += src[x * n + k]; + if (++left == denom) + { + left = 0; + for (k = 0; k < n; k++) + { + dst[k] = sum[k] / denom; + sum[k] = 0; + } + dst += n; + } + } + + /* left overs */ + if (left) + for (k = 0; k < n; k++) + dst[k] = sum[k] / left; +} + +static inline void srownp2(byte * restrict src, byte * restrict dst, unsigned w, unsigned log2denom, unsigned n) +{ + unsigned x, left, k; + unsigned sum[FZ_MAXCOLORS]; + + left = 0; + for (k = 0; k < n; k++) + sum[k] = 0; + + for (x = 0; x < w; x++) + { + for (k = 0; k < n; k++) + sum[k] += src[x * n + k]; + if (++left == (1<> log2denom; + sum[k] = 0; + } + dst += n; + } + } + + /* left overs */ + if (left) + for (k = 0; k < n; k++) + dst[k] = sum[k] / left; +} + +static FORCEINLINE void srow1d9(byte * restrict src, byte * restrict dst, unsigned w) +{ + int left, runs; + unsigned sum; + + left = w % 9; + runs = w / 9; + while (runs-- > 0) + { + sum = *src++; + sum += *src++; + sum += *src++; + sum += *src++; + sum += *src++; + sum += *src++; + sum += *src++; + sum += *src++; + sum += *src++; + *dst++ = sum / 9; + } + + /* left overs */ + if (left) + { + runs = left; + sum = *src++; + while (--runs > 0) + sum += *src++; + *dst = sum / left; + } +} + +static void srow1(byte *src, byte *dst, int w, int denom) +{ + if (9 == denom) + srow1d9(src, dst, w); + else + srown(src, dst, w, denom, 1); +} + +static FORCEINLINE void srow2d3(byte *src, byte *dst, int w) +{ + int left; + int runs; + unsigned sum0, sum1; + + left = w % 3; + runs = w / 3; + + while (runs-- > 0) + { + sum0 = *src++; + sum1 = *src++; + sum0 += *src++; + sum1 += *src++; + sum0 += *src++; + sum1 += *src++; + *dst++ = sum0 / 3; + *dst++ = sum1 / 3; + } + + /* left overs */ + if (left) + { + sum0 = *src++; + sum1 = *src++; + if (2 == left) + { + sum0 += *src++; + sum1 += *src++; + } + *dst++ = sum0 / left; + *dst = sum1 / left; + } +} + +static void srow2(byte *src, byte *dst, int w, int denom) +{ + if (3 == denom) + srow2d3(src, dst, w); + else + srown(src, dst, w, denom, 2); +} + +static void srow4(byte *src, byte *dst, int w, int denom) +{ + srown(src, dst, w, denom, 4); +} + +static void srow5(byte *src, byte *dst, int w, int denom) +{ + srown(src, dst, w, denom, 5); +} + +static void srow5p2(byte * restrict src, byte * restrict dst, int w, int log2denom) +{ + srownp2(src, dst, w, log2denom, 5); +} + +static FORCEINLINE void scoln(byte * restrict src, byte * restrict dst, int w, int denom, int n) +{ + int x, y, k; + byte *s; + int sum[FZ_MAXCOLORS]; + + for (x = 0; x < w; x++) + { + s = src + (x * n); + for (k = 0; k < n; k++) + sum[k] = 0; + for (y = 0; y < denom; y++) + for (k = 0; k < n; k++) + sum[k] += s[y * w * n + k]; + for (k = 0; k < n; k++) + dst[k] = sum[k] / denom; + dst += n; + } +} + +static inline void scolnp2(byte *src, byte *dst, int w, int log2denom, int n) +{ + int x, y, k; + byte *s; + int sum[FZ_MAXCOLORS]; + + for (x = 0; x < w; x++) + { + s = src + (x * n); + for (k = 0; k < n; k++) + sum[k] = 0; + for (y = 0; y < (1<> log2denom; + dst += n; + } +} + +static void scol1(byte *src, byte *dst, int w, int denom) +{ + scoln(src, dst, w, denom, 1); +} + +static FORCEINLINE void scol2d3(byte *src, byte *dst, int w) +{ + byte *srcend; + int sum0, sum1; + int w2 = w * 2; + + srcend = src + w2; + while (src < srcend) + { + sum0 = src[0]; + sum1 = src[1]; + sum0 += src[w2]; + sum1 += src[w2 + 1]; + sum0 += src[2 * w2]; + sum1 += src[2 * w2 + 1]; + + *dst++ = sum0 / 3; + *dst++ = sum1 / 3; + src += 2; + } +} + +static void scol2(byte *src, byte *dst, int w, int denom) +{ + if (3 == denom) + scol2d3(src, dst, w); + else + scoln(src, dst, w, denom, 2); +} + +static void scol4(byte *src, byte *dst, int w, int denom) +{ + scoln(src, dst, w, denom, 4); +} + +static void scol5(byte *src, byte *dst, int w, int denom) +{ + scoln(src, dst, w, denom, 5); +} + +static void scol5p2(byte *src, byte *dst, int w, int denom) +{ + scolnp2(src, dst, w, denom, 5); +} + +void (*fz_srown)(byte *src, byte *dst, int w, int denom, int n) = srown; +void (*fz_srow1)(byte *src, byte *dst, int w, int denom) = srow1; +void (*fz_srow2)(byte *src, byte *dst, int w, int denom) = srow2; +void (*fz_srow4)(byte *src, byte *dst, int w, int denom) = srow4; +void (*fz_srow5)(byte *src, byte *dst, int w, int denom) = srow5; + +void (*fz_scoln)(byte *src, byte *dst, int w, int denom, int n) = scoln; +void (*fz_scol1)(byte *src, byte *dst, int w, int denom) = scol1; +void (*fz_scol2)(byte *src, byte *dst, int w, int denom) = scol2; +void (*fz_scol4)(byte *src, byte *dst, int w, int denom) = scol4; +void (*fz_scol5)(byte *src, byte *dst, int w, int denom) = scol5; + +fz_error * +fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom) +{ + fz_error *error; + fz_pixmap *dst; + unsigned char *buf; + int y, iy, oy; + int ow, oh, n; + int ydenom2 = ydenom; + + void (*srowx)(byte *src, byte *dst, int w, int denom) = nil; + void (*scolx)(byte *src, byte *dst, int w, int denom) = nil; + + ow = (src->w + xdenom - 1) / xdenom; + oh = (src->h + ydenom - 1) / ydenom; + n = src->n; + + buf = fz_malloc(ow * n * ydenom); + if (!buf) + return fz_outofmem; + + error = fz_newpixmap(&dst, 0, 0, ow, oh, src->n); + if (error) + { + fz_free(buf); + return error; + } + + switch (n) + { + case 1: srowx = fz_srow1; scolx = fz_scol1; break; + case 2: srowx = fz_srow2; scolx = fz_scol2; break; + case 4: srowx = fz_srow4; scolx = fz_scol4; break; + case 5: srowx = fz_srow5; scolx = fz_scol5; + if (!(xdenom & (xdenom - 1))) + { + unsigned v = xdenom; + xdenom = 0; + while ((v >>= 1)) xdenom++; + srowx = srow5p2; + } + if (!(ydenom & (ydenom - 1))) + { + unsigned v = ydenom2; + ydenom2 = 0; + while ((v >>= 1)) ydenom2++; + scolx = scol5p2; + } + + break; + } + + if (srowx && scolx) + { + for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++) + { + for (iy = 0; iy < ydenom; iy++) + srowx(src->samples + (y + iy) * src->w * n, + buf + iy * ow * n, + src->w, xdenom); + scolx(buf, dst->samples + oy * dst->w * n, dst->w, ydenom2); + } + + ydenom = src->h - y; + if (ydenom) + { + for (iy = 0; iy < ydenom; iy++) + srowx(src->samples + (y + iy) * src->w * n, + buf + iy * ow * n, + src->w, xdenom); + scolx(buf, dst->samples + oy * dst->w * n, dst->w, ydenom2); + } + } + + else + { + for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++) + { + for (iy = 0; iy < ydenom; iy++) + fz_srown(src->samples + (y + iy) * src->w * n, + buf + iy * ow * n, + src->w, xdenom, n); + fz_scoln(buf, dst->samples + oy * dst->w * n, dst->w, ydenom2, n); + } + + ydenom = src->h - y; + if (ydenom) + { + for (iy = 0; iy < ydenom; iy++) + fz_srown(src->samples + (y + iy) * src->w * n, + buf + iy * ow * n, + src->w, xdenom, n); + fz_scoln(buf, dst->samples + oy * dst->w * n, dst->w, ydenom2, n); + } + } + + fz_free(buf); + *dstp = dst; + return nil; +} + diff --git a/rosapps/smartpdf/fitz/raster/imageunpack.c b/rosapps/smartpdf/fitz/raster/imageunpack.c new file mode 100644 index 00000000000..8e13f82e8b2 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/imageunpack.c @@ -0,0 +1,251 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef unsigned char byte; + +/* + * Apply decode parameters + */ + +static void decodetile(fz_pixmap *pix, int skip, float *decode) +{ + int min[FZ_MAXCOLORS]; + int max[FZ_MAXCOLORS]; + int sub[FZ_MAXCOLORS]; + int needed = 0; + byte *p = pix->samples; + int n = pix->n; + int wh = pix->w * pix->h; + int i; + + min[0] = 0; + max[0] = 255; + sub[0] = 255; + + for (i = skip; i < n; i++) + { + min[i] = decode[(i - skip) * 2] * 255; + max[i] = decode[(i - skip) * 2 + 1] * 255; + sub[i] = max[i] - min[i]; + needed |= (min[i] != 0) | (max[i] != 255); + } + + if (!needed) + return; + + while (wh--) + { + for (i = 0; i < n; i++) + p[i] = min[i] + fz_mul255(sub[i], p[i]); + p += n; + } +} + +/* + * Unpack image samples and optionally pad pixels with opaque alpha + */ + +#define tbit(buf,x) ((buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 ) * 255 +#define ttwo(buf,x) ((buf[x >> 2] >> ( ( 3 - (x & 3) ) << 1 ) ) & 3 ) * 85 +#define tnib(buf,x) ((buf[x >> 1] >> ( ( 1 - (x & 1) ) << 2 ) ) & 15 ) * 17 +#define toct(buf,x) (buf[x]) + +static byte t1pad0[256][8]; +static byte t1pad1[256][16]; + +static void init1() +{ + static int inited = 0; + byte bits[1]; + int i, k, x; + + if (inited) + return; + + for (i = 0; i < 256; i++) + { + bits[0] = i; + for (k = 0; k < 8; k++) + { + x = tbit(bits, k); + t1pad0[i][k] = x; + t1pad1[i][k * 2 + 0] = 255; + t1pad1[i][k * 2 + 1] = x; + } + } + + inited = 1; +} + +static void loadtile1(byte *src, int sw, byte *dst, int dw, int w, int h, int pad) +{ + byte *sp; + byte *dp; + int x; + + init1(); + + if (pad == 0) + { + int w3 = w >> 3; + while (h--) + { + sp = src; + dp = dst; + for (x = 0; x < w3; x++) + { + memcpy(dp, t1pad0[*sp++], 8); + dp += 8; + } + x = x << 3; + if (x < w) + memcpy(dp, t1pad0[*sp], w - x); + src += sw; + dst += dw; + } + } + + else if (pad == 1) + { + int w3 = w >> 3; + while (h--) + { + sp = src; + dp = dst; + for (x = 0; x < w3; x++) + { + memcpy(dp, t1pad1[*sp++], 16); + dp += 16; + } + x = x << 3; + if (x < w) + memcpy(dp, t1pad1[*sp], (w - x) << 1); + src += sw; + dst += dw; + } + } + + else + { + while (h--) + { + dp = dst; + for (x = 0; x < w; x++) + { + if ((x % pad) == 0) + *dp++ = 255; + *dp++ = tbit(src, x); + } + src += sw; + dst += dw; + } + } +} + +#define TILE(getf) \ +{ \ + int x; \ + if (!pad) \ + while (h--) \ + { \ + for (x = 0; x < w; x++) \ + dst[x] = getf(src, x); \ + src += sw; \ + dst += dw; \ + } \ + else \ + while (h--) \ + { \ + byte *dp = dst; \ + for (x = 0; x < w; x++) \ + { \ + if ((x % pad) == 0) \ + *dp++ = 255; \ + *dp++ = getf(src, x); \ + } \ + src += sw; \ + dst += dw; \ + } \ +} + +static inline void loadtile8_fast_pad3(byte * restrict src, byte * restrict dst, int w, int h) +{ + int tocopy = (h * w) / 3; + while (tocopy--) + { + *dst++ = 255; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + } + /* TODO: if there was a reminder, copy it */ +} + +static void loadtile8_fast(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad) +{ + int x; + + if (!pad) + { + if (sw == dw) + { + memmove(dst, src, h * w); + } + else + { + while (h--) + { + memmove(dst, src, w); + src += sw; + dst += dw; + } + } + } + else + { + int swdelta = sw - w; + int dwdelta = dw - w - (w / pad); + if ( (0 == swdelta) && (0 == dwdelta) ) + { + if (3 == pad) + loadtile8_fast_pad3(src, dst, w, h); + else + while (h--) + { + for (x = 0; x < w; x++) + { + if ((x % pad) == 0) + *dst++ = 255; + *dst++ = *src++; + } + } + } + else + while (h--) + { + for (x = 0; x < w; x++) + { + if ((x % pad) == 0) + *dst++ = 255; + *dst++ = *src++; + } + src += swdelta; + dst += dwdelta; + } + } +} +static void loadtile2(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad) + TILE(ttwo) +static void loadtile4(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad) + TILE(tnib) +static void loadtile8_orig(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad) + TILE(toct) + +#define loadtile8 loadtile8_fast + +void (*fz_decodetile)(fz_pixmap *pix, int skip, float *decode) = decodetile; +void (*fz_loadtile1)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile1; +void (*fz_loadtile2)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile2; +void (*fz_loadtile4)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile4; +void (*fz_loadtile8)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile8; diff --git a/rosapps/smartpdf/fitz/raster/meshdraw.c b/rosapps/smartpdf/fitz/raster/meshdraw.c new file mode 100644 index 00000000000..c0d798e6de7 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/meshdraw.c @@ -0,0 +1,404 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +/* + * polygon clipping + */ + +enum { IN, OUT, ENTER, LEAVE }; +enum { MAXV = 3 + 4 }; +enum { MAXN = 2 + FZ_MAXCOLORS }; + +static int clipx(float val, int ismax, float *v1, float *v2, int n) +{ + float t; + int i; + int v1o = ismax ? v1[0] > val : v1[0] < val; + int v2o = ismax ? v2[0] > val : v2[0] < val; + if (v1o + v2o == 0) + return IN; + if (v1o + v2o == 2) + return OUT; + if (v2o) + { + t = (val - v1[0]) / (v2[0] - v1[0]); + v2[0] = val; + v2[1] = v1[1] + t * (v2[1] - v1[1]); + for (i = 2; i < n; i++) + v2[i] = v1[i] + t * (v2[i] - v1[i]); + return LEAVE; + } + else + { + t = (val - v2[0]) / (v1[0] - v2[0]); + v1[0] = val; + v1[1] = v2[1] + t * (v1[1] - v2[1]); + for (i = 2; i < n; i++) + v1[i] = v2[i] + t * (v1[i] - v2[i]); + return ENTER; + } +} + +static int clipy(float val, int ismax, float *v1, float *v2, int n) +{ + float t; + int i; + int v1o = ismax ? v1[1] > val : v1[1] < val; + int v2o = ismax ? v2[1] > val : v2[1] < val; + if (v1o + v2o == 0) + return IN; + if (v1o + v2o == 2) + return OUT; + if (v2o) + { + t = (val - v1[1]) / (v2[1] - v1[1]); + v2[0] = v1[0] + t * (v2[0] - v1[0]); + v2[1] = val; + for (i = 2; i < n; i++) + v2[i] = v1[i] + t * (v2[i] - v1[i]); + return LEAVE; + } + else + { + t = (val - v2[1]) / (v1[1] - v2[1]); + v1[0] = v2[0] + t * (v1[0] - v2[0]); + v1[1] = val; + for (i = 2; i < n; i++) + v1[i] = v2[i] + t * (v1[i] - v2[i]); + return ENTER; + } +} + +static inline void copyvert(float *dst, float *src, int n) +{ + while (n--) + *dst++ = *src++; +} + +static int clippoly(float src[MAXV][MAXN], + float dst[MAXV][MAXN], int len, int n, + float val, int isy, int ismax) +{ + float cv1[MAXN]; + float cv2[MAXN]; + int v1, v2, cp; + int r; + + v1 = len - 1; + cp = 0; + + for (v2 = 0; v2 < len; v2++) + { + copyvert(cv1, src[v1], n); + copyvert(cv2, src[v2], n); + + if (isy) + r = clipy(val, ismax, cv1, cv2, n); + else + r = clipx(val, ismax, cv1, cv2, n); + + switch (r) + { + case IN: + copyvert(dst[cp++], cv2, n); + break; + case OUT: + break; + case LEAVE: + copyvert(dst[cp++], cv2, n); + break; + case ENTER: + copyvert(dst[cp++], cv1, n); + copyvert(dst[cp++], cv2, n); + break; + } + v1 = v2; + } + + return cp; +} + +/* + * gouraud shaded polygon scan conversion + */ + +static inline void +drawscan(fz_pixmap *pix, int y, int x1, int x2, int *v1, int *v2, int n) +{ + unsigned char *p = pix->samples + ((y - pix->y) * pix->w + (x1 - pix->x)) * pix->n; + int v[FZ_MAXCOLORS]; + int dv[FZ_MAXCOLORS]; + int w = x2 - x1; + int k; + + assert(w >= 0); + assert(y >= pix->y); + assert(y < pix->y + pix->h); + assert(x1 >= pix->x); + assert(x2 <= pix->x + pix->w); + + if (w == 0) + return; + + for (k = 0; k < n; k++) + { + v[k] = v1[k]; + dv[k] = (v2[k] - v1[k]) / w; + } + + while (w--) + { + *p++ = 255; + for (k = 0; k < n; k++) + { + *p++ = v[k] >> 16; + v[k] += dv[k]; + } + } +} + +static inline int +findnext(int gel[MAXV][MAXN], int len, int a, int *s, int *e, int d) +{ + int b; + + while (1) + { + b = a + d; + if (b == len) + b = 0; + if (b == -1) + b = len - 1; + + if (gel[b][1] == gel[a][1]) + { + a = b; + continue; + } + + if (gel[b][1] > gel[a][1]) + { + *s = a; + *e = b; + return 0; + } + + return 1; + } +} + +static inline void +loadedge(int gel[MAXV][MAXN], int s, int e, int *ael, int *del, int n) +{ + int swp, k, dy; + + if (gel[s][1] > gel[s][1]) + { + swp = s; s = e; e = swp; + } + + dy = gel[e][1] - gel[s][1]; + + ael[0] = gel[s][0]; + del[0] = (gel[e][0] - gel[s][0]) / dy; + for (k = 2; k < n; k++) + { + ael[k] = gel[s][k]; + del[k] = (gel[e][k] - gel[s][k]) / dy; + } +} + +static inline void +stepedge(int *ael, int *del, int n) +{ + int k; + ael[0] += del[0]; + for (k = 2; k < n; k++) + ael[k] += del[k]; +} + +void +fz_drawtriangle(fz_pixmap *pix, float *av, float *bv, float *cv, int n) +{ + float poly[MAXV][MAXN]; + float temp[MAXV][MAXN]; + float cx0 = pix->x; + float cy0 = pix->y; + float cx1 = pix->x + pix->w; + float cy1 = pix->y + pix->h; + + int gel[MAXV][MAXN]; + int ael[2][MAXN]; + int del[2][MAXN]; + int y, s0, s1, e0, e1; + int top, bot, len; + + int i, k; + + copyvert(poly[0], av, n); + copyvert(poly[1], bv, n); + copyvert(poly[2], cv, n); + + len = clippoly(poly, temp, 3, n, cx0, 0, 0); + len = clippoly(temp, poly, len, n, cx1, 0, 1); + len = clippoly(poly, temp, len, n, cy0, 1, 0); + len = clippoly(temp, poly, len, n, cy1, 1, 1); + + if (len < 3) + return; + + for (i = 0; i < len; i++) + { + gel[i][0] = fz_floor(poly[i][0] + 0.5) * 65536; /* trunc and fix */ + gel[i][1] = fz_floor(poly[i][1] + 0.5); /* y is not fixpoint */ + for (k = 2; k < n; k++) + gel[i][k] = poly[i][k] * 65536; /* fix with precision */ + } + + top = bot = 0; + for (i = 0; i < len; i++) + { + if (gel[i][1] < gel[top][1]) + top = i; + if (gel[i][1] > gel[bot][1]) + bot = i; + } + + if (gel[bot][1] - gel[top][1] == 0) + return; + + y = gel[top][1]; + + if (findnext(gel, len, top, &s0, &e0, 1)) + return; + if (findnext(gel, len, top, &s1, &e1, -1)) + return; + + loadedge(gel, s0, e0, ael[0], del[0], n); + loadedge(gel, s1, e1, ael[1], del[1], n); + + while (1) + { + int x0 = ael[0][0] >> 16; + int x1 = ael[1][0] >> 16; + + if (ael[0][0] < ael[1][0]) + drawscan(pix, y, x0, x1, ael[0]+2, ael[1]+2, n-2); + else + drawscan(pix, y, x1, x0, ael[1]+2, ael[0]+2, n-2); + + stepedge(ael[0], del[0], n); + stepedge(ael[1], del[1], n); + y ++; + + if (y >= gel[e0][1]) + { + if (findnext(gel, len, e0, &s0, &e0, 1)) + return; + loadedge(gel, s0, e0, ael[0], del[0], n); + } + + if (y >= gel[e1][1]) + { + if (findnext(gel, len, e1, &s1, &e1, -1)) + return; + loadedge(gel, s1, e1, ael[1], del[1], n); + } + } +} + +/* + * mesh drawing + */ + +fz_error * +fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *destcs, fz_pixmap *dest) +{ + unsigned char clut[256][3]; + unsigned char *s, *d; + fz_error *error; + fz_pixmap *temp; + float rgb[3]; + float tri[3][MAXN]; + fz_point p; + int i, j, k, n; + + assert(dest->n == 4); + + ctm = fz_concat(shade->matrix, ctm); + + if (shade->usefunction) + { + n = 3; + error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, 2); + if (error) + return error; + } + else if (shade->cs != destcs) + { + n = 2 + shade->cs->n; + error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, + shade->cs->n + 1); + if (error) + return error; + } + else + { + n = 2 + shade->cs->n; + temp = dest; + } + + fz_clearpixmap(temp); + + for (i = 0; i < shade->meshlen; i++) + { + for (k = 0; k < 3; k++) + { + p.x = shade->mesh[(i * 3 + k) * n + 0]; + p.y = shade->mesh[(i * 3 + k) * n + 1]; + p = fz_transformpoint(ctm, p); + tri[k][0] = p.x; + tri[k][1] = p.y; + for (j = 2; j < n; j++) + tri[k][j] = shade->mesh[( i * 3 + k) * n + j] * 255; + } + fz_drawtriangle(temp, tri[0], tri[1], tri[2], n); + } + + if (shade->usefunction) + { + for (i = 0; i < 256; i++) + { + fz_convertcolor(shade->cs, shade->function[i], destcs, rgb); + clut[i][0] = rgb[0] * 255; + clut[i][1] = rgb[1] * 255; + clut[i][2] = rgb[2] * 255; + } + + n = temp->w * temp->h; + s = temp->samples; + d = dest->samples; + + while (n--) + { + d[0] = s[0]; + d[1] = fz_mul255(s[0], clut[s[1]][0]); + d[2] = fz_mul255(s[0], clut[s[1]][1]); + d[3] = fz_mul255(s[0], clut[s[1]][2]); + s += 2; + d += 4; + } + + fz_droppixmap(temp); + } + + else if (shade->cs != destcs) + { + fz_convertpixmap(shade->cs, temp, destcs, dest); + fz_droppixmap(temp); + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/raster/pathfill.c b/rosapps/smartpdf/fitz/raster/pathfill.c new file mode 100644 index 00000000000..e361b9a50fd --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/pathfill.c @@ -0,0 +1,134 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +static fz_error * +line(fz_gel *gel, fz_matrix *ctm, float x0, float y0, float x1, float y1) +{ + float tx0 = ctm->a * x0 + ctm->c * y0 + ctm->e; + float ty0 = ctm->b * x0 + ctm->d * y0 + ctm->f; + float tx1 = ctm->a * x1 + ctm->c * y1 + ctm->e; + float ty1 = ctm->b * x1 + ctm->d * y1 + ctm->f; + return fz_insertgel(gel, tx0, ty0, tx1, ty1); +} + +static fz_error * +bezier(fz_gel *gel, fz_matrix *ctm, float flatness, + float xa, float ya, + float xb, float yb, + float xc, float yc, + float xd, float yd) +{ + fz_error *error; + float dmax; + float xab, yab; + float xbc, ybc; + float xcd, ycd; + float xabc, yabc; + float xbcd, ybcd; + float xabcd, yabcd; + + /* termination check */ + dmax = ABS(xa - xb); + dmax = MAX(dmax, ABS(ya - yb)); + dmax = MAX(dmax, ABS(xd - xc)); + dmax = MAX(dmax, ABS(yd - yc)); + if (dmax < flatness) + return line(gel, ctm, xa, ya, xd, yd); + + xab = xa + xb; + yab = ya + yb; + xbc = xb + xc; + ybc = yb + yc; + xcd = xc + xd; + ycd = yc + yd; + + xabc = xab + xbc; + yabc = yab + ybc; + xbcd = xbc + xcd; + ybcd = ybc + ycd; + + xabcd = xabc + xbcd; + yabcd = yabc + ybcd; + + xab *= 0.5f; yab *= 0.5f; + xbc *= 0.5f; ybc *= 0.5f; + xcd *= 0.5f; ycd *= 0.5f; + + xabc *= 0.25f; yabc *= 0.25f; + xbcd *= 0.25f; ybcd *= 0.25f; + + xabcd *= 0.125f; yabcd *= 0.125f; + + error = bezier(gel, ctm, flatness, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd); + if (error) + return error; + return bezier(gel, ctm, flatness, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd); +} + +fz_error * +fz_fillpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness) +{ + fz_error *error; + float x1, y1, x2, y2, x3, y3; + float cx = 0; + float cy = 0; + float bx = 0; + float by = 0; + int i = 0; + + while (i < path->len) + { + switch (path->els[i++].k) + { + case FZ_MOVETO: + x1 = path->els[i++].v; + y1 = path->els[i++].v; + cx = bx = x1; + cy = by = y1; + break; + + case FZ_LINETO: + x1 = path->els[i++].v; + y1 = path->els[i++].v; + error = line(gel, &ctm, cx, cy, x1, y1); + if (error) + return error; + cx = x1; + cy = y1; + break; + + case FZ_CURVETO: + x1 = path->els[i++].v; + y1 = path->els[i++].v; + x2 = path->els[i++].v; + y2 = path->els[i++].v; + x3 = path->els[i++].v; + y3 = path->els[i++].v; + error = bezier(gel, &ctm, flatness, cx, cy, x1, y1, x2, y2, x3, y3); + if (error) + return error; + cx = x3; + cy = y3; + break; + + case FZ_CLOSEPATH: + error = line(gel, &ctm, cx, cy, bx, by); + if (error) + return error; + cx = bx; + cy = by; + break; + } + } + + if (i && (cx != bx || cy != by)) + { + error = line(gel, &ctm, cx, cy, bx, by); + if (error) + return error; + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/raster/pathscan.c b/rosapps/smartpdf/fitz/raster/pathscan.c new file mode 100644 index 00000000000..9e04788f219 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/pathscan.c @@ -0,0 +1,486 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +/* + * Global Edge List -- list of straight path segments for scan conversion + * + * Stepping along the edges is with bresenham's line algorithm. + * + * See Mike Abrash -- Graphics Programming Black Book (notably chapter 40) + */ + +fz_error * +fz_newgel(fz_gel **gelp) +{ + fz_gel *gel; + + gel = *gelp = fz_malloc(sizeof(fz_gel)); + if (!gel) + return fz_outofmem; + + gel->edges = nil; + + gel->cap = 512; + gel->len = 0; + gel->edges = fz_malloc(sizeof(fz_edge) * gel->cap); + if (!gel->edges) { + fz_free(gel); + return fz_outofmem; + } + + gel->xmin = gel->ymin = INT_MAX; + gel->xmax = gel->ymax = INT_MIN; + gel->hs = 1; + gel->vs = 1; + + return nil; +} + +void +fz_resetgel(fz_gel *gel, int hs, int vs) +{ + gel->xmin = gel->ymin = INT_MAX; + gel->xmax = gel->ymax = INT_MIN; + gel->hs = hs; + gel->vs = vs; + gel->len = 0; +} + +void +fz_dropgel(fz_gel *gel) +{ + fz_free(gel->edges); + fz_free(gel); +} + +fz_irect +fz_boundgel(fz_gel *gel) +{ + fz_irect bbox; + bbox.x0 = fz_idiv(gel->xmin, gel->hs); + bbox.y0 = fz_idiv(gel->ymin, gel->vs); + bbox.x1 = fz_idiv(gel->xmax, gel->hs) + 1; + bbox.y1 = fz_idiv(gel->ymax, gel->vs) + 1; + return bbox; +} + +fz_error * +fz_insertgel(fz_gel *gel, float fx0, float fy0, float fx1, float fy1) +{ + fz_edge *edge; + int x0, y0, x1, y1; + int dx, dy; + int winding; + int width; + int tmp; + + fx0 *= gel->hs; + fy0 *= gel->vs; + fx1 *= gel->hs; + fy1 *= gel->vs; + + /* TODO: should we round or truncate? */ + x0 = fx0 < 0 ? fx0 - 0.5 : fx0 + 0.5; + y0 = fy0 < 0 ? fy0 - 0.5 : fy0 + 0.5; + x1 = fx1 < 0 ? fx1 - 0.5 : fx1 + 0.5; + y1 = fy1 < 0 ? fy1 - 0.5 : fy1 + 0.5; + + if (y0 == y1) + return nil; + + if (y0 > y1) { + winding = -1; + tmp = x0; x0 = x1; x1 = tmp; + tmp = y0; y0 = y1; y1 = tmp; + } + else + winding = 1; + + if (x0 < gel->xmin) gel->xmin = x0; + if (x0 > gel->xmax) gel->xmax = x0; + if (x1 < gel->xmin) gel->xmin = x1; + if (x1 > gel->xmax) gel->xmax = x1; + + if (y0 < gel->ymin) gel->ymin = y0; + if (y1 > gel->ymax) gel->ymax = y1; + + if (gel->len + 1 == gel->cap) { + int newcap = gel->cap + 512; + fz_edge *newedges = fz_realloc(gel->edges, sizeof(fz_edge) * newcap); + if (!newedges) + return fz_outofmem; + gel->cap = newcap; + gel->edges = newedges; + } + + edge = &gel->edges[gel->len++]; + + dy = y1 - y0; + dx = x1 - x0; + width = dx < 0 ? -dx : dx; + + edge->xdir = dx > 0 ? 1 : -1; + edge->ydir = winding; + edge->x = x0; + edge->y = y0; + edge->h = dy; + edge->adjdown = dy; + + /* initial error term going l->r and r->l */ + if (dx >= 0) + edge->e = 0; + else + edge->e = -dy + 1; + + /* y-major edge */ + if (dy >= width) { + edge->xmove = 0; + edge->adjup = width; + } + + /* x-major edge */ + else { + edge->xmove = (width / dy) * edge->xdir; + edge->adjup = width % dy; + } + + return nil; +} + +void +fz_sortgel(fz_gel *gel) +{ + fz_edge *a = gel->edges; + int n = gel->len; + + int h, i, k; + fz_edge t; + + h = 1; + if (n < 14) { + h = 1; + } + else { + while (h < n) + h = 3 * h + 1; + h /= 3; + h /= 3; + } + + while (h > 0) + { + for (i = 0; i < n; i++) { + t = a[i]; + k = i - h; + /* TODO: sort on y major, x minor */ + while (k >= 0 && a[k].y > t.y) { + a[k + h] = a[k]; + k -= h; + } + a[k + h] = t; + } + + h /= 3; + } +} + +/* + * Active Edge List -- keep track of active edges while sweeping + */ + +fz_error * +fz_newael(fz_ael **aelp) +{ + fz_ael *ael; + + ael = *aelp = fz_malloc(sizeof(fz_ael)); + if (!ael) + return fz_outofmem; + + ael->cap = 64; + ael->len = 0; + ael->edges = fz_malloc(sizeof(fz_edge*) * ael->cap); + if (!ael->edges) { + fz_free(ael); + return fz_outofmem; + } + + return nil; +} + +void +fz_dropael(fz_ael *ael) +{ + fz_free(ael->edges); + fz_free(ael); +} + +static inline void +sortael(fz_edge **a, int n) +{ + int h, i, k; + fz_edge *t; + + h = 1; + if (n < 14) { + h = 1; + } + else { + while (h < n) + h = 3 * h + 1; + h /= 3; + h /= 3; + } + + while (h > 0) + { + for (i = 0; i < n; i++) { + t = a[i]; + k = i - h; + while (k >= 0 && a[k]->x > t->x) { + a[k + h] = a[k]; + k -= h; + } + a[k + h] = t; + } + + h /= 3; + } +} + +static fz_error * +insertael(fz_ael *ael, fz_gel *gel, int y, int *e) +{ + /* insert edges that start here */ + int e2 = *e; + while (e2 < gel->len && gel->edges[e2].y == y) { + if (ael->len + 1 == ael->cap) { + int newcap = ael->cap + 256; + fz_edge **newedges = fz_realloc(ael->edges, sizeof(fz_edge*) * newcap); + if (!newedges) + return fz_outofmem; + ael->edges = newedges; + ael->cap = newcap; + } + ael->edges[ael->len++] = &gel->edges[e2++]; + } + *e = e2; + /* shell-sort the edges by increasing x */ + sortael(ael->edges, ael->len); + + return nil; +} + +static void +advanceael(fz_ael *ael) +{ + fz_edge *edge; + int i = 0; + + while (i < ael->len) + { + edge = ael->edges[i]; + + edge->h --; + + /* terminator! */ + if (edge->h == 0) { + ael->edges[i] = ael->edges[--ael->len]; + } + + else { + edge->x += edge->xmove; + edge->e += edge->adjup; + if (edge->e > 0) { + edge->x += edge->xdir; + edge->e -= edge->adjdown; + } + i ++; + } + } +} + +/* + * Scan convert + */ + +static inline void +addspan(unsigned char *list, int x0, int x1, int xofs, int hs) +{ + int x0pix, x0sub; + int x1pix, x1sub; + + if (x0 == x1) + return; + + /* x between 0 and width of bbox */ + x0 -= xofs; + x1 -= xofs; + + x0pix = x0 / hs; + x0sub = x0 % hs; + x1pix = x1 / hs; + x1sub = x1 % hs; + + if (x0pix == x1pix) + { + list[x0pix] += x1sub - x0sub; + list[x0pix+1] += x0sub - x1sub; + } + + else + { + list[x0pix] += hs - x0sub; + list[x0pix+1] += x0sub; + list[x1pix] += x1sub - hs; + list[x1pix+1] += -x1sub; + } +} + +static inline void +nonzerowinding(fz_ael *ael, unsigned char *list, int xofs, int hs) +{ + int winding = 0; + int x = 0; + int i; + for (i = 0; i < ael->len; i++) + { + if (!winding && (winding + ael->edges[i]->ydir)) + x = ael->edges[i]->x; + if (winding && !(winding + ael->edges[i]->ydir)) + addspan(list, x, ael->edges[i]->x, xofs, hs); + winding += ael->edges[i]->ydir; + } +} + +static inline void +evenodd(fz_ael *ael, unsigned char *list, int xofs, int hs) +{ + int even = 0; + int x = 0; + int i; + for (i = 0; i < ael->len; i++) + { + if (!even) + x = ael->edges[i]->x; + else + addspan(list, x, ael->edges[i]->x, xofs, hs); + even = !even; + } +} + +static inline void toalpha(unsigned char *list, int n) +{ + int d = 0; + while (n--) + { + d += *list; + *list++ = d; + } +} + +static inline void blit(fz_pixmap *pix, int x, int y, + unsigned char *list, int skipx, int len, + unsigned char *rgb, int over) +{ + unsigned char *dst; + int cov; + + dst = pix->samples + ( (y - pix->y) * pix->w + (x - pix->x) ) * pix->n; + cov = 0; + + while (skipx--) + { + cov += *list; + *list = 0; + ++list; + } + + if (rgb) + fz_path_w3i1o4(rgb, list, cov, len, dst); + else if (over) + fz_path_1o1(list, cov, len, dst); + else + fz_path_1c1(list, cov, len, dst); +} + +fz_error * +fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, fz_irect clip, + fz_pixmap *pix, unsigned char *rgb, int over) +{ + fz_error *error; + unsigned char *deltas; + int y, e; + int yd, yc; + + int xmin = fz_idiv(gel->xmin, gel->hs); + int xmax = fz_idiv(gel->xmax, gel->hs) + 1; + + int xofs = xmin * gel->hs; + int hs = gel->hs; + int vs = gel->vs; + + int skipx = clip.x0 - xmin; + int clipn = clip.x1 - clip.x0; + + assert(clip.x0 >= xmin); + assert(clip.x1 <= xmax); + + if (gel->len == 0) + return nil; + + deltas = fz_malloc(xmax - xmin + 1); + if (!deltas) + return fz_outofmem; + + memset(deltas, 0, xmax - xmin + 1); + + e = 0; + y = gel->edges[0].y; + yc = fz_idiv(y, vs); + yd = yc; + + while (ael->len > 0 || e < gel->len) + { + yc = fz_idiv(y, vs); + if (yc != yd) + { + if (yd >= clip.y0 && yd < clip.y1) + { + blit(pix, xmin + skipx, yd, deltas, skipx, clipn, rgb, over); + } + } + yd = yc; + + error = insertael(ael, gel, y, &e); + if (error) { + fz_free(deltas); + return error; + } + + if (yd >= clip.y0 && yd < clip.y1) + { + if (eofill) + evenodd(ael, deltas, xofs, hs); + else + nonzerowinding(ael, deltas, xofs, hs); + } + + advanceael(ael); + + if (ael->len > 0) + y ++; + else if (e < gel->len) + y = gel->edges[e].y; + } + + if (yd >= clip.y0 && yd < clip.y1) + { + blit(pix, xmin + skipx, yd, deltas, skipx, clipn, rgb, over); + } + + fz_free(deltas); + return nil; +} + diff --git a/rosapps/smartpdf/fitz/raster/pathstroke.c b/rosapps/smartpdf/fitz/raster/pathstroke.c new file mode 100644 index 00000000000..b7b76f9f06d --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/pathstroke.c @@ -0,0 +1,727 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +enum { BUTT = 0, ROUND = 1, SQUARE = 2, MITER = 0, BEVEL = 2 }; + +struct sctx +{ + fz_gel *gel; + fz_matrix *ctm; + float flatness; + + int linecap; + int linejoin; + float linewidth; + float miterlimit; + fz_point beg[2]; + fz_point seg[2]; + int sn, bn; + int dot; + + fz_dash *dash; + int toggle; + int offset; + float phase; + fz_point cur; +}; + +static fz_error * +line(struct sctx *s, float x0, float y0, float x1, float y1) +{ + float tx0 = s->ctm->a * x0 + s->ctm->c * y0 + s->ctm->e; + float ty0 = s->ctm->b * x0 + s->ctm->d * y0 + s->ctm->f; + float tx1 = s->ctm->a * x1 + s->ctm->c * y1 + s->ctm->e; + float ty1 = s->ctm->b * x1 + s->ctm->d * y1 + s->ctm->f; + return fz_insertgel(s->gel, tx0, ty0, tx1, ty1); +} + +static fz_error * +arc(struct sctx *s, + float xc, float yc, + float x0, float y0, + float x1, float y1) +{ + fz_error *error; + float th0, th1, r; + float theta; + float ox, oy, nx, ny; + int n, i; + + r = fabs(s->linewidth); + theta = 2 * M_SQRT2 * sqrt(s->flatness / r); + th0 = atan2(y0, x0); + th1 = atan2(y1, x1); + + if (r > 0) + { + if (th0 < th1) + th0 += M_PI * 2; + n = ceil((th0 - th1) / theta); + } + else + { + if (th1 < th0) + th1 += M_PI * 2; + n = ceil((th1 - th0) / theta); + } + + ox = x0; + oy = y0; + for (i = 1; i < n; i++) + { + theta = th0 + (th1 - th0) * i / n; + nx = cos(theta) * r; + ny = sin(theta) * r; + error = line(s, xc + ox, yc + oy, xc + nx, yc + ny); + if (error) return error; + ox = nx; + oy = ny; + } + + error = line(s, xc + ox, yc + oy, xc + x1, yc + y1); + if (error) return error; + + return nil; +} + +static fz_error * +linestroke(struct sctx *s, fz_point a, fz_point b) +{ + fz_error *error; + + float dx = b.x - a.x; + float dy = b.y - a.y; + float scale = s->linewidth / sqrt(dx * dx + dy * dy); + float dlx = dy * scale; + float dly = -dx * scale; + + error = line(s, a.x - dlx, a.y - dly, b.x - dlx, b.y - dly); + if (error) return error; + + error = line(s, b.x + dlx, b.y + dly, a.x + dlx, a.y + dly); + if (error) return error; + + return nil; +} + +static fz_error * +linejoin(struct sctx *s, fz_point a, fz_point b, fz_point c) +{ + fz_error *error; + float miterlimit = s->miterlimit; + float linewidth = s->linewidth; + int linejoin = s->linejoin; + float dx0, dy0; + float dx1, dy1; + float dlx0, dly0; + float dlx1, dly1; + float dmx, dmy; + float dmr2; + float scale; + float cross; + + dx0 = b.x - a.x; + dy0 = b.y - a.y; + + dx1 = c.x - b.x; + dy1 = c.y - b.y; + + if (dx0 * dx0 + dy0 * dy0 < FLT_EPSILON) + return nil; + if (dx1 * dx1 + dy1 * dy1 < FLT_EPSILON) + return nil; + + scale = linewidth / sqrt(dx0 * dx0 + dy0 * dy0); + dlx0 = dy0 * scale; + dly0 = -dx0 * scale; + + scale = linewidth / sqrt(dx1 * dx1 + dy1 * dy1); + dlx1 = dy1 * scale; + dly1 = -dx1 * scale; + + cross = dx1 * dy0 - dx0 * dy1; + + dmx = (dlx0 + dlx1) * 0.5; + dmy = (dly0 + dly1) * 0.5; + dmr2 = dmx * dmx + dmy * dmy; + + if (cross * cross < FLT_EPSILON && dx0 * dx1 + dy0 * dy1 >= 0) + linejoin = BEVEL; + + if (linejoin == MITER) + if (dmr2 * miterlimit * miterlimit < linewidth * linewidth) + linejoin = BEVEL; + + if (linejoin == BEVEL) + { + error = line(s, b.x - dlx0, b.y - dly0, b.x - dlx1, b.y - dly1); + if (error) return error; + error = line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0); + if (error) return error; + } + + if (linejoin == MITER) + { + scale = linewidth * linewidth / dmr2; + dmx *= scale; + dmy *= scale; + + if (cross < 0) + { + error = line(s, b.x - dlx0, b.y - dly0, b.x - dlx1, b.y - dly1); + if (error) return error; + error = line(s, b.x + dlx1, b.y + dly1, b.x + dmx, b.y + dmy); + if (error) return error; + error = line(s, b.x + dmx, b.y + dmy, b.x + dlx0, b.y + dly0); + if (error) return error; + } + else + { + error = line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0); + if (error) return error; + error = line(s, b.x - dlx0, b.y - dly0, b.x - dmx, b.y - dmy); + if (error) return error; + error = line(s, b.x - dmx, b.y - dmy, b.x - dlx1, b.y - dly1); + if (error) return error; + } + } + + if (linejoin == ROUND) + { + if (cross < 0) + { + error = line(s, b.x - dlx0, b.y - dly0, b.x - dlx1, b.y - dly1); + if (error) return error; + error = arc(s, b.x, b.y, dlx1, dly1, dlx0, dly0); + if (error) return error; + } + else + { + error = line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0); + if (error) return error; + error = arc(s, b.x, b.y, -dlx0, -dly0, -dlx1, -dly1); + if (error) return error; + } + } + + return nil; +} + +static fz_error * +linecap(struct sctx *s, fz_point a, fz_point b) +{ + fz_error *error; + float flatness = s->flatness; + float linewidth = s->linewidth; + int linecap = s->linecap; + + float dx = b.x - a.x; + float dy = b.y - a.y; + + float scale = linewidth / sqrt(dx * dx + dy * dy); + float dlx = dy * scale; + float dly = -dx * scale; + + if (linecap == BUTT) + return line(s, b.x - dlx, b.y - dly, b.x + dlx, b.y + dly); + + if (linecap == ROUND) + { + int i; + int n = ceil(M_PI / (2.0 * M_SQRT2 * sqrt(flatness / linewidth))); + float ox = b.x - dlx; + float oy = b.y - dly; + for (i = 1; i < n; i++) + { + float theta = M_PI * i / n; + float cth = cos(theta); + float sth = sin(theta); + float nx = b.x - dlx * cth - dly * sth; + float ny = b.y - dly * cth + dlx * sth; + error = line(s, ox, oy, nx, ny); + if (error) return error; + ox = nx; + oy = ny; + } + error = line(s, ox, oy, b.x + dlx, b.y + dly); + if (error) return error; + } + + if (linecap == SQUARE) + { + error = line(s, b.x - dlx, b.y - dly, + b.x - dlx - dly, + b.y - dly + dlx); + if (error) return error; + error = line(s, b.x - dlx - dly, + b.y - dly + dlx, + b.x + dlx - dly, + b.y + dly + dlx); + if (error) return error; + error = line(s, b.x + dlx - dly, + b.y + dly + dlx, + b.x + dlx, b.y + dly); + if (error) return error; + } + + return nil; +} + +static fz_error * +linedot(struct sctx *s, fz_point a) +{ + fz_error *error; + float flatness = s->flatness; + float linewidth = s->linewidth; + int n = ceil(M_PI / (M_SQRT2 * sqrt(flatness / linewidth))); + float ox = a.x - linewidth; + float oy = a.y; + int i; + for (i = 1; i < n; i++) + { + float theta = M_PI * 2 * i / n; + float cth = cos(theta); + float sth = sin(theta); + float nx = a.x - cth * linewidth; + float ny = a.y + sth * linewidth; + error = line(s, ox, oy, nx, ny); + if (error) return error; + ox = nx; + oy = ny; + } + error = line(s, ox, oy, a.x - linewidth, a.y); + if (error) return error; + return nil; +} + +static fz_error * +strokeflush(struct sctx *s) +{ + fz_error *error; + + if (s->sn == 2) + { + error = linecap(s, s->beg[1], s->beg[0]); + if (error) return error; + error = linecap(s, s->seg[0], s->seg[1]); + if (error) return error; + } + else if (s->dot) + { + error = linedot(s, s->beg[0]); + if (error) return error; + } + + s->dot = 0; + + return nil; +} + +static fz_error * +strokemoveto(struct sctx *s, fz_point cur) +{ + fz_error *error; + + error = strokeflush(s); + if (error) return error; + + s->seg[0] = cur; + s->beg[0] = cur; + s->sn = 1; + s->bn = 1; + + return nil; +} + +static fz_error * +strokelineto(struct sctx *s, fz_point cur) +{ + fz_error *error; + + float dx = cur.x - s->seg[s->sn-1].x; + float dy = cur.y - s->seg[s->sn-1].y; + + if (dx * dx + dy * dy < s->flatness * s->flatness * 0.25) + { + s->dot = 1; + return nil; + } + + error = linestroke(s, s->seg[s->sn-1], cur); + if (error) return error; + + if (s->sn == 2) + { + error = linejoin(s, s->seg[0], s->seg[1], cur); + if (error) return error; + + s->seg[0] = s->seg[1]; + s->seg[1] = cur; + } + + if (s->sn == 1) + s->seg[s->sn++] = cur; + if (s->bn == 1) + s->beg[s->bn++] = cur; + + return nil; +} + +static fz_error * +strokeclosepath(struct sctx *s) +{ + fz_error *error; + + if (s->sn == 2) + { + error = strokelineto(s, s->beg[0]); + if (error) return error; + + if (s->seg[1].x == s->beg[0].x && s->seg[1].y == s->beg[0].y) + error = linejoin(s, s->seg[0], s->beg[0], s->beg[1]); + else + error = linejoin(s, s->seg[1], s->beg[0], s->beg[1]); + if (error) return error; + } + + else if (s->dot) + { + error = linedot(s, s->beg[0]); + if (error) return error; + } + + s->bn = 0; + s->sn = 0; + s->dot = 0; + + return nil; +} + +static fz_error * +strokebezier(struct sctx *s, + float xa, float ya, + float xb, float yb, + float xc, float yc, + float xd, float yd) +{ + fz_error *error; + float dmax; + float xab, yab; + float xbc, ybc; + float xcd, ycd; + float xabc, yabc; + float xbcd, ybcd; + float xabcd, yabcd; + + /* termination check */ + dmax = ABS(xa - xb); + dmax = MAX(dmax, ABS(ya - yb)); + dmax = MAX(dmax, ABS(xd - xc)); + dmax = MAX(dmax, ABS(yd - yc)); + if (dmax < s->flatness) { + fz_point p; + p.x = xd; + p.y = yd; + return strokelineto(s, p); + } + + xab = xa + xb; + yab = ya + yb; + xbc = xb + xc; + ybc = yb + yc; + xcd = xc + xd; + ycd = yc + yd; + + xabc = xab + xbc; + yabc = yab + ybc; + xbcd = xbc + xcd; + ybcd = ybc + ycd; + + xabcd = xabc + xbcd; + yabcd = yabc + ybcd; + + xab *= 0.5f; yab *= 0.5f; + xbc *= 0.5f; ybc *= 0.5f; + xcd *= 0.5f; ycd *= 0.5f; + + xabc *= 0.25f; yabc *= 0.25f; + xbcd *= 0.25f; ybcd *= 0.25f; + + xabcd *= 0.125f; yabcd *= 0.125f; + + error = strokebezier(s, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd); + if (error) + return error; + + return strokebezier(s, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd); +} + +fz_error * +fz_strokepath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness) +{ + fz_error *error; + struct sctx s; + fz_point p0, p1, p2, p3; + int i; + + s.gel = gel; + s.ctm = &ctm; + s.flatness = flatness; + + s.linecap = path->linecap; + s.linejoin = path->linejoin; + s.linewidth = path->linewidth * 0.5; + s.miterlimit = path->miterlimit; + s.sn = 0; + s.bn = 0; + s.dot = 0; + + i = 0; + + while (i < path->len) + { + switch (path->els[i++].k) + { + case FZ_MOVETO: + p1.x = path->els[i++].v; + p1.y = path->els[i++].v; + error = strokemoveto(&s, p1); + if (error) + return error; + p0 = p1; + break; + + case FZ_LINETO: + p1.x = path->els[i++].v; + p1.y = path->els[i++].v; + error = strokelineto(&s, p1); + if (error) + return error; + p0 = p1; + break; + + case FZ_CURVETO: + p1.x = path->els[i++].v; + p1.y = path->els[i++].v; + p2.x = path->els[i++].v; + p2.y = path->els[i++].v; + p3.x = path->els[i++].v; + p3.y = path->els[i++].v; + error = strokebezier(&s, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + if (error) + return error; + p0 = p3; + break; + + case FZ_CLOSEPATH: + error = strokeclosepath(&s); + if (error) + return error; + break; + } + } + + return strokeflush(&s); +} + +static fz_error * +dashmoveto(struct sctx *s, fz_point a) +{ + s->toggle = 1; + s->offset = 0; + s->phase = s->dash->phase; + + while (s->phase >= s->dash->array[s->offset]) + { + s->toggle = !s->toggle; + s->phase -= s->dash->array[s->offset]; + s->offset ++; + if (s->offset == s->dash->len) + s->offset = 0; + } + + s->cur = a; + + if (s->toggle) + return strokemoveto(s, a); + + return nil; +} + +static fz_error * +dashlineto(struct sctx *s, fz_point b) +{ + fz_error *error; + float dx, dy; + float total, used, ratio; + fz_point a; + fz_point m; + + a = s->cur; + dx = b.x - a.x; + dy = b.y - a.y; + total = sqrt(dx * dx + dy * dy); + used = 0; + + while (total - used > s->dash->array[s->offset] - s->phase) + { + used += s->dash->array[s->offset] - s->phase; + ratio = used / total; + m.x = a.x + ratio * dx; + m.y = a.y + ratio * dy; + + if (s->toggle) + error = strokelineto(s, m); + else + error = strokemoveto(s, m); + if (error) + return error; + + s->toggle = !s->toggle; + s->phase = 0; + s->offset ++; + if (s->offset == s->dash->len) + s->offset = 0; + } + + s->phase += total - used; + + s->cur = b; + + if (s->toggle) + return strokelineto(s, b); + + return nil; +} + +static fz_error * +dashbezier(struct sctx *s, + float xa, float ya, + float xb, float yb, + float xc, float yc, + float xd, float yd) +{ + fz_error *error; + float dmax; + float xab, yab; + float xbc, ybc; + float xcd, ycd; + float xabc, yabc; + float xbcd, ybcd; + float xabcd, yabcd; + + /* termination check */ + dmax = ABS(xa - xb); + dmax = MAX(dmax, ABS(ya - yb)); + dmax = MAX(dmax, ABS(xd - xc)); + dmax = MAX(dmax, ABS(yd - yc)); + if (dmax < s->flatness) { + fz_point p; + p.x = xd; + p.y = yd; + return dashlineto(s, p); + } + + xab = xa + xb; + yab = ya + yb; + xbc = xb + xc; + ybc = yb + yc; + xcd = xc + xd; + ycd = yc + yd; + + xabc = xab + xbc; + yabc = yab + ybc; + xbcd = xbc + xcd; + ybcd = ybc + ycd; + + xabcd = xabc + xbcd; + yabcd = yabc + ybcd; + + xab *= 0.5f; yab *= 0.5f; + xbc *= 0.5f; ybc *= 0.5f; + xcd *= 0.5f; ycd *= 0.5f; + + xabc *= 0.25f; yabc *= 0.25f; + xbcd *= 0.25f; ybcd *= 0.25f; + + xabcd *= 0.125f; yabcd *= 0.125f; + + error = dashbezier(s, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd); + if (error) return error; + return dashbezier(s, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd); +} + +fz_error * +fz_dashpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness) +{ + fz_error *error; + struct sctx s; + fz_point p0, p1, p2, p3, beg; + int i; + + s.gel = gel; + s.ctm = &ctm; + s.flatness = flatness; + + s.linecap = path->linecap; + s.linejoin = path->linejoin; + s.linewidth = path->linewidth * 0.5; + s.miterlimit = path->miterlimit; + s.sn = 0; + s.bn = 0; + s.dot = 0; + + s.dash = path->dash; + s.toggle = 0; + s.offset = 0; + s.phase = 0; + + i = 0; + + while (i < path->len) + { + switch (path->els[i++].k) + { + case FZ_MOVETO: + p1.x = path->els[i++].v; + p1.y = path->els[i++].v; + error = dashmoveto(&s, p1); + if (error) + return error; + beg = p0 = p1; + break; + + case FZ_LINETO: + p1.x = path->els[i++].v; + p1.y = path->els[i++].v; + error = dashlineto(&s, p1); + if (error) + return error; + p0 = p1; + break; + + case FZ_CURVETO: + p1.x = path->els[i++].v; + p1.y = path->els[i++].v; + p2.x = path->els[i++].v; + p2.y = path->els[i++].v; + p3.x = path->els[i++].v; + p3.y = path->els[i++].v; + error = dashbezier(&s, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + if (error) + return error; + p0 = p3; + break; + + case FZ_CLOSEPATH: + error = dashlineto(&s, beg); + if (error) + return error; + break; + } + } + + return strokeflush(&s); +} + diff --git a/rosapps/smartpdf/fitz/raster/pixmap.c b/rosapps/smartpdf/fitz/raster/pixmap.c new file mode 100644 index 00000000000..71834427b38 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/pixmap.c @@ -0,0 +1,127 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +fz_error * +fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n) +{ + fz_pixmap *pix; + + pix = *pixp = fz_malloc(sizeof(fz_pixmap)); + if (!pix) + return fz_outofmem; + + pix->x = x; + pix->y = y; + pix->w = w; + pix->h = h; + pix->n = n; + + pix->samples = fz_malloc(pix->w * pix->h * pix->n * sizeof(fz_sample)); + if (!pix->samples) { + fz_free(pix); + return fz_outofmem; + } + + return nil; +} + +fz_error * +fz_newpixmapwithrect(fz_pixmap **pixp, fz_irect r, int n) +{ + return fz_newpixmap(pixp, + r.x0, r.y0, + r.x1 - r.x0, + r.y1 - r.y0, n); +} + +fz_error * +fz_newpixmapcopy(fz_pixmap **pixp, fz_pixmap *old) +{ + fz_error *error; + error = fz_newpixmap(pixp, old->x, old->y, old->w, old->h, old->n); + if (error) + return error; + memcpy((*pixp)->samples, old->samples, old->w * old->h * old->n); + return nil; +} + +void +fz_droppixmap(fz_pixmap *pix) +{ + fz_free(pix->samples); + fz_free(pix); +} + +void +fz_clearpixmap(fz_pixmap *pix) +{ + memset(pix->samples, 0, pix->w * pix->h * pix->n * sizeof(fz_sample)); +} + +void +fz_gammapixmap(fz_pixmap *pix, float gamma) +{ + unsigned char table[256]; + int n = pix->w * pix->h * pix->n; + unsigned char *p = pix->samples; + int i; + for (i = 0; i < 256; i++) + table[i] = CLAMP(pow(i / 255.0, gamma) * 255.0, 0, 255); + while (n--) + *p = table[*p]; p++; +} + +void +fz_debugpixmap(fz_pixmap *pix) +{ + if (pix->n == 4) + { + int x, y; + FILE *ppm = fopen("out.ppm", "wb"); + FILE *pgm = fopen("out.pgm", "wb"); + fprintf(ppm, "P6\n%d %d\n255\n", pix->w, pix->h); + fprintf(pgm, "P5\n%d %d\n255\n", pix->w, pix->h); + + for (y = 0; y < pix->h; y++) + for (x = 0; x < pix->w; x++) + { + int a = pix->samples[x * pix->n + y * pix->w * pix->n + 0]; + int r = pix->samples[x * pix->n + y * pix->w * pix->n + 1]; + int g = pix->samples[x * pix->n + y * pix->w * pix->n + 2]; + int b = pix->samples[x * pix->n + y * pix->w * pix->n + 3]; + putc(a, pgm); + putc(r, ppm); + putc(g, ppm); + putc(b, ppm); + } + + if (ppm) + fclose(ppm); + if (pgm) + fclose(pgm); + } + + else if (pix->n == 2) + { + int x, y; + FILE *pgm = fopen("out.pgm", "wb"); + fprintf(pgm, "P5\n%d %d\n255\n", pix->w, pix->h); + + for (y = 0; y < pix->h; y++) + for (x = 0; x < pix->w; x++) + { + putc(pix->samples[y * pix->w * 2 + x * 2 + 1], pgm); + } + fclose(pgm); + } + + else if (pix->n == 1) + { + FILE *pgm = fopen("out.pgm", "w"); + fprintf(pgm, "P5\n%d %d\n255\n", pix->w, pix->h); + fwrite(pix->samples, 1, pix->w * pix->h, pgm); + fclose(pgm); + } +} + diff --git a/rosapps/smartpdf/fitz/raster/porterduff.c b/rosapps/smartpdf/fitz/raster/porterduff.c new file mode 100644 index 00000000000..74b34ac20bc --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/porterduff.c @@ -0,0 +1,359 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef unsigned char byte; + +/* + * Blend pixmap regions + */ + +/* dst = src over dst */ +static void +duff_non(byte * restrict sp0, int sw, int sn, byte * restrict dp0, int dw, int w0, int h) +{ + int k; + while (h--) + { + byte *sp = sp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte sa = sp[0]; + byte ssa = 255 - sa; + for (k = 0; k < sn; k++) + { + dp[k] = sp[k] + fz_mul255(dp[k], ssa); + } + sp += sn; + dp += sn; + } + sp0 += sw; + dp0 += dw; + } +} + +/* dst = src in msk */ +static void +duff_nimcn(byte * restrict sp0, int sw, int sn, byte * restrict mp0, int mw, int mn, byte * restrict dp0, int dw, int w0, int h) +{ + int k; + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + for (k = 0; k < sn; k++) + dp[k] = fz_mul255(sp[k], ma); + sp += sn; + mp += mn; + dp += sn; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +/* dst = src in msk over dst */ +static void +duff_nimon(byte * restrict sp0, int sw, int sn, byte * restrict mp0, int mw, int mn, byte * restrict dp0, int dw, int w0, int h) +{ + int k; + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + /* TODO: validate this */ + byte ma = mp[0]; + byte sa = fz_mul255(sp[0], ma); + byte ssa = 255 - sa; + for (k = 0; k < sn; k++) + { + dp[k] = fz_mul255(sp[k], ma) + fz_mul255(dp[k], ssa); + } + sp += sn; + mp += mn; + dp += sn; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_1o1(byte * restrict sp0, int sw, byte * restrict dp0, int dw, int w0, int h) +{ + /* duff_non(sp0, sw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + dp[0] = sp[0] + fz_mul255(dp[0], 255 - sp[0]); + sp ++; + dp ++; + } + sp0 += sw; + dp0 += dw; + } +} + +static void duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h) +{ + /* duff_non(sp0, sw, 4, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ssa = 255 - sp[0]; + dp[0] = sp[0] + fz_mul255(dp[0], ssa); + dp[1] = sp[1] + fz_mul255(dp[1], ssa); + dp[2] = sp[2] + fz_mul255(dp[2], ssa); + dp[3] = sp[3] + fz_mul255(dp[3], ssa); + sp += 4; + dp += 4; + } + sp0 += sw; + dp0 += dw; + } +} + +static void duff_1i1c1(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) +{ + /* duff_nimcn(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + dp[0] = fz_mul255(sp[0], mp[0]); + sp ++; + mp ++; + dp ++; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_4i1c4(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) +{ + /* duff_nimcn(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + dp[0] = fz_mul255(sp[0], ma); + dp[1] = fz_mul255(sp[1], ma); + dp[2] = fz_mul255(sp[2], ma); + dp[3] = fz_mul255(sp[3], ma); + sp += 4; + mp += 1; + dp += 4; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_1i1o1(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) +{ + /* duff_nimon(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + byte sa = fz_mul255(sp[0], ma); + byte ssa = 255 - sa; + dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa); + sp ++; + mp ++; + dp ++; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_4i1o4(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) +{ + /* duff_nimon(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + byte sa = fz_mul255(sp[0], ma); + byte ssa = 255 - sa; + dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa); + dp[1] = fz_mul255(sp[1], ma) + fz_mul255(dp[1], ssa); + dp[2] = fz_mul255(sp[2], ma) + fz_mul255(dp[2], ssa); + dp[3] = fz_mul255(sp[3], ma) + fz_mul255(dp[3], ssa); + sp += 4; + mp += 1; + dp += 4; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +/* + * Path and text masks + */ + +static void path_1c1(byte * restrict src, int cov, int len, byte * restrict dst) +{ + while (len--) + { + cov += *src; *src = 0; src++; + *dst++ = cov; + } +} + +static void path_1o1(byte * restrict src, int cov, int len, byte * restrict dst) +{ + while (len--) + { + cov += *src; *src = 0; src++; + dst[0] = cov + fz_mul255(dst[0], 255 - cov); + dst++; + } +} + +static void path_w3i1o4(byte * restrict rgb, byte * restrict src, int cov, int len, byte * restrict dst) +{ + byte rgb0 = rgb[0]; + byte rgb1 = rgb[1]; + byte rgb2 = rgb[2]; + byte ssa; + while (len--) + { + cov += *src; *src = 0; src++; + ssa = 255 - cov; + dst[0] = cov + fz_mul255(dst[0], ssa); + dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa); + dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa); + dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa); + dst += 4; + } +} + +static void text_1c1(byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) +{ + while (h--) + { + byte *src = src0; + byte *dst = dst0; + int w = w0; + while (w--) + { + *dst++ = *src++; + } + src0 += srcw; + dst0 += dstw; + } +} + +static void text_1o1(byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) +{ + while (h--) + { + byte *src = src0; + byte *dst = dst0; + int w = w0; + while (w--) + { + dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]); + src++; + dst++; + } + src0 += srcw; + dst0 += dstw; + } +} + +static void text_w3i1o4(byte * restrict rgb, byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) +{ + unsigned char rgb0 = rgb[0]; + unsigned char rgb1 = rgb[1]; + unsigned char rgb2 = rgb[2]; + while (h--) + { + byte *src = src0; + byte *dst = dst0; + int w = w0; + while (w--) + { + byte sa = src[0]; + byte ssa = 255 - sa; + dst[0] = sa + fz_mul255(dst[0], ssa); + dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa); + dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa); + dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa); + src ++; + dst += 4; + } + src0 += srcw; + dst0 += dstw; + } +} + +/* + * ... and the function pointers + */ + +void (*fz_duff_non)(byte*,int,int,byte*,int,int,int) = duff_non; +void (*fz_duff_nimcn)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimcn; +void (*fz_duff_nimon)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimon; +void (*fz_duff_1o1)(byte*,int,byte*,int,int,int) = duff_1o1; +void (*fz_duff_4o4)(byte*,int,byte*,int,int,int) = duff_4o4; +void (*fz_duff_1i1c1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1c1; +void (*fz_duff_4i1c4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1c4; +void (*fz_duff_1i1o1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1o1; +void (*fz_duff_4i1o4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1o4; + +void (*fz_path_1c1)(byte*,int,int,byte*) = path_1c1; +void (*fz_path_1o1)(byte*,int,int,byte*) = path_1o1; +void (*fz_path_w3i1o4)(byte*,byte*,int,int,byte*) = path_w3i1o4; + +void (*fz_text_1c1)(byte*,int,byte*,int,int,int) = text_1c1; +void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1; +void (*fz_text_w3i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w3i1o4; + diff --git a/rosapps/smartpdf/fitz/raster/render.c b/rosapps/smartpdf/fitz/raster/render.c new file mode 100644 index 00000000000..9df1064dc25 --- /dev/null +++ b/rosapps/smartpdf/fitz/raster/render.c @@ -0,0 +1,885 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +#ifdef _WIN32 + #undef noDEBUG + #undef DEBUG + #define DEBUG(...) + #define noDEBUG(...) +#else + #define noDEBUG(args...) printf(args) + #ifndef DEBUG + #define DEBUG(args...) + #endif +#endif + +#define QUANT(x,a) (((int)((x) * (a))) / (a)) +#define HSUBPIX 5.0 +#define VSUBPIX 5.0 + +#define FNONE 0 +#define FOVER 1 +#define FRGB 4 + +static fz_error *rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm); + +fz_error * +fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem) +{ + fz_error *error; + fz_renderer *gc; + + gc = fz_malloc(sizeof(fz_renderer)); + if (!gc) + return fz_outofmem; + + gc->maskonly = maskonly; + gc->model = pcm; + gc->cache = nil; + gc->gel = nil; + gc->ael = nil; + + error = fz_newglyphcache(&gc->cache, gcmem / 24, gcmem); + if (error) + goto cleanup; + + error = fz_newgel(&gc->gel); + if (error) + goto cleanup; + + error = fz_newael(&gc->ael); + if (error) + goto cleanup; + + gc->dest = nil; + gc->over = nil; + gc->rgb[0] = 0; + gc->rgb[1] = 0; + gc->rgb[2] = 0; + gc->flag = 0; + + *gcp = gc; + return nil; + +cleanup: + if (gc->model) fz_dropcolorspace(gc->model); + if (gc->cache) fz_dropglyphcache(gc->cache); + if (gc->gel) fz_dropgel(gc->gel); + if (gc->ael) fz_dropael(gc->ael); + fz_free(gc); + return error; +} + +void +fz_droprenderer(fz_renderer *gc) +{ + if (gc->dest) fz_droppixmap(gc->dest); + if (gc->over) fz_droppixmap(gc->over); + + if (gc->model) fz_dropcolorspace(gc->model); + if (gc->cache) fz_dropglyphcache(gc->cache); + if (gc->gel) fz_dropgel(gc->gel); + if (gc->ael) fz_dropael(gc->ael); + fz_free(gc); +} + +/* + * Transform + */ + +static fz_error * +rendertransform(fz_renderer *gc, fz_transformnode *transform, fz_matrix ctm) +{ + fz_error *error; +DEBUG("transform [%g %g %g %g %g %g]\n", +transform->m.a, transform->m.b, +transform->m.c, transform->m.d, +transform->m.e, transform->m.f); +DEBUG("{\n"); + ctm = fz_concat(transform->m, ctm); + error = rendernode(gc, transform->super.first, ctm); +DEBUG("}\n"); + return error; +} + +/* + * Color + */ + +static fz_error * +rendersolid(fz_renderer *gc, fz_solidnode *solid, fz_matrix ctm) +{ + fz_error *error; + float rgb[3]; + unsigned char *p; + int n; + + if (gc->maskonly) + return fz_throw("assert: mask only renderer"); + if (gc->model->n != 3) + return fz_throw("assert: non-rgb renderer"); + + fz_convertcolor(solid->cs, solid->samples, gc->model, rgb); + gc->rgb[0] = rgb[0] * 255; + gc->rgb[1] = rgb[1] * 255; + gc->rgb[2] = rgb[2] * 255; + +DEBUG("solid %s [%d %d %d];\n", solid->cs->name, gc->rgb[0], gc->rgb[1], gc->rgb[2]); + + if (gc->flag == FOVER) + { + p = gc->over->samples; + n = gc->over->w * gc->over->h; + } + else + { + error = fz_newpixmapwithrect(&gc->dest, gc->clip, 4); + if (error) + return error; + p = gc->dest->samples; + n = gc->dest->w * gc->dest->h; + } + + while (n--) + { + p[0] = 255; + p[1] = gc->rgb[0]; + p[2] = gc->rgb[1]; + p[3] = gc->rgb[2]; + p += 4; + } + + return nil; +} + +/* + * Path + */ + +enum { HS = 17, VS = 15, SF = 1 }; + +static fz_error * +renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm) +{ + fz_error *error; + float flatness; + fz_irect gbox; + fz_irect clip; + + flatness = 0.3 / fz_matrixexpansion(ctm); + if (flatness < 0.1) + flatness = 0.1f; + + fz_resetgel(gc->gel, HS, VS); + + if (path->paint == FZ_STROKE) + { + if (path->dash) + error = fz_dashpath(gc->gel, path, ctm, flatness); + else + error = fz_strokepath(gc->gel, path, ctm, flatness); + } + else + error = fz_fillpath(gc->gel, path, ctm, flatness); + if (error) + return error; + + fz_sortgel(gc->gel); + + gbox = fz_boundgel(gc->gel); + clip = fz_intersectirects(gc->clip, gbox); + + if (fz_isemptyrect(clip)) + return nil; + +DEBUG("path %s;\n", path->paint == FZ_STROKE ? "stroke" : "fill"); + + if (gc->flag & FRGB) + { + return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, + clip, gc->over, gc->rgb, 1); + } + else if (gc->flag & FOVER) + { + return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, + clip, gc->over, nil, 1); + } + else + { + error = fz_newpixmapwithrect(&gc->dest, clip, 1); + if (error) + return error; + fz_clearpixmap(gc->dest); + return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, + clip, gc->dest, nil, 0); + } +} + +/* + * Text + */ + +static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig, int yorig) +{ + unsigned char *dp, *sp; + int w, h; + + int dx0 = dst->x; + int dy0 = dst->y; + int dx1 = dst->x + dst->w; + int dy1 = dst->y + dst->h; + + int x0 = xorig + src->x; + int y0 = yorig + src->y; + int x1 = x0 + src->w; + int y1 = y0 + src->h; + + int sx0 = 0; + int sy0 = 0; + int sx1 = src->w; + int sy1 = src->h; + + if (x1 <= dx0 || x0 >= dx1) return; + if (y1 <= dy0 || y0 >= dy1) return; + if (x0 < dx0) { sx0 += dx0 - x0; x0 = dx0; } + if (y0 < dy0) { sy0 += dy0 - y0; y0 = dy0; } + if (x1 > dx1) { sx1 += dx1 - x1; x1 = dx1; } + if (y1 > dy1) { sy1 += dy1 - y1; y1 = dy1; } + + sp = src->samples + (sy0 * src->w + sx0); + dp = dst->samples + ((y0 - dst->y) * dst->w + (x0 - dst->x)) * dst->n; + + w = sx1 - sx0; + h = sy1 - sy0; + + switch (gc->flag) + { + case FNONE: + assert(dst->n == 1); + fz_text_1o1(sp, src->w, dp, dst->w, w, h); + break; + + case FOVER: + assert(dst->n == 1); + fz_text_1o1(sp, src->w, dp, dst->w, w, h); + break; + + case FOVER | FRGB: + assert(dst->n == 4); + fz_text_w3i1o4(gc->rgb, sp, src->w, dp, dst->w * 4, w, h); + break; + + default: + assert(!"impossible flag in text span function"); + } +} + +static fz_error * +rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm) +{ + fz_error *error; + fz_irect tbox; + fz_irect clip; + fz_matrix tm, trm; + fz_glyph glyph; + int i, x, y, cid; + + tbox = fz_roundrect(fz_boundnode((fz_node*)text, ctm)); + clip = fz_intersectirects(gc->clip, tbox); + +DEBUG("text %s n=%d [%g %g %g %g];\n", +text->font->name, text->len, +text->trm.a, text->trm.b, text->trm.c, text->trm.d); + + if (fz_isemptyrect(clip)) + return nil; + + if (!(gc->flag & FOVER)) + { + error = fz_newpixmapwithrect(&gc->dest, clip, 1); + if (error) + return error; + fz_clearpixmap(gc->dest); + } + + tm = text->trm; + + for (i = 0; i < text->len; i++) + { + cid = text->els[i].cid; + tm.e = text->els[i].x; + tm.f = text->els[i].y; + trm = fz_concat(tm, ctm); + x = fz_floor(trm.e); + y = fz_floor(trm.f); + trm.e = QUANT(trm.e - fz_floor(trm.e), HSUBPIX); + trm.f = QUANT(trm.f - fz_floor(trm.f), VSUBPIX); + + error = fz_renderglyph(gc->cache, &glyph, text->font, cid, trm); + if (error) + return error; + + if (!(gc->flag & FOVER)) + drawglyph(gc, gc->dest, &glyph, x, y); + else + drawglyph(gc, gc->over, &glyph, x, y); + } + + return nil; +} + +/* + * Image + */ + +static inline void +calcimagescale(fz_matrix ctm, int w, int h, int *odx, int *ody) +{ + float sx, sy; + int dx, dy; + + sx = sqrt(ctm.a * ctm.a + ctm.b * ctm.b); + dx = 1; + while (((w+dx-1)/dx)/sx > 2.0 && (w+dx-1)/dx > 1) + dx++; + + sy = sqrt(ctm.c * ctm.c + ctm.d * ctm.d); + dy = 1; + while (((h+dy-1)/dy)/sy > 2.0 && (h+dy-1)/dy > 1) + dy++; + + *odx = dx; + *ody = dy; +} + +static fz_error * +renderimage(fz_renderer *gc, fz_imagenode *node, fz_matrix ctm) +{ + fz_error *error; + fz_image *image = node->image; + fz_irect bbox; + fz_irect clip; + int dx, dy; + fz_pixmap *tile; + fz_pixmap *temp; + fz_matrix imgmat; + fz_matrix invmat; + int fa, fb, fc, fd; + int u0, v0; + int x0, y0; + int w, h; + +DEBUG("image %dx%d %d+%d %s\n{\n", image->w, image->h, image->n, image->a, image->cs?image->cs->name:"(nil)"); + + bbox = fz_roundrect(fz_boundnode((fz_node*)node, ctm)); + clip = fz_intersectirects(gc->clip, bbox); + + if (fz_isemptyrect(clip)) + return nil; + + calcimagescale(ctm, image->w, image->h, &dx, &dy); + +DEBUG(" load image\n"); + error = fz_newpixmap(&tile, 0, 0, image->w, image->h, image->n + 1); + if (error) + return error; + + error = image->loadtile(image, tile); + if (error) + goto cleanup; + + if (dx != 1 || dy != 1) + { +DEBUG(" scale image 1/%d 1/%d\n", dx, dy); + error = fz_scalepixmap(&temp, tile, dx, dy); + if (error) + goto cleanup; + fz_droppixmap(tile); + tile = temp; + } + + if (image->cs && image->cs != gc->model) + { +DEBUG(" convert from %s to %s\n", image->cs->name, gc->model->name); + error = fz_newpixmap(&temp, tile->x, tile->y, tile->w, tile->h, gc->model->n + 1); + if (error) + goto cleanup; + fz_convertpixmap(image->cs, tile, gc->model, temp); + fz_droppixmap(tile); + tile = temp; + } + + imgmat.a = 1.0 / tile->w; + imgmat.b = 0.0; + imgmat.c = 0.0; + imgmat.d = -1.0 / tile->h; + imgmat.e = 0.0; + imgmat.f = 1.0; + invmat = fz_invertmatrix(fz_concat(imgmat, ctm)); + + w = clip.x1 - clip.x0; + h = clip.y1 - clip.y0; + x0 = clip.x0; + y0 = clip.y0; + u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536; + v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536; + fa = invmat.a * 65536; + fb = invmat.b * 65536; + fc = invmat.c * 65536; + fd = invmat.d * 65536; + +#define PSRC tile->samples, tile->w, tile->h +#define PDST(p) p->samples + ((y0-p->y) * p->w + (x0-p->x)) * p->n, p->w * p->n +#define PCTM u0, v0, fa, fb, fc, fd, w, h + + switch (gc->flag) + { + case FNONE: + { +DEBUG(" fnone %d x %d\n", w, h); + if (image->cs) + error = fz_newpixmapwithrect(&gc->dest, clip, gc->model->n + 1); + else + error = fz_newpixmapwithrect(&gc->dest, clip, 1); + if (error) + goto cleanup; + + if (image->cs) + fz_img_4c4(PSRC, PDST(gc->dest), PCTM); + else + fz_img_1c1(PSRC, PDST(gc->dest), PCTM); + } + break; + + case FOVER: + { +DEBUG(" fover %d x %d\n", w, h); + if (image->cs) + fz_img_4o4(PSRC, PDST(gc->over), PCTM); + else + fz_img_1o1(PSRC, PDST(gc->over), PCTM); + } + break; + + case FOVER | FRGB: +DEBUG(" fover+rgb %d x %d\n", w, h); + fz_img_w3i1o4(gc->rgb, PSRC, PDST(gc->over), PCTM); + break; + + default: + assert(!"impossible flag in image span function"); + } + +DEBUG("}\n"); + + fz_droppixmap(tile); + return nil; + +cleanup: + fz_droppixmap(tile); + return error; +} + +/* + * Shade + */ + +static fz_error * +rendershade(fz_renderer *gc, fz_shadenode *node, fz_matrix ctm) +{ + fz_error *error; + fz_irect bbox; + + assert(!gc->maskonly); + + DEBUG("shade;\n"); + + bbox = fz_roundrect(fz_boundnode((fz_node*)node, ctm)); + bbox = fz_intersectirects(gc->clip, bbox); + + error = fz_newpixmapwithrect(&gc->dest, bbox, gc->model->n + 1); + if (error) + return error; + + return fz_rendershade(node->shade, ctm, gc->model, gc->dest); +} + +/* + * Over, Mask and Blend + */ + +static void +blendover(fz_renderer *gc, fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *sp, *dp; + fz_irect sr, dr; + int x, y, w, h; + + sr.x0 = src->x; + sr.y0 = src->y; + sr.x1 = src->x + src->w; + sr.y1 = src->y + src->h; + + dr.x0 = dst->x; + dr.y0 = dst->y; + dr.x1 = dst->x + dst->w; + dr.y1 = dst->y + dst->h; + + dr = fz_intersectirects(sr, dr); + x = dr.x0; + y = dr.y0; + w = dr.x1 - dr.x0; + h = dr.y1 - dr.y0; + + sp = src->samples + ((y - src->y) * src->w + (x - src->x)) * src->n; + dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n; + + if (src->n == 1 && dst->n == 1) + fz_duff_1o1(sp, src->w, dp, dst->w, w, h); + else if (src->n == 4 && dst->n == 4) + fz_duff_4o4(sp, src->w * 4, dp, dst->w * 4, w, h); + else if (src->n == dst->n) + fz_duff_non(sp, src->w * src->n, src->n, dp, dst->w * dst->n, w, h); + else + assert(!"blendover src and dst mismatch"); +} + +static void +blendmask(fz_renderer *gc, fz_pixmap *src, fz_pixmap *msk, fz_pixmap *dst, int over) +{ + unsigned char *sp, *dp, *mp; + fz_irect sr, dr, mr; + int x, y, w, h; + + sr.x0 = src->x; + sr.y0 = src->y; + sr.x1 = src->x + src->w; + sr.y1 = src->y + src->h; + + dr.x0 = dst->x; + dr.y0 = dst->y; + dr.x1 = dst->x + dst->w; + dr.y1 = dst->y + dst->h; + + mr.x0 = msk->x; + mr.y0 = msk->y; + mr.x1 = msk->x + msk->w; + mr.y1 = msk->y + msk->h; + + dr = fz_intersectirects(sr, dr); + dr = fz_intersectirects(dr, mr); + x = dr.x0; + y = dr.y0; + w = dr.x1 - dr.x0; + h = dr.y1 - dr.y0; + + sp = src->samples + ((y - src->y) * src->w + (x - src->x)) * src->n; + mp = msk->samples + ((y - msk->y) * msk->w + (x - msk->x)) * msk->n; + dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n; + + if (over) + { + if (src->n == 1 && msk->n == 1 && dst->n == 1) + fz_duff_1i1o1(sp, src->w, mp, msk->w, dp, dst->w, w, h); + else if (src->n == 4 && msk->n == 1 && dst->n == 4) + fz_duff_4i1o4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h); + else if (src->n == dst->n) + fz_duff_nimon(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h); + else + assert(!"blendmaskover src and msk and dst mismatch"); + } + else + { + if (src->n == 1 && msk->n == 1 && dst->n == 1) + fz_duff_1i1c1(sp, src->w, mp, msk->w, dp, dst->w, w, h); + else if (src->n == 4 && msk->n == 1 && dst->n == 4) + fz_duff_4i1c4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h); + else if (src->n == dst->n) + fz_duff_nimcn(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h); + else + assert(!"blendmask src and msk and dst mismatch"); + } +} + +static fz_error * +renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm) +{ + fz_error *error; + fz_node *child; + int cluster = 0; + + if (!gc->over) + { +DEBUG("over cluster %d\n{\n", gc->maskonly ? 1 : 4); + cluster = 1; + if (gc->maskonly) + error = fz_newpixmapwithrect(&gc->over, gc->clip, 1); + else + error = fz_newpixmapwithrect(&gc->over, gc->clip, 4); + if (error) + return error; + fz_clearpixmap(gc->over); + } +else DEBUG("over\n{\n"); + + for (child = over->super.first; child; child = child->next) + { + error = rendernode(gc, child, ctm); + if (error) + return error; + if (gc->dest) + { + blendover(gc, gc->dest, gc->over); + fz_droppixmap(gc->dest); + gc->dest = nil; + } + } + + if (cluster) + { + gc->dest = gc->over; + gc->over = nil; + } + +DEBUG("}\n"); + + return nil; +} + +static fz_error * +rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm) +{ + fz_error *error; + int oldmaskonly; + fz_pixmap *oldover; + fz_irect oldclip; + fz_irect bbox; + fz_irect clip; + fz_pixmap *shapepix = nil; + fz_pixmap *colorpix = nil; + fz_node *shape; + fz_node *color; + float rgb[3]; + + shape = mask->super.first; + color = shape->next; + + /* special case black voodo */ + if (gc->flag & FOVER) + { + if (fz_issolidnode(color)) + { + fz_solidnode *solid = (fz_solidnode*)color; + + fz_convertcolor(solid->cs, solid->samples, gc->model, rgb); + gc->rgb[0] = rgb[0] * 255; + gc->rgb[1] = rgb[1] * 255; + gc->rgb[2] = rgb[2] * 255; + gc->flag |= FRGB; + + /* we know these can handle the FRGB shortcut */ + if (fz_ispathnode(shape)) + return renderpath(gc, (fz_pathnode*)shape, ctm); + if (fz_istextnode(shape)) + return rendertext(gc, (fz_textnode*)shape, ctm); + if (fz_isimagenode(shape)) + return renderimage(gc, (fz_imagenode*)shape, ctm); + } + } + + oldclip = gc->clip; + oldover = gc->over; + + bbox = fz_roundrect(fz_boundnode(shape, ctm)); + clip = fz_intersectirects(bbox, gc->clip); + bbox = fz_roundrect(fz_boundnode(color, ctm)); + clip = fz_intersectirects(bbox, clip); + + if (fz_isemptyrect(clip)) + return nil; + +DEBUG("mask [%d %d %d %d]\n{\n", clip.x0, clip.y0, clip.x1, clip.y1); + + { + fz_irect sbox = fz_roundrect(fz_boundnode(shape, ctm)); + fz_irect cbox = fz_roundrect(fz_boundnode(color, ctm)); + if (cbox.x0 >= sbox.x0 && cbox.x1 <= sbox.x1) + if (cbox.y0 >= sbox.y0 && cbox.y1 <= sbox.y1) + DEBUG("potentially useless mask\n"); + } + + gc->clip = clip; + gc->over = nil; + + oldmaskonly = gc->maskonly; + gc->maskonly = 1; + + error = rendernode(gc, shape, ctm); + if (error) + goto cleanup; + shapepix = gc->dest; + gc->dest = nil; + + gc->maskonly = oldmaskonly; + + error = rendernode(gc, color, ctm); + if (error) + goto cleanup; + colorpix = gc->dest; + gc->dest = nil; + + gc->clip = oldclip; + gc->over = oldover; + + if (shapepix && colorpix) + { + if (gc->over) + { + blendmask(gc, colorpix, shapepix, gc->over, 1); + } + else + { + clip.x0 = MAX(colorpix->x, shapepix->x); + clip.y0 = MAX(colorpix->y, shapepix->y); + clip.x1 = MIN(colorpix->x+colorpix->w, shapepix->x+shapepix->w); + clip.y1 = MIN(colorpix->y+colorpix->h, shapepix->y+shapepix->h); + error = fz_newpixmapwithrect(&gc->dest, clip, colorpix->n); + if (error) + goto cleanup; + blendmask(gc, colorpix, shapepix, gc->dest, 0); + } + } + +DEBUG("}\n"); + + if (shapepix) fz_droppixmap(shapepix); + if (colorpix) fz_droppixmap(colorpix); + return nil; + +cleanup: + if (shapepix) fz_droppixmap(shapepix); + if (colorpix) fz_droppixmap(colorpix); + return error; +} + +/* + * Dispatch + */ + +static fz_error * +rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm) +{ + if (!node) + return nil; + + gc->flag = FNONE; + if (gc->over) + gc->flag |= FOVER; + + switch (node->kind) + { + case FZ_NOVER: + return renderover(gc, (fz_overnode*)node, ctm); + case FZ_NMASK: + return rendermask(gc, (fz_masknode*)node, ctm); + case FZ_NTRANSFORM: + return rendertransform(gc, (fz_transformnode*)node, ctm); + case FZ_NCOLOR: + return rendersolid(gc, (fz_solidnode*)node, ctm); + case FZ_NPATH: + return renderpath(gc, (fz_pathnode*)node, ctm); + case FZ_NTEXT: + return rendertext(gc, (fz_textnode*)node, ctm); + case FZ_NIMAGE: + return renderimage(gc, (fz_imagenode*)node, ctm); + case FZ_NSHADE: + return rendershade(gc, (fz_shadenode*)node, ctm); + case FZ_NLINK: + return rendernode(gc, ((fz_linknode*)node)->tree->root, ctm); + case FZ_NMETA: + return rendernode(gc, node->first, ctm); + } + + return nil; +} + +fz_error * +fz_rendertree(fz_pixmap **outp, + fz_renderer *gc, fz_tree *tree, fz_matrix ctm, + fz_irect bbox, int white) +{ + fz_error *error; + + gc->clip = bbox; + gc->over = nil; + + if (gc->maskonly) + error = fz_newpixmapwithrect(&gc->over, bbox, 1); + else + error = fz_newpixmapwithrect(&gc->over, bbox, 4); + if (error) + return error; + + if (white) + memset(gc->over->samples, 0xff, gc->over->w * gc->over->h * gc->over->n); + else + memset(gc->over->samples, 0x00, gc->over->w * gc->over->h * gc->over->n); + +DEBUG("tree %d [%d %d %d %d]\n{\n", +gc->maskonly ? 1 : 4, +bbox.x0, bbox.y0, bbox.x1, bbox.y1); + + error = rendernode(gc, tree->root, ctm); + if (error) + return error; + +DEBUG("}\n"); + + if (gc->dest) + { + blendover(gc, gc->dest, gc->over); + fz_droppixmap(gc->dest); + gc->dest = nil; + } + + *outp = gc->over; + gc->over = nil; + + return nil; +} + +fz_error * +fz_rendertreeover(fz_renderer *gc, fz_pixmap *dest, fz_tree *tree, fz_matrix ctm) +{ + fz_error *error; + + assert(!gc->maskonly); + assert(dest->n == 4); + + gc->clip.x0 = dest->x; + gc->clip.y0 = dest->y; + gc->clip.x1 = dest->x + dest->w; + gc->clip.y1 = dest->y + dest->h; + + gc->over = dest; + + error = rendernode(gc, tree->root, ctm); + if (error) + { + gc->over = nil; + return error; + } + + if (gc->dest) + { + blendover(gc, gc->dest, gc->over); + fz_droppixmap(gc->dest); + gc->dest = nil; + } + + gc->over = nil; + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/samus/sa_fixdoc.c b/rosapps/smartpdf/fitz/samus/sa_fixdoc.c new file mode 100644 index 00000000000..5e69064fcbb --- /dev/null +++ b/rosapps/smartpdf/fitz/samus/sa_fixdoc.c @@ -0,0 +1,327 @@ +/* + * FixedDocumentSequence and FixedDocument parts. + */ + +#include "fitz.h" +#include "samus.h" + +typedef struct sa_fixdoc_s sa_fixdoc; +typedef struct sa_fixpage_s sa_fixpage; + +struct sa_fixdocseq_s +{ + int count; /* pages */ + sa_fixdoc *docs; +}; + +struct sa_fixdoc_s +{ + int count; + sa_fixpage *pages; + sa_fixdoc *next; +}; + +struct sa_fixpage_s +{ + char *part; + int width; + int height; + /* char **linktargets; */ + sa_fixpage *next; +}; + +/* + * Debugging + */ + +static void +sa_debugfixdoc(sa_fixdoc *doc, int i) +{ + sa_fixpage *page = doc->pages; + printf(" FixedDocument\n {\n"); + while (page) + { + printf(" FixedPage %d w=%d h=%d %s\n", i, + page->width, page->height, page->part); + page = page->next; + i ++; + } + printf(" }\n"); +} + +void +sa_debugfixdocseq(sa_fixdocseq *seq) +{ + sa_fixdoc *doc = seq->docs; + int i = 0; + printf("FixedDocumentSequence count=%d\n{\n", seq->count); + while (doc) + { + sa_debugfixdoc(doc, i); + i += doc->count; + doc = doc->next; + } + printf("}\n"); +} + +/* + * Free data structures + */ + +static void +sa_dropfixpage(sa_fixpage *page) +{ + sa_fixpage *next; + while (page) + { + next = page->next; + fz_free(page->part); + fz_free(page); + page = next; + } +} + +static void +sa_dropfixdoc(sa_fixdoc *doc) +{ + sa_fixdoc *next; + while (doc) + { + next = doc->next; + if (doc->pages) + sa_dropfixpage(doc->pages); + fz_free(doc); + doc = next; + } +} + +void +sa_dropfixdocseq(sa_fixdocseq *seq) +{ + sa_dropfixdoc(seq->docs); + fz_free(seq); +} + +/* + * Load FixedDocument + */ +static fz_error * +sa_loadfixdoc(sa_fixdoc **docp, sa_package *pack, char *part) +{ + fz_error *error; + fz_stream *stm; + sa_xmlparser *parser; + sa_xmlitem *item; + sa_fixdoc *doc; + sa_fixpage *page; + sa_fixpage *last; + char buf[1024]; + + page = nil; + last = nil; + + error = sa_openpart(&stm, pack, part); + if (error) + return error; + + doc = fz_malloc(sizeof(sa_fixdoc)); + if (!doc) + { + error = fz_outofmem; + goto cleanupstm; + } + + doc->count = 0; + doc->pages = nil; + doc->next = nil; + + error = sa_openxml(&parser, stm, 0); + if (error) + goto cleanupdoc; + + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "FixedDocument")) + { + sa_xmldown(parser); + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "PageContent")) + { + char *src = sa_xmlatt(item, "Source"); + char *w = sa_xmlatt(item, "Width"); + char *h = sa_xmlatt(item, "Height"); + + if (!w) w = "0"; + if (!h) h = "0"; + + if (src) + { + sa_resolvepath(buf, part, src, sizeof buf); + page = fz_malloc(sizeof(sa_fixpage)); + if (!page) + { + error = fz_outofmem; + goto cleanupxml; + } + + page->part = fz_strdup(buf); + if (!page->part) + { + fz_free(page); + error = fz_outofmem; + goto cleanupxml; + } + + page->width = atoi(w); + page->height = atoi(h); + + if (last) + last->next = page; + else + doc->pages = page; + doc->count ++; + last = page; + } + } + item = sa_xmlnext(parser); + } + sa_xmlup(parser); + } + item = sa_xmlnext(parser); + } + + sa_closexml(parser); + fz_dropstream(stm); + *docp = doc; + return nil; + +cleanupxml: + sa_closexml(parser); +cleanupdoc: + sa_dropfixdoc(doc); +cleanupstm: + fz_dropstream(stm); + return error; +} + +/* + * Load FixedDocumentSequence + */ +fz_error * +sa_loadfixdocseq(sa_fixdocseq **seqp, sa_package *pack, char *part) +{ + fz_error *error; + fz_stream *stm; + sa_xmlparser *parser; + sa_xmlitem *item; + sa_fixdocseq *seq; + sa_fixdoc *doc; + sa_fixdoc *last; + char buf[1024]; + + seq = nil; + last = nil; + + error = sa_openpart(&stm, pack, part); + if (error) + return error; + + seq = fz_malloc(sizeof(sa_fixdocseq)); + if (!seq) + { + error = fz_outofmem; + goto cleanupstm; + } + + seq->count = 0; + seq->docs = nil; + + error = sa_openxml(&parser, stm, 0); + if (error) + goto cleanupseq; + + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "FixedDocumentSequence")) + { + sa_xmldown(parser); + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "DocumentReference")) + { + char *src = sa_xmlatt(item, "Source"); + if (src) + { + sa_resolvepath(buf, part, src, sizeof buf); + error = sa_loadfixdoc(&doc, pack, buf); + if (error) + goto cleanupxml; + if (last) + last->next = doc; + else + seq->docs = doc; + seq->count += doc->count; + last = doc; + } + } + item = sa_xmlnext(parser); + } + sa_xmlup(parser); + } + item = sa_xmlnext(parser); + } + + sa_closexml(parser); + fz_dropstream(stm); + *seqp = seq; + return nil; + +cleanupxml: + sa_closexml(parser); +cleanupseq: + sa_dropfixdocseq(seq); +cleanupstm: + fz_dropstream(stm); + return error; +} + +/* + * Accessors + */ + +int +sa_getpagecount(sa_fixdocseq *seq) +{ + return seq->count; +} + +char * +sa_getpagepart(sa_fixdocseq *seq, int idx) +{ + sa_fixdoc *doc = seq->docs; + int cur = 0; + + if (idx < 0 || idx >= seq->count) + return nil; + + while (doc) + { + sa_fixpage *page = doc->pages; + while (page) + { + if (idx == cur) + return page->part; + page = page->next; + cur ++; + } + doc = doc->next; + } + + return nil; +} + diff --git a/rosapps/smartpdf/fitz/samus/sa_misc.c b/rosapps/smartpdf/fitz/samus/sa_misc.c new file mode 100644 index 00000000000..0f71b4a2974 --- /dev/null +++ b/rosapps/smartpdf/fitz/samus/sa_misc.c @@ -0,0 +1,55 @@ +#include "fitz.h" +#include "samus.h" + +/* + * Create a new canonical absolute path given both + * a base url (current directory) and a relative or absolute name. + */ +char * +sa_resolvepath(char *dst, char *baseurl, char *parturl, int dstlen) +{ + char *end; + + if (parturl[0] == '/') + { + strlcpy(dst, parturl, dstlen); + } + else + { + strlcpy(dst, baseurl, dstlen); + end = strrchr(dst, '/'); + if (end) + end[1] = 0; + strlcat(dst, parturl, dstlen); + cleanname(dst); + } + + return dst; +} + +/* + * Test part names for equivalence. + * + * What we *should* do here (according to the spec) is... + * - Convert part name to a Unicode string by un-escaping UTF-8 octets. + * - Convert this to upper case. + * - Normalize to NFC. + * + * But all we do is a case insensitive ASCII string comparison. + */ + +static inline int toupper(int c) +{ + if (c >= 'a' && c <= 'z') + return c + 'A' - 'a'; + return c; +} + +int sa_strcmp(char *a, char *b) +{ + while (toupper(*a) == toupper(*b++)) + if (*a++ == 0) + return 0; + return toupper(*a) - toupper(*(b-1)); +} + diff --git a/rosapps/smartpdf/fitz/samus/sa_pack.c b/rosapps/smartpdf/fitz/samus/sa_pack.c new file mode 100644 index 00000000000..4c65ba38099 --- /dev/null +++ b/rosapps/smartpdf/fitz/samus/sa_pack.c @@ -0,0 +1,387 @@ +/* + * Metro physical packages and parts, mapped to a zip archive. + */ + +#include "fitz.h" +#include "samus.h" + +typedef struct sa_default_s sa_default; +typedef struct sa_override_s sa_override; + +struct sa_package_s +{ + sa_zip *zip; + sa_default *defaults; + sa_override *overrides; +}; + +/* + * Load the [Content_Types].xml data structures + * that define content types for the parts in the package. + */ + +struct sa_default_s +{ + char *extension; + char *mimetype; + sa_default *next; +}; + +struct sa_override_s +{ + char *partname; + char *mimetype; + sa_override *next; +}; + +static fz_error * +readcontenttypes(sa_package *pack) +{ + fz_error *error; + fz_stream *zipstm; + sa_xmlparser *parser; + sa_xmlitem *item; + + error = sa_openzipentry(&zipstm, pack->zip, "[Content_Types].xml"); + if (error) + return error; + + error = sa_openxml(&parser, zipstm, 0); + if (error) + goto cleanupzip; + + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "Types")) + { + sa_xmldown(parser); + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "Default")) + { + char *ext = sa_xmlatt(item, "Extension"); + char *type = sa_xmlatt(item, "ContentType"); + if (ext && type) + { + sa_default *newdef; + if (strchr(type, ';')) + strchr(type, ';')[0] = 0; + newdef = fz_malloc(sizeof(sa_default)); + if (!newdef) { error = fz_outofmem; goto cleanupxml; } + newdef->extension = fz_strdup(ext); + newdef->mimetype = fz_strdup(type); + newdef->next = pack->defaults; + pack->defaults = newdef; + } + } + + if (!strcmp(sa_xmlname(item), "Override")) + { + char *name = sa_xmlatt(item, "PartName"); + char *type = sa_xmlatt(item, "ContentType"); + if (name && type) + { + sa_override *newovr; + if (strchr(type, ';')) + strchr(type, ';')[0] = 0; + newovr = fz_malloc(sizeof(sa_override)); + if (!newovr) { error = fz_outofmem; goto cleanupxml; } + newovr->partname = fz_strdup(name); + newovr->mimetype = fz_strdup(type); + newovr->next = pack->overrides; + pack->overrides = newovr; + } + } + + item = sa_xmlnext(parser); + } + sa_xmlup(parser); + } + } + + sa_closexml(parser); + fz_dropstream(zipstm); + return nil; + +cleanupxml: + sa_closexml(parser); +cleanupzip: + fz_dropstream(zipstm); + return error; +} + +/* + * Return the type of a part, or nil if it doenst exist or has no type. + */ +char * +sa_typepart(sa_package *pack, char *partname) +{ + sa_default *def; + sa_override *ovr; + char *ext; + + if (partname[0] != '/') + return nil; + + if (sa_accesszipentry(pack->zip, partname + 1)) + { + for (ovr = pack->overrides; ovr; ovr = ovr->next) + if (!sa_strcmp(partname, ovr->partname)) + return ovr->mimetype; + + ext = strrchr(partname, '.'); + if (ext) + { + for (def = pack->defaults; def; def = def->next) + if (!sa_strcmp(ext + 1, def->extension)) + return def->mimetype; + } + } + + return nil; +} + +/* + * Open a package... + * Open the ZIP file. + * Load the content types. + * Load the relations for the root. + */ +fz_error * +sa_openpackage(sa_package **packp, char *filename) +{ + fz_error *error; + sa_package *pack; + + pack = fz_malloc(sizeof(sa_package)); + if (!pack) + return fz_outofmem; + + pack->zip = nil; + pack->defaults = nil; + pack->overrides = nil; + + error = sa_openzip(&pack->zip, filename); + if (error) + { + sa_closepackage(pack); + return error; + } + + error = readcontenttypes(pack); + if (error) + { + sa_closepackage(pack); + return error; + } + + *packp = pack; + return nil; +} + +void +sa_closepackage(sa_package *pack) +{ + sa_default *def, *ndef; + sa_override *ovr, *novr; + + if (pack->zip) + sa_closezip(pack->zip); + + for (def = pack->defaults; def; def = ndef) + { + ndef = def->next; + fz_free(def->extension); + fz_free(def->mimetype); + fz_free(def); + } + + for (ovr = pack->overrides; ovr; ovr = novr) + { + novr = ovr->next; + fz_free(ovr->partname); + fz_free(ovr->mimetype); + fz_free(ovr); + } + + fz_free(pack); +} + +void +sa_debugpackage(sa_package *pack) +{ + sa_default *def; + sa_override *ovr; + + printf("package\n{\n"); + + if (pack->zip) + sa_debugzip(pack->zip); + + printf(" defaults\n {\n"); + for (def = pack->defaults; def; def = def->next) + printf(" %-8s %s\n", def->extension, def->mimetype); + printf(" }\n"); + + printf(" overrides\n {\n"); + for (ovr = pack->overrides; ovr; ovr = ovr->next) + printf(" %s\n %s\n", ovr->partname, ovr->mimetype); + printf(" }\n"); + + printf("}\n"); +} + +/* + * Open a part for reading. + * It is NOT safe to open more than one part at a time. + */ +fz_error * +sa_openpart(fz_stream **stmp, sa_package *pack, char *partname) +{ + if (partname[0] != '/') + return fz_throw("ioerror: invalid part name: %s", partname); + return sa_openzipentry(stmp, pack->zip, partname + 1); +} + +/* + * Load a linked list of all the relations of a part. + * This is contained in /_rels/.rels + */ +fz_error * +sa_loadrelations(sa_relation **relsp, sa_package *pack, char *partname) +{ + fz_error *error; + fz_stream *zipstm; + sa_xmlparser *parser; + sa_xmlitem *item; + sa_relation *rels; + int len; + char *sep; + char *relsname; + char buf[1024]; + + if (partname[0] != '/') + return fz_throw("ioerror: invalid part name: %s", partname); + + sep = strrchr(partname, '/'); + if (!sep) + return fz_throw("ioerror: invalid part name: %s", partname); + + len = strlen(partname) + 11 + 1; + relsname = fz_malloc(len); + if (!relsname) + return fz_outofmem; + + memcpy(relsname, partname, sep - partname + 1); + relsname[sep - partname + 1] = 0; + strcat(relsname, "_rels/"); + strcat(relsname, sep + 1); + strcat(relsname, ".rels"); + + rels = nil; + + if (!sa_accesszipentry(pack->zip, relsname + 1)) + { + fz_free(relsname); + *relsp = nil; + return nil; + } + + error = sa_openzipentry(&zipstm, pack->zip, relsname + 1); + if (error) + goto cleanupname; + + error = sa_openxml(&parser, zipstm, 0); + if (error) + goto cleanupzip; + + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "Relationships")) + { + sa_xmldown(parser); + item = sa_xmlnext(parser); + while (item) + { + if (!strcmp(sa_xmlname(item), "Relationship")) + { + char *mode = sa_xmlatt(item, "TargetMode"); + char *id = sa_xmlatt(item, "Id"); + char *target = sa_xmlatt(item, "Target"); + char *type = sa_xmlatt(item, "Type"); + + if (!mode) + mode = "Internal"; + + if (id && target && type) + { + sa_relation *newrel; + newrel = fz_malloc(sizeof(sa_relation)); + if (!newrel) { error = fz_outofmem; goto cleanupxml; } + newrel->external = !strcmp(mode, "External"); + newrel->id = fz_strdup(id); + newrel->type = fz_strdup(type); + newrel->next = rels; + if (newrel->external) + newrel->target = fz_strdup(target); + else + { + sa_resolvepath(buf, partname, target, sizeof buf); + newrel->target = fz_strdup(buf); + } + rels = newrel; + } + } + + item = sa_xmlnext(parser); + } + sa_xmlup(parser); + } + } + + sa_closexml(parser); + fz_dropstream(zipstm); + fz_free(relsname); + *relsp = rels; + return nil; + +cleanupxml: + sa_closexml(parser); +cleanupzip: + fz_dropstream(zipstm); +cleanupname: + fz_free(relsname); + return error; +} + +void +sa_debugrelations(sa_relation *rel) +{ + printf("relations\n{\n"); + while (rel) + { + printf(" %s\n", rel->type); + printf(" %s%s\n", rel->external ? "external " : "", rel->target); + rel = rel->next; + } + printf("}\n"); +} + +void +sa_droprelations(sa_relation *rel) +{ + sa_relation *nrel; + while (rel) + { + nrel = rel->next; + fz_free(rel->target); + fz_free(rel->id); + fz_free(rel->type); + fz_free(rel); + rel = nrel; + } +} + diff --git a/rosapps/smartpdf/fitz/samus/sa_tiff.c b/rosapps/smartpdf/fitz/samus/sa_tiff.c new file mode 100644 index 00000000000..3fc6c7fe866 --- /dev/null +++ b/rosapps/smartpdf/fitz/samus/sa_tiff.c @@ -0,0 +1,653 @@ +/* + * Minimal TIFF image loader. Baseline TIFF 6.0 with CMYK support. + * Limited bit depth and extra samples support, as per Metro. + */ + +#include "fitz.h" +#include "samus.h" + +typedef struct sa_tiff_s sa_tiff; + +struct sa_tiff_s +{ + /* file and byte order */ + fz_stream *file; + unsigned order; + + /* where we can find the strips of image data */ + unsigned rowsperstrip; + unsigned *stripoffsets; + unsigned *stripbytecounts; + + /* colormap */ + unsigned *colormap; + + /* assorted tags */ + unsigned subfiletype; + unsigned photometric; + unsigned compression; + unsigned imagewidth; + unsigned imagelength; + unsigned samplesperpixel; + unsigned bitspersample; + unsigned planar; + unsigned xresolution; + unsigned yresolution; + unsigned resolutionunit; + unsigned fillorder; + unsigned g3opts; + unsigned g4opts; +}; + +enum +{ + TII = 0x4949, /* 'II' */ + TMM = 0x4d4d, /* 'MM' */ + TBYTE = 1, + TASCII = 2, + TSHORT = 3, + TLONG = 4, + TRATIONAL = 5 +}; + +#define NewSubfileType 254 +#define ImageWidth 256 +#define ImageLength 257 +#define BitsPerSample 258 +#define Compression 259 +#define PhotometricInterpretation 262 +#define FillOrder 266 +#define StripOffsets 273 +#define SamplesPerPixel 277 +#define RowsPerStrip 278 +#define StripByteCounts 279 +#define XResolution 282 +#define YResolution 283 +#define PlanarConfiguration 284 +#define T4Options 292 +#define T6Options 293 +#define ResolutionUnit 296 +#define ColorMap 320 + +static const unsigned char bitrev[256] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +static inline unsigned readshort(sa_tiff *tiff) +{ + unsigned a = fz_readbyte(tiff->file); + unsigned b = fz_readbyte(tiff->file); + if (tiff->order == TII) + return (b << 8) | a; + return (a << 8) | b; +} + +static inline unsigned readlong(sa_tiff *tiff) +{ + unsigned a = fz_readbyte(tiff->file); + unsigned b = fz_readbyte(tiff->file); + unsigned c = fz_readbyte(tiff->file); + unsigned d = fz_readbyte(tiff->file); + if (tiff->order == TII) + return (d << 24) | (c << 16) | (b << 8) | a; + return (a << 24) | (b << 16) | (c << 8) | d; +} + +static void +readtagval(unsigned *p, sa_tiff *tiff, unsigned type, unsigned ofs, unsigned n) +{ + fz_seek(tiff->file, ofs, 0); + while (n--) + { + switch (type) + { + case TRATIONAL: + *p = readlong(tiff); + *p = *p / readlong(tiff); + p ++; + break; + case TBYTE: *p++ = fz_readbyte(tiff->file); break; + case TSHORT: *p++ = readshort(tiff); break; + case TLONG: *p++ = readlong(tiff); break; + default: *p++ = 0; break; + } + } +} + +static void +tiffdebug(sa_tiff *tiff) +{ + int i, n; + + printf("TIFF <<\n"); + printf("\t/NewSubfileType %u\n", tiff->subfiletype); + printf("\t/PhotometricInterpretation %u\n", tiff->photometric); + printf("\t/Compression %u\n", tiff->compression); + printf("\t/ImageWidth %u\n", tiff->imagewidth); + printf("\t/ImageLength %u\n", tiff->imagelength); + printf("\t/BitsPerSample %u\n", tiff->bitspersample); + printf("\t/SamplesPerPixel %u\n", tiff->samplesperpixel); + printf("\t/PlanarConfiguration %u\n", tiff->planar); + printf("\t/XResolution %u\n", tiff->xresolution); + printf("\t/YResolution %u\n", tiff->yresolution); + printf("\t/ResolutionUnit %u\n", tiff->resolutionunit); + printf("\t/FillOrder %u\n", tiff->fillorder); + printf("\t/T4Options %u\n", tiff->g3opts); + printf("\t/T6Options %u\n", tiff->g4opts); + + printf("\t/ColorMap $%p\n", tiff->colormap); + + n = (tiff->imagelength + tiff->rowsperstrip - 1) / tiff->rowsperstrip; + + printf("\t/RowsPerStrip %u\n", tiff->rowsperstrip); + + if (tiff->stripoffsets) + { + printf("\t/StripOffsets [\n"); + for (i = 0; i < n; i++) + printf("\t\t%u\n", tiff->stripoffsets[i]); + printf("\t]\n"); + } + + if (tiff->stripbytecounts) + { + printf("\t/StripByteCounts [\n"); + for (i = 0; i < n; i++) + printf("\t\t%u\n", tiff->stripbytecounts[i]); + printf("\t]\n"); + } + + printf(">>\n"); +} + +static fz_error * +tiffreaduncompressed(sa_tiff *tiff, unsigned char *mem, unsigned len) +{ + printf("uncompressed %d bytes\n", len); + return nil; +} + +static fz_error * +tiffreadfiltered(sa_tiff *tiff, + unsigned char *mem, unsigned len, fz_filter *filter) +{ + fz_error *error; + fz_buffer *buf; + fz_buffer *out; + int count = 0; + + printf("compressed %d bytes\n", len); + + error = fz_newbufferwithmemory(&buf, mem, len); + if (error) + return error; + + error = fz_newbuffer(&out, FZ_BUFSIZE); + if (error) + { + fz_dropbuffer(buf); + return error; + } + + buf->eof = 1; + + while (1) + { + error = fz_process(filter, buf, out); + + printf(" + %d bytes\n", out->wp - out->rp); + + count += out->wp - out->rp; + + if (error == fz_ioneedin) + { + error = fz_throw("ioerror: premature eof in filter"); + goto cleanup; + } + else if (error == fz_ioneedout) + { + if (out->wp - out->rp == 0) + { + error = fz_growbuffer(out); + if (error) + goto cleanup; + } + out->rp = out->bp; + out->wp = out->bp; + } + else if (error == fz_iodone) + { + break; + } + else + goto cleanup; + } + + printf(" = %d bytes\n", count); + + return nil; + +cleanup: +printf("cleanup\n"); + fz_dropbuffer(out); + fz_dropbuffer(buf); + return error; +} + +static fz_error * +tiffreadpackbits(sa_tiff *tiff, unsigned char *mem, unsigned len) +{ + fz_error *error; + fz_filter *filter; + + error = fz_newrld(&filter, 0); + if (error) + return error; + + error = tiffreadfiltered(tiff, mem, len, filter); + fz_dropfilter(filter); + return error; +} + +static fz_error * +tiffreadfax(sa_tiff *tiff, unsigned char *mem, unsigned len, int comp) +{ + fz_error *error; + fz_filter *filter; + fz_obj *params; + + switch (comp) + { + default: + case 2: + error = fz_packobj(¶ms, + "<< /EncodedByteAlign true /EndOfLine false /EndOfBlock false " + "/K 0 /Columns %i /Rows %i /BlackIs1 %b >>", + tiff->imagewidth, + tiff->imagelength, + tiff->photometric == 0); + break; + case 3: + error = fz_packobj(¶ms, + "<< /EndOfLine false /EndOfBlock false " + "/K %i /Columns %i /Rows %i /BlackIs1 %b >>", + (tiff->g3opts & 1) ? tiff->rowsperstrip : 0, + tiff->imagewidth, + tiff->imagelength, + tiff->photometric == 0); + break; + case 4: + error = fz_packobj(¶ms, + "<< /EndOfLine false /EndOfBlock false " + "/K -1 /Columns %i /Rows %i /BlackIs1 %b >>", + tiff->imagewidth, + tiff->imagelength, + tiff->photometric == 0); + break; + } + + if (error) + return error; + + error = fz_newfaxd(&filter, params); + fz_dropobj(params); + if (error) + return error; + + error = tiffreadfiltered(tiff, mem, len, filter); + fz_dropfilter(filter); + return error; +} + +static fz_error * +tiffreadlzw(sa_tiff *tiff, unsigned char *mem, unsigned len) +{ + fz_error *error; + fz_filter *filter; + fz_obj *params; + + error = fz_packobj(¶ms, "<>"); + if (error) + return error; + + error = fz_newlzwd(&filter, params); + fz_dropobj(params); + if (error) + return error; + + error = tiffreadfiltered(tiff, mem, len, filter); + fz_dropfilter(filter); + return error; +} + +static fz_error * +tiffreadstrips(sa_tiff *tiff) +{ + /* switch on compression to create a filter */ + /* feed each strip to the filter */ + /* read out the data and pack the samples into an sa_image */ + + /* type 32773 / packbits -- nothing special (same row-padding as PDF) */ + /* type 2 / ccitt rle -- no EOL, no RTC, rows are byte-aligned */ + /* type 3 and 4 / g3 and g4 -- each strip starts new section */ + /* type 5 / lzw -- each strip is handled separately */ + + fz_error *error; + unsigned char *mem; + + int row; + int strip; + int len; + int i; + +printf("TIFF "); +printf("w=%d h=%d n=%d bpc=%d ", + tiff->imagewidth, tiff->imagelength, + tiff->samplesperpixel, tiff->bitspersample); + + switch (tiff->photometric) + { + case 0: printf("WhiteIsZero "); break; + case 1: printf("BlackIsZero "); break; + case 2: printf("RGB "); break; + case 3: printf("RGBPal "); break; + case 5: printf("CMYK "); break; + default: return fz_throw("ioerror: unknown TIFF color space: %d", tiff->photometric); + } + + switch (tiff->compression) + { + case 1: printf("Uncompressed "); break; + case 2: printf("CCITT "); break; + case 3: printf("FaxG3"); break; + case 4: printf("FaxG4"); break; + case 5: printf("LZW "); break; + case 32773: printf("PackBits "); break; + default: + return fz_throw("ioerror: unknown TIFF compression: %d", tiff->compression); + } + + printf("\n"); + + strip = 0; + for (row = 0; row < tiff->imagelength; row += tiff->rowsperstrip) + { + unsigned offset = tiff->stripoffsets[strip]; + unsigned bytecount = tiff->stripbytecounts[strip]; + + mem = fz_malloc(bytecount); + if (!mem) + return fz_outofmem; + + fz_seek(tiff->file, offset, 0); + len = fz_read(tiff->file, mem, bytecount); + if (len < 0) + { + fz_free(mem); + return fz_ioerror(tiff->file); + } + + if (tiff->fillorder == 2) + for (i = 0; i < len; i++) + mem[i] = bitrev[mem[i]]; + + switch (tiff->compression) + { + case 1: error = tiffreaduncompressed(tiff, mem, len); break; + case 2: error = tiffreadfax(tiff, mem, len, 2); break; + case 3: error = tiffreadfax(tiff, mem, len, 3); break; + case 4: error = tiffreadfax(tiff, mem, len, 4); break; + case 5: error = tiffreadlzw(tiff, mem, len); break; + case 32773: error = tiffreadpackbits(tiff, mem, len); break; + } + + fz_free(mem); + + if (error) + return error; + + strip ++; + } + + if (tiff->photometric == 3 && tiff->colormap) + { + /* TODO expand RGBPal datain buf via colormap to output */ + } + else + { + /* TODO copy buf to output */ + } + + return nil; +} + +static fz_error * +tiffreadtag(sa_tiff *tiff, unsigned offset) +{ + unsigned tag; + unsigned type; + unsigned count; + unsigned value; + + fz_seek(tiff->file, offset, 0); + tag = readshort(tiff); + type = readshort(tiff); + count = readlong(tiff); + + if ((type == TBYTE && count <= 4) || + (type == TSHORT && count <= 2) || + (type == TLONG && count <= 1)) + value = fz_tell(tiff->file); + else + value = readlong(tiff); + + switch (tag) + { + case NewSubfileType: + readtagval(&tiff->subfiletype, tiff, type, value, 1); + break; + case ImageWidth: + readtagval(&tiff->imagewidth, tiff, type, value, 1); + break; + case ImageLength: + readtagval(&tiff->imagelength, tiff, type, value, 1); + break; + case BitsPerSample: + readtagval(&tiff->bitspersample, tiff, type, value, 1); + break; + case Compression: + readtagval(&tiff->compression, tiff, type, value, 1); + break; + case PhotometricInterpretation: + readtagval(&tiff->photometric, tiff, type, value, 1); + break; + case FillOrder: + readtagval(&tiff->fillorder, tiff, type, value, 1); + break; + case SamplesPerPixel: + readtagval(&tiff->samplesperpixel, tiff, type, value, 1); + break; + case RowsPerStrip: + readtagval(&tiff->rowsperstrip, tiff, type, value, 1); + break; + case XResolution: + readtagval(&tiff->xresolution, tiff, type, value, 1); + break; + case YResolution: + readtagval(&tiff->yresolution, tiff, type, value, 1); + break; + case PlanarConfiguration: + readtagval(&tiff->planar, tiff, type, value, 1); + break; + case T4Options: + readtagval(&tiff->g3opts, tiff, type, value, 1); + break; + case T6Options: + readtagval(&tiff->g4opts, tiff, type, value, 1); + break; + case ResolutionUnit: + readtagval(&tiff->resolutionunit, tiff, type, value, 1); + break; + + case StripOffsets: + tiff->stripoffsets = fz_malloc(count * sizeof(unsigned)); + if (!tiff->stripoffsets) + return fz_outofmem; + readtagval(tiff->stripoffsets, tiff, type, value, count); + break; + + case StripByteCounts: + tiff->stripbytecounts = fz_malloc(count * sizeof(unsigned)); + if (!tiff->stripbytecounts) + return fz_outofmem; + readtagval(tiff->stripbytecounts, tiff, type, value, count); + break; + + case ColorMap: + tiff->colormap = fz_malloc(count * sizeof(unsigned)); + if (!tiff->colormap) + return fz_outofmem; + readtagval(tiff->colormap, tiff, type, value, count); + break; + + default: + /* + printf("unknown tag: %d t=%d n=%d\n", tag, type, count); + */ + break; + } + + return nil; +} + +static fz_error * +tiffreadifd(sa_tiff *tiff, unsigned offset) +{ + fz_error *error; + unsigned count; + unsigned i; + + fz_seek(tiff->file, offset, 0); + count = readshort(tiff); + + offset += 2; + for (i = 0; i < count; i++) + { + error = tiffreadtag(tiff, offset); + if (error) + return error; + offset += 12; + } + + if (getenv("TIFFDEBUG")) + tiffdebug(tiff); + + return tiffreadstrips(tiff); +} + +static fz_error * +tiffreadifh(sa_tiff *tiff, fz_stream *file) +{ + unsigned version; + unsigned offset; + + memset(tiff, 0, sizeof(sa_tiff)); + tiff->file = file; + + /* tag defaults, where applicable */ + tiff->bitspersample = 1; + tiff->compression = 1; + tiff->samplesperpixel = 1; + tiff->resolutionunit = 2; + tiff->rowsperstrip = 0xFFFFFFFF; + tiff->fillorder = 1; + tiff->planar = 1; + tiff->subfiletype = 0; + + /* get byte order marker */ + tiff->order = TII; + tiff->order = readshort(tiff); + if (tiff->order != TII && tiff->order != TMM) + return fz_throw("ioerror: not a TIFF file"); + + /* check version */ + version = readshort(tiff); + if (version != 42) + return fz_throw("ioerror: not a TIFF file"); + + /* get offset of IFD and then read it */ + offset = readlong(tiff); + return tiffreadifd(tiff, offset); +} + +fz_error * +sa_readtiff(fz_stream *file) +{ + fz_error *error; + fz_buffer *buf; + fz_stream *newfile; + sa_tiff tiff; + int n; + + /* TIFF requires random access. In Metro TIFFs are embedded in ZIP files. + * Compressed streams are not seekable, so we copy the data to an + * in-memory data buffer instead of reading from the original stream. + */ + + n = fz_readall(&buf, file); + if (n < 0) + return fz_ioerror(file); + +printf("readall -> %d\n", n); + + error = fz_openrbuffer(&newfile, buf); + if (error) + { + fz_dropbuffer(buf); + return error; + } + + error = tiffreadifh(&tiff, newfile); + + fz_free(tiff.colormap); + fz_free(tiff.stripoffsets); + fz_free(tiff.stripbytecounts); + + fz_dropstream(newfile); + fz_dropbuffer(buf); + + return error; +} + diff --git a/rosapps/smartpdf/fitz/samus/sa_xml.c b/rosapps/smartpdf/fitz/samus/sa_xml.c new file mode 100644 index 00000000000..065fa7651c5 --- /dev/null +++ b/rosapps/smartpdf/fitz/samus/sa_xml.c @@ -0,0 +1,344 @@ +#include "fitz.h" +#include "samus.h" + +#include + +#define XMLBUFLEN 4096 + +struct sa_xmlitem_s +{ + char *name; + char **atts; + sa_xmlitem *up; + sa_xmlitem *down; + sa_xmlitem *next; +}; + +struct sa_xmlparser_s +{ + fz_error *error; + sa_xmlitem *root; + sa_xmlitem *head; + int nexted; + int downed; +}; + +static void dropitem(sa_xmlitem *item) +{ + sa_xmlitem *next; + while (item) + { + next = item->next; + if (item->down) + dropitem(item->down); + fz_free(item); + item = next; + } +} + +static void onopentag(void *zp, const char *name, const char **atts) +{ + struct sa_xmlparser_s *sp = zp; + sa_xmlitem *item; + sa_xmlitem *tail; + int namelen; + int attslen; + int textlen; + char *p; + int i; + + if (sp->error) + return; + + /* count size to alloc */ + + namelen = strlen(name) + 1; + attslen = sizeof(char*); + textlen = 0; + for (i = 0; atts[i]; i++) + { + attslen += sizeof(char*); + textlen += strlen(atts[i]) + 1; + } + + item = fz_malloc(sizeof(sa_xmlitem) + attslen + namelen + textlen); + if (!item) + { + sp->error = fz_outofmem; + return; + } + + /* copy strings to new memory */ + + item->atts = (char**) (((char*)item) + sizeof(sa_xmlitem)); + item->name = ((char*)item) + sizeof(sa_xmlitem) + attslen; + p = ((char*)item) + sizeof(sa_xmlitem) + attslen + namelen; + + strcpy(item->name, name); + for (i = 0; atts[i]; i++) + { + item->atts[i] = p; + strcpy(item->atts[i], atts[i]); + p += strlen(p) + 1; + } + + item->atts[i] = 0; + + /* link item into tree */ + + item->up = sp->head; + item->down = nil; + item->next = nil; + + if (!sp->head) + { + sp->root = item; + sp->head = item; + return; + } + + if (!sp->head->down) + { + sp->head->down = item; + sp->head = item; + return; + } + + tail = sp->head->down; + while (tail->next) + tail = tail->next; + tail->next = item; + sp->head = item; +} + +static void onclosetag(void *zp, const char *name) +{ + struct sa_xmlparser_s *sp = zp; + + if (sp->error) + return; + + if (sp->head) + sp->head = sp->head->up; +} + +static inline int isxmlspace(int c) +{ + return c == ' ' || c == '\t' || c == '\r' || c == '\n'; +} + +static void ontext(void *zp, const char *buf, int len) +{ + struct sa_xmlparser_s *sp = zp; + int i; + + if (sp->error) + return; + + for (i = 0; i < len; i++) + { + if (!isxmlspace(buf[i])) + { + char *tmp = fz_malloc(len + 1); + const char *atts[] = {"", tmp, 0}; + if (!tmp) + { + sp->error = fz_outofmem; + return; + } + memcpy(tmp, buf, len); + tmp[len] = 0; + onopentag(zp, "", atts); + onclosetag(zp, ""); + fz_free(tmp); + return; + } + } +} + +fz_error * +sa_openxml(sa_xmlparser **spp, fz_stream *file, int ns) +{ + fz_error *error = nil; + sa_xmlparser *sp; + XML_Parser xp; + char *buf; + int len; + + sp = fz_malloc(sizeof(sa_xmlparser)); + if (!sp) + return fz_outofmem; + + sp->error = nil; + sp->root = nil; + sp->head = nil; + sp->downed = 0; + sp->nexted = 0; + + if (ns) + xp = XML_ParserCreateNS(nil, ns); + else + xp = XML_ParserCreate(nil); + if (!xp) + { + fz_free(sp); + return fz_outofmem; + } + + XML_SetUserData(xp, sp); + XML_SetParamEntityParsing(xp, XML_PARAM_ENTITY_PARSING_NEVER); + + XML_SetStartElementHandler(xp, onopentag); + XML_SetEndElementHandler(xp, onclosetag); + XML_SetCharacterDataHandler(xp, ontext); + + while (1) + { + buf = XML_GetBuffer(xp, XMLBUFLEN); + + len = fz_read(file, buf, XMLBUFLEN); + if (len < 0) + { + error = fz_ioerror(file); + goto cleanup; + } + + if (!XML_ParseBuffer(xp, len, len == 0)) + { + error = fz_throw("ioerror: xml: %s", + XML_ErrorString(XML_GetErrorCode(xp))); + goto cleanup; + } + + if (sp->error) + { + error = sp->error; + sp->error = nil; + goto cleanup; + } + + if (len == 0) + break; + } + + sp->head = nil; + *spp = sp; + return nil; + +cleanup: + if (sp->root) + dropitem(sp->root); + fz_free(sp); + XML_ParserFree(xp); + return error; +} + +void +sa_closexml(sa_xmlparser *sp) +{ + if (sp->root) + dropitem(sp->root); + fz_free(sp); +} + +static void indent(int n) +{ + while (n--) + printf(" "); +} + +void +sa_debugxml(sa_xmlitem *item, int level) +{ + int i; + + while (item) + { + indent(level); + + if (strlen(item->name) == 0) + printf("%s\n", item->atts[1]); + else + { + printf("<%s", item->name); + + for (i = 0; item->atts[i]; i += 2) + printf(" %s=\"%s\"", item->atts[i], item->atts[i+1]); + + if (item->down) + { + printf(">\n"); + sa_debugxml(item->down, level + 1); + indent(level); + printf("\n", item->name); + } + else + printf(" />\n"); + } + + item = item->next; + } +} + +sa_xmlitem * +sa_xmlnext(sa_xmlparser *sp) +{ + if (sp->downed) + return nil; + + if (!sp->head) + { + sp->head = sp->root; + return sp->head; + } + + if (!sp->nexted) + { + sp->nexted = 1; + return sp->head; + } + + if (sp->head->next) + { + sp->head = sp->head->next; + return sp->head; + } + + return nil; +} + +void +sa_xmldown(sa_xmlparser *sp) +{ + if (!sp->downed && sp->head && sp->head->down) + sp->head = sp->head->down; + else + sp->downed ++; + sp->nexted = 0; +} + +void +sa_xmlup(sa_xmlparser *sp) +{ + if (!sp->downed && sp->head && sp->head->up) + sp->head = sp->head->up; + else + sp->downed --; +} + +char * +sa_xmlname(sa_xmlitem *item) +{ + return item->name; +} + +char * +sa_xmlatt(sa_xmlitem *item, char *att) +{ + int i; + for (i = 0; item->atts[i]; i += 2) + if (!strcmp(item->atts[i], att)) + return item->atts[i + 1]; + return nil; +} + diff --git a/rosapps/smartpdf/fitz/samus/sa_zip.c b/rosapps/smartpdf/fitz/samus/sa_zip.c new file mode 100644 index 00000000000..c00f6f06a24 --- /dev/null +++ b/rosapps/smartpdf/fitz/samus/sa_zip.c @@ -0,0 +1,313 @@ +/* + * Support for a subset of PKZIP format v4.5: + * - no encryption + * - no multi-disk + * - only Store and Deflate + * - ZIP64 format (long long sizes and offsets) [TODO] + * + * TODO for Metro compliance: compare file names by unescaping %XX + * and then converting to upper-case NFC. + */ + +#include "fitz.h" +#include "samus.h" + +typedef struct sa_zipent_s sa_zipent; + +struct sa_zipent_s +{ + unsigned offset; + unsigned csize; + unsigned usize; + char *name; +}; + +struct sa_zip_s +{ + fz_stream *file; + int len; + sa_zipent *table; +}; + +static inline unsigned int read2(fz_stream *f) +{ + unsigned char a = fz_readbyte(f); + unsigned char b = fz_readbyte(f); + return (b << 8) | a; +} + +static inline unsigned int read4(fz_stream *f) +{ + unsigned char a = fz_readbyte(f); + unsigned char b = fz_readbyte(f); + unsigned char c = fz_readbyte(f); + unsigned char d = fz_readbyte(f); + return (d << 24) | (c << 16) | (b << 8) | a; +} + +static fz_error *readzipdir(sa_zip *zip, int startoffset) +{ + unsigned sign; + unsigned csize, usize; + unsigned namesize, metasize, comsize; + unsigned offset; + int i; + + fz_seek(zip->file, startoffset, 0); + + for (i = 0; i < zip->len; i++) + { + sign = read4(zip->file); + if (sign != 0x02014b50) + return fz_throw("ioerror: unknown zip signature"); + + (void) read2(zip->file); /* version made by */ + (void) read2(zip->file); /* version to extract */ + (void) read2(zip->file); /* general */ + (void) read2(zip->file); /* method */ + (void) read2(zip->file); /* last mod file time */ + (void) read2(zip->file); /* last mod file date */ + (void) read4(zip->file); /* crc-32 */ + csize = read4(zip->file); + usize = read4(zip->file); + namesize = read2(zip->file); + metasize = read2(zip->file); + comsize = read2(zip->file); + (void) read2(zip->file); /* disk number start */ + (void) read2(zip->file); /* int file atts */ + (void) read4(zip->file); /* ext file atts */ + offset = read4(zip->file); + + zip->table[i].offset = offset; + zip->table[i].csize = csize; + zip->table[i].usize = usize; + + zip->table[i].name = fz_malloc(namesize + 1); + if (!zip->table[i].name) + return fz_outofmem; + fz_read(zip->file, zip->table[i].name, namesize); + zip->table[i].name[namesize] = 0; + + fz_seek(zip->file, metasize, 1); + fz_seek(zip->file, comsize, 1); + } + + return nil; +} + +static fz_error *readzipendofdir(sa_zip *zip, int startoffset) +{ + unsigned sign; + unsigned count; + unsigned offset; + + fz_seek(zip->file, startoffset, 0); + + sign = read4(zip->file); + if (sign != 0x06054b50) + return fz_throw("ioerror: unknown zip signature"); + + (void) read2(zip->file); /* this disk */ + (void) read2(zip->file); /* start disk */ + (void) read2(zip->file); /* ents in this disk */ + count = read2(zip->file); /* ents in central directory */ + (void) read4(zip->file); /* size of central directory */ + offset = read4(zip->file); /* offset to central directory */ + + zip->len = count; + zip->table = fz_malloc(zip->len * sizeof(sa_zipent)); + if (!zip->table) + return fz_outofmem; + + memset(zip->table, 0, zip->len * sizeof(sa_zipent)); + + return readzipdir(zip, offset); +} + +static fz_error *findzipendofdir(sa_zip *zip) +{ + char buf[512]; + int back, maxback, filesize; + int n, i; + + filesize = fz_seek(zip->file, 0, 2); + if (filesize < 0) + return fz_ioerror(zip->file); + + maxback = MIN(filesize, 0xFFFF + sizeof buf); + back = MIN(maxback, sizeof buf); + + while (back < maxback) + { + fz_seek(zip->file, filesize - back, 0); + n = fz_read(zip->file, buf, sizeof buf); + if (n < 0) + return fz_ioerror(zip->file); + + for (i = n - 4; i > 0; i--) + if (!memcmp(buf + i, "\120\113\5\6", 4)) + return readzipendofdir(zip, filesize - back + i); + + back += sizeof buf - 4; + } + + return fz_throw("ioerror: could not find central directory in zip"); +} + +/* + * Open a ZIP archive for reading. + * Load the table of contents. + */ +fz_error * +sa_openzip(sa_zip **zipp, char *filename) +{ + fz_error *error; + sa_zip *zip; + + zip = *zipp = fz_malloc(sizeof(sa_zip)); + if (!zip) + return fz_outofmem; + + zip->file = nil; + zip->len = 0; + zip->table = nil; + + error = fz_openrfile(&zip->file, filename); + if (error) + return error; + + return findzipendofdir(zip); +} + +/* + * Free the table of contents and close the underlying file. + */ +void +sa_closezip(sa_zip *zip) +{ + int i; + + if (zip->file) + fz_dropstream(zip->file); + + for (i = 0; i < zip->len; i++) + if (zip->table[i].name) + fz_free(zip->table[i].name); + + fz_free(zip->table); +} + +/* + * Print a table of contents of the zip archive + */ +void +sa_debugzip(sa_zip *zip) +{ + int i; + + for (i = 0; i < zip->len; i++) + { + printf("%8u ", zip->table[i].usize); + if (zip->table[i].usize) + printf("%3d%% ", zip->table[i].csize * 100 / zip->table[i].usize); + else + printf(" --- "); + printf("%s\n", zip->table[i].name); + } +} + +int +sa_accesszipentry(sa_zip *zip, char *name) +{ + int i; + for (i = 0; i < zip->len; i++) + if (!sa_strcmp(name, zip->table[i].name)) + return 1; + return 0; +} + +/* + * Seek and push decoding filter to read an individual file in the zip archive. + */ +static fz_error *reallyopenzipentry(fz_stream **stmp, sa_zip *zip, int idx) +{ + fz_error *error; + fz_filter *filter; + fz_obj *obj; + unsigned sign, version, general, method; + unsigned csize, usize; + unsigned namesize, metasize; + int t; + + t = fz_seek(zip->file, zip->table[idx].offset, 0); + if (t < 0) + return fz_ioerror(zip->file); + + sign = read4(zip->file); + if (sign != 0x04034b50) + return fz_throw("ioerror: unknown zip signature"); + + version = read2(zip->file); + general = read2(zip->file); + method = read2(zip->file); + (void) read2(zip->file); /* time */ + (void) read2(zip->file); /* date */ + (void) read4(zip->file); /* crc-32 */ + csize = read4(zip->file); + usize = read4(zip->file); + namesize = read2(zip->file); + metasize = read2(zip->file); + + if ((version & 0xff) > 45) + return fz_throw("ioerror: unsupported zip version"); + + if (general & 0x0001) + return fz_throw("ioerror: encrypted zip entry"); + + t = fz_seek(zip->file, namesize + metasize, 1); + if (t < 0) + return fz_ioerror(zip->file); + + switch (method) + { + case 0: + error = fz_newnullfilter(&filter, csize); + if (error) + return error; + break; + + case 8: + error = fz_packobj(&obj, "<>"); + if (error) + return error; + error = fz_newflated(&filter, obj); + fz_dropobj(obj); + if (error) + return error; + break; + + default: + return fz_throw("ioerror: unsupported compression method"); + break; + } + + error = fz_openrfilter(stmp, filter, zip->file); + fz_dropfilter(filter); + if (error) + return error; + + return nil; +} + +fz_error * +sa_openzipentry(fz_stream **stmp, sa_zip *zip, char *name) +{ + int i; + + for (i = 0; i < zip->len; i++) + if (!sa_strcmp(name, zip->table[i].name)) + return reallyopenzipentry(stmp, zip, i); + + return fz_throw("ioerror: file not found in zip: '%s'", name); +} + diff --git a/rosapps/smartpdf/fitz/stream/crypt_arc4.c b/rosapps/smartpdf/fitz/stream/crypt_arc4.c new file mode 100644 index 00000000000..0a5c942fdb3 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/crypt_arc4.c @@ -0,0 +1,96 @@ +/* This code illustrates a sample implementation + * of the Arcfour algorithm + * Copyright (c) April 29, 1997 Kalle Kaukonen. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that this copyright + * notice and disclaimer are retained. + * + * THIS SOFTWARE IS PROVIDED BY KALLE KAUKONEN 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 KALLE + * KAUKONEN 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. + */ + +#include "fitz-base.h" +#include "fitz-stream.h" + +void +fz_arc4init(fz_arc4 *arc4, unsigned char *key, unsigned keylen) +{ + unsigned int t, u; + unsigned int keyindex; + unsigned int stateindex; + unsigned char *state; + unsigned int counter; + + state = arc4->state; + + arc4->x = 0; + arc4->y = 0; + + for (counter = 0; counter < 256; counter++) { + state[counter] = counter; + } + + keyindex = 0; + stateindex = 0; + + for (counter = 0; counter < 256; counter++) { + t = state[counter]; + stateindex = (stateindex + key[keyindex] + t) & 0xff; + u = state[stateindex]; + + state[stateindex] = t; + state[counter] = u; + + if (++keyindex >= keylen) { + keyindex = 0; + } + } +} + +unsigned char +fz_arc4next(fz_arc4 *arc4) +{ + unsigned int x; + unsigned int y; + unsigned int sx, sy; + unsigned char *state; + + state = arc4->state; + + x = (arc4->x + 1) & 0xff; + sx = state[x]; + y = (sx + arc4->y) & 0xff; + sy = state[y]; + + arc4->x = x; + arc4->y = y; + + state[y] = sx; + state[x] = sy; + + return state[(sx + sy) & 0xff]; +} + +void +fz_arc4encrypt(fz_arc4 *arc4, unsigned char *dest, unsigned char *src, unsigned len) +{ + unsigned int i; + for (i = 0; i < len; i++) { + unsigned char x; + x = fz_arc4next(arc4); + dest[i] = src[i] ^ x; + } +} + diff --git a/rosapps/smartpdf/fitz/stream/crypt_crc32.c b/rosapps/smartpdf/fitz/stream/crypt_crc32.c new file mode 100644 index 00000000000..dded733e48b --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/crypt_crc32.c @@ -0,0 +1,86 @@ +/* + * Compute the CRC-32 of a data buffer + */ + +#include "fitz-base.h" +#include "fitz-stream.h" + +static const unsigned long crctab[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 +}; + +#define DO1(buf) crc = crctab[((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); + +unsigned long +fz_crc32(unsigned long crc, unsigned char *buf, int len) +{ + if (buf == nil) + return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) + { + do { DO1(buf); } while (--len); + } + return crc ^ 0xffffffffL; +} + diff --git a/rosapps/smartpdf/fitz/stream/crypt_md5.c b/rosapps/smartpdf/fitz/stream/crypt_md5.c new file mode 100644 index 00000000000..cf20024b7f5 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/crypt_md5.c @@ -0,0 +1,270 @@ +/* +MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. +All rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*/ + +#include "fitz-base.h" +#include "fitz-stream.h" + +/* Constants for MD5Transform routine */ +enum +{ + S11 = 7, S12 = 12, S13 = 17, S14 = 22, + S21 = 5, S22 = 9, S23 = 14, S24 = 20, + S31 = 4, S32 = 11, S33 = 16, S34 = 23, + S41 = 6, S42 = 10, S43 = 15, S44 = 21 +}; + +static void encode(unsigned char *, unsigned long *, unsigned); +static void decode(unsigned long *, unsigned char *, unsigned); +static void transform(unsigned long state[4], unsigned char block[64]); + +static unsigned char padding[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 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE rotates x left n bits */ +#define ROTATE(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + * Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (unsigned long)(ac); \ + (a) = ROTATE ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (unsigned long)(ac); \ + (a) = ROTATE ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (unsigned long)(ac); \ + (a) = ROTATE ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (unsigned long)(ac); \ + (a) = ROTATE ((a), (s)); \ + (a) += (b); \ + } + +static void encode(unsigned char *output, unsigned long *input, unsigned len) +{ + unsigned i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +static void decode(unsigned long *output, unsigned char *input, unsigned len) +{ + unsigned i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[i] = ((unsigned long)input[j]) | + (((unsigned long)input[j+1]) << 8) | + (((unsigned long)input[j+2]) << 16) | + (((unsigned long)input[j+3]) << 24); + } +} + +static void transform(unsigned long state[4], unsigned char block[64]) +{ + unsigned long a = state[0]; + unsigned long b = state[1]; + unsigned long c = state[2]; + unsigned long d = state[3]; + unsigned long x[16]; + + decode(x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information */ + memset(x, 0, sizeof (x)); +} + +/* MD5 initialization. Begins an MD5 operation, writing a new context. */ +void fz_md5init(fz_md5 *context) +{ + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest operation, + * processing another message block, and updating the context. + */ +void fz_md5update(fz_md5 *context, unsigned char *input, unsigned inlen) +{ + unsigned i, index, partlen; + + /* Compute number of bytes mod 64 */ + index = (unsigned)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + context->count[0] += (unsigned long) inlen << 3; + if (context->count[0] < (unsigned long) inlen << 3) + context->count[1] ++; + context->count[1] += (unsigned long) inlen >> 29; + + partlen = 64 - index; + + /* Transform as many times as possible. */ + if (inlen >= partlen) { + memcpy(context->buffer + index, input, partlen); + transform(context->state, context->buffer); + + for (i = partlen; i + 63 < inlen; i += 64) + transform(context->state, input + i); + + index = 0; + } + else { + i = 0; + } + + /* Buffer remaining input */ + memcpy(context->buffer + index, input + i, inlen - i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + * the message digest and zeroizing the context. + */ +void fz_md5final(fz_md5 *context, unsigned char digest[16]) +{ + unsigned char bits[8]; + unsigned index, padlen; + + /* Save number of bits */ + encode(bits, context->count, 8); + + /* Pad out to 56 mod 64 */ + index = (unsigned)((context->count[0] >> 3) & 0x3f); + padlen = index < 56 ? 56 - index : 120 - index; + fz_md5update(context, padding, padlen); + + /* Append length (before padding) */ + fz_md5update(context, bits, 8); + + /* Store state in digest */ + encode(digest, context->state, 16); + + /* Zeroize sensitive information */ + memset(context, 0, sizeof(fz_md5)); +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_a85d.c b/rosapps/smartpdf/fitz/stream/filt_a85d.c new file mode 100644 index 00000000000..3db4951a18a --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_a85d.c @@ -0,0 +1,129 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +typedef struct fz_a85d_s fz_a85d; + +struct fz_a85d_s +{ + fz_filter super; + unsigned long word; + int count; +}; + +static inline int iswhite(int a) +{ + switch (a) { + case '\n': case '\r': case '\t': case ' ': + case '\0': case '\f': case '\b': case 0177: + return 1; + } + return 0; +} + +fz_error * +fz_newa85d(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_a85d, f, a85d); + f->word = 0; + f->count = 0; + return nil; +} + +void +fz_dropa85d(fz_filter *f) +{ +} + +fz_error * +fz_processa85d(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_a85d *f = (fz_a85d*)filter; + int c; + + while (1) + { + if (in->rp == in->wp) + return fz_ioneedin; + + c = *in->rp++; + + if (c >= '!' && c <= 'u') { + if (f->count == 4) { + if (out->wp + 4 > out->ep) { + in->rp --; + return fz_ioneedout; + } + + f->word = f->word * 85 + (c - '!'); + + *out->wp++ = (f->word >> 24) & 0xff; + *out->wp++ = (f->word >> 16) & 0xff; + *out->wp++ = (f->word >> 8) & 0xff; + *out->wp++ = (f->word) & 0xff; + + f->word = 0; + f->count = 0; + } + else { + f->word = f->word * 85 + (c - '!'); + f->count ++; + } + } + + else if (c == 'z' && f->count == 0) { + if (out->wp + 4 > out->ep) { + in->rp --; + return fz_ioneedout; + } + *out->wp++ = 0; + *out->wp++ = 0; + *out->wp++ = 0; + *out->wp++ = 0; + } + + else if (c == '~') { + if (in->rp == in->wp) { + in->rp --; + return fz_ioneedin; + } + + c = *in->rp++; + + if (c != '>') { + return fz_throw("ioerror: bad eod marker in a85d"); + } + + if (out->wp + f->count - 1 > out->ep) { + in->rp -= 2; + return fz_ioneedout; + } + + switch (f->count) { + case 0: + break; + case 1: + return fz_throw("ioerror: partial final byte in a85d"); + case 2: + f->word = f->word * (85L * 85 * 85) + 0xffffffL; + goto o1; + case 3: + f->word = f->word * (85L * 85) + 0xffffL; + goto o2; + case 4: + f->word = f->word * 85 + 0xffL; + *(out->wp+2) = f->word >> 8; +o2: *(out->wp+1) = f->word >> 16; +o1: *(out->wp+0) = f->word >> 24; + out->wp += f->count - 1; + break; + } + out->eof = 1; + return fz_iodone; + } + + else if (!iswhite(c)) { + return fz_throw("ioerror: bad data in a85d: '%c'", c); + } + } +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_a85e.c b/rosapps/smartpdf/fitz/stream/filt_a85e.c new file mode 100644 index 00000000000..357bd4deae5 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_a85e.c @@ -0,0 +1,128 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +typedef struct fz_a85e_s fz_a85e; + +struct fz_a85e_s +{ + fz_filter super; + int c; +}; + +fz_error * +fz_newa85e(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_a85e, f, a85e); + f->c = 0; + return nil; +} + +void +fz_dropa85e(fz_filter *f) +{ +} + +fz_error * +fz_processa85e(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_a85e *f = (fz_a85e*)filter; + unsigned long word; + int count; + int n; + + n = 0; + + while (1) + { + if (f->c >= 70) { + if (out->wp + 1 > out->ep) + return fz_ioneedout; + *out->wp++ = '\n'; + f->c = 0; + n ++; + } + + if (in->rp + 4 <= in->wp) + { + word = (in->rp[0] << 24) | + (in->rp[1] << 16) | + (in->rp[2] << 8) | + (in->rp[3]); + if (word == 0) { + if (out->wp + 1 > out->ep) + return fz_ioneedout; + *out->wp++ = 'z'; + f->c ++; + n ++; + } + else { + unsigned long v1, v2, v3, v4; + + if (out->wp + 5 > out->ep) + return fz_ioneedout; + + v4 = word / 85; + v3 = v4 / 85; + v2 = v3 / 85; + v1 = v2 / 85; + + *out->wp++ = (v1 % 85) + '!'; + *out->wp++ = (v2 % 85) + '!'; + *out->wp++ = (v3 % 85) + '!'; + *out->wp++ = (v4 % 85) + '!'; + *out->wp++ = (word % 85) + '!'; + f->c += 5; + n += 5; + } + in->rp += 4; + } + + else if (in->eof) + { + unsigned long divisor; + + if (in->rp == in->wp) + goto needinput; /* handle clean eof here */ + + count = in->wp - in->rp; + + if (out->wp + count + 3 > out->ep) + return fz_ioneedout; + + word = 0; + switch (count) { + case 3: word |= in->rp[2] << 8; + case 2: word |= in->rp[1] << 16; + case 1: word |= in->rp[0] << 24; + } + in->rp += count; + + divisor = 85L * 85 * 85 * 85; + while (count-- >= 0) { + *out->wp++ = ((word / divisor) % 85) + '!'; + divisor /= 85; + } + + *out->wp++ = '~'; + *out->wp++ = '>'; + out->eof = 1; + return fz_iodone; + } + + else { + goto needinput; + } + } + +needinput: + if (in->eof) { + if (out->wp + 2 > out->ep) + return fz_ioneedout; + *out->wp++ = '~'; + *out->wp++ = '>'; + out->eof = 1; + return fz_iodone; + } + return fz_ioneedin; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_ahxd.c b/rosapps/smartpdf/fitz/stream/filt_ahxd.c new file mode 100644 index 00000000000..f54670b2670 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_ahxd.c @@ -0,0 +1,113 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +typedef struct fz_ahxd_s fz_ahxd; + +struct fz_ahxd_s +{ + fz_filter super; + int odd; + int a; +}; + +static inline int iswhite(int a) +{ + switch (a) { + case '\n': case '\r': case '\t': case ' ': + case '\0': case '\f': case '\b': case 0177: + return 1; + } + return 0; +} + +static inline int ishex(int a) +{ + return (a >= 'A' && a <= 'F') || + (a >= 'a' && a <= 'f') || + (a >= '0' && a <= '9'); +} + +static inline int fromhex(int a) +{ + if (a >= 'A' && a <= 'F') + return a - 'A' + 0xA; + if (a >= 'a' && a <= 'f') + return a - 'a' + 0xA; + if (a >= '0' && a <= '9') + return a - '0'; + return 0; +} + +fz_error * +fz_newahxd(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_ahxd, f, ahxd); + f->odd = 0; + f->a = 0; + return nil; +} + +void +fz_dropahxd(fz_filter *f) +{ +} + +fz_error * +fz_processahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_ahxd *f = (fz_ahxd*)filter; + int b, c; + + while (1) + { + if (in->rp == in->wp) + return fz_ioneedin; + + if (out->wp == out->ep) + return fz_ioneedout; + + c = *in->rp++; + + if (ishex(c)) { + if (!f->odd) { + f->a = fromhex(c); + f->odd = 1; + } + else { + b = fromhex(c); + *out->wp++ = (f->a << 4) | b; + f->odd = 0; + } + } + + else if (c == '>') { + if (f->odd) + *out->wp++ = (f->a << 4); + out->eof = 1; + return fz_iodone; + } + + else if (!iswhite(c)) { + return fz_throw("ioerror: bad data in ahxd: '%c'", c); + } + } +} + +void +fz_pushbackahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out, int n) +{ + int k; + + assert(filter->process == fz_processahxd); + assert(out->wp - n >= out->rp); + + k = 0; + while (k < n * 2) { + in->rp --; + if (ishex(*in->rp)) + k ++; + } + + out->wp -= n; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_ahxe.c b/rosapps/smartpdf/fitz/stream/filt_ahxe.c new file mode 100644 index 00000000000..12c8aad04a5 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_ahxe.c @@ -0,0 +1,65 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +typedef struct fz_ahxe_s fz_ahxe; + +struct fz_ahxe_s +{ + fz_filter super; + int c; +}; + +static const char tohex[16] = "0123456789ABCDEF"; + +fz_error * +fz_newahxe(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_ahxe, f, ahxe); + f->c = 0; + return nil; +} + +void +fz_dropahxe(fz_filter *f) +{ +} + +fz_error * +fz_processahxe(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_ahxe *f = (fz_ahxe*)filter; + int a, b, c; + + while (1) + { + if (in->rp == in->wp) + goto needinput; + + if (out->wp + 2 >= out->ep) /* can write 3 bytes from 1 */ + return fz_ioneedout; + + c = *in->rp++; + a = tohex[(c >> 4) & 0x0f]; + b = tohex[c & 0x0f]; + + *out->wp++ = a; + *out->wp++ = b; + + f->c += 2; + if (f->c == 60) { + *out->wp++ = '\n'; + f->c = 0; + } + } + +needinput: + if (in->eof) { + if (out->wp == out->ep) + return fz_ioneedout; + *out->wp++ = '>'; + out->eof = 1; + return fz_iodone; + } + return fz_ioneedin; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_arc4.c b/rosapps/smartpdf/fitz/stream/filt_arc4.c new file mode 100644 index 00000000000..3b3c5957b0d --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_arc4.c @@ -0,0 +1,47 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +typedef struct fz_arc4c_s fz_arc4c; + +struct fz_arc4c_s +{ + fz_filter super; + fz_arc4 arc4; +}; + +fz_error * +fz_newarc4filter(fz_filter **fp, unsigned char *key, unsigned keylen) +{ + FZ_NEWFILTER(fz_arc4c, f, arc4filter); + fz_arc4init(&f->arc4, key, keylen); + return nil; +} + +void +fz_droparc4filter(fz_filter *f) +{ +} + +fz_error * +fz_processarc4filter(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_arc4c *f = (fz_arc4c*)filter; + int n; + + while (1) + { + if (in->rp + 1 > in->wp) { + if (in->eof) + return fz_iodone; + return fz_ioneedin; + } + if (out->wp + 1 > out->ep) + return fz_ioneedout; + + n = MIN(in->wp - in->rp, out->ep - out->wp); + fz_arc4encrypt(&f->arc4, out->wp, in->rp, n); + in->rp += n; + out->wp += n; + } +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_dctc.h b/rosapps/smartpdf/fitz/stream/filt_dctc.h new file mode 100644 index 00000000000..8aa6aeb7613 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_dctc.h @@ -0,0 +1,39 @@ +/* + * Extend libjpegs error handler to use setjmp/longjmp + */ + +#include + +#include + +struct myerrmgr +{ + struct jpeg_error_mgr super; + jmp_buf jb; + char msg[JMSG_LENGTH_MAX]; +}; + +static void myerrexit(j_common_ptr cinfo) +{ + struct myerrmgr *err = (struct myerrmgr *)cinfo->err; + char msgbuf[JMSG_LENGTH_MAX]; + err->super.format_message(cinfo, msgbuf); + strlcpy(err->msg, msgbuf, sizeof err->msg); + longjmp(err->jb, 1); +} + +static void myoutmess(j_common_ptr cinfo) +{ + struct myerrmgr *err = (struct myerrmgr *)cinfo->err; + char msgbuf[JMSG_LENGTH_MAX]; + err->super.format_message(cinfo, msgbuf); + fprintf(stderr, "ioerror: dct: %s", msgbuf); +} + +static void myiniterr(struct myerrmgr *err) +{ + jpeg_std_error(&err->super); + err->super.error_exit = myerrexit; + err->super.output_message = myoutmess; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_dctd.c b/rosapps/smartpdf/fitz/stream/filt_dctd.c new file mode 100644 index 00000000000..38ab3fbff87 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_dctd.c @@ -0,0 +1,220 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +#include "filt_dctc.h" + +typedef struct fz_dctd_s fz_dctd; + +struct mysrcmgr +{ + struct jpeg_source_mgr super; + fz_buffer *buf; + int skip; +}; + +struct fz_dctd_s +{ + fz_filter super; + struct jpeg_decompress_struct cinfo; + struct mysrcmgr src; + struct myerrmgr err; + int colortransform; + int stage; +}; + +static void myinitsource(j_decompress_ptr cinfo) { /* empty */ } +static boolean myfillinput(j_decompress_ptr cinfo) { return FALSE; } +static void mytermsource(j_decompress_ptr cinfo) { /* empty */ } + +static void myskipinput(j_decompress_ptr cinfo, long n) +{ + struct mysrcmgr *src = (struct mysrcmgr *)cinfo->src; + fz_buffer *in = src->buf; + + assert(src->skip == 0); + + in->rp = in->wp - src->super.bytes_in_buffer; + + if (in->rp + n > in->wp) { + src->skip = (in->rp + n) - in->wp; + in->rp = in->wp; + } + else { + src->skip = 0; + in->rp += n; + } + + src->super.bytes_in_buffer = in->wp - in->rp; + src->super.next_input_byte = in->rp; +} + +fz_error * +fz_newdctd(fz_filter **fp, fz_obj *params) +{ + fz_error *err; + fz_obj *obj; + int colortransform; + + FZ_NEWFILTER(fz_dctd, d, dctd); + + colortransform = 1; + + if (params) { + obj = fz_dictgets(params, "ColorTransform"); + if (obj) colortransform = fz_toint(obj); + } + + d->colortransform = colortransform; + d->stage = 0; + + /* setup error callback first thing */ + myiniterr(&d->err); + d->cinfo.err = (struct jpeg_error_mgr*) &d->err; + + if (setjmp(d->err.jb)) { + err = fz_throw("ioerror in dctd: %s", d->err.msg); + fz_free(d); + return err; + } + + /* create decompression object. this zeroes cinfo except for err. */ + jpeg_create_decompress(&d->cinfo); + + /* prepare source manager */ + d->cinfo.src = (struct jpeg_source_mgr *)&d->src; + d->src.super.init_source = myinitsource; + d->src.super.fill_input_buffer = myfillinput; + d->src.super.skip_input_data = myskipinput; + d->src.super.resync_to_restart = jpeg_resync_to_restart; + d->src.super.term_source = mytermsource; + + d->src.super.bytes_in_buffer = 0; + d->src.super.next_input_byte = nil; + d->src.skip = 0; + + /* speed up jpeg decoding a bit */ + d->cinfo.dct_method = JDCT_FASTEST; + d->cinfo.do_fancy_upsampling = FALSE; + + return nil; +} + +void +fz_dropdctd(fz_filter *filter) +{ + fz_dctd *d = (fz_dctd*)filter; + if (setjmp(d->err.jb)) { + fprintf(stderr, "ioerror in dct: jpeg_destroy_decompress: %s", d->err.msg); + return; + } + jpeg_destroy_decompress(&d->cinfo); +} + +fz_error * +fz_processdctd(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_dctd *d = (fz_dctd*)filter; + boolean b; + int i; + int stride; + JSAMPROW scanlines[1]; + + d->src.buf = in; + + /* skip any bytes left over from myskipinput() */ + if (d->src.skip > 0) { + if (in->rp + d->src.skip > in->wp) { + d->src.skip = (in->rp + d->src.skip) - in->wp; + in->rp = in->wp; + goto needinput; + } + else { + in->rp += d->src.skip; + d->src.skip = 0; + } + } + + d->src.super.bytes_in_buffer = in->wp - in->rp; + d->src.super.next_input_byte = in->rp; + + if (setjmp(d->err.jb)) { + return fz_throw("ioerror in dctd: %s", d->err.msg); + } + + switch (d->stage) + { + case 0: + i = jpeg_read_header(&d->cinfo, TRUE); + if (i == JPEG_SUSPENDED) + goto needinput; + + /* FIXME: default value if ColorTransform is not set */ + + if (!d->cinfo.saw_Adobe_marker) { + switch (d->cinfo.num_components) { + case 3: + if (d->colortransform) + d->cinfo.jpeg_color_space = JCS_YCbCr; + else + d->cinfo.jpeg_color_space = JCS_RGB; + break; + case 4: + if (d->colortransform) + d->cinfo.jpeg_color_space = JCS_YCCK; + else + d->cinfo.jpeg_color_space = JCS_CMYK; + break; + } + } + + /* fall through */ + d->stage = 1; + + case 1: + b = jpeg_start_decompress(&d->cinfo); + if (b == FALSE) + goto needinput; + + /* fall through */ + d->stage = 2; + + case 2: + stride = d->cinfo.output_width * d->cinfo.output_components; + + while (d->cinfo.output_scanline < d->cinfo.output_height) + { + if (out->wp + stride > out->ep) + goto needoutput; + + scanlines[0] = out->wp; + + i = jpeg_read_scanlines(&d->cinfo, scanlines, 1); + + if (i == 0) + goto needinput; + + out->wp += stride; + } + + /* fall through */ + d->stage = 3; + + case 3: + b = jpeg_finish_decompress(&d->cinfo); + if (b == FALSE) + goto needinput; + d->stage = 4; + out->eof = 1; + in->rp = in->wp - d->src.super.bytes_in_buffer; + return fz_iodone; + } + +needinput: + in->rp = in->wp - d->src.super.bytes_in_buffer; + return fz_ioneedin; + +needoutput: + in->rp = in->wp - d->src.super.bytes_in_buffer; + return fz_ioneedout; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_dcte.c b/rosapps/smartpdf/fitz/stream/filt_dcte.c new file mode 100644 index 00000000000..06f3fcbefb7 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_dcte.c @@ -0,0 +1,253 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +#include "filt_dctc.h" + +typedef struct fz_dcte_s fz_dcte; + +struct mydstmgr +{ + struct jpeg_destination_mgr super; + fz_buffer *buf; +}; + +struct fz_dcte_s +{ + fz_filter super; + + struct jpeg_compress_struct cinfo; + struct mydstmgr dst; + struct myerrmgr err; + int stage; + + int columns; + int rows; + int colors; +}; + +static void myinitdest(j_compress_ptr cinfo) { /* empty */ } +static boolean myemptybuf(j_compress_ptr cinfo) { return FALSE; } +static void mytermdest(j_compress_ptr cinfo) { /* empty */ } + +fz_error * +fz_newdcte(fz_filter **fp, fz_obj *params) +{ + fz_error *err; + fz_obj *obj; + int i; + + FZ_NEWFILTER(fz_dcte, e, dcte); + + e->stage = 0; + + obj = fz_dictgets(params, "Columns"); + if (!obj) { fz_free(e); return fz_throw("ioerror in dcte: missing Columns parameter"); } + e->columns = fz_toint(obj); + + obj = fz_dictgets(params, "Rows"); + if (!obj) { fz_free(e); return fz_throw("ioerror in dcte: missing Rows parameter"); } + e->rows = fz_toint(obj); + + obj = fz_dictgets(params, "Colors"); + if (!obj) { fz_free(e); return fz_throw("ioerror in dcte: missing Colors parameter"); } + e->colors = fz_toint(obj); + + /* setup error callback first thing */ + myiniterr(&e->err); + e->cinfo.err = (struct jpeg_error_mgr*) &e->err; + + if (setjmp(e->err.jb)) { + err = fz_throw("ioerror in dcte: %s", e->err.msg); + fz_free(e); + return err; + } + + jpeg_create_compress(&e->cinfo); + + /* prepare destination manager */ + e->cinfo.dest = (struct jpeg_destination_mgr *) &e->dst; + e->dst.super.init_destination = myinitdest; + e->dst.super.empty_output_buffer = myemptybuf; + e->dst.super.term_destination = mytermdest; + + e->dst.super.next_output_byte = nil; + e->dst.super.free_in_buffer = 0; + + /* prepare required encoding options */ + e->cinfo.image_width = e->columns; + e->cinfo.image_height = e->rows; + e->cinfo.input_components = e->colors; + + switch (e->colors) { + case 1: e->cinfo.in_color_space = JCS_GRAYSCALE; break; + case 3: e->cinfo.in_color_space = JCS_RGB; break; + case 4: e->cinfo.in_color_space = JCS_CMYK; break; + default: e->cinfo.in_color_space = JCS_UNKNOWN; break; + } + + jpeg_set_defaults(&e->cinfo); + + /* FIXME check this */ + obj = fz_dictgets(params, "ColorTransform"); + if (obj) { + int colortransform = fz_toint(obj); + if (e->colors == 3 && !colortransform) + jpeg_set_colorspace(&e->cinfo, JCS_RGB); + if (e->colors == 4 && colortransform) + jpeg_set_colorspace(&e->cinfo, JCS_YCCK); + if (e->colors == 4 && !colortransform) + jpeg_set_colorspace(&e->cinfo, JCS_CMYK); + } + + obj = fz_dictgets(params, "HSamples"); + if (obj && fz_isarray(obj)) { + fz_obj *o; + for (i = 0; i < e->colors; i++) { + o = fz_arrayget(obj, i); + e->cinfo.comp_info[i].h_samp_factor = fz_toint(o); + } + } + + obj = fz_dictgets(params, "VSamples"); + if (obj && fz_isarray(obj)) { + fz_obj *o; + for (i = 0; i < e->colors; i++) { + o = fz_arrayget(obj, i); + e->cinfo.comp_info[i].v_samp_factor = fz_toint(o); + } + } + + /* TODO: quant-tables and huffman-tables */ + + return nil; +} + +void +fz_dropdcte(fz_filter *filter) +{ + fz_dcte *e = (fz_dcte*)filter; + + if (setjmp(e->err.jb)) { + fprintf(stderr, "ioerror in dcte: jpeg_destroy_compress: %s", e->err.msg); + return; + } + + jpeg_destroy_compress(&e->cinfo); +} + +/* Adobe says zigzag order. IJG > v6a says natural order. */ +#if JPEG_LIB_VERSION >= 61 +#define unzigzag(x) unzigzagorder[x] +/* zigzag array position of n'th element of natural array order */ +static const unsigned char unzigzagorder[] = +{ + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63 +}; +#else +#define unzigzag(x) (x) +#endif + +fz_error * +fz_setquanttables(fz_dcte *e, unsigned int **qtables, int qfactor) +{ + int i, j; + unsigned int table[64]; + + if (setjmp(e->err.jb)) { + return fz_throw("ioerror in dcte: %s", e->err.msg); + } + + /* TODO: check for duplicate tables */ + + for (i = 0; i < e->colors; i++) { + for (j = 0; j < 64; j++) { + table[j] = unzigzag(qtables[i][j]); + } + jpeg_add_quant_table(&e->cinfo, i, table, qfactor, TRUE); + e->cinfo.comp_info[i].quant_tbl_no = i; + } + + return nil; +} + +fz_error * +fz_processdcte(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_dcte *e = (fz_dcte*)filter; + JSAMPROW scanline[1]; + int stride; + int i; + + e->dst.buf = out; + e->dst.super.free_in_buffer = out->ep - out->wp; + e->dst.super.next_output_byte = out->wp; + + if (setjmp(e->err.jb)) { + return fz_throw("ioerror in dcte: %s", e->err.msg); + } + + switch (e->stage) + { + case 0: + /* must have enough space for markers, typically 600 bytes or so */ + if (out->wp + 1024 > out->ep) + goto needoutput; + + jpeg_start_compress(&e->cinfo, TRUE); + + /* TODO: write Adobe ColorTransform marker */ + + /* fall through */ + e->stage = 1; + + case 1: + stride = e->columns * e->colors; + + while (e->cinfo.next_scanline < e->cinfo.image_height) + { + if (in->rp + stride > in->wp) + goto needinput; + + scanline[0] = in->rp; + + i = jpeg_write_scanlines(&e->cinfo, scanline, 1); + + if (i == 0) + goto needoutput; + + in->rp += stride; + } + + /* fall through */ + e->stage = 2; + + case 2: + /* must have enough space for end markers */ + if (out->wp + 100 > out->ep) + goto needoutput; + + /* finish compress cannot suspend! */ + jpeg_finish_compress(&e->cinfo); + + e->stage = 3; + out->eof = 1; + out->wp = out->ep - e->dst.super.free_in_buffer; + return fz_iodone; + } + +needinput: + out->wp = out->ep - e->dst.super.free_in_buffer; + return fz_ioneedin; + +needoutput: + out->wp = out->ep - e->dst.super.free_in_buffer; + return fz_ioneedout; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_faxc.h b/rosapps/smartpdf/fitz/stream/filt_faxc.h new file mode 100644 index 00000000000..14cae13fa55 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_faxc.h @@ -0,0 +1,125 @@ +/* common bit magic */ + +static inline void +printbits(FILE *f, int code, int nbits) +{ + int n, b; + for (n = nbits - 1; n >= 0; n--) + { + b = (code >> n) & 1; + fprintf(f, "%c", b ? '1' : '0'); + } +} + +static inline int +getbit(const unsigned char *buf, int x) +{ + return ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1; +} + +static inline void +printline(FILE *f, unsigned char *line, int w) +{ + int i; + for (i = 0; i < w; i++) + fprintf(f, "%c", getbit(line, i) ? '#' : '.'); + fprintf(f, "\n"); +} + +static inline int +getrun(const unsigned char *line, int x, int w, int c) +{ + int z; + int b; + + if (x < 0) + x = 0; + + z = x; + while (z < w) + { + b = getbit(line, z); + if (c != b) + break; + z ++; + } + + return z - x; +} + +static inline int +findchanging(const unsigned char *line, int x, int w) +{ + int a, b; + + if (line == 0) + return w; + + if (x == -1) + { + a = 0; + x = 0; + } + else + { + a = getbit(line, x); + x++; + } + + while (x < w) + { + b = getbit(line, x); + if (a != b) + break; + x++; + } + + return x; +} + +static inline int +findchangingcolor(const unsigned char *line, int x, int w, int color) +{ + if (line == 0) + return w; + + x = findchanging(line, x, w); + + if (x < w && getbit(line, x) != color) + x = findchanging(line, x, w); + + return x; +} + +static const unsigned char lm[8] = + { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 }; + +static const unsigned char rm[8] = + { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; + +static inline void +setbits(unsigned char *line, int x0, int x1) +{ + int a0, a1, b0, b1, a; + + a0 = x0 >> 3; + a1 = x1 >> 3; + + b0 = x0 & 7; + b1 = x1 & 7; + + if (a0 == a1) + { + if (b1) + line[a0] |= lm[b0] & rm[b1]; + } + else + { + line[a0] |= lm[b0]; + for (a = a0 + 1; a < a1; a++) + line[a] = 0xFF; + if (b1) + line[a1] |= rm[b1]; + } +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_faxd.c b/rosapps/smartpdf/fitz/stream/filt_faxd.c new file mode 100644 index 00000000000..45f9d556c71 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_faxd.c @@ -0,0 +1,442 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +#include "filt_faxd.h" +#include "filt_faxc.h" + +enum +{ + SNORMAL, /* neutral state, waiting for any code */ + SMAKEUP, /* got a 1d makeup code, waiting for terminating code */ + SEOL, /* at eol, needs output buffer space */ + SH1, SH2 /* in H part 1 and 2 (both makeup and terminating codes) */ +}; + +/* TODO: uncompressed */ + +typedef struct fz_faxd_s fz_faxd; + +struct fz_faxd_s +{ + fz_filter super; + + int k; + int endofline; + int encodedbytealign; + int columns; + int rows; + int endofblock; + int blackis1; + + int stride; + int ridx; + + int bidx; + unsigned int word; + + int stage, a, c, dim, eolc; + unsigned char *ref; + unsigned char *dst; +}; + +fz_error * +fz_newfaxd(fz_filter **fp, fz_obj *params) +{ + fz_obj *obj; + + FZ_NEWFILTER(fz_faxd, fax, faxd); + + fax->ref = nil; + fax->dst = nil; + + fax->k = 0; + fax->endofline = 0; + fax->encodedbytealign = 0; + fax->columns = 1728; + fax->rows = 0; + fax->endofblock = 1; + fax->blackis1 = 0; + + obj = fz_dictgets(params, "K"); + if (obj) fax->k = fz_toint(obj); + + obj = fz_dictgets(params, "EndOfLine"); + if (obj) fax->endofline = fz_tobool(obj); + + obj = fz_dictgets(params, "EncodedByteAlign"); + if (obj) fax->encodedbytealign = fz_tobool(obj); + + obj = fz_dictgets(params, "Columns"); + if (obj) fax->columns = fz_toint(obj); + + obj = fz_dictgets(params, "Rows"); + if (obj) fax->rows = fz_toint(obj); + + obj = fz_dictgets(params, "EndOfBlock"); + if (obj) fax->endofblock = fz_tobool(obj); + + obj = fz_dictgets(params, "BlackIs1"); + if (obj) fax->blackis1 = fz_tobool(obj); + + fax->stride = ((fax->columns - 1) >> 3) + 1; + fax->ridx = 0; + fax->bidx = 32; + fax->word = 0; + + fax->stage = SNORMAL; + fax->a = -1; + fax->c = 0; + fax->dim = fax->k < 0 ? 2 : 1; + fax->eolc = 0; + + fax->ref = fz_malloc(fax->stride); + if (!fax->ref) { fz_free(fax); return fz_outofmem; } + + fax->dst = fz_malloc(fax->stride); + if (!fax->dst) { fz_free(fax); fz_free(fax->ref); return fz_outofmem; } + + memset(fax->ref, 0, fax->stride); + memset(fax->dst, 0, fax->stride); + + return nil; +} + +void +fz_dropfaxd(fz_filter *p) +{ + fz_faxd *fax = (fz_faxd*) p; + fz_free(fax->ref); + fz_free(fax->dst); +} + +static inline void eatbits(fz_faxd *fax, int nbits) +{ + fax->word <<= nbits; + fax->bidx += nbits; +} + +static inline fz_error * fillbits(fz_faxd *fax, fz_buffer *in) +{ + while (fax->bidx >= 8) + { + if (in->rp + 1 > in->wp) + return fz_ioneedin; + fax->bidx -= 8; + fax->word |= *in->rp << fax->bidx; + in->rp ++; + } + return nil; +} + +static int +getcode(fz_faxd *fax, const cfd_node *table, int initialbits) +{ + unsigned int word = fax->word; + int tidx = word >> (32 - initialbits); + int val = table[tidx].val; + int nbits = table[tidx].nbits; + + if (nbits > initialbits) + { + int mask = (1 << (32 - initialbits)) - 1; + tidx = val + ((word & mask) >> (32 - nbits)); + val = table[tidx].val; + nbits = initialbits + table[tidx].nbits; + } + + eatbits(fax, nbits); + + return val; +} + +/* decode one 1d code */ +static fz_error * +dec1d(fz_faxd *fax) +{ + int code; + + if (fax->a == -1) + fax->a = 0; + + if (fax->c) + code = getcode(fax, cf_black_decode, cfd_black_initial_bits); + else + code = getcode(fax, cf_white_decode, cfd_white_initial_bits); + + if (code == UNCOMPRESSED) + return fz_throw("ioerror: uncompressed data in faxd"); + + if (code < 0) + return fz_throw("ioerror: negative code in 1d faxd"); + + if (fax->a + code > fax->columns) + return fz_throw("ioerror: overflow in 1d faxd"); + + if (fax->c) + setbits(fax->dst, fax->a, fax->a + code); + + fax->a += code; + + if (code < 64) + { + fax->c = !fax->c; + fax->stage = SNORMAL; + } + else + fax->stage = SMAKEUP; + + return nil; +} + +/* decode one 2d code */ +static fz_error * +dec2d(fz_faxd *fax) +{ + int code, b1, b2; + + if (fax->stage == SH1 || fax->stage == SH2) + { + if (fax->a == -1) + fax->a = 0; + + if (fax->c) + code = getcode(fax, cf_black_decode, cfd_black_initial_bits); + else + code = getcode(fax, cf_white_decode, cfd_white_initial_bits); + + if (code == UNCOMPRESSED) + return fz_throw("ioerror: uncompressed data in faxd"); + + if (code < 0) + return fz_throw("ioerror: negative code in 2d faxd"); + + if (fax->a + code > fax->columns) + return fz_throw("ioerror: overflow in 2d faxd"); + + if (fax->c) + setbits(fax->dst, fax->a, fax->a + code); + + fax->a += code; + + if (code < 64) + { + fax->c = !fax->c; + if (fax->stage == SH1) + fax->stage = SH2; + else if (fax->stage == SH2) + fax->stage = SNORMAL; + } + + return nil; + } + + code = getcode(fax, cf_2d_decode, cfd_2d_initial_bits); + + switch (code) + { + case H: + fax->stage = SH1; + break; + + case P: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + b2 = findchanging(fax->ref, b1, fax->columns); + if (fax->c) setbits(fax->dst, fax->a, b2); + fax->a = b2; + break; + + case V0: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + if (fax->c) setbits(fax->dst, fax->a, b1); + fax->a = b1; + fax->c = !fax->c; + break; + + case VR1: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + if (fax->c) setbits(fax->dst, fax->a, b1 + 1); + fax->a = b1 + 1; + fax->c = !fax->c; + break; + + case VR2: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + if (fax->c) setbits(fax->dst, fax->a, b1 + 2); + fax->a = b1 + 2; + fax->c = !fax->c; + break; + + case VR3: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + if (fax->c) setbits(fax->dst, fax->a, b1 + 3); + fax->a = b1 + 3; + fax->c = !fax->c; + break; + + case VL1: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + if (fax->c) setbits(fax->dst, fax->a, b1 - 1); + fax->a = b1 - 1; + fax->c = !fax->c; + break; + + case VL2: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + if (fax->c) setbits(fax->dst, fax->a, b1 - 2); + fax->a = b1 - 2; + fax->c = !fax->c; + break; + + case VL3: + b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c); + if (fax->c) setbits(fax->dst, fax->a, b1 - 3); + fax->a = b1 - 3; + fax->c = !fax->c; + break; + + case UNCOMPRESSED: + return fz_throw("ioerror: uncompressed data in faxd"); + + case ERROR: + return fz_throw("ioerror: invalid code in 2d faxd"); + + default: + return fz_throw("ioerror: invalid code in 2d faxd (%d)", code); + } + + return 0; +} + +fz_error * +fz_processfaxd(fz_filter *f, fz_buffer *in, fz_buffer *out) +{ + fz_faxd *fax = (fz_faxd*)f; + fz_error *error; + int i; + + if (fax->stage == SEOL) + goto eol; + +loop: + + if (fillbits(fax, in)) + { + if (in->eof) + { + if (fax->bidx > 31) + { + if (fax->a > 0) + goto eol; + goto rtc; + } + } + else + { + return fz_ioneedin; + } + } + + if ((fax->word >> (32 - 12)) == 0) + { + eatbits(fax, 1); + goto loop; + } + + if ((fax->word >> (32 - 12)) == 1) + { + eatbits(fax, 12); + fax->eolc ++; + + if (fax->k > 0) + { + if ((fax->word >> (32 - 1)) == 1) + fax->dim = 1; + else + fax->dim = 2; + eatbits(fax, 1); + } + } + else if (fax->dim == 1) + { + fax->eolc = 0; + error = dec1d(fax); + if (error) return error; + + } + else if (fax->dim == 2) + { + fax->eolc = 0; + error = dec2d(fax); + if (error) return error; + } + + /* no eol check after makeup codes nor in the middle of an H code */ + if (fax->stage == SMAKEUP || fax->stage == SH1 || fax->stage == SH2) + goto loop; + + /* check for eol conditions */ + if (fax->eolc || fax->a >= fax->columns) + { + if (fax->a > 0) + goto eol; + if (fax->eolc == (fax->k < 0 ? 2 : 6)) + goto rtc; + } + + goto loop; + +eol: + fax->stage = SEOL; + if (out->wp + fax->stride > out->ep) + return fz_ioneedout; + + if (fax->blackis1) + memcpy(out->wp, fax->dst, fax->stride); + else + for (i = 0; i < fax->stride; i++) + out->wp[i] = ~fax->dst[i]; + + memcpy(fax->ref, fax->dst, fax->stride); + memset(fax->dst, 0, fax->stride); + out->wp += fax->stride; + + fax->stage = SNORMAL; + fax->c = 0; + fax->a = -1; + fax->ridx ++; + + if (!fax->endofblock && fax->rows) + { + if (fax->ridx >= fax->rows) + goto rtc; + } + + /* we have not read dim from eol, make a guess */ + if (fax->k > 0 && !fax->eolc) + { + if (fax->ridx % fax->k == 0) + fax->dim = 1; + else + fax->dim = 2; + } + + /* if endofline & encodedbytealign, EOLs are *not* optional */ + if (fax->encodedbytealign) + { + if (fax->endofline) + eatbits(fax, (12 - fax->bidx) & 7); + else + eatbits(fax, (8 - fax->bidx) & 7); + } + + goto loop; + +rtc: + i = (32 - fax->bidx) / 8; + while (i-- && in->rp > in->bp) + in->rp --; + + out->eof = 1; + return fz_iodone; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_faxd.h b/rosapps/smartpdf/fitz/stream/filt_faxd.h new file mode 100644 index 00000000000..9f3fb470fb2 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_faxd.h @@ -0,0 +1,61 @@ +/* Fax G3/G4 tables */ + +/* + the first 2^(initialbits) entries map bit patterns to decodes + let's say initial_bits is 8 for the sake of example + and that the code is 1001 + that means that entries 0x90 .. 0x9f have the entry { val, 4 } + because those are all the bytes that start with the code + and the 4 is the length of the code +... if (n_bits > initial_bits) ... + anyway, in that case, it basically points to a mini table + the n_bits is the maximum length of all codes beginning with that byte + so 2^(n_bits - initial_bits) is the size of the mini-table + peter came up with this, and it makes sense +*/ + +typedef struct cfd_node_s cfd_node; + +struct cfd_node_s +{ + short val; + short nbits; +}; + +enum +{ + cfd_white_initial_bits = 8, + cfd_black_initial_bits = 7, + cfd_2d_initial_bits = 7, + cfd_uncompressed_initial_bits = 6 /* must be 6 */ +}; + +/* non-run codes in tables */ +enum +{ + ERROR = -1, + ZEROS = -2, /* EOL follows, possibly with more padding first */ + UNCOMPRESSED = -3 +}; + +/* semantic codes for cf_2d_decode */ +enum +{ + P = -4, + H = -5, + VR3 = 0, + VR2 = 1, + VR1 = 2, + V0 = 3, + VL1 = 4, + VL2 = 5, + VL3 = 6 +}; + +/* Decoding tables */ + +extern const cfd_node cf_white_decode[]; +extern const cfd_node cf_black_decode[]; +extern const cfd_node cf_2d_decode[]; +extern const cfd_node cf_uncompressed_decode[]; + diff --git a/rosapps/smartpdf/fitz/stream/filt_faxdtab.c b/rosapps/smartpdf/fitz/stream/filt_faxdtab.c new file mode 100644 index 00000000000..6efcf05337c --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_faxdtab.c @@ -0,0 +1,931 @@ +/* Tables for CCITTFaxDecode filter. */ + +/* This file was generated automatically. It is governed by the same terms */ +/* as the files scfetab.c and scfdgen.c from which it was derived. */ +/* Consult those files for the licensing terms and conditions. */ + +#include "filt_faxd.h" + +/* White decoding table. */ +const cfd_node cf_white_decode[] = { + { 256, 12 }, + { 272, 12 }, + { 29, 8 }, + { 30, 8 }, + { 45, 8 }, + { 46, 8 }, + { 22, 7 }, + { 22, 7 }, + { 23, 7 }, + { 23, 7 }, + { 47, 8 }, + { 48, 8 }, + { 13, 6 }, + { 13, 6 }, + { 13, 6 }, + { 13, 6 }, + { 20, 7 }, + { 20, 7 }, + { 33, 8 }, + { 34, 8 }, + { 35, 8 }, + { 36, 8 }, + { 37, 8 }, + { 38, 8 }, + { 19, 7 }, + { 19, 7 }, + { 31, 8 }, + { 32, 8 }, + { 1, 6 }, + { 1, 6 }, + { 1, 6 }, + { 1, 6 }, + { 12, 6 }, + { 12, 6 }, + { 12, 6 }, + { 12, 6 }, + { 53, 8 }, + { 54, 8 }, + { 26, 7 }, + { 26, 7 }, + { 39, 8 }, + { 40, 8 }, + { 41, 8 }, + { 42, 8 }, + { 43, 8 }, + { 44, 8 }, + { 21, 7 }, + { 21, 7 }, + { 28, 7 }, + { 28, 7 }, + { 61, 8 }, + { 62, 8 }, + { 63, 8 }, + { 0, 8 }, + { 320, 8 }, + { 384, 8 }, + { 10, 5 }, + { 10, 5 }, + { 10, 5 }, + { 10, 5 }, + { 10, 5 }, + { 10, 5 }, + { 10, 5 }, + { 10, 5 }, + { 11, 5 }, + { 11, 5 }, + { 11, 5 }, + { 11, 5 }, + { 11, 5 }, + { 11, 5 }, + { 11, 5 }, + { 11, 5 }, + { 27, 7 }, + { 27, 7 }, + { 59, 8 }, + { 60, 8 }, + { 288, 9 }, + { 290, 9 }, + { 18, 7 }, + { 18, 7 }, + { 24, 7 }, + { 24, 7 }, + { 49, 8 }, + { 50, 8 }, + { 51, 8 }, + { 52, 8 }, + { 25, 7 }, + { 25, 7 }, + { 55, 8 }, + { 56, 8 }, + { 57, 8 }, + { 58, 8 }, + { 192, 6 }, + { 192, 6 }, + { 192, 6 }, + { 192, 6 }, + { 1664, 6 }, + { 1664, 6 }, + { 1664, 6 }, + { 1664, 6 }, + { 448, 8 }, + { 512, 8 }, + { 292, 9 }, + { 640, 8 }, + { 576, 8 }, + { 294, 9 }, + { 296, 9 }, + { 298, 9 }, + { 300, 9 }, + { 302, 9 }, + { 256, 7 }, + { 256, 7 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 2, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 128, 5 }, + { 128, 5 }, + { 128, 5 }, + { 128, 5 }, + { 128, 5 }, + { 128, 5 }, + { 128, 5 }, + { 128, 5 }, + { 8, 5 }, + { 8, 5 }, + { 8, 5 }, + { 8, 5 }, + { 8, 5 }, + { 8, 5 }, + { 8, 5 }, + { 8, 5 }, + { 9, 5 }, + { 9, 5 }, + { 9, 5 }, + { 9, 5 }, + { 9, 5 }, + { 9, 5 }, + { 9, 5 }, + { 9, 5 }, + { 16, 6 }, + { 16, 6 }, + { 16, 6 }, + { 16, 6 }, + { 17, 6 }, + { 17, 6 }, + { 17, 6 }, + { 17, 6 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 14, 6 }, + { 14, 6 }, + { 14, 6 }, + { 14, 6 }, + { 15, 6 }, + { 15, 6 }, + { 15, 6 }, + { 15, 6 }, + { 64, 5 }, + { 64, 5 }, + { 64, 5 }, + { 64, 5 }, + { 64, 5 }, + { 64, 5 }, + { 64, 5 }, + { 64, 5 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { 7, 4 }, + { -2, 3 }, + { -2, 3 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -3, 4 }, + { 1792, 3 }, + { 1792, 3 }, + { 1984, 4 }, + { 2048, 4 }, + { 2112, 4 }, + { 2176, 4 }, + { 2240, 4 }, + { 2304, 4 }, + { 1856, 3 }, + { 1856, 3 }, + { 1920, 3 }, + { 1920, 3 }, + { 2368, 4 }, + { 2432, 4 }, + { 2496, 4 }, + { 2560, 4 }, + { 1472, 1 }, + { 1536, 1 }, + { 1600, 1 }, + { 1728, 1 }, + { 704, 1 }, + { 768, 1 }, + { 832, 1 }, + { 896, 1 }, + { 960, 1 }, + { 1024, 1 }, + { 1088, 1 }, + { 1152, 1 }, + { 1216, 1 }, + { 1280, 1 }, + { 1344, 1 }, + { 1408, 1 } +}; + +/* Black decoding table. */ +const cfd_node cf_black_decode[] = { + { 128, 12 }, + { 160, 13 }, + { 224, 12 }, + { 256, 12 }, + { 10, 7 }, + { 11, 7 }, + { 288, 12 }, + { 12, 7 }, + { 9, 6 }, + { 9, 6 }, + { 8, 6 }, + { 8, 6 }, + { 7, 5 }, + { 7, 5 }, + { 7, 5 }, + { 7, 5 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 6, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 1, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 3, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { 2, 2 }, + { -2, 4 }, + { -2, 4 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -3, 5 }, + { 1792, 4 }, + { 1792, 4 }, + { 1984, 5 }, + { 2048, 5 }, + { 2112, 5 }, + { 2176, 5 }, + { 2240, 5 }, + { 2304, 5 }, + { 1856, 4 }, + { 1856, 4 }, + { 1920, 4 }, + { 1920, 4 }, + { 2368, 5 }, + { 2432, 5 }, + { 2496, 5 }, + { 2560, 5 }, + { 18, 3 }, + { 18, 3 }, + { 18, 3 }, + { 18, 3 }, + { 18, 3 }, + { 18, 3 }, + { 18, 3 }, + { 18, 3 }, + { 52, 5 }, + { 52, 5 }, + { 640, 6 }, + { 704, 6 }, + { 768, 6 }, + { 832, 6 }, + { 55, 5 }, + { 55, 5 }, + { 56, 5 }, + { 56, 5 }, + { 1280, 6 }, + { 1344, 6 }, + { 1408, 6 }, + { 1472, 6 }, + { 59, 5 }, + { 59, 5 }, + { 60, 5 }, + { 60, 5 }, + { 1536, 6 }, + { 1600, 6 }, + { 24, 4 }, + { 24, 4 }, + { 24, 4 }, + { 24, 4 }, + { 25, 4 }, + { 25, 4 }, + { 25, 4 }, + { 25, 4 }, + { 1664, 6 }, + { 1728, 6 }, + { 320, 5 }, + { 320, 5 }, + { 384, 5 }, + { 384, 5 }, + { 448, 5 }, + { 448, 5 }, + { 512, 6 }, + { 576, 6 }, + { 53, 5 }, + { 53, 5 }, + { 54, 5 }, + { 54, 5 }, + { 896, 6 }, + { 960, 6 }, + { 1024, 6 }, + { 1088, 6 }, + { 1152, 6 }, + { 1216, 6 }, + { 64, 3 }, + { 64, 3 }, + { 64, 3 }, + { 64, 3 }, + { 64, 3 }, + { 64, 3 }, + { 64, 3 }, + { 64, 3 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 13, 1 }, + { 23, 4 }, + { 23, 4 }, + { 50, 5 }, + { 51, 5 }, + { 44, 5 }, + { 45, 5 }, + { 46, 5 }, + { 47, 5 }, + { 57, 5 }, + { 58, 5 }, + { 61, 5 }, + { 256, 5 }, + { 16, 3 }, + { 16, 3 }, + { 16, 3 }, + { 16, 3 }, + { 17, 3 }, + { 17, 3 }, + { 17, 3 }, + { 17, 3 }, + { 48, 5 }, + { 49, 5 }, + { 62, 5 }, + { 63, 5 }, + { 30, 5 }, + { 31, 5 }, + { 32, 5 }, + { 33, 5 }, + { 40, 5 }, + { 41, 5 }, + { 22, 4 }, + { 22, 4 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 14, 1 }, + { 15, 2 }, + { 15, 2 }, + { 15, 2 }, + { 15, 2 }, + { 15, 2 }, + { 15, 2 }, + { 15, 2 }, + { 15, 2 }, + { 128, 5 }, + { 192, 5 }, + { 26, 5 }, + { 27, 5 }, + { 28, 5 }, + { 29, 5 }, + { 19, 4 }, + { 19, 4 }, + { 20, 4 }, + { 20, 4 }, + { 34, 5 }, + { 35, 5 }, + { 36, 5 }, + { 37, 5 }, + { 38, 5 }, + { 39, 5 }, + { 21, 4 }, + { 21, 4 }, + { 42, 5 }, + { 43, 5 }, + { 0, 3 }, + { 0, 3 }, + { 0, 3 }, + { 0, 3 } +}; + +/* 2-D decoding table. */ +const cfd_node cf_2d_decode[] = { + { 128, 11 }, + { 144, 10 }, + { 6, 7 }, + { 0, 7 }, + { 5, 6 }, + { 5, 6 }, + { 1, 6 }, + { 1, 6 }, + { -4, 4 }, + { -4, 4 }, + { -4, 4 }, + { -4, 4 }, + { -4, 4 }, + { -4, 4 }, + { -4, 4 }, + { -4, 4 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { -5, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 4, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { 3, 1 }, + { -2, 4 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -1, 0 }, + { -3, 3 } +}; + +/* Uncompresssed decoding table. */ +const cfd_node cf_uncompressed_decode[] = { + { 64, 12 }, + { 5, 6 }, + { 4, 5 }, + { 4, 5 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 3, 4 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { 0, 1 }, + { -1, 0 }, + { -1, 0 }, + { 8, 6 }, + { 9, 6 }, + { 6, 5 }, + { 6, 5 }, + { 7, 5 }, + { 7, 5 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 4, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 5, 4 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 2, 3 }, + { 3, 3 }, + { 3, 3 }, + { 3, 3 }, + { 3, 3 }, + { 3, 3 }, + { 3, 3 }, + { 3, 3 }, + { 3, 3 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 0, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 }, + { 1, 2 } +}; + +/* Dummy executable code to pacify compilers. */ +void scfdtab_dummy(void) { } + diff --git a/rosapps/smartpdf/fitz/stream/filt_faxe.c b/rosapps/smartpdf/fitz/stream/filt_faxe.c new file mode 100644 index 00000000000..97c16c0dc43 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_faxe.c @@ -0,0 +1,399 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +#include "filt_faxe.h" +#include "filt_faxc.h" + +/* TODO: honor Rows param */ + +typedef struct fz_faxe_s fz_faxe; + +struct fz_faxe_s +{ + fz_filter super; + + int k; + int endofline; + int encodedbytealign; + int columns; + int endofblock; + int blackis1; + + int stride; + int ridx; /* how many rows in total */ + int bidx; /* how many bits are already used in out->wp */ + unsigned char bsave; /* partial byte saved between process() calls */ + + int stage; + int a0, c; /* mid-line coding state */ + + unsigned char *ref; + unsigned char *src; +}; + +fz_error * +fz_newfaxe(fz_filter **fp, fz_obj *params) +{ + fz_obj *obj; + + FZ_NEWFILTER(fz_faxe, fax, faxe); + + fax->ref = nil; + fax->src = nil; + + fax->k = 0; + fax->endofline = 0; + fax->encodedbytealign = 0; + fax->columns = 1728; + fax->endofblock = 1; + fax->blackis1 = 0; + + obj = fz_dictgets(params, "K"); + if (obj) fax->k = fz_toint(obj); + + obj = fz_dictgets(params, "EndOfLine"); + if (obj) fax->endofline = fz_tobool(obj); + + obj = fz_dictgets(params, "EncodedByteAlign"); + if (obj) fax->encodedbytealign = fz_tobool(obj); + + obj = fz_dictgets(params, "Columns"); + if (obj) fax->columns = fz_toint(obj); + + obj = fz_dictgets(params, "EndOfBlock"); + if (obj) fax->endofblock = fz_tobool(obj); + + obj = fz_dictgets(params, "BlackIs1"); + if (obj) fax->blackis1 = fz_tobool(obj); + + fax->stride = ((fax->columns - 1) >> 3) + 1; + fax->bidx = 0; + fax->ridx = 0; + + fax->stage = 0; + fax->a0 = -1; + fax->c = 0; + + fax->ref = fz_malloc(fax->stride); + if (!fax->ref) { fz_free(fax); return fz_outofmem; } + + fax->src = fz_malloc(fax->stride); + if (!fax->src) { fz_free(fax); fz_free(fax->ref); return fz_outofmem; } + + memset(fax->ref, 0, fax->stride); + memset(fax->src, 0, fax->stride); + + return nil; +} + +void +fz_dropfaxe(fz_filter *p) +{ + fz_faxe *fax = (fz_faxe*) p; + fz_free(fax->src); + fz_free(fax->ref); +} + +enum { codebytes = 2 }; + +static inline int runbytes(int run) +{ + int m = (run / 64) / 40 + 1; /* number of makeup codes */ + return codebytes * (m + 1); /* bytes for makeup + term codes */ +} + +static void +putbits(fz_faxe *fax, fz_buffer *out, int code, int nbits) +{ + while (nbits > 0) + { + if (fax->bidx == 0) + *out->wp = 0; + + /* code does not fit: shift right */ + if (nbits > (8 - fax->bidx)) + { + *out->wp |= code >> (nbits - (8 - fax->bidx)); + nbits = nbits - (8 - fax->bidx); + fax->bidx = 0; + out->wp ++; + } + + /* shift left */ + else + { + *out->wp |= code << ((8 - fax->bidx) - nbits); + fax->bidx += nbits; + if (fax->bidx == 8) + { + fax->bidx = 0; + out->wp ++; + } + nbits = 0; + } + } +} + +static inline void +putcode(fz_faxe *fax, fz_buffer *out, const cfe_code *run) +{ + putbits(fax, out, run->code, run->nbits); +} + +static void +putrun(fz_faxe *fax, fz_buffer *out, int run, int c) +{ + int m; + + const cf_runs *codetable = c ? &cf_black_runs : &cf_white_runs; + + if (run > 63) + { + m = run / 64; + while (m > 40) + { + putcode(fax, out, &codetable->makeup[40]); + m -= 40; + } + if (m > 0) + { + putcode(fax, out, &codetable->makeup[m]); + } + putcode(fax, out, &codetable->termination[run % 64]); + } + else + { + putcode(fax, out, &codetable->termination[run]); + } +} + +static fz_error * +enc1d(fz_faxe *fax, unsigned char *line, fz_buffer *out) +{ + int run; + + if (fax->a0 < 0) + fax->a0 = 0; + + while (fax->a0 < fax->columns) + { + run = getrun(line, fax->a0, fax->columns, fax->c); + + if (out->wp + 1 + runbytes(run) > out->ep) + return fz_ioneedout; + + putrun(fax, out, run, fax->c); + + fax->a0 += run; + fax->c = !fax->c; + } + + return 0; +} + +static fz_error * +enc2d(fz_faxe *fax, unsigned char *ref, unsigned char *src, fz_buffer *out) +{ + int a1, a2, b1, b2; + int run1, run2, n; + + while (fax->a0 < fax->columns) + { + a1 = findchanging(src, fax->a0, fax->columns); + b1 = findchangingcolor(ref, fax->a0, fax->columns, !fax->c); + b2 = findchanging(ref, b1, fax->columns); + + /* pass */ + if (b2 < a1) + { + if (out->wp + 1 + codebytes > out->ep) + return fz_ioneedout; + + putcode(fax, out, &cf2_run_pass); + + fax->a0 = b2; + } + + /* vertical */ + else if (ABS(b1 - a1) <= 3) + { + if (out->wp + 1 + codebytes > out->ep) + return fz_ioneedout; + + putcode(fax, out, &cf2_run_vertical[b1 - a1 + 3]); + + fax->a0 = a1; + fax->c = !fax->c; + } + + /* horizontal */ + else + { + a2 = findchanging(src, a1, fax->columns); + run1 = a1 - fax->a0; + run2 = a2 - a1; + n = codebytes + runbytes(run1) + runbytes(run2); + + if (out->wp + 1 + n > out->ep) + return fz_ioneedout; + + putcode(fax, out, &cf2_run_horizontal); + putrun(fax, out, run1, fax->c); + putrun(fax, out, run2, !fax->c); + + fax->a0 = a2; + } + } + + return 0; +} + +static fz_error * +process(fz_faxe *fax, fz_buffer *in, fz_buffer *out) +{ + fz_error *error; + int i, n; + + while (1) + { + if (in->rp == in->wp && in->eof) + goto rtc; + + switch (fax->stage) + { + case 0: + if (fax->encodedbytealign) + { + if (fax->endofline) + { + if (out->wp + 1 + 1 > out->ep) + return fz_ioneedout; + + /* make sure that EOL ends on a byte border */ + putbits(fax, out, 0, (12 - fax->bidx) & 7); + } + else + { + if (fax->bidx) + { + if (out->wp + 1 > out->ep) + return fz_ioneedout; + fax->bidx = 0; + out->wp ++; + } + } + } + + fax->stage ++; + + case 1: + if (fax->endofline) + { + if (out->wp + 1 + codebytes + 1 > out->ep) + return fz_ioneedout; + + if (fax->k > 0) + { + if (fax->ridx % fax->k == 0) + putcode(fax, out, &cf2_run_eol_1d); + else + putcode(fax, out, &cf2_run_eol_2d); + } + else + { + putcode(fax, out, &cf_run_eol); + } + } + + fax->stage ++; + + case 2: + if (in->rp + fax->stride > in->wp) + { + if (in->eof) /* XXX barf here? */ + goto rtc; + return fz_ioneedin; + } + + memcpy(fax->ref, fax->src, fax->stride); + memcpy(fax->src, in->rp, fax->stride); + + if (!fax->blackis1) + { + for (i = 0; i < fax->stride; i++) + fax->src[i] = ~fax->src[i]; + } + + in->rp += fax->stride; + + fax->c = 0; + fax->a0 = -1; + + fax->stage ++; + + case 3: + error = 0; /* to silence compiler */ + + if (fax->k < 0) + error = enc2d(fax, fax->ref, fax->src, out); + + else if (fax->k == 0) + error = enc1d(fax, fax->src, out); + + else if (fax->k > 0) + { + if (fax->ridx % fax->k == 0) + error = enc1d(fax, fax->src, out); + else + error = enc2d(fax, fax->ref, fax->src, out); + } + + if (error) + return error; + + fax->ridx ++; + + fax->stage = 0; + } + } + +rtc: + if (fax->endofblock) + { + n = fax->k < 0 ? 2 : 6; + + if (out->wp + 1 + codebytes * n > out->ep) + return fz_ioneedout; + + for (i = 0; i < n; i++) + { + putcode(fax, out, &cf_run_eol); + if (fax->k > 0) + putbits(fax, out, 1, 1); + } + } + + if (fax->bidx) + out->wp ++; + out->eof = 1; + + return fz_iodone; +} + +fz_error * +fz_processfaxe(fz_filter *p, fz_buffer *in, fz_buffer *out) +{ + fz_faxe *fax = (fz_faxe*) p; + fz_error *error; + + /* restore partial bits */ + *out->wp = fax->bsave; + + error = process(fax, in, out); + + /* save partial bits */ + fax->bsave = *out->wp; + + return error; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_faxe.h b/rosapps/smartpdf/fitz/stream/filt_faxe.h new file mode 100644 index 00000000000..dd3fc1216a4 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_faxe.h @@ -0,0 +1,37 @@ +/* Fax G3/G4 tables */ + +typedef struct cfe_code_s cfe_code; + +struct cfe_code_s +{ + unsigned short code; + unsigned short nbits; +}; + +typedef struct cf_runs_s { + cfe_code termination[64]; + cfe_code makeup[41]; +} cf_runs; + +/* Encoding tables */ + +/* Codes common to 1-D and 2-D encoding. */ +extern const cfe_code cf_run_eol; +extern const cf_runs cf_white_runs, cf_black_runs; +extern const cfe_code cf_uncompressed[6]; +extern const cfe_code cf_uncompressed_exit[10]; /* indexed by 2 x length of */ + +/* 1-D encoding. */ +extern const cfe_code cf1_run_uncompressed; + +/* 2-D encoding. */ +enum { cf2_run_vertical_offset = 3 }; +extern const cfe_code cf2_run_pass; +extern const cfe_code cf2_run_vertical[7]; /* indexed by b1 - a1 + offset */ +extern const cfe_code cf2_run_horizontal; +extern const cfe_code cf2_run_uncompressed; + +/* 2-D Group 3 encoding. */ +extern const cfe_code cf2_run_eol_1d; +extern const cfe_code cf2_run_eol_2d; + diff --git a/rosapps/smartpdf/fitz/stream/filt_faxetab.c b/rosapps/smartpdf/fitz/stream/filt_faxetab.c new file mode 100644 index 00000000000..34914c2d4d5 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_faxetab.c @@ -0,0 +1,131 @@ +/* Tables for CCITTFaxEncode filter */ + +#include "filt_faxe.h" + +/* Define the end-of-line code. */ +const cfe_code cf_run_eol = {1, 12}; + +/* Define the 1-D code that signals uncompressed data. */ +const cfe_code cf1_run_uncompressed = {0xf, 12}; + +/* Define the 2-D run codes. */ +const cfe_code cf2_run_pass = {0x1, 4}; +const cfe_code cf2_run_vertical[7] = +{ + {0x3, 7}, + {0x3, 6}, + {0x3, 3}, + {0x1, 1}, + {0x2, 3}, + {0x2, 6}, + {0x2, 7} +}; +const cfe_code cf2_run_horizontal = {1, 3}; +const cfe_code cf2_run_uncompressed = {0xf, 10}; + +/* EOL codes for Group 3 2-D. */ +const cfe_code cf2_run_eol_1d = { (1 << 1) + 1, 12 + 1}; +const cfe_code cf2_run_eol_2d = { (1 << 1) + 0, 12 + 1}; + +/* White run codes. */ +const cf_runs cf_white_runs = +{ + /* Termination codes */ + { + {0x35, 8}, {0x7, 6}, {0x7, 4}, {0x8, 4}, + {0xb, 4}, {0xc, 4}, {0xe, 4}, {0xf, 4}, + {0x13, 5}, {0x14, 5}, {0x7, 5}, {0x8, 5}, + {0x8, 6}, {0x3, 6}, {0x34, 6}, {0x35, 6}, + {0x2a, 6}, {0x2b, 6}, {0x27, 7}, {0xc, 7}, + {0x8, 7}, {0x17, 7}, {0x3, 7}, {0x4, 7}, + {0x28, 7}, {0x2b, 7}, {0x13, 7}, {0x24, 7}, + {0x18, 7}, {0x2, 8}, {0x3, 8}, {0x1a, 8}, + {0x1b, 8}, {0x12, 8}, {0x13, 8}, {0x14, 8}, + {0x15, 8}, {0x16, 8}, {0x17, 8}, {0x28, 8}, + {0x29, 8}, {0x2a, 8}, {0x2b, 8}, {0x2c, 8}, + {0x2d, 8}, {0x4, 8}, {0x5, 8}, {0xa, 8}, + {0xb, 8}, {0x52, 8}, {0x53, 8}, {0x54, 8}, + {0x55, 8}, {0x24, 8}, {0x25, 8}, {0x58, 8}, + {0x59, 8}, {0x5a, 8}, {0x5b, 8}, {0x4a, 8}, + {0x4b, 8}, {0x32, 8}, {0x33, 8}, {0x34, 8} + }, + + /* Make-up codes */ + { + {0, 0} /* dummy */ , {0x1b, 5}, {0x12, 5}, {0x17, 6}, + {0x37, 7}, {0x36, 8}, {0x37, 8}, {0x64, 8}, + {0x65, 8}, {0x68, 8}, {0x67, 8}, {0xcc, 9}, + {0xcd, 9}, {0xd2, 9}, {0xd3, 9}, {0xd4, 9}, + {0xd5, 9}, {0xd6, 9}, {0xd7, 9}, {0xd8, 9}, + {0xd9, 9}, {0xda, 9}, {0xdb, 9}, {0x98, 9}, + {0x99, 9}, {0x9a, 9}, {0x18, 6}, {0x9b, 9}, + {0x8, 11}, {0xc, 11}, {0xd, 11}, {0x12, 12}, + {0x13, 12}, {0x14, 12}, {0x15, 12}, {0x16, 12}, + {0x17, 12}, {0x1c, 12}, {0x1d, 12}, {0x1e, 12}, + {0x1f, 12} + } +}; + +/* Black run codes. */ +const cf_runs cf_black_runs = +{ + /* Termination codes */ + { + {0x37, 10}, {0x2, 3}, {0x3, 2}, {0x2, 2}, + {0x3, 3}, {0x3, 4}, {0x2, 4}, {0x3, 5}, + {0x5, 6}, {0x4, 6}, {0x4, 7}, {0x5, 7}, + {0x7, 7}, {0x4, 8}, {0x7, 8}, {0x18, 9}, + {0x17, 10}, {0x18, 10}, {0x8, 10}, {0x67, 11}, + {0x68, 11}, {0x6c, 11}, {0x37, 11}, {0x28, 11}, + {0x17, 11}, {0x18, 11}, {0xca, 12}, {0xcb, 12}, + {0xcc, 12}, {0xcd, 12}, {0x68, 12}, {0x69, 12}, + {0x6a, 12}, {0x6b, 12}, {0xd2, 12}, {0xd3, 12}, + {0xd4, 12}, {0xd5, 12}, {0xd6, 12}, {0xd7, 12}, + {0x6c, 12}, {0x6d, 12}, {0xda, 12}, {0xdb, 12}, + {0x54, 12}, {0x55, 12}, {0x56, 12}, {0x57, 12}, + {0x64, 12}, {0x65, 12}, {0x52, 12}, {0x53, 12}, + {0x24, 12}, {0x37, 12}, {0x38, 12}, {0x27, 12}, + {0x28, 12}, {0x58, 12}, {0x59, 12}, {0x2b, 12}, + {0x2c, 12}, {0x5a, 12}, {0x66, 12}, {0x67, 12} + }, + + /* Make-up codes. */ + { + {0, 0} /* dummy */ , {0xf, 10}, {0xc8, 12}, {0xc9, 12}, + {0x5b, 12}, {0x33, 12}, {0x34, 12}, {0x35, 12}, + {0x6c, 13}, {0x6d, 13}, {0x4a, 13}, {0x4b, 13}, + {0x4c, 13}, {0x4d, 13}, {0x72, 13}, {0x73, 13}, + {0x74, 13}, {0x75, 13}, {0x76, 13}, {0x77, 13}, + {0x52, 13}, {0x53, 13}, {0x54, 13}, {0x55, 13}, + {0x5a, 13}, {0x5b, 13}, {0x64, 13}, {0x65, 13}, + {0x8, 11}, {0xc, 11}, {0xd, 11}, {0x12, 12}, + {0x13, 12}, {0x14, 12}, {0x15, 12}, {0x16, 12}, + {0x17, 12}, {0x1c, 12}, {0x1d, 12}, {0x1e, 12}, + {0x1f, 12} + } +}; + +/* Uncompressed codes. */ +const cfe_code cf_uncompressed[6] = +{ + {1, 1}, + {1, 2}, + {1, 3}, + {1, 4}, + {1, 5}, + {1, 6} +}; + +/* Uncompressed exit codes. */ +const cfe_code cf_uncompressed_exit[10] = +{ + {2, 8}, {3, 8}, + {2, 9}, {3, 9}, + {2, 10}, {3, 10}, + {2, 11}, {3, 11}, + {2, 12}, {3, 12} +}; + +/* Some C compilers insist on having executable code in every file.... */ +void scfetab_dummy(void) { } + diff --git a/rosapps/smartpdf/fitz/stream/filt_flate.c b/rosapps/smartpdf/fitz/stream/filt_flate.c new file mode 100644 index 00000000000..00310172b47 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_flate.c @@ -0,0 +1,211 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +#include + +typedef struct fz_flate_s fz_flate; + +struct fz_flate_s +{ + fz_filter super; + z_stream z; +}; + +static void * +zmalloc(void *opaque, unsigned int items, unsigned int size) +{ + fz_memorycontext *mctx = (fz_memorycontext*)opaque; + return mctx->malloc(mctx, items * size); +} + +fz_error * +fz_newflated(fz_filter **fp, fz_obj *params) +{ + fz_error *eo; + fz_obj *obj; + int zipfmt; + int ei; + + FZ_NEWFILTER(fz_flate, f, flated); + + f->z.zalloc = zmalloc; + f->z.zfree = (void(*)(void*,void*))fz_currentmemorycontext()->free; + f->z.opaque = fz_currentmemorycontext(); + f->z.next_in = nil; + f->z.avail_in = 0; + + zipfmt = 0; + + if (params) + { + obj = fz_dictgets(params, "ZIP"); + if (obj) zipfmt = fz_tobool(obj); + } + + if (zipfmt) + { + /* if windowbits is negative the zlib header is skipped */ + ei = inflateInit2(&f->z, -15); + } + else + ei = inflateInit(&f->z); + + if (ei != Z_OK) + { + eo = fz_throw("ioerror: inflateInit: %s", f->z.msg); + fz_free(f); + return eo; + } + + return nil; +} + +void +fz_dropflated(fz_filter *f) +{ + z_streamp zp = &((fz_flate*)f)->z; + int err; + + err = inflateEnd(zp); + if (err != Z_OK) + fprintf(stderr, "inflateEnd: %s", zp->msg); +} + +fz_error * +fz_processflated(fz_filter *f, fz_buffer *in, fz_buffer *out) +{ + z_streamp zp = &((fz_flate*)f)->z; + int err; + + if (in->rp == in->wp && !in->eof) + return fz_ioneedin; + if (out->wp == out->ep) + return fz_ioneedout; + + zp->next_in = in->rp; + zp->avail_in = in->wp - in->rp; + + zp->next_out = out->wp; + zp->avail_out = out->ep - out->wp; + + err = inflate(zp, Z_NO_FLUSH); + + in->rp = in->wp - zp->avail_in; + out->wp = out->ep - zp->avail_out; + + if (err == Z_STREAM_END) + { + out->eof = 1; + return fz_iodone; + } + else if (err == Z_OK) + { + if (in->rp == in->wp && !in->eof) + return fz_ioneedin; + if (out->wp == out->ep) + return fz_ioneedout; + return fz_ioneedin; /* hmm, what's going on here? */ + } + else + { + return fz_throw("ioerror: inflate: %s", zp->msg); + } +} + +fz_error * +fz_newflatee(fz_filter **fp, fz_obj *params) +{ + fz_obj *obj; + fz_error *eo; + int effort; + int zipfmt; + int ei; + + FZ_NEWFILTER(fz_flate, f, flatee); + + effort = -1; + zipfmt = 0; + + if (params) + { + obj = fz_dictgets(params, "Effort"); + if (obj) effort = fz_toint(obj); + obj = fz_dictgets(params, "ZIP"); + if (obj) effort = fz_tobool(obj); + } + + f->z.zalloc = zmalloc; + f->z.zfree = (void(*)(void*,void*))fz_currentmemorycontext()->free; + f->z.opaque = fz_currentmemorycontext(); + f->z.next_in = nil; + f->z.avail_in = 0; + + if (zipfmt) + ei = deflateInit2(&f->z, effort, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + else + ei = deflateInit(&f->z, effort); + + if (ei != Z_OK) + { + eo = fz_throw("ioerror: deflateInit: %s", f->z.msg); + fz_free(f); + return eo; + } + + return nil; +} + +void +fz_dropflatee(fz_filter *f) +{ + z_streamp zp = &((fz_flate*)f)->z; + int err; + + err = deflateEnd(zp); + if (err != Z_OK) + fprintf(stderr, "deflateEnd: %s", zp->msg); + + fz_free(f); +} + +fz_error * +fz_processflatee(fz_filter *f, fz_buffer *in, fz_buffer *out) +{ + z_streamp zp = &((fz_flate*)f)->z; + int err; + + if (in->rp == in->wp && !in->eof) + return fz_ioneedin; + if (out->wp == out->ep) + return fz_ioneedout; + + zp->next_in = in->rp; + zp->avail_in = in->wp - in->rp; + + zp->next_out = out->wp; + zp->avail_out = out->ep - out->wp; + + err = deflate(zp, in->eof ? Z_FINISH : Z_NO_FLUSH); + + in->rp = in->wp - zp->avail_in; + out->wp = out->ep - zp->avail_out; + + if (err == Z_STREAM_END) + { + out->eof = 1; + return fz_iodone; + } + else if (err == Z_OK) + { + if (in->rp == in->wp && !in->eof) + return fz_ioneedin; + if (out->wp == out->ep) + return fz_ioneedout; + return fz_ioneedin; /* hmm? */ + } + else + { + return fz_throw("ioerror: deflate: %s", zp->msg); + } +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_jbig2d.c b/rosapps/smartpdf/fitz/stream/filt_jbig2d.c new file mode 100644 index 00000000000..ce73ee538c7 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_jbig2d.c @@ -0,0 +1,116 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +/* TODO: complete rewrite with error checking and use fitz memctx */ + +/* + so to use a global_ctx, you run your global data through a normal ctx + then call jbig2_make_global_ctx with the normal context + that does the (currently null) conversion + make_global_ctx after i fed it all the global stream data? + maskros: yes + and you pass the new global ctx object to jbig2_ctx_new() when you ++create the per-page ctx +*/ + +#ifdef WIN32 /* Microsoft Visual C++ */ + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef __int64 int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; + +#else +#include +#endif + +#include + +typedef struct fz_jbig2d_s fz_jbig2d; + +struct fz_jbig2d_s +{ + fz_filter super; + Jbig2Ctx *ctx; + Jbig2GlobalCtx *gctx; + Jbig2Image *page; + int idx; +}; + +fz_error * +fz_newjbig2d(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_jbig2d, d, jbig2d); + d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, nil, nil, nil); + d->page = nil; + d->idx = 0; + return nil; +} + +void +fz_dropjbig2d(fz_filter *filter) +{ + fz_jbig2d *d = (fz_jbig2d*)filter; + jbig2_ctx_free(d->ctx); +} + +fz_error * +fz_setjbig2dglobalstream(fz_filter *filter, unsigned char *buf, int len) +{ + fz_jbig2d *d = (fz_jbig2d*)filter; + jbig2_data_in(d->ctx, buf, len); + d->gctx = jbig2_make_global_ctx(d->ctx); + d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, d->gctx, nil, nil); + return nil; +} + +fz_error * +fz_processjbig2d(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_jbig2d *d = (fz_jbig2d*)filter; + int len; + int i; + + while (1) + { + if (in->rp == in->wp) { + if (!in->eof) + return fz_ioneedin; + + if (!d->page) { + jbig2_complete_page(d->ctx); + d->page = jbig2_page_out(d->ctx); + } + + if (out->wp == out->ep) + return fz_ioneedout; + + len = out->ep - out->wp; + if (d->idx + len > d->page->height * d->page->stride) + len = d->page->height * d->page->stride - d->idx; + + /* XXX memcpy(out->wp, d->page->data + d->idx, len); */ + for (i = 0; i < len; i++) + out->wp[i] = ~ d->page->data[d->idx + i]; + + out->wp += len; + d->idx += len; + + if (d->idx == d->page->height * d->page->stride) { + jbig2_release_page(d->ctx, d->page); + out->eof = 1; + return fz_iodone; + } + } + else { + len = in->wp - in->rp; + jbig2_data_in(d->ctx, in->rp, len); + in->rp += len; + } + } +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_jpxd.c b/rosapps/smartpdf/fitz/stream/filt_jpxd.c new file mode 100644 index 00000000000..1b93f47725d --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_jpxd.c @@ -0,0 +1,144 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +/* TODO: bpc */ + +/* + * We use the Jasper JPEG2000 coder for now. + */ + +#include + +static char *colorspacename(jas_clrspc_t clrspc) +{ + switch (jas_clrspc_fam(clrspc)) + { + case JAS_CLRSPC_FAM_UNKNOWN: return "Unknown"; + case JAS_CLRSPC_FAM_XYZ: return "XYZ"; + case JAS_CLRSPC_FAM_LAB: return "Lab"; + case JAS_CLRSPC_FAM_GRAY: return "Gray"; + case JAS_CLRSPC_FAM_RGB: return "RGB"; + case JAS_CLRSPC_FAM_YCBCR: return "YCbCr"; + } + return "Unknown"; +} + +typedef struct fz_jpxd_s fz_jpxd; + +struct fz_jpxd_s +{ + fz_filter super; + jas_stream_t *stream; + jas_image_t *image; + int offset; + int stage; +}; + +fz_error * +fz_newjpxd(fz_filter **fp, fz_obj *params) +{ + int err; + + FZ_NEWFILTER(fz_jpxd, d, jpxd); + + err = jas_init(); + if (err) { + fz_free(d); + return fz_throw("ioerror in jpxd: jas_init()"); + } + + d->stream = jas_stream_memopen(nil, 0); + if (!d->stream) { + fz_free(d); + return fz_throw("ioerror in jpxd: jas_stream_memopen()"); + } + + d->image = nil; + d->offset = 0; + d->stage = 0; + + return nil; +} + +void +fz_dropjpxd(fz_filter *filter) +{ + fz_jpxd *d = (fz_jpxd*)filter; + if (d->stream) jas_stream_close(d->stream); + if (d->image) jas_image_destroy(d->image); +} + +fz_error * +fz_processjpxd(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_jpxd *d = (fz_jpxd*)filter; + int n, bpc, w, h; + int i, x, y; + + switch (d->stage) + { + case 0: goto input; + case 1: goto decode; + case 2: goto output; + } + +input: + while (in->rp < in->wp) { + n = jas_stream_write(d->stream, in->rp, in->wp - in->rp); + in->rp += n; + } + + if (!in->eof) + return fz_ioneedin; + + d->stage = 1; + +decode: + jas_stream_seek(d->stream, 0, 0); + + d->image = jas_image_decode(d->stream, -1, 0); + if (!d->image) + return fz_throw("ioerror in jpxd: unable to decode image data"); + + fprintf(stderr, "P%c\n# JPX %d x %d n=%d bpc=%d colorspace=%04x %s\n%d %d\n%d\n", + jas_image_numcmpts(d->image) == 1 ? '5' : '6', + + jas_image_width(d->image), + jas_image_height(d->image), + jas_image_numcmpts(d->image), + jas_image_cmptprec(d->image, 0), + jas_image_clrspc(d->image), + colorspacename(jas_image_clrspc(d->image)), + + jas_image_width(d->image), + jas_image_height(d->image), + (1 << jas_image_cmptprec(d->image, 0)) - 1); + + d->stage = 2; + +output: + w = jas_image_width(d->image); + h = jas_image_height(d->image); + n = jas_image_numcmpts(d->image); + bpc = jas_image_cmptprec(d->image, 0); /* use precision of first component for all... */ + + while (d->offset < w * h) + { + y = d->offset / w; + x = d->offset - y * w; + + /* FIXME bpc != 8 */ + + if (out->wp + n >= out->ep) + return fz_ioneedout; + + for (i = 0; i < n; i++) + *out->wp++ = jas_image_readcmptsample(d->image, i, x, y); + + d->offset ++; + } + + out->eof = 1; + return fz_iodone; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_lzwd.c b/rosapps/smartpdf/fitz/stream/filt_lzwd.c new file mode 100644 index 00000000000..bbdb498472c --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_lzwd.c @@ -0,0 +1,254 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +/* TODO: error checking */ + +enum +{ + MINBITS = 9, + MAXBITS = 12, + NUMCODES = (1 << MAXBITS), + LZW_CLEAR = 256, + LZW_EOD = 257, + LZW_FIRST = 258 +}; + +typedef struct lzw_code_s lzw_code; + +struct lzw_code_s +{ + int prev; /* prev code (in string) */ + unsigned short length; /* string len, including this token */ + unsigned char value; /* data value */ + unsigned char firstchar; /* first token of string */ +}; + +typedef struct fz_lzwd_s fz_lzwd; + +struct fz_lzwd_s +{ + fz_filter super; + + int earlychange; + + unsigned int word; /* bits loaded from data */ + int bidx; + + int resume; /* resume output of code from needout */ + int codebits; /* num bits/code */ + int code; /* current code */ + int oldcode; /* previously recognized code */ + int nextcode; /* next free entry */ + lzw_code table[NUMCODES]; +}; + +fz_error * +fz_newlzwd(fz_filter **fp, fz_obj *params) +{ + int i; + + FZ_NEWFILTER(fz_lzwd, lzw, lzwd); + + lzw->earlychange = 0; + + if (params) + { + fz_obj *obj; + obj = fz_dictgets(params, "EarlyChange"); + if (obj) lzw->earlychange = fz_toint(obj) != 0; + } + + lzw->bidx = 32; + lzw->word = 0; + + for (i = 0; i < 256; i++) + { + lzw->table[i].value = i; + lzw->table[i].firstchar = i; + lzw->table[i].length = 1; + lzw->table[i].prev = -1; + } + + for (i = LZW_FIRST; i < NUMCODES; i++) + { + lzw->table[i].value = 0; + lzw->table[i].firstchar = 0; + lzw->table[i].length = 0; + lzw->table[i].prev = -1; + } + + lzw->codebits = MINBITS; + lzw->code = -1; + lzw->nextcode = LZW_FIRST; + lzw->oldcode = -1; + lzw->resume = 0; + + return nil; +} + +void +fz_droplzwd(fz_filter *filter) +{ +} + +static inline void eatbits(fz_lzwd *lzw, int nbits) +{ + lzw->word <<= nbits; + lzw->bidx += nbits; +} + +static inline fz_error * fillbits(fz_lzwd *lzw, fz_buffer *in) +{ + while (lzw->bidx >= 8) + { + if (in->rp + 1 > in->wp) + return fz_ioneedin; + lzw->bidx -= 8; + lzw->word |= *in->rp << lzw->bidx; + in->rp ++; + } + return nil; +} + +static inline void unstuff(fz_lzwd *lzw, fz_buffer *in) +{ + int i = (32 - lzw->bidx) / 8; + while (i-- && in->rp > in->bp) + in->rp --; +} + +fz_error * +fz_processlzwd(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_lzwd *lzw = (fz_lzwd*)filter; + unsigned char *s; + int len; + + if (lzw->resume) + { + lzw->resume = 0; + goto output; + } + + while (1) + { + if (fillbits(lzw, in)) + { + if (in->eof) + { + if (lzw->bidx > 32 - lzw->codebits) + { + out->eof = 1; + unstuff(lzw, in); + return fz_iodone; + } + } + else + { + return fz_ioneedin; + } + } + + lzw->code = lzw->word >> (32 - lzw->codebits); + + if (lzw->code == LZW_EOD) + { + eatbits(lzw, lzw->codebits); + out->eof = 1; + unstuff(lzw, in); + return fz_iodone; + } + + if (lzw->code == LZW_CLEAR) + { + int oldcodebits = lzw->codebits; + + lzw->codebits = MINBITS; + lzw->nextcode = LZW_FIRST; + + lzw->code = lzw->word >> (32 - oldcodebits - MINBITS) & ((1 << MINBITS) - 1); + + if (lzw->code == LZW_EOD) + { + eatbits(lzw, oldcodebits + MINBITS); + out->eof = 1; + unstuff(lzw, in); + return fz_iodone; + } + + if (out->wp + 1 > out->ep) + return fz_ioneedout; + + *out->wp++ = lzw->code; + + lzw->oldcode = lzw->code; + + eatbits(lzw, oldcodebits + MINBITS); + + continue; + } + + eatbits(lzw, lzw->codebits); + + /* if stream starts without a clear code, oldcode is undefined... */ + if (lzw->oldcode == -1) + { + lzw->oldcode = lzw->code; + goto output; + } + + /* add new entry to the code table */ + lzw->table[lzw->nextcode].prev = lzw->oldcode; + lzw->table[lzw->nextcode].firstchar = lzw->table[lzw->oldcode].firstchar; + lzw->table[lzw->nextcode].length = lzw->table[lzw->oldcode].length + 1; + if (lzw->code < lzw->nextcode) + lzw->table[lzw->nextcode].value = lzw->table[lzw->code].firstchar; + else + lzw->table[lzw->nextcode].value = lzw->table[lzw->nextcode].firstchar; + + lzw->nextcode ++; + + if (lzw->nextcode >= (1 << lzw->codebits) - lzw->earlychange - 1) + { + lzw->codebits ++; + if (lzw->codebits > MAXBITS) + lzw->codebits = MAXBITS; /* FIXME */ + } + + lzw->oldcode = lzw->code; + +output: + /* code maps to a string, copy to output (in reverse...) */ + if (lzw->code > 255) + { + if (out->wp + lzw->table[lzw->code].length > out->ep) + { + lzw->resume = 1; + return fz_ioneedout; + } + + len = lzw->table[lzw->code].length; + s = out->wp + len; + + do + { + *(--s) = lzw->table[lzw->code].value; + lzw->code = lzw->table[lzw->code].prev; + } while (lzw->code >= 0 && s > out->wp); + out->wp += len; + } + + /* ... or just a single character */ + else + { + if (out->wp + 1 > out->ep) + { + lzw->resume = 1; + return fz_ioneedout; + } + + *out->wp++ = lzw->code; + } + } +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_lzwe.c b/rosapps/smartpdf/fitz/stream/filt_lzwe.c new file mode 100644 index 00000000000..a24d8fe5d72 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_lzwe.c @@ -0,0 +1,262 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +#define noDEBUG 1 + +enum +{ + MINBITS = 9, + MAXBITS = 12, + MAXBYTES = 2, + NUMCODES = (1 << MAXBITS), + LZW_CLEAR = 256, + LZW_EOD = 257, + LZW_FIRST = 258, + HSIZE = 9001, /* 91% occupancy (???) */ + HSHIFT = (13 - 8) +}; + +typedef struct lzw_hash_s lzw_hash; + +struct lzw_hash_s +{ + int hash; + int code; +}; + +typedef struct fz_lzwe_s fz_lzwe; + +struct fz_lzwe_s +{ + fz_filter super; + + int earlychange; + + int bidx; /* partial bits used in out->wp */ + unsigned char bsave; /* partial byte saved between process() calls */ + + int resume; + int code; + int fcode; + int hcode; + + int codebits; + int oldcode; + int nextcode; + + lzw_hash table[HSIZE]; +}; + +static void +clearhash(fz_lzwe *lzw) +{ + int i; + for (i = 0; i < HSIZE; i++) + lzw->table[i].hash = -1; +} + +fz_error * +fz_newlzwe(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_lzwe, lzw, lzwe); + + lzw->earlychange = 0; + + if (params) + { + fz_obj *obj; + obj = fz_dictgets(params, "EarlyChange"); + if (obj) lzw->earlychange = fz_toint(obj) != 0; + } + + lzw->bidx = 0; + lzw->bsave = 0; + + lzw->resume = 0; + lzw->code = -1; + lzw->hcode = -1; + lzw->fcode = -1; + + lzw->codebits = MINBITS; + lzw->nextcode = LZW_FIRST; + lzw->oldcode = -1; /* generates LZW_CLEAR */ + + clearhash(lzw); + + return nil; +} + +void +fz_droplzwe(fz_filter *filter) +{ +} + +static void +putcode(fz_lzwe *lzw, fz_buffer *out, int code) +{ + int nbits = lzw->codebits; + + while (nbits > 0) + { + if (lzw->bidx == 0) + { + *out->wp = 0; + } + + /* code does not fit: shift right */ + if (nbits > (8 - lzw->bidx)) + { + *out->wp |= code >> (nbits - (8 - lzw->bidx)); + nbits = nbits - (8 - lzw->bidx); + lzw->bidx = 0; + out->wp ++; + } + + /* shift left */ + else + { + *out->wp |= code << ((8 - lzw->bidx) - nbits); + lzw->bidx += nbits; + if (lzw->bidx == 8) + { + lzw->bidx = 0; + out->wp ++; + } + nbits = 0; + } + } +} + + +static fz_error * +compress(fz_lzwe *lzw, fz_buffer *in, fz_buffer *out) +{ + if (lzw->resume) + { + lzw->resume = 0; + goto resume; + } + + /* at start of data, output a clear code */ + if (lzw->oldcode == -1) + { + if (out->wp + 3 > out->ep) + return fz_ioneedout; + + if (in->rp + 1 > in->wp) + { + if (in->eof) + goto eof; + return fz_ioneedin; + } + + putcode(lzw, out, LZW_CLEAR); + + lzw->oldcode = *in->rp++; + } + +begin: + while (1) + { + if (in->rp + 1 > in->wp) + { + if (in->eof) + goto eof; + return fz_ioneedin; + } + + /* read character */ + lzw->code = *in->rp++; + + /* hash string + character */ + lzw->fcode = (lzw->code << MAXBITS) + lzw->oldcode; + lzw->hcode = (lzw->code << HSHIFT) ^ lzw->oldcode; + + /* primary hash */ + if (lzw->table[lzw->hcode].hash == lzw->fcode) + { + lzw->oldcode = lzw->table[lzw->hcode].code; + continue; + } + + /* secondary hash */ + if (lzw->table[lzw->hcode].hash != -1) + { + int disp = HSIZE - lzw->hcode; + if (lzw->hcode == 0) + disp = 1; + do + { + lzw->hcode = lzw->hcode - disp; + if (lzw->hcode < 0) + lzw->hcode += HSIZE; + if (lzw->table[lzw->hcode].hash == lzw->fcode) + { + lzw->oldcode = lzw->table[lzw->hcode].code; + goto begin; + } + } while (lzw->table[lzw->hcode].hash != -1); + } + +resume: + /* new entry: emit code and add to table */ + + /* reserve space for this code and an eventual CLEAR code */ + if (out->wp + 5 > out->ep) + { + lzw->resume = 1; + return fz_ioneedout; + } + + putcode(lzw, out, lzw->oldcode); + + lzw->oldcode = lzw->code; + lzw->table[lzw->hcode].code = lzw->nextcode; + lzw->table[lzw->hcode].hash = lzw->fcode; + + lzw->nextcode ++; + + /* table is full: emit clear code and reset */ + if (lzw->nextcode == NUMCODES - 1) + { + putcode(lzw, out, LZW_CLEAR); + clearhash(lzw); + lzw->nextcode = LZW_FIRST; + lzw->codebits = MINBITS; + } + + /* check if next entry will be too big for the code size */ + else if (lzw->nextcode >= (1 << lzw->codebits) - lzw->earlychange) + { + lzw->codebits ++; + } + } + +eof: + if (out->wp + 5 > out->ep) + return fz_ioneedout; + + putcode(lzw, out, lzw->oldcode); + putcode(lzw, out, LZW_EOD); + + out->eof = 1; + return fz_iodone; +} + +fz_error * +fz_processlzwe(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_lzwe *lzw = (fz_lzwe*)filter; + fz_error *error; + + /* restore partial bits */ + *out->wp = lzw->bsave; + + error = compress(lzw, in, out); + + /* save partial bits */ + lzw->bsave = *out->wp; + + return error; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_null.c b/rosapps/smartpdf/fitz/stream/filt_null.c new file mode 100644 index 00000000000..f51039b4ab7 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_null.c @@ -0,0 +1,53 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +typedef struct fz_nullfilter_s fz_nullfilter; + +struct fz_nullfilter_s +{ + fz_filter super; + int len; + int cur; +}; + +fz_error * +fz_newnullfilter(fz_filter **fp, int len) +{ + FZ_NEWFILTER(fz_nullfilter, f, nullfilter); + f->len = len; + f->cur = 0; + return nil; +} + +void +fz_dropnullfilter(fz_filter *f) +{ +} + +fz_error * +fz_processnullfilter(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_nullfilter *f = (fz_nullfilter*)filter; + int n; + + n = MIN(in->wp - in->rp, out->ep - out->wp); + if (f->len >= 0) + n = MIN(n, f->len - f->cur); + + if (n) { + memcpy(out->wp, in->rp, n); + in->rp += n; + out->wp += n; + f->cur += n; + } + + if (f->cur == f->len) + return fz_iodone; + if (in->rp == in->wp) + return fz_ioneedin; + if (out->wp == out->ep) + return fz_ioneedout; + + return fz_throw("braindead programmer in nullfilter"); +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_pipeline.c b/rosapps/smartpdf/fitz/stream/filt_pipeline.c new file mode 100644 index 00000000000..65e1c38d191 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_pipeline.c @@ -0,0 +1,129 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +#define noDEBUG 1 + +typedef struct fz_pipeline_s fz_pipeline; + +fz_error * fz_processpipeline(fz_filter *filter, fz_buffer *in, fz_buffer *out); + +struct fz_pipeline_s +{ + fz_filter super; + fz_filter *head; + fz_buffer *buffer; + fz_filter *tail; + int tailneedsin; +}; + +fz_error * +fz_chainpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail, fz_buffer *buf) +{ + FZ_NEWFILTER(fz_pipeline, p, pipeline); + p->head = fz_keepfilter(head); + p->tail = fz_keepfilter(tail); + p->tailneedsin = 1; + p->buffer = fz_keepbuffer(buf); + return nil; +} + +void +fz_unchainpipeline(fz_filter *filter, fz_filter **oldfp, fz_buffer **oldbp) +{ + fz_pipeline *p = (fz_pipeline*)filter; + + *oldfp = fz_keepfilter(p->head); + *oldbp = fz_keepbuffer(p->buffer); + + fz_dropfilter(filter); +} + +fz_error * +fz_newpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail) +{ + fz_error *error; + + FZ_NEWFILTER(fz_pipeline, p, pipeline); + p->head = fz_keepfilter(head); + p->tail = fz_keepfilter(tail); + p->tailneedsin = 1; + + error = fz_newbuffer(&p->buffer, FZ_BUFSIZE); + if (error) { fz_free(p); return error; } + + return nil; +} + +void +fz_droppipeline(fz_filter *filter) +{ + fz_pipeline *p = (fz_pipeline*)filter; + fz_dropfilter(p->head); + fz_dropfilter(p->tail); + fz_dropbuffer(p->buffer); +} + +fz_error * +fz_processpipeline(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_pipeline *p = (fz_pipeline*)filter; + fz_error *e; + + if (p->buffer->eof) + goto tail; + + if (p->tailneedsin && p->head->produced) + goto tail; + +head: + e = fz_process(p->head, in, p->buffer); + + if (e == fz_ioneedin) + return fz_ioneedin; + + else if (e == fz_ioneedout) + { + if (p->tailneedsin && !p->head->produced) + { + fz_error *be = nil; + if (p->buffer->rp > p->buffer->bp) + be = fz_rewindbuffer(p->buffer); + else + be = fz_growbuffer(p->buffer); + if (be) + return be; + goto head; + } + goto tail; + } + + else if (e == fz_iodone) + goto tail; + + else + return e; + +tail: + e = fz_process(p->tail, p->buffer, out); + + if (e == fz_ioneedin) + { + if (p->buffer->eof) + return fz_throw("ioerror: premature eof in pipeline"); + p->tailneedsin = 1; + goto head; + } + + else if (e == fz_ioneedout) + { + p->tailneedsin = 0; + return fz_ioneedout; + } + + else if (e == fz_iodone) + return fz_iodone; + + else + return e; +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_predict.c b/rosapps/smartpdf/fitz/stream/filt_predict.c new file mode 100644 index 00000000000..bf4680e703f --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_predict.c @@ -0,0 +1,239 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +/* TODO: check if this works with 16bpp images */ + +enum { MAXC = 32 }; + +typedef struct fz_predict_s fz_predict; + +struct fz_predict_s +{ + fz_filter super; + + int predictor; + int columns; + int colors; + int bpc; + + int stride; + int bpp; + unsigned char *ref; + + int encode; +}; + +fz_error * +fz_newpredict(fz_filter **fp, fz_obj *params, int encode) +{ + fz_obj *obj; + + FZ_NEWFILTER(fz_predict, p, predict); + + p->encode = encode; + + p->predictor = 1; + p->columns = 1; + p->colors = 1; + p->bpc = 8; + + obj = fz_dictgets(params, "Predictor"); + if (obj) p->predictor = fz_toint(obj); + + obj = fz_dictgets(params, "Columns"); + if (obj) p->columns = fz_toint(obj); + + obj = fz_dictgets(params, "Colors"); + if (obj) p->colors = fz_toint(obj); + + obj = fz_dictgets(params, "BitsPerComponent"); + if (obj) p->bpc = fz_toint(obj); + + p->stride = (p->bpc * p->colors * p->columns + 7) / 8; + p->bpp = (p->bpc * p->colors + 7) / 8; + + if (p->predictor >= 10) { + p->ref = fz_malloc(p->stride); + if (!p->ref) { fz_free(p); return fz_outofmem; } + memset(p->ref, 0, p->stride); + } + else { + p->ref = nil; + } + + return nil; +} + +void +fz_droppredict(fz_filter *filter) +{ + fz_predict *p = (fz_predict*)filter; + fz_free(p->ref); +} + +static inline int +getcomponent(unsigned char *buf, int x, int bpc) +{ + switch (bpc) + { + case 1: return buf[x / 8] >> (7 - (x % 8)) & 0x01; + case 2: return buf[x / 4] >> ((3 - (x % 4)) * 2) & 0x03; + case 4: return buf[x / 2] >> ((1 - (x % 2)) * 4) & 0x0f; + case 8: return buf[x]; + } + return 0; +} + +static inline void +putcomponent(unsigned char *buf, int x, int bpc, int value) +{ + switch (bpc) + { + case 1: buf[x / 8] |= value << (7 - (x % 8)); break; + case 2: buf[x / 4] |= value << ((3 - (x % 4)) * 2); break; + case 4: buf[x / 2] |= value << ((1 - (x % 2)) * 4); break; + case 8: buf[x] = value; break; + } +} + +static inline int +paeth(int a, int b, int c) +{ + /* The definitions of ac and bc are correct, not a typo. */ + int ac = b - c, bc = a - c, abcc = ac + bc; + int pa = (ac < 0 ? -ac : ac); + int pb = (bc < 0 ? -bc : bc); + int pc = (abcc < 0 ? -abcc : abcc); + return pa <= pb && pa <= pc ? a : pb <= pc ? b : c; +} + +static inline void +none(fz_predict *p, unsigned char *in, unsigned char *out) +{ + memcpy(out, in, p->stride); +} + +static void +tiff(fz_predict *p, unsigned char *in, unsigned char *out) +{ + int left[MAXC]; + int i, k; + + for (k = 0; k < p->colors; k++) + left[k] = 0; + + for (i = 0; i < p->columns; i++) { + for (k = 0; k < p->colors; k++) { + int a = getcomponent(in, i * p->colors + k, p->bpc); + int b = p->encode ? a - left[k] : a + left[k]; + int c = b % (1 << p->bpc); + putcomponent(out, i * p->colors + k, p->bpc, c); + left[k] = p->encode ? a : c; + } + } +} + +static void +png(fz_predict *p, unsigned char *in, unsigned char *out, int predictor) +{ + int upleft[MAXC], left[MAXC], i, k; + + for (k = 0; k < p->bpp; k++) { + left[k] = 0; + upleft[k] = 0; + } + + if (p->encode) + { + for (k = 0, i = 0; i < p->stride; k = (k + 1) % p->bpp, i ++) + { + switch (predictor) + { + case 0: out[i] = in[i]; break; + case 1: out[i] = in[i] - left[k]; break; + case 2: out[i] = in[i] - p->ref[i]; break; + case 3: out[i] = in[i] - (left[k] + p->ref[i]) / 2; break; + case 4: out[i] = in[i] - paeth(left[k], p->ref[i], upleft[k]); break; + } + left[k] = in[i]; + upleft[k] = p->ref[i]; + } + } + + else + { + for (k = 0, i = 0; i < p->stride; k = (k + 1) % p->bpp, i ++) + { + switch (predictor) + { + case 0: out[i] = in[i]; break; + case 1: out[i] = in[i] + left[k]; break; + case 2: out[i] = in[i] + p->ref[i]; break; + case 3: out[i] = in[i] + (left[k] + p->ref[i]) / 2; break; + case 4: out[i] = in[i] + paeth(left[k], p->ref[i], upleft[k]); break; + } + left[k] = out[i]; + upleft[k] = p->ref[i]; + } + } +} + +fz_error * +fz_processpredict(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_predict *dec = (fz_predict*)filter; + int ispng = dec->predictor >= 10; + int predictor; + + while (1) + { + if (in->rp + dec->stride + (!dec->encode && ispng) > in->wp) { + if (in->eof) + return fz_iodone; + return fz_ioneedin; + } + + if (out->wp + dec->stride + (dec->encode && ispng) > out->ep) + return fz_ioneedout; + + if (dec->predictor == 1) { + none(dec, in->rp, out->wp); + } + else if (dec->predictor == 2) { + if (dec->bpc != 8) + memset(out->wp, 0, dec->stride); + tiff(dec, in->rp, out->wp); + } + else { + if (dec->encode) { + predictor = dec->predictor - 10; + if (predictor < 0 || predictor > 4) + predictor = 1; + *out->wp ++ = predictor; + } + else { + predictor = *in->rp++; + } + png(dec, in->rp, out->wp, predictor); + } + + if (dec->ref) + memcpy(dec->ref, out->wp, dec->stride); + + in->rp += dec->stride; + out->wp += dec->stride; + } +} + +fz_error * +fz_newpredictd(fz_filter **fp, fz_obj *params) +{ + return fz_newpredict(fp, params, 0); +} + +fz_error * +fz_newpredicte(fz_filter **fp, fz_obj *params) +{ + return fz_newpredict(fp, params, 1); +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_rld.c b/rosapps/smartpdf/fitz/stream/filt_rld.c new file mode 100644 index 00000000000..dc720fbd2af --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_rld.c @@ -0,0 +1,74 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +fz_error * +fz_newrld(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_filter, f, rld); + return nil; +} + +void +fz_droprld(fz_filter *rld) +{ +} + +fz_error * +fz_processrld(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + int run, i; + unsigned char c; + + while (1) + { + if (in->rp == in->wp) + { + if (in->eof) + { + out->eof = 1; + return fz_iodone; + } + return fz_ioneedin; + } + + if (out->wp == out->ep) + return fz_ioneedout; + + run = *in->rp++; + + if (run == 128) { + out->eof = 1; + return fz_iodone; + } + + else if (run < 128) { + run = run + 1; + if (in->rp + run > in->wp) { + in->rp --; + return fz_ioneedin; + } + if (out->wp + run > out->ep) { + in->rp --; + return fz_ioneedout; + } + for (i = 0; i < run; i++) + *out->wp++ = *in->rp++; + } + + else if (run > 128) { + run = 257 - run; + if (in->rp + 1 > in->wp) { + in->rp --; + return fz_ioneedin; + } + if (out->wp + run > out->ep) { + in->rp --; + return fz_ioneedout; + } + c = *in->rp++; + for (i = 0; i < run; i++) + *out->wp++ = c; + } + } +} + diff --git a/rosapps/smartpdf/fitz/stream/filt_rle.c b/rosapps/smartpdf/fitz/stream/filt_rle.c new file mode 100644 index 00000000000..598733e1b59 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/filt_rle.c @@ -0,0 +1,238 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +/* TODO: rewrite! + * make it non-optimal or something, + * just not this horrid mess... + */ + +#define noDEBUG + +typedef struct fz_rle_s fz_rle; + +struct fz_rle_s +{ + fz_filter super; + int reclen; + int curlen; + int state; + int run; + unsigned char buf[128]; +}; + +enum { + ZERO, + ONE, + DIFF, + SAME, + END +}; + +fz_error * +fz_newrle(fz_filter **fp, fz_obj *params) +{ + FZ_NEWFILTER(fz_rle, enc, rle); + + if (params) + enc->reclen = fz_toint(params); + else + enc->reclen = 0; + + enc->curlen = 0; + enc->state = ZERO; + enc->run = 0; + + return nil; +} + +void +fz_droprle(fz_filter *enc) +{ +} + +static fz_error * +putone(fz_rle *enc, fz_buffer *in, fz_buffer *out) +{ + if (out->wp + 2 >= out->ep) + return fz_ioneedout; + +#ifdef DEBUG +fprintf(stderr, "one '%c'\n", enc->buf[0]); +#endif + + *out->wp++ = 0; + *out->wp++ = enc->buf[0]; + + return nil; +} + +static fz_error * +putsame(fz_rle *enc, fz_buffer *in, fz_buffer *out) +{ + if (out->wp + enc->run >= out->ep) + return fz_ioneedout; + +#ifdef DEBUG +fprintf(stderr, "same %d x '%c'\n", enc->run, enc->buf[0]); +#endif + + *out->wp++ = 257 - enc->run; + *out->wp++ = enc->buf[0]; + return nil; +} + +static fz_error * +putdiff(fz_rle *enc, fz_buffer *in, fz_buffer *out) +{ + int i; + if (out->wp + enc->run >= out->ep) + return fz_ioneedout; + +#ifdef DEBUG +fprintf(stderr, "diff %d\n", enc->run); +#endif + + *out->wp++ = enc->run - 1; + for (i = 0; i < enc->run; i++) + *out->wp++ = enc->buf[i]; + return nil; +} + +static fz_error * +puteod(fz_rle *enc, fz_buffer *in, fz_buffer *out) +{ + if (out->wp + 1 >= out->ep) + return fz_ioneedout; + +#ifdef DEBUG +fprintf(stderr, "eod\n"); +#endif + + *out->wp++ = 128; + return nil; +} + +static fz_error * +savebuf(fz_rle *enc, fz_buffer *in, fz_buffer *out) +{ + switch (enc->state) + { + case ZERO: return nil; + case ONE: return putone(enc, in, out); + case SAME: return putsame(enc, in, out); + case DIFF: return putdiff(enc, in, out); + case END: return puteod(enc, in, out); + default: assert(!"invalid state in rle"); return nil; + } +} + +fz_error * +fz_processrle(fz_filter *filter, fz_buffer *in, fz_buffer *out) +{ + fz_rle *enc = (fz_rle*)filter; + fz_error *error; + unsigned char c; + + while (1) + { + + if (enc->reclen && enc->curlen == enc->reclen) { + error = savebuf(enc, in, out); + if (error) return error; +#ifdef DEBUG +fprintf(stderr, "--record--\n"); +#endif + enc->state = ZERO; + enc->curlen = 0; + } + + if (in->rp == in->wp) { + if (in->eof) { + if (enc->state != END) { + error = savebuf(enc, in, out); + if (error) return error; + } + enc->state = END; + } + else + return fz_ioneedin; + } + + c = *in->rp; + + switch (enc->state) + { + case ZERO: + enc->state = ONE; + enc->run = 1; + enc->buf[0] = c; + break; + + case ONE: + enc->state = DIFF; + enc->run = 2; + enc->buf[1] = c; + break; + + case DIFF: + /* out of space */ + if (enc->run == 128) { + error = putdiff(enc, in, out); + if (error) return error; + + enc->state = ONE; + enc->run = 1; + enc->buf[0] = c; + } + + /* run of three that are the same */ + else if ((enc->run > 1) && + (c == enc->buf[enc->run - 1]) && + (c == enc->buf[enc->run - 2])) + { + if (enc->run >= 3) { + enc->run -= 2; /* skip prev two for diff run */ + error = putdiff(enc, in, out); + if (error) return error; + } + + enc->state = SAME; + enc->run = 3; + enc->buf[0] = c; + } + + /* keep on collecting */ + else { + enc->buf[enc->run++] = c; + } + break; + + case SAME: + if (enc->run == 128 || c != enc->buf[0]) { + error = putsame(enc, in, out); + if (error) return error; + + enc->state = ONE; + enc->run = 1; + enc->buf[0] = c; + } + else { + enc->run ++; + } + break; + + case END: + error = puteod(enc, in, out); + if (error) return error; + + out->eof = 1; + return fz_iodone; + } + + in->rp ++; + + enc->curlen ++; + + } +} + diff --git a/rosapps/smartpdf/fitz/stream/obj_array.c b/rosapps/smartpdf/fitz/stream/obj_array.c new file mode 100644 index 00000000000..666e113aaa8 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/obj_array.c @@ -0,0 +1,185 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +void fz_droparray(fz_obj *obj); + +fz_error * +fz_newarray(fz_obj **op, int initialcap) +{ + fz_obj *obj; + int i; + + obj = *op = fz_malloc(sizeof (fz_obj)); + if (!obj) return fz_outofmem; + + obj->refs = 1; + obj->kind = FZ_ARRAY; + + obj->u.a.len = 0; + obj->u.a.cap = initialcap > 0 ? initialcap : 6; + + obj->u.a.items = fz_malloc(sizeof (fz_obj*) * obj->u.a.cap); + if (!obj->u.a.items) { fz_free(obj); return fz_outofmem; } + + for (i = 0; i < obj->u.a.cap; i++) + obj->u.a.items[i] = nil; + + return nil; +} + +fz_error * +fz_copyarray(fz_obj **op, fz_obj *obj) +{ + fz_error *error; + fz_obj *new; + int i; + + if (!fz_isarray(obj)) + return fz_throw("typecheck in copyarray"); + + error = fz_newarray(&new, fz_arraylen(obj)); + if (error) return error; + *op = new; + + for (i = 0; i < fz_arraylen(obj); i++) { + error = fz_arraypush(new, fz_arrayget(obj, i)); + if (error) { fz_droparray(new); return error; } + } + + return nil; +} + +fz_error * +fz_deepcopyarray(fz_obj **op, fz_obj *obj) +{ + fz_error *error; + fz_obj *new; + fz_obj *val; + int i; + + if (!fz_isarray(obj)) + return fz_throw("typecheck in deepcopyarray"); + + error = fz_newarray(&new, fz_arraylen(obj)); + if (error) return error; + *op = new; + + for (i = 0; i < fz_arraylen(obj); i++) + { + val = fz_arrayget(obj, i); + + if (fz_isarray(val)) { + error = fz_deepcopyarray(&val, val); + if (error) { fz_droparray(new); return error; } + error = fz_arraypush(new, val); + if (error) { fz_dropobj(val); fz_droparray(new); return error; } + fz_dropobj(val); + } + + else if (fz_isdict(val)) { + error = fz_deepcopydict(&val, val); + if (error) { fz_droparray(new); return error; } + error = fz_arraypush(new, val); + if (error) { fz_dropobj(val); fz_droparray(new); return error; } + fz_dropobj(val); + } + + else { + error = fz_arraypush(new, val); + if (error) { fz_droparray(new); return error; } + } + } + + return nil; +} + +int +fz_arraylen(fz_obj *obj) +{ + if (!fz_isarray(obj)) + return 0; + return obj->u.a.len; +} + +fz_obj * +fz_arrayget(fz_obj *obj, int i) +{ + if (!fz_isarray(obj)) + return nil; + + if (i < 0 || i >= obj->u.a.len) + return nil; + + return obj->u.a.items[i]; +} + +fz_error * +fz_arrayput(fz_obj *obj, int i, fz_obj *item) +{ + if (!fz_isarray(obj)) + return fz_throw("typecheck in arrayput"); + if (i < 0) + return fz_throw("rangecheck in arrayput: %d < 0", i); + if (i >= obj->u.a.len) + return fz_throw("rangecheck in arrayput: %d > %d", i, obj->u.a.len); + + if (obj->u.a.items[i]) + fz_dropobj(obj->u.a.items[i]); + obj->u.a.items[i] = fz_keepobj(item); + + return nil; +} + +static fz_error * +growarray(fz_obj *obj) +{ + fz_obj **newitems; + int newcap; + int i; + + newcap = obj->u.a.cap * 2; + newitems = fz_realloc(obj->u.a.items, sizeof (fz_obj*) * newcap); + if (!newitems) return fz_outofmem; + + obj->u.a.items = newitems; + for (i = obj->u.a.cap ; i < newcap; i++) + obj->u.a.items[i] = nil; + obj->u.a.cap = newcap; + + return nil; +} + +fz_error * +fz_arraypush(fz_obj *obj, fz_obj *item) +{ + fz_error *error; + + if (!fz_isarray(obj)) + return fz_throw("typecheck in arraypush"); + + if (obj->u.a.len + 1 > obj->u.a.cap) { + error = growarray(obj); + if (error) return error; + } + + obj->u.a.items[obj->u.a.len] = fz_keepobj(item); + obj->u.a.len++; + + return nil; +} + +void +fz_droparray(fz_obj *obj) +{ + int i; + + assert(obj->kind == FZ_ARRAY); + + for (i = 0; i < obj->u.a.len; i++) + if (obj->u.a.items[i]) + fz_dropobj(obj->u.a.items[i]); + + fz_free(obj->u.a.items); + fz_free(obj); +} + diff --git a/rosapps/smartpdf/fitz/stream/obj_dict.c b/rosapps/smartpdf/fitz/stream/obj_dict.c new file mode 100644 index 00000000000..2eef56b503b --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/obj_dict.c @@ -0,0 +1,356 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +/* keep either names or strings in the dict. don't mix & match. */ + +static int keyvalcmp(const void *ap, const void *bp) +{ + const fz_keyval *a = ap; + const fz_keyval *b = bp; + if (fz_isname(a->k)) + return strcmp(fz_toname(a->k), fz_toname(b->k)); + if (fz_isstring(a->k)) + return strcmp(fz_tostrbuf(a->k), fz_tostrbuf(b->k)); + return -1; +} + +static inline int keystrcmp(fz_obj *key, char *s) +{ + if (fz_isname(key)) + return strcmp(fz_toname(key), s); + if (fz_isstring(key)) + return strcmp(fz_tostrbuf(key), s); + return -1; +} + +fz_error * +fz_newdict(fz_obj **op, int initialcap) +{ + fz_obj *obj; + int i; + + obj = *op = fz_malloc(sizeof (fz_obj)); + if (!obj) return fz_outofmem; + + obj->refs = 1; + obj->kind = FZ_DICT; + + obj->u.d.sorted = 1; + obj->u.d.len = 0; + obj->u.d.cap = initialcap > 0 ? initialcap : 10; + + obj->u.d.items = fz_malloc(sizeof(fz_keyval) * obj->u.d.cap); + if (!obj->u.d.items) { fz_free(obj); return fz_outofmem; } + + for (i = 0; i < obj->u.d.cap; i++) { + obj->u.d.items[i].k = nil; + obj->u.d.items[i].v = nil; + } + + return nil; +} + +fz_error * +fz_copydict(fz_obj **op, fz_obj *obj) +{ + fz_error *error; + fz_obj *new; + int i; + + if (!fz_isdict(obj)) + return fz_throw("typecheck in copydict"); + + error = fz_newdict(&new, obj->u.d.cap); + if (error) return error; + *op = new; + + for (i = 0; i < fz_dictlen(obj); i++) { + error = fz_dictput(new, fz_dictgetkey(obj, i), fz_dictgetval(obj, i)); + if (error) { fz_dropobj(new); return error; } + } + + return nil; +} + +fz_error * +fz_deepcopydict(fz_obj **op, fz_obj *obj) +{ + fz_error *error; + fz_obj *new; + fz_obj *val; + int i; + + if (!fz_isdict(obj)) + return fz_throw("typecheck in deepcopydict"); + + error = fz_newdict(&new, obj->u.d.cap); + if (error) return error; + *op = new; + + for (i = 0; i < fz_dictlen(obj); i++) + { + val = fz_dictgetval(obj, i); + + if (fz_isarray(val)) { + error = fz_deepcopyarray(&val, val); + if (error) { fz_dropobj(new); return error; } + error = fz_dictput(new, fz_dictgetkey(obj, i), val); + if (error) { fz_dropobj(val); fz_dropobj(new); return error; } + fz_dropobj(val); + } + + else if (fz_isdict(val)) { + error = fz_deepcopydict(&val, val); + if (error) { fz_dropobj(new); return error; } + error = fz_dictput(new, fz_dictgetkey(obj, i), val); + if (error) { fz_dropobj(val); fz_dropobj(new); return error; } + fz_dropobj(val); + } + + else { + error = fz_dictput(new, fz_dictgetkey(obj, i), val); + if (error) { fz_dropobj(new); return error; } + } + } + + return nil; +} + +static fz_error * +growdict(fz_obj *obj) +{ + fz_keyval *newitems; + int newcap; + int i; + + newcap = obj->u.d.cap * 2; + + newitems = fz_realloc(obj->u.d.items, sizeof(fz_keyval) * newcap); + if (!newitems) return fz_outofmem; + + obj->u.d.items = newitems; + for (i = obj->u.d.cap; i < newcap; i++) { + obj->u.d.items[i].k = nil; + obj->u.d.items[i].v = nil; + } + obj->u.d.cap = newcap; + + return nil; +} + +int +fz_dictlen(fz_obj *obj) +{ + if (!fz_isdict(obj)) + return 0; + return obj->u.d.len; +} + +fz_obj * +fz_dictgetkey(fz_obj *obj, int i) +{ + if (!fz_isdict(obj)) + return nil; + + if (i < 0 || i >= obj->u.d.len) + return nil; + + return obj->u.d.items[i].k; +} + +fz_obj * +fz_dictgetval(fz_obj *obj, int i) +{ + if (!fz_isdict(obj)) + return nil; + + if (i < 0 || i >= obj->u.d.len) + return nil; + + return obj->u.d.items[i].v; +} + +static inline int dictfinds(fz_obj *obj, char *key) +{ + if (obj->u.d.sorted) + { + int l = 0; + int r = obj->u.d.len - 1; + while (l <= r) + { + int m = (l + r) >> 1; + int c = -keystrcmp(obj->u.d.items[m].k, key); + if (c < 0) + r = m - 1; + else if (c > 0) + l = m + 1; + else + return m; + } + } + + else + { + int i; + for (i = 0; i < obj->u.d.len; i++) + if (keystrcmp(obj->u.d.items[i].k, key) == 0) + return i; + } + + return -1; +} + +fz_obj * +fz_dictgets(fz_obj *obj, char *key) +{ + int i; + + if (!fz_isdict(obj)) + return nil; + + i = dictfinds(obj, key); + if (i >= 0) + return obj->u.d.items[i].v; + + return nil; +} + +fz_obj * +fz_dictget(fz_obj *obj, fz_obj *key) +{ + if (fz_isname(key)) + return fz_dictgets(obj, fz_toname(key)); + if (fz_isstring(key)) + return fz_dictgets(obj, fz_tostrbuf(key)); + return nil; +} + +fz_obj * +fz_dictgetsa(fz_obj *obj, char *key, char *abbrev) +{ + fz_obj *v; + v = fz_dictgets(obj, key); + if (v) + return v; + return fz_dictgets(obj, abbrev); +} + +fz_error * +fz_dictput(fz_obj *obj, fz_obj *key, fz_obj *val) +{ + fz_error *error; + char *s; + int i; + + if (!fz_isdict(obj)) + return fz_throw("typecheck in dictput"); + + if (fz_isname(key)) + s = fz_toname(key); + else if (fz_isstring(key)) + s = fz_tostrbuf(key); + else + return fz_throw("typecheck in dictput"); + + i = dictfinds(obj, s); + if (i >= 0) + { + fz_dropobj(obj->u.d.items[i].v); + obj->u.d.items[i].v = fz_keepobj(val); + return nil; + } + + if (obj->u.d.len + 1 > obj->u.d.cap) + { + error = growdict(obj); + if (error) + return error; + } + + /* borked! */ + if (obj->u.d.len) + if (keystrcmp(obj->u.d.items[obj->u.d.len - 1].k, s) > 0) + obj->u.d.sorted = 0; + + obj->u.d.items[obj->u.d.len].k = fz_keepobj(key); + obj->u.d.items[obj->u.d.len].v = fz_keepobj(val); + obj->u.d.len ++; + + return nil; +} + +fz_error * +fz_dictputs(fz_obj *obj, char *key, fz_obj *val) +{ + fz_error *error; + fz_obj *keyobj; + error = fz_newname(&keyobj, key); + if (error) return error; + error = fz_dictput(obj, keyobj, val); + fz_dropobj(keyobj); + return error; +} + +fz_error * +fz_dictdels(fz_obj *obj, char *key) +{ + int i; + + if (!fz_isdict(obj)) + return fz_throw("typecheck in dictdel"); + + i = dictfinds(obj, key); + if (i >= 0) + { + fz_dropobj(obj->u.d.items[i].k); + fz_dropobj(obj->u.d.items[i].v); + obj->u.d.sorted = 0; + obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1]; + obj->u.d.len --; + } + + return nil; +} + +fz_error * +fz_dictdel(fz_obj *obj, fz_obj *key) +{ + if (fz_isname(key)) + return fz_dictdels(obj, fz_toname(key)); + else if (fz_isstring(key)) + return fz_dictdels(obj, fz_tostrbuf(key)); + else + return fz_throw("typecheck in dictdel"); +} + +void +fz_dropdict(fz_obj *obj) +{ + int i; + + if (!fz_isdict(obj)) + return; + + for (i = 0; i < obj->u.d.len; i++) { + if (obj->u.d.items[i].k) + fz_dropobj(obj->u.d.items[i].k); + if (obj->u.d.items[i].v) + fz_dropobj(obj->u.d.items[i].v); + } + + fz_free(obj->u.d.items); + fz_free(obj); +} + +void +fz_sortdict(fz_obj *obj) +{ + if (!fz_isdict(obj)) + return; + if (!obj->u.d.sorted) + { + qsort(obj->u.d.items, obj->u.d.len, sizeof(fz_keyval), keyvalcmp); + obj->u.d.sorted = 1; + } +} + diff --git a/rosapps/smartpdf/fitz/stream/obj_parse.c b/rosapps/smartpdf/fitz/stream/obj_parse.c new file mode 100644 index 00000000000..bd8133a2907 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/obj_parse.c @@ -0,0 +1,402 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +struct vap { va_list ap; }; + +static inline int iswhite(int ch) +{ + return + ch == '\000' || + ch == '\011' || + ch == '\012' || + ch == '\014' || + ch == '\015' || + ch == '\040'; +} + +static inline int isdelim(int ch) +{ + return + ch == '(' || ch == ')' || + ch == '<' || ch == '>' || + ch == '[' || ch == ']' || + ch == '{' || ch == '}' || + ch == '/' || + ch == '%'; +} + +static inline int isregular(int ch) +{ + return !isdelim(ch) && !iswhite(ch) && ch != EOF; +} + +static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v); + +static inline int fromhex(char ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 0xA; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 0xA; + return 0; +} + +static inline void skipwhite(char **sp) +{ + char *s = *sp; + while (iswhite(*s)) + s ++; + *sp = s; +} + +static void parsekeyword(char **sp, char *b, char *eb) +{ + char *s = *sp; + while (b < eb && isregular(*s)) + *b++ = *s++; + *b++ = 0; + *sp = s; +} + +static fz_error *parsename(fz_obj **obj, char **sp) +{ + char buf[64]; + char *s = *sp; + char *p = buf; + + s ++; /* skip '/' */ + while (p < buf + sizeof buf - 1 && isregular(*s)) + *p++ = *s++; + *p++ = 0; + *sp = s; + + return fz_newname(obj, buf); +} + +static fz_error *parsenumber(fz_obj **obj, char **sp) +{ + char buf[32]; + char *s = *sp; + char *p = buf; + + while (p < buf + sizeof buf - 1) + { + if (s[0] == '-' || s[0] == '.' || (s[0] >= '0' && s[0] <= '9')) + *p++ = *s++; + else + break; + } + *p++ = 0; + *sp = s; + + if (strchr(buf, '.')) + return fz_newreal(obj, atof(buf)); + return fz_newint(obj, atoi(buf)); +} + +static fz_error *parsedict(fz_obj **obj, char **sp, struct vap *v) +{ + fz_error *error = nil; + fz_obj *dict = nil; + fz_obj *key = nil; + fz_obj *val = nil; + char *s = *sp; + + error = fz_newdict(&dict, 8); + if (error) return error; + *obj = dict; + + s += 2; /* skip "<<" */ + + while (*s) + { + skipwhite(&s); + + /* end-of-dict marker >> */ + if (*s == '>') { + s ++; + if (*s == '>') { + s ++; + break; + } + error = fz_throw("syntaxerror in parsedict"); + goto cleanup; + } + + /* non-name as key, bail */ + if (*s != '/') { + error = fz_throw("syntaxerror in parsedict"); + goto cleanup; + } + + error = parsename(&key, &s); + if (error) goto cleanup; + + skipwhite(&s); + + error = parseobj(&val, &s, v); + if (error) goto cleanup; + + error = fz_dictput(dict, key, val); + if (error) goto cleanup; + + fz_dropobj(val); val = nil; + fz_dropobj(key); key = nil; + } + + *sp = s; + return nil; + +cleanup: + if (val) fz_dropobj(val); + if (key) fz_dropobj(key); + if (dict) fz_dropobj(dict); + *obj = nil; + *sp = s; + return error; +} + +static fz_error *parsearray(fz_obj **obj, char **sp, struct vap *v) +{ + fz_error *error; + fz_obj *a; + fz_obj *o; + char *s = *sp; + + error = fz_newarray(&a, 8); + if (error) return error; + *obj = a; + + s ++; /* skip '[' */ + + while (*s) + { + skipwhite(&s); + + if (*s == ']') { + s ++; + break; + } + + error = parseobj(&o, &s, v); + if (error) { *obj = nil; fz_dropobj(a); return error; } + + error = fz_arraypush(a, o); + if (error) { fz_dropobj(o); *obj = nil; fz_dropobj(a); return error; } + + fz_dropobj(o); + } + + *sp = s; + return nil; +} + +static fz_error *parsestring(fz_obj **obj, char **sp) +{ + char buf[512]; + char *s = *sp; + char *p = buf; + int balance = 1; + int oct; + + s ++; /* skip '(' */ + + while (*s && p < buf + sizeof buf) + { + if (*s == '(') + { + balance ++; + *p++ = *s++; + } + else if (*s == ')') + { + balance --; + *p++ = *s++; + } + else if (*s == '\\') + { + s ++; + if (*s >= '0' && *s <= '9') + { + oct = *s - '0'; + s ++; + if (*s >= '0' && *s <= '9') + { + oct = oct * 8 + (*s - '0'); + s ++; + if (*s >= '0' && *s <= '9') + { + oct = oct * 8 + (*s - '0'); + s ++; + } + } + *p++ = oct; + } + else switch (*s) + { + case 'n': *p++ = '\n'; s++; break; + case 'r': *p++ = '\r'; s++; break; + case 't': *p++ = '\t'; s++; break; + case 'b': *p++ = '\b'; s++; break; + case 'f': *p++ = '\f'; s++; break; + default: *p++ = *s++; break; + } + } + else + *p++ = *s++; + + if (balance == 0) + break; + } + + *sp = s; + return fz_newstring(obj, buf, p - buf - 1); +} + +static fz_error *parsehexstring(fz_obj **obj, char **sp) +{ + char buf[512]; + char *s = *sp; + char *p = buf; + int a, b; + + s ++; /* skip '<' */ + + while (*s && p < buf + sizeof buf) + { + skipwhite(&s); + if (*s == '>') { + s ++; + break; + } + a = *s++; + + if (*s == '\0') + break; + + skipwhite(&s); + if (*s == '>') { + s ++; + break; + } + b = *s++; + + *p++ = fromhex(a) * 16 + fromhex(b); + } + + *sp = s; + return fz_newstring(obj, buf, p - buf); +} + +static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v) +{ + fz_error *error; + char buf[32]; + int oid, gid, len; + char *tmp; + char *s = *sp; + + if (*s == '\0') + return fz_throw("syntaxerror in parseobj: end-of-string"); + + skipwhite(&s); + + error = nil; + + if (v != nil && *s == '%') + { + s ++; + switch (*s) + { + case 'p': error = fz_newpointer(obj, va_arg(v->ap, void*)); break; + case 'o': *obj = fz_keepobj(va_arg(v->ap, fz_obj*)); break; + case 'b': error = fz_newbool(obj, va_arg(v->ap, int)); break; + case 'i': error = fz_newint(obj, va_arg(v->ap, int)); break; + case 'f': error = fz_newreal(obj, (float)va_arg(v->ap, double)); break; + case 'n': error = fz_newname(obj, va_arg(v->ap, char*)); break; + case 'r': + oid = va_arg(v->ap, int); + gid = va_arg(v->ap, int); + error = fz_newindirect(obj, oid, gid); + break; + case 's': + tmp = va_arg(v->ap, char*); + error = fz_newstring(obj, tmp, strlen(tmp)); + break; + case '#': + tmp = va_arg(v->ap, char*); + len = va_arg(v->ap, int); + error = fz_newstring(obj, tmp, len); + break; + default: + error = fz_throw("unknown format specifier in packobj: '%c'", *s); + break; + } + s ++; + } + + else if (*s == '/') + error = parsename(obj, &s); + + else if (*s == '(') + error = parsestring(obj, &s); + + else if (*s == '<') { + if (s[1] == '<') + error = parsedict(obj, &s, v); + else + error = parsehexstring(obj, &s); + } + + else if (*s == '[') + error = parsearray(obj, &s, v); + + else if (*s == '-' || *s == '.' || (*s >= '0' && *s <= '9')) + error = parsenumber(obj, &s); + + else if (isregular(*s)) + { + parsekeyword(&s, buf, buf + sizeof buf); + + if (strcmp("true", buf) == 0) + error = fz_newbool(obj, 1); + else if (strcmp("false", buf) == 0) + error = fz_newbool(obj, 0); + else if (strcmp("null", buf) == 0) + error = fz_newnull(obj); + else + error = fz_throw("syntaxerror in parseobj: undefined keyword %s", buf); + } + + else + error = fz_throw("syntaxerror in parseobj"); + + *sp = s; + return error; +} + +fz_error * +fz_packobj(fz_obj **op, char *fmt, ...) +{ + fz_error *error; + struct vap v; + va_list ap; + + va_start(ap, fmt); + va_copy(v.ap, ap); + + error = parseobj(op, &fmt, &v); + + va_end(ap); + + return error; +} + +fz_error * +fz_parseobj(fz_obj **op, char *str) +{ + return parseobj(op, &str, nil); +} + diff --git a/rosapps/smartpdf/fitz/stream/obj_print.c b/rosapps/smartpdf/fitz/stream/obj_print.c new file mode 100644 index 00000000000..3207230663b --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/obj_print.c @@ -0,0 +1,337 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +struct fmt +{ + char *buf; + int cap; + int len; + int indent; + int tight; + int col; + int sep; + int last; +}; + +static void fmtobj(struct fmt *fmt, fz_obj *obj); + +static inline int iswhite(int ch) +{ + return + ch == '\000' || + ch == '\011' || + ch == '\012' || + ch == '\014' || + ch == '\015' || + ch == '\040'; +} + +static inline int isdelim(int ch) +{ + return ch == '(' || ch == ')' || + ch == '<' || ch == '>' || + ch == '[' || ch == ']' || + ch == '{' || ch == '}' || + ch == '/' || + ch == '%'; +} + +static inline void fmtputc(struct fmt *fmt, int c) +{ + if (fmt->sep && !isdelim(fmt->last) && !isdelim(c)) { + fmt->sep = 0; + fmtputc(fmt, ' '); + } + fmt->sep = 0; + + if (fmt->buf && fmt->len < fmt->cap) + fmt->buf[fmt->len] = c; + + if (c == '\n') + fmt->col = 0; + else + fmt->col ++; + + fmt->len ++; + + fmt->last = c; +} + +static void fmtindent(struct fmt *fmt) +{ + int i = fmt->indent; + while (i--) { + fmtputc(fmt, ' '); + fmtputc(fmt, ' '); + } +} + +static inline void fmtputs(struct fmt *fmt, char *s) +{ + while (*s) + fmtputc(fmt, *s++); +} + +static inline void fmtsep(struct fmt *fmt) +{ + fmt->sep = 1; +} + +static void fmtstr(struct fmt *fmt, fz_obj *obj) +{ + int i; + int c; + + fmtputc(fmt, '('); + for (i = 0; i < obj->u.s.len; i++) + { + c = (unsigned char) obj->u.s.buf[i]; + if (c == '\n') + fmtputs(fmt, "\\n"); + else if (c == '\r') + fmtputs(fmt, "\\r"); + else if (c == '\t') + fmtputs(fmt, "\\t"); + else if (c == '\b') + fmtputs(fmt, "\\b"); + else if (c == '\f') + fmtputs(fmt, "\\f"); + else if (c == '(') + fmtputs(fmt, "\\("); + else if (c == ')') + fmtputs(fmt, "\\)"); + else if (c < 32 || c > 126) { + char buf[16]; + fmtputc(fmt, '\\'); + sprintf(buf, "%o", c); + fmtputs(fmt, buf); + } + else + fmtputc(fmt, c); + } + fmtputc(fmt, ')'); +} + +static void fmthex(struct fmt *fmt, fz_obj *obj) +{ + int i; + int b; + int c; + + fmtputc(fmt, '<'); + for (i = 0; i < obj->u.s.len; i++) { + b = (unsigned char) obj->u.s.buf[i]; + c = (b >> 4) & 0x0f; + fmtputc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA); + c = (b) & 0x0f; + fmtputc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA); + } + fmtputc(fmt, '>'); +} + +static void fmtname(struct fmt *fmt, fz_obj *obj) +{ + char *s = fz_toname(obj); + int i, c; + + fmtputc(fmt, '/'); + + for (i = 0; s[i]; i++) + { + if (isdelim(s[i]) || iswhite(s[i])) + { + fmtputc(fmt, '#'); + c = (s[i] >> 4) & 0xf; + fmtputc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA); + c = s[i] & 0xf; + fmtputc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA); + } + else + { + fmtputc(fmt, s[i]); + } + } +} + +static void fmtarray(struct fmt *fmt, fz_obj *obj) +{ + int i; + + if (fmt->tight) { + fmtputc(fmt, '['); + for (i = 0; i < fz_arraylen(obj); i++) { + fmtobj(fmt, fz_arrayget(obj, i)); + fmtsep(fmt); + } + fmtputc(fmt, ']'); + } + else { + fmtputs(fmt, "[ "); + for (i = 0; i < fz_arraylen(obj); i++) { + if (fmt->col > 60) { + fmtputc(fmt, '\n'); + fmtindent(fmt); + } + fmtobj(fmt, fz_arrayget(obj, i)); + fmtputc(fmt, ' '); + } + fmtputc(fmt, ']'); + fmtsep(fmt); + } +} + +static void fmtdict(struct fmt *fmt, fz_obj *obj) +{ + int i; + fz_obj *key, *val; + + if (fmt->tight) { + fmtputs(fmt, "<<"); + for (i = 0; i < fz_dictlen(obj); i++) { + fmtobj(fmt, fz_dictgetkey(obj, i)); + fmtsep(fmt); + fmtobj(fmt, fz_dictgetval(obj, i)); + fmtsep(fmt); + } + fmtputs(fmt, ">>"); + } + else { + fmtputs(fmt, "<<\n"); + fmt->indent ++; + for (i = 0; i < fz_dictlen(obj); i++) { + key = fz_dictgetkey(obj, i); + val = fz_dictgetval(obj, i); + fmtindent(fmt); + fmtobj(fmt, key); + fmtputc(fmt, ' '); + if (fz_isarray(val)) + fmt->indent ++; + fmtobj(fmt, val); + fmtputc(fmt, '\n'); + if (fz_isarray(val)) + fmt->indent --; + } + fmt->indent --; + fmtindent(fmt); + fmtputs(fmt, ">>"); + } +} + +static void fmtobj(struct fmt *fmt, fz_obj *obj) +{ + char buf[256]; + + if (!obj) { + fmtputs(fmt, ""); + return; + } + + switch (obj->kind) + { + case FZ_NULL: + fmtputs(fmt, "null"); + break; + case FZ_BOOL: + fmtputs(fmt, fz_tobool(obj) ? "true" : "false"); + break; + case FZ_INT: + sprintf(buf, "%d", fz_toint(obj)); + fmtputs(fmt, buf); + break; + case FZ_REAL: + sprintf(buf, "%g", fz_toreal(obj)); + if (strchr(buf, 'e')) /* bad news! */ + sprintf(buf, fabs(fz_toreal(obj)) > 1 ? "%1.1f" : "%1.8f", fz_toreal(obj)); + fmtputs(fmt, buf); + break; + case FZ_STRING: + { + int added = 0; + int i, c; + for (i = 0; i < obj->u.s.len; i++) { + c = (unsigned char)obj->u.s.buf[i]; + if (strchr("()\\\n\r\t\b\f", c) != 0) + added ++; + else if (c < 8) + added ++; + else if (c < 32) + added += 2; + else if (c >= 127) + added += 3; + } + if (added < obj->u.s.len) + fmtstr(fmt, obj); + else + fmthex(fmt, obj); + } + break; + case FZ_NAME: + fmtname(fmt, obj); + break; + case FZ_ARRAY: + fmtarray(fmt, obj); + break; + case FZ_DICT: + fmtdict(fmt, obj); + break; + case FZ_INDIRECT: + sprintf(buf, "%d %d R", obj->u.r.oid, obj->u.r.gid); + fmtputs(fmt, buf); + break; + case FZ_POINTER: + sprintf(buf, "$%p", obj->u.p); + fmtputs(fmt, buf); + break; + default: + sprintf(buf, "", obj->kind); + fmtputs(fmt, buf); + break; + } +} + +int +fz_sprintobj(char *s, int n, fz_obj *obj, int tight) +{ + struct fmt fmt; + + fmt.indent = 0; + fmt.col = 0; + fmt.sep = 0; + fmt.last = 0; + + fmt.tight = tight; + fmt.buf = s; + fmt.cap = n; + fmt.len = 0; + fmtobj(&fmt, obj); + + if (fmt.buf && fmt.len < fmt.cap) + fmt.buf[fmt.len] = '\0'; + + return fmt.len; +} + +void +fz_debugobj(fz_obj *obj) +{ + char buf[1024]; + char *ptr; + int n; + + n = fz_sprintobj(nil, 0, obj, 0); + if (n < sizeof buf) + { + fz_sprintobj(buf, sizeof buf, obj, 0); + fwrite(buf, 1, n, stdout); + } + else + { + ptr = fz_malloc(n); + if (!ptr) + return; + fz_sprintobj(ptr, n, obj, 0); + fwrite(ptr, 1, n, stdout); + fz_free(ptr); + } +} + diff --git a/rosapps/smartpdf/fitz/stream/obj_simple.c b/rosapps/smartpdf/fitz/stream/obj_simple.c new file mode 100644 index 00000000000..f47b881774b --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/obj_simple.c @@ -0,0 +1,374 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +extern void fz_droparray(fz_obj *array); +extern void fz_dropdict(fz_obj *dict); + +//#define DO_OBJ_STATS 1 + +#ifdef DO_OBJ_STATS +static int objstats[FZ_POINTER+1]; +static int intsLessThan65k; + +static const char *getTypeName(int type) +{ + switch (type) { + case FZ_NULL: + return "FZ_NULL"; + case FZ_BOOL: + return "FZ_BOOL"; + case FZ_INT: + return "FZ_INT"; + case FZ_REAL: + return "FZ_REAL"; + case FZ_STRING: + return "FZ_STRING"; + case FZ_NAME: + return "FZ_NAME"; + case FZ_ARRAY: + return "FZ_ARRAY"; + case FZ_DICT: + return "FZ_DICT"; + case FZ_INDIRECT: + return "FZ_INDIRECT"; + case FZ_POINTER: + return "FZ_POINTER"; + } + return "unknown"; +} + +void dump_type_stats(void) +{ + int i; + int total = 0; + int val; + double percent; + + for (i = FZ_NULL; i <= FZ_POINTER; i++) { + total += objstats[i]; + } + + printf("total: %d\n", total); + for (i = FZ_NULL; i <= FZ_POINTER; i++) { + val = objstats[i]; + percent = ((double)val * 100.0) / (double)total; + printf("%5d %.2f%% %s\n", val, percent, getTypeName(i)); + } + val = intsLessThan65k; + percent = ((double)val * 100.0) / (double)total; + printf("%5d %.2f%% %s\n", val, percent, "intsLessThan65k"); +} +#else +void dump_type_stats(void) +{ +} +#endif + +#ifdef DO_OBJ_STATS +#define NEWOBJ(KIND,SIZE) \ + fz_obj *o; \ + o = *op = fz_malloc(SIZE); \ + if (!o) return fz_outofmem; \ + o->refs = 1; \ + o->kind = KIND; \ + objstats[KIND]++; +#else +#define NEWOBJ(KIND,SIZE) \ + fz_obj *o; \ + o = *op = fz_malloc(SIZE); \ + if (!o) return fz_outofmem; \ + o->refs = 1; \ + o->kind = KIND; +#endif + +fz_error * +fz_newnull(fz_obj **op) +{ + NEWOBJ(FZ_NULL, sizeof (fz_obj)); + return nil; +} + +fz_error * +fz_newbool(fz_obj **op, int b) +{ + NEWOBJ(FZ_BOOL, sizeof (fz_obj)); + o->u.b = b; + return nil; +} + +fz_error * +fz_newint(fz_obj **op, int i) +{ + NEWOBJ(FZ_INT, sizeof (fz_obj)); + o->u.i = i; +#ifdef DO_OBJ_STATS + if (i < 65536) + ++intsLessThan65k; +#endif DO_OBJ_STATS + return nil; +} + +fz_error * +fz_newreal(fz_obj **op, float f) +{ + NEWOBJ(FZ_REAL, sizeof (fz_obj)); + o->u.f = f; + return nil; +} + +fz_error * +fz_newstring(fz_obj **op, char *str, int len) +{ + NEWOBJ(FZ_STRING, offsetof(fz_obj, u.s.buf) + len + 1); + o->u.s.len = len; + memcpy(o->u.s.buf, str, len); + o->u.s.buf[len] = '\0'; + return nil; +} + +fz_error * +fz_newname(fz_obj **op, char *str) +{ + NEWOBJ(FZ_NAME, offsetof(fz_obj, u.n) + strlen(str) + 1); + strcpy(o->u.n, str); + return nil; +} + +fz_error * +fz_newindirect(fz_obj **op, int objid, int genid) +{ + NEWOBJ(FZ_INDIRECT, sizeof (fz_obj)); + o->u.r.oid = objid; + o->u.r.gid = genid; + return nil; +} + +fz_error * +fz_newpointer(fz_obj **op, void *p) +{ + NEWOBJ(FZ_POINTER, sizeof (fz_obj)); + o->u.p = p; + return nil; +} + +fz_obj * +fz_keepobj(fz_obj *o) +{ + assert(o != nil); + assert(o->refs > 0); + o->refs ++; + return o; +} + +void +fz_dropobj(fz_obj *o) +{ + assert(o != nil); + assert(o->refs > 0); + if (--o->refs == 0) + { + if (o->kind == FZ_ARRAY) + fz_droparray(o); + else if (o->kind == FZ_DICT) + fz_dropdict(o); + else + fz_free(o); + } +} + +int +fz_isnull(fz_obj *obj) +{ + return obj ? obj->kind == FZ_NULL : 0; +} + +int +fz_isbool(fz_obj *obj) +{ + return obj ? obj->kind == FZ_BOOL : 0; +} + +int +fz_isint(fz_obj *obj) +{ + return obj ? obj->kind == FZ_INT : 0; +} + +int +fz_isreal(fz_obj *obj) +{ + return obj ? obj->kind == FZ_REAL : 0; +} + +int +fz_isstring(fz_obj *obj) +{ + return obj ? obj->kind == FZ_STRING : 0; +} + +int +fz_isname(fz_obj *obj) +{ + return obj ? obj->kind == FZ_NAME : 0; +} + +int +fz_isarray(fz_obj *obj) +{ + return obj ? obj->kind == FZ_ARRAY : 0; +} + +int +fz_isdict(fz_obj *obj) +{ + return obj ? obj->kind == FZ_DICT : 0; +} + +int +fz_isindirect(fz_obj *obj) +{ + return obj ? obj->kind == FZ_INDIRECT : 0; +} + +int +fz_ispointer(fz_obj *obj) +{ + return obj ? obj->kind == FZ_POINTER : 0; +} + +int +fz_tobool(fz_obj *obj) +{ + if (fz_isbool(obj)) + return obj->u.b; + return 0; +} + +int +fz_toint(fz_obj *obj) +{ + if (fz_isint(obj)) + return obj->u.i; + if (fz_isreal(obj)) + return obj->u.f; + return 0; +} + +float +fz_toreal(fz_obj *obj) +{ + if (fz_isreal(obj)) + return obj->u.f; + if (fz_isint(obj)) + return obj->u.i; + return 0; +} + +char * +fz_toname(fz_obj *obj) +{ + if (fz_isname(obj)) + return obj->u.n; + return ""; +} + +char * +fz_tostrbuf(fz_obj *obj) +{ + if (fz_isstring(obj)) + return obj->u.s.buf; + return ""; +} + +int +fz_tostrlen(fz_obj *obj) +{ + if (fz_isstring(obj)) + return obj->u.s.len; + return 0; +} + +int +fz_tonum(fz_obj *obj) +{ + if (fz_isindirect(obj)) + return obj->u.r.oid; + return 0; +} + +int +fz_togen(fz_obj *obj) +{ + if (fz_isindirect(obj)) + return obj->u.r.gid; + return 0; +} + +void * +fz_topointer(fz_obj *obj) +{ + if (fz_ispointer(obj)) + return obj->u.p; + return nil; +} + +fz_error * +fz_newnamefromstring(fz_obj **op, fz_obj *str) +{ + NEWOBJ(FZ_NAME, offsetof(fz_obj, u.n) + fz_tostrlen(str) + 1); + memcpy(o->u.n, fz_tostrbuf(str), fz_tostrlen(str)); + o->u.n[fz_tostrlen(str)] = '\0'; + return nil; +} + +int +fz_objcmp(fz_obj *a, fz_obj *b) +{ + int i; + + if (a == b) + return 0; + if (a->kind != b->kind) + return 1; + + switch (a->kind) + { + case FZ_NULL: return 0; + case FZ_BOOL: return a->u.b - b->u.b; + case FZ_INT: return a->u.i - b->u.i; + case FZ_REAL: return a->u.f - b->u.f; + case FZ_STRING: + if (a->u.s.len != b->u.s.len) + return a->u.s.len - b->u.s.len; + return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len); + case FZ_NAME: + return strcmp(a->u.n, b->u.n); + + case FZ_INDIRECT: + if (a->u.r.oid == b->u.r.oid) + return a->u.r.gid - b->u.r.gid; + return a->u.r.oid - b->u.r.oid; + + case FZ_ARRAY: + if (a->u.a.len != b->u.a.len) + return a->u.a.len - b->u.a.len; + for (i = 0; i < a->u.a.len; i++) + if (fz_objcmp(a->u.a.items[i], b->u.a.items[i])) + return 1; + return 0; + + case FZ_DICT: + if (a->u.d.len != b->u.d.len) + return a->u.d.len - b->u.d.len; + for (i = 0; i < a->u.d.len; i++) + { + if (fz_objcmp(a->u.d.items[i].k, b->u.d.items[i].k)) + return 1; + if (fz_objcmp(a->u.d.items[i].v, b->u.d.items[i].v)) + return 1; + } + return 0; + } + return 1; +} + diff --git a/rosapps/smartpdf/fitz/stream/stm_buffer.c b/rosapps/smartpdf/fitz/stream/stm_buffer.c new file mode 100644 index 00000000000..4fc5636c51d --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/stm_buffer.c @@ -0,0 +1,94 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +fz_error * +fz_newbuffer(fz_buffer **bp, int size) +{ + fz_buffer *b; + + b = *bp = fz_malloc(sizeof(fz_buffer)); + if (!b) return fz_outofmem; + + b->refs = 1; + b->ownsdata = 1; + b->bp = fz_malloc(size); + if (!b->bp) { fz_free(b); return fz_outofmem; } + + b->rp = b->bp; + b->wp = b->bp; + b->ep = b->bp + size; + b->eof = 0; + + return nil; +} + +fz_error * +fz_newbufferwithmemory(fz_buffer **bp, unsigned char *data, int size) +{ + fz_buffer *b; + + b = *bp = fz_malloc(sizeof(fz_buffer)); + if (!b) return fz_outofmem; + + b->refs = 1; + b->ownsdata = 0; + b->bp = data; + + b->rp = b->bp; + b->wp = b->bp + size; + b->ep = b->bp + size; + b->eof = 0; + + return nil; +} + +fz_buffer * +fz_keepbuffer(fz_buffer *buf) +{ + buf->refs ++; + return buf; +} + +void +fz_dropbuffer(fz_buffer *buf) +{ + if (--buf->refs == 0) + { + if (buf->ownsdata) + fz_free(buf->bp); + fz_free(buf); + } +} + +fz_error * +fz_growbuffer(fz_buffer *buf) +{ + unsigned char *newbp; + + int rp = buf->rp - buf->bp; + int wp = buf->wp - buf->bp; + int ep = buf->ep - buf->bp; + + assert(buf->ownsdata); + + newbp = fz_realloc(buf->bp, ep * 2); + if (!newbp) return fz_outofmem; + + buf->bp = newbp; + buf->rp = buf->bp + rp; + buf->wp = buf->bp + wp; + buf->ep = buf->bp + ep * 2; + + return nil; +} + +fz_error * +fz_rewindbuffer(fz_buffer *buf) +{ + assert(buf->ownsdata); + memmove(buf->bp, buf->rp, buf->wp - buf->rp); + buf->wp = buf->bp + (buf->wp - buf->rp); + buf->rp = buf->bp; + return nil; +} + diff --git a/rosapps/smartpdf/fitz/stream/stm_filter.c b/rosapps/smartpdf/fitz/stream/stm_filter.c new file mode 100644 index 00000000000..c809113685f --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/stm_filter.c @@ -0,0 +1,52 @@ +#include "fitz-base.h" +#include "fitz-stream.h" + +fz_error fz_kioneedin = { -1, "", "", "filter.c", 0 }; +fz_error fz_kioneedout = { -1, "", "", "filter.c", 0 }; +fz_error fz_kiodone = { -1, "", "", "filter.c", 0 }; + +fz_error * +fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out) +{ + fz_error *reason; + unsigned char *oldrp; + unsigned char *oldwp; + + assert(!out->eof); + + oldrp = in->rp; + oldwp = out->wp; + + reason = f->process(f, in, out); + + assert(in->rp <= in->wp); + assert(out->wp <= out->ep); + + f->consumed = in->rp > oldrp; + f->produced = out->wp > oldwp; + f->count += out->wp - oldwp; + + if (reason != fz_ioneedin && reason != fz_ioneedout) + out->eof = 1; + + return reason; +} + +fz_filter * +fz_keepfilter(fz_filter *f) +{ + f->refs ++; + return f; +} + +void +fz_dropfilter(fz_filter *f) +{ + if (--f->refs == 0) + { + if (f->drop) + f->drop(f); + fz_free(f); + } +} + diff --git a/rosapps/smartpdf/fitz/stream/stm_misc.c b/rosapps/smartpdf/fitz/stream/stm_misc.c new file mode 100644 index 00000000000..23e25729679 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/stm_misc.c @@ -0,0 +1,194 @@ +/* + * Miscellaneous I/O functions + */ + +#include "fitz-base.h" +#include "fitz-stream.h" + +int fz_tell(fz_stream *stm) +{ + if (stm->mode == FZ_SREAD) + return fz_rtell(stm); + return fz_wtell(stm); +} + +int fz_seek(fz_stream *stm, int offset, int whence) +{ + if (stm->mode == FZ_SREAD) + return fz_rseek(stm, offset, whence); + return fz_wseek(stm, offset, whence); +} + +/* + * Read a line terminated by LF or CR or CRLF. + */ + +int fz_readline(fz_stream *stm, char *mem, int n) +{ + char *s = mem; + int c = EOF; + while (n > 1) + { + c = fz_readbyte(stm); + if (c == EOF) + break; + if (c == '\r') { + c = fz_peekbyte(stm); + if (c == '\n') + c = fz_readbyte(stm); + break; + } + if (c == '\n') + break; + *s++ = c; + n--; + } + if (n) + *s = '\0'; + return s - mem; +} + +struct fz_linkedbuf_s +{ + int len; + struct fz_linkedbuf_s * next; +}; + +typedef struct fz_linkedbuf_s fz_linkedbuf; + +fz_error *fz_newlinkedbuf(fz_linkedbuf **bufp, int len, unsigned char **data) +{ + fz_linkedbuf *buf; + + buf = *bufp = fz_malloc(sizeof(fz_linkedbuf) + len); + if (!buf) return fz_outofmem; + buf->next = nil; + buf->len = len; + *data = (unsigned char*)buf + sizeof(fz_linkedbuf); + return nil; +} + +fz_error *fz_growlinkedbuf(fz_linkedbuf *buf, int len, unsigned char **data) +{ + fz_linkedbuf *newbuf; + fz_error *error; + + error = fz_newlinkedbuf(&newbuf, len, data); + if (error) return error; + while (buf->next) + buf = buf->next; + buf->next = newbuf; + return nil; +} + +void fz_droplinkedbuf(fz_linkedbuf *buf) +{ + fz_linkedbuf *next; + while (buf) { + next = buf->next; + fz_free(buf); + buf = next; + } +} + +int fz_linkedbuflen(fz_linkedbuf *buf) +{ + int len = 0; + while (buf) { + len += buf->len; + buf = buf->next; + } + return len; +} + +fz_error *fz_linearizelinkedbuf(fz_linkedbuf *buf, int len, unsigned char **datap) +{ + unsigned char *data, *bufdata; + int tocopy; + int buflen = fz_linkedbuflen(buf); + assert(len <= buflen); + data = *datap = fz_malloc(len); + if (!data) return fz_outofmem; + + while (len > 0) + { + bufdata = (unsigned char*)buf + sizeof(fz_linkedbuf); + tocopy = MIN(len, buf->len); + memmove(data, bufdata, tocopy); + buf = buf->next; + data += tocopy; + len -= tocopy; + } + return nil; +} + +/* + * Utility function to consume all the contents of an input stream into + * a freshly allocated buffer; realloced and trimmed to size. + */ + +enum { MINCHUNKSIZE = 1024 * 8 }; +enum { MAXCHUNKSIZE = MINCHUNKSIZE * 10 }; + +int fz_readall(fz_buffer **bufp, fz_stream *stm) +{ + fz_buffer *real; + fz_error *error; + fz_linkedbuf *buf; + unsigned char *data; + int totallen; + int n; + int chunksize = MINCHUNKSIZE; + + *bufp = nil; + + totallen = 0; + error = fz_newlinkedbuf(&buf, chunksize, &data); + if (error) + return -1; + + while (1) + { + n = fz_read(stm, data, chunksize); + if (n < 0) + { + fz_free(buf); + return -1; + } + + totallen += n; + if (n != chunksize) + break; + + if (chunksize < MAXCHUNKSIZE) + chunksize = chunksize + MINCHUNKSIZE; + error = fz_growlinkedbuf(buf, chunksize, &data); + if (error) + { + fz_droplinkedbuf(buf); + return -1; + } + } + + error = fz_linearizelinkedbuf(buf, totallen, &data); + fz_droplinkedbuf(buf); + if (error) + return -1; + + real = *bufp = fz_malloc(sizeof(fz_buffer)); + if (!real) + { + fz_free(data); + return -1; + } + + real->refs = 1; + real->ownsdata = 1; + real->bp = data; + real->rp = data; + real->wp = data + totallen; + real->ep = data + totallen; + real->eof = 1; + return totallen; +} + diff --git a/rosapps/smartpdf/fitz/stream/stm_open.c b/rosapps/smartpdf/fitz/stream/stm_open.c new file mode 100644 index 00000000000..6481288ad69 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/stm_open.c @@ -0,0 +1,223 @@ +/* + * Creation and destruction. + */ + +#include "fitz-base.h" +#include "fitz-stream.h" + +static fz_stream * +newstm(int kind, int mode) +{ + fz_stream *stm; + + stm = fz_malloc(sizeof(fz_stream)); + if (!stm) + return nil; + + stm->refs = 1; + stm->kind = kind; + stm->mode = mode; + stm->dead = 0; + stm->error = nil; + stm->buffer = nil; + + stm->chain = nil; + stm->filter = nil; + stm->file = -1; + + return stm; +} + +fz_error * +fz_ioerror(fz_stream *stm) +{ + fz_error *error; + if (stm->error) + { + error = stm->error; + stm->error = nil; + return error; + } + return fz_throw("ioerror: no error"); +} + +fz_stream * +fz_keepstream(fz_stream *stm) +{ + stm->refs ++; + return stm; +} + +void +fz_dropstream(fz_stream *stm) +{ + stm->refs --; + if (stm->refs == 0) + { + if (stm->error) + { + fz_warn("unhandled %s", stm->error->msg); + fz_droperror(stm->error); + } + + if (stm->mode == FZ_SWRITE) + { + stm->buffer->eof = 1; + fz_flush(stm); + } + + switch (stm->kind) + { + case FZ_SFILE: + close(stm->file); + break; + case FZ_SFILTER: + fz_dropfilter(stm->filter); + fz_dropstream(stm->chain); + break; + case FZ_SBUFFER: + break; + } + + fz_dropbuffer(stm->buffer); + fz_free(stm); + } +} + +static fz_error * +openfile(fz_stream **stmp, char *path, int mode, int realmode) +{ + fz_error *error; + fz_stream *stm; + + stm = newstm(FZ_SFILE, mode); + if (!stm) + return fz_outofmem; + + error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE); + if (error) + { + fz_free(stm); + return error; + } + + stm->file = open(path, realmode, 0666); + if (stm->file < 0) + { + fz_dropbuffer(stm->buffer); + fz_free(stm); + return fz_throw("ioerror: open '%s' failed: %s", path, strerror(errno)); + } + + *stmp = stm; + return nil; +} + +static fz_error * +openfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src, int mode) +{ + fz_error *error; + fz_stream *stm; + + stm = newstm(FZ_SFILTER, mode); + if (!stm) + return fz_outofmem; + + error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE); + if (error) + { + fz_free(stm); + return error; + } + + stm->chain = fz_keepstream(src); + stm->filter = fz_keepfilter(flt); + + *stmp = stm; + return nil; +} + +static fz_error * +openbuffer(fz_stream **stmp, fz_buffer *buf, int mode) +{ + fz_stream *stm; + + stm = newstm(FZ_SBUFFER, mode); + if (!stm) + return fz_outofmem; + + stm->buffer = fz_keepbuffer(buf); + + if (mode == FZ_SREAD) + stm->buffer->eof = 1; + + *stmp = stm; + return nil; +} + +fz_error * fz_openrfile(fz_stream **stmp, char *path) +{ + return openfile(stmp, path, FZ_SREAD, O_BINARY | O_RDONLY); +} + +fz_error * fz_openwfile(fz_stream **stmp, char *path) +{ + return openfile(stmp, path, FZ_SWRITE, + O_BINARY | O_WRONLY | O_CREAT | O_TRUNC); +} + +fz_error * fz_openafile(fz_stream **stmp, char *path) +{ + fz_error *error; + int t; + + error = openfile(stmp, path, FZ_SWRITE, O_BINARY | O_WRONLY); + if (error) + return error; + + t = lseek((*stmp)->file, 0, 2); + if (t < 0) + { + (*stmp)->dead = 1; + return fz_throw("ioerror: lseek: %s", strerror(errno)); + } + + return nil; +} + +fz_error * fz_openrfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src) +{ + return openfilter(stmp, flt, src, FZ_SREAD); +} + +fz_error * fz_openwfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src) +{ + return openfilter(stmp, flt, src, FZ_SWRITE); +} + +fz_error * fz_openrbuffer(fz_stream **stmp, fz_buffer *buf) +{ + return openbuffer(stmp, buf, FZ_SREAD); +} + +fz_error * fz_openwbuffer(fz_stream **stmp, fz_buffer *buf) +{ + return openbuffer(stmp, buf, FZ_SWRITE); +} + +fz_error * fz_openrmemory(fz_stream **stmp, char *mem, int len) +{ + fz_error *error; + fz_buffer *buf; + + error = fz_newbufferwithmemory(&buf, mem, len); + if (error) + return error; + + error = fz_openrbuffer(stmp, buf); + + fz_dropbuffer(buf); + + return error; +} + diff --git a/rosapps/smartpdf/fitz/stream/stm_read.c b/rosapps/smartpdf/fitz/stream/stm_read.c new file mode 100644 index 00000000000..12e6a2889ec --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/stm_read.c @@ -0,0 +1,263 @@ +/* + * Input streams. + */ + +#include "fitz-base.h" +#include "fitz-stream.h" + +int +fz_makedata(fz_stream *stm) +{ + fz_buffer *buf = stm->buffer; + fz_error *error; + fz_error *reason; + int produced; + int n; + + if (stm->dead) + return -1; + + if (stm->mode != FZ_SREAD) + return -1; + + if (buf->eof) + return 0; + + error = fz_rewindbuffer(buf); + if (error) + goto cleanup; + + if (buf->ep - buf->wp == 0) + { + error = fz_growbuffer(buf); + if (error) + goto cleanup; + } + + switch (stm->kind) + { + + case FZ_SFILE: + n = read(stm->file, buf->wp, buf->ep - buf->wp); + if (n == -1) + { + stm->error = fz_throw("ioerror: read: %s", strerror(errno)); + stm->dead = 1; + return -1; + } + if (n == 0) + buf->eof = 1; + buf->wp += n; + return n; + + case FZ_SFILTER: + produced = 0; + + while (1) + { + reason = fz_process(stm->filter, stm->chain->buffer, buf); + + if (stm->filter->produced) + produced = 1; + + if (reason == fz_ioneedin) + { + if (fz_makedata(stm->chain) < 0) + { + stm->dead = 1; + return -1; + } + } + + else if (reason == fz_ioneedout) + { + if (produced) + return 0; + + if (buf->rp > buf->bp) + { + error = fz_rewindbuffer(buf); + if (error) + goto cleanup; + } + else + { + error = fz_growbuffer(buf); + if (error) + goto cleanup; + } + } + + else if (reason == fz_iodone) + { + return 0; + } + + else + { + error = reason; + goto cleanup; + } + } + + case FZ_SBUFFER: + return 0; + } + + return -1; + +cleanup: + stm->error = error; + stm->dead = 1; + return -1; +} + +int fz_rtell(fz_stream *stm) +{ + fz_buffer *buf = stm->buffer; + int t; + + if (stm->dead) + return -1; + + if (stm->mode != FZ_SREAD) + return -1; + + switch (stm->kind) + { + case FZ_SFILE: + t = lseek(stm->file, 0, 1); + if (t < 0) + { + stm->dead = 1; + return -1; + } + return t - (buf->wp - buf->rp); + + case FZ_SFILTER: + return stm->filter->count - (buf->wp - buf->rp); + + case FZ_SBUFFER: + return buf->rp - buf->bp; + } + + return -1; +} + +int fz_rseek(fz_stream *stm, int offset, int whence) +{ + fz_buffer *buf = stm->buffer; + int t, c; + + if (stm->dead) + return -1; + + if (stm->mode != FZ_SREAD) + return -1; + + if (whence == 1) + { + int cur = fz_rtell(stm); + if (cur < 0) + return -1; + offset = cur + offset; + whence = 0; + } + + buf->eof = 0; + + switch (stm->kind) + { + case FZ_SFILE: + t = lseek(stm->file, offset, whence); + if (t < 0) + { + stm->error = fz_throw("ioerror: lseek: %s", strerror(errno)); + stm->dead = 1; + return -1; + } + + buf->rp = buf->bp; + buf->wp = buf->bp; + + return t; + + case FZ_SFILTER: + if (whence == 0) + { + if (offset < fz_tell(stm)) + { + stm->error = fz_throw("ioerror: cannot seek back in filter"); + stm->dead = 1; + return -1; + } + while (fz_tell(stm) < offset) + { + c = fz_readbyte(stm); + if (c == EOF) + break; + } + return fz_tell(stm); + } + else + { + stm->dead = 1; + return -1; + } + + case FZ_SBUFFER: + if (whence == 0) + buf->rp = CLAMP(buf->bp + offset, buf->bp, buf->ep); + else + buf->rp = CLAMP(buf->ep + offset, buf->bp, buf->ep); + return buf->rp - buf->bp; + } + + return -1; +} + +int fz_readbytex(fz_stream *stm) +{ + fz_buffer *buf = stm->buffer; + if (buf->rp == buf->wp) + { + if (buf->eof) return EOF; + if (fz_makedata(stm) < 0) return EOF; + } + if (buf->rp < buf->wp) + return *buf->rp++; + return EOF; +} + +int fz_peekbytex(fz_stream *stm) +{ + fz_buffer *buf = stm->buffer; + if (buf->rp == buf->wp) + { + if (buf->eof) return EOF; + if (fz_makedata(stm) < 0) return EOF; + } + if (buf->rp < buf->wp) + return *buf->rp; + return EOF; +} + +int fz_read(fz_stream *stm, unsigned char *mem, int n) +{ + fz_buffer *buf = stm->buffer; + int i = 0; + + while (i < n) + { + while (buf->rp < buf->wp && i < n) + mem[i++] = *buf->rp++; + if (buf->rp == buf->wp) + { + if (buf->eof) return i; + if (fz_makedata(stm) < 0) return -1; + } + } + + return i; +} + diff --git a/rosapps/smartpdf/fitz/stream/stm_write.c b/rosapps/smartpdf/fitz/stream/stm_write.c new file mode 100644 index 00000000000..d4eb99af668 --- /dev/null +++ b/rosapps/smartpdf/fitz/stream/stm_write.c @@ -0,0 +1,280 @@ +/* + * Output streams. + */ + +#include "fitz-base.h" +#include "fitz-stream.h" + +int fz_wtell(fz_stream *stm) +{ + fz_buffer *buf = stm->buffer; + int t; + + if (stm->dead) + return -1; + + if (stm->mode != FZ_SWRITE) + return -1; + + switch (stm->kind) + { + case FZ_SFILE: + t = lseek(stm->file, 0, 1); + if (t < 0) + { + stm->error = fz_throw("ioerror: lseek: %s", strerror(errno)); + stm->dead = 1; + return -1; + } + return t + (buf->wp - buf->rp); + + case FZ_SFILTER: + return stm->filter->count + (buf->wp - buf->rp); + + case FZ_SBUFFER: + return buf->wp - buf->bp; + } + + return -1; +} + +int fz_wseek(fz_stream *stm, int offset, int whence) +{ + fz_buffer *buf = stm->buffer; + int t; + + if (stm->dead) + return -1; + + if (stm->mode != FZ_SWRITE) + return -1; + + if (stm->kind != FZ_SFILE) + return -1; + + t = lseek(stm->file, offset, whence); + if (t < 0) + { + stm->error = fz_throw("ioerror: lseek: %s", strerror(errno)); + stm->dead = 1; + return -1; + } + + buf->rp = buf->bp; + buf->wp = buf->bp; + buf->eof = 0; + + return t; +} + +static int flushfilter(fz_stream *stm) +{ + fz_buffer *buf = stm->buffer; + fz_error *error; + fz_error *reason; + int t; + +loop: + + reason = fz_process(stm->filter, stm->buffer, stm->chain->buffer); + + if (reason == fz_ioneedin) + { + if (buf->rp > buf->ep) + fz_rewindbuffer(buf); + else + { + error = fz_growbuffer(buf); + if (error) + goto cleanup; + } + } + + else if (reason == fz_ioneedout) + { + t = fz_flush(stm->chain); + if (t < 0) + return -1; + } + + else if (reason == fz_iodone) + { + stm->dead = 2; /* special flag that we are dead because of eod */ + } + + else + { + error = reason; + goto cleanup; + } + + /* if we are at eof, repeat until other filter sets otherside to eof */ + if (buf->eof && !stm->chain->buffer->eof) + goto loop; + + return 0; + +cleanup: + stm->error = error; + stm->dead = 1; + return -1; +} + +/* + * Empty the buffer into the sink. + * Promise to make more space available. + * Called by fz_write and fz_dropstream. + * If buffer is eof, then all data must be flushed. + */ +int fz_flush(fz_stream *stm) +{ + fz_buffer *buf = stm->buffer; + fz_error *error; + int t; + + if (stm->dead == 2) + return 0; + + if (stm->dead) + return -1; + + if (stm->mode != FZ_SWRITE) + return -1; + + switch (stm->kind) + { + case FZ_SFILE: + while (buf->rp < buf->wp) + { + t = write(stm->file, buf->rp, buf->wp - buf->rp); + if (t < 0) + { + stm->error = fz_throw("ioerror: write: %s", strerror(errno)); + stm->dead = 1; + return -1; + } + + buf->rp += t; + } + + if (buf->rp > buf->bp) + fz_rewindbuffer(buf); + + return 0; + + case FZ_SFILTER: + return flushfilter(stm); + + case FZ_SBUFFER: + if (!buf->eof && buf->wp == buf->ep) + { + error = fz_growbuffer(buf); + if (error) + { + stm->error = error; + stm->dead = 1; + return -1; + } + } + return 0; + } + + return -1; +} + +/* + * Write data to stream. + * Buffer until internal buffer is full. + * When full, call fz_flush to make more space available. + */ +int fz_write(fz_stream *stm, unsigned char *mem, int n) +{ + fz_buffer *buf = stm->buffer; + int i = 0; + int t; + + if (stm->dead == 2) + return 0; + + if (stm->dead) + return -1; + + if (stm->mode != FZ_SWRITE) + return -1; + + while (i < n) + { + while (buf->wp < buf->ep && i < n) + *buf->wp++ = mem[i++]; + + if (buf->wp == buf->ep && i < n) + { + t = fz_flush(stm); + if (t < 0) + return -1; + if (stm->dead) + return i; + } + } + + return n; +} + +int fz_printstr(fz_stream *stm, char *s) +{ + return fz_write(stm, s, strlen(s)); +} + +int fz_printobj(fz_stream *file, fz_obj *obj, int tight) +{ + char buf[1024]; + char *ptr; + int n; + + n = fz_sprintobj(nil, 0, obj, tight); + if (n < sizeof buf) + { + fz_sprintobj(buf, sizeof buf, obj, tight); + return fz_write(file, buf, n); + } + else + { + ptr = fz_malloc(n); + if (!ptr) + return -1; + fz_sprintobj(ptr, n, obj, tight); + n = fz_write(file, ptr, n); + fz_free(ptr); + return n; + } +} + +int fz_print(fz_stream *stm, char *fmt, ...) +{ + va_list ap; + char buf[1024]; + char *p; + int n; + + va_start(ap, fmt); + n = vsnprintf(buf, sizeof buf, fmt, ap); + va_end(ap); + + if (n < sizeof buf) + return fz_write(stm, buf, n); + + p = fz_malloc(n); + if (!p) + return -1; + + va_start(ap, fmt); + vsnprintf(p, n, fmt, ap); + va_end(ap); + + n = fz_write(stm, p, n); + + fz_free(p); + + return n; +} + diff --git a/rosapps/smartpdf/fitz/world/node_misc1.c b/rosapps/smartpdf/fitz/world/node_misc1.c new file mode 100644 index 00000000000..8884c66c7a4 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_misc1.c @@ -0,0 +1,191 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +void fz_dropmetanode(fz_metanode* node); +void fz_droplinknode(fz_linknode* node); +void fz_droppathnode(fz_pathnode* node); +void fz_droptextnode(fz_textnode* node); +void fz_dropimagenode(fz_imagenode* node); +void fz_dropshadenode(fz_shadenode* node); + +fz_rect fz_boundtransformnode(fz_transformnode* node, fz_matrix ctm); +fz_rect fz_boundovernode(fz_overnode* node, fz_matrix ctm); +fz_rect fz_boundmasknode(fz_masknode* node, fz_matrix ctm); +fz_rect fz_boundblendnode(fz_blendnode* node, fz_matrix ctm); +fz_rect fz_boundsolidnode(fz_solidnode* node, fz_matrix ctm); +fz_rect fz_boundpathnode(fz_pathnode* node, fz_matrix ctm); +fz_rect fz_boundtextnode(fz_textnode* node, fz_matrix ctm); +fz_rect fz_boundimagenode(fz_imagenode* node, fz_matrix ctm); +fz_rect fz_boundshadenode(fz_shadenode* node, fz_matrix ctm); +fz_rect fz_boundlinknode(fz_linknode* node, fz_matrix ctm); +fz_rect fz_boundmetanode(fz_metanode* node, fz_matrix ctm); + +void +fz_initnode(fz_node *node, fz_nodekind kind) +{ + node->kind = kind; + node->parent = nil; + node->first = nil; + node->last = nil; + node->next = nil; +} + +#define TAILRECURSION 1 + +/* Naive implementation uses so much stack that some PDFs can blow default + 1MB stack on Windows. A partially tail-recursive version (enabled + when TAILRECURSION is defined) doesn't have this problem (at least I + don't know of a PDF that can blow stack with this version although I'm + sure it's possible to artificially create one) */ +void +fz_dropnode(fz_node *node) +{ +#ifdef TAILRECURSION + fz_node *next; +tailrecursion: +#endif + if (node->first) + fz_dropnode(node->first); + +#ifdef TAILRECURSION + next = node->next; +#else + if (node->next) + fz_dropnode(node->next); +#endif + + switch (node->kind) + { + case FZ_NTRANSFORM: + case FZ_NOVER: + case FZ_NMASK: + case FZ_NBLEND: + case FZ_NCOLOR: + break; + case FZ_NPATH: + fz_droppathnode((fz_pathnode *) node); + break; + case FZ_NTEXT: + fz_droptextnode((fz_textnode *) node); + break; + case FZ_NIMAGE: + fz_dropimagenode((fz_imagenode *) node); + break; + case FZ_NSHADE: + fz_dropshadenode((fz_shadenode *) node); + break; + case FZ_NLINK: + fz_droplinknode((fz_linknode *) node); + break; + case FZ_NMETA: + fz_dropmetanode((fz_metanode *) node); + break; + } + + fz_free(node); +#ifdef TAILRECURSION + if (next) + { + node = next; + goto tailrecursion; + } +#endif +} + +fz_rect +fz_boundnode(fz_node *node, fz_matrix ctm) +{ + switch (node->kind) + { + case FZ_NTRANSFORM: + return fz_boundtransformnode((fz_transformnode *) node, ctm); + case FZ_NOVER: + return fz_boundovernode((fz_overnode *) node, ctm); + case FZ_NMASK: + return fz_boundmasknode((fz_masknode *) node, ctm); + case FZ_NBLEND: + return fz_boundblendnode((fz_blendnode *) node, ctm); + case FZ_NCOLOR: + return fz_boundsolidnode((fz_solidnode *) node, ctm); + case FZ_NPATH: + return fz_boundpathnode((fz_pathnode *) node, ctm); + case FZ_NTEXT: + return fz_boundtextnode((fz_textnode *) node, ctm); + case FZ_NIMAGE: + return fz_boundimagenode((fz_imagenode *) node, ctm); + case FZ_NSHADE: + return fz_boundshadenode((fz_shadenode *) node, ctm); + case FZ_NLINK: + return fz_boundlinknode((fz_linknode *) node, ctm); + case FZ_NMETA: + return fz_boundmetanode((fz_metanode *) node, ctm); + } + return fz_emptyrect; +} + +int +fz_istransformnode(fz_node *node) +{ + return node ? node->kind == FZ_NTRANSFORM : 0; +} + +int +fz_isovernode(fz_node *node) +{ + return node ? node->kind == FZ_NOVER : 0; +} + +int +fz_ismasknode(fz_node *node) +{ + return node ? node->kind == FZ_NMASK : 0; +} + +int +fz_isblendnode(fz_node *node) +{ + return node ? node->kind == FZ_NBLEND : 0; +} + +int +fz_issolidnode(fz_node *node) +{ + return node ? node->kind == FZ_NCOLOR : 0; +} + +int +fz_ispathnode(fz_node *node) +{ + return node ? node->kind == FZ_NPATH : 0; +} + +int +fz_istextnode(fz_node *node) +{ + return node ? node->kind == FZ_NTEXT : 0; +} + +int +fz_isimagenode(fz_node *node) +{ + return node ? node->kind == FZ_NIMAGE : 0; +} + +int +fz_isshadenode(fz_node *node) +{ + return node ? node->kind == FZ_NSHADE : 0; +} + +int +fz_islinknode(fz_node *node) +{ + return node ? node->kind == FZ_NLINK : 0; +} + +int +fz_ismetanode(fz_node *node) +{ + return node ? node->kind == FZ_NMETA : 0; +} + diff --git a/rosapps/smartpdf/fitz/world/node_misc2.c b/rosapps/smartpdf/fitz/world/node_misc2.c new file mode 100644 index 00000000000..5234cbc809a --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_misc2.c @@ -0,0 +1,332 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +/* + * Over + */ + +fz_error * +fz_newovernode(fz_node **nodep) +{ + fz_node *node; + + node = *nodep = fz_malloc(sizeof (fz_overnode)); + if (!node) + return fz_outofmem; + + fz_initnode(node, FZ_NOVER); + + return nil; +} + +fz_rect +fz_boundovernode(fz_overnode *node, fz_matrix ctm) +{ + fz_node *child; + fz_rect bbox; + fz_rect temp; + + child = node->super.first; + if (!child) + return fz_emptyrect; + + bbox = fz_boundnode(child, ctm); + + child = child->next; + while (child) + { + temp = fz_boundnode(child, ctm); + bbox = fz_mergerects(temp, bbox); + child = child->next; + } + + return bbox; +} + +/* + * Mask + */ + +fz_error * +fz_newmasknode(fz_node **nodep) +{ + fz_node *node; + + node = *nodep = fz_malloc(sizeof (fz_masknode)); + if (!node) + return fz_outofmem; + + fz_initnode(node, FZ_NMASK); + + return nil; +} + +fz_rect +fz_boundmasknode(fz_masknode *node, fz_matrix ctm) +{ + fz_node *shape; + fz_node *color; + fz_rect one, two; + + shape = node->super.first; + color = shape->next; + + one = fz_boundnode(shape, ctm); + two = fz_boundnode(color, ctm); + return fz_intersectrects(one, two); +} + +/* + * Blend + */ + +fz_error * +fz_newblendnode(fz_node **nodep, fz_colorspace *cs, fz_blendkind b, int k, int i) +{ + fz_blendnode *node; + + node = fz_malloc(sizeof (fz_blendnode)); + if (!node) + return fz_outofmem; + *nodep = (fz_node*)node; + + fz_initnode((fz_node*)node, FZ_NBLEND); + node->cs = fz_keepcolorspace(cs); + node->mode = b; + node->knockout = k; + node->isolated = i; + + return nil; +} + +fz_rect +fz_boundblendnode(fz_blendnode *node, fz_matrix ctm) +{ + fz_node *child; + fz_rect bbox; + fz_rect temp; + + child = node->super.first; + if (!child) + return fz_emptyrect; + + bbox = fz_boundnode(child, ctm); + + child = child->next; + while (child) + { + temp = fz_boundnode(child, ctm); + bbox = fz_mergerects(temp, bbox); + child = child->next; + } + + return bbox; +} + +void +fz_dropblendnode(fz_blendnode *node) +{ + fz_dropcolorspace(node->cs); +} + +/* + * Transform + */ + +fz_error * +fz_newtransformnode(fz_node **nodep, fz_matrix m) +{ + fz_transformnode *node; + + node = fz_malloc(sizeof (fz_transformnode)); + if (!node) + return fz_outofmem; + *nodep = (fz_node*)node; + + fz_initnode((fz_node*)node, FZ_NTRANSFORM); + node->m = m; + + return nil; +} + +fz_rect +fz_boundtransformnode(fz_transformnode *node, fz_matrix ctm) +{ + if (!node->super.first) + return fz_emptyrect; + return fz_boundnode(node->super.first, fz_concat(node->m, ctm)); +} + +/* + * Meta info + */ + +fz_error * +fz_newmetanode(fz_node **nodep, char *name, void *dict) +{ + fz_metanode *node; + + node = fz_malloc(sizeof (fz_metanode)); + if (!node) + return fz_outofmem; + *nodep = (fz_node*)node; + + fz_initnode((fz_node*)node, FZ_NMETA); + node->name = name; + node->dict = dict; + + return nil; +} + +void +fz_dropmetanode(fz_metanode *node) +{ + if (node->dict) + fz_warn("leaking meta node '%s'", node->name); +} + +fz_rect +fz_boundmetanode(fz_metanode *node, fz_matrix ctm) +{ + if (!node->super.first) + return fz_emptyrect; + return fz_boundnode(node->super.first, ctm); +} + +/* + * Link to tree + */ + +fz_error * +fz_newlinknode(fz_node **nodep, fz_tree *subtree) +{ + fz_linknode *node; + + node = fz_malloc(sizeof (fz_linknode)); + if (!node) + return fz_outofmem; + *nodep = (fz_node*)node; + + fz_initnode((fz_node*)node, FZ_NLINK); + node->tree = fz_keeptree(subtree); + + return nil; +} + +void +fz_droplinknode(fz_linknode *node) +{ + fz_droptree(node->tree); +} + +fz_rect +fz_boundlinknode(fz_linknode *node, fz_matrix ctm) +{ + return fz_boundtree(node->tree, ctm); +} + +/* + * Solid color + */ + +fz_error * +fz_newsolidnode(fz_node **nodep, fz_colorspace *cs, int n, float *v) +{ + fz_solidnode *node; + int i; + + node = fz_malloc(sizeof(fz_solidnode) + sizeof(float) * n); + if (!node) + return fz_outofmem; + *nodep = (fz_node*)node; + + fz_initnode((fz_node*)node, FZ_NCOLOR); + node->cs = fz_keepcolorspace(cs); + node->n = n; + for (i = 0; i < n; i++) + node->samples[i] = v[i]; + + return nil; +} + +fz_rect +fz_boundsolidnode(fz_solidnode *node, fz_matrix ctm) +{ + return fz_infiniterect; +} + +void +fz_dropsolidnode(fz_solidnode *node) +{ + fz_dropcolorspace(node->cs); +} + +/* + * Image node + */ + +fz_error * +fz_newimagenode(fz_node **nodep, fz_image *image) +{ + fz_imagenode *node; + + node = fz_malloc(sizeof (fz_imagenode)); + if (!node) + return fz_outofmem; + *nodep = (fz_node*)node; + + fz_initnode((fz_node*)node, FZ_NIMAGE); + node->image = fz_keepimage(image); + + return nil; +} + +void +fz_dropimagenode(fz_imagenode *node) +{ + fz_dropimage(node->image); +} + +fz_rect +fz_boundimagenode(fz_imagenode *node, fz_matrix ctm) +{ + fz_rect bbox; + bbox.x0 = 0; + bbox.y0 = 0; + bbox.x1 = 1; + bbox.y1 = 1; + return fz_transformaabb(ctm, bbox); +} + +/* + * Shade node + */ + +fz_error * +fz_newshadenode(fz_node **nodep, fz_shade *shade) +{ + fz_shadenode *node; + + node = fz_malloc(sizeof (fz_shadenode)); + if (!node) + return fz_outofmem; + *nodep = (fz_node*)node; + + fz_initnode((fz_node*)node, FZ_NSHADE); + node->shade = fz_keepshade(shade); + + return nil; +} + +void +fz_dropshadenode(fz_shadenode *node) +{ + fz_dropshade(node->shade); +} + +fz_rect +fz_boundshadenode(fz_shadenode *node, fz_matrix ctm) +{ + return fz_boundshade(node->shade, ctm); +} + diff --git a/rosapps/smartpdf/fitz/world/node_optimize.c b/rosapps/smartpdf/fitz/world/node_optimize.c new file mode 100644 index 00000000000..ffb2c646368 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_optimize.c @@ -0,0 +1,314 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +/* + * Remove (mask ... white) until we get something not white + */ + +static int iswhitenode(fz_solidnode *node) +{ + if (!strcmp(node->cs->name, "DeviceGray")) + return fabs(node->samples[0] - 1.0) < FLT_EPSILON; + if (!strcmp(node->cs->name, "DeviceRGB")) + return fabs(node->samples[0] - 1.0) < FLT_EPSILON && + fabs(node->samples[1] - 1.0) < FLT_EPSILON && + fabs(node->samples[2] - 1.0) < FLT_EPSILON; + if (!strcmp(node->cs->name, "DeviceCMYK")) + return fabs(node->samples[0]) < FLT_EPSILON && + fabs(node->samples[1]) < FLT_EPSILON && + fabs(node->samples[2]) < FLT_EPSILON && + fabs(node->samples[3]) < FLT_EPSILON; + return 0; +} + +static int cleanwhite(fz_node *node) +{ + fz_node *current; + fz_node *next; + fz_node *shape; + fz_node *color; + + for (current = node->first; current; current = next) + { + next = current->next; + + if (fz_islinknode(current)) + return 1; + else if (fz_isimagenode(current)) + return 1; + else if (fz_isshadenode(current)) + return 1; + else if (fz_issolidnode(current)) + { + if (!iswhitenode((fz_solidnode*)current)) + return 1; + } + + else if (fz_ismasknode(current)) + { + shape = current->first; + color = shape->next; + if (fz_issolidnode(color)) + { + if (iswhitenode((fz_solidnode*)color)) + fz_removenode(current); + else + return 1; + } + else + { + if (cleanwhite(current)) + return 1; + } + } + + else + { + if (cleanwhite(current)) + return 1; + } + } + + return 0; +} + +/* + * Remove useless overs that only have one child. + */ + +static void cleanovers(fz_node *node) +{ + fz_node *prev; + fz_node *next; + fz_node *current; + fz_node *child; + + prev = nil; + for (current = node->first; current; current = next) + { + next = current->next; + + if (fz_isovernode(current)) + { + if (current->first == current->last) + { + child = current->first; + fz_removenode(current); + if (child) + { + if (prev) + fz_insertnodeafter(prev, child); + else + fz_insertnodefirst(node, child); + } + current = child; + } + } + + if (current) + prev = current; + } + + for (current = node->first; current; current = current->next) + cleanovers(current); +} + +/* + * Remove rectangular clip-masks whose contents fit... + */ + +static int getrect(fz_pathnode *path, fz_rect *bboxp) +{ + float x, y, w, h; + + /* move x y, line x+w y, line x+w y+h, line x y+h, close */ + + if (path->len != 13) + return 0; + + if (path->els[0].k != FZ_MOVETO) return 0; + x = path->els[1].v; + y = path->els[2].v; + + if (path->els[3].k != FZ_LINETO) return 0; + w = path->els[4].v - x; + if (path->els[5].v != y) return 0; + + if (path->els[6].k != FZ_LINETO) return 0; + if (path->els[7].v != x + w) return 0; + h = path->els[8].v - y; + + if (path->els[9].k != FZ_LINETO) return 0; + if (path->els[10].v != x) return 0; + if (path->els[11].v != y + h) return 0; + + if (path->els[12].k != FZ_CLOSEPATH) return 0; + + bboxp->x0 = MIN(x, x + w); + bboxp->y0 = MIN(y, y + h); + bboxp->x1 = MAX(x, x + w); + bboxp->y1 = MAX(y, y + h); + + return 1; +} + +static int fitsinside(fz_node *node, fz_rect clip) +{ + fz_rect bbox; + bbox = fz_boundnode(node, fz_identity()); + if (fz_isinfiniterect(bbox)) return 0; + if (fz_isemptyrect(bbox)) return 1; + if (bbox.x0 < clip.x0) return 0; + if (bbox.x1 > clip.x1) return 0; + if (bbox.y0 < clip.y0) return 0; + if (bbox.y1 > clip.y1) return 0; + return 1; +} + +static void cleanmasks(fz_node *node) +{ + fz_node *prev; + fz_node *current; + fz_node *shape; + fz_node *color; + fz_rect bbox; + + for (current = node->first; current; current = current->next) + cleanmasks(current); + + prev = nil; + for (current = node->first; current; current = current->next) + { +retry: + if (!current) + break; + + if (fz_ismasknode(current)) + { + shape = current->first; + color = shape->next; + + if (color == nil) + { + fz_removenode(current); + prev = nil; + current = node->first; + goto retry; + } + + if (fz_ispathnode(shape)) + { + if (getrect((fz_pathnode*)shape, &bbox)) + { + if (fitsinside(color, bbox)) + { + fz_removenode(current); + if (prev) + fz_insertnodeafter(prev, color); + else + fz_insertnodefirst(node, color); + current = color; + goto retry; + } + } + } + } + + prev = current; + } +} + +/* + * Turn 1x1 images into rectangle fills + */ + +static fz_error *clean1x1(fz_node *node) +{ + fz_error *error; + fz_node *current; + fz_node *color; + fz_pathnode *rect; + fz_node *mask; + fz_image *image; + fz_pixmap *pix; + float v[FZ_MAXCOLORS]; + int i; + + for (current = node->first; current; current = current->next) + { + if (fz_isimagenode(current)) + { + image = ((fz_imagenode*)current)->image; + if (image->w == 1 && image->h == 1) + { + error = fz_newpathnode(&rect); + fz_moveto(rect, 0, 0); + fz_lineto(rect, 1, 0); + fz_lineto(rect, 1, 1); + fz_lineto(rect, 0, 1); + fz_closepath(rect); + fz_endpath(rect, FZ_FILL, nil, nil); + + if (image->cs) + { + error = fz_newpixmap(&pix, 0, 0, 1, 1, image->n + 1); + if (error) + return error; + + error = image->loadtile(image, pix); + if (error) + return error; + + for (i = 0; i < image->n; i++) + v[i] = pix->samples[i + 1] / 255.0; + + fz_droppixmap(pix); + + error = fz_newsolidnode(&color, image->cs, image->n, v); + if (error) + return error; + error = fz_newmasknode(&mask); + if (error) + return error; + + fz_insertnodeafter(current, mask); + fz_insertnodelast(mask, (fz_node*)rect); + fz_insertnodelast(mask, color); + fz_removenode(current); + current = mask; + } + + else + { + /* pray that the 1x1 image mask is all opaque */ + fz_insertnodeafter(current, (fz_node*)rect); + fz_removenode(current); + current = (fz_node*)rect; + } + } + } + + error = clean1x1(current); + if (error) + return error; + } + + return nil; +} + +/* + * + */ + +fz_error * +fz_optimizetree(fz_tree *tree) +{ + if (getenv("DONTOPT")) + return nil; + cleanwhite(tree->root); + cleanovers(tree->root); + cleanmasks(tree->root); + clean1x1(tree->root); + return nil; +} + diff --git a/rosapps/smartpdf/fitz/world/node_path.c b/rosapps/smartpdf/fitz/world/node_path.c new file mode 100644 index 00000000000..bbf3da5d4a6 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_path.c @@ -0,0 +1,306 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +fz_error * +fz_newpathnode(fz_pathnode **pathp) +{ + fz_pathnode *path; + + path = *pathp = fz_malloc(sizeof(fz_pathnode)); + if (!path) + return fz_outofmem; + + fz_initnode((fz_node*)path, FZ_NPATH); + + path->paint = FZ_FILL; + path->linecap = 0; + path->linejoin = 0; + path->linewidth = 1.0; + path->miterlimit = 10.0; + path->dash = nil; + path->len = 0; + path->cap = 0; + path->els = nil; + + return nil; +} + +fz_error * +fz_clonepathnode(fz_pathnode **pathp, fz_pathnode *oldpath) +{ + fz_pathnode *path; + + path = *pathp = fz_malloc(sizeof(fz_pathnode)); + if (!path) + return fz_outofmem; + + fz_initnode((fz_node*)path, FZ_NPATH); + + path->paint = FZ_FILL; + path->linecap = 0; + path->linejoin = 0; + path->linewidth = 1.0; + path->miterlimit = 10.0; + path->dash = nil; + path->len = oldpath->len; + path->cap = oldpath->len; + + path->els = fz_malloc(sizeof (fz_pathel) * path->len); + if (!path->els) { + fz_free(path); + return fz_outofmem; + } + memcpy(path->els, oldpath->els, sizeof(fz_pathel) * path->len); + + return nil; +} + +void +fz_droppathnode(fz_pathnode *node) +{ + fz_free(node->dash); + fz_free(node->els); +} + +static fz_error * +growpath(fz_pathnode *path, int n) +{ + int newcap; + fz_pathel *newels; + + while (path->len + n > path->cap) + { + newcap = path->cap + 36; + newels = fz_realloc(path->els, sizeof (fz_pathel) * newcap); + if (!newels) + return fz_outofmem; + path->cap = newcap; + path->els = newels; + } + + return nil; +} + +fz_error * +fz_moveto(fz_pathnode *path, float x, float y) +{ + if (growpath(path, 3) != nil) + return fz_outofmem; + path->els[path->len++].k = FZ_MOVETO; + path->els[path->len++].v = x; + path->els[path->len++].v = y; + return nil; +} + +fz_error * +fz_lineto(fz_pathnode *path, float x, float y) +{ + if (growpath(path, 3) != nil) + return fz_outofmem; + path->els[path->len++].k = FZ_LINETO; + path->els[path->len++].v = x; + path->els[path->len++].v = y; + return nil; +} + +fz_error * +fz_curveto(fz_pathnode *path, + float x1, float y1, + float x2, float y2, + float x3, float y3) +{ + if (growpath(path, 7) != nil) + return fz_outofmem; + path->els[path->len++].k = FZ_CURVETO; + path->els[path->len++].v = x1; + path->els[path->len++].v = y1; + path->els[path->len++].v = x2; + path->els[path->len++].v = y2; + path->els[path->len++].v = x3; + path->els[path->len++].v = y3; + return nil; +} + +fz_error * +fz_curvetov(fz_pathnode *path, float x2, float y2, float x3, float y3) +{ + float x1 = path->els[path->len-2].v; + float y1 = path->els[path->len-1].v; + return fz_curveto(path, x1, y1, x2, y2, x3, y3); +} + +fz_error * +fz_curvetoy(fz_pathnode *path, float x1, float y1, float x3, float y3) +{ + return fz_curveto(path, x1, y1, x3, y3, x3, y3); +} + +fz_error * +fz_closepath(fz_pathnode *path) +{ + if (growpath(path, 1) != nil) + return fz_outofmem; + path->els[path->len++].k = FZ_CLOSEPATH; + return nil; +} + +fz_error * +fz_endpath(fz_pathnode *path, fz_pathkind paint, fz_stroke *stroke, fz_dash *dash) +{ + fz_pathel *newels; + + newels = fz_realloc(path->els, path->len * sizeof(fz_pathel)); + if (!newels) + return fz_outofmem; + path->els = newels; + + path->paint = paint; + path->dash = dash; + if (stroke) + { + path->linecap = stroke->linecap; + path->linejoin = stroke->linejoin; + path->linewidth = stroke->linewidth; + path->miterlimit = stroke->miterlimit; + } + + if (path->linewidth < 0.01) + path->linewidth = 0.01f; + + return nil; +} + +static inline fz_rect boundexpand(fz_rect r, fz_point p) +{ + if (p.x < r.x0) r.x0 = p.x; + if (p.y < r.y0) r.y0 = p.y; + if (p.x > r.x1) r.x1 = p.x; + if (p.y > r.y1) r.y1 = p.y; + return r; +} + +fz_rect +fz_boundpathnode(fz_pathnode *path, fz_matrix ctm) +{ + fz_point p; + fz_rect r = fz_emptyrect; + int i = 0; + + if (path->len) + { + p.x = path->els[1].v; + p.y = path->els[2].v; + p = fz_transformpoint(ctm, p); + r.x0 = r.x1 = p.x; + r.y0 = r.y1 = p.y; + } + + while (i < path->len) + { + switch (path->els[i++].k) + { + case FZ_CURVETO: + p.x = path->els[i++].v; + p.y = path->els[i++].v; + r = boundexpand(r, fz_transformpoint(ctm, p)); + p.x = path->els[i++].v; + p.y = path->els[i++].v; + r = boundexpand(r, fz_transformpoint(ctm, p)); + case FZ_MOVETO: + case FZ_LINETO: + p.x = path->els[i++].v; + p.y = path->els[i++].v; + r = boundexpand(r, fz_transformpoint(ctm, p)); + break; + case FZ_CLOSEPATH: + break; + } + } + + if (path->paint == FZ_STROKE) + { + float miterlength = sin(path->miterlimit / 2.0); + float linewidth = path->linewidth; + float expand = MAX(miterlength, linewidth) / 2.0; + r.x0 -= expand; + r.y0 -= expand; + r.x1 += expand; + r.y1 += expand; + } + + return r; +} + +void +fz_debugpathnode(fz_pathnode *path) +{ + float x, y; + int i = 0; + while (i < path->len) + { + switch (path->els[i++].k) + { + case FZ_MOVETO: + x = path->els[i++].v; + y = path->els[i++].v; + printf("%g %g m\n", x, y); + break; + case FZ_LINETO: + x = path->els[i++].v; + y = path->els[i++].v; + printf("%g %g l\n", x, y); + break; + case FZ_CURVETO: + x = path->els[i++].v; + y = path->els[i++].v; + printf("%g %g ", x, y); + x = path->els[i++].v; + y = path->els[i++].v; + printf("%g %g ", x, y); + x = path->els[i++].v; + y = path->els[i++].v; + printf("%g %g c\n", x, y); + break; + case FZ_CLOSEPATH: + printf("h\n"); + } + } + + switch (path->paint) + { + case FZ_STROKE: + printf("S\n"); + break; + case FZ_FILL: + printf("f\n"); + break; + case FZ_EOFILL: + printf("f*\n"); + break; + } +} + +fz_error * +fz_newdash(fz_dash **dashp, float phase, int len, float *array) +{ + fz_dash *dash; + int i; + + dash = *dashp = fz_malloc(sizeof(fz_dash) + sizeof(float) * len); + if (!dash) + return fz_outofmem; + + dash->len = len; + dash->phase = phase; + for (i = 0; i < len; i++) + dash->array[i] = array[i]; + + return nil; +} + +void +fz_dropdash(fz_dash *dash) +{ + fz_free(dash); +} + diff --git a/rosapps/smartpdf/fitz/world/node_text.c b/rosapps/smartpdf/fitz/world/node_text.c new file mode 100644 index 00000000000..c6f19e29ca9 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_text.c @@ -0,0 +1,142 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +fz_error * +fz_newtextnode(fz_textnode **textp, fz_font *font) +{ + fz_textnode *text; + + text = fz_malloc(sizeof(fz_textnode)); + if (!text) + return fz_outofmem; + + fz_initnode((fz_node*)text, FZ_NTEXT); + + text->font = fz_keepfont(font); + text->trm = fz_identity(); + text->len = 0; + text->cap = 0; + text->els = nil; + + *textp = text; + return nil; +} + +fz_error * +fz_clonetextnode(fz_textnode **textp, fz_textnode *oldtext) +{ + fz_textnode *text; + + text = *textp = fz_malloc(sizeof(fz_textnode)); + if (!text) + return fz_outofmem; + + fz_initnode((fz_node*)text, FZ_NTEXT); + + text->font = fz_keepfont(oldtext->font); + text->trm = oldtext->trm; + text->len = oldtext->len; + text->cap = oldtext->len; + text->els = nil; + + text->els = fz_malloc(sizeof(fz_textel) * text->len); + if (!text->els) + { + fz_dropfont(text->font); + fz_free(text); + return fz_outofmem; + } + + memcpy(text->els, oldtext->els, sizeof(fz_textel) * text->len); + + *textp = text; + return nil; +} + +void +fz_droptextnode(fz_textnode *text) +{ + fz_dropfont(text->font); + fz_free(text->els); +} + +fz_rect +fz_boundtextnode(fz_textnode *text, fz_matrix ctm) +{ + fz_matrix trm; + fz_rect bbox; + fz_rect fbox; + int i; + + if (text->len == 0) + return fz_emptyrect; + + /* find bbox of glyph origins in ctm space */ + + bbox.x0 = bbox.x1 = text->els[0].x; + bbox.y0 = bbox.y1 = text->els[0].y; + + for (i = 1; i < text->len; i++) + { + bbox.x0 = MIN(bbox.x0, text->els[i].x); + bbox.y0 = MIN(bbox.y0, text->els[i].y); + bbox.x1 = MAX(bbox.x1, text->els[i].x); + bbox.y1 = MAX(bbox.y1, text->els[i].y); + } + + bbox = fz_transformaabb(ctm, bbox); + + /* find bbox of font in trm * ctm space */ + + trm = fz_concat(text->trm, ctm); + trm.e = 0; + trm.f = 0; + + fbox.x0 = text->font->bbox.x0 * 0.001; + fbox.y0 = text->font->bbox.y0 * 0.001; + fbox.x1 = text->font->bbox.x1 * 0.001; + fbox.y1 = text->font->bbox.y1 * 0.001; + + fbox = fz_transformaabb(trm, fbox); + + /* expand glyph origin bbox by font bbox */ + + bbox.x0 += fbox.x0; + bbox.y0 += fbox.y0; + bbox.x1 += fbox.x1; + bbox.y1 += fbox.y1; + + return bbox; +} + +static fz_error * +growtext(fz_textnode *text, int n) +{ + int newcap; + fz_textel *newels; + + while (text->len + n > text->cap) + { + newcap = text->cap + 36; + newels = fz_realloc(text->els, sizeof (fz_textel) * newcap); + if (!newels) + return fz_outofmem; + text->cap = newcap; + text->els = newels; + } + + return nil; +} + +fz_error * +fz_addtext(fz_textnode *text, int cid, float x, float y) +{ + if (growtext(text, 1) != nil) + return fz_outofmem; + text->els[text->len].cid = cid; + text->els[text->len].x = x; + text->els[text->len].y = y; + text->len++; + return nil; +} + diff --git a/rosapps/smartpdf/fitz/world/node_tolisp.c b/rosapps/smartpdf/fitz/world/node_tolisp.c new file mode 100644 index 00000000000..a02c02613b6 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_tolisp.c @@ -0,0 +1,192 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +static void indent(int level) +{ + while (level--) + putchar(' '); +} + +static void lispnode(fz_node *node, int level); + +static void lispmeta(fz_metanode *node, int level) +{ + fz_node *child; + indent(level); + printf("(meta "); + if (node->name) { fz_debugobj(node->name); } + if (node->dict) { printf("\n"); fz_debugobj(node->dict); } + printf("\n"); + for (child = node->super.first; child; child = child->next) + lispnode(child, level + 1); + indent(level); + printf(")\n"); +} + +static void lispover(fz_overnode *node, int level) +{ + fz_node *child; + indent(level); + printf("(over\n"); + for (child = node->super.first; child; child = child->next) + lispnode(child, level + 1); + indent(level); + printf(")\n"); +} + +static void lispmask(fz_masknode *node, int level) +{ + fz_node *child; + indent(level); + printf("(mask\n"); + for (child = node->super.first; child; child = child->next) + lispnode(child, level + 1); + indent(level); + printf(")\n"); +} + +static void lispblend(fz_blendnode *node, int level) +{ + fz_node *child; + indent(level); + printf("(blend-%d\n", node->mode); + for (child = node->super.first; child; child = child->next) + lispnode(child, level + 1); + indent(level); + printf(")\n"); +} + +static void lisptransform(fz_transformnode *node, int level) +{ + indent(level); + printf("(transform %g %g %g %g %g %g\n", + node->m.a, node->m.b, + node->m.c, node->m.d, + node->m.e, node->m.f); + lispnode(node->super.first, level + 1); + indent(level); + printf(")\n"); +} + +static void lispcolor(fz_colornode *node, int level) +{ + int i; + indent(level); + printf("(color %s ", node->cs->name); + for (i = 0; i < node->n; i++) + printf("%g ", node->samples[i]); + printf(")\n"); +} + +static void lisplink(fz_linknode *node, int level) +{ + indent(level); + printf("(link %p)\n", node->tree); +} + +static void lisppath(fz_pathnode *node, int level) +{ + int i; + + indent(level); + + if (node->paint == FZ_STROKE) + { + printf("(path 'stroke %d %d %g %g ", + node->linecap, + node->linejoin, + node->linewidth, + node->miterlimit); + if (node->dash) + { + printf("%g '( ", node->dash->phase); + for (i = 0; i < node->dash->len; i++) + printf("%g ", node->dash->array[i]); + printf(")"); + } + else + printf("0 '()"); + } + else + { + printf("(path '%s", node->paint == FZ_FILL ? "fill" : "eofill"); + } + + printf("\n"); + fz_debugpathnode(node); + + indent(level); + printf(")\n"); +} + +static void lisptext(fz_textnode *node, int level) +{ + int i; + + indent(level); + printf("(text %s [%g %g %g %g]\n", node->font->name, + node->trm.a, node->trm.b, node->trm.c, node->trm.d); + + for (i = 0; i < node->len; i++) + { + indent(level + 1); + if (node->els[i].cid >= 32 && node->els[i].cid < 128) + printf("(cid '%c' %g %g)\n", node->els[i].cid, node->els[i].x, node->els[i].y); + else + printf("(cid <%04x> %g %g)\n", node->els[i].cid, node->els[i].x, node->els[i].y); + } + + indent(level); + printf(")\n"); +} + +static void lispimage(fz_imagenode *node, int level) +{ + fz_image *image = node->image; + indent(level); + printf("(image %dx%d %d+%d)\n", image->w, image->h, image->n, image->a); +} + +static void lispshade(fz_shadenode *node, int level) +{ + indent(level); + printf("(shade)\n"); +} + +static void lispnode(fz_node *node, int level) +{ + if (!node) + { + indent(level); + printf("(nil)\n"); + return; + } + + switch (node->kind) + { + case FZ_NMETA: lispmeta((fz_metanode*)node, level); break; + case FZ_NOVER: lispover((fz_overnode*)node, level); break; + case FZ_NMASK: lispmask((fz_masknode*)node, level); break; + case FZ_NBLEND: lispblend((fz_blendnode*)node, level); break; + case FZ_NTRANSFORM: lisptransform((fz_transformnode*)node, level); break; + case FZ_NCOLOR: lispcolor((fz_colornode*)node, level); break; + case FZ_NPATH: lisppath((fz_pathnode*)node, level); break; + case FZ_NTEXT: lisptext((fz_textnode*)node, level); break; + case FZ_NIMAGE: lispimage((fz_imagenode*)node, level); break; + case FZ_NSHADE: lispshade((fz_shadenode*)node, level); break; + case FZ_NLINK: lisplink((fz_linknode*)node, level); break; + } +} + +void +fz_debugnode(fz_node *node) +{ + lispnode(node, 0); +} + +void +fz_debugtree(fz_tree *tree) +{ + lispnode(tree->root, 0); +} + diff --git a/rosapps/smartpdf/fitz/world/node_toxml.c b/rosapps/smartpdf/fitz/world/node_toxml.c new file mode 100644 index 00000000000..42ef6f9c287 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_toxml.c @@ -0,0 +1,200 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +static void indent(int level) +{ + while (level--) + putchar(' '); +} + +static void xmlnode(fz_node *node, int level); + +static void xmlmeta(fz_metanode *node, int level) +{ + fz_node *child; + + indent(level); + printf("\n", node->name); + + for (child = node->super.first; child; child = child->next) + xmlnode(child, level + 1); + + indent(level); + printf("\n"); +} + +static void xmlover(fz_overnode *node, int level) +{ + fz_node *child; + indent(level); + printf("\n"); + for (child = node->super.first; child; child = child->next) + xmlnode(child, level + 1); + indent(level); + printf("\n"); +} + +static void xmlmask(fz_masknode *node, int level) +{ + fz_node *child; + indent(level); + printf("\n"); + for (child = node->super.first; child; child = child->next) + xmlnode(child, level + 1); + indent(level); + printf("\n"); +} + +static void xmlblend(fz_blendnode *node, int level) +{ + fz_node *child; + indent(level); + printf("\n", node->mode); + for (child = node->super.first; child; child = child->next) + xmlnode(child, level + 1); + indent(level); + printf("\n"); +} + +static void xmltransform(fz_transformnode *node, int level) +{ + indent(level); + printf("\n", + node->m.a, node->m.b, + node->m.c, node->m.d, + node->m.e, node->m.f); + xmlnode(node->super.first, level + 1); + indent(level); + printf("\n"); +} + +static void xmlsolid(fz_solidnode *node, int level) +{ + int i; + indent(level); + printf("cs->name); + for (i = 0; i < node->n; i++) + { + printf("%g", node->samples[i]); + if (i < node->n - 1) + putchar(' '); + } + printf("\" />\n"); +} + +static void xmllink(fz_linknode *node, int level) +{ + indent(level); + printf("\n", node->tree); +} + +static void xmlpath(fz_pathnode *node, int level) +{ + int i; + + indent(level); + + if (node->paint == FZ_STROKE) + { + printf("linecap, + node->linejoin, + node->linewidth, + node->miterlimit); + if (node->dash) + { + printf(" phase=\"%g\" array=\"", node->dash->phase); + for (i = 0; i < node->dash->len; i++) + printf("%g ", node->dash->array[i]); + printf("\""); + } + printf(">\n"); + } + else + { + printf("\n", + node->paint == FZ_FILL ? "nonzero" : "evenodd"); + } + + fz_debugpathnode(node); + + indent(level); + printf("\n"); +} + +static void xmltext(fz_textnode *node, int level) +{ + int i; + + indent(level); + printf("\n", node->font->name, + node->trm.a, node->trm.b, node->trm.c, node->trm.d); + + for (i = 0; i < node->len; i++) + { + indent(level + 1); + if (node->els[i].cid >= 32 && node->els[i].cid < 128) + printf("\n", + node->els[i].cid, node->els[i].x, node->els[i].y); + else + printf("\" x=\"%g\" y=\"%g\" />\n", + node->els[i].cid, node->els[i].x, node->els[i].y); + } + + indent(level); + printf("\n"); +} + +static void xmlimage(fz_imagenode *node, int level) +{ + fz_image *image = node->image; + indent(level); + printf("\n", + image->w, image->h, image->n, image->a); +} + +static void xmlshade(fz_shadenode *node, int level) +{ + indent(level); + printf("\n"); +} + +static void xmlnode(fz_node *node, int level) +{ + if (!node) + { + indent(level); + printf("\n"); + return; + } + + switch (node->kind) + { + case FZ_NMETA: xmlmeta((fz_metanode*)node, level); break; + case FZ_NOVER: xmlover((fz_overnode*)node, level); break; + case FZ_NMASK: xmlmask((fz_masknode*)node, level); break; + case FZ_NBLEND: xmlblend((fz_blendnode*)node, level); break; + case FZ_NTRANSFORM: xmltransform((fz_transformnode*)node, level); break; + case FZ_NCOLOR: xmlsolid((fz_solidnode*)node, level); break; + case FZ_NPATH: xmlpath((fz_pathnode*)node, level); break; + case FZ_NTEXT: xmltext((fz_textnode*)node, level); break; + case FZ_NIMAGE: xmlimage((fz_imagenode*)node, level); break; + case FZ_NSHADE: xmlshade((fz_shadenode*)node, level); break; + case FZ_NLINK: xmllink((fz_linknode*)node, level); break; + } +} + +void +fz_debugnode(fz_node *node) +{ + xmlnode(node, 0); +} + +void +fz_debugtree(fz_tree *tree) +{ + printf("\n"); + xmlnode(tree->root, 1); + printf("\n"); +} + diff --git a/rosapps/smartpdf/fitz/world/node_tree.c b/rosapps/smartpdf/fitz/world/node_tree.c new file mode 100644 index 00000000000..2bb822d5f2e --- /dev/null +++ b/rosapps/smartpdf/fitz/world/node_tree.c @@ -0,0 +1,110 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +fz_error * +fz_newtree(fz_tree **treep) +{ + fz_tree *tree; + + tree = *treep = fz_malloc(sizeof (fz_tree)); + if (!tree) + return fz_outofmem; + + tree->refs = 1; + tree->root = nil; + tree->head = nil; + + return nil; +} + +fz_tree * +fz_keeptree(fz_tree *tree) +{ + assert(tree->refs > 0); + tree->refs ++; + return tree; +} + +void +fz_droptree(fz_tree *tree) +{ + assert(tree->refs > 0); + if (--tree->refs == 0) + { + if (tree->root) + fz_dropnode(tree->root); + fz_free(tree); + } +} + +fz_rect +fz_boundtree(fz_tree *tree, fz_matrix ctm) +{ + if (tree->root) + return fz_boundnode(tree->root, ctm); + return fz_emptyrect; +} + +void +fz_insertnodefirst(fz_node *parent, fz_node *child) +{ + child->parent = parent; + child->next = parent->first; + parent->first = child; + if (!parent->last) + parent->last = child; +} + +void +fz_insertnodelast(fz_node *parent, fz_node *child) +{ + child->parent = parent; + if (!parent->first) + parent->first = child; + else + parent->last->next = child; + parent->last = child; +} + +void +fz_insertnodeafter(fz_node *prev, fz_node *child) +{ + fz_node *parent = prev->parent; + child->parent = parent; + if (parent->last == prev) + parent->last = child; + child->next = prev->next; + prev->next = child; +} + +void +fz_removenode(fz_node *child) +{ + fz_node *parent = child->parent; + fz_node *prev; + fz_node *node; + + if (parent->first == child) + { + parent->first = child->next; + if (parent->last == child) + parent->last = nil; + return; + } + + prev = parent->first; + node = prev->next; + + while (node) + { + if (node == child) + { + prev->next = child->next; + } + prev = node; + node = node->next; + } + + parent->last = prev; +} + diff --git a/rosapps/smartpdf/fitz/world/res_colorspace.c b/rosapps/smartpdf/fitz/world/res_colorspace.c new file mode 100644 index 00000000000..27d323abfbb --- /dev/null +++ b/rosapps/smartpdf/fitz/world/res_colorspace.c @@ -0,0 +1,92 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +void +fz_convertpixmap(fz_colorspace *srcs, fz_pixmap *src, fz_colorspace *dsts, fz_pixmap *dst) +{ + srcs->convpixmap(srcs, src, dsts, dst); +} + +void +fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv) +{ + srcs->convcolor(srcs, srcv, dsts, dstv); +} + +fz_colorspace * +fz_keepcolorspace(fz_colorspace *cs) +{ + if (cs->refs < 0) + return cs; + cs->refs ++; + return cs; +} + +void +fz_dropcolorspace(fz_colorspace *cs) +{ + if (cs->refs < 0) + return; + if (--cs->refs == 0) + { + if (cs->drop) + cs->drop(cs); + fz_free(cs); + } +} + +void +fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv) +{ + float xyz[3]; + int i; + + if (srcs != dsts) + { + srcs->toxyz(srcs, srcv, xyz); + dsts->fromxyz(dsts, xyz, dstv); + for (i = 0; i < dsts->n; i++) + dstv[i] = CLAMP(dstv[i], 0.0, 1.0); + } + else + { + for (i = 0; i < srcs->n; i++) + dstv[i] = srcv[i]; + } +} + +void +fz_stdconvpixmap(fz_colorspace *srcs, fz_pixmap *src, fz_colorspace *dsts, fz_pixmap *dst) +{ + float srcv[FZ_MAXCOLORS]; + float dstv[FZ_MAXCOLORS]; + int y, x, k; + + unsigned char *s = src->samples; + unsigned char *d = dst->samples; + +#ifndef NDEBUG + printf("convert pixmap from %s to %s\n", srcs->name, dsts->name); +#endif + + assert(src->w == dst->w && src->h == dst->h); + assert(src->n == srcs->n + 1); + assert(dst->n == dsts->n + 1); + + for (y = 0; y < src->h; y++) + { + for (x = 0; x < src->w; x++) + { + *d++ = *s++; + + for (k = 0; k < src->n - 1; k++) + srcv[k] = *s++ / 255.0; + + fz_convertcolor(srcs, srcv, dsts, dstv); + + for (k = 0; k < dst->n - 1; k++) + *d++ = dstv[k] * 255; + } + } +} + diff --git a/rosapps/smartpdf/fitz/world/res_font.c b/rosapps/smartpdf/fitz/world/res_font.c new file mode 100644 index 00000000000..d27d5bb4e1c --- /dev/null +++ b/rosapps/smartpdf/fitz/world/res_font.c @@ -0,0 +1,270 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +void +fz_initfont(fz_font *font, char *name) +{ + font->refs = 1; + strlcpy(font->name, name, sizeof font->name); + + font->wmode = 0; + + font->bbox.x0 = 0; + font->bbox.y0 = 0; + font->bbox.x1 = 1000; + font->bbox.y1 = 1000; + + font->hmtxcap = 0; + font->vmtxcap = 0; + font->nhmtx = 0; + font->nvmtx = 0; + font->hmtx = nil; + font->vmtx = nil; + + font->dhmtx.lo = 0x0000; + font->dhmtx.hi = 0xFFFF; + font->dhmtx.w = 0; + + font->dvmtx.lo = 0x0000; + font->dvmtx.hi = 0xFFFF; + font->dvmtx.x = 0; + font->dvmtx.y = 880; + font->dvmtx.w = -1000; +} + +fz_font * +fz_keepfont(fz_font *font) +{ + font->refs ++; + return font; +} + +void +fz_dropfont(fz_font *font) +{ + if (--font->refs == 0) + { + if (font->drop) + font->drop(font); + fz_free(font->hmtx); + fz_free(font->vmtx); + fz_free(font); + } +} + +void +fz_setfontwmode(fz_font *font, int wmode) +{ + font->wmode = wmode; +} + +void +fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax) +{ + font->bbox.x0 = xmin; + font->bbox.y0 = ymin; + font->bbox.x1 = xmax; + font->bbox.y1 = ymax; +} + +void +fz_setdefaulthmtx(fz_font *font, int w) +{ + font->dhmtx.w = w; +} + +void +fz_setdefaultvmtx(fz_font *font, int y, int w) +{ + font->dvmtx.y = y; + font->dvmtx.w = w; +} + +fz_error * +fz_addhmtx(fz_font *font, int lo, int hi, int w) +{ + int newcap; + fz_hmtx *newmtx; + + if (font->nhmtx + 1 >= font->hmtxcap) + { + newcap = font->hmtxcap + 16; + newmtx = fz_realloc(font->hmtx, sizeof(fz_hmtx) * newcap); + if (!newmtx) + return fz_outofmem; + font->hmtxcap = newcap; + font->hmtx = newmtx; + } + + font->hmtx[font->nhmtx].lo = lo; + font->hmtx[font->nhmtx].hi = hi; + font->hmtx[font->nhmtx].w = w; + font->nhmtx++; + + return nil; +} + +fz_error * +fz_addvmtx(fz_font *font, int lo, int hi, int x, int y, int w) +{ + int newcap; + fz_vmtx *newmtx; + + if (font->nvmtx + 1 >= font->vmtxcap) + { + newcap = font->vmtxcap + 16; + newmtx = fz_realloc(font->vmtx, sizeof(fz_vmtx) * newcap); + if (!newmtx) + return fz_outofmem; + font->vmtxcap = newcap; + font->vmtx = newmtx; + } + + font->vmtx[font->nvmtx].lo = lo; + font->vmtx[font->nvmtx].hi = hi; + font->vmtx[font->nvmtx].x = x; + font->vmtx[font->nvmtx].y = y; + font->vmtx[font->nvmtx].w = w; + font->nvmtx++; + + return nil; +} + +static int cmph(const void *a0, const void *b0) +{ + fz_hmtx *a = (fz_hmtx*)a0; + fz_hmtx *b = (fz_hmtx*)b0; + return a->lo - b->lo; +} + +static int cmpv(const void *a0, const void *b0) +{ + fz_vmtx *a = (fz_vmtx*)a0; + fz_vmtx *b = (fz_vmtx*)b0; + return a->lo - b->lo; +} + +fz_error * +fz_endhmtx(fz_font *font) +{ + fz_hmtx *newmtx; + + if (!font->hmtx) + return nil; + + qsort(font->hmtx, font->nhmtx, sizeof(fz_hmtx), cmph); + + newmtx = fz_realloc(font->hmtx, sizeof(fz_hmtx) * font->nhmtx); + if (!newmtx) + return fz_outofmem; + font->hmtxcap = font->nhmtx; + font->hmtx = newmtx; + + return nil; +} + +fz_error * +fz_endvmtx(fz_font *font) +{ + fz_vmtx *newmtx; + + if (!font->vmtx) + return nil; + + qsort(font->vmtx, font->nvmtx, sizeof(fz_vmtx), cmpv); + + newmtx = fz_realloc(font->vmtx, sizeof(fz_vmtx) * font->nvmtx); + if (!newmtx) + return fz_outofmem; + font->vmtxcap = font->nvmtx; + font->vmtx = newmtx; + + return nil; +} + +fz_hmtx +fz_gethmtx(fz_font *font, int cid) +{ + int l = 0; + int r = font->nhmtx - 1; + int m; + + if (!font->hmtx) + goto notfound; + + while (l <= r) + { + m = (l + r) >> 1; + if (cid < font->hmtx[m].lo) + r = m - 1; + else if (cid > font->hmtx[m].hi) + l = m + 1; + else + return font->hmtx[m]; + } + +notfound: + return font->dhmtx; +} + +fz_vmtx +fz_getvmtx(fz_font *font, int cid) +{ + fz_hmtx h; + fz_vmtx v; + int l = 0; + int r = font->nvmtx - 1; + int m; + + if (!font->vmtx) + goto notfound; + + while (l <= r) + { + m = (l + r) >> 1; + if (cid < font->vmtx[m].lo) + r = m - 1; + else if (cid > font->vmtx[m].hi) + l = m + 1; + else + return font->vmtx[m]; + } + +notfound: + h = fz_gethmtx(font, cid); + v = font->dvmtx; + v.x = h.w / 2; + return v; +} + +void +fz_debugfont(fz_font *font) +{ + int i; + + printf("font '%s' {\n", font->name); + printf(" wmode %d\n", font->wmode); + printf(" bbox [%d %d %d %d]\n", + font->bbox.x0, font->bbox.y0, + font->bbox.x1, font->bbox.y1); + printf(" DW %d\n", font->dhmtx.w); + + printf(" W {\n"); + for (i = 0; i < font->nhmtx; i++) + printf(" <%04x> <%04x> %d\n", + font->hmtx[i].lo, font->hmtx[i].hi, font->hmtx[i].w); + printf(" }\n"); + + if (font->wmode) + { + printf(" DW2 [%d %d]\n", font->dvmtx.y, font->dvmtx.w); + printf(" W2 {\n"); + for (i = 0; i < font->nvmtx; i++) + printf(" <%04x> <%04x> %d %d %d\n", font->vmtx[i].lo, font->vmtx[i].hi, + font->vmtx[i].x, font->vmtx[i].y, font->vmtx[i].w); + printf(" }\n"); + } + + printf("}\n"); +} + diff --git a/rosapps/smartpdf/fitz/world/res_image.c b/rosapps/smartpdf/fitz/world/res_image.c new file mode 100644 index 00000000000..2d172669430 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/res_image.c @@ -0,0 +1,23 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +fz_image * +fz_keepimage(fz_image *image) +{ + image->refs ++; + return image; +} + +void +fz_dropimage(fz_image *image) +{ + if (--image->refs == 0) + { + if (image->drop) + image->drop(image); + if (image->cs) + fz_dropcolorspace(image->cs); + fz_free(image); + } +} + diff --git a/rosapps/smartpdf/fitz/world/res_shade.c b/rosapps/smartpdf/fitz/world/res_shade.c new file mode 100644 index 00000000000..4bfc5831e80 --- /dev/null +++ b/rosapps/smartpdf/fitz/world/res_shade.c @@ -0,0 +1,29 @@ +#include "fitz-base.h" +#include "fitz-world.h" + +fz_shade * +fz_keepshade(fz_shade *shade) +{ + shade->refs ++; + return shade; +} + +void +fz_dropshade(fz_shade *shade) +{ + if (--shade->refs == 0) + { + if (shade->cs) + fz_dropcolorspace(shade->cs); + fz_free(shade->mesh); + fz_free(shade); + } +} + +fz_rect +fz_boundshade(fz_shade *shade, fz_matrix ctm) +{ + ctm = fz_concat(shade->matrix, ctm); + return fz_transformaabb(ctm, shade->bbox); +} + diff --git a/rosapps/smartpdf/fitzheadlib.vcproj b/rosapps/smartpdf/fitzheadlib.vcproj new file mode 100644 index 00000000000..f34f4d0de9b --- /dev/null +++ b/rosapps/smartpdf/fitzheadlib.vcproj @@ -0,0 +1,810 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/smartpdf/fitzlib.cbp b/rosapps/smartpdf/fitzlib.cbp new file mode 100644 index 00000000000..a41896600e1 --- /dev/null +++ b/rosapps/smartpdf/fitzlib.cbp @@ -0,0 +1,465 @@ + + + + + + diff --git a/rosapps/smartpdf/fitzlib.vcproj b/rosapps/smartpdf/fitzlib.vcproj new file mode 100644 index 00000000000..7a0292334a2 --- /dev/null +++ b/rosapps/smartpdf/fitzlib.vcproj @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/smartpdf/pdfbench.vcproj b/rosapps/smartpdf/pdfbench.vcproj new file mode 100644 index 00000000000..501301561c1 --- /dev/null +++ b/rosapps/smartpdf/pdfbench.vcproj @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/smartpdf/pdfbenchbase.vcproj b/rosapps/smartpdf/pdfbenchbase.vcproj new file mode 100644 index 00000000000..52798f8cc81 --- /dev/null +++ b/rosapps/smartpdf/pdfbenchbase.vcproj @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/smartpdf/poppler.rbuild b/rosapps/smartpdf/poppler.rbuild new file mode 100644 index 00000000000..70dd21f49ac --- /dev/null +++ b/rosapps/smartpdf/poppler.rbuild @@ -0,0 +1,117 @@ + + ntdll + kernel32 + libjpeg + zlib + freetype + + + + + + + + + + + \"\" + 1 + 1 + + + . + . + include + . + src + baseutils + poppler + poppler/goo + poppler/fofi + poppler/splash + poppler/poppler + + + Annot.cc + Array.cc + BuiltinFont.cc + BuiltinFontTables.cc + Catalog.cc + CharCodeToUnicode.cc + CMap.cc + DCTStream.cc + Decrypt.cc + Dict.cc + FlateStream.cc + FontEncodingTables.cc + Function.cc + Gfx.cc + GfxFont.cc + GfxState.cc + GlobalParams.cc + GlobalParamsWin.cc + JArithmeticDecoder.cc + JBIG2Stream.cc + JPXStream.cc + Lexer.cc + Link.cc + NameToCharCode.cc + Object.cc + Outline.cc + OutputDev.cc + Page.cc + PageLabelInfo.cc + Parser.cc + PDFDoc.cc + PDFDocEncoding.cc + PSTokenizer.cc + SecurityHandler.cc + Sound.cc + SplashOutputDev.cc + Stream.cc + TextOutputDev.cc + UGooString.cc + UnicodeMap.cc + UnicodeTypeTable.cc + XpdfPluginAPI.cc + XRef.cc + + + FastAlloc.cc + FastFixedAllocator.cc + FixedPoint.cc + gfile.cc + gmem.c + gmempp.cc + GooHash.cc + GooList.cc + GooString.cc + GooTimer.cc + + + FoFiBase.cc + FoFiEncodings.cc + FoFiTrueType.cc + FoFiType1.cc + FoFiType1C.cc + + + Splash.cc + SplashBitmap.cc + SplashClip.cc + SplashFont.cc + SplashFontEngine.cc + SplashFontFile.cc + SplashFontFileID.cc + SplashFTFont.cc + SplashFTFontEngine.cc + SplashFTFontFile.cc + SplashPath.cc + SplashPattern.cc + SplashScreen.cc + SplashState.cc + SplashXPath.cc + SplashXPathScanner.cc + + + diff --git a/rosapps/smartpdf/poppler/AUTHORS b/rosapps/smartpdf/poppler/AUTHORS new file mode 100644 index 00000000000..03eae37e643 --- /dev/null +++ b/rosapps/smartpdf/poppler/AUTHORS @@ -0,0 +1,3 @@ +xpdf is written by Derek Noonburg + +libpoppler is a fork of xpdf-3.00 by Kristian Høgsberg diff --git a/rosapps/smartpdf/poppler/COPYING b/rosapps/smartpdf/poppler/COPYING new file mode 100644 index 00000000000..d60c31a97a5 --- /dev/null +++ b/rosapps/smartpdf/poppler/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/rosapps/smartpdf/poppler/ChangeLog b/rosapps/smartpdf/poppler/ChangeLog new file mode 100644 index 00000000000..72b07cff439 --- /dev/null +++ b/rosapps/smartpdf/poppler/ChangeLog @@ -0,0 +1,3339 @@ +2007-01-17 Albert Astals Cid + + * poppler/Sound.h: + * poppler/Sound.cc: + * qt4/src/poppler-sound.cc: Move most of the sound reading code + into the Sound class, so frontends can use it easily. + Patch by Pino Toscano . + +2007-01-13 Albert Astals Cid + + * poppler/Stream.h: + * poppler/Stream.cc: Remove MemStream::setNeedFree method i really did + not need it + * qt4/src/poppler-document.cc: + * qt4/src/poppler-link.cc: + * qt4/src/poppler-page.cc: + * qt4/src/poppler-private.h: Make Document::loadFromData work on + documents with a password and don't need to do a malloc and a memcpy. + +2007-01-13 Albert Astals Cid + + * configure.ac + * poppler/Makefile.am + * qt4/src/Makefile.am + * qt4/src/poppler-document.cc + * qt4/src/poppler-link.cc + * qt4/src/poppler-page.cc + * qt4/src/poppler-private.h + * qt4/src/poppler-qt4.h: Make the Qt4 frontend compilable even with + no Splash backend. Patch by Pino Toscano . + +2007-01-13 Albert Astals Cid + + * poppler/Stream.h: + * poppler/Stream.cc: Add MemStream::setNeedFree method + * qt4/src/poppler-document.cc: + * qt4/src/poppler-private.h: + * qt4/src/poppler-qt4.h: Add Document::loadFromData method + +2007-01-11 Albert Astals Cid + + * goo/gmem.c: Merge change from xpdf-3.01pl2 + +2007-01-11 Albert Astals Cid + + * poppler/Catalog.h: + * poppler/Catalog.cc: Limit max depth of recursive calls on + readPageTree to fix MOAB-06-01-2007 + +2007-01-06 Albert Astals Cid + + * poppler/Sound.cc + * qt4/src/poppler-link.cc + * qt4/src/poppler-link.h + * qt4/src/poppler-page.cc + * qt4/src/poppler-sound.cc: Patch by Pino Toscano + to fix some memory leaks when dealing with sounds. + +2007-01-04 Albert Astals Cid + + * qt4/src/poppler-private.h: gmallocn -> new[] + +2007-01-04 Albert Astals Cid + + * qt/poppler-page-transition.cc: Fix memory leak. Patch by + Tobias Koenig + +2006-12-30 Albert Astals Cid + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-document.cc: Add const & to some parameters. Patch + by Pino Toscano + +2006-12-29 Albert Astals Cid + + * poppler/UGooString.cc: Patch by Pino Toscano + so that QStringToUGooString does not crash. + +2006-12-28 Brad Taylor + + * poppler/glib/poppler-document.h: + * poppler/glib/poppler-document.cc: Add poppler_document_new_from_data + to allow loading PDFs out of memory. + +2006-12-28 Albert Astals Cid + + * qt4/src/poppler-embeddedfile.cc: + * qt4/src/poppler-document.cc: + * qt/poppler-document.cc: Fix memory leaks. + +2006-12-28 Albert Astals Cid + + * goo/GooString.cc + * goo/GooString.h + * goo/gmem.c + * goo/gmem.h + * poppler/Lexer.cc + * poppler/Lexer.h + * poppler/PageLabelInfo.cc + * poppler/Parser.cc + * poppler/UGooString.cc + * poppler/UGooString.h: Patch by Krzysztof Kowalczyk + to improve performance. + See bug 7808 for details. + +2006-12-28 Albert Astals Cid + + * poppler/Annot.cc: + * poppler/Annot.h: Add type checking to processing of "Rect". Patch by + Scott Turner + +2006-12-27 Albert Astals Cid + + * poppler/Catalog.h: + * qt4/src/poppler-qt4.h: Remove , after last value of enum. Thanks to + André Wöbbeking + +2006-12-26 Albert Astals Cid + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-page.cc: Add Page::duration() function to the qt4 + frontend. + +2006-12-26 Albert Astals Cid + + * glib/test-poppler-glib.c: + * glib/poppler-page.cc: + * glib/poppler-page.h: + * poppler/Page.cc: + * poppler/Page.h: Implement /Dur entry in page object. Patch by Carlos + Garcia Campos + +2006-12-23 Albert Astals Cid + + * poppler/PSTokenizer.cc: Enhance PSTokenizer::getToken performance. + Patch by Scott Turner . In a random pdf i tested + the patchs improves PSTokenizer::getToken performance by 15% + +2006-12-23 Albert Astals Cid + + * qt/poppler-page.cc: Fix memory leak in Page::textList. Patch by + Jerry Epplin + + * poppler/Page.cc: Fix memory leak when reading a wrong color map in a + thumbnail. Patch by Scott Turner + +2006-12-20 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Fix scaling of maskedImage masks. They + should be scaled to the size of the image not the size of the mask. + Fixes #9403. + +2006-12-20 Jeff Muizelaar + + * poppler/GlobalParams.cc: Try to make zero-width lines as close to + one pixel wide as we can. Fixes #9393. + +2006-12-19 Albert Astals Cid + + * poppler/SplashOutputDev.cc: Fix gray calculation. Patch by Scott + Turner + +2006-12-12 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Change a cairo_set_matrix to + cairo_transform so that we don't blindly clobber the existing matrix. + Patch by Daniel Colascione. + Fixes #9190. + +2006-12-09 Jeff Muizelaar + + * poppler/Function.cc: Initialize PostScriptFunction::codeString to + NULL so that it can safely deleted if initialization fails. + Fixes #9263. + +2006-11-23 Albert Astals Cid + + * m4/libjpeg.m4: Make JPEG library header search work under MSYS. + Patch by Alexis Wilke + +2006-11-19 Albert Astals Cid + + * qt4/src/poppler-link.cc: + * qt4/src/poppler-page.cc: + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-textbox.cc: Fix memory leaks + * splash/Splash.cc: Initialize the values of nClipRes + +2006-11-18 Albert Astals Cid + + * qt4/src/poppler-document.cc + * qt4/src/poppler-qt4.h: Add int marginRight, int marginBottom, int + marginLeft, int marginTop, bool strictMargins to Document::print() + +2006-11-15 Albert Astals Cid + + * qt4/src/Mainpage.dox: + * qt4/src/Doxyfile: + * qt4/src/poppler-annotation.h: + * qt4/src/poppler-link.h: + * qt4/src/poppler-qt4.h: Improve API documentation. Patch by + Pino Toscano. + +2006-11-15 Albert Astals Cid + + * qt4/src/poppler-link.cc: + * qt4/src/poppler-page.cc: + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-document.cc: + * qt4/src/poppler-private.h: Generalize the way we render the pages: + merge all the Page::renderTo* functions in only one that renders on + a QImage, taking into account the currently chosen backend. + It is possible to switch rendering backend using the Document. + Patch by Pino Toscano. + + * qt4/tests/stress-poppler-qt4.cpp: + * qt4/tests/test-password-qt4.cpp: + * qt4/tests/test-poppler-qt4.cpp: Adapt the tests to the changes in + the rendering API of Page. Patch by Pino Toscano. + +2006-11-13 Albert Astals Cid + + * poppler/ArthurOutputDev.cc: Small fix to get colors right + +2006-11-11 Albert Astals Cid + + * poppler/PSOutputDev.cc: Fix typo when outputing PS scale + +2006-11-07 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: take horizontal scaling into account + when updating the font. Also, cleanup some unused code. Fixes #8924. + +2006-10-18 Albert Astals Cid + + * qt4/src/poppler-document.cc: + * qt4/src/poppler-private.h: Do not crash when opening a + encrypted document. Do not crash when unlocking a locked + document. + +2006-10-12 Albert Astals Cid + + * splash/Splash.cc: + * splash/SplashErrorCodes.h: Do not crash on documents that report a + 0x0 mask for an image, like + http://bugs.kde.org/attachment.cgi?id=18083&action=view + +2006-10-08 Albert Astals Cid + + * poppler/Link.cc: + * poppler/Link.h: + * poppler/Makefile.am: + * poppler/Page.cc: + * poppler/Page.h: + * poppler/Sound.cc: + * poppler/Sound.h: Make poppler able to read Sound objects, Sound + actions and Opening/Closing page actions. Patch by Pino Toscano. + + * qt4/src/Makefile.am: + * qt4/src/poppler-link.cc: + * qt4/src/poppler-link.h: + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-page.cc: + * qt4/src/poppler-sound.cc: Support for sounds, sound links and page + actions in the Qt4 backend. Patch by Pino Toscano. + +2006-09-30 Albert Astals Cid + + * qt4/src/poppler-page.cc: PA is optional, H is a name not a string + +2006-09-25 Albert Astals Cid + + * glib/Makefile.am + * qt/Makefile.am + * qt4/src/Makefile.am + * qt4/tests/Makefile.am + * test/Makefile.am + * utils/Makefile.am: Add FONTCONFIG_CFLAGS FONTCONFIG_LIBS for people + that need them. Patch by morfoh@opensde.org. Fixes bug #8415 + +2006-09-21 Kristian Høgsberg + + * NEWS: Update list of bugs fixes, release 0.5.4. + + * configure.ac: Check for gtk+ 2.8 for the gtk+ test case, invert + help text for zlib option (#7788, #7661). + + * utils/pdftops.cc: Get duplex setting from GlobalParams. + + * glib/poppler-page.cc (_poppler_page_new): Make PopplerPage + reference its document throughout the lifetime of the page (#7005). + + * poppler/Gfx.cc: Remove the right out->updateAll() call. + +2006-09-20 Kristian Høgsberg + + * NEWS: Sum up changes. + + * configure.ac: Bump release to 0.5.4. + + * poppler/Gfx.cc: Remove last remnant of erroneous type3 commit a + while back, fixing #8182. + +2006-09-20 Jeff Muizelaar + + * poppler/TextOutputDev.cc: TextFontInfo stores a copy of a pointer + to a GfxFont but does not increment the reference count. Fix the + problem by calling incRefCnt and decRefCnt appropriately. Fixes #4649 + +2006-09-19 Kristian Høgsberg + + * poppler/GlobalParams.cc: Add scanEncodingDirs() to automatically + scan in any encodings found under ${datadir}/poppler. + + * m4/define-dir.m4: New file, adds AC_DEFINE_DIR macro. + +2006-09-13 Kristian Høgsberg + + * poppler/Makefile.am (libpoppler_la_LIBADD): Add cairo libs to + link if configured. + + * configure.ac: Tighten glib check (#7906), add check for C++ + compiler (#8048). + +2006-09-11 Albert Astals Cid + + * qt4/src/poppler-annotation.cc: + * qt4/src/poppler-annotation.h: + * qt4/src/poppler-page.cc: Add support for LinkAnnotation. Patch by + Pino Toscano + +2006-09-08 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: The work-around for 1x1 imagemasks was + not calling cairo_set_source causing the rectangles to be drawn + the wrong colour occasionally. Fix by moving the existing call to + cairo_set_source above the work-around. Fixes #7113. + +2006-09-06 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Avoid crashing in CairoOutputDev if + endString is called without a corresponding beginString. Fixes #4515. + +2006-09-06 Jeff Muizelaar + + * configure.ac: + * poppler/FlateStream.cc: + * poppler/FlateStream.h: Fix FlateStream to not read more than it + needs. This has a performance impact because our input buffer is now + only 1 byte large, however correctness is better than performance. + This should fix #3948. + +2006-09-04 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Initialize currentFont to NULL before + use. Found by Pascal Terjan. Fixes #7924. + +2006-09-03 Albert Astals Cid + + * poppler/Dict.cc: + * poppler/Dict.h: + * poppler/Object.h: + * poppler/Parser.cc: Patch by Krzysztof Kowalczyk to increase speed by + means of doing less copies between objects. See bug 8112 for more + information. + +2006-08-25 Albert Astals Cid + + * qt4/src/poppler-private.h: Init m_fontInfoScanner to NULL. Discovered by + Rafael Rodríguez + +2006-08-16 Albert Astals Cid + + * qt/poppler-page.cc: Report correct page size. Backport from Qt4 + frontend. Patch by Wilfried Huss + +2006-08-16 Albert Astals Cid + + * configure.ac: Add a warning saying zlib code is not perfect. + +2006-08-11 Albert Astals Cid + + * poppler/Catalog.cc: Fix leak + +2006-08-10 Albert Astals Cid + + * poppler/SplashOutputDev.cc: Try to fix refs to fonts yet again. + +2006-08-05 Albert Astals Cid + + * poppler/Catalog.cc: The name array can contain references to strings + instead of stings themselves, or at least PDF of + https://bugs.freedesktop.org/show_bug.cgi?id=7780 does. This makes it + work with that file + * qt4/src/poppler-embeddedfile.cc: Use UGooString for description + +2006-08-05 Albert Astals Cid + + * utils/pdftotext.cc: + * utils/pdfinfo.cc: + * utils/pdffonts.cc: Add the posibility of reading a file from stdin. + Patch by Dom Lachowicz + +2006-08-03 Albert Astals Cid + + * configure.ac: Use the correct variable to output the utils status. + Patch by Dom Lachowicz + +2006-07-30 Albert Astals Cid + + * poppler/GfxState.cc: make nGfxBlendModeNames define return the + correct size of the gfxBlendModeNames array so it does not access + invalid memory areas when the blend mode is not found. Discovered by + Krzysztof Kowalczyk + +2006-07-29 Albert Astals Cid + + * splash/SplashFontEngine.cc: + * poppler/SplashOutputDev.cc: Fix memory leak when using embedded + fonts in the pdf file. Patch by Krzysztof Kowalczyk + +2006-07-29 Albert Astals Cid + + * configure.ac: Disable qt and qt4 frontends if splash backend is + disabled + +2006-07-28 Kristian Høgsberg + + * poppler/CairoOutputDev.cc: Don't set font matrix translation + (fix from Behdad Esfahbod). + +2006-07-27 Albert Astals Cid + + * poppler/Stream.cc: If you are going to test a variable, better + initialize it first ;-) Fixes bug 7646 + +2006-07-26 Albert Astals Cid + + * qt/poppler-document.cc: + * qt/poppler-private.h: + * qt/poppler-qt.h: Port the QDomDocument *Document::toc() const method + from the qt4 frontend to the qt frontend. Patch by Wilfried Huss + +2006-07-25 Albert Astals Cid + + * qt4/src/poppler-document.cc: Obey kdeprint masters in that a library + should output as much device independent PS as posible, so disabling + duplex printing for default is a good idea. + +2006-07-24 Kristian Høgsberg + + * configure.ac: + * poppler/Makefile.am: Move fontconfig dependency to libpoppler. + +2006-07-18 Jeff Muizelaar + + * poppler/Gfx.cc: fix opCloseStroke to match the behaviour of + a separate opClose and opStroke. Previously, opCloseStroke only + closes if there is a path however opClose closes unconditionally. + +2006-07-18 Jeff Muizelaar + + * poppler/TextOutputDev.cc: call setDefaultCTM() after start page + like in Gfx.cc. This fixes a regression caused by the fix to #6948. + +2006-07-16 Albert Astals Cid + + * poppler/GfxState.cc: Do not crash when we can not + parse a GfxImageColorMap + Fixes crash on pdf that can be found at + http://bugs.kde.org/show_bug.cgi?id=130846 + +2006-06-28 Albert Astals Cid + + * poppler/DCTStream.cc: + * poppler/DCTStream.h: Reset jpeg structures on reset. + Fixes crash while printing pdf at + http://bugs.kde.org/attachment.cgi?id=16818&action=view + +2006-06-25 Albert Astals Cid + + * qt/poppler-document.cc + * qt/poppler-qt.h + * qt4/src/poppler-document.cc + * qt4/src/poppler-qt4.h: Ask for paper size width and height to pass + it to PSOutputDev + +2006-06-25 Albert Astals Cid + + * qt/Makefile.am + * qt/poppler-document.cc + * qt/poppler-page.cc + * qt/poppler-private.h + * qt/poppler-qt.h + * qt/poppler-link.cc + * qt/poppler-link.h: Adding link support to Qt3 frontend, patch by + Wilfried Huss based on Qt4 code + +2006-06-11 Albert Astals Cid + + * poppler/UGooString.cc: When any of the chars that we + are passing to the UGooString is not pdfencodable, do not + encode the string, because we loose information if we do, + this fixes rendering of + http://publikationen.ub.uni-frankfurt.de/volltexte/2005/890/pdf/TR_abs_g.pdf + and other docs with type3 fonts and ligatures + +2006-06-01 Albert Astals Cid + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-page.cc: Add Rotation parameter that is passed + to the respective output devs + +2006-06-01 Albert Astals Cid + + * qt/poppler-document.cc: + * qt/poppler-qt.h: Add printing support, patch by + Stefan Kebekus + +2006-06-01 Jeff Muizelaar + + * poppler/PSOutputDev.cc: + * poppler/PSOutputDev.h: Change filename parameter to PSOutputDev + constructor from char * to const char *. + +2006-05-31 Albert Astals Cid + + * poppler/SplashOutputDev.cc: + * splash/Splash.cc: Fix splashModeRGB8Qt mode, that is, make it + show images + +2006-05-31 Jeff Muizelaar + + * TODO: Remove items's from my list that are done. + +2006-05-31 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: Change the cairo backend to use the + transformation in cairo instead of doing all of the transformations in + the OutputDevice. Fixes #6948. + +2006-05-31 Kristian Høgsberg + + * NEWS: Sum up changes. + + * configure.ac: Bump release to 0.5.3. + +2006-05-30 Kristian Høgsberg + + * poppler-glib.pc.in: + * configure.ac: Add poppler as a private requires if pkg-config + supports it. + +2006-05-30 Kristian Høgsberg + + * test/gtk-cairo-test.cc: Add --page option to gtk-cairo-test. + +2006-05-29 Jeff Muizelaar + + * poppler/CairoFontEngine.cc: + * poppler/CairoFontEngine.h: + * poppler/CairoOutputDev.cc: Allow CairoFont creation to fail more + gracefully. Fixes #4030. + +2006-05-27 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: Back out the rest of krh's type3 + font work. This fixes type3 fonts in CairoOutputDevice. + +2006-05-21 Albert Astals Cid + + * poppler/SplashOutputDev.cc: + * qt4/src/poppler-private.h: + * splash/Splash.cc: + * splash/SplashBitmap.cc: + * splash/SplashTypes.h: bring splashModeRGB8 back to the old code + (before Frank's patch), create splashModeRGB8Qt that has Frank's + codepath and is used by Qt frontends. Fixes corruption on + other programs expecting the old behaviour. + +2006-05-23 Kristian Høgsberg + + * qt4/src/Makefile.am (libpoppler_qt4_la_SOURCES): Add missing + poppler-annotation-helper.h. + +2006-05-22 Kristian Høgsberg + + * configure.ac: Bump release. + * NEWS: Sum up changes. + +2006-05-22 Kristian Høgsberg + + Patch from Rainer Keller to fix the ImageOutputDev (#6984). + + * utils/ImageOutputDev.cc (drawImage): Upate to work with new + 16-bit color representation. + + * utils/ImageOutputDev.h: Return gTrue for needNonText(). + +2006-05-21 Kristian Høgsberg + + * poppler/CairoFontEngine.cc: + * poppler/CairoFontEngine.h: Back out type3 font work committed by + accident. + +2006-05-21 Albert Astals Cid + + * qt4/src/poppler-page.cc: + * qt/src/poppler-page.cc: Swap byte order on bigendian machines. + Thanks a lot to Jonathan Riddell for letting me use + his minimac for testing + +2006-05-19 Kristian Høgsberg + + * glib/poppler-action.h: + * glib/poppler-action.cc: Add poppler_dest_get_type(), patch from + Kouhei Sutou (#6907). + + * poppler-glib.pc.in (Requires): Add gdk-2.0 dependency, from + Kouhei Sutou (#6896). + + * glib/poppler-document.h (POPPLER_TYPE_INDEX_ITER) + (POPPLER_TYPE_FONTS_ITER): Add these macros, patch from Kouhei + Sutou (#6897). + + * glib/Makefile.am (INCLUDES): Add define for G_LOG_DOMAIN, from + Kouhei Sutou (#6899). + + * glib/poppler-document.cc (poppler_document_save): Memleak patch + from Paolo Borelli (#6908). + +2006-05-19 Kristian Høgsberg + + * TextOutputDev.h: + * TextOutputDev.cc: + * UnicodeTypeTable.h: + * UnicodeTypeTable.cc: + * UnicodeCClassTables.h: + * UnicodeCompTables.h: + * UnicodeDecompTables.h: + * gen-unicode-tables.py: Patch from Ed Catmur (#2929) to convert + search string and document text to unicode NFKC (compatibility + composition) before matching so ligatures match correctly. + +2006-05-19 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_prepare_output_dev): Fix the + rotation bug for real. + +2006-05-19 Kristian Høgsberg + + Patch from Kouhei Sutou (#6905). + + * glib/poppler-document.cc: + * glib/poppler-document.h: + * glib/poppler-private.h: + * glib/reference/tmpl/poppler-private.sgml: + * glib/reference/tmpl/poppler.sgml: Make PopplerPSOutput a proper + glib object. + +2006-05-19 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_prepare_output_dev): Fix + rotation bug (#6913, #6926). + + Memory leak patch from Carlos Garcia Campos (#6947). + + * glib/poppler-action.cc: + * glib/poppler-document.cc: + * glib/poppler-page.cc: + * poppler/CairoFontEngine.cc: + * poppler/CairoFontEngine.h: + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: + * poppler/Gfx.cc: + * poppler/TextOutputDev.cc: Fix various memory leaks. + +2006-05-19 Albert Astals Cid + + * qt4/src/poppler-link.cc: Patch by Pino Toscano, ensure the + splashoutput is created when parsing the TOC. + +2006-05-14 Albert Astals Cid + + * poppler/FontInfo.cc: Fix possible crash, half patch + by Kouhei Sutou + +2006-05-13 Albert Astals Cid + + * poppler/GfxState.cc: + * poppler/GfxState.h: Fix memleak, patch by + Carlos Garcia Campos + +2006-05-13 Albert Astals Cid + + * qt4/src/poppler-document.cc: leak-- + * qt4/src/poppler-private.h: Refcount globalparams + * qt4/tests/test-poppler-qt4.cpp: Some leaks less + +2006-05-12 Albert Astals Cid + + * qt4/src/Makefile.am + * qt4/src/poppler-annotation-helper.h + * qt4/src/poppler-annotation.cc + * qt4/src/poppler-annotation.h + * qt4/src/poppler-link.cc + * qt4/src/poppler-link.h + * qt4/src/poppler-page.cc + * qt4/src/poppler-qt4.h: Code for annotations stripped from oKular, + it's all based on Enrico's work, so ask him for details, the problem + is that he left KDE development a while ago. + + +2006-05-09 Albert Astals Cid + + * qt4/src/Makefile.am: + * qt4/src/poppler-document.cc: + * qt4/src/poppler-link.cc: + * qt4/src/poppler-page.cc: + * qt4/src/poppler-private.h: + * qt4/src/poppler-qt4.h: Adding links extraction code, should work as + it is basically stripped out from kpdf + +2006-05-05 Albert Astals Cid + + * poppler/Catalog.cc: Fix memleak, patch by + Carlos Garcia Campos + +2006-05-05 Albert Astals Cid + + * poppler/Function.cc: quick fix for KDE bug #126760 + +2006-05-04 Albert Astals Cid + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-page.cc: Implement search functionality + +2006-05-02 Kristian Høgsberg + + * glib/poppler-page.cc: + * poppler/Gfx.cc: + * poppler/GfxFont.cc: + * poppler/GfxFont.h: + * poppler/GfxState.cc: + * poppler/TextOutputDev.cc: Patch from Gary Coady to add reference + counting to GfxFont so we don't crash on text selection (#4481). + +2006-05-01 Albert Astals Cid + + * qt4/src/poppler-page.cc: + * qt4/src/poppler-private.h: + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-textbox.cc: Add nextWord(), hasSpaceAfter() and + edge() to TextBox + +2006-05-01 Albert Astals Cid + + * qt4/src/poppler-document.cc: + * qt4/src/poppler-private.h: + * qt4/src/poppler-qt4.h: Add the possibility of setting the paper + color + +2006-04-29 Albert Astals Cid + + * poppler/JBIG2Stream.cc: fix memory leak. Bug 6765, reported by + Kjartan Maraas. + +2006-04-27 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: delete imgStr if some of the cairo + functions fail. Fixes coverty reports #2106, #2107, #2077 and + bug #6764. Patch by Kjartan Maraas. + +2006-04-23 Albert Astals Cid + + * qt4/src/poppler-private.h: Protect us against a link not having + a destination or a namedDestination + +2006-04-18 Albert Astals Cid + + * goo/GooVector.h: Fix typo that was preventing build with MSVC8 + Discovered by Reece Dunn + +2006-04-16 Carlos Garcia Campos + + * glib/poppler-action.cc: + * glib/poppler-action.h: + * glib/poppler-private.h: + * glib/poppler.h: + Add support for named destinations and named actions. + + * glib/poppler-document.cc: + * glib/poppler-document.h: + Allow to find named destinations in document. + +2006-04-12 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: Add support for masked images to the cairo + backend. CairoOutputDevice really should have been refactored before + committing this, but the results were so pretty I couldn't resist. + Fixes #6174. + +2006-04-12 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Fix breakage by krh by only calling + cairo_destroy on non-null. + +2006-04-11 Kristian Høgsberg + + * configure.ac: + * poppler-glib.pc.in: + * glib/Makefile.am: + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler.h: + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: + * glib/poppler-features.h.in: + Make the CairoOutputDev render to a cairo_t instead of a + cairo_surface_t and expose that functionality in the glib wrapper + (poppler_page_render). + + * test/Makefile.am: + * test/gtk-cairo-test.cc: + Update gtk-cairo-test to use this new interface and add a spin + button for changing page (#5951). + + * utils/Makefile.am (EXTRA_DIST): Fix warning where this was + assigned twice. + +2006-04-10 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: take originX and originY into account in + drawChar() to draw vertical text properly. Fixes #6551. + +2006-04-09 Albert Astals Cid + + * m4/qt.m4: Improve for systems that need -pthread to be linked when + linking Qt. Patch by Diego Pettenò + +2006-04-08 Albert Astals Cid + + * poppler/Makefile.am: + * qt4/src/Makefile.am: Don't link Qt4 in libpoppler when using Qt4 frontend + Patch by Stefan Schweizer + +2006-04-05 Albert Astals Cid + + * poppler/JBIG2Stream.cc: Fix for some buggy JBIG2 documents, patch by + Raj Kumar and Paul Walmsley. Fixes bug 6500 + +2006-04-05 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: use a separate matrix for the softmask. + fixes #6492. + +2006-04-04 Albert Astals Cid + + * splash/Splash.cc: + * splash/SplashBitmap.cc: Make Splashbitmap RGB8 use 32bits internally + * qt/poppler-page.cc: + * qt4/src/poppler-page.cc: Adapt to splashbitmap change so copying to + QImage is faster. + Patch by Frank Meerkötter slightly modified by Albert Astals Cid + +2006-04-04 Albert Astals Cid + + * splash/SplashFTFont.cc: Fix crash when using fixedpoint math. Patch + by Frank Meerkoetter + +2006-04-02 Albert Astals Cid + + * m4/qt.m4: Add QtXml lib to Qt4 binding as now it's needed + * qt4/src/poppler-document.cc: Add the possibility to get the toc of + a file, print it to PS and get a LinkDestination from a "symbolic" name + * qt4/src/poppler-page.cc: Add the possibility of getting the defaultCTM + +2006-04-01 Albert Astals Cid + + * poppler/XRef.cc: Fix parsing of some TOCs, bug was due a int to uint + comparison, sorry for introducing that bug. Fixes bug 6454 + +2006-03-20 Jeff Muizelaar + + * glib/poppler-page.cc: Avoid strdup in poppler_page_get_property and + make code cleaner. Combined with the memleak fix closes #6187. + Patch by chpe. + +2006-03-20 Jeff Muizelaar + + * glib/poppler-page.cc: Fix memory leak in poppler_page_get_text + Patch by chpe. + +2006-03-20 Albert Astals Cid + + * qt/poppler-document.cc: + * qt4/src/poppler-document.cc: Use UGooString for dates, fixes KDE + bug 123938 + +2006-03-20 Carlos Garcia Campos + + reviewed by: Jeff Muizelaar + + * glib/poppler-document.cc: Fix memory leak in poppler_font_info_free + +2006-03-20 Jeff Muizelaar + + * poppler/CairoFontEngine.h: remove unused variables + +2006-03-19 Albert Astals Cid + + * utils/HtmlOutputDev.[cc|h]: Fix broken code + +2006-03-16 Albert Astals Cid + + * poppler/Page.cc: Remove a #ifdef that was never defined (nice to + have so sucky W args), probably came from gpdf (it's not on xpdf + sources) and was causing bugs 6079 and 6167 + +2006-03-16 Albert Astals Cid + + * poppler/FontInfo.cc: Embedded fonts don't have a font file + +2006-03-14 Albert Astals Cid + + * qt4/src/poppler-qt4.h: Fix compilation with gcc4.1, patch by + Michael Olbrich + +2006-03-11 Albert Astals Cid + + * poppler/FontInfo.cc: + * poppler/FontInfo.h: Add getFile() function that returns + the path of the font that is beign used in the system to + represent that font + * qt4/src/poppler-document.cc: + * qt4/src/poppler-fontinfo.cc: + * qt4/src/poppler-private.h: + * qt4/src/poppler-qt4.h: Add the file() function + * qt4/tests/poppler-fonts.cpp: Show the path of the font + used to represent each font + +2006-03-09 Albert Astals Cid + + * glib/Makefile.am: Build with cairo disabled, patch by Eduardo de + Barros Lima + +2006-02-28 Kristian Høgsberg + + * configure.ac: Bump release to 0.5.1. + + * NEWS: Sum up 0.5.1 changes so far. + + * TextOutputDev.h: add getters for a couple of attributes. + + * glib/Makefile.am: + * poppler/Makefile.am: Move cairo link dependency to glib bindings. + +2006-02-28 Kristian Høgsberg + + * goo/gmem.c: (gmalloc), (grealloc): + * poppler/JBIG2Stream.cc: + * poppler/Stream.cc: + * poppler/Stream.h: + * splash/SplashXPathScanner.cc: + + More integer overflow fixes from Derek Noonburg (#5922). + +2006-02-28 Kristian Høgsberg + + * poppler/PSOutputDev.cc: Make PSOutputDev constructor respect + passed in paper size (#5946, #5749). + +2006-02-28 Kristian Høgsberg + + * glib/poppler-document.cc (info_dict_get_string): Refactor + _popper_goo_string_to_utf8() out into it's own function. + + * glib/poppler-page.cc (poppler_page_get_property): Use + _popper_goo_string_to_utf8() here to convert ucs2 page labels. + + * glib/poppler-page.cc (poppler_page_get_selection_region): Add + braces to fix warning. + + * poppler/PageLabelInfo.cc: If the label prefix string has a ucs2 + marker, append the number part of the label as ucs2 (#5952). + +2006-02-25 Albert Astals Cid + + * poppler/Object.cc: Fix warning + +2006-02-23 Albert Astals Cid + + * utils/Makefile.am: Do not build pdftoppm when SplashOutputDev is + disabled as that does not work + +2006-02-18 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: + * poppler/GfxState.cc: + * poppler/GfxState.h: Add support for drawSoftMaskedImage to + CairoOutputDev. Ugly but works. + +2006-02-16 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Work around cairo bug when scaling + 1x1 bitmaps. Fixes #3387. Also gives a performance improvement. + +2006-02-16 Albert Astals Cid + + * qt4/src/Makefile.am: + * qt/Makefile.am: + * poppler/Makefile.am: + * glib/Makefile.am: Update soname as we are not really compatible + anymore with previous releases that had soname 0.0.0 + +2006-02-13 Albert Astals Cid + + * poppler/ArthurOutputDev.cc: Make it compile after changing code so + we did not pass files to freetype but buffers + +2006-02-13 Albert Astals Cid + + * poppler/PSOutputDev.cc: Commit setupExternalCIDTrueTypeFont patch + kpdf got from Takashi Iwai (SuSe) a long time ago + +2006-02-06 Albert Astals Cid + + * configure.ac: + * goo/FixedPoint.h: + * splash/Splash.cc: + * splash/SplashTypes.h: Various fixes from Frank Meerkötter to enable + fixedpoint arithmetic + +2006-02-06 Albert Astals Cid + + * poppler/Annot.cc: Fix small leaks + * poppler/JBIG2Stream.cc: Remove check improving as really did not + improve anything + +2006-02-05 Albert Astals Cid + + * poppler/Gfx.cc: Fix small leak + * poppler/GfxFont.cc: I needed that guard in kpdf to fix a crash and + it surely does not hurt + * poppler/JBIG2Stream.cc: Improve check (comes from kpdf) + * poppler/SplashOutputDev.cc: Unneeded var-- + +2006-02-04 Jeff Muizelaar + + * poppler/Gfx.cc: + * poppler/OutputDev.cc: + * poppler/OutputDev.h: Let output devices know about pdf grouping + operators. + Patch by Thorkild Stray. + +2006-02-04 Jeff Muizelaar + + * poppler/GlobalParams.cc: Check all fonts returned by fontconfig. + Discard the ones that are not truetype or type1. Fixes #5758. + Patch by Ed Catmur. + +2006-02-04 Albert Astals Cid + + * utils/Makefile.am: + * utils/pdftoppm.cc: Actually create pdftoppm patch by Stefan + Schweizer + * utils/pdf2xml.dtd: Added a DTD of the xml pdftohtml creates patch by + Stefan Schweizer + * poppler/SplashOutputDev.cc: Remove bug from "do not use an external + file to pass fonts to Freetype" patch, patch by Stefan Schweizer + + +2006-02-02 Albert Astals Cid + + * splash/SplashXPathScanner.cc: CVE-2006-0301 fix by Derek (xpdf man + itslef) got though Dirk Mueller of KDE security team + +2006-02-02 Albert Astals Cid + + * fofi/FoFiTrueType.cc: + * fofi/FoFiTrueType.h: + * fofi/FoFiType1C.h: + * goo/gfile.cc: + * poppler/GfxFont.cc: + * poppler/GfxFont.h: + * poppler/GlobalParams.cc: + * poppler/GlobalParams.h: + * poppler/SplashOutputDev.cc: + * splash/SplashFTFontEngine.cc: + * splash/SplashFTFontEngine.h: + * splash/SplashFTFontFile.cc: + * splash/SplashFTFontFile.h: + * splash/SplashFontEngine.cc: + * splash/SplashFontEngine.h: + * splash/SplashFontFile.cc: + * splash/SplashFontFile.h: + * splash/SplashT1FontEngine.cc: + * splash/SplashT1FontFile.cc: + * splash/SplashT1FontFile.h: Merge patch to not use external file + when passing the font to Freetype, original patch by Takashi Iwai + adapted by me to kpdf rediffed by Stefan Schweizer against poppler + cvs + +2006-01-31 Jeff Muizelaar + + * poppler/GlobalParams.cc (GlobalParams::getDisplayFont): + Allow ttc fonts to be used. + +2006-01-28 Jeff Muizelaar + + * glib/poppler-attachment.h: fix compile by adding include. + Acked-by: Jonathan Blanford + +2006-01-26 Kristian Høgsberg + + * poppler/CairoOutputDev.cc: Patch from Christian Krause; handle + 0-width lines (#5545). + +Tue Jan 24 01:19:40 2006 Jonathan Blandford + + * glib/Makefile.am: + * glib/poppler-attachment.cc: + * glib/poppler-attachment.h: + * glib/poppler-document.cc: + * glib/poppler-document.h: + * glib/poppler-page.cc: + * glib/poppler-private.h: + * glib/poppler.h: + * glib/test-poppler-glib.c: + * glib/reference/tmpl/poppler-enums.sgml: + * glib/reference/tmpl/poppler-unused.sgml: glib bindings for the + embedded file support. It doesn't support mtime and ctime yet, + but the rest works. + +2006-01-23 Kristian Høgsberg + + * configure.ac: + * poppler/GlobalParams.cc: + * poppler/poppler-config.h.in: + * utils/pdftohtml.cc: + * utils/pdftops.cc: Respect command line paper size settings (#5641). + Drop the built-in paper sizes. + +2006-01-23 Kristian Høgsberg + + * glib/test-poppler-glib.c (print_document_info, print_index): + Move variable declarations to top (#5692). + + * utils/*.cc: Move config.h #include to top of #include's (#5693). + + * splash/SplashFTFont.cc: Don't use deprecated freetype include + files. + +2006-01-21 Jeff Muizelaar + + * TODO: Add my todo list. + +2006-01-18 Albert Astals Cid + + * glib/poppler-action.cc: + * glib/poppler-document.cc: + * poppler/Annot.cc: + * poppler/Catalog.cc: + * poppler/Catalog.h: + * poppler/Dict.cc: + * poppler/Dict.h: + * poppler/FontInfo.cc: + * poppler/Function.cc: + * poppler/Gfx.cc: + * poppler/GfxFont.cc: + * poppler/GfxState.cc: + * poppler/Link.cc: + * poppler/Link.h: + * poppler/Makefile.am: + * poppler/Object.h: + * poppler/Outline.cc: + * poppler/PDFDoc.cc: + * poppler/PDFDoc.h: + * poppler/PSOutputDev.cc: + * poppler/Page.cc: + * poppler/PageLabelInfo.cc: + * poppler/Parser.cc: + * poppler/SecurityHandler.cc: + * poppler/Stream.cc: + * poppler/XRef.cc: + * qt/poppler-document.cc: + * qt/poppler-page-transition.cc: + * qt4/src/Makefile.am: + * qt4/src/poppler-document.cc: + * qt4/src/poppler-private.h: + * qt4/src/poppler-qt4.h: + * qt4/tests/Makefile.am: + * utils/HtmlOutputDev.cc: + * utils/pdffonts.cc: + * utils/pdfinfo.cc: + * utils/pdftohtml.cc: + * utils/pdftotext.cc: Brad patch for embedded document extraction, + only has Qt4 bindings for now, needs Qt3 and glib work + +2006-01-18 Albert Astals Cid + + * qt/poppler-page-transition.h: + * qt4/src/Doxyfile: Add some more documentation to PageTransition, + patch by Stefan Kebekus + +2006-01-18 Albert Astals Cid + + * poppler/CharCodeToUnicode.cc: Fix check for length that was not + having into account that there could be \n or \r in tokens an that + those do not have to be took into account. Fixes + http://bugs.kde.org/show_bug.cgi?id=120310 + +2006-01-17 Albert Astals Cid + + * poppler/Lexer.cc: + * poppler/Lexer.h: + * poppler/Parser.cc: + * poppler/Parser.h: + * poppler/XRef.cc: + * poppler/XRef.h: When doing the parsing check with XREF we did not + grow too much. Fixes serialata10a.pdf + +2006-01-12 Jeff Muizelaar + + * poppler/GlobalParams.cc: Make buildFcPattern() static. + +2006-01-11 Kristian Høgsberg + + * poppler/JBIG2Stream.cc: + * poppler/Stream.cc: Merge patch to fix CVE-2005-3624, + CVE-2005-3625 and CVE-2005-3627 issues. + +2006-01-10 Albert Astals Cid + + * configure.ac: + * m4/qt.m4: Fix bugs created when splitting the code from + configure.ac, take QTDIR into account when looking for QtTestLib and + do not die if it is not found as it is not mandatory + * qt/poppler-page-transition.cc: + * qt/poppler-page.cc: + * qt/poppler-private.h: + * qt4/tests/Makefile.am: + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-page.cc: + * qt4/src/Makefile.am: Fix mess created my the moving and renaming of + PageTransition.cc + +2006-01-10 Kristian Høgsberg + + * splash/Makefile.am: Only install splash headers if + --enable-xpdf-headers is given. + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Set this here. + +2006-01-10 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: + Fix the following fixme in CairoOutputDevice. + + // FIXME: This is quite right yet, we need to accumulate all + // glyphs within one text object before we clip. Right now this + // just add this one string. + + The fix uses a strategy similar to the one the Splash backend. + textClipPath is used to store the appended path from each call to + endString(). The accumulated path is clipped in endTextObject. + +2006-01-08 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Don't try and load type3 fonts (#4030). + +2006-01-08 Jeff Muizelaar + + * poppler/Page.cc: use colToByte for reading thumbnails (#5420). + + Patch by Nickolay V. Shmyrev. + +2006-01-07 Jeff Muizelaar + + * poppler/CairoOutputDev.cc: Initialize (fill|stroke)_opacity. + +2006-01-06 Kristian Høgsberg + + * qt/poppler-page.cc: + * qt/poppler-private.h: + * qt/poppler-qt.h: + * qt4/src/Makefile.am: + * qt/Makefile.am: + * poppler/Makefile.am: Move PageTransition to qt bindings, move + contents from Private.h to qt/poppler-private.h. + + * poppler/TextOutputDev.cc (visitWord): Remove #warning. + + * utils/Makefile.am (pdfimages_SOURCES): Add ImageOutputDev.h, use + dist_man1_MANS so we actually dist the man pages. + + * goo/Makefile.am (poppler_goo_include_HEADERS): Add GooVector.h. + + * glib/reference/Makefile.am: DOC_SOURCE_DIR must be relative to + $(srcdir), fix this to make distchek run. + + * m4/qt.m4: + * m4/libjpeg.m4: + * acinclude.m4: + * configure.ac: Split out Qt and libjpeg checks from configure.ac + and acinclude.m4 to m4/qt.m4 and m4/libjpeg.m4. + +2006-01-06 Albert Astals Cid + + * poppler/DCTStream.cc: Fix handling of malformed jpeg streams like + the one at http://bugs.kde.org/show_bug.cgi?id=119569 + +2006-01-02 Albert Astals Cid + + * qt/poppler-page.cc: + * qt/poppler-qt.h: + * qt4/src/poppler-page.cc: + * qt4/src/poppler-qt4.h: Introduce variants of renderTo that return a + QImage and do not use a QPixmap so threading is possible. + +2006-01-02 Albert Astals Cid + + * poppler/PageTransition.cc: Use error() insted of std::cerr + +Sun Jan 1 18:50:51 2006 Jonathan Blandford + + * Makefile.am: + * autogen.sh: + * configure.ac: + * gtk-doc.make: + * glib/Makefile.am: enable gtk-doc support. + +2006-01-01 Albert Astals Cid + + * qt4/src/poppler-private.h: + * qt4/src/poppler-page.cc: + * qt4/src/poppler-document.cc: Don't create a SplashOutputDev for + every splashRenderToPixmap + * qt/poppler-page.cc: + * qt/poppler-private.h: Don't create a SplashOutputDev for every + renderToPixmap. + +Sun Jan 1 15:32:08 2006 Jonathan Blandford + + * glib/reference/*: More gtk-doc work. Not enabled for building + by default, but filled in. + +Fri Dec 30 21:08:33 2005 Jonathan Blandford + + * glib/*{cc,h}: Update inline doc comments. This is in + preparation for gtk-doc support. + +2005-12-30 Albert Astals Cid + + * utils/HtmlOutputDev.cc: + * utils/ImageOutputDev.cc: Fix build when using --disable-libjpeg + +2005-12-28 Brad Hards + + * qt4/src/poppler-private.h (Poppler): delete passwords after we've + initialised the PDFDoc + + * qt4/src/poppler-qt4.h: Add warning about deleting the Document + when done. + + * qt4/tests/check_*.cpp: Delete the Poppler::Document + and Poppler::Page objects to avoid leaks + + * qt4/tests/check_version.cpp: removed, there is a replacement + automated test. + + * qt4/tests/poppler-fonts.cpp (main): Delete Poppler::Document on exit + to avoid a memory leak. + + * qt4/tests/stress-poppler-qt4.cpp: Delete Poppler::Document and + Poppler::Page objects to avoid leaks. + + * qt4/src/poppler-document.cc (Poppler): Delete *doc in + Document::load(), to avoid a memory leak on failure. + Delete font results list, avoid a memory leak + Delete font scanner object, avoid a memory leak + +2005-12-27 Brad Hards + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-document.cc: add convertDate() function that + turns char* PDF date strings into QDateTime. This version handles + the timezone conversions. Refactored the existing date() method + to use it. + * qt4/tests/check_dateConversion.cpp: unit tests for convertDate() + * qt4/tests/check_metadata.cpp: update to reflect UTC. + * qt4/tests/.cvsignore: suppress check_dateConversion + + * qt4/src/Doxyfile (JAVADOC_AUTOBRIEF): Turned on automatic + \brief mode. + + * qt4/src/poppler-qt4.h: Update API documentation. Patch from + Stefan Kebekus, with some changes. Removed \brief entries. + +2005-12-21 Kristian Høgsberg + + * NEWS: Sum up 0.5 changes so far. + + * acinclude.m4: Split jpeg macros out into this file. + + * poppler/Stream.cc: Apply latest CVE-2005-3191 updates. + +2005-12-21 Kristian Høgsberg + + * utils/Makefile.am: Add parseargs.h to sources and add + -I$(top_srcdir)/poppler to INCLUDES. + + * poppler/CairoFontEngine.cc: Apply patch from Hiroyuki Ikezoe to + man non-embedded CJK fonts work. + +2005-12-18 Albert Astals Cid + + * configure.ac: Better jpeg detection, refer to ml PCbsd problem + * utils/Makefile.am: Add fontconfig cflags to utils as not always is + on /usr/include Fixes build problems on Slackware. Patch adapted from + a Giovanni Venturi patch. + * poppler/Page.cc: Only discard cropbox sizes one by one and not + completely. Jeff and Martin were right. + +2005-12-12 Albert Astals Cid + + * poppler/Page.cc: Ignore cropBox if it seems incorrect. + +2005-12-12 Kristian Høgsberg + + * Makefile.am: + * configure.ac: + * goo/GooVector.h: + * utils/HtmlFonts.cc: + * utils/HtmlFonts.h: + * utils/HtmlLinks.cc: + * utils/HtmlLinks.h: + * utils/HtmlOutputDev.cc: + * utils/HtmlOutputDev.h: + * utils/ImageOutputDev.cc: + * utils/ImageOutputDev.h: + * utils/Makefile.am: + * utils/parseargs.c: + * utils/parseargs.h: + * utils/pdffonts.1: + * utils/pdffonts.cc: + * utils/pdfimages.1: + * utils/pdfimages.cc: + * utils/pdfinfo.1: + * utils/pdfinfo.cc: + * utils/pdftohtml.1: + * utils/pdftohtml.cc: + * utils/pdftoppm.1: + * utils/pdftoppm.cc: + * utils/pdftops.1: + * utils/pdftops.cc: + * utils/pdftotext.1: + * utils/pdftotext.cc: Add command line utilities from xpdf. + +2005-12-10 Albert Astals Cid + + * qt4/src/poppler-page.cc: + * qt4/src/poppler-qt4.h: + * qt4/src/tests/test-poppler-qt4.cpp: The parameters x,y,w,h to the + method splashRenderToPixmap are now used. Convenient + defaults are provided. The test has been changed accordingly. Some + added documentation. Patch by Stefan Kebekus + +2005-12-09 Kristian Høgsberg + + * poppler/GfxState.cc: Use colToByte() for converting GxfColorComp + to bytes (really fix #5117). + + * poppler/Stream.cc: Remove duplicated check (#5243). + + * configure.ac: + * poppler/Makefile.am (poppler_includedir): + * goo/Makefile.am (poppler_goo_include_HEADERS): Make installation + of xpdf header files optional. + +2005-12-08 Albert Astals Cid + + * configure.ac: Detect if gettimeofday is available, fixes for correct + linking to Qt4 on windows + * goo/GooTimer.[cc|h]: Only build if gettimeofday is available + * poppler/Gfx.cc: Only use the timer for profiling if gettimeofday is + available + * poppler/GlobalParams.cc: Remove extra unlockGlobalParams that was + making windows hang + * splash/SplashFTFontEngine.cc: i need unistd.h on windows also + * splash/SplashFontFile.cc: i need unistd.h on windows also + +2005-12-08 Albert Astals Cid + + * glib/Makefile.am: + * poppler/Makefile.am: + * qt/Makefile.am: + * test/Makefile.am: Remove -DDATADIR we are not using if for anything + and it shadows a windows typedef + +2005-12-07 Brad Hards + + * poppler/PDFDoc.cc: Remove the version check. + + * qt4/src/poppler-document.cc: + * qt4/src/poppler-qt4.h: add in a new method infoKeys() - to get + metadata keys + + * qt4/tests/check_metadata.cpp: add unit test for infoKeys(). + +2005-12-06 Brad Hards + + * qt4/tests/check_metadata.cpp : add unit tests + for date, more linearization, page sizes, number of pages + +2005-12-05 Brad Hards + + * qt4/tests/check_fonts.cpp (checkType3): Add another case to fonts + unit test + (checkTrueType): Add test for TrueType as well. + +2005-12-04 Albert Astals Cid + + * poppler/CairoFontEngine.cc: Correct fix for #5149, i broke it when + merging xpdf 3.01 patches + +2005-12-04 Albert Astals Cid + + * poppler/JPXStream.cc: Fix error in merging CAN-2005-3193 fix. Thanks + Daniel Gryniewicz for notifying + +2005-12-04 Albert Astals Cid + + * qt/poppler-qt.h: + * qt/poppler-fontinfo.h: + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-fontinfo.cc: Implement copy constructor of FontInfo needed + as Q[Value]List uses it when appending + +2005-12-04 Brad Hards + + * qt4/tests/.cvsignore: Add unit test to cvs suppressions + + * qt4/src/poppler-qt4.h: + qt4/src/fontinfo.cc: add implementation for + FontInfo::typeName() + + * qt4/tests/check_fonts.cpp: + * qt4/tests/Makefile.am: add unit test for fonts + + * qt4/src/Mainpage.dox: Minor typo fixes. + +2005-12-03 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_set_selection_alpha): Use + Nickolays original fix instead of trying to be clever with + gdk_pixbuf_fill(). + + * poppler/CairoFontEngine.cc: Fix text corruption bug (#5149), + a rerun of an old classic (#3340). + + * poppler/GfxState.cc: Fixing another problem with new GfxRGB + representation causing images to show up as random pixels (#5117). + +2005-12-03 Kristian Høgsberg + + * qt/Makefile.am (noinst_PROGRAMS): Only build qt test program if + splash is enabled. + + * poppler/CairoOutputDev.cc: Remove unused grid snapping code, + sidestepping #4507. + + * glib/poppler-document.h (PopplerPermissions): Breaking enum + definition over multiple lines confuses glib-mkenums (#4600). + + * poppler/Makefile.am (libpoppler_la_LIBADD): Add FREETYPE_LIBS + (#4515). + + * poppler/TextOutputDev.cc: + * qt/poppler-qt.h: GCC-4.1 fixes (#5031). + +2005-12-03 Kristian Høgsberg + + Fixes from Nickolay V. Shmyrev: + + * poppler/TextOutputDev.cc (TextLine::visitSelection, + TextBlock::visitSelection): Fix selection crash with zero-width + word boxes or zero-height line boxes (#4402). + + * poppler/CairoOutputDev.h: Fix wrong cairo-ft.h include (#4413). + + * poppler/CairoOutputDev.cc (eoFill, fill): + * glib/poppler-page.cc (poppler_page_render_selection): Update to + work with new GfxColor definition and use + cairo_pattern_create_rgba() to cache cairo_pattern_t's for the + fill and stroke colors. + + * glib/poppler-page.cc (poppler_page_set_selection_alpha): Zero + out pixbuf first. + +2005-12-03 Albert Astals Cid + + * qt/poppler-document.cc: + * qt/poppler-private.h: + * qt/poppler-qt.h: Backported font retrieving from Qt4 frontend + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-fontinfo.cc: + * qt4/src/poppler-textbox.cc: Remove implementation of that classes + from the header, use pimpl + +2005-12-03 Albert Astals Cid + + * qt4/src/poppler-page.cc: + * qt4/src/Doxyfile: + * qt4/src/poppler-qt4.h: + * qt4/tests/test-poppler-qt4.cpp: Updated documentation and removed + some BC functions that were not needed as we still do not guarantee + BC. Patch by Stefan Kebekus + +2005-12-01 Albert Astals Cid + + * poppler/JPXStream.cc: + * poppler/Stream.cc: + * poppler/Stream.h: Fix CAN-2005-3193 based on + ftp://ftp.foolabs.com/pub/xpdf/xpdf-3.01pl1.patch + +2005-11-28 Albert Astals Cid + + * qt4/src/poppler-page,cc: + * qt4/src/poppler-page-qt,h: Fix QPixmap contents generation messed + when doing the xpdf 3.01 transition + * qt4/tests/test-poppler-qt4.cpp: Use Splash backend by default, added + -arthur option to use the Arthur backend + +2005-11-27 Brad Hards + + * qt4/src/poppler-qt4.h: add some missing API documentation + + * qt4/tests: updated unit tests to use Qt4.1 version of + QTestlib. + +2005-11-25 Albert Astals Cid + + * qt4/src/poppler-page.cc: + * qt4/src/poppler-qt.h: Some more functions, patch by Stefan Kebekus + +2005-11-21 Albert Astals Cid + + * test/pdf-inspector.cc: Fix page range + +2005-11-21 Albert Astals Cid + + * qt/poppler-page.cc: + * qt/poppler-qt.h: Some more functions, patch by Stefan Kebekus + +2005-11-21 Albert Astals Cid + + * qt/Makefile.am: Fix build problems some people were having + +2005-11-20 Kristian Høgsberg + + * poppler/GfxState.cc: Fix the byte_lookup initialization broken + by the merges (#4350). Modify GfxColorSpace::getRGBLine() to work + with new GfXColor type. + +2005-11-17 Albert Astals Cid + + * splash/SplashFTFont.cc: Make it compile using FreeType 2.2.0 + preversions + +2005-11-04 Albert Astals Cid + + * glib/poppler-document.cc: + * glib/poppler-page.cc: Make it compile using --disable-cairo-output + +2005-11-01 Albert Astals Cid + + * poppler/Stream.h: + * poppler/OutputDev.h: Comment some unused parameters to calm down + compiler warnings + +2005-10-30 Albert Astals Cid + + * glib/poppler-page.cc + * poppler/ArthurOutputDev.cc + * poppler/ArthurOutputDev.h + * poppler/CairoOutputDev.cc + * poppler/CairoOutputDev.h + * poppler/Gfx.cc + * poppler/Gfx.h + * poppler/GfxState.cc + * poppler/GfxState.h + * poppler/OutputDev.cc + * poppler/OutputDev.h + * poppler/PDFDoc.cc + * poppler/PDFDoc.h + * poppler/PSOutputDev.cc + * poppler/PSOutputDev.h + * poppler/Page.cc + * poppler/Page.h + * poppler/SplashOutputDev.cc + * poppler/SplashOutputDev.h + * poppler/TextOutputDev.cc + * poppler/TextOutputDev.h + * qt/poppler-page.cc + * qt4/src/poppler-page.cc + * splash/Splash.cc + * splash/Splash.h + * splash/SplashBitmap.cc + * splash/SplashBitmap.h + * splash/SplashPattern.cc + * splash/SplashPattern.h + * splash/SplashState.cc + * splash/SplashState.h + * splash/SplashTypes.h + * test/gtk-cairo-test.cc + * test/gtk-splash-test.cc + * test/pdf-inspector.cc: Last xpdf 3.01 merges + + +2005-10-16 Kristian Høgsberg + + * poppler/poppler-config.h.in (GCC_PRINTF_FORMAT): Remove evil + space character in macro definition. + +2005-10-16 Albert Astals Cid + + * splash/SplashXPathScanner.cc: Merge from xpdf 3.01 + * splash/SplashScreen.[cc|h]: Merge from xpdf 3.01 + * splash/SplashFTFont.cc: Merge from xpdf 3.01 + * poppler/Annot.[cc|h]: Merge from xpdf 3.01 + * poppler/FontInfo.cc + * poppler/Page.cc: + * poppler/PSOutputDev.cc: Changes needed due to Annot changes + * poppler/Function.[cc|h]: Merge from xpdf 3.01 + * poppler/Stream.[cc|h]: Merge from xpdf 3.01 + * poppler/GfxFont.cc: Merge from xpdf 3.01 + +2005-10-05 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_render_to_ps): Fix another + off-by-one page number error (#4555). + +2005-09-26 Marco Pesenti Gritti + + * glib/poppler-action.cc: + + Initialize window title even if the action is unknown + +2005-09-26 Marco Pesenti Gritti + + * glib/poppler-action.cc: + * glib/poppler-action.h: + + Implement launch action + +2005-09-20 Albert Astals Cid + + * poppler/GlobalParams.[cc|h]: Merge from xpdf 3.01 + * poppler/Link.cc: Merge from xpdf 3.01 + * poppler/Parser.cc: Merge from xpdf 3.01 + * poppler/TextOutputDev.[cc|h]: Merge from xpdf 3.01 + * poppler/UnicodeMap.cc: More grealloc -> greallocn + * poppler/UnicodeTypeTable.cc: Merge from xpdf 3.01 + * poppler/XRef.cc: Merge from xpdf 3.01 + +2005-09-20 Marco Pesenti Gritti + + * poppler/XRef.cc: + + Remove duplicated initialization + +2005-09-20 Marco Pesenti Gritti + + * poppler/GlobalParams.cc: + + s/G/Goo in not yet compiled plugins code + +2005-09-20 Marco Pesenti Gritti + + * poppler/Makefile.am: + + Add XPDFPlugin*. Thanks to TSDgeos that noticed this. + + * poppler/XpdfPluginAPI.cc: + + Fixup + +2005-09-16 Marco Pesenti Gritti + + * poppler/PDFDoc.cc: + * poppler/PDFDoc.h: + * poppler/XRef.cc: + * poppler/XRef.h: + + Merge more from 3.01 + +2005-09-16 Marco Pesenti Gritti + + * poppler/XRef.cc: + + Merge some initialization that I lost before + +2005-09-16 Marco Pesenti Gritti + + * poppler/XRef.cc: + + Merge change from 3.01 + +2005-09-16 Marco Pesenti Gritti + + * poppler/CharCodeToUnicode.cc: + * poppler/CharCodeToUnicode.h: + + Improvements from xpdf 3.01 + +2005-09-16 Marco Pesenti Gritti + + * poppler/CMap.cc: + + Improvements from xpdf 3.01 + +2005-09-16 Marco Pesenti Gritti + + * poppler/NameToUnicodeTable.h: + * poppler/UnicodeTypeTable.cc: + * poppler/UnicodeTypeTable.h: + + Merge some unicode table changes from xpdf 3.01 + +2005-09-16 Marco Pesenti Gritti + + * poppler/SplashOutputDev.h: + * splash/Splash.cc: + * splash/Splash.h: + + Modified region support from xpdf 3.01 + +2005-09-16 Marco Pesenti Gritti + + * goo/Makefile.am: + * poppler/DCTStream.h: + * poppler/Decrypt.cc: + * poppler/Decrypt.h: + * poppler/FlateStream.h: + * poppler/GlobalParams.cc: + * poppler/GlobalParams.h: + * poppler/Makefile.am: + * poppler/PDFDoc.cc: + * poppler/PDFDoc.h: + * poppler/Parser.cc: + * poppler/Parser.h: + * poppler/Stream.cc: + * poppler/Stream.h: + * poppler/XRef.cc: + * poppler/XRef.h: + * poppler/poppler-config.h.in: + + Merge security plugins support from xpdf 3.01 + +2005-09-16 Marco Pesenti Gritti + + * configure.ac: + * goo/Makefile.am: + * splash/Makefile.am: + * splash/SplashFTFont.cc: + * splash/SplashMath.h: + * splash/SplashTypes.h: + * goo/FixedPoint.cc: + * goo/FixedPoint.h: + + Merge support for fixed point + +2005-09-16 Marco Pesenti Gritti + + * poppler/ArthurOutputDev.cc: + * poppler/CairoFontEngine.cc: + * poppler/TextOutputDev.cc: + * poppler/UnicodeMap.cc: + + Use mallocn when possible + +2005-09-16 Albert Astals Cid + * splash/: Some merges from xpdf 3.01 + +2005-09-16 Albert Astals Cid + * configure.ac + * splash/SplashFTFontEngine.[cc|h] + * poppler/CairoFontEngine.[cc|h]: Merge the xpdf 3.01 change that uses + runtime detection of freetype version + +2005-09-15 Albert Astals Cid + * poppler/: Some minor merges from xpdf 3.01 + +2005-09-14 Albert Astals Cid + * fofi/ + * poppler/PSOutputDev.[cc|h]: Merge all xpdf 3.01 changes in fofi + +2005-09-06 Kristian Høgsberg + + * configure.ac: Enable A4_PAPER and OPI_SUPPORT by default. There + is no reason to not enable OPI and the paper size should be + controlled by the application. + + * test/Makefile.am (EXTRA_DIST): Add pdf-operators.c + +2005-09-03 Brad Hards + + * qt4/tests/ : + * configure.ac: switch qt4 unit tests to use QtTestLib, a more + capable system, and easier to maintain. + +2005-09-02 Kristian Høgsberg + + * glib/poppler-page.cc: Apply Marcos rotation fix. + +2005-08-31 Brad Hards + + * poppler/JArithmeticDecoder.cc + * poppler/JArithmeticDecoder.h + * poppler/JBIG2Stream.cc + * poppler/JBIG2Stream.h: merge in some of the JBIG2 changes from + xpdf 3.0.1. + + +2005-08-29 Kristian Høgsberg + + * configure.ac (HAVE_FREETYPE_H): Patch from Hiroyuki Ikezoe: Set + HAVE_FREETYPE_217_OR_OLDER to 0 if we found freetype using + pkg-config (#4223). + +2005-08-28 Brad Hards + + * fofi/FoFiTrueType.cc: + * goo/GooHash.cc: + * goo/GooHash.h: + * goo/GooList.cc: + * goo/GooList.h: + * goo/GooString.cc: + * goo/GooString.h: + * goo/gmem.c: merge the Goo* improvements from xpdf 3.0.1. This + change is based on martink's work (7-xpdf-3.01-goo-improvements.patch) + with some tweaking by me. + +2005-08-27 Jeff Muizelaar + + * poppler/FlateStream.cc: Fix predictor leak. + +2005-08-27 Jeff Muizelaar + + * configure.ac: Disable the zlib-based decoder by default. See #3948. + +2005-08-27 Brad Hards + + * Merge the gmalloc -> gmallocn changes from xpdf 3.0.1. This + change is based on martink's work (13-xpdf-3.01-goo-allocn.patch) + with some tweaking by me. There may be some residual gmallocn + changes still to be merged. + +2005-08-24 Martin Kretzschmar + + * configure.ac: add /usr/include/qt4 to qt4_incdirs. That's what + Debian and Ubuntu use. Maybe we should just use pkg-config. If + it's usable with qt4. + + * test/.cvsignore: ignore pdf_inspector binary. + +2005-08-24 Kristian Høgsberg + + * poppler/TextOutputDev.cc: Push rotation argument down to + GfxState constructor. This is still not completely functional yet. + + * glib/poppler-page.cc (poppler_page_render_selection): Add + rotation argument so API is useful. Not yet implemented. + (poppler_page_prepare_output_dev): Patch from Marco to fix + rotation using the cairo backend. + +Tue Aug 23 17:21:02 2005 Jonathan Blandford + + * test/Makefile.am (gtk_cairo_test_LDADD): add + FREETYPE_{CFLAGS,LIBS} to the cairo deps + +Tue Aug 23 13:38:01 2005 Jonathan Blandford + + * configure.ac: + * poppler/Gfx.cc: + * poppler/Gfx.h: + * poppler/GlobalParams.cc: + * poppler/GlobalParams.h: + * poppler/Makefile.am: + * poppler/OutputDev.cc: + * poppler/OutputDev.h: + * poppler/ProfileData.cc: + * poppler/ProfileData.h: + * test/Makefile.am: + * test/pdf-inspector.cc: + * test/pdf-inspector.glade: + * test/pdf-operators.c: Initial cut at a pdf inspector. This + should help us look at PDF files. + +2005-08-22 Kristian Høgsberg + + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler-private.h: + * glib/test-poppler-glib.c: Patch from Marco to simplify the glib + rotation API. + +2005-08-21 Kristian Høgsberg + + * poppler/Makefile.am (INCLUDES): Add FREETYPE_CFLAGS. + + * configure.ac: Make freetype check use pkg-config if possible. + +2005-08-17 Kristian Høgsberg + + * poppler/GfxFont.cc: Add fix discussed in #3131 to only use the + MacRoman char map if the font has one or the font dicts specifies + /MacRoman. + +2005-08-08 Albert Astals Cid + + * poppler/PDFDoc.cc: Improve the checking for %%EOF + +2005-08-06 Kristian Høgsberg + + * glib/poppler-page.cc: + * glib/poppler-page.h: Use GdkColor for specifying selection + colors, we alreay depend on GDK anyway. + +2005-08-06 Albert Astals Cid + + * poppler/PDFDoc.cc: Increase the range for searching %%EOF up to + the 1024 bytes pdf spec says adobe checks for, needed + to work with http://bugs.kde.org/show_bug.cgi?id=110034 and some other + private pdf i got sent + +2005-08-06 Brad Hards + + * qt4/src/poppler-document.cc: + * qt4/src/poppler-qt4.h: Add password arguments to document + constructor. + + * qt4/src/Doxyfile: Add define so doxygen can extract the + API for Qt4 bindings again. + + * qt4/tests/test-password-qt4.cpp: new test framework for + encrypted files. + +2005-08-05 Kristian Høgsberg + + * poppler/TextOutputDev.cc (visitLine): Round selection + coordinates in device space, so selection isn't fuzzy. + + * poppler/GfxState.cc: + * poppler/GfxState.h: Add simple Matrix class. + +2005-08-05 Kristian Høgsberg + + * glib/poppler-page.cc: + * glib/poppler-page.h: + * poppler/TextOutputDev.cc: + * poppler/TextOutputDev.h: Propagate selection colors to the glib API. + +2005-08-04 Brad Hards + + * poppler/ArthurOutputDev.cc: Fix problem with drawing filled objects + that was introduced in Rev 1.4. + +2005-08-03 Brad Hards + + * qt4/tests/test-poppler-qt4.cpp (keyPressEvent): add support for + page-up / page-down keys to change which page is displayed, and + q to quit. + +2005-08-01 Albert Astals Cid + + * poppler/DCTStream.[cc|h]: Fix problem in the patch to fix #3299 + +2005-08-01 Kristian Høgsberg + + Patch from Dan Winship + + * glib/poppler-page.cc (poppler_page_copy_to_pixbuf): Set alpha to + 0xff (opaque), not 0x00. + +2005-08-01 Brad Hards + + * poppler/ArthurOutputDev.cc: Fix up the fill problem with + drawing text, where the "middle" of glyphs with a "hole" + (like d, o, p, b, g) got filled. Also remove some debugging + code. The glyphs are still ugly though. + +2005-07-31 Brad Hards + + * poppler/ArthurOutputDev.cc: An initial version of proper + font handling, based on work by Albert Astals Cid. I changed + it to stroke the glyphs based on the SplashPath. In the longer + term, Arthur should use FreeType paths directly - hopefully + that will be less ugly, and not fill everything. + +2005-07-29 Brad Hards + + * qt4/tests: add test cases for version and facing pagelayout. + Also updated .cvsignore for these and a couple of older files. + + * poppler/ArthurOutputDev.cc (startPage): Make sure page is + filled white. Earlier versions of Qt4 seemed to have an + eggshell coloured background, but it changed to black at + some point. + + * poppler/ArthurOutputDev.cc: remove a couple more TODOs, + based on current Qt4 working OK. + +2005-07-29 Kristian Høgsberg + + * poppler/TextOutputDev.cc: Finish TextSelectionDumper class for + extracting the text from a selection. Add + TextPage::getSelectionText() and TextOutputDev::getSelectionText() + methods to expose the new functionality. + + * glib/poppler-page.cc (poppler_page_get_text): Use + TextOutputDev::getSelectionText() to get the text from the + selection. + + * glib/poppler-document.cc (poppler_document_new_from_file): + * glib/poppler-page.cc (_poppler_page_new): Add extra NULL to + g_object_new() constructor to silence gcc warning about missing + sentinel. + +2005-07-28 Albert Astals Cid + + * poppler/PageLabelInfo.[cc|h]: Fix memory leaks + +2005-07-28 Albert Astals Cid + + * glib/poppler-document.cc: + * poppler/CairoFontEngine.[cc|h]: + * poppler/CairoOutputDev.cc: + * poppler/GlobalParams.[cc|h]: + * poppler/SplashOutputDev.[cc|h]: + * qt/poppler-document.cc: + * qt4/src/poppler-document.cc: + * test/gtk-cairo-test.cc: + * test/gtk-splash-test.cc: + Use fontconfig for finding which font use for not embeded fonts + +2005-07-28 Kristian Høgsberg + + * poppler/poppler-config.h.in: Add GCC_PRINTF_FORMAT macro to + annotate printf-like functions (#3638). + + * poppler/Error.h: Add GCC_PRINTF_FORMAT to error(). + + * poppler/PSOutputDev.h: Add GCC_PRINTF_FORMAT to + PSOutputDev::writePSFmt(). + + * poppler/PSOutputDev.cc, poppler/GlobalParams.cc: Quiet new + printf warnings. + + * poppler/TextOutputDev.cc (TextBlock::visitSelection): Assign + start and stop coordinates in one place so we don't assign the + same point to both in some corner cases. + (TextWord::visitSelection): Initialize begin to len, not len + 1 + to fix crash. + + (TextWord::visitSelection, TextLine::visitSelection): Change + selection trigger; now midpoint of glyph must be included in + selection area for glyph to be in selection. + +2005-07-27 Martin Kretzschmar + + * poppler/PSOutputDev.cc (PSOutputDev): change the constructor to + take paper size and duplex setting parameters. + (init): add paper size and duplex parameters. + (writeDocSetup): add duplex parameter. + + * poppler/PSOutputDev.h: update declarations. + + * glib/poppler-private.h (struct _PopplerPSFile): store necessary + information to eventually construct a PSOutputDev. + + * glib/poppler-page.cc (poppler_page_render_to_ps): initialize the + output dev if it doesn't exist yet. + + * glib/poppler-document.cc (poppler_ps_file_new): don't create the + PSOutputDev here, just store filename and page range. + (poppler_ps_file_set_paper_size, poppler_ps_file_set_duplex): new + functions. + (poppler_ps_file_free): free the filename which we strdup now. + + * glib/poppler-document.h: add prototypes. + +2005-07-26 Albert Astals Cid + + * qt/test-poppler-qt-cpp: Fix mem leak + +2005-07-26 Kristian Høgsberg + + * fofi/FoFiType1.cc: Make check for end of encoding array a bit + more liberal so we don't crash on complex encoding arrays. + +2005-07-25 Albert Astals Cid + + * poppler/DCTStream.cc: Work on bad jpeg data that have garbage before + the start marker. Fixes bug #3299 + +2005-07-22 Albert Astals Cid + + * poppler/CairoFontEngine.cc: Fix mem leak. Reported in bug #3586 by + Kjartan Maraas, initial patch by Martin Kretzschmar. + +2005-07-22 Albert Astals Cid + + * qt/test-poppler-qt.cpp: Make it possible to change the displayed + page using Up and Down keys + +2005-07-22 Albert Astals Cid + + * splash/Splash.cc: Fix bugs #3728 and #3750 + +2005-07-20 Martin Kretzschmar + + * glib/poppler-document.cc (poppler_fonts_iter_get_name): if the + font is a subset, strip the ABCDEF+ tag. + (poppler_fonts_iter_get_full_name): does what the old get_name did. + (poppler_fonts_iter_get_font_type, poppler_fonts_iter_is_embedded) + (poppler_fonts_iter_is_subset): new wrappers. + + * glib/poppler-document.h (PopplerFontType): new enum. + Update prototypes. + +2005-07-15 Martin Kretzschmar + + * test/gtk-cairo-test.cc: update for 2005-06-27 change to actually + display something again. + +2005-07-10 Brad Hards + + * poppler/ArthurOutputDev.cc: General cleanup - removing + dead code, and some minor tweaks. No new features. + +2005-07-08 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_set_selection_alpha): Add + this function to initialize the alpha channel when using the + splash backend. + + * poppler/TextOutputDev.cc (visitLine): Add missing scaling of + intra-line selection edges. + +2005-07-07 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_prepare_output_dev): Account + for page rotation when creating the cairo surface. + +2005-07-06 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_copy_to_pixbuf): Add out of + bounds checking (from Marco). + +2005-07-07 Brad Hards + + * qt4/src/poppler-document.cc: + * qt4/src/poppler-qt4.h: Add pageLayout() function for Qt4 + bindings + + * qt4/tests/check_pagelayout_single.cpp: + * qt4/tests/check_pagelayout_none.cpp: + * Makefile.am: Add unit tests for pageLayout() + + * glib/poppler-document.cc (convert_page_mode): Update to + reflect the Catalog API change. I'm not that good at glib, + so this has a non-zero chance of being pure crackrock. + + * poppler/Catalog.cc: + * poppler/Catalog.h: update page mode options to PDF 1.6 + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-document.cc: add Qt4 bindings for additional + pageMode() value created by change above + + * qt4/src/poppler-qt4.h: minor updates to API docs. + + * qt4/tests/Makefile.am: + * qt4/tests/check_pagemode_*.cpp: unit tests for Qt4 pageMode() call + and associated enum. This is the initial checkin for these files + +2005-07-06 Albert Astals Cid + + * poppler/PDFDoc.[cc|h]: Add checkFooter to check document ends with + %%EOF + * poppler/GfxFont.[cc|h]: Extract family, stretch and weight from the + font descriptor + +2005-07-06 Brad Hards + + * qt4/tests/Makefile.am: + * qt4/tests/check_linearised.cpp: Added unit test for linearised + property + + * qt4/tests/poppler-fonts.cpp (main): update to reflect API change, + and also to show "[none]" if the font is nameless. + + * qt4/src/poppler-document.cc (Poppler): + * qt4/src/poppler-qt4.h: remove the unicode translation bool, + it is really an internal thing. + +2005-07-05 Albert Astals Cid + + * qt4/src/poppler-document.cc (Poppler): + * qt4/src/poppler-qt4.h: Don't crash with files that have fonts with + no name, for example the one found at + http://bugs.kde.org/show_bug.cgi?id=101520. + +2005-07-05 Brad Hards + + * qt4/tests/check_author.cpp: + * qt4/tests/check_permissions.cpp: + * Makefile.am: + * .cvsignore: add a couple more test cases + + * qt4/src/poppler-document.cc (Poppler): + * qt4/src/poppler-qt4.h: Add Qt4 bindings for the + additional user permission properties. + + * poppler/XRef.h: + * poppler/Xref.cc: + * poppler/PDFDoc.h: Add some more user permissions properties - + high resolution printing, document assembly, extraction for + accessibility and form completion. + +2005-07-04 Brad Hards + + * qt4/src/poppler-page.cc: fix typo bug that + prevented correct detection of upside down pages + + * qt4/tests/check-orientation.cpp: fix path to + point to test module. + + * qt4/.cvsignore: update to reflect new files + + * qt4/tests/Makefile.am: + * qt4/tests/poppler-fonts.cpp: initial import of a simple font + metadata listing application. + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-document.cc complete Qt4 font metadata handling + + * qt4/src/poppler-qt4.h: + * qt4/src/poppler-page.cc: change the render API to make it more + Qt-like. + + * qt4/tests/test-poppler-qt4.cpp: + * qt4/tests/stress-poppler-qt4.cpp: update to reflect changes + to render API + + * poppler/FontInfo.h/cc: make FontInfo::type() return a enum + instead of a GooString. As discussed on mailing list, if you + want a string representation, you get to make one at the bindings + layer (ie typeName() didn't make the grade in the final patch) + + * qt4/tests/poppler-fonts.cpp (main): change order in test + code to reflect actual testcase file + +2005-07-01 Kristian Høgsberg + + * poppler/TextOutputDev.cc: Make selection also work when dragging + backwards in the text flow. Currently this is a big pile of + if-statements, and there is certainly room for improvement. + +2005-06-30 Kristian Høgsberg + + * glib/poppler-page.h: * glib/poppler-page.cc + (poppler_page_copy_to_pixbuf): Fix splash compilation (patch from + Marco). + (poppler_page_render_to_pixbuf): Drop dest_x and dest_y + coordinates from this function. This functionality can be + achieved using a sub-GdkPixbuf. + + * glib/test-poppler-glib.c (main): Update test case. + +2005-06-29 Kristian Høgsberg + + * glib/poppler-private.h: Move TextOutputDev.h include here from + poppler-page.cc + +2005-06-29 Kristian Høgsberg + + * configure.ac: + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler-private.h: + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: + * poppler/Page.cc: + * poppler/Page.h: + * poppler/TextOutputDev.cc: + * poppler/TextOutputDev.h: Add support for rendering real + selection (based on text flow). + +2005-06-28 Albert Astals Cid + + * poppler/FontInfo.[cc,h]: Add FontInfo::getType() + +2005-06-28 Albert Astals Cid + + * poppler/ArthurOutputDev.cc: use transformation matrix for image + rendering + +2005-06-28 Brad Hards + + * .cvsignore: + * qt4/.cvsignore: + * qt4/src/.cvsignore: + * qt4/tests/.cvsignore: update to reflect the Qt4 bindings. + +2005-06-28 Brad Hards + + * qt4/: + * Makefile.am: + * configure.ac: + * poppler-qt4.pc.in: Initial import of Qt4 bindings, based + on the Qt3 bindings. API is still in flux. + + * poppler/AuthurOutputDev.[cc,h]: + * poppler/Makefile.am: Initial import of Qt4 backend renderer. + Incomplete at this stage. + +2005-06-27 Kristian Høgsberg + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: Change CairoOutputDev to render to a + given surface and let the user create that surface. + + * glib/poppler-document.cc: + * glib/poppler-page.cc: + * glib/poppler-private.h: Create the cairo image surface here + instead and pass it to the CairoOutputDev for rendering. + + * poppler/CairoOutputDevImage.cc: + * poppler/CairoOutputDevImage.h: + * poppler/CairoOutputDevX.cc: + * poppler/CairoOutputDevX.h: + * poppler/Makefile.am: Remove specialized cairo output devices. + +2005-06-26 Kristian Høgsberg + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDev.h: Switch back to using drawChar() for + text, but utilize the beginString() and endString() hooks so we + can use cairo_show_glyphs() efficiently. + +2005-06-26 Albert Astals Cid + * qt/poppler-page.cc: + * qt/poppler-page.h: Add PageTransition class and + PageTransition* Page::getTransition() const; to the qt frontend. + +2005-06-26 Martin Kretzschmar + + * glib/.cvsignore: add poppler-enums.[ch]. + + * configure.ac: require glib 2.4+ for g_value_take_string and + G_DEFINE_TYPE. + +2005-06-25 Jeff Muizelaar + + * poppler/Error.h: Maybe fix build on Solaris. + +2005-06-20 Kristian Høgsberg + + * NEWS: + * configure.ac: Bump version to 0.3.3 and sum up changes since + last release. + + * glib/poppler-page.cc (poppler_page_find_text): Initialize xMin + and yMin to avoid referencing unintialized memory (#3582). + +2005-06-20 Martin Kretzschmar + + * glib/poppler-document.cc (info_dict_get_string): convert + from PDFDocEncoding to UTF-8. + +2005-06-20 Kristian Høgsberg + + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler.h: Clean up glib rotation implementation and add a + getter for rotation. Patch from Marco. + +2005-06-20 Kristian Høgsberg + + * glib/poppler-document.cc: + * poppler/FontInfo.cc: Fixes from Marco to handle fonts without + name (typically type 3 fonts) and fix an iterator bug. + +2005-06-20 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_get_link_mapping): Adjust + link coordinates so they're relative to bounding box lower left + corner (#3396). + +2005-06-17 Kristian Høgsberg + + * autogen.sh: Patch from Emil Soleyman-Zomalan to enable checks + for automake >= 1.7 (#3554). + +2005-06-15 Kristian Høgsberg + + * glib/poppler-document.cc: + * glib/poppler-document.h: Patch from Marco to get initial status + (open or closed) for bookmark subtrees. + +2005-06-13 Kristian Høgsberg + + * glib/poppler-document.cc: + * glib/poppler-document.h: + * glib/poppler-private.h: + * glib/poppler.h: + * glib/test-poppler-glib.c: + * poppler/Makefile.am: Patch from Marco to extract font info from + document. + +2005-06-08 Kristian Høgsberg + + * poppler/CairoFontEngine.cc: Remember to delete tmpFileName. + Patch from Nikolai Weibull (#3491). + +2005-06-07 Kristian Høgsberg + + * qt/test-poppler-qt.cpp: Add stdlib.h include for exit(). + +2005-06-02 Kristian Høgsberg + + * poppler/TextOutputDev.h: + * qt/poppler-qt.h: Patch from Stanislav Brabec + to fix gcc 4.0.1 warnings on undeclared friend classes. + + * test/gtk-splash-test.cc: Fix from Martin Kretzschmar + to compile with OPI enabled (#2911). + +2005-06-02 Kristian Høgsberg + + Patch from Stanislav Brabec : + + * configure.ac: + * poppler-cairo.pc.in: + * poppler-glib.pc.in: + * poppler-qt.pc.in: + * poppler-splash.pc.in: Misc fixes to pkg-config files. + +2005-06-01 Jeff Muizelaar + + * poppler/Error.cc: + * poppler/Error.h: Make error handling function setable through + setErrorFunction. + + Based on a patch by Albert Astals Cid. + +2005-05-29 Kristian Høgsberg + + * glib/*: Add more meta data properties to poppler document. + Patch by Emil Soleyman-Zomalan (#3359). + +2005-05-26 Kristian Høgsberg + + * poppler/CairoOutputDev.cc (clip): Remove snapToGrid so clip() + prototype matches what Gfx actually calls (fixes clipping). + + * poppler/CairoOutputDev.cc: Update fill color, stroke color, fill + opacity and stroke opacity from GfxState on restore, since they + aren't handled by cairo_restore() (#3362). + + * poppler/CairoOutputDev.cc: Comment out tolerance setting until + we figure out how cairo settings relate to pdf settings. + + * poppler/CairoOutputDev.cc: Support fill and stroke opacity. + + * poppler/GfxState.cc: + * poppler/GfxState.h: Add GfxColorSpace::getRGBLine here and + implement in subclasses. + + * poppler/CairoOutputDev.cc (drawImage): Use getRGBLine here. + +Mon May 23 00:22:41 2005 Jonathan Blandford + + * glib/poppler-document.h: Add a permissions flag to the glib + bindings. + +2005-05-21 Kristian Høgsberg + + * glib/poppler-document.cc (poppler_ps_file_new): Fix off-by-one + error spotted by Jürg Billeter. + +2005-05-20 Kristian Høgsberg + + * poppler/CairoOutputDev.cc: Account for different row vs. column + vector conventions between cairo and poppler. + + * poppler/CairoFontEngine.cc: Only get the code to gid map if + we're using freetype 2.1.7 or older (#3340). + +2005-05-19 Kristian Høgsberg + + * poppler/CairoFontEngine.cc: Only cast to Gfx8BitFont when we + know for sure we have a truetype font. + GfxCIDFont::getCIDToGIDLen() can return 0 in which case codeToGID + will be NULL, and we end up casting it to a Gfx8BitFont (#3265). + +2005-05-18 Kristian Høgsberg + + * configure.ac: Require cairo 0.5.0, bump release to 0.3.2. + + * NEWS: Sum up latest changes. + + * glib/poppler-document.cc (poppler_ps_file_new): Take a page + range here instead of just number of pages. + +2005-05-17 Kristian Høgsberg + + * poppler/CairoOutputDevX.cc: + * test/gtk-cairo-test.cc: Chase the cairo xlib constructor again. + +2005-05-16 Kristian Høgsberg + + Patch from Christian Persch (#3300): + + * configure.ac: Check for glib-mkenums. + + * glib/Makefile.am (poppler-enums.h): Generate glib enums at + compile time. + + * glib/poppler-enums.c: + * glib/poppler-enums.h: Removed. + +2005-05-16 Kristian Høgsberg + + * test/gtk-cairo-test.cc: Update this test case also. + + * poppler/CairoOutputDevX.cc: Track changes to cairo Xlib surface + constructors. + + * poppler/CairoFontEngine.cc (cairo_font_face_destroy): Make this + static. + +Thu May 12 23:10:45 2005 Jonathan Blandford + + * glib/poppler.gidl: add metadata file. + +2005-05-12 Kristian Høgsberg + + * poppler/CairoOutputDev.cc: + * poppler/CairoOutputDevX.cc: + * poppler/CairoOutputDevImage.cc: + * test/gtk-cairo-test.cc: Update to latest cairo changes, patch + from Jens Taprogge (#3281) + +2005-05-11 Kristian Høgsberg + + * glib/poppler.cc (poppler_get_backend, poppler_get_version): Add + these functions so it's easy to tell if poppler is using cairo or + splash and what version. + + * glib/test-poppler-glib.c (main): Print out version and backend. + +2005-05-06 Kristian Høgsberg + + * glib/Makefile.am (libpoppler_glib_la_LIBADD): Link poppler-glib + against poppler. + + * qt/Makefile.am (libpoppler_qt_la_LIBADD): Ditto for qt. + + * poppler-glib.pc (Libs): Drop -lpoppler from link. + + * poppler-qt.pc (Libs): Ditto for qt. + + * configure.ac: Test for both libqt-mt.la and libqt-mt.so in that + order. + +2005-05-04 Kristian Høgsberg + + * poppler/CairoOutputDev.cc (CairoOutputDev::drawImageMask, + CairoOutputDev::drawImage): Track cairo cvs API changes; use + cairo_mask() and cairo_paint() for drawing image masks and images. + +2005-05-04 Kristian Høgsberg + + * poppler/CairoOutputDev.cc: Fix matrix convention confusion. + +2005-05-04 Kristian Høgsberg + + Patches from Albert Astals Cid: + + * qt/poppler-page.cc (getText): Use QString::fromUtf8() instead of + implicit latin1 cast constructor. + + * qt/test-poppler-qt.cpp (main): Use a QLabel for showing text + instead of qDebug. + +Wed May 4 02:31:05 2005 Jonathan Blandford + + * glib/poppler-document.cc: + * glib/poppler-document.h: + * glib/poppler-enums.c: (poppler_permissions_get_type): + * glib/poppler-enums.h: + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler.h: + + Register a bunch of boxed types to test introspection, and for + LBs. Also, remove unused 'popper_document_save()' (-: + +2005-05-01 Kristian Høgsberg + + * poppler/CairoFontEngine.cc: + * poppler/CairoFontEngine.h: + * poppler/CairoOutputDev.cc: Back out workaround for cairo 0.4.0 + font API and port to new cairo head. + +2005-05-01 Jeff Muizelaar + + * splash/SplashFTFont.cc (SplashFTFont::getGlyphPath): + Use FT_LOAD_NO_BITMAP to make sure we get outlines loaded instead + of bitmaps for use in FT_Outline_Decompose. + + Patch from Albert Astals Cid. + +2005-05-01 Jeff Muizelaar + + * goo/gmem.c: (gmalloc), (grealloc), (gfree): + * goo/gmem.h: make memory functions use size_t instead of int. + + Patch from Takashi Iwai through Albert Astals Cid. + +2005-04-30 Jeff Muizelaar + + * qt/poppler-document.cc (Document::unlock) : + * qt/poppler-qt.h (Document::unlock): + Add const to the password argument. + + Patch from Albert Astals Cid. + +2005-04-30 Jeff Muizelaar + + * fofi/FoFiType1.cc (FoFiType1::parse): + Don't assume Encoding array of Type1 fonts end in "foo def". + http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF says + "This sequence of assignments must be followed by an instance of the + token def or readonly; such a token may not occur within the sequence + of assignments." so it must end with "readonly" "def" "readonly def" + (That is what most fonts are using and this is why it was not + crashing) + + Patch from Albert Astals Cid. + +Fri Apr 29 14:54:44 2005 Jonathan Blandford + + * goo/GooTimer.h: New class to do simple timing checks. + + * glib/poppler-document.c: Patch from Martin Kretzschmar to really + set the PDF version correct. Third time's the charm. + +2005-04-29 Kristian Høgsberg + + * configure.ac: Bump release to 0.3.1. + + * NEWS: Write up news for 0.3.1 release. + +2005-04-28 Kristian Høgsberg + + Patch from Martin Kretzschmar: + + * poppler/GlobalParams.cc: use UTF-8 as the default text encoding. + Fixes Bug 2934. + +2005-04-27 Jeff Muizelaar + + * configure.ac: + * poppler/FlateStream.cc: + * poppler/FlateStream.h: + * poppler/Makefile.am: + * poppler/Stream.cc: + * poppler/Stream.h: Add a reimplementation of FlateStream using + zlib. + +2005-04-27 Kristian Høgsberg + + * poppler/Catalog.cc (NameTree::lookup): Fix bsearch return value + NULL check. Found by Albert Astals Cid. + +Tue Apr 26 13:13:42 2005 Jonathan Blandford + + * glib/test-poppler-glib.c (main): add a quick dump-to-text test. + +2005-04-24 Kristian Høgsberg + + * qt/Makefile.am (libpoppler_qt_la_SOURCES): Add poppler-private.h + to SOURCES. + +2005-04-23 Kristian Høgsberg + + * poppler/CairoFontEngine.cc: Use the right fileName for loading + CID fonts (#3114). + +2005-04-22 Kristian Høgsberg + + * configure.ac: Actually commit version number bump. + +2005-04-22 Martin Kretzschmar + + * poppler/CairoFontEngine.cc: declare matrix variable before the + first goto. Fixes build with gcc 3.3. + +Fri Apr 22 00:01:40 2005 Kristian Høgsberg + + * poppler/CairoFontEngine.cc: Hack around semi-broken cairo-0.4.0 + font API to fix the problem where some glyphs would show up at the + wrong sizes. We now create an FT_Face for each size and font + combination we encounter, since an FT_Face can't be shared between + several cairo_font_t. + +Thu Apr 21 15:43:52 2005 Kristian Høgsberg + + * poppler/Outline.cc: + * poppler/Outline.h: Implement the documented behaviour for + Outline::getItems() and OutlineItem::getKids() and make + documentation more precise (Patch from Marco). + +Thu Apr 21 02:25:20 2005 Kristian Høgsberg + + * poppler/CairoFontEngine.cc (CairoFont::getFont): Cache + cairo_font_t's for a given CairoFont. With this patch cairo will + recognize glyphs coming from the same font as such and the glyph + cache will actually work. + + * glib/poppler-document.cc (poppler_document_new_from_file): Add + output device (cairo or splash) to PopplerDocument and initialize + it in the constructor. + + * glib/poppler-page.cc (splash_render_to_pixbuf, + cairo_render_to_pixbuf): Use output device from associated poppler + document instead of creating a new one. + + * poppler-glib.pc.in (Requires): Add Requires: field. + + * poppler/Page.cc (loadThumb): Remove unecessary and buggy call to + Stream::addFilters(), reported by Ryan Lortie (#3046). + +2005-04-13 Jeff Muizelaar + + * qt/poppler-page.cc (Page::getText): + * qt/poppler-qt.h: add a getText method for getting + the text on a page + + * qt/test-poppler-qt.c (PDFDisplay::PDFDisplay): + add the option to display the text on a page + + Patch from Albert Astals Cid. + +Tue Apr 19 17:21:19 2005 Jonathan Blandford + + * glib/poppler-document.cc (poppler_document_get_property): Use + %.2g instead. + +Tue Apr 19 17:11:52 2005 Jonathan Blandford + + * glib/poppler-document.cc (poppler_document_get_property): Use %g + instead of %f to avoid versioning like PDF-1.50000 + +Tue Apr 19 15:43:35 2005 Kristian Høgsberg + + * glib/poppler-action.cc (_poppler_action_new): Handle NULL links + gracefully (fix from Jeff). + +Tue Apr 19 00:20:08 2005 Kristian Høgsberg + + * poppler/Catalog.cc: Fix from Marco to make sure we always + initialize Catalog::pageLabelInfo. + +Sat Apr 16 14:53:15 2005 Jonathan Blandford + + * glib/Makefile.am: Create poppler-enums.[ch] + + * glib/poppler.h: + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler-action.h: Try to clean up the headers a bit + + * glib/poppler-document.cc: + * glib/poppler-document.h: Add support for document data. + Implemented as a lot of GObject properties. + + * glib/poppler-enums.c: + * glib/poppler-enums.h: New autogenerated files. + + * glib/test-poppler-glib.c: Test the new document metadata. Seems + to work nicely, other than the PDF string and View Prefs. + + * poppler/Catalog.cc: + * poppler/Catalog.h: Extend to support PageLayout. + +2005-04-14 Kristian Høgsberg + + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler-private.h: + * glib/poppler.h: Patch from Marco Pesenti Gritti to set page + orientaton. + +2005-04-13 Jeff Muizelaar + + * poppler/CairoOutputDevImage.cc (getBitmap): remove unused + SplashBitmap. Patch from Albert Astals Cid. + +2005-04-12 Kristian Høgsberg + + * configure.ac: Add fontconfig to PKG_CHECK_MODULES for the cairo + backend too, since we shouldn't depend on cairo.pc to pull that in + for us. + + * poppler/Makefile.am (INCLUDES): Add $(splash_includes) to + INCLUDES to make sure the fontconfig include path is added when + using the splash backend. + +2005-04-09 Jeff Muizelaar + + * poppler-qt.h: + * poppler-document.cc (okToPrint, okToChange, okToCopy): + Patch from Albert Astals Cid adding more metadata exports + +2005-04-08 Kristian Høgsberg + + * poppler-qt.pc.in (Libs): Add -lpoppler to Libs. + +2005-04-07 Jeff Muizelaar + + * configure.ac: redo the qt tests from Albert Astals Cid + +2005-04-07 Jeff Muizelaar + + * qt/poppler-document.cc: + * qt/poppler-page.cc: + * qt/poppler-qt.h: + Patch from Albert Astals Cid adding consts and exporting some more + metadata. + +2005-04-07 Kristian Høgsberg + + * glib/poppler-document.cc: + * glib/poppler-document.h: + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler-private.h: Print to PS support from Marco Pesenti + Gritti. + +Thu Apr 7 12:25:39 2005 Jonathan Blandford + + * configure.ac: check for qt, not glib, when enabling the qt + subdir + +2005-04-06 Jeff Muizelaar + + * .cvsignore, glib/.cvsignore, qt/.cvsignore: + Add more things to .cvsignore. + Patch from Martin Kretzschmar. + +2005-04-06 Jeff Muizelaar + + * poppler-page.cc (Page::Page, Page::~Page): + Construct and deconstruct the PageData object. + Patch from Albert Astals Cid. + +2005-04-06 Jeff Muizelaar + + * Makefile.am, configure.ac: Add configuration for qt wrapper. + + * poppler-qt.pc.in: + * qt/Makefile.am: + * qt/poppler-document.cc: + * qt/poppler-page.cc: + * qt/poppler-private.h: + * qt/poppler-qt.h: + * qt/test-poppler-qt.cpp: + New files. + +2005-04-05 Kristian Høgsberg + + * NEWS: Attempt to sum up changes since 0.1.2. + + * configure.ac: Bump release to 0.2.0, add AC_DEFINEs for cairo + and splash availability. + + * poppler/CairoFontEngine.cc: Disable hinting. + + * glib/poppler-page.cc (poppler_page_render_to_pixbuf): Choose + either splash or cairo rendering, based on configure choice. + (cairo_render_to_pixbuf): New function to render using the cairo + backend. + (splash_render_to_pixbuf): Split out the splash code to this + function. + +2005-04-04 Kristian Høgsberg + + * ChangeLog: Add this entry to test commit mailer script. + + * TODO: Add reminder about using PDF font descriptors with + fontconfig. + + * configure.ac: Add checks for mkstemp() and mkstemps(). + + * glib/poppler-page.cc (poppler_page_find_text): Reverse + y-coordinates so we return PDF style coordinates. + + From Maro Pesenti Gritti : + + * configure.ac, poppler/Makefile.am: Check for fontconfig when + we're building the splash backend. + + * glib/poppler-page.cc (poppler_page_get_text): New function to + select text on page. + +2005-04-04 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_find_text): Reverse list of + matches so we get them in the right order. + +2005-04-03 Martin Kretzschmar + + * poppler/DCTStream.h: Wrap #include in extern "C" + Fixes build with unpatched libjpeg. + +2005-04-02 Jeff Muizelaar + + * poppler/Page.h: + * poppler/Page.cc (Page::Page): + Some initial infrastructure for supporting transitions. + +2005-03-31 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_render_to_pixbuf): Clip + output to destination pixbuf and fix RGB order. + +2005-03-31 Kristian Høgsberg + + * glib/poppler-page.cc (poppler_page_find_text): New function to + seach a page for occurrences of a given text string. + + * glib/poppler-page.cc: Add g_return_if_fail() checks to a couple + of functions. + +Thu Mar 31 00:26:20 2005 Jonathan Blandford + + * glib/poppler-page.cc: + * glib/poppler-page.h (poppler_page_get_link_mapping, + poppler_page_free_link_mapping): New functions to get a mapping of + links to locations on the current document. + +2005-03-30 Jeff Muizelaar + + * poppler/DCTStream.h: change x to unsigned int to eliminate + comparision warning + +2005-03-30 Jeff Muizelaar + + * poppler/Catalog.cc: delete pageLabelInfo on deconstruction + +Tue Mar 29 23:07:17 2005 Jonathan Blandford + + * glib/poppler-page.h: Reformat. + +Tue Mar 29 22:49:15 2005 Jonathan Blandford + + * glib/poppler-action.[ch]: New item to encapsulate links. + * glib/poppler-document.[ch] (poppler_index_iter_get_action): New + function to get the action. Also, fix some warnings. + * glib/poppler-private.h (_poppler_action_new): New function. + * glib/test-poppler-glib.c: Fix warnings. + +Tue Mar 29 02:36:00 2005 Jonathan Blandford + + * glib/poppler-document.[ch] (PopplerIndexIter): Add an iter to + extract the index from the doc. Includes a bad hack, for now. + +Mon Mar 28 22:02:07 2005 Jonathan Blandford + + * glib/poppler-page.cc: + * glib/poppler-page.h (poppler_page_get_thumbnail_size): New + function. + * poppler-glib.pc.in: add -lpoppler-glib to the libs line. + +2005-03-28 Kristian Høgsberg + + * poppler/Page.cc (loadThumb): Backend agnostic method for + extracting an embedded thumbnail iamge. + + * poppler/Dict.cc (lookupInt): New convenience method. + + * glib/poppler-page.cc (poppler_page_get_thumbnail): New glib + function for getting the embedded thumbnail image for a page. + +2005-03-25 Kristian Høgsberg + + * configure.ac: Check for fontconfig for glib bindings. + +2005-03-24 Kristian Høgsberg + + * glib/Makefile.am: Use POPPLER_GLIB_CFLAGS and POPPLER_GLIB_LIBS + instead of GTK_TEST_*. Reported by Adam Jackson . + +2005-03-23 Kristian Høgsberg + + * poppler/Catalog.cc (indexToLabel, labelToIndex): Add stricter + checking of incoming labels and indices. + + * glib/test-poppler-glib.c (main): Change test program to take the + page label from the command line. + + * glib/poppler-page.cc: + * glib/poppler-page.h: Add poppler_page_get_index() and rename + popper_page_get_dimension() to popper_page_get_size() + +2005-03-22 Kristian Høgsberg + + * glib/poppler-document.cc: Implement poppler_document_save(). + + * glib/poppler-document.h: Add prototype and format headers + properly. + +2005-03-22 Kristian Høgsberg + + * configure.ac: Fix --disable-popper typo reported by Albert. + Require exactly cairo 0.4 since CVS cairo has API changes. + +2005-03-22 Kristian Høgsberg + + * poppler/Array.cc: + * poppler/Array.h: Add getString() convenience method. + + * poppler/Catalog.cc: + * poppler/Catalog.h: Optimize lookup of named destinations. + +2005-03-21 Kristian Høgsberg + + * NEWS, TODO: Update these. + +2005-03-21 Kristian Høgsberg + + From Albert Astals Cid : + + * poppler/Catalog.cc, poppler/Catalog.h: Parse PageMode setting + from the Catalog dict and expose it through getPageMode() method. + +2005-03-21 Kristian Høgsberg + + * glib/poppler-document.cc: + * glib/poppler-document.h: Expose the document title as a GObject + property. + + * glib/poppler-page.cc: Expose the page label as a GObject + property. + + * glib/poppler-private.h: Add the page index to PopplerPage. + + * glib/test-poppler-glib.c: Print out page label and document + title. + + * poppler/Catalog.cc: + * poppler/Catalog.h: Add page label accessors. + + * poppler/PageLabelInfo.cc: + * poppler/PageLabelInfo.h: New files. + + * poppler/Makefile.am: Add new files to sources. + +2005-03-20 Kristian Høgsberg + + * glib/poppler-document.cc: + * glib/poppler-page.h: + * glib/poppler.cc: + * poppler/Array.cc: + * poppler/Array.h: + * poppler/Catalog.cc: Fix up filenames in #include statements and + comments. + +2005-03-19 Kristian Høgsberg + + Land the first bits of the glib wrapper. + + * Makefile.am: + * configure.ac: Add new glib subdirectory and configure options + for glib wrapper. + + * glib/Makefile.am: + * glib/poppler-document.cc: + * glib/poppler-document.h: + * glib/poppler-page.cc: + * glib/poppler-page.h: + * glib/poppler-private.h: + * glib/poppler.cc: + * glib/poppler.h: + * glib/test-poppler-glib.c: + * poppler-glib.pc.in: New files. + +2005-03-16 Jeff Muizelaar + + From Dan Sheridan + + * poppler/XRef.cc (XRef::checkEncrypted): + The key length should be 5 for revision 2 documents. + +2005-03-11 Kristian Høgsberg + + From Jeff Muizelaar : + + * poppler/CairoOutputDev.cc (CairoOutputDev::drawImageMask): Use + getLine instead of getPixel. + + * configure.ac: Add checks for libjpeg. + + * DCTStream.cc, DCTStream.h, Stream.cc, Stream.h, Makefile.am: + Conditionally use libjpeg instead of xpdf jpeg decoder. + +2005-03-10 Kristian Høgsberg + + From Jeff Muizelaar : + + * poppler/CairoFontEngine.cc (CairoFontEngine::getFont): + Don't print "Type 3 font!" message. + + * poppler/CairoOutputDev.cc (CairoOutputDev::drawImageMask): + Enable image mask drawing and do it properly, albeit slowly. + + * poppler/CairoOutputDev.h + (CairoOutputDev::interpretType3Chars): Return true so that + Gfx.cc turns type3 characters into calls to drawImageMask + +2005-03-09 Kristian Høgsberg + + * NEWS: Describe 0.1.2 (and 0.1.1) release. + + * configure.ac: Bump poppler version to 0.1.2 + +2005-03-09 Kristian Høgsberg + + * configure.ac: Bump cairo requirement to 0.4. + +2005-03-04 Kristian Høgsberg + + Patch from Jeff Muizelaar . Changed to allocate + glyphs using gmalloc. + + * poppler/CairoOutputDev.cc (CairoOutputDev::drawString): + Implement drawString instead of drawChar. This change should + make clipping to a text path work and has a performance + improvement. Currently the code is a little ugly because we + can't concat matrices to cairo without losing our current font. + + * poppler/CairoOutputDev.h (CairoOutputDev::useDrawChar): + Tell Gfx.cc that it should use drawString instead of drawChar. + +2005-03-04 Kristian Høgsberg + + * test/gtk-cairo-test.cc (view_load): + * test/gtk-splash-test.cc (view_load): Fix missing return + statement, and remove unused variables. + + * configure.ac: Add configure option to enable the default KDE + flags as described by Albert Astals Cid . + + * TODO: Update with Jeff's items. + + * .cvsignore: + * */.cvsignore: Add these to silence CVS. + + * configure.ac: Implement same check for gtk+-2.0 tests as for + cairo. + +2005-03-04 Kristian Høgsberg + + * configure.ac: Only fail hard in check for cairo if the user + specified --enable-cairo-output (from Brad Hards + ). Print summary of configure results at the + end of configure script. + + * poppler/poppler-config.h: Remove this file (noticed by Brad + Hards ). + +2005-03-03 Kristian Høgsberg + + Patch from Jeff Muizelaar : + + * poppler/CairoOutputDev.cc (CairoOutputDev::drawImage, + CairoOutputDev::drawImageMask): destroy the image surface and + free the image buffer. + +2005-03-03 Kristian Høgsberg + + * autogen.sh: Add -i to autoreconf invocation. + + * autogen.sh: Add to CVS. + +2005-03-01 Kristian Høgsberg + + * poppler/*.h: Take config.h out of header files. + + * configure.ac: Bump release to 0.1.1 to build a tar ball that + works with CVS evince. + + * poppler.pc.in (Cflags): Change include dir to be poppler. + + * poppler/Makefile.am (poppler_include_HEADERS): Add splash and + cairo headers. + +2005-02-27 Kristian Høgsberg + + * test/gtk-cairo-test.cc: Add cairo test case. + + * configure.ac, poppler/Makefile.am, poppler/Cairo*: Add Alex + Larsons cairo output device. + + * configure.ac, Makefile.am: Make splash backend conditional. + + * test/*: Add optional GdkRGB based test program (taken from + evince). + + * goo/*: rename files and functions to GooHash, GooString etc. to + avoid nasty glib clash. + + * poppler.pc.in: New file. + + * configure.ac: Combining bits from evince configure.ac and + removing checks only required by the xpdf applications. + + * everything: Created poppler as a fork of xpdf. diff --git a/rosapps/smartpdf/poppler/INSTALL b/rosapps/smartpdf/poppler/INSTALL new file mode 100644 index 00000000000..56b077d6a0b --- /dev/null +++ b/rosapps/smartpdf/poppler/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PREFIX', the package will +use PREFIX as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/rosapps/smartpdf/poppler/NEWS b/rosapps/smartpdf/poppler/NEWS new file mode 100644 index 00000000000..67911238e77 --- /dev/null +++ b/rosapps/smartpdf/poppler/NEWS @@ -0,0 +1,110 @@ +Release 0.5.4 + + - Automatically read in CJK encoding files if they're + installed (#2984, #7105, #7093). This works with the new + poppler-data package. + - Speed ups by Krzysztof Kowalczyk (#8112) + - Patch from Dom Lachowicz to let the utils take input on stdin. + - Bugs fixed (#8182, #4649, #7906, #8048, #7113, #4515, #3948, + #7924, #7780, #7646, #6948, #7788, #7661, #7005) + +Release 0.5.3 + + - Add poppler as a private requires of poppler-glib. + - Allow CairoFont creation to fail more gracefully (#4030). + - Back out the rest of krh's type3 font work. + - Revert splashModeRGB8 changes. + - Add missing poppler-annotation-helper.h. + +Release 0.5.2 + + - Much improved Qt bindings (Albert Astals Cid). + - Cairo backend now supports masked images (Jeff Muizelaar, #6174). + - Patches from Kouhei Sutou to make glib bindings more + language binding friendly (#6907, #6897, #6899, #6905). + - Search now works with ligatures (Ed Catmull, #2929). + - The glib bindings now has an entry point to render to a cairo_t. + - GCC 4.1 and MSVC compilation fixes. + - Memory leaks plugged: #6908, #6947, #6765, #6764, #6187 + - Misc bug fixes: #6984, #6896, #6913, #6926, #4481, #5951, + #6551, #6500, #6492, #6454, #6079, #6167. + +Release 0.5.1 + + - Support for embedded files. + - Handle 0-width lines correctly. + - Avoid external file use when opening fonts. + - Only use vector fonts returned from fontconfig (#5758). + - Fix scaled 1x1 pixmaps use for drawing lines (#3387). + - drawSoftMaskedImage support in cairo backend. + - Misc bug fixes: #5922, #5946, #5749, #5952, #4030, #5420. + +Release 0.5.0 + + - Font matching code for non embedded fonts now use fontconfig + instead of hard coded list of fonts. + - Merge in Xpdf 3.01 changes. + - Add command line tools from Xpdf. + - Make install of Xpdf header files ./configure'able. + +Release 0.4.0 + + - Real text selection. + - API breakage in glib wrapper: dropping dest_x and dest_y + arguments from poppler_page_render_to_pixbuf(). + +Release 0.3.3 + + - New glib API to get document font information (Marco). + - More document properties available as glib properties (Emil + Soleyman-Zomalan, #3359) + - Optimize color conversion for images. + - Support for constant opacity. + - Fix problems with pkg-config files. + - Bugs fixes: #3491, #2911, #3362, #3340, #3265, #3239, #3396. + +Release 0.3.2 + + - New API to get poppler version and backend type. + - Various font fixes from Albert Astals Cid. + - Update to cairo 0.5.0 API, including better font support. + - Meta data for the glib binding. + +Release 0.3.1 + + - Add qt/poppler-private.h to SOURCES + - Jeff's path to use zlib instead of builtin decompression. + - Bug fixes: #2934, segfault on invalid links, #3114 + +Release 0.3.0 + + - First cut at qt wrapper, including a getText() method for + getting text from a page. + - More glib functionality: meta data, set page orientation, + print to PS + - Performance fixes for glib cairo + - Bug fixes + +Release 0.2.0 (Tue Apr 5 12:32:10 EDT 2005) + + - Add glib wrapper for poppler, which will use cairo rendering + if available + - Support for page labels + - configure and build fixes. + +Release 0.1.2 (Wed Mar 9 10:45:58 EST 2005) + + - cairo optimizations and fixes from Jeff Muizelaar + - Bump cairo requirement to 0.4 + - Make cairo and gtk checks fail gracefully + +Release 0.1.1 + + - Fix issues with installed header files including config.h + - Fix a couple of typos in pkg-config files + - Install splash and cairo header files when necessary + +Release 0.1 - no date yet + + - First release + - More NEWS here diff --git a/rosapps/smartpdf/poppler/README b/rosapps/smartpdf/poppler/README new file mode 100644 index 00000000000..c2c9e28fa40 --- /dev/null +++ b/rosapps/smartpdf/poppler/README @@ -0,0 +1,37 @@ +This is poppler, a PDF rendering library. + +Poppler is a fork of the xpdf PDF viewer developed by Derek Noonburg +of Glyph and Cog, LLC. The purpose of forking xpdf is twofold. +First, we want to provide PDF rendering functionality as a shared +library, to centralize the maintenence effort. Today a number of +applications incorporate the xpdf code base, and whenever a security +issue is discovered, all these applications exchange patches and put +out new releases. In turn, all distributions must package and release +new version of these xpdf based viewers. It's safe to say that +there's a lot of duplicated effort with the current situaion. Even if +poppler in the short term introduces yet another xpdf derived code +base to the world, we hope that over time these applications will +adopt poppler. After all, we only need one application to use poppler +to break even. + +Second, we would like to move libpoppler forward in a number of areas +that doesn't fit within the goals of xpdf. By design, xpdf depends on +very few libraries and runs a wide range of X based platforms. This +is a strong feature and reasonable design goal. However, with poppler +we would like to replace parts of xpdf that are now available as +standard components of modern Unix desktop environments. One such +example is fontconfig, which solves the problem of matching and +locating fonts on the system, in a standardized and well understood +way. Another example is cairo, which provides high quality 2D +rendering. See the file TODO for a list of planned changes. + +Please note that xpdf, and thus poppler, is licensed under the GPL, +not the LGPL. Consequently, any application using poppler must also +be licensed under the GPL. If you want to incorporate Xpdf based PDF +rendering in a closed source product, please contact Glyph & Cog +(www.glyphandcog.com) for commercial licensing options. + + Kristian Høgsberg, Feb. 27, 2005 + + +See the README-XPDF for the original xpdf-3.00 README. diff --git a/rosapps/smartpdf/poppler/README-XPDF b/rosapps/smartpdf/poppler/README-XPDF new file mode 100644 index 00000000000..ff674a2a7b7 --- /dev/null +++ b/rosapps/smartpdf/poppler/README-XPDF @@ -0,0 +1,376 @@ +Xpdf +==== + +version 3.00 +2004-jan-22 + +The Xpdf software and documentation are +copyright 1996-2004 Glyph & Cog, LLC. + +Email: derekn@foolabs.com +WWW: http://www.foolabs.com/xpdf/ + +The PDF data structures, operators, and specification are +copyright 1985-2003 Adobe Systems Inc. + + +What is Xpdf? +------------- + +Xpdf is an open source viewer for Portable Document Format (PDF) +files. (These are also sometimes also called 'Acrobat' files, from +the name of Adobe's PDF software.) The Xpdf project also includes a +PDF text extractor, PDF-to-PostScript converter, and various other +utilities. + +Xpdf runs under the X Window System on UNIX, VMS, and OS/2. The non-X +components (pdftops, pdftotext, etc.) also run on Win32 systems and +should run on pretty much any system with a decent C++ compiler. + +Xpdf is designed to be small and efficient. It can use Type 1 or +TrueType fonts. + + +Distribution +------------ + +Xpdf is licensed under the GNU General Public License (GPL), version +2. In my opinion, the GPL is a convoluted, confusing, ambiguous mess. +But it's also pervasive, and I'm sick of arguing. And even if it is +confusing, the basic idea is good. + +In order to cut down on the confusion a little bit, here are some +informal clarifications: + +- I don't mind if you redistribute Xpdf in source and/or binary form, + as long as you include all of the documentation: README, man pages + (or help files), and COPYING. (Note that the README file contains a + pointer to a web page with the source code.) + +- Selling a CD-ROM that contains Xpdf is fine with me, as long as it + includes the documentation. I wouldn't mind receiving a sample + copy, but it's not necessary. + +- If you make useful changes to Xpdf, please make the source code + available -- post it on a web site, email it to me, whatever. + +If you're interested in commercial licensing, please see the Glyph & +Cog web site: + + http://www.glyphandcog.com/ + + +Compatibility +------------- + +Xpdf is developed and tested on a Linux 2.4 x86 system. + +In addition, it has been compiled by others on Solaris, AIX, HP-UX, +Digital Unix, Irix, and numerous other Unix implementations, as well +as VMS and OS/2. It should work on pretty much any system which runs +X11 and has Unix-like libraries. You'll need ANSI C++ and C compilers +to compile it. + +The non-X components of Xpdf (pdftops, pdftotext, pdfinfo, pdffonts, +pdftoppm, and pdfimages) can also be compiled on Win32 systems. See +the Xpdf web page for details. + +If you compile Xpdf for a system not listed on the web page, please +let me know. If you're willing to make your binary available by ftp +or on the web, I'll be happy to add a link from the Xpdf web page. I +have decided not to host any binaries I didn't compile myself (for +disk space and support reasons). + +If you can't get Xpdf to compile on your system, send me email and +I'll try to help. + +Xpdf has been ported to the Acorn, Amiga, BeOS, and EPOC. See the +Xpdf web page for links. + + +Getting Xpdf +------------ + +The latest version is available from: + + http://www.foolabs.com/xpdf/ + +or: + + ftp://ftp.foolabs.com/pub/xpdf/ + +Source code and several precompiled executables are available. + +Announcements of new versions are posted to several newsgroups +(comp.text.pdf, comp.os.linux.announce, and others) and emailed to a +list of people. If you'd like to receive email notification of new +versions, just let me know. + + +Running Xpdf +------------ + +To run xpdf, simply type: + + xpdf file.pdf + +To generate a PostScript file, hit the "print" button in xpdf, or run +pdftops: + + pdftops file.pdf + +To generate a plain text file, run pdftotext: + + pdftotext file.pdf + +There are four additional utilities (which are fully described in +their man pages): + + pdfinfo -- dumps a PDF file's Info dictionary (plus some other + useful information) + pdffonts -- lists the fonts used in a PDF file along with various + information for each font + pdftoppm -- converts a PDF file to a series of PPM/PGM/PBM-format + bitmaps + pdfimages -- extracts the images from a PDF file + +Command line options and many other details are described in the man +pages (xpdf.1, etc.) and the VMS help files (xpdf.hlp, etc.). + + +Upgrading from Xpdf 2.xx +------------------------ + +WARNING: Xpdf 3.00 switched to a new PDF rasterizer, which no longer +uses X fonts. You'll need a set of Base-14 fonts -- the URW fonts +distributed with ghostscript can be used for this. Xpdf will search +for the URW fonts, but if you have them installed in a non-standard +directory, you'll need to set up an xpdfrc config file to point to +them. For full details, please see the xpdfrc(5) man page. + + +Compiling Xpdf +-------------- + +See the separate file, INSTALL. + + +Bugs +---- + +If you find a bug in Xpdf, i.e., if it prints an error message, +crashes, or incorrectly displays a document, and you don't see that +bug listed here, please send me email, with a pointer (URL, ftp site, +etc.) to the PDF file. + + +Acknowledgments +--------------- + +Thanks to: + +* Patrick Voigt for help with the remote server code. +* Patrick Moreau, Martin P.J. Zinser, and David Mathog for the VMS + port. +* David Boldt and Rick Rodgers for sample man pages. +* Brendan Miller for the icon idea. +* Olly Betts for help testing pdftotext. +* Peter Ganten for the OS/2 port. +* Michael Richmond for the Win32 port of pdftops and pdftotext and the + xpdf/cygwin/XFree86 build instructions. +* Frank M. Siegert for improvements in the PostScript code. +* Leo Smiers for the decryption patches. +* Rainer Menzner for creating t1lib, and for helping me adapt it to + xpdf. +* Pine Tree Systems A/S for funding the OPI and EPS support in + pdftops. +* Easy Software Products for funding the "sh" operator support. +* Tom Kacvinsky for help with FreeType and for being my interface to + the FreeType team. +* Theppitak Karoonboonyanan for help with Thai support. +* Leonard Rosenthol for help and contributions on a bunch of things. +* Alexandros Diamantidis and Maria Adaloglou for help with Greek + support. +* Lawrence Lai for help with the CJK Unicode maps. + +Various people have contributed modifications made for use by the +pdftex project: + +* Han The Thanh +* Martin Schröder of ArtCom GmbH + + +References +---------- + +Adobe Systems Inc., _PDF Reference: Adobe Portable Document Format +Version 1.5_. +http://partners.adobe.com/asn/tech/pdf/specifications.jsp +[The manual for PDF version 1.5.] + +Adobe Systems Inc., _PostScript Language Reference_, 3rd ed. +Addison-Wesley, 1999, ISBN 0-201-37922-8. +[The official PostScript manual.] + +Adobe Systems, Inc., _The Type 42 Font Format Specification_, +Adobe Developer Support Technical Specification #5012. 1998. +http://partners.adobe.com/asn/developer/pdfs/tn/5012.Type42_Spec.pdf +[Type 42 is the format used to embed TrueType fonts in PostScript +files.] + +Adobe Systems, Inc., _Adobe CMap and CIDFont Files Specification_, +Adobe Developer Support Technical Specification #5014. 1995. +http://www.adobe.com/supportservice/devrelations/PDFS/TN/5014.CIDFont_Spec.pdf +[CMap file format needed for Japanese and Chinese font support.] + +Adobe Systems, Inc., _Adobe-Japan1-4 Character Collection for +CID-Keyed Fonts_, Adobe Developer Support Technical Note #5078. +2000. +http://partners.adobe.com/asn/developer/PDFS/TN/5078.CID_Glyph.pdf +[The Adobe Japanese character set.] + +Adobe Systems, Inc., _Adobe-GB1-4 Character Collection for +CID-Keyed Fonts_, Adobe Developer Support Technical Note #5079. +2000. +http://partners.adobe.com/asn/developer/pdfs/tn/5079.Adobe-GB1-4.pdf +[The Adobe Chinese GB (simplified) character set.] + +Adobe Systems, Inc., _Adobe-CNS1-3 Character Collection for +CID-Keyed Fonts_, Adobe Developer Support Technical Note #5080. +2000. +http://partners.adobe.com/asn/developer/PDFS/TN/5080.CNS_CharColl.pdf +[The Adobe Chinese CNS (traditional) character set.] + +Adobe Systems Inc., _Supporting the DCT Filters in PostScript Level +2_, Adobe Developer Support Technical Note #5116. 1992. +http://www.adobe.com/supportservice/devrelations/PDFS/TN/5116.PS2_DCT.PDF +[Description of the DCTDecode filter parameters.] + +Adobe Systems Inc., _Open Prepress Interface (OPI) Specification - +Version 2.0_, Adobe Developer Support Technical Note #5660. 2000. +http://partners.adobe.com/asn/developer/PDFS/TN/5660.OPI_2.0.pdf + +Adobe Systems Inc., CMap files. +ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/ +[The actual CMap files for the 16-bit CJK encodings.] + +Adobe Systems Inc., Unicode glyph lists. +http://partners.adobe.com/asn/developer/type/unicodegn.html +http://partners.adobe.com/asn/developer/type/glyphlist.txt +http://partners.adobe.com/asn/developer/type/corporateuse.txt +http://partners.adobe.com/asn/developer/type/zapfdingbats.txt +[Mappings between character names to Unicode.] + +Aldus Corp., _OPI: Open Prepress Interface Specification 1.3_. 1993. +http://partners.adobe.com/asn/developer/PDFS/TN/OPI_13.pdf + +Anonymous, RC4 source code. +ftp://ftp.ox.ac.uk/pub/crypto/misc/rc4.tar.gz +ftp://idea.sec.dsi.unimi.it/pub/crypt/code/rc4.tar.gz +[This is the algorithm used to encrypt PDF files.] + +T. Boutell, et al., "PNG (Portable Network Graphics) Specification, +Version 1.0. RFC 2083. +[PDF uses the PNG filter algorithms.] + +CCITT, "Information Technology - Digital Compression and Coding of +Continuous-tone Still Images - Requirements and Guidelines", CCITT +Recommendation T.81. +http://www.w3.org/Graphics/JPEG/ +[The official JPEG spec.] + +A. Chernov, "Registration of a Cyrillic Character Set". RFC 1489. +[Documentation for the KOI8-R Cyrillic encoding.] + +Roman Czyborra, "The ISO 8859 Alphabet Soup". +http://czyborra.com/charsets/iso8859.html +[Documentation on the various ISO 859 encodings.] + +L. Peter Deutsch, "ZLIB Compressed Data Format Specification version +3.3". RFC 1950. +[Information on the general format used in FlateDecode streams.] + +L. Peter Deutsch, "DEFLATE Compressed Data Format Specification +version 1.3". RFC 1951. +[The definition of the compression algorithm used in FlateDecode +streams.] + +Jim Flowers, "X Logical Font Description Conventions", Version 1.5, X +Consortium Standard, X Version 11, Release 6.1. +ftp://ftp.x.org/pub/R6.1/xc/doc/hardcopy/XLFD/xlfd.PS.Z +[The official specification of X font descriptors, including font +transformation matrices.] + +Foley, van Dam, Feiner, and Hughes, _Computer Graphics: Principles and +Practice_, 2nd ed. Addison-Wesley, 1990, ISBN 0-201-12110-7. +[Colorspace conversion functions, Bezier spline math.] + +Robert L. Hummel, _Programmer's Technical Reference: Data and Fax +Communications_. Ziff-Davis Press, 1993, ISBN 1-56276-077-7. +[CCITT Group 3 and 4 fax decoding.] + +ISO/IEC, _Information technology -- Lossy/lossless coding of bi-level +images_. ISO/IEC 14492, First edition (2001-12-15). +http://webstore.ansi.org/ +[The official JBIG2 standard. The final draft of this spec is +available from http://www.jpeg.org/jbighomepage.html.] + +ISO/IEC, _Information technology -- JPEG 2000 image coding system -- +Part 1: Core coding system_. ISO/IEC 15444-1, First edition +(2000-12-15). +http://webstore.ansi.org/ +[The official JPEG 2000 standard. The final committee draft of this +spec is available from http://www.jpeg.org/JPEG2000.html, but there +were changes made to the bitstream format between that draft and the +published spec.] + +ITU, "Standardization of Group 3 facsimile terminals for document +transmission", ITU-T Recommendation T.4, 1999. +ITU, "Facsimile coding schemes and coding control functions for Group 4 +facsimile apparatus", ITU-T Recommendation T.6, 1993. +http://www.itu.int/ +[The official Group 3 and 4 fax standards - used by the CCITTFaxDecode +stream, as well as the JBIG2Decode stream.] + +Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, "Practical +Fast 1-D DCT Algorithms with 11 Multiplications". IEEE Intl. Conf. on +Acoustics, Speech & Signal Processing, 1989, 988-991. +[The fast IDCT algorithm used in the DCTDecode filter.] + +Microsoft, _TrueType 1.0 Font Files_, rev. 1.66. 1995. +http://www.microsoft.com/typography/tt/tt.htm +[The TrueType font spec (in MS Word format, naturally).] + +Thai Industrial Standard, "Standard for Thai Character Codes for +Computers", TIS-620-2533 (1990). +http://www.nectec.or.th/it-standards/std620/std620.htm +[The TIS-620 Thai encoding.] + +P. Peterlin, "ISO 8859-2 (Latin 2) Resources". +http://sizif.mf.uni-lj.si/linux/cee/iso8859-2.html +[This is a web page with all sorts of useful Latin-2 character set and +font information.] + +Charles Poynton, "Color FAQ". +http://www.inforamp.net/~poynton/ColorFAQ.html +[The mapping from the CIE 1931 (XYZ) color space to RGB.] + +R. Rivest, "The MD5 Message-Digest Algorithm". RFC 1321. +[MD5 is used in PDF document encryption.] + +Unicode Consortium, "Unicode Home Page". +http://www.unicode.org/ +[Online copy of the Unicode spec.] + +W3C Recommendation, "PNG (Portable Network Graphics) Specification +Version 1.0". +http://www.w3.org/Graphics/PNG/ +[Defines the PNG image predictor.] + +Gregory K. Wallace, "The JPEG Still Picture Compression Standard". +ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz +[Good description of the JPEG standard. Also published in CACM, April +1991, and submitted to IEEE Transactions on Consumer Electronics.] + +F. Yergeau, "UTF-8, a transformation format of ISO 10646". RFC 2279. +[A commonly used Unicode encoding.] diff --git a/rosapps/smartpdf/poppler/TODO b/rosapps/smartpdf/poppler/TODO new file mode 100644 index 00000000000..c7971a8390f --- /dev/null +++ b/rosapps/smartpdf/poppler/TODO @@ -0,0 +1,51 @@ +Here's the plan as of March 21: + + - Finish glib and qobject wrappers and get rid of the 80 + header files that current constitute the poppler public API. + Make sure the APIs are usable for kpdf and evince and other + tools that use poppler (thumbnailers, metadata plugins + etc.). + + - Make the cairo backend feature complete and optimize the + heck out of it. + + - Investigate better (that is, normal) text selection. + + - Use PDF font descriptors to create an FcPattern. + +Convert to use as much existing infra-structure as possible: + - drop t1lib entirely + - use fontconfig + - dont use /etc/xpdf.rc, add abstraction that can work with + GNOME and KDE configuration systems (GConf and ?) + - improve cairo backend + - use jasper for jpeg2000 decoding? + - use littlecms for color management? + - use libtiff for ccitt decoding? + +Performance: + - Add simle performance benchmark that takes a pdf and renders + every page 100 times or so. Start keeping track of + performance. + - make color space conversion stuff more sane (right now we + hack around some of it in the cairo backend) + - move away from getChar to a more read(2) like interface + +Done: + - rename GString etc in goo lib to make it more glib friendly + - make splash optional + + - Install poppler-splash.pc and poppler-cairo.pc to indicate + available backends. Alternatively, just hide the backend + choice from the application. This is done now, but for this + to work properly, we really need multiple .so's. + + [ This will go away again once we get the wrappers done. ] + +Jeff Muizelaar's TODO: + Short Term: + - factor out some of the color conversion code from CairoOutputDev and ArthurOutputDev. + - fix patterned text fills. + Long Term: + - use cairo glyph cache for type3 fonts. + - try to use cairo pattern support. diff --git a/rosapps/smartpdf/poppler/fofi/FoFiBase.cc b/rosapps/smartpdf/poppler/fofi/FoFiBase.cc new file mode 100644 index 00000000000..ef8992a0825 --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiBase.cc @@ -0,0 +1,156 @@ +//======================================================================== +// +// FoFiBase.cc +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "FoFiBase.h" + +//------------------------------------------------------------------------ +// FoFiBase +//------------------------------------------------------------------------ + +FoFiBase::FoFiBase(char *fileA, int lenA, GBool freeFileDataA) { + fileData = file = (Guchar *)fileA; + len = lenA; + freeFileData = freeFileDataA; +} + +FoFiBase::~FoFiBase() { + if (freeFileData) { + gfree(fileData); + } +} + +char *FoFiBase::readFile(char *fileName, int *fileLen) { + FILE *f; + char *buf; + int n; + + if (!(f = fopen(fileName, "rb"))) { + return NULL; + } + fseek(f, 0, SEEK_END); + n = (int)ftell(f); + fseek(f, 0, SEEK_SET); + buf = (char *)gmalloc(n); + if ((int)fread(buf, 1, n, f) != n) { + gfree(buf); + fclose(f); + return NULL; + } + fclose(f); + *fileLen = n; + return buf; +} + +int FoFiBase::getS8(int pos, GBool *ok) { + int x; + + if (pos < 0 || pos >= len) { + *ok = gFalse; + return 0; + } + x = file[pos]; + if (x & 0x80) { + x |= ~0xff; + } + return x; +} + +int FoFiBase::getU8(int pos, GBool *ok) { + if (pos < 0 || pos >= len) { + *ok = gFalse; + return 0; + } + return file[pos]; +} + +int FoFiBase::getS16BE(int pos, GBool *ok) { + int x; + + if (pos < 0 || pos+1 >= len) { + *ok = gFalse; + return 0; + } + x = file[pos]; + x = (x << 8) + file[pos+1]; + if (x & 0x8000) { + x |= ~0xffff; + } + return x; +} + +int FoFiBase::getU16BE(int pos, GBool *ok) { + int x; + + if (pos < 0 || pos+1 >= len) { + *ok = gFalse; + return 0; + } + x = file[pos]; + x = (x << 8) + file[pos+1]; + return x; +} + +int FoFiBase::getS32BE(int pos, GBool *ok) { + int x; + + if (pos < 0 || pos+3 >= len) { + *ok = gFalse; + return 0; + } + x = file[pos]; + x = (x << 8) + file[pos+1]; + x = (x << 8) + file[pos+2]; + x = (x << 8) + file[pos+3]; + if (x & 0x80000000) { + x |= ~0xffffffff; + } + return x; +} + +Guint FoFiBase::getU32BE(int pos, GBool *ok) { + Guint x; + + if (pos < 0 || pos+3 >= len) { + *ok = gFalse; + return 0; + } + x = file[pos]; + x = (x << 8) + file[pos+1]; + x = (x << 8) + file[pos+2]; + x = (x << 8) + file[pos+3]; + return x; +} + +Guint FoFiBase::getUVarBE(int pos, int size, GBool *ok) { + Guint x; + int i; + + if (pos < 0 || pos + size > len) { + *ok = gFalse; + return 0; + } + x = 0; + for (i = 0; i < size; ++i) { + x = (x << 8) + file[pos + i]; + } + return x; +} + +GBool FoFiBase::checkRegion(int pos, int size) { + return pos >= 0 && + pos + size >= pos && + pos + size <= len; +} diff --git a/rosapps/smartpdf/poppler/fofi/FoFiBase.h b/rosapps/smartpdf/poppler/fofi/FoFiBase.h new file mode 100644 index 00000000000..e2550017aac --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiBase.h @@ -0,0 +1,55 @@ +//======================================================================== +// +// FoFiBase.h +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FOFIBASE_H +#define FOFIBASE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +//------------------------------------------------------------------------ + +typedef void (*FoFiOutputFunc)(void *stream, char *data, int len); + +//------------------------------------------------------------------------ +// FoFiBase +//------------------------------------------------------------------------ + +class FoFiBase { +public: + + virtual ~FoFiBase(); + +protected: + + FoFiBase(char *fileA, int lenA, GBool freeFileDataA); + static char *readFile(char *fileName, int *fileLen); + + // S = signed / U = unsigned + // 8/16/32/Var = word length, in bytes + // BE = big endian + int getS8(int pos, GBool *ok); + int getU8(int pos, GBool *ok); + int getS16BE(int pos, GBool *ok); + int getU16BE(int pos, GBool *ok); + int getS32BE(int pos, GBool *ok); + Guint getU32BE(int pos, GBool *ok); + Guint getUVarBE(int pos, int size, GBool *ok); + + GBool checkRegion(int pos, int size); + + Guchar *fileData; + Guchar *file; + int len; + GBool freeFileData; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/fofi/FoFiEncodings.cc b/rosapps/smartpdf/poppler/fofi/FoFiEncodings.cc new file mode 100644 index 00000000000..946b56c19d0 --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiEncodings.cc @@ -0,0 +1,994 @@ +//======================================================================== +// +// FoFiEncodings.cc +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "FoFiEncodings.h" + +//------------------------------------------------------------------------ +// Type 1 and 1C font data +//------------------------------------------------------------------------ + +char *fofiType1StandardEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "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", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + NULL, + "endash", + "dagger", + "daggerdbl", + "periodcentered", + NULL, + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + NULL, + "questiondown", + NULL, + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + NULL, + "ring", + "cedilla", + NULL, + "hungarumlaut", + "ogonek", + "caron", + "emdash", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "AE", + NULL, + "ordfeminine", + NULL, + NULL, + NULL, + NULL, + "Lslash", + "Oslash", + "OE", + "ordmasculine", + NULL, + NULL, + NULL, + NULL, + NULL, + "ae", + NULL, + NULL, + NULL, + "dotlessi", + NULL, + NULL, + "lslash", + "oslash", + "oe", + "germandbls", + NULL, + NULL, + NULL, + NULL +}; + +char *fofiType1ExpertEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclamsmall", + "Hungarumlautsmall", + NULL, + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + NULL, + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + NULL, + NULL, + NULL, + "isuperior", + NULL, + NULL, + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + NULL, + NULL, + "rsuperior", + "ssuperior", + "tsuperior", + NULL, + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + NULL, + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + NULL, + NULL, + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + NULL, + "Dotaccentsmall", + NULL, + NULL, + "Macronsmall", + NULL, + NULL, + "figuredash", + "hypheninferior", + NULL, + NULL, + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + NULL, + NULL, + NULL, + "onequarter", + "onehalf", + "threequarters", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + NULL, + NULL, + "zerosuperior", + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall" +}; + +//------------------------------------------------------------------------ +// Type 1C font data +//------------------------------------------------------------------------ + +char *fofiType1CStdStrings[391] = { + ".notdef", + "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", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", + "001.000", + "001.001", + "001.002", + "001.003", + "Black", + "Bold", + "Book", + "Light", + "Medium", + "Regular", + "Roman", + "Semibold" +}; + +Gushort fofiType1CISOAdobeCharset[229] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228 +}; + +Gushort fofiType1CExpertCharset[166] = { + 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, + 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378 +}; + +Gushort fofiType1CExpertSubsetCharset[87] = { + 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, + 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, + 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, + 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346 +}; diff --git a/rosapps/smartpdf/poppler/fofi/FoFiEncodings.h b/rosapps/smartpdf/poppler/fofi/FoFiEncodings.h new file mode 100644 index 00000000000..fb4eca86d9f --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiEncodings.h @@ -0,0 +1,34 @@ +//======================================================================== +// +// FoFiEncodings.h +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FOFIENCODINGS_H +#define FOFIENCODINGS_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +//------------------------------------------------------------------------ +// Type 1 and 1C font data +//------------------------------------------------------------------------ + +extern char *fofiType1StandardEncoding[256]; +extern char *fofiType1ExpertEncoding[256]; + +//------------------------------------------------------------------------ +// Type 1C font data +//------------------------------------------------------------------------ + +extern char *fofiType1CStdStrings[391]; +extern Gushort fofiType1CISOAdobeCharset[229]; +extern Gushort fofiType1CExpertCharset[166]; +extern Gushort fofiType1CExpertSubsetCharset[87]; + +#endif diff --git a/rosapps/smartpdf/poppler/fofi/FoFiTrueType.cc b/rosapps/smartpdf/poppler/fofi/FoFiTrueType.cc new file mode 100644 index 00000000000..6e7d95a6859 --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiTrueType.cc @@ -0,0 +1,1781 @@ +//======================================================================== +// +// FoFiTrueType.cc +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gtypes.h" +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "goo/GooHash.h" +#include "FoFiTrueType.h" + +// +// Terminology +// ----------- +// +// character code = number used as an element of a text string +// +// character name = glyph name = name for a particular glyph within a +// font +// +// glyph index = GID = position (within some internal table in the font) +// where the instructions to draw a particular glyph are +// stored +// +// Type 1 fonts +// ------------ +// +// Type 1 fonts contain: +// +// Encoding: array of glyph names, maps char codes to glyph names +// +// Encoding[charCode] = charName +// +// CharStrings: dictionary of instructions, keyed by character names, +// maps character name to glyph data +// +// CharStrings[charName] = glyphData +// +// TrueType fonts +// -------------- +// +// TrueType fonts contain: +// +// 'cmap' table: mapping from character code to glyph index; there may +// be multiple cmaps in a TrueType font +// +// cmap[charCode] = gid +// +// 'post' table: mapping from glyph index to glyph name +// +// post[gid] = glyphName +// +// Type 42 fonts +// ------------- +// +// Type 42 fonts contain: +// +// Encoding: array of glyph names, maps char codes to glyph names +// +// Encoding[charCode] = charName +// +// CharStrings: dictionary of glyph indexes, keyed by character names, +// maps character name to glyph index +// +// CharStrings[charName] = gid +// + +//------------------------------------------------------------------------ + +#define ttcfTag 0x74746366 + +//------------------------------------------------------------------------ + +struct TrueTypeTable { + Guint tag; + Guint checksum; + int offset; + int origOffset; + int len; +}; + +struct TrueTypeCmap { + int platform; + int encoding; + int offset; + int len; + int fmt; +}; + +struct TrueTypeLoca { + int idx; + int origOffset; + int newOffset; + int len; +}; + +#define cmapTag 0x636d6170 +#define glyfTag 0x676c7966 +#define headTag 0x68656164 +#define locaTag 0x6c6f6361 +#define nameTag 0x6e616d65 +#define postTag 0x706f7374 + +static int cmpTrueTypeLocaOffset(const void *p1, const void *p2) { + TrueTypeLoca *loca1 = (TrueTypeLoca *)p1; + TrueTypeLoca *loca2 = (TrueTypeLoca *)p2; + + if (loca1->origOffset == loca2->origOffset) { + return loca1->idx - loca2->idx; + } + return loca1->origOffset - loca2->origOffset; +} + +static int cmpTrueTypeLocaIdx(const void *p1, const void *p2) { + TrueTypeLoca *loca1 = (TrueTypeLoca *)p1; + TrueTypeLoca *loca2 = (TrueTypeLoca *)p2; + + return loca1->idx - loca2->idx; +} + +static int cmpTrueTypeTableTag(const void *p1, const void *p2) { + TrueTypeTable *tab1 = (TrueTypeTable *)p1; + TrueTypeTable *tab2 = (TrueTypeTable *)p2; + + return (int)tab1->tag - (int)tab2->tag; +} + +//------------------------------------------------------------------------ + +struct T42Table { + char *tag; // 4-byte tag + GBool required; // required by the TrueType spec? +}; + +// TrueType tables to be embedded in Type 42 fonts. +// NB: the table names must be in alphabetical order here. +#define nT42Tables 11 +static T42Table t42Tables[nT42Tables] = { + { "cvt ", gTrue }, + { "fpgm", gTrue }, + { "glyf", gTrue }, + { "head", gTrue }, + { "hhea", gTrue }, + { "hmtx", gTrue }, + { "loca", gTrue }, + { "maxp", gTrue }, + { "prep", gTrue }, + { "vhea", gFalse }, + { "vmtx", gFalse } +}; +#define t42HeadTable 3 +#define t42LocaTable 6 +#define t42GlyfTable 2 +#define t42VheaTable 9 +#define t42VmtxTable 10 + +//------------------------------------------------------------------------ + +// Glyph names in some arbitrary standard order that Apple uses for +// their TrueType fonts. +static char *macGlyphNames[258] = { + ".notdef", "null", "CR", "space", + "exclam", "quotedbl", "numbersign", "dollar", + "percent", "ampersand", "quotesingle", "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", "grave", + "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", "Adieresis", "Aring", + "Ccedilla", "Eacute", "Ntilde", "Odieresis", + "Udieresis", "aacute", "agrave", "acircumflex", + "adieresis", "atilde", "aring", "ccedilla", + "eacute", "egrave", "ecircumflex", "edieresis", + "iacute", "igrave", "icircumflex", "idieresis", + "ntilde", "oacute", "ograve", "ocircumflex", + "odieresis", "otilde", "uacute", "ugrave", + "ucircumflex", "udieresis", "dagger", "degree", + "cent", "sterling", "section", "bullet", + "paragraph", "germandbls", "registered", "copyright", + "trademark", "acute", "dieresis", "notequal", + "AE", "Oslash", "infinity", "plusminus", + "lessequal", "greaterequal", "yen", "mu1", + "partialdiff", "summation", "product", "pi", + "integral", "ordfeminine", "ordmasculine", "Ohm", + "ae", "oslash", "questiondown", "exclamdown", + "logicalnot", "radical", "florin", "approxequal", + "increment", "guillemotleft", "guillemotright", "ellipsis", + "nbspace", "Agrave", "Atilde", "Otilde", + "OE", "oe", "endash", "emdash", + "quotedblleft", "quotedblright", "quoteleft", "quoteright", + "divide", "lozenge", "ydieresis", "Ydieresis", + "fraction", "currency", "guilsinglleft", "guilsinglright", + "fi", "fl", "daggerdbl", "periodcentered", + "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", + "Ecircumflex", "Aacute", "Edieresis", "Egrave", + "Iacute", "Icircumflex", "Idieresis", "Igrave", + "Oacute", "Ocircumflex", "applelogo", "Ograve", + "Uacute", "Ucircumflex", "Ugrave", "dotlessi", + "circumflex", "tilde", "overscore", "breve", + "dotaccent", "ring", "cedilla", "hungarumlaut", + "ogonek", "caron", "Lslash", "lslash", + "Scaron", "scaron", "Zcaron", "zcaron", + "brokenbar", "Eth", "eth", "Yacute", + "yacute", "Thorn", "thorn", "minus", + "multiply", "onesuperior", "twosuperior", "threesuperior", + "onehalf", "onequarter", "threequarters", "franc", + "Gbreve", "gbreve", "Idot", "Scedilla", + "scedilla", "Cacute", "cacute", "Ccaron", + "ccaron", "dmacron" +}; + +//------------------------------------------------------------------------ +// FoFiTrueType +//------------------------------------------------------------------------ + +FoFiTrueType *FoFiTrueType::make(char *fileA, int lenA, int faceIndexA) { + FoFiTrueType *ff; + + ff = new FoFiTrueType(fileA, lenA, gFalse, faceIndexA); + if (!ff->parsedOk) { + delete ff; + return NULL; + } + return ff; +} + +FoFiTrueType *FoFiTrueType::load(char *fileName, int faceIndexA) { + FoFiTrueType *ff; + char *fileA; + int lenA; + + if (!(fileA = FoFiBase::readFile(fileName, &lenA))) { + return NULL; + } + ff = new FoFiTrueType(fileA, lenA, gTrue, faceIndexA); + if (!ff->parsedOk) { + delete ff; + return NULL; + } + return ff; +} + +FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA): + FoFiBase(fileA, lenA, freeFileDataA) +{ + tables = NULL; + nTables = 0; + cmaps = NULL; + nCmaps = 0; + nameToGID = NULL; + parsedOk = gFalse; + faceIndex = faceIndexA; + + parse(); +} + +FoFiTrueType::~FoFiTrueType() { + gfree(tables); + gfree(cmaps); + if (nameToGID) { + delete nameToGID; + } +} + +int FoFiTrueType::getNumCmaps() { + return nCmaps; +} + +int FoFiTrueType::getCmapPlatform(int i) { + return cmaps[i].platform; +} + +int FoFiTrueType::getCmapEncoding(int i) { + return cmaps[i].encoding; +} + +int FoFiTrueType::findCmap(int platform, int encoding) { + int i; + + for (i = 0; i < nCmaps; ++i) { + if (cmaps[i].platform == platform && cmaps[i].encoding == encoding) { + return i; + } + } + return -1; +} + +Gushort FoFiTrueType::mapCodeToGID(int i, int c) { + Gushort gid; + int segCnt, segEnd, segStart, segDelta, segOffset; + int cmapFirst, cmapLen; + int pos, a, b, m; + GBool ok; + + if (i < 0 || i >= nCmaps) { + return 0; + } + ok = gTrue; + pos = cmaps[i].offset; + switch (cmaps[i].fmt) { + case 0: + if (c < 0 || c >= cmaps[i].len - 6) { + return 0; + } + gid = getU8(cmaps[i].offset + 6 + c, &ok); + break; + case 4: + segCnt = getU16BE(pos + 6, &ok) / 2; + a = -1; + b = segCnt - 1; + segEnd = getU16BE(pos + 14 + 2*b, &ok); + if (c > segEnd) { + // malformed font -- the TrueType spec requires the last segEnd + // to be 0xffff + return 0; + } + // invariant: seg[a].end < code <= seg[b].end + while (b - a > 1 && ok) { + m = (a + b) / 2; + segEnd = getU16BE(pos + 14 + 2*m, &ok); + if (segEnd < c) { + a = m; + } else { + b = m; + } + } + segStart = getU16BE(pos + 16 + 2*segCnt + 2*b, &ok); + segDelta = getU16BE(pos + 16 + 4*segCnt + 2*b, &ok); + segOffset = getU16BE(pos + 16 + 6*segCnt + 2*b, &ok); + if (c < segStart) { + return 0; + } + if (segOffset == 0) { + gid = (c + segDelta) & 0xffff; + } else { + gid = getU16BE(pos + 16 + 6*segCnt + 2*b + + segOffset + 2 * (c - segStart), &ok); + if (gid != 0) { + gid = (gid + segDelta) & 0xffff; + } + } + break; + case 6: + cmapFirst = getU16BE(pos + 6, &ok); + cmapLen = getU16BE(pos + 8, &ok); + if (c < cmapFirst || c >= cmapFirst + cmapLen) { + return 0; + } + gid = getU16BE(pos + 10 + 2 * (c - cmapFirst), &ok); + break; + default: + return 0; + } + if (!ok) { + return 0; + } + return gid; +} + +int FoFiTrueType::mapNameToGID(char *name) { + if (!nameToGID) { + return 0; + } + return nameToGID->lookupInt(name); +} + +int FoFiTrueType::getEmbeddingRights() { + int i, fsType; + GBool ok; + + if ((i = seekTable("OS/2")) < 0) { + return 4; + } + ok = gTrue; + fsType = getU16BE(tables[i].offset + 8, &ok); + if (!ok) { + return 4; + } + if (fsType & 0x0008) { + return 2; + } + if (fsType & 0x0004) { + return 1; + } + if (fsType & 0x0002) { + return 0; + } + return 3; +} + +void FoFiTrueType::convertToType42(char *psName, char **encoding, + Gushort *codeToGID, + FoFiOutputFunc outputFunc, + void *outputStream) { + char buf[512]; + GBool ok; + + // write the header + ok = gTrue; + sprintf(buf, "%%!PS-TrueTypeFont-%g\n", (double)getS32BE(0, &ok) / 65536.0); + (*outputFunc)(outputStream, buf, strlen(buf)); + + // begin the font dictionary + (*outputFunc)(outputStream, "10 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/FontType 42 def\n", 17); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + sprintf(buf, "/FontBBox [%d %d %d %d] def\n", + bbox[0], bbox[1], bbox[2], bbox[3]); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/PaintType 0 def\n", 17); + + // write the guts of the dictionary + cvtEncoding(encoding, outputFunc, outputStream); + cvtCharStrings(encoding, codeToGID, outputFunc, outputStream); + cvtSfnts(outputFunc, outputStream, NULL, gFalse); + + // end the dictionary and define the font + (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40); +} + +void FoFiTrueType::convertToCIDType2(char *psName, + Gushort *cidMap, int nCIDs, + GBool needVerticalMetrics, + FoFiOutputFunc outputFunc, + void *outputStream) { + char buf[512]; + Gushort cid; + GBool ok; + int i, j, k; + + // write the header + ok = gTrue; + sprintf(buf, "%%!PS-TrueTypeFont-%g\n", (double)getS32BE(0, &ok) / 65536.0); + (*outputFunc)(outputStream, buf, strlen(buf)); + + // begin the font dictionary + (*outputFunc)(outputStream, "20 dict begin\n", 14); + (*outputFunc)(outputStream, "/CIDFontName /", 14); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/CIDFontType 2 def\n", 19); + (*outputFunc)(outputStream, "/FontType 42 def\n", 17); + (*outputFunc)(outputStream, "/CIDSystemInfo 3 dict dup begin\n", 32); + (*outputFunc)(outputStream, " /Registry (Adobe) def\n", 24); + (*outputFunc)(outputStream, " /Ordering (Identity) def\n", 27); + (*outputFunc)(outputStream, " /Supplement 0 def\n", 20); + (*outputFunc)(outputStream, " end def\n", 10); + (*outputFunc)(outputStream, "/GDBytes 2 def\n", 15); + if (cidMap) { + sprintf(buf, "/CIDCount %d def\n", nCIDs); + (*outputFunc)(outputStream, buf, strlen(buf)); + if (nCIDs > 32767) { + (*outputFunc)(outputStream, "/CIDMap [", 9); + for (i = 0; i < nCIDs; i += 32768 - 16) { + (*outputFunc)(outputStream, "<\n", 2); + for (j = 0; j < 32768 - 16 && i+j < nCIDs; j += 16) { + (*outputFunc)(outputStream, " ", 2); + for (k = 0; k < 16 && i+j+k < nCIDs; ++k) { + cid = cidMap[i+j+k]; + sprintf(buf, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "\n", 1); + } + (*outputFunc)(outputStream, " >", 3); + } + (*outputFunc)(outputStream, "\n", 1); + (*outputFunc)(outputStream, "] def\n", 6); + } else { + (*outputFunc)(outputStream, "/CIDMap <\n", 10); + for (i = 0; i < nCIDs; i += 16) { + (*outputFunc)(outputStream, " ", 2); + for (j = 0; j < 16 && i+j < nCIDs; ++j) { + cid = cidMap[i+j]; + sprintf(buf, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "\n", 1); + } + (*outputFunc)(outputStream, "> def\n", 6); + } + } else { + // direct mapping - just fill the string(s) with s[i]=i + sprintf(buf, "/CIDCount %d def\n", nGlyphs); + (*outputFunc)(outputStream, buf, strlen(buf)); + if (nGlyphs > 32767) { + (*outputFunc)(outputStream, "/CIDMap [\n", 10); + for (i = 0; i < nGlyphs; i += 32767) { + j = nGlyphs - i < 32767 ? nGlyphs - i : 32767; + sprintf(buf, " %d string 0 1 %d {\n", 2 * j, j - 1); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, " 2 copy dup 2 mul exch %d add -8 bitshift put\n", i); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, " 1 index exch dup 2 mul 1 add exch %d add" + " 255 and put\n", i); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, " } for\n", 8); + } + (*outputFunc)(outputStream, "] def\n", 6); + } else { + sprintf(buf, "/CIDMap %d string\n", 2 * nGlyphs); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, " 0 1 %d {\n", nGlyphs - 1); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, + " 2 copy dup 2 mul exch -8 bitshift put\n", 42); + (*outputFunc)(outputStream, + " 1 index exch dup 2 mul 1 add exch 255 and put\n", 50); + (*outputFunc)(outputStream, " } for\n", 8); + (*outputFunc)(outputStream, "def\n", 4); + } + } + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + sprintf(buf, "/FontBBox [%d %d %d %d] def\n", + bbox[0], bbox[1], bbox[2], bbox[3]); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/PaintType 0 def\n", 17); + (*outputFunc)(outputStream, "/Encoding [] readonly def\n", 26); + (*outputFunc)(outputStream, "/CharStrings 1 dict dup begin\n", 30); + (*outputFunc)(outputStream, " /.notdef 0 def\n", 17); + (*outputFunc)(outputStream, " end readonly def\n", 19); + + // write the guts of the dictionary + cvtSfnts(outputFunc, outputStream, NULL, needVerticalMetrics); + + // end the dictionary and define the font + (*outputFunc)(outputStream, + "CIDFontName currentdict end /CIDFont defineresource pop\n", + 56); +} + +void FoFiTrueType::convertToType0(char *psName, Gushort *cidMap, int nCIDs, + GBool needVerticalMetrics, + FoFiOutputFunc outputFunc, + void *outputStream) { + char buf[512]; + GooString *sfntsName; + int n, i, j; + + // write the Type 42 sfnts array + sfntsName = (new GooString(psName))->append("_sfnts"); + cvtSfnts(outputFunc, outputStream, sfntsName, needVerticalMetrics); + delete sfntsName; + + // write the descendant Type 42 fonts + n = cidMap ? nCIDs : nGlyphs; + for (i = 0; i < n; i += 256) { + (*outputFunc)(outputStream, "10 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, psName, strlen(psName)); + sprintf(buf, "_%02x def\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 42 def\n", 17); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + sprintf(buf, "/FontBBox [%d %d %d %d] def\n", + bbox[0], bbox[1], bbox[2], bbox[3]); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/PaintType 0 def\n", 17); + (*outputFunc)(outputStream, "/sfnts ", 7); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, "_sfnts def\n", 11); + (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); + for (j = 0; j < 256 && i+j < n; ++j) { + sprintf(buf, "dup %d /c%02x put\n", j, j); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "readonly def\n", 13); + (*outputFunc)(outputStream, "/CharStrings 257 dict dup begin\n", 32); + (*outputFunc)(outputStream, "/.notdef 0 def\n", 15); + for (j = 0; j < 256 && i+j < n; ++j) { + sprintf(buf, "/c%02x %d def\n", j, cidMap ? cidMap[i+j] : i+j); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "end readonly def\n", 17); + (*outputFunc)(outputStream, + "FontName currentdict end definefont pop\n", 40); + } + + // write the Type 0 parent font + (*outputFunc)(outputStream, "16 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/FontType 0 def\n", 16); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + (*outputFunc)(outputStream, "/FMapType 2 def\n", 16); + (*outputFunc)(outputStream, "/Encoding [\n", 12); + for (i = 0; i < n; i += 256) { + sprintf(buf, "%d\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "/FDepVector [\n", 14); + for (i = 0; i < n; i += 256) { + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, psName, strlen(psName)); + sprintf(buf, "_%02x findfont\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40); +} + +void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc, + void *outputStream, char *name, + Gushort *codeToGID) { + // this substitute cmap table maps char codes 0000-ffff directly to + // glyphs 0000-ffff + static char cmapTab[36] = { + 0, 0, // table version number + 0, 1, // number of encoding tables + 0, 1, // platform ID + 0, 0, // encoding ID + 0, 0, 0, 12, // offset of subtable + 0, 4, // subtable format + 0, 24, // subtable length + 0, 0, // subtable version + 0, 2, // segment count * 2 + 0, 2, // 2 * 2 ^ floor(log2(segCount)) + 0, 0, // floor(log2(segCount)) + 0, 0, // 2*segCount - 2*2^floor(log2(segCount)) + (char)0xff, (char)0xff, // endCount[0] + 0, 0, // reserved + 0, 0, // startCount[0] + 0, 0, // idDelta[0] + 0, 0 // pad to a mulitple of four bytes + }; + static char nameTab[8] = { + 0, 0, // format + 0, 0, // number of name records + 0, 6, // offset to start of string storage + 0, 0 // pad to multiple of four bytes + }; + static char postTab[32] = { + 0, 1, 0, 0, // format + 0, 0, 0, 0, // italic angle + 0, 0, // underline position + 0, 0, // underline thickness + 0, 0, 0, 0, // fixed pitch + 0, 0, 0, 0, // min Type 42 memory + 0, 0, 0, 0, // max Type 42 memory + 0, 0, 0, 0, // min Type 1 memory + 0, 0, 0, 0 // max Type 1 memory + }; + GBool missingCmap, missingName, missingPost, unsortedLoca, badCmapLen; + int nZeroLengthTables; + TrueTypeLoca *locaTable; + TrueTypeTable *newTables; + char *newNameTab, *newCmapTab; + int nNewTables, cmapIdx, cmapLen, glyfLen, newNameLen, newCmapLen, next; + Guint locaChecksum, glyfChecksum, fileChecksum; + char *tableDir; + char locaBuf[4], checksumBuf[4]; + GBool ok; + Guint t; + int pos, i, j, k, n; + + // check for missing tables + missingCmap = (cmapIdx = seekTable("cmap")) < 0; + missingName = seekTable("name") < 0; + missingPost = seekTable("post") < 0; + + // read the loca table, check to see if it's sorted + locaTable = (TrueTypeLoca *)gmallocn(nGlyphs + 1, sizeof(TrueTypeLoca)); + unsortedLoca = gFalse; + i = seekTable("loca"); + pos = tables[i].offset; + ok = gTrue; + for (i = 0; i <= nGlyphs; ++i) { + if (locaFmt) { + locaTable[i].origOffset = (int)getU32BE(pos + i*4, &ok); + } else { + locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok); + } + if (i > 0 && locaTable[i].origOffset < locaTable[i-1].origOffset) { + unsortedLoca = gTrue; + } + locaTable[i].idx = i; + } + + // check for zero-length tables + nZeroLengthTables = 0; + for (i = 0; i < nTables; ++i) { + if (tables[i].len == 0) { + ++nZeroLengthTables; + } + } + + // check for an incorrect cmap table length + badCmapLen = gFalse; + cmapLen = 0; // make gcc happy + if (!missingCmap) { + cmapLen = cmaps[0].offset + cmaps[0].len; + for (i = 1; i < nCmaps; ++i) { + if (cmaps[i].offset + cmaps[i].len > cmapLen) { + cmapLen = cmaps[i].offset + cmaps[i].len; + } + } + cmapLen -= tables[cmapIdx].offset; + if (cmapLen > tables[cmapIdx].len) { + badCmapLen = gTrue; + } + } + + // if nothing is broken, just write the TTF file as is + if (!missingCmap && !missingName && !missingPost && !unsortedLoca && + !badCmapLen && nZeroLengthTables == 0 && !name && !codeToGID) { + (*outputFunc)(outputStream, (char *)file, len); + goto done1; + } + + // sort the 'loca' table: some (non-compliant) fonts have + // out-of-order loca tables; in order to correctly handle the case + // where (compliant) fonts have empty entries in the middle of the + // table, cmpTrueTypeLocaOffset uses offset as its primary sort key, + // and idx as its secondary key (ensuring that adjacent entries with + // the same pos value remain in the same order) + glyfLen = 0; // make gcc happy + if (unsortedLoca) { + qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca), + &cmpTrueTypeLocaOffset); + for (i = 0; i < nGlyphs; ++i) { + locaTable[i].len = locaTable[i+1].origOffset - locaTable[i].origOffset; + } + locaTable[nGlyphs].len = 0; + qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca), + &cmpTrueTypeLocaIdx); + pos = 0; + for (i = 0; i <= nGlyphs; ++i) { + locaTable[i].newOffset = pos; + pos += locaTable[i].len; + if (pos & 3) { + pos += 4 - (pos & 3); + } + } + glyfLen = pos; + } + + // compute checksums for the loca and glyf tables + locaChecksum = glyfChecksum = 0; + if (unsortedLoca) { + if (locaFmt) { + for (j = 0; j <= nGlyphs; ++j) { + locaChecksum += locaTable[j].newOffset; + } + } else { + for (j = 0; j <= nGlyphs; j += 2) { + locaChecksum += locaTable[j].newOffset << 16; + if (j + 1 <= nGlyphs) { + locaChecksum += locaTable[j+1].newOffset; + } + } + } + pos = tables[seekTable("glyf")].offset; + for (j = 0; j < nGlyphs; ++j) { + n = locaTable[j].len; + if (n > 0) { + k = locaTable[j].origOffset; + if (checkRegion(pos + k, n)) { + glyfChecksum += computeTableChecksum(file + pos + k, n); + } + } + } + } + + // construct the new name table + if (name) { + n = strlen(name); + newNameLen = (6 + 4*12 + 2 * (3*n + 7) + 3) & ~3; + newNameTab = (char *)gmalloc(newNameLen); + memset(newNameTab, 0, newNameLen); + newNameTab[0] = 0; // format selector + newNameTab[1] = 0; + newNameTab[2] = 0; // number of name records + newNameTab[3] = 4; + newNameTab[4] = 0; // offset to start of string storage + newNameTab[5] = 6 + 4*12; + next = 0; + for (i = 0; i < 4; ++i) { + newNameTab[6 + i*12 + 0] = 0; // platform ID = Microsoft + newNameTab[6 + i*12 + 1] = 3; + newNameTab[6 + i*12 + 2] = 0; // encoding ID = Unicode + newNameTab[6 + i*12 + 3] = 1; + newNameTab[6 + i*12 + 4] = 0x04; // language ID = American English + newNameTab[6 + i*12 + 5] = 0x09; + newNameTab[6 + i*12 + 6] = 0; // name ID + newNameTab[6 + i*12 + 7] = i + 1; + newNameTab[6 + i*12 + 8] = i+1 == 2 ? 0 : ((2*n) >> 8); // string length + newNameTab[6 + i*12 + 9] = i+1 == 2 ? 14 : ((2*n) & 0xff); + newNameTab[6 + i*12 + 10] = next >> 8; // string offset + newNameTab[6 + i*12 + 11] = next & 0xff; + if (i+1 == 2) { + memcpy(newNameTab + 6 + 4*12 + next, "\0R\0e\0g\0u\0l\0a\0r", 14); + next += 14; + } else { + for (j = 0; j < n; ++j) { + newNameTab[6 + 4*12 + next + 2*j] = 0; + newNameTab[6 + 4*12 + next + 2*j + 1] = name[j]; + } + next += 2*n; + } + } + } else { + newNameLen = 0; + newNameTab = NULL; + } + + // construct the new cmap table + if (codeToGID) { + newCmapLen = 44 + 256 * 2; + newCmapTab = (char *)gmalloc(newCmapLen); + newCmapTab[0] = 0; // table version number = 0 + newCmapTab[1] = 0; + newCmapTab[2] = 0; // number of encoding tables = 1 + newCmapTab[3] = 1; + newCmapTab[4] = 0; // platform ID = Microsoft + newCmapTab[5] = 3; + newCmapTab[6] = 0; // encoding ID = Unicode + newCmapTab[7] = 1; + newCmapTab[8] = 0; // offset of subtable + newCmapTab[9] = 0; + newCmapTab[10] = 0; + newCmapTab[11] = 12; + newCmapTab[12] = 0; // subtable format = 4 + newCmapTab[13] = 4; + newCmapTab[14] = 0x02; // subtable length + newCmapTab[15] = 0x20; + newCmapTab[16] = 0; // subtable version = 0 + newCmapTab[17] = 0; + newCmapTab[18] = 0; // segment count * 2 + newCmapTab[19] = 4; + newCmapTab[20] = 0; // 2 * 2 ^ floor(log2(segCount)) + newCmapTab[21] = 4; + newCmapTab[22] = 0; // floor(log2(segCount)) + newCmapTab[23] = 1; + newCmapTab[24] = 0; // 2*segCount - 2*2^floor(log2(segCount)) + newCmapTab[25] = 0; + newCmapTab[26] = 0x00; // endCount[0] + newCmapTab[27] = (char)0xff; + newCmapTab[28] = (char)0xff; // endCount[1] + newCmapTab[29] = (char)0xff; + newCmapTab[30] = 0; // reserved + newCmapTab[31] = 0; + newCmapTab[32] = 0x00; // startCount[0] + newCmapTab[33] = 0x00; + newCmapTab[34] = (char)0xff; // startCount[1] + newCmapTab[35] = (char)0xff; + newCmapTab[36] = 0; // idDelta[0] + newCmapTab[37] = 0; + newCmapTab[38] = 0; // idDelta[1] + newCmapTab[39] = 1; + newCmapTab[40] = 0; // idRangeOffset[0] + newCmapTab[41] = 4; + newCmapTab[42] = 0; // idRangeOffset[1] + newCmapTab[43] = 0; + for (i = 0; i < 256; ++i) { + newCmapTab[44 + 2*i] = codeToGID[i] >> 8; + newCmapTab[44 + 2*i + 1] = codeToGID[i] & 0xff; + } + } else { + newCmapLen = 0; + newCmapTab = NULL; + } + + // construct the new table directory: + // - keep all original tables with non-zero length + // - fix the cmap table's length, if necessary + // - add missing tables + // - sort the table by tag + // - compute new table positions, including 4-byte alignment + // - (re)compute table checksums + nNewTables = nTables - nZeroLengthTables + + (missingCmap ? 1 : 0) + (missingName ? 1 : 0) + + (missingPost ? 1 : 0); + newTables = (TrueTypeTable *)gmallocn(nNewTables, sizeof(TrueTypeTable)); + j = 0; + for (i = 0; i < nTables; ++i) { + if (tables[i].len > 0) { + newTables[j] = tables[i]; + newTables[j].origOffset = tables[i].offset; + if (checkRegion(tables[i].offset, newTables[i].len)) { + newTables[j].checksum = + computeTableChecksum(file + tables[i].offset, tables[i].len); + if (tables[i].tag == headTag) { + // don't include the file checksum + newTables[j].checksum -= getU32BE(tables[i].offset + 8, &ok); + } + } + if (newTables[j].tag == cmapTag && codeToGID) { + newTables[j].len = newCmapLen; + newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab, + newCmapLen); + } else if (newTables[j].tag == cmapTag && badCmapLen) { + newTables[j].len = cmapLen; + } else if (newTables[j].tag == locaTag && unsortedLoca) { + newTables[j].len = (nGlyphs + 1) * (locaFmt ? 4 : 2); + newTables[j].checksum = locaChecksum; + } else if (newTables[j].tag == glyfTag && unsortedLoca) { + newTables[j].len = glyfLen; + newTables[j].checksum = glyfChecksum; + } else if (newTables[j].tag == nameTag && name) { + newTables[j].len = newNameLen; + newTables[j].checksum = computeTableChecksum((Guchar *)newNameTab, + newNameLen); + } + ++j; + } + } + if (missingCmap) { + newTables[j].tag = cmapTag; + if (codeToGID) { + newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab, + newCmapLen); + newTables[j].len = newCmapLen; + } else { + newTables[j].checksum = computeTableChecksum((Guchar *)cmapTab, + sizeof(cmapTab)); + newTables[j].len = sizeof(cmapTab); + } + ++j; + } + if (missingName) { + newTables[j].tag = nameTag; + if (name) { + newTables[j].checksum = computeTableChecksum((Guchar *)newNameTab, + newNameLen); + newTables[j].len = newNameLen; + } else { + newTables[j].checksum = computeTableChecksum((Guchar *)nameTab, + sizeof(nameTab)); + newTables[j].len = sizeof(nameTab); + } + ++j; + } + if (missingPost) { + newTables[j].tag = postTag; + newTables[j].checksum = computeTableChecksum((Guchar *)postTab, + sizeof(postTab)); + newTables[j].len = sizeof(postTab); + ++j; + } + qsort(newTables, nNewTables, sizeof(TrueTypeTable), + &cmpTrueTypeTableTag); + pos = 12 + nNewTables * 16; + for (i = 0; i < nNewTables; ++i) { + newTables[i].offset = pos; + pos += newTables[i].len; + if (pos & 3) { + pos += 4 - (pos & 3); + } + } + + // write the table directory + tableDir = (char *)gmalloc(12 + nNewTables * 16); + tableDir[0] = 0x00; // sfnt version + tableDir[1] = 0x01; + tableDir[2] = 0x00; + tableDir[3] = 0x00; + tableDir[4] = (char)((nNewTables >> 8) & 0xff); // numTables + tableDir[5] = (char)(nNewTables & 0xff); + for (i = -1, t = (Guint)nNewTables; t; ++i, t >>= 1) ; + t = 1 << (4 + i); + tableDir[6] = (char)((t >> 8) & 0xff); // searchRange + tableDir[7] = (char)(t & 0xff); + tableDir[8] = (char)((i >> 8) & 0xff); // entrySelector + tableDir[9] = (char)(i & 0xff); + t = nNewTables * 16 - t; + tableDir[10] = (char)((t >> 8) & 0xff); // rangeShift + tableDir[11] = (char)(t & 0xff); + pos = 12; + for (i = 0; i < nNewTables; ++i) { + tableDir[pos ] = (char)(newTables[i].tag >> 24); + tableDir[pos+ 1] = (char)(newTables[i].tag >> 16); + tableDir[pos+ 2] = (char)(newTables[i].tag >> 8); + tableDir[pos+ 3] = (char) newTables[i].tag; + tableDir[pos+ 4] = (char)(newTables[i].checksum >> 24); + tableDir[pos+ 5] = (char)(newTables[i].checksum >> 16); + tableDir[pos+ 6] = (char)(newTables[i].checksum >> 8); + tableDir[pos+ 7] = (char) newTables[i].checksum; + tableDir[pos+ 8] = (char)(newTables[i].offset >> 24); + tableDir[pos+ 9] = (char)(newTables[i].offset >> 16); + tableDir[pos+10] = (char)(newTables[i].offset >> 8); + tableDir[pos+11] = (char) newTables[i].offset; + tableDir[pos+12] = (char)(newTables[i].len >> 24); + tableDir[pos+13] = (char)(newTables[i].len >> 16); + tableDir[pos+14] = (char)(newTables[i].len >> 8); + tableDir[pos+15] = (char) newTables[i].len; + pos += 16; + } + (*outputFunc)(outputStream, tableDir, 12 + nNewTables * 16); + + // compute the file checksum + fileChecksum = computeTableChecksum((Guchar *)tableDir, + 12 + nNewTables * 16); + for (i = 0; i < nNewTables; ++i) { + fileChecksum += newTables[i].checksum; + } + fileChecksum = 0xb1b0afba - fileChecksum; + + // write the tables + for (i = 0; i < nNewTables; ++i) { + if (newTables[i].tag == headTag) { + if (checkRegion(newTables[i].origOffset, newTables[i].len)) { + (*outputFunc)(outputStream, (char *)file + newTables[i].origOffset, 8); + checksumBuf[0] = fileChecksum >> 24; + checksumBuf[1] = fileChecksum >> 16; + checksumBuf[2] = fileChecksum >> 8; + checksumBuf[3] = fileChecksum; + (*outputFunc)(outputStream, checksumBuf, 4); + (*outputFunc)(outputStream, + (char *)file + newTables[i].origOffset + 12, + newTables[i].len - 12); + } else { + for (j = 0; j < newTables[i].len; ++j) { + (*outputFunc)(outputStream, "\0", 1); + } + } + } else if (newTables[i].tag == cmapTag && codeToGID) { + (*outputFunc)(outputStream, newCmapTab, newTables[i].len); + } else if (newTables[i].tag == cmapTag && missingCmap) { + (*outputFunc)(outputStream, cmapTab, newTables[i].len); + } else if (newTables[i].tag == nameTag && name) { + (*outputFunc)(outputStream, newNameTab, newTables[i].len); + } else if (newTables[i].tag == nameTag && missingName) { + (*outputFunc)(outputStream, nameTab, newTables[i].len); + } else if (newTables[i].tag == postTag && missingPost) { + (*outputFunc)(outputStream, postTab, newTables[i].len); + } else if (newTables[i].tag == locaTag && unsortedLoca) { + for (j = 0; j <= nGlyphs; ++j) { + if (locaFmt) { + locaBuf[0] = (char)(locaTable[j].newOffset >> 24); + locaBuf[1] = (char)(locaTable[j].newOffset >> 16); + locaBuf[2] = (char)(locaTable[j].newOffset >> 8); + locaBuf[3] = (char) locaTable[j].newOffset; + (*outputFunc)(outputStream, locaBuf, 4); + } else { + locaBuf[0] = (char)(locaTable[j].newOffset >> 9); + locaBuf[1] = (char)(locaTable[j].newOffset >> 1); + (*outputFunc)(outputStream, locaBuf, 2); + } + } + } else if (newTables[i].tag == glyfTag && unsortedLoca) { + pos = tables[seekTable("glyf")].offset; + for (j = 0; j < nGlyphs; ++j) { + n = locaTable[j].len; + if (n > 0) { + k = locaTable[j].origOffset; + if (checkRegion(pos + k, n)) { + (*outputFunc)(outputStream, (char *)file + pos + k, n); + } else { + for (k = 0; k < n; ++k) { + (*outputFunc)(outputStream, "\0", 1); + } + } + if ((k = locaTable[j].len & 3)) { + (*outputFunc)(outputStream, "\0\0\0\0", 4 - k); + } + } + } + } else { + if (checkRegion(newTables[i].origOffset, newTables[i].len)) { + (*outputFunc)(outputStream, (char *)file + newTables[i].origOffset, + newTables[i].len); + } else { + for (j = 0; j < newTables[i].len; ++j) { + (*outputFunc)(outputStream, "\0", 1); + } + } + } + if (newTables[i].len & 3) { + (*outputFunc)(outputStream, "\0\0\0", 4 - (newTables[i].len & 3)); + } + } + + gfree(newCmapTab); + gfree(newNameTab); + gfree(tableDir); + gfree(newTables); + done1: + gfree(locaTable); +} + +void FoFiTrueType::cvtEncoding(char **encoding, + FoFiOutputFunc outputFunc, + void *outputStream) { + char *name; + char buf[64]; + int i; + + (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); + if (encoding) { + for (i = 0; i < 256; ++i) { + if (!(name = encoding[i])) { + name = ".notdef"; + } + sprintf(buf, "dup %d /", i); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, name, strlen(name)); + (*outputFunc)(outputStream, " put\n", 5); + } + } else { + for (i = 0; i < 256; ++i) { + sprintf(buf, "dup %d /c%02x put\n", i, i); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + } + (*outputFunc)(outputStream, "readonly def\n", 13); +} + +void FoFiTrueType::cvtCharStrings(char **encoding, + Gushort *codeToGID, + FoFiOutputFunc outputFunc, + void *outputStream) { + char *name; + char buf[64], buf2[16]; + int i, k; + + // always define '.notdef' + (*outputFunc)(outputStream, "/CharStrings 256 dict dup begin\n", 32); + (*outputFunc)(outputStream, "/.notdef 0 def\n", 15); + + // if there's no 'cmap' table, punt + if (nCmaps == 0) { + goto err; + } + + // map char name to glyph index: + // 1. use encoding to map name to char code + // 2. use codeToGID to map char code to glyph index + // N.B. We do this in reverse order because font subsets can have + // weird encodings that use the same character name twice, and + // the first definition is probably the one we want. + k = 0; // make gcc happy + for (i = 255; i >= 0; --i) { + if (encoding) { + name = encoding[i]; + } else { + sprintf(buf2, "c%02x", i); + name = buf2; + } + if (name && strcmp(name, ".notdef")) { + k = codeToGID[i]; + // note: Distiller (maybe Adobe's PS interpreter in general) + // doesn't like TrueType fonts that have CharStrings entries + // which point to nonexistent glyphs, hence the (k < nGlyphs) + // test + if (k > 0 && k < nGlyphs) { + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, name, strlen(name)); + sprintf(buf, " %d def\n", k); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + } + } + + err: + (*outputFunc)(outputStream, "end readonly def\n", 17); +} + +void FoFiTrueType::cvtSfnts(FoFiOutputFunc outputFunc, + void *outputStream, GooString *name, + GBool needVerticalMetrics) { + Guchar headData[54]; + TrueTypeLoca *locaTable; + Guchar *locaData; + TrueTypeTable newTables[nT42Tables]; + Guchar tableDir[12 + nT42Tables*16]; + GBool ok; + Guint checksum; + int nNewTables; + int length, pos, glyfPos, i, j, k; + Guchar vheaTab[36] = { + 0, 1, 0, 0, // table version number + 0, 0, // ascent + 0, 0, // descent + 0, 0, // reserved + 0, 0, // max advance height + 0, 0, // min top side bearing + 0, 0, // min bottom side bearing + 0, 0, // y max extent + 0, 0, // caret slope rise + 0, 1, // caret slope run + 0, 0, // caret offset + 0, 0, // reserved + 0, 0, // reserved + 0, 0, // reserved + 0, 0, // reserved + 0, 0, // metric data format + 0, 1 // number of advance heights in vmtx table + }; + Guchar *vmtxTab; + GBool needVhea, needVmtx; + int advance; + + // construct the 'head' table, zero out the font checksum + i = seekTable("head"); + pos = tables[i].offset; + if (!checkRegion(pos, 54)) { + return; + } + memcpy(headData, file + pos, 54); + headData[8] = headData[9] = headData[10] = headData[11] = (Guchar)0; + + // read the original 'loca' table, pad entries out to 4 bytes, and + // sort it into proper order -- some (non-compliant) fonts have + // out-of-order loca tables; in order to correctly handle the case + // where (compliant) fonts have empty entries in the middle of the + // table, cmpTrueTypeLocaPos uses offset as its primary sort key, + // and idx as its secondary key (ensuring that adjacent entries with + // the same pos value remain in the same order) + locaTable = (TrueTypeLoca *)gmallocn(nGlyphs + 1, sizeof(TrueTypeLoca)); + i = seekTable("loca"); + pos = tables[i].offset; + ok = gTrue; + for (i = 0; i <= nGlyphs; ++i) { + locaTable[i].idx = i; + if (locaFmt) { + locaTable[i].origOffset = (int)getU32BE(pos + i*4, &ok); + } else { + locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok); + } + } + qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca), + &cmpTrueTypeLocaOffset); + for (i = 0; i < nGlyphs; ++i) { + locaTable[i].len = locaTable[i+1].origOffset - locaTable[i].origOffset; + } + locaTable[nGlyphs].len = 0; + qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca), + &cmpTrueTypeLocaIdx); + pos = 0; + for (i = 0; i <= nGlyphs; ++i) { + locaTable[i].newOffset = pos; + pos += locaTable[i].len; + if (pos & 3) { + pos += 4 - (pos & 3); + } + } + + // construct the new 'loca' table + locaData = (Guchar *)gmallocn(nGlyphs + 1, (locaFmt ? 4 : 2)); + for (i = 0; i <= nGlyphs; ++i) { + pos = locaTable[i].newOffset; + if (locaFmt) { + locaData[4*i ] = (Guchar)(pos >> 24); + locaData[4*i+1] = (Guchar)(pos >> 16); + locaData[4*i+2] = (Guchar)(pos >> 8); + locaData[4*i+3] = (Guchar) pos; + } else { + locaData[2*i ] = (Guchar)(pos >> 9); + locaData[2*i+1] = (Guchar)(pos >> 1); + } + } + + // count the number of tables + nNewTables = 0; + for (i = 0; i < nT42Tables; ++i) { + if (t42Tables[i].required || + seekTable(t42Tables[i].tag) >= 0) { + ++nNewTables; + } + } + vmtxTab = NULL; // make gcc happy + advance = 0; // make gcc happy + if (needVerticalMetrics) { + needVhea = seekTable("vhea") < 0; + needVmtx = seekTable("vmtx") < 0; + if (needVhea || needVmtx) { + i = seekTable("head"); + advance = getU16BE(tables[i].offset + 18, &ok); // units per em + if (needVhea) { + ++nNewTables; + } + if (needVmtx) { + ++nNewTables; + } + } + } + + // construct the new table headers, including table checksums + // (pad each table out to a multiple of 4 bytes) + pos = 12 + nNewTables*16; + k = 0; + for (i = 0; i < nT42Tables; ++i) { + length = -1; + checksum = 0; // make gcc happy + if (i == t42HeadTable) { + length = 54; + checksum = computeTableChecksum(headData, 54); + } else if (i == t42LocaTable) { + length = (nGlyphs + 1) * (locaFmt ? 4 : 2); + checksum = computeTableChecksum(locaData, length); + } else if (i == t42GlyfTable) { + length = 0; + checksum = 0; + glyfPos = tables[seekTable("glyf")].offset; + for (j = 0; j < nGlyphs; ++j) { + length += locaTable[j].len; + if (length & 3) { + length += 4 - (length & 3); + } + if (checkRegion(glyfPos + locaTable[j].origOffset, locaTable[j].len)) { + checksum += + computeTableChecksum(file + glyfPos + locaTable[j].origOffset, + locaTable[j].len); + } + } + } else { + if ((j = seekTable(t42Tables[i].tag)) >= 0) { + length = tables[j].len; + if (checkRegion(tables[j].offset, length)) { + checksum = computeTableChecksum(file + tables[j].offset, length); + } + } else if (needVerticalMetrics && i == t42VheaTable) { + vheaTab[10] = advance / 256; // max advance height + vheaTab[11] = advance % 256; + length = sizeof(vheaTab); + checksum = computeTableChecksum(vheaTab, length); + } else if (needVerticalMetrics && i == t42VmtxTable) { + length = 4 + (nGlyphs - 1) * 4; + vmtxTab = (Guchar *)gmalloc(length); + vmtxTab[0] = advance / 256; + vmtxTab[1] = advance % 256; + for (j = 2; j < length; j += 2) { + vmtxTab[j] = 0; + vmtxTab[j+1] = 0; + } + checksum = computeTableChecksum(vmtxTab, length); + } else if (t42Tables[i].required) { + //~ error(-1, "Embedded TrueType font is missing a required table ('%s')", + //~ t42Tables[i].tag); + length = 0; + checksum = 0; + } + } + if (length >= 0) { + newTables[k].tag = ((t42Tables[i].tag[0] & 0xff) << 24) | + ((t42Tables[i].tag[1] & 0xff) << 16) | + ((t42Tables[i].tag[2] & 0xff) << 8) | + (t42Tables[i].tag[3] & 0xff); + newTables[k].checksum = checksum; + newTables[k].offset = pos; + newTables[k].len = length; + pos += length; + if (pos & 3) { + pos += 4 - (length & 3); + } + ++k; + } + } + + // construct the table directory + tableDir[0] = 0x00; // sfnt version + tableDir[1] = 0x01; + tableDir[2] = 0x00; + tableDir[3] = 0x00; + tableDir[4] = 0; // numTables + tableDir[5] = nNewTables; + tableDir[6] = 0; // searchRange + tableDir[7] = (Guchar)128; + tableDir[8] = 0; // entrySelector + tableDir[9] = 3; + tableDir[10] = 0; // rangeShift + tableDir[11] = (Guchar)(16 * nNewTables - 128); + pos = 12; + for (i = 0; i < nNewTables; ++i) { + tableDir[pos ] = (Guchar)(newTables[i].tag >> 24); + tableDir[pos+ 1] = (Guchar)(newTables[i].tag >> 16); + tableDir[pos+ 2] = (Guchar)(newTables[i].tag >> 8); + tableDir[pos+ 3] = (Guchar) newTables[i].tag; + tableDir[pos+ 4] = (Guchar)(newTables[i].checksum >> 24); + tableDir[pos+ 5] = (Guchar)(newTables[i].checksum >> 16); + tableDir[pos+ 6] = (Guchar)(newTables[i].checksum >> 8); + tableDir[pos+ 7] = (Guchar) newTables[i].checksum; + tableDir[pos+ 8] = (Guchar)(newTables[i].offset >> 24); + tableDir[pos+ 9] = (Guchar)(newTables[i].offset >> 16); + tableDir[pos+10] = (Guchar)(newTables[i].offset >> 8); + tableDir[pos+11] = (Guchar) newTables[i].offset; + tableDir[pos+12] = (Guchar)(newTables[i].len >> 24); + tableDir[pos+13] = (Guchar)(newTables[i].len >> 16); + tableDir[pos+14] = (Guchar)(newTables[i].len >> 8); + tableDir[pos+15] = (Guchar) newTables[i].len; + pos += 16; + } + + // compute the font checksum and store it in the head table + checksum = computeTableChecksum(tableDir, 12 + nNewTables*16); + for (i = 0; i < nNewTables; ++i) { + checksum += newTables[i].checksum; + } + checksum = 0xb1b0afba - checksum; // because the TrueType spec says so + headData[ 8] = (Guchar)(checksum >> 24); + headData[ 9] = (Guchar)(checksum >> 16); + headData[10] = (Guchar)(checksum >> 8); + headData[11] = (Guchar) checksum; + + // start the sfnts array + if (name) { + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, name->getCString(), name->getLength()); + (*outputFunc)(outputStream, " [\n", 3); + } else { + (*outputFunc)(outputStream, "/sfnts [\n", 9); + } + + // write the table directory + dumpString(tableDir, 12 + nNewTables*16, outputFunc, outputStream); + + // write the tables + for (i = 0; i < nNewTables; ++i) { + if (i == t42HeadTable) { + dumpString(headData, 54, outputFunc, outputStream); + } else if (i == t42LocaTable) { + length = (nGlyphs + 1) * (locaFmt ? 4 : 2); + dumpString(locaData, length, outputFunc, outputStream); + } else if (i == t42GlyfTable) { + glyfPos = tables[seekTable("glyf")].offset; + for (j = 0; j < nGlyphs; ++j) { + if (locaTable[j].len > 0 && + checkRegion(glyfPos + locaTable[j].origOffset, locaTable[j].len)) { + dumpString(file + glyfPos + locaTable[j].origOffset, + locaTable[j].len, outputFunc, outputStream); + } + } + } else { + // length == 0 means the table is missing and the error was + // already reported during the construction of the table + // headers + if ((length = newTables[i].len) > 0) { + if ((j = seekTable(t42Tables[i].tag)) >= 0 && + checkRegion(tables[j].offset, tables[j].len)) { + dumpString(file + tables[j].offset, tables[j].len, + outputFunc, outputStream); + } else if (needVerticalMetrics && i == t42VheaTable) { + dumpString(vheaTab, length, outputFunc, outputStream); + } else if (needVerticalMetrics && i == t42VmtxTable) { + dumpString(vmtxTab, length, outputFunc, outputStream); + gfree(vmtxTab); + } + } + } + } + + // end the sfnts array + (*outputFunc)(outputStream, "] def\n", 6); + + gfree(locaData); + gfree(locaTable); +} + +void FoFiTrueType::dumpString(Guchar *s, int length, + FoFiOutputFunc outputFunc, + void *outputStream) { + char buf[64]; + int pad, i, j; + + (*outputFunc)(outputStream, "<", 1); + for (i = 0; i < length; i += 32) { + for (j = 0; j < 32 && i+j < length; ++j) { + sprintf(buf, "%02X", s[i+j] & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (i % (65536 - 32) == 65536 - 64) { + (*outputFunc)(outputStream, ">\n<", 3); + } else if (i+32 < length) { + (*outputFunc)(outputStream, "\n", 1); + } + } + if (length & 3) { + pad = 4 - (length & 3); + for (i = 0; i < pad; ++i) { + (*outputFunc)(outputStream, "00", 2); + } + } + // add an extra zero byte because the Adobe Type 42 spec says so + (*outputFunc)(outputStream, "00>\n", 4); +} + +Guint FoFiTrueType::computeTableChecksum(Guchar *data, int length) { + Guint checksum, word; + int i; + + checksum = 0; + for (i = 0; i+3 < length; i += 4) { + word = ((data[i ] & 0xff) << 24) + + ((data[i+1] & 0xff) << 16) + + ((data[i+2] & 0xff) << 8) + + (data[i+3] & 0xff); + checksum += word; + } + if (length & 3) { + word = 0; + i = length & ~3; + switch (length & 3) { + case 3: + word |= (data[i+2] & 0xff) << 8; + case 2: + word |= (data[i+1] & 0xff) << 16; + case 1: + word |= (data[i ] & 0xff) << 24; + break; + } + checksum += word; + } + return checksum; +} + +#define toTag(a,b,c,d) (((unsigned int)(a)<<24) | ((unsigned int)(b)<<16) | ((unsigned int)(c)<<8) | (d)) + +void FoFiTrueType::parse() { + Guint topTag; + int pos, i, j; + unsigned int head; + + parsedOk = gTrue; + + // look for a collection (TTC) + topTag = getU32BE(0, &parsedOk); + if (!parsedOk) { + return; + } + if (topTag == ttcfTag) { + pos = getU32BE(12, &parsedOk); + if (!parsedOk) { + return; + } + } else { + pos = 0; + } + + // read the table directory + head = getU32BE(pos, &parsedOk); + if (! parsedOk) + return; + if (head == toTag('t','t','c','f')) { + /* TTC font */ + int dircount; + + dircount = getU32BE(8, &parsedOk); + if (!parsedOk) + return; + if (! dircount) { + parsedOk = gFalse; + return; + } + + if (faceIndex >= dircount) + faceIndex = 0; + pos = getU32BE(12 + faceIndex * 4, &parsedOk); + if (! parsedOk) + return; + } + + pos += 4; + nTables = getU16BE(pos, &parsedOk); + if (!parsedOk) { + return; + } + + pos += 8; + tables = (TrueTypeTable *)gmallocn(nTables, sizeof(TrueTypeTable)); + for (i = 0; i < nTables; ++i) { + tables[i].tag = getU32BE(pos, &parsedOk); + tables[i].checksum = getU32BE(pos + 4, &parsedOk); + tables[i].offset = (int)getU32BE(pos + 8, &parsedOk); + tables[i].len = (int)getU32BE(pos + 12, &parsedOk); + if (tables[i].offset + tables[i].len < tables[i].offset || + tables[i].offset + tables[i].len > len) { + parsedOk = gFalse; + } + pos += 16; + } + if (!parsedOk) { + return; + } + + // check for tables that are required by both the TrueType spec and + // the Type 42 spec + if (seekTable("head") < 0 || + seekTable("hhea") < 0 || + seekTable("loca") < 0 || + seekTable("maxp") < 0 || + seekTable("glyf") < 0 || + seekTable("hmtx") < 0) { + parsedOk = gFalse; + return; + } + + // read the cmaps + if ((i = seekTable("cmap")) >= 0) { + pos = tables[i].offset + 2; + nCmaps = getU16BE(pos, &parsedOk); + pos += 2; + if (!parsedOk) { + return; + } + cmaps = (TrueTypeCmap *)gmallocn(nCmaps, sizeof(TrueTypeCmap)); + for (j = 0; j < nCmaps; ++j) { + cmaps[j].platform = getU16BE(pos, &parsedOk); + cmaps[j].encoding = getU16BE(pos + 2, &parsedOk); + cmaps[j].offset = tables[i].offset + getU32BE(pos + 4, &parsedOk); + pos += 8; + cmaps[j].fmt = getU16BE(cmaps[j].offset, &parsedOk); + cmaps[j].len = getU16BE(cmaps[j].offset + 2, &parsedOk); + } + if (!parsedOk) { + return; + } + } else { + nCmaps = 0; + } + + // get the number of glyphs from the maxp table + i = seekTable("maxp"); + nGlyphs = getU16BE(tables[i].offset + 4, &parsedOk); + if (!parsedOk) { + return; + } + + // get the bbox and loca table format from the head table + i = seekTable("head"); + bbox[0] = getS16BE(tables[i].offset + 36, &parsedOk); + bbox[1] = getS16BE(tables[i].offset + 38, &parsedOk); + bbox[2] = getS16BE(tables[i].offset + 40, &parsedOk); + bbox[3] = getS16BE(tables[i].offset + 42, &parsedOk); + locaFmt = getS16BE(tables[i].offset + 50, &parsedOk); + if (!parsedOk) { + return; + } + + // make sure the loca table is sane (correct length and entries are + // in bounds) + i = seekTable("loca"); + if (tables[i].len < (nGlyphs + 1) * (locaFmt ? 4 : 2)) { + parsedOk = gFalse; + return; + } + for (j = 0; j <= nGlyphs; ++j) { + if (locaFmt) { + pos = (int)getU32BE(tables[i].offset + j*4, &parsedOk); + } else { + pos = getU16BE(tables[i].offset + j*2, &parsedOk); + } + if (pos < 0 || pos > len) { + parsedOk = gFalse; + } + } + if (!parsedOk) { + return; + } + + // read the post table + readPostTable(); +} + +void FoFiTrueType::readPostTable() { + GooString *name; + int tablePos, postFmt, stringIdx, stringPos; + GBool ok; + int i, j, n, m; + + ok = gTrue; + if ((i = seekTable("post")) < 0) { + return; + } + tablePos = tables[i].offset; + postFmt = getU32BE(tablePos, &ok); + if (!ok) { + goto err; + } + if (postFmt == 0x00010000) { + nameToGID = new GooHash(gTrue); + for (i = 0; i < 258; ++i) { + nameToGID->add(new GooString(macGlyphNames[i]), i); + } + } else if (postFmt == 0x00020000) { + nameToGID = new GooHash(gTrue); + n = getU16BE(tablePos + 32, &ok); + if (!ok) { + goto err; + } + if (n > nGlyphs) { + n = nGlyphs; + } + stringIdx = 0; + stringPos = tablePos + 34 + 2*n; + for (i = 0; i < n; ++i) { + j = getU16BE(tablePos + 34 + 2*i, &ok); + if (j < 258) { + nameToGID->removeInt(macGlyphNames[j]); + nameToGID->add(new GooString(macGlyphNames[j]), i); + } else { + j -= 258; + if (j != stringIdx) { + for (stringIdx = 0, stringPos = tablePos + 34 + 2*n; + stringIdx < j; + ++stringIdx, stringPos += 1 + getU8(stringPos, &ok)) ; + if (!ok) { + goto err; + } + } + m = getU8(stringPos, &ok); + if (!ok || !checkRegion(stringPos + 1, m)) { + goto err; + } + name = new GooString((char *)&file[stringPos + 1], m); + nameToGID->removeInt(name); + nameToGID->add(name, i); + ++stringIdx; + stringPos += 1 + m; + } + } + } else if (postFmt == 0x00028000) { + nameToGID = new GooHash(gTrue); + for (i = 0; i < nGlyphs; ++i) { + j = getU8(tablePos + 32 + i, &ok); + if (!ok) { + goto err; + } + if (j < 258) { + nameToGID->removeInt(macGlyphNames[j]); + nameToGID->add(new GooString(macGlyphNames[j]), i); + } + } + } + + return; + + err: + if (nameToGID) { + delete nameToGID; + nameToGID = NULL; + } +} + +int FoFiTrueType::seekTable(char *tag) { + Guint tagI; + int i; + + tagI = ((tag[0] & 0xff) << 24) | + ((tag[1] & 0xff) << 16) | + ((tag[2] & 0xff) << 8) | + (tag[3] & 0xff); + for (i = 0; i < nTables; ++i) { + if (tables[i].tag == tagI) { + return i; + } + } + return -1; +} diff --git a/rosapps/smartpdf/poppler/fofi/FoFiTrueType.h b/rosapps/smartpdf/poppler/fofi/FoFiTrueType.h new file mode 100644 index 00000000000..c81e3b7ae7f --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiTrueType.h @@ -0,0 +1,139 @@ +//======================================================================== +// +// FoFiTrueType.h +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FOFITRUETYPE_H +#define FOFITRUETYPE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "FoFiBase.h" + +class GooString; +class GooHash; +struct TrueTypeTable; +struct TrueTypeCmap; + +//------------------------------------------------------------------------ +// FoFiTrueType +//------------------------------------------------------------------------ + +class FoFiTrueType: public FoFiBase { +public: + + // Create a FoFiTrueType object from a memory buffer. + static FoFiTrueType *make(char *fileA, int lenA, int faceIndexA=0); + + // Create a FoFiTrueType object from a file on disk. + static FoFiTrueType *load(char *fileName, int faceIndexA=0); + + FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA=0); + virtual ~FoFiTrueType(); + + // Return the number of cmaps defined by this font. + int getNumCmaps(); + + // Return the platform ID of the th cmap. + int getCmapPlatform(int i); + + // Return the encoding ID of the th cmap. + int getCmapEncoding(int i); + + // Return the index of the cmap for , . Returns + // -1 if there is no corresponding cmap. + int findCmap(int platform, int encoding); + + // Return the GID corresponding to according to the th cmap. + Gushort mapCodeToGID(int i, int c); + + // Returns the GID corresponding to according to the post + // table. Returns 0 if there is no mapping for or if the + // font does not have a post table. + int mapNameToGID(char *name); + + // Returns the least restrictive embedding licensing right (as + // defined by the TrueType spec): + // * 4: OS/2 table is missing or invalid + // * 3: installable embedding + // * 2: editable embedding + // * 1: preview & print embedding + // * 0: restricted license embedding + int getEmbeddingRights(); + + // Convert to a Type 42 font, suitable for embedding in a PostScript + // file. will be used as the PostScript font name (so we + // don't need to depend on the 'name' table in the font). The + // array specifies the mapping from char codes to names. + // If is NULL, the encoding is unknown or undefined. The + // array specifies the mapping from char codes to GIDs. + void convertToType42(char *psName, char **encoding, + Gushort *codeToGID, + FoFiOutputFunc outputFunc, void *outputStream); + + // Convert to a Type 2 CIDFont, suitable for embedding in a + // PostScript file. will be used as the PostScript font + // name (so we don't need to depend on the 'name' table in the + // font). The array maps CIDs to GIDs; it has + // entries. + void convertToCIDType2(char *psName, Gushort *cidMap, int nCIDs, + GBool needVerticalMetrics, + FoFiOutputFunc outputFunc, void *outputStream); + + // Convert to a Type 0 (but non-CID) composite font, suitable for + // embedding in a PostScript file. will be used as the + // PostScript font name (so we don't need to depend on the 'name' + // table in the font). The array maps CIDs to GIDs; it has + // entries. + void convertToType0(char *psName, Gushort *cidMap, int nCIDs, + GBool needVerticalMetrics, + FoFiOutputFunc outputFunc, void *outputStream); + + // Write a clean TTF file, filling in missing tables and correcting + // various other errors. If is non-NULL, the font is renamed + // to . If is non-NULL, the font is re-encoded, + // using a Windows Unicode cmap. If is NULL and the font is + // complete and correct, it will be written unmodified. + void writeTTF(FoFiOutputFunc outputFunc, void *outputStream, + char *name = NULL, Gushort *codeToGID = NULL); + +private: + + void cvtEncoding(char **encoding, + FoFiOutputFunc outputFunc, + void *outputStream); + void cvtCharStrings(char **encoding, + Gushort *codeToGID, + FoFiOutputFunc outputFunc, + void *outputStream); + void cvtSfnts(FoFiOutputFunc outputFunc, + void *outputStream, GooString *name, + GBool needVerticalMetrics); + void dumpString(Guchar *s, int length, + FoFiOutputFunc outputFunc, + void *outputStream); + Guint computeTableChecksum(Guchar *data, int length); + void parse(); + void readPostTable(); + int seekTable(char *tag); + + TrueTypeTable *tables; + int nTables; + TrueTypeCmap *cmaps; + int nCmaps; + int nGlyphs; + int locaFmt; + int bbox[4]; + GooHash *nameToGID; + + GBool parsedOk; + int faceIndex; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/fofi/FoFiType1.cc b/rosapps/smartpdf/poppler/fofi/FoFiType1.cc new file mode 100644 index 00000000000..19753dc42af --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiType1.cc @@ -0,0 +1,207 @@ +//======================================================================== +// +// FoFiType1.cc +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "FoFiEncodings.h" +#include "FoFiType1.h" + +//------------------------------------------------------------------------ +// FoFiType1 +//------------------------------------------------------------------------ + +FoFiType1 *FoFiType1::make(char *fileA, int lenA) { + return new FoFiType1(fileA, lenA, gFalse); +} + +FoFiType1 *FoFiType1::load(char *fileName) { + char *fileA; + int lenA; + + if (!(fileA = FoFiBase::readFile(fileName, &lenA))) { + return NULL; + } + return new FoFiType1(fileA, lenA, gTrue); +} + +FoFiType1::FoFiType1(char *fileA, int lenA, GBool freeFileDataA): + FoFiBase(fileA, lenA, freeFileDataA) +{ + name = NULL; + encoding = NULL; + parsed = gFalse; +} + +FoFiType1::~FoFiType1() { + int i; + + if (name) { + gfree(name); + } + if (encoding && encoding != fofiType1StandardEncoding) { + for (i = 0; i < 256; ++i) { + gfree(encoding[i]); + } + gfree(encoding); + } +} + +char *FoFiType1::getName() { + if (!parsed) { + parse(); + } + return name; +} + +char **FoFiType1::getEncoding() { + if (!parsed) { + parse(); + } + return encoding; +} + +void FoFiType1::writeEncoded(char **newEncoding, + FoFiOutputFunc outputFunc, void *outputStream) { + char buf[512]; + char *line; + int i; + + // copy everything up to the encoding + for (line = (char *)file; + line && strncmp(line, "/Encoding", 9); + line = getNextLine(line)) ; + if (!line) { + // no encoding - just copy the whole font file + (*outputFunc)(outputStream, (char *)file, len); + return; + } + (*outputFunc)(outputStream, (char *)file, line - (char *)file); + + // write the new encoding + (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); + (*outputFunc)(outputStream, + "0 1 255 {1 index exch /.notdef put} for\n", 40); + for (i = 0; i < 256; ++i) { + if (newEncoding[i]) { + sprintf(buf, "dup %d /%s put\n", i, newEncoding[i]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + } + (*outputFunc)(outputStream, "readonly def\n", 13); + + // copy everything after the encoding + if (!strncmp(line, "/Encoding StandardEncoding def", 30)) { + line = getNextLine(line); + } else { + for (line = getNextLine(line); + line && strncmp(line, "readonly def", 12); + line = getNextLine(line)) ; + if (line) { + line = getNextLine(line); + } + } + if (line) { + (*outputFunc)(outputStream, line, ((char *)file + len) - line); + } +} + +char *FoFiType1::getNextLine(char *line) { + while (line < (char *)file + len && *line != '\x0a' && *line != '\x0d') { + ++line; + } + if (line < (char *)file + len && *line == '\x0d') { + ++line; + } + if (line < (char *)file + len && *line == '\x0a') { + ++line; + } + if (line >= (char *)file + len) { + return NULL; + } + return line; +} + +void FoFiType1::parse() { + char *line, *line1, *p, *p2; + char buf[256]; + char c; + int n, code, i, j; + + for (i = 1, line = (char *)file; + i <= 100 && line && (!name || !encoding); + ++i) { + + // get font name + if (!name && !strncmp(line, "/FontName", 9)) { + strncpy(buf, line, 255); + buf[255] = '\0'; + if ((p = strchr(buf+9, '/')) && + (p = strtok(p+1, " \t\n\r"))) { + name = copyString(p); + } + line = getNextLine(line); + + // get encoding + } else if (!encoding && + !strncmp(line, "/Encoding StandardEncoding def", 30)) { + encoding = fofiType1StandardEncoding; + } else if (!encoding && + !strncmp(line, "/Encoding 256 array", 19)) { + encoding = (char **)gmallocn(256, sizeof(char *)); + for (j = 0; j < 256; ++j) { + encoding[j] = NULL; + } + for (j = 0, line = getNextLine(line); + j < 300 && line && (line1 = getNextLine(line)); + ++j, line = line1) { + if ((n = line1 - line) > 255) { + n = 255; + } + strncpy(buf, line, n); + buf[n] = '\0'; + for (p = buf; *p == ' ' || *p == '\t'; ++p) ; + if (!strncmp(p, "dup", 3)) { + for (p += 3; *p == ' ' || *p == '\t'; ++p) ; + for (p2 = p; *p2 >= '0' && *p2 <= '9'; ++p2) ; + if (*p2) { + c = *p2; + *p2 = '\0'; + if ((code = atoi(p)) < 256) { + *p2 = c; + for (p = p2; *p == ' ' || *p == '\t'; ++p) ; + if (*p == '/') { + ++p; + for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ; + *p2 = '\0'; + encoding[code] = copyString(p); + } + } + } + } else { + if (strtok(buf, " \t") && + (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) { + break; + } + } + } + //~ check for getinterval/putinterval junk + + } else { + line = getNextLine(line); + } + } + + parsed = gTrue; +} diff --git a/rosapps/smartpdf/poppler/fofi/FoFiType1.h b/rosapps/smartpdf/poppler/fofi/FoFiType1.h new file mode 100644 index 00000000000..85e67b1c82b --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiType1.h @@ -0,0 +1,57 @@ +//======================================================================== +// +// FoFiType1.h +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FOFITYPE1_H +#define FOFITYPE1_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "FoFiBase.h" + +//------------------------------------------------------------------------ +// FoFiType1 +//------------------------------------------------------------------------ + +class FoFiType1: public FoFiBase { +public: + + // Create a FoFiType1 object from a memory buffer. + static FoFiType1 *make(char *fileA, int lenA); + + // Create a FoFiType1 object from a file on disk. + static FoFiType1 *load(char *fileName); + + virtual ~FoFiType1(); + + // Return the font name. + char *getName(); + + // Return the encoding, as an array of 256 names (any of which may + // be NULL). + char **getEncoding(); + + // Write a version of the Type 1 font file with a new encoding. + void writeEncoded(char **newEncoding, + FoFiOutputFunc outputFunc, void *outputStream); + +private: + + FoFiType1(char *fileA, int lenA, GBool freeFileDataA); + + char *getNextLine(char *line); + void parse(); + + char *name; + char **encoding; + GBool parsed; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/fofi/FoFiType1C.cc b/rosapps/smartpdf/poppler/fofi/FoFiType1C.cc new file mode 100644 index 00000000000..b2d0528bf36 --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiType1C.cc @@ -0,0 +1,2481 @@ +//======================================================================== +// +// FoFiType1C.cc +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "FoFiEncodings.h" +#include "FoFiType1C.h" + +//------------------------------------------------------------------------ + +static char hexChars[17] = "0123456789ABCDEF"; + +//------------------------------------------------------------------------ +// FoFiType1C +//------------------------------------------------------------------------ + +FoFiType1C *FoFiType1C::make(char *fileA, int lenA) { + FoFiType1C *ff; + + ff = new FoFiType1C(fileA, lenA, gFalse); + if (!ff->parse()) { + delete ff; + return NULL; + } + return ff; +} + +FoFiType1C *FoFiType1C::load(char *fileName) { + FoFiType1C *ff; + char *fileA; + int lenA; + + if (!(fileA = FoFiBase::readFile(fileName, &lenA))) { + return NULL; + } + ff = new FoFiType1C(fileA, lenA, gTrue); + if (!ff->parse()) { + delete ff; + return NULL; + } + return ff; +} + +FoFiType1C::FoFiType1C(char *fileA, int lenA, GBool freeFileDataA): + FoFiBase(fileA, lenA, freeFileDataA) +{ + name = NULL; + encoding = NULL; + privateDicts = NULL; + fdSelect = NULL; + charset = NULL; +} + +FoFiType1C::~FoFiType1C() { + int i; + + if (name) { + delete name; + } + if (encoding && + encoding != fofiType1StandardEncoding && + encoding != fofiType1ExpertEncoding) { + for (i = 0; i < 256; ++i) { + gfree(encoding[i]); + } + gfree(encoding); + } + if (privateDicts) { + gfree(privateDicts); + } + if (fdSelect) { + gfree(fdSelect); + } + if (charset && + charset != fofiType1CISOAdobeCharset && + charset != fofiType1CExpertCharset && + charset != fofiType1CExpertSubsetCharset) { + gfree(charset); + } +} + +char *FoFiType1C::getName() { + return name ? name->getCString() : (char *)NULL; +} + +char **FoFiType1C::getEncoding() { + return encoding; +} + +Gushort *FoFiType1C::getCIDToGIDMap(int *nCIDs) { + Gushort *map; + int n, i; + + // a CID font's top dict has ROS as the first operator + if (topDict.firstOp != 0x0c1e) { + *nCIDs = 0; + return NULL; + } + + // in a CID font, the charset data is the GID-to-CID mapping, so all + // we have to do is reverse it + n = 0; + for (i = 0; i < nGlyphs; ++i) { + if (charset[i] > n) { + n = charset[i]; + } + } + ++n; + map = (Gushort *)gmallocn(n, sizeof(Gushort)); + memset(map, 0, n * sizeof(Gushort)); + for (i = 0; i < nGlyphs; ++i) { + map[charset[i]] = i; + } + *nCIDs = n; + return map; +} + +void FoFiType1C::convertToType1(char **newEncoding, GBool ascii, + FoFiOutputFunc outputFunc, + void *outputStream) { + Type1CEexecBuf eb; + Type1CIndex subrIdx; + Type1CIndexVal val; + char buf[512]; + char **enc; + GBool ok; + int i; + + // write header and font dictionary, up to encoding + ok = gTrue; + (*outputFunc)(outputStream, "%!FontType1-1.0: ", 17); + (*outputFunc)(outputStream, name->getCString(), name->getLength()); + if (topDict.versionSID != 0) { + getString(topDict.versionSID, buf, &ok); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "\n", 1); + // the dictionary needs room for 12 entries: the following 9, plus + // Private and CharStrings (in the eexec section) and FID (which is + // added by definefont) + (*outputFunc)(outputStream, "12 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontInfo 10 dict dup begin\n", 28); + if (topDict.versionSID != 0) { + (*outputFunc)(outputStream, "/version (", 10); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); + } + if (topDict.noticeSID != 0) { + getString(topDict.noticeSID, buf, &ok); + (*outputFunc)(outputStream, "/Notice (", 9); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); + } + if (topDict.copyrightSID != 0) { + getString(topDict.copyrightSID, buf, &ok); + (*outputFunc)(outputStream, "/Copyright (", 12); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); + } + if (topDict.fullNameSID != 0) { + getString(topDict.fullNameSID, buf, &ok); + (*outputFunc)(outputStream, "/FullName (", 11); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); + } + if (topDict.familyNameSID != 0) { + getString(topDict.familyNameSID, buf, &ok); + (*outputFunc)(outputStream, "/FamilyName (", 13); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); + } + if (topDict.weightSID != 0) { + getString(topDict.weightSID, buf, &ok); + (*outputFunc)(outputStream, "/Weight (", 9); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); + } + if (topDict.isFixedPitch) { + (*outputFunc)(outputStream, "/isFixedPitch true def\n", 23); + } else { + (*outputFunc)(outputStream, "/isFixedPitch false def\n", 24); + } + sprintf(buf, "/ItalicAngle %g def\n", topDict.italicAngle); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/UnderlinePosition %g def\n", topDict.underlinePosition); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/UnderlineThickness %g def\n", topDict.underlineThickness); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "end readonly def\n", 17); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, name->getCString(), name->getLength()); + (*outputFunc)(outputStream, " def\n", 5); + sprintf(buf, "/PaintType %d def\n", topDict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 1 def\n", 16); + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", + topDict.fontMatrix[0], topDict.fontMatrix[1], topDict.fontMatrix[2], + topDict.fontMatrix[3], topDict.fontMatrix[4], topDict.fontMatrix[5]); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/FontBBox [%g %g %g %g] readonly def\n", + topDict.fontBBox[0], topDict.fontBBox[1], + topDict.fontBBox[2], topDict.fontBBox[3]); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth); + (*outputFunc)(outputStream, buf, strlen(buf)); + if (topDict.uniqueID != 0) { + sprintf(buf, "/UniqueID %d def\n", topDict.uniqueID); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + + // write the encoding + (*outputFunc)(outputStream, "/Encoding ", 10); + if (!newEncoding && encoding == fofiType1StandardEncoding) { + (*outputFunc)(outputStream, "StandardEncoding def\n", 21); + } else { + (*outputFunc)(outputStream, "256 array\n", 10); + (*outputFunc)(outputStream, + "0 1 255 {1 index exch /.notdef put} for\n", 40); + enc = newEncoding ? newEncoding : encoding; + for (i = 0; i < 256; ++i) { + if (enc[i]) { + sprintf(buf, "dup %d /%s put\n", i, enc[i]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + } + (*outputFunc)(outputStream, "readonly def\n", 13); + } + (*outputFunc)(outputStream, "currentdict end\n", 16); + + // start the binary section + (*outputFunc)(outputStream, "currentfile eexec\n", 18); + eb.outputFunc = outputFunc; + eb.outputStream = outputStream; + eb.ascii = ascii; + eb.r1 = 55665; + eb.line = 0; + + // write the private dictionary + eexecWrite(&eb, "\x83\xca\x73\xd5"); + eexecWrite(&eb, "dup /Private 32 dict dup begin\n"); + eexecWrite(&eb, "/RD {string currentfile exch readstring pop}" + " executeonly def\n"); + eexecWrite(&eb, "/ND {noaccess def} executeonly def\n"); + eexecWrite(&eb, "/NP {noaccess put} executeonly def\n"); + eexecWrite(&eb, "/MinFeature {16 16} def\n"); + eexecWrite(&eb, "/password 5839 def\n"); + if (privateDicts[0].nBlueValues) { + eexecWrite(&eb, "/BlueValues ["); + for (i = 0; i < privateDicts[0].nBlueValues; ++i) { + sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].blueValues[i]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[0].nOtherBlues) { + eexecWrite(&eb, "/OtherBlues ["); + for (i = 0; i < privateDicts[0].nOtherBlues; ++i) { + sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].otherBlues[i]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[0].nFamilyBlues) { + eexecWrite(&eb, "/FamilyBlues ["); + for (i = 0; i < privateDicts[0].nFamilyBlues; ++i) { + sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].familyBlues[i]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[0].nFamilyOtherBlues) { + eexecWrite(&eb, "/FamilyOtherBlues ["); + for (i = 0; i < privateDicts[0].nFamilyOtherBlues; ++i) { + sprintf(buf, "%s%d", i > 0 ? " " : "", + privateDicts[0].familyOtherBlues[i]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[0].blueScale != 0.039625) { + sprintf(buf, "/BlueScale %g def\n", privateDicts[0].blueScale); + eexecWrite(&eb, buf); + } + if (privateDicts[0].blueShift != 7) { + sprintf(buf, "/BlueShift %d def\n", privateDicts[0].blueShift); + eexecWrite(&eb, buf); + } + if (privateDicts[0].blueFuzz != 1) { + sprintf(buf, "/BlueFuzz %d def\n", privateDicts[0].blueFuzz); + eexecWrite(&eb, buf); + } + if (privateDicts[0].hasStdHW) { + sprintf(buf, "/StdHW [%g] def\n", privateDicts[0].stdHW); + eexecWrite(&eb, buf); + } + if (privateDicts[0].hasStdVW) { + sprintf(buf, "/StdVW [%g] def\n", privateDicts[0].stdVW); + eexecWrite(&eb, buf); + } + if (privateDicts[0].nStemSnapH) { + eexecWrite(&eb, "/StemSnapH ["); + for (i = 0; i < privateDicts[0].nStemSnapH; ++i) { + sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapH[i]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[0].nStemSnapV) { + eexecWrite(&eb, "/StemSnapV ["); + for (i = 0; i < privateDicts[0].nStemSnapV; ++i) { + sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapV[i]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[0].hasForceBold) { + sprintf(buf, "/ForceBold %s def\n", + privateDicts[0].forceBold ? "true" : "false"); + eexecWrite(&eb, buf); + } + if (privateDicts[0].forceBoldThreshold != 0) { + sprintf(buf, "/ForceBoldThreshold %g def\n", + privateDicts[0].forceBoldThreshold); + eexecWrite(&eb, buf); + } + if (privateDicts[0].languageGroup != 0) { + sprintf(buf, "/LanguageGroup %d def\n", privateDicts[0].languageGroup); + eexecWrite(&eb, buf); + } + if (privateDicts[0].expansionFactor != 0.06) { + sprintf(buf, "/ExpansionFactor %g def\n", privateDicts[0].expansionFactor); + eexecWrite(&eb, buf); + } + + // set up subroutines + ok = gTrue; + getIndex(privateDicts[0].subrsOffset, &subrIdx, &ok); + if (!ok) { + subrIdx.pos = -1; + } + + // write the CharStrings + sprintf(buf, "2 index /CharStrings %d dict dup begin\n", nGlyphs); + eexecWrite(&eb, buf); + for (i = 0; i < nGlyphs; ++i) { + ok = gTrue; + getIndexVal(&charStringsIdx, i, &val, &ok); + if (ok) { + getString(charset[i], buf, &ok); + if (ok) { + eexecCvtGlyph(&eb, buf, val.pos, val.len, &subrIdx, &privateDicts[0]); + } + } + } + eexecWrite(&eb, "end\n"); + eexecWrite(&eb, "end\n"); + eexecWrite(&eb, "readonly put\n"); + eexecWrite(&eb, "noaccess put\n"); + eexecWrite(&eb, "dup /FontName get exch definefont pop\n"); + eexecWrite(&eb, "mark currentfile closefile\n"); + + // trailer + if (ascii && eb.line > 0) { + (*outputFunc)(outputStream, "\n", 1); + } + for (i = 0; i < 8; ++i) { + (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); + } + (*outputFunc)(outputStream, "cleartomark\n", 12); +} + +void FoFiType1C::convertToCIDType0(char *psName, + FoFiOutputFunc outputFunc, + void *outputStream) { + int *cidMap; + GooString *charStrings; + int *charStringOffsets; + Type1CIndex subrIdx; + Type1CIndexVal val; + int nCIDs, gdBytes; + char buf[512], buf2[512]; + GBool ok; + int gid, offset, n, i, j, k; + + // compute the CID count and build the CID-to-GID mapping + nCIDs = 0; + for (i = 0; i < nGlyphs; ++i) { + if (charset[i] >= nCIDs) { + nCIDs = charset[i] + 1; + } + } + cidMap = (int *)gmallocn(nCIDs, sizeof(int)); + for (i = 0; i < nCIDs; ++i) { + cidMap[i] = -1; + } + for (i = 0; i < nGlyphs; ++i) { + cidMap[charset[i]] = i; + } + + // build the charstrings + charStrings = new GooString(); + charStringOffsets = (int *)gmallocn(nCIDs + 1, sizeof(int)); + for (i = 0; i < nCIDs; ++i) { + charStringOffsets[i] = charStrings->getLength(); + if ((gid = cidMap[i]) >= 0) { + ok = gTrue; + getIndexVal(&charStringsIdx, gid, &val, &ok); + if (ok) { + getIndex(privateDicts[fdSelect[gid]].subrsOffset, &subrIdx, &ok); + if (!ok) { + subrIdx.pos = -1; + } + cvtGlyph(val.pos, val.len, charStrings, + &subrIdx, &privateDicts[fdSelect[gid]], gTrue); + } + } + } + charStringOffsets[nCIDs] = charStrings->getLength(); + + // compute gdBytes = number of bytes needed for charstring offsets + // (offset size needs to account for the charstring offset table, + // with a worst case of five bytes per entry, plus the charstrings + // themselves) + i = (nCIDs + 1) * 5 + charStrings->getLength(); + if (i < 0x100) { + gdBytes = 1; + } else if (i < 0x10000) { + gdBytes = 2; + } else if (i < 0x1000000) { + gdBytes = 3; + } else { + gdBytes = 4; + } + + // begin the font dictionary + (*outputFunc)(outputStream, "/CIDInit /ProcSet findresource begin\n", 37); + (*outputFunc)(outputStream, "20 dict begin\n", 14); + (*outputFunc)(outputStream, "/CIDFontName /", 14); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/CIDFontType 0 def\n", 19); + (*outputFunc)(outputStream, "/CIDSystemInfo 3 dict dup begin\n", 32); + if (topDict.registrySID > 0 && topDict.orderingSID > 0) { + ok = gTrue; + getString(topDict.registrySID, buf, &ok); + if (ok) { + (*outputFunc)(outputStream, " /Registry (", 13); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") def\n", 6); + } + ok = gTrue; + getString(topDict.orderingSID, buf, &ok); + if (ok) { + (*outputFunc)(outputStream, " /Ordering (", 13); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") def\n", 6); + } + } else { + (*outputFunc)(outputStream, " /Registry (Adobe) def\n", 24); + (*outputFunc)(outputStream, " /Ordering (Identity) def\n", 27); + } + sprintf(buf, " /Supplement %d def\n", topDict.supplement); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "end def\n", 8); + if (topDict.hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", + topDict.fontMatrix[0], topDict.fontMatrix[1], + topDict.fontMatrix[2], topDict.fontMatrix[3], + topDict.fontMatrix[4], topDict.fontMatrix[5]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } else if (privateDicts[0].hasFontMatrix) { + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + } else { + (*outputFunc)(outputStream, + "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38); + } + sprintf(buf, "/FontBBox [%g %g %g %g] def\n", + topDict.fontBBox[0], topDict.fontBBox[1], + topDict.fontBBox[2], topDict.fontBBox[3]); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontInfo 1 dict dup begin\n", 27); + (*outputFunc)(outputStream, " /FSType 8 def\n", 16); + (*outputFunc)(outputStream, "end def\n", 8); + + // CIDFont-specific entries + sprintf(buf, "/CIDCount %d def\n", nCIDs); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FDBytes 1 def\n", 15); + sprintf(buf, "/GDBytes %d def\n", gdBytes); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/CIDMapOffset 0 def\n", 20); + if (topDict.paintType != 0) { + sprintf(buf, "/PaintType %d def\n", topDict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + + // FDArray entry + sprintf(buf, "/FDArray %d array\n", nFDs); + (*outputFunc)(outputStream, buf, strlen(buf)); + for (i = 0; i < nFDs; ++i) { + sprintf(buf, "dup %d 10 dict begin\n", i); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 1 def\n", 16); + if (privateDicts[i].hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", + privateDicts[i].fontMatrix[0], + privateDicts[i].fontMatrix[1], + privateDicts[i].fontMatrix[2], + privateDicts[i].fontMatrix[3], + privateDicts[i].fontMatrix[4], + privateDicts[i].fontMatrix[5]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } else { + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + } + sprintf(buf, "/PaintType %d def\n", topDict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/Private 32 dict begin\n", 23); + if (privateDicts[i].nBlueValues) { + (*outputFunc)(outputStream, "/BlueValues [", 13); + for (j = 0; j < privateDicts[i].nBlueValues; ++j) { + sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].blueValues[j]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + } + if (privateDicts[i].nOtherBlues) { + (*outputFunc)(outputStream, "/OtherBlues [", 13); + for (j = 0; j < privateDicts[i].nOtherBlues; ++j) { + sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].otherBlues[j]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + } + if (privateDicts[i].nFamilyBlues) { + (*outputFunc)(outputStream, "/FamilyBlues [", 14); + for (j = 0; j < privateDicts[i].nFamilyBlues; ++j) { + sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].familyBlues[j]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + } + if (privateDicts[i].nFamilyOtherBlues) { + (*outputFunc)(outputStream, "/FamilyOtherBlues [", 19); + for (j = 0; j < privateDicts[i].nFamilyOtherBlues; ++j) { + sprintf(buf, "%s%d", j > 0 ? " " : "", + privateDicts[i].familyOtherBlues[j]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + } + if (privateDicts[i].blueScale != 0.039625) { + sprintf(buf, "/BlueScale %g def\n", privateDicts[i].blueScale); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].blueShift != 7) { + sprintf(buf, "/BlueShift %d def\n", privateDicts[i].blueShift); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].blueFuzz != 1) { + sprintf(buf, "/BlueFuzz %d def\n", privateDicts[i].blueFuzz); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].hasStdHW) { + sprintf(buf, "/StdHW [%g] def\n", privateDicts[i].stdHW); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].hasStdVW) { + sprintf(buf, "/StdVW [%g] def\n", privateDicts[i].stdVW); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].nStemSnapH) { + (*outputFunc)(outputStream, "/StemSnapH [", 12); + for (j = 0; j < privateDicts[i].nStemSnapH; ++j) { + sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapH[j]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + } + if (privateDicts[i].nStemSnapV) { + (*outputFunc)(outputStream, "/StemSnapV [", 12); + for (j = 0; j < privateDicts[i].nStemSnapV; ++j) { + sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapV[j]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + } + if (privateDicts[i].hasForceBold) { + sprintf(buf, "/ForceBold %s def\n", + privateDicts[i].forceBold ? "true" : "false"); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].forceBoldThreshold != 0) { + sprintf(buf, "/ForceBoldThreshold %g def\n", + privateDicts[i].forceBoldThreshold); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].languageGroup != 0) { + sprintf(buf, "/LanguageGroup %d def\n", privateDicts[i].languageGroup); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (privateDicts[i].expansionFactor != 0.06) { + sprintf(buf, "/ExpansionFactor %g def\n", + privateDicts[i].expansionFactor); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "currentdict end def\n", 20); + (*outputFunc)(outputStream, "currentdict end put\n", 20); + } + (*outputFunc)(outputStream, "def\n", 4); + + // start the binary section + offset = (nCIDs + 1) * (1 + gdBytes); + sprintf(buf, "(Hex) %d StartData\n", + offset + charStrings->getLength()); + (*outputFunc)(outputStream, buf, strlen(buf)); + + // write the charstring offset (CIDMap) table + for (i = 0; i <= nCIDs; i += 6) { + for (j = 0; j < 6 && i+j <= nCIDs; ++j) { + if (i+j < nCIDs && cidMap[i+j] >= 0) { + buf[0] = (char)fdSelect[cidMap[i+j]]; + } else { + buf[0] = (char)0; + } + n = offset + charStringOffsets[i+j]; + for (k = gdBytes; k >= 1; --k) { + buf[k] = (char)(n & 0xff); + n >>= 8; + } + for (k = 0; k <= gdBytes; ++k) { + sprintf(buf2, "%02x", buf[k] & 0xff); + (*outputFunc)(outputStream, buf2, 2); + } + } + (*outputFunc)(outputStream, "\n", 1); + } + + // write the charstring data + n = charStrings->getLength(); + for (i = 0; i < n; i += 32) { + for (j = 0; j < 32 && i+j < n; ++j) { + sprintf(buf, "%02x", charStrings->getChar(i+j) & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (i + 32 >= n) { + (*outputFunc)(outputStream, ">", 1); + } + (*outputFunc)(outputStream, "\n", 1); + } + + gfree(charStringOffsets); + delete charStrings; + gfree(cidMap); +} + +void FoFiType1C::convertToType0(char *psName, + FoFiOutputFunc outputFunc, + void *outputStream) { + int *cidMap; + Type1CIndex subrIdx; + Type1CIndexVal val; + int nCIDs; + char buf[512]; + Type1CEexecBuf eb; + GBool ok; + int fd, i, j, k; + + // compute the CID count and build the CID-to-GID mapping + nCIDs = 0; + for (i = 0; i < nGlyphs; ++i) { + if (charset[i] >= nCIDs) { + nCIDs = charset[i] + 1; + } + } + cidMap = (int *)gmallocn(nCIDs, sizeof(int)); + for (i = 0; i < nCIDs; ++i) { + cidMap[i] = -1; + } + for (i = 0; i < nGlyphs; ++i) { + cidMap[charset[i]] = i; + } + + // write the descendant Type 1 fonts + for (i = 0; i < nCIDs; i += 256) { + + //~ this assumes that all CIDs in this block have the same FD -- + //~ to handle multiple FDs correctly, need to somehow divide the + //~ font up by FD + fd = 0; + for (j = 0; j < 256 && i+j < nCIDs; ++j) { + if (cidMap[i+j] >= 0) { + fd = fdSelect[cidMap[i+j]]; + break; + } + } + + // font dictionary (unencrypted section) + (*outputFunc)(outputStream, "16 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, psName, strlen(psName)); + sprintf(buf, "_%02x def\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 1 def\n", 16); + if (privateDicts[fd].hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", + privateDicts[fd].fontMatrix[0], + privateDicts[fd].fontMatrix[1], + privateDicts[fd].fontMatrix[2], + privateDicts[fd].fontMatrix[3], + privateDicts[fd].fontMatrix[4], + privateDicts[fd].fontMatrix[5]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } else if (topDict.hasFontMatrix) { + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + } else { + (*outputFunc)(outputStream, + "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38); + } + sprintf(buf, "/FontBBox [%g %g %g %g] def\n", + topDict.fontBBox[0], topDict.fontBBox[1], + topDict.fontBBox[2], topDict.fontBBox[3]); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/PaintType %d def\n", topDict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + if (topDict.paintType != 0) { + sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); + for (j = 0; j < 256 && i+j < nCIDs; ++j) { + sprintf(buf, "dup %d /c%02x put\n", j, j); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + if (j < 256) { + sprintf(buf, "%d 1 255 { 1 index exch /.notdef put } for\n", j); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "readonly def\n", 13); + (*outputFunc)(outputStream, "currentdict end\n", 16); + + // start the binary section + (*outputFunc)(outputStream, "currentfile eexec\n", 18); + eb.outputFunc = outputFunc; + eb.outputStream = outputStream; + eb.ascii = gTrue; + eb.r1 = 55665; + eb.line = 0; + + // start the private dictionary + eexecWrite(&eb, "\x83\xca\x73\xd5"); + eexecWrite(&eb, "dup /Private 32 dict dup begin\n"); + eexecWrite(&eb, "/RD {string currentfile exch readstring pop}" + " executeonly def\n"); + eexecWrite(&eb, "/ND {noaccess def} executeonly def\n"); + eexecWrite(&eb, "/NP {noaccess put} executeonly def\n"); + eexecWrite(&eb, "/MinFeature {16 16} def\n"); + eexecWrite(&eb, "/password 5839 def\n"); + if (privateDicts[fd].nBlueValues) { + eexecWrite(&eb, "/BlueValues ["); + for (k = 0; k < privateDicts[fd].nBlueValues; ++k) { + sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].blueValues[k]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[fd].nOtherBlues) { + eexecWrite(&eb, "/OtherBlues ["); + for (k = 0; k < privateDicts[fd].nOtherBlues; ++k) { + sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].otherBlues[k]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[fd].nFamilyBlues) { + eexecWrite(&eb, "/FamilyBlues ["); + for (k = 0; k < privateDicts[fd].nFamilyBlues; ++k) { + sprintf(buf, "%s%d", k > 0 ? " " : "", + privateDicts[fd].familyBlues[k]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[fd].nFamilyOtherBlues) { + eexecWrite(&eb, "/FamilyOtherBlues ["); + for (k = 0; k < privateDicts[fd].nFamilyOtherBlues; ++k) { + sprintf(buf, "%s%d", k > 0 ? " " : "", + privateDicts[fd].familyOtherBlues[k]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[fd].blueScale != 0.039625) { + sprintf(buf, "/BlueScale %g def\n", privateDicts[fd].blueScale); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].blueShift != 7) { + sprintf(buf, "/BlueShift %d def\n", privateDicts[fd].blueShift); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].blueFuzz != 1) { + sprintf(buf, "/BlueFuzz %d def\n", privateDicts[fd].blueFuzz); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].hasStdHW) { + sprintf(buf, "/StdHW [%g] def\n", privateDicts[fd].stdHW); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].hasStdVW) { + sprintf(buf, "/StdVW [%g] def\n", privateDicts[fd].stdVW); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].nStemSnapH) { + eexecWrite(&eb, "/StemSnapH ["); + for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) { + sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapH[k]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[fd].nStemSnapV) { + eexecWrite(&eb, "/StemSnapV ["); + for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) { + sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapV[k]); + eexecWrite(&eb, buf); + } + eexecWrite(&eb, "] def\n"); + } + if (privateDicts[fd].hasForceBold) { + sprintf(buf, "/ForceBold %s def\n", + privateDicts[fd].forceBold ? "true" : "false"); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].forceBoldThreshold != 0) { + sprintf(buf, "/ForceBoldThreshold %g def\n", + privateDicts[fd].forceBoldThreshold); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].languageGroup != 0) { + sprintf(buf, "/LanguageGroup %d def\n", privateDicts[fd].languageGroup); + eexecWrite(&eb, buf); + } + if (privateDicts[fd].expansionFactor != 0.06) { + sprintf(buf, "/ExpansionFactor %g def\n", + privateDicts[fd].expansionFactor); + eexecWrite(&eb, buf); + } + + // set up the subroutines + ok = gTrue; + getIndex(privateDicts[fd].subrsOffset, &subrIdx, &ok); + if (!ok) { + subrIdx.pos = -1; + } + + // start the CharStrings + sprintf(buf, "2 index /CharStrings 256 dict dup begin\n"); + eexecWrite(&eb, buf); + + // write the .notdef CharString + ok = gTrue; + getIndexVal(&charStringsIdx, 0, &val, &ok); + if (ok) { + eexecCvtGlyph(&eb, ".notdef", val.pos, val.len, + &subrIdx, &privateDicts[fd]); + } + + // write the CharStrings + for (j = 0; j < 256 && i+j < nCIDs; ++j) { + if (cidMap[i+j] >= 0) { + ok = gTrue; + getIndexVal(&charStringsIdx, cidMap[i+j], &val, &ok); + if (ok) { + sprintf(buf, "c%02x", j); + eexecCvtGlyph(&eb, buf, val.pos, val.len, + &subrIdx, &privateDicts[fd]); + } + } + } + eexecWrite(&eb, "end\n"); + eexecWrite(&eb, "end\n"); + eexecWrite(&eb, "readonly put\n"); + eexecWrite(&eb, "noaccess put\n"); + eexecWrite(&eb, "dup /FontName get exch definefont pop\n"); + eexecWrite(&eb, "mark currentfile closefile\n"); + + // trailer + if (eb.line > 0) { + (*outputFunc)(outputStream, "\n", 1); + } + for (j = 0; j < 8; ++j) { + (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); + } + (*outputFunc)(outputStream, "cleartomark\n", 12); + } + + // write the Type 0 parent font + (*outputFunc)(outputStream, "16 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/FontType 0 def\n", 16); + if (topDict.hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", + topDict.fontMatrix[0], topDict.fontMatrix[1], + topDict.fontMatrix[2], topDict.fontMatrix[3], + topDict.fontMatrix[4], topDict.fontMatrix[5]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } else { + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + } + (*outputFunc)(outputStream, "/FMapType 2 def\n", 16); + (*outputFunc)(outputStream, "/Encoding [\n", 12); + for (i = 0; i < nCIDs; i += 256) { + sprintf(buf, "%d\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "/FDepVector [\n", 14); + for (i = 0; i < nCIDs; i += 256) { + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, psName, strlen(psName)); + sprintf(buf, "_%02x findfont\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + } + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40); + + gfree(cidMap); +} + +void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, char *glyphName, + int offset, int nBytes, + Type1CIndex *subrIdx, + Type1CPrivateDict *pDict) { + char buf[512]; + GooString *charBuf; + + // generate the charstring + charBuf = new GooString(); + cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue); + + sprintf(buf, "/%s %d RD ", glyphName, charBuf->getLength()); + eexecWrite(eb, buf); + eexecWriteCharstring(eb, (Guchar *)charBuf->getCString(), + charBuf->getLength()); + eexecWrite(eb, " ND\n"); + + delete charBuf; +} + +void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf, + Type1CIndex *subrIdx, Type1CPrivateDict *pDict, + GBool top) { + Type1CIndexVal val; + GBool ok, dFP; + double d, dx, dy; + Gushort r2; + Guchar byte; + int pos, subrBias, start, i, k; + + start = charBuf->getLength(); + if (top) { + charBuf->append((char)73); + charBuf->append((char)58); + charBuf->append((char)147); + charBuf->append((char)134); + nOps = 0; + nHints = 0; + firstOp = gTrue; + openPath = gFalse; + } + + pos = offset; + while (pos < offset + nBytes) { + ok = gTrue; + pos = getOp(pos, gTrue, &ok); + if (!ok) { + break; + } + if (!ops[nOps - 1].isNum) { + --nOps; // drop the operator + switch (ops[nOps].op) { + case 0x0001: // hstem + if (firstOp) { + cvtGlyphWidth(nOps & 1, charBuf, pDict); + firstOp = gFalse; + } + if (nOps & 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps); + } + d = 0; + dFP = gFalse; + for (k = 0; k < nOps; k += 2) { + // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints + if (ops[k+1].num < 0) { + d += ops[k].num + ops[k+1].num; + dFP |= ops[k].isFP | ops[k+1].isFP; + cvtNum(d, dFP, charBuf); + cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf); + } else { + d += ops[k].num; + dFP |= ops[k].isFP; + cvtNum(d, dFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + d += ops[k+1].num; + dFP |= ops[k+1].isFP; + } + charBuf->append((char)1); + } + nHints += nOps / 2; + nOps = 0; + break; + case 0x0003: // vstem + if (firstOp) { + cvtGlyphWidth(nOps & 1, charBuf, pDict); + firstOp = gFalse; + } + if (nOps & 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps); + } + d = 0; + dFP = gFalse; + for (k = 0; k < nOps; k += 2) { + // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints + if (ops[k+1].num < 0) { + d += ops[k].num + ops[k+1].num; + dFP |= ops[k].isFP | ops[k+1].isFP; + cvtNum(d, dFP, charBuf); + cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf); + } else { + d += ops[k].num; + dFP |= ops[k].isFP; + cvtNum(d, dFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + d += ops[k+1].num; + dFP |= ops[k+1].isFP; + } + charBuf->append((char)3); + } + nHints += nOps / 2; + nOps = 0; + break; + case 0x0004: // vmoveto + if (firstOp) { + cvtGlyphWidth(nOps == 2, charBuf, pDict); + firstOp = gFalse; + } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } + if (nOps != 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps); + } + cvtNum(ops[0].num, ops[0].isFP, charBuf); + charBuf->append((char)4); + nOps = 0; + break; + case 0x0005: // rlineto + if (nOps < 2 || nOps % 2 != 0) { + //~ error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps); + } + for (k = 0; k < nOps; k += 2) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + charBuf->append((char)5); + } + nOps = 0; + openPath = gTrue; + break; + case 0x0006: // hlineto + if (nOps < 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps); + } + for (k = 0; k < nOps; ++k) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + charBuf->append((char)((k & 1) ? 7 : 6)); + } + nOps = 0; + openPath = gTrue; + break; + case 0x0007: // vlineto + if (nOps < 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps); + } + for (k = 0; k < nOps; ++k) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + charBuf->append((char)((k & 1) ? 6 : 7)); + } + nOps = 0; + openPath = gTrue; + break; + case 0x0008: // rrcurveto + if (nOps < 6 || nOps % 6 != 0) { + //~ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps); + } + for (k = 0; k < nOps; k += 6) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf); + charBuf->append((char)8); + } + nOps = 0; + openPath = gTrue; + break; + case 0x000a: // callsubr + if (nOps >= 1) { + subrBias = (subrIdx->len < 1240) + ? 107 : (subrIdx->len < 33900) ? 1131 : 32768; + k = subrBias + (int)ops[nOps - 1].num; + --nOps; + ok = gTrue; + getIndexVal(subrIdx, k, &val, &ok); + if (ok) { + cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse); + } + } else { + //~ error(-1, "Too few args to Type 2 callsubr"); + } + // don't clear the stack + break; + case 0x000b: // return + // don't clear the stack + break; + case 0x000e: // endchar / seac + if (firstOp) { + cvtGlyphWidth(nOps == 1 || nOps == 5, charBuf, pDict); + firstOp = gFalse; + } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } + if (nOps == 4) { + cvtNum(0, gFalse, charBuf); + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[3].num, ops[3].isFP, charBuf); + charBuf->append((char)12)->append((char)6); + } else if (nOps == 0) { + charBuf->append((char)14); + } else { + //~ error(-1, "Wrong number of args (%d) to Type 2 endchar", nOps); + } + nOps = 0; + break; + case 0x000f: // (obsolete) + // this op is ignored, but we need the glyph width + if (firstOp) { + cvtGlyphWidth(nOps > 0, charBuf, pDict); + firstOp = gFalse; + } + nOps = 0; + break; + case 0x0010: // blend + //~ error(-1, "Unimplemented Type 2 charstring op: %d", file[i]); + nOps = 0; + break; + case 0x0012: // hstemhm + // ignored + if (firstOp) { + cvtGlyphWidth(nOps & 1, charBuf, pDict); + firstOp = gFalse; + } + if (nOps & 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hstemhm", nOps); + } + nHints += nOps / 2; + nOps = 0; + break; + case 0x0013: // hintmask + // ignored + if (firstOp) { + cvtGlyphWidth(nOps & 1, charBuf, pDict); + firstOp = gFalse; + } + if (nOps > 0) { + if (nOps & 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hintmask/vstemhm", + //~ nOps); + } + nHints += nOps / 2; + } + pos += (nHints + 7) >> 3; + nOps = 0; + break; + case 0x0014: // cntrmask + // ignored + if (firstOp) { + cvtGlyphWidth(nOps & 1, charBuf, pDict); + firstOp = gFalse; + } + if (nOps > 0) { + if (nOps & 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 cntrmask/vstemhm", + //~ nOps); + } + nHints += nOps / 2; + } + pos += (nHints + 7) >> 3; + nOps = 0; + break; + case 0x0015: // rmoveto + if (firstOp) { + cvtGlyphWidth(nOps == 3, charBuf, pDict); + firstOp = gFalse; + } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } + if (nOps != 2) { + //~ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps); + } + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[1].num, ops[1].isFP, charBuf); + charBuf->append((char)21); + nOps = 0; + break; + case 0x0016: // hmoveto + if (firstOp) { + cvtGlyphWidth(nOps == 2, charBuf, pDict); + firstOp = gFalse; + } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } + if (nOps != 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps); + } + cvtNum(ops[0].num, ops[0].isFP, charBuf); + charBuf->append((char)22); + nOps = 0; + break; + case 0x0017: // vstemhm + // ignored + if (firstOp) { + cvtGlyphWidth(nOps & 1, charBuf, pDict); + firstOp = gFalse; + } + if (nOps & 1) { + //~ error(-1, "Wrong number of args (%d) to Type 2 vstemhm", nOps); + } + nHints += nOps / 2; + nOps = 0; + break; + case 0x0018: // rcurveline + if (nOps < 8 || (nOps - 2) % 6 != 0) { + //~ error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps); + } + for (k = 0; k < nOps - 2; k += 6) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf); + charBuf->append((char)8); + } + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k].isFP, charBuf); + charBuf->append((char)5); + nOps = 0; + openPath = gTrue; + break; + case 0x0019: // rlinecurve + if (nOps < 8 || (nOps - 6) % 2 != 0) { + //~ error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps); + } + for (k = 0; k < nOps - 6; k += 2) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k].isFP, charBuf); + charBuf->append((char)5); + } + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf); + charBuf->append((char)8); + nOps = 0; + openPath = gTrue; + break; + case 0x001a: // vvcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { + //~ error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps); + } + if (nOps % 2 == 1) { + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[3].num, ops[3].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[4].num, ops[4].isFP, charBuf); + charBuf->append((char)8); + k = 5; + } else { + k = 0; + } + for (; k < nOps; k += 4) { + cvtNum(0, gFalse, charBuf); + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + charBuf->append((char)8); + } + nOps = 0; + openPath = gTrue; + break; + case 0x001b: // hhcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps); + } + if (nOps % 2 == 1) { + cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[3].num, ops[3].isFP, charBuf); + cvtNum(ops[4].num, ops[4].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + charBuf->append((char)8); + k = 5; + } else { + k = 0; + } + for (; k < nOps; k += 4) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + charBuf->append((char)8); + } + nOps = 0; + openPath = gTrue; + break; + case 0x001d: // callgsubr + if (nOps >= 1) { + k = gsubrBias + (int)ops[nOps - 1].num; + --nOps; + ok = gTrue; + getIndexVal(&gsubrIdx, k, &val, &ok); + if (ok) { + cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse); + } + } else { + //~ error(-1, "Too few args to Type 2 callgsubr"); + } + // don't clear the stack + break; + case 0x001e: // vhcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { + //~ error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps); + } + for (k = 0; k < nOps && k != nOps-5; k += 4) { + if (k % 8 == 0) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + charBuf->append((char)30); + } else { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + charBuf->append((char)31); + } + } + if (k == nOps-5) { + if (k % 8 == 0) { + cvtNum(0, gFalse, charBuf); + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + } else { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + } + charBuf->append((char)8); + } + nOps = 0; + openPath = gTrue; + break; + case 0x001f: // hvcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps); + } + for (k = 0; k < nOps && k != nOps-5; k += 4) { + if (k % 8 == 0) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + charBuf->append((char)31); + } else { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + charBuf->append((char)30); + } + } + if (k == nOps-5) { + if (k % 8 == 0) { + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + } else { + cvtNum(0, gFalse, charBuf); + cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); + cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + } + charBuf->append((char)8); + } + nOps = 0; + openPath = gTrue; + break; + case 0x0c00: // dotsection (should be Type 1 only?) + // ignored + nOps = 0; + break; + case 0x0c03: // and + case 0x0c04: // or + case 0x0c05: // not + case 0x0c08: // store + case 0x0c09: // abs + case 0x0c0a: // add + case 0x0c0b: // sub + case 0x0c0c: // div + case 0x0c0d: // load + case 0x0c0e: // neg + case 0x0c0f: // eq + case 0x0c12: // drop + case 0x0c14: // put + case 0x0c15: // get + case 0x0c16: // ifelse + case 0x0c17: // random + case 0x0c18: // mul + case 0x0c1a: // sqrt + case 0x0c1b: // dup + case 0x0c1c: // exch + case 0x0c1d: // index + case 0x0c1e: // roll + //~ error(-1, "Unimplemented Type 2 charstring op: 12.%d", file[i+1]); + nOps = 0; + break; + case 0x0c22: // hflex + if (nOps != 7) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps); + } + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[3].num, ops[3].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + charBuf->append((char)8); + cvtNum(ops[4].num, ops[4].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[5].num, ops[5].isFP, charBuf); + cvtNum(-ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[6].num, ops[6].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + charBuf->append((char)8); + nOps = 0; + openPath = gTrue; + break; + case 0x0c23: // flex + if (nOps != 13) { + //~ error(-1, "Wrong number of args (%d) to Type 2 flex", nOps); + } + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[3].num, ops[3].isFP, charBuf); + cvtNum(ops[4].num, ops[4].isFP, charBuf); + cvtNum(ops[5].num, ops[5].isFP, charBuf); + charBuf->append((char)8); + cvtNum(ops[6].num, ops[6].isFP, charBuf); + cvtNum(ops[7].num, ops[7].isFP, charBuf); + cvtNum(ops[8].num, ops[8].isFP, charBuf); + cvtNum(ops[9].num, ops[9].isFP, charBuf); + cvtNum(ops[10].num, ops[10].isFP, charBuf); + cvtNum(ops[11].num, ops[11].isFP, charBuf); + charBuf->append((char)8); + nOps = 0; + openPath = gTrue; + break; + case 0x0c24: // hflex1 + if (nOps != 9) { + //~ error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps); + } + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[3].num, ops[3].isFP, charBuf); + cvtNum(ops[4].num, ops[4].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + charBuf->append((char)8); + cvtNum(ops[5].num, ops[5].isFP, charBuf); + cvtNum(0, gFalse, charBuf); + cvtNum(ops[6].num, ops[6].isFP, charBuf); + cvtNum(ops[7].num, ops[7].isFP, charBuf); + cvtNum(ops[8].num, ops[8].isFP, charBuf); + cvtNum(-(ops[1].num + ops[3].num + ops[7].num), + ops[1].isFP | ops[3].isFP | ops[7].isFP, charBuf); + charBuf->append((char)8); + nOps = 0; + openPath = gTrue; + break; + case 0x0c25: // flex1 + if (nOps != 11) { + //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps); + } + cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[2].num, ops[2].isFP, charBuf); + cvtNum(ops[3].num, ops[3].isFP, charBuf); + cvtNum(ops[4].num, ops[4].isFP, charBuf); + cvtNum(ops[5].num, ops[5].isFP, charBuf); + charBuf->append((char)8); + cvtNum(ops[6].num, ops[6].isFP, charBuf); + cvtNum(ops[7].num, ops[7].isFP, charBuf); + cvtNum(ops[8].num, ops[8].isFP, charBuf); + cvtNum(ops[9].num, ops[9].isFP, charBuf); + dx = ops[0].num + ops[2].num + ops[4].num + ops[6].num + ops[8].num; + dy = ops[1].num + ops[3].num + ops[5].num + ops[7].num + ops[9].num; + if (fabs(dx) > fabs(dy)) { + cvtNum(ops[10].num, ops[10].isFP, charBuf); + cvtNum(-dy, ops[1].isFP | ops[3].isFP | ops[5].isFP | + ops[7].isFP | ops[9].isFP, charBuf); + } else { + cvtNum(-dx, ops[0].isFP | ops[2].isFP | ops[4].isFP | + ops[6].isFP | ops[8].isFP, charBuf); + cvtNum(ops[10].num, ops[10].isFP, charBuf); + } + charBuf->append((char)8); + nOps = 0; + openPath = gTrue; + break; + default: + //~ error(-1, "Illegal Type 2 charstring op: %04x", + //~ ops[nOps].op); + nOps = 0; + break; + } + } + } + + // charstring encryption + if (top) { + r2 = 4330; + for (i = start; i < charBuf->getLength(); ++i) { + byte = charBuf->getChar(i) ^ (r2 >> 8); + charBuf->setChar(i, byte); + r2 = (byte + r2) * 52845 + 22719; + } + } +} + +void FoFiType1C::cvtGlyphWidth(GBool useOp, GooString *charBuf, + Type1CPrivateDict *pDict) { + double w; + GBool wFP; + int i; + + if (useOp) { + w = pDict->nominalWidthX + ops[0].num; + wFP = pDict->nominalWidthXFP | ops[0].isFP; + for (i = 1; i < nOps; ++i) { + ops[i-1] = ops[i]; + } + --nOps; + } else { + w = pDict->defaultWidthX; + wFP = pDict->defaultWidthXFP; + } + cvtNum(0, gFalse, charBuf); + cvtNum(w, wFP, charBuf); + charBuf->append((char)13); +} + +void FoFiType1C::cvtNum(double x, GBool isFP, GooString *charBuf) { + Guchar buf[12]; + int y, n; + + n = 0; + if (isFP) { + if (x >= -32768 && x < 32768) { + y = (int)(x * 256.0); + buf[0] = 255; + buf[1] = (Guchar)(y >> 24); + buf[2] = (Guchar)(y >> 16); + buf[3] = (Guchar)(y >> 8); + buf[4] = (Guchar)y; + buf[5] = 255; + buf[6] = 0; + buf[7] = 0; + buf[8] = 1; + buf[9] = 0; + buf[10] = 12; + buf[11] = 12; + n = 12; + } else { + //~ error(-1, "Type 2 fixed point constant out of range"); + } + } else { + y = (int)x; + if (y >= -107 && y <= 107) { + buf[0] = (Guchar)(y + 139); + n = 1; + } else if (y > 107 && y <= 1131) { + y -= 108; + buf[0] = (Guchar)((y >> 8) + 247); + buf[1] = (Guchar)(y & 0xff); + n = 2; + } else if (y < -107 && y >= -1131) { + y = -y - 108; + buf[0] = (Guchar)((y >> 8) + 251); + buf[1] = (Guchar)(y & 0xff); + n = 2; + } else { + buf[0] = 255; + buf[1] = (Guchar)(y >> 24); + buf[2] = (Guchar)(y >> 16); + buf[3] = (Guchar)(y >> 8); + buf[4] = (Guchar)y; + n = 5; + } + } + charBuf->append((char *)buf, n); +} + +void FoFiType1C::eexecWrite(Type1CEexecBuf *eb, char *s) { + Guchar *p; + Guchar x; + + for (p = (Guchar *)s; *p; ++p) { + x = *p ^ (eb->r1 >> 8); + eb->r1 = (x + eb->r1) * 52845 + 22719; + if (eb->ascii) { + (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1); + (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1); + eb->line += 2; + if (eb->line == 64) { + (*eb->outputFunc)(eb->outputStream, "\n", 1); + eb->line = 0; + } + } else { + (*eb->outputFunc)(eb->outputStream, (char *)&x, 1); + } + } +} + +void FoFiType1C::eexecWriteCharstring(Type1CEexecBuf *eb, + Guchar *s, int n) { + Guchar x; + int i; + + // eexec encryption + for (i = 0; i < n; ++i) { + x = s[i] ^ (eb->r1 >> 8); + eb->r1 = (x + eb->r1) * 52845 + 22719; + if (eb->ascii) { + (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1); + (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1); + eb->line += 2; + if (eb->line == 64) { + (*eb->outputFunc)(eb->outputStream, "\n", 1); + eb->line = 0; + } + } else { + (*eb->outputFunc)(eb->outputStream, (char *)&x, 1); + } + } +} + +GBool FoFiType1C::parse() { + Type1CIndex fdIdx; + Type1CIndexVal val; + int i; + + parsedOk = gTrue; + + // some tools embed Type 1C fonts with an extra whitespace char at + // the beginning + if (len > 0 && file[0] != '\x01') { + ++file; + --len; + } + + // find the indexes + getIndex(getU8(2, &parsedOk), &nameIdx, &parsedOk); + getIndex(nameIdx.endPos, &topDictIdx, &parsedOk); + getIndex(topDictIdx.endPos, &stringIdx, &parsedOk); + getIndex(stringIdx.endPos, &gsubrIdx, &parsedOk); + if (!parsedOk) { + return gFalse; + } + gsubrBias = (gsubrIdx.len < 1240) ? 107 + : (gsubrIdx.len < 33900) ? 1131 : 32768; + + // read the first font name + getIndexVal(&nameIdx, 0, &val, &parsedOk); + if (!parsedOk) { + return gFalse; + } + name = new GooString((char *)&file[val.pos], val.len); + + // read the top dict for the first font + readTopDict(); + + // for CID fonts: read the FDArray dicts and private dicts + if (topDict.firstOp == 0x0c1e) { + if (topDict.fdArrayOffset == 0) { + nFDs = 1; + privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict)); + readPrivateDict(0, 0, &privateDicts[0]); + } else { + getIndex(topDict.fdArrayOffset, &fdIdx, &parsedOk); + if (!parsedOk) { + return gFalse; + } + nFDs = fdIdx.len; + privateDicts = (Type1CPrivateDict *) + gmallocn(nFDs, sizeof(Type1CPrivateDict)); + for (i = 0; i < nFDs; ++i) { + getIndexVal(&fdIdx, i, &val, &parsedOk); + if (!parsedOk) { + return gFalse; + } + readFD(val.pos, val.len, &privateDicts[i]); + } + } + + // for 8-bit fonts: read the private dict + } else { + privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict)); + readPrivateDict(topDict.privateOffset, topDict.privateSize, + &privateDicts[0]); + } + + // check for parse errors in the private dict(s) + if (!parsedOk) { + return gFalse; + } + + // get the charstrings index + if (topDict.charStringsOffset <= 0) { + parsedOk = gFalse; + return gFalse; + } + getIndex(topDict.charStringsOffset, &charStringsIdx, &parsedOk); + if (!parsedOk) { + return gFalse; + } + nGlyphs = charStringsIdx.len; + + // for CID fonts: read the FDSelect table + if (topDict.firstOp == 0x0c1e) { + readFDSelect(); + if (!parsedOk) { + return gFalse; + } + } + + // read the charset + if (!readCharset()) { + parsedOk = gFalse; + return gFalse; + } + + // for 8-bit fonts: build the encoding + if (topDict.firstOp != 0x0c14 && topDict.firstOp != 0x0c1e) { + buildEncoding(); + if (!parsedOk) { + return gFalse; + } + } + + return parsedOk; +} + +void FoFiType1C::readTopDict() { + Type1CIndexVal topDictPtr; + int pos; + + topDict.firstOp = -1; + topDict.versionSID = 0; + topDict.noticeSID = 0; + topDict.copyrightSID = 0; + topDict.fullNameSID = 0; + topDict.familyNameSID = 0; + topDict.weightSID = 0; + topDict.isFixedPitch = 0; + topDict.italicAngle = 0; + topDict.underlinePosition = -100; + topDict.underlineThickness = 50; + topDict.paintType = 0; + topDict.charstringType = 2; + topDict.fontMatrix[0] = 0.001; + topDict.fontMatrix[1] = 0; + topDict.fontMatrix[2] = 0; + topDict.fontMatrix[3] = 0.001; + topDict.fontMatrix[4] = 0; + topDict.fontMatrix[5] = 0; + topDict.hasFontMatrix = gFalse; + topDict.uniqueID = 0; + topDict.fontBBox[0] = 0; + topDict.fontBBox[1] = 0; + topDict.fontBBox[2] = 0; + topDict.fontBBox[3] = 0; + topDict.strokeWidth = 0; + topDict.charsetOffset = 0; + topDict.encodingOffset = 0; + topDict.charStringsOffset = 0; + topDict.privateSize = 0; + topDict.privateOffset = 0; + topDict.registrySID = 0; + topDict.orderingSID = 0; + topDict.supplement = 0; + topDict.fdArrayOffset = 0; + topDict.fdSelectOffset = 0; + + getIndexVal(&topDictIdx, 0, &topDictPtr, &parsedOk); + pos = topDictPtr.pos; + nOps = 0; + while (pos < topDictPtr.pos + topDictPtr.len) { + pos = getOp(pos, gFalse, &parsedOk); + if (!parsedOk) { + break; + } + if (!ops[nOps - 1].isNum) { + --nOps; // drop the operator + if (topDict.firstOp < 0) { + topDict.firstOp = ops[nOps].op; + } + switch (ops[nOps].op) { + case 0x0000: topDict.versionSID = (int)ops[0].num; break; + case 0x0001: topDict.noticeSID = (int)ops[0].num; break; + case 0x0c00: topDict.copyrightSID = (int)ops[0].num; break; + case 0x0002: topDict.fullNameSID = (int)ops[0].num; break; + case 0x0003: topDict.familyNameSID = (int)ops[0].num; break; + case 0x0004: topDict.weightSID = (int)ops[0].num; break; + case 0x0c01: topDict.isFixedPitch = (int)ops[0].num; break; + case 0x0c02: topDict.italicAngle = ops[0].num; break; + case 0x0c03: topDict.underlinePosition = ops[0].num; break; + case 0x0c04: topDict.underlineThickness = ops[0].num; break; + case 0x0c05: topDict.paintType = (int)ops[0].num; break; + case 0x0c06: topDict.charstringType = (int)ops[0].num; break; + case 0x0c07: topDict.fontMatrix[0] = ops[0].num; + topDict.fontMatrix[1] = ops[1].num; + topDict.fontMatrix[2] = ops[2].num; + topDict.fontMatrix[3] = ops[3].num; + topDict.fontMatrix[4] = ops[4].num; + topDict.fontMatrix[5] = ops[5].num; + topDict.hasFontMatrix = gTrue; break; + case 0x000d: topDict.uniqueID = (int)ops[0].num; break; + case 0x0005: topDict.fontBBox[0] = ops[0].num; + topDict.fontBBox[1] = ops[1].num; + topDict.fontBBox[2] = ops[2].num; + topDict.fontBBox[3] = ops[3].num; break; + case 0x0c08: topDict.strokeWidth = ops[0].num; break; + case 0x000f: topDict.charsetOffset = (int)ops[0].num; break; + case 0x0010: topDict.encodingOffset = (int)ops[0].num; break; + case 0x0011: topDict.charStringsOffset = (int)ops[0].num; break; + case 0x0012: topDict.privateSize = (int)ops[0].num; + topDict.privateOffset = (int)ops[1].num; break; + case 0x0c1e: topDict.registrySID = (int)ops[0].num; + topDict.orderingSID = (int)ops[1].num; + topDict.supplement = (int)ops[2].num; break; + case 0x0c24: topDict.fdArrayOffset = (int)ops[0].num; break; + case 0x0c25: topDict.fdSelectOffset = (int)ops[0].num; break; + } + nOps = 0; + } + } +} + +// Read a CID font dict (FD) - this pulls out the private dict +// pointer, and reads the private dict. It also pulls the FontMatrix +// (if any) out of the FD. +void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) { + int pos, pSize, pOffset; + double fontMatrix[6]; + GBool hasFontMatrix; + + hasFontMatrix = gFalse; + pSize = pOffset = 0; + pos = offset; + nOps = 0; + while (pos < offset + length) { + pos = getOp(pos, gFalse, &parsedOk); + if (!parsedOk) { + return; + } + if (!ops[nOps - 1].isNum) { + if (ops[nOps - 1].op == 0x0012) { + if (nOps < 3) { + parsedOk = gFalse; + return; + } + pSize = (int)ops[0].num; + pOffset = (int)ops[1].num; + break; + } else if (ops[nOps - 1].op == 0x0c07) { + fontMatrix[0] = ops[0].num; + fontMatrix[1] = ops[1].num; + fontMatrix[2] = ops[2].num; + fontMatrix[3] = ops[3].num; + fontMatrix[4] = ops[4].num; + fontMatrix[5] = ops[5].num; + hasFontMatrix = gTrue; + } + nOps = 0; + } + } + readPrivateDict(pOffset, pSize, pDict); + if (hasFontMatrix) { + pDict->fontMatrix[0] = fontMatrix[0]; + pDict->fontMatrix[1] = fontMatrix[1]; + pDict->fontMatrix[2] = fontMatrix[2]; + pDict->fontMatrix[3] = fontMatrix[3]; + pDict->fontMatrix[4] = fontMatrix[4]; + pDict->fontMatrix[5] = fontMatrix[5]; + pDict->hasFontMatrix = gTrue; + } +} + +void FoFiType1C::readPrivateDict(int offset, int length, + Type1CPrivateDict *pDict) { + int pos; + + pDict->hasFontMatrix = gFalse; + pDict->nBlueValues = 0; + pDict->nOtherBlues = 0; + pDict->nFamilyBlues = 0; + pDict->nFamilyOtherBlues = 0; + pDict->blueScale = 0.039625; + pDict->blueShift = 7; + pDict->blueFuzz = 1; + pDict->hasStdHW = gFalse; + pDict->hasStdVW = gFalse; + pDict->nStemSnapH = 0; + pDict->nStemSnapV = 0; + pDict->hasForceBold = gFalse; + pDict->forceBoldThreshold = 0; + pDict->languageGroup = 0; + pDict->expansionFactor = 0.06; + pDict->initialRandomSeed = 0; + pDict->subrsOffset = 0; + pDict->defaultWidthX = 0; + pDict->defaultWidthXFP = gFalse; + pDict->nominalWidthX = 0; + pDict->nominalWidthXFP = gFalse; + + // no dictionary + if (offset == 0 || length == 0) { + return; + } + + pos = offset; + nOps = 0; + while (pos < offset + length) { + pos = getOp(pos, gFalse, &parsedOk); + if (!parsedOk) { + break; + } + if (!ops[nOps - 1].isNum) { + --nOps; // drop the operator + switch (ops[nOps].op) { + case 0x0006: + pDict->nBlueValues = getDeltaIntArray(pDict->blueValues, + type1CMaxBlueValues); + break; + case 0x0007: + pDict->nOtherBlues = getDeltaIntArray(pDict->otherBlues, + type1CMaxOtherBlues); + break; + case 0x0008: + pDict->nFamilyBlues = getDeltaIntArray(pDict->familyBlues, + type1CMaxBlueValues); + break; + case 0x0009: + pDict->nFamilyOtherBlues = getDeltaIntArray(pDict->familyOtherBlues, + type1CMaxOtherBlues); + break; + case 0x0c09: + pDict->blueScale = ops[0].num; + break; + case 0x0c0a: + pDict->blueShift = (int)ops[0].num; + break; + case 0x0c0b: + pDict->blueFuzz = (int)ops[0].num; + break; + case 0x000a: + pDict->stdHW = ops[0].num; + pDict->hasStdHW = gTrue; + break; + case 0x000b: + pDict->stdVW = ops[0].num; + pDict->hasStdVW = gTrue; + break; + case 0x0c0c: + pDict->nStemSnapH = getDeltaFPArray(pDict->stemSnapH, + type1CMaxStemSnap); + break; + case 0x0c0d: + pDict->nStemSnapV = getDeltaFPArray(pDict->stemSnapV, + type1CMaxStemSnap); + break; + case 0x0c0e: + pDict->forceBold = ops[0].num != 0; + pDict->hasForceBold = gTrue; + break; + case 0x0c0f: + pDict->forceBoldThreshold = ops[0].num; + break; + case 0x0c11: + pDict->languageGroup = (int)ops[0].num; + break; + case 0x0c12: + pDict->expansionFactor = ops[0].num; + break; + case 0x0c13: + pDict->initialRandomSeed = (int)ops[0].num; + break; + case 0x0013: + pDict->subrsOffset = offset + (int)ops[0].num; + break; + case 0x0014: + pDict->defaultWidthX = ops[0].num; + pDict->defaultWidthXFP = ops[0].isFP; + break; + case 0x0015: + pDict->nominalWidthX = ops[0].num; + pDict->nominalWidthXFP = ops[0].isFP; + break; + } + nOps = 0; + } + } +} + +void FoFiType1C::readFDSelect() { + int fdSelectFmt, pos, nRanges, gid0, gid1, fd, i, j; + + fdSelect = (Guchar *)gmalloc(nGlyphs); + if (topDict.fdSelectOffset == 0) { + for (i = 0; i < nGlyphs; ++i) { + fdSelect[i] = 0; + } + } else { + pos = topDict.fdSelectOffset; + fdSelectFmt = getU8(pos++, &parsedOk); + if (!parsedOk) { + return; + } + if (fdSelectFmt == 0) { + if (!checkRegion(pos, nGlyphs)) { + parsedOk = gFalse; + return; + } + memcpy(fdSelect, file + pos, nGlyphs); + } else if (fdSelectFmt == 3) { + nRanges = getU16BE(pos, &parsedOk); + pos += 2; + gid0 = getU16BE(pos, &parsedOk); + pos += 2; + for (i = 1; i <= nRanges; ++i) { + fd = getU8(pos++, &parsedOk); + gid1 = getU16BE(pos, &parsedOk); + if (!parsedOk) { + return; + } + pos += 2; + if (gid0 > gid1 || gid1 > nGlyphs) { + //~ error(-1, "Bad FDSelect table in CID font"); + parsedOk = gFalse; + return; + } + for (j = gid0; j < gid1; ++j) { + fdSelect[j] = fd; + } + gid0 = gid1; + } + } else { + //~ error(-1, "Unknown FDSelect table format in CID font"); + for (i = 0; i < nGlyphs; ++i) { + fdSelect[i] = 0; + } + } + } +} + +void FoFiType1C::buildEncoding() { + char buf[256]; + int nCodes, nRanges, encFormat; + int pos, c, sid, nLeft, nSups, i, j; + + if (topDict.encodingOffset == 0) { + encoding = fofiType1StandardEncoding; + + } else if (topDict.encodingOffset == 1) { + encoding = fofiType1ExpertEncoding; + + } else { + encoding = (char **)gmallocn(256, sizeof(char *)); + for (i = 0; i < 256; ++i) { + encoding[i] = NULL; + } + pos = topDict.encodingOffset; + encFormat = getU8(pos++, &parsedOk); + if (!parsedOk) { + return; + } + if ((encFormat & 0x7f) == 0) { + nCodes = 1 + getU8(pos++, &parsedOk); + if (!parsedOk) { + return; + } + if (nCodes > nGlyphs) { + nCodes = nGlyphs; + } + for (i = 1; i < nCodes; ++i) { + c = getU8(pos++, &parsedOk); + if (!parsedOk) { + return; + } + if (encoding[c]) { + gfree(encoding[c]); + } + encoding[c] = copyString(getString(charset[i], buf, &parsedOk)); + } + } else if ((encFormat & 0x7f) == 1) { + nRanges = getU8(pos++, &parsedOk); + if (!parsedOk) { + return; + } + nCodes = 1; + for (i = 0; i < nRanges; ++i) { + c = getU8(pos++, &parsedOk); + nLeft = getU8(pos++, &parsedOk); + if (!parsedOk) { + return; + } + for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) { + if (c < 256) { + if (encoding[c]) { + gfree(encoding[c]); + } + encoding[c] = copyString(getString(charset[nCodes], buf, + &parsedOk)); + } + ++nCodes; + ++c; + } + } + } + if (encFormat & 0x80) { + nSups = getU8(pos++, &parsedOk); + if (!parsedOk) { + return; + } + for (i = 0; i < nSups; ++i) { + c = getU8(pos++, &parsedOk);; + if (!parsedOk) { + return;; + } + sid = getU16BE(pos, &parsedOk); + pos += 2; + if (!parsedOk) { + return; + } + if (encoding[c]) { + gfree(encoding[c]); + } + encoding[c] = copyString(getString(sid, buf, &parsedOk)); + } + } + } +} + +GBool FoFiType1C::readCharset() { + int charsetFormat, c, pos; + int nLeft, i, j; + + if (topDict.charsetOffset == 0) { + charset = fofiType1CISOAdobeCharset; + } else if (topDict.charsetOffset == 1) { + charset = fofiType1CExpertCharset; + } else if (topDict.charsetOffset == 2) { + charset = fofiType1CExpertSubsetCharset; + } else { + charset = (Gushort *)gmallocn(nGlyphs, sizeof(Gushort)); + for (i = 0; i < nGlyphs; ++i) { + charset[i] = 0; + } + pos = topDict.charsetOffset; + charsetFormat = getU8(pos++, &parsedOk); + if (charsetFormat == 0) { + for (i = 1; i < nGlyphs; ++i) { + charset[i] = (Gushort)getU16BE(pos, &parsedOk); + pos += 2; + if (!parsedOk) { + break; + } + } + } else if (charsetFormat == 1) { + i = 1; + while (i < nGlyphs) { + c = getU16BE(pos, &parsedOk); + pos += 2; + nLeft = getU8(pos++, &parsedOk); + if (!parsedOk) { + break; + } + for (j = 0; j <= nLeft && i < nGlyphs; ++j) { + charset[i++] = (Gushort)c++; + } + } + } else if (charsetFormat == 2) { + i = 1; + while (i < nGlyphs) { + c = getU16BE(pos, &parsedOk); + pos += 2; + nLeft = getU16BE(pos, &parsedOk); + pos += 2; + if (!parsedOk) { + break; + } + for (j = 0; j <= nLeft && i < nGlyphs; ++j) { + charset[i++] = (Gushort)c++; + } + } + } + if (!parsedOk) { + gfree(charset); + charset = NULL; + return gFalse; + } + } + return gTrue; +} + +int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) { + static char nybChars[16] = "0123456789.ee -"; + Type1COp op; + char buf[65]; + int b0, b1, nyb0, nyb1, x, i; + + b0 = getU8(pos++, ok); + op.isNum = gTrue; + op.isFP = gFalse; + + if (b0 == 28) { + x = getU8(pos++, ok); + x = (x << 8) | getU8(pos++, ok); + if (x & 0x8000) { + x |= ~0xffff; + } + op.num = x; + + } else if (!charstring && b0 == 29) { + x = getU8(pos++, ok); + x = (x << 8) | getU8(pos++, ok); + x = (x << 8) | getU8(pos++, ok); + x = (x << 8) | getU8(pos++, ok); + if (x & 0x80000000) { + x |= ~0xffffffff; + } + op.num = x; + + } else if (!charstring && b0 == 30) { + i = 0; + do { + b1 = getU8(pos++, ok); + nyb0 = b1 >> 4; + nyb1 = b1 & 0x0f; + if (nyb0 == 0xf) { + break; + } + buf[i++] = nybChars[nyb0]; + if (i == 64) { + break; + } + if (nyb0 == 0xc) { + buf[i++] = '-'; + } + if (i == 64) { + break; + } + if (nyb1 == 0xf) { + break; + } + buf[i++] = nybChars[nyb1]; + if (i == 64) { + break; + } + if (nyb1 == 0xc) { + buf[i++] = '-'; + } + } while (i < 64); + buf[i] = '\0'; + op.num = atof(buf); + op.isFP = gTrue; + + } else if (b0 >= 32 && b0 <= 246) { + op.num = b0 - 139; + + } else if (b0 >= 247 && b0 <= 250) { + op.num = ((b0 - 247) << 8) + getU8(pos++, ok) + 108; + + } else if (b0 >= 251 && b0 <= 254) { + op.num = -((b0 - 251) << 8) - getU8(pos++, ok) - 108; + + } else if (charstring && b0 == 255) { + x = getU8(pos++, ok); + x = (x << 8) | getU8(pos++, ok); + x = (x << 8) | getU8(pos++, ok); + x = (x << 8) | getU8(pos++, ok); + if (x & 0x80000000) { + x |= ~0xffffffff; + } + op.num = (double)x / 65536.0; + op.isFP = gTrue; + + } else if (b0 == 12) { + op.isNum = gFalse; + op.op = 0x0c00 + getU8(pos++, ok); + + } else { + op.isNum = gFalse; + op.op = b0; + } + + if (nOps < 49) { + ops[nOps++] = op; + } + + return pos; +} + +// Convert the delta-encoded ops array to an array of ints. +int FoFiType1C::getDeltaIntArray(int *arr, int maxLen) { + int x; + int n, i; + + if ((n = nOps) > maxLen) { + n = maxLen; + } + x = 0; + for (i = 0; i < n; ++i) { + x += (int)ops[i].num; + arr[i] = x; + } + return n; +} + +// Convert the delta-encoded ops array to an array of doubles. +int FoFiType1C::getDeltaFPArray(double *arr, int maxLen) { + double x; + int n, i; + + if ((n = nOps) > maxLen) { + n = maxLen; + } + x = 0; + for (i = 0; i < n; ++i) { + x += ops[i].num; + arr[i] = x; + } + return n; +} + +void FoFiType1C::getIndex(int pos, Type1CIndex *idx, GBool *ok) { + idx->pos = pos; + idx->len = getU16BE(pos, ok); + if (idx->len == 0) { + // empty indexes are legal and contain just the length field + idx->offSize = 0; + idx->startPos = idx->endPos = pos + 2; + } else { + idx->offSize = getU8(pos + 2, ok); + if (idx->offSize < 1 || idx->offSize > 4) { + *ok = gFalse; + } + idx->startPos = pos + 3 + (idx->len + 1) * idx->offSize - 1; + if (idx->startPos < 0 || idx->startPos >= len) { + *ok = gFalse; + } + idx->endPos = idx->startPos + getUVarBE(pos + 3 + idx->len * idx->offSize, + idx->offSize, ok); + if (idx->endPos < idx->startPos || idx->endPos > len) { + *ok = gFalse; + } + } +} + +void FoFiType1C::getIndexVal(Type1CIndex *idx, int i, + Type1CIndexVal *val, GBool *ok) { + int pos0, pos1; + + if (i < 0 || i >= idx->len) { + *ok = gFalse; + return; + } + pos0 = idx->startPos + getUVarBE(idx->pos + 3 + i * idx->offSize, + idx->offSize, ok); + pos1 = idx->startPos + getUVarBE(idx->pos + 3 + (i + 1) * idx->offSize, + idx->offSize, ok); + if (pos0 < idx->startPos || pos0 > idx->endPos || + pos1 <= idx->startPos || pos1 > idx->endPos || + pos1 < pos0) { + *ok = gFalse; + } + val->pos = pos0; + val->len = pos1 - pos0; +} + +char *FoFiType1C::getString(int sid, char *buf, GBool *ok) { + Type1CIndexVal val; + int n; + + if (sid < 391) { + strcpy(buf, fofiType1CStdStrings[sid]); + } else { + sid -= 391; + getIndexVal(&stringIdx, sid, &val, ok); + if (*ok) { + if ((n = val.len) > 255) { + n = 255; + } + strncpy(buf, (char *)&file[val.pos], n); + buf[n] = '\0'; + } else { + buf[0] = '\0'; + } + } + return buf; +} diff --git a/rosapps/smartpdf/poppler/fofi/FoFiType1C.h b/rosapps/smartpdf/poppler/fofi/FoFiType1C.h new file mode 100644 index 00000000000..ce4decdc5e1 --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/FoFiType1C.h @@ -0,0 +1,230 @@ +//======================================================================== +// +// FoFiType1C.h +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FOFITYPE1C_H +#define FOFITYPE1C_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "FoFiBase.h" + +class GooString; + +//------------------------------------------------------------------------ + +struct Type1CIndex { + int pos; // absolute position in file + int len; // length (number of entries) + int offSize; // offset size + int startPos; // position of start of index data - 1 + int endPos; // position one byte past end of the index +}; + +struct Type1CIndexVal { + int pos; // absolute position in file + int len; // length, in bytes +}; + +struct Type1CTopDict { + int firstOp; + + int versionSID; + int noticeSID; + int copyrightSID; + int fullNameSID; + int familyNameSID; + int weightSID; + int isFixedPitch; + double italicAngle; + double underlinePosition; + double underlineThickness; + int paintType; + int charstringType; + double fontMatrix[6]; + GBool hasFontMatrix; // CID fonts are allowed to put their + // FontMatrix in the FD instead of the + // top dict + int uniqueID; + double fontBBox[4]; + double strokeWidth; + int charsetOffset; + int encodingOffset; + int charStringsOffset; + int privateSize; + int privateOffset; + + // CIDFont entries + int registrySID; + int orderingSID; + int supplement; + int fdArrayOffset; + int fdSelectOffset; +}; + +#define type1CMaxBlueValues 14 +#define type1CMaxOtherBlues 10 +#define type1CMaxStemSnap 12 + +struct Type1CPrivateDict { + double fontMatrix[6]; + GBool hasFontMatrix; + int blueValues[type1CMaxBlueValues]; + int nBlueValues; + int otherBlues[type1CMaxOtherBlues]; + int nOtherBlues; + int familyBlues[type1CMaxBlueValues]; + int nFamilyBlues; + int familyOtherBlues[type1CMaxOtherBlues]; + int nFamilyOtherBlues; + double blueScale; + int blueShift; + int blueFuzz; + double stdHW; + GBool hasStdHW; + double stdVW; + GBool hasStdVW; + double stemSnapH[type1CMaxStemSnap]; + int nStemSnapH; + double stemSnapV[type1CMaxStemSnap]; + int nStemSnapV; + GBool forceBold; + GBool hasForceBold; + double forceBoldThreshold; + int languageGroup; + double expansionFactor; + int initialRandomSeed; + int subrsOffset; + double defaultWidthX; + GBool defaultWidthXFP; + double nominalWidthX; + GBool nominalWidthXFP; +}; + +struct Type1COp { + GBool isNum; // true -> number, false -> operator + GBool isFP; // true -> floating point number, false -> int + union { + double num; // if num is true + int op; // if num is false + }; +}; + +struct Type1CEexecBuf { + FoFiOutputFunc outputFunc; + void *outputStream; + GBool ascii; // ASCII encoding? + Gushort r1; // eexec encryption key + int line; // number of eexec chars left on current line +}; + +//------------------------------------------------------------------------ +// FoFiType1C +//------------------------------------------------------------------------ + +class FoFiType1C: public FoFiBase { +public: + + // Create a FoFiType1C object from a memory buffer. + static FoFiType1C *make(char *fileA, int lenA); + + // Create a FoFiType1C object from a file on disk. + static FoFiType1C *load(char *fileName); + + FoFiType1C(char *fileA, int lenA, GBool freeFileDataA); + virtual ~FoFiType1C(); + + // Return the font name. + char *getName(); + + // Return the encoding, as an array of 256 names (any of which may + // be NULL). This is only useful with 8-bit fonts. + char **getEncoding(); + + // Return the mapping from CIDs to GIDs, and return the number of + // CIDs in *. This is only useful for CID fonts. + Gushort *getCIDToGIDMap(int *nCIDs); + + // Convert to a Type 1 font, suitable for embedding in a PostScript + // file. This is only useful with 8-bit fonts. If is + // not NULL, it will be used in place of the encoding in the Type 1C + // font. If is true the eexec section will be hex-encoded, + // otherwise it will be left as binary data. + void convertToType1(char **newEncoding, GBool ascii, + FoFiOutputFunc outputFunc, void *outputStream); + + // Convert to a Type 0 CIDFont, suitable for embedding in a + // PostScript file. will be used as the PostScript font + // name. + void convertToCIDType0(char *psName, + FoFiOutputFunc outputFunc, void *outputStream); + + // Convert to a Type 0 (but non-CID) composite font, suitable for + // embedding in a PostScript file. will be used as the + // PostScript font name. + void convertToType0(char *psName, + FoFiOutputFunc outputFunc, void *outputStream); + +private: + + void eexecCvtGlyph(Type1CEexecBuf *eb, char *glyphName, + int offset, int nBytes, + Type1CIndex *subrIdx, + Type1CPrivateDict *pDict); + void cvtGlyph(int offset, int nBytes, GooString *charBuf, + Type1CIndex *subrIdx, Type1CPrivateDict *pDict, + GBool top); + void cvtGlyphWidth(GBool useOp, GooString *charBuf, + Type1CPrivateDict *pDict); + void cvtNum(double x, GBool isFP, GooString *charBuf); + void eexecWrite(Type1CEexecBuf *eb, char *s); + void eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n); + GBool parse(); + void readTopDict(); + void readFD(int offset, int length, Type1CPrivateDict *pDict); + void readPrivateDict(int offset, int length, Type1CPrivateDict *pDict); + void readFDSelect(); + void buildEncoding(); + GBool readCharset(); + int getOp(int pos, GBool charstring, GBool *ok); + int getDeltaIntArray(int *arr, int maxLen); + int getDeltaFPArray(double *arr, int maxLen); + void getIndex(int pos, Type1CIndex *idx, GBool *ok); + void getIndexVal(Type1CIndex *idx, int i, Type1CIndexVal *val, GBool *ok); + char *getString(int sid, char *buf, GBool *ok); + + GooString *name; + char **encoding; + + Type1CIndex nameIdx; + Type1CIndex topDictIdx; + Type1CIndex stringIdx; + Type1CIndex gsubrIdx; + Type1CIndex charStringsIdx; + + Type1CTopDict topDict; + Type1CPrivateDict *privateDicts; + + int nGlyphs; + int nFDs; + Guchar *fdSelect; + Gushort *charset; + int gsubrBias; + + GBool parsedOk; + + Type1COp ops[49]; // operands and operator + int nOps; // number of operands + int nHints; // number of hints for the current glyph + GBool firstOp; // true if we haven't hit the first op yet + GBool openPath; // true if there is an unclosed path +}; + +#endif diff --git a/rosapps/smartpdf/poppler/fofi/Makefile.am b/rosapps/smartpdf/poppler/fofi/Makefile.am new file mode 100644 index 00000000000..78cf3a8ad79 --- /dev/null +++ b/rosapps/smartpdf/poppler/fofi/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = \ + -I$(top_srcdir) + +noinst_LTLIBRARIES = libfofi.la + +libfofi_la_SOURCES = \ + FoFiBase.cc \ + FoFiBase.h \ + FoFiEncodings.cc \ + FoFiEncodings.h \ + FoFiTrueType.cc \ + FoFiTrueType.h \ + FoFiType1.cc \ + FoFiType1.h \ + FoFiType1C.cc \ + FoFiType1C.h diff --git a/rosapps/smartpdf/poppler/goo/FastAlloc.cc b/rosapps/smartpdf/poppler/goo/FastAlloc.cc new file mode 100644 index 00000000000..269070f4cea --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/FastAlloc.cc @@ -0,0 +1,321 @@ +/* Written by: Krzysztof Kowalczyk (http://blog.kowalczyk.info) + License: Public Domain (http://creativecommons.org/licenses/publicdomain/) + Take all the code you want, I'll just write more. +*/ + +#include "FastAlloc.h" +#include +#include "FastFixedAllocator.h" +#include "GooMutex.h" +#include "gmem.h" +#include "gtypes.h" +#include +#include +#include + +//#define DO_MEM_STATS 1 +#ifdef DO_MEM_STATS + +#define ALLOCS_AT_A_TIME 1024 + +typedef struct { + size_t size; + void * p; +} AllocRecord; + +static AllocRecord gAllocs[ALLOCS_AT_A_TIME]; +static int gAllocsCount = 0; + +#define ITS_A_FREE (size_t)-1 + +#define MAX_BUF_FILENAME_SIZE 256 +#define LOG_BUF_SIZE 2048 + +static char gLogFileName[MAX_BUF_FILENAME_SIZE] = {0}; +static char gLogBuf[LOG_BUF_SIZE]; +static const char * gLogFileNamePattern = "fast_alloc_%d.txt"; +static int gLogBufUsed = 0; + +#ifdef MULTITHREADED +GooMutex logMutex; +#endif + +static GBool FileExists(const char *fileName) +{ + struct stat buf; + int res; + + res = stat(fileName, &buf); + if (0 != res) + return gFalse; + return gTrue; +} + +void LogSetFileNamePattern(const char *fileNamePattern) +{ + assert(!gLogFileNamePattern); + gLogFileNamePattern = fileNamePattern; +} + +static GBool LogGenUniqueFile(void) +{ + static GBool tried = gFalse; + int n = 0; + + assert(gLogFileNamePattern); + if (gLogFileName[0]) + return gTrue; /* already generated */ + if (tried) + return gFalse; + tried = gTrue; + while (n < 999) { + sprintf(gLogFileName, gLogFileNamePattern, n); + if (!FileExists(gLogFileName)) + return gTrue; + ++n; + } + gLogFileName[0] = 0; + assert(0); + return gFalse; +} + +static void LogAllocs(void) +{ + FILE * fp; + int i; + char buf[256]; + int len; + + assert(gAllocsCount <= ALLOCS_AT_A_TIME); + if (0 == gAllocsCount) + return; + + if (!LogGenUniqueFile()) + return; + fp = fopen(gLogFileName, "a"); + if (!fp) + return; + + for (i = 0; i < gAllocsCount; i++) { + if (ITS_A_FREE == gAllocs[i].size) { + len = sprintf(buf, "- 0x%p\n", gAllocs[i].p); + } else { + len = sprintf(buf, "+ 0x%p 0x%x\n", gAllocs[i].p, gAllocs[i].size); + } + assert(len >= 0); + if (len > 0) + fwrite(buf, 1, len, fp); + } + fclose(fp); +} + +void RecordEntry(void *p, size_t size) +{ +#ifdef MULTITHREADED + gLockMutex(&logMutex); +#endif + if (ALLOCS_AT_A_TIME == gAllocsCount) { + LogAllocs(); + gAllocsCount = 0; + } + assert(gAllocsCount < ALLOCS_AT_A_TIME); + gAllocs[gAllocsCount].size = size; + gAllocs[gAllocsCount].p = p; + ++gAllocsCount; +#ifdef MULTITHREADED + gUnlockMutex(&logMutex); +#endif +} + +void RecordMalloc(void *p, size_t size) +{ + assert(size != ITS_A_FREE); + if (p) + RecordEntry(p, size); +} + +void RecordFree(void *p) +{ + if (p) + RecordEntry(p, ITS_A_FREE); +} + +void RecordRealloc(void *oldP, void *newP, size_t newSize) +{ + RecordFree(oldP); + RecordMalloc(newP, newSize); +} + +/* To make sure that we log everything without explicitly calling + LogAllocs() at the end, this class' destructor should be called by C++ + runtime at the end of program */ +class EnsureLastAllocsLogged { +public: + EnsureLastAllocsLogged() { + } + ~EnsureLastAllocsLogged(void) { + LogAllocs(); + } +}; +static EnsureLastAllocsLogged gEnsureLastAllocsLogged; + +#ifdef MULTITHREADED +static MutexAutoInitDestroy gLogMutexInit(&logMutex); +#endif + +#else +#define RecordMalloc(p, size) +#define RecordFree(p) +#define RecordRealloc(oldP, newP, newSize) +#endif + +#ifdef USE_FAST_ALLOC +void malloc_hook(void *p, size_t size) +{ + RecordMalloc(p, size); +} + +void free_hook(void *p) +{ + RecordFree(p); +} + +void realloc_hook(void *oldP, void *newP, size_t newSize) +{ + RecordRealloc(oldP, newP, newSize); +} + +#define MAGIC_COOKIE_FOR_0_16 (FreeListNode*)0xa1b2c3d4 +#define MAGIC_COOKIE_FOR_32 (FreeListNode*)0x11326374 +#define MAGIC_COOKIE_FOR_88 (FreeListNode*)0x91a2c8d9 +#define MAGIC_COOKIE_FOR_20_24 (FreeListNode*)0x51783c4d + +/* Acording to my profiles, covering allocations in ranges <0-16>, <20-24>, + 32 and 88 covers 89% allocations (in scenario I've measured which was + loading a PDF document PDFReference16.pdf (available at adobe website). + They're also ordered by frequence (sizes most frequently allocated first) */ +#define ALLOCATORS_COUNT 4 +static FastFixedAllocator gAllocators[ALLOCATORS_COUNT] = { + FastFixedAllocator(0,16,4096,MAGIC_COOKIE_FOR_0_16), + FastFixedAllocator(32,32,1024,MAGIC_COOKIE_FOR_32), + FastFixedAllocator(88,88,1024,MAGIC_COOKIE_FOR_88), + FastFixedAllocator(20,24,1024,MAGIC_COOKIE_FOR_20_24), +}; + +/* Return an allocator for a given size or NULL if doesn't exist. + Speed of this function is critical so it was inlined */ +static inline FastFixedAllocator *GetAllocatorForSize(size_t size) +{ + if ((size > 0) && (size <= 16)) + return &gAllocators[0]; + else if (32 == size) + return &gAllocators[1]; + else if (88 == size) + return &gAllocators[2]; + else if ((size >= 20) && (size <= 24)) + return &gAllocators[3]; + else + return NULL; +} + +/* Return an allocator that allocated this pointer or NULL if comes + from system alloc. + Speed of this function is critical so it was inlined */ +static inline FastFixedAllocator *GetAllocatorForPointer(void *p) +{ + FreeListNode * freeListNode; + if (!p) + return NULL; + freeListNode = (FreeListNode*)((char*)p - sizeof(FreeListNode)); + if (MAGIC_COOKIE_FOR_0_16 == freeListNode->next) { + if (gAllocators[0].AllocatedPointerFast(p)) { + return &gAllocators[0]; + } + } else if (MAGIC_COOKIE_FOR_32 == freeListNode->next) { + if (gAllocators[1].AllocatedPointerFast(p)) { + return &gAllocators[1]; + } + } else if (MAGIC_COOKIE_FOR_88 == freeListNode->next) { + if (gAllocators[2].AllocatedPointerFast(p)) { + return &gAllocators[2]; + } + } else if (MAGIC_COOKIE_FOR_20_24 == freeListNode->next) { + if (gAllocators[3].AllocatedPointerFast(p)) { + return &gAllocators[3]; + } + } + return NULL; +} + +void *fast_malloc(size_t size) +{ + FastFixedAllocator *allocator; + void * p = NULL; + + allocator = GetAllocatorForSize(size); + if (allocator) { + p = allocator->Alloc(size); + } + + if (!p) + p = malloc(size); + malloc_hook(p, size); + return p; +} + +void fast_free(void *p) +{ + FastFixedAllocator *allocator; + free_hook(p); + allocator = GetAllocatorForPointer(p); + if (allocator) { + allocator->Free(p); + } else + free(p); +} + +void *fast_realloc(void *oldP, size_t size) +{ + FastFixedAllocator * allocator; + void * newP = NULL; + size_t oldSize; + + if (!oldP) + return fast_malloc(size); + + allocator = GetAllocatorForPointer(oldP); + if (allocator) { + if (size > 0) { + oldSize = allocator->AllocationSize(); + if (size > oldSize) { + newP = fast_malloc(size); + memcpy(newP, oldP, oldSize); + } else + newP = oldP; + } + allocator->Free(oldP); + } + else + newP = realloc(oldP, size); + realloc_hook(oldP, newP, size); + return newP; +} +#endif + +#ifndef DEBUG_MEM +void *operator new(size_t size) { + return gmalloc(size); +} + +void *operator new[](size_t size) { + return gmalloc(size); +} + +void operator delete(void *p) { + gfree(p); +} + +void operator delete[](void *p) { + gfree(p); +} +#endif diff --git a/rosapps/smartpdf/poppler/goo/FastAlloc.h b/rosapps/smartpdf/poppler/goo/FastAlloc.h new file mode 100644 index 00000000000..d53d853d81b --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/FastAlloc.h @@ -0,0 +1,28 @@ +#ifndef FAST_ALLOC_H_ +#define FAST_ALLOC_H_ + +/* Written by: Krzysztof Kowalczyk (http://blog.kowalczyk.info) + License: Public Domain (http://creativecommons.org/licenses/publicdomain/) + Take all the code you want, I'll just write more. +*/ + +#ifdef _WIN32 +#include // size_t on windows +#else +#include // size_t +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +void * fast_malloc(size_t size); +void fast_free(void *p); +void * fast_realloc(void *oldP, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/poppler/goo/FastFixedAllocator.cc b/rosapps/smartpdf/poppler/goo/FastFixedAllocator.cc new file mode 100644 index 00000000000..80bb293353e --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/FastFixedAllocator.cc @@ -0,0 +1,148 @@ +/* Written by: Krzysztof Kowalczyk (http://blog.kowalczyk.info) + License: Public Domain (http://creativecommons.org/licenses/publicdomain/) + Take all the code you want, I'll just write more. +*/ + +#include "FastFixedAllocator.h" +#include +#include + +void *FastFixedAllocator::Alloc(size_t size) { + char * p; + void * toReturn = NULL; + ChunkBlockNode * currChunk; + int totalBlockSize; + bool needsToAllocateNewBlock; + FreeListNode * freeListNode; + +#ifdef MULTITHREADED + gLockMutex(&allocMutex); +#endif + + /* can we satisfy the allocation from the free list ? */ + if (freeListRoot) { + freeListNode = freeListRoot; + freeListRoot = freeListRoot->next; + freeListNode->next = magicCookie; /* mark as being used */ + p = (char*)freeListNode; + toReturn = (void*) (p + sizeof(FreeListNode)); +#ifdef FAST_ALLOC_STATS + totalAllocs++; + allocsFromFreeList++; +#endif + goto Exit; + } + + /* can we satisfy the allocation from the last allocated block? + We only have to look at the last allocated chunk since + the lack of free list entries means all data in chunks is currently used */ + currChunk = chunkBlockListRoot; + needsToAllocateNewBlock = true; + +#ifdef FAST_ALLOC_STATS + totalAllocs++; +#endif + + if (currChunk) { + assert(currChunk->chunksUsed >= 0); + assert(currChunk->chunksUsed <= chunksAtATime); + if (currChunk->chunksUsed < chunksAtATime) { + /* we still have space in the last allocated block */ + needsToAllocateNewBlock = false; + } + } + + if (needsToAllocateNewBlock) { + totalBlockSize = GetBlockSize(); + currChunk = (ChunkBlockNode*)malloc(totalBlockSize); + if (!currChunk) + goto Exit; + currChunk->chunksUsed = 0; + currChunk->next = chunkBlockListRoot; + chunkBlockListRoot = currChunk; + } +#ifdef FAST_ALLOC_STATS + else { + allocsFromBlock++; + } +#endif + + p = (char*)currChunk; + p += sizeof(ChunkBlockNode); + p += (GetTotalChunkSize() * currChunk->chunksUsed); + freeListNode = (FreeListNode*)p; + freeListNode->next = magicCookie; /* mark as being used */ + toReturn = (void*)(p + sizeof(FreeListNode)); + currChunk->chunksUsed++; + assert(currChunk->chunksUsed <= chunksAtATime); + +Exit: +#ifdef MULTITHREADED + gUnlockMutex(&allocMutex); +#endif + return toReturn; +} + +void FastFixedAllocator::Free(void *p) { + FreeListNode * freeListNode; + + assert(AllocatedPointerSlow(p)); + +#ifdef MULTITHREADED + gLockMutex(&allocMutex); +#endif + freeListNode = (FreeListNode*)((char*)p - sizeof(FreeListNode)); + assert(magicCookie == freeListNode->next); + freeListNode->next = freeListRoot; + freeListRoot = freeListNode; +#ifdef MULTITHREADED + gUnlockMutex(&allocMutex); +#endif +} + +/* Return true if is a pointer that belongs to memory that we allocated + (and is currently used; doesn't work for pointers in our free list + This check must be fast. */ +bool FastFixedAllocator::AllocatedPointerSlow(void *pA) { + FreeListNode * freeListNode; + ChunkBlockNode * currChunk; + char * p, *blockStart, *blockEnd; + + if (!pA) + return false; + + /* note: this might actually fail on some systems because we're looking + at a memory of unknown origin. If the memory before the pointer is not + accessible, we'll crash. Some debugging memory allocators use a trick + of protecting memory right before and after the allocated chunk, to + catch accesses beyond allocated chunks. + This shouldn't be a problem when running on regular Unix or Windows system. + I don't have a better idea on how to make this check fast. */ + freeListNode = (FreeListNode*)((char*)pA - sizeof(FreeListNode)); + if (magicCookie != freeListNode->next) { + /* no magic value so it's not a pointer we allocated */ + return false; + } + + /* It's possible (although highly unlikely) that a random pointer will have + our magic value as well, so we still have to traverse all blocks to see + if a pointer lies within memory allocated for blocks */ + p = (char*)pA - sizeof(FreeListNode); + currChunk = chunkBlockListRoot; + while (currChunk) { + blockStart = (char*)currChunk; + blockEnd = blockStart + GetBlockSize(); + blockStart += sizeof(ChunkBlockNode); + if ((p >= blockStart) && (p < blockEnd)) { +#ifdef DEBUG + /* something's wrong if it looks like allocated by us but not on a proper + boundary */ + unsigned long pos = (unsigned long)(p - blockStart); + assert(0 == pos % GetTotalChunkSize()); +#endif + return true; + } + currChunk = currChunk->next; + } + return false; +} diff --git a/rosapps/smartpdf/poppler/goo/FastFixedAllocator.h b/rosapps/smartpdf/poppler/goo/FastFixedAllocator.h new file mode 100644 index 00000000000..0d3f68a4c80 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/FastFixedAllocator.h @@ -0,0 +1,162 @@ +#ifndef FAST_FIXED_ALLOCATOR_H_ +#define FAST_FIXED_ALLOCATOR_H_ + +/* Written by: Krzysztof Kowalczyk (http://blog.kowalczyk.info) + License: Public Domain (http://creativecommons.org/licenses/publicdomain/) + Take all the code you want, I'll just write more. +*/ + +#include +#include +#include "GooMutex.h" + +/* +This is a a specialized allocator design to allocate large numbers of small +objects (chunks) quickly. + +It does that by employing two techniques: +- allocating blocks of objects (chunks) at a time +- a free list of all freed allocations + +By allocating memory in blocks it makes less trips to system memory allocator. + +By using free list it can satisfy new allocations from memory that has been +previously allocated and freed. This helps especially if there's a lot of +trashing (allocating/freeing). + +It adds sizeof(char*) overhead for each allocation i.e. on 32-bit machine +allocating 4 byte chunks uses 8 bytes. The overhead is for storing a pointer +to the next free chunk if the chunk is on free list. + +This is ok, because we actually use less memory than most OS allocators, since: +- OS allocators also have overhead for keeping track of allocation, which is + likely to be bigger than sizeof(char*) +- OS allocators round allocation (e.g. to 16-byte boundary on Ubuntu 6 libc) +*/ + +/* Define if you want statistics about how many allocations there were and + what is our hit ratio (number of allocations served from free list and + from existing block of memory) */ +#define FAST_ALLOC_STATS 1 + +/* We prepend this to every allocated chunk */ +typedef struct FreeListNode { + struct FreeListNode *next; +} FreeListNode; + +/* Keeps info about a bunch of chunks allocated as one block */ +typedef struct ChunkBlockNode { + struct ChunkBlockNode * next; + int chunksUsed; + /* data comes inline here */ +} ChunkBlockNode; + +class FastFixedAllocator { + +public: + FastFixedAllocator(size_t chunkSizeLowA, size_t chunkSizeHighA, + int chunksAtATimeA, FreeListNode *magicCookieA) : + chunkSizeLow(chunkSizeLowA), + chunkSizeHigh(chunkSizeHighA), + magicCookie(magicCookieA), + chunksAtATime(chunksAtATimeA), + freeListRoot(NULL), chunkBlockListRoot(NULL) +#ifdef FAST_ALLOC_STATS + , totalAllocs(0), allocsFromFreeList(0), allocsFromBlock(0) +#endif + { +#ifdef MULTITHREADED + gInitMutex(&allocMutex); +#endif + } + ~FastFixedAllocator(void) { +#ifdef MULTITHREADED + gDestroyMutex(&allocMutex); +#endif + } + + bool HandlesSize(size_t size) { + if ((size <= chunkSizeHigh) && (size >= chunkSizeLow)) + return true; + return false; + } + + size_t AllocationSize(void) { return chunkSizeHigh; } + void * Alloc(size_t size); + void Free(void* p); + bool AllocatedPointerSlow(void *pA); + + /* like AllcoatedPointerSlow but assumes that NULL check and magicCookie + check has already been performed. Also, forced inline by being defined + in a header file. Speed of this function is critical to the allocator */ + bool AllocatedPointerFast(void *pA) { + ChunkBlockNode * currChunk; + char * p, *blockStart, *blockEnd; + +#if DEBUG + assert(pA); + FreeListNode * freeListNode; + freeListNode = (FreeListNode*)((char*)pA - sizeof(FreeListNode)); + assert(magicCookie == freeListNode->next); +#endif + + p = (char*)pA - sizeof(FreeListNode); + currChunk = chunkBlockListRoot; + while (currChunk) { + blockStart = (char*)currChunk; + blockEnd = blockStart + GetBlockSize(); + blockStart += sizeof(ChunkBlockNode); + if ((p >= blockStart) && (p < blockEnd)) { + #ifdef DEBUG + /* something's wrong if it looks like allocated by us but not on a proper + boundary */ + unsigned long pos = (unsigned long)(p - blockStart); + assert(0 == pos % GetTotalChunkSize()); + #endif + return true; + } + currChunk = currChunk->next; + } + return false; +} + +private: + int GetTotalChunkSize(void) { + return sizeof(FreeListNode) + chunkSizeHigh; + } + int GetBlockSize(void) { + return sizeof(ChunkBlockNode) + (GetTotalChunkSize() * chunksAtATime); + } + + /* This allocator handles allocations for allocation sizes + in range */ + size_t chunkSizeLow; + size_t chunkSizeHigh; + + /* We need a relly fast check for deciding whether a given pointer was allocated + by us or not, so that we know we can put it on a free list when it's being + freed. + We do that by putting a magic value ( in the place used to store + pointer to next free chunk when this value is on a free list. That way + if the magic value is not there, we know it's not pointer to memory we + allocated (should be majority of cases). + for each instance should be unique (otherwise it'll be slow) + */ + FreeListNode * magicCookie; + + int chunksAtATime; + FreeListNode * freeListRoot; + ChunkBlockNode * chunkBlockListRoot; + +#ifdef FAST_ALLOC_STATS + /* gather statistics about allocations */ + int totalAllocs; + int allocsFromFreeList; + int allocsFromBlock; +#endif +#ifdef MULTITHREADED + GooMutex allocMutex; +#endif +}; + +#endif diff --git a/rosapps/smartpdf/poppler/goo/FixedPoint.cc b/rosapps/smartpdf/poppler/goo/FixedPoint.cc new file mode 100644 index 00000000000..1dd669bd666 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/FixedPoint.cc @@ -0,0 +1,95 @@ +//======================================================================== +// +// FixedPoint.cc +// +// Fixed point type, with C++ operators. +// +// Copyright 2004 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#if USE_FIXEDPOINT + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "FixedPoint.h" + +FixedPoint FixedPoint::sqrt(FixedPoint x) { + FixedPoint y0, y1, z; + + if (x.val <= 0) { + y1.val = 0; + } else { + y1.val = x.val >> 1; + do { + y0.val = y1.val; + z = x / y0; + y1.val = (y0.val + z.val) >> 1; + } while (::abs(y0.val - y1.val) > 1); + } + return y1; +} + +//~ this is not very accurate +FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) { + FixedPoint t, t2, lnx0, lnx, z0, z; + int d, i; + + if (y.val <= 0) { + z.val = 0; + } else { + // y * ln(x) + t = (x - 1) / (x + 1); + t2 = t * t; + d = 1; + lnx = 0; + do { + lnx0 = lnx; + lnx += t / d; + t *= t2; + d += 2; + } while (::abs(lnx.val - lnx0.val) > 2); + lnx.val <<= 1; + t = y * lnx; + // exp(y * ln(x)) + t2 = t; + d = 1; + i = 1; + z = 1; + do { + z0 = z; + z += t2 / d; + t2 *= t; + ++i; + d *= i; + } while (::abs(z.val - z0.val) > 2 && d < (1 << fixptShift)); + } + return z; +} + +int FixedPoint::mul(int x, int y) { +#if 1 //~tmp + return ((FixPtInt64)x * y) >> fixptShift; +#else + int ah0, ah, bh, al, bl; + ah0 = x & fixptMaskH; + ah = x >> fixptShift; + al = x - ah0; + bh = y >> fixptShift; + bl = y - (bh << fixptShift); + return ah0 * bh + ah * bl + al * bh + ((al * bl) >> fixptShift); +#endif +} + +int FixedPoint::div(int x, int y) { +#if 1 //~tmp + return ((FixPtInt64)x << fixptShift) / y; +#else +#endif +} + +#endif // USE_FIXEDPOINT diff --git a/rosapps/smartpdf/poppler/goo/FixedPoint.h b/rosapps/smartpdf/poppler/goo/FixedPoint.h new file mode 100644 index 00000000000..fccb0ff0cb8 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/FixedPoint.h @@ -0,0 +1,150 @@ +//======================================================================== +// +// FixedPoint.h +// +// Fixed point type, with C++ operators. +// +// Copyright 2004 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FIXEDPOINT_H +#define FIXEDPOINT_H + +#include + +#if USE_FIXEDPOINT + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include + +#define fixptShift 16 +#define fixptMaskL ((1 << fixptShift) - 1) +#define fixptMaskH (~fixptMaskL) + +typedef long long FixPtInt64; + +class FixedPoint { +public: + + FixedPoint() { val = 0; } + FixedPoint(const FixedPoint &x) { val = x.val; } + FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); } + FixedPoint(int x) { val = x << fixptShift; } + FixedPoint(long x) { val = x << fixptShift; } + + operator float() + { return (float) val * ((float)1 / (float)(1 << fixptShift)); } + operator double() + { return (double) val * (1.0 / (double)(1 << fixptShift)); } + operator int() + { return val >> fixptShift; } + + int getRaw() { return val; } + + FixedPoint operator =(FixedPoint x) { val = x.val; return *this; } + + int operator ==(FixedPoint x) { return val == x.val; } + int operator ==(double x) { return *this == (FixedPoint)x; } + int operator ==(int x) { return *this == (FixedPoint)x; } + int operator ==(long x) { return *this == (FixedPoint)x; } + + int operator !=(FixedPoint x) { return val != x.val; } + int operator !=(double x) { return *this != (FixedPoint)x; } + int operator !=(int x) { return *this != (FixedPoint)x; } + int operator !=(long x) { return *this != (FixedPoint)x; } + + int operator <(FixedPoint x) { return val < x.val; } + int operator <(double x) { return *this < (FixedPoint)x; } + int operator <(int x) { return *this < (FixedPoint)x; } + int operator <(long x) { return *this < (FixedPoint)x; } + + int operator <=(FixedPoint x) { return val <= x.val; } + int operator <=(double x) { return *this <= (FixedPoint)x; } + int operator <=(int x) { return *this <= (FixedPoint)x; } + int operator <=(long x) { return *this <= (FixedPoint)x; } + + int operator >(FixedPoint x) { return val > x.val; } + int operator >(double x) { return *this > (FixedPoint)x; } + int operator >(int x) { return *this > (FixedPoint)x; } + int operator >(long x) { return *this > (FixedPoint)x; } + + int operator >=(FixedPoint x) { return val >= x.val; } + int operator >=(double x) { return *this >= (FixedPoint)x; } + int operator >=(int x) { return *this >= (FixedPoint)x; } + int operator >=(long x) { return *this >= (FixedPoint)x; } + + FixedPoint operator -() { return make(-val); } + + FixedPoint operator +(FixedPoint x) { return make(val + x.val); } + FixedPoint operator +(double x) { return *this + (FixedPoint)x; } + FixedPoint operator +(int x) { return *this + (FixedPoint)x; } + FixedPoint operator +(long x) { return *this + (FixedPoint)x; } + + FixedPoint operator +=(FixedPoint x) { val = val + x.val; return *this; } + FixedPoint operator +=(double x) { return *this += (FixedPoint)x; } + FixedPoint operator +=(int x) { return *this += (FixedPoint)x; } + FixedPoint operator +=(long x) { return *this += (FixedPoint)x; } + + FixedPoint operator -(FixedPoint x) { return make(val - x.val); } + FixedPoint operator -(double x) { return *this - (FixedPoint)x; } + FixedPoint operator -(int x) { return *this - (FixedPoint)x; } + FixedPoint operator -(long x) { return *this - (FixedPoint)x; } + + FixedPoint operator -=(FixedPoint x) { val = val - x.val; return *this; } + FixedPoint operator -=(double x) { return *this -= (FixedPoint)x; } + FixedPoint operator -=(int x) { return *this -= (FixedPoint)x; } + FixedPoint operator -=(long x) { return *this -= (FixedPoint)x; } + + FixedPoint operator *(FixedPoint x) { return make(mul(val, x.val)); } + FixedPoint operator *(double x) { return *this * (FixedPoint)x; } + FixedPoint operator *(int x) { return *this * (FixedPoint)x; } + FixedPoint operator *(long x) { return *this * (FixedPoint)x; } + + FixedPoint operator *=(FixedPoint x) { val = mul(val, x.val); return *this; } + FixedPoint operator *=(double x) { return *this *= (FixedPoint)x; } + FixedPoint operator *=(int x) { return *this *= (FixedPoint)x; } + FixedPoint operator *=(long x) { return *this *= (FixedPoint)x; } + + FixedPoint operator /(FixedPoint x) { return make(div(val, x.val)); } + FixedPoint operator /(double x) { return *this / (FixedPoint)x; } + FixedPoint operator /(int x) { return *this / (FixedPoint)x; } + FixedPoint operator /(long x) { return *this / (FixedPoint)x; } + + FixedPoint operator /=(FixedPoint x) { val = div(val, x.val); return *this; } + FixedPoint operator /=(double x) { return *this /= (FixedPoint)x; } + FixedPoint operator /=(int x) { return *this /= (FixedPoint)x; } + FixedPoint operator /=(long x) { return *this /= (FixedPoint)x; } + + static FixedPoint abs(FixedPoint x) { return make(::abs(x.val)); } + + static int floor(FixedPoint x) { return x.val >> fixptShift; } + + static int ceil(FixedPoint x) + { return (x.val & fixptMaskL) ? ((x.val >> fixptShift) + 1) + : (x.val >> fixptShift); } + + static int round(FixedPoint x) + { return (x.val + (1 << (fixptShift - 1))) >> fixptShift; } + + static FixedPoint sqrt(FixedPoint x); + + static FixedPoint pow(FixedPoint x, FixedPoint y); + +private: + + static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; } + + static int mul(int x, int y); + static int div(int x, int y); + + int val; // 16.16 fixed point +}; + +#endif // USE_FIXEDPOINT + +#endif diff --git a/rosapps/smartpdf/poppler/goo/GooHash.cc b/rosapps/smartpdf/poppler/goo/GooHash.cc new file mode 100644 index 00000000000..5da9d69f82c --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooHash.cc @@ -0,0 +1,380 @@ +//======================================================================== +// +// GooHash.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "gmem.h" +#include "GooString.h" +#include "GooHash.h" + +//------------------------------------------------------------------------ + +struct GooHashBucket { + GooString *key; + union { + void *p; + int i; + } val; + GooHashBucket *next; +}; + +struct GooHashIter { + int h; + GooHashBucket *p; +}; + +//------------------------------------------------------------------------ + +GooHash::GooHash(GBool deleteKeysA) { + int h; + + deleteKeys = deleteKeysA; + size = 7; + tab = (GooHashBucket **)gmallocn(size, sizeof(GooHashBucket *)); + for (h = 0; h < size; ++h) { + tab[h] = NULL; + } + len = 0; +} + +GooHash::~GooHash() { + GooHashBucket *p; + int h; + + for (h = 0; h < size; ++h) { + while (tab[h]) { + p = tab[h]; + tab[h] = p->next; + if (deleteKeys) { + delete p->key; + } + delete p; + } + } + gfree(tab); +} + +void GooHash::add(GooString *key, void *val) { + GooHashBucket *p; + int h; + + // expand the table if necessary + if (len >= size) { + expand(); + } + + // add the new symbol + p = new GooHashBucket; + p->key = key; + p->val.p = val; + h = hash(key); + p->next = tab[h]; + tab[h] = p; + ++len; +} + +void GooHash::add(GooString *key, int val) { + GooHashBucket *p; + int h; + + // expand the table if necessary + if (len >= size) { + expand(); + } + + // add the new symbol + p = new GooHashBucket; + p->key = key; + p->val.i = val; + h = hash(key); + p->next = tab[h]; + tab[h] = p; + ++len; +} + +void GooHash::replace(GooString *key, void *val) { + GooHashBucket *p; + int h; + + if ((p = find(key, &h))) { + p->val.p = val; + delete key; + } else { + add(key, val); + } +} + +void GooHash::replace(GooString *key, int val) { + GooHashBucket *p; + int h; + + if ((p = find(key, &h))) { + p->val.i = val; + delete key; + } else { + add(key, val); + } +} + +void *GooHash::lookup(GooString *key) { + GooHashBucket *p; + int h; + + if (!(p = find(key, &h))) { + return NULL; + } + return p->val.p; +} + +int GooHash::lookupInt(GooString *key) { + GooHashBucket *p; + int h; + + if (!(p = find(key, &h))) { + return 0; + } + return p->val.i; +} + +void *GooHash::lookup(char *key) { + GooHashBucket *p; + int h; + + if (!(p = find(key, &h))) { + return NULL; + } + return p->val.p; +} + +int GooHash::lookupInt(char *key) { + GooHashBucket *p; + int h; + + if (!(p = find(key, &h))) { + return 0; + } + return p->val.i; +} + +void *GooHash::remove(GooString *key) { + GooHashBucket *p; + GooHashBucket **q; + void *val; + int h; + + if (!(p = find(key, &h))) { + return NULL; + } + q = &tab[h]; + while (*q != p) { + q = &((*q)->next); + } + *q = p->next; + if (deleteKeys) { + delete p->key; + } + val = p->val.p; + delete p; + --len; + return val; +} + +int GooHash::removeInt(GooString *key) { + GooHashBucket *p; + GooHashBucket **q; + int val; + int h; + + if (!(p = find(key, &h))) { + return 0; + } + q = &tab[h]; + while (*q != p) { + q = &((*q)->next); + } + *q = p->next; + if (deleteKeys) { + delete p->key; + } + val = p->val.i; + delete p; + --len; + return val; +} + +void *GooHash::remove(char *key) { + GooHashBucket *p; + GooHashBucket **q; + void *val; + int h; + + if (!(p = find(key, &h))) { + return NULL; + } + q = &tab[h]; + while (*q != p) { + q = &((*q)->next); + } + *q = p->next; + if (deleteKeys) { + delete p->key; + } + val = p->val.p; + delete p; + --len; + return val; +} + +int GooHash::removeInt(char *key) { + GooHashBucket *p; + GooHashBucket **q; + int val; + int h; + + if (!(p = find(key, &h))) { + return 0; + } + q = &tab[h]; + while (*q != p) { + q = &((*q)->next); + } + *q = p->next; + if (deleteKeys) { + delete p->key; + } + val = p->val.i; + delete p; + --len; + return val; +} + +void GooHash::startIter(GooHashIter **iter) { + *iter = new GooHashIter; + (*iter)->h = -1; + (*iter)->p = NULL; +} + +GBool GooHash::getNext(GooHashIter **iter, GooString **key, void **val) { + if (!*iter) { + return gFalse; + } + if ((*iter)->p) { + (*iter)->p = (*iter)->p->next; + } + while (!(*iter)->p) { + if (++(*iter)->h == size) { + delete *iter; + *iter = NULL; + return gFalse; + } + (*iter)->p = tab[(*iter)->h]; + } + *key = (*iter)->p->key; + *val = (*iter)->p->val.p; + return gTrue; +} + +GBool GooHash::getNext(GooHashIter **iter, GooString **key, int *val) { + if (!*iter) { + return gFalse; + } + if ((*iter)->p) { + (*iter)->p = (*iter)->p->next; + } + while (!(*iter)->p) { + if (++(*iter)->h == size) { + delete *iter; + *iter = NULL; + return gFalse; + } + (*iter)->p = tab[(*iter)->h]; + } + *key = (*iter)->p->key; + *val = (*iter)->p->val.i; + return gTrue; +} + +void GooHash::killIter(GooHashIter **iter) { + delete *iter; + *iter = NULL; +} + +void GooHash::expand() { + GooHashBucket **oldTab; + GooHashBucket *p; + int oldSize, h, i; + + oldSize = size; + oldTab = tab; + size = 2*size + 1; + tab = (GooHashBucket **)gmallocn(size, sizeof(GooHashBucket *)); + for (h = 0; h < size; ++h) { + tab[h] = NULL; + } + for (i = 0; i < oldSize; ++i) { + while (oldTab[i]) { + p = oldTab[i]; + oldTab[i] = oldTab[i]->next; + h = hash(p->key); + p->next = tab[h]; + tab[h] = p; + } + } + gfree(oldTab); +} + +GooHashBucket *GooHash::find(GooString *key, int *h) { + GooHashBucket *p; + + *h = hash(key); + for (p = tab[*h]; p; p = p->next) { + if (!p->key->cmp(key)) { + return p; + } + } + return NULL; +} + +GooHashBucket *GooHash::find(char *key, int *h) { + GooHashBucket *p; + + *h = hash(key); + for (p = tab[*h]; p; p = p->next) { + if (!p->key->cmp(key)) { + return p; + } + } + return NULL; +} + +int GooHash::hash(GooString *key) { + char *p; + unsigned int h; + int i; + + h = 0; + for (p = key->getCString(), i = 0; i < key->getLength(); ++p, ++i) { + h = 17 * h + (int)(*p & 0xff); + } + return (int)(h % size); +} + +int GooHash::hash(char *key) { + char *p; + unsigned int h; + + h = 0; + for (p = key; *p; ++p) { + h = 17 * h + (int)(*p & 0xff); + } + return (int)(h % size); +} diff --git a/rosapps/smartpdf/poppler/goo/GooHash.h b/rosapps/smartpdf/poppler/goo/GooHash.h new file mode 100644 index 00000000000..bdcf1c43ece --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooHash.h @@ -0,0 +1,76 @@ +//======================================================================== +// +// GooHash.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GHASH_H +#define GHASH_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "gtypes.h" + +class GooString; +struct GooHashBucket; +struct GooHashIter; + +//------------------------------------------------------------------------ + +class GooHash { +public: + + GooHash(GBool deleteKeysA = gFalse); + ~GooHash(); + void add(GooString *key, void *val); + void add(GooString *key, int val); + void replace(GooString *key, void *val); + void replace(GooString *key, int val); + void *lookup(GooString *key); + int lookupInt(GooString *key); + void *lookup(char *key); + int lookupInt(char *key); + void *remove(GooString *key); + int removeInt(GooString *key); + void *remove(char *key); + int removeInt(char *key); + int getLength() { return len; } + void startIter(GooHashIter **iter); + GBool getNext(GooHashIter **iter, GooString **key, void **val); + GBool getNext(GooHashIter **iter, GooString **key, int *val); + void killIter(GooHashIter **iter); + +private: + + void expand(); + GooHashBucket *find(GooString *key, int *h); + GooHashBucket *find(char *key, int *h); + int hash(GooString *key); + int hash(char *key); + + GBool deleteKeys; // set if key strings should be deleted + int size; // number of buckets + int len; // number of entries + GooHashBucket **tab; +}; + +#define deleteGooHash(hash, T) \ + do { \ + GooHash *_hash = (hash); \ + { \ + GooHashIter *_iter; \ + GooString *_key; \ + void *_p; \ + _hash->startIter(&_iter); \ + while (_hash->getNext(&_iter, &_key, &_p)) { \ + delete (T*)_p; \ + } \ + delete _hash; \ + } \ + } while(0) + +#endif diff --git a/rosapps/smartpdf/poppler/goo/GooList.cc b/rosapps/smartpdf/poppler/goo/GooList.cc new file mode 100644 index 00000000000..dc6e4e21e00 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooList.cc @@ -0,0 +1,97 @@ +//======================================================================== +// +// GooList.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "gmem.h" +#include "GooList.h" + +//------------------------------------------------------------------------ +// GooList +//------------------------------------------------------------------------ + +GooList::GooList() { + size = 8; + data = (void **)gmallocn(size, sizeof(void*)); + length = 0; + inc = 0; +} + +GooList::GooList(int sizeA) { + size = sizeA; + data = (void **)gmallocn(size, sizeof(void*)); + length = 0; + inc = 0; +} + +GooList::~GooList() { + gfree(data); +} + +void GooList::append(void *p) { + if (length >= size) { + expand(); + } + data[length++] = p; +} + +void GooList::append(GooList *list) { + int i; + + while (length + list->length > size) { + expand(); + } + for (i = 0; i < list->length; ++i) { + data[length++] = list->data[i]; + } +} + +void GooList::insert(int i, void *p) { + if (length >= size) { + expand(); + } + if (i < length) { + memmove(data+i+1, data+i, (length - i) * sizeof(void *)); + } + data[i] = p; + ++length; +} + +void *GooList::del(int i) { + void *p; + + p = data[i]; + if (i < length - 1) { + memmove(data+i, data+i+1, (length - i - 1) * sizeof(void *)); + } + --length; + if (size - length >= ((inc > 0) ? inc : size/2)) { + shrink(); + } + return p; +} + +void GooList::sort(int (*cmp)(const void *obj1, const void *obj2)) { + qsort(data, length, sizeof(void *), cmp); +} + +void GooList::expand() { + size += (inc > 0) ? inc : size; + data = (void **)greallocn(data, size, sizeof(void*)); +} + +void GooList::shrink() { + size -= (inc > 0) ? inc : size/2; + data = (void **)greallocn(data, size, sizeof(void*)); +} diff --git a/rosapps/smartpdf/poppler/goo/GooList.h b/rosapps/smartpdf/poppler/goo/GooList.h new file mode 100644 index 00000000000..576f3e8142d --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooList.h @@ -0,0 +1,94 @@ +//======================================================================== +// +// GooList.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GLIST_H +#define GLIST_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "gtypes.h" + +//------------------------------------------------------------------------ +// GooList +//------------------------------------------------------------------------ + +class GooList { +public: + + // Create an empty list. + GooList(); + + // Create an empty list with space for elements. + GooList(int sizeA); + + // Destructor - does not free pointed-to objects. + ~GooList(); + + //----- general + + // Get the number of elements. + int getLength() { return length; } + + //----- ordered list support + + // Return the th element. + // Assumes 0 <= i < length. + void *get(int i) { return data[i]; } + + // Append an element to the end of the list. + void append(void *p); + + // Append another list to the end of this one. + void append(GooList *list); + + // Insert an element at index . + // Assumes 0 <= i <= length. + void insert(int i, void *p); + + // Deletes and returns the element at index . + // Assumes 0 <= i < length. + void *del(int i); + + // Sort the list accoring to the given comparison function. + // NB: this sorts an array of pointers, so the pointer args need to + // be double-dereferenced. + void sort(int (*cmp)(const void *ptr1, const void *ptr2)); + + //----- control + + // Set allocation increment to . If inc > 0, that many + // elements will be allocated every time the list is expanded. + // If inc <= 0, the list will be doubled in size. + void setAllocIncr(int incA) { inc = incA; } + +private: + + void expand(); + void shrink(); + + void **data; // the list elements + int size; // size of data array + int length; // number of elements on list + int inc; // allocation increment +}; + +#define deleteGooList(list, T) \ + do { \ + GooList *_list = (list); \ + { \ + int _i; \ + for (_i = 0; _i < _list->getLength(); ++_i) { \ + delete (T*)_list->get(_i); \ + } \ + delete _list; \ + } \ + } while (0) + +#endif diff --git a/rosapps/smartpdf/poppler/goo/GooMutex.h b/rosapps/smartpdf/poppler/goo/GooMutex.h new file mode 100644 index 00000000000..d6ab73d28b4 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooMutex.h @@ -0,0 +1,70 @@ +//======================================================================== +// +// GooMutex.h +// +// Portable mutex macros. +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GMUTEX_H +#define GMUTEX_H + +// Usage: +// +// GooMutex m; +// gInitMutex(&m); +// ... +// gLockMutex(&m); +// ... critical section ... +// gUnlockMutex(&m); +// ... +// gDestroyMutex(&m); + +#ifdef WIN32 + +#include + +typedef CRITICAL_SECTION GooMutex; + +#define gInitMutex(m) InitializeCriticalSection(m) +#define gInitMutexReentrant(m) InitializeCriticalSection(m) +#define gDestroyMutex(m) DeleteCriticalSection(m) +#define gLockMutex(m) EnterCriticalSection(m) +#define gUnlockMutex(m) LeaveCriticalSection(m) + +#else // assume pthreads + +#include + +typedef pthread_mutex_t GooMutex; + +#define gInitMutex(m) pthread_mutex_init(m, NULL) +#define gDestroyMutex(m) pthread_mutex_destroy(m) +#define gLockMutex(m) pthread_mutex_lock(m) +#define gUnlockMutex(m) pthread_mutex_unlock(m) + +#define gInitMutexReentrant(m) \ + { \ + pthread_mutexattr_t attr; \ + pthread_mutexattr_init(&attr); \ + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); \ + pthread_mutex_init(mutex, &attr); \ + } +#endif + +class MutexAutoInitDestroy { +public: + MutexAutoInitDestroy(GooMutex *mutex) { + mMutex = mutex; + gInitMutexReentrant(mMutex); + } + ~MutexAutoInitDestroy() { + gDestroyMutex(mMutex); + } +private: + GooMutex *mMutex; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/goo/GooString.cc b/rosapps/smartpdf/poppler/goo/GooString.cc new file mode 100644 index 00000000000..25b6c1fc76f --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooString.cc @@ -0,0 +1,327 @@ +//======================================================================== +// +// GooString.cc +// +// Simple variable-length string type. +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "gtypes.h" +#include "GooString.h" + +int inline GooString::roundedSize(int len) { + int delta; + if (len <= STR_STATIC_SIZE-1) + return STR_STATIC_SIZE; + delta = len < 256 ? 7 : 255; + return ((len + 1) + delta) & ~delta; +} + +// Make sure that the buffer is big enough to contain characters +// plus terminating 0. +// We assume that if this is being called from the constructor, was set +// to NULL and was set to 0 to indicate unused string before calling us. +void inline GooString::resize(int newLength) { + int curSize = roundedSize(length); + int newSize = roundedSize(newLength); + + assert(s); + + if (curSize != newSize) { + char *sNew = sStatic; + if (newSize != STR_STATIC_SIZE) + sNew = new char[newSize]; + + // we had to re-allocate the memory, so copy the content of previous + // buffer into a new buffer + if (newLength < length) { + memcpy(sNew, s, newLength); + } else { + memcpy(sNew, s, length); + } + if (s != sStatic) { + assert(curSize != STR_STATIC_SIZE); + delete[] s; + } + s = sNew; + } + + length = newLength; + s[length] = '\0'; +} + +GooString* GooString::Set(const char *s1, int s1Len, const char *s2, int s2Len) +{ + int newLen = 0; + char *p; + + if (s1) { + if (CALC_STRING_LEN == s1Len) { + s1Len = strlen(s1); + } else + assert(s1Len >= 0); + newLen += s1Len; + } + + if (s2) { + if (CALC_STRING_LEN == s2Len) { + s2Len = strlen(s2); + } else + assert(s2Len >= 0); + newLen += s2Len; + } + + resize(newLen); + p = s; + if (s1) { + memcpy(p, s1, s1Len); + p += s1Len; + } + if (s2) { + memcpy(p, s2, s2Len); + p += s2Len; + } + return this; +} + +GooString::GooString() { + s = sStatic; + length = 0; + Set(NULL); +} + +GooString::GooString(const char *sA) { + s = sStatic; + length = 0; + Set(sA, CALC_STRING_LEN); +} + +GooString::GooString(const char *sA, int lengthA) { + s = sStatic; + length = 0; + Set(sA, lengthA); +} + +GooString::GooString(GooString *str, int idx, int lengthA) { + s = sStatic; + length = 0; + assert(idx + lengthA < str->length); + Set(str->getCString() + idx, lengthA); +} + +GooString::GooString(GooString *str) { + s = sStatic; + length = 0; + Set(str->getCString(), str->length); +} + +GooString::GooString(GooString *str1, GooString *str2) { + s = sStatic; + length = 0; + Set(str1->getCString(), str1->length, str2->getCString(), str2->length); +} + +GooString *GooString::fromInt(int x) { + char buf[24]; // enough space for 64-bit ints plus a little extra + GBool neg; + Guint y; + int i; + + i = 24; + if (x == 0) { + buf[--i] = '0'; + } else { + if ((neg = x < 0)) { + y = (Guint)-x; + } else { + y = (Guint)x; + } + while (i > 0 && y > 0) { + buf[--i] = '0' + y % 10; + y /= 10; + } + if (neg && i > 0) { + buf[--i] = '-'; + } + } + return new GooString(buf + i, 24 - i); +} + +GooString::~GooString() { + if (s != sStatic) + delete[] s; +} + +GooString *GooString::clear() { + resize(0); + return this; +} + +GooString *GooString::append(char c) { + return append((const char*)&c, 1); +} + +GooString *GooString::append(GooString *str) { + return append(str->getCString(), str->getLength()); +} + +GooString *GooString::append(const char *str, int lengthA) { + int prevLen = length; + if (CALC_STRING_LEN == lengthA) + lengthA = strlen(str); + resize(length + lengthA); + memcpy(s + prevLen, str, lengthA); + return this; +} + +GooString *GooString::insert(int i, char c) { + return insert(i, (const char*)&c, 1); +} + +GooString *GooString::insert(int i, GooString *str) { + return insert(i, str->getCString(), str->getLength()); +} + +GooString *GooString::insert(int i, const char *str, int lengthA) { + int j; + int prevLen = length; + if (CALC_STRING_LEN == lengthA) + lengthA = strlen(str); + + resize(length + lengthA); + for (j = prevLen; j >= i; --j) + s[j+lengthA] = s[j]; + memcpy(s+i, str, lengthA); + return this; +} + +GooString *GooString::del(int i, int n) { + int j; + + if (n > 0) { + if (i + n > length) { + n = length - i; + } + for (j = i; j <= length - n; ++j) { + s[j] = s[j + n]; + } + resize(length - n); + } + return this; +} + +GooString *GooString::upperCase() { + int i; + + for (i = 0; i < length; ++i) { + if (islower(s[i])) + s[i] = toupper(s[i]); + } + return this; +} + +GooString *GooString::lowerCase() { + int i; + + for (i = 0; i < length; ++i) { + if (isupper(s[i])) + s[i] = tolower(s[i]); + } + return this; +} + +int GooString::cmp(GooString *str) { + int n1, n2, i, x; + char *p1, *p2; + + n1 = length; + n2 = str->length; + for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + return n1 - n2; +} + +int GooString::cmpN(GooString *str, int n) { + int n1, n2, i, x; + char *p1, *p2; + + n1 = length; + n2 = str->length; + for (i = 0, p1 = s, p2 = str->s; + i < n1 && i < n2 && i < n; + ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + if (i == n) { + return 0; + } + return n1 - n2; +} + +int GooString::cmp(const char *sA) { + int n1, i, x; + const char *p1, *p2; + + n1 = length; + for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + if (i < n1) { + return 1; + } + if (*p2) { + return -1; + } + return 0; +} + +int GooString::cmpN(const char *sA, int n) { + int n1, i, x; + const char *p1, *p2; + + n1 = length; + for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + if (i == n) { + return 0; + } + if (i < n1) { + return 1; + } + if (*p2) { + return -1; + } + return 0; +} + +GBool GooString::hasUnicodeMarker(void) +{ + return (s[0] & 0xff) == 0xfe && (s[1] & 0xff) == 0xff; +} diff --git a/rosapps/smartpdf/poppler/goo/GooString.h b/rosapps/smartpdf/poppler/goo/GooString.h new file mode 100644 index 00000000000..427b292b356 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooString.h @@ -0,0 +1,230 @@ +//======================================================================== +// +// GooString.h +// +// Simple variable-length string type. +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GSTRING_H +#define GSTRING_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include // for NULL +#include "gtypes.h" +#include "GooMutex.h" + +class GooString { +public: + + // Create an empty string. + GooString(); + + // Create a string from a C string. + GooString(const char *sA); + + // Create a string from chars at . This string + // can contain null characters. + GooString(const char *sA, int lengthA); + + // Create a string from chars at in . + GooString(GooString *str, int idx, int lengthA); + + // Set content of a string to concatination of and . They can both + // be NULL. if or is CALC_STRING_LEN, then length of the string + // will be calculated with strlen(). Otherwise we assume they are a valid + // length of string (or its substring) + +/* @note: gnu g++ fix */ + GooString* Set(const char *s1, int s1Len=CALC_STRING_LEN, const char *s2=NULL, int s2Len=CALC_STRING_LEN); + +/* original code line: + * GooString* GooString::Set(const char *s1, int s1Len=CALC_STRING_LEN, const char *s2=NULL, int s2Len=CALC_STRING_LEN); + */ + + GooString(GooString *str); + + // Return a newly allocated copy of the string + GooString *copy() { return new GooString(this); } + + // Concatenate two strings. + GooString(GooString *str1, GooString *str2); + + // Convert an integer to a string. + static GooString *fromInt(int x); + + ~GooString(); + + // Get length. + int getLength() const { return length; } + + // Get C string. + char *getCString() const { return s; } + + // Get th character. + char getChar(int i) { return s[i]; } + + // Change th character. + void setChar(int i, char c) { s[i] = c; } + + // Clear string to zero length. + GooString *clear(); + + // Append a character or string. + GooString *append(char c); + GooString *append(GooString *str); + GooString *append(const char *str, int lengthA=CALC_STRING_LEN); + + // Insert a character or string. + GooString *insert(int i, char c); + GooString *insert(int i, GooString *str); + GooString *insert(int i, const char *str, int lengthA=CALC_STRING_LEN); + + // Delete a character or range of characters. + GooString *del(int i, int n = 1); + + // Convert string to all-upper/all-lower case. + GooString *upperCase(); + GooString *lowerCase(); + + // Compare two strings: -1:< 0:= +1:> + int cmp(GooString *str); + int cmpN(GooString *str, int n); + int cmp(const char *sA); + int cmpN(const char *sA, int n); + + GBool hasUnicodeMarker(void); + + // a special value telling that the length of the string is not given + // so it must be calculated from the strings + static const int CALC_STRING_LEN = -1; + +private: + // you can tweak this number for a different speed/memory usage tradeoffs. + // In libc malloc() rounding is 16 so it's best to choose a value that + // results in sizeof(GooString) be a multiple of 16. + // 24 makes sizeof(GooString) to be 32. + static const int STR_STATIC_SIZE = 24; + + int roundedSize(int len); + + char sStatic[STR_STATIC_SIZE]; + int length; + char *s; + + void resize(int newLength); +}; + +//Uncomment if you want to gather stats on hit rate of the cache +//#define CALC_OBJECT_STRING_CACHE_STATS 1 + +/* A cache for GooString. You can think of it as a custom allocator + for GooString(). Use alloc() to get a new GooString() and free() to free + existing GooString(). It keeps last GooStringCache::CACHE_SIZE free()ed + strings in a cache (which is a stack) and satisfies the alloc()s from + the cache first, thus saves free()/malloc() cycle. + It's used by Object::free()/Object::init*() and works great for them + because they recycle strings like crazy. +*/ +class GooStringCache +{ +public: + GooStringCache() { + inCache = 0; +#ifdef CALC_OBJECT_STRING_CACHE_STATS + totalAllocs = 0; + allocsFromCache = 0; +#endif +#if MULTITHREADED + gInitMutex(&mutex); +#endif + } + + ~GooStringCache() { + for (int i=0; igetCString(), str->getLength()); + } + + // alloc and free are called a lot, so make them inline + GooString *alloc(const char *txt, int strLen = GooString::CALC_STRING_LEN) { + GooString *res = NULL; +#if MULTITHREADED + gLockMutex(&mutex); +#endif +#ifdef CALC_OBJECT_STRING_CACHE_STATS + ++totalAllocs; +#endif + if (inCache > 0) { + // pop the value from the top of the stack + res = stringsCached[inCache-1]; + res->Set(txt, strLen); + --inCache; +#ifdef CALC_OBJECT_STRING_CACHE_STATS + ++allocsFromCache; +#endif + goto Exit; + } else { + res = new GooString(txt, strLen); + goto Exit; + } +Exit: +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif + return res; + } + + void free(GooString *str) { +#if MULTITHREADED + gLockMutex(&mutex); +#endif + if (inCache < CACHE_SIZE) { + // put the value at the top of the stack + stringsCached[inCache] = str; + ++inCache; + } else { + // cache is full + delete str; + } +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif + } +private: + // CACHE_SIZE size affects 2 things: + // - alloc() hit ratio i.e. how many alloc()s can be satisfied from cache + // as opposed to allocating new GooString() with generic malloc() + // This is a *very* effective cache. I get 99.98% alloc() hit ratio even + // with CACHE_SIZE of 8. 95% with CACHE_SIZE of 4 + // - how often we call delete on GooString(). When cache is full, we delete + // strings the usual way. When CACHE_SIZE grows, we hit delete less + // 64 is chosen by gut feeling, might use some tweaking + static const int CACHE_SIZE = 64; + +#ifdef CALC_OBJECT_STRING_CACHE_STATS + int totalAllocs; + int allocsFromCache; +#endif + int inCache; + // you can think of it as a stack, we only add something to the top + // or take it from the top + GooString *stringsCached[CACHE_SIZE]; +#if MULTITHREADED + GooMutex mutex; +#endif +}; + +#endif diff --git a/rosapps/smartpdf/poppler/goo/GooTimer.cc b/rosapps/smartpdf/poppler/goo/GooTimer.cc new file mode 100644 index 00000000000..e9ae2e61ad0 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooTimer.cc @@ -0,0 +1,66 @@ +//======================================================================== +// +// GooTimer.cc +// +// Copyright 2005 Jonathan Blandford +// Inspired by gtimer.c in glib, which is Copyright 2000 by the GLib Team +// +//======================================================================== + +#include + +#ifdef HAVE_GETTIMEOFDAY + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "GooTimer.h" + +//------------------------------------------------------------------------ +// GooTimer +//------------------------------------------------------------------------ + + +GooTimer::GooTimer() { + gettimeofday (&start, NULL); + active = true; +} + + +void +GooTimer::stop() { + gettimeofday (&end, NULL); + active = false; +} + +#define USEC_PER_SEC 1000000 +double +GooTimer::getElapsed () +{ + double total; + struct timeval elapsed; + + if (active) + gettimeofday (&end, NULL); + + if (start.tv_usec > end.tv_usec) + { + end.tv_usec += USEC_PER_SEC; + end.tv_sec--; + } + + elapsed.tv_usec = end.tv_usec - start.tv_usec; + elapsed.tv_sec = end.tv_sec - start.tv_sec; + + total = elapsed.tv_sec + ((double) elapsed.tv_usec / 1e6); + if (total < 0) + { + total = 0; + } + + return total; +} + +#endif diff --git a/rosapps/smartpdf/poppler/goo/GooTimer.h b/rosapps/smartpdf/poppler/goo/GooTimer.h new file mode 100644 index 00000000000..86bc42ff15a --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooTimer.h @@ -0,0 +1,44 @@ +//======================================================================== +// +// GooList.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifdef HAVE_GETTIMEOFDAY + +#ifndef GOOTIMER_H +#define GOOTIMER_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "gtypes.h" +#include + +//------------------------------------------------------------------------ +// GooList +//------------------------------------------------------------------------ + +class GooTimer { +public: + + // Create a new timer. + GooTimer(); + + void stop (); + double getElapsed(); + + +private: + + struct timeval start; + struct timeval end; + GBool active; +}; + +#endif + +#endif diff --git a/rosapps/smartpdf/poppler/goo/GooVector.h b/rosapps/smartpdf/poppler/goo/GooVector.h new file mode 100644 index 00000000000..67a3a1d71e4 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/GooVector.h @@ -0,0 +1,101 @@ +#ifndef _VECTOR_H +#define _VECTOR_H +#include "goo/gtypes.h" + + +template +class GooVector{ +private: + + int _size; + T* last; + T* storage; + + void resize(){ + if (_size==0) _size=2;else _size=2*_size; + T *tmp=new T[_size]; + if (storage){ + last=copy(storage,last,tmp); + delete [] storage; + } + else last=tmp; + storage=tmp; + } + + T* copy(T* src1,T* src2,T* dest){ + T* tmp=src1; + T* d=dest; + while(tmp!=src2){ + *d=*tmp; + d++;tmp++; + } + return d; + } + +public: + typedef T* iterator; + + GooVector(){ + _size=0; + last=0; + storage=0; +} + + + +virtual ~GooVector(){ + delete[] storage ; +} + +void reset(){ + last=storage; +} + +int size(){ + return (last-storage); +} +void push_back(const T& elem){ + if (!storage||(size() >=_size)) resize(); + *last=elem; + last++; + + +} + + +T pop_back() { + if (last!=storage) last--; + + return *last; +} + + +T operator[](unsigned int i){ + return *(storage+i); +} + + +GBool isEmpty() const{ + return !_size || (last==storage) ; +} + + + +iterator begin() const{ + return storage; +} + +iterator end() const { + return last; +} +}; +#endif + + + + + + + + + diff --git a/rosapps/smartpdf/poppler/goo/Makefile.am b/rosapps/smartpdf/poppler/goo/Makefile.am new file mode 100644 index 00000000000..c844207d47f --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/Makefile.am @@ -0,0 +1,29 @@ +noinst_LTLIBRARIES = libgoo.la + +if ENABLE_XPDF_HEADERS + +poppler_goo_includedir = $(includedir)/poppler/goo +poppler_goo_include_HEADERS = \ + GooHash.h \ + GooList.h \ + GooTimer.h \ + GooMutex.h \ + GooString.h \ + GooVector.h \ + gmem.h \ + gtypes.h \ + gmem.h \ + gfile.h \ + FixedPoint.h + +endif + +libgoo_la_SOURCES = \ + gfile.cc \ + gmempp.cc \ + GooHash.cc \ + GooList.cc \ + GooTimer.cc \ + GooString.cc \ + gmem.c \ + FixedPoint.cc diff --git a/rosapps/smartpdf/poppler/goo/gfile.cc b/rosapps/smartpdf/poppler/goo/gfile.cc new file mode 100644 index 00000000000..8fa120f26a9 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/gfile.cc @@ -0,0 +1,709 @@ +//======================================================================== +// +// gfile.cc +// +// Miscellaneous file and directory name manipulation. +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifndef WIN32 +# if defined(MACOS) +# include +# elif !defined(ACORN) +# include +# include +# include +# endif +# include +# include +# if !defined(VMS) && !defined(ACORN) && !defined(MACOS) +# include +# endif +# if defined(VMS) && (__DECCXX_VER < 50200000) +# include +# endif +#endif // WIN32 +#include "GooString.h" +#include "gfile.h" + +// Some systems don't define this, so just make it something reasonably +// large. +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +//------------------------------------------------------------------------ + +GooString *getHomeDir() { +#ifdef VMS + //---------- VMS ---------- + return new GooString("SYS$LOGIN:"); + +#elif defined(__EMX__) || defined(WIN32) + //---------- OS/2+EMX and Win32 ---------- + char *s; + GooString *ret; + + if ((s = getenv("HOME"))) + ret = new GooString(s); + else + ret = new GooString("."); + return ret; + +#elif defined(ACORN) + //---------- RISCOS ---------- + return new GooString("@"); + +#elif defined(MACOS) + //---------- MacOS ---------- + return new GooString(":"); + +#else + //---------- Unix ---------- + char *s; + struct passwd *pw; + GooString *ret; + + if ((s = getenv("HOME"))) { + ret = new GooString(s); + } else { + if ((s = getenv("USER"))) + pw = getpwnam(s); + else + pw = getpwuid(getuid()); + if (pw) + ret = new GooString(pw->pw_dir); + else + ret = new GooString("."); + } + return ret; +#endif +} + +GooString *getCurrentDir() { + char buf[PATH_MAX+1]; + +#if defined(__EMX__) + if (_getcwd2(buf, sizeof(buf))) +#elif defined(WIN32) + if (GetCurrentDirectory(sizeof((TCHAR*)buf), (TCHAR*)buf)) /* @note: TCHAR* cast */ +#elif defined(ACORN) + if (strcpy(buf, "@")) +#elif defined(MACOS) + if (strcpy(buf, ":")) +#else + if (getcwd(buf, sizeof(buf))) +#endif + return new GooString(buf); + return new GooString(); +} + +GooString *appendToPath(GooString *path, char *fileName) { +#if defined(VMS) + //---------- VMS ---------- + //~ this should handle everything necessary for file + //~ requesters, but it's certainly not complete + char *p0, *p1, *p2; + char *q1; + + p0 = path->getCString(); + p1 = p0 + path->getLength() - 1; + if (!strcmp(fileName, "-")) { + if (*p1 == ']') { + for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ; + if (*p2 == '[') + ++p2; + path->del(p2 - p0, p1 - p2); + } else if (*p1 == ':') { + path->append("[-]"); + } else { + path->clear(); + path->append("[-]"); + } + } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) { + if (*p1 == ']') { + path->insert(p1 - p0, '.'); + path->insert(p1 - p0 + 1, fileName, q1 - fileName); + } else if (*p1 == ':') { + path->append('['); + path->append(']'); + path->append(fileName, q1 - fileName); + } else { + path->clear(); + path->append(fileName, q1 - fileName); + } + } else { + if (*p1 != ']' && *p1 != ':') + path->clear(); + path->append(fileName); + } + return path; + +#elif defined(WIN32) + //---------- Win32 ---------- + GooString *tmp; + char buf[MAX_PATH];/* @note: use MAX_PATH instead of "buf[256]" */ + char *fp; + + tmp = new GooString(path); + tmp->append('/'); + tmp->append(fileName); + GetFullPathNameA(tmp->getCString(), sizeof(buf), buf, &fp); /* @note: ANSI function as workaround */ + delete tmp; + path->clear(); + path->append(buf); + return path; + +#elif defined(ACORN) + //---------- RISCOS ---------- + char *p; + int i; + + path->append("."); + i = path->getLength(); + path->append(fileName); + for (p = path->getCString() + i; *p; ++p) { + if (*p == '/') { + *p = '.'; + } else if (*p == '.') { + *p = '/'; + } + } + return path; + +#elif defined(MACOS) + //---------- MacOS ---------- + char *p; + int i; + + path->append(":"); + i = path->getLength(); + path->append(fileName); + for (p = path->getCString() + i; *p; ++p) { + if (*p == '/') { + *p = ':'; + } else if (*p == '.') { + *p = ':'; + } + } + return path; + +#elif defined(__EMX__) + //---------- OS/2+EMX ---------- + int i; + + // appending "." does nothing + if (!strcmp(fileName, ".")) + return path; + + // appending ".." goes up one directory + if (!strcmp(fileName, "..")) { + for (i = path->getLength() - 2; i >= 0; --i) { + if (path->getChar(i) == '/' || path->getChar(i) == '\\' || + path->getChar(i) == ':') + break; + } + if (i <= 0) { + if (path->getChar(0) == '/' || path->getChar(0) == '\\') { + path->del(1, path->getLength() - 1); + } else if (path->getLength() >= 2 && path->getChar(1) == ':') { + path->del(2, path->getLength() - 2); + } else { + path->clear(); + path->append(".."); + } + } else { + if (path->getChar(i-1) == ':') + ++i; + path->del(i, path->getLength() - i); + } + return path; + } + + // otherwise, append "/" and new path component + if (path->getLength() > 0 && + path->getChar(path->getLength() - 1) != '/' && + path->getChar(path->getLength() - 1) != '\\') + path->append('/'); + path->append(fileName); + return path; + +#else + //---------- Unix ---------- + int i; + + // appending "." does nothing + if (!strcmp(fileName, ".")) + return path; + + // appending ".." goes up one directory + if (!strcmp(fileName, "..")) { + for (i = path->getLength() - 2; i >= 0; --i) { + if (path->getChar(i) == '/') + break; + } + if (i <= 0) { + if (path->getChar(0) == '/') { + path->del(1, path->getLength() - 1); + } else { + path->clear(); + path->append(".."); + } + } else { + path->del(i, path->getLength() - i); + } + return path; + } + + // otherwise, append "/" and new path component + if (path->getLength() > 0 && + path->getChar(path->getLength() - 1) != '/') + path->append('/'); + path->append(fileName); + return path; +#endif +} + +GooString *grabPath(char *fileName) { +#ifdef VMS + //---------- VMS ---------- + char *p; + + if ((p = strrchr(fileName, ']'))) + return new GooString(fileName, p + 1 - fileName); + if ((p = strrchr(fileName, ':'))) + return new GooString(fileName, p + 1 - fileName); + return new GooString(); + +#elif defined(__EMX__) || defined(WIN32) + //---------- OS/2+EMX and Win32 ---------- + char *p; + + if ((p = strrchr(fileName, '/'))) + return new GooString(fileName, p - fileName); + if ((p = strrchr(fileName, '\\'))) + return new GooString(fileName, p - fileName); + if ((p = strrchr(fileName, ':'))) + return new GooString(fileName, p + 1 - fileName); + return new GooString(); + +#elif defined(ACORN) + //---------- RISCOS ---------- + char *p; + + if ((p = strrchr(fileName, '.'))) + return new GooString(fileName, p - fileName); + return new GooString(); + +#elif defined(MACOS) + //---------- MacOS ---------- + char *p; + + if ((p = strrchr(fileName, ':'))) + return new GooString(fileName, p - fileName); + return new GooString(); + +#else + //---------- Unix ---------- + char *p; + + if ((p = strrchr(fileName, '/'))) + return new GooString(fileName, p - fileName); + return new GooString(); +#endif +} + +GBool isAbsolutePath(char *path) { +#ifdef VMS + //---------- VMS ---------- + return strchr(path, ':') || + (path[0] == '[' && path[1] != '.' && path[1] != '-'); + +#elif defined(__EMX__) || defined(WIN32) + //---------- OS/2+EMX and Win32 ---------- + return path[0] == '/' || path[0] == '\\' || path[1] == ':'; + +#elif defined(ACORN) + //---------- RISCOS ---------- + return path[0] == '$'; + +#elif defined(MACOS) + //---------- MacOS ---------- + return path[0] != ':'; + +#else + //---------- Unix ---------- + return path[0] == '/'; +#endif +} + +GooString *makePathAbsolute(GooString *path) { +#ifdef VMS + //---------- VMS ---------- + char buf[PATH_MAX+1]; + + if (!isAbsolutePath(path->getCString())) { + if (getcwd(buf, sizeof(buf))) { + path->insert(0, buf); + } + } + return path; + +#elif defined(WIN32) + //---------- Win32 ---------- + char buf[_MAX_PATH]; + char *fp; + + buf[0] = '\0'; + if (!GetFullPathNameA(path->getCString(), _MAX_PATH, buf, &fp)) { /* @note: ANSI function as workaround */ + path->clear(); + return path; + } + path->clear(); + path->append(buf); + return path; + +#elif defined(ACORN) + //---------- RISCOS ---------- + path->insert(0, '@'); + return path; + +#elif defined(MACOS) + //---------- MacOS ---------- + path->del(0, 1); + return path; + +#else + //---------- Unix and OS/2+EMX ---------- + struct passwd *pw; + char buf[PATH_MAX+1]; + GooString *s; + char *p1, *p2; + int n; + + if (path->getChar(0) == '~') { + if (path->getChar(1) == '/' || +#ifdef __EMX__ + path->getChar(1) == '\\' || +#endif + path->getLength() == 1) { + path->del(0, 1); + s = getHomeDir(); + path->insert(0, s); + delete s; + } else { + p1 = path->getCString() + 1; +#ifdef __EMX__ + for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ; +#else + for (p2 = p1; *p2 && *p2 != '/'; ++p2) ; +#endif + if ((n = p2 - p1) > PATH_MAX) + n = PATH_MAX; + strncpy(buf, p1, n); + buf[n] = '\0'; + if ((pw = getpwnam(buf))) { + path->del(0, p2 - p1 + 1); + path->insert(0, pw->pw_dir); + } + } + } else if (!isAbsolutePath(path->getCString())) { + if (getcwd(buf, sizeof(buf))) { +#ifndef __EMX__ + path->insert(0, '/'); +#endif + path->insert(0, buf); + } + } + return path; +#endif +} + +time_t getModTime(char *fileName) { +#ifdef WIN32 + //~ should implement this, but it's (currently) only used in xpdf + return 0; +#else + struct stat statBuf; + + if (stat(fileName, &statBuf)) { + return 0; + } + return statBuf.st_mtime; +#endif +} + +GBool openTempFile(GooString **name, FILE **f, char *mode, char *ext) { +#if defined(WIN32) + //---------- Win32 ---------- + char *s; + + if (!(s = _tempnam(getenv("TEMP"), NULL))) { + return gFalse; + } + *name = new GooString(s); + free(s); + if (ext) { + (*name)->append(ext); + } + if (!(*f = fopen((*name)->getCString(), mode))) { + delete (*name); + return gFalse; + } + return gTrue; +#elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS) + //---------- non-Unix ---------- + char *s; + + // There is a security hole here: an attacker can create a symlink + // with this file name after the tmpnam call and before the fopen + // call. I will happily accept fixes to this function for non-Unix + // OSs. + if (!(s = tmpnam(NULL))) { + return gFalse; + } + *name = new GooString(s); + if (ext) { + (*name)->append(ext); + } + if (!(*f = fopen((*name)->getCString(), mode))) { + delete (*name); + return gFalse; + } + return gTrue; +#else + //---------- Unix ---------- + char *s; + int fd; + + if (ext) { +#if HAVE_MKSTEMPS + if ((s = getenv("TMPDIR"))) { + *name = new GooString(s); + } else { + *name = new GooString("/tmp"); + } + (*name)->append("/XXXXXX")->append(ext); + fd = mkstemps((*name)->getCString(), strlen(ext)); +#elif defined(HAVE_MKSTEMP) + if ((s = getenv("TMPDIR"))) { + *name = new GooString(s); + } else { + *name = new GooString("/tmp"); + } + (*name)->append("/XXXXXX")->append(ext); + fd = mkstemp((*name)->getCString()); +#else + if (!(s = tmpnam(NULL))) { + return gFalse; + } + *name = new GooString(s); + (*name)->append(ext); + fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600); +#endif + } else { +#if HAVE_MKSTEMP + if ((s = getenv("TMPDIR"))) { + *name = new GooString(s); + } else { + *name = new GooString("/tmp"); + } + (*name)->append("/XXXXXX"); + fd = mkstemp((*name)->getCString()); +#else // HAVE_MKSTEMP + if (!(s = tmpnam(NULL))) { + return gFalse; + } + *name = new GooString(s); + fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600); +#endif // HAVE_MKSTEMP + } + if (fd < 0 || !(*f = fdopen(fd, mode))) { + delete *name; + return gFalse; + } + return gTrue; +#endif +} + +GBool executeCommand(char *cmd) { +#ifdef VMS + return system(cmd) ? gTrue : gFalse; +#else + return system(cmd) ? gFalse : gTrue; +#endif +} + +char *getLine(char *buf, int size, FILE *f) { + int c, i; + + i = 0; + while (i < size - 1) { + if ((c = fgetc(f)) == EOF) { + break; + } + buf[i++] = (char)c; + if (c == '\x0a') { + break; + } + if (c == '\x0d') { + c = fgetc(f); + if (c == '\x0a' && i < size - 1) { + buf[i++] = (char)c; + } else if (c != EOF) { + ungetc(c, f); + } + break; + } + } + buf[i] = '\0'; + if (i == 0) { + return NULL; + } + return buf; +} + +//------------------------------------------------------------------------ +// GDir and GDirEntry +//------------------------------------------------------------------------ + +GDirEntry::GDirEntry(char *dirPath, char *nameA, GBool doStat) { +#ifdef VMS + char *p; +#elif defined(WIN32) + int fa; +#elif defined(ACORN) +#else + struct stat st; +#endif + + name = new GooString(nameA); + dir = gFalse; + fullPath = new GooString(dirPath); + appendToPath(fullPath, nameA); + if (doStat) { +#ifdef VMS + if (!strcmp(nameA, "-") || + ((p = strrchr(nameA, '.')) && !strncmp(p, ".DIR;", 5))) + dir = gTrue; +#elif defined(ACORN) +#else +#ifdef WIN32 + fa = GetFileAttributes((TCHAR*)fullPath->getCString()); /* @note: TCHAR* cast */ + dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY)); +#else + if (stat(fullPath->getCString(), &st) == 0) + dir = S_ISDIR(st.st_mode); +#endif +#endif + } +} + +GDirEntry::~GDirEntry() { + delete fullPath; + delete name; +} + +GDir::GDir(char *name, GBool doStatA) { + path = new GooString(name); + doStat = doStatA; +#if defined(WIN32) + GooString *tmp; + + tmp = path->copy(); + tmp->append("/*.*"); + hnd = FindFirstFile((TCHAR*)tmp->getCString(), &ffd); /* @note: TCHAR* cast */ + delete tmp; +#elif defined(ACORN) +#elif defined(MACOS) +#else + dir = opendir(name); +#ifdef VMS + needParent = strchr(name, '[') != NULL; +#endif +#endif +} + +GDir::~GDir() { + delete path; +#if defined(WIN32) + if (INVALID_HANDLE_VALUE != hnd) + FindClose(hnd); +#elif defined(ACORN) +#elif defined(MACOS) +#else + if (dir) + closedir(dir); +#endif +} + +GDirEntry *GDir::getNextEntry() { + GDirEntry *e; + +#if defined(WIN32) + if (INVALID_HANDLE_VALUE == hnd) + return NULL; + + e = new GDirEntry(path->getCString(), (char*)ffd.cFileName, doStat);/* @note: char* cast */ + BOOL found = FindNextFile(hnd, &ffd); + if (!found) { + FindClose(hnd); + hnd = INVALID_HANDLE_VALUE; + } +#elif defined(ACORN) +#elif defined(MACOS) +#elif defined(VMS) + struct dirent *ent; + e = NULL; + if (dir) { + if (needParent) { + e = new GDirEntry(path->getCString(), "-", doStat); + needParent = gFalse; + return e; + } + ent = readdir(dir); + if (ent) { + e = new GDirEntry(path->getCString(), ent->d_name, doStat); + } + } +#else + struct dirent *ent; + e = NULL; + if (dir) { + do { + ent = readdir(dir); + } + while (ent && (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))); + if (ent) { + e = new GDirEntry(path->getCString(), ent->d_name, doStat); + } + } +#endif + + return e; +} + +void GDir::rewind() { +#ifdef WIN32 + GooString *tmp; + + if (hnd) + FindClose(hnd); + tmp = path->copy(); + tmp->append("/*.*"); + hnd = FindFirstFile((TCHAR*)tmp->getCString(), &ffd); /* @note: TCHAR* cast */ + delete tmp; +#elif defined(ACORN) +#elif defined(MACOS) +#else + if (dir) + rewinddir(dir); +#ifdef VMS + needParent = strchr(path->getCString(), '[') != NULL; +#endif +#endif +} diff --git a/rosapps/smartpdf/poppler/goo/gfile.h b/rosapps/smartpdf/poppler/goo/gfile.h new file mode 100644 index 00000000000..ce505624002 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/gfile.h @@ -0,0 +1,142 @@ +//======================================================================== +// +// gfile.h +// +// Miscellaneous file and directory name manipulation. +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GFILE_H +#define GFILE_H + +#include +#include +#include +extern "C" { +#if defined(WIN32) +# include +# ifdef FPTEX +# include +# else +# include +# endif +#elif defined(ACORN) +#elif defined(MACOS) +# include +#else +# include +# include +# ifdef VMS +# include "vms_dirent.h" +# elif HAVE_DIRENT_H +# include +# define NAMLEN(d) strlen((d)->d_name) +# else +# define dirent direct +# define NAMLEN(d) (d)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# endif +#endif +} +#include "gtypes.h" + +class GooString; + +//------------------------------------------------------------------------ + +// Get home directory path. +extern GooString *getHomeDir(); + +// Get current directory. +extern GooString *getCurrentDir(); + +// Append a file name to a path string. may be an empty +// string, denoting the current directory). Returns . +extern GooString *appendToPath(GooString *path, char *fileName); + +// Grab the path from the front of the file name. If there is no +// directory component in , returns an empty string. +extern GooString *grabPath(char *fileName); + +// Is this an absolute path or file name? +extern GBool isAbsolutePath(char *path); + +// Make this path absolute by prepending current directory (if path is +// relative) or prepending user's directory (if path starts with '~'). +extern GooString *makePathAbsolute(GooString *path); + +// Get the modification time for . Returns 0 if there is an +// error. +extern time_t getModTime(char *fileName); + +// Create a temporary file and open it for writing. If is not +// NULL, it will be used as the file name extension. Returns both the +// name and the file pointer. For security reasons, all writing +// should be done to the returned file pointer; the file may be +// reopened later for reading, but not for writing. The string +// should be "w" or "wb". Returns true on success. +extern GBool openTempFile(GooString **name, FILE **f, char *mode, char *ext); + +// Execute . Returns true on success. +extern GBool executeCommand(char *cmd); + +// Just like fgets, but handles Unix, Mac, and/or DOS end-of-line +// conventions. +extern char *getLine(char *buf, int size, FILE *f); + +//------------------------------------------------------------------------ +// GDir and GDirEntry +//------------------------------------------------------------------------ + +class GDirEntry { +public: + + GDirEntry(char *dirPath, char *nameA, GBool doStat); + ~GDirEntry(); + GooString *getName() { return name; } + GooString *getFullPath() { return fullPath; } + GBool isDir() { return dir; } + +private: + + GooString *name; // dir/file name + GooString *fullPath; + GBool dir; // is it a directory? +}; + +class GDir { +public: + + GDir(char *name, GBool doStatA = gTrue); + ~GDir(); + GDirEntry *getNextEntry(); + void rewind(); + +private: + + GooString *path; // directory path + GBool doStat; // call stat() for each entry? +#if defined(WIN32) + WIN32_FIND_DATA ffd; + HANDLE hnd; +#elif defined(ACORN) +#elif defined(MACOS) +#else + DIR *dir; // the DIR structure from opendir() +#ifdef VMS + GBool needParent; // need to return an entry for [-] +#endif +#endif +}; + +#endif diff --git a/rosapps/smartpdf/poppler/goo/gmem.c b/rosapps/smartpdf/poppler/goo/gmem.c new file mode 100644 index 00000000000..9925af484ee --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/gmem.c @@ -0,0 +1,275 @@ +/* + * gmem.c + * + * Memory routines with out-of-memory checking. + * + * Copyright 1996-2003 Glyph & Cog, LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include "gmem.h" +#include "FastAlloc.h" +#ifdef USE_KAZLIB_EXCEPT +#include "except.h" +#endif + +#ifdef DEBUG_MEM + +typedef struct _GMemHdr { + int size; + int index; + struct _GMemHdr *next; +} GMemHdr; + +#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7) +#define gMemTrlSize (sizeof(long)) + +#if gmemTrlSize==8 +#define gMemDeadVal 0xdeadbeefdeadbeefUL +#else +#define gMemDeadVal 0xdeadbeefUL +#endif + +/* round data size so trailer will be aligned */ +#define gMemDataSize(size) \ + ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize) + +#define gMemNLists 64 +#define gMemListShift 4 +#define gMemListMask (gMemNLists - 1) +static GMemHdr *gMemList[gMemNLists] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static int gMemIndex = 0; +static int gMemAlloc = 0; +static int gMemInUse = 0; + +void *gmalloc(size_t size) { + size_t size1; + char *mem; + GMemHdr *hdr; + void *data; + int lst; + unsigned long *trl, *p; + + if (size <= 0) + return NULL; + size1 = gMemDataSize(size); + if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + hdr = (GMemHdr *)mem; + data = (void *)(mem + gMemHdrSize); + trl = (unsigned long *)(mem + gMemHdrSize + size1); + hdr->size = size; + hdr->index = gMemIndex++; + lst = ((int)hdr >> gMemListShift) & gMemListMask; + hdr->next = gMemList[lst]; + gMemList[lst] = hdr; + ++gMemAlloc; + gMemInUse += size; + for (p = (unsigned long *)data; p <= trl; ++p) + *p = gMemDeadVal; + return data; +} + +void *grealloc(void *p, size_t size) { + GMemHdr *hdr; + void *q; + size_t oldSize; + + if (size <= 0) { + if (p) + gfree(p); + return NULL; + } + if (p) { + hdr = (GMemHdr *)((char *)p - gMemHdrSize); + oldSize = hdr->size; + q = gmalloc(size); + memcpy(q, p, size < oldSize ? size : oldSize); + gfree(p); + } else { + q = gmalloc(size); + } + return q; +} + +void gfree(void *p) { + size_t size; + GMemHdr *hdr; + GMemHdr *prevHdr, *q; + int lst; + unsigned long *trl, *clr; + + if (p) { + hdr = (GMemHdr *)((char *)p - gMemHdrSize); + lst = ((int)hdr >> gMemListShift) & gMemListMask; + for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) { + if (q == hdr) + break; + } + if (q) { + if (prevHdr) + prevHdr->next = hdr->next; + else + gMemList[lst] = hdr->next; + --gMemAlloc; + gMemInUse -= hdr->size; + size = gMemDataSize(hdr->size); + trl = (unsigned long *)((char *)hdr + gMemHdrSize + size); + if (*trl != gMemDeadVal) { + fprintf(stderr, "Overwrite past end of block %d at address %p\n", + hdr->index, p); + } + for (clr = (unsigned long *)hdr; clr <= trl; ++clr) + *clr = gMemDeadVal; + free(hdr); + } else { + fprintf(stderr, "Attempted to free bad address %p\n", p); + } + } +} + +void gMemReport(FILE *f) { + GMemHdr *p; + int lst; + + fprintf(f, "%d memory allocations in all\n", gMemIndex); + if (gMemAlloc > 0) { + fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc); + fprintf(f, " index size\n"); + fprintf(f, "-------- --------\n"); + for (lst = 0; lst < gMemNLists; ++lst) { + for (p = gMemList[lst]; p; p = p->next) + fprintf(f, "%8d %8d\n", p->index, p->size); + } + } else { + fprintf(f, "No memory blocks left allocated\n"); + } +} +#else /* DEBUG_MEM */ + +#ifdef DEBUG +/* You can simiulate low-memory under simulator by limiting the max size of + allocation in debug build by setting env variable PDF_ALLOC_LIMIT */ +#define NO_ALLOC_LIMIT (size_t)-1 +#define LIMIT_NOT_CHECKED (size_t)-2 +static size_t gAllocLimit = LIMIT_NOT_CHECKED; + +static int OverLimit(size_t size) { + if (LIMIT_NOT_CHECKED == gAllocLimit) { + char *limit = getenv("PDF_ALLOC_LIMIT"); + if (limit) { + gAllocLimit = atoi(limit); + printf("Max alloc is %d\n", (int)gAllocLimit); + } else { + gAllocLimit = NO_ALLOC_LIMIT; + } + } + if ((NO_ALLOC_LIMIT != gAllocLimit) && (size > gAllocLimit)) + return 1; + return 0; +} +#else +#define OverLimit(n) 0 +#endif + +void gfree(void *p) { +#ifdef USE_FAST_ALLOC + fast_free(p); +#else + free(p); +#endif +} + +void *gmalloc(size_t size) { + void *p = NULL; + if (!OverLimit(size)) { + #ifdef USE_FAST_ALLOC + p = fast_malloc(size); + #else + if (size <= 0) + return NULL; + p = malloc(size); + #endif + } +#ifdef USE_KAZLIB_EXCEPT + if ((0 != size) && (NULL == p)) + except_throw(1, 1, "out of memory"); +#endif + return p; +} + +void *grealloc(void *p, size_t size) { + void *q = NULL; + if (!OverLimit(size)) { + #ifdef USE_FAST_ALLOC + q = fast_realloc(p, size); + #else + if (size <= 0) { + if (p) + free(p); + return NULL; + } + if (p) + q = realloc(p, size); + else + q = malloc(size); +#endif + } +#ifdef USE_KAZLIB_EXCEPT + if ((0 != size) && (NULL == q)) + except_throw(1, 1, "out of memory"); +#endif + return q; +} +#endif /* !DEBUG_MEM */ + +void *gmallocn(int nObjs, int objSize) { + int n; + + n = nObjs * objSize; + assert((objSize != 0) && (n / objSize == nObjs)); + if (objSize == 0 || n / objSize != nObjs) { + fprintf(stderr, "Bogus memory allocation size\n"); + exit(1); + } + return gmalloc(n); +} + +void *greallocn(void *p, int nObjs, int objSize) { + int n; + + n = nObjs * objSize; + assert((objSize != 0) && (n / objSize == nObjs)); + if (objSize == 0 || n / objSize != nObjs) { + fprintf(stderr, "Bogus memory allocation size\n"); + exit(1); + } + return grealloc(p, n); +} + +char *copyString(char *s) { + char *s1; + + int len = strlen(s) + 1; + s1 = (char *)gmalloc(len); + strcpy(s1, s); + return s1; +} diff --git a/rosapps/smartpdf/poppler/goo/gmem.h b/rosapps/smartpdf/poppler/goo/gmem.h new file mode 100644 index 00000000000..267d1b995cc --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/gmem.h @@ -0,0 +1,62 @@ +/* + * gmem.h + * + * Memory routines with out-of-memory checking. + * + * Copyright 1996-2003 Glyph & Cog, LLC + */ + +#ifndef GMEM_H +#define GMEM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Same as malloc, but prints error message and exits if malloc() + * returns NULL. + */ +extern void *gmalloc(size_t size); + +/* + * Same as realloc, but prints error message and exits if realloc() + * returns NULL. If

is NULL, calls malloc instead of realloc(). + */ +extern void *grealloc(void *p, size_t size); + +/* + * These are similar to gmalloc and grealloc, but take an object count + * and size. The result is similar to allocating nObjs * objSize + * bytes, but there is an additional error check that the total size + * doesn't overflow an int. + */ +extern void *gmallocn(int nObjs, int objSize); +extern void *greallocn(void *p, int nObjs, int objSize); + +/* + * #ifdef DEBUG_MEM, adds debuging info. If not, same as free. + */ +extern void gfree(void *p); + +#ifdef DEBUG_MEM +/* + * Report on unfreed memory. + */ +extern void gMemReport(FILE *f); +#else +#define gMemReport(f) +#endif + +/* + * Allocate memory and copy a string into it. + */ +extern char *copyString(char *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/poppler/goo/gmempp.cc b/rosapps/smartpdf/poppler/goo/gmempp.cc new file mode 100644 index 00000000000..a70338ca3ce --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/gmempp.cc @@ -0,0 +1,32 @@ +//======================================================================== +// +// gmempp.cc +// +// Use gmalloc/gfree for C++ new/delete operators. +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include +#include "gmem.h" + +#ifdef DEBUG_MEM + +void *operator new(size_t size) { + return gmalloc((int)size); +} + +void *operator new[](size_t size) { + return gmalloc((int)size); +} + +void operator delete(void *p) { + gfree(p); +} + +void operator delete[](void *p) { + gfree(p); +} + +#endif diff --git a/rosapps/smartpdf/poppler/goo/gtypes.h b/rosapps/smartpdf/poppler/goo/gtypes.h new file mode 100644 index 00000000000..9f64f57d4a1 --- /dev/null +++ b/rosapps/smartpdf/poppler/goo/gtypes.h @@ -0,0 +1,29 @@ +/* + * gtypes.h + * + * Some useful simple types. + * + * Copyright 1996-2003 Glyph & Cog, LLC + */ + +#ifndef GTYPES_H +#define GTYPES_H + +/* + * These have stupid names to avoid conflicts with some (but not all) + * C++ compilers which define them. + */ +typedef int GBool; +#define gTrue 1 +#define gFalse 0 + +/* + * These have stupid names to avoid conflicts with , + * which on various systems defines some random subset of these. + */ +typedef unsigned char Guchar; +typedef unsigned short Gushort; +typedef unsigned int Guint; +typedef unsigned long Gulong; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Annot.cc b/rosapps/smartpdf/poppler/poppler/Annot.cc new file mode 100644 index 00000000000..6d07b87f425 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Annot.cc @@ -0,0 +1,325 @@ +//======================================================================== +// +// Annot.cc +// +// Copyright 2000-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "Object.h" +#include "Catalog.h" +#include "Gfx.h" +#include "Lexer.h" +#include "UGooString.h" +#include "Annot.h" + +//------------------------------------------------------------------------ +// Annot +//------------------------------------------------------------------------ + +Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict) { + Object apObj, asObj, obj1, obj2; + GBool regen, isTextField; + double t; + + ok = gTrue; + xref = xrefA; + appearBuf = NULL; + + if (dict->lookup("Rect", &obj1)->isArray() && + obj1.arrayGetLength() == 4) { + readArrayNum(&obj1, 0, &xMin); + readArrayNum(&obj1, 1, &yMin); + readArrayNum(&obj1, 2, &xMax); + readArrayNum(&obj1, 3, &yMax); + if (ok) { + if (xMin > xMax) { + t = xMin; xMin = xMax; xMax = t; + } + if (yMin > yMax) { + t = yMin; yMin = yMax; yMax = t; + } + } else { + //~ this should return an error + xMin = yMin = 0; + xMax = yMax = 1; + } + } else { + //~ this should return an error + xMin = yMin = 0; + xMax = yMax = 1; + } + obj1.free(); + + // check if field apperances need to be regenerated + regen = gFalse; + if (acroForm) { + acroForm->lookup("NeedAppearances", &obj1); + if (obj1.isBool() && obj1.getBool()) { + regen = gTrue; + } + obj1.free(); + } + + // check for a text-type field + isTextField = dict->lookup("FT", &obj1)->isName("Tx"); + obj1.free(); + +#if 0 //~ appearance stream generation is not finished yet + if (regen && isTextField) { + generateAppearance(acroForm, dict); + } else { +#endif + if (dict->lookup("AP", &apObj)->isDict()) { + if (dict->lookup("AS", &asObj)->isName()) { + if (apObj.dictLookup("N", &obj1)->isDict()) { + if (obj1.dictLookupNF(asObj.getNameC(), &obj2)->isRef()) { + obj2.copy(&appearance); + ok = gTrue; + } else { + obj2.free(); + if (obj1.dictLookupNF("Off", &obj2)->isRef()) { + obj2.copy(&appearance); + ok = gTrue; + } + } + obj2.free(); + } + obj1.free(); + } else { + if (apObj.dictLookupNF("N", &obj1)->isRef()) { + obj1.copy(&appearance); + ok = gTrue; + } + obj1.free(); + } + asObj.free(); + } + apObj.free(); +#if 0 //~ appearance stream generation is not finished yet + } +#endif +} + +void Annot::readArrayNum(Object *pdfArray, int key, double *value) { + Object valueObject; + + pdfArray->arrayGet(key, &valueObject); + if (valueObject.isNum()) { + *value = valueObject.getNum(); + } else { + *value = 0; + ok = gFalse; + } + valueObject.free(); +} + +Annot::~Annot() { + appearance.free(); + if (appearBuf) { + delete appearBuf; + } +} + +void Annot::generateAppearance(Dict *acroForm, Dict *dict) { + MemStream *appearStream; + Object daObj, vObj, drObj, appearDict, obj1, obj2; + GooString *daStr, *daStr1, *vStr, *s; + char buf[256]; + double fontSize; + int c; + int i0, i1; + + //~ DA can be inherited + if (dict->lookup("DA", &daObj)->isString()) { + daStr = daObj.getString(); + + // look for a font size + //~ may want to parse the DS entry in place of this (if it exists) + daStr1 = NULL; + fontSize = 10; + for (i1 = daStr->getLength() - 2; i1 >= 0; --i1) { + if (daStr->getChar(i1) == 'T' && daStr->getChar(i1+1) == 'f') { + for (--i1; i1 >= 0 && Lexer::isSpace(daStr->getChar(i1)); --i1) ; + for (i0 = i1; i0 >= 0 && !Lexer::isSpace(daStr->getChar(i0)); --i0) ; + if (i0 >= 0) { + ++i0; + ++i1; + s = new GooString(daStr, i0, i1 - i0); + fontSize = atof(s->getCString()); + delete s; + + // autosize the font + if (fontSize == 0) { + fontSize = 0.67 * (yMax - yMin); + daStr1 = new GooString(daStr, 0, i0); + sprintf(buf, "%.2f", fontSize); + daStr1->append(buf); + daStr1->append(daStr->getCString() + i1, + daStr->getLength() - i1); + } + } + break; + } + } + + // build the appearance stream contents + appearBuf = new GooString(); + appearBuf->append("/Tx BMC\n"); + appearBuf->append("q BT\n"); + appearBuf->append(daStr1 ? daStr1 : daStr)->append("\n"); + if (dict->lookup("V", &vObj)->isString()) { + //~ handle quadding -- this requires finding the font and using + //~ the encoding and char widths + sprintf(buf, "1 0 0 1 %.2f %.2f Tm\n", 2.0, yMax - yMin - fontSize); + appearBuf->append(buf); + sprintf(buf, "%g TL\n", fontSize); + appearBuf->append(buf); + vStr = vObj.getString(); + i0 = 0; + while (i0 < vStr->getLength()) { + for (i1 = i0; + i1 < vStr->getLength() && + vStr->getChar(i1) != '\n' && vStr->getChar(i1) != '\r'; + ++i1) ; + if (i0 > 0) { + appearBuf->append("T*\n"); + } + appearBuf->append('('); + for (; i0 < i1; ++i0) { + c = vStr->getChar(i0); + if (c == '(' || c == ')' || c == '\\') { + appearBuf->append('\\'); + appearBuf->append(c); + } else if (c < 0x20 || c >= 0x80) { + sprintf(buf, "\\%03o", c); + appearBuf->append(buf); + } else { + appearBuf->append(c); + } + } + appearBuf->append(") Tj\n"); + if (i1 + 1 < vStr->getLength() && + vStr->getChar(i1) == '\r' && vStr->getChar(i1 + 1) == '\n') { + i0 = i1 + 2; + } else { + i0 = i1 + 1; + } + } + } + vObj.free(); + appearBuf->append("ET Q\n"); + appearBuf->append("EMC\n"); + + // build the appearance stream dictionary + appearDict.initDict(xref); + appearDict.dictAdd("Length", obj1.initInt(appearBuf->getLength())); + appearDict.dictAdd("Subtype", obj1.initName("Form")); + obj1.initArray(xref); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(xMax - xMin)); + obj1.arrayAdd(obj2.initReal(yMax - yMin)); + appearDict.dictAdd("BBox", &obj1); + + // find the resource dictionary + dict->lookup("DR", &drObj); + if (!drObj.isDict()) { + dict->lookup("Parent", &obj1); + while (obj1.isDict()) { + drObj.free(); + obj1.dictLookup("DR", &drObj); + if (drObj.isDict()) { + break; + } + obj1.dictLookup("Parent", &obj2); + obj1.free(); + obj1 = obj2; + } + obj1.free(); + if (!drObj.isDict()) { + if (acroForm) { + drObj.free(); + acroForm->lookup("DR", &drObj); + } + } + } + if (drObj.isDict()) { + appearDict.dictAdd("Resources", drObj.copy(&obj1)); + } + drObj.free(); + + // build the appearance stream + appearStream = new MemStream(appearBuf->getCString(), 0, + appearBuf->getLength(), &appearDict); + appearance.initStream(appearStream); + ok = gTrue; + + if (daStr1) { + delete daStr1; + } + } + daObj.free(); +} + +void Annot::draw(Gfx *gfx) { + Object obj; + + if (appearance.fetch(xref, &obj)->isStream()) { + gfx->doAnnot(&obj, xMin, yMin, xMax, yMax); + } + obj.free(); +} + +//------------------------------------------------------------------------ +// Annots +//------------------------------------------------------------------------ + +Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) { + Dict *acroForm; + Annot *annot; + Object obj1; + int size; + int i; + + annots = NULL; + size = 0; + nAnnots = 0; + + acroForm = catalog->getAcroForm()->isDict() ? + catalog->getAcroForm()->getDict() : NULL; + if (annotsObj->isArray()) { + for (i = 0; i < annotsObj->arrayGetLength(); ++i) { + if (annotsObj->arrayGet(i, &obj1)->isDict()) { + annot = new Annot(xref, acroForm, obj1.getDict()); + if (annot->isOk()) { + if (nAnnots >= size) { + size += 16; + annots = (Annot **)greallocn(annots, size, sizeof(Annot *)); + } + annots[nAnnots++] = annot; + } else { + delete annot; + } + } + obj1.free(); + } + } +} + +Annots::~Annots() { + int i; + + for (i = 0; i < nAnnots; ++i) { + delete annots[i]; + } + gfree(annots); +} diff --git a/rosapps/smartpdf/poppler/poppler/Annot.h b/rosapps/smartpdf/poppler/poppler/Annot.h new file mode 100644 index 00000000000..5b1dd9b970e --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Annot.h @@ -0,0 +1,72 @@ +//======================================================================== +// +// Annot.h +// +// Copyright 2000-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef ANNOT_H +#define ANNOT_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +class XRef; +class Gfx; +class Catalog; + +//------------------------------------------------------------------------ +// Annot +//------------------------------------------------------------------------ + +class Annot { +public: + + Annot(XRef *xrefA, Dict *acroForm, Dict *dict); + ~Annot(); + GBool isOk() { return ok; } + + void draw(Gfx *gfx); + + // Get appearance object. + Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } + +private: + + void generateAppearance(Dict *acroForm, Dict *dict); + void readArrayNum(Object *pdfArray, int key, double *value); + + XRef *xref; // the xref table for this PDF file + Object appearance; // a reference to the Form XObject stream + // for the normal appearance + GooString *appearBuf; + double xMin, yMin, // annotation rectangle + xMax, yMax; + GBool ok; +}; + +//------------------------------------------------------------------------ +// Annots +//------------------------------------------------------------------------ + +class Annots { +public: + + // Extract non-link annotations from array of annotations. + Annots(XRef *xref, Catalog *catalog, Object *annotsObj); + + ~Annots(); + + // Iterate through list of annotations. + int getNumAnnots() { return nAnnots; } + Annot *getAnnot(int i) { return annots[i]; } + +private: + + Annot **annots; + int nAnnots; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Array.cc b/rosapps/smartpdf/poppler/poppler/Array.cc new file mode 100644 index 00000000000..b31d6c52bc4 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Array.cc @@ -0,0 +1,88 @@ +//======================================================================== +// +// Array.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "Object.h" +#include "Array.h" + +//------------------------------------------------------------------------ +// Array +//------------------------------------------------------------------------ + +Array::Array(XRef *xrefA) { + xref = xrefA; + elems = NULL; + size = length = 0; + ref = 1; +} + +Array::~Array() { + int i; + + for (i = 0; i < length; ++i) + elems[i].free(); + gfree(elems); +} + +void Array::add(Object *elem) { + if (length == size) { + if (length == 0) { + size = 8; + } else { + size *= 2; + } + elems = (Object *)greallocn(elems, size, sizeof(Object)); + } + elems[length] = *elem; + ++length; +} + +Object *Array::get(int i, Object *obj) { + if (i < 0 || i >= length) { +#ifdef DEBUG_MEM + abort(); +#else + return obj->initNull(); +#endif + } + return elems[i].fetch(xref, obj); +} + +Object *Array::getNF(int i, Object *obj) { + if (i < 0 || i >= length) { +#ifdef DEBUG_MEM + abort(); +#else + return obj->initNull(); +#endif + } + return elems[i].copy(obj); +} + +GBool Array::getString(int i, GooString *string) +{ + Object obj; + + if (getNF(i, &obj)->isString()) { + string->clear(); + string->append(obj.getString()); + obj.free(); + return gTrue; + } else { + obj.free(); + return gFalse; + } +} diff --git a/rosapps/smartpdf/poppler/poppler/Array.h b/rosapps/smartpdf/poppler/poppler/Array.h new file mode 100644 index 00000000000..a62833025b9 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Array.h @@ -0,0 +1,57 @@ +//======================================================================== +// +// Array.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef ARRAY_H +#define ARRAY_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "Object.h" + +class XRef; + +//------------------------------------------------------------------------ +// Array +//------------------------------------------------------------------------ + +class Array { +public: + + // Constructor. + Array(XRef *xrefA); + + // Destructor. + ~Array(); + + // Reference counting. + int incRef() { return ++ref; } + int decRef() { return --ref; } + + // Get number of elements. + int getLength() { return length; } + + // Add an element. + void add(Object *elem); + + // Accessors. + Object *get(int i, Object *obj); + Object *getNF(int i, Object *obj); + GBool getString(int i, GooString *string); + +private: + + XRef *xref; // the xref table for this PDF file + Object *elems; // array of elements + int size; // size of array + int length; // number of elements in array + int ref; // reference count +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/ArthurOutputDev.cc b/rosapps/smartpdf/poppler/poppler/ArthurOutputDev.cc new file mode 100644 index 00000000000..51bf4dff2f3 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/ArthurOutputDev.cc @@ -0,0 +1,743 @@ +//======================================================================== +// +// ArthurOutputDev.cc +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, Inc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include + +#include "goo/gfile.h" +#include "GlobalParams.h" +#include "Error.h" +#include "Object.h" +#include "GfxState.h" +#include "GfxFont.h" +#include "Link.h" +#include "CharCodeToUnicode.h" +#include "FontEncodingTables.h" +#include +#include "ArthurOutputDev.h" + +#include +#include +//------------------------------------------------------------------------ + +#include "splash/SplashFontFileID.h" +#include "splash/SplashFontFile.h" +#include "splash/SplashFontEngine.h" +#include "splash/SplashFont.h" +#include "splash/SplashMath.h" +#include "splash/SplashPath.h" +#include "splash/SplashGlyphBitmap.h" +//------------------------------------------------------------------------ +// SplashOutFontFileID +//------------------------------------------------------------------------ + +class SplashOutFontFileID: public SplashFontFileID { +public: + + SplashOutFontFileID(Ref *rA) { r = *rA; } + + ~SplashOutFontFileID() {} + + GBool matches(SplashFontFileID *id) { + return ((SplashOutFontFileID *)id)->r.num == r.num && + ((SplashOutFontFileID *)id)->r.gen == r.gen; + } + +private: + + Ref r; +}; + + + +//------------------------------------------------------------------------ +// ArthurOutputDev +//------------------------------------------------------------------------ + +ArthurOutputDev::ArthurOutputDev(QPainter *painter): + m_painter(painter) +{ + m_currentBrush = QBrush(Qt::SolidPattern); + m_fontEngine = 0; +} + +ArthurOutputDev::~ArthurOutputDev() +{ +} + +void ArthurOutputDev::startDoc(XRef *xrefA) { + int i; + + xref = xrefA; + if (m_fontEngine) { + delete m_fontEngine; + } + m_fontEngine = new SplashFontEngine( +#if HAVE_T1LIB_H + globalParams->getEnableT1lib(), +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + globalParams->getEnableFreeType(), +#endif + globalParams->getAntialias()); +} + +void ArthurOutputDev::startPage(int pageNum, GfxState *state) +{ + // fill page with white background. + int w = static_cast(state->getPageWidth()); + int h = static_cast(state->getPageHeight()); + QColor fillColour(Qt::white); + QBrush fill(fillColour); + m_painter->save(); + m_painter->setPen(fillColour); + m_painter->setBrush(fill); + m_painter->drawRect(0, 0, w, h); + m_painter->restore(); +} + +void ArthurOutputDev::endPage() { +} + +void ArthurOutputDev::drawLink(Link *link, Catalog *catalog) +{ +} + +void ArthurOutputDev::saveState(GfxState *state) +{ + m_painter->save(); +} + +void ArthurOutputDev::restoreState(GfxState *state) +{ + m_painter->restore(); +} + +void ArthurOutputDev::updateAll(GfxState *state) +{ + updateLineDash(state); + updateLineJoin(state); + updateLineCap(state); + updateLineWidth(state); + updateFlatness(state); + updateMiterLimit(state); + updateFillColor(state); + updateStrokeColor(state); + updateFillOpacity(state); + updateStrokeOpacity(state); + m_needFontUpdate = gTrue; +} + +// This looks wrong - why aren't adjusting the matrix? +void ArthurOutputDev::updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, + double m31, double m32) +{ + updateLineDash(state); + updateLineJoin(state); + updateLineCap(state); + updateLineWidth(state); +} + +void ArthurOutputDev::updateLineDash(GfxState *state) +{ + // qDebug() << "updateLineDash"; +} + +void ArthurOutputDev::updateFlatness(GfxState *state) +{ + // qDebug() << "updateFlatness"; +} + +void ArthurOutputDev::updateLineJoin(GfxState *state) +{ + switch (state->getLineJoin()) { + case 0: + m_currentPen.setJoinStyle(Qt::MiterJoin); + break; + case 1: + m_currentPen.setJoinStyle(Qt::RoundJoin); + break; + case 2: + m_currentPen.setJoinStyle(Qt::BevelJoin); + break; + } + m_painter->setPen(m_currentPen); +} + +void ArthurOutputDev::updateLineCap(GfxState *state) +{ + switch (state->getLineCap()) { + case 0: + m_currentPen.setCapStyle(Qt::FlatCap); + break; + case 1: + m_currentPen.setCapStyle(Qt::RoundCap); + break; + case 2: + m_currentPen.setCapStyle(Qt::SquareCap); + break; + } + m_painter->setPen(m_currentPen); +} + +void ArthurOutputDev::updateMiterLimit(GfxState *state) +{ + // We can't do mitre (or Miter) limit with Qt4 yet. + // the limit is in state->getMiterLimit() when we get there +} + +void ArthurOutputDev::updateLineWidth(GfxState *state) +{ + m_currentPen.setWidthF(state->getTransformedLineWidth()); + m_painter->setPen(m_currentPen); +} + +void ArthurOutputDev::updateFillColor(GfxState *state) +{ + GfxRGB rgb; + QColor brushColour = m_currentBrush.color(); + state->getFillRGB(&rgb); + brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF()); + m_currentBrush.setColor(brushColour); +} + +void ArthurOutputDev::updateStrokeColor(GfxState *state) +{ + GfxRGB rgb; + QColor penColour = m_currentPen.color(); + state->getStrokeRGB(&rgb); + penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF()); + m_currentPen.setColor(penColour); + m_painter->setPen(m_currentPen); +} + +void ArthurOutputDev::updateFillOpacity(GfxState *state) +{ + QColor brushColour= m_currentBrush.color(); + brushColour.setAlphaF(state->getFillOpacity()); + m_currentBrush.setColor(brushColour); +} + +void ArthurOutputDev::updateStrokeOpacity(GfxState *state) +{ + QColor penColour= m_currentPen.color(); + penColour.setAlphaF(state->getStrokeOpacity()); + m_currentPen.setColor(penColour); + m_painter->setPen(m_currentPen); +} + +void ArthurOutputDev::updateFont(GfxState *state) +{ + GfxFont *gfxFont; + GfxFontType fontType; + SplashOutFontFileID *id; + SplashFontFile *fontFile; + SplashFontSrc *fontsrc; + FoFiTrueType *ff; + Ref embRef; + Object refObj, strObj; + GooString *fileName, *substName; + char *tmpBuf; + int tmpBufLen; + Gushort *codeToGID; + DisplayFontParam *dfp; + double m11, m12, m21, m22, w1, w2; + SplashCoord mat[4]; + char *name; + int c, substIdx, n, code; + + m_needFontUpdate = false; + m_font = NULL; + fileName = NULL; + tmpBuf = NULL; + substIdx = -1; + + if (!(gfxFont = state->getFont())) { + goto err1; + } + fontType = gfxFont->getType(); + if (fontType == fontType3) { + goto err1; + } + + // check the font file cache + id = new SplashOutFontFileID(gfxFont->getID()); + if ((fontFile = m_fontEngine->getFontFile(id))) { + delete id; + + } else { + + // if there is an embedded font, write it to disk + if (gfxFont->getEmbeddedFontID(&embRef)) { + tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen); + if (! tmpBuf) + goto err2; + // if there is an external font file, use it + } else if (!(fileName = gfxFont->getExtFontFile())) { + + // look for a display font mapping or a substitute font + dfp = NULL; + if (gfxFont->getName()) { + dfp = globalParams->getDisplayFont(gfxFont); + } + if (!dfp) { + error(-1, "Couldn't find a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + switch (dfp->kind) { + case displayFontT1: + fileName = dfp->t1.fileName; + fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1; + break; + case displayFontTT: + fileName = dfp->tt.fileName; + fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType; + break; + } + } + + fontsrc = new SplashFontSrc; + if (fileName) + fontsrc->setFile(fileName, gFalse); + else + fontsrc->setBuf(tmpBuf, tmpBufLen, gFalse); + + // load the font file + switch (fontType) { + case fontType1: + if (!(fontFile = m_fontEngine->loadType1Font( + id, + fontsrc, + ((Gfx8BitFont *)gfxFont)->getEncoding()))) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontType1C: + if (!(fontFile = m_fontEngine->loadType1CFont( + id, + fontsrc, + ((Gfx8BitFont *)gfxFont)->getEncoding()))) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontTrueType: + if (!(ff = FoFiTrueType::load(fileName->getCString()))) { + goto err2; + } + codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff); + delete ff; + if (!(fontFile = m_fontEngine->loadTrueTypeFont( + id, + fontsrc, + codeToGID, 256))) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontCIDType0: + case fontCIDType0C: + if (!(fontFile = m_fontEngine->loadCIDFont( + id, + fontsrc))) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontCIDType2: + n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); + codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); + memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), + n * sizeof(Gushort)); + if (!(fontFile = m_fontEngine->loadTrueTypeFont( + id, + fontsrc, + codeToGID, n))) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + default: + // this shouldn't happen + goto err2; + } + } + + // get the font matrix + state->getFontTransMat(&m11, &m12, &m21, &m22); + m11 *= state->getHorizScaling(); + m12 *= state->getHorizScaling(); + + // create the scaled font + mat[0] = m11; mat[1] = -m12; + mat[2] = m21; mat[3] = -m22; + m_font = m_fontEngine->getFont(fontFile, mat); + + return; + + err2: + delete id; + err1: + return; +} + +static QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule) +{ + GfxSubpath *subpath; + double x1, y1, x2, y2, x3, y3; + int i, j; + + QPainterPath qPath; + qPath.setFillRule(fillRule); + for (i = 0; i < path->getNumSubpaths(); ++i) { + subpath = path->getSubpath(i); + if (subpath->getNumPoints() > 0) { + state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1); + qPath.moveTo(x1, y1); + j = 1; + while (j < subpath->getNumPoints()) { + if (subpath->getCurve(j)) { + state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1); + state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2); + state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3); + qPath.cubicTo( x1, y1, x2, y2, x3, y3); + j += 3; + } else { + state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1); + qPath.lineTo(x1, y1); + ++j; + } + } + if (subpath->isClosed()) { + qPath.closeSubpath(); + } + } + } + return qPath; +} + +void ArthurOutputDev::stroke(GfxState *state) +{ + m_painter->drawPath( convertPath( state, state->getPath(), Qt::OddEvenFill ) ); +} + +void ArthurOutputDev::fill(GfxState *state) +{ + m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush ); +} + +void ArthurOutputDev::eoFill(GfxState *state) +{ + m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush ); +} + +void ArthurOutputDev::clip(GfxState *state) +{ + m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) ); +} + +void ArthurOutputDev::eoClip(GfxState *state) +{ + m_painter->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ) ); +} + +void ArthurOutputDev::drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, Unicode *u, int uLen) { + double x1, y1; +// SplashPath *path; + int render; + + if (m_needFontUpdate) { + updateFont(state); + } + if (!m_font) { + return; + } + + // check for invisible text -- this is used by Acrobat Capture + render = state->getRender(); + if (render == 3) { + return; + } + + x -= originX; + y -= originY; + state->transform(x, y, &x1, &y1); + + // fill + if (!(render & 1)) { + int x0, y0, xFrac, yFrac; + SplashGlyphBitmap glyph; + + x0 = static_cast(floor(x1)); + xFrac = splashFloor((x1 - x0) * splashFontFraction); + y0 = static_cast(floor(y1)); + yFrac = splashFloor((y1 - y0) * splashFontFraction); + SplashPath * fontPath; + fontPath = m_font->getGlyphPath(code); + if (fontPath) { + QPainterPath qPath; + qPath.setFillRule(Qt::WindingFill); + for (int i = 0; i < fontPath->length; ++i) { + if (fontPath->flags[i] & splashPathFirst) { + qPath.moveTo(x0+fontPath->pts[i].x, y0+fontPath->pts[i].y); + } else if (fontPath->flags[i] & splashPathCurve) { + qPath.quadTo(x0+fontPath->pts[i].x, y0+fontPath->pts[i].y, + x0+fontPath->pts[i+1].x, y0+fontPath->pts[i+1].y); + ++i; + } else if (fontPath->flags[i] & splashPathArcCW) { + qDebug() << "Need to implement arc"; + } else { + qPath.lineTo(x0+fontPath->pts[i].x, y0+fontPath->pts[i].y); + } + if (fontPath->flags[i] & splashPathLast) { + qPath.closeSubpath(); + } + } + m_painter->save(); + GfxRGB rgb; + QColor brushColour = m_currentBrush.color(); + state->getFillRGB(&rgb); + brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getFillOpacity()); + m_painter->setBrush(brushColour); + QColor penColour = m_currentPen.color(); + state->getStrokeRGB(&rgb); + penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getStrokeOpacity()); + m_painter->setPen(penColour); + m_painter->drawPath( qPath ); + m_painter->restore(); + } + } + + // stroke + if ((render & 3) == 1 || (render & 3) == 2) { + qDebug() << "no stroke"; + /* + if ((path = m_font->getGlyphPath(code))) { + path->offset((SplashCoord)x1, (SplashCoord)y1); + splash->stroke(path); + delete path; + } + */ + } + + // clip + if (render & 4) { + qDebug() << "no clip"; + /* + path = m_font->getGlyphPath(code); + path->offset((SplashCoord)x1, (SplashCoord)y1); + if (textClipPath) { + textClipPath->append(path); + delete path; + } else { + textClipPath = path; + } + */ + } +} + +GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen) +{ + return gFalse; +} + +void ArthurOutputDev::endType3Char(GfxState *state) +{ +} + +void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy) +{ +} + +void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury) +{ +} + +void ArthurOutputDev::endTextObject(GfxState *state) +{ +} + + +void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) +{ + qDebug() << "drawImageMask"; +#if 0 + unsigned char *buffer; + unsigned char *dest; + cairo_surface_t *image; + cairo_pattern_t *pattern; + int x, y; + ImageStream *imgStr; + Guchar *pix; + double *ctm; + cairo_matrix_t matrix; + int invert_bit; + int row_stride; + + row_stride = (width + 3) & ~3; + buffer = (unsigned char *) malloc (height * row_stride); + if (buffer == NULL) { + error(-1, "Unable to allocate memory for image."); + return; + } + + /* TODO: Do we want to cache these? */ + imgStr = new ImageStream(str, width, 1, 1); + imgStr->reset(); + + invert_bit = invert ? 1 : 0; + + for (y = 0; y < height; y++) { + pix = imgStr->getLine(); + dest = buffer + y * row_stride; + for (x = 0; x < width; x++) { + + if (pix[x] ^ invert_bit) + *dest++ = 0; + else + *dest++ = 255; + } + } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8, + width, height, row_stride); + if (image == NULL) + return; + pattern = cairo_pattern_create_for_surface (image); + if (pattern == NULL) + return; + + ctm = state->getCTM(); + LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n", + width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5])); + matrix.xx = ctm[0] / width; + matrix.xy = -ctm[2] / height; + matrix.yx = ctm[1] / width; + matrix.yy = -ctm[3] / height; + matrix.x0 = ctm[2] + ctm[4]; + matrix.y0 = ctm[3] + ctm[5]; + cairo_matrix_invert (&matrix); + cairo_pattern_set_matrix (pattern, &matrix); + + cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST); + /* FIXME: Doesn't the image mask support any colorspace? */ + cairo_set_source_rgb (cairo, fill_color.r, fill_color.g, fill_color.b); + cairo_mask (cairo, pattern); + + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + free (buffer); + delete imgStr; +#endif +} + +//TODO: lots more work here. +void ArthurOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) +{ + unsigned char *buffer; + unsigned int *dest; + int x, y; + ImageStream *imgStr; + Guchar *pix; + GfxRGB rgb; + int alpha, i; + double *ctm; + QMatrix matrix; + int is_identity_transform; + + buffer = (unsigned char *)gmalloc (width * height * 4); + + /* TODO: Do we want to cache these? */ + imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + /* ICCBased color space doesn't do any color correction + * so check its underlying color space as well */ + is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csICCBased && + ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB; + + if (maskColors) { + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + + for (x = 0; x < width; x++) { + for (i = 0; i < colorMap->getNumPixelComps(); ++i) { + + if (pix[i] < maskColors[2*i] * 255|| + pix[i] > maskColors[2*i+1] * 255) { + *dest = *dest | 0xff000000; + break; + } + } + pix += colorMap->getNumPixelComps(); + dest++; + } + } + + m_image = new QImage(buffer, width, height, QImage::Format_ARGB32); + } + else { + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + } + + m_image = new QImage(buffer, width, height, QImage::Format_RGB32); + } + + if (m_image == NULL || m_image->isNull()) { + qDebug() << "Null image"; + return; + } + ctm = state->getCTM(); + matrix.setMatrix(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]); + + m_painter->setMatrix(matrix, true); + m_painter->drawImage( QPoint(0,0), *m_image ); + free (buffer); + delete imgStr; + +} diff --git a/rosapps/smartpdf/poppler/poppler/ArthurOutputDev.h b/rosapps/smartpdf/poppler/poppler/ArthurOutputDev.h new file mode 100644 index 00000000000..667e3b9aefc --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/ArthurOutputDev.h @@ -0,0 +1,144 @@ +//======================================================================== +// +// ArthurOutputDev.h +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, INC +// +//======================================================================== + +#ifndef CAIROOUTPUTDEV_H +#define CAIROOUTPUTDEV_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "OutputDev.h" +#include "GfxState.h" + +#include + +class GfxState; +class GfxPath; +class Gfx8BitFont; +struct GfxRGB; + +class SplashFont; +class SplashFontEngine; +class SplashGlyphBitmap; + +//------------------------------------------------------------------------ +// ArthurOutputDev - Qt 4 QPainter renderer +//------------------------------------------------------------------------ + +class ArthurOutputDev: public OutputDev { +public: + + // Constructor. + ArthurOutputDev(QPainter *painter ); + + // Destructor. + virtual ~ArthurOutputDev(); + + //----- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gTrue; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gTrue; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() { return gTrue; } + + //----- initialization and control + + // Start a page. + virtual void startPage(int pageNum, GfxState *state); + + // End a page. + virtual void endPage(); + + //----- link borders + virtual void drawLink(Link *link, Catalog *catalog); + + //----- save/restore graphics state + virtual void saveState(GfxState *state); + virtual void restoreState(GfxState *state); + + //----- update graphics state + virtual void updateAll(GfxState *state); + virtual void updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32); + virtual void updateLineDash(GfxState *state); + virtual void updateFlatness(GfxState *state); + virtual void updateLineJoin(GfxState *state); + virtual void updateLineCap(GfxState *state); + virtual void updateMiterLimit(GfxState *state); + virtual void updateLineWidth(GfxState *state); + virtual void updateFillColor(GfxState *state); + virtual void updateStrokeColor(GfxState *state); + virtual void updateFillOpacity(GfxState *state); + virtual void updateStrokeOpacity(GfxState *state); + + //----- update text state + virtual void updateFont(GfxState *state); + + //----- path painting + virtual void stroke(GfxState *state); + virtual void fill(GfxState *state); + virtual void eoFill(GfxState *state); + + //----- path clipping + virtual void clip(GfxState *state); + virtual void eoClip(GfxState *state); + + //----- text drawing + // virtual void drawString(GfxState *state, GooString *s); + virtual void drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, Unicode *u, int uLen); + virtual GBool beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen); + virtual void endType3Char(GfxState *state); + virtual void endTextObject(GfxState *state); + + //----- image drawing + virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg); + + //----- Type 3 font operators + virtual void type3D0(GfxState *state, double wx, double wy); + virtual void type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury); + + //----- special access + + // Called to indicate that a new PDF document has been loaded. + void startDoc(XRef *xrefA); + + GBool isReverseVideo() { return gFalse; } + +private: + QPainter *m_painter; + QFont m_currentFont; + QPen m_currentPen; + QBrush m_currentBrush; + GBool m_needFontUpdate; // set when the font needs to be updated + QImage *m_image; + SplashFontEngine *m_fontEngine; + SplashFont *m_font; // current font + XRef *xref; // xref table for current document +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/BaseFile.h b/rosapps/smartpdf/poppler/poppler/BaseFile.h new file mode 100644 index 00000000000..7aedec1a775 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/BaseFile.h @@ -0,0 +1,82 @@ +//======================================================================== +// +// BaseFile.h +// +// Copyright 1999 Derek B. Noonburg assigned by Michael Meeks. +// +//======================================================================== + +#ifndef BASEFILE_H +#define BASEFILE_H + +#include +#include + +#include "Error.h" + +typedef FILE * BaseFile; + +static inline BaseFile +bxpdfopen (GooString *fileName1) +{ + GooString *fileName2; + // try to open file + fileName2 = NULL; + BaseFile file; + +#ifdef VMS + if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) { + error(-1, "Couldn't open file '%s'", fileName->getCString()); + return NULL; + } +#else + if (!(file = fopen(fileName1->getCString(), "rb"))) { + fileName2 = fileName1->copy(); + fileName2->lowerCase(); + if (!(file = fopen(fileName2->getCString(), "rb"))) { + fileName2->upperCase(); + if (!(file = fopen(fileName2->getCString(), "rb"))) { + error(-1, "Couldn't open file '%s'", fileName1->getCString()); + delete fileName2; + return NULL; + } + } + delete fileName2; + } +#endif + return file; +} + +static inline void +bfclose (BaseFile file) +{ + fclose (file); +} + +static inline size_t +bfread (void *ptr, size_t size, size_t nmemb, BaseFile file) +{ + return fread (ptr, size, nmemb, file); +} + +static inline int +bfseek (BaseFile file, long offset, int whence) +{ + return fseek (file, offset, whence); +} + +static inline void +brewind (BaseFile file) +{ + rewind (file); +} + +static inline long +bftell (BaseFile file) +{ + return ftell (file); +}*/ + +#endif /* BASEFILE_H */ + + diff --git a/rosapps/smartpdf/poppler/poppler/BuiltinFont.cc b/rosapps/smartpdf/poppler/poppler/BuiltinFont.cc new file mode 100644 index 00000000000..329ff62fc39 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/BuiltinFont.cc @@ -0,0 +1,65 @@ +//======================================================================== +// +// BuiltinFont.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "FontEncodingTables.h" +#include "BuiltinFont.h" + +//------------------------------------------------------------------------ + +BuiltinFontWidths::BuiltinFontWidths(BuiltinFontWidth *widths, int sizeA) { + int i, h; + + size = sizeA; + tab = (BuiltinFontWidth **)gmallocn(size, sizeof(BuiltinFontWidth *)); + for (i = 0; i < size; ++i) { + tab[i] = NULL; + } + for (i = 0; i < sizeA; ++i) { + h = hash(widths[i].name); + widths[i].next = tab[h]; + tab[h] = &widths[i]; + } +} + +BuiltinFontWidths::~BuiltinFontWidths() { + gfree(tab); +} + +GBool BuiltinFontWidths::getWidth(char *name, Gushort *width) { + int h; + BuiltinFontWidth *p; + + h = hash(name); + for (p = tab[h]; p; p = p->next) { + if (!strcmp(p->name, name)) { + *width = p->width; + return gTrue; + } + } + return gFalse; +} + +int BuiltinFontWidths::hash(char *name) { + char *p; + unsigned int h; + + h = 0; + for (p = name; *p; ++p) { + h = 17 * h + (int)(*p & 0xff); + } + return (int)(h % size); +} diff --git a/rosapps/smartpdf/poppler/poppler/BuiltinFont.h b/rosapps/smartpdf/poppler/poppler/BuiltinFont.h new file mode 100644 index 00000000000..8652034fd63 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/BuiltinFont.h @@ -0,0 +1,55 @@ +//======================================================================== +// +// BuiltinFont.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef BUILTINFONT_H +#define BUILTINFONT_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +struct BuiltinFont; +class BuiltinFontWidths; + +//------------------------------------------------------------------------ + +struct BuiltinFont { + char *name; + char **defaultBaseEnc; + short ascent; + short descent; + short bbox[4]; + BuiltinFontWidths *widths; +}; + +//------------------------------------------------------------------------ + +struct BuiltinFontWidth { + char *name; + Gushort width; + BuiltinFontWidth *next; +}; + +class BuiltinFontWidths { +public: + + BuiltinFontWidths(BuiltinFontWidth *widths, int sizeA); + ~BuiltinFontWidths(); + GBool getWidth(char *name, Gushort *width); + +private: + + int hash(char *name); + + BuiltinFontWidth **tab; + int size; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/BuiltinFontTables.cc b/rosapps/smartpdf/poppler/poppler/BuiltinFontTables.cc new file mode 100644 index 00000000000..5115b7bcf13 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/BuiltinFontTables.cc @@ -0,0 +1,4284 @@ +//======================================================================== +// +// BuiltinFontTables.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include +#include +#include "FontEncodingTables.h" +#include "BuiltinFontTables.h" + +static BuiltinFontWidth courierWidthsTab[] = { + { "Ntilde", 600, NULL }, + { "rcaron", 600, NULL }, + { "kcommaaccent", 600, NULL }, + { "Ncommaaccent", 600, NULL }, + { "Zacute", 600, NULL }, + { "comma", 600, NULL }, + { "cedilla", 600, NULL }, + { "plusminus", 600, NULL }, + { "circumflex", 600, NULL }, + { "dotaccent", 600, NULL }, + { "edotaccent", 600, NULL }, + { "asciitilde", 600, NULL }, + { "colon", 600, NULL }, + { "onehalf", 600, NULL }, + { "dollar", 600, NULL }, + { "Lcaron", 600, NULL }, + { "ntilde", 600, NULL }, + { "Aogonek", 600, NULL }, + { "ncommaaccent", 600, NULL }, + { "minus", 600, NULL }, + { "Iogonek", 600, NULL }, + { "zacute", 600, NULL }, + { "yen", 600, NULL }, + { "space", 600, NULL }, + { "Omacron", 600, NULL }, + { "questiondown", 600, NULL }, + { "emdash", 600, NULL }, + { "Agrave", 600, NULL }, + { "three", 600, NULL }, + { "numbersign", 600, NULL }, + { "lcaron", 600, NULL }, + { "A", 600, NULL }, + { "B", 600, NULL }, + { "C", 600, NULL }, + { "aogonek", 600, NULL }, + { "D", 600, NULL }, + { "E", 600, NULL }, + { "onequarter", 600, NULL }, + { "F", 600, NULL }, + { "G", 600, NULL }, + { "H", 600, NULL }, + { "I", 600, NULL }, + { "J", 600, NULL }, + { "K", 600, NULL }, + { "iogonek", 600, NULL }, + { "L", 600, NULL }, + { "backslash", 600, NULL }, + { "periodcentered", 600, NULL }, + { "M", 600, NULL }, + { "N", 600, NULL }, + { "omacron", 600, NULL }, + { "Tcommaaccent", 600, NULL }, + { "O", 600, NULL }, + { "P", 600, NULL }, + { "Q", 600, NULL }, + { "Uhungarumlaut", 600, NULL }, + { "R", 600, NULL }, + { "Aacute", 600, NULL }, + { "caron", 600, NULL }, + { "S", 600, NULL }, + { "T", 600, NULL }, + { "U", 600, NULL }, + { "agrave", 600, NULL }, + { "V", 600, NULL }, + { "W", 600, NULL }, + { "equal", 600, NULL }, + { "question", 600, NULL }, + { "X", 600, NULL }, + { "Y", 600, NULL }, + { "Z", 600, NULL }, + { "four", 600, NULL }, + { "a", 600, NULL }, + { "Gcommaaccent", 600, NULL }, + { "b", 600, NULL }, + { "c", 600, NULL }, + { "d", 600, NULL }, + { "e", 600, NULL }, + { "f", 600, NULL }, + { "g", 600, NULL }, + { "bullet", 600, NULL }, + { "h", 600, NULL }, + { "i", 600, NULL }, + { "Oslash", 600, NULL }, + { "dagger", 600, NULL }, + { "j", 600, NULL }, + { "k", 600, NULL }, + { "l", 600, NULL }, + { "m", 600, NULL }, + { "n", 600, NULL }, + { "tcommaaccent", 600, NULL }, + { "o", 600, NULL }, + { "ordfeminine", 600, NULL }, + { "ring", 600, NULL }, + { "p", 600, NULL }, + { "q", 600, NULL }, + { "uhungarumlaut", 600, NULL }, + { "r", 600, NULL }, + { "twosuperior", 600, NULL }, + { "aacute", 600, NULL }, + { "s", 600, NULL }, + { "OE", 600, NULL }, + { "t", 600, NULL }, + { "divide", 600, NULL }, + { "u", 600, NULL }, + { "Ccaron", 600, NULL }, + { "v", 600, NULL }, + { "w", 600, NULL }, + { "x", 600, NULL }, + { "y", 600, NULL }, + { "z", 600, NULL }, + { "Gbreve", 600, NULL }, + { "commaaccent", 600, NULL }, + { "hungarumlaut", 600, NULL }, + { "Idotaccent", 600, NULL }, + { "Nacute", 600, NULL }, + { "quotedbl", 600, NULL }, + { "gcommaaccent", 600, NULL }, + { "mu", 600, NULL }, + { "greaterequal", 600, NULL }, + { "Scaron", 600, NULL }, + { "Lslash", 600, NULL }, + { "semicolon", 600, NULL }, + { "oslash", 600, NULL }, + { "lessequal", 600, NULL }, + { "lozenge", 600, NULL }, + { "parenright", 600, NULL }, + { "ccaron", 600, NULL }, + { "Ecircumflex", 600, NULL }, + { "gbreve", 600, NULL }, + { "trademark", 600, NULL }, + { "daggerdbl", 600, NULL }, + { "nacute", 600, NULL }, + { "macron", 600, NULL }, + { "Otilde", 600, NULL }, + { "Emacron", 600, NULL }, + { "ellipsis", 600, NULL }, + { "scaron", 600, NULL }, + { "AE", 600, NULL }, + { "Ucircumflex", 600, NULL }, + { "lslash", 600, NULL }, + { "quotedblleft", 600, NULL }, + { "hyphen", 600, NULL }, + { "guilsinglright", 600, NULL }, + { "quotesingle", 600, NULL }, + { "eight", 600, NULL }, + { "exclamdown", 600, NULL }, + { "endash", 600, NULL }, + { "oe", 600, NULL }, + { "Abreve", 600, NULL }, + { "Umacron", 600, NULL }, + { "ecircumflex", 600, NULL }, + { "Adieresis", 600, NULL }, + { "copyright", 600, NULL }, + { "Egrave", 600, NULL }, + { "slash", 600, NULL }, + { "Edieresis", 600, NULL }, + { "otilde", 600, NULL }, + { "Idieresis", 600, NULL }, + { "parenleft", 600, NULL }, + { "one", 600, NULL }, + { "emacron", 600, NULL }, + { "Odieresis", 600, NULL }, + { "ucircumflex", 600, NULL }, + { "bracketleft", 600, NULL }, + { "Ugrave", 600, NULL }, + { "quoteright", 600, NULL }, + { "Udieresis", 600, NULL }, + { "perthousand", 600, NULL }, + { "Ydieresis", 600, NULL }, + { "umacron", 600, NULL }, + { "abreve", 600, NULL }, + { "Eacute", 600, NULL }, + { "adieresis", 600, NULL }, + { "egrave", 600, NULL }, + { "edieresis", 600, NULL }, + { "idieresis", 600, NULL }, + { "Eth", 600, NULL }, + { "ae", 600, NULL }, + { "asterisk", 600, NULL }, + { "odieresis", 600, NULL }, + { "Uacute", 600, NULL }, + { "ugrave", 600, NULL }, + { "five", 600, NULL }, + { "nine", 600, NULL }, + { "udieresis", 600, NULL }, + { "Zcaron", 600, NULL }, + { "Scommaaccent", 600, NULL }, + { "threequarters", 600, NULL }, + { "guillemotright", 600, NULL }, + { "Ccedilla", 600, NULL }, + { "ydieresis", 600, NULL }, + { "tilde", 600, NULL }, + { "at", 600, NULL }, + { "eacute", 600, NULL }, + { "underscore", 600, NULL }, + { "Euro", 600, NULL }, + { "Dcroat", 600, NULL }, + { "zero", 600, NULL }, + { "multiply", 600, NULL }, + { "eth", 600, NULL }, + { "Scedilla", 600, NULL }, + { "Racute", 600, NULL }, + { "Ograve", 600, NULL }, + { "partialdiff", 600, NULL }, + { "uacute", 600, NULL }, + { "braceleft", 600, NULL }, + { "Thorn", 600, NULL }, + { "zcaron", 600, NULL }, + { "scommaaccent", 600, NULL }, + { "ccedilla", 600, NULL }, + { "Dcaron", 600, NULL }, + { "dcroat", 600, NULL }, + { "scedilla", 600, NULL }, + { "Oacute", 600, NULL }, + { "Ocircumflex", 600, NULL }, + { "ogonek", 600, NULL }, + { "ograve", 600, NULL }, + { "racute", 600, NULL }, + { "Tcaron", 600, NULL }, + { "Eogonek", 600, NULL }, + { "thorn", 600, NULL }, + { "degree", 600, NULL }, + { "registered", 600, NULL }, + { "radical", 600, NULL }, + { "Aring", 600, NULL }, + { "percent", 600, NULL }, + { "six", 600, NULL }, + { "paragraph", 600, NULL }, + { "dcaron", 600, NULL }, + { "Uogonek", 600, NULL }, + { "two", 600, NULL }, + { "summation", 600, NULL }, + { "Igrave", 600, NULL }, + { "Lacute", 600, NULL }, + { "ocircumflex", 600, NULL }, + { "oacute", 600, NULL }, + { "Uring", 600, NULL }, + { "Lcommaaccent", 600, NULL }, + { "tcaron", 600, NULL }, + { "eogonek", 600, NULL }, + { "Delta", 600, NULL }, + { "Ohungarumlaut", 600, NULL }, + { "asciicircum", 600, NULL }, + { "aring", 600, NULL }, + { "grave", 600, NULL }, + { "uogonek", 600, NULL }, + { "bracketright", 600, NULL }, + { "ampersand", 600, NULL }, + { "Iacute", 600, NULL }, + { "lacute", 600, NULL }, + { "igrave", 600, NULL }, + { "Ncaron", 600, NULL }, + { "plus", 600, NULL }, + { "uring", 600, NULL }, + { "quotesinglbase", 600, NULL }, + { "lcommaaccent", 600, NULL }, + { "Yacute", 600, NULL }, + { "ohungarumlaut", 600, NULL }, + { "threesuperior", 600, NULL }, + { "acute", 600, NULL }, + { "section", 600, NULL }, + { "dieresis", 600, NULL }, + { "quotedblbase", 600, NULL }, + { "iacute", 600, NULL }, + { "ncaron", 600, NULL }, + { "florin", 600, NULL }, + { "yacute", 600, NULL }, + { "Rcommaaccent", 600, NULL }, + { "fi", 600, NULL }, + { "fl", 600, NULL }, + { "Acircumflex", 600, NULL }, + { "Cacute", 600, NULL }, + { "Icircumflex", 600, NULL }, + { "guillemotleft", 600, NULL }, + { "germandbls", 600, NULL }, + { "seven", 600, NULL }, + { "Amacron", 600, NULL }, + { "Sacute", 600, NULL }, + { "ordmasculine", 600, NULL }, + { "dotlessi", 600, NULL }, + { "sterling", 600, NULL }, + { "notequal", 600, NULL }, + { "Imacron", 600, NULL }, + { "rcommaaccent", 600, NULL }, + { "Zdotaccent", 600, NULL }, + { "acircumflex", 600, NULL }, + { "cacute", 600, NULL }, + { "Ecaron", 600, NULL }, + { "braceright", 600, NULL }, + { "icircumflex", 600, NULL }, + { "quotedblright", 600, NULL }, + { "amacron", 600, NULL }, + { "sacute", 600, NULL }, + { "imacron", 600, NULL }, + { "cent", 600, NULL }, + { "currency", 600, NULL }, + { "logicalnot", 600, NULL }, + { "zdotaccent", 600, NULL }, + { "Atilde", 600, NULL }, + { "breve", 600, NULL }, + { "bar", 600, NULL }, + { "fraction", 600, NULL }, + { "less", 600, NULL }, + { "ecaron", 600, NULL }, + { "guilsinglleft", 600, NULL }, + { "exclam", 600, NULL }, + { "period", 600, NULL }, + { "Rcaron", 600, NULL }, + { "Kcommaaccent", 600, NULL }, + { "greater", 600, NULL }, + { "atilde", 600, NULL }, + { "brokenbar", 600, NULL }, + { "quoteleft", 600, NULL }, + { "Edotaccent", 600, NULL }, + { "onesuperior", 600, NULL } +}; + +static BuiltinFontWidth courierBoldWidthsTab[] = { + { "Ntilde", 600, NULL }, + { "rcaron", 600, NULL }, + { "kcommaaccent", 600, NULL }, + { "Ncommaaccent", 600, NULL }, + { "Zacute", 600, NULL }, + { "comma", 600, NULL }, + { "cedilla", 600, NULL }, + { "plusminus", 600, NULL }, + { "circumflex", 600, NULL }, + { "dotaccent", 600, NULL }, + { "edotaccent", 600, NULL }, + { "asciitilde", 600, NULL }, + { "colon", 600, NULL }, + { "onehalf", 600, NULL }, + { "dollar", 600, NULL }, + { "Lcaron", 600, NULL }, + { "ntilde", 600, NULL }, + { "Aogonek", 600, NULL }, + { "ncommaaccent", 600, NULL }, + { "minus", 600, NULL }, + { "Iogonek", 600, NULL }, + { "zacute", 600, NULL }, + { "yen", 600, NULL }, + { "space", 600, NULL }, + { "Omacron", 600, NULL }, + { "questiondown", 600, NULL }, + { "emdash", 600, NULL }, + { "Agrave", 600, NULL }, + { "three", 600, NULL }, + { "numbersign", 600, NULL }, + { "lcaron", 600, NULL }, + { "A", 600, NULL }, + { "B", 600, NULL }, + { "C", 600, NULL }, + { "aogonek", 600, NULL }, + { "D", 600, NULL }, + { "E", 600, NULL }, + { "onequarter", 600, NULL }, + { "F", 600, NULL }, + { "G", 600, NULL }, + { "H", 600, NULL }, + { "I", 600, NULL }, + { "J", 600, NULL }, + { "K", 600, NULL }, + { "iogonek", 600, NULL }, + { "backslash", 600, NULL }, + { "L", 600, NULL }, + { "periodcentered", 600, NULL }, + { "M", 600, NULL }, + { "N", 600, NULL }, + { "omacron", 600, NULL }, + { "Tcommaaccent", 600, NULL }, + { "O", 600, NULL }, + { "P", 600, NULL }, + { "Q", 600, NULL }, + { "Uhungarumlaut", 600, NULL }, + { "R", 600, NULL }, + { "Aacute", 600, NULL }, + { "caron", 600, NULL }, + { "S", 600, NULL }, + { "T", 600, NULL }, + { "U", 600, NULL }, + { "agrave", 600, NULL }, + { "V", 600, NULL }, + { "W", 600, NULL }, + { "X", 600, NULL }, + { "question", 600, NULL }, + { "equal", 600, NULL }, + { "Y", 600, NULL }, + { "Z", 600, NULL }, + { "four", 600, NULL }, + { "a", 600, NULL }, + { "Gcommaaccent", 600, NULL }, + { "b", 600, NULL }, + { "c", 600, NULL }, + { "d", 600, NULL }, + { "e", 600, NULL }, + { "f", 600, NULL }, + { "g", 600, NULL }, + { "bullet", 600, NULL }, + { "h", 600, NULL }, + { "i", 600, NULL }, + { "Oslash", 600, NULL }, + { "dagger", 600, NULL }, + { "j", 600, NULL }, + { "k", 600, NULL }, + { "l", 600, NULL }, + { "m", 600, NULL }, + { "n", 600, NULL }, + { "tcommaaccent", 600, NULL }, + { "o", 600, NULL }, + { "ordfeminine", 600, NULL }, + { "ring", 600, NULL }, + { "p", 600, NULL }, + { "q", 600, NULL }, + { "uhungarumlaut", 600, NULL }, + { "r", 600, NULL }, + { "twosuperior", 600, NULL }, + { "aacute", 600, NULL }, + { "s", 600, NULL }, + { "OE", 600, NULL }, + { "t", 600, NULL }, + { "divide", 600, NULL }, + { "u", 600, NULL }, + { "Ccaron", 600, NULL }, + { "v", 600, NULL }, + { "w", 600, NULL }, + { "x", 600, NULL }, + { "y", 600, NULL }, + { "z", 600, NULL }, + { "Gbreve", 600, NULL }, + { "commaaccent", 600, NULL }, + { "hungarumlaut", 600, NULL }, + { "Idotaccent", 600, NULL }, + { "Nacute", 600, NULL }, + { "quotedbl", 600, NULL }, + { "gcommaaccent", 600, NULL }, + { "mu", 600, NULL }, + { "greaterequal", 600, NULL }, + { "Scaron", 600, NULL }, + { "Lslash", 600, NULL }, + { "semicolon", 600, NULL }, + { "oslash", 600, NULL }, + { "lessequal", 600, NULL }, + { "lozenge", 600, NULL }, + { "parenright", 600, NULL }, + { "ccaron", 600, NULL }, + { "Ecircumflex", 600, NULL }, + { "gbreve", 600, NULL }, + { "trademark", 600, NULL }, + { "daggerdbl", 600, NULL }, + { "nacute", 600, NULL }, + { "macron", 600, NULL }, + { "Otilde", 600, NULL }, + { "Emacron", 600, NULL }, + { "ellipsis", 600, NULL }, + { "scaron", 600, NULL }, + { "AE", 600, NULL }, + { "Ucircumflex", 600, NULL }, + { "lslash", 600, NULL }, + { "quotedblleft", 600, NULL }, + { "guilsinglright", 600, NULL }, + { "hyphen", 600, NULL }, + { "quotesingle", 600, NULL }, + { "eight", 600, NULL }, + { "exclamdown", 600, NULL }, + { "endash", 600, NULL }, + { "oe", 600, NULL }, + { "Abreve", 600, NULL }, + { "Umacron", 600, NULL }, + { "ecircumflex", 600, NULL }, + { "Adieresis", 600, NULL }, + { "copyright", 600, NULL }, + { "Egrave", 600, NULL }, + { "slash", 600, NULL }, + { "Edieresis", 600, NULL }, + { "otilde", 600, NULL }, + { "Idieresis", 600, NULL }, + { "parenleft", 600, NULL }, + { "one", 600, NULL }, + { "emacron", 600, NULL }, + { "Odieresis", 600, NULL }, + { "ucircumflex", 600, NULL }, + { "bracketleft", 600, NULL }, + { "Ugrave", 600, NULL }, + { "quoteright", 600, NULL }, + { "Udieresis", 600, NULL }, + { "perthousand", 600, NULL }, + { "Ydieresis", 600, NULL }, + { "umacron", 600, NULL }, + { "abreve", 600, NULL }, + { "Eacute", 600, NULL }, + { "adieresis", 600, NULL }, + { "egrave", 600, NULL }, + { "edieresis", 600, NULL }, + { "idieresis", 600, NULL }, + { "Eth", 600, NULL }, + { "ae", 600, NULL }, + { "asterisk", 600, NULL }, + { "odieresis", 600, NULL }, + { "Uacute", 600, NULL }, + { "ugrave", 600, NULL }, + { "nine", 600, NULL }, + { "five", 600, NULL }, + { "udieresis", 600, NULL }, + { "Zcaron", 600, NULL }, + { "Scommaaccent", 600, NULL }, + { "threequarters", 600, NULL }, + { "guillemotright", 600, NULL }, + { "Ccedilla", 600, NULL }, + { "ydieresis", 600, NULL }, + { "tilde", 600, NULL }, + { "at", 600, NULL }, + { "eacute", 600, NULL }, + { "underscore", 600, NULL }, + { "Euro", 600, NULL }, + { "Dcroat", 600, NULL }, + { "multiply", 600, NULL }, + { "zero", 600, NULL }, + { "eth", 600, NULL }, + { "Scedilla", 600, NULL }, + { "Ograve", 600, NULL }, + { "Racute", 600, NULL }, + { "partialdiff", 600, NULL }, + { "uacute", 600, NULL }, + { "braceleft", 600, NULL }, + { "Thorn", 600, NULL }, + { "zcaron", 600, NULL }, + { "scommaaccent", 600, NULL }, + { "ccedilla", 600, NULL }, + { "Dcaron", 600, NULL }, + { "dcroat", 600, NULL }, + { "Ocircumflex", 600, NULL }, + { "Oacute", 600, NULL }, + { "scedilla", 600, NULL }, + { "ogonek", 600, NULL }, + { "ograve", 600, NULL }, + { "racute", 600, NULL }, + { "Tcaron", 600, NULL }, + { "Eogonek", 600, NULL }, + { "thorn", 600, NULL }, + { "degree", 600, NULL }, + { "registered", 600, NULL }, + { "radical", 600, NULL }, + { "Aring", 600, NULL }, + { "percent", 600, NULL }, + { "six", 600, NULL }, + { "paragraph", 600, NULL }, + { "dcaron", 600, NULL }, + { "Uogonek", 600, NULL }, + { "two", 600, NULL }, + { "summation", 600, NULL }, + { "Igrave", 600, NULL }, + { "Lacute", 600, NULL }, + { "ocircumflex", 600, NULL }, + { "oacute", 600, NULL }, + { "Uring", 600, NULL }, + { "Lcommaaccent", 600, NULL }, + { "tcaron", 600, NULL }, + { "eogonek", 600, NULL }, + { "Delta", 600, NULL }, + { "Ohungarumlaut", 600, NULL }, + { "asciicircum", 600, NULL }, + { "aring", 600, NULL }, + { "grave", 600, NULL }, + { "uogonek", 600, NULL }, + { "bracketright", 600, NULL }, + { "Iacute", 600, NULL }, + { "ampersand", 600, NULL }, + { "igrave", 600, NULL }, + { "lacute", 600, NULL }, + { "Ncaron", 600, NULL }, + { "plus", 600, NULL }, + { "uring", 600, NULL }, + { "quotesinglbase", 600, NULL }, + { "lcommaaccent", 600, NULL }, + { "Yacute", 600, NULL }, + { "ohungarumlaut", 600, NULL }, + { "threesuperior", 600, NULL }, + { "acute", 600, NULL }, + { "section", 600, NULL }, + { "dieresis", 600, NULL }, + { "iacute", 600, NULL }, + { "quotedblbase", 600, NULL }, + { "ncaron", 600, NULL }, + { "florin", 600, NULL }, + { "yacute", 600, NULL }, + { "Rcommaaccent", 600, NULL }, + { "fi", 600, NULL }, + { "fl", 600, NULL }, + { "Acircumflex", 600, NULL }, + { "Cacute", 600, NULL }, + { "Icircumflex", 600, NULL }, + { "guillemotleft", 600, NULL }, + { "germandbls", 600, NULL }, + { "Amacron", 600, NULL }, + { "seven", 600, NULL }, + { "Sacute", 600, NULL }, + { "ordmasculine", 600, NULL }, + { "dotlessi", 600, NULL }, + { "sterling", 600, NULL }, + { "notequal", 600, NULL }, + { "Imacron", 600, NULL }, + { "rcommaaccent", 600, NULL }, + { "Zdotaccent", 600, NULL }, + { "acircumflex", 600, NULL }, + { "cacute", 600, NULL }, + { "Ecaron", 600, NULL }, + { "icircumflex", 600, NULL }, + { "braceright", 600, NULL }, + { "quotedblright", 600, NULL }, + { "amacron", 600, NULL }, + { "sacute", 600, NULL }, + { "imacron", 600, NULL }, + { "cent", 600, NULL }, + { "currency", 600, NULL }, + { "logicalnot", 600, NULL }, + { "zdotaccent", 600, NULL }, + { "Atilde", 600, NULL }, + { "breve", 600, NULL }, + { "bar", 600, NULL }, + { "fraction", 600, NULL }, + { "less", 600, NULL }, + { "ecaron", 600, NULL }, + { "guilsinglleft", 600, NULL }, + { "exclam", 600, NULL }, + { "period", 600, NULL }, + { "Rcaron", 600, NULL }, + { "Kcommaaccent", 600, NULL }, + { "greater", 600, NULL }, + { "atilde", 600, NULL }, + { "brokenbar", 600, NULL }, + { "quoteleft", 600, NULL }, + { "Edotaccent", 600, NULL }, + { "onesuperior", 600, NULL } +}; + +static BuiltinFontWidth courierBoldObliqueWidthsTab[] = { + { "Ntilde", 600, NULL }, + { "rcaron", 600, NULL }, + { "kcommaaccent", 600, NULL }, + { "Ncommaaccent", 600, NULL }, + { "Zacute", 600, NULL }, + { "comma", 600, NULL }, + { "cedilla", 600, NULL }, + { "plusminus", 600, NULL }, + { "circumflex", 600, NULL }, + { "dotaccent", 600, NULL }, + { "edotaccent", 600, NULL }, + { "asciitilde", 600, NULL }, + { "colon", 600, NULL }, + { "onehalf", 600, NULL }, + { "dollar", 600, NULL }, + { "Lcaron", 600, NULL }, + { "ntilde", 600, NULL }, + { "Aogonek", 600, NULL }, + { "ncommaaccent", 600, NULL }, + { "minus", 600, NULL }, + { "Iogonek", 600, NULL }, + { "zacute", 600, NULL }, + { "yen", 600, NULL }, + { "space", 600, NULL }, + { "Omacron", 600, NULL }, + { "questiondown", 600, NULL }, + { "emdash", 600, NULL }, + { "Agrave", 600, NULL }, + { "three", 600, NULL }, + { "numbersign", 600, NULL }, + { "lcaron", 600, NULL }, + { "A", 600, NULL }, + { "B", 600, NULL }, + { "C", 600, NULL }, + { "aogonek", 600, NULL }, + { "D", 600, NULL }, + { "E", 600, NULL }, + { "onequarter", 600, NULL }, + { "F", 600, NULL }, + { "G", 600, NULL }, + { "H", 600, NULL }, + { "I", 600, NULL }, + { "J", 600, NULL }, + { "K", 600, NULL }, + { "iogonek", 600, NULL }, + { "backslash", 600, NULL }, + { "L", 600, NULL }, + { "periodcentered", 600, NULL }, + { "M", 600, NULL }, + { "N", 600, NULL }, + { "omacron", 600, NULL }, + { "Tcommaaccent", 600, NULL }, + { "O", 600, NULL }, + { "P", 600, NULL }, + { "Q", 600, NULL }, + { "Uhungarumlaut", 600, NULL }, + { "R", 600, NULL }, + { "Aacute", 600, NULL }, + { "caron", 600, NULL }, + { "S", 600, NULL }, + { "T", 600, NULL }, + { "U", 600, NULL }, + { "agrave", 600, NULL }, + { "V", 600, NULL }, + { "W", 600, NULL }, + { "X", 600, NULL }, + { "question", 600, NULL }, + { "equal", 600, NULL }, + { "Y", 600, NULL }, + { "Z", 600, NULL }, + { "four", 600, NULL }, + { "a", 600, NULL }, + { "Gcommaaccent", 600, NULL }, + { "b", 600, NULL }, + { "c", 600, NULL }, + { "d", 600, NULL }, + { "e", 600, NULL }, + { "f", 600, NULL }, + { "g", 600, NULL }, + { "bullet", 600, NULL }, + { "h", 600, NULL }, + { "i", 600, NULL }, + { "Oslash", 600, NULL }, + { "dagger", 600, NULL }, + { "j", 600, NULL }, + { "k", 600, NULL }, + { "l", 600, NULL }, + { "m", 600, NULL }, + { "n", 600, NULL }, + { "tcommaaccent", 600, NULL }, + { "o", 600, NULL }, + { "ordfeminine", 600, NULL }, + { "ring", 600, NULL }, + { "p", 600, NULL }, + { "q", 600, NULL }, + { "uhungarumlaut", 600, NULL }, + { "r", 600, NULL }, + { "twosuperior", 600, NULL }, + { "aacute", 600, NULL }, + { "s", 600, NULL }, + { "OE", 600, NULL }, + { "t", 600, NULL }, + { "divide", 600, NULL }, + { "u", 600, NULL }, + { "Ccaron", 600, NULL }, + { "v", 600, NULL }, + { "w", 600, NULL }, + { "x", 600, NULL }, + { "y", 600, NULL }, + { "z", 600, NULL }, + { "Gbreve", 600, NULL }, + { "commaaccent", 600, NULL }, + { "hungarumlaut", 600, NULL }, + { "Idotaccent", 600, NULL }, + { "Nacute", 600, NULL }, + { "quotedbl", 600, NULL }, + { "gcommaaccent", 600, NULL }, + { "mu", 600, NULL }, + { "greaterequal", 600, NULL }, + { "Scaron", 600, NULL }, + { "Lslash", 600, NULL }, + { "semicolon", 600, NULL }, + { "oslash", 600, NULL }, + { "lessequal", 600, NULL }, + { "lozenge", 600, NULL }, + { "parenright", 600, NULL }, + { "ccaron", 600, NULL }, + { "Ecircumflex", 600, NULL }, + { "gbreve", 600, NULL }, + { "trademark", 600, NULL }, + { "daggerdbl", 600, NULL }, + { "nacute", 600, NULL }, + { "macron", 600, NULL }, + { "Otilde", 600, NULL }, + { "Emacron", 600, NULL }, + { "ellipsis", 600, NULL }, + { "scaron", 600, NULL }, + { "AE", 600, NULL }, + { "Ucircumflex", 600, NULL }, + { "lslash", 600, NULL }, + { "quotedblleft", 600, NULL }, + { "guilsinglright", 600, NULL }, + { "hyphen", 600, NULL }, + { "quotesingle", 600, NULL }, + { "eight", 600, NULL }, + { "exclamdown", 600, NULL }, + { "endash", 600, NULL }, + { "oe", 600, NULL }, + { "Abreve", 600, NULL }, + { "Umacron", 600, NULL }, + { "ecircumflex", 600, NULL }, + { "Adieresis", 600, NULL }, + { "copyright", 600, NULL }, + { "Egrave", 600, NULL }, + { "slash", 600, NULL }, + { "Edieresis", 600, NULL }, + { "otilde", 600, NULL }, + { "Idieresis", 600, NULL }, + { "parenleft", 600, NULL }, + { "one", 600, NULL }, + { "emacron", 600, NULL }, + { "Odieresis", 600, NULL }, + { "ucircumflex", 600, NULL }, + { "bracketleft", 600, NULL }, + { "Ugrave", 600, NULL }, + { "quoteright", 600, NULL }, + { "Udieresis", 600, NULL }, + { "perthousand", 600, NULL }, + { "Ydieresis", 600, NULL }, + { "umacron", 600, NULL }, + { "abreve", 600, NULL }, + { "Eacute", 600, NULL }, + { "adieresis", 600, NULL }, + { "egrave", 600, NULL }, + { "edieresis", 600, NULL }, + { "idieresis", 600, NULL }, + { "Eth", 600, NULL }, + { "ae", 600, NULL }, + { "asterisk", 600, NULL }, + { "odieresis", 600, NULL }, + { "Uacute", 600, NULL }, + { "ugrave", 600, NULL }, + { "nine", 600, NULL }, + { "five", 600, NULL }, + { "udieresis", 600, NULL }, + { "Zcaron", 600, NULL }, + { "Scommaaccent", 600, NULL }, + { "threequarters", 600, NULL }, + { "guillemotright", 600, NULL }, + { "Ccedilla", 600, NULL }, + { "ydieresis", 600, NULL }, + { "tilde", 600, NULL }, + { "at", 600, NULL }, + { "eacute", 600, NULL }, + { "underscore", 600, NULL }, + { "Euro", 600, NULL }, + { "Dcroat", 600, NULL }, + { "multiply", 600, NULL }, + { "zero", 600, NULL }, + { "eth", 600, NULL }, + { "Scedilla", 600, NULL }, + { "Ograve", 600, NULL }, + { "Racute", 600, NULL }, + { "partialdiff", 600, NULL }, + { "uacute", 600, NULL }, + { "braceleft", 600, NULL }, + { "Thorn", 600, NULL }, + { "zcaron", 600, NULL }, + { "scommaaccent", 600, NULL }, + { "ccedilla", 600, NULL }, + { "Dcaron", 600, NULL }, + { "dcroat", 600, NULL }, + { "Ocircumflex", 600, NULL }, + { "Oacute", 600, NULL }, + { "scedilla", 600, NULL }, + { "ogonek", 600, NULL }, + { "ograve", 600, NULL }, + { "racute", 600, NULL }, + { "Tcaron", 600, NULL }, + { "Eogonek", 600, NULL }, + { "thorn", 600, NULL }, + { "degree", 600, NULL }, + { "registered", 600, NULL }, + { "radical", 600, NULL }, + { "Aring", 600, NULL }, + { "percent", 600, NULL }, + { "six", 600, NULL }, + { "paragraph", 600, NULL }, + { "dcaron", 600, NULL }, + { "Uogonek", 600, NULL }, + { "two", 600, NULL }, + { "summation", 600, NULL }, + { "Igrave", 600, NULL }, + { "Lacute", 600, NULL }, + { "ocircumflex", 600, NULL }, + { "oacute", 600, NULL }, + { "Uring", 600, NULL }, + { "Lcommaaccent", 600, NULL }, + { "tcaron", 600, NULL }, + { "eogonek", 600, NULL }, + { "Delta", 600, NULL }, + { "Ohungarumlaut", 600, NULL }, + { "asciicircum", 600, NULL }, + { "aring", 600, NULL }, + { "grave", 600, NULL }, + { "uogonek", 600, NULL }, + { "bracketright", 600, NULL }, + { "Iacute", 600, NULL }, + { "ampersand", 600, NULL }, + { "igrave", 600, NULL }, + { "lacute", 600, NULL }, + { "Ncaron", 600, NULL }, + { "plus", 600, NULL }, + { "uring", 600, NULL }, + { "quotesinglbase", 600, NULL }, + { "lcommaaccent", 600, NULL }, + { "Yacute", 600, NULL }, + { "ohungarumlaut", 600, NULL }, + { "threesuperior", 600, NULL }, + { "acute", 600, NULL }, + { "section", 600, NULL }, + { "dieresis", 600, NULL }, + { "iacute", 600, NULL }, + { "quotedblbase", 600, NULL }, + { "ncaron", 600, NULL }, + { "florin", 600, NULL }, + { "yacute", 600, NULL }, + { "Rcommaaccent", 600, NULL }, + { "fi", 600, NULL }, + { "fl", 600, NULL }, + { "Acircumflex", 600, NULL }, + { "Cacute", 600, NULL }, + { "Icircumflex", 600, NULL }, + { "guillemotleft", 600, NULL }, + { "germandbls", 600, NULL }, + { "Amacron", 600, NULL }, + { "seven", 600, NULL }, + { "Sacute", 600, NULL }, + { "ordmasculine", 600, NULL }, + { "dotlessi", 600, NULL }, + { "sterling", 600, NULL }, + { "notequal", 600, NULL }, + { "Imacron", 600, NULL }, + { "rcommaaccent", 600, NULL }, + { "Zdotaccent", 600, NULL }, + { "acircumflex", 600, NULL }, + { "cacute", 600, NULL }, + { "Ecaron", 600, NULL }, + { "icircumflex", 600, NULL }, + { "braceright", 600, NULL }, + { "quotedblright", 600, NULL }, + { "amacron", 600, NULL }, + { "sacute", 600, NULL }, + { "imacron", 600, NULL }, + { "cent", 600, NULL }, + { "currency", 600, NULL }, + { "logicalnot", 600, NULL }, + { "zdotaccent", 600, NULL }, + { "Atilde", 600, NULL }, + { "breve", 600, NULL }, + { "bar", 600, NULL }, + { "fraction", 600, NULL }, + { "less", 600, NULL }, + { "ecaron", 600, NULL }, + { "guilsinglleft", 600, NULL }, + { "exclam", 600, NULL }, + { "period", 600, NULL }, + { "Rcaron", 600, NULL }, + { "Kcommaaccent", 600, NULL }, + { "greater", 600, NULL }, + { "atilde", 600, NULL }, + { "brokenbar", 600, NULL }, + { "quoteleft", 600, NULL }, + { "Edotaccent", 600, NULL }, + { "onesuperior", 600, NULL } +}; + +static BuiltinFontWidth courierObliqueWidthsTab[] = { + { "Ntilde", 600, NULL }, + { "rcaron", 600, NULL }, + { "kcommaaccent", 600, NULL }, + { "Ncommaaccent", 600, NULL }, + { "Zacute", 600, NULL }, + { "comma", 600, NULL }, + { "cedilla", 600, NULL }, + { "plusminus", 600, NULL }, + { "circumflex", 600, NULL }, + { "dotaccent", 600, NULL }, + { "edotaccent", 600, NULL }, + { "asciitilde", 600, NULL }, + { "colon", 600, NULL }, + { "onehalf", 600, NULL }, + { "dollar", 600, NULL }, + { "Lcaron", 600, NULL }, + { "ntilde", 600, NULL }, + { "Aogonek", 600, NULL }, + { "ncommaaccent", 600, NULL }, + { "minus", 600, NULL }, + { "Iogonek", 600, NULL }, + { "zacute", 600, NULL }, + { "yen", 600, NULL }, + { "space", 600, NULL }, + { "Omacron", 600, NULL }, + { "questiondown", 600, NULL }, + { "emdash", 600, NULL }, + { "Agrave", 600, NULL }, + { "three", 600, NULL }, + { "numbersign", 600, NULL }, + { "lcaron", 600, NULL }, + { "A", 600, NULL }, + { "B", 600, NULL }, + { "C", 600, NULL }, + { "aogonek", 600, NULL }, + { "D", 600, NULL }, + { "E", 600, NULL }, + { "onequarter", 600, NULL }, + { "F", 600, NULL }, + { "G", 600, NULL }, + { "H", 600, NULL }, + { "I", 600, NULL }, + { "J", 600, NULL }, + { "K", 600, NULL }, + { "iogonek", 600, NULL }, + { "backslash", 600, NULL }, + { "L", 600, NULL }, + { "periodcentered", 600, NULL }, + { "M", 600, NULL }, + { "N", 600, NULL }, + { "omacron", 600, NULL }, + { "Tcommaaccent", 600, NULL }, + { "O", 600, NULL }, + { "P", 600, NULL }, + { "Q", 600, NULL }, + { "Uhungarumlaut", 600, NULL }, + { "R", 600, NULL }, + { "Aacute", 600, NULL }, + { "caron", 600, NULL }, + { "S", 600, NULL }, + { "T", 600, NULL }, + { "U", 600, NULL }, + { "agrave", 600, NULL }, + { "V", 600, NULL }, + { "W", 600, NULL }, + { "X", 600, NULL }, + { "question", 600, NULL }, + { "equal", 600, NULL }, + { "Y", 600, NULL }, + { "Z", 600, NULL }, + { "four", 600, NULL }, + { "a", 600, NULL }, + { "Gcommaaccent", 600, NULL }, + { "b", 600, NULL }, + { "c", 600, NULL }, + { "d", 600, NULL }, + { "e", 600, NULL }, + { "f", 600, NULL }, + { "g", 600, NULL }, + { "bullet", 600, NULL }, + { "h", 600, NULL }, + { "i", 600, NULL }, + { "Oslash", 600, NULL }, + { "dagger", 600, NULL }, + { "j", 600, NULL }, + { "k", 600, NULL }, + { "l", 600, NULL }, + { "m", 600, NULL }, + { "n", 600, NULL }, + { "tcommaaccent", 600, NULL }, + { "o", 600, NULL }, + { "ordfeminine", 600, NULL }, + { "ring", 600, NULL }, + { "p", 600, NULL }, + { "q", 600, NULL }, + { "uhungarumlaut", 600, NULL }, + { "r", 600, NULL }, + { "twosuperior", 600, NULL }, + { "aacute", 600, NULL }, + { "s", 600, NULL }, + { "OE", 600, NULL }, + { "t", 600, NULL }, + { "divide", 600, NULL }, + { "u", 600, NULL }, + { "Ccaron", 600, NULL }, + { "v", 600, NULL }, + { "w", 600, NULL }, + { "x", 600, NULL }, + { "y", 600, NULL }, + { "z", 600, NULL }, + { "Gbreve", 600, NULL }, + { "commaaccent", 600, NULL }, + { "hungarumlaut", 600, NULL }, + { "Idotaccent", 600, NULL }, + { "Nacute", 600, NULL }, + { "quotedbl", 600, NULL }, + { "gcommaaccent", 600, NULL }, + { "mu", 600, NULL }, + { "greaterequal", 600, NULL }, + { "Scaron", 600, NULL }, + { "Lslash", 600, NULL }, + { "semicolon", 600, NULL }, + { "oslash", 600, NULL }, + { "lessequal", 600, NULL }, + { "lozenge", 600, NULL }, + { "parenright", 600, NULL }, + { "ccaron", 600, NULL }, + { "Ecircumflex", 600, NULL }, + { "gbreve", 600, NULL }, + { "trademark", 600, NULL }, + { "daggerdbl", 600, NULL }, + { "nacute", 600, NULL }, + { "macron", 600, NULL }, + { "Otilde", 600, NULL }, + { "Emacron", 600, NULL }, + { "ellipsis", 600, NULL }, + { "scaron", 600, NULL }, + { "AE", 600, NULL }, + { "Ucircumflex", 600, NULL }, + { "lslash", 600, NULL }, + { "quotedblleft", 600, NULL }, + { "guilsinglright", 600, NULL }, + { "hyphen", 600, NULL }, + { "quotesingle", 600, NULL }, + { "eight", 600, NULL }, + { "exclamdown", 600, NULL }, + { "endash", 600, NULL }, + { "oe", 600, NULL }, + { "Abreve", 600, NULL }, + { "Umacron", 600, NULL }, + { "ecircumflex", 600, NULL }, + { "Adieresis", 600, NULL }, + { "copyright", 600, NULL }, + { "Egrave", 600, NULL }, + { "slash", 600, NULL }, + { "Edieresis", 600, NULL }, + { "otilde", 600, NULL }, + { "Idieresis", 600, NULL }, + { "parenleft", 600, NULL }, + { "one", 600, NULL }, + { "emacron", 600, NULL }, + { "Odieresis", 600, NULL }, + { "ucircumflex", 600, NULL }, + { "bracketleft", 600, NULL }, + { "Ugrave", 600, NULL }, + { "quoteright", 600, NULL }, + { "Udieresis", 600, NULL }, + { "perthousand", 600, NULL }, + { "Ydieresis", 600, NULL }, + { "umacron", 600, NULL }, + { "abreve", 600, NULL }, + { "Eacute", 600, NULL }, + { "adieresis", 600, NULL }, + { "egrave", 600, NULL }, + { "edieresis", 600, NULL }, + { "idieresis", 600, NULL }, + { "Eth", 600, NULL }, + { "ae", 600, NULL }, + { "asterisk", 600, NULL }, + { "odieresis", 600, NULL }, + { "Uacute", 600, NULL }, + { "ugrave", 600, NULL }, + { "nine", 600, NULL }, + { "five", 600, NULL }, + { "udieresis", 600, NULL }, + { "Zcaron", 600, NULL }, + { "Scommaaccent", 600, NULL }, + { "threequarters", 600, NULL }, + { "guillemotright", 600, NULL }, + { "Ccedilla", 600, NULL }, + { "ydieresis", 600, NULL }, + { "tilde", 600, NULL }, + { "at", 600, NULL }, + { "eacute", 600, NULL }, + { "underscore", 600, NULL }, + { "Euro", 600, NULL }, + { "Dcroat", 600, NULL }, + { "multiply", 600, NULL }, + { "zero", 600, NULL }, + { "eth", 600, NULL }, + { "Scedilla", 600, NULL }, + { "Ograve", 600, NULL }, + { "Racute", 600, NULL }, + { "partialdiff", 600, NULL }, + { "uacute", 600, NULL }, + { "braceleft", 600, NULL }, + { "Thorn", 600, NULL }, + { "zcaron", 600, NULL }, + { "scommaaccent", 600, NULL }, + { "ccedilla", 600, NULL }, + { "Dcaron", 600, NULL }, + { "dcroat", 600, NULL }, + { "Ocircumflex", 600, NULL }, + { "Oacute", 600, NULL }, + { "scedilla", 600, NULL }, + { "ogonek", 600, NULL }, + { "ograve", 600, NULL }, + { "racute", 600, NULL }, + { "Tcaron", 600, NULL }, + { "Eogonek", 600, NULL }, + { "thorn", 600, NULL }, + { "degree", 600, NULL }, + { "registered", 600, NULL }, + { "radical", 600, NULL }, + { "Aring", 600, NULL }, + { "percent", 600, NULL }, + { "six", 600, NULL }, + { "paragraph", 600, NULL }, + { "dcaron", 600, NULL }, + { "Uogonek", 600, NULL }, + { "two", 600, NULL }, + { "summation", 600, NULL }, + { "Igrave", 600, NULL }, + { "Lacute", 600, NULL }, + { "ocircumflex", 600, NULL }, + { "oacute", 600, NULL }, + { "Uring", 600, NULL }, + { "Lcommaaccent", 600, NULL }, + { "tcaron", 600, NULL }, + { "eogonek", 600, NULL }, + { "Delta", 600, NULL }, + { "Ohungarumlaut", 600, NULL }, + { "asciicircum", 600, NULL }, + { "aring", 600, NULL }, + { "grave", 600, NULL }, + { "uogonek", 600, NULL }, + { "bracketright", 600, NULL }, + { "Iacute", 600, NULL }, + { "ampersand", 600, NULL }, + { "igrave", 600, NULL }, + { "lacute", 600, NULL }, + { "Ncaron", 600, NULL }, + { "plus", 600, NULL }, + { "uring", 600, NULL }, + { "quotesinglbase", 600, NULL }, + { "lcommaaccent", 600, NULL }, + { "Yacute", 600, NULL }, + { "ohungarumlaut", 600, NULL }, + { "threesuperior", 600, NULL }, + { "acute", 600, NULL }, + { "section", 600, NULL }, + { "dieresis", 600, NULL }, + { "iacute", 600, NULL }, + { "quotedblbase", 600, NULL }, + { "ncaron", 600, NULL }, + { "florin", 600, NULL }, + { "yacute", 600, NULL }, + { "Rcommaaccent", 600, NULL }, + { "fi", 600, NULL }, + { "fl", 600, NULL }, + { "Acircumflex", 600, NULL }, + { "Cacute", 600, NULL }, + { "Icircumflex", 600, NULL }, + { "guillemotleft", 600, NULL }, + { "germandbls", 600, NULL }, + { "Amacron", 600, NULL }, + { "seven", 600, NULL }, + { "Sacute", 600, NULL }, + { "ordmasculine", 600, NULL }, + { "dotlessi", 600, NULL }, + { "sterling", 600, NULL }, + { "notequal", 600, NULL }, + { "Imacron", 600, NULL }, + { "rcommaaccent", 600, NULL }, + { "Zdotaccent", 600, NULL }, + { "acircumflex", 600, NULL }, + { "cacute", 600, NULL }, + { "Ecaron", 600, NULL }, + { "icircumflex", 600, NULL }, + { "braceright", 600, NULL }, + { "quotedblright", 600, NULL }, + { "amacron", 600, NULL }, + { "sacute", 600, NULL }, + { "imacron", 600, NULL }, + { "cent", 600, NULL }, + { "currency", 600, NULL }, + { "logicalnot", 600, NULL }, + { "zdotaccent", 600, NULL }, + { "Atilde", 600, NULL }, + { "breve", 600, NULL }, + { "bar", 600, NULL }, + { "fraction", 600, NULL }, + { "less", 600, NULL }, + { "ecaron", 600, NULL }, + { "guilsinglleft", 600, NULL }, + { "exclam", 600, NULL }, + { "period", 600, NULL }, + { "Rcaron", 600, NULL }, + { "Kcommaaccent", 600, NULL }, + { "greater", 600, NULL }, + { "atilde", 600, NULL }, + { "brokenbar", 600, NULL }, + { "quoteleft", 600, NULL }, + { "Edotaccent", 600, NULL }, + { "onesuperior", 600, NULL } +}; + +static BuiltinFontWidth helveticaWidthsTab[] = { + { "Ntilde", 722, NULL }, + { "rcaron", 333, NULL }, + { "kcommaaccent", 500, NULL }, + { "Ncommaaccent", 722, NULL }, + { "Zacute", 611, NULL }, + { "comma", 278, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 584, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 556, NULL }, + { "asciitilde", 584, NULL }, + { "colon", 278, NULL }, + { "onehalf", 834, NULL }, + { "dollar", 556, NULL }, + { "Lcaron", 556, NULL }, + { "ntilde", 556, NULL }, + { "Aogonek", 667, NULL }, + { "ncommaaccent", 556, NULL }, + { "minus", 584, NULL }, + { "Iogonek", 278, NULL }, + { "zacute", 500, NULL }, + { "yen", 556, NULL }, + { "space", 278, NULL }, + { "Omacron", 778, NULL }, + { "questiondown", 611, NULL }, + { "emdash", 1000, NULL }, + { "Agrave", 667, NULL }, + { "three", 556, NULL }, + { "numbersign", 556, NULL }, + { "lcaron", 299, NULL }, + { "A", 667, NULL }, + { "B", 667, NULL }, + { "C", 722, NULL }, + { "aogonek", 556, NULL }, + { "D", 722, NULL }, + { "E", 667, NULL }, + { "onequarter", 834, NULL }, + { "F", 611, NULL }, + { "G", 778, NULL }, + { "H", 722, NULL }, + { "I", 278, NULL }, + { "J", 500, NULL }, + { "K", 667, NULL }, + { "iogonek", 222, NULL }, + { "backslash", 278, NULL }, + { "L", 556, NULL }, + { "periodcentered", 278, NULL }, + { "M", 833, NULL }, + { "N", 722, NULL }, + { "omacron", 556, NULL }, + { "Tcommaaccent", 611, NULL }, + { "O", 778, NULL }, + { "P", 667, NULL }, + { "Q", 778, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 722, NULL }, + { "Aacute", 667, NULL }, + { "caron", 333, NULL }, + { "S", 667, NULL }, + { "T", 611, NULL }, + { "U", 722, NULL }, + { "agrave", 556, NULL }, + { "V", 667, NULL }, + { "W", 944, NULL }, + { "X", 667, NULL }, + { "question", 556, NULL }, + { "equal", 584, NULL }, + { "Y", 667, NULL }, + { "Z", 611, NULL }, + { "four", 556, NULL }, + { "a", 556, NULL }, + { "Gcommaaccent", 778, NULL }, + { "b", 556, NULL }, + { "c", 500, NULL }, + { "d", 556, NULL }, + { "e", 556, NULL }, + { "f", 278, NULL }, + { "g", 556, NULL }, + { "bullet", 350, NULL }, + { "h", 556, NULL }, + { "i", 222, NULL }, + { "Oslash", 778, NULL }, + { "dagger", 556, NULL }, + { "j", 222, NULL }, + { "k", 500, NULL }, + { "l", 222, NULL }, + { "m", 833, NULL }, + { "n", 556, NULL }, + { "tcommaaccent", 278, NULL }, + { "o", 556, NULL }, + { "ordfeminine", 370, NULL }, + { "ring", 333, NULL }, + { "p", 556, NULL }, + { "q", 556, NULL }, + { "uhungarumlaut", 556, NULL }, + { "r", 333, NULL }, + { "twosuperior", 333, NULL }, + { "aacute", 556, NULL }, + { "s", 500, NULL }, + { "OE", 1000, NULL }, + { "t", 278, NULL }, + { "divide", 584, NULL }, + { "u", 556, NULL }, + { "Ccaron", 722, NULL }, + { "v", 500, NULL }, + { "w", 722, NULL }, + { "x", 500, NULL }, + { "y", 500, NULL }, + { "z", 500, NULL }, + { "Gbreve", 778, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 278, NULL }, + { "Nacute", 722, NULL }, + { "quotedbl", 355, NULL }, + { "gcommaaccent", 556, NULL }, + { "mu", 556, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 667, NULL }, + { "Lslash", 556, NULL }, + { "semicolon", 278, NULL }, + { "oslash", 611, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 471, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 500, NULL }, + { "Ecircumflex", 667, NULL }, + { "gbreve", 556, NULL }, + { "trademark", 1000, NULL }, + { "daggerdbl", 556, NULL }, + { "nacute", 556, NULL }, + { "macron", 333, NULL }, + { "Otilde", 778, NULL }, + { "Emacron", 667, NULL }, + { "ellipsis", 1000, NULL }, + { "scaron", 500, NULL }, + { "AE", 1000, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 222, NULL }, + { "quotedblleft", 333, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 191, NULL }, + { "eight", 556, NULL }, + { "exclamdown", 333, NULL }, + { "endash", 556, NULL }, + { "oe", 944, NULL }, + { "Abreve", 667, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 556, NULL }, + { "Adieresis", 667, NULL }, + { "copyright", 737, NULL }, + { "Egrave", 667, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 667, NULL }, + { "otilde", 556, NULL }, + { "Idieresis", 278, NULL }, + { "parenleft", 333, NULL }, + { "one", 556, NULL }, + { "emacron", 556, NULL }, + { "Odieresis", 778, NULL }, + { "ucircumflex", 556, NULL }, + { "bracketleft", 278, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 222, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 667, NULL }, + { "umacron", 556, NULL }, + { "abreve", 556, NULL }, + { "Eacute", 667, NULL }, + { "adieresis", 556, NULL }, + { "egrave", 556, NULL }, + { "edieresis", 556, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 889, NULL }, + { "asterisk", 389, NULL }, + { "odieresis", 556, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 556, NULL }, + { "nine", 556, NULL }, + { "five", 556, NULL }, + { "udieresis", 556, NULL }, + { "Zcaron", 611, NULL }, + { "Scommaaccent", 667, NULL }, + { "threequarters", 834, NULL }, + { "guillemotright", 556, NULL }, + { "Ccedilla", 722, NULL }, + { "ydieresis", 500, NULL }, + { "tilde", 333, NULL }, + { "at", 1015, NULL }, + { "eacute", 556, NULL }, + { "underscore", 556, NULL }, + { "Euro", 556, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 584, NULL }, + { "zero", 556, NULL }, + { "eth", 556, NULL }, + { "Scedilla", 667, NULL }, + { "Ograve", 778, NULL }, + { "Racute", 722, NULL }, + { "partialdiff", 476, NULL }, + { "uacute", 556, NULL }, + { "braceleft", 334, NULL }, + { "Thorn", 667, NULL }, + { "zcaron", 500, NULL }, + { "scommaaccent", 500, NULL }, + { "ccedilla", 500, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 556, NULL }, + { "Ocircumflex", 778, NULL }, + { "Oacute", 778, NULL }, + { "scedilla", 500, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 556, NULL }, + { "racute", 333, NULL }, + { "Tcaron", 611, NULL }, + { "Eogonek", 667, NULL }, + { "thorn", 556, NULL }, + { "degree", 400, NULL }, + { "registered", 737, NULL }, + { "radical", 453, NULL }, + { "Aring", 667, NULL }, + { "percent", 889, NULL }, + { "six", 556, NULL }, + { "paragraph", 537, NULL }, + { "dcaron", 643, NULL }, + { "Uogonek", 722, NULL }, + { "two", 556, NULL }, + { "summation", 600, NULL }, + { "Igrave", 278, NULL }, + { "Lacute", 556, NULL }, + { "ocircumflex", 556, NULL }, + { "oacute", 556, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 556, NULL }, + { "tcaron", 317, NULL }, + { "eogonek", 556, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 778, NULL }, + { "asciicircum", 469, NULL }, + { "aring", 556, NULL }, + { "grave", 333, NULL }, + { "uogonek", 556, NULL }, + { "bracketright", 278, NULL }, + { "Iacute", 278, NULL }, + { "ampersand", 667, NULL }, + { "igrave", 278, NULL }, + { "lacute", 222, NULL }, + { "Ncaron", 722, NULL }, + { "plus", 584, NULL }, + { "uring", 556, NULL }, + { "quotesinglbase", 222, NULL }, + { "lcommaaccent", 222, NULL }, + { "Yacute", 667, NULL }, + { "ohungarumlaut", 556, NULL }, + { "threesuperior", 333, NULL }, + { "acute", 333, NULL }, + { "section", 556, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 333, NULL }, + { "ncaron", 556, NULL }, + { "florin", 556, NULL }, + { "yacute", 500, NULL }, + { "Rcommaaccent", 722, NULL }, + { "fi", 500, NULL }, + { "fl", 500, NULL }, + { "Acircumflex", 667, NULL }, + { "Cacute", 722, NULL }, + { "Icircumflex", 278, NULL }, + { "guillemotleft", 556, NULL }, + { "germandbls", 611, NULL }, + { "Amacron", 667, NULL }, + { "seven", 556, NULL }, + { "Sacute", 667, NULL }, + { "ordmasculine", 365, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 556, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 278, NULL }, + { "rcommaaccent", 333, NULL }, + { "Zdotaccent", 611, NULL }, + { "acircumflex", 556, NULL }, + { "cacute", 500, NULL }, + { "Ecaron", 667, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 334, NULL }, + { "quotedblright", 333, NULL }, + { "amacron", 556, NULL }, + { "sacute", 500, NULL }, + { "imacron", 278, NULL }, + { "cent", 556, NULL }, + { "currency", 556, NULL }, + { "logicalnot", 584, NULL }, + { "zdotaccent", 500, NULL }, + { "Atilde", 667, NULL }, + { "breve", 333, NULL }, + { "bar", 260, NULL }, + { "fraction", 167, NULL }, + { "less", 584, NULL }, + { "ecaron", 556, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 278, NULL }, + { "period", 278, NULL }, + { "Rcaron", 722, NULL }, + { "Kcommaaccent", 667, NULL }, + { "greater", 584, NULL }, + { "atilde", 556, NULL }, + { "brokenbar", 260, NULL }, + { "quoteleft", 222, NULL }, + { "Edotaccent", 667, NULL }, + { "onesuperior", 333, NULL } +}; + +static BuiltinFontWidth helveticaBoldWidthsTab[] = { + { "Ntilde", 722, NULL }, + { "rcaron", 389, NULL }, + { "kcommaaccent", 556, NULL }, + { "Ncommaaccent", 722, NULL }, + { "Zacute", 611, NULL }, + { "comma", 278, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 584, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 556, NULL }, + { "asciitilde", 584, NULL }, + { "colon", 333, NULL }, + { "onehalf", 834, NULL }, + { "dollar", 556, NULL }, + { "Lcaron", 611, NULL }, + { "ntilde", 611, NULL }, + { "Aogonek", 722, NULL }, + { "ncommaaccent", 611, NULL }, + { "minus", 584, NULL }, + { "Iogonek", 278, NULL }, + { "zacute", 500, NULL }, + { "yen", 556, NULL }, + { "space", 278, NULL }, + { "Omacron", 778, NULL }, + { "questiondown", 611, NULL }, + { "emdash", 1000, NULL }, + { "Agrave", 722, NULL }, + { "three", 556, NULL }, + { "numbersign", 556, NULL }, + { "lcaron", 400, NULL }, + { "A", 722, NULL }, + { "B", 722, NULL }, + { "C", 722, NULL }, + { "aogonek", 556, NULL }, + { "D", 722, NULL }, + { "E", 667, NULL }, + { "onequarter", 834, NULL }, + { "F", 611, NULL }, + { "G", 778, NULL }, + { "H", 722, NULL }, + { "I", 278, NULL }, + { "J", 556, NULL }, + { "K", 722, NULL }, + { "iogonek", 278, NULL }, + { "backslash", 278, NULL }, + { "L", 611, NULL }, + { "periodcentered", 278, NULL }, + { "M", 833, NULL }, + { "N", 722, NULL }, + { "omacron", 611, NULL }, + { "Tcommaaccent", 611, NULL }, + { "O", 778, NULL }, + { "P", 667, NULL }, + { "Q", 778, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 722, NULL }, + { "Aacute", 722, NULL }, + { "caron", 333, NULL }, + { "S", 667, NULL }, + { "T", 611, NULL }, + { "U", 722, NULL }, + { "agrave", 556, NULL }, + { "V", 667, NULL }, + { "W", 944, NULL }, + { "X", 667, NULL }, + { "question", 611, NULL }, + { "equal", 584, NULL }, + { "Y", 667, NULL }, + { "Z", 611, NULL }, + { "four", 556, NULL }, + { "a", 556, NULL }, + { "Gcommaaccent", 778, NULL }, + { "b", 611, NULL }, + { "c", 556, NULL }, + { "d", 611, NULL }, + { "e", 556, NULL }, + { "f", 333, NULL }, + { "g", 611, NULL }, + { "bullet", 350, NULL }, + { "h", 611, NULL }, + { "i", 278, NULL }, + { "Oslash", 778, NULL }, + { "dagger", 556, NULL }, + { "j", 278, NULL }, + { "k", 556, NULL }, + { "l", 278, NULL }, + { "m", 889, NULL }, + { "n", 611, NULL }, + { "tcommaaccent", 333, NULL }, + { "o", 611, NULL }, + { "ordfeminine", 370, NULL }, + { "ring", 333, NULL }, + { "p", 611, NULL }, + { "q", 611, NULL }, + { "uhungarumlaut", 611, NULL }, + { "r", 389, NULL }, + { "twosuperior", 333, NULL }, + { "aacute", 556, NULL }, + { "s", 556, NULL }, + { "OE", 1000, NULL }, + { "t", 333, NULL }, + { "divide", 584, NULL }, + { "u", 611, NULL }, + { "Ccaron", 722, NULL }, + { "v", 556, NULL }, + { "w", 778, NULL }, + { "x", 556, NULL }, + { "y", 556, NULL }, + { "z", 500, NULL }, + { "Gbreve", 778, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 278, NULL }, + { "Nacute", 722, NULL }, + { "quotedbl", 474, NULL }, + { "gcommaaccent", 611, NULL }, + { "mu", 611, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 667, NULL }, + { "Lslash", 611, NULL }, + { "semicolon", 333, NULL }, + { "oslash", 611, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 494, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 556, NULL }, + { "Ecircumflex", 667, NULL }, + { "gbreve", 611, NULL }, + { "trademark", 1000, NULL }, + { "daggerdbl", 556, NULL }, + { "nacute", 611, NULL }, + { "macron", 333, NULL }, + { "Otilde", 778, NULL }, + { "Emacron", 667, NULL }, + { "ellipsis", 1000, NULL }, + { "scaron", 556, NULL }, + { "AE", 1000, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 278, NULL }, + { "quotedblleft", 500, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 238, NULL }, + { "eight", 556, NULL }, + { "exclamdown", 333, NULL }, + { "endash", 556, NULL }, + { "oe", 944, NULL }, + { "Abreve", 722, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 556, NULL }, + { "Adieresis", 722, NULL }, + { "copyright", 737, NULL }, + { "Egrave", 667, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 667, NULL }, + { "otilde", 611, NULL }, + { "Idieresis", 278, NULL }, + { "parenleft", 333, NULL }, + { "one", 556, NULL }, + { "emacron", 556, NULL }, + { "Odieresis", 778, NULL }, + { "ucircumflex", 611, NULL }, + { "bracketleft", 333, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 278, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 667, NULL }, + { "umacron", 611, NULL }, + { "abreve", 556, NULL }, + { "Eacute", 667, NULL }, + { "adieresis", 556, NULL }, + { "egrave", 556, NULL }, + { "edieresis", 556, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 889, NULL }, + { "asterisk", 389, NULL }, + { "odieresis", 611, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 611, NULL }, + { "nine", 556, NULL }, + { "five", 556, NULL }, + { "udieresis", 611, NULL }, + { "Zcaron", 611, NULL }, + { "Scommaaccent", 667, NULL }, + { "threequarters", 834, NULL }, + { "guillemotright", 556, NULL }, + { "Ccedilla", 722, NULL }, + { "ydieresis", 556, NULL }, + { "tilde", 333, NULL }, + { "dbldaggerumlaut", 556, NULL }, + { "at", 975, NULL }, + { "eacute", 556, NULL }, + { "underscore", 556, NULL }, + { "Euro", 556, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 584, NULL }, + { "zero", 556, NULL }, + { "eth", 611, NULL }, + { "Scedilla", 667, NULL }, + { "Ograve", 778, NULL }, + { "Racute", 722, NULL }, + { "partialdiff", 494, NULL }, + { "uacute", 611, NULL }, + { "braceleft", 389, NULL }, + { "Thorn", 667, NULL }, + { "zcaron", 500, NULL }, + { "scommaaccent", 556, NULL }, + { "ccedilla", 556, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 611, NULL }, + { "Ocircumflex", 778, NULL }, + { "Oacute", 778, NULL }, + { "scedilla", 556, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 611, NULL }, + { "racute", 389, NULL }, + { "Tcaron", 611, NULL }, + { "Eogonek", 667, NULL }, + { "thorn", 611, NULL }, + { "degree", 400, NULL }, + { "registered", 737, NULL }, + { "radical", 549, NULL }, + { "Aring", 722, NULL }, + { "percent", 889, NULL }, + { "six", 556, NULL }, + { "paragraph", 556, NULL }, + { "dcaron", 743, NULL }, + { "Uogonek", 722, NULL }, + { "two", 556, NULL }, + { "summation", 600, NULL }, + { "Igrave", 278, NULL }, + { "Lacute", 611, NULL }, + { "ocircumflex", 611, NULL }, + { "oacute", 611, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 611, NULL }, + { "tcaron", 389, NULL }, + { "eogonek", 556, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 778, NULL }, + { "asciicircum", 584, NULL }, + { "aring", 556, NULL }, + { "grave", 333, NULL }, + { "uogonek", 611, NULL }, + { "bracketright", 333, NULL }, + { "Iacute", 278, NULL }, + { "ampersand", 722, NULL }, + { "igrave", 278, NULL }, + { "lacute", 278, NULL }, + { "Ncaron", 722, NULL }, + { "plus", 584, NULL }, + { "uring", 611, NULL }, + { "quotesinglbase", 278, NULL }, + { "lcommaaccent", 278, NULL }, + { "Yacute", 667, NULL }, + { "ohungarumlaut", 611, NULL }, + { "threesuperior", 333, NULL }, + { "acute", 333, NULL }, + { "section", 556, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 500, NULL }, + { "ncaron", 611, NULL }, + { "florin", 556, NULL }, + { "yacute", 556, NULL }, + { "Rcommaaccent", 722, NULL }, + { "fi", 611, NULL }, + { "fl", 611, NULL }, + { "Acircumflex", 722, NULL }, + { "Cacute", 722, NULL }, + { "Icircumflex", 278, NULL }, + { "guillemotleft", 556, NULL }, + { "germandbls", 611, NULL }, + { "Amacron", 722, NULL }, + { "seven", 556, NULL }, + { "Sacute", 667, NULL }, + { "ordmasculine", 365, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 556, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 278, NULL }, + { "rcommaaccent", 389, NULL }, + { "Zdotaccent", 611, NULL }, + { "acircumflex", 556, NULL }, + { "cacute", 556, NULL }, + { "Ecaron", 667, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 389, NULL }, + { "quotedblright", 500, NULL }, + { "amacron", 556, NULL }, + { "sacute", 556, NULL }, + { "imacron", 278, NULL }, + { "cent", 556, NULL }, + { "currency", 556, NULL }, + { "logicalnot", 584, NULL }, + { "zdotaccent", 500, NULL }, + { "Atilde", 722, NULL }, + { "breve", 333, NULL }, + { "bar", 280, NULL }, + { "fraction", 167, NULL }, + { "less", 584, NULL }, + { "ecaron", 556, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 333, NULL }, + { "period", 278, NULL }, + { "Rcaron", 722, NULL }, + { "Kcommaaccent", 722, NULL }, + { "greater", 584, NULL }, + { "atilde", 556, NULL }, + { "brokenbar", 280, NULL }, + { "quoteleft", 278, NULL }, + { "Edotaccent", 667, NULL }, + { "onesuperior", 333, NULL } +}; + +static BuiltinFontWidth helveticaBoldObliqueWidthsTab[] = { + { "Ntilde", 722, NULL }, + { "rcaron", 389, NULL }, + { "kcommaaccent", 556, NULL }, + { "Ncommaaccent", 722, NULL }, + { "Zacute", 611, NULL }, + { "comma", 278, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 584, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 556, NULL }, + { "asciitilde", 584, NULL }, + { "colon", 333, NULL }, + { "onehalf", 834, NULL }, + { "dollar", 556, NULL }, + { "Lcaron", 611, NULL }, + { "ntilde", 611, NULL }, + { "Aogonek", 722, NULL }, + { "ncommaaccent", 611, NULL }, + { "minus", 584, NULL }, + { "Iogonek", 278, NULL }, + { "zacute", 500, NULL }, + { "yen", 556, NULL }, + { "space", 278, NULL }, + { "Omacron", 778, NULL }, + { "questiondown", 611, NULL }, + { "emdash", 1000, NULL }, + { "Agrave", 722, NULL }, + { "three", 556, NULL }, + { "numbersign", 556, NULL }, + { "lcaron", 400, NULL }, + { "A", 722, NULL }, + { "B", 722, NULL }, + { "C", 722, NULL }, + { "aogonek", 556, NULL }, + { "D", 722, NULL }, + { "E", 667, NULL }, + { "onequarter", 834, NULL }, + { "F", 611, NULL }, + { "G", 778, NULL }, + { "H", 722, NULL }, + { "I", 278, NULL }, + { "J", 556, NULL }, + { "K", 722, NULL }, + { "iogonek", 278, NULL }, + { "backslash", 278, NULL }, + { "L", 611, NULL }, + { "periodcentered", 278, NULL }, + { "M", 833, NULL }, + { "N", 722, NULL }, + { "omacron", 611, NULL }, + { "Tcommaaccent", 611, NULL }, + { "O", 778, NULL }, + { "P", 667, NULL }, + { "Q", 778, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 722, NULL }, + { "Aacute", 722, NULL }, + { "caron", 333, NULL }, + { "S", 667, NULL }, + { "T", 611, NULL }, + { "U", 722, NULL }, + { "agrave", 556, NULL }, + { "V", 667, NULL }, + { "W", 944, NULL }, + { "X", 667, NULL }, + { "question", 611, NULL }, + { "equal", 584, NULL }, + { "Y", 667, NULL }, + { "Z", 611, NULL }, + { "four", 556, NULL }, + { "a", 556, NULL }, + { "Gcommaaccent", 778, NULL }, + { "b", 611, NULL }, + { "c", 556, NULL }, + { "d", 611, NULL }, + { "e", 556, NULL }, + { "f", 333, NULL }, + { "g", 611, NULL }, + { "bullet", 350, NULL }, + { "h", 611, NULL }, + { "i", 278, NULL }, + { "Oslash", 778, NULL }, + { "dagger", 556, NULL }, + { "j", 278, NULL }, + { "k", 556, NULL }, + { "l", 278, NULL }, + { "m", 889, NULL }, + { "n", 611, NULL }, + { "tcommaaccent", 333, NULL }, + { "o", 611, NULL }, + { "ordfeminine", 370, NULL }, + { "ring", 333, NULL }, + { "p", 611, NULL }, + { "q", 611, NULL }, + { "uhungarumlaut", 611, NULL }, + { "r", 389, NULL }, + { "twosuperior", 333, NULL }, + { "aacute", 556, NULL }, + { "s", 556, NULL }, + { "OE", 1000, NULL }, + { "t", 333, NULL }, + { "divide", 584, NULL }, + { "u", 611, NULL }, + { "Ccaron", 722, NULL }, + { "v", 556, NULL }, + { "w", 778, NULL }, + { "x", 556, NULL }, + { "y", 556, NULL }, + { "z", 500, NULL }, + { "Gbreve", 778, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 278, NULL }, + { "Nacute", 722, NULL }, + { "quotedbl", 474, NULL }, + { "gcommaaccent", 611, NULL }, + { "mu", 611, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 667, NULL }, + { "Lslash", 611, NULL }, + { "semicolon", 333, NULL }, + { "oslash", 611, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 494, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 556, NULL }, + { "Ecircumflex", 667, NULL }, + { "gbreve", 611, NULL }, + { "trademark", 1000, NULL }, + { "daggerdbl", 556, NULL }, + { "nacute", 611, NULL }, + { "macron", 333, NULL }, + { "Otilde", 778, NULL }, + { "Emacron", 667, NULL }, + { "ellipsis", 1000, NULL }, + { "scaron", 556, NULL }, + { "AE", 1000, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 278, NULL }, + { "quotedblleft", 500, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 238, NULL }, + { "eight", 556, NULL }, + { "exclamdown", 333, NULL }, + { "endash", 556, NULL }, + { "oe", 944, NULL }, + { "Abreve", 722, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 556, NULL }, + { "Adieresis", 722, NULL }, + { "copyright", 737, NULL }, + { "Egrave", 667, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 667, NULL }, + { "otilde", 611, NULL }, + { "Idieresis", 278, NULL }, + { "parenleft", 333, NULL }, + { "one", 556, NULL }, + { "emacron", 556, NULL }, + { "Odieresis", 778, NULL }, + { "ucircumflex", 611, NULL }, + { "bracketleft", 333, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 278, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 667, NULL }, + { "umacron", 611, NULL }, + { "abreve", 556, NULL }, + { "Eacute", 667, NULL }, + { "adieresis", 556, NULL }, + { "egrave", 556, NULL }, + { "edieresis", 556, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 889, NULL }, + { "asterisk", 389, NULL }, + { "odieresis", 611, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 611, NULL }, + { "nine", 556, NULL }, + { "five", 556, NULL }, + { "udieresis", 611, NULL }, + { "Zcaron", 611, NULL }, + { "Scommaaccent", 667, NULL }, + { "threequarters", 834, NULL }, + { "guillemotright", 556, NULL }, + { "Ccedilla", 722, NULL }, + { "ydieresis", 556, NULL }, + { "tilde", 333, NULL }, + { "at", 975, NULL }, + { "eacute", 556, NULL }, + { "underscore", 556, NULL }, + { "Euro", 556, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 584, NULL }, + { "zero", 556, NULL }, + { "eth", 611, NULL }, + { "Scedilla", 667, NULL }, + { "Ograve", 778, NULL }, + { "Racute", 722, NULL }, + { "partialdiff", 494, NULL }, + { "uacute", 611, NULL }, + { "braceleft", 389, NULL }, + { "Thorn", 667, NULL }, + { "zcaron", 500, NULL }, + { "scommaaccent", 556, NULL }, + { "ccedilla", 556, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 611, NULL }, + { "Ocircumflex", 778, NULL }, + { "Oacute", 778, NULL }, + { "scedilla", 556, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 611, NULL }, + { "racute", 389, NULL }, + { "Tcaron", 611, NULL }, + { "Eogonek", 667, NULL }, + { "thorn", 611, NULL }, + { "degree", 400, NULL }, + { "registered", 737, NULL }, + { "radical", 549, NULL }, + { "Aring", 722, NULL }, + { "percent", 889, NULL }, + { "six", 556, NULL }, + { "paragraph", 556, NULL }, + { "dcaron", 743, NULL }, + { "Uogonek", 722, NULL }, + { "two", 556, NULL }, + { "summation", 600, NULL }, + { "Igrave", 278, NULL }, + { "Lacute", 611, NULL }, + { "ocircumflex", 611, NULL }, + { "oacute", 611, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 611, NULL }, + { "tcaron", 389, NULL }, + { "eogonek", 556, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 778, NULL }, + { "asciicircum", 584, NULL }, + { "aring", 556, NULL }, + { "grave", 333, NULL }, + { "uogonek", 611, NULL }, + { "bracketright", 333, NULL }, + { "Iacute", 278, NULL }, + { "ampersand", 722, NULL }, + { "igrave", 278, NULL }, + { "lacute", 278, NULL }, + { "Ncaron", 722, NULL }, + { "plus", 584, NULL }, + { "uring", 611, NULL }, + { "quotesinglbase", 278, NULL }, + { "lcommaaccent", 278, NULL }, + { "Yacute", 667, NULL }, + { "ohungarumlaut", 611, NULL }, + { "threesuperior", 333, NULL }, + { "acute", 333, NULL }, + { "section", 556, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 500, NULL }, + { "ncaron", 611, NULL }, + { "florin", 556, NULL }, + { "yacute", 556, NULL }, + { "Rcommaaccent", 722, NULL }, + { "fi", 611, NULL }, + { "fl", 611, NULL }, + { "Acircumflex", 722, NULL }, + { "Cacute", 722, NULL }, + { "Icircumflex", 278, NULL }, + { "guillemotleft", 556, NULL }, + { "germandbls", 611, NULL }, + { "Amacron", 722, NULL }, + { "seven", 556, NULL }, + { "Sacute", 667, NULL }, + { "ordmasculine", 365, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 556, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 278, NULL }, + { "rcommaaccent", 389, NULL }, + { "Zdotaccent", 611, NULL }, + { "acircumflex", 556, NULL }, + { "cacute", 556, NULL }, + { "Ecaron", 667, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 389, NULL }, + { "quotedblright", 500, NULL }, + { "amacron", 556, NULL }, + { "sacute", 556, NULL }, + { "imacron", 278, NULL }, + { "cent", 556, NULL }, + { "currency", 556, NULL }, + { "logicalnot", 584, NULL }, + { "zdotaccent", 500, NULL }, + { "Atilde", 722, NULL }, + { "breve", 333, NULL }, + { "bar", 280, NULL }, + { "fraction", 167, NULL }, + { "less", 584, NULL }, + { "ecaron", 556, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 333, NULL }, + { "period", 278, NULL }, + { "Rcaron", 722, NULL }, + { "Kcommaaccent", 722, NULL }, + { "greater", 584, NULL }, + { "atilde", 556, NULL }, + { "brokenbar", 280, NULL }, + { "quoteleft", 278, NULL }, + { "Edotaccent", 667, NULL }, + { "onesuperior", 333, NULL } +}; + +static BuiltinFontWidth helveticaObliqueWidthsTab[] = { + { "Ntilde", 722, NULL }, + { "rcaron", 333, NULL }, + { "kcommaaccent", 500, NULL }, + { "Ncommaaccent", 722, NULL }, + { "Zacute", 611, NULL }, + { "comma", 278, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 584, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 556, NULL }, + { "asciitilde", 584, NULL }, + { "colon", 278, NULL }, + { "onehalf", 834, NULL }, + { "dollar", 556, NULL }, + { "Lcaron", 556, NULL }, + { "ntilde", 556, NULL }, + { "Aogonek", 667, NULL }, + { "ncommaaccent", 556, NULL }, + { "minus", 584, NULL }, + { "Iogonek", 278, NULL }, + { "zacute", 500, NULL }, + { "yen", 556, NULL }, + { "space", 278, NULL }, + { "Omacron", 778, NULL }, + { "questiondown", 611, NULL }, + { "emdash", 1000, NULL }, + { "Agrave", 667, NULL }, + { "three", 556, NULL }, + { "numbersign", 556, NULL }, + { "lcaron", 299, NULL }, + { "A", 667, NULL }, + { "B", 667, NULL }, + { "C", 722, NULL }, + { "aogonek", 556, NULL }, + { "D", 722, NULL }, + { "E", 667, NULL }, + { "onequarter", 834, NULL }, + { "F", 611, NULL }, + { "G", 778, NULL }, + { "H", 722, NULL }, + { "I", 278, NULL }, + { "J", 500, NULL }, + { "K", 667, NULL }, + { "iogonek", 222, NULL }, + { "backslash", 278, NULL }, + { "L", 556, NULL }, + { "periodcentered", 278, NULL }, + { "M", 833, NULL }, + { "N", 722, NULL }, + { "omacron", 556, NULL }, + { "Tcommaaccent", 611, NULL }, + { "O", 778, NULL }, + { "P", 667, NULL }, + { "Q", 778, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 722, NULL }, + { "Aacute", 667, NULL }, + { "caron", 333, NULL }, + { "S", 667, NULL }, + { "T", 611, NULL }, + { "U", 722, NULL }, + { "agrave", 556, NULL }, + { "V", 667, NULL }, + { "W", 944, NULL }, + { "X", 667, NULL }, + { "question", 556, NULL }, + { "equal", 584, NULL }, + { "Y", 667, NULL }, + { "Z", 611, NULL }, + { "four", 556, NULL }, + { "a", 556, NULL }, + { "Gcommaaccent", 778, NULL }, + { "b", 556, NULL }, + { "c", 500, NULL }, + { "d", 556, NULL }, + { "e", 556, NULL }, + { "f", 278, NULL }, + { "g", 556, NULL }, + { "bullet", 350, NULL }, + { "h", 556, NULL }, + { "i", 222, NULL }, + { "Oslash", 778, NULL }, + { "dagger", 556, NULL }, + { "j", 222, NULL }, + { "k", 500, NULL }, + { "l", 222, NULL }, + { "m", 833, NULL }, + { "n", 556, NULL }, + { "tcommaaccent", 278, NULL }, + { "o", 556, NULL }, + { "ordfeminine", 370, NULL }, + { "ring", 333, NULL }, + { "p", 556, NULL }, + { "q", 556, NULL }, + { "uhungarumlaut", 556, NULL }, + { "r", 333, NULL }, + { "twosuperior", 333, NULL }, + { "aacute", 556, NULL }, + { "s", 500, NULL }, + { "OE", 1000, NULL }, + { "t", 278, NULL }, + { "divide", 584, NULL }, + { "u", 556, NULL }, + { "Ccaron", 722, NULL }, + { "v", 500, NULL }, + { "w", 722, NULL }, + { "x", 500, NULL }, + { "y", 500, NULL }, + { "z", 500, NULL }, + { "Gbreve", 778, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 278, NULL }, + { "Nacute", 722, NULL }, + { "quotedbl", 355, NULL }, + { "gcommaaccent", 556, NULL }, + { "mu", 556, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 667, NULL }, + { "Lslash", 556, NULL }, + { "semicolon", 278, NULL }, + { "oslash", 611, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 471, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 500, NULL }, + { "Ecircumflex", 667, NULL }, + { "gbreve", 556, NULL }, + { "trademark", 1000, NULL }, + { "daggerdbl", 556, NULL }, + { "nacute", 556, NULL }, + { "macron", 333, NULL }, + { "Otilde", 778, NULL }, + { "Emacron", 667, NULL }, + { "ellipsis", 1000, NULL }, + { "scaron", 500, NULL }, + { "AE", 1000, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 222, NULL }, + { "quotedblleft", 333, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 191, NULL }, + { "eight", 556, NULL }, + { "exclamdown", 333, NULL }, + { "endash", 556, NULL }, + { "oe", 944, NULL }, + { "Abreve", 667, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 556, NULL }, + { "Adieresis", 667, NULL }, + { "copyright", 737, NULL }, + { "Egrave", 667, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 667, NULL }, + { "otilde", 556, NULL }, + { "Idieresis", 278, NULL }, + { "parenleft", 333, NULL }, + { "one", 556, NULL }, + { "emacron", 556, NULL }, + { "Odieresis", 778, NULL }, + { "ucircumflex", 556, NULL }, + { "bracketleft", 278, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 222, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 667, NULL }, + { "umacron", 556, NULL }, + { "abreve", 556, NULL }, + { "Eacute", 667, NULL }, + { "adieresis", 556, NULL }, + { "egrave", 556, NULL }, + { "edieresis", 556, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 889, NULL }, + { "asterisk", 389, NULL }, + { "odieresis", 556, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 556, NULL }, + { "nine", 556, NULL }, + { "five", 556, NULL }, + { "udieresis", 556, NULL }, + { "Zcaron", 611, NULL }, + { "Scommaaccent", 667, NULL }, + { "threequarters", 834, NULL }, + { "guillemotright", 556, NULL }, + { "Ccedilla", 722, NULL }, + { "ydieresis", 500, NULL }, + { "tilde", 333, NULL }, + { "at", 1015, NULL }, + { "eacute", 556, NULL }, + { "underscore", 556, NULL }, + { "Euro", 556, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 584, NULL }, + { "zero", 556, NULL }, + { "eth", 556, NULL }, + { "Scedilla", 667, NULL }, + { "Ograve", 778, NULL }, + { "Racute", 722, NULL }, + { "partialdiff", 476, NULL }, + { "uacute", 556, NULL }, + { "braceleft", 334, NULL }, + { "Thorn", 667, NULL }, + { "zcaron", 500, NULL }, + { "scommaaccent", 500, NULL }, + { "ccedilla", 500, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 556, NULL }, + { "Ocircumflex", 778, NULL }, + { "Oacute", 778, NULL }, + { "scedilla", 500, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 556, NULL }, + { "racute", 333, NULL }, + { "Tcaron", 611, NULL }, + { "Eogonek", 667, NULL }, + { "thorn", 556, NULL }, + { "degree", 400, NULL }, + { "registered", 737, NULL }, + { "radical", 453, NULL }, + { "Aring", 667, NULL }, + { "percent", 889, NULL }, + { "six", 556, NULL }, + { "paragraph", 537, NULL }, + { "dcaron", 643, NULL }, + { "Uogonek", 722, NULL }, + { "two", 556, NULL }, + { "summation", 600, NULL }, + { "Igrave", 278, NULL }, + { "Lacute", 556, NULL }, + { "ocircumflex", 556, NULL }, + { "oacute", 556, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 556, NULL }, + { "tcaron", 317, NULL }, + { "eogonek", 556, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 778, NULL }, + { "asciicircum", 469, NULL }, + { "aring", 556, NULL }, + { "grave", 333, NULL }, + { "uogonek", 556, NULL }, + { "bracketright", 278, NULL }, + { "Iacute", 278, NULL }, + { "ampersand", 667, NULL }, + { "igrave", 278, NULL }, + { "lacute", 222, NULL }, + { "Ncaron", 722, NULL }, + { "plus", 584, NULL }, + { "uring", 556, NULL }, + { "quotesinglbase", 222, NULL }, + { "lcommaaccent", 222, NULL }, + { "Yacute", 667, NULL }, + { "ohungarumlaut", 556, NULL }, + { "threesuperior", 333, NULL }, + { "acute", 333, NULL }, + { "section", 556, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 333, NULL }, + { "ncaron", 556, NULL }, + { "florin", 556, NULL }, + { "yacute", 500, NULL }, + { "Rcommaaccent", 722, NULL }, + { "fi", 500, NULL }, + { "fl", 500, NULL }, + { "Acircumflex", 667, NULL }, + { "Cacute", 722, NULL }, + { "Icircumflex", 278, NULL }, + { "guillemotleft", 556, NULL }, + { "germandbls", 611, NULL }, + { "Amacron", 667, NULL }, + { "seven", 556, NULL }, + { "Sacute", 667, NULL }, + { "ordmasculine", 365, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 556, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 278, NULL }, + { "rcommaaccent", 333, NULL }, + { "Zdotaccent", 611, NULL }, + { "acircumflex", 556, NULL }, + { "cacute", 500, NULL }, + { "Ecaron", 667, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 334, NULL }, + { "quotedblright", 333, NULL }, + { "amacron", 556, NULL }, + { "sacute", 500, NULL }, + { "imacron", 278, NULL }, + { "cent", 556, NULL }, + { "currency", 556, NULL }, + { "logicalnot", 584, NULL }, + { "zdotaccent", 500, NULL }, + { "Atilde", 667, NULL }, + { "breve", 333, NULL }, + { "bar", 260, NULL }, + { "fraction", 167, NULL }, + { "less", 584, NULL }, + { "ecaron", 556, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 278, NULL }, + { "period", 278, NULL }, + { "Rcaron", 722, NULL }, + { "Kcommaaccent", 667, NULL }, + { "greater", 584, NULL }, + { "atilde", 556, NULL }, + { "brokenbar", 260, NULL }, + { "quoteleft", 222, NULL }, + { "Edotaccent", 667, NULL }, + { "onesuperior", 333, NULL } +}; + +static BuiltinFontWidth symbolWidthsTab[] = { + { "bracketleftex", 384, NULL }, + { "alpha", 631, NULL }, + { "union", 768, NULL }, + { "infinity", 713, NULL }, + { "comma", 250, NULL }, + { "copyrightsans", 790, NULL }, + { "plusminus", 549, NULL }, + { "arrowup", 603, NULL }, + { "apple", 790, NULL }, + { "parenleftbt", 384, NULL }, + { "notelement", 713, NULL }, + { "colon", 278, NULL }, + { "beta", 549, NULL }, + { "braceleftbt", 494, NULL }, + { "Lambda", 686, NULL }, + { "Phi", 763, NULL }, + { "minus", 549, NULL }, + { "space", 250, NULL }, + { "Sigma", 592, NULL }, + { "approxequal", 549, NULL }, + { "minute", 247, NULL }, + { "circleplus", 768, NULL }, + { "Omicron", 722, NULL }, + { "three", 500, NULL }, + { "numbersign", 500, NULL }, + { "lambda", 549, NULL }, + { "phi", 521, NULL }, + { "aleph", 823, NULL }, + { "Tau", 611, NULL }, + { "spade", 753, NULL }, + { "logicaland", 603, NULL }, + { "sigma", 603, NULL }, + { "propersuperset", 713, NULL }, + { "omicron", 549, NULL }, + { "question", 444, NULL }, + { "equal", 549, NULL }, + { "Epsilon", 611, NULL }, + { "emptyset", 823, NULL }, + { "diamond", 753, NULL }, + { "four", 500, NULL }, + { "Mu", 889, NULL }, + { "parenlefttp", 384, NULL }, + { "club", 753, NULL }, + { "bullet", 460, NULL }, + { "Omega", 768, NULL }, + { "tau", 439, NULL }, + { "Upsilon", 690, NULL }, + { "bracelefttp", 494, NULL }, + { "heart", 753, NULL }, + { "divide", 549, NULL }, + { "epsilon", 439, NULL }, + { "logicalor", 603, NULL }, + { "parenleftex", 384, NULL }, + { "greaterequal", 549, NULL }, + { "mu", 576, NULL }, + { "Nu", 722, NULL }, + { "therefore", 863, NULL }, + { "notsubset", 713, NULL }, + { "omega", 686, NULL }, + { "semicolon", 278, NULL }, + { "element", 713, NULL }, + { "upsilon", 576, NULL }, + { "existential", 549, NULL }, + { "integralbt", 686, NULL }, + { "lessequal", 549, NULL }, + { "phi1", 603, NULL }, + { "lozenge", 494, NULL }, + { "trademarkserif", 890, NULL }, + { "parenright", 333, NULL }, + { "reflexsuperset", 713, NULL }, + { "sigma1", 439, NULL }, + { "nu", 521, NULL }, + { "Gamma", 603, NULL }, + { "angleright", 329, NULL }, + { "ellipsis", 1000, NULL }, + { "Rho", 556, NULL }, + { "parenrightbt", 384, NULL }, + { "radicalex", 500, NULL }, + { "eight", 500, NULL }, + { "angleleft", 329, NULL }, + { "arrowdbldown", 603, NULL }, + { "congruent", 549, NULL }, + { "Theta", 741, NULL }, + { "intersection", 768, NULL }, + { "Pi", 768, NULL }, + { "slash", 278, NULL }, + { "registerserif", 790, NULL }, + { "parenleft", 333, NULL }, + { "one", 500, NULL }, + { "gamma", 411, NULL }, + { "bracketleft", 333, NULL }, + { "rho", 549, NULL }, + { "circlemultiply", 768, NULL }, + { "Chi", 722, NULL }, + { "theta", 521, NULL }, + { "pi", 549, NULL }, + { "integraltp", 686, NULL }, + { "Eta", 722, NULL }, + { "product", 823, NULL }, + { "nine", 500, NULL }, + { "five", 500, NULL }, + { "propersubset", 713, NULL }, + { "bracketrightbt", 384, NULL }, + { "trademarksans", 786, NULL }, + { "dotmath", 250, NULL }, + { "integralex", 686, NULL }, + { "chi", 549, NULL }, + { "parenrighttp", 384, NULL }, + { "eta", 603, NULL }, + { "underscore", 500, NULL }, + { "Euro", 750, NULL }, + { "multiply", 549, NULL }, + { "zero", 500, NULL }, + { "partialdiff", 494, NULL }, + { "angle", 768, NULL }, + { "arrowdblleft", 987, NULL }, + { "braceleft", 480, NULL }, + { "parenrightex", 384, NULL }, + { "Rfraktur", 795, NULL }, + { "Zeta", 611, NULL }, + { "braceex", 494, NULL }, + { "arrowdblup", 603, NULL }, + { "arrowdown", 603, NULL }, + { "Ifraktur", 686, NULL }, + { "degree", 400, NULL }, + { "Iota", 333, NULL }, + { "perpendicular", 658, NULL }, + { "radical", 549, NULL }, + { "asteriskmath", 500, NULL }, + { "percent", 833, NULL }, + { "zeta", 494, NULL }, + { "six", 500, NULL }, + { "two", 500, NULL }, + { "weierstrass", 987, NULL }, + { "summation", 713, NULL }, + { "bracketrighttp", 384, NULL }, + { "carriagereturn", 658, NULL }, + { "suchthat", 439, NULL }, + { "arrowvertex", 603, NULL }, + { "Delta", 612, NULL }, + { "iota", 329, NULL }, + { "arrowhorizex", 1000, NULL }, + { "bracketrightex", 384, NULL }, + { "bracketright", 333, NULL }, + { "ampersand", 778, NULL }, + { "plus", 549, NULL }, + { "proportional", 713, NULL }, + { "delta", 494, NULL }, + { "copyrightserif", 790, NULL }, + { "bracerightmid", 494, NULL }, + { "arrowleft", 987, NULL }, + { "second", 411, NULL }, + { "arrowdblboth", 1042, NULL }, + { "florin", 500, NULL }, + { "Psi", 795, NULL }, + { "bracerightbt", 494, NULL }, + { "bracketleftbt", 384, NULL }, + { "seven", 500, NULL }, + { "braceleftmid", 494, NULL }, + { "notequal", 549, NULL }, + { "psi", 686, NULL }, + { "equivalence", 549, NULL }, + { "universal", 713, NULL }, + { "arrowdblright", 987, NULL }, + { "braceright", 480, NULL }, + { "reflexsubset", 713, NULL }, + { "Xi", 645, NULL }, + { "theta1", 631, NULL }, + { "logicalnot", 713, NULL }, + { "Kappa", 722, NULL }, + { "similar", 549, NULL }, + { "bar", 200, NULL }, + { "fraction", 167, NULL }, + { "less", 549, NULL }, + { "registersans", 790, NULL }, + { "omega1", 713, NULL }, + { "exclam", 333, NULL }, + { "Upsilon1", 620, NULL }, + { "bracerighttp", 494, NULL }, + { "xi", 493, NULL }, + { "period", 250, NULL }, + { "Alpha", 722, NULL }, + { "arrowright", 987, NULL }, + { "greater", 549, NULL }, + { "bracketlefttp", 384, NULL }, + { "kappa", 549, NULL }, + { "gradient", 713, NULL }, + { "integral", 274, NULL }, + { "arrowboth", 1042, NULL }, + { "Beta", 667, NULL } +}; + +static BuiltinFontWidth timesBoldWidthsTab[] = { + { "Ntilde", 722, NULL }, + { "rcaron", 444, NULL }, + { "kcommaaccent", 556, NULL }, + { "Ncommaaccent", 722, NULL }, + { "Zacute", 667, NULL }, + { "comma", 250, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 570, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 444, NULL }, + { "asciitilde", 520, NULL }, + { "colon", 333, NULL }, + { "onehalf", 750, NULL }, + { "dollar", 500, NULL }, + { "Lcaron", 667, NULL }, + { "ntilde", 556, NULL }, + { "Aogonek", 722, NULL }, + { "ncommaaccent", 556, NULL }, + { "minus", 570, NULL }, + { "Iogonek", 389, NULL }, + { "zacute", 444, NULL }, + { "yen", 500, NULL }, + { "space", 250, NULL }, + { "Omacron", 778, NULL }, + { "questiondown", 500, NULL }, + { "emdash", 1000, NULL }, + { "Agrave", 722, NULL }, + { "three", 500, NULL }, + { "numbersign", 500, NULL }, + { "lcaron", 394, NULL }, + { "A", 722, NULL }, + { "B", 667, NULL }, + { "C", 722, NULL }, + { "aogonek", 500, NULL }, + { "D", 722, NULL }, + { "E", 667, NULL }, + { "onequarter", 750, NULL }, + { "F", 611, NULL }, + { "G", 778, NULL }, + { "H", 778, NULL }, + { "I", 389, NULL }, + { "J", 500, NULL }, + { "K", 778, NULL }, + { "iogonek", 278, NULL }, + { "backslash", 278, NULL }, + { "L", 667, NULL }, + { "periodcentered", 250, NULL }, + { "M", 944, NULL }, + { "N", 722, NULL }, + { "omacron", 500, NULL }, + { "Tcommaaccent", 667, NULL }, + { "O", 778, NULL }, + { "P", 611, NULL }, + { "Q", 778, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 722, NULL }, + { "Aacute", 722, NULL }, + { "caron", 333, NULL }, + { "S", 556, NULL }, + { "T", 667, NULL }, + { "U", 722, NULL }, + { "agrave", 500, NULL }, + { "V", 722, NULL }, + { "W", 1000, NULL }, + { "X", 722, NULL }, + { "question", 500, NULL }, + { "equal", 570, NULL }, + { "Y", 722, NULL }, + { "Z", 667, NULL }, + { "four", 500, NULL }, + { "a", 500, NULL }, + { "Gcommaaccent", 778, NULL }, + { "b", 556, NULL }, + { "c", 444, NULL }, + { "d", 556, NULL }, + { "e", 444, NULL }, + { "f", 333, NULL }, + { "g", 500, NULL }, + { "bullet", 350, NULL }, + { "h", 556, NULL }, + { "i", 278, NULL }, + { "Oslash", 778, NULL }, + { "dagger", 500, NULL }, + { "j", 333, NULL }, + { "k", 556, NULL }, + { "l", 278, NULL }, + { "m", 833, NULL }, + { "n", 556, NULL }, + { "tcommaaccent", 333, NULL }, + { "o", 500, NULL }, + { "ordfeminine", 300, NULL }, + { "ring", 333, NULL }, + { "p", 556, NULL }, + { "q", 556, NULL }, + { "uhungarumlaut", 556, NULL }, + { "r", 444, NULL }, + { "twosuperior", 300, NULL }, + { "aacute", 500, NULL }, + { "s", 389, NULL }, + { "OE", 1000, NULL }, + { "t", 333, NULL }, + { "divide", 570, NULL }, + { "u", 556, NULL }, + { "Ccaron", 722, NULL }, + { "v", 500, NULL }, + { "w", 722, NULL }, + { "x", 500, NULL }, + { "y", 500, NULL }, + { "z", 444, NULL }, + { "Gbreve", 778, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 389, NULL }, + { "Nacute", 722, NULL }, + { "quotedbl", 555, NULL }, + { "gcommaaccent", 500, NULL }, + { "mu", 556, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 556, NULL }, + { "Lslash", 667, NULL }, + { "semicolon", 333, NULL }, + { "oslash", 500, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 494, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 444, NULL }, + { "Ecircumflex", 667, NULL }, + { "gbreve", 500, NULL }, + { "trademark", 1000, NULL }, + { "daggerdbl", 500, NULL }, + { "nacute", 556, NULL }, + { "macron", 333, NULL }, + { "Otilde", 778, NULL }, + { "Emacron", 667, NULL }, + { "ellipsis", 1000, NULL }, + { "scaron", 389, NULL }, + { "AE", 1000, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 278, NULL }, + { "quotedblleft", 500, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 278, NULL }, + { "eight", 500, NULL }, + { "exclamdown", 333, NULL }, + { "endash", 500, NULL }, + { "oe", 722, NULL }, + { "Abreve", 722, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 444, NULL }, + { "Adieresis", 722, NULL }, + { "copyright", 747, NULL }, + { "Egrave", 667, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 667, NULL }, + { "otilde", 500, NULL }, + { "Idieresis", 389, NULL }, + { "parenleft", 333, NULL }, + { "one", 500, NULL }, + { "emacron", 444, NULL }, + { "Odieresis", 778, NULL }, + { "ucircumflex", 556, NULL }, + { "bracketleft", 333, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 333, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 722, NULL }, + { "umacron", 556, NULL }, + { "abreve", 500, NULL }, + { "Eacute", 667, NULL }, + { "adieresis", 500, NULL }, + { "egrave", 444, NULL }, + { "edieresis", 444, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 722, NULL }, + { "asterisk", 500, NULL }, + { "odieresis", 500, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 556, NULL }, + { "nine", 500, NULL }, + { "five", 500, NULL }, + { "udieresis", 556, NULL }, + { "Zcaron", 667, NULL }, + { "Scommaaccent", 556, NULL }, + { "threequarters", 750, NULL }, + { "guillemotright", 500, NULL }, + { "Ccedilla", 722, NULL }, + { "ydieresis", 500, NULL }, + { "tilde", 333, NULL }, + { "at", 930, NULL }, + { "eacute", 444, NULL }, + { "underscore", 500, NULL }, + { "Euro", 500, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 570, NULL }, + { "zero", 500, NULL }, + { "eth", 500, NULL }, + { "Scedilla", 556, NULL }, + { "Ograve", 778, NULL }, + { "Racute", 722, NULL }, + { "partialdiff", 494, NULL }, + { "uacute", 556, NULL }, + { "braceleft", 394, NULL }, + { "Thorn", 611, NULL }, + { "zcaron", 444, NULL }, + { "scommaaccent", 389, NULL }, + { "ccedilla", 444, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 556, NULL }, + { "Ocircumflex", 778, NULL }, + { "Oacute", 778, NULL }, + { "scedilla", 389, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 500, NULL }, + { "racute", 444, NULL }, + { "Tcaron", 667, NULL }, + { "Eogonek", 667, NULL }, + { "thorn", 556, NULL }, + { "degree", 400, NULL }, + { "registered", 747, NULL }, + { "radical", 549, NULL }, + { "Aring", 722, NULL }, + { "percent", 1000, NULL }, + { "six", 500, NULL }, + { "paragraph", 540, NULL }, + { "dcaron", 672, NULL }, + { "Uogonek", 722, NULL }, + { "two", 500, NULL }, + { "summation", 600, NULL }, + { "Igrave", 389, NULL }, + { "Lacute", 667, NULL }, + { "ocircumflex", 500, NULL }, + { "oacute", 500, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 667, NULL }, + { "tcaron", 416, NULL }, + { "eogonek", 444, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 778, NULL }, + { "asciicircum", 581, NULL }, + { "aring", 500, NULL }, + { "grave", 333, NULL }, + { "uogonek", 556, NULL }, + { "bracketright", 333, NULL }, + { "Iacute", 389, NULL }, + { "ampersand", 833, NULL }, + { "igrave", 278, NULL }, + { "lacute", 278, NULL }, + { "Ncaron", 722, NULL }, + { "plus", 570, NULL }, + { "uring", 556, NULL }, + { "quotesinglbase", 333, NULL }, + { "lcommaaccent", 278, NULL }, + { "Yacute", 722, NULL }, + { "ohungarumlaut", 500, NULL }, + { "threesuperior", 300, NULL }, + { "acute", 333, NULL }, + { "section", 500, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 500, NULL }, + { "ncaron", 556, NULL }, + { "florin", 500, NULL }, + { "yacute", 500, NULL }, + { "Rcommaaccent", 722, NULL }, + { "fi", 556, NULL }, + { "fl", 556, NULL }, + { "Acircumflex", 722, NULL }, + { "Cacute", 722, NULL }, + { "Icircumflex", 389, NULL }, + { "guillemotleft", 500, NULL }, + { "germandbls", 556, NULL }, + { "Amacron", 722, NULL }, + { "seven", 500, NULL }, + { "Sacute", 556, NULL }, + { "ordmasculine", 330, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 500, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 389, NULL }, + { "rcommaaccent", 444, NULL }, + { "Zdotaccent", 667, NULL }, + { "acircumflex", 500, NULL }, + { "cacute", 444, NULL }, + { "Ecaron", 667, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 394, NULL }, + { "quotedblright", 500, NULL }, + { "amacron", 500, NULL }, + { "sacute", 389, NULL }, + { "imacron", 278, NULL }, + { "cent", 500, NULL }, + { "currency", 500, NULL }, + { "logicalnot", 570, NULL }, + { "zdotaccent", 444, NULL }, + { "Atilde", 722, NULL }, + { "breve", 333, NULL }, + { "bar", 220, NULL }, + { "fraction", 167, NULL }, + { "less", 570, NULL }, + { "ecaron", 444, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 333, NULL }, + { "period", 250, NULL }, + { "Rcaron", 722, NULL }, + { "Kcommaaccent", 778, NULL }, + { "greater", 570, NULL }, + { "atilde", 500, NULL }, + { "brokenbar", 220, NULL }, + { "quoteleft", 333, NULL }, + { "Edotaccent", 667, NULL }, + { "onesuperior", 300, NULL } +}; + +static BuiltinFontWidth timesBoldItalicWidthsTab[] = { + { "Ntilde", 722, NULL }, + { "rcaron", 389, NULL }, + { "kcommaaccent", 500, NULL }, + { "Ncommaaccent", 722, NULL }, + { "Zacute", 611, NULL }, + { "comma", 250, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 570, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 444, NULL }, + { "asciitilde", 570, NULL }, + { "colon", 333, NULL }, + { "onehalf", 750, NULL }, + { "dollar", 500, NULL }, + { "Lcaron", 611, NULL }, + { "ntilde", 556, NULL }, + { "Aogonek", 667, NULL }, + { "ncommaaccent", 556, NULL }, + { "minus", 606, NULL }, + { "Iogonek", 389, NULL }, + { "zacute", 389, NULL }, + { "yen", 500, NULL }, + { "space", 250, NULL }, + { "Omacron", 722, NULL }, + { "questiondown", 500, NULL }, + { "emdash", 1000, NULL }, + { "Agrave", 667, NULL }, + { "three", 500, NULL }, + { "numbersign", 500, NULL }, + { "lcaron", 382, NULL }, + { "A", 667, NULL }, + { "B", 667, NULL }, + { "C", 667, NULL }, + { "aogonek", 500, NULL }, + { "D", 722, NULL }, + { "E", 667, NULL }, + { "onequarter", 750, NULL }, + { "F", 667, NULL }, + { "G", 722, NULL }, + { "H", 778, NULL }, + { "I", 389, NULL }, + { "J", 500, NULL }, + { "K", 667, NULL }, + { "iogonek", 278, NULL }, + { "backslash", 278, NULL }, + { "L", 611, NULL }, + { "periodcentered", 250, NULL }, + { "M", 889, NULL }, + { "N", 722, NULL }, + { "omacron", 500, NULL }, + { "Tcommaaccent", 611, NULL }, + { "O", 722, NULL }, + { "P", 611, NULL }, + { "Q", 722, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 667, NULL }, + { "Aacute", 667, NULL }, + { "caron", 333, NULL }, + { "S", 556, NULL }, + { "T", 611, NULL }, + { "U", 722, NULL }, + { "agrave", 500, NULL }, + { "V", 667, NULL }, + { "W", 889, NULL }, + { "X", 667, NULL }, + { "question", 500, NULL }, + { "equal", 570, NULL }, + { "Y", 611, NULL }, + { "Z", 611, NULL }, + { "four", 500, NULL }, + { "a", 500, NULL }, + { "Gcommaaccent", 722, NULL }, + { "b", 500, NULL }, + { "c", 444, NULL }, + { "d", 500, NULL }, + { "e", 444, NULL }, + { "f", 333, NULL }, + { "g", 500, NULL }, + { "bullet", 350, NULL }, + { "h", 556, NULL }, + { "i", 278, NULL }, + { "Oslash", 722, NULL }, + { "dagger", 500, NULL }, + { "j", 278, NULL }, + { "k", 500, NULL }, + { "l", 278, NULL }, + { "m", 778, NULL }, + { "n", 556, NULL }, + { "tcommaaccent", 278, NULL }, + { "o", 500, NULL }, + { "ordfeminine", 266, NULL }, + { "ring", 333, NULL }, + { "p", 500, NULL }, + { "q", 500, NULL }, + { "uhungarumlaut", 556, NULL }, + { "r", 389, NULL }, + { "twosuperior", 300, NULL }, + { "aacute", 500, NULL }, + { "s", 389, NULL }, + { "OE", 944, NULL }, + { "t", 278, NULL }, + { "divide", 570, NULL }, + { "u", 556, NULL }, + { "Ccaron", 667, NULL }, + { "v", 444, NULL }, + { "w", 667, NULL }, + { "x", 500, NULL }, + { "y", 444, NULL }, + { "z", 389, NULL }, + { "Gbreve", 722, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 389, NULL }, + { "Nacute", 722, NULL }, + { "quotedbl", 555, NULL }, + { "gcommaaccent", 500, NULL }, + { "mu", 576, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 556, NULL }, + { "Lslash", 611, NULL }, + { "semicolon", 333, NULL }, + { "oslash", 500, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 494, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 444, NULL }, + { "Ecircumflex", 667, NULL }, + { "gbreve", 500, NULL }, + { "trademark", 1000, NULL }, + { "daggerdbl", 500, NULL }, + { "nacute", 556, NULL }, + { "macron", 333, NULL }, + { "Otilde", 722, NULL }, + { "Emacron", 667, NULL }, + { "ellipsis", 1000, NULL }, + { "scaron", 389, NULL }, + { "AE", 944, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 278, NULL }, + { "quotedblleft", 500, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 278, NULL }, + { "eight", 500, NULL }, + { "exclamdown", 389, NULL }, + { "endash", 500, NULL }, + { "oe", 722, NULL }, + { "Abreve", 667, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 444, NULL }, + { "Adieresis", 667, NULL }, + { "copyright", 747, NULL }, + { "Egrave", 667, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 667, NULL }, + { "otilde", 500, NULL }, + { "Idieresis", 389, NULL }, + { "parenleft", 333, NULL }, + { "one", 500, NULL }, + { "emacron", 444, NULL }, + { "Odieresis", 722, NULL }, + { "ucircumflex", 556, NULL }, + { "bracketleft", 333, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 333, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 611, NULL }, + { "umacron", 556, NULL }, + { "abreve", 500, NULL }, + { "Eacute", 667, NULL }, + { "adieresis", 500, NULL }, + { "egrave", 444, NULL }, + { "edieresis", 444, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 722, NULL }, + { "asterisk", 500, NULL }, + { "odieresis", 500, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 556, NULL }, + { "nine", 500, NULL }, + { "five", 500, NULL }, + { "udieresis", 556, NULL }, + { "Zcaron", 611, NULL }, + { "Scommaaccent", 556, NULL }, + { "threequarters", 750, NULL }, + { "guillemotright", 500, NULL }, + { "Ccedilla", 667, NULL }, + { "ydieresis", 444, NULL }, + { "tilde", 333, NULL }, + { "at", 832, NULL }, + { "eacute", 444, NULL }, + { "underscore", 500, NULL }, + { "Euro", 500, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 570, NULL }, + { "zero", 500, NULL }, + { "eth", 500, NULL }, + { "Scedilla", 556, NULL }, + { "Ograve", 722, NULL }, + { "Racute", 667, NULL }, + { "partialdiff", 494, NULL }, + { "uacute", 556, NULL }, + { "braceleft", 348, NULL }, + { "Thorn", 611, NULL }, + { "zcaron", 389, NULL }, + { "scommaaccent", 389, NULL }, + { "ccedilla", 444, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 500, NULL }, + { "Ocircumflex", 722, NULL }, + { "Oacute", 722, NULL }, + { "scedilla", 389, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 500, NULL }, + { "racute", 389, NULL }, + { "Tcaron", 611, NULL }, + { "Eogonek", 667, NULL }, + { "thorn", 500, NULL }, + { "degree", 400, NULL }, + { "registered", 747, NULL }, + { "radical", 549, NULL }, + { "Aring", 667, NULL }, + { "percent", 833, NULL }, + { "six", 500, NULL }, + { "paragraph", 500, NULL }, + { "dcaron", 608, NULL }, + { "Uogonek", 722, NULL }, + { "two", 500, NULL }, + { "summation", 600, NULL }, + { "Igrave", 389, NULL }, + { "Lacute", 611, NULL }, + { "ocircumflex", 500, NULL }, + { "oacute", 500, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 611, NULL }, + { "tcaron", 366, NULL }, + { "eogonek", 444, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 722, NULL }, + { "asciicircum", 570, NULL }, + { "aring", 500, NULL }, + { "grave", 333, NULL }, + { "uogonek", 556, NULL }, + { "bracketright", 333, NULL }, + { "Iacute", 389, NULL }, + { "ampersand", 778, NULL }, + { "igrave", 278, NULL }, + { "lacute", 278, NULL }, + { "Ncaron", 722, NULL }, + { "plus", 570, NULL }, + { "uring", 556, NULL }, + { "quotesinglbase", 333, NULL }, + { "lcommaaccent", 278, NULL }, + { "Yacute", 611, NULL }, + { "ohungarumlaut", 500, NULL }, + { "threesuperior", 300, NULL }, + { "acute", 333, NULL }, + { "section", 500, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 500, NULL }, + { "ncaron", 556, NULL }, + { "florin", 500, NULL }, + { "yacute", 444, NULL }, + { "Rcommaaccent", 667, NULL }, + { "fi", 556, NULL }, + { "fl", 556, NULL }, + { "Acircumflex", 667, NULL }, + { "Cacute", 667, NULL }, + { "Icircumflex", 389, NULL }, + { "guillemotleft", 500, NULL }, + { "germandbls", 500, NULL }, + { "Amacron", 667, NULL }, + { "seven", 500, NULL }, + { "Sacute", 556, NULL }, + { "ordmasculine", 300, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 500, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 389, NULL }, + { "rcommaaccent", 389, NULL }, + { "Zdotaccent", 611, NULL }, + { "acircumflex", 500, NULL }, + { "cacute", 444, NULL }, + { "Ecaron", 667, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 348, NULL }, + { "quotedblright", 500, NULL }, + { "amacron", 500, NULL }, + { "sacute", 389, NULL }, + { "imacron", 278, NULL }, + { "cent", 500, NULL }, + { "currency", 500, NULL }, + { "logicalnot", 606, NULL }, + { "zdotaccent", 389, NULL }, + { "Atilde", 667, NULL }, + { "breve", 333, NULL }, + { "bar", 220, NULL }, + { "fraction", 167, NULL }, + { "less", 570, NULL }, + { "ecaron", 444, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 389, NULL }, + { "period", 250, NULL }, + { "Rcaron", 667, NULL }, + { "Kcommaaccent", 667, NULL }, + { "greater", 570, NULL }, + { "atilde", 500, NULL }, + { "brokenbar", 220, NULL }, + { "quoteleft", 333, NULL }, + { "Edotaccent", 667, NULL }, + { "onesuperior", 300, NULL } +}; + +static BuiltinFontWidth timesItalicWidthsTab[] = { + { "Ntilde", 667, NULL }, + { "rcaron", 389, NULL }, + { "kcommaaccent", 444, NULL }, + { "Ncommaaccent", 667, NULL }, + { "Zacute", 556, NULL }, + { "comma", 250, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 675, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 444, NULL }, + { "asciitilde", 541, NULL }, + { "colon", 333, NULL }, + { "onehalf", 750, NULL }, + { "dollar", 500, NULL }, + { "Lcaron", 611, NULL }, + { "ntilde", 500, NULL }, + { "Aogonek", 611, NULL }, + { "ncommaaccent", 500, NULL }, + { "minus", 675, NULL }, + { "Iogonek", 333, NULL }, + { "zacute", 389, NULL }, + { "yen", 500, NULL }, + { "space", 250, NULL }, + { "Omacron", 722, NULL }, + { "questiondown", 500, NULL }, + { "emdash", 889, NULL }, + { "Agrave", 611, NULL }, + { "three", 500, NULL }, + { "numbersign", 500, NULL }, + { "lcaron", 300, NULL }, + { "A", 611, NULL }, + { "B", 611, NULL }, + { "C", 667, NULL }, + { "aogonek", 500, NULL }, + { "D", 722, NULL }, + { "E", 611, NULL }, + { "onequarter", 750, NULL }, + { "F", 611, NULL }, + { "G", 722, NULL }, + { "H", 722, NULL }, + { "I", 333, NULL }, + { "J", 444, NULL }, + { "K", 667, NULL }, + { "iogonek", 278, NULL }, + { "backslash", 278, NULL }, + { "L", 556, NULL }, + { "periodcentered", 250, NULL }, + { "M", 833, NULL }, + { "N", 667, NULL }, + { "omacron", 500, NULL }, + { "Tcommaaccent", 556, NULL }, + { "O", 722, NULL }, + { "P", 611, NULL }, + { "Q", 722, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 611, NULL }, + { "Aacute", 611, NULL }, + { "caron", 333, NULL }, + { "S", 500, NULL }, + { "T", 556, NULL }, + { "U", 722, NULL }, + { "agrave", 500, NULL }, + { "V", 611, NULL }, + { "W", 833, NULL }, + { "X", 611, NULL }, + { "question", 500, NULL }, + { "equal", 675, NULL }, + { "Y", 556, NULL }, + { "Z", 556, NULL }, + { "four", 500, NULL }, + { "a", 500, NULL }, + { "Gcommaaccent", 722, NULL }, + { "b", 500, NULL }, + { "c", 444, NULL }, + { "d", 500, NULL }, + { "e", 444, NULL }, + { "f", 278, NULL }, + { "g", 500, NULL }, + { "bullet", 350, NULL }, + { "h", 500, NULL }, + { "i", 278, NULL }, + { "Oslash", 722, NULL }, + { "dagger", 500, NULL }, + { "j", 278, NULL }, + { "k", 444, NULL }, + { "l", 278, NULL }, + { "m", 722, NULL }, + { "n", 500, NULL }, + { "tcommaaccent", 278, NULL }, + { "o", 500, NULL }, + { "ordfeminine", 276, NULL }, + { "ring", 333, NULL }, + { "p", 500, NULL }, + { "q", 500, NULL }, + { "uhungarumlaut", 500, NULL }, + { "r", 389, NULL }, + { "twosuperior", 300, NULL }, + { "aacute", 500, NULL }, + { "s", 389, NULL }, + { "OE", 944, NULL }, + { "t", 278, NULL }, + { "divide", 675, NULL }, + { "u", 500, NULL }, + { "Ccaron", 667, NULL }, + { "v", 444, NULL }, + { "w", 667, NULL }, + { "x", 444, NULL }, + { "y", 444, NULL }, + { "z", 389, NULL }, + { "Gbreve", 722, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 333, NULL }, + { "Nacute", 667, NULL }, + { "quotedbl", 420, NULL }, + { "gcommaaccent", 500, NULL }, + { "mu", 500, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 500, NULL }, + { "Lslash", 556, NULL }, + { "semicolon", 333, NULL }, + { "oslash", 500, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 471, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 444, NULL }, + { "Ecircumflex", 611, NULL }, + { "gbreve", 500, NULL }, + { "trademark", 980, NULL }, + { "daggerdbl", 500, NULL }, + { "nacute", 500, NULL }, + { "macron", 333, NULL }, + { "Otilde", 722, NULL }, + { "Emacron", 611, NULL }, + { "ellipsis", 889, NULL }, + { "scaron", 389, NULL }, + { "AE", 889, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 278, NULL }, + { "quotedblleft", 556, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 214, NULL }, + { "eight", 500, NULL }, + { "exclamdown", 389, NULL }, + { "endash", 500, NULL }, + { "oe", 667, NULL }, + { "Abreve", 611, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 444, NULL }, + { "Adieresis", 611, NULL }, + { "copyright", 760, NULL }, + { "Egrave", 611, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 611, NULL }, + { "otilde", 500, NULL }, + { "Idieresis", 333, NULL }, + { "parenleft", 333, NULL }, + { "one", 500, NULL }, + { "emacron", 444, NULL }, + { "Odieresis", 722, NULL }, + { "ucircumflex", 500, NULL }, + { "bracketleft", 389, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 333, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 556, NULL }, + { "umacron", 500, NULL }, + { "abreve", 500, NULL }, + { "Eacute", 611, NULL }, + { "adieresis", 500, NULL }, + { "egrave", 444, NULL }, + { "edieresis", 444, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 667, NULL }, + { "asterisk", 500, NULL }, + { "odieresis", 500, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 500, NULL }, + { "nine", 500, NULL }, + { "five", 500, NULL }, + { "udieresis", 500, NULL }, + { "Zcaron", 556, NULL }, + { "Scommaaccent", 500, NULL }, + { "threequarters", 750, NULL }, + { "guillemotright", 500, NULL }, + { "Ccedilla", 667, NULL }, + { "ydieresis", 444, NULL }, + { "tilde", 333, NULL }, + { "at", 920, NULL }, + { "eacute", 444, NULL }, + { "underscore", 500, NULL }, + { "Euro", 500, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 675, NULL }, + { "zero", 500, NULL }, + { "eth", 500, NULL }, + { "Scedilla", 500, NULL }, + { "Ograve", 722, NULL }, + { "Racute", 611, NULL }, + { "partialdiff", 476, NULL }, + { "uacute", 500, NULL }, + { "braceleft", 400, NULL }, + { "Thorn", 611, NULL }, + { "zcaron", 389, NULL }, + { "scommaaccent", 389, NULL }, + { "ccedilla", 444, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 500, NULL }, + { "Ocircumflex", 722, NULL }, + { "Oacute", 722, NULL }, + { "scedilla", 389, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 500, NULL }, + { "racute", 389, NULL }, + { "Tcaron", 556, NULL }, + { "Eogonek", 611, NULL }, + { "thorn", 500, NULL }, + { "degree", 400, NULL }, + { "registered", 760, NULL }, + { "radical", 453, NULL }, + { "Aring", 611, NULL }, + { "percent", 833, NULL }, + { "six", 500, NULL }, + { "paragraph", 523, NULL }, + { "dcaron", 544, NULL }, + { "Uogonek", 722, NULL }, + { "two", 500, NULL }, + { "summation", 600, NULL }, + { "Igrave", 333, NULL }, + { "Lacute", 556, NULL }, + { "ocircumflex", 500, NULL }, + { "oacute", 500, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 556, NULL }, + { "tcaron", 300, NULL }, + { "eogonek", 444, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 722, NULL }, + { "asciicircum", 422, NULL }, + { "aring", 500, NULL }, + { "grave", 333, NULL }, + { "uogonek", 500, NULL }, + { "bracketright", 389, NULL }, + { "Iacute", 333, NULL }, + { "ampersand", 778, NULL }, + { "igrave", 278, NULL }, + { "lacute", 278, NULL }, + { "Ncaron", 667, NULL }, + { "plus", 675, NULL }, + { "uring", 500, NULL }, + { "quotesinglbase", 333, NULL }, + { "lcommaaccent", 278, NULL }, + { "Yacute", 556, NULL }, + { "ohungarumlaut", 500, NULL }, + { "threesuperior", 300, NULL }, + { "acute", 333, NULL }, + { "section", 500, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 556, NULL }, + { "ncaron", 500, NULL }, + { "florin", 500, NULL }, + { "yacute", 444, NULL }, + { "Rcommaaccent", 611, NULL }, + { "fi", 500, NULL }, + { "fl", 500, NULL }, + { "Acircumflex", 611, NULL }, + { "Cacute", 667, NULL }, + { "Icircumflex", 333, NULL }, + { "guillemotleft", 500, NULL }, + { "germandbls", 500, NULL }, + { "Amacron", 611, NULL }, + { "seven", 500, NULL }, + { "Sacute", 500, NULL }, + { "ordmasculine", 310, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 500, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 333, NULL }, + { "rcommaaccent", 389, NULL }, + { "Zdotaccent", 556, NULL }, + { "acircumflex", 500, NULL }, + { "cacute", 444, NULL }, + { "Ecaron", 611, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 400, NULL }, + { "quotedblright", 556, NULL }, + { "amacron", 500, NULL }, + { "sacute", 389, NULL }, + { "imacron", 278, NULL }, + { "cent", 500, NULL }, + { "currency", 500, NULL }, + { "logicalnot", 675, NULL }, + { "zdotaccent", 389, NULL }, + { "Atilde", 611, NULL }, + { "breve", 333, NULL }, + { "bar", 275, NULL }, + { "fraction", 167, NULL }, + { "less", 675, NULL }, + { "ecaron", 444, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 333, NULL }, + { "period", 250, NULL }, + { "Rcaron", 611, NULL }, + { "Kcommaaccent", 667, NULL }, + { "greater", 675, NULL }, + { "atilde", 500, NULL }, + { "brokenbar", 275, NULL }, + { "quoteleft", 333, NULL }, + { "Edotaccent", 611, NULL }, + { "onesuperior", 300, NULL } +}; + +static BuiltinFontWidth timesRomanWidthsTab[] = { + { "Ntilde", 722, NULL }, + { "rcaron", 333, NULL }, + { "kcommaaccent", 500, NULL }, + { "Ncommaaccent", 722, NULL }, + { "Zacute", 611, NULL }, + { "comma", 250, NULL }, + { "cedilla", 333, NULL }, + { "plusminus", 564, NULL }, + { "circumflex", 333, NULL }, + { "dotaccent", 333, NULL }, + { "edotaccent", 444, NULL }, + { "asciitilde", 541, NULL }, + { "colon", 278, NULL }, + { "onehalf", 750, NULL }, + { "dollar", 500, NULL }, + { "Lcaron", 611, NULL }, + { "ntilde", 500, NULL }, + { "Aogonek", 722, NULL }, + { "ncommaaccent", 500, NULL }, + { "minus", 564, NULL }, + { "Iogonek", 333, NULL }, + { "zacute", 444, NULL }, + { "yen", 500, NULL }, + { "space", 250, NULL }, + { "Omacron", 722, NULL }, + { "questiondown", 444, NULL }, + { "emdash", 1000, NULL }, + { "Agrave", 722, NULL }, + { "three", 500, NULL }, + { "numbersign", 500, NULL }, + { "lcaron", 344, NULL }, + { "A", 722, NULL }, + { "B", 667, NULL }, + { "C", 667, NULL }, + { "aogonek", 444, NULL }, + { "D", 722, NULL }, + { "E", 611, NULL }, + { "onequarter", 750, NULL }, + { "F", 556, NULL }, + { "G", 722, NULL }, + { "H", 722, NULL }, + { "I", 333, NULL }, + { "J", 389, NULL }, + { "K", 722, NULL }, + { "iogonek", 278, NULL }, + { "backslash", 278, NULL }, + { "L", 611, NULL }, + { "periodcentered", 250, NULL }, + { "M", 889, NULL }, + { "N", 722, NULL }, + { "omacron", 500, NULL }, + { "Tcommaaccent", 611, NULL }, + { "O", 722, NULL }, + { "P", 556, NULL }, + { "Q", 722, NULL }, + { "Uhungarumlaut", 722, NULL }, + { "R", 667, NULL }, + { "Aacute", 722, NULL }, + { "caron", 333, NULL }, + { "S", 556, NULL }, + { "T", 611, NULL }, + { "U", 722, NULL }, + { "agrave", 444, NULL }, + { "V", 722, NULL }, + { "W", 944, NULL }, + { "X", 722, NULL }, + { "question", 444, NULL }, + { "equal", 564, NULL }, + { "Y", 722, NULL }, + { "Z", 611, NULL }, + { "four", 500, NULL }, + { "a", 444, NULL }, + { "Gcommaaccent", 722, NULL }, + { "b", 500, NULL }, + { "c", 444, NULL }, + { "d", 500, NULL }, + { "e", 444, NULL }, + { "f", 333, NULL }, + { "g", 500, NULL }, + { "bullet", 350, NULL }, + { "h", 500, NULL }, + { "i", 278, NULL }, + { "Oslash", 722, NULL }, + { "dagger", 500, NULL }, + { "j", 278, NULL }, + { "k", 500, NULL }, + { "l", 278, NULL }, + { "m", 778, NULL }, + { "n", 500, NULL }, + { "tcommaaccent", 278, NULL }, + { "o", 500, NULL }, + { "ordfeminine", 276, NULL }, + { "ring", 333, NULL }, + { "p", 500, NULL }, + { "q", 500, NULL }, + { "uhungarumlaut", 500, NULL }, + { "r", 333, NULL }, + { "twosuperior", 300, NULL }, + { "aacute", 444, NULL }, + { "s", 389, NULL }, + { "OE", 889, NULL }, + { "t", 278, NULL }, + { "divide", 564, NULL }, + { "u", 500, NULL }, + { "Ccaron", 667, NULL }, + { "v", 500, NULL }, + { "w", 722, NULL }, + { "x", 500, NULL }, + { "y", 500, NULL }, + { "z", 444, NULL }, + { "Gbreve", 722, NULL }, + { "commaaccent", 250, NULL }, + { "hungarumlaut", 333, NULL }, + { "Idotaccent", 333, NULL }, + { "Nacute", 722, NULL }, + { "quotedbl", 408, NULL }, + { "gcommaaccent", 500, NULL }, + { "mu", 500, NULL }, + { "greaterequal", 549, NULL }, + { "Scaron", 556, NULL }, + { "Lslash", 611, NULL }, + { "semicolon", 278, NULL }, + { "oslash", 500, NULL }, + { "lessequal", 549, NULL }, + { "lozenge", 471, NULL }, + { "parenright", 333, NULL }, + { "ccaron", 444, NULL }, + { "Ecircumflex", 611, NULL }, + { "gbreve", 500, NULL }, + { "trademark", 980, NULL }, + { "daggerdbl", 500, NULL }, + { "nacute", 500, NULL }, + { "macron", 333, NULL }, + { "Otilde", 722, NULL }, + { "Emacron", 611, NULL }, + { "ellipsis", 1000, NULL }, + { "scaron", 389, NULL }, + { "AE", 889, NULL }, + { "Ucircumflex", 722, NULL }, + { "lslash", 278, NULL }, + { "quotedblleft", 444, NULL }, + { "guilsinglright", 333, NULL }, + { "hyphen", 333, NULL }, + { "quotesingle", 180, NULL }, + { "eight", 500, NULL }, + { "exclamdown", 333, NULL }, + { "endash", 500, NULL }, + { "oe", 722, NULL }, + { "Abreve", 722, NULL }, + { "Umacron", 722, NULL }, + { "ecircumflex", 444, NULL }, + { "Adieresis", 722, NULL }, + { "copyright", 760, NULL }, + { "Egrave", 611, NULL }, + { "slash", 278, NULL }, + { "Edieresis", 611, NULL }, + { "otilde", 500, NULL }, + { "Idieresis", 333, NULL }, + { "parenleft", 333, NULL }, + { "one", 500, NULL }, + { "emacron", 444, NULL }, + { "Odieresis", 722, NULL }, + { "ucircumflex", 500, NULL }, + { "bracketleft", 333, NULL }, + { "Ugrave", 722, NULL }, + { "quoteright", 333, NULL }, + { "Udieresis", 722, NULL }, + { "perthousand", 1000, NULL }, + { "Ydieresis", 722, NULL }, + { "umacron", 500, NULL }, + { "abreve", 444, NULL }, + { "Eacute", 611, NULL }, + { "adieresis", 444, NULL }, + { "egrave", 444, NULL }, + { "edieresis", 444, NULL }, + { "idieresis", 278, NULL }, + { "Eth", 722, NULL }, + { "ae", 667, NULL }, + { "asterisk", 500, NULL }, + { "odieresis", 500, NULL }, + { "Uacute", 722, NULL }, + { "ugrave", 500, NULL }, + { "nine", 500, NULL }, + { "five", 500, NULL }, + { "udieresis", 500, NULL }, + { "Zcaron", 611, NULL }, + { "Scommaaccent", 556, NULL }, + { "threequarters", 750, NULL }, + { "guillemotright", 500, NULL }, + { "Ccedilla", 667, NULL }, + { "ydieresis", 500, NULL }, + { "tilde", 333, NULL }, + { "at", 921, NULL }, + { "eacute", 444, NULL }, + { "underscore", 500, NULL }, + { "Euro", 500, NULL }, + { "Dcroat", 722, NULL }, + { "multiply", 564, NULL }, + { "zero", 500, NULL }, + { "eth", 500, NULL }, + { "Scedilla", 556, NULL }, + { "Ograve", 722, NULL }, + { "Racute", 667, NULL }, + { "partialdiff", 476, NULL }, + { "uacute", 500, NULL }, + { "braceleft", 480, NULL }, + { "Thorn", 556, NULL }, + { "zcaron", 444, NULL }, + { "scommaaccent", 389, NULL }, + { "ccedilla", 444, NULL }, + { "Dcaron", 722, NULL }, + { "dcroat", 500, NULL }, + { "Ocircumflex", 722, NULL }, + { "Oacute", 722, NULL }, + { "scedilla", 389, NULL }, + { "ogonek", 333, NULL }, + { "ograve", 500, NULL }, + { "racute", 333, NULL }, + { "Tcaron", 611, NULL }, + { "Eogonek", 611, NULL }, + { "thorn", 500, NULL }, + { "degree", 400, NULL }, + { "registered", 760, NULL }, + { "radical", 453, NULL }, + { "Aring", 722, NULL }, + { "percent", 833, NULL }, + { "six", 500, NULL }, + { "paragraph", 453, NULL }, + { "dcaron", 588, NULL }, + { "Uogonek", 722, NULL }, + { "two", 500, NULL }, + { "summation", 600, NULL }, + { "Igrave", 333, NULL }, + { "Lacute", 611, NULL }, + { "ocircumflex", 500, NULL }, + { "oacute", 500, NULL }, + { "Uring", 722, NULL }, + { "Lcommaaccent", 611, NULL }, + { "tcaron", 326, NULL }, + { "eogonek", 444, NULL }, + { "Delta", 612, NULL }, + { "Ohungarumlaut", 722, NULL }, + { "asciicircum", 469, NULL }, + { "aring", 444, NULL }, + { "grave", 333, NULL }, + { "uogonek", 500, NULL }, + { "bracketright", 333, NULL }, + { "Iacute", 333, NULL }, + { "ampersand", 778, NULL }, + { "igrave", 278, NULL }, + { "lacute", 278, NULL }, + { "Ncaron", 722, NULL }, + { "plus", 564, NULL }, + { "uring", 500, NULL }, + { "quotesinglbase", 333, NULL }, + { "lcommaaccent", 278, NULL }, + { "Yacute", 722, NULL }, + { "ohungarumlaut", 500, NULL }, + { "threesuperior", 300, NULL }, + { "acute", 333, NULL }, + { "section", 500, NULL }, + { "dieresis", 333, NULL }, + { "iacute", 278, NULL }, + { "quotedblbase", 444, NULL }, + { "ncaron", 500, NULL }, + { "florin", 500, NULL }, + { "yacute", 500, NULL }, + { "Rcommaaccent", 667, NULL }, + { "fi", 556, NULL }, + { "fl", 556, NULL }, + { "Acircumflex", 722, NULL }, + { "Cacute", 667, NULL }, + { "Icircumflex", 333, NULL }, + { "guillemotleft", 500, NULL }, + { "germandbls", 500, NULL }, + { "Amacron", 722, NULL }, + { "seven", 500, NULL }, + { "Sacute", 556, NULL }, + { "ordmasculine", 310, NULL }, + { "dotlessi", 278, NULL }, + { "sterling", 500, NULL }, + { "notequal", 549, NULL }, + { "Imacron", 333, NULL }, + { "rcommaaccent", 333, NULL }, + { "Zdotaccent", 611, NULL }, + { "acircumflex", 444, NULL }, + { "cacute", 444, NULL }, + { "Ecaron", 611, NULL }, + { "icircumflex", 278, NULL }, + { "braceright", 480, NULL }, + { "quotedblright", 444, NULL }, + { "amacron", 444, NULL }, + { "sacute", 389, NULL }, + { "imacron", 278, NULL }, + { "cent", 500, NULL }, + { "currency", 500, NULL }, + { "logicalnot", 564, NULL }, + { "zdotaccent", 444, NULL }, + { "Atilde", 722, NULL }, + { "breve", 333, NULL }, + { "bar", 200, NULL }, + { "fraction", 167, NULL }, + { "less", 564, NULL }, + { "ecaron", 444, NULL }, + { "guilsinglleft", 333, NULL }, + { "exclam", 333, NULL }, + { "period", 250, NULL }, + { "Rcaron", 667, NULL }, + { "Kcommaaccent", 722, NULL }, + { "greater", 564, NULL }, + { "atilde", 444, NULL }, + { "brokenbar", 200, NULL }, + { "quoteleft", 333, NULL }, + { "Edotaccent", 611, NULL }, + { "onesuperior", 300, NULL } +}; + +static BuiltinFontWidth zapfDingbatsWidthsTab[] = { + { "a81", 438, NULL }, + { "a82", 138, NULL }, + { "a83", 277, NULL }, + { "a84", 415, NULL }, + { "a85", 509, NULL }, + { "a86", 410, NULL }, + { "a87", 234, NULL }, + { "a88", 234, NULL }, + { "a89", 390, NULL }, + { "a140", 788, NULL }, + { "a141", 788, NULL }, + { "a142", 788, NULL }, + { "a143", 788, NULL }, + { "a144", 788, NULL }, + { "a145", 788, NULL }, + { "a146", 788, NULL }, + { "a147", 788, NULL }, + { "a148", 788, NULL }, + { "a149", 788, NULL }, + { "a90", 390, NULL }, + { "a91", 276, NULL }, + { "a92", 276, NULL }, + { "space", 278, NULL }, + { "a93", 317, NULL }, + { "a94", 317, NULL }, + { "a95", 334, NULL }, + { "a96", 334, NULL }, + { "a97", 392, NULL }, + { "a98", 392, NULL }, + { "a99", 668, NULL }, + { "a150", 788, NULL }, + { "a151", 788, NULL }, + { "a152", 788, NULL }, + { "a153", 788, NULL }, + { "a154", 788, NULL }, + { "a155", 788, NULL }, + { "a156", 788, NULL }, + { "a157", 788, NULL }, + { "a158", 788, NULL }, + { "a159", 788, NULL }, + { "a160", 894, NULL }, + { "a161", 838, NULL }, + { "a162", 924, NULL }, + { "a163", 1016, NULL }, + { "a164", 458, NULL }, + { "a165", 924, NULL }, + { "a166", 918, NULL }, + { "a167", 927, NULL }, + { "a168", 928, NULL }, + { "a169", 928, NULL }, + { "a170", 834, NULL }, + { "a171", 873, NULL }, + { "a172", 828, NULL }, + { "a173", 924, NULL }, + { "a174", 917, NULL }, + { "a175", 930, NULL }, + { "a176", 931, NULL }, + { "a177", 463, NULL }, + { "a178", 883, NULL }, + { "a179", 836, NULL }, + { "a180", 867, NULL }, + { "a181", 696, NULL }, + { "a182", 874, NULL }, + { "a183", 760, NULL }, + { "a184", 946, NULL }, + { "a185", 865, NULL }, + { "a186", 967, NULL }, + { "a187", 831, NULL }, + { "a188", 873, NULL }, + { "a189", 927, NULL }, + { "a1", 974, NULL }, + { "a2", 961, NULL }, + { "a3", 980, NULL }, + { "a4", 719, NULL }, + { "a5", 789, NULL }, + { "a6", 494, NULL }, + { "a7", 552, NULL }, + { "a8", 537, NULL }, + { "a9", 577, NULL }, + { "a190", 970, NULL }, + { "a191", 918, NULL }, + { "a192", 748, NULL }, + { "a193", 836, NULL }, + { "a194", 771, NULL }, + { "a195", 888, NULL }, + { "a196", 748, NULL }, + { "a197", 771, NULL }, + { "a198", 888, NULL }, + { "a199", 867, NULL }, + { "a10", 692, NULL }, + { "a11", 960, NULL }, + { "a12", 939, NULL }, + { "a13", 549, NULL }, + { "a14", 855, NULL }, + { "a15", 911, NULL }, + { "a16", 933, NULL }, + { "a17", 945, NULL }, + { "a18", 974, NULL }, + { "a19", 755, NULL }, + { "a20", 846, NULL }, + { "a21", 762, NULL }, + { "a22", 761, NULL }, + { "a23", 571, NULL }, + { "a24", 677, NULL }, + { "a25", 763, NULL }, + { "a26", 760, NULL }, + { "a27", 759, NULL }, + { "a28", 754, NULL }, + { "a29", 786, NULL }, + { "a30", 788, NULL }, + { "a31", 788, NULL }, + { "a32", 790, NULL }, + { "a33", 793, NULL }, + { "a34", 794, NULL }, + { "a35", 816, NULL }, + { "a36", 823, NULL }, + { "a37", 789, NULL }, + { "a38", 841, NULL }, + { "a39", 823, NULL }, + { "a40", 833, NULL }, + { "a41", 816, NULL }, + { "a42", 831, NULL }, + { "a43", 923, NULL }, + { "a44", 744, NULL }, + { "a45", 723, NULL }, + { "a46", 749, NULL }, + { "a47", 790, NULL }, + { "a48", 792, NULL }, + { "a49", 695, NULL }, + { "a100", 668, NULL }, + { "a101", 732, NULL }, + { "a102", 544, NULL }, + { "a103", 544, NULL }, + { "a104", 910, NULL }, + { "a105", 911, NULL }, + { "a106", 667, NULL }, + { "a107", 760, NULL }, + { "a108", 760, NULL }, + { "a109", 626, NULL }, + { "a50", 776, NULL }, + { "a51", 768, NULL }, + { "a52", 792, NULL }, + { "a53", 759, NULL }, + { "a54", 707, NULL }, + { "a55", 708, NULL }, + { "a56", 682, NULL }, + { "a57", 701, NULL }, + { "a58", 826, NULL }, + { "a59", 815, NULL }, + { "a110", 694, NULL }, + { "a111", 595, NULL }, + { "a112", 776, NULL }, + { "a117", 690, NULL }, + { "a118", 791, NULL }, + { "a119", 790, NULL }, + { "a60", 789, NULL }, + { "a61", 789, NULL }, + { "a62", 707, NULL }, + { "a63", 687, NULL }, + { "a64", 696, NULL }, + { "a65", 689, NULL }, + { "a66", 786, NULL }, + { "a67", 787, NULL }, + { "a68", 713, NULL }, + { "a69", 791, NULL }, + { "a200", 696, NULL }, + { "a201", 874, NULL }, + { "a120", 788, NULL }, + { "a121", 788, NULL }, + { "a202", 974, NULL }, + { "a122", 788, NULL }, + { "a203", 762, NULL }, + { "a123", 788, NULL }, + { "a204", 759, NULL }, + { "a124", 788, NULL }, + { "a205", 509, NULL }, + { "a125", 788, NULL }, + { "a206", 410, NULL }, + { "a126", 788, NULL }, + { "a127", 788, NULL }, + { "a128", 788, NULL }, + { "a129", 788, NULL }, + { "a70", 785, NULL }, + { "a71", 791, NULL }, + { "a72", 873, NULL }, + { "a73", 761, NULL }, + { "a74", 762, NULL }, + { "a75", 759, NULL }, + { "a76", 892, NULL }, + { "a77", 892, NULL }, + { "a78", 788, NULL }, + { "a79", 784, NULL }, + { "a130", 788, NULL }, + { "a131", 788, NULL }, + { "a132", 788, NULL }, + { "a133", 788, NULL }, + { "a134", 788, NULL }, + { "a135", 788, NULL }, + { "a136", 788, NULL }, + { "a137", 788, NULL }, + { "a138", 788, NULL }, + { "a139", 788, NULL } +}; + +BuiltinFont builtinFonts[] = { + { "Courier", standardEncoding, 629, -157, { -23, -250, 715, 805}, NULL }, + { "Courier-Bold", standardEncoding, 629, -157, {-113, -250, 749, 801}, NULL }, + { "Courier-BoldOblique", standardEncoding, 629, -157, { -57, -250, 869, 801}, NULL }, + { "Courier-Oblique", standardEncoding, 629, -157, { -27, -250, 849, 805}, NULL }, + { "Helvetica", standardEncoding, 718, -207, {-166, -225, 1000, 931}, NULL }, + { "Helvetica-Bold", standardEncoding, 718, -207, {-170, -228, 1003, 962}, NULL }, + { "Helvetica-BoldOblique", standardEncoding, 718, -207, {-174, -228, 1114, 962}, NULL }, + { "Helvetica-Oblique", standardEncoding, 718, -207, {-170, -225, 1116, 931}, NULL }, + { "Symbol", symbolEncoding, 1010, -293, {-180, -293, 1090, 1010}, NULL }, + { "Times-Bold", standardEncoding, 683, -217, {-168, -218, 1000, 935}, NULL }, + { "Times-BoldItalic", standardEncoding, 683, -217, {-200, -218, 996, 921}, NULL }, + { "Times-Italic", standardEncoding, 683, -217, {-169, -217, 1010, 883}, NULL }, + { "Times-Roman", standardEncoding, 683, -217, {-168, -218, 1000, 898}, NULL }, + { "ZapfDingbats", zapfDingbatsEncoding, 820, -143, { -1, -143, 981, 820}, NULL } +}; + +BuiltinFont *builtinFontSubst[] = { + &builtinFonts[0], + &builtinFonts[3], + &builtinFonts[1], + &builtinFonts[2], + &builtinFonts[4], + &builtinFonts[7], + &builtinFonts[5], + &builtinFonts[6], + &builtinFonts[12], + &builtinFonts[11], + &builtinFonts[9], + &builtinFonts[10] +}; + +void initBuiltinFontTables() { + builtinFonts[0].widths = new BuiltinFontWidths(courierWidthsTab, 315); + builtinFonts[1].widths = new BuiltinFontWidths(courierBoldWidthsTab, 315); + builtinFonts[2].widths = new BuiltinFontWidths(courierBoldObliqueWidthsTab, 315); + builtinFonts[3].widths = new BuiltinFontWidths(courierObliqueWidthsTab, 315); + builtinFonts[4].widths = new BuiltinFontWidths(helveticaWidthsTab, 315); + builtinFonts[5].widths = new BuiltinFontWidths(helveticaBoldWidthsTab, 316); + builtinFonts[6].widths = new BuiltinFontWidths(helveticaBoldObliqueWidthsTab, 315); + builtinFonts[7].widths = new BuiltinFontWidths(helveticaObliqueWidthsTab, 315); + builtinFonts[8].widths = new BuiltinFontWidths(symbolWidthsTab, 190); + builtinFonts[9].widths = new BuiltinFontWidths(timesBoldWidthsTab, 315); + builtinFonts[10].widths = new BuiltinFontWidths(timesBoldItalicWidthsTab, 315); + builtinFonts[11].widths = new BuiltinFontWidths(timesItalicWidthsTab, 315); + builtinFonts[12].widths = new BuiltinFontWidths(timesRomanWidthsTab, 315); + builtinFonts[13].widths = new BuiltinFontWidths(zapfDingbatsWidthsTab, 202); +} + +void freeBuiltinFontTables() { + int i; + + for (i = 0; i < 14; ++i) { + delete builtinFonts[i].widths; + } +} diff --git a/rosapps/smartpdf/poppler/poppler/BuiltinFontTables.h b/rosapps/smartpdf/poppler/poppler/BuiltinFontTables.h new file mode 100644 index 00000000000..eb45549efd2 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/BuiltinFontTables.h @@ -0,0 +1,23 @@ +//======================================================================== +// +// BuiltinFontTables.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef BUILTINFONTTABLES_H +#define BUILTINFONTTABLES_H + +#include "BuiltinFont.h" + +#define nBuiltinFonts 14 +#define nBuiltinFontSubsts 12 + +extern BuiltinFont builtinFonts[nBuiltinFonts]; +extern BuiltinFont *builtinFontSubst[nBuiltinFontSubsts]; + +extern void initBuiltinFontTables(); +extern void freeBuiltinFontTables(); + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/CMap.cc b/rosapps/smartpdf/poppler/poppler/CMap.cc new file mode 100644 index 00000000000..65f47669410 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CMap.cc @@ -0,0 +1,408 @@ +//======================================================================== +// +// CMap.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include "goo/gmem.h" +#include "goo/gfile.h" +#include "goo/GooString.h" +#include "Error.h" +#include "GlobalParams.h" +#include "PSTokenizer.h" +#include "CMap.h" + +//------------------------------------------------------------------------ + +struct CMapVectorEntry { + GBool isVector; + union { + CMapVectorEntry *vector; + CID cid; + }; +}; + +//------------------------------------------------------------------------ + +static int getCharFromFile(void *data) { + return fgetc((FILE *)data); +} + +//------------------------------------------------------------------------ + +CMap *CMap::parse(CMapCache *cache, GooString *collectionA, + GooString *cMapNameA) { + FILE *f; + CMap *cmap; + PSTokenizer *pst; + char tok1[256], tok2[256], tok3[256]; + int n1, n2, n3; + Guint start, end, code; + + if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) { + + // Check for an identity CMap. + if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { + return new CMap(collectionA->copy(), cMapNameA->copy(), 0); + } + if (!cMapNameA->cmp("Identity-V")) { + return new CMap(collectionA->copy(), cMapNameA->copy(), 1); + } + + error(-1, "Couldn't find '%s' CMap file for '%s' collection", + cMapNameA->getCString(), collectionA->getCString()); + return NULL; + } + + cmap = new CMap(collectionA->copy(), cMapNameA->copy()); + + pst = new PSTokenizer(&getCharFromFile, f); + pst->getToken(tok1, sizeof(tok1), &n1); + while (pst->getToken(tok2, sizeof(tok2), &n2)) { + if (!strcmp(tok2, "usecmap")) { + if (tok1[0] == '/') { + cmap->useCMap(cache, tok1 + 1); + } + pst->getToken(tok1, sizeof(tok1), &n1); + } else if (!strcmp(tok1, "/WMode")) { + cmap->wMode = atoi(tok2); + pst->getToken(tok1, sizeof(tok1), &n1); + } else if (!strcmp(tok2, "begincodespacerange")) { + while (pst->getToken(tok1, sizeof(tok1), &n1)) { + if (!strcmp(tok1, "endcodespacerange")) { + break; + } + if (!pst->getToken(tok2, sizeof(tok2), &n2) || + !strcmp(tok2, "endcodespacerange")) { + error(-1, "Illegal entry in codespacerange block in CMap"); + break; + } + if (tok1[0] == '<' && tok2[0] == '<' && + n1 == n2 && n1 >= 4 && (n1 & 1) == 0) { + tok1[n1 - 1] = tok2[n1 - 1] = '\0'; + sscanf(tok1 + 1, "%x", &start); + sscanf(tok2 + 1, "%x", &end); + n1 = (n1 - 2) / 2; + cmap->addCodeSpace(cmap->vector, start, end, n1); + } + } + pst->getToken(tok1, sizeof(tok1), &n1); + } else if (!strcmp(tok2, "begincidchar")) { + while (pst->getToken(tok1, sizeof(tok1), &n1)) { + if (!strcmp(tok1, "endcidchar")) { + break; + } + if (!pst->getToken(tok2, sizeof(tok2), &n2) || + !strcmp(tok2, "endcidchar")) { + error(-1, "Illegal entry in cidchar block in CMap"); + break; + } + if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' && + n1 >= 4 && (n1 & 1) == 0)) { + error(-1, "Illegal entry in cidchar block in CMap"); + continue; + } + tok1[n1 - 1] = '\0'; + if (sscanf(tok1 + 1, "%x", &code) != 1) { + error(-1, "Illegal entry in cidchar block in CMap"); + continue; + } + n1 = (n1 - 2) / 2; + cmap->addCIDs(code, code, n1, (CID)atoi(tok2)); + } + pst->getToken(tok1, sizeof(tok1), &n1); + } else if (!strcmp(tok2, "begincidrange")) { + while (pst->getToken(tok1, sizeof(tok1), &n1)) { + if (!strcmp(tok1, "endcidrange")) { + break; + } + if (!pst->getToken(tok2, sizeof(tok2), &n2) || + !strcmp(tok2, "endcidrange") || + !pst->getToken(tok3, sizeof(tok3), &n3) || + !strcmp(tok3, "endcidrange")) { + error(-1, "Illegal entry in cidrange block in CMap"); + break; + } + if (tok1[0] == '<' && tok2[0] == '<' && + n1 == n2 && n1 >= 4 && (n1 & 1) == 0) { + tok1[n1 - 1] = tok2[n1 - 1] = '\0'; + sscanf(tok1 + 1, "%x", &start); + sscanf(tok2 + 1, "%x", &end); + n1 = (n1 - 2) / 2; + cmap->addCIDs(start, end, n1, (CID)atoi(tok3)); + } + } + pst->getToken(tok1, sizeof(tok1), &n1); + } else { + strcpy(tok1, tok2); + } + } + delete pst; + + fclose(f); + + return cmap; +} + +CMap::CMap(GooString *collectionA, GooString *cMapNameA) { + int i; + + collection = collectionA; + cMapName = cMapNameA; + wMode = 0; + vector = (CMapVectorEntry *)gmallocn(256, sizeof(CMapVectorEntry)); + for (i = 0; i < 256; ++i) { + vector[i].isVector = gFalse; + vector[i].cid = 0; + } + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + +CMap::CMap(GooString *collectionA, GooString *cMapNameA, int wModeA) { + collection = collectionA; + cMapName = cMapNameA; + wMode = wModeA; + vector = NULL; + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + +void CMap::useCMap(CMapCache *cache, char *useName) { + GooString *useNameStr; + CMap *subCMap; + + useNameStr = new GooString(useName); + subCMap = cache->getCMap(collection, useNameStr); + delete useNameStr; + if (!subCMap) { + return; + } + copyVector(vector, subCMap->vector); + subCMap->decRefCnt(); +} + +void CMap::copyVector(CMapVectorEntry *dest, CMapVectorEntry *src) { + int i, j; + + for (i = 0; i < 256; ++i) { + if (src[i].isVector) { + if (!dest[i].isVector) { + dest[i].isVector = gTrue; + dest[i].vector = + (CMapVectorEntry *)gmallocn(256, sizeof(CMapVectorEntry)); + for (j = 0; j < 256; ++j) { + dest[i].vector[j].isVector = gFalse; + dest[i].vector[j].cid = 0; + } + } + copyVector(dest[i].vector, src[i].vector); + } else { + if (dest[i].isVector) { + error(-1, "Collision in usecmap"); + } else { + dest[i].cid = src[i].cid; + } + } + } +} + +void CMap::addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end, + Guint nBytes) { + Guint start2, end2; + int startByte, endByte, i, j; + + if (nBytes > 1) { + startByte = (start >> (8 * (nBytes - 1))) & 0xff; + endByte = (end >> (8 * (nBytes - 1))) & 0xff; + start2 = start & ((1 << (8 * (nBytes - 1))) - 1); + end2 = end & ((1 << (8 * (nBytes - 1))) - 1); + for (i = startByte; i <= endByte; ++i) { + if (!vec[i].isVector) { + vec[i].isVector = gTrue; + vec[i].vector = + (CMapVectorEntry *)gmallocn(256, sizeof(CMapVectorEntry)); + for (j = 0; j < 256; ++j) { + vec[i].vector[j].isVector = gFalse; + vec[i].vector[j].cid = 0; + } + } + addCodeSpace(vec[i].vector, start2, end2, nBytes - 1); + } + } +} + +void CMap::addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID) { + CMapVectorEntry *vec; + CID cid; + int byte; + Guint i; + + vec = vector; + for (i = nBytes - 1; i >= 1; --i) { + byte = (start >> (8 * i)) & 0xff; + if (!vec[byte].isVector) { + error(-1, "Invalid CID (%0*x - %0*x) in CMap", + 2*nBytes, start, 2*nBytes, end); + return; + } + vec = vec[byte].vector; + } + cid = firstCID; + for (byte = (int)(start & 0xff); byte <= (int)(end & 0xff); ++byte) { + if (vec[byte].isVector) { + error(-1, "Invalid CID (%0*x - %0*x) in CMap", + 2*nBytes, start, 2*nBytes, end); + } else { + vec[byte].cid = cid; + } + ++cid; + } +} + +CMap::~CMap() { + delete collection; + delete cMapName; + if (vector) { + freeCMapVector(vector); + } +#if MULTITHREADED + gDestroyMutex(&mutex); +#endif +} + +void CMap::freeCMapVector(CMapVectorEntry *vec) { + int i; + + for (i = 0; i < 256; ++i) { + if (vec[i].isVector) { + freeCMapVector(vec[i].vector); + } + } + gfree(vec); +} + +void CMap::incRefCnt() { +#if MULTITHREADED + gLockMutex(&mutex); +#endif + ++refCnt; +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif +} + +void CMap::decRefCnt() { + GBool done; + +#if MULTITHREADED + gLockMutex(&mutex); +#endif + done = --refCnt == 0; +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif + if (done) { + delete this; + } +} + +GBool CMap::match(GooString *collectionA, GooString *cMapNameA) { + return !collection->cmp(collectionA) && !cMapName->cmp(cMapNameA); +} + +CID CMap::getCID(char *s, int len, int *nUsed) { + CMapVectorEntry *vec; + int n, i; + + if (!(vec = vector)) { + // identity CMap + *nUsed = 2; + if (len < 2) { + return 0; + } + return ((s[0] & 0xff) << 8) + (s[1] & 0xff); + } + n = 0; + while (1) { + if (n >= len) { + *nUsed = n; + return 0; + } + i = s[n++] & 0xff; + if (!vec[i].isVector) { + *nUsed = n; + return vec[i].cid; + } + vec = vec[i].vector; + } +} + +//------------------------------------------------------------------------ + +CMapCache::CMapCache() { + int i; + + for (i = 0; i < cMapCacheSize; ++i) { + cache[i] = NULL; + } +} + +CMapCache::~CMapCache() { + int i; + + for (i = 0; i < cMapCacheSize; ++i) { + if (cache[i]) { + cache[i]->decRefCnt(); + } + } +} + +CMap *CMapCache::getCMap(GooString *collection, GooString *cMapName) { + CMap *cmap; + int i, j; + + if (cache[0] && cache[0]->match(collection, cMapName)) { + cache[0]->incRefCnt(); + return cache[0]; + } + for (i = 1; i < cMapCacheSize; ++i) { + if (cache[i] && cache[i]->match(collection, cMapName)) { + cmap = cache[i]; + for (j = i; j >= 1; --j) { + cache[j] = cache[j - 1]; + } + cache[0] = cmap; + cmap->incRefCnt(); + return cmap; + } + } + if ((cmap = CMap::parse(this, collection, cMapName))) { + if (cache[cMapCacheSize - 1]) { + cache[cMapCacheSize - 1]->decRefCnt(); + } + for (j = cMapCacheSize - 1; j >= 1; --j) { + cache[j] = cache[j - 1]; + } + cache[0] = cmap; + cmap->incRefCnt(); + return cmap; + } + return NULL; +} diff --git a/rosapps/smartpdf/poppler/poppler/CMap.h b/rosapps/smartpdf/poppler/poppler/CMap.h new file mode 100644 index 00000000000..85b44d9a9af --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CMap.h @@ -0,0 +1,101 @@ +//======================================================================== +// +// CMap.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef CMAP_H +#define CMAP_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "poppler-config.h" +#include "goo/gtypes.h" +#include "CharTypes.h" + +#if MULTITHREADED +#include +#endif + +class GooString; +struct CMapVectorEntry; +class CMapCache; + +//------------------------------------------------------------------------ + +class CMap { +public: + + // Create the CMap specified by and . Sets + // the initial reference count to 1. Returns NULL on failure. + static CMap *parse(CMapCache *cache, GooString *collectionA, + GooString *cMapNameA); + + ~CMap(); + + void incRefCnt(); + void decRefCnt(); + + // Return collection name (-). + GooString *getCollection() { return collection; } + + // Return true if this CMap matches the specified , and + // . + GBool match(GooString *collectionA, GooString *cMapNameA); + + // Return the CID corresponding to the character code starting at + // , which contains bytes. Sets * to the number of + // bytes used by the char code. + CID getCID(char *s, int len, int *nUsed); + + // Return the writing mode (0=horizontal, 1=vertical). + int getWMode() { return wMode; } + +private: + + CMap(GooString *collectionA, GooString *cMapNameA); + CMap(GooString *collectionA, GooString *cMapNameA, int wModeA); + void useCMap(CMapCache *cache, char *useName); + void copyVector(CMapVectorEntry *dest, CMapVectorEntry *src); + void addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end, + Guint nBytes); + void addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID); + void freeCMapVector(CMapVectorEntry *vec); + + GooString *collection; + GooString *cMapName; + int wMode; // writing mode (0=horizontal, 1=vertical) + CMapVectorEntry *vector; // vector for first byte (NULL for + // identity CMap) + int refCnt; +#if MULTITHREADED + GooMutex mutex; +#endif +}; + +//------------------------------------------------------------------------ + +#define cMapCacheSize 4 + +class CMapCache { +public: + + CMapCache(); + ~CMapCache(); + + // Get the CMap for the specified character collection. + // Increments its reference count; there will be one reference for + // the cache plus one for the caller of this function. Returns NULL + // on failure. + CMap *getCMap(GooString *collection, GooString *cMapName); + +private: + + CMap *cache[cMapCacheSize]; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/CairoFontEngine.cc b/rosapps/smartpdf/poppler/poppler/CairoFontEngine.cc new file mode 100644 index 00000000000..0ec0a005591 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CairoFontEngine.cc @@ -0,0 +1,364 @@ +//======================================================================== +// +// CairoFontEngine.cc +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, Inc +// +//======================================================================== + +#include + +#include "config.h" +#include +#include "CairoFontEngine.h" +#include "CharCodeToUnicode.h" +#include "GlobalParams.h" +#include +#include +#include "goo/gfile.h" +#include "Error.h" + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +static void fileWrite(void *stream, char *data, int len) { + fwrite(data, 1, len, (FILE *)stream); +} + +//------------------------------------------------------------------------ +// CairoFont +//------------------------------------------------------------------------ + +static void cairo_font_face_destroy (void *data) +{ + CairoFont *font = (CairoFont *) data; + + delete font; +} + +CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs) { + Ref embRef; + Object refObj, strObj; + GooString *tmpFileName, *fileName, *substName,*tmpFileName2; + DisplayFontParam *dfp; + FILE *tmpFile; + int c, i, n, code, cmap; + GfxFontType fontType; + char **enc; + char *name; + FoFiTrueType *ff; + FoFiType1C *ff1c; + CharCodeToUnicode *ctu; + Unicode uBuf[8]; + Ref ref; + static cairo_user_data_key_t cairo_font_face_key; + cairo_font_face_t *cairo_font_face; + FT_Face face; + + Gushort *codeToGID; + int codeToGIDLen; + + dfp = NULL; + codeToGID = NULL; + codeToGIDLen = 0; + cairo_font_face = NULL; + + ref = *gfxFont->getID(); + fontType = gfxFont->getType(); + + tmpFileName = NULL; + + if (gfxFont->getEmbeddedFontID(&embRef)) { + if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { + error(-1, "Couldn't create temporary font file"); + goto err2; + } + + refObj.initRef(embRef.num, embRef.gen); + refObj.fetch(xref, &strObj); + refObj.free(); + strObj.streamReset(); + while ((c = strObj.streamGetChar()) != EOF) { + fputc(c, tmpFile); + } + strObj.streamClose(); + strObj.free(); + fclose(tmpFile); + fileName = tmpFileName; + + } else if (!(fileName = gfxFont->getExtFontFile())) { + // look for a display font mapping or a substitute font + dfp = NULL; + if (gfxFont->getName()) { + dfp = globalParams->getDisplayFont(gfxFont); + } + if (!dfp) { + error(-1, "Couldn't find a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + switch (dfp->kind) { + case displayFontT1: + fileName = dfp->t1.fileName; + fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1; + break; + case displayFontTT: + fileName = dfp->tt.fileName; + fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType; + break; + } + } + + switch (fontType) { + case fontType1: + case fontType1C: + if (FT_New_Face(lib, fileName->getCString(), 0, &face)) { + error(-1, "could not create type1 face"); + goto err2; + } + + enc = ((Gfx8BitFont *)gfxFont)->getEncoding(); + + codeToGID = (Gushort *)gmallocn(256, sizeof(int)); + codeToGIDLen = 256; + for (i = 0; i < 256; ++i) { + codeToGID[i] = 0; + if ((name = enc[i])) { + codeToGID[i] = (Gushort)FT_Get_Name_Index(face, name); + } + } + break; + + case fontCIDType2: + codeToGID = NULL; + n = 0; + if (dfp) { + // create a CID-to-GID mapping, via Unicode + if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) { + if ((ff = FoFiTrueType::load(fileName->getCString()))) { + // look for a Unicode cmap + for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) { + if ((ff->getCmapPlatform(cmap) == 3 && + ff->getCmapEncoding(cmap) == 1) || + ff->getCmapPlatform(cmap) == 0) { + break; + } + } + if (cmap < ff->getNumCmaps()) { + // map CID -> Unicode -> GID + n = ctu->getLength(); + codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); + for (code = 0; code < n; ++code) { + if (ctu->mapToUnicode(code, uBuf, 8) > 0) { + codeToGID[code] = ff->mapCodeToGID(cmap, uBuf[0]); + } else { + codeToGID[code] = 0; + } + } + } + delete ff; + } + ctu->decRefCnt(); + } else { + error(-1, "Couldn't find a mapping to Unicode for font '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + } else { + if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { + n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); + codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); + memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), + n * sizeof(Gushort)); + } + } + codeToGIDLen = n; + /* Fall through */ + case fontTrueType: + if (!(ff = FoFiTrueType::load(fileName->getCString()))) { + error(-1, "failed to load truetype font\n"); + goto err2; + } + /* This might be set already for the CIDType2 case */ + if (fontType == fontTrueType) { + codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff); + codeToGIDLen = 256; + } + if (!openTempFile(&tmpFileName2, &tmpFile, "wb", NULL)) { + delete ff; + error(-1, "failed to open truetype tempfile\n"); + goto err2; + } + ff->writeTTF(&fileWrite, tmpFile); + fclose(tmpFile); + delete ff; + + if (FT_New_Face(lib, tmpFileName2->getCString(), 0, &face)) { + error(-1, "could not create truetype face\n"); + goto err2; + } + unlink (tmpFileName2->getCString()); + delete tmpFileName2; + break; + + case fontCIDType0: + case fontCIDType0C: + + codeToGID = NULL; + codeToGIDLen = 0; + + if (!useCIDs) + { + if ((ff1c = FoFiType1C::load(fileName->getCString()))) { + codeToGID = ff1c->getCIDToGIDMap(&codeToGIDLen); + delete ff1c; + } + } + + if (FT_New_Face(lib, fileName->getCString(), 0, &face)) { + gfree(codeToGID); + codeToGID = NULL; + error(-1, "could not create cid face\n"); + goto err2; + } + break; + + default: + printf ("font type not handled\n"); + goto err2; + break; + } + + // delete the (temporary) font file -- with Unix hard link + // semantics, this will remove the last link; otherwise it will + // return an error, leaving the file to be deleted later + if (fileName == tmpFileName) { + unlink (fileName->getCString()); + delete tmpFileName; + } + + cairo_font_face = cairo_ft_font_face_create_for_ft_face (face, + FT_LOAD_NO_HINTING | + FT_LOAD_NO_BITMAP); + if (cairo_font_face == NULL) { + error(-1, "could not create cairo font\n"); + goto err2; /* this doesn't do anything, but it looks like we're + * handling the error */ + } { + CairoFont *ret = new CairoFont(ref, cairo_font_face, face, codeToGID, codeToGIDLen); + cairo_font_face_set_user_data (cairo_font_face, + &cairo_font_face_key, + ret, + cairo_font_face_destroy); + + return ret; + } + err2: + /* hmm? */ + printf ("some font thing failed\n"); + return NULL; +} + +CairoFont::CairoFont(Ref ref, cairo_font_face_t *cairo_font_face, FT_Face face, + Gushort *codeToGID, int codeToGIDLen) : ref(ref), cairo_font_face(cairo_font_face), + face(face), codeToGID(codeToGID), + codeToGIDLen(codeToGIDLen) { } + +CairoFont::~CairoFont() { + FT_Done_Face (face); + gfree(codeToGID); +} + +GBool +CairoFont::matches(Ref &other) { + return (other.num == ref.num && other.gen == ref.gen); +} + +cairo_font_face_t * +CairoFont::getFontFace(void) { + return cairo_font_face; +} + +unsigned long +CairoFont::getGlyph(CharCode code, + Unicode *u, int uLen) { + FT_UInt gid; + + if (codeToGID && code < codeToGIDLen) { + gid = (FT_UInt)codeToGID[code]; + } else { + gid = (FT_UInt)code; + } + return gid; +} + +//------------------------------------------------------------------------ +// CairoFontEngine +//------------------------------------------------------------------------ + +CairoFontEngine::CairoFontEngine(FT_Library libA) { + int i; + + lib = libA; + for (i = 0; i < cairoFontCacheSize; ++i) { + fontCache[i] = NULL; + } + + FT_Int major, minor, patch; + // as of FT 2.1.8, CID fonts are indexed by CID instead of GID + FT_Library_Version(lib, &major, &minor, &patch); + useCIDs = major > 2 || + (major == 2 && (minor > 1 || (minor == 1 && patch > 7))); +} + +CairoFontEngine::~CairoFontEngine() { + int i; + + for (i = 0; i < cairoFontCacheSize; ++i) { + if (fontCache[i]) + delete fontCache[i]; + } +} + +CairoFont * +CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref) { + int i, j; + Ref ref; + CairoFont *font; + GfxFontType fontType; + + fontType = gfxFont->getType(); + if (fontType == fontType3) { + /* Need to figure this out later */ + // return NULL; + } + + ref = *gfxFont->getID(); + + for (i = 0; i < cairoFontCacheSize; ++i) { + font = fontCache[i]; + if (font && font->matches(ref)) { + for (j = i; j > 0; --j) { + fontCache[j] = fontCache[j-1]; + } + fontCache[0] = font; + return font; + } + } + + font = CairoFont::create (gfxFont, xref, lib, useCIDs); + //XXX: if font is null should we still insert it into the cache? + if (fontCache[cairoFontCacheSize - 1]) { + delete fontCache[cairoFontCacheSize - 1]; + } + for (j = cairoFontCacheSize - 1; j > 0; --j) { + fontCache[j] = fontCache[j-1]; + } + fontCache[0] = font; + return font; +} + diff --git a/rosapps/smartpdf/poppler/poppler/CairoFontEngine.h b/rosapps/smartpdf/poppler/poppler/CairoFontEngine.h new file mode 100644 index 00000000000..f32b6a99667 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CairoFontEngine.h @@ -0,0 +1,61 @@ +//======================================================================== +// +// CairoFontEngine.h +// +//======================================================================== + +#ifndef CAIROFONTENGINE_H +#define CAIROFONTENGINE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include + +#include "GfxFont.h" + +class CairoFont { +public: + static CairoFont *create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs); + ~CairoFont(); + + GBool matches(Ref &other); + cairo_font_face_t *getFontFace(void); + unsigned long getGlyph(CharCode code, Unicode *u, int uLen); +private: + CairoFont(Ref ref, cairo_font_face_t *cairo_font_face, FT_Face face, + Gushort *codeToGID, int codeToGIDLen); + Ref ref; + cairo_font_face_t *cairo_font_face; + FT_Face face; + + Gushort *codeToGID; + int codeToGIDLen; +}; + +//------------------------------------------------------------------------ + +#define cairoFontCacheSize 64 + +//------------------------------------------------------------------------ +// CairoFontEngine +//------------------------------------------------------------------------ + +class CairoFontEngine { +public: + + // Create a font engine. + CairoFontEngine(FT_Library libA); + ~CairoFontEngine(); + + CairoFont *getFont(GfxFont *gfxFont, XRef *xref); + +private: + CairoFont *fontCache[cairoFontCacheSize]; + FT_Library lib; + GBool useCIDs; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/CairoOutputDev.cc b/rosapps/smartpdf/poppler/poppler/CairoOutputDev.cc new file mode 100644 index 00000000000..d25f5f85e6e --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CairoOutputDev.cc @@ -0,0 +1,873 @@ +//======================================================================== +// +// CairoOutputDev.cc +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, Inc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include + +#include "goo/gfile.h" +#include "GlobalParams.h" +#include "Error.h" +#include "Object.h" +#include "GfxState.h" +#include "GfxFont.h" +#include "Link.h" +#include "CharCodeToUnicode.h" +#include "FontEncodingTables.h" +#include +#include +#include "CairoOutputDev.h" +#include "CairoFontEngine.h" + +//------------------------------------------------------------------------ + +// #define LOG_CAIRO + +#ifdef LOG_CAIRO +#define LOG(x) (x) +#else +#define LOG(x) +#endif + + +//------------------------------------------------------------------------ +// CairoOutputDev +//------------------------------------------------------------------------ + +CairoOutputDev::CairoOutputDev() { + xref = NULL; + + FT_Init_FreeType(&ft_lib); + fontEngine = NULL; + glyphs = NULL; + fill_pattern = NULL; + stroke_pattern = NULL; + stroke_opacity = 1.0; + fill_opacity = 1.0; + textClipPath = NULL; + cairo = NULL; + currentFont = NULL; +} + +CairoOutputDev::~CairoOutputDev() { + if (fontEngine) { + delete fontEngine; + } + FT_Done_FreeType(ft_lib); + + if (cairo) + cairo_destroy (cairo); + cairo_pattern_destroy (stroke_pattern); + cairo_pattern_destroy (fill_pattern); +} + +void CairoOutputDev::setCairo(cairo_t *cairo) +{ + if (this->cairo != NULL) + cairo_destroy (this->cairo); + if (cairo != NULL) + this->cairo = cairo_reference (cairo); + else + this->cairo = NULL; +} + +void CairoOutputDev::startDoc(XRef *xrefA) { + xref = xrefA; + if (fontEngine) { + delete fontEngine; + } + fontEngine = new CairoFontEngine(ft_lib); +} + +void CairoOutputDev::drawLink(Link *link, Catalog *catalog) { +} + +void CairoOutputDev::saveState(GfxState *state) { + LOG(printf ("save\n")); + cairo_save (cairo); +} + +void CairoOutputDev::restoreState(GfxState *state) { + LOG(printf ("restore\n")); + cairo_restore (cairo); + + /* These aren't restored by cairo_restore() since we keep them in + * the output device. */ + updateFillColor(state); + updateStrokeColor(state); + updateFillOpacity(state); + updateStrokeOpacity(state); +} + +void CairoOutputDev::updateAll(GfxState *state) { + updateLineDash(state); + updateLineJoin(state); + updateLineCap(state); + updateLineWidth(state); + updateFlatness(state); + updateMiterLimit(state); + updateFillColor(state); + updateStrokeColor(state); + updateFillOpacity(state); + updateStrokeOpacity(state); + needFontUpdate = gTrue; +} + +void CairoOutputDev::setDefaultCTM(double *ctm) { + cairo_matrix_t matrix; + matrix.xx = ctm[0]; + matrix.yx = ctm[1]; + matrix.xy = ctm[2]; + matrix.yy = ctm[3]; + matrix.x0 = ctm[4]; + matrix.y0 = ctm[5]; + + cairo_transform (cairo, &matrix); + + OutputDev::setDefaultCTM(ctm); +} + +void CairoOutputDev::updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, + double m31, double m32) { + cairo_matrix_t matrix; + matrix.xx = m11; + matrix.yx = m12; + matrix.xy = m21; + matrix.yy = m22; + matrix.x0 = m31; + matrix.y0 = m32; + + cairo_transform (cairo, &matrix); + updateLineDash(state); + updateLineJoin(state); + updateLineCap(state); + updateLineWidth(state); +} + +void CairoOutputDev::updateLineDash(GfxState *state) { + double *dashPattern; + int dashLength; + double dashStart; + + state->getLineDash(&dashPattern, &dashLength, &dashStart); + cairo_set_dash (cairo, dashPattern, dashLength, dashStart); +} + +void CairoOutputDev::updateFlatness(GfxState *state) { + // cairo_set_tolerance (cairo, state->getFlatness()); +} + +void CairoOutputDev::updateLineJoin(GfxState *state) { + switch (state->getLineJoin()) { + case 0: + cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER); + break; + case 1: + cairo_set_line_join (cairo, CAIRO_LINE_JOIN_ROUND); + break; + case 2: + cairo_set_line_join (cairo, CAIRO_LINE_JOIN_BEVEL); + break; + } +} + +void CairoOutputDev::updateLineCap(GfxState *state) { + switch (state->getLineCap()) { + case 0: + cairo_set_line_cap (cairo, CAIRO_LINE_CAP_BUTT); + break; + case 1: + cairo_set_line_cap (cairo, CAIRO_LINE_CAP_ROUND); + break; + case 2: + cairo_set_line_cap (cairo, CAIRO_LINE_CAP_SQUARE); + break; + } +} + +void CairoOutputDev::updateMiterLimit(GfxState *state) { + cairo_set_miter_limit (cairo, state->getMiterLimit()); +} + +#define MIN(a,b) (a) < (b) ? (a) : (b) + +void CairoOutputDev::updateLineWidth(GfxState *state) { + LOG(printf ("line width: %f\n", state->getLineWidth())); + if (state->getLineWidth() == 0.0) { + /* find out how big pixels (device unit) are in the x and y directions + * choose the smaller of the two as our line width */ + double x = 1.0, y = 1.0; + cairo_device_to_user_distance(cairo, &x, &y); + cairo_set_line_width (cairo, MIN(fabs(x),fabs(y))); + } else { + cairo_set_line_width (cairo, state->getLineWidth()); + } +} + +void CairoOutputDev::updateFillColor(GfxState *state) { + state->getFillRGB(&fill_color); + + cairo_pattern_destroy(fill_pattern); + fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0, + fill_color.g / 65535.0, + fill_color.b / 65535.0, + fill_opacity); + + LOG(printf ("fill color: %d %d %d\n", + fill_color.r, fill_color.g, fill_color.b)); +} + +void CairoOutputDev::updateStrokeColor(GfxState *state) { + state->getStrokeRGB(&stroke_color); + + cairo_pattern_destroy(stroke_pattern); + stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0, + stroke_color.g / 65535.0, + stroke_color.b / 65535.0, + stroke_opacity); + + LOG(printf ("stroke color: %d %d %d\n", + stroke_color.r, stroke_color.g, stroke_color.b)); +} + +void CairoOutputDev::updateFillOpacity(GfxState *state) { + fill_opacity = state->getFillOpacity(); + + cairo_pattern_destroy(fill_pattern); + fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0, + fill_color.g / 65535.0, + fill_color.b / 65535.0, + fill_opacity); + + LOG(printf ("fill opacity: %f\n", fill_opacity)); +} + +void CairoOutputDev::updateStrokeOpacity(GfxState *state) { + stroke_opacity = state->getStrokeOpacity(); + + cairo_pattern_destroy(stroke_pattern); + stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0, + stroke_color.g / 65535.0, + stroke_color.b / 65535.0, + stroke_opacity); + + LOG(printf ("stroke opacity: %f\n", stroke_opacity)); +} + +void CairoOutputDev::updateFont(GfxState *state) { + cairo_font_face_t *font_face; + cairo_matrix_t matrix; + + LOG(printf ("updateFont() font=%s\n", state->getFont()->getName()->getCString())); + + needFontUpdate = gFalse; + + if (state->getFont()->getType() == fontType3) + return; + + currentFont = fontEngine->getFont (state->getFont(), xref); + + if (!currentFont) + return; + + LOG(printf ("font matrix: %f %f %f %f\n", m11, m12, m21, m22)); + + font_face = currentFont->getFontFace(); + cairo_set_font_face (cairo, font_face); + + double fontSize = state->getFontSize(); + double *m = state->getTextMat(); + matrix.xx = m[0] * fontSize * state->getHorizScaling(); + matrix.yx = m[1] * fontSize * state->getHorizScaling(); + matrix.xy = -m[2] * fontSize; + matrix.yy = -m[3] * fontSize; + matrix.x0 = 0; + matrix.y0 = 0; + cairo_set_font_matrix (cairo, &matrix); +} + +void CairoOutputDev::doPath(GfxState *state, GfxPath *path) { + GfxSubpath *subpath; + int i, j; + for (i = 0; i < path->getNumSubpaths(); ++i) { + subpath = path->getSubpath(i); + if (subpath->getNumPoints() > 0) { + cairo_move_to (cairo, subpath->getX(0), subpath->getY(0)); + j = 1; + while (j < subpath->getNumPoints()) { + if (subpath->getCurve(j)) { + cairo_curve_to( cairo, + subpath->getX(j), subpath->getY(j), + subpath->getX(j+1), subpath->getY(j+1), + subpath->getX(j+2), subpath->getY(j+2)); + + j += 3; + } else { + cairo_line_to (cairo, subpath->getX(j), subpath->getY(j)); + ++j; + } + } + if (subpath->isClosed()) { + LOG (printf ("close\n")); + cairo_close_path (cairo); + } + } + } +} + +void CairoOutputDev::stroke(GfxState *state) { + doPath (state, state->getPath()); + cairo_set_source (cairo, stroke_pattern); + LOG(printf ("stroke\n")); + cairo_stroke (cairo); +} + +void CairoOutputDev::fill(GfxState *state) { + doPath (state, state->getPath()); + cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING); + cairo_set_source (cairo, fill_pattern); + LOG(printf ("fill\n")); + cairo_fill (cairo); +} + +void CairoOutputDev::eoFill(GfxState *state) { + doPath (state, state->getPath()); + cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD); + cairo_set_source (cairo, fill_pattern); + LOG(printf ("fill-eo\n")); + cairo_fill (cairo); +} + +void CairoOutputDev::clip(GfxState *state) { + doPath (state, state->getPath()); + cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING); + cairo_clip (cairo); + LOG (printf ("clip\n")); +} + +void CairoOutputDev::eoClip(GfxState *state) { + doPath (state, state->getPath()); + cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD); + cairo_clip (cairo); + LOG (printf ("clip-eo\n")); +} + +void CairoOutputDev::beginString(GfxState *state, GooString *s) +{ + int len = s->getLength(); + + if (needFontUpdate) + updateFont(state); + + glyphs = (cairo_glyph_t *) gmalloc (len * sizeof (cairo_glyph_t)); + glyphCount = 0; +} + +void CairoOutputDev::drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, Unicode *u, int uLen) +{ + if (!currentFont) + return; + + glyphs[glyphCount].index = currentFont->getGlyph (code, u, uLen); + glyphs[glyphCount].x = x - originX; + glyphs[glyphCount].y = y - originY; + glyphCount++; +} + +void CairoOutputDev::endString(GfxState *state) +{ + int render; + + if (!currentFont) + return; + + // endString can be called without a corresponding beginString. If this + // happens glyphs will be null so don't draw anything, just return. + // XXX: OutputDevs should probably not have to deal with this... + if (!glyphs) + return; + + // ignore empty strings and invisible text -- this is used by + // Acrobat Capture + render = state->getRender(); + if (render == 3 || glyphCount == 0) { + gfree(glyphs); + glyphs = NULL; + return; + } + + if (!(render & 1)) { + LOG (printf ("fill string\n")); + cairo_set_source (cairo, fill_pattern); + cairo_show_glyphs (cairo, glyphs, glyphCount); + } + + // stroke + if ((render & 3) == 1 || (render & 3) == 2) { + LOG (printf ("stroke string\n")); + cairo_set_source (cairo, stroke_pattern); + cairo_glyph_path (cairo, glyphs, glyphCount); + cairo_stroke (cairo); + } + + // clip + if (render & 4) { + LOG (printf ("clip string\n")); + // append the glyph path to textClipPath. + + // set textClipPath as the currentPath + if (textClipPath) { + cairo_append_path (cairo, textClipPath); + cairo_path_destroy (textClipPath); + } + + // append the glyph path + cairo_glyph_path (cairo, glyphs, glyphCount); + + // move the path back into textClipPath + // and clear the current path + textClipPath = cairo_copy_path (cairo); + cairo_new_path (cairo); + } + + gfree (glyphs); + glyphs = NULL; +} + +GBool CairoOutputDev::beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen) { + + cairo_save (cairo); + double *ctm; + cairo_matrix_t matrix; + + ctm = state->getCTM(); + matrix.xx = ctm[0]; + matrix.yx = ctm[1]; + matrix.xy = ctm[2]; + matrix.yy = ctm[3]; + matrix.x0 = ctm[4]; + matrix.y0 = ctm[5]; + cairo_set_matrix(cairo, &matrix); + return gFalse; +} + +void CairoOutputDev::endType3Char(GfxState *state) { + cairo_restore (cairo); +} + +void CairoOutputDev::type3D0(GfxState *state, double wx, double wy) { +} + +void CairoOutputDev::type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury) { +} + +void CairoOutputDev::endTextObject(GfxState *state) { + if (textClipPath) { + // clip the accumulated text path + cairo_append_path (cairo, textClipPath); + cairo_clip (cairo); + cairo_path_destroy (textClipPath); + textClipPath = NULL; + } + +} + + +void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + unsigned char *buffer; + unsigned char *dest; + cairo_surface_t *image; + cairo_pattern_t *pattern; + int x, y; + ImageStream *imgStr; + Guchar *pix; + cairo_matrix_t matrix; + int invert_bit; + int row_stride; + + /* FIXME: Doesn't the image mask support any colorspace? */ + cairo_set_source (cairo, fill_pattern); + + /* work around a cairo bug when scaling 1x1 surfaces */ + if (width == 1 && height == 1) { + cairo_save (cairo); + cairo_rectangle (cairo, 0., 0., width, height); + cairo_fill (cairo); + cairo_restore (cairo); + return; + } + + row_stride = (width + 3) & ~3; + buffer = (unsigned char *) malloc (height * row_stride); + if (buffer == NULL) { + error(-1, "Unable to allocate memory for image."); + return; + } + + /* TODO: Do we want to cache these? */ + imgStr = new ImageStream(str, width, 1, 1); + imgStr->reset(); + + invert_bit = invert ? 1 : 0; + + for (y = 0; y < height; y++) { + pix = imgStr->getLine(); + dest = buffer + y * row_stride; + for (x = 0; x < width; x++) { + + if (pix[x] ^ invert_bit) + *dest++ = 0; + else + *dest++ = 255; + } + } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8, + width, height, row_stride); + if (image == NULL) { + delete imgStr; + return; + } + pattern = cairo_pattern_create_for_surface (image); + if (pattern == NULL) { + delete imgStr; + return; + } + + cairo_matrix_init_translate (&matrix, 0, height); + cairo_matrix_scale (&matrix, width, -height); + + cairo_pattern_set_matrix (pattern, &matrix); + + /* we should actually be using CAIRO_FILTER_NEAREST here. However, + * cairo doesn't yet do minifaction filtering causing scaled down + * images with CAIRO_FILTER_NEAREST to look really bad */ + cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST); + + cairo_mask (cairo, pattern); + + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + free (buffer); + delete imgStr; +} + +void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref, + Stream *str, int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, int maskWidth, + int maskHeight, GBool maskInvert) +{ + ImageStream *maskImgStr; + maskImgStr = new ImageStream(maskStr, maskWidth, 1, 1); + maskImgStr->reset(); + + int row_stride = (maskWidth + 3) & ~3; + unsigned char *maskBuffer; + maskBuffer = (unsigned char *)gmalloc (row_stride * maskHeight); + unsigned char *maskDest; + cairo_surface_t *maskImage; + cairo_pattern_t *maskPattern; + Guchar *pix; + int x, y; + + int invert_bit; + + invert_bit = maskInvert ? 1 : 0; + + for (y = 0; y < height; y++) { + pix = maskImgStr->getLine(); + maskDest = maskBuffer + y * row_stride; + for (x = 0; x < width; x++) { + if (pix[x] ^ invert_bit) + *maskDest++ = 0; + else + *maskDest++ = 255; + } + } + + maskImage = cairo_image_surface_create_for_data (maskBuffer, CAIRO_FORMAT_A8, + maskWidth, maskHeight, row_stride); + + delete maskImgStr; + maskStr->close(); + + unsigned char *buffer; + unsigned int *dest; + cairo_surface_t *image; + cairo_pattern_t *pattern; + ImageStream *imgStr; + GfxRGB rgb; + int alpha, i; + cairo_matrix_t matrix; + int is_identity_transform; + + buffer = (unsigned char *)gmalloc (width * height * 4); + + /* TODO: Do we want to cache these? */ + imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + /* ICCBased color space doesn't do any color correction + * so check its underlying color space as well */ + is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csICCBased && + ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB; + + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_RGB24, + width, height, width * 4); + + if (image == NULL) { + delete imgStr; + return; + } + pattern = cairo_pattern_create_for_surface (image); + maskPattern = cairo_pattern_create_for_surface (maskImage); + if (pattern == NULL) { + delete imgStr; + return; + } + + LOG (printf ("drawMaskedImage %dx%d\n", width, height)); + + cairo_matrix_init_translate (&matrix, 0, height); + cairo_matrix_scale (&matrix, width, -height); + + /* scale the mask to the size of the image unlike softMask */ + cairo_pattern_set_matrix (pattern, &matrix); + cairo_pattern_set_matrix (maskPattern, &matrix); + + cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR); + cairo_set_source (cairo, pattern); + cairo_mask (cairo, maskPattern); + + cairo_pattern_destroy (maskPattern); + cairo_surface_destroy (maskImage); + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + free (buffer); + free (maskBuffer); + delete imgStr; +} + +void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap) +{ + ImageStream *maskImgStr; + maskImgStr = new ImageStream(maskStr, maskWidth, + maskColorMap->getNumPixelComps(), + maskColorMap->getBits()); + maskImgStr->reset(); + + int row_stride = (maskWidth + 3) & ~3; + unsigned char *maskBuffer; + maskBuffer = (unsigned char *)gmalloc (row_stride * maskHeight); + unsigned char *maskDest; + cairo_surface_t *maskImage; + cairo_pattern_t *maskPattern; + Guchar *pix; + int x, y; + for (y = 0; y < maskHeight; y++) { + maskDest = (unsigned char *) (maskBuffer + y * row_stride); + pix = maskImgStr->getLine(); + maskColorMap->getGrayLine (pix, maskDest, maskWidth); + } + + maskImage = cairo_image_surface_create_for_data (maskBuffer, CAIRO_FORMAT_A8, + maskWidth, maskHeight, row_stride); + + delete maskImgStr; + maskStr->close(); + + unsigned char *buffer; + unsigned int *dest; + cairo_surface_t *image; + cairo_pattern_t *pattern; + ImageStream *imgStr; + GfxRGB rgb; + int alpha, i; + cairo_matrix_t matrix; + cairo_matrix_t maskMatrix; + int is_identity_transform; + + buffer = (unsigned char *)gmalloc (width * height * 4); + + /* TODO: Do we want to cache these? */ + imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + /* ICCBased color space doesn't do any color correction + * so check its underlying color space as well */ + is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csICCBased && + ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB; + + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_RGB24, + width, height, width * 4); + + if (image == NULL) { + delete imgStr; + return; + } + pattern = cairo_pattern_create_for_surface (image); + maskPattern = cairo_pattern_create_for_surface (maskImage); + if (pattern == NULL) { + delete imgStr; + return; + } + + LOG (printf ("drawSoftMaskedImage %dx%d\n", width, height)); + + cairo_matrix_init_translate (&matrix, 0, height); + cairo_matrix_scale (&matrix, width, -height); + + cairo_matrix_init_translate (&maskMatrix, 0, maskHeight); + cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight); + + cairo_pattern_set_matrix (pattern, &matrix); + cairo_pattern_set_matrix (maskPattern, &maskMatrix); + + cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR); + cairo_set_source (cairo, pattern); + cairo_mask (cairo, maskPattern); + + cairo_pattern_destroy (maskPattern); + cairo_surface_destroy (maskImage); + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + free (buffer); + free (maskBuffer); + delete imgStr; +} +void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) +{ + unsigned char *buffer; + unsigned int *dest; + cairo_surface_t *image; + cairo_pattern_t *pattern; + int x, y; + ImageStream *imgStr; + Guchar *pix; + GfxRGB rgb; + int alpha, i; + cairo_matrix_t matrix; + int is_identity_transform; + + buffer = (unsigned char *)gmalloc (width * height * 4); + + /* TODO: Do we want to cache these? */ + imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + /* ICCBased color space doesn't do any color correction + * so check its underlying color space as well */ + is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csICCBased && + ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB; + + if (maskColors) { + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + + for (x = 0; x < width; x++) { + for (i = 0; i < colorMap->getNumPixelComps(); ++i) { + + if (pix[i] < maskColors[2*i] * 255|| + pix[i] > maskColors[2*i+1] * 255) { + *dest = *dest | 0xff000000; + break; + } + } + pix += colorMap->getNumPixelComps(); + dest++; + } + } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_ARGB32, + width, height, width * 4); + } + else { + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_RGB24, + width, height, width * 4); + } + + if (image == NULL) { + delete imgStr; + return; + } + pattern = cairo_pattern_create_for_surface (image); + if (pattern == NULL) { + delete imgStr; + return; + } + + LOG (printf ("drawImageMask %dx%d\n", width, height)); + + cairo_matrix_init_translate (&matrix, 0, height); + cairo_matrix_scale (&matrix, width, -height); + + cairo_pattern_set_matrix (pattern, &matrix); + + cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR); + cairo_set_source (cairo, pattern); + cairo_paint (cairo); + + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + free (buffer); + delete imgStr; +} diff --git a/rosapps/smartpdf/poppler/poppler/CairoOutputDev.h b/rosapps/smartpdf/poppler/poppler/CairoOutputDev.h new file mode 100644 index 00000000000..f91a20f61f2 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CairoOutputDev.h @@ -0,0 +1,171 @@ +//======================================================================== +// +// CairoOutputDev.h +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, INC +// +//======================================================================== + +#ifndef CAIROOUTPUTDEV_H +#define CAIROOUTPUTDEV_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include +#include "OutputDev.h" +#include "GfxState.h" + +class GfxState; +class GfxPath; +class Gfx8BitFont; +struct GfxRGB; +class CairoFontEngine; +class CairoFont; + +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +// CairoOutputDev +//------------------------------------------------------------------------ + +class CairoOutputDev: public OutputDev { +public: + + // Constructor. + CairoOutputDev(); + + // Destructor. + virtual ~CairoOutputDev(); + + //----- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gTrue; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gTrue; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() { return gTrue; } + + //----- initialization and control + + // Start a page. + virtual void startPage(int pageNum, GfxState *state) { } + + // End a page. + virtual void endPage() { } + + //----- link borders + virtual void drawLink(Link *link, Catalog *catalog); + + //----- save/restore graphics state + virtual void saveState(GfxState *state); + virtual void restoreState(GfxState *state); + + //----- update graphics state + virtual void updateAll(GfxState *state); + virtual void setDefaultCTM(double *ctm); + virtual void updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32); + virtual void updateLineDash(GfxState *state); + virtual void updateFlatness(GfxState *state); + virtual void updateLineJoin(GfxState *state); + virtual void updateLineCap(GfxState *state); + virtual void updateMiterLimit(GfxState *state); + virtual void updateLineWidth(GfxState *state); + virtual void updateFillColor(GfxState *state); + virtual void updateStrokeColor(GfxState *state); + virtual void updateFillOpacity(GfxState *state); + virtual void updateStrokeOpacity(GfxState *state); + + //----- update text state + virtual void updateFont(GfxState *state); + + //----- path painting + virtual void stroke(GfxState *state); + virtual void fill(GfxState *state); + virtual void eoFill(GfxState *state); + + //----- path clipping + virtual void clip(GfxState *state); + virtual void eoClip(GfxState *state); + + //----- text drawing + void beginString(GfxState *state, GooString *s); + void endString(GfxState *state); + void drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, Unicode *u, int uLen); + + virtual GBool beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen); + virtual void endType3Char(GfxState *state); + virtual void endTextObject(GfxState *state); + + //----- image drawing + virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg); + virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap); + + virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GBool maskInvert); + + + //----- Type 3 font operators + virtual void type3D0(GfxState *state, double wx, double wy); + virtual void type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury); + + //----- special access + + // Called to indicate that a new PDF document has been loaded. + void startDoc(XRef *xrefA); + + GBool isReverseVideo() { return gFalse; } + + void setCairo (cairo_t *cr); + +protected: + void doPath(GfxState *state, GfxPath *path); + + GfxRGB fill_color, stroke_color; + cairo_pattern_t *fill_pattern, *stroke_pattern; + double fill_opacity; + double stroke_opacity; + CairoFont *currentFont; + + XRef *xref; // xref table for current document + + FT_Library ft_lib; + CairoFontEngine *fontEngine; + cairo_t *cairo; + GBool needFontUpdate; // set when the font needs to be updated + cairo_surface_t *surface; + cairo_glyph_t *glyphs; + int glyphCount; + cairo_path_t *textClipPath; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Catalog.cc b/rosapps/smartpdf/poppler/poppler/Catalog.cc new file mode 100644 index 00000000000..8ffba654ee0 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Catalog.cc @@ -0,0 +1,617 @@ +//======================================================================== +// +// Catalog.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "Object.h" +#include "XRef.h" +#include "Array.h" +#include "Dict.h" +#include "Page.h" +#include "Error.h" +#include "Link.h" +#include "PageLabelInfo.h" +#include "UGooString.h" +#include "Catalog.h" + +// This define is used to limit the depth of recursive readPageTree calls +// This is needed because the page tree nodes can reference their parents +// leaving us in an infinite loop +// Most sane pdf documents don't have a call depth higher than 10 +#define MAX_CALL_DEPTH 1000 + +//------------------------------------------------------------------------ +// Catalog +//------------------------------------------------------------------------ + +Catalog::Catalog(XRef *xrefA) { + Object catDict, pagesDict; + Object obj, obj2; + int numPages0; + int i; + + ok = gTrue; + xref = xrefA; + pages = NULL; + pageRefs = NULL; + numPages = pagesSize = 0; + baseURI = NULL; + pageLabelInfo = NULL; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + goto err1; + } + + // read page tree + catDict.dictLookup("Pages", &pagesDict); + // This should really be isDict("Pages"), but I've seen at least one + // PDF file where the /Type entry is missing. + if (!pagesDict.isDict()) { + error(-1, "Top-level pages object is wrong type (%s)", + pagesDict.getTypeName()); + goto err2; + } + pagesDict.dictLookup("Count", &obj); + // some PDF files actually use real numbers here ("/Count 9.0") + if (!obj.isNum()) { + error(-1, "Page count in top-level pages object is wrong type (%s)", + obj.getTypeName()); + goto err3; + } + pagesSize = numPages0 = (int)obj.getNum(); + obj.free(); + pages = (Page **)gmallocn(pagesSize, sizeof(Page *)); + pageRefs = (Ref *)gmallocn(pagesSize, sizeof(Ref)); + for (i = 0; i < pagesSize; ++i) { + pages[i] = NULL; + pageRefs[i].num = -1; + pageRefs[i].gen = -1; + } + numPages = readPageTree(pagesDict.getDict(), NULL, 0, 0); + if (numPages != numPages0) { + error(-1, "Page count in top-level pages object is incorrect"); + } + pagesDict.free(); + + // read named destination dictionary + catDict.dictLookup("Dests", &dests); + + // read root of named destination tree - PDF1.6 table 3.28 + if (catDict.dictLookup("Names", &obj)->isDict()) { + obj.dictLookup("Dests", &obj2); + destNameTree.init(xref, &obj2); + obj2.free(); + obj.dictLookup("EmbeddedFiles", &obj2); + embeddedFileNameTree.init(xref, &obj2); + obj2.free(); + } + obj.free(); + + if (catDict.dictLookup("PageLabels", &obj)->isDict()) + pageLabelInfo = new PageLabelInfo(&obj, numPages); + obj.free(); + + // read page mode + pageMode = pageModeNone; + if (catDict.dictLookup("PageMode", &obj)->isName()) { + if (obj.isName("UseNone")) + pageMode = pageModeNone; + else if (obj.isName("UseOutlines")) + pageMode = pageModeOutlines; + else if (obj.isName("UseThumbs")) + pageMode = pageModeThumbs; + else if (obj.isName("FullScreen")) + pageMode = pageModeFullScreen; + else if (obj.isName("UseOC")) + pageMode = pageModeOC; + else if (obj.isName("UseAttachments")) + pageMode = pageModeAttach; + } + obj.free(); + + pageLayout = pageLayoutNone; + if (catDict.dictLookup("PageLayout", &obj)->isName()) { + if (obj.isName("SinglePage")) + pageLayout = pageLayoutSinglePage; + if (obj.isName("OneColumn")) + pageLayout = pageLayoutOneColumn; + if (obj.isName("TwoColumnLeft")) + pageLayout = pageLayoutTwoColumnLeft; + if (obj.isName("TwoColumnRight")) + pageLayout = pageLayoutTwoColumnRight; + if (obj.isName("TwoPageLeft")) + pageLayout = pageLayoutTwoPageLeft; + if (obj.isName("TwoPageRight")) + pageLayout = pageLayoutTwoPageRight; + } + obj.free(); + + // read base URI + if (catDict.dictLookup("URI", &obj)->isDict()) { + if (obj.dictLookup("Base", &obj2)->isString()) { + baseURI = obj2.getString()->copy(); + } + obj2.free(); + } + obj.free(); + + // get the metadata stream + catDict.dictLookup("Metadata", &metadata); + + // get the structure tree root + catDict.dictLookup("StructTreeRoot", &structTreeRoot); + + // get the outline dictionary + catDict.dictLookup("Outlines", &outline); + + // get the AcroForm dictionary + catDict.dictLookup("AcroForm", &acroForm); + + catDict.free(); + return; + + err3: + obj.free(); + err2: + pagesDict.free(); + err1: + catDict.free(); + dests.initNull(); + ok = gFalse; +} + +Catalog::~Catalog() { + int i; + + if (pages) { + for (i = 0; i < pagesSize; ++i) { + if (pages[i]) { + delete pages[i]; + } + } + gfree(pages); + gfree(pageRefs); + } + dests.free(); + destNameTree.free(); + embeddedFileNameTree.free(); + if (baseURI) { + delete baseURI; + } + delete pageLabelInfo; + metadata.free(); + structTreeRoot.free(); + outline.free(); + acroForm.free(); +} + +GooString *Catalog::readMetadata() { + GooString *s; + Dict *dict; + Object obj; + int c; + + if (!metadata.isStream()) { + return NULL; + } + dict = metadata.streamGetDict(); + if (!dict->lookup("Subtype", &obj)->isName("XML")) { + error(-1, "Unknown Metadata type: '%s'", + obj.isName() ? obj.getNameC() : "???"); + } + obj.free(); + s = new GooString(); + metadata.streamReset(); + while ((c = metadata.streamGetChar()) != EOF) { + s->append(c); + } + metadata.streamClose(); + return s; +} + +int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, int callDepth) { + Object kids; + Object kid; + Object kidRef; + PageAttrs *attrs1, *attrs2; + Page *page; + int i, j; + + attrs1 = new PageAttrs(attrs, pagesDict); + pagesDict->lookup("Kids", &kids); + if (!kids.isArray()) { + error(-1, "Kids object (page %d) is wrong type (%s)", + start+1, kids.getTypeName()); + goto err1; + } + for (i = 0; i < kids.arrayGetLength(); ++i) { + kids.arrayGet(i, &kid); + if (kid.isDict("Page")) { + attrs2 = new PageAttrs(attrs1, kid.getDict()); + page = new Page(xref, start+1, kid.getDict(), attrs2); + if (!page->isOk()) { + ++start; + goto err3; + } + if (start >= pagesSize) { + pagesSize += 32; + pages = (Page **)greallocn(pages, pagesSize, sizeof(Page *)); + pageRefs = (Ref *)greallocn(pageRefs, pagesSize, sizeof(Ref)); + for (j = pagesSize - 32; j < pagesSize; ++j) { + pages[j] = NULL; + pageRefs[j].num = -1; + pageRefs[j].gen = -1; + } + } + pages[start] = page; + kids.arrayGetNF(i, &kidRef); + if (kidRef.isRef()) { + pageRefs[start].num = kidRef.getRefNum(); + pageRefs[start].gen = kidRef.getRefGen(); + } + kidRef.free(); + ++start; + // This should really be isDict("Pages"), but I've seen at least one + // PDF file where the /Type entry is missing. + } else if (kid.isDict()) { + if (callDepth > MAX_CALL_DEPTH) { + error(-1, "Limit of %d recursive calls reached while reading the page tree. If your document is correct and not a test to try to force a crash, please report a bug.", MAX_CALL_DEPTH); + } else { + if ((start = readPageTree(kid.getDict(), attrs1, start, callDepth + 1)) + < 0) + goto err2; + } + } else { + error(-1, "Kid object (page %d) is wrong type (%s)", + start+1, kid.getTypeName()); + } + kid.free(); + } + delete attrs1; + kids.free(); + return start; + + err3: + delete page; + err2: + kid.free(); + err1: + kids.free(); + delete attrs1; + ok = gFalse; + return -1; +} + +int Catalog::findPage(int num, int gen) { + int i; + + for (i = 0; i < numPages; ++i) { + if (pageRefs[i].num == num && pageRefs[i].gen == gen) + return i + 1; + } + return 0; +} + +LinkDest *Catalog::findDest(UGooString *name) { + LinkDest *dest; + Object obj1, obj2; + GBool found; + + // try named destination dictionary then name tree + found = gFalse; + if (dests.isDict()) { + if (!dests.dictLookup(*name, &obj1)->isNull()) + found = gTrue; + else + obj1.free(); + } + if (!found) { + if (destNameTree.lookup(name, &obj1)) + found = gTrue; + else + obj1.free(); + } + if (!found) + return NULL; + + // construct LinkDest + dest = NULL; + if (obj1.isArray()) { + dest = new LinkDest(obj1.getArray()); + } else if (obj1.isDict()) { + if (obj1.dictLookup("D", &obj2)->isArray()) + dest = new LinkDest(obj2.getArray()); + else + error(-1, "Bad named destination value"); + obj2.free(); + } else { + error(-1, "Bad named destination value"); + } + obj1.free(); + if (dest && !dest->isOk()) { + delete dest; + dest = NULL; + } + + return dest; +} + +EmbFile *Catalog::embeddedFile(int i) +{ + Object efDict; + Object fileSpec; + Object fileDesc; + Object paramDict; + Object paramObj; + Object strObj; + Object obj, obj2; + obj = embeddedFileNameTree.getValue(i); + GooString *fileName = new GooString(); + char *descString = embeddedFileNameTree.getName(i)->getCStringCopy(); + GooString *desc = new GooString(descString); + delete[] descString; + GooString *createDate = new GooString(); + GooString *modDate = new GooString(); + Stream *efStream = NULL; + if (obj.isRef()) { + if (obj.fetch(xref, &efDict)->isDict()) { + // efDict matches Table 3.40 in the PDF1.6 spec + efDict.dictLookup("F", &fileSpec); + if (fileSpec.isString()) { + delete fileName; + fileName = new GooString(fileSpec.getString()); + } + fileSpec.free(); + + // the logic here is that the description from the name + // dictionary is used if we don't have a more specific + // description - see the Note: on page 157 of the PDF1.6 spec + efDict.dictLookup("Desc", &fileDesc); + if (fileDesc.isString()) { + delete desc; + desc = new GooString(fileDesc.getString()); + } else { + efDict.dictLookup("Description", &fileDesc); + if (fileDesc.isString()) { + delete desc; + desc = new GooString(fileDesc.getString()); + } + } + fileDesc.free(); + + efDict.dictLookup("EF", &obj2); + if (obj2.isDict()) { + // This gives us the raw data stream bytes + + obj2.dictLookup("F", &strObj); + if (strObj.isStream()) { + efStream = strObj.getStream(); + } + + if (!efStream) { + delete desc; + delete modDate; + delete createDate; + delete fileName; + return NULL; + } + + // dataDict corresponds to Table 3.41 in the PDF1.6 spec. + Dict *dataDict = efStream->getDict(); + + // subtype is normally mimetype. You can extract it with code like this: + // Object subtypeName; + // dataDict->lookup( "Subtype", &subtypeName ); + // It is optional, so this will sometimes return a null object + // if (subtypeName.isName()) { + // std::cout << "got subtype name: " << subtypeName.getName() << std::endl; + // } + + // paramDict corresponds to Table 3.42 in the PDF1.6 spec + Object paramDict; + dataDict->lookup( "Params", ¶mDict ); + if (paramDict.isDict()) { + paramDict.dictLookup("ModDate", ¶mObj); + if (paramObj.isString()) { + delete modDate; + modDate = new GooString(paramObj.getString()); + } + paramObj.free(); + paramDict.dictLookup("CreationDate", ¶mObj); + if (paramObj.isString()) { + delete createDate; + createDate = new GooString(paramObj.getString()); + } + paramObj.free(); + } + paramDict.free(); + } + efDict.free(); + obj2.free(); + } + } + EmbFile *embeddedFile = new EmbFile(fileName, desc, createDate, modDate, strObj); + strObj.free(); + return embeddedFile; +} + +NameTree::NameTree(void) +{ + size = 0; + length = 0; + entries = NULL; +} + +NameTree::Entry::Entry(Array *array, int index) { + GooString n; + if (!array->getString(index, &n) || !array->getNF(index + 1, &value)) { + Object aux; + array->get(index, &aux); + if (aux.isString() && array->getNF(index + 1, &value) ) + { + n.append(aux.getString()); + } + else + error(-1, "Invalid page tree"); + } + name = new UGooString(n); +} + +NameTree::Entry::~Entry() { + value.free(); + delete name; +} + +void NameTree::addEntry(Entry *entry) +{ + if (length == size) { + if (length == 0) { + size = 8; + } else { + size *= 2; + } + entries = (Entry **) grealloc (entries, sizeof (Entry *) * size); + } + + entries[length] = entry; + ++length; +} + +void NameTree::init(XRef *xrefA, Object *tree) { + xref = xrefA; + parse(tree); +} + +void NameTree::parse(Object *tree) { + Object names; + Object kids, kid; + int i; + + if (!tree->isDict()) + return; + + // leaf node + if (tree->dictLookup("Names", &names)->isArray()) { + for (i = 0; i < names.arrayGetLength(); i += 2) { + NameTree::Entry *entry; + + entry = new Entry(names.getArray(), i); + addEntry(entry); + } + } + names.free(); + + // root or intermediate node + if (tree->dictLookup("Kids", &kids)->isArray()) { + for (i = 0; i < kids.arrayGetLength(); ++i) { + if (kids.arrayGet(i, &kid)->isDict()) + parse(&kid); + kid.free(); + } + } + kids.free(); +} + +int NameTree::Entry::cmp(const void *voidKey, const void *voidEntry) +{ + UGooString *key = (UGooString *) voidKey; + Entry *entry = *(NameTree::Entry **) voidEntry; + + return key->cmp(entry->name); +} + +GBool NameTree::lookup(UGooString *name, Object *obj) +{ + Entry **entry; + char *cname; + + entry = (Entry **) bsearch(name, entries, + length, sizeof(Entry *), Entry::cmp); + if (entry != NULL) { + (*entry)->value.fetch(xref, obj); + return gTrue; + } else { + cname = name->getCStringCopy(); + printf("failed to look up %s\n", cname); + delete[] cname; + obj->initNull(); + return gFalse; + } +} + +Object NameTree::getValue(int index) +{ + if (index < length) { + return entries[index]->value; + } else { + return Object(); + } +} + +UGooString *NameTree::getName(int index) +{ + if (index < length) { + return entries[index]->name; + } else { + return NULL; + } +} + +void NameTree::free() +{ + int i; + + for (i = 0; i < length; i++) + delete entries[i]; + + gfree(entries); +} + +GBool Catalog::labelToIndex(GooString *label, int *index) +{ + char *end; + + if (pageLabelInfo != NULL) { + if (!pageLabelInfo->labelToIndex(label, index)) + return gFalse; + } else { + *index = strtol(label->getCString(), &end, 10) - 1; + if (*end != '\0') + return gFalse; + } + + if (*index < 0 || *index >= numPages) + return gFalse; + + return gTrue; +} + +GBool Catalog::indexToLabel(int index, GooString *label) +{ + char buffer[32]; + + if (index < 0 || index >= numPages) + return gFalse; + + if (pageLabelInfo != NULL) { + return pageLabelInfo->indexToLabel(index, label); + } else { + snprintf(buffer, sizeof (buffer), "%d", index + 1); + label->append(buffer); + return gTrue; + } +} diff --git a/rosapps/smartpdf/poppler/poppler/Catalog.h b/rosapps/smartpdf/poppler/poppler/Catalog.h new file mode 100644 index 00000000000..0800bd9388c --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Catalog.h @@ -0,0 +1,200 @@ +//======================================================================== +// +// Catalog.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef CATALOG_H +#define CATALOG_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +class XRef; +class Object; +class Page; +class PageAttrs; +struct Ref; +class LinkDest; +class UGooString; +class PageLabelInfo; + +//------------------------------------------------------------------------ +// NameTree +//------------------------------------------------------------------------ + +class NameTree { +public: + NameTree(); + void init(XRef *xref, Object *tree); + void parse(Object *tree); + GBool lookup(UGooString *name, Object *obj); + void free(); + int numEntries() { return length; }; + // iterator accessor + Object getValue(int i); + UGooString *getName(int i); + +private: + struct Entry { + Entry(Array *array, int index); + ~Entry(); + UGooString *name; + Object value; + void free(); + static int cmp(const void *key, const void *entry); + }; + + void addEntry(Entry *entry); + + XRef *xref; + Object *root; + Entry **entries; + int size, length; // size is the number of entries in + // the array of Entry* + // length is the number of real Entry +}; + +class EmbFile { +public: + EmbFile(GooString *name, GooString *description, + GooString *createDate, + GooString *modDate, Object objStr) : + m_name(name), + m_description(description), + m_createDate(createDate), + m_modDate(modDate) + { + objStr.copy(&m_objStr); + } + + ~EmbFile() + { + delete m_name; + delete m_description; + delete m_modDate; + delete m_createDate; + m_objStr.free(); + } + + GooString *name() { return m_name; } + GooString *description() { return m_description; } + GooString *modDate() { return m_modDate; } + GooString *createDate() { return m_createDate; } + Object &streamObject() { return m_objStr; } + +private: + GooString *m_name; + GooString *m_description; + GooString *m_createDate; + GooString *m_modDate; + Object m_objStr; +}; + +//------------------------------------------------------------------------ +// Catalog +//------------------------------------------------------------------------ + +class Catalog { +public: + + // Constructor. + Catalog(XRef *xrefA); + + // Destructor. + ~Catalog(); + + // Is catalog valid? + GBool isOk() { return ok; } + + // Get number of pages. + int getNumPages() { return numPages; } + + // Get a page. + Page *getPage(int i) { return pages[i-1]; } + + // Get the reference for a page object. + Ref *getPageRef(int i) { return &pageRefs[i-1]; } + + // Return base URI, or NULL if none. + GooString *getBaseURI() { return baseURI; } + + // Return the contents of the metadata stream, or NULL if there is + // no metadata. + GooString *readMetadata(); + + // Return the structure tree root object. + Object *getStructTreeRoot() { return &structTreeRoot; } + + // Find a page, given its object ID. Returns page number, or 0 if + // not found. + int findPage(int num, int gen); + + // Find a named destination. Returns the link destination, or + // NULL if is not a destination. + LinkDest *findDest(UGooString *name); + + // Get the number of embedded files + int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); } + + // Get the i'th file embedded (at the Document level) in the document + EmbFile *embeddedFile(int i); + + // Convert between page indices and page labels. + GBool labelToIndex(GooString *label, int *index); + GBool indexToLabel(int index, GooString *label); + + Object *getOutline() { return &outline; } + + Object *getAcroForm() { return &acroForm; } + + enum PageMode { + pageModeNone, + pageModeOutlines, + pageModeThumbs, + pageModeFullScreen, + pageModeOC, + pageModeAttach + }; + enum PageLayout { + pageLayoutNone, + pageLayoutSinglePage, + pageLayoutOneColumn, + pageLayoutTwoColumnLeft, + pageLayoutTwoColumnRight, + pageLayoutTwoPageLeft, + pageLayoutTwoPageRight + }; + + // Returns the page mode. + PageMode getPageMode() { return pageMode; } + PageLayout getPageLayout() { return pageLayout; } + +private: + + XRef *xref; // the xref table for this PDF file + Page **pages; // array of pages + Ref *pageRefs; // object ID for each page + int numPages; // number of pages + int pagesSize; // size of pages array + Object dests; // named destination dictionary + NameTree destNameTree; // named destination name-tree + NameTree embeddedFileNameTree; // embedded file name-tree + GooString *baseURI; // base URI for URI-type links + Object metadata; // metadata stream + Object structTreeRoot; // structure tree root dictionary + Object outline; // outline dictionary + Object acroForm; // AcroForm dictionary + GBool ok; // true if catalog is valid + PageLabelInfo *pageLabelInfo; // info about page labels + PageMode pageMode; // page mode + PageLayout pageLayout; // page layout + + int readPageTree(Dict *pages, PageAttrs *attrs, int start, int callDepth); + Object *findDestInTree(Object *tree, GooString *name, Object *obj); +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.cc b/rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.cc new file mode 100644 index 00000000000..40abf0aa91c --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.cc @@ -0,0 +1,563 @@ +//======================================================================== +// +// CharCodeToUnicode.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "goo/gfile.h" +#include "goo/GooString.h" +#include "Error.h" +#include "GlobalParams.h" +#include "PSTokenizer.h" +#include "CharCodeToUnicode.h" + +//------------------------------------------------------------------------ + +#define maxUnicodeString 8 + +struct CharCodeToUnicodeString { + CharCode c; + Unicode u[maxUnicodeString]; + int len; +}; + +//------------------------------------------------------------------------ + +static int getCharFromString(void *data) { + char *p; + int c; + + p = *(char **)data; + if (*p) { + c = *p++; + *(char **)data = p; + } else { + c = EOF; + } + return c; +} + +static int getCharFromFile(void *data) { + return fgetc((FILE *)data); +} + +//------------------------------------------------------------------------ + +CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName, + GooString *collection) { + FILE *f; + Unicode *mapA; + CharCode size, mapLenA; + char buf[64]; + Unicode u; + CharCodeToUnicode *ctu; + + if (!(f = fopen(fileName->getCString(), "r"))) { + error(-1, "Couldn't open cidToUnicode file '%s'", + fileName->getCString()); + return NULL; + } + + size = 32768; + mapA = (Unicode *)gmallocn(size, sizeof(Unicode)); + mapLenA = 0; + + while (getLine(buf, sizeof(buf), f)) { + if (mapLenA == size) { + size *= 2; + mapA = (Unicode *)greallocn(mapA, size, sizeof(Unicode)); + } + if (sscanf(buf, "%x", &u) == 1) { + mapA[mapLenA] = u; + } else { + error(-1, "Bad line (%d) in cidToUnicode file '%s'", + (int)(mapLenA + 1), fileName->getCString()); + mapA[mapLenA] = 0; + } + ++mapLenA; + } + fclose(f); + + ctu = new CharCodeToUnicode(collection->copy(), mapA, mapLenA, gTrue, + NULL, 0, 0); + gfree(mapA); + return ctu; +} + +CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode( + GooString *fileName) { + FILE *f; + Unicode *mapA; + CharCodeToUnicodeString *sMapA; + CharCode size, oldSize, len, sMapSizeA, sMapLenA; + char buf[256]; + char *tok; + Unicode u0; + Unicode uBuf[maxUnicodeString]; + CharCodeToUnicode *ctu; + int line, n, i; + + if (!(f = fopen(fileName->getCString(), "r"))) { + error(-1, "Couldn't open unicodeToUnicode file '%s'", + fileName->getCString()); + return NULL; + } + + size = 4096; + mapA = (Unicode *)gmallocn(size, sizeof(Unicode)); + memset(mapA, 0, size * sizeof(Unicode)); + len = 0; + sMapA = NULL; + sMapSizeA = sMapLenA = 0; + + line = 0; + while (getLine(buf, sizeof(buf), f)) { + ++line; + if (!(tok = strtok(buf, " \t\r\n")) || + sscanf(tok, "%x", &u0) != 1) { + error(-1, "Bad line (%d) in unicodeToUnicode file '%s'", + line, fileName->getCString()); + continue; + } + n = 0; + while (n < maxUnicodeString) { + if (!(tok = strtok(NULL, " \t\r\n"))) { + break; + } + if (sscanf(tok, "%x", &uBuf[n]) != 1) { + error(-1, "Bad line (%d) in unicodeToUnicode file '%s'", + line, fileName->getCString()); + break; + } + ++n; + } + if (n < 1) { + error(-1, "Bad line (%d) in unicodeToUnicode file '%s'", + line, fileName->getCString()); + continue; + } + if (u0 >= size) { + oldSize = size; + while (u0 >= size) { + size *= 2; + } + mapA = (Unicode *)greallocn(mapA, size, sizeof(Unicode)); + memset(mapA + oldSize, 0, (size - oldSize) * sizeof(Unicode)); + } + if (n == 1) { + mapA[u0] = uBuf[0]; + } else { + mapA[u0] = 0; + if (sMapLenA == sMapSizeA) { + sMapSizeA += 16; + sMapA = (CharCodeToUnicodeString *) + greallocn(sMapA, sMapSizeA, sizeof(CharCodeToUnicodeString)); + } + sMapA[sMapLenA].c = u0; + for (i = 0; i < n; ++i) { + sMapA[sMapLenA].u[i] = uBuf[i]; + } + sMapA[sMapLenA].len = n; + ++sMapLenA; + } + if (u0 >= len) { + len = u0 + 1; + } + } + fclose(f); + + ctu = new CharCodeToUnicode(fileName->copy(), mapA, len, gTrue, + sMapA, sMapLenA, sMapSizeA); + gfree(mapA); + return ctu; +} + +CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) { + return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0, 0); +} + +CharCodeToUnicode *CharCodeToUnicode::parseCMap(GooString *buf, int nBits) { + CharCodeToUnicode *ctu; + char *p; + + ctu = new CharCodeToUnicode(NULL); + p = buf->getCString(); + ctu->parseCMap1(&getCharFromString, &p, nBits); + return ctu; +} + +void CharCodeToUnicode::mergeCMap(GooString *buf, int nBits) { + char *p; + + p = buf->getCString(); + parseCMap1(&getCharFromString, &p, nBits); +} + +void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, + int nBits) { + PSTokenizer *pst; + char tok1[256], tok2[256], tok3[256]; + int nDigits, n1, n2, n3; + CharCode i; + CharCode code1, code2; + GooString *name; + FILE *f; + + nDigits = nBits / 4; + pst = new PSTokenizer(getCharFunc, data); + pst->getToken(tok1, sizeof(tok1), &n1); + while (pst->getToken(tok2, sizeof(tok2), &n2)) { + if (!strcmp(tok2, "usecmap")) { + if (tok1[0] == '/') { + name = new GooString(tok1 + 1); + if ((f = globalParams->findToUnicodeFile(name))) { + parseCMap1(&getCharFromFile, f, nBits); + fclose(f); + } else { + error(-1, "Couldn't find ToUnicode CMap file for '%s'", + name->getCString()); + } + delete name; + } + pst->getToken(tok1, sizeof(tok1), &n1); + } else if (!strcmp(tok2, "beginbfchar")) { + while (pst->getToken(tok1, sizeof(tok1), &n1)) { + if (!strcmp(tok1, "endbfchar")) { + break; + } + if (!pst->getToken(tok2, sizeof(tok2), &n2) || + !strcmp(tok2, "endbfchar")) { + error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); + break; + } + if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && + tok2[0] == '<' && tok2[n2 - 1] == '>')) { + + // check there was no line jump inside the token and so the length is + // longer than it should be + int countAux = 0; + for (int k = 0; k < n1; k++) + if (tok1[k] != '\n' && tok1[k] != '\r') countAux++; + + if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && + tok2[0] == '<' && tok2[n2 - 1] == '>')) { + error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); + continue; + } + } + tok1[n1 - 1] = tok2[n2 - 1] = '\0'; + if (sscanf(tok1 + 1, "%x", &code1) != 1) { + error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); + continue; + } + addMapping(code1, tok2 + 1, n2 - 2, 0); + } + pst->getToken(tok1, sizeof(tok1), &n1); + } else if (!strcmp(tok2, "beginbfrange")) { + while (pst->getToken(tok1, sizeof(tok1), &n1)) { + if (!strcmp(tok1, "endbfrange")) { + break; + } + if (!pst->getToken(tok2, sizeof(tok2), &n2) || + !strcmp(tok2, "endbfrange") || + !pst->getToken(tok3, sizeof(tok3), &n3) || + !strcmp(tok3, "endbfrange")) { + error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); + break; + } + if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && + n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) { + // check there was no line jump inside the token and so the length is + // longer than it should be + int countAux = 0; + for (int k = 0; k < n1; k++) + if (tok1[k] != '\n' && tok1[k] != '\r') countAux++; + + int countAux2 = 0; + for (int k = 0; k < n1; k++) + if (tok2[k] != '\n' && tok2[k] != '\r') countAux++; + + if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && + countAux2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) { + error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); + continue; + } + } + tok1[n1 - 1] = tok2[n2 - 1] = '\0'; + if (sscanf(tok1 + 1, "%x", &code1) != 1 || + sscanf(tok2 + 1, "%x", &code2) != 1) { + error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); + continue; + } + if (!strcmp(tok3, "[")) { + i = 0; + while (pst->getToken(tok1, sizeof(tok1), &n1) && + code1 + i <= code2) { + if (!strcmp(tok1, "]")) { + break; + } + if (tok1[0] == '<' && tok1[n1 - 1] == '>') { + tok1[n1 - 1] = '\0'; + addMapping(code1 + i, tok1 + 1, n1 - 2, 0); + } else { + error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); + } + ++i; + } + } else if (tok3[0] == '<' && tok3[n3 - 1] == '>') { + tok3[n3 - 1] = '\0'; + for (i = 0; code1 <= code2; ++code1, ++i) { + addMapping(code1, tok3 + 1, n3 - 2, i); + } + + } else { + error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); + } + } + pst->getToken(tok1, sizeof(tok1), &n1); + } else { + strcpy(tok1, tok2); + } + } + delete pst; +} + +void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, + int offset) { + CharCode oldLen, i; + Unicode u; + char uHex[5]; + int j; + + if (code >= mapLen) { + oldLen = mapLen; + mapLen = (code + 256) & ~255; + map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode)); + for (i = oldLen; i < mapLen; ++i) { + map[i] = 0; + } + } + if (n <= 4) { + if (sscanf(uStr, "%x", &u) != 1) { + error(-1, "Illegal entry in ToUnicode CMap"); + return; + } + map[code] = u + offset; + } else { + if (sMapLen >= sMapSize) { + sMapSize = sMapSize + 16; + sMap = (CharCodeToUnicodeString *) + greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString)); + } + map[code] = 0; + sMap[sMapLen].c = code; + sMap[sMapLen].len = n / 4; + for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) { + strncpy(uHex, uStr + j*4, 4); + uHex[4] = '\0'; + if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { + error(-1, "Illegal entry in ToUnicode CMap"); + } + } + sMap[sMapLen].u[sMap[sMapLen].len - 1] += offset; + ++sMapLen; + } +} + +CharCodeToUnicode::CharCodeToUnicode(GooString *tagA) { + CharCode i; + + tag = tagA; + mapLen = 256; + map = (Unicode *)gmallocn(mapLen, sizeof(Unicode)); + for (i = 0; i < mapLen; ++i) { + map[i] = 0; + } + sMap = NULL; + sMapLen = sMapSize = 0; + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + +CharCodeToUnicode::CharCodeToUnicode(GooString *tagA, Unicode *mapA, + CharCode mapLenA, GBool copyMap, + CharCodeToUnicodeString *sMapA, + int sMapLenA, int sMapSizeA) { + tag = tagA; + mapLen = mapLenA; + if (copyMap) { + map = (Unicode *)gmallocn(mapLen, sizeof(Unicode)); + memcpy(map, mapA, mapLen * sizeof(Unicode)); + } else { + map = mapA; + } + sMap = sMapA; + sMapLen = sMapLenA; + sMapSize = sMapSizeA; + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + +CharCodeToUnicode::~CharCodeToUnicode() { + if (tag) { + delete tag; + } + gfree(map); + if (sMap) { + gfree(sMap); + } +#if MULTITHREADED + gDestroyMutex(&mutex); +#endif +} + +void CharCodeToUnicode::incRefCnt() { +#if MULTITHREADED + gLockMutex(&mutex); +#endif + ++refCnt; +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif +} + +void CharCodeToUnicode::decRefCnt() { + GBool done; + +#if MULTITHREADED + gLockMutex(&mutex); +#endif + done = --refCnt == 0; +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif + if (done) { + delete this; + } +} + +GBool CharCodeToUnicode::match(GooString *tagA) { + return tag && !tag->cmp(tagA); +} + +void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) { + int i, j; + + if (len == 1) { + map[c] = u[0]; + } else { + for (i = 0; i < sMapLen; ++i) { + if (sMap[i].c == c) { + break; + } + } + if (i == sMapLen) { + if (sMapLen == sMapSize) { + sMapSize += 8; + sMap = (CharCodeToUnicodeString *) + greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString)); + } + ++sMapLen; + } + map[c] = 0; + sMap[i].c = c; + sMap[i].len = len; + for (j = 0; j < len && j < maxUnicodeString; ++j) { + sMap[i].u[j] = u[j]; + } + } +} + +int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) { + int i, j; + + if (c >= mapLen) { + return 0; + } + if (map[c]) { + u[0] = map[c]; + return 1; + } + for (i = 0; i < sMapLen; ++i) { + if (sMap[i].c == c) { + for (j = 0; j < sMap[i].len && j < size; ++j) { + u[j] = sMap[i].u[j]; + } + return j; + } + } + return 0; +} + +//------------------------------------------------------------------------ + +CharCodeToUnicodeCache::CharCodeToUnicodeCache(int sizeA) { + int i; + + size = sizeA; + cache = (CharCodeToUnicode **)gmallocn(size, sizeof(CharCodeToUnicode *)); + for (i = 0; i < size; ++i) { + cache[i] = NULL; + } +} + +CharCodeToUnicodeCache::~CharCodeToUnicodeCache() { + int i; + + for (i = 0; i < size; ++i) { + if (cache[i]) { + cache[i]->decRefCnt(); + } + } + gfree(cache); +} + +CharCodeToUnicode *CharCodeToUnicodeCache::getCharCodeToUnicode(GooString *tag) { + CharCodeToUnicode *ctu; + int i, j; + + if (cache[0] && cache[0]->match(tag)) { + cache[0]->incRefCnt(); + return cache[0]; + } + for (i = 1; i < size; ++i) { + if (cache[i] && cache[i]->match(tag)) { + ctu = cache[i]; + for (j = i; j >= 1; --j) { + cache[j] = cache[j - 1]; + } + cache[0] = ctu; + ctu->incRefCnt(); + return ctu; + } + } + return NULL; +} + +void CharCodeToUnicodeCache::add(CharCodeToUnicode *ctu) { + int i; + + if (cache[size - 1]) { + cache[size - 1]->decRefCnt(); + } + for (i = size - 1; i >= 1; --i) { + cache[i] = cache[i - 1]; + } + cache[0] = ctu; + ctu->incRefCnt(); +} diff --git a/rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.h b/rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.h new file mode 100644 index 00000000000..b0e7a490911 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CharCodeToUnicode.h @@ -0,0 +1,116 @@ +//======================================================================== +// +// CharCodeToUnicode.h +// +// Mapping from character codes to Unicode. +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef CHARCODETOUNICODE_H +#define CHARCODETOUNICODE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "poppler-config.h" +#include "CharTypes.h" + +#if MULTITHREADED +#include +#endif + +struct CharCodeToUnicodeString; + +//------------------------------------------------------------------------ + +class CharCodeToUnicode { +public: + + // Read the CID-to-Unicode mapping for from the file + // specified by . Sets the initial reference count to 1. + // Returns NULL on failure. + static CharCodeToUnicode *parseCIDToUnicode(GooString *fileName, + GooString *collection); + + // Create a Unicode-to-Unicode mapping from the file specified by + // . Sets the initial reference count to 1. Returns NULL + // on failure. + static CharCodeToUnicode *parseUnicodeToUnicode(GooString *fileName); + + // Create the CharCode-to-Unicode mapping for an 8-bit font. + // is an array of 256 Unicode indexes. Sets the initial + // reference count to 1. + static CharCodeToUnicode *make8BitToUnicode(Unicode *toUnicode); + + // Parse a ToUnicode CMap for an 8- or 16-bit font. + static CharCodeToUnicode *parseCMap(GooString *buf, int nBits); + + // Parse a ToUnicode CMap for an 8- or 16-bit font, merging it into + // . + void mergeCMap(GooString *buf, int nBits); + + ~CharCodeToUnicode(); + + void incRefCnt(); + void decRefCnt(); + + // Return true if this mapping matches the specified . + GBool match(GooString *tagA); + + // Set the mapping for . + void setMapping(CharCode c, Unicode *u, int len); + + // Map a CharCode to Unicode. + int mapToUnicode(CharCode c, Unicode *u, int size); + + // Return the mapping's length, i.e., one more than the max char + // code supported by the mapping. + CharCode getLength() { return mapLen; } + +private: + + void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits); + void addMapping(CharCode code, char *uStr, int n, int offset); + CharCodeToUnicode(GooString *tagA); + CharCodeToUnicode(GooString *tagA, Unicode *mapA, + CharCode mapLenA, GBool copyMap, + CharCodeToUnicodeString *sMapA, + int sMapLenA, int sMapSizeA); + + GooString *tag; + Unicode *map; + CharCode mapLen; + CharCodeToUnicodeString *sMap; + int sMapLen, sMapSize; + int refCnt; +#if MULTITHREADED + GooMutex mutex; +#endif +}; + +//------------------------------------------------------------------------ + +class CharCodeToUnicodeCache { +public: + + CharCodeToUnicodeCache(int sizeA); + ~CharCodeToUnicodeCache(); + + // Get the CharCodeToUnicode object for . Increments its + // reference count; there will be one reference for the cache plus + // one for the caller of this function. Returns NULL on failure. + CharCodeToUnicode *getCharCodeToUnicode(GooString *tag); + + // Insert into the cache, in the most-recently-used position. + void add(CharCodeToUnicode *ctu); + +private: + + CharCodeToUnicode **cache; + int size; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/CharTypes.h b/rosapps/smartpdf/poppler/poppler/CharTypes.h new file mode 100644 index 00000000000..d0df630d0c9 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CharTypes.h @@ -0,0 +1,24 @@ +//======================================================================== +// +// CharTypes.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef CHARTYPES_H +#define CHARTYPES_H + +// Unicode character. +typedef unsigned int Unicode; + +// Character ID for CID character collections. +typedef unsigned int CID; + +// This is large enough to hold any of the following: +// - 8-bit char code +// - 16-bit CID +// - Unicode +typedef unsigned int CharCode; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/CompactFontTables.h b/rosapps/smartpdf/poppler/poppler/CompactFontTables.h new file mode 100644 index 00000000000..28e16e775ea --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/CompactFontTables.h @@ -0,0 +1,464 @@ +//======================================================================== +// +// CompactFontTables.h +// +// Copyright 1999-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef COMPACTFONTINFO_H +#define COMPACTFONTINFO_H + +static char *type1CStdStrings[391] = { + ".notdef", + "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", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", + "001.000", + "001.001", + "001.002", + "001.003", + "Black", + "Bold", + "Book", + "Light", + "Medium", + "Regular", + "Roman", + "Semibold" +}; + +static Gushort type1CISOAdobeCharset[229] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228 +}; + +static Gushort type1CExpertCharset[166] = { + 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, + 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378 +}; + +static Gushort type1CExpertSubsetCharset[87] = { + 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, + 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, + 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, + 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346 +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/DCTStream.cc b/rosapps/smartpdf/poppler/poppler/DCTStream.cc new file mode 100644 index 00000000000..ef5db3d2ae2 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/DCTStream.cc @@ -0,0 +1,170 @@ +//======================================================================== +// +// DCTStream.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include "DCTStream.h" + +static void str_init_source(j_decompress_ptr cinfo) +{ +} + +static boolean str_fill_input_buffer(j_decompress_ptr cinfo) +{ + int c; + struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src; + if (src->index == 0) { + c = 0xFF; + src->index++; + } + else if (src->index == 1) { + c = 0xD8; + src->index++; + } + else c = src->str->getChar(); + if (c != EOF) + { + src->buffer = c; + src->pub.next_input_byte = &src->buffer; + src->pub.bytes_in_buffer = 1; + return TRUE; + } + else return FALSE; +} + +static void str_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src; + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + str_fill_input_buffer(cinfo); + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void str_term_source(j_decompress_ptr cinfo) +{ +} + +DCTStream::DCTStream(Stream *strA): + FilterStream(strA) { + init(); +} + +DCTStream::~DCTStream() { + jpeg_destroy_decompress(&cinfo); + delete str; +} + +void DCTStream::init() +{ + jpeg_create_decompress(&cinfo); + src.pub.init_source = str_init_source; + src.pub.fill_input_buffer = str_fill_input_buffer; + src.pub.skip_input_data = str_skip_input_data; + src.pub.resync_to_restart = jpeg_resync_to_restart; + src.pub.term_source = str_term_source; + src.pub.bytes_in_buffer = 0; + src.pub.next_input_byte = NULL; + src.str = str; + src.index = 0; + cinfo.src = (jpeg_source_mgr *)&src; + cinfo.err = jpeg_std_error(&jerr); + x = 0; + row_buffer = NULL; +} + +void DCTStream::reset() { + int row_stride; + + str->reset(); + + if (row_buffer) + { + jpeg_destroy_decompress(&cinfo); + init(); + } + + // JPEG data has to start with 0xFF 0xD8 + // but some pdf like the one on + // https://bugs.freedesktop.org/show_bug.cgi?id=3299 + // does have some garbage before that this seeks for + // the start marker... + bool startFound = false; + int c = 0, c2 = 0; + while (!startFound) + { + if (!c) + { + c = str->getChar(); + if (c == -1) + { + error(-1, "Could not find start of jpeg data"); + exit(1); + } + if (c != 0xFF) c = 0; + } + else + { + c2 = str->getChar(); + if (c2 != 0xD8) + { + c = 0; + c2 = 0; + } + else startFound = true; + } + } + + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + row_stride = cinfo.output_width * cinfo.output_components; + row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); +} + +int DCTStream::getChar() { + int c; + + if (x == 0) { + if (cinfo.output_scanline < cinfo.output_height) + { + if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF; + } + else return EOF; + } + c = row_buffer[0][x]; + x++; + if (x == cinfo.output_width * cinfo.output_components) + x = 0; + return c; +} + +int DCTStream::lookChar() { + int c; + c = row_buffer[0][x]; + return c; +} + +GooString *DCTStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 2) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("<< >> /DCTDecode filter\n"); + return s; +} + +GBool DCTStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} diff --git a/rosapps/smartpdf/poppler/poppler/DCTStream.h b/rosapps/smartpdf/poppler/poppler/DCTStream.h new file mode 100644 index 00000000000..7503e16a1e8 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/DCTStream.h @@ -0,0 +1,73 @@ +//======================================================================== +// +// DCTStream.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef DCTSTREAM_H +#define DCTSTREAM_H +#include + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include "goo/gmem.h" +#include "goo/gfile.h" +#include "poppler-config.h" +#include "Error.h" +#include "Object.h" +#include "Decrypt.h" +#include "Stream.h" + +extern "C" { +#include +} + +struct str_src_mgr { + struct jpeg_source_mgr pub; + JOCTET buffer; + Stream *str; + int index; +}; + + +class DCTStream: public FilterStream { +public: + + DCTStream(Stream *strA); + virtual ~DCTStream(); + virtual StreamKind getKind() { return strDCT; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + Stream *getRawStream() { return str; } + +private: + void init(); + + unsigned int x; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct str_src_mgr src; + JSAMPARRAY row_buffer; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Decrypt.cc b/rosapps/smartpdf/poppler/poppler/Decrypt.cc new file mode 100644 index 00000000000..2d8884ba2a9 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Decrypt.cc @@ -0,0 +1,411 @@ +//======================================================================== +// +// Decrypt.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "Decrypt.h" + +static void rc4InitKey(Guchar *key, int keyLen, Guchar *state); +static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c); +static void md5(Guchar *msg, int msgLen, Guchar *digest); + +static Guchar passwordPad[32] = { + 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, + 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, + 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, + 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a +}; + +//------------------------------------------------------------------------ +// Decrypt +//------------------------------------------------------------------------ + +Decrypt::Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen) { + int i; + + // construct object key + for (i = 0; i < keyLength; ++i) { + objKey[i] = fileKey[i]; + } + objKey[keyLength] = objNum & 0xff; + objKey[keyLength + 1] = (objNum >> 8) & 0xff; + objKey[keyLength + 2] = (objNum >> 16) & 0xff; + objKey[keyLength + 3] = objGen & 0xff; + objKey[keyLength + 4] = (objGen >> 8) & 0xff; + md5(objKey, keyLength + 5, objKey); + + // set up for decryption + x = y = 0; + if ((objKeyLength = keyLength + 5) > 16) { + objKeyLength = 16; + } + rc4InitKey(objKey, objKeyLength, state); +} + +void Decrypt::reset() { + x = y = 0; + rc4InitKey(objKey, objKeyLength, state); +} + +Guchar Decrypt::decryptByte(Guchar c) { + return rc4DecryptByte(state, &x, &y, c); +} + +GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, + GooString *ownerKey, GooString *userKey, + int permissions, GooString *fileID, + GooString *ownerPassword, GooString *userPassword, + Guchar *fileKey, GBool encryptMetadata, + GBool *ownerPasswordOk) { + Guchar test[32], test2[32]; + GooString *userPassword2; + Guchar fState[256]; + Guchar tmpKey[16]; + Guchar fx, fy; + int len, i, j; + + // try using the supplied owner password to generate the user password + *ownerPasswordOk = gFalse; + if (ownerPassword) { + len = ownerPassword->getLength(); + if (len < 32) { + memcpy(test, ownerPassword->getCString(), len); + memcpy(test + len, passwordPad, 32 - len); + } else { + memcpy(test, ownerPassword->getCString(), 32); + } + md5(test, 32, test); + if (encRevision == 3) { + for (i = 0; i < 50; ++i) { + md5(test, 16, test); + } + } + if (encRevision == 2) { + rc4InitKey(test, keyLength, fState); + fx = fy = 0; + for (i = 0; i < 32; ++i) { + test2[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i)); + } + } else { + memcpy(test2, ownerKey->getCString(), 32); + for (i = 19; i >= 0; --i) { + for (j = 0; j < keyLength; ++j) { + tmpKey[j] = test[j] ^ i; + } + rc4InitKey(tmpKey, keyLength, fState); + fx = fy = 0; + for (j = 0; j < 32; ++j) { + test2[j] = rc4DecryptByte(fState, &fx, &fy, test2[j]); + } + } + } + userPassword2 = new GooString((char *)test2, 32); + if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, + permissions, fileID, userPassword2, fileKey, + encryptMetadata)) { + *ownerPasswordOk = gTrue; + delete userPassword2; + return gTrue; + } + delete userPassword2; + } + + // try using the supplied user password + return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, + permissions, fileID, userPassword, fileKey, + encryptMetadata); +} + +GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength, + GooString *ownerKey, GooString *userKey, + int permissions, GooString *fileID, + GooString *userPassword, Guchar *fileKey, + GBool encryptMetadata) { + Guchar *buf; + Guchar test[32]; + Guchar fState[256]; + Guchar tmpKey[16]; + Guchar fx, fy; + int len, i, j; + GBool ok; + + // generate file key + buf = (Guchar *)gmalloc(72 + fileID->getLength()); + if (userPassword) { + len = userPassword->getLength(); + if (len < 32) { + memcpy(buf, userPassword->getCString(), len); + memcpy(buf + len, passwordPad, 32 - len); + } else { + memcpy(buf, userPassword->getCString(), 32); + } + } else { + memcpy(buf, passwordPad, 32); + } + memcpy(buf + 32, ownerKey->getCString(), 32); + buf[64] = permissions & 0xff; + buf[65] = (permissions >> 8) & 0xff; + buf[66] = (permissions >> 16) & 0xff; + buf[67] = (permissions >> 24) & 0xff; + memcpy(buf + 68, fileID->getCString(), fileID->getLength()); + len = 68 + fileID->getLength(); + if (!encryptMetadata) { + buf[len++] = 0xff; + buf[len++] = 0xff; + buf[len++] = 0xff; + buf[len++] = 0xff; + } + md5(buf, len, fileKey); + if (encRevision == 3) { + for (i = 0; i < 50; ++i) { + md5(fileKey, keyLength, fileKey); + } + } + + // test user password + if (encRevision == 2) { + rc4InitKey(fileKey, keyLength, fState); + fx = fy = 0; + for (i = 0; i < 32; ++i) { + test[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i)); + } + ok = memcmp(test, passwordPad, 32) == 0; + } else if (encRevision == 3) { + memcpy(test, userKey->getCString(), 32); + for (i = 19; i >= 0; --i) { + for (j = 0; j < keyLength; ++j) { + tmpKey[j] = fileKey[j] ^ i; + } + rc4InitKey(tmpKey, keyLength, fState); + fx = fy = 0; + for (j = 0; j < 32; ++j) { + test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]); + } + } + memcpy(buf, passwordPad, 32); + memcpy(buf + 32, fileID->getCString(), fileID->getLength()); + md5(buf, 32 + fileID->getLength(), buf); + ok = memcmp(test, buf, 16) == 0; + } else { + ok = gFalse; + } + + gfree(buf); + return ok; +} + +//------------------------------------------------------------------------ +// RC4-compatible decryption +//------------------------------------------------------------------------ + +static void rc4InitKey(Guchar *key, int keyLen, Guchar *state) { + Guchar index1, index2; + Guchar t; + int i; + + for (i = 0; i < 256; ++i) + state[i] = i; + index1 = index2 = 0; + for (i = 0; i < 256; ++i) { + index2 = (key[index1] + state[i] + index2) % 256; + t = state[i]; + state[i] = state[index2]; + state[index2] = t; + index1 = (index1 + 1) % keyLen; + } +} + +static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c) { + Guchar x1, y1, tx, ty; + + x1 = *x = (*x + 1) % 256; + y1 = *y = (state[*x] + *y) % 256; + tx = state[x1]; + ty = state[y1]; + state[x1] = ty; + state[y1] = tx; + return c ^ state[(tx + ty) % 256]; +} + +//------------------------------------------------------------------------ +// MD5 message digest +//------------------------------------------------------------------------ + +// this works around a bug in older Sun compilers +static inline Gulong rotateLeft(Gulong x, int r) { + x &= 0xffffffff; + return ((x << r) | (x >> (32 - r))) & 0xffffffff; +} + +static inline Gulong md5Round1(Gulong a, Gulong b, Gulong c, Gulong d, + Gulong Xk, Gulong s, Gulong Ti) { + return b + rotateLeft((a + ((b & c) | (~b & d)) + Xk + Ti), s); +} + +static inline Gulong md5Round2(Gulong a, Gulong b, Gulong c, Gulong d, + Gulong Xk, Gulong s, Gulong Ti) { + return b + rotateLeft((a + ((b & d) | (c & ~d)) + Xk + Ti), s); +} + +static inline Gulong md5Round3(Gulong a, Gulong b, Gulong c, Gulong d, + Gulong Xk, Gulong s, Gulong Ti) { + return b + rotateLeft((a + (b ^ c ^ d) + Xk + Ti), s); +} + +static inline Gulong md5Round4(Gulong a, Gulong b, Gulong c, Gulong d, + Gulong Xk, Gulong s, Gulong Ti) { + return b + rotateLeft((a + (c ^ (b | ~d)) + Xk + Ti), s); +} + +static void md5(Guchar *msg, int msgLen, Guchar *digest) { + Gulong x[16]; + Gulong a, b, c, d, aa, bb, cc, dd; + int n64; + int i, j, k; + + // compute number of 64-byte blocks + // (length + pad byte (0x80) + 8 bytes for length) + n64 = (msgLen + 1 + 8 + 63) / 64; + + // initialize a, b, c, d + a = 0x67452301; + b = 0xefcdab89; + c = 0x98badcfe; + d = 0x10325476; + + // loop through blocks + k = 0; + for (i = 0; i < n64; ++i) { + + // grab a 64-byte block + for (j = 0; j < 16 && k < msgLen - 3; ++j, k += 4) + x[j] = (((((msg[k+3] << 8) + msg[k+2]) << 8) + msg[k+1]) << 8) + msg[k]; + if (i == n64 - 1) { + if (k == msgLen - 3) + x[j] = 0x80000000 + (((msg[k+2] << 8) + msg[k+1]) << 8) + msg[k]; + else if (k == msgLen - 2) + x[j] = 0x800000 + (msg[k+1] << 8) + msg[k]; + else if (k == msgLen - 1) + x[j] = 0x8000 + msg[k]; + else + x[j] = 0x80; + ++j; + while (j < 16) + x[j++] = 0; + x[14] = msgLen << 3; + } + + // save a, b, c, d + aa = a; + bb = b; + cc = c; + dd = d; + + // round 1 + a = md5Round1(a, b, c, d, x[0], 7, 0xd76aa478); + d = md5Round1(d, a, b, c, x[1], 12, 0xe8c7b756); + c = md5Round1(c, d, a, b, x[2], 17, 0x242070db); + b = md5Round1(b, c, d, a, x[3], 22, 0xc1bdceee); + a = md5Round1(a, b, c, d, x[4], 7, 0xf57c0faf); + d = md5Round1(d, a, b, c, x[5], 12, 0x4787c62a); + c = md5Round1(c, d, a, b, x[6], 17, 0xa8304613); + b = md5Round1(b, c, d, a, x[7], 22, 0xfd469501); + a = md5Round1(a, b, c, d, x[8], 7, 0x698098d8); + d = md5Round1(d, a, b, c, x[9], 12, 0x8b44f7af); + c = md5Round1(c, d, a, b, x[10], 17, 0xffff5bb1); + b = md5Round1(b, c, d, a, x[11], 22, 0x895cd7be); + a = md5Round1(a, b, c, d, x[12], 7, 0x6b901122); + d = md5Round1(d, a, b, c, x[13], 12, 0xfd987193); + c = md5Round1(c, d, a, b, x[14], 17, 0xa679438e); + b = md5Round1(b, c, d, a, x[15], 22, 0x49b40821); + + // round 2 + a = md5Round2(a, b, c, d, x[1], 5, 0xf61e2562); + d = md5Round2(d, a, b, c, x[6], 9, 0xc040b340); + c = md5Round2(c, d, a, b, x[11], 14, 0x265e5a51); + b = md5Round2(b, c, d, a, x[0], 20, 0xe9b6c7aa); + a = md5Round2(a, b, c, d, x[5], 5, 0xd62f105d); + d = md5Round2(d, a, b, c, x[10], 9, 0x02441453); + c = md5Round2(c, d, a, b, x[15], 14, 0xd8a1e681); + b = md5Round2(b, c, d, a, x[4], 20, 0xe7d3fbc8); + a = md5Round2(a, b, c, d, x[9], 5, 0x21e1cde6); + d = md5Round2(d, a, b, c, x[14], 9, 0xc33707d6); + c = md5Round2(c, d, a, b, x[3], 14, 0xf4d50d87); + b = md5Round2(b, c, d, a, x[8], 20, 0x455a14ed); + a = md5Round2(a, b, c, d, x[13], 5, 0xa9e3e905); + d = md5Round2(d, a, b, c, x[2], 9, 0xfcefa3f8); + c = md5Round2(c, d, a, b, x[7], 14, 0x676f02d9); + b = md5Round2(b, c, d, a, x[12], 20, 0x8d2a4c8a); + + // round 3 + a = md5Round3(a, b, c, d, x[5], 4, 0xfffa3942); + d = md5Round3(d, a, b, c, x[8], 11, 0x8771f681); + c = md5Round3(c, d, a, b, x[11], 16, 0x6d9d6122); + b = md5Round3(b, c, d, a, x[14], 23, 0xfde5380c); + a = md5Round3(a, b, c, d, x[1], 4, 0xa4beea44); + d = md5Round3(d, a, b, c, x[4], 11, 0x4bdecfa9); + c = md5Round3(c, d, a, b, x[7], 16, 0xf6bb4b60); + b = md5Round3(b, c, d, a, x[10], 23, 0xbebfbc70); + a = md5Round3(a, b, c, d, x[13], 4, 0x289b7ec6); + d = md5Round3(d, a, b, c, x[0], 11, 0xeaa127fa); + c = md5Round3(c, d, a, b, x[3], 16, 0xd4ef3085); + b = md5Round3(b, c, d, a, x[6], 23, 0x04881d05); + a = md5Round3(a, b, c, d, x[9], 4, 0xd9d4d039); + d = md5Round3(d, a, b, c, x[12], 11, 0xe6db99e5); + c = md5Round3(c, d, a, b, x[15], 16, 0x1fa27cf8); + b = md5Round3(b, c, d, a, x[2], 23, 0xc4ac5665); + + // round 4 + a = md5Round4(a, b, c, d, x[0], 6, 0xf4292244); + d = md5Round4(d, a, b, c, x[7], 10, 0x432aff97); + c = md5Round4(c, d, a, b, x[14], 15, 0xab9423a7); + b = md5Round4(b, c, d, a, x[5], 21, 0xfc93a039); + a = md5Round4(a, b, c, d, x[12], 6, 0x655b59c3); + d = md5Round4(d, a, b, c, x[3], 10, 0x8f0ccc92); + c = md5Round4(c, d, a, b, x[10], 15, 0xffeff47d); + b = md5Round4(b, c, d, a, x[1], 21, 0x85845dd1); + a = md5Round4(a, b, c, d, x[8], 6, 0x6fa87e4f); + d = md5Round4(d, a, b, c, x[15], 10, 0xfe2ce6e0); + c = md5Round4(c, d, a, b, x[6], 15, 0xa3014314); + b = md5Round4(b, c, d, a, x[13], 21, 0x4e0811a1); + a = md5Round4(a, b, c, d, x[4], 6, 0xf7537e82); + d = md5Round4(d, a, b, c, x[11], 10, 0xbd3af235); + c = md5Round4(c, d, a, b, x[2], 15, 0x2ad7d2bb); + b = md5Round4(b, c, d, a, x[9], 21, 0xeb86d391); + + // increment a, b, c, d + a += aa; + b += bb; + c += cc; + d += dd; + } + + // break digest into bytes + digest[0] = (Guchar)(a & 0xff); + digest[1] = (Guchar)((a >>= 8) & 0xff); + digest[2] = (Guchar)((a >>= 8) & 0xff); + digest[3] = (Guchar)((a >>= 8) & 0xff); + digest[4] = (Guchar)(b & 0xff); + digest[5] = (Guchar)((b >>= 8) & 0xff); + digest[6] = (Guchar)((b >>= 8) & 0xff); + digest[7] = (Guchar)((b >>= 8) & 0xff); + digest[8] = (Guchar)(c & 0xff); + digest[9] = (Guchar)((c >>= 8) & 0xff); + digest[10] = (Guchar)((c >>= 8) & 0xff); + digest[11] = (Guchar)((c >>= 8) & 0xff); + digest[12] = (Guchar)(d & 0xff); + digest[13] = (Guchar)((d >>= 8) & 0xff); + digest[14] = (Guchar)((d >>= 8) & 0xff); + digest[15] = (Guchar)((d >>= 8) & 0xff); +} diff --git a/rosapps/smartpdf/poppler/poppler/Decrypt.h b/rosapps/smartpdf/poppler/poppler/Decrypt.h new file mode 100644 index 00000000000..1435c538274 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Decrypt.h @@ -0,0 +1,61 @@ +//======================================================================== +// +// Decrypt.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef DECRYPT_H +#define DECRYPT_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "goo/GooString.h" + +//------------------------------------------------------------------------ +// Decrypt +//------------------------------------------------------------------------ + +class Decrypt { +public: + + // Initialize the decryptor object. + Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen); + + // Reset decryption. + void reset(); + + // Decrypt one byte. + Guchar decryptByte(Guchar c); + + // Generate a file key. The buffer must have space for at + // least 16 bytes. Checks and then + // and returns true if either is correct. Sets if + // the owner password was correct. Either or both of the passwords + // may be NULL, which is treated as an empty string. + static GBool makeFileKey(int encVersion, int encRevision, int keyLength, + GooString *ownerKey, GooString *userKey, + int permissions, GooString *fileID, + GooString *ownerPassword, GooString *userPassword, + Guchar *fileKey, GBool encryptMetadata, + GBool *ownerPasswordOk); + +private: + + static GBool makeFileKey2(int encVersion, int encRevision, int keyLength, + GooString *ownerKey, GooString *userKey, + int permissions, GooString *fileID, + GooString *userPassword, Guchar *fileKey, + GBool encryptMetadata); + + int objKeyLength; + Guchar objKey[21]; + Guchar state[256]; + Guchar x, y; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Dict.cc b/rosapps/smartpdf/poppler/poppler/Dict.cc new file mode 100644 index 00000000000..3b8939677b3 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Dict.cc @@ -0,0 +1,203 @@ +//======================================================================== +// +// Dict.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include "goo/gmem.h" +#include "Error.h" +#include "Object.h" +#include "UGooString.h" +#include "XRef.h" +#include "Dict.h" + +//------------------------------------------------------------------------ +// Dict +//------------------------------------------------------------------------ + +Dict::Dict(XRef *xrefA) { + xref = xrefA; + entries = NULL; + size = length = 0; + ref = 1; +} + +Dict::~Dict() { + int i; + + for (i = 0; i < length; ++i) { + delete entries[i].key; + entries[i].val.free(); + } + gfree(entries); +} + +void Dict::addOwnKeyVal(UGooString *key, Object *val) { + if (length == size) { + if (length == 0) { + size = 8; + } else { + size *= 2; + } + entries = (DictEntry *)greallocn(entries, size, sizeof(DictEntry)); + } + entries[length].key = key; + entries[length].val = *val; + ++length; +} + +inline DictEntry *Dict::find(const UGooString &key) const { + int i; + + for (i = 0; i < length; ++i) { + if (!key.cmp(entries[i].key)) + return &entries[i]; + } + return NULL; +} + +inline DictEntry *Dict::find(const char *key, int keyLen) const { + int i; + + for (i = 0; i < length; ++i) { + if (0 == entries[i].key->cmp(key, keyLen)) + return &entries[i]; + } + return NULL; +} + +// length of string "Type" +#define TYPE_STR_LEN 4 + +GBool Dict::is(char *type) const { + DictEntry *e = find("Type", TYPE_STR_LEN); + if (!e) + return gFalse; + return e->val.isName(type); +} + +Object *Dict::lookup(const char *key, Object *obj, int keyLen) const { + DictEntry *e = find(key, keyLen); + if (!e) + return obj->initNull(); + return e->val.fetch(xref, obj); +} + +Object *Dict::lookupNF(const char *key, Object *obj, int keyLen) const { + DictEntry *e = find(key, keyLen); + if (!e) + return obj->initNull(); + return e->val.copy(obj); +} + +Object *Dict::lookup(const UGooString &key, Object *obj) const { + DictEntry *e = find(key); + if (!e) + return obj->initNull(); + return e->val.fetch(xref, obj); +} + +Object *Dict::lookupNF(const UGooString &key, Object *obj) const { + DictEntry *e = find(key); + if (!e) + return obj->initNull(); + return e->val.copy(obj); +} + +Object *Dict::lookupRefNoFetch(const char *key, int keyLen) const { + DictEntry *e; + e = find(key); + if (!e) + return NULL; + return &(e->val); +} + +Object *Dict::lookupRefNoFetch(const UGooString &key) const { + DictEntry *e; + e = find(key); + if (!e) + return NULL; + return &(e->val); + +} + +GBool Dict::lookupBool(const char *key, const char *alt_key, GBool *value) const { + Object *obj; + + // FIXME: handle ref objects as well + obj = lookupRefNoFetch(key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupBool for %s", key); + assert(0); + } + if (obj && obj->isBool()) { + *value = obj->getBool(); + return gTrue; + } + + if (!alt_key) + return gFalse; + obj = lookupRefNoFetch(alt_key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupBool for %s", alt_key); + assert(0); + } + if (obj && obj->isBool()) { + *value = obj->getBool(); + return gTrue; + } + + return gFalse; +} + +GBool Dict::lookupInt(const char *key, const char *alt_key, int *value) const { + Object *obj; + + // FIXME: handle ref objects as well + obj = lookupRefNoFetch(key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupInt for %s", key); + assert(0); + } + if (obj && obj->isInt()) { + *value = obj->getInt(); + return gTrue; + } + + if (!alt_key) + return gFalse; + obj = lookupRefNoFetch(alt_key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupInt for %s", alt_key); + assert(0); + } + if (obj && obj->isInt()) { + *value = obj->getInt(); + return gTrue; + } + + return gFalse; +} + +UGooString *Dict::getKey(int i) const { + return entries[i].key; +} + +Object *Dict::getVal(int i, Object *obj) const { + return entries[i].val.fetch(xref, obj); +} + +Object *Dict::getValNF(int i, Object *obj) const { + return entries[i].val.copy(obj); +} diff --git a/rosapps/smartpdf/poppler/poppler/Dict.h b/rosapps/smartpdf/poppler/poppler/Dict.h new file mode 100644 index 00000000000..2514bb8cc37 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Dict.h @@ -0,0 +1,89 @@ +//======================================================================== +// +// Dict.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef DICT_H +#define DICT_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "Object.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ +// Dict +//------------------------------------------------------------------------ + +struct DictEntry { + UGooString *key; + Object val; +}; + +class Dict { +public: + + Dict(XRef *xrefA); + + ~Dict(); + + // Reference counting. + int incRef() { return ++ref; } + int decRef() { return --ref; } + + // Get number of entries. + int getLength() const { return length; } + + // Add an entry + void addOwnKeyVal(UGooString *key, Object *val); + // FIXME: should also be renamed to addOwnVal() + void add(const UGooString &key, Object *val) { + addOwnKeyVal(new UGooString(key), val); + } + void addOwnVal(const char *key, Object *val) { + addOwnKeyVal(new UGooString(key), val); + } + + // Check if dictionary is of specified type. + GBool is(char *type) const; + + // Look up an entry and return the value. Returns a null object + // if is not in the dictionary. + Object *lookup(const UGooString &key, Object *obj) const; + Object *lookupNF(const UGooString &key, Object *obj) const; + Object *lookupRefNoFetch(const UGooString &key) const; + Object *lookup(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN) const; + Object *lookupNF(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN) const; + Object *lookupRefNoFetch(const char *key, int keyLen=UGooString::CALC_STRING_LEN) const; + + GBool lookupBool(const char *key, const char *alt_key, GBool *value) const; + GBool lookupInt(const char *key, const char *alt_key, int *value) const; + + // Iterative accessors. + UGooString *getKey(int i) const; + Object *getVal(int i, Object *obj) const; + Object *getValNF(int i, Object *obj) const; + + // Set the xref pointer. This is only used in one special case: the + // trailer dictionary, which is read before the xref table is + // parsed. + void setXRef(XRef *xrefA) { xref = xrefA; } + +private: + + XRef *xref; // the xref table for this PDF file + DictEntry *entries; // array of entries + int size; // size of array + int length; // number of entries in dictionary + int ref; // reference count + + DictEntry *find(const UGooString &key) const; + DictEntry *find(const char *key, int keyLen) const; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Error.cc b/rosapps/smartpdf/poppler/poppler/Error.cc new file mode 100644 index 00000000000..f3b98b95c7e --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Error.cc @@ -0,0 +1,49 @@ +//======================================================================== +// +// Error.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include "GlobalParams.h" +#include "Error.h" + +static void CDECL defaultErrorFunction(int pos, char *msg, va_list args) +{ + if (pos >= 0) { + fprintf(stderr, "Error (%d): ", pos); + } else { + fprintf(stderr, "Error: "); + } + vfprintf(stderr, msg, args); + fprintf(stderr, "\n"); + fflush(stderr); +} + +static void CDECL (*errorFunction)(int , char *, va_list args) = defaultErrorFunction; + +void setErrorFunction(void CDECL (* f)(int , char *, va_list args)) +{ + errorFunction = f; +} + +void CDECL error(int pos, char *msg, ...) { + va_list args; + // NB: this can be called before the globalParams object is created + if (globalParams && globalParams->getErrQuiet()) { + return; + } + va_start(args, msg); + (*errorFunction)(pos, msg, args); + va_end(args); +} diff --git a/rosapps/smartpdf/poppler/poppler/Error.h b/rosapps/smartpdf/poppler/poppler/Error.h new file mode 100644 index 00000000000..d307223c5b3 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Error.h @@ -0,0 +1,23 @@ +//======================================================================== +// +// Error.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef ERROR_H +#define ERROR_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include "poppler-config.h" + +extern void CDECL error(int pos, char *msg, ...) GCC_PRINTF_FORMAT (2, 3); + +void setErrorFunction(void (* f)(int , char *, va_list args)); + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/ErrorCodes.h b/rosapps/smartpdf/poppler/poppler/ErrorCodes.h new file mode 100644 index 00000000000..b28528df564 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/ErrorCodes.h @@ -0,0 +1,36 @@ +//======================================================================== +// +// ErrorCodes.h +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef ERRORCODES_H +#define ERRORCODES_H + +#define errNone 0 // no error + +#define errOpenFile 1 // couldn't open the PDF file + +#define errBadCatalog 2 // couldn't read the page catalog + +#define errDamaged 3 // PDF file was damaged and couldn't be + // repaired + +#define errEncrypted 4 // file was encrypted and password was + // incorrect or not supplied + +#define errHighlightFile 5 // nonexistent or invalid highlight file + +#define errBadPrinter 6 // invalid printer + +#define errPrinting 7 // error during printing + +#define errPermission 8 // PDF file doesn't allow that operation + +#define errBadPageNum 9 // invalid page number + +#define errFileIO 10 // file I/O error + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/FlateStream.cc b/rosapps/smartpdf/poppler/poppler/FlateStream.cc new file mode 100644 index 00000000000..90b3f1d980c --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/FlateStream.cc @@ -0,0 +1,116 @@ +//======================================================================== +// +// FlateStream.cc +// +// Copyright (C) 2005, Jeff Muizelaar +// +//======================================================================== +#include "FlateStream.h" +FlateStream::FlateStream(Stream *strA, int predictor, int columns, int colors, int bits) : + FilterStream(strA) +{ + if (predictor != 1) { + pred = new StreamPredictor(this, predictor, columns, colors, bits); + } else { + pred = NULL; + } + out_pos = 0; + memset(&d_stream, 0, sizeof(d_stream)); + inflateInit(&d_stream); +} + +FlateStream::~FlateStream() { + inflateEnd(&d_stream); + delete pred; + delete str; +} + +void FlateStream::reset() { + //FIXME: what are the semantics of reset? + //i.e. how much intialization has to happen in the constructor? + + /* reinitialize zlib */ + inflateEnd(&d_stream); + memset(&d_stream, 0, sizeof(d_stream)); + inflateInit(&d_stream); + + str->reset(); + d_stream.avail_in = 0; + status = Z_OK; + out_pos = 0; + out_buf_len = 0; +} + +int FlateStream::getChar() { + if (pred) + return pred->getChar(); + else + return getRawChar(); +} + +int FlateStream::lookChar() { + if (pred) + return pred->lookChar(); + + if (fill_buffer()) + return EOF; + + return out_buf[out_pos]; +} + +int FlateStream::fill_buffer() { + /* only fill the buffer if it has all been used */ + if (out_pos >= out_buf_len) { + /* check if the flatestream has been exhausted */ + if (status == Z_STREAM_END) { + return -1; + } + + /* set to the begining of out_buf */ + d_stream.avail_out = sizeof(out_buf); + d_stream.next_out = out_buf; + out_pos = 0; + + while (1) { + /* buffer is empty so we need to fill it */ + if (d_stream.avail_in == 0) { + int c; + /* read from the source stream */ + while (d_stream.avail_in < sizeof(in_buf) && (c = str->getChar()) != EOF) { + in_buf[d_stream.avail_in++] = c; + } + d_stream.next_in = in_buf; + } + + /* keep decompressing until we can't anymore */ + if (d_stream.avail_out == 0 || d_stream.avail_in == 0 || (status != Z_OK && status != Z_BUF_ERROR)) + break; + status = inflate(&d_stream, Z_SYNC_FLUSH); + } + + out_buf_len = sizeof(out_buf) - d_stream.avail_out; + if (status != Z_OK && status != Z_STREAM_END) + return -1; + if (!out_buf_len) + return -1; + } + + return 0; +} + +GooString *FlateStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 3 || pred) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("<< >> /FlateDecode filter\n"); + return s; +} + +GBool FlateStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} diff --git a/rosapps/smartpdf/poppler/poppler/FlateStream.h b/rosapps/smartpdf/poppler/poppler/FlateStream.h new file mode 100644 index 00000000000..0dea9482455 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/FlateStream.h @@ -0,0 +1,73 @@ +//======================================================================== +// +// FlateStream.h +// +// Copyright (C) 2005, Jeff Muizelaar +// +//======================================================================== + +#ifndef FLATESTREAM_H +#define FLATESTREAM_H +#include + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include "goo/gmem.h" +#include "goo/gfile.h" +#include "poppler-config.h" +#include "Error.h" +#include "Object.h" +#include "Decrypt.h" +#include "Stream.h" + +extern "C" { +#include +} + +class FlateStream: public FilterStream { +public: + + FlateStream(Stream *strA, int predictor, int columns, int colors, int bits); + virtual ~FlateStream(); + virtual StreamKind getKind() { return strFlate; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + + int getRawChar() { + if (fill_buffer()) + return EOF; + + return out_buf[out_pos++]; + } + +private: + int fill_buffer(void); + z_stream d_stream; + StreamPredictor *pred; + int status; + /* in_buf currently needs to be 1 or we over read from EmbedStreams */ + unsigned char in_buf[1]; + unsigned char out_buf[4096]; + int out_pos; + int out_buf_len; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/FontEncodingTables.cc b/rosapps/smartpdf/poppler/poppler/FontEncodingTables.cc new file mode 100644 index 00000000000..cd8d8926542 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/FontEncodingTables.cc @@ -0,0 +1,1824 @@ +//======================================================================== +// +// FontEncodingTables.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include +#include +#include "FontEncodingTables.h" + +char *macRomanEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "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", + "grave", + "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", + NULL, + "Adieresis", + "Aring", + "Ccedilla", + "Eacute", + "Ntilde", + "Odieresis", + "Udieresis", + "aacute", + "agrave", + "acircumflex", + "adieresis", + "atilde", + "aring", + "ccedilla", + "eacute", + "egrave", + "ecircumflex", + "edieresis", + "iacute", + "igrave", + "icircumflex", + "idieresis", + "ntilde", + "oacute", + "ograve", + "ocircumflex", + "odieresis", + "otilde", + "uacute", + "ugrave", + "ucircumflex", + "udieresis", + "dagger", + "degree", + "cent", + "sterling", + "section", + "bullet", + "paragraph", + "germandbls", + "registered", + "copyright", + "trademark", + "acute", + "dieresis", + "notequal", + "AE", + "Oslash", + "infinity", + "plusminus", + "lessequal", + "greaterequal", + "yen", + "mu", + "partialdiff", + "summation", + "product", + "pi", + "integral", + "ordfeminine", + "ordmasculine", + "Omega", + "ae", + "oslash", + "questiondown", + "exclamdown", + "logicalnot", + "radical", + "florin", + "approxequal", + "Delta", + "guillemotleft", + "guillemotright", + "ellipsis", + "space", + "Agrave", + "Atilde", + "Otilde", + "OE", + "oe", + "endash", + "emdash", + "quotedblleft", + "quotedblright", + "quoteleft", + "quoteright", + "divide", + "lozenge", + "ydieresis", + "Ydieresis", + "fraction", + "currency", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "daggerdbl", + "periodcentered", + "quotesinglbase", + "quotedblbase", + "perthousand", + "Acircumflex", + "Ecircumflex", + "Aacute", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Oacute", + "Ocircumflex", + "apple", + "Ograve", + "Uacute", + "Ucircumflex", + "Ugrave", + "dotlessi", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron" +}; + +char *macExpertEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclamsmall", + "Hungarumlautsmall", + "centoldstyle", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + NULL, + "threequartersemdash", + NULL, + "questionsmall", + NULL, + NULL, + NULL, + NULL, + "Ethsmall", + NULL, + NULL, + "onequarter", + "onehalf", + "threequarters", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + NULL, + "parenrightinferior", + "Circumflexsmall", + "hypheninferior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + NULL, + NULL, + "asuperior", + "centsuperior", + NULL, + NULL, + NULL, + NULL, + "Aacutesmall", + "Agravesmall", + "Acircumflexsmall", + "Adieresissmall", + "Atildesmall", + "Aringsmall", + "Ccedillasmall", + "Eacutesmall", + "Egravesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Iacutesmall", + "Igravesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ntildesmall", + "Oacutesmall", + "Ogravesmall", + "Ocircumflexsmall", + "Odieresissmall", + "Otildesmall", + "Uacutesmall", + "Ugravesmall", + "Ucircumflexsmall", + "Udieresissmall", + NULL, + "eightsuperior", + "fourinferior", + "threeinferior", + "sixinferior", + "eightinferior", + "seveninferior", + "Scaronsmall", + NULL, + "centinferior", + "twoinferior", + NULL, + "Dieresissmall", + NULL, + "Caronsmall", + "osuperior", + "fiveinferior", + NULL, + "commainferior", + "periodinferior", + "Yacutesmall", + NULL, + "dollarinferior", + NULL, + NULL, + "Thornsmall", + NULL, + "nineinferior", + "zeroinferior", + "Zcaronsmall", + "AEsmall", + "Oslashsmall", + "questiondownsmall", + "oneinferior", + "Lslashsmall", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Cedillasmall", + NULL, + NULL, + NULL, + NULL, + NULL, + "OEsmall", + "figuredash", + "hyphensuperior", + NULL, + NULL, + NULL, + NULL, + "exclamdownsmall", + NULL, + "Ydieresissmall", + NULL, + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "ninesuperior", + "zerosuperior", + NULL, + "esuperior", + "rsuperior", + "tsuperior", + NULL, + NULL, + "isuperior", + "ssuperior", + "dsuperior", + NULL, + NULL, + NULL, + NULL, + NULL, + "lsuperior", + "Ogoneksmall", + "Brevesmall", + "Macronsmall", + "bsuperior", + "nsuperior", + "msuperior", + "commasuperior", + "periodsuperior", + "Dotaccentsmall", + "Ringsmall", + NULL, + NULL, + NULL, + NULL +}; + +char *winAnsiEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "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", + "grave", + "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", + "bullet", + "Euro", + "bullet", + "quotesinglbase", + "florin", + "quotedblbase", + "ellipsis", + "dagger", + "daggerdbl", + "circumflex", + "perthousand", + "Scaron", + "guilsinglleft", + "OE", + "bullet", + "Zcaron", + "bullet", + "bullet", + "quoteleft", + "quoteright", + "quotedblleft", + "quotedblright", + "bullet", + "endash", + "emdash", + "tilde", + "trademark", + "scaron", + "guilsinglright", + "oe", + "bullet", + "zcaron", + "Ydieresis", + "space", + "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" +}; + +char *standardEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "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", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + NULL, + "endash", + "dagger", + "daggerdbl", + "periodcentered", + NULL, + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + NULL, + "questiondown", + NULL, + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + NULL, + "ring", + "cedilla", + NULL, + "hungarumlaut", + "ogonek", + "caron", + "emdash", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "AE", + NULL, + "ordfeminine", + NULL, + NULL, + NULL, + NULL, + "Lslash", + "Oslash", + "OE", + "ordmasculine", + NULL, + NULL, + NULL, + NULL, + NULL, + "ae", + NULL, + NULL, + NULL, + "dotlessi", + NULL, + NULL, + "lslash", + "oslash", + "oe", + "germandbls", + NULL, + NULL, + NULL, + NULL +}; + +char *expertEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclamsmall", + "Hungarumlautsmall", + NULL, + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + NULL, + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + NULL, + NULL, + NULL, + "isuperior", + NULL, + NULL, + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + NULL, + NULL, + "rsuperior", + "ssuperior", + "tsuperior", + NULL, + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + NULL, + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + NULL, + NULL, + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + NULL, + "Dotaccentsmall", + NULL, + NULL, + "Macronsmall", + NULL, + NULL, + "figuredash", + "hypheninferior", + NULL, + NULL, + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + NULL, + NULL, + NULL, + "onequarter", + "onehalf", + "threequarters", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + NULL, + NULL, + "zerosuperior", + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall" +}; + +char *symbolEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "universal", + "numbersign", + "existential", + "percent", + "ampersand", + "suchthat", + "parenleft", + "parenright", + "asteriskmath", + "plus", + "comma", + "minus", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "congruent", + "Alpha", + "Beta", + "Chi", + "Delta", + "Epsilon", + "Phi", + "Gamma", + "Eta", + "Iota", + "theta1", + "Kappa", + "Lambda", + "Mu", + "Nu", + "Omicron", + "Pi", + "Theta", + "Rho", + "Sigma", + "Tau", + "Upsilon", + "sigma1", + "Omega", + "Xi", + "Psi", + "Zeta", + "bracketleft", + "therefore", + "bracketright", + "perpendicular", + "underscore", + "radicalex", + "alpha", + "beta", + "chi", + "delta", + "epsilon", + "phi", + "gamma", + "eta", + "iota", + "phi1", + "kappa", + "lambda", + "mu", + "nu", + "omicron", + "pi", + "theta", + "rho", + "sigma", + "tau", + "upsilon", + "omega1", + "omega", + "xi", + "psi", + "zeta", + "braceleft", + "bar", + "braceright", + "similar", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Upsilon1", + "minute", + "lessequal", + "fraction", + "infinity", + "florin", + "club", + "diamond", + "heart", + "spade", + "arrowboth", + "arrowleft", + "arrowup", + "arrowright", + "arrowdown", + "degree", + "plusminus", + "second", + "greaterequal", + "multiply", + "proportional", + "partialdiff", + "bullet", + "divide", + "notequal", + "equivalence", + "approxequal", + "ellipsis", + "arrowvertex", + "arrowhorizex", + "carriagereturn", + "aleph", + "Ifraktur", + "Rfraktur", + "weierstrass", + "circlemultiply", + "circleplus", + "emptyset", + "intersection", + "union", + "propersuperset", + "reflexsuperset", + "notsubset", + "propersubset", + "reflexsubset", + "element", + "notelement", + "angle", + "gradient", + "registerserif", + "copyrightserif", + "trademarkserif", + "product", + "radical", + "dotmath", + "logicalnot", + "logicaland", + "logicalor", + "arrowdblboth", + "arrowdblleft", + "arrowdblup", + "arrowdblright", + "arrowdbldown", + "lozenge", + "angleleft", + "registersans", + "copyrightsans", + "trademarksans", + "summation", + "parenlefttp", + "parenleftex", + "parenleftbt", + "bracketlefttp", + "bracketleftex", + "bracketleftbt", + "bracelefttp", + "braceleftmid", + "braceleftbt", + "braceex", + NULL, + "angleright", + "integral", + "integraltp", + "integralex", + "integralbt", + "parenrighttp", + "parenrightex", + "parenrightbt", + "bracketrighttp", + "bracketrightex", + "bracketrightbt", + "bracerighttp", + "bracerightmid", + "bracerightbt", + NULL +}; + +char *zapfDingbatsEncoding[256] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "a1", + "a2", + "a202", + "a3", + "a4", + "a5", + "a119", + "a118", + "a117", + "a11", + "a12", + "a13", + "a14", + "a15", + "a16", + "a105", + "a17", + "a18", + "a19", + "a20", + "a21", + "a22", + "a23", + "a24", + "a25", + "a26", + "a27", + "a28", + "a6", + "a7", + "a8", + "a9", + "a10", + "a29", + "a30", + "a31", + "a32", + "a33", + "a34", + "a35", + "a36", + "a37", + "a38", + "a39", + "a40", + "a41", + "a42", + "a43", + "a44", + "a45", + "a46", + "a47", + "a48", + "a49", + "a50", + "a51", + "a52", + "a53", + "a54", + "a55", + "a56", + "a57", + "a58", + "a59", + "a60", + "a61", + "a62", + "a63", + "a64", + "a65", + "a66", + "a67", + "a68", + "a69", + "a70", + "a71", + "a72", + "a73", + "a74", + "a203", + "a75", + "a204", + "a76", + "a77", + "a78", + "a79", + "a81", + "a82", + "a83", + "a84", + "a97", + "a98", + "a99", + "a100", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "a101", + "a102", + "a103", + "a104", + "a106", + "a107", + "a108", + "a112", + "a111", + "a110", + "a109", + "a120", + "a121", + "a122", + "a123", + "a124", + "a125", + "a126", + "a127", + "a128", + "a129", + "a130", + "a131", + "a132", + "a133", + "a134", + "a135", + "a136", + "a137", + "a138", + "a139", + "a140", + "a141", + "a142", + "a143", + "a144", + "a145", + "a146", + "a147", + "a148", + "a149", + "a150", + "a151", + "a152", + "a153", + "a154", + "a155", + "a156", + "a157", + "a158", + "a159", + "a160", + "a161", + "a163", + "a164", + "a196", + "a165", + "a192", + "a166", + "a167", + "a168", + "a169", + "a170", + "a171", + "a172", + "a173", + "a162", + "a174", + "a175", + "a176", + "a177", + "a178", + "a179", + "a193", + "a180", + "a199", + "a181", + "a200", + "a182", + NULL, + "a201", + "a183", + "a184", + "a197", + "a185", + "a194", + "a198", + "a186", + "a195", + "a187", + "a188", + "a189", + "a190", + "a191", + NULL +}; diff --git a/rosapps/smartpdf/poppler/poppler/FontEncodingTables.h b/rosapps/smartpdf/poppler/poppler/FontEncodingTables.h new file mode 100644 index 00000000000..8b0a1e7e993 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/FontEncodingTables.h @@ -0,0 +1,20 @@ +//======================================================================== +// +// FontEncodingTables.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FONTENCODINGTABLES_H +#define FONTENCODINGTABLES_H + +extern char *macRomanEncoding[]; +extern char *macExpertEncoding[]; +extern char *winAnsiEncoding[]; +extern char *standardEncoding[]; +extern char *expertEncoding[]; +extern char *symbolEncoding[]; +extern char *zapfDingbatsEncoding[]; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/FontInfo.cc b/rosapps/smartpdf/poppler/poppler/FontInfo.cc new file mode 100644 index 00000000000..f0d4df02bc9 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/FontInfo.cc @@ -0,0 +1,212 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include "GlobalParams.h" +#include "Error.h" +#include "Object.h" +#include "Dict.h" +#include "GfxFont.h" +#include "Annot.h" +#include "PDFDoc.h" +#include "FontInfo.h" +#include "UGooString.h" + +FontInfoScanner::FontInfoScanner(PDFDoc *docA) { + doc = docA; + currentPage = 1; + fonts = NULL; + fontsLen = fontsSize = 0; +} + +FontInfoScanner::~FontInfoScanner() { + gfree(fonts); +} + +GooList *FontInfoScanner::scan(int nPages) { + GooList *result; + Page *page; + Dict *resDict; + Annots *annots; + Object obj1, obj2; + int pg, i, lastPage; + + if (currentPage > doc->getNumPages()) { + return NULL; + } + + result = new GooList(); + + lastPage = currentPage + nPages; + if (lastPage > doc->getNumPages()) { + lastPage = doc->getNumPages(); + } + + for (pg = currentPage; pg <= lastPage; ++pg) { + page = doc->getCatalog()->getPage(pg); + if ((resDict = page->getResourceDict())) { + scanFonts(resDict, result); + } + annots = new Annots(doc->getXRef(), doc->getCatalog(), page->getAnnots(&obj1)); + obj1.free(); + for (i = 0; i < annots->getNumAnnots(); ++i) { + if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) { + obj1.streamGetDict()->lookup("Resources", &obj2); + if (obj2.isDict()) { + scanFonts(obj2.getDict(), result); + } + obj2.free(); + } + obj1.free(); + } + delete annots; + } + + currentPage = lastPage + 1; + + return result; +} + +void FontInfoScanner::scanFonts(Dict *resDict, GooList *fontsList) { + Object obj1, obj2, xObjDict, xObj, resObj; + Ref r; + GfxFontDict *gfxFontDict; + GfxFont *font; + int i; + + // scan the fonts in this resource dictionary + gfxFontDict = NULL; + resDict->lookupNF("Font", &obj1); + if (obj1.isRef()) { + obj1.fetch(doc->getXRef(), &obj2); + if (obj2.isDict()) { + r = obj1.getRef(); + gfxFontDict = new GfxFontDict(doc->getXRef(), &r, obj2.getDict()); + } + obj2.free(); + } else if (obj1.isDict()) { + gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict()); + } + if (gfxFontDict) { + for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { + int k; + if ((font = gfxFontDict->getFont(i))) { + Ref fontRef = *font->getID(); + GBool alreadySeen = gFalse; + + // check for an already-seen font + for (k = 0; k < fontsLen; ++k) { + if (fontRef.num == fonts[k].num && fontRef.gen == fonts[k].gen) { + alreadySeen = gTrue; + } + } + + // add this font to the list + if (!alreadySeen) { + fontsList->append(new FontInfo(font, doc)); + if (fontsLen == fontsSize) { + fontsSize += 32; + fonts = (Ref *)grealloc(fonts, fontsSize * sizeof(Ref)); + } + fonts[fontsLen++] = *font->getID(); + } + } + } + delete gfxFontDict; + } + obj1.free(); + + // recursively scan any resource dictionaries in objects in this + // resource dictionary + resDict->lookup("XObject", &xObjDict); + if (xObjDict.isDict()) { + for (i = 0; i < xObjDict.dictGetLength(); ++i) { + xObjDict.dictGetVal(i, &xObj); + if (xObj.isStream()) { + xObj.streamGetDict()->lookup("Resources", &resObj); + if (resObj.isDict()) { + scanFonts(resObj.getDict(), fontsList); + } + resObj.free(); + } + xObj.free(); + } + } + xObjDict.free(); +} + +FontInfo::FontInfo(GfxFont *font, PDFDoc *doc) { + GooString *origName; + Ref embRef; + Object fontObj, toUnicodeObj; + int i; + + fontRef = *font->getID(); + + // font name + origName = font->getOrigName(); + if (origName != NULL) { + name = font->getOrigName()->copy(); + } else { + name = NULL; + } + + // font type + type = (FontInfo::Type)font->getType(); + + // check for an embedded font + if (font->getType() == fontType3) { + emb = gTrue; + } else { + emb = font->getEmbeddedFontID(&embRef); + } + + if (!emb) + { + DisplayFontParam *dfp = globalParams->getDisplayFont(font); + if (dfp) + { + if (dfp->kind == displayFontT1) file = dfp->t1.fileName->copy(); + else file = dfp->tt.fileName->copy(); + } + else file = NULL; + } + else file = NULL; + + // look for a ToUnicode map + hasToUnicode = gFalse; + if (doc->getXRef()->fetch(fontRef.num, fontRef.gen, &fontObj)->isDict()) { + hasToUnicode = fontObj.dictLookup("ToUnicode", &toUnicodeObj)->isStream(); + toUnicodeObj.free(); + } + fontObj.free(); + + // check for a font subset name: capital letters followed by a '+' + // sign + subset = gFalse; + if (name) { + for (i = 0; i < name->getLength(); ++i) { + if (name->getChar(i) < 'A' || name->getChar(i) > 'Z') { + break; + } + } + subset = i > 0 && i < name->getLength() && name->getChar(i) == '+'; + } +} + +FontInfo::FontInfo(FontInfo& f) { + name = f.name ? f.name->copy() : NULL; + file = f.file ? f.file->copy() : NULL; + type = f.type; + emb = f.emb; + subset = f.subset; + hasToUnicode = f.hasToUnicode; + fontRef = f.fontRef; +} + +FontInfo::~FontInfo() { + delete name; + delete file; +} diff --git a/rosapps/smartpdf/poppler/poppler/FontInfo.h b/rosapps/smartpdf/poppler/poppler/FontInfo.h new file mode 100644 index 00000000000..e58237bb7c5 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/FontInfo.h @@ -0,0 +1,65 @@ +#ifndef FONT_INFO_H +#define FONT_INFO_H + +#include "goo/gtypes.h" +#include "goo/GooList.h" + +class FontInfo { +public: + enum Type { + unknown, + Type1, + Type1C, + Type3, + TrueType, + CIDType0, + CIDType0C, + CIDTrueType + }; + + // Constructor. + FontInfo(GfxFont *fontA, PDFDoc *doc); + // Copy constructor + FontInfo(FontInfo& f); + // Destructor. + ~FontInfo(); + + GooString *getName() { return name; }; + GooString *getFile() { return file; }; + Type getType() { return type; }; + GBool getEmbedded() { return emb; }; + GBool getSubset() { return subset; }; + GBool getToUnicode() { return hasToUnicode; }; + +private: + GooString *name; + GooString *file; + Type type; + GBool emb; + GBool subset; + GBool hasToUnicode; + Ref fontRef; +}; + +class FontInfoScanner { +public: + + // Constructor. + FontInfoScanner(PDFDoc *doc); + // Destructor. + ~FontInfoScanner(); + + GooList *scan(int nPages); + +private: + + PDFDoc *doc; + int currentPage; + Ref *fonts; + int fontsLen; + int fontsSize; + + void scanFonts(Dict *resDict, GooList *fontsList); +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Function.cc b/rosapps/smartpdf/poppler/poppler/Function.cc new file mode 100644 index 00000000000..f0f5026ac1e --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Function.cc @@ -0,0 +1,1539 @@ +//======================================================================== +// +// Function.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include "goo/gmem.h" +#include "Object.h" +#include "Dict.h" +#include "Stream.h" +#include "Error.h" +#include "Function.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ +// Function +//------------------------------------------------------------------------ + +Function::Function() { +} + +Function::~Function() { +} + +Function *Function::parse(Object *funcObj) { + Function *func; + Dict *dict; + int funcType; + Object obj1; + + if (funcObj->isStream()) { + dict = funcObj->streamGetDict(); + } else if (funcObj->isDict()) { + dict = funcObj->getDict(); + } else if (funcObj->isName("Identity")) { + return new IdentityFunction(); + } else { + error(-1, "Expected function dictionary or stream"); + return NULL; + } + + if (!dict->lookup("FunctionType", &obj1)->isInt()) { + error(-1, "Function type is missing or wrong type"); + obj1.free(); + return NULL; + } + funcType = obj1.getInt(); + obj1.free(); + + if (funcType == 0) { + func = new SampledFunction(funcObj, dict); + } else if (funcType == 2) { + func = new ExponentialFunction(funcObj, dict); + } else if (funcType == 3) { + func = new StitchingFunction(funcObj, dict); + } else if (funcType == 4) { + func = new PostScriptFunction(funcObj, dict); + } else { + error(-1, "Unimplemented function type (%d)", funcType); + return NULL; + } + if (!func->isOk()) { + delete func; + return NULL; + } + + return func; +} + +GBool Function::init(Dict *dict) { + Object obj1, obj2; + int i; + + //----- Domain + if (!dict->lookup("Domain", &obj1)->isArray()) { + error(-1, "Function is missing domain"); + goto err2; + } + m = obj1.arrayGetLength() / 2; + if (m > funcMaxInputs) { + error(-1, "Functions with more than %d inputs are unsupported", + funcMaxInputs); + goto err2; + } + for (i = 0; i < m; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function domain array"); + goto err1; + } + domain[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function domain array"); + goto err1; + } + domain[i][1] = obj2.getNum(); + obj2.free(); + } + obj1.free(); + + //----- Range + hasRange = gFalse; + n = 0; + if (dict->lookup("Range", &obj1)->isArray()) { + hasRange = gTrue; + n = obj1.arrayGetLength() / 2; + if (n > funcMaxOutputs) { + error(-1, "Functions with more than %d outputs are unsupported", + funcMaxOutputs); + goto err2; + } + for (i = 0; i < n; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function range array"); + goto err1; + } + range[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function range array"); + goto err1; + } + range[i][1] = obj2.getNum(); + obj2.free(); + } + } + obj1.free(); + + return gTrue; + + err1: + obj2.free(); + err2: + obj1.free(); + return gFalse; +} + +//------------------------------------------------------------------------ +// IdentityFunction +//------------------------------------------------------------------------ + +IdentityFunction::IdentityFunction() { + int i; + + // fill these in with arbitrary values just in case they get used + // somewhere + m = funcMaxInputs; + n = funcMaxOutputs; + for (i = 0; i < funcMaxInputs; ++i) { + domain[i][0] = 0; + domain[i][1] = 1; + } + hasRange = gFalse; +} + +IdentityFunction::~IdentityFunction() { +} + +void IdentityFunction::transform(double *in, double *out) { + int i; + + for (i = 0; i < funcMaxOutputs; ++i) { + out[i] = in[i]; + } +} + +//------------------------------------------------------------------------ +// SampledFunction +//------------------------------------------------------------------------ + +SampledFunction::SampledFunction(Object *funcObj, Dict *dict) { + Stream *str; + int sampleBits; + double sampleMul; + Object obj1, obj2; + Guint buf, bitMask; + int bits; + int s; + int i; + + samples = NULL; + ok = gFalse; + + //----- initialize the generic stuff + if (!init(dict)) { + goto err1; + } + if (!hasRange) { + error(-1, "Type 0 function is missing range"); + goto err1; + } + + //----- get the stream + if (!funcObj->isStream()) { + error(-1, "Type 0 function isn't a stream"); + goto err1; + } + str = funcObj->getStream(); + + //----- Size + if (!dict->lookup("Size", &obj1)->isArray() || + obj1.arrayGetLength() != m) { + error(-1, "Function has missing or invalid size array"); + goto err2; + } + for (i = 0; i < m; ++i) { + obj1.arrayGet(i, &obj2); + if (!obj2.isInt()) { + error(-1, "Illegal value in function size array"); + goto err3; + } + sampleSize[i] = obj2.getInt(); + obj2.free(); + } + obj1.free(); + idxMul[0] = n; + for (i = 1; i < m; ++i) { + idxMul[i] = idxMul[i-1] * sampleSize[i-1]; + } + + //----- BitsPerSample + if (!dict->lookup("BitsPerSample", &obj1)->isInt()) { + error(-1, "Function has missing or invalid BitsPerSample"); + goto err2; + } + sampleBits = obj1.getInt(); + sampleMul = 1.0 / (double)((1 << sampleBits) - 1); + obj1.free(); + + //----- Encode + if (dict->lookup("Encode", &obj1)->isArray() && + obj1.arrayGetLength() == 2*m) { + for (i = 0; i < m; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function encode array"); + goto err3; + } + encode[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function encode array"); + goto err3; + } + encode[i][1] = obj2.getNum(); + obj2.free(); + } + } else { + for (i = 0; i < m; ++i) { + encode[i][0] = 0; + encode[i][1] = sampleSize[i] - 1; + } + } + obj1.free(); + for (i = 0; i < m; ++i) { + inputMul[i] = (encode[i][1] - encode[i][0]) / + (domain[i][1] - domain[i][0]); + } + + //----- Decode + if (dict->lookup("Decode", &obj1)->isArray() && + obj1.arrayGetLength() == 2*n) { + for (i = 0; i < n; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function decode array"); + goto err3; + } + decode[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function decode array"); + goto err3; + } + decode[i][1] = obj2.getNum(); + obj2.free(); + } + } else { + for (i = 0; i < n; ++i) { + decode[i][0] = range[i][0]; + decode[i][1] = range[i][1]; + } + } + obj1.free(); + + //----- samples + nSamples = n; + for (i = 0; i < m; ++i) + nSamples *= sampleSize[i]; + samples = (double *)gmallocn(nSamples, sizeof(double)); + buf = 0; + bits = 0; + bitMask = (1 << sampleBits) - 1; + str->reset(); + for (i = 0; i < nSamples; ++i) { + if (sampleBits == 8) { + s = str->getChar(); + } else if (sampleBits == 16) { + s = str->getChar(); + s = (s << 8) + str->getChar(); + } else if (sampleBits == 32) { + s = str->getChar(); + s = (s << 8) + str->getChar(); + s = (s << 8) + str->getChar(); + s = (s << 8) + str->getChar(); + } else { + while (bits < sampleBits) { + buf = (buf << 8) | (str->getChar() & 0xff); + bits += 8; + } + s = (buf >> (bits - sampleBits)) & bitMask; + bits -= sampleBits; + } + samples[i] = (double)s * sampleMul; + } + str->close(); + + ok = gTrue; + return; + + err3: + obj2.free(); + err2: + obj1.free(); + err1: + return; +} + +SampledFunction::~SampledFunction() { + if (samples) { + gfree(samples); + } +} + +SampledFunction::SampledFunction(SampledFunction *func) { + memcpy(this, func, sizeof(SampledFunction)); + samples = (double *)gmallocn(nSamples, sizeof(double)); + memcpy(samples, func->samples, nSamples * sizeof(double)); +} + +void SampledFunction::transform(double *in, double *out) { + double x; + int e[funcMaxInputs][2]; + double efrac0[funcMaxInputs]; + double efrac1[funcMaxInputs]; + double s[1 << funcMaxInputs]; + int i, j, k, idx, t; + + // map input values into sample array + for (i = 0; i < m; ++i) { + x = (in[i] - domain[i][0]) * inputMul[i] + encode[i][0]; + if (x < 0) { + x = 0; + } else if (x > sampleSize[i] - 1) { + x = sampleSize[i] - 1; + } + e[i][0] = (int)x; + if ((e[i][1] = e[i][0] + 1) >= sampleSize[i]) { + // this happens if in[i] = domain[i][1] + e[i][1] = e[i][0]; + } + efrac1[i] = x - e[i][0]; + efrac0[i] = 1 - efrac1[i]; + } + + // for each output, do m-linear interpolation + for (i = 0; i < n; ++i) { + + // pull 2^m values out of the sample array + for (j = 0; j < (1<>= 1) { + idx += idxMul[k] * (e[k][t & 1]); + } + if (idx >= 0 && idx < nSamples) s[j] = samples[idx]; + } + + // do m sets of interpolations + for (j = 0, t = (1<>= 1) { + for (k = 0; k < t; k += 2) { + s[k >> 1] = efrac0[j] * s[k] + efrac1[j] * s[k+1]; + } + } + + // map output value to range + out[i] = s[0] * (decode[i][1] - decode[i][0]) + decode[i][0]; + if (out[i] < range[i][0]) { + out[i] = range[i][0]; + } else if (out[i] > range[i][1]) { + out[i] = range[i][1]; + } + } +} + +//------------------------------------------------------------------------ +// ExponentialFunction +//------------------------------------------------------------------------ + +ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { + Object obj1, obj2; + int i; + + ok = gFalse; + + //----- initialize the generic stuff + if (!init(dict)) { + goto err1; + } + if (m != 1) { + error(-1, "Exponential function with more than one input"); + goto err1; + } + + //----- C0 + if (dict->lookup("C0", &obj1)->isArray()) { + if (hasRange && obj1.arrayGetLength() != n) { + error(-1, "Function's C0 array is wrong length"); + goto err2; + } + n = obj1.arrayGetLength(); + for (i = 0; i < n; ++i) { + obj1.arrayGet(i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function C0 array"); + goto err3; + } + c0[i] = obj2.getNum(); + obj2.free(); + } + } else { + if (hasRange && n != 1) { + error(-1, "Function's C0 array is wrong length"); + goto err2; + } + n = 1; + c0[0] = 0; + } + obj1.free(); + + //----- C1 + if (dict->lookup("C1", &obj1)->isArray()) { + if (obj1.arrayGetLength() != n) { + error(-1, "Function's C1 array is wrong length"); + goto err2; + } + for (i = 0; i < n; ++i) { + obj1.arrayGet(i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function C1 array"); + goto err3; + } + c1[i] = obj2.getNum(); + obj2.free(); + } + } else { + if (n != 1) { + error(-1, "Function's C1 array is wrong length"); + goto err2; + } + c1[0] = 1; + } + obj1.free(); + + //----- N (exponent) + if (!dict->lookup("N", &obj1)->isNum()) { + error(-1, "Function has missing or invalid N"); + goto err2; + } + e = obj1.getNum(); + obj1.free(); + + ok = gTrue; + return; + + err3: + obj2.free(); + err2: + obj1.free(); + err1: + return; +} + +ExponentialFunction::~ExponentialFunction() { +} + +ExponentialFunction::ExponentialFunction(ExponentialFunction *func) { + memcpy(this, func, sizeof(ExponentialFunction)); +} + +void ExponentialFunction::transform(double *in, double *out) { + double x; + int i; + + if (in[0] < domain[0][0]) { + x = domain[0][0]; + } else if (in[0] > domain[0][1]) { + x = domain[0][1]; + } else { + x = in[0]; + } + for (i = 0; i < n; ++i) { + out[i] = c0[i] + pow(x, e) * (c1[i] - c0[i]); + if (hasRange) { + if (out[i] < range[i][0]) { + out[i] = range[i][0]; + } else if (out[i] > range[i][1]) { + out[i] = range[i][1]; + } + } + } + return; +} + +//------------------------------------------------------------------------ +// StitchingFunction +//------------------------------------------------------------------------ + +StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) { + Object obj1, obj2; + int i; + + ok = gFalse; + funcs = NULL; + bounds = NULL; + encode = NULL; + + //----- initialize the generic stuff + if (!init(dict)) { + goto err1; + } + if (m != 1) { + error(-1, "Stitching function with more than one input"); + goto err1; + } + + //----- Functions + if (!dict->lookup("Functions", &obj1)->isArray()) { + error(-1, "Missing 'Functions' entry in stitching function"); + goto err1; + } + k = obj1.arrayGetLength(); + funcs = (Function **)gmallocn(k, sizeof(Function *)); + bounds = (double *)gmallocn(k + 1, sizeof(double)); + encode = (double *)gmallocn(2 * k, sizeof(double)); + for (i = 0; i < k; ++i) { + funcs[i] = NULL; + } + for (i = 0; i < k; ++i) { + if (!(funcs[i] = Function::parse(obj1.arrayGet(i, &obj2)))) { + goto err2; + } + if (i > 0 && (funcs[i]->getInputSize() != 1 || + funcs[i]->getOutputSize() != funcs[0]->getOutputSize())) { + error(-1, "Incompatible subfunctions in stitching function"); + goto err2; + } + obj2.free(); + } + obj1.free(); + + //----- Bounds + if (!dict->lookup("Bounds", &obj1)->isArray() || + obj1.arrayGetLength() != k - 1) { + error(-1, "Missing or invalid 'Bounds' entry in stitching function"); + goto err1; + } + bounds[0] = domain[0][0]; + for (i = 1; i < k; ++i) { + if (!obj1.arrayGet(i - 1, &obj2)->isNum()) { + error(-1, "Invalid type in 'Bounds' array in stitching function"); + goto err2; + } + bounds[i] = obj2.getNum(); + obj2.free(); + } + bounds[k] = domain[0][1]; + obj1.free(); + + //----- Encode + if (!dict->lookup("Encode", &obj1)->isArray() || + obj1.arrayGetLength() != 2 * k) { + error(-1, "Missing or invalid 'Encode' entry in stitching function"); + goto err1; + } + for (i = 0; i < 2 * k; ++i) { + if (!obj1.arrayGet(i, &obj2)->isNum()) { + error(-1, "Invalid type in 'Encode' array in stitching function"); + goto err2; + } + encode[i] = obj2.getNum(); + obj2.free(); + } + obj1.free(); + + ok = gTrue; + return; + + err2: + obj2.free(); + err1: + obj1.free(); +} + +StitchingFunction::StitchingFunction(StitchingFunction *func) { + int i; + + k = func->k; + funcs = (Function **)gmallocn(k, sizeof(Function *)); + for (i = 0; i < k; ++i) { + funcs[i] = func->funcs[i]->copy(); + } + bounds = (double *)gmallocn(k + 1, sizeof(double)); + memcpy(bounds, func->bounds, (k + 1) * sizeof(double)); + encode = (double *)gmallocn(2 * k, sizeof(double)); + memcpy(encode, func->encode, 2 * k * sizeof(double)); + ok = gTrue; +} + +StitchingFunction::~StitchingFunction() { + int i; + + if (funcs) { + for (i = 0; i < k; ++i) { + if (funcs[i]) { + delete funcs[i]; + } + } + } + gfree(funcs); + gfree(bounds); + gfree(encode); +} + +void StitchingFunction::transform(double *in, double *out) { + double x; + int i; + + if (in[0] < domain[0][0]) { + x = domain[0][0]; + } else if (in[0] > domain[0][1]) { + x = domain[0][1]; + } else { + x = in[0]; + } + for (i = 0; i < k - 1; ++i) { + if (x < bounds[i+1]) { + break; + } + } + x = encode[2*i] + ((x - bounds[i]) / (bounds[i+1] - bounds[i])) * + (encode[2*i+1] - encode[2*i]); + funcs[i]->transform(&x, out); +} + +//------------------------------------------------------------------------ +// PostScriptFunction +//------------------------------------------------------------------------ + +enum PSOp { + psOpAbs, + psOpAdd, + psOpAnd, + psOpAtan, + psOpBitshift, + psOpCeiling, + psOpCopy, + psOpCos, + psOpCvi, + psOpCvr, + psOpDiv, + psOpDup, + psOpEq, + psOpExch, + psOpExp, + psOpFalse, + psOpFloor, + psOpGe, + psOpGt, + psOpIdiv, + psOpIndex, + psOpLe, + psOpLn, + psOpLog, + psOpLt, + psOpMod, + psOpMul, + psOpNe, + psOpNeg, + psOpNot, + psOpOr, + psOpPop, + psOpRoll, + psOpRound, + psOpSin, + psOpSqrt, + psOpSub, + psOpTrue, + psOpTruncate, + psOpXor, + psOpIf, + psOpIfelse, + psOpReturn +}; + +// Note: 'if' and 'ifelse' are parsed separately. +// The rest are listed here in alphabetical order. +// The index in this table is equivalent to the entry in PSOp. +char *psOpNames[] = { + "abs", + "add", + "and", + "atan", + "bitshift", + "ceiling", + "copy", + "cos", + "cvi", + "cvr", + "div", + "dup", + "eq", + "exch", + "exp", + "false", + "floor", + "ge", + "gt", + "idiv", + "index", + "le", + "ln", + "log", + "lt", + "mod", + "mul", + "ne", + "neg", + "not", + "or", + "pop", + "roll", + "round", + "sin", + "sqrt", + "sub", + "true", + "truncate", + "xor" +}; + +#define nPSOps (sizeof(psOpNames) / sizeof(char *)) + +enum PSObjectType { + psBool, + psInt, + psReal, + psOperator, + psBlock +}; + +// In the code array, 'if'/'ifelse' operators take up three slots +// plus space for the code in the subclause(s). +// +// +---------------------------------+ +// | psOperator: psOpIf / psOpIfelse | +// +---------------------------------+ +// | psBlock: ptr= | +// +---------------------------------+ +// | psBlock: ptr= | +// +---------------------------------+ +// | if clause | +// | ... | +// | psOperator: psOpReturn | +// +---------------------------------+ +// | else clause | +// | ... | +// | psOperator: psOpReturn | +// +---------------------------------+ +// | ... | +// +// For 'if', pointer is present in the code stream but unused. + +struct PSObject { + PSObjectType type; + union { + GBool booln; // boolean (stack only) + int intg; // integer (stack and code) + double real; // real (stack and code) + PSOp op; // operator (code only) + int blk; // if/ifelse block pointer (code only) + }; +}; + +#define psStackSize 100 + +class PSStack { +public: + + PSStack() { sp = psStackSize; } + void pushBool(GBool booln); + void pushInt(int intg); + void pushReal(double real); + GBool popBool(); + int popInt(); + double popNum(); + GBool empty() { return sp == psStackSize; } + GBool topIsInt() { return sp < psStackSize && stack[sp].type == psInt; } + GBool topTwoAreInts() + { return sp < psStackSize - 1 && + stack[sp].type == psInt && + stack[sp+1].type == psInt; } + GBool topIsReal() { return sp < psStackSize && stack[sp].type == psReal; } + GBool topTwoAreNums() + { return sp < psStackSize - 1 && + (stack[sp].type == psInt || stack[sp].type == psReal) && + (stack[sp+1].type == psInt || stack[sp+1].type == psReal); } + void copy(int n); + void roll(int n, int j); + void index(int i); + void pop(); + +private: + + GBool checkOverflow(int n = 1); + GBool checkUnderflow(); + GBool checkType(PSObjectType t1, PSObjectType t2); + + PSObject stack[psStackSize]; + int sp; +}; + +GBool PSStack::checkOverflow(int n) { + if (sp - n < 0) { + error(-1, "Stack overflow in PostScript function"); + return gFalse; + } + return gTrue; +} + +GBool PSStack::checkUnderflow() { + if (sp == psStackSize) { + error(-1, "Stack underflow in PostScript function"); + return gFalse; + } + return gTrue; +} + +GBool PSStack::checkType(PSObjectType t1, PSObjectType t2) { + if (stack[sp].type != t1 && stack[sp].type != t2) { + error(-1, "Type mismatch in PostScript function"); + return gFalse; + } + return gTrue; +} + +void PSStack::pushBool(GBool booln) { + if (checkOverflow()) { + stack[--sp].type = psBool; + stack[sp].booln = booln; + } +} + +void PSStack::pushInt(int intg) { + if (checkOverflow()) { + stack[--sp].type = psInt; + stack[sp].intg = intg; + } +} + +void PSStack::pushReal(double real) { + if (checkOverflow()) { + stack[--sp].type = psReal; + stack[sp].real = real; + } +} + +GBool PSStack::popBool() { + if (checkUnderflow() && checkType(psBool, psBool)) { + return stack[sp++].booln; + } + return gFalse; +} + +int PSStack::popInt() { + if (checkUnderflow() && checkType(psInt, psInt)) { + return stack[sp++].intg; + } + return 0; +} + +double PSStack::popNum() { + double ret; + + if (checkUnderflow() && checkType(psInt, psReal)) { + ret = (stack[sp].type == psInt) ? (double)stack[sp].intg : stack[sp].real; + ++sp; + return ret; + } + return 0; +} + +void PSStack::copy(int n) { + int i; + + if (sp + n > psStackSize) { + error(-1, "Stack underflow in PostScript function"); + return; + } + if (!checkOverflow(n)) { + return; + } + for (i = sp + n - 1; i >= sp; --i) { + stack[i - n] = stack[i]; + } + sp -= n; +} + +void PSStack::roll(int n, int j) { + PSObject obj; + int i, k; + + if (j >= 0) { + j %= n; + } else { + j = -j % n; + if (j != 0) { + j = n - j; + } + } + if (n <= 0 || j == 0) { + return; + } + for (i = 0; i < j; ++i) { + obj = stack[sp]; + for (k = sp; k < sp + n - 1; ++k) { + stack[k] = stack[k+1]; + } + stack[sp + n - 1] = obj; + } +} + +void PSStack::index(int i) { + if (!checkOverflow()) { + return; + } + --sp; + stack[sp] = stack[sp + 1 + i]; +} + +void PSStack::pop() { + if (!checkUnderflow()) { + return; + } + ++sp; +} + +PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) { + Stream *str; + int codePtr; + GooString *tok; + + code = NULL; + codeString = NULL; + codeSize = 0; + ok = gFalse; + + //----- initialize the generic stuff + if (!init(dict)) { + goto err1; + } + if (!hasRange) { + error(-1, "Type 4 function is missing range"); + goto err1; + } + + //----- get the stream + if (!funcObj->isStream()) { + error(-1, "Type 4 function isn't a stream"); + goto err1; + } + str = funcObj->getStream(); + + //----- parse the function + codeString = new GooString(); + str->reset(); + if (!(tok = getToken(str)) || tok->cmp("{")) { + error(-1, "Expected '{' at start of PostScript function"); + if (tok) { + delete tok; + } + goto err1; + } + delete tok; + codePtr = 0; + if (!parseCode(str, &codePtr)) { + goto err2; + } + str->close(); + + ok = gTrue; + + err2: + str->close(); + err1: + return; +} + +PostScriptFunction::PostScriptFunction(PostScriptFunction *func) { + memcpy(this, func, sizeof(PostScriptFunction)); + code = (PSObject *)gmallocn(codeSize, sizeof(PSObject)); + memcpy(code, func->code, codeSize * sizeof(PSObject)); + codeString = func->codeString->copy(); +} + +PostScriptFunction::~PostScriptFunction() { + gfree(code); + delete codeString; +} + +void PostScriptFunction::transform(double *in, double *out) { + PSStack *stack; + int i; + + stack = new PSStack(); + for (i = 0; i < m; ++i) { + //~ may need to check for integers here + stack->pushReal(in[i]); + } + exec(stack, 0); + for (i = n - 1; i >= 0; --i) { + out[i] = stack->popNum(); + if (out[i] < range[i][0]) { + out[i] = range[i][0]; + } else if (out[i] > range[i][1]) { + out[i] = range[i][1]; + } + } + // if (!stack->empty()) { + // error(-1, "Extra values on stack at end of PostScript function"); + // } + delete stack; +} + +GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) { + GooString *tok; + char *p; + GBool isReal; + int opPtr, elsePtr; + int a, b, mid, cmp; + + while (1) { + if (!(tok = getToken(str))) { + error(-1, "Unexpected end of PostScript function stream"); + return gFalse; + } + p = tok->getCString(); + if (isdigit(*p) || *p == '.' || *p == '-') { + isReal = gFalse; + for (++p; *p; ++p) { + if (*p == '.') { + isReal = gTrue; + break; + } + } + resizeCode(*codePtr); + if (isReal) { + code[*codePtr].type = psReal; + code[*codePtr].real = atof(tok->getCString()); + } else { + code[*codePtr].type = psInt; + code[*codePtr].intg = atoi(tok->getCString()); + } + ++*codePtr; + delete tok; + } else if (!tok->cmp("{")) { + delete tok; + opPtr = *codePtr; + *codePtr += 3; + resizeCode(opPtr + 2); + if (!parseCode(str, codePtr)) { + return gFalse; + } + if (!(tok = getToken(str))) { + error(-1, "Unexpected end of PostScript function stream"); + return gFalse; + } + if (!tok->cmp("{")) { + elsePtr = *codePtr; + delete tok; + if (!parseCode(str, codePtr)) { + return gFalse; + } + if (!(tok = getToken(str))) { + error(-1, "Unexpected end of PostScript function stream"); + return gFalse; + } + } else { + elsePtr = -1; + } + if (!tok->cmp("if")) { + if (elsePtr >= 0) { + error(-1, "Got 'if' operator with two blocks in PostScript function"); + delete tok; + return gFalse; + } + code[opPtr].type = psOperator; + code[opPtr].op = psOpIf; + code[opPtr+2].type = psBlock; + code[opPtr+2].blk = *codePtr; + } else if (!tok->cmp("ifelse")) { + if (elsePtr < 0) { + error(-1, "Got 'ifelse' operator with one blocks in PostScript function"); + delete tok; + return gFalse; + } + code[opPtr].type = psOperator; + code[opPtr].op = psOpIfelse; + code[opPtr+1].type = psBlock; + code[opPtr+1].blk = elsePtr; + code[opPtr+2].type = psBlock; + code[opPtr+2].blk = *codePtr; + } else { + error(-1, "Expected if/ifelse operator in PostScript function"); + delete tok; + return gFalse; + } + delete tok; + } else if (!tok->cmp("}")) { + delete tok; + resizeCode(*codePtr); + code[*codePtr].type = psOperator; + code[*codePtr].op = psOpReturn; + ++*codePtr; + break; + } else { + a = -1; + b = nPSOps; + // invariant: psOpNames[a] < tok < psOpNames[b] + while (b - a > 1) { + mid = (a + b) / 2; + cmp = tok->cmp(psOpNames[mid]); + if (cmp > 0) { + a = mid; + } else if (cmp < 0) { + b = mid; + } else { + a = b = mid; + } + } + if (cmp != 0) { + error(-1, "Unknown operator '%s' in PostScript function", + tok->getCString()); + delete tok; + return gFalse; + } + delete tok; + resizeCode(*codePtr); + code[*codePtr].type = psOperator; + code[*codePtr].op = (PSOp)a; + ++*codePtr; + } + } + return gTrue; +} + +GooString *PostScriptFunction::getToken(Stream *str) { + GooString *s; + int c; + + s = new GooString(); + do { + c = str->getChar(); + if (c != EOF) { + codeString->append(c); + } + } while (c != EOF && isspace(c)); + if (c == '{' || c == '}') { + s->append((char)c); + } else if (isdigit(c) || c == '.' || c == '-') { + while (1) { + s->append((char)c); + c = str->lookChar(); + if (c == EOF || !(isdigit(c) || c == '.' || c == '-')) { + break; + } + str->getChar(); + codeString->append(c); + } + } else { + while (1) { + s->append((char)c); + c = str->lookChar(); + if (c == EOF || !isalnum(c)) { + break; + } + str->getChar(); + codeString->append(c); + } + } + return s; +} + +void PostScriptFunction::resizeCode(int newSize) { + if (newSize >= codeSize) { + codeSize += 64; + code = (PSObject *)greallocn(code, codeSize, sizeof(PSObject)); + } +} + +void PostScriptFunction::exec(PSStack *stack, int codePtr) { + int i1, i2; + double r1, r2; + GBool b1, b2; + + while (1) { + switch (code[codePtr].type) { + case psInt: + stack->pushInt(code[codePtr++].intg); + break; + case psReal: + stack->pushReal(code[codePtr++].real); + break; + case psOperator: + switch (code[codePtr++].op) { + case psOpAbs: + if (stack->topIsInt()) { + stack->pushInt(abs(stack->popInt())); + } else { + stack->pushReal(fabs(stack->popNum())); + } + break; + case psOpAdd: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushInt(i1 + i2); + } else { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushReal(r1 + r2); + } + break; + case psOpAnd: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushInt(i1 & i2); + } else { + b2 = stack->popBool(); + b1 = stack->popBool(); + stack->pushBool(b1 && b2); + } + break; + case psOpAtan: + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushReal(atan2(r1, r2)); + break; + case psOpBitshift: + i2 = stack->popInt(); + i1 = stack->popInt(); + if (i2 > 0) { + stack->pushInt(i1 << i2); + } else if (i2 < 0) { + stack->pushInt((int)((Guint)i1 >> i2)); + } else { + stack->pushInt(i1); + } + break; + case psOpCeiling: + if (!stack->topIsInt()) { + stack->pushReal(ceil(stack->popNum())); + } + break; + case psOpCopy: + stack->copy(stack->popInt()); + break; + case psOpCos: + stack->pushReal(cos(stack->popNum())); + break; + case psOpCvi: + if (!stack->topIsInt()) { + stack->pushInt((int)stack->popNum()); + } + break; + case psOpCvr: + if (!stack->topIsReal()) { + stack->pushReal(stack->popNum()); + } + break; + case psOpDiv: + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushReal(r1 / r2); + break; + case psOpDup: + stack->copy(1); + break; + case psOpEq: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushBool(i1 == i2); + } else if (stack->topTwoAreNums()) { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushBool(r1 == r2); + } else { + b2 = stack->popBool(); + b1 = stack->popBool(); + stack->pushBool(b1 == b2); + } + break; + case psOpExch: + stack->roll(2, 1); + break; + case psOpExp: + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushReal(pow(r1, r2)); + break; + case psOpFalse: + stack->pushBool(gFalse); + break; + case psOpFloor: + if (!stack->topIsInt()) { + stack->pushReal(floor(stack->popNum())); + } + break; + case psOpGe: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushBool(i1 >= i2); + } else { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushBool(r1 >= r2); + } + break; + case psOpGt: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushBool(i1 > i2); + } else { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushBool(r1 > r2); + } + break; + case psOpIdiv: + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushInt(i1 / i2); + break; + case psOpIndex: + stack->index(stack->popInt()); + break; + case psOpLe: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushBool(i1 <= i2); + } else { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushBool(r1 <= r2); + } + break; + case psOpLn: + stack->pushReal(log(stack->popNum())); + break; + case psOpLog: + stack->pushReal(log10(stack->popNum())); + break; + case psOpLt: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushBool(i1 < i2); + } else { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushBool(r1 < r2); + } + break; + case psOpMod: + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushInt(i1 % i2); + break; + case psOpMul: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + //~ should check for out-of-range, and push a real instead + stack->pushInt(i1 * i2); + } else { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushReal(r1 * r2); + } + break; + case psOpNe: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushBool(i1 != i2); + } else if (stack->topTwoAreNums()) { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushBool(r1 != r2); + } else { + b2 = stack->popBool(); + b1 = stack->popBool(); + stack->pushBool(b1 != b2); + } + break; + case psOpNeg: + if (stack->topIsInt()) { + stack->pushInt(-stack->popInt()); + } else { + stack->pushReal(-stack->popNum()); + } + break; + case psOpNot: + if (stack->topIsInt()) { + stack->pushInt(~stack->popInt()); + } else { + stack->pushBool(!stack->popBool()); + } + break; + case psOpOr: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushInt(i1 | i2); + } else { + b2 = stack->popBool(); + b1 = stack->popBool(); + stack->pushBool(b1 || b2); + } + break; + case psOpPop: + stack->pop(); + break; + case psOpRoll: + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->roll(i1, i2); + break; + case psOpRound: + if (!stack->topIsInt()) { + r1 = stack->popNum(); + stack->pushReal((r1 >= 0) ? floor(r1 + 0.5) : ceil(r1 - 0.5)); + } + break; + case psOpSin: + stack->pushReal(sin(stack->popNum())); + break; + case psOpSqrt: + stack->pushReal(sqrt(stack->popNum())); + break; + case psOpSub: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushInt(i1 - i2); + } else { + r2 = stack->popNum(); + r1 = stack->popNum(); + stack->pushReal(r1 - r2); + } + break; + case psOpTrue: + stack->pushBool(gTrue); + break; + case psOpTruncate: + if (!stack->topIsInt()) { + r1 = stack->popNum(); + stack->pushReal((r1 >= 0) ? floor(r1) : ceil(r1)); + } + break; + case psOpXor: + if (stack->topTwoAreInts()) { + i2 = stack->popInt(); + i1 = stack->popInt(); + stack->pushInt(i1 ^ i2); + } else { + b2 = stack->popBool(); + b1 = stack->popBool(); + stack->pushBool(b1 ^ b2); + } + break; + case psOpIf: + b1 = stack->popBool(); + if (b1) { + exec(stack, codePtr + 2); + } + codePtr = code[codePtr + 1].blk; + break; + case psOpIfelse: + b1 = stack->popBool(); + if (b1) { + exec(stack, codePtr + 2); + } else { + exec(stack, code[codePtr].blk); + } + codePtr = code[codePtr + 1].blk; + break; + case psOpReturn: + return; + } + break; + default: + error(-1, "Internal: bad object in PostScript function code"); + break; + } + } +} diff --git a/rosapps/smartpdf/poppler/poppler/Function.h b/rosapps/smartpdf/poppler/poppler/Function.h new file mode 100644 index 00000000000..0fd71f4d3f0 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Function.h @@ -0,0 +1,223 @@ +//======================================================================== +// +// Function.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef FUNCTION_H +#define FUNCTION_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "Object.h" + +class Dict; +class Stream; +struct PSObject; +class PSStack; + +//------------------------------------------------------------------------ +// Function +//------------------------------------------------------------------------ + +#define funcMaxInputs 8 +#define funcMaxOutputs 32 + +class Function { +public: + + Function(); + + virtual ~Function(); + + // Construct a function. Returns NULL if unsuccessful. + static Function *parse(Object *funcObj); + + // Initialize the entries common to all function types. + GBool init(Dict *dict); + + virtual Function *copy() = 0; + + // Return the function type: + // -1 : identity + // 0 : sampled + // 2 : exponential + // 3 : stitching + // 4 : PostScript + virtual int getType() = 0; + + // Return size of input and output tuples. + int getInputSize() { return m; } + int getOutputSize() { return n; } + + double getDomainMin(int i) { return domain[i][0]; } + double getDomainMax(int i) { return domain[i][1]; } + double getRangeMin(int i) { return range[i][0]; } + double getRangeMax(int i) { return range[i][1]; } + GBool getHasRange() { return hasRange; } + + // Transform an input tuple into an output tuple. + virtual void transform(double *in, double *out) = 0; + + virtual GBool isOk() = 0; + +protected: + + int m, n; // size of input and output tuples + double // min and max values for function domain + domain[funcMaxInputs][2]; + double // min and max values for function range + range[funcMaxOutputs][2]; + GBool hasRange; // set if range is defined +}; + +//------------------------------------------------------------------------ +// IdentityFunction +//------------------------------------------------------------------------ + +class IdentityFunction: public Function { +public: + + IdentityFunction(); + virtual ~IdentityFunction(); + virtual Function *copy() { return new IdentityFunction(); } + virtual int getType() { return -1; } + virtual void transform(double *in, double *out); + virtual GBool isOk() { return gTrue; } + +private: +}; + +//------------------------------------------------------------------------ +// SampledFunction +//------------------------------------------------------------------------ + +class SampledFunction: public Function { +public: + + SampledFunction(Object *funcObj, Dict *dict); + virtual ~SampledFunction(); + virtual Function *copy() { return new SampledFunction(this); } + virtual int getType() { return 0; } + virtual void transform(double *in, double *out); + virtual GBool isOk() { return ok; } + + int getSampleSize(int i) { return sampleSize[i]; } + double getEncodeMin(int i) { return encode[i][0]; } + double getEncodeMax(int i) { return encode[i][1]; } + double getDecodeMin(int i) { return decode[i][0]; } + double getDecodeMax(int i) { return decode[i][1]; } + double *getSamples() { return samples; } + +private: + + SampledFunction(SampledFunction *func); + + int // number of samples for each domain element + sampleSize[funcMaxInputs]; + double // min and max values for domain encoder + encode[funcMaxInputs][2]; + double // min and max values for range decoder + decode[funcMaxOutputs][2]; + double // input multipliers + inputMul[funcMaxInputs]; + int idxMul[funcMaxInputs]; // sample array index multipliers + double *samples; // the samples + int nSamples; // size of the samples array + GBool ok; +}; + +//------------------------------------------------------------------------ +// ExponentialFunction +//------------------------------------------------------------------------ + +class ExponentialFunction: public Function { +public: + + ExponentialFunction(Object *funcObj, Dict *dict); + virtual ~ExponentialFunction(); + virtual Function *copy() { return new ExponentialFunction(this); } + virtual int getType() { return 2; } + virtual void transform(double *in, double *out); + virtual GBool isOk() { return ok; } + + double *getC0() { return c0; } + double *getC1() { return c1; } + double getE() { return e; } + +private: + + ExponentialFunction(ExponentialFunction *func); + + double c0[funcMaxOutputs]; + double c1[funcMaxOutputs]; + double e; + GBool ok; +}; + +//------------------------------------------------------------------------ +// StitchingFunction +//------------------------------------------------------------------------ + +class StitchingFunction: public Function { +public: + + StitchingFunction(Object *funcObj, Dict *dict); + virtual ~StitchingFunction(); + virtual Function *copy() { return new StitchingFunction(this); } + virtual int getType() { return 3; } + virtual void transform(double *in, double *out); + virtual GBool isOk() { return ok; } + + int getNumFuncs() { return k; } + Function *getFunc(int i) { return funcs[i]; } + double *getBounds() { return bounds; } + double *getEncode() { return encode; } + +private: + + StitchingFunction(StitchingFunction *func); + + int k; + Function **funcs; + double *bounds; + double *encode; + GBool ok; +}; + +//------------------------------------------------------------------------ +// PostScriptFunction +//------------------------------------------------------------------------ + +class PostScriptFunction: public Function { +public: + + PostScriptFunction(Object *funcObj, Dict *dict); + virtual ~PostScriptFunction(); + virtual Function *copy() { return new PostScriptFunction(this); } + virtual int getType() { return 4; } + virtual void transform(double *in, double *out); + virtual GBool isOk() { return ok; } + + GooString *getCodeString() { return codeString; } + +private: + + PostScriptFunction(PostScriptFunction *func); + GBool parseCode(Stream *str, int *codePtr); + GooString *getToken(Stream *str); + void resizeCode(int newSize); + void exec(PSStack *stack, int codePtr); + + GooString *codeString; + PSObject *code; + int codeSize; + GBool ok; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Gfx.cc b/rosapps/smartpdf/poppler/poppler/Gfx.cc new file mode 100644 index 00000000000..1e4642cc892 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Gfx.cc @@ -0,0 +1,3651 @@ +//======================================================================== +// +// Gfx.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "goo/gmem.h" +#include "goo/GooTimer.h" +#include "goo/GooHash.h" +#include "GlobalParams.h" +#include "CharTypes.h" +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Stream.h" +#include "Lexer.h" +#include "Parser.h" +#include "GfxFont.h" +#include "GfxState.h" +#include "OutputDev.h" +#include "Page.h" +#include "Error.h" +#include "Gfx.h" +#include "ProfileData.h" +#include "UGooString.h" + +// the MSVC math.h doesn't define this +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +//------------------------------------------------------------------------ +// constants +//------------------------------------------------------------------------ + +// Max recursive depth for a function shading fill. +#define functionMaxDepth 6 + +// Max delta allowed in any color component for a function shading fill. +#define functionColorDelta (dblToCol(1 / 256.0)) + +// Max number of splits along the t axis for an axial shading fill. +#define axialMaxSplits 256 + +// Max delta allowed in any color component for an axial shading fill. +#define axialColorDelta (dblToCol(1 / 256.0)) + +// Max number of splits along the t axis for a radial shading fill. +#define radialMaxSplits 256 + +// Max delta allowed in any color component for a radial shading fill. +#define radialColorDelta (dblToCol(1 / 256.0)) + +// Max recursive depth for a Gouraud triangle shading fill. +#define gouraudMaxDepth 4 + +// Max delta allowed in any color component for a Gouraud triangle +// shading fill. +#define gouraudColorDelta (dblToCol(1 / 256.0)) + +// Max recursive depth for a patch mesh shading fill. +#define patchMaxDepth 6 + +// Max delta allowed in any color component for a patch mesh shading +// fill. +#define patchColorDelta (dblToCol(1 / 256.0)) + +//------------------------------------------------------------------------ +// Operator table +//------------------------------------------------------------------------ + +#ifdef WIN32 // this works around a bug in the VC7 compiler +# pragma optimize("",off) +#endif + +Operator Gfx::opTab[] = { + {"\"", 3, {tchkNum, tchkNum, tchkString}, + &Gfx::opMoveSetShowText}, + {"'", 1, {tchkString}, + &Gfx::opMoveShowText}, + {"B", 0, {tchkNone}, + &Gfx::opFillStroke}, + {"B*", 0, {tchkNone}, + &Gfx::opEOFillStroke}, + {"BDC", 2, {tchkName, tchkProps}, + &Gfx::opBeginMarkedContent}, + {"BI", 0, {tchkNone}, + &Gfx::opBeginImage}, + {"BMC", 1, {tchkName}, + &Gfx::opBeginMarkedContent}, + {"BT", 0, {tchkNone}, + &Gfx::opBeginText}, + {"BX", 0, {tchkNone}, + &Gfx::opBeginIgnoreUndef}, + {"CS", 1, {tchkName}, + &Gfx::opSetStrokeColorSpace}, + {"DP", 2, {tchkName, tchkProps}, + &Gfx::opMarkPoint}, + {"Do", 1, {tchkName}, + &Gfx::opXObject}, + {"EI", 0, {tchkNone}, + &Gfx::opEndImage}, + {"EMC", 0, {tchkNone}, + &Gfx::opEndMarkedContent}, + {"ET", 0, {tchkNone}, + &Gfx::opEndText}, + {"EX", 0, {tchkNone}, + &Gfx::opEndIgnoreUndef}, + {"F", 0, {tchkNone}, + &Gfx::opFill}, + {"G", 1, {tchkNum}, + &Gfx::opSetStrokeGray}, + {"ID", 0, {tchkNone}, + &Gfx::opImageData}, + {"J", 1, {tchkInt}, + &Gfx::opSetLineCap}, + {"K", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetStrokeCMYKColor}, + {"M", 1, {tchkNum}, + &Gfx::opSetMiterLimit}, + {"MP", 1, {tchkName}, + &Gfx::opMarkPoint}, + {"Q", 0, {tchkNone}, + &Gfx::opRestore}, + {"RG", 3, {tchkNum, tchkNum, tchkNum}, + &Gfx::opSetStrokeRGBColor}, + {"S", 0, {tchkNone}, + &Gfx::opStroke}, + {"SC", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetStrokeColor}, + {"SCN", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, + tchkSCN}, + &Gfx::opSetStrokeColorN}, + {"T*", 0, {tchkNone}, + &Gfx::opTextNextLine}, + {"TD", 2, {tchkNum, tchkNum}, + &Gfx::opTextMoveSet}, + {"TJ", 1, {tchkArray}, + &Gfx::opShowSpaceText}, + {"TL", 1, {tchkNum}, + &Gfx::opSetTextLeading}, + {"Tc", 1, {tchkNum}, + &Gfx::opSetCharSpacing}, + {"Td", 2, {tchkNum, tchkNum}, + &Gfx::opTextMove}, + {"Tf", 2, {tchkName, tchkNum}, + &Gfx::opSetFont}, + {"Tj", 1, {tchkString}, + &Gfx::opShowText}, + {"Tm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opSetTextMatrix}, + {"Tr", 1, {tchkInt}, + &Gfx::opSetTextRender}, + {"Ts", 1, {tchkNum}, + &Gfx::opSetTextRise}, + {"Tw", 1, {tchkNum}, + &Gfx::opSetWordSpacing}, + {"Tz", 1, {tchkNum}, + &Gfx::opSetHorizScaling}, + {"W", 0, {tchkNone}, + &Gfx::opClip}, + {"W*", 0, {tchkNone}, + &Gfx::opEOClip}, + {"b", 0, {tchkNone}, + &Gfx::opCloseFillStroke}, + {"b*", 0, {tchkNone}, + &Gfx::opCloseEOFillStroke}, + {"c", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opCurveTo}, + {"cm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opConcat}, + {"cs", 1, {tchkName}, + &Gfx::opSetFillColorSpace}, + {"d", 2, {tchkArray, tchkNum}, + &Gfx::opSetDash}, + {"d0", 2, {tchkNum, tchkNum}, + &Gfx::opSetCharWidth}, + {"d1", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opSetCacheDevice}, + {"f", 0, {tchkNone}, + &Gfx::opFill}, + {"f*", 0, {tchkNone}, + &Gfx::opEOFill}, + {"g", 1, {tchkNum}, + &Gfx::opSetFillGray}, + {"gs", 1, {tchkName}, + &Gfx::opSetExtGState}, + {"h", 0, {tchkNone}, + &Gfx::opClosePath}, + {"i", 1, {tchkNum}, + &Gfx::opSetFlat}, + {"j", 1, {tchkInt}, + &Gfx::opSetLineJoin}, + {"k", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetFillCMYKColor}, + {"l", 2, {tchkNum, tchkNum}, + &Gfx::opLineTo}, + {"m", 2, {tchkNum, tchkNum}, + &Gfx::opMoveTo}, + {"n", 0, {tchkNone}, + &Gfx::opEndPath}, + {"q", 0, {tchkNone}, + &Gfx::opSave}, + {"re", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opRectangle}, + {"rg", 3, {tchkNum, tchkNum, tchkNum}, + &Gfx::opSetFillRGBColor}, + {"ri", 1, {tchkName}, + &Gfx::opSetRenderingIntent}, + {"s", 0, {tchkNone}, + &Gfx::opCloseStroke}, + {"sc", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetFillColor}, + {"scn", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, + tchkSCN}, + &Gfx::opSetFillColorN}, + {"sh", 1, {tchkName}, + &Gfx::opShFill}, + {"v", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opCurveTo1}, + {"w", 1, {tchkNum}, + &Gfx::opSetLineWidth}, + {"y", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opCurveTo2}, +}; + +#ifdef WIN32 // this works around a bug in the VC7 compiler +# pragma optimize("",on) +#endif + +#define numOps (sizeof(opTab) / sizeof(Operator)) + +//------------------------------------------------------------------------ +// GfxResources +//------------------------------------------------------------------------ + +GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) { + Object obj1, obj2; + Ref r; + + if (resDict) { + + // build font dictionary + fonts = NULL; + resDict->lookupNF("Font", &obj1); + if (obj1.isRef()) { + obj1.fetch(xref, &obj2); + if (obj2.isDict()) { + r = obj1.getRef(); + fonts = new GfxFontDict(xref, &r, obj2.getDict()); + } + obj2.free(); + } else if (obj1.isDict()) { + fonts = new GfxFontDict(xref, NULL, obj1.getDict()); + } + obj1.free(); + + // get XObject dictionary + resDict->lookup("XObject", &xObjDict); + + // get color space dictionary + resDict->lookup("ColorSpace", &colorSpaceDict); + + // get pattern dictionary + resDict->lookup("Pattern", &patternDict); + + // get shading dictionary + resDict->lookup("Shading", &shadingDict); + + // get graphics state parameter dictionary + resDict->lookup("ExtGState", &gStateDict); + + } else { + fonts = NULL; + xObjDict.initNull(); + colorSpaceDict.initNull(); + patternDict.initNull(); + shadingDict.initNull(); + gStateDict.initNull(); + } + + next = nextA; +} + +GfxResources::~GfxResources() { + if (fonts) { + delete fonts; + } + xObjDict.free(); + colorSpaceDict.free(); + patternDict.free(); + shadingDict.free(); + gStateDict.free(); +} + +GfxFont *GfxResources::lookupFont(char *name) { + GfxFont *font; + GfxResources *resPtr; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->fonts) { + if ((font = resPtr->fonts->lookup(name))) + return font; + } + } + error(-1, "Unknown font tag '%s'", name); + return NULL; +} + +GBool GfxResources::lookupXObject(char *name, Object *obj) { + GfxResources *resPtr; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->xObjDict.isDict()) { + if (!resPtr->xObjDict.dictLookup(name, obj)->isNull()) + return gTrue; + obj->free(); + } + } + error(-1, "XObject '%s' is unknown", name); + return gFalse; +} + +GBool GfxResources::lookupXObjectNF(char *name, Object *obj) { + GfxResources *resPtr; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->xObjDict.isDict()) { + if (!resPtr->xObjDict.dictLookupNF(name, obj)->isNull()) + return gTrue; + obj->free(); + } + } + error(-1, "XObject '%s' is unknown", name); + return gFalse; +} + +void GfxResources::lookupColorSpace(char *name, Object *obj) { + GfxResources *resPtr; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->colorSpaceDict.isDict()) { + if (!resPtr->colorSpaceDict.dictLookup(name, obj)->isNull()) { + return; + } + obj->free(); + } + } + obj->initNull(); +} + +GfxPattern *GfxResources::lookupPattern(char *name) { + GfxResources *resPtr; + GfxPattern *pattern; + Object obj; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->patternDict.isDict()) { + if (!resPtr->patternDict.dictLookup(name, &obj)->isNull()) { + pattern = GfxPattern::parse(&obj); + obj.free(); + return pattern; + } + obj.free(); + } + } + error(-1, "Unknown pattern '%s'", name); + return NULL; +} + +GfxShading *GfxResources::lookupShading(char *name) { + GfxResources *resPtr; + GfxShading *shading; + Object obj; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->shadingDict.isDict()) { + if (!resPtr->shadingDict.dictLookup(name, &obj)->isNull()) { + shading = GfxShading::parse(&obj); + obj.free(); + return shading; + } + obj.free(); + } + } + error(-1, "Unknown shading '%s'", name); + return NULL; +} + +GBool GfxResources::lookupGState(char *name, Object *obj) { + GfxResources *resPtr; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->gStateDict.isDict()) { + if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) { + return gTrue; + } + obj->free(); + } + } + error(-1, "ExtGState '%s' is unknown", name); + return gFalse; +} + +//------------------------------------------------------------------------ +// Gfx +//------------------------------------------------------------------------ + +Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, + double hDPI, double vDPI, PDFRectangle *box, + PDFRectangle *cropBox, int rotate, + GBool (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA) { + int i; + + xref = xrefA; + subPage = gFalse; + printCommands = globalParams->getPrintCommands(); + profileCommands = globalParams->getProfileCommands(); + + // start the resource stack + res = new GfxResources(xref, resDict, NULL); + + // initialize + out = outA; + state = new GfxState(hDPI, vDPI, box, rotate, out->upsideDown()); + fontChanged = gFalse; + clip = clipNone; + ignoreUndef = 0; + out->startPage(pageNum, state); + out->setDefaultCTM(state->getCTM()); + out->updateAll(state); + for (i = 0; i < 6; ++i) { + baseMatrix[i] = state->getCTM()[i]; + } + formDepth = 0; + abortCheckCbk = abortCheckCbkA; + abortCheckCbkData = abortCheckCbkDataA; + + // set crop box + if (cropBox) { + state->moveTo(cropBox->x1, cropBox->y1); + state->lineTo(cropBox->x2, cropBox->y1); + state->lineTo(cropBox->x2, cropBox->y2); + state->lineTo(cropBox->x1, cropBox->y2); + state->closePath(); + state->clip(); + out->clip(state); + state->clearPath(); + } +} + +Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, + PDFRectangle *box, PDFRectangle *cropBox, + GBool (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA) { + int i; + + xref = xrefA; + subPage = gTrue; + printCommands = globalParams->getPrintCommands(); + + // start the resource stack + res = new GfxResources(xref, resDict, NULL); + + // initialize + out = outA; + state = new GfxState(72, 72, box, 0, gFalse); + fontChanged = gFalse; + clip = clipNone; + ignoreUndef = 0; + for (i = 0; i < 6; ++i) { + baseMatrix[i] = state->getCTM()[i]; + } + formDepth = 0; + abortCheckCbk = abortCheckCbkA; + abortCheckCbkData = abortCheckCbkDataA; + + // set crop box + if (cropBox) { + state->moveTo(cropBox->x1, cropBox->y1); + state->lineTo(cropBox->x2, cropBox->y1); + state->lineTo(cropBox->x2, cropBox->y2); + state->lineTo(cropBox->x1, cropBox->y2); + state->closePath(); + state->clip(); + out->clip(state); + state->clearPath(); + } +} + +Gfx::~Gfx() { + while (state && state->hasSaves()) { + restoreState(); + } + if (!subPage) { + out->endPage(); + } + while (res) { + popResources(); + } + delete state; +} + +void Gfx::display(Object *obj, GBool topLevel) { + Object obj2; + int i; + + if (obj->isArray()) { + for (i = 0; i < obj->arrayGetLength(); ++i) { + obj->arrayGet(i, &obj2); + if (!obj2.isStream()) { + error(-1, "Weird page contents"); + obj2.free(); + return; + } + obj2.free(); + } + } else if (!obj->isStream()) { + error(-1, "Weird page contents"); + return; + } + parser = new Parser(xref, new Lexer(xref, obj)); + go(topLevel); + delete parser; + parser = NULL; +} + +void Gfx::go(GBool topLevel) { + Object obj; + Object args[maxArgs]; + int numArgs, i; + int lastAbortCheck; +#ifdef HAVE_GETTIMEOFDAY + GooTimer *timer; +#endif + + // scan a sequence of objects + updateLevel = lastAbortCheck = 0; + numArgs = 0; + parser->getObj(&obj); + while (!obj.isEOF()) { + + // got a command - execute it + if (obj.isCmd()) { + if (printCommands) { + obj.print(stdout); + for (i = 0; i < numArgs; ++i) { + printf(" "); + args[i].print(stdout); + } + printf("\n"); + fflush(stdout); + } +#ifdef HAVE_GETTIMEOFDAY + if (profileCommands) + timer = new GooTimer (); +#endif + + // Run the operation + execOp(&obj, args, numArgs); + +#ifdef HAVE_GETTIMEOFDAY + // Update the profile information + if (profileCommands) { + GooHash *hash; + + hash = out->getProfileHash (); + if (hash) { + GooString *cmd_g; + ProfileData *data_p; + + cmd_g = new GooString (obj.getCmd()); + data_p = (ProfileData *)hash->lookup (cmd_g); + if (data_p == NULL) { + data_p = new ProfileData(); + hash->add (cmd_g, data_p); + } + + data_p->addElement (timer->getElapsed ()); + } + delete (timer); + } +#endif + obj.free(); + for (i = 0; i < numArgs; ++i) + args[i].free(); + numArgs = 0; + + // periodically update display + if (++updateLevel >= 20000) { + out->dump(); + updateLevel = 0; + } + + // check for an abort + if (abortCheckCbk) { + if (updateLevel - lastAbortCheck > 10) { + if ((*abortCheckCbk)(abortCheckCbkData)) { + break; + } + lastAbortCheck = updateLevel; + } + } + + // got an argument - save it + } else if (numArgs < maxArgs) { + args[numArgs++] = obj; + + // too many arguments - something is wrong + } else { + error(getPos(), "Too many args in content stream"); + if (printCommands) { + printf("throwing away arg: "); + obj.print(stdout); + printf("\n"); + fflush(stdout); + } + obj.free(); + } + + // grab the next object + parser->getObj(&obj); + } + obj.free(); + + // args at end with no command + if (numArgs > 0) { + error(getPos(), "Leftover args in content stream"); + if (printCommands) { + printf("%d leftovers:", numArgs); + for (i = 0; i < numArgs; ++i) { + printf(" "); + args[i].print(stdout); + } + printf("\n"); + fflush(stdout); + } + for (i = 0; i < numArgs; ++i) + args[i].free(); + } + + // update display + if (topLevel && updateLevel > 0) { + out->dump(); + } +} + +void Gfx::execOp(Object *cmd, Object args[], int numArgs) { + Operator *op; + char *name; + Object *argPtr; + int i; + + // find operator + name = cmd->getCmd()->getCString(); + if (!(op = findOp(name))) { + if (ignoreUndef == 0) + error(getPos(), "Unknown operator '%s'", name); + return; + } + + // type check args + argPtr = args; + if (op->numArgs >= 0) { + if (numArgs < op->numArgs) { + error(getPos(), "Too few (%d) args to '%s' operator", numArgs, name); + return; + } + if (numArgs > op->numArgs) { +#if 0 + error(getPos(), "Too many (%d) args to '%s' operator", numArgs, name); +#endif + argPtr += numArgs - op->numArgs; + numArgs = op->numArgs; + } + } else { + if (numArgs > -op->numArgs) { + error(getPos(), "Too many (%d) args to '%s' operator", + numArgs, name); + return; + } + } + for (i = 0; i < numArgs; ++i) { + if (!checkArg(&argPtr[i], op->tchk[i])) { + error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)", + i, name, argPtr[i].getTypeName()); + return; + } + } + + // do it + (this->*op->func)(argPtr, numArgs); +} + +Operator *Gfx::findOp(char *name) { + int a, b, m, cmp; + + a = -1; + b = numOps; + // invariant: opTab[a] < name < opTab[b] + while (b - a > 1) { + m = (a + b) / 2; + cmp = strcmp(opTab[m].name, name); + if (cmp < 0) + a = m; + else if (cmp > 0) + b = m; + else + a = b = m; + } + if (cmp != 0) + return NULL; + return &opTab[a]; +} + +GBool Gfx::checkArg(Object *arg, TchkType type) { + switch (type) { + case tchkBool: return arg->isBool(); + case tchkInt: return arg->isInt(); + case tchkNum: return arg->isNum(); + case tchkString: return arg->isString(); + case tchkName: return arg->isName(); + case tchkArray: return arg->isArray(); + case tchkProps: return arg->isDict() || arg->isName(); + case tchkSCN: return arg->isNum() || arg->isName(); + case tchkNone: return gFalse; + } + return gFalse; +} + +int Gfx::getPos() { + return parser ? parser->getPos() : -1; +} + +//------------------------------------------------------------------------ +// graphics state operators +//------------------------------------------------------------------------ + +void Gfx::opSave(Object args[], int numArgs) { + saveState(); +} + +void Gfx::opRestore(Object args[], int numArgs) { + restoreState(); +} + +void Gfx::opConcat(Object args[], int numArgs) { + state->concatCTM(args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum(), + args[4].getNum(), args[5].getNum()); + out->updateCTM(state, args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum(), + args[4].getNum(), args[5].getNum()); + fontChanged = gTrue; +} + +void Gfx::opSetDash(Object args[], int numArgs) { + Array *a; + int length; + Object obj; + double *dash; + int i; + + a = args[0].getArray(); + length = a->getLength(); + if (length == 0) { + dash = NULL; + } else { + dash = (double *)gmallocn(length, sizeof(double)); + for (i = 0; i < length; ++i) { + dash[i] = a->get(i, &obj)->getNum(); + obj.free(); + } + } + state->setLineDash(dash, length, args[1].getNum()); + out->updateLineDash(state); +} + +void Gfx::opSetFlat(Object args[], int numArgs) { + state->setFlatness((int)args[0].getNum()); + out->updateFlatness(state); +} + +void Gfx::opSetLineJoin(Object args[], int numArgs) { + state->setLineJoin(args[0].getInt()); + out->updateLineJoin(state); +} + +void Gfx::opSetLineCap(Object args[], int numArgs) { + state->setLineCap(args[0].getInt()); + out->updateLineCap(state); +} + +void Gfx::opSetMiterLimit(Object args[], int numArgs) { + state->setMiterLimit(args[0].getNum()); + out->updateMiterLimit(state); +} + +void Gfx::opSetLineWidth(Object args[], int numArgs) { + state->setLineWidth(args[0].getNum()); + out->updateLineWidth(state); +} + +void Gfx::opSetExtGState(Object args[], int numArgs) { + Object obj1, obj2; + GfxBlendMode mode; + GBool haveFillOP; + + if (!res->lookupGState(args[0].getNameC(), &obj1)) { + return; + } + if (!obj1.isDict()) { + error(getPos(), "ExtGState '%s' is wrong type", args[0].getNameC()); + obj1.free(); + return; + } + + // transparency support: blend mode, fill/stroke opacity + if (!obj1.dictLookup("BM", &obj2)->isNull()) { + if (state->parseBlendMode(&obj2, &mode)) { + state->setBlendMode(mode); + out->updateBlendMode(state); + } else { + error(getPos(), "Invalid blend mode in ExtGState"); + } + } + obj2.free(); + if (obj1.dictLookup("ca", &obj2)->isNum()) { + state->setFillOpacity(obj2.getNum()); + out->updateFillOpacity(state); + } + obj2.free(); + if (obj1.dictLookup("CA", &obj2)->isNum()) { + state->setStrokeOpacity(obj2.getNum()); + out->updateStrokeOpacity(state); + } + obj2.free(); + + // fill/stroke overprint + if ((haveFillOP = (obj1.dictLookup("op", &obj2)->isBool()))) { + state->setFillOverprint(obj2.getBool()); + out->updateFillOverprint(state); + } + obj2.free(); + if (obj1.dictLookup("OP", &obj2)->isBool()) { + state->setStrokeOverprint(obj2.getBool()); + out->updateStrokeOverprint(state); + if (!haveFillOP) { + state->setFillOverprint(obj2.getBool()); + out->updateFillOverprint(state); + } + } + obj2.free(); + + obj1.free(); +} + +void Gfx::opSetRenderingIntent(Object args[], int numArgs) { +} + +//------------------------------------------------------------------------ +// color operators +//------------------------------------------------------------------------ + +void Gfx::opSetFillGray(Object args[], int numArgs) { + GfxColor color; + + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceGrayColorSpace()); + out->updateFillColorSpace(state); + color.c[0] = dblToCol(args[0].getNum()); + state->setFillColor(&color); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeGray(Object args[], int numArgs) { + GfxColor color; + + state->setStrokePattern(NULL); + state->setStrokeColorSpace(new GfxDeviceGrayColorSpace()); + out->updateStrokeColorSpace(state); + color.c[0] = dblToCol(args[0].getNum()); + state->setStrokeColor(&color); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { + GfxColor color; + int i; + + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); + out->updateFillColorSpace(state); + for (i = 0; i < 4; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setFillColor(&color); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) { + GfxColor color; + int i; + + state->setStrokePattern(NULL); + state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace()); + out->updateStrokeColorSpace(state); + for (i = 0; i < 4; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setStrokeColor(&color); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillRGBColor(Object args[], int numArgs) { + GfxColor color; + int i; + + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceRGBColorSpace()); + out->updateFillColorSpace(state); + for (i = 0; i < 3; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setFillColor(&color); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) { + GfxColor color; + int i; + + state->setStrokePattern(NULL); + state->setStrokeColorSpace(new GfxDeviceRGBColorSpace()); + out->updateStrokeColorSpace(state); + for (i = 0; i < 3; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setStrokeColor(&color); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillColorSpace(Object args[], int numArgs) { + Object obj; + GfxColorSpace *colorSpace; + GfxColor color; + int i; + + state->setFillPattern(NULL); + res->lookupColorSpace(args[0].getNameC(), &obj); + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0]); + } else { + colorSpace = GfxColorSpace::parse(&obj); + } + obj.free(); + if (colorSpace) { + state->setFillColorSpace(colorSpace); + out->updateFillColorSpace(state); + } else { + error(getPos(), "Bad color space (fill)"); + } + for (i = 0; i < gfxColorMaxComps; ++i) { + color.c[i] = 0; + } + state->setFillColor(&color); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) { + Object obj; + GfxColorSpace *colorSpace; + GfxColor color; + int i; + + state->setStrokePattern(NULL); + res->lookupColorSpace(args[0].getNameC(), &obj); + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0]); + } else { + colorSpace = GfxColorSpace::parse(&obj); + } + obj.free(); + if (colorSpace) { + state->setStrokeColorSpace(colorSpace); + out->updateStrokeColorSpace(state); + } else { + error(getPos(), "Bad color space (stroke)"); + } + for (i = 0; i < gfxColorMaxComps; ++i) { + color.c[i] = 0; + } + state->setStrokeColor(&color); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillColor(Object args[], int numArgs) { + GfxColor color; + int i; + + state->setFillPattern(NULL); + for (i = 0; i < numArgs; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setFillColor(&color); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeColor(Object args[], int numArgs) { + GfxColor color; + int i; + + state->setStrokePattern(NULL); + for (i = 0; i < numArgs; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setStrokeColor(&color); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillColorN(Object args[], int numArgs) { + GfxColor color; + GfxPattern *pattern; + int i; + + if (state->getFillColorSpace()->getMode() == csPattern) { + if (numArgs > 1) { + for (i = 0; i < numArgs && i < 4; ++i) { + if (args[i].isNum()) { + color.c[i] = dblToCol(args[i].getNum()); + } + } + state->setFillColor(&color); + out->updateFillColor(state); + } + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getNameC()))) { + state->setFillPattern(pattern); + } + + } else { + state->setFillPattern(NULL); + for (i = 0; i < numArgs && i < 4; ++i) { + if (args[i].isNum()) { + color.c[i] = dblToCol(args[i].getNum()); + } + } + state->setFillColor(&color); + out->updateFillColor(state); + } +} + +void Gfx::opSetStrokeColorN(Object args[], int numArgs) { + GfxColor color; + GfxPattern *pattern; + int i; + + if (state->getStrokeColorSpace()->getMode() == csPattern) { + if (numArgs > 1) { + for (i = 0; i < numArgs && i < 4; ++i) { + if (args[i].isNum()) { + color.c[i] = dblToCol(args[i].getNum()); + } + } + state->setStrokeColor(&color); + out->updateStrokeColor(state); + } + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getNameC()))) { + state->setStrokePattern(pattern); + } + + } else { + state->setStrokePattern(NULL); + for (i = 0; i < numArgs && i < 4; ++i) { + if (args[i].isNum()) { + color.c[i] = dblToCol(args[i].getNum()); + } + } + state->setStrokeColor(&color); + out->updateStrokeColor(state); + } +} + +//------------------------------------------------------------------------ +// path segment operators +//------------------------------------------------------------------------ + +void Gfx::opMoveTo(Object args[], int numArgs) { + state->moveTo(args[0].getNum(), args[1].getNum()); +} + +void Gfx::opLineTo(Object args[], int numArgs) { + if (!state->isCurPt()) { + error(getPos(), "No current point in lineto"); + return; + } + state->lineTo(args[0].getNum(), args[1].getNum()); +} + +void Gfx::opCurveTo(Object args[], int numArgs) { + double x1, y1, x2, y2, x3, y3; + + if (!state->isCurPt()) { + error(getPos(), "No current point in curveto"); + return; + } + x1 = args[0].getNum(); + y1 = args[1].getNum(); + x2 = args[2].getNum(); + y2 = args[3].getNum(); + x3 = args[4].getNum(); + y3 = args[5].getNum(); + state->curveTo(x1, y1, x2, y2, x3, y3); +} + +void Gfx::opCurveTo1(Object args[], int numArgs) { + double x1, y1, x2, y2, x3, y3; + + if (!state->isCurPt()) { + error(getPos(), "No current point in curveto1"); + return; + } + x1 = state->getCurX(); + y1 = state->getCurY(); + x2 = args[0].getNum(); + y2 = args[1].getNum(); + x3 = args[2].getNum(); + y3 = args[3].getNum(); + state->curveTo(x1, y1, x2, y2, x3, y3); +} + +void Gfx::opCurveTo2(Object args[], int numArgs) { + double x1, y1, x2, y2, x3, y3; + + if (!state->isCurPt()) { + error(getPos(), "No current point in curveto2"); + return; + } + x1 = args[0].getNum(); + y1 = args[1].getNum(); + x2 = args[2].getNum(); + y2 = args[3].getNum(); + x3 = x2; + y3 = y2; + state->curveTo(x1, y1, x2, y2, x3, y3); +} + +void Gfx::opRectangle(Object args[], int numArgs) { + double x, y, w, h; + + x = args[0].getNum(); + y = args[1].getNum(); + w = args[2].getNum(); + h = args[3].getNum(); + state->moveTo(x, y); + state->lineTo(x + w, y); + state->lineTo(x + w, y + h); + state->lineTo(x, y + h); + state->closePath(); +} + +void Gfx::opClosePath(Object args[], int numArgs) { + if (!state->isCurPt()) { + error(getPos(), "No current point in closepath"); + return; + } + state->closePath(); +} + +//------------------------------------------------------------------------ +// path painting operators +//------------------------------------------------------------------------ + +void Gfx::opEndPath(Object args[], int numArgs) { + doEndPath(); +} + +void Gfx::opStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in stroke"); + return; + } + if (state->isPath()) + out->stroke(state); + doEndPath(); +} + +void Gfx::opCloseStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in closepath/stroke"); + return; + } + state->closePath(); + if (state->isPath()) { + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opFill(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in fill"); + return; + } + if (state->isPath()) { + if (state->getFillColorSpace()->getMode() == csPattern) { + doPatternFill(gFalse); + } else { + out->fill(state); + } + } + doEndPath(); +} + +void Gfx::opEOFill(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in eofill"); + return; + } + if (state->isPath()) { + if (state->getFillColorSpace()->getMode() == csPattern) { + doPatternFill(gTrue); + } else { + out->eoFill(state); + } + } + doEndPath(); +} + +void Gfx::opFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in fill/stroke"); + return; + } + if (state->isPath()) { + if (state->getFillColorSpace()->getMode() == csPattern) { + doPatternFill(gFalse); + } else { + out->fill(state); + } + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opCloseFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in closepath/fill/stroke"); + return; + } + if (state->isPath()) { + state->closePath(); + if (state->getFillColorSpace()->getMode() == csPattern) { + doPatternFill(gFalse); + } else { + out->fill(state); + } + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opEOFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in eofill/stroke"); + return; + } + if (state->isPath()) { + if (state->getFillColorSpace()->getMode() == csPattern) { + doPatternFill(gTrue); + } else { + out->eoFill(state); + } + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opCloseEOFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in closepath/eofill/stroke"); + return; + } + if (state->isPath()) { + state->closePath(); + if (state->getFillColorSpace()->getMode() == csPattern) { + doPatternFill(gTrue); + } else { + out->eoFill(state); + } + out->stroke(state); + } + doEndPath(); +} + +void Gfx::doPatternFill(GBool eoFill) { + GfxPattern *pattern; + + // this is a bit of a kludge -- patterns can be really slow, so we + // skip them if we're only doing text extraction, since they almost + // certainly don't contain any text + if (!out->needNonText()) { + return; + } + + if (!(pattern = state->getFillPattern())) { + return; + } + switch (pattern->getType()) { + case 1: + doTilingPatternFill((GfxTilingPattern *)pattern, eoFill); + break; + case 2: + doShadingPatternFill((GfxShadingPattern *)pattern, eoFill); + break; + default: + error(getPos(), "Unimplemented pattern type (%d) in fill", + pattern->getType()); + break; + } +} + +void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill) { + GfxPatternColorSpace *patCS; + GfxColorSpace *cs; + GfxPath *savedPath; + double xMin, yMin, xMax, yMax, x, y, x1, y1; + double cxMin, cyMin, cxMax, cyMax; + int xi0, yi0, xi1, yi1, xi, yi; + double *ctm, *btm, *ptm; + double m[6], ictm[6], m1[6], imb[6]; + double det; + double xstep, ystep; + int i; + + // get color space + patCS = (GfxPatternColorSpace *)state->getFillColorSpace(); + + // construct a (pattern space) -> (current space) transform matrix + ctm = state->getCTM(); + btm = baseMatrix; + ptm = tPat->getMatrix(); + // iCTM = invert CTM + det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + ictm[0] = ctm[3] * det; + ictm[1] = -ctm[1] * det; + ictm[2] = -ctm[2] * det; + ictm[3] = ctm[0] * det; + ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; + ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; + // m1 = PTM * BTM = PTM * base transform matrix + m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2]; + m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3]; + m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2]; + m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3]; + m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4]; + m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5]; + // m = m1 * iCTM = (PTM * BTM) * (iCTM) + m[0] = m1[0] * ictm[0] + m1[1] * ictm[2]; + m[1] = m1[0] * ictm[1] + m1[1] * ictm[3]; + m[2] = m1[2] * ictm[0] + m1[3] * ictm[2]; + m[3] = m1[2] * ictm[1] + m1[3] * ictm[3]; + m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4]; + m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5]; + + // construct a (device space) -> (pattern space) transform matrix + det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]); + imb[0] = m1[3] * det; + imb[1] = -m1[1] * det; + imb[2] = -m1[2] * det; + imb[3] = m1[0] * det; + imb[4] = (m1[2] * m1[5] - m1[3] * m1[4]) * det; + imb[5] = (m1[1] * m1[4] - m1[0] * m1[5]) * det; + + // save current graphics state + savedPath = state->getPath()->copy(); + saveState(); + + // set underlying color space (for uncolored tiling patterns); set + // various other parameters (stroke color, line width) to match + // Adobe's behavior + if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) { + state->setFillColorSpace(cs->copy()); + out->updateFillColorSpace(state); + state->setStrokeColorSpace(cs->copy()); + out->updateStrokeColorSpace(state); + state->setStrokeColor(state->getFillColor()); + } else { + state->setFillColorSpace(new GfxDeviceGrayColorSpace()); + out->updateFillColorSpace(state); + state->setStrokeColorSpace(new GfxDeviceGrayColorSpace()); + out->updateStrokeColorSpace(state); + } + state->setFillPattern(NULL); + out->updateFillColor(state); + state->setStrokePattern(NULL); + out->updateStrokeColor(state); + state->setLineWidth(0); + out->updateLineWidth(state); + + // clip to current path + state->clip(); + if (eoFill) { + out->eoClip(state); + } else { + out->clip(state); + } + state->clearPath(); + + // get the clip region, check for empty + state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax); + if (cxMin > cxMax || cyMin > cyMax) { + goto err; + } + + // transform clip region bbox to pattern space + xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4]; + yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5]; + x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4]; + y1 = cxMin * imb[1] + cyMax * imb[3] + imb[5]; + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + x1 = cxMax * imb[0] + cyMin * imb[2] + imb[4]; + y1 = cxMax * imb[1] + cyMin * imb[3] + imb[5]; + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + x1 = cxMax * imb[0] + cyMax * imb[2] + imb[4]; + y1 = cxMax * imb[1] + cyMax * imb[3] + imb[5]; + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + + // draw the pattern + //~ this should treat negative steps differently -- start at right/top + //~ edge instead of left/bottom (?) + xstep = fabs(tPat->getXStep()); + ystep = fabs(tPat->getYStep()); + xi0 = (int)floor((xMin - tPat->getBBox()[0]) / xstep); + xi1 = (int)ceil((xMax - tPat->getBBox()[0]) / xstep); + yi0 = (int)floor((yMin - tPat->getBBox()[1]) / ystep); + yi1 = (int)ceil((yMax - tPat->getBBox()[1]) / ystep); + for (i = 0; i < 4; ++i) { + m1[i] = m[i]; + } + if (out->useTilingPatternFill()) { + m1[4] = m[4]; + m1[5] = m[5]; + out->tilingPatternFill(state, tPat->getContentStream(), + tPat->getPaintType(), tPat->getResDict(), + m1, tPat->getBBox(), + xi0, yi0, xi1, yi1, xstep, ystep); + } else { + for (yi = yi0; yi < yi1; ++yi) { + for (xi = xi0; xi < xi1; ++xi) { + x = xi * xstep; + y = yi * ystep; + m1[4] = x * m[0] + y * m[2] + m[4]; + m1[5] = x * m[1] + y * m[3] + m[5]; + doForm1(tPat->getContentStream(), tPat->getResDict(), + m1, tPat->getBBox()); + } + } + } + + // restore graphics state + err: + restoreState(); + state->setPath(savedPath); +} + +void Gfx::doShadingPatternFill(GfxShadingPattern *sPat, GBool eoFill) { + GfxShading *shading; + GfxPath *savedPath; + double *ctm, *btm, *ptm; + double m[6], ictm[6], m1[6]; + double xMin, yMin, xMax, yMax; + double det; + + shading = sPat->getShading(); + + // save current graphics state + savedPath = state->getPath()->copy(); + saveState(); + + // clip to bbox + if (shading->getHasBBox()) { + shading->getBBox(&xMin, &yMin, &xMax, &yMax); + state->moveTo(xMin, yMin); + state->lineTo(xMax, yMin); + state->lineTo(xMax, yMax); + state->lineTo(xMin, yMax); + state->closePath(); + state->clip(); + out->clip(state); + state->setPath(savedPath->copy()); + } + + // clip to current path + state->clip(); + if (eoFill) { + out->eoClip(state); + } else { + out->clip(state); + } + + // set the color space + state->setFillColorSpace(shading->getColorSpace()->copy()); + out->updateFillColorSpace(state); + + // background color fill + if (shading->getHasBackground()) { + state->setFillColor(shading->getBackground()); + out->updateFillColor(state); + out->fill(state); + } + state->clearPath(); + + // construct a (pattern space) -> (current space) transform matrix + ctm = state->getCTM(); + btm = baseMatrix; + ptm = sPat->getMatrix(); + // iCTM = invert CTM + det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + ictm[0] = ctm[3] * det; + ictm[1] = -ctm[1] * det; + ictm[2] = -ctm[2] * det; + ictm[3] = ctm[0] * det; + ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; + ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; + // m1 = PTM * BTM = PTM * base transform matrix + m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2]; + m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3]; + m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2]; + m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3]; + m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4]; + m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5]; + // m = m1 * iCTM = (PTM * BTM) * (iCTM) + m[0] = m1[0] * ictm[0] + m1[1] * ictm[2]; + m[1] = m1[0] * ictm[1] + m1[1] * ictm[3]; + m[2] = m1[2] * ictm[0] + m1[3] * ictm[2]; + m[3] = m1[2] * ictm[1] + m1[3] * ictm[3]; + m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4]; + m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5]; + + // set the new matrix + state->concatCTM(m[0], m[1], m[2], m[3], m[4], m[5]); + out->updateCTM(state, m[0], m[1], m[2], m[3], m[4], m[5]); + + // do shading type-specific operations + switch (shading->getType()) { + case 1: + doFunctionShFill((GfxFunctionShading *)shading); + break; + case 2: + doAxialShFill((GfxAxialShading *)shading); + break; + case 3: + doRadialShFill((GfxRadialShading *)shading); + break; + case 4: + case 5: + doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading); + break; + case 6: + case 7: + doPatchMeshShFill((GfxPatchMeshShading *)shading); + break; + } + + // restore graphics state + restoreState(); + state->setPath(savedPath); +} + +void Gfx::opShFill(Object args[], int numArgs) { + GfxShading *shading; + GfxPath *savedPath; + double xMin, yMin, xMax, yMax; + + if (!(shading = res->lookupShading(args[0].getNameC()))) { + return; + } + + // save current graphics state + savedPath = state->getPath()->copy(); + saveState(); + + // clip to bbox + if (shading->getHasBBox()) { + shading->getBBox(&xMin, &yMin, &xMax, &yMax); + state->moveTo(xMin, yMin); + state->lineTo(xMax, yMin); + state->lineTo(xMax, yMax); + state->lineTo(xMin, yMax); + state->closePath(); + state->clip(); + out->clip(state); + state->clearPath(); + } + + // set the color space + state->setFillColorSpace(shading->getColorSpace()->copy()); + out->updateFillColorSpace(state); + + // do shading type-specific operations + switch (shading->getType()) { + case 1: + doFunctionShFill((GfxFunctionShading *)shading); + break; + case 2: + doAxialShFill((GfxAxialShading *)shading); + break; + case 3: + doRadialShFill((GfxRadialShading *)shading); + break; + case 4: + case 5: + doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading); + break; + case 6: + case 7: + doPatchMeshShFill((GfxPatchMeshShading *)shading); + break; + } + + // restore graphics state + restoreState(); + state->setPath(savedPath); + + delete shading; +} + +void Gfx::doFunctionShFill(GfxFunctionShading *shading) { + double x0, y0, x1, y1; + GfxColor colors[4]; + + if (out->useShadedFills()) { + out->functionShadedFill(state, shading); + } else { + shading->getDomain(&x0, &y0, &x1, &y1); + shading->getColor(x0, y0, &colors[0]); + shading->getColor(x0, y1, &colors[1]); + shading->getColor(x1, y0, &colors[2]); + shading->getColor(x1, y1, &colors[3]); + doFunctionShFill1(shading, x0, y0, x1, y1, colors, 0); + } +} + +void Gfx::doFunctionShFill1(GfxFunctionShading *shading, + double x0, double y0, + double x1, double y1, + GfxColor *colors, int depth) { + GfxColor fillColor; + GfxColor color0M, color1M, colorM0, colorM1, colorMM; + GfxColor colors2[4]; + double *matrix; + double xM, yM; + int nComps, i, j; + + nComps = shading->getColorSpace()->getNComps(); + matrix = shading->getMatrix(); + + // compare the four corner colors + for (i = 0; i < 4; ++i) { + for (j = 0; j < nComps; ++j) { + if (abs(colors[i].c[j] - colors[(i+1)&3].c[j]) > functionColorDelta) { + break; + } + } + if (j < nComps) { + break; + } + } + + // center of the rectangle + xM = 0.5 * (x0 + x1); + yM = 0.5 * (y0 + y1); + + // the four corner colors are close (or we hit the recursive limit) + // -- fill the rectangle; but require at least one subdivision + // (depth==0) to avoid problems when the four outer corners of the + // shaded region are the same color + if ((i == 4 && depth > 0) || depth == functionMaxDepth) { + + // use the center color + shading->getColor(xM, yM, &fillColor); + state->setFillColor(&fillColor); + out->updateFillColor(state); + + // fill the rectangle + state->moveTo(x0 * matrix[0] + y0 * matrix[2] + matrix[4], + x0 * matrix[1] + y0 * matrix[3] + matrix[5]); + state->lineTo(x1 * matrix[0] + y0 * matrix[2] + matrix[4], + x1 * matrix[1] + y0 * matrix[3] + matrix[5]); + state->lineTo(x1 * matrix[0] + y1 * matrix[2] + matrix[4], + x1 * matrix[1] + y1 * matrix[3] + matrix[5]); + state->lineTo(x0 * matrix[0] + y1 * matrix[2] + matrix[4], + x0 * matrix[1] + y1 * matrix[3] + matrix[5]); + state->closePath(); + out->fill(state); + state->clearPath(); + + // the four corner colors are not close enough -- subdivide the + // rectangle + } else { + + // colors[0] colorM0 colors[2] + // (x0,y0) (xM,y0) (x1,y0) + // +----------+----------+ + // | | | + // | UL | UR | + // color0M | colorMM | color1M + // (x0,yM) +----------+----------+ (x1,yM) + // | (xM,yM) | + // | LL | LR | + // | | | + // +----------+----------+ + // colors[1] colorM1 colors[3] + // (x0,y1) (xM,y1) (x1,y1) + + shading->getColor(x0, yM, &color0M); + shading->getColor(x1, yM, &color1M); + shading->getColor(xM, y0, &colorM0); + shading->getColor(xM, y1, &colorM1); + shading->getColor(xM, yM, &colorMM); + + // upper-left sub-rectangle + colors2[0] = colors[0]; + colors2[1] = color0M; + colors2[2] = colorM0; + colors2[3] = colorMM; + doFunctionShFill1(shading, x0, y0, xM, yM, colors2, depth + 1); + + // lower-left sub-rectangle + colors2[0] = color0M; + colors2[1] = colors[1]; + colors2[2] = colorMM; + colors2[3] = colorM1; + doFunctionShFill1(shading, x0, yM, xM, y1, colors2, depth + 1); + + // upper-right sub-rectangle + colors2[0] = colorM0; + colors2[1] = colorMM; + colors2[2] = colors[2]; + colors2[3] = color1M; + doFunctionShFill1(shading, xM, y0, x1, yM, colors2, depth + 1); + + // lower-right sub-rectangle + colors2[0] = colorMM; + colors2[1] = colorM1; + colors2[2] = color1M; + colors2[3] = colors[3]; + doFunctionShFill1(shading, xM, yM, x1, y1, colors2, depth + 1); + } +} + +void Gfx::doAxialShFill(GfxAxialShading *shading) { + double xMin, yMin, xMax, yMax; + double x0, y0, x1, y1; + double dx, dy, mul; + GBool dxZero, dyZero; + double tMin, tMax, t, tx, ty; + double s[4], sMin, sMax, tmp; + double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1; + double t0, t1, tt; + double ta[axialMaxSplits + 1]; + int next[axialMaxSplits + 1]; + GfxColor color0, color1; + int nComps; + int i, j, k, kk; + + if (out->useShadedFills()) { + + out->axialShadedFill(state, shading); + + } else { + + // get the clip region bbox + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + + // compute min and max t values, based on the four corners of the + // clip region bbox + shading->getCoords(&x0, &y0, &x1, &y1); + dx = x1 - x0; + dy = y1 - y0; + dxZero = fabs(dx) < 0.001; + dyZero = fabs(dy) < 0.001; + mul = 1 / (dx * dx + dy * dy); + tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul; + t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + if (tMin < 0 && !shading->getExtend0()) { + tMin = 0; + } + if (tMax > 1 && !shading->getExtend1()) { + tMax = 1; + } + + // get the function domain + t0 = shading->getDomain0(); + t1 = shading->getDomain1(); + + // Traverse the t axis and do the shading. + // + // For each point (tx, ty) on the t axis, consider a line through + // that point perpendicular to the t axis: + // + // x(s) = tx + s * -dy --> s = (x - tx) / -dy + // y(s) = ty + s * dx --> s = (y - ty) / dx + // + // Then look at the intersection of this line with the bounding box + // (xMin, yMin, xMax, yMax). In the general case, there are four + // intersection points: + // + // s0 = (xMin - tx) / -dy + // s1 = (xMax - tx) / -dy + // s2 = (yMin - ty) / dx + // s3 = (yMax - ty) / dx + // + // and we want the middle two s values. + // + // In the case where dx = 0, take s0 and s1; in the case where dy = + // 0, take s2 and s3. + // + // Each filled polygon is bounded by two of these line segments + // perpdendicular to the t axis. + // + // The t axis is bisected into smaller regions until the color + // difference across a region is small enough, and then the region + // is painted with a single color. + + // set up: require at least one split to avoid problems when the two + // ends of the t axis have the same color + nComps = shading->getColorSpace()->getNComps(); + ta[0] = tMin; + next[0] = axialMaxSplits / 2; + ta[axialMaxSplits / 2] = 0.5 * (tMin + tMax); + next[axialMaxSplits / 2] = axialMaxSplits; + ta[axialMaxSplits] = tMax; + + // compute the color at t = tMin + if (tMin < 0) { + tt = t0; + } else if (tMin > 1) { + tt = t1; + } else { + tt = t0 + (t1 - t0) * tMin; + } + shading->getColor(tt, &color0); + + // compute the coordinates of the point on the t axis at t = tMin; + // then compute the intersection of the perpendicular line with the + // bounding box + tx = x0 + tMin * dx; + ty = y0 + tMin * dy; + if (dxZero && dyZero) { + sMin = sMax = 0; + } if (dxZero) { + sMin = (xMin - tx) / -dy; + sMax = (xMax - tx) / -dy; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else if (dyZero) { + sMin = (yMin - ty) / dx; + sMax = (yMax - ty) / dx; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else { + s[0] = (yMin - ty) / dx; + s[1] = (yMax - ty) / dx; + s[2] = (xMin - tx) / -dy; + s[3] = (xMax - tx) / -dy; + for (j = 0; j < 3; ++j) { + kk = j; + for (k = j + 1; k < 4; ++k) { + if (s[k] < s[kk]) { + kk = k; + } + } + tmp = s[j]; s[j] = s[kk]; s[kk] = tmp; + } + sMin = s[1]; + sMax = s[2]; + } + ux0 = tx - sMin * dy; + uy0 = ty + sMin * dx; + vx0 = tx - sMax * dy; + vy0 = ty + sMax * dx; + + i = 0; + while (i < axialMaxSplits) { + + // bisect until color difference is small enough or we hit the + // bisection limit + j = next[i]; + while (j > i + 1) { + if (ta[j] < 0) { + tt = t0; + } else if (ta[j] > 1) { + tt = t1; + } else { + tt = t0 + (t1 - t0) * ta[j]; + } + shading->getColor(tt, &color1); + for (k = 0; k < nComps; ++k) { + if (abs(color1.c[k] - color0.c[k]) > axialColorDelta) { + break; + } + } + if (k == nComps) { + break; + } + k = (i + j) / 2; + ta[k] = 0.5 * (ta[i] + ta[j]); + next[i] = k; + next[k] = j; + j = k; + } + + // use the average of the colors of the two sides of the region + for (k = 0; k < nComps; ++k) { + color0.c[k] = (color0.c[k] + color1.c[k]) / 2; + } + + // compute the coordinates of the point on the t axis; then + // compute the intersection of the perpendicular line with the + // bounding box + tx = x0 + ta[j] * dx; + ty = y0 + ta[j] * dy; + if (dxZero && dyZero) { + sMin = sMax = 0; + } if (dxZero) { + sMin = (xMin - tx) / -dy; + sMax = (xMax - tx) / -dy; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else if (dyZero) { + sMin = (yMin - ty) / dx; + sMax = (yMax - ty) / dx; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else { + s[0] = (yMin - ty) / dx; + s[1] = (yMax - ty) / dx; + s[2] = (xMin - tx) / -dy; + s[3] = (xMax - tx) / -dy; + for (j = 0; j < 3; ++j) { + kk = j; + for (k = j + 1; k < 4; ++k) { + if (s[k] < s[kk]) { + kk = k; + } + } + tmp = s[j]; s[j] = s[kk]; s[kk] = tmp; + } + sMin = s[1]; + sMax = s[2]; + } + ux1 = tx - sMin * dy; + uy1 = ty + sMin * dx; + vx1 = tx - sMax * dy; + vy1 = ty + sMax * dx; + + // set the color + state->setFillColor(&color0); + out->updateFillColor(state); + + // fill the region + state->moveTo(ux0, uy0); + state->lineTo(vx0, vy0); + state->lineTo(vx1, vy1); + state->lineTo(ux1, uy1); + state->closePath(); + out->fill(state); + state->clearPath(); + + // set up for next region + ux0 = ux1; + uy0 = uy1; + vx0 = vx1; + vy0 = vy1; + color0 = color1; + i = next[i]; + } + } +} + +void Gfx::doRadialShFill(GfxRadialShading *shading) { + double sMin, sMax, xMin, yMin, xMax, yMax; + double x0, y0, r0, x1, y1, r1, t0, t1; + int nComps; + GfxColor colorA, colorB; + double xa, ya, xb, yb, ra, rb; + double ta, tb, sa, sb; + int ia, ib, k, n; + double *ctm; + double angle, t, d0, d1; + + if (out->useShadedFills()) { + + out->radialShadedFill(state, shading); + + } else { + + // get the shading info + shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1); + t0 = shading->getDomain0(); + t1 = shading->getDomain1(); + nComps = shading->getColorSpace()->getNComps(); + + // compute the (possibly extended) s range + sMin = 0; + sMax = 1; + if (shading->getExtend0()) { + if (r0 < r1) { + // extend the smaller end + sMin = -r0 / (r1 - r0); + } else { + // extend the larger end + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + d0 = (x0 - xMin) * (x0 - xMin); + d1 = (x0 - xMax) * (x0 - xMax); + sMin = d0 > d1 ? d0 : d1; + d0 = (y0 - yMin) * (y0 - yMin); + d1 = (y0 - yMax) * (y0 - yMax); + sMin += d0 > d1 ? d0 : d1; + sMin = (sqrt(sMin) - r0) / (r1 - r0); + if (sMin > 0) { + sMin = 0; + } else if (sMin < -20) { + // sanity check + sMin = -20; + } + } + } + if (shading->getExtend1()) { + if (r1 < r0) { + // extend the smaller end + sMax = -r0 / (r1 - r0); + } else if (r1 > r0) { + // extend the larger end + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + d0 = (x1 - xMin) * (x1 - xMin); + d1 = (x1 - xMax) * (x1 - xMax); + sMax = d0 > d1 ? d0 : d1; + d0 = (y1 - yMin) * (y1 - yMin); + d1 = (y1 - yMax) * (y1 - yMax); + sMax += d0 > d1 ? d0 : d1; + sMax = (sqrt(sMax) - r0) / (r1 - r0); + if (sMax < 1) { + sMax = 1; + } else if (sMax > 20) { + // sanity check + sMax = 20; + } + } + } + + // compute the number of steps into which circles must be divided to + // achieve a curve flatness of 0.1 pixel in device space for the + // largest circle (note that "device space" is 72 dpi when generating + // PostScript, hence the relatively small 0.1 pixel accuracy) + ctm = state->getCTM(); + t = fabs(ctm[0]); + if (fabs(ctm[1]) > t) { + t = fabs(ctm[1]); + } + if (fabs(ctm[2]) > t) { + t = fabs(ctm[2]); + } + if (fabs(ctm[3]) > t) { + t = fabs(ctm[3]); + } + if (r0 > r1) { + t *= r0; + } else { + t *= r1; + } + if (t < 1) { + n = 3; + } else { + n = (int)(M_PI / acos(1 - 0.1 / t)); + if (n < 3) { + n = 3; + } else if (n > 200) { + n = 200; + } + } + + // Traverse the t axis and do the shading. + // + // This generates and fills a series of rings. Each ring is defined + // by two circles: + // sa, ta, xa, ya, ra, colorA + // sb, tb, xb, yb, rb, colorB + // + // The s/t axis is divided into radialMaxSplits parts; these parts + // are combined as much as possible while respecting the + // radialColorDelta parameter. + + // setup for the start circle + ia = 0; + sa = sMin; + ta = t0 + sa * (t1 - t0); + xa = x0 + sa * (x1 - x0); + ya = y0 + sa * (y1 - y0); + ra = r0 + sa * (r1 - r0); + if (ta < t0) { + shading->getColor(t0, &colorA); + } else if (ta > t1) { + shading->getColor(t1, &colorA); + } else { + shading->getColor(ta, &colorA); + } + + while (ia < radialMaxSplits) { + + // go as far along the t axis (toward t1) as we can, such that the + // color difference is within the tolerance (radialColorDelta) -- + // this uses bisection (between the current value, t, and t1), + // limited to radialMaxSplits points along the t axis; require at + // least one split to avoid problems when the innermost and + // outermost colors are the same + ib = radialMaxSplits; + sb = sMin + ((double)ib / (double)radialMaxSplits) * (sMax - sMin); + tb = t0 + sb * (t1 - t0); + if (tb < t0) { + shading->getColor(t0, &colorB); + } else if (tb > t1) { + shading->getColor(t1, &colorB); + } else { + shading->getColor(tb, &colorB); + } + while (ib - ia > 1) { + for (k = 0; k < nComps; ++k) { + if (abs(colorB.c[k] - colorA.c[k]) > radialColorDelta) { + break; + } + } + if (k == nComps && ib < radialMaxSplits) { + break; + } + ib = (ia + ib) / 2; + sb = sMin + ((double)ib / (double)radialMaxSplits) * (sMax - sMin); + tb = t0 + sb * (t1 - t0); + if (tb < t0) { + shading->getColor(t0, &colorB); + } else if (tb > t1) { + shading->getColor(t1, &colorB); + } else { + shading->getColor(tb, &colorB); + } + } + + // compute center and radius of the circle + xb = x0 + sb * (x1 - x0); + yb = y0 + sb * (y1 - y0); + rb = r0 + sb * (r1 - r0); + + // use the average of the colors at the two circles + for (k = 0; k < nComps; ++k) { + colorA.c[k] = (colorA.c[k] + colorB.c[k]) / 2; + } + state->setFillColor(&colorA); + out->updateFillColor(state); + + // construct path for first circle + state->moveTo(xa + ra, ya); + for (k = 1; k < n; ++k) { + angle = ((double)k / (double)n) * 2 * M_PI; + state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle)); + } + state->closePath(); + + // construct and append path for second circle + state->moveTo(xb + rb, yb); + for (k = 1; k < n; ++k) { + angle = ((double)k / (double)n) * 2 * M_PI; + state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle)); + } + state->closePath(); + + // fill the ring + out->eoFill(state); + state->clearPath(); + + // step to the next value of t + ia = ib; + sa = sb; + ta = tb; + xa = xb; + ya = yb; + ra = rb; + colorA = colorB; + } + } +} + +void Gfx::doGouraudTriangleShFill(GfxGouraudTriangleShading *shading) { + double x0, y0, x1, y1, x2, y2; + GfxColor color0, color1, color2; + int i; + + for (i = 0; i < shading->getNTriangles(); ++i) { + shading->getTriangle(i, &x0, &y0, &color0, + &x1, &y1, &color1, + &x2, &y2, &color2); + gouraudFillTriangle(x0, y0, &color0, x1, y1, &color1, x2, y2, &color2, + shading->getColorSpace()->getNComps(), 0); + } +} + +void Gfx::gouraudFillTriangle(double x0, double y0, GfxColor *color0, + double x1, double y1, GfxColor *color1, + double x2, double y2, GfxColor *color2, + int nComps, int depth) { + double x01, y01, x12, y12, x20, y20; + GfxColor color01, color12, color20; + int i; + + for (i = 0; i < nComps; ++i) { + if (abs(color0->c[i] - color1->c[i]) > gouraudColorDelta || + abs(color1->c[i] - color2->c[i]) > gouraudColorDelta) { + break; + } + } + if (i == nComps || depth == gouraudMaxDepth) { + state->setFillColor(color0); + out->updateFillColor(state); + state->moveTo(x0, y0); + state->lineTo(x1, y1); + state->lineTo(x2, y2); + state->closePath(); + out->fill(state); + state->clearPath(); + } else { + x01 = 0.5 * (x0 + x1); + y01 = 0.5 * (y0 + y1); + x12 = 0.5 * (x1 + x2); + y12 = 0.5 * (y1 + y2); + x20 = 0.5 * (x2 + x0); + y20 = 0.5 * (y2 + y0); + //~ if the shading has a Function, this should interpolate on the + //~ function parameter, not on the color components + for (i = 0; i < nComps; ++i) { + color01.c[i] = (color0->c[i] + color1->c[i]) / 2; + color12.c[i] = (color1->c[i] + color2->c[i]) / 2; + color20.c[i] = (color2->c[i] + color0->c[i]) / 2; + } + gouraudFillTriangle(x0, y0, color0, x01, y01, &color01, + x20, y20, &color20, nComps, depth + 1); + gouraudFillTriangle(x01, y01, &color01, x1, y1, color1, + x12, y12, &color12, nComps, depth + 1); + gouraudFillTriangle(x01, y01, &color01, x12, y12, &color12, + x20, y20, &color20, nComps, depth + 1); + gouraudFillTriangle(x20, y20, &color20, x12, y12, &color12, + x2, y2, color2, nComps, depth + 1); + } +} + +void Gfx::doPatchMeshShFill(GfxPatchMeshShading *shading) { + int start, i; + + if (shading->getNPatches() > 128) { + start = 3; + } else if (shading->getNPatches() > 64) { + start = 2; + } else if (shading->getNPatches() > 16) { + start = 1; + } else { + start = 0; + } + for (i = 0; i < shading->getNPatches(); ++i) { + fillPatch(shading->getPatch(i), shading->getColorSpace()->getNComps(), + start); + } +} + +void Gfx::fillPatch(GfxPatch *patch, int nComps, int depth) { + GfxPatch patch00, patch01, patch10, patch11; + double xx[4][8], yy[4][8]; + double xxm, yym; + int i; + + for (i = 0; i < nComps; ++i) { + if (abs(patch->color[0][0].c[i] - patch->color[0][1].c[i]) + > patchColorDelta || + abs(patch->color[0][1].c[i] - patch->color[1][1].c[i]) + > patchColorDelta || + abs(patch->color[1][1].c[i] - patch->color[1][0].c[i]) + > patchColorDelta || + abs(patch->color[1][0].c[i] - patch->color[0][0].c[i]) + > patchColorDelta) { + break; + } + } + if (i == nComps || depth == patchMaxDepth) { + state->setFillColor(&patch->color[0][0]); + out->updateFillColor(state); + state->moveTo(patch->x[0][0], patch->y[0][0]); + state->curveTo(patch->x[0][1], patch->y[0][1], + patch->x[0][2], patch->y[0][2], + patch->x[0][3], patch->y[0][3]); + state->curveTo(patch->x[1][3], patch->y[1][3], + patch->x[2][3], patch->y[2][3], + patch->x[3][3], patch->y[3][3]); + state->curveTo(patch->x[3][2], patch->y[3][2], + patch->x[3][1], patch->y[3][1], + patch->x[3][0], patch->y[3][0]); + state->curveTo(patch->x[2][0], patch->y[2][0], + patch->x[1][0], patch->y[1][0], + patch->x[0][0], patch->y[0][0]); + state->closePath(); + out->fill(state); + state->clearPath(); + } else { + for (i = 0; i < 4; ++i) { + xx[i][0] = patch->x[i][0]; + yy[i][0] = patch->y[i][0]; + xx[i][1] = 0.5 * (patch->x[i][0] + patch->x[i][1]); + yy[i][1] = 0.5 * (patch->y[i][0] + patch->y[i][1]); + xxm = 0.5 * (patch->x[i][1] + patch->x[i][2]); + yym = 0.5 * (patch->y[i][1] + patch->y[i][2]); + xx[i][6] = 0.5 * (patch->x[i][2] + patch->x[i][3]); + yy[i][6] = 0.5 * (patch->y[i][2] + patch->y[i][3]); + xx[i][2] = 0.5 * (xx[i][1] + xxm); + yy[i][2] = 0.5 * (yy[i][1] + yym); + xx[i][5] = 0.5 * (xxm + xx[i][6]); + yy[i][5] = 0.5 * (yym + yy[i][6]); + xx[i][3] = xx[i][4] = 0.5 * (xx[i][2] + xx[i][5]); + yy[i][3] = yy[i][4] = 0.5 * (yy[i][2] + yy[i][5]); + xx[i][7] = patch->x[i][3]; + yy[i][7] = patch->y[i][3]; + } + for (i = 0; i < 4; ++i) { + patch00.x[0][i] = xx[0][i]; + patch00.y[0][i] = yy[0][i]; + patch00.x[1][i] = 0.5 * (xx[0][i] + xx[1][i]); + patch00.y[1][i] = 0.5 * (yy[0][i] + yy[1][i]); + xxm = 0.5 * (xx[1][i] + xx[2][i]); + yym = 0.5 * (yy[1][i] + yy[2][i]); + patch10.x[2][i] = 0.5 * (xx[2][i] + xx[3][i]); + patch10.y[2][i] = 0.5 * (yy[2][i] + yy[3][i]); + patch00.x[2][i] = 0.5 * (patch00.x[1][i] + xxm); + patch00.y[2][i] = 0.5 * (patch00.y[1][i] + yym); + patch10.x[1][i] = 0.5 * (xxm + patch10.x[2][i]); + patch10.y[1][i] = 0.5 * (yym + patch10.y[2][i]); + patch00.x[3][i] = 0.5 * (patch00.x[2][i] + patch10.x[1][i]); + patch00.y[3][i] = 0.5 * (patch00.y[2][i] + patch10.y[1][i]); + patch10.x[0][i] = patch00.x[3][i]; + patch10.y[0][i] = patch00.y[3][i]; + patch10.x[3][i] = xx[3][i]; + patch10.y[3][i] = yy[3][i]; + } + for (i = 4; i < 8; ++i) { + patch01.x[0][i-4] = xx[0][i]; + patch01.y[0][i-4] = yy[0][i]; + patch01.x[1][i-4] = 0.5 * (xx[0][i] + xx[1][i]); + patch01.y[1][i-4] = 0.5 * (yy[0][i] + yy[1][i]); + xxm = 0.5 * (xx[1][i] + xx[2][i]); + yym = 0.5 * (yy[1][i] + yy[2][i]); + patch11.x[2][i-4] = 0.5 * (xx[2][i] + xx[3][i]); + patch11.y[2][i-4] = 0.5 * (yy[2][i] + yy[3][i]); + patch01.x[2][i-4] = 0.5 * (patch01.x[1][i-4] + xxm); + patch01.y[2][i-4] = 0.5 * (patch01.y[1][i-4] + yym); + patch11.x[1][i-4] = 0.5 * (xxm + patch11.x[2][i-4]); + patch11.y[1][i-4] = 0.5 * (yym + patch11.y[2][i-4]); + patch01.x[3][i-4] = 0.5 * (patch01.x[2][i-4] + patch11.x[1][i-4]); + patch01.y[3][i-4] = 0.5 * (patch01.y[2][i-4] + patch11.y[1][i-4]); + patch11.x[0][i-4] = patch01.x[3][i-4]; + patch11.y[0][i-4] = patch01.y[3][i-4]; + patch11.x[3][i-4] = xx[3][i]; + patch11.y[3][i-4] = yy[3][i]; + } + //~ if the shading has a Function, this should interpolate on the + //~ function parameter, not on the color components + for (i = 0; i < nComps; ++i) { + patch00.color[0][0].c[i] = patch->color[0][0].c[i]; + patch00.color[0][1].c[i] = (patch->color[0][0].c[i] + + patch->color[0][1].c[i]) / 2; + patch01.color[0][0].c[i] = patch00.color[0][1].c[i]; + patch01.color[0][1].c[i] = patch->color[0][1].c[i]; + patch01.color[1][1].c[i] = (patch->color[0][1].c[i] + + patch->color[1][1].c[i]) / 2; + patch11.color[0][1].c[i] = patch01.color[1][1].c[i]; + patch11.color[1][1].c[i] = patch->color[1][1].c[i]; + patch11.color[1][0].c[i] = (patch->color[1][1].c[i] + + patch->color[1][0].c[i]) / 2; + patch10.color[1][1].c[i] = patch11.color[1][0].c[i]; + patch10.color[1][0].c[i] = patch->color[1][0].c[i]; + patch10.color[0][0].c[i] = (patch->color[1][0].c[i] + + patch->color[0][0].c[i]) / 2; + patch00.color[1][0].c[i] = patch10.color[0][0].c[i]; + patch00.color[1][1].c[i] = (patch00.color[1][0].c[i] + + patch01.color[1][1].c[i]) / 2; + patch01.color[1][0].c[i] = patch00.color[1][1].c[i]; + patch11.color[0][0].c[i] = patch00.color[1][1].c[i]; + patch10.color[0][1].c[i] = patch00.color[1][1].c[i]; + } + fillPatch(&patch00, nComps, depth + 1); + fillPatch(&patch10, nComps, depth + 1); + fillPatch(&patch01, nComps, depth + 1); + fillPatch(&patch11, nComps, depth + 1); + } +} + +void Gfx::doEndPath() { + if (state->isCurPt() && clip != clipNone) { + state->clip(); + if (clip == clipNormal) { + out->clip(state); + } else { + out->eoClip(state); + } + } + clip = clipNone; + state->clearPath(); +} + +//------------------------------------------------------------------------ +// path clipping operators +//------------------------------------------------------------------------ + +void Gfx::opClip(Object args[], int numArgs) { + clip = clipNormal; +} + +void Gfx::opEOClip(Object args[], int numArgs) { + clip = clipEO; +} + +//------------------------------------------------------------------------ +// text object operators +//------------------------------------------------------------------------ + +void Gfx::opBeginText(Object args[], int numArgs) { + state->setTextMat(1, 0, 0, 1, 0, 0); + state->textMoveTo(0, 0); + out->updateTextMat(state); + out->updateTextPos(state); + fontChanged = gTrue; +} + +void Gfx::opEndText(Object args[], int numArgs) { + out->endTextObject(state); +} + +//------------------------------------------------------------------------ +// text state operators +//------------------------------------------------------------------------ + +void Gfx::opSetCharSpacing(Object args[], int numArgs) { + state->setCharSpace(args[0].getNum()); + out->updateCharSpace(state); +} + +void Gfx::opSetFont(Object args[], int numArgs) { + GfxFont *font; + + if (!(font = res->lookupFont(args[0].getNameC()))) { + return; + } + if (printCommands) { + printf(" font: tag=%s name='%s' %g\n", + font->getTag()->getCString(), + font->getName() ? font->getName()->getCString() : "???", + args[1].getNum()); + fflush(stdout); + } + + font->incRefCnt(); + state->setFont(font, args[1].getNum()); + fontChanged = gTrue; +} + +void Gfx::opSetTextLeading(Object args[], int numArgs) { + state->setLeading(args[0].getNum()); +} + +void Gfx::opSetTextRender(Object args[], int numArgs) { + state->setRender(args[0].getInt()); + out->updateRender(state); +} + +void Gfx::opSetTextRise(Object args[], int numArgs) { + state->setRise(args[0].getNum()); + out->updateRise(state); +} + +void Gfx::opSetWordSpacing(Object args[], int numArgs) { + state->setWordSpace(args[0].getNum()); + out->updateWordSpace(state); +} + +void Gfx::opSetHorizScaling(Object args[], int numArgs) { + state->setHorizScaling(args[0].getNum()); + out->updateHorizScaling(state); + fontChanged = gTrue; +} + +//------------------------------------------------------------------------ +// text positioning operators +//------------------------------------------------------------------------ + +void Gfx::opTextMove(Object args[], int numArgs) { + double tx, ty; + + tx = state->getLineX() + args[0].getNum(); + ty = state->getLineY() + args[1].getNum(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); +} + +void Gfx::opTextMoveSet(Object args[], int numArgs) { + double tx, ty; + + tx = state->getLineX() + args[0].getNum(); + ty = args[1].getNum(); + state->setLeading(-ty); + ty += state->getLineY(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); +} + +void Gfx::opSetTextMatrix(Object args[], int numArgs) { + state->setTextMat(args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum(), + args[4].getNum(), args[5].getNum()); + state->textMoveTo(0, 0); + out->updateTextMat(state); + out->updateTextPos(state); + fontChanged = gTrue; +} + +void Gfx::opTextNextLine(Object args[], int numArgs) { + double tx, ty; + + tx = state->getLineX(); + ty = state->getLineY() - state->getLeading(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); +} + +//------------------------------------------------------------------------ +// text string operators +//------------------------------------------------------------------------ + +void Gfx::opShowText(Object args[], int numArgs) { + if (!state->getFont()) { + error(getPos(), "No font in show"); + return; + } + if (fontChanged) { + out->updateFont(state); + fontChanged = gFalse; + } + out->beginStringOp(state); + doShowText(args[0].getString()); + out->endStringOp(state); +} + +void Gfx::opMoveShowText(Object args[], int numArgs) { + double tx, ty; + + if (!state->getFont()) { + error(getPos(), "No font in move/show"); + return; + } + if (fontChanged) { + out->updateFont(state); + fontChanged = gFalse; + } + tx = state->getLineX(); + ty = state->getLineY() - state->getLeading(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); + out->beginStringOp(state); + doShowText(args[0].getString()); + out->endStringOp(state); +} + +void Gfx::opMoveSetShowText(Object args[], int numArgs) { + double tx, ty; + + if (!state->getFont()) { + error(getPos(), "No font in move/set/show"); + return; + } + if (fontChanged) { + out->updateFont(state); + fontChanged = gFalse; + } + state->setWordSpace(args[0].getNum()); + state->setCharSpace(args[1].getNum()); + tx = state->getLineX(); + ty = state->getLineY() - state->getLeading(); + state->textMoveTo(tx, ty); + out->updateWordSpace(state); + out->updateCharSpace(state); + out->updateTextPos(state); + out->beginStringOp(state); + doShowText(args[2].getString()); + out->endStringOp(state); +} + +void Gfx::opShowSpaceText(Object args[], int numArgs) { + Array *a; + Object obj; + int wMode; + int i; + + if (!state->getFont()) { + error(getPos(), "No font in show/space"); + return; + } + if (fontChanged) { + out->updateFont(state); + fontChanged = gFalse; + } + out->beginStringOp(state); + wMode = state->getFont()->getWMode(); + a = args[0].getArray(); + for (i = 0; i < a->getLength(); ++i) { + a->get(i, &obj); + if (obj.isNum()) { + // this uses the absolute value of the font size to match + // Acrobat's behavior + if (wMode) { + state->textShift(0, -obj.getNum() * 0.001 * + fabs(state->getFontSize())); + } else { + state->textShift(-obj.getNum() * 0.001 * + fabs(state->getFontSize()), 0); + } + out->updateTextShift(state, obj.getNum()); + } else if (obj.isString()) { + doShowText(obj.getString()); + } else { + error(getPos(), "Element of show/space array must be number or string"); + } + obj.free(); + } + out->endStringOp(state); +} + +void Gfx::doShowText(GooString *s) { + GfxFont *font; + int wMode; + double riseX, riseY; + CharCode code; + Unicode u[8]; + double x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy, lineX, lineY; + double originX, originY, tOriginX, tOriginY; + double oldCTM[6], newCTM[6]; + double *mat; + Object charProc; + Dict *resDict; + Parser *oldParser; + char *p; + int len, n, uLen, nChars, nSpaces, i; + + font = state->getFont(); + wMode = font->getWMode(); + + if (out->useDrawChar()) { + out->beginString(state, s); + } + + // handle a Type 3 char + if (font->getType() == fontType3 && out->interpretType3Chars()) { + mat = state->getCTM(); + for (i = 0; i < 6; ++i) { + oldCTM[i] = mat[i]; + } + mat = state->getTextMat(); + newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2]; + newCTM[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3]; + newCTM[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2]; + newCTM[3] = mat[2] * oldCTM[1] + mat[3] * oldCTM[3]; + mat = font->getFontMatrix(); + newCTM[0] = mat[0] * newCTM[0] + mat[1] * newCTM[2]; + newCTM[1] = mat[0] * newCTM[1] + mat[1] * newCTM[3]; + newCTM[2] = mat[2] * newCTM[0] + mat[3] * newCTM[2]; + newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3]; + newCTM[0] *= state->getFontSize(); + newCTM[1] *= state->getFontSize(); + newCTM[2] *= state->getFontSize(); + newCTM[3] *= state->getFontSize(); + newCTM[0] *= state->getHorizScaling(); + newCTM[2] *= state->getHorizScaling(); + state->textTransformDelta(0, state->getRise(), &riseX, &riseY); + curX = state->getCurX(); + curY = state->getCurY(); + lineX = state->getLineX(); + lineY = state->getLineY(); + oldParser = parser; + p = s->getCString(); + len = s->getLength(); + while (len > 0) { + n = font->getNextChar(p, len, &code, + u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, + &dx, &dy, &originX, &originY); + dx = dx * state->getFontSize() + state->getCharSpace(); + if (n == 1 && *p == ' ') { + dx += state->getWordSpace(); + } + dx *= state->getHorizScaling(); + dy *= state->getFontSize(); + state->textTransformDelta(dx, dy, &tdx, &tdy); + state->transform(curX + riseX, curY + riseY, &x, &y); + saveState(); + state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y); + //~ out->updateCTM(???) + if (!out->beginType3Char(state, curX + riseX, curY + riseY, tdx, tdy, + code, u, uLen)) { + ((Gfx8BitFont *)font)->getCharProc(code, &charProc); + if ((resDict = ((Gfx8BitFont *)font)->getResources())) { + pushResources(resDict); + } + if (charProc.isStream()) { + display(&charProc, gFalse); + } else { + error(getPos(), "Missing or bad Type3 CharProc entry"); + } + out->endType3Char(state); + if (resDict) { + popResources(); + } + charProc.free(); + } + restoreState(); + // GfxState::restore() does *not* restore the current position, + // so we deal with it here using (curX, curY) and (lineX, lineY) + curX += tdx; + curY += tdy; + state->moveTo(curX, curY); + state->textSetPos(lineX, lineY); + p += n; + len -= n; + } + parser = oldParser; + + } else if (out->useDrawChar()) { + state->textTransformDelta(0, state->getRise(), &riseX, &riseY); + p = s->getCString(); + len = s->getLength(); + while (len > 0) { + n = font->getNextChar(p, len, &code, + u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, + &dx, &dy, &originX, &originY); + if (wMode) { + dx *= state->getFontSize(); + dy = dy * state->getFontSize() + state->getCharSpace(); + if (n == 1 && *p == ' ') { + dy += state->getWordSpace(); + } + } else { + dx = dx * state->getFontSize() + state->getCharSpace(); + if (n == 1 && *p == ' ') { + dx += state->getWordSpace(); + } + dx *= state->getHorizScaling(); + dy *= state->getFontSize(); + } + state->textTransformDelta(dx, dy, &tdx, &tdy); + originX *= state->getFontSize(); + originY *= state->getFontSize(); + state->textTransformDelta(originX, originY, &tOriginX, &tOriginY); + out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY, + tdx, tdy, tOriginX, tOriginY, code, n, u, uLen); + state->shift(tdx, tdy); + p += n; + len -= n; + } + + } else { + dx = dy = 0; + p = s->getCString(); + len = s->getLength(); + nChars = nSpaces = 0; + while (len > 0) { + n = font->getNextChar(p, len, &code, + u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, + &dx2, &dy2, &originX, &originY); + dx += dx2; + dy += dy2; + if (n == 1 && *p == ' ') { + ++nSpaces; + } + ++nChars; + p += n; + len -= n; + } + if (wMode) { + dx *= state->getFontSize(); + dy = dy * state->getFontSize() + + nChars * state->getCharSpace() + + nSpaces * state->getWordSpace(); + } else { + dx = dx * state->getFontSize() + + nChars * state->getCharSpace() + + nSpaces * state->getWordSpace(); + dx *= state->getHorizScaling(); + dy *= state->getFontSize(); + } + state->textTransformDelta(dx, dy, &tdx, &tdy); + out->drawString(state, s); + state->shift(tdx, tdy); + } + + if (out->useDrawChar()) { + out->endString(state); + } + + updateLevel += 10 * s->getLength(); +} + +//------------------------------------------------------------------------ +// XObject operators +//------------------------------------------------------------------------ + +void Gfx::opXObject(Object args[], int numArgs) { + Object obj1, obj2, obj3, refObj; +#if OPI_SUPPORT + Object opiDict; +#endif + + if (!res->lookupXObject(args[0].getNameC(), &obj1)) { + return; + } + if (!obj1.isStream()) { + error(getPos(), "XObject '%s' is wrong type", args[0].getNameC()); + obj1.free(); + return; + } +#if OPI_SUPPORT + obj1.streamGetDict()->lookup("OPI", &opiDict); + if (opiDict.isDict()) { + out->opiBegin(state, opiDict.getDict()); + } +#endif + obj1.streamGetDict()->lookup("Subtype", &obj2); + if (obj2.isName("Image")) { + if (out->needNonText()) { + res->lookupXObjectNF(args[0].getNameC(), &refObj); + doImage(&refObj, obj1.getStream(), gFalse); + refObj.free(); + } + } else if (obj2.isName("Form")) { + doForm(&obj1); + } else if (obj2.isName("PS")) { + obj1.streamGetDict()->lookup("Level1", &obj3); + out->psXObject(obj1.getStream(), + obj3.isStream() ? obj3.getStream() : (Stream *)NULL); + } else if (obj2.isName()) { + error(getPos(), "Unknown XObject subtype '%s'", obj2.getNameC()); + } else { + error(getPos(), "XObject subtype is missing or wrong type"); + } + obj2.free(); +#if OPI_SUPPORT + if (opiDict.isDict()) { + out->opiEnd(state, opiDict.getDict()); + } + opiDict.free(); +#endif + obj1.free(); +} + +void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { + Dict *dict, *maskDict; + int width, height; + int bits, maskBits; + StreamColorSpaceMode csMode; + GBool mask; + GBool invert; + GfxColorSpace *colorSpace, *maskColorSpace; + GfxImageColorMap *colorMap, *maskColorMap; + Object maskObj, smaskObj; + GBool haveColorKeyMask, haveExplicitMask, haveSoftMask; + int maskColors[2*gfxColorMaxComps]; + int maskWidth, maskHeight; + GBool maskInvert; + Stream *maskStr; + Object obj1, obj2; + int i; + + // get info from the stream + bits = 0; + csMode = streamCSNone; + str->getImageParams(&bits, &csMode); + + // get stream dict + dict = str->getDict(); + + // get size + dict->lookup("Width", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("W", &obj1); + } + if (!obj1.isInt()) + goto err2; + width = obj1.getInt(); + obj1.free(); + dict->lookup("Height", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("H", &obj1); + } + if (!obj1.isInt()) + goto err2; + height = obj1.getInt(); + obj1.free(); + + // image or mask? + dict->lookup("ImageMask", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("IM", &obj1); + } + mask = gFalse; + if (obj1.isBool()) + mask = obj1.getBool(); + else if (!obj1.isNull()) + goto err2; + obj1.free(); + + // bit depth + if (bits == 0) { + dict->lookup("BitsPerComponent", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("BPC", &obj1); + } + if (obj1.isInt()) { + bits = obj1.getInt(); + } else if (mask) { + bits = 1; + } else { + goto err2; + } + obj1.free(); + } + + // display a mask + if (mask) { + + // check for inverted mask + if (bits != 1) + goto err1; + invert = gFalse; + dict->lookup("Decode", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("D", &obj1); + } + if (obj1.isArray()) { + obj1.arrayGet(0, &obj2); + if (obj2.isInt() && obj2.getInt() == 1) + invert = gTrue; + obj2.free(); + } else if (!obj1.isNull()) { + goto err2; + } + obj1.free(); + + // draw it + out->drawImageMask(state, ref, str, width, height, invert, inlineImg); + + } else { + + // get color space and color map + dict->lookup("ColorSpace", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("CS", &obj1); + } + if (obj1.isName()) { + res->lookupColorSpace(obj1.getNameC(), &obj2); + if (!obj2.isNull()) { + obj1.free(); + obj1 = obj2; + } else { + obj2.free(); + } + } + if (!obj1.isNull()) { + colorSpace = GfxColorSpace::parse(&obj1); + } else if (csMode == streamCSDeviceGray) { + colorSpace = new GfxDeviceGrayColorSpace(); + } else if (csMode == streamCSDeviceRGB) { + colorSpace = new GfxDeviceRGBColorSpace(); + } else if (csMode == streamCSDeviceCMYK) { + colorSpace = new GfxDeviceCMYKColorSpace(); + } else { + colorSpace = NULL; + } + obj1.free(); + if (!colorSpace) { + goto err1; + } + dict->lookup("Decode", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("D", &obj1); + } + colorMap = new GfxImageColorMap(bits, &obj1, colorSpace); + obj1.free(); + if (!colorMap->isOk()) { + delete colorMap; + goto err1; + } + + // get the mask + haveColorKeyMask = haveExplicitMask = haveSoftMask = gFalse; + maskStr = NULL; // make gcc happy + maskWidth = maskHeight = 0; // make gcc happy + maskInvert = gFalse; // make gcc happy + maskColorMap = NULL; // make gcc happy + dict->lookup("Mask", &maskObj); + dict->lookup("SMask", &smaskObj); + if (smaskObj.isStream()) { + // soft mask + if (inlineImg) { + goto err1; + } + maskStr = smaskObj.getStream(); + maskDict = smaskObj.streamGetDict(); + maskDict->lookup("Width", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("W", &obj1); + } + if (!obj1.isInt()) { + goto err2; + } + maskWidth = obj1.getInt(); + obj1.free(); + maskDict->lookup("Height", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("H", &obj1); + } + if (!obj1.isInt()) { + goto err2; + } + maskHeight = obj1.getInt(); + obj1.free(); + maskDict->lookup("BitsPerComponent", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("BPC", &obj1); + } + if (!obj1.isInt()) { + goto err2; + } + maskBits = obj1.getInt(); + obj1.free(); + maskDict->lookup("ColorSpace", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("CS", &obj1); + } + if (obj1.isName()) { + res->lookupColorSpace(obj1.getNameC(), &obj2); + if (!obj2.isNull()) { + obj1.free(); + obj1 = obj2; + } else { + obj2.free(); + } + } + maskColorSpace = GfxColorSpace::parse(&obj1); + obj1.free(); + if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) { + goto err1; + } + maskDict->lookup("Decode", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("D", &obj1); + } + maskColorMap = new GfxImageColorMap(maskBits, &obj1, maskColorSpace); + obj1.free(); + if (!maskColorMap->isOk()) { + delete maskColorMap; + goto err1; + } + //~ handle the Matte entry + haveSoftMask = gTrue; + } else if (maskObj.isArray()) { + // color key mask + for (i = 0; + i < maskObj.arrayGetLength() && i < 2*gfxColorMaxComps; + ++i) { + maskObj.arrayGet(i, &obj1); + maskColors[i] = obj1.getInt(); + obj1.free(); + } + haveColorKeyMask = gTrue; + } else if (maskObj.isStream()) { + // explicit mask + if (inlineImg) { + goto err1; + } + maskStr = maskObj.getStream(); + maskDict = maskObj.streamGetDict(); + maskDict->lookup("Width", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("W", &obj1); + } + if (!obj1.isInt()) { + goto err2; + } + maskWidth = obj1.getInt(); + obj1.free(); + maskDict->lookup("Height", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("H", &obj1); + } + if (!obj1.isInt()) { + goto err2; + } + maskHeight = obj1.getInt(); + obj1.free(); + maskDict->lookup("ImageMask", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("IM", &obj1); + } + if (!obj1.isBool() || !obj1.getBool()) { + goto err2; + } + obj1.free(); + maskInvert = gFalse; + maskDict->lookup("Decode", &obj1); + if (obj1.isNull()) { + obj1.free(); + maskDict->lookup("D", &obj1); + } + if (obj1.isArray()) { + obj1.arrayGet(0, &obj2); + if (obj2.isInt() && obj2.getInt() == 1) { + maskInvert = gTrue; + } + obj2.free(); + } else if (!obj1.isNull()) { + goto err2; + } + obj1.free(); + haveExplicitMask = gTrue; + } + + // draw it + if (haveSoftMask) { + out->drawSoftMaskedImage(state, ref, str, width, height, colorMap, + maskStr, maskWidth, maskHeight, maskColorMap); + delete maskColorMap; + } else if (haveExplicitMask) { + out->drawMaskedImage(state, ref, str, width, height, colorMap, + maskStr, maskWidth, maskHeight, maskInvert); + } else { + out->drawImage(state, ref, str, width, height, colorMap, + haveColorKeyMask ? maskColors : (int *)NULL, inlineImg); + } + delete colorMap; + + maskObj.free(); + smaskObj.free(); + } + + if ((i = width * height) > 1000) { + i = 1000; + } + updateLevel += i; + + return; + + err2: + obj1.free(); + err1: + error(getPos(), "Bad image parameters"); +} + +void Gfx::doForm(Object *str) { + Dict *dict; + Object matrixObj, bboxObj; + double m[6], bbox[6]; + Object resObj; + Dict *resDict; + Object obj1; + int i; + + // check for excessive recursion + if (formDepth > 20) { + return; + } + + // get stream dict + dict = str->streamGetDict(); + + // check form type + dict->lookup("FormType", &obj1); + if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) { + error(getPos(), "Unknown form type"); + } + obj1.free(); + + // get bounding box + dict->lookup("BBox", &bboxObj); + if (!bboxObj.isArray()) { + matrixObj.free(); + bboxObj.free(); + error(getPos(), "Bad form bounding box"); + return; + } + for (i = 0; i < 4; ++i) { + bboxObj.arrayGet(i, &obj1); + bbox[i] = obj1.getNum(); + obj1.free(); + } + bboxObj.free(); + + // get matrix + dict->lookup("Matrix", &matrixObj); + if (matrixObj.isArray()) { + for (i = 0; i < 6; ++i) { + matrixObj.arrayGet(i, &obj1); + m[i] = obj1.getNum(); + obj1.free(); + } + } else { + m[0] = 1; m[1] = 0; + m[2] = 0; m[3] = 1; + m[4] = 0; m[5] = 0; + } + matrixObj.free(); + + // get resources + dict->lookup("Resources", &resObj); + resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; + + // draw it + ++formDepth; + doForm1(str, resDict, m, bbox); + --formDepth; + + resObj.free(); +} + +void Gfx::doAnnot(Object *str, double xMin, double yMin, + double xMax, double yMax) { + Dict *dict, *resDict; + Object matrixObj, bboxObj, resObj; + Object obj1; + double m[6], bbox[6], ictm[6]; + double *ctm; + double formX0, formY0, formX1, formY1; + double annotX0, annotY0, annotX1, annotY1; + double det, x, y, sx, sy; + int i; + + // get stream dict + dict = str->streamGetDict(); + + // get the form bounding box + dict->lookup("BBox", &bboxObj); + if (!bboxObj.isArray()) { + bboxObj.free(); + error(getPos(), "Bad form bounding box"); + return; + } + for (i = 0; i < 4; ++i) { + bboxObj.arrayGet(i, &obj1); + bbox[i] = obj1.getNum(); + obj1.free(); + } + bboxObj.free(); + + // get the form matrix + dict->lookup("Matrix", &matrixObj); + if (matrixObj.isArray()) { + for (i = 0; i < 6; ++i) { + matrixObj.arrayGet(i, &obj1); + m[i] = obj1.getNum(); + obj1.free(); + } + } else { + m[0] = 1; m[1] = 0; + m[2] = 0; m[3] = 1; + m[4] = 0; m[5] = 0; + } + matrixObj.free(); + + // transform the form bbox from form space to user space + formX0 = bbox[0] * m[0] + bbox[1] * m[2] + m[4]; + formY0 = bbox[0] * m[1] + bbox[1] * m[3] + m[5]; + formX1 = bbox[2] * m[0] + bbox[3] * m[2] + m[4]; + formY1 = bbox[2] * m[1] + bbox[3] * m[3] + m[5]; + + // transform the annotation bbox from default user space to user + // space: (bbox * baseMatrix) * iCTM + ctm = state->getCTM(); + det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + ictm[0] = ctm[3] * det; + ictm[1] = -ctm[1] * det; + ictm[2] = -ctm[2] * det; + ictm[3] = ctm[0] * det; + ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; + ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; + x = baseMatrix[0] * xMin + baseMatrix[2] * yMin + baseMatrix[4]; + y = baseMatrix[1] * xMin + baseMatrix[3] * yMin + baseMatrix[5]; + annotX0 = ictm[0] * x + ictm[2] * y + ictm[4]; + annotY0 = ictm[1] * x + ictm[3] * y + ictm[5]; + x = baseMatrix[0] * xMax + baseMatrix[2] * yMax + baseMatrix[4]; + y = baseMatrix[1] * xMax + baseMatrix[3] * yMax + baseMatrix[5]; + annotX1 = ictm[0] * x + ictm[2] * y + ictm[4]; + annotY1 = ictm[1] * x + ictm[3] * y + ictm[5]; + + // swap min/max coords + if (formX0 > formX1) { + x = formX0; formX0 = formX1; formX1 = x; + } + if (formY0 > formY1) { + y = formY0; formY0 = formY1; formY1 = y; + } + if (annotX0 > annotX1) { + x = annotX0; annotX0 = annotX1; annotX1 = x; + } + if (annotY0 > annotY1) { + y = annotY0; annotY0 = annotY1; annotY1 = y; + } + + // scale the form to fit the annotation bbox + if (formX1 == formX0) { + // this shouldn't happen + sx = 1; + } else { + sx = (annotX1 - annotX0) / (formX1 - formX0); + } + if (formY1 == formY0) { + // this shouldn't happen + sy = 1; + } else { + sy = (annotY1 - annotY0) / (formY1 - formY0); + } + m[0] *= sx; + m[2] *= sx; + m[4] = (m[4] - formX0) * sx + annotX0; + m[1] *= sy; + m[3] *= sy; + m[5] = (m[5] - formY0) * sy + annotY0; + + // get resources + dict->lookup("Resources", &resObj); + resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; + + // draw it + doForm1(str, resDict, m, bbox); + + resObj.free(); + bboxObj.free(); +} + +void Gfx::doForm1(Object *str, Dict *resDict, double *matrix, double *bbox) { + Parser *oldParser; + double oldBaseMatrix[6]; + int i; + + // push new resources on stack + pushResources(resDict); + + // save current graphics state + saveState(); + + // kill any pre-existing path + state->clearPath(); + + // save current parser + oldParser = parser; + + // set form transformation matrix + state->concatCTM(matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5]); + out->updateCTM(state, matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5]); + + // set new base matrix + for (i = 0; i < 6; ++i) { + oldBaseMatrix[i] = baseMatrix[i]; + baseMatrix[i] = state->getCTM()[i]; + } + + // set form bounding box + state->moveTo(bbox[0], bbox[1]); + state->lineTo(bbox[2], bbox[1]); + state->lineTo(bbox[2], bbox[3]); + state->lineTo(bbox[0], bbox[3]); + state->closePath(); + state->clip(); + out->clip(state); + state->clearPath(); + + // draw the form + display(str, gFalse); + + // restore base matrix + for (i = 0; i < 6; ++i) { + baseMatrix[i] = oldBaseMatrix[i]; + } + + // restore parser + parser = oldParser; + + // restore graphics state + restoreState(); + + // pop resource stack + popResources(); + + return; +} + +//------------------------------------------------------------------------ +// in-line image operators +//------------------------------------------------------------------------ + +void Gfx::opBeginImage(Object args[], int numArgs) { + Stream *str; + int c1, c2; + + // build dict/stream + str = buildImageStream(); + + // display the image + if (str) { + doImage(NULL, str, gTrue); + + // skip 'EI' tag + c1 = str->getBaseStream()->getChar(); + c2 = str->getBaseStream()->getChar(); + while (!(c1 == 'E' && c2 == 'I') && c2 != EOF) { + c1 = c2; + c2 = str->getBaseStream()->getChar(); + } + delete str; + } +} + +Stream *Gfx::buildImageStream() { + Object dict; + Object obj; + Object dictObj; + Stream *str; + GBool isEOF = gFalse; + + dict.initDict(xref); + while (1) { + parser->getObj(&obj); + isEOF = obj.isEOF(); + if (isEOF || obj.isCmd("ID")) + break; + if (!obj.isName()) { + error(getPos(), "Inline image dictionary key must be a name object"); + } else { + parser->getObj(&dictObj); + isEOF = dictObj.isEOF(); + if (isEOF) + break; + if (dictObj.isError()) { + // FIXME: we probably should not build a stream in this case either + // but this behaviour was in poppler for a while so maybe it's ok + dictObj.free(); + break; + } + dict.dictAddOwnVal(obj.getNameC(), &dictObj); + } + obj.free(); + } + + obj.free(); + if (isEOF) { + error(getPos(), "End of file in inline image"); + dict.free(); + return NULL; + } + + str = new EmbedStream(parser->getStream(), &dict, gFalse, 0); + str = str->addFilters(&dict); + + return str; +} + +void Gfx::opImageData(Object args[], int numArgs) { + error(getPos(), "Internal: got 'ID' operator"); +} + +void Gfx::opEndImage(Object args[], int numArgs) { + error(getPos(), "Internal: got 'EI' operator"); +} + +//------------------------------------------------------------------------ +// type 3 font operators +//------------------------------------------------------------------------ + +void Gfx::opSetCharWidth(Object args[], int numArgs) { + out->type3D0(state, args[0].getNum(), args[1].getNum()); +} + +void Gfx::opSetCacheDevice(Object args[], int numArgs) { + out->type3D1(state, args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum(), + args[4].getNum(), args[5].getNum()); +} + +//------------------------------------------------------------------------ +// compatibility operators +//------------------------------------------------------------------------ + +void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) { + ++ignoreUndef; +} + +void Gfx::opEndIgnoreUndef(Object args[], int numArgs) { + if (ignoreUndef > 0) + --ignoreUndef; +} + +//------------------------------------------------------------------------ +// marked content operators +//------------------------------------------------------------------------ + +void Gfx::opBeginMarkedContent(Object args[], int numArgs) { + if (printCommands) { + printf(" marked content: %s ", args[0].getNameC()); + if (numArgs == 2) + args[2].print(stdout); + printf("\n"); + fflush(stdout); + } + + if(numArgs == 2) { + out->beginMarkedContent(args[0].getNameC(),args[1].getDict()); + } else { + out->beginMarkedContent(args[0].getNameC()); + } +} + +void Gfx::opEndMarkedContent(Object args[], int numArgs) { + out->endMarkedContent(); +} + +void Gfx::opMarkPoint(Object args[], int numArgs) { + if (printCommands) { + printf(" mark point: %s ", args[0].getNameC()); + if (numArgs == 2) + args[2].print(stdout); + printf("\n"); + fflush(stdout); + } + + if(numArgs == 2) { + out->markPoint(args[0].getNameC(),args[1].getDict()); + } else { + out->markPoint(args[0].getNameC()); + } + +} + +//------------------------------------------------------------------------ +// misc +//------------------------------------------------------------------------ + +void Gfx::saveState() { + out->saveState(state); + state = state->save(); +} + +void Gfx::restoreState() { + state = state->restore(); + out->restoreState(state); +} + +void Gfx::pushResources(Dict *resDict) { + res = new GfxResources(xref, resDict, res); +} + +void Gfx::popResources() { + GfxResources *resPtr; + + resPtr = res->getNext(); + delete res; + res = resPtr; +} diff --git a/rosapps/smartpdf/poppler/poppler/Gfx.h b/rosapps/smartpdf/poppler/poppler/Gfx.h new file mode 100644 index 00000000000..8e8c96b2438 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Gfx.h @@ -0,0 +1,293 @@ +//======================================================================== +// +// Gfx.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GFX_H +#define GFX_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "Object.h" + +class GooString; +class XRef; +class Array; +class Stream; +class Parser; +class Dict; +class OutputDev; +class GfxFontDict; +class GfxFont; +class GfxPattern; +class GfxTilingPattern; +class GfxShadingPattern; +class GfxShading; +class GfxFunctionShading; +class GfxAxialShading; +class GfxRadialShading; +class GfxGouraudTriangleShading; +class GfxPatchMeshShading; +struct GfxPatch; +class GfxState; +struct GfxColor; +class Gfx; +class PDFRectangle; + +//------------------------------------------------------------------------ +// Gfx +//------------------------------------------------------------------------ + +enum GfxClipType { + clipNone, + clipNormal, + clipEO +}; + +enum TchkType { + tchkBool, // boolean + tchkInt, // integer + tchkNum, // number (integer or real) + tchkString, // string + tchkName, // name + tchkArray, // array + tchkProps, // properties (dictionary or name) + tchkSCN, // scn/SCN args (number of name) + tchkNone // used to avoid empty initializer lists +}; + +#define maxArgs 8 + +struct Operator { + char name[4]; + int numArgs; + TchkType tchk[maxArgs]; + void (Gfx::*func)(Object args[], int numArgs); +}; + +class GfxResources { +public: + + GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA); + ~GfxResources(); + + GfxFont *lookupFont(char *name); + GBool lookupXObject(char *name, Object *obj); + GBool lookupXObjectNF(char *name, Object *obj); + void lookupColorSpace(char *name, Object *obj); + GfxPattern *lookupPattern(char *name); + GfxShading *lookupShading(char *name); + GBool lookupGState(char *name, Object *obj); + + GfxResources *getNext() { return next; } + +private: + + GfxFontDict *fonts; + Object xObjDict; + Object colorSpaceDict; + Object patternDict; + Object shadingDict; + Object gStateDict; + GfxResources *next; +}; + +class Gfx { +public: + + // Constructor for regular output. + Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, + double hDPI, double vDPI, PDFRectangle *box, + PDFRectangle *cropBox, int rotate, + GBool (*abortCheckCbkA)(void *data) = NULL, + void *abortCheckCbkDataA = NULL); + + // Constructor for a sub-page object. + Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, + PDFRectangle *box, PDFRectangle *cropBox, + GBool (*abortCheckCbkA)(void *data) = NULL, + void *abortCheckCbkDataA = NULL); + + ~Gfx(); + + // Interpret a stream or array of streams. + void display(Object *obj, GBool topLevel = gTrue); + + // Display an annotation, given its appearance (a Form XObject) and + // bounding box (in default user space). + void doAnnot(Object *str, double xMin, double yMin, + double xMax, double yMax); + + // Save graphics state. + void saveState(); + + // Restore graphics state. + void restoreState(); + + // Get the current graphics state object. + GfxState *getState() { return state; } + +private: + + XRef *xref; // the xref table for this PDF file + OutputDev *out; // output device + GBool subPage; // is this a sub-page object? + GBool printCommands; // print the drawing commands (for debugging) + GBool profileCommands; // profile the drawing commands (for debugging) + GfxResources *res; // resource stack + int updateLevel; + + GfxState *state; // current graphics state + GBool fontChanged; // set if font or text matrix has changed + GfxClipType clip; // do a clip? + int ignoreUndef; // current BX/EX nesting level + double baseMatrix[6]; // default matrix for most recent + // page/form/pattern + int formDepth; + + Parser *parser; // parser for page content stream(s) + + GBool // callback to check for an abort + (*abortCheckCbk)(void *data); + void *abortCheckCbkData; + + static Operator opTab[]; // table of operators + + void go(GBool topLevel); + void execOp(Object *cmd, Object args[], int numArgs); + Operator *findOp(char *name); + GBool checkArg(Object *arg, TchkType type); + int getPos(); + + // graphics state operators + void opSave(Object args[], int numArgs); + void opRestore(Object args[], int numArgs); + void opConcat(Object args[], int numArgs); + void opSetDash(Object args[], int numArgs); + void opSetFlat(Object args[], int numArgs); + void opSetLineJoin(Object args[], int numArgs); + void opSetLineCap(Object args[], int numArgs); + void opSetMiterLimit(Object args[], int numArgs); + void opSetLineWidth(Object args[], int numArgs); + void opSetExtGState(Object args[], int numArgs); + void opSetRenderingIntent(Object args[], int numArgs); + + // color operators + void opSetFillGray(Object args[], int numArgs); + void opSetStrokeGray(Object args[], int numArgs); + void opSetFillCMYKColor(Object args[], int numArgs); + void opSetStrokeCMYKColor(Object args[], int numArgs); + void opSetFillRGBColor(Object args[], int numArgs); + void opSetStrokeRGBColor(Object args[], int numArgs); + void opSetFillColorSpace(Object args[], int numArgs); + void opSetStrokeColorSpace(Object args[], int numArgs); + void opSetFillColor(Object args[], int numArgs); + void opSetStrokeColor(Object args[], int numArgs); + void opSetFillColorN(Object args[], int numArgs); + void opSetStrokeColorN(Object args[], int numArgs); + + // path segment operators + void opMoveTo(Object args[], int numArgs); + void opLineTo(Object args[], int numArgs); + void opCurveTo(Object args[], int numArgs); + void opCurveTo1(Object args[], int numArgs); + void opCurveTo2(Object args[], int numArgs); + void opRectangle(Object args[], int numArgs); + void opClosePath(Object args[], int numArgs); + + // path painting operators + void opEndPath(Object args[], int numArgs); + void opStroke(Object args[], int numArgs); + void opCloseStroke(Object args[], int numArgs); + void opFill(Object args[], int numArgs); + void opEOFill(Object args[], int numArgs); + void opFillStroke(Object args[], int numArgs); + void opCloseFillStroke(Object args[], int numArgs); + void opEOFillStroke(Object args[], int numArgs); + void opCloseEOFillStroke(Object args[], int numArgs); + void doPatternFill(GBool eoFill); + void doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill); + void doShadingPatternFill(GfxShadingPattern *sPat, GBool eoFill); + void opShFill(Object args[], int numArgs); + void doFunctionShFill(GfxFunctionShading *shading); + void doFunctionShFill1(GfxFunctionShading *shading, + double x0, double y0, + double x1, double y1, + GfxColor *colors, int depth); + void doAxialShFill(GfxAxialShading *shading); + void doRadialShFill(GfxRadialShading *shading); + void doGouraudTriangleShFill(GfxGouraudTriangleShading *shading); + void gouraudFillTriangle(double x0, double y0, GfxColor *color0, + double x1, double y1, GfxColor *color1, + double x2, double y2, GfxColor *color2, + int nComps, int depth); + void doPatchMeshShFill(GfxPatchMeshShading *shading); + void fillPatch(GfxPatch *patch, int nComps, int depth); + void doEndPath(); + + // path clipping operators + void opClip(Object args[], int numArgs); + void opEOClip(Object args[], int numArgs); + + // text object operators + void opBeginText(Object args[], int numArgs); + void opEndText(Object args[], int numArgs); + + // text state operators + void opSetCharSpacing(Object args[], int numArgs); + void opSetFont(Object args[], int numArgs); + void opSetTextLeading(Object args[], int numArgs); + void opSetTextRender(Object args[], int numArgs); + void opSetTextRise(Object args[], int numArgs); + void opSetWordSpacing(Object args[], int numArgs); + void opSetHorizScaling(Object args[], int numArgs); + + // text positioning operators + void opTextMove(Object args[], int numArgs); + void opTextMoveSet(Object args[], int numArgs); + void opSetTextMatrix(Object args[], int numArgs); + void opTextNextLine(Object args[], int numArgs); + + // text string operators + void opShowText(Object args[], int numArgs); + void opMoveShowText(Object args[], int numArgs); + void opMoveSetShowText(Object args[], int numArgs); + void opShowSpaceText(Object args[], int numArgs); + void doShowText(GooString *s); + + // XObject operators + void opXObject(Object args[], int numArgs); + void doImage(Object *ref, Stream *str, GBool inlineImg); + void doForm(Object *str); + void doForm1(Object *str, Dict *resDict, double *matrix, double *bbox); + + // in-line image operators + void opBeginImage(Object args[], int numArgs); + Stream *buildImageStream(); + void opImageData(Object args[], int numArgs); + void opEndImage(Object args[], int numArgs); + + // type 3 font operators + void opSetCharWidth(Object args[], int numArgs); + void opSetCacheDevice(Object args[], int numArgs); + + // compatibility operators + void opBeginIgnoreUndef(Object args[], int numArgs); + void opEndIgnoreUndef(Object args[], int numArgs); + + // marked content operators + void opBeginMarkedContent(Object args[], int numArgs); + void opEndMarkedContent(Object args[], int numArgs); + void opMarkPoint(Object args[], int numArgs); + + void pushResources(Dict *resDict); + void popResources(); +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/GfxFont.cc b/rosapps/smartpdf/poppler/poppler/GfxFont.cc new file mode 100644 index 00000000000..baf4a1f7d58 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/GfxFont.cc @@ -0,0 +1,1649 @@ +//======================================================================== +// +// GfxFont.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include "goo/gmem.h" +#include "Error.h" +#include "Object.h" +#include "Dict.h" +#include "GlobalParams.h" +#include "CMap.h" +#include "CharCodeToUnicode.h" +#include "FontEncodingTables.h" +#include "BuiltinFontTables.h" +#include +#include +#include +#include "UGooString.h" +#include "GfxFont.h" + +//------------------------------------------------------------------------ + +struct StdFontMapEntry { + char *altName; + char *properName; +}; + +// Acrobat 4.0 and earlier substituted Base14-compatible fonts without +// providing Widths and a FontDescriptor, so we munge the names into +// the proper Base14 names. This table is from implementation note 44 +// in the PDF 1.4 spec, with some additions based on empirical +// evidence. +static StdFontMapEntry stdFontMap[] = { + { "Arial", "Helvetica" }, + { "Arial,Bold", "Helvetica-Bold" }, + { "Arial,BoldItalic", "Helvetica-BoldOblique" }, + { "Arial,Italic", "Helvetica-Oblique" }, + { "Arial-Bold", "Helvetica-Bold" }, + { "Arial-BoldItalic", "Helvetica-BoldOblique" }, + { "Arial-BoldItalicMT", "Helvetica-BoldOblique" }, + { "Arial-BoldMT", "Helvetica-Bold" }, + { "Arial-Italic", "Helvetica-Oblique" }, + { "Arial-ItalicMT", "Helvetica-Oblique" }, + { "ArialMT", "Helvetica" }, + { "Courier,Bold", "Courier-Bold" }, + { "Courier,BoldItalic", "Courier-BoldOblique" }, + { "Courier,Italic", "Courier-Oblique" }, + { "CourierNew", "Courier" }, + { "CourierNew,Bold", "Courier-Bold" }, + { "CourierNew,BoldItalic", "Courier-BoldOblique" }, + { "CourierNew,Italic", "Courier-Oblique" }, + { "CourierNew-Bold", "Courier-Bold" }, + { "CourierNew-BoldItalic", "Courier-BoldOblique" }, + { "CourierNew-Italic", "Courier-Oblique" }, + { "CourierNewPS-BoldItalicMT", "Courier-BoldOblique" }, + { "CourierNewPS-BoldMT", "Courier-Bold" }, + { "CourierNewPS-ItalicMT", "Courier-Oblique" }, + { "CourierNewPSMT", "Courier" }, + { "Helvetica,Bold", "Helvetica-Bold" }, + { "Helvetica,BoldItalic", "Helvetica-BoldOblique" }, + { "Helvetica,Italic", "Helvetica-Oblique" }, + { "Helvetica-BoldItalic", "Helvetica-BoldOblique" }, + { "Helvetica-Italic", "Helvetica-Oblique" }, + { "Symbol,Bold", "Symbol" }, + { "Symbol,BoldItalic", "Symbol" }, + { "Symbol,Italic", "Symbol" }, + { "TimesNewRoman", "Times-Roman" }, + { "TimesNewRoman,Bold", "Times-Bold" }, + { "TimesNewRoman,BoldItalic", "Times-BoldItalic" }, + { "TimesNewRoman,Italic", "Times-Italic" }, + { "TimesNewRoman-Bold", "Times-Bold" }, + { "TimesNewRoman-BoldItalic", "Times-BoldItalic" }, + { "TimesNewRoman-Italic", "Times-Italic" }, + { "TimesNewRomanPS", "Times-Roman" }, + { "TimesNewRomanPS-Bold", "Times-Bold" }, + { "TimesNewRomanPS-BoldItalic", "Times-BoldItalic" }, + { "TimesNewRomanPS-BoldItalicMT", "Times-BoldItalic" }, + { "TimesNewRomanPS-BoldMT", "Times-Bold" }, + { "TimesNewRomanPS-Italic", "Times-Italic" }, + { "TimesNewRomanPS-ItalicMT", "Times-Italic" }, + { "TimesNewRomanPSMT", "Times-Roman" }, + { "TimesNewRomanPSMT,Bold", "Times-Bold" }, + { "TimesNewRomanPSMT,BoldItalic", "Times-BoldItalic" }, + { "TimesNewRomanPSMT,Italic", "Times-Italic" } +}; + +//------------------------------------------------------------------------ +// GfxFont +//------------------------------------------------------------------------ + +GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) { + GooString *nameA; + GfxFont *font; + Object obj1; + + // get base font name + nameA = NULL; + fontDict->lookup("BaseFont", &obj1); + if (obj1.isName()) { + nameA = new GooString(obj1.getName()); + } + obj1.free(); + + // get font type + font = NULL; + fontDict->lookup("Subtype", &obj1); + if (obj1.isName("Type1") || obj1.isName("MMType1")) { + font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1, fontDict); + } else if (obj1.isName("Type1C")) { + font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1C, fontDict); + } else if (obj1.isName("Type3")) { + font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType3, fontDict); + } else if (obj1.isName("TrueType")) { + font = new Gfx8BitFont(xref, tagA, idA, nameA, fontTrueType, fontDict); + } else if (obj1.isName("Type0")) { + font = new GfxCIDFont(xref, tagA, idA, nameA, fontDict); + } else { + error(-1, "Unknown font type: '%s'", + obj1.isName() ? obj1.getNameC() : "???"); + font = new Gfx8BitFont(xref, tagA, idA, nameA, fontUnknownType, fontDict); + } + obj1.free(); + + return font; +} + +GfxFont::GfxFont(char *tagA, Ref idA, GooString *nameA) { + ok = gFalse; + tag = new GooString(tagA); + id = idA; + name = nameA; + origName = nameA; + embFontName = NULL; + extFontFile = NULL; + family = NULL; + stretch = StretchNotDefined; + weight = WeightNotDefined; + refCnt = 1; +} + +GfxFont::~GfxFont() { + delete tag; + delete family; + if (origName && origName != name) { + delete origName; + } + if (name) { + delete name; + } + if (embFontName) { + delete embFontName; + } + if (extFontFile) { + delete extFontFile; + } +} + +void GfxFont::incRefCnt() { + refCnt++; +} + +void GfxFont::decRefCnt() { + if (--refCnt == 0) + delete this; +} + +void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) { + Object obj1, obj2, obj3, obj4; + double t; + int i; + + // assume Times-Roman by default (for substitution purposes) + flags = fontSerif; + + embFontID.num = -1; + embFontID.gen = -1; + missingWidth = 0; + + if (fontDict->lookup("FontDescriptor", &obj1)->isDict()) { + + // get flags + if (obj1.dictLookup("Flags", &obj2)->isInt()) { + flags = obj2.getInt(); + } + obj2.free(); + + // get name + obj1.dictLookup("FontName", &obj2); + if (obj2.isName()) { + embFontName = new GooString(obj2.getName()); + } + obj2.free(); + + // get family + obj1.dictLookup("FontFamily", &obj2); + if (obj2.isString()) family = new GooString(obj2.getString()); + obj2.free(); + + // get stretch + obj1.dictLookup("FontStretch", &obj2); + if (obj2.isName()) { + char *name = obj2.getNameC(); + if (strcmp(name, "UltraCondensed") == 0) stretch = UltraCondensed; + else if (strcmp(name, "ExtraCondensed") == 0) stretch = ExtraCondensed; + else if (strcmp(name, "Condensed") == 0) stretch = Condensed; + else if (strcmp(name, "SemiCondensed") == 0) stretch = SemiCondensed; + else if (strcmp(name, "Normal") == 0) stretch = Normal; + else if (strcmp(name, "SemiExpanded") == 0) stretch = SemiExpanded; + else if (strcmp(name, "Expanded") == 0) stretch = Expanded; + else if (strcmp(name, "ExtraExpanded") == 0) stretch = ExtraExpanded; + else if (strcmp(name, "UltraExpanded") == 0) stretch = UltraExpanded; + else error(-1, "Invalid Font Stretch"); + } + obj2.free(); + + // get weight + obj1.dictLookup("FontWeight", &obj2); + if (obj2.isNum()) { + if (obj2.getNum() == 100) weight = W100; + else if (obj2.getNum() == 200) weight = W200; + else if (obj2.getNum() == 300) weight = W300; + else if (obj2.getNum() == 400) weight = W400; + else if (obj2.getNum() == 500) weight = W500; + else if (obj2.getNum() == 600) weight = W600; + else if (obj2.getNum() == 700) weight = W700; + else if (obj2.getNum() == 800) weight = W800; + else if (obj2.getNum() == 900) weight = W900; + else error(-1, "Invalid Font Weight"); + } + obj2.free(); + + // look for embedded font file + if (obj1.dictLookupNF("FontFile", &obj2)->isRef()) { + embFontID = obj2.getRef(); + if (type != fontType1) { + error(-1, "Mismatch between font type and embedded font file"); + type = fontType1; + } + } + obj2.free(); + if (embFontID.num == -1 && + obj1.dictLookupNF("FontFile2", &obj2)->isRef()) { + embFontID = obj2.getRef(); + if (type != fontTrueType && type != fontCIDType2) { + error(-1, "Mismatch between font type and embedded font file"); + type = type == fontCIDType0 ? fontCIDType2 : fontTrueType; + } + } + obj2.free(); + if (embFontID.num == -1 && + obj1.dictLookupNF("FontFile3", &obj2)->isRef()) { + if (obj2.fetch(xref, &obj3)->isStream()) { + obj3.streamGetDict()->lookup("Subtype", &obj4); + if (obj4.isName("Type1")) { + embFontID = obj2.getRef(); + if (type != fontType1) { + error(-1, "Mismatch between font type and embedded font file"); + type = fontType1; + } + } else if (obj4.isName("Type1C")) { + embFontID = obj2.getRef(); + if (type != fontType1 && type != fontType1C) { + error(-1, "Mismatch between font type and embedded font file"); + } + type = fontType1C; + } else if (obj4.isName("TrueType")) { + embFontID = obj2.getRef(); + if (type != fontTrueType) { + error(-1, "Mismatch between font type and embedded font file"); + type = fontTrueType; + } + } else if (obj4.isName("CIDFontType0C")) { + embFontID = obj2.getRef(); + if (type != fontCIDType0) { + error(-1, "Mismatch between font type and embedded font file"); + } + type = fontCIDType0C; + } else { + error(-1, "Unknown embedded font type '%s'", + obj4.isName() ? obj4.getNameC() : "???"); + } + obj4.free(); + } + obj3.free(); + } + obj2.free(); + + // look for MissingWidth + obj1.dictLookup("MissingWidth", &obj2); + if (obj2.isNum()) { + missingWidth = obj2.getNum(); + } + obj2.free(); + + // get Ascent and Descent + obj1.dictLookup("Ascent", &obj2); + if (obj2.isNum()) { + t = 0.001 * obj2.getNum(); + // some broken font descriptors set ascent and descent to 0 + if (t != 0) { + ascent = t; + } + } + obj2.free(); + obj1.dictLookup("Descent", &obj2); + if (obj2.isNum()) { + t = 0.001 * obj2.getNum(); + // some broken font descriptors set ascent and descent to 0 + if (t != 0) { + descent = t; + } + // some broken font descriptors specify a positive descent + if (descent > 0) { + descent = -descent; + } + } + obj2.free(); + + // font FontBBox + if (obj1.dictLookup("FontBBox", &obj2)->isArray()) { + for (i = 0; i < 4 && i < obj2.arrayGetLength(); ++i) { + if (obj2.arrayGet(i, &obj3)->isNum()) { + fontBBox[i] = 0.001 * obj3.getNum(); + } + obj3.free(); + } + } + obj2.free(); + + } + obj1.free(); +} + +CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits, + CharCodeToUnicode *ctu) { + GooString *buf; + Object obj1; + int c; + + if (!fontDict->lookup("ToUnicode", &obj1)->isStream()) { + obj1.free(); + return NULL; + } + buf = new GooString(); + obj1.streamReset(); + while ((c = obj1.streamGetChar()) != EOF) { + buf->append(c); + } + obj1.streamClose(); + obj1.free(); + if (ctu) { + ctu->mergeCMap(buf, nBits); + } else { + ctu = CharCodeToUnicode::parseCMap(buf, nBits); + } + delete buf; + return ctu; +} + +void GfxFont::findExtFontFile() { + static char *type1Exts[] = { ".pfa", ".pfb", ".ps", "", NULL }; + static char *ttExts[] = { ".ttf", ".ttc", NULL }; + + if (name) { + if (type == fontType1) { + extFontFile = globalParams->findFontFile(name, type1Exts); + } else if (type == fontTrueType) { + extFontFile = globalParams->findFontFile(name, ttExts); + } + } +} + +char *GfxFont::readExtFontFile(int *len) { + FILE *f; + char *buf; + + if (!(f = fopen(extFontFile->getCString(), "rb"))) { + error(-1, "External font file '%s' vanished", extFontFile->getCString()); + return NULL; + } + fseek(f, 0, SEEK_END); + *len = (int)ftell(f); + fseek(f, 0, SEEK_SET); + buf = (char *)gmalloc(*len); + if ((int)fread(buf, 1, *len, f) != *len) { + error(-1, "Error reading external font file '%s'", + extFontFile->getCString()); + } + fclose(f); + return buf; +} + +char *GfxFont::readEmbFontFile(XRef *xref, int *len) { + char *buf; + Object obj1, obj2; + Stream *str; + int c; + int size, i; + + obj1.initRef(embFontID.num, embFontID.gen); + obj1.fetch(xref, &obj2); + if (!obj2.isStream()) { + error(-1, "Embedded font file is not a stream"); + obj2.free(); + obj1.free(); + embFontID.num = -1; + return NULL; + } + str = obj2.getStream(); + + buf = NULL; + i = size = 0; + str->reset(); + while ((c = str->getChar()) != EOF) { + if (i == size) { + size += 4096; + buf = (char *)grealloc(buf, size); + } + buf[i++] = c; + } + *len = i; + str->close(); + + obj2.free(); + obj1.free(); + + return buf; +} + +//------------------------------------------------------------------------ +// Gfx8BitFont +//------------------------------------------------------------------------ + +Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GooString *nameA, + GfxFontType typeA, Dict *fontDict): + GfxFont(tagA, idA, nameA) +{ + GooString *name2; + BuiltinFont *builtinFont; + char **baseEnc; + GBool baseEncFromFontFile; + char *buf; + int len; + FoFiType1 *ffT1; + FoFiType1C *ffT1C; + int code, code2; + char *charName; + GBool missing, hex; + Unicode toUnicode[256]; + CharCodeToUnicode *utu, *ctu2; + Unicode uBuf[8]; + double mul; + int firstChar, lastChar; + Gushort w; + Object obj1, obj2, obj3; + int n, i, a, b, m; + + refCnt = 1; + type = typeA; + ctu = NULL; + + // do font name substitution for various aliases of the Base 14 font + // names + if (name) { + name2 = name->copy(); + i = 0; + while (i < name2->getLength()) { + if (name2->getChar(i) == ' ') { + name2->del(i); + } else { + ++i; + } + } + a = 0; + b = sizeof(stdFontMap) / sizeof(StdFontMapEntry); + // invariant: stdFontMap[a].altName <= name2 < stdFontMap[b].altName + while (b - a > 1) { + m = (a + b) / 2; + if (name2->cmp(stdFontMap[m].altName) >= 0) { + a = m; + } else { + b = m; + } + } + if (!name2->cmp(stdFontMap[a].altName)) { + name = new GooString(stdFontMap[a].properName); + } + delete name2; + } + + // is it a built-in font? + builtinFont = NULL; + if (name) { + for (i = 0; i < nBuiltinFonts; ++i) { + if (!name->cmp(builtinFonts[i].name)) { + builtinFont = &builtinFonts[i]; + break; + } + } + } + + // default ascent/descent values + if (builtinFont) { + ascent = 0.001 * builtinFont->ascent; + descent = 0.001 * builtinFont->descent; + fontBBox[0] = 0.001 * builtinFont->bbox[0]; + fontBBox[1] = 0.001 * builtinFont->bbox[1]; + fontBBox[2] = 0.001 * builtinFont->bbox[2]; + fontBBox[3] = 0.001 * builtinFont->bbox[3]; + } else { + ascent = 0.95; + descent = -0.35; + fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0; + } + + // get info from font descriptor + readFontDescriptor(xref, fontDict); + + // for non-embedded fonts, don't trust the ascent/descent/bbox + // values from the font descriptor + if (builtinFont && embFontID.num < 0) { + ascent = 0.001 * builtinFont->ascent; + descent = 0.001 * builtinFont->descent; + fontBBox[0] = 0.001 * builtinFont->bbox[0]; + fontBBox[1] = 0.001 * builtinFont->bbox[1]; + fontBBox[2] = 0.001 * builtinFont->bbox[2]; + fontBBox[3] = 0.001 * builtinFont->bbox[3]; + } + + // look for an external font file + findExtFontFile(); + + // get font matrix + fontMat[0] = fontMat[3] = 1; + fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0; + if (fontDict->lookup("FontMatrix", &obj1)->isArray()) { + for (i = 0; i < 6 && i < obj1.arrayGetLength(); ++i) { + if (obj1.arrayGet(i, &obj2)->isNum()) { + fontMat[i] = obj2.getNum(); + } + obj2.free(); + } + } + obj1.free(); + + // get Type 3 bounding box, font definition, and resources + if (type == fontType3) { + if (fontDict->lookup("FontBBox", &obj1)->isArray()) { + for (i = 0; i < 4 && i < obj1.arrayGetLength(); ++i) { + if (obj1.arrayGet(i, &obj2)->isNum()) { + fontBBox[i] = obj2.getNum(); + } + obj2.free(); + } + } + obj1.free(); + if (!fontDict->lookup("CharProcs", &charProcs)->isDict()) { + error(-1, "Missing or invalid CharProcs dictionary in Type 3 font"); + charProcs.free(); + } + if (!fontDict->lookup("Resources", &resources)->isDict()) { + resources.free(); + } + } + + //----- build the font encoding ----- + + // Encodings start with a base encoding, which can come from + // (in order of priority): + // 1. FontDict.Encoding or FontDict.Encoding.BaseEncoding + // - MacRoman / MacExpert / WinAnsi / Standard + // 2. embedded or external font file + // 3. default: + // - builtin --> builtin encoding + // - TrueType --> WinAnsiEncoding + // - others --> StandardEncoding + // and then add a list of differences (if any) from + // FontDict.Encoding.Differences. + + // check FontDict for base encoding + hasEncoding = gFalse; + usesMacRomanEnc = gFalse; + baseEnc = NULL; + baseEncFromFontFile = gFalse; + fontDict->lookup("Encoding", &obj1); + if (obj1.isDict()) { + obj1.dictLookup("BaseEncoding", &obj2); + if (obj2.isName("MacRomanEncoding")) { + hasEncoding = gTrue; + usesMacRomanEnc = gTrue; + baseEnc = macRomanEncoding; + } else if (obj2.isName("MacExpertEncoding")) { + hasEncoding = gTrue; + baseEnc = macExpertEncoding; + } else if (obj2.isName("WinAnsiEncoding")) { + hasEncoding = gTrue; + baseEnc = winAnsiEncoding; + } + obj2.free(); + } else if (obj1.isName("MacRomanEncoding")) { + hasEncoding = gTrue; + usesMacRomanEnc = gTrue; + baseEnc = macRomanEncoding; + } else if (obj1.isName("MacExpertEncoding")) { + hasEncoding = gTrue; + baseEnc = macExpertEncoding; + } else if (obj1.isName("WinAnsiEncoding")) { + hasEncoding = gTrue; + baseEnc = winAnsiEncoding; + } + + // check embedded or external font file for base encoding + // (only for Type 1 fonts - trying to get an encoding out of a + // TrueType font is a losing proposition) + ffT1 = NULL; + ffT1C = NULL; + buf = NULL; + if (type == fontType1 && (extFontFile || embFontID.num >= 0)) { + if (extFontFile) { + ffT1 = FoFiType1::load(extFontFile->getCString()); + } else { + buf = readEmbFontFile(xref, &len); + ffT1 = FoFiType1::make(buf, len); + } + if (ffT1) { + if (ffT1->getName()) { + if (embFontName) { + delete embFontName; + } + embFontName = new GooString(ffT1->getName()); + } + if (!baseEnc) { + baseEnc = ffT1->getEncoding(); + baseEncFromFontFile = gTrue; + } + } + } else if (type == fontType1C && (extFontFile || embFontID.num >= 0)) { + if (extFontFile) { + ffT1C = FoFiType1C::load(extFontFile->getCString()); + } else { + buf = readEmbFontFile(xref, &len); + ffT1C = FoFiType1C::make(buf, len); + } + if (ffT1C) { + if (ffT1C->getName()) { + if (embFontName) { + delete embFontName; + } + embFontName = new GooString(ffT1C->getName()); + } + if (!baseEnc) { + baseEnc = ffT1C->getEncoding(); + baseEncFromFontFile = gTrue; + } + } + } + if (buf) { + gfree(buf); + } + + // get default base encoding + if (!baseEnc) { + if (builtinFont && embFontID.num < 0) { + baseEnc = builtinFont->defaultBaseEnc; + hasEncoding = gTrue; + } else if (type == fontTrueType) { + baseEnc = winAnsiEncoding; + } else { + baseEnc = standardEncoding; + } + } + + // copy the base encoding + for (i = 0; i < 256; ++i) { + enc[i] = baseEnc[i]; + if ((encFree[i] = baseEncFromFontFile) && enc[i]) { + enc[i] = copyString(baseEnc[i]); + } + } + + // some Type 1C font files have empty encodings, which can break the + // T1C->T1 conversion (since the 'seac' operator depends on having + // the accents in the encoding), so we fill in any gaps from + // StandardEncoding + if (type == fontType1C && (extFontFile || embFontID.num >= 0) && + baseEncFromFontFile) { + for (i = 0; i < 256; ++i) { + if (!enc[i] && standardEncoding[i]) { + enc[i] = standardEncoding[i]; + encFree[i] = gFalse; + } + } + } + + // merge differences into encoding + if (obj1.isDict()) { + obj1.dictLookup("Differences", &obj2); + if (obj2.isArray()) { + hasEncoding = gTrue; + code = 0; + for (i = 0; i < obj2.arrayGetLength(); ++i) { + obj2.arrayGet(i, &obj3); + if (obj3.isInt()) { + code = obj3.getInt(); + } else if (obj3.isName()) { + if (code >= 0 && code < 256) { + if (encFree[code]) { + gfree(enc[code]); + } + enc[code] = copyString(obj3.getNameC()); + encFree[code] = gTrue; + } + ++code; + } else { + error(-1, "Wrong type in font encoding resource differences (%s)", + obj3.getTypeName()); + } + obj3.free(); + } + } + obj2.free(); + } + obj1.free(); + if (ffT1) { + delete ffT1; + } + if (ffT1C) { + delete ffT1C; + } + + //----- build the mapping to Unicode ----- + + // pass 1: use the name-to-Unicode mapping table + missing = hex = gFalse; + for (code = 0; code < 256; ++code) { + if ((charName = enc[code])) { + if (!(toUnicode[code] = globalParams->mapNameToUnicode(charName)) && + strcmp(charName, ".notdef")) { + // if it wasn't in the name-to-Unicode table, check for a + // name that looks like 'Axx' or 'xx', where 'A' is any letter + // and 'xx' is two hex digits + if ((strlen(charName) == 3 && + isalpha(charName[0]) && + isxdigit(charName[1]) && isxdigit(charName[2]) && + ((charName[1] >= 'a' && charName[1] <= 'f') || + (charName[1] >= 'A' && charName[1] <= 'F') || + (charName[2] >= 'a' && charName[2] <= 'f') || + (charName[2] >= 'A' && charName[2] <= 'F'))) || + (strlen(charName) == 2 && + isxdigit(charName[0]) && isxdigit(charName[1]) && + ((charName[0] >= 'a' && charName[0] <= 'f') || + (charName[0] >= 'A' && charName[0] <= 'F') || + (charName[1] >= 'a' && charName[1] <= 'f') || + (charName[1] >= 'A' && charName[1] <= 'F')))) { + hex = gTrue; + } + missing = gTrue; + } + } else { + toUnicode[code] = 0; + } + } + + // pass 2: try to fill in the missing chars, looking for names of + // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B' + // are any letters, 'xx' is two hex digits, and 'nn' is 2-4 + // decimal digits + if (missing && globalParams->getMapNumericCharNames()) { + for (code = 0; code < 256; ++code) { + if ((charName = enc[code]) && !toUnicode[code] && + strcmp(charName, ".notdef")) { + n = strlen(charName); + code2 = -1; + if (hex && n == 3 && isalpha(charName[0]) && + isxdigit(charName[1]) && isxdigit(charName[2])) { + sscanf(charName+1, "%x", &code2); + } else if (hex && n == 2 && + isxdigit(charName[0]) && isxdigit(charName[1])) { + sscanf(charName, "%x", &code2); + } else if (!hex && n >= 2 && n <= 4 && + isdigit(charName[0]) && isdigit(charName[1])) { + code2 = atoi(charName); + } else if (n >= 3 && n <= 5 && + isdigit(charName[1]) && isdigit(charName[2])) { + code2 = atoi(charName+1); + } else if (n >= 4 && n <= 6 && + isdigit(charName[2]) && isdigit(charName[3])) { + code2 = atoi(charName+2); + } + if (code2 >= 0 && code2 <= 0xff) { + toUnicode[code] = (Unicode)code2; + } + } + } + } + + // construct the char code -> Unicode mapping object + ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode); + + // merge in a ToUnicode CMap, if there is one -- this overwrites + // existing entries in ctu, i.e., the ToUnicode CMap takes + // precedence, but the other encoding info is allowed to fill in any + // holes + readToUnicodeCMap(fontDict, 8, ctu); + + // look for a Unicode-to-Unicode mapping + if (name && (utu = globalParams->getUnicodeToUnicode(name))) { + for (i = 0; i < 256; ++i) { + toUnicode[i] = 0; + } + ctu2 = CharCodeToUnicode::make8BitToUnicode(toUnicode); + for (i = 0; i < 256; ++i) { + n = ctu->mapToUnicode((CharCode)i, uBuf, 8); + if (n >= 1) { + n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8); + if (n >= 1) { + ctu2->setMapping((CharCode)i, uBuf, n); + } + } + } + utu->decRefCnt(); + delete ctu; + ctu = ctu2; + } + + //----- get the character widths ----- + + // initialize all widths + for (code = 0; code < 256; ++code) { + widths[code] = missingWidth * 0.001; + } + + // use widths from font dict, if present + fontDict->lookup("FirstChar", &obj1); + firstChar = obj1.isInt() ? obj1.getInt() : 0; + obj1.free(); + if (firstChar < 0 || firstChar > 255) { + firstChar = 0; + } + fontDict->lookup("LastChar", &obj1); + lastChar = obj1.isInt() ? obj1.getInt() : 255; + obj1.free(); + if (lastChar < 0 || lastChar > 255) { + lastChar = 255; + } + mul = (type == fontType3) ? fontMat[0] : 0.001; + fontDict->lookup("Widths", &obj1); + if (obj1.isArray()) { + flags |= fontFixedWidth; + if (obj1.arrayGetLength() < lastChar - firstChar + 1) { + lastChar = firstChar + obj1.arrayGetLength() - 1; + } + for (code = firstChar; code <= lastChar; ++code) { + obj1.arrayGet(code - firstChar, &obj2); + if (obj2.isNum()) { + widths[code] = obj2.getNum() * mul; + if (widths[code] != widths[firstChar]) { + flags &= ~fontFixedWidth; + } + } + obj2.free(); + } + + // use widths from built-in font + } else if (builtinFont) { + // this is a kludge for broken PDF files that encode char 32 + // as .notdef + if (builtinFont->widths->getWidth("space", &w)) { + widths[32] = 0.001 * w; + } + for (code = 0; code < 256; ++code) { + if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) { + widths[code] = 0.001 * w; + } + } + + // couldn't find widths -- use defaults + } else { + // this is technically an error -- the Widths entry is required + // for all but the Base-14 fonts -- but certain PDF generators + // apparently don't include widths for Arial and TimesNewRoman + if (isFixedWidth()) { + i = 0; + } else if (isSerif()) { + i = 8; + } else { + i = 4; + } + if (isBold()) { + i += 2; + } + if (isItalic()) { + i += 1; + } + builtinFont = builtinFontSubst[i]; + // this is a kludge for broken PDF files that encode char 32 + // as .notdef + if (builtinFont->widths->getWidth("space", &w)) { + widths[32] = 0.001 * w; + } + for (code = 0; code < 256; ++code) { + if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) { + widths[code] = 0.001 * w; + } + } + } + obj1.free(); + + ok = gTrue; +} + +Gfx8BitFont::~Gfx8BitFont() { + int i; + + for (i = 0; i < 256; ++i) { + if (encFree[i] && enc[i]) { + gfree(enc[i]); + } + } + ctu->decRefCnt(); + if (charProcs.isDict()) { + charProcs.free(); + } + if (resources.isDict()) { + resources.free(); + } +} + +int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, + Unicode *u, int uSize, int *uLen, + double *dx, double *dy, double *ox, double *oy) { + CharCode c; + + *code = c = (CharCode)(*s & 0xff); + *uLen = ctu->mapToUnicode(c, u, uSize); + *dx = widths[c]; + *dy = *ox = *oy = 0; + return 1; +} + +CharCodeToUnicode *Gfx8BitFont::getToUnicode() { + ctu->incRefCnt(); + return ctu; +} + +Gushort *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) { + Gushort *map; + int cmapPlatform, cmapEncoding; + int unicodeCmap, macRomanCmap, msSymbolCmap, cmap; + GBool useMacRoman, useUnicode; + char *charName; + Unicode u; + int code, i, n; + + map = (Gushort *)gmallocn(256, sizeof(Gushort)); + for (i = 0; i < 256; ++i) { + map[i] = 0; + } + + // To match up with the Adobe-defined behaviour, we choose a cmap + // like this: + // 1. If the PDF font has an encoding: + // 1a. If the PDF font specified MacRomanEncoding and the + // TrueType font has a Macintosh Roman cmap, use it, and + // reverse map the char names through MacRomanEncoding to + // get char codes. + // 1b. If the TrueType font has a Microsoft Unicode cmap or a + // non-Microsoft Unicode cmap, use it, and use the Unicode + // indexes, not the char codes. + // 1c. If the PDF font is symbolic and the TrueType font has a + // Microsoft Symbol cmap, use it, and use char codes + // directly (possibly with an offset of 0xf000). + // 1d. If the TrueType font has a Macintosh Roman cmap, use it, + // as in case 1a. + // 2. If the PDF font does not have an encoding or the PDF font is + // symbolic: + // 2a. If the TrueType font has a Macintosh Roman cmap, use it, + // and use char codes directly (possibly with an offset of + // 0xf000). + // 2b. If the TrueType font has a Microsoft Symbol cmap, use it, + // and use char codes directly (possible with an offset of + // 0xf000). + // 3. If none of these rules apply, use the first cmap and hope for + // the best (this shouldn't happen). + unicodeCmap = macRomanCmap = msSymbolCmap = -1; + for (i = 0; i < ff->getNumCmaps(); ++i) { + cmapPlatform = ff->getCmapPlatform(i); + cmapEncoding = ff->getCmapEncoding(i); + if ((cmapPlatform == 3 && cmapEncoding == 1) || + cmapPlatform == 0) { + unicodeCmap = i; + } else if (cmapPlatform == 1 && cmapEncoding == 0) { + macRomanCmap = i; + } else if (cmapPlatform == 3 && cmapEncoding == 0) { + msSymbolCmap = i; + } + } + cmap = 0; + useMacRoman = gFalse; + useUnicode = gFalse; + if (hasEncoding) { + if (usesMacRomanEnc && macRomanCmap >= 0) { + cmap = macRomanCmap; + useMacRoman = gTrue; + } else if (unicodeCmap >= 0) { + cmap = unicodeCmap; + useUnicode = gTrue; + } else if ((flags & fontSymbolic) && msSymbolCmap >= 0) { + cmap = msSymbolCmap; + } else if ((flags & fontSymbolic) && macRomanCmap >= 0) { + cmap = macRomanCmap; + } else if (macRomanCmap >= 0) { + cmap = macRomanCmap; + useMacRoman = gTrue; + } + } else { + if (macRomanCmap >= 0) { + cmap = macRomanCmap; + } else if (msSymbolCmap >= 0) { + cmap = msSymbolCmap; + } + } + + // reverse map the char names through MacRomanEncoding, then map the + // char codes through the cmap + if (useMacRoman) { + for (i = 0; i < 256; ++i) { + if ((charName = enc[i])) { + if ((code = globalParams->getMacRomanCharCode(charName))) { + map[i] = ff->mapCodeToGID(cmap, code); + } + } + } + + // map Unicode through the cmap + } else if (useUnicode) { + for (i = 0; i < 256; ++i) { + if (((charName = enc[i]) && + (u = globalParams->mapNameToUnicode(charName))) || + (n = ctu->mapToUnicode((CharCode)i, &u, 1))) { + map[i] = ff->mapCodeToGID(cmap, u); + } + } + + // map the char codes through the cmap, possibly with an offset of + // 0xf000 + } else { + for (i = 0; i < 256; ++i) { + if (!(map[i] = ff->mapCodeToGID(cmap, i))) { + map[i] = ff->mapCodeToGID(cmap, 0xf000 + i); + } + } + } + + // try the TrueType 'post' table to handle any unmapped characters + for (i = 0; i < 256; ++i) { + if (!map[i] && (charName = enc[i])) { + map[i] = (Gushort)(int)ff->mapNameToGID(charName); + } + } + + return map; +} + +Dict *Gfx8BitFont::getCharProcs() { + return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL; +} + +Object *Gfx8BitFont::getCharProc(int code, Object *proc) { + if (enc[code] && charProcs.isDict()) { + charProcs.dictLookup(enc[code], proc); + } else { + proc->initNull(); + } + return proc; +} + +Dict *Gfx8BitFont::getResources() { + return resources.isDict() ? resources.getDict() : (Dict *)NULL; +} + +//------------------------------------------------------------------------ +// GfxCIDFont +//------------------------------------------------------------------------ + +static int CDECL cmpWidthExcep(const void *w1, const void *w2) { + return ((GfxFontCIDWidthExcep *)w1)->first - + ((GfxFontCIDWidthExcep *)w2)->first; +} + +static int CDECL cmpWidthExcepV(const void *w1, const void *w2) { + return ((GfxFontCIDWidthExcepV *)w1)->first - + ((GfxFontCIDWidthExcepV *)w2)->first; +} + +GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GooString *nameA, + Dict *fontDict): + GfxFont(tagA, idA, nameA) +{ + Dict *desFontDict; + GooString *collection, *cMapName; + Object desFontDictObj; + Object obj1, obj2, obj3, obj4, obj5, obj6; + CharCodeToUnicode *utu; + CharCode c; + Unicode uBuf[8]; + int c1, c2; + int excepsSize, i, j, k, n; + + refCnt = 1; + ascent = 0.95; + descent = -0.35; + fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0; + cMap = NULL; + ctu = NULL; + widths.defWidth = 1.0; + widths.defHeight = -1.0; + widths.defVY = 0.880; + widths.exceps = NULL; + widths.nExceps = 0; + widths.excepsV = NULL; + widths.nExcepsV = 0; + cidToGID = NULL; + cidToGIDLen = 0; + + // get the descendant font + if (!fontDict->lookup("DescendantFonts", &obj1)->isArray()) { + error(-1, "Missing DescendantFonts entry in Type 0 font"); + obj1.free(); + goto err1; + } + if (!obj1.arrayGet(0, &desFontDictObj)->isDict()) { + error(-1, "Bad descendant font in Type 0 font"); + goto err3; + } + obj1.free(); + desFontDict = desFontDictObj.getDict(); + + // font type + if (!desFontDict->lookup("Subtype", &obj1)) { + error(-1, "Missing Subtype entry in Type 0 descendant font"); + goto err3; + } + if (obj1.isName("CIDFontType0")) { + type = fontCIDType0; + } else if (obj1.isName("CIDFontType2")) { + type = fontCIDType2; + } else { + error(-1, "Unknown Type 0 descendant font type '%s'", + obj1.isName() ? obj1.getNameC() : "???"); + goto err3; + } + obj1.free(); + + // get info from font descriptor + readFontDescriptor(xref, desFontDict); + + // look for an external font file + findExtFontFile(); + + //----- encoding info ----- + + // char collection + if (!desFontDict->lookup("CIDSystemInfo", &obj1)->isDict()) { + error(-1, "Missing CIDSystemInfo dictionary in Type 0 descendant font"); + goto err3; + } + obj1.dictLookup("Registry", &obj2); + obj1.dictLookup("Ordering", &obj3); + if (!obj2.isString() || !obj3.isString()) { + error(-1, "Invalid CIDSystemInfo dictionary in Type 0 descendant font"); + goto err4; + } + collection = obj2.getString()->copy()->append('-')->append(obj3.getString()); + obj3.free(); + obj2.free(); + obj1.free(); + + // look for a ToUnicode CMap + if (!(ctu = readToUnicodeCMap(fontDict, 16, NULL))) { + + // the "Adobe-Identity" and "Adobe-UCS" collections don't have + // cidToUnicode files + if (collection->cmp("Adobe-Identity") && + collection->cmp("Adobe-UCS")) { + + // look for a user-supplied .cidToUnicode file + if (!(ctu = globalParams->getCIDToUnicode(collection))) { + error(-1, "Unknown character collection '%s'", + collection->getCString()); + // fall-through, assuming the Identity mapping -- this appears + // to match Adobe's behavior + } + } + } + + // look for a Unicode-to-Unicode mapping + if (name && (utu = globalParams->getUnicodeToUnicode(name))) { + if (ctu) { + for (c = 0; c < ctu->getLength(); ++c) { + n = ctu->mapToUnicode(c, uBuf, 8); + if (n >= 1) { + n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8); + if (n >= 1) { + ctu->setMapping(c, uBuf, n); + } + } + } + utu->decRefCnt(); + } else { + ctu = utu; + } + } + + // encoding (i.e., CMap) + //~ need to handle a CMap stream here + //~ also need to deal with the UseCMap entry in the stream dict + if (!fontDict->lookup("Encoding", &obj1)->isName()) { + error(-1, "Missing or invalid Encoding entry in Type 0 font"); + delete collection; + goto err3; + } + cMapName = new GooString(obj1.getName()); + obj1.free(); + if (!(cMap = globalParams->getCMap(collection, cMapName))) { + error(-1, "Unknown CMap '%s' for character collection '%s'", + cMapName->getCString(), collection->getCString()); + delete collection; + delete cMapName; + goto err2; + } + delete collection; + delete cMapName; + + // CIDToGIDMap (for embedded TrueType fonts) + if (type == fontCIDType2) { + desFontDict->lookup("CIDToGIDMap", &obj1); + if (obj1.isStream()) { + cidToGIDLen = 0; + i = 64; + cidToGID = (Gushort *)gmallocn(i, sizeof(Gushort)); + obj1.streamReset(); + while ((c1 = obj1.streamGetChar()) != EOF && + (c2 = obj1.streamGetChar()) != EOF) { + if (cidToGIDLen == i) { + i *= 2; + cidToGID = (Gushort *)greallocn(cidToGID, i, sizeof(Gushort)); + } + cidToGID[cidToGIDLen++] = (Gushort)((c1 << 8) + c2); + } + } else if (!obj1.isName("Identity") && !obj1.isNull()) { + error(-1, "Invalid CIDToGIDMap entry in CID font"); + } + obj1.free(); + } + + //----- character metrics ----- + + // default char width + if (desFontDict->lookup("DW", &obj1)->isInt()) { + widths.defWidth = obj1.getInt() * 0.001; + } + obj1.free(); + + // char width exceptions + if (desFontDict->lookup("W", &obj1)->isArray()) { + excepsSize = 0; + i = 0; + while (i + 1 < obj1.arrayGetLength()) { + obj1.arrayGet(i, &obj2); + obj1.arrayGet(i + 1, &obj3); + if (obj2.isInt() && obj3.isInt() && i + 2 < obj1.arrayGetLength()) { + if (obj1.arrayGet(i + 2, &obj4)->isNum()) { + if (widths.nExceps == excepsSize) { + excepsSize += 16; + widths.exceps = (GfxFontCIDWidthExcep *) + greallocn(widths.exceps, + excepsSize, sizeof(GfxFontCIDWidthExcep)); + } + widths.exceps[widths.nExceps].first = obj2.getInt(); + widths.exceps[widths.nExceps].last = obj3.getInt(); + widths.exceps[widths.nExceps].width = obj4.getNum() * 0.001; + ++widths.nExceps; + } else { + error(-1, "Bad widths array in Type 0 font"); + } + obj4.free(); + i += 3; + } else if (obj2.isInt() && obj3.isArray()) { + if (widths.nExceps + obj3.arrayGetLength() > excepsSize) { + excepsSize = (widths.nExceps + obj3.arrayGetLength() + 15) & ~15; + widths.exceps = (GfxFontCIDWidthExcep *) + greallocn(widths.exceps, + excepsSize, sizeof(GfxFontCIDWidthExcep)); + } + j = obj2.getInt(); + for (k = 0; k < obj3.arrayGetLength(); ++k) { + if (obj3.arrayGet(k, &obj4)->isNum()) { + widths.exceps[widths.nExceps].first = j; + widths.exceps[widths.nExceps].last = j; + widths.exceps[widths.nExceps].width = obj4.getNum() * 0.001; + ++j; + ++widths.nExceps; + } else { + error(-1, "Bad widths array in Type 0 font"); + } + obj4.free(); + } + i += 2; + } else { + error(-1, "Bad widths array in Type 0 font"); + ++i; + } + obj3.free(); + obj2.free(); + } + qsort(widths.exceps, widths.nExceps, sizeof(GfxFontCIDWidthExcep), + &cmpWidthExcep); + } + obj1.free(); + + // default metrics for vertical font + if (desFontDict->lookup("DW2", &obj1)->isArray() && + obj1.arrayGetLength() == 2) { + if (obj1.arrayGet(0, &obj2)->isNum()) { + widths.defVY = obj2.getNum() * 0.001; + } + obj2.free(); + if (obj1.arrayGet(1, &obj2)->isNum()) { + widths.defHeight = obj2.getNum() * 0.001; + } + obj2.free(); + } + obj1.free(); + + // char metric exceptions for vertical font + if (desFontDict->lookup("W2", &obj1)->isArray()) { + excepsSize = 0; + i = 0; + while (i + 1 < obj1.arrayGetLength()) { + obj1.arrayGet(i, &obj2); + obj1.arrayGet(i+ 1, &obj3); + if (obj2.isInt() && obj3.isInt() && i + 4 < obj1.arrayGetLength()) { + if (obj1.arrayGet(i + 2, &obj4)->isNum() && + obj1.arrayGet(i + 3, &obj5)->isNum() && + obj1.arrayGet(i + 4, &obj6)->isNum()) { + if (widths.nExcepsV == excepsSize) { + excepsSize += 16; + widths.excepsV = (GfxFontCIDWidthExcepV *) + greallocn(widths.excepsV, + excepsSize, sizeof(GfxFontCIDWidthExcepV)); + } + widths.excepsV[widths.nExcepsV].first = obj2.getInt(); + widths.excepsV[widths.nExcepsV].last = obj3.getInt(); + widths.excepsV[widths.nExcepsV].height = obj4.getNum() * 0.001; + widths.excepsV[widths.nExcepsV].vx = obj5.getNum() * 0.001; + widths.excepsV[widths.nExcepsV].vy = obj6.getNum() * 0.001; + ++widths.nExcepsV; + } else { + error(-1, "Bad widths (W2) array in Type 0 font"); + } + obj6.free(); + obj5.free(); + obj4.free(); + i += 5; + } else if (obj2.isInt() && obj3.isArray()) { + if (widths.nExcepsV + obj3.arrayGetLength() / 3 > excepsSize) { + excepsSize = + (widths.nExcepsV + obj3.arrayGetLength() / 3 + 15) & ~15; + widths.excepsV = (GfxFontCIDWidthExcepV *) + greallocn(widths.excepsV, + excepsSize, sizeof(GfxFontCIDWidthExcepV)); + } + j = obj2.getInt(); + for (k = 0; k < obj3.arrayGetLength(); k += 3) { + if (obj3.arrayGet(k, &obj4)->isNum() && + obj3.arrayGet(k+1, &obj5)->isNum() && + obj3.arrayGet(k+2, &obj6)->isNum()) { + widths.excepsV[widths.nExceps].first = j; + widths.excepsV[widths.nExceps].last = j; + widths.excepsV[widths.nExceps].height = obj4.getNum() * 0.001; + widths.excepsV[widths.nExceps].vx = obj5.getNum() * 0.001; + widths.excepsV[widths.nExceps].vy = obj6.getNum() * 0.001; + ++j; + ++widths.nExcepsV; + } else { + error(-1, "Bad widths (W2) array in Type 0 font"); + } + obj6.free(); + obj5.free(); + obj4.free(); + } + i += 2; + } else { + error(-1, "Bad widths (W2) array in Type 0 font"); + ++i; + } + obj3.free(); + obj2.free(); + } + qsort(widths.excepsV, widths.nExcepsV, sizeof(GfxFontCIDWidthExcepV), + &cmpWidthExcepV); + } + obj1.free(); + + desFontDictObj.free(); + ok = gTrue; + return; + + err4: + obj3.free(); + obj2.free(); + err3: + obj1.free(); + err2: + desFontDictObj.free(); + err1:; +} + +GfxCIDFont::~GfxCIDFont() { + if (cMap) { + cMap->decRefCnt(); + } + if (ctu) { + ctu->decRefCnt(); + } + gfree(widths.exceps); + gfree(widths.excepsV); + if (cidToGID) { + gfree(cidToGID); + } +} + +int GfxCIDFont::getNextChar(char *s, int len, CharCode *code, + Unicode *u, int uSize, int *uLen, + double *dx, double *dy, double *ox, double *oy) { + CID cid; + double w, h, vx, vy; + int n, a, b, m; + + if (!cMap) { + *code = 0; + *uLen = 0; + *dx = *dy = 0; + return 1; + } + + *code = (CharCode)(cid = cMap->getCID(s, len, &n)); + if (ctu) { + *uLen = ctu->mapToUnicode(cid, u, uSize); + } else { + *uLen = 0; + } + + // horizontal + if (cMap->getWMode() == 0) { + w = widths.defWidth; + h = vx = vy = 0; + if (widths.nExceps > 0 && cid >= widths.exceps[0].first) { + a = 0; + b = widths.nExceps; + // invariant: widths.exceps[a].first <= cid < widths.exceps[b].first + while (b - a > 1) { + m = (a + b) / 2; + if (widths.exceps[m].first <= cid) { + a = m; + } else { + b = m; + } + } + if (cid <= widths.exceps[a].last) { + w = widths.exceps[a].width; + } + } + + // vertical + } else { + w = 0; + h = widths.defHeight; + vx = widths.defWidth / 2; + vy = widths.defVY; + if (widths.nExcepsV > 0 && cid >= widths.excepsV[0].first) { + a = 0; + b = widths.nExcepsV; + // invariant: widths.excepsV[a].first <= cid < widths.excepsV[b].first + while (b - a > 1) { + m = (a + b) / 2; + if (widths.excepsV[m].last <= cid) { + a = m; + } else { + b = m; + } + } + if (cid <= widths.excepsV[a].last) { + h = widths.excepsV[a].height; + vx = widths.excepsV[a].vx; + vy = widths.excepsV[a].vy; + } + } + } + + *dx = w; + *dy = h; + *ox = vx; + *oy = vy; + + return n; +} + +int GfxCIDFont::getWMode() { + return cMap ? cMap->getWMode() : 0; +} + +CharCodeToUnicode *GfxCIDFont::getToUnicode() { + if (ctu) { + ctu->incRefCnt(); + } + return ctu; +} + +GooString *GfxCIDFont::getCollection() { + return cMap ? cMap->getCollection() : (GooString *)NULL; +} + +Gushort *GfxCIDFont::getCodeToGIDMap(FoFiTrueType *ff, int *mapsizep) { + Gushort *map; + int cmapPlatform, cmapEncoding; + int cmap; + Unicode u; + int i; + CharCode mapsize; + CharCode cidlen; + + *mapsizep = 0; + if (!ctu) return NULL; + + /* we use only unicode cmap */ + cmap = -1; + for (i = 0; i < ff->getNumCmaps(); ++i) { + cmapPlatform = ff->getCmapPlatform(i); + cmapEncoding = ff->getCmapEncoding(i); + if ((cmapPlatform == 3 && cmapEncoding == 1) || cmapPlatform == 0) + cmap = i; + } + if (cmap < 0) + return NULL; + + cidlen = 0; + mapsize = 64; + map = (Gushort *)gmalloc(mapsize * sizeof(Gushort)); + + while (cidlen < ctu->getLength()) { + int n; + if ((n = ctu->mapToUnicode((CharCode)cidlen, &u, 1)) == 0) { + cidlen++; + continue; + } + if (cidlen >= mapsize) { + while (cidlen >= mapsize) + mapsize *= 2; + map = (Gushort *)grealloc(map, mapsize * sizeof(Gushort)); + } + map[cidlen] = ff->mapCodeToGID(cmap, u); + cidlen++; + } + + *mapsizep = cidlen; + return map; +} + +//------------------------------------------------------------------------ +// GfxFontDict +//------------------------------------------------------------------------ + +GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) { + int i; + Object obj1, obj2; + Ref r; + + numFonts = fontDict->getLength(); + fonts = (GfxFont **)gmallocn(numFonts, sizeof(GfxFont *)); + for (i = 0; i < numFonts; ++i) { + fontDict->getValNF(i, &obj1); + obj1.fetch(xref, &obj2); + if (obj2.isDict()) { + if (obj1.isRef()) { + r = obj1.getRef(); + } else { + // no indirect reference for this font, so invent a unique one + // (legal generation numbers are five digits, so any 6-digit + // number would be safe) + r.num = i; + if (fontDictRef) { + r.gen = 100000 + fontDictRef->num; + } else { + r.gen = 999999; + } + } + char *aux = fontDict->getKey(i)->getCStringCopy(); + fonts[i] = GfxFont::makeFont(xref, aux, + r, obj2.getDict()); + delete[] aux; + if (fonts[i] && !fonts[i]->isOk()) { + delete fonts[i]; + fonts[i] = NULL; + } + } else { + error(-1, "font resource is not a dictionary"); + fonts[i] = NULL; + } + obj1.free(); + obj2.free(); + } +} + +GfxFontDict::~GfxFontDict() { + int i; + + for (i = 0; i < numFonts; ++i) { + if (fonts[i]) { + fonts[i]->decRefCnt(); + } + } + gfree(fonts); +} + +GfxFont *GfxFontDict::lookup(char *tag) { + int i; + + for (i = 0; i < numFonts; ++i) { + if (fonts[i] && fonts[i]->matches(tag)) { + return fonts[i]; + } + } + return NULL; +} diff --git a/rosapps/smartpdf/poppler/poppler/GfxFont.h b/rosapps/smartpdf/poppler/poppler/GfxFont.h new file mode 100644 index 00000000000..80612ef60f2 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/GfxFont.h @@ -0,0 +1,355 @@ +//======================================================================== +// +// GfxFont.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GFXFONT_H +#define GFXFONT_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "goo/GooString.h" +#include "Object.h" +#include "CharTypes.h" + +class Dict; +class CMap; +class CharCodeToUnicode; +class FoFiTrueType; +struct GfxFontCIDWidths; + +//------------------------------------------------------------------------ +// GfxFontType +//------------------------------------------------------------------------ + +enum GfxFontType { + //----- Gfx8BitFont + fontUnknownType, + fontType1, + fontType1C, + fontType3, + fontTrueType, + //----- GfxCIDFont + fontCIDType0, + fontCIDType0C, + fontCIDType2 +}; + +//------------------------------------------------------------------------ +// GfxFontCIDWidths +//------------------------------------------------------------------------ + +struct GfxFontCIDWidthExcep { + CID first; // this record applies to + CID last; // CIDs .. + double width; // char width +}; + +struct GfxFontCIDWidthExcepV { + CID first; // this record applies to + CID last; // CIDs .. + double height; // char height + double vx, vy; // origin position +}; + +struct GfxFontCIDWidths { + double defWidth; // default char width + double defHeight; // default char height + double defVY; // default origin position + GfxFontCIDWidthExcep *exceps; // exceptions + int nExceps; // number of valid entries in exceps + GfxFontCIDWidthExcepV * // exceptions for vertical font + excepsV; + int nExcepsV; // number of valid entries in excepsV +}; + +//------------------------------------------------------------------------ +// GfxFont +//------------------------------------------------------------------------ + +#define fontFixedWidth (1 << 0) +#define fontSerif (1 << 1) +#define fontSymbolic (1 << 2) +#define fontItalic (1 << 6) +#define fontBold (1 << 18) + +class GfxFont { +public: + + enum Stretch { + StretchNotDefined, + UltraCondensed, + ExtraCondensed, + Condensed, + SemiCondensed, + Normal, + SemiExpanded, + Expanded, + ExtraExpanded, + UltraExpanded }; + + enum Weight { + WeightNotDefined, + W100, + W200, + W300, + W400, // Normal + W500, + W600, + W700, // Bold + W800, + W900 }; + + // Build a GfxFont object. + static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict); + + GfxFont(char *tagA, Ref idA, GooString *nameA); + + virtual ~GfxFont(); + + GBool isOk() { return ok; } + + void incRefCnt(); + void decRefCnt(); + + // Get font tag. + GooString *getTag() { return tag; } + + // Get font dictionary ID. + Ref *getID() { return &id; } + + // Does this font match the tag? + GBool matches(char *tagA) { return !tag->cmp(tagA); } + + // Get base font name. + GooString *getName() { return name; } + + // Get font family name. + GooString *getFamily() { return family; } + + // Get font stretch. + Stretch getStretch() { return stretch; } + + // Get font weight. + Weight getWeight() { return weight; } + + // Get the original font name (ignornig any munging that might have + // been done to map to a canonical Base-14 font name). + GooString *getOrigName() { return origName; } + + // Get font type. + GfxFontType getType() { return type; } + virtual GBool isCIDFont() { return gFalse; } + + // Get embedded font ID, i.e., a ref for the font file stream. + // Returns false if there is no embedded font. + GBool getEmbeddedFontID(Ref *embID) + { *embID = embFontID; return embFontID.num >= 0; } + + // Get the PostScript font name for the embedded font. Returns + // NULL if there is no embedded font. + GooString *getEmbeddedFontName() { return embFontName; } + + // Get the name of the external font file. Returns NULL if there + // is no external font file. + GooString *getExtFontFile() { return extFontFile; } + + // Get font descriptor flags. + GBool isFixedWidth() { return flags & fontFixedWidth; } + GBool isSerif() { return flags & fontSerif; } + GBool isSymbolic() { return flags & fontSymbolic; } + GBool isItalic() { return flags & fontItalic; } + GBool isBold() { return flags & fontBold; } + + // Return the font matrix. + double *getFontMatrix() { return fontMat; } + + // Return the font bounding box. + double *getFontBBox() { return fontBBox; } + + // Return the ascent and descent values. + double getAscent() { return ascent; } + double getDescent() { return descent; } + + // Return the writing mode (0=horizontal, 1=vertical). + virtual int getWMode() { return 0; } + + // Read an external or embedded font file into a buffer. + char *readExtFontFile(int *len); + char *readEmbFontFile(XRef *xref, int *len); + + // Get the next char from a string of bytes, returning the + // char , its Unicode mapping , its displacement vector + // (, ), and its origin offset vector (, ). + // is the number of entries available in , and is set to + // the number actually used. Returns the number of bytes used by + // the char code. + virtual int getNextChar(char *s, int len, CharCode *code, + Unicode *u, int uSize, int *uLen, + double *dx, double *dy, double *ox, double *oy) = 0; + +protected: + + void readFontDescriptor(XRef *xref, Dict *fontDict); + CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits, + CharCodeToUnicode *ctu); + void findExtFontFile(); + + GooString *tag; // PDF font tag + Ref id; // reference (used as unique ID) + GooString *name; // font name + GooString *family; // font family + Stretch stretch; // font stretch + Weight weight; // font weight + GooString *origName; // original font name + GfxFontType type; // type of font + int flags; // font descriptor flags + GooString *embFontName; // name of embedded font + Ref embFontID; // ref to embedded font file stream + GooString *extFontFile; // external font file name + double fontMat[6]; // font matrix (Type 3 only) + double fontBBox[4]; // font bounding box (Type 3 only) + double missingWidth; // "default" width + double ascent; // max height above baseline + double descent; // max depth below baseline + int refCnt; + GBool ok; +}; + +//------------------------------------------------------------------------ +// Gfx8BitFont +//------------------------------------------------------------------------ + +class Gfx8BitFont: public GfxFont { +public: + + Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GooString *nameA, + GfxFontType typeA, Dict *fontDict); + + virtual ~Gfx8BitFont(); + + virtual int getNextChar(char *s, int len, CharCode *code, + Unicode *u, int uSize, int *uLen, + double *dx, double *dy, double *ox, double *oy); + + // Return the encoding. + char **getEncoding() { return enc; } + + // Return the Unicode map. + CharCodeToUnicode *getToUnicode(); + + // Return the character name associated with . + char *getCharName(int code) { return enc[code]; } + + // Returns true if the PDF font specified an encoding. + GBool getHasEncoding() { return hasEncoding; } + + // Returns true if the PDF font specified MacRomanEncoding. + GBool getUsesMacRomanEnc() { return usesMacRomanEnc; } + + // Get width of a character. + double getWidth(Guchar c) { return widths[c]; } + + // Return a char code-to-GID mapping for the provided font file. + // (This is only useful for TrueType fonts.) + Gushort *getCodeToGIDMap(FoFiTrueType *ff); + + // Return the Type 3 CharProc dictionary, or NULL if none. + Dict *getCharProcs(); + + // Return the Type 3 CharProc for the character associated with . + Object *getCharProc(int code, Object *proc); + + // Return the Type 3 Resources dictionary, or NULL if none. + Dict *getResources(); + +private: + + char *enc[256]; // char code --> char name + char encFree[256]; // boolean for each char name: if set, + // the string is malloc'ed + CharCodeToUnicode *ctu; // char code --> Unicode + GBool hasEncoding; + GBool usesMacRomanEnc; + double widths[256]; // character widths + Object charProcs; // Type 3 CharProcs dictionary + Object resources; // Type 3 Resources dictionary +}; + +//------------------------------------------------------------------------ +// GfxCIDFont +//------------------------------------------------------------------------ + +class GfxCIDFont: public GfxFont { +public: + + GfxCIDFont(XRef *xref, char *tagA, Ref idA, GooString *nameA, + Dict *fontDict); + + virtual ~GfxCIDFont(); + + virtual GBool isCIDFont() { return gTrue; } + + virtual int getNextChar(char *s, int len, CharCode *code, + Unicode *u, int uSize, int *uLen, + double *dx, double *dy, double *ox, double *oy); + + // Return the writing mode (0=horizontal, 1=vertical). + virtual int getWMode(); + + // Return the Unicode map. + CharCodeToUnicode *getToUnicode(); + + // Get the collection name (-). + GooString *getCollection(); + + // Return the CID-to-GID mapping table. These should only be called + // if type is fontCIDType2. + Gushort *getCIDToGID() { return cidToGID; } + int getCIDToGIDLen() { return cidToGIDLen; } + + Gushort *getCodeToGIDMap(FoFiTrueType *ff, int *length); + +private: + + CMap *cMap; // char code --> CID + CharCodeToUnicode *ctu; // CID --> Unicode + GfxFontCIDWidths widths; // character widths + Gushort *cidToGID; // CID --> GID mapping (for embedded + // TrueType fonts) + int cidToGIDLen; +}; + +//------------------------------------------------------------------------ +// GfxFontDict +//------------------------------------------------------------------------ + +class GfxFontDict { +public: + + // Build the font dictionary, given the PDF font dictionary. + GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict); + + // Destructor. + ~GfxFontDict(); + + // Get the specified font. + GfxFont *lookup(char *tag); + + // Iterative access. + int getNumFonts() { return numFonts; } + GfxFont *getFont(int i) { return fonts[i]; } + +private: + + GfxFont **fonts; // list of fonts + int numFonts; // number of fonts +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/GfxState.cc b/rosapps/smartpdf/poppler/poppler/GfxState.cc new file mode 100644 index 00000000000..48fd8dea2b3 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/GfxState.cc @@ -0,0 +1,4187 @@ +//======================================================================== +// +// GfxState.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include "goo/gmem.h" +#include "Error.h" +#include "Object.h" +#include "Array.h" +#include "Page.h" +#include "GfxState.h" +#include "GfxFont.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ + +static inline GfxColorComp clip01(GfxColorComp x) { + return (x < 0) ? 0 : (x > gfxColorComp1) ? gfxColorComp1 : x; +} + +static inline double clip01(double x) { + return (x < 0) ? 0 : (x > 1) ? 1 : x; +} + +GBool Matrix::invertTo(Matrix *other) +{ + double det; + + det = 1 / (m[0] * m[3] - m[1] * m[2]); + other->m[0] = m[3] * det; + other->m[1] = -m[1] * det; + other->m[2] = -m[2] * det; + other->m[3] = m[0] * det; + other->m[4] = (m[2] * m[5] - m[3] * m[4]) * det; + other->m[5] = (m[1] * m[4] - m[0] * m[5]) * det; + + return gTrue; +} + +void Matrix::transform(double x, double y, double *tx, double *ty) +{ + double temp_x, temp_y; + + temp_x = m[0] * x + m[2] * y + m[4]; + temp_y = m[1] * x + m[3] * y + m[5]; + + *tx = temp_x; + *ty = temp_y; +} + +//------------------------------------------------------------------------ + +struct gfxBlendModeName { + char *name; + GfxBlendMode mode; +}; + +static gfxBlendModeName gfxBlendModeNames[] = { + { "Normal", gfxBlendNormal }, + { "Compatible", gfxBlendNormal }, + { "Multiply", gfxBlendMultiply }, + { "Screen", gfxBlendScreen }, + { "Overlay", gfxBlendOverlay }, + { "Darken", gfxBlendDarken }, + { "Lighten", gfxBlendLighten }, + { "ColorDodge", gfxBlendColorDodge }, + { "ColorBurn", gfxBlendColorBurn }, + { "HardLight", gfxBlendHardLight }, + { "SoftLight", gfxBlendSoftLight }, + { "Difference", gfxBlendDifference }, + { "Exclusion", gfxBlendExclusion }, + { "Hue", gfxBlendHue }, + { "Saturation", gfxBlendSaturation }, + { "Color", gfxBlendColor }, + { "Luminosity", gfxBlendLuminosity } +}; + +#define nGfxBlendModeNames \ + ((int)((sizeof(gfxBlendModeNames) / sizeof(gfxBlendModeName)))) + +//------------------------------------------------------------------------ +// +// NB: This must match the GfxColorSpaceMode enum defined in +// GfxState.h +static char *gfxColorSpaceModeNames[] = { + "DeviceGray", + "CalGray", + "DeviceRGB", + "CalRGB", + "DeviceCMYK", + "Lab", + "ICCBased", + "Indexed", + "Separation", + "DeviceN", + "Pattern" +}; + +#define nGfxColorSpaceModes ((sizeof(gfxColorSpaceModeNames) / sizeof(char *))) + +//------------------------------------------------------------------------ +// GfxColorSpace +//------------------------------------------------------------------------ + +GfxColorSpace::GfxColorSpace() { +} + +GfxColorSpace::~GfxColorSpace() { +} + +GfxColorSpace *GfxColorSpace::parse(Object *csObj) { + GfxColorSpace *cs; + Object obj1; + + cs = NULL; + if (csObj->isName()) { + if (csObj->isName("DeviceGray") || csObj->isName("G")) { + cs = new GfxDeviceGrayColorSpace(); + } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) { + cs = new GfxDeviceRGBColorSpace(); + } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) { + cs = new GfxDeviceCMYKColorSpace(); + } else if (csObj->isName("Pattern")) { + cs = new GfxPatternColorSpace(NULL); + } else { + error(-1, "Bad color space '%s'", csObj->getNameC()); + } + } else if (csObj->isArray()) { + csObj->arrayGet(0, &obj1); + if (obj1.isName("DeviceGray") || obj1.isName("G")) { + cs = new GfxDeviceGrayColorSpace(); + } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) { + cs = new GfxDeviceRGBColorSpace(); + } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) { + cs = new GfxDeviceCMYKColorSpace(); + } else if (obj1.isName("CalGray")) { + cs = GfxCalGrayColorSpace::parse(csObj->getArray()); + } else if (obj1.isName("CalRGB")) { + cs = GfxCalRGBColorSpace::parse(csObj->getArray()); + } else if (obj1.isName("Lab")) { + cs = GfxLabColorSpace::parse(csObj->getArray()); + } else if (obj1.isName("ICCBased")) { + cs = GfxICCBasedColorSpace::parse(csObj->getArray()); + } else if (obj1.isName("Indexed") || obj1.isName("I")) { + cs = GfxIndexedColorSpace::parse(csObj->getArray()); + } else if (obj1.isName("Separation")) { + cs = GfxSeparationColorSpace::parse(csObj->getArray()); + } else if (obj1.isName("DeviceN")) { + cs = GfxDeviceNColorSpace::parse(csObj->getArray()); + } else if (obj1.isName("Pattern")) { + cs = GfxPatternColorSpace::parse(csObj->getArray()); + } else { + error(-1, "Bad color space"); + } + obj1.free(); + } else { + error(-1, "Bad color space - expected name or array"); + } + return cs; +} + +void GfxColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange, + int maxImgPixel) { + int i; + + for (i = 0; i < getNComps(); ++i) { + decodeLow[i] = 0; + decodeRange[i] = 1; + } +} + +int GfxColorSpace::getNumColorSpaceModes() { + return nGfxColorSpaceModes; +} + +char *GfxColorSpace::getColorSpaceModeName(int idx) { + return gfxColorSpaceModeNames[idx]; +} + +void GfxColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length) { + int i, j, n; + GfxColor color; + GfxRGB rgb; + + n = getNComps(); + for (i = 0; i < length; i++) { + + for (j = 0; j < n; j++) + color.c[j] = in[i * n + j] * 256; + + getRGB (&color, &rgb); + out[i] = + ((int) colToByte(rgb.r) << 16) | + ((int) colToByte(rgb.g) << 8) | + ((int) colToByte(rgb.b) << 0); + } +} + +void GfxColorSpace::getGrayLine(Guchar *in, unsigned char *out, int length) { + int i, j, n; + GfxColor color; + GfxGray gray; + + n = getNComps(); + for (i = 0; i < length; i++) { + + for (j = 0; j < n; j++) + color.c[j] = in[i * n + j] * 256; + + getGray (&color, &gray); + out[i] = colToByte(gray); + } +} + + +//------------------------------------------------------------------------ +// GfxDeviceGrayColorSpace +//------------------------------------------------------------------------ + +GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() { +} + +GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() { +} + +GfxColorSpace *GfxDeviceGrayColorSpace::copy() { + return new GfxDeviceGrayColorSpace(); +} + +void GfxDeviceGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01(color->c[0]); +} + +void GfxDeviceGrayColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) { + memcpy (out, in, length); +} + +void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + rgb->r = rgb->g = rgb->b = clip01(color->c[0]); +} + +void GfxDeviceGrayColorSpace::getRGBLine(Guchar *in, unsigned int *out, + int length) { + int i; + + for (i = 0; i < length; i++) + out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0); +} + +void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + cmyk->c = cmyk->m = cmyk->y = 0; + cmyk->k = clip01(gfxColorComp1 - color->c[0]); +} + +//------------------------------------------------------------------------ +// GfxCalGrayColorSpace +//------------------------------------------------------------------------ + +GfxCalGrayColorSpace::GfxCalGrayColorSpace() { + whiteX = whiteY = whiteZ = 1; + blackX = blackY = blackZ = 0; + gamma = 1; +} + +GfxCalGrayColorSpace::~GfxCalGrayColorSpace() { +} + +GfxColorSpace *GfxCalGrayColorSpace::copy() { + GfxCalGrayColorSpace *cs; + + cs = new GfxCalGrayColorSpace(); + cs->whiteX = whiteX; + cs->whiteY = whiteY; + cs->whiteZ = whiteZ; + cs->blackX = blackX; + cs->blackY = blackY; + cs->blackZ = blackZ; + cs->gamma = gamma; + return cs; +} + +GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) { + GfxCalGrayColorSpace *cs; + Object obj1, obj2, obj3; + + arr->get(1, &obj1); + if (!obj1.isDict()) { + error(-1, "Bad CalGray color space"); + obj1.free(); + return NULL; + } + cs = new GfxCalGrayColorSpace(); + if (obj1.dictLookup("WhitePoint", &obj2)->isArray() && + obj2.arrayGetLength() == 3) { + obj2.arrayGet(0, &obj3); + cs->whiteX = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->whiteY = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->whiteZ = obj3.getNum(); + obj3.free(); + } + obj2.free(); + if (obj1.dictLookup("BlackPoint", &obj2)->isArray() && + obj2.arrayGetLength() == 3) { + obj2.arrayGet(0, &obj3); + cs->blackX = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->blackY = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->blackZ = obj3.getNum(); + obj3.free(); + } + obj2.free(); + if (obj1.dictLookup("Gamma", &obj2)->isNum()) { + cs->gamma = obj2.getNum(); + } + obj2.free(); + obj1.free(); + return cs; +} + +void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01(color->c[0]); +} + +void GfxCalGrayColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) { + memcpy (out, in, length); +} + +void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + rgb->r = rgb->g = rgb->b = clip01(color->c[0]); +} + +void GfxCalGrayColorSpace::getRGBLine(Guchar *in, unsigned int *out, + int length) { + int i; + + for (i = 0; i < length; i++) + out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0); +} + +void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + cmyk->c = cmyk->m = cmyk->y = 0; + cmyk->k = clip01(gfxColorComp1 - color->c[0]); +} + +//------------------------------------------------------------------------ +// GfxDeviceRGBColorSpace +//------------------------------------------------------------------------ + +GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() { +} + +GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() { +} + +GfxColorSpace *GfxDeviceRGBColorSpace::copy() { + return new GfxDeviceRGBColorSpace(); +} + +void GfxDeviceRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01((GfxColorComp)(0.3 * color->c[0] + + 0.59 * color->c[1] + + 0.11 * color->c[2] + 0.5)); +} + +void GfxDeviceRGBColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) { + int i; + + for (i = 0; i < length; i++) { + out[i] = + (in[i * 3 + 0] * 19595 + + in[i * 3 + 1] * 38469 + + in[i * 3 + 2] * 7472) / 65536; + } +} + +void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + rgb->r = clip01(color->c[0]); + rgb->g = clip01(color->c[1]); + rgb->b = clip01(color->c[2]); +} + +void GfxDeviceRGBColorSpace::getRGBLine(Guchar *in, unsigned int *out, + int length) { + Guchar *p; + int i; + + for (i = 0, p = in; i < length; i++, p += 3) + out[i] = (p[0] << 16) | (p[1] << 8) | (p[2] << 0); +} + +void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + GfxColorComp c, m, y, k; + + c = clip01(gfxColorComp1 - color->c[0]); + m = clip01(gfxColorComp1 - color->c[1]); + y = clip01(gfxColorComp1 - color->c[2]); + k = c; + if (m < k) { + k = m; + } + if (y < k) { + k = y; + } + cmyk->c = c - k; + cmyk->m = m - k; + cmyk->y = y - k; + cmyk->k = k; +} + +//------------------------------------------------------------------------ +// GfxCalRGBColorSpace +//------------------------------------------------------------------------ + +GfxCalRGBColorSpace::GfxCalRGBColorSpace() { + whiteX = whiteY = whiteZ = 1; + blackX = blackY = blackZ = 0; + gammaR = gammaG = gammaB = 1; + mat[0] = 1; mat[1] = 0; mat[2] = 0; + mat[3] = 0; mat[4] = 1; mat[5] = 0; + mat[6] = 0; mat[7] = 0; mat[8] = 1; +} + +GfxCalRGBColorSpace::~GfxCalRGBColorSpace() { +} + +GfxColorSpace *GfxCalRGBColorSpace::copy() { + GfxCalRGBColorSpace *cs; + int i; + + cs = new GfxCalRGBColorSpace(); + cs->whiteX = whiteX; + cs->whiteY = whiteY; + cs->whiteZ = whiteZ; + cs->blackX = blackX; + cs->blackY = blackY; + cs->blackZ = blackZ; + cs->gammaR = gammaR; + cs->gammaG = gammaG; + cs->gammaB = gammaB; + for (i = 0; i < 9; ++i) { + cs->mat[i] = mat[i]; + } + return cs; +} + +GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) { + GfxCalRGBColorSpace *cs; + Object obj1, obj2, obj3; + int i; + + arr->get(1, &obj1); + if (!obj1.isDict()) { + error(-1, "Bad CalRGB color space"); + obj1.free(); + return NULL; + } + cs = new GfxCalRGBColorSpace(); + if (obj1.dictLookup("WhitePoint", &obj2)->isArray() && + obj2.arrayGetLength() == 3) { + obj2.arrayGet(0, &obj3); + cs->whiteX = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->whiteY = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->whiteZ = obj3.getNum(); + obj3.free(); + } + obj2.free(); + if (obj1.dictLookup("BlackPoint", &obj2)->isArray() && + obj2.arrayGetLength() == 3) { + obj2.arrayGet(0, &obj3); + cs->blackX = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->blackY = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->blackZ = obj3.getNum(); + obj3.free(); + } + obj2.free(); + if (obj1.dictLookup("Gamma", &obj2)->isArray() && + obj2.arrayGetLength() == 3) { + obj2.arrayGet(0, &obj3); + cs->gammaR = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->gammaG = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->gammaB = obj3.getNum(); + obj3.free(); + } + obj2.free(); + if (obj1.dictLookup("Matrix", &obj2)->isArray() && + obj2.arrayGetLength() == 9) { + for (i = 0; i < 9; ++i) { + obj2.arrayGet(i, &obj3); + cs->mat[i] = obj3.getNum(); + obj3.free(); + } + } + obj2.free(); + obj1.free(); + return cs; +} + +void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01((GfxColorComp)(0.299 * color->c[0] + + 0.587 * color->c[1] + + 0.114 * color->c[2] + 0.5)); +} + +void GfxCalRGBColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) { + int i; + + for (i = 0; i < length; i++) { + out[i] = + (in[i * 3 + 0] * 19595 + + in[i * 3 + 1] * 38469 + + in[i * 3 + 2] * 7472) / 65536; + } +} + +void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + rgb->r = clip01(color->c[0]); + rgb->g = clip01(color->c[1]); + rgb->b = clip01(color->c[2]); +} + +void GfxCalRGBColorSpace::getRGBLine(Guchar *in, unsigned int *out, + int length) { + Guchar *p; + int i; + + for (i = 0, p = in; i < length; i++, p += 3) + out[i] = (p[0] << 16) | (p[1] << 8) | (p[2] << 0); +} + +void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + GfxColorComp c, m, y, k; + + c = clip01(gfxColorComp1 - color->c[0]); + m = clip01(gfxColorComp1 - color->c[1]); + y = clip01(gfxColorComp1 - color->c[2]); + k = c; + if (m < k) { + k = m; + } + if (y < k) { + k = y; + } + cmyk->c = c - k; + cmyk->m = m - k; + cmyk->y = y - k; + cmyk->k = k; +} + +//------------------------------------------------------------------------ +// GfxDeviceCMYKColorSpace +//------------------------------------------------------------------------ + +GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() { +} + +GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() { +} + +GfxColorSpace *GfxDeviceCMYKColorSpace::copy() { + return new GfxDeviceCMYKColorSpace(); +} + +void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = clip01((GfxColorComp)(gfxColorComp1 - color->c[3] + - 0.3 * color->c[0] + - 0.59 * color->c[1] + - 0.11 * color->c[2] + 0.5)); +} + +void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + double c, m, y, k, c1, m1, y1, k1, r, g, b, x; + + c = colToDbl(color->c[0]); + m = colToDbl(color->c[1]); + y = colToDbl(color->c[2]); + k = colToDbl(color->c[3]); + c1 = 1 - c; + m1 = 1 - m; + y1 = 1 - y; + k1 = 1 - k; + // this is a matrix multiplication, unrolled for performance + // C M Y K + x = c1 * m1 * y1 * k1; // 0 0 0 0 + r = g = b = x; + x = c1 * m1 * y1 * k; // 0 0 0 1 + r += 0.1373 * x; + g += 0.1216 * x; + b += 0.1255 * x; + x = c1 * m1 * y * k1; // 0 0 1 0 + r += x; + g += 0.9490 * x; + x = c1 * m1 * y * k; // 0 0 1 1 + r += 0.1098 * x; + g += 0.1020 * x; + x = c1 * m * y1 * k1; // 0 1 0 0 + r += 0.9255 * x; + b += 0.5490 * x; + x = c1 * m * y1 * k; // 0 1 0 1 + r += 0.1412 * x; + x = c1 * m * y * k1; // 0 1 1 0 + r += 0.9294 * x; + g += 0.1098 * x; + b += 0.1412 * x; + x = c1 * m * y * k; // 0 1 1 1 + r += 0.1333 * x; + x = c * m1 * y1 * k1; // 1 0 0 0 + g += 0.6784 * x; + b += 0.9373 * x; + x = c * m1 * y1 * k; // 1 0 0 1 + g += 0.0588 * x; + b += 0.1412 * x; + x = c * m1 * y * k1; // 1 0 1 0 + g += 0.6510 * x; + b += 0.3137 * x; + x = c * m1 * y * k; // 1 0 1 1 + g += 0.0745 * x; + x = c * m * y1 * k1; // 1 1 0 0 + r += 0.1804 * x; + g += 0.1922 * x; + b += 0.5725 * x; + x = c * m * y1 * k; // 1 1 0 1 + b += 0.0078 * x; + x = c * m * y * k1; // 1 1 1 0 + r += 0.2118 * x; + g += 0.2119 * x; + b += 0.2235 * x; + rgb->r = clip01(dblToCol(r)); + rgb->g = clip01(dblToCol(g)); + rgb->b = clip01(dblToCol(b)); +} + +void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + cmyk->c = clip01(color->c[0]); + cmyk->m = clip01(color->c[1]); + cmyk->y = clip01(color->c[2]); + cmyk->k = clip01(color->c[3]); +} + +//------------------------------------------------------------------------ +// GfxLabColorSpace +//------------------------------------------------------------------------ + +// This is the inverse of MatrixLMN in Example 4.10 from the PostScript +// Language Reference, Third Edition. +static double xyzrgb[3][3] = { + { 3.240449, -1.537136, -0.498531 }, + { -0.969265, 1.876011, 0.041556 }, + { 0.055643, -0.204026, 1.057229 } +}; + +GfxLabColorSpace::GfxLabColorSpace() { + whiteX = whiteY = whiteZ = 1; + blackX = blackY = blackZ = 0; + aMin = bMin = -100; + aMax = bMax = 100; +} + +GfxLabColorSpace::~GfxLabColorSpace() { +} + +GfxColorSpace *GfxLabColorSpace::copy() { + GfxLabColorSpace *cs; + + cs = new GfxLabColorSpace(); + cs->whiteX = whiteX; + cs->whiteY = whiteY; + cs->whiteZ = whiteZ; + cs->blackX = blackX; + cs->blackY = blackY; + cs->blackZ = blackZ; + cs->aMin = aMin; + cs->aMax = aMax; + cs->bMin = bMin; + cs->bMax = bMax; + cs->kr = kr; + cs->kg = kg; + cs->kb = kb; + return cs; +} + +GfxColorSpace *GfxLabColorSpace::parse(Array *arr) { + GfxLabColorSpace *cs; + Object obj1, obj2, obj3; + + arr->get(1, &obj1); + if (!obj1.isDict()) { + error(-1, "Bad Lab color space"); + obj1.free(); + return NULL; + } + cs = new GfxLabColorSpace(); + if (obj1.dictLookup("WhitePoint", &obj2)->isArray() && + obj2.arrayGetLength() == 3) { + obj2.arrayGet(0, &obj3); + cs->whiteX = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->whiteY = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->whiteZ = obj3.getNum(); + obj3.free(); + } + obj2.free(); + if (obj1.dictLookup("BlackPoint", &obj2)->isArray() && + obj2.arrayGetLength() == 3) { + obj2.arrayGet(0, &obj3); + cs->blackX = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->blackY = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->blackZ = obj3.getNum(); + obj3.free(); + } + obj2.free(); + if (obj1.dictLookup("Range", &obj2)->isArray() && + obj2.arrayGetLength() == 4) { + obj2.arrayGet(0, &obj3); + cs->aMin = obj3.getNum(); + obj3.free(); + obj2.arrayGet(1, &obj3); + cs->aMax = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2, &obj3); + cs->bMin = obj3.getNum(); + obj3.free(); + obj2.arrayGet(3, &obj3); + cs->bMax = obj3.getNum(); + obj3.free(); + } + obj2.free(); + obj1.free(); + + cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX + + xyzrgb[0][1] * cs->whiteY + + xyzrgb[0][2] * cs->whiteZ); + cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX + + xyzrgb[1][1] * cs->whiteY + + xyzrgb[1][2] * cs->whiteZ); + cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX + + xyzrgb[2][1] * cs->whiteY + + xyzrgb[2][2] * cs->whiteZ); + + return cs; +} + +void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) { + GfxRGB rgb; + + getRGB(color, &rgb); + *gray = clip01((GfxColorComp)(0.299 * rgb.r + + 0.587 * rgb.g + + 0.114 * rgb.b + 0.5)); +} + +void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + double X, Y, Z; + double t1, t2; + double r, g, b; + + // convert L*a*b* to CIE 1931 XYZ color space + t1 = (colToDbl(color->c[0]) + 16) / 116; + t2 = t1 + colToDbl(color->c[1]) / 500; + if (t2 >= (6.0 / 29.0)) { + X = t2 * t2 * t2; + } else { + X = (108.0 / 841.0) * (t2 - (4.0 / 29.0)); + } + X *= whiteX; + if (t1 >= (6.0 / 29.0)) { + Y = t1 * t1 * t1; + } else { + Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0)); + } + Y *= whiteY; + t2 = t1 - colToDbl(color->c[2]) / 200; + if (t2 >= (6.0 / 29.0)) { + Z = t2 * t2 * t2; + } else { + Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0)); + } + Z *= whiteZ; + + // convert XYZ to RGB, including gamut mapping and gamma correction + r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z; + g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z; + b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z; + rgb->r = dblToCol(pow(clip01(r * kr), 0.5)); + rgb->g = dblToCol(pow(clip01(g * kg), 0.5)); + rgb->b = dblToCol(pow(clip01(b * kb), 0.5)); +} + +void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + GfxRGB rgb; + GfxColorComp c, m, y, k; + + getRGB(color, &rgb); + c = clip01(gfxColorComp1 - rgb.r); + m = clip01(gfxColorComp1 - rgb.g); + y = clip01(gfxColorComp1 - rgb.b); + k = c; + if (m < k) { + k = m; + } + if (y < k) { + k = y; + } + cmyk->c = c - k; + cmyk->m = m - k; + cmyk->y = y - k; + cmyk->k = k; +} + +void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange, + int maxImgPixel) { + decodeLow[0] = 0; + decodeRange[0] = 100; + decodeLow[1] = aMin; + decodeRange[1] = aMax - aMin; + decodeLow[2] = bMin; + decodeRange[2] = bMax - bMin; +} + +//------------------------------------------------------------------------ +// GfxICCBasedColorSpace +//------------------------------------------------------------------------ + +GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA, + Ref *iccProfileStreamA) { + nComps = nCompsA; + alt = altA; + iccProfileStream = *iccProfileStreamA; + rangeMin[0] = rangeMin[1] = rangeMin[2] = rangeMin[3] = 0; + rangeMax[0] = rangeMax[1] = rangeMax[2] = rangeMax[3] = 1; +} + +GfxICCBasedColorSpace::~GfxICCBasedColorSpace() { + delete alt; +} + +GfxColorSpace *GfxICCBasedColorSpace::copy() { + GfxICCBasedColorSpace *cs; + int i; + + cs = new GfxICCBasedColorSpace(nComps, alt->copy(), &iccProfileStream); + for (i = 0; i < 4; ++i) { + cs->rangeMin[i] = rangeMin[i]; + cs->rangeMax[i] = rangeMax[i]; + } + return cs; +} + +GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { + GfxICCBasedColorSpace *cs; + Ref iccProfileStreamA; + int nCompsA; + GfxColorSpace *altA; + Dict *dict; + Object obj1, obj2, obj3; + int i; + + arr->getNF(1, &obj1); + if (obj1.isRef()) { + iccProfileStreamA = obj1.getRef(); + } else { + iccProfileStreamA.num = 0; + iccProfileStreamA.gen = 0; + } + obj1.free(); + arr->get(1, &obj1); + if (!obj1.isStream()) { + error(-1, "Bad ICCBased color space (stream)"); + obj1.free(); + return NULL; + } + dict = obj1.streamGetDict(); + if (!dict->lookup("N", &obj2)->isInt()) { + error(-1, "Bad ICCBased color space (N)"); + obj2.free(); + obj1.free(); + return NULL; + } + nCompsA = obj2.getInt(); + obj2.free(); + if (nCompsA > gfxColorMaxComps) { + error(-1, "ICCBased color space with too many (%d > %d) components", + nCompsA, gfxColorMaxComps); + nCompsA = gfxColorMaxComps; + } + if (dict->lookup("Alternate", &obj2)->isNull() || + !(altA = GfxColorSpace::parse(&obj2))) { + switch (nCompsA) { + case 1: + altA = new GfxDeviceGrayColorSpace(); + break; + case 3: + altA = new GfxDeviceRGBColorSpace(); + break; + case 4: + altA = new GfxDeviceCMYKColorSpace(); + break; + default: + error(-1, "Bad ICCBased color space - invalid N"); + obj2.free(); + obj1.free(); + return NULL; + } + } + obj2.free(); + cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA); + if (dict->lookup("Range", &obj2)->isArray() && + obj2.arrayGetLength() == 2 * nCompsA) { + for (i = 0; i < nCompsA; ++i) { + obj2.arrayGet(2*i, &obj3); + cs->rangeMin[i] = obj3.getNum(); + obj3.free(); + obj2.arrayGet(2*i+1, &obj3); + cs->rangeMax[i] = obj3.getNum(); + obj3.free(); + } + } + obj2.free(); + obj1.free(); + return cs; +} + +void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) { + alt->getGray(color, gray); +} + +void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + alt->getRGB(color, rgb); +} + +void GfxICCBasedColorSpace::getRGBLine(Guchar *in, unsigned int *out, + int length) { + alt->getRGBLine(in, out, length); +} + +void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + alt->getCMYK(color, cmyk); +} + +void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow, + double *decodeRange, + int maxImgPixel) { + alt->getDefaultRanges(decodeLow, decodeRange, maxImgPixel); + +#if 0 + // this is nominally correct, but some PDF files don't set the + // correct ranges in the ICCBased dict + int i; + + for (i = 0; i < nComps; ++i) { + decodeLow[i] = rangeMin[i]; + decodeRange[i] = rangeMax[i] - rangeMin[i]; + } +#endif +} + +//------------------------------------------------------------------------ +// GfxIndexedColorSpace +//------------------------------------------------------------------------ + +GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA, + int indexHighA) { + base = baseA; + indexHigh = indexHighA; + lookup = (Guchar *)gmallocn((indexHigh + 1) * base->getNComps(), + sizeof(Guchar)); +} + +GfxIndexedColorSpace::~GfxIndexedColorSpace() { + delete base; + gfree(lookup); +} + +GfxColorSpace *GfxIndexedColorSpace::copy() { + GfxIndexedColorSpace *cs; + + cs = new GfxIndexedColorSpace(base->copy(), indexHigh); + memcpy(cs->lookup, lookup, + (indexHigh + 1) * base->getNComps() * sizeof(Guchar)); + return cs; +} + +GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { + GfxIndexedColorSpace *cs; + GfxColorSpace *baseA; + int indexHighA; + Object obj1; + int x; + char *s; + int n, i, j; + + if (arr->getLength() != 4) { + error(-1, "Bad Indexed color space"); + goto err1; + } + arr->get(1, &obj1); + if (!(baseA = GfxColorSpace::parse(&obj1))) { + error(-1, "Bad Indexed color space (base color space)"); + goto err2; + } + obj1.free(); + if (!arr->get(2, &obj1)->isInt()) { + error(-1, "Bad Indexed color space (hival)"); + delete baseA; + goto err2; + } + indexHighA = obj1.getInt(); + if (indexHighA < 0 || indexHighA > 255) { + // the PDF spec requires indexHigh to be in [0,255] -- allowing + // values larger than 255 creates a security hole: if nComps * + // indexHigh is greater than 2^31, the loop below may overwrite + // past the end of the array + error(-1, "Bad Indexed color space (invalid indexHigh value)"); + delete baseA; + goto err2; + } + obj1.free(); + cs = new GfxIndexedColorSpace(baseA, indexHighA); + arr->get(3, &obj1); + n = baseA->getNComps(); + if (obj1.isStream()) { + obj1.streamReset(); + for (i = 0; i <= indexHighA; ++i) { + for (j = 0; j < n; ++j) { + if ((x = obj1.streamGetChar()) == EOF) { + error(-1, "Bad Indexed color space (lookup table stream too short)"); + goto err3; + } + cs->lookup[i*n + j] = (Guchar)x; + } + } + obj1.streamClose(); + } else if (obj1.isString()) { + if (obj1.getString()->getLength() < (indexHighA + 1) * n) { + error(-1, "Bad Indexed color space (lookup table string too short)"); + goto err3; + } + s = obj1.getString()->getCString(); + for (i = 0; i <= indexHighA; ++i) { + for (j = 0; j < n; ++j) { + cs->lookup[i*n + j] = (Guchar)*s++; + } + } + } else { + error(-1, "Bad Indexed color space (lookup table)"); + goto err3; + } + obj1.free(); + return cs; + + err3: + delete cs; + err2: + obj1.free(); + err1: + return NULL; +} + +GfxColor *GfxIndexedColorSpace::mapColorToBase(GfxColor *color, + GfxColor *baseColor) { + Guchar *p; + double low[gfxColorMaxComps], range[gfxColorMaxComps]; + int n, i; + + n = base->getNComps(); + base->getDefaultRanges(low, range, indexHigh); + p = &lookup[(int)(colToDbl(color->c[0]) + 0.5) * n]; + for (i = 0; i < n; ++i) { + baseColor->c[i] = dblToCol(low[i] + (p[i] / 255.0) * range[i]); + } + return baseColor; +} + +void GfxIndexedColorSpace::getGray(GfxColor *color, GfxGray *gray) { + GfxColor color2; + + base->getGray(mapColorToBase(color, &color2), gray); +} + +void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + GfxColor color2; + + base->getRGB(mapColorToBase(color, &color2), rgb); +} + +void GfxIndexedColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length) { + Guchar *line; + int i, j, n; + + n = base->getNComps(); + line = (Guchar *) gmalloc (length * n); + for (i = 0; i < length; i++) + for (j = 0; j < n; j++) + line[i * n + j] = lookup[in[i] * n + j]; + + base->getRGBLine(line, out, length); + + gfree (line); +} + +void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + GfxColor color2; + + base->getCMYK(mapColorToBase(color, &color2), cmyk); +} + +void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow, + double *decodeRange, + int maxImgPixel) { + decodeLow[0] = 0; + decodeRange[0] = maxImgPixel; +} + +//------------------------------------------------------------------------ +// GfxSeparationColorSpace +//------------------------------------------------------------------------ + +GfxSeparationColorSpace::GfxSeparationColorSpace(GooString *nameA, + GfxColorSpace *altA, + Function *funcA) { + name = nameA; + alt = altA; + func = funcA; +} + +GfxSeparationColorSpace::~GfxSeparationColorSpace() { + delete name; + delete alt; + delete func; +} + +GfxColorSpace *GfxSeparationColorSpace::copy() { + return new GfxSeparationColorSpace(name->copy(), alt->copy(), func->copy()); +} + +//~ handle the 'All' and 'None' colorants +GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) { + GfxSeparationColorSpace *cs; + GooString *nameA; + GfxColorSpace *altA; + Function *funcA; + Object obj1; + + if (arr->getLength() != 4) { + error(-1, "Bad Separation color space"); + goto err1; + } + if (!arr->get(1, &obj1)->isName()) { + error(-1, "Bad Separation color space (name)"); + goto err2; + } + nameA = new GooString(obj1.getName()); + obj1.free(); + arr->get(2, &obj1); + if (!(altA = GfxColorSpace::parse(&obj1))) { + error(-1, "Bad Separation color space (alternate color space)"); + goto err3; + } + obj1.free(); + arr->get(3, &obj1); + if (!(funcA = Function::parse(&obj1))) { + goto err4; + } + obj1.free(); + cs = new GfxSeparationColorSpace(nameA, altA, funcA); + return cs; + + err4: + delete altA; + err3: + delete nameA; + err2: + obj1.free(); + err1: + return NULL; +} + +void GfxSeparationColorSpace::getGray(GfxColor *color, GfxGray *gray) { + double x; + double c[gfxColorMaxComps]; + GfxColor color2; + int i; + + x = colToDbl(color->c[0]); + func->transform(&x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } + alt->getGray(&color2, gray); +} + +void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + double x; + double c[gfxColorMaxComps]; + GfxColor color2; + int i; + + x = colToDbl(color->c[0]); + func->transform(&x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } + alt->getRGB(&color2, rgb); +} + +void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + double x; + double c[gfxColorMaxComps]; + GfxColor color2; + int i; + + x = colToDbl(color->c[0]); + func->transform(&x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } + alt->getCMYK(&color2, cmyk); +} + +//------------------------------------------------------------------------ +// GfxDeviceNColorSpace +//------------------------------------------------------------------------ + +GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA, + GfxColorSpace *altA, + Function *funcA) { + nComps = nCompsA; + alt = altA; + func = funcA; +} + +GfxDeviceNColorSpace::~GfxDeviceNColorSpace() { + int i; + + for (i = 0; i < nComps; ++i) { + delete names[i]; + } + delete alt; + delete func; +} + +GfxColorSpace *GfxDeviceNColorSpace::copy() { + GfxDeviceNColorSpace *cs; + int i; + + cs = new GfxDeviceNColorSpace(nComps, alt->copy(), func->copy()); + for (i = 0; i < nComps; ++i) { + cs->names[i] = names[i]->copy(); + } + return cs; +} + +//~ handle the 'None' colorant +GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) { + GfxDeviceNColorSpace *cs; + int nCompsA; + GooString *namesA[gfxColorMaxComps]; + GfxColorSpace *altA; + Function *funcA; + Object obj1, obj2; + int i; + + if (arr->getLength() != 4 && arr->getLength() != 5) { + error(-1, "Bad DeviceN color space"); + goto err1; + } + if (!arr->get(1, &obj1)->isArray()) { + error(-1, "Bad DeviceN color space (names)"); + goto err2; + } + nCompsA = obj1.arrayGetLength(); + if (nCompsA > gfxColorMaxComps) { + error(-1, "DeviceN color space with too many (%d > %d) components", + nCompsA, gfxColorMaxComps); + nCompsA = gfxColorMaxComps; + } + for (i = 0; i < nCompsA; ++i) { + if (!obj1.arrayGet(i, &obj2)->isName()) { + error(-1, "Bad DeviceN color space (names)"); + obj2.free(); + goto err2; + } + namesA[i] = new GooString(obj2.getName()); + obj2.free(); + } + obj1.free(); + arr->get(2, &obj1); + if (!(altA = GfxColorSpace::parse(&obj1))) { + error(-1, "Bad DeviceN color space (alternate color space)"); + goto err3; + } + obj1.free(); + arr->get(3, &obj1); + if (!(funcA = Function::parse(&obj1))) { + goto err4; + } + obj1.free(); + cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA); + for (i = 0; i < nCompsA; ++i) { + cs->names[i] = namesA[i]; + } + return cs; + + err4: + delete altA; + err3: + for (i = 0; i < nCompsA; ++i) { + delete namesA[i]; + } + err2: + obj1.free(); + err1: + return NULL; +} + +void GfxDeviceNColorSpace::getGray(GfxColor *color, GfxGray *gray) { + double x[gfxColorMaxComps], c[gfxColorMaxComps]; + GfxColor color2; + int i; + + for (i = 0; i < nComps; ++i) { + x[i] = colToDbl(color->c[i]); + } + func->transform(x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } + alt->getGray(&color2, gray); +} + +void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + double x[gfxColorMaxComps], c[gfxColorMaxComps]; + GfxColor color2; + int i; + + for (i = 0; i < nComps; ++i) { + x[i] = colToDbl(color->c[i]); + } + func->transform(x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } + alt->getRGB(&color2, rgb); +} + +void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + double x[gfxColorMaxComps], c[gfxColorMaxComps]; + GfxColor color2; + int i; + + for (i = 0; i < nComps; ++i) { + x[i] = colToDbl(color->c[i]); + } + func->transform(x, c); + for (i = 0; i < alt->getNComps(); ++i) { + color2.c[i] = dblToCol(c[i]); + } + alt->getCMYK(&color2, cmyk); +} + +//------------------------------------------------------------------------ +// GfxPatternColorSpace +//------------------------------------------------------------------------ + +GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *underA) { + under = underA; +} + +GfxPatternColorSpace::~GfxPatternColorSpace() { + if (under) { + delete under; + } +} + +GfxColorSpace *GfxPatternColorSpace::copy() { + return new GfxPatternColorSpace(under ? under->copy() : + (GfxColorSpace *)NULL); +} + +GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) { + GfxPatternColorSpace *cs; + GfxColorSpace *underA; + Object obj1; + + if (arr->getLength() != 1 && arr->getLength() != 2) { + error(-1, "Bad Pattern color space"); + return NULL; + } + underA = NULL; + if (arr->getLength() == 2) { + arr->get(1, &obj1); + if (!(underA = GfxColorSpace::parse(&obj1))) { + error(-1, "Bad Pattern color space (underlying color space)"); + obj1.free(); + return NULL; + } + obj1.free(); + } + cs = new GfxPatternColorSpace(underA); + return cs; +} + +void GfxPatternColorSpace::getGray(GfxColor *color, GfxGray *gray) { + *gray = 0; +} + +void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { + rgb->r = rgb->g = rgb->b = 0; +} + +void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { + cmyk->c = cmyk->m = cmyk->y = 0; + cmyk->k = 1; +} + +//------------------------------------------------------------------------ +// Pattern +//------------------------------------------------------------------------ + +GfxPattern::GfxPattern(int typeA) { + type = typeA; +} + +GfxPattern::~GfxPattern() { +} + +GfxPattern *GfxPattern::parse(Object *obj) { + GfxPattern *pattern; + Object obj1; + + if (obj->isDict()) { + obj->dictLookup("PatternType", &obj1); + } else if (obj->isStream()) { + obj->streamGetDict()->lookup("PatternType", &obj1); + } else { + return NULL; + } + pattern = NULL; + if (obj1.isInt() && obj1.getInt() == 1) { + pattern = GfxTilingPattern::parse(obj); + } else if (obj1.isInt() && obj1.getInt() == 2) { + pattern = GfxShadingPattern::parse(obj); + } + obj1.free(); + return pattern; +} + +//------------------------------------------------------------------------ +// GfxTilingPattern +//------------------------------------------------------------------------ + +GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) { + GfxTilingPattern *pat; + Dict *dict; + int paintTypeA, tilingTypeA; + double bboxA[4], matrixA[6]; + double xStepA, yStepA; + Object resDictA; + Object obj1, obj2; + int i; + + if (!patObj->isStream()) { + return NULL; + } + dict = patObj->streamGetDict(); + + if (dict->lookup("PaintType", &obj1)->isInt()) { + paintTypeA = obj1.getInt(); + } else { + paintTypeA = 1; + error(-1, "Invalid or missing PaintType in pattern"); + } + obj1.free(); + if (dict->lookup("TilingType", &obj1)->isInt()) { + tilingTypeA = obj1.getInt(); + } else { + tilingTypeA = 1; + error(-1, "Invalid or missing TilingType in pattern"); + } + obj1.free(); + bboxA[0] = bboxA[1] = 0; + bboxA[2] = bboxA[3] = 1; + if (dict->lookup("BBox", &obj1)->isArray() && + obj1.arrayGetLength() == 4) { + for (i = 0; i < 4; ++i) { + if (obj1.arrayGet(i, &obj2)->isNum()) { + bboxA[i] = obj2.getNum(); + } + obj2.free(); + } + } else { + error(-1, "Invalid or missing BBox in pattern"); + } + obj1.free(); + if (dict->lookup("XStep", &obj1)->isNum()) { + xStepA = obj1.getNum(); + } else { + xStepA = 1; + error(-1, "Invalid or missing XStep in pattern"); + } + obj1.free(); + if (dict->lookup("YStep", &obj1)->isNum()) { + yStepA = obj1.getNum(); + } else { + yStepA = 1; + error(-1, "Invalid or missing YStep in pattern"); + } + obj1.free(); + if (!dict->lookup("Resources", &resDictA)->isDict()) { + resDictA.free(); + resDictA.initNull(); + error(-1, "Invalid or missing Resources in pattern"); + } + matrixA[0] = 1; matrixA[1] = 0; + matrixA[2] = 0; matrixA[3] = 1; + matrixA[4] = 0; matrixA[5] = 0; + if (dict->lookup("Matrix", &obj1)->isArray() && + obj1.arrayGetLength() == 6) { + for (i = 0; i < 6; ++i) { + if (obj1.arrayGet(i, &obj2)->isNum()) { + matrixA[i] = obj2.getNum(); + } + obj2.free(); + } + } + obj1.free(); + + pat = new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA, + &resDictA, matrixA, patObj); + resDictA.free(); + return pat; +} + +GfxTilingPattern::GfxTilingPattern(int paintTypeA, int tilingTypeA, + double *bboxA, double xStepA, double yStepA, + Object *resDictA, double *matrixA, + Object *contentStreamA): + GfxPattern(1) +{ + int i; + + paintType = paintTypeA; + tilingType = tilingTypeA; + for (i = 0; i < 4; ++i) { + bbox[i] = bboxA[i]; + } + xStep = xStepA; + yStep = yStepA; + resDictA->copy(&resDict); + for (i = 0; i < 6; ++i) { + matrix[i] = matrixA[i]; + } + contentStreamA->copy(&contentStream); +} + +GfxTilingPattern::~GfxTilingPattern() { + resDict.free(); + contentStream.free(); +} + +GfxPattern *GfxTilingPattern::copy() { + return new GfxTilingPattern(paintType, tilingType, bbox, xStep, yStep, + &resDict, matrix, &contentStream); +} + +//------------------------------------------------------------------------ +// GfxShadingPattern +//------------------------------------------------------------------------ + +GfxShadingPattern *GfxShadingPattern::parse(Object *patObj) { + Dict *dict; + GfxShading *shadingA; + double matrixA[6]; + Object obj1, obj2; + int i; + + if (!patObj->isDict()) { + return NULL; + } + dict = patObj->getDict(); + + dict->lookup("Shading", &obj1); + shadingA = GfxShading::parse(&obj1); + obj1.free(); + if (!shadingA) { + return NULL; + } + + matrixA[0] = 1; matrixA[1] = 0; + matrixA[2] = 0; matrixA[3] = 1; + matrixA[4] = 0; matrixA[5] = 0; + if (dict->lookup("Matrix", &obj1)->isArray() && + obj1.arrayGetLength() == 6) { + for (i = 0; i < 6; ++i) { + if (obj1.arrayGet(i, &obj2)->isNum()) { + matrixA[i] = obj2.getNum(); + } + obj2.free(); + } + } + obj1.free(); + + return new GfxShadingPattern(shadingA, matrixA); +} + +GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA): + GfxPattern(2) +{ + int i; + + shading = shadingA; + for (i = 0; i < 6; ++i) { + matrix[i] = matrixA[i]; + } +} + +GfxShadingPattern::~GfxShadingPattern() { + delete shading; +} + +GfxPattern *GfxShadingPattern::copy() { + return new GfxShadingPattern(shading->copy(), matrix); +} + +//------------------------------------------------------------------------ +// GfxShading +//------------------------------------------------------------------------ + +GfxShading::GfxShading(int typeA) { + type = typeA; + colorSpace = NULL; +} + +GfxShading::GfxShading(GfxShading *shading) { + int i; + + type = shading->type; + colorSpace = shading->colorSpace->copy(); + for (i = 0; i < gfxColorMaxComps; ++i) { + background.c[i] = shading->background.c[i]; + } + hasBackground = shading->hasBackground; + xMin = shading->xMin; + yMin = shading->yMin; + xMax = shading->xMax; + yMax = shading->yMax; + hasBBox = shading->hasBBox; +} + +GfxShading::~GfxShading() { + if (colorSpace) { + delete colorSpace; + } +} + +GfxShading *GfxShading::parse(Object *obj) { + GfxShading *shading; + Dict *dict; + int typeA; + Object obj1; + + if (obj->isDict()) { + dict = obj->getDict(); + } else if (obj->isStream()) { + dict = obj->streamGetDict(); + } else { + return NULL; + } + + if (!dict->lookup("ShadingType", &obj1)->isInt()) { + error(-1, "Invalid ShadingType in shading dictionary"); + obj1.free(); + return NULL; + } + typeA = obj1.getInt(); + obj1.free(); + + switch (typeA) { + case 1: + shading = GfxFunctionShading::parse(dict); + break; + case 2: + shading = GfxAxialShading::parse(dict); + break; + case 3: + shading = GfxRadialShading::parse(dict); + break; + case 4: + if (obj->isStream()) { + shading = GfxGouraudTriangleShading::parse(4, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 4 shading object"); + goto err1; + } + break; + case 5: + if (obj->isStream()) { + shading = GfxGouraudTriangleShading::parse(5, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 5 shading object"); + goto err1; + } + break; + case 6: + if (obj->isStream()) { + shading = GfxPatchMeshShading::parse(6, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 6 shading object"); + goto err1; + } + break; + case 7: + if (obj->isStream()) { + shading = GfxPatchMeshShading::parse(7, dict, obj->getStream()); + } else { + error(-1, "Invalid Type 7 shading object"); + goto err1; + } + break; + default: + error(-1, "Unimplemented shading type %d", typeA); + goto err1; + } + + return shading; + + err1: + return NULL; +} + +GBool GfxShading::init(Dict *dict) { + Object obj1, obj2; + int i; + + dict->lookup("ColorSpace", &obj1); + if (!(colorSpace = GfxColorSpace::parse(&obj1))) { + error(-1, "Bad color space in shading dictionary"); + obj1.free(); + return gFalse; + } + obj1.free(); + + for (i = 0; i < gfxColorMaxComps; ++i) { + background.c[i] = 0; + } + hasBackground = gFalse; + if (dict->lookup("Background", &obj1)->isArray()) { + if (obj1.arrayGetLength() == colorSpace->getNComps()) { + hasBackground = gTrue; + for (i = 0; i < colorSpace->getNComps(); ++i) { + background.c[i] = dblToCol(obj1.arrayGet(i, &obj2)->getNum()); + obj2.free(); + } + } else { + error(-1, "Bad Background in shading dictionary"); + } + } + obj1.free(); + + xMin = yMin = xMax = yMax = 0; + hasBBox = gFalse; + if (dict->lookup("BBox", &obj1)->isArray()) { + if (obj1.arrayGetLength() == 4) { + hasBBox = gTrue; + xMin = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + yMin = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + xMax = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + yMax = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + } else { + error(-1, "Bad BBox in shading dictionary"); + } + } + obj1.free(); + + return gTrue; +} + +//------------------------------------------------------------------------ +// GfxFunctionShading +//------------------------------------------------------------------------ + +GfxFunctionShading::GfxFunctionShading(double x0A, double y0A, + double x1A, double y1A, + double *matrixA, + Function **funcsA, int nFuncsA): + GfxShading(1) +{ + int i; + + x0 = x0A; + y0 = y0A; + x1 = x1A; + y1 = y1A; + for (i = 0; i < 6; ++i) { + matrix[i] = matrixA[i]; + } + nFuncs = nFuncsA; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = funcsA[i]; + } +} + +GfxFunctionShading::GfxFunctionShading(GfxFunctionShading *shading): + GfxShading(shading) +{ + int i; + + x0 = shading->x0; + y0 = shading->y0; + x1 = shading->x1; + y1 = shading->y1; + for (i = 0; i < 6; ++i) { + matrix[i] = shading->matrix[i]; + } + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } +} + +GfxFunctionShading::~GfxFunctionShading() { + int i; + + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; + } +} + +GfxFunctionShading *GfxFunctionShading::parse(Dict *dict) { + GfxFunctionShading *shading; + double x0A, y0A, x1A, y1A; + double matrixA[6]; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + Object obj1, obj2; + int i; + + x0A = y0A = 0; + x1A = y1A = 1; + if (dict->lookup("Domain", &obj1)->isArray() && + obj1.arrayGetLength() == 4) { + x0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + y0A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + x1A = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + y1A = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + } + obj1.free(); + + matrixA[0] = 1; matrixA[1] = 0; + matrixA[2] = 0; matrixA[3] = 1; + matrixA[4] = 0; matrixA[5] = 0; + if (dict->lookup("Matrix", &obj1)->isArray() && + obj1.arrayGetLength() == 6) { + matrixA[0] = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + matrixA[1] = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + matrixA[2] = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + matrixA[3] = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + matrixA[4] = obj1.arrayGet(4, &obj2)->getNum(); + obj2.free(); + matrixA[5] = obj1.arrayGet(5, &obj2)->getNum(); + obj2.free(); + } + obj1.free(); + + dict->lookup("Function", &obj1); + if (obj1.isArray()) { + nFuncsA = obj1.arrayGetLength(); + if (nFuncsA > gfxColorMaxComps) { + error(-1, "Invalid Function array in shading dictionary"); + goto err1; + } + for (i = 0; i < nFuncsA; ++i) { + obj1.arrayGet(i, &obj2); + if (!(funcsA[i] = Function::parse(&obj2))) { + goto err2; + } + obj2.free(); + } + } else { + nFuncsA = 1; + if (!(funcsA[0] = Function::parse(&obj1))) { + goto err1; + } + } + obj1.free(); + + shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA, + funcsA, nFuncsA); + if (!shading->init(dict)) { + delete shading; + return NULL; + } + return shading; + + err2: + obj2.free(); + err1: + obj1.free(); + return NULL; +} + +GfxShading *GfxFunctionShading::copy() { + return new GfxFunctionShading(this); +} + +void GfxFunctionShading::getColor(double x, double y, GfxColor *color) { + double in[2], out[gfxColorMaxComps]; + int i; + + // NB: there can be one function with n outputs or n functions with + // one output each (where n = number of color components) + for (i = 0; i < gfxColorMaxComps; ++i) { + out[i] = 0; + } + in[0] = x; + in[1] = y; + for (i = 0; i < nFuncs; ++i) { + funcs[i]->transform(in, &out[i]); + } + for (i = 0; i < gfxColorMaxComps; ++i) { + color->c[i] = dblToCol(out[i]); + } +} + +//------------------------------------------------------------------------ +// GfxAxialShading +//------------------------------------------------------------------------ + +GfxAxialShading::GfxAxialShading(double x0A, double y0A, + double x1A, double y1A, + double t0A, double t1A, + Function **funcsA, int nFuncsA, + GBool extend0A, GBool extend1A): + GfxShading(2) +{ + int i; + + x0 = x0A; + y0 = y0A; + x1 = x1A; + y1 = y1A; + t0 = t0A; + t1 = t1A; + nFuncs = nFuncsA; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = funcsA[i]; + } + extend0 = extend0A; + extend1 = extend1A; +} + +GfxAxialShading::GfxAxialShading(GfxAxialShading *shading): + GfxShading(shading) +{ + int i; + + x0 = shading->x0; + y0 = shading->y0; + x1 = shading->x1; + y1 = shading->y1; + t0 = shading->t0; + y1 = shading->t1; + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } + extend0 = shading->extend0; + extend1 = shading->extend1; +} + +GfxAxialShading::~GfxAxialShading() { + int i; + + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; + } +} + +GfxAxialShading *GfxAxialShading::parse(Dict *dict) { + GfxAxialShading *shading; + double x0A, y0A, x1A, y1A; + double t0A, t1A; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + GBool extend0A, extend1A; + Object obj1, obj2; + int i; + + x0A = y0A = x1A = y1A = 0; + if (dict->lookup("Coords", &obj1)->isArray() && + obj1.arrayGetLength() == 4) { + x0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + y0A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + x1A = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + y1A = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + } else { + error(-1, "Missing or invalid Coords in shading dictionary"); + goto err1; + } + obj1.free(); + + t0A = 0; + t1A = 1; + if (dict->lookup("Domain", &obj1)->isArray() && + obj1.arrayGetLength() == 2) { + t0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + t1A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + } + obj1.free(); + + dict->lookup("Function", &obj1); + if (obj1.isArray()) { + nFuncsA = obj1.arrayGetLength(); + if (nFuncsA > gfxColorMaxComps) { + error(-1, "Invalid Function array in shading dictionary"); + goto err1; + } + for (i = 0; i < nFuncsA; ++i) { + obj1.arrayGet(i, &obj2); + if (!(funcsA[i] = Function::parse(&obj2))) { + obj1.free(); + obj2.free(); + goto err1; + } + obj2.free(); + } + } else { + nFuncsA = 1; + if (!(funcsA[0] = Function::parse(&obj1))) { + obj1.free(); + goto err1; + } + } + obj1.free(); + + extend0A = extend1A = gFalse; + if (dict->lookup("Extend", &obj1)->isArray() && + obj1.arrayGetLength() == 2) { + extend0A = obj1.arrayGet(0, &obj2)->getBool(); + obj2.free(); + extend1A = obj1.arrayGet(1, &obj2)->getBool(); + obj2.free(); + } + obj1.free(); + + shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A, + funcsA, nFuncsA, extend0A, extend1A); + if (!shading->init(dict)) { + delete shading; + return NULL; + } + return shading; + + err1: + return NULL; +} + +GfxShading *GfxAxialShading::copy() { + return new GfxAxialShading(this); +} + +void GfxAxialShading::getColor(double t, GfxColor *color) { + double out[gfxColorMaxComps]; + int i; + + // NB: there can be one function with n outputs or n functions with + // one output each (where n = number of color components) + for (i = 0; i < gfxColorMaxComps; ++i) { + out[i] = 0; + } + for (i = 0; i < nFuncs; ++i) { + funcs[i]->transform(&t, &out[i]); + } + for (i = 0; i < gfxColorMaxComps; ++i) { + color->c[i] = dblToCol(out[i]); + } +} + +//------------------------------------------------------------------------ +// GfxRadialShading +//------------------------------------------------------------------------ + +GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A, + double x1A, double y1A, double r1A, + double t0A, double t1A, + Function **funcsA, int nFuncsA, + GBool extend0A, GBool extend1A): + GfxShading(3) +{ + int i; + + x0 = x0A; + y0 = y0A; + r0 = r0A; + x1 = x1A; + y1 = y1A; + r1 = r1A; + t0 = t0A; + t1 = t1A; + nFuncs = nFuncsA; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = funcsA[i]; + } + extend0 = extend0A; + extend1 = extend1A; +} + +GfxRadialShading::GfxRadialShading(GfxRadialShading *shading): + GfxShading(shading) +{ + int i; + + x0 = shading->x0; + y0 = shading->y0; + r0 = shading->r0; + x1 = shading->x1; + y1 = shading->y1; + r1 = shading->r1; + t0 = shading->t0; + y1 = shading->t1; + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } + extend0 = shading->extend0; + extend1 = shading->extend1; +} + +GfxRadialShading::~GfxRadialShading() { + int i; + + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; + } +} + +GfxRadialShading *GfxRadialShading::parse(Dict *dict) { + GfxRadialShading *shading; + double x0A, y0A, r0A, x1A, y1A, r1A; + double t0A, t1A; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + GBool extend0A, extend1A; + Object obj1, obj2; + int i; + + x0A = y0A = r0A = x1A = y1A = r1A = 0; + if (dict->lookup("Coords", &obj1)->isArray() && + obj1.arrayGetLength() == 6) { + x0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + y0A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + r0A = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + x1A = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + y1A = obj1.arrayGet(4, &obj2)->getNum(); + obj2.free(); + r1A = obj1.arrayGet(5, &obj2)->getNum(); + obj2.free(); + } else { + error(-1, "Missing or invalid Coords in shading dictionary"); + goto err1; + } + obj1.free(); + + t0A = 0; + t1A = 1; + if (dict->lookup("Domain", &obj1)->isArray() && + obj1.arrayGetLength() == 2) { + t0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + t1A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + } + obj1.free(); + + dict->lookup("Function", &obj1); + if (obj1.isArray()) { + nFuncsA = obj1.arrayGetLength(); + if (nFuncsA > gfxColorMaxComps) { + error(-1, "Invalid Function array in shading dictionary"); + goto err1; + } + for (i = 0; i < nFuncsA; ++i) { + obj1.arrayGet(i, &obj2); + if (!(funcsA[i] = Function::parse(&obj2))) { + obj1.free(); + obj2.free(); + goto err1; + } + obj2.free(); + } + } else { + nFuncsA = 1; + if (!(funcsA[0] = Function::parse(&obj1))) { + obj1.free(); + goto err1; + } + } + obj1.free(); + + extend0A = extend1A = gFalse; + if (dict->lookup("Extend", &obj1)->isArray() && + obj1.arrayGetLength() == 2) { + extend0A = obj1.arrayGet(0, &obj2)->getBool(); + obj2.free(); + extend1A = obj1.arrayGet(1, &obj2)->getBool(); + obj2.free(); + } + obj1.free(); + + shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A, + funcsA, nFuncsA, extend0A, extend1A); + if (!shading->init(dict)) { + delete shading; + return NULL; + } + return shading; + + err1: + return NULL; +} + +GfxShading *GfxRadialShading::copy() { + return new GfxRadialShading(this); +} + +void GfxRadialShading::getColor(double t, GfxColor *color) { + double out[gfxColorMaxComps]; + int i; + + // NB: there can be one function with n outputs or n functions with + // one output each (where n = number of color components) + for (i = 0; i < gfxColorMaxComps; ++i) { + out[i] = 0; + } + for (i = 0; i < nFuncs; ++i) { + funcs[i]->transform(&t, &out[i]); + } + for (i = 0; i < gfxColorMaxComps; ++i) { + color->c[i] = dblToCol(out[i]); + } +} + +//------------------------------------------------------------------------ +// GfxShadingBitBuf +//------------------------------------------------------------------------ + +class GfxShadingBitBuf { +public: + + GfxShadingBitBuf(Stream *strA); + ~GfxShadingBitBuf(); + GBool getBits(int n, Guint *val); + void flushBits(); + +private: + + Stream *str; + int bitBuf; + int nBits; +}; + +GfxShadingBitBuf::GfxShadingBitBuf(Stream *strA) { + str = strA; + str->reset(); + bitBuf = 0; + nBits = 0; +} + +GfxShadingBitBuf::~GfxShadingBitBuf() { + str->close(); +} + +GBool GfxShadingBitBuf::getBits(int n, Guint *val) { + int x; + + if (nBits >= n) { + x = (bitBuf >> (nBits - n)) & ((1 << n) - 1); + nBits -= n; + } else { + x = 0; + if (nBits > 0) { + x = bitBuf & ((1 << nBits) - 1); + n -= nBits; + nBits = 0; + } + while (n > 0) { + if ((bitBuf = str->getChar()) == EOF) { + nBits = 0; + return gFalse; + } + if (n >= 8) { + x = (x << 8) | bitBuf; + n -= 8; + } else { + x = (x << n) | (bitBuf >> (8 - n)); + nBits = 8 - n; + n = 0; + } + } + } + *val = x; + return gTrue; +} + +void GfxShadingBitBuf::flushBits() { + bitBuf = 0; + nBits = 0; +} + +//------------------------------------------------------------------------ +// GfxGouraudTriangleShading +//------------------------------------------------------------------------ + +GfxGouraudTriangleShading::GfxGouraudTriangleShading( + int typeA, + GfxGouraudVertex *verticesA, int nVerticesA, + int (*trianglesA)[3], int nTrianglesA, + Function **funcsA, int nFuncsA): + GfxShading(typeA) +{ + int i; + + vertices = verticesA; + nVertices = nVerticesA; + triangles = trianglesA; + nTriangles = nTrianglesA; + nFuncs = nFuncsA; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = funcsA[i]; + } +} + +GfxGouraudTriangleShading::GfxGouraudTriangleShading( + GfxGouraudTriangleShading *shading): + GfxShading(shading) +{ + int i; + + nVertices = shading->nVertices; + vertices = (GfxGouraudVertex *)gmallocn(nVertices, sizeof(GfxGouraudVertex)); + memcpy(vertices, shading->vertices, nVertices * sizeof(GfxGouraudVertex)); + nTriangles = shading->nTriangles; + triangles = (int (*)[3])gmallocn(nTriangles * 3, sizeof(int)); + memcpy(triangles, shading->triangles, nTriangles * 3 * sizeof(int)); + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } +} + +GfxGouraudTriangleShading::~GfxGouraudTriangleShading() { + int i; + + gfree(vertices); + gfree(triangles); + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; + } +} + +GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA, + Dict *dict, + Stream *str) { + GfxGouraudTriangleShading *shading; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + int coordBits, compBits, flagBits, vertsPerRow, nRows; + double xMin, xMax, yMin, yMax; + double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps]; + double xMul, yMul; + double cMul[gfxColorMaxComps]; + GfxGouraudVertex *verticesA; + int (*trianglesA)[3]; + int nComps, nVerticesA, nTrianglesA, vertSize, triSize; + Guint x, y, flag; + Guint c[gfxColorMaxComps]; + GfxShadingBitBuf *bitBuf; + Object obj1, obj2; + int i, j, k, state; + + if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) { + coordBits = obj1.getInt(); + } else { + error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary"); + goto err2; + } + obj1.free(); + if (dict->lookup("BitsPerComponent", &obj1)->isInt()) { + compBits = obj1.getInt(); + } else { + error(-1, "Missing or invalid BitsPerComponent in shading dictionary"); + goto err2; + } + obj1.free(); + flagBits = vertsPerRow = 0; // make gcc happy + if (typeA == 4) { + if (dict->lookup("BitsPerFlag", &obj1)->isInt()) { + flagBits = obj1.getInt(); + } else { + error(-1, "Missing or invalid BitsPerFlag in shading dictionary"); + goto err2; + } + obj1.free(); + } else { + if (dict->lookup("VerticesPerRow", &obj1)->isInt()) { + vertsPerRow = obj1.getInt(); + } else { + error(-1, "Missing or invalid VerticesPerRow in shading dictionary"); + goto err2; + } + obj1.free(); + } + if (dict->lookup("Decode", &obj1)->isArray() && + obj1.arrayGetLength() >= 6) { + xMin = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + xMax = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1); + yMin = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + yMax = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1); + for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) { + cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum(); + obj2.free(); + cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum(); + obj2.free(); + cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1); + } + nComps = i; + } else { + error(-1, "Missing or invalid Decode array in shading dictionary"); + goto err2; + } + obj1.free(); + + if (!dict->lookup("Function", &obj1)->isNull()) { + if (obj1.isArray()) { + nFuncsA = obj1.arrayGetLength(); + if (nFuncsA > gfxColorMaxComps) { + error(-1, "Invalid Function array in shading dictionary"); + goto err1; + } + for (i = 0; i < nFuncsA; ++i) { + obj1.arrayGet(i, &obj2); + if (!(funcsA[i] = Function::parse(&obj2))) { + obj1.free(); + obj2.free(); + goto err1; + } + obj2.free(); + } + } else { + nFuncsA = 1; + if (!(funcsA[0] = Function::parse(&obj1))) { + obj1.free(); + goto err1; + } + } + } else { + nFuncsA = 0; + } + obj1.free(); + + nVerticesA = nTrianglesA = 0; + verticesA = NULL; + trianglesA = NULL; + vertSize = triSize = 0; + state = 0; + flag = 0; // make gcc happy + bitBuf = new GfxShadingBitBuf(str); + while (1) { + if (typeA == 4) { + if (!bitBuf->getBits(flagBits, &flag)) { + break; + } + } + if (!bitBuf->getBits(coordBits, &x) || + !bitBuf->getBits(coordBits, &y)) { + break; + } + for (i = 0; i < nComps; ++i) { + if (!bitBuf->getBits(compBits, &c[i])) { + break; + } + } + if (i < nComps) { + break; + } + if (nVerticesA == vertSize) { + vertSize = (vertSize == 0) ? 16 : 2 * vertSize; + verticesA = (GfxGouraudVertex *) + greallocn(verticesA, vertSize, sizeof(GfxGouraudVertex)); + } + verticesA[nVerticesA].x = xMin + xMul * (double)x; + verticesA[nVerticesA].y = yMin + yMul * (double)y; + for (i = 0; i < nComps; ++i) { + verticesA[nVerticesA].color.c[i] = + dblToCol(cMin[i] + cMul[i] * (double)c[i]); + } + ++nVerticesA; + bitBuf->flushBits(); + if (typeA == 4) { + if (state == 0 || state == 1) { + ++state; + } else if (state == 2 || flag > 0) { + if (nTrianglesA == triSize) { + triSize = (triSize == 0) ? 16 : 2 * triSize; + trianglesA = (int (*)[3]) + greallocn(trianglesA, triSize * 3, sizeof(int)); + } + if (state == 2) { + trianglesA[nTrianglesA][0] = nVerticesA - 3; + trianglesA[nTrianglesA][1] = nVerticesA - 2; + trianglesA[nTrianglesA][2] = nVerticesA - 1; + ++state; + } else if (flag == 1) { + trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][1]; + trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2]; + trianglesA[nTrianglesA][2] = nVerticesA - 1; + } else { // flag == 2 + trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][0]; + trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2]; + trianglesA[nTrianglesA][2] = nVerticesA - 1; + } + ++nTrianglesA; + } else { // state == 3 && flag == 0 + state = 1; + } + } + } + delete bitBuf; + if (typeA == 5) { + nRows = nVerticesA / vertsPerRow; + nTrianglesA = (nRows - 1) * 2 * (vertsPerRow - 1); + trianglesA = (int (*)[3])gmallocn(nTrianglesA * 3, sizeof(int)); + k = 0; + for (i = 0; i < nRows - 1; ++i) { + for (j = 0; j < vertsPerRow - 1; ++j) { + trianglesA[k][0] = i * vertsPerRow + j; + trianglesA[k][1] = i * vertsPerRow + j+1; + trianglesA[k][2] = (i+1) * vertsPerRow + j; + ++k; + trianglesA[k][0] = i * vertsPerRow + j+1; + trianglesA[k][1] = (i+1) * vertsPerRow + j; + trianglesA[k][2] = (i+1) * vertsPerRow + j+1; + ++k; + } + } + } + + shading = new GfxGouraudTriangleShading(typeA, verticesA, nVerticesA, + trianglesA, nTrianglesA, + funcsA, nFuncsA); + if (!shading->init(dict)) { + delete shading; + return NULL; + } + return shading; + + err2: + obj1.free(); + err1: + return NULL; +} + +GfxShading *GfxGouraudTriangleShading::copy() { + return new GfxGouraudTriangleShading(this); +} + +void GfxGouraudTriangleShading::getTriangle( + int i, + double *x0, double *y0, GfxColor *color0, + double *x1, double *y1, GfxColor *color1, + double *x2, double *y2, GfxColor *color2) { + double in; + double out[gfxColorMaxComps]; + int v, j; + + v = triangles[i][0]; + *x0 = vertices[v].x; + *y0 = vertices[v].y; + if (nFuncs > 0) { + in = colToDbl(vertices[v].color.c[0]); + for (j = 0; j < nFuncs; ++j) { + funcs[j]->transform(&in, &out[j]); + } + for (j = 0; j < gfxColorMaxComps; ++j) { + color0->c[j] = dblToCol(out[j]); + } + } else { + *color0 = vertices[v].color; + } + v = triangles[i][1]; + *x1 = vertices[v].x; + *y1 = vertices[v].y; + if (nFuncs > 0) { + in = colToDbl(vertices[v].color.c[0]); + for (j = 0; j < nFuncs; ++j) { + funcs[j]->transform(&in, &out[j]); + } + for (j = 0; j < gfxColorMaxComps; ++j) { + color1->c[j] = dblToCol(out[j]); + } + } else { + *color1 = vertices[v].color; + } + v = triangles[i][2]; + *x2 = vertices[v].x; + *y2 = vertices[v].y; + if (nFuncs > 0) { + in = colToDbl(vertices[v].color.c[0]); + for (j = 0; j < nFuncs; ++j) { + funcs[j]->transform(&in, &out[j]); + } + for (j = 0; j < gfxColorMaxComps; ++j) { + color2->c[j] = dblToCol(out[j]); + } + } else { + *color2 = vertices[v].color; + } +} + +//------------------------------------------------------------------------ +// GfxPatchMeshShading +//------------------------------------------------------------------------ + +GfxPatchMeshShading::GfxPatchMeshShading(int typeA, + GfxPatch *patchesA, int nPatchesA, + Function **funcsA, int nFuncsA): + GfxShading(typeA) +{ + int i; + + patches = patchesA; + nPatches = nPatchesA; + nFuncs = nFuncsA; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = funcsA[i]; + } +} + +GfxPatchMeshShading::GfxPatchMeshShading(GfxPatchMeshShading *shading): + GfxShading(shading) +{ + int i; + + nPatches = shading->nPatches; + patches = (GfxPatch *)gmallocn(nPatches, sizeof(GfxPatch)); + memcpy(patches, shading->patches, nPatches * sizeof(GfxPatch)); + nFuncs = shading->nFuncs; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = shading->funcs[i]->copy(); + } +} + +GfxPatchMeshShading::~GfxPatchMeshShading() { + int i; + + gfree(patches); + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; + } +} + +GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict, + Stream *str) { + GfxPatchMeshShading *shading; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + int coordBits, compBits, flagBits; + double xMin, xMax, yMin, yMax; + double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps]; + double xMul, yMul; + double cMul[gfxColorMaxComps]; + GfxPatch *patchesA, *p; + int nComps, nPatchesA, patchesSize, nPts, nColors; + Guint flag; + double x[16], y[16]; + Guint xi, yi; + GfxColorComp c[4][gfxColorMaxComps]; + Guint ci[4]; + GfxShadingBitBuf *bitBuf; + Object obj1, obj2; + int i, j; + + if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) { + coordBits = obj1.getInt(); + } else { + error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary"); + goto err2; + } + obj1.free(); + if (dict->lookup("BitsPerComponent", &obj1)->isInt()) { + compBits = obj1.getInt(); + } else { + error(-1, "Missing or invalid BitsPerComponent in shading dictionary"); + goto err2; + } + obj1.free(); + if (dict->lookup("BitsPerFlag", &obj1)->isInt()) { + flagBits = obj1.getInt(); + } else { + error(-1, "Missing or invalid BitsPerFlag in shading dictionary"); + goto err2; + } + obj1.free(); + if (dict->lookup("Decode", &obj1)->isArray() && + obj1.arrayGetLength() >= 6) { + xMin = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + xMax = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1); + yMin = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + yMax = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1); + for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) { + cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum(); + obj2.free(); + cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum(); + obj2.free(); + cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1); + } + nComps = i; + } else { + error(-1, "Missing or invalid Decode array in shading dictionary"); + goto err2; + } + obj1.free(); + + if (!dict->lookup("Function", &obj1)->isNull()) { + if (obj1.isArray()) { + nFuncsA = obj1.arrayGetLength(); + if (nFuncsA > gfxColorMaxComps) { + error(-1, "Invalid Function array in shading dictionary"); + goto err1; + } + for (i = 0; i < nFuncsA; ++i) { + obj1.arrayGet(i, &obj2); + if (!(funcsA[i] = Function::parse(&obj2))) { + obj1.free(); + obj2.free(); + goto err1; + } + obj2.free(); + } + } else { + nFuncsA = 1; + if (!(funcsA[0] = Function::parse(&obj1))) { + obj1.free(); + goto err1; + } + } + } else { + nFuncsA = 0; + } + obj1.free(); + + nPatchesA = 0; + patchesA = NULL; + patchesSize = 0; + bitBuf = new GfxShadingBitBuf(str); + while (1) { + if (!bitBuf->getBits(flagBits, &flag)) { + break; + } + if (typeA == 6) { + switch (flag) { + case 0: nPts = 12; nColors = 4; break; + case 1: + case 2: + case 3: + default: nPts = 8; nColors = 2; break; + } + } else { + switch (flag) { + case 0: nPts = 16; nColors = 4; break; + case 1: + case 2: + case 3: + default: nPts = 12; nColors = 2; break; + } + } + for (i = 0; i < nPts; ++i) { + if (!bitBuf->getBits(coordBits, &xi) || + !bitBuf->getBits(coordBits, &yi)) { + break; + } + x[i] = xMin + xMul * (double)xi; + y[i] = yMin + yMul * (double)yi; + } + if (i < nPts) { + break; + } + for (i = 0; i < nColors; ++i) { + for (j = 0; j < nComps; ++j) { + if (!bitBuf->getBits(compBits, &ci[j])) { + break; + } + c[i][j] = dblToCol(cMin[j] + cMul[j] * (double)ci[j]); + } + if (j < nComps) { + break; + } + } + if (i < nColors) { + break; + } + if (nPatchesA == patchesSize) { + patchesSize = (patchesSize == 0) ? 16 : 2 * patchesSize; + patchesA = (GfxPatch *)greallocn(patchesA, + patchesSize, sizeof(GfxPatch)); + } + p = &patchesA[nPatchesA]; + if (typeA == 6) { + switch (flag) { + case 0: + p->x[0][0] = x[0]; + p->y[0][0] = y[0]; + p->x[0][1] = x[1]; + p->y[0][1] = y[1]; + p->x[0][2] = x[2]; + p->y[0][2] = y[2]; + p->x[0][3] = x[3]; + p->y[0][3] = y[3]; + p->x[1][3] = x[4]; + p->y[1][3] = y[4]; + p->x[2][3] = x[5]; + p->y[2][3] = y[5]; + p->x[3][3] = x[6]; + p->y[3][3] = y[6]; + p->x[3][2] = x[7]; + p->y[3][2] = y[7]; + p->x[3][1] = x[8]; + p->y[3][1] = y[8]; + p->x[3][0] = x[9]; + p->y[3][0] = y[9]; + p->x[2][0] = x[10]; + p->y[2][0] = y[10]; + p->x[1][0] = x[11]; + p->y[1][0] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = c[0][j]; + p->color[0][1].c[j] = c[1][j]; + p->color[1][1].c[j] = c[2][j]; + p->color[1][0].c[j] = c[3][j]; + } + break; + case 1: + p->x[0][0] = patchesA[nPatchesA-1].x[0][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[0][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[1][3]; + p->y[0][1] = patchesA[nPatchesA-1].y[1][3]; + p->x[0][2] = patchesA[nPatchesA-1].x[2][3]; + p->y[0][2] = patchesA[nPatchesA-1].y[2][3]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][3]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 2: + p->x[0][0] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[3][2]; + p->y[0][1] = patchesA[nPatchesA-1].y[3][2]; + p->x[0][2] = patchesA[nPatchesA-1].x[3][1]; + p->y[0][2] = patchesA[nPatchesA-1].y[3][1]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 3: + p->x[0][0] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][0]; + p->x[0][1] = patchesA[nPatchesA-1].x[2][0]; + p->y[0][1] = patchesA[nPatchesA-1].y[2][0]; + p->x[0][2] = patchesA[nPatchesA-1].x[1][0]; + p->y[0][2] = patchesA[nPatchesA-1].y[1][0]; + p->x[0][3] = patchesA[nPatchesA-1].x[0][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[0][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + for (j = 0; j < nComps; ++j) { + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + } + } else { + switch (flag) { + case 0: + p->x[0][0] = x[0]; + p->y[0][0] = y[0]; + p->x[0][1] = x[1]; + p->y[0][1] = y[1]; + p->x[0][2] = x[2]; + p->y[0][2] = y[2]; + p->x[0][3] = x[3]; + p->y[0][3] = y[3]; + p->x[1][3] = x[4]; + p->y[1][3] = y[4]; + p->x[2][3] = x[5]; + p->y[2][3] = y[5]; + p->x[3][3] = x[6]; + p->y[3][3] = y[6]; + p->x[3][2] = x[7]; + p->y[3][2] = y[7]; + p->x[3][1] = x[8]; + p->y[3][1] = y[8]; + p->x[3][0] = x[9]; + p->y[3][0] = y[9]; + p->x[2][0] = x[10]; + p->y[2][0] = y[10]; + p->x[1][0] = x[11]; + p->y[1][0] = y[11]; + p->x[1][1] = x[12]; + p->y[1][1] = y[12]; + p->x[1][2] = x[13]; + p->y[1][2] = y[13]; + p->x[2][2] = x[14]; + p->y[2][2] = y[14]; + p->x[2][1] = x[15]; + p->y[2][1] = y[15]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = c[0][j]; + p->color[0][1].c[j] = c[1][j]; + p->color[1][1].c[j] = c[2][j]; + p->color[1][0].c[j] = c[3][j]; + } + break; + case 1: + p->x[0][0] = patchesA[nPatchesA-1].x[0][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[0][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[1][3]; + p->y[0][1] = patchesA[nPatchesA-1].y[1][3]; + p->x[0][2] = patchesA[nPatchesA-1].x[2][3]; + p->y[0][2] = patchesA[nPatchesA-1].y[2][3]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][3]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + p->x[1][1] = x[8]; + p->y[1][1] = y[8]; + p->x[1][2] = x[9]; + p->y[1][2] = y[9]; + p->x[2][2] = x[10]; + p->y[2][2] = y[10]; + p->x[2][1] = x[11]; + p->y[2][1] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 2: + p->x[0][0] = patchesA[nPatchesA-1].x[3][3]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][3]; + p->x[0][1] = patchesA[nPatchesA-1].x[3][2]; + p->y[0][1] = patchesA[nPatchesA-1].y[3][2]; + p->x[0][2] = patchesA[nPatchesA-1].x[3][1]; + p->y[0][2] = patchesA[nPatchesA-1].y[3][1]; + p->x[0][3] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[3][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + p->x[1][1] = x[8]; + p->y[1][1] = y[8]; + p->x[1][2] = x[9]; + p->y[1][2] = y[9]; + p->x[2][2] = x[10]; + p->y[2][2] = y[10]; + p->x[2][1] = x[11]; + p->y[2][1] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + case 3: + p->x[0][0] = patchesA[nPatchesA-1].x[3][0]; + p->y[0][0] = patchesA[nPatchesA-1].y[3][0]; + p->x[0][1] = patchesA[nPatchesA-1].x[2][0]; + p->y[0][1] = patchesA[nPatchesA-1].y[2][0]; + p->x[0][2] = patchesA[nPatchesA-1].x[1][0]; + p->y[0][2] = patchesA[nPatchesA-1].y[1][0]; + p->x[0][3] = patchesA[nPatchesA-1].x[0][0]; + p->y[0][3] = patchesA[nPatchesA-1].y[0][0]; + p->x[1][3] = x[0]; + p->y[1][3] = y[0]; + p->x[2][3] = x[1]; + p->y[2][3] = y[1]; + p->x[3][3] = x[2]; + p->y[3][3] = y[2]; + p->x[3][2] = x[3]; + p->y[3][2] = y[3]; + p->x[3][1] = x[4]; + p->y[3][1] = y[4]; + p->x[3][0] = x[5]; + p->y[3][0] = y[5]; + p->x[2][0] = x[6]; + p->y[2][0] = y[6]; + p->x[1][0] = x[7]; + p->y[1][0] = y[7]; + p->x[1][1] = x[8]; + p->y[1][1] = y[8]; + p->x[1][2] = x[9]; + p->y[1][2] = y[9]; + p->x[2][2] = x[10]; + p->y[2][2] = y[10]; + p->x[2][1] = x[11]; + p->y[2][1] = y[11]; + for (j = 0; j < nComps; ++j) { + p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][0].c[j]; + p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j]; + p->color[1][1].c[j] = c[0][j]; + p->color[1][0].c[j] = c[1][j]; + } + break; + } + } + ++nPatchesA; + bitBuf->flushBits(); + } + delete bitBuf; + + if (typeA == 6) { + for (i = 0; i < nPatchesA; ++i) { + p = &patchesA[i]; + p->x[1][1] = (-4 * p->x[0][0] + +6 * (p->x[0][1] + p->x[1][0]) + -2 * (p->x[0][3] + p->x[3][0]) + +3 * (p->x[3][1] + p->x[1][3]) + - p->x[3][3]) / 9; + p->y[1][1] = (-4 * p->y[0][0] + +6 * (p->y[0][1] + p->y[1][0]) + -2 * (p->y[0][3] + p->y[3][0]) + +3 * (p->y[3][1] + p->y[1][3]) + - p->y[3][3]) / 9; + p->x[1][2] = (-4 * p->x[0][3] + +6 * (p->x[0][2] + p->x[1][3]) + -2 * (p->x[0][0] + p->x[3][3]) + +3 * (p->x[3][2] + p->x[1][0]) + - p->x[3][0]) / 9; + p->y[1][2] = (-4 * p->y[0][3] + +6 * (p->y[0][2] + p->y[1][3]) + -2 * (p->y[0][0] + p->y[3][3]) + +3 * (p->y[3][2] + p->y[1][0]) + - p->y[3][0]) / 9; + p->x[2][1] = (-4 * p->x[3][0] + +6 * (p->x[3][1] + p->x[2][0]) + -2 * (p->x[3][3] + p->x[0][0]) + +3 * (p->x[0][1] + p->x[2][3]) + - p->x[0][3]) / 9; + p->y[2][1] = (-4 * p->y[3][0] + +6 * (p->y[3][1] + p->y[2][0]) + -2 * (p->y[3][3] + p->y[0][0]) + +3 * (p->y[0][1] + p->y[2][3]) + - p->y[0][3]) / 9; + p->x[2][2] = (-4 * p->x[3][3] + +6 * (p->x[3][2] + p->x[2][3]) + -2 * (p->x[3][0] + p->x[0][3]) + +3 * (p->x[0][2] + p->x[2][0]) + - p->x[0][0]) / 9; + p->y[2][2] = (-4 * p->y[3][3] + +6 * (p->y[3][2] + p->y[2][3]) + -2 * (p->y[3][0] + p->y[0][3]) + +3 * (p->y[0][2] + p->y[2][0]) + - p->y[0][0]) / 9; + } + } + + shading = new GfxPatchMeshShading(typeA, patchesA, nPatchesA, + funcsA, nFuncsA); + if (!shading->init(dict)) { + delete shading; + return NULL; + } + return shading; + + err2: + obj1.free(); + err1: + return NULL; +} + +GfxShading *GfxPatchMeshShading::copy() { + return new GfxPatchMeshShading(this); +} + +//------------------------------------------------------------------------ +// GfxImageColorMap +//------------------------------------------------------------------------ + +GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, + GfxColorSpace *colorSpaceA) { + GfxIndexedColorSpace *indexedCS; + GfxSeparationColorSpace *sepCS; + int maxPixel, indexHigh; + Guchar *lookup2; + Function *sepFunc; + Object obj; + double x[gfxColorMaxComps]; + double y[gfxColorMaxComps]; + int i, j, k, byte; + double mapped; + + ok = gTrue; + + // bits per component and color space + bits = bitsA; + maxPixel = (1 << bits) - 1; + colorSpace = colorSpaceA; + + // get decode map + if (decode->isNull()) { + nComps = colorSpace->getNComps(); + colorSpace->getDefaultRanges(decodeLow, decodeRange, maxPixel); + } else if (decode->isArray()) { + nComps = decode->arrayGetLength() / 2; + if (nComps != colorSpace->getNComps()) { + goto err1; + } + for (i = 0; i < nComps; ++i) { + decode->arrayGet(2*i, &obj); + if (!obj.isNum()) { + goto err2; + } + decodeLow[i] = obj.getNum(); + obj.free(); + decode->arrayGet(2*i+1, &obj); + if (!obj.isNum()) { + goto err2; + } + decodeRange[i] = obj.getNum() - decodeLow[i]; + obj.free(); + } + } else { + goto err1; + } + + // Construct a lookup table -- this stores pre-computed decoded + // values for each component, i.e., the result of applying the + // decode mapping to each possible image pixel component value. + // + // Optimization: for Indexed and Separation color spaces (which have + // only one component), we store color values in the lookup table + // rather than component values. + for (k = 0; k < gfxColorMaxComps; ++k) { + lookup[k] = NULL; + } + colorSpace2 = NULL; + nComps2 = 0; + if (colorSpace->getMode() == csIndexed) { + // Note that indexHigh may not be the same as maxPixel -- + // Distiller will remove unused palette entries, resulting in + // indexHigh < maxPixel. + indexedCS = (GfxIndexedColorSpace *)colorSpace; + colorSpace2 = indexedCS->getBase(); + indexHigh = indexedCS->getIndexHigh(); + nComps2 = colorSpace2->getNComps(); + lookup2 = indexedCS->getLookup(); + colorSpace2->getDefaultRanges(x, y, indexHigh); + byte_lookup = (Guchar *)gmalloc ((maxPixel + 1) * nComps2); + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1, + sizeof(GfxColorComp)); + for (i = 0; i <= maxPixel; ++i) { + j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5); + if (j < 0) { + j = 0; + } else if (j > indexHigh) { + j = indexHigh; + } + + mapped = x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k]; + lookup[k][i] = dblToCol(mapped); + byte_lookup[i * nComps2 + k] = (Guchar) (mapped * 255); + } + } + } else if (colorSpace->getMode() == csSeparation) { + sepCS = (GfxSeparationColorSpace *)colorSpace; + colorSpace2 = sepCS->getAlt(); + nComps2 = colorSpace2->getNComps(); + sepFunc = sepCS->getFunc(); + byte_lookup = (Guchar *)gmallocn ((maxPixel + 1), nComps2); + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1, + sizeof(GfxColorComp)); + for (i = 0; i <= maxPixel; ++i) { + x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel; + sepFunc->transform(x, y); + lookup[k][i] = dblToCol(y[k]); + byte_lookup[i*nComps2 + k] = (Guchar) (y[k] * 255); + } + } + } else { + byte_lookup = (Guchar *)gmallocn ((maxPixel + 1), nComps); + for (k = 0; k < nComps; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1, + sizeof(GfxColorComp)); + for (i = 0; i <= maxPixel; ++i) { + mapped = decodeLow[k] + (i * decodeRange[k]) / maxPixel; + lookup[k][i] = dblToCol(mapped); + byte = (int) (mapped * 255.0 + 0.5); + if (byte < 0) + byte = 0; + else if (byte > 255) + byte = 255; + byte_lookup[i * nComps + k] = byte; + } + } + } + + return; + + err2: + obj.free(); + err1: + ok = gFalse; + for (k = 0; k < gfxColorMaxComps; ++k) { + lookup[k] = NULL; + } + byte_lookup = NULL; +} + +GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) { + int n, i, k; + + colorSpace = colorMap->colorSpace->copy(); + bits = colorMap->bits; + nComps = colorMap->nComps; + nComps2 = colorMap->nComps2; + colorSpace2 = NULL; + for (k = 0; k < gfxColorMaxComps; ++k) { + lookup[k] = NULL; + } + n = 1 << bits; + if (colorSpace->getMode() == csIndexed) { + colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase(); + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp)); + memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp)); + } + } else if (colorSpace->getMode() == csSeparation) { + colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt(); + for (k = 0; k < nComps2; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp)); + memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp)); + } + } else { + for (k = 0; k < nComps; ++k) { + lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp)); + memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp)); + } + } + for (i = 0; i < nComps; ++i) { + decodeLow[i] = colorMap->decodeLow[i]; + decodeRange[i] = colorMap->decodeRange[i]; + } + ok = gTrue; +} + +GfxImageColorMap::~GfxImageColorMap() { + int i; + + delete colorSpace; + for (i = 0; i < gfxColorMaxComps; ++i) { + gfree(lookup[i]); + } + gfree(byte_lookup); +} + +void GfxImageColorMap::getGray(Guchar *x, GfxGray *gray) { + GfxColor color; + int i; + + if (colorSpace2) { + for (i = 0; i < nComps2; ++i) { + color.c[i] = lookup[i][x[0]]; + } + colorSpace2->getGray(&color, gray); + } else { + for (i = 0; i < nComps; ++i) { + color.c[i] = lookup[i][x[i]]; + } + colorSpace->getGray(&color, gray); + } +} + +void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) { + GfxColor color; + int i; + + if (colorSpace2) { + for (i = 0; i < nComps2; ++i) { + color.c[i] = lookup[i][x[0]]; + } + colorSpace2->getRGB(&color, rgb); + } else { + for (i = 0; i < nComps; ++i) { + color.c[i] = lookup[i][x[i]]; + } + colorSpace->getRGB(&color, rgb); + } +} + +void GfxImageColorMap::getGrayLine(Guchar *in, Guchar *out, int length) { + int i, j; + Guchar *inp, *tmp_line; + + switch (colorSpace->getMode()) { + case csIndexed: + case csSeparation: + tmp_line = (Guchar *) gmalloc (length * nComps2); + for (i = 0; i < length; i++) { + for (j = 0; j < nComps2; j++) { + tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j]; + } + } + colorSpace2->getGrayLine(tmp_line, out, length); + gfree (tmp_line); + break; + + default: + inp = in; + for (j = 0; j < length; j++) + for (i = 0; i < nComps; i++) { + *inp = byte_lookup[*inp * nComps + i]; + inp++; + } + colorSpace->getGrayLine(in, out, length); + break; + } +} + +void GfxImageColorMap::getRGBLine(Guchar *in, unsigned int *out, int length) { + int i, j; + Guchar *inp, *tmp_line; + + switch (colorSpace->getMode()) { + case csIndexed: + case csSeparation: + tmp_line = (Guchar *) gmalloc (length * nComps2); + for (i = 0; i < length; i++) { + for (j = 0; j < nComps2; j++) { + tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j]; + } + } + colorSpace2->getRGBLine(tmp_line, out, length); + gfree (tmp_line); + break; + + default: + inp = in; + for (j = 0; j < length; j++) + for (i = 0; i < nComps; i++) { + *inp = byte_lookup[*inp * nComps + i]; + inp++; + } + colorSpace->getRGBLine(in, out, length); + break; + } + +} + +void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) { + GfxColor color; + int i; + + if (colorSpace2) { + for (i = 0; i < nComps2; ++i) { + color.c[i] = lookup[i][x[0]]; + } + colorSpace2->getCMYK(&color, cmyk); + } else { + for (i = 0; i < nComps; ++i) { + color.c[i] = lookup[i][x[i]]; + } + colorSpace->getCMYK(&color, cmyk); + } +} + +void GfxImageColorMap::getColor(Guchar *x, GfxColor *color) { + int maxPixel, i; + + maxPixel = (1 << bits) - 1; + for (i = 0; i < nComps; ++i) { + color->c[i] = dblToCol(decodeLow[i] + (x[i] * decodeRange[i]) / maxPixel); + } +} + +//------------------------------------------------------------------------ +// GfxSubpath and GfxPath +//------------------------------------------------------------------------ + +GfxSubpath::GfxSubpath(double x1, double y1) { + size = 16; + x = (double *)gmallocn(size, sizeof(double)); + y = (double *)gmallocn(size, sizeof(double)); + curve = (GBool *)gmallocn(size, sizeof(GBool)); + n = 1; + x[0] = x1; + y[0] = y1; + curve[0] = gFalse; + closed = gFalse; +} + +GfxSubpath::~GfxSubpath() { + gfree(x); + gfree(y); + gfree(curve); +} + +// Used for copy(). +GfxSubpath::GfxSubpath(GfxSubpath *subpath) { + size = subpath->size; + n = subpath->n; + x = (double *)gmallocn(size, sizeof(double)); + y = (double *)gmallocn(size, sizeof(double)); + curve = (GBool *)gmallocn(size, sizeof(GBool)); + memcpy(x, subpath->x, n * sizeof(double)); + memcpy(y, subpath->y, n * sizeof(double)); + memcpy(curve, subpath->curve, n * sizeof(GBool)); + closed = subpath->closed; +} + +void GfxSubpath::lineTo(double x1, double y1) { + if (n >= size) { + size += 16; + x = (double *)greallocn(x, size, sizeof(double)); + y = (double *)greallocn(y, size, sizeof(double)); + curve = (GBool *)greallocn(curve, size, sizeof(GBool)); + } + x[n] = x1; + y[n] = y1; + curve[n] = gFalse; + ++n; +} + +void GfxSubpath::curveTo(double x1, double y1, double x2, double y2, + double x3, double y3) { + if (n+3 > size) { + size += 16; + x = (double *)greallocn(x, size, sizeof(double)); + y = (double *)greallocn(y, size, sizeof(double)); + curve = (GBool *)greallocn(curve, size, sizeof(GBool)); + } + x[n] = x1; + y[n] = y1; + x[n+1] = x2; + y[n+1] = y2; + x[n+2] = x3; + y[n+2] = y3; + curve[n] = curve[n+1] = gTrue; + curve[n+2] = gFalse; + n += 3; +} + +void GfxSubpath::close() { + if (x[n-1] != x[0] || y[n-1] != y[0]) { + lineTo(x[0], y[0]); + } + closed = gTrue; +} + +void GfxSubpath::offset(double dx, double dy) { + int i; + + for (i = 0; i < n; ++i) { + x[i] += dx; + y[i] += dy; + } +} + +GfxPath::GfxPath() { + justMoved = gFalse; + size = 16; + n = 0; + firstX = firstY = 0; + subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *)); +} + +GfxPath::~GfxPath() { + int i; + + for (i = 0; i < n; ++i) + delete subpaths[i]; + gfree(subpaths); +} + +// Used for copy(). +GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1, + GfxSubpath **subpaths1, int n1, int size1) { + int i; + + justMoved = justMoved1; + firstX = firstX1; + firstY = firstY1; + size = size1; + n = n1; + subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *)); + for (i = 0; i < n; ++i) + subpaths[i] = subpaths1[i]->copy(); +} + +void GfxPath::moveTo(double x, double y) { + justMoved = gTrue; + firstX = x; + firstY = y; +} + +void GfxPath::lineTo(double x, double y) { + if (justMoved) { + if (n >= size) { + size += 16; + subpaths = (GfxSubpath **) + greallocn(subpaths, size, sizeof(GfxSubpath *)); + } + subpaths[n] = new GfxSubpath(firstX, firstY); + ++n; + justMoved = gFalse; + } + subpaths[n-1]->lineTo(x, y); +} + +void GfxPath::curveTo(double x1, double y1, double x2, double y2, + double x3, double y3) { + if (justMoved) { + if (n >= size) { + size += 16; + subpaths = (GfxSubpath **) + greallocn(subpaths, size, sizeof(GfxSubpath *)); + } + subpaths[n] = new GfxSubpath(firstX, firstY); + ++n; + justMoved = gFalse; + } + subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3); +} + +void GfxPath::close() { + // this is necessary to handle the pathological case of + // moveto/closepath/clip, which defines an empty clipping region + if (justMoved) { + if (n >= size) { + size += 16; + subpaths = (GfxSubpath **) + greallocn(subpaths, size, sizeof(GfxSubpath *)); + } + subpaths[n] = new GfxSubpath(firstX, firstY); + ++n; + justMoved = gFalse; + } + subpaths[n-1]->close(); +} + +void GfxPath::append(GfxPath *path) { + int i; + + if (n + path->n > size) { + size = n + path->n; + subpaths = (GfxSubpath **) + greallocn(subpaths, size, sizeof(GfxSubpath *)); + } + for (i = 0; i < path->n; ++i) { + subpaths[n++] = path->subpaths[i]->copy(); + } + justMoved = gFalse; +} + +void GfxPath::offset(double dx, double dy) { + int i; + + for (i = 0; i < n; ++i) { + subpaths[i]->offset(dx, dy); + } +} + +//------------------------------------------------------------------------ +// GfxState +//------------------------------------------------------------------------ + +GfxState::GfxState(double hDPI, double vDPI, PDFRectangle *pageBox, + int rotateA, GBool upsideDown) { + double kx, ky; + + rotate = rotateA; + px1 = pageBox->x1; + py1 = pageBox->y1; + px2 = pageBox->x2; + py2 = pageBox->y2; + kx = hDPI / 72.0; + ky = vDPI / 72.0; + if (rotate == 90) { + ctm[0] = 0; + ctm[1] = upsideDown ? ky : -ky; + ctm[2] = kx; + ctm[3] = 0; + ctm[4] = -kx * py1; + ctm[5] = ky * (upsideDown ? -px1 : px2); + pageWidth = kx * (py2 - py1); + pageHeight = ky * (px2 - px1); + } else if (rotate == 180) { + ctm[0] = -kx; + ctm[1] = 0; + ctm[2] = 0; + ctm[3] = upsideDown ? ky : -ky; + ctm[4] = kx * px2; + ctm[5] = ky * (upsideDown ? -py1 : py2); + pageWidth = kx * (px2 - px1); + pageHeight = ky * (py2 - py1); + } else if (rotate == 270) { + ctm[0] = 0; + ctm[1] = upsideDown ? -ky : ky; + ctm[2] = -kx; + ctm[3] = 0; + ctm[4] = kx * py2; + ctm[5] = ky * (upsideDown ? px2 : -px1); + pageWidth = kx * (py2 - py1); + pageHeight = ky * (px2 - px1); + } else { + ctm[0] = kx; + ctm[1] = 0; + ctm[2] = 0; + ctm[3] = upsideDown ? -ky : ky; + ctm[4] = -kx * px1; + ctm[5] = ky * (upsideDown ? py2 : -py1); + pageWidth = kx * (px2 - px1); + pageHeight = ky * (py2 - py1); + } + + fillColorSpace = new GfxDeviceGrayColorSpace(); + strokeColorSpace = new GfxDeviceGrayColorSpace(); + fillColor.c[0] = 0; + strokeColor.c[0] = 0; + fillPattern = NULL; + strokePattern = NULL; + blendMode = gfxBlendNormal; + fillOpacity = 1; + strokeOpacity = 1; + fillOverprint = gFalse; + strokeOverprint = gFalse; + + lineWidth = 1; + lineDash = NULL; + lineDashLength = 0; + lineDashStart = 0; + flatness = 1; + lineJoin = 0; + lineCap = 0; + miterLimit = 10; + + font = NULL; + fontSize = 0; + textMat[0] = 1; textMat[1] = 0; + textMat[2] = 0; textMat[3] = 1; + textMat[4] = 0; textMat[5] = 0; + charSpace = 0; + wordSpace = 0; + horizScaling = 1; + leading = 0; + rise = 0; + render = 0; + + path = new GfxPath(); + curX = curY = 0; + lineX = lineY = 0; + + clipXMin = 0; + clipYMin = 0; + clipXMax = pageWidth; + clipYMax = pageHeight; + + saved = NULL; +} + +GfxState::~GfxState() { + if (fillColorSpace) { + delete fillColorSpace; + } + if (strokeColorSpace) { + delete strokeColorSpace; + } + if (fillPattern) { + delete fillPattern; + } + if (strokePattern) { + delete strokePattern; + } + gfree(lineDash); + if (path) { + // this gets set to NULL by restore() + delete path; + } + if (saved) { + delete saved; + } + if (font) { + font->decRefCnt(); + } +} + +// Used for copy(); +GfxState::GfxState(GfxState *state) { + memcpy(this, state, sizeof(GfxState)); + if (fillColorSpace) { + fillColorSpace = state->fillColorSpace->copy(); + } + if (strokeColorSpace) { + strokeColorSpace = state->strokeColorSpace->copy(); + } + if (fillPattern) { + fillPattern = state->fillPattern->copy(); + } + if (strokePattern) { + strokePattern = state->strokePattern->copy(); + } + if (lineDashLength > 0) { + lineDash = (double *)gmallocn(lineDashLength, sizeof(double)); + memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double)); + } + if (font) + font->incRefCnt(); + + saved = NULL; +} + +void GfxState::setPath(GfxPath *pathA) { + delete path; + path = pathA; +} + +void GfxState::getUserClipBBox(double *xMin, double *yMin, + double *xMax, double *yMax) { + double ictm[6]; + double xMin1, yMin1, xMax1, yMax1, det, tx, ty; + + // invert the CTM + det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + ictm[0] = ctm[3] * det; + ictm[1] = -ctm[1] * det; + ictm[2] = -ctm[2] * det; + ictm[3] = ctm[0] * det; + ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; + ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; + + // transform all four corners of the clip bbox; find the min and max + // x and y values + xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4]; + yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5]; + tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4]; + ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5]; + if (tx < xMin1) { + xMin1 = tx; + } else if (tx > xMax1) { + xMax1 = tx; + } + if (ty < yMin1) { + yMin1 = ty; + } else if (ty > yMax1) { + yMax1 = ty; + } + tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4]; + ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5]; + if (tx < xMin1) { + xMin1 = tx; + } else if (tx > xMax1) { + xMax1 = tx; + } + if (ty < yMin1) { + yMin1 = ty; + } else if (ty > yMax1) { + yMax1 = ty; + } + tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4]; + ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5]; + if (tx < xMin1) { + xMin1 = tx; + } else if (tx > xMax1) { + xMax1 = tx; + } + if (ty < yMin1) { + yMin1 = ty; + } else if (ty > yMax1) { + yMax1 = ty; + } + + *xMin = xMin1; + *yMin = yMin1; + *xMax = xMax1; + *yMax = yMax1; +} + +double GfxState::transformWidth(double w) { + double x, y; + + x = ctm[0] + ctm[2]; + y = ctm[1] + ctm[3]; + return w * sqrt(0.5 * (x * x + y * y)); +} + +double GfxState::getTransformedFontSize() { + double x1, y1, x2, y2; + + x1 = textMat[2] * fontSize; + y1 = textMat[3] * fontSize; + x2 = ctm[0] * x1 + ctm[2] * y1; + y2 = ctm[1] * x1 + ctm[3] * y1; + return sqrt(x2 * x2 + y2 * y2); +} + +void GfxState::getFontTransMat(double *m11, double *m12, + double *m21, double *m22) { + *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize; + *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize; + *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize; + *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize; +} + +void GfxState::setCTM(double a, double b, double c, + double d, double e, double f) { + int i; + + ctm[0] = a; + ctm[1] = b; + ctm[2] = c; + ctm[3] = d; + ctm[4] = e; + ctm[5] = f; + + // avoid FP exceptions on badly messed up PDF files + for (i = 0; i < 6; ++i) { + if (ctm[i] > 1e10) { + ctm[i] = 1e10; + } else if (ctm[i] < -1e10) { + ctm[i] = -1e10; + } + } +} + +void GfxState::concatCTM(double a, double b, double c, + double d, double e, double f) { + double a1 = ctm[0]; + double b1 = ctm[1]; + double c1 = ctm[2]; + double d1 = ctm[3]; + int i; + + ctm[0] = a * a1 + b * c1; + ctm[1] = a * b1 + b * d1; + ctm[2] = c * a1 + d * c1; + ctm[3] = c * b1 + d * d1; + ctm[4] = e * a1 + f * c1 + ctm[4]; + ctm[5] = e * b1 + f * d1 + ctm[5]; + + // avoid FP exceptions on badly messed up PDF files + for (i = 0; i < 6; ++i) { + if (ctm[i] > 1e10) { + ctm[i] = 1e10; + } else if (ctm[i] < -1e10) { + ctm[i] = -1e10; + } + } +} + +void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { + if (fillColorSpace) { + delete fillColorSpace; + } + fillColorSpace = colorSpace; +} + +void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) { + if (strokeColorSpace) { + delete strokeColorSpace; + } + strokeColorSpace = colorSpace; +} + +void GfxState::setFillPattern(GfxPattern *pattern) { + if (fillPattern) { + delete fillPattern; + } + fillPattern = pattern; +} + +void GfxState::setStrokePattern(GfxPattern *pattern) { + if (strokePattern) { + delete strokePattern; + } + strokePattern = pattern; +} + +void GfxState::setFont(GfxFont *fontA, double fontSizeA) { + if (font) + font->decRefCnt(); + + font = fontA; + fontSize = fontSizeA; +} + +void GfxState::setLineDash(double *dash, int length, double start) { + if (lineDash) + gfree(lineDash); + lineDash = dash; + lineDashLength = length; + lineDashStart = start; +} + +void GfxState::clearPath() { + delete path; + path = new GfxPath(); +} + +void GfxState::clip() { + double xMin, yMin, xMax, yMax, x, y; + GfxSubpath *subpath; + int i, j; + + xMin = xMax = yMin = yMax = 0; // make gcc happy + for (i = 0; i < path->getNumSubpaths(); ++i) { + subpath = path->getSubpath(i); + for (j = 0; j < subpath->getNumPoints(); ++j) { + transform(subpath->getX(j), subpath->getY(j), &x, &y); + if (i == 0 && j == 0) { + xMin = xMax = x; + yMin = yMax = y; + } else { + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + } + } + } + if (xMin > clipXMin) { + clipXMin = xMin; + } + if (yMin > clipYMin) { + clipYMin = yMin; + } + if (xMax < clipXMax) { + clipXMax = xMax; + } + if (yMax < clipYMax) { + clipYMax = yMax; + } +} + +void GfxState::textShift(double tx, double ty) { + double dx, dy; + + textTransformDelta(tx, ty, &dx, &dy); + curX += dx; + curY += dy; +} + +void GfxState::shift(double dx, double dy) { + curX += dx; + curY += dy; +} + +GfxState *GfxState::save() { + GfxState *newState; + + newState = copy(); + newState->saved = this; + return newState; +} + +GfxState *GfxState::restore() { + GfxState *oldState; + + if (saved) { + oldState = saved; + + // these attributes aren't saved/restored by the q/Q operators + oldState->path = path; + oldState->curX = curX; + oldState->curY = curY; + oldState->lineX = lineX; + oldState->lineY = lineY; + + path = NULL; + saved = NULL; + delete this; + + } else { + oldState = this; + } + + return oldState; +} + +GBool GfxState::parseBlendMode(Object *obj, GfxBlendMode *mode) { + Object obj2; + int i, j; + + if (obj->isName()) { + for (i = 0; i < nGfxBlendModeNames; ++i) { + if (!strcmp(obj->getNameC(), gfxBlendModeNames[i].name)) { + *mode = gfxBlendModeNames[i].mode; + return gTrue; + } + } + return gFalse; + } else if (obj->isArray()) { + for (i = 0; i < obj->arrayGetLength(); ++i) { + obj->arrayGet(i, &obj2); + if (!obj2.isName()) { + obj2.free(); + return gFalse; + } + for (j = 0; j < nGfxBlendModeNames; ++j) { + if (!strcmp(obj2.getNameC(), gfxBlendModeNames[j].name)) { + obj2.free(); + *mode = gfxBlendModeNames[j].mode; + return gTrue; + } + } + obj2.free(); + } + *mode = gfxBlendNormal; + return gTrue; + } else { + return gFalse; + } +} diff --git a/rosapps/smartpdf/poppler/poppler/GfxState.h b/rosapps/smartpdf/poppler/poppler/GfxState.h new file mode 100644 index 00000000000..4a436301da4 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/GfxState.h @@ -0,0 +1,1228 @@ +//======================================================================== +// +// GfxState.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GFXSTATE_H +#define GFXSTATE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "Object.h" +#include "Function.h" + +class Array; +class GfxFont; +class PDFRectangle; +class GfxShading; + +class Matrix { +public: + double m[6]; + + GBool invertTo(Matrix *other); + void transform(double x, double y, double *tx, double *ty); +}; + +//------------------------------------------------------------------------ +// GfxBlendMode +//------------------------------------------------------------------------ + +enum GfxBlendMode { + gfxBlendNormal, + gfxBlendMultiply, + gfxBlendScreen, + gfxBlendOverlay, + gfxBlendDarken, + gfxBlendLighten, + gfxBlendColorDodge, + gfxBlendColorBurn, + gfxBlendHardLight, + gfxBlendSoftLight, + gfxBlendDifference, + gfxBlendExclusion, + gfxBlendHue, + gfxBlendSaturation, + gfxBlendColor, + gfxBlendLuminosity +}; + +//------------------------------------------------------------------------ +// GfxColorComp +//------------------------------------------------------------------------ + +// 16.16 fixed point color component +typedef int GfxColorComp; + +#define gfxColorComp1 0x10000 + +static inline GfxColorComp dblToCol(double x) { + return (GfxColorComp)(x * gfxColorComp1); +} + +static inline double colToDbl(GfxColorComp x) { + return (double)x / (double)gfxColorComp1; +} + +static inline GfxColorComp byteToCol(Guchar x) { + // (x / 255) << 16 = (0.0000000100000001... * x) << 16 + // = ((x << 8) + (x) + (x >> 8) + ...) << 16 + // = (x << 8) + (x) + (x >> 7) + // [for rounding] + return (GfxColorComp)((x << 8) + x + (x >> 7)); +} + +static inline Guchar colToByte(GfxColorComp x) { + // 255 * x + 0.5 = 256 * x - x + 0x8000 + return (Guchar)(((x << 8) - x + 0x8000) >> 16); +} + +//------------------------------------------------------------------------ +// GfxColor +//------------------------------------------------------------------------ + +#define gfxColorMaxComps funcMaxOutputs + +struct GfxColor { + GfxColorComp c[gfxColorMaxComps]; +}; + +//------------------------------------------------------------------------ +// GfxGray +//------------------------------------------------------------------------ + +typedef GfxColorComp GfxGray; + +//------------------------------------------------------------------------ +// GfxRGB +//------------------------------------------------------------------------ + +struct GfxRGB { + GfxColorComp r, g, b; +}; + +//------------------------------------------------------------------------ +// GfxCMYK +//------------------------------------------------------------------------ + +struct GfxCMYK { + GfxColorComp c, m, y, k; +}; + +//------------------------------------------------------------------------ +// GfxColorSpace +//------------------------------------------------------------------------ + +// NB: The nGfxColorSpaceModes constant and the gfxColorSpaceModeNames +// array defined in GfxState.cc must match this enum. +enum GfxColorSpaceMode { + csDeviceGray, + csCalGray, + csDeviceRGB, + csCalRGB, + csDeviceCMYK, + csLab, + csICCBased, + csIndexed, + csSeparation, + csDeviceN, + csPattern +}; + +class GfxColorSpace { +public: + + GfxColorSpace(); + virtual ~GfxColorSpace(); + virtual GfxColorSpace *copy() = 0; + virtual GfxColorSpaceMode getMode() = 0; + + // Construct a color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Object *csObj); + + // Convert to gray, RGB, or CMYK. + virtual void getGray(GfxColor *color, GfxGray *gray) = 0; + virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0; + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0; + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + + // Return the number of color components. + virtual int getNComps() = 0; + + // Return the default ranges for each component, assuming an image + // with a max pixel value of . + virtual void getDefaultRanges(double *decodeLow, double *decodeRange, + int maxImgPixel); + + // Return the number of color space modes + static int getNumColorSpaceModes(); + + // Return the name of the th color space mode. + static char *getColorSpaceModeName(int idx); + +private: +}; + +//------------------------------------------------------------------------ +// GfxDeviceGrayColorSpace +//------------------------------------------------------------------------ + +class GfxDeviceGrayColorSpace: public GfxColorSpace { +public: + + GfxDeviceGrayColorSpace(); + virtual ~GfxDeviceGrayColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csDeviceGray; } + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + + virtual int getNComps() { return 1; } + +private: +}; + +//------------------------------------------------------------------------ +// GfxCalGrayColorSpace +//------------------------------------------------------------------------ + +class GfxCalGrayColorSpace: public GfxColorSpace { +public: + + GfxCalGrayColorSpace(); + virtual ~GfxCalGrayColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csCalGray; } + + // Construct a CalGray color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + + virtual int getNComps() { return 1; } + + // CalGray-specific access. + double getWhiteX() { return whiteX; } + double getWhiteY() { return whiteY; } + double getWhiteZ() { return whiteZ; } + double getBlackX() { return blackX; } + double getBlackY() { return blackY; } + double getBlackZ() { return blackZ; } + double getGamma() { return gamma; } + +private: + + double whiteX, whiteY, whiteZ; // white point + double blackX, blackY, blackZ; // black point + double gamma; // gamma value +}; + +//------------------------------------------------------------------------ +// GfxDeviceRGBColorSpace +//------------------------------------------------------------------------ + +class GfxDeviceRGBColorSpace: public GfxColorSpace { +public: + + GfxDeviceRGBColorSpace(); + virtual ~GfxDeviceRGBColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csDeviceRGB; } + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + + virtual int getNComps() { return 3; } + +private: +}; + +//------------------------------------------------------------------------ +// GfxCalRGBColorSpace +//------------------------------------------------------------------------ + +class GfxCalRGBColorSpace: public GfxColorSpace { +public: + + GfxCalRGBColorSpace(); + virtual ~GfxCalRGBColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csCalRGB; } + + // Construct a CalRGB color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + + virtual int getNComps() { return 3; } + + // CalRGB-specific access. + double getWhiteX() { return whiteX; } + double getWhiteY() { return whiteY; } + double getWhiteZ() { return whiteZ; } + double getBlackX() { return blackX; } + double getBlackY() { return blackY; } + double getBlackZ() { return blackZ; } + double getGammaR() { return gammaR; } + double getGammaG() { return gammaG; } + double getGammaB() { return gammaB; } + double *getMatrix() { return mat; } + +private: + + double whiteX, whiteY, whiteZ; // white point + double blackX, blackY, blackZ; // black point + double gammaR, gammaG, gammaB; // gamma values + double mat[9]; // ABC -> XYZ transform matrix +}; + +//------------------------------------------------------------------------ +// GfxDeviceCMYKColorSpace +//------------------------------------------------------------------------ + +class GfxDeviceCMYKColorSpace: public GfxColorSpace { +public: + + GfxDeviceCMYKColorSpace(); + virtual ~GfxDeviceCMYKColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csDeviceCMYK; } + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + + virtual int getNComps() { return 4; } + +private: +}; + +//------------------------------------------------------------------------ +// GfxLabColorSpace +//------------------------------------------------------------------------ + +class GfxLabColorSpace: public GfxColorSpace { +public: + + GfxLabColorSpace(); + virtual ~GfxLabColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csLab; } + + // Construct a Lab color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + + virtual int getNComps() { return 3; } + + virtual void getDefaultRanges(double *decodeLow, double *decodeRange, + int maxImgPixel); + + // Lab-specific access. + double getWhiteX() { return whiteX; } + double getWhiteY() { return whiteY; } + double getWhiteZ() { return whiteZ; } + double getBlackX() { return blackX; } + double getBlackY() { return blackY; } + double getBlackZ() { return blackZ; } + double getAMin() { return aMin; } + double getAMax() { return aMax; } + double getBMin() { return bMin; } + double getBMax() { return bMax; } + +private: + + double whiteX, whiteY, whiteZ; // white point + double blackX, blackY, blackZ; // black point + double aMin, aMax, bMin, bMax; // range for the a and b components + double kr, kg, kb; // gamut mapping mulitpliers +}; + +//------------------------------------------------------------------------ +// GfxICCBasedColorSpace +//------------------------------------------------------------------------ + +class GfxICCBasedColorSpace: public GfxColorSpace { +public: + + GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA, + Ref *iccProfileStreamA); + virtual ~GfxICCBasedColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csICCBased; } + + // Construct an ICCBased color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + virtual int getNComps() { return nComps; } + + virtual void getDefaultRanges(double *decodeLow, double *decodeRange, + int maxImgPixel); + + // ICCBased-specific access. + GfxColorSpace *getAlt() { return alt; } + +private: + + int nComps; // number of color components (1, 3, or 4) + GfxColorSpace *alt; // alternate color space + double rangeMin[4]; // min values for each component + double rangeMax[4]; // max values for each component + Ref iccProfileStream; // the ICC profile +}; + +//------------------------------------------------------------------------ +// GfxIndexedColorSpace +//------------------------------------------------------------------------ + +class GfxIndexedColorSpace: public GfxColorSpace { +public: + + GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA); + virtual ~GfxIndexedColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csIndexed; } + + // Construct a Lab color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + + virtual int getNComps() { return 1; } + + virtual void getDefaultRanges(double *decodeLow, double *decodeRange, + int maxImgPixel); + + // Indexed-specific access. + GfxColorSpace *getBase() { return base; } + int getIndexHigh() { return indexHigh; } + Guchar *getLookup() { return lookup; } + GfxColor *mapColorToBase(GfxColor *color, GfxColor *baseColor); + +private: + + GfxColorSpace *base; // base color space + int indexHigh; // max pixel value + Guchar *lookup; // lookup table +}; + +//------------------------------------------------------------------------ +// GfxSeparationColorSpace +//------------------------------------------------------------------------ + +class GfxSeparationColorSpace: public GfxColorSpace { +public: + + GfxSeparationColorSpace(GooString *nameA, GfxColorSpace *altA, + Function *funcA); + virtual ~GfxSeparationColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csSeparation; } + + // Construct a Separation color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + + virtual int getNComps() { return 1; } + + // Separation-specific access. + GooString *getName() { return name; } + GfxColorSpace *getAlt() { return alt; } + Function *getFunc() { return func; } + +private: + + GooString *name; // colorant name + GfxColorSpace *alt; // alternate color space + Function *func; // tint transform (into alternate color space) +}; + +//------------------------------------------------------------------------ +// GfxDeviceNColorSpace +//------------------------------------------------------------------------ + +class GfxDeviceNColorSpace: public GfxColorSpace { +public: + + GfxDeviceNColorSpace(int nCompsA, GfxColorSpace *alt, Function *func); + virtual ~GfxDeviceNColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csDeviceN; } + + // Construct a DeviceN color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + + virtual int getNComps() { return nComps; } + + // DeviceN-specific access. + GooString *getColorantName(int i) { return names[i]; } + GfxColorSpace *getAlt() { return alt; } + Function *getTintTransformFunc() { return func; } + +private: + + int nComps; // number of components + GooString // colorant names + *names[gfxColorMaxComps]; + GfxColorSpace *alt; // alternate color space + Function *func; // tint transform (into alternate color space) +}; + +//------------------------------------------------------------------------ +// GfxPatternColorSpace +//------------------------------------------------------------------------ + +class GfxPatternColorSpace: public GfxColorSpace { +public: + + GfxPatternColorSpace(GfxColorSpace *underA); + virtual ~GfxPatternColorSpace(); + virtual GfxColorSpace *copy(); + virtual GfxColorSpaceMode getMode() { return csPattern; } + + // Construct a Pattern color space. Returns NULL if unsuccessful. + static GfxColorSpace *parse(Array *arr); + + virtual void getGray(GfxColor *color, GfxGray *gray); + virtual void getRGB(GfxColor *color, GfxRGB *rgb); + virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + + virtual int getNComps() { return 0; } + + // Pattern-specific access. + GfxColorSpace *getUnder() { return under; } + +private: + + GfxColorSpace *under; // underlying color space (for uncolored + // patterns) +}; + +//------------------------------------------------------------------------ +// GfxPattern +//------------------------------------------------------------------------ + +class GfxPattern { +public: + + GfxPattern(int typeA); + virtual ~GfxPattern(); + + static GfxPattern *parse(Object *obj); + + virtual GfxPattern *copy() = 0; + + int getType() { return type; } + +private: + + int type; +}; + +//------------------------------------------------------------------------ +// GfxTilingPattern +//------------------------------------------------------------------------ + +class GfxTilingPattern: public GfxPattern { +public: + + static GfxTilingPattern *parse(Object *patObj); + virtual ~GfxTilingPattern(); + + virtual GfxPattern *copy(); + + int getPaintType() { return paintType; } + int getTilingType() { return tilingType; } + double *getBBox() { return bbox; } + double getXStep() { return xStep; } + double getYStep() { return yStep; } + Dict *getResDict() + { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; } + double *getMatrix() { return matrix; } + Object *getContentStream() { return &contentStream; } + +private: + + GfxTilingPattern(int paintTypeA, int tilingTypeA, + double *bboxA, double xStepA, double yStepA, + Object *resDictA, double *matrixA, + Object *contentStreamA); + + int paintType; + int tilingType; + double bbox[4]; + double xStep, yStep; + Object resDict; + double matrix[6]; + Object contentStream; +}; + +//------------------------------------------------------------------------ +// GfxShadingPattern +//------------------------------------------------------------------------ + +class GfxShadingPattern: public GfxPattern { +public: + + static GfxShadingPattern *parse(Object *patObj); + virtual ~GfxShadingPattern(); + + virtual GfxPattern *copy(); + + GfxShading *getShading() { return shading; } + double *getMatrix() { return matrix; } + +private: + + GfxShadingPattern(GfxShading *shadingA, double *matrixA); + + GfxShading *shading; + double matrix[6]; +}; + +//------------------------------------------------------------------------ +// GfxShading +//------------------------------------------------------------------------ + +class GfxShading { +public: + + GfxShading(int typeA); + GfxShading(GfxShading *shading); + virtual ~GfxShading(); + + static GfxShading *parse(Object *obj); + + virtual GfxShading *copy() = 0; + + int getType() { return type; } + GfxColorSpace *getColorSpace() { return colorSpace; } + GfxColor *getBackground() { return &background; } + GBool getHasBackground() { return hasBackground; } + void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA) + { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } + GBool getHasBBox() { return hasBBox; } + +protected: + + GBool init(Dict *dict); + + int type; + GfxColorSpace *colorSpace; + GfxColor background; + GBool hasBackground; + double xMin, yMin, xMax, yMax; + GBool hasBBox; +}; + +//------------------------------------------------------------------------ +// GfxFunctionShading +//------------------------------------------------------------------------ + +class GfxFunctionShading: public GfxShading { +public: + + GfxFunctionShading(double x0A, double y0A, + double x1A, double y1A, + double *matrixA, + Function **funcsA, int nFuncsA); + GfxFunctionShading(GfxFunctionShading *shading); + virtual ~GfxFunctionShading(); + + static GfxFunctionShading *parse(Dict *dict); + + virtual GfxShading *copy(); + + void getDomain(double *x0A, double *y0A, double *x1A, double *y1A) + { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; } + double *getMatrix() { return matrix; } + int getNFuncs() { return nFuncs; } + Function *getFunc(int i) { return funcs[i]; } + void getColor(double x, double y, GfxColor *color); + +private: + + double x0, y0, x1, y1; + double matrix[6]; + Function *funcs[gfxColorMaxComps]; + int nFuncs; +}; + +//------------------------------------------------------------------------ +// GfxAxialShading +//------------------------------------------------------------------------ + +class GfxAxialShading: public GfxShading { +public: + + GfxAxialShading(double x0A, double y0A, + double x1A, double y1A, + double t0A, double t1A, + Function **funcsA, int nFuncsA, + GBool extend0A, GBool extend1A); + GfxAxialShading(GfxAxialShading *shading); + virtual ~GfxAxialShading(); + + static GfxAxialShading *parse(Dict *dict); + + virtual GfxShading *copy(); + + void getCoords(double *x0A, double *y0A, double *x1A, double *y1A) + { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; } + double getDomain0() { return t0; } + double getDomain1() { return t1; } + GBool getExtend0() { return extend0; } + GBool getExtend1() { return extend1; } + int getNFuncs() { return nFuncs; } + Function *getFunc(int i) { return funcs[i]; } + void getColor(double t, GfxColor *color); + +private: + + double x0, y0, x1, y1; + double t0, t1; + Function *funcs[gfxColorMaxComps]; + int nFuncs; + GBool extend0, extend1; +}; + +//------------------------------------------------------------------------ +// GfxRadialShading +//------------------------------------------------------------------------ + +class GfxRadialShading: public GfxShading { +public: + + GfxRadialShading(double x0A, double y0A, double r0A, + double x1A, double y1A, double r1A, + double t0A, double t1A, + Function **funcsA, int nFuncsA, + GBool extend0A, GBool extend1A); + GfxRadialShading(GfxRadialShading *shading); + virtual ~GfxRadialShading(); + + static GfxRadialShading *parse(Dict *dict); + + virtual GfxShading *copy(); + + void getCoords(double *x0A, double *y0A, double *r0A, + double *x1A, double *y1A, double *r1A) + { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; } + double getDomain0() { return t0; } + double getDomain1() { return t1; } + GBool getExtend0() { return extend0; } + GBool getExtend1() { return extend1; } + int getNFuncs() { return nFuncs; } + Function *getFunc(int i) { return funcs[i]; } + void getColor(double t, GfxColor *color); + +private: + + double x0, y0, r0, x1, y1, r1; + double t0, t1; + Function *funcs[gfxColorMaxComps]; + int nFuncs; + GBool extend0, extend1; +}; + +//------------------------------------------------------------------------ +// GfxGouraudTriangleShading +//------------------------------------------------------------------------ + +struct GfxGouraudVertex { + double x, y; + GfxColor color; +}; + +class GfxGouraudTriangleShading: public GfxShading { +public: + + GfxGouraudTriangleShading(int typeA, + GfxGouraudVertex *verticesA, int nVerticesA, + int (*trianglesA)[3], int nTrianglesA, + Function **funcsA, int nFuncsA); + GfxGouraudTriangleShading(GfxGouraudTriangleShading *shading); + virtual ~GfxGouraudTriangleShading(); + + static GfxGouraudTriangleShading *parse(int typeA, Dict *dict, Stream *str); + + virtual GfxShading *copy(); + + int getNTriangles() { return nTriangles; } + void getTriangle(int i, double *x0, double *y0, GfxColor *color0, + double *x1, double *y1, GfxColor *color1, + double *x2, double *y2, GfxColor *color2); + +private: + + GfxGouraudVertex *vertices; + int nVertices; + int (*triangles)[3]; + int nTriangles; + Function *funcs[gfxColorMaxComps]; + int nFuncs; +}; + +//------------------------------------------------------------------------ +// GfxPatchMeshShading +//------------------------------------------------------------------------ + +struct GfxPatch { + double x[4][4]; + double y[4][4]; + GfxColor color[2][2]; +}; + +class GfxPatchMeshShading: public GfxShading { +public: + + GfxPatchMeshShading(int typeA, GfxPatch *patchesA, int nPatchesA, + Function **funcsA, int nFuncsA); + GfxPatchMeshShading(GfxPatchMeshShading *shading); + virtual ~GfxPatchMeshShading(); + + static GfxPatchMeshShading *parse(int typeA, Dict *dict, Stream *str); + + virtual GfxShading *copy(); + + int getNPatches() { return nPatches; } + GfxPatch *getPatch(int i) { return &patches[i]; } + +private: + + GfxPatch *patches; + int nPatches; + Function *funcs[gfxColorMaxComps]; + int nFuncs; +}; + +//------------------------------------------------------------------------ +// GfxImageColorMap +//------------------------------------------------------------------------ + +class GfxImageColorMap { +public: + + // Constructor. + GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA); + + // Destructor. + ~GfxImageColorMap(); + + // Return a copy of this color map. + GfxImageColorMap *copy() { return new GfxImageColorMap(this); } + + // Is color map valid? + GBool isOk() { return ok; } + + // Get the color space. + GfxColorSpace *getColorSpace() { return colorSpace; } + + // Get stream decoding info. + int getNumPixelComps() { return nComps; } + int getBits() { return bits; } + + // Get decode table. + double getDecodeLow(int i) { return decodeLow[i]; } + double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; } + + // Convert an image pixel to a color. + void getGray(Guchar *x, GfxGray *gray); + void getRGB(Guchar *x, GfxRGB *rgb); + void getRGBLine(Guchar *in, unsigned int *out, int length); + void getGrayLine(Guchar *in, Guchar *out, int length); + void getCMYK(Guchar *x, GfxCMYK *cmyk); + void getColor(Guchar *x, GfxColor *color); + +private: + + GfxImageColorMap(GfxImageColorMap *colorMap); + + GfxColorSpace *colorSpace; // the image color space + int bits; // bits per component + int nComps; // number of components in a pixel + GfxColorSpace *colorSpace2; // secondary color space + int nComps2; // number of components in colorSpace2 + GfxColorComp * // lookup table + lookup[gfxColorMaxComps]; + Guchar *byte_lookup; + Guchar *tmp_line; + double // minimum values for each component + decodeLow[gfxColorMaxComps]; + double // max - min value for each component + decodeRange[gfxColorMaxComps]; + GBool ok; +}; + +//------------------------------------------------------------------------ +// GfxSubpath and GfxPath +//------------------------------------------------------------------------ + +class GfxSubpath { +public: + + // Constructor. + GfxSubpath(double x1, double y1); + + // Destructor. + ~GfxSubpath(); + + // Copy. + GfxSubpath *copy() { return new GfxSubpath(this); } + + // Get points. + int getNumPoints() { return n; } + double getX(int i) { return x[i]; } + double getY(int i) { return y[i]; } + GBool getCurve(int i) { return curve[i]; } + + // Get last point. + double getLastX() { return x[n-1]; } + double getLastY() { return y[n-1]; } + + // Add a line segment. + void lineTo(double x1, double y1); + + // Add a Bezier curve. + void curveTo(double x1, double y1, double x2, double y2, + double x3, double y3); + + // Close the subpath. + void close(); + GBool isClosed() { return closed; } + + // Add (, ) to each point in the subpath. + void offset(double dx, double dy); + +private: + + double *x, *y; // points + GBool *curve; // curve[i] => point i is a control point + // for a Bezier curve + int n; // number of points + int size; // size of x/y arrays + GBool closed; // set if path is closed + + GfxSubpath(GfxSubpath *subpath); +}; + +class GfxPath { +public: + + // Constructor. + GfxPath(); + + // Destructor. + ~GfxPath(); + + // Copy. + GfxPath *copy() + { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); } + + // Is there a current point? + GBool isCurPt() { return n > 0 || justMoved; } + + // Is the path non-empty, i.e., is there at least one segment? + GBool isPath() { return n > 0; } + + // Get subpaths. + int getNumSubpaths() { return n; } + GfxSubpath *getSubpath(int i) { return subpaths[i]; } + + // Get last point on last subpath. + double getLastX() { return subpaths[n-1]->getLastX(); } + double getLastY() { return subpaths[n-1]->getLastY(); } + + // Move the current point. + void moveTo(double x, double y); + + // Add a segment to the last subpath. + void lineTo(double x, double y); + + // Add a Bezier curve to the last subpath + void curveTo(double x1, double y1, double x2, double y2, + double x3, double y3); + + // Close the last subpath. + void close(); + + // Append to . + void append(GfxPath *path); + + // Add (, ) to each point in the path. + void offset(double dx, double dy); + +private: + + GBool justMoved; // set if a new subpath was just started + double firstX, firstY; // first point in new subpath + GfxSubpath **subpaths; // subpaths + int n; // number of subpaths + int size; // size of subpaths array + + GfxPath(GBool justMoved1, double firstX1, double firstY1, + GfxSubpath **subpaths1, int n1, int size1); +}; + +//------------------------------------------------------------------------ +// GfxState +//------------------------------------------------------------------------ + +class GfxState { +public: + + // Construct a default GfxState, for a device with resolution + // x , page box , page rotation , and + // coordinate system specified by . + GfxState(double hDPI, double vDPI, PDFRectangle *pageBox, + int rotateA, GBool upsideDown); + + // Destructor. + ~GfxState(); + + // Copy. + GfxState *copy() { return new GfxState(this); } + + // Accessors. + double *getCTM() { return ctm; } + void getCTM(Matrix *m) { memcpy (m->m, ctm, sizeof m->m); } + double getX1() { return px1; } + double getY1() { return py1; } + double getX2() { return px2; } + double getY2() { return py2; } + double getPageWidth() { return pageWidth; } + double getPageHeight() { return pageHeight; } + int getRotate() { return rotate; } + GfxColor *getFillColor() { return &fillColor; } + GfxColor *getStrokeColor() { return &strokeColor; } + void getFillGray(GfxGray *gray) + { fillColorSpace->getGray(&fillColor, gray); } + void getStrokeGray(GfxGray *gray) + { strokeColorSpace->getGray(&strokeColor, gray); } + void getFillRGB(GfxRGB *rgb) + { fillColorSpace->getRGB(&fillColor, rgb); } + void getStrokeRGB(GfxRGB *rgb) + { strokeColorSpace->getRGB(&strokeColor, rgb); } + void getFillCMYK(GfxCMYK *cmyk) + { fillColorSpace->getCMYK(&fillColor, cmyk); } + void getStrokeCMYK(GfxCMYK *cmyk) + { strokeColorSpace->getCMYK(&strokeColor, cmyk); } + GfxColorSpace *getFillColorSpace() { return fillColorSpace; } + GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; } + GfxPattern *getFillPattern() { return fillPattern; } + GfxPattern *getStrokePattern() { return strokePattern; } + GfxBlendMode getBlendMode() { return blendMode; } + double getFillOpacity() { return fillOpacity; } + double getStrokeOpacity() { return strokeOpacity; } + GBool getFillOverprint() { return fillOverprint; } + GBool getStrokeOverprint() { return strokeOverprint; } + double getLineWidth() { return lineWidth; } + void getLineDash(double **dash, int *length, double *start) + { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; } + int getFlatness() { return flatness; } + int getLineJoin() { return lineJoin; } + int getLineCap() { return lineCap; } + double getMiterLimit() { return miterLimit; } + GfxFont *getFont() { return font; } + double getFontSize() { return fontSize; } + double *getTextMat() { return textMat; } + double getCharSpace() { return charSpace; } + double getWordSpace() { return wordSpace; } + double getHorizScaling() { return horizScaling; } + double getLeading() { return leading; } + double getRise() { return rise; } + int getRender() { return render; } + GfxPath *getPath() { return path; } + void setPath(GfxPath *pathA); + double getCurX() { return curX; } + double getCurY() { return curY; } + void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax) + { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; } + void getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax); + double getLineX() { return lineX; } + double getLineY() { return lineY; } + + // Is there a current point/path? + GBool isCurPt() { return path->isCurPt(); } + GBool isPath() { return path->isPath(); } + + // Transforms. + void transform(double x1, double y1, double *x2, double *y2) + { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4]; + *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; } + void transformDelta(double x1, double y1, double *x2, double *y2) + { *x2 = ctm[0] * x1 + ctm[2] * y1; + *y2 = ctm[1] * x1 + ctm[3] * y1; } + void textTransform(double x1, double y1, double *x2, double *y2) + { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4]; + *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; } + void textTransformDelta(double x1, double y1, double *x2, double *y2) + { *x2 = textMat[0] * x1 + textMat[2] * y1; + *y2 = textMat[1] * x1 + textMat[3] * y1; } + double transformWidth(double w); + double getTransformedLineWidth() + { return transformWidth(lineWidth); } + double getTransformedFontSize(); + void getFontTransMat(double *m11, double *m12, double *m21, double *m22); + + // Change state parameters. + void setCTM(double a, double b, double c, + double d, double e, double f); + void concatCTM(double a, double b, double c, + double d, double e, double f); + void setFillColorSpace(GfxColorSpace *colorSpace); + void setStrokeColorSpace(GfxColorSpace *colorSpace); + void setFillColor(GfxColor *color) { fillColor = *color; } + void setStrokeColor(GfxColor *color) { strokeColor = *color; } + void setFillPattern(GfxPattern *pattern); + void setStrokePattern(GfxPattern *pattern); + void setBlendMode(GfxBlendMode mode) { blendMode = mode; } + void setFillOpacity(double opac) { fillOpacity = opac; } + void setStrokeOpacity(double opac) { strokeOpacity = opac; } + void setFillOverprint(GBool op) { fillOverprint = op; } + void setStrokeOverprint(GBool op) { strokeOverprint = op; } + void setLineWidth(double width) { lineWidth = width; } + void setLineDash(double *dash, int length, double start); + void setFlatness(int flatness1) { flatness = flatness1; } + void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; } + void setLineCap(int lineCap1) { lineCap = lineCap1; } + void setMiterLimit(double limit) { miterLimit = limit; } + void setFont(GfxFont *fontA, double fontSizeA); + void setTextMat(double a, double b, double c, + double d, double e, double f) + { textMat[0] = a; textMat[1] = b; textMat[2] = c; + textMat[3] = d; textMat[4] = e; textMat[5] = f; } + void setCharSpace(double space) + { charSpace = space; } + void setWordSpace(double space) + { wordSpace = space; } + void setHorizScaling(double scale) + { horizScaling = 0.01 * scale; } + void setLeading(double leadingA) + { leading = leadingA; } + void setRise(double riseA) + { rise = riseA; } + void setRender(int renderA) + { render = renderA; } + + // Add to path. + void moveTo(double x, double y) + { path->moveTo(curX = x, curY = y); } + void lineTo(double x, double y) + { path->lineTo(curX = x, curY = y); } + void curveTo(double x1, double y1, double x2, double y2, + double x3, double y3) + { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); } + void closePath() + { path->close(); curX = path->getLastX(); curY = path->getLastY(); } + void clearPath(); + + // Update clip region. + void clip(); + + // Text position. + void textSetPos(double tx, double ty) { lineX = tx; lineY = ty; } + void textMoveTo(double tx, double ty) + { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); } + void textShift(double tx, double ty); + void shift(double dx, double dy); + + // Push/pop GfxState on/off stack. + GfxState *save(); + GfxState *restore(); + GBool hasSaves() { return saved != NULL; } + + // Misc + GBool parseBlendMode(Object *obj, GfxBlendMode *mode); + +private: + + double ctm[6]; // coord transform matrix + double px1, py1, px2, py2; // page corners (user coords) + double pageWidth, pageHeight; // page size (pixels) + int rotate; // page rotation angle + + GfxColorSpace *fillColorSpace; // fill color space + GfxColorSpace *strokeColorSpace; // stroke color space + GfxColor fillColor; // fill color + GfxColor strokeColor; // stroke color + GfxPattern *fillPattern; // fill pattern + GfxPattern *strokePattern; // stroke pattern + GfxBlendMode blendMode; // transparency blend mode + double fillOpacity; // fill opacity + double strokeOpacity; // stroke opacity + GBool fillOverprint; // fill overprint + GBool strokeOverprint; // stroke overprint + + double lineWidth; // line width + double *lineDash; // line dash + int lineDashLength; + double lineDashStart; + int flatness; // curve flatness + int lineJoin; // line join style + int lineCap; // line cap style + double miterLimit; // line miter limit + + GfxFont *font; // font + double fontSize; // font size + double textMat[6]; // text matrix + double charSpace; // character spacing + double wordSpace; // word spacing + double horizScaling; // horizontal scaling + double leading; // text leading + double rise; // text rise + int render; // text rendering mode + + GfxPath *path; // array of path elements + double curX, curY; // current point (user coords) + double lineX, lineY; // start of current text line (text coords) + + double clipXMin, clipYMin, // bounding box for clip region + clipXMax, clipYMax; + + GfxState *saved; // next GfxState on stack + + GfxState(GfxState *state); +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/GlobalParams.cc b/rosapps/smartpdf/poppler/poppler/GlobalParams.cc new file mode 100644 index 00000000000..e5d6436bf94 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/GlobalParams.cc @@ -0,0 +1,2051 @@ +//======================================================================== +// +// GlobalParams.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#ifdef ENABLE_PLUGINS +# ifndef WIN32 +# include +# endif +#endif +#ifdef WIN32 +# include +#endif +#ifdef HAVE_FONTCONFIG_H +# include +#endif +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "goo/GooHash.h" +#include "goo/gfile.h" +#include "Error.h" +#include "NameToCharCode.h" +#include "CharCodeToUnicode.h" +#include "UnicodeMap.h" +#include "CMap.h" +#include "BuiltinFontTables.h" +#include "FontEncodingTables.h" +#ifdef ENABLE_PLUGINS +# include "XpdfPluginAPI.h" +#endif +#include "GlobalParams.h" +#include "GfxFont.h" + +#if MULTITHREADED +# define lockGlobalParams gLockMutex(&mutex) +# define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex) +# define lockCMapCache gLockMutex(&cMapCacheMutex) +# define unlockGlobalParams gUnlockMutex(&mutex) +# define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex) +# define unlockCMapCache gUnlockMutex(&cMapCacheMutex) +#else +# define lockGlobalParams +# define lockUnicodeMapCache +# define lockCMapCache +# define unlockGlobalParams +# define unlockUnicodeMapCache +# define unlockCMapCache +#endif + +#ifndef FC_WEIGHT_BOOK +#define FC_WEIGHT_BOOK 75 +#endif + +#include "NameToUnicodeTable.h" +#include "UnicodeMapTables.h" +#include "UTF8.h" + +#ifdef ENABLE_PLUGINS +# ifdef WIN32 +extern XpdfPluginVecTable xpdfPluginVecTable; +# endif +#endif + +//------------------------------------------------------------------------ + +#define cidToUnicodeCacheSize 4 +#define unicodeToUnicodeCacheSize 4 + +//------------------------------------------------------------------------ + +GlobalParams *globalParams = NULL; + +//------------------------------------------------------------------------ +// DisplayFontParam +//------------------------------------------------------------------------ + +DisplayFontParam::DisplayFontParam(GooString *nameA, + DisplayFontParamKind kindA) { + name = nameA; + kind = kindA; + switch (kind) { + case displayFontT1: + t1.fileName = NULL; + break; + case displayFontTT: + tt.fileName = NULL; + break; + } +} + +DisplayFontParam::~DisplayFontParam() { + delete name; + switch (kind) { + case displayFontT1: + if (t1.fileName) { + delete t1.fileName; + } + break; + case displayFontTT: + if (tt.fileName) { + delete tt.fileName; + } + break; + } +} + +//------------------------------------------------------------------------ +// PSFontParam +//------------------------------------------------------------------------ + +PSFontParam::PSFontParam(GooString *pdfFontNameA, int wModeA, + GooString *psFontNameA, GooString *encodingA) { + pdfFontName = pdfFontNameA; + wMode = wModeA; + psFontName = psFontNameA; + encoding = encodingA; +} + +PSFontParam::~PSFontParam() { + delete pdfFontName; + delete psFontName; + if (encoding) { + delete encoding; + } +} + +#ifdef ENABLE_PLUGINS +//------------------------------------------------------------------------ +// Plugin +//------------------------------------------------------------------------ + +class Plugin { +public: + + static Plugin *load(char *type, char *name); + ~Plugin(); + +private: + +#ifdef WIN32 + Plugin(HMODULE libA); + HMODULE lib; +#else + Plugin(void *dlA); + void *dl; +#endif +}; + +Plugin *Plugin::load(char *type, char *name) { + GooString *path; + Plugin *plugin; + XpdfPluginVecTable *vt; + XpdfBool (*xpdfInitPlugin)(void); +#ifdef WIN32 + HMODULE libA; +#else + void *dlA; +#endif + + path = globalParams->getBaseDir(); + appendToPath(path, "plugins"); + appendToPath(path, type); + appendToPath(path, name); + +#ifdef WIN32 + path->append(".dll"); + if (!(libA = LoadLibrary(path->getCString()))) { + error(-1, "Failed to load plugin '%s'", + path->getCString()); + goto err1; + } + if (!(vt = (XpdfPluginVecTable *) + GetProcAddress(libA, "xpdfPluginVecTable"))) { + error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'", + path->getCString()); + goto err2; + } +#else + //~ need to deal with other extensions here + path->append(".so"); + if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) { + error(-1, "Failed to load plugin '%s': %s", + path->getCString(), dlerror()); + goto err1; + } + if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) { + error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'", + path->getCString()); + goto err2; + } +#endif + + if (vt->version != xpdfPluginVecTable.version) { + error(-1, "Plugin '%s' is wrong version", path->getCString()); + goto err2; + } + memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable)); + +#ifdef WIN32 + if (!(xpdfInitPlugin = (XpdfBool (*)(void)) + GetProcAddress(libA, "xpdfInitPlugin"))) { + error(-1, "Failed to find xpdfInitPlugin in plugin '%s'", + path->getCString()); + goto err2; + } +#else + if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) { + error(-1, "Failed to find xpdfInitPlugin in plugin '%s'", + path->getCString()); + goto err2; + } +#endif + + if (!(*xpdfInitPlugin)()) { + error(-1, "Initialization of plugin '%s' failed", + path->getCString()); + goto err2; + } + +#ifdef WIN32 + plugin = new Plugin(libA); +#else + plugin = new Plugin(dlA); +#endif + + delete path; + return plugin; + + err2: +#ifdef WIN32 + FreeLibrary(libA); +#else + dlclose(dlA); +#endif + err1: + delete path; + return NULL; +} + +#ifdef WIN32 +Plugin::Plugin(HMODULE libA) { + lib = libA; +} +#else +Plugin::Plugin(void *dlA) { + dl = dlA; +} +#endif + +Plugin::~Plugin() { + void (*xpdfFreePlugin)(void); + +#ifdef WIN32 + if ((xpdfFreePlugin = (void (*)(void)) + GetProcAddress(lib, "xpdfFreePlugin"))) { + (*xpdfFreePlugin)(); + } + FreeLibrary(lib); +#else + if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) { + (*xpdfFreePlugin)(); + } + dlclose(dl); +#endif +} + +#endif // ENABLE_PLUGINS + +//------------------------------------------------------------------------ +// parsing +//------------------------------------------------------------------------ + +GlobalParams::GlobalParams(char *cfgFileName) { + UnicodeMap *map; + GooString *fileName; + FILE *f; + int i; + +#ifdef HAVE_FONTCONFIG_H + FcInit(); + FCcfg = FcConfigGetCurrent(); +#endif + +#if MULTITHREADED + gInitMutex(&mutex); + gInitMutex(&unicodeMapCacheMutex); + gInitMutex(&cMapCacheMutex); +#endif + + initBuiltinFontTables(); + + // scan the encoding in reverse because we want the lowest-numbered + // index for each char name ('space' is encoded twice) + macRomanReverseMap = new NameToCharCode(); + for (i = 255; i >= 0; --i) { + if (macRomanEncoding[i]) { + macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); + } + } + +#ifdef WIN32 + // baseDir will be set by a call to setBaseDir + baseDir = new GooString(); +#else + baseDir = appendToPath(getHomeDir(), ".xpdf"); +#endif + nameToUnicode = new NameToCharCode(); + cidToUnicodes = new GooHash(gTrue); + unicodeToUnicodes = new GooHash(gTrue); + residentUnicodeMaps = new GooHash(); + unicodeMaps = new GooHash(gTrue); + cMapDirs = new GooHash(gTrue); + toUnicodeDirs = new GooList(); + displayFonts = new GooHash(); + psPaperWidth = -1; + psPaperHeight = -1; + psImageableLLX = psImageableLLY = 0; + psImageableURX = psPaperWidth; + psImageableURY = psPaperHeight; + psCrop = gTrue; + psExpandSmaller = gFalse; + psShrinkLarger = gTrue; + psCenter = gTrue; + psDuplex = gFalse; + psLevel = psLevel2; + psFile = NULL; + psFonts = new GooHash(); + psNamedFonts16 = new GooList(); + psFonts16 = new GooList(); + psEmbedType1 = gTrue; + psEmbedTrueType = gTrue; + psEmbedCIDPostScript = gTrue; + psEmbedCIDTrueType = gTrue; + psOPI = gFalse; + psASCIIHex = gFalse; + textEncoding = new GooString("UTF-8"); +#if defined(WIN32) + textEOL = eolDOS; +#elif defined(MACOS) + textEOL = eolMac; +#else + textEOL = eolUnix; +#endif + textPageBreaks = gTrue; + textKeepTinyChars = gFalse; + fontDirs = new GooList(); + initialZoom = new GooString("125"); + continuousView = gFalse; + enableT1lib = gTrue; + enableFreeType = gTrue; + antialias = gTrue; + urlCommand = NULL; + movieCommand = NULL; + mapNumericCharNames = gTrue; + printCommands = gFalse; + profileCommands = gFalse; + errQuiet = gFalse; + + cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize); + unicodeToUnicodeCache = + new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize); + unicodeMapCache = new UnicodeMapCache(); + cMapCache = new CMapCache(); + +#ifdef ENABLE_PLUGINS + plugins = new GooList(); + securityHandlers = new GooList(); +#endif + + // set up the initial nameToUnicode table + for (i = 0; nameToUnicodeTab[i].name; ++i) { + nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u); + } + + // set up the residentUnicodeMaps table + map = new UnicodeMap("Latin1", gFalse, + latin1UnicodeMapRanges, latin1UnicodeMapLen); + residentUnicodeMaps->add(map->getEncodingName(), map); + map = new UnicodeMap("ASCII7", gFalse, + ascii7UnicodeMapRanges, ascii7UnicodeMapLen); + residentUnicodeMaps->add(map->getEncodingName(), map); + map = new UnicodeMap("Symbol", gFalse, + symbolUnicodeMapRanges, symbolUnicodeMapLen); + residentUnicodeMaps->add(map->getEncodingName(), map); + map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges, + zapfDingbatsUnicodeMapLen); + residentUnicodeMaps->add(map->getEncodingName(), map); + map = new UnicodeMap("UTF-8", gTrue, &mapUTF8); + residentUnicodeMaps->add(map->getEncodingName(), map); + map = new UnicodeMap("UCS-2", gTrue, &mapUCS2); + residentUnicodeMaps->add(map->getEncodingName(), map); + + // look for a user config file, then a system-wide config file + f = NULL; + fileName = NULL; + if (cfgFileName && cfgFileName[0]) { + fileName = new GooString(cfgFileName); + if (!(f = fopen(fileName->getCString(), "r"))) { + delete fileName; + } + } + if (!f) { + fileName = appendToPath(getHomeDir(), xpdfUserConfigFile); + if (!(f = fopen(fileName->getCString(), "r"))) { + delete fileName; + } + } + if (!f) { +#if defined(WIN32) && !defined(__CYGWIN32__) + char buf[512]; + /* @note: TCHAR* cast */ + i = GetModuleFileName(NULL, (TCHAR*)buf, sizeof(buf)); + if (i <= 0 || i >= sizeof(buf)) { + // error or path too long for buffer - just use the current dir + buf[0] = '\0'; + } + fileName = grabPath(buf); + appendToPath(fileName, xpdfSysConfigFile); +#else + fileName = new GooString(xpdfSysConfigFile); +#endif + if (!(f = fopen(fileName->getCString(), "r"))) { + delete fileName; + } + } + if (f) { + parseFile(fileName, f); + delete fileName; + fclose(f); + } + + scanEncodingDirs(); +} + +void GlobalParams::parseFile(GooString *fileName, FILE *f) { + int line; + GooList *tokens; + GooString *cmd, *incFile; + char *p1, *p2; + char buf[512]; + FILE *f2; + + line = 1; + while (getLine(buf, sizeof(buf) - 1, f)) { + + // break the line into tokens + tokens = new GooList(); + p1 = buf; + while (*p1) { + for (; *p1 && isspace(*p1); ++p1) ; + if (!*p1) { + break; + } + if (*p1 == '"' || *p1 == '\'') { + for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ; + ++p1; + } else { + for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ; + } + tokens->append(new GooString(p1, p2 - p1)); + p1 = *p2 ? p2 + 1 : p2; + } + + if (tokens->getLength() > 0 && + ((GooString *)tokens->get(0))->getChar(0) != '#') { + cmd = (GooString *)tokens->get(0); + if (!cmd->cmp("include")) { + if (tokens->getLength() == 2) { + incFile = (GooString *)tokens->get(1); + if ((f2 = fopen(incFile->getCString(), "r"))) { + parseFile(incFile, f2); + fclose(f2); + } else { + error(-1, "Couldn't find included config file: '%s' (%s:%d)", + incFile->getCString(), fileName->getCString(), line); + } + } else { + error(-1, "Bad 'include' config file command (%s:%d)", + fileName->getCString(), line); + } + } else if (!cmd->cmp("nameToUnicode")) { + if (tokens->getLength() != 2) + error(-1, "Bad 'nameToUnicode' config file command (%s:%d)", + fileName->getCString(), line); + else + parseNameToUnicode((GooString *) tokens->get(1)); + } else if (!cmd->cmp("cidToUnicode")) { + parseCIDToUnicode(tokens, fileName, line); + } else if (!cmd->cmp("unicodeToUnicode")) { + parseUnicodeToUnicode(tokens, fileName, line); + } else if (!cmd->cmp("unicodeMap")) { + parseUnicodeMap(tokens, fileName, line); + } else if (!cmd->cmp("cMapDir")) { + parseCMapDir(tokens, fileName, line); + } else if (!cmd->cmp("toUnicodeDir")) { + parseToUnicodeDir(tokens, fileName, line); + } else if (!cmd->cmp("displayFontT1")) { + // deprecated + } else if (!cmd->cmp("displayFontTT")) { + // deprecated + } else if (!cmd->cmp("displayNamedCIDFontT1")) { + // deprecated + } else if (!cmd->cmp("displayCIDFontT1")) { + // deprecated + } else if (!cmd->cmp("displayNamedCIDFontTT")) { + // deprecated + } else if (!cmd->cmp("displayCIDFontTT")) { + // deprecated + } else if (!cmd->cmp("psFile")) { + parsePSFile(tokens, fileName, line); + } else if (!cmd->cmp("psFont")) { + parsePSFont(tokens, fileName, line); + } else if (!cmd->cmp("psNamedFont16")) { + parsePSFont16("psNamedFont16", psNamedFonts16, + tokens, fileName, line); + } else if (!cmd->cmp("psFont16")) { + parsePSFont16("psFont16", psFonts16, tokens, fileName, line); + } else if (!cmd->cmp("psPaperSize")) { + parsePSPaperSize(tokens, fileName, line); + } else if (!cmd->cmp("psImageableArea")) { + parsePSImageableArea(tokens, fileName, line); + } else if (!cmd->cmp("psCrop")) { + parseYesNo("psCrop", &psCrop, tokens, fileName, line); + } else if (!cmd->cmp("psExpandSmaller")) { + parseYesNo("psExpandSmaller", &psExpandSmaller, + tokens, fileName, line); + } else if (!cmd->cmp("psShrinkLarger")) { + parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line); + } else if (!cmd->cmp("psCenter")) { + parseYesNo("psCenter", &psCenter, tokens, fileName, line); + } else if (!cmd->cmp("psDuplex")) { + parseYesNo("psDuplex", &psDuplex, tokens, fileName, line); + } else if (!cmd->cmp("psLevel")) { + parsePSLevel(tokens, fileName, line); + } else if (!cmd->cmp("psEmbedType1Fonts")) { + parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line); + } else if (!cmd->cmp("psEmbedTrueTypeFonts")) { + parseYesNo("psEmbedTrueType", &psEmbedTrueType, + tokens, fileName, line); + } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) { + parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript, + tokens, fileName, line); + } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) { + parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType, + tokens, fileName, line); + } else if (!cmd->cmp("psOPI")) { + parseYesNo("psOPI", &psOPI, tokens, fileName, line); + } else if (!cmd->cmp("psASCIIHex")) { + parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line); + } else if (!cmd->cmp("textEncoding")) { + parseTextEncoding(tokens, fileName, line); + } else if (!cmd->cmp("textEOL")) { + parseTextEOL(tokens, fileName, line); + } else if (!cmd->cmp("textPageBreaks")) { + parseYesNo("textPageBreaks", &textPageBreaks, + tokens, fileName, line); + } else if (!cmd->cmp("textKeepTinyChars")) { + parseYesNo("textKeepTinyChars", &textKeepTinyChars, + tokens, fileName, line); + } else if (!cmd->cmp("fontDir")) { + parseFontDir(tokens, fileName, line); + } else if (!cmd->cmp("initialZoom")) { + parseInitialZoom(tokens, fileName, line); + } else if (!cmd->cmp("continuousView")) { + parseYesNo("continuousView", &continuousView, tokens, fileName, line); + } else if (!cmd->cmp("enableT1lib")) { + parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line); + } else if (!cmd->cmp("enableFreeType")) { + parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line); + } else if (!cmd->cmp("antialias")) { + parseYesNo("antialias", &antialias, tokens, fileName, line); + } else if (!cmd->cmp("urlCommand")) { + parseCommand("urlCommand", &urlCommand, tokens, fileName, line); + } else if (!cmd->cmp("movieCommand")) { + parseCommand("movieCommand", &movieCommand, tokens, fileName, line); + } else if (!cmd->cmp("mapNumericCharNames")) { + parseYesNo("mapNumericCharNames", &mapNumericCharNames, + tokens, fileName, line); + } else if (!cmd->cmp("printCommands")) { + parseYesNo("printCommands", &printCommands, tokens, fileName, line); + } else if (!cmd->cmp("errQuiet")) { + parseYesNo("errQuiet", &errQuiet, tokens, fileName, line); + } else { + error(-1, "Unknown config file command '%s' (%s:%d)", + cmd->getCString(), fileName->getCString(), line); + if (!cmd->cmp("displayFontX") || + !cmd->cmp("displayNamedCIDFontX") || + !cmd->cmp("displayCIDFontX")) { + error(-1, "-- Xpdf no longer supports X fonts"); + } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) { + error(-1, "-- The t1libControl and freetypeControl options have been replaced"); + error(-1, " by the enableT1lib, enableFreeType, and antialias options"); + } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) { + error(-1, "-- the config file format has changed since Xpdf 0.9x"); + } + } + } + + deleteGooList(tokens, GooString); + ++line; + } +} + +void GlobalParams::scanEncodingDirs() { + GDir *dir; + GDirEntry *entry; + + dir = new GDir(POPPLER_DATADIR "/nameToUnicode", gFalse); + while (entry = dir->getNextEntry(), entry != NULL) { + parseNameToUnicode(entry->getFullPath()); + delete entry; + } + delete dir; + + dir = new GDir(POPPLER_DATADIR "/cidToUnicode", gFalse); + while (entry = dir->getNextEntry(), entry != NULL) { + addCIDToUnicode(entry->getName(), entry->getFullPath()); + delete entry; + } + delete dir; + + dir = new GDir(POPPLER_DATADIR "/unicodeMap", gFalse); + while (entry = dir->getNextEntry(), entry != NULL) { + addUnicodeMap(entry->getName(), entry->getFullPath()); + delete entry; + } + delete dir; + + dir = new GDir(POPPLER_DATADIR "/cMap", gFalse); + while (entry = dir->getNextEntry(), entry != NULL) { + addCMapDir(entry->getName(), entry->getFullPath()); + toUnicodeDirs->append(entry->getFullPath()->copy()); + delete entry; + } + delete dir; +} + +void GlobalParams::parseNameToUnicode(GooString *name) { + char *tok1, *tok2; + FILE *f; + char buf[256]; + int line; + Unicode u; + + if (!(f = fopen(name->getCString(), "r"))) { + error(-1, "Couldn't open 'nameToUnicode' file '%s'", + name->getCString()); + return; + } + line = 1; + while (getLine(buf, sizeof(buf), f)) { + tok1 = strtok(buf, " \t\r\n"); + tok2 = strtok(NULL, " \t\r\n"); + if (tok1 && tok2) { + sscanf(tok1, "%x", &u); + nameToUnicode->add(tok2, u); + } else { + error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", + name->getCString(), line); + } + ++line; + } + fclose(f); +} + +void GlobalParams::addCIDToUnicode(GooString *collection, + GooString *fileName) { + GooString *old; + + if ((old = (GooString *)cidToUnicodes->remove(collection))) { + delete old; + } + cidToUnicodes->add(collection->copy(), fileName->copy()); +} + +void GlobalParams::parseCIDToUnicode(GooList *tokens, GooString *fileName, + int line) { + if (tokens->getLength() != 3) { + error(-1, "Bad 'cidToUnicode' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + addCIDToUnicode((GooString *)tokens->get(1), (GooString *)tokens->get(2)); +} + +void GlobalParams::parseUnicodeToUnicode(GooList *tokens, GooString *fileName, + int line) { + GooString *font, *file, *old; + + if (tokens->getLength() != 3) { + error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + font = (GooString *)tokens->get(1); + file = (GooString *)tokens->get(2); + if ((old = (GooString *)unicodeToUnicodes->remove(font))) { + delete old; + } + unicodeToUnicodes->add(font->copy(), file->copy()); +} + +void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName) +{ + GooString *old; + + if ((old = (GooString *)unicodeMaps->remove(encodingName))) { + delete old; + } + unicodeMaps->add(encodingName->copy(), fileName->copy()); +} + +void GlobalParams::parseUnicodeMap(GooList *tokens, GooString *fileName, + int line) { + + if (tokens->getLength() != 3) { + error(-1, "Bad 'unicodeMap' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + addUnicodeMap((GooString *)tokens->get(1), (GooString *)tokens->get(2)); + } + +void GlobalParams::addCMapDir(GooString *collection, GooString *dir) { + GooList *list; + + if (!(list = (GooList *)cMapDirs->lookup(collection))) { + list = new GooList(); + cMapDirs->add(collection->copy(), list); + } + list->append(dir->copy()); +} + +void GlobalParams::parseCMapDir(GooList *tokens, GooString *fileName, int line) { + if (tokens->getLength() != 3) { + error(-1, "Bad 'cMapDir' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + addCMapDir((GooString *)tokens->get(1), (GooString *)tokens->get(2)); +} + +void GlobalParams::parseToUnicodeDir(GooList *tokens, GooString *fileName, + int line) { + if (tokens->getLength() != 2) { + error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + toUnicodeDirs->append(((GooString *)tokens->get(1))->copy()); +} + +void GlobalParams::parsePSPaperSize(GooList *tokens, GooString *fileName, + int line) { + GooString *tok; + + if (tokens->getLength() == 2) { + tok = (GooString *)tokens->get(1); + if (!setPSPaperSize(tok->getCString())) { + error(-1, "Bad 'psPaperSize' config file command (%s:%d)", + fileName->getCString(), line); + } + } else if (tokens->getLength() == 3) { + tok = (GooString *)tokens->get(1); + psPaperWidth = atoi(tok->getCString()); + tok = (GooString *)tokens->get(2); + psPaperHeight = atoi(tok->getCString()); + psImageableLLX = psImageableLLY = 0; + psImageableURX = psPaperWidth; + psImageableURY = psPaperHeight; + } else { + error(-1, "Bad 'psPaperSize' config file command (%s:%d)", + fileName->getCString(), line); + } +} + +void GlobalParams::parsePSImageableArea(GooList *tokens, GooString *fileName, + int line) { + if (tokens->getLength() != 5) { + error(-1, "Bad 'psImageableArea' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + psImageableLLX = atoi(((GooString *)tokens->get(1))->getCString()); + psImageableLLY = atoi(((GooString *)tokens->get(2))->getCString()); + psImageableURX = atoi(((GooString *)tokens->get(3))->getCString()); + psImageableURY = atoi(((GooString *)tokens->get(4))->getCString()); +} + +void GlobalParams::parsePSLevel(GooList *tokens, GooString *fileName, int line) { + GooString *tok; + + if (tokens->getLength() != 2) { + error(-1, "Bad 'psLevel' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + tok = (GooString *)tokens->get(1); + if (!tok->cmp("level1")) { + psLevel = psLevel1; + } else if (!tok->cmp("level1sep")) { + psLevel = psLevel1Sep; + } else if (!tok->cmp("level2")) { + psLevel = psLevel2; + } else if (!tok->cmp("level2sep")) { + psLevel = psLevel2Sep; + } else if (!tok->cmp("level3")) { + psLevel = psLevel3; + } else if (!tok->cmp("level3Sep")) { + psLevel = psLevel3Sep; + } else { + error(-1, "Bad 'psLevel' config file command (%s:%d)", + fileName->getCString(), line); + } +} + +void GlobalParams::parsePSFile(GooList *tokens, GooString *fileName, int line) { + if (tokens->getLength() != 2) { + error(-1, "Bad 'psFile' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + if (psFile) { + delete psFile; + } + psFile = ((GooString *)tokens->get(1))->copy(); +} + +void GlobalParams::parsePSFont(GooList *tokens, GooString *fileName, int line) { + PSFontParam *param; + + if (tokens->getLength() != 3) { + error(-1, "Bad 'psFont' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + param = new PSFontParam(((GooString *)tokens->get(1))->copy(), 0, + ((GooString *)tokens->get(2))->copy(), NULL); + psFonts->add(param->pdfFontName, param); +} + +void GlobalParams::parsePSFont16(char *cmdName, GooList *fontList, + GooList *tokens, GooString *fileName, int line) { + PSFontParam *param; + int wMode; + GooString *tok; + + if (tokens->getLength() != 5) { + error(-1, "Bad '%s' config file command (%s:%d)", + cmdName, fileName->getCString(), line); + return; + } + tok = (GooString *)tokens->get(2); + if (!tok->cmp("H")) { + wMode = 0; + } else if (!tok->cmp("V")) { + wMode = 1; + } else { + error(-1, "Bad '%s' config file command (%s:%d)", + cmdName, fileName->getCString(), line); + return; + } + param = new PSFontParam(((GooString *)tokens->get(1))->copy(), + wMode, + ((GooString *)tokens->get(3))->copy(), + ((GooString *)tokens->get(4))->copy()); + fontList->append(param); +} + +void GlobalParams::parseTextEncoding(GooList *tokens, GooString *fileName, + int line) { + if (tokens->getLength() != 2) { + error(-1, "Bad 'textEncoding' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + delete textEncoding; + textEncoding = ((GooString *)tokens->get(1))->copy(); +} + +void GlobalParams::parseTextEOL(GooList *tokens, GooString *fileName, int line) { + GooString *tok; + + if (tokens->getLength() != 2) { + error(-1, "Bad 'textEOL' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + tok = (GooString *)tokens->get(1); + if (!tok->cmp("unix")) { + textEOL = eolUnix; + } else if (!tok->cmp("dos")) { + textEOL = eolDOS; + } else if (!tok->cmp("mac")) { + textEOL = eolMac; + } else { + error(-1, "Bad 'textEOL' config file command (%s:%d)", + fileName->getCString(), line); + } +} + +void GlobalParams::parseFontDir(GooList *tokens, GooString *fileName, int line) { + if (tokens->getLength() != 2) { + error(-1, "Bad 'fontDir' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + fontDirs->append(((GooString *)tokens->get(1))->copy()); +} + +void GlobalParams::parseInitialZoom(GooList *tokens, + GooString *fileName, int line) { + if (tokens->getLength() != 2) { + error(-1, "Bad 'initialZoom' config file command (%s:%d)", + fileName->getCString(), line); + return; + } + delete initialZoom; + initialZoom = ((GooString *)tokens->get(1))->copy(); +} + +void GlobalParams::parseCommand(char *cmdName, GooString **val, + GooList *tokens, GooString *fileName, int line) { + if (tokens->getLength() != 2) { + error(-1, "Bad '%s' config file command (%s:%d)", + cmdName, fileName->getCString(), line); + return; + } + if (*val) { + delete *val; + } + *val = ((GooString *)tokens->get(1))->copy(); +} + +void GlobalParams::parseYesNo(char *cmdName, GBool *flag, + GooList *tokens, GooString *fileName, int line) { + GooString *tok; + + if (tokens->getLength() != 2) { + error(-1, "Bad '%s' config file command (%s:%d)", + cmdName, fileName->getCString(), line); + return; + } + tok = (GooString *)tokens->get(1); + if (!parseYesNo2(tok->getCString(), flag)) { + error(-1, "Bad '%s' config file command (%s:%d)", + cmdName, fileName->getCString(), line); + } +} + +GBool GlobalParams::parseYesNo2(char *token, GBool *flag) { + if (!strcmp(token, "yes")) { + *flag = gTrue; + } else if (!strcmp(token, "no")) { + *flag = gFalse; + } else { + return gFalse; + } + return gTrue; +} + +GlobalParams::~GlobalParams() { + GooHashIter *iter; + GooString *key; + GooList *list; + + freeBuiltinFontTables(); + + delete macRomanReverseMap; + + delete baseDir; + delete nameToUnicode; + deleteGooHash(cidToUnicodes, GooString); + deleteGooHash(unicodeToUnicodes, GooString); + deleteGooHash(residentUnicodeMaps, UnicodeMap); + deleteGooHash(unicodeMaps, GooString); + deleteGooList(toUnicodeDirs, GooString); + deleteGooHash(displayFonts, DisplayFontParam); + if (psFile) { + delete psFile; + } + deleteGooHash(psFonts, PSFontParam); + deleteGooList(psNamedFonts16, PSFontParam); + deleteGooList(psFonts16, PSFontParam); + delete textEncoding; + deleteGooList(fontDirs, GooString); + delete initialZoom; + if (urlCommand) { + delete urlCommand; + } + if (movieCommand) { + delete movieCommand; + } + + cMapDirs->startIter(&iter); + while (cMapDirs->getNext(&iter, &key, (void **)&list)) { + deleteGooList(list, GooString); + } + delete cMapDirs; + + delete cidToUnicodeCache; + delete unicodeToUnicodeCache; + delete unicodeMapCache; + delete cMapCache; + +#ifdef ENABLE_PLUGINS + delete securityHandlers; + deleteGooList(plugins, Plugin); +#endif + +#if MULTITHREADED + gDestroyMutex(&mutex); + gDestroyMutex(&unicodeMapCacheMutex); + gDestroyMutex(&cMapCacheMutex); +#endif +} + +//------------------------------------------------------------------------ + +void GlobalParams::setBaseDir(char *dir) { + delete baseDir; + baseDir = new GooString(dir); +} + +//------------------------------------------------------------------------ +// accessors +//------------------------------------------------------------------------ + +CharCode GlobalParams::getMacRomanCharCode(char *charName) { + // no need to lock - macRomanReverseMap is constant + return macRomanReverseMap->lookup(charName); +} + +GooString *GlobalParams::getBaseDir() { + GooString *s; + + lockGlobalParams; + s = baseDir->copy(); + unlockGlobalParams; + return s; +} + +Unicode GlobalParams::mapNameToUnicode(char *charName) { + // no need to lock - nameToUnicode is constant + return nameToUnicode->lookup(charName); +} + +UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) { + UnicodeMap *map; + + lockGlobalParams; + map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName); + unlockGlobalParams; + if (map) { + map->incRefCnt(); + } + return map; +} + +FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) { + GooString *fileName; + FILE *f; + + lockGlobalParams; + if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) { + f = fopen(fileName->getCString(), "r"); + } else { + f = NULL; + } + unlockGlobalParams; + return f; +} + +FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) { + GooList *list; + GooString *dir; + GooString *fileName; + FILE *f; + int i; + + lockGlobalParams; + if (!(list = (GooList *)cMapDirs->lookup(collection))) { + unlockGlobalParams; + return NULL; + } + for (i = 0; i < list->getLength(); ++i) { + dir = (GooString *)list->get(i); + fileName = appendToPath(dir->copy(), cMapName->getCString()); + f = fopen(fileName->getCString(), "r"); + delete fileName; + if (f) { + unlockGlobalParams; + return f; + } + } + unlockGlobalParams; + return NULL; +} + +FILE *GlobalParams::findToUnicodeFile(GooString *name) { + GooString *dir, *fileName; + FILE *f; + int i; + + lockGlobalParams; + for (i = 0; i < toUnicodeDirs->getLength(); ++i) { + dir = (GooString *)toUnicodeDirs->get(i); + fileName = appendToPath(dir->copy(), name->getCString()); + f = fopen(fileName->getCString(), "r"); + delete fileName; + if (f) { + unlockGlobalParams; + return f; + } + } + unlockGlobalParams; + return NULL; +} + +GBool findModifier(const char *name, const char *modifier, const char **start) +{ + const char *match; + + if (name == NULL) + return gFalse; + + match = strstr(name, modifier); + if (match) { + if (*start == NULL || match < *start) + *start = match; + return gTrue; + } + else { + return gFalse; + } +} + +#ifdef HAVE_FONTCONFIG_H +static FcPattern *buildFcPattern(GfxFont *font) +{ + int weight = FC_WEIGHT_NORMAL, + slant = FC_SLANT_ROMAN, + width = FC_WIDTH_NORMAL, + spacing = FC_PROPORTIONAL; + bool deleteFamily = false; + char *family, *name, *lang, *modifiers; + const char *start; + FcPattern *p; + + // this is all heuristics will be overwritten if font had proper info + name = font->getName()->getCString(); + + modifiers = strchr (name, ','); + if (modifiers == NULL) + modifiers = strchr (name, '-'); + + // remove the - from the names, for some reason, Fontconfig does not + // understand "MS-Mincho" but does with "MS Mincho" + int len = strlen(name); + for (int i = 0; i < len; i++) + name[i] = (name[i] == '-' ? ' ' : name[i]); + + start = NULL; + findModifier(modifiers, "Regular", &start); + findModifier(modifiers, "Roman", &start); + + if (findModifier(modifiers, "Oblique", &start)) + slant = FC_SLANT_OBLIQUE; + if (findModifier(modifiers, "Italic", &start)) + slant = FC_SLANT_ITALIC; + if (findModifier(modifiers, "Bold", &start)) + weight = FC_WEIGHT_BOLD; + if (findModifier(modifiers, "Light", &start)) + weight = FC_WEIGHT_LIGHT; + if (findModifier(modifiers, "Condensed", &start)) + width = FC_WIDTH_CONDENSED; + + if (start) { + // There have been "modifiers" in the name, crop them to obtain + // the family name + family = new char[len+1]; + strcpy(family, name); + int pos = (modifiers - name); + family[pos] = '\0'; + deleteFamily = true; + } + else { + family = name; + } + + // use font flags + if (font->isFixedWidth()) + spacing = FC_MONO; + if (font->isBold()) + weight = FC_WEIGHT_BOLD; + if (font->isItalic()) + slant = FC_SLANT_ITALIC; + + // if the FontDescriptor specified a family name use it + if (font->getFamily()) { + if (deleteFamily) { + delete[] family; + deleteFamily = false; + } + family = font->getFamily()->getCString(); + } + + // if the FontDescriptor specified a weight use it + switch (font -> getWeight()) + { + case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break; + case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break; + case GfxFont::W300: weight = FC_WEIGHT_BOOK; break; + case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break; + case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break; + case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break; + case GfxFont::W700: weight = FC_WEIGHT_BOLD; break; + case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break; + case GfxFont::W900: weight = FC_WEIGHT_BLACK; break; + default: break; + } + + // if the FontDescriptor specified a width use it + switch (font -> getStretch()) + { + case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break; + case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break; + case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break; + case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break; + case GfxFont::Normal: width = FC_WIDTH_NORMAL; break; + case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break; + case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break; + case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break; + case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break; + default: break; + } + + // find the language we want the font to support + if (font->isCIDFont()) + { + GooString *collection = ((GfxCIDFont *)font)->getCollection(); + if (collection) + { + if (strcmp(collection->getCString(), "Adobe-GB1") == 0) + lang = "zh-cn"; // Simplified Chinese + else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0) + lang = "zh-tw"; // Traditional Chinese + else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0) + lang = "ja"; // Japanese + else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0) + lang = "ja"; // Japanese + else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0) + lang = "ko"; // Korean + else if (strcmp(collection->getCString(), "Adobe-UCS") == 0) + lang = "xx"; + else if (strcmp(collection->getCString(), "Adobe-Identity") == 0) + lang = "xx"; + else + { + error(-1, "Unknown CID font collection, please report to poppler bugzilla."); + lang = "xx"; + } + } + else lang = "xx"; + } + else lang = "xx"; + + p = FcPatternBuild(NULL, + FC_FAMILY, FcTypeString, family, + FC_SLANT, FcTypeInteger, slant, + FC_WEIGHT, FcTypeInteger, weight, + FC_WIDTH, FcTypeInteger, width, + FC_SPACING, FcTypeInteger, spacing, + FC_LANG, FcTypeString, lang, + NULL); + if (deleteFamily) + delete[] family; + return p; +} +#endif + +/* if you can't or don't want to use Fontconfig, you need to implement + this function for your platform. For Windows, it's in GlobalParamsWin.cc +*/ +#ifdef HAVE_FONTCONFIG_H +DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) { + DisplayFontParam *dfp; + FcPattern *p=0; + + GooString *fontName = font->getName(); + if (!fontName) return NULL; + + lockGlobalParams; + dfp = (DisplayFontParam *)displayFonts->lookup(fontName); + if (!dfp) + { + FcChar8* s; + char * ext; + FcResult res; + FcFontSet *set; + int i; + p = buildFcPattern(font); + + if (!p) + goto fin; + FcConfigSubstitute(FCcfg, p, FcMatchPattern); + FcDefaultSubstitute(p); + set = FcFontSort(FCcfg, p, FcFalse, NULL, &res); + if (!set) + goto fin; + for (i = 0; i < set->nfont; ++i) + { + res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s); + if (res != FcResultMatch || !s) + continue; + ext = strrchr((char*)s,'.'); + if (!ext) + continue; + if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4)) + { + dfp = new DisplayFontParam(fontName->copy(), displayFontTT); + dfp->tt.fileName = new GooString((char*)s); + FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex)); + } + else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) + { + dfp = new DisplayFontParam(fontName->copy(), displayFontT1); + dfp->t1.fileName = new GooString((char*)s); + } + else + continue; + displayFonts->add(dfp->name,dfp); + break; + } + FcFontSetDestroy(set); + } +fin: + if (p) + FcPatternDestroy(p); + + unlockGlobalParams; + return dfp; +} +#endif + +GooString *GlobalParams::getPSFile() { + GooString *s; + + lockGlobalParams; + s = psFile ? psFile->copy() : (GooString *)NULL; + unlockGlobalParams; + return s; +} + +int GlobalParams::getPSPaperWidth() { + int w; + + lockGlobalParams; + w = psPaperWidth; + unlockGlobalParams; + return w; +} + +int GlobalParams::getPSPaperHeight() { + int h; + + lockGlobalParams; + h = psPaperHeight; + unlockGlobalParams; + return h; +} + +void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) { + lockGlobalParams; + *llx = psImageableLLX; + *lly = psImageableLLY; + *urx = psImageableURX; + *ury = psImageableURY; + unlockGlobalParams; +} + +GBool GlobalParams::getPSCrop() { + GBool f; + + lockGlobalParams; + f = psCrop; + unlockGlobalParams; + return f; +} + +GBool GlobalParams::getPSExpandSmaller() { + GBool f; + + lockGlobalParams; + f = psExpandSmaller; + unlockGlobalParams; + return f; +} + +GBool GlobalParams::getPSShrinkLarger() { + GBool f; + + lockGlobalParams; + f = psShrinkLarger; + unlockGlobalParams; + return f; +} + +GBool GlobalParams::getPSCenter() { + GBool f; + + lockGlobalParams; + f = psCenter; + unlockGlobalParams; + return f; +} + +GBool GlobalParams::getPSDuplex() { + GBool d; + + lockGlobalParams; + d = psDuplex; + unlockGlobalParams; + return d; +} + +PSLevel GlobalParams::getPSLevel() { + PSLevel level; + + lockGlobalParams; + level = psLevel; + unlockGlobalParams; + return level; +} + +PSFontParam *GlobalParams::getPSFont(GooString *fontName) { + PSFontParam *p; + + lockGlobalParams; + p = (PSFontParam *)psFonts->lookup(fontName); + unlockGlobalParams; + return p; +} + +PSFontParam *GlobalParams::getPSFont16(GooString *fontName, + GooString *collection, int wMode) { + PSFontParam *p; + int i; + + lockGlobalParams; + p = NULL; + if (fontName) { + for (i = 0; i < psNamedFonts16->getLength(); ++i) { + p = (PSFontParam *)psNamedFonts16->get(i); + if (!p->pdfFontName->cmp(fontName) && + p->wMode == wMode) { + break; + } + p = NULL; + } + } + if (!p && collection) { + for (i = 0; i < psFonts16->getLength(); ++i) { + p = (PSFontParam *)psFonts16->get(i); + if (!p->pdfFontName->cmp(collection) && + p->wMode == wMode) { + break; + } + p = NULL; + } + } + unlockGlobalParams; + return p; +} + +GBool GlobalParams::getPSEmbedType1() { + GBool e; + + lockGlobalParams; + e = psEmbedType1; + unlockGlobalParams; + return e; +} + +GBool GlobalParams::getPSEmbedTrueType() { + GBool e; + + lockGlobalParams; + e = psEmbedTrueType; + unlockGlobalParams; + return e; +} + +GBool GlobalParams::getPSEmbedCIDPostScript() { + GBool e; + + lockGlobalParams; + e = psEmbedCIDPostScript; + unlockGlobalParams; + return e; +} + +GBool GlobalParams::getPSEmbedCIDTrueType() { + GBool e; + + lockGlobalParams; + e = psEmbedCIDTrueType; + unlockGlobalParams; + return e; +} + +GBool GlobalParams::getPSOPI() { + GBool opi; + + lockGlobalParams; + opi = psOPI; + unlockGlobalParams; + return opi; +} + +GBool GlobalParams::getPSASCIIHex() { + GBool ah; + + lockGlobalParams; + ah = psASCIIHex; + unlockGlobalParams; + return ah; +} + +GooString *GlobalParams::getTextEncodingName() { + GooString *s; + + lockGlobalParams; + s = textEncoding->copy(); + unlockGlobalParams; + return s; +} + +EndOfLineKind GlobalParams::getTextEOL() { + EndOfLineKind eol; + + lockGlobalParams; + eol = textEOL; + unlockGlobalParams; + return eol; +} + +GBool GlobalParams::getTextPageBreaks() { + GBool pageBreaks; + + lockGlobalParams; + pageBreaks = textPageBreaks; + unlockGlobalParams; + return pageBreaks; +} + +GBool GlobalParams::getTextKeepTinyChars() { + GBool tiny; + + lockGlobalParams; + tiny = textKeepTinyChars; + unlockGlobalParams; + return tiny; +} + +GooString *GlobalParams::findFontFile(GooString *fontName, char **exts) { + GooString *dir, *fileName; + char **ext; + FILE *f; + int i; + + lockGlobalParams; + for (i = 0; i < fontDirs->getLength(); ++i) { + dir = (GooString *)fontDirs->get(i); + for (ext = exts; *ext; ++ext) { + fileName = appendToPath(dir->copy(), fontName->getCString()); + fileName->append(*ext); + if ((f = fopen(fileName->getCString(), "rb"))) { + fclose(f); + unlockGlobalParams; + return fileName; + } + delete fileName; + } + } + unlockGlobalParams; + return NULL; +} + +GooString *GlobalParams::getInitialZoom() { + GooString *s; + + lockGlobalParams; + s = initialZoom->copy(); + unlockGlobalParams; + return s; +} + +GBool GlobalParams::getContinuousView() { + GBool f; + + lockGlobalParams; + f = continuousView; + unlockGlobalParams; + return f; +} + +GBool GlobalParams::getEnableT1lib() { + GBool f; + + lockGlobalParams; + f = enableT1lib; + unlockGlobalParams; + return f; +} + +GBool GlobalParams::getEnableFreeType() { + GBool f; + + lockGlobalParams; + f = enableFreeType; + unlockGlobalParams; + return f; +} + + +GBool GlobalParams::getAntialias() { + GBool f; + + lockGlobalParams; + f = antialias; + unlockGlobalParams; + return f; +} + +GBool GlobalParams::getMapNumericCharNames() { + GBool map; + + lockGlobalParams; + map = mapNumericCharNames; + unlockGlobalParams; + return map; +} + +GBool GlobalParams::getPrintCommands() { + GBool p; + + lockGlobalParams; + p = printCommands; + unlockGlobalParams; + return p; +} + +GBool GlobalParams::getProfileCommands() { + GBool p; + + lockGlobalParams; + p = profileCommands; + unlockGlobalParams; + return p; +} + +GBool GlobalParams::getErrQuiet() { + GBool q; + + lockGlobalParams; + q = errQuiet; + unlockGlobalParams; + return q; +} + +CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) { + GooString *fileName; + CharCodeToUnicode *ctu; + + lockGlobalParams; + if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) { + if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) && + (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) { + cidToUnicodeCache->add(ctu); + } + } + unlockGlobalParams; + return ctu; +} + +CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) { + CharCodeToUnicode *ctu; + GooHashIter *iter; + GooString *fontPattern, *fileName; + + lockGlobalParams; + fileName = NULL; + unicodeToUnicodes->startIter(&iter); + while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) { + if (strstr(fontName->getCString(), fontPattern->getCString())) { + unicodeToUnicodes->killIter(&iter); + break; + } + fileName = NULL; + } + if (fileName) { + if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) { + if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) { + unicodeToUnicodeCache->add(ctu); + } + } + } else { + ctu = NULL; + } + unlockGlobalParams; + return ctu; +} + +UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) { + return getUnicodeMap2(encodingName); +} + +UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) { + UnicodeMap *map; + + if (!(map = getResidentUnicodeMap(encodingName))) { + lockUnicodeMapCache; + map = unicodeMapCache->getUnicodeMap(encodingName); + unlockUnicodeMapCache; + } + return map; +} + +CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName) { + CMap *cMap; + + lockCMapCache; + cMap = cMapCache->getCMap(collection, cMapName); + unlockCMapCache; + return cMap; +} + +UnicodeMap *GlobalParams::getTextEncoding() { + return getUnicodeMap2(textEncoding); +} + +//------------------------------------------------------------------------ +// functions to set parameters +//------------------------------------------------------------------------ + +void GlobalParams::setPSFile(char *file) { + lockGlobalParams; + if (psFile) { + delete psFile; + } + psFile = new GooString(file); + unlockGlobalParams; +} + +GBool GlobalParams::setPSPaperSize(char *size) { + lockGlobalParams; + if (!strcmp(size, "match")) { + psPaperWidth = psPaperHeight = -1; + } else if (!strcmp(size, "letter")) { + psPaperWidth = 612; + psPaperHeight = 792; + } else if (!strcmp(size, "legal")) { + psPaperWidth = 612; + psPaperHeight = 1008; + } else if (!strcmp(size, "A4")) { + psPaperWidth = 595; + psPaperHeight = 842; + } else if (!strcmp(size, "A3")) { + psPaperWidth = 842; + psPaperHeight = 1190; + } else { + unlockGlobalParams; + return gFalse; + } + psImageableLLX = psImageableLLY = 0; + psImageableURX = psPaperWidth; + psImageableURY = psPaperHeight; + unlockGlobalParams; + return gTrue; +} + +void GlobalParams::setPSPaperWidth(int width) { + lockGlobalParams; + psPaperWidth = width; + psImageableLLX = 0; + psImageableURX = psPaperWidth; + unlockGlobalParams; +} + +void GlobalParams::setPSPaperHeight(int height) { + lockGlobalParams; + psPaperHeight = height; + psImageableLLY = 0; + psImageableURY = psPaperHeight; + unlockGlobalParams; +} + +void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) { + lockGlobalParams; + psImageableLLX = llx; + psImageableLLY = lly; + psImageableURX = urx; + psImageableURY = ury; + unlockGlobalParams; +} + +void GlobalParams::setPSCrop(GBool crop) { + lockGlobalParams; + psCrop = crop; + unlockGlobalParams; +} + +void GlobalParams::setPSExpandSmaller(GBool expand) { + lockGlobalParams; + psExpandSmaller = expand; + unlockGlobalParams; +} + +void GlobalParams::setPSShrinkLarger(GBool shrink) { + lockGlobalParams; + psShrinkLarger = shrink; + unlockGlobalParams; +} + +void GlobalParams::setPSCenter(GBool center) { + lockGlobalParams; + psCenter = center; + unlockGlobalParams; +} + +void GlobalParams::setPSDuplex(GBool duplex) { + lockGlobalParams; + psDuplex = duplex; + unlockGlobalParams; +} + +void GlobalParams::setPSLevel(PSLevel level) { + lockGlobalParams; + psLevel = level; + unlockGlobalParams; +} + +void GlobalParams::setPSEmbedType1(GBool embed) { + lockGlobalParams; + psEmbedType1 = embed; + unlockGlobalParams; +} + +void GlobalParams::setPSEmbedTrueType(GBool embed) { + lockGlobalParams; + psEmbedTrueType = embed; + unlockGlobalParams; +} + +void GlobalParams::setPSEmbedCIDPostScript(GBool embed) { + lockGlobalParams; + psEmbedCIDPostScript = embed; + unlockGlobalParams; +} + +void GlobalParams::setPSEmbedCIDTrueType(GBool embed) { + lockGlobalParams; + psEmbedCIDTrueType = embed; + unlockGlobalParams; +} + +void GlobalParams::setPSOPI(GBool opi) { + lockGlobalParams; + psOPI = opi; + unlockGlobalParams; +} + +void GlobalParams::setPSASCIIHex(GBool hex) { + lockGlobalParams; + psASCIIHex = hex; + unlockGlobalParams; +} + +void GlobalParams::setTextEncoding(char *encodingName) { + lockGlobalParams; + delete textEncoding; + textEncoding = new GooString(encodingName); + unlockGlobalParams; +} + +GBool GlobalParams::setTextEOL(char *s) { + lockGlobalParams; + if (!strcmp(s, "unix")) { + textEOL = eolUnix; + } else if (!strcmp(s, "dos")) { + textEOL = eolDOS; + } else if (!strcmp(s, "mac")) { + textEOL = eolMac; + } else { + unlockGlobalParams; + return gFalse; + } + unlockGlobalParams; + return gTrue; +} + +void GlobalParams::setTextPageBreaks(GBool pageBreaks) { + lockGlobalParams; + textPageBreaks = pageBreaks; + unlockGlobalParams; +} + +void GlobalParams::setTextKeepTinyChars(GBool keep) { + lockGlobalParams; + textKeepTinyChars = keep; + unlockGlobalParams; +} + +void GlobalParams::setInitialZoom(char *s) { + lockGlobalParams; + delete initialZoom; + initialZoom = new GooString(s); + unlockGlobalParams; +} + +void GlobalParams::setContinuousView(GBool cont) { + lockGlobalParams; + continuousView = cont; + unlockGlobalParams; +} + +GBool GlobalParams::setEnableT1lib(char *s) { + GBool ok; + + lockGlobalParams; + ok = parseYesNo2(s, &enableT1lib); + unlockGlobalParams; + return ok; +} + +GBool GlobalParams::setEnableFreeType(char *s) { + GBool ok; + + lockGlobalParams; + ok = parseYesNo2(s, &enableFreeType); + unlockGlobalParams; + return ok; +} + + +GBool GlobalParams::setAntialias(char *s) { + GBool ok; + + lockGlobalParams; + ok = parseYesNo2(s, &antialias); + unlockGlobalParams; + return ok; +} + +void GlobalParams::setMapNumericCharNames(GBool map) { + lockGlobalParams; + mapNumericCharNames = map; + unlockGlobalParams; +} + +void GlobalParams::setPrintCommands(GBool printCommandsA) { + lockGlobalParams; + printCommands = printCommandsA; + unlockGlobalParams; +} + +void GlobalParams::setProfileCommands(GBool profileCommandsA) { + lockGlobalParams; + profileCommands = profileCommandsA; + unlockGlobalParams; +} + +void GlobalParams::setErrQuiet(GBool errQuietA) { + lockGlobalParams; + errQuiet = errQuietA; + unlockGlobalParams; +} + +void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) { +#ifdef ENABLE_PLUGINS + lockGlobalParams; + securityHandlers->append(handler); + unlockGlobalParams; +#endif +} + +XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) { +#ifdef ENABLE_PLUGINS + XpdfSecurityHandler *hdlr; + int i; + + lockGlobalParams; + for (i = 0; i < securityHandlers->getLength(); ++i) { + hdlr = (XpdfSecurityHandler *)securityHandlers->get(i); + if (!stricmp(hdlr->name, name)) { + unlockGlobalParams; + return hdlr; + } + } + unlockGlobalParams; + + if (!loadPlugin("security", name)) { + return NULL; + } + + lockGlobalParams; + for (i = 0; i < securityHandlers->getLength(); ++i) { + hdlr = (XpdfSecurityHandler *)securityHandlers->get(i); + if (!strcmp(hdlr->name, name)) { + unlockGlobalParams; + return hdlr; + } + } + unlockGlobalParams; +#endif + + return NULL; +} + +#ifdef ENABLE_PLUGINS +//------------------------------------------------------------------------ +// plugins +//------------------------------------------------------------------------ + +GBool GlobalParams::loadPlugin(char *type, char *name) { + Plugin *plugin; + + if (!(plugin = Plugin::load(type, name))) { + return gFalse; + } + lockGlobalParams; + plugins->append(plugin); + unlockGlobalParams; + return gTrue; +} + +#endif // ENABLE_PLUGINS diff --git a/rosapps/smartpdf/poppler/poppler/GlobalParams.h b/rosapps/smartpdf/poppler/poppler/GlobalParams.h new file mode 100644 index 00000000000..5010535d320 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/GlobalParams.h @@ -0,0 +1,355 @@ +//======================================================================== +// +// GlobalParams.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef GLOBALPARAMS_H +#define GLOBALPARAMS_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "poppler-config.h" +#include +#include +#ifdef HAVE_FONTCONFIG_H +#include +#endif +#include "goo/gtypes.h" +#include "CharTypes.h" + +#if MULTITHREADED +#include +#endif + +class GooString; +class GooList; +class GooHash; +class NameToCharCode; +class CharCodeToUnicode; +class CharCodeToUnicodeCache; +class UnicodeMap; +class UnicodeMapCache; +class CMap; +class CMapCache; +struct XpdfSecurityHandler; +class GlobalParams; +class GfxFont; + +//------------------------------------------------------------------------ + +// The global parameters object. +extern GlobalParams *globalParams; + +//------------------------------------------------------------------------ + +enum DisplayFontParamKind { + displayFontT1, + displayFontTT +}; + +struct DisplayFontParamT1 { + GooString *fileName; +}; + +struct DisplayFontParamTT { + GooString *fileName; + int faceIndex; +}; + +class DisplayFontParam { +public: + + GooString *name; // font name for 8-bit fonts and named + // CID fonts; collection name for + // generic CID fonts + DisplayFontParamKind kind; + union { + DisplayFontParamT1 t1; + DisplayFontParamTT tt; + }; + + DisplayFontParam(GooString *nameA, DisplayFontParamKind kindA); + void setFileName(GooString *fileNameA) { + if (displayFontT1 == kind) + t1.fileName = fileNameA; + else { + assert(displayFontTT == kind); + tt.fileName = fileNameA; + } + } + ~DisplayFontParam(); +}; + +//------------------------------------------------------------------------ + +class PSFontParam { +public: + + GooString *pdfFontName; // PDF font name for 8-bit fonts and + // named 16-bit fonts; char collection + // name for generic 16-bit fonts + int wMode; // writing mode (0=horiz, 1=vert) for + // 16-bit fonts + GooString *psFontName; // PostScript font name + GooString *encoding; // encoding, for 16-bit fonts only + + PSFontParam(GooString *pdfFontNameA, int wModeA, + GooString *psFontNameA, GooString *encodingA); + ~PSFontParam(); +}; + +//------------------------------------------------------------------------ + +enum PSLevel { + psLevel1, + psLevel1Sep, + psLevel2, + psLevel2Sep, + psLevel3, + psLevel3Sep +}; + +//------------------------------------------------------------------------ + +enum EndOfLineKind { + eolUnix, // LF + eolDOS, // CR+LF + eolMac // CR +}; + +//------------------------------------------------------------------------ + +class GlobalParams { +public: + + // Initialize the global parameters by attempting to read a config + // file. + GlobalParams(char *cfgFileName); + + ~GlobalParams(); + + void setBaseDir(char *dir); + +#ifndef HAVE_FONTCONFIG_H + void setupBaseFonts(char *dir); +#endif + + //----- accessors + + CharCode getMacRomanCharCode(char *charName); + + GooString *getBaseDir(); + Unicode mapNameToUnicode(char *charName); + UnicodeMap *getResidentUnicodeMap(GooString *encodingName); + FILE *getUnicodeMapFile(GooString *encodingName); + FILE *findCMapFile(GooString *collection, GooString *cMapName); + FILE *findToUnicodeFile(GooString *name); + DisplayFontParam *getDisplayFont(GfxFont *font); + GooString *getPSFile(); + int getPSPaperWidth(); + int getPSPaperHeight(); + void getPSImageableArea(int *llx, int *lly, int *urx, int *ury); + GBool getPSDuplex(); + GBool getPSCrop(); + GBool getPSExpandSmaller(); + GBool getPSShrinkLarger(); + GBool getPSCenter(); + PSLevel getPSLevel(); + PSFontParam *getPSFont(GooString *fontName); + PSFontParam *getPSFont16(GooString *fontName, GooString *collection, int wMode); + GBool getPSEmbedType1(); + GBool getPSEmbedTrueType(); + GBool getPSEmbedCIDPostScript(); + GBool getPSEmbedCIDTrueType(); + GBool getPSOPI(); + GBool getPSASCIIHex(); + GooString *getTextEncodingName(); + EndOfLineKind getTextEOL(); + GBool getTextPageBreaks(); + GBool getTextKeepTinyChars(); + GooString *findFontFile(GooString *fontName, char **exts); + GooString *getInitialZoom(); + GBool getContinuousView(); + GBool getEnableT1lib(); + GBool getEnableFreeType(); + GBool getAntialias(); + GooString *getURLCommand() { return urlCommand; } + GooString *getMovieCommand() { return movieCommand; } + GBool getMapNumericCharNames(); + GBool getPrintCommands(); + GBool getProfileCommands(); + GBool getErrQuiet(); + + CharCodeToUnicode *getCIDToUnicode(GooString *collection); + CharCodeToUnicode *getUnicodeToUnicode(GooString *fontName); + UnicodeMap *getUnicodeMap(GooString *encodingName); + CMap *getCMap(GooString *collection, GooString *cMapName); + UnicodeMap *getTextEncoding(); +#ifdef ENABLE_PLUGINS + GBool loadPlugin(char *type, char *name); +#endif + + //----- functions to set parameters + + void setPSFile(char *file); + GBool setPSPaperSize(char *size); + void setPSPaperWidth(int width); + void setPSPaperHeight(int height); + void setPSImageableArea(int llx, int lly, int urx, int ury); + void setPSDuplex(GBool duplex); + void setPSCrop(GBool crop); + void setPSExpandSmaller(GBool expand); + void setPSShrinkLarger(GBool shrink); + void setPSCenter(GBool center); + void setPSLevel(PSLevel level); + void setPSEmbedType1(GBool embed); + void setPSEmbedTrueType(GBool embed); + void setPSEmbedCIDPostScript(GBool embed); + void setPSEmbedCIDTrueType(GBool embed); + void setPSOPI(GBool opi); + void setPSASCIIHex(GBool hex); + void setTextEncoding(char *encodingName); + GBool setTextEOL(char *s); + void setTextPageBreaks(GBool pageBreaks); + void setTextKeepTinyChars(GBool keep); + void setInitialZoom(char *s); + void setContinuousView(GBool cont); + GBool setEnableT1lib(char *s); + GBool setEnableFreeType(char *s); + GBool setAntialias(char *s); + void setMapNumericCharNames(GBool map); + void setPrintCommands(GBool printCommandsA); + void setProfileCommands(GBool profileCommandsA); + void setErrQuiet(GBool errQuietA); + + //----- security handlers + + void addSecurityHandler(XpdfSecurityHandler *handler); + XpdfSecurityHandler *getSecurityHandler(char *name); + +private: + + void parseFile(GooString *fileName, FILE *f); + void parseNameToUnicode(GooString *name); + void parseCIDToUnicode(GooList *tokens, GooString *fileName, int line); + void parseUnicodeToUnicode(GooList *tokens, GooString *fileName, int line); + void parseUnicodeMap(GooList *tokens, GooString *fileName, int line); + void parseCMapDir(GooList *tokens, GooString *fileName, int line); + void parseToUnicodeDir(GooList *tokens, GooString *fileName, int line); + void parsePSFile(GooList *tokens, GooString *fileName, int line); + void parsePSPaperSize(GooList *tokens, GooString *fileName, int line); + void parsePSImageableArea(GooList *tokens, GooString *fileName, int line); + void parsePSLevel(GooList *tokens, GooString *fileName, int line); + void parsePSFont(GooList *tokens, GooString *fileName, int line); + void parsePSFont16(char *cmdName, GooList *fontList, + GooList *tokens, GooString *fileName, int line); + void parseTextEncoding(GooList *tokens, GooString *fileName, int line); + void parseTextEOL(GooList *tokens, GooString *fileName, int line); + void parseFontDir(GooList *tokens, GooString *fileName, int line); + void parseInitialZoom(GooList *tokens, GooString *fileName, int line); + void parseCommand(char *cmdName, GooString **val, + GooList *tokens, GooString *fileName, int line); + void parseYesNo(char *cmdName, GBool *flag, + GooList *tokens, GooString *fileName, int line); + GBool parseYesNo2(char *token, GBool *flag); + UnicodeMap *getUnicodeMap2(GooString *encodingName); + + void scanEncodingDirs(); + void addCIDToUnicode(GooString *collection, GooString *fileName); + void addUnicodeMap(GooString *encodingName, GooString *fileName); + void addCMapDir(GooString *collection, GooString *dir); + + //----- static tables + + NameToCharCode * // mapping from char name to + macRomanReverseMap; // MacRomanEncoding index + + //----- user-modifiable settings + + GooString *baseDir; // base directory - for plugins, etc. + NameToCharCode * // mapping from char name to Unicode + nameToUnicode; + GooHash *cidToUnicodes; // files for mappings from char collections + // to Unicode, indexed by collection name + // [GooString] + GooHash *unicodeToUnicodes; // files for Unicode-to-Unicode mappings, + // indexed by font name pattern [GooString] + GooHash *residentUnicodeMaps; // mappings from Unicode to char codes, + // indexed by encoding name [UnicodeMap] + GooHash *unicodeMaps; // files for mappings from Unicode to char + // codes, indexed by encoding name [GooString] + GooHash *cMapDirs; // list of CMap dirs, indexed by collection + // name [GooList[GooString]] + GooList *toUnicodeDirs; // list of ToUnicode CMap dirs [GooString] + GooHash *displayFonts; // display font info, indexed by font name + // [DisplayFontParam] + GooString *psFile; // PostScript file or command (for xpdf) + int psPaperWidth; // paper size, in PostScript points, for + int psPaperHeight; // PostScript output + int psImageableLLX, // imageable area, in PostScript points, + psImageableLLY, // for PostScript output + psImageableURX, + psImageableURY; + GBool psCrop; // crop PS output to CropBox + GBool psExpandSmaller; // expand smaller pages to fill paper + GBool psShrinkLarger; // shrink larger pages to fit paper + GBool psCenter; // center pages on the paper + GBool psDuplex; // enable duplexing in PostScript? + PSLevel psLevel; // PostScript level to generate + GooHash *psFonts; // PostScript font info, indexed by PDF + // font name [PSFontParam] + GooList *psNamedFonts16; // named 16-bit fonts [PSFontParam] + GooList *psFonts16; // generic 16-bit fonts [PSFontParam] + GBool psEmbedType1; // embed Type 1 fonts? + GBool psEmbedTrueType; // embed TrueType fonts? + GBool psEmbedCIDPostScript; // embed CID PostScript fonts? + GBool psEmbedCIDTrueType; // embed CID TrueType fonts? + GBool psOPI; // generate PostScript OPI comments? + GBool psASCIIHex; // use ASCIIHex instead of ASCII85? + GooString *textEncoding; // encoding (unicodeMap) to use for text + // output + EndOfLineKind textEOL; // type of EOL marker to use for text + // output + GBool textPageBreaks; // insert end-of-page markers? + GBool textKeepTinyChars; // keep all characters in text output + GooList *fontDirs; // list of font dirs [GooString] + GooString *initialZoom; // initial zoom level + GBool continuousView; // continuous view mode + GBool enableT1lib; // t1lib enable flag + GBool enableFreeType; // FreeType enable flag + GBool antialias; // anti-aliasing enable flag + GooString *urlCommand; // command executed for URL links + GooString *movieCommand; // command executed for movie annotations + GBool mapNumericCharNames; // map numeric char names (from font subsets)? + GBool printCommands; // print the drawing commands + GBool profileCommands; // profile the drawing commands + GBool errQuiet; // suppress error messages? + + CharCodeToUnicodeCache *cidToUnicodeCache; + CharCodeToUnicodeCache *unicodeToUnicodeCache; + UnicodeMapCache *unicodeMapCache; + CMapCache *cMapCache; + +#ifdef HAVE_FONTCONFIG_H + FcConfig *FCcfg; +#endif + +#ifdef ENABLE_PLUGINS + GList *plugins; // list of plugins [Plugin] + GList *securityHandlers; // list of loaded security handlers + // [XpdfSecurityHandler] +#endif + +#if MULTITHREADED + GooMutex mutex; + GooMutex unicodeMapCacheMutex; + GooMutex cMapCacheMutex; +#endif +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/GlobalParamsWin.cc b/rosapps/smartpdf/poppler/poppler/GlobalParamsWin.cc new file mode 100644 index 00000000000..4689e69e123 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/GlobalParamsWin.cc @@ -0,0 +1,287 @@ +/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info) + but mostly based on xpdf code. + License: + +TODO: instead of a fixed mapping defined in displayFontTab, it could +scan the whole fonts directory, parse TTF files and build font +description for all fonts available in Windows. That's how GhostPDF (aka. mupdf) +works. +*/ + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include + +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "goo/GooHash.h" +#include "goo/gfile.h" +#include "Error.h" +#include "NameToCharCode.h" +#include "CharCodeToUnicode.h" +#include "UnicodeMap.h" +#include "CMap.h" +#include "BuiltinFontTables.h" +#include "FontEncodingTables.h" +#include "GlobalParams.h" +#include "GfxFont.h" + +#if MULTITHREADED +# define lockGlobalParams gLockMutex(&mutex) +# define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex) +# define lockCMapCache gLockMutex(&cMapCacheMutex) +# define unlockGlobalParams gUnlockMutex(&mutex) +# define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex) +# define unlockCMapCache gUnlockMutex(&cMapCacheMutex) +#else +# define lockGlobalParams +# define lockUnicodeMapCache +# define lockCMapCache +# define unlockGlobalParams +# define unlockUnicodeMapCache +# define unlockCMapCache +#endif + +#define DEFAULT_SUBSTITUTE_FONT "Helvetica" + +static struct { + char *name; + char *t1FileName; + char *ttFileName; +} displayFontTab[] = { + {"Courier", "n022003l.pfb", "cour.ttf"}, + {"Courier-Bold", "n022004l.pfb", "courbd.ttf"}, + {"Courier-BoldOblique", "n022024l.pfb", "courbi.ttf"}, + {"Courier-Oblique", "n022023l.pfb", "couri.ttf"}, + {"Helvetica", "n019003l.pfb", "arial.ttf"}, + {"Helvetica-Bold", "n019004l.pfb", "arialbd.ttf"}, + {"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf"}, + {"Helvetica-Oblique", "n019023l.pfb", "ariali.ttf"}, + // TODO: not sure if "symbol.ttf" is right + {"Symbol", "s050000l.pfb", "symbol.ttf"}, + {"Times-Bold", "n021004l.pfb", "timesbd.ttf"}, + {"Times-BoldItalic", "n021024l.pfb", "timesbi.ttf"}, + {"Times-Italic", "n021023l.pfb", "timesi.ttf"}, + {"Times-Roman", "n021003l.pfb", "times.ttf"}, + // TODO: not sure if "wingding.ttf" is right + {"ZapfDingbats", "d050000l.pfb", "wingding.ttf"}, + + // those seem to be frequently accessed by PDF files and I kind of guess + // which font file do the refer to + {"Palatino", NULL, "pala.ttf"}, + {"Palatino-Roman", NULL, "pala.ttf"}, + {"Palatino-Bold", NULL, "palab.ttf"}, + {"Palatino-Italic", NULL, "palai.ttf"}, + {"Palatino,Italic", NULL, "palai.ttf"}, + {"Palatino-BoldItalic", NULL, "palabi.ttf"}, + + {"ArialBlack", NULL, "arialbd.ttf"}, + + {"ArialNarrow", NULL, "arialn.ttf"}, + {"ArialNarrow,Bold", NULL, "arialnb.ttf"}, + {"ArialNarrow,Italic", NULL, "arialni.ttf"}, + {"ArialNarrow,BoldItalic", NULL, "arialnbi.ttf"}, + {"ArialNarrow-Bold", NULL, "arialnb.ttf"}, + {"ArialNarrow-Italic", NULL, "arialni.ttf"}, + {"ArialNarrow-BoldItalic", NULL, "arialnbi.ttf"}, + + {"HelveticaNarrow", NULL, "arialn.ttf"}, + {"HelveticaNarrow,Bold", NULL, "arialnb.ttf"}, + {"HelveticaNarrow,Italic", NULL, "arialni.ttf"}, + {"HelveticaNarrow,BoldItalic", NULL, "arialnbi.ttf"}, + {"HelveticaNarrow-Bold", NULL, "arialnb.ttf"}, + {"HelveticaNarrow-Italic", NULL, "arialni.ttf"}, + {"HelveticaNarrow-BoldItalic", NULL, "arialnbi.ttf"}, + + {"BookAntiqua", NULL, "bkant.ttf"}, + {"BookAntiqua,Bold", NULL, "bkant.ttf"}, + {"BookAntiqua,Italic", NULL, "bkant.ttf"}, + {"BookAntiqua,BoldItalic", NULL, "bkant.ttf"}, + {"BookAntiqua-Bold", NULL, "bkant.ttf"}, + {"BookAntiqua-Italic", NULL, "bkant.ttf"}, + {"BookAntiqua-BoldItalic", NULL, "bkant.ttf"}, + + {"Verdana", NULL, "verdana.ttf"}, + {"Verdana,Bold", NULL, "verdanab.ttf"}, + {"Verdana,Italic", NULL, "verdanai.ttf"}, + {"Verdana,BoldItalic", NULL, "verdanaz.ttf"}, + {"Verdana-Bold", NULL, "verdanab.ttf"}, + {"Verdana-Italic", NULL, "verdanai.ttf"}, + {"Verdana-BoldItalic", NULL, "verdanaz.ttf"}, + + {"Tahoma", NULL, "tahoma.ttf"}, + {"Tahoma,Bold", NULL, "tahomabd.ttf"}, + {"Tahoma,Italic", NULL, "tahoma.ttf"}, + {"Tahoma,BoldItalic", NULL, "tahomabd.ttf"}, + {"Tahoma-Bold", NULL, "tahomabd.ttf"}, + {"Tahoma-Italic", NULL, "tahoma.ttf"}, + {"Tahoma-BoldItalic", NULL, "tahomabd.ttf"}, + + {"CCRIKH+Verdana", NULL, "verdana.ttf"}, + {"CCRIKH+Verdana,Bold", NULL, "verdanab.ttf"}, + {"CCRIKH+Verdana,Italic", NULL, "verdanai.ttf"}, + {"CCRIKH+Verdana,BoldItalic", NULL, "verdanaz.ttf"}, + {"CCRIKH+Verdana-Bold", NULL, "verdanab.ttf"}, + {"CCRIKH+Verdana-Italic", NULL, "verdanai.ttf"}, + {"CCRIKH+Verdana-BoldItalic", NULL, "verdanaz.ttf"}, + + {"Georgia", NULL, "georgia.ttf"}, + {"Georgia,Bold", NULL, "georgiab.ttf"}, + {"Georgia,Italic", NULL, "georgiai.ttf"}, + {"Georgia,BoldItalic", NULL, "georgiaz.ttf"}, + {"Georgia-Bold", NULL, "georgiab.ttf"}, + {"Georgia-Italic", NULL, "georgiai.ttf"}, + {"Georgia-BoldItalic", NULL, "georgiaz.ttf"}, + + {NULL} +}; + +#define FONTS_SUBDIR "\\fonts" + +static void GetWindowsFontDir(char *winFontDir, int cbWinFontDirLen) +{ + BOOL (__stdcall *SHGetSpecialFolderPathFunc)(HWND hwndOwner, + LPTSTR lpszPath, + int nFolder, + BOOL fCreate); + HRESULT (__stdcall *SHGetFolderPathFunc)(HWND hwndOwner, + int nFolder, + HANDLE hToken, + DWORD dwFlags, + LPTSTR pszPath); + + // SHGetSpecialFolderPath isn't available in older versions of shell32.dll (Win95 and + // WinNT4), so do a dynamic load of ANSI versions. + winFontDir[0] = '\0'; + + HMODULE hLib = LoadLibrary(L"shell32.dll"); /* @note: "L" cast */ + if (hLib) { + SHGetFolderPathFunc = (HRESULT (__stdcall *)(HWND, int, HANDLE, DWORD, LPTSTR)) + GetProcAddress(hLib, "SHGetFolderPathA"); + if (SHGetFolderPathFunc) + (*SHGetFolderPathFunc)(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, (TCHAR*)winFontDir); /* @note: TCHAR* cast */ + + if (!winFontDir[0]) { + // Try an older function + SHGetSpecialFolderPathFunc = (BOOL (__stdcall *)(HWND, LPTSTR, int, BOOL)) + GetProcAddress(hLib, "SHGetSpecialFolderPathA"); + if (SHGetSpecialFolderPathFunc) + (*SHGetSpecialFolderPathFunc)(NULL, (TCHAR*)winFontDir, CSIDL_FONTS, FALSE); /* @note: TCHAR* cast */ + } + FreeLibrary(hLib); + } + if (winFontDir[0]) + return; + + // Try older DLL + hLib = LoadLibrary(L"SHFolder.dll"); /* @note: "L" cast */ + if (hLib) { + SHGetFolderPathFunc = (HRESULT (__stdcall *)(HWND, int, HANDLE, DWORD, LPTSTR)) + GetProcAddress(hLib, "SHGetFolderPathA"); + if (SHGetFolderPathFunc) + (*SHGetFolderPathFunc)(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, (TCHAR*)winFontDir); /* @note: TCHAR* cast */ + FreeLibrary(hLib); + } + if (winFontDir[0]) + return; + + // Everything else failed so the standard fonts directory. + GetWindowsDirectory((TCHAR*)winFontDir, cbWinFontDirLen); /* @note: TCHAR* cast */ + if (winFontDir[0]) { + strncat(winFontDir, FONTS_SUBDIR, cbWinFontDirLen); + winFontDir[cbWinFontDirLen-1] = 0; + } +} + +static bool FileExists(const char *path) +{ + FILE * f = fopen(path, "rb"); + if (f) { + fclose(f); + return true; + } + return false; +} + +static void AddFont(GooHash *displayFonts, char *fontName, GooString *fontPath, DisplayFontParamKind kind) +{ + DisplayFontParam *dfp = new DisplayFontParam(new GooString(fontName), kind); + dfp->setFileName(fontPath); + displayFonts->add(dfp->name, dfp); +} + +void GlobalParams::setupBaseFonts(char * dir) +{ + static bool baseFontsInitialized = false; + if (baseFontsInitialized) + return; + baseFontsInitialized = true; + + char winFontDir[MAX_PATH]; + GetWindowsFontDir(winFontDir, sizeof(winFontDir)); + + for (int i = 0; displayFontTab[i].name; ++i) { + char *fontName = displayFontTab[i].name; + if (displayFonts->lookup(fontName)) + continue; + + if (dir) { + GooString *fontPath = appendToPath(new GooString(dir), displayFontTab[i].t1FileName); + if (FileExists(fontPath->getCString())) { + AddFont(displayFonts, fontName, fontPath, displayFontT1); + continue; + } + delete fontPath; + } + + if (winFontDir[0] && displayFontTab[i].ttFileName) { + GooString *fontPath = appendToPath(new GooString(winFontDir), displayFontTab[i].ttFileName); + if (FileExists(fontPath->getCString())) { + AddFont(displayFonts, fontName, fontPath, displayFontTT); + continue; + } + delete fontPath; + } + + error(-1, "No display font for '%s'", fontName); + } +} + +static char *findSubstituteName(const char *origName) +{ + assert(origName); + if (!origName) return NULL; + /* TODO: try to at least guess bold/italic/bolditalic from the name */ + return DEFAULT_SUBSTITUTE_FONT; +} + +/* Windows implementation of external font matching code */ +DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) { + DisplayFontParam * dfp; + GooString * fontName = font->getName(); + char * substFontName = NULL; + + if (!fontName) return NULL; + lockGlobalParams; + setupBaseFonts(NULL); + dfp = (DisplayFontParam *)displayFonts->lookup(fontName); + if (!dfp) { + substFontName = findSubstituteName(fontName->getCString()); + error(-1, "Couldn't find a font for '%s', subst is '%s'", fontName->getCString(), substFontName); + dfp = (DisplayFontParam *)displayFonts->lookup(substFontName); + assert(dfp); + } + unlockGlobalParams; + return dfp; +} + diff --git a/rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.cc b/rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.cc new file mode 100644 index 00000000000..ec0778e64f4 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.cc @@ -0,0 +1,322 @@ +//======================================================================== +// +// JArithmeticDecoder.cc +// +// Copyright 2002-2004 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "Object.h" +#include "Stream.h" +#include "JArithmeticDecoder.h" + +//------------------------------------------------------------------------ +// JArithmeticDecoderStates +//------------------------------------------------------------------------ + +JArithmeticDecoderStats::JArithmeticDecoderStats(int contextSizeA) { + contextSize = contextSizeA; + cxTab = (Guchar *)gmallocn(contextSize, sizeof(Guchar)); + reset(); +} + +JArithmeticDecoderStats::~JArithmeticDecoderStats() { + gfree(cxTab); +} + +JArithmeticDecoderStats *JArithmeticDecoderStats::copy() { + JArithmeticDecoderStats *stats; + + stats = new JArithmeticDecoderStats(contextSize); + memcpy(stats->cxTab, cxTab, contextSize); + return stats; +} + +void JArithmeticDecoderStats::reset() { + memset(cxTab, 0, contextSize); +} + +void JArithmeticDecoderStats::copyFrom(JArithmeticDecoderStats *stats) { + memcpy(cxTab, stats->cxTab, contextSize); +} + +void JArithmeticDecoderStats::setEntry(Guint cx, int i, int mps) { + cxTab[cx] = (i << 1) + mps; +} + +//------------------------------------------------------------------------ +// JArithmeticDecoder +//------------------------------------------------------------------------ + +Guint JArithmeticDecoder::qeTab[47] = { + 0x56010000, 0x34010000, 0x18010000, 0x0AC10000, + 0x05210000, 0x02210000, 0x56010000, 0x54010000, + 0x48010000, 0x38010000, 0x30010000, 0x24010000, + 0x1C010000, 0x16010000, 0x56010000, 0x54010000, + 0x51010000, 0x48010000, 0x38010000, 0x34010000, + 0x30010000, 0x28010000, 0x24010000, 0x22010000, + 0x1C010000, 0x18010000, 0x16010000, 0x14010000, + 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000, + 0x08A10000, 0x05210000, 0x04410000, 0x02A10000, + 0x02210000, 0x01410000, 0x01110000, 0x00850000, + 0x00490000, 0x00250000, 0x00150000, 0x00090000, + 0x00050000, 0x00010000, 0x56010000 +}; + +int JArithmeticDecoder::nmpsTab[47] = { + 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46 +}; + +int JArithmeticDecoder::nlpsTab[47] = { + 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14, + 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46 +}; + +int JArithmeticDecoder::switchTab[47] = { + 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 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 +}; + +JArithmeticDecoder::JArithmeticDecoder() { + str = NULL; + dataLen = 0; + limitStream = gFalse; +} + +inline Guint JArithmeticDecoder::readByte() { + if (limitStream) { + --dataLen; + if (dataLen < 0) { + return 0xff; + } + } + return (Guint)str->getChar() & 0xff; +} + +JArithmeticDecoder::~JArithmeticDecoder() { + cleanup(); +} + +void JArithmeticDecoder::start() { + buf0 = readByte(); + buf1 = readByte(); + + // INITDEC + c = (buf0 ^ 0xff) << 16; + byteIn(); + c <<= 7; + ct -= 7; + a = 0x80000000; +} + +void JArithmeticDecoder::restart(int dataLenA) { + int oldDataLen; + + oldDataLen = dataLen; + dataLen = dataLenA; + if (oldDataLen == -1) { + buf1 = readByte(); + } else if (oldDataLen <= -2) { + buf0 = readByte(); + buf1 = readByte(); + } +} + +void JArithmeticDecoder::cleanup() { + if (limitStream) { + while (dataLen > 0) { + buf0 = buf1; + buf1 = readByte(); + } + } +} + +int JArithmeticDecoder::decodeBit(Guint context, + JArithmeticDecoderStats *stats) { + int bit; + Guint qe; + int iCX, mpsCX; + + iCX = stats->cxTab[context] >> 1; + mpsCX = stats->cxTab[context] & 1; + qe = qeTab[iCX]; + a -= qe; + if (c < a) { + if (a & 0x80000000) { + bit = mpsCX; + } else { + // MPS_EXCHANGE + if (a < qe) { + bit = 1 - mpsCX; + if (switchTab[iCX]) { + stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX); + } else { + stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX; + } + } else { + bit = mpsCX; + stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX; + } + // RENORMD + do { + if (ct == 0) { + byteIn(); + } + a <<= 1; + c <<= 1; + --ct; + } while (!(a & 0x80000000)); + } + } else { + c -= a; + // LPS_EXCHANGE + if (a < qe) { + bit = mpsCX; + stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX; + } else { + bit = 1 - mpsCX; + if (switchTab[iCX]) { + stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX); + } else { + stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX; + } + } + a = qe; + // RENORMD + do { + if (ct == 0) { + byteIn(); + } + a <<= 1; + c <<= 1; + --ct; + } while (!(a & 0x80000000)); + } + return bit; +} + +int JArithmeticDecoder::decodeByte(Guint context, + JArithmeticDecoderStats *stats) { + int byte; + int i; + + byte = 0; + for (i = 0; i < 8; ++i) { + byte = (byte << 1) | decodeBit(context, stats); + } + return byte; +} + +GBool JArithmeticDecoder::decodeInt(int *x, JArithmeticDecoderStats *stats) { + int s; + Guint v; + int i; + + prev = 1; + s = decodeIntBit(stats); + if (decodeIntBit(stats)) { + if (decodeIntBit(stats)) { + if (decodeIntBit(stats)) { + if (decodeIntBit(stats)) { + if (decodeIntBit(stats)) { + v = 0; + for (i = 0; i < 32; ++i) { + v = (v << 1) | decodeIntBit(stats); + } + v += 4436; + } else { + v = 0; + for (i = 0; i < 12; ++i) { + v = (v << 1) | decodeIntBit(stats); + } + v += 340; + } + } else { + v = 0; + for (i = 0; i < 8; ++i) { + v = (v << 1) | decodeIntBit(stats); + } + v += 84; + } + } else { + v = 0; + for (i = 0; i < 6; ++i) { + v = (v << 1) | decodeIntBit(stats); + } + v += 20; + } + } else { + v = decodeIntBit(stats); + v = (v << 1) | decodeIntBit(stats); + v = (v << 1) | decodeIntBit(stats); + v = (v << 1) | decodeIntBit(stats); + v += 4; + } + } else { + v = decodeIntBit(stats); + v = (v << 1) | decodeIntBit(stats); + } + + if (s) { + if (v == 0) { + return gFalse; + } + *x = -(int)v; + } else { + *x = (int)v; + } + return gTrue; +} + +int JArithmeticDecoder::decodeIntBit(JArithmeticDecoderStats *stats) { + int bit; + + bit = decodeBit(prev, stats); + if (prev < 0x100) { + prev = (prev << 1) | bit; + } else { + prev = (((prev << 1) | bit) & 0x1ff) | 0x100; + } + return bit; +} + +Guint JArithmeticDecoder::decodeIAID(Guint codeLen, + JArithmeticDecoderStats *stats) { + Guint i; + int bit; + + prev = 1; + for (i = 0; i < codeLen; ++i) { + bit = decodeBit(prev, stats); + prev = (prev << 1) | bit; + } + return prev - (1 << codeLen); +} + +void JArithmeticDecoder::byteIn() { + if (buf0 == 0xff) { + if (buf1 > 0x8f) { + ct = 8; + } else { + buf0 = buf1; + buf1 = readByte(); + c = c + 0xfe00 - (buf0 << 9); + ct = 7; + } + } else { + buf0 = buf1; + buf1 = readByte(); + c = c + 0xff00 - (buf0 << 8); + ct = 8; + } +} diff --git a/rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.h b/rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.h new file mode 100644 index 00000000000..0f091b7bd84 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/JArithmeticDecoder.h @@ -0,0 +1,107 @@ +//======================================================================== +// +// JArithmeticDecoder.h +// +// Arithmetic decoder used by the JBIG2 and JPEG2000 decoders. +// +// Copyright 2002-2004 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef JARITHMETICDECODER_H +#define JARITHMETICDECODER_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +class Stream; + +//------------------------------------------------------------------------ +// JArithmeticDecoderStats +//------------------------------------------------------------------------ + +class JArithmeticDecoderStats { +public: + + JArithmeticDecoderStats(int contextSizeA); + ~JArithmeticDecoderStats(); + JArithmeticDecoderStats *copy(); + void reset(); + int getContextSize() { return contextSize; } + void copyFrom(JArithmeticDecoderStats *stats); + void setEntry(Guint cx, int i, int mps); + +private: + + Guchar *cxTab; // cxTab[cx] = (i[cx] << 1) + mps[cx] + int contextSize; + + friend class JArithmeticDecoder; +}; + +//------------------------------------------------------------------------ +// JArithmeticDecoder +//------------------------------------------------------------------------ + +class JArithmeticDecoder { +public: + + JArithmeticDecoder(); + ~JArithmeticDecoder(); + + void setStream(Stream *strA) + { str = strA; dataLen = 0; limitStream = gFalse; } + void setStream(Stream *strA, int dataLenA) + { str = strA; dataLen = dataLenA; limitStream = gTrue; } + + // Start decoding on a new stream. This fills the byte buffers and + // runs INITDEC. + void start(); + + // Restart decoding on an interrupted stream. This refills the + // buffers if needed, but does not run INITDEC. (This is used in + // JPEG 2000 streams when codeblock data is split across multiple + // packets/layers.) + void restart(int dataLenA); + + // Read any leftover data in the stream. + void cleanup(); + + // Decode one bit. + int decodeBit(Guint context, JArithmeticDecoderStats *stats); + + // Decode eight bits. + int decodeByte(Guint context, JArithmeticDecoderStats *stats); + + // Returns false for OOB, otherwise sets * and returns true. + GBool decodeInt(int *x, JArithmeticDecoderStats *stats); + + Guint decodeIAID(Guint codeLen, + JArithmeticDecoderStats *stats); + +private: + + Guint readByte(); + int decodeIntBit(JArithmeticDecoderStats *stats); + void byteIn(); + + static Guint qeTab[47]; + static int nmpsTab[47]; + static int nlpsTab[47]; + static int switchTab[47]; + + Guint buf0, buf1; + Guint c, a; + int ct; + + Guint prev; // for the integer decoder + + Stream *str; + int dataLen; + GBool limitStream; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/JBIG2Stream.cc b/rosapps/smartpdf/poppler/poppler/JBIG2Stream.cc new file mode 100644 index 00000000000..1ef56055349 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/JBIG2Stream.cc @@ -0,0 +1,3468 @@ +//======================================================================== +// +// JBIG2Stream.cc +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/GooList.h" +#include "Error.h" +#include "JArithmeticDecoder.h" +#include "JBIG2Stream.h" + +//~ share these tables +#include "Stream-CCITT.h" + +//------------------------------------------------------------------------ + +static int contextSize[4] = { 16, 13, 10, 10 }; +static int refContextSize[2] = { 13, 10 }; + +//------------------------------------------------------------------------ +// JBIG2HuffmanTable +//------------------------------------------------------------------------ + +#define jbig2HuffmanLOW 0xfffffffd +#define jbig2HuffmanOOB 0xfffffffe +#define jbig2HuffmanEOT 0xffffffff + +struct JBIG2HuffmanTable { + int val; + Guint prefixLen; + Guint rangeLen; // can also be LOW, OOB, or EOT + Guint prefix; +}; + +JBIG2HuffmanTable huffTableA[] = { + { 0, 1, 4, 0x000 }, + { 16, 2, 8, 0x002 }, + { 272, 3, 16, 0x006 }, + { 65808, 3, 32, 0x007 }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableB[] = { + { 0, 1, 0, 0x000 }, + { 1, 2, 0, 0x002 }, + { 2, 3, 0, 0x006 }, + { 3, 4, 3, 0x00e }, + { 11, 5, 6, 0x01e }, + { 75, 6, 32, 0x03e }, + { 0, 6, jbig2HuffmanOOB, 0x03f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableC[] = { + { 0, 1, 0, 0x000 }, + { 1, 2, 0, 0x002 }, + { 2, 3, 0, 0x006 }, + { 3, 4, 3, 0x00e }, + { 11, 5, 6, 0x01e }, + { 0, 6, jbig2HuffmanOOB, 0x03e }, + { 75, 7, 32, 0x0fe }, + { -256, 8, 8, 0x0fe }, + { -257, 8, jbig2HuffmanLOW, 0x0ff }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableD[] = { + { 1, 1, 0, 0x000 }, + { 2, 2, 0, 0x002 }, + { 3, 3, 0, 0x006 }, + { 4, 4, 3, 0x00e }, + { 12, 5, 6, 0x01e }, + { 76, 5, 32, 0x01f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableE[] = { + { 1, 1, 0, 0x000 }, + { 2, 2, 0, 0x002 }, + { 3, 3, 0, 0x006 }, + { 4, 4, 3, 0x00e }, + { 12, 5, 6, 0x01e }, + { 76, 6, 32, 0x03e }, + { -255, 7, 8, 0x07e }, + { -256, 7, jbig2HuffmanLOW, 0x07f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableF[] = { + { 0, 2, 7, 0x000 }, + { 128, 3, 7, 0x002 }, + { 256, 3, 8, 0x003 }, + { -1024, 4, 9, 0x008 }, + { -512, 4, 8, 0x009 }, + { -256, 4, 7, 0x00a }, + { -32, 4, 5, 0x00b }, + { 512, 4, 9, 0x00c }, + { 1024, 4, 10, 0x00d }, + { -2048, 5, 10, 0x01c }, + { -128, 5, 6, 0x01d }, + { -64, 5, 5, 0x01e }, + { -2049, 6, jbig2HuffmanLOW, 0x03e }, + { 2048, 6, 32, 0x03f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableG[] = { + { -512, 3, 8, 0x000 }, + { 256, 3, 8, 0x001 }, + { 512, 3, 9, 0x002 }, + { 1024, 3, 10, 0x003 }, + { -1024, 4, 9, 0x008 }, + { -256, 4, 7, 0x009 }, + { -32, 4, 5, 0x00a }, + { 0, 4, 5, 0x00b }, + { 128, 4, 7, 0x00c }, + { -128, 5, 6, 0x01a }, + { -64, 5, 5, 0x01b }, + { 32, 5, 5, 0x01c }, + { 64, 5, 6, 0x01d }, + { -1025, 5, jbig2HuffmanLOW, 0x01e }, + { 2048, 5, 32, 0x01f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableH[] = { + { 0, 2, 1, 0x000 }, + { 0, 2, jbig2HuffmanOOB, 0x001 }, + { 4, 3, 4, 0x004 }, + { -1, 4, 0, 0x00a }, + { 22, 4, 4, 0x00b }, + { 38, 4, 5, 0x00c }, + { 2, 5, 0, 0x01a }, + { 70, 5, 6, 0x01b }, + { 134, 5, 7, 0x01c }, + { 3, 6, 0, 0x03a }, + { 20, 6, 1, 0x03b }, + { 262, 6, 7, 0x03c }, + { 646, 6, 10, 0x03d }, + { -2, 7, 0, 0x07c }, + { 390, 7, 8, 0x07d }, + { -15, 8, 3, 0x0fc }, + { -5, 8, 1, 0x0fd }, + { -7, 9, 1, 0x1fc }, + { -3, 9, 0, 0x1fd }, + { -16, 9, jbig2HuffmanLOW, 0x1fe }, + { 1670, 9, 32, 0x1ff }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableI[] = { + { 0, 2, jbig2HuffmanOOB, 0x000 }, + { -1, 3, 1, 0x002 }, + { 1, 3, 1, 0x003 }, + { 7, 3, 5, 0x004 }, + { -3, 4, 1, 0x00a }, + { 43, 4, 5, 0x00b }, + { 75, 4, 6, 0x00c }, + { 3, 5, 1, 0x01a }, + { 139, 5, 7, 0x01b }, + { 267, 5, 8, 0x01c }, + { 5, 6, 1, 0x03a }, + { 39, 6, 2, 0x03b }, + { 523, 6, 8, 0x03c }, + { 1291, 6, 11, 0x03d }, + { -5, 7, 1, 0x07c }, + { 779, 7, 9, 0x07d }, + { -31, 8, 4, 0x0fc }, + { -11, 8, 2, 0x0fd }, + { -15, 9, 2, 0x1fc }, + { -7, 9, 1, 0x1fd }, + { -32, 9, jbig2HuffmanLOW, 0x1fe }, + { 3339, 9, 32, 0x1ff }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableJ[] = { + { -2, 2, 2, 0x000 }, + { 6, 2, 6, 0x001 }, + { 0, 2, jbig2HuffmanOOB, 0x002 }, + { -3, 5, 0, 0x018 }, + { 2, 5, 0, 0x019 }, + { 70, 5, 5, 0x01a }, + { 3, 6, 0, 0x036 }, + { 102, 6, 5, 0x037 }, + { 134, 6, 6, 0x038 }, + { 198, 6, 7, 0x039 }, + { 326, 6, 8, 0x03a }, + { 582, 6, 9, 0x03b }, + { 1094, 6, 10, 0x03c }, + { -21, 7, 4, 0x07a }, + { -4, 7, 0, 0x07b }, + { 4, 7, 0, 0x07c }, + { 2118, 7, 11, 0x07d }, + { -5, 8, 0, 0x0fc }, + { 5, 8, 0, 0x0fd }, + { -22, 8, jbig2HuffmanLOW, 0x0fe }, + { 4166, 8, 32, 0x0ff }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableK[] = { + { 1, 1, 0, 0x000 }, + { 2, 2, 1, 0x002 }, + { 4, 4, 0, 0x00c }, + { 5, 4, 1, 0x00d }, + { 7, 5, 1, 0x01c }, + { 9, 5, 2, 0x01d }, + { 13, 6, 2, 0x03c }, + { 17, 7, 2, 0x07a }, + { 21, 7, 3, 0x07b }, + { 29, 7, 4, 0x07c }, + { 45, 7, 5, 0x07d }, + { 77, 7, 6, 0x07e }, + { 141, 7, 32, 0x07f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableL[] = { + { 1, 1, 0, 0x000 }, + { 2, 2, 0, 0x002 }, + { 3, 3, 1, 0x006 }, + { 5, 5, 0, 0x01c }, + { 6, 5, 1, 0x01d }, + { 8, 6, 1, 0x03c }, + { 10, 7, 0, 0x07a }, + { 11, 7, 1, 0x07b }, + { 13, 7, 2, 0x07c }, + { 17, 7, 3, 0x07d }, + { 25, 7, 4, 0x07e }, + { 41, 8, 5, 0x0fe }, + { 73, 8, 32, 0x0ff }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableM[] = { + { 1, 1, 0, 0x000 }, + { 2, 3, 0, 0x004 }, + { 7, 3, 3, 0x005 }, + { 3, 4, 0, 0x00c }, + { 5, 4, 1, 0x00d }, + { 4, 5, 0, 0x01c }, + { 15, 6, 1, 0x03a }, + { 17, 6, 2, 0x03b }, + { 21, 6, 3, 0x03c }, + { 29, 6, 4, 0x03d }, + { 45, 6, 5, 0x03e }, + { 77, 7, 6, 0x07e }, + { 141, 7, 32, 0x07f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableN[] = { + { 0, 1, 0, 0x000 }, + { -2, 3, 0, 0x004 }, + { -1, 3, 0, 0x005 }, + { 1, 3, 0, 0x006 }, + { 2, 3, 0, 0x007 }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +JBIG2HuffmanTable huffTableO[] = { + { 0, 1, 0, 0x000 }, + { -1, 3, 0, 0x004 }, + { 1, 3, 0, 0x005 }, + { -2, 4, 0, 0x00c }, + { 2, 4, 0, 0x00d }, + { -4, 5, 1, 0x01c }, + { 3, 5, 1, 0x01d }, + { -8, 6, 2, 0x03c }, + { 5, 6, 2, 0x03d }, + { -24, 7, 4, 0x07c }, + { 9, 7, 4, 0x07d }, + { -25, 7, jbig2HuffmanLOW, 0x07e }, + { 25, 7, 32, 0x07f }, + { 0, 0, jbig2HuffmanEOT, 0 } +}; + +//------------------------------------------------------------------------ +// JBIG2HuffmanDecoder +//------------------------------------------------------------------------ + +class JBIG2HuffmanDecoder { +public: + + JBIG2HuffmanDecoder(); + ~JBIG2HuffmanDecoder(); + void setStream(Stream *strA) { str = strA; } + + void reset(); + + // Returns false for OOB, otherwise sets * and returns true. + GBool decodeInt(int *x, JBIG2HuffmanTable *table); + + Guint readBits(Guint n); + Guint readBit(); + + // Sort the table by prefix length and assign prefix values. + void buildTable(JBIG2HuffmanTable *table, Guint len); + +private: + + Stream *str; + Guint buf; + Guint bufLen; +}; + +JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() { + str = NULL; + reset(); +} + +JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() { +} + +void JBIG2HuffmanDecoder::reset() { + buf = 0; + bufLen = 0; +} + +//~ optimize this +GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) { + Guint i, len, prefix; + + i = 0; + len = 0; + prefix = 0; + while (table[i].rangeLen != jbig2HuffmanEOT) { + while (len < table[i].prefixLen) { + prefix = (prefix << 1) | readBit(); + ++len; + } + if (prefix == table[i].prefix) { + if (table[i].rangeLen == jbig2HuffmanOOB) { + return gFalse; + } + if (table[i].rangeLen == jbig2HuffmanLOW) { + *x = table[i].val - readBits(32); + } else if (table[i].rangeLen > 0) { + *x = table[i].val + readBits(table[i].rangeLen); + } else { + *x = table[i].val; + } + return gTrue; + } + ++i; + } + return gFalse; +} + +Guint JBIG2HuffmanDecoder::readBits(Guint n) { + Guint x, mask, nLeft; + + mask = (n == 32) ? 0xffffffff : ((1 << n) - 1); + if (bufLen >= n) { + x = (buf >> (bufLen - n)) & mask; + bufLen -= n; + } else { + x = buf & ((1 << bufLen) - 1); + nLeft = n - bufLen; + bufLen = 0; + while (nLeft >= 8) { + x = (x << 8) | (str->getChar() & 0xff); + nLeft -= 8; + } + if (nLeft > 0) { + buf = str->getChar(); + bufLen = 8 - nLeft; + x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1)); + } + } + return x; +} + +Guint JBIG2HuffmanDecoder::readBit() { + if (bufLen == 0) { + buf = str->getChar(); + bufLen = 8; + } + --bufLen; + return (buf >> bufLen) & 1; +} + +void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) { + Guint i, j, k, prefix; + JBIG2HuffmanTable tab; + + // stable selection sort: + // - entries with prefixLen > 0, in ascending prefixLen order + // - entry with prefixLen = 0, rangeLen = EOT + // - all other entries with prefixLen = 0 + // (on entry, table[len] has prefixLen = 0, rangeLen = EOT) + for (i = 0; i < len; ++i) { + for (j = i; j < len && table[j].prefixLen == 0; ++j) ; + if (j == len) { + break; + } + for (k = j + 1; k < len; ++k) { + if (table[k].prefixLen > 0 && + table[k].prefixLen < table[j].prefixLen) { + j = k; + } + } + if (j != i) { + tab = table[j]; + for (k = j; k > i; --k) { + table[k] = table[k - 1]; + } + table[i] = tab; + } + } + table[i] = table[len]; + + // assign prefixes + i = 0; + prefix = 0; + table[i++].prefix = prefix++; + for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) { + prefix <<= table[i].prefixLen - table[i-1].prefixLen; + table[i].prefix = prefix++; + } +} + +//------------------------------------------------------------------------ +// JBIG2MMRDecoder +//------------------------------------------------------------------------ + +class JBIG2MMRDecoder { +public: + + JBIG2MMRDecoder(); + ~JBIG2MMRDecoder(); + void setStream(Stream *strA) { str = strA; } + void reset(); + int get2DCode(); + int getBlackCode(); + int getWhiteCode(); + Guint get24Bits(); + void skipTo(Guint length); + +private: + + Stream *str; + Guint buf; + Guint bufLen; + Guint nBytesRead; +}; + +JBIG2MMRDecoder::JBIG2MMRDecoder() { + str = NULL; + reset(); +} + +JBIG2MMRDecoder::~JBIG2MMRDecoder() { +} + +void JBIG2MMRDecoder::reset() { + buf = 0; + bufLen = 0; + nBytesRead = 0; +} + +int JBIG2MMRDecoder::get2DCode() { + CCITTCode *p; + + if (bufLen == 0) { + buf = str->getChar() & 0xff; + bufLen = 8; + ++nBytesRead; + p = &twoDimTab1[(buf >> 1) & 0x7f]; + } else if (bufLen == 8) { + p = &twoDimTab1[(buf >> 1) & 0x7f]; + } else { + p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f]; + if (p->bits < 0 || p->bits > (int)bufLen) { + buf = (buf << 8) | (str->getChar() & 0xff); + bufLen += 8; + ++nBytesRead; + p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f]; + } + } + if (p->bits < 0) { + error(str->getPos(), "Bad two dim code in JBIG2 MMR stream"); + return 0; + } + bufLen -= p->bits; + return p->n; +} + +int JBIG2MMRDecoder::getWhiteCode() { + CCITTCode *p; + Guint code; + + if (bufLen == 0) { + buf = str->getChar() & 0xff; + bufLen = 8; + ++nBytesRead; + } + while (1) { + if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) { + if (bufLen <= 12) { + code = buf << (12 - bufLen); + } else { + code = buf >> (bufLen - 12); + } + p = &whiteTab1[code & 0x1f]; + } else { + if (bufLen <= 9) { + code = buf << (9 - bufLen); + } else { + code = buf >> (bufLen - 9); + } + p = &whiteTab2[code & 0x1ff]; + } + if (p->bits > 0 && p->bits <= (int)bufLen) { + bufLen -= p->bits; + return p->n; + } + if (bufLen >= 12) { + break; + } + buf = (buf << 8) | (str->getChar() & 0xff); + bufLen += 8; + ++nBytesRead; + } + error(str->getPos(), "Bad white code in JBIG2 MMR stream"); + // eat a bit and return a positive number so that the caller doesn't + // go into an infinite loop + --bufLen; + return 1; +} + +int JBIG2MMRDecoder::getBlackCode() { + CCITTCode *p; + Guint code; + + if (bufLen == 0) { + buf = str->getChar() & 0xff; + bufLen = 8; + ++nBytesRead; + } + while (1) { + if (bufLen >= 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) { + if (bufLen <= 13) { + code = buf << (13 - bufLen); + } else { + code = buf >> (bufLen - 13); + } + p = &blackTab1[code & 0x7f]; + } else if (bufLen >= 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) { + if (bufLen <= 12) { + code = buf << (12 - bufLen); + } else { + code = buf >> (bufLen - 12); + } + p = &blackTab2[(code & 0xff) - 64]; + } else { + if (bufLen <= 6) { + code = buf << (6 - bufLen); + } else { + code = buf >> (bufLen - 6); + } + p = &blackTab3[code & 0x3f]; + } + if (p->bits > 0 && p->bits <= (int)bufLen) { + bufLen -= p->bits; + return p->n; + } + if (bufLen >= 13) { + break; + } + buf = (buf << 8) | (str->getChar() & 0xff); + bufLen += 8; + ++nBytesRead; + } + error(str->getPos(), "Bad black code in JBIG2 MMR stream"); + // eat a bit and return a positive number so that the caller doesn't + // go into an infinite loop + --bufLen; + return 1; +} + +Guint JBIG2MMRDecoder::get24Bits() { + while (bufLen < 24) { + buf = (buf << 8) | (str->getChar() & 0xff); + bufLen += 8; + ++nBytesRead; + } + return (buf >> (bufLen - 24)) & 0xffffff; +} + +void JBIG2MMRDecoder::skipTo(Guint length) { + while (nBytesRead < length) { + str->getChar(); + ++nBytesRead; + } +} + +//------------------------------------------------------------------------ +// JBIG2Segment +//------------------------------------------------------------------------ + +enum JBIG2SegmentType { + jbig2SegBitmap, + jbig2SegSymbolDict, + jbig2SegPatternDict, + jbig2SegCodeTable +}; + +class JBIG2Segment { +public: + + JBIG2Segment(Guint segNumA) { segNum = segNumA; } + virtual ~JBIG2Segment() {} + void setSegNum(Guint segNumA) { segNum = segNumA; } + Guint getSegNum() { return segNum; } + virtual JBIG2SegmentType getType() = 0; + +private: + + Guint segNum; +}; + +//------------------------------------------------------------------------ +// JBIG2Bitmap +//------------------------------------------------------------------------ + +struct JBIG2BitmapPtr { + Guchar *p; + int shift; + int x; +}; + +class JBIG2Bitmap: public JBIG2Segment { +public: + + JBIG2Bitmap(Guint segNumA, int wA, int hA); + virtual ~JBIG2Bitmap(); + virtual JBIG2SegmentType getType() { return jbig2SegBitmap; } + JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); } + JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA); + void expand(int newH, Guint pixel); + void clearToZero(); + void clearToOne(); + int getWidth() { return w; } + int getHeight() { return h; } + int getPixel(int x, int y) + { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 : + (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; } + void setPixel(int x, int y) + { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); } + void clearPixel(int x, int y) + { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); } + void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr); + int nextPixel(JBIG2BitmapPtr *ptr); + void duplicateRow(int yDest, int ySrc); + void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp); + Guchar *getDataPtr() { return data; } + int getDataSize() { return h * line; } + +private: + + JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap); + + int w, h, line; + Guchar *data; +}; + +JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA): + JBIG2Segment(segNumA) +{ + w = wA; + h = hA; + line = (wA + 7) >> 3; + + if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) { + error(-1, "invalid width/height"); + data = NULL; + return; + } + // need to allocate one extra guard byte for use in combine() + data = (Guchar *)gmalloc(h * line + 1); + data[h * line] = 0; +} + +JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap): + JBIG2Segment(segNumA) +{ + w = bitmap->w; + h = bitmap->h; + line = bitmap->line; + + if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) { + error(-1, "invalid width/height"); + data = NULL; + return; + } + // need to allocate one extra guard byte for use in combine() + data = (Guchar *)gmalloc(h * line + 1); + memcpy(data, bitmap->data, h * line); + data[h * line] = 0; +} + +JBIG2Bitmap::~JBIG2Bitmap() { + gfree(data); +} + +//~ optimize this +JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) { + JBIG2Bitmap *slice; + Guint xx, yy; + + slice = new JBIG2Bitmap(0, wA, hA); + slice->clearToZero(); + for (yy = 0; yy < hA; ++yy) { + for (xx = 0; xx < wA; ++xx) { + if (getPixel(x + xx, y + yy)) { + slice->setPixel(xx, yy); + } + } + } + return slice; +} + +void JBIG2Bitmap::expand(int newH, Guint pixel) { + if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) { + error(-1, "invalid width/height"); + gfree(data); + data = NULL; + return; + } + // need to allocate one extra guard byte for use in combine() + data = (Guchar *)grealloc(data, newH * line + 1); + if (pixel) { + memset(data + h * line, 0xff, (newH - h) * line); + } else { + memset(data + h * line, 0x00, (newH - h) * line); + } + h = newH; + data[h * line] = 0; +} + +void JBIG2Bitmap::clearToZero() { + memset(data, 0, h * line); +} + +void JBIG2Bitmap::clearToOne() { + memset(data, 0xff, h * line); +} + +inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) { + if (y < 0 || y >= h || x >= w) { + ptr->p = NULL; + } else if (x < 0) { + ptr->p = &data[y * line]; + ptr->shift = 7; + ptr->x = x; + } else { + ptr->p = &data[y * line + (x >> 3)]; + ptr->shift = 7 - (x & 7); + ptr->x = x; + } +} + +inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) { + int pix; + + if (!ptr->p) { + pix = 0; + } else if (ptr->x < 0) { + ++ptr->x; + pix = 0; + } else { + pix = (*ptr->p >> ptr->shift) & 1; + if (++ptr->x == w) { + ptr->p = NULL; + } else if (ptr->shift == 0) { + ++ptr->p; + ptr->shift = 7; + } else { + --ptr->shift; + } + } + return pix; +} + +void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) { + memcpy(data + yDest * line, data + ySrc * line, line); +} + +void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y, + Guint combOp) { + int x0, x1, y0, y1, xx, yy; + Guchar *srcPtr, *destPtr; + Guint src0, src1, src, dest, s1, s2, m1, m2, m3; + GBool oneByte; + + if (y < 0) { + y0 = -y; + } else { + y0 = 0; + } + if (y + bitmap->h > h) { + y1 = h - y; + } else { + y1 = bitmap->h; + } + if (y0 >= y1) { + return; + } + + if (x >= 0) { + x0 = x & ~7; + } else { + x0 = 0; + } + x1 = x + bitmap->w; + if (x1 > w) { + x1 = w; + } + if (x0 >= x1) { + return; + } + + s1 = x & 7; + s2 = 8 - s1; + m1 = 0xff >> (x1 & 7); + m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7)); + m3 = (0xff >> s1) & m2; + + oneByte = x0 == ((x1 - 1) & ~7); + + for (yy = y0; yy < y1; ++yy) { + + // one byte per line -- need to mask both left and right side + if (oneByte) { + if (x >= 0) { + destPtr = data + (y + yy) * line + (x >> 3); + srcPtr = bitmap->data + yy * bitmap->line; + dest = *destPtr; + src1 = *srcPtr; + switch (combOp) { + case 0: // or + dest |= (src1 >> s1) & m2; + break; + case 1: // and + dest &= ((0xff00 | src1) >> s1) | m1; + break; + case 2: // xor + dest ^= (src1 >> s1) & m2; + break; + case 3: // xnor + dest ^= ((src1 ^ 0xff) >> s1) & m2; + break; + case 4: // replace + dest = (dest & ~m3) | ((src1 >> s1) & m3); + break; + } + *destPtr = dest; + } else { + destPtr = data + (y + yy) * line; + srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3); + dest = *destPtr; + src1 = *srcPtr; + switch (combOp) { + case 0: // or + dest |= src1 & m2; + break; + case 1: // and + dest &= src1 | m1; + break; + case 2: // xor + dest ^= src1 & m2; + break; + case 3: // xnor + dest ^= (src1 ^ 0xff) & m2; + break; + case 4: // replace + dest = (src1 & m2) | (dest & m1); + break; + } + *destPtr = dest; + } + + // multiple bytes per line -- need to mask left side of left-most + // byte and right side of right-most byte + } else { + + // left-most byte + if (x >= 0) { + destPtr = data + (y + yy) * line + (x >> 3); + srcPtr = bitmap->data + yy * bitmap->line; + src1 = *srcPtr++; + dest = *destPtr; + switch (combOp) { + case 0: // or + dest |= src1 >> s1; + break; + case 1: // and + dest &= (0xff00 | src1) >> s1; + break; + case 2: // xor + dest ^= src1 >> s1; + break; + case 3: // xnor + dest ^= (src1 ^ 0xff) >> s1; + break; + case 4: // replace + dest = (dest & (0xff << s2)) | (src1 >> s1); + break; + } + *destPtr++ = dest; + xx = x0 + 8; + } else { + destPtr = data + (y + yy) * line; + srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3); + src1 = *srcPtr++; + xx = x0; + } + + // middle bytes + for (; xx < x1 - 8; xx += 8) { + dest = *destPtr; + src0 = src1; + src1 = *srcPtr++; + src = (((src0 << 8) | src1) >> s1) & 0xff; + switch (combOp) { + case 0: // or + dest |= src; + break; + case 1: // and + dest &= src; + break; + case 2: // xor + dest ^= src; + break; + case 3: // xnor + dest ^= src ^ 0xff; + break; + case 4: // replace + dest = src; + break; + } + *destPtr++ = dest; + } + + // right-most byte + // note: this last byte (src1) may not actually be used, depending + // on the values of s1, m1, and m2 - and in fact, it may be off + // the edge of the source bitmap, which means we need to allocate + // one extra guard byte at the end of each bitmap + dest = *destPtr; + src0 = src1; + src1 = *srcPtr++; + src = (((src0 << 8) | src1) >> s1) & 0xff; + switch (combOp) { + case 0: // or + dest |= src & m2; + break; + case 1: // and + dest &= src | m1; + break; + case 2: // xor + dest ^= src & m2; + break; + case 3: // xnor + dest ^= (src ^ 0xff) & m2; + break; + case 4: // replace + dest = (src & m2) | (dest & m1); + break; + } + *destPtr = dest; + } + } +} + +//------------------------------------------------------------------------ +// JBIG2SymbolDict +//------------------------------------------------------------------------ + +class JBIG2SymbolDict: public JBIG2Segment { +public: + + JBIG2SymbolDict(Guint segNumA, Guint sizeA); + virtual ~JBIG2SymbolDict(); + virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; } + Guint getSize() { return size; } + void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; } + JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; } + void setGenericRegionStats(JArithmeticDecoderStats *stats) + { genericRegionStats = stats; } + void setRefinementRegionStats(JArithmeticDecoderStats *stats) + { refinementRegionStats = stats; } + JArithmeticDecoderStats *getGenericRegionStats() + { return genericRegionStats; } + JArithmeticDecoderStats *getRefinementRegionStats() + { return refinementRegionStats; } + +private: + + Guint size; + JBIG2Bitmap **bitmaps; + JArithmeticDecoderStats *genericRegionStats; + JArithmeticDecoderStats *refinementRegionStats; +}; + +JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA): + JBIG2Segment(segNumA) +{ + size = sizeA; + bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *)); + genericRegionStats = NULL; + refinementRegionStats = NULL; +} + +JBIG2SymbolDict::~JBIG2SymbolDict() { + Guint i; + + for (i = 0; i < size; ++i) { + delete bitmaps[i]; + } + gfree(bitmaps); + if (genericRegionStats) { + delete genericRegionStats; + } + if (refinementRegionStats) { + delete refinementRegionStats; + } +} + +//------------------------------------------------------------------------ +// JBIG2PatternDict +//------------------------------------------------------------------------ + +class JBIG2PatternDict: public JBIG2Segment { +public: + + JBIG2PatternDict(Guint segNumA, Guint sizeA); + virtual ~JBIG2PatternDict(); + virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; } + Guint getSize() { return size; } + void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; } + JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; } + +private: + + Guint size; + JBIG2Bitmap **bitmaps; +}; + +JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA): + JBIG2Segment(segNumA) +{ + size = sizeA; + bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *)); +} + +JBIG2PatternDict::~JBIG2PatternDict() { + Guint i; + + for (i = 0; i < size; ++i) { + delete bitmaps[i]; + } + gfree(bitmaps); +} + +//------------------------------------------------------------------------ +// JBIG2CodeTable +//------------------------------------------------------------------------ + +class JBIG2CodeTable: public JBIG2Segment { +public: + + JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA); + virtual ~JBIG2CodeTable(); + virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; } + JBIG2HuffmanTable *getHuffTable() { return table; } + +private: + + JBIG2HuffmanTable *table; +}; + +JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA): + JBIG2Segment(segNumA) +{ + table = tableA; +} + +JBIG2CodeTable::~JBIG2CodeTable() { + gfree(table); +} + +//------------------------------------------------------------------------ +// JBIG2Stream +//------------------------------------------------------------------------ + +JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream): + FilterStream(strA) +{ + pageBitmap = NULL; + + arithDecoder = new JArithmeticDecoder(); + genericRegionStats = new JArithmeticDecoderStats(1 << 1); + refinementRegionStats = new JArithmeticDecoderStats(1 << 1); + iadhStats = new JArithmeticDecoderStats(1 << 9); + iadwStats = new JArithmeticDecoderStats(1 << 9); + iaexStats = new JArithmeticDecoderStats(1 << 9); + iaaiStats = new JArithmeticDecoderStats(1 << 9); + iadtStats = new JArithmeticDecoderStats(1 << 9); + iaitStats = new JArithmeticDecoderStats(1 << 9); + iafsStats = new JArithmeticDecoderStats(1 << 9); + iadsStats = new JArithmeticDecoderStats(1 << 9); + iardxStats = new JArithmeticDecoderStats(1 << 9); + iardyStats = new JArithmeticDecoderStats(1 << 9); + iardwStats = new JArithmeticDecoderStats(1 << 9); + iardhStats = new JArithmeticDecoderStats(1 << 9); + iariStats = new JArithmeticDecoderStats(1 << 9); + iaidStats = new JArithmeticDecoderStats(1 << 1); + huffDecoder = new JBIG2HuffmanDecoder(); + mmrDecoder = new JBIG2MMRDecoder(); + + segments = globalSegments = new GooList(); + if (globalsStream->isStream()) { + curStr = globalsStream->getStream(); + curStr->reset(); + arithDecoder->setStream(curStr); + huffDecoder->setStream(curStr); + mmrDecoder->setStream(curStr); + readSegments(); + } + + segments = NULL; + curStr = NULL; + dataPtr = dataEnd = NULL; +} + +JBIG2Stream::~JBIG2Stream() { + delete arithDecoder; + delete genericRegionStats; + delete refinementRegionStats; + delete iadhStats; + delete iadwStats; + delete iaexStats; + delete iaaiStats; + delete iadtStats; + delete iaitStats; + delete iafsStats; + delete iadsStats; + delete iardxStats; + delete iardyStats; + delete iardwStats; + delete iardhStats; + delete iariStats; + delete iaidStats; + delete huffDecoder; + delete mmrDecoder; + if (pageBitmap) { + delete pageBitmap; + } + if (segments) { + deleteGooList(segments, JBIG2Segment); + } + if (globalSegments) { + deleteGooList(globalSegments, JBIG2Segment); + } + delete str; +} + +void JBIG2Stream::reset() { + if (pageBitmap) { + delete pageBitmap; + pageBitmap = NULL; + } + if (segments) { + deleteGooList(segments, JBIG2Segment); + } + segments = new GooList(); + + curStr = str; + curStr->reset(); + arithDecoder->setStream(curStr); + huffDecoder->setStream(curStr); + mmrDecoder->setStream(curStr); + readSegments(); + + if (pageBitmap) { + dataPtr = pageBitmap->getDataPtr(); + dataEnd = dataPtr + pageBitmap->getDataSize(); + } else { + dataPtr = NULL; + } +} + +int JBIG2Stream::getChar() { + if (dataPtr && dataPtr < dataEnd) { + return (*dataPtr++ ^ 0xff) & 0xff; + } + return EOF; +} + +int JBIG2Stream::lookChar() { + if (dataPtr && dataPtr < dataEnd) { + return (*dataPtr ^ 0xff) & 0xff; + } + return EOF; +} + +GooString *JBIG2Stream::getPSFilter(int psLevel, char *indent) { + return NULL; +} + +GBool JBIG2Stream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +void JBIG2Stream::readSegments() { + Guint segNum, segFlags, segType, page, segLength; + Guint refFlags, nRefSegs; + Guint *refSegs; + int segDataPos; + int c1, c2, c3; + Guint i; + + while (readULong(&segNum)) { + + // segment header flags + if (!readUByte(&segFlags)) { + goto eofError1; + } + segType = segFlags & 0x3f; + + // referred-to segment count and retention flags + if (!readUByte(&refFlags)) { + goto eofError1; + } + nRefSegs = refFlags >> 5; + if (nRefSegs == 7) { + if ((c1 = curStr->getChar()) == EOF || + (c2 = curStr->getChar()) == EOF || + (c3 = curStr->getChar()) == EOF) { + goto eofError1; + } + refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3; + nRefSegs = refFlags & 0x1fffffff; + for (i = 0; i < (nRefSegs + 9) >> 3; ++i) { + c1 = curStr->getChar(); + } + } + + // referred-to segment numbers + refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint)); + if (segNum <= 256) { + for (i = 0; i < nRefSegs; ++i) { + if (!readUByte(&refSegs[i])) { + goto eofError2; + } + } + } else if (segNum <= 65536) { + for (i = 0; i < nRefSegs; ++i) { + if (!readUWord(&refSegs[i])) { + goto eofError2; + } + } + } else { + for (i = 0; i < nRefSegs; ++i) { + if (!readULong(&refSegs[i])) { + goto eofError2; + } + } + } + + // segment page association + if (segFlags & 0x40) { + if (!readULong(&page)) { + goto eofError2; + } + } else { + if (!readUByte(&page)) { + goto eofError2; + } + } + + // segment data length + if (!readULong(&segLength)) { + goto eofError2; + } + + // keep track of the start of the segment data + segDataPos = getPos(); + + // read the segment data + switch (segType) { + case 0: + if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) { + goto syntaxError; + } + break; + case 4: + readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs); + break; + case 6: + readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs); + break; + case 7: + readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs); + break; + case 16: + readPatternDictSeg(segNum, segLength); + break; + case 20: + readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength, + refSegs, nRefSegs); + break; + case 22: + readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength, + refSegs, nRefSegs); + break; + case 23: + readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength, + refSegs, nRefSegs); + break; + case 36: + readGenericRegionSeg(segNum, gFalse, gFalse, segLength); + break; + case 38: + readGenericRegionSeg(segNum, gTrue, gFalse, segLength); + break; + case 39: + readGenericRegionSeg(segNum, gTrue, gTrue, segLength); + break; + case 40: + readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength, + refSegs, nRefSegs); + break; + case 42: + readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength, + refSegs, nRefSegs); + break; + case 43: + readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength, + refSegs, nRefSegs); + break; + case 48: + readPageInfoSeg(segLength); + break; + case 50: + readEndOfStripeSeg(segLength); + break; + case 52: + readProfilesSeg(segLength); + break; + case 53: + readCodeTableSeg(segNum, segLength); + break; + case 62: + readExtensionSeg(segLength); + break; + default: + error(getPos(), "Unknown segment type in JBIG2 stream"); + for (i = 0; i < segLength; ++i) { + if ((c1 = curStr->getChar()) == EOF) { + goto eofError2; + } + } + break; + } + + // Make sure the segment handler read all of the bytes in the + // segment data, unless this segment is marked as having an + // unknown length (section 7.2.7 of the JBIG2 Final Committee Draft) + + if (segLength != 0xffffffff) { + + int segExtraBytes = segDataPos + segLength - getPos(); + if (segExtraBytes > 0) { + + // If we didn't read all of the bytes in the segment data, + // indicate an error, and throw away the rest of the data. + + // v.3.1.01.13 of the LuraTech PDF Compressor Server will + // sometimes generate an extraneous NULL byte at the end of + // arithmetic-coded symbol dictionary segments when numNewSyms + // == 0. Segments like this often occur for blank pages. + + error(getPos(), "%d extraneous byte%s after segment", + segExtraBytes, (segExtraBytes > 1) ? "s" : ""); + + // Burn through the remaining bytes -- inefficient, but + // hopefully we're not doing this much + + int trash; + for (int i = segExtraBytes; i > 0; i--) { + readByte(&trash); + } + + } else if (segExtraBytes < 0) { + + // If we read more bytes than we should have, according to the + // segment length field, note an error. + + error(getPos(), "Previous segment handler read too many bytes"); + + } + + } + + gfree(refSegs); + } + + return; + + syntaxError: + gfree(refSegs); + return; + + eofError2: + gfree(refSegs); + eofError1: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, + Guint *refSegs, Guint nRefSegs) { + JBIG2SymbolDict *symbolDict; + JBIG2HuffmanTable *huffDHTable, *huffDWTable; + JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable; + JBIG2Segment *seg; + GooList *codeTables; + JBIG2SymbolDict *inputSymbolDict; + Guint flags, sdTemplate, sdrTemplate, huff, refAgg; + Guint huffDH, huffDW, huffBMSize, huffAggInst; + Guint contextUsed, contextRetained; + int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2]; + Guint numExSyms, numNewSyms, numInputSyms, symCodeLen; + JBIG2Bitmap **bitmaps; + JBIG2Bitmap *collBitmap, *refBitmap; + Guint *symWidths; + Guint symHeight, symWidth, totalWidth, x, symID; + int dh, dw, refAggNum, refDX, refDY, bmSize; + GBool ex; + int run, cnt; + Guint i, j, k; + Guchar *p; + + // symbol dictionary flags + if (!readUWord(&flags)) { + goto eofError; + } + sdTemplate = (flags >> 10) & 3; + sdrTemplate = (flags >> 12) & 1; + huff = flags & 1; + refAgg = (flags >> 1) & 1; + huffDH = (flags >> 2) & 3; + huffDW = (flags >> 4) & 3; + huffBMSize = (flags >> 6) & 1; + huffAggInst = (flags >> 7) & 1; + contextUsed = (flags >> 8) & 1; + contextRetained = (flags >> 9) & 1; + + // symbol dictionary AT flags + if (!huff) { + if (sdTemplate == 0) { + if (!readByte(&sdATX[0]) || + !readByte(&sdATY[0]) || + !readByte(&sdATX[1]) || + !readByte(&sdATY[1]) || + !readByte(&sdATX[2]) || + !readByte(&sdATY[2]) || + !readByte(&sdATX[3]) || + !readByte(&sdATY[3])) { + goto eofError; + } + } else { + if (!readByte(&sdATX[0]) || + !readByte(&sdATY[0])) { + goto eofError; + } + } + } + + // symbol dictionary refinement AT flags + if (refAgg && !sdrTemplate) { + if (!readByte(&sdrATX[0]) || + !readByte(&sdrATY[0]) || + !readByte(&sdrATX[1]) || + !readByte(&sdrATY[1])) { + goto eofError; + } + } + + // SDNUMEXSYMS and SDNUMNEWSYMS + if (!readULong(&numExSyms) || !readULong(&numNewSyms)) { + goto eofError; + } + + // get referenced segments: input symbol dictionaries and code tables + codeTables = new GooList(); + numInputSyms = 0; + for (i = 0; i < nRefSegs; ++i) { + seg = findSegment(refSegs[i]); + if (seg->getType() == jbig2SegSymbolDict) { + numInputSyms += ((JBIG2SymbolDict *)seg)->getSize(); + } else if (seg->getType() == jbig2SegCodeTable) { + codeTables->append(seg); + } + } + + // compute symbol code length + symCodeLen = 0; + i = 1; + while (i < numInputSyms + numNewSyms) { + ++symCodeLen; + i <<= 1; + } + + // get the input symbol bitmaps + bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms, + sizeof(JBIG2Bitmap *)); + for (i = 0; i < numInputSyms + numNewSyms; ++i) { + bitmaps[i] = NULL; + } + k = 0; + inputSymbolDict = NULL; + for (i = 0; i < nRefSegs; ++i) { + seg = findSegment(refSegs[i]); + if (seg->getType() == jbig2SegSymbolDict) { + inputSymbolDict = (JBIG2SymbolDict *)seg; + for (j = 0; j < inputSymbolDict->getSize(); ++j) { + bitmaps[k++] = inputSymbolDict->getBitmap(j); + } + } + } + + // get the Huffman tables + huffDHTable = huffDWTable = NULL; // make gcc happy + huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy + i = 0; + if (huff) { + if (huffDH == 0) { + huffDHTable = huffTableD; + } else if (huffDH == 1) { + huffDHTable = huffTableE; + } else { + huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffDW == 0) { + huffDWTable = huffTableB; + } else if (huffDW == 1) { + huffDWTable = huffTableC; + } else { + huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffBMSize == 0) { + huffBMSizeTable = huffTableA; + } else { + huffBMSizeTable = + ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffAggInst == 0) { + huffAggInstTable = huffTableA; + } else { + huffAggInstTable = + ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + } + delete codeTables; + + // set up the Huffman decoder + if (huff) { + huffDecoder->reset(); + + // set up the arithmetic decoder + } else { + if (contextUsed && inputSymbolDict) { + resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats()); + } else { + resetGenericStats(sdTemplate, NULL); + } + resetIntStats(symCodeLen); + arithDecoder->start(); + } + + // set up the arithmetic decoder for refinement/aggregation + if (refAgg) { + if (contextUsed && inputSymbolDict) { + resetRefinementStats(sdrTemplate, + inputSymbolDict->getRefinementRegionStats()); + } else { + resetRefinementStats(sdrTemplate, NULL); + } + } + + // allocate symbol widths storage + symWidths = NULL; + if (huff && !refAgg) { + symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint)); + } + + symHeight = 0; + i = 0; + while (i < numNewSyms) { + + // read the height class delta height + if (huff) { + huffDecoder->decodeInt(&dh, huffDHTable); + } else { + arithDecoder->decodeInt(&dh, iadhStats); + } + if (dh < 0 && (Guint)-dh >= symHeight) { + error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); + goto syntaxError; + } + symHeight += dh; + symWidth = 0; + totalWidth = 0; + j = i; + + // read the symbols in this height class + while (1) { + + // read the delta width + if (huff) { + if (!huffDecoder->decodeInt(&dw, huffDWTable)) { + break; + } + } else { + if (!arithDecoder->decodeInt(&dw, iadwStats)) { + break; + } + } + if (dw < 0 && (Guint)-dw >= symWidth) { + error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); + goto syntaxError; + } + symWidth += dw; + + // using a collective bitmap, so don't read a bitmap here + if (huff && !refAgg) { + symWidths[i] = symWidth; + totalWidth += symWidth; + + // refinement/aggregate coding + } else if (refAgg) { + if (huff) { + if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) { + break; + } + } else { + if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) { + break; + } + } +#if 0 //~ This special case was added about a year before the final draft + //~ of the JBIG2 spec was released. I have encountered some old + //~ JBIG2 images that predate it. + if (0) { +#else + if (refAggNum == 1) { +#endif + if (huff) { + symID = huffDecoder->readBits(symCodeLen); + huffDecoder->decodeInt(&refDX, huffTableO); + huffDecoder->decodeInt(&refDY, huffTableO); + huffDecoder->decodeInt(&bmSize, huffTableA); + huffDecoder->reset(); + arithDecoder->start(); + } else { + symID = arithDecoder->decodeIAID(symCodeLen, iaidStats); + arithDecoder->decodeInt(&refDX, iardxStats); + arithDecoder->decodeInt(&refDY, iardyStats); + } + refBitmap = bitmaps[symID]; + bitmaps[numInputSyms + i] = + readGenericRefinementRegion(symWidth, symHeight, + sdrTemplate, gFalse, + refBitmap, refDX, refDY, + sdrATX, sdrATY); + //~ do we need to use the bmSize value here (in Huffman mode)? + } else { + bitmaps[numInputSyms + i] = + readTextRegion(huff, gTrue, symWidth, symHeight, + refAggNum, 0, numInputSyms + i, NULL, + symCodeLen, bitmaps, 0, 0, 0, 1, 0, + huffTableF, huffTableH, huffTableK, huffTableO, + huffTableO, huffTableO, huffTableO, huffTableA, + sdrTemplate, sdrATX, sdrATY); + } + + // non-ref/agg coding + } else { + bitmaps[numInputSyms + i] = + readGenericBitmap(gFalse, symWidth, symHeight, + sdTemplate, gFalse, gFalse, NULL, + sdATX, sdATY, 0); + } + + ++i; + } + + // read the collective bitmap + if (huff && !refAgg) { + huffDecoder->decodeInt(&bmSize, huffBMSizeTable); + huffDecoder->reset(); + if (bmSize == 0) { + collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight); + bmSize = symHeight * ((totalWidth + 7) >> 3); + p = collBitmap->getDataPtr(); + for (k = 0; k < (Guint)bmSize; ++k) { + *p++ = curStr->getChar(); + } + } else { + collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight, + 0, gFalse, gFalse, NULL, NULL, NULL, + bmSize); + } + x = 0; + for (; j < i; ++j) { + bitmaps[numInputSyms + j] = + collBitmap->getSlice(x, 0, symWidths[j], symHeight); + x += symWidths[j]; + } + delete collBitmap; + } + } + + // create the symbol dict object + symbolDict = new JBIG2SymbolDict(segNum, numExSyms); + + // exported symbol list + i = j = 0; + ex = gFalse; + while (i < numInputSyms + numNewSyms) { + if (huff) { + huffDecoder->decodeInt(&run, huffTableA); + } else { + arithDecoder->decodeInt(&run, iaexStats); + } + if (ex) { + for (cnt = 0; cnt < run; ++cnt) { + symbolDict->setBitmap(j++, bitmaps[i++]->copy()); + } + } else { + i += run; + } + ex = !ex; + } + + for (i = 0; i < numNewSyms; ++i) { + delete bitmaps[numInputSyms + i]; + } + gfree(bitmaps); + if (symWidths) { + gfree(symWidths); + } + + // save the arithmetic decoder stats + if (!huff && contextRetained) { + symbolDict->setGenericRegionStats(genericRegionStats->copy()); + if (refAgg) { + symbolDict->setRefinementRegionStats(refinementRegionStats->copy()); + } + } + + // store the new symbol dict + segments->append(symbolDict); + + return gTrue; + + syntaxError: + for (i = 0; i < numNewSyms; ++i) { + if (bitmaps[numInputSyms + i]) { + delete bitmaps[numInputSyms + i]; + } + } + gfree(bitmaps); + if (symWidths) { + gfree(symWidths); + } + return gFalse; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); + return gFalse; +} + +void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length, + Guint *refSegs, Guint nRefSegs) { + JBIG2Bitmap *bitmap; + JBIG2HuffmanTable runLengthTab[36]; + JBIG2HuffmanTable *symCodeTab; + JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable; + JBIG2HuffmanTable *huffRDWTable, *huffRDHTable; + JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable; + JBIG2Segment *seg; + GooList *codeTables; + JBIG2SymbolDict *symbolDict; + JBIG2Bitmap **syms; + Guint w, h, x, y, segInfoFlags, extCombOp; + Guint flags, huff, refine, logStrips, refCorner, transposed; + Guint combOp, defPixel, templ; + int sOffset; + Guint huffFlags, huffFS, huffDS, huffDT; + Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize; + Guint numInstances, numSyms, symCodeLen; + int atx[2], aty[2]; + Guint i, k, kk; + int j; + + // region segment info field + if (!readULong(&w) || !readULong(&h) || + !readULong(&x) || !readULong(&y) || + !readUByte(&segInfoFlags)) { + goto eofError; + } + extCombOp = segInfoFlags & 7; + + // rest of the text region header + if (!readUWord(&flags)) { + goto eofError; + } + huff = flags & 1; + refine = (flags >> 1) & 1; + logStrips = (flags >> 2) & 3; + refCorner = (flags >> 4) & 3; + transposed = (flags >> 6) & 1; + combOp = (flags >> 7) & 3; + defPixel = (flags >> 9) & 1; + sOffset = (flags >> 10) & 0x1f; + if (sOffset & 0x10) { + sOffset |= -1 - 0x0f; + } + templ = (flags >> 15) & 1; + huffFS = huffDS = huffDT = 0; // make gcc happy + huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy + if (huff) { + if (!readUWord(&huffFlags)) { + goto eofError; + } + huffFS = huffFlags & 3; + huffDS = (huffFlags >> 2) & 3; + huffDT = (huffFlags >> 4) & 3; + huffRDW = (huffFlags >> 6) & 3; + huffRDH = (huffFlags >> 8) & 3; + huffRDX = (huffFlags >> 10) & 3; + huffRDY = (huffFlags >> 12) & 3; + huffRSize = (huffFlags >> 14) & 1; + } + if (refine && templ == 0) { + if (!readByte(&atx[0]) || !readByte(&aty[0]) || + !readByte(&atx[1]) || !readByte(&aty[1])) { + goto eofError; + } + } + if (!readULong(&numInstances)) { + goto eofError; + } + + // get symbol dictionaries and tables + codeTables = new GooList(); + numSyms = 0; + for (i = 0; i < nRefSegs; ++i) { + if ((seg = findSegment(refSegs[i]))) { + if (seg->getType() == jbig2SegSymbolDict) { + numSyms += ((JBIG2SymbolDict *)seg)->getSize(); + } else if (seg->getType() == jbig2SegCodeTable) { + codeTables->append(seg); + } + } else { + error(getPos(), "Invalid segment reference in JBIG2 text region"); + } + } + symCodeLen = 0; + i = 1; + while (i < numSyms) { + ++symCodeLen; + i <<= 1; + } + + // get the symbol bitmaps + syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *)); + kk = 0; + for (i = 0; i < nRefSegs; ++i) { + if ((seg = findSegment(refSegs[i]))) { + if (seg->getType() == jbig2SegSymbolDict) { + symbolDict = (JBIG2SymbolDict *)seg; + for (k = 0; k < symbolDict->getSize(); ++k) { + syms[kk++] = symbolDict->getBitmap(k); + } + } + } + } + + // get the Huffman tables + huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy + huffRDWTable = huffRDHTable = NULL; // make gcc happy + huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy + i = 0; + if (huff) { + if (huffFS == 0) { + huffFSTable = huffTableF; + } else if (huffFS == 1) { + huffFSTable = huffTableG; + } else { + huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffDS == 0) { + huffDSTable = huffTableH; + } else if (huffDS == 1) { + huffDSTable = huffTableI; + } else if (huffDS == 2) { + huffDSTable = huffTableJ; + } else { + huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffDT == 0) { + huffDTTable = huffTableK; + } else if (huffDT == 1) { + huffDTTable = huffTableL; + } else if (huffDT == 2) { + huffDTTable = huffTableM; + } else { + huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffRDW == 0) { + huffRDWTable = huffTableN; + } else if (huffRDW == 1) { + huffRDWTable = huffTableO; + } else { + huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffRDH == 0) { + huffRDHTable = huffTableN; + } else if (huffRDH == 1) { + huffRDHTable = huffTableO; + } else { + huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffRDX == 0) { + huffRDXTable = huffTableN; + } else if (huffRDX == 1) { + huffRDXTable = huffTableO; + } else { + huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffRDY == 0) { + huffRDYTable = huffTableN; + } else if (huffRDY == 1) { + huffRDYTable = huffTableO; + } else { + huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + if (huffRSize == 0) { + huffRSizeTable = huffTableA; + } else { + huffRSizeTable = + ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); + } + } + delete codeTables; + + // symbol ID Huffman decoding table + if (huff) { + huffDecoder->reset(); + for (i = 0; i < 32; ++i) { + runLengthTab[i].val = i; + runLengthTab[i].prefixLen = huffDecoder->readBits(4); + runLengthTab[i].rangeLen = 0; + } + runLengthTab[32].val = 0x103; + runLengthTab[32].prefixLen = huffDecoder->readBits(4); + runLengthTab[32].rangeLen = 2; + runLengthTab[33].val = 0x203; + runLengthTab[33].prefixLen = huffDecoder->readBits(4); + runLengthTab[33].rangeLen = 3; + runLengthTab[34].val = 0x20b; + runLengthTab[34].prefixLen = huffDecoder->readBits(4); + runLengthTab[34].rangeLen = 7; + runLengthTab[35].prefixLen = 0; + runLengthTab[35].rangeLen = jbig2HuffmanEOT; + huffDecoder->buildTable(runLengthTab, 35); + symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1, + sizeof(JBIG2HuffmanTable)); + for (i = 0; i < numSyms; ++i) { + symCodeTab[i].val = i; + symCodeTab[i].rangeLen = 0; + } + i = 0; + while (i < numSyms) { + huffDecoder->decodeInt(&j, runLengthTab); + if (j > 0x200) { + for (j -= 0x200; j && i < numSyms; --j) { + symCodeTab[i++].prefixLen = 0; + } + } else if (j > 0x100) { + for (j -= 0x100; j && i < numSyms; --j) { + symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen; + ++i; + } + } else { + symCodeTab[i++].prefixLen = j; + } + } + symCodeTab[numSyms].prefixLen = 0; + symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT; + huffDecoder->buildTable(symCodeTab, numSyms); + huffDecoder->reset(); + + // set up the arithmetic decoder + } else { + symCodeTab = NULL; + resetIntStats(symCodeLen); + arithDecoder->start(); + } + if (refine) { + resetRefinementStats(templ, NULL); + } + + bitmap = readTextRegion(huff, refine, w, h, numInstances, + logStrips, numSyms, symCodeTab, symCodeLen, syms, + defPixel, combOp, transposed, refCorner, sOffset, + huffFSTable, huffDSTable, huffDTTable, + huffRDWTable, huffRDHTable, + huffRDXTable, huffRDYTable, huffRSizeTable, + templ, atx, aty); + + gfree(syms); + + // combine the region bitmap into the page bitmap + if (imm) { + if (pageH == 0xffffffff && y + h > curPageH) { + pageBitmap->expand(y + h, pageDefPixel); + } + pageBitmap->combine(bitmap, x, y, extCombOp); + delete bitmap; + + // store the region bitmap + } else { + bitmap->setSegNum(segNum); + segments->append(bitmap); + } + + // clean up the Huffman decoder + if (huff) { + gfree(symCodeTab); + } + + return; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, + int w, int h, + Guint numInstances, + Guint logStrips, + int numSyms, + JBIG2HuffmanTable *symCodeTab, + Guint symCodeLen, + JBIG2Bitmap **syms, + Guint defPixel, Guint combOp, + Guint transposed, Guint refCorner, + int sOffset, + JBIG2HuffmanTable *huffFSTable, + JBIG2HuffmanTable *huffDSTable, + JBIG2HuffmanTable *huffDTTable, + JBIG2HuffmanTable *huffRDWTable, + JBIG2HuffmanTable *huffRDHTable, + JBIG2HuffmanTable *huffRDXTable, + JBIG2HuffmanTable *huffRDYTable, + JBIG2HuffmanTable *huffRSizeTable, + Guint templ, + int *atx, int *aty) { + JBIG2Bitmap *bitmap; + JBIG2Bitmap *symbolBitmap; + Guint strips; + int t, dt, tt, s, ds, sFirst, j; + int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize; + Guint symID, inst, bw, bh; + + strips = 1 << logStrips; + + // allocate the bitmap + bitmap = new JBIG2Bitmap(0, w, h); + if (defPixel) { + bitmap->clearToOne(); + } else { + bitmap->clearToZero(); + } + + // decode initial T value + if (huff) { + huffDecoder->decodeInt(&t, huffDTTable); + } else { + arithDecoder->decodeInt(&t, iadtStats); + } + t *= -(int)strips; + + inst = 0; + sFirst = 0; + while (inst < numInstances) { + + // decode delta-T + if (huff) { + huffDecoder->decodeInt(&dt, huffDTTable); + } else { + arithDecoder->decodeInt(&dt, iadtStats); + } + t += dt * strips; + + // first S value + if (huff) { + huffDecoder->decodeInt(&ds, huffFSTable); + } else { + arithDecoder->decodeInt(&ds, iafsStats); + } + sFirst += ds; + s = sFirst; + + // read the instances + while (1) { + + // T value + if (strips == 1) { + dt = 0; + } else if (huff) { + dt = huffDecoder->readBits(logStrips); + } else { + arithDecoder->decodeInt(&dt, iaitStats); + } + tt = t + dt; + + // symbol ID + if (huff) { + if (symCodeTab) { + huffDecoder->decodeInt(&j, symCodeTab); + symID = (Guint)j; + } else { + symID = huffDecoder->readBits(symCodeLen); + } + } else { + symID = arithDecoder->decodeIAID(symCodeLen, iaidStats); + } + + if (symID >= (Guint)numSyms) { + error(getPos(), "Invalid symbol number in JBIG2 text region"); + } else { + + // get the symbol bitmap + symbolBitmap = NULL; + if (refine) { + if (huff) { + ri = (int)huffDecoder->readBit(); + } else { + arithDecoder->decodeInt(&ri, iariStats); + } + } else { + ri = 0; + } + if (ri) { + if (huff) { + huffDecoder->decodeInt(&rdw, huffRDWTable); + huffDecoder->decodeInt(&rdh, huffRDHTable); + huffDecoder->decodeInt(&rdx, huffRDXTable); + huffDecoder->decodeInt(&rdy, huffRDYTable); + huffDecoder->decodeInt(&bmSize, huffRSizeTable); + huffDecoder->reset(); + arithDecoder->start(); + } else { + arithDecoder->decodeInt(&rdw, iardwStats); + arithDecoder->decodeInt(&rdh, iardhStats); + arithDecoder->decodeInt(&rdx, iardxStats); + arithDecoder->decodeInt(&rdy, iardyStats); + } + refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx; + refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy; + + symbolBitmap = + readGenericRefinementRegion(rdw + syms[symID]->getWidth(), + rdh + syms[symID]->getHeight(), + templ, gFalse, syms[symID], + refDX, refDY, atx, aty); + //~ do we need to use the bmSize value here (in Huffman mode)? + } else { + symbolBitmap = syms[symID]; + } + + // combine the symbol bitmap into the region bitmap + //~ something is wrong here - refCorner shouldn't degenerate into + //~ two cases + bw = symbolBitmap->getWidth() - 1; + bh = symbolBitmap->getHeight() - 1; + if (transposed) { + switch (refCorner) { + case 0: // bottom left + bitmap->combine(symbolBitmap, tt, s, combOp); + break; + case 1: // top left + bitmap->combine(symbolBitmap, tt, s, combOp); + break; + case 2: // bottom right + bitmap->combine(symbolBitmap, tt - bw, s, combOp); + break; + case 3: // top right + bitmap->combine(symbolBitmap, tt - bw, s, combOp); + break; + } + s += bh; + } else { + switch (refCorner) { + case 0: // bottom left + bitmap->combine(symbolBitmap, s, tt - bh, combOp); + break; + case 1: // top left + bitmap->combine(symbolBitmap, s, tt, combOp); + break; + case 2: // bottom right + bitmap->combine(symbolBitmap, s, tt - bh, combOp); + break; + case 3: // top right + bitmap->combine(symbolBitmap, s, tt, combOp); + break; + } + s += bw; + } + if (ri) { + delete symbolBitmap; + } + } + + // next instance + ++inst; + + // next S value + if (huff) { + if (!huffDecoder->decodeInt(&ds, huffDSTable)) { + break; + } + } else { + if (!arithDecoder->decodeInt(&ds, iadsStats)) { + break; + } + } + s += sOffset + ds; + } + } + + return bitmap; +} + +void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) { + JBIG2PatternDict *patternDict; + JBIG2Bitmap *bitmap; + Guint flags, patternW, patternH, grayMax, templ, mmr; + int atx[4], aty[4]; + Guint i, x; + + // halftone dictionary flags, pattern width and height, max gray value + if (!readUByte(&flags) || + !readUByte(&patternW) || + !readUByte(&patternH) || + !readULong(&grayMax)) { + goto eofError; + } + templ = (flags >> 1) & 3; + mmr = flags & 1; + + // set up the arithmetic decoder + if (!mmr) { + resetGenericStats(templ, NULL); + arithDecoder->start(); + } + + // read the bitmap + atx[0] = -(int)patternW; aty[0] = 0; + atx[1] = -3; aty[1] = -1; + atx[2] = 2; aty[2] = -2; + atx[3] = -2; aty[3] = -2; + bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH, + templ, gFalse, gFalse, NULL, + atx, aty, length - 7); + + // create the pattern dict object + patternDict = new JBIG2PatternDict(segNum, grayMax + 1); + + // split up the bitmap + x = 0; + for (i = 0; i <= grayMax; ++i) { + patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH)); + x += patternW; + } + + // free memory + delete bitmap; + + // store the new pattern dict + segments->append(patternDict); + + return; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length, + Guint *refSegs, Guint nRefSegs) { + JBIG2Bitmap *bitmap; + JBIG2Segment *seg; + JBIG2PatternDict *patternDict; + JBIG2Bitmap *skipBitmap; + Guint *grayImg; + JBIG2Bitmap *grayBitmap; + JBIG2Bitmap *patternBitmap; + Guint w, h, x, y, segInfoFlags, extCombOp; + Guint flags, mmr, templ, enableSkip, combOp; + Guint gridW, gridH, stepX, stepY, patW, patH; + int atx[4], aty[4]; + int gridX, gridY, xx, yy, bit, j; + Guint bpp, m, n, i; + + // region segment info field + if (!readULong(&w) || !readULong(&h) || + !readULong(&x) || !readULong(&y) || + !readUByte(&segInfoFlags)) { + goto eofError; + } + extCombOp = segInfoFlags & 7; + + // rest of the halftone region header + if (!readUByte(&flags)) { + goto eofError; + } + mmr = flags & 1; + templ = (flags >> 1) & 3; + enableSkip = (flags >> 3) & 1; + combOp = (flags >> 4) & 7; + if (!readULong(&gridW) || !readULong(&gridH) || + !readLong(&gridX) || !readLong(&gridY) || + !readUWord(&stepX) || !readUWord(&stepY)) { + goto eofError; + } + if (w == 0 || h == 0 || w >= INT_MAX / h) { + error(getPos(), "Bad bitmap size in JBIG2 halftone segment"); + return; + } + if (gridH == 0 || gridW >= INT_MAX / gridH) { + error(getPos(), "Bad grid size in JBIG2 halftone segment"); + return; + } + + // get pattern dictionary + if (nRefSegs != 1) { + error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); + return; + } + seg = findSegment(refSegs[0]); + if (seg->getType() != jbig2SegPatternDict) { + error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); + return; + } + if (gridH == 0 || gridW >= INT_MAX / gridH) { + error(getPos(), "Bad size in JBIG2 halftone segment"); + return; + } + if (w == 0 || h >= INT_MAX / w) { + error(getPos(), "Bad size in JBIG2 bitmap segment"); + return; + } + + patternDict = (JBIG2PatternDict *)seg; + bpp = 0; + i = 1; + while (i < patternDict->getSize()) { + ++bpp; + i <<= 1; + } + patW = patternDict->getBitmap(0)->getWidth(); + patH = patternDict->getBitmap(0)->getHeight(); + + // set up the arithmetic decoder + if (!mmr) { + resetGenericStats(templ, NULL); + arithDecoder->start(); + } + + // allocate the bitmap + bitmap = new JBIG2Bitmap(segNum, w, h); + if (flags & 0x80) { // HDEFPIXEL + bitmap->clearToOne(); + } else { + bitmap->clearToZero(); + } + + // compute the skip bitmap + skipBitmap = NULL; + if (enableSkip) { + skipBitmap = new JBIG2Bitmap(0, gridW, gridH); + skipBitmap->clearToZero(); + for (m = 0; m < gridH; ++m) { + xx = gridX + m * stepY; + yy = gridY + m * stepX; + for (n = 0; n < gridW; ++n) { + if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w || + ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) { + skipBitmap->setPixel(n, m); + } + } + } + } + + // read the gray-scale image + grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint)); + memset(grayImg, 0, gridW * gridH * sizeof(Guint)); + atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1; + atx[1] = -3; aty[1] = -1; + atx[2] = 2; aty[2] = -2; + atx[3] = -2; aty[3] = -2; + for (j = bpp - 1; j >= 0; --j) { + grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse, + enableSkip, skipBitmap, atx, aty, -1); + i = 0; + for (m = 0; m < gridH; ++m) { + for (n = 0; n < gridW; ++n) { + bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1); + grayImg[i] = (grayImg[i] << 1) | bit; + ++i; + } + } + delete grayBitmap; + } + + // decode the image + i = 0; + for (m = 0; m < gridH; ++m) { + xx = gridX + m * stepY; + yy = gridY + m * stepX; + for (n = 0; n < gridW; ++n) { + if (!(enableSkip && skipBitmap->getPixel(n, m))) { + patternBitmap = patternDict->getBitmap(grayImg[i]); + bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp); + } + xx += stepX; + yy -= stepY; + ++i; + } + } + + delete skipBitmap; + gfree(grayImg); + + // combine the region bitmap into the page bitmap + if (imm) { + if (pageH == 0xffffffff && y + h > curPageH) { + pageBitmap->expand(y + h, pageDefPixel); + } + pageBitmap->combine(bitmap, x, y, extCombOp); + delete bitmap; + + // store the region bitmap + } else { + segments->append(bitmap); + } + + return; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length) { + JBIG2Bitmap *bitmap; + Guint w, h, x, y, segInfoFlags, extCombOp; + Guint flags, mmr, templ, tpgdOn; + int atx[4], aty[4]; + + // region segment info field + if (!readULong(&w) || !readULong(&h) || + !readULong(&x) || !readULong(&y) || + !readUByte(&segInfoFlags)) { + goto eofError; + } + extCombOp = segInfoFlags & 7; + + // rest of the generic region segment header + if (!readUByte(&flags)) { + goto eofError; + } + mmr = flags & 1; + templ = (flags >> 1) & 3; + tpgdOn = (flags >> 3) & 1; + + // AT flags + if (!mmr) { + if (templ == 0) { + if (!readByte(&atx[0]) || + !readByte(&aty[0]) || + !readByte(&atx[1]) || + !readByte(&aty[1]) || + !readByte(&atx[2]) || + !readByte(&aty[2]) || + !readByte(&atx[3]) || + !readByte(&aty[3])) { + goto eofError; + } + } else { + if (!readByte(&atx[0]) || + !readByte(&aty[0])) { + goto eofError; + } + } + } + + // set up the arithmetic decoder + if (!mmr) { + resetGenericStats(templ, NULL); + arithDecoder->start(); + } + + // read the bitmap + bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse, + NULL, atx, aty, mmr ? 0 : length - 18); + + // combine the region bitmap into the page bitmap + if (imm) { + if (pageH == 0xffffffff && y + h > curPageH) { + pageBitmap->expand(y + h, pageDefPixel); + } + pageBitmap->combine(bitmap, x, y, extCombOp); + delete bitmap; + + // store the region bitmap + } else { + bitmap->setSegNum(segNum); + segments->append(bitmap); + } + + return; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, + int templ, GBool tpgdOn, + GBool useSkip, JBIG2Bitmap *skip, + int *atx, int *aty, + int mmrDataLength) { + JBIG2Bitmap *bitmap; + GBool ltp; + Guint ltpCX, cx, cx0, cx1, cx2; + JBIG2BitmapPtr cxPtr0, cxPtr1; + JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3; + int *refLine, *codingLine; + int code1, code2, code3; + int x, y, a0, pix, i, refI, codingI; + + bitmap = new JBIG2Bitmap(0, w, h); + bitmap->clearToZero(); + + //----- MMR decode + + if (mmr) { + + mmrDecoder->reset(); + refLine = (int *)gmallocn(w + 2, sizeof(int)); + codingLine = (int *)gmallocn(w + 2, sizeof(int)); + codingLine[0] = codingLine[1] = w; + + for (y = 0; y < h; ++y) { + + // copy coding line to ref line + for (i = 0; codingLine[i] < w; ++i) { + refLine[i] = codingLine[i]; + } + refLine[i] = refLine[i + 1] = w; + + // decode a line + refI = 0; // b1 = refLine[refI] + codingI = 0; // a1 = codingLine[codingI] + a0 = 0; + do { + code1 = mmrDecoder->get2DCode(); + switch (code1) { + case twoDimPass: + if (refLine[refI] < w) { + a0 = refLine[refI + 1]; + refI += 2; + } + break; + case twoDimHoriz: + if (codingI & 1) { + code1 = 0; + do { + code1 += code3 = mmrDecoder->getBlackCode(); + } while (code3 >= 64); + code2 = 0; + do { + code2 += code3 = mmrDecoder->getWhiteCode(); + } while (code3 >= 64); + } else { + code1 = 0; + do { + code1 += code3 = mmrDecoder->getWhiteCode(); + } while (code3 >= 64); + code2 = 0; + do { + code2 += code3 = mmrDecoder->getBlackCode(); + } while (code3 >= 64); + } + if (code1 > 0 || code2 > 0) { + a0 = codingLine[codingI++] = a0 + code1; + a0 = codingLine[codingI++] = a0 + code2; + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } + } + break; + case twoDimVert0: + a0 = codingLine[codingI++] = refLine[refI]; + if (refLine[refI] < w) { + ++refI; + } + break; + case twoDimVertR1: + a0 = codingLine[codingI++] = refLine[refI] + 1; + if (refLine[refI] < w) { + ++refI; + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } + } + break; + case twoDimVertR2: + a0 = codingLine[codingI++] = refLine[refI] + 2; + if (refLine[refI] < w) { + ++refI; + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } + } + break; + case twoDimVertR3: + a0 = codingLine[codingI++] = refLine[refI] + 3; + if (refLine[refI] < w) { + ++refI; + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } + } + break; + case twoDimVertL1: + a0 = codingLine[codingI++] = refLine[refI] - 1; + if (refI > 0) { + --refI; + } else { + ++refI; + } + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } + break; + case twoDimVertL2: + a0 = codingLine[codingI++] = refLine[refI] - 2; + if (refI > 0) { + --refI; + } else { + ++refI; + } + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } + break; + case twoDimVertL3: + a0 = codingLine[codingI++] = refLine[refI] - 3; + if (refI > 0) { + --refI; + } else { + ++refI; + } + while (refLine[refI] <= a0 && refLine[refI] < w) { + refI += 2; + } + break; + default: + error(getPos(), "Illegal code in JBIG2 MMR bitmap data"); + break; + } + } while (a0 < w); + codingLine[codingI++] = w; + + // convert the run lengths to a bitmap line + i = 0; + while (codingLine[i] < w) { + for (x = codingLine[i]; x < codingLine[i+1]; ++x) { + bitmap->setPixel(x, y); + } + i += 2; + } + } + + if (mmrDataLength >= 0) { + mmrDecoder->skipTo(mmrDataLength); + } else { + if (mmrDecoder->get24Bits() != 0x001001) { + error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data"); + } + } + + gfree(refLine); + gfree(codingLine); + + //----- arithmetic decode + + } else { + // set up the typical row context + ltpCX = 0; // make gcc happy + if (tpgdOn) { + switch (templ) { + case 0: + ltpCX = 0x3953; // 001 11001 0101 0011 + break; + case 1: + ltpCX = 0x079a; // 0011 11001 101 0 + break; + case 2: + ltpCX = 0x0e3; // 001 1100 01 1 + break; + case 3: + ltpCX = 0x18a; // 01100 0101 1 + break; + } + } + + ltp = 0; + cx = cx0 = cx1 = cx2 = 0; // make gcc happy + for (y = 0; y < h; ++y) { + + // check for a "typical" (duplicate) row + if (tpgdOn) { + if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) { + ltp = !ltp; + } + if (ltp) { + bitmap->duplicateRow(y, y-1); + continue; + } + } + + switch (templ) { + case 0: + + // set up the context + bitmap->getPixelPtr(0, y-2, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); + bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1); + bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2); + bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3); + + // decode the row + for (x = 0; x < w; ++x) { + + // build the context + cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) | + (bitmap->nextPixel(&atPtr0) << 3) | + (bitmap->nextPixel(&atPtr1) << 2) | + (bitmap->nextPixel(&atPtr2) << 1) | + bitmap->nextPixel(&atPtr3); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; + + // decode the pixel + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + bitmap->setPixel(x, y); + } + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07; + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; + cx2 = ((cx2 << 1) | pix) & 0x0f; + } + break; + + case 1: + + // set up the context + bitmap->getPixelPtr(0, y-2, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); + + // decode the row + for (x = 0; x < w; ++x) { + + // build the context + cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) | + bitmap->nextPixel(&atPtr0); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; + + // decode the pixel + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + bitmap->setPixel(x, y); + } + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f; + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; + cx2 = ((cx2 << 1) | pix) & 0x07; + } + break; + + case 2: + + // set up the context + bitmap->getPixelPtr(0, y-2, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); + + // decode the row + for (x = 0; x < w; ++x) { + + // build the context + cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) | + bitmap->nextPixel(&atPtr0); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; + + // decode the pixel + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + bitmap->setPixel(x, y); + } + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07; + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f; + cx2 = ((cx2 << 1) | pix) & 0x03; + } + break; + + case 3: + + // set up the context + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); + + // decode the row + for (x = 0; x < w; ++x) { + + // build the context + cx = (cx1 << 5) | (cx2 << 1) | + bitmap->nextPixel(&atPtr0); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; + + // decode the pixel + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + bitmap->setPixel(x, y); + } + + // update the context + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; + cx2 = ((cx2 << 1) | pix) & 0x0f; + } + break; + } + } + } + + return bitmap; +} + +void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length, + Guint *refSegs, + Guint nRefSegs) { + JBIG2Bitmap *bitmap, *refBitmap; + Guint w, h, x, y, segInfoFlags, extCombOp; + Guint flags, templ, tpgrOn; + int atx[2], aty[2]; + JBIG2Segment *seg; + + // region segment info field + if (!readULong(&w) || !readULong(&h) || + !readULong(&x) || !readULong(&y) || + !readUByte(&segInfoFlags)) { + goto eofError; + } + extCombOp = segInfoFlags & 7; + + // rest of the generic refinement region segment header + if (!readUByte(&flags)) { + goto eofError; + } + templ = flags & 1; + tpgrOn = (flags >> 1) & 1; + + // AT flags + if (!templ) { + if (!readByte(&atx[0]) || !readByte(&aty[0]) || + !readByte(&atx[1]) || !readByte(&aty[1])) { + goto eofError; + } + } + + // resize the page bitmap if needed + if (nRefSegs == 0 || imm) { + if (pageH == 0xffffffff && y + h > curPageH) { + pageBitmap->expand(y + h, pageDefPixel); + } + } + + // get referenced bitmap + if (nRefSegs > 1) { + error(getPos(), "Bad reference in JBIG2 generic refinement segment"); + return; + } + if (nRefSegs == 1) { + seg = findSegment(refSegs[0]); + if (seg->getType() != jbig2SegBitmap) { + error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment"); + return; + } + refBitmap = (JBIG2Bitmap *)seg; + } else { + refBitmap = pageBitmap->getSlice(x, y, w, h); + } + + // set up the arithmetic decoder + resetRefinementStats(templ, NULL); + arithDecoder->start(); + + // read + bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn, + refBitmap, 0, 0, atx, aty); + + // combine the region bitmap into the page bitmap + if (imm) { + pageBitmap->combine(bitmap, x, y, extCombOp); + delete bitmap; + + // store the region bitmap + } else { + bitmap->setSegNum(segNum); + segments->append(bitmap); + } + + // delete the referenced bitmap + if (nRefSegs == 1) { + discardSegment(refSegs[0]); + } else { + delete refBitmap; + } + + return; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h, + int templ, GBool tpgrOn, + JBIG2Bitmap *refBitmap, + int refDX, int refDY, + int *atx, int *aty) { + JBIG2Bitmap *bitmap; + GBool ltp; + Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2; + JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6; + JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2; + int x, y, pix; + + if (w < 0 || h <= 0 || w >= INT_MAX / h) { + error(-1, "invalid width/height"); + return NULL; + } + + bitmap = new JBIG2Bitmap(0, w, h); + bitmap->clearToZero(); + + // set up the typical row context + if (templ) { + ltpCX = 0x008; + } else { + ltpCX = 0x0010; + } + + ltp = 0; + for (y = 0; y < h; ++y) { + + if (templ) { + + // set up the context + bitmap->getPixelPtr(0, y-1, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(-1, y, &cxPtr1); + refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3); + cx3 = refBitmap->nextPixel(&cxPtr3); + cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3); + refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4); + cx4 = refBitmap->nextPixel(&cxPtr4); + + // set up the typical prediction context + tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy + if (tpgrOn) { + refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0); + tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1); + tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2); + tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); + } + + for (x = 0; x < w; ++x) { + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7; + cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7; + cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3; + + if (tpgrOn) { + // update the typical predictor context + tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7; + tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7; + tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7; + + // check for a "typical" pixel + if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) { + ltp = !ltp; + } + if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) { + bitmap->clearPixel(x, y); + continue; + } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) { + bitmap->setPixel(x, y); + continue; + } + } + + // build the context + cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) | + (refBitmap->nextPixel(&cxPtr2) << 5) | + (cx3 << 2) | cx4; + + // decode the pixel + if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) { + bitmap->setPixel(x, y); + } + } + + } else { + + // set up the context + bitmap->getPixelPtr(0, y-1, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(-1, y, &cxPtr1); + refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2); + cx2 = refBitmap->nextPixel(&cxPtr2); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3); + cx3 = refBitmap->nextPixel(&cxPtr3); + cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3); + refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4); + cx4 = refBitmap->nextPixel(&cxPtr4); + cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4); + bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5); + refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6); + + // set up the typical prediction context + tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy + if (tpgrOn) { + refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0); + tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1); + tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2); + tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); + } + + for (x = 0; x < w; ++x) { + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3; + cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3; + cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7; + cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7; + + if (tpgrOn) { + // update the typical predictor context + tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7; + tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7; + tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7; + + // check for a "typical" pixel + if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) { + ltp = !ltp; + } + if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) { + bitmap->clearPixel(x, y); + continue; + } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) { + bitmap->setPixel(x, y); + continue; + } + } + + // build the context + cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) | + (cx2 << 8) | (cx3 << 5) | (cx4 << 2) | + (bitmap->nextPixel(&cxPtr5) << 1) | + refBitmap->nextPixel(&cxPtr6); + + // decode the pixel + if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) { + bitmap->setPixel(x, y); + } + } + } + } + + return bitmap; +} + +void JBIG2Stream::readPageInfoSeg(Guint length) { + Guint xRes, yRes, flags, striping; + + if (!readULong(&pageW) || !readULong(&pageH) || + !readULong(&xRes) || !readULong(&yRes) || + !readUByte(&flags) || !readUWord(&striping)) { + goto eofError; + } + pageDefPixel = (flags >> 2) & 1; + defCombOp = (flags >> 3) & 3; + + // allocate the page bitmap + if (pageH == 0xffffffff) { + curPageH = striping & 0x7fff; + } else { + curPageH = pageH; + } + pageBitmap = new JBIG2Bitmap(0, pageW, curPageH); + + // default pixel value + if (pageDefPixel) { + pageBitmap->clearToOne(); + } else { + pageBitmap->clearToZero(); + } + + return; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +void JBIG2Stream::readEndOfStripeSeg(Guint length) { + Guint i; + + // skip the segment + for (i = 0; i < length; ++i) { + curStr->getChar(); + } +} + +void JBIG2Stream::readProfilesSeg(Guint length) { + Guint i; + + // skip the segment + for (i = 0; i < length; ++i) { + curStr->getChar(); + } +} + +void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) { + JBIG2HuffmanTable *huffTab; + Guint flags, oob, prefixBits, rangeBits; + int lowVal, highVal, val; + Guint huffTabSize, i; + + if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) { + goto eofError; + } + oob = flags & 1; + prefixBits = ((flags >> 1) & 7) + 1; + rangeBits = ((flags >> 4) & 7) + 1; + + huffDecoder->reset(); + huffTabSize = 8; + huffTab = (JBIG2HuffmanTable *) + gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable)); + i = 0; + val = lowVal; + while (val < highVal) { + if (i == huffTabSize) { + huffTabSize *= 2; + huffTab = (JBIG2HuffmanTable *) + greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable)); + } + huffTab[i].val = val; + huffTab[i].prefixLen = huffDecoder->readBits(prefixBits); + huffTab[i].rangeLen = huffDecoder->readBits(rangeBits); + val += 1 << huffTab[i].rangeLen; + ++i; + } + if (i + oob + 3 > huffTabSize) { + huffTabSize = i + oob + 3; + huffTab = (JBIG2HuffmanTable *) + greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable)); + } + huffTab[i].val = lowVal - 1; + huffTab[i].prefixLen = huffDecoder->readBits(prefixBits); + huffTab[i].rangeLen = jbig2HuffmanLOW; + ++i; + huffTab[i].val = highVal; + huffTab[i].prefixLen = huffDecoder->readBits(prefixBits); + huffTab[i].rangeLen = 32; + ++i; + if (oob) { + huffTab[i].val = 0; + huffTab[i].prefixLen = huffDecoder->readBits(prefixBits); + huffTab[i].rangeLen = jbig2HuffmanOOB; + ++i; + } + huffTab[i].val = 0; + huffTab[i].prefixLen = 0; + huffTab[i].rangeLen = jbig2HuffmanEOT; + huffDecoder->buildTable(huffTab, i); + + // create and store the new table segment + segments->append(new JBIG2CodeTable(segNum, huffTab)); + + return; + + eofError: + error(getPos(), "Unexpected EOF in JBIG2 stream"); +} + +void JBIG2Stream::readExtensionSeg(Guint length) { + Guint i; + + // skip the segment + for (i = 0; i < length; ++i) { + curStr->getChar(); + } +} + +JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) { + JBIG2Segment *seg; + int i; + + for (i = 0; i < globalSegments->getLength(); ++i) { + seg = (JBIG2Segment *)globalSegments->get(i); + if (seg->getSegNum() == segNum) { + return seg; + } + } + for (i = 0; i < segments->getLength(); ++i) { + seg = (JBIG2Segment *)segments->get(i); + if (seg->getSegNum() == segNum) { + return seg; + } + } + return NULL; +} + +void JBIG2Stream::discardSegment(Guint segNum) { + JBIG2Segment *seg; + int i; + + for (i = 0; i < globalSegments->getLength(); ++i) { + seg = (JBIG2Segment *)globalSegments->get(i); + if (seg->getSegNum() == segNum) { + globalSegments->del(i); + return; + } + } + for (i = 0; i < segments->getLength(); ++i) { + seg = (JBIG2Segment *)segments->get(i); + if (seg->getSegNum() == segNum) { + segments->del(i); + return; + } + } +} + +void JBIG2Stream::resetGenericStats(Guint templ, + JArithmeticDecoderStats *prevStats) { + int size; + + size = contextSize[templ]; + if (prevStats && prevStats->getContextSize() == size) { + if (genericRegionStats->getContextSize() == size) { + genericRegionStats->copyFrom(prevStats); + } else { + delete genericRegionStats; + genericRegionStats = prevStats->copy(); + } + } else { + if (genericRegionStats->getContextSize() == size) { + genericRegionStats->reset(); + } else { + delete genericRegionStats; + genericRegionStats = new JArithmeticDecoderStats(1 << size); + } + } +} + +void JBIG2Stream::resetRefinementStats(Guint templ, + JArithmeticDecoderStats *prevStats) { + int size; + + size = refContextSize[templ]; + if (prevStats && prevStats->getContextSize() == size) { + if (refinementRegionStats->getContextSize() == size) { + refinementRegionStats->copyFrom(prevStats); + } else { + delete refinementRegionStats; + refinementRegionStats = prevStats->copy(); + } + } else { + if (refinementRegionStats->getContextSize() == size) { + refinementRegionStats->reset(); + } else { + delete refinementRegionStats; + refinementRegionStats = new JArithmeticDecoderStats(1 << size); + } + } +} + +void JBIG2Stream::resetIntStats(int symCodeLen) { + iadhStats->reset(); + iadwStats->reset(); + iaexStats->reset(); + iaaiStats->reset(); + iadtStats->reset(); + iaitStats->reset(); + iafsStats->reset(); + iadsStats->reset(); + iardxStats->reset(); + iardyStats->reset(); + iardwStats->reset(); + iardhStats->reset(); + iariStats->reset(); + if (iaidStats->getContextSize() == symCodeLen + 1) { + iaidStats->reset(); + } else { + delete iaidStats; + iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1)); + } +} + +GBool JBIG2Stream::readUByte(Guint *x) { + int c0; + + if ((c0 = curStr->getChar()) == EOF) { + return gFalse; + } + *x = (Guint)c0; + return gTrue; +} + +GBool JBIG2Stream::readByte(int *x) { + int c0; + + if ((c0 = curStr->getChar()) == EOF) { + return gFalse; + } + *x = c0; + if (c0 & 0x80) { + *x |= -1 - 0xff; + } + return gTrue; +} + +GBool JBIG2Stream::readUWord(Guint *x) { + int c0, c1; + + if ((c0 = curStr->getChar()) == EOF || + (c1 = curStr->getChar()) == EOF) { + return gFalse; + } + *x = (Guint)((c0 << 8) | c1); + return gTrue; +} + +GBool JBIG2Stream::readULong(Guint *x) { + int c0, c1, c2, c3; + + if ((c0 = curStr->getChar()) == EOF || + (c1 = curStr->getChar()) == EOF || + (c2 = curStr->getChar()) == EOF || + (c3 = curStr->getChar()) == EOF) { + return gFalse; + } + *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3); + return gTrue; +} + +GBool JBIG2Stream::readLong(int *x) { + int c0, c1, c2, c3; + + if ((c0 = curStr->getChar()) == EOF || + (c1 = curStr->getChar()) == EOF || + (c2 = curStr->getChar()) == EOF || + (c3 = curStr->getChar()) == EOF) { + return gFalse; + } + *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3); + if (c0 & 0x80) { + *x |= -1 - (int)0xffffffff; + } + return gTrue; +} diff --git a/rosapps/smartpdf/poppler/poppler/JBIG2Stream.h b/rosapps/smartpdf/poppler/poppler/JBIG2Stream.h new file mode 100644 index 00000000000..8692e9722b9 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/JBIG2Stream.h @@ -0,0 +1,141 @@ +//======================================================================== +// +// JBIG2Stream.h +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef JBIG2STREAM_H +#define JBIG2STREAM_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "Object.h" +#include "Stream.h" + +class GooList; +class JBIG2Segment; +class JBIG2Bitmap; +class JArithmeticDecoder; +class JArithmeticDecoderStats; +class JBIG2HuffmanDecoder; +struct JBIG2HuffmanTable; +class JBIG2MMRDecoder; + +//------------------------------------------------------------------------ + +class JBIG2Stream: public FilterStream { +public: + + JBIG2Stream(Stream *strA, Object *globalsStream); + virtual ~JBIG2Stream(); + virtual StreamKind getKind() { return strJBIG2; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + void readSegments(); + GBool readSymbolDictSeg(Guint segNum, Guint length, + Guint *refSegs, Guint nRefSegs); + void readTextRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length, + Guint *refSegs, Guint nRefSegs); + JBIG2Bitmap *readTextRegion(GBool huff, GBool refine, + int w, int h, + Guint numInstances, + Guint logStrips, + int numSyms, + JBIG2HuffmanTable *symCodeTab, + Guint symCodeLen, + JBIG2Bitmap **syms, + Guint defPixel, Guint combOp, + Guint transposed, Guint refCorner, + int sOffset, + JBIG2HuffmanTable *huffFSTable, + JBIG2HuffmanTable *huffDSTable, + JBIG2HuffmanTable *huffDTTable, + JBIG2HuffmanTable *huffRDWTable, + JBIG2HuffmanTable *huffRDHTable, + JBIG2HuffmanTable *huffRDXTable, + JBIG2HuffmanTable *huffRDYTable, + JBIG2HuffmanTable *huffRSizeTable, + Guint templ, + int *atx, int *aty); + void readPatternDictSeg(Guint segNum, Guint length); + void readHalftoneRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length, + Guint *refSegs, Guint nRefSegs); + void readGenericRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length); + JBIG2Bitmap *readGenericBitmap(GBool mmr, int w, int h, + int templ, GBool tpgdOn, + GBool useSkip, JBIG2Bitmap *skip, + int *atx, int *aty, + int mmrDataLength); + void readGenericRefinementRegionSeg(Guint segNum, GBool imm, + GBool lossless, Guint length, + Guint *refSegs, + Guint nRefSegs); + JBIG2Bitmap *readGenericRefinementRegion(int w, int h, + int templ, GBool tpgrOn, + JBIG2Bitmap *refBitmap, + int refDX, int refDY, + int *atx, int *aty); + void readPageInfoSeg(Guint length); + void readEndOfStripeSeg(Guint length); + void readProfilesSeg(Guint length); + void readCodeTableSeg(Guint segNum, Guint length); + void readExtensionSeg(Guint length); + JBIG2Segment *findSegment(Guint segNum); + void discardSegment(Guint segNum); + void resetGenericStats(Guint templ, + JArithmeticDecoderStats *prevStats); + void resetRefinementStats(Guint templ, + JArithmeticDecoderStats *prevStats); + void resetIntStats(int symCodeLen); + GBool readUByte(Guint *x); + GBool readByte(int *x); + GBool readUWord(Guint *x); + GBool readULong(Guint *x); + GBool readLong(int *x); + + Guint pageW, pageH, curPageH; + Guint pageDefPixel; + JBIG2Bitmap *pageBitmap; + Guint defCombOp; + GooList *segments; // [JBIG2Segment] + GooList *globalSegments; // [JBIG2Segment] + Stream *curStr; + Guchar *dataPtr; + Guchar *dataEnd; + + JArithmeticDecoder *arithDecoder; + JArithmeticDecoderStats *genericRegionStats; + JArithmeticDecoderStats *refinementRegionStats; + JArithmeticDecoderStats *iadhStats; + JArithmeticDecoderStats *iadwStats; + JArithmeticDecoderStats *iaexStats; + JArithmeticDecoderStats *iaaiStats; + JArithmeticDecoderStats *iadtStats; + JArithmeticDecoderStats *iaitStats; + JArithmeticDecoderStats *iafsStats; + JArithmeticDecoderStats *iadsStats; + JArithmeticDecoderStats *iardxStats; + JArithmeticDecoderStats *iardyStats; + JArithmeticDecoderStats *iardwStats; + JArithmeticDecoderStats *iardhStats; + JArithmeticDecoderStats *iariStats; + JArithmeticDecoderStats *iaidStats; + JBIG2HuffmanDecoder *huffDecoder; + JBIG2MMRDecoder *mmrDecoder; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/JPXStream.cc b/rosapps/smartpdf/poppler/poppler/JPXStream.cc new file mode 100644 index 00000000000..6ede2831c3d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/JPXStream.cc @@ -0,0 +1,2967 @@ +//======================================================================== +// +// JPXStream.cc +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "goo/gmem.h" +#include "Error.h" +#include "JArithmeticDecoder.h" +#include "JPXStream.h" + +//~ to do: +// - precincts +// - ROI +// - progression order changes +// - packed packet headers +// - support for palettes, channel maps, etc. +// - make sure all needed JP2/JPX subboxes are parsed (readBoxes) +// - can we assume that QCC segments must come after the QCD segment? +// - skip EPH markers (readTilePartData) +// - handle tilePartToEOC in readTilePartData +// - deal with multiple codeword segments (readTilePartData, +// readCodeBlockData) +// - progression orders 2, 3, and 4 +// - in coefficient decoding (readCodeBlockData): +// - termination pattern: terminate after every coding pass +// - error resilience segmentation symbol +// - selective arithmetic coding bypass +// - vertically causal context formation +// - coeffs longer than 31 bits (should just ignore the extra bits?) +// - handle boxes larger than 2^32 bytes +// - the fixed-point arithmetic won't handle 16-bit pixels + +//------------------------------------------------------------------------ + +// number of contexts for the arithmetic decoder +#define jpxNContexts 19 + +#define jpxContextSigProp 0 // 0 - 8: significance prop and cleanup +#define jpxContextSign 9 // 9 - 13: sign +#define jpxContextMagRef 14 // 14 -16: magnitude refinement +#define jpxContextRunLength 17 // cleanup: run length +#define jpxContextUniform 18 // cleanup: first signif coeff + +//------------------------------------------------------------------------ + +#define jpxPassSigProp 0 +#define jpxPassMagRef 1 +#define jpxPassCleanup 2 + +//------------------------------------------------------------------------ + +// arithmetic decoder context for the significance propagation and +// cleanup passes: +// [horiz][vert][diag][subband] +// where subband = 0 for HL +// = 1 for LH and LL +// = 2 for HH +static Guint sigPropContext[3][3][5][3] = { + {{{ 0, 0, 0 }, // horiz=0, vert=0, diag=0 + { 1, 1, 3 }, // horiz=0, vert=0, diag=1 + { 2, 2, 6 }, // horiz=0, vert=0, diag=2 + { 2, 2, 8 }, // horiz=0, vert=0, diag=3 + { 2, 2, 8 }}, // horiz=0, vert=0, diag=4 + {{ 5, 3, 1 }, // horiz=0, vert=1, diag=0 + { 6, 3, 4 }, // horiz=0, vert=1, diag=1 + { 6, 3, 7 }, // horiz=0, vert=1, diag=2 + { 6, 3, 8 }, // horiz=0, vert=1, diag=3 + { 6, 3, 8 }}, // horiz=0, vert=1, diag=4 + {{ 8, 4, 2 }, // horiz=0, vert=2, diag=0 + { 8, 4, 5 }, // horiz=0, vert=2, diag=1 + { 8, 4, 7 }, // horiz=0, vert=2, diag=2 + { 8, 4, 8 }, // horiz=0, vert=2, diag=3 + { 8, 4, 8 }}}, // horiz=0, vert=2, diag=4 + {{{ 3, 5, 1 }, // horiz=1, vert=0, diag=0 + { 3, 6, 4 }, // horiz=1, vert=0, diag=1 + { 3, 6, 7 }, // horiz=1, vert=0, diag=2 + { 3, 6, 8 }, // horiz=1, vert=0, diag=3 + { 3, 6, 8 }}, // horiz=1, vert=0, diag=4 + {{ 7, 7, 2 }, // horiz=1, vert=1, diag=0 + { 7, 7, 5 }, // horiz=1, vert=1, diag=1 + { 7, 7, 7 }, // horiz=1, vert=1, diag=2 + { 7, 7, 8 }, // horiz=1, vert=1, diag=3 + { 7, 7, 8 }}, // horiz=1, vert=1, diag=4 + {{ 8, 7, 2 }, // horiz=1, vert=2, diag=0 + { 8, 7, 5 }, // horiz=1, vert=2, diag=1 + { 8, 7, 7 }, // horiz=1, vert=2, diag=2 + { 8, 7, 8 }, // horiz=1, vert=2, diag=3 + { 8, 7, 8 }}}, // horiz=1, vert=2, diag=4 + {{{ 4, 8, 2 }, // horiz=2, vert=0, diag=0 + { 4, 8, 5 }, // horiz=2, vert=0, diag=1 + { 4, 8, 7 }, // horiz=2, vert=0, diag=2 + { 4, 8, 8 }, // horiz=2, vert=0, diag=3 + { 4, 8, 8 }}, // horiz=2, vert=0, diag=4 + {{ 7, 8, 2 }, // horiz=2, vert=1, diag=0 + { 7, 8, 5 }, // horiz=2, vert=1, diag=1 + { 7, 8, 7 }, // horiz=2, vert=1, diag=2 + { 7, 8, 8 }, // horiz=2, vert=1, diag=3 + { 7, 8, 8 }}, // horiz=2, vert=1, diag=4 + {{ 8, 8, 2 }, // horiz=2, vert=2, diag=0 + { 8, 8, 5 }, // horiz=2, vert=2, diag=1 + { 8, 8, 7 }, // horiz=2, vert=2, diag=2 + { 8, 8, 8 }, // horiz=2, vert=2, diag=3 + { 8, 8, 8 }}} // horiz=2, vert=2, diag=4 +}; + +// arithmetic decoder context and xor bit for the sign bit in the +// significance propagation pass: +// [horiz][vert][k] +// where horiz/vert are offset by 2 (i.e., range is -2 .. 2) +// and k = 0 for the context +// = 1 for the xor bit +static Guint signContext[5][5][2] = { + {{ 13, 1 }, // horiz=-2, vert=-2 + { 13, 1 }, // horiz=-2, vert=-1 + { 12, 1 }, // horiz=-2, vert= 0 + { 11, 1 }, // horiz=-2, vert=+1 + { 11, 1 }}, // horiz=-2, vert=+2 + {{ 13, 1 }, // horiz=-1, vert=-2 + { 13, 1 }, // horiz=-1, vert=-1 + { 12, 1 }, // horiz=-1, vert= 0 + { 11, 1 }, // horiz=-1, vert=+1 + { 11, 1 }}, // horiz=-1, vert=+2 + {{ 10, 1 }, // horiz= 0, vert=-2 + { 10, 1 }, // horiz= 0, vert=-1 + { 9, 0 }, // horiz= 0, vert= 0 + { 10, 0 }, // horiz= 0, vert=+1 + { 10, 0 }}, // horiz= 0, vert=+2 + {{ 11, 0 }, // horiz=+1, vert=-2 + { 11, 0 }, // horiz=+1, vert=-1 + { 12, 0 }, // horiz=+1, vert= 0 + { 13, 0 }, // horiz=+1, vert=+1 + { 13, 0 }}, // horiz=+1, vert=+2 + {{ 11, 0 }, // horiz=+2, vert=-2 + { 11, 0 }, // horiz=+2, vert=-1 + { 12, 0 }, // horiz=+2, vert= 0 + { 13, 0 }, // horiz=+2, vert=+1 + { 13, 0 }}, // horiz=+2, vert=+2 +}; + +//------------------------------------------------------------------------ + +// constants used in the IDWT +#define idwtAlpha -1.586134342059924 +#define idwtBeta -0.052980118572961 +#define idwtGamma 0.882911075530934 +#define idwtDelta 0.443506852043971 +#define idwtKappa 1.230174104914001 +#define idwtIKappa (1.0 / idwtKappa) + +// number of bits to the right of the decimal point for the fixed +// point arithmetic used in the IDWT +#define fracBits 16 + +//------------------------------------------------------------------------ + +// floor(x / y) +#define jpxFloorDiv(x, y) ((x) / (y)) + +// floor(x / 2^y) +#define jpxFloorDivPow2(x, y) ((x) >> (y)) + +// ceil(x / y) +#define jpxCeilDiv(x, y) (((x) + (y) - 1) / (y)) + +// ceil(x / 2^y) +#define jpxCeilDivPow2(x, y) (((x) + (1 << (y)) - 1) >> (y)) + +//------------------------------------------------------------------------ + +JPXStream::JPXStream(Stream *strA): + FilterStream(strA) +{ + nComps = 0; + bpc = NULL; + width = height = 0; + haveCS = gFalse; + havePalette = gFalse; + haveCompMap = gFalse; + haveChannelDefn = gFalse; + + img.tiles = NULL; + bitBuf = 0; + bitBufLen = 0; + bitBufSkip = gFalse; + byteCount = 0; +} + +JPXStream::~JPXStream() { + JPXTile *tile; + JPXTileComp *tileComp; + JPXResLevel *resLevel; + JPXPrecinct *precinct; + JPXSubband *subband; + JPXCodeBlock *cb; + Guint comp, i, k, r, pre, sb, sbCount; + + gfree(bpc); + if (havePalette) { + gfree(palette.bpc); + gfree(palette.c); + } + if (haveCompMap) { + gfree(compMap.comp); + gfree(compMap.type); + gfree(compMap.pComp); + } + if (haveChannelDefn) { + gfree(channelDefn.idx); + gfree(channelDefn.type); + gfree(channelDefn.assoc); + } + + if (img.tiles) { + for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { + tile = &img.tiles[i]; + if (tile->tileComps) { + for (comp = 0; comp < img.nComps; ++comp) { + tileComp = &tile->tileComps[comp]; + gfree(tileComp->quantSteps); + gfree(tileComp->data); + gfree(tileComp->buf); + if (tileComp->resLevels) { + for (r = 0; r <= tileComp->nDecompLevels; ++r) { + resLevel = &tileComp->resLevels[r]; + if (resLevel->precincts) { + for (pre = 0; pre < 1; ++pre) { + precinct = &resLevel->precincts[pre]; + if (precinct->subbands) { + if (0 == r) + sbCount = 1; + else + sbCount = 3; + for (sb = 0; sb < sbCount; ++sb) { + subband = &precinct->subbands[sb]; + gfree(subband->inclusion); + gfree(subband->zeroBitPlane); + if (subband->cbs) { + for (k = 0; k < subband->nXCBs * subband->nYCBs; ++k) { + cb = &subband->cbs[k]; + gfree(cb->coeffs); + if (cb->arithDecoder) { + delete cb->arithDecoder; + } + if (cb->stats) { + delete cb->stats; + } + } + gfree(subband->cbs); + } + } + gfree(precinct->subbands); + } + } + gfree(img.tiles[i].tileComps[comp].resLevels[r].precincts); + } + } + gfree(img.tiles[i].tileComps[comp].resLevels); + } + } + gfree(img.tiles[i].tileComps); + } + } + gfree(img.tiles); + } + delete str; +} + +void JPXStream::reset() { + str->reset(); + if (readBoxes()) { + curY = img.yOffset; + } else { + // readBoxes reported an error, so we go immediately to EOF + curY = img.ySize; + } + curX = img.xOffset; + curComp = 0; + readBufLen = 0; +} + +int JPXStream::getChar() { + int c; + + if (readBufLen < 8) { + fillReadBuf(); + } + if (readBufLen == 8) { + c = readBuf & 0xff; + readBufLen = 0; + } else if (readBufLen > 8) { + c = (readBuf >> (readBufLen - 8)) & 0xff; + readBufLen -= 8; + } else if (readBufLen == 0) { + c = EOF; + } else { + c = (readBuf << (8 - readBufLen)) & 0xff; + readBufLen = 0; + } + return c; +} + +int JPXStream::lookChar() { + int c; + + if (readBufLen < 8) { + fillReadBuf(); + } + if (readBufLen == 8) { + c = readBuf & 0xff; + } else if (readBufLen > 8) { + c = (readBuf >> (readBufLen - 8)) & 0xff; + } else if (readBufLen == 0) { + c = EOF; + } else { + c = (readBuf << (8 - readBufLen)) & 0xff; + } + return c; +} + +void JPXStream::fillReadBuf() { + JPXTileComp *tileComp; + Guint tileIdx, tx, ty; + int pix, pixBits; + + do { + if (curY >= img.ySize) { + return; + } + tileIdx = ((curY - img.yTileOffset) / img.yTileSize) * img.nXTiles + + (curX - img.xTileOffset) / img.xTileSize; +#if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid + tileComp = &img.tiles[tileIdx].tileComps[curComp]; +#else + tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp]; +#endif + tx = jpxCeilDiv((curX - img.xTileOffset) % img.xTileSize, tileComp->hSep); + ty = jpxCeilDiv((curY - img.yTileOffset) % img.yTileSize, tileComp->vSep); + pix = (int)tileComp->data[ty * (tileComp->x1 - tileComp->x0) + tx]; + pixBits = tileComp->prec; +#if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid + if (++curComp == img.nComps) { +#else + if (havePalette) { + if (pix >= 0 && pix < palette.nEntries) { + pix = palette.c[pix * palette.nComps + curComp]; + } else { + pix = + pixBits = palette.bpc[curComp]; + } + if (++curComp == (Guint)(havePalette ? palette.nComps : img.nComps)) { +#endif + curComp = 0; + if (++curX == img.xSize) { + curX = img.xOffset; + ++curY; + } + } + if (pixBits == 8) { + readBuf = (readBuf << 8) | (pix & 0xff); + } else { + readBuf = (readBuf << pixBits) | (pix & ((1 << pixBits) - 1)); + } + readBufLen += pixBits; + } while (readBufLen < 8); +} + +GooString *JPXStream::getPSFilter(int psLevel, char *indent) { + return NULL; +} + +GBool JPXStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +void JPXStream::getImageParams(int *bitsPerComponent, + StreamColorSpaceMode *csMode) { + Guint boxType, boxLen, dataLen, csEnum; + Guint bpc1, dummy, i; + int csMeth, csPrec, csPrec1, dummy2; + StreamColorSpaceMode csMode1; + GBool haveBPC, haveCSMode; + + csPrec = 0; // make gcc happy + haveBPC = haveCSMode = gFalse; + str->reset(); + if (str->lookChar() == 0xff) { + getImageParams2(bitsPerComponent, csMode); + } else { + while (readBoxHdr(&boxType, &boxLen, &dataLen)) { + if (boxType == 0x6a703268) { // JP2 header + // skip the superbox + } else if (boxType == 0x69686472) { // image header + if (readULong(&dummy) && + readULong(&dummy) && + readUWord(&dummy) && + readUByte(&bpc1) && + readUByte(&dummy) && + readUByte(&dummy) && + readUByte(&dummy)) { + *bitsPerComponent = bpc1 + 1; + haveBPC = gTrue; + } + } else if (boxType == 0x636F6C72) { // color specification + if (readByte(&csMeth) && + readByte(&csPrec1) && + readByte(&dummy2)) { + if (csMeth == 1) { + if (readULong(&csEnum)) { + csMode1 = streamCSNone; + if (csEnum == jpxCSBiLevel || + csEnum == jpxCSGrayscale) { + csMode1 = streamCSDeviceGray; + } else if (csEnum == jpxCSCMYK) { + csMode1 = streamCSDeviceCMYK; + } else if (csEnum == jpxCSsRGB || + csEnum == jpxCSCISesRGB || + csEnum == jpxCSROMMRGB) { + csMode1 = streamCSDeviceRGB; + } + if (csMode1 != streamCSNone && + (!haveCSMode || csPrec1 > csPrec)) { + *csMode = csMode1; + csPrec = csPrec1; + haveCSMode = gTrue; + } + for (i = 0; i < dataLen - 7; ++i) { + str->getChar(); + } + } + } else { + for (i = 0; i < dataLen - 3; ++i) { + str->getChar(); + } + } + } + } else if (boxType == 0x6A703263) { // codestream + if (!(haveBPC && haveCSMode)) { + getImageParams2(bitsPerComponent, csMode); + } + break; + } else { + for (i = 0; i < dataLen; ++i) { + str->getChar(); + } + } + } + } + str->close(); +} + +// Get image parameters from the codestream. +void JPXStream::getImageParams2(int *bitsPerComponent, + StreamColorSpaceMode *csMode) { + int segType; + Guint segLen, nComps1, bpc1, dummy, i; + + while (readMarkerHdr(&segType, &segLen)) { + if (segType == 0x51) { // SIZ - image and tile size + if (readUWord(&dummy) && + readULong(&dummy) && + readULong(&dummy) && + readULong(&dummy) && + readULong(&dummy) && + readULong(&dummy) && + readULong(&dummy) && + readULong(&dummy) && + readULong(&dummy) && + readUWord(&nComps1) && + readUByte(&bpc1)) { + *bitsPerComponent = (bpc1 & 0x7f) + 1; + // if there's no color space info, take a guess + if (nComps1 == 1) { + *csMode = streamCSDeviceGray; + } else if (nComps1 == 3) { + *csMode = streamCSDeviceRGB; + } else if (nComps1 == 4) { + *csMode = streamCSDeviceCMYK; + } + } + break; + } else { + if (segLen > 2) { + for (i = 0; i < segLen - 2; ++i) { + str->getChar(); + } + } + } + } +} + +GBool JPXStream::readBoxes() { + Guint boxType, boxLen, dataLen; + Guint bpc1, compression, unknownColorspace, ipr; + Guint i, j; + + haveImgHdr = gFalse; + + // check for a naked JPEG 2000 codestream (without the JP2/JPX + // wrapper) -- this appears to be a violation of the PDF spec, but + // Acrobat allows it + if (str->lookChar() == 0xff) { + error(getPos(), "Naked JPEG 2000 codestream, missing JP2/JPX wrapper"); + readCodestream(0); + nComps = img.nComps; + bpc = (Guint *)gmallocn(nComps, sizeof(Guint)); + for (i = 0; i < nComps; ++i) { + bpc[i] = img.tiles[0].tileComps[i].prec; + } + width = img.xSize - img.xOffset; + height = img.ySize - img.yOffset; + return gTrue; + } + + while (readBoxHdr(&boxType, &boxLen, &dataLen)) { + switch (boxType) { + case 0x6a703268: // JP2 header + // this is a grouping box ('superbox') which has no real + // contents and doesn't appear to be used consistently, i.e., + // some things which should be subboxes of the JP2 header box + // show up outside of it - so we simply ignore the JP2 header + // box + break; + case 0x69686472: // image header + if (!readULong(&height) || + !readULong(&width) || + !readUWord(&nComps) || + !readUByte(&bpc1) || + !readUByte(&compression) || + !readUByte(&unknownColorspace) || + !readUByte(&ipr)) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + if (compression != 7) { + error(getPos(), "Unknown compression type in JPX stream"); + return gFalse; + } + bpc = (Guint *)gmallocn(nComps, sizeof(Guint)); + for (i = 0; i < nComps; ++i) { + bpc[i] = bpc1; + } + haveImgHdr = gTrue; + break; + case 0x62706363: // bits per component + if (!haveImgHdr) { + error(getPos(), "Found bits per component box before image header box in JPX stream"); + return gFalse; + } + if (dataLen != nComps) { + error(getPos(), "Invalid bits per component box in JPX stream"); + return gFalse; + } + for (i = 0; i < nComps; ++i) { + if (!readUByte(&bpc[i])) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + } + break; + case 0x636F6C72: // color specification + if (!readColorSpecBox(dataLen)) { + return gFalse; + } + break; + case 0x70636c72: // palette + if (!readUWord(&palette.nEntries) || + !readUByte(&palette.nComps)) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + palette.bpc = (Guint *)gmallocn(palette.nComps, sizeof(Guint)); + palette.c = + (int *)gmallocn(palette.nEntries * palette.nComps, sizeof(int)); + for (i = 0; i < palette.nComps; ++i) { + if (!readUByte(&palette.bpc[i])) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + ++palette.bpc[i]; + } + for (i = 0; i < palette.nEntries; ++i) { + for (j = 0; j < palette.nComps; ++j) { + if (!readNBytes(((palette.bpc[j] & 0x7f) + 7) >> 3, + (palette.bpc[j] & 0x80) ? gTrue : gFalse, + &palette.c[i * palette.nComps + j])) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + } + } + havePalette = gTrue; + break; + case 0x636d6170: // component mapping + compMap.nChannels = dataLen / 4; + compMap.comp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint)); + compMap.type = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint)); + compMap.pComp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint)); + for (i = 0; i < compMap.nChannels; ++i) { + if (!readUWord(&compMap.comp[i]) || + !readUByte(&compMap.type[i]) || + !readUByte(&compMap.pComp[i])) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + } + haveCompMap = gTrue; + break; + case 0x63646566: // channel definition + if (!readUWord(&channelDefn.nChannels)) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + channelDefn.idx = + (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint)); + channelDefn.type = + (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint)); + channelDefn.assoc = + (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint)); + for (i = 0; i < channelDefn.nChannels; ++i) { + if (!readUWord(&channelDefn.idx[i]) || + !readUWord(&channelDefn.type[i]) || + !readUWord(&channelDefn.assoc[i])) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + } + haveChannelDefn = gTrue; + break; + case 0x6A703263: // contiguous codestream + if (!bpc) { + error(getPos(), "JPX stream is missing the image header box"); + } + if (!haveCS) { + error(getPos(), "JPX stream has no supported color spec"); + } + if (!readCodestream(dataLen)) { + return gFalse; + } + break; + default: + for (i = 0; i < dataLen; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Unexpected EOF in JPX stream"); + return gFalse; + } + } + break; + } + } + return gTrue; +} + +GBool JPXStream::readColorSpecBox(Guint dataLen) { + JPXColorSpec newCS; + Guint csApprox, csEnum; + Guint i; + GBool ok; + + ok = gFalse; + if (!readUByte(&newCS.meth) || + !readByte(&newCS.prec) || + !readUByte(&csApprox)) { + goto err; + } + switch (newCS.meth) { + case 1: // enumerated colorspace + if (!readULong(&csEnum)) { + goto err; + } + newCS.enumerated.type = (JPXColorSpaceType)csEnum; + switch (newCS.enumerated.type) { + case jpxCSBiLevel: + ok = gTrue; + break; + case jpxCSYCbCr1: + ok = gTrue; + break; + case jpxCSYCbCr2: + ok = gTrue; + break; + case jpxCSYCBCr3: + ok = gTrue; + break; + case jpxCSPhotoYCC: + ok = gTrue; + break; + case jpxCSCMY: + ok = gTrue; + break; + case jpxCSCMYK: + ok = gTrue; + break; + case jpxCSYCCK: + ok = gTrue; + break; + case jpxCSCIELab: + if (dataLen == 7 + 7*4) { + if (!readULong(&newCS.enumerated.cieLab.rl) || + !readULong(&newCS.enumerated.cieLab.ol) || + !readULong(&newCS.enumerated.cieLab.ra) || + !readULong(&newCS.enumerated.cieLab.oa) || + !readULong(&newCS.enumerated.cieLab.rb) || + !readULong(&newCS.enumerated.cieLab.ob) || + !readULong(&newCS.enumerated.cieLab.il)) { + goto err; + } + } else if (dataLen == 7) { + //~ this assumes the 8-bit case + newCS.enumerated.cieLab.rl = 100; + newCS.enumerated.cieLab.ol = 0; + newCS.enumerated.cieLab.ra = 255; + newCS.enumerated.cieLab.oa = 128; + newCS.enumerated.cieLab.rb = 255; + newCS.enumerated.cieLab.ob = 96; + newCS.enumerated.cieLab.il = 0x00443530; + } else { + goto err; + } + ok = gTrue; + break; + case jpxCSsRGB: + ok = gTrue; + break; + case jpxCSGrayscale: + ok = gTrue; + break; + case jpxCSBiLevel2: + ok = gTrue; + break; + case jpxCSCIEJab: + // not allowed in PDF + goto err; + case jpxCSCISesRGB: + ok = gTrue; + break; + case jpxCSROMMRGB: + ok = gTrue; + break; + case jpxCSsRGBYCbCr: + ok = gTrue; + break; + case jpxCSYPbPr1125: + ok = gTrue; + break; + case jpxCSYPbPr1250: + ok = gTrue; + break; + default: + goto err; + } + break; + case 2: // restricted ICC profile + case 3: // any ICC profile (JPX) + case 4: // vendor color (JPX) + for (i = 0; i < dataLen - 3; ++i) { + if (str->getChar() == EOF) { + goto err; + } + } + break; + } + + if (ok && (!haveCS || newCS.prec > cs.prec)) { + cs = newCS; + haveCS = gTrue; + } + + return gTrue; + + err: + error(getPos(), "Error in JPX color spec"); + return gFalse; +} + +GBool JPXStream::readCodestream(Guint len) { + JPXTile *tile; + JPXTileComp *tileComp; + int segType; + GBool haveSIZ, haveCOD, haveQCD, haveSOT; + Guint precinctSize, style; + Guint segLen, capabilities, nTiles, comp, i, j, r; + + //----- main header + haveSIZ = haveCOD = haveQCD = haveSOT = gFalse; + do { + if (!readMarkerHdr(&segType, &segLen)) { + error(getPos(), "Error in JPX codestream"); + return gFalse; + } + switch (segType) { + case 0x4f: // SOC - start of codestream + // marker only + break; + case 0x51: // SIZ - image and tile size + if (!readUWord(&capabilities) || + !readULong(&img.xSize) || + !readULong(&img.ySize) || + !readULong(&img.xOffset) || + !readULong(&img.yOffset) || + !readULong(&img.xTileSize) || + !readULong(&img.yTileSize) || + !readULong(&img.xTileOffset) || + !readULong(&img.yTileOffset) || + !readUWord(&img.nComps)) { + error(getPos(), "Error in JPX SIZ marker segment"); + return gFalse; + } + if (haveImgHdr && img.nComps != nComps) { + error(getPos(), "Different number of components in JPX SIZ marker segment"); + return gFalse; + } + img.nXTiles = (img.xSize - img.xTileOffset + img.xTileSize - 1) + / img.xTileSize; + img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1) + / img.yTileSize; + nTiles = img.nXTiles * img.nYTiles; + // check for overflow before allocating memory + if (nTiles == 0 || nTiles / img.nXTiles != img.nYTiles) { + error(getPos(), "Bad tile count in JPX SIZ marker segment"); + return gFalse; + } + img.tiles = (JPXTile *)gmallocn(nTiles, sizeof(JPXTile)); + for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { + img.tiles[i].tileComps = (JPXTileComp *)gmallocn(img.nComps, + sizeof(JPXTileComp)); + for (comp = 0; comp < img.nComps; ++comp) { + img.tiles[i].tileComps[comp].quantSteps = NULL; + img.tiles[i].tileComps[comp].data = NULL; + img.tiles[i].tileComps[comp].buf = NULL; + img.tiles[i].tileComps[comp].resLevels = NULL; + } + } + for (comp = 0; comp < img.nComps; ++comp) { + if (!readUByte(&img.tiles[0].tileComps[comp].prec) || + !readUByte(&img.tiles[0].tileComps[comp].hSep) || + !readUByte(&img.tiles[0].tileComps[comp].vSep)) { + error(getPos(), "Error in JPX SIZ marker segment"); + return gFalse; + } + img.tiles[0].tileComps[comp].sgned = + (img.tiles[0].tileComps[comp].prec & 0x80) ? gTrue : gFalse; + img.tiles[0].tileComps[comp].prec = + (img.tiles[0].tileComps[comp].prec & 0x7f) + 1; + for (i = 1; i < img.nXTiles * img.nYTiles; ++i) { + img.tiles[i].tileComps[comp] = img.tiles[0].tileComps[comp]; + } + } + haveSIZ = gTrue; + break; + case 0x52: // COD - coding style default + if (!readUByte(&img.tiles[0].tileComps[0].style) || + !readUByte(&img.tiles[0].progOrder) || + !readUWord(&img.tiles[0].nLayers) || + !readUByte(&img.tiles[0].multiComp) || + !readUByte(&img.tiles[0].tileComps[0].nDecompLevels) || + !readUByte(&img.tiles[0].tileComps[0].codeBlockW) || + !readUByte(&img.tiles[0].tileComps[0].codeBlockH) || + !readUByte(&img.tiles[0].tileComps[0].codeBlockStyle) || + !readUByte(&img.tiles[0].tileComps[0].transform)) { + error(getPos(), "Error in JPX COD marker segment"); + return gFalse; + } + img.tiles[0].tileComps[0].codeBlockW += 2; + img.tiles[0].tileComps[0].codeBlockH += 2; + for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { + if (i != 0) { + img.tiles[i].progOrder = img.tiles[0].progOrder; + img.tiles[i].nLayers = img.tiles[0].nLayers; + img.tiles[i].multiComp = img.tiles[0].multiComp; + } + for (comp = 0; comp < img.nComps; ++comp) { + if (!(i == 0 && comp == 0)) { + img.tiles[i].tileComps[comp].style = + img.tiles[0].tileComps[0].style; + img.tiles[i].tileComps[comp].nDecompLevels = + img.tiles[0].tileComps[0].nDecompLevels; + img.tiles[i].tileComps[comp].codeBlockW = + img.tiles[0].tileComps[0].codeBlockW; + img.tiles[i].tileComps[comp].codeBlockH = + img.tiles[0].tileComps[0].codeBlockH; + img.tiles[i].tileComps[comp].codeBlockStyle = + img.tiles[0].tileComps[0].codeBlockStyle; + img.tiles[i].tileComps[comp].transform = + img.tiles[0].tileComps[0].transform; + } + img.tiles[i].tileComps[comp].resLevels = + (JPXResLevel *)gmallocn( + (img.tiles[i].tileComps[comp].nDecompLevels + 1), + sizeof(JPXResLevel)); + for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) { + img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL; + } + } + } + for (r = 0; r <= img.tiles[0].tileComps[0].nDecompLevels; ++r) { + if (img.tiles[0].tileComps[0].style & 0x01) { + if (!readUByte(&precinctSize)) { + error(getPos(), "Error in JPX COD marker segment"); + return gFalse; + } + img.tiles[0].tileComps[0].resLevels[r].precinctWidth = + precinctSize & 0x0f; + img.tiles[0].tileComps[0].resLevels[r].precinctHeight = + (precinctSize >> 4) & 0x0f; + } else { + img.tiles[0].tileComps[0].resLevels[r].precinctWidth = 15; + img.tiles[0].tileComps[0].resLevels[r].precinctHeight = 15; + } + } + for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { + for (comp = 0; comp < img.nComps; ++comp) { + if (!(i == 0 && comp == 0)) { + for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) { + img.tiles[i].tileComps[comp].resLevels[r].precinctWidth = + img.tiles[0].tileComps[0].resLevels[r].precinctWidth; + img.tiles[i].tileComps[comp].resLevels[r].precinctHeight = + img.tiles[0].tileComps[0].resLevels[r].precinctHeight; + } + } + } + } + haveCOD = gTrue; + break; + case 0x53: // COC - coding style component + if (!haveCOD) { + error(getPos(), "JPX COC marker segment before COD segment"); + return gFalse; + } + if ((img.nComps > 256 && !readUWord(&comp)) || + (img.nComps <= 256 && !readUByte(&comp)) || + comp >= img.nComps || + !readUByte(&style) || + !readUByte(&img.tiles[0].tileComps[comp].nDecompLevels) || + !readUByte(&img.tiles[0].tileComps[comp].codeBlockW) || + !readUByte(&img.tiles[0].tileComps[comp].codeBlockH) || + !readUByte(&img.tiles[0].tileComps[comp].codeBlockStyle) || + !readUByte(&img.tiles[0].tileComps[comp].transform)) { + error(getPos(), "Error in JPX COC marker segment"); + return gFalse; + } + img.tiles[0].tileComps[comp].style = + (img.tiles[0].tileComps[comp].style & ~1) | (style & 1); + img.tiles[0].tileComps[comp].codeBlockW += 2; + img.tiles[0].tileComps[comp].codeBlockH += 2; + for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { + if (i != 0) { + img.tiles[i].tileComps[comp].style = + img.tiles[0].tileComps[comp].style; + img.tiles[i].tileComps[comp].nDecompLevels = + img.tiles[0].tileComps[comp].nDecompLevels; + img.tiles[i].tileComps[comp].codeBlockW = + img.tiles[0].tileComps[comp].codeBlockW; + img.tiles[i].tileComps[comp].codeBlockH = + img.tiles[0].tileComps[comp].codeBlockH; + img.tiles[i].tileComps[comp].codeBlockStyle = + img.tiles[0].tileComps[comp].codeBlockStyle; + img.tiles[i].tileComps[comp].transform = + img.tiles[0].tileComps[comp].transform; + } + img.tiles[i].tileComps[comp].resLevels = + (JPXResLevel *)greallocn( + img.tiles[i].tileComps[comp].resLevels, + (img.tiles[i].tileComps[comp].nDecompLevels + 1), + sizeof(JPXResLevel)); + for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) { + img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL; + } + } + for (r = 0; r <= img.tiles[0].tileComps[comp].nDecompLevels; ++r) { + if (img.tiles[0].tileComps[comp].style & 0x01) { + if (!readUByte(&precinctSize)) { + error(getPos(), "Error in JPX COD marker segment"); + return gFalse; + } + img.tiles[0].tileComps[comp].resLevels[r].precinctWidth = + precinctSize & 0x0f; + img.tiles[0].tileComps[comp].resLevels[r].precinctHeight = + (precinctSize >> 4) & 0x0f; + } else { + img.tiles[0].tileComps[comp].resLevels[r].precinctWidth = 15; + img.tiles[0].tileComps[comp].resLevels[r].precinctHeight = 15; + } + } + for (i = 1; i < img.nXTiles * img.nYTiles; ++i) { + for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) { + img.tiles[i].tileComps[comp].resLevels[r].precinctWidth = + img.tiles[0].tileComps[comp].resLevels[r].precinctWidth; + img.tiles[i].tileComps[comp].resLevels[r].precinctHeight = + img.tiles[0].tileComps[comp].resLevels[r].precinctHeight; + } + } + break; + case 0x5c: // QCD - quantization default + if (!readUByte(&img.tiles[0].tileComps[0].quantStyle)) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x00) { + img.tiles[0].tileComps[0].nQuantSteps = segLen - 3; + img.tiles[0].tileComps[0].quantSteps = + (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps, + img.tiles[0].tileComps[0].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) { + if (!readUByte(&img.tiles[0].tileComps[0].quantSteps[i])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } + } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x01) { + img.tiles[0].tileComps[0].nQuantSteps = 1; + img.tiles[0].tileComps[0].quantSteps = + (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps, + img.tiles[0].tileComps[0].nQuantSteps, + sizeof(Guint)); + if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[0])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x02) { + img.tiles[0].tileComps[0].nQuantSteps = (segLen - 3) / 2; + img.tiles[0].tileComps[0].quantSteps = + (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps, + img.tiles[0].tileComps[0].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) { + if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[i])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } + } else { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { + for (comp = 0; comp < img.nComps; ++comp) { + if (!(i == 0 && comp == 0)) { + img.tiles[i].tileComps[comp].quantStyle = + img.tiles[0].tileComps[0].quantStyle; + img.tiles[i].tileComps[comp].nQuantSteps = + img.tiles[0].tileComps[0].nQuantSteps; + img.tiles[i].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[i].tileComps[comp].quantSteps, + img.tiles[0].tileComps[0].nQuantSteps, + sizeof(Guint)); + for (j = 0; j < img.tiles[0].tileComps[0].nQuantSteps; ++j) { + img.tiles[i].tileComps[comp].quantSteps[j] = + img.tiles[0].tileComps[0].quantSteps[j]; + } + } + } + } + haveQCD = gTrue; + break; + case 0x5d: // QCC - quantization component + if (!haveQCD) { + error(getPos(), "JPX QCC marker segment before QCD segment"); + return gFalse; + } + if ((img.nComps > 256 && !readUWord(&comp)) || + (img.nComps <= 256 && !readUByte(&comp)) || + comp >= img.nComps || + !readUByte(&img.tiles[0].tileComps[comp].quantStyle)) { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x00) { + img.tiles[0].tileComps[comp].nQuantSteps = + segLen - (img.nComps > 256 ? 5 : 4); + img.tiles[0].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps, + img.tiles[0].tileComps[comp].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) { + if (!readUByte(&img.tiles[0].tileComps[comp].quantSteps[i])) { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + } + } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x01) { + img.tiles[0].tileComps[comp].nQuantSteps = 1; + img.tiles[0].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps, + img.tiles[0].tileComps[comp].nQuantSteps, + sizeof(Guint)); + if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[0])) { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x02) { + img.tiles[0].tileComps[comp].nQuantSteps = + (segLen - (img.nComps > 256 ? 5 : 4)) / 2; + img.tiles[0].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps, + img.tiles[0].tileComps[comp].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) { + if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[i])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } + } else { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + for (i = 1; i < img.nXTiles * img.nYTiles; ++i) { + img.tiles[i].tileComps[comp].quantStyle = + img.tiles[0].tileComps[comp].quantStyle; + img.tiles[i].tileComps[comp].nQuantSteps = + img.tiles[0].tileComps[comp].nQuantSteps; + img.tiles[i].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[i].tileComps[comp].quantSteps, + img.tiles[0].tileComps[comp].nQuantSteps, + sizeof(Guint)); + for (j = 0; j < img.tiles[0].tileComps[comp].nQuantSteps; ++j) { + img.tiles[i].tileComps[comp].quantSteps[j] = + img.tiles[0].tileComps[comp].quantSteps[j]; + } + } + break; + case 0x5e: // RGN - region of interest +#if 1 //~ ROI is unimplemented + fprintf(stderr, "RGN\n"); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PPM marker segment"); + return gFalse; + } + } +#else + if ((img.nComps > 256 && !readUWord(&comp)) || + (img.nComps <= 256 && !readUByte(&comp)) || + comp >= img.nComps || + !readUByte(&compInfo[comp].defROI.style) || + !readUByte(&compInfo[comp].defROI.shift)) { + error(getPos(), "Error in JPX RGN marker segment"); + return gFalse; + } +#endif + break; + case 0x5f: // POC - progression order change +#if 1 //~ progression order changes are unimplemented + fprintf(stderr, "POC\n"); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PPM marker segment"); + return gFalse; + } + } +#else + nProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7); + progs = (JPXProgOrder *)gmallocn(nProgs, sizeof(JPXProgOrder)); + for (i = 0; i < nProgs; ++i) { + if (!readUByte(&progs[i].startRes) || + !(img.nComps > 256 && readUWord(&progs[i].startComp)) || + !(img.nComps <= 256 && readUByte(&progs[i].startComp)) || + !readUWord(&progs[i].endLayer) || + !readUByte(&progs[i].endRes) || + !(img.nComps > 256 && readUWord(&progs[i].endComp)) || + !(img.nComps <= 256 && readUByte(&progs[i].endComp)) || + !readUByte(&progs[i].progOrder)) { + error(getPos(), "Error in JPX POC marker segment"); + return gFalse; + } + } +#endif + break; + case 0x60: // PPM - packed packet headers, main header +#if 1 //~ packed packet headers are unimplemented + fprintf(stderr, "PPM\n"); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PPM marker segment"); + return gFalse; + } + } +#endif + break; + case 0x55: // TLM - tile-part lengths + // skipped + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX TLM marker segment"); + return gFalse; + } + } + break; + case 0x57: // PLM - packet length, main header + // skipped + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PLM marker segment"); + return gFalse; + } + } + break; + case 0x63: // CRG - component registration + // skipped + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX CRG marker segment"); + return gFalse; + } + } + break; + case 0x64: // COM - comment + // skipped + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX COM marker segment"); + return gFalse; + } + } + break; + case 0x90: // SOT - start of tile + haveSOT = gTrue; + break; + default: + error(getPos(), "Unknown marker segment %02x in JPX stream", segType); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + break; + } + } + break; + } + } while (!haveSOT); + + if (!haveSIZ) { + error(getPos(), "Missing SIZ marker segment in JPX stream"); + return gFalse; + } + if (!haveCOD) { + error(getPos(), "Missing COD marker segment in JPX stream"); + return gFalse; + } + if (!haveQCD) { + error(getPos(), "Missing QCD marker segment in JPX stream"); + return gFalse; + } + + //----- read the tile-parts + while (1) { + if (!readTilePart()) { + return gFalse; + } + if (!readMarkerHdr(&segType, &segLen)) { + error(getPos(), "Error in JPX codestream"); + return gFalse; + } + if (segType != 0x90) { // SOT - start of tile + break; + } + } + + if (segType != 0xd9) { // EOC - end of codestream + error(getPos(), "Missing EOC marker in JPX codestream"); + return gFalse; + } + + //----- finish decoding the image + for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { + tile = &img.tiles[i]; + for (comp = 0; comp < img.nComps; ++comp) { + tileComp = &tile->tileComps[comp]; + inverseTransform(tileComp); + } + if (!inverseMultiCompAndDC(tile)) { + return gFalse; + } + } + + //~ can free memory below tileComps here, and also tileComp.buf + + return gTrue; +} + +GBool JPXStream::readTilePart() { + JPXTile *tile; + JPXTileComp *tileComp; + JPXResLevel *resLevel; + JPXPrecinct *precinct; + JPXSubband *subband; + JPXCodeBlock *cb; + GBool haveSOD; + Guint tileIdx, tilePartLen, tilePartIdx, nTileParts; + GBool tilePartToEOC; + Guint precinctSize, style; + Guint n, nSBs, nx, ny, sbx0, sby0, comp, segLen; + Guint i, j, k, cbX, cbY, r, pre, sb, cbi; + int segType, level; + + // process the SOT marker segment + if (!readUWord(&tileIdx) || + !readULong(&tilePartLen) || + !readUByte(&tilePartIdx) || + !readUByte(&nTileParts)) { + error(getPos(), "Error in JPX SOT marker segment"); + return gFalse; + } + + if (tileIdx >= img.nXTiles * img.nYTiles) { + error(getPos(), "Weird tile index in JPX stream"); + return gFalse; + } + + tilePartToEOC = tilePartLen == 0; + tilePartLen -= 12; // subtract size of SOT segment + + haveSOD = gFalse; + do { + if (!readMarkerHdr(&segType, &segLen)) { + error(getPos(), "Error in JPX tile-part codestream"); + return gFalse; + } + tilePartLen -= 2 + segLen; + switch (segType) { + case 0x52: // COD - coding style default + if (!readUByte(&img.tiles[tileIdx].tileComps[0].style) || + !readUByte(&img.tiles[tileIdx].progOrder) || + !readUWord(&img.tiles[tileIdx].nLayers) || + !readUByte(&img.tiles[tileIdx].multiComp) || + !readUByte(&img.tiles[tileIdx].tileComps[0].nDecompLevels) || + !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockW) || + !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockH) || + !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockStyle) || + !readUByte(&img.tiles[tileIdx].tileComps[0].transform)) { + error(getPos(), "Error in JPX COD marker segment"); + return gFalse; + } + img.tiles[tileIdx].tileComps[0].codeBlockW += 2; + img.tiles[tileIdx].tileComps[0].codeBlockH += 2; + for (comp = 0; comp < img.nComps; ++comp) { + if (comp != 0) { + img.tiles[tileIdx].tileComps[comp].style = + img.tiles[tileIdx].tileComps[0].style; + img.tiles[tileIdx].tileComps[comp].nDecompLevels = + img.tiles[tileIdx].tileComps[0].nDecompLevels; + img.tiles[tileIdx].tileComps[comp].codeBlockW = + img.tiles[tileIdx].tileComps[0].codeBlockW; + img.tiles[tileIdx].tileComps[comp].codeBlockH = + img.tiles[tileIdx].tileComps[0].codeBlockH; + img.tiles[tileIdx].tileComps[comp].codeBlockStyle = + img.tiles[tileIdx].tileComps[0].codeBlockStyle; + img.tiles[tileIdx].tileComps[comp].transform = + img.tiles[tileIdx].tileComps[0].transform; + } + img.tiles[tileIdx].tileComps[comp].resLevels = + (JPXResLevel *)greallocn( + img.tiles[tileIdx].tileComps[comp].resLevels, + (img.tiles[tileIdx].tileComps[comp].nDecompLevels + 1), + sizeof(JPXResLevel)); + for (r = 0; + r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; + ++r) { + img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL; + } + } + for (r = 0; r <= img.tiles[tileIdx].tileComps[0].nDecompLevels; ++r) { + if (img.tiles[tileIdx].tileComps[0].style & 0x01) { + if (!readUByte(&precinctSize)) { + error(getPos(), "Error in JPX COD marker segment"); + return gFalse; + } + img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth = + precinctSize & 0x0f; + img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight = + (precinctSize >> 4) & 0x0f; + } else { + img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth = 15; + img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight = 15; + } + } + for (comp = 1; comp < img.nComps; ++comp) { + for (r = 0; + r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; + ++r) { + img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth = + img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth; + img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight = + img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight; + } + } + break; + case 0x53: // COC - coding style component + if ((img.nComps > 256 && !readUWord(&comp)) || + (img.nComps <= 256 && !readUByte(&comp)) || + comp >= img.nComps || + !readUByte(&style) || + !readUByte(&img.tiles[tileIdx].tileComps[comp].nDecompLevels) || + !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockW) || + !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockH) || + !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockStyle) || + !readUByte(&img.tiles[tileIdx].tileComps[comp].transform)) { + error(getPos(), "Error in JPX COC marker segment"); + return gFalse; + } + img.tiles[tileIdx].tileComps[comp].style = + (img.tiles[tileIdx].tileComps[comp].style & ~1) | (style & 1); + img.tiles[tileIdx].tileComps[comp].codeBlockW += 2; + img.tiles[tileIdx].tileComps[comp].codeBlockH += 2; + img.tiles[tileIdx].tileComps[comp].resLevels = + (JPXResLevel *)greallocn( + img.tiles[tileIdx].tileComps[comp].resLevels, + (img.tiles[tileIdx].tileComps[comp].nDecompLevels + 1), + sizeof(JPXResLevel)); + for (r = 0; r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; ++r) { + img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL; + } + for (r = 0; r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; ++r) { + if (img.tiles[tileIdx].tileComps[comp].style & 0x01) { + if (!readUByte(&precinctSize)) { + error(getPos(), "Error in JPX COD marker segment"); + return gFalse; + } + img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth = + precinctSize & 0x0f; + img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight = + (precinctSize >> 4) & 0x0f; + } else { + img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth = 15; + img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight = 15; + } + } + break; + case 0x5c: // QCD - quantization default + if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantStyle)) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x00) { + img.tiles[tileIdx].tileComps[0].nQuantSteps = + segLen - 3; + img.tiles[tileIdx].tileComps[0].quantSteps = + (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps, + img.tiles[tileIdx].tileComps[0].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) { + if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } + } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x01) { + img.tiles[tileIdx].tileComps[0].nQuantSteps = 1; + img.tiles[tileIdx].tileComps[0].quantSteps = + (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps, + img.tiles[tileIdx].tileComps[0].nQuantSteps, + sizeof(Guint)); + if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[0])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x02) { + img.tiles[tileIdx].tileComps[0].nQuantSteps = (segLen - 3) / 2; + img.tiles[tileIdx].tileComps[0].quantSteps = + (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps, + img.tiles[tileIdx].tileComps[0].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) { + if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } + } else { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + for (comp = 1; comp < img.nComps; ++comp) { + img.tiles[tileIdx].tileComps[comp].quantStyle = + img.tiles[tileIdx].tileComps[0].quantStyle; + img.tiles[tileIdx].tileComps[comp].nQuantSteps = + img.tiles[tileIdx].tileComps[0].nQuantSteps; + img.tiles[tileIdx].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps, + img.tiles[tileIdx].tileComps[0].nQuantSteps, + sizeof(Guint)); + for (j = 0; j < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++j) { + img.tiles[tileIdx].tileComps[comp].quantSteps[j] = + img.tiles[tileIdx].tileComps[0].quantSteps[j]; + } + } + break; + case 0x5d: // QCC - quantization component + if ((img.nComps > 256 && !readUWord(&comp)) || + (img.nComps <= 256 && !readUByte(&comp)) || + comp >= img.nComps || + !readUByte(&img.tiles[tileIdx].tileComps[comp].quantStyle)) { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f) == 0x00) { + img.tiles[tileIdx].tileComps[comp].nQuantSteps = + segLen - (img.nComps > 256 ? 5 : 4); + img.tiles[tileIdx].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps, + img.tiles[tileIdx].tileComps[comp].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) { + if (!readUByte(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + } + } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f) + == 0x01) { + img.tiles[tileIdx].tileComps[comp].nQuantSteps = 1; + img.tiles[tileIdx].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps, + img.tiles[tileIdx].tileComps[comp].nQuantSteps, + sizeof(Guint)); + if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[0])) { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f) + == 0x02) { + img.tiles[tileIdx].tileComps[comp].nQuantSteps = + (segLen - (img.nComps > 256 ? 5 : 4)) / 2; + img.tiles[tileIdx].tileComps[comp].quantSteps = + (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps, + img.tiles[tileIdx].tileComps[comp].nQuantSteps, + sizeof(Guint)); + for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) { + if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) { + error(getPos(), "Error in JPX QCD marker segment"); + return gFalse; + } + } + } else { + error(getPos(), "Error in JPX QCC marker segment"); + return gFalse; + } + break; + case 0x5e: // RGN - region of interest +#if 1 //~ ROI is unimplemented + fprintf(stderr, "RGN\n"); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PPM marker segment"); + return gFalse; + } + } +#else + if ((img.nComps > 256 && !readUWord(&comp)) || + (img.nComps <= 256 && !readUByte(&comp)) || + comp >= img.nComps || + !readUByte(&compInfo[comp].roi.style) || + !readUByte(&compInfo[comp].roi.shift)) { + error(getPos(), "Error in JPX RGN marker segment"); + return gFalse; + } +#endif + break; + case 0x5f: // POC - progression order change +#if 1 //~ progression order changes are unimplemented + fprintf(stderr, "POC\n"); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PPM marker segment"); + return gFalse; + } + } +#else + nTileProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7); + tileProgs = (JPXProgOrder *)gmallocn(nTileProgs, sizeof(JPXProgOrder)); + for (i = 0; i < nTileProgs; ++i) { + if (!readUByte(&tileProgs[i].startRes) || + !(img.nComps > 256 && readUWord(&tileProgs[i].startComp)) || + !(img.nComps <= 256 && readUByte(&tileProgs[i].startComp)) || + !readUWord(&tileProgs[i].endLayer) || + !readUByte(&tileProgs[i].endRes) || + !(img.nComps > 256 && readUWord(&tileProgs[i].endComp)) || + !(img.nComps <= 256 && readUByte(&tileProgs[i].endComp)) || + !readUByte(&tileProgs[i].progOrder)) { + error(getPos(), "Error in JPX POC marker segment"); + return gFalse; + } + } +#endif + break; + case 0x61: // PPT - packed packet headers, tile-part hdr +#if 1 //~ packed packet headers are unimplemented + fprintf(stderr, "PPT\n"); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PPT marker segment"); + return gFalse; + } + } +#endif + case 0x58: // PLT - packet length, tile-part header + // skipped + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX PLT marker segment"); + return gFalse; + } + } + break; + case 0x64: // COM - comment + // skipped + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + error(getPos(), "Error in JPX COM marker segment"); + return gFalse; + } + } + break; + case 0x93: // SOD - start of data + haveSOD = gTrue; + break; + default: + error(getPos(), "Unknown marker segment %02x in JPX tile-part stream", + segType); + for (i = 0; i < segLen - 2; ++i) { + if (str->getChar() == EOF) { + break; + } + } + break; + } + } while (!haveSOD); + + //----- initialize the tile, precincts, and code-blocks + if (tilePartIdx == 0) { + tile = &img.tiles[tileIdx]; + i = tileIdx / img.nXTiles; + j = tileIdx % img.nXTiles; + if ((tile->x0 = img.xTileOffset + j * img.xTileSize) < img.xOffset) { + tile->x0 = img.xOffset; + } + if ((tile->y0 = img.yTileOffset + i * img.yTileSize) < img.yOffset) { + tile->y0 = img.yOffset; + } + if ((tile->x1 = img.xTileOffset + (j + 1) * img.xTileSize) > img.xSize) { + tile->x1 = img.xSize; + } + if ((tile->y1 = img.yTileOffset + (i + 1) * img.yTileSize) > img.ySize) { + tile->y1 = img.ySize; + } + tile->comp = 0; + tile->res = 0; + tile->precinct = 0; + tile->layer = 0; + tile->maxNDecompLevels = 0; + for (comp = 0; comp < img.nComps; ++comp) { + tileComp = &tile->tileComps[comp]; + if (tileComp->nDecompLevels > tile->maxNDecompLevels) { + tile->maxNDecompLevels = tileComp->nDecompLevels; + } + tileComp->x0 = jpxCeilDiv(tile->x0, tileComp->hSep); + tileComp->y0 = jpxCeilDiv(tile->y0, tileComp->hSep); + tileComp->x1 = jpxCeilDiv(tile->x1, tileComp->hSep); + tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->hSep); + tileComp->cbW = 1 << tileComp->codeBlockW; + tileComp->cbH = 1 << tileComp->codeBlockH; + tileComp->data = (int *)gmallocn((tileComp->x1 - tileComp->x0) * + (tileComp->y1 - tileComp->y0), + sizeof(int)); + if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) { + n = tileComp->x1 - tileComp->x0; + } else { + n = tileComp->y1 - tileComp->y0; + } + tileComp->buf = (int *)gmallocn(n + 8, sizeof(int)); + for (r = 0; r <= tileComp->nDecompLevels; ++r) { + resLevel = &tileComp->resLevels[r]; + k = r == 0 ? tileComp->nDecompLevels + : tileComp->nDecompLevels - r + 1; + resLevel->x0 = jpxCeilDivPow2(tileComp->x0, k); + resLevel->y0 = jpxCeilDivPow2(tileComp->y0, k); + resLevel->x1 = jpxCeilDivPow2(tileComp->x1, k); + resLevel->y1 = jpxCeilDivPow2(tileComp->y1, k); + if (r == 0) { + resLevel->bx0[0] = resLevel->x0; + resLevel->by0[0] = resLevel->y0; + resLevel->bx1[0] = resLevel->x1; + resLevel->by1[0] = resLevel->y1; + } else { + resLevel->bx0[0] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k); + resLevel->by0[0] = resLevel->y0; + resLevel->bx1[0] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k); + resLevel->by1[0] = resLevel->y1; + resLevel->bx0[1] = resLevel->x0; + resLevel->by0[1] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k); + resLevel->bx1[1] = resLevel->x1; + resLevel->by1[1] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k); + resLevel->bx0[2] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k); + resLevel->by0[2] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k); + resLevel->bx1[2] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k); + resLevel->by1[2] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k); + } + resLevel->precincts = (JPXPrecinct *)gmallocn(1, sizeof(JPXPrecinct)); + for (pre = 0; pre < 1; ++pre) { + precinct = &resLevel->precincts[pre]; + precinct->x0 = resLevel->x0; + precinct->y0 = resLevel->y0; + precinct->x1 = resLevel->x1; + precinct->y1 = resLevel->y1; + nSBs = r == 0 ? 1 : 3; + precinct->subbands = + (JPXSubband *)gmallocn(nSBs, sizeof(JPXSubband)); + for (sb = 0; sb < nSBs; ++sb) { + subband = &precinct->subbands[sb]; + subband->x0 = resLevel->bx0[sb]; + subband->y0 = resLevel->by0[sb]; + subband->x1 = resLevel->bx1[sb]; + subband->y1 = resLevel->by1[sb]; + subband->nXCBs = jpxCeilDivPow2(subband->x1, + tileComp->codeBlockW) + - jpxFloorDivPow2(subband->x0, + tileComp->codeBlockW); + subband->nYCBs = jpxCeilDivPow2(subband->y1, + tileComp->codeBlockH) + - jpxFloorDivPow2(subband->y0, + tileComp->codeBlockH); + n = subband->nXCBs > subband->nYCBs ? subband->nXCBs + : subband->nYCBs; + for (subband->maxTTLevel = 0, --n; + n; + ++subband->maxTTLevel, n >>= 1) ; + n = 0; + for (level = subband->maxTTLevel; level >= 0; --level) { + nx = jpxCeilDivPow2(subband->nXCBs, level); + ny = jpxCeilDivPow2(subband->nYCBs, level); + n += nx * ny; + } + subband->inclusion = + (JPXTagTreeNode *)gmallocn(n, sizeof(JPXTagTreeNode)); + subband->zeroBitPlane = + (JPXTagTreeNode *)gmallocn(n, sizeof(JPXTagTreeNode)); + for (k = 0; k < n; ++k) { + subband->inclusion[k].finished = gFalse; + subband->inclusion[k].val = 0; + subband->zeroBitPlane[k].finished = gFalse; + subband->zeroBitPlane[k].val = 0; + } + subband->cbs = (JPXCodeBlock *)gmallocn(subband->nXCBs * + subband->nYCBs, + sizeof(JPXCodeBlock)); + sbx0 = jpxFloorDivPow2(subband->x0, tileComp->codeBlockW); + sby0 = jpxFloorDivPow2(subband->y0, tileComp->codeBlockH); + cb = subband->cbs; + for (cbY = 0; cbY < subband->nYCBs; ++cbY) { + for (cbX = 0; cbX < subband->nXCBs; ++cbX) { + cb->x0 = (sbx0 + cbX) << tileComp->codeBlockW; + cb->x1 = cb->x0 + tileComp->cbW; + if (subband->x0 > cb->x0) { + cb->x0 = subband->x0; + } + if (subband->x1 < cb->x1) { + cb->x1 = subband->x1; + } + cb->y0 = (sby0 + cbY) << tileComp->codeBlockH; + cb->y1 = cb->y0 + tileComp->cbH; + if (subband->y0 > cb->y0) { + cb->y0 = subband->y0; + } + if (subband->y1 < cb->y1) { + cb->y1 = subband->y1; + } + cb->seen = gFalse; + cb->lBlock = 3; + cb->nextPass = jpxPassCleanup; + cb->nZeroBitPlanes = 0; + cb->coeffs = + (JPXCoeff *)gmallocn((1 << (tileComp->codeBlockW + + tileComp->codeBlockH)), + sizeof(JPXCoeff)); + for (cbi = 0; + cbi < (Guint)(1 << (tileComp->codeBlockW + + tileComp->codeBlockH)); + ++cbi) { + cb->coeffs[cbi].flags = 0; + cb->coeffs[cbi].len = 0; + cb->coeffs[cbi].mag = 0; + } + cb->arithDecoder = NULL; + cb->stats = NULL; + ++cb; + } + } + } + } + } + } + } + + return readTilePartData(tileIdx, tilePartLen, tilePartToEOC); +} + +GBool JPXStream::readTilePartData(Guint tileIdx, + Guint tilePartLen, GBool tilePartToEOC) { + JPXTile *tile; + JPXTileComp *tileComp; + JPXResLevel *resLevel; + JPXPrecinct *precinct; + JPXSubband *subband; + JPXCodeBlock *cb; + Guint ttVal; + Guint bits, cbX, cbY, nx, ny, i, j, n, sb; + int level; + Guint sbCount; + + tile = &img.tiles[tileIdx]; + + // read all packets from this tile-part + while (1) { + if (tilePartToEOC) { + //~ peek for an EOC marker + } else if (tilePartLen == 0) { + break; + } + + tileComp = &tile->tileComps[tile->comp]; + resLevel = &tileComp->resLevels[tile->res]; + precinct = &resLevel->precincts[tile->precinct]; + + //----- packet header + + // zero-length flag + if (!readBits(1, &bits)) { + goto err; + } + if (0 == tile->res) + sbCount = 1; + else + sbCount = 3; + if (!bits) { + // packet is empty -- clear all code-block inclusion flags + for (sb = 0; sb < sbCount; ++sb) { + subband = &precinct->subbands[sb]; + for (cbY = 0; cbY < subband->nYCBs; ++cbY) { + for (cbX = 0; cbX < subband->nXCBs; ++cbX) { + cb = &subband->cbs[cbY * subband->nXCBs + cbX]; + cb->included = gFalse; + } + } + } + } else { + + for (sb = 0; sb < sbCount; ++sb) { + subband = &precinct->subbands[sb]; + for (cbY = 0; cbY < subband->nYCBs; ++cbY) { + for (cbX = 0; cbX < subband->nXCBs; ++cbX) { + cb = &subband->cbs[cbY * subband->nXCBs + cbX]; + + // skip code-blocks with no coefficients + if (cb->x0 >= cb->x1 || cb->y0 >= cb->y1) { + cb->included = gFalse; + continue; + } + + // code-block inclusion + if (cb->seen) { + if (!readBits(1, &cb->included)) { + goto err; + } + } else { + ttVal = 0; + i = 0; + for (level = subband->maxTTLevel; level >= 0; --level) { + nx = jpxCeilDivPow2(subband->nXCBs, level); + ny = jpxCeilDivPow2(subband->nYCBs, level); + j = i + (cbY >> level) * nx + (cbX >> level); + if (!subband->inclusion[j].finished && + !subband->inclusion[j].val) { + subband->inclusion[j].val = ttVal; + } else { + ttVal = subband->inclusion[j].val; + } + while (!subband->inclusion[j].finished && + ttVal <= tile->layer) { + if (!readBits(1, &bits)) { + goto err; + } + if (bits == 1) { + subband->inclusion[j].finished = gTrue; + } else { + ++ttVal; + } + } + subband->inclusion[j].val = ttVal; + if (ttVal > tile->layer) { + break; + } + i += nx * ny; + } + cb->included = level < 0; + } + + if (cb->included) { + + // zero bit-plane count + if (!cb->seen) { + ttVal = 0; + i = 0; + for (level = subband->maxTTLevel; level >= 0; --level) { + nx = jpxCeilDivPow2(subband->nXCBs, level); + ny = jpxCeilDivPow2(subband->nYCBs, level); + j = i + (cbY >> level) * nx + (cbX >> level); + if (!subband->zeroBitPlane[j].finished && + !subband->zeroBitPlane[j].val) { + subband->zeroBitPlane[j].val = ttVal; + } else { + ttVal = subband->zeroBitPlane[j].val; + } + while (!subband->zeroBitPlane[j].finished) { + if (!readBits(1, &bits)) { + goto err; + } + if (bits == 1) { + subband->zeroBitPlane[j].finished = gTrue; + } else { + ++ttVal; + } + } + subband->zeroBitPlane[j].val = ttVal; + i += nx * ny; + } + cb->nZeroBitPlanes = ttVal; + } + + // number of coding passes + if (!readBits(1, &bits)) { + goto err; + } + if (bits == 0) { + cb->nCodingPasses = 1; + } else { + if (!readBits(1, &bits)) { + goto err; + } + if (bits == 0) { + cb->nCodingPasses = 2; + } else { + if (!readBits(2, &bits)) { + goto err; + } + if (bits < 3) { + cb->nCodingPasses = 3 + bits; + } else { + if (!readBits(5, &bits)) { + goto err; + } + if (bits < 31) { + cb->nCodingPasses = 6 + bits; + } else { + if (!readBits(7, &bits)) { + goto err; + } + cb->nCodingPasses = 37 + bits; + } + } + } + } + + // update Lblock + while (1) { + if (!readBits(1, &bits)) { + goto err; + } + if (!bits) { + break; + } + ++cb->lBlock; + } + + // length of compressed data + //~ deal with multiple codeword segments + for (n = cb->lBlock, i = cb->nCodingPasses >> 1; + i; + ++n, i >>= 1) ; + if (!readBits(n, &cb->dataLen)) { + goto err; + } + } + } + } + } + } + tilePartLen -= byteCount; + clearBitBuf(); + + //----- packet data + + if (0 == tile->res) + sbCount = 1; + else + sbCount = 3; + for (sb = 0; sb < sbCount; ++sb) { + subband = &precinct->subbands[sb]; + for (cbY = 0; cbY < subband->nYCBs; ++cbY) { + for (cbX = 0; cbX < subband->nXCBs; ++cbX) { + cb = &subband->cbs[cbY * subband->nXCBs + cbX]; + if (cb->included) { + if (!readCodeBlockData(tileComp, resLevel, precinct, subband, + tile->res, sb, cb)) { + return gFalse; + } + tilePartLen -= cb->dataLen; + cb->seen = gTrue; + } + } + } + } + + //----- next packet + + switch (tile->progOrder) { + case 0: // layer, resolution level, component, precinct + if (++tile->comp == img.nComps) { + tile->comp = 0; + if (++tile->res == tile->maxNDecompLevels + 1) { + tile->res = 0; + if (++tile->layer == tile->nLayers) { + tile->layer = 0; + } + } + } + break; + case 1: // resolution level, layer, component, precinct + if (++tile->comp == img.nComps) { + tile->comp = 0; + if (++tile->layer == tile->nLayers) { + tile->layer = 0; + if (++tile->res == tile->maxNDecompLevels + 1) { + tile->res = 0; + } + } + } + break; + case 2: // resolution level, precinct, component, layer + //~ this isn't correct -- see B.12.1.3 + if (++tile->layer == tile->nLayers) { + tile->layer = 0; + if (++tile->comp == img.nComps) { + tile->comp = 0; + if (++tile->res == tile->maxNDecompLevels + 1) { + tile->res = 0; + } + } + } + break; + case 3: // precinct, component, resolution level, layer + //~ this isn't correct -- see B.12.1.4 + if (++tile->layer == tile->nLayers) { + tile->layer = 0; + if (++tile->res == tile->maxNDecompLevels + 1) { + tile->res = 0; + if (++tile->comp == img.nComps) { + tile->comp = 0; + } + } + } + break; + case 4: // component, precinct, resolution level, layer + //~ this isn't correct -- see B.12.1.5 + if (++tile->layer == tile->nLayers) { + tile->layer = 0; + if (++tile->res == tile->maxNDecompLevels + 1) { + tile->res = 0; + if (++tile->comp == img.nComps) { + tile->comp = 0; + } + } + } + break; + } + } + + return gTrue; + + err: + error(getPos(), "Error in JPX stream"); + return gFalse; +} + +GBool JPXStream::readCodeBlockData(JPXTileComp *tileComp, + JPXResLevel *resLevel, + JPXPrecinct *precinct, + JPXSubband *subband, + Guint res, Guint sb, + JPXCodeBlock *cb) { + JPXCoeff *coeff0, *coeff1, *coeff; + Guint horiz, vert, diag, all, cx, xorBit; + int horizSign, vertSign; + Guint i, x, y0, y1, y2; + + if (cb->arithDecoder) { + cb->arithDecoder->restart(cb->dataLen); + } else { + cb->arithDecoder = new JArithmeticDecoder(); + cb->arithDecoder->setStream(str, cb->dataLen); + cb->arithDecoder->start(); + cb->stats = new JArithmeticDecoderStats(jpxNContexts); + cb->stats->setEntry(jpxContextSigProp, 4, 0); + cb->stats->setEntry(jpxContextRunLength, 3, 0); + cb->stats->setEntry(jpxContextUniform, 46, 0); + } + + for (i = 0; i < cb->nCodingPasses; ++i) { + switch (cb->nextPass) { + + //----- significance propagation pass + case jpxPassSigProp: + for (y0 = cb->y0, coeff0 = cb->coeffs; + y0 < cb->y1; + y0 += 4, coeff0 += 4 << tileComp->codeBlockW) { + for (x = cb->x0, coeff1 = coeff0; + x < cb->x1; + ++x, ++coeff1) { + for (y1 = 0, coeff = coeff1; + y1 < 4 && y0+y1 < cb->y1; + ++y1, coeff += tileComp->cbW) { + if (!(coeff->flags & jpxCoeffSignificant)) { + horiz = vert = diag = 0; + horizSign = vertSign = 2; + if (x > cb->x0) { + if (coeff[-1].flags & jpxCoeffSignificant) { + ++horiz; + horizSign += (coeff[-1].flags & jpxCoeffSign) ? -1 : 1; + } + if (y0+y1 > cb->y0) { + diag += (coeff[-(int)tileComp->cbW - 1].flags + >> jpxCoeffSignificantB) & 1; + } + if (y0+y1 < cb->y1 - 1) { + diag += (coeff[tileComp->cbW - 1].flags + >> jpxCoeffSignificantB) & 1; + } + } + if (x < cb->x1 - 1) { + if (coeff[1].flags & jpxCoeffSignificant) { + ++horiz; + horizSign += (coeff[1].flags & jpxCoeffSign) ? -1 : 1; + } + if (y0+y1 > cb->y0) { + diag += (coeff[-(int)tileComp->cbW + 1].flags + >> jpxCoeffSignificantB) & 1; + } + if (y0+y1 < cb->y1 - 1) { + diag += (coeff[tileComp->cbW + 1].flags + >> jpxCoeffSignificantB) & 1; + } + } + if (y0+y1 > cb->y0) { + if (coeff[-(int)tileComp->cbW].flags & jpxCoeffSignificant) { + ++vert; + vertSign += (coeff[-(int)tileComp->cbW].flags & jpxCoeffSign) + ? -1 : 1; + } + } + if (y0+y1 < cb->y1 - 1) { + if (coeff[tileComp->cbW].flags & jpxCoeffSignificant) { + ++vert; + vertSign += (coeff[tileComp->cbW].flags & jpxCoeffSign) + ? -1 : 1; + } + } + cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb]; + if (cx != 0) { + if (cb->arithDecoder->decodeBit(cx, cb->stats)) { + coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef; + coeff->mag = (coeff->mag << 1) | 1; + cx = signContext[horizSign][vertSign][0]; + xorBit = signContext[horizSign][vertSign][1]; + if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) { + coeff->flags |= jpxCoeffSign; + } + } + ++coeff->len; + coeff->flags |= jpxCoeffTouched; + } + } + } + } + } + ++cb->nextPass; + break; + + //----- magnitude refinement pass + case jpxPassMagRef: + for (y0 = cb->y0, coeff0 = cb->coeffs; + y0 < cb->y1; + y0 += 4, coeff0 += 4 << tileComp->codeBlockW) { + for (x = cb->x0, coeff1 = coeff0; + x < cb->x1; + ++x, ++coeff1) { + for (y1 = 0, coeff = coeff1; + y1 < 4 && y0+y1 < cb->y1; + ++y1, coeff += tileComp->cbW) { + if ((coeff->flags & jpxCoeffSignificant) && + !(coeff->flags & jpxCoeffTouched)) { + if (coeff->flags & jpxCoeffFirstMagRef) { + all = 0; + if (x > cb->x0) { + all += (coeff[-1].flags >> jpxCoeffSignificantB) & 1; + if (y0+y1 > cb->y0) { + all += (coeff[-(int)tileComp->cbW - 1].flags + >> jpxCoeffSignificantB) & 1; + } + if (y0+y1 < cb->y1 - 1) { + all += (coeff[tileComp->cbW - 1].flags + >> jpxCoeffSignificantB) & 1; + } + } + if (x < cb->x1 - 1) { + all += (coeff[1].flags >> jpxCoeffSignificantB) & 1; + if (y0+y1 > cb->y0) { + all += (coeff[-(int)tileComp->cbW + 1].flags + >> jpxCoeffSignificantB) & 1; + } + if (y0+y1 < cb->y1 - 1) { + all += (coeff[tileComp->cbW + 1].flags + >> jpxCoeffSignificantB) & 1; + } + } + if (y0+y1 > cb->y0) { + all += (coeff[-(int)tileComp->cbW].flags + >> jpxCoeffSignificantB) & 1; + } + if (y0+y1 < cb->y1 - 1) { + all += (coeff[tileComp->cbW].flags + >> jpxCoeffSignificantB) & 1; + } + cx = all ? 15 : 14; + } else { + cx = 16; + } + coeff->mag = (coeff->mag << 1) | + cb->arithDecoder->decodeBit(cx, cb->stats); + ++coeff->len; + coeff->flags |= jpxCoeffTouched; + coeff->flags &= ~jpxCoeffFirstMagRef; + } + } + } + } + ++cb->nextPass; + break; + + //----- cleanup pass + case jpxPassCleanup: + for (y0 = cb->y0, coeff0 = cb->coeffs; + y0 < cb->y1; + y0 += 4, coeff0 += 4 << tileComp->codeBlockW) { + for (x = cb->x0, coeff1 = coeff0; + x < cb->x1; + ++x, ++coeff1) { + y1 = 0; + if (y0 + 3 < cb->y1 && + !(coeff1->flags & jpxCoeffTouched) && + !(coeff1[tileComp->cbW].flags & jpxCoeffTouched) && + !(coeff1[2 * tileComp->cbW].flags & jpxCoeffTouched) && + !(coeff1[3 * tileComp->cbW].flags & jpxCoeffTouched) && + (x == cb->x0 || y0 == cb->y0 || + !(coeff1[-(int)tileComp->cbW - 1].flags + & jpxCoeffSignificant)) && + (y0 == cb->y0 || + !(coeff1[-(int)tileComp->cbW].flags + & jpxCoeffSignificant)) && + (x == cb->x1 - 1 || y0 == cb->y0 || + !(coeff1[-(int)tileComp->cbW + 1].flags + & jpxCoeffSignificant)) && + (x == cb->x0 || + (!(coeff1[-1].flags & jpxCoeffSignificant) && + !(coeff1[tileComp->cbW - 1].flags + & jpxCoeffSignificant) && + !(coeff1[2 * tileComp->cbW - 1].flags + & jpxCoeffSignificant) && + !(coeff1[3 * tileComp->cbW - 1].flags + & jpxCoeffSignificant))) && + (x == cb->x1 - 1 || + (!(coeff1[1].flags & jpxCoeffSignificant) && + !(coeff1[tileComp->cbW + 1].flags + & jpxCoeffSignificant) && + !(coeff1[2 * tileComp->cbW + 1].flags + & jpxCoeffSignificant) && + !(coeff1[3 * tileComp->cbW + 1].flags + & jpxCoeffSignificant))) && + (x == cb->x0 || y0+4 == cb->y1 || + !(coeff1[4 * tileComp->cbW - 1].flags & jpxCoeffSignificant)) && + (y0+4 == cb->y1 || + !(coeff1[4 * tileComp->cbW].flags & jpxCoeffSignificant)) && + (x == cb->x1 - 1 || y0+4 == cb->y1 || + !(coeff1[4 * tileComp->cbW + 1].flags + & jpxCoeffSignificant))) { + if (cb->arithDecoder->decodeBit(jpxContextRunLength, cb->stats)) { + y1 = cb->arithDecoder->decodeBit(jpxContextUniform, cb->stats); + y1 = (y1 << 1) | + cb->arithDecoder->decodeBit(jpxContextUniform, cb->stats); + for (y2 = 0, coeff = coeff1; + y2 < y1; + ++y2, coeff += tileComp->cbW) { + ++coeff->len; + } + coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef; + coeff->mag = (coeff->mag << 1) | 1; + ++coeff->len; + cx = signContext[2][2][0]; + xorBit = signContext[2][2][1]; + if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) { + coeff->flags |= jpxCoeffSign; + } + ++y1; + } else { + for (y1 = 0, coeff = coeff1; + y1 < 4; + ++y1, coeff += tileComp->cbW) { + ++coeff->len; + } + y1 = 4; + } + } + for (coeff = &coeff1[y1 << tileComp->codeBlockW]; + y1 < 4 && y0 + y1 < cb->y1; + ++y1, coeff += tileComp->cbW) { + if (!(coeff->flags & jpxCoeffTouched)) { + horiz = vert = diag = 0; + horizSign = vertSign = 2; + if (x > cb->x0) { + if (coeff[-1].flags & jpxCoeffSignificant) { + ++horiz; + horizSign += (coeff[-1].flags & jpxCoeffSign) ? -1 : 1; + } + if (y0+y1 > cb->y0) { + diag += (coeff[-(int)tileComp->cbW - 1].flags + >> jpxCoeffSignificantB) & 1; + } + if (y0+y1 < cb->y1 - 1) { + diag += (coeff[tileComp->cbW - 1].flags + >> jpxCoeffSignificantB) & 1; + } + } + if (x < cb->x1 - 1) { + if (coeff[1].flags & jpxCoeffSignificant) { + ++horiz; + horizSign += (coeff[1].flags & jpxCoeffSign) ? -1 : 1; + } + if (y0+y1 > cb->y0) { + diag += (coeff[-(int)tileComp->cbW + 1].flags + >> jpxCoeffSignificantB) & 1; + } + if (y0+y1 < cb->y1 - 1) { + diag += (coeff[tileComp->cbW + 1].flags + >> jpxCoeffSignificantB) & 1; + } + } + if (y0+y1 > cb->y0) { + if (coeff[-(int)tileComp->cbW].flags & jpxCoeffSignificant) { + ++vert; + vertSign += (coeff[-(int)tileComp->cbW].flags & jpxCoeffSign) + ? -1 : 1; + } + } + if (y0+y1 < cb->y1 - 1) { + if (coeff[tileComp->cbW].flags & jpxCoeffSignificant) { + ++vert; + vertSign += (coeff[tileComp->cbW].flags & jpxCoeffSign) + ? -1 : 1; + } + } + cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb]; + if (cb->arithDecoder->decodeBit(cx, cb->stats)) { + coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef; + coeff->mag = (coeff->mag << 1) | 1; + cx = signContext[horizSign][vertSign][0]; + xorBit = signContext[horizSign][vertSign][1]; + if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) { + coeff->flags |= jpxCoeffSign; + } + } + ++coeff->len; + } else { + coeff->flags &= ~jpxCoeffTouched; + } + } + } + } + cb->nextPass = jpxPassSigProp; + break; + } + } + + cb->arithDecoder->cleanup(); + return gTrue; +} + +// Inverse quantization, and wavelet transform (IDWT). This also does +// the initial shift to convert to fixed point format. +void JPXStream::inverseTransform(JPXTileComp *tileComp) { + JPXResLevel *resLevel; + JPXPrecinct *precinct; + JPXSubband *subband; + JPXCodeBlock *cb; + JPXCoeff *coeff0, *coeff; + Guint qStyle, guard, eps, shift; + int shift2; + double mu; + int val; + int *dataPtr; + Guint nx0, ny0, nx1, ny1; + Guint r, cbX, cbY, x, y; + + //----- (NL)LL subband (resolution level 0) + + resLevel = &tileComp->resLevels[0]; + precinct = &resLevel->precincts[0]; + subband = &precinct->subbands[0]; + + // i-quant parameters + qStyle = tileComp->quantStyle & 0x1f; + guard = (tileComp->quantStyle >> 5) & 7; + if (qStyle == 0) { + eps = (tileComp->quantSteps[0] >> 3) & 0x1f; + shift = guard + eps - 1; + mu = 0; // make gcc happy + } else { + shift = guard - 1 + tileComp->prec; + mu = (double)(0x800 + (tileComp->quantSteps[0] & 0x7ff)) / 2048.0; + } + if (tileComp->transform == 0) { + shift += fracBits; + } + + // copy (NL)LL into the upper-left corner of the data array, doing + // the fixed point adjustment and dequantization along the way + cb = subband->cbs; + for (cbY = 0; cbY < subband->nYCBs; ++cbY) { + for (cbX = 0; cbX < subband->nXCBs; ++cbX) { + for (y = cb->y0, coeff0 = cb->coeffs; + y < cb->y1; + ++y, coeff0 += tileComp->cbW) { + dataPtr = &tileComp->data[(y - subband->y0) + * (tileComp->x1 - tileComp->x0) + + (cb->x0 - subband->x0)]; + for (x = cb->x0, coeff = coeff0; x < cb->x1; ++x, ++coeff) { + val = (int)coeff->mag; + if (val != 0) { + shift2 = shift - (cb->nZeroBitPlanes + coeff->len); + if (shift2 > 0) { + val = (val << shift2) + (1 << (shift2 - 1)); + } else { + val >>= -shift2; + } + if (qStyle == 0) { + if (tileComp->transform == 0) { + val &= -1 << fracBits; + } + } else { + val = (int)((double)val * mu); + } + if (coeff->flags & jpxCoeffSign) { + val = -val; + } + } + *dataPtr++ = val; + } + } + ++cb; + } + } + + //----- IDWT for each level + + for (r = 1; r <= tileComp->nDecompLevels; ++r) { + resLevel = &tileComp->resLevels[r]; + + // (n)LL is already in the upper-left corner of the + // tile-component data array -- interleave with (n)HL/LH/HH + // and inverse transform to get (n-1)LL, which will be stored + // in the upper-left corner of the tile-component data array + if (r == tileComp->nDecompLevels) { + nx0 = tileComp->x0; + ny0 = tileComp->y0; + nx1 = tileComp->x1; + ny1 = tileComp->y1; + } else { + nx0 = tileComp->resLevels[r+1].x0; + ny0 = tileComp->resLevels[r+1].y0; + nx1 = tileComp->resLevels[r+1].x1; + ny1 = tileComp->resLevels[r+1].y1; + } + inverseTransformLevel(tileComp, r, resLevel, nx0, ny0, nx1, ny1); + } +} + +// Do one level of the inverse transform: +// - take (n)LL from the tile-component data array +// - take (n)HL/LH/HH from +// - leave the resulting (n-1)LL in the tile-component data array +void JPXStream::inverseTransformLevel(JPXTileComp *tileComp, + Guint r, JPXResLevel *resLevel, + Guint nx0, Guint ny0, + Guint nx1, Guint ny1) { + JPXPrecinct *precinct; + JPXSubband *subband; + JPXCodeBlock *cb; + JPXCoeff *coeff0, *coeff; + Guint qStyle, guard, eps, shift, t; + int shift2; + double mu; + int val; + int *dataPtr; + Guint xo, yo; + Guint x, y, sb, cbX, cbY; + int xx, yy; + + //----- interleave + + // spread out LL + for (yy = resLevel->y1 - 1; yy >= (int)resLevel->y0; --yy) { + for (xx = resLevel->x1 - 1; xx >= (int)resLevel->x0; --xx) { + tileComp->data[(2 * yy - ny0) * (tileComp->x1 - tileComp->x0) + + (2 * xx - nx0)] = + tileComp->data[(yy - resLevel->y0) * (tileComp->x1 - tileComp->x0) + + (xx - resLevel->x0)]; + } + } + + // i-quant parameters + qStyle = tileComp->quantStyle & 0x1f; + guard = (tileComp->quantStyle >> 5) & 7; + + // interleave HL/LH/HH + precinct = &resLevel->precincts[0]; + for (sb = 0; sb < 3; ++sb) { + + // i-quant parameters + if (qStyle == 0) { + eps = (tileComp->quantSteps[3*r - 2 + sb] >> 3) & 0x1f; + shift = guard + eps - 1; + mu = 0; // make gcc happy + } else { + shift = guard + tileComp->prec; + if (sb == 2) { + ++shift; + } + t = tileComp->quantSteps[qStyle == 1 ? 0 : (3*r - 2 + sb)]; + mu = (double)(0x800 + (t & 0x7ff)) / 2048.0; + } + if (tileComp->transform == 0) { + shift += fracBits; + } + + // copy the subband coefficients into the data array, doing the + // fixed point adjustment and dequantization along the way + xo = (sb & 1) ? 0 : 1; + yo = (sb > 0) ? 1 : 0; + subband = &precinct->subbands[sb]; + cb = subband->cbs; + for (cbY = 0; cbY < subband->nYCBs; ++cbY) { + for (cbX = 0; cbX < subband->nXCBs; ++cbX) { + for (y = cb->y0, coeff0 = cb->coeffs; + y < cb->y1; + ++y, coeff0 += tileComp->cbW) { + dataPtr = &tileComp->data[(2 * y + yo - ny0) + * (tileComp->x1 - tileComp->x0) + + (2 * cb->x0 + xo - nx0)]; + for (x = cb->x0, coeff = coeff0; x < cb->x1; ++x, ++coeff) { + val = (int)coeff->mag; + if (val != 0) { + shift2 = shift - (cb->nZeroBitPlanes + coeff->len); + if (shift2 > 0) { + val = (val << shift2) + (1 << (shift2 - 1)); + } else { + val >>= -shift2; + } + if (qStyle == 0) { + if (tileComp->transform == 0) { + val &= -1 << fracBits; + } + } else { + val = (int)((double)val * mu); + } + if (coeff->flags & jpxCoeffSign) { + val = -val; + } + } + *dataPtr = val; + dataPtr += 2; + } + } + ++cb; + } + } + } + + //----- horizontal (row) transforms + dataPtr = tileComp->data; + for (y = 0; y < ny1 - ny0; ++y) { + inverseTransform1D(tileComp, dataPtr, 1, nx0, nx1); + dataPtr += tileComp->x1 - tileComp->x0; + } + + //----- vertical (column) transforms + dataPtr = tileComp->data; + for (x = 0; x < nx1 - nx0; ++x) { + inverseTransform1D(tileComp, dataPtr, + tileComp->x1 - tileComp->x0, ny0, ny1); + ++dataPtr; + } +} + +void JPXStream::inverseTransform1D(JPXTileComp *tileComp, + int *data, Guint stride, + Guint i0, Guint i1) { + int *buf; + Guint offset, end, i; + + //----- special case for length = 1 + if (i1 - i0 == 1) { + if (i0 & 1) { + *data >>= 1; + } + + } else { + + // choose an offset: this makes even buf[] indexes correspond to + // odd values of i, and vice versa + offset = 3 + (i0 & 1); + end = offset + i1 - i0; + + //----- gather + buf = tileComp->buf; + for (i = 0; i < i1 - i0; ++i) { + buf[offset + i] = data[i * stride]; + } + + //----- extend right + buf[end] = buf[end - 2]; + if (i1 - i0 == 2) { + buf[end+1] = buf[offset + 1]; + buf[end+2] = buf[offset]; + buf[end+3] = buf[offset + 1]; + } else { + buf[end+1] = buf[end - 3]; + if (i1 - i0 == 3) { + buf[end+2] = buf[offset + 1]; + buf[end+3] = buf[offset + 2]; + } else { + buf[end+2] = buf[end - 4]; + if (i1 - i0 == 4) { + buf[end+3] = buf[offset + 1]; + } else { + buf[end+3] = buf[end - 5]; + } + } + } + + //----- extend left + buf[offset - 1] = buf[offset + 1]; + buf[offset - 2] = buf[offset + 2]; + buf[offset - 3] = buf[offset + 3]; + if (offset == 4) { + buf[0] = buf[offset + 4]; + } + + //----- 9-7 irreversible filter + + if (tileComp->transform == 0) { + // step 1 (even) + for (i = 1; i <= end + 2; i += 2) { + buf[i] = (int)(idwtKappa * buf[i]); + } + // step 2 (odd) + for (i = 0; i <= end + 3; i += 2) { + buf[i] = (int)(idwtIKappa * buf[i]); + } + // step 3 (even) + for (i = 1; i <= end + 2; i += 2) { + buf[i] = (int)(buf[i] - idwtDelta * (buf[i-1] + buf[i+1])); + } + // step 4 (odd) + for (i = 2; i <= end + 1; i += 2) { + buf[i] = (int)(buf[i] - idwtGamma * (buf[i-1] + buf[i+1])); + } + // step 5 (even) + for (i = 3; i <= end; i += 2) { + buf[i] = (int)(buf[i] - idwtBeta * (buf[i-1] + buf[i+1])); + } + // step 6 (odd) + for (i = 4; i <= end - 1; i += 2) { + buf[i] = (int)(buf[i] - idwtAlpha * (buf[i-1] + buf[i+1])); + } + + //----- 5-3 reversible filter + + } else { + // step 1 (even) + for (i = 3; i <= end; i += 2) { + buf[i] -= (buf[i-1] + buf[i+1] + 2) >> 2; + } + // step 2 (odd) + for (i = 4; i < end; i += 2) { + buf[i] += (buf[i-1] + buf[i+1]) >> 1; + } + } + + //----- scatter + for (i = 0; i < i1 - i0; ++i) { + data[i * stride] = buf[offset + i]; + } + } +} + +// Inverse multi-component transform and DC level shift. This also +// converts fixed point samples back to integers. +GBool JPXStream::inverseMultiCompAndDC(JPXTile *tile) { + JPXTileComp *tileComp; + int coeff, d0, d1, d2, t, minVal, maxVal, zeroVal; + int *dataPtr; + Guint j, comp, x, y; + + //----- inverse multi-component transform + + if (tile->multiComp == 1) { + if (img.nComps < 3 || + tile->tileComps[0].hSep != tile->tileComps[1].hSep || + tile->tileComps[0].vSep != tile->tileComps[1].vSep || + tile->tileComps[1].hSep != tile->tileComps[2].hSep || + tile->tileComps[1].vSep != tile->tileComps[2].vSep) { + return gFalse; + } + + // inverse irreversible multiple component transform + if (tile->tileComps[0].transform == 0) { + j = 0; + for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) { + for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) { + d0 = tile->tileComps[0].data[j]; + d1 = tile->tileComps[1].data[j]; + d2 = tile->tileComps[2].data[j]; + tile->tileComps[0].data[j] = (int)(d0 + 1.402 * d2 + 0.5); + tile->tileComps[1].data[j] = + (int)(d0 - 0.34413 * d1 - 0.71414 * d2 + 0.5); + tile->tileComps[2].data[j] = (int)(d0 + 1.772 * d1 + 0.5); + ++j; + } + } + + // inverse reversible multiple component transform + } else { + j = 0; + for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) { + for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) { + d0 = tile->tileComps[0].data[j]; + d1 = tile->tileComps[1].data[j]; + d2 = tile->tileComps[2].data[j]; + tile->tileComps[1].data[j] = t = d0 - ((d2 + d1) >> 2); + tile->tileComps[0].data[j] = d2 + t; + tile->tileComps[2].data[j] = d1 + t; + ++j; + } + } + } + } + + //----- DC level shift + for (comp = 0; comp < img.nComps; ++comp) { + tileComp = &tile->tileComps[comp]; + + // signed: clip + if (tileComp->sgned) { + minVal = -(1 << (tileComp->prec - 1)); + maxVal = (1 << (tileComp->prec - 1)) - 1; + dataPtr = tileComp->data; + for (y = 0; y < tileComp->y1 - tileComp->y0; ++y) { + for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) { + coeff = *dataPtr; + if (tileComp->transform == 0) { + coeff >>= fracBits; + } + if (coeff < minVal) { + coeff = minVal; + } else if (coeff > maxVal) { + coeff = maxVal; + } + *dataPtr++ = coeff; + } + } + + // unsigned: inverse DC level shift and clip + } else { + maxVal = (1 << tileComp->prec) - 1; + zeroVal = 1 << (tileComp->prec - 1); + dataPtr = tileComp->data; + for (y = 0; y < tileComp->y1 - tileComp->y0; ++y) { + for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) { + coeff = *dataPtr; + if (tileComp->transform == 0) { + coeff >>= fracBits; + } + coeff += zeroVal; + if (coeff < 0) { + coeff = 0; + } else if (coeff > maxVal) { + coeff = maxVal; + } + *dataPtr++ = coeff; + } + } + } + } + + return gTrue; +} + +GBool JPXStream::readBoxHdr(Guint *boxType, Guint *boxLen, Guint *dataLen) { + Guint len, lenH; + + if (!readULong(&len) || + !readULong(boxType)) { + return gFalse; + } + if (len == 1) { + if (!readULong(&lenH) || !readULong(&len)) { + return gFalse; + } + if (lenH) { + error(getPos(), "JPX stream contains a box larger than 2^32 bytes"); + return gFalse; + } + *boxLen = len; + *dataLen = len - 16; + } else if (len == 0) { + *boxLen = 0; + *dataLen = 0; + } else { + *boxLen = len; + *dataLen = len - 8; + } + return gTrue; +} + +int JPXStream::readMarkerHdr(int *segType, Guint *segLen) { + int c; + + do { + do { + if ((c = str->getChar()) == EOF) { + return gFalse; + } + } while (c != 0xff); + do { + if ((c = str->getChar()) == EOF) { + return gFalse; + } + } while (c == 0xff); + } while (c == 0x00); + *segType = c; + if ((c >= 0x30 && c <= 0x3f) || + c == 0x4f || c == 0x92 || c == 0x93 || c == 0xd9) { + *segLen = 0; + return gTrue; + } + return readUWord(segLen); +} + +GBool JPXStream::readUByte(Guint *x) { + int c0; + + if ((c0 = str->getChar()) == EOF) { + return gFalse; + } + *x = (Guint)c0; + return gTrue; +} + +GBool JPXStream::readByte(int *x) { + int c0; + + if ((c0 = str->getChar()) == EOF) { + return gFalse; + } + *x = c0; + if (c0 & 0x80) { + *x |= -1 - 0xff; + } + return gTrue; +} + +GBool JPXStream::readUWord(Guint *x) { + int c0, c1; + + if ((c0 = str->getChar()) == EOF || + (c1 = str->getChar()) == EOF) { + return gFalse; + } + *x = (Guint)((c0 << 8) | c1); + return gTrue; +} + +GBool JPXStream::readULong(Guint *x) { + int c0, c1, c2, c3; + + if ((c0 = str->getChar()) == EOF || + (c1 = str->getChar()) == EOF || + (c2 = str->getChar()) == EOF || + (c3 = str->getChar()) == EOF) { + return gFalse; + } + *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3); + return gTrue; +} + +GBool JPXStream::readNBytes(int nBytes, GBool signd, int *x) { + int y, c, i; + + y = 0; + for (i = 0; i < nBytes; ++i) { + if ((c = str->getChar()) == EOF) { + return gFalse; + } + y = (y << 8) + c; + } + if (signd) { + if (y & (1 << (8 * nBytes - 1))) { + y |= -1 << (8 * nBytes); + } + } + *x = y; + return gTrue; +} + +GBool JPXStream::readBits(int nBits, Guint *x) { + int c; + + while (bitBufLen < nBits) { + if ((c = str->getChar()) == EOF) { + return gFalse; + } + ++byteCount; + if (bitBufSkip) { + bitBuf = (bitBuf << 7) | (c & 0x7f); + bitBufLen += 7; + } else { + bitBuf = (bitBuf << 8) | (c & 0xff); + bitBufLen += 8; + } + bitBufSkip = c == 0xff; + } + *x = (bitBuf >> (bitBufLen - nBits)) & ((1 << nBits) - 1); + bitBufLen -= nBits; + return gTrue; +} + +void JPXStream::clearBitBuf() { + bitBufLen = 0; + bitBufSkip = gFalse; + byteCount = 0; +} diff --git a/rosapps/smartpdf/poppler/poppler/JPXStream.h b/rosapps/smartpdf/poppler/poppler/JPXStream.h new file mode 100644 index 00000000000..2de7641bbde --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/JPXStream.h @@ -0,0 +1,347 @@ +//======================================================================== +// +// JPXStream.h +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef JPXSTREAM_H +#define JPXSTREAM_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "Object.h" +#include "Stream.h" + +class JArithmeticDecoderStats; + +//------------------------------------------------------------------------ + +enum JPXColorSpaceType { + jpxCSBiLevel = 0, + jpxCSYCbCr1 = 1, + jpxCSYCbCr2 = 3, + jpxCSYCBCr3 = 4, + jpxCSPhotoYCC = 9, + jpxCSCMY = 11, + jpxCSCMYK = 12, + jpxCSYCCK = 13, + jpxCSCIELab = 14, + jpxCSsRGB = 16, + jpxCSGrayscale = 17, + jpxCSBiLevel2 = 18, + jpxCSCIEJab = 19, + jpxCSCISesRGB = 20, + jpxCSROMMRGB = 21, + jpxCSsRGBYCbCr = 22, + jpxCSYPbPr1125 = 23, + jpxCSYPbPr1250 = 24 +}; + +struct JPXColorSpecCIELab { + Guint rl, ol, ra, oa, rb, ob, il; +}; + +struct JPXColorSpecEnumerated { + JPXColorSpaceType type; // color space type + union { + JPXColorSpecCIELab cieLab; + }; +}; + +struct JPXColorSpec { + Guint meth; // method + int prec; // precedence + union { + JPXColorSpecEnumerated enumerated; + }; +}; + +//------------------------------------------------------------------------ + +struct JPXPalette { + Guint nEntries; // number of entries in the palette + Guint nComps; // number of components in each entry + Guint *bpc; // bits per component, for each component + int *c; // color data: + // c[i*nComps+j] = entry i, component j +}; + +//------------------------------------------------------------------------ + +struct JPXCompMap { + Guint nChannels; // number of channels + Guint *comp; // codestream components mapped to each channel + Guint *type; // 0 for direct use, 1 for palette mapping + Guint *pComp; // palette components to use +}; + +//------------------------------------------------------------------------ + +struct JPXChannelDefn { + Guint nChannels; // number of channels + Guint *idx; // channel indexes + Guint *type; // channel types + Guint *assoc; // channel associations +}; + +//------------------------------------------------------------------------ + +struct JPXTagTreeNode { + GBool finished; // true if this node is finished + Guint val; // current value +}; + +//------------------------------------------------------------------------ + +struct JPXCoeff { + Gushort flags; // flag bits + Gushort len; // number of significant bits in mag + Guint mag; // magnitude value +}; + +// coefficient flags +#define jpxCoeffSignificantB 0 +#define jpxCoeffTouchedB 1 +#define jpxCoeffFirstMagRefB 2 +#define jpxCoeffSignB 7 +#define jpxCoeffSignificant (1 << jpxCoeffSignificantB) +#define jpxCoeffTouched (1 << jpxCoeffTouchedB) +#define jpxCoeffFirstMagRef (1 << jpxCoeffFirstMagRefB) +#define jpxCoeffSign (1 << jpxCoeffSignB) + +//------------------------------------------------------------------------ + +struct JPXCodeBlock { + //----- size + Guint x0, y0, x1, y1; // bounds + + //----- persistent state + GBool seen; // true if this code-block has already + // been seen + Guint lBlock; // base number of bits used for pkt data length + Guint nextPass; // next coding pass + + //---- info from first packet + Guint nZeroBitPlanes; // number of zero bit planes + + //----- info for the current packet + Guint included; // code-block inclusion in this packet: + // 0=not included, 1=included + Guint nCodingPasses; // number of coding passes in this pkt + Guint dataLen; // pkt data length + + //----- coefficient data + JPXCoeff *coeffs; // the coefficients + JArithmeticDecoder // arithmetic decoder + *arithDecoder; + JArithmeticDecoderStats // arithmetic decoder stats + *stats; +}; + +//------------------------------------------------------------------------ + +struct JPXSubband { + //----- computed + Guint x0, y0, x1, y1; // bounds + Guint nXCBs, nYCBs; // number of code-blocks in the x and y + // directions + + //----- tag trees + Guint maxTTLevel; // max tag tree level + JPXTagTreeNode *inclusion; // inclusion tag tree for each subband + JPXTagTreeNode *zeroBitPlane; // zero-bit plane tag tree for each + // subband + + //----- children + JPXCodeBlock *cbs; // the code-blocks (len = nXCBs * nYCBs) +}; + +//------------------------------------------------------------------------ + +struct JPXPrecinct { + //----- computed + Guint x0, y0, x1, y1; // bounds of the precinct + + //----- children + JPXSubband *subbands; // the subbands +}; + +//------------------------------------------------------------------------ + +struct JPXResLevel { + //----- from the COD and COC segments (main and tile) + Guint precinctWidth; // log2(precinct width) + Guint precinctHeight; // log2(precinct height) + + //----- computed + Guint x0, y0, x1, y1; // bounds of the tile-comp (for this res level) + Guint bx0[3], by0[3], // subband bounds + bx1[3], by1[3]; + + //---- children + JPXPrecinct *precincts; // the precincts +}; + +//------------------------------------------------------------------------ + +struct JPXTileComp { + //----- from the SIZ segment + GBool sgned; // 1 for signed, 0 for unsigned + Guint prec; // precision, in bits + Guint hSep; // horizontal separation of samples + Guint vSep; // vertical separation of samples + + //----- from the COD and COC segments (main and tile) + Guint style; // coding style parameter (Scod / Scoc) + Guint nDecompLevels; // number of decomposition levels + Guint codeBlockW; // log2(code-block width) + Guint codeBlockH; // log2(code-block height) + Guint codeBlockStyle; // code-block style + Guint transform; // wavelet transformation + + //----- from the QCD and QCC segments (main and tile) + Guint quantStyle; // quantization style + Guint *quantSteps; // quantization step size for each subband + Guint nQuantSteps; // number of entries in quantSteps + + //----- computed + Guint x0, y0, x1, y1; // bounds of the tile-comp, in ref coords + Guint cbW; // code-block width + Guint cbH; // code-block height + + //----- image data + int *data; // the decoded image data + int *buf; // intermediate buffer for the inverse + // transform + + //----- children + JPXResLevel *resLevels; // the resolution levels + // (len = nDecompLevels + 1) +}; + +//------------------------------------------------------------------------ + +struct JPXTile { + //----- from the COD segments (main and tile) + Guint progOrder; // progression order + Guint nLayers; // number of layers + Guint multiComp; // multiple component transformation + + //----- computed + Guint x0, y0, x1, y1; // bounds of the tile, in ref coords + Guint maxNDecompLevels; // max number of decomposition levels used + // in any component in this tile + + //----- progression order loop counters + Guint comp; // component + Guint res; // resolution level + Guint precinct; // precinct + Guint layer; // layer + + //----- children + JPXTileComp *tileComps; // the tile-components (len = JPXImage.nComps) +}; + +//------------------------------------------------------------------------ + +struct JPXImage { + //----- from the SIZ segment + Guint xSize, ySize; // size of reference grid + Guint xOffset, yOffset; // image offset + Guint xTileSize, yTileSize; // size of tiles + Guint xTileOffset, // offset of first tile + yTileOffset; + Guint nComps; // number of components + + //----- computed + Guint nXTiles; // number of tiles in x direction + Guint nYTiles; // number of tiles in y direction + + //----- children + JPXTile *tiles; // the tiles (len = nXTiles * nYTiles) +}; + +//------------------------------------------------------------------------ + +class JPXStream: public FilterStream { +public: + + JPXStream(Stream *strA); + virtual ~JPXStream(); + virtual StreamKind getKind() { return strJPX; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual void getImageParams(int *bitsPerComponent, + StreamColorSpaceMode *csMode); + +private: + + void fillReadBuf(); + void getImageParams2(int *bitsPerComponent, StreamColorSpaceMode *csMode); + GBool readBoxes(); + GBool readColorSpecBox(Guint dataLen); + GBool readCodestream(Guint len); + GBool readTilePart(); + GBool readTilePartData(Guint tileIdx, + Guint tilePartLen, GBool tilePartToEOC); + GBool readCodeBlockData(JPXTileComp *tileComp, + JPXResLevel *resLevel, + JPXPrecinct *precinct, + JPXSubband *subband, + Guint res, Guint sb, + JPXCodeBlock *cb); + void inverseTransform(JPXTileComp *tileComp); + void inverseTransformLevel(JPXTileComp *tileComp, + Guint r, JPXResLevel *resLevel, + Guint nx0, Guint ny0, + Guint nx1, Guint ny1); + void inverseTransform1D(JPXTileComp *tileComp, + int *data, Guint stride, + Guint i0, Guint i1); + GBool inverseMultiCompAndDC(JPXTile *tile); + GBool readBoxHdr(Guint *boxType, Guint *boxLen, Guint *dataLen); + int readMarkerHdr(int *segType, Guint *segLen); + GBool readUByte(Guint *x); + GBool readByte(int *x); + GBool readUWord(Guint *x); + GBool readULong(Guint *x); + GBool readNBytes(int nBytes, GBool signd, int *x); + GBool readBits(int nBits, Guint *x); + void clearBitBuf(); + + Guint nComps; // number of components + Guint *bpc; // bits per component, for each component + Guint width, height; // image size + GBool haveImgHdr; // set if a JP2/JPX image header has been + // found + JPXColorSpec cs; // color specification + GBool haveCS; // set if a color spec has been found + JPXPalette palette; // the palette + GBool havePalette; // set if a palette has been found + JPXCompMap compMap; // the component mapping + GBool haveCompMap; // set if a component mapping has been found + JPXChannelDefn channelDefn; // channel definition + GBool haveChannelDefn; // set if a channel defn has been found + + JPXImage img; // JPEG2000 decoder data + Guint bitBuf; // buffer for bit reads + int bitBufLen; // number of bits in bitBuf + GBool bitBufSkip; // true if next bit should be skipped + // (for bit stuffing) + Guint byteCount; // number of bytes read since last call + // to clearBitBuf + + Guint curX, curY, curComp; // current position for lookChar/getChar + Guint readBuf; // read buffer + Guint readBufLen; // number of valid bits in readBuf +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Lexer.cc b/rosapps/smartpdf/poppler/poppler/Lexer.cc new file mode 100644 index 00000000000..ee03b3279a4 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Lexer.cc @@ -0,0 +1,566 @@ +//======================================================================== +// +// Lexer.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// Copyright 2006 Krzysztof Kowalczyk (http://blog.kowalczyk.info) +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "Lexer.h" +#include "Error.h" +#include "XRef.h" + +//------------------------------------------------------------------------ + +// A '1' in this array means the character is white space. A '1' or +// '2' means the character ends a name or command. +static char specialChars[256] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx +}; + +#define IS_DIGIT(c) (((c >= '0') && (c <= '9')) ? 1 : 0) + +//------------------------------------------------------------------------ +// Lexer +//------------------------------------------------------------------------ + +Lexer::Lexer(XRef *xrefA, Stream *str) { + Object obj; + + lookCharLastValueCached = LOOK_VALUE_NOT_CACHED; + xref = xrefA; + + buf = NULL; + bufCurPos = NULL; + bufSize = 0; + bufLeft = 0; + curStr.initStream(str); + streams = new Array(xref); + streams->add(curStr.copy(&obj)); + strPtr = 0; + freeArray = gTrue; + curStr.streamReset(); + curStrHasGetBuf = curStr.getStream()->hasGetBuf(); +} + +Lexer::Lexer(XRef *xrefA, Object *obj) { + Object obj2; + + lookCharLastValueCached = LOOK_VALUE_NOT_CACHED; + xref = xrefA; + curStrHasGetBuf = gFalse; + buf = NULL; + bufCurPos = NULL; + bufSize = 0; + bufLeft = 0; + + if (obj->isStream()) { + streams = new Array(xref); + freeArray = gTrue; + streams->add(obj->copy(&obj2)); + } else { + assert(obj->isArray()); + streams = obj->getArray(); + freeArray = gFalse; + } + strPtr = 0; + if (streams->getLength() > 0) { + streams->get(strPtr, &curStr); + curStr.streamReset(); + curStrHasGetBuf = curStr.getStream()->hasGetBuf(); + } +} + +Lexer::~Lexer() { + if (!curStr.isNone()) { + curStr.streamClose(); + curStr.free(); + } + if (freeArray) { + delete streams; + } +} + +GBool Lexer::fillBuf() { + assert(curStrHasGetBuf); + assert(curStr.getStream()->hasGetBuf()); + assert(0 == bufLeft); + + GBool hasData = curStr.getStream()->getBuf(&buf, &bufSize); + if (!hasData) + return gFalse; + assert(bufSize > 0); + bufCurPos = buf; + bufLeft = bufSize; + return gTrue; +} + +void Lexer::nextStream() { + curStr.streamClose(); + curStr.free(); + ++strPtr; + curStrHasGetBuf = gFalse; // important for getChar() while (curStrHasGetBuf) correct break + if (strPtr < streams->getLength()) { + streams->get(strPtr, &curStr); + curStr.streamReset(); + curStrHasGetBuf = curStr.getStream()->hasGetBuf(); + } +} + +Stream *Lexer::getStream() +{ + if (curStr.isNone()) + return (Stream *)NULL; + + if (bufLeft > 0) { + // the caller expects sequential stream but we have buffered some stuff + // so we have to give it back to the stream + assert(curStrHasGetBuf); + curStr.getStream()->ungetBuf(bufLeft); + bufLeft = 0; + lookCharLastValueCached = LOOK_VALUE_NOT_CACHED; + } + return curStr.getStream(); +} + +int Lexer::getPos() { + Guint pos; + + if (curStr.isNone()) + return -1; + + pos = curStr.streamGetPos(); + if (curStrHasGetBuf) { + pos -= bufLeft; + } + + if (LOOK_VALUE_NOT_CACHED != lookCharLastValueCached) + --pos; + return (int)pos; +} + +void Lexer::setPos(Guint pos, int dir) { + if (curStr.isNone()) + return; + curStr.streamSetPos(pos, dir); + lookCharLastValueCached = Lexer::LOOK_VALUE_NOT_CACHED; + bufLeft = 0; +} + +void Lexer::skipChar() { + getChar(); +} + +Object *Lexer::getObj(Object *obj, int objNum) { + char *p; + int c, c2; + GBool comment, neg, done; + int numParen; + int xi; + double xf, scale; + GooString *s; + int n, m; + + // skip whitespace and comments + comment = gFalse; + while (1) { + if ((c = getChar()) == EOF) { + return obj->initEOF(); + } + if (comment) { + if (c == '\r' || c == '\n') + comment = gFalse; + } else if (c == '%') { + comment = gTrue; + } else if (specialChars[c] != 1) { + break; + } + } + + // start reading token + switch (c) { + + // number + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': case '.': + neg = gFalse; + xi = 0; + if (c == '-') { + neg = gTrue; + } else if (c == '.') { + goto doReal; + } else { + xi = c - '0'; + } + while (1) { + c = lookChar(); + if (IS_DIGIT(c)) { + skipChar(); + xi = xi * 10 + (c - '0'); + } else if (c == '.') { + skipChar(); + goto doReal; + } else { + break; + } + } + if (neg) + xi = -xi; + obj->initInt(xi); + break; + doReal: + xf = xi; + scale = 0.1; + while (1) { + c = lookChar(); + if (c == '-') { + // ignore minus signs in the middle of numbers to match + // Adobe's behavior + error(getPos(), "Badly formatted number"); + skipChar(); + continue; + } + if (!IS_DIGIT(c)) { + break; + } + skipChar(); + xf = xf + scale * (c - '0'); + scale *= 0.1; + } + if (neg) + xf = -xf; + obj->initReal(xf); + break; + + // string + case '(': + p = tokBuf; + n = 0; + numParen = 1; + done = gFalse; + s = NULL; + do { + c2 = EOF; + switch (c = getChar()) { + + case EOF: +#if 0 + // This breaks some PDF files, e.g., ones from Photoshop. + case '\r': + case '\n': +#endif + error(getPos(), "Unterminated string"); + done = gTrue; + break; + + case '(': + ++numParen; + c2 = c; + break; + + case ')': + if (--numParen == 0) { + done = gTrue; + } else { + c2 = c; + } + break; + + case '\\': + switch (c = getChar()) { + case 'n': + c2 = '\n'; + break; + case 'r': + c2 = '\r'; + break; + case 't': + c2 = '\t'; + break; + case 'b': + c2 = '\b'; + break; + case 'f': + c2 = '\f'; + break; + case '\\': + case '(': + case ')': + c2 = c; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c2 = c - '0'; + c = lookChar(); + if (c >= '0' && c <= '7') { + skipChar(); + c2 = (c2 << 3) + (c - '0'); + c = lookChar(); + if (c >= '0' && c <= '7') { + skipChar(); + c2 = (c2 << 3) + (c - '0'); + } + } + break; + case '\r': + c = lookChar(); + if (c == '\n') { + skipChar(); + } + break; + case '\n': + break; + case EOF: + error(getPos(), "Unterminated string"); + done = gTrue; + break; + default: + c2 = c; + break; + } + break; + + default: + c2 = c; + break; + } + + if (c2 != EOF) { + if (n == tokBufSize) { + if (!s) + s = new GooString(tokBuf, tokBufSize); + else + s->append(tokBuf, tokBufSize); + p = tokBuf; + n = 0; + + // we are growing see if the document is not malformed and we are growing too much + if (objNum != -1) + { + int newObjNum = xref->getNumEntry(getPos()); + if (newObjNum != objNum) + { + error(getPos(), "Unterminated string"); + done = gTrue; + } + } + } + *p++ = (char)c2; + ++n; + } + } while (!done); + if (!s) + s = new GooString(tokBuf, n); + else + s->append(tokBuf, n); + obj->initString(s); + break; + + // name + case '/': + p = tokBuf; + n = 0; + while ((c = lookChar()) != EOF && !specialChars[c]) { + skipChar(); + if (c == '#') { + c2 = lookChar(); + if (c2 >= '0' && c2 <= '9') { + c = c2 - '0'; + } else if (c2 >= 'A' && c2 <= 'F') { + c = c2 - 'A' + 10; + } else if (c2 >= 'a' && c2 <= 'f') { + c = c2 - 'a' + 10; + } else { + goto notEscChar; + } + skipChar(); + c <<= 4; + c2 = getChar(); + if (c2 >= '0' && c2 <= '9') { + c += c2 - '0'; + } else if (c2 >= 'A' && c2 <= 'F') { + c += c2 - 'A' + 10; + } else if (c2 >= 'a' && c2 <= 'f') { + c += c2 - 'a' + 10; + } else { + error(getPos(), "Illegal digit in hex char in name"); + } + } + notEscChar: + if (++n == tokBufSize) { + error(getPos(), "Name token too long"); + break; + } + *p++ = c; + } + *p = '\0'; + obj->initName(tokBuf); + break; + + // array punctuation + case '[': + case ']': + tokBuf[0] = c; + tokBuf[1] = '\0'; + obj->initCmd(tokBuf); + break; + + // hex string or dict punctuation + case '<': + c = lookChar(); + + // dict punctuation + if (c == '<') { + skipChar(); + tokBuf[0] = tokBuf[1] = '<'; + tokBuf[2] = '\0'; + obj->initCmd(tokBuf); + + // hex string + } else { + p = tokBuf; + m = n = 0; + c2 = 0; + s = NULL; + while (1) { + c = getChar(); + if (c == '>') { + break; + } else if (c == EOF) { + error(getPos(), "Unterminated hex string"); + break; + } else if (specialChars[c] != 1) { + c2 = c2 << 4; + if (c >= '0' && c <= '9') + c2 += c - '0'; + else if (c >= 'A' && c <= 'F') + c2 += c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + c2 += c - 'a' + 10; + else + error(getPos(), "Illegal character <%02x> in hex string", c); + if (++m == 2) { + if (n == tokBufSize) { + if (!s) + s = new GooString(tokBuf, tokBufSize); + else + s->append(tokBuf, tokBufSize); + p = tokBuf; + n = 0; + } + *p++ = (char)c2; + ++n; + c2 = 0; + m = 0; + } + } + } + if (!s) + s = new GooString(tokBuf, n); + else + s->append(tokBuf, n); + if (m == 1) + s->append((char)(c2 << 4)); + obj->initString(s); + } + break; + + // dict punctuation + case '>': + c = lookChar(); + if (c == '>') { + skipChar(); + tokBuf[0] = tokBuf[1] = '>'; + tokBuf[2] = '\0'; + obj->initCmd(tokBuf); + } else { + error(getPos(), "Illegal character '>'"); + obj->initError(); + } + break; + + // error + case ')': + case '{': + case '}': + error(getPos(), "Illegal character '%c'", c); + obj->initError(); + break; + + // command + default: + p = tokBuf; + *p++ = c; + n = 1; + while ((c = lookChar()) != EOF && !specialChars[c]) { + skipChar(); + if (++n == tokBufSize) { + error(getPos(), "Command token too long"); + break; + } + *p++ = c; + } + *p = '\0'; + if (tokBuf[0] == 't' && !strcmp(tokBuf, "true")) { + obj->initBool(gTrue); + } else if (tokBuf[0] == 'f' && !strcmp(tokBuf, "false")) { + obj->initBool(gFalse); + } else if (tokBuf[0] == 'n' && !strcmp(tokBuf, "null")) { + obj->initNull(); + } else { + obj->initCmd(tokBuf); + } + break; + } + + return obj; +} + +void Lexer::skipToNextLine() { + int c; + + while (1) { + c = getChar(); + if (c == EOF || c == '\n') { + return; + } + if (c == '\r') { + if ((c = lookChar()) == '\n') { + skipChar(); + } + return; + } + } +} + +GBool Lexer::isSpace(int c) { + return c >= 0 && c <= 0xff && specialChars[c] == 1; +} diff --git a/rosapps/smartpdf/poppler/poppler/Lexer.h b/rosapps/smartpdf/poppler/poppler/Lexer.h new file mode 100644 index 00000000000..00a6623ee41 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Lexer.h @@ -0,0 +1,130 @@ +//======================================================================== +// +// Lexer.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// Copyright 2006 Krzysztof Kowalczyk (http://blog.kowalczyk.info) +// +//======================================================================== + +#ifndef LEXER_H +#define LEXER_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include "Object.h" +#include "Stream.h" + +class XRef; + +#define tokBufSize 128 // size of token buffer + +//------------------------------------------------------------------------ +// Lexer +//------------------------------------------------------------------------ + +class Lexer { +public: + + // Construct a lexer for a single stream. Deletes the stream when + // lexer is deleted. + Lexer(XRef *xrefA, Stream *str); + + // Construct a lexer for a stream or array of streams (assumes obj + // is either a stream or array of streams). + Lexer(XRef *xrefA, Object *obj); + + // Destructor. + ~Lexer(); + + // Get the next object from the input stream. + Object *getObj(Object *obj, int objNum = -1); + + // Skip to the beginning of the next line in the input stream. + void skipToNextLine(); + + // Skip over one character. + void skipChar(); + + Stream *getStream(); + + // Get current position in file. This is only used for error + // messages, so it returns an int instead of a Guint. + int getPos(); + + // Set position in file. + void setPos(Guint pos, int dir = 0); + + // Returns true if is a whitespace character. + static GBool isSpace(int c); + +private: + + // we really want lookChar() and getChar() to be inlined + int lookChar() { + if (LOOK_VALUE_NOT_CACHED != lookCharLastValueCached) { + return lookCharLastValueCached; + } + lookCharLastValueCached = getChar(); + return lookCharLastValueCached; + } + + int getChar() { + int c; + GBool hasMoreData; + + if (LOOK_VALUE_NOT_CACHED != lookCharLastValueCached) { + c = lookCharLastValueCached; + lookCharLastValueCached = LOOK_VALUE_NOT_CACHED; + assert( (c >= LOOK_VALUE_NOT_CACHED) && (c < 256)); + return c; + } + + while (curStrHasGetBuf) { + if (bufLeft > 0) { + c = *bufCurPos++ & 0xff; + bufLeft--; + return c; + } + hasMoreData = fillBuf(); + if (!hasMoreData) + nextStream(); + } + + c = EOF; + while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) { + nextStream(); + } + return c; + } + + void nextStream(); + GBool fillBuf(); + + Array * streams; // array of input streams + int strPtr; // index of current stream + Object curStr; // current stream + GBool freeArray; // should lexer free the streams array? + char tokBuf[tokBufSize]; // temporary token buffer + XRef * xref; + + // often (e.g. ~30% on PDF Refernce 1.6 pdf file from Adobe site) getChar + // is called right after lookChar. In order to avoid expensive re-doing + // getChar() of underlying stream, we cache the last value found by + // lookChar() in lookCharLastValueCached. A special value + // LOOK_VALUE_NOT_CACHED that should never be part of stream indicates + // that no value was cached + static const int LOOK_VALUE_NOT_CACHED = -3; + int lookCharLastValueCached; + + GBool curStrHasGetBuf; // does current stream support GetBuf() ? + char * buf; + char * bufCurPos; + int bufSize; + int bufLeft; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Link.cc b/rosapps/smartpdf/poppler/poppler/Link.cc new file mode 100644 index 00000000000..61f97286bd9 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Link.cc @@ -0,0 +1,963 @@ +//======================================================================== +// +// Link.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "Error.h" +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Link.h" +#include "Sound.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ +// LinkAction +//------------------------------------------------------------------------ + +LinkAction *LinkAction::parseDest(Object *obj) { + LinkAction *action; + + action = new LinkGoTo(obj); + if (!action->isOk()) { + delete action; + return NULL; + } + return action; +} + +LinkAction *LinkAction::parseAction(Object *obj, GooString *baseURI) { + LinkAction *action; + Object obj2, obj3, obj4; + + if (!obj->isDict()) { + error(-1, "parseAction: Bad annotation action for URI '%s'", + baseURI ? baseURI->getCString() : "NULL"); + return NULL; + } + + obj->dictLookup("S", &obj2); + + // GoTo action + if (obj2.isName("GoTo")) { + obj->dictLookup("D", &obj3); + action = new LinkGoTo(&obj3); + obj3.free(); + + // GoToR action + } else if (obj2.isName("GoToR")) { + obj->dictLookup("F", &obj3); + obj->dictLookup("D", &obj4); + action = new LinkGoToR(&obj3, &obj4); + obj3.free(); + obj4.free(); + + // Launch action + } else if (obj2.isName("Launch")) { + action = new LinkLaunch(obj); + + // URI action + } else if (obj2.isName("URI")) { + obj->dictLookup("URI", &obj3); + action = new LinkURI(&obj3, baseURI); + obj3.free(); + + // Named action + } else if (obj2.isName("Named")) { + obj->dictLookup("N", &obj3); + action = new LinkNamed(&obj3); + obj3.free(); + + // Movie action + } else if (obj2.isName("Movie")) { + obj->dictLookupNF("Annot", &obj3); + obj->dictLookup("T", &obj4); + action = new LinkMovie(&obj3, &obj4); + obj3.free(); + obj4.free(); + + // Sound action + } else if (obj2.isName("Sound")) { + action = new LinkSound(obj); + + // unknown action + } else if (obj2.isName()) { + action = new LinkUnknown(obj2.getNameC()); + + // action is missing or wrong type + } else { + error(-1, "parseAction: Unknown annotation action object: URI = '%s'", + baseURI ? baseURI->getCString() : "NULL"); + action = NULL; + } + + obj2.free(); + + if (action && !action->isOk()) { + delete action; + return NULL; + } + return action; +} + +GooString *LinkAction::getFileSpecName(Object *fileSpecObj) { + GooString *name; + Object obj1; + + name = NULL; + + // string + if (fileSpecObj->isString()) { + name = fileSpecObj->getString()->copy(); + + // dictionary + } else if (fileSpecObj->isDict()) { +#ifdef WIN32 + if (!fileSpecObj->dictLookup("DOS", &obj1)->isString()) { +#else + if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) { +#endif + obj1.free(); + fileSpecObj->dictLookup("F", &obj1); + } + if (obj1.isString()) { + name = obj1.getString()->copy(); + } else { + error(-1, "Illegal file spec in link"); + } + obj1.free(); + + // error + } else { + error(-1, "Illegal file spec in link"); + } + + // system-dependent path manipulation + if (name) { +#ifdef WIN32 + int i, j; + + // "//...." --> "\...." + // "/x/...." --> "x:\...." + // "/server/share/...." --> "\\server\share\...." + // convert escaped slashes to slashes and unescaped slashes to backslashes + i = 0; + if (name->getChar(0) == '/') { + if (name->getLength() >= 2 && name->getChar(1) == '/') { + name->del(0); + i = 0; + } else if (name->getLength() >= 2 && + ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') || + (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) && + (name->getLength() == 2 || name->getChar(2) == '/')) { + name->setChar(0, name->getChar(1)); + name->setChar(1, ':'); + i = 2; + } else { + for (j = 2; j < name->getLength(); ++j) { + if (name->getChar(j-1) != '\\' && + name->getChar(j) == '/') { + break; + } + } + if (j < name->getLength()) { + name->setChar(0, '\\'); + name->insert(0, '\\'); + i = 2; + } + } + } + for (; i < name->getLength(); ++i) { + if (name->getChar(i) == '/') { + name->setChar(i, '\\'); + } else if (name->getChar(i) == '\\' && + i+1 < name->getLength() && + name->getChar(i+1) == '/') { + name->del(i); + } + } +#else + // no manipulation needed for Unix +#endif + } + + return name; +} + +//------------------------------------------------------------------------ +// LinkDest +//------------------------------------------------------------------------ + +LinkDest::LinkDest(Array *a) { + Object obj1, obj2; + + // initialize fields + left = bottom = right = top = zoom = 0; + ok = gFalse; + + // get page + if (a->getLength() < 2) { + error(-1, "Annotation destination array is too short"); + return; + } + a->getNF(0, &obj1); + if (obj1.isInt()) { + pageNum = obj1.getInt() + 1; + pageIsRef = gFalse; + } else if (obj1.isRef()) { + pageRef.num = obj1.getRefNum(); + pageRef.gen = obj1.getRefGen(); + pageIsRef = gTrue; + } else { + error(-1, "Bad annotation destination"); + goto err2; + } + obj1.free(); + + // get destination type + a->get(1, &obj1); + + // XYZ link + if (obj1.isName("XYZ")) { + kind = destXYZ; + if (a->getLength() < 3) { + changeLeft = gFalse; + } else { + a->get(2, &obj2); + if (obj2.isNull()) { + changeLeft = gFalse; + } else if (obj2.isNum()) { + changeLeft = gTrue; + left = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); + } + if (a->getLength() < 4) { + changeTop = gFalse; + } else { + a->get(3, &obj2); + if (obj2.isNull()) { + changeTop = gFalse; + } else if (obj2.isNum()) { + changeTop = gTrue; + top = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); + } + if (a->getLength() < 5) { + changeZoom = gFalse; + } else { + a->get(4, &obj2); + if (obj2.isNull()) { + changeZoom = gFalse; + } else if (obj2.isNum()) { + changeZoom = gTrue; + zoom = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); + } + + // Fit link + } else if (obj1.isName("Fit")) { + if (a->getLength() < 2) { + error(-1, "Annotation destination array is too short"); + goto err2; + } + kind = destFit; + + // FitH link + } else if (obj1.isName("FitH")) { + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); + goto err2; + } + kind = destFitH; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + top = obj2.getNum(); + obj2.free(); + + // FitV link + } else if (obj1.isName("FitV")) { + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); + goto err2; + } + kind = destFitV; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + left = obj2.getNum(); + obj2.free(); + + // FitR link + } else if (obj1.isName("FitR")) { + if (a->getLength() < 6) { + error(-1, "Annotation destination array is too short"); + goto err2; + } + kind = destFitR; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + left = obj2.getNum(); + obj2.free(); + if (!a->get(3, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + bottom = obj2.getNum(); + obj2.free(); + if (!a->get(4, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + right = obj2.getNum(); + obj2.free(); + if (!a->get(5, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + top = obj2.getNum(); + obj2.free(); + + // FitB link + } else if (obj1.isName("FitB")) { + if (a->getLength() < 2) { + error(-1, "Annotation destination array is too short"); + goto err2; + } + kind = destFitB; + + // FitBH link + } else if (obj1.isName("FitBH")) { + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); + goto err2; + } + kind = destFitBH; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + top = obj2.getNum(); + obj2.free(); + + // FitBV link + } else if (obj1.isName("FitBV")) { + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); + goto err2; + } + kind = destFitBV; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + left = obj2.getNum(); + obj2.free(); + + // unknown link kind + } else { + error(-1, "Unknown annotation destination type"); + goto err2; + } + + obj1.free(); + ok = gTrue; + return; + + err1: + obj2.free(); + err2: + obj1.free(); +} + +LinkDest::LinkDest(LinkDest *dest) { + kind = dest->kind; + pageIsRef = dest->pageIsRef; + if (pageIsRef) + pageRef = dest->pageRef; + else + pageNum = dest->pageNum; + left = dest->left; + bottom = dest->bottom; + right = dest->right; + top = dest->top; + zoom = dest->zoom; + changeLeft = dest->changeLeft; + changeTop = dest->changeTop; + changeZoom = dest->changeZoom; + ok = gTrue; +} + +//------------------------------------------------------------------------ +// LinkGoTo +//------------------------------------------------------------------------ + +LinkGoTo::LinkGoTo(Object *destObj) { + dest = NULL; + namedDest = NULL; + + // named destination + if (destObj->isName()) { + namedDest = new UGooString(destObj->getNameC()); + } else if (destObj->isString()) { + namedDest = new UGooString(*destObj->getString()); + + // destination dictionary + } else if (destObj->isArray()) { + dest = new LinkDest(destObj->getArray()); + if (!dest->isOk()) { + delete dest; + dest = NULL; + } + + // error + } else { + error(-1, "Illegal annotation destination"); + } +} + +LinkGoTo::~LinkGoTo() { + if (dest) + delete dest; + if (namedDest) + delete namedDest; +} + +//------------------------------------------------------------------------ +// LinkGoToR +//------------------------------------------------------------------------ + +LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) { + dest = NULL; + namedDest = NULL; + + // get file name + fileName = getFileSpecName(fileSpecObj); + + // named destination + if (destObj->isName()) { + namedDest = new UGooString(destObj->getNameC()); + } else if (destObj->isString()) { + namedDest = new UGooString(*destObj->getString()); + + // destination dictionary + } else if (destObj->isArray()) { + dest = new LinkDest(destObj->getArray()); + if (!dest->isOk()) { + delete dest; + dest = NULL; + } + + // error + } else { + error(-1, "Illegal annotation destination"); + } +} + +LinkGoToR::~LinkGoToR() { + if (fileName) + delete fileName; + if (dest) + delete dest; + if (namedDest) + delete namedDest; +} + + +//------------------------------------------------------------------------ +// LinkLaunch +//------------------------------------------------------------------------ + +LinkLaunch::LinkLaunch(Object *actionObj) { + Object obj1, obj2; + + fileName = NULL; + params = NULL; + + if (actionObj->isDict()) { + if (!actionObj->dictLookup("F", &obj1)->isNull()) { + fileName = getFileSpecName(&obj1); + } else { + obj1.free(); +#ifdef WIN32 + if (actionObj->dictLookup("Win", &obj1)->isDict()) { + obj1.dictLookup("F", &obj2); + fileName = getFileSpecName(&obj2); + obj2.free(); + if (obj1.dictLookup("P", &obj2)->isString()) { + params = obj2.getString()->copy(); + } + obj2.free(); + } else { + error(-1, "Bad launch-type link action"); + } +#else + //~ This hasn't been defined by Adobe yet, so assume it looks + //~ just like the Win dictionary until they say otherwise. + if (actionObj->dictLookup("Unix", &obj1)->isDict()) { + obj1.dictLookup("F", &obj2); + fileName = getFileSpecName(&obj2); + obj2.free(); + if (obj1.dictLookup("P", &obj2)->isString()) { + params = obj2.getString()->copy(); + } + obj2.free(); + } else { + error(-1, "Bad launch-type link action"); + } +#endif + } + obj1.free(); + } +} + +LinkLaunch::~LinkLaunch() { + if (fileName) + delete fileName; + if (params) + delete params; +} + +//------------------------------------------------------------------------ +// LinkURI +//------------------------------------------------------------------------ + +LinkURI::LinkURI(Object *uriObj, GooString *baseURI) { + GooString *uri2; + int n; + char c; + + uri = NULL; + if (uriObj->isString()) { + uri2 = uriObj->getString()->copy(); + if (baseURI && baseURI->getLength() > 0) { + n = strcspn(uri2->getCString(), "/:"); + if (n == uri2->getLength() || uri2->getChar(n) == '/') { + uri = baseURI->copy(); + c = uri->getChar(uri->getLength() - 1); + if (c == '/' || c == '?') { + if (uri2->getChar(0) == '/') { + uri2->del(0); + } + } else { + if (uri2->getChar(0) != '/') { + uri->append('/'); + } + } + uri->append(uri2); + delete uri2; + } else { + uri = uri2; + } + } else { + uri = uri2; + } + } else { + error(-1, "Illegal URI-type link"); + } +} + +LinkURI::~LinkURI() { + if (uri) + delete uri; +} + +//------------------------------------------------------------------------ +// LinkNamed +//------------------------------------------------------------------------ + +LinkNamed::LinkNamed(Object *nameObj) { + name = NULL; + if (nameObj->isName()) { + name = new GooString(nameObj->getName()); + } +} + +LinkNamed::~LinkNamed() { + if (name) { + delete name; + } +} + +//------------------------------------------------------------------------ +// LinkMovie +//------------------------------------------------------------------------ + +LinkMovie::LinkMovie(Object *annotObj, Object *titleObj) { + annotRef.num = -1; + title = NULL; + if (annotObj->isRef()) { + annotRef = annotObj->getRef(); + } else if (titleObj->isString()) { + title = titleObj->getString()->copy(); + } else { + error(-1, "Movie action is missing both the Annot and T keys"); + } +} + +LinkMovie::~LinkMovie() { + if (title) { + delete title; + } +} + +//------------------------------------------------------------------------ +// LinkSound +//------------------------------------------------------------------------ + +LinkSound::LinkSound(Object *soundObj) { + volume = 1.0; + sync = gFalse; + repeat = gFalse; + mix = gFalse; + sound = NULL; + if (soundObj->isDict()) + { + Object tmp; + // volume + soundObj->dictLookup("Volume", &tmp); + if (tmp.isNum()) { + volume = tmp.getNum(); + } + tmp.free(); + // sync + soundObj->dictLookup("Synchronous", &tmp); + if (tmp.isBool()) { + sync = tmp.getBool(); + } + tmp.free(); + // repeat + soundObj->dictLookup("Repeat", &tmp); + if (tmp.isBool()) { + repeat = tmp.getBool(); + } + tmp.free(); + // mix + soundObj->dictLookup("Mix", &tmp); + if (tmp.isBool()) { + mix = tmp.getBool(); + } + tmp.free(); + // 'Sound' object + soundObj->dictLookup("Sound", &tmp); + sound = Sound::parseSound(&tmp); + tmp.free(); + } +} + +LinkSound::~LinkSound() { + delete sound; +} + +//------------------------------------------------------------------------ +// LinkUnknown +//------------------------------------------------------------------------ + +LinkUnknown::LinkUnknown(char *actionA) { + action = new GooString(actionA); +} + +LinkUnknown::~LinkUnknown() { + delete action; +} + +//------------------------------------------------------------------------ +// LinkBorderStyle +//------------------------------------------------------------------------ + +LinkBorderStyle::LinkBorderStyle(LinkBorderType typeA, double widthA, + double *dashA, int dashLengthA, + double rA, double gA, double bA) { + type = typeA; + width = widthA; + dash = dashA; + dashLength = dashLengthA; + r = rA; + g = gA; + b = bA; +} + +LinkBorderStyle::~LinkBorderStyle() { + if (dash) { + gfree(dash); + } +} + +//------------------------------------------------------------------------ +// Link +//------------------------------------------------------------------------ + +Link::Link(Dict *dict, GooString *baseURI) { + Object obj1, obj2, obj3; + LinkBorderType borderType; + double borderWidth; + double *borderDash; + int borderDashLength; + double borderR, borderG, borderB; + double t; + int i; + + borderStyle = NULL; + action = NULL; + ok = gFalse; + + // get rectangle + if (!dict->lookup("Rect", &obj1)->isArray()) { + error(-1, "Annotation rectangle is wrong type"); + goto err2; + } + if (!obj1.arrayGet(0, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + x1 = obj2.getNum(); + obj2.free(); + if (!obj1.arrayGet(1, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + y1 = obj2.getNum(); + obj2.free(); + if (!obj1.arrayGet(2, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + x2 = obj2.getNum(); + obj2.free(); + if (!obj1.arrayGet(3, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + y2 = obj2.getNum(); + obj2.free(); + obj1.free(); + if (x1 > x2) { + t = x1; + x1 = x2; + x2 = t; + } + if (y1 > y2) { + t = y1; + y1 = y2; + y2 = t; + } + + // get the border style info + borderType = linkBorderSolid; + borderWidth = 1; + borderDash = NULL; + borderDashLength = 0; + borderR = 0; + borderG = 0; + borderB = 1; + if (dict->lookup("BS", &obj1)->isDict()) { + if (obj1.dictLookup("S", &obj2)->isName()) { + if (obj2.isName("S")) { + borderType = linkBorderSolid; + } else if (obj2.isName("D")) { + borderType = linkBorderDashed; + } else if (obj2.isName("B")) { + borderType = linkBorderEmbossed; + } else if (obj2.isName("I")) { + borderType = linkBorderEngraved; + } else if (obj2.isName("U")) { + borderType = linkBorderUnderlined; + } + } + obj2.free(); + if (obj1.dictLookup("W", &obj2)->isNum()) { + borderWidth = obj2.getNum(); + } + obj2.free(); + if (obj1.dictLookup("D", &obj2)->isArray()) { + borderDashLength = obj2.arrayGetLength(); + borderDash = (double *)gmallocn(borderDashLength, sizeof(double)); + for (i = 0; i < borderDashLength; ++i) { + if (obj2.arrayGet(i, &obj3)->isNum()) { + borderDash[i] = obj3.getNum(); + } else { + borderDash[i] = 1; + } + obj3.free(); + } + } + obj2.free(); + } else { + obj1.free(); + if (dict->lookup("Border", &obj1)->isArray()) { + if (obj1.arrayGetLength() >= 3) { + if (obj1.arrayGet(2, &obj2)->isNum()) { + borderWidth = obj2.getNum(); + } + obj2.free(); + if (obj1.arrayGetLength() >= 4) { + if (obj1.arrayGet(3, &obj2)->isArray()) { + borderType = linkBorderDashed; + borderDashLength = obj2.arrayGetLength(); + borderDash = (double *)gmallocn(borderDashLength, sizeof(double)); + for (i = 0; i < borderDashLength; ++i) { + if (obj2.arrayGet(i, &obj3)->isNum()) { + borderDash[i] = obj3.getNum(); + } else { + borderDash[i] = 1; + } + obj3.free(); + } + } else { + // Adobe draws no border at all if the last element is of + // the wrong type. + borderWidth = 0; + } + obj2.free(); + } + } + } + } + obj1.free(); + if (dict->lookup("C", &obj1)->isArray() && obj1.arrayGetLength() == 3) { + if (obj1.arrayGet(0, &obj2)->isNum()) { + borderR = obj2.getNum(); + } + obj1.free(); + if (obj1.arrayGet(1, &obj2)->isNum()) { + borderG = obj2.getNum(); + } + obj1.free(); + if (obj1.arrayGet(2, &obj2)->isNum()) { + borderB = obj2.getNum(); + } + obj1.free(); + } + obj1.free(); + borderStyle = new LinkBorderStyle(borderType, borderWidth, + borderDash, borderDashLength, + borderR, borderG, borderB); + + // look for destination + if (!dict->lookup("Dest", &obj1)->isNull()) { + action = LinkAction::parseDest(&obj1); + + // look for action + } else { + obj1.free(); + if (dict->lookup("A", &obj1)->isDict()) { + action = LinkAction::parseAction(&obj1, baseURI); + } + } + obj1.free(); + + // check for bad action + if (action) { + ok = gTrue; + } + + return; + + err1: + obj2.free(); + err2: + obj1.free(); +} + +Link::~Link() { + if (borderStyle) { + delete borderStyle; + } + if (action) { + delete action; + } +} + +//------------------------------------------------------------------------ +// Links +//------------------------------------------------------------------------ + +Links::Links(Object *annots, GooString *baseURI) { + Link *link; + Object obj1, obj2; + int size; + int i; + + links = NULL; + size = 0; + numLinks = 0; + + if (annots->isArray()) { + for (i = 0; i < annots->arrayGetLength(); ++i) { + if (annots->arrayGet(i, &obj1)->isDict()) { + if (obj1.dictLookup("Subtype", &obj2)->isName("Link")) { + link = new Link(obj1.getDict(), baseURI); + if (link->isOk()) { + if (numLinks >= size) { + size += 16; + links = (Link **)greallocn(links, size, sizeof(Link *)); + } + links[numLinks++] = link; + } else { + delete link; + } + } + obj2.free(); + } + obj1.free(); + } + } +} + +Links::~Links() { + int i; + + for (i = 0; i < numLinks; ++i) + delete links[i]; + gfree(links); +} + +LinkAction *Links::find(double x, double y) const { + int i; + + for (i = numLinks - 1; i >= 0; --i) { + if (links[i]->inRect(x, y)) { + return links[i]->getAction(); + } + } + return NULL; +} + +GBool Links::onLink(double x, double y) const { + int i; + + for (i = 0; i < numLinks; ++i) { + if (links[i]->inRect(x, y)) + return gTrue; + } + return gFalse; +} diff --git a/rosapps/smartpdf/poppler/poppler/Link.h b/rosapps/smartpdf/poppler/poppler/Link.h new file mode 100644 index 00000000000..ff334833607 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Link.h @@ -0,0 +1,440 @@ +//======================================================================== +// +// Link.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef LINK_H +#define LINK_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "Object.h" + +class GooString; +class UGooString; +class Array; +class Dict; +class Sound; + +//------------------------------------------------------------------------ +// LinkAction +//------------------------------------------------------------------------ + +enum LinkActionKind { + actionGoTo, // go to destination + actionGoToR, // go to destination in new file + actionLaunch, // launch app (or open document) + actionURI, // URI + actionNamed, // named action + actionMovie, // movie action + actionSound, // sound action + actionUnknown // anything else +}; + +class LinkAction { +public: + + // Destructor. + virtual ~LinkAction() {} + + // Was the LinkAction created successfully? + virtual GBool isOk() = 0; + + // Check link action type. + virtual LinkActionKind getKind() = 0; + + // Parse a destination (old-style action) name, string, or array. + static LinkAction *parseDest(Object *obj); + + // Parse an action dictionary. + static LinkAction *parseAction(Object *obj, GooString *baseURI = NULL); + + // Extract a file name from a file specification (string or + // dictionary). + static GooString *getFileSpecName(Object *fileSpecObj); +}; + +//------------------------------------------------------------------------ +// LinkDest +//------------------------------------------------------------------------ + +enum LinkDestKind { + destXYZ, + destFit, + destFitH, + destFitV, + destFitR, + destFitB, + destFitBH, + destFitBV +}; + +class LinkDest { +public: + + // Build a LinkDest from the array. + LinkDest(Array *a); + + // Copy a LinkDest. + LinkDest *copy() { return new LinkDest(this); } + + // Was the LinkDest created successfully? + GBool isOk() { return ok; } + + // Accessors. + LinkDestKind getKind() { return kind; } + GBool isPageRef() { return pageIsRef; } + int getPageNum() { return pageNum; } + Ref getPageRef() { return pageRef; } + double getLeft() { return left; } + double getBottom() { return bottom; } + double getRight() { return right; } + double getTop() { return top; } + double getZoom() { return zoom; } + GBool getChangeLeft() { return changeLeft; } + GBool getChangeTop() { return changeTop; } + GBool getChangeZoom() { return changeZoom; } + +private: + + LinkDestKind kind; // destination type + GBool pageIsRef; // is the page a reference or number? + union { + Ref pageRef; // reference to page + int pageNum; // one-relative page number + }; + double left, bottom; // position + double right, top; + double zoom; // zoom factor + GBool changeLeft, changeTop; // for destXYZ links, which position + GBool changeZoom; // components to change + GBool ok; // set if created successfully + + LinkDest(LinkDest *dest); +}; + +//------------------------------------------------------------------------ +// LinkGoTo +//------------------------------------------------------------------------ + +class LinkGoTo: public LinkAction { +public: + + // Build a LinkGoTo from a destination (dictionary, name, or string). + LinkGoTo(Object *destObj); + + // Destructor. + virtual ~LinkGoTo(); + + // Was the LinkGoTo created successfully? + virtual GBool isOk() { return dest || namedDest; } + + // Accessors. + virtual LinkActionKind getKind() { return actionGoTo; } + LinkDest *getDest() { return dest; } + UGooString *getNamedDest() { return namedDest; } + +private: + + LinkDest *dest; // regular destination (NULL for remote + // link with bad destination) + UGooString *namedDest; // named destination (only one of dest and + // and namedDest may be non-NULL) +}; + +//------------------------------------------------------------------------ +// LinkGoToR +//------------------------------------------------------------------------ + +class LinkGoToR: public LinkAction { +public: + + // Build a LinkGoToR from a file spec (dictionary) and destination + // (dictionary, name, or string). + LinkGoToR(Object *fileSpecObj, Object *destObj); + + // Destructor. + virtual ~LinkGoToR(); + + // Was the LinkGoToR created successfully? + virtual GBool isOk() { return fileName && (dest || namedDest); } + + // Accessors. + virtual LinkActionKind getKind() { return actionGoToR; } + GooString *getFileName() { return fileName; } + LinkDest *getDest() { return dest; } + UGooString *getNamedDest() { return namedDest; } + +private: + + GooString *fileName; // file name + LinkDest *dest; // regular destination (NULL for remote + // link with bad destination) + UGooString *namedDest; // named destination (only one of dest and + // and namedDest may be non-NULL) +}; + +//------------------------------------------------------------------------ +// LinkLaunch +//------------------------------------------------------------------------ + +class LinkLaunch: public LinkAction { +public: + + // Build a LinkLaunch from an action dictionary. + LinkLaunch(Object *actionObj); + + // Destructor. + virtual ~LinkLaunch(); + + // Was the LinkLaunch created successfully? + virtual GBool isOk() { return fileName != NULL; } + + // Accessors. + virtual LinkActionKind getKind() { return actionLaunch; } + GooString *getFileName() { return fileName; } + GooString *getParams() { return params; } + +private: + + GooString *fileName; // file name + GooString *params; // parameters +}; + +//------------------------------------------------------------------------ +// LinkURI +//------------------------------------------------------------------------ + +class LinkURI: public LinkAction { +public: + + // Build a LinkURI given the URI (string) and base URI. + LinkURI(Object *uriObj, GooString *baseURI); + + // Destructor. + virtual ~LinkURI(); + + // Was the LinkURI created successfully? + virtual GBool isOk() { return uri != NULL; } + + // Accessors. + virtual LinkActionKind getKind() { return actionURI; } + GooString *getURI() { return uri; } + +private: + + GooString *uri; // the URI +}; + +//------------------------------------------------------------------------ +// LinkNamed +//------------------------------------------------------------------------ + +class LinkNamed: public LinkAction { +public: + + // Build a LinkNamed given the action name. + LinkNamed(Object *nameObj); + + virtual ~LinkNamed(); + + virtual GBool isOk() { return name != NULL; } + + virtual LinkActionKind getKind() { return actionNamed; } + GooString *getName() { return name; } + +private: + + GooString *name; +}; + +//------------------------------------------------------------------------ +// LinkMovie +//------------------------------------------------------------------------ + +class LinkMovie: public LinkAction { +public: + + LinkMovie(Object *annotObj, Object *titleObj); + + virtual ~LinkMovie(); + + virtual GBool isOk() { return annotRef.num >= 0 || title != NULL; } + + virtual LinkActionKind getKind() { return actionMovie; } + GBool hasAnnotRef() { return annotRef.num >= 0; } + Ref *getAnnotRef() { return &annotRef; } + GooString *getTitle() { return title; } + +private: + + Ref annotRef; + GooString *title; +}; + +//------------------------------------------------------------------------ +// LinkSound +//------------------------------------------------------------------------ + +class LinkSound: public LinkAction { +public: + + LinkSound(Object *soundObj); + + virtual ~LinkSound(); + + virtual GBool isOk() { return sound != NULL; } + + virtual LinkActionKind getKind() { return actionSound; } + + double getVolume() { return volume; } + GBool getSynchronous() { return sync; } + GBool getRepeat() { return repeat; } + GBool getMix() { return mix; } + Sound *getSound() { return sound; } + +private: + + double volume; + GBool sync; + GBool repeat; + GBool mix; + Sound *sound; +}; + +//------------------------------------------------------------------------ +// LinkUnknown +//------------------------------------------------------------------------ + +class LinkUnknown: public LinkAction { +public: + + // Build a LinkUnknown with the specified action type. + LinkUnknown(char *actionA); + + // Destructor. + virtual ~LinkUnknown(); + + // Was the LinkUnknown create successfully? + virtual GBool isOk() { return action != NULL; } + + // Accessors. + virtual LinkActionKind getKind() { return actionUnknown; } + GooString *getAction() { return action; } + +private: + + GooString *action; // action subtype +}; + +//------------------------------------------------------------------------ +// LinkBorderStyle +//------------------------------------------------------------------------ + +enum LinkBorderType { + linkBorderSolid, + linkBorderDashed, + linkBorderEmbossed, + linkBorderEngraved, + linkBorderUnderlined +}; + +class LinkBorderStyle { +public: + + LinkBorderStyle(LinkBorderType typeA, double widthA, + double *dashA, int dashLengthA, + double rA, double gA, double bA); + ~LinkBorderStyle(); + + LinkBorderType getType() { return type; } + double getWidth() { return width; } + void getDash(double **dashA, int *dashLengthA) + { *dashA = dash; *dashLengthA = dashLength; } + void getColor(double *rA, double *gA, double *bA) + { *rA = r; *gA = g; *bA = b; } + +private: + + LinkBorderType type; + double width; + double *dash; + int dashLength; + double r, g, b; +}; + +//------------------------------------------------------------------------ +// Link +//------------------------------------------------------------------------ + +class Link { +public: + + // Construct a link, given its dictionary. + Link(Dict *dict, GooString *baseURI); + + // Destructor. + ~Link(); + + // Was the link created successfully? + GBool isOk() { return ok; } + + // Check if point is inside the link rectangle. + GBool inRect(double x, double y) + { return x1 <= x && x <= x2 && y1 <= y && y <= y2; } + + // Get action. + LinkAction *getAction() { return action; } + + // Get the link rectangle. + void getRect(double *xa1, double *ya1, double *xa2, double *ya2) + { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; } + + // Get the border style info. + LinkBorderStyle *getBorderStyle() { return borderStyle; } + +private: + + double x1, y1; // lower left corner + double x2, y2; // upper right corner + LinkBorderStyle *borderStyle; // border style + LinkAction *action; // action + GBool ok; // is link valid? +}; + +//------------------------------------------------------------------------ +// Links +//------------------------------------------------------------------------ + +class Links { +public: + + // Extract links from array of annotations. + Links(Object *annots, GooString *baseURI); + + // Destructor. + ~Links(); + + // Iterate through list of links. + int getNumLinks() const { return numLinks; } + Link *getLink(int i) const { return links[i]; } + + // If point , is in a link, return the associated action; + // else return NULL. + LinkAction *find(double x, double y) const; + + // Return true if , is in a link. + GBool onLink(double x, double y) const; + +private: + + Link **links; + int numLinks; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Makefile.am b/rosapps/smartpdf/poppler/poppler/Makefile.am new file mode 100644 index 00000000000..edece025d46 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Makefile.am @@ -0,0 +1,215 @@ +if BUILD_SPLASH_OUTPUT + +splash_sources = \ + SplashOutputDev.cc + +splash_headers = \ + SplashOutputDev.h + +splash_includes = \ + $(SPLASH_CFLAGS) + +splash_libs = \ + $(SPLASH_LIBS) \ + $(top_builddir)/splash/libsplash.la + +endif + +if BUILD_POPPLER_QT4 + +poppler_arthur = libpoppler-arthur.la + +libpoppler_arthur_la_SOURCES = \ + ArthurOutputDev.h \ + ArthurOutputDev.cc + +arthur_includes = \ + $(POPPLER_QT4_CXXFLAGS) + +arthur_libs = \ + $(POPPLER_QT4_LIBS) + +endif + + +if BUILD_CAIRO_OUTPUT + +poppler_cairo = libpoppler-cairo.la + +cairo_includes = \ + $(CAIRO_CFLAGS) + +cairo_libs = \ + $(CAIRO_LIBS) + +libpoppler_cairo_la_SOURCES = \ + CairoFontEngine.cc \ + CairoFontEngine.h \ + CairoOutputDev.cc \ + CairoOutputDev.h + +endif + +if BUILD_LIBJPEG + +libjpeg_sources = \ + DCTStream.h \ + DCTStream.cc + +libjpeg_libs = \ + $(LIBJPEG_LIBS) + +endif + +if BUILD_ZLIB + +zlib_sources = \ + FlateStream.h \ + FlateStream.cc + +zlib_libs = \ + $(ZLIB_LIBS) + +endif + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/goo \ + $(splash_includes) \ + $(cairo_includes) \ + $(arthur_includes) \ + $(FREETYPE_CFLAGS) \ + $(FONTCONFIG_CFLAGS) + +lib_LTLIBRARIES = libpoppler.la + +noinst_LTLIBRARIES = $(poppler_cairo) \ + $(poppler_arthur) + +libpoppler_la_LIBADD = \ + $(top_builddir)/goo/libgoo.la \ + $(top_builddir)/fofi/libfofi.la \ + $(splash_libs) \ + $(cairo_libs) \ + $(libjpeg_libs) \ + $(zlib_libs) \ + $(FREETYPE_LIBS) \ + $(FONTCONFIG_LIBS) + +libpoppler_la_LDFLAGS = -version-info 1:0:0 + +if ENABLE_XPDF_HEADERS + +poppler_includedir = $(includedir)/poppler +poppler_include_HEADERS = \ + $(splash_headers) \ + Annot.h \ + Array.h \ + BaseFile.h \ + BuiltinFont.h \ + BuiltinFontTables.h \ + Catalog.h \ + CharCodeToUnicode.h \ + CMap.h \ + Decrypt.h \ + Dict.h \ + Error.h \ + FontEncodingTables.h \ + FontInfo.h \ + Function.cc \ + Function.h \ + Gfx.h \ + GfxFont.h \ + GfxState.h \ + GlobalParams.h \ + JArithmeticDecoder.h \ + JBIG2Stream.h \ + JPXStream.h \ + Lexer.h \ + Link.h \ + NameToCharCode.h \ + Object.h \ + Outline.h \ + OutputDev.h \ + Page.h \ + Parser.h \ + PDFDoc.h \ + PDFDocEncoding.h \ + ProfileData.h \ + PSTokenizer.h \ + Stream-CCITT.h \ + Stream.h \ + UnicodeMap.h \ + UnicodeMapTables.h \ + UnicodeTypeTable.h \ + UnicodeCClassTables.h \ + UnicodeCompTables.h \ + UnicodeDecompTables.h \ + XRef.h \ + CharTypes.h \ + CompactFontTables.h \ + ErrorCodes.h \ + NameToUnicodeTable.h \ + PSOutputDev.h \ + TextOutputDev.h \ + SecurityHandler.h \ + UGooString.h \ + UTF8.h \ + XpdfPluginAPI.h \ + Sound.h \ + poppler-config.h + +endif + +libpoppler_la_SOURCES = \ + $(splash_sources) \ + $(cairo_sources) \ + $(arthur_sources) \ + $(libjpeg_sources) \ + $(zlib_sources) \ + Annot.cc \ + Array.cc \ + BuiltinFont.cc \ + BuiltinFontTables.cc \ + Catalog.cc \ + CharCodeToUnicode.cc \ + CMap.cc \ + Decrypt.cc \ + Dict.cc \ + Error.cc \ + FontEncodingTables.cc \ + FontInfo.cc \ + Function.cc \ + Gfx.cc \ + GfxFont.cc \ + GfxState.cc \ + GlobalParams.cc \ + JArithmeticDecoder.cc \ + JBIG2Stream.cc \ + JPXStream.cc \ + Lexer.cc \ + Link.cc \ + NameToCharCode.cc \ + Object.cc \ + Outline.cc \ + OutputDev.cc \ + Page.cc \ + Parser.cc \ + PDFDoc.cc \ + PDFDocEncoding.cc \ + ProfileData.cc \ + PSTokenizer.cc \ + Stream.cc \ + UnicodeMap.cc \ + UnicodeTypeTable.cc \ + XRef.cc \ + PSOutputDev.cc \ + TextOutputDev.cc \ + PageLabelInfo.h \ + PageLabelInfo.cc \ + SecurityHandler.cc \ + UGooString.cc \ + Sound.cc \ + XpdfPluginAPI.cc + +EXTRA_DIST = gen-unicode-tables.py diff --git a/rosapps/smartpdf/poppler/poppler/NameToCharCode.cc b/rosapps/smartpdf/poppler/poppler/NameToCharCode.cc new file mode 100644 index 00000000000..efe1c4de0bd --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/NameToCharCode.cc @@ -0,0 +1,116 @@ +//======================================================================== +// +// NameToCharCode.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "NameToCharCode.h" + +//------------------------------------------------------------------------ + +struct NameToCharCodeEntry { + char *name; + CharCode c; +}; + +//------------------------------------------------------------------------ + +NameToCharCode::NameToCharCode() { + int i; + + size = 31; + len = 0; + tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); + for (i = 0; i < size; ++i) { + tab[i].name = NULL; + } +} + +NameToCharCode::~NameToCharCode() { + int i; + + for (i = 0; i < size; ++i) { + if (tab[i].name) { + gfree(tab[i].name); + } + } + gfree(tab); +} + +void NameToCharCode::add(char *name, CharCode c) { + NameToCharCodeEntry *oldTab; + int h, i, oldSize; + + // expand the table if necessary + if (len >= size / 2) { + oldSize = size; + oldTab = tab; + size = 2*size + 1; + tab = (NameToCharCodeEntry *)gmallocn(size, sizeof(NameToCharCodeEntry)); + for (h = 0; h < size; ++h) { + tab[h].name = NULL; + } + for (i = 0; i < oldSize; ++i) { + if (oldTab[i].name) { + h = hash(oldTab[i].name); + while (tab[h].name) { + if (++h == size) { + h = 0; + } + } + tab[h] = oldTab[i]; + } + } + gfree(oldTab); + } + + // add the new name + h = hash(name); + while (tab[h].name && strcmp(tab[h].name, name)) { + if (++h == size) { + h = 0; + } + } + if (!tab[h].name) { + tab[h].name = copyString(name); + } + tab[h].c = c; + + ++len; +} + +CharCode NameToCharCode::lookup(char *name) { + int h; + + h = hash(name); + while (tab[h].name) { + if (!strcmp(tab[h].name, name)) { + return tab[h].c; + } + if (++h == size) { + h = 0; + } + } + return 0; +} + +int NameToCharCode::hash(char *name) { + char *p; + unsigned int h; + + h = 0; + for (p = name; *p; ++p) { + h = 17 * h + (int)(*p & 0xff); + } + return (int)(h % size); +} diff --git a/rosapps/smartpdf/poppler/poppler/NameToCharCode.h b/rosapps/smartpdf/poppler/poppler/NameToCharCode.h new file mode 100644 index 00000000000..bc57c3736c1 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/NameToCharCode.h @@ -0,0 +1,40 @@ +//======================================================================== +// +// NameToCharCode.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef NAMETOCHARCODE_H +#define NAMETOCHARCODE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "CharTypes.h" + +struct NameToCharCodeEntry; + +//------------------------------------------------------------------------ + +class NameToCharCode { +public: + + NameToCharCode(); + ~NameToCharCode(); + + void add(char *name, CharCode c); + CharCode lookup(char *name); + +private: + + int hash(char *name); + + NameToCharCodeEntry *tab; + int size; + int len; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/NameToUnicodeTable.h b/rosapps/smartpdf/poppler/poppler/NameToUnicodeTable.h new file mode 100644 index 00000000000..0b1812c0c48 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/NameToUnicodeTable.h @@ -0,0 +1,1097 @@ +//======================================================================== +// +// NameToUnicodeTable.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +static struct { + Unicode u; + char *name; +} nameToUnicodeTab[] = { + {0x0021, "!"}, + {0x0023, "#"}, + {0x0024, "$"}, + {0x0025, "%"}, + {0x0026, "&"}, + {0x0027, "'"}, + {0x0028, "("}, + {0x0029, ")"}, + {0x002a, "*"}, + {0x002b, "+"}, + {0x002c, ","}, + {0x002d, "-"}, + {0x002e, "."}, + {0x002f, "/"}, + {0x0030, "0"}, + {0x0031, "1"}, + {0x0032, "2"}, + {0x0033, "3"}, + {0x0034, "4"}, + {0x0035, "5"}, + {0x0036, "6"}, + {0x0037, "7"}, + {0x0038, "8"}, + {0x0039, "9"}, + {0x003a, ":"}, + {0x003b, ";"}, + {0x003c, "<"}, + {0x003d, "="}, + {0x003e, ">"}, + {0x003f, "?"}, + {0x0040, "@"}, + {0x0041, "A"}, + {0x00c6, "AE"}, + {0x01fc, "AEacute"}, + {0xf7e6, "AEsmall"}, + {0x00c1, "Aacute"}, + {0xf7e1, "Aacutesmall"}, + {0x0102, "Abreve"}, + {0x00c2, "Acircumflex"}, + {0xf7e2, "Acircumflexsmall"}, + {0xf6c9, "Acute"}, + {0xf7b4, "Acutesmall"}, + {0x00c4, "Adieresis"}, + {0xf7e4, "Adieresissmall"}, + {0x00c0, "Agrave"}, + {0xf7e0, "Agravesmall"}, + {0x0391, "Alpha"}, + {0x0386, "Alphatonos"}, + {0x0100, "Amacron"}, + {0x0104, "Aogonek"}, + {0x00c5, "Aring"}, + {0x01fa, "Aringacute"}, + {0xf7e5, "Aringsmall"}, + {0xf761, "Asmall"}, + {0x00c3, "Atilde"}, + {0xf7e3, "Atildesmall"}, + {0x0042, "B"}, + {0x0392, "Beta"}, + {0xf6f4, "Brevesmall"}, + {0xf762, "Bsmall"}, + {0x0043, "C"}, + {0x0106, "Cacute"}, + {0xf6ca, "Caron"}, + {0xf6f5, "Caronsmall"}, + {0x010c, "Ccaron"}, + {0x00c7, "Ccedilla"}, + {0xf7e7, "Ccedillasmall"}, + {0x0108, "Ccircumflex"}, + {0x010a, "Cdotaccent"}, + {0xf7b8, "Cedillasmall"}, + {0x03a7, "Chi"}, + {0xf6f6, "Circumflexsmall"}, + {0xf763, "Csmall"}, + {0x0044, "D"}, + {0x010e, "Dcaron"}, + {0x0110, "Dcroat"}, + {0x2206, "Delta"}, + {0xf6cb, "Dieresis"}, + {0xf6cc, "DieresisAcute"}, + {0xf6cd, "DieresisGrave"}, + {0xf7a8, "Dieresissmall"}, + {0xf6f7, "Dotaccentsmall"}, + {0xf764, "Dsmall"}, + {0x0045, "E"}, + {0x00c9, "Eacute"}, + {0xf7e9, "Eacutesmall"}, + {0x0114, "Ebreve"}, + {0x011a, "Ecaron"}, + {0x00ca, "Ecircumflex"}, + {0xf7ea, "Ecircumflexsmall"}, + {0x00cb, "Edieresis"}, + {0xf7eb, "Edieresissmall"}, + {0x0116, "Edotaccent"}, + {0x00c8, "Egrave"}, + {0xf7e8, "Egravesmall"}, + {0x0112, "Emacron"}, + {0x014a, "Eng"}, + {0x0118, "Eogonek"}, + {0x0395, "Epsilon"}, + {0x0388, "Epsilontonos"}, + {0xf765, "Esmall"}, + {0x0397, "Eta"}, + {0x0389, "Etatonos"}, + {0x00d0, "Eth"}, + {0xf7f0, "Ethsmall"}, + {0x20ac, "Euro"}, + {0x0046, "F"}, + {0xf766, "Fsmall"}, + {0x0047, "G"}, + {0x0393, "Gamma"}, + {0x011e, "Gbreve"}, + {0x01e6, "Gcaron"}, + {0x011c, "Gcircumflex"}, + {0x0122, "Gcommaaccent"}, + {0x0120, "Gdotaccent"}, + {0xf6ce, "Grave"}, + {0xf760, "Gravesmall"}, + {0xf767, "Gsmall"}, + {0x0048, "H"}, + {0x25cf, "H18533"}, + {0x25aa, "H18543"}, + {0x25ab, "H18551"}, + {0x25a1, "H22073"}, + {0x0126, "Hbar"}, + {0x0124, "Hcircumflex"}, + {0xf768, "Hsmall"}, + {0xf6cf, "Hungarumlaut"}, + {0xf6f8, "Hungarumlautsmall"}, + {0x0049, "I"}, + {0x0132, "IJ"}, + {0x00cd, "Iacute"}, + {0xf7ed, "Iacutesmall"}, + {0x012c, "Ibreve"}, + {0x00ce, "Icircumflex"}, + {0xf7ee, "Icircumflexsmall"}, + {0x00cf, "Idieresis"}, + {0xf7ef, "Idieresissmall"}, + {0x0130, "Idotaccent"}, + {0x2111, "Ifraktur"}, + {0x00cc, "Igrave"}, + {0xf7ec, "Igravesmall"}, + {0x012a, "Imacron"}, + {0x012e, "Iogonek"}, + {0x0399, "Iota"}, + {0x03aa, "Iotadieresis"}, + {0x038a, "Iotatonos"}, + {0xf769, "Ismall"}, + {0x0128, "Itilde"}, + {0x004a, "J"}, + {0x0134, "Jcircumflex"}, + {0xf76a, "Jsmall"}, + {0x004b, "K"}, + {0x039a, "Kappa"}, + {0x0136, "Kcommaaccent"}, + {0xf76b, "Ksmall"}, + {0x004c, "L"}, + {0xf6bf, "LL"}, + {0x0139, "Lacute"}, + {0x039b, "Lambda"}, + {0x013d, "Lcaron"}, + {0x013b, "Lcommaaccent"}, + {0x013f, "Ldot"}, + {0x0141, "Lslash"}, + {0xf6f9, "Lslashsmall"}, + {0xf76c, "Lsmall"}, + {0x004d, "M"}, + {0xf6d0, "Macron"}, + {0xf7af, "Macronsmall"}, + {0xf76d, "Msmall"}, + {0x039c, "Mu"}, + {0x004e, "N"}, + {0x0143, "Nacute"}, + {0x0147, "Ncaron"}, + {0x0145, "Ncommaaccent"}, + {0xf76e, "Nsmall"}, + {0x00d1, "Ntilde"}, + {0xf7f1, "Ntildesmall"}, + {0x039d, "Nu"}, + {0x004f, "O"}, + {0x0152, "OE"}, + {0xf6fa, "OEsmall"}, + {0x00d3, "Oacute"}, + {0xf7f3, "Oacutesmall"}, + {0x014e, "Obreve"}, + {0x00d4, "Ocircumflex"}, + {0xf7f4, "Ocircumflexsmall"}, + {0x00d6, "Odieresis"}, + {0xf7f6, "Odieresissmall"}, + {0xf6fb, "Ogoneksmall"}, + {0x00d2, "Ograve"}, + {0xf7f2, "Ogravesmall"}, + {0x01a0, "Ohorn"}, + {0x0150, "Ohungarumlaut"}, + {0x014c, "Omacron"}, + {0x2126, "Omega"}, + {0x038f, "Omegatonos"}, + {0x039f, "Omicron"}, + {0x038c, "Omicrontonos"}, + {0x00d8, "Oslash"}, + {0x01fe, "Oslashacute"}, + {0xf7f8, "Oslashsmall"}, + {0xf76f, "Osmall"}, + {0x00d5, "Otilde"}, + {0xf7f5, "Otildesmall"}, + {0x0050, "P"}, + {0x03a6, "Phi"}, + {0x03a0, "Pi"}, + {0x03a8, "Psi"}, + {0xf770, "Psmall"}, + {0x0051, "Q"}, + {0xf771, "Qsmall"}, + {0x0052, "R"}, + {0x0154, "Racute"}, + {0x0158, "Rcaron"}, + {0x0156, "Rcommaaccent"}, + {0x211c, "Rfraktur"}, + {0x03a1, "Rho"}, + {0xf6fc, "Ringsmall"}, + {0xf772, "Rsmall"}, + {0x0053, "S"}, + {0x250c, "SF010000"}, + {0x2514, "SF020000"}, + {0x2510, "SF030000"}, + {0x2518, "SF040000"}, + {0x253c, "SF050000"}, + {0x252c, "SF060000"}, + {0x2534, "SF070000"}, + {0x251c, "SF080000"}, + {0x2524, "SF090000"}, + {0x2500, "SF100000"}, + {0x2502, "SF110000"}, + {0x2561, "SF190000"}, + {0x2562, "SF200000"}, + {0x2556, "SF210000"}, + {0x2555, "SF220000"}, + {0x2563, "SF230000"}, + {0x2551, "SF240000"}, + {0x2557, "SF250000"}, + {0x255d, "SF260000"}, + {0x255c, "SF270000"}, + {0x255b, "SF280000"}, + {0x255e, "SF360000"}, + {0x255f, "SF370000"}, + {0x255a, "SF380000"}, + {0x2554, "SF390000"}, + {0x2569, "SF400000"}, + {0x2566, "SF410000"}, + {0x2560, "SF420000"}, + {0x2550, "SF430000"}, + {0x256c, "SF440000"}, + {0x2567, "SF450000"}, + {0x2568, "SF460000"}, + {0x2564, "SF470000"}, + {0x2565, "SF480000"}, + {0x2559, "SF490000"}, + {0x2558, "SF500000"}, + {0x2552, "SF510000"}, + {0x2553, "SF520000"}, + {0x256b, "SF530000"}, + {0x256a, "SF540000"}, + {0x015a, "Sacute"}, + {0x0160, "Scaron"}, + {0xf6fd, "Scaronsmall"}, + {0x015e, "Scedilla"}, + {0x015c, "Scircumflex"}, + {0x0218, "Scommaaccent"}, + {0x03a3, "Sigma"}, + {0xf773, "Ssmall"}, + {0x0054, "T"}, + {0x03a4, "Tau"}, + {0x0166, "Tbar"}, + {0x0164, "Tcaron"}, + {0x0162, "Tcommaaccent"}, + {0x0398, "Theta"}, + {0x00de, "Thorn"}, + {0xf7fe, "Thornsmall"}, + {0xf6fe, "Tildesmall"}, + {0xf774, "Tsmall"}, + {0x0055, "U"}, + {0x00da, "Uacute"}, + {0xf7fa, "Uacutesmall"}, + {0x016c, "Ubreve"}, + {0x00db, "Ucircumflex"}, + {0xf7fb, "Ucircumflexsmall"}, + {0x00dc, "Udieresis"}, + {0xf7fc, "Udieresissmall"}, + {0x00d9, "Ugrave"}, + {0xf7f9, "Ugravesmall"}, + {0x01af, "Uhorn"}, + {0x0170, "Uhungarumlaut"}, + {0x016a, "Umacron"}, + {0x0172, "Uogonek"}, + {0x03a5, "Upsilon"}, + {0x03d2, "Upsilon1"}, + {0x03ab, "Upsilondieresis"}, + {0x038e, "Upsilontonos"}, + {0x016e, "Uring"}, + {0xf775, "Usmall"}, + {0x0168, "Utilde"}, + {0x0056, "V"}, + {0xf776, "Vsmall"}, + {0x0057, "W"}, + {0x1e82, "Wacute"}, + {0x0174, "Wcircumflex"}, + {0x1e84, "Wdieresis"}, + {0x1e80, "Wgrave"}, + {0xf777, "Wsmall"}, + {0x0058, "X"}, + {0x039e, "Xi"}, + {0xf778, "Xsmall"}, + {0x0059, "Y"}, + {0x00dd, "Yacute"}, + {0xf7fd, "Yacutesmall"}, + {0x0176, "Ycircumflex"}, + {0x0178, "Ydieresis"}, + {0xf7ff, "Ydieresissmall"}, + {0x1ef2, "Ygrave"}, + {0xf779, "Ysmall"}, + {0x005a, "Z"}, + {0x0179, "Zacute"}, + {0x017d, "Zcaron"}, + {0xf6ff, "Zcaronsmall"}, + {0x017b, "Zdotaccent"}, + {0x0396, "Zeta"}, + {0xf77a, "Zsmall"}, + {0x0022, "\""}, + {0x005c, "\\"}, + {0x005d, "]"}, + {0x005e, "^"}, + {0x005f, "_"}, + {0x0060, "`"}, + {0x0061, "a"}, + {0x00e1, "aacute"}, + {0x0103, "abreve"}, + {0x00e2, "acircumflex"}, + {0x00b4, "acute"}, + {0x0301, "acutecomb"}, + {0x00e4, "adieresis"}, + {0x00e6, "ae"}, + {0x01fd, "aeacute"}, + {0x2015, "afii00208"}, + {0x0410, "afii10017"}, + {0x0411, "afii10018"}, + {0x0412, "afii10019"}, + {0x0413, "afii10020"}, + {0x0414, "afii10021"}, + {0x0415, "afii10022"}, + {0x0401, "afii10023"}, + {0x0416, "afii10024"}, + {0x0417, "afii10025"}, + {0x0418, "afii10026"}, + {0x0419, "afii10027"}, + {0x041a, "afii10028"}, + {0x041b, "afii10029"}, + {0x041c, "afii10030"}, + {0x041d, "afii10031"}, + {0x041e, "afii10032"}, + {0x041f, "afii10033"}, + {0x0420, "afii10034"}, + {0x0421, "afii10035"}, + {0x0422, "afii10036"}, + {0x0423, "afii10037"}, + {0x0424, "afii10038"}, + {0x0425, "afii10039"}, + {0x0426, "afii10040"}, + {0x0427, "afii10041"}, + {0x0428, "afii10042"}, + {0x0429, "afii10043"}, + {0x042a, "afii10044"}, + {0x042b, "afii10045"}, + {0x042c, "afii10046"}, + {0x042d, "afii10047"}, + {0x042e, "afii10048"}, + {0x042f, "afii10049"}, + {0x0490, "afii10050"}, + {0x0402, "afii10051"}, + {0x0403, "afii10052"}, + {0x0404, "afii10053"}, + {0x0405, "afii10054"}, + {0x0406, "afii10055"}, + {0x0407, "afii10056"}, + {0x0408, "afii10057"}, + {0x0409, "afii10058"}, + {0x040a, "afii10059"}, + {0x040b, "afii10060"}, + {0x040c, "afii10061"}, + {0x040e, "afii10062"}, + {0xf6c4, "afii10063"}, + {0xf6c5, "afii10064"}, + {0x0430, "afii10065"}, + {0x0431, "afii10066"}, + {0x0432, "afii10067"}, + {0x0433, "afii10068"}, + {0x0434, "afii10069"}, + {0x0435, "afii10070"}, + {0x0451, "afii10071"}, + {0x0436, "afii10072"}, + {0x0437, "afii10073"}, + {0x0438, "afii10074"}, + {0x0439, "afii10075"}, + {0x043a, "afii10076"}, + {0x043b, "afii10077"}, + {0x043c, "afii10078"}, + {0x043d, "afii10079"}, + {0x043e, "afii10080"}, + {0x043f, "afii10081"}, + {0x0440, "afii10082"}, + {0x0441, "afii10083"}, + {0x0442, "afii10084"}, + {0x0443, "afii10085"}, + {0x0444, "afii10086"}, + {0x0445, "afii10087"}, + {0x0446, "afii10088"}, + {0x0447, "afii10089"}, + {0x0448, "afii10090"}, + {0x0449, "afii10091"}, + {0x044a, "afii10092"}, + {0x044b, "afii10093"}, + {0x044c, "afii10094"}, + {0x044d, "afii10095"}, + {0x044e, "afii10096"}, + {0x044f, "afii10097"}, + {0x0491, "afii10098"}, + {0x0452, "afii10099"}, + {0x0453, "afii10100"}, + {0x0454, "afii10101"}, + {0x0455, "afii10102"}, + {0x0456, "afii10103"}, + {0x0457, "afii10104"}, + {0x0458, "afii10105"}, + {0x0459, "afii10106"}, + {0x045a, "afii10107"}, + {0x045b, "afii10108"}, + {0x045c, "afii10109"}, + {0x045e, "afii10110"}, + {0x040f, "afii10145"}, + {0x0462, "afii10146"}, + {0x0472, "afii10147"}, + {0x0474, "afii10148"}, + {0xf6c6, "afii10192"}, + {0x045f, "afii10193"}, + {0x0463, "afii10194"}, + {0x0473, "afii10195"}, + {0x0475, "afii10196"}, + {0xf6c7, "afii10831"}, + {0xf6c8, "afii10832"}, + {0x04d9, "afii10846"}, + {0x200e, "afii299"}, + {0x200f, "afii300"}, + {0x200d, "afii301"}, + {0x066a, "afii57381"}, + {0x060c, "afii57388"}, + {0x0660, "afii57392"}, + {0x0661, "afii57393"}, + {0x0662, "afii57394"}, + {0x0663, "afii57395"}, + {0x0664, "afii57396"}, + {0x0665, "afii57397"}, + {0x0666, "afii57398"}, + {0x0667, "afii57399"}, + {0x0668, "afii57400"}, + {0x0669, "afii57401"}, + {0x061b, "afii57403"}, + {0x061f, "afii57407"}, + {0x0621, "afii57409"}, + {0x0622, "afii57410"}, + {0x0623, "afii57411"}, + {0x0624, "afii57412"}, + {0x0625, "afii57413"}, + {0x0626, "afii57414"}, + {0x0627, "afii57415"}, + {0x0628, "afii57416"}, + {0x0629, "afii57417"}, + {0x062a, "afii57418"}, + {0x062b, "afii57419"}, + {0x062c, "afii57420"}, + {0x062d, "afii57421"}, + {0x062e, "afii57422"}, + {0x062f, "afii57423"}, + {0x0630, "afii57424"}, + {0x0631, "afii57425"}, + {0x0632, "afii57426"}, + {0x0633, "afii57427"}, + {0x0634, "afii57428"}, + {0x0635, "afii57429"}, + {0x0636, "afii57430"}, + {0x0637, "afii57431"}, + {0x0638, "afii57432"}, + {0x0639, "afii57433"}, + {0x063a, "afii57434"}, + {0x0640, "afii57440"}, + {0x0641, "afii57441"}, + {0x0642, "afii57442"}, + {0x0643, "afii57443"}, + {0x0644, "afii57444"}, + {0x0645, "afii57445"}, + {0x0646, "afii57446"}, + {0x0648, "afii57448"}, + {0x0649, "afii57449"}, + {0x064a, "afii57450"}, + {0x064b, "afii57451"}, + {0x064c, "afii57452"}, + {0x064d, "afii57453"}, + {0x064e, "afii57454"}, + {0x064f, "afii57455"}, + {0x0650, "afii57456"}, + {0x0651, "afii57457"}, + {0x0652, "afii57458"}, + {0x0647, "afii57470"}, + {0x06a4, "afii57505"}, + {0x067e, "afii57506"}, + {0x0686, "afii57507"}, + {0x0698, "afii57508"}, + {0x06af, "afii57509"}, + {0x0679, "afii57511"}, + {0x0688, "afii57512"}, + {0x0691, "afii57513"}, + {0x06ba, "afii57514"}, + {0x06d2, "afii57519"}, + {0x06d5, "afii57534"}, + {0x20aa, "afii57636"}, + {0x05be, "afii57645"}, + {0x05c3, "afii57658"}, + {0x05d0, "afii57664"}, + {0x05d1, "afii57665"}, + {0x05d2, "afii57666"}, + {0x05d3, "afii57667"}, + {0x05d4, "afii57668"}, + {0x05d5, "afii57669"}, + {0x05d6, "afii57670"}, + {0x05d7, "afii57671"}, + {0x05d8, "afii57672"}, + {0x05d9, "afii57673"}, + {0x05da, "afii57674"}, + {0x05db, "afii57675"}, + {0x05dc, "afii57676"}, + {0x05dd, "afii57677"}, + {0x05de, "afii57678"}, + {0x05df, "afii57679"}, + {0x05e0, "afii57680"}, + {0x05e1, "afii57681"}, + {0x05e2, "afii57682"}, + {0x05e3, "afii57683"}, + {0x05e4, "afii57684"}, + {0x05e5, "afii57685"}, + {0x05e6, "afii57686"}, + {0x05e7, "afii57687"}, + {0x05e8, "afii57688"}, + {0x05e9, "afii57689"}, + {0x05ea, "afii57690"}, + {0xfb2a, "afii57694"}, + {0xfb2b, "afii57695"}, + {0xfb4b, "afii57700"}, + {0xfb1f, "afii57705"}, + {0x05f0, "afii57716"}, + {0x05f1, "afii57717"}, + {0x05f2, "afii57718"}, + {0xfb35, "afii57723"}, + {0x05b4, "afii57793"}, + {0x05b5, "afii57794"}, + {0x05b6, "afii57795"}, + {0x05bb, "afii57796"}, + {0x05b8, "afii57797"}, + {0x05b7, "afii57798"}, + {0x05b0, "afii57799"}, + {0x05b2, "afii57800"}, + {0x05b1, "afii57801"}, + {0x05b3, "afii57802"}, + {0x05c2, "afii57803"}, + {0x05c1, "afii57804"}, + {0x05b9, "afii57806"}, + {0x05bc, "afii57807"}, + {0x05bd, "afii57839"}, + {0x05bf, "afii57841"}, + {0x05c0, "afii57842"}, + {0x02bc, "afii57929"}, + {0x2105, "afii61248"}, + {0x2113, "afii61289"}, + {0x2116, "afii61352"}, + {0x202c, "afii61573"}, + {0x202d, "afii61574"}, + {0x202e, "afii61575"}, + {0x200c, "afii61664"}, + {0x066d, "afii63167"}, + {0x02bd, "afii64937"}, + {0x00e0, "agrave"}, + {0x2135, "aleph"}, + {0x03b1, "alpha"}, + {0x03ac, "alphatonos"}, + {0x0101, "amacron"}, + {0x0026, "ampersand"}, + {0xf726, "ampersandsmall"}, + {0x2220, "angle"}, + {0x2329, "angleleft"}, + {0x232a, "angleright"}, + {0x0387, "anoteleia"}, + {0x0105, "aogonek"}, + {0x2248, "approxequal"}, + {0x00e5, "aring"}, + {0x01fb, "aringacute"}, + {0x2194, "arrowboth"}, + {0x21d4, "arrowdblboth"}, + {0x21d3, "arrowdbldown"}, + {0x21d0, "arrowdblleft"}, + {0x21d2, "arrowdblright"}, + {0x21d1, "arrowdblup"}, + {0x2193, "arrowdown"}, + {0xf8e7, "arrowhorizex"}, + {0x2190, "arrowleft"}, + {0x2192, "arrowright"}, + {0x2191, "arrowup"}, + {0x2195, "arrowupdn"}, + {0x21a8, "arrowupdnbse"}, + {0xf8e6, "arrowvertex"}, + {0x005e, "asciicircum"}, + {0x007e, "asciitilde"}, + {0x002a, "asterisk"}, + {0x2217, "asteriskmath"}, + {0xf6e9, "asuperior"}, + {0x0040, "at"}, + {0x00e3, "atilde"}, + {0x0062, "b"}, + {0x005c, "backslash"}, + {0x007c, "bar"}, + {0x03b2, "beta"}, + {0x2588, "block"}, + {0xf8f4, "braceex"}, + {0x007b, "braceleft"}, + {0xf8f3, "braceleftbt"}, + {0xf8f2, "braceleftmid"}, + {0xf8f1, "bracelefttp"}, + {0x007d, "braceright"}, + {0xf8fe, "bracerightbt"}, + {0xf8fd, "bracerightmid"}, + {0xf8fc, "bracerighttp"}, + {0x005b, "bracketleft"}, + {0xf8f0, "bracketleftbt"}, + {0xf8ef, "bracketleftex"}, + {0xf8ee, "bracketlefttp"}, + {0x005d, "bracketright"}, + {0xf8fb, "bracketrightbt"}, + {0xf8fa, "bracketrightex"}, + {0xf8f9, "bracketrighttp"}, + {0x02d8, "breve"}, + {0x00a6, "brokenbar"}, + {0xf6ea, "bsuperior"}, + {0x2022, "bullet"}, + {0x0063, "c"}, + {0x0107, "cacute"}, + {0x02c7, "caron"}, + {0x21b5, "carriagereturn"}, + {0x010d, "ccaron"}, + {0x00e7, "ccedilla"}, + {0x0109, "ccircumflex"}, + {0x010b, "cdotaccent"}, + {0x00b8, "cedilla"}, + {0x00a2, "cent"}, + {0xf6df, "centinferior"}, + {0xf7a2, "centoldstyle"}, + {0xf6e0, "centsuperior"}, + {0x03c7, "chi"}, + {0x25cb, "circle"}, + {0x2297, "circlemultiply"}, + {0x2295, "circleplus"}, + {0x02c6, "circumflex"}, + {0x2663, "club"}, + {0x003a, "colon"}, + {0x20a1, "colonmonetary"}, + {0x002c, "comma"}, + {0xf6c3, "commaaccent"}, + {0xf6e1, "commainferior"}, + {0xf6e2, "commasuperior"}, + {0x2245, "congruent"}, + {0x00a9, "copyright"}, + {0x00a9, "copyrightsans"}, + {0x00a9, "copyrightserif"}, + {0x00a4, "currency"}, + {0xf6d1, "cyrBreve"}, + {0xf6d2, "cyrFlex"}, + {0xf6d4, "cyrbreve"}, + {0xf6d5, "cyrflex"}, + {0x0064, "d"}, + {0x2020, "dagger"}, + {0x2021, "daggerdbl"}, + {0xf6d3, "dblGrave"}, + {0xf6d6, "dblgrave"}, + {0x010f, "dcaron"}, + {0x0111, "dcroat"}, + {0x00b0, "degree"}, + {0x03b4, "delta"}, + {0x2666, "diamond"}, + {0x00a8, "dieresis"}, + {0xf6d7, "dieresisacute"}, + {0xf6d8, "dieresisgrave"}, + {0x0385, "dieresistonos"}, + {0x00f7, "divide"}, + {0x2593, "dkshade"}, + {0x2584, "dnblock"}, + {0x0024, "dollar"}, + {0xf6e3, "dollarinferior"}, + {0xf724, "dollaroldstyle"}, + {0xf6e4, "dollarsuperior"}, + {0x20ab, "dong"}, + {0x02d9, "dotaccent"}, + {0x0323, "dotbelowcomb"}, + {0x0131, "dotlessi"}, + {0xf6be, "dotlessj"}, + {0x22c5, "dotmath"}, + {0xf6eb, "dsuperior"}, + {0x0065, "e"}, + {0x00e9, "eacute"}, + {0x0115, "ebreve"}, + {0x011b, "ecaron"}, + {0x00ea, "ecircumflex"}, + {0x00eb, "edieresis"}, + {0x0117, "edotaccent"}, + {0x00e8, "egrave"}, + {0x0038, "eight"}, + {0x2088, "eightinferior"}, + {0xf738, "eightoldstyle"}, + {0x2078, "eightsuperior"}, + {0x2208, "element"}, + {0x2026, "ellipsis"}, + {0x0113, "emacron"}, + {0x2014, "emdash"}, + {0x2205, "emptyset"}, + {0x2013, "endash"}, + {0x014b, "eng"}, + {0x0119, "eogonek"}, + {0x03b5, "epsilon"}, + {0x03ad, "epsilontonos"}, + {0x003d, "equal"}, + {0x2261, "equivalence"}, + {0x212e, "estimated"}, + {0xf6ec, "esuperior"}, + {0x03b7, "eta"}, + {0x03ae, "etatonos"}, + {0x00f0, "eth"}, + {0x0021, "exclam"}, + {0x203c, "exclamdbl"}, + {0x00a1, "exclamdown"}, + {0xf7a1, "exclamdownsmall"}, + {0x0021, "exclamleft"}, + {0xf721, "exclamsmall"}, + {0x2203, "existential"}, + {0x0066, "f"}, + {0x2640, "female"}, + {0xfb00, "ff"}, + {0xfb03, "ffi"}, + {0xfb04, "ffl"}, + {0xfb01, "fi"}, + {0x2012, "figuredash"}, + {0x25a0, "filledbox"}, + {0x25ac, "filledrect"}, + {0x0035, "five"}, + {0x215d, "fiveeighths"}, + {0x2085, "fiveinferior"}, + {0xf735, "fiveoldstyle"}, + {0x2075, "fivesuperior"}, + {0xfb02, "fl"}, + {0x0192, "florin"}, + {0x0034, "four"}, + {0x2084, "fourinferior"}, + {0xf734, "fouroldstyle"}, + {0x2074, "foursuperior"}, + {0x2044, "fraction"}, + {0x20a3, "franc"}, + {0x0067, "g"}, + {0x03b3, "gamma"}, + {0x011f, "gbreve"}, + {0x01e7, "gcaron"}, + {0x011d, "gcircumflex"}, + {0x0123, "gcommaaccent"}, + {0x0121, "gdotaccent"}, + {0x00df, "germandbls"}, + {0x2207, "gradient"}, + {0x0060, "grave"}, + {0x0300, "gravecomb"}, + {0x003e, "greater"}, + {0x2265, "greaterequal"}, + {0x00ab, "guillemotleft"}, + {0x00bb, "guillemotright"}, + {0x2039, "guilsinglleft"}, + {0x203a, "guilsinglright"}, + {0x0068, "h"}, + {0x0127, "hbar"}, + {0x0125, "hcircumflex"}, + {0x2665, "heart"}, + {0x0309, "hookabovecomb"}, + {0x2302, "house"}, + {0x02dd, "hungarumlaut"}, + {0x002d, "hyphen"}, + {0xf6e5, "hypheninferior"}, + {0xf6e6, "hyphensuperior"}, + {0x0069, "i"}, + {0x00ed, "iacute"}, + {0x012d, "ibreve"}, + {0x00ee, "icircumflex"}, + {0x00ef, "idieresis"}, + {0x00ec, "igrave"}, + {0x0133, "ij"}, + {0x012b, "imacron"}, + {0x221e, "infinity"}, + {0x222b, "integral"}, + {0x2321, "integralbt"}, + {0xf8f5, "integralex"}, + {0x2320, "integraltp"}, + {0x2229, "intersection"}, + {0x25d8, "invbullet"}, + {0x25d9, "invcircle"}, + {0x263b, "invsmileface"}, + {0x012f, "iogonek"}, + {0x03b9, "iota"}, + {0x03ca, "iotadieresis"}, + {0x0390, "iotadieresistonos"}, + {0x03af, "iotatonos"}, + {0xf6ed, "isuperior"}, + {0x0129, "itilde"}, + {0x006a, "j"}, + {0x0135, "jcircumflex"}, + {0x006b, "k"}, + {0x03ba, "kappa"}, + {0x0137, "kcommaaccent"}, + {0x0138, "kgreenlandic"}, + {0x006c, "l"}, + {0x013a, "lacute"}, + {0x03bb, "lambda"}, + {0x013e, "lcaron"}, + {0x013c, "lcommaaccent"}, + {0x0140, "ldot"}, + {0x003c, "less"}, + {0x2264, "lessequal"}, + {0x258c, "lfblock"}, + {0x20a4, "lira"}, + {0xf6c0, "ll"}, + {0x2227, "logicaland"}, + {0x00ac, "logicalnot"}, + {0x2228, "logicalor"}, + {0x017f, "longs"}, + {0x25ca, "lozenge"}, + {0x0142, "lslash"}, + {0xf6ee, "lsuperior"}, + {0x2591, "ltshade"}, + {0x006d, "m"}, + {0x00af, "macron"}, + {0x2642, "male"}, + {0x2212, "minus"}, + {0x2032, "minute"}, + {0xf6ef, "msuperior"}, + {0x00b5, "mu"}, + {0x00d7, "multiply"}, + {0x266a, "musicalnote"}, + {0x266b, "musicalnotedbl"}, + {0x006e, "n"}, + {0x0144, "nacute"}, + {0x0149, "napostrophe"}, + {0x00a0, "nbspace"}, + {0x0148, "ncaron"}, + {0x0146, "ncommaaccent"}, + {0x0039, "nine"}, + {0x2089, "nineinferior"}, + {0xf739, "nineoldstyle"}, + {0x2079, "ninesuperior"}, + {0x00a0, "nonbreakingspace"}, + {0x2209, "notelement"}, + {0x2260, "notequal"}, + {0x2284, "notsubset"}, + {0x207f, "nsuperior"}, + {0x00f1, "ntilde"}, + {0x03bd, "nu"}, + {0x0023, "numbersign"}, + {0x006f, "o"}, + {0x00f3, "oacute"}, + {0x014f, "obreve"}, + {0x00f4, "ocircumflex"}, + {0x00f6, "odieresis"}, + {0x0153, "oe"}, + {0x02db, "ogonek"}, + {0x00f2, "ograve"}, + {0x01a1, "ohorn"}, + {0x0151, "ohungarumlaut"}, + {0x014d, "omacron"}, + {0x03c9, "omega"}, + {0x03d6, "omega1"}, + {0x03ce, "omegatonos"}, + {0x03bf, "omicron"}, + {0x03cc, "omicrontonos"}, + {0x0031, "one"}, + {0x2024, "onedotenleader"}, + {0x215b, "oneeighth"}, + {0xf6dc, "onefitted"}, + {0x00bd, "onehalf"}, + {0x2081, "oneinferior"}, + {0xf731, "oneoldstyle"}, + {0x00bc, "onequarter"}, + {0x00b9, "onesuperior"}, + {0x2153, "onethird"}, + {0x25e6, "openbullet"}, + {0x00aa, "ordfeminine"}, + {0x00ba, "ordmasculine"}, + {0x221f, "orthogonal"}, + {0x00f8, "oslash"}, + {0x01ff, "oslashacute"}, + {0xf6f0, "osuperior"}, + {0x00f5, "otilde"}, + {0x0070, "p"}, + {0x00b6, "paragraph"}, + {0x0028, "parenleft"}, + {0xf8ed, "parenleftbt"}, + {0xf8ec, "parenleftex"}, + {0x208d, "parenleftinferior"}, + {0x207d, "parenleftsuperior"}, + {0xf8eb, "parenlefttp"}, + {0x0029, "parenright"}, + {0xf8f8, "parenrightbt"}, + {0xf8f7, "parenrightex"}, + {0x208e, "parenrightinferior"}, + {0x207e, "parenrightsuperior"}, + {0xf8f6, "parenrighttp"}, + {0x2202, "partialdiff"}, + {0x0025, "percent"}, + {0x002e, "period"}, + {0x00b7, "periodcentered"}, + {0xf6e7, "periodinferior"}, + {0xf6e8, "periodsuperior"}, + {0x22a5, "perpendicular"}, + {0x2030, "perthousand"}, + {0x20a7, "peseta"}, + {0x03c6, "phi"}, + {0x03d5, "phi1"}, + {0x03c0, "pi"}, + {0x002b, "plus"}, + {0x00b1, "plusminus"}, + {0x211e, "prescription"}, + {0x220f, "product"}, + {0x2282, "propersubset"}, + {0x2283, "propersuperset"}, + {0x221d, "proportional"}, + {0x03c8, "psi"}, + {0x0071, "q"}, + {0x003f, "question"}, + {0x00bf, "questiondown"}, + {0xf7bf, "questiondownsmall"}, + {0xf73f, "questionsmall"}, + {0x0022, "quotedbl"}, + {0x201e, "quotedblbase"}, + {0x201c, "quotedblleft"}, + {0x201d, "quotedblright"}, + {0x2018, "quoteleft"}, + {0x201b, "quotereversed"}, + {0x2019, "quoteright"}, + {0x201a, "quotesinglbase"}, + {0x0027, "quotesingle"}, + {0x0072, "r"}, + {0x0155, "racute"}, + {0x221a, "radical"}, + {0xf8e5, "radicalex"}, + {0x0159, "rcaron"}, + {0x0157, "rcommaaccent"}, + {0x2286, "reflexsubset"}, + {0x2287, "reflexsuperset"}, + {0x00ae, "registered"}, + {0x00ae, "registersans"}, + {0x00ae, "registerserif"}, + {0x2310, "revlogicalnot"}, + {0x03c1, "rho"}, + {0x02da, "ring"}, + {0xf6f1, "rsuperior"}, + {0x2590, "rtblock"}, + {0xf6dd, "rupiah"}, + {0x0073, "s"}, + {0x015b, "sacute"}, + {0x0161, "scaron"}, + {0x015f, "scedilla"}, + {0x015d, "scircumflex"}, + {0x0219, "scommaaccent"}, + {0x2033, "second"}, + {0x00a7, "section"}, + {0x003b, "semicolon"}, + {0x0037, "seven"}, + {0x215e, "seveneighths"}, + {0x2087, "seveninferior"}, + {0xf737, "sevenoldstyle"}, + {0x2077, "sevensuperior"}, + {0x2592, "shade"}, + {0x03c3, "sigma"}, + {0x03c2, "sigma1"}, + {0x223c, "similar"}, + {0x0036, "six"}, + {0x2086, "sixinferior"}, + {0xf736, "sixoldstyle"}, + {0x2076, "sixsuperior"}, + {0x002f, "slash"}, + {0x263a, "smileface"}, + {0x0020, "space"}, + {0x2660, "spade"}, + {0xf6f2, "ssuperior"}, + {0x00a3, "sterling"}, + {0x220b, "suchthat"}, + {0x2211, "summation"}, + {0x263c, "sun"}, + {0x0074, "t"}, + {0x03c4, "tau"}, + {0x0167, "tbar"}, + {0x0165, "tcaron"}, + {0x0163, "tcommaaccent"}, + {0x2234, "therefore"}, + {0x03b8, "theta"}, + {0x03d1, "theta1"}, + {0x00fe, "thorn"}, + {0x0033, "three"}, + {0x215c, "threeeighths"}, + {0x2083, "threeinferior"}, + {0xf733, "threeoldstyle"}, + {0x00be, "threequarters"}, + {0xf6de, "threequartersemdash"}, + {0x00b3, "threesuperior"}, + {0x02dc, "tilde"}, + {0x0303, "tildecomb"}, + {0x0384, "tonos"}, + {0x2122, "trademark"}, + {0x2122, "trademarksans"}, + {0x2122, "trademarkserif"}, + {0x25bc, "triagdn"}, + {0x25c4, "triaglf"}, + {0x25ba, "triagrt"}, + {0x25b2, "triagup"}, + {0xf6f3, "tsuperior"}, + {0x0032, "two"}, + {0x2025, "twodotenleader"}, + {0x2082, "twoinferior"}, + {0xf732, "twooldstyle"}, + {0x00b2, "twosuperior"}, + {0x2154, "twothirds"}, + {0x0075, "u"}, + {0x00fa, "uacute"}, + {0x016d, "ubreve"}, + {0x00fb, "ucircumflex"}, + {0x00fc, "udieresis"}, + {0x00f9, "ugrave"}, + {0x01b0, "uhorn"}, + {0x0171, "uhungarumlaut"}, + {0x016b, "umacron"}, + {0x005f, "underscore"}, + {0x2017, "underscoredbl"}, + {0x222a, "union"}, + {0x2200, "universal"}, + {0x0173, "uogonek"}, + {0x2580, "upblock"}, + {0x03c5, "upsilon"}, + {0x03cb, "upsilondieresis"}, + {0x03b0, "upsilondieresistonos"}, + {0x03cd, "upsilontonos"}, + {0x016f, "uring"}, + {0x0169, "utilde"}, + {0x0076, "v"}, + {0x0077, "w"}, + {0x1e83, "wacute"}, + {0x0175, "wcircumflex"}, + {0x1e85, "wdieresis"}, + {0x2118, "weierstrass"}, + {0x1e81, "wgrave"}, + {0x0078, "x"}, + {0x03be, "xi"}, + {0x0079, "y"}, + {0x00fd, "yacute"}, + {0x0177, "ycircumflex"}, + {0x00ff, "ydieresis"}, + {0x00a5, "yen"}, + {0x1ef3, "ygrave"}, + {0x007a, "z"}, + {0x017a, "zacute"}, + {0x017e, "zcaron"}, + {0x017c, "zdotaccent"}, + {0x0030, "zero"}, + {0x2080, "zeroinferior"}, + {0xf730, "zerooldstyle"}, + {0x2070, "zerosuperior"}, + {0x03b6, "zeta"}, + {0x007b, "{"}, + {0x007c, "|"}, + {0x007d, "}"}, + {0x007e, "~"}, + { 0, NULL } +}; diff --git a/rosapps/smartpdf/poppler/poppler/Object.cc b/rosapps/smartpdf/poppler/poppler/Object.cc new file mode 100644 index 00000000000..edd380b51dc --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Object.cc @@ -0,0 +1,236 @@ +//======================================================================== +// +// Object.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Error.h" +#include "Stream.h" +#include "UGooString.h" +#include "XRef.h" + +GooStringCache g_objectStringCache; + +//------------------------------------------------------------------------ +// Object +//------------------------------------------------------------------------ + +char *objTypeNames[numObjTypes] = { + "boolean", + "integer", + "real", + "string", + "name", + "null", + "array", + "dictionary", + "stream", + "ref", + "cmd", + "error", + "eof", + "none" +}; + +#ifdef DEBUG_MEM +int Object::numAlloc[numObjTypes] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#endif + +Object *Object::initArray(XRef *xref) { + initObj(objArray); + array = new Array(xref); + return this; +} + +Object *Object::initDict(XRef *xref) { + initObj(objDict); + dict = new Dict(xref); + return this; +} + +Object *Object::initDict(Dict *dictA) { + initObj(objDict); + dict = dictA; + dict->incRef(); + return this; +} + +Object *Object::initStream(Stream *streamA) { + initObj(objStream); + stream = streamA; + return this; +} + +Object *Object::copy(Object *obj) { + *obj = *this; + switch (type) { + case objString: + obj->string = g_objectStringCache.alloc(string); + break; + case objName: + obj->name = g_objectStringCache.alloc(name); + break; + case objArray: + array->incRef(); + break; + case objDict: + dict->incRef(); + break; + case objStream: + stream->incRef(); + break; + case objCmd: + obj->cmd = g_objectStringCache.alloc(cmd); + break; + default: + break; + } +#ifdef DEBUG_MEM + ++numAlloc[type]; +#endif + return obj; +} + +Object *Object::fetch(XRef *xref, Object *obj) { + return (type == objRef && xref) ? + xref->fetch(ref.num, ref.gen, obj) : copy(obj); +} + +void Object::free() { + switch (type) { + case objString: + g_objectStringCache.free(string); + break; + case objName: + g_objectStringCache.free(name); + break; + case objArray: + if (0 == array->decRef()) { + delete array; + } + break; + case objDict: + if (0 == dict->decRef()) { + delete dict; + } + break; + case objStream: + if (0 == stream->decRef()) { + delete stream; + } + break; + case objCmd: + g_objectStringCache.free(cmd); + break; + default: + break; + } +#ifdef DEBUG_MEM + --numAlloc[type]; +#endif + type = objNone; +} + +char *Object::getTypeName() { + return objTypeNames[type]; +} + +void Object::print(FILE *f) { + Object obj; + int i; + + switch (type) { + case objBool: + fprintf(f, "%s", booln ? "true" : "false"); + break; + case objInt: + fprintf(f, "%d", intg); + break; + case objReal: + fprintf(f, "%g", real); + break; + case objString: + fprintf(f, "("); + fwrite(string->getCString(), 1, string->getLength(), f); + fprintf(f, ")"); + break; + case objName: + fprintf(f, "/%s", name); + break; + case objNull: + fprintf(f, "null"); + break; + case objArray: + fprintf(f, "["); + for (i = 0; i < arrayGetLength(); ++i) { + if (i > 0) + fprintf(f, " "); + arrayGetNF(i, &obj); + obj.print(f); + obj.free(); + } + fprintf(f, "]"); + break; + case objDict: + fprintf(f, "<<"); + for (i = 0; i < dictGetLength(); ++i) { + char *key = dictGetKey(i)->getCStringCopy(); + fprintf(f, " /%s ", key); + delete[] key; + dictGetValNF(i, &obj); + obj.print(f); + obj.free(); + } + fprintf(f, " >>"); + break; + case objStream: + fprintf(f, ""); + break; + case objRef: + fprintf(f, "%d %d R", ref.num, ref.gen); + break; + case objCmd: + fprintf(f, "%s", cmd->getCString()); + break; + case objError: + fprintf(f, ""); + break; + case objEOF: + fprintf(f, ""); + break; + case objNone: + fprintf(f, ""); + break; + } +} + +void Object::memCheck(FILE *f) { +#ifdef DEBUG_MEM + int i; + int t; + + t = 0; + for (i = 0; i < numObjTypes; ++i) + t += numAlloc[i]; + if (t > 0) { + fprintf(f, "Allocated objects:\n"); + for (i = 0; i < numObjTypes; ++i) { + if (numAlloc[i] > 0) + fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]); + } + } +#endif +} diff --git a/rosapps/smartpdf/poppler/poppler/Object.h b/rosapps/smartpdf/poppler/poppler/Object.h new file mode 100644 index 00000000000..4b133c7fa1f --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Object.h @@ -0,0 +1,352 @@ +//======================================================================== +// +// Object.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef OBJECT_H +#define OBJECT_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include +#include "goo/gtypes.h" +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "UGooString.h" + +class XRef; +class Array; +class Dict; +class Stream; + +extern GooStringCache g_objectStringCache; + +//------------------------------------------------------------------------ +// Ref +//------------------------------------------------------------------------ + +struct Ref { + int num; // object number + int gen; // generation number +}; + +//------------------------------------------------------------------------ +// object types +//------------------------------------------------------------------------ + +enum ObjType { + // simple objects + objBool, // boolean + objInt, // integer + objReal, // real + objString, // string + objName, // name + objNull, // null + + // complex objects + objArray, // array + objDict, // dictionary + objStream, // stream + objRef, // indirect reference + + // special objects + objCmd, // command name + objError, // error return from Lexer + objEOF, // end of file return from Lexer + objNone // uninitialized object +}; + +#define numObjTypes 14 // total number of object types + +//------------------------------------------------------------------------ +// Object +//------------------------------------------------------------------------ + +#ifdef DEBUG_MEM +#define initObj(t) ++numAlloc[type = t] +#else +#define initObj(t) type = t +#endif + +class Object { +public: + + // Default constructor. + Object(): + type(objNone) {} + + // Initialize an object. + Object *initBool(GBool boolnA) + { initObj(objBool); booln = boolnA; return this; } + Object *initInt(int intgA) + { initObj(objInt); intg = intgA; return this; } + Object *initReal(double realA) + { initObj(objReal); real = realA; return this; } + Object *initString(GooString *stringA) { + initObj(objString); + string = stringA; + return this; } + Object *initName(char *nameA) { + initObj(objName); + name = g_objectStringCache.alloc(nameA); + return this; + } + + Object *initNull() + { initObj(objNull); return this; } + Object *initArray(XRef *xref); + Object *initDict(XRef *xref); + Object *initDict(Dict *dictA); + Object *initStream(Stream *streamA); + Object *initRef(int numA, int genA) + { initObj(objRef); ref.num = numA; ref.gen = genA; return this; } + Object *initCmd(char *cmdA) { + initObj(objCmd); + cmd = g_objectStringCache.alloc(cmdA); + return this; + } + Object *initError() + { initObj(objError); return this; } + Object *initEOF() + { initObj(objEOF); return this; } + + // Copy an object. + Object *copy(Object *obj); + Object *shallowCopy(Object *obj) { + *obj = *this; + return obj; + } + + // If object is a Ref, fetch and return the referenced object. + // Otherwise, return a copy of the object. + Object *fetch(XRef *xref, Object *obj); + + // Free object contents. + void free(); + + // Type checking. + ObjType getType() { return type; } + GBool isBool() { return type == objBool; } + GBool isInt() { return type == objInt; } + GBool isReal() { return type == objReal; } + GBool isNum() { return type == objInt || type == objReal; } + GBool isString() { return type == objString; } + GBool isName() { return type == objName; } + GBool isNull() { return type == objNull; } + GBool isArray() { return type == objArray; } + GBool isDict() { return type == objDict; } + GBool isStream() { return type == objStream; } + GBool isRef() { return type == objRef; } + GBool isCmd() { return type == objCmd; } + GBool isError() { return type == objError; } + GBool isEOF() { return type == objEOF; } + GBool isNone() { return type == objNone; } + + // Special type checking. + GBool isName(char *nameA) + { return type == objName && (0 == name->cmp(nameA)); } + GBool isDict(char *dictType); + GBool isStream(char *dictType); + GBool isCmd(char *cmdA) + { return type == objCmd && (0 == cmd->cmp(cmdA)); } + + // Accessors. NB: these assume object is of correct type. + GBool getBool() { return booln; } + int getInt() { return intg; } + double getReal() { return real; } + double getNum() { return type == objInt ? (double)intg : real; } + GooString *getString() { return string; } + GooString *getName() { return name; } + char *getNameC() { return name->getCString(); } + Array *getArray() { return array; } + Dict *getDict() { return dict; } + Stream *getStream() { return stream; } + Ref getRef() { return ref; } + int getRefNum() { return ref.num; } + int getRefGen() { return ref.gen; } + GooString *getCmd() { return cmd; } + + // Array accessors. + int arrayGetLength(); + void arrayAdd(Object *elem); + Object *arrayGet(int i, Object *obj); + Object *arrayGetNF(int i, Object *obj); + + // Dict accessors. + int dictGetLength(); + void dictAddOwnKeyVal(UGooString *key, Object *val); + void dictAdd(const UGooString &key, Object *val); + void dictAddOwnVal(const char *key, Object *val); + GBool dictIs(char *dictType); + Object *dictLookup(const UGooString &key, Object *obj); + Object *dictLookupNF(const UGooString &key, Object *obj); + Object *dictLookupRefNoFetch(const UGooString &key); + Object *dictLookup(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN); + Object *dictLookupNF(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN); + Object *dictLookupRefNoFetch(const char *key, int keyLen=UGooString::CALC_STRING_LEN); + GBool dictLookupBool(const char *key, const char *alt_key, GBool *value); + GBool dictLookupInt(const char *key, const char *alt_key, int *value); + + UGooString *dictGetKey(int i); + Object *dictGetVal(int i, Object *obj); + Object *dictGetValNF(int i, Object *obj); + + // Stream accessors. + GBool streamIs(char *dictType); + void streamReset(); + void streamClose(); + int streamGetChar(); + int streamLookChar(); + char *streamGetLine(char *buf, int size); + Guint streamGetPos(); + void streamSetPos(Guint pos, int dir = 0); + Dict *streamGetDict(); + + // Output. + char *getTypeName(); + void print(FILE *f = stdout); + + // Memory testing. + static void memCheck(FILE *f); + +private: + + ObjType type; // object type + union { // value for each type: + GBool booln; // boolean + int intg; // integer + double real; // real + GooString *string; // string + GooString *name; // name + Array *array; // array + Dict *dict; // dictionary + Stream *stream; // stream + Ref ref; // indirect reference + GooString *cmd; // command + }; + +#ifdef DEBUG_MEM + static int // number of each type of object + numAlloc[numObjTypes]; // currently allocated +#endif +}; + +//------------------------------------------------------------------------ +// Array accessors. +//------------------------------------------------------------------------ + +#include "Array.h" + +inline int Object::arrayGetLength() + { return array->getLength(); } + +inline void Object::arrayAdd(Object *elem) + { array->add(elem); } + +inline Object *Object::arrayGet(int i, Object *obj) + { return array->get(i, obj); } + +inline Object *Object::arrayGetNF(int i, Object *obj) + { return array->getNF(i, obj); } + +//------------------------------------------------------------------------ +// Dict accessors. +//------------------------------------------------------------------------ + +#include "Dict.h" + +inline int Object::dictGetLength() + { return dict->getLength(); } + +inline void Object::dictAdd(const UGooString &key, Object *val) + { dict->add(key, val); } + +inline void Object::dictAddOwnVal(const char *key, Object *val) + { dict->addOwnVal(key, val); } + +inline void Object::dictAddOwnKeyVal(UGooString *key, Object *val) + { dict->addOwnKeyVal(key, val); } + +inline GBool Object::dictIs(char *dictType) + { return dict->is(dictType); } + +inline GBool Object::isDict(char *dictType) + { return type == objDict && dictIs(dictType); } + +inline Object *Object::dictLookup(const UGooString &key, Object *obj) + { return dict->lookup(key, obj); } + +inline Object *Object::dictLookup(const char *key, Object *obj, int keyLen) + { return dict->lookup(key, obj, keyLen); } + +inline Object *Object::dictLookupNF(const UGooString &key, Object *obj) + { return dict->lookupNF(key, obj); } + +inline Object *Object::dictLookupNF(const char *key, Object *obj, int keyLen) + { return dict->lookupNF(key, obj, keyLen); } + +inline Object *Object::dictLookupRefNoFetch(const UGooString &key) + { return dict->lookupRefNoFetch(key); } + +inline Object *Object::dictLookupRefNoFetch(const char *key, int keyLen) + { return dict->lookupRefNoFetch(key, keyLen); } + +inline GBool Object::dictLookupBool(const char *key, const char *alt_key, GBool *value) + { return dict->lookupBool(key, alt_key, value); } + +inline GBool Object::dictLookupInt(const char *key, const char *alt_key, int *value) + { return dict->lookupInt(key, alt_key, value); } + +inline UGooString *Object::dictGetKey(int i) + { return dict->getKey(i); } + +inline Object *Object::dictGetVal(int i, Object *obj) + { return dict->getVal(i, obj); } + +inline Object *Object::dictGetValNF(int i, Object *obj) + { return dict->getValNF(i, obj); } + +//------------------------------------------------------------------------ +// Stream accessors. +//------------------------------------------------------------------------ + +#include "Stream.h" + +inline GBool Object::streamIs(char *dictType) + { return stream->getDict()->is(dictType); } + +inline GBool Object::isStream(char *dictType) + { return type == objStream && streamIs(dictType); } + +inline void Object::streamReset() + { stream->reset(); } + +inline void Object::streamClose() + { stream->close(); } + +inline int Object::streamGetChar(){ + return stream->getChar(); +} + +inline int Object::streamLookChar() + { return stream->lookChar(); } + +inline char *Object::streamGetLine(char *buf, int size) + { return stream->getLine(buf, size); } + +inline Guint Object::streamGetPos() + { return stream->getPos(); } + +inline void Object::streamSetPos(Guint pos, int dir) + { stream->setPos(pos, dir); } + +inline Dict *Object::streamGetDict() + { return stream->getDict(); } + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Outline.cc b/rosapps/smartpdf/poppler/poppler/Outline.cc new file mode 100644 index 00000000000..11f9c5e1281 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Outline.cc @@ -0,0 +1,158 @@ +//======================================================================== +// +// Outline.cc +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "Link.h" +#include "PDFDocEncoding.h" +#include "Outline.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ + +Outline::Outline(Object *outlineObj, XRef *xref) { + Object first, last; + + items = NULL; + if (!outlineObj->isDict()) { + return; + } + items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first), + outlineObj->dictLookupNF("Last", &last), + xref); + first.free(); + last.free(); +} + +Outline::~Outline() { + if (items) { + deleteGooList(items, OutlineItem); + } +} + +//------------------------------------------------------------------------ + +OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) { + Object obj1; + GooString *s; + int i; + + xref = xrefA; + title = NULL; + action = NULL; + kids = NULL; + + if (dict->lookup("Title", &obj1)->isString()) { + s = obj1.getString(); + if ((s->getChar(0) & 0xff) == 0xfe && + (s->getChar(1) & 0xff) == 0xff) { + titleLen = (s->getLength() - 2) / 2; + title = (Unicode *)gmallocn(titleLen, sizeof(Unicode)); + for (i = 0; i < titleLen; ++i) { + title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) | + (s->getChar(3 + 2*i) & 0xff); + } + } else { + titleLen = s->getLength(); + title = (Unicode *)gmallocn(titleLen, sizeof(Unicode)); + for (i = 0; i < titleLen; ++i) { + title[i] = pdfDocEncoding[s->getChar(i) & 0xff]; + } + } + } else { + titleLen = 0; + } + obj1.free(); + + if (!dict->lookup("Dest", &obj1)->isNull()) { + action = LinkAction::parseDest(&obj1); + } else { + obj1.free(); + if (!dict->lookup("A", &obj1)->isNull()) { + action = LinkAction::parseAction(&obj1); + } + } + obj1.free(); + + dict->lookupNF("First", &firstRef); + dict->lookupNF("Last", &lastRef); + dict->lookupNF("Next", &nextRef); + + startsOpen = gFalse; + if (dict->lookup("Count", &obj1)->isInt()) { + if (obj1.getInt() > 0) { + startsOpen = gTrue; + } + } + obj1.free(); +} + +OutlineItem::~OutlineItem() { + close(); + if (title) { + gfree(title); + } + if (action) { + delete action; + } + firstRef.free(); + lastRef.free(); + nextRef.free(); +} + +GooList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef, + XRef *xrefA) { + GooList *items; + OutlineItem *item; + Object obj; + Object *p; + + items = new GooList(); + p = firstItemRef; + while (p->isRef()) { + if (!p->fetch(xrefA, &obj)->isDict()) { + obj.free(); + break; + } + item = new OutlineItem(obj.getDict(), xrefA); + obj.free(); + items->append(item); + if (p->getRef().num == lastItemRef->getRef().num && + p->getRef().gen == lastItemRef->getRef().gen) { + break; + } + p = &item->nextRef; + } + + if (!items->getLength()) { + delete items; + items = NULL; + } + + return items; +} + +void OutlineItem::open() { + if (!kids) { + kids = readItemList(&firstRef, &lastRef, xref); + } +} + +void OutlineItem::close() { + if (kids) { + deleteGooList(kids, OutlineItem); + kids = NULL; + } +} diff --git a/rosapps/smartpdf/poppler/poppler/Outline.h b/rosapps/smartpdf/poppler/poppler/Outline.h new file mode 100644 index 00000000000..999c21e257d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Outline.h @@ -0,0 +1,75 @@ +//======================================================================== +// +// Outline.h +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef OUTLINE_H +#define OUTLINE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "Object.h" +#include "CharTypes.h" + +class GooString; +class GooList; +class XRef; +class LinkAction; + +//------------------------------------------------------------------------ + +class Outline { +public: + + Outline(Object *outlineObj, XRef *xref); + ~Outline(); + + GooList *getItems() { return items; } + +private: + + GooList *items; // NULL if document has no outline, + // otherwise, a list of OutlineItem +}; + +//------------------------------------------------------------------------ + +class OutlineItem { +public: + + OutlineItem(Dict *dict, XRef *xrefA); + ~OutlineItem(); + + static GooList *readItemList(Object *firstItemRef, Object *lastItemRef, + XRef *xrefA); + + void open(); + void close(); + + Unicode *getTitle() { return title; } + int getTitleLength() { return titleLen; } + LinkAction *getAction() { return action; } + GBool isOpen() { return startsOpen; } + GBool hasKids() { return firstRef.isRef(); } + GooList *getKids() { return kids; } + +private: + + XRef *xref; + Unicode *title; + int titleLen; + LinkAction *action; + Object firstRef; + Object lastRef; + Object nextRef; + GBool startsOpen; + GooList *kids; // NULL if this item is closed or has no kids, + // otherwise a list of OutlineItem +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/OutputDev.cc b/rosapps/smartpdf/poppler/poppler/OutputDev.cc new file mode 100644 index 00000000000..282588b203b --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/OutputDev.cc @@ -0,0 +1,162 @@ +//======================================================================== +// +// OutputDev.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "Object.h" +#include "Stream.h" +#include "GfxState.h" +#include "OutputDev.h" +#include "goo/GooHash.h" + +//------------------------------------------------------------------------ +// OutputDev +//------------------------------------------------------------------------ + +void OutputDev::setDefaultCTM(double *ctm) { + int i; + double det; + + for (i = 0; i < 6; ++i) { + defCTM[i] = ctm[i]; + } + det = 1 / (defCTM[0] * defCTM[3] - defCTM[1] * defCTM[2]); + defICTM[0] = defCTM[3] * det; + defICTM[1] = -defCTM[1] * det; + defICTM[2] = -defCTM[2] * det; + defICTM[3] = defCTM[0] * det; + defICTM[4] = (defCTM[2] * defCTM[5] - defCTM[3] * defCTM[4]) * det; + defICTM[5] = (defCTM[1] * defCTM[4] - defCTM[0] * defCTM[5]) * det; +} + +void OutputDev::cvtDevToUser(double dx, double dy, double *ux, double *uy) { + *ux = defICTM[0] * dx + defICTM[2] * dy + defICTM[4]; + *uy = defICTM[1] * dx + defICTM[3] * dy + defICTM[5]; +} + +void OutputDev::cvtUserToDev(double ux, double uy, int *dx, int *dy) { + *dx = (int)(defCTM[0] * ux + defCTM[2] * uy + defCTM[4] + 0.5); + *dy = (int)(defCTM[1] * ux + defCTM[3] * uy + defCTM[5] + 0.5); +} + +void OutputDev::updateAll(GfxState *state) { + updateLineDash(state); + updateFlatness(state); + updateLineJoin(state); + updateLineCap(state); + updateMiterLimit(state); + updateLineWidth(state); + updateFillColorSpace(state); + updateFillColor(state); + updateStrokeColorSpace(state); + updateStrokeColor(state); + updateBlendMode(state); + updateFillOpacity(state); + updateStrokeOpacity(state); + updateFillOverprint(state); + updateStrokeOverprint(state); + updateFont(state); +} + +GBool OutputDev::beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen) { + return gFalse; +} + +void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + int i, j; + + if (inlineImg) { + str->reset(); + j = height * ((width + 7) / 8); + for (i = 0; i < j; ++i) + str->getChar(); + str->close(); + } +} + +void OutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) { + int i, j; + + if (inlineImg) { + str->reset(); + j = height * ((width * colorMap->getNumPixelComps() * + colorMap->getBits() + 7) / 8); + for (i = 0; i < j; ++i) + str->getChar(); + str->close(); + } +} + +void OutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GBool maskInvert) { + drawImage(state, ref, str, width, height, colorMap, NULL, gFalse); +} + +void OutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap) { + drawImage(state, ref, str, width, height, colorMap, NULL, gFalse); +} + +void OutputDev::endMarkedContent() { +} + +void OutputDev::beginMarkedContent(char *name) { +} + +void OutputDev::beginMarkedContent(char *name, Dict *properties) { +} + +void OutputDev::markPoint(char *name) { +} + +void OutputDev::markPoint(char *name, Dict *properties) { +} + + +#if OPI_SUPPORT +void OutputDev::opiBegin(GfxState *state, Dict *opiDict) { +} + +void OutputDev::opiEnd(GfxState *state, Dict *opiDict) { +} +#endif + +void OutputDev::startProfile() { + if (profileHash) + delete profileHash; + + profileHash = new GooHash (true); +} + +GooHash *OutputDev::endProfile() { + GooHash *profile = profileHash; + + profileHash = NULL; + + return profile; +} + diff --git a/rosapps/smartpdf/poppler/poppler/OutputDev.h b/rosapps/smartpdf/poppler/poppler/OutputDev.h new file mode 100644 index 00000000000..b51b7c1f9a7 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/OutputDev.h @@ -0,0 +1,223 @@ +//======================================================================== +// +// OutputDev.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef OUTPUTDEV_H +#define OUTPUTDEV_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include "goo/gtypes.h" +#include "CharTypes.h" + +class Dict; +class GooHash; +class GooString; +class GfxState; +class GfxColorSpace; +class GfxImageColorMap; +class GfxFunctionShading; +class GfxAxialShading; +class GfxRadialShading; +class Stream; +class Link; +class Catalog; + +//------------------------------------------------------------------------ +// OutputDev +//------------------------------------------------------------------------ + +class OutputDev { +public: + + // Constructor. + OutputDev() { profileHash = NULL; } + + // Destructor. + virtual ~OutputDev() {} + + //----- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() = 0; + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() = 0; + + // Does this device use tilingPatternFill()? If this returns false, + // tiling pattern fills will be reduced to a series of other drawing + // operations. + virtual GBool useTilingPatternFill() { return gFalse; } + + // Does this device use functionShadedFill(), axialShadedFill(), and + // radialShadedFill()? If this returns false, these shaded fills + // will be reduced to a series of other drawing operations. + virtual GBool useShadedFills() { return gFalse; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() = 0; + + // Does this device need non-text content? + virtual GBool needNonText() { return gTrue; } + + //----- initialization and control + + // Set default transform matrix. + virtual void setDefaultCTM(double *ctm); + + // Start a page. + virtual void startPage(int /*pageNum*/, GfxState * /*state*/) {} + + // End a page. + virtual void endPage() {} + + // Dump page contents to display. + virtual void dump() {} + + //----- coordinate conversion + + // Convert between device and user coordinates. + virtual void cvtDevToUser(double dx, double dy, double *ux, double *uy); + virtual void cvtUserToDev(double ux, double uy, int *dx, int *dy); + + double *getDefCTM() { return defCTM; } + double *getDefICTM() { return defICTM; } + + //----- link borders + virtual void drawLink(Link * /*link*/, Catalog * /*catalog*/) {} + + //----- save/restore graphics state + virtual void saveState(GfxState * /*state*/) {} + virtual void restoreState(GfxState * /*state*/) {} + + //----- update graphics state + virtual void updateAll(GfxState *state); + virtual void updateCTM(GfxState * /*state*/, double /*m11*/, double /*m12*/, + double /*m21*/, double /*m22*/, double /*m31*/, double /*m32*/) {} + virtual void updateLineDash(GfxState * /*state*/) {} + virtual void updateFlatness(GfxState * /*state*/) {} + virtual void updateLineJoin(GfxState * /*state*/) {} + virtual void updateLineCap(GfxState * /*state*/) {} + virtual void updateMiterLimit(GfxState * /*state*/) {} + virtual void updateLineWidth(GfxState * /*state*/) {} + virtual void updateFillColorSpace(GfxState * /*state*/) {} + virtual void updateStrokeColorSpace(GfxState * /*state*/) {} + virtual void updateFillColor(GfxState * /*state*/) {} + virtual void updateStrokeColor(GfxState * /*state*/) {} + virtual void updateBlendMode(GfxState * /*state*/) {} + virtual void updateFillOpacity(GfxState * /*state*/) {} + virtual void updateStrokeOpacity(GfxState * /*state*/) {} + virtual void updateFillOverprint(GfxState * /*state*/) {} + virtual void updateStrokeOverprint(GfxState * /*state*/) {} + + //----- update text state + virtual void updateFont(GfxState * /*state*/) {} + virtual void updateTextMat(GfxState * /*state*/) {} + virtual void updateCharSpace(GfxState * /*state*/) {} + virtual void updateRender(GfxState * /*state*/) {} + virtual void updateRise(GfxState * /*state*/) {} + virtual void updateWordSpace(GfxState * /*state*/) {} + virtual void updateHorizScaling(GfxState * /*state*/) {} + virtual void updateTextPos(GfxState * /*state*/) {} + virtual void updateTextShift(GfxState * /*state*/, double /*shift*/) {} + + //----- path painting + virtual void stroke(GfxState * /*state*/) {} + virtual void fill(GfxState * /*state*/) {} + virtual void eoFill(GfxState * /*state*/) {} + virtual void tilingPatternFill(GfxState * /*state*/, Object * /*str*/, + int /*paintType*/, Dict * /*resDict*/, + double * /*mat*/, double * /*bbox*/, + int /*x0*/, int /*y0*/, int /*x1*/, int /*y1*/, + double /*xStep*/, double /*yStep*/) {} + virtual void functionShadedFill(GfxState * /*state*/, + GfxFunctionShading * /*shading*/) {} + virtual void axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/) {} + virtual void radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/) {} + + //----- path clipping + virtual void clip(GfxState * /*state*/) {} + virtual void eoClip(GfxState * /*state*/) {} + + //----- text drawing + virtual void beginStringOp(GfxState * /*state*/) {} + virtual void endStringOp(GfxState * /*state*/) {} + virtual void beginString(GfxState * /*state*/, GooString * /*s*/) {} + virtual void endString(GfxState * /*state*/) {} + virtual void drawChar(GfxState * /*state*/, double /*x*/, double /*y*/, + double /*dx*/, double /*dy*/, + double /*originX*/, double /*originY*/, + CharCode /*code*/, int /*nBytes*/, Unicode * /*u*/, int /*uLen*/) {} + virtual void drawString(GfxState * /*state*/, GooString * /*s*/) {} + virtual GBool beginType3Char(GfxState * /*state*/, double /*x*/, double /*y*/, + double /*dx*/, double /*dy*/, + CharCode /*code*/, Unicode * /*u*/, int /*uLen*/); + virtual void endType3Char(GfxState * /*state*/) {} + virtual void endTextObject(GfxState * /*state*/) {} + + //----- image drawing + virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg); + virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, int maskWidth, int maskHeight, + GBool maskInvert); + virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap); + + //----- grouping operators + + virtual void endMarkedContent(); + virtual void beginMarkedContent(char *name); + virtual void beginMarkedContent(char *name, Dict *properties); + virtual void markPoint(char *name); + virtual void markPoint(char *name, Dict *properties); + + + +#if OPI_SUPPORT + //----- OPI functions + virtual void opiBegin(GfxState *state, Dict *opiDict); + virtual void opiEnd(GfxState *state, Dict *opiDict); +#endif + + //----- Type 3 font operators + virtual void type3D0(GfxState * /*state*/, double /*wx*/, double /*wy*/) {} + virtual void type3D1(GfxState * /*state*/, double /*wx*/, double /*wy*/, + double /*llx*/, double /*lly*/, double /*urx*/, double /*ury*/) {} + + //----- PostScript XObjects + virtual void psXObject(Stream * /*psStream*/, Stream * /*level1Stream*/) {} + + //----- Profiling + virtual void startProfile(); + virtual GooHash *getProfileHash() {return profileHash; } + virtual GooHash *endProfile(); + + +private: + + double defCTM[6]; // default coordinate transform matrix + double defICTM[6]; // inverse of default CTM + GooHash *profileHash; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/PDFDoc.cc b/rosapps/smartpdf/poppler/poppler/PDFDoc.cc new file mode 100644 index 00000000000..1ca1333a6f6 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PDFDoc.cc @@ -0,0 +1,486 @@ +//======================================================================== +// +// PDFDoc.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#ifdef WIN32 +# include +#endif +#include "goo/GooString.h" +#include "poppler-config.h" +#include "GlobalParams.h" +#include "Page.h" +#include "Catalog.h" +#include "Stream.h" +#include "XRef.h" +#include "Link.h" +#include "OutputDev.h" +#include "Error.h" +#include "ErrorCodes.h" +#include "Lexer.h" +#include "Parser.h" +#include "SecurityHandler.h" +#ifndef DISABLE_OUTLINE +#include "Outline.h" +#endif +#include "PDFDoc.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ + +#define headerSearchSize 1024 // read this many bytes at beginning of + // file to look for '%PDF' + +//------------------------------------------------------------------------ +// PDFDoc +//------------------------------------------------------------------------ + +PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) { + Object obj; + GooString *fileName1, *fileName2; + + ok = gFalse; + errCode = errNone; + + guiData = guiDataA; + + file = NULL; + str = NULL; + xref = NULL; + catalog = NULL; + links = NULL; +#ifndef DISABLE_OUTLINE + outline = NULL; +#endif + + fileName = fileNameA; + fileName1 = fileName; + + + // try to open file + fileName2 = NULL; +#ifdef VMS + if (!(file = fopen(fileName1->getCString(), "rb", "ctx=stm"))) { + error(-1, "Couldn't open file '%s'", fileName1->getCString()); + errCode = errOpenFile; + return; + } +#else + if (!(file = fopen(fileName1->getCString(), "rb"))) { + fileName2 = fileName->copy(); + fileName2->lowerCase(); + if (!(file = fopen(fileName2->getCString(), "rb"))) { + fileName2->upperCase(); + if (!(file = fopen(fileName2->getCString(), "rb"))) { + error(-1, "Couldn't open file '%s'", fileName->getCString()); + delete fileName2; + errCode = errOpenFile; + return; + } + } + delete fileName2; + } +#endif + + // create stream + obj.initNull(); + str = new FileStream(file, 0, gFalse, 0, &obj); + + ok = setup(ownerPassword, userPassword); +} + +#ifdef WIN32 +PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) { + OSVERSIONINFO version; + wchar_t fileName2[_MAX_PATH + 1]; + Object obj; + int i; + + ok = gFalse; + errCode = errNone; + + guiData = guiDataA; + + file = NULL; + str = NULL; + xref = NULL; + catalog = NULL; + links = NULL; +#ifndef DISABLE_OUTLINE + outline = NULL; +#endif + + //~ file name should be stored in Unicode (?) + fileName = new GooString(); + for (i = 0; i < fileNameLen; ++i) { + fileName->append((char)fileNameA[i]); + } + + // zero-terminate the file name string + for (i = 0; i < fileNameLen && i < _MAX_PATH; ++i) { + fileName2[i] = fileNameA[i]; + } + fileName2[i] = 0; + + // try to open file + // NB: _wfopen is only available in NT + version.dwOSVersionInfoSize = sizeof(version); + GetVersionEx(&version); + if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) { + file = _wfopen(fileName2, L"rb"); + } else { + file = fopen(fileName->getCString(), "rb"); + } + if (!file) { + error(-1, "Couldn't open file '%s'", fileName->getCString()); + errCode = errOpenFile; + return; + } + + // create stream + obj.initNull(); + str = new FileStream(file, 0, gFalse, 0, &obj); + + ok = setup(ownerPassword, userPassword); +} +#endif + +PDFDoc::PDFDoc(BaseStream *strA, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) { + ok = gFalse; + errCode = errNone; + guiData = guiDataA; + fileName = NULL; + file = NULL; + str = strA; + xref = NULL; + catalog = NULL; + links = NULL; +#ifndef DISABLE_OUTLINE + outline = NULL; +#endif + ok = setup(ownerPassword, userPassword); +} + +GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) { + str->reset(); + + // check footer + if (!checkFooter()) return gFalse; + + // check header + checkHeader(); + + // read xref table + xref = new XRef(str); + if (!xref->isOk()) { + error(-1, "Couldn't read xref table"); + errCode = xref->getErrorCode(); + return gFalse; + } + + // check for encryption + if (!checkEncryption(ownerPassword, userPassword)) { + errCode = errEncrypted; + return gFalse; + } + + // read catalog + catalog = new Catalog(xref); + if (!catalog->isOk()) { + error(-1, "Couldn't read page catalog"); + errCode = errBadCatalog; + return gFalse; + } + +#ifndef DISABLE_OUTLINE + // read outline + outline = new Outline(catalog->getOutline(), xref); +#endif + + // done + return gTrue; +} + +PDFDoc::~PDFDoc() { +#ifndef DISABLE_OUTLINE + if (outline) { + delete outline; + } +#endif + if (catalog) { + delete catalog; + } + if (xref) { + delete xref; + } + if (str) { + delete str; + } + if (file) { + fclose(file); + } + if (fileName) { + delete fileName; + } + if (links) { + delete links; + } +} + + +// Check for a %%EOF at the end of this stream +GBool PDFDoc::checkFooter() { + // we look in the last 1024 chars because Adobe does the same + char *eof = new char[1025]; + int pos = str->getPos(); + str->setPos(1024, -1); + int i, ch; + for (i = 0; i < 1024; i++) + { + ch = str->getChar(); + if (ch == EOF) + break; + eof[i] = ch; + } + eof[i] = '\0'; + + bool found = false; + for (i = i - 5; i >= 0; i--) { + if (strncmp (&eof[i], "%%EOF", 5) == 0) { + found = true; + break; + } + } + if (!found) + { + error(-1, "Document has not the mandatory ending %%EOF"); + errCode = errDamaged; + delete[] eof; + return gFalse; + } + delete[] eof; + str->setPos(pos); + return gTrue; +} + +// Check for a PDF header on this stream. Skip past some garbage +// if necessary. +void PDFDoc::checkHeader() { + char hdrBuf[headerSearchSize+1]; + char *p; + int i; + + pdfVersion = 0; + for (i = 0; i < headerSearchSize; ++i) { + hdrBuf[i] = str->getChar(); + } + hdrBuf[headerSearchSize] = '\0'; + for (i = 0; i < headerSearchSize - 5; ++i) { + if (!strncmp(&hdrBuf[i], "%PDF-", 5)) { + break; + } + } + if (i >= headerSearchSize - 5) { + error(-1, "May not be a PDF file (continuing anyway)"); + return; + } + str->moveStart(i); + if (!(p = strtok(&hdrBuf[i+5], " \t\n\r"))) { + error(-1, "May not be a PDF file (continuing anyway)"); + return; + } + { + char *theLocale = setlocale(LC_NUMERIC, "C"); + pdfVersion = atof(p); + setlocale(LC_NUMERIC, theLocale); + } + // We don't do the version check. Don't add it back in. +} + +GBool PDFDoc::checkEncryption(GooString *ownerPassword, GooString *userPassword) { + Object encrypt; + GBool encrypted; + SecurityHandler *secHdlr; + GBool ret; + + xref->getTrailerDict()->dictLookup("Encrypt", &encrypt); + if ((encrypted = encrypt.isDict())) { + if ((secHdlr = SecurityHandler::make(this, &encrypt))) { + if (secHdlr->checkEncryption(ownerPassword, userPassword)) { + // authorization succeeded + xref->setEncryption(secHdlr->getPermissionFlags(), + secHdlr->getOwnerPasswordOk(), + secHdlr->getFileKey(), + secHdlr->getFileKeyLength(), + secHdlr->getEncVersion(), + secHdlr->getEncRevision()); + ret = gTrue; + } else { + // authorization failed + ret = gFalse; + } + delete secHdlr; + } else { + // couldn't find the matching security handler + ret = gFalse; + } + } else { + // document is not encrypted + ret = gTrue; + } + encrypt.free(); + return ret; +} + +void PDFDoc::displayPage(OutputDev *out, int page, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, GBool doLinks, + GBool (*abortCheckCbk)(void *data), + void *abortCheckCbkData, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), + void *annotDisplayDecideCbkData) { + Page *p; + + if (globalParams->getPrintCommands()) { + printf("***** page %d *****\n", page); + } + p = catalog->getPage(page); + if (doLinks) { + if (links) { + delete links; + } + getLinks(p); + p->display(out, hDPI, vDPI, rotate, useMediaBox, crop, links, catalog, + abortCheckCbk, abortCheckCbkData, + annotDisplayDecideCbk, annotDisplayDecideCbkData); + } else { + p->display(out, hDPI, vDPI, rotate, useMediaBox, crop, NULL, catalog, + abortCheckCbk, abortCheckCbkData, + annotDisplayDecideCbk, annotDisplayDecideCbkData); + } +} + +void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage, + double hDPI, double vDPI, int rotate, GBool useMediaBox, + GBool crop, GBool doLinks, + GBool (*abortCheckCbk)(void *data), + void *abortCheckCbkData, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), + void *annotDisplayDecideCbkData) { + int page; + + for (page = firstPage; page <= lastPage; ++page) { + displayPage(out, page, hDPI, vDPI, rotate, useMediaBox, crop, doLinks, + abortCheckCbk, abortCheckCbkData, + annotDisplayDecideCbk, annotDisplayDecideCbkData); + } +} + +void PDFDoc::displayPageSlice(OutputDev *out, int page, + double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, GBool doLinks, + int sliceX, int sliceY, int sliceW, int sliceH, + GBool (*abortCheckCbk)(void *data), + void *abortCheckCbkData, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), + void *annotDisplayDecideCbkData) { + Page *p; + + p = catalog->getPage(page); + if (doLinks) + { + if (links) { + delete links; + } + getLinks(p); + p->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, + sliceX, sliceY, sliceW, sliceH, + links, catalog, + abortCheckCbk, abortCheckCbkData, + annotDisplayDecideCbk, annotDisplayDecideCbkData); + } else { + p->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, + sliceX, sliceY, sliceW, sliceH, + NULL, catalog, + abortCheckCbk, abortCheckCbkData, + annotDisplayDecideCbk, annotDisplayDecideCbkData); + } +} + +Links *PDFDoc::takeLinks() { + Links *ret; + + ret = links; + links = NULL; + return ret; +} + +GBool PDFDoc::isLinearized() { + Parser *parser; + Object obj1, obj2, obj3, obj4, obj5; + GBool lin; + + lin = gFalse; + obj1.initNull(); + parser = new Parser(xref, + new Lexer(xref, + str->makeSubStream(str->getStart(), gFalse, 0, &obj1))); + parser->getObj(&obj1); + parser->getObj(&obj2); + parser->getObj(&obj3); + parser->getObj(&obj4); + if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && + obj4.isDict()) { + obj4.dictLookup("Linearized", &obj5); + if (obj5.isNum() && obj5.getNum() > 0) { + lin = gTrue; + } + obj5.free(); + } + obj4.free(); + obj3.free(); + obj2.free(); + obj1.free(); + delete parser; + return lin; +} + +GBool PDFDoc::saveAs(GooString *name) { + FILE *f; + int c; + + if (!(f = fopen(name->getCString(), "wb"))) { + error(-1, "Couldn't open file '%s'", name->getCString()); + return gFalse; + } + str->reset(); + while ((c = str->getChar()) != EOF) { + fputc(c, f); + } + str->close(); + fclose(f); + return gTrue; +} + +void PDFDoc::getLinks(Page *page) { + Object obj; + + links = new Links(page->getAnnots(&obj), catalog->getBaseURI()); + obj.free(); +} diff --git a/rosapps/smartpdf/poppler/poppler/PDFDoc.h b/rosapps/smartpdf/poppler/poppler/PDFDoc.h new file mode 100644 index 00000000000..3aaf8d64c3e --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PDFDoc.h @@ -0,0 +1,196 @@ +//======================================================================== +// +// PDFDoc.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef PDFDOC_H +#define PDFDOC_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include "XRef.h" +#include "Catalog.h" +#include "Page.h" +#include "Annot.h" + +class GooString; +class BaseStream; +class OutputDev; +class Links; +class LinkAction; +class LinkDest; +class Outline; + +//------------------------------------------------------------------------ +// PDFDoc +//------------------------------------------------------------------------ + +class PDFDoc { +public: + + PDFDoc(GooString *fileNameA, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + +#ifdef WIN32 + PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); +#endif + + PDFDoc(BaseStream *strA, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + ~PDFDoc(); + + // Was PDF document successfully opened? + GBool isOk() { return ok; } + + // Get the error code (if isOk() returns false). + int getErrorCode() { return errCode; } + + // Get file name. + GooString *getFileName() { return fileName; } + + // Get the xref table. + XRef *getXRef() { return xref; } + + // Get catalog. + Catalog *getCatalog() { return catalog; } + + // Get base stream. + BaseStream *getBaseStream() { return str; } + + // Get page parameters. + double getPageMediaWidth(int page) + { return catalog->getPage(page)->getMediaWidth(); } + double getPageMediaHeight(int page) + { return catalog->getPage(page)->getMediaHeight(); } + double getPageCropWidth(int page) + { return catalog->getPage(page)->getCropWidth(); } + double getPageCropHeight(int page) + { return catalog->getPage(page)->getCropHeight(); } + int getPageRotate(int page) + { return catalog->getPage(page)->getRotate(); } + + // Get number of pages. + int getNumPages() { return catalog->getNumPages(); } + + // Return the contents of the metadata stream, or NULL if there is + // no metadata. + GooString *readMetadata() { return catalog->readMetadata(); } + + // Return the structure tree root object. + Object *getStructTreeRoot() { return catalog->getStructTreeRoot(); } + + // Display a page. + void displayPage(OutputDev *out, int page, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, GBool doLinks, + GBool (*abortCheckCbk)(void *data) = NULL, + void *abortCheckCbkData = NULL, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, + void *annotDisplayDecideCbkData = NULL); + + // Display a range of pages. + void displayPages(OutputDev *out, int firstPage, int lastPage, + double hDPI, double vDPI, int rotate, + GBool useMediaBox, GBool crop, GBool doLinks, + GBool (*abortCheckCbk)(void *data) = NULL, + void *abortCheckCbkData = NULL, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, + void *annotDisplayDecideCbkData = NULL); + + // Display part of a page. + void displayPageSlice(OutputDev *out, int page, + double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, GBool doLinks, + int sliceX, int sliceY, int sliceW, int sliceH, + GBool (*abortCheckCbk)(void *data) = NULL, + void *abortCheckCbkData = NULL, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, + void *annotDisplayDecideCbkData = NULL); + + // Find a page, given its object ID. Returns page number, or 0 if + // not found. + int findPage(int num, int gen) { return catalog->findPage(num, gen); } + + // Returns the links for the current page, transferring ownership to + // the caller. + Links *takeLinks(); + + // Find a named destination. Returns the link destination, or + // NULL if is not a destination. + LinkDest *findDest(UGooString *name) + { return catalog->findDest(name); } + +#ifndef DISABLE_OUTLINE + // Return the outline object. + Outline *getOutline() { return outline; } +#endif + + // Is the file encrypted? + GBool isEncrypted() { return xref->isEncrypted(); } + + // Check various permissions. + GBool okToPrint(GBool ignoreOwnerPW = gFalse) + { return xref->okToPrint(ignoreOwnerPW); } + GBool okToPrintHighRes(GBool ignoreOwnerPW = gFalse) + { return xref->okToPrintHighRes(ignoreOwnerPW); } + GBool okToChange(GBool ignoreOwnerPW = gFalse) + { return xref->okToChange(ignoreOwnerPW); } + GBool okToCopy(GBool ignoreOwnerPW = gFalse) + { return xref->okToCopy(ignoreOwnerPW); } + GBool okToAddNotes(GBool ignoreOwnerPW = gFalse) + { return xref->okToAddNotes(ignoreOwnerPW); } + GBool okToFillForm(GBool ignoreOwnerPW = gFalse) + { return xref->okToFillForm(ignoreOwnerPW); } + GBool okToAccessibility(GBool ignoreOwnerPW = gFalse) + { return xref->okToAccessibility(ignoreOwnerPW); } + GBool okToAssemble(GBool ignoreOwnerPW = gFalse) + { return xref->okToAssemble(ignoreOwnerPW); } + + + // Is this document linearized? + GBool isLinearized(); + + // Return the document's Info dictionary (if any). + Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); } + Object *getDocInfoNF(Object *obj) { return xref->getDocInfoNF(obj); } + + // Return the PDF version specified by the file. + double getPDFVersion() { return pdfVersion; } + + // Save this file with another name. + GBool saveAs(GooString *name); + + // Return a pointer to the GUI (XPDFCore or WinPDFCore object). + void *getGUIData() { return guiData; } + +private: + + GBool setup(GooString *ownerPassword, GooString *userPassword); + GBool checkFooter(); + void checkHeader(); + GBool checkEncryption(GooString *ownerPassword, GooString *userPassword); + void getLinks(Page *page); + + GooString *fileName; + FILE *file; + BaseStream *str; + void *guiData; + double pdfVersion; + XRef *xref; + Catalog *catalog; + Links *links; +#ifndef DISABLE_OUTLINE + Outline *outline; +#endif + + GBool ok; + int errCode; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/PDFDocEncoding.cc b/rosapps/smartpdf/poppler/poppler/PDFDocEncoding.cc new file mode 100644 index 00000000000..89dc3828312 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PDFDocEncoding.cc @@ -0,0 +1,44 @@ +//======================================================================== +// +// PDFDocEncoding.h +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include "PDFDocEncoding.h" + +Unicode pdfDocEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 00 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 10 + 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, // 20 + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, // 30 + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, // 40 + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, // 50 + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, // 60 + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, // 70 + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, + 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, // 80 + 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, + 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, // 90 + 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, + 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, // a0 + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, // b0 + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, // c0 + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, // d0 + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, // e0 + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, // f0 + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; diff --git a/rosapps/smartpdf/poppler/poppler/PDFDocEncoding.h b/rosapps/smartpdf/poppler/poppler/PDFDocEncoding.h new file mode 100644 index 00000000000..3259d3e1064 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PDFDocEncoding.h @@ -0,0 +1,16 @@ +//======================================================================== +// +// PDFDocEncoding.h +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef PDFDOCENCODING_H +#define PDFDOCENCODING_H + +#include "CharTypes.h" + +extern Unicode pdfDocEncoding[256]; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/PSOutputDev.cc b/rosapps/smartpdf/poppler/poppler/PSOutputDev.cc new file mode 100644 index 00000000000..aa3f36a60be --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PSOutputDev.cc @@ -0,0 +1,4958 @@ +//======================================================================== +// +// PSOutputDev.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "poppler-config.h" +#include "GlobalParams.h" +#include "Object.h" +#include "Error.h" +#include "Function.h" +#include "Gfx.h" +#include "GfxState.h" +#include "GfxFont.h" +#include "UnicodeMap.h" +#include +#include +#include "Catalog.h" +#include "Page.h" +#include "Stream.h" +#include "Annot.h" +#include "PSOutputDev.h" +#include "UGooString.h" + +#ifdef MACOS +// needed for setting type/creator of MacOS files +#include "ICSupport.h" +#endif + +//------------------------------------------------------------------------ +// PostScript prolog and setup +//------------------------------------------------------------------------ + +// The '~' escapes mark prolog code that is emitted only in certain +// levels: +// +// ~[123][sn] +// ^ ^----- s=psLevel*Sep, n=psLevel* +// +----- 1=psLevel1*, 2=psLevel2*, 3=psLevel3* + +static char *prolog[] = { + "/xpdf 75 dict def xpdf begin", + "% PDF special state", + "/pdfDictSize 15 def", + "~1sn", + "/pdfStates 64 array def", + " 0 1 63 {", + " pdfStates exch pdfDictSize dict", + " dup /pdfStateIdx 3 index put", + " put", + " } for", + "~123sn", + "/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", + "~1sn", + "/pdfOpNames [", + " /pdfFill /pdfStroke /pdfLastFill /pdfLastStroke", + " /pdfTextMat /pdfFontSize /pdfCharSpacing /pdfTextRender", + " /pdfTextRise /pdfWordSpacing /pdfHorizScaling /pdfTextClipPath", + "] def", + "~123sn", + "/pdfStartPage {", + "~1sn", + " pdfStates 0 get begin", + "~23sn", + " pdfDictSize dict begin", + "~23n", + " /pdfFillCS [] def", + " /pdfFillXform {} def", + " /pdfStrokeCS [] def", + " /pdfStrokeXform {} def", + "~1n", + " /pdfFill 0 def", + " /pdfStroke 0 def", + "~1s", + " /pdfFill [0 0 0 1] def", + " /pdfStroke [0 0 0 1] def", + "~23sn", + " /pdfFill [0] def", + " /pdfStroke [0] def", + " /pdfFillOP false def", + " /pdfStrokeOP false def", + "~123sn", + " /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", + "~23s", + "% 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", + "~123sn", + "% PDF color state", + "~1n", + "/g { dup /pdfFill exch def setgray", + " /pdfLastFill true def /pdfLastStroke false def } def", + "/G { dup /pdfStroke exch def setgray", + " /pdfLastStroke true def /pdfLastFill false def } def", + "/fCol {", + " pdfLastFill not {", + " pdfFill setgray", + " /pdfLastFill true def /pdfLastStroke false def", + " } if", + "} def", + "/sCol {", + " pdfLastStroke not {", + " pdfStroke setgray", + " /pdfLastStroke true def /pdfLastFill false def", + " } if", + "} def", + "~1s", + "/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", + "/fCol {", + " pdfLastFill not {", + " pdfFill aload pop setcmykcolor", + " /pdfLastFill true def /pdfLastStroke false def", + " } if", + "} def", + "/sCol {", + " pdfLastStroke not {", + " pdfStroke aload pop setcmykcolor", + " /pdfLastStroke true def /pdfLastFill false def", + " } if", + "} def", + "~23n", + "/cs { /pdfFillXform exch def dup /pdfFillCS exch def", + " setcolorspace } def", + "/CS { /pdfStrokeXform exch def dup /pdfStrokeCS exch def", + " setcolorspace } def", + "/sc { pdfLastFill not { pdfFillCS setcolorspace } if", + " dup /pdfFill exch def aload pop pdfFillXform setcolor", + " /pdfLastFill true def /pdfLastStroke false def } def", + "/SC { pdfLastStroke not { pdfStrokeCS setcolorspace } if", + " dup /pdfStroke exch def aload pop pdfStrokeXform setcolor", + " /pdfLastStroke true def /pdfLastFill false def } def", + "/op { /pdfFillOP exch def", + " pdfLastFill { pdfFillOP setoverprint } if } def", + "/OP { /pdfStrokeOP exch def", + " pdfLastStroke { pdfStrokeOP setoverprint } if } def", + "/fCol {", + " pdfLastFill not {", + " pdfFillCS setcolorspace", + " pdfFill aload pop pdfFillXform setcolor", + " pdfFillOP setoverprint", + " /pdfLastFill true def /pdfLastStroke false def", + " } if", + "} def", + "/sCol {", + " pdfLastStroke not {", + " pdfStrokeCS setcolorspace", + " pdfStroke aload pop pdfStrokeXform setcolor", + " pdfStrokeOP setoverprint", + " /pdfLastStroke true def /pdfLastFill false def", + " } if", + "} def", + "~23s", + "/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", + "/op { /pdfFillOP exch def", + " pdfLastFill { pdfFillOP setoverprint } if } def", + "/OP { /pdfStrokeOP exch def", + " pdfLastStroke { pdfStrokeOP setoverprint } if } def", + "/fCol {", + " pdfLastFill not {", + " pdfFill aload length 4 eq {", + " setcmykcolor", + " }{", + " findcmykcustomcolor exch setcustomcolor", + " } ifelse", + " pdfFillOP setoverprint", + " /pdfLastFill true def /pdfLastStroke false def", + " } if", + "} def", + "/sCol {", + " pdfLastStroke not {", + " pdfStroke aload length 4 eq {", + " setcmykcolor", + " }{", + " findcmykcustomcolor exch setcustomcolor", + " } ifelse", + " pdfStrokeOP setoverprint", + " /pdfLastStroke true def /pdfLastFill false def", + " } if", + "} def", + "~123sn", + "% 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", + "~3sn", + "/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", + "~123sn", + "% graphics state operators", + "~1sn", + "/q {", + " gsave", + " pdfOpNames length 1 sub -1 0 { pdfOpNames exch get load } for", + " pdfStates pdfStateIdx 1 add get begin", + " pdfOpNames { exch def } forall", + "} def", + "/Q { end grestore } def", + "~23sn", + "/q { gsave pdfDictSize dict begin } def", + "/Q {", + " end grestore", + " /pdfLastFill where {", + " pop", + " pdfLastFill {", + " pdfFillOP setoverprint", + " } {", + " pdfStrokeOP setoverprint", + " } ifelse", + " } if", + "} def", + "~123sn", + "/cm { concat } def", + "/d { setdash } def", + "/i { setflat } def", + "/j { setlinejoin } def", + "/J { setlinecap } def", + "/M { setmiterlimit } def", + "/w { setlinewidth } 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 {", // awidthcharpath + " 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", // because stringwidth has to draw Type 3 chars + " 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", // because stringwidth has to draw Type 3 chars + " 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", // because stringwidth has to draw Type 3 chars + " 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", + "~1ns", + "% Level 1 image operators", + "~1n", + "/pdfIm1 {", + " /pdfImBuf1 4 index string def", + " { currentfile pdfImBuf1 readhexstring pop } image", + "} def", + "~1s", + "/pdfIm1Sep {", + " /pdfImBuf1 4 index string def", + " /pdfImBuf2 4 index string def", + " /pdfImBuf3 4 index string def", + " /pdfImBuf4 4 index string def", + " { currentfile pdfImBuf1 readhexstring pop }", + " { currentfile pdfImBuf2 readhexstring pop }", + " { currentfile pdfImBuf3 readhexstring pop }", + " { currentfile pdfImBuf4 readhexstring pop }", + " true 4 colorimage", + "} def", + "~1ns", + "/pdfImM1 {", + " fCol /pdfImBuf1 4 index 7 add 8 idiv string def", + " { currentfile pdfImBuf1 readhexstring pop } imagemask", + "} def", + "/pdfImM1a {", + " { 2 copy get exch 1 add exch } imagemask", + " pop pop", + "} def", + "~23sn", + "% Level 2 image operators", + "/pdfImBuf 100 string def", + "/pdfIm {", + " image", + " { currentfile pdfImBuf readline", + " not { pop exit } if", + " (%-EOD-) eq { exit } if } loop", + "} def", + "~23s", + "/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", + "~23sn", + "/pdfImM {", + " fCol imagemask", + " { currentfile pdfImBuf readline", + " not { pop exit } if", + " (%-EOD-) eq { exit } if } loop", + "} def", + "/pdfImClip {", + " gsave", + " 0 2 4 index length 1 sub {", + " dup 4 index exch 2 copy", + " get 5 index div put", + " 1 add 3 index exch 2 copy", + " get 3 index div put", + " } for", + " pop pop rectclip", + "} def", + "/pdfImClipEnd { grestore } def", + "~23n", + "% shading operators", + "/colordelta {", + " false 0 1 3 index length 1 sub {", + " dup 4 index exch get 3 index 3 2 roll get sub abs 0.004 gt {", + " pop true", + " } if", + " } for", + " exch pop exch pop", + "} def", + "/funcCol { func n array astore } def", + "/funcSH {", + " dup 0 eq {", + " true", + " } {", + " dup 6 eq {", + " false", + " } {", + " 4 index 4 index funcCol dup", + " 6 index 4 index funcCol dup", + " 3 1 roll colordelta 3 1 roll", + " 5 index 5 index funcCol dup", + " 3 1 roll colordelta 3 1 roll", + " 6 index 8 index funcCol dup", + " 3 1 roll colordelta 3 1 roll", + " colordelta or or or", + " } ifelse", + " } ifelse", + " {", + " 1 add", + " 4 index 3 index add 0.5 mul exch 4 index 3 index add 0.5 mul exch", + " 6 index 6 index 4 index 4 index 4 index funcSH", + " 2 index 6 index 6 index 4 index 4 index funcSH", + " 6 index 2 index 4 index 6 index 4 index funcSH", + " 5 3 roll 3 2 roll funcSH pop pop", + " } {", + " pop 3 index 2 index add 0.5 mul 3 index 2 index add 0.5 mul", + " funcCol sc", + " dup 4 index exch mat transform m", + " 3 index 3 index mat transform l", + " 1 index 3 index mat transform l", + " mat transform l pop pop h f*", + " } ifelse", + "} def", + "/axialCol {", + " dup 0 lt {", + " pop t0", + " } {", + " dup 1 gt {", + " pop t1", + " } {", + " dt mul t0 add", + " } ifelse", + " } ifelse", + " func n array astore", + "} def", + "/axialSH {", + " dup 0 eq {", + " true", + " } {", + " dup 8 eq {", + " false", + " } {", + " 2 index axialCol 2 index axialCol colordelta", + " } ifelse", + " } ifelse", + " {", + " 1 add 3 1 roll 2 copy add 0.5 mul", + " dup 4 3 roll exch 4 index axialSH", + " exch 3 2 roll axialSH", + " } {", + " pop 2 copy add 0.5 mul axialCol sc", + " exch dup dx mul x0 add exch dy mul y0 add", + " 3 2 roll dup dx mul x0 add exch dy mul y0 add", + " dx abs dy abs ge {", + " 2 copy yMin sub dy mul dx div add yMin m", + " yMax sub dy mul dx div add yMax l", + " 2 copy yMax sub dy mul dx div add yMax l", + " yMin sub dy mul dx div add yMin l", + " h f*", + " } {", + " exch 2 copy xMin sub dx mul dy div add xMin exch m", + " xMax sub dx mul dy div add xMax exch l", + " exch 2 copy xMax sub dx mul dy div add xMax exch l", + " xMin sub dx mul dy div add xMin exch l", + " h f*", + " } ifelse", + " } ifelse", + "} def", + "/radialCol {", + " dup t0 lt {", + " pop t0", + " } {", + " dup t1 gt {", + " pop t1", + " } if", + " } ifelse", + " func n array astore", + "} def", + "/radialSH {", + " dup 0 eq {", + " true", + " } {", + " dup 8 eq {", + " false", + " } {", + " 2 index dt mul t0 add radialCol", + " 2 index dt mul t0 add radialCol colordelta", + " } ifelse", + " } ifelse", + " {", + " 1 add 3 1 roll 2 copy add 0.5 mul", + " dup 4 3 roll exch 4 index radialSH", + " exch 3 2 roll radialSH", + " } {", + " pop 2 copy add 0.5 mul dt mul t0 add axialCol sc", + " exch dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add", + " 0 360 arc h", + " dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add", + " 0 360 arc h f*", + " } ifelse", + "} def", + "~123sn", + "end", + NULL +}; + +static char *cmapProlog[] = { + "/CIDInit /ProcSet findresource begin", + "10 dict begin", + " begincmap", + " /CMapType 1 def", + " /CMapName /Identity-H def", + " /CIDSystemInfo 3 dict dup begin", + " /Registry (Adobe) def", + " /Ordering (Identity) def", + " /Supplement 0 def", + " end def", + " 1 begincodespacerange", + " <0000> ", + " endcodespacerange", + " 0 usefont", + " 1 begincidrange", + " <0000> 0", + " endcidrange", + " endcmap", + " currentdict CMapName exch /CMap defineresource pop", + "end", + "10 dict begin", + " begincmap", + " /CMapType 1 def", + " /CMapName /Identity-V def", + " /CIDSystemInfo 3 dict dup begin", + " /Registry (Adobe) def", + " /Ordering (Identity) def", + " /Supplement 0 def", + " end def", + " /WMode 1 def", + " 1 begincodespacerange", + " <0000> ", + " endcodespacerange", + " 0 usefont", + " 1 begincidrange", + " <0000> 0", + " endcidrange", + " endcmap", + " currentdict CMapName exch /CMap defineresource pop", + "end", + "end", + NULL +}; + +//------------------------------------------------------------------------ +// Fonts +//------------------------------------------------------------------------ + +struct PSSubstFont { + char *psName; // PostScript name + double mWidth; // width of 'm' character +}; + +static char *psFonts[] = { + "Courier", + "Courier-Bold", + "Courier-Oblique", + "Courier-BoldOblique", + "Helvetica", + "Helvetica-Bold", + "Helvetica-Oblique", + "Helvetica-BoldOblique", + "Symbol", + "Times-Roman", + "Times-Bold", + "Times-Italic", + "Times-BoldItalic", + "ZapfDingbats", + NULL +}; + +static PSSubstFont psSubstFonts[] = { + {"Helvetica", 0.833}, + {"Helvetica-Oblique", 0.833}, + {"Helvetica-Bold", 0.889}, + {"Helvetica-BoldOblique", 0.889}, + {"Times-Roman", 0.788}, + {"Times-Italic", 0.722}, + {"Times-Bold", 0.833}, + {"Times-BoldItalic", 0.778}, + {"Courier", 0.600}, + {"Courier-Oblique", 0.600}, + {"Courier-Bold", 0.600}, + {"Courier-BoldOblique", 0.600} +}; + +// Encoding info for substitute 16-bit font +struct PSFont16Enc { + Ref fontID; + GooString *enc; +}; + +//------------------------------------------------------------------------ +// process colors +//------------------------------------------------------------------------ + +#define psProcessCyan 1 +#define psProcessMagenta 2 +#define psProcessYellow 4 +#define psProcessBlack 8 +#define psProcessCMYK 15 + +//------------------------------------------------------------------------ +// PSOutCustomColor +//------------------------------------------------------------------------ + +class PSOutCustomColor { +public: + + PSOutCustomColor(double cA, double mA, + double yA, double kA, GooString *nameA); + ~PSOutCustomColor(); + + double c, m, y, k; + GooString *name; + PSOutCustomColor *next; +}; + +PSOutCustomColor::PSOutCustomColor(double cA, double mA, + double yA, double kA, GooString *nameA) { + c = cA; + m = mA; + y = yA; + k = kA; + name = nameA; + next = NULL; +} + +PSOutCustomColor::~PSOutCustomColor() { + delete name; +} + +//------------------------------------------------------------------------ +// DeviceNRecoder +//------------------------------------------------------------------------ + +class DeviceNRecoder: public FilterStream { +public: + + DeviceNRecoder(Stream *strA, int widthA, int heightA, + GfxImageColorMap *colorMapA); + virtual ~DeviceNRecoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx++]; } + virtual int lookChar() + { return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx]; } + virtual GooString *getPSFilter(int psLevel, char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gTrue; } + virtual GBool isEncoder() { return gTrue; } + +private: + + GBool fillBuf(); + + int width, height; + GfxImageColorMap *colorMap; + Function *func; + ImageStream *imgStr; + int buf[gfxColorMaxComps]; + int pixelIdx; + int bufIdx; + int bufSize; +}; + +DeviceNRecoder::DeviceNRecoder(Stream *strA, int widthA, int heightA, + GfxImageColorMap *colorMapA): + FilterStream(strA) { + width = widthA; + height = heightA; + colorMap = colorMapA; + imgStr = NULL; + pixelIdx = 0; + bufIdx = gfxColorMaxComps; + bufSize = ((GfxDeviceNColorSpace *)colorMap->getColorSpace())-> + getAlt()->getNComps(); + func = ((GfxDeviceNColorSpace *)colorMap->getColorSpace())-> + getTintTransformFunc(); +} + +DeviceNRecoder::~DeviceNRecoder() { + if (imgStr) { + delete imgStr; + } +} + +void DeviceNRecoder::reset() { + imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); +} + +GBool DeviceNRecoder::fillBuf() { + Guchar pixBuf[gfxColorMaxComps]; + GfxColor color; + double x[gfxColorMaxComps], y[gfxColorMaxComps]; + int i; + + if (pixelIdx >= width * height) { + return gFalse; + } + imgStr->getPixel(pixBuf); + colorMap->getColor(pixBuf, &color); + for (i = 0; + i < ((GfxDeviceNColorSpace *)colorMap->getColorSpace())->getNComps(); + ++i) { + x[i] = colToDbl(color.c[i]); + } + func->transform(x, y); + for (i = 0; i < bufSize; ++i) { + buf[i] = (int)(y[i] * 255 + 0.5); + } + bufIdx = 0; + ++pixelIdx; + return gTrue; +} + +//------------------------------------------------------------------------ +// PSOutputDev +//------------------------------------------------------------------------ + +extern "C" { +typedef void (*SignalFunc)(int); +} + +static void outputToFile(void *stream, char *data, int len) { + fwrite(data, 1, len, (FILE *)stream); +} + +PSOutputDev::PSOutputDev(const char *fileName, XRef *xrefA, Catalog *catalog, + int firstPage, int lastPage, PSOutMode modeA, + int paperWidthA, int paperHeightA, GBool duplexA, + int imgLLXA, int imgLLYA, int imgURXA, int imgURYA, + GBool manualCtrlA) { + FILE *f; + PSFileType fileTypeA; + + underlayCbk = NULL; + underlayCbkData = NULL; + overlayCbk = NULL; + overlayCbkData = NULL; + + fontIDs = NULL; + fontFileIDs = NULL; + fontFileNames = NULL; + font16Enc = NULL; + xobjStack = NULL; + embFontList = NULL; + customColors = NULL; + haveTextClip = gFalse; + t3String = NULL; + + // open file or pipe + if (!strcmp(fileName, "-")) { + fileTypeA = psStdout; + f = stdout; + } else if (fileName[0] == '|') { + fileTypeA = psPipe; +#ifdef HAVE_POPEN +#ifndef WIN32 + signal(SIGPIPE, (SignalFunc)SIG_IGN); +#endif + if (!(f = popen(fileName + 1, "w"))) { + error(-1, "Couldn't run print command '%s'", fileName); + ok = gFalse; + return; + } +#else + error(-1, "Print commands are not supported ('%s')", fileName); + ok = gFalse; + return; +#endif + } else { + fileTypeA = psFile; + if (!(f = fopen(fileName, "w"))) { + error(-1, "Couldn't open PostScript file '%s'", fileName); + ok = gFalse; + return; + } + } + + init(outputToFile, f, fileTypeA, + xrefA, catalog, firstPage, lastPage, modeA, + imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, + paperWidthA, paperHeightA, duplexA); +} + +PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, + XRef *xrefA, Catalog *catalog, + int firstPage, int lastPage, PSOutMode modeA, + int paperWidthA, int paperHeightA, GBool duplexA, + int imgLLXA, int imgLLYA, int imgURXA, int imgURYA, + GBool manualCtrlA) { + underlayCbk = NULL; + underlayCbkData = NULL; + overlayCbk = NULL; + overlayCbkData = NULL; + + fontIDs = NULL; + fontFileIDs = NULL; + fontFileNames = NULL; + font16Enc = NULL; + xobjStack = NULL; + embFontList = NULL; + customColors = NULL; + haveTextClip = gFalse; + t3String = NULL; + + init(outputFuncA, outputStreamA, psGeneric, + xrefA, catalog, firstPage, lastPage, modeA, + imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, + paperWidthA, paperHeightA, duplexA); +} + +void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, + PSFileType fileTypeA, XRef *xrefA, Catalog *catalog, + int firstPage, int lastPage, PSOutMode modeA, + int imgLLXA, int imgLLYA, int imgURXA, int imgURYA, + GBool manualCtrlA, int paperWidthA, int paperHeightA, + GBool duplexA) { + Page *page; + PDFRectangle *box; + + // initialize + ok = gTrue; + outputFunc = outputFuncA; + outputStream = outputStreamA; + fileType = fileTypeA; + xref = xrefA; + level = globalParams->getPSLevel(); + mode = modeA; + paperWidth = paperWidthA; + paperHeight = paperHeightA; + imgLLX = imgLLXA; + imgLLY = imgLLYA; + imgURX = imgURXA; + imgURY = imgURYA; + if (paperWidth < 0 || paperHeight < 0) { + // this check is needed in case the document has zero pages + if (firstPage > 0 && firstPage <= catalog->getNumPages()) { + page = catalog->getPage(firstPage); + paperWidth = (int)ceil(page->getMediaWidth()); + paperHeight = (int)ceil(page->getMediaHeight()); + } else { + paperWidth = 1; + paperHeight = 1; + } + } + if (imgLLX == 0 && imgURX == 0 && imgLLY == 0 && imgURY == 0) { + globalParams->getPSImageableArea(&imgLLX, &imgLLY, &imgURX, &imgURY); + if (imgURX <= 0 || imgURY <= 0) { + imgLLX = imgLLY = 0; + imgURX = paperWidth; + imgURY = paperHeight; + } + } + manualCtrl = manualCtrlA; + if (mode == psModeForm) { + lastPage = firstPage; + } + processColors = 0; + inType3Char = gFalse; + +#if OPI_SUPPORT + // initialize OPI nesting levels + opi13Nest = 0; + opi20Nest = 0; +#endif + + tx0 = ty0 = 0; + xScale0 = yScale0 = 0; + rotate0 = -1; + clipLLX0 = clipLLY0 = 0; + clipURX0 = clipURY0 = -1; + + // initialize fontIDs, fontFileIDs, and fontFileNames lists + fontIDSize = 64; + fontIDLen = 0; + fontIDs = (Ref *)gmallocn(fontIDSize, sizeof(Ref)); + fontFileIDSize = 64; + fontFileIDLen = 0; + fontFileIDs = (Ref *)gmallocn(fontFileIDSize, sizeof(Ref)); + fontFileNameSize = 64; + fontFileNameLen = 0; + fontFileNames = (GooString **)gmallocn(fontFileNameSize, sizeof(GooString *)); + psFileNames = (GooString **)gmallocn(fontFileNameSize, sizeof(GooString *)); + nextTrueTypeNum = 0; + font16EncLen = 0; + font16EncSize = 0; + + xobjStack = new GooList(); + numSaves = 0; + numTilingPatterns = 0; + nextFunc = 0; + + // initialize embedded font resource comment list + embFontList = new GooString(); + + if (!manualCtrl) { + // this check is needed in case the document has zero pages + if (firstPage > 0 && firstPage <= catalog->getNumPages()) { + writeHeader(firstPage, lastPage, + catalog->getPage(firstPage)->getMediaBox(), + catalog->getPage(firstPage)->getCropBox(), + catalog->getPage(firstPage)->getRotate()); + } else { + box = new PDFRectangle(0, 0, 1, 1); + writeHeader(firstPage, lastPage, box, box, 0); + delete box; + } + if (mode != psModeForm) { + writePS("%%BeginProlog\n"); + } + writeXpdfProcset(); + if (mode != psModeForm) { + writePS("%%EndProlog\n"); + writePS("%%BeginSetup\n"); + } + writeDocSetup(catalog, firstPage, lastPage, duplexA); + if (mode != psModeForm) { + writePS("%%EndSetup\n"); + } + } + + // initialize sequential page number + seqPage = 1; +} + +PSOutputDev::~PSOutputDev() { + PSOutCustomColor *cc; + int i; + + if (ok) { + if (!manualCtrl) { + writePS("%%Trailer\n"); + writeTrailer(); + if (mode != psModeForm) { + writePS("%%EOF\n"); + } + } + if (fileType == psFile) { +#ifdef MACOS + ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle); +#endif + fclose((FILE *)outputStream); + } +#ifdef HAVE_POPEN + else if (fileType == psPipe) { + pclose((FILE *)outputStream); +#ifndef WIN32 + signal(SIGPIPE, (SignalFunc)SIG_DFL); +#endif + } +#endif + } + if (embFontList) { + delete embFontList; + } + if (fontIDs) { + gfree(fontIDs); + } + if (fontFileIDs) { + gfree(fontFileIDs); + } + if (fontFileNames) { + for (i = 0; i < fontFileNameLen; ++i) { + delete fontFileNames[i]; + } + gfree(fontFileNames); + } + if (psFileNames) { + for (i = 0; i < fontFileNameLen; ++i) { + if (psFileNames[i]) + delete psFileNames[i]; + } + gfree(psFileNames); + } + if (font16Enc) { + for (i = 0; i < font16EncLen; ++i) { + delete font16Enc[i].enc; + } + gfree(font16Enc); + } + if (xobjStack) { + delete xobjStack; + } + while (customColors) { + cc = customColors; + customColors = cc->next; + delete cc; + } +} + +void PSOutputDev::writeHeader(int firstPage, int lastPage, + PDFRectangle *mediaBox, PDFRectangle *cropBox, + int pageRotate) { + double x1, y1, x2, y2; + + switch (mode) { + case psModePS: + writePS("%!PS-Adobe-3.0\n"); + writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); + writePSFmt("%%%%LanguageLevel: %d\n", + (level == psLevel1 || level == psLevel1Sep) ? 1 : + (level == psLevel2 || level == psLevel2Sep) ? 2 : 3); + if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { + writePS("%%DocumentProcessColors: (atend)\n"); + writePS("%%DocumentCustomColors: (atend)\n"); + } + writePS("%%DocumentSuppliedResources: (atend)\n"); + writePSFmt("%%%%DocumentMedia: plain %d %d 0 () ()\n", + paperWidth, paperHeight); + writePSFmt("%%%%BoundingBox: 0 0 %d %d\n", paperWidth, paperHeight); + writePSFmt("%%%%Pages: %d\n", lastPage - firstPage + 1); + writePS("%%EndComments\n"); + writePS("%%BeginDefaults\n"); + writePS("%%PageMedia: plain\n"); + writePS("%%EndDefaults\n"); + break; + case psModeEPS: + writePS("%!PS-Adobe-3.0 EPSF-3.0\n"); + writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); + writePSFmt("%%%%LanguageLevel: %d\n", + (level == psLevel1 || level == psLevel1Sep) ? 1 : + (level == psLevel2 || level == psLevel2Sep) ? 2 : 3); + if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { + writePS("%%DocumentProcessColors: (atend)\n"); + writePS("%%DocumentCustomColors: (atend)\n"); + } + epsX1 = cropBox->x1; + epsY1 = cropBox->y1; + epsX2 = cropBox->x2; + epsY2 = cropBox->y2; + if (pageRotate == 0 || pageRotate == 180) { + x1 = epsX1; + y1 = epsY1; + x2 = epsX2; + y2 = epsY2; + } else { // pageRotate == 90 || pageRotate == 270 + x1 = 0; + y1 = 0; + x2 = epsY2 - epsY1; + y2 = epsX2 - epsX1; + } + writePSFmt("%%%%BoundingBox: %d %d %d %d\n", + (int)floor(x1), (int)floor(y1), (int)ceil(x2), (int)ceil(y2)); + if (floor(x1) != ceil(x1) || floor(y1) != ceil(y1) || + floor(x2) != ceil(x2) || floor(y2) != ceil(y2)) { + writePSFmt("%%%%HiResBoundingBox: %g %g %g %g\n", x1, y1, x2, y2); + } + writePS("%%DocumentSuppliedResources: (atend)\n"); + writePS("%%EndComments\n"); + break; + case psModeForm: + writePS("%!PS-Adobe-3.0 Resource-Form\n"); + writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); + writePSFmt("%%%%LanguageLevel: %d\n", + (level == psLevel1 || level == psLevel1Sep) ? 1 : + (level == psLevel2 || level == psLevel2Sep) ? 2 : 3); + if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { + writePS("%%DocumentProcessColors: (atend)\n"); + writePS("%%DocumentCustomColors: (atend)\n"); + } + writePS("%%DocumentSuppliedResources: (atend)\n"); + writePS("%%EndComments\n"); + writePS("32 dict dup begin\n"); + writePSFmt("/BBox [%d %d %d %d] def\n", + (int)floor(mediaBox->x1), (int)floor(mediaBox->y1), + (int)ceil(mediaBox->x2), (int)ceil(mediaBox->y2)); + writePS("/FormType 1 def\n"); + writePS("/Matrix [1 0 0 1 0 0] def\n"); + break; + } +} + +void PSOutputDev::writeXpdfProcset() { + GBool lev1, lev2, lev3, sep, nonSep; + char **p; + char *q; + + writePSFmt("%%%%BeginResource: procset xpdf %s 0\n", xpdfVersion); + lev1 = lev2 = lev3 = sep = nonSep = gTrue; + for (p = prolog; *p; ++p) { + if ((*p)[0] == '~') { + lev1 = lev2 = lev3 = sep = nonSep = gFalse; + for (q = *p + 1; *q; ++q) { + switch (*q) { + case '1': lev1 = gTrue; break; + case '2': lev2 = gTrue; break; + case '3': lev3 = gTrue; break; + case 's': sep = gTrue; break; + case 'n': nonSep = gTrue; break; + } + } + } else if ((level == psLevel1 && lev1 && nonSep) || + (level == psLevel1Sep && lev1 && sep) || + (level == psLevel2 && lev2 && nonSep) || + (level == psLevel2Sep && lev2 && sep) || + (level == psLevel3 && lev3 && nonSep) || + (level == psLevel3Sep && lev3 && sep)) { + writePSFmt("%s\n", *p); + } + } + writePS("%%EndResource\n"); + + if (level >= psLevel3) { + for (p = cmapProlog; *p; ++p) { + writePSFmt("%s\n", *p); + } + } +} + +void PSOutputDev::writeDocSetup(Catalog *catalog, + int firstPage, int lastPage, + GBool duplexA) { + Page *page; + Dict *resDict; + Annots *annots; + Object obj1, obj2; + int pg, i; + + if (mode == psModeForm) { + // swap the form and xpdf dicts + writePS("xpdf end begin dup begin\n"); + } else { + writePS("xpdf begin\n"); + } + for (pg = firstPage; pg <= lastPage; ++pg) { + page = catalog->getPage(pg); + if ((resDict = page->getResourceDict())) { + setupResources(resDict); + } + annots = new Annots(xref, catalog, page->getAnnots(&obj1)); + obj1.free(); + for (i = 0; i < annots->getNumAnnots(); ++i) { + if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) { + obj1.streamGetDict()->lookup("Resources", &obj2); + if (obj2.isDict()) { + setupResources(obj2.getDict()); + } + obj2.free(); + } + obj1.free(); + } + delete annots; + } + if (mode != psModeForm) { + if (mode != psModeEPS && !manualCtrl) { + writePSFmt("%d %d %s pdfSetup\n", + paperWidth, paperHeight, duplexA ? "true" : "false"); + } +#if OPI_SUPPORT + if (globalParams->getPSOPI()) { + writePS("/opiMatrix matrix currentmatrix def\n"); + } +#endif + } +} + +void PSOutputDev::writePageTrailer() { + if (mode != psModeForm) { + writePS("pdfEndPage\n"); + } +} + +void PSOutputDev::writeTrailer() { + PSOutCustomColor *cc; + + if (mode == psModeForm) { + writePS("/Foo exch /Form defineresource pop\n"); + } else { + writePS("end\n"); + writePS("%%DocumentSuppliedResources:\n"); + writePS(embFontList->getCString()); + if (level == psLevel1Sep || level == psLevel2Sep || + level == psLevel3Sep) { + writePS("%%DocumentProcessColors:"); + if (processColors & psProcessCyan) { + writePS(" Cyan"); + } + if (processColors & psProcessMagenta) { + writePS(" Magenta"); + } + if (processColors & psProcessYellow) { + writePS(" Yellow"); + } + if (processColors & psProcessBlack) { + writePS(" Black"); + } + writePS("\n"); + writePS("%%DocumentCustomColors:"); + for (cc = customColors; cc; cc = cc->next) { + writePSFmt(" (%s)", cc->name->getCString()); + } + writePS("\n"); + writePS("%%CMYKCustomColor:\n"); + for (cc = customColors; cc; cc = cc->next) { + writePSFmt("%%%%+ %g %g %g %g (%s)\n", + cc->c, cc->m, cc->y, cc->k, cc->name->getCString()); + } + } + } +} + +void PSOutputDev::setupResources(Dict *resDict) { + Object xObjDict, xObjRef, xObj, patDict, patRef, pat, resObj; + Ref ref0, ref1; + GBool skip; + int i, j; + + setupFonts(resDict); + setupImages(resDict); + + //----- recursively scan XObjects + resDict->lookup("XObject", &xObjDict); + if (xObjDict.isDict()) { + for (i = 0; i < xObjDict.dictGetLength(); ++i) { + + // avoid infinite recursion on XObjects + skip = gFalse; + if ((xObjDict.dictGetValNF(i, &xObjRef)->isRef())) { + ref0 = xObjRef.getRef(); + for (j = 0; j < xobjStack->getLength(); ++j) { + ref1 = *(Ref *)xobjStack->get(j); + if (ref1.num == ref0.num && ref1.gen == ref0.gen) { + skip = gTrue; + break; + } + } + if (!skip) { + xobjStack->append(&ref0); + } + } + if (!skip) { + + // process the XObject's resource dictionary + xObjDict.dictGetVal(i, &xObj); + if (xObj.isStream()) { + xObj.streamGetDict()->lookup("Resources", &resObj); + if (resObj.isDict()) { + setupResources(resObj.getDict()); + } + resObj.free(); + } + xObj.free(); + } + + if (xObjRef.isRef() && !skip) { + xobjStack->del(xobjStack->getLength() - 1); + } + xObjRef.free(); + } + } + xObjDict.free(); + + //----- recursively scan Patterns + resDict->lookup("Pattern", &patDict); + if (patDict.isDict()) { + inType3Char = gTrue; + for (i = 0; i < patDict.dictGetLength(); ++i) { + + // avoid infinite recursion on Patterns + skip = gFalse; + if ((patDict.dictGetValNF(i, &patRef)->isRef())) { + ref0 = patRef.getRef(); + for (j = 0; j < xobjStack->getLength(); ++j) { + ref1 = *(Ref *)xobjStack->get(j); + if (ref1.num == ref0.num && ref1.gen == ref0.gen) { + skip = gTrue; + break; + } + } + if (!skip) { + xobjStack->append(&ref0); + } + } + if (!skip) { + + // process the Pattern's resource dictionary + patDict.dictGetVal(i, &pat); + if (pat.isStream()) { + pat.streamGetDict()->lookup("Resources", &resObj); + if (resObj.isDict()) { + setupResources(resObj.getDict()); + } + resObj.free(); + } + pat.free(); + } + + if (patRef.isRef() && !skip) { + xobjStack->del(xobjStack->getLength() - 1); + } + patRef.free(); + } + inType3Char = gFalse; + } + patDict.free(); +} + +void PSOutputDev::setupFonts(Dict *resDict) { + Object obj1, obj2; + Ref r; + GfxFontDict *gfxFontDict; + GfxFont *font; + int i; + + gfxFontDict = NULL; + resDict->lookupNF("Font", &obj1); + if (obj1.isRef()) { + obj1.fetch(xref, &obj2); + if (obj2.isDict()) { + r = obj1.getRef(); + gfxFontDict = new GfxFontDict(xref, &r, obj2.getDict()); + } + obj2.free(); + } else if (obj1.isDict()) { + gfxFontDict = new GfxFontDict(xref, NULL, obj1.getDict()); + } + if (gfxFontDict) { + for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { + if ((font = gfxFontDict->getFont(i))) { + setupFont(font, resDict); + } + } + delete gfxFontDict; + } + obj1.free(); +} + +void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) { + Ref fontFileID; + GooString *name; + PSFontParam *fontParam; + GooString *psName; + char type3Name[64], buf[16]; + GBool subst; + UnicodeMap *uMap; + char *charName; + double xs, ys; + int code; + double w1, w2; + double *fm; + int i, j; + DisplayFontParam *dfp; + + // check if font is already set up + for (i = 0; i < fontIDLen; ++i) { + if (fontIDs[i].num == font->getID()->num && + fontIDs[i].gen == font->getID()->gen) { + return; + } + } + + // add entry to fontIDs list + if (fontIDLen >= fontIDSize) { + fontIDSize += 64; + fontIDs = (Ref *)greallocn(fontIDs, fontIDSize, sizeof(Ref)); + } + fontIDs[fontIDLen++] = *font->getID(); + + xs = ys = 1; + subst = gFalse; + + // check for resident 8-bit font + if (font->getName() && + (fontParam = globalParams->getPSFont(font->getName()))) { + psName = new GooString(fontParam->psFontName->getCString()); + + // check for embedded Type 1 font + } else if (globalParams->getPSEmbedType1() && + font->getType() == fontType1 && + font->getEmbeddedFontID(&fontFileID)) { + psName = filterPSName(font->getEmbeddedFontName()); + setupEmbeddedType1Font(&fontFileID, psName); + + // check for embedded Type 1C font + } else if (globalParams->getPSEmbedType1() && + font->getType() == fontType1C && + font->getEmbeddedFontID(&fontFileID)) { + psName = filterPSName(font->getEmbeddedFontName()); + setupEmbeddedType1CFont(font, &fontFileID, psName); + + // check for external Type 1 font file + } else if (globalParams->getPSEmbedType1() && + font->getType() == fontType1 && + font->getExtFontFile()) { + // this assumes that the PS font name matches the PDF font name + psName = font->getName()->copy(); + setupExternalType1Font(font->getExtFontFile(), psName); + + // check for embedded TrueType font + } else if (globalParams->getPSEmbedTrueType() && + font->getType() == fontTrueType && + font->getEmbeddedFontID(&fontFileID)) { + psName = filterPSName(font->getEmbeddedFontName()); + setupEmbeddedTrueTypeFont(font, &fontFileID, psName); + + // check for external TrueType font file + } else if (globalParams->getPSEmbedTrueType() && + font->getType() == fontTrueType && + font->getExtFontFile()) { + psName = setupExternalTrueTypeFont(font); + + // check for embedded CID PostScript font + } else if (globalParams->getPSEmbedCIDPostScript() && + font->getType() == fontCIDType0C && + font->getEmbeddedFontID(&fontFileID)) { + psName = filterPSName(font->getEmbeddedFontName()); + setupEmbeddedCIDType0Font(font, &fontFileID, psName); + + // check for embedded CID TrueType font + } else if (globalParams->getPSEmbedCIDTrueType() && + font->getType() == fontCIDType2 && + font->getEmbeddedFontID(&fontFileID)) { + psName = filterPSName(font->getEmbeddedFontName()); + setupEmbeddedCIDTrueTypeFont(font, &fontFileID, psName, gTrue); + + } else if (font->getType() == fontType3) { + sprintf(type3Name, "T3_%d_%d", + font->getID()->num, font->getID()->gen); + psName = new GooString(type3Name); + setupType3Font(font, psName, parentResDict); + + // check for external CID TrueType font file + } else if (globalParams->getPSEmbedCIDTrueType() && + font->getType() == fontCIDType2 && + font->getExtFontFile()) { + psName = setupExternalCIDTrueTypeFont(font, font->getExtFontFile()); + + // do 8-bit font substitution + } else if (!font->isCIDFont()) { + subst = gTrue; + name = font->getName(); + psName = NULL; + if (name) { + for (i = 0; psFonts[i]; ++i) { + if (name->cmp(psFonts[i]) == 0) { + psName = new GooString(psFonts[i]); + break; + } + } + } + if (!psName) { + if (font->isFixedWidth()) { + i = 8; + } else if (font->isSerif()) { + i = 4; + } else { + i = 0; + } + if (font->isBold()) { + i += 2; + } + if (font->isItalic()) { + i += 1; + } + psName = new GooString(psSubstFonts[i].psName); + for (code = 0; code < 256; ++code) { + if ((charName = ((Gfx8BitFont *)font)->getCharName(code)) && + charName[0] == 'm' && charName[1] == '\0') { + break; + } + } + if (code < 256) { + w1 = ((Gfx8BitFont *)font)->getWidth(code); + } else { + w1 = 0; + } + w2 = psSubstFonts[i].mWidth; + xs = w1 / w2; + if (xs < 0.1) { + xs = 1; + } + if (font->getType() == fontType3) { + // This is a hack which makes it possible to substitute for some + // Type 3 fonts. The problem is that it's impossible to know what + // the base coordinate system used in the font is without actually + // rendering the font. + ys = xs; + fm = font->getFontMatrix(); + if (fm[0] != 0) { + ys *= fm[3] / fm[0]; + } + } else { + ys = 1; + } + } + + // do 16-bit font substitution + } else if ((fontParam = globalParams-> + getPSFont16(font->getName(), + ((GfxCIDFont *)font)->getCollection(), + font->getWMode()))) { + subst = gTrue; + psName = fontParam->psFontName->copy(); + if (font16EncLen >= font16EncSize) { + font16EncSize += 16; + font16Enc = (PSFont16Enc *)greallocn(font16Enc, + font16EncSize, sizeof(PSFont16Enc)); + } + font16Enc[font16EncLen].fontID = *font->getID(); + font16Enc[font16EncLen].enc = fontParam->encoding->copy(); + if ((uMap = globalParams->getUnicodeMap(font16Enc[font16EncLen].enc))) { + uMap->decRefCnt(); + ++font16EncLen; + } else { + error(-1, "Couldn't find Unicode map for 16-bit font encoding '%s'", + font16Enc[font16EncLen].enc->getCString()); + } + + // try the display font for embedding + } else if (globalParams->getPSEmbedCIDTrueType() && + ((GfxCIDFont *)font)->getCollection() && + (dfp = globalParams-> + getDisplayFont(font)) && + dfp->kind == displayFontTT) { + psName = setupExternalCIDTrueTypeFont(font, dfp->tt.fileName, dfp->tt.faceIndex); + + // give up - can't do anything with this font + } else { + error(-1, "Couldn't find a font to substitute for '%s' ('%s' character collection)", + font->getName() ? font->getName()->getCString() : "(unnamed)", + ((GfxCIDFont *)font)->getCollection() + ? ((GfxCIDFont *)font)->getCollection()->getCString() + : "(unknown)"); + return; + } + + // generate PostScript code to set up the font + if (font->isCIDFont()) { + if (level == psLevel3 || level == psLevel3Sep) { + writePSFmt("/F%d_%d /%s %d pdfMakeFont16L3\n", + font->getID()->num, font->getID()->gen, psName->getCString(), + font->getWMode()); + } else { + writePSFmt("/F%d_%d /%s %d pdfMakeFont16\n", + font->getID()->num, font->getID()->gen, psName->getCString(), + font->getWMode()); + } + } else { + writePSFmt("/F%d_%d /%s %g %g\n", + font->getID()->num, font->getID()->gen, psName->getCString(), + xs, ys); + for (i = 0; i < 256; i += 8) { + writePSFmt((i == 0) ? "[ " : " "); + for (j = 0; j < 8; ++j) { + if (font->getType() == fontTrueType && + !subst && + !((Gfx8BitFont *)font)->getHasEncoding()) { + sprintf(buf, "c%02x", i+j); + charName = buf; + } else { + charName = ((Gfx8BitFont *)font)->getCharName(i+j); + // this is a kludge for broken PDF files that encode char 32 + // as .notdef + if (i+j == 32 && charName && !strcmp(charName, ".notdef")) { + charName = "space"; + } + } + writePS("/"); + writePSName(charName ? charName : (char *)".notdef"); + // the empty name is legal in PDF and PostScript, but PostScript + // uses a double-slash (//...) for "immediately evaluated names", + // so we need to add a space character here + if (charName && !charName[0]) { + writePS(" "); + } + } + writePS((i == 256-8) ? (char *)"]\n" : (char *)"\n"); + } + writePS("pdfMakeFont\n"); + } + + delete psName; +} + +void PSOutputDev::setupEmbeddedType1Font(Ref *id, GooString *psName) { + static char hexChar[17] = "0123456789abcdef"; + Object refObj, strObj, obj1, obj2, obj3; + Dict *dict; + int length1, length2, length3; + int c; + int start[4]; + GBool binMode; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) + return; + } + + // add entry to fontFileIDs list + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)greallocn(fontFileIDs, fontFileIDSize, sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + + // get the font stream and info + refObj.initRef(id->num, id->gen); + refObj.fetch(xref, &strObj); + refObj.free(); + if (!strObj.isStream()) { + error(-1, "Embedded font file object is not a stream"); + goto err1; + } + if (!(dict = strObj.streamGetDict())) { + error(-1, "Embedded font stream is missing its dictionary"); + goto err1; + } + dict->lookup("Length1", &obj1); + dict->lookup("Length2", &obj2); + dict->lookup("Length3", &obj3); + if (!obj1.isInt() || !obj2.isInt() || !obj3.isInt()) { + error(-1, "Missing length fields in embedded font stream dictionary"); + obj1.free(); + obj2.free(); + obj3.free(); + goto err1; + } + length1 = obj1.getInt(); + length2 = obj2.getInt(); + length3 = obj3.getInt(); + obj1.free(); + obj2.free(); + obj3.free(); + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // copy ASCII portion of font + strObj.streamReset(); + for (i = 0; i < length1 && (c = strObj.streamGetChar()) != EOF; ++i) { + writePSChar(c); + } + + // figure out if encrypted portion is binary or ASCII + binMode = gFalse; + for (i = 0; i < 4; ++i) { + start[i] = strObj.streamGetChar(); + if (start[i] == EOF) { + error(-1, "Unexpected end of file in embedded font stream"); + goto err1; + } + if (!((start[i] >= '0' && start[i] <= '9') || + (start[i] >= 'A' && start[i] <= 'F') || + (start[i] >= 'a' && start[i] <= 'f'))) + binMode = gTrue; + } + + // convert binary data to ASCII + if (binMode) { + for (i = 0; i < 4; ++i) { + writePSChar(hexChar[(start[i] >> 4) & 0x0f]); + writePSChar(hexChar[start[i] & 0x0f]); + } +#if 0 // this causes trouble for various PostScript printers + // if Length2 is incorrect (too small), font data gets chopped, so + // we take a few extra characters from the trailer just in case + length2 += length3 >= 8 ? 8 : length3; +#endif + while (i < length2) { + if ((c = strObj.streamGetChar()) == EOF) { + break; + } + writePSChar(hexChar[(c >> 4) & 0x0f]); + writePSChar(hexChar[c & 0x0f]); + if (++i % 32 == 0) { + writePSChar('\n'); + } + } + if (i % 32 > 0) { + writePSChar('\n'); + } + + // already in ASCII format -- just copy it + } else { + for (i = 0; i < 4; ++i) { + writePSChar(start[i]); + } + for (i = 4; i < length2; ++i) { + if ((c = strObj.streamGetChar()) == EOF) { + break; + } + writePSChar(c); + } + } + + // write padding and "cleartomark" + for (i = 0; i < 8; ++i) { + writePS("00000000000000000000000000000000" + "00000000000000000000000000000000\n"); + } + writePS("cleartomark\n"); + + // ending comment + writePS("%%EndResource\n"); + + err1: + strObj.streamClose(); + strObj.free(); +} + +//~ This doesn't handle .pfb files or binary eexec data (which only +//~ happens in pfb files?). +void PSOutputDev::setupExternalType1Font(GooString *fileName, GooString *psName) { + FILE *fontFile; + int c; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileNameLen; ++i) { + if (!fontFileNames[i]->cmp(fileName)) { + return; + } + } + + // add entry to fontFileNames list + if (fontFileNameLen >= fontFileNameSize) { + fontFileNameSize += 64; + fontFileNames = (GooString **)greallocn(fontFileNames, + fontFileNameSize, sizeof(GooString *)); + psFileNames = (GooString **)greallocn(psFileNames, + fontFileNameSize, sizeof(GooString *)); + } + fontFileNames[fontFileNameLen] = fileName->copy(); + psFileNames[fontFileNameLen] = psName->copy(); + fontFileNameLen++; + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // copy the font file + if (!(fontFile = fopen(fileName->getCString(), "rb"))) { + error(-1, "Couldn't open external font file"); + return; + } + while ((c = fgetc(fontFile)) != EOF) { + writePSChar(c); + } + fclose(fontFile); + + // ending comment + writePS("%%EndResource\n"); +} + +void PSOutputDev::setupEmbeddedType1CFont(GfxFont *font, Ref *id, + GooString *psName) { + char *fontBuf; + int fontLen; + FoFiType1C *ffT1C; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) + return; + } + + // add entry to fontFileIDs list + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)greallocn(fontFileIDs, fontFileIDSize, sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // convert it to a Type 1 font + fontBuf = font->readEmbFontFile(xref, &fontLen); + if ((ffT1C = FoFiType1C::make(fontBuf, fontLen))) { + ffT1C->convertToType1(NULL, gTrue, outputFunc, outputStream); + delete ffT1C; + } + gfree(fontBuf); + + // ending comment + writePS("%%EndResource\n"); +} + +void PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, + GooString *psName) { + char unique[32]; + char *fontBuf; + int fontLen; + FoFiTrueType *ffTT; + Gushort *codeToGID; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) { + sprintf(unique, "_%d", nextTrueTypeNum++); + psName->append(unique); + break; + } + } + + // add entry to fontFileIDs list + if (i == fontFileIDLen) { + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)greallocn(fontFileIDs, fontFileIDSize, sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + } + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // convert it to a Type 42 font + fontBuf = font->readEmbFontFile(xref, &fontLen); + if ((ffTT = FoFiTrueType::make(fontBuf, fontLen))) { + codeToGID = ((Gfx8BitFont *)font)->getCodeToGIDMap(ffTT); + ffTT->convertToType42(psName->getCString(), + ((Gfx8BitFont *)font)->getHasEncoding() + ? ((Gfx8BitFont *)font)->getEncoding() + : (char **)NULL, + codeToGID, outputFunc, outputStream); + gfree(codeToGID); + delete ffTT; + } + gfree(fontBuf); + + // ending comment + writePS("%%EndResource\n"); +} + +GooString *PSOutputDev::setupExternalTrueTypeFont(GfxFont *font) { + GooString *fileName; + char *fontBuf; + int fontLen; + FoFiTrueType *ffTT; + Gushort *codeToGID; + GooString *psName; + int i; + + // check if font is already embedded + fileName = font->getExtFontFile(); + for (i = 0; i < fontFileNameLen; ++i) { + if (!fontFileNames[i]->cmp(fileName)) { + return psFileNames[i]->copy(); + } + } + + psName = filterPSName(font->getName()); + // add entry to fontFileNames list + if (i == fontFileNameLen) { + if (fontFileNameLen >= fontFileNameSize) { + fontFileNameSize += 64; + fontFileNames = + (GooString **)greallocn(fontFileNames, + fontFileNameSize, sizeof(GooString *)); + psFileNames = + (GooString **)greallocn(psFileNames, + fontFileNameSize, sizeof(GooString *)); + } + } + fontFileNames[fontFileNameLen] = fileName->copy(); + psFileNames[fontFileNameLen] = psName->copy(); + fontFileNameLen++; + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // convert it to a Type 42 font + fontBuf = font->readExtFontFile(&fontLen); + if ((ffTT = FoFiTrueType::make(fontBuf, fontLen))) { + codeToGID = ((Gfx8BitFont *)font)->getCodeToGIDMap(ffTT); + ffTT->convertToType42(psName->getCString(), + ((Gfx8BitFont *)font)->getHasEncoding() + ? ((Gfx8BitFont *)font)->getEncoding() + : (char **)NULL, + codeToGID, outputFunc, outputStream); + delete ffTT; + gfree(codeToGID); + } + gfree(fontBuf); + + // ending comment + writePS("%%EndResource\n"); + return psName; +} + +GooString *PSOutputDev::setupExternalCIDTrueTypeFont(GfxFont *font, GooString *fileName, int faceIndex) { +// char *fontBuf; +// int fontLen; + FoFiTrueType *ffTT; + Gushort *codeToGID; + GooString *psName; + int i; + GooString *myFileName; + + myFileName = fileName->copy(); + if (faceIndex > 0) { + char tmp[32]; + sprintf(tmp, ",%d", faceIndex); + myFileName->append(tmp); + } + // check if font is already embedded + for (i = 0; i < fontFileNameLen; ++i) { + if (!fontFileNames[i]->cmp(myFileName)) { + delete myFileName; + return psFileNames[i]->copy(); + } + } + + psName = filterPSName(font->getName()); + // add entry to fontFileNames list + if (i == fontFileNameLen) { + if (fontFileNameLen >= fontFileNameSize) { + fontFileNameSize += 64; + fontFileNames = + (GooString **)grealloc(fontFileNames, + fontFileNameSize * sizeof(GooString *)); + psFileNames = + (GooString **)grealloc(psFileNames, + fontFileNameSize * sizeof(GooString *)); + } + } + fontFileNames[fontFileNameLen] = myFileName; + psFileNames[fontFileNameLen] = psName->copy(); + fontFileNameLen++; + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // convert it to a CID type2 font + if ((ffTT = FoFiTrueType::load(fileName->getCString(), faceIndex))) { + int n = ((GfxCIDFont *)font)->getCIDToGIDLen(); + if (n) { + codeToGID = (Gushort *)gmalloc(n * sizeof(Gushort)); + memcpy(codeToGID, ((GfxCIDFont *)font)->getCIDToGID(), n * sizeof(Gushort)); + } else { + codeToGID = ((GfxCIDFont *)font)->getCodeToGIDMap(ffTT, &n); + } + if (globalParams->getPSLevel() >= psLevel3) { + // Level 3: use a CID font + ffTT->convertToCIDType2(psName->getCString(), + codeToGID, n, gTrue, + outputFunc, outputStream); + } else { + // otherwise: use a non-CID composite font + ffTT->convertToType0(psName->getCString(), + codeToGID, n, gTrue, + outputFunc, outputStream); + } + gfree(codeToGID); + delete ffTT; + } + + // ending comment + writePS("%%EndResource\n"); + return psName; +} + +void PSOutputDev::setupEmbeddedCIDType0Font(GfxFont *font, Ref *id, + GooString *psName) { + char *fontBuf; + int fontLen; + FoFiType1C *ffT1C; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) + return; + } + + // add entry to fontFileIDs list + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)greallocn(fontFileIDs, fontFileIDSize, sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // convert it to a Type 0 font + fontBuf = font->readEmbFontFile(xref, &fontLen); + if ((ffT1C = FoFiType1C::make(fontBuf, fontLen))) { + if (globalParams->getPSLevel() >= psLevel3) { + // Level 3: use a CID font + ffT1C->convertToCIDType0(psName->getCString(), outputFunc, outputStream); + } else { + // otherwise: use a non-CID composite font + ffT1C->convertToType0(psName->getCString(), outputFunc, outputStream); + } + delete ffT1C; + } + gfree(fontBuf); + + // ending comment + writePS("%%EndResource\n"); +} + +void PSOutputDev::setupEmbeddedCIDTrueTypeFont(GfxFont *font, Ref *id, + GooString *psName, + GBool needVerticalMetrics) { + char unique[32]; + char *fontBuf; + int fontLen; + FoFiTrueType *ffTT; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) { + sprintf(unique, "_%d", nextTrueTypeNum++); + psName->append(unique); + break; + } + } + + // add entry to fontFileIDs list + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)greallocn(fontFileIDs, fontFileIDSize, sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // convert it to a Type 0 font + fontBuf = font->readEmbFontFile(xref, &fontLen); + if ((ffTT = FoFiTrueType::make(fontBuf, fontLen))) { + if (globalParams->getPSLevel() >= psLevel3) { + // Level 3: use a CID font + ffTT->convertToCIDType2(psName->getCString(), + ((GfxCIDFont *)font)->getCIDToGID(), + ((GfxCIDFont *)font)->getCIDToGIDLen(), + needVerticalMetrics, + outputFunc, outputStream); + } else { + // otherwise: use a non-CID composite font + ffTT->convertToType0(psName->getCString(), + ((GfxCIDFont *)font)->getCIDToGID(), + ((GfxCIDFont *)font)->getCIDToGIDLen(), + needVerticalMetrics, + outputFunc, outputStream); + } + delete ffTT; + } + gfree(fontBuf); + + // ending comment + writePS("%%EndResource\n"); +} + +void PSOutputDev::setupType3Font(GfxFont *font, GooString *psName, + Dict *parentResDict) { + Dict *resDict; + Dict *charProcs; + Object charProc; + Gfx *gfx; + PDFRectangle box; + double *m; + char buf[256]; + int i; + + // set up resources used by font + if ((resDict = ((Gfx8BitFont *)font)->getResources())) { + inType3Char = gTrue; + setupResources(resDict); + inType3Char = gFalse; + } else { + resDict = parentResDict; + } + + // beginning comment + writePSFmt("%%%%BeginResource: font %s\n", psName->getCString()); + embFontList->append("%%+ font "); + embFontList->append(psName->getCString()); + embFontList->append("\n"); + + // font dictionary + writePS("8 dict begin\n"); + writePS("/FontType 3 def\n"); + m = font->getFontMatrix(); + writePSFmt("/FontMatrix [%g %g %g %g %g %g] def\n", + m[0], m[1], m[2], m[3], m[4], m[5]); + m = font->getFontBBox(); + writePSFmt("/FontBBox [%g %g %g %g] def\n", + m[0], m[1], m[2], m[3]); + writePS("/Encoding 256 array def\n"); + writePS(" 0 1 255 { Encoding exch /.notdef put } for\n"); + writePS("/BuildGlyph {\n"); + writePS(" exch /CharProcs get exch\n"); + writePS(" 2 copy known not { pop /.notdef } if\n"); + writePS(" get exec\n"); + writePS("} bind def\n"); + writePS("/BuildChar {\n"); + writePS(" 1 index /Encoding get exch get\n"); + writePS(" 1 index /BuildGlyph get exec\n"); + writePS("} bind def\n"); + if ((charProcs = ((Gfx8BitFont *)font)->getCharProcs())) { + writePSFmt("/CharProcs %d dict def\n", charProcs->getLength()); + writePS("CharProcs begin\n"); + box.x1 = m[0]; + box.y1 = m[1]; + box.x2 = m[2]; + box.y2 = m[3]; + gfx = new Gfx(xref, this, resDict, &box, NULL); + inType3Char = gTrue; + t3Cacheable = gFalse; + for (i = 0; i < charProcs->getLength(); ++i) { + writePS("/"); + char *aux = charProcs->getKey(i)->getCStringCopy(); + writePSName(aux); + delete[] aux; + writePS(" {\n"); + gfx->display(charProcs->getVal(i, &charProc)); + charProc.free(); + if (t3String) { + if (t3Cacheable) { + sprintf(buf, "%g %g %g %g %g %g setcachedevice\n", + t3WX, t3WY, t3LLX, t3LLY, t3URX, t3URY); + } else { + sprintf(buf, "%g %g setcharwidth\n", t3WX, t3WY); + } + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, t3String->getCString(), + t3String->getLength()); + delete t3String; + t3String = NULL; + } + (*outputFunc)(outputStream, "Q\n", 2); + writePS("} def\n"); + } + inType3Char = gFalse; + delete gfx; + writePS("end\n"); + } + writePS("currentdict end\n"); + writePSFmt("/%s exch definefont pop\n", psName->getCString()); + + // ending comment + writePS("%%EndResource\n"); +} + +void PSOutputDev::setupImages(Dict *resDict) { + Object xObjDict, xObj, xObjRef, subtypeObj; + int i; + + if (!(mode == psModeForm || inType3Char)) { + return; + } + + //----- recursively scan XObjects + resDict->lookup("XObject", &xObjDict); + if (xObjDict.isDict()) { + for (i = 0; i < xObjDict.dictGetLength(); ++i) { + xObjDict.dictGetValNF(i, &xObjRef); + xObjDict.dictGetVal(i, &xObj); + if (xObj.isStream()) { + xObj.streamGetDict()->lookup("Subtype", &subtypeObj); + if (subtypeObj.isName("Image")) { + if (xObjRef.isRef()) { + setupImage(xObjRef.getRef(), xObj.getStream()); + } else { + error(-1, "Image in resource dict is not an indirect reference"); + } + } + subtypeObj.free(); + } + xObj.free(); + xObjRef.free(); + } + } + xObjDict.free(); +} + +void PSOutputDev::setupImage(Ref id, Stream *str) { + GBool useASCIIHex; + int c; + int size, line, col, i; + + // construct an encoder stream + useASCIIHex = level == psLevel1 || level == psLevel1Sep || + globalParams->getPSASCIIHex(); + if (useASCIIHex) { + str = new ASCIIHexEncoder(str); + } else { + str = new ASCII85Encoder(str); + } + + // compute image data size + str->reset(); + col = size = 0; + do { + do { + c = str->getChar(); + } while (c == '\n' || c == '\r'); + if (c == (useASCIIHex ? '>' : '~') || c == EOF) { + break; + } + if (c == 'z') { + ++col; + } else { + ++col; + for (i = 1; i <= (useASCIIHex ? 1 : 4); ++i) { + do { + c = str->getChar(); + } while (c == '\n' || c == '\r'); + if (c == (useASCIIHex ? '>' : '~') || c == EOF) { + break; + } + ++col; + } + } + if (col > 225) { + ++size; + col = 0; + } + } while (c != (useASCIIHex ? '>' : '~') && c != EOF); + ++size; + writePSFmt("%d array dup /ImData_%d_%d exch def\n", size, id.num, id.gen); + str->close(); + + // write the data into the array + str->reset(); + line = col = 0; + writePS((char *)(useASCIIHex ? "dup 0 <" : "dup 0 <~")); + do { + do { + c = str->getChar(); + } while (c == '\n' || c == '\r'); + if (c == (useASCIIHex ? '>' : '~') || c == EOF) { + break; + } + if (c == 'z') { + writePSChar(c); + ++col; + } else { + writePSChar(c); + ++col; + for (i = 1; i <= (useASCIIHex ? 1 : 4); ++i) { + do { + c = str->getChar(); + } while (c == '\n' || c == '\r'); + if (c == (useASCIIHex ? '>' : '~') || c == EOF) { + break; + } + writePSChar(c); + ++col; + } + } + // each line is: "dup nnnnn <~...data...~> put" + // so max data length = 255 - 20 = 235 + // chunks are 1 or 4 bytes each, so we have to stop at 232 + // but make it 225 just to be safe + if (col > 225) { + writePS((char *)(useASCIIHex ? "> put\n" : "~> put\n")); + ++line; + writePSFmt((char *)(useASCIIHex ? "dup %d <" : "dup %d <~"), line); + col = 0; + } + } while (c != (useASCIIHex ? '>' : '~') && c != EOF); + writePS((char *)(useASCIIHex ? "> put\n" : "~> put\n")); + writePS("pop\n"); + str->close(); + + delete str; +} + +void PSOutputDev::startPage(int pageNum, GfxState *state) { + int x1, y1, x2, y2, width, height; + int imgWidth, imgHeight, imgWidth2, imgHeight2; + GBool landscape; + + + if (mode == psModePS) { + writePSFmt("%%%%Page: %d %d\n", pageNum, seqPage); + writePS("%%BeginPageSetup\n"); + } + + // underlays + if (underlayCbk) { + (*underlayCbk)(this, underlayCbkData); + } + if (overlayCbk) { + saveState(NULL); + } + + switch (mode) { + + case psModePS: + // rotate, translate, and scale page + imgWidth = imgURX - imgLLX; + imgHeight = imgURY - imgLLY; + x1 = (int)floor(state->getX1()); + y1 = (int)floor(state->getY1()); + x2 = (int)ceil(state->getX2()); + y2 = (int)ceil(state->getY2()); + width = x2 - x1; + height = y2 - y1; + tx = ty = 0; + // rotation and portrait/landscape mode + if (rotate0 >= 0) { + rotate = (360 - rotate0) % 360; + landscape = gFalse; + } else { + rotate = (360 - state->getRotate()) % 360; + if (rotate == 0 || rotate == 180) { + if (width > height && width > imgWidth) { + rotate += 90; + landscape = gTrue; + } else { + landscape = gFalse; + } + } else { // rotate == 90 || rotate == 270 + if (height > width && height > imgWidth) { + rotate = 270 - rotate; + landscape = gTrue; + } else { + landscape = gFalse; + } + } + } + writePSFmt("%%%%PageOrientation: %s\n", + landscape ? "Landscape" : "Portrait"); + writePS("pdfStartPage\n"); + if (rotate == 0) { + imgWidth2 = imgWidth; + imgHeight2 = imgHeight; + } else if (rotate == 90) { + writePS("90 rotate\n"); + ty = -imgWidth; + imgWidth2 = imgHeight; + imgHeight2 = imgWidth; + } else if (rotate == 180) { + writePS("180 rotate\n"); + imgWidth2 = imgWidth; + imgHeight2 = imgHeight; + tx = -imgWidth; + ty = -imgHeight; + } else { // rotate == 270 + writePS("270 rotate\n"); + tx = -imgHeight; + imgWidth2 = imgHeight; + imgHeight2 = imgWidth; + } + // shrink or expand + if (xScale0 > 0 && yScale0 > 0) { + xScale = xScale0; + yScale = yScale0; + } else if ((globalParams->getPSShrinkLarger() && + (width > imgWidth2 || height > imgHeight2)) || + (globalParams->getPSExpandSmaller() && + (width < imgWidth2 && height < imgHeight2))) { + xScale = (double)imgWidth2 / (double)width; + yScale = (double)imgHeight2 / (double)height; + if (yScale < xScale) { + xScale = yScale; + } else { + yScale = xScale; + } + } else { + xScale = yScale = 1; + } + // deal with odd bounding boxes or clipping + if (clipLLX0 < clipURX0 && clipLLY0 < clipURY0) { + tx -= xScale * clipLLX0; + ty -= yScale * clipLLY0; + } else { + tx -= xScale * x1; + ty -= yScale * y1; + } + // center + if (globalParams->getPSCenter()) { + if (clipLLX0 < clipURX0 && clipLLY0 < clipURY0) { + tx += (imgWidth2 - xScale * (clipURX0 - clipLLX0)) / 2; + ty += (imgHeight2 - yScale * (clipURY0 - clipLLY0)) / 2; + } else { + tx += (imgWidth2 - xScale * width) / 2; + ty += (imgHeight2 - yScale * height) / 2; + } + } + tx += rotate == 0 ? imgLLX + tx0 : imgLLY + ty0; + ty += rotate == 0 ? imgLLY + ty0 : -(imgLLX + tx0); + if (tx != 0 || ty != 0) { + writePSFmt("%g %g translate\n", tx, ty); + } + if (xScale != 1 || yScale != 1) { + writePSFmt("%0.4f %0.4f scale\n", xScale, yScale); + } + if (clipLLX0 < clipURX0 && clipLLY0 < clipURY0) { + writePSFmt("%g %g %g %g re W\n", + clipLLX0, clipLLY0, clipURX0 - clipLLX0, clipURY0 - clipLLY0); + } else { + writePSFmt("%d %d %d %d re W\n", x1, y1, x2 - x1, y2 - y1); + } + + writePS("%%EndPageSetup\n"); + ++seqPage; + break; + + case psModeEPS: + writePS("pdfStartPage\n"); + tx = ty = 0; + rotate = (360 - state->getRotate()) % 360; + if (rotate == 0) { + } else if (rotate == 90) { + writePS("90 rotate\n"); + tx = -epsX1; + ty = -epsY2; + } else if (rotate == 180) { + writePS("180 rotate\n"); + tx = -(epsX1 + epsX2); + ty = -(epsY1 + epsY2); + } else { // rotate == 270 + writePS("270 rotate\n"); + tx = -epsX2; + ty = -epsY1; + } + if (tx != 0 || ty != 0) { + writePSFmt("%g %g translate\n", tx, ty); + } + xScale = yScale = 1; + break; + + case psModeForm: + writePS("/PaintProc {\n"); + writePS("begin xpdf begin\n"); + writePS("pdfStartPage\n"); + tx = ty = 0; + xScale = yScale = 1; + rotate = 0; + break; + } +} + +void PSOutputDev::endPage() { + if (overlayCbk) { + restoreState(NULL); + (*overlayCbk)(this, overlayCbkData); + } + + + if (mode == psModeForm) { + writePS("pdfEndPage\n"); + writePS("end end\n"); + writePS("} def\n"); + writePS("end end\n"); + } else { + if (!manualCtrl) { + writePS("showpage\n"); + } + writePS("%%PageTrailer\n"); + writePageTrailer(); + } +} + +void PSOutputDev::saveState(GfxState *state) { + writePS("q\n"); + ++numSaves; +} + +void PSOutputDev::restoreState(GfxState *state) { + writePS("Q\n"); + --numSaves; +} + +void PSOutputDev::updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32) { + writePSFmt("[%g %g %g %g %g %g] cm\n", m11, m12, m21, m22, m31, m32); +} + +void PSOutputDev::updateLineDash(GfxState *state) { + double *dash; + double start; + int length, i; + + state->getLineDash(&dash, &length, &start); + writePS("["); + for (i = 0; i < length; ++i) { + writePSFmt("%g%s", + dash[i] == 0 ? 1 : dash[i], + (i == length-1) ? "" : " "); + } + writePSFmt("] %g d\n", start); +} + +void PSOutputDev::updateFlatness(GfxState *state) { + writePSFmt("%d i\n", state->getFlatness()); +} + +void PSOutputDev::updateLineJoin(GfxState *state) { + writePSFmt("%d j\n", state->getLineJoin()); +} + +void PSOutputDev::updateLineCap(GfxState *state) { + writePSFmt("%d J\n", state->getLineCap()); +} + +void PSOutputDev::updateMiterLimit(GfxState *state) { + writePSFmt("%g M\n", state->getMiterLimit()); +} + +void PSOutputDev::updateLineWidth(GfxState *state) { + writePSFmt("%g w\n", state->getLineWidth()); +} + +void PSOutputDev::updateFillColorSpace(GfxState *state) { + switch (level) { + case psLevel1: + case psLevel1Sep: + break; + case psLevel2: + case psLevel3: + if (state->getFillColorSpace()->getMode() != csPattern) { + dumpColorSpaceL2(state->getFillColorSpace(), gTrue, gFalse); + writePS(" cs\n"); + } + break; + case psLevel2Sep: + case psLevel3Sep: + break; + } +} + +void PSOutputDev::updateStrokeColorSpace(GfxState *state) { + switch (level) { + case psLevel1: + case psLevel1Sep: + break; + case psLevel2: + case psLevel3: + if (state->getStrokeColorSpace()->getMode() != csPattern) { + dumpColorSpaceL2(state->getStrokeColorSpace(), gTrue, gFalse); + writePS(" CS\n"); + } + break; + case psLevel2Sep: + case psLevel3Sep: + break; + } +} + +void PSOutputDev::updateFillColor(GfxState *state) { + GfxColor color; + GfxColor *colorPtr; + GfxGray gray; + GfxCMYK cmyk; + GfxSeparationColorSpace *sepCS; + double c, m, y, k; + int i; + + switch (level) { + case psLevel1: + state->getFillGray(&gray); + writePSFmt("%g g\n", colToDbl(gray)); + break; + case psLevel1Sep: + state->getFillCMYK(&cmyk); + c = colToDbl(cmyk.c); + m = colToDbl(cmyk.m); + y = colToDbl(cmyk.y); + k = colToDbl(cmyk.k); + writePSFmt("%g %g %g %g k\n", c, m, y, k); + addProcessColor(c, m, y, k); + break; + case psLevel2: + case psLevel3: + if (state->getFillColorSpace()->getMode() != csPattern) { + colorPtr = state->getFillColor(); + writePS("["); + for (i = 0; i < state->getFillColorSpace()->getNComps(); ++i) { + if (i > 0) { + writePS(" "); + } + writePSFmt("%g", colToDbl(colorPtr->c[i])); + } + writePS("] sc\n"); + } + break; + case psLevel2Sep: + case psLevel3Sep: + if (state->getFillColorSpace()->getMode() == csSeparation) { + sepCS = (GfxSeparationColorSpace *)state->getFillColorSpace(); + color.c[0] = gfxColorComp1; + sepCS->getCMYK(&color, &cmyk); + writePSFmt("%g %g %g %g %g (%s) ck\n", + colToDbl(state->getFillColor()->c[0]), + colToDbl(cmyk.c), colToDbl(cmyk.m), + colToDbl(cmyk.y), colToDbl(cmyk.k), + sepCS->getName()->getCString()); + addCustomColor(sepCS); + } else { + state->getFillCMYK(&cmyk); + c = colToDbl(cmyk.c); + m = colToDbl(cmyk.m); + y = colToDbl(cmyk.y); + k = colToDbl(cmyk.k); + writePSFmt("%g %g %g %g k\n", c, m, y, k); + addProcessColor(c, m, y, k); + } + break; + } + t3Cacheable = gFalse; +} + +void PSOutputDev::updateStrokeColor(GfxState *state) { + GfxColor color; + GfxColor *colorPtr; + GfxGray gray; + GfxCMYK cmyk; + GfxSeparationColorSpace *sepCS; + double c, m, y, k; + int i; + + switch (level) { + case psLevel1: + state->getStrokeGray(&gray); + writePSFmt("%g G\n", colToDbl(gray)); + break; + case psLevel1Sep: + state->getStrokeCMYK(&cmyk); + c = colToDbl(cmyk.c); + m = colToDbl(cmyk.m); + y = colToDbl(cmyk.y); + k = colToDbl(cmyk.k); + writePSFmt("%g %g %g %g K\n", c, m, y, k); + addProcessColor(c, m, y, k); + break; + case psLevel2: + case psLevel3: + if (state->getStrokeColorSpace()->getMode() != csPattern) { + colorPtr = state->getStrokeColor(); + writePS("["); + for (i = 0; i < state->getStrokeColorSpace()->getNComps(); ++i) { + if (i > 0) { + writePS(" "); + } + writePSFmt("%g", colToDbl(colorPtr->c[i])); + } + writePS("] SC\n"); + } + break; + case psLevel2Sep: + case psLevel3Sep: + if (state->getStrokeColorSpace()->getMode() == csSeparation) { + sepCS = (GfxSeparationColorSpace *)state->getStrokeColorSpace(); + color.c[0] = gfxColorComp1; + sepCS->getCMYK(&color, &cmyk); + writePSFmt("%g %g %g %g %g (%s) CK\n", + colToDbl(state->getStrokeColor()->c[0]), + colToDbl(cmyk.c), colToDbl(cmyk.m), + colToDbl(cmyk.y), colToDbl(cmyk.k), + sepCS->getName()->getCString()); + addCustomColor(sepCS); + } else { + state->getStrokeCMYK(&cmyk); + c = colToDbl(cmyk.c); + m = colToDbl(cmyk.m); + y = colToDbl(cmyk.y); + k = colToDbl(cmyk.k); + writePSFmt("%g %g %g %g K\n", c, m, y, k); + addProcessColor(c, m, y, k); + } + break; + } + t3Cacheable = gFalse; +} + +void PSOutputDev::addProcessColor(double c, double m, double y, double k) { + if (c > 0) { + processColors |= psProcessCyan; + } + if (m > 0) { + processColors |= psProcessMagenta; + } + if (y > 0) { + processColors |= psProcessYellow; + } + if (k > 0) { + processColors |= psProcessBlack; + } +} + +void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) { + PSOutCustomColor *cc; + GfxColor color; + GfxCMYK cmyk; + + for (cc = customColors; cc; cc = cc->next) { + if (!cc->name->cmp(sepCS->getName())) { + return; + } + } + color.c[0] = gfxColorComp1; + sepCS->getCMYK(&color, &cmyk); + cc = new PSOutCustomColor(colToDbl(cmyk.c), colToDbl(cmyk.m), + colToDbl(cmyk.y), colToDbl(cmyk.k), + sepCS->getName()->copy()); + cc->next = customColors; + customColors = cc; +} + +void PSOutputDev::updateFillOverprint(GfxState *state) { + if (level >= psLevel2) { + writePSFmt("%s op\n", state->getFillOverprint() ? "true" : "false"); + } +} + +void PSOutputDev::updateStrokeOverprint(GfxState *state) { + if (level >= psLevel2) { + writePSFmt("%s OP\n", state->getStrokeOverprint() ? "true" : "false"); + } +} + +void PSOutputDev::updateFont(GfxState *state) { + if (state->getFont()) { + writePSFmt("/F%d_%d %g Tf\n", + state->getFont()->getID()->num, state->getFont()->getID()->gen, + fabs(state->getFontSize()) < 0.00001 ? 0.00001 + : state->getFontSize()); + } +} + +void PSOutputDev::updateTextMat(GfxState *state) { + double *mat; + + mat = state->getTextMat(); + if (fabs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.00001) { + // avoid a singular (or close-to-singular) matrix + writePSFmt("[0.00001 0 0 0.00001 %g %g] Tm\n", mat[4], mat[5]); + } else { + writePSFmt("[%g %g %g %g %g %g] Tm\n", + mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + } +} + +void PSOutputDev::updateCharSpace(GfxState *state) { + writePSFmt("%g Tc\n", state->getCharSpace()); +} + +void PSOutputDev::updateRender(GfxState *state) { + int rm; + + rm = state->getRender(); + writePSFmt("%d Tr\n", rm); + rm &= 3; + if (rm != 0 && rm != 3) { + t3Cacheable = gFalse; + } +} + +void PSOutputDev::updateRise(GfxState *state) { + writePSFmt("%g Ts\n", state->getRise()); +} + +void PSOutputDev::updateWordSpace(GfxState *state) { + writePSFmt("%g Tw\n", state->getWordSpace()); +} + +void PSOutputDev::updateHorizScaling(GfxState *state) { + double h; + + h = state->getHorizScaling(); + if (fabs(h) < 0.01) { + h = 0.01; + } + writePSFmt("%g Tz\n", h); +} + +void PSOutputDev::updateTextPos(GfxState *state) { + writePSFmt("%g %g Td\n", state->getLineX(), state->getLineY()); +} + +void PSOutputDev::updateTextShift(GfxState *state, double shift) { + if (state->getFont()->getWMode()) { + writePSFmt("%g TJmV\n", shift); + } else { + writePSFmt("%g TJm\n", shift); + } +} + +void PSOutputDev::stroke(GfxState *state) { + doPath(state->getPath()); + if (t3String) { + // if we're construct a cacheable Type 3 glyph, we need to do + // everything in the fill color + writePS("Sf\n"); + } else { + writePS("S\n"); + } +} + +void PSOutputDev::fill(GfxState *state) { + doPath(state->getPath()); + writePS("f\n"); +} + +void PSOutputDev::eoFill(GfxState *state) { + doPath(state->getPath()); + writePS("f*\n"); +} + +void PSOutputDev::tilingPatternFill(GfxState *state, Object *str, + int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep) { + PDFRectangle box; + Gfx *gfx; + + // define a Type 3 font + writePS("8 dict begin\n"); + writePS("/FontType 3 def\n"); + writePS("/FontMatrix [1 0 0 1 0 0] def\n"); + writePSFmt("/FontBBox [%g %g %g %g] def\n", + bbox[0], bbox[1], bbox[2], bbox[3]); + writePS("/Encoding 256 array def\n"); + writePS(" 0 1 255 { Encoding exch /.notdef put } for\n"); + writePS(" Encoding 120 /x put\n"); + writePS("/BuildGlyph {\n"); + writePS(" exch /CharProcs get exch\n"); + writePS(" 2 copy known not { pop /.notdef } if\n"); + writePS(" get exec\n"); + writePS("} bind def\n"); + writePS("/BuildChar {\n"); + writePS(" 1 index /Encoding get exch get\n"); + writePS(" 1 index /BuildGlyph get exec\n"); + writePS("} bind def\n"); + writePS("/CharProcs 1 dict def\n"); + writePS("CharProcs begin\n"); + box.x1 = bbox[0]; + box.y1 = bbox[1]; + box.x2 = bbox[2]; + box.y2 = bbox[3]; + gfx = new Gfx(xref, this, resDict, &box, NULL); + writePS("/x {\n"); + if (paintType == 2) { + writePSFmt("%g 0 %g %g %g %g setcachedevice\n", + xStep, bbox[0], bbox[1], bbox[2], bbox[3]); + } else { + writePSFmt("%g 0 setcharwidth\n", xStep); + } + inType3Char = gTrue; + ++numTilingPatterns; + gfx->display(str); + --numTilingPatterns; + inType3Char = gFalse; + writePS("} def\n"); + delete gfx; + writePS("end\n"); + writePS("currentdict end\n"); + writePSFmt("/xpdfTile%d exch definefont pop\n", numTilingPatterns); + + // draw the tiles + writePSFmt("/xpdfTile%d findfont setfont\n", numTilingPatterns); + writePSFmt("gsave [%g %g %g %g %g %g] concat\n", + mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + writePSFmt("%d 1 %d { %g exch %g mul m %d 1 %d { pop (x) show } for } for\n", + y0, y1 - 1, x0 * xStep, yStep, x0, x1 - 1); + writePS("grestore\n"); +} + +void PSOutputDev::functionShadedFill(GfxState *state, + GfxFunctionShading *shading) { + double x0, y0, x1, y1; + double *mat; + int i; + + shading->getDomain(&x0, &y0, &x1, &y1); + mat = shading->getMatrix(); + writePSFmt("/mat [%g %g %g %g %g %g] def\n", + mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + writePSFmt("/n %d def\n", shading->getColorSpace()->getNComps()); + if (shading->getNFuncs() == 1) { + writePS("/func "); + cvtFunction(shading->getFunc(0)); + writePS("def\n"); + } else { + writePS("/func {\n"); + for (i = 0; i < shading->getNFuncs(); ++i) { + if (i < shading->getNFuncs() - 1) { + writePS("2 copy\n"); + } + cvtFunction(shading->getFunc(i)); + writePS("exec\n"); + if (i < shading->getNFuncs() - 1) { + writePS("3 1 roll\n"); + } + } + writePS("} def\n"); + } + writePSFmt("%g %g %g %g 0 funcSH\n", x0, y0, x1, y1); +} + +void PSOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) { + double xMin, yMin, xMax, yMax; + double x0, y0, x1, y1, dx, dy, mul; + double tMin, tMax, t, t0, t1; + int i; + + // get the clip region bbox + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + + // compute min and max t values, based on the four corners of the + // clip region bbox + shading->getCoords(&x0, &y0, &x1, &y1); + dx = x1 - x0; + dy = y1 - y0; + mul = 1 / (dx * dx + dy * dy); + tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul; + t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + if (tMin < 0 && !shading->getExtend0()) { + tMin = 0; + } + if (tMax > 1 && !shading->getExtend1()) { + tMax = 1; + } + + // get the function domain + t0 = shading->getDomain0(); + t1 = shading->getDomain1(); + + // generate the PS code + writePSFmt("/t0 %g def\n", t0); + writePSFmt("/t1 %g def\n", t1); + writePSFmt("/dt %g def\n", t1 - t0); + writePSFmt("/x0 %g def\n", x0); + writePSFmt("/y0 %g def\n", y0); + writePSFmt("/dx %g def\n", x1 - x0); + writePSFmt("/x1 %g def\n", x1); + writePSFmt("/y1 %g def\n", y1); + writePSFmt("/dy %g def\n", y1 - y0); + writePSFmt("/xMin %g def\n", xMin); + writePSFmt("/yMin %g def\n", yMin); + writePSFmt("/xMax %g def\n", xMax); + writePSFmt("/yMax %g def\n", yMax); + writePSFmt("/n %d def\n", shading->getColorSpace()->getNComps()); + if (shading->getNFuncs() == 1) { + writePS("/func "); + cvtFunction(shading->getFunc(0)); + writePS("def\n"); + } else { + writePS("/func {\n"); + for (i = 0; i < shading->getNFuncs(); ++i) { + if (i < shading->getNFuncs() - 1) { + writePS("dup\n"); + } + cvtFunction(shading->getFunc(i)); + writePS("exec\n"); + if (i < shading->getNFuncs() - 1) { + writePS("exch\n"); + } + } + writePS("} def\n"); + } + writePSFmt("%g %g 0 axialSH\n", tMin, tMax); +} + +void PSOutputDev::radialShadedFill(GfxState *state, + GfxRadialShading *shading) { + double x0, y0, r0, x1, y1, r1, t0, t1, sMin, sMax; + double xMin, yMin, xMax, yMax; + double d0, d1; + int i; + + // get the shading info + shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1); + t0 = shading->getDomain0(); + t1 = shading->getDomain1(); + + // compute the (possibly extended) s range + sMin = 0; + sMax = 1; + if (shading->getExtend0()) { + if (r0 < r1) { + // extend the smaller end + sMin = -r0 / (r1 - r0); + } else { + // extend the larger end + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + d0 = (x0 - xMin) * (x0 - xMin); + d1 = (x0 - xMax) * (x0 - xMax); + sMin = d0 > d1 ? d0 : d1; + d0 = (y0 - yMin) * (y0 - yMin); + d1 = (y0 - yMax) * (y0 - yMax); + sMin += d0 > d1 ? d0 : d1; + sMin = (sqrt(sMin) - r0) / (r1 - r0); + if (sMin > 0) { + sMin = 0; + } else if (sMin < -20) { + // sanity check + sMin = -20; + } + } + } + if (shading->getExtend1()) { + if (r1 < r0) { + // extend the smaller end + sMax = -r0 / (r1 - r0); + } else if (r1 > r0) { + // extend the larger end + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + d0 = (x1 - xMin) * (x1 - xMin); + d1 = (x1 - xMax) * (x1 - xMax); + sMax = d0 > d1 ? d0 : d1; + d0 = (y1 - yMin) * (y1 - yMin); + d1 = (y1 - yMax) * (y1 - yMax); + sMax += d0 > d1 ? d0 : d1; + sMax = (sqrt(sMax) - r0) / (r1 - r0); + if (sMax < 1) { + sMax = 1; + } else if (sMax > 20) { + // sanity check + sMax = 20; + } + } + } + + // generate the PS code + writePSFmt("/x0 %g def\n", x0); + writePSFmt("/x1 %g def\n", x1); + writePSFmt("/dx %g def\n", x1 - x0); + writePSFmt("/y0 %g def\n", y0); + writePSFmt("/y1 %g def\n", y1); + writePSFmt("/dy %g def\n", y1 - y0); + writePSFmt("/r0 %g def\n", r0); + writePSFmt("/r1 %g def\n", r1); + writePSFmt("/dr %g def\n", r1 - r0); + writePSFmt("/t0 %g def\n", t0); + writePSFmt("/t1 %g def\n", t1); + writePSFmt("/dt %g def\n", t1 - t0); + writePSFmt("/n %d def\n", shading->getColorSpace()->getNComps()); + if (shading->getNFuncs() == 1) { + writePS("/func "); + cvtFunction(shading->getFunc(0)); + writePS("def\n"); + } else { + writePS("/func {\n"); + for (i = 0; i < shading->getNFuncs(); ++i) { + if (i < shading->getNFuncs() - 1) { + writePS("dup\n"); + } + cvtFunction(shading->getFunc(i)); + writePS("exec\n"); + if (i < shading->getNFuncs() - 1) { + writePS("exch\n"); + } + } + writePS("} def\n"); + } + writePSFmt("%g %g 0 radialSH\n", sMin, sMax); +} + +void PSOutputDev::clip(GfxState *state) { + doPath(state->getPath()); + writePS("W\n"); +} + +void PSOutputDev::eoClip(GfxState *state) { + doPath(state->getPath()); + writePS("W*\n"); +} + +void PSOutputDev::doPath(GfxPath *path) { + GfxSubpath *subpath; + double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4; + int n, m, i, j; + + n = path->getNumSubpaths(); + + if (n == 1 && path->getSubpath(0)->getNumPoints() == 5) { + subpath = path->getSubpath(0); + x0 = subpath->getX(0); + y0 = subpath->getY(0); + x4 = subpath->getX(4); + y4 = subpath->getY(4); + if (x4 == x0 && y4 == y0) { + x1 = subpath->getX(1); + y1 = subpath->getY(1); + x2 = subpath->getX(2); + y2 = subpath->getY(2); + x3 = subpath->getX(3); + y3 = subpath->getY(3); + if (x0 == x1 && x2 == x3 && y0 == y3 && y1 == y2) { + writePSFmt("%g %g %g %g re\n", + x0 < x2 ? x0 : x2, y0 < y1 ? y0 : y1, + fabs(x2 - x0), fabs(y1 - y0)); + return; + } else if (x0 == x3 && x1 == x2 && y0 == y1 && y2 == y3) { + writePSFmt("%g %g %g %g re\n", + x0 < x1 ? x0 : x1, y0 < y2 ? y0 : y2, + fabs(x1 - x0), fabs(y2 - y0)); + return; + } + } + } + + for (i = 0; i < n; ++i) { + subpath = path->getSubpath(i); + m = subpath->getNumPoints(); + writePSFmt("%g %g m\n", subpath->getX(0), subpath->getY(0)); + j = 1; + while (j < m) { + if (subpath->getCurve(j)) { + writePSFmt("%g %g %g %g %g %g c\n", subpath->getX(j), subpath->getY(j), + subpath->getX(j+1), subpath->getY(j+1), + subpath->getX(j+2), subpath->getY(j+2)); + j += 3; + } else { + writePSFmt("%g %g l\n", subpath->getX(j), subpath->getY(j)); + ++j; + } + } + if (subpath->isClosed()) { + writePS("h\n"); + } + } +} + +void PSOutputDev::drawString(GfxState *state, GooString *s) { + GfxFont *font; + int wMode; + GooString *s2; + double dx, dy, dx2, dy2, originX, originY; + char *p; + UnicodeMap *uMap; + CharCode code; + Unicode u[8]; + char buf[8]; + int len, nChars, uLen, n, m, i, j; + + // check for invisible text -- this is used by Acrobat Capture + if (state->getRender() == 3) { + return; + } + + // ignore empty strings + if (s->getLength() == 0) { + return; + } + + // get the font + if (!(font = state->getFont())) { + return; + } + wMode = font->getWMode(); + + // check for a subtitute 16-bit font + uMap = NULL; + if (font->isCIDFont()) { + for (i = 0; i < font16EncLen; ++i) { + if (font->getID()->num == font16Enc[i].fontID.num && + font->getID()->gen == font16Enc[i].fontID.gen) { + uMap = globalParams->getUnicodeMap(font16Enc[i].enc); + break; + } + } + } + + // compute width of chars in string, ignoring char spacing and word + // spacing -- the Tj operator will adjust for the metrics of the + // font that's actually used + dx = dy = 0; + nChars = 0; + p = s->getCString(); + len = s->getLength(); + if (font->isCIDFont()) { + s2 = new GooString(); + } else { + s2 = s; + } + while (len > 0) { + n = font->getNextChar(p, len, &code, + u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, + &dx2, &dy2, &originX, &originY); + if (font->isCIDFont()) { + if (uMap) { + for (i = 0; i < uLen; ++i) { + m = uMap->mapUnicode(u[i], buf, (int)sizeof(buf)); + for (j = 0; j < m; ++j) { + s2->append(buf[j]); + } + } + //~ this really needs to get the number of chars in the target + //~ encoding - which may be more than the number of Unicode + //~ chars + nChars += uLen; + } else { + s2->append((char)((code >> 8) & 0xff)); + s2->append((char)(code & 0xff)); + ++nChars; + } + } + dx += dx2; + dy += dy2; + p += n; + len -= n; + } + dx *= state->getFontSize() * state->getHorizScaling(); + dy *= state->getFontSize(); + if (uMap) { + uMap->decRefCnt(); + } + + if (s2->getLength() > 0) { + writePSString(s2); + if (font->isCIDFont()) { + if (wMode) { + writePSFmt(" %d %g Tj16V\n", nChars, dy); + } else { + writePSFmt(" %d %g Tj16\n", nChars, dx); + } + } else { + writePSFmt(" %g Tj\n", dx); + } + } + if (font->isCIDFont()) { + delete s2; + } + + if (state->getRender() & 4) { + haveTextClip = gTrue; + } +} + +void PSOutputDev::endTextObject(GfxState *state) { + if (haveTextClip) { + writePS("Tclip\n"); + haveTextClip = gFalse; + } +} + +void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + int len; + + len = height * ((width + 7) / 8); + if (level == psLevel1 || level == psLevel1Sep) { + doImageL1(ref, NULL, invert, inlineImg, str, width, height, len); + } else { + doImageL2(ref, NULL, invert, inlineImg, str, width, height, len, + NULL, NULL, 0, 0, gFalse); + } +} + +void PSOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) { + int len; + + len = height * ((width * colorMap->getNumPixelComps() * + colorMap->getBits() + 7) / 8); + switch (level) { + case psLevel1: + doImageL1(ref, colorMap, gFalse, inlineImg, str, width, height, len); + break; + case psLevel1Sep: + //~ handle indexed, separation, ... color spaces + doImageL1Sep(colorMap, gFalse, inlineImg, str, width, height, len); + break; + case psLevel2: + case psLevel2Sep: + case psLevel3: + case psLevel3Sep: + doImageL2(ref, colorMap, gFalse, inlineImg, str, + width, height, len, maskColors, NULL, 0, 0, gFalse); + break; + } + t3Cacheable = gFalse; +} + +void PSOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GBool maskInvert) { + int len; + + len = height * ((width * colorMap->getNumPixelComps() * + colorMap->getBits() + 7) / 8); + switch (level) { + case psLevel1: + doImageL1(ref, colorMap, gFalse, gFalse, str, width, height, len); + break; + case psLevel1Sep: + //~ handle indexed, separation, ... color spaces + doImageL1Sep(colorMap, gFalse, gFalse, str, width, height, len); + break; + case psLevel2: + case psLevel2Sep: + case psLevel3: + case psLevel3Sep: + doImageL2(ref, colorMap, gFalse, gFalse, str, width, height, len, + NULL, maskStr, maskWidth, maskHeight, maskInvert); + break; + } + t3Cacheable = gFalse; +} + +void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len) { + ImageStream *imgStr; + Guchar pixBuf[gfxColorMaxComps]; + GfxGray gray; + int col, x, y, c, i; + + if (inType3Char && !colorMap) { + if (inlineImg) { + // create an array + str = new FixedLengthEncoder(str, len); + str = new ASCIIHexEncoder(str); + str->reset(); + col = 0; + writePS("[<"); + do { + do { + c = str->getChar(); + } while (c == '\n' || c == '\r'); + if (c == '>' || c == EOF) { + break; + } + writePSChar(c); + ++col; + // each line is: "<...data...>" + // so max data length = 255 - 4 = 251 + // but make it 240 just to be safe + // chunks are 2 bytes each, so we need to stop on an even col number + if (col == 240) { + writePS(">\n<"); + col = 0; + } + } while (c != '>' && c != EOF); + writePS(">]\n"); + writePS("0\n"); + str->close(); + delete str; + } else { + // set up to use the array already created by setupImages() + writePSFmt("ImData_%d_%d 0\n", ref->getRefNum(), ref->getRefGen()); + } + } + + // image/imagemask command + if (inType3Char && !colorMap) { + writePSFmt("%d %d %s [%d 0 0 %d 0 %d] pdfImM1a\n", + width, height, invert ? "true" : "false", + width, -height, height); + } else if (colorMap) { + writePSFmt("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1\n", + width, height, + width, -height, height); + } else { + writePSFmt("%d %d %s [%d 0 0 %d 0 %d] pdfImM1\n", + width, height, invert ? "true" : "false", + width, -height, height); + } + + // image data + if (!(inType3Char && !colorMap)) { + + if (colorMap) { + + // set up to process the data stream + imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + // process the data stream + i = 0; + for (y = 0; y < height; ++y) { + + // write the line + for (x = 0; x < width; ++x) { + imgStr->getPixel(pixBuf); + colorMap->getGray(pixBuf, &gray); + writePSFmt("%02x", colToByte(gray)); + if (++i == 32) { + writePSChar('\n'); + i = 0; + } + } + } + if (i != 0) { + writePSChar('\n'); + } + delete imgStr; + + // imagemask + } else { + str->reset(); + i = 0; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; x += 8) { + writePSFmt("%02x", str->getChar() & 0xff); + if (++i == 32) { + writePSChar('\n'); + i = 0; + } + } + } + if (i != 0) { + writePSChar('\n'); + } + str->close(); + } + } +} + +void PSOutputDev::doImageL1Sep(GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len) { + ImageStream *imgStr; + Guchar *lineBuf; + Guchar pixBuf[gfxColorMaxComps]; + GfxCMYK cmyk; + int x, y, i, comp; + + // width, height, matrix, bits per component + writePSFmt("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1Sep\n", + width, height, + width, -height, height); + + // allocate a line buffer + lineBuf = (Guchar *)gmalloc(4 * width); + + // set up to process the data stream + imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + // process the data stream + i = 0; + for (y = 0; y < height; ++y) { + + // read the line + for (x = 0; x < width; ++x) { + imgStr->getPixel(pixBuf); + colorMap->getCMYK(pixBuf, &cmyk); + lineBuf[4*x+0] = colToByte(cmyk.c); + lineBuf[4*x+1] = colToByte(cmyk.m); + lineBuf[4*x+2] = colToByte(cmyk.y); + lineBuf[4*x+3] = colToByte(cmyk.k); + addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m), + colToDbl(cmyk.y), colToDbl(cmyk.k)); + } + + // write one line of each color component + for (comp = 0; comp < 4; ++comp) { + for (x = 0; x < width; ++x) { + writePSFmt("%02x", lineBuf[4*x + comp]); + if (++i == 32) { + writePSChar('\n'); + i = 0; + } + } + } + } + + if (i != 0) { + writePSChar('\n'); + } + + delete imgStr; + gfree(lineBuf); +} + +void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len, + int *maskColors, Stream *maskStr, + int maskWidth, int maskHeight, GBool maskInvert) { + ImageStream *imgStr; + Guchar *line, *pix; + GooString *s; + int n, numComps; + GBool useRLE, useASCII, useASCIIHex, useCompressed; + GfxSeparationColorSpace *sepCS; + GfxColor color; + GfxCMYK cmyk; + int c; + int col, i, x, x0, y, y0, maskXor; + + // color key masking + if (maskColors && colorMap && !inlineImg) { + // can't read the stream twice for inline images -- but masking + // isn't allowed with inline images anyway + writePS("[\n"); + numComps = colorMap->getNumPixelComps(); + imgStr = new ImageStream(str, width, numComps, colorMap->getBits()); + imgStr->reset(); + for (y = 0, y0 = 0; y < height; ++y) { + if (!(line = imgStr->getLine())) { + break; + } + for (x = 0, x0 = 0, pix = line; x < width; ++x, pix += numComps) { + for (i = 0; i < numComps; ++i) { + if (pix[i] < maskColors[2*i] || + pix[i] > maskColors[2*i+1]) { + break; + } + } + if (i == numComps) { + if (y0 < y) { + writePSFmt("0 %d %d %d\n", height - y, width, y - y0); + } + if (x0 < x) { + writePSFmt("%d %d %d 1\n", x0, height - y - 1, x - x0); + } + x0 = x + 1; + y0 = y + 1; + } + } + if (x0 > 0 && x0 < width) { + writePSFmt("%d %d %d 1\n", x0, height - y - 1, width - x0); + } + } + if (y0 < height) { + writePSFmt("0 0 %d %d\n", width, height - y0); + } + delete imgStr; + str->close(); + writePSFmt("] %d %d pdfImClip\n", width, height); + + // explicit masking + } else if (maskStr) { + writePS("[\n"); + imgStr = new ImageStream(maskStr, maskWidth, 1, 1); + imgStr->reset(); + maskXor = maskInvert ? 1 : 0; + for (y = 0, y0 = 0; y < maskHeight; ++y) { + if (!(line = imgStr->getLine())) { + break; + } + for (x = 0, x0 = 0, pix = line; x < maskWidth; ++x, ++pix) { + if (*pix ^ maskXor) { + if (y0 < y) { + writePSFmt("0 %d %d %d\n", maskHeight - y, maskWidth, y - y0); + } + if (x0 < x) { + writePSFmt("%d %d %d 1\n", x0, maskHeight - y - 1, x - x0); + } + x0 = x + 1; + y0 = y + 1; + } + } + if (x0 > 0 && x0 < maskWidth) { + writePSFmt("%d %d %d 1\n", x0, maskHeight - y - 1, maskWidth - x0); + } + } + if (y0 < maskHeight) { + writePSFmt("0 0 %d %d\n", maskWidth, maskHeight - y0); + } + delete imgStr; + maskStr->close(); + writePSFmt("] %d %d pdfImClip\n", maskWidth, maskHeight); + } + + // color space + if (colorMap) { + dumpColorSpaceL2(colorMap->getColorSpace(), gFalse, gTrue); + writePS(" setcolorspace\n"); + } + + useASCIIHex = globalParams->getPSASCIIHex(); + + // set up the image data + if (mode == psModeForm || inType3Char) { + if (inlineImg) { + // create an array + str = new FixedLengthEncoder(str, len); + if (useASCIIHex) { + str = new ASCIIHexEncoder(str); + } else { + str = new ASCII85Encoder(str); + } + str->reset(); + col = 0; + writePS((char *)(useASCIIHex ? "[<" : "[<~")); + do { + do { + c = str->getChar(); + } while (c == '\n' || c == '\r'); + if (c == (useASCIIHex ? '>' : '~') || c == EOF) { + break; + } + if (c == 'z') { + writePSChar(c); + ++col; + } else { + writePSChar(c); + ++col; + for (i = 1; i <= (useASCIIHex ? 1 : 4); ++i) { + do { + c = str->getChar(); + } while (c == '\n' || c == '\r'); + if (c == (useASCIIHex ? '>' : '~') || c == EOF) { + break; + } + writePSChar(c); + ++col; + } + } + // each line is: "<~...data...~>" + // so max data length = 255 - 6 = 249 + // chunks are 1 or 5 bytes each, so we have to stop at 245 + // but make it 240 just to be safe + if (col > 240) { + writePS((char *)(useASCIIHex ? ">\n<" : "~>\n<~")); + col = 0; + } + } while (c != (useASCIIHex ? '>' : '~') && c != EOF); + writePS((char *)(useASCIIHex ? ">]\n" : "~>]\n")); + writePS("0\n"); + str->close(); + delete str; + } else { + // set up to use the array already created by setupImages() + writePSFmt("ImData_%d_%d 0\n", ref->getRefNum(), ref->getRefGen()); + } + } + + // image dictionary + writePS("<<\n /ImageType 1\n"); + + // width, height, matrix, bits per component + writePSFmt(" /Width %d\n", width); + writePSFmt(" /Height %d\n", height); + writePSFmt(" /ImageMatrix [%d 0 0 %d 0 %d]\n", width, -height, height); + if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) { + writePSFmt(" /BitsPerComponent 8\n"); + } else { + writePSFmt(" /BitsPerComponent %d\n", + colorMap ? colorMap->getBits() : 1); + } + + // decode + if (colorMap) { + writePS(" /Decode ["); + if ((level == psLevel2Sep || level == psLevel3Sep) && + colorMap->getColorSpace()->getMode() == csSeparation) { + // this matches up with the code in the pdfImSep operator + n = (1 << colorMap->getBits()) - 1; + writePSFmt("%g %g", colorMap->getDecodeLow(0) * n, + colorMap->getDecodeHigh(0) * n); + } else if (colorMap->getColorSpace()->getMode() == csDeviceN) { + numComps = ((GfxDeviceNColorSpace *)colorMap->getColorSpace())-> + getAlt()->getNComps(); + for (i = 0; i < numComps; ++i) { + if (i > 0) { + writePS(" "); + } + writePS("0 1"); + } + } else { + numComps = colorMap->getNumPixelComps(); + for (i = 0; i < numComps; ++i) { + if (i > 0) { + writePS(" "); + } + writePSFmt("%g %g", colorMap->getDecodeLow(i), + colorMap->getDecodeHigh(i)); + } + } + writePS("]\n"); + } else { + writePSFmt(" /Decode [%d %d]\n", invert ? 1 : 0, invert ? 0 : 1); + } + + if (mode == psModeForm || inType3Char) { + + // data source + writePS(" /DataSource { 2 copy get exch 1 add exch }\n"); + + // end of image dictionary + writePSFmt(">>\n%s\n", colorMap ? "image" : "imagemask"); + + // get rid of the array and index + writePS("pop pop\n"); + + } else { + + // data source + writePS(" /DataSource currentfile\n"); + s = str->getPSFilter(level < psLevel2 ? 1 : level < psLevel3 ? 2 : 3, + " "); + if ((colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) || + inlineImg || !s) { + useRLE = gTrue; + useASCII = gTrue; + useCompressed = gFalse; + } else { + useRLE = gFalse; + useASCII = str->isBinary(); + useCompressed = gTrue; + } + if (useASCII) { + writePSFmt(" /ASCII%sDecode filter\n", + useASCIIHex ? "Hex" : "85"); + } + if (useRLE) { + writePS(" /RunLengthDecode filter\n"); + } + if (useCompressed) { + writePS(s->getCString()); + } + if (s) { + delete s; + } + + // cut off inline image streams at appropriate length + if (inlineImg) { + str = new FixedLengthEncoder(str, len); + } else if (useCompressed) { + str = str->getBaseStream(); + } + + // recode DeviceN data + if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) { + str = new DeviceNRecoder(str, width, height, colorMap); + } + + // add RunLengthEncode and ASCIIHex/85 encode filters + if (useRLE) { + str = new RunLengthEncoder(str); + } + if (useASCII) { + if (useASCIIHex) { + str = new ASCIIHexEncoder(str); + } else { + str = new ASCII85Encoder(str); + } + } + + // end of image dictionary + writePS(">>\n"); +#if OPI_SUPPORT + if (opi13Nest) { + if (inlineImg) { + // this can't happen -- OPI dictionaries are in XObjects + error(-1, "Internal: OPI in inline image"); + n = 0; + } else { + // need to read the stream to count characters -- the length + // is data-dependent (because of ASCII and RLE filters) + str->reset(); + n = 0; + while ((c = str->getChar()) != EOF) { + ++n; + } + str->close(); + } + // +6/7 for "pdfIm\n" / "pdfImM\n" + // +8 for newline + trailer + n += colorMap ? 14 : 15; + writePSFmt("%%%%BeginData: %d Hex Bytes\n", n); + } +#endif + if ((level == psLevel2Sep || level == psLevel3Sep) && colorMap && + colorMap->getColorSpace()->getMode() == csSeparation) { + color.c[0] = gfxColorComp1; + sepCS = (GfxSeparationColorSpace *)colorMap->getColorSpace(); + sepCS->getCMYK(&color, &cmyk); + writePSFmt("%g %g %g %g (%s) pdfImSep\n", + colToDbl(cmyk.c), colToDbl(cmyk.m), + colToDbl(cmyk.y), colToDbl(cmyk.k), + sepCS->getName()->getCString()); + } else { + writePSFmt("%s\n", colorMap ? "pdfIm" : "pdfImM"); + } + + // copy the stream data + str->reset(); + while ((c = str->getChar()) != EOF) { + writePSChar(c); + } + str->close(); + + // add newline and trailer to the end + writePSChar('\n'); + writePS("%-EOD-\n"); +#if OPI_SUPPORT + if (opi13Nest) { + writePS("%%EndData\n"); + } +#endif + + // delete encoders + if (useRLE || useASCII || inlineImg) { + delete str; + } + } + + if ((maskColors && colorMap && !inlineImg) || maskStr) { + writePS("pdfImClipEnd\n"); + } +} + +void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace, + GBool genXform, GBool updateColors) { + GfxCalGrayColorSpace *calGrayCS; + GfxCalRGBColorSpace *calRGBCS; + GfxLabColorSpace *labCS; + GfxIndexedColorSpace *indexedCS; + GfxSeparationColorSpace *separationCS; + GfxDeviceNColorSpace *deviceNCS; + GfxColorSpace *baseCS; + Guchar *lookup, *p; + double x[gfxColorMaxComps], y[gfxColorMaxComps]; + GfxColor color; + GfxCMYK cmyk; + Function *func; + int n, numComps, numAltComps; + int byte; + int i, j, k; + + switch (colorSpace->getMode()) { + + case csDeviceGray: + writePS("/DeviceGray"); + if (genXform) { + writePS(" {}"); + } + if (updateColors) { + processColors |= psProcessBlack; + } + break; + + case csCalGray: + calGrayCS = (GfxCalGrayColorSpace *)colorSpace; + writePS("[/CIEBasedA <<\n"); + writePSFmt(" /DecodeA {%g exp} bind\n", calGrayCS->getGamma()); + writePSFmt(" /MatrixA [%g %g %g]\n", + calGrayCS->getWhiteX(), calGrayCS->getWhiteY(), + calGrayCS->getWhiteZ()); + writePSFmt(" /WhitePoint [%g %g %g]\n", + calGrayCS->getWhiteX(), calGrayCS->getWhiteY(), + calGrayCS->getWhiteZ()); + writePSFmt(" /BlackPoint [%g %g %g]\n", + calGrayCS->getBlackX(), calGrayCS->getBlackY(), + calGrayCS->getBlackZ()); + writePS(">>]"); + if (genXform) { + writePS(" {}"); + } + if (updateColors) { + processColors |= psProcessBlack; + } + break; + + case csDeviceRGB: + writePS("/DeviceRGB"); + if (genXform) { + writePS(" {}"); + } + if (updateColors) { + processColors |= psProcessCMYK; + } + break; + + case csCalRGB: + calRGBCS = (GfxCalRGBColorSpace *)colorSpace; + writePS("[/CIEBasedABC <<\n"); + writePSFmt(" /DecodeABC [{%g exp} bind {%g exp} bind {%g exp} bind]\n", + calRGBCS->getGammaR(), calRGBCS->getGammaG(), + calRGBCS->getGammaB()); + writePSFmt(" /MatrixABC [%g %g %g %g %g %g %g %g %g]\n", + calRGBCS->getMatrix()[0], calRGBCS->getMatrix()[1], + calRGBCS->getMatrix()[2], calRGBCS->getMatrix()[3], + calRGBCS->getMatrix()[4], calRGBCS->getMatrix()[5], + calRGBCS->getMatrix()[6], calRGBCS->getMatrix()[7], + calRGBCS->getMatrix()[8]); + writePSFmt(" /WhitePoint [%g %g %g]\n", + calRGBCS->getWhiteX(), calRGBCS->getWhiteY(), + calRGBCS->getWhiteZ()); + writePSFmt(" /BlackPoint [%g %g %g]\n", + calRGBCS->getBlackX(), calRGBCS->getBlackY(), + calRGBCS->getBlackZ()); + writePS(">>]"); + if (genXform) { + writePS(" {}"); + } + if (updateColors) { + processColors |= psProcessCMYK; + } + break; + + case csDeviceCMYK: + writePS("/DeviceCMYK"); + if (genXform) { + writePS(" {}"); + } + if (updateColors) { + processColors |= psProcessCMYK; + } + break; + + case csLab: + labCS = (GfxLabColorSpace *)colorSpace; + writePS("[/CIEBasedABC <<\n"); + writePSFmt(" /RangeABC [0 100 %g %g %g %g]\n", + labCS->getAMin(), labCS->getAMax(), + labCS->getBMin(), labCS->getBMax()); + writePS(" /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]\n"); + writePS(" /MatrixABC [1 1 1 1 0 0 0 0 -1]\n"); + writePS(" /DecodeLMN\n"); + writePS(" [{dup 6 29 div ge {dup dup mul mul}\n"); + writePSFmt(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind\n", + labCS->getWhiteX()); + writePS(" {dup 6 29 div ge {dup dup mul mul}\n"); + writePSFmt(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind\n", + labCS->getWhiteY()); + writePS(" {dup 6 29 div ge {dup dup mul mul}\n"); + writePSFmt(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind]\n", + labCS->getWhiteZ()); + writePSFmt(" /WhitePoint [%g %g %g]\n", + labCS->getWhiteX(), labCS->getWhiteY(), labCS->getWhiteZ()); + writePSFmt(" /BlackPoint [%g %g %g]\n", + labCS->getBlackX(), labCS->getBlackY(), labCS->getBlackZ()); + writePS(">>]"); + if (genXform) { + writePS(" {}"); + } + if (updateColors) { + processColors |= psProcessCMYK; + } + break; + + case csICCBased: + // there is no transform function to the alternate color space, so + // we can use it directly + dumpColorSpaceL2(((GfxICCBasedColorSpace *)colorSpace)->getAlt(), + genXform, updateColors); + break; + + case csIndexed: + indexedCS = (GfxIndexedColorSpace *)colorSpace; + baseCS = indexedCS->getBase(); + writePS("[/Indexed "); + dumpColorSpaceL2(baseCS, gFalse, gFalse); + n = indexedCS->getIndexHigh(); + numComps = baseCS->getNComps(); + lookup = indexedCS->getLookup(); + writePSFmt(" %d <\n", n); + if (baseCS->getMode() == csDeviceN) { + func = ((GfxDeviceNColorSpace *)baseCS)->getTintTransformFunc(); + numAltComps = ((GfxDeviceNColorSpace *)baseCS)->getAlt()->getNComps(); + p = lookup; + for (i = 0; i <= n; i += 8) { + writePS(" "); + for (j = i; j < i+8 && j <= n; ++j) { + for (k = 0; k < numComps; ++k) { + x[k] = *p++ / 255.0; + } + func->transform(x, y); + for (k = 0; k < numAltComps; ++k) { + byte = (int)(y[k] * 255 + 0.5); + if (byte < 0) { + byte = 0; + } else if (byte > 255) { + byte = 255; + } + writePSFmt("%02x", byte); + } + if (updateColors) { + color.c[0] = dblToCol(j); + indexedCS->getCMYK(&color, &cmyk); + addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m), + colToDbl(cmyk.y), colToDbl(cmyk.k)); + } + } + writePS("\n"); + } + } else { + for (i = 0; i <= n; i += 8) { + writePS(" "); + for (j = i; j < i+8 && j <= n; ++j) { + for (k = 0; k < numComps; ++k) { + writePSFmt("%02x", lookup[j * numComps + k]); + } + if (updateColors) { + color.c[0] = dblToCol(j); + indexedCS->getCMYK(&color, &cmyk); + addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m), + colToDbl(cmyk.y), colToDbl(cmyk.k)); + } + } + writePS("\n"); + } + } + writePS(">]"); + if (genXform) { + writePS(" {}"); + } + break; + + case csSeparation: + separationCS = (GfxSeparationColorSpace *)colorSpace; + writePS("[/Separation /"); + writePSName(separationCS->getName()->getCString()); + writePS(" "); + dumpColorSpaceL2(separationCS->getAlt(), gFalse, gFalse); + writePS("\n"); + cvtFunction(separationCS->getFunc()); + writePS("]"); + if (genXform) { + writePS(" {}"); + } + if (updateColors) { + addCustomColor(separationCS); + } + break; + + case csDeviceN: + // DeviceN color spaces are a Level 3 PostScript feature. + deviceNCS = (GfxDeviceNColorSpace *)colorSpace; + dumpColorSpaceL2(deviceNCS->getAlt(), gFalse, updateColors); + if (genXform) { + writePS(" "); + cvtFunction(deviceNCS->getTintTransformFunc()); + } + break; + + case csPattern: + //~ unimplemented + break; + } +} + +#if OPI_SUPPORT +void PSOutputDev::opiBegin(GfxState *state, Dict *opiDict) { + Object dict; + + if (globalParams->getPSOPI()) { + opiDict->lookup("2.0", &dict); + if (dict.isDict()) { + opiBegin20(state, dict.getDict()); + dict.free(); + } else { + dict.free(); + opiDict->lookup("1.3", &dict); + if (dict.isDict()) { + opiBegin13(state, dict.getDict()); + } + dict.free(); + } + } +} + +void PSOutputDev::opiBegin20(GfxState *state, Dict *dict) { + Object obj1, obj2, obj3, obj4; + double width, height, left, right, top, bottom; + int w, h; + int i; + + writePS("%%BeginOPI: 2.0\n"); + writePS("%%Distilled\n"); + + dict->lookup("F", &obj1); + if (getFileSpec(&obj1, &obj2)) { + writePSFmt("%%%%ImageFileName: %s\n", + obj2.getString()->getCString()); + obj2.free(); + } + obj1.free(); + + dict->lookup("MainImage", &obj1); + if (obj1.isString()) { + writePSFmt("%%%%MainImage: %s\n", obj1.getString()->getCString()); + } + obj1.free(); + + //~ ignoring 'Tags' entry + //~ need to use writePSString() and deal with >255-char lines + + dict->lookup("Size", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 2) { + obj1.arrayGet(0, &obj2); + width = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + height = obj2.getNum(); + obj2.free(); + writePSFmt("%%%%ImageDimensions: %g %g\n", width, height); + } + obj1.free(); + + dict->lookup("CropRect", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 4) { + obj1.arrayGet(0, &obj2); + left = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + top = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2, &obj2); + right = obj2.getNum(); + obj2.free(); + obj1.arrayGet(3, &obj2); + bottom = obj2.getNum(); + obj2.free(); + writePSFmt("%%%%ImageCropRect: %g %g %g %g\n", left, top, right, bottom); + } + obj1.free(); + + dict->lookup("Overprint", &obj1); + if (obj1.isBool()) { + writePSFmt("%%%%ImageOverprint: %s\n", obj1.getBool() ? "true" : "false"); + } + obj1.free(); + + dict->lookup("Inks", &obj1); + if (obj1.isName()) { + writePSFmt("%%%%ImageInks: %s\n", obj1.getName()); + } else if (obj1.isArray() && obj1.arrayGetLength() >= 1) { + obj1.arrayGet(0, &obj2); + if (obj2.isName()) { + writePSFmt("%%%%ImageInks: %s %d", + obj2.getName(), (obj1.arrayGetLength() - 1) / 2); + for (i = 1; i+1 < obj1.arrayGetLength(); i += 2) { + obj1.arrayGet(i, &obj3); + obj1.arrayGet(i+1, &obj4); + if (obj3.isString() && obj4.isNum()) { + writePS(" "); + writePSString(obj3.getString()); + writePSFmt(" %g", obj4.getNum()); + } + obj3.free(); + obj4.free(); + } + writePS("\n"); + } + obj2.free(); + } + obj1.free(); + + writePS("gsave\n"); + + writePS("%%BeginIncludedImage\n"); + + dict->lookup("IncludedImageDimensions", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 2) { + obj1.arrayGet(0, &obj2); + w = obj2.getInt(); + obj2.free(); + obj1.arrayGet(1, &obj2); + h = obj2.getInt(); + obj2.free(); + writePSFmt("%%%%IncludedImageDimensions: %d %d\n", w, h); + } + obj1.free(); + + dict->lookup("IncludedImageQuality", &obj1); + if (obj1.isNum()) { + writePSFmt("%%%%IncludedImageQuality: %g\n", obj1.getNum()); + } + obj1.free(); + + ++opi20Nest; +} + +void PSOutputDev::opiBegin13(GfxState *state, Dict *dict) { + Object obj1, obj2; + int left, right, top, bottom, samples, bits, width, height; + double c, m, y, k; + double llx, lly, ulx, uly, urx, ury, lrx, lry; + double tllx, tlly, tulx, tuly, turx, tury, tlrx, tlry; + double horiz, vert; + int i, j; + + writePS("save\n"); + writePS("/opiMatrix2 matrix currentmatrix def\n"); + writePS("opiMatrix setmatrix\n"); + + dict->lookup("F", &obj1); + if (getFileSpec(&obj1, &obj2)) { + writePSFmt("%%ALDImageFileName: %s\n", + obj2.getString()->getCString()); + obj2.free(); + } + obj1.free(); + + dict->lookup("CropRect", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 4) { + obj1.arrayGet(0, &obj2); + left = obj2.getInt(); + obj2.free(); + obj1.arrayGet(1, &obj2); + top = obj2.getInt(); + obj2.free(); + obj1.arrayGet(2, &obj2); + right = obj2.getInt(); + obj2.free(); + obj1.arrayGet(3, &obj2); + bottom = obj2.getInt(); + obj2.free(); + writePSFmt("%%ALDImageCropRect: %d %d %d %d\n", left, top, right, bottom); + } + obj1.free(); + + dict->lookup("Color", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 5) { + obj1.arrayGet(0, &obj2); + c = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + m = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2, &obj2); + y = obj2.getNum(); + obj2.free(); + obj1.arrayGet(3, &obj2); + k = obj2.getNum(); + obj2.free(); + obj1.arrayGet(4, &obj2); + if (obj2.isString()) { + writePSFmt("%%ALDImageColor: %g %g %g %g ", c, m, y, k); + writePSString(obj2.getString()); + writePS("\n"); + } + obj2.free(); + } + obj1.free(); + + dict->lookup("ColorType", &obj1); + if (obj1.isName()) { + writePSFmt("%%ALDImageColorType: %s\n", obj1.getName()); + } + obj1.free(); + + //~ ignores 'Comments' entry + //~ need to handle multiple lines + + dict->lookup("CropFixed", &obj1); + if (obj1.isArray()) { + obj1.arrayGet(0, &obj2); + ulx = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + uly = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2, &obj2); + lrx = obj2.getNum(); + obj2.free(); + obj1.arrayGet(3, &obj2); + lry = obj2.getNum(); + obj2.free(); + writePSFmt("%%ALDImageCropFixed: %g %g %g %g\n", ulx, uly, lrx, lry); + } + obj1.free(); + + dict->lookup("GrayMap", &obj1); + if (obj1.isArray()) { + writePS("%ALDImageGrayMap:"); + for (i = 0; i < obj1.arrayGetLength(); i += 16) { + if (i > 0) { + writePS("\n%%+"); + } + for (j = 0; j < 16 && i+j < obj1.arrayGetLength(); ++j) { + obj1.arrayGet(i+j, &obj2); + writePSFmt(" %d", obj2.getInt()); + obj2.free(); + } + } + writePS("\n"); + } + obj1.free(); + + dict->lookup("ID", &obj1); + if (obj1.isString()) { + writePSFmt("%%ALDImageID: %s\n", obj1.getString()->getCString()); + } + obj1.free(); + + dict->lookup("ImageType", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 2) { + obj1.arrayGet(0, &obj2); + samples = obj2.getInt(); + obj2.free(); + obj1.arrayGet(1, &obj2); + bits = obj2.getInt(); + obj2.free(); + writePSFmt("%%ALDImageType: %d %d\n", samples, bits); + } + obj1.free(); + + dict->lookup("Overprint", &obj1); + if (obj1.isBool()) { + writePSFmt("%%ALDImageOverprint: %s\n", obj1.getBool() ? "true" : "false"); + } + obj1.free(); + + dict->lookup("Position", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 8) { + obj1.arrayGet(0, &obj2); + llx = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + lly = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2, &obj2); + ulx = obj2.getNum(); + obj2.free(); + obj1.arrayGet(3, &obj2); + uly = obj2.getNum(); + obj2.free(); + obj1.arrayGet(4, &obj2); + urx = obj2.getNum(); + obj2.free(); + obj1.arrayGet(5, &obj2); + ury = obj2.getNum(); + obj2.free(); + obj1.arrayGet(6, &obj2); + lrx = obj2.getNum(); + obj2.free(); + obj1.arrayGet(7, &obj2); + lry = obj2.getNum(); + obj2.free(); + opiTransform(state, llx, lly, &tllx, &tlly); + opiTransform(state, ulx, uly, &tulx, &tuly); + opiTransform(state, urx, ury, &turx, &tury); + opiTransform(state, lrx, lry, &tlrx, &tlry); + writePSFmt("%%ALDImagePosition: %g %g %g %g %g %g %g %g\n", + tllx, tlly, tulx, tuly, turx, tury, tlrx, tlry); + obj2.free(); + } + obj1.free(); + + dict->lookup("Resolution", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 2) { + obj1.arrayGet(0, &obj2); + horiz = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + vert = obj2.getNum(); + obj2.free(); + writePSFmt("%%ALDImageResoution: %g %g\n", horiz, vert); + obj2.free(); + } + obj1.free(); + + dict->lookup("Size", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 2) { + obj1.arrayGet(0, &obj2); + width = obj2.getInt(); + obj2.free(); + obj1.arrayGet(1, &obj2); + height = obj2.getInt(); + obj2.free(); + writePSFmt("%%ALDImageDimensions: %d %d\n", width, height); + } + obj1.free(); + + //~ ignoring 'Tags' entry + //~ need to use writePSString() and deal with >255-char lines + + dict->lookup("Tint", &obj1); + if (obj1.isNum()) { + writePSFmt("%%ALDImageTint: %g\n", obj1.getNum()); + } + obj1.free(); + + dict->lookup("Transparency", &obj1); + if (obj1.isBool()) { + writePSFmt("%%ALDImageTransparency: %s\n", obj1.getBool() ? "true" : "false"); + } + obj1.free(); + + writePS("%%BeginObject: image\n"); + writePS("opiMatrix2 setmatrix\n"); + ++opi13Nest; +} + +// Convert PDF user space coordinates to PostScript default user space +// coordinates. This has to account for both the PDF CTM and the +// PSOutputDev page-fitting transform. +void PSOutputDev::opiTransform(GfxState *state, double x0, double y0, + double *x1, double *y1) { + double t; + + state->transform(x0, y0, x1, y1); + *x1 += tx; + *y1 += ty; + if (rotate == 90) { + t = *x1; + *x1 = -*y1; + *y1 = t; + } else if (rotate == 180) { + *x1 = -*x1; + *y1 = -*y1; + } else if (rotate == 270) { + t = *x1; + *x1 = *y1; + *y1 = -t; + } + *x1 *= xScale; + *y1 *= yScale; +} + +void PSOutputDev::opiEnd(GfxState *state, Dict *opiDict) { + Object dict; + + if (globalParams->getPSOPI()) { + opiDict->lookup("2.0", &dict); + if (dict.isDict()) { + writePS("%%EndIncludedImage\n"); + writePS("%%EndOPI\n"); + writePS("grestore\n"); + --opi20Nest; + dict.free(); + } else { + dict.free(); + opiDict->lookup("1.3", &dict); + if (dict.isDict()) { + writePS("%%EndObject\n"); + writePS("restore\n"); + --opi13Nest; + } + dict.free(); + } + } +} + +GBool PSOutputDev::getFileSpec(Object *fileSpec, Object *fileName) { + if (fileSpec->isString()) { + fileSpec->copy(fileName); + return gTrue; + } + if (fileSpec->isDict()) { + fileSpec->dictLookup("DOS", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("Mac", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("Unix", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("F", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + } + return gFalse; +} +#endif // OPI_SUPPORT + +void PSOutputDev::type3D0(GfxState *state, double wx, double wy) { + writePSFmt("%g %g setcharwidth\n", wx, wy); + writePS("q\n"); +} + +void PSOutputDev::type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury) { + t3WX = wx; + t3WY = wy; + t3LLX = llx; + t3LLY = lly; + t3URX = urx; + t3URY = ury; + t3String = new GooString(); + writePS("q\n"); + t3Cacheable = gTrue; +} + +void PSOutputDev::psXObject(Stream *psStream, Stream *level1Stream) { + Stream *str; + int c; + + if ((level == psLevel1 || level == psLevel1Sep) && level1Stream) { + str = level1Stream; + } else { + str = psStream; + } + str->reset(); + while ((c = str->getChar()) != EOF) { + writePSChar(c); + } + str->close(); +} + +//~ can nextFunc be reset to 0 -- maybe at the start of each page? +//~ or maybe at the start of each color space / pattern? +void PSOutputDev::cvtFunction(Function *func) { + SampledFunction *func0; + ExponentialFunction *func2; + StitchingFunction *func3; + PostScriptFunction *func4; + int thisFunc, m, n, nSamples, i, j, k; + + switch (func->getType()) { + + case -1: // identity + writePS("{}\n"); + break; + + case 0: // sampled + func0 = (SampledFunction *)func; + thisFunc = nextFunc++; + m = func0->getInputSize(); + n = func0->getOutputSize(); + nSamples = n; + for (i = 0; i < m; ++i) { + nSamples *= func0->getSampleSize(i); + } + writePSFmt("/xpdfSamples%d [\n", thisFunc); + for (i = 0; i < nSamples; ++i) { + writePSFmt("%g\n", func0->getSamples()[i]); + } + writePS("] def\n"); + writePSFmt("{ %d array %d array %d 2 roll\n", 2*m, m, m+2); + // [e01] [efrac] x0 x1 ... xm-1 + for (i = m-1; i >= 0; --i) { + // [e01] [efrac] x0 x1 ... xi + writePSFmt("%g sub %g mul %g add\n", + func0->getDomainMin(i), + (func0->getEncodeMax(i) - func0->getEncodeMin(i)) / + (func0->getDomainMax(i) - func0->getDomainMin(i)), + func0->getEncodeMin(i)); + // [e01] [efrac] x0 x1 ... xi-1 xi' + writePSFmt("dup 0 lt { pop 0 } { dup %d gt { pop %d } if } ifelse\n", + func0->getSampleSize(i) - 1, func0->getSampleSize(i) - 1); + // [e01] [efrac] x0 x1 ... xi-1 xi' + writePS("dup floor cvi exch dup ceiling cvi exch 2 index sub\n"); + // [e01] [efrac] x0 x1 ... xi-1 floor(xi') ceiling(xi') xi'-floor(xi') + writePSFmt("%d index %d 3 2 roll put\n", i+3, i); + // [e01] [efrac] x0 x1 ... xi-1 floor(xi') ceiling(xi') + writePSFmt("%d index %d 3 2 roll put\n", i+3, 2*i+1); + // [e01] [efrac] x0 x1 ... xi-1 floor(xi') + writePSFmt("%d index %d 3 2 roll put\n", i+2, 2*i); + // [e01] [efrac] x0 x1 ... xi-1 + } + // [e01] [efrac] + for (i = 0; i < n; ++i) { + // [e01] [efrac] y(0) ... y(i-1) + for (j = 0; j < (1<> k) & 1)); + for (k = m - 2; k >= 0; --k) { + writePSFmt("%d mul %d index %d get add\n", + func0->getSampleSize(k), + i + j + 3, + 2 * k + ((j >> k) & 1)); + } + if (n > 1) { + writePSFmt("%d mul %d add ", n, i); + } + writePS("get\n"); + } + // [e01] [efrac] y(0) ... y(i-1) s(0) s(1) ... s(2^m-1) + for (j = 0; j < m; ++j) { + // [e01] [efrac] y(0) ... y(i-1) s(0) s(1) ... s(2^(m-j)-1) + for (k = 0; k < (1 << (m - j)); k += 2) { + // [e01] [efrac] y(0) ... y(i-1) <2^(m-j)-k s values> + writePSFmt("%d index %d get dup\n", i + k/2 + (1 << (m-j)) - k, j); + writePS("3 2 roll mul exch 1 exch sub 3 2 roll mul add\n"); + writePSFmt("%d 1 roll\n", k/2 + (1 << m-j) - k - 1); + } + // [e01] [efrac] s'(0) s'(1) ... s(2^(m-j-1)-1) + } + // [e01] [efrac] y(0) ... y(i-1) s + writePSFmt("%g mul %g add\n", + func0->getDecodeMax(i) - func0->getDecodeMin(i), + func0->getDecodeMin(i)); + writePSFmt("dup %g lt { pop %g } { dup %g gt { pop %g } if } ifelse\n", + func0->getRangeMin(i), func0->getRangeMin(i), + func0->getRangeMax(i), func0->getRangeMax(i)); + // [e01] [efrac] y(0) ... y(i-1) y(i) + } + // [e01] [efrac] y(0) ... y(n-1) + writePSFmt("%d %d roll pop pop }\n", n+2, n); + break; + + case 2: // exponential + func2 = (ExponentialFunction *)func; + n = func2->getOutputSize(); + writePSFmt("{ dup %g lt { pop %g } { dup %g gt { pop %g } if } ifelse\n", + func2->getDomainMin(0), func2->getDomainMin(0), + func2->getDomainMax(0), func2->getDomainMax(0)); + // x + for (i = 0; i < n; ++i) { + // x y(0) .. y(i-1) + writePSFmt("%d index %g exp %g mul %g add\n", + i, func2->getE(), func2->getC1()[i] - func2->getC0()[i], + func2->getC0()[i]); + if (func2->getHasRange()) { + writePSFmt("dup %g lt { pop %g } { dup %g gt { pop %g } if } ifelse\n", + func2->getRangeMin(i), func2->getRangeMin(i), + func2->getRangeMax(i), func2->getRangeMax(i)); + } + } + // x y(0) .. y(n-1) + writePSFmt("%d %d roll pop }\n", n+1, n); + break; + + case 3: // stitching + func3 = (StitchingFunction *)func; + thisFunc = nextFunc++; + for (i = 0; i < func3->getNumFuncs(); ++i) { + cvtFunction(func3->getFunc(i)); + writePSFmt("/xpdfFunc%d_%d exch def\n", thisFunc, i); + } + writePSFmt("{ dup %g lt { pop %g } { dup %g gt { pop %g } if } ifelse\n", + func3->getDomainMin(0), func3->getDomainMin(0), + func3->getDomainMax(0), func3->getDomainMax(0)); + for (i = 0; i < func3->getNumFuncs() - 1; ++i) { + writePSFmt("dup %g lt { %g sub %g mul %g add xpdfFunc%d_%d } {\n", + func3->getBounds()[i+1], + func3->getBounds()[i], + (func3->getEncode()[2*i+1] - func3->getEncode()[2*i]) / + (func3->getBounds()[i+1] - func3->getBounds()[i]), + func3->getEncode()[2*i], + thisFunc, i); + } + writePSFmt("%g sub %g mul %g add xpdfFunc%d_%d\n", + func3->getBounds()[i], + (func3->getEncode()[2*i+1] - func3->getEncode()[2*i]) / + (func3->getBounds()[i+1] - func3->getBounds()[i]), + func3->getEncode()[2*i], + thisFunc, i); + for (i = 0; i < func3->getNumFuncs() - 1; ++i) { + writePS("} ifelse\n"); + } + writePS("}\n"); + break; + + case 4: // PostScript + func4 = (PostScriptFunction *)func; + writePS(func4->getCodeString()->getCString()); + writePS("\n"); + break; + } +} + +void PSOutputDev::writePSChar(char c) { + if (t3String) { + t3String->append(c); + } else { + (*outputFunc)(outputStream, &c, 1); + } +} + +void PSOutputDev::writePS(char *s) { + if (t3String) { + t3String->append(s); + } else { + (*outputFunc)(outputStream, s, strlen(s)); + } +} + +void PSOutputDev::writePSFmt(const char *fmt, ...) { + va_list args; + char buf[512]; + + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + if (t3String) { + t3String->append(buf); + } else { + (*outputFunc)(outputStream, buf, strlen(buf)); + } +} + +void PSOutputDev::writePSString(GooString *s) { + Guchar *p; + int n, line; + char buf[8]; + + writePSChar('('); + line = 1; + for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) { + if (line >= 64) { + writePSChar('\\'); + writePSChar('\n'); + line = 0; + } + if (*p == '(' || *p == ')' || *p == '\\') { + writePSChar('\\'); + writePSChar((char)*p); + line += 2; + } else if (*p < 0x20 || *p >= 0x80) { + sprintf(buf, "\\%03o", *p); + writePS(buf); + line += 4; + } else { + writePSChar((char)*p); + ++line; + } + } + writePSChar(')'); +} + +void PSOutputDev::writePSName(char *s) { + char *p; + char c; + + p = s; + while ((c = *p++)) { + if (c <= (char)0x20 || c >= (char)0x7f || + c == '(' || c == ')' || c == '<' || c == '>' || + c == '[' || c == ']' || c == '{' || c == '}' || + c == '/' || c == '%') { + writePSFmt("#%02x", c & 0xff); + } else { + writePSChar(c); + } + } +} + +GooString *PSOutputDev::filterPSName(GooString *name) { + GooString *name2; + char buf[8]; + int i; + char c; + + name2 = new GooString(); + + // ghostscript chokes on names that begin with out-of-limits + // numbers, e.g., 1e4foo is handled correctly (as a name), but + // 1e999foo generates a limitcheck error + c = name->getChar(0); + if (c >= '0' && c <= '9') { + name2->append('f'); + } + + for (i = 0; i < name->getLength(); ++i) { + c = name->getChar(i); + if (c <= (char)0x20 || c >= (char)0x7f || + c == '(' || c == ')' || c == '<' || c == '>' || + c == '[' || c == ']' || c == '{' || c == '}' || + c == '/' || c == '%') { + sprintf(buf, "#%02x", c & 0xff); + name2->append(buf); + } else { + name2->append(c); + } + } + return name2; +} diff --git a/rosapps/smartpdf/poppler/poppler/PSOutputDev.h b/rosapps/smartpdf/poppler/poppler/PSOutputDev.h new file mode 100644 index 00000000000..ef7ac60def5 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PSOutputDev.h @@ -0,0 +1,356 @@ +//======================================================================== +// +// PSOutputDev.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef PSOUTPUTDEV_H +#define PSOUTPUTDEV_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include +#include "Object.h" +#include "GlobalParams.h" +#include "OutputDev.h" + +class GfxPath; +class GfxFont; +class GfxColorSpace; +class GfxSeparationColorSpace; +class PDFRectangle; +struct PSFont16Enc; +class PSOutCustomColor; +class Function; + +//------------------------------------------------------------------------ +// PSOutputDev +//------------------------------------------------------------------------ + +enum PSOutMode { + psModePS, + psModeEPS, + psModeForm +}; + +enum PSFileType { + psFile, // write to file + psPipe, // write to pipe + psStdout, // write to stdout + psGeneric // write to a generic stream +}; + +typedef void (*PSOutputFunc)(void *stream, char *data, int len); + +class PSOutputDev: public OutputDev { +public: + + // Open a PostScript output file, and write the prolog. + PSOutputDev(const char *fileName, XRef *xrefA, Catalog *catalog, + int firstPage, int lastPage, PSOutMode modeA, + int paperWidthA = -1, int paperHeightA = -1, + GBool duplexA = gTrue, + int imgLLXA = 0, int imgLLYA = 0, + int imgURXA = 0, int imgURYA = 0, + GBool manualCtrlA = gFalse); + + // Open a PSOutputDev that will write to a generic stream. + PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, + XRef *xrefA, Catalog *catalog, + int firstPage, int lastPage, PSOutMode modeA, + int paperWidthA = -1, int paperHeightA = -1, + GBool duplexA = gTrue, + int imgLLXA = 0, int imgLLYA = 0, + int imgURXA = 0, int imgURYA = 0, + GBool manualCtrlA = gFalse); + + // Destructor -- writes the trailer and closes the file. + virtual ~PSOutputDev(); + + // Check if file was successfully created. + virtual GBool isOk() { return ok; } + + //---- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gFalse; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gFalse; } + + // Does this device use tilingPatternFill()? If this returns false, + // tiling pattern fills will be reduced to a series of other drawing + // operations. + virtual GBool useTilingPatternFill() { return gTrue; } + + // Does this device use functionShadedFill(), axialShadedFill(), and + // radialShadedFill()? If this returns false, these shaded fills + // will be reduced to a series of other drawing operations. + virtual GBool useShadedFills() + { return level == psLevel2 || level == psLevel3; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() { return gFalse; } + + //----- header/trailer (used only if manualCtrl is true) + + // Write the document-level header. + void writeHeader(int firstPage, int lastPage, + PDFRectangle *mediaBox, PDFRectangle *cropBox, + int pageRotate); + + // Write the Xpdf procset. + void writeXpdfProcset(); + + // Write the document-level setup. + void writeDocSetup(Catalog *catalog, int firstPage, int lastPage, GBool duplexA); + + // Write the trailer for the current page. + void writePageTrailer(); + + // Write the document trailer. + void writeTrailer(); + + //----- initialization and control + + // Start a page. + virtual void startPage(int pageNum, GfxState *state); + + // End a page. + virtual void endPage(); + + //----- save/restore graphics state + virtual void saveState(GfxState *state); + virtual void restoreState(GfxState *state); + + //----- update graphics state + virtual void updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32); + virtual void updateLineDash(GfxState *state); + virtual void updateFlatness(GfxState *state); + virtual void updateLineJoin(GfxState *state); + virtual void updateLineCap(GfxState *state); + virtual void updateMiterLimit(GfxState *state); + virtual void updateLineWidth(GfxState *state); + virtual void updateFillColorSpace(GfxState *state); + virtual void updateStrokeColorSpace(GfxState *state); + virtual void updateFillColor(GfxState *state); + virtual void updateStrokeColor(GfxState *state); + virtual void updateFillOverprint(GfxState *state); + virtual void updateStrokeOverprint(GfxState *state); + + //----- update text state + virtual void updateFont(GfxState *state); + virtual void updateTextMat(GfxState *state); + virtual void updateCharSpace(GfxState *state); + virtual void updateRender(GfxState *state); + virtual void updateRise(GfxState *state); + virtual void updateWordSpace(GfxState *state); + virtual void updateHorizScaling(GfxState *state); + virtual void updateTextPos(GfxState *state); + virtual void updateTextShift(GfxState *state, double shift); + + //----- path painting + virtual void stroke(GfxState *state); + virtual void fill(GfxState *state); + virtual void eoFill(GfxState *state); + virtual void tilingPatternFill(GfxState *state, Object *str, + int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep); + virtual void functionShadedFill(GfxState *state, + GfxFunctionShading *shading); + virtual void axialShadedFill(GfxState *state, GfxAxialShading *shading); + virtual void radialShadedFill(GfxState *state, GfxRadialShading *shading); + + //----- path clipping + virtual void clip(GfxState *state); + virtual void eoClip(GfxState *state); + + //----- text drawing + virtual void drawString(GfxState *state, GooString *s); + virtual void endTextObject(GfxState *state); + + //----- image drawing + virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg); + virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, int maskWidth, int maskHeight, + GBool maskInvert); + +#if OPI_SUPPORT + //----- OPI functions + virtual void opiBegin(GfxState *state, Dict *opiDict); + virtual void opiEnd(GfxState *state, Dict *opiDict); +#endif + + //----- Type 3 font operators + virtual void type3D0(GfxState *state, double wx, double wy); + virtual void type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury); + + //----- PostScript XObjects + virtual void psXObject(Stream *psStream, Stream *level1Stream); + + //----- miscellaneous + void setOffset(double x, double y) + { tx0 = x; ty0 = y; } + void setScale(double x, double y) + { xScale0 = x; yScale0 = y; } + void setRotate(int rotateA) + { rotate0 = rotateA; } + void setClip(double llx, double lly, double urx, double ury) + { clipLLX0 = llx; clipLLY0 = lly; clipURX0 = urx; clipURY0 = ury; } + void setUnderlayCbk(void (*cbk)(PSOutputDev *psOut, void *data), + void *data) + { underlayCbk = cbk; underlayCbkData = data; } + void setOverlayCbk(void (*cbk)(PSOutputDev *psOut, void *data), + void *data) + { overlayCbk = cbk; overlayCbkData = data; } + +private: + + void init(PSOutputFunc outputFuncA, void *outputStreamA, + PSFileType fileTypeA, XRef *xrefA, Catalog *catalog, + int firstPage, int lastPage, PSOutMode modeA, + int imgLLXA, int imgLLYA, int imgURXA, int imgURYA, + GBool manualCtrlA, int paperWidthA, int paperHeightA, + GBool duplexA); + void setupResources(Dict *resDict); + void setupFonts(Dict *resDict); + void setupFont(GfxFont *font, Dict *parentResDict); + void setupEmbeddedType1Font(Ref *id, GooString *psName); + void setupExternalType1Font(GooString *fileName, GooString *psName); + void setupEmbeddedType1CFont(GfxFont *font, Ref *id, GooString *psName); + void setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, GooString *psName); + GooString *setupExternalTrueTypeFont(GfxFont *font); + void setupEmbeddedCIDType0Font(GfxFont *font, Ref *id, GooString *psName); + void setupEmbeddedCIDTrueTypeFont(GfxFont *font, Ref *id, GooString *psName, + GBool needVerticalMetrics); + GooString *setupExternalCIDTrueTypeFont(GfxFont *font, GooString *fileName, int faceIndex = 0); + void setupType3Font(GfxFont *font, GooString *psName, Dict *parentResDict); + void setupImages(Dict *resDict); + void setupImage(Ref id, Stream *str); + void addProcessColor(double c, double m, double y, double k); + void addCustomColor(GfxSeparationColorSpace *sepCS); + void doPath(GfxPath *path); + void doImageL1(Object *ref, GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len); + void doImageL1Sep(GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len); + void doImageL2(Object *ref, GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len, + int *maskColors, Stream *maskStr, + int maskWidth, int maskHeight, GBool maskInvert); + void dumpColorSpaceL2(GfxColorSpace *colorSpace, + GBool genXform, GBool updateColors); +#if OPI_SUPPORT + void opiBegin20(GfxState *state, Dict *dict); + void opiBegin13(GfxState *state, Dict *dict); + void opiTransform(GfxState *state, double x0, double y0, + double *x1, double *y1); + GBool getFileSpec(Object *fileSpec, Object *fileName); +#endif + void cvtFunction(Function *func); + void writePSChar(char c); + void writePS(char *s); + void writePSFmt(const char *fmt, ...) GCC_PRINTF_FORMAT(2, 3); + void writePSString(GooString *s); + void writePSName(char *s); + GooString *filterPSName(GooString *name); + + PSLevel level; // PostScript level (1, 2, separation) + PSOutMode mode; // PostScript mode (PS, EPS, form) + int paperWidth; // width of paper, in pts + int paperHeight; // height of paper, in pts + int imgLLX, imgLLY, // imageable area, in pts + imgURX, imgURY; + + PSOutputFunc outputFunc; + void *outputStream; + PSFileType fileType; // file / pipe / stdout + GBool manualCtrl; + int seqPage; // current sequential page number + void (*underlayCbk)(PSOutputDev *psOut, void *data); + void *underlayCbkData; + void (*overlayCbk)(PSOutputDev *psOut, void *data); + void *overlayCbkData; + + XRef *xref; // the xref table for this PDF file + + Ref *fontIDs; // list of object IDs of all used fonts + int fontIDLen; // number of entries in fontIDs array + int fontIDSize; // size of fontIDs array + Ref *fontFileIDs; // list of object IDs of all embedded fonts + int fontFileIDLen; // number of entries in fontFileIDs array + int fontFileIDSize; // size of fontFileIDs array + GooString **fontFileNames; // list of names of all embedded external fonts + GooString **psFileNames; // list of names of all embedded external fonts + int fontFileNameLen; // number of entries in fontFileNames array + int fontFileNameSize; // size of fontFileNames array + int nextTrueTypeNum; // next unique number to append to a TrueType + // font name + PSFont16Enc *font16Enc; // encodings for substitute 16-bit fonts + int font16EncLen; // number of entries in font16Enc array + int font16EncSize; // size of font16Enc array + GooList *xobjStack; // stack of XObject dicts currently being + // processed + int numSaves; // current number of gsaves + int numTilingPatterns; // current number of nested tiling patterns + int nextFunc; // next unique number to use for a function + + double tx0, ty0; // global translation + double xScale0, yScale0; // global scaling + int rotate0; // rotation angle (0, 90, 180, 270) + double clipLLX0, clipLLY0, + clipURX0, clipURY0; + double tx, ty; // global translation for current page + double xScale, yScale; // global scaling for current page + int rotate; // rotation angle for current page + double epsX1, epsY1, // EPS bounding box (unrotated) + epsX2, epsY2; + + GooString *embFontList; // resource comments for embedded fonts + + int processColors; // used process colors + PSOutCustomColor // used custom colors + *customColors; + + GBool haveTextClip; // set if text has been drawn with a + // clipping render mode + + GBool inType3Char; // inside a Type 3 CharProc + GooString *t3String; // Type 3 content string + double t3WX, t3WY, // Type 3 character parameters + t3LLX, t3LLY, t3URX, t3URY; + GBool t3Cacheable; // cleared if char is not cacheable + +#if OPI_SUPPORT + int opi13Nest; // nesting level of OPI 1.3 objects + int opi20Nest; // nesting level of OPI 2.0 objects +#endif + + GBool ok; // set up ok? + + + friend class WinPDFPrinter; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/PSTokenizer.cc b/rosapps/smartpdf/poppler/poppler/PSTokenizer.cc new file mode 100644 index 00000000000..e872787ccd8 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PSTokenizer.cc @@ -0,0 +1,144 @@ +//======================================================================== +// +// PSTokenizer.cc +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "PSTokenizer.h" + +//------------------------------------------------------------------------ + +// A '1' in this array means the character is white space. A '1' or +// '2' means the character ends a name or command. +static char specialChars[256] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx +}; + +//------------------------------------------------------------------------ + +PSTokenizer::PSTokenizer(int (*getCharFuncA)(void *), void *dataA) { + getCharFunc = getCharFuncA; + data = dataA; + charBuf = -1; +} + +PSTokenizer::~PSTokenizer() { +} + +GBool PSTokenizer::getToken(char *buf, int size, int *length) { + GBool comment, backslash; + int c; + int i; + + // skip leading whitespace and comments + comment = gFalse; + while (1) { + if ((c = getChar()) == EOF) { + buf[0] = '\0'; + *length = 0; + return gFalse; + } + if (comment) { + if (c == '\x0a' || c == '\x0d') { + comment = gFalse; + } + } else if (c == '%') { + comment = gTrue; + } else if (specialChars[c] != 1) { + break; + } + } + + // Reserve room for terminating '\0' + size--; + + // read a token + i = 0; + buf[i++] = c; + if (c == '(') { + backslash = gFalse; + while ((c = lookChar()) != EOF) { + consumeChar(); + if (i < size) { + buf[i++] = c; + } + if (c == '\\') { + backslash = gTrue; + } else if (!backslash && c == ')') { + break; + } else { + backslash = gFalse; + } + } + } else if (c == '<') { + while ((c = lookChar()) != EOF) { + consumeChar(); + if (i < size) { + buf[i++] = c; + } + if (c == '>') { + break; + } + } + } else if (c != '[' && c != ']') { + while ((c = lookChar()) != EOF && !specialChars[c]) { + consumeChar(); + if (i < size) { + buf[i++] = c; + } + } + } + // Zero terminate token string + buf[i] = '\0'; + // Return length of token + *length = i; + + return gTrue; +} + +int PSTokenizer::lookChar() { + if (charBuf < 0) { + charBuf = (*getCharFunc)(data); + } + return charBuf; +} + +void PSTokenizer::consumeChar() { + charBuf = -1; +} + +int PSTokenizer::getChar() { + int c = charBuf; + + if (c < 0) { + c = (*getCharFunc)(data); + } else { + charBuf = -1; + } + return c; +} diff --git a/rosapps/smartpdf/poppler/poppler/PSTokenizer.h b/rosapps/smartpdf/poppler/poppler/PSTokenizer.h new file mode 100644 index 00000000000..fa6d4c2795f --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PSTokenizer.h @@ -0,0 +1,40 @@ +//======================================================================== +// +// PSTokenizer.h +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef PSTOKENIZER_H +#define PSTOKENIZER_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +//------------------------------------------------------------------------ + +class PSTokenizer { +public: + + PSTokenizer(int (*getCharFuncA)(void *), void *dataA); + ~PSTokenizer(); + + // Get the next PostScript token. Returns false at end-of-stream. + GBool getToken(char *buf, int size, int *length); + +private: + + int lookChar(); + void consumeChar(); + int getChar(); + + int (*getCharFunc)(void *); + void *data; + int charBuf; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Page.cc b/rosapps/smartpdf/poppler/poppler/Page.cc new file mode 100644 index 00000000000..74cb45d8b1e --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Page.cc @@ -0,0 +1,566 @@ +//======================================================================== +// +// Page.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "GlobalParams.h" +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "Link.h" +#include "OutputDev.h" +#ifndef PDF_PARSER_ONLY +#include "Gfx.h" +#include "GfxState.h" +#include "Annot.h" +#include "TextOutputDev.h" +#endif +#include "Error.h" +#include "Page.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ +// PageAttrs +//------------------------------------------------------------------------ + +PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { + Object obj1; + + // get old/default values + if (attrs) { + mediaBox = attrs->mediaBox; + cropBox = attrs->cropBox; + haveCropBox = attrs->haveCropBox; + rotate = attrs->rotate; + attrs->resources.copy(&resources); + } else { + // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary + // but some (non-compliant) PDF files don't specify a MediaBox + mediaBox.x1 = 0; + mediaBox.y1 = 0; + mediaBox.x2 = 612; + mediaBox.y2 = 792; + cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0; + haveCropBox = gFalse; + rotate = 0; + resources.initNull(); + } + + // media box + readBox(dict, "MediaBox", &mediaBox); + + // crop box + if (readBox(dict, "CropBox", &cropBox)) { + haveCropBox = gTrue; + } + if (!haveCropBox) { + cropBox = mediaBox; + } + else + { + // cropBox can not be bigger than mediaBox + if (cropBox.x2 - cropBox.x1 > mediaBox.x2 - mediaBox.x1) + { + cropBox.x1 = mediaBox.x1; + cropBox.x2 = mediaBox.x2; + } + if (cropBox.y2 - cropBox.y1 > mediaBox.y2 - mediaBox.y1) + { + cropBox.y1 = mediaBox.y1; + cropBox.y2 = mediaBox.y2; + } + } + + // other boxes + bleedBox = cropBox; + readBox(dict, "BleedBox", &bleedBox); + trimBox = cropBox; + readBox(dict, "TrimBox", &trimBox); + artBox = cropBox; + readBox(dict, "ArtBox", &artBox); + + // rotate + dict->lookup("Rotate", &obj1); + if (obj1.isInt()) { + rotate = obj1.getInt(); + } + obj1.free(); + while (rotate < 0) { + rotate += 360; + } + while (rotate >= 360) { + rotate -= 360; + } + + // misc attributes + dict->lookup("LastModified", &lastModified); + dict->lookup("BoxColorInfo", &boxColorInfo); + dict->lookup("Group", &group); + dict->lookup("Metadata", &metadata); + dict->lookup("PieceInfo", &pieceInfo); + dict->lookup("SeparationInfo", &separationInfo); + + // resource dictionary + dict->lookup("Resources", &obj1); + if (obj1.isDict()) { + resources.free(); + obj1.copy(&resources); + } + obj1.free(); +} + +PageAttrs::~PageAttrs() { + lastModified.free(); + boxColorInfo.free(); + group.free(); + metadata.free(); + pieceInfo.free(); + separationInfo.free(); + resources.free(); +} + +GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { + PDFRectangle tmp; + double t; + Object obj1, obj2; + GBool ok; + + dict->lookup(key, &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 4) { + ok = gTrue; + obj1.arrayGet(0, &obj2); + if (obj2.isNum()) { + tmp.x1 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + obj1.arrayGet(1, &obj2); + if (obj2.isNum()) { + tmp.y1 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + obj1.arrayGet(2, &obj2); + if (obj2.isNum()) { + tmp.x2 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + obj1.arrayGet(3, &obj2); + if (obj2.isNum()) { + tmp.y2 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + if (ok) { + if (tmp.x1 > tmp.x2) { + t = tmp.x1; tmp.x1 = tmp.x2; tmp.x2 = t; + } + if (tmp.y1 > tmp.y2) { + t = tmp.y1; tmp.y1 = tmp.y2; tmp.y2 = t; + } + *box = tmp; + } + } else { + ok = gFalse; + } + obj1.free(); + return ok; +} + +//------------------------------------------------------------------------ +// Page +//------------------------------------------------------------------------ + +Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA) { + Object tmp; + + ok = gTrue; + xref = xrefA; + num = numA; + duration = -1; + + // get attributes + attrs = attrsA; + + // transtion + pageDict->lookupNF("Trans", &trans); + if (!(trans.isDict() || trans.isNull())) { + error(-1, "Page transition object (page %d) is wrong type (%s)", + num, trans.getTypeName()); + trans.free(); + } + + // duration + pageDict->lookupNF("Dur", &tmp); + if (!(tmp.isNum() || tmp.isNull())) { + error(-1, "Page duration object (page %d) is wrong type (%s)", + num, tmp.getTypeName()); + } else if (tmp.isNum()) { + duration = tmp.getNum(); + } + tmp.free(); + + // annotations + pageDict->lookupNF("Annots", &annots); + if (!(annots.isRef() || annots.isArray() || annots.isNull())) { + error(-1, "Page annotations object (page %d) is wrong type (%s)", + num, annots.getTypeName()); + annots.free(); + goto err2; + } + + // contents + pageDict->lookupNF("Contents", &contents); + if (!(contents.isRef() || contents.isArray() || + contents.isNull())) { + error(-1, "Page contents object (page %d) is wrong type (%s)", + num, contents.getTypeName()); + contents.free(); + goto err1; + } + + // thumb + pageDict->lookupNF("Thumb", &thumb); + if (!(thumb.isStream() || thumb.isNull() || thumb.isRef())) { + error(-1, "Page thumb object (page %d) is wrong type (%s)", + num, thumb.getTypeName()); + thumb.initNull(); + } + + // actions + pageDict->lookupNF("AA", &actions); + if (!(actions.isDict() || actions.isNull())) { + error(-1, "Page additional action object (page %d) is wrong type (%s)", + num, actions.getTypeName()); + actions.initNull(); + } + + return; + + trans.initNull(); + err2: + annots.initNull(); + err1: + contents.initNull(); + ok = gFalse; +} + +Page::~Page() { + delete attrs; + annots.free(); + contents.free(); +} + +void Page::display(OutputDev *out, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, + Links *links, Catalog *catalog, + GBool (*abortCheckCbk)(void *data), + void *abortCheckCbkData, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), + void *annotDisplayDecideCbkData) { + displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, -1, -1, -1, -1, links, catalog, + abortCheckCbk, abortCheckCbkData, + annotDisplayDecideCbk, annotDisplayDecideCbkData); +} + +Gfx *Page::createGfx(OutputDev *out, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, + int sliceX, int sliceY, int sliceW, int sliceH, + Links *links, Catalog *catalog, + GBool (*abortCheckCbk)(void *data), + void *abortCheckCbkData, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), + void *annotDisplayDecideCbkData) { + PDFRectangle *mediaBox, *cropBox, *baseBox; + PDFRectangle box; + Gfx *gfx; + double kx, ky; + + rotate += getRotate(); + if (rotate >= 360) { + rotate -= 360; + } else if (rotate < 0) { + rotate += 360; + } + + mediaBox = getMediaBox(); + cropBox = getCropBox(); + if (sliceW >= 0 && sliceH >= 0) { + baseBox = useMediaBox ? mediaBox : cropBox; + kx = 72.0 / hDPI; + ky = 72.0 / vDPI; + if (rotate == 90) { + if (out->upsideDown()) { + box.x1 = baseBox->x1 + ky * sliceY; + box.x2 = baseBox->x1 + ky * (sliceY + sliceH); + } else { + box.x1 = baseBox->x2 - ky * (sliceY + sliceH); + box.x2 = baseBox->x2 - ky * sliceY; + } + box.y1 = baseBox->y1 + kx * sliceX; + box.y2 = baseBox->y1 + kx * (sliceX + sliceW); + } else if (rotate == 180) { + box.x1 = baseBox->x2 - kx * (sliceX + sliceW); + box.x2 = baseBox->x2 - kx * sliceX; + if (out->upsideDown()) { + box.y1 = baseBox->y1 + ky * sliceY; + box.y2 = baseBox->y1 + ky * (sliceY + sliceH); + } else { + box.y1 = baseBox->y2 - ky * (sliceY + sliceH); + box.y2 = baseBox->y2 - ky * sliceY; + } + } else if (rotate == 270) { + if (out->upsideDown()) { + box.x1 = baseBox->x2 - ky * (sliceY + sliceH); + box.x2 = baseBox->x2 - ky * sliceY; + } else { + box.x1 = baseBox->x1 + ky * sliceY; + box.x2 = baseBox->x1 + ky * (sliceY + sliceH); + } + box.y1 = baseBox->y2 - kx * (sliceX + sliceW); + box.y2 = baseBox->y2 - kx * sliceX; + } else { + box.x1 = baseBox->x1 + kx * sliceX; + box.x2 = baseBox->x1 + kx * (sliceX + sliceW); + if (out->upsideDown()) { + box.y1 = baseBox->y2 - ky * (sliceY + sliceH); + box.y2 = baseBox->y2 - ky * sliceY; + } else { + box.y1 = baseBox->y1 + ky * sliceY; + box.y2 = baseBox->y1 + ky * (sliceY + sliceH); + } + } + } else if (useMediaBox) { + box = *mediaBox; + } else { + box = *cropBox; + crop = gFalse; + } + + if (globalParams->getPrintCommands()) { + printf("***** MediaBox = ll:%g,%g ur:%g,%g\n", + mediaBox->x1, mediaBox->y1, mediaBox->x2, mediaBox->y2); + printf("***** CropBox = ll:%g,%g ur:%g,%g\n", + cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2); + printf("***** Rotate = %d\n", attrs->getRotate()); + } + + gfx = new Gfx(xref, out, num, attrs->getResourceDict(), + hDPI, vDPI, &box, crop ? cropBox : (PDFRectangle *)NULL, + rotate, abortCheckCbk, abortCheckCbkData); + + return gfx; +} + +void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, + int sliceX, int sliceY, int sliceW, int sliceH, + Links *links, Catalog *catalog, + GBool (*abortCheckCbk)(void *data), + void *abortCheckCbkData, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), + void *annotDisplayDecideCbkData) { + Gfx *gfx; + Object obj; + Link *link; + Annots *annotList; + int i; + + gfx = createGfx(out, hDPI, vDPI, rotate, useMediaBox, crop, + sliceX, sliceY, sliceW, sliceH, + links, catalog, + abortCheckCbk, abortCheckCbkData, + annotDisplayDecideCbk, annotDisplayDecideCbkData); + + contents.fetch(xref, &obj); + if (!obj.isNull()) { + gfx->saveState(); + gfx->display(&obj); + gfx->restoreState(); + } + obj.free(); + + // draw links + if (links) { + gfx->saveState(); + for (i = 0; i < links->getNumLinks(); ++i) { + link = links->getLink(i); + out->drawLink(link, catalog); + } + gfx->restoreState(); + out->dump(); + } + + // draw non-link annotations + annotList = new Annots(xref, catalog, annots.fetch(xref, &obj)); + obj.free(); + if (annotList->getNumAnnots() > 0) { + if (globalParams->getPrintCommands()) { + printf("***** Annotations\n"); + } + for (i = 0; i < annotList->getNumAnnots(); ++i) { + Annot *annot = annotList->getAnnot(i); + if ((annotDisplayDecideCbk && + (*annotDisplayDecideCbk)(annot, annotDisplayDecideCbkData)) || + !annotDisplayDecideCbk) + annot->draw(gfx); + } + out->dump(); + } + delete annotList; + + delete gfx; +} + +void Page::display(Gfx *gfx) { + Object obj; + + contents.fetch(xref, &obj); + if (!obj.isNull()) { + gfx->saveState(); + gfx->display(&obj); + gfx->restoreState(); + } + obj.free(); +} + +GBool Page::loadThumb(unsigned char **data_out, + int *width_out, int *height_out, + int *rowstride_out) +{ + ImageStream *imgstr = NULL; + unsigned char *pixbufdata; + unsigned int pixbufdatasize; + int row, col; + int width, height, bits; + unsigned char *p; + Object obj1, fetched_thumb; + Dict *dict; + GfxColorSpace *colorSpace; + GBool success = gFalse; + Stream *str; + GfxImageColorMap *colorMap = NULL; + + /* Get stream dict */ + thumb.fetch(xref, &fetched_thumb); + if (fetched_thumb.isNull()) { + fetched_thumb.free(); + return gFalse; + } + + dict = fetched_thumb.streamGetDict(); + str = fetched_thumb.getStream(); + + if (!dict->lookupInt("Width", "W", &width)) + goto fail1; + if (!dict->lookupInt("Height", "H", &height)) + goto fail1; + if (!dict->lookupInt("BitsPerComponent", "BPC", &bits)) + goto fail1; + + /* Check for invalid dimensions and integer overflow. */ + if (width <= 0 || height <= 0) + goto fail1; + if (width > INT_MAX / 3 / height) + goto fail1; + pixbufdatasize = width * height * 3; + + /* Get color space */ + dict->lookup ("ColorSpace", &obj1); + if (obj1.isNull ()) { + obj1.free (); + dict->lookup ("CS", &obj1); + } + colorSpace = GfxColorSpace::parse(&obj1); + obj1.free(); + if (!colorSpace) { + fprintf (stderr, "Error: Cannot parse color space\n"); + goto fail1; + } + + dict->lookup("Decode", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("D", &obj1); + } + colorMap = new GfxImageColorMap(bits, &obj1, colorSpace); + obj1.free(); + if (!colorMap->isOk()) { + fprintf (stderr, "Error: invalid colormap\n"); + goto fail1; + } + + pixbufdata = (unsigned char *) gmalloc(pixbufdatasize); + p = pixbufdata; + imgstr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgstr->reset(); + for (row = 0; row < height; ++row) { + for (col = 0; col < width; ++col) { + Guchar pix[gfxColorMaxComps]; + GfxRGB rgb; + + imgstr->getPixel(pix); + colorMap->getRGB(pix, &rgb); + + *p++ = colToByte(rgb.r); + *p++ = colToByte(rgb.g); + *p++ = colToByte(rgb.b); + } + } + + success = gTrue; + + if (data_out) + *data_out = pixbufdata; + else + gfree(pixbufdata); + if (width_out) + *width_out = width; + if (height_out) + *height_out = height; + if (rowstride_out) + *rowstride_out = width * 3; + + delete imgstr; + fail1: + delete colorMap; + fetched_thumb.free(); + + return success; +} + +void Page::getDefaultCTM(double *ctm, double hDPI, double vDPI, + int rotate, GBool upsideDown) { + GfxState *state; + int i; + rotate += getRotate(); + if (rotate >= 360) { + rotate -= 360; + } else if (rotate < 0) { + rotate += 360; + } + state = new GfxState(hDPI, vDPI, getMediaBox(), rotate, upsideDown); + for (i = 0; i < 6; ++i) { + ctm[i] = state->getCTM()[i]; + } + delete state; +} diff --git a/rosapps/smartpdf/poppler/poppler/Page.h b/rosapps/smartpdf/poppler/poppler/Page.h new file mode 100644 index 00000000000..338615dcc75 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Page.h @@ -0,0 +1,210 @@ +//======================================================================== +// +// Page.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef PAGE_H +#define PAGE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "Object.h" + +class Dict; +class XRef; +class OutputDev; +class Links; +class Catalog; +class Annots; +class Annot; +class Gfx; + +//------------------------------------------------------------------------ + +class PDFRectangle { +public: + double x1, y1, x2, y2; + + PDFRectangle() { x1 = y1 = x2 = y2 = 0; } + PDFRectangle(double x1A, double y1A, double x2A, double y2A) + { x1 = x1A; y1 = y1A; x2 = x2A; y2 = y2A; } + GBool isValid() { return x1 != 0 || y1 != 0 || x2 != 0 || y2 != 0; } +}; + +//------------------------------------------------------------------------ +// PageAttrs +//------------------------------------------------------------------------ + +class PageAttrs { +public: + + // Construct a new PageAttrs object by merging a dictionary + // (of type Pages or Page) into another PageAttrs object. If + // is NULL, uses defaults. + PageAttrs(PageAttrs *attrs, Dict *dict); + + // Destructor. + ~PageAttrs(); + + // Accessors. + PDFRectangle *getMediaBox() { return &mediaBox; } + PDFRectangle *getCropBox() { return &cropBox; } + GBool isCropped() { return haveCropBox; } + PDFRectangle *getBleedBox() { return &bleedBox; } + PDFRectangle *getTrimBox() { return &trimBox; } + PDFRectangle *getArtBox() { return &artBox; } + int getRotate() { return rotate; } + GooString *getLastModified() + { return lastModified.isString() + ? lastModified.getString() : (GooString *)NULL; } + Dict *getBoxColorInfo() + { return boxColorInfo.isDict() ? boxColorInfo.getDict() : (Dict *)NULL; } + Dict *getGroup() + { return group.isDict() ? group.getDict() : (Dict *)NULL; } + Stream *getMetadata() + { return metadata.isStream() ? metadata.getStream() : (Stream *)NULL; } + Dict *getPieceInfo() + { return pieceInfo.isDict() ? pieceInfo.getDict() : (Dict *)NULL; } + Dict *getSeparationInfo() + { return separationInfo.isDict() + ? separationInfo.getDict() : (Dict *)NULL; } + Dict *getResourceDict() + { return resources.isDict() ? resources.getDict() : (Dict *)NULL; } + +private: + + GBool readBox(Dict *dict, char *key, PDFRectangle *box); + + PDFRectangle mediaBox; + PDFRectangle cropBox; + GBool haveCropBox; + PDFRectangle bleedBox; + PDFRectangle trimBox; + PDFRectangle artBox; + int rotate; + Object lastModified; + Object boxColorInfo; + Object group; + Object metadata; + Object pieceInfo; + Object separationInfo; + Object resources; +}; + +//------------------------------------------------------------------------ +// Page +//------------------------------------------------------------------------ + +class Page { +public: + + // Constructor. + Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA); + + // Destructor. + ~Page(); + + // Is page valid? + GBool isOk() { return ok; } + + // Get page parameters. + PDFRectangle *getMediaBox() { return attrs->getMediaBox(); } + PDFRectangle *getCropBox() { return attrs->getCropBox(); } + GBool isCropped() { return attrs->isCropped(); } + double getMediaWidth() + { return attrs->getMediaBox()->x2 - attrs->getMediaBox()->x1; } + double getMediaHeight() + { return attrs->getMediaBox()->y2 - attrs->getMediaBox()->y1; } + double getCropWidth() + { return attrs->getCropBox()->x2 - attrs->getCropBox()->x1; } + double getCropHeight() + { return attrs->getCropBox()->y2 - attrs->getCropBox()->y1; } + PDFRectangle *getBleedBox() { return attrs->getBleedBox(); } + PDFRectangle *getTrimBox() { return attrs->getTrimBox(); } + PDFRectangle *getArtBox() { return attrs->getArtBox(); } + int getRotate() { return attrs->getRotate(); } + GooString *getLastModified() { return attrs->getLastModified(); } + Dict *getBoxColorInfo() { return attrs->getBoxColorInfo(); } + Dict *getGroup() { return attrs->getGroup(); } + Stream *getMetadata() { return attrs->getMetadata(); } + Dict *getPieceInfo() { return attrs->getPieceInfo(); } + Dict *getSeparationInfo() { return attrs->getSeparationInfo(); } + + // Get resource dictionary. + Dict *getResourceDict() { return attrs->getResourceDict(); } + + // Get annotations array. + Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); } + + // Get contents. + Object *getContents(Object *obj) { return contents.fetch(xref, obj); } + + // Get thumb. + Object *getThumb(Object *obj) { return thumb.fetch(xref, obj); } + GBool loadThumb(unsigned char **data, int *width, int *height, int *rowstride); + + // Get transition. + Object *getTrans(Object *obj) { return trans.fetch(xref, obj); } + + // Get duration, the maximum length of time, in seconds, + // that the page is displayed before the presentation automatically + // advances to the next page + double getDuration() { return duration; } + + // Get actions + Object *getActions(Object *obj) { return actions.fetch(xref, obj); } + + Gfx *createGfx(OutputDev *out, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, + int sliceX, int sliceY, int sliceW, int sliceH, + Links *links, Catalog *catalog, + GBool (*abortCheckCbk)(void *data), + void *abortCheckCbkData, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), + void *annotDisplayDecideCbkData); + + // Display a page. + void display(OutputDev *out, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, + Links *links, Catalog *catalog, + GBool (*abortCheckCbk)(void *data) = NULL, + void *abortCheckCbkData = NULL, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, + void *annotDisplayDecideCbkData = NULL); + + // Display part of a page. + void displaySlice(OutputDev *out, double hDPI, double vDPI, + int rotate, GBool useMediaBox, GBool crop, + int sliceX, int sliceY, int sliceW, int sliceH, + Links *links, Catalog *catalog, + GBool (*abortCheckCbk)(void *data) = NULL, + void *abortCheckCbkData = NULL, + GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, + void *annotDisplayDecideCbkData = NULL); + + void display(Gfx *gfx); + + // Get the page's default CTM. + void getDefaultCTM(double *ctm, double hDPI, double vDPI, + int rotate, GBool upsideDown); + +private: + + XRef *xref; // the xref table for this PDF file + int num; // page number + PageAttrs *attrs; // page attributes + Object annots; // annotations array + Object contents; // page contents + Object thumb; // page thumbnail + Object trans; // page transition + Object actions; // page addiction actions + double duration; // page duration + GBool ok; // true if page is valid +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/PageLabelInfo.cc b/rosapps/smartpdf/poppler/poppler/PageLabelInfo.cc new file mode 100644 index 00000000000..525c04ce31d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PageLabelInfo.cc @@ -0,0 +1,376 @@ +#include +#include +#include +#include +#include +#include "UGooString.h" + +#include "PageLabelInfo.h" + +/* http://mathworld.wolfram.com/RomanNumerals.html */ + +static int fromRoman(const char *buffer) { + int digit_value, prev_digit_value, value; + int i; + + prev_digit_value = INT_MAX; + value = 0; + for (i = 0; buffer[i] != '\0'; i++) { + switch (buffer[i]) { + case 'm': + case 'M': + digit_value = 1000; + break; + case 'd': + case 'D': + digit_value = 500; + break; + case 'c': + case 'C': + digit_value = 100; + break; + case 'l': + case 'L': + digit_value = 50; + break; + case 'x': + case 'X': + digit_value = 10; + break; + case 'v': + case 'V': + digit_value = 5; + break; + case 'i': + case 'I': + digit_value = 1; + break; + default: + return -1; + } + + if (digit_value <= prev_digit_value) + value += digit_value; + else + value += digit_value - prev_digit_value * 2; + prev_digit_value = digit_value; + } + + return value; +} + +static void toRoman(int number, GooString *str, GBool uppercase) { + static const char uppercaseNumerals[] = "IVXLCDM"; + static const char lowercaseNumerals[] = "ivxlcdm"; + int divisor; + int i, j, k; + const char *wh; + + if (uppercase) + wh = uppercaseNumerals; + else + wh = lowercaseNumerals; + + divisor = 1000; + for (k = 3; k >= 0; k--) { + i = number / divisor; + number = number % divisor; + + switch (i) { + case 0: + break; + case 5: + str->append(wh[2 * k + 1]); + break; + case 9: + str->append(wh[2 * k + 0]); + str->append(wh[ 2 * k + 2]); + break; + case 4: + str->append(wh[2 * k + 0]); + str->append(wh[2 * k + 1]); + break; + default: + if (i > 5) { + str->append(wh[2 * k + 1]); + i -= 5; + } + for (j = 0; j < i; j++) { + str->append(wh[2 * k + 0]); + } + } + + divisor = divisor / 10; + } +} + +static int fromLatin(const char *buffer) +{ + int count; + const char *p; + + for (p = buffer; *p; p++) { + if (*p != buffer[0]) + return -1; + } + + count = p - buffer; + if (buffer[0] >= 'a' && buffer[0] <= 'z') + return 26 * (count - 1) + buffer[0] - 'a' + 1; + if (buffer[0] >= 'A' && buffer[0] <= 'Z') + return 26 * (count - 1) + buffer[0] - 'A' + 1; + + return -1; +} + +static void toLatin(int number, GooString *str, GBool uppercase) { + char base, letter; + int i, count; + + if (uppercase) + base = 'A'; + else + base = 'a'; + + count = (number - 1) / 26 + 1; + letter = base + (number - 1) % 26; + + for (i = 0; i < count; i++) + str->append(letter); +} + +PageLabelInfo::Interval::Interval(Object *dict, int baseA) { + Object obj; + + style = None; + if (dict->dictLookup("S", &obj)->isName()) { + if (obj.isName("D")) { + style = Arabic; + } else if (obj.isName("R")) { + style = UppercaseRoman; + } else if (obj.isName("r")) { + style = LowercaseRoman; + } else if (obj.isName("A")) { + style = UppercaseLatin; + } else if (obj.isName("a")) { + style = LowercaseLatin; + } + } + obj.free(); + + if (dict->dictLookup("P", &obj)->isString()) + prefix = obj.getString()->copy(); + else + prefix = new GooString(""); + obj.free(); + + if (dict->dictLookup("St", &obj)->isInt()) + first = obj.getInt(); + else + first = 1; + obj.free(); + + base = baseA; +} + +PageLabelInfo::Interval::~Interval() { + delete prefix; +} + +PageLabelInfo::PageLabelInfo(Object *tree, int numPages) { + int i; + Interval *interval, *next; + + parse(tree); + + for (i = 0; i < intervals.getLength(); i++) { + interval = (Interval *) intervals.get(i); + + if (i + 1 < intervals.getLength()) { + next = (Interval *) intervals.get(i + 1); + interval->length = next->base - interval->base; + } else { + interval->length = numPages - interval->base; + } + } +} + +PageLabelInfo::~PageLabelInfo() { + int i; + for (i = 0; i < intervals.getLength(); ++i) { + delete (Interval*)intervals.get(i); + } +} + +void PageLabelInfo::parse(Object *tree) { + Object nums, obj; + Object kids, kid, limits, low, high; + int i, base; + Interval *interval; + + // leaf node + if (tree->dictLookup("Nums", &nums)->isArray()) { + for (i = 0; i < nums.arrayGetLength(); i += 2) { + if (!nums.arrayGet(i, &obj)->isInt()) { + obj.free(); + continue; + } + base = obj.getInt(); + obj.free(); + if (!nums.arrayGet(i + 1, &obj)->isDict()) { + obj.free(); + continue; + } + + interval = new Interval(&obj, base); + obj.free(); + intervals.append(interval); + } + } + nums.free(); + + if (tree->dictLookup("Kids", &kids)->isArray()) { + for (i = 0; i < kids.arrayGetLength(); ++i) { + if (kids.arrayGet(i, &kid)->isDict()) + parse(&kid); + kid.free(); + } + } + kids.free(); +} + +GBool PageLabelInfo::labelToIndex(GooString *label, int *index) +{ + Interval *interval; + char *str = label->getCString(), *end; + int prefixLength; + int i, base, number; + + base = 0; + for (i = 0; i < intervals.getLength(); i++) { + interval = (Interval *) intervals.get(i); + prefixLength = interval->prefix->getLength(); + if (label->cmpN(interval->prefix, prefixLength) != 0) + continue; + + switch (interval->style) { + case Interval::Arabic: + number = strtol(str + prefixLength, &end, 10); + if (*end == '\0' && number - interval->first < interval->length) { + *index = base + number - interval->first; + return gTrue; + } + break; + case Interval::LowercaseRoman: + case Interval::UppercaseRoman: + number = fromRoman(str + prefixLength); + if (number >= 0 && number - interval->first < interval->length) { + *index = base + number - interval->first; + return gTrue; + } + break; + case Interval::UppercaseLatin: + case Interval::LowercaseLatin: + number = fromLatin(str + prefixLength); + if (number >= 0 && number - interval->first < interval->length) { + *index = base + number - interval->first; + return gTrue; + } + break; + case Interval::None: + break; + } + + base += interval->length; + } + + return gFalse; +} + +GBool PageLabelInfo::indexToLabel(int index, GooString *label) +{ + char buffer[32]; + int i, base, number; + Interval *interval; + GooString number_string; + + base = 0; + interval = NULL; + for (i = 0; i < intervals.getLength(); i++) { + interval = (Interval *) intervals.get(i); + if (base <= index && index < base + interval->length) + break; + base += interval->length; + } + + if (i == intervals.getLength()) + return gFalse; + + number = index - base + interval->first; + switch (interval->style) { + case Interval::Arabic: + snprintf (buffer, sizeof(buffer), "%d", number); + number_string.append(buffer); + break; + case Interval::LowercaseRoman: + toRoman(number, &number_string, gFalse); + break; + case Interval::UppercaseRoman: + toRoman(number, &number_string, gTrue); + break; + case Interval::UppercaseLatin: + case Interval::LowercaseLatin: + number = 0; + break; + case Interval::None: + break; + } + + label->clear(); + label->append(interval->prefix); + if (label->hasUnicodeMarker()) { + int i, len; + char ucs2_char[2]; + + /* Convert the ascii number string to ucs2 and append. */ + len = number_string.getLength (); + ucs2_char[0] = 0; + for (i = 0; i < len; ++i) { + ucs2_char[1] = number_string.getChar(i); + label->append(ucs2_char, 2); + } + ucs2_char[1] = 0; + label->append(ucs2_char, 2); + } else { + label->append(&number_string); + } + + return gTrue; +} + +#ifdef TEST +int main(int argc, char *argv[]) +{ + { + GooString str; + toRoman(177, &str, gFalse); + assert (str.cmp("clxxvii") == 0); + } + + { + GooString roman("clxxvii"); + assert (fromRoman(roman.getCString()) == 177); + } + + { + GooString str; + toLatin(54, &str, gFalse); + assert (str.cmp("bbb") == 0); + } + + { + GooString latin("ddd"); + assert (fromLatin(latin.getCString()) == 56); + } +} +#endif diff --git a/rosapps/smartpdf/poppler/poppler/PageLabelInfo.h b/rosapps/smartpdf/poppler/poppler/PageLabelInfo.h new file mode 100644 index 00000000000..f7364194daf --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PageLabelInfo.h @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +class PageLabelInfo { +public: + PageLabelInfo(Object *tree, int numPages); + ~PageLabelInfo(); + GBool labelToIndex(GooString *label, int *index); + GBool indexToLabel(int index, GooString *label); + +private: + void parse(Object *tree); + +private: + struct Interval { + Interval(Object *dict, int baseA); + ~Interval(); + GooString *prefix; + enum NumberStyle { + None, + Arabic, + LowercaseRoman, + UppercaseRoman, + UppercaseLatin, + LowercaseLatin + } style; + int first, base, length; + }; + + GooList intervals; +}; diff --git a/rosapps/smartpdf/poppler/poppler/PageTransition.cc b/rosapps/smartpdf/poppler/poppler/PageTransition.cc new file mode 100644 index 00000000000..2c4b0f07208 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/PageTransition.cc @@ -0,0 +1,189 @@ +/* PageTransition.cc + * Copyright (C) 2005, Net Integration Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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 + +#include "Error.h" +#include "Object.h" +#include "PageTransition.h" +#include "Private.h" + +namespace Poppler { + +class PageTransitionData +{ + public: + PageTransition::Type type; + int duration; + PageTransition::Alignment alignment; + PageTransition::Direction direction; + int angle; + double scale; + bool rectangular; +}; + +PageTransition::PageTransition(const PageTransitionParams ¶ms) +{ + data = new PageTransitionData(); + data->type = Replace; + data->duration = 1; + data->alignment = Horizontal; + data->direction = Inward; + data->angle = 0; + data->scale = 1.0; + data->rectangular = false; + + // Paranoid safety checks + if (params.dictObj == 0) { + error(-1, "PageTransition::PageTransition() called with params.dictObj==0"); + return; + } + if (params.dictObj->isDict() == false) { + error(-1, "PageTransition::PageTransition() called with params.dictObj->isDict()==false"); + return; + } + + // Obtain a pointer to the dictionary and start parsing. + Dict *transDict = params.dictObj->getDict(); + Object obj; + + if (transDict->lookup("S", &obj)->isName()) { + const char *s = obj.getName(); + if (strcmp("R", s) == 0) + data->type = Replace; + else if (strcmp("Split", s) == 0) + data->type = Split; + else if (strcmp("Blinds", s) == 0) + data->type = Blinds; + else if (strcmp("Box", s) == 0) + data->type = Box; + else if (strcmp("Wipe", s) == 0) + data->type = Wipe; + else if (strcmp("Dissolve", s) == 0) + data->type = Dissolve; + else if (strcmp("Glitter", s) == 0) + data->type = Glitter; + else if (strcmp("Fly", s) == 0) + data->type = Fly; + else if (strcmp("Push", s) == 0) + data->type = Push; + else if (strcmp("Cover", s) == 0) + data->type = Cover; + else if (strcmp("Uncover", s) == 0) + data->type = Push; + else if (strcmp("Fade", s) == 0) + data->type = Cover; + } + obj.free(); + + if (transDict->lookup("D", &obj)->isInt()) { + data->duration = obj.getInt(); + } + obj.free(); + + if (transDict->lookup("Dm", &obj)->isName()) { + const char *dm = obj.getName(); + if ( strcmp( "H", dm ) == 0 ) + data->alignment = Horizontal; + else if ( strcmp( "V", dm ) == 0 ) + data->alignment = Vertical; + } + obj.free(); + + if (transDict->lookup("M", &obj)->isName()) { + const char *m = obj.getName(); + if ( strcmp( "I", m ) == 0 ) + data->direction = Inward; + else if ( strcmp( "O", m ) == 0 ) + data->direction = Outward; + } + obj.free(); + + if (transDict->lookup("Di", &obj)->isInt()) { + data->angle = obj.getInt(); + } + obj.free(); + + if (transDict->lookup("Di", &obj)->isName()) { + if ( strcmp( "None", obj.getName() ) == 0 ) + data->angle = 0; + } + obj.free(); + + if (transDict->lookup("SS", &obj)->isReal()) { + data->scale = obj.getReal(); + } + obj.free(); + + if (transDict->lookup("B", &obj)->isBool()) { + data->rectangular = obj.getBool(); + } + obj.free(); +} + +PageTransition::PageTransition(const PageTransition &pt) +{ + data = new PageTransitionData(); + data->type = pt.data->type; + data->duration = pt.data->duration; + data->alignment = pt.data->alignment; + data->direction = pt.data->direction; + data->angle = pt.data->angle; + data->scale = pt.data->scale; + data->rectangular = pt.data->rectangular; +} + +PageTransition::~PageTransition() +{ +} + +PageTransition::Type PageTransition::type() const +{ + return data->type; +} + +int PageTransition::duration() const +{ + return data->duration; +} + +PageTransition::Alignment PageTransition::alignment() const +{ + return data->alignment; +} + +PageTransition::Direction PageTransition::direction() const +{ + return data->direction; +} + +int PageTransition::angle() const +{ + return data->angle; +} + +double PageTransition::scale() const +{ + return data->scale; +} +bool PageTransition::isRectangular() const +{ + return data->rectangular; +} + +} diff --git a/rosapps/smartpdf/poppler/poppler/Parser.cc b/rosapps/smartpdf/poppler/poppler/Parser.cc new file mode 100644 index 00000000000..2b26c08bf3c --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Parser.cc @@ -0,0 +1,216 @@ +//======================================================================== +// +// Parser.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Parser.h" +#include "XRef.h" +#include "Error.h" +#include "Decrypt.h" +#include "UGooString.h" + +Parser::Parser(XRef *xrefA, Lexer *lexerA) { + xref = xrefA; + lexer = lexerA; + inlineImg = 0; + lexer->getObj(&buf1); + lexer->getObj(&buf2); +} + +Parser::~Parser() { + buf1.free(); + buf2.free(); + delete lexer; +} + +Object *Parser::getObj(Object *obj, + Guchar *fileKey, int keyLength, + int objNum, int objGen) { + Stream *str; + Object obj2; + int num; + Decrypt *decrypt; + GooString *s; + char *p; + int i; + + // refill buffer after inline image data + if (inlineImg == 2) { + buf1.free(); + buf2.free(); + lexer->getObj(&buf1); + lexer->getObj(&buf2); + inlineImg = 0; + } + + // array + if (buf1.isCmd("[")) { + shift(); + obj->initArray(xref); + while (!buf1.isCmd("]") && !buf1.isEOF()) + obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen)); + if (buf1.isEOF()) + error(getPos(), "End of file inside array"); + shift(); + + // dictionary or stream + } else if (buf1.isCmd("<<")) { + shift(objNum); + obj->initDict(xref); + while (!buf1.isCmd(">>") && !buf1.isEOF()) { + if (!buf1.isName()) { + error(getPos(), "Dictionary key must be a name object"); + shift(); + } else { + // buf1 might go away in shift(), so construct the key + UGooString *key = new UGooString(buf1.getNameC()); + shift(); + if (buf1.isEOF() || buf1.isError()) { + delete key; + break; + } + obj->dictAddOwnKeyVal(key, getObj(&obj2, fileKey, keyLength, objNum, objGen)); + } + } + if (buf1.isEOF()) + error(getPos(), "End of file inside dictionary"); + if (buf2.isCmd("stream")) { + if ((str = makeStream(obj))) { + obj->initStream(str); + if (fileKey) { + str->getBaseStream()->doDecryption(fileKey, keyLength, + objNum, objGen); + } + } else { + obj->free(); + obj->initError(); + } + } else { + shift(); + } + + // indirect reference or integer + } else if (buf1.isInt()) { + num = buf1.getInt(); + shift(); + if (buf1.isInt() && buf2.isCmd("R")) { + obj->initRef(num, buf1.getInt()); + shift(); + shift(); + } else { + obj->initInt(num); + } + + // string + } else if (buf1.isString() && fileKey) { + buf1.copy(obj); + s = obj->getString(); + decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); + for (i = 0, p = obj->getString()->getCString(); + i < s->getLength(); + ++i, ++p) { + *p = decrypt->decryptByte(*p); + } + delete decrypt; + shift(); + + // simple object + } else { + // avoid re-allocating memory for complex objects like strings by + // shallow copy of to and nulling so that + // subsequent buf1.free() won't free this memory + buf1.shallowCopy(obj); + buf1.initNull(); + shift(); + } + + return obj; +} + +Stream *Parser::makeStream(Object *dict) { + Object obj; + BaseStream *baseStr; + Stream *str; + Guint pos, endPos, length; + + // get stream start position + lexer->skipToNextLine(); + pos = lexer->getPos(); + + // get length + dict->dictLookup("Length", &obj); + if (obj.isInt()) { + length = (Guint)obj.getInt(); + obj.free(); + } else { + error(getPos(), "Bad 'Length' attribute in stream"); + obj.free(); + return NULL; + } + + // check for length in damaged file + if (xref && xref->getStreamEnd(pos, &endPos)) { + length = endPos - pos; + } + + // in badly damaged PDF files, we can run off the end of the input + // stream immediately after the "stream" token + if (!lexer->getStream()) { + return NULL; + } + baseStr = lexer->getStream()->getBaseStream(); + lexer->setPos(pos + length); + // refill token buffers and check for 'endstream' + shift(); // kill '>>' + shift(); // kill 'stream' + if (buf1.isCmd("endstream")) { + shift(); + } else { + error(getPos(), "Missing 'endstream'"); + // kludge for broken PDF files: just add 5k to the length, and + // hope its enough + length += 5000; + } + + // make base stream + str = baseStr->makeSubStream(pos, gTrue, length, dict); + + // get filters + str = str->addFilters(dict); + + return str; +} + +void Parser::shift(int objNum) { + if (inlineImg > 0) { + if (inlineImg < 2) { + ++inlineImg; + } else { + // in a damaged content stream, if 'ID' shows up in the middle + // of a dictionary, we need to reset + inlineImg = 0; + } + } else if (buf2.isCmd("ID")) { + lexer->skipChar(); // skip char after 'ID' command + inlineImg = 1; + } + buf1.free(); + buf2.shallowCopy(&buf1); + if (inlineImg > 0) // don't buffer inline image data + buf2.initNull(); + else + lexer->getObj(&buf2, objNum); +} diff --git a/rosapps/smartpdf/poppler/poppler/Parser.h b/rosapps/smartpdf/poppler/poppler/Parser.h new file mode 100644 index 00000000000..53d0fe3551d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Parser.h @@ -0,0 +1,52 @@ +//======================================================================== +// +// Parser.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef PARSER_H +#define PARSER_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "Lexer.h" + +//------------------------------------------------------------------------ +// Parser +//------------------------------------------------------------------------ + +class Parser { +public: + + Parser(XRef *xrefA, Lexer *lexerA); + + ~Parser(); + + // Get the next object from the input stream. + Object *getObj(Object *obj, + Guchar *fileKey = NULL, int keyLength = 0, + int objNum = 0, int objGen = 0); + + // Get stream. + Stream *getStream() { return lexer->getStream(); } + + // Get current position in file. + int getPos() { return lexer->getPos(); } + +private: + + XRef *xref; // the xref table for this PDF file + Lexer *lexer; // input stream + Object buf1, buf2; // next two tokens + int inlineImg; // set when inline image data is encountered + + Stream *makeStream(Object *dict); + void shift(int objNum = -1); +}; + +#endif + diff --git a/rosapps/smartpdf/poppler/poppler/ProfileData.cc b/rosapps/smartpdf/poppler/poppler/ProfileData.cc new file mode 100644 index 00000000000..a0c44747a56 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/ProfileData.cc @@ -0,0 +1,44 @@ +//======================================================================== +// +// ProfileData.cc +// +// Copyright 2005 Jonathan Blandford +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "ProfileData.h" + +//------------------------------------------------------------------------ +// ProfileData +//------------------------------------------------------------------------ + +ProfileData::ProfileData() { + count = 0; + total = 0.0; + min = 0.0; + max = 0.0; +} + +void +ProfileData::addElement (double elapsed) { + if (count == 0) { + min = elapsed; + max = elapsed; + } else { + if (elapsed < min) + min = elapsed; + if (elapsed > max) + max = elapsed; + } + total += elapsed; + count ++; +} + diff --git a/rosapps/smartpdf/poppler/poppler/ProfileData.h b/rosapps/smartpdf/poppler/poppler/ProfileData.h new file mode 100644 index 00000000000..418ee010755 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/ProfileData.h @@ -0,0 +1,41 @@ +//======================================================================== +// +// ProfileData.h +// +// Copyright 2005 Jonathan Blandford +// +//======================================================================== + +#ifndef PROFILE_DATA_H +#define PROFILE_DATA_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +//------------------------------------------------------------------------ +// ProfileData +//------------------------------------------------------------------------ + +class ProfileData { +public: + + // Constructor. + ProfileData (); + + // Destructor. + ~ProfileData() {} + + void addElement (double elapsed); + int getCount () { return count; } + double getTotal () { return total; } + double getMin () { return max; } + double getMax () { return max; } +private: + int count; // size of array + double total; // number of elements in array + double min; // reference count + double max; // reference count +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/SecurityHandler.cc b/rosapps/smartpdf/poppler/poppler/SecurityHandler.cc new file mode 100644 index 00000000000..e0ef2f8c3ef --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/SecurityHandler.cc @@ -0,0 +1,360 @@ +//======================================================================== +// +// SecurityHandler.cc +// +// Copyright 2004 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "GooString.h" +#include "PDFDoc.h" +#include "Decrypt.h" +#include "Error.h" +#include "GlobalParams.h" +#if HAVE_XPDFCORE +# include "XPDFCore.h" +#elif HAVE_WINPDFCORE +# include "WinPDFCore.h" +#endif +#ifdef ENABLE_PLUGINS +# include "XpdfPluginAPI.h" +#endif +#include "SecurityHandler.h" +#include "UGooString.h" + +//------------------------------------------------------------------------ +// SecurityHandler +//------------------------------------------------------------------------ + +SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) { + Object filterObj; + SecurityHandler *secHdlr; + + encryptDictA->dictLookup("Filter", &filterObj); + if (filterObj.isName("Standard")) { + secHdlr = new StandardSecurityHandler(docA, encryptDictA); + } else if (filterObj.isName()) { +#ifdef ENABLE_PLUGINS + XpdfSecurityHandler *xsh; + if ((xsh = globalParams->getSecurityHandler(filterObj.getName()))) { + secHdlr = new ExternalSecurityHandler(docA, encryptDictA, xsh); + } else { +#endif + error(-1, "Couldn't find the '%s' security handler", filterObj.getNameC()); + secHdlr = NULL; +#ifdef ENABLE_PLUGINS + } +#endif + } else { + error(-1, "Missing or invalid 'Filter' entry in encryption dictionary"); + secHdlr = NULL; + } + filterObj.free(); + return secHdlr; +} + +SecurityHandler::SecurityHandler(PDFDoc *docA) { + doc = docA; +} + +SecurityHandler::~SecurityHandler() { +} + +GBool SecurityHandler::checkEncryption(GooString *ownerPassword, + GooString *userPassword) { + void *authData; + GBool ok; + int i; + + if (ownerPassword || userPassword) { + authData = makeAuthData(ownerPassword, userPassword); + } else { + authData = NULL; + } + ok = authorize(authData); + if (authData) { + freeAuthData(authData); + } + for (i = 0; !ok && i < 3; ++i) { + if (!(authData = getAuthData())) { + break; + } + ok = authorize(authData); + if (authData) { + freeAuthData(authData); + } + } + if (!ok) { + error(-1, "Incorrect password"); + } + return ok; +} + +//------------------------------------------------------------------------ +// StandardSecurityHandler +//------------------------------------------------------------------------ + +StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA, + Object *encryptDictA): + SecurityHandler(docA) +{ + Object versionObj, revisionObj, lengthObj; + Object ownerKeyObj, userKeyObj, permObj, fileIDObj; + Object fileIDObj1; + Object cryptFiltersObj, streamFilterObj, stringFilterObj; + Object cryptFilterObj, cfmObj, cfLengthObj; + Object encryptMetadataObj; + + ok = gFalse; + fileID = NULL; + ownerKey = NULL; + userKey = NULL; + + encryptDictA->dictLookup("V", &versionObj); + encryptDictA->dictLookup("R", &revisionObj); + encryptDictA->dictLookup("Length", &lengthObj); + encryptDictA->dictLookup("O", &ownerKeyObj); + encryptDictA->dictLookup("U", &userKeyObj); + encryptDictA->dictLookup("P", &permObj); + doc->getXRef()->getTrailerDict()->dictLookup("ID", &fileIDObj); + if (versionObj.isInt() && + revisionObj.isInt() && + ownerKeyObj.isString() && ownerKeyObj.getString()->getLength() == 32 && + userKeyObj.isString() && userKeyObj.getString()->getLength() == 32 && + permObj.isInt()) { + encVersion = versionObj.getInt(); + encRevision = revisionObj.getInt(); + // revision 2 forces a 40-bit key - some buggy PDF generators + // set the Length value incorrectly + if (encRevision == 2 || !lengthObj.isInt()) { + fileKeyLength = 5; + } else { + fileKeyLength = lengthObj.getInt() / 8; + } + encryptMetadata = gTrue; + //~ this currently only handles a subset of crypt filter functionality + if (encVersion == 4 && encRevision == 4) { + encryptDictA->dictLookup("CF", &cryptFiltersObj); + encryptDictA->dictLookup("StmF", &streamFilterObj); + encryptDictA->dictLookup("StrF", &stringFilterObj); + if (cryptFiltersObj.isDict() && + streamFilterObj.isName() && + stringFilterObj.isName() && + !strcmp(streamFilterObj.getNameC(), stringFilterObj.getNameC())) { + if (cryptFiltersObj.dictLookup(streamFilterObj.getNameC(), + &cryptFilterObj)->isDict()) { + if (cryptFilterObj.dictLookup("CFM", &cfmObj)->isName("V2")) { + encVersion = 2; + encRevision = 3; + if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) { + //~ according to the spec, this should be cfLengthObj / 8 + fileKeyLength = cfLengthObj.getInt(); + } + cfLengthObj.free(); + } + cfmObj.free(); + } + cryptFilterObj.free(); + } + stringFilterObj.free(); + streamFilterObj.free(); + cryptFiltersObj.free(); + if (encryptDictA->dictLookup("EncryptMetadata", + &encryptMetadataObj)->isBool()) { + encryptMetadata = encryptMetadataObj.getBool(); + } + encryptMetadataObj.free(); + } + permFlags = permObj.getInt(); + ownerKey = ownerKeyObj.getString()->copy(); + userKey = userKeyObj.getString()->copy(); + if (encVersion >= 1 && encVersion <= 2 && + encRevision >= 2 && encRevision <= 3) { + if (fileIDObj.isArray()) { + if (fileIDObj.arrayGet(0, &fileIDObj1)->isString()) { + fileID = fileIDObj1.getString()->copy(); + } else { + fileID = new GooString(); + } + fileIDObj1.free(); + } else { + fileID = new GooString(); + } + ok = gTrue; + } else { + error(-1, "Unsupported version/revision (%d/%d) of Standard security handler", + encVersion, encRevision); + } + } else { + error(-1, "Weird encryption info"); + } + if (fileKeyLength > 16) { + fileKeyLength = 16; + } + fileIDObj.free(); + permObj.free(); + userKeyObj.free(); + ownerKeyObj.free(); + lengthObj.free(); + revisionObj.free(); + versionObj.free(); +} + +StandardSecurityHandler::~StandardSecurityHandler() { + if (fileID) { + delete fileID; + } + if (ownerKey) { + delete ownerKey; + } + if (userKey) { + delete userKey; + } +} + +void *StandardSecurityHandler::makeAuthData(GooString *ownerPassword, + GooString *userPassword) { + return new StandardAuthData(ownerPassword ? ownerPassword->copy() + : (GooString *)NULL, + userPassword ? userPassword->copy() + : (GooString *)NULL); +} + +/* If USE_OWN_GET_AUTH_DATA is defined, the client has to provide this method + by itself. That way it's possible to use it in different UIs without the + need to modify poppler sources */ +#ifndef USE_OWN_GET_AUTH_DATA +void *StandardSecurityHandler::getAuthData() { +#if HAVE_XPDFCORE + XPDFCore *core; + GooString *password; + + if (!(core = (XPDFCore *)doc->getGUIData()) || + !(password = core->getPassword())) { + return NULL; + } + return new StandardAuthData(password, password->copy()); +#elif HAVE_WINPDFCORE + WinPDFCore *core; + GooString *password; + + if (!(core = (WinPDFCore *)doc->getGUIData()) || + !(password = core->getPassword())) { + return NULL; + } + return new StandardAuthData(password, password->copy()); +#else + return NULL; +#endif +} +#endif + +void StandardSecurityHandler::freeAuthData(void *authData) { + delete (StandardAuthData *)authData; +} + +GBool StandardSecurityHandler::authorize(void *authData) { + GooString *ownerPassword, *userPassword; + + if (!ok) { + return gFalse; + } + if (authData) { + ownerPassword = ((StandardAuthData *)authData)->ownerPassword; + userPassword = ((StandardAuthData *)authData)->userPassword; + } else { + ownerPassword = NULL; + userPassword = NULL; + } + if (!Decrypt::makeFileKey(encVersion, encRevision, fileKeyLength, + ownerKey, userKey, permFlags, fileID, + ownerPassword, userPassword, fileKey, + encryptMetadata, &ownerPasswordOk)) { + return gFalse; + } + return gTrue; +} + +#ifdef ENABLE_PLUGINS + +//------------------------------------------------------------------------ +// ExternalSecurityHandler +//------------------------------------------------------------------------ + +ExternalSecurityHandler::ExternalSecurityHandler(PDFDoc *docA, + Object *encryptDictA, + XpdfSecurityHandler *xshA): + SecurityHandler(docA) +{ + encryptDictA->copy(&encryptDict); + xsh = xshA; + ok = gFalse; + + if (!(*xsh->newDoc)(xsh->handlerData, (XpdfDoc)docA, + (XpdfObject)encryptDictA, &docData)) { + return; + } + + ok = gTrue; +} + +ExternalSecurityHandler::~ExternalSecurityHandler() { + (*xsh->freeDoc)(xsh->handlerData, docData); + encryptDict.free(); +} + +void *ExternalSecurityHandler::makeAuthData(GooString *ownerPassword, + GooString *userPassword) { + char *opw, *upw; + void *authData; + + opw = ownerPassword ? ownerPassword->getCString() : (char *)NULL; + upw = userPassword ? userPassword->getCString() : (char *)NULL; + if (!(*xsh->makeAuthData)(xsh->handlerData, docData, opw, upw, &authData)) { + return NULL; + } + return authData; +} + +void *ExternalSecurityHandler::getAuthData() { + void *authData; + + if (!(*xsh->getAuthData)(xsh->handlerData, docData, &authData)) { + return NULL; + } + return authData; +} + +void ExternalSecurityHandler::freeAuthData(void *authData) { + (*xsh->freeAuthData)(xsh->handlerData, docData, authData); +} + +GBool ExternalSecurityHandler::authorize(void *authData) { + char *key; + int length; + + if (!ok) { + return gFalse; + } + permFlags = (*xsh->authorize)(xsh->handlerData, docData, authData); + if (!(permFlags & xpdfPermissionOpen)) { + return gFalse; + } + if (!(*xsh->getKey)(xsh->handlerData, docData, &key, &length, &encVersion)) { + return gFalse; + } + if ((fileKeyLength = length) > 16) { + fileKeyLength = 16; + } + memcpy(fileKey, key, fileKeyLength); + (*xsh->freeKey)(xsh->handlerData, docData, key, length); + return gTrue; +} + +#endif // ENABLE_PLUGINS diff --git a/rosapps/smartpdf/poppler/poppler/SecurityHandler.h b/rosapps/smartpdf/poppler/poppler/SecurityHandler.h new file mode 100644 index 00000000000..4177f461898 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/SecurityHandler.h @@ -0,0 +1,174 @@ +//======================================================================== +// +// SecurityHandler.h +// +// Copyright 2004 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef SECURITYHANDLER_H +#define SECURITYHANDLER_H + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "gtypes.h" +#include "Object.h" + +class GooString; +class PDFDoc; +struct XpdfSecurityHandler; + +//------------------------------------------------------------------------ +// SecurityHandler +//------------------------------------------------------------------------ + +class SecurityHandler { +public: + + static SecurityHandler *make(PDFDoc *docA, Object *encryptDictA); + + SecurityHandler(PDFDoc *docA); + virtual ~SecurityHandler(); + + // Check the document's encryption. If the document is encrypted, + // this will first try and (in + // "batch" mode), and if those fail, it will attempt to request a + // password from the user. This is the high-level function that + // calls the lower level functions for the specific security handler + // (requesting a password three times, etc.). Returns true if the + // document can be opened (if it's unencrypted, or if a correct + // password is obtained); false otherwise (encrypted and no correct + // password). + GBool checkEncryption(GooString *ownerPassword, + GooString *userPassword); + + // Create authorization data for the specified owner and user + // passwords. If the security handler doesn't support "batch" mode, + // this function should return NULL. + virtual void *makeAuthData(GooString *ownerPassword, + GooString *userPassword) = 0; + + // Construct authorization data, typically by prompting the user for + // a password. Returns an authorization data object, or NULL to + // cancel. + virtual void *getAuthData() = 0; + + // Free the authorization data returned by makeAuthData or + // getAuthData. + virtual void freeAuthData(void *authData) = 0; + + // Attempt to authorize the document, using the supplied + // authorization data (which may be NULL). Returns true if + // successful (i.e., if at least the right to open the document was + // granted). + virtual GBool authorize(void *authData) = 0; + + // Return the various authorization parameters. These are only + // valid after authorize has returned true. + virtual int getPermissionFlags() = 0; + virtual GBool getOwnerPasswordOk() = 0; + virtual Guchar *getFileKey() = 0; + virtual int getFileKeyLength() = 0; + virtual int getEncVersion() = 0; + virtual int getEncRevision() = 0; + +protected: + + PDFDoc *doc; +}; + +//------------------------------------------------------------------------ +// StandardSecurityHandler +//------------------------------------------------------------------------ + +class StandardAuthData { +public: + + StandardAuthData(GooString *ownerPasswordA, GooString *userPasswordA) { + ownerPassword = ownerPasswordA; + userPassword = userPasswordA; + } + + ~StandardAuthData() { + delete ownerPassword; + delete userPassword; + } + + GooString *ownerPassword; + GooString *userPassword; +}; + +class StandardSecurityHandler: public SecurityHandler { +public: + + StandardSecurityHandler(PDFDoc *docA, Object *encryptDictA); + virtual ~StandardSecurityHandler(); + + virtual void *makeAuthData(GooString *ownerPassword, + GooString *userPassword); + virtual void *getAuthData(); + virtual void freeAuthData(void *authData); + virtual GBool authorize(void *authData); + virtual int getPermissionFlags() { return permFlags; } + virtual GBool getOwnerPasswordOk() { return ownerPasswordOk; } + virtual Guchar *getFileKey() { return fileKey; } + virtual int getFileKeyLength() { return fileKeyLength; } + virtual int getEncVersion() { return encVersion; } + virtual int getEncRevision() { return encRevision; } + +private: + + int permFlags; + GBool ownerPasswordOk; + Guchar fileKey[16]; + int fileKeyLength; + int encVersion; + int encRevision; + GBool encryptMetadata; + + GooString *ownerKey, *userKey; + GooString *fileID; + GBool ok; +}; + +#ifdef ENABLE_PLUGINS +//------------------------------------------------------------------------ +// ExternalSecurityHandler +//------------------------------------------------------------------------ + +class ExternalSecurityHandler: public SecurityHandler { +public: + + ExternalSecurityHandler(PDFDoc *docA, Object *encryptDictA, + XpdfSecurityHandler *xshA); + virtual ~ExternalSecurityHandler(); + + virtual void *makeAuthData(GooString *ownerPassword, + GooString *userPassword); + virtual void *getAuthData(); + virtual void freeAuthData(void *authData); + virtual GBool authorize(void *authData); + virtual int getPermissionFlags() { return permFlags; } + virtual GBool getOwnerPasswordOk() { return gFalse; } + virtual Guchar *getFileKey() { return fileKey; } + virtual int getFileKeyLength() { return fileKeyLength; } + virtual int getEncVersion() { return encVersion; } + +private: + + Object encryptDict; + XpdfSecurityHandler *xsh; + void *docData; + int permFlags; + Guchar fileKey[16]; + int fileKeyLength; + int encVersion; + GBool ok; +}; +#endif // ENABLE_PLUGINS + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Sound.cc b/rosapps/smartpdf/poppler/poppler/Sound.cc new file mode 100644 index 00000000000..31defec8111 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Sound.cc @@ -0,0 +1,140 @@ +/* Sound.cc - an object that holds the sound structure + * Copyright (C) 2006-2007, Pino Toscano + * + * This 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, 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 "GooString.h" +#include "Object.h" +#include "Sound.h" +#include "Stream.h" +#include "Link.h" + +Sound *Sound::parseSound(Object *obj) +{ + // let's try to see if this Object is a Sound, according to the PDF specs + // (section 9.2) + Stream *str = NULL; + // the Object must be a Stream + if (obj->isStream()) { + str = obj->getStream(); + } else { + return NULL; + } + // the Stream must have a Dict + Dict *dict = str->getDict(); + if (dict == NULL) + return NULL; + Object tmp; + // the Dict must have the 'R' key of type num + dict->lookup("R", &tmp); + if (tmp.isNum()) { + return new Sound(obj); + } else { + return NULL; + } +} + +Sound::Sound(Object *obj, bool readAttrs) +{ + streamObj = new Object(); + streamObj->initNull(); + obj->copy(streamObj); + + fileName = NULL; + samplingRate = 0.0; + channels = 1; + bitsPerSample = 8; + encoding = soundRaw; + + if (readAttrs) + { + Object tmp; + Dict *dict = streamObj->getStream()->getDict(); + dict->lookup("F", &tmp); + if (!tmp.isNull()) { + // valid 'F' key -> external file + kind = soundExternal; + fileName = LinkAction::getFileSpecName(&tmp); + } else { + // no file specification, then the sound data have to be + // extracted from the stream + kind = soundEmbedded; + } + tmp.free(); + // sampling rate + dict->lookup("R", &tmp); + if (tmp.isNum()) { + samplingRate = tmp.getNum(); + } + tmp.free(); + // sound channels + dict->lookup("C", &tmp); + if (tmp.isInt()) { + channels = tmp.getInt(); + } + tmp.free(); + // bits per sample + dict->lookup("B", &tmp); + if (tmp.isInt()) { + bitsPerSample = tmp.getInt(); + } + tmp.free(); + // encoding format + dict->lookup("E", &tmp); + if (tmp.isName()) + { + const char *enc = tmp.getNameC(); + if (strcmp("Raw", enc) == 0) { + encoding = soundRaw; + } else if (strcmp("Signed", enc) == 0) { + encoding = soundSigned; + } else if (strcmp("muLaw", enc) == 0) { + encoding = soundMuLaw; + } else if (strcmp("ALaw", enc) == 0) { + encoding = soundALaw; + } + } + tmp.free(); + } +} + +Sound::~Sound() +{ + delete fileName; + streamObj->free(); + delete streamObj; +} + +Stream *Sound::getStream() +{ + return streamObj->getStream(); +} + +Sound *Sound::copy() +{ + Sound *newsound = new Sound(streamObj, false); + + newsound->kind = kind; + if (fileName) { + newsound->fileName = fileName->copy(); + } + newsound->samplingRate = samplingRate; + newsound->channels = channels; + newsound->bitsPerSample = bitsPerSample; + newsound->encoding = encoding; + + return newsound; +} diff --git a/rosapps/smartpdf/poppler/poppler/Sound.h b/rosapps/smartpdf/poppler/poppler/Sound.h new file mode 100644 index 00000000000..88c96f12f6d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Sound.h @@ -0,0 +1,74 @@ +/* Sound.h - an object that holds the sound structure + * Copyright (C) 2006-2007, Pino Toscano + * + * This 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef Sound_H +#define Sound_H + +class GooString; +class Object; +class Stream; + +//------------------------------------------------------------------------ + +enum SoundKind { + soundEmbedded, // embedded sound + soundExternal // external sound +}; + +enum SoundEncoding { + soundRaw, // raw encoding + soundSigned, // twos-complement values + soundMuLaw, // mu-law-encoded samples + soundALaw // A-law-encoded samples +}; + +class Sound +{ +public: + // Try to parse the Object s + static Sound *parseSound(Object *s); + + // Destructor + ~Sound(); + + Object *getObject() { return streamObj; } + Stream *getStream(); + + SoundKind getSoundKind() { return kind; } + GooString *getFileName() { return fileName; } + double getSamplingRate() { return samplingRate; } + int getChannels() { return channels; } + int getBitsPerSample() { return bitsPerSample; } + SoundEncoding getEncoding() { return encoding; } + + Sound *copy(); + +private: + // Create a sound. The Object obj is ensured to be a Stream with a Dict + Sound(Object *obj, bool readAttrs = true); + + Object *streamObj; + SoundKind kind; + GooString *fileName; + double samplingRate; + int channels; + int bitsPerSample; + SoundEncoding encoding; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/SplashOutputDev.cc b/rosapps/smartpdf/poppler/poppler/SplashOutputDev.cc new file mode 100644 index 00000000000..cac21785a01 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/SplashOutputDev.cc @@ -0,0 +1,2511 @@ +//======================================================================== +// +// SplashOutputDev.cc +// +// Copyright 2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gfile.h" +#include "GlobalParams.h" +#include "Error.h" +#include "Object.h" +#include "GfxFont.h" +#include "Link.h" +#include "CharCodeToUnicode.h" +#include "FontEncodingTables.h" +#include "fofi/FoFiTrueType.h" +#include "splash/SplashBitmap.h" +#include "splash/SplashGlyphBitmap.h" +#include "splash/SplashPattern.h" +#include "splash/SplashScreen.h" +#include "splash/SplashPath.h" +#include "splash/SplashState.h" +#include "splash/SplashErrorCodes.h" +#include "splash/SplashFontEngine.h" +#include "splash/SplashFont.h" +#include "splash/SplashFontFile.h" +#include "splash/SplashFontFileID.h" +#include "splash/Splash.h" +#include "SplashOutputDev.h" + +//------------------------------------------------------------------------ +// Blend functions +//------------------------------------------------------------------------ + +static void splashOutBlendMultiply(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + // note: floor(x / 255) = x >> 8 (for 16-bit x) + blend[i] = (dest[i] * src[i]) >> 8; + } +} + +static void splashOutBlendScreen(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + // note: floor(x / 255) = x >> 8 (for 16-bit x) + blend[i] = dest[i] + src[i] - ((dest[i] * src[i]) >> 8); + } +} + +static void splashOutBlendOverlay(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + //~ not sure if this is right + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + // note: floor(x / 255) = x >> 8 (for 16-bit x) + blend[i] = dest[i] < 0x80 ? ((dest[i] * src[i]) >> 8) + : dest[i] + src[i] - ((dest[i] * src[i]) >> 8); + } +} + +static void splashOutBlendDarken(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + blend[i] = dest[i] < src[i] ? dest[i] : src[i]; + } +} + +static void splashOutBlendLighten(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + blend[i] = dest[i] > src[i] ? dest[i] : src[i]; + } +} + +static void splashOutBlendColorDodge(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, + SplashColorMode cm) { + int i, x; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + x = dest[i] + src[i]; + blend[i] = x <= 255 ? x : 255; + } +} + +static void splashOutBlendColorBurn(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i, x; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + x = dest[i] - (255 - src[i]); + blend[i] = x >= 0 ? x : 0; + } +} + +static void splashOutBlendHardLight(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + //~ not sure if this is right + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + // note: floor(x / 255) = x >> 8 (for 16-bit x) + blend[i] = src[i] < 0x80 + ? ((dest[i] * (src[i] * 2)) >> 8) + : 0xff - (((0xff - dest[i]) * (0x1ff - src[i] * 2)) >> 8); + } +} + +static void splashOutBlendSoftLight(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i, x; + + //~ not sure if this is right + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + if (src[i] < 0x80) { + x = dest[i] - (0x80 - src[i]); + blend[i] = x >= 0 ? x : 0; + } else { + x = dest[i] + (src[i] - 0x80); + blend[i] = x <= 255 ? x : 255; + } + } +} + +static void splashOutBlendDifference(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, + SplashColorMode cm) { + int i; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + blend[i] = dest[i] < src[i] ? src[i] - dest[i] : dest[i] - src[i]; + } +} + +static void splashOutBlendExclusion(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + //~ not sure what this is supposed to do + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + blend[i] = dest[i] < src[i] ? src[i] - dest[i] : dest[i] - src[i]; + } +} + +static void cvtRGBToHSV(Guchar r, Guchar g, Guchar b, int *h, int *s, int *v) { + int cmax, cmid, cmin, x; + + if (r >= g) { + if (g >= b) { x = 0; cmax = r; cmid = g; cmin = b; } + else if (b >= r) { x = 4; cmax = b; cmid = r; cmin = g; } + else { x = 5; cmax = r; cmid = b; cmin = g; } + } else { + if (r >= b) { x = 1; cmax = g; cmid = r; cmin = b; } + else if (g >= b) { x = 2; cmax = g; cmid = b; cmin = r; } + else { x = 3; cmax = b; cmid = g; cmin = r; } + } + if (cmax == cmin) { + *h = *s = 0; + } else { + *h = x * 60; + if (x & 1) { + *h += ((cmax - cmid) * 60) / (cmax - cmin); + } else { + *h += ((cmid - cmin) * 60) / (cmax - cmin); + } + *s = (255 * (cmax - cmin)) / cmax; + } + *v = cmax; +} + +static void cvtHSVToRGB(int h, int s, int v, Guchar *r, Guchar *g, Guchar *b) { + int x, f, cmax, cmid, cmin; + + if (s == 0) { + *r = *g = *b = v; + } else { + x = h / 60; + f = h % 60; + cmax = v; + if (x & 1) { + cmid = (v * 255 - ((s * f) / 60)) >> 8; + } else { + cmid = (v * (255 - ((s * (60 - f)) / 60))) >> 8; + } + // note: floor(x / 255) = x >> 8 (for 16-bit x) + cmin = (v * (255 - s)) >> 8; + switch (x) { + case 0: *r = cmax; *g = cmid; *b = cmin; break; + case 1: *g = cmax; *r = cmid; *b = cmin; break; + case 2: *g = cmax; *b = cmid; *r = cmin; break; + case 3: *b = cmax; *g = cmid; *r = cmin; break; + case 4: *b = cmax; *r = cmid; *g = cmin; break; + case 5: *r = cmax; *b = cmid; *g = cmin; break; + } + } +} + +static void splashOutBlendHue(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int hs, ss, vs, hd, sd, vd; +#if SPLASH_CMYK + Guchar r, g, b; +#endif + + switch (cm) { + case splashModeMono1: + case splashModeMono8: + blend[0] = dest[0]; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs); + cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd); + cvtHSVToRGB(hs, sd, vd, &blend[0], &blend[1], &blend[2]); + break; + case splashModeBGR8: + cvtRGBToHSV(src[2], src[1], src[0], &hs, &ss, &vs); + cvtRGBToHSV(dest[2], dest[1], dest[0], &hd, &sd, &vd); + cvtHSVToRGB(hs, sd, vd, &blend[2], &blend[1], &blend[0]); + break; +#if SPLASH_CMYK + case splashModeCMYK8: + //~ (0xff - ...) should be clipped + cvtRGBToHSV(0xff - (src[0] + src[3]), + 0xff - (src[1] + src[3]), + 0xff - (src[2] + src[3]), &hs, &ss, &vs); + cvtRGBToHSV(0xff - (dest[0] + dest[3]), + 0xff - (dest[1] + dest[3]), + 0xff - (dest[2] + dest[3]), &hd, &sd, &vd); + cvtHSVToRGB(hs, sd, vd, &r, &g, &b); + //~ should do black generation + blend[0] = 0xff - r; + blend[0] = 0xff - g; + blend[0] = 0xff - b; + blend[3] = 0; + break; +#endif + default: + //~ unimplemented + break; + } +} + +static void splashOutBlendSaturation(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, + SplashColorMode cm) { + int hs, ss, vs, hd, sd, vd; +#if SPLASH_CMYK + Guchar r, g, b; +#endif + + switch (cm) { + case splashModeMono1: + case splashModeMono8: + blend[0] = dest[0]; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs); + cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd); + cvtHSVToRGB(hd, ss, vd, &blend[0], &blend[1], &blend[2]); + break; + case splashModeBGR8: + cvtRGBToHSV(src[2], src[1], src[0], &hs, &ss, &vs); + cvtRGBToHSV(dest[2], dest[1], dest[0], &hd, &sd, &vd); + cvtHSVToRGB(hd, ss, vd, &blend[2], &blend[1], &blend[0]); + break; +#if SPLASH_CMYK + case splashModeCMYK8: + //~ (0xff - ...) should be clipped + cvtRGBToHSV(0xff - (src[0] + src[3]), + 0xff - (src[1] + src[3]), + 0xff - (src[2] + src[3]), &hs, &ss, &vs); + cvtRGBToHSV(0xff - (dest[0] + dest[3]), + 0xff - (dest[1] + dest[3]), + 0xff - (dest[2] + dest[3]), &hd, &sd, &vd); + cvtHSVToRGB(hd, ss, vd, &r, &g, &b); + //~ should do black generation + blend[0] = 0xff - r; + blend[0] = 0xff - g; + blend[0] = 0xff - b; + blend[3] = 0; + break; +#endif + default: + //~ unimplemented + break; + } +} + +static void splashOutBlendColor(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int hs, ss, vs, hd, sd, vd; +#if SPLASH_CMYK + Guchar r, g, b; +#endif + + switch (cm) { + case splashModeMono1: + case splashModeMono8: + blend[0] = dest[0]; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs); + cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd); + cvtHSVToRGB(hs, ss, vd, &blend[0], &blend[1], &blend[2]); + break; + case splashModeBGR8: + cvtRGBToHSV(src[2], src[1], src[0], &hs, &ss, &vs); + cvtRGBToHSV(dest[2], dest[1], dest[0], &hd, &sd, &vd); + cvtHSVToRGB(hs, ss, vd, &blend[2], &blend[1], &blend[0]); + break; +#if SPLASH_CMYK + case splashModeCMYK8: + //~ (0xff - ...) should be clipped + cvtRGBToHSV(0xff - (src[0] + src[3]), + 0xff - (src[1] + src[3]), + 0xff - (src[2] + src[3]), &hs, &ss, &vs); + cvtRGBToHSV(0xff - (dest[0] + dest[3]), + 0xff - (dest[1] + dest[3]), + 0xff - (dest[2] + dest[3]), &hd, &sd, &vd); + cvtHSVToRGB(hs, ss, vd, &r, &g, &b); + //~ should do black generation + blend[0] = 0xff - r; + blend[0] = 0xff - g; + blend[0] = 0xff - b; + blend[3] = 0; + break; +#endif + default: + //~ unimplemented + break; + } +} + +static void splashOutBlendLuminosity(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, + SplashColorMode cm) { + int hs, ss, vs, hd, sd, vd; +#if SPLASH_CMYK + Guchar r, g, b; +#endif + + switch (cm) { + case splashModeMono1: + case splashModeMono8: + blend[0] = dest[0]; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs); + cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd); + cvtHSVToRGB(hd, sd, vs, &blend[0], &blend[1], &blend[2]); + break; + case splashModeBGR8: + cvtRGBToHSV(src[2], src[1], src[0], &hs, &ss, &vs); + cvtRGBToHSV(dest[2], dest[1], dest[0], &hd, &sd, &vd); + cvtHSVToRGB(hd, sd, vs, &blend[2], &blend[1], &blend[0]); + break; +#if SPLASH_CMYK + case splashModeCMYK8: + //~ (0xff - ...) should be clipped + cvtRGBToHSV(0xff - (src[0] + src[3]), + 0xff - (src[1] + src[3]), + 0xff - (src[2] + src[3]), &hs, &ss, &vs); + cvtRGBToHSV(0xff - (dest[0] + dest[3]), + 0xff - (dest[1] + dest[3]), + 0xff - (dest[2] + dest[3]), &hd, &sd, &vd); + cvtHSVToRGB(hd, sd, vs, &r, &g, &b); + //~ should do black generation + blend[0] = 0xff - r; + blend[0] = 0xff - g; + blend[0] = 0xff - b; + blend[3] = 0; + break; +#endif + default: + //~ unimplemented + break; + } +} + +// NB: This must match the GfxBlendMode enum defined in GfxState.h. +SplashBlendFunc splashOutBlendFuncs[] = { + NULL, + &splashOutBlendMultiply, + &splashOutBlendScreen, + &splashOutBlendOverlay, + &splashOutBlendDarken, + &splashOutBlendLighten, + &splashOutBlendColorDodge, + &splashOutBlendColorBurn, + &splashOutBlendHardLight, + &splashOutBlendSoftLight, + &splashOutBlendDifference, + &splashOutBlendExclusion, + &splashOutBlendHue, + &splashOutBlendSaturation, + &splashOutBlendColor, + &splashOutBlendLuminosity +}; + +//------------------------------------------------------------------------ +// SplashOutFontFileID +//------------------------------------------------------------------------ + +class SplashOutFontFileID: public SplashFontFileID { +public: + + SplashOutFontFileID(Ref *rA) { r = *rA; } + + ~SplashOutFontFileID() {} + + GBool matches(SplashFontFileID *id) { + return ((SplashOutFontFileID *)id)->r.num == r.num && + ((SplashOutFontFileID *)id)->r.gen == r.gen; + } + +private: + + Ref r; +}; + +//------------------------------------------------------------------------ +// T3FontCache +//------------------------------------------------------------------------ + +struct T3FontCacheTag { + Gushort code; + Gushort mru; // valid bit (0x8000) and MRU index +}; + +class T3FontCache { +public: + + T3FontCache(Ref *fontID, double m11A, double m12A, + double m21A, double m22A, + int glyphXA, int glyphYA, int glyphWA, int glyphHA, + GBool aa); + ~T3FontCache(); + GBool matches(Ref *idA, double m11A, double m12A, + double m21A, double m22A) + { return fontID.num == idA->num && fontID.gen == idA->gen && + m11 == m11A && m12 == m12A && m21 == m21A && m22 == m22A; } + + Ref fontID; // PDF font ID + double m11, m12, m21, m22; // transform matrix + int glyphX, glyphY; // pixel offset of glyph bitmaps + int glyphW, glyphH; // size of glyph bitmaps, in pixels + int glyphSize; // size of glyph bitmaps, in bytes + int cacheSets; // number of sets in cache + int cacheAssoc; // cache associativity (glyphs per set) + Guchar *cacheData; // glyph pixmap cache + T3FontCacheTag *cacheTags; // cache tags, i.e., char codes +}; + +T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A, + double m21A, double m22A, + int glyphXA, int glyphYA, int glyphWA, int glyphHA, + GBool aa) { + int i; + + fontID = *fontIDA; + m11 = m11A; + m12 = m12A; + m21 = m21A; + m22 = m22A; + glyphX = glyphXA; + glyphY = glyphYA; + glyphW = glyphWA; + glyphH = glyphHA; + if (aa) { + glyphSize = glyphW * glyphH; + } else { + glyphSize = ((glyphW + 7) >> 3) * glyphH; + } + cacheAssoc = 8; + if (glyphSize <= 256) { + cacheSets = 8; + } else if (glyphSize <= 512) { + cacheSets = 4; + } else if (glyphSize <= 1024) { + cacheSets = 2; + } else { + cacheSets = 1; + } + cacheData = (Guchar *)gmallocn(cacheSets * cacheAssoc, glyphSize); + cacheTags = (T3FontCacheTag *)gmallocn(cacheSets * cacheAssoc, + sizeof(T3FontCacheTag)); + for (i = 0; i < cacheSets * cacheAssoc; ++i) { + cacheTags[i].mru = i & (cacheAssoc - 1); + } +} + +T3FontCache::~T3FontCache() { + gfree(cacheData); + gfree(cacheTags); +} + +struct T3GlyphStack { + Gushort code; // character code + double x, y; // position to draw the glyph + + //----- cache info + T3FontCache *cache; // font cache for the current font + T3FontCacheTag *cacheTag; // pointer to cache tag for the glyph + Guchar *cacheData; // pointer to cache data for the glyph + + //----- saved state + SplashBitmap *origBitmap; + Splash *origSplash; + double origCTM4, origCTM5; + + T3GlyphStack *next; // next object on stack +}; + +//------------------------------------------------------------------------ +// SplashOutputDev +//------------------------------------------------------------------------ + +SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA, + int bitmapRowPadA, + GBool reverseVideoA, + SplashColorPtr paperColorA, + GBool bitmapTopDownA, + GBool allowAntialiasA) { + colorMode = colorModeA; + bitmapRowPad = bitmapRowPadA; + bitmapTopDown = bitmapTopDownA; + allowAntialias = allowAntialiasA; + reverseVideo = reverseVideoA; + splashColorCopy(paperColor, paperColorA); + + xref = NULL; + + bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode, bitmapTopDown); + splash = new Splash(bitmap); + splash->clear(paperColor); + + fontEngine = NULL; + + nT3Fonts = 0; + t3GlyphStack = NULL; + + font = NULL; + needFontUpdate = gFalse; + textClipPath = NULL; +} + +SplashOutputDev::~SplashOutputDev() { + int i; + + for (i = 0; i < nT3Fonts; ++i) { + delete t3FontCache[i]; + } + if (fontEngine) { + delete fontEngine; + } + if (splash) { + delete splash; + } + if (bitmap) { + delete bitmap; + } +} + +void SplashOutputDev::startDoc(XRef *xrefA) { + int i; + + xref = xrefA; + if (fontEngine) { + delete fontEngine; + } + fontEngine = new SplashFontEngine( +#if HAVE_T1LIB_H + globalParams->getEnableT1lib(), +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + globalParams->getEnableFreeType(), +#endif + allowAntialias && + globalParams->getAntialias() && + colorMode != splashModeMono1); + for (i = 0; i < nT3Fonts; ++i) { + delete t3FontCache[i]; + } + nT3Fonts = 0; +} + +void SplashOutputDev::startPage(int pageNum, GfxState *state) { + int w, h; + SplashColor color; + + w = state ? (int)(state->getPageWidth() + 0.5) : 1; + h = state ? (int)(state->getPageHeight() + 0.5) : 1; + if (splash) { + delete splash; + splash = NULL; + } + if (!bitmap || w != bitmap->getWidth() || h != bitmap->getHeight()) { + if (bitmap) { + delete bitmap; + } + bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, bitmapTopDown); + } + splash = new Splash(bitmap); + switch (colorMode) { + case splashModeMono1: + case splashModeMono8: + color[0] = 0; + break; + case splashModeRGB8: + case splashModeBGR8: + case splashModeRGB8Qt: + color[0] = color[1] = color[2] = 0; + break; + case splashModeAMono8: + color[0] = 0xff; + color[1] = 0; + break; + case splashModeARGB8: + color[0] = 255; + color[1] = color[2] = color[3] = 0; + break; + case splashModeBGRA8: + color[0] = color[1] = color[2] = 0; + color[3] = 255; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + color[0] = color[1] = color[2] = color[3] = 0; + break; + case splashModeACMYK8: + color[0] = 255; + color[1] = color[2] = color[3] = color[4] = 0; + break; +#endif + } + splash->setStrokePattern(new SplashSolidColor(color)); + splash->setFillPattern(new SplashSolidColor(color)); + splash->setLineCap(splashLineCapButt); + splash->setLineJoin(splashLineJoinMiter); + splash->setLineDash(NULL, 0, 0); + splash->setMiterLimit(10); + splash->setFlatness(1); + splash->clear(paperColor); +} + +void SplashOutputDev::endPage() { +} + +void SplashOutputDev::drawLink(Link *link, Catalog *catalog) { + double x1, y1, x2, y2; + LinkBorderStyle *borderStyle; + double r, g, b; + GfxRGB rgb; + GfxGray gray; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + double *dash; + int dashLength; + SplashCoord dashList[20]; + SplashPath *path; + int x, y, i; + + link->getRect(&x1, &y1, &x2, &y2); + borderStyle = link->getBorderStyle(); + if (borderStyle->getWidth() > 0) { + borderStyle->getColor(&r, &g, &b); + rgb.r = dblToCol(r); + rgb.g = dblToCol(g); + rgb.b = dblToCol(b); + gray = dblToCol(0.299 * r + 0.587 * g + 0.114 * b); + if (gray > gfxColorComp1) { + gray = gfxColorComp1; + } +#if SPLASH_CMYK + cmyk.c = gfxColorComp1 - rgb.r; + cmyk.m = gfxColorComp1 - rgb.g; + cmyk.y = gfxColorComp1 - rgb.b; + cmyk.k = 0; + splash->setStrokePattern(getColor(gray, &rgb, &cmyk)); +#else + splash->setStrokePattern(getColor(gray, &rgb)); +#endif + splash->setLineWidth((SplashCoord)borderStyle->getWidth()); + borderStyle->getDash(&dash, &dashLength); + if (borderStyle->getType() == linkBorderDashed && dashLength > 0) { + if (dashLength > 20) { + dashLength = 20; + } + for (i = 0; i < dashLength; ++i) { + dashList[i] = (SplashCoord)dash[i]; + } + splash->setLineDash(dashList, dashLength, 0); + } + path = new SplashPath(); + if (borderStyle->getType() == linkBorderUnderlined) { + cvtUserToDev(x1, y1, &x, &y); + path->moveTo((SplashCoord)x, (SplashCoord)y); + cvtUserToDev(x2, y1, &x, &y); + path->lineTo((SplashCoord)x, (SplashCoord)y); + } else { + cvtUserToDev(x1, y1, &x, &y); + path->moveTo((SplashCoord)x, (SplashCoord)y); + cvtUserToDev(x2, y1, &x, &y); + path->lineTo((SplashCoord)x, (SplashCoord)y); + cvtUserToDev(x2, y2, &x, &y); + path->lineTo((SplashCoord)x, (SplashCoord)y); + cvtUserToDev(x1, y2, &x, &y); + path->lineTo((SplashCoord)x, (SplashCoord)y); + path->close(); + } + splash->stroke(path); + delete path; + } +} + +void SplashOutputDev::saveState(GfxState *state) { + splash->saveState(); +} + +void SplashOutputDev::restoreState(GfxState *state) { + splash->restoreState(); + needFontUpdate = gTrue; +} + +void SplashOutputDev::updateAll(GfxState *state) { + updateLineDash(state); + updateLineJoin(state); + updateLineCap(state); + updateLineWidth(state); + updateFlatness(state); + updateMiterLimit(state); + updateFillColor(state); + updateStrokeColor(state); + needFontUpdate = gTrue; +} + +void SplashOutputDev::updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, + double m31, double m32) { + updateLineDash(state); + updateLineJoin(state); + updateLineCap(state); + updateLineWidth(state); +} + +void SplashOutputDev::updateLineDash(GfxState *state) { + double *dashPattern; + int dashLength; + double dashStart; + SplashCoord dash[20]; + SplashCoord phase; + int i; + + state->getLineDash(&dashPattern, &dashLength, &dashStart); + if (dashLength > 20) { + dashLength = 20; + } + for (i = 0; i < dashLength; ++i) { + dash[i] = (SplashCoord)state->transformWidth(dashPattern[i]); + if (dash[i] < 1) { + dash[i] = 1; + } + } + phase = (SplashCoord)state->transformWidth(dashStart); + splash->setLineDash(dash, dashLength, phase); +} + +void SplashOutputDev::updateFlatness(GfxState *state) { + splash->setFlatness(state->getFlatness()); +} + +void SplashOutputDev::updateLineJoin(GfxState *state) { + splash->setLineJoin(state->getLineJoin()); +} + +void SplashOutputDev::updateLineCap(GfxState *state) { + splash->setLineCap(state->getLineCap()); +} + +void SplashOutputDev::updateMiterLimit(GfxState *state) { + splash->setMiterLimit(state->getMiterLimit()); +} + +void SplashOutputDev::updateLineWidth(GfxState *state) { + splash->setLineWidth(state->getTransformedLineWidth()); +} + +void SplashOutputDev::updateFillColor(GfxState *state) { + GfxGray gray; + GfxRGB rgb; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + + state->getFillGray(&gray); + state->getFillRGB(&rgb); +#if SPLASH_CMYK + state->getFillCMYK(&cmyk); + splash->setFillPattern(getColor(gray, &rgb, &cmyk)); +#else + splash->setFillPattern(getColor(gray, &rgb)); +#endif +} + +void SplashOutputDev::updateStrokeColor(GfxState *state) { + GfxGray gray; + GfxRGB rgb; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + + state->getStrokeGray(&gray); + state->getStrokeRGB(&rgb); +#if SPLASH_CMYK + state->getStrokeCMYK(&cmyk); + splash->setStrokePattern(getColor(gray, &rgb, &cmyk)); +#else + splash->setStrokePattern(getColor(gray, &rgb)); +#endif +} + +#if SPLASH_CMYK +SplashPattern *SplashOutputDev::getColor(GfxGray gray, GfxRGB *rgb, + GfxCMYK *cmyk) { +#else +SplashPattern *SplashOutputDev::getColor(GfxGray gray, GfxRGB *rgb) { +#endif + SplashPattern *pattern; + SplashColor color0, color1; + GfxColorComp r, g, b; + + if (reverseVideo) { + gray = gfxColorComp1 - gray; + r = gfxColorComp1 - rgb->r; + g = gfxColorComp1 - rgb->g; + b = gfxColorComp1 - rgb->b; + } else { + r = rgb->r; + g = rgb->g; + b = rgb->b; + } + + pattern = NULL; // make gcc happy + switch (colorMode) { + case splashModeMono1: + color0[0] = 0; + color1[0] = 1; + pattern = new SplashHalftone(color0, color1, + splash->getScreen()->copy(), + (SplashCoord)colToDbl(gray)); + break; + case splashModeMono8: + color1[0] = colToByte(gray); + pattern = new SplashSolidColor(color1); + break; + case splashModeAMono8: + color1[0] = 255; + color1[1] = colToByte(gray); + pattern = new SplashSolidColor(color1); + break; + case splashModeRGB8: + case splashModeRGB8Qt: + color1[0] = colToByte(r); + color1[1] = colToByte(g); + color1[2] = colToByte(b); + pattern = new SplashSolidColor(color1); + break; + case splashModeBGR8: + color1[2] = colToByte(r); + color1[1] = colToByte(g); + color1[0] = colToByte(b); + pattern = new SplashSolidColor(color1); + break; + case splashModeARGB8: + color1[0] = 255; + color1[1] = colToByte(r); + color1[2] = colToByte(g); + color1[3] = colToByte(b); + pattern = new SplashSolidColor(color1); + break; + case splashModeBGRA8: + color1[3] = 255; + color1[2] = colToByte(r); + color1[1] = colToByte(g); + color1[0] = colToByte(b); + pattern = new SplashSolidColor(color1); + break; +#if SPLASH_CMYK + case splashModeCMYK8: + color1[0] = colToByte(cmyk->c); + color1[1] = colToByte(cmyk->m); + color1[2] = colToByte(cmyk->y); + color1[3] = colToByte(cmyk->k); + pattern = new SplashSolidColor(color1); + break; + case splashModeACMYK8: + color1[0] = 255; + color1[1] = colToByte(cmyk->c); + color1[2] = colToByte(cmyk->m); + color1[3] = colToByte(cmyk->y); + color1[4] = colToByte(cmyk->k); + pattern = new SplashSolidColor(color1); + break; +#endif + } + + return pattern; +} + +void SplashOutputDev::updateBlendMode(GfxState *state) { + splash->setBlendFunc(splashOutBlendFuncs[state->getBlendMode()]); +} + +void SplashOutputDev::updateFillOpacity(GfxState *state) { + splash->setFillAlpha((SplashCoord)state->getFillOpacity()); +} + +void SplashOutputDev::updateStrokeOpacity(GfxState *state) { + splash->setStrokeAlpha((SplashCoord)state->getStrokeOpacity()); +} + +void SplashOutputDev::updateFont(GfxState *state) { + GfxFont *gfxFont; + GfxFontType fontType; + SplashOutFontFileID *id; + SplashFontFile *fontFile; + SplashFontSrc *fontsrc = NULL; + FoFiTrueType *ff; + Ref embRef; + Object refObj, strObj; + GooString *fileName; + char *tmpBuf; + int tmpBufLen; + Gushort *codeToGID; + DisplayFontParam *dfp; + CharCodeToUnicode *ctu; + double m11, m12, m21, m22; + SplashCoord mat[4]; + Unicode uBuf[8]; + int substIdx, n, code, cmap; + int faceIndex = 0; + + needFontUpdate = gFalse; + font = NULL; + fileName = NULL; + tmpBuf = NULL; + tmpBufLen = 0; + substIdx = -1; + dfp = NULL; + + if (!(gfxFont = state->getFont())) { + goto err1; + } + fontType = gfxFont->getType(); + if (fontType == fontType3) { + goto err1; + } + + // check the font file cache + id = new SplashOutFontFileID(gfxFont->getID()); + if ((fontFile = fontEngine->getFontFile(id))) { + delete id; + + } else { + + // if there is an embedded font, write it to disk + if (gfxFont->getEmbeddedFontID(&embRef)) { + tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen); + if (! tmpBuf) + goto err2; + // if there is an external font file, use it + } else if (!(fileName = gfxFont->getExtFontFile())) { + + // look for a display font mapping or a substitute font + dfp = NULL; + if (gfxFont->getName()) { + dfp = globalParams->getDisplayFont(gfxFont); + } + if (!dfp) { + error(-1, "Couldn't find a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + switch (dfp->kind) { + case displayFontT1: + fileName = dfp->t1.fileName; + fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1; + break; + case displayFontTT: + fileName = dfp->tt.fileName; + fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType; + faceIndex = dfp->tt.faceIndex; + break; + } + } + + fontsrc = new SplashFontSrc; + if (fileName) + fontsrc->setFile(fileName, gFalse); + else + fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue); + + // load the font file + switch (fontType) { + case fontType1: + fontFile = fontEngine->loadType1Font(id, fontsrc, + ((Gfx8BitFont *)gfxFont)->getEncoding()); + if (! fontFile) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontType1C: + fontFile = fontEngine->loadType1CFont(id, fontsrc, + ((Gfx8BitFont *)gfxFont)->getEncoding()); + if (! fontFile) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontTrueType: + if (fileName) + ff = FoFiTrueType::load(fileName->getCString()); + else + ff = new FoFiTrueType(tmpBuf, tmpBufLen, gFalse); + if (ff) { + codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff); + n = 256; + delete ff; + } else { + codeToGID = NULL; + n = 0; + } + if (!(fontFile = fontEngine->loadTrueTypeFont( + id, + fontsrc, + codeToGID, n))) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontCIDType0: + case fontCIDType0C: + fontFile = fontEngine->loadCIDFont(id, fontsrc); + if (! fontFile) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + case fontCIDType2: + codeToGID = NULL; + n = 0; + if (dfp) { + // create a CID-to-GID mapping, via Unicode + if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) { + if (fileName) + ff = FoFiTrueType::load(fileName->getCString()); + else + ff = new FoFiTrueType(tmpBuf, tmpBufLen, gFalse); + if (ff) { + // look for a Unicode cmap + for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) { + if ((ff->getCmapPlatform(cmap) == 3 && + ff->getCmapEncoding(cmap) == 1) || + ff->getCmapPlatform(cmap) == 0) { + break; + } + } + if (cmap < ff->getNumCmaps()) { + // map CID -> Unicode -> GID + n = ctu->getLength(); + codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); + for (code = 0; code < n; ++code) { + if (ctu->mapToUnicode(code, uBuf, 8) > 0) { + codeToGID[code] = ff->mapCodeToGID(cmap, uBuf[0]); + } else { + codeToGID[code] = 0; + } + } + } + delete ff; + } + ctu->decRefCnt(); + } else { + error(-1, "Couldn't find a mapping to Unicode for font '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + } + } else { + if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { + n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); + if (n) { + codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); + memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), + n * sizeof(Gushort)); + } else { + if (fileName) + ff = FoFiTrueType::load(fileName->getCString()); + else + ff = new FoFiTrueType(tmpBuf, tmpBufLen, gFalse); + if (! ff) + goto err2; + codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n); + delete ff; + } + } + } + if (!(fontFile = fontEngine->loadTrueTypeFont( + id, + fontsrc, + codeToGID, + n, + faceIndex))) { + error(-1, "Couldn't create a font for '%s'", + gfxFont->getName() ? gfxFont->getName()->getCString() + : "(unnamed)"); + goto err2; + } + break; + default: + // this shouldn't happen + goto err2; + } + } + + // get the font matrix + state->getFontTransMat(&m11, &m12, &m21, &m22); + m11 *= state->getHorizScaling(); + m12 *= state->getHorizScaling(); + + // create the scaled font + mat[0] = m11; mat[1] = -m12; + mat[2] = m21; mat[3] = -m22; + if (fabs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.01) { + // avoid a singular (or close-to-singular) matrix + mat[0] = 0.01; mat[1] = 0; + mat[2] = 0; mat[3] = 0.01; + } + font = fontEngine->getFont(fontFile, mat); + + if (fontsrc && !fontsrc->isFile) + fontsrc->unref(); + return; + + err2: + delete id; + err1: + if (fontsrc && !fontsrc->isFile) + fontsrc->unref(); + return; +} + +void SplashOutputDev::stroke(GfxState *state) { + SplashPath *path; + + path = convertPath(state, state->getPath()); + splash->stroke(path); + delete path; +} + +void SplashOutputDev::fill(GfxState *state) { + SplashPath *path; + + path = convertPath(state, state->getPath()); + splash->fill(path, gFalse); + delete path; +} + +void SplashOutputDev::eoFill(GfxState *state) { + SplashPath *path; + + path = convertPath(state, state->getPath()); + splash->fill(path, gTrue); + delete path; +} + +void SplashOutputDev::clip(GfxState *state) { + SplashPath *path; + + path = convertPath(state, state->getPath()); + splash->clipToPath(path, gFalse); + delete path; +} + +void SplashOutputDev::eoClip(GfxState *state) { + SplashPath *path; + + path = convertPath(state, state->getPath()); + splash->clipToPath(path, gTrue); + delete path; +} + +SplashPath *SplashOutputDev::convertPath(GfxState *state, GfxPath *path) { + SplashPath *sPath; + GfxSubpath *subpath; + double x1, y1, x2, y2, x3, y3; + int i, j; + + sPath = new SplashPath(); + for (i = 0; i < path->getNumSubpaths(); ++i) { + subpath = path->getSubpath(i); + if (subpath->getNumPoints() > 0) { + state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1); + sPath->moveTo((SplashCoord)x1, (SplashCoord)y1); + j = 1; + while (j < subpath->getNumPoints()) { + if (subpath->getCurve(j)) { + state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1); + state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2); + state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3); + sPath->curveTo((SplashCoord)x1, (SplashCoord)y1, + (SplashCoord)x2, (SplashCoord)y2, + (SplashCoord)x3, (SplashCoord)y3); + j += 3; + } else { + state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1); + sPath->lineTo((SplashCoord)x1, (SplashCoord)y1); + ++j; + } + } + if (subpath->isClosed()) { + sPath->close(); + } + } + } + return sPath; +} + +void SplashOutputDev::drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, + Unicode *u, int uLen) { + double x1, y1; + SplashPath *path; + int render; + + if (needFontUpdate) { + updateFont(state); + } + if (!font) { + return; + } + + // check for invisible text -- this is used by Acrobat Capture + render = state->getRender(); + if (render == 3) { + return; + } + + x -= originX; + y -= originY; + state->transform(x, y, &x1, &y1); + + // fill + if (!(render & 1)) { + splash->fillChar((SplashCoord)x1, (SplashCoord)y1, code, font); + } + + // stroke + if ((render & 3) == 1 || (render & 3) == 2) { + if ((path = font->getGlyphPath(code))) { + path->offset((SplashCoord)x1, (SplashCoord)y1); + splash->stroke(path); + delete path; + } + } + + // clip + if (render & 4) { + path = font->getGlyphPath(code); + path->offset((SplashCoord)x1, (SplashCoord)y1); + if (textClipPath) { + textClipPath->append(path); + delete path; + } else { + textClipPath = path; + } + } +} + +GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen) { + GfxFont *gfxFont; + Ref *fontID; + double *ctm, *bbox; + T3FontCache *t3Font; + T3GlyphStack *t3gs; + double x1, y1, xMin, yMin, xMax, yMax, xt, yt; + int i, j; + + if (!(gfxFont = state->getFont())) { + return gFalse; + } + fontID = gfxFont->getID(); + ctm = state->getCTM(); + state->transform(0, 0, &xt, &yt); + + // is it the first (MRU) font in the cache? + if (!(nT3Fonts > 0 && + t3FontCache[0]->matches(fontID, ctm[0], ctm[1], ctm[2], ctm[3]))) { + + // is the font elsewhere in the cache? + for (i = 1; i < nT3Fonts; ++i) { + if (t3FontCache[i]->matches(fontID, ctm[0], ctm[1], ctm[2], ctm[3])) { + t3Font = t3FontCache[i]; + for (j = i; j > 0; --j) { + t3FontCache[j] = t3FontCache[j - 1]; + } + t3FontCache[0] = t3Font; + break; + } + } + if (i >= nT3Fonts) { + + // create new entry in the font cache + if (nT3Fonts == splashOutT3FontCacheSize) { + delete t3FontCache[nT3Fonts - 1]; + --nT3Fonts; + } + for (j = nT3Fonts; j > 0; --j) { + t3FontCache[j] = t3FontCache[j - 1]; + } + ++nT3Fonts; + bbox = gfxFont->getFontBBox(); + if (bbox[0] == 0 && bbox[1] == 0 && bbox[2] == 0 && bbox[3] == 0) { + // broken bounding box -- just take a guess + xMin = xt - 5; + xMax = xMin + 30; + yMax = yt + 15; + yMin = yMax - 45; + } else { + state->transform(bbox[0], bbox[1], &x1, &y1); + xMin = xMax = x1; + yMin = yMax = y1; + state->transform(bbox[0], bbox[3], &x1, &y1); + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + state->transform(bbox[2], bbox[1], &x1, &y1); + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + state->transform(bbox[2], bbox[3], &x1, &y1); + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + } + t3FontCache[0] = new T3FontCache(fontID, ctm[0], ctm[1], ctm[2], ctm[3], + (int)floor(xMin - xt), + (int)floor(yMin - yt), + (int)ceil(xMax) - (int)floor(xMin) + 3, + (int)ceil(yMax) - (int)floor(yMin) + 3, + colorMode != splashModeMono1); + } + } + t3Font = t3FontCache[0]; + + // is the glyph in the cache? + i = (code & (t3Font->cacheSets - 1)) * t3Font->cacheAssoc; + for (j = 0; j < t3Font->cacheAssoc; ++j) { + if ((t3Font->cacheTags[i+j].mru & 0x8000) && + t3Font->cacheTags[i+j].code == code) { + drawType3Glyph(t3Font, &t3Font->cacheTags[i+j], + t3Font->cacheData + (i+j) * t3Font->glyphSize, + xt, yt); + return gTrue; + } + } + + // push a new Type 3 glyph record + t3gs = new T3GlyphStack(); + t3gs->next = t3GlyphStack; + t3GlyphStack = t3gs; + t3GlyphStack->code = code; + t3GlyphStack->x = xt; + t3GlyphStack->y = yt; + t3GlyphStack->cache = t3Font; + t3GlyphStack->cacheTag = NULL; + t3GlyphStack->cacheData = NULL; + + return gFalse; +} + +void SplashOutputDev::endType3Char(GfxState *state) { + T3GlyphStack *t3gs; + double *ctm; + + if (t3GlyphStack->cacheTag) { + memcpy(t3GlyphStack->cacheData, bitmap->getDataPtr(), + t3GlyphStack->cache->glyphSize); + delete bitmap; + delete splash; + bitmap = t3GlyphStack->origBitmap; + splash = t3GlyphStack->origSplash; + ctm = state->getCTM(); + state->setCTM(ctm[0], ctm[1], ctm[2], ctm[3], + t3GlyphStack->origCTM4, t3GlyphStack->origCTM5); + drawType3Glyph(t3GlyphStack->cache, + t3GlyphStack->cacheTag, t3GlyphStack->cacheData, + t3GlyphStack->x, t3GlyphStack->y); + } + t3gs = t3GlyphStack; + t3GlyphStack = t3gs->next; + delete t3gs; +} + +void SplashOutputDev::type3D0(GfxState *state, double wx, double wy) { +} + +void SplashOutputDev::type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury) { + double *ctm; + T3FontCache *t3Font; + SplashColor color; + double xt, yt, xMin, xMax, yMin, yMax, x1, y1; + int i, j; + + t3Font = t3GlyphStack->cache; + + // check for a valid bbox + state->transform(0, 0, &xt, &yt); + state->transform(llx, lly, &x1, &y1); + xMin = xMax = x1; + yMin = yMax = y1; + state->transform(llx, ury, &x1, &y1); + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + state->transform(urx, lly, &x1, &y1); + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + state->transform(urx, ury, &x1, &y1); + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + if (xMin - xt < t3Font->glyphX || + yMin - yt < t3Font->glyphY || + xMax - xt > t3Font->glyphX + t3Font->glyphW || + yMax - yt > t3Font->glyphY + t3Font->glyphH) { + error(-1, "Bad bounding box in Type 3 glyph"); + return; + } + + // allocate a cache entry + i = (t3GlyphStack->code & (t3Font->cacheSets - 1)) * t3Font->cacheAssoc; + for (j = 0; j < t3Font->cacheAssoc; ++j) { + if ((t3Font->cacheTags[i+j].mru & 0x7fff) == t3Font->cacheAssoc - 1) { + t3Font->cacheTags[i+j].mru = 0x8000; + t3Font->cacheTags[i+j].code = t3GlyphStack->code; + t3GlyphStack->cacheTag = &t3Font->cacheTags[i+j]; + t3GlyphStack->cacheData = t3Font->cacheData + (i+j) * t3Font->glyphSize; + } else { + ++t3Font->cacheTags[i+j].mru; + } + } + + // save state + t3GlyphStack->origBitmap = bitmap; + t3GlyphStack->origSplash = splash; + ctm = state->getCTM(); + t3GlyphStack->origCTM4 = ctm[4]; + t3GlyphStack->origCTM5 = ctm[5]; + + // create the temporary bitmap + if (colorMode == splashModeMono1) { + bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1, + splashModeMono1); + splash = new Splash(bitmap); + color[0] = 0; + splash->clear(color); + color[0] = 1; + } else { + bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1, + splashModeMono8); + splash = new Splash(bitmap); + color[0] = 0x00; + splash->clear(color); + color[0] = 0xff; + } + splash->setFillPattern(new SplashSolidColor(color)); + splash->setStrokePattern(new SplashSolidColor(color)); + //~ this should copy other state from t3GlyphStack->origSplash? + state->setCTM(ctm[0], ctm[1], ctm[2], ctm[3], + -t3Font->glyphX, -t3Font->glyphY); +} + +void SplashOutputDev::drawType3Glyph(T3FontCache *t3Font, + T3FontCacheTag *tag, Guchar *data, + double x, double y) { + SplashGlyphBitmap glyph; + + glyph.x = -t3Font->glyphX; + glyph.y = -t3Font->glyphY; + glyph.w = t3Font->glyphW; + glyph.h = t3Font->glyphH; + glyph.aa = colorMode != splashModeMono1; + glyph.data = data; + glyph.freeData = gFalse; + splash->fillGlyph((SplashCoord)x, (SplashCoord)y, &glyph); +} + +void SplashOutputDev::endTextObject(GfxState *state) { + if (textClipPath) { + splash->clipToPath(textClipPath, gFalse); + delete textClipPath; + textClipPath = NULL; + } +} + +struct SplashOutImageMaskData { + ImageStream *imgStr; + GBool invert; + int width, height, y; +}; + +GBool SplashOutputDev::imageMaskSrc(void *data, SplashColorPtr line) { + SplashOutImageMaskData *imgMaskData = (SplashOutImageMaskData *)data; + Guchar *p; + SplashColorPtr q; + int x; + + if (imgMaskData->y == imgMaskData->height) { + return gFalse; + } + for (x = 0, p = imgMaskData->imgStr->getLine(), q = line; + x < imgMaskData->width; + ++x) { + *q++ = *p++ ^ imgMaskData->invert; + } + ++imgMaskData->y; + return gTrue; +} + +void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + double *ctm; + SplashCoord mat[6]; + SplashOutImageMaskData imgMaskData; + + ctm = state->getCTM(); + mat[0] = ctm[0]; + mat[1] = ctm[1]; + mat[2] = -ctm[2]; + mat[3] = -ctm[3]; + mat[4] = ctm[2] + ctm[4]; + mat[5] = ctm[3] + ctm[5]; + + imgMaskData.imgStr = new ImageStream(str, width, 1, 1); + imgMaskData.imgStr->reset(); + imgMaskData.invert = invert ? 0 : 1; + imgMaskData.width = width; + imgMaskData.height = height; + imgMaskData.y = 0; + + splash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat); + if (inlineImg) { + while (imgMaskData.y < height) { + imgMaskData.imgStr->getLine(); + ++imgMaskData.y; + } + } + + delete imgMaskData.imgStr; + str->close(); +} + +struct SplashOutImageData { + ImageStream *imgStr; + GfxImageColorMap *colorMap; + SplashColorPtr lookup; + int *maskColors; + SplashColorMode colorMode; + int width, height, y; +}; + +GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr line) { + SplashOutImageData *imgData = (SplashOutImageData *)data; + Guchar *p; + SplashColorPtr q, col; + GfxRGB rgb; + GfxGray gray; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + int nComps, x; + + if (imgData->y == imgData->height) { + return gFalse; + } + + nComps = imgData->colorMap->getNumPixelComps(); + + if (imgData->lookup) { + switch (imgData->colorMode) { + case splashModeMono1: + case splashModeMono8: + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, ++p) { + *q++ = imgData->lookup[*p]; + } + break; + case splashModeRGB8: + case splashModeBGR8: + case splashModeRGB8Qt: + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, ++p) { + col = &imgData->lookup[3 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + } + break; +#if SPLASH_CMYK + case splashModeCMYK8: + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, ++p) { + col = &imgData->lookup[4 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + *q++ = col[3]; + } + break; +#endif + case splashModeAMono8: + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeACMYK8: +#endif + //~ unimplemented + break; + } + } else { + switch (imgData->colorMode) { + case splashModeMono1: + case splashModeMono8: + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, p += nComps) { + imgData->colorMap->getGray(p, &gray); + *q++ = colToByte(gray); + } + break; + case splashModeRGB8: + case splashModeRGB8Qt: + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, p += nComps) { + imgData->colorMap->getRGB(p, &rgb); + *q++ = colToByte(rgb.r); + *q++ = colToByte(rgb.g); + *q++ = colToByte(rgb.b); + } + break; + case splashModeBGR8: + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, p += nComps) { + imgData->colorMap->getRGB(p, &rgb); + *q++ = colToByte(rgb.b); + *q++ = colToByte(rgb.g); + *q++ = colToByte(rgb.r); + } + break; +#if SPLASH_CMYK + case splashModeCMYK8: + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, p += nComps) { + imgData->colorMap->getCMYK(p, &cmyk); + *q++ = colToByte(cmyk.c); + *q++ = colToByte(cmyk.m); + *q++ = colToByte(cmyk.y); + *q++ = colToByte(cmyk.k); + } + break; +#endif + case splashModeAMono8: + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeACMYK8: +#endif + //~ unimplemented + break; + } + } + + ++imgData->y; + return gTrue; +} + +GBool SplashOutputDev::alphaImageSrc(void *data, SplashColorPtr line) { + SplashOutImageData *imgData = (SplashOutImageData *)data; + Guchar *p; + SplashColorPtr q, col; + GfxRGB rgb; + GfxGray gray; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + Guchar alpha; + int nComps, x, i; + + if (imgData->y == imgData->height) { + return gFalse; + } + + nComps = imgData->colorMap->getNumPixelComps(); + + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, p += nComps) { + alpha = 0; + for (i = 0; i < nComps; ++i) { + if (p[i] < imgData->maskColors[2*i] || + p[i] > imgData->maskColors[2*i+1]) { + alpha = 0xff; + break; + } + } + if (imgData->lookup) { + switch (imgData->colorMode) { + case splashModeMono1: + case splashModeMono8: + *q++ = alpha; + *q++ = imgData->lookup[*p]; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + *q++ = alpha; + col = &imgData->lookup[3 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + break; + case splashModeBGR8: + col = &imgData->lookup[3 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + *q++ = alpha; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + *q++ = alpha; + col = &imgData->lookup[4 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + *q++ = col[3]; + break; +#endif + case splashModeAMono8: + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeACMYK8: +#endif + //~ unimplemented + break; + } + } else { + switch (imgData->colorMode) { + case splashModeMono1: + case splashModeMono8: + imgData->colorMap->getGray(p, &gray); + *q++ = alpha; + *q++ = colToByte(gray); + break; + case splashModeRGB8: + case splashModeRGB8Qt: + imgData->colorMap->getRGB(p, &rgb); + *q++ = alpha; + *q++ = colToByte(rgb.r); + *q++ = colToByte(rgb.g); + *q++ = colToByte(rgb.b); + break; + case splashModeBGR8: + imgData->colorMap->getRGB(p, &rgb); + *q++ = colToByte(rgb.b); + *q++ = colToByte(rgb.g); + *q++ = colToByte(rgb.r); + *q++ = alpha; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + imgData->colorMap->getCMYK(p, &cmyk); + *q++ = alpha; + *q++ = colToByte(cmyk.c); + *q++ = colToByte(cmyk.m); + *q++ = colToByte(cmyk.y); + *q++ = colToByte(cmyk.k); + break; +#endif + case splashModeAMono8: + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeACMYK8: +#endif + //~ unimplemented + break; + } + } + } + + ++imgData->y; + return gTrue; +} + +void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) { + double *ctm; + SplashCoord mat[6]; + SplashOutImageData imgData; + SplashColorMode srcMode; + SplashImageSource src; + GfxGray gray; + GfxRGB rgb; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + Guchar pix; + int n, i; + + ctm = state->getCTM(); + mat[0] = ctm[0]; + mat[1] = ctm[1]; + mat[2] = -ctm[2]; + mat[3] = -ctm[3]; + mat[4] = ctm[2] + ctm[4]; + mat[5] = ctm[3] + ctm[5]; + + imgData.imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgData.imgStr->reset(); + imgData.colorMap = colorMap; + imgData.maskColors = maskColors; + imgData.colorMode = colorMode; + imgData.width = width; + imgData.height = height; + imgData.y = 0; + + // special case for one-channel (monochrome/gray/separation) images: + // build a lookup table here + imgData.lookup = NULL; + if (colorMap->getNumPixelComps() == 1) { + n = 1 << colorMap->getBits(); + switch (colorMode) { + case splashModeMono1: + case splashModeMono8: + imgData.lookup = (SplashColorPtr)gmalloc(n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getGray(&pix, &gray); + imgData.lookup[i] = colToByte(gray); + } + break; + case splashModeRGB8: + case splashModeRGB8Qt: + imgData.lookup = (SplashColorPtr)gmalloc(3 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getRGB(&pix, &rgb); + imgData.lookup[3*i] = colToByte(rgb.r); + imgData.lookup[3*i+1] = colToByte(rgb.g); + imgData.lookup[3*i+2] = colToByte(rgb.b); + } + break; + case splashModeBGR8: + imgData.lookup = (SplashColorPtr)gmalloc(3 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getRGB(&pix, &rgb); + imgData.lookup[3*i] = colToByte(rgb.b); + imgData.lookup[3*i+1] = colToByte(rgb.g); + imgData.lookup[3*i+2] = colToByte(rgb.r); + } + break; +#if SPLASH_CMYK + case splashModeCMYK8: + imgData.lookup = (SplashColorPtr)gmalloc(4 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getCMYK(&pix, &cmyk); + imgData.lookup[4*i] = colToByte(cmyk.c); + imgData.lookup[4*i+1] = colToByte(cmyk.m); + imgData.lookup[4*i+2] = colToByte(cmyk.y); + imgData.lookup[4*i+3] = colToByte(cmyk.k); + } + break; +#endif + default: + //~ unimplemented + break; + } + } + + switch (colorMode) { + case splashModeMono1: + case splashModeMono8: + srcMode = maskColors ? splashModeAMono8 : splashModeMono8; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + srcMode = maskColors ? splashModeARGB8 : splashModeRGB8; + break; + case splashModeBGR8: + srcMode = maskColors ? splashModeBGRA8 : splashModeBGR8; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + srcMode = maskColors ? splashModeACMYK8 : splashModeCMYK8; + break; +#endif + default: + //~ unimplemented + srcMode = splashModeRGB8; + break; + } + src = maskColors ? &alphaImageSrc : &imageSrc; + splash->drawImage(src, &imgData, srcMode, width, height, mat); + if (inlineImg) { + while (imgData.y < height) { + imgData.imgStr->getLine(); + ++imgData.y; + } + } + + gfree(imgData.lookup); + delete imgData.imgStr; + str->close(); +} + +struct SplashOutMaskedImageData { + ImageStream *imgStr; + GfxImageColorMap *colorMap; + SplashBitmap *mask; + SplashColorPtr lookup; + SplashColorMode colorMode; + int width, height, y; +}; + +GBool SplashOutputDev::maskedImageSrc(void *data, SplashColorPtr line) { + SplashOutMaskedImageData *imgData = (SplashOutMaskedImageData *)data; + Guchar *p; + SplashColor maskColor; + SplashColorPtr q, col; + GfxRGB rgb; + GfxGray gray; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + Guchar alpha; + int nComps, x; + + if (imgData->y == imgData->height) { + return gFalse; + } + + nComps = imgData->colorMap->getNumPixelComps(); + + for (x = 0, p = imgData->imgStr->getLine(), q = line; + x < imgData->width; + ++x, p += nComps) { + imgData->mask->getPixel(x, imgData->y, maskColor); + alpha = maskColor[0] ? 0xff : 0x00; + if (imgData->lookup) { + switch (imgData->colorMode) { + case splashModeMono1: + case splashModeMono8: + *q++ = alpha; + *q++ = imgData->lookup[*p]; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + *q++ = alpha; + col = &imgData->lookup[3 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + break; + case splashModeBGR8: + col = &imgData->lookup[3 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + *q++ = alpha; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + *q++ = alpha; + col = &imgData->lookup[4 * *p]; + *q++ = col[0]; + *q++ = col[1]; + *q++ = col[2]; + *q++ = col[3]; + break; +#endif + case splashModeAMono8: + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeACMYK8: +#endif + //~ unimplemented + break; + } + } else { + switch (imgData->colorMode) { + case splashModeMono1: + case splashModeMono8: + imgData->colorMap->getGray(p, &gray); + *q++ = alpha; + *q++ = colToByte(gray); + break; + case splashModeRGB8: + case splashModeRGB8Qt: + imgData->colorMap->getRGB(p, &rgb); + *q++ = alpha; + *q++ = colToByte(rgb.r); + *q++ = colToByte(rgb.g); + *q++ = colToByte(rgb.b); + break; + case splashModeBGR8: + imgData->colorMap->getRGB(p, &rgb); + *q++ = colToByte(rgb.b); + *q++ = colToByte(rgb.g); + *q++ = colToByte(rgb.r); + *q++ = alpha; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + imgData->colorMap->getCMYK(p, &cmyk); + *q++ = alpha; + *q++ = colToByte(cmyk.c); + *q++ = colToByte(cmyk.m); + *q++ = colToByte(cmyk.y); + *q++ = colToByte(cmyk.k); + break; +#endif + case splashModeAMono8: + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeACMYK8: +#endif + //~ unimplemented + break; + } + } + } + + ++imgData->y; + return gTrue; +} + +void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref, + Stream *str, int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, int maskWidth, + int maskHeight, GBool maskInvert) { + double *ctm; + SplashCoord mat[6]; + SplashOutMaskedImageData imgData; + SplashOutImageMaskData imgMaskData; + SplashColorMode srcMode; + SplashBitmap *maskBitmap; + Splash *maskSplash; + SplashColor maskColor; + GfxGray gray; + GfxRGB rgb; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + Guchar pix; + int n, i; + + //----- scale the mask image to the same size as the source image + + mat[0] = (SplashCoord)width; + mat[1] = 0; + mat[2] = 0; + mat[3] = (SplashCoord)height; + mat[4] = 0; + mat[5] = 0; + imgMaskData.imgStr = new ImageStream(maskStr, maskWidth, 1, 1); + imgMaskData.imgStr->reset(); + imgMaskData.invert = maskInvert ? 0 : 1; + imgMaskData.width = maskWidth; + imgMaskData.height = maskHeight; + imgMaskData.y = 0; + maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1); + maskSplash = new Splash(maskBitmap); + maskColor[0] = 0; + maskSplash->clear(maskColor); + maskColor[0] = 1; + maskSplash->setFillPattern(new SplashSolidColor(maskColor)); + maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData, + maskWidth, maskHeight, mat); + delete imgMaskData.imgStr; + maskStr->close(); + delete maskSplash; + + //----- draw the source image + + ctm = state->getCTM(); + mat[0] = ctm[0]; + mat[1] = ctm[1]; + mat[2] = -ctm[2]; + mat[3] = -ctm[3]; + mat[4] = ctm[2] + ctm[4]; + mat[5] = ctm[3] + ctm[5]; + + imgData.imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgData.imgStr->reset(); + imgData.colorMap = colorMap; + imgData.mask = maskBitmap; + imgData.colorMode = colorMode; + imgData.width = width; + imgData.height = height; + imgData.y = 0; + + // special case for one-channel (monochrome/gray/separation) images: + // build a lookup table here + imgData.lookup = NULL; + if (colorMap->getNumPixelComps() == 1) { + n = 1 << colorMap->getBits(); + switch (colorMode) { + case splashModeMono1: + case splashModeMono8: + imgData.lookup = (SplashColorPtr)gmalloc(n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getGray(&pix, &gray); + imgData.lookup[i] = colToByte(gray); + } + break; + case splashModeRGB8: + case splashModeRGB8Qt: + imgData.lookup = (SplashColorPtr)gmalloc(3 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getRGB(&pix, &rgb); + imgData.lookup[3*i] = colToByte(rgb.r); + imgData.lookup[3*i+1] = colToByte(rgb.g); + imgData.lookup[3*i+2] = colToByte(rgb.b); + } + break; + case splashModeBGR8: + imgData.lookup = (SplashColorPtr)gmalloc(3 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getRGB(&pix, &rgb); + imgData.lookup[3*i] = colToByte(rgb.b); + imgData.lookup[3*i+1] = colToByte(rgb.g); + imgData.lookup[3*i+2] = colToByte(rgb.r); + } + break; +#if SPLASH_CMYK + case splashModeCMYK8: + imgData.lookup = (SplashColorPtr)gmalloc(4 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getCMYK(&pix, &cmyk); + imgData.lookup[4*i] = colToByte(cmyk.c); + imgData.lookup[4*i+1] = colToByte(cmyk.m); + imgData.lookup[4*i+2] = colToByte(cmyk.y); + imgData.lookup[4*i+3] = colToByte(cmyk.k); + } + break; +#endif + default: + //~ unimplemented + break; + } + } + + switch (colorMode) { + case splashModeMono1: + case splashModeMono8: + srcMode = splashModeAMono8; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + srcMode = splashModeARGB8; + break; + case splashModeBGR8: + srcMode = splashModeBGRA8; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + srcMode = splashModeACMYK8; + break; +#endif + default: + //~ unimplemented + srcMode = splashModeARGB8; + break; + } + splash->drawImage(&maskedImageSrc, &imgData, srcMode, width, height, mat); + + delete maskBitmap; + gfree(imgData.lookup); + delete imgData.imgStr; + str->close(); +} + +void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, + Stream *str, int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap) { + double *ctm; + SplashCoord mat[6]; + SplashOutImageData imgData; + SplashOutImageData imgMaskData; + SplashColorMode srcMode; + SplashBitmap *maskBitmap; + Splash *maskSplash; + SplashColor maskColor; + GfxGray gray; + GfxRGB rgb; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + Guchar pix; + int n, i; + + ctm = state->getCTM(); + mat[0] = ctm[0]; + mat[1] = ctm[1]; + mat[2] = -ctm[2]; + mat[3] = -ctm[3]; + mat[4] = ctm[2] + ctm[4]; + mat[5] = ctm[3] + ctm[5]; + + //----- set up the soft mask + + imgMaskData.imgStr = new ImageStream(maskStr, maskWidth, + maskColorMap->getNumPixelComps(), + maskColorMap->getBits()); + imgMaskData.imgStr->reset(); + imgMaskData.colorMap = maskColorMap; + imgMaskData.maskColors = NULL; + imgMaskData.colorMode = splashModeMono8; + imgMaskData.width = maskWidth; + imgMaskData.height = maskHeight; + imgMaskData.y = 0; + n = 1 << maskColorMap->getBits(); + imgMaskData.lookup = (SplashColorPtr)gmalloc(n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + maskColorMap->getGray(&pix, &gray); + imgMaskData.lookup[i] = colToByte(gray); + } + maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(), + 1, splashModeMono8); + maskSplash = new Splash(maskBitmap); + maskColor[0] = 0; + maskSplash->clear(maskColor); + maskSplash->drawImage(&imageSrc, &imgMaskData, + splashModeMono8, maskWidth, maskHeight, mat); + delete imgMaskData.imgStr; + maskStr->close(); + gfree(imgMaskData.lookup); + delete maskSplash; + splash->setSoftMask(maskBitmap); + + //----- draw the source image + + imgData.imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgData.imgStr->reset(); + imgData.colorMap = colorMap; + imgData.maskColors = NULL; + imgData.colorMode = colorMode; + imgData.width = width; + imgData.height = height; + imgData.y = 0; + + // special case for one-channel (monochrome/gray/separation) images: + // build a lookup table here + imgData.lookup = NULL; + if (colorMap->getNumPixelComps() == 1) { + n = 1 << colorMap->getBits(); + switch (colorMode) { + case splashModeMono1: + case splashModeMono8: + imgData.lookup = (SplashColorPtr)gmalloc(n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getGray(&pix, &gray); + imgData.lookup[i] = colToByte(gray); + } + break; + case splashModeRGB8: + case splashModeRGB8Qt: + imgData.lookup = (SplashColorPtr)gmalloc(3 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getRGB(&pix, &rgb); + imgData.lookup[3*i] = colToByte(rgb.r); + imgData.lookup[3*i+1] = colToByte(rgb.g); + imgData.lookup[3*i+2] = colToByte(rgb.b); + } + break; + case splashModeBGR8: + imgData.lookup = (SplashColorPtr)gmalloc(3 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getRGB(&pix, &rgb); + imgData.lookup[3*i] = colToByte(rgb.b); + imgData.lookup[3*i+1] = colToByte(rgb.g); + imgData.lookup[3*i+2] = colToByte(rgb.r); + } + break; +#if SPLASH_CMYK + case splashModeCMYK8: + imgData.lookup = (SplashColorPtr)gmalloc(4 * n); + for (i = 0; i < n; ++i) { + pix = (Guchar)i; + colorMap->getCMYK(&pix, &cmyk); + imgData.lookup[4*i] = colToByte(cmyk.c); + imgData.lookup[4*i+1] = colToByte(cmyk.m); + imgData.lookup[4*i+2] = colToByte(cmyk.y); + imgData.lookup[4*i+3] = colToByte(cmyk.k); + } + break; +#endif + default: + //~ unimplemented + break; + } + } + + switch (colorMode) { + case splashModeMono1: + case splashModeMono8: + srcMode = splashModeMono8; + break; + case splashModeRGB8: + case splashModeRGB8Qt: + srcMode = splashModeRGB8; + break; + case splashModeBGR8: + srcMode = splashModeBGR8; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + srcMode = splashModeCMYK8; + break; +#endif + default: + //~ unimplemented + srcMode = splashModeRGB8; + break; + } + splash->drawImage(&imageSrc, &imgData, srcMode, width, height, mat); + + splash->setSoftMask(NULL); + gfree(imgData.lookup); + delete imgData.imgStr; + str->close(); +} + +void SplashOutputDev::setPaperColor(SplashColorPtr paperColorA) { + splashColorCopy(paperColor, paperColorA); +} + +int SplashOutputDev::getBitmapWidth() { + return bitmap->getWidth(); +} + +int SplashOutputDev::getBitmapHeight() { + return bitmap->getHeight(); +} + +SplashBitmap *SplashOutputDev::takeBitmap() { + SplashBitmap *ret; + + ret = bitmap; + bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode, bitmapTopDown); + return ret; +} + +void SplashOutputDev::getModRegion(int *xMin, int *yMin, + int *xMax, int *yMax) { + splash->getModRegion(xMin, yMin, xMax, yMax); +} + +void SplashOutputDev::clearModRegion() { + splash->clearModRegion(); +} + +void SplashOutputDev::setFillColor(int r, int g, int b) { + GfxRGB rgb; + GfxGray gray; +#if SPLASH_CMYK + GfxCMYK cmyk; +#endif + + rgb.r = byteToCol(r); + rgb.g = byteToCol(g); + rgb.b = byteToCol(b); + gray = (GfxColorComp)(0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b + 0.5); + if (gray > gfxColorComp1) { + gray = gfxColorComp1; + } +#if SPLASH_CMYK + cmyk.c = gfxColorComp1 - rgb.r; + cmyk.m = gfxColorComp1 - rgb.g; + cmyk.y = gfxColorComp1 - rgb.b; + cmyk.k = 0; + splash->setFillPattern(getColor(gray, &rgb, &cmyk)); +#else + splash->setFillPattern(getColor(gray, &rgb)); +#endif +} + diff --git a/rosapps/smartpdf/poppler/poppler/SplashOutputDev.h b/rosapps/smartpdf/poppler/poppler/SplashOutputDev.h new file mode 100644 index 00000000000..caa64555245 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/SplashOutputDev.h @@ -0,0 +1,217 @@ +//======================================================================== +// +// SplashOutputDev.h +// +// Copyright 2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef SPLASHOUTPUTDEV_H +#define SPLASHOUTPUTDEV_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "splash/SplashTypes.h" +#include "poppler-config.h" +#include "OutputDev.h" +#include "GfxState.h" + +class Gfx8BitFont; +class SplashBitmap; +class Splash; +class SplashPath; +class SplashPattern; +class SplashFontEngine; +class SplashFont; +class T3FontCache; +struct T3FontCacheTag; +struct T3GlyphStack; + +//------------------------------------------------------------------------ + +// number of Type 3 fonts to cache +#define splashOutT3FontCacheSize 8 + +//------------------------------------------------------------------------ +// SplashOutputDev +//------------------------------------------------------------------------ + +class SplashOutputDev: public OutputDev { +public: + + // Constructor. + SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA, + GBool reverseVideoA, SplashColorPtr paperColorA, + GBool bitmapTopDownA = gTrue, + GBool allowAntialiasA = gTrue); + + // Destructor. + virtual ~SplashOutputDev(); + + //----- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gTrue; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gTrue; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() { return gTrue; } + + //----- initialization and control + + // Start a page. + virtual void startPage(int pageNum, GfxState *state); + + // End a page. + virtual void endPage(); + + //----- link borders + virtual void drawLink(Link *link, Catalog *catalog); + + //----- save/restore graphics state + virtual void saveState(GfxState *state); + virtual void restoreState(GfxState *state); + + //----- update graphics state + virtual void updateAll(GfxState *state); + virtual void updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32); + virtual void updateLineDash(GfxState *state); + virtual void updateFlatness(GfxState *state); + virtual void updateLineJoin(GfxState *state); + virtual void updateLineCap(GfxState *state); + virtual void updateMiterLimit(GfxState *state); + virtual void updateLineWidth(GfxState *state); + virtual void updateFillColor(GfxState *state); + virtual void updateStrokeColor(GfxState *state); + virtual void updateBlendMode(GfxState *state); + virtual void updateFillOpacity(GfxState *state); + virtual void updateStrokeOpacity(GfxState *state); + + //----- update text state + virtual void updateFont(GfxState *state); + + //----- path painting + virtual void stroke(GfxState *state); + virtual void fill(GfxState *state); + virtual void eoFill(GfxState *state); + + //----- path clipping + virtual void clip(GfxState *state); + virtual void eoClip(GfxState *state); + + //----- text drawing + virtual void drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, Unicode *u, int uLen); + virtual GBool beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen); + virtual void endType3Char(GfxState *state); + virtual void endTextObject(GfxState *state); + + //----- image drawing + virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg); + virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, int maskWidth, int maskHeight, + GBool maskInvert); + virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap); + + //----- Type 3 font operators + virtual void type3D0(GfxState *state, double wx, double wy); + virtual void type3D1(GfxState *state, double wx, double wy, + double llx, double lly, double urx, double ury); + + //----- special access + + // Called to indicate that a new PDF document has been loaded. + void startDoc(XRef *xrefA); + + void setPaperColor(SplashColorPtr paperColorA); + + GBool isReverseVideo() { return reverseVideo; } + void setReverseVideo(GBool reverseVideoA) { reverseVideo = reverseVideoA; } + + // Get the bitmap and its size. + SplashBitmap *getBitmap() { return bitmap; } + int getBitmapWidth(); + int getBitmapHeight(); + + // Returns the last rasterized bitmap, transferring ownership to the + // caller. + SplashBitmap *takeBitmap(); + + // Get the Splash object. + Splash *getSplash() { return splash; } + + // Get the modified region. + void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax); + + // Clear the modified region. + void clearModRegion(); + + // Set the Splash fill color. + void setFillColor(int r, int g, int b); + + SplashFont *getCurrentFont() { return font; } + +private: + +#if SPLASH_CMYK + SplashPattern *getColor(GfxGray gray, GfxRGB *rgb, GfxCMYK *cmyk); +#else + SplashPattern *getColor(GfxGray gray, GfxRGB *rgb); +#endif + SplashPath *convertPath(GfxState *state, GfxPath *path); + void drawType3Glyph(T3FontCache *t3Font, + T3FontCacheTag *tag, Guchar *data, + double x, double y); + static GBool imageMaskSrc(void *data, SplashColorPtr line); + static GBool imageSrc(void *data, SplashColorPtr line); + static GBool alphaImageSrc(void *data, SplashColorPtr line); + static GBool maskedImageSrc(void *data, SplashColorPtr line); + + SplashColorMode colorMode; + int bitmapRowPad; + GBool bitmapTopDown; + GBool allowAntialias; + GBool reverseVideo; // reverse video mode + SplashColor paperColor; // paper color + + XRef *xref; // xref table for current document + + SplashBitmap *bitmap; + Splash *splash; + SplashFontEngine *fontEngine; + + T3FontCache * // Type 3 font cache + t3FontCache[splashOutT3FontCacheSize]; + int nT3Fonts; // number of valid entries in t3FontCache + T3GlyphStack *t3GlyphStack; // Type 3 glyph context stack + + SplashFont *font; // current font + GBool needFontUpdate; // set when the font needs to be updated + SplashPath *textClipPath; // clipping path built with text object +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/Stream-CCITT.h b/rosapps/smartpdf/poppler/poppler/Stream-CCITT.h new file mode 100644 index 00000000000..c4458fe714e --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Stream-CCITT.h @@ -0,0 +1,459 @@ +//======================================================================== +// +// Stream-CCITT.h +// +// Tables for CCITT Fax decoding. +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +struct CCITTCode { + short bits; + short n; +}; + +#define ccittEOL -2 + +//------------------------------------------------------------------------ +// 2D codes +//------------------------------------------------------------------------ + +#define twoDimPass 0 +#define twoDimHoriz 1 +#define twoDimVert0 2 +#define twoDimVertR1 3 +#define twoDimVertL1 4 +#define twoDimVertR2 5 +#define twoDimVertL2 6 +#define twoDimVertR3 7 +#define twoDimVertL3 8 + +// 1-7 bit codes +static CCITTCode twoDimTab1[128] = { + {-1, -1}, {-1, -1}, // 000000x + {7, twoDimVertL3}, // 0000010 + {7, twoDimVertR3}, // 0000011 + {6, twoDimVertL2}, {6, twoDimVertL2}, // 000010x + {6, twoDimVertR2}, {6, twoDimVertR2}, // 000011x + {4, twoDimPass}, {4, twoDimPass}, // 0001xxx + {4, twoDimPass}, {4, twoDimPass}, + {4, twoDimPass}, {4, twoDimPass}, + {4, twoDimPass}, {4, twoDimPass}, + {3, twoDimHoriz}, {3, twoDimHoriz}, // 001xxxx + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimVertL1}, {3, twoDimVertL1}, // 010xxxx + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, // 011xxxx + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {1, twoDimVert0}, {1, twoDimVert0}, // 1xxxxxx + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0} +}; + +//------------------------------------------------------------------------ +// white run lengths +//------------------------------------------------------------------------ + +// 11-12 bit codes (upper 7 bits are 0) +static CCITTCode whiteTab1[32] = { + {-1, -1}, // 00000 + {12, ccittEOL}, // 00001 + {-1, -1}, {-1, -1}, // 0001x + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 001xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 010xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 011xx + {11, 1792}, {11, 1792}, // 1000x + {12, 1984}, // 10010 + {12, 2048}, // 10011 + {12, 2112}, // 10100 + {12, 2176}, // 10101 + {12, 2240}, // 10110 + {12, 2304}, // 10111 + {11, 1856}, {11, 1856}, // 1100x + {11, 1920}, {11, 1920}, // 1101x + {12, 2368}, // 11100 + {12, 2432}, // 11101 + {12, 2496}, // 11110 + {12, 2560} // 11111 +}; + +// 1-9 bit codes +static CCITTCode whiteTab2[512] = { + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 0000000xx + {8, 29}, {8, 29}, // 00000010x + {8, 30}, {8, 30}, // 00000011x + {8, 45}, {8, 45}, // 00000100x + {8, 46}, {8, 46}, // 00000101x + {7, 22}, {7, 22}, {7, 22}, {7, 22}, // 0000011xx + {7, 23}, {7, 23}, {7, 23}, {7, 23}, // 0000100xx + {8, 47}, {8, 47}, // 00001010x + {8, 48}, {8, 48}, // 00001011x + {6, 13}, {6, 13}, {6, 13}, {6, 13}, // 000011xxx + {6, 13}, {6, 13}, {6, 13}, {6, 13}, + {7, 20}, {7, 20}, {7, 20}, {7, 20}, // 0001000xx + {8, 33}, {8, 33}, // 00010010x + {8, 34}, {8, 34}, // 00010011x + {8, 35}, {8, 35}, // 00010100x + {8, 36}, {8, 36}, // 00010101x + {8, 37}, {8, 37}, // 00010110x + {8, 38}, {8, 38}, // 00010111x + {7, 19}, {7, 19}, {7, 19}, {7, 19}, // 0001100xx + {8, 31}, {8, 31}, // 00011010x + {8, 32}, {8, 32}, // 00011011x + {6, 1}, {6, 1}, {6, 1}, {6, 1}, // 000111xxx + {6, 1}, {6, 1}, {6, 1}, {6, 1}, + {6, 12}, {6, 12}, {6, 12}, {6, 12}, // 001000xxx + {6, 12}, {6, 12}, {6, 12}, {6, 12}, + {8, 53}, {8, 53}, // 00100100x + {8, 54}, {8, 54}, // 00100101x + {7, 26}, {7, 26}, {7, 26}, {7, 26}, // 0010011xx + {8, 39}, {8, 39}, // 00101000x + {8, 40}, {8, 40}, // 00101001x + {8, 41}, {8, 41}, // 00101010x + {8, 42}, {8, 42}, // 00101011x + {8, 43}, {8, 43}, // 00101100x + {8, 44}, {8, 44}, // 00101101x + {7, 21}, {7, 21}, {7, 21}, {7, 21}, // 0010111xx + {7, 28}, {7, 28}, {7, 28}, {7, 28}, // 0011000xx + {8, 61}, {8, 61}, // 00110010x + {8, 62}, {8, 62}, // 00110011x + {8, 63}, {8, 63}, // 00110100x + {8, 0}, {8, 0}, // 00110101x + {8, 320}, {8, 320}, // 00110110x + {8, 384}, {8, 384}, // 00110111x + {5, 10}, {5, 10}, {5, 10}, {5, 10}, // 00111xxxx + {5, 10}, {5, 10}, {5, 10}, {5, 10}, + {5, 10}, {5, 10}, {5, 10}, {5, 10}, + {5, 10}, {5, 10}, {5, 10}, {5, 10}, + {5, 11}, {5, 11}, {5, 11}, {5, 11}, // 01000xxxx + {5, 11}, {5, 11}, {5, 11}, {5, 11}, + {5, 11}, {5, 11}, {5, 11}, {5, 11}, + {5, 11}, {5, 11}, {5, 11}, {5, 11}, + {7, 27}, {7, 27}, {7, 27}, {7, 27}, // 0100100xx + {8, 59}, {8, 59}, // 01001010x + {8, 60}, {8, 60}, // 01001011x + {9, 1472}, // 010011000 + {9, 1536}, // 010011001 + {9, 1600}, // 010011010 + {9, 1728}, // 010011011 + {7, 18}, {7, 18}, {7, 18}, {7, 18}, // 0100111xx + {7, 24}, {7, 24}, {7, 24}, {7, 24}, // 0101000xx + {8, 49}, {8, 49}, // 01010010x + {8, 50}, {8, 50}, // 01010011x + {8, 51}, {8, 51}, // 01010100x + {8, 52}, {8, 52}, // 01010101x + {7, 25}, {7, 25}, {7, 25}, {7, 25}, // 0101011xx + {8, 55}, {8, 55}, // 01011000x + {8, 56}, {8, 56}, // 01011001x + {8, 57}, {8, 57}, // 01011010x + {8, 58}, {8, 58}, // 01011011x + {6, 192}, {6, 192}, {6, 192}, {6, 192}, // 010111xxx + {6, 192}, {6, 192}, {6, 192}, {6, 192}, + {6, 1664}, {6, 1664}, {6, 1664}, {6, 1664}, // 011000xxx + {6, 1664}, {6, 1664}, {6, 1664}, {6, 1664}, + {8, 448}, {8, 448}, // 01100100x + {8, 512}, {8, 512}, // 01100101x + {9, 704}, // 011001100 + {9, 768}, // 011001101 + {8, 640}, {8, 640}, // 01100111x + {8, 576}, {8, 576}, // 01101000x + {9, 832}, // 011010010 + {9, 896}, // 011010011 + {9, 960}, // 011010100 + {9, 1024}, // 011010101 + {9, 1088}, // 011010110 + {9, 1152}, // 011010111 + {9, 1216}, // 011011000 + {9, 1280}, // 011011001 + {9, 1344}, // 011011010 + {9, 1408}, // 011011011 + {7, 256}, {7, 256}, {7, 256}, {7, 256}, // 0110111xx + {4, 2}, {4, 2}, {4, 2}, {4, 2}, // 0111xxxxx + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, // 1000xxxxx + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {5, 128}, {5, 128}, {5, 128}, {5, 128}, // 10010xxxx + {5, 128}, {5, 128}, {5, 128}, {5, 128}, + {5, 128}, {5, 128}, {5, 128}, {5, 128}, + {5, 128}, {5, 128}, {5, 128}, {5, 128}, + {5, 8}, {5, 8}, {5, 8}, {5, 8}, // 10011xxxx + {5, 8}, {5, 8}, {5, 8}, {5, 8}, + {5, 8}, {5, 8}, {5, 8}, {5, 8}, + {5, 8}, {5, 8}, {5, 8}, {5, 8}, + {5, 9}, {5, 9}, {5, 9}, {5, 9}, // 10100xxxx + {5, 9}, {5, 9}, {5, 9}, {5, 9}, + {5, 9}, {5, 9}, {5, 9}, {5, 9}, + {5, 9}, {5, 9}, {5, 9}, {5, 9}, + {6, 16}, {6, 16}, {6, 16}, {6, 16}, // 101010xxx + {6, 16}, {6, 16}, {6, 16}, {6, 16}, + {6, 17}, {6, 17}, {6, 17}, {6, 17}, // 101011xxx + {6, 17}, {6, 17}, {6, 17}, {6, 17}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, // 1011xxxxx + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, // 1100xxxxx + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {6, 14}, {6, 14}, {6, 14}, {6, 14}, // 110100xxx + {6, 14}, {6, 14}, {6, 14}, {6, 14}, + {6, 15}, {6, 15}, {6, 15}, {6, 15}, // 110101xxx + {6, 15}, {6, 15}, {6, 15}, {6, 15}, + {5, 64}, {5, 64}, {5, 64}, {5, 64}, // 11011xxxx + {5, 64}, {5, 64}, {5, 64}, {5, 64}, + {5, 64}, {5, 64}, {5, 64}, {5, 64}, + {5, 64}, {5, 64}, {5, 64}, {5, 64}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, // 1110xxxxx + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, // 1111xxxxx + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7} +}; + +//------------------------------------------------------------------------ +// black run lengths +//------------------------------------------------------------------------ + +// 10-13 bit codes (upper 6 bits are 0) +static CCITTCode blackTab1[128] = { + {-1, -1}, {-1, -1}, // 000000000000x + {12, ccittEOL}, {12, ccittEOL}, // 000000000001x + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000001xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000010xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000011xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000100xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000101xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000110xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000111xx + {11, 1792}, {11, 1792}, {11, 1792}, {11, 1792}, // 00000001000xx + {12, 1984}, {12, 1984}, // 000000010010x + {12, 2048}, {12, 2048}, // 000000010011x + {12, 2112}, {12, 2112}, // 000000010100x + {12, 2176}, {12, 2176}, // 000000010101x + {12, 2240}, {12, 2240}, // 000000010110x + {12, 2304}, {12, 2304}, // 000000010111x + {11, 1856}, {11, 1856}, {11, 1856}, {11, 1856}, // 00000001100xx + {11, 1920}, {11, 1920}, {11, 1920}, {11, 1920}, // 00000001101xx + {12, 2368}, {12, 2368}, // 000000011100x + {12, 2432}, {12, 2432}, // 000000011101x + {12, 2496}, {12, 2496}, // 000000011110x + {12, 2560}, {12, 2560}, // 000000011111x + {10, 18}, {10, 18}, {10, 18}, {10, 18}, // 0000001000xxx + {10, 18}, {10, 18}, {10, 18}, {10, 18}, + {12, 52}, {12, 52}, // 000000100100x + {13, 640}, // 0000001001010 + {13, 704}, // 0000001001011 + {13, 768}, // 0000001001100 + {13, 832}, // 0000001001101 + {12, 55}, {12, 55}, // 000000100111x + {12, 56}, {12, 56}, // 000000101000x + {13, 1280}, // 0000001010010 + {13, 1344}, // 0000001010011 + {13, 1408}, // 0000001010100 + {13, 1472}, // 0000001010101 + {12, 59}, {12, 59}, // 000000101011x + {12, 60}, {12, 60}, // 000000101100x + {13, 1536}, // 0000001011010 + {13, 1600}, // 0000001011011 + {11, 24}, {11, 24}, {11, 24}, {11, 24}, // 00000010111xx + {11, 25}, {11, 25}, {11, 25}, {11, 25}, // 00000011000xx + {13, 1664}, // 0000001100100 + {13, 1728}, // 0000001100101 + {12, 320}, {12, 320}, // 000000110011x + {12, 384}, {12, 384}, // 000000110100x + {12, 448}, {12, 448}, // 000000110101x + {13, 512}, // 0000001101100 + {13, 576}, // 0000001101101 + {12, 53}, {12, 53}, // 000000110111x + {12, 54}, {12, 54}, // 000000111000x + {13, 896}, // 0000001110010 + {13, 960}, // 0000001110011 + {13, 1024}, // 0000001110100 + {13, 1088}, // 0000001110101 + {13, 1152}, // 0000001110110 + {13, 1216}, // 0000001110111 + {10, 64}, {10, 64}, {10, 64}, {10, 64}, // 0000001111xxx + {10, 64}, {10, 64}, {10, 64}, {10, 64} +}; + +// 7-12 bit codes (upper 4 bits are 0) +static CCITTCode blackTab2[192] = { + {8, 13}, {8, 13}, {8, 13}, {8, 13}, // 00000100xxxx + {8, 13}, {8, 13}, {8, 13}, {8, 13}, + {8, 13}, {8, 13}, {8, 13}, {8, 13}, + {8, 13}, {8, 13}, {8, 13}, {8, 13}, + {11, 23}, {11, 23}, // 00000101000x + {12, 50}, // 000001010010 + {12, 51}, // 000001010011 + {12, 44}, // 000001010100 + {12, 45}, // 000001010101 + {12, 46}, // 000001010110 + {12, 47}, // 000001010111 + {12, 57}, // 000001011000 + {12, 58}, // 000001011001 + {12, 61}, // 000001011010 + {12, 256}, // 000001011011 + {10, 16}, {10, 16}, {10, 16}, {10, 16}, // 0000010111xx + {10, 17}, {10, 17}, {10, 17}, {10, 17}, // 0000011000xx + {12, 48}, // 000001100100 + {12, 49}, // 000001100101 + {12, 62}, // 000001100110 + {12, 63}, // 000001100111 + {12, 30}, // 000001101000 + {12, 31}, // 000001101001 + {12, 32}, // 000001101010 + {12, 33}, // 000001101011 + {12, 40}, // 000001101100 + {12, 41}, // 000001101101 + {11, 22}, {11, 22}, // 00000110111x + {8, 14}, {8, 14}, {8, 14}, {8, 14}, // 00000111xxxx + {8, 14}, {8, 14}, {8, 14}, {8, 14}, + {8, 14}, {8, 14}, {8, 14}, {8, 14}, + {8, 14}, {8, 14}, {8, 14}, {8, 14}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, // 0000100xxxxx + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, // 0000101xxxxx + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {9, 15}, {9, 15}, {9, 15}, {9, 15}, // 000011000xxx + {9, 15}, {9, 15}, {9, 15}, {9, 15}, + {12, 128}, // 000011001000 + {12, 192}, // 000011001001 + {12, 26}, // 000011001010 + {12, 27}, // 000011001011 + {12, 28}, // 000011001100 + {12, 29}, // 000011001101 + {11, 19}, {11, 19}, // 00001100111x + {11, 20}, {11, 20}, // 00001101000x + {12, 34}, // 000011010010 + {12, 35}, // 000011010011 + {12, 36}, // 000011010100 + {12, 37}, // 000011010101 + {12, 38}, // 000011010110 + {12, 39}, // 000011010111 + {11, 21}, {11, 21}, // 00001101100x + {12, 42}, // 000011011010 + {12, 43}, // 000011011011 + {10, 0}, {10, 0}, {10, 0}, {10, 0}, // 0000110111xx + {7, 12}, {7, 12}, {7, 12}, {7, 12}, // 0000111xxxxx + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12} +}; + +// 2-6 bit codes +static CCITTCode blackTab3[64] = { + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 0000xx + {6, 9}, // 000100 + {6, 8}, // 000101 + {5, 7}, {5, 7}, // 00011x + {4, 6}, {4, 6}, {4, 6}, {4, 6}, // 0010xx + {4, 5}, {4, 5}, {4, 5}, {4, 5}, // 0011xx + {3, 1}, {3, 1}, {3, 1}, {3, 1}, // 010xxx + {3, 1}, {3, 1}, {3, 1}, {3, 1}, + {3, 4}, {3, 4}, {3, 4}, {3, 4}, // 011xxx + {3, 4}, {3, 4}, {3, 4}, {3, 4}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, // 10xxxx + {2, 3}, {2, 3}, {2, 3}, {2, 3}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, // 11xxxx + {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2} +}; diff --git a/rosapps/smartpdf/poppler/poppler/Stream.cc b/rosapps/smartpdf/poppler/poppler/Stream.cc new file mode 100644 index 00000000000..b00f6205f50 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Stream.cc @@ -0,0 +1,4731 @@ +//======================================================================== +// +// Stream.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// Copyright 2006: Krzysztof Kowalczyk (http://blog.kowalczyk.info) +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include +#include "goo/gmem.h" +#include "goo/gfile.h" +#include "poppler-config.h" +#include "Error.h" +#include "Object.h" +#include "Lexer.h" +#include "Decrypt.h" +#include "GfxState.h" +#include "Stream.h" +#include "JBIG2Stream.h" +#include "JPXStream.h" +#include "Stream-CCITT.h" +#include "UGooString.h" + +/* You can disable getBuf() on File/Flate/Embed streams by commenting those out. +This might be helpful when tracking down problems (i.e. if you suspect getBuf() +handling has a bug, you can easily disable it to verify that it's gone when +getBuf() is not used anywhere */ +#define ENABLE_FILE_GET_BUF 1 +#define ENABLE_FLATE_GET_BUF 1 +#define ENABLE_EMBED_GET_BUF 1 + +#ifdef ENABLE_LIBJPEG +#include "DCTStream.h" +#endif + +#ifdef ENABLE_ZLIB +#include "FlateStream.h" +#endif + +#ifdef __DJGPP__ +static GBool setDJSYSFLAGS = gFalse; +#endif + +#ifdef VMS +#ifdef __GNUC__ +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif +#endif + +// FIXME: add more names when you need +const char *getStreamKindName(StreamKind kind) +{ + if (strFile == kind) + return "FileStream"; + else if (strFlate == kind) + return "FlateStream"; + else + return "Unknown"; +} + +//------------------------------------------------------------------------ +// Stream (base class) +//------------------------------------------------------------------------ + +Stream::Stream() { + ref = 1; +} + +Stream::~Stream() { +} + +void Stream::close() { +} + +int Stream::getRawChar() { + error(-1, "Internal: called getRawChar() on non-predictor stream"); + return EOF; +} + +char *Stream::getLine(char *buf, int size) { + int i; + int c; + + if (lookChar() == EOF) + return NULL; + for (i = 0; i < size - 1; ++i) { + c = getChar(); + if (c == EOF || c == '\n') + break; + if (c == '\r') { + if ((c = lookChar()) == '\n') + getChar(); + break; + } + buf[i] = c; + } + buf[i] = '\0'; + return buf; +} + +GooString *Stream::getPSFilter(int psLevel, char *indent) { + return new GooString(); +} + +Stream *Stream::addFilters(Object *dict) { + Object obj, obj2; + Object params, params2; + Stream *str; + int i; + + str = this; + dict->dictLookup("Filter", &obj); + if (obj.isNull()) { + obj.free(); + dict->dictLookup("F", &obj); + } + dict->dictLookup("DecodeParms", ¶ms); + if (params.isNull()) { + params.free(); + dict->dictLookup("DP", ¶ms); + } + if (obj.isName()) { + str = makeFilter(obj.getNameC(), str, ¶ms); + } else if (obj.isArray()) { + for (i = 0; i < obj.arrayGetLength(); ++i) { + obj.arrayGet(i, &obj2); + if (params.isArray()) + params.arrayGet(i, ¶ms2); + else + params2.initNull(); + if (obj2.isName()) { + str = makeFilter(obj2.getNameC(), str, ¶ms2); + } else { + error(getPos(), "Bad filter name"); + str = new EOFStream(str); + } + obj2.free(); + params2.free(); + } + } else if (!obj.isNull()) { + error(getPos(), "Bad 'Filter' attribute in stream"); + } + obj.free(); + params.free(); + + return str; +} + +Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { + int pred; // parameters + int colors; + int bits; + int early; + int encoding; + GBool endOfLine, byteAlign, endOfBlock, black; + int columns, rows; + Object globals, obj; + + if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) { + str = new ASCIIHexStream(str); + } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) { + str = new ASCII85Stream(str); + } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) { + pred = 1; + columns = 1; + colors = 1; + bits = 8; + early = 1; + if (params->isDict()) { + params->dictLookupInt("Predictor", NULL, &pred); + params->dictLookupInt("Columns", NULL, &columns); + params->dictLookupInt("Colors", NULL, &colors); + params->dictLookupInt("BitsPerComponent", NULL, &bits); + params->dictLookupInt("EarlyChange", NULL, &early); + } + str = new LZWStream(str, pred, columns, colors, bits, early); + } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) { + str = new RunLengthStream(str); + } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) { + encoding = 0; + endOfLine = gFalse; + byteAlign = gFalse; + columns = 1728; + rows = 0; + endOfBlock = gTrue; + black = gFalse; + if (params->isDict()) { + params->dictLookupInt("K", NULL, &encoding); + params->dictLookupBool("EndOfLine", NULL, &endOfLine); + params->dictLookupBool("EncodedByteAlign", NULL, &byteAlign); + params->dictLookupInt("Columns", NULL, &columns); + params->dictLookupInt("Rows", NULL, &rows); + params->dictLookupBool("EndOfBlock", NULL, &endOfBlock); + params->dictLookupBool("BlackIs1", NULL, &black); + } + str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign, + columns, rows, endOfBlock, black); + } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) { + str = new DCTStream(str); + } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) { + pred = 1; + columns = 1; + colors = 1; + bits = 8; + if (params->isDict()) { + params->dictLookupInt("Predictor", NULL, &pred); + params->dictLookupInt("Columns", NULL, &columns); + params->dictLookupInt("Colors", NULL, &colors); + params->dictLookupInt("BitsPerComponent", NULL, &bits); + } + str = new FlateStream(str, pred, columns, colors, bits); + } else if (!strcmp(name, "JBIG2Decode")) { + if (params->isDict()) { + params->dictLookup("JBIG2Globals", &globals); + } + str = new JBIG2Stream(str, &globals); + globals.free(); + } else if (!strcmp(name, "JPXDecode")) { + str = new JPXStream(str); + } else { + error(getPos(), "Unknown filter '%s'", name); + str = new EOFStream(str); + } + return str; +} + +//------------------------------------------------------------------------ +// BaseStream +//------------------------------------------------------------------------ + +BaseStream::BaseStream(Object *dictA) { + dict = *dictA; + decrypt = NULL; +} + +BaseStream::~BaseStream() { + dict.free(); + if (decrypt) + delete decrypt; +} + +void BaseStream::doDecryption(Guchar *fileKey, int keyLength, + int objNum, int objGen) { + decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); +} + +//------------------------------------------------------------------------ +// FilterStream +//------------------------------------------------------------------------ + +FilterStream::FilterStream(Stream *strA) { + str = strA; +} + +FilterStream::~FilterStream() { +} + +void FilterStream::close() { + str->close(); +} + +void FilterStream::setPos(Guint pos, int dir) { + error(-1, "Internal: called setPos() on FilterStream"); +} + +//------------------------------------------------------------------------ +// ImageStream +//------------------------------------------------------------------------ + +ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) { + int imgLineSize; + + str = strA; + width = widthA; + nComps = nCompsA; + nBits = nBitsA; + + nVals = width * nComps; + if (nBits == 1) { + imgLineSize = (nVals + 7) & ~7; + } else { + imgLineSize = nVals; + } + imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar)); + imgIdx = nVals; +} + +ImageStream::~ImageStream() { + gfree(imgLine); +} + +void ImageStream::reset() { + str->reset(); +} + +GBool ImageStream::getPixel(Guchar *pix) { + int i; + + if (imgIdx >= nVals) { + getLine(); + imgIdx = 0; + } + for (i = 0; i < nComps; ++i) { + pix[i] = imgLine[imgIdx++]; + } + return gTrue; +} + +Guchar *ImageStream::getLine() { + Gulong buf, bitMask; + int bits; + int c; + int i; + GBool hasData; + + if (nBits == 1) { + Guchar *tmpImgLine = imgLine; + if (str->hasGetBuf()) { + int leftBytes = nVals / 8; + if (nVals % 8 > 0) + ++leftBytes; + char *buf; + int bufSize; + while (leftBytes > 0) { + hasData = str->getBuf(&buf, &bufSize, leftBytes); + if (!hasData) + return imgLine; + leftBytes -= bufSize; + while (bufSize > 0) { + c = *(unsigned char*)buf; + ++buf; + bufSize--; + *tmpImgLine++ = (Guchar)((c >> 7) & 1); + *tmpImgLine++ = (Guchar)((c >> 6) & 1); + *tmpImgLine++ = (Guchar)((c >> 5) & 1); + *tmpImgLine++ = (Guchar)((c >> 4) & 1); + *tmpImgLine++ = (Guchar)((c >> 3) & 1); + *tmpImgLine++ = (Guchar)((c >> 2) & 1); + *tmpImgLine++ = (Guchar)((c >> 1) & 1); + *tmpImgLine++ = (Guchar)(c & 1); + } + } + } else { + Guchar *tmpImgLine = imgLine; + for (i = 0; i < nVals; i += 8) { + c = str->getChar(); + *tmpImgLine++ = (Guchar)((c >> 7) & 1); + *tmpImgLine++ = (Guchar)((c >> 6) & 1); + *tmpImgLine++ = (Guchar)((c >> 5) & 1); + *tmpImgLine++ = (Guchar)((c >> 4) & 1); + *tmpImgLine++ = (Guchar)((c >> 3) & 1); + *tmpImgLine++ = (Guchar)((c >> 2) & 1); + *tmpImgLine++ = (Guchar)((c >> 1) & 1); + *tmpImgLine++ = (Guchar)(c & 1); + } + } + } else if (nBits == 8) { + if (str->hasGetBuf()) { + int left = nVals; + char *buf; + int bufSize; + Guchar *tmpImgLine = imgLine; + while (left > 0) { + hasData = str->getBuf(&buf, &bufSize, left); + if (!hasData) + return imgLine; + left -= bufSize; + while (bufSize > 0) { + c = *(unsigned char*)buf; + ++buf; + bufSize--; + *tmpImgLine++ = c; + } + } + } else { + for (i = 0; i < nVals; ++i) { + imgLine[i] = str->getChar(); + } + } + } else { + bitMask = (1 << nBits) - 1; + buf = 0; + bits = 0; + for (i = 0; i < nVals; ++i) { + if (bits < nBits) { + buf = (buf << 8) | (str->getChar() & 0xff); + bits += 8; + } + imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask); + bits -= nBits; + } + } + return imgLine; +} + +void ImageStream::skipLine() { + int n, i; + + n = (nVals * nBits + 7) >> 3; + for (i = 0; i < n; ++i) { + str->getChar(); + } +} + +//------------------------------------------------------------------------ +// StreamPredictor +//------------------------------------------------------------------------ + +StreamPredictor::StreamPredictor(Stream *strA, int predictorA, + int widthA, int nCompsA, int nBitsA) { + int totalBits; + + str = strA; + predictor = predictorA; + width = widthA; + nComps = nCompsA; + nBits = nBitsA; + predLine = NULL; + ok = gFalse; + + nVals = width * nComps; + if (width <= 0 || nComps <= 0 || nBits <= 0 || + nComps >= INT_MAX/nBits || + width >= INT_MAX/nComps/nBits || + nVals * nBits + 7 < 0) { + return; + } + totalBits = nVals * nBits; + if (totalBits == 0 || + (totalBits / nBits) / nComps != width || + totalBits + 7 < 0) { + return; + } + pixBytes = (nComps * nBits + 7) >> 3; + rowBytes = ((totalBits + 7) >> 3) + pixBytes; + if (rowBytes < 0) { + return; + } + predLine = (Guchar *)gmalloc(rowBytes); + memset(predLine, 0, rowBytes); + predIdx = rowBytes; + + ok = gTrue; +} + +StreamPredictor::~StreamPredictor() { + gfree(predLine); +} + +int StreamPredictor::lookChar() { + if (predIdx >= rowBytes) { + if (!getNextLine()) { + return EOF; + } + } + return predLine[predIdx]; +} + +int StreamPredictor::getChar() { + if (predIdx >= rowBytes) { + if (!getNextLine()) { + return EOF; + } + } + return predLine[predIdx++]; +} + +GBool StreamPredictor::getNextLine() { + int curPred; + Guchar upLeftBuf[gfxColorMaxComps * 2 + 1]; + int left, up, upLeft, p, pa, pb, pc; + int c; + Gulong inBuf, outBuf, bitMask; + int inBits, outBits; + int i, j, k, kk; + + // get PNG optimum predictor number + if (predictor >= 10) { + if ((curPred = str->getRawChar()) == EOF) { + return gFalse; + } + curPred += 10; + } else { + curPred = predictor; + } + + // read the raw line, apply PNG (byte) predictor + memset(upLeftBuf, 0, pixBytes + 1); + for (i = pixBytes; i < rowBytes; ++i) { + for (j = pixBytes; j > 0; --j) { + upLeftBuf[j] = upLeftBuf[j-1]; + } + upLeftBuf[0] = predLine[i]; + if ((c = str->getRawChar()) == EOF) { + if (i > pixBytes) { + // this ought to return false, but some (broken) PDF files + // contain truncated image data, and Adobe apparently reads the + // last partial line + break; + } + return gFalse; + } + switch (curPred) { + case 11: // PNG sub + predLine[i] = predLine[i - pixBytes] + (Guchar)c; + break; + case 12: // PNG up + predLine[i] = predLine[i] + (Guchar)c; + break; + case 13: // PNG average + predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) + + (Guchar)c; + break; + case 14: // PNG Paeth + left = predLine[i - pixBytes]; + up = predLine[i]; + upLeft = upLeftBuf[pixBytes]; + p = left + up - upLeft; + if ((pa = p - left) < 0) + pa = -pa; + if ((pb = p - up) < 0) + pb = -pb; + if ((pc = p - upLeft) < 0) + pc = -pc; + if (pa <= pb && pa <= pc) + predLine[i] = left + (Guchar)c; + else if (pb <= pc) + predLine[i] = up + (Guchar)c; + else + predLine[i] = upLeft + (Guchar)c; + break; + case 10: // PNG none + default: // no predictor or TIFF predictor + predLine[i] = (Guchar)c; + break; + } + } + + // apply TIFF (component) predictor + if (predictor == 2) { + if (nBits == 1) { + inBuf = predLine[pixBytes - 1]; + for (i = pixBytes; i < rowBytes; i += 8) { + // 1-bit add is just xor + inBuf = (inBuf << 8) | predLine[i]; + predLine[i] ^= inBuf >> nComps; + } + } else if (nBits == 8) { + for (i = pixBytes; i < rowBytes; ++i) { + predLine[i] += predLine[i - nComps]; + } + } else { + memset(upLeftBuf, 0, nComps + 1); + bitMask = (1 << nBits) - 1; + inBuf = outBuf = 0; + inBits = outBits = 0; + j = k = pixBytes; + for (i = 0; i < width; ++i) { + for (kk = 0; kk < nComps; ++kk) { + if (inBits < nBits) { + inBuf = (inBuf << 8) | (predLine[j++] & 0xff); + inBits += 8; + } + upLeftBuf[kk] = (upLeftBuf[kk] + + (inBuf >> (inBits - nBits))) & bitMask; + inBits -= nBits; + outBuf = (outBuf << nBits) | upLeftBuf[kk]; + outBits += nBits; + if (outBits >= 8) { + predLine[k++] = (Guchar)(outBuf >> (outBits - 8)); + outBits -= 8; + } + } + } + if (outBits > 0) { + predLine[k++] = (Guchar)((outBuf << (8 - outBits)) + + (inBuf & ((1 << (8 - outBits)) - 1))); + } + } + } + + // reset to start of line + predIdx = pixBytes; + + return gTrue; +} + +//------------------------------------------------------------------------ +// FileStream +//------------------------------------------------------------------------ + +FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA, + Guint lengthA, Object *dictA): + BaseStream(dictA) { + f = fA; + start = startA; + limited = limitedA; + length = lengthA; + bufPtr = bufEnd = buf; + bufPos = start; + savePos = 0; + saved = gFalse; +} + +FileStream::~FileStream() { + close(); +} + +Stream *FileStream::makeSubStream(Guint startA, GBool limitedA, + Guint lengthA, Object *dictA) { + return new FileStream(f, startA, limitedA, lengthA, dictA); +} + +void FileStream::reset() { +#if HAVE_FSEEKO + savePos = (Guint)ftello(f); + fseeko(f, start, SEEK_SET); +#elif HAVE_FSEEK64 + savePos = (Guint)ftell64(f); + fseek64(f, start, SEEK_SET); +#else + savePos = (Guint)ftell(f); + fseek(f, start, SEEK_SET); +#endif + saved = gTrue; + bufPtr = bufEnd = buf; + bufPos = start; + if (decrypt) + decrypt->reset(); +} + +void FileStream::close() { + if (saved) { +#if HAVE_FSEEKO + fseeko(f, savePos, SEEK_SET); +#elif HAVE_FSEEK64 + fseek64(f, savePos, SEEK_SET); +#else + fseek(f, savePos, SEEK_SET); +#endif + saved = gFalse; + } +} + +GBool FileStream::fillBuf() { + int n; + char *p; + + bufPos += bufEnd - buf; + bufPtr = bufEnd = buf; + if (limited && bufPos >= start + length) { + return gFalse; + } + if (limited && bufPos + fileStreamBufSize > start + length) { + n = start + length - bufPos; + } else { + n = fileStreamBufSize; + } + n = fread(buf, 1, n, f); + bufEnd = buf + n; + if (bufPtr >= bufEnd) { + return gFalse; + } + if (decrypt) { + for (p = buf; p < bufEnd; ++p) { + *p = (char)decrypt->decryptByte((Guchar)*p); + } + } + return gTrue; +} + +void FileStream::setPos(Guint pos, int dir) { + Guint size; + + if (dir >= 0) { +#if HAVE_FSEEKO + fseeko(f, pos, SEEK_SET); +#elif HAVE_FSEEK64 + fseek64(f, pos, SEEK_SET); +#else + fseek(f, pos, SEEK_SET); +#endif + bufPos = pos; + } else { +#if HAVE_FSEEKO + fseeko(f, 0, SEEK_END); + size = (Guint)ftello(f); +#elif HAVE_FSEEK64 + fseek64(f, 0, SEEK_END); + size = (Guint)ftell64(f); +#else + fseek(f, 0, SEEK_END); + size = (Guint)ftell(f); +#endif + if (pos > size) + pos = (Guint)size; +#ifdef __CYGWIN32__ + //~ work around a bug in cygwin's implementation of fseek + rewind(f); +#endif +#if HAVE_FSEEKO + fseeko(f, -(int)pos, SEEK_END); + bufPos = (Guint)ftello(f); +#elif HAVE_FSEEK64 + fseek64(f, -(int)pos, SEEK_END); + bufPos = (Guint)ftell64(f); +#else + fseek(f, -(int)pos, SEEK_END); + bufPos = (Guint)ftell(f); +#endif + } + bufPtr = bufEnd = buf; +} + +void FileStream::moveStart(int delta) { + start += delta; + bufPtr = bufEnd = buf; + bufPos = start; +} + +GBool FileStream::hasGetBuf() { +#ifdef ENABLE_FILE_GET_BUF + return gTrue; +#else + return gFalse; +#endif +} + +GBool FileStream::getBuf(char **bufOut, int *bufSizeOut, int maxSize) +{ + int size; + if (bufPtr >= bufEnd) { + if (!fillBuf()) { + return gFalse; + } + } + assert(bufEnd > bufPtr); + size = bufEnd - bufPtr; + if (Stream::NO_SIZE_LIMIT != maxSize) { + assert(maxSize > 0); + if (size > maxSize) + size = maxSize; + } + *bufOut = bufPtr; + *bufSizeOut = size; + bufPtr += size; + return gTrue; +} + +void FileStream::ungetBuf(int sizeToGoBack) { + bufPtr -= sizeToGoBack; + assert(bufPtr >= buf); +} + +//------------------------------------------------------------------------ +// MemStream +//------------------------------------------------------------------------ + +MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA): + BaseStream(dictA) { + buf = bufA; + start = startA; + length = lengthA; + bufEnd = buf + start + length; + bufPtr = buf + start; + needFree = gFalse; +} + +MemStream::~MemStream() { + if (needFree) { + gfree(buf); + } +} + +Stream *MemStream::makeSubStream(Guint startA, GBool limited, + Guint lengthA, Object *dictA) { + MemStream *subStr; + Guint newLength; + + if (!limited || startA + lengthA > start + length) { + newLength = start + length - startA; + } else { + newLength = lengthA; + } + subStr = new MemStream(buf, startA, newLength, dictA); + return subStr; +} + +void MemStream::reset() { + bufPtr = buf + start; + if (decrypt) { + decrypt->reset(); + } +} + +void MemStream::close() { +} + +void MemStream::setPos(Guint pos, int dir) { + Guint i; + + if (dir >= 0) { + i = pos; + } else { + i = start + length - pos; + } + if (i < start) { + i = start; + } else if (i > start + length) { + i = start + length; + } + bufPtr = buf + i; +} + +void MemStream::moveStart(int delta) { + start += delta; + length -= delta; + bufPtr = buf + start; +} + +void MemStream::doDecryption(Guchar *fileKey, int keyLength, + int objNum, int objGen) { + char *newBuf; + char *p, *q; + + this->BaseStream::doDecryption(fileKey, keyLength, objNum, objGen); + if (decrypt) { + newBuf = (char *)gmalloc(length); + for (p = buf + start, q = newBuf; p < bufEnd; ++p, ++q) { + *q = (char)decrypt->decryptByte((Guchar)*p); + } + bufEnd = newBuf + length; + bufPtr = newBuf + (bufPtr - (buf + start)); + start = 0; + buf = newBuf; + needFree = gTrue; + } +} + +//------------------------------------------------------------------------ +// EmbedStream +//------------------------------------------------------------------------ + +EmbedStream::EmbedStream(Stream *strA, Object *dictA, + GBool limitedA, Guint lengthA): + BaseStream(dictA) { + str = strA; + limited = limitedA; + length = lengthA; +} + +EmbedStream::~EmbedStream() { +} + +Stream *EmbedStream::makeSubStream(Guint start, GBool limitedA, + Guint lengthA, Object *dictA) { + error(-1, "Internal: called makeSubStream() on EmbedStream"); + return NULL; +} + +GBool EmbedStream::hasGetBuf() { +#ifdef ENABLE_EMBED_GET_BUF + return str->hasGetBuf(); +#else + return gFalse; +#endif +} + +void EmbedStream::ungetBuf(int sizeToGoBack) { + str->ungetBuf(sizeToGoBack); + if (limited) { + length += sizeToGoBack; + } +} + +GBool EmbedStream::getBuf(char **bufOut, int *bufSizeOut, int maxSize) { + if (limited && (0 == length)) { + return gFalse; + } + + if (limited) { + if (Stream::NO_SIZE_LIMIT == maxSize) { + maxSize = length; + } else { + if (maxSize > (int)length) + maxSize = (int)length; + } + } + GBool hasData = str->getBuf(bufOut, bufSizeOut, maxSize); + if (!hasData) + return gFalse; + + if (limited) { + assert((int)length >= *bufSizeOut); + length -= *bufSizeOut; + } + assert(*bufSizeOut > 0); + return gTrue; +} + +int EmbedStream::getChar() { + if (limited) { + if (0 == length) { + return EOF; + } + --length; + } + return str->getChar(); +} + +int EmbedStream::lookChar() { + if (limited && !length) { + return EOF; + } + return str->lookChar(); +} + +void EmbedStream::setPos(Guint pos, int dir) { + error(-1, "Internal: called setPos() on EmbedStream"); +} + +Guint EmbedStream::getStart() { + error(-1, "Internal: called getStart() on EmbedStream"); + return 0; +} + +void EmbedStream::moveStart(int delta) { + error(-1, "Internal: called moveStart() on EmbedStream"); +} + +//------------------------------------------------------------------------ +// ASCIIHexStream +//------------------------------------------------------------------------ + +ASCIIHexStream::ASCIIHexStream(Stream *strA): + FilterStream(strA) { + buf = EOF; + eof = gFalse; +} + +ASCIIHexStream::~ASCIIHexStream() { + delete str; +} + +void ASCIIHexStream::reset() { + str->reset(); + buf = EOF; + eof = gFalse; +} + +int ASCIIHexStream::lookChar() { + int c1, c2, x; + + if (buf != EOF) + return buf; + if (eof) { + buf = EOF; + return EOF; + } + do { + c1 = str->getChar(); + } while (isspace(c1)); + if (c1 == '>') { + eof = gTrue; + buf = EOF; + return buf; + } + do { + c2 = str->getChar(); + } while (isspace(c2)); + if (c2 == '>') { + eof = gTrue; + c2 = '0'; + } + if (c1 >= '0' && c1 <= '9') { + x = (c1 - '0') << 4; + } else if (c1 >= 'A' && c1 <= 'F') { + x = (c1 - 'A' + 10) << 4; + } else if (c1 >= 'a' && c1 <= 'f') { + x = (c1 - 'a' + 10) << 4; + } else if (c1 == EOF) { + eof = gTrue; + x = 0; + } else { + error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1); + x = 0; + } + if (c2 >= '0' && c2 <= '9') { + x += c2 - '0'; + } else if (c2 >= 'A' && c2 <= 'F') { + x += c2 - 'A' + 10; + } else if (c2 >= 'a' && c2 <= 'f') { + x += c2 - 'a' + 10; + } else if (c2 == EOF) { + eof = gTrue; + x = 0; + } else { + error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2); + } + buf = x & 0xff; + return buf; +} + +GooString *ASCIIHexStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 2) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("/ASCIIHexDecode filter\n"); + return s; +} + +GBool ASCIIHexStream::isBinary(GBool last) { + return str->isBinary(gFalse); +} + +//------------------------------------------------------------------------ +// ASCII85Stream +//------------------------------------------------------------------------ + +ASCII85Stream::ASCII85Stream(Stream *strA): + FilterStream(strA) { + index = n = 0; + eof = gFalse; +} + +ASCII85Stream::~ASCII85Stream() { + delete str; +} + +void ASCII85Stream::reset() { + str->reset(); + index = n = 0; + eof = gFalse; +} + +int ASCII85Stream::lookChar() { + int k; + Gulong t; + + if (index >= n) { + if (eof) + return EOF; + index = 0; + do { + c[0] = str->getChar(); + } while (Lexer::isSpace(c[0])); + if (c[0] == '~' || c[0] == EOF) { + eof = gTrue; + n = 0; + return EOF; + } else if (c[0] == 'z') { + b[0] = b[1] = b[2] = b[3] = 0; + n = 4; + } else { + for (k = 1; k < 5; ++k) { + do { + c[k] = str->getChar(); + } while (Lexer::isSpace(c[k])); + if (c[k] == '~' || c[k] == EOF) + break; + } + n = k - 1; + if (k < 5 && (c[k] == '~' || c[k] == EOF)) { + for (++k; k < 5; ++k) + c[k] = 0x21 + 84; + eof = gTrue; + } + t = 0; + for (k = 0; k < 5; ++k) + t = t * 85 + (c[k] - 0x21); + for (k = 3; k >= 0; --k) { + b[k] = (int)(t & 0xff); + t >>= 8; + } + } + } + return b[index]; +} + +GooString *ASCII85Stream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 2) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("/ASCII85Decode filter\n"); + return s; +} + +GBool ASCII85Stream::isBinary(GBool last) { + return str->isBinary(gFalse); +} + +//------------------------------------------------------------------------ +// LZWStream +//------------------------------------------------------------------------ + +LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors, + int bits, int earlyA): + FilterStream(strA) { + if (predictor != 1) { + pred = new StreamPredictor(this, predictor, columns, colors, bits); + if (!pred->isOk()) { + delete pred; + pred = NULL; + } + } else { + pred = NULL; + } + early = earlyA; + eof = gFalse; + inputBits = 0; + clearTable(); +} + +LZWStream::~LZWStream() { + if (pred) { + delete pred; + } + delete str; +} + +int LZWStream::getChar() { + if (pred) { + return pred->getChar(); + } + if (eof) { + return EOF; + } + if (seqIndex >= seqLength) { + if (!processNextCode()) { + return EOF; + } + } + return seqBuf[seqIndex++]; +} + +int LZWStream::lookChar() { + if (pred) { + return pred->lookChar(); + } + if (eof) { + return EOF; + } + if (seqIndex >= seqLength) { + if (!processNextCode()) { + return EOF; + } + } + return seqBuf[seqIndex]; +} + +int LZWStream::getRawChar() { + if (eof) { + return EOF; + } + if (seqIndex >= seqLength) { + if (!processNextCode()) { + return EOF; + } + } + return seqBuf[seqIndex++]; +} + +void LZWStream::reset() { + str->reset(); + eof = gFalse; + inputBits = 0; + clearTable(); +} + +GBool LZWStream::processNextCode() { + int code; + int nextLength; + int i, j; + + // check for EOF + if (eof) { + return gFalse; + } + + // check for eod and clear-table codes + start: + code = getCode(); + if (code == EOF || code == 257) { + eof = gTrue; + return gFalse; + } + if (code == 256) { + clearTable(); + goto start; + } + if (nextCode >= 4097) { + error(getPos(), "Bad LZW stream - expected clear-table code"); + clearTable(); + } + + // process the next code + nextLength = seqLength + 1; + if (code < 256) { + seqBuf[0] = code; + seqLength = 1; + } else if (code < nextCode) { + seqLength = table[code].length; + for (i = seqLength - 1, j = code; i > 0; --i) { + seqBuf[i] = table[j].tail; + j = table[j].head; + } + seqBuf[0] = j; + } else if (code == nextCode) { + seqBuf[seqLength] = newChar; + ++seqLength; + } else { + error(getPos(), "Bad LZW stream - unexpected code"); + eof = gTrue; + return gFalse; + } + newChar = seqBuf[0]; + if (first) { + first = gFalse; + } else { + table[nextCode].length = nextLength; + table[nextCode].head = prevCode; + table[nextCode].tail = newChar; + ++nextCode; + if (nextCode + early == 512) + nextBits = 10; + else if (nextCode + early == 1024) + nextBits = 11; + else if (nextCode + early == 2048) + nextBits = 12; + } + prevCode = code; + + // reset buffer + seqIndex = 0; + + return gTrue; +} + +void LZWStream::clearTable() { + nextCode = 258; + nextBits = 9; + seqIndex = seqLength = 0; + first = gTrue; +} + +int LZWStream::getCode() { + int c; + int code; + + while (inputBits < nextBits) { + if ((c = str->getChar()) == EOF) + return EOF; + inputBuf = (inputBuf << 8) | (c & 0xff); + inputBits += 8; + } + code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1); + inputBits -= nextBits; + return code; +} + +GooString *LZWStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 2 || pred) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("<< "); + if (!early) { + s->append("/EarlyChange 0 "); + } + s->append(">> /LZWDecode filter\n"); + return s; +} + +GBool LZWStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +//------------------------------------------------------------------------ +// RunLengthStream +//------------------------------------------------------------------------ + +RunLengthStream::RunLengthStream(Stream *strA): + FilterStream(strA) { + bufPtr = bufEnd = buf; + eof = gFalse; +} + +RunLengthStream::~RunLengthStream() { + delete str; +} + +void RunLengthStream::reset() { + str->reset(); + bufPtr = bufEnd = buf; + eof = gFalse; +} + +GooString *RunLengthStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 2) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("/RunLengthDecode filter\n"); + return s; +} + +GBool RunLengthStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +GBool RunLengthStream::fillBuf() { + int c; + int n, i; + + if (eof) + return gFalse; + c = str->getChar(); + if (c == 0x80 || c == EOF) { + eof = gTrue; + return gFalse; + } + if (c < 0x80) { + n = c + 1; + for (i = 0; i < n; ++i) + buf[i] = (char)str->getChar(); + } else { + n = 0x101 - c; + c = str->getChar(); + for (i = 0; i < n; ++i) + buf[i] = (char)c; + } + bufPtr = buf; + bufEnd = buf + n; + return gTrue; +} + +//------------------------------------------------------------------------ +// CCITTFaxStream +//------------------------------------------------------------------------ + +CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, + GBool byteAlignA, int columnsA, int rowsA, + GBool endOfBlockA, GBool blackA): + FilterStream(strA) { + encoding = encodingA; + endOfLine = endOfLineA; + byteAlign = byteAlignA; + columns = columnsA; + if (columns + 3 < 1 || columns + 4 < 1 || columns < 1) { + columns = 1; + } + rows = rowsA; + endOfBlock = endOfBlockA; + black = blackA; + refLine = (short *)gmallocn(columns + 4, sizeof(short)); + codingLine = (short *)gmallocn(columns + 3, sizeof(short)); + + eof = gFalse; + row = 0; + nextLine2D = encoding < 0; + inputBits = 0; + codingLine[0] = 0; + codingLine[1] = refLine[2] = columns; + a0 = 1; + + buf = EOF; +} + +CCITTFaxStream::~CCITTFaxStream() { + delete str; + gfree(refLine); + gfree(codingLine); +} + +void CCITTFaxStream::reset() { + short code1; + + str->reset(); + eof = gFalse; + row = 0; + nextLine2D = encoding < 0; + inputBits = 0; + codingLine[0] = 0; + codingLine[1] = refLine[2] = columns; + a0 = 1; + buf = EOF; + + // skip any initial zero bits and end-of-line marker, and get the 2D + // encoding tag + while ((code1 = lookBits(12)) == 0) { + eatBits(1); + } + if (code1 == 0x001) { + eatBits(12); + } + if (encoding > 0) { + nextLine2D = !lookBits(1); + eatBits(1); + } +} + +int CCITTFaxStream::lookChar() { + short code1, code2, code3; + int a0New; + GBool err, gotEOL; + int ret; + int bits, i; + + // if at eof just return EOF + if (eof && codingLine[a0] >= columns) { + return EOF; + } + + // read the next row + err = gFalse; + if (codingLine[a0] >= columns) { + + // 2-D encoding + if (nextLine2D) { + for (i = 0; codingLine[i] < columns; ++i) + refLine[i] = codingLine[i]; + refLine[i] = refLine[i + 1] = columns; + b1 = 1; + a0New = codingLine[a0 = 0] = 0; + do { + code1 = getTwoDimCode(); + switch (code1) { + case twoDimPass: + if (refLine[b1] < columns) { + a0New = refLine[b1 + 1]; + b1 += 2; + } + break; + case twoDimHoriz: + if ((a0 & 1) == 0) { + code1 = code2 = 0; + do { + code1 += code3 = getWhiteCode(); + } while (code3 >= 64); + do { + code2 += code3 = getBlackCode(); + } while (code3 >= 64); + } else { + code1 = code2 = 0; + do { + code1 += code3 = getBlackCode(); + } while (code3 >= 64); + do { + code2 += code3 = getWhiteCode(); + } while (code3 >= 64); + } + if (code1 > 0 || code2 > 0) { + codingLine[a0 + 1] = a0New + code1; + ++a0; + a0New = codingLine[a0 + 1] = codingLine[a0] + code2; + ++a0; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVert0: + a0New = codingLine[++a0] = refLine[b1]; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertR1: + a0New = codingLine[++a0] = refLine[b1] + 1; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL1: + if (a0 == 0 || refLine[b1] - 1 > a0New) { + a0New = codingLine[++a0] = refLine[b1] - 1; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertR2: + a0New = codingLine[++a0] = refLine[b1] + 2; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL2: + if (a0 == 0 || refLine[b1] - 2 > a0New) { + a0New = codingLine[++a0] = refLine[b1] - 2; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertR3: + a0New = codingLine[++a0] = refLine[b1] + 3; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL3: + if (a0 == 0 || refLine[b1] - 3 > a0New) { + a0New = codingLine[++a0] = refLine[b1] - 3; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case EOF: + eof = gTrue; + codingLine[a0 = 0] = columns; + return EOF; + default: + error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1); + err = gTrue; + break; + } + } while (codingLine[a0] < columns); + + // 1-D encoding + } else { + codingLine[a0 = 0] = 0; + while (1) { + code1 = 0; + do { + code1 += code3 = getWhiteCode(); + } while (code3 >= 64); + codingLine[a0+1] = codingLine[a0] + code1; + ++a0; + if (codingLine[a0] >= columns) + break; + code2 = 0; + do { + code2 += code3 = getBlackCode(); + } while (code3 >= 64); + codingLine[a0+1] = codingLine[a0] + code2; + ++a0; + if (codingLine[a0] >= columns) + break; + } + } + + if (codingLine[a0] != columns) { + error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]); + // force the row to be the correct length + while (codingLine[a0] > columns) { + --a0; + } + codingLine[++a0] = columns; + err = gTrue; + } + + // byte-align the row + if (byteAlign) { + inputBits &= ~7; + } + + // check for end-of-line marker, skipping over any extra zero bits + gotEOL = gFalse; + if (!endOfBlock && row == rows - 1) { + eof = gTrue; + } else { + code1 = lookBits(12); + while (code1 == 0) { + eatBits(1); + code1 = lookBits(12); + } + if (code1 == 0x001) { + eatBits(12); + gotEOL = gTrue; + } else if (code1 == EOF) { + eof = gTrue; + } + } + + // get 2D encoding tag + if (!eof && encoding > 0) { + nextLine2D = !lookBits(1); + eatBits(1); + } + + // check for end-of-block marker + if (endOfBlock && gotEOL) { + code1 = lookBits(12); + if (code1 == 0x001) { + eatBits(12); + if (encoding > 0) { + lookBits(1); + eatBits(1); + } + if (encoding >= 0) { + for (i = 0; i < 4; ++i) { + code1 = lookBits(12); + if (code1 != 0x001) { + error(getPos(), "Bad RTC code in CCITTFax stream"); + } + eatBits(12); + if (encoding > 0) { + lookBits(1); + eatBits(1); + } + } + } + eof = gTrue; + } + + // look for an end-of-line marker after an error -- we only do + // this if we know the stream contains end-of-line markers because + // the "just plow on" technique tends to work better otherwise + } else if (err && endOfLine) { + do { + if (code1 == EOF) { + eof = gTrue; + return EOF; + } + eatBits(1); + code1 = lookBits(13); + } while ((code1 >> 1) != 0x001); + eatBits(12); + if (encoding > 0) { + eatBits(1); + nextLine2D = !(code1 & 1); + } + } + + a0 = 0; + outputBits = codingLine[1] - codingLine[0]; + if (outputBits == 0) { + a0 = 1; + outputBits = codingLine[2] - codingLine[1]; + } + + ++row; + } + + // get a byte + if (outputBits >= 8) { + ret = ((a0 & 1) == 0) ? 0xff : 0x00; + if ((outputBits -= 8) == 0) { + ++a0; + if (codingLine[a0] < columns) { + outputBits = codingLine[a0 + 1] - codingLine[a0]; + } + } + } else { + bits = 8; + ret = 0; + do { + if (outputBits > bits) { + i = bits; + bits = 0; + if ((a0 & 1) == 0) { + ret |= 0xff >> (8 - i); + } + outputBits -= i; + } else { + i = outputBits; + bits -= outputBits; + if ((a0 & 1) == 0) { + ret |= (0xff >> (8 - i)) << bits; + } + outputBits = 0; + ++a0; + if (codingLine[a0] < columns) { + outputBits = codingLine[a0 + 1] - codingLine[a0]; + } + } + } while (bits > 0 && codingLine[a0] < columns); + } + buf = black ? (ret ^ 0xff) : ret; + return buf; +} + +short CCITTFaxStream::getTwoDimCode() { + short code; + CCITTCode *p; + int n; + + code = 0; // make gcc happy + if (endOfBlock) { + code = lookBits(7); + p = &twoDimTab1[code]; + if (p->bits > 0) { + eatBits(p->bits); + return p->n; + } + } else { + for (n = 1; n <= 7; ++n) { + code = lookBits(n); + if (n < 7) { + code <<= 7 - n; + } + p = &twoDimTab1[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code); + return EOF; +} + +short CCITTFaxStream::getWhiteCode() { + short code; + CCITTCode *p; + int n; + + code = 0; // make gcc happy + if (endOfBlock) { + code = lookBits(12); + if ((code >> 5) == 0) { + p = &whiteTab1[code]; + } else { + p = &whiteTab2[code >> 3]; + } + if (p->bits > 0) { + eatBits(p->bits); + return p->n; + } + } else { + for (n = 1; n <= 9; ++n) { + code = lookBits(n); + if (n < 9) { + code <<= 9 - n; + } + p = &whiteTab2[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + for (n = 11; n <= 12; ++n) { + code = lookBits(n); + if (n < 12) { + code <<= 12 - n; + } + p = &whiteTab1[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + error(getPos(), "Bad white code (%04x) in CCITTFax stream", code); + // eat a bit and return a positive number so that the caller doesn't + // go into an infinite loop + eatBits(1); + return 1; +} + +short CCITTFaxStream::getBlackCode() { + short code; + CCITTCode *p; + int n; + + code = 0; // make gcc happy + if (endOfBlock) { + code = lookBits(13); + if ((code >> 7) == 0) { + p = &blackTab1[code]; + } else if ((code >> 9) == 0) { + p = &blackTab2[(code >> 1) - 64]; + } else { + p = &blackTab3[code >> 7]; + } + if (p->bits > 0) { + eatBits(p->bits); + return p->n; + } + } else { + for (n = 2; n <= 6; ++n) { + code = lookBits(n); + if (n < 6) { + code <<= 6 - n; + } + p = &blackTab3[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + for (n = 7; n <= 12; ++n) { + code = lookBits(n); + if (n < 12) { + code <<= 12 - n; + } + if (code >= 64) { + p = &blackTab2[code - 64]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + for (n = 10; n <= 13; ++n) { + code = lookBits(n); + if (n < 13) { + code <<= 13 - n; + } + p = &blackTab1[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + error(getPos(), "Bad black code (%04x) in CCITTFax stream", code); + // eat a bit and return a positive number so that the caller doesn't + // go into an infinite loop + eatBits(1); + return 1; +} + +short CCITTFaxStream::lookBits(int n) { + int c; + + while (inputBits < n) { + if ((c = str->getChar()) == EOF) { + if (inputBits == 0) { + return EOF; + } + // near the end of the stream, the caller may ask for more bits + // than are available, but there may still be a valid code in + // however many bits are available -- we need to return correct + // data in this case + return (inputBuf << (n - inputBits)) & (0xffff >> (16 - n)); + } + inputBuf = (inputBuf << 8) + c; + inputBits += 8; + } + return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n)); +} + +GooString *CCITTFaxStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + char s1[50]; + + if (psLevel < 2) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("<< "); + if (encoding != 0) { + sprintf(s1, "/K %d ", encoding); + s->append(s1); + } + if (endOfLine) { + s->append("/EndOfLine true "); + } + if (byteAlign) { + s->append("/EncodedByteAlign true "); + } + sprintf(s1, "/Columns %d ", columns); + s->append(s1); + if (rows != 0) { + sprintf(s1, "/Rows %d ", rows); + s->append(s1); + } + if (!endOfBlock) { + s->append("/EndOfBlock false "); + } + if (black) { + s->append("/BlackIs1 true "); + } + s->append(">> /CCITTFaxDecode filter\n"); + return s; +} + +GBool CCITTFaxStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +#ifndef ENABLE_LIBJPEG + +//------------------------------------------------------------------------ +// DCTStream +//------------------------------------------------------------------------ + +// IDCT constants (20.12 fixed point format) +#define dctCos1 4017 // cos(pi/16) +#define dctSin1 799 // sin(pi/16) +#define dctCos3 3406 // cos(3*pi/16) +#define dctSin3 2276 // sin(3*pi/16) +#define dctCos6 1567 // cos(6*pi/16) +#define dctSin6 3784 // sin(6*pi/16) +#define dctSqrt2 5793 // sqrt(2) +#define dctSqrt1d2 2896 // sqrt(2) / 2 + +// color conversion parameters (16.16 fixed point format) +#define dctCrToR 91881 // 1.4020 +#define dctCbToG -22553 // -0.3441363 +#define dctCrToG -46802 // -0.71413636 +#define dctCbToB 116130 // 1.772 + +// clip [-256,511] --> [0,255] +#define dctClipOffset 256 +static Guchar dctClip[768]; +static int dctClipInit = 0; + +// zig zag decode map +static int dctZigZag[64] = { + 0, + 1, 8, + 16, 9, 2, + 3, 10, 17, 24, + 32, 25, 18, 11, 4, + 5, 12, 19, 26, 33, 40, + 48, 41, 34, 27, 20, 13, 6, + 7, 14, 21, 28, 35, 42, 49, 56, + 57, 50, 43, 36, 29, 22, 15, + 23, 30, 37, 44, 51, 58, + 59, 52, 45, 38, 31, + 39, 46, 53, 60, + 61, 54, 47, + 55, 62, + 63 +}; + +DCTStream::DCTStream(Stream *strA): + FilterStream(strA) { + int i, j; + + progressive = interleaved = gFalse; + width = height = 0; + mcuWidth = mcuHeight = 0; + numComps = 0; + comp = 0; + x = y = dy = 0; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 32; ++j) { + rowBuf[i][j] = NULL; + } + frameBuf[i] = NULL; + } + + if (!dctClipInit) { + for (i = -256; i < 0; ++i) + dctClip[dctClipOffset + i] = 0; + for (i = 0; i < 256; ++i) + dctClip[dctClipOffset + i] = i; + for (i = 256; i < 512; ++i) + dctClip[dctClipOffset + i] = 255; + dctClipInit = 1; + } +} + +DCTStream::~DCTStream() { + int i, j; + + delete str; + if (progressive || !interleaved) { + for (i = 0; i < numComps; ++i) { + gfree(frameBuf[i]); + } + } else { + for (i = 0; i < numComps; ++i) { + for (j = 0; j < mcuHeight; ++j) { + gfree(rowBuf[i][j]); + } + } + } +} + +void DCTStream::reset() { + int i, j; + + str->reset(); + + progressive = interleaved = gFalse; + width = height = 0; + numComps = 0; + numQuantTables = 0; + numDCHuffTables = 0; + numACHuffTables = 0; + colorXform = 0; + gotJFIFMarker = gFalse; + gotAdobeMarker = gFalse; + restartInterval = 0; + + if (!readHeader()) { + y = height; + return; + } + + // compute MCU size + if (numComps == 1) { + compInfo[0].hSample = compInfo[0].vSample = 1; + } + mcuWidth = compInfo[0].hSample; + mcuHeight = compInfo[0].vSample; + for (i = 1; i < numComps; ++i) { + if (compInfo[i].hSample > mcuWidth) { + mcuWidth = compInfo[i].hSample; + } + if (compInfo[i].vSample > mcuHeight) { + mcuHeight = compInfo[i].vSample; + } + } + mcuWidth *= 8; + mcuHeight *= 8; + + // figure out color transform + if (!gotAdobeMarker && numComps == 3) { + if (gotJFIFMarker) { + colorXform = 1; + } else if (compInfo[0].id == 82 && compInfo[1].id == 71 && + compInfo[2].id == 66) { // ASCII "RGB" + colorXform = 0; + } else { + colorXform = 1; + } + } + + if (progressive || !interleaved) { + + // allocate a buffer for the whole image + bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth; + bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight; + for (i = 0; i < numComps; ++i) { + frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int)); + memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int)); + } + + // read the image data + do { + restartMarker = 0xd0; + restart(); + readScan(); + } while (readHeader()); + + // decode + decodeImage(); + + // initialize counters + comp = 0; + x = 0; + y = 0; + + } else { + + // allocate a buffer for one row of MCUs + bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth; + for (i = 0; i < numComps; ++i) { + for (j = 0; j < mcuHeight; ++j) { + rowBuf[i][j] = (Guchar *)gmallocn(bufWidth, sizeof(Guchar)); + } + } + + // initialize counters + comp = 0; + x = 0; + y = 0; + dy = mcuHeight; + + restartMarker = 0xd0; + restart(); + } +} + +int DCTStream::getChar() { + int c; + + if (y >= height) { + return EOF; + } + if (progressive || !interleaved) { + c = frameBuf[comp][y * bufWidth + x]; + if (++comp == numComps) { + comp = 0; + if (++x == width) { + x = 0; + ++y; + } + } + } else { + if (dy >= mcuHeight) { + if (!readMCURow()) { + y = height; + return EOF; + } + comp = 0; + x = 0; + dy = 0; + } + c = rowBuf[comp][dy][x]; + if (++comp == numComps) { + comp = 0; + if (++x == width) { + x = 0; + ++y; + ++dy; + if (y == height) { + readTrailer(); + } + } + } + } + return c; +} + +int DCTStream::lookChar() { + if (y >= height) { + return EOF; + } + if (progressive || !interleaved) { + return frameBuf[comp][y * bufWidth + x]; + } else { + if (dy >= mcuHeight) { + if (!readMCURow()) { + y = height; + return EOF; + } + comp = 0; + x = 0; + dy = 0; + } + return rowBuf[comp][dy][x]; + } +} + +void DCTStream::restart() { + int i; + + inputBits = 0; + restartCtr = restartInterval; + for (i = 0; i < numComps; ++i) { + compInfo[i].prevDC = 0; + } + eobRun = 0; +} + +// Read one row of MCUs from a sequential JPEG stream. +GBool DCTStream::readMCURow() { + int data1[64]; + Guchar data2[64]; + Guchar *p1, *p2; + int pY, pCb, pCr, pR, pG, pB; + int h, v, horiz, vert, hSub, vSub; + int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i; + int c; + + for (x1 = 0; x1 < width; x1 += mcuWidth) { + + // deal with restart marker + if (restartInterval > 0 && restartCtr == 0) { + c = readMarker(); + if (c != restartMarker) { + error(getPos(), "Bad DCT data: incorrect restart marker"); + return gFalse; + } + if (++restartMarker == 0xd8) + restartMarker = 0xd0; + restart(); + } + + // read one MCU + for (cc = 0; cc < numComps; ++cc) { + h = compInfo[cc].hSample; + v = compInfo[cc].vSample; + horiz = mcuWidth / h; + vert = mcuHeight / v; + hSub = horiz / 8; + vSub = vert / 8; + for (y2 = 0; y2 < mcuHeight; y2 += vert) { + for (x2 = 0; x2 < mcuWidth; x2 += horiz) { + if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]], + &acHuffTables[scanInfo.acHuffTable[cc]], + &compInfo[cc].prevDC, + data1)) { + return gFalse; + } + transformDataUnit(quantTables[compInfo[cc].quantTable], + data1, data2); + if (hSub == 1 && vSub == 1) { + for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) { + p1 = &rowBuf[cc][y2+y3][x1+x2]; + p1[0] = data2[i]; + p1[1] = data2[i+1]; + p1[2] = data2[i+2]; + p1[3] = data2[i+3]; + p1[4] = data2[i+4]; + p1[5] = data2[i+5]; + p1[6] = data2[i+6]; + p1[7] = data2[i+7]; + } + } else if (hSub == 2 && vSub == 2) { + for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) { + p1 = &rowBuf[cc][y2+y3][x1+x2]; + p2 = &rowBuf[cc][y2+y3+1][x1+x2]; + p1[0] = p1[1] = p2[0] = p2[1] = data2[i]; + p1[2] = p1[3] = p2[2] = p2[3] = data2[i+1]; + p1[4] = p1[5] = p2[4] = p2[5] = data2[i+2]; + p1[6] = p1[7] = p2[6] = p2[7] = data2[i+3]; + p1[8] = p1[9] = p2[8] = p2[9] = data2[i+4]; + p1[10] = p1[11] = p2[10] = p2[11] = data2[i+5]; + p1[12] = p1[13] = p2[12] = p2[13] = data2[i+6]; + p1[14] = p1[15] = p2[14] = p2[15] = data2[i+7]; + } + } else { + i = 0; + for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) { + for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) { + for (y5 = 0; y5 < vSub; ++y5) + for (x5 = 0; x5 < hSub; ++x5) + rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data2[i]; + ++i; + } + } + } + } + } + } + --restartCtr; + + // color space conversion + if (colorXform) { + // convert YCbCr to RGB + if (numComps == 3) { + for (y2 = 0; y2 < mcuHeight; ++y2) { + for (x2 = 0; x2 < mcuWidth; ++x2) { + pY = rowBuf[0][y2][x1+x2]; + pCb = rowBuf[1][y2][x1+x2] - 128; + pCr = rowBuf[2][y2][x1+x2] - 128; + pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16; + rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR]; + pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16; + rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG]; + pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16; + rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB]; + } + } + // convert YCbCrK to CMYK (K is passed through unchanged) + } else if (numComps == 4) { + for (y2 = 0; y2 < mcuHeight; ++y2) { + for (x2 = 0; x2 < mcuWidth; ++x2) { + pY = rowBuf[0][y2][x1+x2]; + pCb = rowBuf[1][y2][x1+x2] - 128; + pCr = rowBuf[2][y2][x1+x2] - 128; + pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16; + rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR]; + pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16; + rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG]; + pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16; + rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB]; + } + } + } + } + } + return gTrue; +} + +// Read one scan from a progressive or non-interleaved JPEG stream. +void DCTStream::readScan() { + int data[64]; + int x1, y1, dx1, dy1, x2, y2, y3, cc, i; + int h, v, horiz, vert, vSub; + int *p1; + int c; + + if (scanInfo.numComps == 1) { + for (cc = 0; cc < numComps; ++cc) { + if (scanInfo.comp[cc]) { + break; + } + } + dx1 = mcuWidth / compInfo[cc].hSample; + dy1 = mcuHeight / compInfo[cc].vSample; + } else { + dx1 = mcuWidth; + dy1 = mcuHeight; + } + + for (y1 = 0; y1 < height; y1 += dy1) { + for (x1 = 0; x1 < width; x1 += dx1) { + + // deal with restart marker + if (restartInterval > 0 && restartCtr == 0) { + c = readMarker(); + if (c != restartMarker) { + error(getPos(), "Bad DCT data: incorrect restart marker"); + return; + } + if (++restartMarker == 0xd8) { + restartMarker = 0xd0; + } + restart(); + } + + // read one MCU + for (cc = 0; cc < numComps; ++cc) { + if (!scanInfo.comp[cc]) { + continue; + } + + h = compInfo[cc].hSample; + v = compInfo[cc].vSample; + horiz = mcuWidth / h; + vert = mcuHeight / v; + vSub = vert / 8; + for (y2 = 0; y2 < dy1; y2 += vert) { + for (x2 = 0; x2 < dx1; x2 += horiz) { + + // pull out the current values + p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)]; + for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) { + data[i] = p1[0]; + data[i+1] = p1[1]; + data[i+2] = p1[2]; + data[i+3] = p1[3]; + data[i+4] = p1[4]; + data[i+5] = p1[5]; + data[i+6] = p1[6]; + data[i+7] = p1[7]; + p1 += bufWidth * vSub; + } + + // read one data unit + if (progressive) { + if (!readProgressiveDataUnit( + &dcHuffTables[scanInfo.dcHuffTable[cc]], + &acHuffTables[scanInfo.acHuffTable[cc]], + &compInfo[cc].prevDC, + data)) { + return; + } + } else { + if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]], + &acHuffTables[scanInfo.acHuffTable[cc]], + &compInfo[cc].prevDC, + data)) { + return; + } + } + + // add the data unit into frameBuf + p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)]; + for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) { + p1[0] = data[i]; + p1[1] = data[i+1]; + p1[2] = data[i+2]; + p1[3] = data[i+3]; + p1[4] = data[i+4]; + p1[5] = data[i+5]; + p1[6] = data[i+6]; + p1[7] = data[i+7]; + p1 += bufWidth * vSub; + } + } + } + } + --restartCtr; + } + } +} + +// Read one data unit from a sequential JPEG stream. +GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]) { + int run, size, amp; + int c; + int i, j; + + if ((size = readHuffSym(dcHuffTable)) == 9999) { + return gFalse; + } + if (size > 0) { + if ((amp = readAmp(size)) == 9999) { + return gFalse; + } + } else { + amp = 0; + } + data[0] = *prevDC += amp; + for (i = 1; i < 64; ++i) { + data[i] = 0; + } + i = 1; + while (i < 64) { + run = 0; + while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) { + run += 0x10; + } + if (c == 9999) { + return gFalse; + } + if (c == 0x00) { + break; + } else { + run += (c >> 4) & 0x0f; + size = c & 0x0f; + amp = readAmp(size); + if (amp == 9999) { + return gFalse; + } + i += run; + if (i < 64) { + j = dctZigZag[i++]; + data[j] = amp; + } + } + } + return gTrue; +} + +// Read one data unit from a sequential JPEG stream. +GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]) { + int run, size, amp, bit, c; + int i, j, k; + + // get the DC coefficient + i = scanInfo.firstCoeff; + if (i == 0) { + if (scanInfo.ah == 0) { + if ((size = readHuffSym(dcHuffTable)) == 9999) { + return gFalse; + } + if (size > 0) { + if ((amp = readAmp(size)) == 9999) { + return gFalse; + } + } else { + amp = 0; + } + data[0] += (*prevDC += amp) << scanInfo.al; + } else { + if ((bit = readBit()) == 9999) { + return gFalse; + } + data[0] += bit << scanInfo.al; + } + ++i; + } + if (scanInfo.lastCoeff == 0) { + return gTrue; + } + + // check for an EOB run + if (eobRun > 0) { + while (i <= scanInfo.lastCoeff) { + j = dctZigZag[i++]; + if (data[j] != 0) { + if ((bit = readBit()) == EOF) { + return gFalse; + } + if (bit) { + data[j] += 1 << scanInfo.al; + } + } + } + --eobRun; + return gTrue; + } + + // read the AC coefficients + while (i <= scanInfo.lastCoeff) { + if ((c = readHuffSym(acHuffTable)) == 9999) { + return gFalse; + } + + // ZRL + if (c == 0xf0) { + k = 0; + while (k < 16) { + j = dctZigZag[i++]; + if (data[j] == 0) { + ++k; + } else { + if ((bit = readBit()) == EOF) { + return gFalse; + } + if (bit) { + data[j] += 1 << scanInfo.al; + } + } + } + + // EOB run + } else if ((c & 0x0f) == 0x00) { + j = c >> 4; + eobRun = 0; + for (k = 0; k < j; ++k) { + if ((bit = readBit()) == EOF) { + return gFalse; + } + eobRun = (eobRun << 1) | bit; + } + eobRun += 1 << j; + while (i <= scanInfo.lastCoeff) { + j = dctZigZag[i++]; + if (data[j] != 0) { + if ((bit = readBit()) == EOF) { + return gFalse; + } + if (bit) { + data[j] += 1 << scanInfo.al; + } + } + } + --eobRun; + break; + + // zero run and one AC coefficient + } else { + run = (c >> 4) & 0x0f; + size = c & 0x0f; + if ((amp = readAmp(size)) == 9999) { + return gFalse; + } + k = 0; + do { + j = dctZigZag[i++]; + while (data[j] != 0) { + if ((bit = readBit()) == EOF) { + return gFalse; + } + if (bit) { + data[j] += 1 << scanInfo.al; + } + j = dctZigZag[i++]; + } + ++k; + } while (k <= run); + data[j] = amp << scanInfo.al; + } + } + + return gTrue; +} + +// Decode a progressive JPEG image. +void DCTStream::decodeImage() { + int dataIn[64]; + Guchar dataOut[64]; + Gushort *quantTable; + int pY, pCb, pCr, pR, pG, pB; + int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i; + int h, v, horiz, vert, hSub, vSub; + int *p0, *p1, *p2; + + for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) { + for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) { + for (cc = 0; cc < numComps; ++cc) { + quantTable = quantTables[compInfo[cc].quantTable]; + h = compInfo[cc].hSample; + v = compInfo[cc].vSample; + horiz = mcuWidth / h; + vert = mcuHeight / v; + hSub = horiz / 8; + vSub = vert / 8; + for (y2 = 0; y2 < mcuHeight; y2 += vert) { + for (x2 = 0; x2 < mcuWidth; x2 += horiz) { + + // pull out the coded data unit + p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)]; + for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) { + dataIn[i] = p1[0]; + dataIn[i+1] = p1[1]; + dataIn[i+2] = p1[2]; + dataIn[i+3] = p1[3]; + dataIn[i+4] = p1[4]; + dataIn[i+5] = p1[5]; + dataIn[i+6] = p1[6]; + dataIn[i+7] = p1[7]; + p1 += bufWidth * vSub; + } + + // transform + transformDataUnit(quantTable, dataIn, dataOut); + + // store back into frameBuf, doing replication for + // subsampled components + p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)]; + if (hSub == 1 && vSub == 1) { + for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) { + p1[0] = dataOut[i] & 0xff; + p1[1] = dataOut[i+1] & 0xff; + p1[2] = dataOut[i+2] & 0xff; + p1[3] = dataOut[i+3] & 0xff; + p1[4] = dataOut[i+4] & 0xff; + p1[5] = dataOut[i+5] & 0xff; + p1[6] = dataOut[i+6] & 0xff; + p1[7] = dataOut[i+7] & 0xff; + p1 += bufWidth; + } + } else if (hSub == 2 && vSub == 2) { + p2 = p1 + bufWidth; + for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) { + p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff; + p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff; + p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff; + p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff; + p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff; + p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff; + p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff; + p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff; + p1 += bufWidth * 2; + p2 += bufWidth * 2; + } + } else { + i = 0; + for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) { + for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) { + p2 = p1 + x4; + for (y5 = 0; y5 < vSub; ++y5) { + for (x5 = 0; x5 < hSub; ++x5) { + p2[x5] = dataOut[i] & 0xff; + } + p2 += bufWidth; + } + ++i; + } + p1 += bufWidth * vSub; + } + } + } + } + } + + // color space conversion + if (colorXform) { + // convert YCbCr to RGB + if (numComps == 3) { + for (y2 = 0; y2 < mcuHeight; ++y2) { + p0 = &frameBuf[0][(y1+y2) * bufWidth + x1]; + p1 = &frameBuf[1][(y1+y2) * bufWidth + x1]; + p2 = &frameBuf[2][(y1+y2) * bufWidth + x1]; + for (x2 = 0; x2 < mcuWidth; ++x2) { + pY = *p0; + pCb = *p1 - 128; + pCr = *p2 - 128; + pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16; + *p0++ = dctClip[dctClipOffset + pR]; + pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + + 32768) >> 16; + *p1++ = dctClip[dctClipOffset + pG]; + pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16; + *p2++ = dctClip[dctClipOffset + pB]; + } + } + // convert YCbCrK to CMYK (K is passed through unchanged) + } else if (numComps == 4) { + for (y2 = 0; y2 < mcuHeight; ++y2) { + p0 = &frameBuf[0][(y1+y2) * bufWidth + x1]; + p1 = &frameBuf[1][(y1+y2) * bufWidth + x1]; + p2 = &frameBuf[2][(y1+y2) * bufWidth + x1]; + for (x2 = 0; x2 < mcuWidth; ++x2) { + pY = *p0; + pCb = *p1 - 128; + pCr = *p2 - 128; + pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16; + *p0++ = 255 - dctClip[dctClipOffset + pR]; + pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + + 32768) >> 16; + *p1++ = 255 - dctClip[dctClipOffset + pG]; + pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16; + *p2++ = 255 - dctClip[dctClipOffset + pB]; + } + } + } + } + } + } +} + +// Transform one data unit -- this performs the dequantization and +// IDCT steps. This IDCT algorithm is taken from: +// Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, +// "Practical Fast 1-D DCT Algorithms with 11 Multiplications", +// IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, +// 988-991. +// The stage numbers mentioned in the comments refer to Figure 1 in this +// paper. +void DCTStream::transformDataUnit(Gushort *quantTable, + int dataIn[64], Guchar dataOut[64]) { + int v0, v1, v2, v3, v4, v5, v6, v7, t; + int *p; + int i; + + // dequant + for (i = 0; i < 64; ++i) { + dataIn[i] *= quantTable[i]; + } + + // inverse DCT on rows + for (i = 0; i < 64; i += 8) { + p = dataIn + i; + + // check for all-zero AC coefficients + if (p[1] == 0 && p[2] == 0 && p[3] == 0 && + p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) { + t = (dctSqrt2 * p[0] + 512) >> 10; + p[0] = t; + p[1] = t; + p[2] = t; + p[3] = t; + p[4] = t; + p[5] = t; + p[6] = t; + p[7] = t; + continue; + } + + // stage 4 + v0 = (dctSqrt2 * p[0] + 128) >> 8; + v1 = (dctSqrt2 * p[4] + 128) >> 8; + v2 = p[2]; + v3 = p[6]; + v4 = (dctSqrt1d2 * (p[1] - p[7]) + 128) >> 8; + v7 = (dctSqrt1d2 * (p[1] + p[7]) + 128) >> 8; + v5 = p[3] << 4; + v6 = p[5] << 4; + + // stage 3 + t = (v0 - v1+ 1) >> 1; + v0 = (v0 + v1 + 1) >> 1; + v1 = t; + t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8; + v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8; + v3 = t; + t = (v4 - v6 + 1) >> 1; + v4 = (v4 + v6 + 1) >> 1; + v6 = t; + t = (v7 + v5 + 1) >> 1; + v5 = (v7 - v5 + 1) >> 1; + v7 = t; + + // stage 2 + t = (v0 - v3 + 1) >> 1; + v0 = (v0 + v3 + 1) >> 1; + v3 = t; + t = (v1 - v2 + 1) >> 1; + v1 = (v1 + v2 + 1) >> 1; + v2 = t; + t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12; + v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12; + v7 = t; + t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12; + v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12; + v6 = t; + + // stage 1 + p[0] = v0 + v7; + p[7] = v0 - v7; + p[1] = v1 + v6; + p[6] = v1 - v6; + p[2] = v2 + v5; + p[5] = v2 - v5; + p[3] = v3 + v4; + p[4] = v3 - v4; + } + + // inverse DCT on columns + for (i = 0; i < 8; ++i) { + p = dataIn + i; + + // check for all-zero AC coefficients + if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 && + p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) { + t = (dctSqrt2 * dataIn[i+0] + 8192) >> 14; + p[0*8] = t; + p[1*8] = t; + p[2*8] = t; + p[3*8] = t; + p[4*8] = t; + p[5*8] = t; + p[6*8] = t; + p[7*8] = t; + continue; + } + + // stage 4 + v0 = (dctSqrt2 * p[0*8] + 2048) >> 12; + v1 = (dctSqrt2 * p[4*8] + 2048) >> 12; + v2 = p[2*8]; + v3 = p[6*8]; + v4 = (dctSqrt1d2 * (p[1*8] - p[7*8]) + 2048) >> 12; + v7 = (dctSqrt1d2 * (p[1*8] + p[7*8]) + 2048) >> 12; + v5 = p[3*8]; + v6 = p[5*8]; + + // stage 3 + t = (v0 - v1 + 1) >> 1; + v0 = (v0 + v1 + 1) >> 1; + v1 = t; + t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12; + v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12; + v3 = t; + t = (v4 - v6 + 1) >> 1; + v4 = (v4 + v6 + 1) >> 1; + v6 = t; + t = (v7 + v5 + 1) >> 1; + v5 = (v7 - v5 + 1) >> 1; + v7 = t; + + // stage 2 + t = (v0 - v3 + 1) >> 1; + v0 = (v0 + v3 + 1) >> 1; + v3 = t; + t = (v1 - v2 + 1) >> 1; + v1 = (v1 + v2 + 1) >> 1; + v2 = t; + t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12; + v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12; + v7 = t; + t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12; + v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12; + v6 = t; + + // stage 1 + p[0*8] = v0 + v7; + p[7*8] = v0 - v7; + p[1*8] = v1 + v6; + p[6*8] = v1 - v6; + p[2*8] = v2 + v5; + p[5*8] = v2 - v5; + p[3*8] = v3 + v4; + p[4*8] = v3 - v4; + } + + // convert to 8-bit integers + for (i = 0; i < 64; ++i) { + dataOut[i] = dctClip[dctClipOffset + 128 + ((dataIn[i] + 8) >> 4)]; + } +} + +int DCTStream::readHuffSym(DCTHuffTable *table) { + Gushort code; + int bit; + int codeBits; + + code = 0; + codeBits = 0; + do { + // add a bit to the code + if ((bit = readBit()) == EOF) + return 9999; + code = (code << 1) + bit; + ++codeBits; + + // look up code + if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) { + code -= table->firstCode[codeBits]; + return table->sym[table->firstSym[codeBits] + code]; + } + } while (codeBits < 16); + + error(getPos(), "Bad Huffman code in DCT stream"); + return 9999; +} + +int DCTStream::readAmp(int size) { + int amp, bit; + int bits; + + amp = 0; + for (bits = 0; bits < size; ++bits) { + if ((bit = readBit()) == EOF) + return 9999; + amp = (amp << 1) + bit; + } + if (amp < (1 << (size - 1))) + amp -= (1 << size) - 1; + return amp; +} + +int DCTStream::readBit() { + int bit; + int c, c2; + + if (inputBits == 0) { + if ((c = str->getChar()) == EOF) + return EOF; + if (c == 0xff) { + do { + c2 = str->getChar(); + } while (c2 == 0xff); + if (c2 != 0x00) { + error(getPos(), "Bad DCT data: missing 00 after ff"); + return EOF; + } + } + inputBuf = c; + inputBits = 8; + } + bit = (inputBuf >> (inputBits - 1)) & 1; + --inputBits; + return bit; +} + +GBool DCTStream::readHeader() { + GBool doScan; + int n; + int c = 0; + int i; + + // read headers + doScan = gFalse; + while (!doScan) { + c = readMarker(); + switch (c) { + case 0xc0: // SOF0 (sequential) + case 0xc1: // SOF1 (extended sequential) + if (!readBaselineSOF()) { + return gFalse; + } + break; + case 0xc2: // SOF2 (progressive) + if (!readProgressiveSOF()) { + return gFalse; + } + break; + case 0xc4: // DHT + if (!readHuffmanTables()) { + return gFalse; + } + break; + case 0xd8: // SOI + break; + case 0xd9: // EOI + return gFalse; + case 0xda: // SOS + if (!readScanInfo()) { + return gFalse; + } + doScan = gTrue; + break; + case 0xdb: // DQT + if (!readQuantTables()) { + return gFalse; + } + break; + case 0xdd: // DRI + if (!readRestartInterval()) { + return gFalse; + } + break; + case 0xe0: // APP0 + if (!readJFIFMarker()) { + return gFalse; + } + break; + case 0xee: // APP14 + if (!readAdobeMarker()) { + return gFalse; + } + break; + case EOF: + error(getPos(), "Bad DCT header"); + return gFalse; + default: + // skip APPn / COM / etc. + if (c >= 0xe0) { + n = read16() - 2; + for (i = 0; i < n; ++i) { + str->getChar(); + } + } else { + error(getPos(), "Unknown DCT marker <%02x>", c); + return gFalse; + } + break; + } + } + + return gTrue; +} + +GBool DCTStream::readBaselineSOF() { + int length; + int prec; + int i; + int c; + + length = read16(); + prec = str->getChar(); + height = read16(); + width = read16(); + numComps = str->getChar(); + if (numComps <= 0 || numComps > 4) { + numComps = 0; + error(getPos(), "Bad number of components in DCT stream"); + return gFalse; + } + if (prec != 8) { + error(getPos(), "Bad DCT precision %d", prec); + return gFalse; + } + for (i = 0; i < numComps; ++i) { + compInfo[i].id = str->getChar(); + c = str->getChar(); + compInfo[i].hSample = (c >> 4) & 0x0f; + compInfo[i].vSample = c & 0x0f; + compInfo[i].quantTable = str->getChar(); + } + progressive = gFalse; + return gTrue; +} + +GBool DCTStream::readProgressiveSOF() { + int length; + int prec; + int i; + int c; + + length = read16(); + prec = str->getChar(); + height = read16(); + width = read16(); + numComps = str->getChar(); + if (prec != 8) { + error(getPos(), "Bad DCT precision %d", prec); + return gFalse; + } + for (i = 0; i < numComps; ++i) { + compInfo[i].id = str->getChar(); + c = str->getChar(); + compInfo[i].hSample = (c >> 4) & 0x0f; + compInfo[i].vSample = c & 0x0f; + compInfo[i].quantTable = str->getChar(); + } + progressive = gTrue; + return gTrue; +} + +GBool DCTStream::readScanInfo() { + int length; + int id, c; + int i, j; + + length = read16() - 2; + scanInfo.numComps = str->getChar(); + if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) { + scanInfo.numComps = 0; + error(getPos(), "Bad number of components in DCT stream"); + return gFalse; + } + --length; + if (length != 2 * scanInfo.numComps + 3) { + error(getPos(), "Bad DCT scan info block"); + return gFalse; + } + interleaved = scanInfo.numComps == numComps; + for (j = 0; j < numComps; ++j) { + scanInfo.comp[j] = gFalse; + } + for (i = 0; i < scanInfo.numComps; ++i) { + id = str->getChar(); + // some (broken) DCT streams reuse ID numbers, but at least they + // keep the components in order, so we check compInfo[i] first to + // work around the problem + if (id == compInfo[i].id) { + j = i; + } else { + for (j = 0; j < numComps; ++j) { + if (id == compInfo[j].id) { + break; + } + } + if (j == numComps) { + error(getPos(), "Bad DCT component ID in scan info block"); + return gFalse; + } + } + scanInfo.comp[j] = gTrue; + c = str->getChar(); + scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f; + scanInfo.acHuffTable[j] = c & 0x0f; + } + scanInfo.firstCoeff = str->getChar(); + scanInfo.lastCoeff = str->getChar(); + c = str->getChar(); + scanInfo.ah = (c >> 4) & 0x0f; + scanInfo.al = c & 0x0f; + return gTrue; +} + +GBool DCTStream::readQuantTables() { + int length, prec, i, index; + + length = read16() - 2; + while (length > 0) { + index = str->getChar(); + prec = (index >> 4) & 0x0f; + index &= 0x0f; + if (prec > 1 || index >= 4) { + error(getPos(), "Bad DCT quantization table"); + return gFalse; + } + if (index == numQuantTables) { + numQuantTables = index + 1; + } + for (i = 0; i < 64; ++i) { + if (prec) { + quantTables[index][dctZigZag[i]] = read16(); + } else { + quantTables[index][dctZigZag[i]] = str->getChar(); + } + } + if (prec) { + length -= 129; + } else { + length -= 65; + } + } + return gTrue; +} + +GBool DCTStream::readHuffmanTables() { + DCTHuffTable *tbl; + int length; + int index; + Gushort code; + Guchar sym; + int i; + int c; + + length = read16() - 2; + while (length > 0) { + index = str->getChar(); + --length; + if ((index & ~0x10) >= 4 || (index & ~0x10) < 0) { + error(getPos(), "Bad DCT Huffman table"); + return gFalse; + } + if (index & 0x10) { + index &= 0x03; + if (index >= numACHuffTables) + numACHuffTables = index+1; + tbl = &acHuffTables[index]; + } else { + index &= 0x0f; + if (index >= numDCHuffTables) + numDCHuffTables = index+1; + tbl = &dcHuffTables[index]; + } + sym = 0; + code = 0; + for (i = 1; i <= 16; ++i) { + c = str->getChar(); + tbl->firstSym[i] = sym; + tbl->firstCode[i] = code; + tbl->numCodes[i] = c; + sym += c; + code = (code + c) << 1; + } + length -= 16; + for (i = 0; i < sym; ++i) + tbl->sym[i] = str->getChar(); + length -= sym; + } + return gTrue; +} + +GBool DCTStream::readRestartInterval() { + int length; + + length = read16(); + if (length != 4) { + error(getPos(), "Bad DCT restart interval"); + return gFalse; + } + restartInterval = read16(); + return gTrue; +} + +GBool DCTStream::readJFIFMarker() { + int length, i; + char buf[5]; + int c; + + length = read16(); + length -= 2; + if (length >= 5) { + for (i = 0; i < 5; ++i) { + if ((c = str->getChar()) == EOF) { + error(getPos(), "Bad DCT APP0 marker"); + return gFalse; + } + buf[i] = c; + } + length -= 5; + if (!memcmp(buf, "JFIF\0", 5)) { + gotJFIFMarker = gTrue; + } + } + while (length > 0) { + if (str->getChar() == EOF) { + error(getPos(), "Bad DCT APP0 marker"); + return gFalse; + } + --length; + } + return gTrue; +} + +GBool DCTStream::readAdobeMarker() { + int length, i; + char buf[12]; + int c; + + length = read16(); + if (length < 14) { + goto err; + } + for (i = 0; i < 12; ++i) { + if ((c = str->getChar()) == EOF) { + goto err; + } + buf[i] = c; + } + if (strncmp(buf, "Adobe", 5)) { + goto err; + } + colorXform = buf[11]; + gotAdobeMarker = gTrue; + for (i = 14; i < length; ++i) { + if (str->getChar() == EOF) { + goto err; + } + } + return gTrue; + + err: + error(getPos(), "Bad DCT Adobe APP14 marker"); + return gFalse; +} + +GBool DCTStream::readTrailer() { + int c; + + c = readMarker(); + if (c != 0xd9) { // EOI + error(getPos(), "Bad DCT trailer"); + return gFalse; + } + return gTrue; +} + +int DCTStream::readMarker() { + int c; + + do { + do { + c = str->getChar(); + } while (c != 0xff && c != EOF); + while (c == 0xff) { + c = str->getChar(); + } + } while (c == 0x00); + return c; +} + +int DCTStream::read16() { + int c1, c2; + + if ((c1 = str->getChar()) == EOF) + return EOF; + if ((c2 = str->getChar()) == EOF) + return EOF; + return (c1 << 8) + c2; +} + +GooString *DCTStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 2) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("<< >> /DCTDecode filter\n"); + return s; +} + +GBool DCTStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +#endif + +#ifndef ENABLE_ZLIB +//------------------------------------------------------------------------ +// FlateStream +//------------------------------------------------------------------------ + +int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 +}; + +FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = { + {0, 3}, + {0, 4}, + {0, 5}, + {0, 6}, + {0, 7}, + {0, 8}, + {0, 9}, + {0, 10}, + {1, 11}, + {1, 13}, + {1, 15}, + {1, 17}, + {2, 19}, + {2, 23}, + {2, 27}, + {2, 31}, + {3, 35}, + {3, 43}, + {3, 51}, + {3, 59}, + {4, 67}, + {4, 83}, + {4, 99}, + {4, 115}, + {5, 131}, + {5, 163}, + {5, 195}, + {5, 227}, + {0, 258}, + {0, 258}, + {0, 258} +}; + +FlateDecode FlateStream::distDecode[flateMaxDistCodes] = { + { 0, 1}, + { 0, 2}, + { 0, 3}, + { 0, 4}, + { 1, 5}, + { 1, 7}, + { 2, 9}, + { 2, 13}, + { 3, 17}, + { 3, 25}, + { 4, 33}, + { 4, 49}, + { 5, 65}, + { 5, 97}, + { 6, 129}, + { 6, 193}, + { 7, 257}, + { 7, 385}, + { 8, 513}, + { 8, 769}, + { 9, 1025}, + { 9, 1537}, + {10, 2049}, + {10, 3073}, + {11, 4097}, + {11, 6145}, + {12, 8193}, + {12, 12289}, + {13, 16385}, + {13, 24577} +}; + +static FlateCode flateFixedLitCodeTabCodes[512] = { + {7, 0x0100}, + {8, 0x0050}, + {8, 0x0010}, + {8, 0x0118}, + {7, 0x0110}, + {8, 0x0070}, + {8, 0x0030}, + {9, 0x00c0}, + {7, 0x0108}, + {8, 0x0060}, + {8, 0x0020}, + {9, 0x00a0}, + {8, 0x0000}, + {8, 0x0080}, + {8, 0x0040}, + {9, 0x00e0}, + {7, 0x0104}, + {8, 0x0058}, + {8, 0x0018}, + {9, 0x0090}, + {7, 0x0114}, + {8, 0x0078}, + {8, 0x0038}, + {9, 0x00d0}, + {7, 0x010c}, + {8, 0x0068}, + {8, 0x0028}, + {9, 0x00b0}, + {8, 0x0008}, + {8, 0x0088}, + {8, 0x0048}, + {9, 0x00f0}, + {7, 0x0102}, + {8, 0x0054}, + {8, 0x0014}, + {8, 0x011c}, + {7, 0x0112}, + {8, 0x0074}, + {8, 0x0034}, + {9, 0x00c8}, + {7, 0x010a}, + {8, 0x0064}, + {8, 0x0024}, + {9, 0x00a8}, + {8, 0x0004}, + {8, 0x0084}, + {8, 0x0044}, + {9, 0x00e8}, + {7, 0x0106}, + {8, 0x005c}, + {8, 0x001c}, + {9, 0x0098}, + {7, 0x0116}, + {8, 0x007c}, + {8, 0x003c}, + {9, 0x00d8}, + {7, 0x010e}, + {8, 0x006c}, + {8, 0x002c}, + {9, 0x00b8}, + {8, 0x000c}, + {8, 0x008c}, + {8, 0x004c}, + {9, 0x00f8}, + {7, 0x0101}, + {8, 0x0052}, + {8, 0x0012}, + {8, 0x011a}, + {7, 0x0111}, + {8, 0x0072}, + {8, 0x0032}, + {9, 0x00c4}, + {7, 0x0109}, + {8, 0x0062}, + {8, 0x0022}, + {9, 0x00a4}, + {8, 0x0002}, + {8, 0x0082}, + {8, 0x0042}, + {9, 0x00e4}, + {7, 0x0105}, + {8, 0x005a}, + {8, 0x001a}, + {9, 0x0094}, + {7, 0x0115}, + {8, 0x007a}, + {8, 0x003a}, + {9, 0x00d4}, + {7, 0x010d}, + {8, 0x006a}, + {8, 0x002a}, + {9, 0x00b4}, + {8, 0x000a}, + {8, 0x008a}, + {8, 0x004a}, + {9, 0x00f4}, + {7, 0x0103}, + {8, 0x0056}, + {8, 0x0016}, + {8, 0x011e}, + {7, 0x0113}, + {8, 0x0076}, + {8, 0x0036}, + {9, 0x00cc}, + {7, 0x010b}, + {8, 0x0066}, + {8, 0x0026}, + {9, 0x00ac}, + {8, 0x0006}, + {8, 0x0086}, + {8, 0x0046}, + {9, 0x00ec}, + {7, 0x0107}, + {8, 0x005e}, + {8, 0x001e}, + {9, 0x009c}, + {7, 0x0117}, + {8, 0x007e}, + {8, 0x003e}, + {9, 0x00dc}, + {7, 0x010f}, + {8, 0x006e}, + {8, 0x002e}, + {9, 0x00bc}, + {8, 0x000e}, + {8, 0x008e}, + {8, 0x004e}, + {9, 0x00fc}, + {7, 0x0100}, + {8, 0x0051}, + {8, 0x0011}, + {8, 0x0119}, + {7, 0x0110}, + {8, 0x0071}, + {8, 0x0031}, + {9, 0x00c2}, + {7, 0x0108}, + {8, 0x0061}, + {8, 0x0021}, + {9, 0x00a2}, + {8, 0x0001}, + {8, 0x0081}, + {8, 0x0041}, + {9, 0x00e2}, + {7, 0x0104}, + {8, 0x0059}, + {8, 0x0019}, + {9, 0x0092}, + {7, 0x0114}, + {8, 0x0079}, + {8, 0x0039}, + {9, 0x00d2}, + {7, 0x010c}, + {8, 0x0069}, + {8, 0x0029}, + {9, 0x00b2}, + {8, 0x0009}, + {8, 0x0089}, + {8, 0x0049}, + {9, 0x00f2}, + {7, 0x0102}, + {8, 0x0055}, + {8, 0x0015}, + {8, 0x011d}, + {7, 0x0112}, + {8, 0x0075}, + {8, 0x0035}, + {9, 0x00ca}, + {7, 0x010a}, + {8, 0x0065}, + {8, 0x0025}, + {9, 0x00aa}, + {8, 0x0005}, + {8, 0x0085}, + {8, 0x0045}, + {9, 0x00ea}, + {7, 0x0106}, + {8, 0x005d}, + {8, 0x001d}, + {9, 0x009a}, + {7, 0x0116}, + {8, 0x007d}, + {8, 0x003d}, + {9, 0x00da}, + {7, 0x010e}, + {8, 0x006d}, + {8, 0x002d}, + {9, 0x00ba}, + {8, 0x000d}, + {8, 0x008d}, + {8, 0x004d}, + {9, 0x00fa}, + {7, 0x0101}, + {8, 0x0053}, + {8, 0x0013}, + {8, 0x011b}, + {7, 0x0111}, + {8, 0x0073}, + {8, 0x0033}, + {9, 0x00c6}, + {7, 0x0109}, + {8, 0x0063}, + {8, 0x0023}, + {9, 0x00a6}, + {8, 0x0003}, + {8, 0x0083}, + {8, 0x0043}, + {9, 0x00e6}, + {7, 0x0105}, + {8, 0x005b}, + {8, 0x001b}, + {9, 0x0096}, + {7, 0x0115}, + {8, 0x007b}, + {8, 0x003b}, + {9, 0x00d6}, + {7, 0x010d}, + {8, 0x006b}, + {8, 0x002b}, + {9, 0x00b6}, + {8, 0x000b}, + {8, 0x008b}, + {8, 0x004b}, + {9, 0x00f6}, + {7, 0x0103}, + {8, 0x0057}, + {8, 0x0017}, + {8, 0x011f}, + {7, 0x0113}, + {8, 0x0077}, + {8, 0x0037}, + {9, 0x00ce}, + {7, 0x010b}, + {8, 0x0067}, + {8, 0x0027}, + {9, 0x00ae}, + {8, 0x0007}, + {8, 0x0087}, + {8, 0x0047}, + {9, 0x00ee}, + {7, 0x0107}, + {8, 0x005f}, + {8, 0x001f}, + {9, 0x009e}, + {7, 0x0117}, + {8, 0x007f}, + {8, 0x003f}, + {9, 0x00de}, + {7, 0x010f}, + {8, 0x006f}, + {8, 0x002f}, + {9, 0x00be}, + {8, 0x000f}, + {8, 0x008f}, + {8, 0x004f}, + {9, 0x00fe}, + {7, 0x0100}, + {8, 0x0050}, + {8, 0x0010}, + {8, 0x0118}, + {7, 0x0110}, + {8, 0x0070}, + {8, 0x0030}, + {9, 0x00c1}, + {7, 0x0108}, + {8, 0x0060}, + {8, 0x0020}, + {9, 0x00a1}, + {8, 0x0000}, + {8, 0x0080}, + {8, 0x0040}, + {9, 0x00e1}, + {7, 0x0104}, + {8, 0x0058}, + {8, 0x0018}, + {9, 0x0091}, + {7, 0x0114}, + {8, 0x0078}, + {8, 0x0038}, + {9, 0x00d1}, + {7, 0x010c}, + {8, 0x0068}, + {8, 0x0028}, + {9, 0x00b1}, + {8, 0x0008}, + {8, 0x0088}, + {8, 0x0048}, + {9, 0x00f1}, + {7, 0x0102}, + {8, 0x0054}, + {8, 0x0014}, + {8, 0x011c}, + {7, 0x0112}, + {8, 0x0074}, + {8, 0x0034}, + {9, 0x00c9}, + {7, 0x010a}, + {8, 0x0064}, + {8, 0x0024}, + {9, 0x00a9}, + {8, 0x0004}, + {8, 0x0084}, + {8, 0x0044}, + {9, 0x00e9}, + {7, 0x0106}, + {8, 0x005c}, + {8, 0x001c}, + {9, 0x0099}, + {7, 0x0116}, + {8, 0x007c}, + {8, 0x003c}, + {9, 0x00d9}, + {7, 0x010e}, + {8, 0x006c}, + {8, 0x002c}, + {9, 0x00b9}, + {8, 0x000c}, + {8, 0x008c}, + {8, 0x004c}, + {9, 0x00f9}, + {7, 0x0101}, + {8, 0x0052}, + {8, 0x0012}, + {8, 0x011a}, + {7, 0x0111}, + {8, 0x0072}, + {8, 0x0032}, + {9, 0x00c5}, + {7, 0x0109}, + {8, 0x0062}, + {8, 0x0022}, + {9, 0x00a5}, + {8, 0x0002}, + {8, 0x0082}, + {8, 0x0042}, + {9, 0x00e5}, + {7, 0x0105}, + {8, 0x005a}, + {8, 0x001a}, + {9, 0x0095}, + {7, 0x0115}, + {8, 0x007a}, + {8, 0x003a}, + {9, 0x00d5}, + {7, 0x010d}, + {8, 0x006a}, + {8, 0x002a}, + {9, 0x00b5}, + {8, 0x000a}, + {8, 0x008a}, + {8, 0x004a}, + {9, 0x00f5}, + {7, 0x0103}, + {8, 0x0056}, + {8, 0x0016}, + {8, 0x011e}, + {7, 0x0113}, + {8, 0x0076}, + {8, 0x0036}, + {9, 0x00cd}, + {7, 0x010b}, + {8, 0x0066}, + {8, 0x0026}, + {9, 0x00ad}, + {8, 0x0006}, + {8, 0x0086}, + {8, 0x0046}, + {9, 0x00ed}, + {7, 0x0107}, + {8, 0x005e}, + {8, 0x001e}, + {9, 0x009d}, + {7, 0x0117}, + {8, 0x007e}, + {8, 0x003e}, + {9, 0x00dd}, + {7, 0x010f}, + {8, 0x006e}, + {8, 0x002e}, + {9, 0x00bd}, + {8, 0x000e}, + {8, 0x008e}, + {8, 0x004e}, + {9, 0x00fd}, + {7, 0x0100}, + {8, 0x0051}, + {8, 0x0011}, + {8, 0x0119}, + {7, 0x0110}, + {8, 0x0071}, + {8, 0x0031}, + {9, 0x00c3}, + {7, 0x0108}, + {8, 0x0061}, + {8, 0x0021}, + {9, 0x00a3}, + {8, 0x0001}, + {8, 0x0081}, + {8, 0x0041}, + {9, 0x00e3}, + {7, 0x0104}, + {8, 0x0059}, + {8, 0x0019}, + {9, 0x0093}, + {7, 0x0114}, + {8, 0x0079}, + {8, 0x0039}, + {9, 0x00d3}, + {7, 0x010c}, + {8, 0x0069}, + {8, 0x0029}, + {9, 0x00b3}, + {8, 0x0009}, + {8, 0x0089}, + {8, 0x0049}, + {9, 0x00f3}, + {7, 0x0102}, + {8, 0x0055}, + {8, 0x0015}, + {8, 0x011d}, + {7, 0x0112}, + {8, 0x0075}, + {8, 0x0035}, + {9, 0x00cb}, + {7, 0x010a}, + {8, 0x0065}, + {8, 0x0025}, + {9, 0x00ab}, + {8, 0x0005}, + {8, 0x0085}, + {8, 0x0045}, + {9, 0x00eb}, + {7, 0x0106}, + {8, 0x005d}, + {8, 0x001d}, + {9, 0x009b}, + {7, 0x0116}, + {8, 0x007d}, + {8, 0x003d}, + {9, 0x00db}, + {7, 0x010e}, + {8, 0x006d}, + {8, 0x002d}, + {9, 0x00bb}, + {8, 0x000d}, + {8, 0x008d}, + {8, 0x004d}, + {9, 0x00fb}, + {7, 0x0101}, + {8, 0x0053}, + {8, 0x0013}, + {8, 0x011b}, + {7, 0x0111}, + {8, 0x0073}, + {8, 0x0033}, + {9, 0x00c7}, + {7, 0x0109}, + {8, 0x0063}, + {8, 0x0023}, + {9, 0x00a7}, + {8, 0x0003}, + {8, 0x0083}, + {8, 0x0043}, + {9, 0x00e7}, + {7, 0x0105}, + {8, 0x005b}, + {8, 0x001b}, + {9, 0x0097}, + {7, 0x0115}, + {8, 0x007b}, + {8, 0x003b}, + {9, 0x00d7}, + {7, 0x010d}, + {8, 0x006b}, + {8, 0x002b}, + {9, 0x00b7}, + {8, 0x000b}, + {8, 0x008b}, + {8, 0x004b}, + {9, 0x00f7}, + {7, 0x0103}, + {8, 0x0057}, + {8, 0x0017}, + {8, 0x011f}, + {7, 0x0113}, + {8, 0x0077}, + {8, 0x0037}, + {9, 0x00cf}, + {7, 0x010b}, + {8, 0x0067}, + {8, 0x0027}, + {9, 0x00af}, + {8, 0x0007}, + {8, 0x0087}, + {8, 0x0047}, + {9, 0x00ef}, + {7, 0x0107}, + {8, 0x005f}, + {8, 0x001f}, + {9, 0x009f}, + {7, 0x0117}, + {8, 0x007f}, + {8, 0x003f}, + {9, 0x00df}, + {7, 0x010f}, + {8, 0x006f}, + {8, 0x002f}, + {9, 0x00bf}, + {8, 0x000f}, + {8, 0x008f}, + {8, 0x004f}, + {9, 0x00ff} +}; + +FlateHuffmanTab FlateStream::fixedLitCodeTab = { + flateFixedLitCodeTabCodes, 9 +}; + +static FlateCode flateFixedDistCodeTabCodes[32] = { + {5, 0x0000}, + {5, 0x0010}, + {5, 0x0008}, + {5, 0x0018}, + {5, 0x0004}, + {5, 0x0014}, + {5, 0x000c}, + {5, 0x001c}, + {5, 0x0002}, + {5, 0x0012}, + {5, 0x000a}, + {5, 0x001a}, + {5, 0x0006}, + {5, 0x0016}, + {5, 0x000e}, + {0, 0x0000}, + {5, 0x0001}, + {5, 0x0011}, + {5, 0x0009}, + {5, 0x0019}, + {5, 0x0005}, + {5, 0x0015}, + {5, 0x000d}, + {5, 0x001d}, + {5, 0x0003}, + {5, 0x0013}, + {5, 0x000b}, + {5, 0x001b}, + {5, 0x0007}, + {5, 0x0017}, + {5, 0x000f}, + {0, 0x0000} +}; + +FlateHuffmanTab FlateStream::fixedDistCodeTab = { + flateFixedDistCodeTabCodes, 5 +}; + +FlateStream::FlateStream(Stream *strA, int predictor, int columns, + int colors, int bits): + FilterStream(strA) { + if (predictor != 1) { + pred = new StreamPredictor(this, predictor, columns, colors, bits); + if (!pred->isOk()) { + delete pred; + pred = NULL; + } + } else { + pred = NULL; + } + litCodeTab.codes = NULL; + distCodeTab.codes = NULL; +} + +FlateStream::~FlateStream() { + if (litCodeTab.codes != fixedLitCodeTab.codes) { + gfree(litCodeTab.codes); + } + if (distCodeTab.codes != fixedDistCodeTab.codes) { + gfree(distCodeTab.codes); + } + if (pred) { + delete pred; + } + delete str; +} + +void FlateStream::reset() { + int cmf, flg; + + index = 0; + remain = 0; + codeBuf = 0; + codeSize = 0; + compressedBlock = gFalse; + endOfBlock = gTrue; + eof = gTrue; + + str->reset(); + + // read header + //~ need to look at window size? + endOfBlock = eof = gTrue; + cmf = str->getChar(); + flg = str->getChar(); + if (cmf == EOF || flg == EOF) + return; + if ((cmf & 0x0f) != 0x08) { + error(getPos(), "Unknown compression method in flate stream"); + return; + } + if ((((cmf << 8) + flg) % 31) != 0) { + error(getPos(), "Bad FCHECK in flate stream"); + return; + } + if (flg & 0x20) { + error(getPos(), "FDICT bit set in flate stream"); + return; + } + + eof = gFalse; +} + +GBool FlateStream::hasGetBuf() { +#ifdef ENABLE_FLATE_GET_BUF + if (pred) + return gFalse; + return gTrue; +#else + return gFalse; +#endif +} + +void FlateStream::ungetBuf(int sizeToGoBack) { + remain += sizeToGoBack; + index -= sizeToGoBack; + if (index < 0) + index = flateWindow + index; +} + +GBool FlateStream::getBuf(char **bufOut, int *bufSizeOut, int maxSize) { + int sizeToReturn; + assert(hasGetBuf()); + while (remain == 0) { + if (endOfBlock && eof) + return gFalse; + readSome(); + } + // buf wraps, for simplicity we return only the part that doesn't wrap + sizeToReturn = remain; + if (index + remain > flateWindow) { + sizeToReturn = flateWindow - index; + } + if (Stream::NO_SIZE_LIMIT != maxSize) { + assert(maxSize > 0); + if (sizeToReturn > maxSize) + sizeToReturn = maxSize; + } + assert(sizeToReturn > 0); + remain -= sizeToReturn; + *bufOut = (char*)&(buf[index]); + *bufSizeOut = sizeToReturn; + index = (index + sizeToReturn) & flateMask; + return gTrue; +} + +int FlateStream::getChar() { + int c; + + if (pred) { + return pred->getChar(); + } + while (remain == 0) { + if (endOfBlock && eof) + return EOF; + readSome(); + } + c = buf[index]; + index = (index + 1) & flateMask; + --remain; + return c; +} + +int FlateStream::lookChar() { + int c; + + if (pred) { + return pred->lookChar(); + } + while (remain == 0) { + if (endOfBlock && eof) + return EOF; + readSome(); + } + c = buf[index]; + return c; +} + +int FlateStream::getRawChar() { + int c; + + while (remain == 0) { + if (endOfBlock && eof) + return EOF; + readSome(); + } + c = buf[index]; + index = (index + 1) & flateMask; + --remain; + return c; +} + +GooString *FlateStream::getPSFilter(int psLevel, char *indent) { + GooString *s; + + if (psLevel < 3 || pred) { + return NULL; + } + if (!(s = str->getPSFilter(psLevel, indent))) { + return NULL; + } + s->append(indent)->append("<< >> /FlateDecode filter\n"); + return s; +} + +GBool FlateStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +void FlateStream::readSome() { + int code1, code2; + int len, dist; + int i, j, k; + int c; + + if (endOfBlock) { + if (!startBlock()) + return; + } + + if (compressedBlock) { + if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF) + goto err; + if (code1 < 256) { + buf[index] = code1; + remain = 1; + } else if (code1 == 256) { + endOfBlock = gTrue; + remain = 0; + } else { + code1 -= 257; + code2 = lengthDecode[code1].bits; + if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF) + goto err; + len = lengthDecode[code1].first + code2; + if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF) + goto err; + code2 = distDecode[code1].bits; + if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF) + goto err; + dist = distDecode[code1].first + code2; + i = index; + j = (index - dist) & flateMask; + for (k = 0; k < len; ++k) { + buf[i] = buf[j]; + i = (i + 1) & flateMask; + j = (j + 1) & flateMask; + } + remain = len; + } + + } else { + len = (blockLen < flateWindow) ? blockLen : flateWindow; + for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) { + if ((c = str->getChar()) == EOF) { + endOfBlock = eof = gTrue; + break; + } + buf[j] = c & 0xff; + } + remain = i; + blockLen -= len; + if (blockLen == 0) + endOfBlock = gTrue; + } + + return; + +err: + error(getPos(), "Unexpected end of file in flate stream"); + endOfBlock = eof = gTrue; + remain = 0; +} + +GBool FlateStream::startBlock() { + int blockHdr; + int c; + int check; + + // free the code tables from the previous block + if (litCodeTab.codes != fixedLitCodeTab.codes) { + gfree(litCodeTab.codes); + } + litCodeTab.codes = NULL; + if (distCodeTab.codes != fixedDistCodeTab.codes) { + gfree(distCodeTab.codes); + } + distCodeTab.codes = NULL; + + // read block header + blockHdr = getCodeWord(3); + if (blockHdr & 1) + eof = gTrue; + blockHdr >>= 1; + + // uncompressed block + if (blockHdr == 0) { + compressedBlock = gFalse; + if ((c = str->getChar()) == EOF) + goto err; + blockLen = c & 0xff; + if ((c = str->getChar()) == EOF) + goto err; + blockLen |= (c & 0xff) << 8; + if ((c = str->getChar()) == EOF) + goto err; + check = c & 0xff; + if ((c = str->getChar()) == EOF) + goto err; + check |= (c & 0xff) << 8; + if (check != (~blockLen & 0xffff)) + error(getPos(), "Bad uncompressed block length in flate stream"); + codeBuf = 0; + codeSize = 0; + + // compressed block with fixed codes + } else if (blockHdr == 1) { + compressedBlock = gTrue; + loadFixedCodes(); + + // compressed block with dynamic codes + } else if (blockHdr == 2) { + compressedBlock = gTrue; + if (!readDynamicCodes()) { + goto err; + } + + // unknown block type + } else { + goto err; + } + + endOfBlock = gFalse; + return gTrue; + +err: + error(getPos(), "Bad block header in flate stream"); + endOfBlock = eof = gTrue; + return gFalse; +} + +void FlateStream::loadFixedCodes() { + litCodeTab.codes = fixedLitCodeTab.codes; + litCodeTab.maxLen = fixedLitCodeTab.maxLen; + distCodeTab.codes = fixedDistCodeTab.codes; + distCodeTab.maxLen = fixedDistCodeTab.maxLen; +} + +GBool FlateStream::readDynamicCodes() { + int numCodeLenCodes; + int numLitCodes; + int numDistCodes; + int codeLenCodeLengths[flateMaxCodeLenCodes]; + FlateHuffmanTab codeLenCodeTab; + int len, repeat, code; + int i; + + codeLenCodeTab.codes = NULL; + + // read lengths + if ((numLitCodes = getCodeWord(5)) == EOF) { + goto err; + } + numLitCodes += 257; + if ((numDistCodes = getCodeWord(5)) == EOF) { + goto err; + } + numDistCodes += 1; + if ((numCodeLenCodes = getCodeWord(4)) == EOF) { + goto err; + } + numCodeLenCodes += 4; + if (numLitCodes > flateMaxLitCodes || + numDistCodes > flateMaxDistCodes || + numCodeLenCodes > flateMaxCodeLenCodes) { + goto err; + } + + // build the code length code table + for (i = 0; i < flateMaxCodeLenCodes; ++i) { + codeLenCodeLengths[i] = 0; + } + for (i = 0; i < numCodeLenCodes; ++i) { + if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) { + goto err; + } + } + compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab); + + // build the literal and distance code tables + len = 0; + repeat = 0; + i = 0; + while (i < numLitCodes + numDistCodes) { + if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) { + goto err; + } + if (code == 16) { + if ((repeat = getCodeWord(2)) == EOF) { + goto err; + } + repeat += 3; + if (i + repeat > numLitCodes + numDistCodes) { + goto err; + } + for (; repeat > 0; --repeat) { + codeLengths[i++] = len; + } + } else if (code == 17) { + if ((repeat = getCodeWord(3)) == EOF) { + goto err; + } + repeat += 3; + if (i + repeat > numLitCodes + numDistCodes) { + goto err; + } + len = 0; + for (; repeat > 0; --repeat) { + codeLengths[i++] = 0; + } + } else if (code == 18) { + if ((repeat = getCodeWord(7)) == EOF) { + goto err; + } + repeat += 11; + if (i + repeat > numLitCodes + numDistCodes) { + goto err; + } + len = 0; + for (; repeat > 0; --repeat) { + codeLengths[i++] = 0; + } + } else { + codeLengths[i++] = len = code; + } + } + compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab); + compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab); + + gfree(codeLenCodeTab.codes); + return gTrue; + +err: + error(getPos(), "Bad dynamic code table in flate stream"); + gfree(codeLenCodeTab.codes); + return gFalse; +} + +// Convert an array of lengths, in value order, into a +// Huffman code lookup table. +void FlateStream::compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab) { + int tabSize, len, code, code2, skip, val, i, t; + + // find max code length + tab->maxLen = 0; + for (val = 0; val < n; ++val) { + if (lengths[val] > tab->maxLen) { + tab->maxLen = lengths[val]; + } + } + + // allocate the table + tabSize = 1 << tab->maxLen; + tab->codes = (FlateCode *)gmallocn(tabSize, sizeof(FlateCode)); + + // clear the table + for (i = 0; i < tabSize; ++i) { + tab->codes[i].len = 0; + tab->codes[i].val = 0; + } + + // build the table + for (len = 1, code = 0, skip = 2; + len <= tab->maxLen; + ++len, code <<= 1, skip <<= 1) { + for (val = 0; val < n; ++val) { + if (lengths[val] == len) { + + // bit-reverse the code + code2 = 0; + t = code; + for (i = 0; i < len; ++i) { + code2 = (code2 << 1) | (t & 1); + t >>= 1; + } + + // fill in the table entries + for (i = code2; i < tabSize; i += skip) { + tab->codes[i].len = (Gushort)len; + tab->codes[i].val = (Gushort)val; + } + + ++code; + } + } + } +} + +int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) { + FlateCode *code; + int c; + + while (codeSize < tab->maxLen) { + if ((c = str->getChar()) == EOF) { + break; + } + codeBuf |= (c & 0xff) << codeSize; + codeSize += 8; + } + code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)]; + if (codeSize == 0 || codeSize < code->len || code->len == 0) { + return EOF; + } + codeBuf >>= code->len; + codeSize -= code->len; + return (int)code->val; +} + +int FlateStream::getCodeWord(int bits) { + int c; + + while (codeSize < bits) { + if ((c = str->getChar()) == EOF) + return EOF; + codeBuf |= (c & 0xff) << codeSize; + codeSize += 8; + } + c = codeBuf & ((1 << bits) - 1); + codeBuf >>= bits; + codeSize -= bits; + return c; +} +#endif + +//------------------------------------------------------------------------ +// EOFStream +//------------------------------------------------------------------------ + +EOFStream::EOFStream(Stream *strA): + FilterStream(strA) { +} + +EOFStream::~EOFStream() { + delete str; +} + +//------------------------------------------------------------------------ +// FixedLengthEncoder +//------------------------------------------------------------------------ + +FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA): + FilterStream(strA) { + length = lengthA; + count = 0; +} + +FixedLengthEncoder::~FixedLengthEncoder() { + if (str->isEncoder()) + delete str; +} + +void FixedLengthEncoder::reset() { + str->reset(); + count = 0; +} + +int FixedLengthEncoder::getChar() { + if (length >= 0 && count >= length) + return EOF; + ++count; + return str->getChar(); +} + +int FixedLengthEncoder::lookChar() { + if (length >= 0 && count >= length) + return EOF; + return str->getChar(); +} + +GBool FixedLengthEncoder::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +//------------------------------------------------------------------------ +// ASCIIHexEncoder +//------------------------------------------------------------------------ + +ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA): + FilterStream(strA) { + bufPtr = bufEnd = buf; + lineLen = 0; + eof = gFalse; +} + +ASCIIHexEncoder::~ASCIIHexEncoder() { + if (str->isEncoder()) { + delete str; + } +} + +void ASCIIHexEncoder::reset() { + str->reset(); + bufPtr = bufEnd = buf; + lineLen = 0; + eof = gFalse; +} + +GBool ASCIIHexEncoder::fillBuf() { + static char *hex = "0123456789abcdef"; + int c; + + if (eof) { + return gFalse; + } + bufPtr = bufEnd = buf; + if ((c = str->getChar()) == EOF) { + *bufEnd++ = '>'; + eof = gTrue; + } else { + if (lineLen >= 64) { + *bufEnd++ = '\n'; + lineLen = 0; + } + *bufEnd++ = hex[(c >> 4) & 0x0f]; + *bufEnd++ = hex[c & 0x0f]; + lineLen += 2; + } + return gTrue; +} + +//------------------------------------------------------------------------ +// ASCII85Encoder +//------------------------------------------------------------------------ + +ASCII85Encoder::ASCII85Encoder(Stream *strA): + FilterStream(strA) { + bufPtr = bufEnd = buf; + lineLen = 0; + eof = gFalse; +} + +ASCII85Encoder::~ASCII85Encoder() { + if (str->isEncoder()) + delete str; +} + +void ASCII85Encoder::reset() { + str->reset(); + bufPtr = bufEnd = buf; + lineLen = 0; + eof = gFalse; +} + +GBool ASCII85Encoder::fillBuf() { + Gulong t; + char buf1[5]; + int c; + int n, i; + + if (eof) + return gFalse; + t = 0; + for (n = 0; n < 4; ++n) { + if ((c = str->getChar()) == EOF) + break; + t = (t << 8) + c; + } + bufPtr = bufEnd = buf; + if (n > 0) { + if (n == 4 && t == 0) { + *bufEnd++ = 'z'; + if (++lineLen == 65) { + *bufEnd++ = '\n'; + lineLen = 0; + } + } else { + if (n < 4) + t <<= 8 * (4 - n); + for (i = 4; i >= 0; --i) { + buf1[i] = (char)(t % 85 + 0x21); + t /= 85; + } + for (i = 0; i <= n; ++i) { + *bufEnd++ = buf1[i]; + if (++lineLen == 65) { + *bufEnd++ = '\n'; + lineLen = 0; + } + } + } + } + if (n < 4) { + *bufEnd++ = '~'; + *bufEnd++ = '>'; + eof = gTrue; + } + return bufPtr < bufEnd; +} + +//------------------------------------------------------------------------ +// RunLengthEncoder +//------------------------------------------------------------------------ + +RunLengthEncoder::RunLengthEncoder(Stream *strA): + FilterStream(strA) { + bufPtr = bufEnd = nextEnd = buf; + eof = gFalse; +} + +RunLengthEncoder::~RunLengthEncoder() { + if (str->isEncoder()) + delete str; +} + +void RunLengthEncoder::reset() { + str->reset(); + bufPtr = bufEnd = nextEnd = buf; + eof = gFalse; +} + +// +// When fillBuf finishes, buf[] looks like this: +// +-----+--------------+-----------------+-- +// + tag | ... data ... | next 0, 1, or 2 | +// +-----+--------------+-----------------+-- +// ^ ^ ^ +// bufPtr bufEnd nextEnd +// +GBool RunLengthEncoder::fillBuf() { + int c, c1, c2; + int n; + + // already hit EOF? + if (eof) + return gFalse; + + // grab two bytes + if (nextEnd < bufEnd + 1) { + if ((c1 = str->getChar()) == EOF) { + eof = gTrue; + return gFalse; + } + } else { + c1 = bufEnd[0] & 0xff; + } + if (nextEnd < bufEnd + 2) { + if ((c2 = str->getChar()) == EOF) { + eof = gTrue; + buf[0] = 0; + buf[1] = c1; + bufPtr = buf; + bufEnd = &buf[2]; + return gTrue; + } + } else { + c2 = bufEnd[1] & 0xff; + } + + // check for repeat + c = 0; // make gcc happy + if (c1 == c2) { + n = 2; + while (n < 128 && (c = str->getChar()) == c1) + ++n; + buf[0] = (char)(257 - n); + buf[1] = c1; + bufEnd = &buf[2]; + if (c == EOF) { + eof = gTrue; + } else if (n < 128) { + buf[2] = c; + nextEnd = &buf[3]; + } else { + nextEnd = bufEnd; + } + + // get up to 128 chars + } else { + buf[1] = c1; + buf[2] = c2; + n = 2; + while (n < 128) { + if ((c = str->getChar()) == EOF) { + eof = gTrue; + break; + } + ++n; + buf[n] = c; + if (buf[n] == buf[n-1]) + break; + } + if (buf[n] == buf[n-1]) { + buf[0] = (char)(n-2-1); + bufEnd = &buf[n-1]; + nextEnd = &buf[n+1]; + } else { + buf[0] = (char)(n-1); + bufEnd = nextEnd = &buf[n+1]; + } + } + bufPtr = buf; + return gTrue; +} diff --git a/rosapps/smartpdf/poppler/poppler/Stream.h b/rosapps/smartpdf/poppler/poppler/Stream.h new file mode 100644 index 00000000000..b7664a67bcb --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/Stream.h @@ -0,0 +1,883 @@ +//======================================================================== +// +// Stream.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// Copyright 2006: Krzysztof Kowalczyk (http://blog.kowalczyk.info) +// +//======================================================================== + +#ifndef STREAM_H +#define STREAM_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include +#include "goo/gtypes.h" +#include "Object.h" + +class Decrypt; +class BaseStream; + +//------------------------------------------------------------------------ + +enum StreamKind { + strFile, + strASCIIHex, + strASCII85, + strLZW, + strRunLength, + strCCITTFax, + strDCT, + strFlate, + strJBIG2, + strJPX, + strWeird // internal-use stream types +}; + +enum StreamColorSpaceMode { + streamCSNone, + streamCSDeviceGray, + streamCSDeviceRGB, + streamCSDeviceCMYK +}; + +//------------------------------------------------------------------------ +// Stream (base class) +//------------------------------------------------------------------------ + +class Stream { +public: + + Stream(); + + virtual ~Stream(); + + // Reference counting. + int incRef() { return ++ref; } + int decRef() { return --ref; } + + // Get kind of stream. + virtual StreamKind getKind() = 0; + + // Reset stream to beginning. + virtual void reset() = 0; + + // Close down the stream. + virtual void close(); + + // Get next char from stream. + virtual int getChar() = 0; + + // Peek at next char in stream. + virtual int lookChar() = 0; + + // Get next char from stream without using the predictor. + // This is only used by StreamPredictor. + virtual int getRawChar(); + + // Get next line from stream. + virtual char *getLine(char *buf, int size); + + // Get current position in file. + virtual int getPos() = 0; + + // Go to a position in the stream. If

is negative, the + // position is from the end of the file; otherwise the position is + // from the start of the file. + virtual void setPos(Guint pos, int dir = 0) = 0; + + // Get PostScript command for the filter(s). + virtual GooString *getPSFilter(int psLevel, char *indent); + + // Does this stream type potentially contain non-printable chars? + virtual GBool isBinary(GBool last = gTrue) = 0; + + // Get the BaseStream of this stream. + virtual BaseStream *getBaseStream() = 0; + + // Get the dictionary associated with this stream. + virtual Dict *getDict() = 0; + + // Is this an encoding filter? + virtual GBool isEncoder() { return gFalse; } + + // Get image parameters which are defined by the stream contents. + virtual void getImageParams(int * /*bitsPerComponent*/, + StreamColorSpaceMode * /*csMode*/) {} + + // Add filters to this stream according to the parameters in . + // Returns the new stream. + Stream *addFilters(Object *dict); + + static const int NO_SIZE_LIMIT = -1; + + virtual GBool hasGetBuf() = 0; + virtual GBool getBuf(char **bufOut, int *bufSizeOut, int maxSize = NO_SIZE_LIMIT) = 0; + virtual void ungetBuf(int sizeToGoBack) = 0; + +private: + + Stream *makeFilter(char *name, Stream *str, Object *params); + + int ref; // reference count +}; + +//------------------------------------------------------------------------ +// BaseStream +// +// This is the base class for all streams that read directly from a file. +//------------------------------------------------------------------------ + +class BaseStream: public Stream { +public: + + BaseStream(Object *dictA); + virtual ~BaseStream(); + virtual Stream *makeSubStream(Guint start, GBool limited, + Guint length, Object *dict) = 0; + virtual void setPos(Guint pos, int dir = 0) = 0; + virtual GBool isBinary(GBool last = gTrue) { return last; } + virtual BaseStream *getBaseStream() { return this; } + virtual Dict *getDict() { return dict.getDict(); } + + // Get/set position of first byte of stream within the file. + virtual Guint getStart() = 0; + virtual void moveStart(int delta) = 0; + + // Set decryption for this stream. + virtual void doDecryption(Guchar *fileKey, int keyLength, + int objNum, int objGen); + +protected: + + Decrypt *decrypt; + +private: + + Object dict; +}; + +//------------------------------------------------------------------------ +// FilterStream +// +// This is the base class for all streams that filter another stream. +//------------------------------------------------------------------------ + +class FilterStream: public Stream { +public: + + FilterStream(Stream *strA); + virtual ~FilterStream(); + virtual void close(); + virtual int getPos() { return str->getPos(); } + virtual void setPos(Guint pos, int dir = 0); + virtual BaseStream *getBaseStream() { return str->getBaseStream(); } + virtual Dict *getDict() { return str->getDict(); } + + // override those in specific filters when you add support for getBuf() + virtual GBool hasGetBuf() { return gFalse; } + virtual GBool getBuf(char **bufOut, int *bufSizeOut, int maxSize) { + assert(0); + return gFalse; + } + virtual void ungetBuf(int sizeToGoBack) { + assert(0); + } + +protected: + + Stream *str; +}; + +//------------------------------------------------------------------------ +// ImageStream +//------------------------------------------------------------------------ + +class ImageStream { +public: + + // Create an image stream object for an image with the specified + // parameters. Note that these are the actual image parameters, + // which may be different from the predictor parameters. + ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA); + + ~ImageStream(); + + // Reset the stream. + void reset(); + + // Gets the next pixel from the stream. should be able to hold + // at least nComps elements. Returns false at end of file. + GBool getPixel(Guchar *pix); + + // Returns a pointer to the next line of pixels. Returns NULL at + // end of file. + Guchar *getLine(); + + // Skip an entire line from the image. + void skipLine(); + +private: + + Stream *str; // base stream + int width; // pixels per line + int nComps; // components per pixel + int nBits; // bits per component + int nVals; // components per line + Guchar *imgLine; // line buffer + int imgIdx; // current index in imgLine +}; + +//------------------------------------------------------------------------ +// StreamPredictor +//------------------------------------------------------------------------ + +class StreamPredictor { +public: + + // Create a predictor object. Note that the parameters are for the + // predictor, and may not match the actual image parameters. + StreamPredictor(Stream *strA, int predictorA, + int widthA, int nCompsA, int nBitsA); + + ~StreamPredictor(); + + GBool isOk() { return ok; } + + int lookChar(); + int getChar(); + +private: + + GBool getNextLine(); + + Stream *str; // base stream + int predictor; // predictor + int width; // pixels per line + int nComps; // components per pixel + int nBits; // bits per component + int nVals; // components per line + int pixBytes; // bytes per pixel + int rowBytes; // bytes per line + Guchar *predLine; // line buffer + int predIdx; // current index in predLine + GBool ok; +}; + +//------------------------------------------------------------------------ +// FileStream +//------------------------------------------------------------------------ + +#define fileStreamBufSize 256 + +class FileStream: public BaseStream { +public: + + FileStream(FILE *fA, Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual ~FileStream(); + virtual Stream *makeSubStream(Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return strFile; } + virtual void reset(); + virtual void close(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart() { return start; } + virtual void moveStart(int delta); + + virtual GBool hasGetBuf(); + virtual GBool getBuf(char **bufOut, int *bufSizeOut, int maxSize); + virtual void ungetBuf(int sizeToGoBack); + +private: + + GBool fillBuf(); + + FILE *f; + Guint start; + GBool limited; + Guint length; + char buf[fileStreamBufSize]; + char *bufPtr; + char *bufEnd; + Guint bufPos; + int savePos; + GBool saved; +}; + +//------------------------------------------------------------------------ +// MemStream +//------------------------------------------------------------------------ + +class MemStream: public BaseStream { +public: + + MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA); + virtual ~MemStream(); + virtual Stream *makeSubStream(Guint start, GBool limited, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual void close(); + virtual int getChar() + { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; } + virtual int lookChar() + { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; } + virtual int getPos() { return (int)(bufPtr - buf); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart() { return start; } + virtual void moveStart(int delta); + virtual void doDecryption(Guchar *fileKey, int keyLength, + int objNum, int objGen); + + virtual GBool hasGetBuf() { return gFalse; } + virtual GBool getBuf(char **bufOut, int *bufSizeOut, int maxSize) { + assert(0); + return gFalse; + } + virtual void ungetBuf(int sizeToGoBack) { assert(0); } + +private: + + char *buf; + Guint start; + Guint length; + char *bufEnd; + char *bufPtr; + GBool needFree; +}; + +//------------------------------------------------------------------------ +// EmbedStream +// +// This is a special stream type used for embedded streams (inline +// images). It reads directly from the base stream -- after the +// EmbedStream is deleted, reads from the base stream will proceed where +// the BaseStream left off. Note that this is very different behavior +// that creating a new FileStream (using makeSubStream). +//------------------------------------------------------------------------ + +class EmbedStream: public BaseStream { +public: + + EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Guint lengthA); + virtual ~EmbedStream(); + virtual Stream *makeSubStream(Guint start, GBool limitedA, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return str->getKind(); } + virtual void reset() {} + virtual int getChar(); + virtual int lookChar(); + virtual int getPos() { return str->getPos(); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart(); + virtual void moveStart(int delta); + + virtual GBool hasGetBuf(); + virtual GBool getBuf(char **bufOut, int *bufSizeOut, int maxSize); + virtual void ungetBuf(int sizeToGoBack); + +private: + + Stream *str; + GBool limited; + Guint length; +}; + +//------------------------------------------------------------------------ +// ASCIIHexStream +//------------------------------------------------------------------------ + +class ASCIIHexStream: public FilterStream { +public: + + ASCIIHexStream(Stream *strA); + virtual ~ASCIIHexStream(); + virtual StreamKind getKind() { return strASCIIHex; } + virtual void reset(); + virtual int getChar() + { int c = lookChar(); buf = EOF; return c; } + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + int buf; + GBool eof; +}; + +//------------------------------------------------------------------------ +// ASCII85Stream +//------------------------------------------------------------------------ + +class ASCII85Stream: public FilterStream { +public: + + ASCII85Stream(Stream *strA); + virtual ~ASCII85Stream(); + virtual StreamKind getKind() { return strASCII85; } + virtual void reset(); + virtual int getChar() + { int ch = lookChar(); ++index; return ch; } + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + int c[5]; + int b[4]; + int index, n; + GBool eof; +}; + +//------------------------------------------------------------------------ +// LZWStream +//------------------------------------------------------------------------ + +class LZWStream: public FilterStream { +public: + + LZWStream(Stream *strA, int predictor, int columns, int colors, + int bits, int earlyA); + virtual ~LZWStream(); + virtual StreamKind getKind() { return strLZW; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getRawChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + StreamPredictor *pred; // predictor + int early; // early parameter + GBool eof; // true if at eof + int inputBuf; // input buffer + int inputBits; // number of bits in input buffer + struct { // decoding table + int length; + int head; + Guchar tail; + } table[4097]; + int nextCode; // next code to be used + int nextBits; // number of bits in next code word + int prevCode; // previous code used in stream + int newChar; // next char to be added to table + Guchar seqBuf[4097]; // buffer for current sequence + int seqLength; // length of current sequence + int seqIndex; // index into current sequence + GBool first; // first code after a table clear + + GBool processNextCode(); + void clearTable(); + int getCode(); +}; + +//------------------------------------------------------------------------ +// RunLengthStream +//------------------------------------------------------------------------ + +class RunLengthStream: public FilterStream { +public: + + RunLengthStream(Stream *strA); + virtual ~RunLengthStream(); + virtual StreamKind getKind() { return strRunLength; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + char buf[128]; // buffer + char *bufPtr; // next char to read + char *bufEnd; // end of buffer + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// CCITTFaxStream +//------------------------------------------------------------------------ + +struct CCITTCodeTable; + +class CCITTFaxStream: public FilterStream { +public: + + CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, + GBool byteAlignA, int columnsA, int rowsA, + GBool endOfBlockA, GBool blackA); + virtual ~CCITTFaxStream(); + virtual StreamKind getKind() { return strCCITTFax; } + virtual void reset(); + virtual int getChar() + { int c = lookChar(); buf = EOF; return c; } + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + int encoding; // 'K' parameter + GBool endOfLine; // 'EndOfLine' parameter + GBool byteAlign; // 'EncodedByteAlign' parameter + int columns; // 'Columns' parameter + int rows; // 'Rows' parameter + GBool endOfBlock; // 'EndOfBlock' parameter + GBool black; // 'BlackIs1' parameter + GBool eof; // true if at eof + GBool nextLine2D; // true if next line uses 2D encoding + int row; // current row + int inputBuf; // input buffer + int inputBits; // number of bits in input buffer + short *refLine; // reference line changing elements + int b1; // index into refLine + short *codingLine; // coding line changing elements + int a0; // index into codingLine + int outputBits; // remaining ouput bits + int buf; // character buffer + + short getTwoDimCode(); + short getWhiteCode(); + short getBlackCode(); + short lookBits(int n); + void eatBits(int n) { if ((inputBits -= n) < 0) inputBits = 0; } +}; + +#ifndef ENABLE_LIBJPEG +//------------------------------------------------------------------------ +// DCTStream +//------------------------------------------------------------------------ + +// DCT component info +struct DCTCompInfo { + int id; // component ID + int hSample, vSample; // horiz/vert sampling resolutions + int quantTable; // quantization table number + int prevDC; // DC coefficient accumulator +}; + +struct DCTScanInfo { + GBool comp[4]; // comp[i] is set if component i is + // included in this scan + int numComps; // number of components in the scan + int dcHuffTable[4]; // DC Huffman table numbers + int acHuffTable[4]; // AC Huffman table numbers + int firstCoeff, lastCoeff; // first and last DCT coefficient + int ah, al; // successive approximation parameters +}; + +// DCT Huffman decoding table +struct DCTHuffTable { + Guchar firstSym[17]; // first symbol for this bit length + Gushort firstCode[17]; // first code for this bit length + Gushort numCodes[17]; // number of codes of this bit length + Guchar sym[256]; // symbols +}; + +class DCTStream: public FilterStream { +public: + + DCTStream(Stream *strA); + virtual ~DCTStream(); + virtual StreamKind getKind() { return strDCT; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + Stream *getRawStream() { return str; } + +private: + + GBool progressive; // set if in progressive mode + GBool interleaved; // set if in interleaved mode + int width, height; // image size + int mcuWidth, mcuHeight; // size of min coding unit, in data units + int bufWidth, bufHeight; // frameBuf size + DCTCompInfo compInfo[4]; // info for each component + DCTScanInfo scanInfo; // info for the current scan + int numComps; // number of components in image + int colorXform; // need YCbCr-to-RGB transform? + GBool gotJFIFMarker; // set if APP0 JFIF marker was present + GBool gotAdobeMarker; // set if APP14 Adobe marker was present + int restartInterval; // restart interval, in MCUs + Gushort quantTables[4][64]; // quantization tables + int numQuantTables; // number of quantization tables + DCTHuffTable dcHuffTables[4]; // DC Huffman tables + DCTHuffTable acHuffTables[4]; // AC Huffman tables + int numDCHuffTables; // number of DC Huffman tables + int numACHuffTables; // number of AC Huffman tables + Guchar *rowBuf[4][32]; // buffer for one MCU (non-progressive mode) + int *frameBuf[4]; // buffer for frame (progressive mode) + int comp, x, y, dy; // current position within image/MCU + int restartCtr; // MCUs left until restart + int restartMarker; // next restart marker + int eobRun; // number of EOBs left in the current run + int inputBuf; // input buffer for variable length codes + int inputBits; // number of valid bits in input buffer + + void restart(); + GBool readMCURow(); + void readScan(); + GBool readDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]); + GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]); + void decodeImage(); + void transformDataUnit(Gushort *quantTable, + int dataIn[64], Guchar dataOut[64]); + int readHuffSym(DCTHuffTable *table); + int readAmp(int size); + int readBit(); + GBool readHeader(); + GBool readBaselineSOF(); + GBool readProgressiveSOF(); + GBool readScanInfo(); + GBool readQuantTables(); + GBool readHuffmanTables(); + GBool readRestartInterval(); + GBool readJFIFMarker(); + GBool readAdobeMarker(); + GBool readTrailer(); + int readMarker(); + int read16(); +}; +#endif + +#ifndef ENABLE_ZLIB +//------------------------------------------------------------------------ +// FlateStream +//------------------------------------------------------------------------ + +#define flateWindow 32768 // buffer size +#define flateMask (flateWindow-1) +#define flateMaxHuffman 15 // max Huffman code length +#define flateMaxCodeLenCodes 19 // max # code length codes +#define flateMaxLitCodes 288 // max # literal codes +#define flateMaxDistCodes 30 // max # distance codes + +// Huffman code table entry +struct FlateCode { + Gushort len; // code length, in bits + Gushort val; // value represented by this code +}; + +struct FlateHuffmanTab { + FlateCode *codes; + int maxLen; +}; + +// Decoding info for length and distance code words +struct FlateDecode { + int bits; // # extra bits + int first; // first length/distance +}; + +class FlateStream: public FilterStream { +public: + + FlateStream(Stream *strA, int predictor, int columns, + int colors, int bits); + virtual ~FlateStream(); + virtual StreamKind getKind() { return strFlate; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getRawChar(); + virtual GooString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + + virtual GBool hasGetBuf(); + virtual GBool getBuf(char **bufOut, int *bufSizeOut, int maxSize); + virtual void ungetBuf(int sizeToGoBack); + +private: + + StreamPredictor *pred; // predictor + Guchar buf[flateWindow]; // output data buffer + int index; // current index into output buffer + int remain; // number valid bytes in output buffer + int codeBuf; // input buffer + int codeSize; // number of bits in input buffer + int // literal and distance code lengths + codeLengths[flateMaxLitCodes + flateMaxDistCodes]; + FlateHuffmanTab litCodeTab; // literal code table + FlateHuffmanTab distCodeTab; // distance code table + GBool compressedBlock; // set if reading a compressed block + int blockLen; // remaining length of uncompressed block + GBool endOfBlock; // set when end of block is reached + GBool eof; // set when end of stream is reached + + static int // code length code reordering + codeLenCodeMap[flateMaxCodeLenCodes]; + static FlateDecode // length decoding info + lengthDecode[flateMaxLitCodes-257]; + static FlateDecode // distance decoding info + distDecode[flateMaxDistCodes]; + static FlateHuffmanTab // fixed literal code table + fixedLitCodeTab; + static FlateHuffmanTab // fixed distance code table + fixedDistCodeTab; + + void readSome(); + GBool startBlock(); + void loadFixedCodes(); + GBool readDynamicCodes(); + void compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab); + int getHuffmanCodeWord(FlateHuffmanTab *tab); + int getCodeWord(int bits); +}; +#endif + +//------------------------------------------------------------------------ +// EOFStream +//------------------------------------------------------------------------ + +class EOFStream: public FilterStream { +public: + + EOFStream(Stream *strA); + virtual ~EOFStream(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset() {} + virtual int getChar() { return EOF; } + virtual int lookChar() { return EOF; } + virtual GooString *getPSFilter(int /*psLevel*/, char * /*indent*/) { return NULL; } + virtual GBool isBinary(GBool /*last = gTrue*/) { return gFalse; } +}; + +//------------------------------------------------------------------------ +// FixedLengthEncoder +//------------------------------------------------------------------------ + +class FixedLengthEncoder: public FilterStream { +public: + + FixedLengthEncoder(Stream *strA, int lengthA); + ~FixedLengthEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GooString *getPSFilter(int /*psLevel*/, char * /*indent*/) { return NULL; } + virtual GBool isBinary(GBool /*last = gTrue*/); + virtual GBool isEncoder() { return gTrue; } + +private: + + int length; + int count; +}; + +//------------------------------------------------------------------------ +// ASCIIHexEncoder +//------------------------------------------------------------------------ + +class ASCIIHexEncoder: public FilterStream { +public: + + ASCIIHexEncoder(Stream *strA); + virtual ~ASCIIHexEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GooString *getPSFilter(int /*psLevel*/, char * /*indent*/) { return NULL; } + virtual GBool isBinary(GBool /*last = gTrue*/) { return gFalse; } + virtual GBool isEncoder() { return gTrue; } + +private: + + char buf[4]; + char *bufPtr; + char *bufEnd; + int lineLen; + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// ASCII85Encoder +//------------------------------------------------------------------------ + +class ASCII85Encoder: public FilterStream { +public: + + ASCII85Encoder(Stream *strA); + virtual ~ASCII85Encoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GooString *getPSFilter(int /*psLevel*/, char * /*indent*/) { return NULL; } + virtual GBool isBinary(GBool /*last = gTrue*/) { return gFalse; } + virtual GBool isEncoder() { return gTrue; } + +private: + + char buf[8]; + char *bufPtr; + char *bufEnd; + int lineLen; + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// RunLengthEncoder +//------------------------------------------------------------------------ + +class RunLengthEncoder: public FilterStream { +public: + + RunLengthEncoder(Stream *strA); + virtual ~RunLengthEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GooString *getPSFilter(int /*psLevel*/, char * /*indent*/) { return NULL; } + virtual GBool isBinary(GBool /*last = gTrue*/) { return gTrue; } + virtual GBool isEncoder() { return gTrue; } + +private: + + char buf[131]; + char *bufPtr; + char *bufEnd; + char *nextEnd; + GBool eof; + + GBool fillBuf(); +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/TextOutputDev.cc b/rosapps/smartpdf/poppler/poppler/TextOutputDev.cc new file mode 100644 index 00000000000..118d3f021f8 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/TextOutputDev.cc @@ -0,0 +1,4247 @@ +//======================================================================== +// +// TextOutputDev.cc +// +// Copyright 1997-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#ifdef WIN32 +#include // for O_BINARY +#include // for setmode +#endif +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "poppler-config.h" +#include "Error.h" +#include "GlobalParams.h" +#include "UnicodeMap.h" +#include "UnicodeTypeTable.h" +#include "TextOutputDev.h" +#include "Page.h" + +#ifdef MACOS +// needed for setting type/creator of MacOS files +#include "ICSupport.h" +#endif + +//------------------------------------------------------------------------ +// parameters +//------------------------------------------------------------------------ + +// Each bucket in a text pool includes baselines within a range of +// this many points. +#define textPoolStep 4 + +// Inter-character space width which will cause addChar to start a new +// word. +#define minWordBreakSpace 0.1 + +// Negative inter-character space width, i.e., overlap, which will +// cause addChar to start a new word. +#define minDupBreakOverlap 0.2 + +// Max distance between baselines of two lines within a block, as a +// fraction of the font size. +#define maxLineSpacingDelta 1.5 + +// Max difference in primary font sizes on two lines in the same +// block. Delta1 is used when examining new lines above and below the +// current block; delta2 is used when examining text that overlaps the +// current block; delta3 is used when examining text to the left and +// right of the current block. +#define maxBlockFontSizeDelta1 0.05 +#define maxBlockFontSizeDelta2 0.6 +#define maxBlockFontSizeDelta3 0.2 + +// Max difference in font sizes inside a word. +#define maxWordFontSizeDelta 0.05 + +// Maximum distance between baselines of two words on the same line, +// e.g., distance between subscript or superscript and the primary +// baseline, as a fraction of the font size. +#define maxIntraLineDelta 0.5 + +// Minimum inter-word spacing, as a fraction of the font size. (Only +// used for raw ordering.) +#define minWordSpacing 0.15 + +// Maximum inter-word spacing, as a fraction of the font size. +#define maxWordSpacing 1.5 + +// Maximum horizontal spacing which will allow a word to be pulled +// into a block. +#define minColSpacing1 0.3 + +// Minimum spacing between columns, as a fraction of the font size. +#define minColSpacing2 1.0 + +// Maximum vertical spacing between blocks within a flow, as a +// multiple of the font size. +#define maxBlockSpacing 2.5 + +// Minimum spacing between characters within a word, as a fraction of +// the font size. +#define minCharSpacing -0.2 + +// Maximum spacing between characters within a word, as a fraction of +// the font size, when there is no obvious extra-wide character +// spacing. +#define maxCharSpacing 0.03 + +// When extra-wide character spacing is detected, the inter-character +// space threshold is set to the minimum inter-character space +// multiplied by this constant. +#define maxWideCharSpacingMul 1.3 + +// Max difference in primary,secondary coordinates (as a fraction of +// the font size) allowed for duplicated text (fake boldface, drop +// shadows) which is to be discarded. +#define dupMaxPriDelta 0.1 +#define dupMaxSecDelta 0.2 + +//------------------------------------------------------------------------ +// TextFontInfo +//------------------------------------------------------------------------ + +TextFontInfo::TextFontInfo(GfxState *state) { + gfxFont = state->getFont(); + if (gfxFont) + gfxFont->incRefCnt(); +#if TEXTOUT_WORD_LIST + fontName = (gfxFont && gfxFont->getOrigName()) + ? gfxFont->getOrigName()->copy() + : (GooString *)NULL; +#endif +} + +TextFontInfo::~TextFontInfo() { + if (gfxFont) + gfxFont->decRefCnt(); +#if TEXTOUT_WORD_LIST + if (fontName) { + delete fontName; + } +#endif +} + +GBool TextFontInfo::matches(GfxState *state) { + return state->getFont() == gfxFont; +} + +//------------------------------------------------------------------------ +// TextWord +//------------------------------------------------------------------------ + +TextWord::TextWord(GfxState *state, int rotA, double x0, double y0, + int charPosA, TextFontInfo *fontA, double fontSizeA) { + GfxFont *gfxFont; + double x, y, ascent, descent; + + rot = rotA; + charPos = charPosA; + charLen = 0; + font = fontA; + fontSize = fontSizeA; + state->transform(x0, y0, &x, &y); + if ((gfxFont = font->gfxFont)) { + ascent = gfxFont->getAscent() * fontSize; + descent = gfxFont->getDescent() * fontSize; + } else { + // this means that the PDF file draws text without a current font, + // which should never happen + ascent = 0.95 * fontSize; + descent = -0.35 * fontSize; + } + switch (rot) { + case 0: + yMin = y - ascent; + yMax = y - descent; + if (yMin == yMax) { + // this is a sanity check for a case that shouldn't happen -- but + // if it does happen, we want to avoid dividing by zero later + yMin = y; + yMax = y + 1; + } + base = y; + break; + case 1: + xMin = x + descent; + xMax = x + ascent; + if (xMin == xMax) { + // this is a sanity check for a case that shouldn't happen -- but + // if it does happen, we want to avoid dividing by zero later + xMin = x; + xMax = x + 1; + } + base = x; + break; + case 2: + yMin = y + descent; + yMax = y + ascent; + if (yMin == yMax) { + // this is a sanity check for a case that shouldn't happen -- but + // if it does happen, we want to avoid dividing by zero later + yMin = y; + yMax = y + 1; + } + base = y; + break; + case 3: + xMin = x - ascent; + xMax = x - descent; + if (xMin == xMax) { + // this is a sanity check for a case that shouldn't happen -- but + // if it does happen, we want to avoid dividing by zero later + xMin = x; + xMax = x + 1; + } + base = x; + break; + } + text = NULL; + charcode = NULL; + edge = NULL; + len = size = 0; + spaceAfter = gFalse; + next = NULL; + +#if TEXTOUT_WORD_LIST + GfxRGB rgb; + + if ((state->getRender() & 3) == 1) { + state->getStrokeRGB(&rgb); + } else { + state->getFillRGB(&rgb); + } + colorR = colToDbl(rgb.r); + colorG = colToDbl(rgb.g); + colorB = colToDbl(rgb.b); +#endif +} + +TextWord::~TextWord() { + gfree(text); + gfree(charcode); + gfree(edge); +} + +void TextWord::addChar(GfxState *state, double x, double y, + double dx, double dy, CharCode c, Unicode u) { + if (len == size) { + size += 16; + text = (Unicode *)greallocn(text, size, sizeof(Unicode)); + charcode = (Unicode *)greallocn(charcode, size, sizeof(CharCode)); + edge = (double *)greallocn(edge, (size + 1), sizeof(double)); + } + text[len] = u; + charcode[len] = c; + switch (rot) { + case 0: + if (len == 0) { + xMin = x; + } + edge[len] = x; + xMax = edge[len+1] = x + dx; + break; + case 1: + if (len == 0) { + yMin = y; + } + edge[len] = y; + yMax = edge[len+1] = y + dy; + break; + case 2: + if (len == 0) { + xMax = x; + } + edge[len] = x; + xMin = edge[len+1] = x + dx; + break; + case 3: + if (len == 0) { + yMax = y; + } + edge[len] = y; + yMin = edge[len+1] = y + dy; + break; + } + ++len; +} + +void TextWord::merge(TextWord *word) { + int i; + + if (word->xMin < xMin) { + xMin = word->xMin; + } + if (word->yMin < yMin) { + yMin = word->yMin; + } + if (word->xMax > xMax) { + xMax = word->xMax; + } + if (word->yMax > yMax) { + yMax = word->yMax; + } + if (len + word->len > size) { + size = len + word->len; + text = (Unicode *)greallocn(text, size, sizeof(Unicode)); + charcode = (CharCode *)greallocn(charcode, (size + 1), sizeof(CharCode)); + edge = (double *)greallocn(edge, (size + 1), sizeof(double)); + } + for (i = 0; i < word->len; ++i) { + text[len + i] = word->text[i]; + charcode[len + i] = word->charcode[i]; + edge[len + i] = word->edge[i]; + } + edge[len + word->len] = word->edge[word->len]; + len += word->len; + charLen += word->charLen; +} + +inline int TextWord::primaryCmp(TextWord *word) { + double cmp; + + cmp = 0; // make gcc happy + switch (rot) { + case 0: + cmp = xMin - word->xMin; + break; + case 1: + cmp = yMin - word->yMin; + break; + case 2: + cmp = word->xMax - xMax; + break; + case 3: + cmp = word->yMax - yMax; + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +double TextWord::primaryDelta(TextWord *word) { + double delta; + + delta = 0; // make gcc happy + switch (rot) { + case 0: + delta = word->xMin - xMax; + break; + case 1: + delta = word->yMin - yMax; + break; + case 2: + delta = xMin - word->xMax; + break; + case 3: + delta = yMin - word->yMax; + break; + } + return delta; +} + +int TextWord::cmpYX(const void *p1, const void *p2) { + TextWord *word1 = *(TextWord **)p1; + TextWord *word2 = *(TextWord **)p2; + double cmp; + + cmp = word1->yMin - word2->yMin; + if (cmp == 0) { + cmp = word1->xMin - word2->xMin; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +#if TEXTOUT_WORD_LIST + +GooString *TextWord::getText() { + GooString *s; + UnicodeMap *uMap; + char buf[8]; + int n, i; + + s = new GooString(); + if (!(uMap = globalParams->getTextEncoding())) { + return s; + } + for (i = 0; i < len; ++i) { + n = uMap->mapUnicode(text[i], buf, sizeof(buf)); + s->append(buf, n); + } + uMap->decRefCnt(); + return s; +} + +#endif // TEXTOUT_WORD_LIST + +//------------------------------------------------------------------------ +// TextPool +//------------------------------------------------------------------------ + +TextPool::TextPool() { + minBaseIdx = 0; + maxBaseIdx = -1; + pool = NULL; + cursor = NULL; + cursorBaseIdx = -1; +} + +TextPool::~TextPool() { + int baseIdx; + TextWord *word, *word2; + + for (baseIdx = minBaseIdx; baseIdx <= maxBaseIdx; ++baseIdx) { + for (word = pool[baseIdx - minBaseIdx]; word; word = word2) { + word2 = word->next; + delete word; + } + } + gfree(pool); +} + +int TextPool::getBaseIdx(double base) { + int baseIdx; + + baseIdx = (int)(base / textPoolStep); + if (baseIdx < minBaseIdx) { + return minBaseIdx; + } + if (baseIdx > maxBaseIdx) { + return maxBaseIdx; + } + return baseIdx; +} + +void TextPool::addWord(TextWord *word) { + TextWord **newPool; + int wordBaseIdx, newMinBaseIdx, newMaxBaseIdx, baseIdx; + TextWord *w0, *w1; + + // expand the array if needed + wordBaseIdx = (int)(word->base / textPoolStep); + if (minBaseIdx > maxBaseIdx) { + minBaseIdx = wordBaseIdx - 128; + maxBaseIdx = wordBaseIdx + 128; + pool = (TextWord **)gmallocn(maxBaseIdx - minBaseIdx + 1, + sizeof(TextWord *)); + for (baseIdx = minBaseIdx; baseIdx <= maxBaseIdx; ++baseIdx) { + pool[baseIdx - minBaseIdx] = NULL; + } + } else if (wordBaseIdx < minBaseIdx) { + newMinBaseIdx = wordBaseIdx - 128; + newPool = (TextWord **)gmallocn(maxBaseIdx - newMinBaseIdx + 1, + sizeof(TextWord *)); + for (baseIdx = newMinBaseIdx; baseIdx < minBaseIdx; ++baseIdx) { + newPool[baseIdx - newMinBaseIdx] = NULL; + } + memcpy(&newPool[minBaseIdx - newMinBaseIdx], pool, + (maxBaseIdx - minBaseIdx + 1) * sizeof(TextWord *)); + gfree(pool); + pool = newPool; + minBaseIdx = newMinBaseIdx; + } else if (wordBaseIdx > maxBaseIdx) { + newMaxBaseIdx = wordBaseIdx + 128; + pool = (TextWord **)greallocn(pool, newMaxBaseIdx - minBaseIdx + 1, + sizeof(TextWord *)); + for (baseIdx = maxBaseIdx + 1; baseIdx <= newMaxBaseIdx; ++baseIdx) { + pool[baseIdx - minBaseIdx] = NULL; + } + maxBaseIdx = newMaxBaseIdx; + } + + // insert the new word + if (cursor && wordBaseIdx == cursorBaseIdx && + word->primaryCmp(cursor) > 0) { + w0 = cursor; + w1 = cursor->next; + } else { + w0 = NULL; + w1 = pool[wordBaseIdx - minBaseIdx]; + } + for (; w1 && word->primaryCmp(w1) > 0; w0 = w1, w1 = w1->next) ; + word->next = w1; + if (w0) { + w0->next = word; + } else { + pool[wordBaseIdx - minBaseIdx] = word; + } + cursor = word; + cursorBaseIdx = wordBaseIdx; +} + +//------------------------------------------------------------------------ +// TextLine +//------------------------------------------------------------------------ + +TextLine::TextLine(TextBlock *blkA, int rotA, double baseA) { + blk = blkA; + rot = rotA; + base = baseA; + words = lastWord = NULL; + text = NULL; + edge = NULL; + col = NULL; + len = 0; + convertedLen = 0; + hyphenated = gFalse; + next = NULL; + xMin = yMin = 0; + xMax = yMax = -1; + normalized = NULL; + normalized_len = 0; + normalized_idx = NULL; +} + +TextLine::~TextLine() { + TextWord *word; + + while (words) { + word = words; + words = words->next; + delete word; + } + gfree(text); + gfree(edge); + gfree(col); + if (normalized) { + gfree(normalized); + gfree(normalized_idx); + } +} + +void TextLine::addWord(TextWord *word) { + if (lastWord) { + lastWord->next = word; + } else { + words = word; + } + lastWord = word; + + if (xMin > xMax) { + xMin = word->xMin; + xMax = word->xMax; + yMin = word->yMin; + yMax = word->yMax; + } else { + if (word->xMin < xMin) { + xMin = word->xMin; + } + if (word->xMax > xMax) { + xMax = word->xMax; + } + if (word->yMin < yMin) { + yMin = word->yMin; + } + if (word->yMax > yMax) { + yMax = word->yMax; + } + } +} + +double TextLine::primaryDelta(TextLine *line) { + double delta; + + delta = 0; // make gcc happy + switch (rot) { + case 0: + delta = line->xMin - xMax; + break; + case 1: + delta = line->yMin - yMax; + break; + case 2: + delta = xMin - line->xMax; + break; + case 3: + delta = yMin - line->yMax; + break; + } + return delta; +} + +int TextLine::primaryCmp(TextLine *line) { + double cmp; + + cmp = 0; // make gcc happy + switch (rot) { + case 0: + cmp = xMin - line->xMin; + break; + case 1: + cmp = yMin - line->yMin; + break; + case 2: + cmp = line->xMax - xMax; + break; + case 3: + cmp = line->yMax - yMax; + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +int TextLine::secondaryCmp(TextLine *line) { + double cmp; + + cmp = (rot == 0 || rot == 3) ? base - line->base : line->base - base; + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +int TextLine::cmpYX(TextLine *line) { + int cmp; + + if ((cmp = secondaryCmp(line))) { + return cmp; + } + return primaryCmp(line); +} + +int TextLine::cmpXY(const void *p1, const void *p2) { + TextLine *line1 = *(TextLine **)p1; + TextLine *line2 = *(TextLine **)p2; + int cmp; + + if ((cmp = line1->primaryCmp(line2))) { + return cmp; + } + return line1->secondaryCmp(line2); +} + +void TextLine::coalesce(UnicodeMap *uMap) { + TextWord *word0, *word1; + double space, delta, minSpace; + GBool isUnicode; + char buf[8]; + int i, j; + + if (words->next) { + + // compute the inter-word space threshold + if (words->len > 1 || words->next->len > 1) { + minSpace = 0; + } else { + minSpace = words->primaryDelta(words->next); + for (word0 = words->next, word1 = word0->next; + word1 && minSpace > 0; + word0 = word1, word1 = word0->next) { + if (word1->len > 1) { + minSpace = 0; + } + delta = word0->primaryDelta(word1); + if (delta < minSpace) { + minSpace = delta; + } + } + } + if (minSpace <= 0) { + space = maxCharSpacing * words->fontSize; + } else { + space = maxWideCharSpacingMul * minSpace; + } + + // merge words + word0 = words; + word1 = words->next; + while (word1) { + if (word0->primaryDelta(word1) >= space) { + word0->spaceAfter = gTrue; + word0 = word1; + word1 = word1->next; + } else if (word0->font == word1->font && + fabs(word0->fontSize - word1->fontSize) < + maxWordFontSizeDelta * words->fontSize && + word1->charPos == word0->charPos + word0->charLen) { + word0->merge(word1); + word0->next = word1->next; + delete word1; + word1 = word0->next; + } else { + word0 = word1; + word1 = word1->next; + } + } + } + + // build the line text + isUnicode = uMap ? uMap->isUnicode() : gFalse; + len = 0; + for (word1 = words; word1; word1 = word1->next) { + len += word1->len; + if (word1->spaceAfter) { + ++len; + } + } + text = (Unicode *)gmallocn(len, sizeof(Unicode)); + edge = (double *)gmallocn(len + 1, sizeof(double)); + i = 0; + for (word1 = words; word1; word1 = word1->next) { + for (j = 0; j < word1->len; ++j) { + text[i] = word1->text[j]; + edge[i] = word1->edge[j]; + ++i; + } + edge[i] = word1->edge[word1->len]; + if (word1->spaceAfter) { + text[i] = (Unicode)0x0020; + ++i; + } + } + + // compute convertedLen and set up the col array + col = (int *)gmallocn(len + 1, sizeof(int)); + convertedLen = 0; + for (i = 0; i < len; ++i) { + col[i] = convertedLen; + if (isUnicode) { + ++convertedLen; + } else if (uMap) { + convertedLen += uMap->mapUnicode(text[i], buf, sizeof(buf)); + } + } + col[len] = convertedLen; + + // check for hyphen at end of line + //~ need to check for other chars used as hyphens + hyphenated = text[len - 1] == (Unicode)'-'; +} + +//------------------------------------------------------------------------ +// TextLineFrag +//------------------------------------------------------------------------ + +class TextLineFrag { +public: + + TextLine *line; // the line object + int start, len; // offset and length of this fragment + // (in Unicode chars) + double xMin, xMax; // bounding box coordinates + double yMin, yMax; + double base; // baseline virtual coordinate + int col; // first column + + void init(TextLine *lineA, int startA, int lenA); + void computeCoords(GBool oneRot); + + static int cmpYXPrimaryRot(const void *p1, const void *p2); + static int cmpYXLineRot(const void *p1, const void *p2); + static int cmpXYLineRot(const void *p1, const void *p2); +}; + +void TextLineFrag::init(TextLine *lineA, int startA, int lenA) { + line = lineA; + start = startA; + len = lenA; + col = line->col[start]; +} + +void TextLineFrag::computeCoords(GBool oneRot) { + TextBlock *blk; + double d0, d1, d2, d3, d4; + + if (oneRot) { + + switch (line->rot) { + case 0: + xMin = line->edge[start]; + xMax = line->edge[start + len]; + yMin = line->yMin; + yMax = line->yMax; + break; + case 1: + xMin = line->xMin; + xMax = line->xMax; + yMin = line->edge[start]; + yMax = line->edge[start + len]; + break; + case 2: + xMin = line->edge[start + len]; + xMax = line->edge[start]; + yMin = line->yMin; + yMax = line->yMax; + break; + case 3: + xMin = line->xMin; + xMax = line->xMax; + yMin = line->edge[start + len]; + yMax = line->edge[start]; + break; + } + base = line->base; + + } else { + + if (line->rot == 0 && line->blk->page->primaryRot == 0) { + + xMin = line->edge[start]; + xMax = line->edge[start + len]; + yMin = line->yMin; + yMax = line->yMax; + base = line->base; + + } else { + + blk = line->blk; + d0 = line->edge[start]; + d1 = line->edge[start + len]; + d2 = d3 = d4 = 0; // make gcc happy + + switch (line->rot) { + case 0: + d2 = line->yMin; + d3 = line->yMax; + d4 = line->base; + d0 = (d0 - blk->xMin) / (blk->xMax - blk->xMin); + d1 = (d1 - blk->xMin) / (blk->xMax - blk->xMin); + d2 = (d2 - blk->yMin) / (blk->yMax - blk->yMin); + d3 = (d3 - blk->yMin) / (blk->yMax - blk->yMin); + d4 = (d4 - blk->yMin) / (blk->yMax - blk->yMin); + break; + case 1: + d2 = line->xMax; + d3 = line->xMin; + d4 = line->base; + d0 = (d0 - blk->yMin) / (blk->yMax - blk->yMin); + d1 = (d1 - blk->yMin) / (blk->yMax - blk->yMin); + d2 = (blk->xMax - d2) / (blk->xMax - blk->xMin); + d3 = (blk->xMax - d3) / (blk->xMax - blk->xMin); + d4 = (blk->xMax - d4) / (blk->xMax - blk->xMin); + break; + case 2: + d2 = line->yMax; + d3 = line->yMin; + d4 = line->base; + d0 = (blk->xMax - d0) / (blk->xMax - blk->xMin); + d1 = (blk->xMax - d1) / (blk->xMax - blk->xMin); + d2 = (blk->yMax - d2) / (blk->yMax - blk->yMin); + d3 = (blk->yMax - d3) / (blk->yMax - blk->yMin); + d4 = (blk->yMax - d4) / (blk->yMax - blk->yMin); + break; + case 3: + d2 = line->xMin; + d3 = line->xMax; + d4 = line->base; + d0 = (blk->yMax - d0) / (blk->yMax - blk->yMin); + d1 = (blk->yMax - d1) / (blk->yMax - blk->yMin); + d2 = (d2 - blk->xMin) / (blk->xMax - blk->xMin); + d3 = (d3 - blk->xMin) / (blk->xMax - blk->xMin); + d4 = (d4 - blk->xMin) / (blk->xMax - blk->xMin); + break; + } + + switch (line->blk->page->primaryRot) { + case 0: + xMin = blk->xMin + d0 * (blk->xMax - blk->xMin); + xMax = blk->xMin + d1 * (blk->xMax - blk->xMin); + yMin = blk->yMin + d2 * (blk->yMax - blk->yMin); + yMax = blk->yMin + d3 * (blk->yMax - blk->yMin); + base = blk->yMin + base * (blk->yMax - blk->yMin); + break; + case 1: + xMin = blk->xMax - d3 * (blk->xMax - blk->xMin); + xMax = blk->xMax - d2 * (blk->xMax - blk->xMin); + yMin = blk->yMin + d0 * (blk->yMax - blk->yMin); + yMax = blk->yMin + d1 * (blk->yMax - blk->yMin); + base = blk->xMax - d4 * (blk->xMax - blk->xMin); + break; + case 2: + xMin = blk->xMax - d1 * (blk->xMax - blk->xMin); + xMax = blk->xMax - d0 * (blk->xMax - blk->xMin); + yMin = blk->yMax - d3 * (blk->yMax - blk->yMin); + yMax = blk->yMax - d2 * (blk->yMax - blk->yMin); + base = blk->yMax - d4 * (blk->yMax - blk->yMin); + break; + case 3: + xMin = blk->xMin + d2 * (blk->xMax - blk->xMin); + xMax = blk->xMin + d3 * (blk->xMax - blk->xMin); + yMin = blk->yMax - d1 * (blk->yMax - blk->yMin); + yMax = blk->yMax - d0 * (blk->yMax - blk->yMin); + base = blk->xMin + d4 * (blk->xMax - blk->xMin); + break; + } + + } + } +} + +int TextLineFrag::cmpYXPrimaryRot(const void *p1, const void *p2) { + TextLineFrag *frag1 = (TextLineFrag *)p1; + TextLineFrag *frag2 = (TextLineFrag *)p2; + double cmp; + + cmp = 0; // make gcc happy + switch (frag1->line->blk->page->primaryRot) { + case 0: + if (fabs(cmp = frag1->yMin - frag2->yMin) < 0.01) { + cmp = frag1->xMin - frag2->xMin; + } + break; + case 1: + if (fabs(cmp = frag2->xMax - frag1->xMax) < 0.01) { + cmp = frag1->yMin - frag2->yMin; + } + break; + case 2: + if (fabs(cmp = frag2->yMin - frag1->yMin) < 0.01) { + cmp = frag2->xMax - frag1->xMax; + } + break; + case 3: + if (fabs(cmp = frag1->xMax - frag2->xMax) < 0.01) { + cmp = frag2->yMax - frag1->yMax; + } + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +int TextLineFrag::cmpYXLineRot(const void *p1, const void *p2) { + TextLineFrag *frag1 = (TextLineFrag *)p1; + TextLineFrag *frag2 = (TextLineFrag *)p2; + double cmp; + + cmp = 0; // make gcc happy + switch (frag1->line->rot) { + case 0: + if ((cmp = frag1->yMin - frag2->yMin) == 0) { + cmp = frag1->xMin - frag2->xMin; + } + break; + case 1: + if ((cmp = frag2->xMax - frag1->xMax) == 0) { + cmp = frag1->yMin - frag2->yMin; + } + break; + case 2: + if ((cmp = frag2->yMin - frag1->yMin) == 0) { + cmp = frag2->xMax - frag1->xMax; + } + break; + case 3: + if ((cmp = frag1->xMax - frag2->xMax) == 0) { + cmp = frag2->yMax - frag1->yMax; + } + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +int TextLineFrag::cmpXYLineRot(const void *p1, const void *p2) { + TextLineFrag *frag1 = (TextLineFrag *)p1; + TextLineFrag *frag2 = (TextLineFrag *)p2; + double cmp; + + cmp = 0; // make gcc happy + switch (frag1->line->rot) { + case 0: + if ((cmp = frag1->xMin - frag2->xMin) == 0) { + cmp = frag1->yMin - frag2->yMin; + } + break; + case 1: + if ((cmp = frag1->yMin - frag2->yMin) == 0) { + cmp = frag2->xMax - frag1->xMax; + } + break; + case 2: + if ((cmp = frag2->xMax - frag1->xMax) == 0) { + cmp = frag2->yMin - frag1->yMin; + } + break; + case 3: + if ((cmp = frag2->yMax - frag1->yMax) == 0) { + cmp = frag1->xMax - frag2->xMax; + } + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +//------------------------------------------------------------------------ +// TextBlock +//------------------------------------------------------------------------ + +TextBlock::TextBlock(TextPage *pageA, int rotA) { + page = pageA; + rot = rotA; + xMin = yMin = 0; + xMax = yMax = -1; + priMin = 0; + priMax = page->pageWidth; + pool = new TextPool(); + lines = NULL; + curLine = NULL; + next = NULL; + stackNext = NULL; +} + +TextBlock::~TextBlock() { + TextLine *line; + + delete pool; + while (lines) { + line = lines; + lines = lines->next; + delete line; + } +} + +void TextBlock::addWord(TextWord *word) { + pool->addWord(word); + if (xMin > xMax) { + xMin = word->xMin; + xMax = word->xMax; + yMin = word->yMin; + yMax = word->yMax; + } else { + if (word->xMin < xMin) { + xMin = word->xMin; + } + if (word->xMax > xMax) { + xMax = word->xMax; + } + if (word->yMin < yMin) { + yMin = word->yMin; + } + if (word->yMax > yMax) { + yMax = word->yMax; + } + } +} + +void TextBlock::coalesce(UnicodeMap *uMap) { + TextWord *word0, *word1, *word2, *bestWord0, *bestWord1, *lastWord; + TextLine *line, *line0, *line1; + int poolMinBaseIdx, startBaseIdx, minBaseIdx, maxBaseIdx; + int baseIdx, bestWordBaseIdx, idx0, idx1; + double minBase, maxBase; + double fontSize, delta, priDelta, secDelta; + TextLine **lineArray; + GBool found; + int col1, col2; + int i, j, k; + + // discard duplicated text (fake boldface, drop shadows) + for (idx0 = pool->minBaseIdx; idx0 <= pool->maxBaseIdx; ++idx0) { + word0 = pool->getPool(idx0); + while (word0) { + priDelta = dupMaxPriDelta * word0->fontSize; + secDelta = dupMaxSecDelta * word0->fontSize; + if (rot == 0 || rot == 3) { + maxBaseIdx = pool->getBaseIdx(word0->base + secDelta); + } else { + maxBaseIdx = pool->getBaseIdx(word0->base - secDelta); + } + found = gFalse; + word1 = word2 = NULL; // make gcc happy + for (idx1 = idx0; idx1 <= maxBaseIdx; ++idx1) { + if (idx1 == idx0) { + word1 = word0; + word2 = word0->next; + } else { + word1 = NULL; + word2 = pool->getPool(idx1); + } + for (; word2; word1 = word2, word2 = word2->next) { + if (word2->len == word0->len && + !memcmp(word2->text, word0->text, + word0->len * sizeof(Unicode))) { + switch (rot) { + case 0: + case 2: + found = fabs(word0->xMin - word2->xMin) < priDelta && + fabs(word0->xMax - word2->xMax) < priDelta && + fabs(word0->yMin - word2->yMin) < secDelta && + fabs(word0->yMax - word2->yMax) < secDelta; + break; + case 1: + case 3: + found = fabs(word0->xMin - word2->xMin) < secDelta && + fabs(word0->xMax - word2->xMax) < secDelta && + fabs(word0->yMin - word2->yMin) < priDelta && + fabs(word0->yMax - word2->yMax) < priDelta; + break; + } + } + if (found) { + break; + } + } + if (found) { + break; + } + } + if (found) { + if (word1) { + word1->next = word2->next; + } else { + pool->setPool(idx1, word2->next); + } + delete word2; + } else { + word0 = word0->next; + } + } + } + + // build the lines + curLine = NULL; + poolMinBaseIdx = pool->minBaseIdx; + charCount = 0; + nLines = 0; + while (1) { + + // find the first non-empty line in the pool + for (; + poolMinBaseIdx <= pool->maxBaseIdx && !pool->getPool(poolMinBaseIdx); + ++poolMinBaseIdx) ; + if (poolMinBaseIdx > pool->maxBaseIdx) { + break; + } + + // look for the left-most word in the first four lines of the + // pool -- this avoids starting with a superscript word + startBaseIdx = poolMinBaseIdx; + for (baseIdx = poolMinBaseIdx + 1; + baseIdx < poolMinBaseIdx + 4 && baseIdx <= pool->maxBaseIdx; + ++baseIdx) { + if (!pool->getPool(baseIdx)) { + continue; + } + if (pool->getPool(baseIdx)->primaryCmp(pool->getPool(startBaseIdx)) + < 0) { + startBaseIdx = baseIdx; + } + } + + // create a new line + word0 = pool->getPool(startBaseIdx); + pool->setPool(startBaseIdx, word0->next); + word0->next = NULL; + line = new TextLine(this, word0->rot, word0->base); + line->addWord(word0); + lastWord = word0; + + // compute the search range + fontSize = word0->fontSize; + minBase = word0->base - maxIntraLineDelta * fontSize; + maxBase = word0->base + maxIntraLineDelta * fontSize; + minBaseIdx = pool->getBaseIdx(minBase); + maxBaseIdx = pool->getBaseIdx(maxBase); + + // find the rest of the words in this line + while (1) { + + // find the left-most word whose baseline is in the range for + // this line + bestWordBaseIdx = 0; + bestWord0 = bestWord1 = NULL; + for (baseIdx = minBaseIdx; baseIdx <= maxBaseIdx; ++baseIdx) { + for (word0 = NULL, word1 = pool->getPool(baseIdx); + word1; + word0 = word1, word1 = word1->next) { + if (word1->base >= minBase && + word1->base <= maxBase && + (delta = lastWord->primaryDelta(word1)) >= + minCharSpacing * fontSize) { + if (delta < maxWordSpacing * fontSize && + (!bestWord1 || word1->primaryCmp(bestWord1) < 0)) { + bestWordBaseIdx = baseIdx; + bestWord0 = word0; + bestWord1 = word1; + } + break; + } + } + } + if (!bestWord1) { + break; + } + + // remove it from the pool, and add it to the line + if (bestWord0) { + bestWord0->next = bestWord1->next; + } else { + pool->setPool(bestWordBaseIdx, bestWord1->next); + } + bestWord1->next = NULL; + line->addWord(bestWord1); + lastWord = bestWord1; + } + + // add the line + if (curLine && line->cmpYX(curLine) > 0) { + line0 = curLine; + line1 = curLine->next; + } else { + line0 = NULL; + line1 = lines; + } + for (; + line1 && line->cmpYX(line1) > 0; + line0 = line1, line1 = line1->next) ; + if (line0) { + line0->next = line; + } else { + lines = line; + } + line->next = line1; + curLine = line; + line->coalesce(uMap); + charCount += line->len; + ++nLines; + } + + // sort lines into xy order for column assignment + lineArray = (TextLine **)gmallocn(nLines, sizeof(TextLine *)); + for (line = lines, i = 0; line; line = line->next, ++i) { + lineArray[i] = line; + } + qsort(lineArray, nLines, sizeof(TextLine *), &TextLine::cmpXY); + + // column assignment + nColumns = 0; + for (i = 0; i < nLines; ++i) { + line0 = lineArray[i]; + col1 = 0; + for (j = 0; j < i; ++j) { + line1 = lineArray[j]; + if (line1->primaryDelta(line0) >= 0) { + col2 = line1->col[line1->len] + 1; + } else { + k = 0; // make gcc happy + switch (rot) { + case 0: + for (k = 0; + k < line1->len && + line0->xMin >= 0.5 * (line1->edge[k] + line1->edge[k+1]); + ++k) ; + break; + case 1: + for (k = 0; + k < line1->len && + line0->yMin >= 0.5 * (line1->edge[k] + line1->edge[k+1]); + ++k) ; + break; + case 2: + for (k = 0; + k < line1->len && + line0->xMax <= 0.5 * (line1->edge[k] + line1->edge[k+1]); + ++k) ; + break; + case 3: + for (k = 0; + k < line1->len && + line0->yMax <= 0.5 * (line1->edge[k] + line1->edge[k+1]); + ++k) ; + break; + } + col2 = line1->col[k]; + } + if (col2 > col1) { + col1 = col2; + } + } + for (k = 0; k <= line0->len; ++k) { + line0->col[k] += col1; + } + if (line0->col[line0->len] > nColumns) { + nColumns = line0->col[line0->len]; + } + } + gfree(lineArray); +} + +void TextBlock::updatePriMinMax(TextBlock *blk) { + double newPriMin, newPriMax; + GBool gotPriMin, gotPriMax; + + gotPriMin = gotPriMax = gFalse; + newPriMin = newPriMax = 0; // make gcc happy + switch (page->primaryRot) { + case 0: + case 2: + if (blk->yMin < yMax && blk->yMax > yMin) { + if (blk->xMin < xMin) { + newPriMin = blk->xMax; + gotPriMin = gTrue; + } + if (blk->xMax > xMax) { + newPriMax = blk->xMin; + gotPriMax = gTrue; + } + } + break; + case 1: + case 3: + if (blk->xMin < xMax && blk->xMax > xMin) { + if (blk->yMin < yMin) { + newPriMin = blk->yMax; + gotPriMin = gTrue; + } + if (blk->yMax > yMax) { + newPriMax = blk->yMin; + gotPriMax = gTrue; + } + } + break; + } + if (gotPriMin) { + if (newPriMin > xMin) { + newPriMin = xMin; + } + if (newPriMin > priMin) { + priMin = newPriMin; + } + } + if (gotPriMax) { + if (newPriMax < xMax) { + newPriMax = xMax; + } + if (newPriMax < priMax) { + priMax = newPriMax; + } + } +} + +int TextBlock::cmpXYPrimaryRot(const void *p1, const void *p2) { + TextBlock *blk1 = *(TextBlock **)p1; + TextBlock *blk2 = *(TextBlock **)p2; + double cmp; + + cmp = 0; // make gcc happy + switch (blk1->page->primaryRot) { + case 0: + if ((cmp = blk1->xMin - blk2->xMin) == 0) { + cmp = blk1->yMin - blk2->yMin; + } + break; + case 1: + if ((cmp = blk1->yMin - blk2->yMin) == 0) { + cmp = blk2->xMax - blk1->xMax; + } + break; + case 2: + if ((cmp = blk2->xMax - blk1->xMax) == 0) { + cmp = blk2->yMin - blk1->yMin; + } + break; + case 3: + if ((cmp = blk2->yMax - blk1->yMax) == 0) { + cmp = blk1->xMax - blk2->xMax; + } + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +int TextBlock::cmpYXPrimaryRot(const void *p1, const void *p2) { + TextBlock *blk1 = *(TextBlock **)p1; + TextBlock *blk2 = *(TextBlock **)p2; + double cmp; + + cmp = 0; // make gcc happy + switch (blk1->page->primaryRot) { + case 0: + if ((cmp = blk1->yMin - blk2->yMin) == 0) { + cmp = blk1->xMin - blk2->xMin; + } + break; + case 1: + if ((cmp = blk2->xMax - blk1->xMax) == 0) { + cmp = blk1->yMin - blk2->yMin; + } + break; + case 2: + if ((cmp = blk2->yMin - blk1->yMin) == 0) { + cmp = blk2->xMax - blk1->xMax; + } + break; + case 3: + if ((cmp = blk1->xMax - blk2->xMax) == 0) { + cmp = blk2->yMax - blk1->yMax; + } + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +int TextBlock::primaryCmp(TextBlock *blk) { + double cmp; + + cmp = 0; // make gcc happy + switch (rot) { + case 0: + cmp = xMin - blk->xMin; + break; + case 1: + cmp = yMin - blk->yMin; + break; + case 2: + cmp = blk->xMax - xMax; + break; + case 3: + cmp = blk->yMax - yMax; + break; + } + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + +double TextBlock::secondaryDelta(TextBlock *blk) { + double delta; + + delta = 0; // make gcc happy + switch (rot) { + case 0: + delta = blk->yMin - yMax; + break; + case 1: + delta = xMin - blk->xMax; + break; + case 2: + delta = yMin - blk->yMax; + break; + case 3: + delta = blk->xMin - xMax; + break; + } + return delta; +} + +GBool TextBlock::isBelow(TextBlock *blk) { + GBool below; + + below = gFalse; // make gcc happy + switch (page->primaryRot) { + case 0: + below = xMin >= blk->priMin && xMax <= blk->priMax && + yMin > blk->yMin; + break; + case 1: + below = yMin >= blk->priMin && yMax <= blk->priMax && + xMax < blk->xMax; + break; + case 2: + below = xMin >= blk->priMin && xMax <= blk->priMax && + yMax < blk->yMax; + break; + case 3: + below = yMin >= blk->priMin && yMax <= blk->priMax && + xMin > blk->xMin; + break; + } + + return below; +} + +//------------------------------------------------------------------------ +// TextFlow +//------------------------------------------------------------------------ + +TextFlow::TextFlow(TextPage *pageA, TextBlock *blk) { + page = pageA; + xMin = blk->xMin; + xMax = blk->xMax; + yMin = blk->yMin; + yMax = blk->yMax; + priMin = blk->priMin; + priMax = blk->priMax; + blocks = lastBlk = blk; + next = NULL; +} + +TextFlow::~TextFlow() { + TextBlock *blk; + + while (blocks) { + blk = blocks; + blocks = blocks->next; + delete blk; + } +} + +void TextFlow::addBlock(TextBlock *blk) { + if (lastBlk) { + lastBlk->next = blk; + } else { + blocks = blk; + } + lastBlk = blk; + if (blk->xMin < xMin) { + xMin = blk->xMin; + } + if (blk->xMax > xMax) { + xMax = blk->xMax; + } + if (blk->yMin < yMin) { + yMin = blk->yMin; + } + if (blk->yMax > yMax) { + yMax = blk->yMax; + } +} + +GBool TextFlow::blockFits(TextBlock *blk, TextBlock *prevBlk) { + GBool fits; + + // lower blocks must use smaller fonts + if (blk->lines->words->fontSize > lastBlk->lines->words->fontSize) { + return gFalse; + } + + fits = gFalse; // make gcc happy + switch (page->primaryRot) { + case 0: + fits = blk->xMin >= priMin && blk->xMax <= priMax; + break; + case 1: + fits = blk->yMin >= priMin && blk->yMax <= priMax; + break; + case 2: + fits = blk->xMin >= priMin && blk->xMax <= priMax; + break; + case 3: + fits = blk->yMin >= priMin && blk->yMax <= priMax; + break; + } + return fits; +} + +#if TEXTOUT_WORD_LIST + +//------------------------------------------------------------------------ +// TextWordList +//------------------------------------------------------------------------ + +TextWordList::TextWordList(TextPage *text, GBool physLayout) { + TextFlow *flow; + TextBlock *blk; + TextLine *line; + TextWord *word; + TextWord **wordArray; + int nWords, i; + + words = new GooList(); + + if (text->rawOrder) { + for (word = text->rawWords; word; word = word->next) { + words->append(word); + } + + } else if (physLayout) { + // this is inefficient, but it's also the least useful of these + // three cases + nWords = 0; + for (flow = text->flows; flow; flow = flow->next) { + for (blk = flow->blocks; blk; blk = blk->next) { + for (line = blk->lines; line; line = line->next) { + for (word = line->words; word; word = word->next) { + ++nWords; + } + } + } + } + wordArray = (TextWord **)gmallocn(nWords, sizeof(TextWord *)); + i = 0; + for (flow = text->flows; flow; flow = flow->next) { + for (blk = flow->blocks; blk; blk = blk->next) { + for (line = blk->lines; line; line = line->next) { + for (word = line->words; word; word = word->next) { + wordArray[i++] = word; + } + } + } + } + qsort(wordArray, nWords, sizeof(TextWord *), &TextWord::cmpYX); + for (i = 0; i < nWords; ++i) { + words->append(wordArray[i]); + } + gfree(wordArray); + + } else { + for (flow = text->flows; flow; flow = flow->next) { + for (blk = flow->blocks; blk; blk = blk->next) { + for (line = blk->lines; line; line = line->next) { + for (word = line->words; word; word = word->next) { + words->append(word); + } + } + } + } + } +} + +TextWordList::~TextWordList() { + delete words; +} + +int TextWordList::getLength() { + return words->getLength(); +} + +TextWord *TextWordList::get(int idx) { + if (idx < 0 || idx >= words->getLength()) { + return NULL; + } + return (TextWord *)words->get(idx); +} + +#endif // TEXTOUT_WORD_LIST + +//------------------------------------------------------------------------ +// TextPage +//------------------------------------------------------------------------ + +TextPage::TextPage(GBool rawOrderA) { + int rot; + + rawOrder = rawOrderA; + curWord = NULL; + charPos = 0; + curFont = NULL; + curFontSize = 0; + nest = 0; + nTinyChars = 0; + lastCharOverlap = gFalse; + if (!rawOrder) { + for (rot = 0; rot < 4; ++rot) { + pools[rot] = new TextPool(); + } + } + flows = NULL; + blocks = NULL; + rawWords = NULL; + rawLastWord = NULL; + fonts = new GooList(); + lastFindXMin = lastFindYMin = 0; + haveLastFind = gFalse; +} + +TextPage::~TextPage() { + int rot; + + clear(); + if (!rawOrder) { + for (rot = 0; rot < 4; ++rot) { + delete pools[rot]; + } + } + delete fonts; +} + +void TextPage::startPage(GfxState *state) { + clear(); + if (state) { + pageWidth = state->getPageWidth(); + pageHeight = state->getPageHeight(); + } else { + pageWidth = pageHeight = 0; + } +} + +void TextPage::endPage() { + if (curWord) { + endWord(); + } +} + +void TextPage::clear() { + int rot; + TextFlow *flow; + TextWord *word; + + if (curWord) { + delete curWord; + curWord = NULL; + } + if (rawOrder) { + while (rawWords) { + word = rawWords; + rawWords = rawWords->next; + delete word; + } + } else { + for (rot = 0; rot < 4; ++rot) { + delete pools[rot]; + } + while (flows) { + flow = flows; + flows = flows->next; + delete flow; + } + gfree(blocks); + } + deleteGooList(fonts, TextFontInfo); + + curWord = NULL; + charPos = 0; + curFont = NULL; + curFontSize = 0; + nest = 0; + nTinyChars = 0; + if (!rawOrder) { + for (rot = 0; rot < 4; ++rot) { + pools[rot] = new TextPool(); + } + } + flows = NULL; + blocks = NULL; + rawWords = NULL; + rawLastWord = NULL; + fonts = new GooList(); +} + +void TextPage::updateFont(GfxState *state) { + GfxFont *gfxFont; + double *fm; + char *name; + int code, mCode, letterCode, anyCode; + double w; + int i; + + // get the font info object + curFont = NULL; + for (i = 0; i < fonts->getLength(); ++i) { + curFont = (TextFontInfo *)fonts->get(i); + if (curFont->matches(state)) { + break; + } + curFont = NULL; + } + if (!curFont) { + curFont = new TextFontInfo(state); + fonts->append(curFont); + } + + // adjust the font size + gfxFont = state->getFont(); + curFontSize = state->getTransformedFontSize(); + if (gfxFont && gfxFont->getType() == fontType3) { + // This is a hack which makes it possible to deal with some Type 3 + // fonts. The problem is that it's impossible to know what the + // base coordinate system used in the font is without actually + // rendering the font. This code tries to guess by looking at the + // width of the character 'm' (which breaks if the font is a + // subset that doesn't contain 'm'). + mCode = letterCode = anyCode = -1; + for (code = 0; code < 256; ++code) { + name = ((Gfx8BitFont *)gfxFont)->getCharName(code); + if (name && name[0] == 'm' && name[1] == '\0') { + mCode = code; + } + if (letterCode < 0 && name && name[1] == '\0' && + ((name[0] >= 'A' && name[0] <= 'Z') || + (name[0] >= 'a' && name[0] <= 'z'))) { + letterCode = code; + } + if (anyCode < 0 && name && + ((Gfx8BitFont *)gfxFont)->getWidth(code) > 0) { + anyCode = code; + } + } + if (mCode >= 0 && + (w = ((Gfx8BitFont *)gfxFont)->getWidth(mCode)) > 0) { + // 0.6 is a generic average 'm' width -- yes, this is a hack + curFontSize *= w / 0.6; + } else if (letterCode >= 0 && + (w = ((Gfx8BitFont *)gfxFont)->getWidth(letterCode)) > 0) { + // even more of a hack: 0.5 is a generic letter width + curFontSize *= w / 0.5; + } else if (anyCode >= 0 && + (w = ((Gfx8BitFont *)gfxFont)->getWidth(anyCode)) > 0) { + // better than nothing: 0.5 is a generic character width + curFontSize *= w / 0.5; + } + fm = gfxFont->getFontMatrix(); + if (fm[0] != 0) { + curFontSize *= fabs(fm[3] / fm[0]); + } + } +} + +void TextPage::beginWord(GfxState *state, double x0, double y0) { + double *fontm; + double m[4], m2[4]; + int rot; + + // This check is needed because Type 3 characters can contain + // text-drawing operations (when TextPage is being used via + // {X,Win}SplashOutputDev rather than TextOutputDev). + if (curWord) { + ++nest; + return; + } + + // compute the rotation + state->getFontTransMat(&m[0], &m[1], &m[2], &m[3]); + if (state->getFont()->getType() == fontType3) { + fontm = state->getFont()->getFontMatrix(); + m2[0] = fontm[0] * m[0] + fontm[1] * m[2]; + m2[1] = fontm[0] * m[1] + fontm[1] * m[3]; + m2[2] = fontm[2] * m[0] + fontm[3] * m[2]; + m2[3] = fontm[2] * m[1] + fontm[3] * m[3]; + m[0] = m2[0]; + m[1] = m2[1]; + m[2] = m2[2]; + m[3] = m2[3]; + } + if (fabs(m[0] * m[3]) > fabs(m[1] * m[2])) { + rot = (m[3] < 0) ? 0 : 2; + } else { + rot = (m[2] > 0) ? 1 : 3; + } + + curWord = new TextWord(state, rot, x0, y0, charPos, curFont, curFontSize); +} + +void TextPage::addChar(GfxState *state, double x, double y, + double dx, double dy, + CharCode c, int nBytes, Unicode *u, int uLen) { + double x1, y1, w1, h1, dx2, dy2, base, sp, delta; + GBool overlap; + int i; + + // throw away chars that aren't inside the page bounds + state->transform(x, y, &x1, &y1); + if (x1 < 0 || x1 > pageWidth || + y1 < 0 || y1 > pageHeight) { + charPos += nBytes; + return; + } + + // subtract char and word spacing from the dx,dy values + sp = state->getCharSpace(); + if (c == (CharCode)0x20) { + sp += state->getWordSpace(); + } + state->textTransformDelta(sp * state->getHorizScaling(), 0, &dx2, &dy2); + dx -= dx2; + dy -= dy2; + state->transformDelta(dx, dy, &w1, &h1); + + // check the tiny chars limit + if (!globalParams->getTextKeepTinyChars() && + fabs(w1) < 3 && fabs(h1) < 3) { + if (++nTinyChars > 50000) { + charPos += nBytes; + return; + } + } + + // break words at space character + if (uLen == 1 && u[0] == (Unicode)0x20) { + if (curWord) { + ++curWord->charLen; + } + charPos += nBytes; + endWord(); + return; + } + + // start a new word if: + // (1) this character doesn't fall in the right place relative to + // the end of the previous word (this places upper and lower + // constraints on the position deltas along both the primary + // and secondary axes), or + // (2) this character overlaps the previous one (duplicated text), or + // (3) the previous character was an overlap (we want each duplicated + // character to be in a word by itself at this stage) + if (curWord && curWord->len > 0) { + base = sp = delta = 0; // make gcc happy + switch (curWord->rot) { + case 0: + base = y1; + sp = x1 - curWord->xMax; + delta = x1 - curWord->edge[curWord->len - 1]; + break; + case 1: + base = x1; + sp = y1 - curWord->yMax; + delta = y1 - curWord->edge[curWord->len - 1]; + break; + case 2: + base = y1; + sp = curWord->xMin - x1; + delta = curWord->edge[curWord->len - 1] - x1; + break; + case 3: + base = x1; + sp = curWord->yMin - y1; + delta = curWord->edge[curWord->len - 1] - y1; + break; + } + overlap = fabs(delta) < dupMaxPriDelta * curWord->fontSize && + fabs(base - curWord->base) < dupMaxSecDelta * curWord->fontSize; + if (overlap || lastCharOverlap || + sp < -minDupBreakOverlap * curWord->fontSize || + sp > minWordBreakSpace * curWord->fontSize || + fabs(base - curWord->base) > 0.5) { + endWord(); + } + lastCharOverlap = overlap; + } else { + lastCharOverlap = gFalse; + } + + if (uLen != 0) { + // start a new word if needed + if (!curWord) { + beginWord(state, x, y); + } + + // page rotation and/or transform matrices can cause text to be + // drawn in reverse order -- in this case, swap the begin/end + // coordinates and break text into individual chars + if ((curWord->rot == 0 && w1 < 0) || + (curWord->rot == 1 && h1 < 0) || + (curWord->rot == 2 && w1 > 0) || + (curWord->rot == 3 && h1 > 0)) { + endWord(); + beginWord(state, x + dx, y + dy); + x1 += w1; + y1 += h1; + w1 = -w1; + h1 = -h1; + } + + // add the characters to the current word + w1 /= uLen; + h1 /= uLen; + for (i = 0; i < uLen; ++i) { + curWord->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, c, u[i]); + } + } + if (curWord) { + curWord->charLen += nBytes; + } + charPos += nBytes; +} + +void TextPage::endWord() { + // This check is needed because Type 3 characters can contain + // text-drawing operations (when TextPage is being used via + // {X,Win}SplashOutputDev rather than TextOutputDev). + if (nest > 0) { + --nest; + return; + } + + if (curWord) { + addWord(curWord); + curWord = NULL; + } +} + +void TextPage::addWord(TextWord *word) { + // throw away zero-length words -- they don't have valid xMin/xMax + // values, and they're useless anyway + if (word->len == 0) { + delete word; + return; + } + + if (rawOrder) { + if (rawLastWord) { + rawLastWord->next = word; + } else { + rawWords = word; + } + rawLastWord = word; + } else { + pools[word->rot]->addWord(word); + } +} + +void TextPage::coalesce(GBool physLayout) { + UnicodeMap *uMap; + TextPool *pool; + TextWord *word0, *word1, *word2; + TextLine *line; + TextBlock *blkList, *blkStack, *blk, *lastBlk, *blk0, *blk1; + TextBlock **blkArray; + TextFlow *flow, *lastFlow; + int rot, poolMinBaseIdx, baseIdx, startBaseIdx; + double minBase, maxBase, newMinBase, newMaxBase; + double fontSize, colSpace1, colSpace2, lineSpace, intraLineSpace, blkSpace; + GBool found; + int count[4]; + int lrCount; + int firstBlkIdx, nBlocksLeft; + int col1, col2; + int i, j, n; + + if (rawOrder) { + primaryRot = 0; + primaryLR = gTrue; + return; + } + + uMap = globalParams->getTextEncoding(); + blkList = NULL; + lastBlk = NULL; + nBlocks = 0; + primaryRot = -1; + +#if 0 // for debugging + printf("*** initial words ***\n"); + for (rot = 0; rot < 4; ++rot) { + pool = pools[rot]; + for (baseIdx = pool->minBaseIdx; baseIdx <= pool->maxBaseIdx; ++baseIdx) { + for (word0 = pool->getPool(baseIdx); word0; word0 = word0->next) { + printf(" word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f rot=%d '", + word0->xMin, word0->xMax, word0->yMin, word0->yMax, + word0->base, word0->fontSize, rot*90); + for (i = 0; i < word0->len; ++i) { + fputc(word0->text[i] & 0xff, stdout); + } + printf("'\n"); + } + } + } + printf("\n"); +#endif + + //----- assemble the blocks + + //~ add an outer loop for writing mode (vertical text) + + // build blocks for each rotation value + for (rot = 0; rot < 4; ++rot) { + pool = pools[rot]; + poolMinBaseIdx = pool->minBaseIdx; + count[rot] = 0; + + // add blocks until no more words are left + while (1) { + + // find the first non-empty line in the pool + for (; + poolMinBaseIdx <= pool->maxBaseIdx && + !pool->getPool(poolMinBaseIdx); + ++poolMinBaseIdx) ; + if (poolMinBaseIdx > pool->maxBaseIdx) { + break; + } + + // look for the left-most word in the first four lines of the + // pool -- this avoids starting with a superscript word + startBaseIdx = poolMinBaseIdx; + for (baseIdx = poolMinBaseIdx + 1; + baseIdx < poolMinBaseIdx + 4 && baseIdx <= pool->maxBaseIdx; + ++baseIdx) { + if (!pool->getPool(baseIdx)) { + continue; + } + if (pool->getPool(baseIdx)->primaryCmp(pool->getPool(startBaseIdx)) + < 0) { + startBaseIdx = baseIdx; + } + } + + // create a new block + word0 = pool->getPool(startBaseIdx); + pool->setPool(startBaseIdx, word0->next); + word0->next = NULL; + blk = new TextBlock(this, rot); + blk->addWord(word0); + + fontSize = word0->fontSize; + minBase = maxBase = word0->base; + colSpace1 = minColSpacing1 * fontSize; + colSpace2 = minColSpacing2 * fontSize; + lineSpace = maxLineSpacingDelta * fontSize; + intraLineSpace = maxIntraLineDelta * fontSize; + + // add words to the block + do { + found = gFalse; + + // look for words on the line above the current top edge of + // the block + newMinBase = minBase; + for (baseIdx = pool->getBaseIdx(minBase); + baseIdx >= pool->getBaseIdx(minBase - lineSpace); + --baseIdx) { + word0 = NULL; + word1 = pool->getPool(baseIdx); + while (word1) { + if (word1->base < minBase && + word1->base >= minBase - lineSpace && + ((rot == 0 || rot == 2) + ? (word1->xMin < blk->xMax && word1->xMax > blk->xMin) + : (word1->yMin < blk->yMax && word1->yMax > blk->yMin)) && + fabs(word1->fontSize - fontSize) < + maxBlockFontSizeDelta1 * fontSize) { + word2 = word1; + if (word0) { + word0->next = word1->next; + } else { + pool->setPool(baseIdx, word1->next); + } + word1 = word1->next; + word2->next = NULL; + blk->addWord(word2); + found = gTrue; + newMinBase = word2->base; + } else { + word0 = word1; + word1 = word1->next; + } + } + } + minBase = newMinBase; + + // look for words on the line below the current bottom edge of + // the block + newMaxBase = maxBase; + for (baseIdx = pool->getBaseIdx(maxBase); + baseIdx <= pool->getBaseIdx(maxBase + lineSpace); + ++baseIdx) { + word0 = NULL; + word1 = pool->getPool(baseIdx); + while (word1) { + if (word1->base > maxBase && + word1->base <= maxBase + lineSpace && + ((rot == 0 || rot == 2) + ? (word1->xMin < blk->xMax && word1->xMax > blk->xMin) + : (word1->yMin < blk->yMax && word1->yMax > blk->yMin)) && + fabs(word1->fontSize - fontSize) < + maxBlockFontSizeDelta1 * fontSize) { + word2 = word1; + if (word0) { + word0->next = word1->next; + } else { + pool->setPool(baseIdx, word1->next); + } + word1 = word1->next; + word2->next = NULL; + blk->addWord(word2); + found = gTrue; + newMaxBase = word2->base; + } else { + word0 = word1; + word1 = word1->next; + } + } + } + maxBase = newMaxBase; + + // look for words that are on lines already in the block, and + // that overlap the block horizontally + for (baseIdx = pool->getBaseIdx(minBase - intraLineSpace); + baseIdx <= pool->getBaseIdx(maxBase + intraLineSpace); + ++baseIdx) { + word0 = NULL; + word1 = pool->getPool(baseIdx); + while (word1) { + if (word1->base >= minBase - intraLineSpace && + word1->base <= maxBase + intraLineSpace && + ((rot == 0 || rot == 2) + ? (word1->xMin < blk->xMax + colSpace1 && + word1->xMax > blk->xMin - colSpace1) + : (word1->yMin < blk->yMax + colSpace1 && + word1->yMax > blk->yMin - colSpace1)) && + fabs(word1->fontSize - fontSize) < + maxBlockFontSizeDelta2 * fontSize) { + word2 = word1; + if (word0) { + word0->next = word1->next; + } else { + pool->setPool(baseIdx, word1->next); + } + word1 = word1->next; + word2->next = NULL; + blk->addWord(word2); + found = gTrue; + } else { + word0 = word1; + word1 = word1->next; + } + } + } + + // only check for outlying words (the next two chunks of code) + // if we didn't find anything else + if (found) { + continue; + } + + // scan down the left side of the block, looking for words + // that are near (but not overlapping) the block; if there are + // three or fewer, add them to the block + n = 0; + for (baseIdx = pool->getBaseIdx(minBase - intraLineSpace); + baseIdx <= pool->getBaseIdx(maxBase + intraLineSpace); + ++baseIdx) { + word1 = pool->getPool(baseIdx); + while (word1) { + if (word1->base >= minBase - intraLineSpace && + word1->base <= maxBase + intraLineSpace && + ((rot == 0 || rot == 2) + ? (word1->xMax <= blk->xMin && + word1->xMax > blk->xMin - colSpace2) + : (word1->yMax <= blk->yMin && + word1->yMax > blk->yMin - colSpace2)) && + fabs(word1->fontSize - fontSize) < + maxBlockFontSizeDelta3 * fontSize) { + ++n; + break; + } + word1 = word1->next; + } + } + if (n > 0 && n <= 3) { + for (baseIdx = pool->getBaseIdx(minBase - intraLineSpace); + baseIdx <= pool->getBaseIdx(maxBase + intraLineSpace); + ++baseIdx) { + word0 = NULL; + word1 = pool->getPool(baseIdx); + while (word1) { + if (word1->base >= minBase - intraLineSpace && + word1->base <= maxBase + intraLineSpace && + ((rot == 0 || rot == 2) + ? (word1->xMax <= blk->xMin && + word1->xMax > blk->xMin - colSpace2) + : (word1->yMax <= blk->yMin && + word1->yMax > blk->yMin - colSpace2)) && + fabs(word1->fontSize - fontSize) < + maxBlockFontSizeDelta3 * fontSize) { + word2 = word1; + if (word0) { + word0->next = word1->next; + } else { + pool->setPool(baseIdx, word1->next); + } + word1 = word1->next; + word2->next = NULL; + blk->addWord(word2); + if (word2->base < minBase) { + minBase = word2->base; + } else if (word2->base > maxBase) { + maxBase = word2->base; + } + found = gTrue; + break; + } else { + word0 = word1; + word1 = word1->next; + } + } + } + } + + // scan down the right side of the block, looking for words + // that are near (but not overlapping) the block; if there are + // three or fewer, add them to the block + n = 0; + for (baseIdx = pool->getBaseIdx(minBase - intraLineSpace); + baseIdx <= pool->getBaseIdx(maxBase + intraLineSpace); + ++baseIdx) { + word1 = pool->getPool(baseIdx); + while (word1) { + if (word1->base >= minBase - intraLineSpace && + word1->base <= maxBase + intraLineSpace && + ((rot == 0 || rot == 2) + ? (word1->xMin >= blk->xMax && + word1->xMin < blk->xMax + colSpace2) + : (word1->yMin >= blk->yMax && + word1->yMin < blk->yMax + colSpace2)) && + fabs(word1->fontSize - fontSize) < + maxBlockFontSizeDelta3 * fontSize) { + ++n; + break; + } + word1 = word1->next; + } + } + if (n > 0 && n <= 3) { + for (baseIdx = pool->getBaseIdx(minBase - intraLineSpace); + baseIdx <= pool->getBaseIdx(maxBase + intraLineSpace); + ++baseIdx) { + word0 = NULL; + word1 = pool->getPool(baseIdx); + while (word1) { + if (word1->base >= minBase - intraLineSpace && + word1->base <= maxBase + intraLineSpace && + ((rot == 0 || rot == 2) + ? (word1->xMin >= blk->xMax && + word1->xMin < blk->xMax + colSpace2) + : (word1->yMin >= blk->yMax && + word1->yMin < blk->yMax + colSpace2)) && + fabs(word1->fontSize - fontSize) < + maxBlockFontSizeDelta3 * fontSize) { + word2 = word1; + if (word0) { + word0->next = word1->next; + } else { + pool->setPool(baseIdx, word1->next); + } + word1 = word1->next; + word2->next = NULL; + blk->addWord(word2); + if (word2->base < minBase) { + minBase = word2->base; + } else if (word2->base > maxBase) { + maxBase = word2->base; + } + found = gTrue; + break; + } else { + word0 = word1; + word1 = word1->next; + } + } + } + } + + } while (found); + + //~ need to compute the primary writing mode (horiz/vert) in + //~ addition to primary rotation + + // coalesce the block, and add it to the list + blk->coalesce(uMap); + if (lastBlk) { + lastBlk->next = blk; + } else { + blkList = blk; + } + lastBlk = blk; + count[rot] += blk->charCount; + if (primaryRot < 0 || count[rot] > count[primaryRot]) { + primaryRot = rot; + } + ++nBlocks; + } + } + +#if 0 // for debugging + printf("*** rotation ***\n"); + for (rot = 0; rot < 4; ++rot) { + printf(" %d: %6d\n", rot, count[rot]); + } + printf(" primary rot = %d\n", primaryRot); + printf("\n"); +#endif + +#if 0 // for debugging + printf("*** blocks ***\n"); + for (blk = blkList; blk; blk = blk->next) { + printf("block: rot=%d x=%.2f..%.2f y=%.2f..%.2f\n", + blk->rot, blk->xMin, blk->xMax, blk->yMin, blk->yMax); + for (line = blk->lines; line; line = line->next) { + printf(" line: x=%.2f..%.2f y=%.2f..%.2f base=%.2f\n", + line->xMin, line->xMax, line->yMin, line->yMax, line->base); + for (word0 = line->words; word0; word0 = word0->next) { + printf(" word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f space=%d: '", + word0->xMin, word0->xMax, word0->yMin, word0->yMax, + word0->base, word0->fontSize, word0->spaceAfter); + for (i = 0; i < word0->len; ++i) { + fputc(word0->text[i] & 0xff, stdout); + } + printf("'\n"); + } + } + } + printf("\n"); +#endif + + // determine the primary direction + lrCount = 0; + for (blk = blkList; blk; blk = blk->next) { + for (line = blk->lines; line; line = line->next) { + for (word0 = line->words; word0; word0 = word0->next) { + for (i = 0; i < word0->len; ++i) { + if (unicodeTypeL(word0->text[i])) { + ++lrCount; + } else if (unicodeTypeR(word0->text[i])) { + --lrCount; + } + } + } + } + } + primaryLR = lrCount >= 0; + +#if 0 // for debugging + printf("*** direction ***\n"); + printf("lrCount = %d\n", lrCount); + printf("primaryLR = %d\n", primaryLR); +#endif + + //----- column assignment + + // sort blocks into xy order for column assignment + if (blocks) + gfree (blocks); + blocks = (TextBlock **)gmallocn(nBlocks, sizeof(TextBlock *)); + for (blk = blkList, i = 0; blk; blk = blk->next, ++i) { + blocks[i] = blk; + } + qsort(blocks, nBlocks, sizeof(TextBlock *), &TextBlock::cmpXYPrimaryRot); + + // column assignment + for (i = 0; i < nBlocks; ++i) { + blk0 = blocks[i]; + col1 = 0; + for (j = 0; j < i; ++j) { + blk1 = blocks[j]; + col2 = 0; // make gcc happy + switch (primaryRot) { + case 0: + if (blk0->xMin > blk1->xMax) { + col2 = blk1->col + blk1->nColumns + 3; + } else if (blk1->xMax == blk1->xMin) { + col2 = blk1->col; + } else { + col2 = blk1->col + (int)(((blk0->xMin - blk1->xMin) / + (blk1->xMax - blk1->xMin)) * + blk1->nColumns); + } + break; + case 1: + if (blk0->yMin > blk1->yMax) { + col2 = blk1->col + blk1->nColumns + 3; + } else if (blk1->yMax == blk1->yMin) { + col2 = blk1->col; + } else { + col2 = blk1->col + (int)(((blk0->yMin - blk1->yMin) / + (blk1->yMax - blk1->yMin)) * + blk1->nColumns); + } + break; + case 2: + if (blk0->xMax < blk1->xMin) { + col2 = blk1->col + blk1->nColumns + 3; + } else if (blk1->xMin == blk1->xMax) { + col2 = blk1->col; + } else { + col2 = blk1->col + (int)(((blk0->xMax - blk1->xMax) / + (blk1->xMin - blk1->xMax)) * + blk1->nColumns); + } + break; + case 3: + if (blk0->yMax < blk1->yMin) { + col2 = blk1->col + blk1->nColumns + 3; + } else if (blk1->yMin == blk1->yMax) { + col2 = blk1->col; + } else { + col2 = blk1->col + (int)(((blk0->yMax - blk1->yMax) / + (blk1->yMin - blk1->yMax)) * + blk1->nColumns); + } + break; + } + if (col2 > col1) { + col1 = col2; + } + } + blk0->col = col1; + for (line = blk0->lines; line; line = line->next) { + for (j = 0; j <= line->len; ++j) { + line->col[j] += col1; + } + } + } + +#if 0 // for debugging + printf("*** blocks, after column assignment ***\n"); + for (blk = blkList; blk; blk = blk->next) { + printf("block: rot=%d x=%.2f..%.2f y=%.2f..%.2f col=%d nCols=%d\n", + blk->rot, blk->xMin, blk->xMax, blk->yMin, blk->yMax, blk->col, + blk->nColumns); + for (line = blk->lines; line; line = line->next) { + printf(" line:\n"); + for (word0 = line->words; word0; word0 = word0->next) { + printf(" word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f space=%d: '", + word0->xMin, word0->xMax, word0->yMin, word0->yMax, + word0->base, word0->fontSize, word0->spaceAfter); + for (i = 0; i < word0->len; ++i) { + fputc(word0->text[i] & 0xff, stdout); + } + printf("'\n"); + } + } + } + printf("\n"); +#endif + + //----- reading order sort + + // sort blocks into yx order (in preparation for reading order sort) + qsort(blocks, nBlocks, sizeof(TextBlock *), &TextBlock::cmpYXPrimaryRot); + + // compute space on left and right sides of each block + for (i = 0; i < nBlocks; ++i) { + blk0 = blocks[i]; + for (j = 0; j < nBlocks; ++j) { + blk1 = blocks[j]; + if (blk1 != blk0) { + blk0->updatePriMinMax(blk1); + } + } + } + +#if 0 // for debugging + printf("*** blocks, after yx sort ***\n"); + for (i = 0; i < nBlocks; ++i) { + blk = blocks[i]; + printf("block: rot=%d x=%.2f..%.2f y=%.2f..%.2f space=%.2f..%.2f\n", + blk->rot, blk->xMin, blk->xMax, blk->yMin, blk->yMax, + blk->priMin, blk->priMax); + for (line = blk->lines; line; line = line->next) { + printf(" line:\n"); + for (word0 = line->words; word0; word0 = word0->next) { + printf(" word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f space=%d: '", + word0->xMin, word0->xMax, word0->yMin, word0->yMax, + word0->base, word0->fontSize, word0->spaceAfter); + for (j = 0; j < word0->len; ++j) { + fputc(word0->text[j] & 0xff, stdout); + } + printf("'\n"); + } + } + } + printf("\n"); +#endif + + // build the flows + //~ this needs to be adjusted for writing mode (vertical text) + //~ this also needs to account for right-to-left column ordering + blkArray = (TextBlock **)gmallocn(nBlocks, sizeof(TextBlock *)); + memcpy(blkArray, blocks, nBlocks * sizeof(TextBlock *)); + while (flows) { + flow = flows; + flows = flows->next; + delete flow; + } + flows = lastFlow = NULL; + firstBlkIdx = 0; + nBlocksLeft = nBlocks; + while (nBlocksLeft > 0) { + + // find the upper-left-most block + for (; !blkArray[firstBlkIdx]; ++firstBlkIdx) ; + i = firstBlkIdx; + blk = blkArray[i]; + for (j = firstBlkIdx + 1; j < nBlocks; ++j) { + blk1 = blkArray[j]; + if (blk1) { + if (blk && blk->secondaryDelta(blk1) > 0) { + break; + } + if (blk1->primaryCmp(blk) < 0) { + i = j; + blk = blk1; + } + } + } + blkArray[i] = NULL; + --nBlocksLeft; + blk->next = NULL; + + // create a new flow, starting with the upper-left-most block + flow = new TextFlow(this, blk); + if (lastFlow) { + lastFlow->next = flow; + } else { + flows = flow; + } + lastFlow = flow; + fontSize = blk->lines->words->fontSize; + + // push the upper-left-most block on the stack + blk->stackNext = NULL; + blkStack = blk; + + // find the other blocks in this flow + while (blkStack) { + + // find the upper-left-most block under (but within + // maxBlockSpacing of) the top block on the stack + blkSpace = maxBlockSpacing * blkStack->lines->words->fontSize; + blk = NULL; + i = -1; + for (j = firstBlkIdx; j < nBlocks; ++j) { + blk1 = blkArray[j]; + if (blk1) { + if (blkStack->secondaryDelta(blk1) > blkSpace) { + break; + } + if (blk && blk->secondaryDelta(blk1) > 0) { + break; + } + if (blk1->isBelow(blkStack) && + (!blk || blk1->primaryCmp(blk) < 0)) { + i = j; + blk = blk1; + } + } + } + + // if a suitable block was found, add it to the flow and push it + // onto the stack + if (blk && flow->blockFits(blk, blkStack)) { + blkArray[i] = NULL; + --nBlocksLeft; + blk->next = NULL; + flow->addBlock(blk); + fontSize = blk->lines->words->fontSize; + blk->stackNext = blkStack; + blkStack = blk; + + // otherwise (if there is no block under the top block or the + // block is not suitable), pop the stack + } else { + blkStack = blkStack->stackNext; + } + } + } + gfree(blkArray); + +#if 0 // for debugging + printf("*** flows ***\n"); + for (flow = flows; flow; flow = flow->next) { + printf("flow: x=%.2f..%.2f y=%.2f..%.2f pri:%.2f..%.2f\n", + flow->xMin, flow->xMax, flow->yMin, flow->yMax, + flow->priMin, flow->priMax); + for (blk = flow->blocks; blk; blk = blk->next) { + printf(" block: rot=%d x=%.2f..%.2f y=%.2f..%.2f pri=%.2f..%.2f\n", + blk->rot, blk->xMin, blk->xMax, blk->yMin, blk->yMax, + blk->priMin, blk->priMax); + for (line = blk->lines; line; line = line->next) { + printf(" line:\n"); + for (word0 = line->words; word0; word0 = word0->next) { + printf(" word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f space=%d: '", + word0->xMin, word0->xMax, word0->yMin, word0->yMax, + word0->base, word0->fontSize, word0->spaceAfter); + for (i = 0; i < word0->len; ++i) { + fputc(word0->text[i] & 0xff, stdout); + } + printf("'\n"); + } + } + } + } + printf("\n"); +#endif + + if (uMap) { + uMap->decRefCnt(); + } +} + +GBool TextPage::findText(Unicode *s, int len, + GBool startAtTop, GBool stopAtBottom, + GBool startAtLast, GBool stopAtLast, + GBool caseSensitive, GBool backward, + double *xMin, double *yMin, + double *xMax, double *yMax) { + TextBlock *blk; + TextLine *line; + Unicode *s2, *txt; + Unicode *p; + int txtSize, m, i, j, k; + double xStart, yStart, xStop, yStop; + double xMin0, yMin0, xMax0, yMax0; + double xMin1, yMin1, xMax1, yMax1; + GBool found; + + //~ needs to handle right-to-left text + + if (rawOrder) { + return gFalse; + } + + // convert the search string to uppercase + if (!caseSensitive) { + s2 = unicodeNormalizeNFKC(s, len, &len, NULL); + for (i = 0; i < len; ++i) { + s2[i] = unicodeToUpper(s2[i]); + } + } else { + s2 = unicodeNormalizeNFKC(s, len, &len, NULL); + } + + txt = NULL; + txtSize = 0; + + xStart = yStart = xStop = yStop = 0; + if (startAtLast && haveLastFind) { + xStart = lastFindXMin; + yStart = lastFindYMin; + } else if (!startAtTop) { + xStart = *xMin; + yStart = *yMin; + } + if (stopAtLast && haveLastFind) { + xStop = lastFindXMin; + yStop = lastFindYMin; + } else if (!stopAtBottom) { + xStop = *xMax; + yStop = *yMax; + } + + found = gFalse; + xMin0 = xMax0 = yMin0 = yMax0 = 0; // make gcc happy + xMin1 = xMax1 = yMin1 = yMax1 = 0; // make gcc happy + + for (i = backward ? nBlocks - 1 : 0; + backward ? i >= 0 : i < nBlocks; + i += backward ? -1 : 1) { + blk = blocks[i]; + + // check: is the block above the top limit? + if (!startAtTop && (backward ? blk->yMin > yStart : blk->yMax < yStart)) { + continue; + } + + // check: is the block below the bottom limit? + if (!stopAtBottom && (backward ? blk->yMax < yStop : blk->yMin > yStop)) { + break; + } + + for (line = blk->lines; line; line = line->next) { + + // check: is the line above the top limit? + if (!startAtTop && + (backward ? line->yMin > yStart : line->yMin < yStart)) { + continue; + } + + // check: is the line below the bottom limit? + if (!stopAtBottom && + (backward ? line->yMin < yStop : line->yMin > yStop)) { + continue; + } + + if (!line->normalized) + line->normalized = unicodeNormalizeNFKC(line->text, line->len, + &line->normalized_len, + &line->normalized_idx); + // convert the line to uppercase + m = line->normalized_len; + if (!caseSensitive) { + if (m > txtSize) { + txt = (Unicode *)greallocn(txt, m, sizeof(Unicode)); + txtSize = m; + } + for (k = 0; k < m; ++k) { + if (txt) + txt[k] = unicodeToUpper(line->normalized[k]); + } + } else { + txt = line->normalized; + } + + // search each position in this line + j = backward ? m - len : 0; + p = txt + j; + while (backward ? j >= 0 : j <= m - len) { + + // compare the strings + for (k = 0; k < len; ++k) { + if (p[k] != s2[k]) { + break; + } + } + + // found it + if (k == len) { + switch (line->rot) { + case 0: + xMin1 = line->edge[line->normalized_idx[j]]; + xMax1 = line->edge[line->normalized_idx[j + len]]; + yMin1 = line->yMin; + yMax1 = line->yMax; + break; + case 1: + xMin1 = line->xMin; + xMax1 = line->xMax; + yMin1 = line->edge[line->normalized_idx[j]]; + yMax1 = line->edge[line->normalized_idx[j + len]]; + break; + case 2: + xMin1 = line->edge[line->normalized_idx[j + len]]; + xMax1 = line->edge[line->normalized_idx[j]]; + yMin1 = line->yMin; + yMax1 = line->yMax; + break; + case 3: + xMin1 = line->xMin; + xMax1 = line->xMax; + yMin1 = line->edge[line->normalized_idx[j + len]]; + yMax1 = line->edge[line->normalized_idx[j]]; + break; + } + if (backward) { + if ((startAtTop || + yMin1 < yStart || (yMin1 == yStart && xMin1 < xStart)) && + (stopAtBottom || + yMin1 > yStop || (yMin1 == yStop && xMin1 > xStop))) { + if (!found || + yMin1 > yMin0 || (yMin1 == yMin0 && xMin1 > xMin0)) { + xMin0 = xMin1; + xMax0 = xMax1; + yMin0 = yMin1; + yMax0 = yMax1; + found = gTrue; + } + } + } else { + if ((startAtTop || + yMin1 > yStart || (yMin1 == yStart && xMin1 > xStart)) && + (stopAtBottom || + yMin1 < yStop || (yMin1 == yStop && xMin1 < xStop))) { + if (!found || + yMin1 < yMin0 || (yMin1 == yMin0 && xMin1 < xMin0)) { + xMin0 = xMin1; + xMax0 = xMax1; + yMin0 = yMin1; + yMax0 = yMax1; + found = gTrue; + } + } + } + } + if (backward) { + --j; + --p; + } else { + ++j; + ++p; + } + } + } + } + + gfree(s2); + if (!caseSensitive) { + gfree(txt); + } + + if (found) { + *xMin = xMin0; + *xMax = xMax0; + *yMin = yMin0; + *yMax = yMax0; + lastFindXMin = xMin0; + lastFindYMin = yMin0; + haveLastFind = gTrue; + return gTrue; + } + + return gFalse; +} + +GooString *TextPage::getText(double xMin, double yMin, + double xMax, double yMax) { + GooString *s; + UnicodeMap *uMap; + GBool isUnicode; + TextBlock *blk; + TextLine *line; + TextLineFrag *frags; + int nFrags, fragsSize; + TextLineFrag *frag; + char space[8], eol[16]; + int spaceLen, eolLen; + int lastRot; + double x, y; + int col, idx0, idx1, i, j; + GBool multiLine, oneRot; + + s = new GooString(); + + if (rawOrder) { + return s; + } + + // get the output encoding + if (!(uMap = globalParams->getTextEncoding())) { + return s; + } + isUnicode = uMap->isUnicode(); + spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); + eolLen = 0; // make gcc happy + switch (globalParams->getTextEOL()) { + case eolUnix: + eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); + break; + case eolDOS: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); + break; + case eolMac: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + break; + } + + //~ writing mode (horiz/vert) + + // collect the line fragments that are in the rectangle + fragsSize = 256; + frags = (TextLineFrag *)gmallocn(fragsSize, sizeof(TextLineFrag)); + nFrags = 0; + lastRot = -1; + oneRot = gTrue; + for (i = 0; i < nBlocks; ++i) { + blk = blocks[i]; + if (xMin < blk->xMax && blk->xMin < xMax && + yMin < blk->yMax && blk->yMin < yMax) { + for (line = blk->lines; line; line = line->next) { + if (xMin < line->xMax && line->xMin < xMax && + yMin < line->yMax && line->yMin < yMax) { + idx0 = idx1 = -1; + switch (line->rot) { + case 0: + y = 0.5 * (line->yMin + line->yMax); + if (yMin < y && y < yMax) { + j = 0; + while (j < line->len) { + if (0.5 * (line->edge[j] + line->edge[j+1]) > xMin) { + idx0 = j; + break; + } + ++j; + } + j = line->len - 1; + while (j >= 0) { + if (0.5 * (line->edge[j] + line->edge[j+1]) < xMax) { + idx1 = j; + break; + } + --j; + } + } + break; + case 1: + x = 0.5 * (line->xMin + line->xMax); + if (xMin < x && x < xMax) { + j = 0; + while (j < line->len) { + if (0.5 * (line->edge[j] + line->edge[j+1]) > yMin) { + idx0 = j; + break; + } + ++j; + } + j = line->len - 1; + while (j >= 0) { + if (0.5 * (line->edge[j] + line->edge[j+1]) < yMax) { + idx1 = j; + break; + } + --j; + } + } + break; + case 2: + y = 0.5 * (line->yMin + line->yMax); + if (yMin < y && y < yMax) { + j = 0; + while (j < line->len) { + if (0.5 * (line->edge[j] + line->edge[j+1]) < xMax) { + idx0 = j; + break; + } + ++j; + } + j = line->len - 1; + while (j >= 0) { + if (0.5 * (line->edge[j] + line->edge[j+1]) > xMin) { + idx1 = j; + break; + } + --j; + } + } + break; + case 3: + x = 0.5 * (line->xMin + line->xMax); + if (xMin < x && x < xMax) { + j = 0; + while (j < line->len) { + if (0.5 * (line->edge[j] + line->edge[j+1]) < yMax) { + idx0 = j; + break; + } + ++j; + } + j = line->len - 1; + while (j >= 0) { + if (0.5 * (line->edge[j] + line->edge[j+1]) > yMin) { + idx1 = j; + break; + } + --j; + } + } + break; + } + if (idx0 >= 0 && idx1 >= 0) { + if (nFrags == fragsSize) { + fragsSize *= 2; + frags = (TextLineFrag *) + greallocn(frags, fragsSize, sizeof(TextLineFrag)); + } + frags[nFrags].init(line, idx0, idx1 - idx0 + 1); + ++nFrags; + if (lastRot >= 0 && line->rot != lastRot) { + oneRot = gFalse; + } + lastRot = line->rot; + } + } + } + } + } + + // sort the fragments and generate the string + if (nFrags > 0) { + + for (i = 0; i < nFrags; ++i) { + frags[i].computeCoords(oneRot); + } + assignColumns(frags, nFrags, oneRot); + + // if all lines in the region have the same rotation, use it; + // otherwise, use the page's primary rotation + if (oneRot) { + qsort(frags, nFrags, sizeof(TextLineFrag), + &TextLineFrag::cmpYXLineRot); + } else { + qsort(frags, nFrags, sizeof(TextLineFrag), + &TextLineFrag::cmpYXPrimaryRot); + } + + col = 0; + multiLine = gFalse; + for (i = 0; i < nFrags; ++i) { + frag = &frags[i]; + + // insert a return + if (frag->col < col || + (i > 0 && fabs(frag->base - frags[i-1].base) > + maxIntraLineDelta * frags[i-1].line->words->fontSize)) { + s->append(eol, eolLen); + col = 0; + multiLine = gTrue; + } + + // column alignment + for (; col < frag->col; ++col) { + s->append(space, spaceLen); + } + + // get the fragment text + col += dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); + } + + if (multiLine) { + s->append(eol, eolLen); + } + } + + gfree(frags); + uMap->decRefCnt(); + + return s; +} + +class TextSelectionVisitor { +public: + TextSelectionVisitor (TextPage *page); + virtual ~TextSelectionVisitor () { } + virtual void visitBlock (TextBlock *block, + TextLine *begin, + TextLine *end, + PDFRectangle *selection) = 0; + virtual void visitLine (TextLine *line, + TextWord *begin, + TextWord *end, + int edge_begin, + int edge_end, + PDFRectangle *selection) = 0; + virtual void visitWord (TextWord *word, int begin, int end, + PDFRectangle *selection) = 0; + +protected: + TextPage *page; +}; + +TextSelectionVisitor::TextSelectionVisitor (TextPage *page) + : page(page) +{ +} + + +class TextSelectionDumper : public TextSelectionVisitor { +public: + TextSelectionDumper(TextPage *page); + virtual ~TextSelectionDumper(); + + virtual void visitBlock (TextBlock *block, + TextLine *begin, + TextLine *end, + PDFRectangle *selection) { }; + virtual void visitLine (TextLine *line, + TextWord *begin, + TextWord *end, + int edge_begin, + int edge_end, + PDFRectangle *selection); + virtual void visitWord (TextWord *word, int begin, int end, + PDFRectangle *selection) { }; + + GooString *getText(void); + +private: + TextLineFrag *frags; + int nFrags, fragsSize; +}; + +TextSelectionDumper::TextSelectionDumper(TextPage *page) + : TextSelectionVisitor(page) +{ + fragsSize = 256; + frags = (TextLineFrag *)gmallocn(fragsSize, sizeof(TextLineFrag)); + nFrags = 0; +} + +TextSelectionDumper::~TextSelectionDumper() +{ + gfree(frags); +} + +void TextSelectionDumper::visitLine (TextLine *line, + TextWord *begin, + TextWord *end, + int edge_begin, + int edge_end, + PDFRectangle *selection) +{ + if (nFrags == fragsSize) { + fragsSize *= 2; + frags = (TextLineFrag *) grealloc(frags, fragsSize * sizeof(TextLineFrag)); + } + + frags[nFrags].init(line, edge_begin, edge_end - edge_begin); + ++nFrags; + +} + +GooString *TextSelectionDumper::getText (void) +{ + GBool oneRot = gTrue; + GooString *s; + TextLineFrag *frag; + int i, col; + GBool multiLine; + UnicodeMap *uMap; + char space[8], eol[16]; + int spaceLen, eolLen; + + s = new GooString(); + + uMap = globalParams->getTextEncoding(); + + if (uMap == NULL) + return s; + + spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); + eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); + + if (nFrags > 0) { + for (i = 0; i < nFrags; ++i) { + frags[i].computeCoords(oneRot); + } + page->assignColumns(frags, nFrags, oneRot); + + // if all lines in the region have the same rotation, use it; + // otherwise, use the page's primary rotation + if (oneRot) { + qsort(frags, nFrags, sizeof(TextLineFrag), + &TextLineFrag::cmpYXLineRot); + } else { + qsort(frags, nFrags, sizeof(TextLineFrag), + &TextLineFrag::cmpYXPrimaryRot); + } + + col = 0; + multiLine = gFalse; + for (i = 0; i < nFrags; ++i) { + frag = &frags[i]; + + // insert a return + if (frag->col < col || + (i > 0 && fabs(frag->base - frags[i-1].base) > + maxIntraLineDelta * frags[i-1].line->words->fontSize)) { + s->append(eol, eolLen); + col = 0; + multiLine = gTrue; + } + + // column alignment + for (; col < frag->col; ++col) { + s->append(space, spaceLen); + } + + // get the fragment text + col += page->dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); + } + + if (multiLine) { + s->append(eol, eolLen); + } + } + + uMap->decRefCnt(); + + return s; +} + +class TextSelectionSizer : public TextSelectionVisitor { +public: + TextSelectionSizer(TextPage *page, double scale); + ~TextSelectionSizer(); + + virtual void visitBlock (TextBlock *block, + TextLine *begin, + TextLine *end, + PDFRectangle *selection) { }; + virtual void visitLine (TextLine *line, + TextWord *begin, + TextWord *end, + int edge_begin, + int edge_end, + PDFRectangle *selection); + virtual void visitWord (TextWord *word, int begin, int end, + PDFRectangle *selection) { }; + + GooList *getRegion(); + +private: + GooList *list; + double scale; +}; + +TextSelectionSizer::TextSelectionSizer(TextPage *page, double scale) + : TextSelectionVisitor(page), + scale(scale) +{ + list = new GooList(); +} + +TextSelectionSizer::~TextSelectionSizer() +{ + delete list; +} + +GooList *TextSelectionSizer::getRegion() +{ + GooList *toReturn = list; + list = NULL; + return toReturn; +} + +void TextSelectionSizer::visitLine (TextLine *line, + TextWord *begin, + TextWord *end, + int edge_begin, + int edge_end, + PDFRectangle *selection) +{ + PDFRectangle *rect; + double x1, y1, x2, y2, margin; + + margin = (line->yMax - line->yMin) / 8; + x1 = line->edge[edge_begin]; + y1 = line->yMin - margin; + x2 = line->edge[edge_end]; + y2 = line->yMax + margin; + + rect = new PDFRectangle (floor (x1 * scale), + floor (y1 * scale), + ceil (x2 * scale), + ceil (y2 * scale)); + list->append (rect); +} + + +class TextSelectionPainter : public TextSelectionVisitor { +public: + TextSelectionPainter(TextPage *page, + double scale, + int rotation, + OutputDev *out, + GfxColor *box_color, + GfxColor *glyph_color); + ~TextSelectionPainter(); + + virtual void visitBlock (TextBlock *block, + TextLine *begin, + TextLine *end, + PDFRectangle *selection) { }; + virtual void visitLine (TextLine *line, + TextWord *begin, + TextWord *end, + int edge_begin, + int edge_end, + PDFRectangle *selection); + virtual void visitWord (TextWord *word, int begin, int end, + PDFRectangle *selection); + +private: + OutputDev *out; + GfxColor *box_color, *glyph_color; + GfxState *state; +}; + +TextSelectionPainter::TextSelectionPainter(TextPage *page, + double scale, + int rotation, + OutputDev *out, + GfxColor *box_color, + GfxColor *glyph_color) + : TextSelectionVisitor(page), + out(out), + box_color(box_color), + glyph_color(glyph_color) +{ + PDFRectangle box(0, 0, page->pageWidth, page->pageHeight); + + state = new GfxState(72 * scale, 72 * scale, &box, rotation, gFalse); + + out->startPage (0, state); + out->setDefaultCTM (state->getCTM()); + + state->setTextMat(1, 0, 0, -1, 0, 0); + state->setFillColorSpace(new GfxDeviceRGBColorSpace()); + +} + +TextSelectionPainter::~TextSelectionPainter() +{ + out->endPage (); + + delete state; +} + +void TextSelectionPainter::visitLine (TextLine *line, + TextWord *begin, + TextWord *end, + int edge_begin, + int edge_end, + PDFRectangle *selection) +{ + double x1, y1, x2, y2, margin; + Matrix ctm, ictm; + + state->setFillColor(box_color); + out->updateFillColor(state); + + margin = (line->yMax - line->yMin) / 8; + x1 = floor (line->edge[edge_begin]); + y1 = floor (line->yMin - margin); + x2 = ceil (line->edge[edge_end]); + y2 = ceil (line->yMax + margin); + + state->getCTM (&ctm); + ctm.transform(line->edge[edge_begin], line->yMin - margin, &x1, &y1); + ctm.transform(line->edge[edge_end], line->yMax + margin, &x2, &y2); + + x1 = floor (x1); + y1 = floor (y1); + x2 = ceil (x2); + y2 = ceil (y2); + + ctm.invertTo (&ictm); + ictm.transform(x1, y1, &x1, &y1); + ictm.transform(x2, y2, &x2, &y2); + + state->moveTo(x1, y1); + state->lineTo(x2, y1); + state->lineTo(x2, y2); + state->lineTo(x1, y2); + state->closePath(); + + out->fill(state); + state->clearPath(); +} + +void TextSelectionPainter::visitWord (TextWord *word, int begin, int end, + PDFRectangle *selection) +{ + GooString *string; + int i; + + state->setFillColor(glyph_color); + out->updateFillColor(state); + word->font->gfxFont->incRefCnt(); + state->setFont(word->font->gfxFont, word->fontSize); + out->updateFont(state); + + /* The only purpose of this string is to let the output device query + * it's length. Might want to change this interface later. */ + + string = new GooString ((char *) word->charcode, end - begin); + + out->beginString(state, string); + + for (i = begin; i < end; i++) + out->drawChar(state, word->edge[i], word->base, 0, 0, 0, 0, + word->charcode[i], 1, NULL, 0); + + out->endString(state); + + delete string; +} + +void TextWord::visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection) +{ + int i, begin, end; + double mid; + + begin = len; + end = 0; + for (i = 0; i < len; i++) { + mid = (edge[i] + edge[i + 1]) / 2; + if (selection->x1 < mid || selection->x2 < mid) + if (i < begin) + begin = i; + if (mid < selection->x1 || mid < selection->x2) + end = i + 1; + } + + /* Skip empty selection. */ + if (end <= begin) + return; + + visitor->visitWord (this, begin, end, selection); +} + +void TextLine::visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection) { + TextWord *p, *begin, *end; + int i, edge_begin, edge_end; + + begin = NULL; + end = NULL; + for (p = words; p != NULL; p = p->next) { + if ((selection->x1 < p->xMax && selection->y1 < p->yMax) || + (selection->x2 < p->xMax && selection->y2 < p->yMax)) + if (begin == NULL) + begin = p; + if ((selection->x1 > p->xMin && selection->y1 > p->yMin || + selection->x2 > p->xMin && selection->y2 > p->yMin) && (begin != NULL)) + end = p->next; + } + + edge_begin = len; + edge_end = 0; + for (i = 0; i < len; i++) { + double mid = (edge[i] + edge[i + 1]) / 2; + if (selection->x1 < mid || selection->x2 < mid) + if (i < edge_begin) + edge_begin = i; + if (mid < selection->x2 || mid < selection->x1) + edge_end = i + 1; + } + + /* Skip empty selection. */ + if (edge_end <= edge_begin) + return; + + visitor->visitLine (this, begin, end, edge_begin, edge_end, selection); + + for (p = begin; p != end; p = p->next) + p->visitSelection (visitor, selection); +} + +void TextBlock::visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection) { + TextLine *p, *begin, *end; + PDFRectangle child_selection; + double start_x, start_y, stop_x, stop_y; + + begin = NULL; + end = NULL; + start_x = selection->x1; + start_y = selection->y1; + stop_x = selection->x2; + stop_y = selection->y2; + + for (p = lines; p != NULL; p = p->next) { + if (selection->x1 < p->xMax && selection->y1 < p->yMax && + selection->x2 < p->xMax && selection->y2 < p->yMax && begin == NULL) { + begin = p; + if (selection->x1 < selection->x2) { + start_x = selection->x1; + start_y = selection->y1; + stop_x = selection->x2; + stop_y = selection->y2; + } else { + start_x = selection->x2; + start_y = selection->y2; + stop_x = selection->x1; + stop_y = selection->y1; + } + } else if (selection->x1 < p->xMax && selection->y1 < p->yMax && begin == NULL) { + begin = p; + start_x = selection->x1; + start_y = selection->y1; + stop_x = selection->x2; + stop_y = selection->y2; + } else if (selection->x2 < p->xMax && selection->y2 < p->yMax && begin == NULL) { + begin = p; + start_x = selection->x2; + start_y = selection->y2; + stop_x = selection->x1; + stop_y = selection->y1; + } + + if ((selection->x1 > p->xMin && selection->y1 > p->yMin || + selection->x2 > p->xMin && selection->y2 > p->yMin) && (begin != NULL)) + end = p->next; + } + + /* Skip empty selection. */ + if (end == begin) + return; + + visitor->visitBlock (this, begin, end, selection); + + for (p = begin; p != end; p = p->next) { + if (p == begin) { + child_selection.x1 = start_x; + child_selection.y1 = start_y; + } else { + child_selection.x1 = 0; + child_selection.y1 = 0; + } + if (p->next == end) { + child_selection.x2 = stop_x; + child_selection.y2 = stop_y; + } else { + child_selection.x2 = page->pageWidth; + child_selection.y2 = page->pageHeight; + } + + p->visitSelection(visitor, &child_selection); + } +} + +void TextPage::visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection) +{ + int i, begin, end; + PDFRectangle child_selection; + double start_x, start_y, stop_x, stop_y; + TextBlock *b; + + begin = nBlocks; + end = 0; + start_x = selection->x1; + start_y = selection->y1; + stop_x = selection->x2; + stop_y = selection->y2; + + for (i = 0; i < nBlocks; i++) { + b = blocks[i]; + + if (selection->x1 < b->xMax && selection->y1 < b->yMax && + selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { + begin = i; + if (selection->y1 < selection->y2) { + start_x = selection->x1; + start_y = selection->y1; + stop_x = selection->x2; + stop_y = selection->y2; + } else { + start_x = selection->x2; + start_y = selection->y2; + stop_x = selection->x1; + stop_y = selection->y1; + } + } else if (selection->x1 < b->xMax && selection->y1 < b->yMax && i < begin) { + begin = i; + start_x = selection->x1; + start_y = selection->y1; + stop_x = selection->x2; + stop_y = selection->y2; + } else if (selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { + begin = i; + start_x = selection->x2; + start_y = selection->y2; + stop_x = selection->x1; + stop_y = selection->y1; + } + + if (selection->x1 > b->xMin && selection->y1 > b->yMin || + selection->x2 > b->xMin && selection->y2 > b->yMin) + end = i + 1; + } + + for (i = begin; i < end; i++) { + if (blocks[i]->xMin < start_x && start_x < blocks[i]->xMax && + blocks[i]->yMin < start_y && start_y < blocks[i]->yMax) { + child_selection.x1 = start_x; + child_selection.y1 = start_y; + } else { + child_selection.x1 = 0; + child_selection.y1 = 0; + } + if (blocks[i]->xMin < stop_x && stop_x < blocks[i]->xMax && + blocks[i]->yMin < stop_y && stop_y < blocks[i]->yMax) { + child_selection.x2 = stop_x; + child_selection.y2 = stop_y; + } else { + child_selection.x2 = pageWidth; + child_selection.y2 = pageHeight; + } + + blocks[i]->visitSelection(visitor, &child_selection); + } +} + +void TextPage::drawSelection(OutputDev *out, + double scale, + int rotation, + PDFRectangle *selection, + GfxColor *glyph_color, GfxColor *box_color) +{ + TextSelectionPainter painter(this, scale, rotation, + out, box_color, glyph_color); + + visitSelection(&painter, selection); +} + +GooList *TextPage::getSelectionRegion(PDFRectangle *selection, + double scale) { + TextSelectionSizer sizer(this, scale); + + visitSelection(&sizer, selection); + + return sizer.getRegion(); +} + +GooString *TextPage::getSelectionText(PDFRectangle *selection) +{ + TextSelectionDumper dumper(this); + + visitSelection(&dumper, selection); + + return dumper.getText(); +} + +GBool TextPage::findCharRange(int pos, int length, + double *xMin, double *yMin, + double *xMax, double *yMax) { + TextBlock *blk; + TextLine *line; + TextWord *word; + double xMin0, xMax0, yMin0, yMax0; + double xMin1, xMax1, yMin1, yMax1; + GBool first; + int i, j0, j1; + + if (rawOrder) { + return gFalse; + } + + //~ this doesn't correctly handle: + //~ - ranges split across multiple lines (the highlighted region + //~ is the bounding box of all the parts of the range) + //~ - cases where characters don't convert one-to-one into Unicode + first = gTrue; + xMin0 = xMax0 = yMin0 = yMax0 = 0; // make gcc happy + xMin1 = xMax1 = yMin1 = yMax1 = 0; // make gcc happy + for (i = 0; i < nBlocks; ++i) { + blk = blocks[i]; + for (line = blk->lines; line; line = line->next) { + for (word = line->words; word; word = word->next) { + if (pos < word->charPos + word->charLen && + word->charPos < pos + length) { + j0 = pos - word->charPos; + if (j0 < 0) { + j0 = 0; + } + j1 = pos + length - 1 - word->charPos; + if (j1 >= word->len) { + j1 = word->len - 1; + } + switch (line->rot) { + case 0: + xMin1 = word->edge[j0]; + xMax1 = word->edge[j1 + 1]; + yMin1 = word->yMin; + yMax1 = word->yMax; + break; + case 1: + xMin1 = word->xMin; + xMax1 = word->xMax; + yMin1 = word->edge[j0]; + yMax1 = word->edge[j1 + 1]; + break; + case 2: + xMin1 = word->edge[j1 + 1]; + xMax1 = word->edge[j0]; + yMin1 = word->yMin; + yMax1 = word->yMax; + break; + case 3: + xMin1 = word->xMin; + xMax1 = word->xMax; + yMin1 = word->edge[j1 + 1]; + yMax1 = word->edge[j0]; + break; + } + if (first || xMin1 < xMin0) { + xMin0 = xMin1; + } + if (first || xMax1 > xMax0) { + xMax0 = xMax1; + } + if (first || yMin1 < yMin0) { + yMin0 = yMin1; + } + if (first || yMax1 > yMax0) { + yMax0 = yMax1; + } + first = gFalse; + } + } + } + } + if (!first) { + *xMin = xMin0; + *xMax = xMax0; + *yMin = yMin0; + *yMax = yMax0; + return gTrue; + } + return gFalse; +} + +void TextPage::dump(void *outputStream, TextOutputFunc outputFunc, + GBool physLayout) { + UnicodeMap *uMap; + TextFlow *flow; + TextBlock *blk; + TextLine *line; + TextLineFrag *frags; + TextWord *word; + int nFrags, fragsSize; + TextLineFrag *frag; + char space[8], eol[16], eop[8]; + int spaceLen, eolLen, eopLen; + GBool pageBreaks; + GooString *s; + int col, i, d, n; + + // get the output encoding + if (!(uMap = globalParams->getTextEncoding())) { + return; + } + spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); + eolLen = 0; // make gcc happy + switch (globalParams->getTextEOL()) { + case eolUnix: + eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); + break; + case eolDOS: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); + break; + case eolMac: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + break; + } + eopLen = uMap->mapUnicode(0x0c, eop, sizeof(eop)); + pageBreaks = globalParams->getTextPageBreaks(); + + //~ writing mode (horiz/vert) + + // output the page in raw (content stream) order + if (rawOrder) { + + for (word = rawWords; word; word = word->next) { + s = new GooString(); + dumpFragment(word->text, word->len, uMap, s); + (*outputFunc)(outputStream, s->getCString(), s->getLength()); + delete s; + if (word->next && + fabs(word->next->base - word->base) < + maxIntraLineDelta * word->fontSize) { + if (word->next->xMin > word->xMax + minWordSpacing * word->fontSize) { + (*outputFunc)(outputStream, space, spaceLen); + } + } else { + (*outputFunc)(outputStream, eol, eolLen); + } + } + + // output the page, maintaining the original physical layout + } else if (physLayout) { + + // collect the line fragments for the page and sort them + fragsSize = 256; + frags = (TextLineFrag *)gmallocn(fragsSize, sizeof(TextLineFrag)); + nFrags = 0; + for (i = 0; i < nBlocks; ++i) { + blk = blocks[i]; + for (line = blk->lines; line; line = line->next) { + if (nFrags == fragsSize) { + fragsSize *= 2; + frags = (TextLineFrag *)greallocn(frags, + fragsSize, sizeof(TextLineFrag)); + } + frags[nFrags].init(line, 0, line->len); + frags[nFrags].computeCoords(gTrue); + ++nFrags; + } + } + qsort(frags, nFrags, sizeof(TextLineFrag), &TextLineFrag::cmpYXPrimaryRot); + +#if 0 // for debugging + printf("*** line fragments ***\n"); + for (i = 0; i < nFrags; ++i) { + frag = &frags[i]; + printf("frag: x=%.2f..%.2f y=%.2f..%.2f base=%.2f '", + frag->xMin, frag->xMax, frag->yMin, frag->yMax, frag->base); + for (n = 0; n < frag->len; ++n) { + fputc(frag->line->text[frag->start + n] & 0xff, stdout); + } + printf("'\n"); + } + printf("\n"); +#endif + + // generate output + col = 0; + for (i = 0; i < nFrags; ++i) { + frag = &frags[i]; + + // column alignment + for (; col < frag->col; ++col) { + (*outputFunc)(outputStream, space, spaceLen); + } + + // print the line + s = new GooString(); + col += dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); + (*outputFunc)(outputStream, s->getCString(), s->getLength()); + delete s; + + // print one or more returns if necessary + if (i == nFrags - 1 || + frags[i+1].col < col || + fabs(frags[i+1].base - frag->base) > + maxIntraLineDelta * frag->line->words->fontSize) { + if (i < nFrags - 1) { + d = (int)((frags[i+1].base - frag->base) / + frag->line->words->fontSize); + if (d < 1) { + d = 1; + } else if (d > 5) { + d = 5; + } + } else { + d = 1; + } + for (; d > 0; --d) { + (*outputFunc)(outputStream, eol, eolLen); + } + col = 0; + } + } + + gfree(frags); + + // output the page, "undoing" the layout + } else { + for (flow = flows; flow; flow = flow->next) { + for (blk = flow->blocks; blk; blk = blk->next) { + for (line = blk->lines; line; line = line->next) { + n = line->len; + if (line->hyphenated && (line->next || blk->next)) { + --n; + } + s = new GooString(); + dumpFragment(line->text, n, uMap, s); + (*outputFunc)(outputStream, s->getCString(), s->getLength()); + delete s; + if (!line->hyphenated) { + if (line->next) { + (*outputFunc)(outputStream, space, spaceLen); + } else if (blk->next) { + //~ this is a bit of a kludge - we should really do a more + //~ intelligent determination of paragraphs + if (blk->next->lines->words->fontSize == + blk->lines->words->fontSize) { + (*outputFunc)(outputStream, space, spaceLen); + } else { + (*outputFunc)(outputStream, eol, eolLen); + } + } + } + } + } + (*outputFunc)(outputStream, eol, eolLen); + (*outputFunc)(outputStream, eol, eolLen); + } + } + + // end of page + if (pageBreaks) { + (*outputFunc)(outputStream, eop, eopLen); + } + + uMap->decRefCnt(); +} + +void TextPage::assignColumns(TextLineFrag *frags, int nFrags, GBool oneRot) { + TextLineFrag *frag0, *frag1; + int rot, col1, col2, i, j, k; + + // all text in the region has the same rotation -- recompute the + // column numbers based only on the text in the region + if (oneRot) { + qsort(frags, nFrags, sizeof(TextLineFrag), &TextLineFrag::cmpXYLineRot); + rot = frags[0].line->rot; + for (i = 0; i < nFrags; ++i) { + frag0 = &frags[i]; + col1 = 0; + for (j = 0; j < i; ++j) { + frag1 = &frags[j]; + col2 = 0; // make gcc happy + switch (rot) { + case 0: + if (frag0->xMin >= frag1->xMax) { + col2 = frag1->col + (frag1->line->col[frag1->start + frag1->len] - + frag1->line->col[frag1->start]) + 1; + } else { + for (k = frag1->start; + k < frag1->start + frag1->len && + frag0->xMin >= 0.5 * (frag1->line->edge[k] + + frag1->line->edge[k+1]); + ++k) ; + col2 = frag1->col + + frag1->line->col[k] - frag1->line->col[frag1->start]; + } + break; + case 1: + if (frag0->yMin >= frag1->yMax) { + col2 = frag1->col + (frag1->line->col[frag1->start + frag1->len] - + frag1->line->col[frag1->start]) + 1; + } else { + for (k = frag1->start; + k < frag1->start + frag1->len && + frag0->yMin >= 0.5 * (frag1->line->edge[k] + + frag1->line->edge[k+1]); + ++k) ; + col2 = frag1->col + + frag1->line->col[k] - frag1->line->col[frag1->start]; + } + break; + case 2: + if (frag0->xMax <= frag1->xMin) { + col2 = frag1->col + (frag1->line->col[frag1->start + frag1->len] - + frag1->line->col[frag1->start]) + 1; + } else { + for (k = frag1->start; + k < frag1->start + frag1->len && + frag0->xMax <= 0.5 * (frag1->line->edge[k] + + frag1->line->edge[k+1]); + ++k) ; + col2 = frag1->col + + frag1->line->col[k] - frag1->line->col[frag1->start]; + } + break; + case 3: + if (frag0->yMax <= frag1->yMin) { + col2 = frag1->col + (frag1->line->col[frag1->start + frag1->len] - + frag1->line->col[frag1->start]) + 1; + } else { + for (k = frag1->start; + k < frag1->start + frag1->len && + frag0->yMax <= 0.5 * (frag1->line->edge[k] + + frag1->line->edge[k+1]); + ++k) ; + col2 = frag1->col + + frag1->line->col[k] - frag1->line->col[frag1->start]; + } + break; + } + if (col2 > col1) { + col1 = col2; + } + } + frag0->col = col1; + } + + // the region includes text at different rotations -- use the + // globally assigned column numbers, offset by the minimum column + // number (i.e., shift everything over to column 0) + } else { + col1 = frags[0].col; + for (i = 1; i < nFrags; ++i) { + if (frags[i].col < col1) { + col1 = frags[i].col; + } + } + for (i = 0; i < nFrags; ++i) { + frags[i].col -= col1; + } + } +} + +int TextPage::dumpFragment(Unicode *text, int len, UnicodeMap *uMap, + GooString *s) { + char lre[8], rle[8], popdf[8], buf[8]; + int lreLen, rleLen, popdfLen, n; + int nCols, i, j, k; + + nCols = 0; + + if (uMap->isUnicode()) { + + lreLen = uMap->mapUnicode(0x202a, lre, sizeof(lre)); + rleLen = uMap->mapUnicode(0x202b, rle, sizeof(rle)); + popdfLen = uMap->mapUnicode(0x202c, popdf, sizeof(popdf)); + + if (primaryLR) { + + i = 0; + while (i < len) { + // output a left-to-right section + for (j = i; j < len && !unicodeTypeR(text[j]); ++j) ; + for (k = i; k < j; ++k) { + n = uMap->mapUnicode(text[k], buf, sizeof(buf)); + s->append(buf, n); + ++nCols; + } + i = j; + // output a right-to-left section + for (j = i; j < len && !unicodeTypeL(text[j]); ++j) ; + if (j > i) { + s->append(rle, rleLen); + for (k = j - 1; k >= i; --k) { + n = uMap->mapUnicode(text[k], buf, sizeof(buf)); + s->append(buf, n); + ++nCols; + } + s->append(popdf, popdfLen); + i = j; + } + } + + } else { + + s->append(rle, rleLen); + i = len - 1; + while (i >= 0) { + // output a right-to-left section + for (j = i; j >= 0 && !unicodeTypeL(text[j]); --j) ; + for (k = i; k > j; --k) { + n = uMap->mapUnicode(text[k], buf, sizeof(buf)); + s->append(buf, n); + ++nCols; + } + i = j; + // output a left-to-right section + for (j = i; j >= 0 && !unicodeTypeR(text[j]); --j) ; + if (j < i) { + s->append(lre, lreLen); + for (k = j + 1; k <= i; ++k) { + n = uMap->mapUnicode(text[k], buf, sizeof(buf)); + s->append(buf, n); + ++nCols; + } + s->append(popdf, popdfLen); + i = j; + } + } + s->append(popdf, popdfLen); + + } + + } else { + for (i = 0; i < len; ++i) { + n = uMap->mapUnicode(text[i], buf, sizeof(buf)); + s->append(buf, n); + nCols += n; + } + } + + return nCols; +} + +#if TEXTOUT_WORD_LIST +TextWordList *TextPage::makeWordList(GBool physLayout) { + return new TextWordList(this, physLayout); +} +#endif + +//------------------------------------------------------------------------ +// TextOutputDev +//------------------------------------------------------------------------ + +static void outputToFile(void *stream, char *text, int len) { + fwrite(text, 1, len, (FILE *)stream); +} + +TextOutputDev::TextOutputDev(char *fileName, GBool physLayoutA, + GBool rawOrderA, GBool append) { + text = NULL; + physLayout = physLayoutA; + rawOrder = rawOrderA; + ok = gTrue; + + // open file + needClose = gFalse; + if (fileName) { + if (!strcmp(fileName, "-")) { + outputStream = stdout; +#ifdef WIN32 + // keep DOS from munging the end-of-line characters + setmode(fileno(stdout), O_BINARY); +#endif + } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) { + needClose = gTrue; + } else { + error(-1, "Couldn't open text file '%s'", fileName); + ok = gFalse; + return; + } + outputFunc = &outputToFile; + } else { + outputStream = NULL; + } + + // set up text object + text = new TextPage(rawOrderA); +} + +TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream, + GBool physLayoutA, GBool rawOrderA) { + outputFunc = func; + outputStream = stream; + needClose = gFalse; + physLayout = physLayoutA; + rawOrder = rawOrderA; + text = new TextPage(rawOrderA); + ok = gTrue; +} + +TextOutputDev::~TextOutputDev() { + if (needClose) { +#ifdef MACOS + ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle); +#endif + fclose((FILE *)outputStream); + } + if (text) { + delete text; + } +} + +void TextOutputDev::startPage(int pageNum, GfxState *state) { + text->startPage(state); +} + +void TextOutputDev::endPage() { + text->endPage(); + text->coalesce(physLayout); + if (outputStream) { + text->dump(outputStream, outputFunc, physLayout); + } +} + +void TextOutputDev::updateFont(GfxState *state) { + text->updateFont(state); +} + +void TextOutputDev::beginString(GfxState *state, GooString *s) { +} + +void TextOutputDev::endString(GfxState *state) { +} + +void TextOutputDev::drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode c, int nBytes, Unicode *u, int uLen) { + text->addChar(state, x, y, dx, dy, c, nBytes, u, uLen); +} + +GBool TextOutputDev::findText(Unicode *s, int len, + GBool startAtTop, GBool stopAtBottom, + GBool startAtLast, GBool stopAtLast, + GBool caseSensitive, GBool backward, + double *xMin, double *yMin, + double *xMax, double *yMax) { + return text->findText(s, len, startAtTop, stopAtBottom, + startAtLast, stopAtLast, caseSensitive, backward, + xMin, yMin, xMax, yMax); +} + +GooString *TextOutputDev::getText(double xMin, double yMin, + double xMax, double yMax) { + return text->getText(xMin, yMin, xMax, yMax); +} + +void TextOutputDev::drawSelection(OutputDev *out, + double scale, + int rotation, + PDFRectangle *selection, + GfxColor *glyph_color, GfxColor *box_color) { + text->drawSelection(out, scale, rotation, selection, glyph_color, box_color); +} + +GooList *TextOutputDev::getSelectionRegion(PDFRectangle *selection, + double scale) { + return text->getSelectionRegion(selection, scale); +} + +GooString *TextOutputDev::getSelectionText(PDFRectangle *selection) +{ + return text->getSelectionText(selection); +} + +GBool TextOutputDev::findCharRange(int pos, int length, + double *xMin, double *yMin, + double *xMax, double *yMax) { + return text->findCharRange(pos, length, xMin, yMin, xMax, yMax); +} + +#if TEXTOUT_WORD_LIST +TextWordList *TextOutputDev::makeWordList() { + return text->makeWordList(physLayout); +} +#endif + +TextPage *TextOutputDev::takeText() { + TextPage *ret; + + ret = text; + text = new TextPage(rawOrder); + return ret; +} diff --git a/rosapps/smartpdf/poppler/poppler/TextOutputDev.h b/rosapps/smartpdf/poppler/poppler/TextOutputDev.h new file mode 100644 index 00000000000..9d5c2ac4d1a --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/TextOutputDev.h @@ -0,0 +1,639 @@ +//======================================================================== +// +// TextOutputDev.h +// +// Copyright 1997-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef TEXTOUTPUTDEV_H +#define TEXTOUTPUTDEV_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "poppler-config.h" +#include +#include "goo/gtypes.h" +#include "GfxFont.h" +#include "GfxState.h" +#include "OutputDev.h" + +class GooString; +class GooList; +class Gfx; +class GfxFont; +class GfxState; +class UnicodeMap; + +class TextWord; +class TextPool; +class TextLine; +class TextLineFrag; +class TextBlock; +class TextFlow; +class TextWordList; +class TextPage; +class TextSelectionVisitor; + +//------------------------------------------------------------------------ + +typedef void (*TextOutputFunc)(void *stream, char *text, int len); + +//------------------------------------------------------------------------ +// TextFontInfo +//------------------------------------------------------------------------ + +class TextFontInfo { +public: + + TextFontInfo(GfxState *state); + ~TextFontInfo(); + + GBool matches(GfxState *state); + +private: + + GfxFont *gfxFont; +#if TEXTOUT_WORD_LIST + GooString *fontName; +#endif + + friend class TextWord; + friend class TextPage; + friend class TextSelectionPainter; +}; + +//------------------------------------------------------------------------ +// TextWord +//------------------------------------------------------------------------ + +class TextWord { +public: + + // Constructor. + TextWord(GfxState *state, int rotA, double x0, double y0, + int charPosA, TextFontInfo *fontA, double fontSize); + + // Destructor. + ~TextWord(); + + // Add a character to the word. + void addChar(GfxState *state, double x, double y, + double dx, double dy, CharCode c, Unicode u); + + // Merge onto the end of . + void merge(TextWord *word); + + // Compares to , returning -1 (<), 0 (=), or +1 (>), + // based on a primary-axis comparison, e.g., x ordering if rot=0. + int primaryCmp(TextWord *word); + + // Return the distance along the primary axis between and + // . + double primaryDelta(TextWord *word); + + static int cmpYX(const void *p1, const void *p2); + + void visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection); + +#if TEXTOUT_WORD_LIST + int getLength() { return len; } + const Unicode *getChar(int idx) { return &text[idx]; } + GooString *getText(); + GooString *getFontName() { return font->fontName; } + void getColor(double *r, double *g, double *b) + { *r = colorR; *g = colorG; *b = colorB; } + void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA) + { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } + double getFontSize() { return fontSize; } + int getRotation() { return rot; } + int getCharPos() { return charPos; } + int getCharLen() { return charLen; } +#endif + double getEdge(int i) { return edge[i]; } + double getBaseline () { return base; } + GBool hasSpaceAfter () { return spaceAfter; } + TextWord* nextWord () { return next; }; +private: + + int rot; // rotation, multiple of 90 degrees + // (0, 1, 2, or 3) + double xMin, xMax; // bounding box x coordinates + double yMin, yMax; // bounding box y coordinates + double base; // baseline x or y coordinate + Unicode *text; // the text + CharCode *charcode; // glyph indices + double *edge; // "near" edge x or y coord of each char + // (plus one extra entry for the last char) + int len; // length of text and edge arrays + int size; // size of text and edge arrays + int charPos; // character position (within content stream) + int charLen; // number of content stream characters in + // this word + TextFontInfo *font; // font information + double fontSize; // font size + GBool spaceAfter; // set if there is a space between this + // word and the next word on the line + TextWord *next; // next word in line + +#if TEXTOUT_WORD_LIST + double colorR, // word color + colorG, + colorB; +#endif + + friend class TextPool; + friend class TextLine; + friend class TextBlock; + friend class TextFlow; + friend class TextWordList; + friend class TextPage; + + friend class TextSelectionPainter; + friend class TextSelectionDumper; +}; + +//------------------------------------------------------------------------ +// TextPool +//------------------------------------------------------------------------ + +class TextPool { +public: + + TextPool(); + ~TextPool(); + + TextWord *getPool(int baseIdx) { return pool[baseIdx - minBaseIdx]; } + void setPool(int baseIdx, TextWord *p) { pool[baseIdx - minBaseIdx] = p; } + + int getBaseIdx(double base); + + void addWord(TextWord *word); + +private: + + int minBaseIdx; // min baseline bucket index + int maxBaseIdx; // max baseline bucket index + TextWord **pool; // array of linked lists, one for each + // baseline value (multiple of 4 pts) + TextWord *cursor; // pointer to last-accessed word + int cursorBaseIdx; // baseline bucket index of last-accessed word + + friend class TextBlock; + friend class TextPage; +}; + +struct TextFlowData; + +//------------------------------------------------------------------------ +// TextLine +//------------------------------------------------------------------------ + +class TextLine { +public: + + TextLine(TextBlock *blkA, int rotA, double baseA); + ~TextLine(); + + void addWord(TextWord *word); + + // Return the distance along the primary axis between and + // . + double primaryDelta(TextLine *line); + + // Compares to , returning -1 (<), 0 (=), or +1 (>), + // based on a primary-axis comparison, e.g., x ordering if rot=0. + int primaryCmp(TextLine *line); + + // Compares to , returning -1 (<), 0 (=), or +1 (>), + // based on a secondary-axis comparison of the baselines, e.g., y + // ordering if rot=0. + int secondaryCmp(TextLine *line); + + int cmpYX(TextLine *line); + + static int cmpXY(const void *p1, const void *p2); + + void coalesce(UnicodeMap *uMap); + + void visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection); + +private: + + TextBlock *blk; // parent block + int rot; // text rotation + double xMin, xMax; // bounding box x coordinates + double yMin, yMax; // bounding box y coordinates + double base; // baseline x or y coordinate + TextWord *words; // words in this line + TextWord *lastWord; // last word in this line + Unicode *text; // Unicode text of the line, including + // spaces between words + double *edge; // "near" edge x or y coord of each char + // (plus one extra entry for the last char) + int *col; // starting column number of each Unicode char + int len; // number of Unicode chars + int convertedLen; // total number of converted characters + GBool hyphenated; // set if last char is a hyphen + TextLine *next; // next line in block + Unicode *normalized; // normalized form of Unicode text + int normalized_len; // number of normalized Unicode chars + int *normalized_idx; // indices of normalized chars into Unicode text + + friend class TextLineFrag; + friend class TextBlock; + friend class TextFlow; + friend class TextWordList; + friend class TextPage; + + friend class TextSelectionPainter; + friend class TextSelectionSizer; + friend class TextSelectionDumper; +}; + +//------------------------------------------------------------------------ +// TextBlock +//------------------------------------------------------------------------ + +class TextBlock { +public: + + TextBlock(TextPage *pageA, int rotA); + ~TextBlock(); + + void addWord(TextWord *word); + + void coalesce(UnicodeMap *uMap); + + // Update this block's priMin and priMax values, looking at . + void updatePriMinMax(TextBlock *blk); + + static int cmpXYPrimaryRot(const void *p1, const void *p2); + + static int cmpYXPrimaryRot(const void *p1, const void *p2); + + int primaryCmp(TextBlock *blk); + + double secondaryDelta(TextBlock *blk); + + // Returns true if is below , relative to the page's + // primary rotation. + GBool isBelow(TextBlock *blk); + + void visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection); + +private: + + TextPage *page; // the parent page + int rot; // text rotation + double xMin, xMax; // bounding box x coordinates + double yMin, yMax; // bounding box y coordinates + double priMin, priMax; // whitespace bounding box along primary axis + + TextPool *pool; // pool of words (used only until lines + // are built) + TextLine *lines; // linked list of lines + TextLine *curLine; // most recently added line + int nLines; // number of lines + int charCount; // number of characters in the block + int col; // starting column + int nColumns; // number of columns in the block + + TextBlock *next; + TextBlock *stackNext; + + friend class TextLine; + friend class TextLineFrag; + friend class TextFlow; + friend class TextWordList; + friend class TextPage; + friend class TextSelectionPainter; +}; + +//------------------------------------------------------------------------ +// TextFlow +//------------------------------------------------------------------------ + +class TextFlow { +public: + + TextFlow(TextPage *pageA, TextBlock *blk); + ~TextFlow(); + + // Add a block to the end of this flow. + void addBlock(TextBlock *blk); + + // Returns true if fits below in the flow, i.e., (1) + // it uses a font no larger than the last block added to the flow, + // and (2) it fits within the flow's [priMin, priMax] along the + // primary axis. + GBool blockFits(TextBlock *blk, TextBlock *prevBlk); + +private: + + TextPage *page; // the parent page + double xMin, xMax; // bounding box x coordinates + double yMin, yMax; // bounding box y coordinates + double priMin, priMax; // whitespace bounding box along primary axis + TextBlock *blocks; // blocks in flow + TextBlock *lastBlk; // last block in this flow + TextFlow *next; + + friend class TextWordList; + friend class TextPage; +}; + +#if TEXTOUT_WORD_LIST + +//------------------------------------------------------------------------ +// TextWordList +//------------------------------------------------------------------------ + +class TextWordList { +public: + + // Build a flat word list, in content stream order (if + // text->rawOrder is true), physical layout order (if + // is true and text->rawOrder is false), or reading order (if both + // flags are false). + TextWordList(TextPage *text, GBool physLayout); + + ~TextWordList(); + + // Return the number of words on the list. + int getLength(); + + // Return the th word from the list. + TextWord *get(int idx); + +private: + + GooList *words; +}; + +#endif // TEXTOUT_WORD_LIST + +//------------------------------------------------------------------------ +// TextPage +//------------------------------------------------------------------------ + +class TextPage { +public: + + // Constructor. + TextPage(GBool rawOrderA); + + // Destructor. + ~TextPage(); + + // Start a new page. + void startPage(GfxState *state); + + // End the current page. + void endPage(); + + // Update the current font. + void updateFont(GfxState *state); + + // Begin a new word. + void beginWord(GfxState *state, double x0, double y0); + + // Add a character to the current word. + void addChar(GfxState *state, double x, double y, + double dx, double dy, + CharCode c, int nBytes, Unicode *u, int uLen); + + // End the current word, sorting it into the list of words. + void endWord(); + + // Add a word, sorting it into the list of words. + void addWord(TextWord *word); + + // Coalesce strings that look like parts of the same line. + void coalesce(GBool physLayout); + + // Find a string. If is true, starts looking at the + // top of the page; else if is true, starts looking + // immediately after the last find result; else starts looking at + // ,. If is true, stops looking at the + // bottom of the page; else if is true, stops looking + // just before the last find result; else stops looking at + // ,. + GBool findText(Unicode *s, int len, + GBool startAtTop, GBool stopAtBottom, + GBool startAtLast, GBool stopAtLast, + GBool caseSensitive, GBool backward, + double *xMin, double *yMin, + double *xMax, double *yMax); + + // Get the text which is inside the specified rectangle. + GooString *getText(double xMin, double yMin, + double xMax, double yMax); + + void visitSelection(TextSelectionVisitor *visitor, + PDFRectangle *selection); + + void drawSelection(OutputDev *out, + double scale, + int rotation, + PDFRectangle *selection, + GfxColor *glyph_color, GfxColor *box_color); + + GooList *getSelectionRegion(PDFRectangle *selection, double scale); + + GooString *getSelectionText(PDFRectangle *selection); + + // Find a string by character position and length. If found, sets + // the text bounding rectangle and returns true; otherwise returns + // false. + GBool findCharRange(int pos, int length, + double *xMin, double *yMin, + double *xMax, double *yMax); + + // Dump contents of page to a file. + void dump(void *outputStream, TextOutputFunc outputFunc, + GBool physLayout); + +#if TEXTOUT_WORD_LIST + // Build a flat word list, in content stream order (if + // this->rawOrder is true), physical layout order (if + // is true and this->rawOrder is false), or reading order (if both + // flags are false). + TextWordList *makeWordList(GBool physLayout); +#endif + +private: + + void clear(); + void assignColumns(TextLineFrag *frags, int nFrags, int rot); + int dumpFragment(Unicode *text, int len, UnicodeMap *uMap, GooString *s); + + GBool rawOrder; // keep text in content stream order + + double pageWidth, pageHeight; // width and height of current page + TextWord *curWord; // currently active string + int charPos; // next character position (within content + // stream) + TextFontInfo *curFont; // current font + double curFontSize; // current font size + int nest; // current nesting level (for Type 3 fonts) + int nTinyChars; // number of "tiny" chars seen so far + GBool lastCharOverlap; // set if the last added char overlapped the + // previous char + + TextPool *pools[4]; // a "pool" of TextWords for each rotation + TextFlow *flows; // linked list of flows + TextBlock **blocks; // array of blocks, in yx order + int nBlocks; // number of blocks + int primaryRot; // primary rotation + GBool primaryLR; // primary direction (true means L-to-R, + // false means R-to-L) + TextWord *rawWords; // list of words, in raw order (only if + // rawOrder is set) + TextWord *rawLastWord; // last word on rawWords list + + GooList *fonts; // all font info objects used on this + // page [TextFontInfo] + + double lastFindXMin, // coordinates of the last "find" result + lastFindYMin; + GBool haveLastFind; + + friend class TextLine; + friend class TextLineFrag; + friend class TextBlock; + friend class TextFlow; + friend class TextWordList; + friend class TextSelectionPainter; + friend class TextSelectionDumper; +}; + +//------------------------------------------------------------------------ +// TextOutputDev +//------------------------------------------------------------------------ + +class TextOutputDev: public OutputDev { +public: + + // Open a text output file. If is NULL, no file is + // written (this is useful, e.g., for searching text). If + // is true, the original physical layout of the text + // is maintained. If is true, the text is kept in + // content stream order. + TextOutputDev(char *fileName, GBool physLayoutA, + GBool rawOrderA, GBool append); + + // Create a TextOutputDev which will write to a generic stream. If + // is true, the original physical layout of the text + // is maintained. If is true, the text is kept in + // content stream order. + TextOutputDev(TextOutputFunc func, void *stream, + GBool physLayoutA, GBool rawOrderA); + + // Destructor. + virtual ~TextOutputDev(); + + // Check if file was successfully created. + virtual GBool isOk() { return ok; } + + //---- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gTrue; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gTrue; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() { return gFalse; } + + // Does this device need non-text content? + virtual GBool needNonText() { return gFalse; } + + //----- initialization and control + + // Start a page. + virtual void startPage(int pageNum, GfxState *state); + + // End a page. + virtual void endPage(); + + //----- update text state + virtual void updateFont(GfxState *state); + + //----- text drawing + virtual void beginString(GfxState *state, GooString *s); + virtual void endString(GfxState *state); + virtual void drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode c, int nBytes, Unicode *u, int uLen); + + //----- special access + + // Find a string. If is true, starts looking at the + // top of the page; else if is true, starts looking + // immediately after the last find result; else starts looking at + // ,. If is true, stops looking at the + // bottom of the page; else if is true, stops looking + // just before the last find result; else stops looking at + // ,. + GBool findText(Unicode *s, int len, + GBool startAtTop, GBool stopAtBottom, + GBool startAtLast, GBool stopAtLast, + GBool caseSensitive, GBool backward, + double *xMin, double *yMin, + double *xMax, double *yMax); + + // Get the text which is inside the specified rectangle. + GooString *getText(double xMin, double yMin, + double xMax, double yMax); + + // Find a string by character position and length. If found, sets + // the text bounding rectangle and returns true; otherwise returns + // false. + GBool findCharRange(int pos, int length, + double *xMin, double *yMin, + double *xMax, double *yMax); + + void drawSelection(OutputDev *out, double scale, int rotation, + PDFRectangle *selection, + GfxColor *glyph_color, GfxColor *box_color); + + GooList *getSelectionRegion(PDFRectangle *selection, double scale); + + GooString *getSelectionText(PDFRectangle *selection); + +#if TEXTOUT_WORD_LIST + // Build a flat word list, in content stream order (if + // this->rawOrder is true), physical layout order (if + // this->physLayout is true and this->rawOrder is false), or reading + // order (if both flags are false). + TextWordList *makeWordList(); +#endif + + // Returns the TextPage object for the last rasterized page, + // transferring ownership to the caller. + TextPage *takeText(); + +private: + + TextOutputFunc outputFunc; // output function + void *outputStream; // output stream + GBool needClose; // need to close the output file? + // (only if outputStream is a FILE*) + TextPage *text; // text for the current page + GBool physLayout; // maintain original physical layout when + // dumping text + GBool rawOrder; // keep text in content stream order + GBool ok; // set up ok? +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/UGooString.cc b/rosapps/smartpdf/poppler/poppler/UGooString.cc new file mode 100644 index 00000000000..ecf145e3d0d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UGooString.cc @@ -0,0 +1,199 @@ +//======================================================================== +// +// UGooString.cc +// +// Unicode string +// +// Copyright 2005 Albert Astals Cid +// +//======================================================================== + +#include +#include + +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "PDFDocEncoding.h" +#include "UGooString.h" + +int inline UGooString::roundedSize(int len) { + int delta; + if (len <= STR_STATIC_SIZE-1) + return STR_STATIC_SIZE; + delta = len < 256 ? 7 : 255; + return ((len + 1) + delta) & ~delta; +} + +// Make sure that the buffer is big enough to contain characters +// plus terminating 0. +// We assume that if this is being called from the constructor, was set +// to NULL and was set to 0 to indicate unused string before calling us. +void inline UGooString::resize(int newLength) { + int curSize = roundedSize(length); + int newSize = roundedSize(newLength); + + assert(s); + + if (curSize != newSize) { + Unicode *sNew = sStatic; + if (newSize != STR_STATIC_SIZE) + sNew = new Unicode[newSize]; + + // we had to re-allocate the memory, so copy the content of previous + // buffer into a new buffer + if (newLength < length) { + memcpy(sNew, s, newLength * sizeof(Unicode)); + } else { + memcpy(sNew, s, length * sizeof(Unicode)); + } + + if (s != sStatic) { + assert(curSize != STR_STATIC_SIZE); + delete[] s; + } + s = sNew; + } + + length = newLength; + s[length] = '\0'; +} + +UGooString::UGooString(void) +{ + s = sStatic; + length = 0; + resize(0); +} + +UGooString::UGooString(GooString &str) +{ + s = sStatic; + length = 0; + if (str.hasUnicodeMarker()) + { + resize((str.getLength() - 2) / 2); + for (int j = 0; j < length; ++j) { + s[j] = ((str.getChar(2 + 2*j) & 0xff) << 8) | (str.getChar(3 + 2*j) & 0xff); + } + } else + Set(str.getCString(), str.getLength()); +} + +UGooString::UGooString(const UGooString &str) +{ + s = sStatic; + length = 0; + Set(str); +} + +UGooString::UGooString(const char *str, int strLen) +{ + s = sStatic; + length = 0; + if (CALC_STRING_LEN == strLen) + strLen = strlen(str); + Set(str, strLen); +} + +UGooString *UGooString::Set(const UGooString &str) +{ + resize(str.length); + memcpy(s, str.s, length * sizeof(Unicode)); + return this; +} + +UGooString* UGooString::Set(const char *str, int strLen) +{ + int j; + bool foundUnencoded = false; + + if (CALC_STRING_LEN == strLen) + strLen = strlen(str); + + resize(strLen); + for (j = 0; j < length; ++j) { + s[j] = pdfDocEncoding[str[j] & 0xff]; + if (!s[j]) { + foundUnencoded = true; + break; + } + } + if (foundUnencoded) + { + for (j = 0; j < length; ++j) { + s[j] = str[j]; + } + } + return this; +} + +UGooString *UGooString::clear(void) +{ + resize(0); + return this; +} + +UGooString::~UGooString() +{ + if (s != sStatic) + delete[] s; +} + +int UGooString::cmp(const UGooString &str) const +{ + return cmp(&str); +} + +int UGooString::cmp(const UGooString *str) const +{ + int n1, n2, i, x; + Unicode *p1, *p2; + + n1 = length; + n2 = str->length; + for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + return n1 - n2; +} + +int UGooString::cmp(const char *str, int strLen) const +{ + int n1, n2, i, x; + Unicode u; + Unicode *p1, *p2; + + assert(str); + if (strLen == CALC_STRING_LEN) { + n2 = 0; + if (str) + n2 = strlen(str); + } else { + n2 = strLen; + } + + p2 = &u; + n1 = length; + for (i = 0, p1 = s; i < n1 && i < n2; ++i, ++p1) { + u = pdfDocEncoding[str[i] & 0xff]; + if (!u) + u = (unsigned char)str[i]; + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + return n1 - n2; +} + +char *UGooString::getCStringCopy() const +{ + char *res = new char[length + 1]; + for (int i = 0; i < length; i++) res[i] = s[i]; + res[length] = '\0'; + return res; +} + diff --git a/rosapps/smartpdf/poppler/poppler/UGooString.h b/rosapps/smartpdf/poppler/poppler/UGooString.h new file mode 100644 index 00000000000..7e1bef30687 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UGooString.h @@ -0,0 +1,78 @@ +//======================================================================== +// +// UGooString.h +// +// Unicode string +// +// Copyright 2005 Albert Astals Cid +// +//======================================================================== + +#ifndef UGooString_H +#define UGooString_H + +#include "CharTypes.h" + +class GooString; + +class UGooString +{ +public: + + // Create empty unicode string + UGooString(void); + + // Create a unicode string from . + UGooString(GooString &str); + + // Copy the unicode string + UGooString(const UGooString &str); + + // Create a unicode string from . + UGooString(const char *str, int strLen = CALC_STRING_LEN); + + UGooString *Set(const char *str, int strLen = CALC_STRING_LEN); + UGooString *Set(const UGooString &str); + + // Set the string to empty string, freeing all dynamically allocated memory + // as a side effect + UGooString *clear(void); + + ~UGooString(); + + void resize(int newLength); + + int getLength() const { return length; } + + // Compare two strings: -1:< 0:= +1:> + int cmp(const UGooString *str) const; + int cmp(const UGooString &str) const; + int cmp(const char *str, int strLen = CALC_STRING_LEN) const; + + // get the unicode + Unicode *unicode() const { return s; } + + // Return a newly allocated copy of the string converted to + // ascii (non-Unicode) format. Caller has to delete [] the result + char *getCStringCopy() const; + + // a special value telling that the length of the string is not given + // so it must be calculated from the strings + static const int CALC_STRING_LEN = -1; + +private: + // you can tweak this number for a different speed/memory usage tradeoffs. + // In libc malloc() rounding is 16 so it's best to choose a value that + // results in sizeof(UGooString) be a multiple of 16. + // 20 makes sizeof(UGooString) to be 48. + static const int STR_STATIC_SIZE = 20; + + int roundedSize(int len); + void initChar(const char *str, int strLen); + + Unicode sStatic[STR_STATIC_SIZE]; + int length; + Unicode *s; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/UTF8.h b/rosapps/smartpdf/poppler/poppler/UTF8.h new file mode 100644 index 00000000000..8536dbf9436 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UTF8.h @@ -0,0 +1,56 @@ +//======================================================================== +// +// UTF8.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +static int mapUTF8(Unicode u, char *buf, int bufSize) { + if (u <= 0x0000007f) { + if (bufSize < 1) { + return 0; + } + buf[0] = (char)u; + return 1; + } else if (u <= 0x000007ff) { + if (bufSize < 2) { + return 0; + } + buf[0] = (char)(0xc0 + (u >> 6)); + buf[1] = (char)(0x80 + (u & 0x3f)); + return 2; + } else if (u <= 0x0000ffff) { + if (bufSize < 3) { + return 0; + } + buf[0] = (char)(0xe0 + (u >> 12)); + buf[1] = (char)(0x80 + ((u >> 6) & 0x3f)); + buf[2] = (char)(0x80 + (u & 0x3f)); + return 3; + } else if (u <= 0x0010ffff) { + if (bufSize < 4) { + return 0; + } + buf[0] = (char)(0xf0 + (u >> 18)); + buf[1] = (char)(0x80 + ((u >> 12) & 0x3f)); + buf[2] = (char)(0x80 + ((u >> 6) & 0x3f)); + buf[3] = (char)(0x80 + (u & 0x3f)); + return 4; + } else { + return 0; + } +} + +static int mapUCS2(Unicode u, char *buf, int bufSize) { + if (u <= 0xffff) { + if (bufSize < 2) { + return 0; + } + buf[0] = (char)((u >> 8) & 0xff); + buf[1] = (char)(u & 0xff); + return 2; + } else { + return 0; + } +} diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeCClassTables.h b/rosapps/smartpdf/poppler/poppler/UnicodeCClassTables.h new file mode 100644 index 00000000000..62f9ecc3657 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeCClassTables.h @@ -0,0 +1,1827 @@ +// Copied from gunidecomp.h in GLib: +// s/[G]_UNICODE_MAX_TABLE_INDEX/UNICODE_MAX_TABLE_INDEX/g +// s/[g]uchar/Unicode/g +// s/[g]int16/short/g +// Can be regenerated from gen-unicode-tables.pl, also in GLib, with relevant +// Unicode data tables from ftp.unicode.org. + +static const Unicode cclass_data[][256] = { + { /* page 3, index 0 */ + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, + 220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, + 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, + 220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, + 220, 220, 230, 230, 230, 220, 220, 0, 230, 230, 230, 220, 220, 220, 220, + 230, 0, 0, 0, 0, 0, 234, 234, 233, 234, 234, 233, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 4, index 1 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 5, index 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, + 230, 230, 230, 0, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 222, + 228, 230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 20, 21, 22, 0, 23, + 0, 24, 25, 0, 230, 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 + }, + { /* page 6, index 3 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, + 230, 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, 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, 220, + 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230, + 230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 7, index 4 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 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, + 230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, + 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 9, index 5 */ + 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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 + }, + { /* page 10, index 6 */ + 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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 + }, + { /* page 11, index 7 */ + 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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 + }, + { /* page 12, index 8 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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 + }, + { /* page 13, index 9 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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 + }, + { /* page 14, index 10 */ + 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, 103, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 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 + }, + { /* page 15, index 11 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 220, 220, 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, 220, 0, 220, 0, 216, 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, 129, 130, 0, + 132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, + 230, 230, 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, 220, 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 + }, + { /* page 16, index 12 */ + 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, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 23, index 13 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 230, 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 + }, + { /* page 24, index 14 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 25, index 15 */ + 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, 222, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 32, index 16 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 1, 1, 230, 230, + 230, 230, 1, 1, 1, 230, 230, 0, 0, 0, 0, 230, 0, 0, 0, 1, 1, 230, 220, + 230, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 48, index 17 */ + 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, 218, 228, 232, 222, + 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 251, index 18 */ + 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, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 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 + }, + { /* page 254, index 19 */ + 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, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 + }, + { /* page 465, index 20 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216, 216, 216, 216, + 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 220, 220, 0, 0, + 230, 230, 230, 230, 230, 220, 220, 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, 230, 230, 230, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +static const short combining_class_table_part1[763] = { + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 /* page 3 */, + 1 /* page 4 */, + 2 /* page 5 */, + 3 /* page 6 */, + 4 /* page 7 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 5 /* page 9 */, + 6 /* page 10 */, + 7 /* page 11 */, + 8 /* page 12 */, + 9 /* page 13 */, + 10 /* page 14 */, + 11 /* page 15 */, + 12 /* page 16 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 13 /* page 23 */, + 14 /* page 24 */, + 15 /* page 25 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 16 /* page 32 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 17 /* page 48 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 18 /* page 251 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 19 /* page 254 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 20 /* page 465 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX +}; + +static const short combining_class_table_part2[768] = { + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX +}; diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeCompTables.h b/rosapps/smartpdf/poppler/poppler/UnicodeCompTables.h new file mode 100644 index 00000000000..68e2f86aee9 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeCompTables.h @@ -0,0 +1,665 @@ +// Copied from gunicomp.h in GLib: +// s/[G]_UNICODE_MAX_TABLE_INDEX/UNICODE_MAX_TABLE_INDEX/g +// s/[g]uint16/unsigned short/g +// s/[g]int16/short/g +// Can be regenerated from gen-unicode-tables.pl, also in GLib, with relevant +// Unicode data tables from ftp.unicode.org. + +#define COMPOSE_FIRST_START 1 +#define COMPOSE_FIRST_SINGLE_START 147 +#define COMPOSE_SECOND_START 357 +#define COMPOSE_SECOND_SINGLE_START 388 + +#define COMPOSE_TABLE_LAST 48 + +static const unsigned short compose_data[][256] = { + { /* page 0, index 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, 147, 148, 149, 0, 0, 1, 2, 3, 4, 5, + 150, 6, 7, 8, 151, 9, 10, 11, 12, 13, 14, 0, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 152, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 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, 48, 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, 49, 0, 153, 154, + 50, 155, 0, 0, 51, 0, 0, 0, 0, 156, 0, 0, 0, 0, 52, 53, 157, 0, 158, 0, + 0, 0, 54, 0, 0, 0, 0, 0, 55, 0, 159, 160, 56, 161, 0, 0, 57, 0, 0, 0, 0, + 162, 0, 0, 0, 0, 58, 59, 163, 0, 164, 0, 0, 0, 60, 0, 0, 0 + }, + { /* page 1, index 1 */ + 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 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, 65, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 166, 0, + 0, 0, 0, 167, 168, 0, 0, 0, 0, 0, 0, 169, 170, 171, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 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, 67, + 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 0, 174, + 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, 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 + }, + { /* page 2, index 2 */ + 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, 177, 178, 179, 180, 0, 0, 0, 0, + 181, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 3, index 3 */ + 357, 358, 359, 360, 361, 0, 362, 363, 364, 365, 366, 367, 368, 0, 0, 369, + 0, 370, 0, 371, 372, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 374, + 375, 376, 377, 378, 379, 0, 0, 0, 0, 380, 381, 0, 382, 383, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, + 72, 0, 73, 0, 74, 0, 0, 0, 0, 0, 75, 0, 184, 0, 0, 0, 76, 0, 0, 0, 77, 0, + 0, 185, 0, 186, 0, 0, 78, 0, 0, 0, 79, 0, 80, 0, 81, 0, 0, 0, 0, 0, 82, + 0, 83, 0, 0, 0, 84, 0, 0, 0, 85, 86, 87, 0, 0, 187, 0, 0, 0, 88, 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 + }, + { /* page 4, index 4 */ + 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 189, 0, 90, + 91, 190, 92, 0, 191, 0, 0, 0, 192, 0, 0, 0, 0, 93, 0, 0, 0, 193, 0, 0, 0, + 194, 0, 195, 0, 0, 94, 0, 0, 196, 0, 95, 96, 197, 97, 0, 198, 0, 0, 0, + 199, 0, 0, 0, 0, 98, 0, 0, 0, 200, 0, 0, 0, 201, 0, 202, 0, 0, 0, 0, 0, + 0, 0, 0, 203, 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, 204, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 208, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 6, index 5 */ + 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, 99, 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, + 210, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 388, 389, 390, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, + 0, 214, 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 + }, + { /* page 9, index 6 */ + 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, 215, 0, 0, 0, 0, 0, 0, 0, + 216, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 391, + 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 392, 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 + }, + { /* page 11, index 7 */ + 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, 393, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 394, 395, 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, 218, 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, 396, 0, 0, 0, 0, 0, 0, 0, 102, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 397, 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 + }, + { /* page 12, index 8 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, + 0, 0, 398, 0, 0, 0, 103, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, + 400, 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 + }, + { /* page 13, index 9 */ + 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, 401, 0, 0, 0, 0, 0, 0, 0, 104, + 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 105, 0, 0, 224, 0, 0, 405, 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 + }, + { /* page 16, index 10 */ + 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, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 + }, + { /* page 30, index 11 */ + 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, 226, 227, 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, 228, 229, 0, 0, + 0, 0, 0, 0, 230, 231, 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, 106, 107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 233, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 235, 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 + }, + { /* page 31, index 12 */ + 108, 109, 236, 237, 238, 239, 240, 241, 110, 111, 242, 243, 244, 245, + 246, 247, 112, 113, 0, 0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 116, + 117, 248, 249, 250, 251, 252, 253, 118, 119, 254, 255, 256, 257, 258, + 259, 120, 121, 0, 0, 0, 0, 0, 0, 122, 123, 0, 0, 0, 0, 0, 0, 124, 125, 0, + 0, 0, 0, 0, 0, 126, 127, 0, 0, 0, 0, 0, 0, 128, 129, 0, 0, 0, 0, 0, 0, 0, + 130, 0, 0, 0, 0, 0, 0, 131, 132, 260, 261, 262, 263, 264, 265, 133, 134, + 266, 267, 268, 269, 270, 271, 272, 0, 0, 0, 273, 0, 0, 0, 0, 0, 0, 0, + 274, 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, 275, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, + 0, 0, 0, 276, 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, 277, 0, 0, 0, 0, 0, 0, 0, 136, 0 + }, + { /* page 33, index 13 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 278, 0, 279, 0, 280, 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, 281, 0, 282, 0, + 283, 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 + }, + { /* page 34, index 14 */ + 0, 0, 0, 284, 0, 0, 0, 0, 285, 0, 0, 286, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 287, 0, 288, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, 0, 0, 0, 0, 290, + 0, 291, 0, 0, 292, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 294, 0, 0, 295, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 297, 298, 0, 0, 299, 300, 0, 0, 301, 302, 303, 304, 0, 0, 0, 0, + 305, 306, 0, 0, 307, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 310, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 312, 313, 0, 314, + 0, 0, 0, 0, 0, 0, 315, 316, 317, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 48, index 15 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0, + 0, 0, 0, 320, 0, 321, 0, 322, 0, 323, 0, 324, 0, 325, 0, 326, 0, 327, 0, + 328, 0, 329, 0, 330, 0, 331, 0, 0, 332, 0, 333, 0, 334, 0, 0, 0, 0, 0, 0, + 137, 0, 0, 138, 0, 0, 139, 0, 0, 140, 0, 0, 141, 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, 386, 387, + 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, 0, 337, 0, 338, 0, 339, + 0, 340, 0, 341, 0, 342, 0, 343, 0, 344, 0, 345, 0, 346, 0, 347, 0, 348, + 0, 0, 349, 0, 350, 0, 351, 0, 0, 0, 0, 0, 0, 142, 0, 0, 143, 0, 0, 144, + 0, 0, 145, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 352, 353, 354, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 356, 0, 0 + } +}; + +static const short compose_table[COMPOSE_TABLE_LAST + 1] = { + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 5 /* page 6 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 6 /* page 9 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 7 /* page 11 */, + 8 /* page 12 */, + 9 /* page 13 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 10 /* page 16 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 11 /* page 30 */, + 12 /* page 31 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 13 /* page 33 */, + 14 /* page 34 */, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 0 + UNICODE_MAX_TABLE_INDEX, + 15 /* page 48 */ +}; + +static const unsigned short compose_first_single[][2] = { + { 0x0338, 0x226e }, + { 0x0338, 0x2260 }, + { 0x0338, 0x226f }, + { 0x0307, 0x1e1e }, + { 0x0302, 0x0134 }, + { 0x0307, 0x1e1f }, + { 0x0304, 0x01de }, + { 0x0301, 0x01fa }, + { 0x0301, 0x1e08 }, + { 0x0301, 0x1e2e }, + { 0x0304, 0x022a }, + { 0x0301, 0x01fe }, + { 0x0304, 0x01df }, + { 0x0301, 0x01fb }, + { 0x0301, 0x1e09 }, + { 0x0301, 0x1e2f }, + { 0x0304, 0x022b }, + { 0x0301, 0x01ff }, + { 0x0307, 0x1e64 }, + { 0x0307, 0x1e65 }, + { 0x0307, 0x1e66 }, + { 0x0307, 0x1e67 }, + { 0x0301, 0x1e78 }, + { 0x0301, 0x1e79 }, + { 0x0308, 0x1e7a }, + { 0x0308, 0x1e7b }, + { 0x0307, 0x1e9b }, + { 0x030c, 0x01ee }, + { 0x0304, 0x01ec }, + { 0x0304, 0x01ed }, + { 0x0304, 0x01e0 }, + { 0x0304, 0x01e1 }, + { 0x0306, 0x1e1c }, + { 0x0306, 0x1e1d }, + { 0x0304, 0x0230 }, + { 0x0304, 0x0231 }, + { 0x030c, 0x01ef }, + { 0x0314, 0x1fec }, + { 0x0345, 0x1fb4 }, + { 0x0345, 0x1fc4 }, + { 0x0345, 0x1ff4 }, + { 0x0308, 0x0407 }, + { 0x0301, 0x0403 }, + { 0x0308, 0x04de }, + { 0x0301, 0x040c }, + { 0x0308, 0x04e6 }, + { 0x0308, 0x04f4 }, + { 0x0308, 0x04f8 }, + { 0x0308, 0x04ec }, + { 0x0301, 0x0453 }, + { 0x0308, 0x04df }, + { 0x0301, 0x045c }, + { 0x0308, 0x04e7 }, + { 0x0308, 0x04f5 }, + { 0x0308, 0x04f9 }, + { 0x0308, 0x04ed }, + { 0x0308, 0x0457 }, + { 0x030f, 0x0476 }, + { 0x030f, 0x0477 }, + { 0x0308, 0x04da }, + { 0x0308, 0x04db }, + { 0x0308, 0x04ea }, + { 0x0308, 0x04eb }, + { 0x0654, 0x0624 }, + { 0x0654, 0x0626 }, + { 0x0654, 0x06c2 }, + { 0x0654, 0x06d3 }, + { 0x0654, 0x06c0 }, + { 0x093c, 0x0929 }, + { 0x093c, 0x0931 }, + { 0x093c, 0x0934 }, + { 0x0bd7, 0x0b94 }, + { 0x0bbe, 0x0bcb }, + { 0x0c56, 0x0c48 }, + { 0x0cd5, 0x0cc0 }, + { 0x0cd5, 0x0ccb }, + { 0x0d3e, 0x0d4b }, + { 0x0dca, 0x0ddd }, + { 0x102e, 0x1026 }, + { 0x0304, 0x1e38 }, + { 0x0304, 0x1e39 }, + { 0x0304, 0x1e5c }, + { 0x0304, 0x1e5d }, + { 0x0307, 0x1e68 }, + { 0x0307, 0x1e69 }, + { 0x0302, 0x1ec6 }, + { 0x0302, 0x1ec7 }, + { 0x0302, 0x1ed8 }, + { 0x0302, 0x1ed9 }, + { 0x0345, 0x1f82 }, + { 0x0345, 0x1f83 }, + { 0x0345, 0x1f84 }, + { 0x0345, 0x1f85 }, + { 0x0345, 0x1f86 }, + { 0x0345, 0x1f87 }, + { 0x0345, 0x1f8a }, + { 0x0345, 0x1f8b }, + { 0x0345, 0x1f8c }, + { 0x0345, 0x1f8d }, + { 0x0345, 0x1f8e }, + { 0x0345, 0x1f8f }, + { 0x0345, 0x1f92 }, + { 0x0345, 0x1f93 }, + { 0x0345, 0x1f94 }, + { 0x0345, 0x1f95 }, + { 0x0345, 0x1f96 }, + { 0x0345, 0x1f97 }, + { 0x0345, 0x1f9a }, + { 0x0345, 0x1f9b }, + { 0x0345, 0x1f9c }, + { 0x0345, 0x1f9d }, + { 0x0345, 0x1f9e }, + { 0x0345, 0x1f9f }, + { 0x0345, 0x1fa2 }, + { 0x0345, 0x1fa3 }, + { 0x0345, 0x1fa4 }, + { 0x0345, 0x1fa5 }, + { 0x0345, 0x1fa6 }, + { 0x0345, 0x1fa7 }, + { 0x0345, 0x1faa }, + { 0x0345, 0x1fab }, + { 0x0345, 0x1fac }, + { 0x0345, 0x1fad }, + { 0x0345, 0x1fae }, + { 0x0345, 0x1faf }, + { 0x0345, 0x1fb2 }, + { 0x0345, 0x1fc2 }, + { 0x0345, 0x1ff2 }, + { 0x0345, 0x1fb7 }, + { 0x0345, 0x1fc7 }, + { 0x0345, 0x1ff7 }, + { 0x0338, 0x219a }, + { 0x0338, 0x219b }, + { 0x0338, 0x21ae }, + { 0x0338, 0x21cd }, + { 0x0338, 0x21cf }, + { 0x0338, 0x21ce }, + { 0x0338, 0x2204 }, + { 0x0338, 0x2209 }, + { 0x0338, 0x220c }, + { 0x0338, 0x2224 }, + { 0x0338, 0x2226 }, + { 0x0338, 0x2241 }, + { 0x0338, 0x2244 }, + { 0x0338, 0x2247 }, + { 0x0338, 0x2249 }, + { 0x0338, 0x226d }, + { 0x0338, 0x2262 }, + { 0x0338, 0x2270 }, + { 0x0338, 0x2271 }, + { 0x0338, 0x2274 }, + { 0x0338, 0x2275 }, + { 0x0338, 0x2278 }, + { 0x0338, 0x2279 }, + { 0x0338, 0x2280 }, + { 0x0338, 0x2281 }, + { 0x0338, 0x22e0 }, + { 0x0338, 0x22e1 }, + { 0x0338, 0x2284 }, + { 0x0338, 0x2285 }, + { 0x0338, 0x2288 }, + { 0x0338, 0x2289 }, + { 0x0338, 0x22e2 }, + { 0x0338, 0x22e3 }, + { 0x0338, 0x22ac }, + { 0x0338, 0x22ad }, + { 0x0338, 0x22ae }, + { 0x0338, 0x22af }, + { 0x0338, 0x22ea }, + { 0x0338, 0x22eb }, + { 0x0338, 0x22ec }, + { 0x0338, 0x22ed }, + { 0x3099, 0x3094 }, + { 0x3099, 0x304c }, + { 0x3099, 0x304e }, + { 0x3099, 0x3050 }, + { 0x3099, 0x3052 }, + { 0x3099, 0x3054 }, + { 0x3099, 0x3056 }, + { 0x3099, 0x3058 }, + { 0x3099, 0x305a }, + { 0x3099, 0x305c }, + { 0x3099, 0x305e }, + { 0x3099, 0x3060 }, + { 0x3099, 0x3062 }, + { 0x3099, 0x3065 }, + { 0x3099, 0x3067 }, + { 0x3099, 0x3069 }, + { 0x3099, 0x309e }, + { 0x3099, 0x30f4 }, + { 0x3099, 0x30ac }, + { 0x3099, 0x30ae }, + { 0x3099, 0x30b0 }, + { 0x3099, 0x30b2 }, + { 0x3099, 0x30b4 }, + { 0x3099, 0x30b6 }, + { 0x3099, 0x30b8 }, + { 0x3099, 0x30ba }, + { 0x3099, 0x30bc }, + { 0x3099, 0x30be }, + { 0x3099, 0x30c0 }, + { 0x3099, 0x30c2 }, + { 0x3099, 0x30c5 }, + { 0x3099, 0x30c7 }, + { 0x3099, 0x30c9 }, + { 0x3099, 0x30f7 }, + { 0x3099, 0x30f8 }, + { 0x3099, 0x30f9 }, + { 0x3099, 0x30fa }, + { 0x3099, 0x30fe } +}; +static const unsigned short compose_second_single[][2] = { + { 0x0627, 0x0622 }, + { 0x0627, 0x0623 }, + { 0x0627, 0x0625 }, + { 0x09c7, 0x09cb }, + { 0x09c7, 0x09cc }, + { 0x0b47, 0x0b4b }, + { 0x0b47, 0x0b48 }, + { 0x0b47, 0x0b4c }, + { 0x0bc6, 0x0bca }, + { 0x0bc6, 0x0bcc }, + { 0x0cc6, 0x0cca }, + { 0x0cc6, 0x0cc7 }, + { 0x0cc6, 0x0cc8 }, + { 0x0d46, 0x0d4a }, + { 0x0d46, 0x0d4c }, + { 0x0dd9, 0x0dda }, + { 0x0dd9, 0x0ddc }, + { 0x0dd9, 0x0dde } +}; +static const unsigned short compose_array[146][31] = { + { 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x0100, 0x0102, 0x0226, 0x00c4, 0x1ea2, 0x00c5, 0, 0x01cd, 0x0200, 0x0202, 0, 0, 0, 0x1ea0, 0, 0x1e00, 0, 0, 0x0104, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e04, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e06, 0, 0, 0, 0 }, + { 0, 0x0106, 0x0108, 0, 0, 0, 0x010a, 0, 0, 0, 0, 0x010c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00c7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e0a, 0, 0, 0, 0, 0x010e, 0, 0, 0, 0, 0, 0x1e0c, 0, 0, 0, 0x1e10, 0, 0x1e12, 0, 0, 0x1e0e, 0, 0, 0, 0 }, + { 0x00c8, 0x00c9, 0x00ca, 0x1ebc, 0x0112, 0x0114, 0x0116, 0x00cb, 0x1eba, 0, 0, 0x011a, 0x0204, 0x0206, 0, 0, 0, 0x1eb8, 0, 0, 0, 0x0228, 0x0118, 0x1e18, 0, 0x1e1a, 0, 0, 0, 0, 0 }, + { 0, 0x01f4, 0x011c, 0, 0x1e20, 0x011e, 0x0120, 0, 0, 0, 0, 0x01e6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0122, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0x0124, 0, 0, 0, 0x1e22, 0x1e26, 0, 0, 0, 0x021e, 0, 0, 0, 0, 0, 0x1e24, 0, 0, 0, 0x1e28, 0, 0, 0x1e2a, 0, 0, 0, 0, 0, 0 }, + { 0x00cc, 0x00cd, 0x00ce, 0x0128, 0x012a, 0x012c, 0x0130, 0x00cf, 0x1ec8, 0, 0, 0x01cf, 0x0208, 0x020a, 0, 0, 0, 0x1eca, 0, 0, 0, 0, 0x012e, 0, 0, 0x1e2c, 0, 0, 0, 0, 0 }, + { 0, 0x1e30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01e8, 0, 0, 0, 0, 0, 0x1e32, 0, 0, 0, 0x0136, 0, 0, 0, 0, 0x1e34, 0, 0, 0, 0 }, + { 0, 0x0139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x013d, 0, 0, 0, 0, 0, 0x1e36, 0, 0, 0, 0x013b, 0, 0x1e3c, 0, 0, 0x1e3a, 0, 0, 0, 0 }, + { 0, 0x1e3e, 0, 0, 0, 0, 0x1e40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01f8, 0x0143, 0, 0x00d1, 0, 0, 0x1e44, 0, 0, 0, 0, 0x0147, 0, 0, 0, 0, 0, 0x1e46, 0, 0, 0, 0x0145, 0, 0x1e4a, 0, 0, 0x1e48, 0, 0, 0, 0 }, + { 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x014c, 0x014e, 0x022e, 0x00d6, 0x1ece, 0, 0x0150, 0x01d1, 0x020c, 0x020e, 0, 0, 0x01a0, 0x1ecc, 0, 0, 0, 0, 0x01ea, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e54, 0, 0, 0, 0, 0x1e56, 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, 0x0154, 0, 0, 0, 0, 0x1e58, 0, 0, 0, 0, 0x0158, 0x0210, 0x0212, 0, 0, 0, 0x1e5a, 0, 0, 0, 0x0156, 0, 0, 0, 0, 0x1e5e, 0, 0, 0, 0 }, + { 0, 0x015a, 0x015c, 0, 0, 0, 0x1e60, 0, 0, 0, 0, 0x0160, 0, 0, 0, 0, 0, 0x1e62, 0, 0, 0x0218, 0x015e, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e6a, 0, 0, 0, 0, 0x0164, 0, 0, 0, 0, 0, 0x1e6c, 0, 0, 0x021a, 0x0162, 0, 0x1e70, 0, 0, 0x1e6e, 0, 0, 0, 0 }, + { 0x00d9, 0x00da, 0x00db, 0x0168, 0x016a, 0x016c, 0, 0x00dc, 0x1ee6, 0x016e, 0x0170, 0x01d3, 0x0214, 0x0216, 0, 0, 0x01af, 0x1ee4, 0x1e72, 0, 0, 0, 0x0172, 0x1e76, 0, 0x1e74, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0x1e7c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e7e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e80, 0x1e82, 0x0174, 0, 0, 0, 0x1e86, 0x1e84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e8a, 0x1e8c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ef2, 0x00dd, 0x0176, 0x1ef8, 0x0232, 0, 0x1e8e, 0x0178, 0x1ef6, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x0179, 0x1e90, 0, 0, 0, 0x017b, 0, 0, 0, 0, 0x017d, 0, 0, 0, 0, 0, 0x1e92, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e94, 0, 0, 0, 0 }, + { 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x0101, 0x0103, 0x0227, 0x00e4, 0x1ea3, 0x00e5, 0, 0x01ce, 0x0201, 0x0203, 0, 0, 0, 0x1ea1, 0, 0x1e01, 0, 0, 0x0105, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e05, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e07, 0, 0, 0, 0 }, + { 0, 0x0107, 0x0109, 0, 0, 0, 0x010b, 0, 0, 0, 0, 0x010d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00e7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e0b, 0, 0, 0, 0, 0x010f, 0, 0, 0, 0, 0, 0x1e0d, 0, 0, 0, 0x1e11, 0, 0x1e13, 0, 0, 0x1e0f, 0, 0, 0, 0 }, + { 0x00e8, 0x00e9, 0x00ea, 0x1ebd, 0x0113, 0x0115, 0x0117, 0x00eb, 0x1ebb, 0, 0, 0x011b, 0x0205, 0x0207, 0, 0, 0, 0x1eb9, 0, 0, 0, 0x0229, 0x0119, 0x1e19, 0, 0x1e1b, 0, 0, 0, 0, 0 }, + { 0, 0x01f5, 0x011d, 0, 0x1e21, 0x011f, 0x0121, 0, 0, 0, 0, 0x01e7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0123, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0x0125, 0, 0, 0, 0x1e23, 0x1e27, 0, 0, 0, 0x021f, 0, 0, 0, 0, 0, 0x1e25, 0, 0, 0, 0x1e29, 0, 0, 0x1e2b, 0, 0x1e96, 0, 0, 0, 0 }, + { 0x00ec, 0x00ed, 0x00ee, 0x0129, 0x012b, 0x012d, 0, 0x00ef, 0x1ec9, 0, 0, 0x01d0, 0x0209, 0x020b, 0, 0, 0, 0x1ecb, 0, 0, 0, 0, 0x012f, 0, 0, 0x1e2d, 0, 0, 0, 0, 0 }, + { 0, 0, 0x0135, 0, 0, 0, 0, 0, 0, 0, 0, 0x01f0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01e9, 0, 0, 0, 0, 0, 0x1e33, 0, 0, 0, 0x0137, 0, 0, 0, 0, 0x1e35, 0, 0, 0, 0 }, + { 0, 0x013a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x013e, 0, 0, 0, 0, 0, 0x1e37, 0, 0, 0, 0x013c, 0, 0x1e3d, 0, 0, 0x1e3b, 0, 0, 0, 0 }, + { 0, 0x1e3f, 0, 0, 0, 0, 0x1e41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01f9, 0x0144, 0, 0x00f1, 0, 0, 0x1e45, 0, 0, 0, 0, 0x0148, 0, 0, 0, 0, 0, 0x1e47, 0, 0, 0, 0x0146, 0, 0x1e4b, 0, 0, 0x1e49, 0, 0, 0, 0 }, + { 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x014d, 0x014f, 0x022f, 0x00f6, 0x1ecf, 0, 0x0151, 0x01d2, 0x020d, 0x020f, 0, 0, 0x01a1, 0x1ecd, 0, 0, 0, 0, 0x01eb, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e55, 0, 0, 0, 0, 0x1e57, 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, 0x0155, 0, 0, 0, 0, 0x1e59, 0, 0, 0, 0, 0x0159, 0x0211, 0x0213, 0, 0, 0, 0x1e5b, 0, 0, 0, 0x0157, 0, 0, 0, 0, 0x1e5f, 0, 0, 0, 0 }, + { 0, 0x015b, 0x015d, 0, 0, 0, 0x1e61, 0, 0, 0, 0, 0x0161, 0, 0, 0, 0, 0, 0x1e63, 0, 0, 0x0219, 0x015f, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e6b, 0x1e97, 0, 0, 0, 0x0165, 0, 0, 0, 0, 0, 0x1e6d, 0, 0, 0x021b, 0x0163, 0, 0x1e71, 0, 0, 0x1e6f, 0, 0, 0, 0 }, + { 0x00f9, 0x00fa, 0x00fb, 0x0169, 0x016b, 0x016d, 0, 0x00fc, 0x1ee7, 0x016f, 0x0171, 0x01d4, 0x0215, 0x0217, 0, 0, 0x01b0, 0x1ee5, 0x1e73, 0, 0, 0, 0x0173, 0x1e77, 0, 0x1e75, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0x1e7d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e7f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e81, 0x1e83, 0x0175, 0, 0, 0, 0x1e87, 0x1e85, 0, 0x1e98, 0, 0, 0, 0, 0, 0, 0, 0x1e89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e8b, 0x1e8d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ef3, 0x00fd, 0x0177, 0x1ef9, 0x0233, 0, 0x1e8f, 0x00ff, 0x1ef7, 0x1e99, 0, 0, 0, 0, 0, 0, 0, 0x1ef5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x017a, 0x1e91, 0, 0, 0, 0x017c, 0, 0, 0, 0, 0x017e, 0, 0, 0, 0, 0, 0x1e93, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e95, 0, 0, 0, 0 }, + { 0x1fed, 0x0385, 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, 0x1fc1, 0, 0, 0 }, + { 0x1ea6, 0x1ea4, 0, 0x1eaa, 0, 0, 0, 0, 0x1ea8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x01fc, 0, 0, 0x01e2, 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 }, + { 0x1ec0, 0x1ebe, 0, 0x1ec4, 0, 0, 0, 0, 0x1ec2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ed2, 0x1ed0, 0, 0x1ed6, 0, 0, 0, 0, 0x1ed4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e4c, 0, 0, 0x022c, 0, 0, 0x1e4e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01db, 0x01d7, 0, 0, 0x01d5, 0, 0, 0, 0, 0, 0, 0x01d9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ea7, 0x1ea5, 0, 0x1eab, 0, 0, 0, 0, 0x1ea9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x01fd, 0, 0, 0x01e3, 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 }, + { 0x1ec1, 0x1ebf, 0, 0x1ec5, 0, 0, 0, 0, 0x1ec3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ed3, 0x1ed1, 0, 0x1ed7, 0, 0, 0, 0, 0x1ed5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e4d, 0, 0, 0x022d, 0, 0, 0x1e4f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01dc, 0x01d8, 0, 0, 0x01d6, 0, 0, 0, 0, 0, 0, 0x01da, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eb0, 0x1eae, 0, 0x1eb4, 0, 0, 0, 0, 0x1eb2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eb1, 0x1eaf, 0, 0x1eb5, 0, 0, 0, 0, 0x1eb3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e14, 0x1e16, 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 }, + { 0x1e15, 0x1e17, 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 }, + { 0x1e50, 0x1e52, 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 }, + { 0x1e51, 0x1e53, 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 }, + { 0x1edc, 0x1eda, 0, 0x1ee0, 0, 0, 0, 0, 0x1ede, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ee2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1edd, 0x1edb, 0, 0x1ee1, 0, 0, 0, 0, 0x1edf, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ee3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eea, 0x1ee8, 0, 0x1eee, 0, 0, 0, 0, 0x1eec, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eeb, 0x1ee9, 0, 0x1eef, 0, 0, 0, 0, 0x1eed, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1fba, 0x0386, 0, 0, 0x1fb9, 0x1fb8, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f08, 0x1f09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fbc, 0, 0 }, + { 0x1fc8, 0x0388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f18, 0x1f19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1fca, 0x0389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f28, 0x1f29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fcc, 0, 0 }, + { 0x1fda, 0x038a, 0, 0, 0x1fd9, 0x1fd8, 0, 0x03aa, 0, 0, 0, 0, 0, 0, 0x1f38, 0x1f39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ff8, 0x038c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f48, 0x1f49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1fea, 0x038e, 0, 0, 0x1fe9, 0x1fe8, 0, 0x03ab, 0, 0, 0, 0, 0, 0, 0, 0x1f59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ffa, 0x038f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f68, 0x1f69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ffc, 0, 0 }, + { 0x1f70, 0x03ac, 0, 0, 0x1fb1, 0x1fb0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f00, 0x1f01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fb6, 0x1fb3, 0, 0 }, + { 0x1f72, 0x03ad, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f10, 0x1f11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f74, 0x03ae, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f20, 0x1f21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fc6, 0x1fc3, 0, 0 }, + { 0x1f76, 0x03af, 0, 0, 0x1fd1, 0x1fd0, 0, 0x03ca, 0, 0, 0, 0, 0, 0, 0x1f30, 0x1f31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fd6, 0, 0, 0 }, + { 0x1f78, 0x03cc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f40, 0x1f41, 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, 0x1fe4, 0x1fe5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f7a, 0x03cd, 0, 0, 0x1fe1, 0x1fe0, 0, 0x03cb, 0, 0, 0, 0, 0, 0, 0x1f50, 0x1f51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fe6, 0, 0, 0 }, + { 0x1f7c, 0x03ce, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f60, 0x1f61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ff6, 0x1ff3, 0, 0 }, + { 0x1fd2, 0x0390, 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, 0x1fd7, 0, 0, 0 }, + { 0x1fe2, 0x03b0, 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, 0x1fe7, 0, 0, 0 }, + { 0, 0x03d3, 0, 0, 0, 0, 0, 0x03d4, 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, 0x04d0, 0, 0x04d2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x0400, 0, 0, 0, 0, 0x04d6, 0, 0x0401, 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, 0x04c1, 0, 0x04dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x040d, 0, 0, 0, 0x04e2, 0x0419, 0, 0x04e4, 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, 0x04ee, 0x040e, 0, 0x04f0, 0, 0, 0x04f2, 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, 0x04d1, 0, 0x04d3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x0450, 0, 0, 0, 0, 0x04d7, 0, 0x0451, 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, 0x04c2, 0, 0x04dd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x045d, 0, 0, 0, 0x04e3, 0x0439, 0, 0x04e5, 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, 0x04ef, 0x045e, 0, 0x04f1, 0, 0, 0x04f3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0x1eac, 0, 0, 0x1eb6, 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, 0x1ead, 0, 0, 0x1eb7, 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 }, + { 0x1f02, 0x1f04, 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, 0x1f06, 0x1f80, 0, 0 }, + { 0x1f03, 0x1f05, 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, 0x1f07, 0x1f81, 0, 0 }, + { 0x1f0a, 0x1f0c, 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, 0x1f0e, 0x1f88, 0, 0 }, + { 0x1f0b, 0x1f0d, 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, 0x1f0f, 0x1f89, 0, 0 }, + { 0x1f12, 0x1f14, 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 }, + { 0x1f13, 0x1f15, 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 }, + { 0x1f1a, 0x1f1c, 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 }, + { 0x1f1b, 0x1f1d, 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 }, + { 0x1f22, 0x1f24, 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, 0x1f26, 0x1f90, 0, 0 }, + { 0x1f23, 0x1f25, 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, 0x1f27, 0x1f91, 0, 0 }, + { 0x1f2a, 0x1f2c, 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, 0x1f2e, 0x1f98, 0, 0 }, + { 0x1f2b, 0x1f2d, 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, 0x1f2f, 0x1f99, 0, 0 }, + { 0x1f32, 0x1f34, 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, 0x1f36, 0, 0, 0 }, + { 0x1f33, 0x1f35, 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, 0x1f37, 0, 0, 0 }, + { 0x1f3a, 0x1f3c, 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, 0x1f3e, 0, 0, 0 }, + { 0x1f3b, 0x1f3d, 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, 0x1f3f, 0, 0, 0 }, + { 0x1f42, 0x1f44, 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 }, + { 0x1f43, 0x1f45, 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 }, + { 0x1f4a, 0x1f4c, 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 }, + { 0x1f4b, 0x1f4d, 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 }, + { 0x1f52, 0x1f54, 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, 0x1f56, 0, 0, 0 }, + { 0x1f53, 0x1f55, 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, 0x1f57, 0, 0, 0 }, + { 0x1f5b, 0x1f5d, 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, 0x1f5f, 0, 0, 0 }, + { 0x1f62, 0x1f64, 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, 0x1f66, 0x1fa0, 0, 0 }, + { 0x1f63, 0x1f65, 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, 0x1f67, 0x1fa1, 0, 0 }, + { 0x1f6a, 0x1f6c, 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, 0x1f6e, 0x1fa8, 0, 0 }, + { 0x1f6b, 0x1f6d, 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, 0x1f6f, 0x1fa9, 0, 0 }, + { 0x1fcd, 0x1fce, 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, 0x1fcf, 0, 0, 0 }, + { 0x1fdd, 0x1fde, 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, 0x1fdf, 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, 0x3070, 0x3071 }, + { 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, 0x3073, 0x3074 }, + { 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, 0x3076, 0x3077 }, + { 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, 0x3079, 0x307a }, + { 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, 0x307c, 0x307d }, + { 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, 0x30d0, 0x30d1 }, + { 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, 0x30d3, 0x30d4 }, + { 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, 0x30d6, 0x30d7 }, + { 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, 0x30d9, 0x30da }, + { 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, 0x30dc, 0x30dd } +}; diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeDecompTables.h b/rosapps/smartpdf/poppler/poppler/UnicodeDecompTables.h new file mode 100644 index 00000000000..4bc34b18d99 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeDecompTables.h @@ -0,0 +1,8526 @@ +// Generated by gen-unicode-tables.py + +typedef struct { + Unicode character; + int length; + int offset; +} decomposition; + +#define DECOMP_TABLE_LENGTH 5143 + +static const decomposition decomp_table[] = { + { 0xa0, 1, 0 }, + { 0xa8, 2, 1 }, + { 0xaa, 1, 3 }, + { 0xaf, 2, 4 }, + { 0xb2, 1, 6 }, + { 0xb3, 1, 7 }, + { 0xb4, 2, 8 }, + { 0xb5, 1, 10 }, + { 0xb8, 2, 11 }, + { 0xb9, 1, 13 }, + { 0xba, 1, 14 }, + { 0xbc, 3, 15 }, + { 0xbd, 3, 18 }, + { 0xbe, 3, 21 }, + { 0xc0, 2, 24 }, + { 0xc1, 2, 26 }, + { 0xc2, 2, 28 }, + { 0xc3, 2, 30 }, + { 0xc4, 2, 32 }, + { 0xc5, 2, 34 }, + { 0xc7, 2, 36 }, + { 0xc8, 2, 38 }, + { 0xc9, 2, 40 }, + { 0xca, 2, 42 }, + { 0xcb, 2, 44 }, + { 0xcc, 2, 46 }, + { 0xcd, 2, 48 }, + { 0xce, 2, 50 }, + { 0xcf, 2, 52 }, + { 0xd1, 2, 54 }, + { 0xd2, 2, 56 }, + { 0xd3, 2, 58 }, + { 0xd4, 2, 60 }, + { 0xd5, 2, 62 }, + { 0xd6, 2, 64 }, + { 0xd9, 2, 66 }, + { 0xda, 2, 68 }, + { 0xdb, 2, 70 }, + { 0xdc, 2, 72 }, + { 0xdd, 2, 74 }, + { 0xe0, 2, 76 }, + { 0xe1, 2, 78 }, + { 0xe2, 2, 80 }, + { 0xe3, 2, 82 }, + { 0xe4, 2, 84 }, + { 0xe5, 2, 86 }, + { 0xe7, 2, 88 }, + { 0xe8, 2, 90 }, + { 0xe9, 2, 92 }, + { 0xea, 2, 94 }, + { 0xeb, 2, 96 }, + { 0xec, 2, 98 }, + { 0xed, 2, 100 }, + { 0xee, 2, 102 }, + { 0xef, 2, 104 }, + { 0xf1, 2, 106 }, + { 0xf2, 2, 108 }, + { 0xf3, 2, 110 }, + { 0xf4, 2, 112 }, + { 0xf5, 2, 114 }, + { 0xf6, 2, 116 }, + { 0xf9, 2, 118 }, + { 0xfa, 2, 120 }, + { 0xfb, 2, 122 }, + { 0xfc, 2, 124 }, + { 0xfd, 2, 126 }, + { 0xff, 2, 128 }, + { 0x100, 2, 130 }, + { 0x101, 2, 132 }, + { 0x102, 2, 134 }, + { 0x103, 2, 136 }, + { 0x104, 2, 138 }, + { 0x105, 2, 140 }, + { 0x106, 2, 142 }, + { 0x107, 2, 144 }, + { 0x108, 2, 146 }, + { 0x109, 2, 148 }, + { 0x10a, 2, 150 }, + { 0x10b, 2, 152 }, + { 0x10c, 2, 154 }, + { 0x10d, 2, 156 }, + { 0x10e, 2, 158 }, + { 0x10f, 2, 160 }, + { 0x112, 2, 162 }, + { 0x113, 2, 164 }, + { 0x114, 2, 166 }, + { 0x115, 2, 168 }, + { 0x116, 2, 170 }, + { 0x117, 2, 172 }, + { 0x118, 2, 174 }, + { 0x119, 2, 176 }, + { 0x11a, 2, 178 }, + { 0x11b, 2, 180 }, + { 0x11c, 2, 182 }, + { 0x11d, 2, 184 }, + { 0x11e, 2, 186 }, + { 0x11f, 2, 188 }, + { 0x120, 2, 190 }, + { 0x121, 2, 192 }, + { 0x122, 2, 194 }, + { 0x123, 2, 196 }, + { 0x124, 2, 198 }, + { 0x125, 2, 200 }, + { 0x128, 2, 202 }, + { 0x129, 2, 204 }, + { 0x12a, 2, 206 }, + { 0x12b, 2, 208 }, + { 0x12c, 2, 210 }, + { 0x12d, 2, 212 }, + { 0x12e, 2, 214 }, + { 0x12f, 2, 216 }, + { 0x130, 2, 218 }, + { 0x132, 2, 220 }, + { 0x133, 2, 222 }, + { 0x134, 2, 224 }, + { 0x135, 2, 226 }, + { 0x136, 2, 228 }, + { 0x137, 2, 230 }, + { 0x139, 2, 232 }, + { 0x13a, 2, 234 }, + { 0x13b, 2, 236 }, + { 0x13c, 2, 238 }, + { 0x13d, 2, 240 }, + { 0x13e, 2, 242 }, + { 0x13f, 2, 244 }, + { 0x140, 2, 246 }, + { 0x143, 2, 248 }, + { 0x144, 2, 250 }, + { 0x145, 2, 252 }, + { 0x146, 2, 254 }, + { 0x147, 2, 256 }, + { 0x148, 2, 258 }, + { 0x149, 2, 260 }, + { 0x14c, 2, 262 }, + { 0x14d, 2, 264 }, + { 0x14e, 2, 266 }, + { 0x14f, 2, 268 }, + { 0x150, 2, 270 }, + { 0x151, 2, 272 }, + { 0x154, 2, 274 }, + { 0x155, 2, 276 }, + { 0x156, 2, 278 }, + { 0x157, 2, 280 }, + { 0x158, 2, 282 }, + { 0x159, 2, 284 }, + { 0x15a, 2, 286 }, + { 0x15b, 2, 288 }, + { 0x15c, 2, 290 }, + { 0x15d, 2, 292 }, + { 0x15e, 2, 294 }, + { 0x15f, 2, 296 }, + { 0x160, 2, 298 }, + { 0x161, 2, 300 }, + { 0x162, 2, 302 }, + { 0x163, 2, 304 }, + { 0x164, 2, 306 }, + { 0x165, 2, 308 }, + { 0x168, 2, 310 }, + { 0x169, 2, 312 }, + { 0x16a, 2, 314 }, + { 0x16b, 2, 316 }, + { 0x16c, 2, 318 }, + { 0x16d, 2, 320 }, + { 0x16e, 2, 322 }, + { 0x16f, 2, 324 }, + { 0x170, 2, 326 }, + { 0x171, 2, 328 }, + { 0x172, 2, 330 }, + { 0x173, 2, 332 }, + { 0x174, 2, 334 }, + { 0x175, 2, 336 }, + { 0x176, 2, 338 }, + { 0x177, 2, 340 }, + { 0x178, 2, 342 }, + { 0x179, 2, 344 }, + { 0x17a, 2, 346 }, + { 0x17b, 2, 348 }, + { 0x17c, 2, 350 }, + { 0x17d, 2, 352 }, + { 0x17e, 2, 354 }, + { 0x17f, 1, 356 }, + { 0x1a0, 2, 357 }, + { 0x1a1, 2, 359 }, + { 0x1af, 2, 361 }, + { 0x1b0, 2, 363 }, + { 0x1c4, 3, 365 }, + { 0x1c5, 3, 368 }, + { 0x1c6, 3, 371 }, + { 0x1c7, 2, 374 }, + { 0x1c8, 2, 376 }, + { 0x1c9, 2, 378 }, + { 0x1ca, 2, 380 }, + { 0x1cb, 2, 382 }, + { 0x1cc, 2, 384 }, + { 0x1cd, 2, 386 }, + { 0x1ce, 2, 388 }, + { 0x1cf, 2, 390 }, + { 0x1d0, 2, 392 }, + { 0x1d1, 2, 394 }, + { 0x1d2, 2, 396 }, + { 0x1d3, 2, 398 }, + { 0x1d4, 2, 400 }, + { 0x1d5, 3, 402 }, + { 0x1d6, 3, 405 }, + { 0x1d7, 3, 408 }, + { 0x1d8, 3, 411 }, + { 0x1d9, 3, 414 }, + { 0x1da, 3, 417 }, + { 0x1db, 3, 420 }, + { 0x1dc, 3, 423 }, + { 0x1de, 3, 426 }, + { 0x1df, 3, 429 }, + { 0x1e0, 3, 432 }, + { 0x1e1, 3, 435 }, + { 0x1e2, 2, 438 }, + { 0x1e3, 2, 440 }, + { 0x1e6, 2, 442 }, + { 0x1e7, 2, 444 }, + { 0x1e8, 2, 446 }, + { 0x1e9, 2, 448 }, + { 0x1ea, 2, 450 }, + { 0x1eb, 2, 452 }, + { 0x1ec, 3, 454 }, + { 0x1ed, 3, 457 }, + { 0x1ee, 2, 460 }, + { 0x1ef, 2, 462 }, + { 0x1f0, 2, 464 }, + { 0x1f1, 2, 466 }, + { 0x1f2, 2, 468 }, + { 0x1f3, 2, 470 }, + { 0x1f4, 2, 472 }, + { 0x1f5, 2, 474 }, + { 0x1f8, 2, 476 }, + { 0x1f9, 2, 478 }, + { 0x1fa, 3, 480 }, + { 0x1fb, 3, 483 }, + { 0x1fc, 2, 486 }, + { 0x1fd, 2, 488 }, + { 0x1fe, 2, 490 }, + { 0x1ff, 2, 492 }, + { 0x200, 2, 494 }, + { 0x201, 2, 496 }, + { 0x202, 2, 498 }, + { 0x203, 2, 500 }, + { 0x204, 2, 502 }, + { 0x205, 2, 504 }, + { 0x206, 2, 506 }, + { 0x207, 2, 508 }, + { 0x208, 2, 510 }, + { 0x209, 2, 512 }, + { 0x20a, 2, 514 }, + { 0x20b, 2, 516 }, + { 0x20c, 2, 518 }, + { 0x20d, 2, 520 }, + { 0x20e, 2, 522 }, + { 0x20f, 2, 524 }, + { 0x210, 2, 526 }, + { 0x211, 2, 528 }, + { 0x212, 2, 530 }, + { 0x213, 2, 532 }, + { 0x214, 2, 534 }, + { 0x215, 2, 536 }, + { 0x216, 2, 538 }, + { 0x217, 2, 540 }, + { 0x218, 2, 542 }, + { 0x219, 2, 544 }, + { 0x21a, 2, 546 }, + { 0x21b, 2, 548 }, + { 0x21e, 2, 550 }, + { 0x21f, 2, 552 }, + { 0x226, 2, 554 }, + { 0x227, 2, 556 }, + { 0x228, 2, 558 }, + { 0x229, 2, 560 }, + { 0x22a, 3, 562 }, + { 0x22b, 3, 565 }, + { 0x22c, 3, 568 }, + { 0x22d, 3, 571 }, + { 0x22e, 2, 574 }, + { 0x22f, 2, 576 }, + { 0x230, 3, 578 }, + { 0x231, 3, 581 }, + { 0x232, 2, 584 }, + { 0x233, 2, 586 }, + { 0x2b0, 1, 588 }, + { 0x2b1, 1, 589 }, + { 0x2b2, 1, 590 }, + { 0x2b3, 1, 591 }, + { 0x2b4, 1, 592 }, + { 0x2b5, 1, 593 }, + { 0x2b6, 1, 594 }, + { 0x2b7, 1, 595 }, + { 0x2b8, 1, 596 }, + { 0x2d8, 2, 597 }, + { 0x2d9, 2, 599 }, + { 0x2da, 2, 601 }, + { 0x2db, 2, 603 }, + { 0x2dc, 2, 605 }, + { 0x2dd, 2, 607 }, + { 0x2e0, 1, 609 }, + { 0x2e1, 1, 610 }, + { 0x2e2, 1, 356 }, + { 0x2e3, 1, 611 }, + { 0x2e4, 1, 612 }, + { 0x340, 1, 613 }, + { 0x341, 1, 614 }, + { 0x343, 1, 615 }, + { 0x344, 2, 616 }, + { 0x374, 1, 618 }, + { 0x37a, 2, 619 }, + { 0x37e, 1, 621 }, + { 0x384, 2, 8 }, + { 0x385, 3, 622 }, + { 0x386, 2, 625 }, + { 0x387, 1, 627 }, + { 0x388, 2, 628 }, + { 0x389, 2, 630 }, + { 0x38a, 2, 632 }, + { 0x38c, 2, 634 }, + { 0x38e, 2, 636 }, + { 0x38f, 2, 638 }, + { 0x390, 3, 640 }, + { 0x3aa, 2, 643 }, + { 0x3ab, 2, 645 }, + { 0x3ac, 2, 647 }, + { 0x3ad, 2, 649 }, + { 0x3ae, 2, 651 }, + { 0x3af, 2, 653 }, + { 0x3b0, 3, 655 }, + { 0x3ca, 2, 658 }, + { 0x3cb, 2, 660 }, + { 0x3cc, 2, 662 }, + { 0x3cd, 2, 664 }, + { 0x3ce, 2, 666 }, + { 0x3d0, 1, 668 }, + { 0x3d1, 1, 669 }, + { 0x3d2, 1, 670 }, + { 0x3d3, 2, 636 }, + { 0x3d4, 2, 645 }, + { 0x3d5, 1, 671 }, + { 0x3d6, 1, 672 }, + { 0x3f0, 1, 673 }, + { 0x3f1, 1, 674 }, + { 0x3f2, 1, 675 }, + { 0x3f4, 1, 676 }, + { 0x3f5, 1, 677 }, + { 0x400, 2, 678 }, + { 0x401, 2, 680 }, + { 0x403, 2, 682 }, + { 0x407, 2, 684 }, + { 0x40c, 2, 686 }, + { 0x40d, 2, 688 }, + { 0x40e, 2, 690 }, + { 0x419, 2, 692 }, + { 0x439, 2, 694 }, + { 0x450, 2, 696 }, + { 0x451, 2, 698 }, + { 0x453, 2, 700 }, + { 0x457, 2, 702 }, + { 0x45c, 2, 704 }, + { 0x45d, 2, 706 }, + { 0x45e, 2, 708 }, + { 0x476, 2, 710 }, + { 0x477, 2, 712 }, + { 0x4c1, 2, 714 }, + { 0x4c2, 2, 716 }, + { 0x4d0, 2, 718 }, + { 0x4d1, 2, 720 }, + { 0x4d2, 2, 722 }, + { 0x4d3, 2, 724 }, + { 0x4d6, 2, 726 }, + { 0x4d7, 2, 728 }, + { 0x4da, 2, 730 }, + { 0x4db, 2, 732 }, + { 0x4dc, 2, 734 }, + { 0x4dd, 2, 736 }, + { 0x4de, 2, 738 }, + { 0x4df, 2, 740 }, + { 0x4e2, 2, 742 }, + { 0x4e3, 2, 744 }, + { 0x4e4, 2, 746 }, + { 0x4e5, 2, 748 }, + { 0x4e6, 2, 750 }, + { 0x4e7, 2, 752 }, + { 0x4ea, 2, 754 }, + { 0x4eb, 2, 756 }, + { 0x4ec, 2, 758 }, + { 0x4ed, 2, 760 }, + { 0x4ee, 2, 762 }, + { 0x4ef, 2, 764 }, + { 0x4f0, 2, 766 }, + { 0x4f1, 2, 768 }, + { 0x4f2, 2, 770 }, + { 0x4f3, 2, 772 }, + { 0x4f4, 2, 774 }, + { 0x4f5, 2, 776 }, + { 0x4f8, 2, 778 }, + { 0x4f9, 2, 780 }, + { 0x587, 2, 782 }, + { 0x622, 2, 784 }, + { 0x623, 2, 786 }, + { 0x624, 2, 788 }, + { 0x625, 2, 790 }, + { 0x626, 2, 792 }, + { 0x675, 2, 794 }, + { 0x676, 2, 796 }, + { 0x677, 2, 798 }, + { 0x678, 2, 800 }, + { 0x6c0, 2, 802 }, + { 0x6c2, 2, 804 }, + { 0x6d3, 2, 806 }, + { 0x929, 2, 808 }, + { 0x931, 2, 810 }, + { 0x934, 2, 812 }, + { 0x958, 2, 814 }, + { 0x959, 2, 816 }, + { 0x95a, 2, 818 }, + { 0x95b, 2, 820 }, + { 0x95c, 2, 822 }, + { 0x95d, 2, 824 }, + { 0x95e, 2, 826 }, + { 0x95f, 2, 828 }, + { 0x9cb, 2, 830 }, + { 0x9cc, 2, 832 }, + { 0x9dc, 2, 834 }, + { 0x9dd, 2, 836 }, + { 0x9df, 2, 838 }, + { 0xa33, 2, 840 }, + { 0xa36, 2, 842 }, + { 0xa59, 2, 844 }, + { 0xa5a, 2, 846 }, + { 0xa5b, 2, 848 }, + { 0xa5e, 2, 850 }, + { 0xb48, 2, 852 }, + { 0xb4b, 2, 854 }, + { 0xb4c, 2, 856 }, + { 0xb5c, 2, 858 }, + { 0xb5d, 2, 860 }, + { 0xb94, 2, 862 }, + { 0xbca, 2, 864 }, + { 0xbcb, 2, 866 }, + { 0xbcc, 2, 868 }, + { 0xc48, 2, 870 }, + { 0xcc0, 2, 872 }, + { 0xcc7, 2, 874 }, + { 0xcc8, 2, 876 }, + { 0xcca, 2, 878 }, + { 0xccb, 3, 880 }, + { 0xd4a, 2, 883 }, + { 0xd4b, 2, 885 }, + { 0xd4c, 2, 887 }, + { 0xdda, 2, 889 }, + { 0xddc, 2, 891 }, + { 0xddd, 3, 893 }, + { 0xdde, 2, 896 }, + { 0xe33, 2, 898 }, + { 0xeb3, 2, 900 }, + { 0xedc, 2, 902 }, + { 0xedd, 2, 904 }, + { 0xf0c, 1, 906 }, + { 0xf43, 2, 907 }, + { 0xf4d, 2, 909 }, + { 0xf52, 2, 911 }, + { 0xf57, 2, 913 }, + { 0xf5c, 2, 915 }, + { 0xf69, 2, 917 }, + { 0xf73, 2, 919 }, + { 0xf75, 2, 921 }, + { 0xf76, 2, 923 }, + { 0xf77, 3, 925 }, + { 0xf78, 2, 928 }, + { 0xf79, 3, 930 }, + { 0xf81, 2, 933 }, + { 0xf93, 2, 935 }, + { 0xf9d, 2, 937 }, + { 0xfa2, 2, 939 }, + { 0xfa7, 2, 941 }, + { 0xfac, 2, 943 }, + { 0xfb9, 2, 945 }, + { 0x1026, 2, 947 }, + { 0x1e00, 2, 949 }, + { 0x1e01, 2, 951 }, + { 0x1e02, 2, 953 }, + { 0x1e03, 2, 955 }, + { 0x1e04, 2, 957 }, + { 0x1e05, 2, 959 }, + { 0x1e06, 2, 961 }, + { 0x1e07, 2, 963 }, + { 0x1e08, 3, 965 }, + { 0x1e09, 3, 968 }, + { 0x1e0a, 2, 971 }, + { 0x1e0b, 2, 973 }, + { 0x1e0c, 2, 975 }, + { 0x1e0d, 2, 977 }, + { 0x1e0e, 2, 979 }, + { 0x1e0f, 2, 981 }, + { 0x1e10, 2, 983 }, + { 0x1e11, 2, 985 }, + { 0x1e12, 2, 987 }, + { 0x1e13, 2, 989 }, + { 0x1e14, 3, 991 }, + { 0x1e15, 3, 994 }, + { 0x1e16, 3, 997 }, + { 0x1e17, 3, 1000 }, + { 0x1e18, 2, 1003 }, + { 0x1e19, 2, 1005 }, + { 0x1e1a, 2, 1007 }, + { 0x1e1b, 2, 1009 }, + { 0x1e1c, 3, 1011 }, + { 0x1e1d, 3, 1014 }, + { 0x1e1e, 2, 1017 }, + { 0x1e1f, 2, 1019 }, + { 0x1e20, 2, 1021 }, + { 0x1e21, 2, 1023 }, + { 0x1e22, 2, 1025 }, + { 0x1e23, 2, 1027 }, + { 0x1e24, 2, 1029 }, + { 0x1e25, 2, 1031 }, + { 0x1e26, 2, 1033 }, + { 0x1e27, 2, 1035 }, + { 0x1e28, 2, 1037 }, + { 0x1e29, 2, 1039 }, + { 0x1e2a, 2, 1041 }, + { 0x1e2b, 2, 1043 }, + { 0x1e2c, 2, 1045 }, + { 0x1e2d, 2, 1047 }, + { 0x1e2e, 3, 1049 }, + { 0x1e2f, 3, 1052 }, + { 0x1e30, 2, 1055 }, + { 0x1e31, 2, 1057 }, + { 0x1e32, 2, 1059 }, + { 0x1e33, 2, 1061 }, + { 0x1e34, 2, 1063 }, + { 0x1e35, 2, 1065 }, + { 0x1e36, 2, 1067 }, + { 0x1e37, 2, 1069 }, + { 0x1e38, 3, 1071 }, + { 0x1e39, 3, 1074 }, + { 0x1e3a, 2, 1077 }, + { 0x1e3b, 2, 1079 }, + { 0x1e3c, 2, 1081 }, + { 0x1e3d, 2, 1083 }, + { 0x1e3e, 2, 1085 }, + { 0x1e3f, 2, 1087 }, + { 0x1e40, 2, 1089 }, + { 0x1e41, 2, 1091 }, + { 0x1e42, 2, 1093 }, + { 0x1e43, 2, 1095 }, + { 0x1e44, 2, 1097 }, + { 0x1e45, 2, 1099 }, + { 0x1e46, 2, 1101 }, + { 0x1e47, 2, 1103 }, + { 0x1e48, 2, 1105 }, + { 0x1e49, 2, 1107 }, + { 0x1e4a, 2, 1109 }, + { 0x1e4b, 2, 1111 }, + { 0x1e4c, 3, 1113 }, + { 0x1e4d, 3, 1116 }, + { 0x1e4e, 3, 1119 }, + { 0x1e4f, 3, 1122 }, + { 0x1e50, 3, 1125 }, + { 0x1e51, 3, 1128 }, + { 0x1e52, 3, 1131 }, + { 0x1e53, 3, 1134 }, + { 0x1e54, 2, 1137 }, + { 0x1e55, 2, 1139 }, + { 0x1e56, 2, 1141 }, + { 0x1e57, 2, 1143 }, + { 0x1e58, 2, 1145 }, + { 0x1e59, 2, 1147 }, + { 0x1e5a, 2, 1149 }, + { 0x1e5b, 2, 1151 }, + { 0x1e5c, 3, 1153 }, + { 0x1e5d, 3, 1156 }, + { 0x1e5e, 2, 1159 }, + { 0x1e5f, 2, 1161 }, + { 0x1e60, 2, 1163 }, + { 0x1e61, 2, 1165 }, + { 0x1e62, 2, 1167 }, + { 0x1e63, 2, 1169 }, + { 0x1e64, 3, 1171 }, + { 0x1e65, 3, 1174 }, + { 0x1e66, 3, 1177 }, + { 0x1e67, 3, 1180 }, + { 0x1e68, 3, 1183 }, + { 0x1e69, 3, 1186 }, + { 0x1e6a, 2, 1189 }, + { 0x1e6b, 2, 1191 }, + { 0x1e6c, 2, 1193 }, + { 0x1e6d, 2, 1195 }, + { 0x1e6e, 2, 1197 }, + { 0x1e6f, 2, 1199 }, + { 0x1e70, 2, 1201 }, + { 0x1e71, 2, 1203 }, + { 0x1e72, 2, 1205 }, + { 0x1e73, 2, 1207 }, + { 0x1e74, 2, 1209 }, + { 0x1e75, 2, 1211 }, + { 0x1e76, 2, 1213 }, + { 0x1e77, 2, 1215 }, + { 0x1e78, 3, 1217 }, + { 0x1e79, 3, 1220 }, + { 0x1e7a, 3, 1223 }, + { 0x1e7b, 3, 1226 }, + { 0x1e7c, 2, 1229 }, + { 0x1e7d, 2, 1231 }, + { 0x1e7e, 2, 1233 }, + { 0x1e7f, 2, 1235 }, + { 0x1e80, 2, 1237 }, + { 0x1e81, 2, 1239 }, + { 0x1e82, 2, 1241 }, + { 0x1e83, 2, 1243 }, + { 0x1e84, 2, 1245 }, + { 0x1e85, 2, 1247 }, + { 0x1e86, 2, 1249 }, + { 0x1e87, 2, 1251 }, + { 0x1e88, 2, 1253 }, + { 0x1e89, 2, 1255 }, + { 0x1e8a, 2, 1257 }, + { 0x1e8b, 2, 1259 }, + { 0x1e8c, 2, 1261 }, + { 0x1e8d, 2, 1263 }, + { 0x1e8e, 2, 1265 }, + { 0x1e8f, 2, 1267 }, + { 0x1e90, 2, 1269 }, + { 0x1e91, 2, 1271 }, + { 0x1e92, 2, 1273 }, + { 0x1e93, 2, 1275 }, + { 0x1e94, 2, 1277 }, + { 0x1e95, 2, 1279 }, + { 0x1e96, 2, 1281 }, + { 0x1e97, 2, 1283 }, + { 0x1e98, 2, 1285 }, + { 0x1e99, 2, 1287 }, + { 0x1e9a, 2, 1289 }, + { 0x1e9b, 2, 1165 }, + { 0x1ea0, 2, 1291 }, + { 0x1ea1, 2, 1293 }, + { 0x1ea2, 2, 1295 }, + { 0x1ea3, 2, 1297 }, + { 0x1ea4, 3, 1299 }, + { 0x1ea5, 3, 1302 }, + { 0x1ea6, 3, 1305 }, + { 0x1ea7, 3, 1308 }, + { 0x1ea8, 3, 1311 }, + { 0x1ea9, 3, 1314 }, + { 0x1eaa, 3, 1317 }, + { 0x1eab, 3, 1320 }, + { 0x1eac, 3, 1323 }, + { 0x1ead, 3, 1326 }, + { 0x1eae, 3, 1329 }, + { 0x1eaf, 3, 1332 }, + { 0x1eb0, 3, 1335 }, + { 0x1eb1, 3, 1338 }, + { 0x1eb2, 3, 1341 }, + { 0x1eb3, 3, 1344 }, + { 0x1eb4, 3, 1347 }, + { 0x1eb5, 3, 1350 }, + { 0x1eb6, 3, 1353 }, + { 0x1eb7, 3, 1356 }, + { 0x1eb8, 2, 1359 }, + { 0x1eb9, 2, 1361 }, + { 0x1eba, 2, 1363 }, + { 0x1ebb, 2, 1365 }, + { 0x1ebc, 2, 1367 }, + { 0x1ebd, 2, 1369 }, + { 0x1ebe, 3, 1371 }, + { 0x1ebf, 3, 1374 }, + { 0x1ec0, 3, 1377 }, + { 0x1ec1, 3, 1380 }, + { 0x1ec2, 3, 1383 }, + { 0x1ec3, 3, 1386 }, + { 0x1ec4, 3, 1389 }, + { 0x1ec5, 3, 1392 }, + { 0x1ec6, 3, 1395 }, + { 0x1ec7, 3, 1398 }, + { 0x1ec8, 2, 1401 }, + { 0x1ec9, 2, 1403 }, + { 0x1eca, 2, 1405 }, + { 0x1ecb, 2, 1407 }, + { 0x1ecc, 2, 1409 }, + { 0x1ecd, 2, 1411 }, + { 0x1ece, 2, 1413 }, + { 0x1ecf, 2, 1415 }, + { 0x1ed0, 3, 1417 }, + { 0x1ed1, 3, 1420 }, + { 0x1ed2, 3, 1423 }, + { 0x1ed3, 3, 1426 }, + { 0x1ed4, 3, 1429 }, + { 0x1ed5, 3, 1432 }, + { 0x1ed6, 3, 1435 }, + { 0x1ed7, 3, 1438 }, + { 0x1ed8, 3, 1441 }, + { 0x1ed9, 3, 1444 }, + { 0x1eda, 3, 1447 }, + { 0x1edb, 3, 1450 }, + { 0x1edc, 3, 1453 }, + { 0x1edd, 3, 1456 }, + { 0x1ede, 3, 1459 }, + { 0x1edf, 3, 1462 }, + { 0x1ee0, 3, 1465 }, + { 0x1ee1, 3, 1468 }, + { 0x1ee2, 3, 1471 }, + { 0x1ee3, 3, 1474 }, + { 0x1ee4, 2, 1477 }, + { 0x1ee5, 2, 1479 }, + { 0x1ee6, 2, 1481 }, + { 0x1ee7, 2, 1483 }, + { 0x1ee8, 3, 1485 }, + { 0x1ee9, 3, 1488 }, + { 0x1eea, 3, 1491 }, + { 0x1eeb, 3, 1494 }, + { 0x1eec, 3, 1497 }, + { 0x1eed, 3, 1500 }, + { 0x1eee, 3, 1503 }, + { 0x1eef, 3, 1506 }, + { 0x1ef0, 3, 1509 }, + { 0x1ef1, 3, 1512 }, + { 0x1ef2, 2, 1515 }, + { 0x1ef3, 2, 1517 }, + { 0x1ef4, 2, 1519 }, + { 0x1ef5, 2, 1521 }, + { 0x1ef6, 2, 1523 }, + { 0x1ef7, 2, 1525 }, + { 0x1ef8, 2, 1527 }, + { 0x1ef9, 2, 1529 }, + { 0x1f00, 2, 1531 }, + { 0x1f01, 2, 1533 }, + { 0x1f02, 3, 1535 }, + { 0x1f03, 3, 1538 }, + { 0x1f04, 3, 1541 }, + { 0x1f05, 3, 1544 }, + { 0x1f06, 3, 1547 }, + { 0x1f07, 3, 1550 }, + { 0x1f08, 2, 1553 }, + { 0x1f09, 2, 1555 }, + { 0x1f0a, 3, 1557 }, + { 0x1f0b, 3, 1560 }, + { 0x1f0c, 3, 1563 }, + { 0x1f0d, 3, 1566 }, + { 0x1f0e, 3, 1569 }, + { 0x1f0f, 3, 1572 }, + { 0x1f10, 2, 1575 }, + { 0x1f11, 2, 1577 }, + { 0x1f12, 3, 1579 }, + { 0x1f13, 3, 1582 }, + { 0x1f14, 3, 1585 }, + { 0x1f15, 3, 1588 }, + { 0x1f18, 2, 1591 }, + { 0x1f19, 2, 1593 }, + { 0x1f1a, 3, 1595 }, + { 0x1f1b, 3, 1598 }, + { 0x1f1c, 3, 1601 }, + { 0x1f1d, 3, 1604 }, + { 0x1f20, 2, 1607 }, + { 0x1f21, 2, 1609 }, + { 0x1f22, 3, 1611 }, + { 0x1f23, 3, 1614 }, + { 0x1f24, 3, 1617 }, + { 0x1f25, 3, 1620 }, + { 0x1f26, 3, 1623 }, + { 0x1f27, 3, 1626 }, + { 0x1f28, 2, 1629 }, + { 0x1f29, 2, 1631 }, + { 0x1f2a, 3, 1633 }, + { 0x1f2b, 3, 1636 }, + { 0x1f2c, 3, 1639 }, + { 0x1f2d, 3, 1642 }, + { 0x1f2e, 3, 1645 }, + { 0x1f2f, 3, 1648 }, + { 0x1f30, 2, 1651 }, + { 0x1f31, 2, 1653 }, + { 0x1f32, 3, 1655 }, + { 0x1f33, 3, 1658 }, + { 0x1f34, 3, 1661 }, + { 0x1f35, 3, 1664 }, + { 0x1f36, 3, 1667 }, + { 0x1f37, 3, 1670 }, + { 0x1f38, 2, 1673 }, + { 0x1f39, 2, 1675 }, + { 0x1f3a, 3, 1677 }, + { 0x1f3b, 3, 1680 }, + { 0x1f3c, 3, 1683 }, + { 0x1f3d, 3, 1686 }, + { 0x1f3e, 3, 1689 }, + { 0x1f3f, 3, 1692 }, + { 0x1f40, 2, 1695 }, + { 0x1f41, 2, 1697 }, + { 0x1f42, 3, 1699 }, + { 0x1f43, 3, 1702 }, + { 0x1f44, 3, 1705 }, + { 0x1f45, 3, 1708 }, + { 0x1f48, 2, 1711 }, + { 0x1f49, 2, 1713 }, + { 0x1f4a, 3, 1715 }, + { 0x1f4b, 3, 1718 }, + { 0x1f4c, 3, 1721 }, + { 0x1f4d, 3, 1724 }, + { 0x1f50, 2, 1727 }, + { 0x1f51, 2, 1729 }, + { 0x1f52, 3, 1731 }, + { 0x1f53, 3, 1734 }, + { 0x1f54, 3, 1737 }, + { 0x1f55, 3, 1740 }, + { 0x1f56, 3, 1743 }, + { 0x1f57, 3, 1746 }, + { 0x1f59, 2, 1749 }, + { 0x1f5b, 3, 1751 }, + { 0x1f5d, 3, 1754 }, + { 0x1f5f, 3, 1757 }, + { 0x1f60, 2, 1760 }, + { 0x1f61, 2, 1762 }, + { 0x1f62, 3, 1764 }, + { 0x1f63, 3, 1767 }, + { 0x1f64, 3, 1770 }, + { 0x1f65, 3, 1773 }, + { 0x1f66, 3, 1776 }, + { 0x1f67, 3, 1779 }, + { 0x1f68, 2, 1782 }, + { 0x1f69, 2, 1784 }, + { 0x1f6a, 3, 1786 }, + { 0x1f6b, 3, 1789 }, + { 0x1f6c, 3, 1792 }, + { 0x1f6d, 3, 1795 }, + { 0x1f6e, 3, 1798 }, + { 0x1f6f, 3, 1801 }, + { 0x1f70, 2, 1804 }, + { 0x1f71, 2, 647 }, + { 0x1f72, 2, 1806 }, + { 0x1f73, 2, 649 }, + { 0x1f74, 2, 1808 }, + { 0x1f75, 2, 651 }, + { 0x1f76, 2, 1810 }, + { 0x1f77, 2, 653 }, + { 0x1f78, 2, 1812 }, + { 0x1f79, 2, 662 }, + { 0x1f7a, 2, 1814 }, + { 0x1f7b, 2, 664 }, + { 0x1f7c, 2, 1816 }, + { 0x1f7d, 2, 666 }, + { 0x1f80, 3, 1818 }, + { 0x1f81, 3, 1821 }, + { 0x1f82, 4, 1824 }, + { 0x1f83, 4, 1828 }, + { 0x1f84, 4, 1832 }, + { 0x1f85, 4, 1836 }, + { 0x1f86, 4, 1840 }, + { 0x1f87, 4, 1844 }, + { 0x1f88, 3, 1848 }, + { 0x1f89, 3, 1851 }, + { 0x1f8a, 4, 1854 }, + { 0x1f8b, 4, 1858 }, + { 0x1f8c, 4, 1862 }, + { 0x1f8d, 4, 1866 }, + { 0x1f8e, 4, 1870 }, + { 0x1f8f, 4, 1874 }, + { 0x1f90, 3, 1878 }, + { 0x1f91, 3, 1881 }, + { 0x1f92, 4, 1884 }, + { 0x1f93, 4, 1888 }, + { 0x1f94, 4, 1892 }, + { 0x1f95, 4, 1896 }, + { 0x1f96, 4, 1900 }, + { 0x1f97, 4, 1904 }, + { 0x1f98, 3, 1908 }, + { 0x1f99, 3, 1911 }, + { 0x1f9a, 4, 1914 }, + { 0x1f9b, 4, 1918 }, + { 0x1f9c, 4, 1922 }, + { 0x1f9d, 4, 1926 }, + { 0x1f9e, 4, 1930 }, + { 0x1f9f, 4, 1934 }, + { 0x1fa0, 3, 1938 }, + { 0x1fa1, 3, 1941 }, + { 0x1fa2, 4, 1944 }, + { 0x1fa3, 4, 1948 }, + { 0x1fa4, 4, 1952 }, + { 0x1fa5, 4, 1956 }, + { 0x1fa6, 4, 1960 }, + { 0x1fa7, 4, 1964 }, + { 0x1fa8, 3, 1968 }, + { 0x1fa9, 3, 1971 }, + { 0x1faa, 4, 1974 }, + { 0x1fab, 4, 1978 }, + { 0x1fac, 4, 1982 }, + { 0x1fad, 4, 1986 }, + { 0x1fae, 4, 1990 }, + { 0x1faf, 4, 1994 }, + { 0x1fb0, 2, 1998 }, + { 0x1fb1, 2, 2000 }, + { 0x1fb2, 3, 2002 }, + { 0x1fb3, 2, 2005 }, + { 0x1fb4, 3, 2007 }, + { 0x1fb6, 2, 2010 }, + { 0x1fb7, 3, 2012 }, + { 0x1fb8, 2, 2015 }, + { 0x1fb9, 2, 2017 }, + { 0x1fba, 2, 2019 }, + { 0x1fbb, 2, 625 }, + { 0x1fbc, 2, 2021 }, + { 0x1fbd, 2, 2023 }, + { 0x1fbe, 1, 2025 }, + { 0x1fbf, 2, 2023 }, + { 0x1fc0, 2, 2026 }, + { 0x1fc1, 3, 2028 }, + { 0x1fc2, 3, 2031 }, + { 0x1fc3, 2, 2034 }, + { 0x1fc4, 3, 2036 }, + { 0x1fc6, 2, 2039 }, + { 0x1fc7, 3, 2041 }, + { 0x1fc8, 2, 2044 }, + { 0x1fc9, 2, 628 }, + { 0x1fca, 2, 2046 }, + { 0x1fcb, 2, 630 }, + { 0x1fcc, 2, 2048 }, + { 0x1fcd, 3, 2050 }, + { 0x1fce, 3, 2053 }, + { 0x1fcf, 3, 2056 }, + { 0x1fd0, 2, 2059 }, + { 0x1fd1, 2, 2061 }, + { 0x1fd2, 3, 2063 }, + { 0x1fd3, 3, 640 }, + { 0x1fd6, 2, 2066 }, + { 0x1fd7, 3, 2068 }, + { 0x1fd8, 2, 2071 }, + { 0x1fd9, 2, 2073 }, + { 0x1fda, 2, 2075 }, + { 0x1fdb, 2, 632 }, + { 0x1fdd, 3, 2077 }, + { 0x1fde, 3, 2080 }, + { 0x1fdf, 3, 2083 }, + { 0x1fe0, 2, 2086 }, + { 0x1fe1, 2, 2088 }, + { 0x1fe2, 3, 2090 }, + { 0x1fe3, 3, 655 }, + { 0x1fe4, 2, 2093 }, + { 0x1fe5, 2, 2095 }, + { 0x1fe6, 2, 2097 }, + { 0x1fe7, 3, 2099 }, + { 0x1fe8, 2, 2102 }, + { 0x1fe9, 2, 2104 }, + { 0x1fea, 2, 2106 }, + { 0x1feb, 2, 636 }, + { 0x1fec, 2, 2108 }, + { 0x1fed, 3, 2110 }, + { 0x1fee, 3, 622 }, + { 0x1fef, 1, 2113 }, + { 0x1ff2, 3, 2114 }, + { 0x1ff3, 2, 2117 }, + { 0x1ff4, 3, 2119 }, + { 0x1ff6, 2, 2122 }, + { 0x1ff7, 3, 2124 }, + { 0x1ff8, 2, 2127 }, + { 0x1ff9, 2, 634 }, + { 0x1ffa, 2, 2129 }, + { 0x1ffb, 2, 638 }, + { 0x1ffc, 2, 2131 }, + { 0x1ffd, 2, 8 }, + { 0x1ffe, 2, 2133 }, + { 0x2000, 1, 0 }, + { 0x2001, 1, 0 }, + { 0x2002, 1, 0 }, + { 0x2003, 1, 0 }, + { 0x2004, 1, 0 }, + { 0x2005, 1, 0 }, + { 0x2006, 1, 0 }, + { 0x2007, 1, 0 }, + { 0x2008, 1, 0 }, + { 0x2009, 1, 0 }, + { 0x200a, 1, 0 }, + { 0x2011, 1, 2135 }, + { 0x2017, 2, 2136 }, + { 0x2024, 1, 2138 }, + { 0x2025, 2, 2139 }, + { 0x2026, 3, 2141 }, + { 0x202f, 1, 0 }, + { 0x2033, 2, 2144 }, + { 0x2034, 3, 2146 }, + { 0x2036, 2, 2149 }, + { 0x2037, 3, 2151 }, + { 0x203c, 2, 2154 }, + { 0x203e, 2, 2156 }, + { 0x2047, 2, 2158 }, + { 0x2048, 2, 2160 }, + { 0x2049, 2, 2162 }, + { 0x2057, 4, 2164 }, + { 0x205f, 1, 0 }, + { 0x2070, 1, 2168 }, + { 0x2071, 1, 2169 }, + { 0x2074, 1, 2170 }, + { 0x2075, 1, 2171 }, + { 0x2076, 1, 2172 }, + { 0x2077, 1, 2173 }, + { 0x2078, 1, 2174 }, + { 0x2079, 1, 2175 }, + { 0x207a, 1, 2176 }, + { 0x207b, 1, 2177 }, + { 0x207c, 1, 2178 }, + { 0x207d, 1, 2179 }, + { 0x207e, 1, 2180 }, + { 0x207f, 1, 2181 }, + { 0x2080, 1, 2168 }, + { 0x2081, 1, 13 }, + { 0x2082, 1, 6 }, + { 0x2083, 1, 7 }, + { 0x2084, 1, 2170 }, + { 0x2085, 1, 2171 }, + { 0x2086, 1, 2172 }, + { 0x2087, 1, 2173 }, + { 0x2088, 1, 2174 }, + { 0x2089, 1, 2175 }, + { 0x208a, 1, 2176 }, + { 0x208b, 1, 2177 }, + { 0x208c, 1, 2178 }, + { 0x208d, 1, 2179 }, + { 0x208e, 1, 2180 }, + { 0x20a8, 2, 2182 }, + { 0x2100, 3, 2184 }, + { 0x2101, 3, 2187 }, + { 0x2102, 1, 2190 }, + { 0x2103, 2, 2191 }, + { 0x2105, 3, 2193 }, + { 0x2106, 3, 2196 }, + { 0x2107, 1, 2199 }, + { 0x2109, 2, 2200 }, + { 0x210a, 1, 2202 }, + { 0x210b, 1, 2203 }, + { 0x210c, 1, 2203 }, + { 0x210d, 1, 2203 }, + { 0x210e, 1, 588 }, + { 0x210f, 1, 2204 }, + { 0x2110, 1, 2205 }, + { 0x2111, 1, 2205 }, + { 0x2112, 1, 2206 }, + { 0x2113, 1, 610 }, + { 0x2115, 1, 2207 }, + { 0x2116, 2, 2208 }, + { 0x2119, 1, 2210 }, + { 0x211a, 1, 2211 }, + { 0x211b, 1, 2212 }, + { 0x211c, 1, 2212 }, + { 0x211d, 1, 2212 }, + { 0x2120, 2, 2213 }, + { 0x2121, 3, 2215 }, + { 0x2122, 2, 2218 }, + { 0x2124, 1, 2220 }, + { 0x2126, 1, 2221 }, + { 0x2128, 1, 2220 }, + { 0x212a, 1, 2222 }, + { 0x212b, 2, 34 }, + { 0x212c, 1, 2223 }, + { 0x212d, 1, 2190 }, + { 0x212f, 1, 2224 }, + { 0x2130, 1, 2225 }, + { 0x2131, 1, 2226 }, + { 0x2133, 1, 2227 }, + { 0x2134, 1, 14 }, + { 0x2135, 1, 2228 }, + { 0x2136, 1, 2229 }, + { 0x2137, 1, 2230 }, + { 0x2138, 1, 2231 }, + { 0x2139, 1, 2169 }, + { 0x213d, 1, 2232 }, + { 0x213e, 1, 2233 }, + { 0x213f, 1, 2234 }, + { 0x2140, 1, 2235 }, + { 0x2145, 1, 2236 }, + { 0x2146, 1, 2237 }, + { 0x2147, 1, 2224 }, + { 0x2148, 1, 2169 }, + { 0x2149, 1, 590 }, + { 0x2153, 3, 2238 }, + { 0x2154, 3, 2241 }, + { 0x2155, 3, 2244 }, + { 0x2156, 3, 2247 }, + { 0x2157, 3, 2250 }, + { 0x2158, 3, 2253 }, + { 0x2159, 3, 2256 }, + { 0x215a, 3, 2259 }, + { 0x215b, 3, 2262 }, + { 0x215c, 3, 2265 }, + { 0x215d, 3, 2268 }, + { 0x215e, 3, 2271 }, + { 0x215f, 2, 2274 }, + { 0x2160, 1, 2205 }, + { 0x2161, 2, 2276 }, + { 0x2162, 3, 2278 }, + { 0x2163, 2, 2281 }, + { 0x2164, 1, 2283 }, + { 0x2165, 2, 2284 }, + { 0x2166, 3, 2286 }, + { 0x2167, 4, 2289 }, + { 0x2168, 2, 2293 }, + { 0x2169, 1, 2295 }, + { 0x216a, 2, 2296 }, + { 0x216b, 3, 2298 }, + { 0x216c, 1, 2206 }, + { 0x216d, 1, 2190 }, + { 0x216e, 1, 2236 }, + { 0x216f, 1, 2227 }, + { 0x2170, 1, 2169 }, + { 0x2171, 2, 2301 }, + { 0x2172, 3, 2303 }, + { 0x2173, 2, 2306 }, + { 0x2174, 1, 2308 }, + { 0x2175, 2, 2309 }, + { 0x2176, 3, 2311 }, + { 0x2177, 4, 2314 }, + { 0x2178, 2, 2318 }, + { 0x2179, 1, 611 }, + { 0x217a, 2, 2320 }, + { 0x217b, 3, 2322 }, + { 0x217c, 1, 610 }, + { 0x217d, 1, 2325 }, + { 0x217e, 1, 2237 }, + { 0x217f, 1, 2326 }, + { 0x219a, 2, 2327 }, + { 0x219b, 2, 2329 }, + { 0x21ae, 2, 2331 }, + { 0x21cd, 2, 2333 }, + { 0x21ce, 2, 2335 }, + { 0x21cf, 2, 2337 }, + { 0x2204, 2, 2339 }, + { 0x2209, 2, 2341 }, + { 0x220c, 2, 2343 }, + { 0x2224, 2, 2345 }, + { 0x2226, 2, 2347 }, + { 0x222c, 2, 2349 }, + { 0x222d, 3, 2351 }, + { 0x222f, 2, 2354 }, + { 0x2230, 3, 2356 }, + { 0x2241, 2, 2359 }, + { 0x2244, 2, 2361 }, + { 0x2247, 2, 2363 }, + { 0x2249, 2, 2365 }, + { 0x2260, 2, 2367 }, + { 0x2262, 2, 2369 }, + { 0x226d, 2, 2371 }, + { 0x226e, 2, 2373 }, + { 0x226f, 2, 2375 }, + { 0x2270, 2, 2377 }, + { 0x2271, 2, 2379 }, + { 0x2274, 2, 2381 }, + { 0x2275, 2, 2383 }, + { 0x2278, 2, 2385 }, + { 0x2279, 2, 2387 }, + { 0x2280, 2, 2389 }, + { 0x2281, 2, 2391 }, + { 0x2284, 2, 2393 }, + { 0x2285, 2, 2395 }, + { 0x2288, 2, 2397 }, + { 0x2289, 2, 2399 }, + { 0x22ac, 2, 2401 }, + { 0x22ad, 2, 2403 }, + { 0x22ae, 2, 2405 }, + { 0x22af, 2, 2407 }, + { 0x22e0, 2, 2409 }, + { 0x22e1, 2, 2411 }, + { 0x22e2, 2, 2413 }, + { 0x22e3, 2, 2415 }, + { 0x22ea, 2, 2417 }, + { 0x22eb, 2, 2419 }, + { 0x22ec, 2, 2421 }, + { 0x22ed, 2, 2423 }, + { 0x2329, 1, 2425 }, + { 0x232a, 1, 2426 }, + { 0x2460, 1, 13 }, + { 0x2461, 1, 6 }, + { 0x2462, 1, 7 }, + { 0x2463, 1, 2170 }, + { 0x2464, 1, 2171 }, + { 0x2465, 1, 2172 }, + { 0x2466, 1, 2173 }, + { 0x2467, 1, 2174 }, + { 0x2468, 1, 2175 }, + { 0x2469, 2, 2427 }, + { 0x246a, 2, 2429 }, + { 0x246b, 2, 2431 }, + { 0x246c, 2, 2433 }, + { 0x246d, 2, 2435 }, + { 0x246e, 2, 2437 }, + { 0x246f, 2, 2439 }, + { 0x2470, 2, 2441 }, + { 0x2471, 2, 2443 }, + { 0x2472, 2, 2445 }, + { 0x2473, 2, 2447 }, + { 0x2474, 3, 2449 }, + { 0x2475, 3, 2452 }, + { 0x2476, 3, 2455 }, + { 0x2477, 3, 2458 }, + { 0x2478, 3, 2461 }, + { 0x2479, 3, 2464 }, + { 0x247a, 3, 2467 }, + { 0x247b, 3, 2470 }, + { 0x247c, 3, 2473 }, + { 0x247d, 4, 2476 }, + { 0x247e, 4, 2480 }, + { 0x247f, 4, 2484 }, + { 0x2480, 4, 2488 }, + { 0x2481, 4, 2492 }, + { 0x2482, 4, 2496 }, + { 0x2483, 4, 2500 }, + { 0x2484, 4, 2504 }, + { 0x2485, 4, 2508 }, + { 0x2486, 4, 2512 }, + { 0x2487, 4, 2516 }, + { 0x2488, 2, 2520 }, + { 0x2489, 2, 2522 }, + { 0x248a, 2, 2524 }, + { 0x248b, 2, 2526 }, + { 0x248c, 2, 2528 }, + { 0x248d, 2, 2530 }, + { 0x248e, 2, 2532 }, + { 0x248f, 2, 2534 }, + { 0x2490, 2, 2536 }, + { 0x2491, 3, 2538 }, + { 0x2492, 3, 2541 }, + { 0x2493, 3, 2544 }, + { 0x2494, 3, 2547 }, + { 0x2495, 3, 2550 }, + { 0x2496, 3, 2553 }, + { 0x2497, 3, 2556 }, + { 0x2498, 3, 2559 }, + { 0x2499, 3, 2562 }, + { 0x249a, 3, 2565 }, + { 0x249b, 3, 2568 }, + { 0x249c, 3, 2571 }, + { 0x249d, 3, 2574 }, + { 0x249e, 3, 2577 }, + { 0x249f, 3, 2580 }, + { 0x24a0, 3, 2583 }, + { 0x24a1, 3, 2586 }, + { 0x24a2, 3, 2589 }, + { 0x24a3, 3, 2592 }, + { 0x24a4, 3, 2595 }, + { 0x24a5, 3, 2598 }, + { 0x24a6, 3, 2601 }, + { 0x24a7, 3, 2604 }, + { 0x24a8, 3, 2607 }, + { 0x24a9, 3, 2610 }, + { 0x24aa, 3, 2613 }, + { 0x24ab, 3, 2616 }, + { 0x24ac, 3, 2619 }, + { 0x24ad, 3, 2622 }, + { 0x24ae, 3, 2625 }, + { 0x24af, 3, 2628 }, + { 0x24b0, 3, 2631 }, + { 0x24b1, 3, 2634 }, + { 0x24b2, 3, 2637 }, + { 0x24b3, 3, 2640 }, + { 0x24b4, 3, 2643 }, + { 0x24b5, 3, 2646 }, + { 0x24b6, 1, 2649 }, + { 0x24b7, 1, 2223 }, + { 0x24b8, 1, 2190 }, + { 0x24b9, 1, 2236 }, + { 0x24ba, 1, 2225 }, + { 0x24bb, 1, 2226 }, + { 0x24bc, 1, 2650 }, + { 0x24bd, 1, 2203 }, + { 0x24be, 1, 2205 }, + { 0x24bf, 1, 2651 }, + { 0x24c0, 1, 2222 }, + { 0x24c1, 1, 2206 }, + { 0x24c2, 1, 2227 }, + { 0x24c3, 1, 2207 }, + { 0x24c4, 1, 2652 }, + { 0x24c5, 1, 2210 }, + { 0x24c6, 1, 2211 }, + { 0x24c7, 1, 2212 }, + { 0x24c8, 1, 2653 }, + { 0x24c9, 1, 2654 }, + { 0x24ca, 1, 2655 }, + { 0x24cb, 1, 2283 }, + { 0x24cc, 1, 2656 }, + { 0x24cd, 1, 2295 }, + { 0x24ce, 1, 2657 }, + { 0x24cf, 1, 2220 }, + { 0x24d0, 1, 3 }, + { 0x24d1, 1, 2658 }, + { 0x24d2, 1, 2325 }, + { 0x24d3, 1, 2237 }, + { 0x24d4, 1, 2224 }, + { 0x24d5, 1, 2659 }, + { 0x24d6, 1, 2202 }, + { 0x24d7, 1, 588 }, + { 0x24d8, 1, 2169 }, + { 0x24d9, 1, 590 }, + { 0x24da, 1, 2660 }, + { 0x24db, 1, 610 }, + { 0x24dc, 1, 2326 }, + { 0x24dd, 1, 2181 }, + { 0x24de, 1, 14 }, + { 0x24df, 1, 2661 }, + { 0x24e0, 1, 2662 }, + { 0x24e1, 1, 591 }, + { 0x24e2, 1, 356 }, + { 0x24e3, 1, 2663 }, + { 0x24e4, 1, 2664 }, + { 0x24e5, 1, 2308 }, + { 0x24e6, 1, 595 }, + { 0x24e7, 1, 611 }, + { 0x24e8, 1, 596 }, + { 0x24e9, 1, 2665 }, + { 0x24ea, 1, 2168 }, + { 0x2a0c, 4, 2666 }, + { 0x2a74, 3, 2670 }, + { 0x2a75, 2, 2673 }, + { 0x2a76, 3, 2675 }, + { 0x2adc, 2, 2678 }, + { 0x2e9f, 1, 2680 }, + { 0x2ef3, 1, 2681 }, + { 0x2f00, 1, 2682 }, + { 0x2f01, 1, 2683 }, + { 0x2f02, 1, 2684 }, + { 0x2f03, 1, 2685 }, + { 0x2f04, 1, 2686 }, + { 0x2f05, 1, 2687 }, + { 0x2f06, 1, 2688 }, + { 0x2f07, 1, 2689 }, + { 0x2f08, 1, 2690 }, + { 0x2f09, 1, 2691 }, + { 0x2f0a, 1, 2692 }, + { 0x2f0b, 1, 2693 }, + { 0x2f0c, 1, 2694 }, + { 0x2f0d, 1, 2695 }, + { 0x2f0e, 1, 2696 }, + { 0x2f0f, 1, 2697 }, + { 0x2f10, 1, 2698 }, + { 0x2f11, 1, 2699 }, + { 0x2f12, 1, 2700 }, + { 0x2f13, 1, 2701 }, + { 0x2f14, 1, 2702 }, + { 0x2f15, 1, 2703 }, + { 0x2f16, 1, 2704 }, + { 0x2f17, 1, 2705 }, + { 0x2f18, 1, 2706 }, + { 0x2f19, 1, 2707 }, + { 0x2f1a, 1, 2708 }, + { 0x2f1b, 1, 2709 }, + { 0x2f1c, 1, 2710 }, + { 0x2f1d, 1, 2711 }, + { 0x2f1e, 1, 2712 }, + { 0x2f1f, 1, 2713 }, + { 0x2f20, 1, 2714 }, + { 0x2f21, 1, 2715 }, + { 0x2f22, 1, 2716 }, + { 0x2f23, 1, 2717 }, + { 0x2f24, 1, 2718 }, + { 0x2f25, 1, 2719 }, + { 0x2f26, 1, 2720 }, + { 0x2f27, 1, 2721 }, + { 0x2f28, 1, 2722 }, + { 0x2f29, 1, 2723 }, + { 0x2f2a, 1, 2724 }, + { 0x2f2b, 1, 2725 }, + { 0x2f2c, 1, 2726 }, + { 0x2f2d, 1, 2727 }, + { 0x2f2e, 1, 2728 }, + { 0x2f2f, 1, 2729 }, + { 0x2f30, 1, 2730 }, + { 0x2f31, 1, 2731 }, + { 0x2f32, 1, 2732 }, + { 0x2f33, 1, 2733 }, + { 0x2f34, 1, 2734 }, + { 0x2f35, 1, 2735 }, + { 0x2f36, 1, 2736 }, + { 0x2f37, 1, 2737 }, + { 0x2f38, 1, 2738 }, + { 0x2f39, 1, 2739 }, + { 0x2f3a, 1, 2740 }, + { 0x2f3b, 1, 2741 }, + { 0x2f3c, 1, 2742 }, + { 0x2f3d, 1, 2743 }, + { 0x2f3e, 1, 2744 }, + { 0x2f3f, 1, 2745 }, + { 0x2f40, 1, 2746 }, + { 0x2f41, 1, 2747 }, + { 0x2f42, 1, 2748 }, + { 0x2f43, 1, 2749 }, + { 0x2f44, 1, 2750 }, + { 0x2f45, 1, 2751 }, + { 0x2f46, 1, 2752 }, + { 0x2f47, 1, 2753 }, + { 0x2f48, 1, 2754 }, + { 0x2f49, 1, 2755 }, + { 0x2f4a, 1, 2756 }, + { 0x2f4b, 1, 2757 }, + { 0x2f4c, 1, 2758 }, + { 0x2f4d, 1, 2759 }, + { 0x2f4e, 1, 2760 }, + { 0x2f4f, 1, 2761 }, + { 0x2f50, 1, 2762 }, + { 0x2f51, 1, 2763 }, + { 0x2f52, 1, 2764 }, + { 0x2f53, 1, 2765 }, + { 0x2f54, 1, 2766 }, + { 0x2f55, 1, 2767 }, + { 0x2f56, 1, 2768 }, + { 0x2f57, 1, 2769 }, + { 0x2f58, 1, 2770 }, + { 0x2f59, 1, 2771 }, + { 0x2f5a, 1, 2772 }, + { 0x2f5b, 1, 2773 }, + { 0x2f5c, 1, 2774 }, + { 0x2f5d, 1, 2775 }, + { 0x2f5e, 1, 2776 }, + { 0x2f5f, 1, 2777 }, + { 0x2f60, 1, 2778 }, + { 0x2f61, 1, 2779 }, + { 0x2f62, 1, 2780 }, + { 0x2f63, 1, 2781 }, + { 0x2f64, 1, 2782 }, + { 0x2f65, 1, 2783 }, + { 0x2f66, 1, 2784 }, + { 0x2f67, 1, 2785 }, + { 0x2f68, 1, 2786 }, + { 0x2f69, 1, 2787 }, + { 0x2f6a, 1, 2788 }, + { 0x2f6b, 1, 2789 }, + { 0x2f6c, 1, 2790 }, + { 0x2f6d, 1, 2791 }, + { 0x2f6e, 1, 2792 }, + { 0x2f6f, 1, 2793 }, + { 0x2f70, 1, 2794 }, + { 0x2f71, 1, 2795 }, + { 0x2f72, 1, 2796 }, + { 0x2f73, 1, 2797 }, + { 0x2f74, 1, 2798 }, + { 0x2f75, 1, 2799 }, + { 0x2f76, 1, 2800 }, + { 0x2f77, 1, 2801 }, + { 0x2f78, 1, 2802 }, + { 0x2f79, 1, 2803 }, + { 0x2f7a, 1, 2804 }, + { 0x2f7b, 1, 2805 }, + { 0x2f7c, 1, 2806 }, + { 0x2f7d, 1, 2807 }, + { 0x2f7e, 1, 2808 }, + { 0x2f7f, 1, 2809 }, + { 0x2f80, 1, 2810 }, + { 0x2f81, 1, 2811 }, + { 0x2f82, 1, 2812 }, + { 0x2f83, 1, 2813 }, + { 0x2f84, 1, 2814 }, + { 0x2f85, 1, 2815 }, + { 0x2f86, 1, 2816 }, + { 0x2f87, 1, 2817 }, + { 0x2f88, 1, 2818 }, + { 0x2f89, 1, 2819 }, + { 0x2f8a, 1, 2820 }, + { 0x2f8b, 1, 2821 }, + { 0x2f8c, 1, 2822 }, + { 0x2f8d, 1, 2823 }, + { 0x2f8e, 1, 2824 }, + { 0x2f8f, 1, 2825 }, + { 0x2f90, 1, 2826 }, + { 0x2f91, 1, 2827 }, + { 0x2f92, 1, 2828 }, + { 0x2f93, 1, 2829 }, + { 0x2f94, 1, 2830 }, + { 0x2f95, 1, 2831 }, + { 0x2f96, 1, 2832 }, + { 0x2f97, 1, 2833 }, + { 0x2f98, 1, 2834 }, + { 0x2f99, 1, 2835 }, + { 0x2f9a, 1, 2836 }, + { 0x2f9b, 1, 2837 }, + { 0x2f9c, 1, 2838 }, + { 0x2f9d, 1, 2839 }, + { 0x2f9e, 1, 2840 }, + { 0x2f9f, 1, 2841 }, + { 0x2fa0, 1, 2842 }, + { 0x2fa1, 1, 2843 }, + { 0x2fa2, 1, 2844 }, + { 0x2fa3, 1, 2845 }, + { 0x2fa4, 1, 2846 }, + { 0x2fa5, 1, 2847 }, + { 0x2fa6, 1, 2848 }, + { 0x2fa7, 1, 2849 }, + { 0x2fa8, 1, 2850 }, + { 0x2fa9, 1, 2851 }, + { 0x2faa, 1, 2852 }, + { 0x2fab, 1, 2853 }, + { 0x2fac, 1, 2854 }, + { 0x2fad, 1, 2855 }, + { 0x2fae, 1, 2856 }, + { 0x2faf, 1, 2857 }, + { 0x2fb0, 1, 2858 }, + { 0x2fb1, 1, 2859 }, + { 0x2fb2, 1, 2860 }, + { 0x2fb3, 1, 2861 }, + { 0x2fb4, 1, 2862 }, + { 0x2fb5, 1, 2863 }, + { 0x2fb6, 1, 2864 }, + { 0x2fb7, 1, 2865 }, + { 0x2fb8, 1, 2866 }, + { 0x2fb9, 1, 2867 }, + { 0x2fba, 1, 2868 }, + { 0x2fbb, 1, 2869 }, + { 0x2fbc, 1, 2870 }, + { 0x2fbd, 1, 2871 }, + { 0x2fbe, 1, 2872 }, + { 0x2fbf, 1, 2873 }, + { 0x2fc0, 1, 2874 }, + { 0x2fc1, 1, 2875 }, + { 0x2fc2, 1, 2876 }, + { 0x2fc3, 1, 2877 }, + { 0x2fc4, 1, 2878 }, + { 0x2fc5, 1, 2879 }, + { 0x2fc6, 1, 2880 }, + { 0x2fc7, 1, 2881 }, + { 0x2fc8, 1, 2882 }, + { 0x2fc9, 1, 2883 }, + { 0x2fca, 1, 2884 }, + { 0x2fcb, 1, 2885 }, + { 0x2fcc, 1, 2886 }, + { 0x2fcd, 1, 2887 }, + { 0x2fce, 1, 2888 }, + { 0x2fcf, 1, 2889 }, + { 0x2fd0, 1, 2890 }, + { 0x2fd1, 1, 2891 }, + { 0x2fd2, 1, 2892 }, + { 0x2fd3, 1, 2893 }, + { 0x2fd4, 1, 2894 }, + { 0x2fd5, 1, 2895 }, + { 0x3000, 1, 0 }, + { 0x3036, 1, 2896 }, + { 0x3038, 1, 2705 }, + { 0x3039, 1, 2897 }, + { 0x303a, 1, 2898 }, + { 0x304c, 2, 2899 }, + { 0x304e, 2, 2901 }, + { 0x3050, 2, 2903 }, + { 0x3052, 2, 2905 }, + { 0x3054, 2, 2907 }, + { 0x3056, 2, 2909 }, + { 0x3058, 2, 2911 }, + { 0x305a, 2, 2913 }, + { 0x305c, 2, 2915 }, + { 0x305e, 2, 2917 }, + { 0x3060, 2, 2919 }, + { 0x3062, 2, 2921 }, + { 0x3065, 2, 2923 }, + { 0x3067, 2, 2925 }, + { 0x3069, 2, 2927 }, + { 0x3070, 2, 2929 }, + { 0x3071, 2, 2931 }, + { 0x3073, 2, 2933 }, + { 0x3074, 2, 2935 }, + { 0x3076, 2, 2937 }, + { 0x3077, 2, 2939 }, + { 0x3079, 2, 2941 }, + { 0x307a, 2, 2943 }, + { 0x307c, 2, 2945 }, + { 0x307d, 2, 2947 }, + { 0x3094, 2, 2949 }, + { 0x309b, 2, 2951 }, + { 0x309c, 2, 2953 }, + { 0x309e, 2, 2955 }, + { 0x309f, 2, 2957 }, + { 0x30ac, 2, 2959 }, + { 0x30ae, 2, 2961 }, + { 0x30b0, 2, 2963 }, + { 0x30b2, 2, 2965 }, + { 0x30b4, 2, 2967 }, + { 0x30b6, 2, 2969 }, + { 0x30b8, 2, 2971 }, + { 0x30ba, 2, 2973 }, + { 0x30bc, 2, 2975 }, + { 0x30be, 2, 2977 }, + { 0x30c0, 2, 2979 }, + { 0x30c2, 2, 2981 }, + { 0x30c5, 2, 2983 }, + { 0x30c7, 2, 2985 }, + { 0x30c9, 2, 2987 }, + { 0x30d0, 2, 2989 }, + { 0x30d1, 2, 2991 }, + { 0x30d3, 2, 2993 }, + { 0x30d4, 2, 2995 }, + { 0x30d6, 2, 2997 }, + { 0x30d7, 2, 2999 }, + { 0x30d9, 2, 3001 }, + { 0x30da, 2, 3003 }, + { 0x30dc, 2, 3005 }, + { 0x30dd, 2, 3007 }, + { 0x30f4, 2, 3009 }, + { 0x30f7, 2, 3011 }, + { 0x30f8, 2, 3013 }, + { 0x30f9, 2, 3015 }, + { 0x30fa, 2, 3017 }, + { 0x30fe, 2, 3019 }, + { 0x30ff, 2, 3021 }, + { 0x3131, 1, 3023 }, + { 0x3132, 1, 3024 }, + { 0x3133, 1, 3025 }, + { 0x3134, 1, 3026 }, + { 0x3135, 1, 3027 }, + { 0x3136, 1, 3028 }, + { 0x3137, 1, 3029 }, + { 0x3138, 1, 3030 }, + { 0x3139, 1, 3031 }, + { 0x313a, 1, 3032 }, + { 0x313b, 1, 3033 }, + { 0x313c, 1, 3034 }, + { 0x313d, 1, 3035 }, + { 0x313e, 1, 3036 }, + { 0x313f, 1, 3037 }, + { 0x3140, 1, 3038 }, + { 0x3141, 1, 3039 }, + { 0x3142, 1, 3040 }, + { 0x3143, 1, 3041 }, + { 0x3144, 1, 3042 }, + { 0x3145, 1, 3043 }, + { 0x3146, 1, 3044 }, + { 0x3147, 1, 3045 }, + { 0x3148, 1, 3046 }, + { 0x3149, 1, 3047 }, + { 0x314a, 1, 3048 }, + { 0x314b, 1, 3049 }, + { 0x314c, 1, 3050 }, + { 0x314d, 1, 3051 }, + { 0x314e, 1, 3052 }, + { 0x314f, 1, 3053 }, + { 0x3150, 1, 3054 }, + { 0x3151, 1, 3055 }, + { 0x3152, 1, 3056 }, + { 0x3153, 1, 3057 }, + { 0x3154, 1, 3058 }, + { 0x3155, 1, 3059 }, + { 0x3156, 1, 3060 }, + { 0x3157, 1, 3061 }, + { 0x3158, 1, 3062 }, + { 0x3159, 1, 3063 }, + { 0x315a, 1, 3064 }, + { 0x315b, 1, 3065 }, + { 0x315c, 1, 3066 }, + { 0x315d, 1, 3067 }, + { 0x315e, 1, 3068 }, + { 0x315f, 1, 3069 }, + { 0x3160, 1, 3070 }, + { 0x3161, 1, 3071 }, + { 0x3162, 1, 3072 }, + { 0x3163, 1, 3073 }, + { 0x3164, 1, 3074 }, + { 0x3165, 1, 3075 }, + { 0x3166, 1, 3076 }, + { 0x3167, 1, 3077 }, + { 0x3168, 1, 3078 }, + { 0x3169, 1, 3079 }, + { 0x316a, 1, 3080 }, + { 0x316b, 1, 3081 }, + { 0x316c, 1, 3082 }, + { 0x316d, 1, 3083 }, + { 0x316e, 1, 3084 }, + { 0x316f, 1, 3085 }, + { 0x3170, 1, 3086 }, + { 0x3171, 1, 3087 }, + { 0x3172, 1, 3088 }, + { 0x3173, 1, 3089 }, + { 0x3174, 1, 3090 }, + { 0x3175, 1, 3091 }, + { 0x3176, 1, 3092 }, + { 0x3177, 1, 3093 }, + { 0x3178, 1, 3094 }, + { 0x3179, 1, 3095 }, + { 0x317a, 1, 3096 }, + { 0x317b, 1, 3097 }, + { 0x317c, 1, 3098 }, + { 0x317d, 1, 3099 }, + { 0x317e, 1, 3100 }, + { 0x317f, 1, 3101 }, + { 0x3180, 1, 3102 }, + { 0x3181, 1, 3103 }, + { 0x3182, 1, 3104 }, + { 0x3183, 1, 3105 }, + { 0x3184, 1, 3106 }, + { 0x3185, 1, 3107 }, + { 0x3186, 1, 3108 }, + { 0x3187, 1, 3109 }, + { 0x3188, 1, 3110 }, + { 0x3189, 1, 3111 }, + { 0x318a, 1, 3112 }, + { 0x318b, 1, 3113 }, + { 0x318c, 1, 3114 }, + { 0x318d, 1, 3115 }, + { 0x318e, 1, 3116 }, + { 0x3192, 1, 2682 }, + { 0x3193, 1, 2688 }, + { 0x3194, 1, 3117 }, + { 0x3195, 1, 3118 }, + { 0x3196, 1, 3119 }, + { 0x3197, 1, 3120 }, + { 0x3198, 1, 3121 }, + { 0x3199, 1, 3122 }, + { 0x319a, 1, 2686 }, + { 0x319b, 1, 3123 }, + { 0x319c, 1, 3124 }, + { 0x319d, 1, 3125 }, + { 0x319e, 1, 3126 }, + { 0x319f, 1, 2690 }, + { 0x3200, 3, 3127 }, + { 0x3201, 3, 3130 }, + { 0x3202, 3, 3133 }, + { 0x3203, 3, 3136 }, + { 0x3204, 3, 3139 }, + { 0x3205, 3, 3142 }, + { 0x3206, 3, 3145 }, + { 0x3207, 3, 3148 }, + { 0x3208, 3, 3151 }, + { 0x3209, 3, 3154 }, + { 0x320a, 3, 3157 }, + { 0x320b, 3, 3160 }, + { 0x320c, 3, 3163 }, + { 0x320d, 3, 3166 }, + { 0x320e, 4, 3169 }, + { 0x320f, 4, 3173 }, + { 0x3210, 4, 3177 }, + { 0x3211, 4, 3181 }, + { 0x3212, 4, 3185 }, + { 0x3213, 4, 3189 }, + { 0x3214, 4, 3193 }, + { 0x3215, 4, 3197 }, + { 0x3216, 4, 3201 }, + { 0x3217, 4, 3205 }, + { 0x3218, 4, 3209 }, + { 0x3219, 4, 3213 }, + { 0x321a, 4, 3217 }, + { 0x321b, 4, 3221 }, + { 0x321c, 4, 3225 }, + { 0x3220, 3, 3229 }, + { 0x3221, 3, 3232 }, + { 0x3222, 3, 3235 }, + { 0x3223, 3, 3238 }, + { 0x3224, 3, 3241 }, + { 0x3225, 3, 3244 }, + { 0x3226, 3, 3247 }, + { 0x3227, 3, 3250 }, + { 0x3228, 3, 3253 }, + { 0x3229, 3, 3256 }, + { 0x322a, 3, 3259 }, + { 0x322b, 3, 3262 }, + { 0x322c, 3, 3265 }, + { 0x322d, 3, 3268 }, + { 0x322e, 3, 3271 }, + { 0x322f, 3, 3274 }, + { 0x3230, 3, 3277 }, + { 0x3231, 3, 3280 }, + { 0x3232, 3, 3283 }, + { 0x3233, 3, 3286 }, + { 0x3234, 3, 3289 }, + { 0x3235, 3, 3292 }, + { 0x3236, 3, 3295 }, + { 0x3237, 3, 3298 }, + { 0x3238, 3, 3301 }, + { 0x3239, 3, 3304 }, + { 0x323a, 3, 3307 }, + { 0x323b, 3, 3310 }, + { 0x323c, 3, 3313 }, + { 0x323d, 3, 3316 }, + { 0x323e, 3, 3319 }, + { 0x323f, 3, 3322 }, + { 0x3240, 3, 3325 }, + { 0x3241, 3, 3328 }, + { 0x3242, 3, 3331 }, + { 0x3243, 3, 3334 }, + { 0x3251, 2, 3337 }, + { 0x3252, 2, 3339 }, + { 0x3253, 2, 3341 }, + { 0x3254, 2, 3343 }, + { 0x3255, 2, 3345 }, + { 0x3256, 2, 3347 }, + { 0x3257, 2, 3349 }, + { 0x3258, 2, 3351 }, + { 0x3259, 2, 3353 }, + { 0x325a, 2, 3355 }, + { 0x325b, 2, 3357 }, + { 0x325c, 2, 3359 }, + { 0x325d, 2, 3361 }, + { 0x325e, 2, 3363 }, + { 0x325f, 2, 3365 }, + { 0x3260, 1, 3023 }, + { 0x3261, 1, 3026 }, + { 0x3262, 1, 3029 }, + { 0x3263, 1, 3031 }, + { 0x3264, 1, 3039 }, + { 0x3265, 1, 3040 }, + { 0x3266, 1, 3043 }, + { 0x3267, 1, 3045 }, + { 0x3268, 1, 3046 }, + { 0x3269, 1, 3048 }, + { 0x326a, 1, 3049 }, + { 0x326b, 1, 3050 }, + { 0x326c, 1, 3051 }, + { 0x326d, 1, 3052 }, + { 0x326e, 2, 3367 }, + { 0x326f, 2, 3369 }, + { 0x3270, 2, 3371 }, + { 0x3271, 2, 3373 }, + { 0x3272, 2, 3375 }, + { 0x3273, 2, 3377 }, + { 0x3274, 2, 3379 }, + { 0x3275, 2, 3381 }, + { 0x3276, 2, 3383 }, + { 0x3277, 2, 3385 }, + { 0x3278, 2, 3387 }, + { 0x3279, 2, 3389 }, + { 0x327a, 2, 3391 }, + { 0x327b, 2, 3393 }, + { 0x3280, 1, 2682 }, + { 0x3281, 1, 2688 }, + { 0x3282, 1, 3117 }, + { 0x3283, 1, 3118 }, + { 0x3284, 1, 3395 }, + { 0x3285, 1, 3396 }, + { 0x3286, 1, 3397 }, + { 0x3287, 1, 2693 }, + { 0x3288, 1, 3398 }, + { 0x3289, 1, 2705 }, + { 0x328a, 1, 2755 }, + { 0x328b, 1, 2767 }, + { 0x328c, 1, 2766 }, + { 0x328d, 1, 2756 }, + { 0x328e, 1, 2848 }, + { 0x328f, 1, 2713 }, + { 0x3290, 1, 2753 }, + { 0x3291, 1, 3399 }, + { 0x3292, 1, 3400 }, + { 0x3293, 1, 3401 }, + { 0x3294, 1, 3402 }, + { 0x3295, 1, 3403 }, + { 0x3296, 1, 3404 }, + { 0x3297, 1, 3405 }, + { 0x3298, 1, 3406 }, + { 0x3299, 1, 3407 }, + { 0x329a, 1, 3408 }, + { 0x329b, 1, 2719 }, + { 0x329c, 1, 3409 }, + { 0x329d, 1, 3410 }, + { 0x329e, 1, 3411 }, + { 0x329f, 1, 3412 }, + { 0x32a0, 1, 3413 }, + { 0x32a1, 1, 3414 }, + { 0x32a2, 1, 3415 }, + { 0x32a3, 1, 3416 }, + { 0x32a4, 1, 3119 }, + { 0x32a5, 1, 3120 }, + { 0x32a6, 1, 3121 }, + { 0x32a7, 1, 3417 }, + { 0x32a8, 1, 3418 }, + { 0x32a9, 1, 3419 }, + { 0x32aa, 1, 3420 }, + { 0x32ab, 1, 3421 }, + { 0x32ac, 1, 3422 }, + { 0x32ad, 1, 3423 }, + { 0x32ae, 1, 3424 }, + { 0x32af, 1, 3425 }, + { 0x32b0, 1, 3426 }, + { 0x32b1, 2, 3427 }, + { 0x32b2, 2, 3429 }, + { 0x32b3, 2, 3431 }, + { 0x32b4, 2, 3433 }, + { 0x32b5, 2, 3435 }, + { 0x32b6, 2, 3437 }, + { 0x32b7, 2, 3439 }, + { 0x32b8, 2, 3441 }, + { 0x32b9, 2, 3443 }, + { 0x32ba, 2, 3445 }, + { 0x32bb, 2, 3447 }, + { 0x32bc, 2, 3449 }, + { 0x32bd, 2, 3451 }, + { 0x32be, 2, 3453 }, + { 0x32bf, 2, 3455 }, + { 0x32c0, 2, 3457 }, + { 0x32c1, 2, 3459 }, + { 0x32c2, 2, 3461 }, + { 0x32c3, 2, 3463 }, + { 0x32c4, 2, 3465 }, + { 0x32c5, 2, 3467 }, + { 0x32c6, 2, 3469 }, + { 0x32c7, 2, 3471 }, + { 0x32c8, 2, 3473 }, + { 0x32c9, 3, 3475 }, + { 0x32ca, 3, 3478 }, + { 0x32cb, 3, 3481 }, + { 0x32d0, 1, 3484 }, + { 0x32d1, 1, 3485 }, + { 0x32d2, 1, 3486 }, + { 0x32d3, 1, 3487 }, + { 0x32d4, 1, 3488 }, + { 0x32d5, 1, 3489 }, + { 0x32d6, 1, 3490 }, + { 0x32d7, 1, 3491 }, + { 0x32d8, 1, 3492 }, + { 0x32d9, 1, 3493 }, + { 0x32da, 1, 3494 }, + { 0x32db, 1, 3495 }, + { 0x32dc, 1, 3496 }, + { 0x32dd, 1, 3497 }, + { 0x32de, 1, 3498 }, + { 0x32df, 1, 3499 }, + { 0x32e0, 1, 3500 }, + { 0x32e1, 1, 3501 }, + { 0x32e2, 1, 3502 }, + { 0x32e3, 1, 3503 }, + { 0x32e4, 1, 3504 }, + { 0x32e5, 1, 3505 }, + { 0x32e6, 1, 3506 }, + { 0x32e7, 1, 3507 }, + { 0x32e8, 1, 3508 }, + { 0x32e9, 1, 3509 }, + { 0x32ea, 1, 3510 }, + { 0x32eb, 1, 3511 }, + { 0x32ec, 1, 3512 }, + { 0x32ed, 1, 3513 }, + { 0x32ee, 1, 3514 }, + { 0x32ef, 1, 3515 }, + { 0x32f0, 1, 3516 }, + { 0x32f1, 1, 3517 }, + { 0x32f2, 1, 3518 }, + { 0x32f3, 1, 3519 }, + { 0x32f4, 1, 3520 }, + { 0x32f5, 1, 3521 }, + { 0x32f6, 1, 3522 }, + { 0x32f7, 1, 3523 }, + { 0x32f8, 1, 3524 }, + { 0x32f9, 1, 3525 }, + { 0x32fa, 1, 3526 }, + { 0x32fb, 1, 3527 }, + { 0x32fc, 1, 3528 }, + { 0x32fd, 1, 3529 }, + { 0x32fe, 1, 3530 }, + { 0x3300, 5, 3531 }, + { 0x3301, 4, 3536 }, + { 0x3302, 5, 3540 }, + { 0x3303, 3, 3545 }, + { 0x3304, 5, 3548 }, + { 0x3305, 3, 3553 }, + { 0x3306, 3, 3556 }, + { 0x3307, 6, 3559 }, + { 0x3308, 4, 3565 }, + { 0x3309, 3, 3569 }, + { 0x330a, 3, 3572 }, + { 0x330b, 3, 3575 }, + { 0x330c, 4, 3578 }, + { 0x330d, 4, 3582 }, + { 0x330e, 4, 3586 }, + { 0x330f, 4, 3590 }, + { 0x3310, 4, 3594 }, + { 0x3311, 4, 3598 }, + { 0x3312, 4, 3602 }, + { 0x3313, 6, 3606 }, + { 0x3314, 2, 3612 }, + { 0x3315, 6, 3614 }, + { 0x3316, 6, 3620 }, + { 0x3317, 5, 3626 }, + { 0x3318, 4, 3631 }, + { 0x3319, 6, 3635 }, + { 0x331a, 6, 3641 }, + { 0x331b, 4, 3647 }, + { 0x331c, 3, 3651 }, + { 0x331d, 3, 3654 }, + { 0x331e, 4, 3657 }, + { 0x331f, 4, 3661 }, + { 0x3320, 5, 3665 }, + { 0x3321, 5, 3670 }, + { 0x3322, 3, 3675 }, + { 0x3323, 3, 3678 }, + { 0x3324, 4, 3681 }, + { 0x3325, 3, 3685 }, + { 0x3326, 3, 3688 }, + { 0x3327, 2, 3691 }, + { 0x3328, 2, 3693 }, + { 0x3329, 3, 3695 }, + { 0x332a, 3, 3698 }, + { 0x332b, 6, 3701 }, + { 0x332c, 4, 3707 }, + { 0x332d, 5, 3711 }, + { 0x332e, 6, 3716 }, + { 0x332f, 4, 3722 }, + { 0x3330, 3, 3726 }, + { 0x3331, 3, 3729 }, + { 0x3332, 6, 3732 }, + { 0x3333, 4, 3738 }, + { 0x3334, 6, 3742 }, + { 0x3335, 3, 3748 }, + { 0x3336, 5, 3751 }, + { 0x3337, 3, 3756 }, + { 0x3338, 4, 3759 }, + { 0x3339, 3, 3763 }, + { 0x333a, 4, 3766 }, + { 0x333b, 5, 3770 }, + { 0x333c, 4, 3775 }, + { 0x333d, 5, 3779 }, + { 0x333e, 4, 3784 }, + { 0x333f, 2, 3788 }, + { 0x3340, 5, 3790 }, + { 0x3341, 3, 3795 }, + { 0x3342, 3, 3798 }, + { 0x3343, 4, 3801 }, + { 0x3344, 3, 3805 }, + { 0x3345, 3, 3808 }, + { 0x3346, 3, 3811 }, + { 0x3347, 5, 3814 }, + { 0x3348, 4, 3819 }, + { 0x3349, 2, 3823 }, + { 0x334a, 6, 3825 }, + { 0x334b, 3, 3831 }, + { 0x334c, 5, 3834 }, + { 0x334d, 4, 3839 }, + { 0x334e, 4, 3843 }, + { 0x334f, 3, 3847 }, + { 0x3350, 3, 3850 }, + { 0x3351, 4, 3853 }, + { 0x3352, 2, 3857 }, + { 0x3353, 4, 3859 }, + { 0x3354, 5, 3863 }, + { 0x3355, 2, 3868 }, + { 0x3356, 6, 3870 }, + { 0x3357, 3, 3876 }, + { 0x3358, 2, 3879 }, + { 0x3359, 2, 3881 }, + { 0x335a, 2, 3883 }, + { 0x335b, 2, 3885 }, + { 0x335c, 2, 3887 }, + { 0x335d, 2, 3889 }, + { 0x335e, 2, 3891 }, + { 0x335f, 2, 3893 }, + { 0x3360, 2, 3895 }, + { 0x3361, 2, 3897 }, + { 0x3362, 3, 3899 }, + { 0x3363, 3, 3902 }, + { 0x3364, 3, 3905 }, + { 0x3365, 3, 3908 }, + { 0x3366, 3, 3911 }, + { 0x3367, 3, 3914 }, + { 0x3368, 3, 3917 }, + { 0x3369, 3, 3920 }, + { 0x336a, 3, 3923 }, + { 0x336b, 3, 3926 }, + { 0x336c, 3, 3929 }, + { 0x336d, 3, 3932 }, + { 0x336e, 3, 3935 }, + { 0x336f, 3, 3938 }, + { 0x3370, 3, 3941 }, + { 0x3371, 3, 3944 }, + { 0x3372, 2, 3947 }, + { 0x3373, 2, 3949 }, + { 0x3374, 3, 3951 }, + { 0x3375, 2, 3954 }, + { 0x3376, 2, 3956 }, + { 0x337b, 2, 3958 }, + { 0x337c, 2, 3960 }, + { 0x337d, 2, 3962 }, + { 0x337e, 2, 3964 }, + { 0x337f, 4, 3966 }, + { 0x3380, 2, 3970 }, + { 0x3381, 2, 3972 }, + { 0x3382, 2, 3974 }, + { 0x3383, 2, 3976 }, + { 0x3384, 2, 3978 }, + { 0x3385, 2, 3980 }, + { 0x3386, 2, 3982 }, + { 0x3387, 2, 3984 }, + { 0x3388, 3, 3986 }, + { 0x3389, 4, 3989 }, + { 0x338a, 2, 3993 }, + { 0x338b, 2, 3995 }, + { 0x338c, 2, 3997 }, + { 0x338d, 2, 3999 }, + { 0x338e, 2, 4001 }, + { 0x338f, 2, 4003 }, + { 0x3390, 2, 4005 }, + { 0x3391, 3, 4007 }, + { 0x3392, 3, 4010 }, + { 0x3393, 3, 4013 }, + { 0x3394, 3, 4016 }, + { 0x3395, 2, 4019 }, + { 0x3396, 2, 4021 }, + { 0x3397, 2, 4023 }, + { 0x3398, 2, 4025 }, + { 0x3399, 2, 4027 }, + { 0x339a, 2, 4029 }, + { 0x339b, 2, 4031 }, + { 0x339c, 2, 4033 }, + { 0x339d, 2, 4035 }, + { 0x339e, 2, 4037 }, + { 0x339f, 3, 4039 }, + { 0x33a0, 3, 4042 }, + { 0x33a1, 2, 4045 }, + { 0x33a2, 3, 4047 }, + { 0x33a3, 3, 4050 }, + { 0x33a4, 3, 4053 }, + { 0x33a5, 2, 4056 }, + { 0x33a6, 3, 4058 }, + { 0x33a7, 3, 4061 }, + { 0x33a8, 4, 4064 }, + { 0x33a9, 2, 4068 }, + { 0x33aa, 3, 4070 }, + { 0x33ab, 3, 4073 }, + { 0x33ac, 3, 4076 }, + { 0x33ad, 3, 4079 }, + { 0x33ae, 5, 4082 }, + { 0x33af, 6, 4087 }, + { 0x33b0, 2, 4093 }, + { 0x33b1, 2, 4095 }, + { 0x33b2, 2, 4097 }, + { 0x33b3, 2, 4099 }, + { 0x33b4, 2, 4101 }, + { 0x33b5, 2, 4103 }, + { 0x33b6, 2, 4105 }, + { 0x33b7, 2, 4107 }, + { 0x33b8, 2, 4109 }, + { 0x33b9, 2, 4111 }, + { 0x33ba, 2, 4113 }, + { 0x33bb, 2, 4115 }, + { 0x33bc, 2, 4117 }, + { 0x33bd, 2, 4119 }, + { 0x33be, 2, 4121 }, + { 0x33bf, 2, 4123 }, + { 0x33c0, 2, 4125 }, + { 0x33c1, 2, 4127 }, + { 0x33c2, 4, 4129 }, + { 0x33c3, 2, 4133 }, + { 0x33c4, 2, 4135 }, + { 0x33c5, 2, 4137 }, + { 0x33c6, 4, 4139 }, + { 0x33c7, 3, 4143 }, + { 0x33c8, 2, 4146 }, + { 0x33c9, 2, 4148 }, + { 0x33ca, 2, 4150 }, + { 0x33cb, 2, 4152 }, + { 0x33cc, 2, 4154 }, + { 0x33cd, 2, 4156 }, + { 0x33ce, 2, 4158 }, + { 0x33cf, 2, 4160 }, + { 0x33d0, 2, 4162 }, + { 0x33d1, 2, 4164 }, + { 0x33d2, 3, 4166 }, + { 0x33d3, 2, 4169 }, + { 0x33d4, 2, 4171 }, + { 0x33d5, 3, 4173 }, + { 0x33d6, 3, 4176 }, + { 0x33d7, 2, 4179 }, + { 0x33d8, 4, 4181 }, + { 0x33d9, 3, 4185 }, + { 0x33da, 2, 4188 }, + { 0x33db, 2, 4190 }, + { 0x33dc, 2, 4192 }, + { 0x33dd, 2, 4194 }, + { 0x33e0, 2, 4196 }, + { 0x33e1, 2, 4198 }, + { 0x33e2, 2, 4200 }, + { 0x33e3, 2, 4202 }, + { 0x33e4, 2, 4204 }, + { 0x33e5, 2, 4206 }, + { 0x33e6, 2, 4208 }, + { 0x33e7, 2, 4210 }, + { 0x33e8, 2, 4212 }, + { 0x33e9, 3, 4214 }, + { 0x33ea, 3, 4217 }, + { 0x33eb, 3, 4220 }, + { 0x33ec, 3, 4223 }, + { 0x33ed, 3, 4226 }, + { 0x33ee, 3, 4229 }, + { 0x33ef, 3, 4232 }, + { 0x33f0, 3, 4235 }, + { 0x33f1, 3, 4238 }, + { 0x33f2, 3, 4241 }, + { 0x33f3, 3, 4244 }, + { 0x33f4, 3, 4247 }, + { 0x33f5, 3, 4250 }, + { 0x33f6, 3, 4253 }, + { 0x33f7, 3, 4256 }, + { 0x33f8, 3, 4259 }, + { 0x33f9, 3, 4262 }, + { 0x33fa, 3, 4265 }, + { 0x33fb, 3, 4268 }, + { 0x33fc, 3, 4271 }, + { 0x33fd, 3, 4274 }, + { 0x33fe, 3, 4277 }, + { 0xf900, 1, 4280 }, + { 0xf901, 1, 4281 }, + { 0xf902, 1, 2840 }, + { 0xf903, 1, 4282 }, + { 0xf904, 1, 4283 }, + { 0xf905, 1, 4284 }, + { 0xf906, 1, 4285 }, + { 0xf907, 1, 2894 }, + { 0xf908, 1, 2894 }, + { 0xf909, 1, 4286 }, + { 0xf90a, 1, 2848 }, + { 0xf90b, 1, 4287 }, + { 0xf90c, 1, 4288 }, + { 0xf90d, 1, 4289 }, + { 0xf90e, 1, 4290 }, + { 0xf90f, 1, 4291 }, + { 0xf910, 1, 4292 }, + { 0xf911, 1, 4293 }, + { 0xf912, 1, 4294 }, + { 0xf913, 1, 4295 }, + { 0xf914, 1, 4296 }, + { 0xf915, 1, 4297 }, + { 0xf916, 1, 4298 }, + { 0xf917, 1, 4299 }, + { 0xf918, 1, 4300 }, + { 0xf919, 1, 4301 }, + { 0xf91a, 1, 4302 }, + { 0xf91b, 1, 4303 }, + { 0xf91c, 1, 4304 }, + { 0xf91d, 1, 4305 }, + { 0xf91e, 1, 4306 }, + { 0xf91f, 1, 4307 }, + { 0xf920, 1, 4308 }, + { 0xf921, 1, 4309 }, + { 0xf922, 1, 4310 }, + { 0xf923, 1, 4311 }, + { 0xf924, 1, 4312 }, + { 0xf925, 1, 4313 }, + { 0xf926, 1, 4314 }, + { 0xf927, 1, 4315 }, + { 0xf928, 1, 4316 }, + { 0xf929, 1, 4317 }, + { 0xf92a, 1, 4318 }, + { 0xf92b, 1, 4319 }, + { 0xf92c, 1, 4320 }, + { 0xf92d, 1, 4321 }, + { 0xf92e, 1, 4322 }, + { 0xf92f, 1, 4323 }, + { 0xf930, 1, 4324 }, + { 0xf931, 1, 4325 }, + { 0xf932, 1, 4326 }, + { 0xf933, 1, 4327 }, + { 0xf934, 1, 2806 }, + { 0xf935, 1, 4328 }, + { 0xf936, 1, 4329 }, + { 0xf937, 1, 4330 }, + { 0xf938, 1, 4331 }, + { 0xf939, 1, 4332 }, + { 0xf93a, 1, 4333 }, + { 0xf93b, 1, 4334 }, + { 0xf93c, 1, 4335 }, + { 0xf93d, 1, 4336 }, + { 0xf93e, 1, 4337 }, + { 0xf93f, 1, 4338 }, + { 0xf940, 1, 2879 }, + { 0xf941, 1, 4339 }, + { 0xf942, 1, 4340 }, + { 0xf943, 1, 4341 }, + { 0xf944, 1, 4342 }, + { 0xf945, 1, 4343 }, + { 0xf946, 1, 4344 }, + { 0xf947, 1, 4345 }, + { 0xf948, 1, 4346 }, + { 0xf949, 1, 4347 }, + { 0xf94a, 1, 4348 }, + { 0xf94b, 1, 4349 }, + { 0xf94c, 1, 4350 }, + { 0xf94d, 1, 4351 }, + { 0xf94e, 1, 4352 }, + { 0xf94f, 1, 4353 }, + { 0xf950, 1, 4354 }, + { 0xf951, 1, 4355 }, + { 0xf952, 1, 4356 }, + { 0xf953, 1, 4357 }, + { 0xf954, 1, 4358 }, + { 0xf955, 1, 4359 }, + { 0xf956, 1, 4360 }, + { 0xf957, 1, 4361 }, + { 0xf958, 1, 4362 }, + { 0xf959, 1, 4363 }, + { 0xf95a, 1, 4364 }, + { 0xf95b, 1, 4365 }, + { 0xf95c, 1, 4296 }, + { 0xf95d, 1, 4366 }, + { 0xf95e, 1, 4367 }, + { 0xf95f, 1, 4368 }, + { 0xf960, 1, 4369 }, + { 0xf961, 1, 4370 }, + { 0xf962, 1, 4371 }, + { 0xf963, 1, 4372 }, + { 0xf964, 1, 4373 }, + { 0xf965, 1, 4374 }, + { 0xf966, 1, 4375 }, + { 0xf967, 1, 4376 }, + { 0xf968, 1, 4377 }, + { 0xf969, 1, 4378 }, + { 0xf96a, 1, 4379 }, + { 0xf96b, 1, 4380 }, + { 0xf96c, 1, 4381 }, + { 0xf96d, 1, 4382 }, + { 0xf96e, 1, 4383 }, + { 0xf96f, 1, 4384 }, + { 0xf970, 1, 4385 }, + { 0xf971, 1, 2842 }, + { 0xf972, 1, 4386 }, + { 0xf973, 1, 4387 }, + { 0xf974, 1, 4388 }, + { 0xf975, 1, 4389 }, + { 0xf976, 1, 4390 }, + { 0xf977, 1, 4391 }, + { 0xf978, 1, 4392 }, + { 0xf979, 1, 4393 }, + { 0xf97a, 1, 4394 }, + { 0xf97b, 1, 4395 }, + { 0xf97c, 1, 4396 }, + { 0xf97d, 1, 4397 }, + { 0xf97e, 1, 4398 }, + { 0xf97f, 1, 4399 }, + { 0xf980, 1, 4400 }, + { 0xf981, 1, 2719 }, + { 0xf982, 1, 4401 }, + { 0xf983, 1, 4402 }, + { 0xf984, 1, 4403 }, + { 0xf985, 1, 4404 }, + { 0xf986, 1, 4405 }, + { 0xf987, 1, 4406 }, + { 0xf988, 1, 4407 }, + { 0xf989, 1, 4408 }, + { 0xf98a, 1, 2700 }, + { 0xf98b, 1, 4409 }, + { 0xf98c, 1, 4410 }, + { 0xf98d, 1, 4411 }, + { 0xf98e, 1, 4412 }, + { 0xf98f, 1, 4413 }, + { 0xf990, 1, 4414 }, + { 0xf991, 1, 4415 }, + { 0xf992, 1, 4416 }, + { 0xf993, 1, 4417 }, + { 0xf994, 1, 4418 }, + { 0xf995, 1, 4419 }, + { 0xf996, 1, 4420 }, + { 0xf997, 1, 4421 }, + { 0xf998, 1, 4422 }, + { 0xf999, 1, 4423 }, + { 0xf99a, 1, 4424 }, + { 0xf99b, 1, 4425 }, + { 0xf99c, 1, 4426 }, + { 0xf99d, 1, 4427 }, + { 0xf99e, 1, 4428 }, + { 0xf99f, 1, 4429 }, + { 0xf9a0, 1, 4430 }, + { 0xf9a1, 1, 4384 }, + { 0xf9a2, 1, 4431 }, + { 0xf9a3, 1, 4432 }, + { 0xf9a4, 1, 4433 }, + { 0xf9a5, 1, 4434 }, + { 0xf9a6, 1, 4435 }, + { 0xf9a7, 1, 4436 }, + { 0xf9a8, 1, 4437 }, + { 0xf9a9, 1, 4438 }, + { 0xf9aa, 1, 4368 }, + { 0xf9ab, 1, 4439 }, + { 0xf9ac, 1, 4440 }, + { 0xf9ad, 1, 4441 }, + { 0xf9ae, 1, 4442 }, + { 0xf9af, 1, 4443 }, + { 0xf9b0, 1, 4444 }, + { 0xf9b1, 1, 4445 }, + { 0xf9b2, 1, 4446 }, + { 0xf9b3, 1, 4447 }, + { 0xf9b4, 1, 4448 }, + { 0xf9b5, 1, 4449 }, + { 0xf9b6, 1, 4450 }, + { 0xf9b7, 1, 4451 }, + { 0xf9b8, 1, 4452 }, + { 0xf9b9, 1, 4453 }, + { 0xf9ba, 1, 4454 }, + { 0xf9bb, 1, 4455 }, + { 0xf9bc, 1, 4456 }, + { 0xf9bd, 1, 4457 }, + { 0xf9be, 1, 4458 }, + { 0xf9bf, 1, 4296 }, + { 0xf9c0, 1, 4459 }, + { 0xf9c1, 1, 4460 }, + { 0xf9c2, 1, 4461 }, + { 0xf9c3, 1, 4462 }, + { 0xf9c4, 1, 2893 }, + { 0xf9c5, 1, 4463 }, + { 0xf9c6, 1, 4464 }, + { 0xf9c7, 1, 4465 }, + { 0xf9c8, 1, 4466 }, + { 0xf9c9, 1, 4467 }, + { 0xf9ca, 1, 4468 }, + { 0xf9cb, 1, 4469 }, + { 0xf9cc, 1, 4470 }, + { 0xf9cd, 1, 4471 }, + { 0xf9ce, 1, 4472 }, + { 0xf9cf, 1, 4473 }, + { 0xf9d0, 1, 4474 }, + { 0xf9d1, 1, 3396 }, + { 0xf9d2, 1, 4475 }, + { 0xf9d3, 1, 4476 }, + { 0xf9d4, 1, 4477 }, + { 0xf9d5, 1, 4478 }, + { 0xf9d6, 1, 4479 }, + { 0xf9d7, 1, 4480 }, + { 0xf9d8, 1, 4481 }, + { 0xf9d9, 1, 4482 }, + { 0xf9da, 1, 4483 }, + { 0xf9db, 1, 4370 }, + { 0xf9dc, 1, 4484 }, + { 0xf9dd, 1, 4485 }, + { 0xf9de, 1, 4486 }, + { 0xf9df, 1, 4487 }, + { 0xf9e0, 1, 4488 }, + { 0xf9e1, 1, 4489 }, + { 0xf9e2, 1, 4490 }, + { 0xf9e3, 1, 4491 }, + { 0xf9e4, 1, 4492 }, + { 0xf9e5, 1, 4493 }, + { 0xf9e6, 1, 4494 }, + { 0xf9e7, 1, 4495 }, + { 0xf9e8, 1, 4496 }, + { 0xf9e9, 1, 2847 }, + { 0xf9ea, 1, 4497 }, + { 0xf9eb, 1, 4498 }, + { 0xf9ec, 1, 4499 }, + { 0xf9ed, 1, 4500 }, + { 0xf9ee, 1, 4501 }, + { 0xf9ef, 1, 4502 }, + { 0xf9f0, 1, 4503 }, + { 0xf9f1, 1, 4504 }, + { 0xf9f2, 1, 4505 }, + { 0xf9f3, 1, 4506 }, + { 0xf9f4, 1, 4507 }, + { 0xf9f5, 1, 4508 }, + { 0xf9f6, 1, 4509 }, + { 0xf9f7, 1, 2798 }, + { 0xf9f8, 1, 4510 }, + { 0xf9f9, 1, 4511 }, + { 0xf9fa, 1, 4512 }, + { 0xf9fb, 1, 4513 }, + { 0xf9fc, 1, 4514 }, + { 0xf9fd, 1, 4515 }, + { 0xf9fe, 1, 4516 }, + { 0xf9ff, 1, 4517 }, + { 0xfa00, 1, 4518 }, + { 0xfa01, 1, 4519 }, + { 0xfa02, 1, 4520 }, + { 0xfa03, 1, 4521 }, + { 0xfa04, 1, 4522 }, + { 0xfa05, 1, 4523 }, + { 0xfa06, 1, 4524 }, + { 0xfa07, 1, 4525 }, + { 0xfa08, 1, 2825 }, + { 0xfa09, 1, 4526 }, + { 0xfa0a, 1, 2828 }, + { 0xfa0b, 1, 4527 }, + { 0xfa0c, 1, 4528 }, + { 0xfa0d, 1, 4529 }, + { 0xfa10, 1, 4530 }, + { 0xfa12, 1, 4531 }, + { 0xfa15, 1, 4532 }, + { 0xfa16, 1, 4533 }, + { 0xfa17, 1, 4534 }, + { 0xfa18, 1, 4535 }, + { 0xfa19, 1, 4536 }, + { 0xfa1a, 1, 4537 }, + { 0xfa1b, 1, 4538 }, + { 0xfa1c, 1, 4539 }, + { 0xfa1d, 1, 4540 }, + { 0xfa1e, 1, 2805 }, + { 0xfa20, 1, 4541 }, + { 0xfa22, 1, 4542 }, + { 0xfa25, 1, 4543 }, + { 0xfa26, 1, 4544 }, + { 0xfa2a, 1, 4545 }, + { 0xfa2b, 1, 4546 }, + { 0xfa2c, 1, 4547 }, + { 0xfa2d, 1, 4548 }, + { 0xfa30, 1, 4549 }, + { 0xfa31, 1, 4550 }, + { 0xfa32, 1, 4551 }, + { 0xfa33, 1, 4552 }, + { 0xfa34, 1, 4553 }, + { 0xfa35, 1, 4554 }, + { 0xfa36, 1, 4555 }, + { 0xfa37, 1, 4556 }, + { 0xfa38, 1, 4557 }, + { 0xfa39, 1, 4558 }, + { 0xfa3a, 1, 4559 }, + { 0xfa3b, 1, 4560 }, + { 0xfa3c, 1, 2726 }, + { 0xfa3d, 1, 4561 }, + { 0xfa3e, 1, 4562 }, + { 0xfa3f, 1, 4563 }, + { 0xfa40, 1, 4564 }, + { 0xfa41, 1, 4565 }, + { 0xfa42, 1, 4566 }, + { 0xfa43, 1, 4567 }, + { 0xfa44, 1, 4568 }, + { 0xfa45, 1, 4569 }, + { 0xfa46, 1, 4570 }, + { 0xfa47, 1, 4571 }, + { 0xfa48, 1, 4572 }, + { 0xfa49, 1, 4573 }, + { 0xfa4a, 1, 4574 }, + { 0xfa4b, 1, 4575 }, + { 0xfa4c, 1, 3401 }, + { 0xfa4d, 1, 4576 }, + { 0xfa4e, 1, 4577 }, + { 0xfa4f, 1, 4578 }, + { 0xfa50, 1, 4579 }, + { 0xfa51, 1, 3405 }, + { 0xfa52, 1, 4580 }, + { 0xfa53, 1, 4581 }, + { 0xfa54, 1, 4582 }, + { 0xfa55, 1, 4583 }, + { 0xfa56, 1, 4584 }, + { 0xfa57, 1, 4420 }, + { 0xfa58, 1, 4585 }, + { 0xfa59, 1, 4586 }, + { 0xfa5a, 1, 4587 }, + { 0xfa5b, 1, 4588 }, + { 0xfa5c, 1, 4589 }, + { 0xfa5d, 1, 4590 }, + { 0xfa5e, 1, 4590 }, + { 0xfa5f, 1, 4591 }, + { 0xfa60, 1, 4592 }, + { 0xfa61, 1, 4593 }, + { 0xfa62, 1, 4594 }, + { 0xfa63, 1, 4595 }, + { 0xfa64, 1, 4596 }, + { 0xfa65, 1, 4597 }, + { 0xfa66, 1, 4598 }, + { 0xfa67, 1, 4543 }, + { 0xfa68, 1, 4599 }, + { 0xfa69, 1, 4600 }, + { 0xfa6a, 1, 4601 }, + { 0xfb00, 2, 4602 }, + { 0xfb01, 2, 4604 }, + { 0xfb02, 2, 4606 }, + { 0xfb03, 3, 4608 }, + { 0xfb04, 3, 4611 }, + { 0xfb05, 2, 4614 }, + { 0xfb06, 2, 4614 }, + { 0xfb13, 2, 4616 }, + { 0xfb14, 2, 4618 }, + { 0xfb15, 2, 4620 }, + { 0xfb16, 2, 4622 }, + { 0xfb17, 2, 4624 }, + { 0xfb1d, 2, 4626 }, + { 0xfb1f, 2, 4628 }, + { 0xfb20, 1, 4630 }, + { 0xfb21, 1, 2228 }, + { 0xfb22, 1, 2231 }, + { 0xfb23, 1, 4631 }, + { 0xfb24, 1, 4632 }, + { 0xfb25, 1, 4633 }, + { 0xfb26, 1, 4634 }, + { 0xfb27, 1, 4635 }, + { 0xfb28, 1, 4636 }, + { 0xfb29, 1, 2176 }, + { 0xfb2a, 2, 4637 }, + { 0xfb2b, 2, 4639 }, + { 0xfb2c, 3, 4641 }, + { 0xfb2d, 3, 4644 }, + { 0xfb2e, 2, 4647 }, + { 0xfb2f, 2, 4649 }, + { 0xfb30, 2, 4651 }, + { 0xfb31, 2, 4653 }, + { 0xfb32, 2, 4655 }, + { 0xfb33, 2, 4657 }, + { 0xfb34, 2, 4659 }, + { 0xfb35, 2, 4661 }, + { 0xfb36, 2, 4663 }, + { 0xfb38, 2, 4665 }, + { 0xfb39, 2, 4667 }, + { 0xfb3a, 2, 4669 }, + { 0xfb3b, 2, 4671 }, + { 0xfb3c, 2, 4673 }, + { 0xfb3e, 2, 4675 }, + { 0xfb40, 2, 4677 }, + { 0xfb41, 2, 4679 }, + { 0xfb43, 2, 4681 }, + { 0xfb44, 2, 4683 }, + { 0xfb46, 2, 4685 }, + { 0xfb47, 2, 4687 }, + { 0xfb48, 2, 4689 }, + { 0xfb49, 2, 4691 }, + { 0xfb4a, 2, 4693 }, + { 0xfb4b, 2, 4695 }, + { 0xfb4c, 2, 4697 }, + { 0xfb4d, 2, 4699 }, + { 0xfb4e, 2, 4701 }, + { 0xfb4f, 2, 4703 }, + { 0xfb50, 1, 4705 }, + { 0xfb51, 1, 4705 }, + { 0xfb52, 1, 4706 }, + { 0xfb53, 1, 4706 }, + { 0xfb54, 1, 4706 }, + { 0xfb55, 1, 4706 }, + { 0xfb56, 1, 4707 }, + { 0xfb57, 1, 4707 }, + { 0xfb58, 1, 4707 }, + { 0xfb59, 1, 4707 }, + { 0xfb5a, 1, 4708 }, + { 0xfb5b, 1, 4708 }, + { 0xfb5c, 1, 4708 }, + { 0xfb5d, 1, 4708 }, + { 0xfb5e, 1, 4709 }, + { 0xfb5f, 1, 4709 }, + { 0xfb60, 1, 4709 }, + { 0xfb61, 1, 4709 }, + { 0xfb62, 1, 4710 }, + { 0xfb63, 1, 4710 }, + { 0xfb64, 1, 4710 }, + { 0xfb65, 1, 4710 }, + { 0xfb66, 1, 4711 }, + { 0xfb67, 1, 4711 }, + { 0xfb68, 1, 4711 }, + { 0xfb69, 1, 4711 }, + { 0xfb6a, 1, 4712 }, + { 0xfb6b, 1, 4712 }, + { 0xfb6c, 1, 4712 }, + { 0xfb6d, 1, 4712 }, + { 0xfb6e, 1, 4713 }, + { 0xfb6f, 1, 4713 }, + { 0xfb70, 1, 4713 }, + { 0xfb71, 1, 4713 }, + { 0xfb72, 1, 4714 }, + { 0xfb73, 1, 4714 }, + { 0xfb74, 1, 4714 }, + { 0xfb75, 1, 4714 }, + { 0xfb76, 1, 4715 }, + { 0xfb77, 1, 4715 }, + { 0xfb78, 1, 4715 }, + { 0xfb79, 1, 4715 }, + { 0xfb7a, 1, 4716 }, + { 0xfb7b, 1, 4716 }, + { 0xfb7c, 1, 4716 }, + { 0xfb7d, 1, 4716 }, + { 0xfb7e, 1, 4717 }, + { 0xfb7f, 1, 4717 }, + { 0xfb80, 1, 4717 }, + { 0xfb81, 1, 4717 }, + { 0xfb82, 1, 4718 }, + { 0xfb83, 1, 4718 }, + { 0xfb84, 1, 4719 }, + { 0xfb85, 1, 4719 }, + { 0xfb86, 1, 4720 }, + { 0xfb87, 1, 4720 }, + { 0xfb88, 1, 4721 }, + { 0xfb89, 1, 4721 }, + { 0xfb8a, 1, 4722 }, + { 0xfb8b, 1, 4722 }, + { 0xfb8c, 1, 4723 }, + { 0xfb8d, 1, 4723 }, + { 0xfb8e, 1, 4724 }, + { 0xfb8f, 1, 4724 }, + { 0xfb90, 1, 4724 }, + { 0xfb91, 1, 4724 }, + { 0xfb92, 1, 4725 }, + { 0xfb93, 1, 4725 }, + { 0xfb94, 1, 4725 }, + { 0xfb95, 1, 4725 }, + { 0xfb96, 1, 4726 }, + { 0xfb97, 1, 4726 }, + { 0xfb98, 1, 4726 }, + { 0xfb99, 1, 4726 }, + { 0xfb9a, 1, 4727 }, + { 0xfb9b, 1, 4727 }, + { 0xfb9c, 1, 4727 }, + { 0xfb9d, 1, 4727 }, + { 0xfb9e, 1, 4728 }, + { 0xfb9f, 1, 4728 }, + { 0xfba0, 1, 4729 }, + { 0xfba1, 1, 4729 }, + { 0xfba2, 1, 4729 }, + { 0xfba3, 1, 4729 }, + { 0xfba4, 2, 802 }, + { 0xfba5, 2, 802 }, + { 0xfba6, 1, 4730 }, + { 0xfba7, 1, 4730 }, + { 0xfba8, 1, 4730 }, + { 0xfba9, 1, 4730 }, + { 0xfbaa, 1, 4731 }, + { 0xfbab, 1, 4731 }, + { 0xfbac, 1, 4731 }, + { 0xfbad, 1, 4731 }, + { 0xfbae, 1, 4732 }, + { 0xfbaf, 1, 4732 }, + { 0xfbb0, 2, 806 }, + { 0xfbb1, 2, 806 }, + { 0xfbd3, 1, 4733 }, + { 0xfbd4, 1, 4733 }, + { 0xfbd5, 1, 4733 }, + { 0xfbd6, 1, 4733 }, + { 0xfbd7, 1, 4734 }, + { 0xfbd8, 1, 4734 }, + { 0xfbd9, 1, 4735 }, + { 0xfbda, 1, 4735 }, + { 0xfbdb, 1, 4736 }, + { 0xfbdc, 1, 4736 }, + { 0xfbdd, 2, 798 }, + { 0xfbde, 1, 4737 }, + { 0xfbdf, 1, 4737 }, + { 0xfbe0, 1, 4738 }, + { 0xfbe1, 1, 4738 }, + { 0xfbe2, 1, 4739 }, + { 0xfbe3, 1, 4739 }, + { 0xfbe4, 1, 4740 }, + { 0xfbe5, 1, 4740 }, + { 0xfbe6, 1, 4740 }, + { 0xfbe7, 1, 4740 }, + { 0xfbe8, 1, 4741 }, + { 0xfbe9, 1, 4741 }, + { 0xfbea, 3, 4742 }, + { 0xfbeb, 3, 4742 }, + { 0xfbec, 3, 4745 }, + { 0xfbed, 3, 4745 }, + { 0xfbee, 3, 4748 }, + { 0xfbef, 3, 4748 }, + { 0xfbf0, 3, 4751 }, + { 0xfbf1, 3, 4751 }, + { 0xfbf2, 3, 4754 }, + { 0xfbf3, 3, 4754 }, + { 0xfbf4, 3, 4757 }, + { 0xfbf5, 3, 4757 }, + { 0xfbf6, 3, 4760 }, + { 0xfbf7, 3, 4760 }, + { 0xfbf8, 3, 4760 }, + { 0xfbf9, 3, 4763 }, + { 0xfbfa, 3, 4763 }, + { 0xfbfb, 3, 4763 }, + { 0xfbfc, 1, 4766 }, + { 0xfbfd, 1, 4766 }, + { 0xfbfe, 1, 4766 }, + { 0xfbff, 1, 4766 }, + { 0xfc00, 3, 4767 }, + { 0xfc01, 3, 4770 }, + { 0xfc02, 3, 4773 }, + { 0xfc03, 3, 4763 }, + { 0xfc04, 3, 4776 }, + { 0xfc05, 2, 4779 }, + { 0xfc06, 2, 4781 }, + { 0xfc07, 2, 4783 }, + { 0xfc08, 2, 4785 }, + { 0xfc09, 2, 4787 }, + { 0xfc0a, 2, 4789 }, + { 0xfc0b, 2, 4791 }, + { 0xfc0c, 2, 4793 }, + { 0xfc0d, 2, 4795 }, + { 0xfc0e, 2, 4797 }, + { 0xfc0f, 2, 4799 }, + { 0xfc10, 2, 4801 }, + { 0xfc11, 2, 4803 }, + { 0xfc12, 2, 4805 }, + { 0xfc13, 2, 4807 }, + { 0xfc14, 2, 4809 }, + { 0xfc15, 2, 4811 }, + { 0xfc16, 2, 4813 }, + { 0xfc17, 2, 4815 }, + { 0xfc18, 2, 4817 }, + { 0xfc19, 2, 4819 }, + { 0xfc1a, 2, 4821 }, + { 0xfc1b, 2, 4823 }, + { 0xfc1c, 2, 4825 }, + { 0xfc1d, 2, 4827 }, + { 0xfc1e, 2, 4829 }, + { 0xfc1f, 2, 4831 }, + { 0xfc20, 2, 4833 }, + { 0xfc21, 2, 4835 }, + { 0xfc22, 2, 4837 }, + { 0xfc23, 2, 4839 }, + { 0xfc24, 2, 4841 }, + { 0xfc25, 2, 4843 }, + { 0xfc26, 2, 4845 }, + { 0xfc27, 2, 4847 }, + { 0xfc28, 2, 4849 }, + { 0xfc29, 2, 4851 }, + { 0xfc2a, 2, 4853 }, + { 0xfc2b, 2, 4855 }, + { 0xfc2c, 2, 4857 }, + { 0xfc2d, 2, 4859 }, + { 0xfc2e, 2, 4861 }, + { 0xfc2f, 2, 4863 }, + { 0xfc30, 2, 4865 }, + { 0xfc31, 2, 4867 }, + { 0xfc32, 2, 4869 }, + { 0xfc33, 2, 4871 }, + { 0xfc34, 2, 4873 }, + { 0xfc35, 2, 4875 }, + { 0xfc36, 2, 4877 }, + { 0xfc37, 2, 4879 }, + { 0xfc38, 2, 4881 }, + { 0xfc39, 2, 4883 }, + { 0xfc3a, 2, 4885 }, + { 0xfc3b, 2, 4887 }, + { 0xfc3c, 2, 4889 }, + { 0xfc3d, 2, 4891 }, + { 0xfc3e, 2, 4893 }, + { 0xfc3f, 2, 4895 }, + { 0xfc40, 2, 4897 }, + { 0xfc41, 2, 4899 }, + { 0xfc42, 2, 4901 }, + { 0xfc43, 2, 4903 }, + { 0xfc44, 2, 4905 }, + { 0xfc45, 2, 4907 }, + { 0xfc46, 2, 4909 }, + { 0xfc47, 2, 4911 }, + { 0xfc48, 2, 4913 }, + { 0xfc49, 2, 4915 }, + { 0xfc4a, 2, 4917 }, + { 0xfc4b, 2, 4919 }, + { 0xfc4c, 2, 4921 }, + { 0xfc4d, 2, 4923 }, + { 0xfc4e, 2, 4925 }, + { 0xfc4f, 2, 4927 }, + { 0xfc50, 2, 4929 }, + { 0xfc51, 2, 4931 }, + { 0xfc52, 2, 4933 }, + { 0xfc53, 2, 4935 }, + { 0xfc54, 2, 4937 }, + { 0xfc55, 2, 4939 }, + { 0xfc56, 2, 4941 }, + { 0xfc57, 2, 4943 }, + { 0xfc58, 2, 4945 }, + { 0xfc59, 2, 4947 }, + { 0xfc5a, 2, 4949 }, + { 0xfc5b, 2, 4951 }, + { 0xfc5c, 2, 4953 }, + { 0xfc5d, 2, 4955 }, + { 0xfc5e, 3, 4957 }, + { 0xfc5f, 3, 4960 }, + { 0xfc60, 3, 4963 }, + { 0xfc61, 3, 4966 }, + { 0xfc62, 3, 4969 }, + { 0xfc63, 3, 4972 }, + { 0xfc64, 3, 4975 }, + { 0xfc65, 3, 4978 }, + { 0xfc66, 3, 4773 }, + { 0xfc67, 3, 4981 }, + { 0xfc68, 3, 4763 }, + { 0xfc69, 3, 4776 }, + { 0xfc6a, 2, 4984 }, + { 0xfc6b, 2, 4986 }, + { 0xfc6c, 2, 4785 }, + { 0xfc6d, 2, 4988 }, + { 0xfc6e, 2, 4787 }, + { 0xfc6f, 2, 4789 }, + { 0xfc70, 2, 4990 }, + { 0xfc71, 2, 4992 }, + { 0xfc72, 2, 4797 }, + { 0xfc73, 2, 4994 }, + { 0xfc74, 2, 4799 }, + { 0xfc75, 2, 4801 }, + { 0xfc76, 2, 4996 }, + { 0xfc77, 2, 4998 }, + { 0xfc78, 2, 4805 }, + { 0xfc79, 2, 5000 }, + { 0xfc7a, 2, 4807 }, + { 0xfc7b, 2, 4809 }, + { 0xfc7c, 2, 4867 }, + { 0xfc7d, 2, 4869 }, + { 0xfc7e, 2, 4875 }, + { 0xfc7f, 2, 4877 }, + { 0xfc80, 2, 4879 }, + { 0xfc81, 2, 4887 }, + { 0xfc82, 2, 4889 }, + { 0xfc83, 2, 4891 }, + { 0xfc84, 2, 4893 }, + { 0xfc85, 2, 4901 }, + { 0xfc86, 2, 4903 }, + { 0xfc87, 2, 4905 }, + { 0xfc88, 2, 5002 }, + { 0xfc89, 2, 4913 }, + { 0xfc8a, 2, 5004 }, + { 0xfc8b, 2, 5006 }, + { 0xfc8c, 2, 4925 }, + { 0xfc8d, 2, 5008 }, + { 0xfc8e, 2, 4927 }, + { 0xfc8f, 2, 4929 }, + { 0xfc90, 2, 4955 }, + { 0xfc91, 2, 5010 }, + { 0xfc92, 2, 5012 }, + { 0xfc93, 2, 4945 }, + { 0xfc94, 2, 5014 }, + { 0xfc95, 2, 4947 }, + { 0xfc96, 2, 4949 }, + { 0xfc97, 3, 4767 }, + { 0xfc98, 3, 4770 }, + { 0xfc99, 3, 5016 }, + { 0xfc9a, 3, 4773 }, + { 0xfc9b, 3, 5019 }, + { 0xfc9c, 2, 4779 }, + { 0xfc9d, 2, 4781 }, + { 0xfc9e, 2, 4783 }, + { 0xfc9f, 2, 4785 }, + { 0xfca0, 2, 5022 }, + { 0xfca1, 2, 4791 }, + { 0xfca2, 2, 4793 }, + { 0xfca3, 2, 4795 }, + { 0xfca4, 2, 4797 }, + { 0xfca5, 2, 5024 }, + { 0xfca6, 2, 4805 }, + { 0xfca7, 2, 4811 }, + { 0xfca8, 2, 4813 }, + { 0xfca9, 2, 4815 }, + { 0xfcaa, 2, 4817 }, + { 0xfcab, 2, 4819 }, + { 0xfcac, 2, 4823 }, + { 0xfcad, 2, 4825 }, + { 0xfcae, 2, 4827 }, + { 0xfcaf, 2, 4829 }, + { 0xfcb0, 2, 4831 }, + { 0xfcb1, 2, 4833 }, + { 0xfcb2, 2, 5026 }, + { 0xfcb3, 2, 4835 }, + { 0xfcb4, 2, 4837 }, + { 0xfcb5, 2, 4839 }, + { 0xfcb6, 2, 4841 }, + { 0xfcb7, 2, 4843 }, + { 0xfcb8, 2, 4845 }, + { 0xfcb9, 2, 4849 }, + { 0xfcba, 2, 4851 }, + { 0xfcbb, 2, 4853 }, + { 0xfcbc, 2, 4855 }, + { 0xfcbd, 2, 4857 }, + { 0xfcbe, 2, 4859 }, + { 0xfcbf, 2, 4861 }, + { 0xfcc0, 2, 4863 }, + { 0xfcc1, 2, 4865 }, + { 0xfcc2, 2, 4871 }, + { 0xfcc3, 2, 4873 }, + { 0xfcc4, 2, 4881 }, + { 0xfcc5, 2, 4883 }, + { 0xfcc6, 2, 4885 }, + { 0xfcc7, 2, 4887 }, + { 0xfcc8, 2, 4889 }, + { 0xfcc9, 2, 4895 }, + { 0xfcca, 2, 4897 }, + { 0xfccb, 2, 4899 }, + { 0xfccc, 2, 4901 }, + { 0xfccd, 2, 5028 }, + { 0xfcce, 2, 4907 }, + { 0xfccf, 2, 4909 }, + { 0xfcd0, 2, 4911 }, + { 0xfcd1, 2, 4913 }, + { 0xfcd2, 2, 4919 }, + { 0xfcd3, 2, 4921 }, + { 0xfcd4, 2, 4923 }, + { 0xfcd5, 2, 4925 }, + { 0xfcd6, 2, 5030 }, + { 0xfcd7, 2, 4931 }, + { 0xfcd8, 2, 4933 }, + { 0xfcd9, 2, 5032 }, + { 0xfcda, 2, 4939 }, + { 0xfcdb, 2, 4941 }, + { 0xfcdc, 2, 4943 }, + { 0xfcdd, 2, 4945 }, + { 0xfcde, 2, 5034 }, + { 0xfcdf, 3, 4773 }, + { 0xfce0, 3, 5019 }, + { 0xfce1, 2, 4785 }, + { 0xfce2, 2, 5022 }, + { 0xfce3, 2, 4797 }, + { 0xfce4, 2, 5024 }, + { 0xfce5, 2, 4805 }, + { 0xfce6, 2, 5036 }, + { 0xfce7, 2, 4831 }, + { 0xfce8, 2, 5038 }, + { 0xfce9, 2, 5040 }, + { 0xfcea, 2, 5042 }, + { 0xfceb, 2, 4887 }, + { 0xfcec, 2, 4889 }, + { 0xfced, 2, 4901 }, + { 0xfcee, 2, 4925 }, + { 0xfcef, 2, 5030 }, + { 0xfcf0, 2, 4945 }, + { 0xfcf1, 2, 5034 }, + { 0xfcf2, 3, 5044 }, + { 0xfcf3, 3, 5047 }, + { 0xfcf4, 3, 5050 }, + { 0xfcf5, 2, 5053 }, + { 0xfcf6, 2, 5055 }, + { 0xfcf7, 2, 5057 }, + { 0xfcf8, 2, 5059 }, + { 0xfcf9, 2, 5061 }, + { 0xfcfa, 2, 5063 }, + { 0xfcfb, 2, 5065 }, + { 0xfcfc, 2, 5067 }, + { 0xfcfd, 2, 5069 }, + { 0xfcfe, 2, 5071 }, + { 0xfcff, 2, 5073 }, + { 0xfd00, 2, 5075 }, + { 0xfd01, 2, 5077 }, + { 0xfd02, 2, 5079 }, + { 0xfd03, 2, 5081 }, + { 0xfd04, 2, 5083 }, + { 0xfd05, 2, 5085 }, + { 0xfd06, 2, 5087 }, + { 0xfd07, 2, 5089 }, + { 0xfd08, 2, 5091 }, + { 0xfd09, 2, 5093 }, + { 0xfd0a, 2, 5095 }, + { 0xfd0b, 2, 5097 }, + { 0xfd0c, 2, 5040 }, + { 0xfd0d, 2, 5099 }, + { 0xfd0e, 2, 5101 }, + { 0xfd0f, 2, 5103 }, + { 0xfd10, 2, 5105 }, + { 0xfd11, 2, 5053 }, + { 0xfd12, 2, 5055 }, + { 0xfd13, 2, 5057 }, + { 0xfd14, 2, 5059 }, + { 0xfd15, 2, 5061 }, + { 0xfd16, 2, 5063 }, + { 0xfd17, 2, 5065 }, + { 0xfd18, 2, 5067 }, + { 0xfd19, 2, 5069 }, + { 0xfd1a, 2, 5071 }, + { 0xfd1b, 2, 5073 }, + { 0xfd1c, 2, 5075 }, + { 0xfd1d, 2, 5077 }, + { 0xfd1e, 2, 5079 }, + { 0xfd1f, 2, 5081 }, + { 0xfd20, 2, 5083 }, + { 0xfd21, 2, 5085 }, + { 0xfd22, 2, 5087 }, + { 0xfd23, 2, 5089 }, + { 0xfd24, 2, 5091 }, + { 0xfd25, 2, 5093 }, + { 0xfd26, 2, 5095 }, + { 0xfd27, 2, 5097 }, + { 0xfd28, 2, 5040 }, + { 0xfd29, 2, 5099 }, + { 0xfd2a, 2, 5101 }, + { 0xfd2b, 2, 5103 }, + { 0xfd2c, 2, 5105 }, + { 0xfd2d, 2, 5093 }, + { 0xfd2e, 2, 5095 }, + { 0xfd2f, 2, 5097 }, + { 0xfd30, 2, 5040 }, + { 0xfd31, 2, 5038 }, + { 0xfd32, 2, 5042 }, + { 0xfd33, 2, 4847 }, + { 0xfd34, 2, 4825 }, + { 0xfd35, 2, 4827 }, + { 0xfd36, 2, 4829 }, + { 0xfd37, 2, 5093 }, + { 0xfd38, 2, 5095 }, + { 0xfd39, 2, 5097 }, + { 0xfd3a, 2, 4847 }, + { 0xfd3b, 2, 4849 }, + { 0xfd3c, 2, 5107 }, + { 0xfd3d, 2, 5107 }, + { 0xfd50, 3, 5109 }, + { 0xfd51, 3, 5112 }, + { 0xfd52, 3, 5112 }, + { 0xfd53, 3, 5115 }, + { 0xfd54, 3, 5118 }, + { 0xfd55, 3, 5121 }, + { 0xfd56, 3, 5124 }, + { 0xfd57, 3, 5127 }, + { 0xfd58, 3, 5130 }, + { 0xfd59, 3, 5130 }, + { 0xfd5a, 3, 5133 }, + { 0xfd5b, 3, 5136 }, + { 0xfd5c, 3, 5139 }, + { 0xfd5d, 3, 5142 }, + { 0xfd5e, 3, 5145 }, + { 0xfd5f, 3, 5148 }, + { 0xfd60, 3, 5148 }, + { 0xfd61, 3, 5151 }, + { 0xfd62, 3, 5154 }, + { 0xfd63, 3, 5154 }, + { 0xfd64, 3, 5157 }, + { 0xfd65, 3, 5157 }, + { 0xfd66, 3, 5160 }, + { 0xfd67, 3, 5163 }, + { 0xfd68, 3, 5163 }, + { 0xfd69, 3, 5166 }, + { 0xfd6a, 3, 5169 }, + { 0xfd6b, 3, 5169 }, + { 0xfd6c, 3, 5172 }, + { 0xfd6d, 3, 5172 }, + { 0xfd6e, 3, 5175 }, + { 0xfd6f, 3, 5178 }, + { 0xfd70, 3, 5178 }, + { 0xfd71, 3, 5181 }, + { 0xfd72, 3, 5181 }, + { 0xfd73, 3, 5184 }, + { 0xfd74, 3, 5187 }, + { 0xfd75, 3, 5190 }, + { 0xfd76, 3, 5193 }, + { 0xfd77, 3, 5193 }, + { 0xfd78, 3, 5196 }, + { 0xfd79, 3, 5199 }, + { 0xfd7a, 3, 5202 }, + { 0xfd7b, 3, 5205 }, + { 0xfd7c, 3, 5208 }, + { 0xfd7d, 3, 5208 }, + { 0xfd7e, 3, 5211 }, + { 0xfd7f, 3, 5214 }, + { 0xfd80, 3, 5217 }, + { 0xfd81, 3, 5220 }, + { 0xfd82, 3, 5223 }, + { 0xfd83, 3, 5226 }, + { 0xfd84, 3, 5226 }, + { 0xfd85, 3, 5229 }, + { 0xfd86, 3, 5229 }, + { 0xfd87, 3, 5232 }, + { 0xfd88, 3, 5232 }, + { 0xfd89, 3, 5235 }, + { 0xfd8a, 3, 5238 }, + { 0xfd8b, 3, 5241 }, + { 0xfd8c, 3, 5244 }, + { 0xfd8d, 3, 5247 }, + { 0xfd8e, 3, 5250 }, + { 0xfd8f, 3, 5253 }, + { 0xfd92, 3, 5256 }, + { 0xfd93, 3, 5259 }, + { 0xfd94, 3, 5262 }, + { 0xfd95, 3, 5265 }, + { 0xfd96, 3, 5268 }, + { 0xfd97, 3, 5271 }, + { 0xfd98, 3, 5271 }, + { 0xfd99, 3, 5274 }, + { 0xfd9a, 3, 5277 }, + { 0xfd9b, 3, 5280 }, + { 0xfd9c, 3, 5283 }, + { 0xfd9d, 3, 5283 }, + { 0xfd9e, 3, 5286 }, + { 0xfd9f, 3, 5289 }, + { 0xfda0, 3, 5292 }, + { 0xfda1, 3, 5295 }, + { 0xfda2, 3, 5298 }, + { 0xfda3, 3, 5301 }, + { 0xfda4, 3, 5304 }, + { 0xfda5, 3, 5307 }, + { 0xfda6, 3, 5310 }, + { 0xfda7, 3, 5313 }, + { 0xfda8, 3, 5316 }, + { 0xfda9, 3, 5319 }, + { 0xfdaa, 3, 5322 }, + { 0xfdab, 3, 5325 }, + { 0xfdac, 3, 5328 }, + { 0xfdad, 3, 5331 }, + { 0xfdae, 3, 5334 }, + { 0xfdaf, 3, 5337 }, + { 0xfdb0, 3, 5340 }, + { 0xfdb1, 3, 5343 }, + { 0xfdb2, 3, 5346 }, + { 0xfdb3, 3, 5349 }, + { 0xfdb4, 3, 5211 }, + { 0xfdb5, 3, 5217 }, + { 0xfdb6, 3, 5352 }, + { 0xfdb7, 3, 5355 }, + { 0xfdb8, 3, 5358 }, + { 0xfdb9, 3, 5361 }, + { 0xfdba, 3, 5364 }, + { 0xfdbb, 3, 5367 }, + { 0xfdbc, 3, 5364 }, + { 0xfdbd, 3, 5358 }, + { 0xfdbe, 3, 5370 }, + { 0xfdbf, 3, 5373 }, + { 0xfdc0, 3, 5376 }, + { 0xfdc1, 3, 5379 }, + { 0xfdc2, 3, 5382 }, + { 0xfdc3, 3, 5367 }, + { 0xfdc4, 3, 5190 }, + { 0xfdc5, 3, 5160 }, + { 0xfdc6, 3, 5385 }, + { 0xfdc7, 3, 5388 }, + { 0xfdf0, 3, 5391 }, + { 0xfdf1, 3, 5394 }, + { 0xfdf2, 4, 5397 }, + { 0xfdf3, 4, 5401 }, + { 0xfdf4, 4, 5405 }, + { 0xfdf5, 4, 5409 }, + { 0xfdf6, 4, 5413 }, + { 0xfdf7, 4, 5417 }, + { 0xfdf8, 4, 5421 }, + { 0xfdf9, 3, 5425 }, + { 0xfdfa, 18, 5428 }, + { 0xfdfb, 8, 5446 }, + { 0xfdfc, 4, 5454 }, + { 0xfe30, 2, 2139 }, + { 0xfe31, 1, 5458 }, + { 0xfe32, 1, 5459 }, + { 0xfe33, 1, 5460 }, + { 0xfe34, 1, 5460 }, + { 0xfe35, 1, 2179 }, + { 0xfe36, 1, 2180 }, + { 0xfe37, 1, 5461 }, + { 0xfe38, 1, 5462 }, + { 0xfe39, 1, 5463 }, + { 0xfe3a, 1, 5464 }, + { 0xfe3b, 1, 5465 }, + { 0xfe3c, 1, 5466 }, + { 0xfe3d, 1, 5467 }, + { 0xfe3e, 1, 5468 }, + { 0xfe3f, 1, 2425 }, + { 0xfe40, 1, 2426 }, + { 0xfe41, 1, 5469 }, + { 0xfe42, 1, 5470 }, + { 0xfe43, 1, 5471 }, + { 0xfe44, 1, 5472 }, + { 0xfe49, 2, 2156 }, + { 0xfe4a, 2, 2156 }, + { 0xfe4b, 2, 2156 }, + { 0xfe4c, 2, 2156 }, + { 0xfe4d, 1, 5460 }, + { 0xfe4e, 1, 5460 }, + { 0xfe4f, 1, 5460 }, + { 0xfe50, 1, 5473 }, + { 0xfe51, 1, 5474 }, + { 0xfe52, 1, 2138 }, + { 0xfe54, 1, 621 }, + { 0xfe55, 1, 5475 }, + { 0xfe56, 1, 5476 }, + { 0xfe57, 1, 5477 }, + { 0xfe58, 1, 5458 }, + { 0xfe59, 1, 2179 }, + { 0xfe5a, 1, 2180 }, + { 0xfe5b, 1, 5461 }, + { 0xfe5c, 1, 5462 }, + { 0xfe5d, 1, 5463 }, + { 0xfe5e, 1, 5464 }, + { 0xfe5f, 1, 5478 }, + { 0xfe60, 1, 5479 }, + { 0xfe61, 1, 5480 }, + { 0xfe62, 1, 2176 }, + { 0xfe63, 1, 5481 }, + { 0xfe64, 1, 5482 }, + { 0xfe65, 1, 5483 }, + { 0xfe66, 1, 2178 }, + { 0xfe68, 1, 5484 }, + { 0xfe69, 1, 5485 }, + { 0xfe6a, 1, 5486 }, + { 0xfe6b, 1, 5487 }, + { 0xfe70, 2, 5488 }, + { 0xfe71, 2, 5490 }, + { 0xfe72, 2, 5492 }, + { 0xfe74, 2, 5494 }, + { 0xfe76, 2, 5496 }, + { 0xfe77, 2, 5498 }, + { 0xfe78, 2, 5500 }, + { 0xfe79, 2, 5502 }, + { 0xfe7a, 2, 5504 }, + { 0xfe7b, 2, 5506 }, + { 0xfe7c, 2, 5508 }, + { 0xfe7d, 2, 5510 }, + { 0xfe7e, 2, 5512 }, + { 0xfe7f, 2, 5514 }, + { 0xfe80, 1, 5516 }, + { 0xfe81, 2, 784 }, + { 0xfe82, 2, 784 }, + { 0xfe83, 2, 786 }, + { 0xfe84, 2, 786 }, + { 0xfe85, 2, 788 }, + { 0xfe86, 2, 788 }, + { 0xfe87, 2, 790 }, + { 0xfe88, 2, 790 }, + { 0xfe89, 2, 792 }, + { 0xfe8a, 2, 792 }, + { 0xfe8b, 2, 792 }, + { 0xfe8c, 2, 792 }, + { 0xfe8d, 1, 5517 }, + { 0xfe8e, 1, 5517 }, + { 0xfe8f, 1, 5518 }, + { 0xfe90, 1, 5518 }, + { 0xfe91, 1, 5518 }, + { 0xfe92, 1, 5518 }, + { 0xfe93, 1, 5519 }, + { 0xfe94, 1, 5519 }, + { 0xfe95, 1, 5520 }, + { 0xfe96, 1, 5520 }, + { 0xfe97, 1, 5520 }, + { 0xfe98, 1, 5520 }, + { 0xfe99, 1, 5521 }, + { 0xfe9a, 1, 5521 }, + { 0xfe9b, 1, 5521 }, + { 0xfe9c, 1, 5521 }, + { 0xfe9d, 1, 5522 }, + { 0xfe9e, 1, 5522 }, + { 0xfe9f, 1, 5522 }, + { 0xfea0, 1, 5522 }, + { 0xfea1, 1, 5523 }, + { 0xfea2, 1, 5523 }, + { 0xfea3, 1, 5523 }, + { 0xfea4, 1, 5523 }, + { 0xfea5, 1, 5524 }, + { 0xfea6, 1, 5524 }, + { 0xfea7, 1, 5524 }, + { 0xfea8, 1, 5524 }, + { 0xfea9, 1, 5525 }, + { 0xfeaa, 1, 5525 }, + { 0xfeab, 1, 5526 }, + { 0xfeac, 1, 5526 }, + { 0xfead, 1, 5527 }, + { 0xfeae, 1, 5527 }, + { 0xfeaf, 1, 5528 }, + { 0xfeb0, 1, 5528 }, + { 0xfeb1, 1, 5529 }, + { 0xfeb2, 1, 5529 }, + { 0xfeb3, 1, 5529 }, + { 0xfeb4, 1, 5529 }, + { 0xfeb5, 1, 5530 }, + { 0xfeb6, 1, 5530 }, + { 0xfeb7, 1, 5530 }, + { 0xfeb8, 1, 5530 }, + { 0xfeb9, 1, 5531 }, + { 0xfeba, 1, 5531 }, + { 0xfebb, 1, 5531 }, + { 0xfebc, 1, 5531 }, + { 0xfebd, 1, 5532 }, + { 0xfebe, 1, 5532 }, + { 0xfebf, 1, 5532 }, + { 0xfec0, 1, 5532 }, + { 0xfec1, 1, 5533 }, + { 0xfec2, 1, 5533 }, + { 0xfec3, 1, 5533 }, + { 0xfec4, 1, 5533 }, + { 0xfec5, 1, 5534 }, + { 0xfec6, 1, 5534 }, + { 0xfec7, 1, 5534 }, + { 0xfec8, 1, 5534 }, + { 0xfec9, 1, 5535 }, + { 0xfeca, 1, 5535 }, + { 0xfecb, 1, 5535 }, + { 0xfecc, 1, 5535 }, + { 0xfecd, 1, 5536 }, + { 0xfece, 1, 5536 }, + { 0xfecf, 1, 5536 }, + { 0xfed0, 1, 5536 }, + { 0xfed1, 1, 5537 }, + { 0xfed2, 1, 5537 }, + { 0xfed3, 1, 5537 }, + { 0xfed4, 1, 5537 }, + { 0xfed5, 1, 5538 }, + { 0xfed6, 1, 5538 }, + { 0xfed7, 1, 5538 }, + { 0xfed8, 1, 5538 }, + { 0xfed9, 1, 5539 }, + { 0xfeda, 1, 5539 }, + { 0xfedb, 1, 5539 }, + { 0xfedc, 1, 5539 }, + { 0xfedd, 1, 5540 }, + { 0xfede, 1, 5540 }, + { 0xfedf, 1, 5540 }, + { 0xfee0, 1, 5540 }, + { 0xfee1, 1, 5541 }, + { 0xfee2, 1, 5541 }, + { 0xfee3, 1, 5541 }, + { 0xfee4, 1, 5541 }, + { 0xfee5, 1, 5542 }, + { 0xfee6, 1, 5542 }, + { 0xfee7, 1, 5542 }, + { 0xfee8, 1, 5542 }, + { 0xfee9, 1, 5543 }, + { 0xfeea, 1, 5543 }, + { 0xfeeb, 1, 5543 }, + { 0xfeec, 1, 5543 }, + { 0xfeed, 1, 5544 }, + { 0xfeee, 1, 5544 }, + { 0xfeef, 1, 4741 }, + { 0xfef0, 1, 4741 }, + { 0xfef1, 1, 5545 }, + { 0xfef2, 1, 5545 }, + { 0xfef3, 1, 5545 }, + { 0xfef4, 1, 5545 }, + { 0xfef5, 3, 5546 }, + { 0xfef6, 3, 5546 }, + { 0xfef7, 3, 5549 }, + { 0xfef8, 3, 5549 }, + { 0xfef9, 3, 5552 }, + { 0xfefa, 3, 5552 }, + { 0xfefb, 2, 5555 }, + { 0xfefc, 2, 5555 }, + { 0xff01, 1, 5477 }, + { 0xff02, 1, 5557 }, + { 0xff03, 1, 5478 }, + { 0xff04, 1, 5485 }, + { 0xff05, 1, 5486 }, + { 0xff06, 1, 5479 }, + { 0xff07, 1, 5558 }, + { 0xff08, 1, 2179 }, + { 0xff09, 1, 2180 }, + { 0xff0a, 1, 5480 }, + { 0xff0b, 1, 2176 }, + { 0xff0c, 1, 5473 }, + { 0xff0d, 1, 5481 }, + { 0xff0e, 1, 2138 }, + { 0xff0f, 1, 5559 }, + { 0xff10, 1, 2168 }, + { 0xff11, 1, 13 }, + { 0xff12, 1, 6 }, + { 0xff13, 1, 7 }, + { 0xff14, 1, 2170 }, + { 0xff15, 1, 2171 }, + { 0xff16, 1, 2172 }, + { 0xff17, 1, 2173 }, + { 0xff18, 1, 2174 }, + { 0xff19, 1, 2175 }, + { 0xff1a, 1, 5475 }, + { 0xff1b, 1, 621 }, + { 0xff1c, 1, 5482 }, + { 0xff1d, 1, 2178 }, + { 0xff1e, 1, 5483 }, + { 0xff1f, 1, 5476 }, + { 0xff20, 1, 5487 }, + { 0xff21, 1, 2649 }, + { 0xff22, 1, 2223 }, + { 0xff23, 1, 2190 }, + { 0xff24, 1, 2236 }, + { 0xff25, 1, 2225 }, + { 0xff26, 1, 2226 }, + { 0xff27, 1, 2650 }, + { 0xff28, 1, 2203 }, + { 0xff29, 1, 2205 }, + { 0xff2a, 1, 2651 }, + { 0xff2b, 1, 2222 }, + { 0xff2c, 1, 2206 }, + { 0xff2d, 1, 2227 }, + { 0xff2e, 1, 2207 }, + { 0xff2f, 1, 2652 }, + { 0xff30, 1, 2210 }, + { 0xff31, 1, 2211 }, + { 0xff32, 1, 2212 }, + { 0xff33, 1, 2653 }, + { 0xff34, 1, 2654 }, + { 0xff35, 1, 2655 }, + { 0xff36, 1, 2283 }, + { 0xff37, 1, 2656 }, + { 0xff38, 1, 2295 }, + { 0xff39, 1, 2657 }, + { 0xff3a, 1, 2220 }, + { 0xff3b, 1, 5560 }, + { 0xff3c, 1, 5484 }, + { 0xff3d, 1, 5561 }, + { 0xff3e, 1, 5562 }, + { 0xff3f, 1, 5460 }, + { 0xff40, 1, 2113 }, + { 0xff41, 1, 3 }, + { 0xff42, 1, 2658 }, + { 0xff43, 1, 2325 }, + { 0xff44, 1, 2237 }, + { 0xff45, 1, 2224 }, + { 0xff46, 1, 2659 }, + { 0xff47, 1, 2202 }, + { 0xff48, 1, 588 }, + { 0xff49, 1, 2169 }, + { 0xff4a, 1, 590 }, + { 0xff4b, 1, 2660 }, + { 0xff4c, 1, 610 }, + { 0xff4d, 1, 2326 }, + { 0xff4e, 1, 2181 }, + { 0xff4f, 1, 14 }, + { 0xff50, 1, 2661 }, + { 0xff51, 1, 2662 }, + { 0xff52, 1, 591 }, + { 0xff53, 1, 356 }, + { 0xff54, 1, 2663 }, + { 0xff55, 1, 2664 }, + { 0xff56, 1, 2308 }, + { 0xff57, 1, 595 }, + { 0xff58, 1, 611 }, + { 0xff59, 1, 596 }, + { 0xff5a, 1, 2665 }, + { 0xff5b, 1, 5461 }, + { 0xff5c, 1, 5563 }, + { 0xff5d, 1, 5462 }, + { 0xff5e, 1, 5564 }, + { 0xff5f, 1, 5565 }, + { 0xff60, 1, 5566 }, + { 0xff61, 1, 5567 }, + { 0xff62, 1, 5469 }, + { 0xff63, 1, 5470 }, + { 0xff64, 1, 5474 }, + { 0xff65, 1, 5568 }, + { 0xff66, 1, 3530 }, + { 0xff67, 1, 5569 }, + { 0xff68, 1, 5570 }, + { 0xff69, 1, 5571 }, + { 0xff6a, 1, 5572 }, + { 0xff6b, 1, 5573 }, + { 0xff6c, 1, 5574 }, + { 0xff6d, 1, 5575 }, + { 0xff6e, 1, 5576 }, + { 0xff6f, 1, 5577 }, + { 0xff70, 1, 5578 }, + { 0xff71, 1, 3484 }, + { 0xff72, 1, 3485 }, + { 0xff73, 1, 3486 }, + { 0xff74, 1, 3487 }, + { 0xff75, 1, 3488 }, + { 0xff76, 1, 3489 }, + { 0xff77, 1, 3490 }, + { 0xff78, 1, 3491 }, + { 0xff79, 1, 3492 }, + { 0xff7a, 1, 3493 }, + { 0xff7b, 1, 3494 }, + { 0xff7c, 1, 3495 }, + { 0xff7d, 1, 3496 }, + { 0xff7e, 1, 3497 }, + { 0xff7f, 1, 3498 }, + { 0xff80, 1, 3499 }, + { 0xff81, 1, 3500 }, + { 0xff82, 1, 3501 }, + { 0xff83, 1, 3502 }, + { 0xff84, 1, 3503 }, + { 0xff85, 1, 3504 }, + { 0xff86, 1, 3505 }, + { 0xff87, 1, 3506 }, + { 0xff88, 1, 3507 }, + { 0xff89, 1, 3508 }, + { 0xff8a, 1, 3509 }, + { 0xff8b, 1, 3510 }, + { 0xff8c, 1, 3511 }, + { 0xff8d, 1, 3512 }, + { 0xff8e, 1, 3513 }, + { 0xff8f, 1, 3514 }, + { 0xff90, 1, 3515 }, + { 0xff91, 1, 3516 }, + { 0xff92, 1, 3517 }, + { 0xff93, 1, 3518 }, + { 0xff94, 1, 3519 }, + { 0xff95, 1, 3520 }, + { 0xff96, 1, 3521 }, + { 0xff97, 1, 3522 }, + { 0xff98, 1, 3523 }, + { 0xff99, 1, 3524 }, + { 0xff9a, 1, 3525 }, + { 0xff9b, 1, 3526 }, + { 0xff9c, 1, 3527 }, + { 0xff9d, 1, 5579 }, + { 0xff9e, 1, 5580 }, + { 0xff9f, 1, 5581 }, + { 0xffa0, 1, 3074 }, + { 0xffa1, 1, 3023 }, + { 0xffa2, 1, 3024 }, + { 0xffa3, 1, 3025 }, + { 0xffa4, 1, 3026 }, + { 0xffa5, 1, 3027 }, + { 0xffa6, 1, 3028 }, + { 0xffa7, 1, 3029 }, + { 0xffa8, 1, 3030 }, + { 0xffa9, 1, 3031 }, + { 0xffaa, 1, 3032 }, + { 0xffab, 1, 3033 }, + { 0xffac, 1, 3034 }, + { 0xffad, 1, 3035 }, + { 0xffae, 1, 3036 }, + { 0xffaf, 1, 3037 }, + { 0xffb0, 1, 3038 }, + { 0xffb1, 1, 3039 }, + { 0xffb2, 1, 3040 }, + { 0xffb3, 1, 3041 }, + { 0xffb4, 1, 3042 }, + { 0xffb5, 1, 3043 }, + { 0xffb6, 1, 3044 }, + { 0xffb7, 1, 3045 }, + { 0xffb8, 1, 3046 }, + { 0xffb9, 1, 3047 }, + { 0xffba, 1, 3048 }, + { 0xffbb, 1, 3049 }, + { 0xffbc, 1, 3050 }, + { 0xffbd, 1, 3051 }, + { 0xffbe, 1, 3052 }, + { 0xffc2, 1, 3053 }, + { 0xffc3, 1, 3054 }, + { 0xffc4, 1, 3055 }, + { 0xffc5, 1, 3056 }, + { 0xffc6, 1, 3057 }, + { 0xffc7, 1, 3058 }, + { 0xffca, 1, 3059 }, + { 0xffcb, 1, 3060 }, + { 0xffcc, 1, 3061 }, + { 0xffcd, 1, 3062 }, + { 0xffce, 1, 3063 }, + { 0xffcf, 1, 3064 }, + { 0xffd2, 1, 3065 }, + { 0xffd3, 1, 3066 }, + { 0xffd4, 1, 3067 }, + { 0xffd5, 1, 3068 }, + { 0xffd6, 1, 3069 }, + { 0xffd7, 1, 3070 }, + { 0xffda, 1, 3071 }, + { 0xffdb, 1, 3072 }, + { 0xffdc, 1, 3073 }, + { 0xffe0, 1, 5582 }, + { 0xffe1, 1, 5583 }, + { 0xffe2, 1, 5584 }, + { 0xffe3, 2, 4 }, + { 0xffe4, 1, 5585 }, + { 0xffe5, 1, 5586 }, + { 0xffe6, 1, 5587 }, + { 0xffe8, 1, 5588 }, + { 0xffe9, 1, 5589 }, + { 0xffea, 1, 5590 }, + { 0xffeb, 1, 5591 }, + { 0xffec, 1, 5592 }, + { 0xffed, 1, 5593 }, + { 0xffee, 1, 5594 }, + { 0x1d15e, 2, 5595 }, + { 0x1d15f, 2, 5597 }, + { 0x1d160, 3, 5599 }, + { 0x1d161, 3, 5602 }, + { 0x1d162, 3, 5605 }, + { 0x1d163, 3, 5608 }, + { 0x1d164, 3, 5611 }, + { 0x1d1bb, 2, 5614 }, + { 0x1d1bc, 2, 5616 }, + { 0x1d1bd, 3, 5618 }, + { 0x1d1be, 3, 5621 }, + { 0x1d1bf, 3, 5624 }, + { 0x1d1c0, 3, 5627 }, + { 0x1d400, 1, 2649 }, + { 0x1d401, 1, 2223 }, + { 0x1d402, 1, 2190 }, + { 0x1d403, 1, 2236 }, + { 0x1d404, 1, 2225 }, + { 0x1d405, 1, 2226 }, + { 0x1d406, 1, 2650 }, + { 0x1d407, 1, 2203 }, + { 0x1d408, 1, 2205 }, + { 0x1d409, 1, 2651 }, + { 0x1d40a, 1, 2222 }, + { 0x1d40b, 1, 2206 }, + { 0x1d40c, 1, 2227 }, + { 0x1d40d, 1, 2207 }, + { 0x1d40e, 1, 2652 }, + { 0x1d40f, 1, 2210 }, + { 0x1d410, 1, 2211 }, + { 0x1d411, 1, 2212 }, + { 0x1d412, 1, 2653 }, + { 0x1d413, 1, 2654 }, + { 0x1d414, 1, 2655 }, + { 0x1d415, 1, 2283 }, + { 0x1d416, 1, 2656 }, + { 0x1d417, 1, 2295 }, + { 0x1d418, 1, 2657 }, + { 0x1d419, 1, 2220 }, + { 0x1d41a, 1, 3 }, + { 0x1d41b, 1, 2658 }, + { 0x1d41c, 1, 2325 }, + { 0x1d41d, 1, 2237 }, + { 0x1d41e, 1, 2224 }, + { 0x1d41f, 1, 2659 }, + { 0x1d420, 1, 2202 }, + { 0x1d421, 1, 588 }, + { 0x1d422, 1, 2169 }, + { 0x1d423, 1, 590 }, + { 0x1d424, 1, 2660 }, + { 0x1d425, 1, 610 }, + { 0x1d426, 1, 2326 }, + { 0x1d427, 1, 2181 }, + { 0x1d428, 1, 14 }, + { 0x1d429, 1, 2661 }, + { 0x1d42a, 1, 2662 }, + { 0x1d42b, 1, 591 }, + { 0x1d42c, 1, 356 }, + { 0x1d42d, 1, 2663 }, + { 0x1d42e, 1, 2664 }, + { 0x1d42f, 1, 2308 }, + { 0x1d430, 1, 595 }, + { 0x1d431, 1, 611 }, + { 0x1d432, 1, 596 }, + { 0x1d433, 1, 2665 }, + { 0x1d434, 1, 2649 }, + { 0x1d435, 1, 2223 }, + { 0x1d436, 1, 2190 }, + { 0x1d437, 1, 2236 }, + { 0x1d438, 1, 2225 }, + { 0x1d439, 1, 2226 }, + { 0x1d43a, 1, 2650 }, + { 0x1d43b, 1, 2203 }, + { 0x1d43c, 1, 2205 }, + { 0x1d43d, 1, 2651 }, + { 0x1d43e, 1, 2222 }, + { 0x1d43f, 1, 2206 }, + { 0x1d440, 1, 2227 }, + { 0x1d441, 1, 2207 }, + { 0x1d442, 1, 2652 }, + { 0x1d443, 1, 2210 }, + { 0x1d444, 1, 2211 }, + { 0x1d445, 1, 2212 }, + { 0x1d446, 1, 2653 }, + { 0x1d447, 1, 2654 }, + { 0x1d448, 1, 2655 }, + { 0x1d449, 1, 2283 }, + { 0x1d44a, 1, 2656 }, + { 0x1d44b, 1, 2295 }, + { 0x1d44c, 1, 2657 }, + { 0x1d44d, 1, 2220 }, + { 0x1d44e, 1, 3 }, + { 0x1d44f, 1, 2658 }, + { 0x1d450, 1, 2325 }, + { 0x1d451, 1, 2237 }, + { 0x1d452, 1, 2224 }, + { 0x1d453, 1, 2659 }, + { 0x1d454, 1, 2202 }, + { 0x1d456, 1, 2169 }, + { 0x1d457, 1, 590 }, + { 0x1d458, 1, 2660 }, + { 0x1d459, 1, 610 }, + { 0x1d45a, 1, 2326 }, + { 0x1d45b, 1, 2181 }, + { 0x1d45c, 1, 14 }, + { 0x1d45d, 1, 2661 }, + { 0x1d45e, 1, 2662 }, + { 0x1d45f, 1, 591 }, + { 0x1d460, 1, 356 }, + { 0x1d461, 1, 2663 }, + { 0x1d462, 1, 2664 }, + { 0x1d463, 1, 2308 }, + { 0x1d464, 1, 595 }, + { 0x1d465, 1, 611 }, + { 0x1d466, 1, 596 }, + { 0x1d467, 1, 2665 }, + { 0x1d468, 1, 2649 }, + { 0x1d469, 1, 2223 }, + { 0x1d46a, 1, 2190 }, + { 0x1d46b, 1, 2236 }, + { 0x1d46c, 1, 2225 }, + { 0x1d46d, 1, 2226 }, + { 0x1d46e, 1, 2650 }, + { 0x1d46f, 1, 2203 }, + { 0x1d470, 1, 2205 }, + { 0x1d471, 1, 2651 }, + { 0x1d472, 1, 2222 }, + { 0x1d473, 1, 2206 }, + { 0x1d474, 1, 2227 }, + { 0x1d475, 1, 2207 }, + { 0x1d476, 1, 2652 }, + { 0x1d477, 1, 2210 }, + { 0x1d478, 1, 2211 }, + { 0x1d479, 1, 2212 }, + { 0x1d47a, 1, 2653 }, + { 0x1d47b, 1, 2654 }, + { 0x1d47c, 1, 2655 }, + { 0x1d47d, 1, 2283 }, + { 0x1d47e, 1, 2656 }, + { 0x1d47f, 1, 2295 }, + { 0x1d480, 1, 2657 }, + { 0x1d481, 1, 2220 }, + { 0x1d482, 1, 3 }, + { 0x1d483, 1, 2658 }, + { 0x1d484, 1, 2325 }, + { 0x1d485, 1, 2237 }, + { 0x1d486, 1, 2224 }, + { 0x1d487, 1, 2659 }, + { 0x1d488, 1, 2202 }, + { 0x1d489, 1, 588 }, + { 0x1d48a, 1, 2169 }, + { 0x1d48b, 1, 590 }, + { 0x1d48c, 1, 2660 }, + { 0x1d48d, 1, 610 }, + { 0x1d48e, 1, 2326 }, + { 0x1d48f, 1, 2181 }, + { 0x1d490, 1, 14 }, + { 0x1d491, 1, 2661 }, + { 0x1d492, 1, 2662 }, + { 0x1d493, 1, 591 }, + { 0x1d494, 1, 356 }, + { 0x1d495, 1, 2663 }, + { 0x1d496, 1, 2664 }, + { 0x1d497, 1, 2308 }, + { 0x1d498, 1, 595 }, + { 0x1d499, 1, 611 }, + { 0x1d49a, 1, 596 }, + { 0x1d49b, 1, 2665 }, + { 0x1d49c, 1, 2649 }, + { 0x1d49e, 1, 2190 }, + { 0x1d49f, 1, 2236 }, + { 0x1d4a2, 1, 2650 }, + { 0x1d4a5, 1, 2651 }, + { 0x1d4a6, 1, 2222 }, + { 0x1d4a9, 1, 2207 }, + { 0x1d4aa, 1, 2652 }, + { 0x1d4ab, 1, 2210 }, + { 0x1d4ac, 1, 2211 }, + { 0x1d4ae, 1, 2653 }, + { 0x1d4af, 1, 2654 }, + { 0x1d4b0, 1, 2655 }, + { 0x1d4b1, 1, 2283 }, + { 0x1d4b2, 1, 2656 }, + { 0x1d4b3, 1, 2295 }, + { 0x1d4b4, 1, 2657 }, + { 0x1d4b5, 1, 2220 }, + { 0x1d4b6, 1, 3 }, + { 0x1d4b7, 1, 2658 }, + { 0x1d4b8, 1, 2325 }, + { 0x1d4b9, 1, 2237 }, + { 0x1d4bb, 1, 2659 }, + { 0x1d4bd, 1, 588 }, + { 0x1d4be, 1, 2169 }, + { 0x1d4bf, 1, 590 }, + { 0x1d4c0, 1, 2660 }, + { 0x1d4c2, 1, 2326 }, + { 0x1d4c3, 1, 2181 }, + { 0x1d4c5, 1, 2661 }, + { 0x1d4c6, 1, 2662 }, + { 0x1d4c7, 1, 591 }, + { 0x1d4c8, 1, 356 }, + { 0x1d4c9, 1, 2663 }, + { 0x1d4ca, 1, 2664 }, + { 0x1d4cb, 1, 2308 }, + { 0x1d4cc, 1, 595 }, + { 0x1d4cd, 1, 611 }, + { 0x1d4ce, 1, 596 }, + { 0x1d4cf, 1, 2665 }, + { 0x1d4d0, 1, 2649 }, + { 0x1d4d1, 1, 2223 }, + { 0x1d4d2, 1, 2190 }, + { 0x1d4d3, 1, 2236 }, + { 0x1d4d4, 1, 2225 }, + { 0x1d4d5, 1, 2226 }, + { 0x1d4d6, 1, 2650 }, + { 0x1d4d7, 1, 2203 }, + { 0x1d4d8, 1, 2205 }, + { 0x1d4d9, 1, 2651 }, + { 0x1d4da, 1, 2222 }, + { 0x1d4db, 1, 2206 }, + { 0x1d4dc, 1, 2227 }, + { 0x1d4dd, 1, 2207 }, + { 0x1d4de, 1, 2652 }, + { 0x1d4df, 1, 2210 }, + { 0x1d4e0, 1, 2211 }, + { 0x1d4e1, 1, 2212 }, + { 0x1d4e2, 1, 2653 }, + { 0x1d4e3, 1, 2654 }, + { 0x1d4e4, 1, 2655 }, + { 0x1d4e5, 1, 2283 }, + { 0x1d4e6, 1, 2656 }, + { 0x1d4e7, 1, 2295 }, + { 0x1d4e8, 1, 2657 }, + { 0x1d4e9, 1, 2220 }, + { 0x1d4ea, 1, 3 }, + { 0x1d4eb, 1, 2658 }, + { 0x1d4ec, 1, 2325 }, + { 0x1d4ed, 1, 2237 }, + { 0x1d4ee, 1, 2224 }, + { 0x1d4ef, 1, 2659 }, + { 0x1d4f0, 1, 2202 }, + { 0x1d4f1, 1, 588 }, + { 0x1d4f2, 1, 2169 }, + { 0x1d4f3, 1, 590 }, + { 0x1d4f4, 1, 2660 }, + { 0x1d4f5, 1, 610 }, + { 0x1d4f6, 1, 2326 }, + { 0x1d4f7, 1, 2181 }, + { 0x1d4f8, 1, 14 }, + { 0x1d4f9, 1, 2661 }, + { 0x1d4fa, 1, 2662 }, + { 0x1d4fb, 1, 591 }, + { 0x1d4fc, 1, 356 }, + { 0x1d4fd, 1, 2663 }, + { 0x1d4fe, 1, 2664 }, + { 0x1d4ff, 1, 2308 }, + { 0x1d500, 1, 595 }, + { 0x1d501, 1, 611 }, + { 0x1d502, 1, 596 }, + { 0x1d503, 1, 2665 }, + { 0x1d504, 1, 2649 }, + { 0x1d505, 1, 2223 }, + { 0x1d507, 1, 2236 }, + { 0x1d508, 1, 2225 }, + { 0x1d509, 1, 2226 }, + { 0x1d50a, 1, 2650 }, + { 0x1d50d, 1, 2651 }, + { 0x1d50e, 1, 2222 }, + { 0x1d50f, 1, 2206 }, + { 0x1d510, 1, 2227 }, + { 0x1d511, 1, 2207 }, + { 0x1d512, 1, 2652 }, + { 0x1d513, 1, 2210 }, + { 0x1d514, 1, 2211 }, + { 0x1d516, 1, 2653 }, + { 0x1d517, 1, 2654 }, + { 0x1d518, 1, 2655 }, + { 0x1d519, 1, 2283 }, + { 0x1d51a, 1, 2656 }, + { 0x1d51b, 1, 2295 }, + { 0x1d51c, 1, 2657 }, + { 0x1d51e, 1, 3 }, + { 0x1d51f, 1, 2658 }, + { 0x1d520, 1, 2325 }, + { 0x1d521, 1, 2237 }, + { 0x1d522, 1, 2224 }, + { 0x1d523, 1, 2659 }, + { 0x1d524, 1, 2202 }, + { 0x1d525, 1, 588 }, + { 0x1d526, 1, 2169 }, + { 0x1d527, 1, 590 }, + { 0x1d528, 1, 2660 }, + { 0x1d529, 1, 610 }, + { 0x1d52a, 1, 2326 }, + { 0x1d52b, 1, 2181 }, + { 0x1d52c, 1, 14 }, + { 0x1d52d, 1, 2661 }, + { 0x1d52e, 1, 2662 }, + { 0x1d52f, 1, 591 }, + { 0x1d530, 1, 356 }, + { 0x1d531, 1, 2663 }, + { 0x1d532, 1, 2664 }, + { 0x1d533, 1, 2308 }, + { 0x1d534, 1, 595 }, + { 0x1d535, 1, 611 }, + { 0x1d536, 1, 596 }, + { 0x1d537, 1, 2665 }, + { 0x1d538, 1, 2649 }, + { 0x1d539, 1, 2223 }, + { 0x1d53b, 1, 2236 }, + { 0x1d53c, 1, 2225 }, + { 0x1d53d, 1, 2226 }, + { 0x1d53e, 1, 2650 }, + { 0x1d540, 1, 2205 }, + { 0x1d541, 1, 2651 }, + { 0x1d542, 1, 2222 }, + { 0x1d543, 1, 2206 }, + { 0x1d544, 1, 2227 }, + { 0x1d546, 1, 2652 }, + { 0x1d54a, 1, 2653 }, + { 0x1d54b, 1, 2654 }, + { 0x1d54c, 1, 2655 }, + { 0x1d54d, 1, 2283 }, + { 0x1d54e, 1, 2656 }, + { 0x1d54f, 1, 2295 }, + { 0x1d550, 1, 2657 }, + { 0x1d552, 1, 3 }, + { 0x1d553, 1, 2658 }, + { 0x1d554, 1, 2325 }, + { 0x1d555, 1, 2237 }, + { 0x1d556, 1, 2224 }, + { 0x1d557, 1, 2659 }, + { 0x1d558, 1, 2202 }, + { 0x1d559, 1, 588 }, + { 0x1d55a, 1, 2169 }, + { 0x1d55b, 1, 590 }, + { 0x1d55c, 1, 2660 }, + { 0x1d55d, 1, 610 }, + { 0x1d55e, 1, 2326 }, + { 0x1d55f, 1, 2181 }, + { 0x1d560, 1, 14 }, + { 0x1d561, 1, 2661 }, + { 0x1d562, 1, 2662 }, + { 0x1d563, 1, 591 }, + { 0x1d564, 1, 356 }, + { 0x1d565, 1, 2663 }, + { 0x1d566, 1, 2664 }, + { 0x1d567, 1, 2308 }, + { 0x1d568, 1, 595 }, + { 0x1d569, 1, 611 }, + { 0x1d56a, 1, 596 }, + { 0x1d56b, 1, 2665 }, + { 0x1d56c, 1, 2649 }, + { 0x1d56d, 1, 2223 }, + { 0x1d56e, 1, 2190 }, + { 0x1d56f, 1, 2236 }, + { 0x1d570, 1, 2225 }, + { 0x1d571, 1, 2226 }, + { 0x1d572, 1, 2650 }, + { 0x1d573, 1, 2203 }, + { 0x1d574, 1, 2205 }, + { 0x1d575, 1, 2651 }, + { 0x1d576, 1, 2222 }, + { 0x1d577, 1, 2206 }, + { 0x1d578, 1, 2227 }, + { 0x1d579, 1, 2207 }, + { 0x1d57a, 1, 2652 }, + { 0x1d57b, 1, 2210 }, + { 0x1d57c, 1, 2211 }, + { 0x1d57d, 1, 2212 }, + { 0x1d57e, 1, 2653 }, + { 0x1d57f, 1, 2654 }, + { 0x1d580, 1, 2655 }, + { 0x1d581, 1, 2283 }, + { 0x1d582, 1, 2656 }, + { 0x1d583, 1, 2295 }, + { 0x1d584, 1, 2657 }, + { 0x1d585, 1, 2220 }, + { 0x1d586, 1, 3 }, + { 0x1d587, 1, 2658 }, + { 0x1d588, 1, 2325 }, + { 0x1d589, 1, 2237 }, + { 0x1d58a, 1, 2224 }, + { 0x1d58b, 1, 2659 }, + { 0x1d58c, 1, 2202 }, + { 0x1d58d, 1, 588 }, + { 0x1d58e, 1, 2169 }, + { 0x1d58f, 1, 590 }, + { 0x1d590, 1, 2660 }, + { 0x1d591, 1, 610 }, + { 0x1d592, 1, 2326 }, + { 0x1d593, 1, 2181 }, + { 0x1d594, 1, 14 }, + { 0x1d595, 1, 2661 }, + { 0x1d596, 1, 2662 }, + { 0x1d597, 1, 591 }, + { 0x1d598, 1, 356 }, + { 0x1d599, 1, 2663 }, + { 0x1d59a, 1, 2664 }, + { 0x1d59b, 1, 2308 }, + { 0x1d59c, 1, 595 }, + { 0x1d59d, 1, 611 }, + { 0x1d59e, 1, 596 }, + { 0x1d59f, 1, 2665 }, + { 0x1d5a0, 1, 2649 }, + { 0x1d5a1, 1, 2223 }, + { 0x1d5a2, 1, 2190 }, + { 0x1d5a3, 1, 2236 }, + { 0x1d5a4, 1, 2225 }, + { 0x1d5a5, 1, 2226 }, + { 0x1d5a6, 1, 2650 }, + { 0x1d5a7, 1, 2203 }, + { 0x1d5a8, 1, 2205 }, + { 0x1d5a9, 1, 2651 }, + { 0x1d5aa, 1, 2222 }, + { 0x1d5ab, 1, 2206 }, + { 0x1d5ac, 1, 2227 }, + { 0x1d5ad, 1, 2207 }, + { 0x1d5ae, 1, 2652 }, + { 0x1d5af, 1, 2210 }, + { 0x1d5b0, 1, 2211 }, + { 0x1d5b1, 1, 2212 }, + { 0x1d5b2, 1, 2653 }, + { 0x1d5b3, 1, 2654 }, + { 0x1d5b4, 1, 2655 }, + { 0x1d5b5, 1, 2283 }, + { 0x1d5b6, 1, 2656 }, + { 0x1d5b7, 1, 2295 }, + { 0x1d5b8, 1, 2657 }, + { 0x1d5b9, 1, 2220 }, + { 0x1d5ba, 1, 3 }, + { 0x1d5bb, 1, 2658 }, + { 0x1d5bc, 1, 2325 }, + { 0x1d5bd, 1, 2237 }, + { 0x1d5be, 1, 2224 }, + { 0x1d5bf, 1, 2659 }, + { 0x1d5c0, 1, 2202 }, + { 0x1d5c1, 1, 588 }, + { 0x1d5c2, 1, 2169 }, + { 0x1d5c3, 1, 590 }, + { 0x1d5c4, 1, 2660 }, + { 0x1d5c5, 1, 610 }, + { 0x1d5c6, 1, 2326 }, + { 0x1d5c7, 1, 2181 }, + { 0x1d5c8, 1, 14 }, + { 0x1d5c9, 1, 2661 }, + { 0x1d5ca, 1, 2662 }, + { 0x1d5cb, 1, 591 }, + { 0x1d5cc, 1, 356 }, + { 0x1d5cd, 1, 2663 }, + { 0x1d5ce, 1, 2664 }, + { 0x1d5cf, 1, 2308 }, + { 0x1d5d0, 1, 595 }, + { 0x1d5d1, 1, 611 }, + { 0x1d5d2, 1, 596 }, + { 0x1d5d3, 1, 2665 }, + { 0x1d5d4, 1, 2649 }, + { 0x1d5d5, 1, 2223 }, + { 0x1d5d6, 1, 2190 }, + { 0x1d5d7, 1, 2236 }, + { 0x1d5d8, 1, 2225 }, + { 0x1d5d9, 1, 2226 }, + { 0x1d5da, 1, 2650 }, + { 0x1d5db, 1, 2203 }, + { 0x1d5dc, 1, 2205 }, + { 0x1d5dd, 1, 2651 }, + { 0x1d5de, 1, 2222 }, + { 0x1d5df, 1, 2206 }, + { 0x1d5e0, 1, 2227 }, + { 0x1d5e1, 1, 2207 }, + { 0x1d5e2, 1, 2652 }, + { 0x1d5e3, 1, 2210 }, + { 0x1d5e4, 1, 2211 }, + { 0x1d5e5, 1, 2212 }, + { 0x1d5e6, 1, 2653 }, + { 0x1d5e7, 1, 2654 }, + { 0x1d5e8, 1, 2655 }, + { 0x1d5e9, 1, 2283 }, + { 0x1d5ea, 1, 2656 }, + { 0x1d5eb, 1, 2295 }, + { 0x1d5ec, 1, 2657 }, + { 0x1d5ed, 1, 2220 }, + { 0x1d5ee, 1, 3 }, + { 0x1d5ef, 1, 2658 }, + { 0x1d5f0, 1, 2325 }, + { 0x1d5f1, 1, 2237 }, + { 0x1d5f2, 1, 2224 }, + { 0x1d5f3, 1, 2659 }, + { 0x1d5f4, 1, 2202 }, + { 0x1d5f5, 1, 588 }, + { 0x1d5f6, 1, 2169 }, + { 0x1d5f7, 1, 590 }, + { 0x1d5f8, 1, 2660 }, + { 0x1d5f9, 1, 610 }, + { 0x1d5fa, 1, 2326 }, + { 0x1d5fb, 1, 2181 }, + { 0x1d5fc, 1, 14 }, + { 0x1d5fd, 1, 2661 }, + { 0x1d5fe, 1, 2662 }, + { 0x1d5ff, 1, 591 }, + { 0x1d600, 1, 356 }, + { 0x1d601, 1, 2663 }, + { 0x1d602, 1, 2664 }, + { 0x1d603, 1, 2308 }, + { 0x1d604, 1, 595 }, + { 0x1d605, 1, 611 }, + { 0x1d606, 1, 596 }, + { 0x1d607, 1, 2665 }, + { 0x1d608, 1, 2649 }, + { 0x1d609, 1, 2223 }, + { 0x1d60a, 1, 2190 }, + { 0x1d60b, 1, 2236 }, + { 0x1d60c, 1, 2225 }, + { 0x1d60d, 1, 2226 }, + { 0x1d60e, 1, 2650 }, + { 0x1d60f, 1, 2203 }, + { 0x1d610, 1, 2205 }, + { 0x1d611, 1, 2651 }, + { 0x1d612, 1, 2222 }, + { 0x1d613, 1, 2206 }, + { 0x1d614, 1, 2227 }, + { 0x1d615, 1, 2207 }, + { 0x1d616, 1, 2652 }, + { 0x1d617, 1, 2210 }, + { 0x1d618, 1, 2211 }, + { 0x1d619, 1, 2212 }, + { 0x1d61a, 1, 2653 }, + { 0x1d61b, 1, 2654 }, + { 0x1d61c, 1, 2655 }, + { 0x1d61d, 1, 2283 }, + { 0x1d61e, 1, 2656 }, + { 0x1d61f, 1, 2295 }, + { 0x1d620, 1, 2657 }, + { 0x1d621, 1, 2220 }, + { 0x1d622, 1, 3 }, + { 0x1d623, 1, 2658 }, + { 0x1d624, 1, 2325 }, + { 0x1d625, 1, 2237 }, + { 0x1d626, 1, 2224 }, + { 0x1d627, 1, 2659 }, + { 0x1d628, 1, 2202 }, + { 0x1d629, 1, 588 }, + { 0x1d62a, 1, 2169 }, + { 0x1d62b, 1, 590 }, + { 0x1d62c, 1, 2660 }, + { 0x1d62d, 1, 610 }, + { 0x1d62e, 1, 2326 }, + { 0x1d62f, 1, 2181 }, + { 0x1d630, 1, 14 }, + { 0x1d631, 1, 2661 }, + { 0x1d632, 1, 2662 }, + { 0x1d633, 1, 591 }, + { 0x1d634, 1, 356 }, + { 0x1d635, 1, 2663 }, + { 0x1d636, 1, 2664 }, + { 0x1d637, 1, 2308 }, + { 0x1d638, 1, 595 }, + { 0x1d639, 1, 611 }, + { 0x1d63a, 1, 596 }, + { 0x1d63b, 1, 2665 }, + { 0x1d63c, 1, 2649 }, + { 0x1d63d, 1, 2223 }, + { 0x1d63e, 1, 2190 }, + { 0x1d63f, 1, 2236 }, + { 0x1d640, 1, 2225 }, + { 0x1d641, 1, 2226 }, + { 0x1d642, 1, 2650 }, + { 0x1d643, 1, 2203 }, + { 0x1d644, 1, 2205 }, + { 0x1d645, 1, 2651 }, + { 0x1d646, 1, 2222 }, + { 0x1d647, 1, 2206 }, + { 0x1d648, 1, 2227 }, + { 0x1d649, 1, 2207 }, + { 0x1d64a, 1, 2652 }, + { 0x1d64b, 1, 2210 }, + { 0x1d64c, 1, 2211 }, + { 0x1d64d, 1, 2212 }, + { 0x1d64e, 1, 2653 }, + { 0x1d64f, 1, 2654 }, + { 0x1d650, 1, 2655 }, + { 0x1d651, 1, 2283 }, + { 0x1d652, 1, 2656 }, + { 0x1d653, 1, 2295 }, + { 0x1d654, 1, 2657 }, + { 0x1d655, 1, 2220 }, + { 0x1d656, 1, 3 }, + { 0x1d657, 1, 2658 }, + { 0x1d658, 1, 2325 }, + { 0x1d659, 1, 2237 }, + { 0x1d65a, 1, 2224 }, + { 0x1d65b, 1, 2659 }, + { 0x1d65c, 1, 2202 }, + { 0x1d65d, 1, 588 }, + { 0x1d65e, 1, 2169 }, + { 0x1d65f, 1, 590 }, + { 0x1d660, 1, 2660 }, + { 0x1d661, 1, 610 }, + { 0x1d662, 1, 2326 }, + { 0x1d663, 1, 2181 }, + { 0x1d664, 1, 14 }, + { 0x1d665, 1, 2661 }, + { 0x1d666, 1, 2662 }, + { 0x1d667, 1, 591 }, + { 0x1d668, 1, 356 }, + { 0x1d669, 1, 2663 }, + { 0x1d66a, 1, 2664 }, + { 0x1d66b, 1, 2308 }, + { 0x1d66c, 1, 595 }, + { 0x1d66d, 1, 611 }, + { 0x1d66e, 1, 596 }, + { 0x1d66f, 1, 2665 }, + { 0x1d670, 1, 2649 }, + { 0x1d671, 1, 2223 }, + { 0x1d672, 1, 2190 }, + { 0x1d673, 1, 2236 }, + { 0x1d674, 1, 2225 }, + { 0x1d675, 1, 2226 }, + { 0x1d676, 1, 2650 }, + { 0x1d677, 1, 2203 }, + { 0x1d678, 1, 2205 }, + { 0x1d679, 1, 2651 }, + { 0x1d67a, 1, 2222 }, + { 0x1d67b, 1, 2206 }, + { 0x1d67c, 1, 2227 }, + { 0x1d67d, 1, 2207 }, + { 0x1d67e, 1, 2652 }, + { 0x1d67f, 1, 2210 }, + { 0x1d680, 1, 2211 }, + { 0x1d681, 1, 2212 }, + { 0x1d682, 1, 2653 }, + { 0x1d683, 1, 2654 }, + { 0x1d684, 1, 2655 }, + { 0x1d685, 1, 2283 }, + { 0x1d686, 1, 2656 }, + { 0x1d687, 1, 2295 }, + { 0x1d688, 1, 2657 }, + { 0x1d689, 1, 2220 }, + { 0x1d68a, 1, 3 }, + { 0x1d68b, 1, 2658 }, + { 0x1d68c, 1, 2325 }, + { 0x1d68d, 1, 2237 }, + { 0x1d68e, 1, 2224 }, + { 0x1d68f, 1, 2659 }, + { 0x1d690, 1, 2202 }, + { 0x1d691, 1, 588 }, + { 0x1d692, 1, 2169 }, + { 0x1d693, 1, 590 }, + { 0x1d694, 1, 2660 }, + { 0x1d695, 1, 610 }, + { 0x1d696, 1, 2326 }, + { 0x1d697, 1, 2181 }, + { 0x1d698, 1, 14 }, + { 0x1d699, 1, 2661 }, + { 0x1d69a, 1, 2662 }, + { 0x1d69b, 1, 591 }, + { 0x1d69c, 1, 356 }, + { 0x1d69d, 1, 2663 }, + { 0x1d69e, 1, 2664 }, + { 0x1d69f, 1, 2308 }, + { 0x1d6a0, 1, 595 }, + { 0x1d6a1, 1, 611 }, + { 0x1d6a2, 1, 596 }, + { 0x1d6a3, 1, 2665 }, + { 0x1d6a8, 1, 5630 }, + { 0x1d6a9, 1, 5631 }, + { 0x1d6aa, 1, 2233 }, + { 0x1d6ab, 1, 5632 }, + { 0x1d6ac, 1, 5633 }, + { 0x1d6ad, 1, 5634 }, + { 0x1d6ae, 1, 5635 }, + { 0x1d6af, 1, 676 }, + { 0x1d6b0, 1, 5636 }, + { 0x1d6b1, 1, 5637 }, + { 0x1d6b2, 1, 5638 }, + { 0x1d6b3, 1, 5639 }, + { 0x1d6b4, 1, 5640 }, + { 0x1d6b5, 1, 5641 }, + { 0x1d6b6, 1, 5642 }, + { 0x1d6b7, 1, 2234 }, + { 0x1d6b8, 1, 5643 }, + { 0x1d6b9, 1, 676 }, + { 0x1d6ba, 1, 5644 }, + { 0x1d6bb, 1, 5645 }, + { 0x1d6bc, 1, 670 }, + { 0x1d6bd, 1, 5646 }, + { 0x1d6be, 1, 5647 }, + { 0x1d6bf, 1, 5648 }, + { 0x1d6c0, 1, 2221 }, + { 0x1d6c1, 1, 5649 }, + { 0x1d6c2, 1, 5650 }, + { 0x1d6c3, 1, 668 }, + { 0x1d6c4, 1, 2232 }, + { 0x1d6c5, 1, 5651 }, + { 0x1d6c6, 1, 677 }, + { 0x1d6c7, 1, 5652 }, + { 0x1d6c8, 1, 5653 }, + { 0x1d6c9, 1, 669 }, + { 0x1d6ca, 1, 2025 }, + { 0x1d6cb, 1, 673 }, + { 0x1d6cc, 1, 5654 }, + { 0x1d6cd, 1, 10 }, + { 0x1d6ce, 1, 5655 }, + { 0x1d6cf, 1, 5656 }, + { 0x1d6d0, 1, 5657 }, + { 0x1d6d1, 1, 672 }, + { 0x1d6d2, 1, 674 }, + { 0x1d6d3, 1, 675 }, + { 0x1d6d4, 1, 5658 }, + { 0x1d6d5, 1, 5659 }, + { 0x1d6d6, 1, 5660 }, + { 0x1d6d7, 1, 671 }, + { 0x1d6d8, 1, 5661 }, + { 0x1d6d9, 1, 5662 }, + { 0x1d6da, 1, 5663 }, + { 0x1d6db, 1, 5664 }, + { 0x1d6dc, 1, 677 }, + { 0x1d6dd, 1, 669 }, + { 0x1d6de, 1, 673 }, + { 0x1d6df, 1, 671 }, + { 0x1d6e0, 1, 674 }, + { 0x1d6e1, 1, 672 }, + { 0x1d6e2, 1, 5630 }, + { 0x1d6e3, 1, 5631 }, + { 0x1d6e4, 1, 2233 }, + { 0x1d6e5, 1, 5632 }, + { 0x1d6e6, 1, 5633 }, + { 0x1d6e7, 1, 5634 }, + { 0x1d6e8, 1, 5635 }, + { 0x1d6e9, 1, 676 }, + { 0x1d6ea, 1, 5636 }, + { 0x1d6eb, 1, 5637 }, + { 0x1d6ec, 1, 5638 }, + { 0x1d6ed, 1, 5639 }, + { 0x1d6ee, 1, 5640 }, + { 0x1d6ef, 1, 5641 }, + { 0x1d6f0, 1, 5642 }, + { 0x1d6f1, 1, 2234 }, + { 0x1d6f2, 1, 5643 }, + { 0x1d6f3, 1, 676 }, + { 0x1d6f4, 1, 5644 }, + { 0x1d6f5, 1, 5645 }, + { 0x1d6f6, 1, 670 }, + { 0x1d6f7, 1, 5646 }, + { 0x1d6f8, 1, 5647 }, + { 0x1d6f9, 1, 5648 }, + { 0x1d6fa, 1, 2221 }, + { 0x1d6fb, 1, 5649 }, + { 0x1d6fc, 1, 5650 }, + { 0x1d6fd, 1, 668 }, + { 0x1d6fe, 1, 2232 }, + { 0x1d6ff, 1, 5651 }, + { 0x1d700, 1, 677 }, + { 0x1d701, 1, 5652 }, + { 0x1d702, 1, 5653 }, + { 0x1d703, 1, 669 }, + { 0x1d704, 1, 2025 }, + { 0x1d705, 1, 673 }, + { 0x1d706, 1, 5654 }, + { 0x1d707, 1, 10 }, + { 0x1d708, 1, 5655 }, + { 0x1d709, 1, 5656 }, + { 0x1d70a, 1, 5657 }, + { 0x1d70b, 1, 672 }, + { 0x1d70c, 1, 674 }, + { 0x1d70d, 1, 675 }, + { 0x1d70e, 1, 5658 }, + { 0x1d70f, 1, 5659 }, + { 0x1d710, 1, 5660 }, + { 0x1d711, 1, 671 }, + { 0x1d712, 1, 5661 }, + { 0x1d713, 1, 5662 }, + { 0x1d714, 1, 5663 }, + { 0x1d715, 1, 5664 }, + { 0x1d716, 1, 677 }, + { 0x1d717, 1, 669 }, + { 0x1d718, 1, 673 }, + { 0x1d719, 1, 671 }, + { 0x1d71a, 1, 674 }, + { 0x1d71b, 1, 672 }, + { 0x1d71c, 1, 5630 }, + { 0x1d71d, 1, 5631 }, + { 0x1d71e, 1, 2233 }, + { 0x1d71f, 1, 5632 }, + { 0x1d720, 1, 5633 }, + { 0x1d721, 1, 5634 }, + { 0x1d722, 1, 5635 }, + { 0x1d723, 1, 676 }, + { 0x1d724, 1, 5636 }, + { 0x1d725, 1, 5637 }, + { 0x1d726, 1, 5638 }, + { 0x1d727, 1, 5639 }, + { 0x1d728, 1, 5640 }, + { 0x1d729, 1, 5641 }, + { 0x1d72a, 1, 5642 }, + { 0x1d72b, 1, 2234 }, + { 0x1d72c, 1, 5643 }, + { 0x1d72d, 1, 676 }, + { 0x1d72e, 1, 5644 }, + { 0x1d72f, 1, 5645 }, + { 0x1d730, 1, 670 }, + { 0x1d731, 1, 5646 }, + { 0x1d732, 1, 5647 }, + { 0x1d733, 1, 5648 }, + { 0x1d734, 1, 2221 }, + { 0x1d735, 1, 5649 }, + { 0x1d736, 1, 5650 }, + { 0x1d737, 1, 668 }, + { 0x1d738, 1, 2232 }, + { 0x1d739, 1, 5651 }, + { 0x1d73a, 1, 677 }, + { 0x1d73b, 1, 5652 }, + { 0x1d73c, 1, 5653 }, + { 0x1d73d, 1, 669 }, + { 0x1d73e, 1, 2025 }, + { 0x1d73f, 1, 673 }, + { 0x1d740, 1, 5654 }, + { 0x1d741, 1, 10 }, + { 0x1d742, 1, 5655 }, + { 0x1d743, 1, 5656 }, + { 0x1d744, 1, 5657 }, + { 0x1d745, 1, 672 }, + { 0x1d746, 1, 674 }, + { 0x1d747, 1, 675 }, + { 0x1d748, 1, 5658 }, + { 0x1d749, 1, 5659 }, + { 0x1d74a, 1, 5660 }, + { 0x1d74b, 1, 671 }, + { 0x1d74c, 1, 5661 }, + { 0x1d74d, 1, 5662 }, + { 0x1d74e, 1, 5663 }, + { 0x1d74f, 1, 5664 }, + { 0x1d750, 1, 677 }, + { 0x1d751, 1, 669 }, + { 0x1d752, 1, 673 }, + { 0x1d753, 1, 671 }, + { 0x1d754, 1, 674 }, + { 0x1d755, 1, 672 }, + { 0x1d756, 1, 5630 }, + { 0x1d757, 1, 5631 }, + { 0x1d758, 1, 2233 }, + { 0x1d759, 1, 5632 }, + { 0x1d75a, 1, 5633 }, + { 0x1d75b, 1, 5634 }, + { 0x1d75c, 1, 5635 }, + { 0x1d75d, 1, 676 }, + { 0x1d75e, 1, 5636 }, + { 0x1d75f, 1, 5637 }, + { 0x1d760, 1, 5638 }, + { 0x1d761, 1, 5639 }, + { 0x1d762, 1, 5640 }, + { 0x1d763, 1, 5641 }, + { 0x1d764, 1, 5642 }, + { 0x1d765, 1, 2234 }, + { 0x1d766, 1, 5643 }, + { 0x1d767, 1, 676 }, + { 0x1d768, 1, 5644 }, + { 0x1d769, 1, 5645 }, + { 0x1d76a, 1, 670 }, + { 0x1d76b, 1, 5646 }, + { 0x1d76c, 1, 5647 }, + { 0x1d76d, 1, 5648 }, + { 0x1d76e, 1, 2221 }, + { 0x1d76f, 1, 5649 }, + { 0x1d770, 1, 5650 }, + { 0x1d771, 1, 668 }, + { 0x1d772, 1, 2232 }, + { 0x1d773, 1, 5651 }, + { 0x1d774, 1, 677 }, + { 0x1d775, 1, 5652 }, + { 0x1d776, 1, 5653 }, + { 0x1d777, 1, 669 }, + { 0x1d778, 1, 2025 }, + { 0x1d779, 1, 673 }, + { 0x1d77a, 1, 5654 }, + { 0x1d77b, 1, 10 }, + { 0x1d77c, 1, 5655 }, + { 0x1d77d, 1, 5656 }, + { 0x1d77e, 1, 5657 }, + { 0x1d77f, 1, 672 }, + { 0x1d780, 1, 674 }, + { 0x1d781, 1, 675 }, + { 0x1d782, 1, 5658 }, + { 0x1d783, 1, 5659 }, + { 0x1d784, 1, 5660 }, + { 0x1d785, 1, 671 }, + { 0x1d786, 1, 5661 }, + { 0x1d787, 1, 5662 }, + { 0x1d788, 1, 5663 }, + { 0x1d789, 1, 5664 }, + { 0x1d78a, 1, 677 }, + { 0x1d78b, 1, 669 }, + { 0x1d78c, 1, 673 }, + { 0x1d78d, 1, 671 }, + { 0x1d78e, 1, 674 }, + { 0x1d78f, 1, 672 }, + { 0x1d790, 1, 5630 }, + { 0x1d791, 1, 5631 }, + { 0x1d792, 1, 2233 }, + { 0x1d793, 1, 5632 }, + { 0x1d794, 1, 5633 }, + { 0x1d795, 1, 5634 }, + { 0x1d796, 1, 5635 }, + { 0x1d797, 1, 676 }, + { 0x1d798, 1, 5636 }, + { 0x1d799, 1, 5637 }, + { 0x1d79a, 1, 5638 }, + { 0x1d79b, 1, 5639 }, + { 0x1d79c, 1, 5640 }, + { 0x1d79d, 1, 5641 }, + { 0x1d79e, 1, 5642 }, + { 0x1d79f, 1, 2234 }, + { 0x1d7a0, 1, 5643 }, + { 0x1d7a1, 1, 676 }, + { 0x1d7a2, 1, 5644 }, + { 0x1d7a3, 1, 5645 }, + { 0x1d7a4, 1, 670 }, + { 0x1d7a5, 1, 5646 }, + { 0x1d7a6, 1, 5647 }, + { 0x1d7a7, 1, 5648 }, + { 0x1d7a8, 1, 2221 }, + { 0x1d7a9, 1, 5649 }, + { 0x1d7aa, 1, 5650 }, + { 0x1d7ab, 1, 668 }, + { 0x1d7ac, 1, 2232 }, + { 0x1d7ad, 1, 5651 }, + { 0x1d7ae, 1, 677 }, + { 0x1d7af, 1, 5652 }, + { 0x1d7b0, 1, 5653 }, + { 0x1d7b1, 1, 669 }, + { 0x1d7b2, 1, 2025 }, + { 0x1d7b3, 1, 673 }, + { 0x1d7b4, 1, 5654 }, + { 0x1d7b5, 1, 10 }, + { 0x1d7b6, 1, 5655 }, + { 0x1d7b7, 1, 5656 }, + { 0x1d7b8, 1, 5657 }, + { 0x1d7b9, 1, 672 }, + { 0x1d7ba, 1, 674 }, + { 0x1d7bb, 1, 675 }, + { 0x1d7bc, 1, 5658 }, + { 0x1d7bd, 1, 5659 }, + { 0x1d7be, 1, 5660 }, + { 0x1d7bf, 1, 671 }, + { 0x1d7c0, 1, 5661 }, + { 0x1d7c1, 1, 5662 }, + { 0x1d7c2, 1, 5663 }, + { 0x1d7c3, 1, 5664 }, + { 0x1d7c4, 1, 677 }, + { 0x1d7c5, 1, 669 }, + { 0x1d7c6, 1, 673 }, + { 0x1d7c7, 1, 671 }, + { 0x1d7c8, 1, 674 }, + { 0x1d7c9, 1, 672 }, + { 0x1d7ce, 1, 2168 }, + { 0x1d7cf, 1, 13 }, + { 0x1d7d0, 1, 6 }, + { 0x1d7d1, 1, 7 }, + { 0x1d7d2, 1, 2170 }, + { 0x1d7d3, 1, 2171 }, + { 0x1d7d4, 1, 2172 }, + { 0x1d7d5, 1, 2173 }, + { 0x1d7d6, 1, 2174 }, + { 0x1d7d7, 1, 2175 }, + { 0x1d7d8, 1, 2168 }, + { 0x1d7d9, 1, 13 }, + { 0x1d7da, 1, 6 }, + { 0x1d7db, 1, 7 }, + { 0x1d7dc, 1, 2170 }, + { 0x1d7dd, 1, 2171 }, + { 0x1d7de, 1, 2172 }, + { 0x1d7df, 1, 2173 }, + { 0x1d7e0, 1, 2174 }, + { 0x1d7e1, 1, 2175 }, + { 0x1d7e2, 1, 2168 }, + { 0x1d7e3, 1, 13 }, + { 0x1d7e4, 1, 6 }, + { 0x1d7e5, 1, 7 }, + { 0x1d7e6, 1, 2170 }, + { 0x1d7e7, 1, 2171 }, + { 0x1d7e8, 1, 2172 }, + { 0x1d7e9, 1, 2173 }, + { 0x1d7ea, 1, 2174 }, + { 0x1d7eb, 1, 2175 }, + { 0x1d7ec, 1, 2168 }, + { 0x1d7ed, 1, 13 }, + { 0x1d7ee, 1, 6 }, + { 0x1d7ef, 1, 7 }, + { 0x1d7f0, 1, 2170 }, + { 0x1d7f1, 1, 2171 }, + { 0x1d7f2, 1, 2172 }, + { 0x1d7f3, 1, 2173 }, + { 0x1d7f4, 1, 2174 }, + { 0x1d7f5, 1, 2175 }, + { 0x1d7f6, 1, 2168 }, + { 0x1d7f7, 1, 13 }, + { 0x1d7f8, 1, 6 }, + { 0x1d7f9, 1, 7 }, + { 0x1d7fa, 1, 2170 }, + { 0x1d7fb, 1, 2171 }, + { 0x1d7fc, 1, 2172 }, + { 0x1d7fd, 1, 2173 }, + { 0x1d7fe, 1, 2174 }, + { 0x1d7ff, 1, 2175 }, + { 0x2f800, 1, 5665 }, + { 0x2f801, 1, 5666 }, + { 0x2f802, 1, 5667 }, + { 0x2f803, 1, 5668 }, + { 0x2f804, 1, 5669 }, + { 0x2f805, 1, 4549 }, + { 0x2f806, 1, 5670 }, + { 0x2f807, 1, 5671 }, + { 0x2f808, 1, 5672 }, + { 0x2f809, 1, 5673 }, + { 0x2f80a, 1, 4550 }, + { 0x2f80b, 1, 5674 }, + { 0x2f80c, 1, 5675 }, + { 0x2f80d, 1, 5676 }, + { 0x2f80e, 1, 4551 }, + { 0x2f80f, 1, 5677 }, + { 0x2f810, 1, 5678 }, + { 0x2f811, 1, 5679 }, + { 0x2f812, 1, 5680 }, + { 0x2f813, 1, 5681 }, + { 0x2f814, 1, 5682 }, + { 0x2f815, 1, 5683 }, + { 0x2f816, 1, 5684 }, + { 0x2f817, 1, 5685 }, + { 0x2f818, 1, 5686 }, + { 0x2f819, 1, 5687 }, + { 0x2f81a, 1, 5688 }, + { 0x2f81b, 1, 5689 }, + { 0x2f81c, 1, 5690 }, + { 0x2f81d, 1, 2698 }, + { 0x2f81e, 1, 5691 }, + { 0x2f81f, 1, 5692 }, + { 0x2f820, 1, 5693 }, + { 0x2f821, 1, 5694 }, + { 0x2f822, 1, 5695 }, + { 0x2f823, 1, 5696 }, + { 0x2f824, 1, 5697 }, + { 0x2f825, 1, 5698 }, + { 0x2f826, 1, 4552 }, + { 0x2f827, 1, 4553 }, + { 0x2f828, 1, 5699 }, + { 0x2f829, 1, 5700 }, + { 0x2f82a, 1, 5701 }, + { 0x2f82b, 1, 4372 }, + { 0x2f82c, 1, 5702 }, + { 0x2f82d, 1, 4554 }, + { 0x2f82e, 1, 5703 }, + { 0x2f82f, 1, 5704 }, + { 0x2f830, 1, 5705 }, + { 0x2f831, 1, 5706 }, + { 0x2f832, 1, 5706 }, + { 0x2f833, 1, 5706 }, + { 0x2f834, 1, 5707 }, + { 0x2f835, 1, 5708 }, + { 0x2f836, 1, 5709 }, + { 0x2f837, 1, 5710 }, + { 0x2f838, 1, 5711 }, + { 0x2f839, 1, 5712 }, + { 0x2f83a, 1, 5713 }, + { 0x2f83b, 1, 5714 }, + { 0x2f83c, 1, 5715 }, + { 0x2f83d, 1, 5716 }, + { 0x2f83e, 1, 5717 }, + { 0x2f83f, 1, 5718 }, + { 0x2f840, 1, 5719 }, + { 0x2f841, 1, 5720 }, + { 0x2f842, 1, 5721 }, + { 0x2f843, 1, 5722 }, + { 0x2f844, 1, 5723 }, + { 0x2f845, 1, 5724 }, + { 0x2f846, 1, 5724 }, + { 0x2f847, 1, 5725 }, + { 0x2f848, 1, 5726 }, + { 0x2f849, 1, 5727 }, + { 0x2f84a, 1, 5728 }, + { 0x2f84b, 1, 5729 }, + { 0x2f84c, 1, 4556 }, + { 0x2f84d, 1, 5730 }, + { 0x2f84e, 1, 5731 }, + { 0x2f84f, 1, 5732 }, + { 0x2f850, 1, 4518 }, + { 0x2f851, 1, 5733 }, + { 0x2f852, 1, 5734 }, + { 0x2f853, 1, 5735 }, + { 0x2f854, 1, 5736 }, + { 0x2f855, 1, 5737 }, + { 0x2f856, 1, 5738 }, + { 0x2f857, 1, 5739 }, + { 0x2f858, 1, 5740 }, + { 0x2f859, 1, 5741 }, + { 0x2f85a, 1, 5742 }, + { 0x2f85b, 1, 5743 }, + { 0x2f85c, 1, 5744 }, + { 0x2f85d, 1, 5745 }, + { 0x2f85e, 1, 5746 }, + { 0x2f85f, 1, 5747 }, + { 0x2f860, 1, 5748 }, + { 0x2f861, 1, 5749 }, + { 0x2f862, 1, 5750 }, + { 0x2f863, 1, 5751 }, + { 0x2f864, 1, 5752 }, + { 0x2f865, 1, 5753 }, + { 0x2f866, 1, 5754 }, + { 0x2f867, 1, 5755 }, + { 0x2f868, 1, 5756 }, + { 0x2f869, 1, 5757 }, + { 0x2f86a, 1, 5758 }, + { 0x2f86b, 1, 5758 }, + { 0x2f86c, 1, 5759 }, + { 0x2f86d, 1, 5760 }, + { 0x2f86e, 1, 5761 }, + { 0x2f86f, 1, 4368 }, + { 0x2f870, 1, 5762 }, + { 0x2f871, 1, 5763 }, + { 0x2f872, 1, 5764 }, + { 0x2f873, 1, 5765 }, + { 0x2f874, 1, 5766 }, + { 0x2f875, 1, 2724 }, + { 0x2f876, 1, 5767 }, + { 0x2f877, 1, 5768 }, + { 0x2f878, 1, 2726 }, + { 0x2f879, 1, 5769 }, + { 0x2f87a, 1, 5770 }, + { 0x2f87b, 1, 5771 }, + { 0x2f87c, 1, 5772 }, + { 0x2f87d, 1, 5773 }, + { 0x2f87e, 1, 5774 }, + { 0x2f87f, 1, 5775 }, + { 0x2f880, 1, 5776 }, + { 0x2f881, 1, 5777 }, + { 0x2f882, 1, 5778 }, + { 0x2f883, 1, 5779 }, + { 0x2f884, 1, 5780 }, + { 0x2f885, 1, 5781 }, + { 0x2f886, 1, 5782 }, + { 0x2f887, 1, 5783 }, + { 0x2f888, 1, 5784 }, + { 0x2f889, 1, 5785 }, + { 0x2f88a, 1, 5786 }, + { 0x2f88b, 1, 5787 }, + { 0x2f88c, 1, 5788 }, + { 0x2f88d, 1, 5789 }, + { 0x2f88e, 1, 4316 }, + { 0x2f88f, 1, 5790 }, + { 0x2f890, 1, 2736 }, + { 0x2f891, 1, 5791 }, + { 0x2f892, 1, 5791 }, + { 0x2f893, 1, 5792 }, + { 0x2f894, 1, 5793 }, + { 0x2f895, 1, 5793 }, + { 0x2f896, 1, 5794 }, + { 0x2f897, 1, 5795 }, + { 0x2f898, 1, 5796 }, + { 0x2f899, 1, 5797 }, + { 0x2f89a, 1, 5798 }, + { 0x2f89b, 1, 5799 }, + { 0x2f89c, 1, 5800 }, + { 0x2f89d, 1, 5801 }, + { 0x2f89e, 1, 5802 }, + { 0x2f89f, 1, 5803 }, + { 0x2f8a0, 1, 5804 }, + { 0x2f8a1, 1, 5805 }, + { 0x2f8a2, 1, 5806 }, + { 0x2f8a3, 1, 4561 }, + { 0x2f8a4, 1, 5807 }, + { 0x2f8a5, 1, 5808 }, + { 0x2f8a6, 1, 5809 }, + { 0x2f8a7, 1, 5810 }, + { 0x2f8a8, 1, 5811 }, + { 0x2f8a9, 1, 5810 }, + { 0x2f8aa, 1, 5812 }, + { 0x2f8ab, 1, 4563 }, + { 0x2f8ac, 1, 5813 }, + { 0x2f8ad, 1, 5814 }, + { 0x2f8ae, 1, 5815 }, + { 0x2f8af, 1, 5816 }, + { 0x2f8b0, 1, 4564 }, + { 0x2f8b1, 1, 4289 }, + { 0x2f8b2, 1, 5817 }, + { 0x2f8b3, 1, 5818 }, + { 0x2f8b4, 1, 5819 }, + { 0x2f8b5, 1, 5820 }, + { 0x2f8b6, 1, 5821 }, + { 0x2f8b7, 1, 5822 }, + { 0x2f8b8, 1, 5823 }, + { 0x2f8b9, 1, 5824 }, + { 0x2f8ba, 1, 5825 }, + { 0x2f8bb, 1, 5826 }, + { 0x2f8bc, 1, 5827 }, + { 0x2f8bd, 1, 5828 }, + { 0x2f8be, 1, 5829 }, + { 0x2f8bf, 1, 5830 }, + { 0x2f8c0, 1, 5831 }, + { 0x2f8c1, 1, 5832 }, + { 0x2f8c2, 1, 5833 }, + { 0x2f8c3, 1, 5834 }, + { 0x2f8c4, 1, 5835 }, + { 0x2f8c5, 1, 5836 }, + { 0x2f8c6, 1, 5837 }, + { 0x2f8c7, 1, 5838 }, + { 0x2f8c8, 1, 4565 }, + { 0x2f8c9, 1, 5839 }, + { 0x2f8ca, 1, 5840 }, + { 0x2f8cb, 1, 5841 }, + { 0x2f8cc, 1, 5842 }, + { 0x2f8cd, 1, 5843 }, + { 0x2f8ce, 1, 5844 }, + { 0x2f8cf, 1, 4567 }, + { 0x2f8d0, 1, 5845 }, + { 0x2f8d1, 1, 5846 }, + { 0x2f8d2, 1, 5847 }, + { 0x2f8d3, 1, 5848 }, + { 0x2f8d4, 1, 5849 }, + { 0x2f8d5, 1, 5850 }, + { 0x2f8d6, 1, 5851 }, + { 0x2f8d7, 1, 5852 }, + { 0x2f8d8, 1, 4317 }, + { 0x2f8d9, 1, 5853 }, + { 0x2f8da, 1, 5854 }, + { 0x2f8db, 1, 5855 }, + { 0x2f8dc, 1, 5856 }, + { 0x2f8dd, 1, 5857 }, + { 0x2f8de, 1, 5858 }, + { 0x2f8df, 1, 5859 }, + { 0x2f8e0, 1, 5860 }, + { 0x2f8e1, 1, 5861 }, + { 0x2f8e2, 1, 4568 }, + { 0x2f8e3, 1, 5862 }, + { 0x2f8e4, 1, 5863 }, + { 0x2f8e5, 1, 5864 }, + { 0x2f8e6, 1, 5865 }, + { 0x2f8e7, 1, 5866 }, + { 0x2f8e8, 1, 5867 }, + { 0x2f8e9, 1, 5868 }, + { 0x2f8ea, 1, 5869 }, + { 0x2f8eb, 1, 5870 }, + { 0x2f8ec, 1, 5871 }, + { 0x2f8ed, 1, 5872 }, + { 0x2f8ee, 1, 5873 }, + { 0x2f8ef, 1, 5874 }, + { 0x2f8f0, 1, 5875 }, + { 0x2f8f1, 1, 5876 }, + { 0x2f8f2, 1, 5877 }, + { 0x2f8f3, 1, 5878 }, + { 0x2f8f4, 1, 5879 }, + { 0x2f8f5, 1, 4385 }, + { 0x2f8f6, 1, 5880 }, + { 0x2f8f7, 1, 5881 }, + { 0x2f8f8, 1, 5882 }, + { 0x2f8f9, 1, 5883 }, + { 0x2f8fa, 1, 5884 }, + { 0x2f8fb, 1, 5885 }, + { 0x2f8fc, 1, 5886 }, + { 0x2f8fd, 1, 5887 }, + { 0x2f8fe, 1, 5888 }, + { 0x2f8ff, 1, 5889 }, + { 0x2f900, 1, 5890 }, + { 0x2f901, 1, 4569 }, + { 0x2f902, 1, 4468 }, + { 0x2f903, 1, 5891 }, + { 0x2f904, 1, 5892 }, + { 0x2f905, 1, 5893 }, + { 0x2f906, 1, 5894 }, + { 0x2f907, 1, 5895 }, + { 0x2f908, 1, 5896 }, + { 0x2f909, 1, 5897 }, + { 0x2f90a, 1, 5898 }, + { 0x2f90b, 1, 5899 }, + { 0x2f90c, 1, 5900 }, + { 0x2f90d, 1, 5901 }, + { 0x2f90e, 1, 5902 }, + { 0x2f90f, 1, 5903 }, + { 0x2f910, 1, 5904 }, + { 0x2f911, 1, 5905 }, + { 0x2f912, 1, 5906 }, + { 0x2f913, 1, 5907 }, + { 0x2f914, 1, 5908 }, + { 0x2f915, 1, 5909 }, + { 0x2f916, 1, 5910 }, + { 0x2f917, 1, 5911 }, + { 0x2f918, 1, 5912 }, + { 0x2f919, 1, 5913 }, + { 0x2f91a, 1, 5914 }, + { 0x2f91b, 1, 5915 }, + { 0x2f91c, 1, 5916 }, + { 0x2f91d, 1, 5917 }, + { 0x2f91e, 1, 5918 }, + { 0x2f91f, 1, 5919 }, + { 0x2f920, 1, 5920 }, + { 0x2f921, 1, 5921 }, + { 0x2f922, 1, 5922 }, + { 0x2f923, 1, 5923 }, + { 0x2f924, 1, 5924 }, + { 0x2f925, 1, 5925 }, + { 0x2f926, 1, 5926 }, + { 0x2f927, 1, 5927 }, + { 0x2f928, 1, 5928 }, + { 0x2f929, 1, 5929 }, + { 0x2f92a, 1, 5930 }, + { 0x2f92b, 1, 5931 }, + { 0x2f92c, 1, 5932 }, + { 0x2f92d, 1, 5932 }, + { 0x2f92e, 1, 5933 }, + { 0x2f92f, 1, 5934 }, + { 0x2f930, 1, 5935 }, + { 0x2f931, 1, 5936 }, + { 0x2f932, 1, 5937 }, + { 0x2f933, 1, 5938 }, + { 0x2f934, 1, 5939 }, + { 0x2f935, 1, 5940 }, + { 0x2f936, 1, 5941 }, + { 0x2f937, 1, 5942 }, + { 0x2f938, 1, 4371 }, + { 0x2f939, 1, 5943 }, + { 0x2f93a, 1, 5944 }, + { 0x2f93b, 1, 5945 }, + { 0x2f93c, 1, 5946 }, + { 0x2f93d, 1, 5947 }, + { 0x2f93e, 1, 5948 }, + { 0x2f93f, 1, 5949 }, + { 0x2f940, 1, 5950 }, + { 0x2f941, 1, 5951 }, + { 0x2f942, 1, 5952 }, + { 0x2f943, 1, 5953 }, + { 0x2f944, 1, 5954 }, + { 0x2f945, 1, 5955 }, + { 0x2f946, 1, 5956 }, + { 0x2f947, 1, 5956 }, + { 0x2f948, 1, 5957 }, + { 0x2f949, 1, 5958 }, + { 0x2f94a, 1, 5959 }, + { 0x2f94b, 1, 5960 }, + { 0x2f94c, 1, 5961 }, + { 0x2f94d, 1, 5962 }, + { 0x2f94e, 1, 5963 }, + { 0x2f94f, 1, 4334 }, + { 0x2f950, 1, 5964 }, + { 0x2f951, 1, 5965 }, + { 0x2f952, 1, 5966 }, + { 0x2f953, 1, 4579 }, + { 0x2f954, 1, 5967 }, + { 0x2f955, 1, 5968 }, + { 0x2f956, 1, 4538 }, + { 0x2f957, 1, 5969 }, + { 0x2f958, 1, 5970 }, + { 0x2f959, 1, 4582 }, + { 0x2f95a, 1, 5971 }, + { 0x2f95b, 1, 5972 }, + { 0x2f95c, 1, 5973 }, + { 0x2f95d, 1, 5974 }, + { 0x2f95e, 1, 5974 }, + { 0x2f95f, 1, 5975 }, + { 0x2f960, 1, 5976 }, + { 0x2f961, 1, 5977 }, + { 0x2f962, 1, 5978 }, + { 0x2f963, 1, 5979 }, + { 0x2f964, 1, 5980 }, + { 0x2f965, 1, 5981 }, + { 0x2f966, 1, 5982 }, + { 0x2f967, 1, 5983 }, + { 0x2f968, 1, 5984 }, + { 0x2f969, 1, 5985 }, + { 0x2f96a, 1, 5986 }, + { 0x2f96b, 1, 5987 }, + { 0x2f96c, 1, 5988 }, + { 0x2f96d, 1, 5989 }, + { 0x2f96e, 1, 5990 }, + { 0x2f96f, 1, 5991 }, + { 0x2f970, 1, 5992 }, + { 0x2f971, 1, 5993 }, + { 0x2f972, 1, 5994 }, + { 0x2f973, 1, 5995 }, + { 0x2f974, 1, 5996 }, + { 0x2f975, 1, 5997 }, + { 0x2f976, 1, 5998 }, + { 0x2f977, 1, 5999 }, + { 0x2f978, 1, 6000 }, + { 0x2f979, 1, 6001 }, + { 0x2f97a, 1, 4588 }, + { 0x2f97b, 1, 6002 }, + { 0x2f97c, 1, 6003 }, + { 0x2f97d, 1, 6004 }, + { 0x2f97e, 1, 6005 }, + { 0x2f97f, 1, 6006 }, + { 0x2f980, 1, 6007 }, + { 0x2f981, 1, 6008 }, + { 0x2f982, 1, 6009 }, + { 0x2f983, 1, 6010 }, + { 0x2f984, 1, 6011 }, + { 0x2f985, 1, 6012 }, + { 0x2f986, 1, 6013 }, + { 0x2f987, 1, 6014 }, + { 0x2f988, 1, 6015 }, + { 0x2f989, 1, 6016 }, + { 0x2f98a, 1, 6017 }, + { 0x2f98b, 1, 5792 }, + { 0x2f98c, 1, 6018 }, + { 0x2f98d, 1, 6019 }, + { 0x2f98e, 1, 6020 }, + { 0x2f98f, 1, 6021 }, + { 0x2f990, 1, 6022 }, + { 0x2f991, 1, 6023 }, + { 0x2f992, 1, 6024 }, + { 0x2f993, 1, 6025 }, + { 0x2f994, 1, 6026 }, + { 0x2f995, 1, 6027 }, + { 0x2f996, 1, 6028 }, + { 0x2f997, 1, 6029 }, + { 0x2f998, 1, 4388 }, + { 0x2f999, 1, 6030 }, + { 0x2f99a, 1, 6031 }, + { 0x2f99b, 1, 6032 }, + { 0x2f99c, 1, 6033 }, + { 0x2f99d, 1, 6034 }, + { 0x2f99e, 1, 6035 }, + { 0x2f99f, 1, 4591 }, + { 0x2f9a0, 1, 6036 }, + { 0x2f9a1, 1, 6037 }, + { 0x2f9a2, 1, 6038 }, + { 0x2f9a3, 1, 6039 }, + { 0x2f9a4, 1, 6040 }, + { 0x2f9a5, 1, 6041 }, + { 0x2f9a6, 1, 6042 }, + { 0x2f9a7, 1, 6043 }, + { 0x2f9a8, 1, 6044 }, + { 0x2f9a9, 1, 6045 }, + { 0x2f9aa, 1, 6046 }, + { 0x2f9ab, 1, 6047 }, + { 0x2f9ac, 1, 6048 }, + { 0x2f9ad, 1, 6049 }, + { 0x2f9ae, 1, 6050 }, + { 0x2f9af, 1, 6051 }, + { 0x2f9b0, 1, 6052 }, + { 0x2f9b1, 1, 6053 }, + { 0x2f9b2, 1, 6054 }, + { 0x2f9b3, 1, 6055 }, + { 0x2f9b4, 1, 4329 }, + { 0x2f9b5, 1, 6056 }, + { 0x2f9b6, 1, 6057 }, + { 0x2f9b7, 1, 6058 }, + { 0x2f9b8, 1, 6059 }, + { 0x2f9b9, 1, 6060 }, + { 0x2f9ba, 1, 6061 }, + { 0x2f9bb, 1, 6062 }, + { 0x2f9bc, 1, 6063 }, + { 0x2f9bd, 1, 6064 }, + { 0x2f9be, 1, 6065 }, + { 0x2f9bf, 1, 6066 }, + { 0x2f9c0, 1, 6067 }, + { 0x2f9c1, 1, 6068 }, + { 0x2f9c2, 1, 6069 }, + { 0x2f9c3, 1, 6070 }, + { 0x2f9c4, 1, 2826 }, + { 0x2f9c5, 1, 6071 }, + { 0x2f9c6, 1, 6072 }, + { 0x2f9c7, 1, 6073 }, + { 0x2f9c8, 1, 6074 }, + { 0x2f9c9, 1, 6075 }, + { 0x2f9ca, 1, 6076 }, + { 0x2f9cb, 1, 6077 }, + { 0x2f9cc, 1, 6078 }, + { 0x2f9cd, 1, 6079 }, + { 0x2f9ce, 1, 6080 }, + { 0x2f9cf, 1, 6081 }, + { 0x2f9d0, 1, 6082 }, + { 0x2f9d1, 1, 6083 }, + { 0x2f9d2, 1, 2833 }, + { 0x2f9d3, 1, 6084 }, + { 0x2f9d4, 1, 6085 }, + { 0x2f9d5, 1, 6086 }, + { 0x2f9d6, 1, 6087 }, + { 0x2f9d7, 1, 6088 }, + { 0x2f9d8, 1, 6089 }, + { 0x2f9d9, 1, 6090 }, + { 0x2f9da, 1, 6091 }, + { 0x2f9db, 1, 6092 }, + { 0x2f9dc, 1, 6093 }, + { 0x2f9dd, 1, 6094 }, + { 0x2f9de, 1, 6095 }, + { 0x2f9df, 1, 6096 }, + { 0x2f9e0, 1, 6097 }, + { 0x2f9e1, 1, 6098 }, + { 0x2f9e2, 1, 6099 }, + { 0x2f9e3, 1, 6100 }, + { 0x2f9e4, 1, 6101 }, + { 0x2f9e5, 1, 6102 }, + { 0x2f9e6, 1, 6103 }, + { 0x2f9e7, 1, 6104 }, + { 0x2f9e8, 1, 6105 }, + { 0x2f9e9, 1, 6106 }, + { 0x2f9ea, 1, 6107 }, + { 0x2f9eb, 1, 6108 }, + { 0x2f9ec, 1, 6109 }, + { 0x2f9ed, 1, 6110 }, + { 0x2f9ee, 1, 6111 }, + { 0x2f9ef, 1, 6112 }, + { 0x2f9f0, 1, 6113 }, + { 0x2f9f1, 1, 6114 }, + { 0x2f9f2, 1, 6115 }, + { 0x2f9f3, 1, 6116 }, + { 0x2f9f4, 1, 6117 }, + { 0x2f9f5, 1, 6118 }, + { 0x2f9f6, 1, 6119 }, + { 0x2f9f7, 1, 6120 }, + { 0x2f9f8, 1, 6121 }, + { 0x2f9f9, 1, 6122 }, + { 0x2f9fa, 1, 6123 }, + { 0x2f9fb, 1, 6124 }, + { 0x2f9fc, 1, 6125 }, + { 0x2f9fd, 1, 6126 }, + { 0x2f9fe, 1, 6127 }, + { 0x2f9ff, 1, 6127 }, + { 0x2fa00, 1, 6128 }, + { 0x2fa01, 1, 6129 }, + { 0x2fa02, 1, 6130 }, + { 0x2fa03, 1, 6131 }, + { 0x2fa04, 1, 6132 }, + { 0x2fa05, 1, 6133 }, + { 0x2fa06, 1, 6134 }, + { 0x2fa07, 1, 6135 }, + { 0x2fa08, 1, 6136 }, + { 0x2fa09, 1, 6137 }, + { 0x2fa0a, 1, 6138 }, + { 0x2fa0b, 1, 6139 }, + { 0x2fa0c, 1, 6140 }, + { 0x2fa0d, 1, 6141 }, + { 0x2fa0e, 1, 6142 }, + { 0x2fa0f, 1, 6143 }, + { 0x2fa10, 1, 6144 }, + { 0x2fa11, 1, 6145 }, + { 0x2fa12, 1, 6146 }, + { 0x2fa13, 1, 6147 }, + { 0x2fa14, 1, 6148 }, + { 0x2fa15, 1, 2881 }, + { 0x2fa16, 1, 6149 }, + { 0x2fa17, 1, 2885 }, + { 0x2fa18, 1, 6150 }, + { 0x2fa19, 1, 6151 }, + { 0x2fa1a, 1, 6152 }, + { 0x2fa1b, 1, 6153 }, + { 0x2fa1c, 1, 2890 }, + { 0x2fa1d, 1, 6154 } +}; + +static const Unicode decomp_expansion[] = { + 0x20 /* offset 0 */ , + 0x20, 0x308 /* offset 1 */ , + 0x61 /* offset 3 */ , + 0x20, 0x304 /* offset 4 */ , + 0x32 /* offset 6 */ , + 0x33 /* offset 7 */ , + 0x20, 0x301 /* offset 8 */ , + 0x3bc /* offset 10 */ , + 0x20, 0x327 /* offset 11 */ , + 0x31 /* offset 13 */ , + 0x6f /* offset 14 */ , + 0x31, 0x2044, 0x34 /* offset 15 */ , + 0x31, 0x2044, 0x32 /* offset 18 */ , + 0x33, 0x2044, 0x34 /* offset 21 */ , + 0x41, 0x300 /* offset 24 */ , + 0x41, 0x301 /* offset 26 */ , + 0x41, 0x302 /* offset 28 */ , + 0x41, 0x303 /* offset 30 */ , + 0x41, 0x308 /* offset 32 */ , + 0x41, 0x30a /* offset 34 */ , + 0x43, 0x327 /* offset 36 */ , + 0x45, 0x300 /* offset 38 */ , + 0x45, 0x301 /* offset 40 */ , + 0x45, 0x302 /* offset 42 */ , + 0x45, 0x308 /* offset 44 */ , + 0x49, 0x300 /* offset 46 */ , + 0x49, 0x301 /* offset 48 */ , + 0x49, 0x302 /* offset 50 */ , + 0x49, 0x308 /* offset 52 */ , + 0x4e, 0x303 /* offset 54 */ , + 0x4f, 0x300 /* offset 56 */ , + 0x4f, 0x301 /* offset 58 */ , + 0x4f, 0x302 /* offset 60 */ , + 0x4f, 0x303 /* offset 62 */ , + 0x4f, 0x308 /* offset 64 */ , + 0x55, 0x300 /* offset 66 */ , + 0x55, 0x301 /* offset 68 */ , + 0x55, 0x302 /* offset 70 */ , + 0x55, 0x308 /* offset 72 */ , + 0x59, 0x301 /* offset 74 */ , + 0x61, 0x300 /* offset 76 */ , + 0x61, 0x301 /* offset 78 */ , + 0x61, 0x302 /* offset 80 */ , + 0x61, 0x303 /* offset 82 */ , + 0x61, 0x308 /* offset 84 */ , + 0x61, 0x30a /* offset 86 */ , + 0x63, 0x327 /* offset 88 */ , + 0x65, 0x300 /* offset 90 */ , + 0x65, 0x301 /* offset 92 */ , + 0x65, 0x302 /* offset 94 */ , + 0x65, 0x308 /* offset 96 */ , + 0x69, 0x300 /* offset 98 */ , + 0x69, 0x301 /* offset 100 */ , + 0x69, 0x302 /* offset 102 */ , + 0x69, 0x308 /* offset 104 */ , + 0x6e, 0x303 /* offset 106 */ , + 0x6f, 0x300 /* offset 108 */ , + 0x6f, 0x301 /* offset 110 */ , + 0x6f, 0x302 /* offset 112 */ , + 0x6f, 0x303 /* offset 114 */ , + 0x6f, 0x308 /* offset 116 */ , + 0x75, 0x300 /* offset 118 */ , + 0x75, 0x301 /* offset 120 */ , + 0x75, 0x302 /* offset 122 */ , + 0x75, 0x308 /* offset 124 */ , + 0x79, 0x301 /* offset 126 */ , + 0x79, 0x308 /* offset 128 */ , + 0x41, 0x304 /* offset 130 */ , + 0x61, 0x304 /* offset 132 */ , + 0x41, 0x306 /* offset 134 */ , + 0x61, 0x306 /* offset 136 */ , + 0x41, 0x328 /* offset 138 */ , + 0x61, 0x328 /* offset 140 */ , + 0x43, 0x301 /* offset 142 */ , + 0x63, 0x301 /* offset 144 */ , + 0x43, 0x302 /* offset 146 */ , + 0x63, 0x302 /* offset 148 */ , + 0x43, 0x307 /* offset 150 */ , + 0x63, 0x307 /* offset 152 */ , + 0x43, 0x30c /* offset 154 */ , + 0x63, 0x30c /* offset 156 */ , + 0x44, 0x30c /* offset 158 */ , + 0x64, 0x30c /* offset 160 */ , + 0x45, 0x304 /* offset 162 */ , + 0x65, 0x304 /* offset 164 */ , + 0x45, 0x306 /* offset 166 */ , + 0x65, 0x306 /* offset 168 */ , + 0x45, 0x307 /* offset 170 */ , + 0x65, 0x307 /* offset 172 */ , + 0x45, 0x328 /* offset 174 */ , + 0x65, 0x328 /* offset 176 */ , + 0x45, 0x30c /* offset 178 */ , + 0x65, 0x30c /* offset 180 */ , + 0x47, 0x302 /* offset 182 */ , + 0x67, 0x302 /* offset 184 */ , + 0x47, 0x306 /* offset 186 */ , + 0x67, 0x306 /* offset 188 */ , + 0x47, 0x307 /* offset 190 */ , + 0x67, 0x307 /* offset 192 */ , + 0x47, 0x327 /* offset 194 */ , + 0x67, 0x327 /* offset 196 */ , + 0x48, 0x302 /* offset 198 */ , + 0x68, 0x302 /* offset 200 */ , + 0x49, 0x303 /* offset 202 */ , + 0x69, 0x303 /* offset 204 */ , + 0x49, 0x304 /* offset 206 */ , + 0x69, 0x304 /* offset 208 */ , + 0x49, 0x306 /* offset 210 */ , + 0x69, 0x306 /* offset 212 */ , + 0x49, 0x328 /* offset 214 */ , + 0x69, 0x328 /* offset 216 */ , + 0x49, 0x307 /* offset 218 */ , + 0x49, 0x4a /* offset 220 */ , + 0x69, 0x6a /* offset 222 */ , + 0x4a, 0x302 /* offset 224 */ , + 0x6a, 0x302 /* offset 226 */ , + 0x4b, 0x327 /* offset 228 */ , + 0x6b, 0x327 /* offset 230 */ , + 0x4c, 0x301 /* offset 232 */ , + 0x6c, 0x301 /* offset 234 */ , + 0x4c, 0x327 /* offset 236 */ , + 0x6c, 0x327 /* offset 238 */ , + 0x4c, 0x30c /* offset 240 */ , + 0x6c, 0x30c /* offset 242 */ , + 0x4c, 0xb7 /* offset 244 */ , + 0x6c, 0xb7 /* offset 246 */ , + 0x4e, 0x301 /* offset 248 */ , + 0x6e, 0x301 /* offset 250 */ , + 0x4e, 0x327 /* offset 252 */ , + 0x6e, 0x327 /* offset 254 */ , + 0x4e, 0x30c /* offset 256 */ , + 0x6e, 0x30c /* offset 258 */ , + 0x2bc, 0x6e /* offset 260 */ , + 0x4f, 0x304 /* offset 262 */ , + 0x6f, 0x304 /* offset 264 */ , + 0x4f, 0x306 /* offset 266 */ , + 0x6f, 0x306 /* offset 268 */ , + 0x4f, 0x30b /* offset 270 */ , + 0x6f, 0x30b /* offset 272 */ , + 0x52, 0x301 /* offset 274 */ , + 0x72, 0x301 /* offset 276 */ , + 0x52, 0x327 /* offset 278 */ , + 0x72, 0x327 /* offset 280 */ , + 0x52, 0x30c /* offset 282 */ , + 0x72, 0x30c /* offset 284 */ , + 0x53, 0x301 /* offset 286 */ , + 0x73, 0x301 /* offset 288 */ , + 0x53, 0x302 /* offset 290 */ , + 0x73, 0x302 /* offset 292 */ , + 0x53, 0x327 /* offset 294 */ , + 0x73, 0x327 /* offset 296 */ , + 0x53, 0x30c /* offset 298 */ , + 0x73, 0x30c /* offset 300 */ , + 0x54, 0x327 /* offset 302 */ , + 0x74, 0x327 /* offset 304 */ , + 0x54, 0x30c /* offset 306 */ , + 0x74, 0x30c /* offset 308 */ , + 0x55, 0x303 /* offset 310 */ , + 0x75, 0x303 /* offset 312 */ , + 0x55, 0x304 /* offset 314 */ , + 0x75, 0x304 /* offset 316 */ , + 0x55, 0x306 /* offset 318 */ , + 0x75, 0x306 /* offset 320 */ , + 0x55, 0x30a /* offset 322 */ , + 0x75, 0x30a /* offset 324 */ , + 0x55, 0x30b /* offset 326 */ , + 0x75, 0x30b /* offset 328 */ , + 0x55, 0x328 /* offset 330 */ , + 0x75, 0x328 /* offset 332 */ , + 0x57, 0x302 /* offset 334 */ , + 0x77, 0x302 /* offset 336 */ , + 0x59, 0x302 /* offset 338 */ , + 0x79, 0x302 /* offset 340 */ , + 0x59, 0x308 /* offset 342 */ , + 0x5a, 0x301 /* offset 344 */ , + 0x7a, 0x301 /* offset 346 */ , + 0x5a, 0x307 /* offset 348 */ , + 0x7a, 0x307 /* offset 350 */ , + 0x5a, 0x30c /* offset 352 */ , + 0x7a, 0x30c /* offset 354 */ , + 0x73 /* offset 356 */ , + 0x4f, 0x31b /* offset 357 */ , + 0x6f, 0x31b /* offset 359 */ , + 0x55, 0x31b /* offset 361 */ , + 0x75, 0x31b /* offset 363 */ , + 0x44, 0x5a, 0x30c /* offset 365 */ , + 0x44, 0x7a, 0x30c /* offset 368 */ , + 0x64, 0x7a, 0x30c /* offset 371 */ , + 0x4c, 0x4a /* offset 374 */ , + 0x4c, 0x6a /* offset 376 */ , + 0x6c, 0x6a /* offset 378 */ , + 0x4e, 0x4a /* offset 380 */ , + 0x4e, 0x6a /* offset 382 */ , + 0x6e, 0x6a /* offset 384 */ , + 0x41, 0x30c /* offset 386 */ , + 0x61, 0x30c /* offset 388 */ , + 0x49, 0x30c /* offset 390 */ , + 0x69, 0x30c /* offset 392 */ , + 0x4f, 0x30c /* offset 394 */ , + 0x6f, 0x30c /* offset 396 */ , + 0x55, 0x30c /* offset 398 */ , + 0x75, 0x30c /* offset 400 */ , + 0x55, 0x308, 0x304 /* offset 402 */ , + 0x75, 0x308, 0x304 /* offset 405 */ , + 0x55, 0x308, 0x301 /* offset 408 */ , + 0x75, 0x308, 0x301 /* offset 411 */ , + 0x55, 0x308, 0x30c /* offset 414 */ , + 0x75, 0x308, 0x30c /* offset 417 */ , + 0x55, 0x308, 0x300 /* offset 420 */ , + 0x75, 0x308, 0x300 /* offset 423 */ , + 0x41, 0x308, 0x304 /* offset 426 */ , + 0x61, 0x308, 0x304 /* offset 429 */ , + 0x41, 0x307, 0x304 /* offset 432 */ , + 0x61, 0x307, 0x304 /* offset 435 */ , + 0xc6, 0x304 /* offset 438 */ , + 0xe6, 0x304 /* offset 440 */ , + 0x47, 0x30c /* offset 442 */ , + 0x67, 0x30c /* offset 444 */ , + 0x4b, 0x30c /* offset 446 */ , + 0x6b, 0x30c /* offset 448 */ , + 0x4f, 0x328 /* offset 450 */ , + 0x6f, 0x328 /* offset 452 */ , + 0x4f, 0x328, 0x304 /* offset 454 */ , + 0x6f, 0x328, 0x304 /* offset 457 */ , + 0x1b7, 0x30c /* offset 460 */ , + 0x292, 0x30c /* offset 462 */ , + 0x6a, 0x30c /* offset 464 */ , + 0x44, 0x5a /* offset 466 */ , + 0x44, 0x7a /* offset 468 */ , + 0x64, 0x7a /* offset 470 */ , + 0x47, 0x301 /* offset 472 */ , + 0x67, 0x301 /* offset 474 */ , + 0x4e, 0x300 /* offset 476 */ , + 0x6e, 0x300 /* offset 478 */ , + 0x41, 0x30a, 0x301 /* offset 480 */ , + 0x61, 0x30a, 0x301 /* offset 483 */ , + 0xc6, 0x301 /* offset 486 */ , + 0xe6, 0x301 /* offset 488 */ , + 0xd8, 0x301 /* offset 490 */ , + 0xf8, 0x301 /* offset 492 */ , + 0x41, 0x30f /* offset 494 */ , + 0x61, 0x30f /* offset 496 */ , + 0x41, 0x311 /* offset 498 */ , + 0x61, 0x311 /* offset 500 */ , + 0x45, 0x30f /* offset 502 */ , + 0x65, 0x30f /* offset 504 */ , + 0x45, 0x311 /* offset 506 */ , + 0x65, 0x311 /* offset 508 */ , + 0x49, 0x30f /* offset 510 */ , + 0x69, 0x30f /* offset 512 */ , + 0x49, 0x311 /* offset 514 */ , + 0x69, 0x311 /* offset 516 */ , + 0x4f, 0x30f /* offset 518 */ , + 0x6f, 0x30f /* offset 520 */ , + 0x4f, 0x311 /* offset 522 */ , + 0x6f, 0x311 /* offset 524 */ , + 0x52, 0x30f /* offset 526 */ , + 0x72, 0x30f /* offset 528 */ , + 0x52, 0x311 /* offset 530 */ , + 0x72, 0x311 /* offset 532 */ , + 0x55, 0x30f /* offset 534 */ , + 0x75, 0x30f /* offset 536 */ , + 0x55, 0x311 /* offset 538 */ , + 0x75, 0x311 /* offset 540 */ , + 0x53, 0x326 /* offset 542 */ , + 0x73, 0x326 /* offset 544 */ , + 0x54, 0x326 /* offset 546 */ , + 0x74, 0x326 /* offset 548 */ , + 0x48, 0x30c /* offset 550 */ , + 0x68, 0x30c /* offset 552 */ , + 0x41, 0x307 /* offset 554 */ , + 0x61, 0x307 /* offset 556 */ , + 0x45, 0x327 /* offset 558 */ , + 0x65, 0x327 /* offset 560 */ , + 0x4f, 0x308, 0x304 /* offset 562 */ , + 0x6f, 0x308, 0x304 /* offset 565 */ , + 0x4f, 0x303, 0x304 /* offset 568 */ , + 0x6f, 0x303, 0x304 /* offset 571 */ , + 0x4f, 0x307 /* offset 574 */ , + 0x6f, 0x307 /* offset 576 */ , + 0x4f, 0x307, 0x304 /* offset 578 */ , + 0x6f, 0x307, 0x304 /* offset 581 */ , + 0x59, 0x304 /* offset 584 */ , + 0x79, 0x304 /* offset 586 */ , + 0x68 /* offset 588 */ , + 0x266 /* offset 589 */ , + 0x6a /* offset 590 */ , + 0x72 /* offset 591 */ , + 0x279 /* offset 592 */ , + 0x27b /* offset 593 */ , + 0x281 /* offset 594 */ , + 0x77 /* offset 595 */ , + 0x79 /* offset 596 */ , + 0x20, 0x306 /* offset 597 */ , + 0x20, 0x307 /* offset 599 */ , + 0x20, 0x30a /* offset 601 */ , + 0x20, 0x328 /* offset 603 */ , + 0x20, 0x303 /* offset 605 */ , + 0x20, 0x30b /* offset 607 */ , + 0x263 /* offset 609 */ , + 0x6c /* offset 610 */ , + 0x78 /* offset 611 */ , + 0x295 /* offset 612 */ , + 0x300 /* offset 613 */ , + 0x301 /* offset 614 */ , + 0x313 /* offset 615 */ , + 0x308, 0x301 /* offset 616 */ , + 0x2b9 /* offset 618 */ , + 0x20, 0x345 /* offset 619 */ , + 0x3b /* offset 621 */ , + 0x20, 0x308, 0x301 /* offset 622 */ , + 0x391, 0x301 /* offset 625 */ , + 0xb7 /* offset 627 */ , + 0x395, 0x301 /* offset 628 */ , + 0x397, 0x301 /* offset 630 */ , + 0x399, 0x301 /* offset 632 */ , + 0x39f, 0x301 /* offset 634 */ , + 0x3a5, 0x301 /* offset 636 */ , + 0x3a9, 0x301 /* offset 638 */ , + 0x3b9, 0x308, 0x301 /* offset 640 */ , + 0x399, 0x308 /* offset 643 */ , + 0x3a5, 0x308 /* offset 645 */ , + 0x3b1, 0x301 /* offset 647 */ , + 0x3b5, 0x301 /* offset 649 */ , + 0x3b7, 0x301 /* offset 651 */ , + 0x3b9, 0x301 /* offset 653 */ , + 0x3c5, 0x308, 0x301 /* offset 655 */ , + 0x3b9, 0x308 /* offset 658 */ , + 0x3c5, 0x308 /* offset 660 */ , + 0x3bf, 0x301 /* offset 662 */ , + 0x3c5, 0x301 /* offset 664 */ , + 0x3c9, 0x301 /* offset 666 */ , + 0x3b2 /* offset 668 */ , + 0x3b8 /* offset 669 */ , + 0x3a5 /* offset 670 */ , + 0x3c6 /* offset 671 */ , + 0x3c0 /* offset 672 */ , + 0x3ba /* offset 673 */ , + 0x3c1 /* offset 674 */ , + 0x3c2 /* offset 675 */ , + 0x398 /* offset 676 */ , + 0x3b5 /* offset 677 */ , + 0x415, 0x300 /* offset 678 */ , + 0x415, 0x308 /* offset 680 */ , + 0x413, 0x301 /* offset 682 */ , + 0x406, 0x308 /* offset 684 */ , + 0x41a, 0x301 /* offset 686 */ , + 0x418, 0x300 /* offset 688 */ , + 0x423, 0x306 /* offset 690 */ , + 0x418, 0x306 /* offset 692 */ , + 0x438, 0x306 /* offset 694 */ , + 0x435, 0x300 /* offset 696 */ , + 0x435, 0x308 /* offset 698 */ , + 0x433, 0x301 /* offset 700 */ , + 0x456, 0x308 /* offset 702 */ , + 0x43a, 0x301 /* offset 704 */ , + 0x438, 0x300 /* offset 706 */ , + 0x443, 0x306 /* offset 708 */ , + 0x474, 0x30f /* offset 710 */ , + 0x475, 0x30f /* offset 712 */ , + 0x416, 0x306 /* offset 714 */ , + 0x436, 0x306 /* offset 716 */ , + 0x410, 0x306 /* offset 718 */ , + 0x430, 0x306 /* offset 720 */ , + 0x410, 0x308 /* offset 722 */ , + 0x430, 0x308 /* offset 724 */ , + 0x415, 0x306 /* offset 726 */ , + 0x435, 0x306 /* offset 728 */ , + 0x4d8, 0x308 /* offset 730 */ , + 0x4d9, 0x308 /* offset 732 */ , + 0x416, 0x308 /* offset 734 */ , + 0x436, 0x308 /* offset 736 */ , + 0x417, 0x308 /* offset 738 */ , + 0x437, 0x308 /* offset 740 */ , + 0x418, 0x304 /* offset 742 */ , + 0x438, 0x304 /* offset 744 */ , + 0x418, 0x308 /* offset 746 */ , + 0x438, 0x308 /* offset 748 */ , + 0x41e, 0x308 /* offset 750 */ , + 0x43e, 0x308 /* offset 752 */ , + 0x4e8, 0x308 /* offset 754 */ , + 0x4e9, 0x308 /* offset 756 */ , + 0x42d, 0x308 /* offset 758 */ , + 0x44d, 0x308 /* offset 760 */ , + 0x423, 0x304 /* offset 762 */ , + 0x443, 0x304 /* offset 764 */ , + 0x423, 0x308 /* offset 766 */ , + 0x443, 0x308 /* offset 768 */ , + 0x423, 0x30b /* offset 770 */ , + 0x443, 0x30b /* offset 772 */ , + 0x427, 0x308 /* offset 774 */ , + 0x447, 0x308 /* offset 776 */ , + 0x42b, 0x308 /* offset 778 */ , + 0x44b, 0x308 /* offset 780 */ , + 0x565, 0x582 /* offset 782 */ , + 0x627, 0x653 /* offset 784 */ , + 0x627, 0x654 /* offset 786 */ , + 0x648, 0x654 /* offset 788 */ , + 0x627, 0x655 /* offset 790 */ , + 0x64a, 0x654 /* offset 792 */ , + 0x627, 0x674 /* offset 794 */ , + 0x648, 0x674 /* offset 796 */ , + 0x6c7, 0x674 /* offset 798 */ , + 0x64a, 0x674 /* offset 800 */ , + 0x6d5, 0x654 /* offset 802 */ , + 0x6c1, 0x654 /* offset 804 */ , + 0x6d2, 0x654 /* offset 806 */ , + 0x928, 0x93c /* offset 808 */ , + 0x930, 0x93c /* offset 810 */ , + 0x933, 0x93c /* offset 812 */ , + 0x915, 0x93c /* offset 814 */ , + 0x916, 0x93c /* offset 816 */ , + 0x917, 0x93c /* offset 818 */ , + 0x91c, 0x93c /* offset 820 */ , + 0x921, 0x93c /* offset 822 */ , + 0x922, 0x93c /* offset 824 */ , + 0x92b, 0x93c /* offset 826 */ , + 0x92f, 0x93c /* offset 828 */ , + 0x9c7, 0x9be /* offset 830 */ , + 0x9c7, 0x9d7 /* offset 832 */ , + 0x9a1, 0x9bc /* offset 834 */ , + 0x9a2, 0x9bc /* offset 836 */ , + 0x9af, 0x9bc /* offset 838 */ , + 0xa32, 0xa3c /* offset 840 */ , + 0xa38, 0xa3c /* offset 842 */ , + 0xa16, 0xa3c /* offset 844 */ , + 0xa17, 0xa3c /* offset 846 */ , + 0xa1c, 0xa3c /* offset 848 */ , + 0xa2b, 0xa3c /* offset 850 */ , + 0xb47, 0xb56 /* offset 852 */ , + 0xb47, 0xb3e /* offset 854 */ , + 0xb47, 0xb57 /* offset 856 */ , + 0xb21, 0xb3c /* offset 858 */ , + 0xb22, 0xb3c /* offset 860 */ , + 0xb92, 0xbd7 /* offset 862 */ , + 0xbc6, 0xbbe /* offset 864 */ , + 0xbc7, 0xbbe /* offset 866 */ , + 0xbc6, 0xbd7 /* offset 868 */ , + 0xc46, 0xc56 /* offset 870 */ , + 0xcbf, 0xcd5 /* offset 872 */ , + 0xcc6, 0xcd5 /* offset 874 */ , + 0xcc6, 0xcd6 /* offset 876 */ , + 0xcc6, 0xcc2 /* offset 878 */ , + 0xcc6, 0xcc2, 0xcd5 /* offset 880 */ , + 0xd46, 0xd3e /* offset 883 */ , + 0xd47, 0xd3e /* offset 885 */ , + 0xd46, 0xd57 /* offset 887 */ , + 0xdd9, 0xdca /* offset 889 */ , + 0xdd9, 0xdcf /* offset 891 */ , + 0xdd9, 0xdcf, 0xdca /* offset 893 */ , + 0xdd9, 0xddf /* offset 896 */ , + 0xe4d, 0xe32 /* offset 898 */ , + 0xecd, 0xeb2 /* offset 900 */ , + 0xeab, 0xe99 /* offset 902 */ , + 0xeab, 0xea1 /* offset 904 */ , + 0xf0b /* offset 906 */ , + 0xf42, 0xfb7 /* offset 907 */ , + 0xf4c, 0xfb7 /* offset 909 */ , + 0xf51, 0xfb7 /* offset 911 */ , + 0xf56, 0xfb7 /* offset 913 */ , + 0xf5b, 0xfb7 /* offset 915 */ , + 0xf40, 0xfb5 /* offset 917 */ , + 0xf71, 0xf72 /* offset 919 */ , + 0xf71, 0xf74 /* offset 921 */ , + 0xfb2, 0xf80 /* offset 923 */ , + 0xfb2, 0xf71, 0xf80 /* offset 925 */ , + 0xfb3, 0xf80 /* offset 928 */ , + 0xfb3, 0xf71, 0xf80 /* offset 930 */ , + 0xf71, 0xf80 /* offset 933 */ , + 0xf92, 0xfb7 /* offset 935 */ , + 0xf9c, 0xfb7 /* offset 937 */ , + 0xfa1, 0xfb7 /* offset 939 */ , + 0xfa6, 0xfb7 /* offset 941 */ , + 0xfab, 0xfb7 /* offset 943 */ , + 0xf90, 0xfb5 /* offset 945 */ , + 0x1025, 0x102e /* offset 947 */ , + 0x41, 0x325 /* offset 949 */ , + 0x61, 0x325 /* offset 951 */ , + 0x42, 0x307 /* offset 953 */ , + 0x62, 0x307 /* offset 955 */ , + 0x42, 0x323 /* offset 957 */ , + 0x62, 0x323 /* offset 959 */ , + 0x42, 0x331 /* offset 961 */ , + 0x62, 0x331 /* offset 963 */ , + 0x43, 0x327, 0x301 /* offset 965 */ , + 0x63, 0x327, 0x301 /* offset 968 */ , + 0x44, 0x307 /* offset 971 */ , + 0x64, 0x307 /* offset 973 */ , + 0x44, 0x323 /* offset 975 */ , + 0x64, 0x323 /* offset 977 */ , + 0x44, 0x331 /* offset 979 */ , + 0x64, 0x331 /* offset 981 */ , + 0x44, 0x327 /* offset 983 */ , + 0x64, 0x327 /* offset 985 */ , + 0x44, 0x32d /* offset 987 */ , + 0x64, 0x32d /* offset 989 */ , + 0x45, 0x304, 0x300 /* offset 991 */ , + 0x65, 0x304, 0x300 /* offset 994 */ , + 0x45, 0x304, 0x301 /* offset 997 */ , + 0x65, 0x304, 0x301 /* offset 1000 */ , + 0x45, 0x32d /* offset 1003 */ , + 0x65, 0x32d /* offset 1005 */ , + 0x45, 0x330 /* offset 1007 */ , + 0x65, 0x330 /* offset 1009 */ , + 0x45, 0x327, 0x306 /* offset 1011 */ , + 0x65, 0x327, 0x306 /* offset 1014 */ , + 0x46, 0x307 /* offset 1017 */ , + 0x66, 0x307 /* offset 1019 */ , + 0x47, 0x304 /* offset 1021 */ , + 0x67, 0x304 /* offset 1023 */ , + 0x48, 0x307 /* offset 1025 */ , + 0x68, 0x307 /* offset 1027 */ , + 0x48, 0x323 /* offset 1029 */ , + 0x68, 0x323 /* offset 1031 */ , + 0x48, 0x308 /* offset 1033 */ , + 0x68, 0x308 /* offset 1035 */ , + 0x48, 0x327 /* offset 1037 */ , + 0x68, 0x327 /* offset 1039 */ , + 0x48, 0x32e /* offset 1041 */ , + 0x68, 0x32e /* offset 1043 */ , + 0x49, 0x330 /* offset 1045 */ , + 0x69, 0x330 /* offset 1047 */ , + 0x49, 0x308, 0x301 /* offset 1049 */ , + 0x69, 0x308, 0x301 /* offset 1052 */ , + 0x4b, 0x301 /* offset 1055 */ , + 0x6b, 0x301 /* offset 1057 */ , + 0x4b, 0x323 /* offset 1059 */ , + 0x6b, 0x323 /* offset 1061 */ , + 0x4b, 0x331 /* offset 1063 */ , + 0x6b, 0x331 /* offset 1065 */ , + 0x4c, 0x323 /* offset 1067 */ , + 0x6c, 0x323 /* offset 1069 */ , + 0x4c, 0x323, 0x304 /* offset 1071 */ , + 0x6c, 0x323, 0x304 /* offset 1074 */ , + 0x4c, 0x331 /* offset 1077 */ , + 0x6c, 0x331 /* offset 1079 */ , + 0x4c, 0x32d /* offset 1081 */ , + 0x6c, 0x32d /* offset 1083 */ , + 0x4d, 0x301 /* offset 1085 */ , + 0x6d, 0x301 /* offset 1087 */ , + 0x4d, 0x307 /* offset 1089 */ , + 0x6d, 0x307 /* offset 1091 */ , + 0x4d, 0x323 /* offset 1093 */ , + 0x6d, 0x323 /* offset 1095 */ , + 0x4e, 0x307 /* offset 1097 */ , + 0x6e, 0x307 /* offset 1099 */ , + 0x4e, 0x323 /* offset 1101 */ , + 0x6e, 0x323 /* offset 1103 */ , + 0x4e, 0x331 /* offset 1105 */ , + 0x6e, 0x331 /* offset 1107 */ , + 0x4e, 0x32d /* offset 1109 */ , + 0x6e, 0x32d /* offset 1111 */ , + 0x4f, 0x303, 0x301 /* offset 1113 */ , + 0x6f, 0x303, 0x301 /* offset 1116 */ , + 0x4f, 0x303, 0x308 /* offset 1119 */ , + 0x6f, 0x303, 0x308 /* offset 1122 */ , + 0x4f, 0x304, 0x300 /* offset 1125 */ , + 0x6f, 0x304, 0x300 /* offset 1128 */ , + 0x4f, 0x304, 0x301 /* offset 1131 */ , + 0x6f, 0x304, 0x301 /* offset 1134 */ , + 0x50, 0x301 /* offset 1137 */ , + 0x70, 0x301 /* offset 1139 */ , + 0x50, 0x307 /* offset 1141 */ , + 0x70, 0x307 /* offset 1143 */ , + 0x52, 0x307 /* offset 1145 */ , + 0x72, 0x307 /* offset 1147 */ , + 0x52, 0x323 /* offset 1149 */ , + 0x72, 0x323 /* offset 1151 */ , + 0x52, 0x323, 0x304 /* offset 1153 */ , + 0x72, 0x323, 0x304 /* offset 1156 */ , + 0x52, 0x331 /* offset 1159 */ , + 0x72, 0x331 /* offset 1161 */ , + 0x53, 0x307 /* offset 1163 */ , + 0x73, 0x307 /* offset 1165 */ , + 0x53, 0x323 /* offset 1167 */ , + 0x73, 0x323 /* offset 1169 */ , + 0x53, 0x301, 0x307 /* offset 1171 */ , + 0x73, 0x301, 0x307 /* offset 1174 */ , + 0x53, 0x30c, 0x307 /* offset 1177 */ , + 0x73, 0x30c, 0x307 /* offset 1180 */ , + 0x53, 0x323, 0x307 /* offset 1183 */ , + 0x73, 0x323, 0x307 /* offset 1186 */ , + 0x54, 0x307 /* offset 1189 */ , + 0x74, 0x307 /* offset 1191 */ , + 0x54, 0x323 /* offset 1193 */ , + 0x74, 0x323 /* offset 1195 */ , + 0x54, 0x331 /* offset 1197 */ , + 0x74, 0x331 /* offset 1199 */ , + 0x54, 0x32d /* offset 1201 */ , + 0x74, 0x32d /* offset 1203 */ , + 0x55, 0x324 /* offset 1205 */ , + 0x75, 0x324 /* offset 1207 */ , + 0x55, 0x330 /* offset 1209 */ , + 0x75, 0x330 /* offset 1211 */ , + 0x55, 0x32d /* offset 1213 */ , + 0x75, 0x32d /* offset 1215 */ , + 0x55, 0x303, 0x301 /* offset 1217 */ , + 0x75, 0x303, 0x301 /* offset 1220 */ , + 0x55, 0x304, 0x308 /* offset 1223 */ , + 0x75, 0x304, 0x308 /* offset 1226 */ , + 0x56, 0x303 /* offset 1229 */ , + 0x76, 0x303 /* offset 1231 */ , + 0x56, 0x323 /* offset 1233 */ , + 0x76, 0x323 /* offset 1235 */ , + 0x57, 0x300 /* offset 1237 */ , + 0x77, 0x300 /* offset 1239 */ , + 0x57, 0x301 /* offset 1241 */ , + 0x77, 0x301 /* offset 1243 */ , + 0x57, 0x308 /* offset 1245 */ , + 0x77, 0x308 /* offset 1247 */ , + 0x57, 0x307 /* offset 1249 */ , + 0x77, 0x307 /* offset 1251 */ , + 0x57, 0x323 /* offset 1253 */ , + 0x77, 0x323 /* offset 1255 */ , + 0x58, 0x307 /* offset 1257 */ , + 0x78, 0x307 /* offset 1259 */ , + 0x58, 0x308 /* offset 1261 */ , + 0x78, 0x308 /* offset 1263 */ , + 0x59, 0x307 /* offset 1265 */ , + 0x79, 0x307 /* offset 1267 */ , + 0x5a, 0x302 /* offset 1269 */ , + 0x7a, 0x302 /* offset 1271 */ , + 0x5a, 0x323 /* offset 1273 */ , + 0x7a, 0x323 /* offset 1275 */ , + 0x5a, 0x331 /* offset 1277 */ , + 0x7a, 0x331 /* offset 1279 */ , + 0x68, 0x331 /* offset 1281 */ , + 0x74, 0x308 /* offset 1283 */ , + 0x77, 0x30a /* offset 1285 */ , + 0x79, 0x30a /* offset 1287 */ , + 0x61, 0x2be /* offset 1289 */ , + 0x41, 0x323 /* offset 1291 */ , + 0x61, 0x323 /* offset 1293 */ , + 0x41, 0x309 /* offset 1295 */ , + 0x61, 0x309 /* offset 1297 */ , + 0x41, 0x302, 0x301 /* offset 1299 */ , + 0x61, 0x302, 0x301 /* offset 1302 */ , + 0x41, 0x302, 0x300 /* offset 1305 */ , + 0x61, 0x302, 0x300 /* offset 1308 */ , + 0x41, 0x302, 0x309 /* offset 1311 */ , + 0x61, 0x302, 0x309 /* offset 1314 */ , + 0x41, 0x302, 0x303 /* offset 1317 */ , + 0x61, 0x302, 0x303 /* offset 1320 */ , + 0x41, 0x323, 0x302 /* offset 1323 */ , + 0x61, 0x323, 0x302 /* offset 1326 */ , + 0x41, 0x306, 0x301 /* offset 1329 */ , + 0x61, 0x306, 0x301 /* offset 1332 */ , + 0x41, 0x306, 0x300 /* offset 1335 */ , + 0x61, 0x306, 0x300 /* offset 1338 */ , + 0x41, 0x306, 0x309 /* offset 1341 */ , + 0x61, 0x306, 0x309 /* offset 1344 */ , + 0x41, 0x306, 0x303 /* offset 1347 */ , + 0x61, 0x306, 0x303 /* offset 1350 */ , + 0x41, 0x323, 0x306 /* offset 1353 */ , + 0x61, 0x323, 0x306 /* offset 1356 */ , + 0x45, 0x323 /* offset 1359 */ , + 0x65, 0x323 /* offset 1361 */ , + 0x45, 0x309 /* offset 1363 */ , + 0x65, 0x309 /* offset 1365 */ , + 0x45, 0x303 /* offset 1367 */ , + 0x65, 0x303 /* offset 1369 */ , + 0x45, 0x302, 0x301 /* offset 1371 */ , + 0x65, 0x302, 0x301 /* offset 1374 */ , + 0x45, 0x302, 0x300 /* offset 1377 */ , + 0x65, 0x302, 0x300 /* offset 1380 */ , + 0x45, 0x302, 0x309 /* offset 1383 */ , + 0x65, 0x302, 0x309 /* offset 1386 */ , + 0x45, 0x302, 0x303 /* offset 1389 */ , + 0x65, 0x302, 0x303 /* offset 1392 */ , + 0x45, 0x323, 0x302 /* offset 1395 */ , + 0x65, 0x323, 0x302 /* offset 1398 */ , + 0x49, 0x309 /* offset 1401 */ , + 0x69, 0x309 /* offset 1403 */ , + 0x49, 0x323 /* offset 1405 */ , + 0x69, 0x323 /* offset 1407 */ , + 0x4f, 0x323 /* offset 1409 */ , + 0x6f, 0x323 /* offset 1411 */ , + 0x4f, 0x309 /* offset 1413 */ , + 0x6f, 0x309 /* offset 1415 */ , + 0x4f, 0x302, 0x301 /* offset 1417 */ , + 0x6f, 0x302, 0x301 /* offset 1420 */ , + 0x4f, 0x302, 0x300 /* offset 1423 */ , + 0x6f, 0x302, 0x300 /* offset 1426 */ , + 0x4f, 0x302, 0x309 /* offset 1429 */ , + 0x6f, 0x302, 0x309 /* offset 1432 */ , + 0x4f, 0x302, 0x303 /* offset 1435 */ , + 0x6f, 0x302, 0x303 /* offset 1438 */ , + 0x4f, 0x323, 0x302 /* offset 1441 */ , + 0x6f, 0x323, 0x302 /* offset 1444 */ , + 0x4f, 0x31b, 0x301 /* offset 1447 */ , + 0x6f, 0x31b, 0x301 /* offset 1450 */ , + 0x4f, 0x31b, 0x300 /* offset 1453 */ , + 0x6f, 0x31b, 0x300 /* offset 1456 */ , + 0x4f, 0x31b, 0x309 /* offset 1459 */ , + 0x6f, 0x31b, 0x309 /* offset 1462 */ , + 0x4f, 0x31b, 0x303 /* offset 1465 */ , + 0x6f, 0x31b, 0x303 /* offset 1468 */ , + 0x4f, 0x31b, 0x323 /* offset 1471 */ , + 0x6f, 0x31b, 0x323 /* offset 1474 */ , + 0x55, 0x323 /* offset 1477 */ , + 0x75, 0x323 /* offset 1479 */ , + 0x55, 0x309 /* offset 1481 */ , + 0x75, 0x309 /* offset 1483 */ , + 0x55, 0x31b, 0x301 /* offset 1485 */ , + 0x75, 0x31b, 0x301 /* offset 1488 */ , + 0x55, 0x31b, 0x300 /* offset 1491 */ , + 0x75, 0x31b, 0x300 /* offset 1494 */ , + 0x55, 0x31b, 0x309 /* offset 1497 */ , + 0x75, 0x31b, 0x309 /* offset 1500 */ , + 0x55, 0x31b, 0x303 /* offset 1503 */ , + 0x75, 0x31b, 0x303 /* offset 1506 */ , + 0x55, 0x31b, 0x323 /* offset 1509 */ , + 0x75, 0x31b, 0x323 /* offset 1512 */ , + 0x59, 0x300 /* offset 1515 */ , + 0x79, 0x300 /* offset 1517 */ , + 0x59, 0x323 /* offset 1519 */ , + 0x79, 0x323 /* offset 1521 */ , + 0x59, 0x309 /* offset 1523 */ , + 0x79, 0x309 /* offset 1525 */ , + 0x59, 0x303 /* offset 1527 */ , + 0x79, 0x303 /* offset 1529 */ , + 0x3b1, 0x313 /* offset 1531 */ , + 0x3b1, 0x314 /* offset 1533 */ , + 0x3b1, 0x313, 0x300 /* offset 1535 */ , + 0x3b1, 0x314, 0x300 /* offset 1538 */ , + 0x3b1, 0x313, 0x301 /* offset 1541 */ , + 0x3b1, 0x314, 0x301 /* offset 1544 */ , + 0x3b1, 0x313, 0x342 /* offset 1547 */ , + 0x3b1, 0x314, 0x342 /* offset 1550 */ , + 0x391, 0x313 /* offset 1553 */ , + 0x391, 0x314 /* offset 1555 */ , + 0x391, 0x313, 0x300 /* offset 1557 */ , + 0x391, 0x314, 0x300 /* offset 1560 */ , + 0x391, 0x313, 0x301 /* offset 1563 */ , + 0x391, 0x314, 0x301 /* offset 1566 */ , + 0x391, 0x313, 0x342 /* offset 1569 */ , + 0x391, 0x314, 0x342 /* offset 1572 */ , + 0x3b5, 0x313 /* offset 1575 */ , + 0x3b5, 0x314 /* offset 1577 */ , + 0x3b5, 0x313, 0x300 /* offset 1579 */ , + 0x3b5, 0x314, 0x300 /* offset 1582 */ , + 0x3b5, 0x313, 0x301 /* offset 1585 */ , + 0x3b5, 0x314, 0x301 /* offset 1588 */ , + 0x395, 0x313 /* offset 1591 */ , + 0x395, 0x314 /* offset 1593 */ , + 0x395, 0x313, 0x300 /* offset 1595 */ , + 0x395, 0x314, 0x300 /* offset 1598 */ , + 0x395, 0x313, 0x301 /* offset 1601 */ , + 0x395, 0x314, 0x301 /* offset 1604 */ , + 0x3b7, 0x313 /* offset 1607 */ , + 0x3b7, 0x314 /* offset 1609 */ , + 0x3b7, 0x313, 0x300 /* offset 1611 */ , + 0x3b7, 0x314, 0x300 /* offset 1614 */ , + 0x3b7, 0x313, 0x301 /* offset 1617 */ , + 0x3b7, 0x314, 0x301 /* offset 1620 */ , + 0x3b7, 0x313, 0x342 /* offset 1623 */ , + 0x3b7, 0x314, 0x342 /* offset 1626 */ , + 0x397, 0x313 /* offset 1629 */ , + 0x397, 0x314 /* offset 1631 */ , + 0x397, 0x313, 0x300 /* offset 1633 */ , + 0x397, 0x314, 0x300 /* offset 1636 */ , + 0x397, 0x313, 0x301 /* offset 1639 */ , + 0x397, 0x314, 0x301 /* offset 1642 */ , + 0x397, 0x313, 0x342 /* offset 1645 */ , + 0x397, 0x314, 0x342 /* offset 1648 */ , + 0x3b9, 0x313 /* offset 1651 */ , + 0x3b9, 0x314 /* offset 1653 */ , + 0x3b9, 0x313, 0x300 /* offset 1655 */ , + 0x3b9, 0x314, 0x300 /* offset 1658 */ , + 0x3b9, 0x313, 0x301 /* offset 1661 */ , + 0x3b9, 0x314, 0x301 /* offset 1664 */ , + 0x3b9, 0x313, 0x342 /* offset 1667 */ , + 0x3b9, 0x314, 0x342 /* offset 1670 */ , + 0x399, 0x313 /* offset 1673 */ , + 0x399, 0x314 /* offset 1675 */ , + 0x399, 0x313, 0x300 /* offset 1677 */ , + 0x399, 0x314, 0x300 /* offset 1680 */ , + 0x399, 0x313, 0x301 /* offset 1683 */ , + 0x399, 0x314, 0x301 /* offset 1686 */ , + 0x399, 0x313, 0x342 /* offset 1689 */ , + 0x399, 0x314, 0x342 /* offset 1692 */ , + 0x3bf, 0x313 /* offset 1695 */ , + 0x3bf, 0x314 /* offset 1697 */ , + 0x3bf, 0x313, 0x300 /* offset 1699 */ , + 0x3bf, 0x314, 0x300 /* offset 1702 */ , + 0x3bf, 0x313, 0x301 /* offset 1705 */ , + 0x3bf, 0x314, 0x301 /* offset 1708 */ , + 0x39f, 0x313 /* offset 1711 */ , + 0x39f, 0x314 /* offset 1713 */ , + 0x39f, 0x313, 0x300 /* offset 1715 */ , + 0x39f, 0x314, 0x300 /* offset 1718 */ , + 0x39f, 0x313, 0x301 /* offset 1721 */ , + 0x39f, 0x314, 0x301 /* offset 1724 */ , + 0x3c5, 0x313 /* offset 1727 */ , + 0x3c5, 0x314 /* offset 1729 */ , + 0x3c5, 0x313, 0x300 /* offset 1731 */ , + 0x3c5, 0x314, 0x300 /* offset 1734 */ , + 0x3c5, 0x313, 0x301 /* offset 1737 */ , + 0x3c5, 0x314, 0x301 /* offset 1740 */ , + 0x3c5, 0x313, 0x342 /* offset 1743 */ , + 0x3c5, 0x314, 0x342 /* offset 1746 */ , + 0x3a5, 0x314 /* offset 1749 */ , + 0x3a5, 0x314, 0x300 /* offset 1751 */ , + 0x3a5, 0x314, 0x301 /* offset 1754 */ , + 0x3a5, 0x314, 0x342 /* offset 1757 */ , + 0x3c9, 0x313 /* offset 1760 */ , + 0x3c9, 0x314 /* offset 1762 */ , + 0x3c9, 0x313, 0x300 /* offset 1764 */ , + 0x3c9, 0x314, 0x300 /* offset 1767 */ , + 0x3c9, 0x313, 0x301 /* offset 1770 */ , + 0x3c9, 0x314, 0x301 /* offset 1773 */ , + 0x3c9, 0x313, 0x342 /* offset 1776 */ , + 0x3c9, 0x314, 0x342 /* offset 1779 */ , + 0x3a9, 0x313 /* offset 1782 */ , + 0x3a9, 0x314 /* offset 1784 */ , + 0x3a9, 0x313, 0x300 /* offset 1786 */ , + 0x3a9, 0x314, 0x300 /* offset 1789 */ , + 0x3a9, 0x313, 0x301 /* offset 1792 */ , + 0x3a9, 0x314, 0x301 /* offset 1795 */ , + 0x3a9, 0x313, 0x342 /* offset 1798 */ , + 0x3a9, 0x314, 0x342 /* offset 1801 */ , + 0x3b1, 0x300 /* offset 1804 */ , + 0x3b5, 0x300 /* offset 1806 */ , + 0x3b7, 0x300 /* offset 1808 */ , + 0x3b9, 0x300 /* offset 1810 */ , + 0x3bf, 0x300 /* offset 1812 */ , + 0x3c5, 0x300 /* offset 1814 */ , + 0x3c9, 0x300 /* offset 1816 */ , + 0x3b1, 0x313, 0x345 /* offset 1818 */ , + 0x3b1, 0x314, 0x345 /* offset 1821 */ , + 0x3b1, 0x313, 0x300, 0x345 /* offset 1824 */ , + 0x3b1, 0x314, 0x300, 0x345 /* offset 1828 */ , + 0x3b1, 0x313, 0x301, 0x345 /* offset 1832 */ , + 0x3b1, 0x314, 0x301, 0x345 /* offset 1836 */ , + 0x3b1, 0x313, 0x342, 0x345 /* offset 1840 */ , + 0x3b1, 0x314, 0x342, 0x345 /* offset 1844 */ , + 0x391, 0x313, 0x345 /* offset 1848 */ , + 0x391, 0x314, 0x345 /* offset 1851 */ , + 0x391, 0x313, 0x300, 0x345 /* offset 1854 */ , + 0x391, 0x314, 0x300, 0x345 /* offset 1858 */ , + 0x391, 0x313, 0x301, 0x345 /* offset 1862 */ , + 0x391, 0x314, 0x301, 0x345 /* offset 1866 */ , + 0x391, 0x313, 0x342, 0x345 /* offset 1870 */ , + 0x391, 0x314, 0x342, 0x345 /* offset 1874 */ , + 0x3b7, 0x313, 0x345 /* offset 1878 */ , + 0x3b7, 0x314, 0x345 /* offset 1881 */ , + 0x3b7, 0x313, 0x300, 0x345 /* offset 1884 */ , + 0x3b7, 0x314, 0x300, 0x345 /* offset 1888 */ , + 0x3b7, 0x313, 0x301, 0x345 /* offset 1892 */ , + 0x3b7, 0x314, 0x301, 0x345 /* offset 1896 */ , + 0x3b7, 0x313, 0x342, 0x345 /* offset 1900 */ , + 0x3b7, 0x314, 0x342, 0x345 /* offset 1904 */ , + 0x397, 0x313, 0x345 /* offset 1908 */ , + 0x397, 0x314, 0x345 /* offset 1911 */ , + 0x397, 0x313, 0x300, 0x345 /* offset 1914 */ , + 0x397, 0x314, 0x300, 0x345 /* offset 1918 */ , + 0x397, 0x313, 0x301, 0x345 /* offset 1922 */ , + 0x397, 0x314, 0x301, 0x345 /* offset 1926 */ , + 0x397, 0x313, 0x342, 0x345 /* offset 1930 */ , + 0x397, 0x314, 0x342, 0x345 /* offset 1934 */ , + 0x3c9, 0x313, 0x345 /* offset 1938 */ , + 0x3c9, 0x314, 0x345 /* offset 1941 */ , + 0x3c9, 0x313, 0x300, 0x345 /* offset 1944 */ , + 0x3c9, 0x314, 0x300, 0x345 /* offset 1948 */ , + 0x3c9, 0x313, 0x301, 0x345 /* offset 1952 */ , + 0x3c9, 0x314, 0x301, 0x345 /* offset 1956 */ , + 0x3c9, 0x313, 0x342, 0x345 /* offset 1960 */ , + 0x3c9, 0x314, 0x342, 0x345 /* offset 1964 */ , + 0x3a9, 0x313, 0x345 /* offset 1968 */ , + 0x3a9, 0x314, 0x345 /* offset 1971 */ , + 0x3a9, 0x313, 0x300, 0x345 /* offset 1974 */ , + 0x3a9, 0x314, 0x300, 0x345 /* offset 1978 */ , + 0x3a9, 0x313, 0x301, 0x345 /* offset 1982 */ , + 0x3a9, 0x314, 0x301, 0x345 /* offset 1986 */ , + 0x3a9, 0x313, 0x342, 0x345 /* offset 1990 */ , + 0x3a9, 0x314, 0x342, 0x345 /* offset 1994 */ , + 0x3b1, 0x306 /* offset 1998 */ , + 0x3b1, 0x304 /* offset 2000 */ , + 0x3b1, 0x300, 0x345 /* offset 2002 */ , + 0x3b1, 0x345 /* offset 2005 */ , + 0x3b1, 0x301, 0x345 /* offset 2007 */ , + 0x3b1, 0x342 /* offset 2010 */ , + 0x3b1, 0x342, 0x345 /* offset 2012 */ , + 0x391, 0x306 /* offset 2015 */ , + 0x391, 0x304 /* offset 2017 */ , + 0x391, 0x300 /* offset 2019 */ , + 0x391, 0x345 /* offset 2021 */ , + 0x20, 0x313 /* offset 2023 */ , + 0x3b9 /* offset 2025 */ , + 0x20, 0x342 /* offset 2026 */ , + 0x20, 0x308, 0x342 /* offset 2028 */ , + 0x3b7, 0x300, 0x345 /* offset 2031 */ , + 0x3b7, 0x345 /* offset 2034 */ , + 0x3b7, 0x301, 0x345 /* offset 2036 */ , + 0x3b7, 0x342 /* offset 2039 */ , + 0x3b7, 0x342, 0x345 /* offset 2041 */ , + 0x395, 0x300 /* offset 2044 */ , + 0x397, 0x300 /* offset 2046 */ , + 0x397, 0x345 /* offset 2048 */ , + 0x20, 0x313, 0x300 /* offset 2050 */ , + 0x20, 0x313, 0x301 /* offset 2053 */ , + 0x20, 0x313, 0x342 /* offset 2056 */ , + 0x3b9, 0x306 /* offset 2059 */ , + 0x3b9, 0x304 /* offset 2061 */ , + 0x3b9, 0x308, 0x300 /* offset 2063 */ , + 0x3b9, 0x342 /* offset 2066 */ , + 0x3b9, 0x308, 0x342 /* offset 2068 */ , + 0x399, 0x306 /* offset 2071 */ , + 0x399, 0x304 /* offset 2073 */ , + 0x399, 0x300 /* offset 2075 */ , + 0x20, 0x314, 0x300 /* offset 2077 */ , + 0x20, 0x314, 0x301 /* offset 2080 */ , + 0x20, 0x314, 0x342 /* offset 2083 */ , + 0x3c5, 0x306 /* offset 2086 */ , + 0x3c5, 0x304 /* offset 2088 */ , + 0x3c5, 0x308, 0x300 /* offset 2090 */ , + 0x3c1, 0x313 /* offset 2093 */ , + 0x3c1, 0x314 /* offset 2095 */ , + 0x3c5, 0x342 /* offset 2097 */ , + 0x3c5, 0x308, 0x342 /* offset 2099 */ , + 0x3a5, 0x306 /* offset 2102 */ , + 0x3a5, 0x304 /* offset 2104 */ , + 0x3a5, 0x300 /* offset 2106 */ , + 0x3a1, 0x314 /* offset 2108 */ , + 0x20, 0x308, 0x300 /* offset 2110 */ , + 0x60 /* offset 2113 */ , + 0x3c9, 0x300, 0x345 /* offset 2114 */ , + 0x3c9, 0x345 /* offset 2117 */ , + 0x3c9, 0x301, 0x345 /* offset 2119 */ , + 0x3c9, 0x342 /* offset 2122 */ , + 0x3c9, 0x342, 0x345 /* offset 2124 */ , + 0x39f, 0x300 /* offset 2127 */ , + 0x3a9, 0x300 /* offset 2129 */ , + 0x3a9, 0x345 /* offset 2131 */ , + 0x20, 0x314 /* offset 2133 */ , + 0x2010 /* offset 2135 */ , + 0x20, 0x333 /* offset 2136 */ , + 0x2e /* offset 2138 */ , + 0x2e, 0x2e /* offset 2139 */ , + 0x2e, 0x2e, 0x2e /* offset 2141 */ , + 0x2032, 0x2032 /* offset 2144 */ , + 0x2032, 0x2032, 0x2032 /* offset 2146 */ , + 0x2035, 0x2035 /* offset 2149 */ , + 0x2035, 0x2035, 0x2035 /* offset 2151 */ , + 0x21, 0x21 /* offset 2154 */ , + 0x20, 0x305 /* offset 2156 */ , + 0x3f, 0x3f /* offset 2158 */ , + 0x3f, 0x21 /* offset 2160 */ , + 0x21, 0x3f /* offset 2162 */ , + 0x2032, 0x2032, 0x2032, 0x2032 /* offset 2164 */ , + 0x30 /* offset 2168 */ , + 0x69 /* offset 2169 */ , + 0x34 /* offset 2170 */ , + 0x35 /* offset 2171 */ , + 0x36 /* offset 2172 */ , + 0x37 /* offset 2173 */ , + 0x38 /* offset 2174 */ , + 0x39 /* offset 2175 */ , + 0x2b /* offset 2176 */ , + 0x2212 /* offset 2177 */ , + 0x3d /* offset 2178 */ , + 0x28 /* offset 2179 */ , + 0x29 /* offset 2180 */ , + 0x6e /* offset 2181 */ , + 0x52, 0x73 /* offset 2182 */ , + 0x61, 0x2f, 0x63 /* offset 2184 */ , + 0x61, 0x2f, 0x73 /* offset 2187 */ , + 0x43 /* offset 2190 */ , + 0xb0, 0x43 /* offset 2191 */ , + 0x63, 0x2f, 0x6f /* offset 2193 */ , + 0x63, 0x2f, 0x75 /* offset 2196 */ , + 0x190 /* offset 2199 */ , + 0xb0, 0x46 /* offset 2200 */ , + 0x67 /* offset 2202 */ , + 0x48 /* offset 2203 */ , + 0x127 /* offset 2204 */ , + 0x49 /* offset 2205 */ , + 0x4c /* offset 2206 */ , + 0x4e /* offset 2207 */ , + 0x4e, 0x6f /* offset 2208 */ , + 0x50 /* offset 2210 */ , + 0x51 /* offset 2211 */ , + 0x52 /* offset 2212 */ , + 0x53, 0x4d /* offset 2213 */ , + 0x54, 0x45, 0x4c /* offset 2215 */ , + 0x54, 0x4d /* offset 2218 */ , + 0x5a /* offset 2220 */ , + 0x3a9 /* offset 2221 */ , + 0x4b /* offset 2222 */ , + 0x42 /* offset 2223 */ , + 0x65 /* offset 2224 */ , + 0x45 /* offset 2225 */ , + 0x46 /* offset 2226 */ , + 0x4d /* offset 2227 */ , + 0x5d0 /* offset 2228 */ , + 0x5d1 /* offset 2229 */ , + 0x5d2 /* offset 2230 */ , + 0x5d3 /* offset 2231 */ , + 0x3b3 /* offset 2232 */ , + 0x393 /* offset 2233 */ , + 0x3a0 /* offset 2234 */ , + 0x2211 /* offset 2235 */ , + 0x44 /* offset 2236 */ , + 0x64 /* offset 2237 */ , + 0x31, 0x2044, 0x33 /* offset 2238 */ , + 0x32, 0x2044, 0x33 /* offset 2241 */ , + 0x31, 0x2044, 0x35 /* offset 2244 */ , + 0x32, 0x2044, 0x35 /* offset 2247 */ , + 0x33, 0x2044, 0x35 /* offset 2250 */ , + 0x34, 0x2044, 0x35 /* offset 2253 */ , + 0x31, 0x2044, 0x36 /* offset 2256 */ , + 0x35, 0x2044, 0x36 /* offset 2259 */ , + 0x31, 0x2044, 0x38 /* offset 2262 */ , + 0x33, 0x2044, 0x38 /* offset 2265 */ , + 0x35, 0x2044, 0x38 /* offset 2268 */ , + 0x37, 0x2044, 0x38 /* offset 2271 */ , + 0x31, 0x2044 /* offset 2274 */ , + 0x49, 0x49 /* offset 2276 */ , + 0x49, 0x49, 0x49 /* offset 2278 */ , + 0x49, 0x56 /* offset 2281 */ , + 0x56 /* offset 2283 */ , + 0x56, 0x49 /* offset 2284 */ , + 0x56, 0x49, 0x49 /* offset 2286 */ , + 0x56, 0x49, 0x49, 0x49 /* offset 2289 */ , + 0x49, 0x58 /* offset 2293 */ , + 0x58 /* offset 2295 */ , + 0x58, 0x49 /* offset 2296 */ , + 0x58, 0x49, 0x49 /* offset 2298 */ , + 0x69, 0x69 /* offset 2301 */ , + 0x69, 0x69, 0x69 /* offset 2303 */ , + 0x69, 0x76 /* offset 2306 */ , + 0x76 /* offset 2308 */ , + 0x76, 0x69 /* offset 2309 */ , + 0x76, 0x69, 0x69 /* offset 2311 */ , + 0x76, 0x69, 0x69, 0x69 /* offset 2314 */ , + 0x69, 0x78 /* offset 2318 */ , + 0x78, 0x69 /* offset 2320 */ , + 0x78, 0x69, 0x69 /* offset 2322 */ , + 0x63 /* offset 2325 */ , + 0x6d /* offset 2326 */ , + 0x2190, 0x338 /* offset 2327 */ , + 0x2192, 0x338 /* offset 2329 */ , + 0x2194, 0x338 /* offset 2331 */ , + 0x21d0, 0x338 /* offset 2333 */ , + 0x21d4, 0x338 /* offset 2335 */ , + 0x21d2, 0x338 /* offset 2337 */ , + 0x2203, 0x338 /* offset 2339 */ , + 0x2208, 0x338 /* offset 2341 */ , + 0x220b, 0x338 /* offset 2343 */ , + 0x2223, 0x338 /* offset 2345 */ , + 0x2225, 0x338 /* offset 2347 */ , + 0x222b, 0x222b /* offset 2349 */ , + 0x222b, 0x222b, 0x222b /* offset 2351 */ , + 0x222e, 0x222e /* offset 2354 */ , + 0x222e, 0x222e, 0x222e /* offset 2356 */ , + 0x223c, 0x338 /* offset 2359 */ , + 0x2243, 0x338 /* offset 2361 */ , + 0x2245, 0x338 /* offset 2363 */ , + 0x2248, 0x338 /* offset 2365 */ , + 0x3d, 0x338 /* offset 2367 */ , + 0x2261, 0x338 /* offset 2369 */ , + 0x224d, 0x338 /* offset 2371 */ , + 0x3c, 0x338 /* offset 2373 */ , + 0x3e, 0x338 /* offset 2375 */ , + 0x2264, 0x338 /* offset 2377 */ , + 0x2265, 0x338 /* offset 2379 */ , + 0x2272, 0x338 /* offset 2381 */ , + 0x2273, 0x338 /* offset 2383 */ , + 0x2276, 0x338 /* offset 2385 */ , + 0x2277, 0x338 /* offset 2387 */ , + 0x227a, 0x338 /* offset 2389 */ , + 0x227b, 0x338 /* offset 2391 */ , + 0x2282, 0x338 /* offset 2393 */ , + 0x2283, 0x338 /* offset 2395 */ , + 0x2286, 0x338 /* offset 2397 */ , + 0x2287, 0x338 /* offset 2399 */ , + 0x22a2, 0x338 /* offset 2401 */ , + 0x22a8, 0x338 /* offset 2403 */ , + 0x22a9, 0x338 /* offset 2405 */ , + 0x22ab, 0x338 /* offset 2407 */ , + 0x227c, 0x338 /* offset 2409 */ , + 0x227d, 0x338 /* offset 2411 */ , + 0x2291, 0x338 /* offset 2413 */ , + 0x2292, 0x338 /* offset 2415 */ , + 0x22b2, 0x338 /* offset 2417 */ , + 0x22b3, 0x338 /* offset 2419 */ , + 0x22b4, 0x338 /* offset 2421 */ , + 0x22b5, 0x338 /* offset 2423 */ , + 0x3008 /* offset 2425 */ , + 0x3009 /* offset 2426 */ , + 0x31, 0x30 /* offset 2427 */ , + 0x31, 0x31 /* offset 2429 */ , + 0x31, 0x32 /* offset 2431 */ , + 0x31, 0x33 /* offset 2433 */ , + 0x31, 0x34 /* offset 2435 */ , + 0x31, 0x35 /* offset 2437 */ , + 0x31, 0x36 /* offset 2439 */ , + 0x31, 0x37 /* offset 2441 */ , + 0x31, 0x38 /* offset 2443 */ , + 0x31, 0x39 /* offset 2445 */ , + 0x32, 0x30 /* offset 2447 */ , + 0x28, 0x31, 0x29 /* offset 2449 */ , + 0x28, 0x32, 0x29 /* offset 2452 */ , + 0x28, 0x33, 0x29 /* offset 2455 */ , + 0x28, 0x34, 0x29 /* offset 2458 */ , + 0x28, 0x35, 0x29 /* offset 2461 */ , + 0x28, 0x36, 0x29 /* offset 2464 */ , + 0x28, 0x37, 0x29 /* offset 2467 */ , + 0x28, 0x38, 0x29 /* offset 2470 */ , + 0x28, 0x39, 0x29 /* offset 2473 */ , + 0x28, 0x31, 0x30, 0x29 /* offset 2476 */ , + 0x28, 0x31, 0x31, 0x29 /* offset 2480 */ , + 0x28, 0x31, 0x32, 0x29 /* offset 2484 */ , + 0x28, 0x31, 0x33, 0x29 /* offset 2488 */ , + 0x28, 0x31, 0x34, 0x29 /* offset 2492 */ , + 0x28, 0x31, 0x35, 0x29 /* offset 2496 */ , + 0x28, 0x31, 0x36, 0x29 /* offset 2500 */ , + 0x28, 0x31, 0x37, 0x29 /* offset 2504 */ , + 0x28, 0x31, 0x38, 0x29 /* offset 2508 */ , + 0x28, 0x31, 0x39, 0x29 /* offset 2512 */ , + 0x28, 0x32, 0x30, 0x29 /* offset 2516 */ , + 0x31, 0x2e /* offset 2520 */ , + 0x32, 0x2e /* offset 2522 */ , + 0x33, 0x2e /* offset 2524 */ , + 0x34, 0x2e /* offset 2526 */ , + 0x35, 0x2e /* offset 2528 */ , + 0x36, 0x2e /* offset 2530 */ , + 0x37, 0x2e /* offset 2532 */ , + 0x38, 0x2e /* offset 2534 */ , + 0x39, 0x2e /* offset 2536 */ , + 0x31, 0x30, 0x2e /* offset 2538 */ , + 0x31, 0x31, 0x2e /* offset 2541 */ , + 0x31, 0x32, 0x2e /* offset 2544 */ , + 0x31, 0x33, 0x2e /* offset 2547 */ , + 0x31, 0x34, 0x2e /* offset 2550 */ , + 0x31, 0x35, 0x2e /* offset 2553 */ , + 0x31, 0x36, 0x2e /* offset 2556 */ , + 0x31, 0x37, 0x2e /* offset 2559 */ , + 0x31, 0x38, 0x2e /* offset 2562 */ , + 0x31, 0x39, 0x2e /* offset 2565 */ , + 0x32, 0x30, 0x2e /* offset 2568 */ , + 0x28, 0x61, 0x29 /* offset 2571 */ , + 0x28, 0x62, 0x29 /* offset 2574 */ , + 0x28, 0x63, 0x29 /* offset 2577 */ , + 0x28, 0x64, 0x29 /* offset 2580 */ , + 0x28, 0x65, 0x29 /* offset 2583 */ , + 0x28, 0x66, 0x29 /* offset 2586 */ , + 0x28, 0x67, 0x29 /* offset 2589 */ , + 0x28, 0x68, 0x29 /* offset 2592 */ , + 0x28, 0x69, 0x29 /* offset 2595 */ , + 0x28, 0x6a, 0x29 /* offset 2598 */ , + 0x28, 0x6b, 0x29 /* offset 2601 */ , + 0x28, 0x6c, 0x29 /* offset 2604 */ , + 0x28, 0x6d, 0x29 /* offset 2607 */ , + 0x28, 0x6e, 0x29 /* offset 2610 */ , + 0x28, 0x6f, 0x29 /* offset 2613 */ , + 0x28, 0x70, 0x29 /* offset 2616 */ , + 0x28, 0x71, 0x29 /* offset 2619 */ , + 0x28, 0x72, 0x29 /* offset 2622 */ , + 0x28, 0x73, 0x29 /* offset 2625 */ , + 0x28, 0x74, 0x29 /* offset 2628 */ , + 0x28, 0x75, 0x29 /* offset 2631 */ , + 0x28, 0x76, 0x29 /* offset 2634 */ , + 0x28, 0x77, 0x29 /* offset 2637 */ , + 0x28, 0x78, 0x29 /* offset 2640 */ , + 0x28, 0x79, 0x29 /* offset 2643 */ , + 0x28, 0x7a, 0x29 /* offset 2646 */ , + 0x41 /* offset 2649 */ , + 0x47 /* offset 2650 */ , + 0x4a /* offset 2651 */ , + 0x4f /* offset 2652 */ , + 0x53 /* offset 2653 */ , + 0x54 /* offset 2654 */ , + 0x55 /* offset 2655 */ , + 0x57 /* offset 2656 */ , + 0x59 /* offset 2657 */ , + 0x62 /* offset 2658 */ , + 0x66 /* offset 2659 */ , + 0x6b /* offset 2660 */ , + 0x70 /* offset 2661 */ , + 0x71 /* offset 2662 */ , + 0x74 /* offset 2663 */ , + 0x75 /* offset 2664 */ , + 0x7a /* offset 2665 */ , + 0x222b, 0x222b, 0x222b, 0x222b /* offset 2666 */ , + 0x3a, 0x3a, 0x3d /* offset 2670 */ , + 0x3d, 0x3d /* offset 2673 */ , + 0x3d, 0x3d, 0x3d /* offset 2675 */ , + 0x2add, 0x338 /* offset 2678 */ , + 0x6bcd /* offset 2680 */ , + 0x9f9f /* offset 2681 */ , + 0x4e00 /* offset 2682 */ , + 0x4e28 /* offset 2683 */ , + 0x4e36 /* offset 2684 */ , + 0x4e3f /* offset 2685 */ , + 0x4e59 /* offset 2686 */ , + 0x4e85 /* offset 2687 */ , + 0x4e8c /* offset 2688 */ , + 0x4ea0 /* offset 2689 */ , + 0x4eba /* offset 2690 */ , + 0x513f /* offset 2691 */ , + 0x5165 /* offset 2692 */ , + 0x516b /* offset 2693 */ , + 0x5182 /* offset 2694 */ , + 0x5196 /* offset 2695 */ , + 0x51ab /* offset 2696 */ , + 0x51e0 /* offset 2697 */ , + 0x51f5 /* offset 2698 */ , + 0x5200 /* offset 2699 */ , + 0x529b /* offset 2700 */ , + 0x52f9 /* offset 2701 */ , + 0x5315 /* offset 2702 */ , + 0x531a /* offset 2703 */ , + 0x5338 /* offset 2704 */ , + 0x5341 /* offset 2705 */ , + 0x535c /* offset 2706 */ , + 0x5369 /* offset 2707 */ , + 0x5382 /* offset 2708 */ , + 0x53b6 /* offset 2709 */ , + 0x53c8 /* offset 2710 */ , + 0x53e3 /* offset 2711 */ , + 0x56d7 /* offset 2712 */ , + 0x571f /* offset 2713 */ , + 0x58eb /* offset 2714 */ , + 0x5902 /* offset 2715 */ , + 0x590a /* offset 2716 */ , + 0x5915 /* offset 2717 */ , + 0x5927 /* offset 2718 */ , + 0x5973 /* offset 2719 */ , + 0x5b50 /* offset 2720 */ , + 0x5b80 /* offset 2721 */ , + 0x5bf8 /* offset 2722 */ , + 0x5c0f /* offset 2723 */ , + 0x5c22 /* offset 2724 */ , + 0x5c38 /* offset 2725 */ , + 0x5c6e /* offset 2726 */ , + 0x5c71 /* offset 2727 */ , + 0x5ddb /* offset 2728 */ , + 0x5de5 /* offset 2729 */ , + 0x5df1 /* offset 2730 */ , + 0x5dfe /* offset 2731 */ , + 0x5e72 /* offset 2732 */ , + 0x5e7a /* offset 2733 */ , + 0x5e7f /* offset 2734 */ , + 0x5ef4 /* offset 2735 */ , + 0x5efe /* offset 2736 */ , + 0x5f0b /* offset 2737 */ , + 0x5f13 /* offset 2738 */ , + 0x5f50 /* offset 2739 */ , + 0x5f61 /* offset 2740 */ , + 0x5f73 /* offset 2741 */ , + 0x5fc3 /* offset 2742 */ , + 0x6208 /* offset 2743 */ , + 0x6236 /* offset 2744 */ , + 0x624b /* offset 2745 */ , + 0x652f /* offset 2746 */ , + 0x6534 /* offset 2747 */ , + 0x6587 /* offset 2748 */ , + 0x6597 /* offset 2749 */ , + 0x65a4 /* offset 2750 */ , + 0x65b9 /* offset 2751 */ , + 0x65e0 /* offset 2752 */ , + 0x65e5 /* offset 2753 */ , + 0x66f0 /* offset 2754 */ , + 0x6708 /* offset 2755 */ , + 0x6728 /* offset 2756 */ , + 0x6b20 /* offset 2757 */ , + 0x6b62 /* offset 2758 */ , + 0x6b79 /* offset 2759 */ , + 0x6bb3 /* offset 2760 */ , + 0x6bcb /* offset 2761 */ , + 0x6bd4 /* offset 2762 */ , + 0x6bdb /* offset 2763 */ , + 0x6c0f /* offset 2764 */ , + 0x6c14 /* offset 2765 */ , + 0x6c34 /* offset 2766 */ , + 0x706b /* offset 2767 */ , + 0x722a /* offset 2768 */ , + 0x7236 /* offset 2769 */ , + 0x723b /* offset 2770 */ , + 0x723f /* offset 2771 */ , + 0x7247 /* offset 2772 */ , + 0x7259 /* offset 2773 */ , + 0x725b /* offset 2774 */ , + 0x72ac /* offset 2775 */ , + 0x7384 /* offset 2776 */ , + 0x7389 /* offset 2777 */ , + 0x74dc /* offset 2778 */ , + 0x74e6 /* offset 2779 */ , + 0x7518 /* offset 2780 */ , + 0x751f /* offset 2781 */ , + 0x7528 /* offset 2782 */ , + 0x7530 /* offset 2783 */ , + 0x758b /* offset 2784 */ , + 0x7592 /* offset 2785 */ , + 0x7676 /* offset 2786 */ , + 0x767d /* offset 2787 */ , + 0x76ae /* offset 2788 */ , + 0x76bf /* offset 2789 */ , + 0x76ee /* offset 2790 */ , + 0x77db /* offset 2791 */ , + 0x77e2 /* offset 2792 */ , + 0x77f3 /* offset 2793 */ , + 0x793a /* offset 2794 */ , + 0x79b8 /* offset 2795 */ , + 0x79be /* offset 2796 */ , + 0x7a74 /* offset 2797 */ , + 0x7acb /* offset 2798 */ , + 0x7af9 /* offset 2799 */ , + 0x7c73 /* offset 2800 */ , + 0x7cf8 /* offset 2801 */ , + 0x7f36 /* offset 2802 */ , + 0x7f51 /* offset 2803 */ , + 0x7f8a /* offset 2804 */ , + 0x7fbd /* offset 2805 */ , + 0x8001 /* offset 2806 */ , + 0x800c /* offset 2807 */ , + 0x8012 /* offset 2808 */ , + 0x8033 /* offset 2809 */ , + 0x807f /* offset 2810 */ , + 0x8089 /* offset 2811 */ , + 0x81e3 /* offset 2812 */ , + 0x81ea /* offset 2813 */ , + 0x81f3 /* offset 2814 */ , + 0x81fc /* offset 2815 */ , + 0x820c /* offset 2816 */ , + 0x821b /* offset 2817 */ , + 0x821f /* offset 2818 */ , + 0x826e /* offset 2819 */ , + 0x8272 /* offset 2820 */ , + 0x8278 /* offset 2821 */ , + 0x864d /* offset 2822 */ , + 0x866b /* offset 2823 */ , + 0x8840 /* offset 2824 */ , + 0x884c /* offset 2825 */ , + 0x8863 /* offset 2826 */ , + 0x897e /* offset 2827 */ , + 0x898b /* offset 2828 */ , + 0x89d2 /* offset 2829 */ , + 0x8a00 /* offset 2830 */ , + 0x8c37 /* offset 2831 */ , + 0x8c46 /* offset 2832 */ , + 0x8c55 /* offset 2833 */ , + 0x8c78 /* offset 2834 */ , + 0x8c9d /* offset 2835 */ , + 0x8d64 /* offset 2836 */ , + 0x8d70 /* offset 2837 */ , + 0x8db3 /* offset 2838 */ , + 0x8eab /* offset 2839 */ , + 0x8eca /* offset 2840 */ , + 0x8f9b /* offset 2841 */ , + 0x8fb0 /* offset 2842 */ , + 0x8fb5 /* offset 2843 */ , + 0x9091 /* offset 2844 */ , + 0x9149 /* offset 2845 */ , + 0x91c6 /* offset 2846 */ , + 0x91cc /* offset 2847 */ , + 0x91d1 /* offset 2848 */ , + 0x9577 /* offset 2849 */ , + 0x9580 /* offset 2850 */ , + 0x961c /* offset 2851 */ , + 0x96b6 /* offset 2852 */ , + 0x96b9 /* offset 2853 */ , + 0x96e8 /* offset 2854 */ , + 0x9751 /* offset 2855 */ , + 0x975e /* offset 2856 */ , + 0x9762 /* offset 2857 */ , + 0x9769 /* offset 2858 */ , + 0x97cb /* offset 2859 */ , + 0x97ed /* offset 2860 */ , + 0x97f3 /* offset 2861 */ , + 0x9801 /* offset 2862 */ , + 0x98a8 /* offset 2863 */ , + 0x98db /* offset 2864 */ , + 0x98df /* offset 2865 */ , + 0x9996 /* offset 2866 */ , + 0x9999 /* offset 2867 */ , + 0x99ac /* offset 2868 */ , + 0x9aa8 /* offset 2869 */ , + 0x9ad8 /* offset 2870 */ , + 0x9adf /* offset 2871 */ , + 0x9b25 /* offset 2872 */ , + 0x9b2f /* offset 2873 */ , + 0x9b32 /* offset 2874 */ , + 0x9b3c /* offset 2875 */ , + 0x9b5a /* offset 2876 */ , + 0x9ce5 /* offset 2877 */ , + 0x9e75 /* offset 2878 */ , + 0x9e7f /* offset 2879 */ , + 0x9ea5 /* offset 2880 */ , + 0x9ebb /* offset 2881 */ , + 0x9ec3 /* offset 2882 */ , + 0x9ecd /* offset 2883 */ , + 0x9ed1 /* offset 2884 */ , + 0x9ef9 /* offset 2885 */ , + 0x9efd /* offset 2886 */ , + 0x9f0e /* offset 2887 */ , + 0x9f13 /* offset 2888 */ , + 0x9f20 /* offset 2889 */ , + 0x9f3b /* offset 2890 */ , + 0x9f4a /* offset 2891 */ , + 0x9f52 /* offset 2892 */ , + 0x9f8d /* offset 2893 */ , + 0x9f9c /* offset 2894 */ , + 0x9fa0 /* offset 2895 */ , + 0x3012 /* offset 2896 */ , + 0x5344 /* offset 2897 */ , + 0x5345 /* offset 2898 */ , + 0x304b, 0x3099 /* offset 2899 */ , + 0x304d, 0x3099 /* offset 2901 */ , + 0x304f, 0x3099 /* offset 2903 */ , + 0x3051, 0x3099 /* offset 2905 */ , + 0x3053, 0x3099 /* offset 2907 */ , + 0x3055, 0x3099 /* offset 2909 */ , + 0x3057, 0x3099 /* offset 2911 */ , + 0x3059, 0x3099 /* offset 2913 */ , + 0x305b, 0x3099 /* offset 2915 */ , + 0x305d, 0x3099 /* offset 2917 */ , + 0x305f, 0x3099 /* offset 2919 */ , + 0x3061, 0x3099 /* offset 2921 */ , + 0x3064, 0x3099 /* offset 2923 */ , + 0x3066, 0x3099 /* offset 2925 */ , + 0x3068, 0x3099 /* offset 2927 */ , + 0x306f, 0x3099 /* offset 2929 */ , + 0x306f, 0x309a /* offset 2931 */ , + 0x3072, 0x3099 /* offset 2933 */ , + 0x3072, 0x309a /* offset 2935 */ , + 0x3075, 0x3099 /* offset 2937 */ , + 0x3075, 0x309a /* offset 2939 */ , + 0x3078, 0x3099 /* offset 2941 */ , + 0x3078, 0x309a /* offset 2943 */ , + 0x307b, 0x3099 /* offset 2945 */ , + 0x307b, 0x309a /* offset 2947 */ , + 0x3046, 0x3099 /* offset 2949 */ , + 0x20, 0x3099 /* offset 2951 */ , + 0x20, 0x309a /* offset 2953 */ , + 0x309d, 0x3099 /* offset 2955 */ , + 0x3088, 0x308a /* offset 2957 */ , + 0x30ab, 0x3099 /* offset 2959 */ , + 0x30ad, 0x3099 /* offset 2961 */ , + 0x30af, 0x3099 /* offset 2963 */ , + 0x30b1, 0x3099 /* offset 2965 */ , + 0x30b3, 0x3099 /* offset 2967 */ , + 0x30b5, 0x3099 /* offset 2969 */ , + 0x30b7, 0x3099 /* offset 2971 */ , + 0x30b9, 0x3099 /* offset 2973 */ , + 0x30bb, 0x3099 /* offset 2975 */ , + 0x30bd, 0x3099 /* offset 2977 */ , + 0x30bf, 0x3099 /* offset 2979 */ , + 0x30c1, 0x3099 /* offset 2981 */ , + 0x30c4, 0x3099 /* offset 2983 */ , + 0x30c6, 0x3099 /* offset 2985 */ , + 0x30c8, 0x3099 /* offset 2987 */ , + 0x30cf, 0x3099 /* offset 2989 */ , + 0x30cf, 0x309a /* offset 2991 */ , + 0x30d2, 0x3099 /* offset 2993 */ , + 0x30d2, 0x309a /* offset 2995 */ , + 0x30d5, 0x3099 /* offset 2997 */ , + 0x30d5, 0x309a /* offset 2999 */ , + 0x30d8, 0x3099 /* offset 3001 */ , + 0x30d8, 0x309a /* offset 3003 */ , + 0x30db, 0x3099 /* offset 3005 */ , + 0x30db, 0x309a /* offset 3007 */ , + 0x30a6, 0x3099 /* offset 3009 */ , + 0x30ef, 0x3099 /* offset 3011 */ , + 0x30f0, 0x3099 /* offset 3013 */ , + 0x30f1, 0x3099 /* offset 3015 */ , + 0x30f2, 0x3099 /* offset 3017 */ , + 0x30fd, 0x3099 /* offset 3019 */ , + 0x30b3, 0x30c8 /* offset 3021 */ , + 0x1100 /* offset 3023 */ , + 0x1101 /* offset 3024 */ , + 0x11aa /* offset 3025 */ , + 0x1102 /* offset 3026 */ , + 0x11ac /* offset 3027 */ , + 0x11ad /* offset 3028 */ , + 0x1103 /* offset 3029 */ , + 0x1104 /* offset 3030 */ , + 0x1105 /* offset 3031 */ , + 0x11b0 /* offset 3032 */ , + 0x11b1 /* offset 3033 */ , + 0x11b2 /* offset 3034 */ , + 0x11b3 /* offset 3035 */ , + 0x11b4 /* offset 3036 */ , + 0x11b5 /* offset 3037 */ , + 0x111a /* offset 3038 */ , + 0x1106 /* offset 3039 */ , + 0x1107 /* offset 3040 */ , + 0x1108 /* offset 3041 */ , + 0x1121 /* offset 3042 */ , + 0x1109 /* offset 3043 */ , + 0x110a /* offset 3044 */ , + 0x110b /* offset 3045 */ , + 0x110c /* offset 3046 */ , + 0x110d /* offset 3047 */ , + 0x110e /* offset 3048 */ , + 0x110f /* offset 3049 */ , + 0x1110 /* offset 3050 */ , + 0x1111 /* offset 3051 */ , + 0x1112 /* offset 3052 */ , + 0x1161 /* offset 3053 */ , + 0x1162 /* offset 3054 */ , + 0x1163 /* offset 3055 */ , + 0x1164 /* offset 3056 */ , + 0x1165 /* offset 3057 */ , + 0x1166 /* offset 3058 */ , + 0x1167 /* offset 3059 */ , + 0x1168 /* offset 3060 */ , + 0x1169 /* offset 3061 */ , + 0x116a /* offset 3062 */ , + 0x116b /* offset 3063 */ , + 0x116c /* offset 3064 */ , + 0x116d /* offset 3065 */ , + 0x116e /* offset 3066 */ , + 0x116f /* offset 3067 */ , + 0x1170 /* offset 3068 */ , + 0x1171 /* offset 3069 */ , + 0x1172 /* offset 3070 */ , + 0x1173 /* offset 3071 */ , + 0x1174 /* offset 3072 */ , + 0x1175 /* offset 3073 */ , + 0x1160 /* offset 3074 */ , + 0x1114 /* offset 3075 */ , + 0x1115 /* offset 3076 */ , + 0x11c7 /* offset 3077 */ , + 0x11c8 /* offset 3078 */ , + 0x11cc /* offset 3079 */ , + 0x11ce /* offset 3080 */ , + 0x11d3 /* offset 3081 */ , + 0x11d7 /* offset 3082 */ , + 0x11d9 /* offset 3083 */ , + 0x111c /* offset 3084 */ , + 0x11dd /* offset 3085 */ , + 0x11df /* offset 3086 */ , + 0x111d /* offset 3087 */ , + 0x111e /* offset 3088 */ , + 0x1120 /* offset 3089 */ , + 0x1122 /* offset 3090 */ , + 0x1123 /* offset 3091 */ , + 0x1127 /* offset 3092 */ , + 0x1129 /* offset 3093 */ , + 0x112b /* offset 3094 */ , + 0x112c /* offset 3095 */ , + 0x112d /* offset 3096 */ , + 0x112e /* offset 3097 */ , + 0x112f /* offset 3098 */ , + 0x1132 /* offset 3099 */ , + 0x1136 /* offset 3100 */ , + 0x1140 /* offset 3101 */ , + 0x1147 /* offset 3102 */ , + 0x114c /* offset 3103 */ , + 0x11f1 /* offset 3104 */ , + 0x11f2 /* offset 3105 */ , + 0x1157 /* offset 3106 */ , + 0x1158 /* offset 3107 */ , + 0x1159 /* offset 3108 */ , + 0x1184 /* offset 3109 */ , + 0x1185 /* offset 3110 */ , + 0x1188 /* offset 3111 */ , + 0x1191 /* offset 3112 */ , + 0x1192 /* offset 3113 */ , + 0x1194 /* offset 3114 */ , + 0x119e /* offset 3115 */ , + 0x11a1 /* offset 3116 */ , + 0x4e09 /* offset 3117 */ , + 0x56db /* offset 3118 */ , + 0x4e0a /* offset 3119 */ , + 0x4e2d /* offset 3120 */ , + 0x4e0b /* offset 3121 */ , + 0x7532 /* offset 3122 */ , + 0x4e19 /* offset 3123 */ , + 0x4e01 /* offset 3124 */ , + 0x5929 /* offset 3125 */ , + 0x5730 /* offset 3126 */ , + 0x28, 0x1100, 0x29 /* offset 3127 */ , + 0x28, 0x1102, 0x29 /* offset 3130 */ , + 0x28, 0x1103, 0x29 /* offset 3133 */ , + 0x28, 0x1105, 0x29 /* offset 3136 */ , + 0x28, 0x1106, 0x29 /* offset 3139 */ , + 0x28, 0x1107, 0x29 /* offset 3142 */ , + 0x28, 0x1109, 0x29 /* offset 3145 */ , + 0x28, 0x110b, 0x29 /* offset 3148 */ , + 0x28, 0x110c, 0x29 /* offset 3151 */ , + 0x28, 0x110e, 0x29 /* offset 3154 */ , + 0x28, 0x110f, 0x29 /* offset 3157 */ , + 0x28, 0x1110, 0x29 /* offset 3160 */ , + 0x28, 0x1111, 0x29 /* offset 3163 */ , + 0x28, 0x1112, 0x29 /* offset 3166 */ , + 0x28, 0x1100, 0x1161, 0x29 /* offset 3169 */ , + 0x28, 0x1102, 0x1161, 0x29 /* offset 3173 */ , + 0x28, 0x1103, 0x1161, 0x29 /* offset 3177 */ , + 0x28, 0x1105, 0x1161, 0x29 /* offset 3181 */ , + 0x28, 0x1106, 0x1161, 0x29 /* offset 3185 */ , + 0x28, 0x1107, 0x1161, 0x29 /* offset 3189 */ , + 0x28, 0x1109, 0x1161, 0x29 /* offset 3193 */ , + 0x28, 0x110b, 0x1161, 0x29 /* offset 3197 */ , + 0x28, 0x110c, 0x1161, 0x29 /* offset 3201 */ , + 0x28, 0x110e, 0x1161, 0x29 /* offset 3205 */ , + 0x28, 0x110f, 0x1161, 0x29 /* offset 3209 */ , + 0x28, 0x1110, 0x1161, 0x29 /* offset 3213 */ , + 0x28, 0x1111, 0x1161, 0x29 /* offset 3217 */ , + 0x28, 0x1112, 0x1161, 0x29 /* offset 3221 */ , + 0x28, 0x110c, 0x116e, 0x29 /* offset 3225 */ , + 0x28, 0x4e00, 0x29 /* offset 3229 */ , + 0x28, 0x4e8c, 0x29 /* offset 3232 */ , + 0x28, 0x4e09, 0x29 /* offset 3235 */ , + 0x28, 0x56db, 0x29 /* offset 3238 */ , + 0x28, 0x4e94, 0x29 /* offset 3241 */ , + 0x28, 0x516d, 0x29 /* offset 3244 */ , + 0x28, 0x4e03, 0x29 /* offset 3247 */ , + 0x28, 0x516b, 0x29 /* offset 3250 */ , + 0x28, 0x4e5d, 0x29 /* offset 3253 */ , + 0x28, 0x5341, 0x29 /* offset 3256 */ , + 0x28, 0x6708, 0x29 /* offset 3259 */ , + 0x28, 0x706b, 0x29 /* offset 3262 */ , + 0x28, 0x6c34, 0x29 /* offset 3265 */ , + 0x28, 0x6728, 0x29 /* offset 3268 */ , + 0x28, 0x91d1, 0x29 /* offset 3271 */ , + 0x28, 0x571f, 0x29 /* offset 3274 */ , + 0x28, 0x65e5, 0x29 /* offset 3277 */ , + 0x28, 0x682a, 0x29 /* offset 3280 */ , + 0x28, 0x6709, 0x29 /* offset 3283 */ , + 0x28, 0x793e, 0x29 /* offset 3286 */ , + 0x28, 0x540d, 0x29 /* offset 3289 */ , + 0x28, 0x7279, 0x29 /* offset 3292 */ , + 0x28, 0x8ca1, 0x29 /* offset 3295 */ , + 0x28, 0x795d, 0x29 /* offset 3298 */ , + 0x28, 0x52b4, 0x29 /* offset 3301 */ , + 0x28, 0x4ee3, 0x29 /* offset 3304 */ , + 0x28, 0x547c, 0x29 /* offset 3307 */ , + 0x28, 0x5b66, 0x29 /* offset 3310 */ , + 0x28, 0x76e3, 0x29 /* offset 3313 */ , + 0x28, 0x4f01, 0x29 /* offset 3316 */ , + 0x28, 0x8cc7, 0x29 /* offset 3319 */ , + 0x28, 0x5354, 0x29 /* offset 3322 */ , + 0x28, 0x796d, 0x29 /* offset 3325 */ , + 0x28, 0x4f11, 0x29 /* offset 3328 */ , + 0x28, 0x81ea, 0x29 /* offset 3331 */ , + 0x28, 0x81f3, 0x29 /* offset 3334 */ , + 0x32, 0x31 /* offset 3337 */ , + 0x32, 0x32 /* offset 3339 */ , + 0x32, 0x33 /* offset 3341 */ , + 0x32, 0x34 /* offset 3343 */ , + 0x32, 0x35 /* offset 3345 */ , + 0x32, 0x36 /* offset 3347 */ , + 0x32, 0x37 /* offset 3349 */ , + 0x32, 0x38 /* offset 3351 */ , + 0x32, 0x39 /* offset 3353 */ , + 0x33, 0x30 /* offset 3355 */ , + 0x33, 0x31 /* offset 3357 */ , + 0x33, 0x32 /* offset 3359 */ , + 0x33, 0x33 /* offset 3361 */ , + 0x33, 0x34 /* offset 3363 */ , + 0x33, 0x35 /* offset 3365 */ , + 0x1100, 0x1161 /* offset 3367 */ , + 0x1102, 0x1161 /* offset 3369 */ , + 0x1103, 0x1161 /* offset 3371 */ , + 0x1105, 0x1161 /* offset 3373 */ , + 0x1106, 0x1161 /* offset 3375 */ , + 0x1107, 0x1161 /* offset 3377 */ , + 0x1109, 0x1161 /* offset 3379 */ , + 0x110b, 0x1161 /* offset 3381 */ , + 0x110c, 0x1161 /* offset 3383 */ , + 0x110e, 0x1161 /* offset 3385 */ , + 0x110f, 0x1161 /* offset 3387 */ , + 0x1110, 0x1161 /* offset 3389 */ , + 0x1111, 0x1161 /* offset 3391 */ , + 0x1112, 0x1161 /* offset 3393 */ , + 0x4e94 /* offset 3395 */ , + 0x516d /* offset 3396 */ , + 0x4e03 /* offset 3397 */ , + 0x4e5d /* offset 3398 */ , + 0x682a /* offset 3399 */ , + 0x6709 /* offset 3400 */ , + 0x793e /* offset 3401 */ , + 0x540d /* offset 3402 */ , + 0x7279 /* offset 3403 */ , + 0x8ca1 /* offset 3404 */ , + 0x795d /* offset 3405 */ , + 0x52b4 /* offset 3406 */ , + 0x79d8 /* offset 3407 */ , + 0x7537 /* offset 3408 */ , + 0x9069 /* offset 3409 */ , + 0x512a /* offset 3410 */ , + 0x5370 /* offset 3411 */ , + 0x6ce8 /* offset 3412 */ , + 0x9805 /* offset 3413 */ , + 0x4f11 /* offset 3414 */ , + 0x5199 /* offset 3415 */ , + 0x6b63 /* offset 3416 */ , + 0x5de6 /* offset 3417 */ , + 0x53f3 /* offset 3418 */ , + 0x533b /* offset 3419 */ , + 0x5b97 /* offset 3420 */ , + 0x5b66 /* offset 3421 */ , + 0x76e3 /* offset 3422 */ , + 0x4f01 /* offset 3423 */ , + 0x8cc7 /* offset 3424 */ , + 0x5354 /* offset 3425 */ , + 0x591c /* offset 3426 */ , + 0x33, 0x36 /* offset 3427 */ , + 0x33, 0x37 /* offset 3429 */ , + 0x33, 0x38 /* offset 3431 */ , + 0x33, 0x39 /* offset 3433 */ , + 0x34, 0x30 /* offset 3435 */ , + 0x34, 0x31 /* offset 3437 */ , + 0x34, 0x32 /* offset 3439 */ , + 0x34, 0x33 /* offset 3441 */ , + 0x34, 0x34 /* offset 3443 */ , + 0x34, 0x35 /* offset 3445 */ , + 0x34, 0x36 /* offset 3447 */ , + 0x34, 0x37 /* offset 3449 */ , + 0x34, 0x38 /* offset 3451 */ , + 0x34, 0x39 /* offset 3453 */ , + 0x35, 0x30 /* offset 3455 */ , + 0x31, 0x6708 /* offset 3457 */ , + 0x32, 0x6708 /* offset 3459 */ , + 0x33, 0x6708 /* offset 3461 */ , + 0x34, 0x6708 /* offset 3463 */ , + 0x35, 0x6708 /* offset 3465 */ , + 0x36, 0x6708 /* offset 3467 */ , + 0x37, 0x6708 /* offset 3469 */ , + 0x38, 0x6708 /* offset 3471 */ , + 0x39, 0x6708 /* offset 3473 */ , + 0x31, 0x30, 0x6708 /* offset 3475 */ , + 0x31, 0x31, 0x6708 /* offset 3478 */ , + 0x31, 0x32, 0x6708 /* offset 3481 */ , + 0x30a2 /* offset 3484 */ , + 0x30a4 /* offset 3485 */ , + 0x30a6 /* offset 3486 */ , + 0x30a8 /* offset 3487 */ , + 0x30aa /* offset 3488 */ , + 0x30ab /* offset 3489 */ , + 0x30ad /* offset 3490 */ , + 0x30af /* offset 3491 */ , + 0x30b1 /* offset 3492 */ , + 0x30b3 /* offset 3493 */ , + 0x30b5 /* offset 3494 */ , + 0x30b7 /* offset 3495 */ , + 0x30b9 /* offset 3496 */ , + 0x30bb /* offset 3497 */ , + 0x30bd /* offset 3498 */ , + 0x30bf /* offset 3499 */ , + 0x30c1 /* offset 3500 */ , + 0x30c4 /* offset 3501 */ , + 0x30c6 /* offset 3502 */ , + 0x30c8 /* offset 3503 */ , + 0x30ca /* offset 3504 */ , + 0x30cb /* offset 3505 */ , + 0x30cc /* offset 3506 */ , + 0x30cd /* offset 3507 */ , + 0x30ce /* offset 3508 */ , + 0x30cf /* offset 3509 */ , + 0x30d2 /* offset 3510 */ , + 0x30d5 /* offset 3511 */ , + 0x30d8 /* offset 3512 */ , + 0x30db /* offset 3513 */ , + 0x30de /* offset 3514 */ , + 0x30df /* offset 3515 */ , + 0x30e0 /* offset 3516 */ , + 0x30e1 /* offset 3517 */ , + 0x30e2 /* offset 3518 */ , + 0x30e4 /* offset 3519 */ , + 0x30e6 /* offset 3520 */ , + 0x30e8 /* offset 3521 */ , + 0x30e9 /* offset 3522 */ , + 0x30ea /* offset 3523 */ , + 0x30eb /* offset 3524 */ , + 0x30ec /* offset 3525 */ , + 0x30ed /* offset 3526 */ , + 0x30ef /* offset 3527 */ , + 0x30f0 /* offset 3528 */ , + 0x30f1 /* offset 3529 */ , + 0x30f2 /* offset 3530 */ , + 0x30a2, 0x30cf, 0x309a, 0x30fc, 0x30c8 /* offset 3531 */ , + 0x30a2, 0x30eb, 0x30d5, 0x30a1 /* offset 3536 */ , + 0x30a2, 0x30f3, 0x30d8, 0x309a, 0x30a2 /* offset 3540 */ , + 0x30a2, 0x30fc, 0x30eb /* offset 3545 */ , + 0x30a4, 0x30cb, 0x30f3, 0x30af, 0x3099 /* offset 3548 */ , + 0x30a4, 0x30f3, 0x30c1 /* offset 3553 */ , + 0x30a6, 0x30a9, 0x30f3 /* offset 3556 */ , + 0x30a8, 0x30b9, 0x30af, 0x30fc, 0x30c8, 0x3099 /* offset 3559 */ , + 0x30a8, 0x30fc, 0x30ab, 0x30fc /* offset 3565 */ , + 0x30aa, 0x30f3, 0x30b9 /* offset 3569 */ , + 0x30aa, 0x30fc, 0x30e0 /* offset 3572 */ , + 0x30ab, 0x30a4, 0x30ea /* offset 3575 */ , + 0x30ab, 0x30e9, 0x30c3, 0x30c8 /* offset 3578 */ , + 0x30ab, 0x30ed, 0x30ea, 0x30fc /* offset 3582 */ , + 0x30ab, 0x3099, 0x30ed, 0x30f3 /* offset 3586 */ , + 0x30ab, 0x3099, 0x30f3, 0x30de /* offset 3590 */ , + 0x30ad, 0x3099, 0x30ab, 0x3099 /* offset 3594 */ , + 0x30ad, 0x3099, 0x30cb, 0x30fc /* offset 3598 */ , + 0x30ad, 0x30e5, 0x30ea, 0x30fc /* offset 3602 */ , + 0x30ad, 0x3099, 0x30eb, 0x30bf, 0x3099, 0x30fc /* offset 3606 */ , + 0x30ad, 0x30ed /* offset 3612 */ , + 0x30ad, 0x30ed, 0x30af, 0x3099, 0x30e9, 0x30e0 /* offset 3614 */ , + 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8, 0x30eb /* offset 3620 */ , + 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8 /* offset 3626 */ , + 0x30af, 0x3099, 0x30e9, 0x30e0 /* offset 3631 */ , + 0x30af, 0x3099, 0x30e9, 0x30e0, 0x30c8, 0x30f3 /* offset 3635 */ , + 0x30af, 0x30eb, 0x30bb, 0x3099, 0x30a4, 0x30ed /* offset 3641 */ , + 0x30af, 0x30ed, 0x30fc, 0x30cd /* offset 3647 */ , + 0x30b1, 0x30fc, 0x30b9 /* offset 3651 */ , + 0x30b3, 0x30eb, 0x30ca /* offset 3654 */ , + 0x30b3, 0x30fc, 0x30db, 0x309a /* offset 3657 */ , + 0x30b5, 0x30a4, 0x30af, 0x30eb /* offset 3661 */ , + 0x30b5, 0x30f3, 0x30c1, 0x30fc, 0x30e0 /* offset 3665 */ , + 0x30b7, 0x30ea, 0x30f3, 0x30af, 0x3099 /* offset 3670 */ , + 0x30bb, 0x30f3, 0x30c1 /* offset 3675 */ , + 0x30bb, 0x30f3, 0x30c8 /* offset 3678 */ , + 0x30bf, 0x3099, 0x30fc, 0x30b9 /* offset 3681 */ , + 0x30c6, 0x3099, 0x30b7 /* offset 3685 */ , + 0x30c8, 0x3099, 0x30eb /* offset 3688 */ , + 0x30c8, 0x30f3 /* offset 3691 */ , + 0x30ca, 0x30ce /* offset 3693 */ , + 0x30ce, 0x30c3, 0x30c8 /* offset 3695 */ , + 0x30cf, 0x30a4, 0x30c4 /* offset 3698 */ , + 0x30cf, 0x309a, 0x30fc, 0x30bb, 0x30f3, 0x30c8 /* offset 3701 */ , + 0x30cf, 0x309a, 0x30fc, 0x30c4 /* offset 3707 */ , + 0x30cf, 0x3099, 0x30fc, 0x30ec, 0x30eb /* offset 3711 */ , + 0x30d2, 0x309a, 0x30a2, 0x30b9, 0x30c8, 0x30eb /* offset 3716 */ , + 0x30d2, 0x309a, 0x30af, 0x30eb /* offset 3722 */ , + 0x30d2, 0x309a, 0x30b3 /* offset 3726 */ , + 0x30d2, 0x3099, 0x30eb /* offset 3729 */ , + 0x30d5, 0x30a1, 0x30e9, 0x30c3, 0x30c8, 0x3099 /* offset 3732 */ , + 0x30d5, 0x30a3, 0x30fc, 0x30c8 /* offset 3738 */ , + 0x30d5, 0x3099, 0x30c3, 0x30b7, 0x30a7, 0x30eb /* offset 3742 */ , + 0x30d5, 0x30e9, 0x30f3 /* offset 3748 */ , + 0x30d8, 0x30af, 0x30bf, 0x30fc, 0x30eb /* offset 3751 */ , + 0x30d8, 0x309a, 0x30bd /* offset 3756 */ , + 0x30d8, 0x309a, 0x30cb, 0x30d2 /* offset 3759 */ , + 0x30d8, 0x30eb, 0x30c4 /* offset 3763 */ , + 0x30d8, 0x309a, 0x30f3, 0x30b9 /* offset 3766 */ , + 0x30d8, 0x309a, 0x30fc, 0x30b7, 0x3099 /* offset 3770 */ , + 0x30d8, 0x3099, 0x30fc, 0x30bf /* offset 3775 */ , + 0x30db, 0x309a, 0x30a4, 0x30f3, 0x30c8 /* offset 3779 */ , + 0x30db, 0x3099, 0x30eb, 0x30c8 /* offset 3784 */ , + 0x30db, 0x30f3 /* offset 3788 */ , + 0x30db, 0x309a, 0x30f3, 0x30c8, 0x3099 /* offset 3790 */ , + 0x30db, 0x30fc, 0x30eb /* offset 3795 */ , + 0x30db, 0x30fc, 0x30f3 /* offset 3798 */ , + 0x30de, 0x30a4, 0x30af, 0x30ed /* offset 3801 */ , + 0x30de, 0x30a4, 0x30eb /* offset 3805 */ , + 0x30de, 0x30c3, 0x30cf /* offset 3808 */ , + 0x30de, 0x30eb, 0x30af /* offset 3811 */ , + 0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3 /* offset 3814 */ , + 0x30df, 0x30af, 0x30ed, 0x30f3 /* offset 3819 */ , + 0x30df, 0x30ea /* offset 3823 */ , + 0x30df, 0x30ea, 0x30cf, 0x3099, 0x30fc, 0x30eb /* offset 3825 */ , + 0x30e1, 0x30ab, 0x3099 /* offset 3831 */ , + 0x30e1, 0x30ab, 0x3099, 0x30c8, 0x30f3 /* offset 3834 */ , + 0x30e1, 0x30fc, 0x30c8, 0x30eb /* offset 3839 */ , + 0x30e4, 0x30fc, 0x30c8, 0x3099 /* offset 3843 */ , + 0x30e4, 0x30fc, 0x30eb /* offset 3847 */ , + 0x30e6, 0x30a2, 0x30f3 /* offset 3850 */ , + 0x30ea, 0x30c3, 0x30c8, 0x30eb /* offset 3853 */ , + 0x30ea, 0x30e9 /* offset 3857 */ , + 0x30eb, 0x30d2, 0x309a, 0x30fc /* offset 3859 */ , + 0x30eb, 0x30fc, 0x30d5, 0x3099, 0x30eb /* offset 3863 */ , + 0x30ec, 0x30e0 /* offset 3868 */ , + 0x30ec, 0x30f3, 0x30c8, 0x30b1, 0x3099, 0x30f3 /* offset 3870 */ , + 0x30ef, 0x30c3, 0x30c8 /* offset 3876 */ , + 0x30, 0x70b9 /* offset 3879 */ , + 0x31, 0x70b9 /* offset 3881 */ , + 0x32, 0x70b9 /* offset 3883 */ , + 0x33, 0x70b9 /* offset 3885 */ , + 0x34, 0x70b9 /* offset 3887 */ , + 0x35, 0x70b9 /* offset 3889 */ , + 0x36, 0x70b9 /* offset 3891 */ , + 0x37, 0x70b9 /* offset 3893 */ , + 0x38, 0x70b9 /* offset 3895 */ , + 0x39, 0x70b9 /* offset 3897 */ , + 0x31, 0x30, 0x70b9 /* offset 3899 */ , + 0x31, 0x31, 0x70b9 /* offset 3902 */ , + 0x31, 0x32, 0x70b9 /* offset 3905 */ , + 0x31, 0x33, 0x70b9 /* offset 3908 */ , + 0x31, 0x34, 0x70b9 /* offset 3911 */ , + 0x31, 0x35, 0x70b9 /* offset 3914 */ , + 0x31, 0x36, 0x70b9 /* offset 3917 */ , + 0x31, 0x37, 0x70b9 /* offset 3920 */ , + 0x31, 0x38, 0x70b9 /* offset 3923 */ , + 0x31, 0x39, 0x70b9 /* offset 3926 */ , + 0x32, 0x30, 0x70b9 /* offset 3929 */ , + 0x32, 0x31, 0x70b9 /* offset 3932 */ , + 0x32, 0x32, 0x70b9 /* offset 3935 */ , + 0x32, 0x33, 0x70b9 /* offset 3938 */ , + 0x32, 0x34, 0x70b9 /* offset 3941 */ , + 0x68, 0x50, 0x61 /* offset 3944 */ , + 0x64, 0x61 /* offset 3947 */ , + 0x41, 0x55 /* offset 3949 */ , + 0x62, 0x61, 0x72 /* offset 3951 */ , + 0x6f, 0x56 /* offset 3954 */ , + 0x70, 0x63 /* offset 3956 */ , + 0x5e73, 0x6210 /* offset 3958 */ , + 0x662d, 0x548c /* offset 3960 */ , + 0x5927, 0x6b63 /* offset 3962 */ , + 0x660e, 0x6cbb /* offset 3964 */ , + 0x682a, 0x5f0f, 0x4f1a, 0x793e /* offset 3966 */ , + 0x70, 0x41 /* offset 3970 */ , + 0x6e, 0x41 /* offset 3972 */ , + 0x3bc, 0x41 /* offset 3974 */ , + 0x6d, 0x41 /* offset 3976 */ , + 0x6b, 0x41 /* offset 3978 */ , + 0x4b, 0x42 /* offset 3980 */ , + 0x4d, 0x42 /* offset 3982 */ , + 0x47, 0x42 /* offset 3984 */ , + 0x63, 0x61, 0x6c /* offset 3986 */ , + 0x6b, 0x63, 0x61, 0x6c /* offset 3989 */ , + 0x70, 0x46 /* offset 3993 */ , + 0x6e, 0x46 /* offset 3995 */ , + 0x3bc, 0x46 /* offset 3997 */ , + 0x3bc, 0x67 /* offset 3999 */ , + 0x6d, 0x67 /* offset 4001 */ , + 0x6b, 0x67 /* offset 4003 */ , + 0x48, 0x7a /* offset 4005 */ , + 0x6b, 0x48, 0x7a /* offset 4007 */ , + 0x4d, 0x48, 0x7a /* offset 4010 */ , + 0x47, 0x48, 0x7a /* offset 4013 */ , + 0x54, 0x48, 0x7a /* offset 4016 */ , + 0x3bc, 0x6c /* offset 4019 */ , + 0x6d, 0x6c /* offset 4021 */ , + 0x64, 0x6c /* offset 4023 */ , + 0x6b, 0x6c /* offset 4025 */ , + 0x66, 0x6d /* offset 4027 */ , + 0x6e, 0x6d /* offset 4029 */ , + 0x3bc, 0x6d /* offset 4031 */ , + 0x6d, 0x6d /* offset 4033 */ , + 0x63, 0x6d /* offset 4035 */ , + 0x6b, 0x6d /* offset 4037 */ , + 0x6d, 0x6d, 0x32 /* offset 4039 */ , + 0x63, 0x6d, 0x32 /* offset 4042 */ , + 0x6d, 0x32 /* offset 4045 */ , + 0x6b, 0x6d, 0x32 /* offset 4047 */ , + 0x6d, 0x6d, 0x33 /* offset 4050 */ , + 0x63, 0x6d, 0x33 /* offset 4053 */ , + 0x6d, 0x33 /* offset 4056 */ , + 0x6b, 0x6d, 0x33 /* offset 4058 */ , + 0x6d, 0x2215, 0x73 /* offset 4061 */ , + 0x6d, 0x2215, 0x73, 0x32 /* offset 4064 */ , + 0x50, 0x61 /* offset 4068 */ , + 0x6b, 0x50, 0x61 /* offset 4070 */ , + 0x4d, 0x50, 0x61 /* offset 4073 */ , + 0x47, 0x50, 0x61 /* offset 4076 */ , + 0x72, 0x61, 0x64 /* offset 4079 */ , + 0x72, 0x61, 0x64, 0x2215, 0x73 /* offset 4082 */ , + 0x72, 0x61, 0x64, 0x2215, 0x73, 0x32 /* offset 4087 */ , + 0x70, 0x73 /* offset 4093 */ , + 0x6e, 0x73 /* offset 4095 */ , + 0x3bc, 0x73 /* offset 4097 */ , + 0x6d, 0x73 /* offset 4099 */ , + 0x70, 0x56 /* offset 4101 */ , + 0x6e, 0x56 /* offset 4103 */ , + 0x3bc, 0x56 /* offset 4105 */ , + 0x6d, 0x56 /* offset 4107 */ , + 0x6b, 0x56 /* offset 4109 */ , + 0x4d, 0x56 /* offset 4111 */ , + 0x70, 0x57 /* offset 4113 */ , + 0x6e, 0x57 /* offset 4115 */ , + 0x3bc, 0x57 /* offset 4117 */ , + 0x6d, 0x57 /* offset 4119 */ , + 0x6b, 0x57 /* offset 4121 */ , + 0x4d, 0x57 /* offset 4123 */ , + 0x6b, 0x3a9 /* offset 4125 */ , + 0x4d, 0x3a9 /* offset 4127 */ , + 0x61, 0x2e, 0x6d, 0x2e /* offset 4129 */ , + 0x42, 0x71 /* offset 4133 */ , + 0x63, 0x63 /* offset 4135 */ , + 0x63, 0x64 /* offset 4137 */ , + 0x43, 0x2215, 0x6b, 0x67 /* offset 4139 */ , + 0x43, 0x6f, 0x2e /* offset 4143 */ , + 0x64, 0x42 /* offset 4146 */ , + 0x47, 0x79 /* offset 4148 */ , + 0x68, 0x61 /* offset 4150 */ , + 0x48, 0x50 /* offset 4152 */ , + 0x69, 0x6e /* offset 4154 */ , + 0x4b, 0x4b /* offset 4156 */ , + 0x4b, 0x4d /* offset 4158 */ , + 0x6b, 0x74 /* offset 4160 */ , + 0x6c, 0x6d /* offset 4162 */ , + 0x6c, 0x6e /* offset 4164 */ , + 0x6c, 0x6f, 0x67 /* offset 4166 */ , + 0x6c, 0x78 /* offset 4169 */ , + 0x6d, 0x62 /* offset 4171 */ , + 0x6d, 0x69, 0x6c /* offset 4173 */ , + 0x6d, 0x6f, 0x6c /* offset 4176 */ , + 0x50, 0x48 /* offset 4179 */ , + 0x70, 0x2e, 0x6d, 0x2e /* offset 4181 */ , + 0x50, 0x50, 0x4d /* offset 4185 */ , + 0x50, 0x52 /* offset 4188 */ , + 0x73, 0x72 /* offset 4190 */ , + 0x53, 0x76 /* offset 4192 */ , + 0x57, 0x62 /* offset 4194 */ , + 0x31, 0x65e5 /* offset 4196 */ , + 0x32, 0x65e5 /* offset 4198 */ , + 0x33, 0x65e5 /* offset 4200 */ , + 0x34, 0x65e5 /* offset 4202 */ , + 0x35, 0x65e5 /* offset 4204 */ , + 0x36, 0x65e5 /* offset 4206 */ , + 0x37, 0x65e5 /* offset 4208 */ , + 0x38, 0x65e5 /* offset 4210 */ , + 0x39, 0x65e5 /* offset 4212 */ , + 0x31, 0x30, 0x65e5 /* offset 4214 */ , + 0x31, 0x31, 0x65e5 /* offset 4217 */ , + 0x31, 0x32, 0x65e5 /* offset 4220 */ , + 0x31, 0x33, 0x65e5 /* offset 4223 */ , + 0x31, 0x34, 0x65e5 /* offset 4226 */ , + 0x31, 0x35, 0x65e5 /* offset 4229 */ , + 0x31, 0x36, 0x65e5 /* offset 4232 */ , + 0x31, 0x37, 0x65e5 /* offset 4235 */ , + 0x31, 0x38, 0x65e5 /* offset 4238 */ , + 0x31, 0x39, 0x65e5 /* offset 4241 */ , + 0x32, 0x30, 0x65e5 /* offset 4244 */ , + 0x32, 0x31, 0x65e5 /* offset 4247 */ , + 0x32, 0x32, 0x65e5 /* offset 4250 */ , + 0x32, 0x33, 0x65e5 /* offset 4253 */ , + 0x32, 0x34, 0x65e5 /* offset 4256 */ , + 0x32, 0x35, 0x65e5 /* offset 4259 */ , + 0x32, 0x36, 0x65e5 /* offset 4262 */ , + 0x32, 0x37, 0x65e5 /* offset 4265 */ , + 0x32, 0x38, 0x65e5 /* offset 4268 */ , + 0x32, 0x39, 0x65e5 /* offset 4271 */ , + 0x33, 0x30, 0x65e5 /* offset 4274 */ , + 0x33, 0x31, 0x65e5 /* offset 4277 */ , + 0x8c48 /* offset 4280 */ , + 0x66f4 /* offset 4281 */ , + 0x8cc8 /* offset 4282 */ , + 0x6ed1 /* offset 4283 */ , + 0x4e32 /* offset 4284 */ , + 0x53e5 /* offset 4285 */ , + 0x5951 /* offset 4286 */ , + 0x5587 /* offset 4287 */ , + 0x5948 /* offset 4288 */ , + 0x61f6 /* offset 4289 */ , + 0x7669 /* offset 4290 */ , + 0x7f85 /* offset 4291 */ , + 0x863f /* offset 4292 */ , + 0x87ba /* offset 4293 */ , + 0x88f8 /* offset 4294 */ , + 0x908f /* offset 4295 */ , + 0x6a02 /* offset 4296 */ , + 0x6d1b /* offset 4297 */ , + 0x70d9 /* offset 4298 */ , + 0x73de /* offset 4299 */ , + 0x843d /* offset 4300 */ , + 0x916a /* offset 4301 */ , + 0x99f1 /* offset 4302 */ , + 0x4e82 /* offset 4303 */ , + 0x5375 /* offset 4304 */ , + 0x6b04 /* offset 4305 */ , + 0x721b /* offset 4306 */ , + 0x862d /* offset 4307 */ , + 0x9e1e /* offset 4308 */ , + 0x5d50 /* offset 4309 */ , + 0x6feb /* offset 4310 */ , + 0x85cd /* offset 4311 */ , + 0x8964 /* offset 4312 */ , + 0x62c9 /* offset 4313 */ , + 0x81d8 /* offset 4314 */ , + 0x881f /* offset 4315 */ , + 0x5eca /* offset 4316 */ , + 0x6717 /* offset 4317 */ , + 0x6d6a /* offset 4318 */ , + 0x72fc /* offset 4319 */ , + 0x90ce /* offset 4320 */ , + 0x4f86 /* offset 4321 */ , + 0x51b7 /* offset 4322 */ , + 0x52de /* offset 4323 */ , + 0x64c4 /* offset 4324 */ , + 0x6ad3 /* offset 4325 */ , + 0x7210 /* offset 4326 */ , + 0x76e7 /* offset 4327 */ , + 0x8606 /* offset 4328 */ , + 0x865c /* offset 4329 */ , + 0x8def /* offset 4330 */ , + 0x9732 /* offset 4331 */ , + 0x9b6f /* offset 4332 */ , + 0x9dfa /* offset 4333 */ , + 0x788c /* offset 4334 */ , + 0x797f /* offset 4335 */ , + 0x7da0 /* offset 4336 */ , + 0x83c9 /* offset 4337 */ , + 0x9304 /* offset 4338 */ , + 0x8ad6 /* offset 4339 */ , + 0x58df /* offset 4340 */ , + 0x5f04 /* offset 4341 */ , + 0x7c60 /* offset 4342 */ , + 0x807e /* offset 4343 */ , + 0x7262 /* offset 4344 */ , + 0x78ca /* offset 4345 */ , + 0x8cc2 /* offset 4346 */ , + 0x96f7 /* offset 4347 */ , + 0x58d8 /* offset 4348 */ , + 0x5c62 /* offset 4349 */ , + 0x6a13 /* offset 4350 */ , + 0x6dda /* offset 4351 */ , + 0x6f0f /* offset 4352 */ , + 0x7d2f /* offset 4353 */ , + 0x7e37 /* offset 4354 */ , + 0x964b /* offset 4355 */ , + 0x52d2 /* offset 4356 */ , + 0x808b /* offset 4357 */ , + 0x51dc /* offset 4358 */ , + 0x51cc /* offset 4359 */ , + 0x7a1c /* offset 4360 */ , + 0x7dbe /* offset 4361 */ , + 0x83f1 /* offset 4362 */ , + 0x9675 /* offset 4363 */ , + 0x8b80 /* offset 4364 */ , + 0x62cf /* offset 4365 */ , + 0x8afe /* offset 4366 */ , + 0x4e39 /* offset 4367 */ , + 0x5be7 /* offset 4368 */ , + 0x6012 /* offset 4369 */ , + 0x7387 /* offset 4370 */ , + 0x7570 /* offset 4371 */ , + 0x5317 /* offset 4372 */ , + 0x78fb /* offset 4373 */ , + 0x4fbf /* offset 4374 */ , + 0x5fa9 /* offset 4375 */ , + 0x4e0d /* offset 4376 */ , + 0x6ccc /* offset 4377 */ , + 0x6578 /* offset 4378 */ , + 0x7d22 /* offset 4379 */ , + 0x53c3 /* offset 4380 */ , + 0x585e /* offset 4381 */ , + 0x7701 /* offset 4382 */ , + 0x8449 /* offset 4383 */ , + 0x8aaa /* offset 4384 */ , + 0x6bba /* offset 4385 */ , + 0x6c88 /* offset 4386 */ , + 0x62fe /* offset 4387 */ , + 0x82e5 /* offset 4388 */ , + 0x63a0 /* offset 4389 */ , + 0x7565 /* offset 4390 */ , + 0x4eae /* offset 4391 */ , + 0x5169 /* offset 4392 */ , + 0x51c9 /* offset 4393 */ , + 0x6881 /* offset 4394 */ , + 0x7ce7 /* offset 4395 */ , + 0x826f /* offset 4396 */ , + 0x8ad2 /* offset 4397 */ , + 0x91cf /* offset 4398 */ , + 0x52f5 /* offset 4399 */ , + 0x5442 /* offset 4400 */ , + 0x5eec /* offset 4401 */ , + 0x65c5 /* offset 4402 */ , + 0x6ffe /* offset 4403 */ , + 0x792a /* offset 4404 */ , + 0x95ad /* offset 4405 */ , + 0x9a6a /* offset 4406 */ , + 0x9e97 /* offset 4407 */ , + 0x9ece /* offset 4408 */ , + 0x66c6 /* offset 4409 */ , + 0x6b77 /* offset 4410 */ , + 0x8f62 /* offset 4411 */ , + 0x5e74 /* offset 4412 */ , + 0x6190 /* offset 4413 */ , + 0x6200 /* offset 4414 */ , + 0x649a /* offset 4415 */ , + 0x6f23 /* offset 4416 */ , + 0x7149 /* offset 4417 */ , + 0x7489 /* offset 4418 */ , + 0x79ca /* offset 4419 */ , + 0x7df4 /* offset 4420 */ , + 0x806f /* offset 4421 */ , + 0x8f26 /* offset 4422 */ , + 0x84ee /* offset 4423 */ , + 0x9023 /* offset 4424 */ , + 0x934a /* offset 4425 */ , + 0x5217 /* offset 4426 */ , + 0x52a3 /* offset 4427 */ , + 0x54bd /* offset 4428 */ , + 0x70c8 /* offset 4429 */ , + 0x88c2 /* offset 4430 */ , + 0x5ec9 /* offset 4431 */ , + 0x5ff5 /* offset 4432 */ , + 0x637b /* offset 4433 */ , + 0x6bae /* offset 4434 */ , + 0x7c3e /* offset 4435 */ , + 0x7375 /* offset 4436 */ , + 0x4ee4 /* offset 4437 */ , + 0x56f9 /* offset 4438 */ , + 0x5dba /* offset 4439 */ , + 0x601c /* offset 4440 */ , + 0x73b2 /* offset 4441 */ , + 0x7469 /* offset 4442 */ , + 0x7f9a /* offset 4443 */ , + 0x8046 /* offset 4444 */ , + 0x9234 /* offset 4445 */ , + 0x96f6 /* offset 4446 */ , + 0x9748 /* offset 4447 */ , + 0x9818 /* offset 4448 */ , + 0x4f8b /* offset 4449 */ , + 0x79ae /* offset 4450 */ , + 0x91b4 /* offset 4451 */ , + 0x96b8 /* offset 4452 */ , + 0x60e1 /* offset 4453 */ , + 0x4e86 /* offset 4454 */ , + 0x50da /* offset 4455 */ , + 0x5bee /* offset 4456 */ , + 0x5c3f /* offset 4457 */ , + 0x6599 /* offset 4458 */ , + 0x71ce /* offset 4459 */ , + 0x7642 /* offset 4460 */ , + 0x84fc /* offset 4461 */ , + 0x907c /* offset 4462 */ , + 0x6688 /* offset 4463 */ , + 0x962e /* offset 4464 */ , + 0x5289 /* offset 4465 */ , + 0x677b /* offset 4466 */ , + 0x67f3 /* offset 4467 */ , + 0x6d41 /* offset 4468 */ , + 0x6e9c /* offset 4469 */ , + 0x7409 /* offset 4470 */ , + 0x7559 /* offset 4471 */ , + 0x786b /* offset 4472 */ , + 0x7d10 /* offset 4473 */ , + 0x985e /* offset 4474 */ , + 0x622e /* offset 4475 */ , + 0x9678 /* offset 4476 */ , + 0x502b /* offset 4477 */ , + 0x5d19 /* offset 4478 */ , + 0x6dea /* offset 4479 */ , + 0x8f2a /* offset 4480 */ , + 0x5f8b /* offset 4481 */ , + 0x6144 /* offset 4482 */ , + 0x6817 /* offset 4483 */ , + 0x9686 /* offset 4484 */ , + 0x5229 /* offset 4485 */ , + 0x540f /* offset 4486 */ , + 0x5c65 /* offset 4487 */ , + 0x6613 /* offset 4488 */ , + 0x674e /* offset 4489 */ , + 0x68a8 /* offset 4490 */ , + 0x6ce5 /* offset 4491 */ , + 0x7406 /* offset 4492 */ , + 0x75e2 /* offset 4493 */ , + 0x7f79 /* offset 4494 */ , + 0x88cf /* offset 4495 */ , + 0x88e1 /* offset 4496 */ , + 0x96e2 /* offset 4497 */ , + 0x533f /* offset 4498 */ , + 0x6eba /* offset 4499 */ , + 0x541d /* offset 4500 */ , + 0x71d0 /* offset 4501 */ , + 0x7498 /* offset 4502 */ , + 0x85fa /* offset 4503 */ , + 0x96a3 /* offset 4504 */ , + 0x9c57 /* offset 4505 */ , + 0x9e9f /* offset 4506 */ , + 0x6797 /* offset 4507 */ , + 0x6dcb /* offset 4508 */ , + 0x81e8 /* offset 4509 */ , + 0x7b20 /* offset 4510 */ , + 0x7c92 /* offset 4511 */ , + 0x72c0 /* offset 4512 */ , + 0x7099 /* offset 4513 */ , + 0x8b58 /* offset 4514 */ , + 0x4ec0 /* offset 4515 */ , + 0x8336 /* offset 4516 */ , + 0x523a /* offset 4517 */ , + 0x5207 /* offset 4518 */ , + 0x5ea6 /* offset 4519 */ , + 0x62d3 /* offset 4520 */ , + 0x7cd6 /* offset 4521 */ , + 0x5b85 /* offset 4522 */ , + 0x6d1e /* offset 4523 */ , + 0x66b4 /* offset 4524 */ , + 0x8f3b /* offset 4525 */ , + 0x964d /* offset 4526 */ , + 0x5ed3 /* offset 4527 */ , + 0x5140 /* offset 4528 */ , + 0x55c0 /* offset 4529 */ , + 0x585a /* offset 4530 */ , + 0x6674 /* offset 4531 */ , + 0x51de /* offset 4532 */ , + 0x732a /* offset 4533 */ , + 0x76ca /* offset 4534 */ , + 0x793c /* offset 4535 */ , + 0x795e /* offset 4536 */ , + 0x7965 /* offset 4537 */ , + 0x798f /* offset 4538 */ , + 0x9756 /* offset 4539 */ , + 0x7cbe /* offset 4540 */ , + 0x8612 /* offset 4541 */ , + 0x8af8 /* offset 4542 */ , + 0x9038 /* offset 4543 */ , + 0x90fd /* offset 4544 */ , + 0x98ef /* offset 4545 */ , + 0x98fc /* offset 4546 */ , + 0x9928 /* offset 4547 */ , + 0x9db4 /* offset 4548 */ , + 0x4fae /* offset 4549 */ , + 0x50e7 /* offset 4550 */ , + 0x514d /* offset 4551 */ , + 0x52c9 /* offset 4552 */ , + 0x52e4 /* offset 4553 */ , + 0x5351 /* offset 4554 */ , + 0x559d /* offset 4555 */ , + 0x5606 /* offset 4556 */ , + 0x5668 /* offset 4557 */ , + 0x5840 /* offset 4558 */ , + 0x58a8 /* offset 4559 */ , + 0x5c64 /* offset 4560 */ , + 0x6094 /* offset 4561 */ , + 0x6168 /* offset 4562 */ , + 0x618e /* offset 4563 */ , + 0x61f2 /* offset 4564 */ , + 0x654f /* offset 4565 */ , + 0x65e2 /* offset 4566 */ , + 0x6691 /* offset 4567 */ , + 0x6885 /* offset 4568 */ , + 0x6d77 /* offset 4569 */ , + 0x6e1a /* offset 4570 */ , + 0x6f22 /* offset 4571 */ , + 0x716e /* offset 4572 */ , + 0x722b /* offset 4573 */ , + 0x7422 /* offset 4574 */ , + 0x7891 /* offset 4575 */ , + 0x7949 /* offset 4576 */ , + 0x7948 /* offset 4577 */ , + 0x7950 /* offset 4578 */ , + 0x7956 /* offset 4579 */ , + 0x798d /* offset 4580 */ , + 0x798e /* offset 4581 */ , + 0x7a40 /* offset 4582 */ , + 0x7a81 /* offset 4583 */ , + 0x7bc0 /* offset 4584 */ , + 0x7e09 /* offset 4585 */ , + 0x7e41 /* offset 4586 */ , + 0x7f72 /* offset 4587 */ , + 0x8005 /* offset 4588 */ , + 0x81ed /* offset 4589 */ , + 0x8279 /* offset 4590 */ , + 0x8457 /* offset 4591 */ , + 0x8910 /* offset 4592 */ , + 0x8996 /* offset 4593 */ , + 0x8b01 /* offset 4594 */ , + 0x8b39 /* offset 4595 */ , + 0x8cd3 /* offset 4596 */ , + 0x8d08 /* offset 4597 */ , + 0x8fb6 /* offset 4598 */ , + 0x96e3 /* offset 4599 */ , + 0x97ff /* offset 4600 */ , + 0x983b /* offset 4601 */ , + 0x66, 0x66 /* offset 4602 */ , + 0x66, 0x69 /* offset 4604 */ , + 0x66, 0x6c /* offset 4606 */ , + 0x66, 0x66, 0x69 /* offset 4608 */ , + 0x66, 0x66, 0x6c /* offset 4611 */ , + 0x73, 0x74 /* offset 4614 */ , + 0x574, 0x576 /* offset 4616 */ , + 0x574, 0x565 /* offset 4618 */ , + 0x574, 0x56b /* offset 4620 */ , + 0x57e, 0x576 /* offset 4622 */ , + 0x574, 0x56d /* offset 4624 */ , + 0x5d9, 0x5b4 /* offset 4626 */ , + 0x5f2, 0x5b7 /* offset 4628 */ , + 0x5e2 /* offset 4630 */ , + 0x5d4 /* offset 4631 */ , + 0x5db /* offset 4632 */ , + 0x5dc /* offset 4633 */ , + 0x5dd /* offset 4634 */ , + 0x5e8 /* offset 4635 */ , + 0x5ea /* offset 4636 */ , + 0x5e9, 0x5c1 /* offset 4637 */ , + 0x5e9, 0x5c2 /* offset 4639 */ , + 0x5e9, 0x5bc, 0x5c1 /* offset 4641 */ , + 0x5e9, 0x5bc, 0x5c2 /* offset 4644 */ , + 0x5d0, 0x5b7 /* offset 4647 */ , + 0x5d0, 0x5b8 /* offset 4649 */ , + 0x5d0, 0x5bc /* offset 4651 */ , + 0x5d1, 0x5bc /* offset 4653 */ , + 0x5d2, 0x5bc /* offset 4655 */ , + 0x5d3, 0x5bc /* offset 4657 */ , + 0x5d4, 0x5bc /* offset 4659 */ , + 0x5d5, 0x5bc /* offset 4661 */ , + 0x5d6, 0x5bc /* offset 4663 */ , + 0x5d8, 0x5bc /* offset 4665 */ , + 0x5d9, 0x5bc /* offset 4667 */ , + 0x5da, 0x5bc /* offset 4669 */ , + 0x5db, 0x5bc /* offset 4671 */ , + 0x5dc, 0x5bc /* offset 4673 */ , + 0x5de, 0x5bc /* offset 4675 */ , + 0x5e0, 0x5bc /* offset 4677 */ , + 0x5e1, 0x5bc /* offset 4679 */ , + 0x5e3, 0x5bc /* offset 4681 */ , + 0x5e4, 0x5bc /* offset 4683 */ , + 0x5e6, 0x5bc /* offset 4685 */ , + 0x5e7, 0x5bc /* offset 4687 */ , + 0x5e8, 0x5bc /* offset 4689 */ , + 0x5e9, 0x5bc /* offset 4691 */ , + 0x5ea, 0x5bc /* offset 4693 */ , + 0x5d5, 0x5b9 /* offset 4695 */ , + 0x5d1, 0x5bf /* offset 4697 */ , + 0x5db, 0x5bf /* offset 4699 */ , + 0x5e4, 0x5bf /* offset 4701 */ , + 0x5d0, 0x5dc /* offset 4703 */ , + 0x671 /* offset 4705 */ , + 0x67b /* offset 4706 */ , + 0x67e /* offset 4707 */ , + 0x680 /* offset 4708 */ , + 0x67a /* offset 4709 */ , + 0x67f /* offset 4710 */ , + 0x679 /* offset 4711 */ , + 0x6a4 /* offset 4712 */ , + 0x6a6 /* offset 4713 */ , + 0x684 /* offset 4714 */ , + 0x683 /* offset 4715 */ , + 0x686 /* offset 4716 */ , + 0x687 /* offset 4717 */ , + 0x68d /* offset 4718 */ , + 0x68c /* offset 4719 */ , + 0x68e /* offset 4720 */ , + 0x688 /* offset 4721 */ , + 0x698 /* offset 4722 */ , + 0x691 /* offset 4723 */ , + 0x6a9 /* offset 4724 */ , + 0x6af /* offset 4725 */ , + 0x6b3 /* offset 4726 */ , + 0x6b1 /* offset 4727 */ , + 0x6ba /* offset 4728 */ , + 0x6bb /* offset 4729 */ , + 0x6c1 /* offset 4730 */ , + 0x6be /* offset 4731 */ , + 0x6d2 /* offset 4732 */ , + 0x6ad /* offset 4733 */ , + 0x6c7 /* offset 4734 */ , + 0x6c6 /* offset 4735 */ , + 0x6c8 /* offset 4736 */ , + 0x6cb /* offset 4737 */ , + 0x6c5 /* offset 4738 */ , + 0x6c9 /* offset 4739 */ , + 0x6d0 /* offset 4740 */ , + 0x649 /* offset 4741 */ , + 0x64a, 0x654, 0x627 /* offset 4742 */ , + 0x64a, 0x654, 0x6d5 /* offset 4745 */ , + 0x64a, 0x654, 0x648 /* offset 4748 */ , + 0x64a, 0x654, 0x6c7 /* offset 4751 */ , + 0x64a, 0x654, 0x6c6 /* offset 4754 */ , + 0x64a, 0x654, 0x6c8 /* offset 4757 */ , + 0x64a, 0x654, 0x6d0 /* offset 4760 */ , + 0x64a, 0x654, 0x649 /* offset 4763 */ , + 0x6cc /* offset 4766 */ , + 0x64a, 0x654, 0x62c /* offset 4767 */ , + 0x64a, 0x654, 0x62d /* offset 4770 */ , + 0x64a, 0x654, 0x645 /* offset 4773 */ , + 0x64a, 0x654, 0x64a /* offset 4776 */ , + 0x628, 0x62c /* offset 4779 */ , + 0x628, 0x62d /* offset 4781 */ , + 0x628, 0x62e /* offset 4783 */ , + 0x628, 0x645 /* offset 4785 */ , + 0x628, 0x649 /* offset 4787 */ , + 0x628, 0x64a /* offset 4789 */ , + 0x62a, 0x62c /* offset 4791 */ , + 0x62a, 0x62d /* offset 4793 */ , + 0x62a, 0x62e /* offset 4795 */ , + 0x62a, 0x645 /* offset 4797 */ , + 0x62a, 0x649 /* offset 4799 */ , + 0x62a, 0x64a /* offset 4801 */ , + 0x62b, 0x62c /* offset 4803 */ , + 0x62b, 0x645 /* offset 4805 */ , + 0x62b, 0x649 /* offset 4807 */ , + 0x62b, 0x64a /* offset 4809 */ , + 0x62c, 0x62d /* offset 4811 */ , + 0x62c, 0x645 /* offset 4813 */ , + 0x62d, 0x62c /* offset 4815 */ , + 0x62d, 0x645 /* offset 4817 */ , + 0x62e, 0x62c /* offset 4819 */ , + 0x62e, 0x62d /* offset 4821 */ , + 0x62e, 0x645 /* offset 4823 */ , + 0x633, 0x62c /* offset 4825 */ , + 0x633, 0x62d /* offset 4827 */ , + 0x633, 0x62e /* offset 4829 */ , + 0x633, 0x645 /* offset 4831 */ , + 0x635, 0x62d /* offset 4833 */ , + 0x635, 0x645 /* offset 4835 */ , + 0x636, 0x62c /* offset 4837 */ , + 0x636, 0x62d /* offset 4839 */ , + 0x636, 0x62e /* offset 4841 */ , + 0x636, 0x645 /* offset 4843 */ , + 0x637, 0x62d /* offset 4845 */ , + 0x637, 0x645 /* offset 4847 */ , + 0x638, 0x645 /* offset 4849 */ , + 0x639, 0x62c /* offset 4851 */ , + 0x639, 0x645 /* offset 4853 */ , + 0x63a, 0x62c /* offset 4855 */ , + 0x63a, 0x645 /* offset 4857 */ , + 0x641, 0x62c /* offset 4859 */ , + 0x641, 0x62d /* offset 4861 */ , + 0x641, 0x62e /* offset 4863 */ , + 0x641, 0x645 /* offset 4865 */ , + 0x641, 0x649 /* offset 4867 */ , + 0x641, 0x64a /* offset 4869 */ , + 0x642, 0x62d /* offset 4871 */ , + 0x642, 0x645 /* offset 4873 */ , + 0x642, 0x649 /* offset 4875 */ , + 0x642, 0x64a /* offset 4877 */ , + 0x643, 0x627 /* offset 4879 */ , + 0x643, 0x62c /* offset 4881 */ , + 0x643, 0x62d /* offset 4883 */ , + 0x643, 0x62e /* offset 4885 */ , + 0x643, 0x644 /* offset 4887 */ , + 0x643, 0x645 /* offset 4889 */ , + 0x643, 0x649 /* offset 4891 */ , + 0x643, 0x64a /* offset 4893 */ , + 0x644, 0x62c /* offset 4895 */ , + 0x644, 0x62d /* offset 4897 */ , + 0x644, 0x62e /* offset 4899 */ , + 0x644, 0x645 /* offset 4901 */ , + 0x644, 0x649 /* offset 4903 */ , + 0x644, 0x64a /* offset 4905 */ , + 0x645, 0x62c /* offset 4907 */ , + 0x645, 0x62d /* offset 4909 */ , + 0x645, 0x62e /* offset 4911 */ , + 0x645, 0x645 /* offset 4913 */ , + 0x645, 0x649 /* offset 4915 */ , + 0x645, 0x64a /* offset 4917 */ , + 0x646, 0x62c /* offset 4919 */ , + 0x646, 0x62d /* offset 4921 */ , + 0x646, 0x62e /* offset 4923 */ , + 0x646, 0x645 /* offset 4925 */ , + 0x646, 0x649 /* offset 4927 */ , + 0x646, 0x64a /* offset 4929 */ , + 0x647, 0x62c /* offset 4931 */ , + 0x647, 0x645 /* offset 4933 */ , + 0x647, 0x649 /* offset 4935 */ , + 0x647, 0x64a /* offset 4937 */ , + 0x64a, 0x62c /* offset 4939 */ , + 0x64a, 0x62d /* offset 4941 */ , + 0x64a, 0x62e /* offset 4943 */ , + 0x64a, 0x645 /* offset 4945 */ , + 0x64a, 0x649 /* offset 4947 */ , + 0x64a, 0x64a /* offset 4949 */ , + 0x630, 0x670 /* offset 4951 */ , + 0x631, 0x670 /* offset 4953 */ , + 0x649, 0x670 /* offset 4955 */ , + 0x20, 0x64c, 0x651 /* offset 4957 */ , + 0x20, 0x64d, 0x651 /* offset 4960 */ , + 0x20, 0x64e, 0x651 /* offset 4963 */ , + 0x20, 0x64f, 0x651 /* offset 4966 */ , + 0x20, 0x650, 0x651 /* offset 4969 */ , + 0x20, 0x651, 0x670 /* offset 4972 */ , + 0x64a, 0x654, 0x631 /* offset 4975 */ , + 0x64a, 0x654, 0x632 /* offset 4978 */ , + 0x64a, 0x654, 0x646 /* offset 4981 */ , + 0x628, 0x631 /* offset 4984 */ , + 0x628, 0x632 /* offset 4986 */ , + 0x628, 0x646 /* offset 4988 */ , + 0x62a, 0x631 /* offset 4990 */ , + 0x62a, 0x632 /* offset 4992 */ , + 0x62a, 0x646 /* offset 4994 */ , + 0x62b, 0x631 /* offset 4996 */ , + 0x62b, 0x632 /* offset 4998 */ , + 0x62b, 0x646 /* offset 5000 */ , + 0x645, 0x627 /* offset 5002 */ , + 0x646, 0x631 /* offset 5004 */ , + 0x646, 0x632 /* offset 5006 */ , + 0x646, 0x646 /* offset 5008 */ , + 0x64a, 0x631 /* offset 5010 */ , + 0x64a, 0x632 /* offset 5012 */ , + 0x64a, 0x646 /* offset 5014 */ , + 0x64a, 0x654, 0x62e /* offset 5016 */ , + 0x64a, 0x654, 0x647 /* offset 5019 */ , + 0x628, 0x647 /* offset 5022 */ , + 0x62a, 0x647 /* offset 5024 */ , + 0x635, 0x62e /* offset 5026 */ , + 0x644, 0x647 /* offset 5028 */ , + 0x646, 0x647 /* offset 5030 */ , + 0x647, 0x670 /* offset 5032 */ , + 0x64a, 0x647 /* offset 5034 */ , + 0x62b, 0x647 /* offset 5036 */ , + 0x633, 0x647 /* offset 5038 */ , + 0x634, 0x645 /* offset 5040 */ , + 0x634, 0x647 /* offset 5042 */ , + 0x640, 0x64e, 0x651 /* offset 5044 */ , + 0x640, 0x64f, 0x651 /* offset 5047 */ , + 0x640, 0x650, 0x651 /* offset 5050 */ , + 0x637, 0x649 /* offset 5053 */ , + 0x637, 0x64a /* offset 5055 */ , + 0x639, 0x649 /* offset 5057 */ , + 0x639, 0x64a /* offset 5059 */ , + 0x63a, 0x649 /* offset 5061 */ , + 0x63a, 0x64a /* offset 5063 */ , + 0x633, 0x649 /* offset 5065 */ , + 0x633, 0x64a /* offset 5067 */ , + 0x634, 0x649 /* offset 5069 */ , + 0x634, 0x64a /* offset 5071 */ , + 0x62d, 0x649 /* offset 5073 */ , + 0x62d, 0x64a /* offset 5075 */ , + 0x62c, 0x649 /* offset 5077 */ , + 0x62c, 0x64a /* offset 5079 */ , + 0x62e, 0x649 /* offset 5081 */ , + 0x62e, 0x64a /* offset 5083 */ , + 0x635, 0x649 /* offset 5085 */ , + 0x635, 0x64a /* offset 5087 */ , + 0x636, 0x649 /* offset 5089 */ , + 0x636, 0x64a /* offset 5091 */ , + 0x634, 0x62c /* offset 5093 */ , + 0x634, 0x62d /* offset 5095 */ , + 0x634, 0x62e /* offset 5097 */ , + 0x634, 0x631 /* offset 5099 */ , + 0x633, 0x631 /* offset 5101 */ , + 0x635, 0x631 /* offset 5103 */ , + 0x636, 0x631 /* offset 5105 */ , + 0x627, 0x64b /* offset 5107 */ , + 0x62a, 0x62c, 0x645 /* offset 5109 */ , + 0x62a, 0x62d, 0x62c /* offset 5112 */ , + 0x62a, 0x62d, 0x645 /* offset 5115 */ , + 0x62a, 0x62e, 0x645 /* offset 5118 */ , + 0x62a, 0x645, 0x62c /* offset 5121 */ , + 0x62a, 0x645, 0x62d /* offset 5124 */ , + 0x62a, 0x645, 0x62e /* offset 5127 */ , + 0x62c, 0x645, 0x62d /* offset 5130 */ , + 0x62d, 0x645, 0x64a /* offset 5133 */ , + 0x62d, 0x645, 0x649 /* offset 5136 */ , + 0x633, 0x62d, 0x62c /* offset 5139 */ , + 0x633, 0x62c, 0x62d /* offset 5142 */ , + 0x633, 0x62c, 0x649 /* offset 5145 */ , + 0x633, 0x645, 0x62d /* offset 5148 */ , + 0x633, 0x645, 0x62c /* offset 5151 */ , + 0x633, 0x645, 0x645 /* offset 5154 */ , + 0x635, 0x62d, 0x62d /* offset 5157 */ , + 0x635, 0x645, 0x645 /* offset 5160 */ , + 0x634, 0x62d, 0x645 /* offset 5163 */ , + 0x634, 0x62c, 0x64a /* offset 5166 */ , + 0x634, 0x645, 0x62e /* offset 5169 */ , + 0x634, 0x645, 0x645 /* offset 5172 */ , + 0x636, 0x62d, 0x649 /* offset 5175 */ , + 0x636, 0x62e, 0x645 /* offset 5178 */ , + 0x637, 0x645, 0x62d /* offset 5181 */ , + 0x637, 0x645, 0x645 /* offset 5184 */ , + 0x637, 0x645, 0x64a /* offset 5187 */ , + 0x639, 0x62c, 0x645 /* offset 5190 */ , + 0x639, 0x645, 0x645 /* offset 5193 */ , + 0x639, 0x645, 0x649 /* offset 5196 */ , + 0x63a, 0x645, 0x645 /* offset 5199 */ , + 0x63a, 0x645, 0x64a /* offset 5202 */ , + 0x63a, 0x645, 0x649 /* offset 5205 */ , + 0x641, 0x62e, 0x645 /* offset 5208 */ , + 0x642, 0x645, 0x62d /* offset 5211 */ , + 0x642, 0x645, 0x645 /* offset 5214 */ , + 0x644, 0x62d, 0x645 /* offset 5217 */ , + 0x644, 0x62d, 0x64a /* offset 5220 */ , + 0x644, 0x62d, 0x649 /* offset 5223 */ , + 0x644, 0x62c, 0x62c /* offset 5226 */ , + 0x644, 0x62e, 0x645 /* offset 5229 */ , + 0x644, 0x645, 0x62d /* offset 5232 */ , + 0x645, 0x62d, 0x62c /* offset 5235 */ , + 0x645, 0x62d, 0x645 /* offset 5238 */ , + 0x645, 0x62d, 0x64a /* offset 5241 */ , + 0x645, 0x62c, 0x62d /* offset 5244 */ , + 0x645, 0x62c, 0x645 /* offset 5247 */ , + 0x645, 0x62e, 0x62c /* offset 5250 */ , + 0x645, 0x62e, 0x645 /* offset 5253 */ , + 0x645, 0x62c, 0x62e /* offset 5256 */ , + 0x647, 0x645, 0x62c /* offset 5259 */ , + 0x647, 0x645, 0x645 /* offset 5262 */ , + 0x646, 0x62d, 0x645 /* offset 5265 */ , + 0x646, 0x62d, 0x649 /* offset 5268 */ , + 0x646, 0x62c, 0x645 /* offset 5271 */ , + 0x646, 0x62c, 0x649 /* offset 5274 */ , + 0x646, 0x645, 0x64a /* offset 5277 */ , + 0x646, 0x645, 0x649 /* offset 5280 */ , + 0x64a, 0x645, 0x645 /* offset 5283 */ , + 0x628, 0x62e, 0x64a /* offset 5286 */ , + 0x62a, 0x62c, 0x64a /* offset 5289 */ , + 0x62a, 0x62c, 0x649 /* offset 5292 */ , + 0x62a, 0x62e, 0x64a /* offset 5295 */ , + 0x62a, 0x62e, 0x649 /* offset 5298 */ , + 0x62a, 0x645, 0x64a /* offset 5301 */ , + 0x62a, 0x645, 0x649 /* offset 5304 */ , + 0x62c, 0x645, 0x64a /* offset 5307 */ , + 0x62c, 0x62d, 0x649 /* offset 5310 */ , + 0x62c, 0x645, 0x649 /* offset 5313 */ , + 0x633, 0x62e, 0x649 /* offset 5316 */ , + 0x635, 0x62d, 0x64a /* offset 5319 */ , + 0x634, 0x62d, 0x64a /* offset 5322 */ , + 0x636, 0x62d, 0x64a /* offset 5325 */ , + 0x644, 0x62c, 0x64a /* offset 5328 */ , + 0x644, 0x645, 0x64a /* offset 5331 */ , + 0x64a, 0x62d, 0x64a /* offset 5334 */ , + 0x64a, 0x62c, 0x64a /* offset 5337 */ , + 0x64a, 0x645, 0x64a /* offset 5340 */ , + 0x645, 0x645, 0x64a /* offset 5343 */ , + 0x642, 0x645, 0x64a /* offset 5346 */ , + 0x646, 0x62d, 0x64a /* offset 5349 */ , + 0x639, 0x645, 0x64a /* offset 5352 */ , + 0x643, 0x645, 0x64a /* offset 5355 */ , + 0x646, 0x62c, 0x62d /* offset 5358 */ , + 0x645, 0x62e, 0x64a /* offset 5361 */ , + 0x644, 0x62c, 0x645 /* offset 5364 */ , + 0x643, 0x645, 0x645 /* offset 5367 */ , + 0x62c, 0x62d, 0x64a /* offset 5370 */ , + 0x62d, 0x62c, 0x64a /* offset 5373 */ , + 0x645, 0x62c, 0x64a /* offset 5376 */ , + 0x641, 0x645, 0x64a /* offset 5379 */ , + 0x628, 0x62d, 0x64a /* offset 5382 */ , + 0x633, 0x62e, 0x64a /* offset 5385 */ , + 0x646, 0x62c, 0x64a /* offset 5388 */ , + 0x635, 0x644, 0x6d2 /* offset 5391 */ , + 0x642, 0x644, 0x6d2 /* offset 5394 */ , + 0x627, 0x644, 0x644, 0x647 /* offset 5397 */ , + 0x627, 0x643, 0x628, 0x631 /* offset 5401 */ , + 0x645, 0x62d, 0x645, 0x62f /* offset 5405 */ , + 0x635, 0x644, 0x639, 0x645 /* offset 5409 */ , + 0x631, 0x633, 0x648, 0x644 /* offset 5413 */ , + 0x639, 0x644, 0x64a, 0x647 /* offset 5417 */ , + 0x648, 0x633, 0x644, 0x645 /* offset 5421 */ , + 0x635, 0x644, 0x649 /* offset 5425 */ , + 0x635, 0x644, 0x649, 0x20, 0x627, 0x644, 0x644, 0x647, 0x20, 0x639, 0x644, 0x64a, 0x647, 0x20, 0x648, 0x633, 0x644, 0x645 /* offset 5428 */ , + 0x62c, 0x644, 0x20, 0x62c, 0x644, 0x627, 0x644, 0x647 /* offset 5446 */ , + 0x631, 0x6cc, 0x627, 0x644 /* offset 5454 */ , + 0x2014 /* offset 5458 */ , + 0x2013 /* offset 5459 */ , + 0x5f /* offset 5460 */ , + 0x7b /* offset 5461 */ , + 0x7d /* offset 5462 */ , + 0x3014 /* offset 5463 */ , + 0x3015 /* offset 5464 */ , + 0x3010 /* offset 5465 */ , + 0x3011 /* offset 5466 */ , + 0x300a /* offset 5467 */ , + 0x300b /* offset 5468 */ , + 0x300c /* offset 5469 */ , + 0x300d /* offset 5470 */ , + 0x300e /* offset 5471 */ , + 0x300f /* offset 5472 */ , + 0x2c /* offset 5473 */ , + 0x3001 /* offset 5474 */ , + 0x3a /* offset 5475 */ , + 0x3f /* offset 5476 */ , + 0x21 /* offset 5477 */ , + 0x23 /* offset 5478 */ , + 0x26 /* offset 5479 */ , + 0x2a /* offset 5480 */ , + 0x2d /* offset 5481 */ , + 0x3c /* offset 5482 */ , + 0x3e /* offset 5483 */ , + 0x5c /* offset 5484 */ , + 0x24 /* offset 5485 */ , + 0x25 /* offset 5486 */ , + 0x40 /* offset 5487 */ , + 0x20, 0x64b /* offset 5488 */ , + 0x640, 0x64b /* offset 5490 */ , + 0x20, 0x64c /* offset 5492 */ , + 0x20, 0x64d /* offset 5494 */ , + 0x20, 0x64e /* offset 5496 */ , + 0x640, 0x64e /* offset 5498 */ , + 0x20, 0x64f /* offset 5500 */ , + 0x640, 0x64f /* offset 5502 */ , + 0x20, 0x650 /* offset 5504 */ , + 0x640, 0x650 /* offset 5506 */ , + 0x20, 0x651 /* offset 5508 */ , + 0x640, 0x651 /* offset 5510 */ , + 0x20, 0x652 /* offset 5512 */ , + 0x640, 0x652 /* offset 5514 */ , + 0x621 /* offset 5516 */ , + 0x627 /* offset 5517 */ , + 0x628 /* offset 5518 */ , + 0x629 /* offset 5519 */ , + 0x62a /* offset 5520 */ , + 0x62b /* offset 5521 */ , + 0x62c /* offset 5522 */ , + 0x62d /* offset 5523 */ , + 0x62e /* offset 5524 */ , + 0x62f /* offset 5525 */ , + 0x630 /* offset 5526 */ , + 0x631 /* offset 5527 */ , + 0x632 /* offset 5528 */ , + 0x633 /* offset 5529 */ , + 0x634 /* offset 5530 */ , + 0x635 /* offset 5531 */ , + 0x636 /* offset 5532 */ , + 0x637 /* offset 5533 */ , + 0x638 /* offset 5534 */ , + 0x639 /* offset 5535 */ , + 0x63a /* offset 5536 */ , + 0x641 /* offset 5537 */ , + 0x642 /* offset 5538 */ , + 0x643 /* offset 5539 */ , + 0x644 /* offset 5540 */ , + 0x645 /* offset 5541 */ , + 0x646 /* offset 5542 */ , + 0x647 /* offset 5543 */ , + 0x648 /* offset 5544 */ , + 0x64a /* offset 5545 */ , + 0x644, 0x627, 0x653 /* offset 5546 */ , + 0x644, 0x627, 0x654 /* offset 5549 */ , + 0x644, 0x627, 0x655 /* offset 5552 */ , + 0x644, 0x627 /* offset 5555 */ , + 0x22 /* offset 5557 */ , + 0x27 /* offset 5558 */ , + 0x2f /* offset 5559 */ , + 0x5b /* offset 5560 */ , + 0x5d /* offset 5561 */ , + 0x5e /* offset 5562 */ , + 0x7c /* offset 5563 */ , + 0x7e /* offset 5564 */ , + 0x2985 /* offset 5565 */ , + 0x2986 /* offset 5566 */ , + 0x3002 /* offset 5567 */ , + 0x30fb /* offset 5568 */ , + 0x30a1 /* offset 5569 */ , + 0x30a3 /* offset 5570 */ , + 0x30a5 /* offset 5571 */ , + 0x30a7 /* offset 5572 */ , + 0x30a9 /* offset 5573 */ , + 0x30e3 /* offset 5574 */ , + 0x30e5 /* offset 5575 */ , + 0x30e7 /* offset 5576 */ , + 0x30c3 /* offset 5577 */ , + 0x30fc /* offset 5578 */ , + 0x30f3 /* offset 5579 */ , + 0x3099 /* offset 5580 */ , + 0x309a /* offset 5581 */ , + 0xa2 /* offset 5582 */ , + 0xa3 /* offset 5583 */ , + 0xac /* offset 5584 */ , + 0xa6 /* offset 5585 */ , + 0xa5 /* offset 5586 */ , + 0x20a9 /* offset 5587 */ , + 0x2502 /* offset 5588 */ , + 0x2190 /* offset 5589 */ , + 0x2191 /* offset 5590 */ , + 0x2192 /* offset 5591 */ , + 0x2193 /* offset 5592 */ , + 0x25a0 /* offset 5593 */ , + 0x25cb /* offset 5594 */ , + 0x1d157, 0x1d165 /* offset 5595 */ , + 0x1d158, 0x1d165 /* offset 5597 */ , + 0x1d158, 0x1d165, 0x1d16e /* offset 5599 */ , + 0x1d158, 0x1d165, 0x1d16f /* offset 5602 */ , + 0x1d158, 0x1d165, 0x1d170 /* offset 5605 */ , + 0x1d158, 0x1d165, 0x1d171 /* offset 5608 */ , + 0x1d158, 0x1d165, 0x1d172 /* offset 5611 */ , + 0x1d1b9, 0x1d165 /* offset 5614 */ , + 0x1d1ba, 0x1d165 /* offset 5616 */ , + 0x1d1b9, 0x1d165, 0x1d16e /* offset 5618 */ , + 0x1d1ba, 0x1d165, 0x1d16e /* offset 5621 */ , + 0x1d1b9, 0x1d165, 0x1d16f /* offset 5624 */ , + 0x1d1ba, 0x1d165, 0x1d16f /* offset 5627 */ , + 0x391 /* offset 5630 */ , + 0x392 /* offset 5631 */ , + 0x394 /* offset 5632 */ , + 0x395 /* offset 5633 */ , + 0x396 /* offset 5634 */ , + 0x397 /* offset 5635 */ , + 0x399 /* offset 5636 */ , + 0x39a /* offset 5637 */ , + 0x39b /* offset 5638 */ , + 0x39c /* offset 5639 */ , + 0x39d /* offset 5640 */ , + 0x39e /* offset 5641 */ , + 0x39f /* offset 5642 */ , + 0x3a1 /* offset 5643 */ , + 0x3a3 /* offset 5644 */ , + 0x3a4 /* offset 5645 */ , + 0x3a6 /* offset 5646 */ , + 0x3a7 /* offset 5647 */ , + 0x3a8 /* offset 5648 */ , + 0x2207 /* offset 5649 */ , + 0x3b1 /* offset 5650 */ , + 0x3b4 /* offset 5651 */ , + 0x3b6 /* offset 5652 */ , + 0x3b7 /* offset 5653 */ , + 0x3bb /* offset 5654 */ , + 0x3bd /* offset 5655 */ , + 0x3be /* offset 5656 */ , + 0x3bf /* offset 5657 */ , + 0x3c3 /* offset 5658 */ , + 0x3c4 /* offset 5659 */ , + 0x3c5 /* offset 5660 */ , + 0x3c7 /* offset 5661 */ , + 0x3c8 /* offset 5662 */ , + 0x3c9 /* offset 5663 */ , + 0x2202 /* offset 5664 */ , + 0x4e3d /* offset 5665 */ , + 0x4e38 /* offset 5666 */ , + 0x4e41 /* offset 5667 */ , + 0x20122 /* offset 5668 */ , + 0x4f60 /* offset 5669 */ , + 0x4fbb /* offset 5670 */ , + 0x5002 /* offset 5671 */ , + 0x507a /* offset 5672 */ , + 0x5099 /* offset 5673 */ , + 0x50cf /* offset 5674 */ , + 0x349e /* offset 5675 */ , + 0x2063a /* offset 5676 */ , + 0x5154 /* offset 5677 */ , + 0x5164 /* offset 5678 */ , + 0x5177 /* offset 5679 */ , + 0x2051c /* offset 5680 */ , + 0x34b9 /* offset 5681 */ , + 0x5167 /* offset 5682 */ , + 0x518d /* offset 5683 */ , + 0x2054b /* offset 5684 */ , + 0x5197 /* offset 5685 */ , + 0x51a4 /* offset 5686 */ , + 0x4ecc /* offset 5687 */ , + 0x51ac /* offset 5688 */ , + 0x51b5 /* offset 5689 */ , + 0x291df /* offset 5690 */ , + 0x5203 /* offset 5691 */ , + 0x34df /* offset 5692 */ , + 0x523b /* offset 5693 */ , + 0x5246 /* offset 5694 */ , + 0x5272 /* offset 5695 */ , + 0x5277 /* offset 5696 */ , + 0x3515 /* offset 5697 */ , + 0x52c7 /* offset 5698 */ , + 0x52fa /* offset 5699 */ , + 0x5305 /* offset 5700 */ , + 0x5306 /* offset 5701 */ , + 0x5349 /* offset 5702 */ , + 0x535a /* offset 5703 */ , + 0x5373 /* offset 5704 */ , + 0x537d /* offset 5705 */ , + 0x537f /* offset 5706 */ , + 0x20a2c /* offset 5707 */ , + 0x7070 /* offset 5708 */ , + 0x53ca /* offset 5709 */ , + 0x53df /* offset 5710 */ , + 0x20b63 /* offset 5711 */ , + 0x53eb /* offset 5712 */ , + 0x53f1 /* offset 5713 */ , + 0x5406 /* offset 5714 */ , + 0x549e /* offset 5715 */ , + 0x5438 /* offset 5716 */ , + 0x5448 /* offset 5717 */ , + 0x5468 /* offset 5718 */ , + 0x54a2 /* offset 5719 */ , + 0x54f6 /* offset 5720 */ , + 0x5510 /* offset 5721 */ , + 0x5553 /* offset 5722 */ , + 0x5563 /* offset 5723 */ , + 0x5584 /* offset 5724 */ , + 0x5599 /* offset 5725 */ , + 0x55ab /* offset 5726 */ , + 0x55b3 /* offset 5727 */ , + 0x55c2 /* offset 5728 */ , + 0x5716 /* offset 5729 */ , + 0x5717 /* offset 5730 */ , + 0x5651 /* offset 5731 */ , + 0x5674 /* offset 5732 */ , + 0x58ee /* offset 5733 */ , + 0x57ce /* offset 5734 */ , + 0x57f4 /* offset 5735 */ , + 0x580d /* offset 5736 */ , + 0x578b /* offset 5737 */ , + 0x5832 /* offset 5738 */ , + 0x5831 /* offset 5739 */ , + 0x58ac /* offset 5740 */ , + 0x214e4 /* offset 5741 */ , + 0x58f2 /* offset 5742 */ , + 0x58f7 /* offset 5743 */ , + 0x5906 /* offset 5744 */ , + 0x591a /* offset 5745 */ , + 0x5922 /* offset 5746 */ , + 0x5962 /* offset 5747 */ , + 0x216a8 /* offset 5748 */ , + 0x216ea /* offset 5749 */ , + 0x59ec /* offset 5750 */ , + 0x5a1b /* offset 5751 */ , + 0x5a27 /* offset 5752 */ , + 0x59d8 /* offset 5753 */ , + 0x5a66 /* offset 5754 */ , + 0x36ee /* offset 5755 */ , + 0x2136a /* offset 5756 */ , + 0x5b08 /* offset 5757 */ , + 0x5b3e /* offset 5758 */ , + 0x219c8 /* offset 5759 */ , + 0x5bc3 /* offset 5760 */ , + 0x5bd8 /* offset 5761 */ , + 0x5bf3 /* offset 5762 */ , + 0x21b18 /* offset 5763 */ , + 0x5bff /* offset 5764 */ , + 0x5c06 /* offset 5765 */ , + 0x5f33 /* offset 5766 */ , + 0x3781 /* offset 5767 */ , + 0x5c60 /* offset 5768 */ , + 0x5cc0 /* offset 5769 */ , + 0x5c8d /* offset 5770 */ , + 0x21de4 /* offset 5771 */ , + 0x5d43 /* offset 5772 */ , + 0x21de6 /* offset 5773 */ , + 0x5d6e /* offset 5774 */ , + 0x5d6b /* offset 5775 */ , + 0x5d7c /* offset 5776 */ , + 0x5de1 /* offset 5777 */ , + 0x5de2 /* offset 5778 */ , + 0x382f /* offset 5779 */ , + 0x5dfd /* offset 5780 */ , + 0x5e28 /* offset 5781 */ , + 0x5e3d /* offset 5782 */ , + 0x5e69 /* offset 5783 */ , + 0x3862 /* offset 5784 */ , + 0x22183 /* offset 5785 */ , + 0x387c /* offset 5786 */ , + 0x5eb0 /* offset 5787 */ , + 0x5eb3 /* offset 5788 */ , + 0x5eb6 /* offset 5789 */ , + 0x2a392 /* offset 5790 */ , + 0x22331 /* offset 5791 */ , + 0x8201 /* offset 5792 */ , + 0x5f22 /* offset 5793 */ , + 0x38c7 /* offset 5794 */ , + 0x232b8 /* offset 5795 */ , + 0x261da /* offset 5796 */ , + 0x5f62 /* offset 5797 */ , + 0x5f6b /* offset 5798 */ , + 0x38e3 /* offset 5799 */ , + 0x5f9a /* offset 5800 */ , + 0x5fcd /* offset 5801 */ , + 0x5fd7 /* offset 5802 */ , + 0x5ff9 /* offset 5803 */ , + 0x6081 /* offset 5804 */ , + 0x393a /* offset 5805 */ , + 0x391c /* offset 5806 */ , + 0x226d4 /* offset 5807 */ , + 0x60c7 /* offset 5808 */ , + 0x6148 /* offset 5809 */ , + 0x614c /* offset 5810 */ , + 0x614e /* offset 5811 */ , + 0x617a /* offset 5812 */ , + 0x61b2 /* offset 5813 */ , + 0x61a4 /* offset 5814 */ , + 0x61af /* offset 5815 */ , + 0x61de /* offset 5816 */ , + 0x6210 /* offset 5817 */ , + 0x621b /* offset 5818 */ , + 0x625d /* offset 5819 */ , + 0x62b1 /* offset 5820 */ , + 0x62d4 /* offset 5821 */ , + 0x6350 /* offset 5822 */ , + 0x22b0c /* offset 5823 */ , + 0x633d /* offset 5824 */ , + 0x62fc /* offset 5825 */ , + 0x6368 /* offset 5826 */ , + 0x6383 /* offset 5827 */ , + 0x63e4 /* offset 5828 */ , + 0x22bf1 /* offset 5829 */ , + 0x6422 /* offset 5830 */ , + 0x63c5 /* offset 5831 */ , + 0x63a9 /* offset 5832 */ , + 0x3a2e /* offset 5833 */ , + 0x6469 /* offset 5834 */ , + 0x647e /* offset 5835 */ , + 0x649d /* offset 5836 */ , + 0x6477 /* offset 5837 */ , + 0x3a6c /* offset 5838 */ , + 0x656c /* offset 5839 */ , + 0x2300a /* offset 5840 */ , + 0x65e3 /* offset 5841 */ , + 0x66f8 /* offset 5842 */ , + 0x6649 /* offset 5843 */ , + 0x3b19 /* offset 5844 */ , + 0x3b08 /* offset 5845 */ , + 0x3ae4 /* offset 5846 */ , + 0x5192 /* offset 5847 */ , + 0x5195 /* offset 5848 */ , + 0x6700 /* offset 5849 */ , + 0x669c /* offset 5850 */ , + 0x80ad /* offset 5851 */ , + 0x43d9 /* offset 5852 */ , + 0x671b /* offset 5853 */ , + 0x6721 /* offset 5854 */ , + 0x675e /* offset 5855 */ , + 0x6753 /* offset 5856 */ , + 0x233c3 /* offset 5857 */ , + 0x3b49 /* offset 5858 */ , + 0x67fa /* offset 5859 */ , + 0x6785 /* offset 5860 */ , + 0x6852 /* offset 5861 */ , + 0x2346d /* offset 5862 */ , + 0x688e /* offset 5863 */ , + 0x681f /* offset 5864 */ , + 0x6914 /* offset 5865 */ , + 0x3b9d /* offset 5866 */ , + 0x6942 /* offset 5867 */ , + 0x69a3 /* offset 5868 */ , + 0x69ea /* offset 5869 */ , + 0x6aa8 /* offset 5870 */ , + 0x236a3 /* offset 5871 */ , + 0x6adb /* offset 5872 */ , + 0x3c18 /* offset 5873 */ , + 0x6b21 /* offset 5874 */ , + 0x238a7 /* offset 5875 */ , + 0x6b54 /* offset 5876 */ , + 0x3c4e /* offset 5877 */ , + 0x6b72 /* offset 5878 */ , + 0x6b9f /* offset 5879 */ , + 0x6bbb /* offset 5880 */ , + 0x23a8d /* offset 5881 */ , + 0x21d0b /* offset 5882 */ , + 0x23afa /* offset 5883 */ , + 0x6c4e /* offset 5884 */ , + 0x23cbc /* offset 5885 */ , + 0x6cbf /* offset 5886 */ , + 0x6ccd /* offset 5887 */ , + 0x6c67 /* offset 5888 */ , + 0x6d16 /* offset 5889 */ , + 0x6d3e /* offset 5890 */ , + 0x6d69 /* offset 5891 */ , + 0x6d78 /* offset 5892 */ , + 0x6d85 /* offset 5893 */ , + 0x23d1e /* offset 5894 */ , + 0x6d34 /* offset 5895 */ , + 0x6e2f /* offset 5896 */ , + 0x6e6e /* offset 5897 */ , + 0x3d33 /* offset 5898 */ , + 0x6ecb /* offset 5899 */ , + 0x6ec7 /* offset 5900 */ , + 0x23ed1 /* offset 5901 */ , + 0x6df9 /* offset 5902 */ , + 0x6f6e /* offset 5903 */ , + 0x23f5e /* offset 5904 */ , + 0x23f8e /* offset 5905 */ , + 0x6fc6 /* offset 5906 */ , + 0x7039 /* offset 5907 */ , + 0x701e /* offset 5908 */ , + 0x701b /* offset 5909 */ , + 0x3d96 /* offset 5910 */ , + 0x704a /* offset 5911 */ , + 0x707d /* offset 5912 */ , + 0x7077 /* offset 5913 */ , + 0x70ad /* offset 5914 */ , + 0x20525 /* offset 5915 */ , + 0x7145 /* offset 5916 */ , + 0x24263 /* offset 5917 */ , + 0x719c /* offset 5918 */ , + 0x43ab /* offset 5919 */ , + 0x7228 /* offset 5920 */ , + 0x7235 /* offset 5921 */ , + 0x7250 /* offset 5922 */ , + 0x24608 /* offset 5923 */ , + 0x7280 /* offset 5924 */ , + 0x7295 /* offset 5925 */ , + 0x24735 /* offset 5926 */ , + 0x24814 /* offset 5927 */ , + 0x737a /* offset 5928 */ , + 0x738b /* offset 5929 */ , + 0x3eac /* offset 5930 */ , + 0x73a5 /* offset 5931 */ , + 0x3eb8 /* offset 5932 */ , + 0x7447 /* offset 5933 */ , + 0x745c /* offset 5934 */ , + 0x7471 /* offset 5935 */ , + 0x7485 /* offset 5936 */ , + 0x74ca /* offset 5937 */ , + 0x3f1b /* offset 5938 */ , + 0x7524 /* offset 5939 */ , + 0x24c36 /* offset 5940 */ , + 0x753e /* offset 5941 */ , + 0x24c92 /* offset 5942 */ , + 0x2219f /* offset 5943 */ , + 0x7610 /* offset 5944 */ , + 0x24fa1 /* offset 5945 */ , + 0x24fb8 /* offset 5946 */ , + 0x25044 /* offset 5947 */ , + 0x3ffc /* offset 5948 */ , + 0x4008 /* offset 5949 */ , + 0x76f4 /* offset 5950 */ , + 0x250f3 /* offset 5951 */ , + 0x250f2 /* offset 5952 */ , + 0x25119 /* offset 5953 */ , + 0x25133 /* offset 5954 */ , + 0x771e /* offset 5955 */ , + 0x771f /* offset 5956 */ , + 0x774a /* offset 5957 */ , + 0x4039 /* offset 5958 */ , + 0x778b /* offset 5959 */ , + 0x4046 /* offset 5960 */ , + 0x4096 /* offset 5961 */ , + 0x2541d /* offset 5962 */ , + 0x784e /* offset 5963 */ , + 0x78cc /* offset 5964 */ , + 0x40e3 /* offset 5965 */ , + 0x25626 /* offset 5966 */ , + 0x2569a /* offset 5967 */ , + 0x256c5 /* offset 5968 */ , + 0x79eb /* offset 5969 */ , + 0x412f /* offset 5970 */ , + 0x7a4a /* offset 5971 */ , + 0x7a4f /* offset 5972 */ , + 0x2597c /* offset 5973 */ , + 0x25aa7 /* offset 5974 */ , + 0x7aae /* offset 5975 */ , + 0x4202 /* offset 5976 */ , + 0x25bab /* offset 5977 */ , + 0x7bc6 /* offset 5978 */ , + 0x7bc9 /* offset 5979 */ , + 0x4227 /* offset 5980 */ , + 0x25c80 /* offset 5981 */ , + 0x7cd2 /* offset 5982 */ , + 0x42a0 /* offset 5983 */ , + 0x7ce8 /* offset 5984 */ , + 0x7ce3 /* offset 5985 */ , + 0x7d00 /* offset 5986 */ , + 0x25f86 /* offset 5987 */ , + 0x7d63 /* offset 5988 */ , + 0x4301 /* offset 5989 */ , + 0x7dc7 /* offset 5990 */ , + 0x7e02 /* offset 5991 */ , + 0x7e45 /* offset 5992 */ , + 0x4334 /* offset 5993 */ , + 0x26228 /* offset 5994 */ , + 0x26247 /* offset 5995 */ , + 0x4359 /* offset 5996 */ , + 0x262d9 /* offset 5997 */ , + 0x7f7a /* offset 5998 */ , + 0x2633e /* offset 5999 */ , + 0x7f95 /* offset 6000 */ , + 0x7ffa /* offset 6001 */ , + 0x264da /* offset 6002 */ , + 0x26523 /* offset 6003 */ , + 0x8060 /* offset 6004 */ , + 0x265a8 /* offset 6005 */ , + 0x8070 /* offset 6006 */ , + 0x2335f /* offset 6007 */ , + 0x43d5 /* offset 6008 */ , + 0x80b2 /* offset 6009 */ , + 0x8103 /* offset 6010 */ , + 0x440b /* offset 6011 */ , + 0x813e /* offset 6012 */ , + 0x5ab5 /* offset 6013 */ , + 0x267a7 /* offset 6014 */ , + 0x267b5 /* offset 6015 */ , + 0x23393 /* offset 6016 */ , + 0x2339c /* offset 6017 */ , + 0x8204 /* offset 6018 */ , + 0x8f9e /* offset 6019 */ , + 0x446b /* offset 6020 */ , + 0x8291 /* offset 6021 */ , + 0x828b /* offset 6022 */ , + 0x829d /* offset 6023 */ , + 0x52b3 /* offset 6024 */ , + 0x82b1 /* offset 6025 */ , + 0x82b3 /* offset 6026 */ , + 0x82bd /* offset 6027 */ , + 0x82e6 /* offset 6028 */ , + 0x26b3c /* offset 6029 */ , + 0x831d /* offset 6030 */ , + 0x8363 /* offset 6031 */ , + 0x83ad /* offset 6032 */ , + 0x8323 /* offset 6033 */ , + 0x83bd /* offset 6034 */ , + 0x83e7 /* offset 6035 */ , + 0x8353 /* offset 6036 */ , + 0x83ca /* offset 6037 */ , + 0x83cc /* offset 6038 */ , + 0x83dc /* offset 6039 */ , + 0x26c36 /* offset 6040 */ , + 0x26d6b /* offset 6041 */ , + 0x26cd5 /* offset 6042 */ , + 0x452b /* offset 6043 */ , + 0x84f1 /* offset 6044 */ , + 0x84f3 /* offset 6045 */ , + 0x8516 /* offset 6046 */ , + 0x273ca /* offset 6047 */ , + 0x8564 /* offset 6048 */ , + 0x26f2c /* offset 6049 */ , + 0x455d /* offset 6050 */ , + 0x4561 /* offset 6051 */ , + 0x26fb1 /* offset 6052 */ , + 0x270d2 /* offset 6053 */ , + 0x456b /* offset 6054 */ , + 0x8650 /* offset 6055 */ , + 0x8667 /* offset 6056 */ , + 0x8669 /* offset 6057 */ , + 0x86a9 /* offset 6058 */ , + 0x8688 /* offset 6059 */ , + 0x870e /* offset 6060 */ , + 0x86e2 /* offset 6061 */ , + 0x8779 /* offset 6062 */ , + 0x8728 /* offset 6063 */ , + 0x876b /* offset 6064 */ , + 0x8786 /* offset 6065 */ , + 0x4d57 /* offset 6066 */ , + 0x87e1 /* offset 6067 */ , + 0x8801 /* offset 6068 */ , + 0x45f9 /* offset 6069 */ , + 0x8860 /* offset 6070 */ , + 0x27667 /* offset 6071 */ , + 0x88d7 /* offset 6072 */ , + 0x88de /* offset 6073 */ , + 0x4635 /* offset 6074 */ , + 0x88fa /* offset 6075 */ , + 0x34bb /* offset 6076 */ , + 0x278ae /* offset 6077 */ , + 0x27966 /* offset 6078 */ , + 0x46be /* offset 6079 */ , + 0x46c7 /* offset 6080 */ , + 0x8aa0 /* offset 6081 */ , + 0x8aed /* offset 6082 */ , + 0x8b8a /* offset 6083 */ , + 0x27ca8 /* offset 6084 */ , + 0x8cab /* offset 6085 */ , + 0x8cc1 /* offset 6086 */ , + 0x8d1b /* offset 6087 */ , + 0x8d77 /* offset 6088 */ , + 0x27f2f /* offset 6089 */ , + 0x20804 /* offset 6090 */ , + 0x8dcb /* offset 6091 */ , + 0x8dbc /* offset 6092 */ , + 0x8df0 /* offset 6093 */ , + 0x208de /* offset 6094 */ , + 0x8ed4 /* offset 6095 */ , + 0x8f38 /* offset 6096 */ , + 0x285d2 /* offset 6097 */ , + 0x285ed /* offset 6098 */ , + 0x9094 /* offset 6099 */ , + 0x90f1 /* offset 6100 */ , + 0x9111 /* offset 6101 */ , + 0x2872e /* offset 6102 */ , + 0x911b /* offset 6103 */ , + 0x9238 /* offset 6104 */ , + 0x92d7 /* offset 6105 */ , + 0x92d8 /* offset 6106 */ , + 0x927c /* offset 6107 */ , + 0x93f9 /* offset 6108 */ , + 0x9415 /* offset 6109 */ , + 0x28bfa /* offset 6110 */ , + 0x958b /* offset 6111 */ , + 0x4995 /* offset 6112 */ , + 0x95b7 /* offset 6113 */ , + 0x28d77 /* offset 6114 */ , + 0x49e6 /* offset 6115 */ , + 0x96c3 /* offset 6116 */ , + 0x5db2 /* offset 6117 */ , + 0x9723 /* offset 6118 */ , + 0x29145 /* offset 6119 */ , + 0x2921a /* offset 6120 */ , + 0x4a6e /* offset 6121 */ , + 0x4a76 /* offset 6122 */ , + 0x97e0 /* offset 6123 */ , + 0x2940a /* offset 6124 */ , + 0x4ab2 /* offset 6125 */ , + 0x29496 /* offset 6126 */ , + 0x980b /* offset 6127 */ , + 0x9829 /* offset 6128 */ , + 0x295b6 /* offset 6129 */ , + 0x98e2 /* offset 6130 */ , + 0x4b33 /* offset 6131 */ , + 0x9929 /* offset 6132 */ , + 0x99a7 /* offset 6133 */ , + 0x99c2 /* offset 6134 */ , + 0x99fe /* offset 6135 */ , + 0x4bce /* offset 6136 */ , + 0x29b30 /* offset 6137 */ , + 0x9b12 /* offset 6138 */ , + 0x9c40 /* offset 6139 */ , + 0x9cfd /* offset 6140 */ , + 0x4cce /* offset 6141 */ , + 0x4ced /* offset 6142 */ , + 0x9d67 /* offset 6143 */ , + 0x2a0ce /* offset 6144 */ , + 0x4cf8 /* offset 6145 */ , + 0x2a105 /* offset 6146 */ , + 0x2a20e /* offset 6147 */ , + 0x2a291 /* offset 6148 */ , + 0x4d56 /* offset 6149 */ , + 0x9efe /* offset 6150 */ , + 0x9f05 /* offset 6151 */ , + 0x9f0f /* offset 6152 */ , + 0x9f16 /* offset 6153 */ , + 0x2a600 /* offset 6154 */ +}; + diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeMap.cc b/rosapps/smartpdf/poppler/poppler/UnicodeMap.cc new file mode 100644 index 00000000000..381e4ca1fce --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeMap.cc @@ -0,0 +1,293 @@ +//======================================================================== +// +// UnicodeMap.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "goo/gfile.h" +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "Error.h" +#include "GlobalParams.h" +#include "UnicodeMap.h" + +//------------------------------------------------------------------------ + +#define maxExtCode 16 + +struct UnicodeMapExt { + Unicode u; // Unicode char + char code[maxExtCode]; + Guint nBytes; +}; + +//------------------------------------------------------------------------ + +UnicodeMap *UnicodeMap::parse(GooString *encodingNameA) { + FILE *f; + UnicodeMap *map; + UnicodeMapRange *range; + UnicodeMapExt *eMap; + int size, eMapsSize; + char buf[256]; + int line, nBytes, i, x; + char *tok1, *tok2, *tok3; + + if (!(f = globalParams->getUnicodeMapFile(encodingNameA))) { + error(-1, "Couldn't find unicodeMap file for the '%s' encoding", + encodingNameA->getCString()); + return NULL; + } + + map = new UnicodeMap(encodingNameA->copy()); + + size = 8; + map->ranges = (UnicodeMapRange *)gmallocn(size, sizeof(UnicodeMapRange)); + eMapsSize = 0; + + line = 1; + while (getLine(buf, sizeof(buf), f)) { + if ((tok1 = strtok(buf, " \t\r\n")) && + (tok2 = strtok(NULL, " \t\r\n"))) { + if (!(tok3 = strtok(NULL, " \t\r\n"))) { + tok3 = tok2; + tok2 = tok1; + } + nBytes = strlen(tok3) / 2; + if (nBytes <= 4) { + if (map->len == size) { + size *= 2; + map->ranges = (UnicodeMapRange *) + greallocn(map->ranges, size, sizeof(UnicodeMapRange)); + } + range = &map->ranges[map->len]; + sscanf(tok1, "%x", &range->start); + sscanf(tok2, "%x", &range->end); + sscanf(tok3, "%x", &range->code); + range->nBytes = nBytes; + ++map->len; + } else if (tok2 == tok1) { + if (map->eMapsLen == eMapsSize) { + eMapsSize += 16; + map->eMaps = (UnicodeMapExt *) + greallocn(map->eMaps, eMapsSize, sizeof(UnicodeMapExt)); + } + eMap = &map->eMaps[map->eMapsLen]; + sscanf(tok1, "%x", &eMap->u); + for (i = 0; i < nBytes; ++i) { + sscanf(tok3 + i*2, "%2x", &x); + eMap->code[i] = (char)x; + } + eMap->nBytes = nBytes; + ++map->eMapsLen; + } else { + error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding", + line, encodingNameA->getCString()); + } + } else { + error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding", + line, encodingNameA->getCString()); + } + ++line; + } + + fclose(f); + + return map; +} + +UnicodeMap::UnicodeMap(GooString *encodingNameA) { + encodingName = encodingNameA; + unicodeOut = gFalse; + kind = unicodeMapUser; + ranges = NULL; + len = 0; + eMaps = NULL; + eMapsLen = 0; + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + +UnicodeMap::UnicodeMap(char *encodingNameA, GBool unicodeOutA, + UnicodeMapRange *rangesA, int lenA) { + encodingName = new GooString(encodingNameA); + unicodeOut = unicodeOutA; + kind = unicodeMapResident; + ranges = rangesA; + len = lenA; + eMaps = NULL; + eMapsLen = 0; + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + +UnicodeMap::UnicodeMap(char *encodingNameA, GBool unicodeOutA, + UnicodeMapFunc funcA) { + encodingName = new GooString(encodingNameA); + unicodeOut = unicodeOutA; + kind = unicodeMapFunc; + func = funcA; + eMaps = NULL; + eMapsLen = 0; + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + +UnicodeMap::~UnicodeMap() { + delete encodingName; + if (kind == unicodeMapUser && ranges) { + gfree(ranges); + } + if (eMaps) { + gfree(eMaps); + } +#if MULTITHREADED + gDestroyMutex(&mutex); +#endif +} + +void UnicodeMap::incRefCnt() { +#if MULTITHREADED + gLockMutex(&mutex); +#endif + ++refCnt; +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif +} + +void UnicodeMap::decRefCnt() { + GBool done; + +#if MULTITHREADED + gLockMutex(&mutex); +#endif + done = --refCnt == 0; +#if MULTITHREADED + gUnlockMutex(&mutex); +#endif + if (done) { + delete this; + } +} + +GBool UnicodeMap::match(GooString *encodingNameA) { + return !encodingName->cmp(encodingNameA); +} + +int UnicodeMap::mapUnicode(Unicode u, char *buf, int bufSize) { + int a, b, m, n, i, j; + Guint code; + + if (kind == unicodeMapFunc) { + return (*func)(u, buf, bufSize); + } + + a = 0; + b = len; + if (u >= ranges[a].start) { + // invariant: ranges[a].start <= u < ranges[b].start + while (b - a > 1) { + m = (a + b) / 2; + if (u >= ranges[m].start) { + a = m; + } else if (u < ranges[m].start) { + b = m; + } + } + if (u <= ranges[a].end) { + n = ranges[a].nBytes; + if (n > bufSize) { + return 0; + } + code = ranges[a].code + (u - ranges[a].start); + for (i = n - 1; i >= 0; --i) { + buf[i] = (char)(code & 0xff); + code >>= 8; + } + return n; + } + } + + for (i = 0; i < eMapsLen; ++i) { + if (eMaps[i].u == u) { + n = eMaps[i].nBytes; + for (j = 0; j < n; ++j) { + buf[j] = eMaps[i].code[j]; + } + return n; + } + } + + return 0; +} + +//------------------------------------------------------------------------ + +UnicodeMapCache::UnicodeMapCache() { + int i; + + for (i = 0; i < unicodeMapCacheSize; ++i) { + cache[i] = NULL; + } +} + +UnicodeMapCache::~UnicodeMapCache() { + int i; + + for (i = 0; i < unicodeMapCacheSize; ++i) { + if (cache[i]) { + cache[i]->decRefCnt(); + } + } +} + +UnicodeMap *UnicodeMapCache::getUnicodeMap(GooString *encodingName) { + UnicodeMap *map; + int i, j; + + if (cache[0] && cache[0]->match(encodingName)) { + cache[0]->incRefCnt(); + return cache[0]; + } + for (i = 1; i < unicodeMapCacheSize; ++i) { + if (cache[i] && cache[i]->match(encodingName)) { + map = cache[i]; + for (j = i; j >= 1; --j) { + cache[j] = cache[j - 1]; + } + cache[0] = map; + map->incRefCnt(); + return map; + } + } + if ((map = UnicodeMap::parse(encodingName))) { + if (cache[unicodeMapCacheSize - 1]) { + cache[unicodeMapCacheSize - 1]->decRefCnt(); + } + for (j = unicodeMapCacheSize - 1; j >= 1; --j) { + cache[j] = cache[j - 1]; + } + cache[0] = map; + map->incRefCnt(); + return map; + } + return NULL; +} diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeMap.h b/rosapps/smartpdf/poppler/poppler/UnicodeMap.h new file mode 100644 index 00000000000..6ed24c2c8ac --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeMap.h @@ -0,0 +1,122 @@ +//======================================================================== +// +// UnicodeMap.h +// +// Mapping from Unicode to an encoding. +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef UNICODEMAP_H +#define UNICODEMAP_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "poppler-config.h" +#include "goo/gtypes.h" +#include "CharTypes.h" + +#if MULTITHREADED +#include +#endif + +class GooString; + +//------------------------------------------------------------------------ + +enum UnicodeMapKind { + unicodeMapUser, // read from a file + unicodeMapResident, // static list of ranges + unicodeMapFunc // function pointer +}; + +typedef int (*UnicodeMapFunc)(Unicode u, char *buf, int bufSize); + +struct UnicodeMapRange { + Unicode start, end; // range of Unicode chars + Guint code, nBytes; // first output code +}; + +struct UnicodeMapExt; + +//------------------------------------------------------------------------ + +class UnicodeMap { +public: + + // Create the UnicodeMap specified by . Sets the + // initial reference count to 1. Returns NULL on failure. + static UnicodeMap *parse(GooString *encodingNameA); + + // Create a resident UnicodeMap. + UnicodeMap(char *encodingNameA, GBool unicodeOutA, + UnicodeMapRange *rangesA, int lenA); + + // Create a resident UnicodeMap that uses a function instead of a + // list of ranges. + UnicodeMap(char *encodingNameA, GBool unicodeOutA, + UnicodeMapFunc funcA); + + ~UnicodeMap(); + + void incRefCnt(); + void decRefCnt(); + + GooString *getEncodingName() { return encodingName; } + + GBool isUnicode() { return unicodeOut; } + + // Return true if this UnicodeMap matches the specified + // . + GBool match(GooString *encodingNameA); + + // Map Unicode to the target encoding. Fills in with the + // output and returns the number of bytes used. Output will be + // truncated at bytes. No string terminator is written. + // Returns 0 if no mapping is found. + int mapUnicode(Unicode u, char *buf, int bufSize); + +private: + + UnicodeMap(GooString *encodingNameA); + + GooString *encodingName; + UnicodeMapKind kind; + GBool unicodeOut; + union { + UnicodeMapRange *ranges; // (user, resident) + UnicodeMapFunc func; // (func) + }; + int len; // (user, resident) + UnicodeMapExt *eMaps; // (user) + int eMapsLen; // (user) + int refCnt; +#if MULTITHREADED + GooMutex mutex; +#endif +}; + +//------------------------------------------------------------------------ + +#define unicodeMapCacheSize 4 + +class UnicodeMapCache { +public: + + UnicodeMapCache(); + ~UnicodeMapCache(); + + // Get the UnicodeMap for . Increments its reference + // count; there will be one reference for the cache plus one for the + // caller of this function. Returns NULL on failure. + UnicodeMap *getUnicodeMap(GooString *encodingName); + +private: + + UnicodeMap *cache[unicodeMapCacheSize]; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeMapTables.h b/rosapps/smartpdf/poppler/poppler/UnicodeMapTables.h new file mode 100644 index 00000000000..9c510346164 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeMapTables.h @@ -0,0 +1,361 @@ +//======================================================================== +// +// UnicodeMapTables.h +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +static UnicodeMapRange latin1UnicodeMapRanges[] = { + { 0x000a, 0x000a, 0x0a, 1 }, + { 0x000c, 0x000d, 0x0c, 1 }, + { 0x0020, 0x007e, 0x20, 1 }, + { 0x00a0, 0x00a0, 0x20, 1 }, + { 0x00a1, 0x00ac, 0xa1, 1 }, + { 0x00ae, 0x00ff, 0xae, 1 }, + { 0x010c, 0x010c, 0x43, 1 }, + { 0x010d, 0x010d, 0x63, 1 }, + { 0x0131, 0x0131, 0x69, 1 }, + { 0x0141, 0x0141, 0x4c, 1 }, + { 0x0142, 0x0142, 0x6c, 1 }, + { 0x0152, 0x0152, 0x4f45, 2 }, + { 0x0153, 0x0153, 0x6f65, 2 }, + { 0x0160, 0x0160, 0x53, 1 }, + { 0x0161, 0x0161, 0x73, 1 }, + { 0x0178, 0x0178, 0x59, 1 }, + { 0x017d, 0x017d, 0x5a, 1 }, + { 0x017e, 0x017e, 0x7a, 1 }, + { 0x02c6, 0x02c6, 0x5e, 1 }, + { 0x02da, 0x02da, 0xb0, 1 }, + { 0x02dc, 0x02dc, 0x7e, 1 }, + { 0x2013, 0x2013, 0xad, 1 }, + { 0x2014, 0x2014, 0x2d2d, 2 }, + { 0x2018, 0x2018, 0x60, 1 }, + { 0x2019, 0x2019, 0x27, 1 }, + { 0x201a, 0x201a, 0x2c, 1 }, + { 0x201c, 0x201c, 0x22, 1 }, + { 0x201d, 0x201d, 0x22, 1 }, + { 0x201e, 0x201e, 0x2c2c, 2 }, + { 0x2022, 0x2022, 0xb7, 1 }, + { 0x2026, 0x2026, 0x2e2e2e, 3 }, + { 0x2039, 0x2039, 0x3c, 1 }, + { 0x203a, 0x203a, 0x3e, 1 }, + { 0x2044, 0x2044, 0x2f, 1 }, + { 0x2122, 0x2122, 0x544d, 2 }, + { 0x2212, 0x2212, 0x2d, 1 }, + { 0xf6f9, 0xf6f9, 0x4c, 1 }, + { 0xf6fa, 0xf6fa, 0x4f45, 2 }, + { 0xf6fc, 0xf6fc, 0xb0, 1 }, + { 0xf6fd, 0xf6fd, 0x53, 1 }, + { 0xf6fe, 0xf6fe, 0x7e, 1 }, + { 0xf6ff, 0xf6ff, 0x5a, 1 }, + { 0xf721, 0xf721, 0x21, 1 }, + { 0xf724, 0xf724, 0x24, 1 }, + { 0xf726, 0xf726, 0x26, 1 }, + { 0xf730, 0xf739, 0x30, 1 }, + { 0xf73f, 0xf73f, 0x3f, 1 }, + { 0xf761, 0xf77a, 0x41, 1 }, + { 0xf7a1, 0xf7a2, 0xa1, 1 }, + { 0xf7bf, 0xf7bf, 0xbf, 1 }, + { 0xf7e0, 0xf7f6, 0xc0, 1 }, + { 0xf7f8, 0xf7fe, 0xd8, 1 }, + { 0xf7ff, 0xf7ff, 0x59, 1 }, + { 0xfb00, 0xfb00, 0x6666, 2 }, + { 0xfb01, 0xfb01, 0x6669, 2 }, + { 0xfb02, 0xfb02, 0x666c, 2 }, + { 0xfb03, 0xfb03, 0x666669, 3 }, + { 0xfb04, 0xfb04, 0x66666c, 3 } +}; +#define latin1UnicodeMapLen (sizeof(latin1UnicodeMapRanges) / sizeof(UnicodeMapRange)) + +static UnicodeMapRange ascii7UnicodeMapRanges[] = { + { 0x000a, 0x000a, 0x0a, 1 }, + { 0x000c, 0x000d, 0x0c, 1 }, + { 0x0020, 0x005f, 0x20, 1 }, + { 0x0061, 0x007e, 0x61, 1 }, + { 0x00a6, 0x00a6, 0x7c, 1 }, + { 0x00a9, 0x00a9, 0x286329, 3 }, + { 0x00ae, 0x00ae, 0x285229, 3 }, + { 0x00b7, 0x00b7, 0x2a, 1 }, + { 0x00bc, 0x00bc, 0x312f34, 3 }, + { 0x00bd, 0x00bd, 0x312f32, 3 }, + { 0x00be, 0x00be, 0x332f34, 3 }, + { 0x00c0, 0x00c0, 0x41, 1 }, + { 0x00c1, 0x00c1, 0x41, 1 }, + { 0x00c2, 0x00c2, 0x41, 1 }, + { 0x00c3, 0x00c3, 0x41, 1 }, + { 0x00c4, 0x00c4, 0x41, 1 }, + { 0x00c5, 0x00c5, 0x41, 1 }, + { 0x00c6, 0x00c6, 0x4145, 2 }, + { 0x00c7, 0x00c7, 0x43, 1 }, + { 0x00c8, 0x00c8, 0x45, 1 }, + { 0x00c9, 0x00c9, 0x45, 1 }, + { 0x00ca, 0x00ca, 0x45, 1 }, + { 0x00cb, 0x00cb, 0x45, 1 }, + { 0x00cc, 0x00cc, 0x49, 1 }, + { 0x00cd, 0x00cd, 0x49, 1 }, + { 0x00ce, 0x00ce, 0x49, 1 }, + { 0x00cf, 0x00cf, 0x49, 1 }, + { 0x00d1, 0x00d2, 0x4e, 1 }, + { 0x00d3, 0x00d3, 0x4f, 1 }, + { 0x00d4, 0x00d4, 0x4f, 1 }, + { 0x00d5, 0x00d5, 0x4f, 1 }, + { 0x00d6, 0x00d6, 0x4f, 1 }, + { 0x00d7, 0x00d7, 0x78, 1 }, + { 0x00d8, 0x00d8, 0x4f, 1 }, + { 0x00d9, 0x00d9, 0x55, 1 }, + { 0x00da, 0x00da, 0x55, 1 }, + { 0x00db, 0x00db, 0x55, 1 }, + { 0x00dc, 0x00dc, 0x55, 1 }, + { 0x00dd, 0x00dd, 0x59, 1 }, + { 0x00e0, 0x00e0, 0x61, 1 }, + { 0x00e1, 0x00e1, 0x61, 1 }, + { 0x00e2, 0x00e2, 0x61, 1 }, + { 0x00e3, 0x00e3, 0x61, 1 }, + { 0x00e4, 0x00e4, 0x61, 1 }, + { 0x00e5, 0x00e5, 0x61, 1 }, + { 0x00e6, 0x00e6, 0x6165, 2 }, + { 0x00e7, 0x00e7, 0x63, 1 }, + { 0x00e8, 0x00e8, 0x65, 1 }, + { 0x00e9, 0x00e9, 0x65, 1 }, + { 0x00ea, 0x00ea, 0x65, 1 }, + { 0x00eb, 0x00eb, 0x65, 1 }, + { 0x00ec, 0x00ec, 0x69, 1 }, + { 0x00ed, 0x00ed, 0x69, 1 }, + { 0x00ee, 0x00ee, 0x69, 1 }, + { 0x00ef, 0x00ef, 0x69, 1 }, + { 0x00f1, 0x00f2, 0x6e, 1 }, + { 0x00f3, 0x00f3, 0x6f, 1 }, + { 0x00f4, 0x00f4, 0x6f, 1 }, + { 0x00f5, 0x00f5, 0x6f, 1 }, + { 0x00f6, 0x00f6, 0x6f, 1 }, + { 0x00f7, 0x00f7, 0x2f, 1 }, + { 0x00f8, 0x00f8, 0x6f, 1 }, + { 0x00f9, 0x00f9, 0x75, 1 }, + { 0x00fa, 0x00fa, 0x75, 1 }, + { 0x00fb, 0x00fb, 0x75, 1 }, + { 0x00fc, 0x00fc, 0x75, 1 }, + { 0x00fd, 0x00fd, 0x79, 1 }, + { 0x00ff, 0x00ff, 0x79, 1 }, + { 0x0131, 0x0131, 0x69, 1 }, + { 0x0141, 0x0141, 0x4c, 1 }, + { 0x0152, 0x0152, 0x4f45, 2 }, + { 0x0153, 0x0153, 0x6f65, 2 }, + { 0x0160, 0x0160, 0x53, 1 }, + { 0x0178, 0x0178, 0x59, 1 }, + { 0x017d, 0x017d, 0x5a, 1 }, + { 0x2013, 0x2013, 0x2d, 1 }, + { 0x2014, 0x2014, 0x2d2d, 2 }, + { 0x2018, 0x2018, 0x60, 1 }, + { 0x2019, 0x2019, 0x27, 1 }, + { 0x201c, 0x201c, 0x22, 1 }, + { 0x201d, 0x201d, 0x22, 1 }, + { 0x2022, 0x2022, 0x2a, 1 }, + { 0x2026, 0x2026, 0x2e2e2e, 3 }, + { 0x2122, 0x2122, 0x544d, 2 }, + { 0x2212, 0x2212, 0x2d, 1 }, + { 0xf6f9, 0xf6f9, 0x4c, 1 }, + { 0xf6fa, 0xf6fa, 0x4f45, 2 }, + { 0xf6fd, 0xf6fd, 0x53, 1 }, + { 0xf6fe, 0xf6fe, 0x7e, 1 }, + { 0xf6ff, 0xf6ff, 0x5a, 1 }, + { 0xf721, 0xf721, 0x21, 1 }, + { 0xf724, 0xf724, 0x24, 1 }, + { 0xf726, 0xf726, 0x26, 1 }, + { 0xf730, 0xf739, 0x30, 1 }, + { 0xf73f, 0xf73f, 0x3f, 1 }, + { 0xf761, 0xf77a, 0x41, 1 }, + { 0xf7e0, 0xf7e0, 0x41, 1 }, + { 0xf7e1, 0xf7e1, 0x41, 1 }, + { 0xf7e2, 0xf7e2, 0x41, 1 }, + { 0xf7e3, 0xf7e3, 0x41, 1 }, + { 0xf7e4, 0xf7e4, 0x41, 1 }, + { 0xf7e5, 0xf7e5, 0x41, 1 }, + { 0xf7e6, 0xf7e6, 0x4145, 2 }, + { 0xf7e7, 0xf7e7, 0x43, 1 }, + { 0xf7e8, 0xf7e8, 0x45, 1 }, + { 0xf7e9, 0xf7e9, 0x45, 1 }, + { 0xf7ea, 0xf7ea, 0x45, 1 }, + { 0xf7eb, 0xf7eb, 0x45, 1 }, + { 0xf7ec, 0xf7ec, 0x49, 1 }, + { 0xf7ed, 0xf7ed, 0x49, 1 }, + { 0xf7ee, 0xf7ee, 0x49, 1 }, + { 0xf7ef, 0xf7ef, 0x49, 1 }, + { 0xf7f1, 0xf7f2, 0x4e, 1 }, + { 0xf7f3, 0xf7f3, 0x4f, 1 }, + { 0xf7f4, 0xf7f4, 0x4f, 1 }, + { 0xf7f5, 0xf7f5, 0x4f, 1 }, + { 0xf7f6, 0xf7f6, 0x4f, 1 }, + { 0xf7f8, 0xf7f8, 0x4f, 1 }, + { 0xf7f9, 0xf7f9, 0x55, 1 }, + { 0xf7fa, 0xf7fa, 0x55, 1 }, + { 0xf7fb, 0xf7fb, 0x55, 1 }, + { 0xf7fc, 0xf7fc, 0x55, 1 }, + { 0xf7fd, 0xf7fd, 0x59, 1 }, + { 0xf7ff, 0xf7ff, 0x59, 1 }, + { 0xfb00, 0xfb00, 0x6666, 2 }, + { 0xfb01, 0xfb01, 0x6669, 2 }, + { 0xfb02, 0xfb02, 0x666c, 2 }, + { 0xfb03, 0xfb03, 0x666669, 3 }, + { 0xfb04, 0xfb04, 0x66666c, 3 } +}; +#define ascii7UnicodeMapLen (sizeof(ascii7UnicodeMapRanges) / sizeof(UnicodeMapRange)) + +static UnicodeMapRange symbolUnicodeMapRanges[] = { + { 0x0020, 0x0021, 0x20, 1 }, + { 0x0023, 0x0023, 0x23, 1 }, + { 0x0025, 0x0026, 0x25, 1 }, + { 0x0028, 0x0029, 0x28, 1 }, + { 0x002b, 0x002c, 0x2b, 1 }, + { 0x002e, 0x003f, 0x2e, 1 }, + { 0x005b, 0x005b, 0x5b, 1 }, + { 0x005d, 0x005d, 0x5d, 1 }, + { 0x005f, 0x005f, 0x5f, 1 }, + { 0x007b, 0x007d, 0x7b, 1 }, + { 0x00ac, 0x00ac, 0xd8, 1 }, + { 0x00b0, 0x00b1, 0xb0, 1 }, + { 0x00b5, 0x00b5, 0x6d, 1 }, + { 0x00d7, 0x00d7, 0xb4, 1 }, + { 0x00f7, 0x00f7, 0xb8, 1 }, + { 0x0192, 0x0192, 0xa6, 1 }, + { 0x0391, 0x0392, 0x41, 1 }, + { 0x0393, 0x0393, 0x47, 1 }, + { 0x0395, 0x0395, 0x45, 1 }, + { 0x0396, 0x0396, 0x5a, 1 }, + { 0x0397, 0x0397, 0x48, 1 }, + { 0x0398, 0x0398, 0x51, 1 }, + { 0x0399, 0x0399, 0x49, 1 }, + { 0x039a, 0x039d, 0x4b, 1 }, + { 0x039e, 0x039e, 0x58, 1 }, + { 0x039f, 0x03a0, 0x4f, 1 }, + { 0x03a1, 0x03a1, 0x52, 1 }, + { 0x03a3, 0x03a5, 0x53, 1 }, + { 0x03a6, 0x03a6, 0x46, 1 }, + { 0x03a7, 0x03a7, 0x43, 1 }, + { 0x03a8, 0x03a8, 0x59, 1 }, + { 0x03b1, 0x03b2, 0x61, 1 }, + { 0x03b3, 0x03b3, 0x67, 1 }, + { 0x03b4, 0x03b5, 0x64, 1 }, + { 0x03b6, 0x03b6, 0x7a, 1 }, + { 0x03b7, 0x03b7, 0x68, 1 }, + { 0x03b8, 0x03b8, 0x71, 1 }, + { 0x03b9, 0x03b9, 0x69, 1 }, + { 0x03ba, 0x03bb, 0x6b, 1 }, + { 0x03bd, 0x03bd, 0x6e, 1 }, + { 0x03be, 0x03be, 0x78, 1 }, + { 0x03bf, 0x03c0, 0x6f, 1 }, + { 0x03c1, 0x03c1, 0x72, 1 }, + { 0x03c2, 0x03c2, 0x56, 1 }, + { 0x03c3, 0x03c5, 0x73, 1 }, + { 0x03c6, 0x03c6, 0x66, 1 }, + { 0x03c7, 0x03c7, 0x63, 1 }, + { 0x03c8, 0x03c8, 0x79, 1 }, + { 0x03c9, 0x03c9, 0x77, 1 }, + { 0x03d1, 0x03d1, 0x4a, 1 }, + { 0x03d2, 0x03d2, 0xa1, 1 }, + { 0x03d5, 0x03d5, 0x6a, 1 }, + { 0x03d6, 0x03d6, 0x76, 1 }, + { 0x2022, 0x2022, 0xb7, 1 }, + { 0x2026, 0x2026, 0xbc, 1 }, + { 0x2032, 0x2032, 0xa2, 1 }, + { 0x2033, 0x2033, 0xb2, 1 }, + { 0x2044, 0x2044, 0xa4, 1 }, + { 0x2111, 0x2111, 0xc1, 1 }, + { 0x2118, 0x2118, 0xc3, 1 }, + { 0x211c, 0x211c, 0xc2, 1 }, + { 0x2126, 0x2126, 0x57, 1 }, + { 0x2135, 0x2135, 0xc0, 1 }, + { 0x2190, 0x2193, 0xac, 1 }, + { 0x2194, 0x2194, 0xab, 1 }, + { 0x21b5, 0x21b5, 0xbf, 1 }, + { 0x21d0, 0x21d3, 0xdc, 1 }, + { 0x21d4, 0x21d4, 0xdb, 1 }, + { 0x2200, 0x2200, 0x22, 1 }, + { 0x2202, 0x2202, 0xb6, 1 }, + { 0x2203, 0x2203, 0x24, 1 }, + { 0x2205, 0x2205, 0xc6, 1 }, + { 0x2206, 0x2206, 0x44, 1 }, + { 0x2207, 0x2207, 0xd1, 1 }, + { 0x2208, 0x2209, 0xce, 1 }, + { 0x220b, 0x220b, 0x27, 1 }, + { 0x220f, 0x220f, 0xd5, 1 }, + { 0x2211, 0x2211, 0xe5, 1 }, + { 0x2212, 0x2212, 0x2d, 1 }, + { 0x2217, 0x2217, 0x2a, 1 }, + { 0x221a, 0x221a, 0xd6, 1 }, + { 0x221d, 0x221d, 0xb5, 1 }, + { 0x221e, 0x221e, 0xa5, 1 }, + { 0x2220, 0x2220, 0xd0, 1 }, + { 0x2227, 0x2228, 0xd9, 1 }, + { 0x2229, 0x222a, 0xc7, 1 }, + { 0x222b, 0x222b, 0xf2, 1 }, + { 0x2234, 0x2234, 0x5c, 1 }, + { 0x223c, 0x223c, 0x7e, 1 }, + { 0x2245, 0x2245, 0x40, 1 }, + { 0x2248, 0x2248, 0xbb, 1 }, + { 0x2260, 0x2261, 0xb9, 1 }, + { 0x2264, 0x2264, 0xa3, 1 }, + { 0x2265, 0x2265, 0xb3, 1 }, + { 0x2282, 0x2282, 0xcc, 1 }, + { 0x2283, 0x2283, 0xc9, 1 }, + { 0x2284, 0x2284, 0xcb, 1 }, + { 0x2286, 0x2286, 0xcd, 1 }, + { 0x2287, 0x2287, 0xca, 1 }, + { 0x2295, 0x2295, 0xc5, 1 }, + { 0x2297, 0x2297, 0xc4, 1 }, + { 0x22a5, 0x22a5, 0x5e, 1 }, + { 0x22c5, 0x22c5, 0xd7, 1 }, + { 0x2320, 0x2320, 0xf3, 1 }, + { 0x2321, 0x2321, 0xf5, 1 }, + { 0x2329, 0x2329, 0xe1, 1 }, + { 0x232a, 0x232a, 0xf1, 1 }, + { 0x25ca, 0x25ca, 0xe0, 1 }, + { 0x2660, 0x2660, 0xaa, 1 }, + { 0x2663, 0x2663, 0xa7, 1 }, + { 0x2665, 0x2665, 0xa9, 1 }, + { 0x2666, 0x2666, 0xa8, 1 }, + { 0xf6d9, 0xf6d9, 0xd3, 1 }, + { 0xf6da, 0xf6da, 0xd2, 1 }, + { 0xf6db, 0xf6db, 0xd4, 1 }, + { 0xf8e5, 0xf8e5, 0x60, 1 }, + { 0xf8e6, 0xf8e7, 0xbd, 1 }, + { 0xf8e8, 0xf8ea, 0xe2, 1 }, + { 0xf8eb, 0xf8f4, 0xe6, 1 }, + { 0xf8f5, 0xf8f5, 0xf4, 1 }, + { 0xf8f6, 0xf8fe, 0xf6, 1 } +}; +#define symbolUnicodeMapLen (sizeof(symbolUnicodeMapRanges) / sizeof(UnicodeMapRange)) + +static UnicodeMapRange zapfDingbatsUnicodeMapRanges[] = { + { 0x0020, 0x0020, 0x20, 1 }, + { 0x2192, 0x2192, 0xd5, 1 }, + { 0x2194, 0x2195, 0xd6, 1 }, + { 0x2460, 0x2469, 0xac, 1 }, + { 0x25a0, 0x25a0, 0x6e, 1 }, + { 0x25b2, 0x25b2, 0x73, 1 }, + { 0x25bc, 0x25bc, 0x74, 1 }, + { 0x25c6, 0x25c6, 0x75, 1 }, + { 0x25cf, 0x25cf, 0x6c, 1 }, + { 0x25d7, 0x25d7, 0x77, 1 }, + { 0x2605, 0x2605, 0x48, 1 }, + { 0x260e, 0x260e, 0x25, 1 }, + { 0x261b, 0x261b, 0x2a, 1 }, + { 0x261e, 0x261e, 0x2b, 1 }, + { 0x2660, 0x2660, 0xab, 1 }, + { 0x2663, 0x2663, 0xa8, 1 }, + { 0x2665, 0x2665, 0xaa, 1 }, + { 0x2666, 0x2666, 0xa9, 1 }, + { 0x2701, 0x2704, 0x21, 1 }, + { 0x2706, 0x2709, 0x26, 1 }, + { 0x270c, 0x2727, 0x2c, 1 }, + { 0x2729, 0x274b, 0x49, 1 }, + { 0x274d, 0x274d, 0x6d, 1 }, + { 0x274f, 0x2752, 0x6f, 1 }, + { 0x2756, 0x2756, 0x76, 1 }, + { 0x2758, 0x275e, 0x78, 1 }, + { 0x2761, 0x2767, 0xa1, 1 }, + { 0x2776, 0x2794, 0xb6, 1 }, + { 0x2798, 0x27af, 0xd8, 1 }, + { 0x27b1, 0x27be, 0xf1, 1 } +}; +#define zapfDingbatsUnicodeMapLen (sizeof(zapfDingbatsUnicodeMapRanges) / sizeof(UnicodeMapRange)) diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.cc b/rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.cc new file mode 100644 index 00000000000..c541c18743d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.cc @@ -0,0 +1,1184 @@ +//======================================================================== +// +// UnicodeTypeTable.cc +// +// Copyright 2004 Glyph & Cog, LLC +// +//======================================================================== + +#include +#include "CharTypes.h" +#include "UnicodeTypeTable.h" +#include "goo/gmem.h" + +struct UnicodeMapTableEntry { + char *vector; + char type; +}; + +struct UnicodeCaseTableVector { + Unicode codes[256]; +}; + +static UnicodeMapTableEntry typeTable[256] = { + { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNLNNNNLNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL", 'X' }, + { NULL, 'L' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLNNNNNNNNNNNNNNLLNNNNNNNNNNNNNNLLLLLNNNNNNNNNLNNNNNNNNNNNNNNNNN", 'X' }, + { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLNNNNNNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNRNRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", 'X' }, + { "RRRRNNNNNNNNNRNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNRRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNRNNNNNNNRRNNNNNNNRRNNNNNNNNNNRRRRRR", 'X' }, + { "RRRRRRRRRRRRRRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNRNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { NULL, 'N' }, + { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLNNNNLLLLLLLLLLLLLNNLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLNNLLLLLLLNNNNN", 'X' }, + { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLNNNNNNNNNNNNNNNN", 'X' }, + { "NNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLNLNNNLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNNNNNNNLLLLLLLNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNNNNLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNLNNNNNLNNLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLNLLNNNNNNNNNNNLLLLLLLNLNLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { "NNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLNNNNNLLLLLLNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLLLLLLLLLLNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLNNNLLLLLLLLLLLLLNNN", 'X' }, + { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLRNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNNNNLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { "NNLNNNNLNNLLLLLLLLLLNLNNNLLLLLNNNNNNLNLNLNLLLLNLLLNLLLLLLLNNLLLLNNNNNLLLLLNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { NULL, 'N' }, + { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { NULL, 'N' }, + { NULL, 'N' }, + { NULL, 'N' }, + { NULL, 'L' }, + { NULL, 'N' }, + { NULL, 'N' }, + { NULL, 'N' }, + { NULL, 'N' }, + { NULL, 'N' }, + { NULL, 'N' }, + { NULL, 'N' }, + { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNNNNNNNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLL", 'X' }, + { NULL, 'L' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN", 'X' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { NULL, 'L' }, + { "LLLLLLLLLLLLLLLLLLLLLLLLRRRRRRNRRRRRRRRRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", 'X' }, + { NULL, 'R' }, + { "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' }, + { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' }, + { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLL", 'X' } +}; + +static UnicodeCaseTableVector caseTable00 = {{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x03bc, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00d7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}}; +static UnicodeCaseTableVector caseTable01 = {{ + 0x0101, 0x0101, 0x0103, 0x0103, 0x0105, 0x0105, 0x0107, 0x0107, + 0x0109, 0x0109, 0x010b, 0x010b, 0x010d, 0x010d, 0x010f, 0x010f, + 0x0111, 0x0111, 0x0113, 0x0113, 0x0115, 0x0115, 0x0117, 0x0117, + 0x0119, 0x0119, 0x011b, 0x011b, 0x011d, 0x011d, 0x011f, 0x011f, + 0x0121, 0x0121, 0x0123, 0x0123, 0x0125, 0x0125, 0x0127, 0x0127, + 0x0129, 0x0129, 0x012b, 0x012b, 0x012d, 0x012d, 0x012f, 0x012f, + 0x0130, 0x0131, 0x0133, 0x0133, 0x0135, 0x0135, 0x0137, 0x0137, + 0x0138, 0x013a, 0x013a, 0x013c, 0x013c, 0x013e, 0x013e, 0x0140, + 0x0140, 0x0142, 0x0142, 0x0144, 0x0144, 0x0146, 0x0146, 0x0148, + 0x0148, 0x0149, 0x014b, 0x014b, 0x014d, 0x014d, 0x014f, 0x014f, + 0x0151, 0x0151, 0x0153, 0x0153, 0x0155, 0x0155, 0x0157, 0x0157, + 0x0159, 0x0159, 0x015b, 0x015b, 0x015d, 0x015d, 0x015f, 0x015f, + 0x0161, 0x0161, 0x0163, 0x0163, 0x0165, 0x0165, 0x0167, 0x0167, + 0x0169, 0x0169, 0x016b, 0x016b, 0x016d, 0x016d, 0x016f, 0x016f, + 0x0171, 0x0171, 0x0173, 0x0173, 0x0175, 0x0175, 0x0177, 0x0177, + 0x00ff, 0x017a, 0x017a, 0x017c, 0x017c, 0x017e, 0x017e, 0x0073, + 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, + 0x0188, 0x0256, 0x0257, 0x018c, 0x018c, 0x018d, 0x01dd, 0x0259, + 0x025b, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, + 0x0199, 0x0199, 0x019a, 0x019b, 0x026f, 0x0272, 0x019e, 0x0275, + 0x01a1, 0x01a1, 0x01a3, 0x01a3, 0x01a5, 0x01a5, 0x0280, 0x01a8, + 0x01a8, 0x0283, 0x01aa, 0x01ab, 0x01ad, 0x01ad, 0x0288, 0x01b0, + 0x01b0, 0x028a, 0x028b, 0x01b4, 0x01b4, 0x01b6, 0x01b6, 0x0292, + 0x01b9, 0x01b9, 0x01ba, 0x01bb, 0x01bd, 0x01bd, 0x01be, 0x01bf, + 0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x01c6, 0x01c6, 0x01c6, 0x01c9, + 0x01c9, 0x01c9, 0x01cc, 0x01cc, 0x01cc, 0x01ce, 0x01ce, 0x01d0, + 0x01d0, 0x01d2, 0x01d2, 0x01d4, 0x01d4, 0x01d6, 0x01d6, 0x01d8, + 0x01d8, 0x01da, 0x01da, 0x01dc, 0x01dc, 0x01dd, 0x01df, 0x01df, + 0x01e1, 0x01e1, 0x01e3, 0x01e3, 0x01e5, 0x01e5, 0x01e7, 0x01e7, + 0x01e9, 0x01e9, 0x01eb, 0x01eb, 0x01ed, 0x01ed, 0x01ef, 0x01ef, + 0x01f0, 0x01f3, 0x01f3, 0x01f3, 0x01f5, 0x01f5, 0x0195, 0x01bf, + 0x01f9, 0x01f9, 0x01fb, 0x01fb, 0x01fd, 0x01fd, 0x01ff, 0x01ff +}}; +static UnicodeCaseTableVector caseTable02 = {{ + 0x0201, 0x0201, 0x0203, 0x0203, 0x0205, 0x0205, 0x0207, 0x0207, + 0x0209, 0x0209, 0x020b, 0x020b, 0x020d, 0x020d, 0x020f, 0x020f, + 0x0211, 0x0211, 0x0213, 0x0213, 0x0215, 0x0215, 0x0217, 0x0217, + 0x0219, 0x0219, 0x021b, 0x021b, 0x021d, 0x021d, 0x021f, 0x021f, + 0x019e, 0x0221, 0x0223, 0x0223, 0x0225, 0x0225, 0x0227, 0x0227, + 0x0229, 0x0229, 0x022b, 0x022b, 0x022d, 0x022d, 0x022f, 0x022f, + 0x0231, 0x0231, 0x0233, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237, + 0x0238, 0x0239, 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f, + 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, + 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f, + 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257, + 0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f, + 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267, + 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f, + 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, + 0x0278, 0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f, + 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, + 0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d, 0x028e, 0x028f, + 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, + 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d, 0x029e, 0x029f, + 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 0x02a6, 0x02a7, + 0x02a8, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad, 0x02ae, 0x02af, + 0x02b0, 0x02b1, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x02b6, 0x02b7, + 0x02b8, 0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf, + 0x02c0, 0x02c1, 0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c7, + 0x02c8, 0x02c9, 0x02ca, 0x02cb, 0x02cc, 0x02cd, 0x02ce, 0x02cf, + 0x02d0, 0x02d1, 0x02d2, 0x02d3, 0x02d4, 0x02d5, 0x02d6, 0x02d7, + 0x02d8, 0x02d9, 0x02da, 0x02db, 0x02dc, 0x02dd, 0x02de, 0x02df, + 0x02e0, 0x02e1, 0x02e2, 0x02e3, 0x02e4, 0x02e5, 0x02e6, 0x02e7, + 0x02e8, 0x02e9, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02ef, + 0x02f0, 0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f5, 0x02f6, 0x02f7, + 0x02f8, 0x02f9, 0x02fa, 0x02fb, 0x02fc, 0x02fd, 0x02fe, 0x02ff +}}; +static UnicodeCaseTableVector caseTable03 = {{ + 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, + 0x0308, 0x0309, 0x030a, 0x030b, 0x030c, 0x030d, 0x030e, 0x030f, + 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, + 0x0318, 0x0319, 0x031a, 0x031b, 0x031c, 0x031d, 0x031e, 0x031f, + 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327, + 0x0328, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, 0x032f, + 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, + 0x0338, 0x0339, 0x033a, 0x033b, 0x033c, 0x033d, 0x033e, 0x033f, + 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x03b9, 0x0346, 0x0347, + 0x0348, 0x0349, 0x034a, 0x034b, 0x034c, 0x034d, 0x034e, 0x034f, + 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357, + 0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f, + 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, + 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f, + 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377, + 0x0378, 0x0379, 0x037a, 0x037b, 0x037c, 0x037d, 0x037e, 0x037f, + 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x03ac, 0x0387, + 0x03ad, 0x03ae, 0x03af, 0x038b, 0x03cc, 0x038d, 0x03cd, 0x03ce, + 0x0390, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03a2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c3, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x03cf, + 0x03b2, 0x03b8, 0x03d2, 0x03d3, 0x03d4, 0x03c6, 0x03c0, 0x03d7, + 0x03d9, 0x03d9, 0x03db, 0x03db, 0x03dd, 0x03dd, 0x03df, 0x03df, + 0x03e1, 0x03e1, 0x03e3, 0x03e3, 0x03e5, 0x03e5, 0x03e7, 0x03e7, + 0x03e9, 0x03e9, 0x03eb, 0x03eb, 0x03ed, 0x03ed, 0x03ef, 0x03ef, + 0x03ba, 0x03c1, 0x03f2, 0x03f3, 0x03b8, 0x03b5, 0x03f6, 0x03f8, + 0x03f8, 0x03f2, 0x03fb, 0x03fb, 0x03fc, 0x03fd, 0x03fe, 0x03ff +}}; +static UnicodeCaseTableVector caseTable04 = {{ + 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, + 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467, + 0x0469, 0x0469, 0x046b, 0x046b, 0x046d, 0x046d, 0x046f, 0x046f, + 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0477, 0x0477, + 0x0479, 0x0479, 0x047b, 0x047b, 0x047d, 0x047d, 0x047f, 0x047f, + 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, + 0x0488, 0x0489, 0x048b, 0x048b, 0x048d, 0x048d, 0x048f, 0x048f, + 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497, + 0x0499, 0x0499, 0x049b, 0x049b, 0x049d, 0x049d, 0x049f, 0x049f, + 0x04a1, 0x04a1, 0x04a3, 0x04a3, 0x04a5, 0x04a5, 0x04a7, 0x04a7, + 0x04a9, 0x04a9, 0x04ab, 0x04ab, 0x04ad, 0x04ad, 0x04af, 0x04af, + 0x04b1, 0x04b1, 0x04b3, 0x04b3, 0x04b5, 0x04b5, 0x04b7, 0x04b7, + 0x04b9, 0x04b9, 0x04bb, 0x04bb, 0x04bd, 0x04bd, 0x04bf, 0x04bf, + 0x04c0, 0x04c2, 0x04c2, 0x04c4, 0x04c4, 0x04c6, 0x04c6, 0x04c8, + 0x04c8, 0x04ca, 0x04ca, 0x04cc, 0x04cc, 0x04ce, 0x04ce, 0x04cf, + 0x04d1, 0x04d1, 0x04d3, 0x04d3, 0x04d5, 0x04d5, 0x04d7, 0x04d7, + 0x04d9, 0x04d9, 0x04db, 0x04db, 0x04dd, 0x04dd, 0x04df, 0x04df, + 0x04e1, 0x04e1, 0x04e3, 0x04e3, 0x04e5, 0x04e5, 0x04e7, 0x04e7, + 0x04e9, 0x04e9, 0x04eb, 0x04eb, 0x04ed, 0x04ed, 0x04ef, 0x04ef, + 0x04f1, 0x04f1, 0x04f3, 0x04f3, 0x04f5, 0x04f5, 0x04f6, 0x04f7, + 0x04f9, 0x04f9, 0x04fa, 0x04fb, 0x04fc, 0x04fd, 0x04fe, 0x04ff +}}; +static UnicodeCaseTableVector caseTable05 = {{ + 0x0501, 0x0501, 0x0503, 0x0503, 0x0505, 0x0505, 0x0507, 0x0507, + 0x0509, 0x0509, 0x050b, 0x050b, 0x050d, 0x050d, 0x050f, 0x050f, + 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, + 0x0518, 0x0519, 0x051a, 0x051b, 0x051c, 0x051d, 0x051e, 0x051f, + 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527, + 0x0528, 0x0529, 0x052a, 0x052b, 0x052c, 0x052d, 0x052e, 0x052f, + 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, + 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, 0x056f, + 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, + 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, + 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557, + 0x0558, 0x0559, 0x055a, 0x055b, 0x055c, 0x055d, 0x055e, 0x055f, + 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, + 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, 0x056f, + 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, + 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, + 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587, + 0x0588, 0x0589, 0x058a, 0x058b, 0x058c, 0x058d, 0x058e, 0x058f, + 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597, + 0x0598, 0x0599, 0x059a, 0x059b, 0x059c, 0x059d, 0x059e, 0x059f, + 0x05a0, 0x05a1, 0x05a2, 0x05a3, 0x05a4, 0x05a5, 0x05a6, 0x05a7, + 0x05a8, 0x05a9, 0x05aa, 0x05ab, 0x05ac, 0x05ad, 0x05ae, 0x05af, + 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, + 0x05b8, 0x05b9, 0x05ba, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, + 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05c4, 0x05c5, 0x05c6, 0x05c7, + 0x05c8, 0x05c9, 0x05ca, 0x05cb, 0x05cc, 0x05cd, 0x05ce, 0x05cf, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0x05eb, 0x05ec, 0x05ed, 0x05ee, 0x05ef, + 0x05f0, 0x05f1, 0x05f2, 0x05f3, 0x05f4, 0x05f5, 0x05f6, 0x05f7, + 0x05f8, 0x05f9, 0x05fa, 0x05fb, 0x05fc, 0x05fd, 0x05fe, 0x05ff +}}; +static UnicodeCaseTableVector caseTable1e = {{ + 0x1e01, 0x1e01, 0x1e03, 0x1e03, 0x1e05, 0x1e05, 0x1e07, 0x1e07, + 0x1e09, 0x1e09, 0x1e0b, 0x1e0b, 0x1e0d, 0x1e0d, 0x1e0f, 0x1e0f, + 0x1e11, 0x1e11, 0x1e13, 0x1e13, 0x1e15, 0x1e15, 0x1e17, 0x1e17, + 0x1e19, 0x1e19, 0x1e1b, 0x1e1b, 0x1e1d, 0x1e1d, 0x1e1f, 0x1e1f, + 0x1e21, 0x1e21, 0x1e23, 0x1e23, 0x1e25, 0x1e25, 0x1e27, 0x1e27, + 0x1e29, 0x1e29, 0x1e2b, 0x1e2b, 0x1e2d, 0x1e2d, 0x1e2f, 0x1e2f, + 0x1e31, 0x1e31, 0x1e33, 0x1e33, 0x1e35, 0x1e35, 0x1e37, 0x1e37, + 0x1e39, 0x1e39, 0x1e3b, 0x1e3b, 0x1e3d, 0x1e3d, 0x1e3f, 0x1e3f, + 0x1e41, 0x1e41, 0x1e43, 0x1e43, 0x1e45, 0x1e45, 0x1e47, 0x1e47, + 0x1e49, 0x1e49, 0x1e4b, 0x1e4b, 0x1e4d, 0x1e4d, 0x1e4f, 0x1e4f, + 0x1e51, 0x1e51, 0x1e53, 0x1e53, 0x1e55, 0x1e55, 0x1e57, 0x1e57, + 0x1e59, 0x1e59, 0x1e5b, 0x1e5b, 0x1e5d, 0x1e5d, 0x1e5f, 0x1e5f, + 0x1e61, 0x1e61, 0x1e63, 0x1e63, 0x1e65, 0x1e65, 0x1e67, 0x1e67, + 0x1e69, 0x1e69, 0x1e6b, 0x1e6b, 0x1e6d, 0x1e6d, 0x1e6f, 0x1e6f, + 0x1e71, 0x1e71, 0x1e73, 0x1e73, 0x1e75, 0x1e75, 0x1e77, 0x1e77, + 0x1e79, 0x1e79, 0x1e7b, 0x1e7b, 0x1e7d, 0x1e7d, 0x1e7f, 0x1e7f, + 0x1e81, 0x1e81, 0x1e83, 0x1e83, 0x1e85, 0x1e85, 0x1e87, 0x1e87, + 0x1e89, 0x1e89, 0x1e8b, 0x1e8b, 0x1e8d, 0x1e8d, 0x1e8f, 0x1e8f, + 0x1e91, 0x1e91, 0x1e93, 0x1e93, 0x1e95, 0x1e95, 0x1e96, 0x1e97, + 0x1e98, 0x1e99, 0x1e9a, 0x1e61, 0x1e9c, 0x1e9d, 0x1e9e, 0x1e9f, + 0x1ea1, 0x1ea1, 0x1ea3, 0x1ea3, 0x1ea5, 0x1ea5, 0x1ea7, 0x1ea7, + 0x1ea9, 0x1ea9, 0x1eab, 0x1eab, 0x1ead, 0x1ead, 0x1eaf, 0x1eaf, + 0x1eb1, 0x1eb1, 0x1eb3, 0x1eb3, 0x1eb5, 0x1eb5, 0x1eb7, 0x1eb7, + 0x1eb9, 0x1eb9, 0x1ebb, 0x1ebb, 0x1ebd, 0x1ebd, 0x1ebf, 0x1ebf, + 0x1ec1, 0x1ec1, 0x1ec3, 0x1ec3, 0x1ec5, 0x1ec5, 0x1ec7, 0x1ec7, + 0x1ec9, 0x1ec9, 0x1ecb, 0x1ecb, 0x1ecd, 0x1ecd, 0x1ecf, 0x1ecf, + 0x1ed1, 0x1ed1, 0x1ed3, 0x1ed3, 0x1ed5, 0x1ed5, 0x1ed7, 0x1ed7, + 0x1ed9, 0x1ed9, 0x1edb, 0x1edb, 0x1edd, 0x1edd, 0x1edf, 0x1edf, + 0x1ee1, 0x1ee1, 0x1ee3, 0x1ee3, 0x1ee5, 0x1ee5, 0x1ee7, 0x1ee7, + 0x1ee9, 0x1ee9, 0x1eeb, 0x1eeb, 0x1eed, 0x1eed, 0x1eef, 0x1eef, + 0x1ef1, 0x1ef1, 0x1ef3, 0x1ef3, 0x1ef5, 0x1ef5, 0x1ef7, 0x1ef7, + 0x1ef9, 0x1ef9, 0x1efa, 0x1efb, 0x1efc, 0x1efd, 0x1efe, 0x1eff +}}; +static UnicodeCaseTableVector caseTable1f = {{ + 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, + 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, + 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0x1f16, 0x1f17, + 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0x1f1e, 0x1f1f, + 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, + 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, + 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, + 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, + 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x1f46, 0x1f47, + 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x1f4e, 0x1f4f, + 0x1f50, 0x1f51, 0x1f52, 0x1f53, 0x1f54, 0x1f55, 0x1f56, 0x1f57, + 0x1f58, 0x1f51, 0x1f5a, 0x1f53, 0x1f5c, 0x1f55, 0x1f5e, 0x1f57, + 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, + 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, + 0x1f70, 0x1f71, 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1f76, 0x1f77, + 0x1f78, 0x1f79, 0x1f7a, 0x1f7b, 0x1f7c, 0x1f7d, 0x1f7e, 0x1f7f, + 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, + 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, + 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, + 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, + 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, + 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, + 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, + 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0x1fbd, 0x03b9, 0x1fbf, + 0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, 0x1fc4, 0x1fc5, 0x1fc6, 0x1fc7, + 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0x1fcd, 0x1fce, 0x1fcf, + 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7, + 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fdc, 0x1fdd, 0x1fde, 0x1fdf, + 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, 0x1fe6, 0x1fe7, + 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1fed, 0x1fee, 0x1fef, + 0x1ff0, 0x1ff1, 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, + 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0x1ffd, 0x1ffe, 0x1fff +}}; +static UnicodeCaseTableVector caseTable21 = {{ + 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107, + 0x2108, 0x2109, 0x210a, 0x210b, 0x210c, 0x210d, 0x210e, 0x210f, + 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117, + 0x2118, 0x2119, 0x211a, 0x211b, 0x211c, 0x211d, 0x211e, 0x211f, + 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x03c9, 0x2127, + 0x2128, 0x2129, 0x006b, 0x00e5, 0x212c, 0x212d, 0x212e, 0x212f, + 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, + 0x2138, 0x2139, 0x213a, 0x213b, 0x213c, 0x213d, 0x213e, 0x213f, + 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147, + 0x2148, 0x2149, 0x214a, 0x214b, 0x214c, 0x214d, 0x214e, 0x214f, + 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, + 0x2158, 0x2159, 0x215a, 0x215b, 0x215c, 0x215d, 0x215e, 0x215f, + 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, + 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f, + 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, + 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f, + 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187, + 0x2188, 0x2189, 0x218a, 0x218b, 0x218c, 0x218d, 0x218e, 0x218f, + 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197, + 0x2198, 0x2199, 0x219a, 0x219b, 0x219c, 0x219d, 0x219e, 0x219f, + 0x21a0, 0x21a1, 0x21a2, 0x21a3, 0x21a4, 0x21a5, 0x21a6, 0x21a7, + 0x21a8, 0x21a9, 0x21aa, 0x21ab, 0x21ac, 0x21ad, 0x21ae, 0x21af, + 0x21b0, 0x21b1, 0x21b2, 0x21b3, 0x21b4, 0x21b5, 0x21b6, 0x21b7, + 0x21b8, 0x21b9, 0x21ba, 0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, + 0x21c0, 0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, + 0x21c8, 0x21c9, 0x21ca, 0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, + 0x21d0, 0x21d1, 0x21d2, 0x21d3, 0x21d4, 0x21d5, 0x21d6, 0x21d7, + 0x21d8, 0x21d9, 0x21da, 0x21db, 0x21dc, 0x21dd, 0x21de, 0x21df, + 0x21e0, 0x21e1, 0x21e2, 0x21e3, 0x21e4, 0x21e5, 0x21e6, 0x21e7, + 0x21e8, 0x21e9, 0x21ea, 0x21eb, 0x21ec, 0x21ed, 0x21ee, 0x21ef, + 0x21f0, 0x21f1, 0x21f2, 0x21f3, 0x21f4, 0x21f5, 0x21f6, 0x21f7, + 0x21f8, 0x21f9, 0x21fa, 0x21fb, 0x21fc, 0x21fd, 0x21fe, 0x21ff +}}; +static UnicodeCaseTableVector caseTable24 = {{ + 0x2400, 0x2401, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407, + 0x2408, 0x2409, 0x240a, 0x240b, 0x240c, 0x240d, 0x240e, 0x240f, + 0x2410, 0x2411, 0x2412, 0x2413, 0x2414, 0x2415, 0x2416, 0x2417, + 0x2418, 0x2419, 0x241a, 0x241b, 0x241c, 0x241d, 0x241e, 0x241f, + 0x2420, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, + 0x2428, 0x2429, 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, + 0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, + 0x2438, 0x2439, 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, + 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, + 0x2448, 0x2449, 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, + 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, + 0x2458, 0x2459, 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, + 0x2470, 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0x2477, + 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x247f, + 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, + 0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d, 0x248e, 0x248f, + 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, + 0x2498, 0x2499, 0x249a, 0x249b, 0x249c, 0x249d, 0x249e, 0x249f, + 0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5, 0x24a6, 0x24a7, + 0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad, 0x24ae, 0x24af, + 0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5, 0x24d0, 0x24d1, + 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, + 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, + 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, + 0x24d0, 0x24d1, 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, + 0x24d8, 0x24d9, 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, + 0x24e0, 0x24e1, 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, + 0x24e8, 0x24e9, 0x24ea, 0x24eb, 0x24ec, 0x24ed, 0x24ee, 0x24ef, + 0x24f0, 0x24f1, 0x24f2, 0x24f3, 0x24f4, 0x24f5, 0x24f6, 0x24f7, + 0x24f8, 0x24f9, 0x24fa, 0x24fb, 0x24fc, 0x24fd, 0x24fe, 0x24ff +}}; +static UnicodeCaseTableVector caseTableff = {{ + 0xff00, 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07, + 0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, + 0xff10, 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, + 0xff18, 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, + 0xff20, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, + 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, + 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, + 0xff58, 0xff59, 0xff5a, 0xff3b, 0xff3c, 0xff3d, 0xff3e, 0xff3f, + 0xff40, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, + 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, + 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, + 0xff58, 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xff5e, 0xff5f, + 0xff60, 0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67, + 0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, + 0xff70, 0xff71, 0xff72, 0xff73, 0xff74, 0xff75, 0xff76, 0xff77, + 0xff78, 0xff79, 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f, + 0xff80, 0xff81, 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87, + 0xff88, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f, + 0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97, + 0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f, + 0xffa0, 0xffa1, 0xffa2, 0xffa3, 0xffa4, 0xffa5, 0xffa6, 0xffa7, + 0xffa8, 0xffa9, 0xffaa, 0xffab, 0xffac, 0xffad, 0xffae, 0xffaf, + 0xffb0, 0xffb1, 0xffb2, 0xffb3, 0xffb4, 0xffb5, 0xffb6, 0xffb7, + 0xffb8, 0xffb9, 0xffba, 0xffbb, 0xffbc, 0xffbd, 0xffbe, 0xffbf, + 0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc4, 0xffc5, 0xffc6, 0xffc7, + 0xffc8, 0xffc9, 0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf, + 0xffd0, 0xffd1, 0xffd2, 0xffd3, 0xffd4, 0xffd5, 0xffd6, 0xffd7, + 0xffd8, 0xffd9, 0xffda, 0xffdb, 0xffdc, 0xffdd, 0xffde, 0xffdf, + 0xffe0, 0xffe1, 0xffe2, 0xffe3, 0xffe4, 0xffe5, 0xffe6, 0xffe7, + 0xffe8, 0xffe9, 0xffea, 0xffeb, 0xffec, 0xffed, 0xffee, 0xffef, + 0xfff0, 0xfff1, 0xfff2, 0xfff3, 0xfff4, 0xfff5, 0xfff6, 0xfff7, + 0xfff8, 0xfff9, 0xfffa, 0xfffb, 0xfffc, 0xfffd, 0xfffe, 0xffff +}}; +static UnicodeCaseTableVector *caseTable[256] = { + &caseTable00, + &caseTable01, + &caseTable02, + &caseTable03, + &caseTable04, + &caseTable05, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &caseTable1e, + &caseTable1f, + NULL, + &caseTable21, + NULL, + NULL, + &caseTable24, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &caseTableff +}; + +static inline char getType(Unicode c) { + int i; + char type; + + if (c > 0xffff) { + type = 'X'; + } else { + i = (c >> 8) & 0xff; + if ((type = typeTable[i].type) == 'X') { + type = typeTable[i].vector[c & 0xff]; + } + } + return type; +} + +GBool unicodeTypeL(Unicode c) { + return getType(c) == 'L'; +} + +GBool unicodeTypeR(Unicode c) { + return getType(c) == 'R'; +} + +Unicode unicodeToUpper(Unicode c) { + int i; + + if (c > 0xffff) { + return c; + } + i = (c >> 8) & 0xff; + if (caseTable[i]) { + return caseTable[i]->codes[c & 0xff]; + } + return c; +} + +#define UNICODE_LAST_CHAR 0x10FFFF +#define UNICODE_MAX_TABLE_INDEX (UNICODE_LAST_CHAR / 256 + 1) +// large empty block between U+2FA1D and U+E0001 +#define UNICODE_LAST_CHAR_PART1 0x2FAFF +#define UNICODE_LAST_PAGE_PART1 (UNICODE_LAST_CHAR_PART1 / 256) +#define UNICODE_PART2_START 0xE0000 + +#include "UnicodeCClassTables.h" +#include "UnicodeCompTables.h" +#include "UnicodeDecompTables.h" + +#define CC_PART1(Page, Char) \ + ((combining_class_table_part1[Page] >= UNICODE_MAX_TABLE_INDEX) \ + ? (combining_class_table_part1[Page] - UNICODE_MAX_TABLE_INDEX) \ + : (cclass_data[combining_class_table_part1[Page]][Char])) + +#define CC_PART2(Page, Char) \ + ((combining_class_table_part2[Page] >= UNICODE_MAX_TABLE_INDEX) \ + ? (combining_class_table_part2[Page] - UNICODE_MAX_TABLE_INDEX) \ + : (cclass_data[combining_class_table_part2[Page]][Char])) + +#define COMBINING_CLASS(u) (((u) <= UNICODE_LAST_CHAR_PART1) \ + ? CC_PART1((u) / 256, (u) % 256) \ + : (((u) >= UNICODE_PART2_START && (u) <= UNICODE_LAST_CHAR) \ + ? CC_PART2(((u) - UNICODE_PART2_START) / 256, (u) % 256) \ + : 0)) + +// Write the compatibility decomposition of @u into @buf, returning the number +// of characters written. @buf may be NULL, in which case the length of the +// decomposition is returned but nothing is written. If @u is its own +// decomposition, write @u into @buf and return 1. +static int decomp_compat(Unicode u, Unicode *buf) { + // decomposition tables stored as lists {character, decomp_length, offset} + // so we do a binary search + int start = 0, end = DECOMP_TABLE_LENGTH; + if (u >= decomp_table[start].character + && u <= decomp_table[end - 1].character) + while (gTrue) { + int midpoint = (start + end) / 2; + if (u == decomp_table[midpoint].character) { + int offset = decomp_table[midpoint].offset; + if (offset == -1) + break; + else { + int length = decomp_table[midpoint].length, i; + if (buf) + for (i = 0; i < length; ++i) + buf[i] = decomp_expansion[offset + i]; + return length; + } + } else if (midpoint == start) + break; + else if (u > decomp_table[midpoint].character) + start = midpoint; + else + end = midpoint; + } + if (buf) + *buf = u; + return 1; +} + +#define CI(Page, Char) \ + ((compose_table[Page] >= UNICODE_MAX_TABLE_INDEX) \ + ? (compose_table[Page] - UNICODE_MAX_TABLE_INDEX) \ + : (compose_data[compose_table[Page]][Char])) + +#define COMPOSE_INDEX(u) \ + ((((u) / 256) > (COMPOSE_TABLE_LAST)) ? 0 : CI((u) / 256, (u) % 255)) + +// If @add combines with @base, write the combination to @out and return +// gTrue. Otherwise return gFalse. +static GBool combine(Unicode base, Unicode add, Unicode *out) { + unsigned short idx_base, idx_add; + + idx_base = COMPOSE_INDEX(base); + if (idx_base >= COMPOSE_FIRST_SINGLE_START + && idx_base < COMPOSE_SECOND_START) { + if (compose_first_single[idx_base - COMPOSE_FIRST_SINGLE_START][0] + == add) { + *out = compose_first_single[idx_base - COMPOSE_FIRST_SINGLE_START][1]; + return gTrue; + } else + return gFalse; + } + + idx_add = COMPOSE_INDEX(add); + if (idx_add >= COMPOSE_SECOND_SINGLE_START) { + if (compose_second_single[idx_add - COMPOSE_SECOND_SINGLE_START][0] + == base) { + *out = compose_second_single[idx_add - COMPOSE_SECOND_SINGLE_START][1]; + return gTrue; + } else + return gFalse; + } + + if (idx_base >= COMPOSE_FIRST_START && idx_base < COMPOSE_FIRST_SINGLE_START + && idx_add >= COMPOSE_SECOND_START + && idx_add < COMPOSE_SECOND_SINGLE_START) { + Unicode o = compose_array[idx_base - COMPOSE_FIRST_START] + [idx_add - COMPOSE_SECOND_START]; + if (o) { + *out = o; + return gTrue; + } + } + + return gFalse; +} + +#define HANGUL_S_BASE 0xAC00 +#define HANGUL_L_BASE 0x1100 +#define HANGUL_V_BASE 0x1161 +#define HANGUL_T_BASE 0x11A7 +#define HANGUL_L_COUNT 19 +#define HANGUL_V_COUNT 21 +#define HANGUL_T_COUNT 28 +#define HANGUL_S_COUNT (HANGUL_L_COUNT * HANGUL_V_COUNT * HANGUL_T_COUNT) +#define HANGUL_N_COUNT (HANGUL_V_COUNT * HANGUL_T_COUNT) +#define HANGUL_IS_L(u) (((u) >= HANGUL_L_BASE) \ + && ((u) < HANGUL_L_BASE + HANGUL_L_COUNT)) +#define HANGUL_IS_V(u) (((u) >= HANGUL_V_BASE) \ + && ((u) < HANGUL_V_BASE + HANGUL_V_COUNT)) +#define HANGUL_IS_T(u) (((u) >= HANGUL_T_BASE) \ + && ((u) < HANGUL_T_BASE + HANGUL_T_COUNT)) +#define HANGUL_IS_SYLLABLE(u) (((u) >= HANGUL_S_BASE) \ + && ((u) < HANGUL_S_BASE + HANGUL_S_COUNT)) +#define HANGUL_SYLLABLE_IS_LV(u) (((u) - HANGUL_S_BASE) % HANGUL_T_COUNT == 0) +#define IS_HANGUL(u) (HANGUL_IS_L(u) || HANGUL_IS_V(u) || HANGUL_IS_T(u) \ + || HANGUL_IS_SYLLABLE(u)) +#define HANGUL_COMPOSE_L_V(l, v) (HANGUL_S_BASE + (HANGUL_T_COUNT * \ + (((v) - HANGUL_V_BASE) + (HANGUL_V_COUNT * ((l) - HANGUL_L_BASE))))) +#define HANGUL_COMPOSE_LV_T(lv, t) ((lv) + ((t) - HANGUL_T_BASE)) + +// Converts Unicode string @in of length @len to its normalization in form +// NFKC (compatibility decomposition + canonical composition). The length of +// the resulting Unicode string is returned in @out_len. If non-NULL, @indices +// is assigned the location of a newly-allocated array of length @out_len + 1, +// for each character in the normalized string giving the index in @in of the +// corresponding unnormalized character. @indices is not guaranteed monotone or +// onto. +Unicode *unicodeNormalizeNFKC(Unicode *in, int len, + int *out_len, int **indices) { + Unicode *out; + int i, o, *classes, *idx = NULL; + + for (i = 0, o = 0; i < len; ++i) { + if (HANGUL_IS_L(in[i]) || HANGUL_IS_SYLLABLE(in[i])) { + o += 1; + } else + o += decomp_compat(in[i], NULL); + } + + out = (Unicode *) gmallocn(o, sizeof(Unicode)); + classes = (int *) gmallocn(o, sizeof(int)); + if (indices) + idx = (int *) gmallocn(o + 1, sizeof(int)); + + for (i = 0, o = 0; i < len; ) { + Unicode u = in[i]; + if (IS_HANGUL(u)) { + if (HANGUL_IS_L(u)) { + Unicode l = u; + if (i+1 < len && HANGUL_IS_V(in[i+1])) { + Unicode lv = HANGUL_COMPOSE_L_V(l, in[++i]); + if (i+1 < len && HANGUL_IS_T(in[i+1])) + out[o] = HANGUL_COMPOSE_LV_T(lv, in[++i]); + else + out[o] = lv; + } else + out[o] = l; + } else if (HANGUL_SYLLABLE_IS_LV(u)) { + Unicode lv = u; + if (i+1 < len && HANGUL_IS_T(in[i+1])) + out[o] = HANGUL_COMPOSE_LV_T(lv, in[++i]); + else + out[o] = lv; + } else + out[o] = u; + if (indices) + idx[o] = i; + ++i; ++o; + } else { + int j, p, q, r, s, dlen; + // write compatibility decompositions into out (we have enough space) + // chomp in until a starter is reached + for (j = i, p = o; j < len; ++j) { + u = in[j]; + if (j != i && COMBINING_CLASS(u) == 0) + break; + dlen = decomp_compat(u, out + p); + for (q = p; q < p + dlen; ++q) { + classes[q] = COMBINING_CLASS(out[q]); + if (indices) + idx[q] = j; + } + p += dlen; + } + // put out[o, p) in canonical ordering + for (q = o + 1; q < p; ++q) + for (r = q; r > o + 1; --r) { // FIXME worth using a better sort? + int swap; + if (classes[r] >= classes[r-1]) + break; + u = out[r]; out[r] = out[r - 1]; out[r - 1] = u; + swap = classes[r]; classes[r] = classes[r - 1]; classes[r - 1] = swap; + if (indices) + swap = idx[r]; idx[r] = idx[r - 1]; idx[r - 1] = swap; + } + // canonical compose out[o, p) + for (q = o + 1; q < p; ++q) + if (!combine(out[o], out[q], &out[o])) + break; + // move out[q, p) back to [o+1, ?) + if (q != o + 1) + for (r = q, s = o + 1; r < p; ++r, ++s) { + out[s] = out[r]; + if (indices) + idx[s] = idx[r]; + } + else + s = p; + i = j; o = s; + } + } + + *out_len = o; + gfree(classes); + if (indices) { + idx[o] = len; + *indices = idx; + } + return out; +} diff --git a/rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.h b/rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.h new file mode 100644 index 00000000000..9330051d928 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/UnicodeTypeTable.h @@ -0,0 +1,23 @@ +//======================================================================== +// +// UnicodeTypeTable.h +// +// Copyright 2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef UNICODETYPETABLE_H +#define UNICODETYPETABLE_H + +#include "goo/gtypes.h" + +extern GBool unicodeTypeL(Unicode c); + +extern GBool unicodeTypeR(Unicode c); + +extern Unicode unicodeToUpper(Unicode c); + +extern Unicode *unicodeNormalizeNFKC(Unicode *in, int len, + int *out_len, int **offsets); + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/XRef.cc b/rosapps/smartpdf/poppler/poppler/XRef.cc new file mode 100644 index 00000000000..44ac4094c4d --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/XRef.cc @@ -0,0 +1,969 @@ + //======================================================================== +// +// XRef.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include "goo/gmem.h" +#include "Object.h" +#include "Stream.h" +#include "Lexer.h" +#include "Parser.h" +#include "Dict.h" +#include "Error.h" +#include "ErrorCodes.h" +#include "UGooString.h" +#include "XRef.h" + +//------------------------------------------------------------------------ + +#define xrefSearchSize 1024 // read this many bytes at end of file + // to look for 'startxref' + +//------------------------------------------------------------------------ +// Permission bits +// Note that the PDF spec uses 1 base (eg bit 3 is 1<<2) +//------------------------------------------------------------------------ + +#define permPrint (1<<2) // bit 3 +#define permChange (1<<3) // bit 4 +#define permCopy (1<<4) // bit 5 +#define permNotes (1<<5) // bit 6 +#define permFillForm (1<<8) // bit 9 +#define permAccessibility (1<<9) // bit 10 +#define permAssemble (1<<10) // bit 11 +#define permHighResPrint (1<<11) // bit 12 +#define defPermFlags 0xfffc + +//------------------------------------------------------------------------ +// ObjectStream +//------------------------------------------------------------------------ + +class ObjectStream { +public: + + // Create an object stream, using object number , + // generation 0. + ObjectStream(XRef *xref, int objStrNumA); + + ~ObjectStream(); + + // Return the object number of this object stream. + int getObjStrNum() { return objStrNum; } + + // Get the th object from this stream, which should be + // object number , generation 0. + Object *getObject(int objIdx, int objNum, Object *obj); + +private: + + int objStrNum; // object number of the object stream + int nObjects; // number of objects in the stream + Object *objs; // the objects (length = nObjects) + int *objNums; // the object numbers (length = nObjects) +}; + +ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { + Stream *str; + Parser *parser; + int *offsets; + Object objStr, obj1, obj2; + int first, i; + + objStrNum = objStrNumA; + nObjects = 0; + objs = NULL; + objNums = NULL; + + if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) { + goto err1; + } + + if (!objStr.streamGetDict()->lookup("N", &obj1)->isInt()) { + obj1.free(); + goto err1; + } + nObjects = obj1.getInt(); + obj1.free(); + if (nObjects <= 0) { + goto err1; + } + + if (!objStr.streamGetDict()->lookup("First", &obj1)->isInt()) { + obj1.free(); + goto err1; + } + first = obj1.getInt(); + obj1.free(); + if (first < 0) { + goto err1; + } + + if (nObjects*(int)sizeof(int)/sizeof(int) != nObjects) { + error(-1, "Invalid 'nObjects'"); + goto err1; + } + + objs = new Object[nObjects]; + objNums = (int *)gmallocn(nObjects, sizeof(int)); + offsets = (int *)gmallocn(nObjects, sizeof(int)); + + // parse the header: object numbers and offsets + objStr.streamReset(); + obj1.initNull(); + str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first); + parser = new Parser(xref, new Lexer(xref, str)); + for (i = 0; i < nObjects; ++i) { + parser->getObj(&obj1); + parser->getObj(&obj2); + if (!obj1.isInt() || !obj2.isInt()) { + obj1.free(); + obj2.free(); + delete parser; + gfree(offsets); + goto err1; + } + objNums[i] = obj1.getInt(); + offsets[i] = obj2.getInt(); + obj1.free(); + obj2.free(); + if (objNums[i] < 0 || offsets[i] < 0 || + (i > 0 && offsets[i] < offsets[i-1])) { + delete parser; + gfree(offsets); + goto err1; + } + } + while (str->getChar() != EOF) ; + delete parser; + + // skip to the first object - this shouldn't be necessary because + // the First key is supposed to be equal to offsets[0], but just in + // case... + for (i = first; i < offsets[0]; ++i) { + objStr.getStream()->getChar(); + } + + // parse the objects + for (i = 0; i < nObjects; ++i) { + obj1.initNull(); + if (i == nObjects - 1) { + str = new EmbedStream(objStr.getStream(), &obj1, gFalse, 0); + } else { + str = new EmbedStream(objStr.getStream(), &obj1, gTrue, + offsets[i+1] - offsets[i]); + } + parser = new Parser(xref, new Lexer(xref, str)); + parser->getObj(&objs[i]); + while (str->getChar() != EOF) ; + delete parser; + } + + gfree(offsets); + + err1: + objStr.free(); + return; +} + +ObjectStream::~ObjectStream() { + int i; + + if (objs) { + for (i = 0; i < nObjects; ++i) { + objs[i].free(); + } + delete[] objs; + } + gfree(objNums); +} + +Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) { + if (objIdx < 0 || objIdx >= nObjects || objNum != objNums[objIdx]) { + return obj->initNull(); + } + return objs[objIdx].copy(obj); +} + +//------------------------------------------------------------------------ +// XRef +//------------------------------------------------------------------------ + +XRef::XRef(BaseStream *strA) { + Guint pos; + Object obj; + + ok = gTrue; + errCode = errNone; + size = 0; + entries = NULL; + streamEnds = NULL; + streamEndsLen = 0; + objStr = NULL; + + encrypted = gFalse; + permFlags = defPermFlags; + ownerPasswordOk = gFalse; + + // read the trailer + str = strA; + start = str->getStart(); + pos = getStartXref(); + + // if there was a problem with the 'startxref' position, try to + // reconstruct the xref table + if (pos == 0) { + if (!(ok = constructXRef())) { + errCode = errDamaged; + return; + } + + // read the xref table + } else { + while (readXRef(&pos)) ; + + // if there was a problem with the xref table, + // try to reconstruct it + if (!ok) { + if (!(ok = constructXRef())) { + errCode = errDamaged; + return; + } + } + } + + // get the root dictionary (catalog) object + trailerDict.dictLookupNF("Root", &obj); + if (obj.isRef()) { + rootNum = obj.getRefNum(); + rootGen = obj.getRefGen(); + obj.free(); + } else { + obj.free(); + if (!(ok = constructXRef())) { + errCode = errDamaged; + return; + } + } + + // now set the trailer dictionary's xref pointer so we can fetch + // indirect objects from it + trailerDict.getDict()->setXRef(this); +} + +XRef::~XRef() { + gfree(entries); + trailerDict.free(); + if (streamEnds) { + gfree(streamEnds); + } + if (objStr) { + delete objStr; + } +} + +// Read the 'startxref' position. +Guint XRef::getStartXref() { + char buf[xrefSearchSize+1]; + char *p; + int c, n, i; + + // read last xrefSearchSize bytes + str->setPos(xrefSearchSize, -1); + for (n = 0; n < xrefSearchSize; ++n) { + if ((c = str->getChar()) == EOF) { + break; + } + buf[n] = c; + } + buf[n] = '\0'; + + // find startxref + for (i = n - 9; i >= 0; --i) { + if (!strncmp(&buf[i], "startxref", 9)) { + break; + } + } + if (i < 0) { + return 0; + } + for (p = &buf[i+9]; isspace(*p); ++p) ; + lastXRefPos = strToUnsigned(p); + + return lastXRefPos; +} + +// Read one xref table section. Also reads the associated trailer +// dictionary, and returns the prev pointer (if any). +GBool XRef::readXRef(Guint *pos) { + Parser *parser; + Object obj; + GBool more; + + // start up a parser, parse one token + obj.initNull(); + parser = new Parser(NULL, + new Lexer(NULL, + str->makeSubStream(start + *pos, gFalse, 0, &obj))); + parser->getObj(&obj); + + // parse an old-style xref table + if (obj.isCmd("xref")) { + obj.free(); + more = readXRefTable(parser, pos); + + // parse an xref stream + } else if (obj.isInt()) { + obj.free(); + if (!parser->getObj(&obj)->isInt()) { + goto err1; + } + obj.free(); + if (!parser->getObj(&obj)->isCmd("obj")) { + goto err1; + } + obj.free(); + if (!parser->getObj(&obj)->isStream()) { + goto err1; + } + more = readXRefStream(obj.getStream(), pos); + obj.free(); + + } else { + goto err1; + } + + delete parser; + return more; + + err1: + obj.free(); + delete parser; + ok = gFalse; + return gFalse; +} + +GBool XRef::readXRefTable(Parser *parser, Guint *pos) { + XRefEntry entry; + GBool more; + Object obj, obj2; + Guint pos2; + int first, n, newSize, i; + + while (1) { + parser->getObj(&obj); + if (obj.isCmd("trailer")) { + obj.free(); + break; + } + if (!obj.isInt()) { + goto err1; + } + first = obj.getInt(); + obj.free(); + if (!parser->getObj(&obj)->isInt()) { + goto err1; + } + n = obj.getInt(); + obj.free(); + if (first < 0 || n < 0 || first + n < 0) { + goto err1; + } + if (first + n > size) { + for (newSize = size ? 2 * size : 1024; + first + n > newSize && newSize > 0; + newSize <<= 1) ; + if (newSize < 0) { + goto err1; + } + if (newSize*(int)sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { + error(-1, "Invalid 'obj' parameters'"); + goto err1; + } + + entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { + entries[i].offset = 0xffffffff; + entries[i].type = xrefEntryFree; + } + size = newSize; + } + for (i = first; i < first + n; ++i) { + if (!parser->getObj(&obj)->isInt()) { + goto err1; + } + entry.offset = (Guint)obj.getInt(); + obj.free(); + if (!parser->getObj(&obj)->isInt()) { + goto err1; + } + entry.gen = obj.getInt(); + obj.free(); + parser->getObj(&obj); + if (obj.isCmd("n")) { + entry.type = xrefEntryUncompressed; + } else if (obj.isCmd("f")) { + entry.type = xrefEntryFree; + } else { + goto err1; + } + obj.free(); + if (entries[i].offset == 0xffffffff) { + entries[i] = entry; + // PDF files of patents from the IBM Intellectual Property + // Network have a bug: the xref table claims to start at 1 + // instead of 0. + if (i == 1 && first == 1 && + entries[1].offset == 0 && entries[1].gen == 65535 && + entries[1].type == xrefEntryFree) { + i = first = 0; + entries[0] = entries[1]; + entries[1].offset = 0xffffffff; + } + } + } + } + + // read the trailer dictionary + if (!parser->getObj(&obj)->isDict()) { + goto err1; + } + + // get the 'Prev' pointer + obj.getDict()->lookupNF("Prev", &obj2); + if (obj2.isInt()) { + *pos = (Guint)obj2.getInt(); + more = gTrue; + } else if (obj2.isRef()) { + // certain buggy PDF generators generate "/Prev NNN 0 R" instead + // of "/Prev NNN" + *pos = (Guint)obj2.getRefNum(); + more = gTrue; + } else { + more = gFalse; + } + obj2.free(); + + // save the first trailer dictionary + if (trailerDict.isNone()) { + obj.copy(&trailerDict); + } + + // check for an 'XRefStm' key + if (obj.getDict()->lookup("XRefStm", &obj2)->isInt()) { + pos2 = (Guint)obj2.getInt(); + readXRef(&pos2); + if (!ok) { + obj2.free(); + goto err1; + } + } + obj2.free(); + + obj.free(); + return more; + + err1: + obj.free(); + ok = gFalse; + return gFalse; +} + +GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { + Dict *dict; + int w[3]; + GBool more; + Object obj, obj2, idx; + int newSize, first, n, i; + + dict = xrefStr->getDict(); + + if (!dict->lookupNF("Size", &obj)->isInt()) { + goto err1; + } + newSize = obj.getInt(); + obj.free(); + if (newSize < 0) { + goto err1; + } + if (newSize > size) { + if (newSize * (int)sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { + error(-1, "Invalid 'size' parameter."); + return gFalse; + } + entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { + entries[i].offset = 0xffffffff; + entries[i].type = xrefEntryFree; + } + size = newSize; + } + + if (!dict->lookupNF("W", &obj)->isArray() || + obj.arrayGetLength() < 3) { + goto err1; + } + for (i = 0; i < 3; ++i) { + if (!obj.arrayGet(i, &obj2)->isInt()) { + obj2.free(); + goto err1; + } + w[i] = obj2.getInt(); + obj2.free(); + if (w[i] < 0 || w[i] > 4) { + goto err1; + } + } + obj.free(); + + xrefStr->reset(); + dict->lookupNF("Index", &idx); + if (idx.isArray()) { + for (i = 0; i+1 < idx.arrayGetLength(); i += 2) { + if (!idx.arrayGet(i, &obj)->isInt()) { + idx.free(); + goto err1; + } + first = obj.getInt(); + obj.free(); + if (!idx.arrayGet(i+1, &obj)->isInt()) { + idx.free(); + goto err1; + } + n = obj.getInt(); + obj.free(); + if (first < 0 || n < 0 || + !readXRefStreamSection(xrefStr, w, first, n)) { + idx.free(); + goto err0; + } + } + } else { + if (!readXRefStreamSection(xrefStr, w, 0, newSize)) { + idx.free(); + goto err0; + } + } + idx.free(); + + dict->lookupNF("Prev", &obj); + if (obj.isInt()) { + *pos = (Guint)obj.getInt(); + more = gTrue; + } else { + more = gFalse; + } + obj.free(); + if (trailerDict.isNone()) { + trailerDict.initDict(dict); + } + + return more; + + err1: + obj.free(); + err0: + ok = gFalse; + return gFalse; +} + +GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) { + Guint offset; + int type, gen, c, newSize, i, j; + + if (first + n < 0) { + return gFalse; + } + if (first + n > size) { + for (newSize = size ? 2 * size : 1024; + first + n > newSize && newSize > 0; + newSize <<= 1) ; + if (newSize < 0) { + return gFalse; + } + if (newSize*(int)sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { + error(-1, "Invalid 'size' inside xref table."); + return gFalse; + } + entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { + entries[i].offset = 0xffffffff; + entries[i].type = xrefEntryFree; + } + size = newSize; + } + for (i = first; i < first + n; ++i) { + if (w[0] == 0) { + type = 1; + } else { + for (type = 0, j = 0; j < w[0]; ++j) { + if ((c = xrefStr->getChar()) == EOF) { + return gFalse; + } + type = (type << 8) + c; + } + } + for (offset = 0, j = 0; j < w[1]; ++j) { + if ((c = xrefStr->getChar()) == EOF) { + return gFalse; + } + offset = (offset << 8) + c; + } + for (gen = 0, j = 0; j < w[2]; ++j) { + if ((c = xrefStr->getChar()) == EOF) { + return gFalse; + } + gen = (gen << 8) + c; + } + if (entries[i].offset == 0xffffffff) { + switch (type) { + case 0: + entries[i].offset = offset; + entries[i].gen = gen; + entries[i].type = xrefEntryFree; + break; + case 1: + entries[i].offset = offset; + entries[i].gen = gen; + entries[i].type = xrefEntryUncompressed; + break; + case 2: + entries[i].offset = offset; + entries[i].gen = gen; + entries[i].type = xrefEntryCompressed; + break; + default: + return gFalse; + } + } + } + + return gTrue; +} + +// Attempt to construct an xref table for a damaged file. +GBool XRef::constructXRef() { + Parser *parser; + Object newTrailerDict, obj; + char buf[256]; + Guint pos; + int num, gen; + int newSize; + int streamEndsSize; + char *p; + int i; + GBool gotRoot; + + gfree(entries); + size = 0; + entries = NULL; + + error(0, "PDF file is damaged - attempting to reconstruct xref table..."); + gotRoot = gFalse; + streamEndsLen = streamEndsSize = 0; + + str->reset(); + while (1) { + pos = str->getPos(); + if (!str->getLine(buf, 256)) { + break; + } + p = buf; + + // got trailer dictionary + if (!strncmp(p, "trailer", 7)) { + obj.initNull(); + parser = new Parser(NULL, + new Lexer(NULL, + str->makeSubStream(pos + 7, gFalse, 0, &obj))); + parser->getObj(&newTrailerDict); + if (newTrailerDict.isDict()) { + newTrailerDict.dictLookupNF("Root", &obj); + if (obj.isRef()) { + rootNum = obj.getRefNum(); + rootGen = obj.getRefGen(); + if (!trailerDict.isNone()) { + trailerDict.free(); + } + newTrailerDict.copy(&trailerDict); + gotRoot = gTrue; + } + obj.free(); + } + newTrailerDict.free(); + delete parser; + + // look for object + } else if (isdigit(*p)) { + num = atoi(p); + if (num > 0) { + do { + ++p; + } while (*p && isdigit(*p)); + if (isspace(*p)) { + do { + ++p; + } while (*p && isspace(*p)); + if (isdigit(*p)) { + gen = atoi(p); + do { + ++p; + } while (*p && isdigit(*p)); + if (isspace(*p)) { + do { + ++p; + } while (*p && isspace(*p)); + if (!strncmp(p, "obj", 3)) { + if (num >= size) { + newSize = (num + 1 + 255) & ~255; + if (newSize < 0) { + error(-1, "Bad object number"); + return gFalse; + } + if (newSize*(int)sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { + error(-1, "Invalid 'obj' parameters."); + return gFalse; + } + entries = (XRefEntry *) + greallocn(entries, newSize, sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { + entries[i].offset = 0xffffffff; + entries[i].type = xrefEntryFree; + } + size = newSize; + } + if (entries[num].type == xrefEntryFree || + gen >= entries[num].gen) { + entries[num].offset = pos - start; + entries[num].gen = gen; + entries[num].type = xrefEntryUncompressed; + } + } + } + } + } + } + + } else if (!strncmp(p, "endstream", 9)) { + if (streamEndsLen == streamEndsSize) { + streamEndsSize += 64; + if (streamEndsSize*(int)sizeof(int)/sizeof(int) != streamEndsSize) { + error(-1, "Invalid 'endstream' parameter."); + return gFalse; + } + streamEnds = (Guint *)greallocn(streamEnds, + streamEndsSize, sizeof(int)); + } + streamEnds[streamEndsLen++] = pos; + } + } + + if (gotRoot) + return gTrue; + + error(-1, "Couldn't find trailer dictionary"); + return gFalse; +} + +void XRef::setEncryption(int permFlagsA, GBool ownerPasswordOkA, + Guchar *fileKeyA, int keyLengthA, + int encVersionA, int encRevisionA) { + int i; + + encrypted = gTrue; + permFlags = permFlagsA; + ownerPasswordOk = ownerPasswordOkA; + if (keyLengthA <= 16) { + keyLength = keyLengthA; + } else { + keyLength = 16; + } + for (i = 0; i < keyLength; ++i) { + fileKey[i] = fileKeyA[i]; + } + encVersion = encVersionA; + encRevision = encRevisionA; +} + +GBool XRef::okToPrint(GBool ignoreOwnerPW) { + return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint); +} + +// we can print at high res if we are only doing security handler revision +// 2 (and we are allowed to print at all), or with security handler rev +// 3 and we are allowed to print, and bit 12 is set. +GBool XRef::okToPrintHighRes(GBool ignoreOwnerPW) { + if (2 == encRevision) { + return (okToPrint(ignoreOwnerPW)); + } else if (encRevision >= 3) { + return (okToPrint(ignoreOwnerPW) && (permFlags & permHighResPrint)); + } else { + // something weird - unknown security handler version + return gFalse; + } +} + +GBool XRef::okToChange(GBool ignoreOwnerPW) { + return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange); +} + +GBool XRef::okToCopy(GBool ignoreOwnerPW) { + return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permCopy); +} + +GBool XRef::okToAddNotes(GBool ignoreOwnerPW) { + return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permNotes); +} + +GBool XRef::okToFillForm(GBool ignoreOwnerPW) { + return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permFillForm); +} + +GBool XRef::okToAccessibility(GBool ignoreOwnerPW) { + return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAccessibility); +} + +GBool XRef::okToAssemble(GBool ignoreOwnerPW) { + return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAssemble); +} + +Object *XRef::fetch(int num, int gen, Object *obj) { + XRefEntry *e; + Parser *parser; + Object obj1, obj2, obj3; + + // check for bogus ref - this can happen in corrupted PDF files + if (num < 0 || num >= size) { + goto err; + } + + e = &entries[num]; + switch (e->type) { + + case xrefEntryUncompressed: + if (e->gen != gen) { + goto err; + } + obj1.initNull(); + parser = new Parser(this, + new Lexer(this, + str->makeSubStream(start + e->offset, gFalse, 0, &obj1))); + parser->getObj(&obj1); + parser->getObj(&obj2); + parser->getObj(&obj3); + if (!obj1.isInt() || obj1.getInt() != num || + !obj2.isInt() || obj2.getInt() != gen || + !obj3.isCmd("obj")) { + obj1.free(); + obj2.free(); + obj3.free(); + delete parser; + goto err; + } + parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength, + num, gen); + obj1.free(); + obj2.free(); + obj3.free(); + delete parser; + break; + + case xrefEntryCompressed: + if (gen != 0) { + goto err; + } + if (!objStr || objStr->getObjStrNum() != (int)e->offset) { + if (objStr) { + delete objStr; + } + objStr = new ObjectStream(this, e->offset); + } + objStr->getObject(e->gen, num, obj); + break; + + default: + goto err; + } + + return obj; + + err: + return obj->initNull(); +} + +Object *XRef::getDocInfo(Object *obj) { + return trailerDict.dictLookup("Info", obj); +} + +// Added for the pdftex project. +Object *XRef::getDocInfoNF(Object *obj) { + return trailerDict.dictLookupNF("Info", obj); +} + +GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) { + int a, b, m; + + if (streamEndsLen == 0 || + streamStart > streamEnds[streamEndsLen - 1]) { + return gFalse; + } + + a = -1; + b = streamEndsLen - 1; + // invariant: streamEnds[a] < streamStart <= streamEnds[b] + while (b - a > 1) { + m = (a + b) / 2; + if (streamStart <= streamEnds[m]) { + b = m; + } else { + a = m; + } + } + *streamEnd = streamEnds[b]; + return gTrue; +} + +int XRef::getNumEntry(int offset) const +{ + if (size > 0) + { + int res = 0; + Guint resOffset = entries[0].offset; + XRefEntry e; + for (int i = 1; i < size; ++i) + { + e = entries[i]; + if (e.offset < (Guint)offset && e.offset >= resOffset) + { + res = i; + resOffset = e.offset; + } + } + return res; + } + else return -1; +} + +Guint XRef::strToUnsigned(char *s) { + Guint x; + char *p; + int i; + + x = 0; + for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) { + x = 10 * x + (*p - '0'); + } + return x; +} diff --git a/rosapps/smartpdf/poppler/poppler/XRef.h b/rosapps/smartpdf/poppler/poppler/XRef.h new file mode 100644 index 00000000000..8a6edc937bd --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/XRef.h @@ -0,0 +1,138 @@ +//======================================================================== +// +// XRef.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef XREF_H +#define XREF_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "Object.h" + +class Dict; +class Stream; +class Parser; +class ObjectStream; + +//------------------------------------------------------------------------ +// XRef +//------------------------------------------------------------------------ + +enum XRefEntryType { + xrefEntryFree, + xrefEntryUncompressed, + xrefEntryCompressed +}; + +struct XRefEntry { + Guint offset; + int gen; + XRefEntryType type; +}; + +class XRef { +public: + + // Constructor. Read xref table from stream. + XRef(BaseStream *strA); + + // Destructor. + ~XRef(); + + // Is xref table valid? + GBool isOk() { return ok; } + + // Get the error code (if isOk() returns false). + int getErrorCode() { return errCode; } + + // Set the encryption parameters. + void setEncryption(int permFlagsA, GBool ownerPasswordOkA, + Guchar *fileKeyA, int keyLengthA, + int encVersionA, int encRevisionA); + + // Is the file encrypted? + GBool isEncrypted() { return encrypted; } + + // Check various permissions. + GBool okToPrint(GBool ignoreOwnerPW = gFalse); + GBool okToPrintHighRes(GBool ignoreOwnerPW = gFalse); + GBool okToChange(GBool ignoreOwnerPW = gFalse); + GBool okToCopy(GBool ignoreOwnerPW = gFalse); + GBool okToAddNotes(GBool ignoreOwnerPW = gFalse); + GBool okToFillForm(GBool ignoreOwnerPW = gFalse); + GBool okToAccessibility(GBool ignoreOwnerPW = gFalse); + GBool okToAssemble(GBool ignoreOwnerPW = gFalse); + + // Get catalog object. + Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); } + + // Fetch an indirect reference. + Object *fetch(int num, int gen, Object *obj); + + // Return the document's Info dictionary (if any). + Object *getDocInfo(Object *obj); + Object *getDocInfoNF(Object *obj); + + // Return the number of objects in the xref table. + int getNumObjects() { return size; } + + // Return the offset of the last xref table. + Guint getLastXRefPos() { return lastXRefPos; } + + // Return the catalog object reference. + int getRootNum() { return rootNum; } + int getRootGen() { return rootGen; } + + // Get end position for a stream in a damaged file. + // Returns false if unknown or file is not damaged. + GBool getStreamEnd(Guint streamStart, Guint *streamEnd); + + // Retuns the entry that belongs to the offset + int getNumEntry(int offset) const; + + // Direct access. + int getSize() { return size; } + XRefEntry *getEntry(int i) { return &entries[i]; } + Object *getTrailerDict() { return &trailerDict; } + +private: + + BaseStream *str; // input stream + Guint start; // offset in file (to allow for garbage + // at beginning of file) + XRefEntry *entries; // xref entries + int size; // size of array + int rootNum, rootGen; // catalog dict + GBool ok; // true if xref table is valid + int errCode; // error code (if is false) + Object trailerDict; // trailer dictionary + Guint lastXRefPos; // offset of last xref table + Guint *streamEnds; // 'endstream' positions - only used in + // damaged files + int streamEndsLen; // number of valid entries in streamEnds + ObjectStream *objStr; // cached object stream + GBool encrypted; // true if file is encrypted + int encRevision; + int encVersion; // encryption algorithm + int keyLength; // length of key, in bytes + int permFlags; // permission bits + Guchar fileKey[16]; // file decryption key + GBool ownerPasswordOk; // true if owner password is correct + + Guint getStartXref(); + GBool readXRef(Guint *pos); + GBool readXRefTable(Parser *parser, Guint *pos); + GBool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n); + GBool readXRefStream(Stream *xrefStr, Guint *pos); + GBool constructXRef(); + Guint strToUnsigned(char *s); +}; + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.cc b/rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.cc new file mode 100644 index 00000000000..aefd5479aa2 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.cc @@ -0,0 +1,262 @@ +//======================================================================== +// +// XpdfPluginAPI.cc +// +// Copyright 2004 Glyph & Cog, LLC +// +//======================================================================== + +#include "config.h" + +#ifdef ENABLE_PLUGINS + +#include "gmem.h" +#include "GlobalParams.h" +#include "Object.h" +#include "PDFDoc.h" +#ifdef WIN32 +#include "WinPDFCore.h" +#else +#include "XPDFCore.h" +#endif +#include "XpdfPluginAPI.h" + +//------------------------------------------------------------------------ + +//~ This should use a pool of Objects; change xpdfFreeObj to match. +static Object *allocObj() { + return (Object *)gmalloc(sizeof(Object)); +} + +//------------------------------------------------------------------------ +// Document access functions +//------------------------------------------------------------------------ + +XpdfObject _xpdfGetInfoDict(XpdfDoc doc) { + Object *obj; + + obj = allocObj(); + return (XpdfObject)((PDFDoc *)doc)->getDocInfo(obj); +} + +XpdfObject _xpdfGetCatalog(XpdfDoc doc) { + Object *obj; + + obj = allocObj(); + return (XpdfObject)((PDFDoc *)doc)->getXRef()->getCatalog(obj); +} + +#ifdef _WIN32 + +HWND _xpdfWin32GetWindow(XpdfDoc doc) { + WinPDFCore *core; + + if (!(core = (WinPDFCore *)((PDFDoc *)doc)->getGUIData())) { + return NULL; + } + return core->getDrawFrame(); +} + +#else + +Widget _xpdfXGetWindow(XpdfDoc doc) { + XPDFCore *core; + + if (!(core = (XPDFCore *)((PDFDoc *)doc)->getGUIData())) { + return NULL; + } + return core->getWidget(); +} + +#endif + +//------------------------------------------------------------------------ +// Object access functions. +//------------------------------------------------------------------------ + +XpdfBool _xpdfObjIsBool(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isBool(); +} + +XpdfBool _xpdfObjIsInt(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isInt(); +} + +XpdfBool _xpdfObjIsReal(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isReal(); +} + +XpdfBool _xpdfObjIsNumber(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isNum(); +} + +XpdfBool _xpdfObjIsString(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isString(); +} + +XpdfBool _xpdfObjIsName(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isName(); +} + +XpdfBool _xpdfObjIsNull(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isNull(); +} + +XpdfBool _xpdfObjIsArray(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isArray(); +} + +XpdfBool _xpdfObjIsDict(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isDict(); +} + +XpdfBool _xpdfObjIsStream(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isStream(); +} + +XpdfBool _xpdfObjIsRef(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->isRef(); +} + +XpdfBool _xpdfBoolValue(XpdfObject obj) { + return (XpdfBool)((Object *)obj)->getBool(); +} + +int _xpdfIntValue(XpdfObject obj) { + if (!((Object *)obj)->isInt()) { + return 0; + } + return ((Object *)obj)->getInt(); +} + +double _xpdfRealValue(XpdfObject obj) { + if (!((Object *)obj)->isReal()) { + return 0; + } + return ((Object *)obj)->getReal(); +} + +double _xpdfNumberValue(XpdfObject obj) { + if (!((Object *)obj)->isNum()) { + return 0; + } + return ((Object *)obj)->getNum(); +} + +int _xpdfStringLength(XpdfObject obj) { + if (!((Object *)obj)->isString()) { + return 0; + } + return ((Object *)obj)->getString()->getLength(); +} + +char *_xpdfStringValue(XpdfObject obj) { + if (!((Object *)obj)->isString()) { + return 0; + } + return ((Object *)obj)->getString()->getCString(); +} + +char *_xpdfNameValue(XpdfObject obj) { + if (!((Object *)obj)->isName()) { + return NULL; + } + return ((Object *)obj)->getName(); +} + +int _xpdfArrayLength(XpdfObject obj) { + if (!((Object *)obj)->isArray()) { + return 0; + } + return ((Object *)obj)->arrayGetLength(); +} + +XpdfObject _xpdfArrayGet(XpdfObject obj, int idx) { + Object *elem; + + elem = allocObj(); + if (!((Object *)obj)->isArray()) { + return (XpdfObject)elem->initNull(); + } + return (XpdfObject)((Object *)obj)->arrayGet(idx, elem); +} + +XpdfObject _xpdfDictGet(XpdfObject obj, char *key) { + Object *elem; + + elem = allocObj(); + if (!((Object *)obj)->isDict()) { + return (XpdfObject)elem->initNull(); + } + return (XpdfObject)((Object *)obj)->dictLookup(key, elem); +} + +void _xpdfFreeObj(XpdfObject obj) { + ((Object *)obj)->free(); + gfree(obj); +} + +//------------------------------------------------------------------------ +// Memory allocation functions +//------------------------------------------------------------------------ + +void *_xpdfMalloc(int size) { + return gmalloc(size); +} + +void *_xpdfRealloc(void *p, int size) { + return grealloc(p, size); +} + +void _xpdfFree(void *p) { + gfree(p); +} + +//------------------------------------------------------------------------ +// Security handlers +//------------------------------------------------------------------------ + +void _xpdfRegisterSecurityHandler(XpdfSecurityHandler *handler) { + if (handler->version <= xpdfPluginAPIVersion) { + globalParams->addSecurityHandler(handler); + } +} + +//------------------------------------------------------------------------ + +XpdfPluginVecTable xpdfPluginVecTable = { + xpdfPluginAPIVersion, + &_xpdfGetInfoDict, + &_xpdfGetCatalog, +#ifdef _WIN32 + &_xpdfWin32GetWindow, +#else + &_xpdfXGetWindow, +#endif + &_xpdfObjIsBool, + &_xpdfObjIsInt, + &_xpdfObjIsReal, + &_xpdfObjIsString, + &_xpdfObjIsName, + &_xpdfObjIsNull, + &_xpdfObjIsArray, + &_xpdfObjIsDict, + &_xpdfObjIsStream, + &_xpdfObjIsRef, + &_xpdfBoolValue, + &_xpdfIntValue, + &_xpdfRealValue, + &_xpdfStringLength, + &_xpdfStringValue, + &_xpdfNameValue, + &_xpdfArrayLength, + &_xpdfArrayGet, + &_xpdfDictGet, + &_xpdfFreeObj, + &_xpdfMalloc, + &_xpdfRealloc, + &_xpdfFree, + &_xpdfRegisterSecurityHandler, +}; + +#endif // ENABLE_PLUGINS diff --git a/rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.h b/rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.h new file mode 100644 index 00000000000..22540f728bd --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/XpdfPluginAPI.h @@ -0,0 +1,341 @@ +/* + * XpdfPluginAPI.h + * + * Copyright 2004 Glyph & Cog, LLC + */ + +#ifndef XPDFPLUGINAPI_H +#define XPDFPLUGINAPI_H + +#ifdef _WIN32 +#include +#else +#define Object XtObject +#include +#undef Object +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------------ + * Macros + *------------------------------------------------------------------------*/ + +/* + * The current API version. + */ +#define xpdfPluginAPIVersion 1 + +#ifdef _WIN32 +# ifdef __cplusplus +# define PLUGINFUNC(retType) extern "C" __declspec(dllexport) retType +# else +# define PLUGINFUNC(retType) extern __declspec(dllexport) retType +# endif +#else +# ifdef __cplusplus +# define PLUGINFUNC(retType) extern "C" retType +# else +# define PLUGINFUNC(retType) extern retType +# endif +#endif + +/*------------------------------------------------------------------------ + * Plugin setup/cleanup + *------------------------------------------------------------------------*/ + +/* + * All plugins are required to implement two functions: + * + * -- Initialize the plugin. Returns non-zero if successful. + * PLUGINFUNC(XpdfBool) xpdfInitPlugin(void); + * + * -- Free the plugin. + * PLUGINFUNC(void) xpdfFreePlugin(void); + */ + +/*------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------*/ + +/* + * Standard C boolean -- zero = false, non-zero = true. + */ +typedef int XpdfBool; +#define xpdfTrue 1 +#define xpdfFalse 0 + +/* + * PDF document handle. + */ +typedef struct _XpdfDoc *XpdfDoc; + +/* + * PDF object handle. + */ +typedef struct _XpdfObject *XpdfObject; + +/* + * Document access permissions. Any of these can be bitwise 'or'ed + * together. If xpdfPermissionOpen is not included, the document + * cannot be opened at all, and the other bits are ignored. + */ +typedef unsigned int XpdfPermission; +#define xpdfPermissionOpen (1 << 0) +#define xpdfPermissionPrint (1 << 2) +#define xpdfPermissionChange (1 << 3) +#define xpdfPermissionCopy (1 << 4) +#define xpdfPermissionNotes (1 << 5) + +/*------------------------------------------------------------------------ + * Security handler + *------------------------------------------------------------------------*/ + +/* + * XpdfSecurityHandler - a security handler plugin should create one + * of these and pass it to xpdfRegisterSecurityHandler. + */ +#ifdef __cplusplus +struct XpdfSecurityHandler { +#else +typedef struct { +#endif + + /* + * Version of the security handler spec (this document) -- use + * xpdfPluginAPIVersion. + */ + int version; + + /* + * Security handler name. + */ + char *name; + + /* + * Any global data the security handler needs. XpdfViewer will pass + * this pointer to all handler functions as the + * argument. + */ + void *handlerData; + + /* + * Allocate and initialize data for a new document. XpdfViewer will + * pass the returned pointer to all other handler functions as the + * argument. Returns non-zero if successful. + */ + XpdfBool (*newDoc)(void *handlerData, XpdfDoc doc, + XpdfObject encryptDict, void **docData); + + /* + * Free the data allocated by newDoc. + */ + void (*freeDoc)(void *handlerData, void *docData); + + /* + * Construct authorization data based on the supplied owner and user + * passwords (either or both of which may be NULL). This function + * is called in "batch" mode, i.e., if the password was supplied on + * the command line or via an Xpdf library API. It should not + * generate any user interaction (e.g., a password dialog). It is + * not required to support this function: the makeAuthData function + * pointer can be set to NULL. Returns non-zero if successful. + */ + XpdfBool (*makeAuthData)(void *handlerData, void *docData, + char *ownerPassword, char *userPassword, + void **authData); + + /* + * Request any needed information (e.g., a password) from the user, + * and construct an authorization data object. Returns non-zero if + * successful. + */ + XpdfBool (*getAuthData)(void *handlerData, void *docData, + void **authData); + + /* + * Free the data allocated by getAuthData. + */ + void (*freeAuthData)(void *handlerData, void *docData, + void *authData); + + /* + * Request permission to access the document. This returns all + * permissions granted by authData. + */ + XpdfPermission (*authorize)(void *handlerData, void *docData, + void *authData); + + /* + * Get the decryption key and algorithm version associated with the + * document. Returns non-zero if successful. + */ + XpdfBool (*getKey)(void *handlerData, void *docData, + char **key, int *keyLen, int *cryptVersion); + + /* + * Free the data allocated by getKey. + */ + void (*freeKey)(void *handlerData, void *docData, + char *key, int keyLen); + +#ifdef __cplusplus +}; +#else +} XpdfSecurityHandler; +#endif + +/*------------------------------------------------------------------------*/ + +typedef struct { + int version; + +/*------------------------------------------------------------------------ + * Document access functions + *------------------------------------------------------------------------*/ + +/* + * Get a document's info dictionary. (The returned object must be + * freed with xpdfFreeObj.) + */ +XpdfObject (*_xpdfGetInfoDict)(XpdfDoc doc); + +/* + * Get a document's catalog ("root") dictionary. (The returned object + * must be freed with xpdfFreeObj.) + */ +XpdfObject (*_xpdfGetCatalog)(XpdfDoc doc); + +#ifdef _WIN32 + +/* + * Get the handle for the viewer window associated with the specified + * document. [Win32 only] + */ +HWND (*_xpdfWin32GetWindow)(XpdfDoc doc); + +#else + +/* + * Get the Motif widget for the viewer window associated with the + * specified document. [X only] + */ +Widget (*_xpdfXGetWindow)(XpdfDoc doc); + +#endif + +/*------------------------------------------------------------------------ + * Object access functions + *------------------------------------------------------------------------*/ + +/* + * Check an object's type. + */ +XpdfBool (*_xpdfObjIsBool)(XpdfObject obj); +XpdfBool (*_xpdfObjIsInt)(XpdfObject obj); +XpdfBool (*_xpdfObjIsReal)(XpdfObject obj); +XpdfBool (*_xpdfObjIsString)(XpdfObject obj); +XpdfBool (*_xpdfObjIsName)(XpdfObject obj); +XpdfBool (*_xpdfObjIsNull)(XpdfObject obj); +XpdfBool (*_xpdfObjIsArray)(XpdfObject obj); +XpdfBool (*_xpdfObjIsDict)(XpdfObject obj); +XpdfBool (*_xpdfObjIsStream)(XpdfObject obj); +XpdfBool (*_xpdfObjIsRef)(XpdfObject obj); + +/* + * Value access. + * (Objects returned by xpdfArrayGet and xpdfDictGet must be freed + * with xpdfFreeObj.) + */ +XpdfBool (*_xpdfBoolValue)(XpdfObject obj); +int (*_xpdfIntValue)(XpdfObject obj); +double (*_xpdfRealValue)(XpdfObject obj); +int (*_xpdfStringLength)(XpdfObject obj); +char *(*_xpdfStringValue)(XpdfObject obj); +char *(*_xpdfNameValue)(XpdfObject obj); +int (*_xpdfArrayLength)(XpdfObject obj); +XpdfObject (*_xpdfArrayGet)(XpdfObject obj, int idx); +XpdfObject (*_xpdfDictGet)(XpdfObject obj, char *key); + +/* + * Object destruction. NB: *all* objects must be freed after use. + */ +void (*_xpdfFreeObj)(XpdfObject obj); + +/*------------------------------------------------------------------------ + * Memory allocation functions + *------------------------------------------------------------------------*/ + +void *(*_xpdfMalloc)(int size); +void *(*_xpdfRealloc)(void *p, int size); +void (*_xpdfFree)(void *p); + +/*------------------------------------------------------------------------ + * Security handler functions + *------------------------------------------------------------------------*/ + +/* + * Register a new security handler. + */ +void (*_xpdfRegisterSecurityHandler)(XpdfSecurityHandler *handler); + +/*------------------------------------------------------------------------*/ + +} XpdfPluginVecTable; + +#ifdef _WIN32 + +extern __declspec(dllexport) XpdfPluginVecTable xpdfPluginVecTable; + +#define xpdfPluginSetup \ + extern __declspec(dllexport) \ + XpdfPluginVecTable xpdfPluginVecTable = {xpdfPluginAPIVersion}; + +#else + +extern XpdfPluginVecTable xpdfPluginVecTable; + +#define xpdfPluginSetup \ + XpdfPluginVecTable xpdfPluginVecTable = {xpdfPluginAPIVersion}; + +#endif + +#define xpdfGetInfoDict (*xpdfPluginVecTable._xpdfGetInfoDict) +#define xpdfGetCatalog (*xpdfPluginVecTable._xpdfGetCatalog) +#ifdef _WIN32 +#define xpdfWin32GetWindow (*xpdfPluginVecTable._xpdfWin32GetWindow) +#else +#define xpdfXGetWindow (*xpdfPluginVecTable._xpdfXGetWindow) +#endif +#define xpdfObjIsBool (*xpdfPluginVecTable._xpdfObjIsBool) +#define xpdfObjIsInt (*xpdfPluginVecTable._xpdfObjIsInt) +#define xpdfObjIsReal (*xpdfPluginVecTable._xpdfObjIsReal) +#define xpdfObjIsString (*xpdfPluginVecTable._xpdfObjIsString) +#define xpdfObjIsName (*xpdfPluginVecTable._xpdfObjIsName) +#define xpdfObjIsNull (*xpdfPluginVecTable._xpdfObjIsNull) +#define xpdfObjIsArray (*xpdfPluginVecTable._xpdfObjIsArray) +#define xpdfObjIsDict (*xpdfPluginVecTable._xpdfObjIsDict) +#define xpdfObjIsStream (*xpdfPluginVecTable._xpdfObjIsStream) +#define xpdfObjIsRef (*xpdfPluginVecTable._xpdfObjIsRef) +#define xpdfBoolValue (*xpdfPluginVecTable._xpdfBoolValue) +#define xpdfIntValue (*xpdfPluginVecTable._xpdfIntValue) +#define xpdfRealValue (*xpdfPluginVecTable._xpdfRealValue) +#define xpdfStringLength (*xpdfPluginVecTable._xpdfStringLength) +#define xpdfStringValue (*xpdfPluginVecTable._xpdfStringValue) +#define xpdfNameValue (*xpdfPluginVecTable._xpdfNameValue) +#define xpdfArrayLength (*xpdfPluginVecTable._xpdfArrayLength) +#define xpdfArrayGet (*xpdfPluginVecTable._xpdfArrayGet) +#define xpdfDictGet (*xpdfPluginVecTable._xpdfDictGet) +#define xpdfFreeObj (*xpdfPluginVecTable._xpdfFreeObj) +#define xpdfMalloc (*xpdfPluginVecTable._xpdfMalloc) +#define xpdfRealloc (*xpdfPluginVecTable._xpdfRealloc) +#define xpdfFree (*xpdfPluginVecTable._xpdfFree) +#define xpdfRegisterSecurityHandler (*xpdfPluginVecTable._xpdfRegisterSecurityHandler) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/poppler/poppler/poppler-config.h.in b/rosapps/smartpdf/poppler/poppler/poppler-config.h.in new file mode 100644 index 00000000000..bd0dd5cd293 --- /dev/null +++ b/rosapps/smartpdf/poppler/poppler/poppler-config.h.in @@ -0,0 +1,150 @@ +//================================================= -*- mode: c++ -*- ==== +// +// poppler-config.h +// +// Copyright 1996-2004 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef POPPLER_CONFIG_H +#define POPPLER_CONFIG_H + +// We duplicate some of the config.h #define's here since they are +// used in some of the header files we install. The #ifndef/#endif +// around #undef look odd, but it's to silence warnings about +// redefining those symbols. + +/* Enable multithreading support. */ +#ifndef MULTITHREADING +#undef MULTITHREADED +#endif + +/* Full path for the system-wide xpdfrc file. */ +#ifndef SYSTEM_XPDFRC +#undef SYSTEM_XPDFRC +#endif + +/* Include support for OPI comments. */ +#ifndef OPI_SUPPORT +#undef OPI_SUPPORT +#endif + +/* Enable word list support. */ +#ifndef TEXTOUT_WORD_LIST +#undef TEXTOUT_WORD_LIST +#endif + +// Also, there's a couple of preprocessor symbols in the header files +// that are used but never defined: DISABLE_OUTLINE, DEBUG_MEM and + +//------------------------------------------------------------------------ +// version +//------------------------------------------------------------------------ + +// xpdf version +#define xpdfVersion "3.00" +#define xpdfVersionNum 3.00 +#define xpdfMajorVersion 3 +#define xpdfMinorVersion 0 +#define xpdfMajorVersionStr "3" +#define xpdfMinorVersionStr "0" + +// supported PDF version +#define supportedPDFVersionStr "1.5" +#define supportedPDFVersionNum 1.5 + +// copyright notice +#define xpdfCopyright "Copyright 1996-2004 Glyph & Cog, LLC" + +// Windows resource file stuff +#define winxpdfVersion "WinXpdf 3.00" +#define xpdfCopyrightAmp "Copyright 1996-2004 Glyph && Cog, LLC" + +//------------------------------------------------------------------------ +// paper size +//------------------------------------------------------------------------ + +// default paper size (in points) for PostScript output +#ifdef A4_PAPER +#define defPaperWidth 595 // ISO A4 (210x297 mm) +#define defPaperHeight 842 +#else +#define defPaperWidth 612 // American letter (8.5x11") +#define defPaperHeight 792 +#endif + +//------------------------------------------------------------------------ +// config file (xpdfrc) path +//------------------------------------------------------------------------ + +// user config file name, relative to the user's home directory +#if defined(VMS) || (defined(WIN32) && !defined(__CYGWIN32__)) +#define xpdfUserConfigFile "xpdfrc" +#else +#define xpdfUserConfigFile ".xpdfrc" +#endif + +// system config file name (set via the configure script) +#ifdef SYSTEM_XPDFRC +#define xpdfSysConfigFile SYSTEM_XPDFRC +#else +// under Windows, we get the directory with the executable and then +// append this file name +#define xpdfSysConfigFile "xpdfrc" +#endif + +//------------------------------------------------------------------------ +// X-related constants +//------------------------------------------------------------------------ + +// default maximum size of color cube to allocate +#define defaultRGBCube 5 + +// number of fonts (combined t1lib, FreeType, X server) to cache +#define xOutFontCacheSize 64 + +// number of Type 3 fonts to cache +#define xOutT3FontCacheSize 8 + +//------------------------------------------------------------------------ +// popen +//------------------------------------------------------------------------ + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define popen _popen +#define pclose _pclose +#endif + +#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(WIN32) || defined(__DJGPP__) || defined(MACOS) +#define POPEN_READ_MODE "rb" +#else +#define POPEN_READ_MODE "r" +#endif + +//------------------------------------------------------------------------ +// Win32 stuff +//------------------------------------------------------------------------ + +#ifdef CDECL +#undef CDECL +#endif + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define CDECL __cdecl +#else +#define CDECL +#endif + +//------------------------------------------------------------------------ +// Compiler +//------------------------------------------------------------------------ + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define GCC_PRINTF_FORMAT(fmt_index, va_index) \ + __attribute__((__format__(__printf__, fmt_index, va_index))) +#else +#define GCC_PRINTF_FORMAT(fmt_index, va_index) +#endif + + +#endif /* POPPLER_CONFIG_H */ diff --git a/rosapps/smartpdf/poppler/splash/Makefile.am b/rosapps/smartpdf/poppler/splash/Makefile.am new file mode 100644 index 00000000000..914b308cf87 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/Makefile.am @@ -0,0 +1,57 @@ +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/goo \ + $(FREETYPE_CFLAGS) + +noinst_LTLIBRARIES = libsplash.la + +if ENABLE_XPDF_HEADERS + +poppler_splash_includedir = $(includedir)/poppler/splash +poppler_splash_include_HEADERS = \ + Splash.h \ + SplashBitmap.h \ + SplashClip.h \ + SplashErrorCodes.h \ + SplashFTFont.h \ + SplashFTFontEngine.h \ + SplashFTFontFile.h \ + SplashFont.h \ + SplashFontEngine.h \ + SplashFontFile.h \ + SplashFontFileID.h \ + SplashGlyphBitmap.h \ + SplashMath.h \ + SplashPath.h \ + SplashPattern.h \ + SplashScreen.h \ + SplashState.h \ + SplashT1Font.h \ + SplashT1FontEngine.h \ + SplashT1FontFile.h \ + SplashTypes.h \ + SplashXPath.h \ + SplashXPathScanner.h + +endif + +libsplash_la_SOURCES = \ + Splash.cc \ + SplashBitmap.cc \ + SplashClip.cc \ + SplashFTFont.cc \ + SplashFTFontEngine.cc \ + SplashFTFontFile.cc \ + SplashFont.cc \ + SplashFontEngine.cc \ + SplashFontFile.cc \ + SplashFontFileID.cc \ + SplashPath.cc \ + SplashPattern.cc \ + SplashScreen.cc \ + SplashState.cc \ + SplashT1Font.cc \ + SplashT1FontEngine.cc \ + SplashT1FontFile.cc \ + SplashXPath.cc \ + SplashXPathScanner.cc diff --git a/rosapps/smartpdf/poppler/splash/Splash.cc b/rosapps/smartpdf/poppler/splash/Splash.cc new file mode 100644 index 00000000000..5e5a1dd9b75 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/Splash.cc @@ -0,0 +1,3365 @@ +//======================================================================== +// +// Splash.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "SplashErrorCodes.h" +#include "SplashMath.h" +#include "SplashBitmap.h" +#include "SplashState.h" +#include "SplashPath.h" +#include "SplashXPath.h" +#include "SplashXPathScanner.h" +#include "SplashPattern.h" +#include "SplashScreen.h" +#include "SplashFont.h" +#include "SplashGlyphBitmap.h" +#include "Splash.h" + +//------------------------------------------------------------------------ + +static void blendNormal(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm) { + int i; + + for (i = 0; i < splashColorModeNComps[cm]; ++i) { + blend[i] = src[i]; + } +} + +//------------------------------------------------------------------------ +// Splash +//------------------------------------------------------------------------ + +Splash::Splash(SplashBitmap *bitmapA) { + bitmap = bitmapA; + state = new SplashState(bitmap->width, bitmap->height); + softMask = NULL; + clearModRegion(); + debugMode = gFalse; +} + +Splash::~Splash() { + while (state && state->next) { + restoreState(); + } + delete state; + if (softMask) { + delete softMask; + } +} + +//------------------------------------------------------------------------ +// state read +//------------------------------------------------------------------------ + +SplashPattern *Splash::getStrokePattern() { + return state->strokePattern; +} + +SplashPattern *Splash::getFillPattern() { + return state->fillPattern; +} + +SplashScreen *Splash::getScreen() { + return state->screen; +} + +SplashBlendFunc Splash::getBlendFunc() { + return state->blendFunc; +} + +SplashCoord Splash::getStrokeAlpha() { + return state->strokeAlpha; +} + +SplashCoord Splash::getFillAlpha() { + return state->fillAlpha; +} + +SplashCoord Splash::getLineWidth() { + return state->lineWidth; +} + +int Splash::getLineCap() { + return state->lineCap; +} + +int Splash::getLineJoin() { + return state->lineJoin; +} + +SplashCoord Splash::getMiterLimit() { + return state->miterLimit; +} + +SplashCoord Splash::getFlatness() { + return state->flatness; +} + +SplashCoord *Splash::getLineDash() { + return state->lineDash; +} + +int Splash::getLineDashLength() { + return state->lineDashLength; +} + +SplashCoord Splash::getLineDashPhase() { + return state->lineDashPhase; +} + +SplashClip *Splash::getClip() { + return state->clip; +} + +//------------------------------------------------------------------------ +// state write +//------------------------------------------------------------------------ + +void Splash::setStrokePattern(SplashPattern *strokePattern) { + state->setStrokePattern(strokePattern); +} + +void Splash::setFillPattern(SplashPattern *fillPattern) { + state->setFillPattern(fillPattern); +} + +void Splash::setScreen(SplashScreen *screen) { + state->setScreen(screen); +} + +void Splash::setBlendFunc(SplashBlendFunc func) { + state->blendFunc = func; +} + +void Splash::setStrokeAlpha(SplashCoord alpha) { + state->strokeAlpha = alpha; +} + +void Splash::setFillAlpha(SplashCoord alpha) { + state->fillAlpha = alpha; +} + +void Splash::setLineWidth(SplashCoord lineWidth) { + state->lineWidth = lineWidth; +} + +void Splash::setLineCap(int lineCap) { + state->lineCap = lineCap; +} + +void Splash::setLineJoin(int lineJoin) { + state->lineJoin = lineJoin; +} + +void Splash::setMiterLimit(SplashCoord miterLimit) { + state->miterLimit = miterLimit; +} + +void Splash::setFlatness(SplashCoord flatness) { + if (flatness < 1) { + state->flatness = 1; + } else { + state->flatness = flatness; + } +} + +void Splash::setLineDash(SplashCoord *lineDash, int lineDashLength, + SplashCoord lineDashPhase) { + state->setLineDash(lineDash, lineDashLength, lineDashPhase); +} + +void Splash::clipResetToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1) { + state->clip->resetToRect(x0, y0, x1, y1); +} + +SplashError Splash::clipToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1) { + return state->clip->clipToRect(x0, y0, x1, y1); +} + +SplashError Splash::clipToPath(SplashPath *path, GBool eo) { + return state->clip->clipToPath(path, state->flatness, eo); +} + +//------------------------------------------------------------------------ +// state save/restore +//------------------------------------------------------------------------ + +void Splash::saveState() { + SplashState *newState; + + newState = state->copy(); + newState->next = state; + state = newState; +} + +SplashError Splash::restoreState() { + SplashState *oldState; + + if (!state->next) { + return splashErrNoSave; + } + oldState = state; + state = state->next; + delete oldState; + return splashOk; +} + +//------------------------------------------------------------------------ +// soft mask +//------------------------------------------------------------------------ + +void Splash::setSoftMask(SplashBitmap *softMaskA) { + if (softMask) { + delete softMask; + } + softMask = softMaskA; +} + +//------------------------------------------------------------------------ +// modified region +//------------------------------------------------------------------------ + +void Splash::clearModRegion() { + modXMin = bitmap->getWidth(); + modYMin = bitmap->getHeight(); + modXMax = -1; + modYMax = -1; +} + +inline void Splash::updateModX(int x) { + if (x < modXMin) { + modXMin = x; + } + if (x > modXMax) { + modXMax = x; + } +} + +inline void Splash::updateModY(int y) { + if (y < modYMin) { + modYMin = y; + } + if (y > modYMax) { + modYMax = y; + } +} + +//------------------------------------------------------------------------ +// drawing operations +//------------------------------------------------------------------------ + +void Splash::clear(SplashColorPtr color) { + SplashColorPtr row, p; + Guchar mono; + int x, y; + + switch (bitmap->mode) { + case splashModeMono1: + mono = color[0] ? 0xff : 0x00; + if (bitmap->rowSize < 0) { + memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), + mono, -bitmap->rowSize * bitmap->height); + } else { + memset(bitmap->data, mono, bitmap->rowSize * bitmap->height); + } + break; + case splashModeMono8: + if (bitmap->rowSize < 0) { + memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), + color[0], -bitmap->rowSize * bitmap->height); + } else { + memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); + } + break; + case splashModeAMono8: + if (color[0] == color[1]) { + if (bitmap->rowSize < 0) { + memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), + color[0], -bitmap->rowSize * bitmap->height); + } else { + memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); + } + } else { + row = bitmap->data; + for (y = 0; y < bitmap->height; ++y) { + p = row; + for (x = 0; x < bitmap->width; ++x) { + *p++ = color[0]; + *p++ = color[1]; + } + row += bitmap->rowSize; + } + } + break; + case splashModeRGB8: + case splashModeBGR8: + if (color[0] == color[1] && color[1] == color[2]) { + if (bitmap->rowSize < 0) { + memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), + color[0], -bitmap->rowSize * bitmap->height); + } else { + memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); + } + } else { + row = bitmap->data; + for (y = 0; y < bitmap->height; ++y) { + p = row; + for (x = 0; x < bitmap->width; ++x) { + *p++ = color[0]; + *p++ = color[1]; + *p++ = color[2]; + } + row += bitmap->rowSize; + } + } + break; + case splashModeRGB8Qt: + if (color[0] == color[1] && color[1] == color[2]) { + if (bitmap->rowSize < 0) { + memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), + color[0], -bitmap->rowSize * bitmap->height); + } else { + memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); + } + } else { + row = bitmap->data; + for (y = 0; y < bitmap->height; ++y) { + p = row; + for (x = 0; x < bitmap->width; ++x) { + *p++ = color[2]; + *p++ = color[1]; + *p++ = color[0]; + *p++ = 255; + } + row += bitmap->rowSize; + } + } + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + if (color[0] == color[1] && color[1] == color[2] && color[2] == color[3]) { + if (bitmap->rowSize < 0) { + memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), + color[0], -bitmap->rowSize * bitmap->height); + } else { + memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); + } + } else { + row = bitmap->data; + for (y = 0; y < bitmap->height; ++y) { + p = row; + for (x = 0; x < bitmap->width; ++x) { + *p++ = color[0]; + *p++ = color[1]; + *p++ = color[2]; + *p++ = color[3]; + } + row += bitmap->rowSize; + } + } + break; +#if SPLASH_CMYK + case splashModeACMYK8: + if (color[0] == color[1] && color[1] == color[2] && + color[2] == color[3] && color[3] == color[4]) { + if (bitmap->rowSize < 0) { + memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), + color[0], -bitmap->rowSize * bitmap->height); + } else { + memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); + } + } else { + row = bitmap->data; + for (y = 0; y < bitmap->height; ++y) { + p = row; + for (x = 0; x < bitmap->width; ++x) { + *p++ = color[0]; + *p++ = color[1]; + *p++ = color[2]; + *p++ = color[3]; + *p++ = color[4]; + } + row += bitmap->rowSize; + } + } + break; +#endif + } + + updateModX(0); + updateModY(0); + updateModX(bitmap->width - 1); + updateModY(bitmap->height - 1); +} + +SplashError Splash::stroke(SplashPath *path) { + SplashXPath *xPath, *xPath2; + + if (debugMode) { + printf("stroke [dash:%d] [width:%.2f]:\n", + state->lineDashLength, (double)state->lineWidth); + dumpPath(path); + } + opClipRes = splashClipAllOutside; + if (path->length == 0) { + return splashErrEmptyPath; + } + xPath = new SplashXPath(path, state->flatness, gFalse); + if (xPath->length == 0) { + delete xPath; + return splashErrEmptyPath; + } + if (state->lineDashLength > 0) { + xPath2 = makeDashedPath(xPath); + delete xPath; + xPath = xPath2; + } + if (state->lineWidth <= 1) { + strokeNarrow(xPath); + } else { + strokeWide(xPath); + } + delete xPath; + return splashOk; +} + +void Splash::strokeNarrow(SplashXPath *xPath) { + SplashXPathSeg *seg; + int x0, x1, x2, x3, y0, y1, x, y, t; + SplashCoord dx, dy, dxdy; + SplashClipResult clipRes; + int nClipRes[3] = {0, 0, 0}; + int i; + + for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) { + + x0 = splashFloor(seg->x0); + x1 = splashFloor(seg->x1); + y0 = splashFloor(seg->y0); + y1 = splashFloor(seg->y1); + + // horizontal segment + if (y0 == y1) { + if (x0 > x1) { + t = x0; x0 = x1; x1 = t; + } + if ((clipRes = state->clip->testSpan(x0, x1, y0)) + != splashClipAllOutside) { + drawSpan(x0, x1, y0, state->strokePattern, state->strokeAlpha, + clipRes == splashClipAllInside); + } + + // segment with |dx| > |dy| + } else if (splashAbs(seg->dxdy) > 1) { + dx = seg->x1 - seg->x0; + dy = seg->y1 - seg->y0; + dxdy = seg->dxdy; + if (y0 > y1) { + t = y0; y0 = y1; y1 = t; + t = x0; x0 = x1; x1 = t; + dx = -dx; + dy = -dy; + } + if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0, + x0 <= x1 ? x1 : x0, y1)) + != splashClipAllOutside) { + if (dx > 0) { + x2 = x0; + x3 = splashFloor(seg->x0 + ((SplashCoord)y0 + 1 - seg->y0) * dxdy); + drawSpan(x2, (x2 <= x3 - 1) ? x3 - 1 : x2, y0, state->strokePattern, + state->strokeAlpha, clipRes == splashClipAllInside); + x2 = x3; + for (y = y0 + 1; y <= y1 - 1; ++y) { + x3 = splashFloor(seg->x0 + ((SplashCoord)y + 1 - seg->y0) * dxdy); + drawSpan(x2, x3 - 1, y, state->strokePattern, + state->strokeAlpha, clipRes == splashClipAllInside); + x2 = x3; + } + drawSpan(x2, x2 <= x1 ? x1 : x2, y1, state->strokePattern, + state->strokeAlpha, clipRes == splashClipAllInside); + } else { + x2 = x0; + x3 = splashFloor(seg->x0 + ((SplashCoord)y0 + 1 - seg->y0) * dxdy); + drawSpan((x3 + 1 <= x2) ? x3 + 1 : x2, x2, y0, state->strokePattern, + state->strokeAlpha, clipRes == splashClipAllInside); + x2 = x3; + for (y = y0 + 1; y <= y1 - 1; ++y) { + x3 = splashFloor(seg->x0 + ((SplashCoord)y + 1 - seg->y0) * dxdy); + drawSpan(x3 + 1, x2, y, state->strokePattern, + state->strokeAlpha, clipRes == splashClipAllInside); + x2 = x3; + } + drawSpan(x1, (x1 <= x2) ? x2 : x1, y1, state->strokePattern, + state->strokeAlpha, clipRes == splashClipAllInside); + } + } + + // segment with |dy| > |dx| + } else { + dxdy = seg->dxdy; + if (y0 > y1) { + t = x0; x0 = x1; x1 = t; + t = y0; y0 = y1; y1 = t; + } + if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0, + x0 <= x1 ? x1 : x0, y1)) + != splashClipAllOutside) { + drawPixel(x0, y0, state->strokePattern, state->strokeAlpha, + clipRes == splashClipAllInside); + for (y = y0 + 1; y <= y1 - 1; ++y) { + x = splashFloor(seg->x0 + ((SplashCoord)y - seg->y0) * dxdy); + drawPixel(x, y, state->strokePattern, state->strokeAlpha, + clipRes == splashClipAllInside); + } + drawPixel(x1, y1, state->strokePattern, state->strokeAlpha, + clipRes == splashClipAllInside); + } + } + ++nClipRes[clipRes]; + } + if (nClipRes[splashClipPartial] || + (nClipRes[splashClipAllInside] && nClipRes[splashClipAllOutside])) { + opClipRes = splashClipPartial; + } else if (nClipRes[splashClipAllInside]) { + opClipRes = splashClipAllInside; + } else { + opClipRes = splashClipAllOutside; + } +} + +void Splash::strokeWide(SplashXPath *xPath) { + SplashXPathSeg *seg, *seg2; + SplashPath *widePath; + SplashCoord d, dx, dy, wdx, wdy, dxPrev, dyPrev, wdxPrev, wdyPrev; + SplashCoord dotprod, miter; + int i, j; + + dx = dy = wdx = wdy = 0; // make gcc happy + dxPrev = dyPrev = wdxPrev = wdyPrev = 0; // make gcc happy + + for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) { + + // save the deltas for the previous segment; if this is the first + // segment on a subpath, compute the deltas for the last segment + // on the subpath (which may be used to draw a line join) + if (seg->flags & splashXPathFirst) { + for (j = i + 1, seg2 = &xPath->segs[j]; j < xPath->length; ++j, ++seg2) { + if (seg2->flags & splashXPathLast) { + d = splashDist(seg2->x0, seg2->y0, seg2->x1, seg2->y1); + if (d == 0) { + //~ not clear what the behavior should be for joins with d==0 + dxPrev = 0; + dyPrev = 1; + } else { + d = (SplashCoord)1 / d; + dxPrev = d * (seg2->x1 - seg2->x0); + dyPrev = d * (seg2->y1 - seg2->y0); + } + wdxPrev = (SplashCoord)0.5 * state->lineWidth * dxPrev; + wdyPrev = (SplashCoord)0.5 * state->lineWidth * dyPrev; + break; + } + } + } else { + dxPrev = dx; + dyPrev = dy; + wdxPrev = wdx; + wdyPrev = wdy; + } + + // compute deltas for this line segment + d = splashDist(seg->x0, seg->y0, seg->x1, seg->y1); + if (d == 0) { + // we need to draw end caps on zero-length lines + //~ not clear what the behavior should be for splashLineCapButt with d==0 + dx = 0; + dy = 1; + } else { + d = (SplashCoord)1 / d; + dx = d * (seg->x1 - seg->x0); + dy = d * (seg->y1 - seg->y0); + } + wdx = (SplashCoord)0.5 * state->lineWidth * dx; + wdy = (SplashCoord)0.5 * state->lineWidth * dy; + + // initialize the path (which will be filled) + widePath = new SplashPath(); + widePath->moveTo(seg->x0 - wdy, seg->y0 + wdx); + + // draw the start cap + if (seg->flags & splashXPathEnd0) { + switch (state->lineCap) { + case splashLineCapButt: + widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx); + break; + case splashLineCapRound: + widePath->arcCWTo(seg->x0 + wdy, seg->y0 - wdx, seg->x0, seg->y0); + break; + case splashLineCapProjecting: + widePath->lineTo(seg->x0 - wdx - wdy, seg->y0 + wdx - wdy); + widePath->lineTo(seg->x0 - wdx + wdy, seg->y0 - wdx - wdy); + widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx); + break; + } + } else { + widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx); + } + + // draw the left side of the segment + widePath->lineTo(seg->x1 + wdy, seg->y1 - wdx); + + // draw the end cap + if (seg->flags & splashXPathEnd1) { + switch (state->lineCap) { + case splashLineCapButt: + widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx); + break; + case splashLineCapRound: + widePath->arcCWTo(seg->x1 - wdy, seg->y1 + wdx, seg->x1, seg->y1); + break; + case splashLineCapProjecting: + widePath->lineTo(seg->x1 + wdx + wdy, seg->y1 - wdx + wdy); + widePath->lineTo(seg->x1 + wdx - wdy, seg->y1 + wdx + wdy); + widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx); + break; + } + } else { + widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx); + } + + // draw the right side of the segment + widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx); + + // fill the segment + fillWithPattern(widePath, gTrue, state->strokePattern, state->strokeAlpha); + delete widePath; + + // draw the line join + if (!(seg->flags & splashXPathEnd0)) { + widePath = NULL; + switch (state->lineJoin) { + case splashLineJoinMiter: + dotprod = -(dx * dxPrev + dy * dyPrev); + if (splashAbs(splashAbs(dotprod) - 1) > 0.01) { + widePath = new SplashPath(); + widePath->moveTo(seg->x0, seg->y0); + miter = (SplashCoord)2 / ((SplashCoord)1 - dotprod); + if (splashSqrt(miter) <= state->miterLimit) { + miter = splashSqrt(miter - 1); + if (dy * dxPrev > dx * dyPrev) { + widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev); + widePath->lineTo(seg->x0 + wdy - miter * wdx, + seg->y0 - wdx - miter * wdy); + widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx); + } else { + widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev); + widePath->lineTo(seg->x0 - wdy - miter * wdx, + seg->y0 + wdx - miter * wdy); + widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx); + } + } else { + if (dy * dxPrev > dx * dyPrev) { + widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev); + widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx); + } else { + widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev); + widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx); + } + } + } + break; + case splashLineJoinRound: + widePath = new SplashPath(); + widePath->moveTo(seg->x0 + wdy, seg->y0 - wdx); + widePath->arcCWTo(seg->x0 + wdy, seg->y0 - wdx, seg->x0, seg->y0); + break; + case splashLineJoinBevel: + widePath = new SplashPath(); + widePath->moveTo(seg->x0, seg->y0); + if (dy * dxPrev > dx * dyPrev) { + widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev); + widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx); + } else { + widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev); + widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx); + } + break; + } + if (widePath) { + fillWithPattern(widePath, gTrue, state->strokePattern, + state->strokeAlpha); + delete widePath; + } + } + } +} + +SplashXPath *Splash::makeDashedPath(SplashXPath *xPath) { + SplashXPath *dPath; + GBool lineDashStartOn, lineDashOn; + GBool atSegStart, atSegEnd, atDashStart, atDashEnd; + int lineDashStartIdx, lineDashIdx, subpathStart; + SplashCoord lineDashTotal, lineDashStartPhase, lineDashDist; + int segIdx; + SplashXPathSeg *seg; + SplashCoord sx0, sy0, sx1, sy1, ax0, ay0, ax1, ay1, dist; + int i; + + dPath = new SplashXPath(); + + lineDashTotal = 0; + for (i = 0; i < state->lineDashLength; ++i) { + lineDashTotal += state->lineDash[i]; + } + lineDashStartPhase = state->lineDashPhase; + i = splashFloor(lineDashStartPhase / lineDashTotal); + lineDashStartPhase -= (SplashCoord)i * lineDashTotal; + lineDashStartOn = gTrue; + lineDashStartIdx = 0; + while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) { + lineDashStartOn = !lineDashStartOn; + lineDashStartPhase -= state->lineDash[lineDashStartIdx]; + ++lineDashStartIdx; + } + + segIdx = 0; + seg = xPath->segs; + sx0 = seg->x0; + sy0 = seg->y0; + sx1 = seg->x1; + sy1 = seg->y1; + dist = splashDist(sx0, sy0, sx1, sy1); + lineDashOn = lineDashStartOn; + lineDashIdx = lineDashStartIdx; + lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase; + atSegStart = gTrue; + atDashStart = gTrue; + subpathStart = dPath->length; + + while (segIdx < xPath->length) { + + ax0 = sx0; + ay0 = sy0; + if (dist <= lineDashDist) { + ax1 = sx1; + ay1 = sy1; + lineDashDist -= dist; + dist = 0; + atSegEnd = gTrue; + atDashEnd = lineDashDist == 0 || (seg->flags & splashXPathLast); + } else { + ax1 = sx0 + (lineDashDist / dist) * (sx1 - sx0); + ay1 = sy0 + (lineDashDist / dist) * (sy1 - sy0); + sx0 = ax1; + sy0 = ay1; + dist -= lineDashDist; + lineDashDist = 0; + atSegEnd = gFalse; + atDashEnd = gTrue; + } + + if (lineDashOn) { + dPath->addSegment(ax0, ay0, ax1, ay1, + atDashStart, atDashEnd, + atDashStart, atDashEnd); + // end of closed subpath + if (atSegEnd && + (seg->flags & splashXPathLast) && + !(seg->flags & splashXPathEnd1)) { + dPath->segs[subpathStart].flags &= ~splashXPathEnd0; + dPath->segs[dPath->length - 1].flags &= ~splashXPathEnd1; + } + } + + if (atDashEnd) { + lineDashOn = !lineDashOn; + if (++lineDashIdx == state->lineDashLength) { + lineDashIdx = 0; + } + lineDashDist = state->lineDash[lineDashIdx]; + atDashStart = gTrue; + } else { + atDashStart = gFalse; + } + if (atSegEnd) { + if (++segIdx < xPath->length) { + ++seg; + sx0 = seg->x0; + sy0 = seg->y0; + sx1 = seg->x1; + sy1 = seg->y1; + dist = splashDist(sx0, sy0, sx1, sy1); + if (seg->flags & splashXPathFirst) { + lineDashOn = lineDashStartOn; + lineDashIdx = lineDashStartIdx; + lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase; + atDashStart = gTrue; + subpathStart = dPath->length; + } + } + atSegStart = gTrue; + } else { + atSegStart = gFalse; + } + } + + return dPath; +} + +SplashError Splash::fill(SplashPath *path, GBool eo) { + if (debugMode) { + printf("fill [eo:%d]:\n", eo); + dumpPath(path); + } + return fillWithPattern(path, eo, state->fillPattern, state->fillAlpha); +} + +SplashError Splash::fillWithPattern(SplashPath *path, GBool eo, + SplashPattern *pattern, + SplashCoord alpha) { + SplashXPath *xPath; + SplashXPathScanner *scanner; + int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y; + SplashClipResult clipRes, clipRes2; + + if (path->length == 0) { + return splashErrEmptyPath; + } + xPath = new SplashXPath(path, state->flatness, gTrue); + xPath->sort(); + scanner = new SplashXPathScanner(xPath, eo); + + // get the min and max x and y values + scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI); + + // check clipping + if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI)) + != splashClipAllOutside) { + + // limit the y range + if (yMinI < state->clip->getYMin()) { + yMinI = state->clip->getYMin(); + } + if (yMaxI > state->clip->getYMax()) { + yMaxI = state->clip->getYMax(); + } + + // draw the spans + for (y = yMinI; y <= yMaxI; ++y) { + while (scanner->getNextSpan(y, &x0, &x1)) { + if (clipRes == splashClipAllInside) { + drawSpan(x0, x1, y, pattern, alpha, gTrue); + } else { + // limit the x range + if (x0 < state->clip->getXMin()) { + x0 = state->clip->getXMin(); + } + if (x1 > state->clip->getXMax()) { + x1 = state->clip->getXMax(); + } + clipRes2 = state->clip->testSpan(x0, x1, y); + drawSpan(x0, x1, y, pattern, alpha, clipRes2 == splashClipAllInside); + } + } + } + } + opClipRes = clipRes; + + delete scanner; + delete xPath; + return splashOk; +} + +SplashError Splash::xorFill(SplashPath *path, GBool eo) { + SplashXPath *xPath; + SplashXPathScanner *scanner; + int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y; + SplashClipResult clipRes, clipRes2; + + if (path->length == 0) { + return splashErrEmptyPath; + } + xPath = new SplashXPath(path, state->flatness, gTrue); + xPath->sort(); + scanner = new SplashXPathScanner(xPath, eo); + + // get the min and max x and y values + scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI); + + // check clipping + if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI)) + != splashClipAllOutside) { + + // limit the y range + if (yMinI < state->clip->getYMin()) { + yMinI = state->clip->getYMin(); + } + if (yMaxI > state->clip->getYMax()) { + yMaxI = state->clip->getYMax(); + } + + // draw the spans + for (y = yMinI; y <= yMaxI; ++y) { + while (scanner->getNextSpan(y, &x0, &x1)) { + if (clipRes == splashClipAllInside) { + xorSpan(x0, x1, y, state->fillPattern, gTrue); + } else { + // limit the x range + if (x0 < state->clip->getXMin()) { + x0 = state->clip->getXMin(); + } + if (x1 > state->clip->getXMax()) { + x1 = state->clip->getXMax(); + } + clipRes2 = state->clip->testSpan(x0, x1, y); + xorSpan(x0, x1, y, state->fillPattern, + clipRes2 == splashClipAllInside); + } + } + } + } + opClipRes = clipRes; + + delete scanner; + delete xPath; + return splashOk; +} + +void Splash::drawPixel(int x, int y, SplashColorPtr color, + SplashCoord alpha, GBool noClip) { + SplashBlendFunc blendFunc; + SplashColorPtr p; + SplashColor dest, blend; + int alpha2, ialpha2; + Guchar t; + + if (noClip || state->clip->test(x, y)) { + if (alpha != 1 || softMask || state->blendFunc) { + blendFunc = state->blendFunc ? state->blendFunc : &blendNormal; + if (softMask) { + alpha2 = (int)(alpha * softMask->data[y * softMask->rowSize + x]); + } else { + alpha2 = (int)(alpha * 255); + } + ialpha2 = 255 - alpha2; + switch (bitmap->mode) { + case splashModeMono1: + p = &bitmap->data[y * bitmap->rowSize + (x >> 3)]; + dest[0] = (*p >> (7 - (x & 7))) & 1; + (*blendFunc)(color, dest, blend, bitmap->mode); + t = (alpha2 * blend[0] + ialpha2 * dest[0]) >> 8; + if (t) { + *p |= 0x80 >> (x & 7); + } else { + *p &= ~(0x80 >> (x & 7)); + } + break; + case splashModeMono8: + p = &bitmap->data[y * bitmap->rowSize + x]; + (*blendFunc)(color, p, blend, bitmap->mode); + // note: floor(x / 255) = x >> 8 (for 16-bit x) + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + break; + case splashModeAMono8: + p = &bitmap->data[y * bitmap->rowSize + 2 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + break; + case splashModeRGB8: + case splashModeBGR8: + p = &bitmap->data[y * bitmap->rowSize + 3 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + break; + case splashModeRGB8Qt: + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[2] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[0] + ialpha2 * p[2]) >> 8; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &bitmap->data[y * bitmap->rowSize + 5 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + p[4] = (alpha2 * blend[4] + ialpha2 * p[4]) >> 8; + break; +#endif + } + } else { + switch (bitmap->mode) { + case splashModeMono1: + p = &bitmap->data[y * bitmap->rowSize + (x >> 3)]; + if (color[0]) { + *p |= 0x80 >> (x & 7); + } else { + *p &= ~(0x80 >> (x & 7)); + } + break; + case splashModeMono8: + p = &bitmap->data[y * bitmap->rowSize + x]; + p[0] = color[0]; + break; + case splashModeAMono8: + p = &bitmap->data[y * bitmap->rowSize + 2 * x]; + p[0] = color[0]; + p[1] = color[1]; + break; + case splashModeRGB8: + case splashModeBGR8: + p = &bitmap->data[y * bitmap->rowSize + 3 * x]; + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + break; + case splashModeRGB8Qt: + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + p[0] = color[2]; + p[1] = color[1]; + p[2] = color[0]; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &bitmap->data[y * bitmap->rowSize + 5 * x]; + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + p[4] = color[4]; + break; +#endif + } + } + updateModX(x); + updateModY(y); + } +} + +void Splash::drawPixel(int x, int y, SplashPattern *pattern, + SplashCoord alpha, GBool noClip) { + SplashBlendFunc blendFunc; + SplashColor color; + SplashColorPtr p; + SplashColor dest, blend; + int alpha2, ialpha2; + Guchar t; + + if (noClip || state->clip->test(x, y)) { + if (alpha != 1 || softMask || state->blendFunc) { + blendFunc = state->blendFunc ? state->blendFunc : &blendNormal; + pattern->getColor(x, y, color); + if (softMask) { + alpha2 = (int)(alpha * softMask->data[y * softMask->rowSize + x]); + } else { + alpha2 = (int)(alpha * 255); + } + ialpha2 = 255 - alpha2; + switch (bitmap->mode) { + case splashModeMono1: + p = &bitmap->data[y * bitmap->rowSize + (x >> 3)]; + dest[0] = (*p >> (7 - (x & 7))) & 1; + (*blendFunc)(color, dest, blend, bitmap->mode); + t = (alpha2 * blend[0] + ialpha2 * dest[0]) >> 8; + if (t) { + *p |= 0x80 >> (x & 7); + } else { + *p &= ~(0x80 >> (x & 7)); + } + break; + case splashModeMono8: + p = &bitmap->data[y * bitmap->rowSize + x]; + (*blendFunc)(color, p, blend, bitmap->mode); + // note: floor(x / 255) = x >> 8 (for 16-bit x) + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + break; + case splashModeAMono8: + p = &bitmap->data[y * bitmap->rowSize + 2 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + break; + case splashModeRGB8: + case splashModeBGR8: + p = &bitmap->data[y * bitmap->rowSize + 3 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + break; + case splashModeRGB8Qt: + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[2] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[0] + ialpha2 * p[2]) >> 8; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &bitmap->data[y * bitmap->rowSize + 5 * x]; + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + p[4] = (alpha2 * blend[4] + ialpha2 * p[4]) >> 8; + break; +#endif + } + } else { + pattern->getColor(x, y, color); + switch (bitmap->mode) { + case splashModeMono1: + p = &bitmap->data[y * bitmap->rowSize + (x >> 3)]; + if (color[0]) { + *p |= 0x80 >> (x & 7); + } else { + *p &= ~(0x80 >> (x & 7)); + } + break; + case splashModeMono8: + p = &bitmap->data[y * bitmap->rowSize + x]; + p[0] = color[0]; + break; + case splashModeAMono8: + p = &bitmap->data[y * bitmap->rowSize + 2 * x]; + p[0] = color[0]; + p[1] = color[1]; + break; + case splashModeRGB8: + case splashModeBGR8: + p = &bitmap->data[y * bitmap->rowSize + 3 * x]; + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + break; + case splashModeRGB8Qt: + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + p[0] = color[2]; + p[1] = color[1]; + p[2] = color[0]; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &bitmap->data[y * bitmap->rowSize + 4 * x]; + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &bitmap->data[y * bitmap->rowSize + 5 * x]; + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + p[4] = color[4]; + break; +#endif + } + } + updateModX(x); + updateModY(y); + } +} + +void Splash::drawSpan(int x0, int x1, int y, SplashPattern *pattern, + SplashCoord alpha, GBool noClip) { + SplashBlendFunc blendFunc; + SplashColor color; + SplashColorPtr p; + SplashColor dest, blend; + Guchar mask, t; + int alpha2, ialpha2; + int i, j, n; + + n = x1 - x0 + 1; + + if (noClip) { + updateModX(x0); + updateModX(x1); + updateModY(y); + } + + if (alpha != 1 || softMask || state->blendFunc) { + blendFunc = state->blendFunc ? state->blendFunc : &blendNormal; + if (softMask) { + alpha2 = ialpha2 = 0; // make gcc happy + } else { + alpha2 = (int)(alpha * 255); + ialpha2 = 255 - alpha2; + } + switch (bitmap->mode) { + case splashModeMono1: + p = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)]; + i = 0; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + if ((j = x0 & 7)) { + mask = 0x80 >> j; + for (; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + dest[0] = (*p >> (7 - j)) & 1; + (*blendFunc)(color, dest, blend, bitmap->mode); + t = (alpha2 * blend[0] + ialpha2 * dest[0]) >> 8; + if (t) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + while (i < n) { + mask = 0x80; + for (j = 0; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + dest[0] = (*p >> (7 - j)) & 1; + (*blendFunc)(color, dest, blend, bitmap->mode); + t = (alpha2 * blend[0] + ialpha2 * dest[0]) >> 8; + if (t) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + } else { + if ((j = x0 & 7)) { + mask = 0x80 >> j; + for (; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + dest[0] = (*p >> (7 - j)) & 1; + (*blendFunc)(color, dest, blend, bitmap->mode); + t = (alpha2 * blend[0] + ialpha2 * dest[0]) >> 8; + if (t) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + while (i < n) { + mask = 0x80; + for (j = 0; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + dest[0] = (*p >> (7 - j)) & 1; + (*blendFunc)(color, dest, blend, bitmap->mode); + t = (alpha2 * blend[0] + ialpha2 * dest[0]) >> 8; + if (t) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + } + break; + + case splashModeMono8: + p = &bitmap->data[y * bitmap->rowSize + x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + *p = (alpha2 * blend[0] + ialpha2 * *p) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + ++p; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + *p = (alpha2 * blend[0] + ialpha2 * *p) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + ++p; + } + } + break; + + case splashModeAMono8: + p = &bitmap->data[y * bitmap->rowSize + 2 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 2; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 2; + } + } + break; + + case splashModeRGB8: + case splashModeBGR8: + p = &bitmap->data[y * bitmap->rowSize + 3 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 3; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 3; + } + } + break; + + case splashModeRGB8Qt: + p = &bitmap->data[y * bitmap->rowSize + 4 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[2] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[0] + ialpha2 * p[2]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } + break; + + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &bitmap->data[y * bitmap->rowSize + 4 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &bitmap->data[y * bitmap->rowSize + 5 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + p[4] = (alpha2 * blend[4] + ialpha2 * p[4]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (softMask) { + alpha2 = (int)(alpha * + softMask->data[y * softMask->rowSize + x0 + i]); + ialpha2 = 255 - alpha2; + } + (*blendFunc)(color, p, blend, bitmap->mode); + p[0] = (alpha2 * blend[0] + ialpha2 * p[0]) >> 8; + p[1] = (alpha2 * blend[1] + ialpha2 * p[1]) >> 8; + p[2] = (alpha2 * blend[2] + ialpha2 * p[2]) >> 8; + p[3] = (alpha2 * blend[3] + ialpha2 * p[3]) >> 8; + p[4] = (alpha2 * blend[4] + ialpha2 * p[4]) >> 8; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } + break; +#endif + } + + } else { + switch (bitmap->mode) { + case splashModeMono1: + p = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)]; + i = 0; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + if ((j = x0 & 7)) { + mask = 0x80 >> j; + for (; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + if (color[0]) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + while (i < n) { + mask = 0x80; + for (j = 0; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + if (color[0]) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + } else { + if ((j = x0 & 7)) { + mask = 0x80 >> j; + for (; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (color[0]) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + while (i < n) { + mask = 0x80; + for (j = 0; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (color[0]) { + *p |= mask; + } else { + *p &= ~mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + } + break; + + case splashModeMono8: + p = &bitmap->data[y * bitmap->rowSize + x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + *p = color[0]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + ++p; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + *p = color[0]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + ++p; + } + } + break; + + case splashModeAMono8: + p = &bitmap->data[y * bitmap->rowSize + 2 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + p[0] = color[0]; + p[1] = color[1]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 2; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] = color[0]; + p[1] = color[1]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 2; + } + } + break; + + case splashModeRGB8: + case splashModeBGR8: + p = &bitmap->data[y * bitmap->rowSize + 3 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 3; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 3; + } + } + break; + + case splashModeRGB8Qt: + p = &bitmap->data[y * bitmap->rowSize + 4 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + p[0] = color[2]; + p[1] = color[1]; + p[2] = color[0]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } + break; + + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &bitmap->data[y * bitmap->rowSize + 4 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &bitmap->data[y * bitmap->rowSize + 5 * x0]; + if (pattern->isStatic()) { + pattern->getColor(0, 0, color); + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + p[4] = color[4]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } else { + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] = color[0]; + p[1] = color[1]; + p[2] = color[2]; + p[3] = color[3]; + p[4] = color[4]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + } + break; +#endif + } + } +} + +void Splash::xorSpan(int x0, int x1, int y, SplashPattern *pattern, + GBool noClip) { + SplashColor color; + SplashColorPtr p; + Guchar mask; + int i, j, n; + + n = x1 - x0 + 1; + + if (noClip) { + updateModX(x0); + updateModX(x1); + updateModY(y); + } + + switch (bitmap->mode) { + case splashModeMono1: + p = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)]; + i = 0; + if ((j = x0 & 7)) { + mask = 0x80 >> j; + for (; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (color[0]) { + *p ^= mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + while (i < n) { + mask = 0x80; + for (j = 0; j < 8 && i < n; ++i, ++j) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + if (color[0]) { + *p ^= mask; + } + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + mask >>= 1; + } + ++p; + } + break; + + case splashModeMono8: + p = &bitmap->data[y * bitmap->rowSize + x0]; + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + *p ^= color[0]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + ++p; + } + break; + + case splashModeAMono8: + p = &bitmap->data[y * bitmap->rowSize + 2 * x0]; + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] ^= color[0]; + p[1] ^= color[1]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 2; + } + break; + + case splashModeRGB8: + case splashModeBGR8: + p = &bitmap->data[y * bitmap->rowSize + 3 * x0]; + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] ^= color[0]; + p[1] ^= color[1]; + p[2] ^= color[2]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 3; + } + break; + + case splashModeRGB8Qt: + p = &bitmap->data[y * bitmap->rowSize + 4 * x0]; + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] ^= color[2]; + p[1] ^= color[1]; + p[2] ^= color[0]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + break; + + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &bitmap->data[y * bitmap->rowSize + 4 * x0]; + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] ^= color[0]; + p[1] ^= color[1]; + p[2] ^= color[2]; + p[3] ^= color[3]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &bitmap->data[y * bitmap->rowSize + 5 * x0]; + for (i = 0; i < n; ++i) { + if (noClip || state->clip->test(x0 + i, y)) { + pattern->getColor(x0 + i, y, color); + p[0] ^= color[0]; + p[1] ^= color[1]; + p[2] ^= color[2]; + p[3] ^= color[3]; + p[4] ^= color[4]; + if (!noClip) { + updateModX(x0 + i); + updateModY(y); + } + } + p += 4; + } + break; +#endif + } +} + +SplashError Splash::fillChar(SplashCoord x, SplashCoord y, + int c, SplashFont *font) { + SplashGlyphBitmap glyph; + int x0, y0, xFrac, yFrac; + SplashError err; + + if (debugMode) { + printf("fillChar: x=%.2f y=%.2f c=%3d=0x%02x='%c'\n", + (double)x, (double)y, c, c, c); + } + x0 = splashFloor(x); + xFrac = splashFloor((x - x0) * splashFontFraction); + y0 = splashFloor(y); + yFrac = splashFloor((y - y0) * splashFontFraction); + if (!font->getGlyph(c, xFrac, yFrac, &glyph)) { + return splashErrNoGlyph; + } + err = fillGlyph(x, y, &glyph); + if (glyph.freeData) { + gfree(glyph.data); + } + return err; +} + +SplashError Splash::fillGlyph(SplashCoord x, SplashCoord y, + SplashGlyphBitmap *glyph) { + SplashBlendFunc blendFunc; + int alpha0, alpha, ialpha; + Guchar *p; + SplashColor fg, dest, blend; + SplashColorPtr pix; + SplashClipResult clipRes; + GBool noClip; + Guchar t; + int x0, y0, x1, y1, xx, xx1, yy; + + x0 = splashFloor(x); + y0 = splashFloor(y); + + if ((clipRes = state->clip->testRect(x0 - glyph->x, + y0 - glyph->y, + x0 - glyph->x + glyph->w - 1, + y0 - glyph->y + glyph->h - 1)) + != splashClipAllOutside) { + noClip = clipRes == splashClipAllInside; + + if (noClip) { + updateModX(x0 - glyph->x); + updateModX(x0 - glyph->x + glyph->w - 1); + updateModY(y0 - glyph->y); + updateModY(y0 - glyph->y + glyph->h - 1); + } + + //~ optimize this + if (state->fillAlpha != 1 || softMask || state->blendFunc) { + blendFunc = state->blendFunc ? state->blendFunc : &blendNormal; + if (glyph->aa) { + p = glyph->data; + for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { + for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) { + alpha = *p++; + if (softMask) { + alpha = (int)(alpha * (float)state->fillAlpha * + softMask->data[y1 * softMask->rowSize + x1]); + } else { + alpha = (int)(alpha * (float)state->fillAlpha); + } + if (alpha > 0) { + if (noClip || state->clip->test(x1, y1)) { + ialpha = 255 - alpha; + state->fillPattern->getColor(x1, y1, fg); + switch (bitmap->mode) { + case splashModeMono1: + pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; + dest[0] = (*pix >> (7 - (x1 & 7))) & 1; + (*blendFunc)(fg, dest, blend, bitmap->mode); + t = (alpha * blend[0] + ialpha * dest[0]) >> 8; + if (t) { + *pix |= 0x80 >> (x1 & 7); + } else { + *pix &= ~(0x80 >> (x1 & 7)); + } + break; + case splashModeMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + // note: floor(x / 255) = x >> 8 (for 16-bit x) + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + break; + case splashModeAMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + break; + case splashModeRGB8: + case splashModeBGR8: + pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; + break; + case splashModeRGB8Qt: + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[2] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[0] + ialpha * pix[2]) >> 8; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; + pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; + pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; + pix[4] = (alpha * blend[4] + ialpha * pix[4]) >> 8; + break; +#endif + } + if (!noClip) { + updateModX(x1); + updateModY(y1); + } + } + } + } + } + + } else { + p = glyph->data; + for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { + for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; xx += 8) { + alpha0 = *p++; + for (xx1 = 0; xx1 < 8 && xx + xx1 < glyph->w; ++xx1, ++x1) { + if (alpha0 & 0x80) { + if (noClip || state->clip->test(x1, y1)) { + if (softMask) { + alpha = (int)(state->fillAlpha * + softMask->data[y1 * softMask->rowSize + x1]); + } else { + alpha = (int)(state->fillAlpha * 255); + } + ialpha = 255 - alpha; + state->fillPattern->getColor(x1, y1, fg); + switch (bitmap->mode) { + case splashModeMono1: + pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; + dest[0] = (*pix >> (7 - (x1 & 7))) & 1; + (*blendFunc)(fg, dest, blend, bitmap->mode); + t = (alpha * blend[0] + ialpha * dest[0]) >> 8; + if (t) { + *pix |= 0x80 >> (x1 & 7); + } else { + *pix &= ~(0x80 >> (x1 & 7)); + } + break; + case splashModeMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + // note: floor(x / 255) = x >> 8 (for 16-bit x) + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + break; + case splashModeAMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + break; + case splashModeRGB8: + case splashModeBGR8: + pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; + break; + case splashModeRGB8Qt: + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[2] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[0] + ialpha * pix[2]) >> 8; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; + pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; + (*blendFunc)(fg, pix, blend, bitmap->mode); + pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; + pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; + pix[4] = (alpha * blend[4] + ialpha * pix[4]) >> 8; + break; +#endif + } + if (!noClip) { + updateModX(x1); + updateModY(y1); + } + } + } + alpha0 <<= 1; + } + } + } + } + + } else { + if (glyph->aa) { + p = glyph->data; + for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { + for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) { + alpha = *p++; + if (alpha > 0) { + if (noClip || state->clip->test(x1, y1)) { + ialpha = 255 - alpha; + state->fillPattern->getColor(x1, y1, fg); + switch (bitmap->mode) { + case splashModeMono1: + if (alpha >= 0x80) { + pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; + if (fg[0]) { + *pix |= 0x80 >> (x1 & 7); + } else { + *pix &= ~(0x80 >> (x1 & 7)); + } + } + break; + case splashModeMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + x1]; + // note: floor(x / 255) = x >> 8 (for 16-bit x) + pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; + break; + case splashModeAMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; + pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; + break; + case splashModeRGB8: + case splashModeBGR8: + pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; + pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * fg[2] + ialpha * pix[2]) >> 8; + break; + case splashModeRGB8Qt: + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + pix[0] = (alpha * fg[2] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * fg[0] + ialpha * pix[2]) >> 8; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * fg[2] + ialpha * pix[2]) >> 8; + pix[3] = (alpha * fg[3] + ialpha * pix[3]) >> 8; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; + pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; + pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; + pix[2] = (alpha * fg[2] + ialpha * pix[2]) >> 8; + pix[3] = (alpha * fg[3] + ialpha * pix[3]) >> 8; + pix[4] = (alpha * fg[4] + ialpha * pix[4]) >> 8; + break; +#endif + } + if (!noClip) { + updateModX(x1); + updateModY(y1); + } + } + } + } + } + + } else { + p = glyph->data; + for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { + for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; xx += 8) { + alpha0 = *p++; + for (xx1 = 0; xx1 < 8 && xx + xx1 < glyph->w; ++xx1, ++x1) { + if (alpha0 & 0x80) { + if (noClip || state->clip->test(x1, y1)) { + state->fillPattern->getColor(x1, y1, fg); + switch (bitmap->mode) { + case splashModeMono1: + pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; + if (fg[0]) { + *pix |= 0x80 >> (x1 & 7); + } else { + *pix &= ~(0x80 >> (x1 & 7)); + } + break; + case splashModeMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + x1]; + pix[0] = fg[0]; + break; + case splashModeAMono8: + pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; + pix[0] = fg[0]; + pix[1] = fg[1]; + break; + case splashModeRGB8: + case splashModeBGR8: + pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; + pix[0] = fg[0]; + pix[1] = fg[1]; + pix[2] = fg[2]; + break; + case splashModeRGB8Qt: + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + pix[0] = fg[2]; + pix[1] = fg[1]; + pix[2] = fg[0]; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; + pix[0] = fg[0]; + pix[1] = fg[1]; + pix[2] = fg[2]; + pix[3] = fg[3]; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; + pix[0] = fg[0]; + pix[1] = fg[1]; + pix[2] = fg[2]; + pix[3] = fg[3]; + pix[4] = fg[4]; + break; +#endif + } + if (!noClip) { + updateModX(x1); + updateModY(y1); + } + } + } + alpha0 <<= 1; + } + } + } + } + } + } + opClipRes = clipRes; + + return splashOk; +} + +SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData, + int w, int h, SplashCoord *mat) { + GBool rot; + SplashCoord xScale, yScale, xShear, yShear, yShear1; + int tx, tx2, ty, ty2, scaledWidth, scaledHeight, xSign, ySign; + int ulx, uly, llx, lly, urx, ury, lrx, lry; + int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1; + int xMin, xMax, yMin, yMax; + SplashClipResult clipRes, clipRes2; + int yp, yq, yt, yStep, lastYStep; + int xp, xq, xt, xStep, xSrc; + int k1, spanXMin, spanXMax, spanY; + SplashColorPtr pixBuf, p; + int pixAcc; + SplashCoord alpha; + int x, y, x1, x2, y2; + SplashCoord y1; + int n, m, i, j; + + if (debugMode) { + printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n", + w, h, (double)mat[0], (double)mat[1], (double)mat[2], + (double)mat[3], (double)mat[4], (double)mat[5]); + } + if (w == 0 && h == 0) return splashErrZeroImage; + + // check for singular matrix + if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) { + return splashErrSingularMatrix; + } + + // compute scale, shear, rotation, translation parameters + rot = splashAbs(mat[1]) > splashAbs(mat[0]); + if (rot) { + xScale = -mat[1]; + yScale = mat[2] - (mat[0] * mat[3]) / mat[1]; + xShear = -mat[3] / yScale; + yShear = -mat[0] / mat[1]; + } else { + xScale = mat[0]; + yScale = mat[3] - (mat[1] * mat[2]) / mat[0]; + xShear = mat[2] / yScale; + yShear = mat[1] / mat[0]; + } + // the +/-0.01 in these computations is to avoid floating point + // precision problems which can lead to gaps between image stripes + // (it can cause image stripes to overlap, but that's a much less + // visible problem) + if (xScale >= 0) { + tx = splashRound(mat[4] - 0.01); + tx2 = splashRound(mat[4] + xScale + 0.01) - 1; + } else { + tx = splashRound(mat[4] + 0.01) - 1; + tx2 = splashRound(mat[4] + xScale - 0.01); + } + scaledWidth = abs(tx2 - tx) + 1; + if (scaledWidth == 0) { + // technically, this should draw nothing, but it generally seems + // better to draw a one-pixel-wide stripe rather than throwing it + // away + scaledWidth = 1; + } + if (yScale >= 0) { + ty = splashRound(mat[5] - 0.01); + ty2 = splashRound(mat[5] + yScale + 0.01) - 1; + } else { + ty = splashRound(mat[5] + 0.01) - 1; + ty2 = splashRound(mat[5] + yScale - 0.01); + } + scaledHeight = abs(ty2 - ty) + 1; + if (scaledHeight == 0) { + // technically, this should draw nothing, but it generally seems + // better to draw a one-pixel-wide stripe rather than throwing it + // away + scaledHeight = 1; + } + xSign = (xScale < 0) ? -1 : 1; + ySign = (yScale < 0) ? -1 : 1; + yShear1 = (SplashCoord)xSign * yShear; + + // clipping + ulx1 = 0; + uly1 = 0; + urx1 = xSign * (scaledWidth - 1); + ury1 = (int)(yShear * urx1); + llx1 = splashRound(xShear * ySign * (scaledHeight - 1)); + lly1 = ySign * (scaledHeight - 1) + (int)(yShear * llx1); + lrx1 = xSign * (scaledWidth - 1) + + splashRound(xShear * ySign * (scaledHeight - 1)); + lry1 = ySign * (scaledHeight - 1) + (int)(yShear * lrx1); + if (rot) { + ulx = tx + uly1; uly = ty - ulx1; + urx = tx + ury1; ury = ty - urx1; + llx = tx + lly1; lly = ty - llx1; + lrx = tx + lry1; lry = ty - lrx1; + } else { + ulx = tx + ulx1; uly = ty + uly1; + urx = tx + urx1; ury = ty + ury1; + llx = tx + llx1; lly = ty + lly1; + lrx = tx + lrx1; lry = ty + lry1; + } + xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx + : (llx < lrx) ? llx : lrx + : (urx < llx) ? (urx < lrx) ? urx : lrx + : (llx < lrx) ? llx : lrx; + xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx + : (llx > lrx) ? llx : lrx + : (urx > llx) ? (urx > lrx) ? urx : lrx + : (llx > lrx) ? llx : lrx; + yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry + : (lly < lry) ? lly : lry + : (ury < lly) ? (ury < lry) ? ury : lry + : (lly < lry) ? lly : lry; + yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry + : (lly > lry) ? lly : lry + : (ury > lly) ? (ury > lry) ? ury : lry + : (lly > lry) ? lly : lry; + clipRes = state->clip->testRect(xMin, yMin, xMax, yMax); + opClipRes = clipRes; + + // compute Bresenham parameters for x and y scaling + yp = h / scaledHeight; + yq = h % scaledHeight; + xp = w / scaledWidth; + xq = w % scaledWidth; + + // allocate pixel buffer + pixBuf = (SplashColorPtr)gmalloc((yp + 1) * w); + + // init y scale Bresenham + yt = 0; + lastYStep = 1; + + for (y = 0; y < scaledHeight; ++y) { + + // y scale Bresenham + yStep = yp; + yt += yq; + if (yt >= scaledHeight) { + yt -= scaledHeight; + ++yStep; + } + + // read row(s) from image + n = (yp > 0) ? yStep : lastYStep; + if (n > 0) { + p = pixBuf; + for (i = 0; i < n; ++i) { + (*src)(srcData, p); + p += w; + } + } + lastYStep = yStep; + + // loop-invariant constants + k1 = splashRound(xShear * ySign * y); + + // clipping test + if (clipRes != splashClipAllInside && + !rot && + (int)(yShear * k1) == + (int)(yShear * (xSign * (scaledWidth - 1) + k1))) { + if (xSign > 0) { + spanXMin = tx + k1; + spanXMax = spanXMin + (scaledWidth - 1); + } else { + spanXMax = tx + k1; + spanXMin = spanXMax - (scaledWidth - 1); + } + spanY = ty + ySign * y + (int)(yShear * k1); + clipRes2 = state->clip->testSpan(spanXMin, spanXMax, spanY); + if (clipRes2 == splashClipAllOutside) { + continue; + } + } else { + clipRes2 = clipRes; + } + + // init x scale Bresenham + xt = 0; + xSrc = 0; + + // x shear + x1 = k1; + + // y shear + y1 = (SplashCoord)ySign * y + yShear * x1; + // this is a kludge: if yShear1 is negative, then (int)y1 would + // change immediately after the first pixel, which is not what we + // want + if (yShear1 < 0) { + y1 += 0.999; + } + + // loop-invariant constants + n = yStep > 0 ? yStep : 1; + + for (x = 0; x < scaledWidth; ++x) { + + // x scale Bresenham + xStep = xp; + xt += xq; + if (xt >= scaledWidth) { + xt -= scaledWidth; + ++xStep; + } + + // rotation + if (rot) { + x2 = (int)y1; + y2 = -x1; + } else { + x2 = x1; + y2 = (int)y1; + } + + // compute the alpha value for (x,y) after the x and y scaling + // operations + m = xStep > 0 ? xStep : 1; + p = pixBuf + xSrc; + pixAcc = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + pixAcc += *p++; + } + p += w - m; + } + + // blend fill color with background + if (pixAcc != 0) { + if (pixAcc == n * m) { + drawPixel(tx + x2, ty + y2, state->fillPattern, state->fillAlpha, + clipRes2 == splashClipAllInside); + } else { + alpha = (SplashCoord)pixAcc / (SplashCoord)(n * m); + drawPixel(tx + x2, ty + y2, state->fillPattern, + state->fillAlpha * alpha, + clipRes2 == splashClipAllInside); + } + } + + // x scale Bresenham + xSrc += xStep; + + // x shear + x1 += xSign; + + // y shear + y1 += yShear1; + } + } + + // free memory + gfree(pixBuf); + + return splashOk; +} + +SplashError Splash::drawImage(SplashImageSource src, void *srcData, + SplashColorMode srcMode, + int w, int h, SplashCoord *mat) { + GBool ok, rot, halftone, srcAlpha; + SplashCoord xScale, yScale, xShear, yShear, yShear1; + int tx, tx2, ty, ty2, scaledWidth, scaledHeight, xSign, ySign; + int ulx, uly, llx, lly, urx, ury, lrx, lry; + int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1; + int xMin, xMax, yMin, yMax; + SplashClipResult clipRes, clipRes2; + int yp, yq, yt, yStep, lastYStep; + int xp, xq, xt, xStep, xSrc; + int k1, spanXMin, spanXMax, spanY; + SplashColorPtr pixBuf, p; + SplashColor pix; +#if SPLASH_CMYK + int pixAcc0, pixAcc1, pixAcc2, pixAcc3; +#else + int pixAcc0, pixAcc1, pixAcc2; +#endif + int alphaAcc; + SplashCoord pixMul, alphaMul, alpha; + int x, y, x1, x2, y2; + SplashCoord y1; + int nComps, n, m, i, j; + + if (debugMode) { + printf("drawImage: srcMode=%d w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n", + srcMode, w, h, (double)mat[0], (double)mat[1], (double)mat[2], + (double)mat[3], (double)mat[4], (double)mat[5]); + } + + // check color modes + ok = gFalse; // make gcc happy + nComps = 0; // make gcc happy + halftone = gFalse; + srcAlpha = gFalse; + switch (bitmap->mode) { + case splashModeMono1: + ok = srcMode == splashModeMono1 || srcMode == splashModeMono8 || + srcMode == splashModeAMono8; + halftone = srcMode == splashModeMono8 || srcMode == splashModeAMono8; + srcAlpha = srcMode == splashModeAMono8; + nComps = srcAlpha ? 2 : 1; + break; + case splashModeMono8: + ok = srcMode == splashModeMono8 || srcMode == splashModeAMono8; + srcAlpha = srcMode == splashModeAMono8; + nComps = srcAlpha ? 2 : 1; + break; + case splashModeAMono8: + //~ not implemented yet + ok = gFalse; + nComps = 2; + break; + case splashModeRGB8Qt: + case splashModeRGB8: + ok = srcMode == splashModeRGB8 || srcMode == splashModeARGB8; + srcAlpha = srcMode == splashModeARGB8; + nComps = srcAlpha ? 4 : 3; + break; + case splashModeBGR8: + ok = srcMode == splashModeBGR8 || srcMode == splashModeBGRA8; + srcAlpha = srcMode == splashModeBGRA8; + nComps = srcAlpha ? 4 : 3; + break; +#if SPLASH_CMYK + case splashModeCMYK8: + ok = srcMode == splashModeCMYK8 || srcMode == splashModeACMYK8; + srcAlpha = srcMode == splashModeACMYK8; + nComps = srcAlpha ? 5 : 4; + break; +#endif + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeACMYK8: +#endif + //~ not implemented yet + ok = gFalse; + nComps = 4; + break; + } + if (!ok) { + return splashErrModeMismatch; + } + + // check for singular matrix + if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) { + return splashErrSingularMatrix; + } + + // compute scale, shear, rotation, translation parameters + rot = splashAbs(mat[1]) > splashAbs(mat[0]); + if (rot) { + xScale = -mat[1]; + yScale = mat[2] - (mat[0] * mat[3]) / mat[1]; + xShear = -mat[3] / yScale; + yShear = -mat[0] / mat[1]; + } else { + xScale = mat[0]; + yScale = mat[3] - (mat[1] * mat[2]) / mat[0]; + xShear = mat[2] / yScale; + yShear = mat[1] / mat[0]; + } + // the +/-0.01 in these computations is to avoid floating point + // precision problems which can lead to gaps between image stripes + // (it can cause image stripes to overlap, but that's a much less + // visible problem) + if (xScale >= 0) { + tx = splashRound(mat[4] - 0.01); + tx2 = splashRound(mat[4] + xScale + 0.01) - 1; + } else { + tx = splashRound(mat[4] + 0.01) - 1; + tx2 = splashRound(mat[4] + xScale - 0.01); + } + scaledWidth = abs(tx2 - tx) + 1; + if (scaledWidth == 0) { + // technically, this should draw nothing, but it generally seems + // better to draw a one-pixel-wide stripe rather than throwing it + // away + scaledWidth = 1; + } + if (yScale >= 0) { + ty = splashRound(mat[5] - 0.01); + ty2 = splashRound(mat[5] + yScale + 0.01) - 1; + } else { + ty = splashRound(mat[5] + 0.01) - 1; + ty2 = splashRound(mat[5] + yScale - 0.01); + } + scaledHeight = abs(ty2 - ty) + 1; + if (scaledHeight == 0) { + // technically, this should draw nothing, but it generally seems + // better to draw a one-pixel-wide stripe rather than throwing it + // away + scaledHeight = 1; + } + xSign = (xScale < 0) ? -1 : 1; + ySign = (yScale < 0) ? -1 : 1; + yShear1 = (SplashCoord)xSign * yShear; + + // clipping + ulx1 = 0; + uly1 = 0; + urx1 = xSign * (scaledWidth - 1); + ury1 = (int)(yShear * urx1); + llx1 = splashRound(xShear * ySign * (scaledHeight - 1)); + lly1 = ySign * (scaledHeight - 1) + (int)(yShear * llx1); + lrx1 = xSign * (scaledWidth - 1) + + splashRound(xShear * ySign * (scaledHeight - 1)); + lry1 = ySign * (scaledHeight - 1) + (int)(yShear * lrx1); + if (rot) { + ulx = tx + uly1; uly = ty - ulx1; + urx = tx + ury1; ury = ty - urx1; + llx = tx + lly1; lly = ty - llx1; + lrx = tx + lry1; lry = ty - lrx1; + } else { + ulx = tx + ulx1; uly = ty + uly1; + urx = tx + urx1; ury = ty + ury1; + llx = tx + llx1; lly = ty + lly1; + lrx = tx + lrx1; lry = ty + lry1; + } + xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx + : (llx < lrx) ? llx : lrx + : (urx < llx) ? (urx < lrx) ? urx : lrx + : (llx < lrx) ? llx : lrx; + xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx + : (llx > lrx) ? llx : lrx + : (urx > llx) ? (urx > lrx) ? urx : lrx + : (llx > lrx) ? llx : lrx; + yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry + : (lly < lry) ? lly : lry + : (ury < lly) ? (ury < lry) ? ury : lry + : (lly < lry) ? lly : lry; + yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry + : (lly > lry) ? lly : lry + : (ury > lly) ? (ury > lry) ? ury : lry + : (lly > lry) ? lly : lry; + clipRes = state->clip->testRect(xMin, yMin, xMax, yMax); + opClipRes = clipRes; + if (clipRes == splashClipAllOutside) { + return splashOk; + } + + // compute Bresenham parameters for x and y scaling + yp = h / scaledHeight; + yq = h % scaledHeight; + xp = w / scaledWidth; + xq = w % scaledWidth; + + // allocate pixel buffer + pixBuf = (SplashColorPtr)gmalloc((yp + 1) * w * nComps); + + pixAcc0 = pixAcc1 = pixAcc2 = 0; // make gcc happy +#if SPLASH_CMYK + pixAcc3 = 0; // make gcc happy +#endif + + if (srcAlpha) { + + // init y scale Bresenham + yt = 0; + lastYStep = 1; + + for (y = 0; y < scaledHeight; ++y) { + + // y scale Bresenham + yStep = yp; + yt += yq; + if (yt >= scaledHeight) { + yt -= scaledHeight; + ++yStep; + } + + // read row(s) from image + n = (yp > 0) ? yStep : lastYStep; + if (n > 0) { + p = pixBuf; + for (i = 0; i < n; ++i) { + (*src)(srcData, p); + p += w * nComps; + } + } + lastYStep = yStep; + + // loop-invariant constants + k1 = splashRound(xShear * ySign * y); + + // clipping test + if (clipRes != splashClipAllInside && + !rot && + (int)(yShear * k1) == + (int)(yShear * (xSign * (scaledWidth - 1) + k1))) { + if (xSign > 0) { + spanXMin = tx + k1; + spanXMax = spanXMin + (scaledWidth - 1); + } else { + spanXMax = tx + k1; + spanXMin = spanXMax - (scaledWidth - 1); + } + spanY = ty + ySign * y + (int)(yShear * k1); + clipRes2 = state->clip->testSpan(spanXMin, spanXMax, spanY); + if (clipRes2 == splashClipAllOutside) { + continue; + } + } else { + clipRes2 = clipRes; + } + + // init x scale Bresenham + xt = 0; + xSrc = 0; + + // x shear + x1 = k1; + + // y shear + y1 = (SplashCoord)ySign * y + yShear * x1; + // this is a kludge: if yShear1 is negative, then (int)y1 would + // change immediately after the first pixel, which is not what + // we want + if (yShear1 < 0) { + y1 += 0.999; + } + + // loop-invariant constants + n = yStep > 0 ? yStep : 1; + + for (x = 0; x < scaledWidth; ++x) { + + // x scale Bresenham + xStep = xp; + xt += xq; + if (xt >= scaledWidth) { + xt -= scaledWidth; + ++xStep; + } + + // rotation + if (rot) { + x2 = (int)y1; + y2 = -x1; + } else { + x2 = x1; + y2 = (int)y1; + } + + // compute the filtered pixel at (x,y) after the x and y scaling + // operations + m = xStep > 0 ? xStep : 1; + alphaAcc = 0; + switch (srcMode) { + case splashModeAMono8: + p = pixBuf + xSrc * 2; + pixAcc0 = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + alphaAcc += *p++; + pixAcc0 += *p++; + } + p += 2 * (w - m); + } + break; + case splashModeARGB8: + p = pixBuf + xSrc * 4; + pixAcc0 = pixAcc1 = pixAcc2 = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + alphaAcc += *p++; + pixAcc0 += *p++; + pixAcc1 += *p++; + pixAcc2 += *p++; + } + p += 4 * (w - m); + } + break; + case splashModeBGRA8: + p = pixBuf + xSrc * 4; + pixAcc0 = pixAcc1 = pixAcc2 = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + pixAcc0 += *p++; + pixAcc1 += *p++; + pixAcc2 += *p++; + alphaAcc += *p++; + } + p += 4 * (w - m); + } + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = pixBuf + xSrc * 5; + pixAcc0 = pixAcc1 = pixAcc2 = pixAcc3 = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + alphaAcc += *p++; + pixAcc0 += *p++; + pixAcc1 += *p++; + pixAcc2 += *p++; + pixAcc3 += *p++; + } + p += 5 * (w - m); + } + break; +#endif + default: // make gcc happy + break; + } + pixMul = (SplashCoord)1 / (SplashCoord)(n * m); + alphaMul = pixMul * (1.0 / 256.0); + alpha = (SplashCoord)alphaAcc * alphaMul; + + if (alpha > 0) { + // mono8 -> mono1 conversion, with halftoning + if (halftone) { + pix[0] = state->screen->test(tx + x2, ty + y2, + (SplashCoord)pixAcc0 * pixMul * (1.0 / 256.0)); + + // no conversion, no halftoning + } else { + switch (bitmap->mode) { +#if SPLASH_CMYK + case splashModeCMYK8: + pix[3] = (int)((SplashCoord)pixAcc3 * pixMul); + // fall through +#endif + case splashModeRGB8: + case splashModeBGR8: + case splashModeRGB8Qt: + pix[2] = (int)((SplashCoord)pixAcc2 * pixMul); + pix[1] = (int)((SplashCoord)pixAcc1 * pixMul); + // fall through + case splashModeMono1: + case splashModeMono8: + pix[0] = (int)((SplashCoord)pixAcc0 * pixMul); + break; + default: // make gcc happy + break; + } + } + + // set pixel + drawPixel(tx + x2, ty + y2, pix, alpha * state->fillAlpha, + clipRes2 == splashClipAllInside); + } + + // x scale Bresenham + xSrc += xStep; + + // x shear + x1 += xSign; + + // y shear + y1 += yShear1; + } + } + + } else { + + // init y scale Bresenham + yt = 0; + lastYStep = 1; + + for (y = 0; y < scaledHeight; ++y) { + + // y scale Bresenham + yStep = yp; + yt += yq; + if (yt >= scaledHeight) { + yt -= scaledHeight; + ++yStep; + } + + // read row(s) from image + n = (yp > 0) ? yStep : lastYStep; + if (n > 0) { + p = pixBuf; + for (i = 0; i < n; ++i) { + (*src)(srcData, p); + p += w * nComps; + } + } + lastYStep = yStep; + + // loop-invariant constants + k1 = splashRound(xShear * ySign * y); + + // clipping test + if (clipRes != splashClipAllInside && + !rot && + (int)(yShear * k1) == + (int)(yShear * (xSign * (scaledWidth - 1) + k1))) { + if (xSign > 0) { + spanXMin = tx + k1; + spanXMax = spanXMin + (scaledWidth - 1); + } else { + spanXMax = tx + k1; + spanXMin = spanXMax - (scaledWidth - 1); + } + spanY = ty + ySign * y + (int)(yShear * k1); + clipRes2 = state->clip->testSpan(spanXMin, spanXMax, spanY); + if (clipRes2 == splashClipAllOutside) { + continue; + } + } else { + clipRes2 = clipRes; + } + + // init x scale Bresenham + xt = 0; + xSrc = 0; + + // x shear + x1 = k1; + + // y shear + y1 = (SplashCoord)ySign * y + yShear * x1; + // this is a kludge: if yShear1 is negative, then (int)y1 would + // change immediately after the first pixel, which is not what + // we want + if (yShear1 < 0) { + y1 += 0.999; + } + + // loop-invariant constants + n = yStep > 0 ? yStep : 1; + + for (x = 0; x < scaledWidth; ++x) { + + // x scale Bresenham + xStep = xp; + xt += xq; + if (xt >= scaledWidth) { + xt -= scaledWidth; + ++xStep; + } + + // rotation + if (rot) { + x2 = (int)y1; + y2 = -x1; + } else { + x2 = x1; + y2 = (int)y1; + } + + // compute the filtered pixel at (x,y) after the x and y scaling + // operations + m = xStep > 0 ? xStep : 1; + switch (srcMode) { + case splashModeMono1: + case splashModeMono8: + p = pixBuf + xSrc; + pixAcc0 = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + pixAcc0 += *p++; + } + p += w - m; + } + break; + case splashModeRGB8: + case splashModeBGR8: + case splashModeRGB8Qt: + p = pixBuf + xSrc * 3; + pixAcc0 = pixAcc1 = pixAcc2 = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + pixAcc0 += *p++; + pixAcc1 += *p++; + pixAcc2 += *p++; + } + p += 3 * (w - m); + } + break; +#if SPLASH_CMYK + case splashModeCMYK8: + p = pixBuf + xSrc * 4; + pixAcc0 = pixAcc1 = pixAcc2 = pixAcc3 = 0; + for (i = 0; i < n; ++i) { + for (j = 0; j < m; ++j) { + pixAcc0 += *p++; + pixAcc1 += *p++; + pixAcc2 += *p++; + pixAcc3 += *p++; + } + p += 4 * (w - m); + } + break; +#endif + default: // make gcc happy + break; + } + pixMul = (SplashCoord)1 / (SplashCoord)(n * m); + + // mono8 -> mono1 conversion, with halftoning + if (halftone) { + pix[0] = state->screen->test(tx + x2, ty + y2, + (SplashCoord)pixAcc0 * pixMul * (1.0 / 256.0)); + + // no conversion, no halftoning + } else { + switch (bitmap->mode) { +#if SPLASH_CMYK + case splashModeCMYK8: + pix[3] = (int)((SplashCoord)pixAcc3 * pixMul); + // fall through +#endif + case splashModeRGB8: + case splashModeRGB8Qt: + case splashModeBGR8: + pix[2] = (int)((SplashCoord)pixAcc2 * pixMul); + pix[1] = (int)((SplashCoord)pixAcc1 * pixMul); + // fall through + case splashModeMono1: + case splashModeMono8: + pix[0] = (int)((SplashCoord)pixAcc0 * pixMul); + break; + default: // make gcc happy + break; + } + } + + // set pixel + drawPixel(tx + x2, ty + y2, pix, state->fillAlpha, + clipRes2 == splashClipAllInside); + + // x scale Bresenham + xSrc += xStep; + + // x shear + x1 += xSign; + + // y shear + y1 += yShear1; + } + } + + } + + gfree(pixBuf); + + return splashOk; +} + +void Splash::dumpPath(SplashPath *path) { + int i; + + for (i = 0; i < path->length; ++i) { + printf(" %3d: x=%8.2f y=%8.2f%s%s%s%s%s\n", + i, (double)path->pts[i].x, (double)path->pts[i].y, + (path->flags[i] & splashPathFirst) ? " first" : "", + (path->flags[i] & splashPathLast) ? " last" : "", + (path->flags[i] & splashPathClosed) ? " closed" : "", + (path->flags[i] & splashPathCurve) ? " curve" : "", + (path->flags[i] & splashPathArcCW) ? " arcCW" : ""); + } +} + +void Splash::dumpXPath(SplashXPath *path) { + int i; + + for (i = 0; i < path->length; ++i) { + printf(" %4d: x0=%8.2f y0=%8.2f x1=%8.2f y1=%8.2f %s%s%s%s%s%s%s\n", + i, (double)path->segs[i].x0, (double)path->segs[i].y0, + (double)path->segs[i].x1, (double)path->segs[i].y1, + (path->segs[i].flags & splashXPathFirst) ? "F" : " ", + (path->segs[i].flags & splashXPathLast) ? "L" : " ", + (path->segs[i].flags & splashXPathEnd0) ? "0" : " ", + (path->segs[i].flags & splashXPathEnd1) ? "1" : " ", + (path->segs[i].flags & splashXPathHoriz) ? "H" : " ", + (path->segs[i].flags & splashXPathVert) ? "V" : " ", + (path->segs[i].flags & splashXPathFlip) ? "P" : " "); + } +} diff --git a/rosapps/smartpdf/poppler/splash/Splash.h b/rosapps/smartpdf/poppler/splash/Splash.h new file mode 100644 index 00000000000..783da8fcfdf --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/Splash.h @@ -0,0 +1,202 @@ +//======================================================================== +// +// Splash.h +// +//======================================================================== + +#ifndef SPLASH_H +#define SPLASH_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" +#include "SplashClip.h" + +class SplashBitmap; +struct SplashGlyphBitmap; +class SplashState; +class SplashPattern; +class SplashScreen; +class SplashPath; +class SplashXPath; +class SplashFont; + +//------------------------------------------------------------------------ + +// Retrieves the next line of pixels in an image mask. Normally, +// fills in * and returns true. If the image stream is +// exhausted, returns false. +typedef GBool (*SplashImageMaskSource)(void *data, SplashColorPtr pixel); + +// Retrieves the next line of pixels in an image. Normally, fills in +// * and returns true. If the image stream is exhausted, +// returns false. +typedef GBool (*SplashImageSource)(void *data, SplashColorPtr line); + +//------------------------------------------------------------------------ +// Splash +//------------------------------------------------------------------------ + +class Splash { +public: + + // Create a new rasterizer object. + Splash(SplashBitmap *bitmapA); + + ~Splash(); + + //----- state read + + SplashPattern *getStrokePattern(); + SplashPattern *getFillPattern(); + SplashScreen *getScreen(); + SplashBlendFunc getBlendFunc(); + SplashCoord getStrokeAlpha(); + SplashCoord getFillAlpha(); + SplashCoord getLineWidth(); + int getLineCap(); + int getLineJoin(); + SplashCoord getMiterLimit(); + SplashCoord getFlatness(); + SplashCoord *getLineDash(); + int getLineDashLength(); + SplashCoord getLineDashPhase(); + SplashClip *getClip(); + + //----- state write + + void setStrokePattern(SplashPattern *strokeColor); + void setFillPattern(SplashPattern *fillColor); + void setScreen(SplashScreen *screen); + void setBlendFunc(SplashBlendFunc func); + void setStrokeAlpha(SplashCoord alpha); + void setFillAlpha(SplashCoord alpha); + void setLineWidth(SplashCoord lineWidth); + void setLineCap(int lineCap); + void setLineJoin(int lineJoin); + void setMiterLimit(SplashCoord miterLimit); + void setFlatness(SplashCoord flatness); + // the array will be copied + void setLineDash(SplashCoord *lineDash, int lineDashLength, + SplashCoord lineDashPhase); + void clipResetToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1); + SplashError clipToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1); + SplashError clipToPath(SplashPath *path, GBool eo); + + //----- state save/restore + + void saveState(); + SplashError restoreState(); + + //----- soft mask + + void setSoftMask(SplashBitmap *softMaskA); + + //----- drawing operations + + // Fill the bitmap with . This is not subject to clipping. + void clear(SplashColorPtr color); + + // Stroke a path using the current stroke pattern. + SplashError stroke(SplashPath *path); + + // Fill a path using the current fill pattern. + SplashError fill(SplashPath *path, GBool eo); + + // Fill a path, XORing with the current fill pattern. + SplashError xorFill(SplashPath *path, GBool eo); + + // Draw a character, using the current fill pattern. + SplashError fillChar(SplashCoord x, SplashCoord y, int c, SplashFont *font); + + // Draw a glyph, using the current fill pattern. This function does + // not free any data, i.e., it ignores glyph->freeData. + SplashError fillGlyph(SplashCoord x, SplashCoord y, + SplashGlyphBitmap *glyph); + + // Draws an image mask using the fill color. This will read + // lines of pixels from , starting with the top line. "1" + // pixels will be drawn with the current fill color; "0" pixels are + // transparent. The matrix: + // [ mat[0] mat[1] 0 ] + // [ mat[2] mat[3] 0 ] + // [ mat[4] mat[5] 1 ] + // maps a unit square to the desired destination for the image, in + // PostScript style: + // [x' y' 1] = [x y 1] * mat + // Note that the Splash y axis points downward, and the image source + // is assumed to produce pixels in raster order, starting from the + // top line. + SplashError fillImageMask(SplashImageMaskSource src, void *srcData, + int w, int h, SplashCoord *mat); + + // Draw an image. This will read lines of pixels from + // , starting with the top line. These pixels are assumed to + // be in the source mode, . The following combinations of + // source and target modes are supported: + // source target + // ------ ------ + // Mono1 Mono1 + // Mono8 Mono1 -- with dithering + // Mono8 Mono8 + // RGB8 RGB8 + // BGR8 BGR8 + // ARGB8 RGB8 -- with source alpha (masking) + // BGRA8 BGR8 -- with source alpha (masking) + // The matrix behaves as for fillImageMask. + SplashError drawImage(SplashImageSource src, void *srcData, + SplashColorMode srcMode, + int w, int h, SplashCoord *mat); + + //----- misc + + // Return the associated bitmap. + SplashBitmap *getBitmap() { return bitmap; } + + // Get a bounding box which includes all modifications since the + // last call to clearModRegion. + void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax) + { *xMin = modXMin; *yMin = modYMin; *xMax = modXMax; *yMax = modYMax; } + + // Clear the modified region bounding box. + void clearModRegion(); + + // Get clipping status for the last drawing operation subject to + // clipping. + SplashClipResult getClipRes() { return opClipRes; } + + // Toggle debug mode on or off. + void setDebugMode(GBool debugModeA) { debugMode = debugModeA; } + +private: + + void updateModX(int x); + void updateModY(int y); + void strokeNarrow(SplashXPath *xPath); + void strokeWide(SplashXPath *xPath); + SplashXPath *makeDashedPath(SplashXPath *xPath); + SplashError fillWithPattern(SplashPath *path, GBool eo, + SplashPattern *pattern, SplashCoord alpha); + void drawPixel(int x, int y, SplashColorPtr color, + SplashCoord alpha, GBool noClip); + void drawPixel(int x, int y, SplashPattern *pattern, + SplashCoord alpha, GBool noClip); + void drawSpan(int x0, int x1, int y, SplashPattern *pattern, + SplashCoord alpha, GBool noClip); + void xorSpan(int x0, int x1, int y, SplashPattern *pattern, GBool noClip); + void dumpPath(SplashPath *path); + void dumpXPath(SplashXPath *path); + + SplashBitmap *bitmap; + SplashState *state; + SplashBitmap *softMask; + int modXMin, modYMin, modXMax, modYMax; + SplashClipResult opClipRes; + GBool debugMode; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashBitmap.cc b/rosapps/smartpdf/poppler/splash/SplashBitmap.cc new file mode 100644 index 00000000000..1a44fea8678 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashBitmap.cc @@ -0,0 +1,268 @@ +//======================================================================== +// +// SplashBitmap.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "SplashErrorCodes.h" +#include "SplashBitmap.h" + +//------------------------------------------------------------------------ +// SplashBitmap +//------------------------------------------------------------------------ + +SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad, + SplashColorMode modeA, GBool topDown) { + width = widthA; + height = heightA; + mode = modeA; + switch (mode) { + case splashModeMono1: + rowSize = (width + 7) >> 3; + break; + case splashModeMono8: + rowSize = width; + break; + case splashModeAMono8: + rowSize = width * 2; + break; + case splashModeRGB8: + case splashModeBGR8: + rowSize = width * 3; + break; + case splashModeRGB8Qt: + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + rowSize = width * 4; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + rowSize = width * 5; + break; +#endif + } + rowSize += rowPad - 1; + rowSize -= rowSize % rowPad; + data = NULL; + data = (SplashColorPtr)gmalloc(rowSize * height); + if (!data) + return; + if (!topDown) { + data += (height - 1) * rowSize; + rowSize = -rowSize; + } +} + + +SplashBitmap::~SplashBitmap() { + if (rowSize < 0) { + gfree(data + (height - 1) * rowSize); + } else { + gfree(data); + } +} + +SplashError SplashBitmap::writePNMFile(char *fileName) { + FILE *f; + SplashColorPtr row, p; + int x, y; + + if (!(f = fopen(fileName, "wb"))) { + return splashErrOpenFile; + } + + switch (mode) { + + case splashModeMono1: + fprintf(f, "P4\n%d %d\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; x += 8) { + fputc(*p ^ 0xff, f); + ++p; + } + row += rowSize; + } + break; + + case splashModeMono8: + fprintf(f, "P5\n%d %d\n255\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; ++x) { + fputc(*p, f); + ++p; + } + row += rowSize; + } + break; + + case splashModeAMono8: + fprintf(f, "P5\n%d %d\n255\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; ++x) { + fputc(splashAMono8M(p), f); + p += 2; + } + row += rowSize; + } + break; + + case splashModeRGB8: + fprintf(f, "P6\n%d %d\n255\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; ++x) { + fputc(splashRGB8R(p), f); + fputc(splashRGB8G(p), f); + fputc(splashRGB8B(p), f); + p += 3; + } + row += rowSize; + } + break; + + case splashModeBGR8: + fprintf(f, "P6\n%d %d\n255\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; ++x) { + fputc(splashBGR8R(p), f); + fputc(splashBGR8G(p), f); + fputc(splashBGR8B(p), f); + p += 3; + } + row += rowSize; + } + break; + + case splashModeRGB8Qt: + fprintf(f, "P6\n%d %d\n255\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; ++x) { + fputc(splashRGB8R(p), f); + fputc(splashRGB8G(p), f); + fputc(splashRGB8B(p), f); + p += 4; + } + row += rowSize; + } + break; + + case splashModeARGB8: + fprintf(f, "P6\n%d %d\n255\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; ++x) { + fputc(splashARGB8R(p), f); + fputc(splashARGB8G(p), f); + fputc(splashARGB8B(p), f); + p += 4; + } + row += rowSize; + } + break; + + case splashModeBGRA8: + fprintf(f, "P6\n%d %d\n255\n", width, height); + row = data; + for (y = 0; y < height; ++y) { + p = row; + for (x = 0; x < width; ++x) { + fputc(splashBGRA8R(p), f); + fputc(splashBGRA8G(p), f); + fputc(splashBGRA8B(p), f); + p += 4; + } + row += rowSize; + } + break; + +#if SPLASH_CMYK + case splashModeCMYK8: + case splashModeACMYK8: + // PNM doesn't support CMYK + break; +#endif + } + + fclose(f); + return splashOk; +} + +void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) { + SplashColorPtr p; + + if (y < 0 || y >= height || x < 0 || x >= width) { + return; + } + switch (mode) { + case splashModeMono1: + p = &data[y * rowSize + (x >> 3)]; + pixel[0] = (p[0] >> (7 - (x & 7))) & 1; + break; + case splashModeMono8: + p = &data[y * rowSize + x]; + pixel[0] = p[0]; + break; + case splashModeAMono8: + p = &data[y * rowSize + 2 * x]; + pixel[0] = p[0]; + pixel[1] = p[1]; + break; + case splashModeRGB8: + case splashModeBGR8: + p = &data[y * rowSize + 3 * x]; + pixel[0] = p[0]; + pixel[1] = p[1]; + pixel[2] = p[2]; + break; + case splashModeRGB8Qt: + p = &data[y * rowSize + 4 * x]; + pixel[0] = p[2]; + pixel[1] = p[1]; + pixel[2] = p[0]; + break; + case splashModeARGB8: + case splashModeBGRA8: +#if SPLASH_CMYK + case splashModeCMYK8: +#endif + p = &data[y * rowSize + 4 * x]; + pixel[0] = p[0]; + pixel[1] = p[1]; + pixel[2] = p[2]; + pixel[3] = p[3]; + break; +#if SPLASH_CMYK + case splashModeACMYK8: + p = &data[y * rowSize + 5 * x]; + pixel[0] = p[0]; + pixel[1] = p[1]; + pixel[2] = p[2]; + pixel[3] = p[3]; + pixel[4] = p[4]; + break; +#endif + } +} diff --git a/rosapps/smartpdf/poppler/splash/SplashBitmap.h b/rosapps/smartpdf/poppler/splash/SplashBitmap.h new file mode 100644 index 00000000000..83f1539f94a --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashBitmap.h @@ -0,0 +1,53 @@ +//======================================================================== +// +// SplashBitmap.h +// +//======================================================================== + +#ifndef SPLASHBITMAP_H +#define SPLASHBITMAP_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +//------------------------------------------------------------------------ +// SplashBitmap +//------------------------------------------------------------------------ + +class SplashBitmap { +public: + + // Create a new bitmap. It will have x pixels in + // color mode . Rows will be padded out to a multiple of + // bytes. If is false, the bitmap will be stored + // upside-down, i.e., with the last row first in memory. + SplashBitmap(int widthA, int heightA, int rowPad, + SplashColorMode modeA, GBool topDown = gTrue); + + ~SplashBitmap(); + + int getWidth() { return width; } + int getHeight() { return height; } + int getRowSize() { return rowSize; } + SplashColorMode getMode() { return mode; } + SplashColorPtr getDataPtr() { return data; } + + SplashError writePNMFile(char *fileName); + + void getPixel(int x, int y, SplashColorPtr pixel); + +private: + + int width, height; // size of bitmap + int rowSize; // size of one row of data, in bytes + // - negative for bottom-up bitmaps + SplashColorMode mode; // color mode + SplashColorPtr data; // pointer to row zero of the bitmap data + + friend class Splash; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashClip.cc b/rosapps/smartpdf/poppler/splash/SplashClip.cc new file mode 100644 index 00000000000..724c65c3846 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashClip.cc @@ -0,0 +1,270 @@ +//======================================================================== +// +// SplashClip.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "SplashErrorCodes.h" +#include "SplashMath.h" +#include "SplashPath.h" +#include "SplashXPath.h" +#include "SplashXPathScanner.h" +#include "SplashClip.h" + +//------------------------------------------------------------------------ +// SplashClip.flags +//------------------------------------------------------------------------ + +#define splashClipEO 0x01 // use even-odd rule + +//------------------------------------------------------------------------ +// SplashClip +//------------------------------------------------------------------------ + +SplashClip::SplashClip(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1) { + if (x0 < x1) { + xMin = splashFloor(x0); + xMax = splashFloor(x1); + } else { + xMin = splashFloor(x1); + xMax = splashFloor(x0); + } + if (y0 < y1) { + yMin = splashFloor(y0); + yMax = splashFloor(y1); + } else { + yMin = splashFloor(y1); + yMax = splashFloor(y0); + } + paths = NULL; + flags = NULL; + scanners = NULL; + length = size = 0; +} + +SplashClip::SplashClip(SplashClip *clip) { + int i; + + xMin = clip->xMin; + yMin = clip->yMin; + xMax = clip->xMax; + yMax = clip->yMax; + length = clip->length; + size = clip->size; + paths = (SplashXPath **)gmallocn(size, sizeof(SplashXPath *)); + flags = (Guchar *)gmallocn(size, sizeof(Guchar)); + scanners = (SplashXPathScanner **) + gmallocn(size, sizeof(SplashXPathScanner *)); + for (i = 0; i < length; ++i) { + paths[i] = clip->paths[i]->copy(); + flags[i] = clip->flags[i]; + scanners[i] = new SplashXPathScanner(paths[i], flags[i] & splashClipEO); + } +} + +SplashClip::~SplashClip() { + int i; + + for (i = 0; i < length; ++i) { + delete paths[i]; + delete scanners[i]; + } + gfree(paths); + gfree(flags); + gfree(scanners); +} + +void SplashClip::grow(int nPaths) { + if (length + nPaths > size) { + if (size == 0) { + size = 32; + } + while (size < length + nPaths) { + size *= 2; + } + paths = (SplashXPath **)greallocn(paths, size, sizeof(SplashXPath *)); + flags = (Guchar *)greallocn(flags, size, sizeof(Guchar)); + scanners = (SplashXPathScanner **) + greallocn(scanners, size, sizeof(SplashXPathScanner *)); + } +} + +void SplashClip::resetToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1) { + int i; + + for (i = 0; i < length; ++i) { + delete paths[i]; + delete scanners[i]; + } + gfree(paths); + gfree(flags); + gfree(scanners); + paths = NULL; + flags = NULL; + scanners = NULL; + length = size = 0; + + if (x0 < x1) { + xMin = splashFloor(x0); + xMax = splashFloor(x1); + } else { + xMin = splashFloor(x1); + xMax = splashFloor(x0); + } + if (y0 < y1) { + yMin = splashFloor(y0); + yMax = splashFloor(y1); + } else { + yMin = splashFloor(y1); + yMax = splashFloor(y0); + } +} + +SplashError SplashClip::clipToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1) { + int x0I, y0I, x1I, y1I; + + if (x0 < x1) { + x0I = splashFloor(x0); + x1I = splashFloor(x1); + } else { + x0I = splashFloor(x1); + x1I = splashFloor(x0); + } + if (x0I > xMin) { + xMin = x0I; + } + if (x1I < xMax) { + xMax = x1I; + } + if (y0 < y1) { + y0I = splashFloor(y0); + y1I = splashFloor(y1); + } else { + y0I = splashFloor(y1); + y1I = splashFloor(y0); + } + if (y0I > yMin) { + yMin = y0I; + } + if (y1I < yMax) { + yMax = y1I; + } + return splashOk; +} + +SplashError SplashClip::clipToPath(SplashPath *path, SplashCoord flatness, + GBool eo) { + SplashXPath *xPath; + + xPath = new SplashXPath(path, flatness, gTrue); + + // check for an empty path + if (xPath->length == 0) { + xMax = xMin - 1; + yMax = yMin - 1; + delete xPath; + + // check for a rectangle + } else if (xPath->length == 4 && + ((xPath->segs[0].x0 == xPath->segs[0].x1 && + xPath->segs[0].x0 == xPath->segs[1].x0 && + xPath->segs[0].x0 == xPath->segs[3].x1 && + xPath->segs[2].x0 == xPath->segs[2].x1 && + xPath->segs[2].x0 == xPath->segs[1].x1 && + xPath->segs[2].x0 == xPath->segs[3].x0 && + xPath->segs[1].y0 == xPath->segs[1].y1 && + xPath->segs[1].y0 == xPath->segs[0].y1 && + xPath->segs[1].y0 == xPath->segs[2].y0 && + xPath->segs[3].y0 == xPath->segs[3].y1 && + xPath->segs[3].y0 == xPath->segs[0].y0 && + xPath->segs[3].y0 == xPath->segs[2].y1) || + (xPath->segs[0].y0 == xPath->segs[0].y1 && + xPath->segs[0].y0 == xPath->segs[1].y0 && + xPath->segs[0].y0 == xPath->segs[3].y1 && + xPath->segs[2].y0 == xPath->segs[2].y1 && + xPath->segs[2].y0 == xPath->segs[1].y1 && + xPath->segs[2].y0 == xPath->segs[3].y0 && + xPath->segs[1].x0 == xPath->segs[1].x1 && + xPath->segs[1].x0 == xPath->segs[0].x1 && + xPath->segs[1].x0 == xPath->segs[2].x0 && + xPath->segs[3].x0 == xPath->segs[3].x1 && + xPath->segs[3].x0 == xPath->segs[0].x0 && + xPath->segs[3].x0 == xPath->segs[2].x1))) { + clipToRect(xPath->segs[0].x0, xPath->segs[0].y0, + xPath->segs[2].x0, xPath->segs[2].y0); + delete xPath; + + } else { + grow(1); + xPath->sort(); + paths[length] = xPath; + flags[length] = eo ? splashClipEO : 0; + scanners[length] = new SplashXPathScanner(xPath, eo); + ++length; + } + + return splashOk; +} + +GBool SplashClip::test(int x, int y) { + int i; + + // check the rectangle + if (x < xMin || x > xMax || y < yMin || y > yMax) { + return gFalse; + } + + // check the paths + for (i = 0; i < length; ++i) { + if (!scanners[i]->test(x, y)) { + return gFalse; + } + } + + return gTrue; +} + +SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin, + int rectXMax, int rectYMax) { + if (rectXMax < xMin || rectXMin > xMax || + rectYMax < yMin || rectYMin > yMax) { + return splashClipAllOutside; + } + if (rectXMin >= xMin && rectXMax <= xMax && + rectYMin >= yMin && rectYMax <= yMax && + length == 0) { + return splashClipAllInside; + } + return splashClipPartial; +} + +SplashClipResult SplashClip::testSpan(int spanXMin, int spanXMax, int spanY) { + int i; + + if (spanXMax < xMin || spanXMin > xMax || + spanY < yMin || spanY > yMax) { + return splashClipAllOutside; + } + if (!(spanXMin >= xMin && spanXMax <= xMax && + spanY >= yMin && spanY <= yMax)) { + return splashClipPartial; + } + for (i = 0; i < length; ++i) { + if (!scanners[i]->testSpan(xMin, xMax, spanY)) { + return splashClipPartial; + } + } + return splashClipAllInside; +} diff --git a/rosapps/smartpdf/poppler/splash/SplashClip.h b/rosapps/smartpdf/poppler/splash/SplashClip.h new file mode 100644 index 00000000000..d27d7ae3592 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashClip.h @@ -0,0 +1,95 @@ +//======================================================================== +// +// SplashClip.h +// +//======================================================================== + +#ifndef SPLASHCLIP_H +#define SPLASHCLIP_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +class SplashPath; +class SplashXPath; +class SplashXPathScanner; + +//------------------------------------------------------------------------ + +enum SplashClipResult { + splashClipAllInside, + splashClipAllOutside, + splashClipPartial +}; + +//------------------------------------------------------------------------ +// SplashClip +//------------------------------------------------------------------------ + +class SplashClip { +public: + + // Create a clip, for the given rectangle. + SplashClip(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1); + + // Copy a clip. + SplashClip *copy() { return new SplashClip(this); } + + ~SplashClip(); + + // Reset the clip to a rectangle. + void resetToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1); + + // Intersect the clip with a rectangle. + SplashError clipToRect(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1); + + // Interesect the clip with . + SplashError clipToPath(SplashPath *path, SplashCoord flatness, + GBool eo); + + // Returns true if (,) is inside the clip. + GBool test(int x, int y); + + // Tests a rectangle against the clipping region. Returns one of: + // - splashClipAllInside if the entire rectangle is inside the + // clipping region, i.e., all pixels in the rectangle are + // visible + // - splashClipAllOutside if the entire rectangle is outside the + // clipping region, i.e., all the pixels in the rectangle are + // clipped + // - splashClipPartial if the rectangle is part inside and part + // outside the clipping region + SplashClipResult testRect(int rectXMin, int rectYMin, + int rectXMax, int rectYMax); + + // Similar to testRect, but tests a horizontal span. + SplashClipResult testSpan(int spanXMin, int spanXMax, int spanY); + + // Get the rectangle part of the clip region. + int getXMin() { return xMin; } + int getXMax() { return xMax; } + int getYMin() { return yMin; } + int getYMax() { return yMax; } + + // Get the number of arbitrary paths used by the clip region. + int getNumPaths() { return length; } + +private: + + SplashClip(SplashClip *clip); + void grow(int nPaths); + + int xMin, yMin, xMax, yMax; + SplashXPath **paths; + Guchar *flags; + SplashXPathScanner **scanners; + int length, size; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashErrorCodes.h b/rosapps/smartpdf/poppler/splash/SplashErrorCodes.h new file mode 100644 index 00000000000..09f2dabcdc7 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashErrorCodes.h @@ -0,0 +1,32 @@ +//======================================================================== +// +// SplashErrorCodes.h +// +//======================================================================== + +#ifndef SPLASHERRORCODES_H +#define SPLASHERRORCODES_H + +//------------------------------------------------------------------------ + +#define splashOk 0 // no error + +#define splashErrNoCurPt 1 // no current point + +#define splashErrEmptyPath 2 // zero points in path + +#define splashErrBogusPath 3 // only one point in subpath + +#define splashErrNoSave 4 // state stack is empty + +#define splashErrOpenFile 5 // couldn't open file + +#define splashErrNoGlyph 6 // couldn't get the requested glyph + +#define splashErrModeMismatch 7 // invalid combination of color modes + +#define splashErrSingularMatrix 8 // matrix is singular + +#define splashErrZeroImage 9 // image of 0x0 + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashFTFont.cc b/rosapps/smartpdf/poppler/splash/SplashFTFont.cc new file mode 100644 index 00000000000..8ffff8eba48 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFTFont.cc @@ -0,0 +1,353 @@ +//======================================================================== +// +// SplashFTFont.cc +// +//======================================================================== + +#include + +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#define MAKE_VERSION( a,b,c ) (((a) << 16) | ((b) << 8) | (c)) + +#define FREETYPE_VERSION \ + MAKE_VERSION(FREETYPE_MAJOR,FREETYPE_MINOR,FREETYPE_PATCH) + +#include +#include FT_OUTLINE_H +#include FT_SIZES_H +#include FT_GLYPH_H +#include "goo/gmem.h" +#include "SplashMath.h" +#include "SplashGlyphBitmap.h" +#include "SplashPath.h" +#include "SplashFTFontEngine.h" +#include "SplashFTFontFile.h" +#include "SplashFTFont.h" + +//------------------------------------------------------------------------ + +#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) ) +static int glyphPathMoveTo(const FT_Vector *pt, void *path); +static int glyphPathLineTo(const FT_Vector *pt, void *path); +static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, void *path); +static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, + const FT_Vector *pt, void *path); +#else +static int glyphPathMoveTo(FT_Vector *pt, void *path); +static int glyphPathLineTo(FT_Vector *pt, void *path); +static int glyphPathConicTo(FT_Vector *ctrl, FT_Vector *pt, void *path); +static int glyphPathCubicTo(FT_Vector *ctrl1, FT_Vector *ctrl2, + FT_Vector *pt, void *path); +#endif + +//------------------------------------------------------------------------ +// SplashFTFont +//------------------------------------------------------------------------ + +SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA): + SplashFont(fontFileA, matA, fontFileA->engine->aa) +{ + FT_Face face; + double size, div; + int x, y; + + face = fontFileA->face; + if (FT_New_Size(face, &sizeObj)) { + return; + } + face->size = sizeObj; + size = splashSqrt(mat[2]*mat[2] + mat[3]*mat[3]); + if (FT_Set_Pixel_Sizes(face, 0, (int)size)) { + return; + } + + div = face->bbox.xMax > 20000 ? 65536 : 1; + + // transform the four corners of the font bounding box -- the min + // and max values form the bounding box of the transformed font + x = (int)((mat[0] * face->bbox.xMin + mat[2] * face->bbox.yMin) / + (div * face->units_per_EM)); + xMin = xMax = x; + y = (int)((mat[1] * face->bbox.xMin + mat[3] * face->bbox.yMin) / + (div * face->units_per_EM)); + yMin = yMax = y; + x = (int)((mat[0] * face->bbox.xMin + mat[2] * face->bbox.yMax) / + (div * face->units_per_EM)); + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + y = (int)((mat[1] * face->bbox.xMin + mat[3] * face->bbox.yMax) / + (div * face->units_per_EM)); + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + x = (int)((mat[0] * face->bbox.xMax + mat[2] * face->bbox.yMin) / + (div * face->units_per_EM)); + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + y = (int)((mat[1] * face->bbox.xMax + mat[3] * face->bbox.yMin) / + (div * face->units_per_EM)); + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + x = (int)((mat[0] * face->bbox.xMax + mat[2] * face->bbox.yMax) / + (div * face->units_per_EM)); + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + y = (int)((mat[1] * face->bbox.xMax + mat[3] * face->bbox.yMax) / + (div * face->units_per_EM)); + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + // This is a kludge: some buggy PDF generators embed fonts with + // zero bounding boxes. + if (xMax == xMin) { + xMin = 0; + xMax = (int)size; + } + if (yMax == yMin) { + yMin = 0; + yMax = (int)((SplashCoord)1.2 * size); + } + + // compute the transform matrix +#if USE_FIXEDPOINT + matrix.xx = (FT_Fixed)((mat[0] / size).getRaw()); + matrix.yx = (FT_Fixed)((mat[1] / size).getRaw()); + matrix.xy = (FT_Fixed)((mat[2] / size).getRaw()); + matrix.yy = (FT_Fixed)((mat[3] / size).getRaw()); +#else + matrix.xx = (FT_Fixed)((mat[0] / size) * 65536); + matrix.yx = (FT_Fixed)((mat[1] / size) * 65536); + matrix.xy = (FT_Fixed)((mat[2] / size) * 65536); + matrix.yy = (FT_Fixed)((mat[3] / size) * 65536); +#endif +} + +SplashFTFont::~SplashFTFont() { +} + +GBool SplashFTFont::getGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap) { + return SplashFont::getGlyph(c, xFrac, 0, bitmap); +} + +GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap) { + SplashFTFontFile *ff; + FT_Vector offset; + FT_GlyphSlot slot; + FT_UInt gid; + int rowSize; + Guchar *p, *q; + int i; + + ff = (SplashFTFontFile *)fontFile; + + ff->face->size = sizeObj; + offset.x = (FT_Pos)(int)((SplashCoord)xFrac * splashFontFractionMul * 64); + offset.y = 0; + FT_Set_Transform(ff->face, &matrix, &offset); + slot = ff->face->glyph; + + if (ff->codeToGID && c < ff->codeToGIDLen) { + gid = (FT_UInt)ff->codeToGID[c]; + } else { + gid = (FT_UInt)c; + } + + // if we have the FT2 bytecode interpreter, autohinting won't be used +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + if (FT_Load_Glyph(ff->face, gid, + aa ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT)) { + return gFalse; + } +#else + // FT2's autohinting doesn't always work very well (especially with + // font subsets), so turn it off if anti-aliasing is enabled; if + // anti-aliasing is disabled, this seems to be a tossup - some fonts + // look better with hinting, some without, so leave hinting on + if (FT_Load_Glyph(ff->face, gid, + aa ? FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP + : FT_LOAD_DEFAULT)) { + return gFalse; + } +#endif + if (FT_Render_Glyph(slot, aa ? ft_render_mode_normal + : ft_render_mode_mono)) { + return gFalse; + } + + bitmap->x = -slot->bitmap_left; + bitmap->y = slot->bitmap_top; + bitmap->w = slot->bitmap.width; + bitmap->h = slot->bitmap.rows; + bitmap->aa = aa; + if (aa) { + rowSize = bitmap->w; + } else { + rowSize = (bitmap->w + 7) >> 3; + } + bitmap->data = (Guchar *)gmalloc(rowSize * bitmap->h); + bitmap->freeData = gTrue; + for (i = 0, p = bitmap->data, q = slot->bitmap.buffer; + i < bitmap->h; + ++i, p += rowSize, q += slot->bitmap.pitch) { + memcpy(p, q, rowSize); + } + + return gTrue; +} + +struct SplashFTFontPath { + SplashPath *path; + GBool needClose; +}; + +SplashPath *SplashFTFont::getGlyphPath(int c) { + static FT_Outline_Funcs outlineFuncs = { + &glyphPathMoveTo, + &glyphPathLineTo, + &glyphPathConicTo, + &glyphPathCubicTo, + 0, 0 + }; + SplashFTFontFile *ff; + SplashFTFontPath path; + FT_GlyphSlot slot; + FT_UInt gid; + FT_Glyph glyph; + + ff = (SplashFTFontFile *)fontFile; + ff->face->size = sizeObj; + FT_Set_Transform(ff->face, &matrix, NULL); + slot = ff->face->glyph; + if (ff->codeToGID && c < ff->codeToGIDLen) { + gid = ff->codeToGID[c]; + } else { + gid = (FT_UInt)c; + } + if (FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP)) { + return NULL; + } + if (FT_Get_Glyph(slot, &glyph)) { + return NULL; + } + path.path = new SplashPath(); + path.needClose = gFalse; + FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline, + &outlineFuncs, &path); + if (path.needClose) { + path.path->close(); + } + FT_Done_Glyph(glyph); + return path.path; +} + +#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) ) +static int glyphPathMoveTo(const FT_Vector *pt, void *path) +#else +static int glyphPathMoveTo(FT_Vector *pt, void *path) +#endif +{ + SplashFTFontPath *p = (SplashFTFontPath *)path; + + if (p->needClose) { + p->path->close(); + p->needClose = gFalse; + } + p->path->moveTo(pt->x / 64.0, -pt->y / 64.0); + return 0; +} + +#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) ) +static int glyphPathLineTo(const FT_Vector *pt, void *path) +#else +static int glyphPathLineTo(FT_Vector *pt, void *path) +#endif +{ + SplashFTFontPath *p = (SplashFTFontPath *)path; + + p->path->lineTo(pt->x / 64.0, -pt->y / 64.0); + p->needClose = gTrue; + return 0; +} + +#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) ) +static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, void *path) +#else +static int glyphPathConicTo(FT_Vector *ctrl, FT_Vector *pt, void *path) +#endif +{ + SplashFTFontPath *p = (SplashFTFontPath *)path; + SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xc, yc; + + if (!p->path->getCurPt(&x0, &y0)) { + return 0; + } + xc = ctrl->x / 64.0; + yc = -ctrl->y / 64.0; + x3 = pt->x / 64.0; + y3 = -pt->y / 64.0; + + // A second-order Bezier curve is defined by two endpoints, p0 and + // p3, and one control point, pc: + // + // p(t) = (1-t)^2*p0 + t*(1-t)*pc + t^2*p3 + // + // A third-order Bezier curve is defined by the same two endpoints, + // p0 and p3, and two control points, p1 and p2: + // + // p(t) = (1-t)^3*p0 + 3t*(1-t)^2*p1 + 3t^2*(1-t)*p2 + t^3*p3 + // + // Applying some algebra, we can convert a second-order curve to a + // third-order curve: + // + // p1 = (1/3) * (p0 + 2pc) + // p2 = (1/3) * (2pc + p3) + + x1 = (SplashCoord)(1.0 / 3.0) * (x0 + (SplashCoord)2 * xc); + y1 = (SplashCoord)(1.0 / 3.0) * (y0 + (SplashCoord)2 * yc); + x2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * xc + x3); + y2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * yc + y3); + + p->path->curveTo(x1, y1, x2, y2, x3, y3); + p->needClose = gTrue; + return 0; +} + +#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) ) +static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, const FT_Vector *pt, void *path) +#else +static int glyphPathCubicTo(FT_Vector *ctrl1, FT_Vector *ctrl2, FT_Vector *pt, void *path) +#endif +{ + SplashFTFontPath *p = (SplashFTFontPath *)path; + + p->path->curveTo(ctrl1->x / 64.0, -ctrl1->y / 64.0, + ctrl2->x / 64.0, -ctrl2->y / 64.0, + pt->x / 64.0, -pt->y / 64.0); + p->needClose = gTrue; + return 0; +} + +#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H diff --git a/rosapps/smartpdf/poppler/splash/SplashFTFont.h b/rosapps/smartpdf/poppler/splash/SplashFTFont.h new file mode 100644 index 00000000000..ae5b5561218 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFTFont.h @@ -0,0 +1,53 @@ +//======================================================================== +// +// SplashFTFont.h +// +//======================================================================== + +#ifndef SPLASHFTFONT_H +#define SPLASHFTFONT_H + +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include FT_FREETYPE_H +#include "SplashFont.h" + +class SplashFTFontFile; + +//------------------------------------------------------------------------ +// SplashFTFont +//------------------------------------------------------------------------ + +class SplashFTFont: public SplashFont { +public: + + SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA); + + virtual ~SplashFTFont(); + + // Munge xFrac and yFrac before calling SplashFont::getGlyph. + virtual GBool getGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap); + + // Rasterize a glyph. The and values are the same + // as described for getGlyph. + virtual GBool makeGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap); + + // Return the path for a glyph. + virtual SplashPath *getGlyphPath(int c); + +private: + + FT_Size sizeObj; + FT_Matrix matrix; +}; + +#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashFTFontEngine.cc b/rosapps/smartpdf/poppler/splash/SplashFTFontEngine.cc new file mode 100644 index 00000000000..64d287b4505 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFTFontEngine.cc @@ -0,0 +1,156 @@ +//======================================================================== +// +// SplashFTFontEngine.cc +// +//======================================================================== + +#include + +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#ifndef WIN32 +#include +#endif +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "goo/gfile.h" +#include "fofi/FoFiTrueType.h" +#include "fofi/FoFiType1C.h" +#include "SplashFTFontFile.h" +#include "SplashFTFontEngine.h" + +#ifdef VMS +#if (__VMS_VER < 70000000) +extern "C" int unlink(char *filename); +#endif +#endif + +//------------------------------------------------------------------------ + +static void fileWrite(void *stream, char *data, int len) { + fwrite(data, 1, len, (FILE *)stream); +} + +//------------------------------------------------------------------------ +// SplashFTFontEngine +//------------------------------------------------------------------------ + +SplashFTFontEngine::SplashFTFontEngine(GBool aaA, FT_Library libA) { + FT_Int major, minor, patch; + + aa = aaA; + lib = libA; + + // as of FT 2.1.8, CID fonts are indexed by CID instead of GID + FT_Library_Version(lib, &major, &minor, &patch); + useCIDs = major > 2 || + (major == 2 && (minor > 1 || (minor == 1 && patch > 7))); +} + +SplashFTFontEngine *SplashFTFontEngine::init(GBool aaA) { + FT_Library libA; + + if (FT_Init_FreeType(&libA)) { + return NULL; + } + return new SplashFTFontEngine(aaA, libA); +} + +SplashFTFontEngine::~SplashFTFontEngine() { + FT_Done_FreeType(lib); +} + +SplashFontFile *SplashFTFontEngine::loadType1Font(SplashFontFileID *idA, + SplashFontSrc *src, + char **enc) { + return SplashFTFontFile::loadType1Font(this, idA, src, enc); +} + +SplashFontFile *SplashFTFontEngine::loadType1CFont(SplashFontFileID *idA, + SplashFontSrc *src, + char **enc) { + return SplashFTFontFile::loadType1Font(this, idA, src, enc); +} + +SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA, + SplashFontSrc *src) { + FoFiType1C *ff; + Gushort *cidToGIDMap; + int nCIDs; + SplashFontFile *ret; + + // check for a CFF font + if (useCIDs) { + cidToGIDMap = NULL; + nCIDs = 0; + } else { + if (src->isFile) { + ff = FoFiType1C::load(src->fileName->getCString()); + } else { + ff = new FoFiType1C(src->buf, src->bufLen, gFalse); + } + if (ff) { + cidToGIDMap = ff->getCIDToGIDMap(&nCIDs); + delete ff; + } else { + cidToGIDMap = NULL; + nCIDs = 0; + } + } + ret = SplashFTFontFile::loadCIDFont(this, idA, src, cidToGIDMap, nCIDs); + if (!ret) { + gfree(cidToGIDMap); + } + return ret; +} + +SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA, + SplashFontSrc *src, + Gushort *codeToGID, + int codeToGIDLen, + int faceIndex) { +#if 0 + FoFiTrueType *ff; + GooString *tmpFileName; + FILE *tmpFile; + SplashFontFile *ret; + + if (!(ff = FoFiTrueType::load(fileName, faceIndex))) { + return NULL; + } + tmpFileName = NULL; + if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { + delete ff; + return NULL; + } + ff->writeTTF(&fileWrite, tmpFile); + delete ff; + fclose(tmpFile); + ret = SplashFTFontFile::loadTrueTypeFont(this, idA, + tmpFileName->getCString(), + gTrue, codeToGID, codeToGIDLen, + faceIndex); + if (ret) { + if (deleteFile) { + unlink(fileName); + } + } else { + unlink(tmpFileName->getCString()); + } + delete tmpFileName; + return ret; +#else + SplashFontFile *ret; + ret = SplashFTFontFile::loadTrueTypeFont(this, idA, src, + codeToGID, codeToGIDLen, + faceIndex); + return ret; +#endif +} + +#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H diff --git a/rosapps/smartpdf/poppler/splash/SplashFTFontEngine.h b/rosapps/smartpdf/poppler/splash/SplashFTFontEngine.h new file mode 100644 index 00000000000..e6600f5800b --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFTFontEngine.h @@ -0,0 +1,57 @@ +//======================================================================== +// +// SplashFTFontEngine.h +// +//======================================================================== + +#ifndef SPLASHFTFONTENGINE_H +#define SPLASHFTFONTENGINE_H + +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include FT_FREETYPE_H +#include "goo/gtypes.h" + +class SplashFontFile; +class SplashFontFileID; +class SplashFontSrc; + +//------------------------------------------------------------------------ +// SplashFTFontEngine +//------------------------------------------------------------------------ + +class SplashFTFontEngine { +public: + + static SplashFTFontEngine *init(GBool aaA); + + ~SplashFTFontEngine(); + + // Load fonts. + SplashFontFile *loadType1Font(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadType1CFont(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadCIDFont(SplashFontFileID *idA, SplashFontSrc *src); + SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, SplashFontSrc *src, + Gushort *codeToGID, int codeToGIDLen, + int faceIndex=0); + +private: + + SplashFTFontEngine(GBool aaA, FT_Library libA); + + GBool aa; + FT_Library lib; + GBool useCIDs; + + friend class SplashFTFontFile; + friend class SplashFTFont; +}; + +#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashFTFontFile.cc b/rosapps/smartpdf/poppler/splash/SplashFTFontFile.cc new file mode 100644 index 00000000000..76927660f56 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFTFontFile.cc @@ -0,0 +1,122 @@ +//======================================================================== +// +// SplashFTFontFile.cc +// +//======================================================================== + +#include + +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "SplashFTFontEngine.h" +#include "SplashFTFont.h" +#include "SplashFTFontFile.h" + +//------------------------------------------------------------------------ +// SplashFTFontFile +//------------------------------------------------------------------------ + +SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + char **encA) { + FT_Face faceA; + Gushort *codeToGIDA; + char *name; + int i; + + if (src->isFile) { + if (FT_New_Face(engineA->lib, src->fileName->getCString(), 0, &faceA)) + return NULL; + } else { + if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, 0, &faceA)) + return NULL; + } + codeToGIDA = (Gushort *)gmallocn(256, sizeof(int)); + for (i = 0; i < 256; ++i) { + codeToGIDA[i] = 0; + if ((name = encA[i])) { + codeToGIDA[i] = (Gushort)FT_Get_Name_Index(faceA, name); + } + } + + return new SplashFTFontFile(engineA, idA, src, + faceA, codeToGIDA, 256); +} + +SplashFontFile *SplashFTFontFile::loadCIDFont(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + Gushort *codeToGIDA, + int codeToGIDLenA) { + FT_Face faceA; + + if (src->isFile) { + if (FT_New_Face(engineA->lib, src->fileName->getCString(), 0, &faceA)) + return NULL; + } else { + if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, 0, &faceA)) + return NULL; + } + + return new SplashFTFontFile(engineA, idA, src, + faceA, codeToGIDA, codeToGIDLenA); +} + +SplashFontFile *SplashFTFontFile::loadTrueTypeFont(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + Gushort *codeToGIDA, + int codeToGIDLenA, + int faceIndexA) { + FT_Face faceA; + + if (src->isFile) { + if (FT_New_Face(engineA->lib, src->fileName->getCString(), faceIndexA, &faceA)) + return NULL; + } else { + if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, faceIndexA, &faceA)) + return NULL; + } + + return new SplashFTFontFile(engineA, idA, src, + faceA, codeToGIDA, codeToGIDLenA); +} + +SplashFTFontFile::SplashFTFontFile(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *srcA, + FT_Face faceA, + Gushort *codeToGIDA, int codeToGIDLenA): + SplashFontFile(idA, srcA) +{ + engine = engineA; + face = faceA; + codeToGID = codeToGIDA; + codeToGIDLen = codeToGIDLenA; +} + +SplashFTFontFile::~SplashFTFontFile() { + if (face) { + FT_Done_Face(face); + } + if (codeToGID) { + gfree(codeToGID); + } +} + +SplashFont *SplashFTFontFile::makeFont(SplashCoord *mat) { + SplashFont *font; + + font = new SplashFTFont(this, mat); + font->initCache(); + return font; +} + +#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H diff --git a/rosapps/smartpdf/poppler/splash/SplashFTFontFile.h b/rosapps/smartpdf/poppler/splash/SplashFTFontFile.h new file mode 100644 index 00000000000..b1d0f41bb63 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFTFontFile.h @@ -0,0 +1,68 @@ +//======================================================================== +// +// SplashFTFontFile.h +// +//======================================================================== + +#ifndef SPLASHFTFONTFILE_H +#define SPLASHFTFONTFILE_H + +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include FT_FREETYPE_H +#include "SplashFontFile.h" + +class SplashFontFileID; +class SplashFTFontEngine; + +//------------------------------------------------------------------------ +// SplashFTFontFile +//------------------------------------------------------------------------ + +class SplashFTFontFile: public SplashFontFile { +public: + + static SplashFontFile *loadType1Font(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, char **encA); + static SplashFontFile *loadCIDFont(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + Gushort *codeToCIDA, int codeToGIDLenA); + static SplashFontFile *loadTrueTypeFont(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + Gushort *codeToGIDA, + int codeToGIDLenA, + int faceIndexA=0); + + virtual ~SplashFTFontFile(); + + // Create a new SplashFTFont, i.e., a scaled instance of this font + // file. + virtual SplashFont *makeFont(SplashCoord *mat); + +private: + + SplashFTFontFile(SplashFTFontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *srcA, + FT_Face faceA, + Gushort *codeToGIDA, int codeToGIDLenA); + + SplashFTFontEngine *engine; + FT_Face face; + Gushort *codeToGID; + int codeToGIDLen; + + friend class SplashFTFont; +}; + +#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashFont.cc b/rosapps/smartpdf/poppler/splash/SplashFont.cc new file mode 100644 index 00000000000..570a9c16b52 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFont.cc @@ -0,0 +1,172 @@ +//======================================================================== +// +// SplashFont.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "SplashMath.h" +#include "SplashGlyphBitmap.h" +#include "SplashFontFile.h" +#include "SplashFont.h" + +//------------------------------------------------------------------------ + +struct SplashFontCacheTag { + int c; + short xFrac, yFrac; // x and y fractions + int mru; // valid bit (0x80000000) and MRU index + int x, y, w, h; // offset and size of glyph +}; + +//------------------------------------------------------------------------ +// SplashFont +//------------------------------------------------------------------------ + +SplashFont::SplashFont(SplashFontFile *fontFileA, SplashCoord *matA, + GBool aaA) { + fontFile = fontFileA; + fontFile->incRefCnt(); + mat[0] = matA[0]; + mat[1] = matA[1]; + mat[2] = matA[2]; + mat[3] = matA[3]; + aa = aaA; + + cache = NULL; + cacheTags = NULL; + + xMin = yMin = xMax = yMax = 0; +} + +void SplashFont::initCache() { + int i; + + // this should be (max - min + 1), but we add some padding to + // deal with rounding errors + glyphW = xMax - xMin + 3; + glyphH = yMax - yMin + 3; + if (aa) { + glyphSize = glyphW * glyphH; + } else { + glyphSize = ((glyphW + 7) >> 3) * glyphH; + } + + // set up the glyph pixmap cache + cacheAssoc = 8; + if (glyphSize <= 256) { + cacheSets = 8; + } else if (glyphSize <= 512) { + cacheSets = 4; + } else if (glyphSize <= 1024) { + cacheSets = 2; + } else { + cacheSets = 1; + } + cache = (Guchar *)gmallocn(cacheSets* cacheAssoc, glyphSize); + cacheTags = (SplashFontCacheTag *)gmallocn(cacheSets * cacheAssoc, + sizeof(SplashFontCacheTag)); + for (i = 0; i < cacheSets * cacheAssoc; ++i) { + cacheTags[i].mru = i & (cacheAssoc - 1); + } +} + +SplashFont::~SplashFont() { + fontFile->decRefCnt(); + if (cache) { + gfree(cache); + } + if (cacheTags) { + gfree(cacheTags); + } +} + +GBool SplashFont::getGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap) { + SplashGlyphBitmap bitmap2; + int size; + Guchar *p; + int i, j, k; + + // no fractional coordinates for large glyphs or non-anti-aliased + // glyphs + if (!aa || glyphH > 50) { + xFrac = yFrac = 0; + } + + // check the cache + i = (c & (cacheSets - 1)) * cacheAssoc; + for (j = 0; j < cacheAssoc; ++j) { + if ((cacheTags[i+j].mru & 0x80000000) && + cacheTags[i+j].c == c && + (int)cacheTags[i+j].xFrac == xFrac && + (int)cacheTags[i+j].yFrac == yFrac) { + bitmap->x = cacheTags[i+j].x; + bitmap->y = cacheTags[i+j].y; + bitmap->w = cacheTags[i+j].w; + bitmap->h = cacheTags[i+j].h; + for (k = 0; k < cacheAssoc; ++k) { + if (k != j && + (cacheTags[i+k].mru & 0x7fffffff) < + (cacheTags[i+j].mru & 0x7fffffff)) { + ++cacheTags[i+k].mru; + } + } + cacheTags[i+j].mru = 0x80000000; + bitmap->aa = aa; + bitmap->data = cache + (i+j) * glyphSize; + bitmap->freeData = gFalse; + return gTrue; + } + } + + // generate the glyph bitmap + if (!makeGlyph(c, xFrac, yFrac, &bitmap2)) { + return gFalse; + } + + // if the glyph doesn't fit in the bounding box, return a temporary + // uncached bitmap + if (bitmap2.w > glyphW || bitmap2.h > glyphH) { + *bitmap = bitmap2; + return gTrue; + } + + // insert glyph pixmap in cache + if (aa) { + size = bitmap2.w * bitmap2.h; + } else { + size = ((bitmap2.w + 7) >> 3) * bitmap2.h; + } + p = NULL; // make gcc happy + for (j = 0; j < cacheAssoc; ++j) { + if ((cacheTags[i+j].mru & 0x7fffffff) == cacheAssoc - 1) { + cacheTags[i+j].mru = 0x80000000; + cacheTags[i+j].c = c; + cacheTags[i+j].xFrac = (short)xFrac; + cacheTags[i+j].yFrac = (short)yFrac; + cacheTags[i+j].x = bitmap2.x; + cacheTags[i+j].y = bitmap2.y; + cacheTags[i+j].w = bitmap2.w; + cacheTags[i+j].h = bitmap2.h; + p = cache + (i+j) * glyphSize; + memcpy(p, bitmap2.data, size); + } else { + ++cacheTags[i+j].mru; + } + } + *bitmap = bitmap2; + bitmap->data = p; + bitmap->freeData = gFalse; + if (bitmap2.freeData) { + gfree(bitmap2.data); + } + return gTrue; +} diff --git a/rosapps/smartpdf/poppler/splash/SplashFont.h b/rosapps/smartpdf/poppler/splash/SplashFont.h new file mode 100644 index 00000000000..59bc14e471f --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFont.h @@ -0,0 +1,95 @@ +//======================================================================== +// +// SplashFont.h +// +//======================================================================== + +#ifndef SPLASHFONT_H +#define SPLASHFONT_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "SplashTypes.h" + +struct SplashGlyphBitmap; +struct SplashFontCacheTag; +class SplashFontFile; +class SplashPath; + +//------------------------------------------------------------------------ + +// Fractional positioning uses this many bits to the right of the +// decimal points. +#define splashFontFractionBits 2 +#define splashFontFraction (1 << splashFontFractionBits) +#define splashFontFractionMul \ + ((SplashCoord)1 / (SplashCoord)splashFontFraction) + +//------------------------------------------------------------------------ +// SplashFont +//------------------------------------------------------------------------ + +class SplashFont { +public: + + SplashFont(SplashFontFile *fontFileA, SplashCoord *matA, GBool aaA); + + // This must be called after the constructor, so that the subclass + // constructor has a chance to compute the bbox. + void initCache(); + + virtual ~SplashFont(); + + SplashFontFile *getFontFile() { return fontFile; } + + // Return true if matches the specified font file and matrix. + GBool matches(SplashFontFile *fontFileA, SplashCoord *matA) { + return fontFileA == fontFile && + matA[0] == mat[0] && matA[1] == mat[1] && + matA[2] == mat[2] && matA[3] == mat[3]; + } + + // Get a glyph - this does a cache lookup first, and if not found, + // creates a new bitmap and adds it to the cache. The and + // values are splashFontFractionBits bits each, representing + // the numerators of fractions in [0, 1), where the denominator is + // splashFontFraction = 1 << splashFontFractionBits. Subclasses + // should override this to zero out xFrac and/or yFrac if they don't + // support fractional coordinates. + virtual GBool getGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap); + + // Rasterize a glyph. The and values are the same + // as described for getGlyph. + virtual GBool makeGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap) = 0; + + // Return the path for a glyph. + virtual SplashPath *getGlyphPath(int c) = 0; + + // Return the font transform matrix. + SplashCoord *getMatrix() { return mat; } + + // Return the glyph bounding box. + void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) + { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } + +protected: + + SplashFontFile *fontFile; + SplashCoord mat[4]; // font transform matrix + GBool aa; // anti-aliasing + int xMin, yMin, xMax, yMax; // glyph bounding box + Guchar *cache; // glyph bitmap cache + SplashFontCacheTag * // cache tags + cacheTags; + int glyphW, glyphH; // size of glyph bitmaps + int glyphSize; // size of glyph bitmaps, in bytes + int cacheSets; // number of sets in cache + int cacheAssoc; // cache associativity (glyphs per set) +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashFontEngine.cc b/rosapps/smartpdf/poppler/splash/SplashFontEngine.cc new file mode 100644 index 00000000000..01b1b6e9438 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFontEngine.cc @@ -0,0 +1,247 @@ +//======================================================================== +// +// SplashFontEngine.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#if HAVE_T1LIB_H +#include +#endif + +#include +#include +#ifndef WIN32 +# include +#endif +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "SplashT1FontEngine.h" +#include "SplashFTFontEngine.h" +#include "SplashFontFile.h" +#include "SplashFontFileID.h" +#include "SplashFont.h" +#include "SplashFontEngine.h" + +#ifdef VMS +#if (__VMS_VER < 70000000) +extern "C" int unlink(char *filename); +#endif +#endif + +//------------------------------------------------------------------------ +// SplashFontEngine +//------------------------------------------------------------------------ + +SplashFontEngine::SplashFontEngine( +#if HAVE_T1LIB_H + GBool enableT1lib, +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + GBool enableFreeType, +#endif + GBool aa) { + int i; + + for (i = 0; i < splashFontCacheSize; ++i) { + fontCache[i] = NULL; + } + +#if HAVE_T1LIB_H + if (enableT1lib) { + t1Engine = SplashT1FontEngine::init(aa); + } else { + t1Engine = NULL; + } +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + if (enableFreeType) { + ftEngine = SplashFTFontEngine::init(aa); + } else { + ftEngine = NULL; + } +#endif +} + +SplashFontEngine::~SplashFontEngine() { + int i; + + for (i = 0; i < splashFontCacheSize; ++i) { + if (fontCache[i]) { + delete fontCache[i]; + } + } + +#if HAVE_T1LIB_H + if (t1Engine) { + delete t1Engine; + } +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + if (ftEngine) { + delete ftEngine; + } +#endif +} + +SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) { + SplashFontFile *fontFile; + int i; + + for (i = 0; i < splashFontCacheSize; ++i) { + if (fontCache[i]) { + fontFile = fontCache[i]->getFontFile(); + if (fontFile && fontFile->getID()->matches(id)) { + return fontFile; + } + } + } + return NULL; +} + +SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA, + SplashFontSrc *src, + char **enc) { + SplashFontFile *fontFile; + + fontFile = NULL; +#if HAVE_T1LIB_H + if (!fontFile && t1Engine) { + fontFile = t1Engine->loadType1Font(idA, src, enc); + } +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + if (!fontFile && ftEngine) { + fontFile = ftEngine->loadType1Font(idA, src, enc); + } +#endif + +#ifndef WIN32 + // delete the (temporary) font file -- with Unix hard link + // semantics, this will remove the last link; otherwise it will + // return an error, leaving the file to be deleted later (if + // loadXYZFont failed, the file will always be deleted) + if (src->isFile) + src->unref(); +#endif + + return fontFile; +} + +SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA, + SplashFontSrc *src, + char **enc) { + SplashFontFile *fontFile; + + fontFile = NULL; +#if HAVE_T1LIB_H + if (!fontFile && t1Engine) { + fontFile = t1Engine->loadType1CFont(idA, src, enc); + } +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + if (!fontFile && ftEngine) { + fontFile = ftEngine->loadType1CFont(idA, src, enc); + } +#endif + +#ifndef WIN32 + // delete the (temporary) font file -- with Unix hard link + // semantics, this will remove the last link; otherwise it will + // return an error, leaving the file to be deleted later (if + // loadXYZFont failed, the file will always be deleted) + if (src->isFile) + src->unref(); +#endif + + return fontFile; +} + +SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA, + SplashFontSrc *src) { + SplashFontFile *fontFile; + + fontFile = NULL; +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + if (!fontFile && ftEngine) { + fontFile = ftEngine->loadCIDFont(idA, src); + } +#endif + +#ifndef WIN32 + // delete the (temporary) font file -- with Unix hard link + // semantics, this will remove the last link; otherwise it will + // return an error, leaving the file to be deleted later (if + // loadXYZFont failed, the file will always be deleted) + if (src->isFile) + src->unref(); +#endif + + return fontFile; +} + +SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA, + SplashFontSrc *src, + Gushort *codeToGID, + int codeToGIDLen, + int faceIndex) { + SplashFontFile *fontFile; + + fontFile = NULL; +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + if (!fontFile && ftEngine) { + fontFile = ftEngine->loadTrueTypeFont(idA, src, + codeToGID, codeToGIDLen, faceIndex); + } +#endif + + if (!fontFile) { + gfree(codeToGID); + } + +#ifndef WIN32 + // delete the (temporary) font file -- with Unix hard link + // semantics, this will remove the last link; otherwise it will + // return an error, leaving the file to be deleted later (if + // loadXYZFont failed, the file will always be deleted) + if (src->isFile) + src->unref(); +#endif + + return fontFile; +} + +SplashFont *SplashFontEngine::getFont(SplashFontFile *fontFile, + SplashCoord *mat) { + SplashFont *font; + int i, j; + + font = fontCache[0]; + if (font && font->matches(fontFile, mat)) { + return font; + } + for (i = 1; i < splashFontCacheSize; ++i) { + font = fontCache[i]; + if (font && font->matches(fontFile, mat)) { + for (j = i; j > 0; --j) { + fontCache[j] = fontCache[j-1]; + } + fontCache[0] = font; + return font; + } + } + font = fontFile->makeFont(mat); + if (fontCache[splashFontCacheSize - 1]) { + delete fontCache[splashFontCacheSize - 1]; + } + for (j = splashFontCacheSize - 1; j > 0; --j) { + fontCache[j] = fontCache[j-1]; + } + fontCache[0] = font; + return font; +} diff --git a/rosapps/smartpdf/poppler/splash/SplashFontEngine.h b/rosapps/smartpdf/poppler/splash/SplashFontEngine.h new file mode 100644 index 00000000000..23c49acd64b --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFontEngine.h @@ -0,0 +1,81 @@ +//======================================================================== +// +// SplashFontEngine.h +// +//======================================================================== + +#ifndef SPLASHFONTENGINE_H +#define SPLASHFONTENGINE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +class SplashT1FontEngine; +class SplashFTFontEngine; +class SplashDTFontEngine; +class SplashFontFile; +class SplashFontFileID; +class SplashFont; +class SplashFontSrc; + +//------------------------------------------------------------------------ + +#define splashFontCacheSize 16 + +//------------------------------------------------------------------------ +// SplashFontEngine +//------------------------------------------------------------------------ + +class SplashFontEngine { +public: + + // Create a font engine. + SplashFontEngine( +#if HAVE_T1LIB_H + GBool enableT1lib, +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + GBool enableFreeType, +#endif + GBool aa); + + ~SplashFontEngine(); + + // Get a font file from the cache. Returns NULL if there is no + // matching entry in the cache. + SplashFontFile *getFontFile(SplashFontFileID *id); + + // Load fonts - these create new SplashFontFile objects. + SplashFontFile *loadType1Font(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadType1CFont(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadCIDFont(SplashFontFileID *idA, SplashFontSrc *src); + SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, SplashFontSrc *src, + Gushort *codeToGID, int codeToGIDLen, + int faceIndex=0); + + // Get a font - this does a cache lookup first, and if not found, + // creates a new SplashFont object and adds it to the cache. The + // matrix: + // [ mat[0] mat[1] ] + // [ mat[2] mat[3] ] + // specifies the font transform in PostScript style: + // [x' y'] = [x y] * mat + // Note that the Splash y axis points downward. + SplashFont *getFont(SplashFontFile *fontFile, SplashCoord *mat); + +private: + + SplashFont *fontCache[splashFontCacheSize]; + +#if HAVE_T1LIB_H + SplashT1FontEngine *t1Engine; +#endif +#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H + SplashFTFontEngine *ftEngine; +#endif +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashFontFile.cc b/rosapps/smartpdf/poppler/splash/SplashFontFile.cc new file mode 100644 index 00000000000..e7cff3e979e --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFontFile.cc @@ -0,0 +1,109 @@ +//======================================================================== +// +// SplashFontFile.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#ifndef WIN32 +#include +#endif +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "SplashFontFile.h" +#include "SplashFontFileID.h" + +#ifdef VMS +#if (__VMS_VER < 70000000) +extern "C" int unlink(char *filename); +#endif +#endif + +//------------------------------------------------------------------------ +// SplashFontFile +//------------------------------------------------------------------------ + +SplashFontFile::SplashFontFile(SplashFontFileID *idA, SplashFontSrc *srcA) { + id = idA; + src = srcA; + src->ref(); + refCnt = 0; +} + +SplashFontFile::~SplashFontFile() { + src->unref(); + delete id; +} + +void SplashFontFile::incRefCnt() { + ++refCnt; +} + +void SplashFontFile::decRefCnt() { + if (!--refCnt) { + delete this; + } +} + +// + +SplashFontSrc::SplashFontSrc() { + isFile = gFalse; + deleteSrc = gFalse; + fileName = NULL; + buf = NULL; + refcnt = 1; +} + +SplashFontSrc::~SplashFontSrc() { + if (deleteSrc) { + if (isFile) { + if (fileName) + unlink(fileName->getCString()); + } else { + if (buf) + gfree(buf); + } + } + + if (isFile && fileName) + delete fileName; +} + +void SplashFontSrc::ref() { + refcnt++; +} + +void SplashFontSrc::unref() { + if (! --refcnt) + delete this; +} + +void SplashFontSrc::setFile(GooString *file, GBool del) +{ + isFile = gTrue; + fileName = file->copy(); + deleteSrc = del; +} + +void SplashFontSrc::setFile(const char *file, GBool del) +{ + isFile = gTrue; + fileName = new GooString(file); + deleteSrc = del; +} + +void SplashFontSrc::setBuf(char *bufA, int bufLenA, GBool del) +{ + isFile = gFalse; + buf = bufA; + bufLen = bufLenA; + deleteSrc = del; +} + diff --git a/rosapps/smartpdf/poppler/splash/SplashFontFile.h b/rosapps/smartpdf/poppler/splash/SplashFontFile.h new file mode 100644 index 00000000000..b36025f7619 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFontFile.h @@ -0,0 +1,76 @@ +//======================================================================== +// +// SplashFontFile.h +// +//======================================================================== + +#ifndef SPLASHFONTFILE_H +#define SPLASHFONTFILE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" +#include "SplashTypes.h" + +class GooString; +class SplashFontEngine; +class SplashFont; +class SplashFontFileID; + +//------------------------------------------------------------------------ +// SplashFontFile +//------------------------------------------------------------------------ + +class SplashFontSrc { +public: + SplashFontSrc(); + ~SplashFontSrc(); + + void setFile(GooString *file, GBool del); + void setFile(const char *file, GBool del); + void setBuf(char *bufA, int buflenA, GBool del); + + void ref(); + void unref(); + + GBool isFile; + GooString *fileName; + char *buf; + int bufLen; + GBool deleteSrc; + int refcnt; +}; + +class SplashFontFile { +public: + + virtual ~SplashFontFile(); + + // Create a new SplashFont, i.e., a scaled instance of this font + // file. + virtual SplashFont *makeFont(SplashCoord *mat) = 0; + + // Get the font file ID. + SplashFontFileID *getID() { return id; } + + // Increment the reference count. + void incRefCnt(); + + // Decrement the reference count. If the new value is zero, delete + // the SplashFontFile object. + void decRefCnt(); + +protected: + + SplashFontFile(SplashFontFileID *idA, SplashFontSrc *srcA); + + SplashFontFileID *id; + SplashFontSrc *src; + int refCnt; + + friend class SplashFontEngine; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashFontFileID.cc b/rosapps/smartpdf/poppler/splash/SplashFontFileID.cc new file mode 100644 index 00000000000..a66dabf61e3 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFontFileID.cc @@ -0,0 +1,23 @@ +//======================================================================== +// +// SplashFontFileID.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "SplashFontFileID.h" + +//------------------------------------------------------------------------ +// SplashFontFileID +//------------------------------------------------------------------------ + +SplashFontFileID::SplashFontFileID() { +} + +SplashFontFileID::~SplashFontFileID() { +} diff --git a/rosapps/smartpdf/poppler/splash/SplashFontFileID.h b/rosapps/smartpdf/poppler/splash/SplashFontFileID.h new file mode 100644 index 00000000000..cfd89ebb56a --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashFontFileID.h @@ -0,0 +1,28 @@ +//======================================================================== +// +// SplashFontFileID.h +// +//======================================================================== + +#ifndef SPLASHFONTFILEID_H +#define SPLASHFONTFILEID_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +//------------------------------------------------------------------------ +// SplashFontFileID +//------------------------------------------------------------------------ + +class SplashFontFileID { +public: + + SplashFontFileID(); + virtual ~SplashFontFileID(); + virtual GBool matches(SplashFontFileID *id) = 0; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashGlyphBitmap.h b/rosapps/smartpdf/poppler/splash/SplashGlyphBitmap.h new file mode 100644 index 00000000000..c062c106e6a --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashGlyphBitmap.h @@ -0,0 +1,24 @@ +//======================================================================== +// +// SplashGlyphBitmap.h +// +//======================================================================== + +#ifndef SPLASHGLYPHBITMAP_H +#define SPLASHGLYPHBITMAP_H + +#include "goo/gtypes.h" + +//------------------------------------------------------------------------ +// SplashGlyphBitmap +//------------------------------------------------------------------------ + +struct SplashGlyphBitmap { + int x, y, w, h; // offset and size of glyph + GBool aa; // anti-aliased: true means 8-bit alpha + // bitmap; false means 1-bit + Guchar *data; // bitmap data + GBool freeData; // true if data memory should be freed +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashMath.h b/rosapps/smartpdf/poppler/splash/SplashMath.h new file mode 100644 index 00000000000..1d4e22647d8 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashMath.h @@ -0,0 +1,77 @@ +//======================================================================== +// +// SplashMath.h +// +//======================================================================== + +#ifndef SPLASHMATH_H +#define SPLASHMATH_H + +#if USE_FIXEDPONT +#include "FixedPoint.h" +#else +#include +#endif +#include "SplashTypes.h" + +static inline SplashCoord splashAbs(SplashCoord x) { +#if USE_FIXEDPOINT + return FixedPoint::abs(x); +#else + return fabs(x); +#endif +} + +static inline int splashFloor(SplashCoord x) { + #if USE_FIXEDPOINT + return FixedPoint::floor(x); + #else + return (int)floor(x); + #endif +} + +static inline int splashCeil(SplashCoord x) { +#if USE_FIXEDPOINT + return FixedPoint::ceil(x); +#else + return (int)ceil(x); +#endif +} + +static inline int splashRound(SplashCoord x) { +#if USE_FIXEDPOINT + return FixedPoint::round(x); +#else + return (int)floor(x + 0.5); +#endif +} + +static inline SplashCoord splashSqrt(SplashCoord x) { +#if USE_FIXEDPOINT + return FixedPoint::sqrt(x); +#else + return sqrt(x); +#endif +} + +static inline SplashCoord splashPow(SplashCoord x, SplashCoord y) { +#if USE_FIXEDPOINT + return FixedPoint::pow(x, y); +#else + return pow(x, y); +#endif +} + +static inline SplashCoord splashDist(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1) { + SplashCoord dx, dy; + dx = x1 - x0; + dy = y1 - y0; +#if USE_FIXEDPOINT + return FixedPoint::sqrt(dx * dx + dy * dy); +#else + return sqrt(dx * dx + dy * dy); +#endif +} + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashPath.cc b/rosapps/smartpdf/poppler/splash/SplashPath.cc new file mode 100644 index 00000000000..1f0f80ddbde --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashPath.cc @@ -0,0 +1,178 @@ +//======================================================================== +// +// SplashPath.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "SplashErrorCodes.h" +#include "SplashPath.h" + +//------------------------------------------------------------------------ +// SplashPath +//------------------------------------------------------------------------ + +// A path can be in three possible states: +// +// 1. no current point -- zero or more finished subpaths +// [curSubpath == length] +// +// 2. one point in subpath +// [curSubpath == length - 1] +// +// 3. open subpath with two or more points +// [curSubpath < length - 1] + +SplashPath::SplashPath() { + pts = NULL; + flags = NULL; + length = size = 0; + curSubpath = 0; +} + +SplashPath::SplashPath(SplashPath *path) { + length = path->length; + size = path->size; + pts = (SplashPathPoint *)gmallocn(size, sizeof(SplashPathPoint)); + flags = (Guchar *)gmallocn(size, sizeof(Guchar)); + memcpy(pts, path->pts, length * sizeof(SplashPathPoint)); + memcpy(flags, path->flags, length * sizeof(Guchar)); + curSubpath = path->curSubpath; +} + +SplashPath::~SplashPath() { + gfree(pts); + gfree(flags); +} + +// Add space for more points. +void SplashPath::grow(int nPts) { + if (length + nPts > size) { + if (size == 0) { + size = 32; + } + while (size < length + nPts) { + size *= 2; + } + pts = (SplashPathPoint *)greallocn(pts, size, sizeof(SplashPathPoint)); + flags = (Guchar *)greallocn(flags, size, sizeof(Guchar)); + } +} + +void SplashPath::append(SplashPath *path) { + int i; + + curSubpath = length + path->curSubpath; + grow(path->length); + for (i = 0; i < path->length; ++i) { + pts[length] = path->pts[i]; + flags[length] = path->flags[i]; + ++length; + } +} + +SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) { + if (onePointSubpath()) { + return splashErrBogusPath; + } + grow(1); + pts[length].x = x; + pts[length].y = y; + flags[length] = splashPathFirst | splashPathLast; + curSubpath = length++; + return splashOk; +} + +SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) { + if (noCurrentPoint()) { + return splashErrNoCurPt; + } + flags[length-1] &= ~splashPathLast; + grow(1); + pts[length].x = x; + pts[length].y = y; + flags[length] = splashPathLast; + ++length; + return splashOk; +} + +SplashError SplashPath::curveTo(SplashCoord x1, SplashCoord y1, + SplashCoord x2, SplashCoord y2, + SplashCoord x3, SplashCoord y3) { + if (noCurrentPoint()) { + return splashErrNoCurPt; + } + flags[length-1] &= ~splashPathLast; + grow(3); + pts[length].x = x1; + pts[length].y = y1; + flags[length] = splashPathCurve; + ++length; + pts[length].x = x2; + pts[length].y = y2; + flags[length] = splashPathCurve; + ++length; + pts[length].x = x3; + pts[length].y = y3; + flags[length] = splashPathLast; + ++length; + return splashOk; +} + +SplashError SplashPath::arcCWTo(SplashCoord x1, SplashCoord y1, + SplashCoord xc, SplashCoord yc) { + if (noCurrentPoint()) { + return splashErrNoCurPt; + } + flags[length-1] &= ~splashPathLast; + grow(2); + pts[length].x = xc; + pts[length].y = yc; + flags[length] = splashPathArcCW; + ++length; + pts[length].x = x1; + pts[length].y = y1; + flags[length] = splashPathLast; + ++length; + return splashOk; +} + +SplashError SplashPath::close() { + if (noCurrentPoint()) { + return splashErrNoCurPt; + } + if (curSubpath == length - 1 || + pts[length - 1].x != pts[curSubpath].x || + pts[length - 1].y != pts[curSubpath].y) { + lineTo(pts[curSubpath].x, pts[curSubpath].y); + } + flags[curSubpath] |= splashPathClosed; + flags[length - 1] |= splashPathClosed; + curSubpath = length; + return splashOk; +} + +void SplashPath::offset(SplashCoord dx, SplashCoord dy) { + int i; + + for (i = 0; i < length; ++i) { + pts[i].x += dx; + pts[i].y += dy; + } +} + +GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) { + if (noCurrentPoint()) { + return gFalse; + } + *x = pts[length - 1].x; + *y = pts[length - 1].y; + return gTrue; +} diff --git a/rosapps/smartpdf/poppler/splash/SplashPath.h b/rosapps/smartpdf/poppler/splash/SplashPath.h new file mode 100644 index 00000000000..1b7362a5371 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashPath.h @@ -0,0 +1,112 @@ +//======================================================================== +// +// SplashPath.h +// +//======================================================================== + +#ifndef SPLASHPATH_H +#define SPLASHPATH_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +//------------------------------------------------------------------------ +// SplashPathPoint +//------------------------------------------------------------------------ + +struct SplashPathPoint { + SplashCoord x, y; +}; + +//------------------------------------------------------------------------ +// SplashPath.flags +//------------------------------------------------------------------------ + +// first point on each subpath sets this flag +#define splashPathFirst 0x01 + +// last point on each subpath sets this flag +#define splashPathLast 0x02 + +// if the subpath is closed, its first and last points must be +// identical, and must set this flag +#define splashPathClosed 0x04 + +// curve control points set this flag +#define splashPathCurve 0x08 + +// clockwise arc center points set this flag +#define splashPathArcCW 0x10 + +//------------------------------------------------------------------------ +// SplashPath +//------------------------------------------------------------------------ + +class SplashPath { +public: + + // Create an empty path. + SplashPath(); + + // Copy a path. + SplashPath *copy() { return new SplashPath(this); } + + ~SplashPath(); + + // Append to . + void append(SplashPath *path); + + // Start a new subpath. + SplashError moveTo(SplashCoord x, SplashCoord y); + + // Add a line segment to the last subpath. + SplashError lineTo(SplashCoord x, SplashCoord y); + + // Add a third-order (cubic) Bezier curve segment to the last + // subpath. + SplashError curveTo(SplashCoord x1, SplashCoord y1, + SplashCoord x2, SplashCoord y2, + SplashCoord x3, SplashCoord y3); + + // Add a clockwise circular arc with center (xc, yc) and endpoint + // (x1, y1). + SplashError arcCWTo(SplashCoord x1, SplashCoord y1, + SplashCoord xc, SplashCoord yc); + + // Close the last subpath, adding a line segment if necessary. + SplashError close(); + + // Add (, ) to every point on this path. + void offset(SplashCoord dx, SplashCoord dy); + + // Get the points on the path. + int getLength() { return length; } + void getPoint(int i, double *x, double *y, Guchar *f) + { *x = pts[i].x; *y = pts[i].y; *f = flags[i]; } + + // Get the current point. + GBool getCurPt(SplashCoord *x, SplashCoord *y); + +private: + + SplashPath(SplashPath *path); + void grow(int nPts); + GBool noCurrentPoint() { return curSubpath == length; } + GBool onePointSubpath() { return curSubpath == length - 1; } + GBool openSubpath() { return curSubpath < length - 1; } + + SplashPathPoint *pts; // array of points + Guchar *flags; // array of flags + int length, size; // length/size of the pts and flags arrays + int curSubpath; // index of first point in last subpath + + friend class SplashXPath; + friend class Splash; + // this is a temporary hack, until we read FreeType paths directly + friend class ArthurOutputDev; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashPattern.cc b/rosapps/smartpdf/poppler/splash/SplashPattern.cc new file mode 100644 index 00000000000..38f39943391 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashPattern.cc @@ -0,0 +1,68 @@ +//======================================================================== +// +// SplashPattern.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "SplashMath.h" +#include "SplashScreen.h" +#include "SplashPattern.h" + +//------------------------------------------------------------------------ +// SplashPattern +//------------------------------------------------------------------------ + +SplashPattern::SplashPattern() { +} + +SplashPattern::~SplashPattern() { +} + +//------------------------------------------------------------------------ +// SplashSolidColor +//------------------------------------------------------------------------ + +SplashSolidColor::SplashSolidColor(SplashColorPtr colorA) { + splashColorCopy(color, colorA); +} + +SplashSolidColor::~SplashSolidColor() { +} + +void SplashSolidColor::getColor(int x, int y, SplashColorPtr c) { + splashColorCopy(c, color); +} + +//------------------------------------------------------------------------ +// SplashHalftone +//------------------------------------------------------------------------ + +SplashHalftone::SplashHalftone(SplashColorPtr color0A, SplashColorPtr color1A, + SplashScreen *screenA, SplashCoord valueA) { + splashColorCopy(color0, color0A); + splashColorCopy(color1, color1A); + screen = screenA; + value = valueA; +} + +SplashPattern *SplashHalftone::copy() { + return new SplashHalftone(color0, color1, screen->copy(), value); +} + +SplashHalftone::~SplashHalftone() { + delete screen; +} + +void SplashHalftone::getColor(int x, int y, SplashColorPtr c) { + splashColorCopy(c, screen->test(x, y, value) ? color1 : color0); +} + +GBool SplashHalftone::isStatic() { + return screen->isStatic(value); +} diff --git a/rosapps/smartpdf/poppler/splash/SplashPattern.h b/rosapps/smartpdf/poppler/splash/SplashPattern.h new file mode 100644 index 00000000000..2e50c43b59d --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashPattern.h @@ -0,0 +1,88 @@ +//======================================================================== +// +// SplashPattern.h +// +//======================================================================== + +#ifndef SPLASHPATTERN_H +#define SPLASHPATTERN_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +class SplashScreen; + +//------------------------------------------------------------------------ +// SplashPattern +//------------------------------------------------------------------------ + +class SplashPattern { +public: + + SplashPattern(); + + virtual SplashPattern *copy() = 0; + + virtual ~SplashPattern(); + + // Return the color value for a specific pixel. + virtual void getColor(int x, int y, SplashColorPtr c) = 0; + + // Returns true if this pattern object will return the same color + // value for all pixels. + virtual GBool isStatic() = 0; + +private: +}; + +//------------------------------------------------------------------------ +// SplashSolidColor +//------------------------------------------------------------------------ + +class SplashSolidColor: public SplashPattern { +public: + + SplashSolidColor(SplashColorPtr colorA); + + virtual SplashPattern *copy() { return new SplashSolidColor(color); } + + virtual ~SplashSolidColor(); + + virtual void getColor(int x, int y, SplashColorPtr c); + + virtual GBool isStatic() { return gTrue; } + +private: + + SplashColor color; +}; + +//------------------------------------------------------------------------ +// SplashHalftone +//------------------------------------------------------------------------ + +class SplashHalftone: public SplashPattern { +public: + + SplashHalftone(SplashColorPtr color0A, SplashColorPtr color1A, + SplashScreen *screenA, SplashCoord valueA); + + virtual SplashPattern *copy(); + + virtual ~SplashHalftone(); + + virtual void getColor(int x, int y, SplashColorPtr c); + + virtual GBool isStatic(); + +private: + + SplashColor color0, color1; + SplashScreen *screen; + SplashCoord value; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashScreen.cc b/rosapps/smartpdf/poppler/splash/SplashScreen.cc new file mode 100644 index 00000000000..221296fd6d2 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashScreen.cc @@ -0,0 +1,141 @@ +//======================================================================== +// +// SplashScreen.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "SplashMath.h" +#include "SplashScreen.h" + +//------------------------------------------------------------------------ +// SplashScreen +//------------------------------------------------------------------------ + +// This generates a 45 degree screen using a circular dot spot +// function. DPI = resolution / ((size / 2) * sqrt(2)). +// Gamma correction (gamma = 1 / 1.33) is also computed here. +SplashScreen::SplashScreen(int sizeA) { + SplashCoord *dist; + SplashCoord u, v, d, val; + int size2, x, y, x1, y1, i; + + size2 = sizeA >> 1; + if (size2 < 1) { + size2 = 1; + } + size = size2 << 1; + + // initialize the threshold matrix + mat = (SplashCoord *)gmallocn(size * size, sizeof(SplashCoord)); + for (y = 0; y < size; ++y) { + for (x = 0; x < size; ++x) { + mat[y * size + x] = -1; + } + } + + // build the distance matrix + dist = (SplashCoord *)gmallocn(size * size2, sizeof(SplashCoord)); + for (y = 0; y < size2; ++y) { + for (x = 0; x < size2; ++x) { + if (x + y < size2 - 1) { + u = (SplashCoord)x + 0.5 - 0; + v = (SplashCoord)y + 0.5 - 0; + } else { + u = (SplashCoord)x + 0.5 - (SplashCoord)size2; + v = (SplashCoord)y + 0.5 - (SplashCoord)size2; + } + dist[y * size2 + x] = u*u + v*v; + } + } + for (y = 0; y < size2; ++y) { + for (x = 0; x < size2; ++x) { + if (x < y) { + u = (SplashCoord)x + 0.5 - 0; + v = (SplashCoord)y + 0.5 - (SplashCoord)size2; + } else { + u = (SplashCoord)x + 0.5 - (SplashCoord)size2; + v = (SplashCoord)y + 0.5 - 0; + } + dist[(size2 + y) * size2 + x] = u*u + v*v; + } + } + + // build the threshold matrix + minVal = 1; + maxVal = 0; + x1 = y1 = 0; // make gcc happy + for (i = 1; i <= size * size2; ++i) { + d = size * size2; + for (y = 0; y < size; ++y) { + for (x = 0; x < size2; ++x) { + if (mat[y * size + x] < 0 && + dist[y * size2 + x] < d) { + x1 = x; + y1 = y; + d = dist[y1 * size2 + x1]; + } + } + } + u = (SplashCoord)1 - (SplashCoord)i / (SplashCoord)(size * size2 + 1); + val = splashPow(u, 1.33); + if (val < minVal) { + minVal = val; + } + if (val > maxVal) { + maxVal = val; + } + mat[y1 * size + x1] = val; + if (y1 < size2) { + mat[(y1 + size2) * size + x1 + size2] = val; + } else { + mat[(y1 - size2) * size + x1 + size2] = val; + } + } + + gfree(dist); +} + +SplashScreen::SplashScreen(SplashScreen *screen) { + int n; + + size = screen->size; + n = size * size * sizeof(SplashCoord); + mat = (SplashCoord *)gmalloc(n); + memcpy(mat, screen->mat, n); + minVal = screen->minVal; + maxVal = screen->maxVal; +} + +SplashScreen::~SplashScreen() { + gfree(mat); +} + +int SplashScreen::test(int x, int y, SplashCoord value) { + int xx, yy; + + if (value < minVal) { + return 0; + } + if (value >= maxVal) { + return 1; + } + if ((xx = x % size) < 0) { + xx = -xx; + } + if ((yy = y % size) < 0) { + yy = -yy; + } + return value < mat[yy * size + xx] ? 0 : 1; +} + +GBool SplashScreen::isStatic(SplashCoord value) { + return value < minVal || value >= maxVal; +} diff --git a/rosapps/smartpdf/poppler/splash/SplashScreen.h b/rosapps/smartpdf/poppler/splash/SplashScreen.h new file mode 100644 index 00000000000..e0df8bbd775 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashScreen.h @@ -0,0 +1,48 @@ +//======================================================================== +// +// SplashScreen.h +// +//======================================================================== + +#ifndef SPLASHSCREEN_H +#define SPLASHSCREEN_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +//------------------------------------------------------------------------ +// SplashScreen +//------------------------------------------------------------------------ + +class SplashScreen { +public: + + SplashScreen(int sizeA); + SplashScreen(SplashScreen *screen); + ~SplashScreen(); + + SplashScreen *copy() { return new SplashScreen(this); } + + // Return the computed pixel value (0=black, 1=white) for the gray + // level at (, ). + int test(int x, int y, SplashCoord value); + + // Returns true if value is above the white threshold or below the + // black threshold, i.e., if the corresponding halftone will be + // solid white or black. + GBool isStatic(SplashCoord value); + +private: + + SplashCoord *mat; // threshold matrix + int size; // size of the threshold matrix + SplashCoord minVal; // any pixel value below minVal generates + // solid black + SplashCoord maxVal; // any pixel value above maxVal generates + // solid white +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashState.cc b/rosapps/smartpdf/poppler/splash/SplashState.cc new file mode 100644 index 00000000000..dd011c01960 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashState.cc @@ -0,0 +1,110 @@ +//======================================================================== +// +// SplashState.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "SplashPattern.h" +#include "SplashScreen.h" +#include "SplashClip.h" +#include "SplashState.h" + +//------------------------------------------------------------------------ +// SplashState +//------------------------------------------------------------------------ + +// number of components in each color mode +int splashColorModeNComps[] = { + 1, 1, 2, 3, 3, 4, 4 +}; + +SplashState::SplashState(int width, int height) { + SplashColor color; + + memset(&color, 0, sizeof(SplashColor)); + strokePattern = new SplashSolidColor(color); + fillPattern = new SplashSolidColor(color); + screen = new SplashScreen(10); + blendFunc = NULL; + strokeAlpha = 1; + fillAlpha = 1; + lineWidth = 0; + lineCap = splashLineCapButt; + lineJoin = splashLineJoinMiter; + miterLimit = 10; + flatness = 1; + lineDash = NULL; + lineDashLength = 0; + lineDashPhase = 0; + clip = new SplashClip(0, 0, width - 1, height - 1); + next = NULL; +} + +SplashState::SplashState(SplashState *state) { + strokePattern = state->strokePattern->copy(); + fillPattern = state->fillPattern->copy(); + screen = state->screen->copy(); + blendFunc = state->blendFunc; + strokeAlpha = state->strokeAlpha; + fillAlpha = state->fillAlpha; + lineWidth = state->lineWidth; + lineCap = state->lineCap; + lineJoin = state->lineJoin; + miterLimit = state->miterLimit; + flatness = state->flatness; + if (state->lineDash) { + lineDashLength = state->lineDashLength; + lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord)); + memcpy(lineDash, state->lineDash, lineDashLength * sizeof(SplashCoord)); + } else { + lineDash = NULL; + lineDashLength = 0; + } + lineDashPhase = state->lineDashPhase; + clip = state->clip->copy(); + next = NULL; +} + +SplashState::~SplashState() { + delete strokePattern; + delete fillPattern; + delete screen; + gfree(lineDash); + delete clip; +} + +void SplashState::setStrokePattern(SplashPattern *strokePatternA) { + delete strokePattern; + strokePattern = strokePatternA; +} + +void SplashState::setFillPattern(SplashPattern *fillPatternA) { + delete fillPattern; + fillPattern = fillPatternA; +} + +void SplashState::setScreen(SplashScreen *screenA) { + delete screen; + screen = screenA; +} + +void SplashState::setLineDash(SplashCoord *lineDashA, int lineDashLengthA, + SplashCoord lineDashPhaseA) { + gfree(lineDash); + lineDashLength = lineDashLengthA; + if (lineDashLength > 0) { + lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord)); + memcpy(lineDash, lineDashA, lineDashLength * sizeof(SplashCoord)); + } else { + lineDash = NULL; + } + lineDashPhase = lineDashPhaseA; +} diff --git a/rosapps/smartpdf/poppler/splash/SplashState.h b/rosapps/smartpdf/poppler/splash/SplashState.h new file mode 100644 index 00000000000..d00de08a8ef --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashState.h @@ -0,0 +1,89 @@ +//======================================================================== +// +// SplashState.h +// +//======================================================================== + +#ifndef SPLASHSTATE_H +#define SPLASHSTATE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +class SplashPattern; +class SplashScreen; +class SplashClip; + +//------------------------------------------------------------------------ +// line cap values +//------------------------------------------------------------------------ + +#define splashLineCapButt 0 +#define splashLineCapRound 1 +#define splashLineCapProjecting 2 + +//------------------------------------------------------------------------ +// line join values +//------------------------------------------------------------------------ + +#define splashLineJoinMiter 0 +#define splashLineJoinRound 1 +#define splashLineJoinBevel 2 + +//------------------------------------------------------------------------ +// SplashState +//------------------------------------------------------------------------ + +class SplashState { +public: + + // Create a new state object, initialized with default settings. + SplashState(int width, int height); + + // Copy a state object. + SplashState *copy() { return new SplashState(this); } + + ~SplashState(); + + // Set the stroke pattern. This does not copy . + void setStrokePattern(SplashPattern *strokePatternA); + + // Set the fill pattern. This does not copy . + void setFillPattern(SplashPattern *fillPatternA); + + // Set the screen. This does not copy . + void setScreen(SplashScreen *screenA); + + // Set the line dash pattern. This copies the array. + void setLineDash(SplashCoord *lineDashA, int lineDashLengthA, + SplashCoord lineDashPhaseA); + +private: + + SplashState(SplashState *state); + + SplashPattern *strokePattern; + SplashPattern *fillPattern; + SplashScreen *screen; + SplashBlendFunc blendFunc; + SplashCoord strokeAlpha; + SplashCoord fillAlpha; + SplashCoord lineWidth; + int lineCap; + int lineJoin; + SplashCoord miterLimit; + SplashCoord flatness; + SplashCoord *lineDash; + int lineDashLength; + SplashCoord lineDashPhase; + SplashClip *clip; + + SplashState *next; // used by Splash class + + friend class Splash; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashT1Font.cc b/rosapps/smartpdf/poppler/splash/SplashT1Font.cc new file mode 100644 index 00000000000..708cc261e20 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashT1Font.cc @@ -0,0 +1,264 @@ +//======================================================================== +// +// SplashT1Font.cc +// +//======================================================================== + +#include + +#if HAVE_T1LIB_H + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "SplashMath.h" +#include "SplashGlyphBitmap.h" +#include "SplashPath.h" +#include "SplashT1FontEngine.h" +#include "SplashT1FontFile.h" +#include "SplashT1Font.h" + +//------------------------------------------------------------------------ + +static Guchar bitReverse[256] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +//------------------------------------------------------------------------ +// SplashT1Font +//------------------------------------------------------------------------ + +SplashT1Font::SplashT1Font(SplashT1FontFile *fontFileA, SplashCoord *matA): + SplashFont(fontFileA, matA, ((SplashT1FontFile *)fontFileA)->engine->aa) +{ + T1_TMATRIX matrix; + BBox bbox; + SplashCoord bbx0, bby0, bbx1, bby1; + int x, y; + + t1libID = T1_CopyFont(fontFileA->t1libID); + + // compute font size + size = (float)splashSqrt(mat[2]*mat[2] + mat[3]*mat[3]); + + // transform the four corners of the font bounding box -- the min + // and max values form the bounding box of the transformed font + bbox = T1_GetFontBBox(t1libID); + bbx0 = 0.001 * bbox.llx; + bby0 = 0.001 * bbox.lly; + bbx1 = 0.001 * bbox.urx; + bby1 = 0.001 * bbox.ury; + // some fonts are completely broken, so we fake it (with values + // large enough that most glyphs should fit) + if (bbx0 == 0 && bby0 == 0 && bbx1 == 0 && bby1 == 0) { + bbx0 = bby0 = -0.5; + bbx1 = bby1 = 1.5; + } + x = (int)(mat[0] * bbx0 + mat[2] * bby0); + xMin = xMax = x; + y = (int)(mat[1] * bbx0 + mat[3] * bby0); + yMin = yMax = y; + x = (int)(mat[0] * bbx0 + mat[2] * bby1); + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + y = (int)(mat[1] * bbx0 + mat[3] * bby1); + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + x = (int)(mat[0] * bbx1 + mat[2] * bby0); + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + y = (int)(mat[1] * bbx1 + mat[3] * bby0); + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + x = (int)(mat[0] * bbx1 + mat[2] * bby1); + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + y = (int)(mat[1] * bbx1 + mat[3] * bby1); + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + // This is a kludge: some buggy PDF generators embed fonts with + // zero bounding boxes. + if (xMax == xMin) { + xMin = 0; + xMax = (int)size; + } + if (yMax == yMin) { + yMin = 0; + yMax = (int)(1.2 * size); + } + // Another kludge: an unusually large xMin or yMin coordinate is + // probably wrong. + if (xMin > 0) { + xMin = 0; + } + if (yMin > 0) { + yMin = 0; + } + // Another kludge: t1lib doesn't correctly handle fonts with + // real (non-integer) bounding box coordinates. + if (xMax - xMin > 5000) { + xMin = 0; + xMax = (int)size; + } + if (yMax - yMin > 5000) { + yMin = 0; + yMax = (int)(1.2 * size); + } + + // transform the font + matrix.cxx = (double)mat[0] / size; + matrix.cxy = (double)mat[1] / size; + matrix.cyx = (double)mat[2] / size; + matrix.cyy = (double)mat[3] / size; + T1_TransformFont(t1libID, &matrix); +} + +SplashT1Font::~SplashT1Font() { + T1_DeleteFont(t1libID); +} + +GBool SplashT1Font::getGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap) { + return SplashFont::getGlyph(c, 0, 0, bitmap); +} + +GBool SplashT1Font::makeGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap) { + GLYPH *glyph; + int n, i; + + if (aa) { + glyph = T1_AASetChar(t1libID, c, size, NULL); + } else { + glyph = T1_SetChar(t1libID, c, size, NULL); + } + if (!glyph) { + return gFalse; + } + + bitmap->x = -glyph->metrics.leftSideBearing; + bitmap->y = glyph->metrics.ascent; + bitmap->w = glyph->metrics.rightSideBearing - glyph->metrics.leftSideBearing; + bitmap->h = glyph->metrics.ascent - glyph->metrics.descent; + bitmap->aa = aa; + if (aa) { + bitmap->data = (Guchar *)glyph->bits; + bitmap->freeData = gFalse; + } else { + n = bitmap->h * ((bitmap->w + 7) >> 3); + bitmap->data = (Guchar *)gmalloc(n); + for (i = 0; i < n; ++i) { + bitmap->data[i] = bitReverse[glyph->bits[i] & 0xff]; + } + bitmap->freeData = gTrue; + } + + return gTrue; +} + +SplashPath *SplashT1Font::getGlyphPath(int c) { + SplashPath *path; + T1_OUTLINE *outline; + T1_PATHSEGMENT *seg; + T1_BEZIERSEGMENT *bez; + SplashCoord x, y, x1, y1; + GBool needClose; + + path = new SplashPath(); + if (!(outline = T1_GetCharOutline(t1libID, c, size, NULL))) { + return path; + } + x = 0; + y = 0; + needClose = gFalse; + for (seg = outline; seg; seg = seg->link) { + switch (seg->type) { + case T1_PATHTYPE_MOVE: + if (needClose) { + path->close(); + needClose = gFalse; + } + x += seg->dest.x / 65536.0; + y += seg->dest.y / 65536.0; + path->moveTo(x, y); + break; + case T1_PATHTYPE_LINE: + x += seg->dest.x / 65536.0; + y += seg->dest.y / 65536.0; + path->lineTo(x, y); + needClose = gTrue; + break; + case T1_PATHTYPE_BEZIER: + bez = (T1_BEZIERSEGMENT *)seg; + x1 = x + bez->dest.x / 65536.0; + y1 = y + bez->dest.y / 65536.0; + path->curveTo(x + bez->B.x / 65536.0, y + bez->B.y / 65536.0, + x + bez->C.x / 65536.0, y + bez->C.y / 65536.0, + x1, y1); + x = x1; + y = y1; + needClose = gTrue; + break; + } + } + if (needClose) { + path->close(); + } + T1_FreeOutline(outline); + return path; +} + +#endif // HAVE_T1LIB_H diff --git a/rosapps/smartpdf/poppler/splash/SplashT1Font.h b/rosapps/smartpdf/poppler/splash/SplashT1Font.h new file mode 100644 index 00000000000..18cd65012a9 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashT1Font.h @@ -0,0 +1,51 @@ +//======================================================================== +// +// SplashT1Font.h +// +//======================================================================== + +#ifndef SPLASHT1FONT_H +#define SPLASHT1FONT_H + +#if HAVE_T1LIB_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashFont.h" + +class SplashT1FontFile; + +//------------------------------------------------------------------------ +// SplashT1Font +//------------------------------------------------------------------------ + +class SplashT1Font: public SplashFont { +public: + + SplashT1Font(SplashT1FontFile *fontFileA, SplashCoord *matA); + + virtual ~SplashT1Font(); + + // Munge xFrac and yFrac before calling SplashFont::getGlyph. + virtual GBool getGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap); + + // Rasterize a glyph. The and values are the same + // as described for getGlyph. + virtual GBool makeGlyph(int c, int xFrac, int yFrac, + SplashGlyphBitmap *bitmap); + + // Return the path for a glyph. + virtual SplashPath *getGlyphPath(int c); + +private: + + int t1libID; // t1lib font ID + float size; +}; + +#endif // HAVE_T1LIB_H + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashT1FontEngine.cc b/rosapps/smartpdf/poppler/splash/SplashT1FontEngine.cc new file mode 100644 index 00000000000..d180a5a8fdb --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashT1FontEngine.cc @@ -0,0 +1,123 @@ +//======================================================================== +// +// SplashT1FontEngine.cc +// +//======================================================================== + +#include + +#if HAVE_T1LIB_H + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#ifndef WIN32 +# include +#endif +#include +#include "goo/GooString.h" +#include "goo/gfile.h" +#include "fofi/FoFiType1C.h" +#include "SplashT1FontFile.h" +#include "SplashT1FontEngine.h" + +#ifdef VMS +#if (__VMS_VER < 70000000) +extern "C" int unlink(char *filename); +#endif +#endif + +//------------------------------------------------------------------------ + +int SplashT1FontEngine::t1libInitCount = 0; + +//------------------------------------------------------------------------ + +static void fileWrite(void *stream, char *data, int len) { + fwrite(data, 1, len, (FILE *)stream); +} + +//------------------------------------------------------------------------ +// SplashT1FontEngine +//------------------------------------------------------------------------ + +SplashT1FontEngine::SplashT1FontEngine(GBool aaA) { + aa = aaA; +} + +SplashT1FontEngine *SplashT1FontEngine::init(GBool aaA) { + // grayVals[i] = round(i * 255 / 16) + static unsigned long grayVals[17] = { + 0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239, 255 + }; + + //~ for multithreading: need a mutex here + if (t1libInitCount == 0) { + T1_SetBitmapPad(8); + if (!T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE | + T1_NO_AFM)) { + return NULL; + } + if (aaA) { + T1_AASetBitsPerPixel(8); + T1_AASetLevel(T1_AA_HIGH); + T1_AAHSetGrayValues(grayVals); + } else { + T1_AANSetGrayValues(0, 1); + } + } + ++t1libInitCount; + + return new SplashT1FontEngine(aaA); +} + +SplashT1FontEngine::~SplashT1FontEngine() { + //~ for multithreading: need a mutex here + if (--t1libInitCount == 0) { + T1_CloseLib(); + } +} + +SplashFontFile *SplashT1FontEngine::loadType1Font(SplashFontFileID *idA, + SplashFontSrc *src, + char **enc) { + return SplashT1FontFile::loadType1Font(this, idA, src, enc); +} + +SplashFontFile *SplashT1FontEngine::loadType1CFont(SplashFontFileID *idA, + SplashFontSrc *src, + char **enc) { + FoFiType1C *ff; + GooString *tmpFileName; + FILE *tmpFile; + SplashFontFile *ret; + + SplashFontSrc *newsrc; + + if (src->isFile) + ff = FoFiType1C::load(src->fileName); + else + ff = new FoFiType1C(src->buf, src->bufLen, gFalse); + if (! ff) + return NULL; + } + tmpFileName = NULL; + if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { + delete ff; + return NULL; + } + ff->convertToType1(NULL, gTrue, &fileWrite, tmpFile); + delete ff; + fclose(tmpFile); + newsrc = new SplashFontSrc; + newsrc->setFile(tmpFileName, gTrue); + delete tmpFileName; + ret = SplashT1FontFile::loadType1Font(this, idA, newsrc, enc); + newsrc->unref(); + return ret; +} + +#endif // HAVE_T1LIB_H diff --git a/rosapps/smartpdf/poppler/splash/SplashT1FontEngine.h b/rosapps/smartpdf/poppler/splash/SplashT1FontEngine.h new file mode 100644 index 00000000000..a89f14fb566 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashT1FontEngine.h @@ -0,0 +1,51 @@ +//======================================================================== +// +// SplashT1FontEngine.h +// +//======================================================================== + +#ifndef SPLASHT1FONTENGINE_H +#define SPLASHT1FONTENGINE_H + +#if HAVE_T1LIB_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "goo/gtypes.h" + +class SplashFontFile; +class SplashFontFileID; + +//------------------------------------------------------------------------ +// SplashT1FontEngine +//------------------------------------------------------------------------ + +class SplashT1FontEngine { +public: + + static SplashT1FontEngine *init(GBool aaA); + + ~SplashT1FontEngine(); + + // Load fonts. + SplashFontFile *loadType1Font(SplashFontFileID *idA, char *fileName, + GBool deleteFile, char **enc); + SplashFontFile *loadType1CFont(SplashFontFileID *idA, char *fileName, + GBool deleteFile, char **enc); + +private: + + SplashT1FontEngine(GBool aaA); + + static int t1libInitCount; + GBool aa; + + friend class SplashT1FontFile; + friend class SplashT1Font; +}; + +#endif // HAVE_T1LIB_H + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashT1FontFile.cc b/rosapps/smartpdf/poppler/splash/SplashT1FontFile.cc new file mode 100644 index 00000000000..c5e9f5fe739 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashT1FontFile.cc @@ -0,0 +1,116 @@ +//======================================================================== +// +// SplashT1FontFile.cc +// +//======================================================================== + +#include + +#if HAVE_T1LIB_H + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "SplashT1FontEngine.h" +#include "SplashT1Font.h" +#include "SplashT1FontFile.h" + +//------------------------------------------------------------------------ +// SplashT1FontFile +//------------------------------------------------------------------------ + +SplashFontFile *SplashT1FontFile::loadType1Font(SplashT1FontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + char **encA) { + int t1libIDA; + char **encTmp; + char *encStrTmp; + int encStrSize; + char *encPtr; + int i; + GString *fileNameA; + SplashFontSrc *newsrc = NULL; + SplashFontFile *ff; + + if (! src->isFile) { + GString *tmpFileName; + FILE *tmpFile; + if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) + return NULL; + fwrite(src->buf, 1, src->bufLen, tmpFile); + fclose(tmpFile); + newsrc = new SplashFontSrc; + newsrc->setFile(tmpFileName, gTrue); + src = newsrc; + delete tmpFileName; + } + fileNameA = src->fileName; + // load the font file + if ((t1libIDA = T1_AddFont(fileNameA)) < 0) { + if (newsrc) + delete newsrc; + return NULL; + } + T1_LoadFont(t1libIDA); + + // reencode it + encStrSize = 0; + for (i = 0; i < 256; ++i) { + if (encA[i]) { + encStrSize += strlen(encA[i]) + 1; + } + } + encTmp = (char **)gmallocn(257, sizeof(char *)); + encStrTmp = (char *)gmallocn(encStrSize, sizeof(char)); + encPtr = encStrTmp; + for (i = 0; i < 256; ++i) { + if (encA[i]) { + strcpy(encPtr, encA[i]); + encTmp[i] = encPtr; + encPtr += strlen(encPtr) + 1; + } else { + encTmp[i] = ".notdef"; + } + } + encTmp[256] = "custom"; + T1_ReencodeFont(t1libIDA, encTmp); + + ff = new SplashT1FontFile(engineA, idA, src, + t1libIDA, encTmp, encStrTmp); + if (newsrc) + newsrc->unref(); + return ff; +} + +SplashT1FontFile::SplashT1FontFile(SplashT1FontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *srcA, + int t1libIDA, char **encA, char *encStrA): + SplashFontFile(idA, srcA) +{ + engine = engineA; + t1libID = t1libIDA; + enc = encA; + encStr = encStrA; +} + +SplashT1FontFile::~SplashT1FontFile() { + gfree(encStr); + gfree(enc); + T1_DeleteFont(t1libID); +} + +SplashFont *SplashT1FontFile::makeFont(SplashCoord *mat) { + SplashFont *font; + + font = new SplashT1Font(this, mat); + font->initCache(); + return font; +} + +#endif // HAVE_T1LIB_H diff --git a/rosapps/smartpdf/poppler/splash/SplashT1FontFile.h b/rosapps/smartpdf/poppler/splash/SplashT1FontFile.h new file mode 100644 index 00000000000..2ab72167a1a --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashT1FontFile.h @@ -0,0 +1,55 @@ +//======================================================================== +// +// SplashT1FontFile.h +// +//======================================================================== + +#ifndef SPLASHT1FONTFILE_H +#define SPLASHT1FONTFILE_H + +#if HAVE_T1LIB_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashFontFile.h" + +class SplashT1FontEngine; + +//------------------------------------------------------------------------ +// SplashT1FontFile +//------------------------------------------------------------------------ + +class SplashT1FontFile: public SplashFontFile { +public: + + static SplashFontFile *loadType1Font(SplashT1FontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + char **encA); + + virtual ~SplashT1FontFile(); + + // Create a new SplashT1Font, i.e., a scaled instance of this font + // file. + virtual SplashFont *makeFont(SplashCoord *mat); + +private: + + SplashT1FontFile(SplashT1FontEngine *engineA, + SplashFontFileID *idA, + SplashFontSrc *src, + int t1libIDA, char **encA, char *encStrA); + + SplashT1FontEngine *engine; + int t1libID; // t1lib font ID + char **enc; + char *encStr; + + friend class SplashT1Font; +}; + +#endif // HAVE_T1LIB_H + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashTypes.h b/rosapps/smartpdf/poppler/splash/SplashTypes.h new file mode 100644 index 00000000000..82aeb8ed835 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashTypes.h @@ -0,0 +1,140 @@ +//======================================================================== +// +// SplashTypes.h +// +//======================================================================== + +#ifndef SPLASHTYPES_H +#define SPLASHTYPES_H + +#include "goo/gtypes.h" + +//------------------------------------------------------------------------ +// coordinates +//------------------------------------------------------------------------ + +#if USE_FIXEDPOINT +#include "goo/FixedPoint.h" +typedef FixedPoint SplashCoord; +#else +typedef double SplashCoord; +#endif + +//------------------------------------------------------------------------ +// colors +//------------------------------------------------------------------------ + +enum SplashColorMode { + splashModeMono1, // 1 bit per component, 8 pixels per byte, + // MSbit is on the left + splashModeMono8, // 1 byte per component, 1 byte per pixel + splashModeAMono8, // 1 byte per component, 2 bytes per pixel: + // AMAM... + splashModeRGB8, // 1 byte per component, 3 bytes per pixel: + // RGBRGB... + splashModeBGR8, // 1 byte per component, 3 bytes per pixel: + // BGRBGR... + splashModeARGB8, // 1 byte per component, 4 bytes per pixel: + // ARGBARGB... + splashModeRGB8Qt, // 1 byte per component, 4 bytes per pixel: + // Specially hacked to use in Qt frontends + splashModeBGRA8 // 1 byte per component, 4 bytes per pixel: + // BGRABGRA... +#if SPLASH_CMYK + , + splashModeCMYK8, // 1 byte per component, 4 bytes per pixel: + // CMYKCMYK... + splashModeACMYK8 // 1 byte per component, 5 bytes per pixel: + // ACMYKACMYK +#endif +}; + +// number of components in each color mode +// (defined in SplashState.cc) +extern int splashColorModeNComps[]; + +// max number of components in any SplashColor +#if SPLASH_CMYK +# define splashMaxColorComps 5 +#else +# define splashMaxColorComps 4 +#endif + +typedef Guchar SplashColor[splashMaxColorComps]; +typedef Guchar *SplashColorPtr; + +// AMono8 +static inline Guchar splashAMono8A(SplashColorPtr am8) { return am8[0]; } +static inline Guchar splashAMono8M(SplashColorPtr am8) { return am8[1]; } + +// RGB8 +static inline Guchar splashRGB8R(SplashColorPtr rgb8) { return rgb8[0]; } +static inline Guchar splashRGB8G(SplashColorPtr rgb8) { return rgb8[1]; } +static inline Guchar splashRGB8B(SplashColorPtr rgb8) { return rgb8[2]; } + +// BGR8 +static inline Guchar splashBGR8R(SplashColorPtr bgr8) { return bgr8[2]; } +static inline Guchar splashBGR8G(SplashColorPtr bgr8) { return bgr8[1]; } +static inline Guchar splashBGR8B(SplashColorPtr bgr8) { return bgr8[0]; } + +// ARGB8 +static inline Guchar splashARGB8A(SplashColorPtr argb8) { return argb8[0]; } +static inline Guchar splashARGB8R(SplashColorPtr argb8) { return argb8[1]; } +static inline Guchar splashARGB8G(SplashColorPtr argb8) { return argb8[2]; } +static inline Guchar splashARGB8B(SplashColorPtr argb8) { return argb8[3]; } + +// ARGB8 +static inline Guchar splashBGRA8A(SplashColorPtr bgra8) { return bgra8[3]; } +static inline Guchar splashBGRA8R(SplashColorPtr bgra8) { return bgra8[2]; } +static inline Guchar splashBGRA8G(SplashColorPtr bgra8) { return bgra8[1]; } +static inline Guchar splashBGRA8B(SplashColorPtr bgra8) { return bgra8[0]; } + +#if SPLASH_CMYK +// CMYK8 +static inline Guchar splashCMYK8C(SplashColorPtr cmyk8) { return cmyk8[0]; } +static inline Guchar splashCMYK8M(SplashColorPtr cmyk8) { return cmyk8[1]; } +static inline Guchar splashCMYK8Y(SplashColorPtr cmyk8) { return cmyk8[2]; } +static inline Guchar splashCMYK8K(SplashColorPtr cmyk8) { return cmyk8[3]; } + +// ACMYK8 +static inline Guchar splashACMYK8A(SplashColorPtr acmyk8) { return acmyk8[0]; } +static inline Guchar splashACMYK8C(SplashColorPtr acmyk8) { return acmyk8[1]; } +static inline Guchar splashACMYK8M(SplashColorPtr acmyk8) { return acmyk8[2]; } +static inline Guchar splashACMYK8Y(SplashColorPtr acmyk8) { return acmyk8[3]; } +static inline Guchar splashACMYK8K(SplashColorPtr acmyk8) { return acmyk8[4]; } +#endif + +static inline void splashColorCopy(SplashColorPtr dest, SplashColorPtr src) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = src[3]; +#if SPLASH_CMYK + dest[4] = src[4]; +#endif +} + +static inline void splashColorXor(SplashColorPtr dest, SplashColorPtr src) { + dest[0] ^= src[0]; + dest[1] ^= src[1]; + dest[2] ^= src[2]; + dest[3] ^= src[3]; +#if SPLASH_CMYK + dest[4] ^= src[4]; +#endif +} + +//------------------------------------------------------------------------ +// blend functions +//------------------------------------------------------------------------ + +typedef void (*SplashBlendFunc)(SplashColorPtr src, SplashColorPtr dest, + SplashColorPtr blend, SplashColorMode cm); + +//------------------------------------------------------------------------ +// error results +//------------------------------------------------------------------------ + +typedef int SplashError; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashXPath.cc b/rosapps/smartpdf/poppler/splash/SplashXPath.cc new file mode 100644 index 00000000000..7fa0865abe7 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashXPath.cc @@ -0,0 +1,414 @@ +//======================================================================== +// +// SplashXPath.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include "goo/gmem.h" +#include "SplashMath.h" +#include "SplashPath.h" +#include "SplashXPath.h" + +//------------------------------------------------------------------------ + +#define maxCurveSplits (1 << 10) + +//------------------------------------------------------------------------ +// SplashXPath +//------------------------------------------------------------------------ + +SplashXPath::SplashXPath() { + segs = NULL; + length = size = 0; +} + +SplashXPath::SplashXPath(SplashPath *path, SplashCoord flatness, + GBool closeSubpaths) { + SplashCoord xc, yc, dx, dy, r, x0, y0, x1, y1; + int quad0, quad1, quad; + int curSubpath, n, i, j; + + segs = NULL; + length = size = 0; + + i = 0; + curSubpath = 0; + while (i < path->length) { + + // first point in subpath - skip it + if (path->flags[i] & splashPathFirst) { + curSubpath = i; + ++i; + + } else { + + // curve segment + if (path->flags[i] & splashPathCurve) { + addCurve(path->pts[i-1].x, path->pts[i-1].y, + path->pts[i ].x, path->pts[i ].y, + path->pts[i+1].x, path->pts[i+1].y, + path->pts[i+2].x, path->pts[i+2].y, + flatness, + (path->flags[i-1] & splashPathFirst), + (path->flags[i+2] & splashPathLast), + !closeSubpaths && + (path->flags[i-1] & splashPathFirst) && + !(path->flags[i-1] & splashPathClosed), + !closeSubpaths && + (path->flags[i+2] & splashPathLast) && + !(path->flags[i+2] & splashPathClosed)); + i += 3; + + // clockwise circular arc + } else if (path->flags[i] & splashPathArcCW) { + xc = path->pts[i].x; + yc = path->pts[i].y; + dx = path->pts[i+1].x - xc; + dy = path->pts[i+1].y - yc; + r = splashSqrt(dx * dx + dy * dy); + if (path->pts[i-1].x < xc && path->pts[i-1].y <= yc) { + quad0 = 0; + } else if (path->pts[i-1].x >= xc && path->pts[i-1].y < yc) { + quad0 = 1; + } else if (path->pts[i-1].x > xc && path->pts[i-1].y >= yc) { + quad0 = 2; + } else { + quad0 = 3; + } + if (path->pts[i+1].x <= xc && path->pts[i+1].y < yc) { + quad1 = 0; + } else if (path->pts[i+1].x > xc && path->pts[i+1].y <= yc) { + quad1 = 1; + } else if (path->pts[i+1].x >= xc && path->pts[i+1].y > yc) { + quad1 = 2; + } else { + quad1 = 3; + } + n = 0; // make gcc happy + if (quad0 == quad1) { + switch (quad0) { + case 0: + case 1: n = path->pts[i-1].x < path->pts[i+1].x ? 0 : 4; break; + case 2: + case 3: n = path->pts[i-1].x > path->pts[i+1].x ? 0 : 4; break; + } + } else { + n = (quad1 - quad0) & 3; + } + x0 = path->pts[i-1].x; + y0 = path->pts[i-1].y; + x1 = y1 = 0; // make gcc happy + quad = quad0; + for (j = 0; j < n; ++j) { + switch (quad) { + case 0: x1 = xc; y1 = yc - r; break; + case 1: x1 = xc + r; y1 = yc; break; + case 2: x1 = xc; y1 = yc + r; break; + case 3: x1 = xc - r; y1 = yc; break; + } + addArc(x0, y0, x1, y1, + xc, yc, r, quad, flatness, + quad == quad0 && (path->flags[i-1] & splashPathFirst), + gFalse, + quad == quad0 && !closeSubpaths && + (path->flags[i-1] & splashPathFirst) && + !(path->flags[i-1] & splashPathClosed), + gFalse); + x0 = x1; + y0 = y1; + quad = (quad + 1) & 3; + } + addArc(x0, y0, path->pts[i+1].x, path->pts[i+1].y, + xc, yc, r, quad, flatness, + quad == quad0 && (path->flags[i-1] & splashPathFirst), + (path->flags[i+1] & splashPathLast), + quad == quad0 && !closeSubpaths && + (path->flags[i-1] & splashPathFirst) && + !(path->flags[i-1] & splashPathClosed), + !closeSubpaths && + (path->flags[i+1] & splashPathLast) && + !(path->flags[i+1] & splashPathClosed)); + i += 2; + + // line segment + } else { + addSegment(path->pts[i-1].x, path->pts[i-1].y, + path->pts[i].x, path->pts[i].y, + path->flags[i-1] & splashPathFirst, + path->flags[i] & splashPathLast, + !closeSubpaths && + (path->flags[i-1] & splashPathFirst) && + !(path->flags[i-1] & splashPathClosed), + !closeSubpaths && + (path->flags[i] & splashPathLast) && + !(path->flags[i] & splashPathClosed)); + ++i; + } + + // close a subpath + if (closeSubpaths && + (path->flags[i-1] & splashPathLast) && + (path->pts[i-1].x != path->pts[curSubpath].x || + path->pts[i-1].y != path->pts[curSubpath]. y)) { + addSegment(path->pts[i-1].x, path->pts[i-1].y, + path->pts[curSubpath].x, path->pts[curSubpath].y, + gFalse, gTrue, gFalse, gFalse); + } + } + } +} + +SplashXPath::SplashXPath(SplashXPath *xPath) { + length = xPath->length; + size = xPath->size; + segs = (SplashXPathSeg *)gmallocn(size, sizeof(SplashXPathSeg)); + memcpy(segs, xPath->segs, length * sizeof(SplashXPathSeg)); +} + +SplashXPath::~SplashXPath() { + gfree(segs); +} + +// Add space for more segments +void SplashXPath::grow(int nSegs) { + if (length + nSegs > size) { + if (size == 0) { + size = 32; + } + while (size < length + nSegs) { + size *= 2; + } + segs = (SplashXPathSeg *)greallocn(segs, size, sizeof(SplashXPathSeg)); + } +} + +void SplashXPath::addCurve(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1, + SplashCoord x2, SplashCoord y2, + SplashCoord x3, SplashCoord y3, + SplashCoord flatness, + GBool first, GBool last, GBool end0, GBool end1) { + SplashCoord cx[maxCurveSplits + 1][3]; + SplashCoord cy[maxCurveSplits + 1][3]; + int cNext[maxCurveSplits + 1]; + SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh; + SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh; + SplashCoord dx, dy, mx, my, d1, d2, flatness2; + int p1, p2, p3; + + flatness2 = flatness * flatness; + + // initial segment + p1 = 0; + p2 = maxCurveSplits; + cx[p1][0] = x0; cy[p1][0] = y0; + cx[p1][1] = x1; cy[p1][1] = y1; + cx[p1][2] = x2; cy[p1][2] = y2; + cx[p2][0] = x3; cy[p2][0] = y3; + cNext[p1] = p2; + + while (p1 < maxCurveSplits) { + + // get the next segment + xl0 = cx[p1][0]; yl0 = cy[p1][0]; + xx1 = cx[p1][1]; yy1 = cy[p1][1]; + xx2 = cx[p1][2]; yy2 = cy[p1][2]; + p2 = cNext[p1]; + xr3 = cx[p2][0]; yr3 = cy[p2][0]; + + // compute the distances from the control points to the + // midpoint of the straight line (this is a bit of a hack, but + // it's much faster than computing the actual distances to the + // line) + mx = (xl0 + xr3) * 0.5; + my = (yl0 + yr3) * 0.5; + dx = xx1 - mx; + dy = yy1 - my; + d1 = dx*dx + dy*dy; + dx = xx2 - mx; + dy = yy2 - my; + d2 = dx*dx + dy*dy; + + // if the curve is flat enough, or no more subdivisions are + // allowed, add the straight line segment + if (p2 - p1 == 1 || (d1 <= flatness2 && d2 <= flatness2)) { + addSegment(xl0, yl0, xr3, yr3, + p1 == 0 && first, + p2 == maxCurveSplits && last, + p1 == 0 && end0, + p2 == maxCurveSplits && end1); + p1 = p2; + + // otherwise, subdivide the curve + } else { + xl1 = (xl0 + xx1) * 0.5; + yl1 = (yl0 + yy1) * 0.5; + xh = (xx1 + xx2) * 0.5; + yh = (yy1 + yy2) * 0.5; + xl2 = (xl1 + xh) * 0.5; + yl2 = (yl1 + yh) * 0.5; + xr2 = (xx2 + xr3) * 0.5; + yr2 = (yy2 + yr3) * 0.5; + xr1 = (xh + xr2) * 0.5; + yr1 = (yh + yr2) * 0.5; + xr0 = (xl2 + xr1) * 0.5; + yr0 = (yl2 + yr1) * 0.5; + // add the new subdivision points + p3 = (p1 + p2) / 2; + cx[p1][1] = xl1; cy[p1][1] = yl1; + cx[p1][2] = xl2; cy[p1][2] = yl2; + cNext[p1] = p3; + cx[p3][0] = xr0; cy[p3][0] = yr0; + cx[p3][1] = xr1; cy[p3][1] = yr1; + cx[p3][2] = xr2; cy[p3][2] = yr2; + cNext[p3] = p2; + } + } +} + +void SplashXPath::addArc(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1, + SplashCoord xc, SplashCoord yc, + SplashCoord r, int quad, + SplashCoord flatness, + GBool first, GBool last, GBool end0, GBool end1) { + SplashCoord px[maxCurveSplits + 1]; + SplashCoord py[maxCurveSplits + 1]; + int pNext[maxCurveSplits + 1]; + SplashCoord r2, flatness2; + SplashCoord xx0, yy0, xx1, yy1, xm, ym, t, dx, dy; + int p1, p2, p3; + + r2 = r * r; + flatness2 = flatness * flatness; + + // initial segment + p1 = 0; + p2 = maxCurveSplits; + px[p1] = x0; py[p1] = y0; + px[p2] = x1; py[p2] = y1; + pNext[p1] = p2; + + while (p1 < maxCurveSplits) { + + // get the next segment + xx0 = px[p1]; yy0 = py[p1]; + p2 = pNext[p1]; + xx1 = px[p2]; yy1 = py[p2]; + + // compute the arc midpoint + t = (xx0 - xc) * (xx1 - xc) - (yy0 - yc) * (yy1 - yc); + xm = splashSqrt((SplashCoord)0.5 * (r2 + t)); + ym = splashSqrt((SplashCoord)0.5 * (r2 - t)); + switch (quad) { + case 0: xm = xc - xm; ym = yc - ym; break; + case 1: xm = xc + xm; ym = yc - ym; break; + case 2: xm = xc + xm; ym = yc + ym; break; + case 3: xm = xc - xm; ym = yc + ym; break; + } + + // compute distance from midpoint of straight segment to midpoint + // of arc + dx = (SplashCoord)0.5 * (xx0 + xx1) - xm; + dy = (SplashCoord)0.5 * (yy0 + yy1) - ym; + + // if the arc is flat enough, or no more subdivisions are allowed, + // add the straight line segment + if (p2 - p1 == 1 || dx * dx + dy * dy <= flatness2) { + addSegment(xx0, yy0, xx1, yy1, + p1 == 0 && first, + p2 == maxCurveSplits && last, + p1 == 0 && end0, + p2 == maxCurveSplits && end1); + p1 = p2; + + // otherwise, subdivide the arc + } else { + p3 = (p1 + p2) / 2; + px[p3] = xm; + py[p3] = ym; + pNext[p1] = p3; + pNext[p3] = p2; + } + } +} + +void SplashXPath::addSegment(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1, + GBool first, GBool last, GBool end0, GBool end1) { + grow(1); + segs[length].x0 = x0; + segs[length].y0 = y0; + segs[length].x1 = x1; + segs[length].y1 = y1; + segs[length].flags = 0; + if (first) { + segs[length].flags |= splashXPathFirst; + } + if (last) { + segs[length].flags |= splashXPathLast; + } + if (end0) { + segs[length].flags |= splashXPathEnd0; + } + if (end1) { + segs[length].flags |= splashXPathEnd1; + } + if (y1 == y0) { + segs[length].dxdy = segs[length].dydx = 0; + segs[length].flags |= splashXPathHoriz; + if (x1 == x0) { + segs[length].flags |= splashXPathVert; + } + } else if (x1 == x0) { + segs[length].dxdy = segs[length].dydx = 0; + segs[length].flags |= splashXPathVert; + } else { + segs[length].dxdy = (x1 - x0) / (y1 - y0); + segs[length].dydx = (SplashCoord)1 / segs[length].dxdy; + } + if (y0 > y1) { + segs[length].flags |= splashXPathFlip; + } + ++length; +} + +static int cmpXPathSegs(const void *arg0, const void *arg1) { + SplashXPathSeg *seg0 = (SplashXPathSeg *)arg0; + SplashXPathSeg *seg1 = (SplashXPathSeg *)arg1; + SplashCoord x0, y0, x1, y1; + + if (seg0->flags & splashXPathFlip) { + x0 = seg0->x1; + y0 = seg0->y1; + } else { + x0 = seg0->x0; + y0 = seg0->y0; + } + if (seg1->flags & splashXPathFlip) { + x1 = seg1->x1; + y1 = seg1->y1; + } else { + x1 = seg1->x0; + y1 = seg1->y0; + } + if (y0 != y1) { + return (y0 > y1) ? 1 : -1; + } + if (x0 != x1) { + return (x0 > x1) ? 1 : -1; + } + return 0; +} + +void SplashXPath::sort() { + qsort(segs, length, sizeof(SplashXPathSeg), &cmpXPathSegs); +} diff --git a/rosapps/smartpdf/poppler/splash/SplashXPath.h b/rosapps/smartpdf/poppler/splash/SplashXPath.h new file mode 100644 index 00000000000..a72d5633bd8 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashXPath.h @@ -0,0 +1,90 @@ +//======================================================================== +// +// SplashXPath.h +// +//======================================================================== + +#ifndef SPLASHXPATH_H +#define SPLASHXPATH_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +class SplashPath; + +//------------------------------------------------------------------------ +// SplashXPathSeg +//------------------------------------------------------------------------ + +struct SplashXPathSeg { + SplashCoord x0, y0; // first endpoint + SplashCoord x1, y1; // second endpoint + SplashCoord dxdy; // slope: delta-x / delta-y + SplashCoord dydx; // slope: delta-y / delta-x + Guint flags; +}; + +#define splashXPathFirst 0x01 // first segment of a subpath +#define splashXPathLast 0x02 // last segment of a subpath +#define splashXPathEnd0 0x04 // first endpoint is end of an open subpath +#define splashXPathEnd1 0x08 // second endpoint is end of an open subpath +#define splashXPathHoriz 0x10 // segment is vertical (y0 == y1) + // (dxdy is undef) +#define splashXPathVert 0x20 // segment is horizontal (x0 == x1) + // (dydx is undef) +#define splashXPathFlip 0x40 // y0 > y1 + +//------------------------------------------------------------------------ +// SplashXPath +//------------------------------------------------------------------------ + +class SplashXPath { +public: + + // Expands (converts to segments) and flattens (converts curves to + // lines) . If is true, closes all open + // subpaths. + SplashXPath(SplashPath *path, SplashCoord flatness, + GBool closeSubpaths); + + // Copy an expanded path. + SplashXPath *copy() { return new SplashXPath(this); } + + ~SplashXPath(); + + // Sort by upper coordinate (lower y), in y-major order. + void sort(); + +private: + + SplashXPath(); + SplashXPath(SplashXPath *xPath); + void grow(int nSegs); + void addCurve(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1, + SplashCoord x2, SplashCoord y2, + SplashCoord x3, SplashCoord y3, + SplashCoord flatness, + GBool first, GBool last, GBool end0, GBool end1); + void addArc(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1, + SplashCoord xc, SplashCoord yc, + SplashCoord r, int quad, + SplashCoord flatness, + GBool first, GBool last, GBool end0, GBool end1); + void addSegment(SplashCoord x0, SplashCoord y0, + SplashCoord x1, SplashCoord y1, + GBool first, GBool last, GBool end0, GBool end1); + + SplashXPathSeg *segs; + int length, size; // length and size of segs array + + friend class SplashXPathScanner; + friend class SplashClip; + friend class Splash; +}; + +#endif diff --git a/rosapps/smartpdf/poppler/splash/SplashXPathScanner.cc b/rosapps/smartpdf/poppler/splash/SplashXPathScanner.cc new file mode 100644 index 00000000000..9b1c1c4f9af --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashXPathScanner.cc @@ -0,0 +1,285 @@ +//======================================================================== +// +// SplashXPathScanner.cc +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include "goo/gmem.h" +#include "SplashMath.h" +#include "SplashXPath.h" +#include "SplashXPathScanner.h" + +//------------------------------------------------------------------------ + +struct SplashIntersect { + int x0, x1; // intersection of segment with [y, y+1) + int count; // EO/NZWN counter increment +}; + +static int cmpIntersect(const void *p0, const void *p1) { + return ((SplashIntersect *)p0)->x0 - ((SplashIntersect *)p1)->x0; +} + +//------------------------------------------------------------------------ +// SplashXPathScanner +//------------------------------------------------------------------------ + +SplashXPathScanner::SplashXPathScanner(SplashXPath *xPathA, GBool eoA) { + SplashXPathSeg *seg; + SplashCoord xMinFP, yMinFP, xMaxFP, yMaxFP; + int i; + + xPath = xPathA; + eo = eoA; + + // compute the bbox + if (xPath->length == 0) { + xMin = yMin = 1; + xMax = yMax = 0; + } else { + seg = &xPath->segs[0]; + if (seg->x0 <= seg->x1) { + xMinFP = seg->x0; + xMaxFP = seg->x1; + } else { + xMinFP = seg->x1; + xMaxFP = seg->x0; + } + if (seg->flags & splashXPathFlip) { + yMinFP = seg->y1; + yMaxFP = seg->y0; + } else { + yMinFP = seg->y0; + yMaxFP = seg->y1; + } + for (i = 1; i < xPath->length; ++i) { + seg = &xPath->segs[i]; + if (seg->x0 < xMinFP) { + xMinFP = seg->x0; + } else if (seg->x0 > xMaxFP) { + xMaxFP = seg->x0; + } + if (seg->x1 < xMinFP) { + xMinFP = seg->x1; + } else if (seg->x1 > xMaxFP) { + xMaxFP = seg->x1; + } + if (seg->flags & splashXPathFlip) { + if (seg->y0 > yMaxFP) { + yMaxFP = seg->y0; + } + } else { + if (seg->y1 > yMaxFP) { + yMaxFP = seg->y1; + } + } + } + xMin = splashFloor(xMinFP); + xMax = splashFloor(xMaxFP); + yMin = splashFloor(yMinFP); + yMax = splashFloor(yMaxFP); + } + + interY = yMin - 1; + xPathIdx = 0; + inter = NULL; + interLen = interSize = 0; +} + +SplashXPathScanner::~SplashXPathScanner() { + gfree(inter); +} + +void SplashXPathScanner::getSpanBounds(int y, int *spanXMin, int *spanXMax) { + if (interY != y) { + computeIntersections(y); + } + if (interLen > 0) { + *spanXMin = inter[0].x0; + *spanXMax = inter[interLen - 1].x1; + } else { + *spanXMin = xMax + 1; + *spanXMax = xMax; + } +} + +GBool SplashXPathScanner::test(int x, int y) { + int count, i; + + if (interY != y) { + computeIntersections(y); + } + count = 0; + for (i = 0; i < interLen && inter[i].x0 <= x; ++i) { + if (x <= inter[i].x1) { + return gTrue; + } + count += inter[i].count; + } + return eo ? (count & 1) : (count != 0); +} + +GBool SplashXPathScanner::testSpan(int x0, int x1, int y) { + int count, xx1, i; + + if (interY != y) { + computeIntersections(y); + } + + count = 0; + for (i = 0; i < interLen && inter[i].x1 < x0; ++i) { + count += inter[i].count; + } + + // invariant: the subspan [x0,xx1] is inside the path + xx1 = x0 - 1; + while (xx1 < x1) { + if (i >= interLen) { + return gFalse; + } + if (inter[i].x0 > xx1 + 1 && + !(eo ? (count & 1) : (count != 0))) { + return gFalse; + } + if (inter[i].x1 > xx1) { + xx1 = inter[i].x1; + } + count += inter[i].count; + ++i; + } + + return gTrue; +} + +GBool SplashXPathScanner::getNextSpan(int y, int *x0, int *x1) { + int xx0, xx1; + + if (interY != y) { + computeIntersections(y); + } + if (interIdx >= interLen) { + return gFalse; + } + xx0 = inter[interIdx].x0; + xx1 = inter[interIdx].x1; + interCount += inter[interIdx].count; + ++interIdx; + while (interIdx < interLen && + (inter[interIdx].x0 <= xx1 || + (eo ? (interCount & 1) : (interCount != 0)))) { + if (inter[interIdx].x1 > xx1) { + xx1 = inter[interIdx].x1; + } + interCount += inter[interIdx].count; + ++interIdx; + } + *x0 = xx0; + *x1 = xx1; + return gTrue; +} + +void SplashXPathScanner::computeIntersections(int y) { + SplashCoord xSegMin, xSegMax, ySegMin, ySegMax, xx0, xx1; + SplashXPathSeg *seg; + int i, j; + + // find the first segment that intersects [y, y+1) + i = (y >= interY) ? xPathIdx : 0; + while (i < xPath->length && + xPath->segs[i].y0 < y && xPath->segs[i].y1 < y) { + ++i; + } + xPathIdx = i; + + // find all of the segments that intersect [y, y+1) and create an + // Intersect element for each one + interLen = 0; + for (j = i; j < xPath->length; ++j) { + seg = &xPath->segs[j]; + if (seg->flags & splashXPathFlip) { + ySegMin = seg->y1; + ySegMax = seg->y0; + } else { + ySegMin = seg->y0; + ySegMax = seg->y1; + } + + // ensure that: ySegMin < y+1 + // y <= ySegMax + if (ySegMin >= y + 1) { + break; + } + if (ySegMax < y) { + continue; + } + + if (interLen == interSize) { + if (interSize == 0) { + interSize = 16; + } else { + interSize *= 2; + } + inter = (SplashIntersect *)greallocn(inter, interSize, + sizeof(SplashIntersect)); + } + + if (seg->flags & splashXPathHoriz) { + xx0 = seg->x0; + xx1 = seg->x1; + } else if (seg->flags & splashXPathVert) { + xx0 = xx1 = seg->x0; + } else { + if (seg->x0 < seg->x1) { + xSegMin = seg->x0; + xSegMax = seg->x1; + } else { + xSegMin = seg->x1; + xSegMax = seg->x0; + } + // intersection with top edge + xx0 = seg->x0 + ((SplashCoord)y - seg->y0) * seg->dxdy; + // intersection with bottom edge + xx1 = seg->x0 + ((SplashCoord)y + 1 - seg->y0) * seg->dxdy; + // the segment may not actually extend to the top and/or bottom edges + if (xx0 < xSegMin) { + xx0 = xSegMin; + } else if (xx0 > xSegMax) { + xx0 = xSegMax; + } + if (xx1 < xSegMin) { + xx1 = xSegMin; + } else if (xx1 > xSegMax) { + xx1 = xSegMax; + } + } + if (xx0 < xx1) { + inter[interLen].x0 = splashFloor(xx0); + inter[interLen].x1 = splashFloor(xx1); + } else { + inter[interLen].x0 = splashFloor(xx1); + inter[interLen].x1 = splashFloor(xx0); + } + if (ySegMin <= y && + (SplashCoord)y < ySegMax && + !(seg->flags & splashXPathHoriz)) { + inter[interLen].count = eo ? 1 + : (seg->flags & splashXPathFlip) ? 1 : -1; + } else { + inter[interLen].count = 0; + } + ++interLen; + } + + qsort(inter, interLen, sizeof(SplashIntersect), &cmpIntersect); + + interY = y; + interIdx = 0; + interCount = 0; +} diff --git a/rosapps/smartpdf/poppler/splash/SplashXPathScanner.h b/rosapps/smartpdf/poppler/splash/SplashXPathScanner.h new file mode 100644 index 00000000000..169d4b0c123 --- /dev/null +++ b/rosapps/smartpdf/poppler/splash/SplashXPathScanner.h @@ -0,0 +1,72 @@ +//======================================================================== +// +// SplashXPathScanner.h +// +//======================================================================== + +#ifndef SPLASHXPATHSCANNER_H +#define SPLASHXPATHSCANNER_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include "SplashTypes.h" + +class SplashXPath; +struct SplashIntersect; + +//------------------------------------------------------------------------ +// SplashXPathScanner +//------------------------------------------------------------------------ + +class SplashXPathScanner { +public: + + // Create a new SplashXPathScanner object. must be sorted. + SplashXPathScanner(SplashXPath *xPathA, GBool eoA); + + ~SplashXPathScanner(); + + // Return the path's bounding box. + void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) + { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } + + // Return the min/max x values for the span at . + void getSpanBounds(int y, int *spanXMin, int *spanXMax); + + // Returns true if (,) is inside the path. + GBool test(int x, int y); + + // Returns true if the entire span ([,], ) is inside the + // path. + GBool testSpan(int x0, int x1, int y); + + // Returns the next span inside the path at . If is + // different than the previous call to getNextSpan, this returns the + // first span at ; otherwise it returns the next span (relative + // to the previous call to getNextSpan). Returns false if there are + // no more spans at . + GBool getNextSpan(int y, int *x0, int *x1); + +private: + + void computeIntersections(int y); + + SplashXPath *xPath; + GBool eo; + int xMin, yMin, xMax, yMax; + + int interY; // current y value + int interIdx; // current index into - used by + // getNextSpan + int interCount; // current EO/NZWN counter - used by + // getNextSpan + int xPathIdx; // current index into - used by + // computeIntersections + SplashIntersect *inter; // intersections array for + int interLen; // number of intersections in + int interSize; // size of the array +}; + +#endif diff --git a/rosapps/smartpdf/poppler/test/Makefile.am b/rosapps/smartpdf/poppler/test/Makefile.am new file mode 100644 index 00000000000..a1c3337495d --- /dev/null +++ b/rosapps/smartpdf/poppler/test/Makefile.am @@ -0,0 +1,69 @@ +if BUILD_GTK_TEST + +if BUILD_SPLASH_OUTPUT + +gtk_splash_test = \ + gtk-splash-test + +splash_includes = \ + -I$(top_srcdir)/splash + +endif + +if BUILD_CAIRO_OUTPUT + +gtk_cairo_test = \ + gtk-cairo-test + +pdf_inspector = \ + pdf_inspector + +cairo_includes = \ + $(CAIRO_CFLAGS) \ + $(FREETYPE_CFLAGS) + +endif + +endif + + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/poppler \ + -I$(top_srcdir)/glib \ + -I$(top_builddir)/glib \ + $(cairo_includes) \ + $(GTK_TEST_CFLAGS) \ + $(FONTCONFIG_CFLAGS) + +noinst_PROGRAMS = $(gtk_splash_test) $(gtk_cairo_test) $(pdf_inspector) + +gtk_splash_test_SOURCES = \ + gtk-splash-test.cc + +gtk_splash_test_LDADD = \ + $(top_builddir)/poppler/libpoppler.la \ + $(GTK_TEST_LIBS) + +gtk_cairo_test_SOURCES = \ + gtk-cairo-test.cc + +gtk_cairo_test_LDADD = \ + $(top_builddir)/poppler/libpoppler.la \ + $(top_builddir)/glib/libpoppler-glib.la \ + $(CAIRO_LIBS) \ + $(GTK_TEST_LIBS) \ + $(FONTCONFIG_LIBS) + +pdf_inspector_SOURCES = \ + pdf-inspector.cc + +pdf_inspector_LDADD = \ + $(top_builddir)/poppler/libpoppler.la \ + $(top_builddir)/poppler/libpoppler-cairo.la \ + $(CAIRO_LIBS) \ + $(FREETYPE_LIBS) \ + $(GTK_TEST_LIBS) + +EXTRA_DIST = \ + pdf-operators.c diff --git a/rosapps/smartpdf/poppler/test/gtk-cairo-test.cc b/rosapps/smartpdf/poppler/test/gtk-cairo-test.cc new file mode 100644 index 00000000000..2049d7200bf --- /dev/null +++ b/rosapps/smartpdf/poppler/test/gtk-cairo-test.cc @@ -0,0 +1,202 @@ +//======================================================================== +// +// GDKSplashOutputDev.cc +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, Inc. (GDK port) +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include +#include + +typedef struct +{ + GtkWidget *window; + GtkWidget *sw; + GtkWidget *drawing_area; + GtkWidget *spin_button; + PopplerPage *page; + PopplerDocument *document; + cairo_surface_t *surface; + int *window_count; +} View; + +static void +drawing_area_expose (GtkWidget *drawing_area, + GdkEventExpose *event, + void *data) +{ + View *v = (View*) data; + GdkRectangle document; + GdkRectangle draw; + cairo_t *cr; + + gdk_window_clear (drawing_area->window); + cr = gdk_cairo_create (drawing_area->window); + + cairo_set_source_surface (cr, v->surface, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); +} + +static void +view_set_page (View *v, int page) +{ + int err; + int w, h; + double width, height; + cairo_t *cr; + + v->page = poppler_document_get_page (v->document, page); + poppler_page_get_size (v->page, &width, &height); + w = (int) ceil(width); + h = (int) ceil(height); + cairo_surface_destroy (v->surface); + v->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + cr = cairo_create (v->surface); + poppler_page_render (v->page, cr); + cairo_destroy (cr); + gtk_widget_set_size_request (v->drawing_area, w, h); + gtk_widget_queue_draw (v->drawing_area); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (v->spin_button), page); +} + +static void +redraw_callback (void *data) +{ + View *v = (View*) data; + + gtk_widget_queue_draw (v->drawing_area); +} + +static void +page_changed_callback (GtkSpinButton *button, View *v) +{ + int page; + + page = gtk_spin_button_get_value_as_int (button); + view_set_page (v, page); +} + +static void +destroy_window_callback (GtkWindow *window, View *v) +{ + if (--(*v->window_count) == 0) + gtk_main_quit(); +} + +static View* +view_new (const char *filename, int *window_count) +{ + View *v; + GtkWidget *window; + GtkWidget *drawing_area; + GtkWidget *sw; + GtkWidget *vbox, *hbox; + GtkWidget *spin_button; + int n_pages; + + v = g_new0 (View, 1); + + v->document = poppler_document_new_from_file (filename, NULL, NULL); + if (v->document == NULL) + return NULL; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + vbox = gtk_vbox_new(FALSE, 5); + + gtk_container_add (GTK_CONTAINER (window), vbox); + drawing_area = gtk_drawing_area_new (); + + sw = gtk_scrolled_window_new (NULL, NULL); + + gtk_box_pack_end (GTK_BOX (vbox), sw, TRUE, TRUE, 0); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), + drawing_area); + + n_pages = poppler_document_get_n_pages (v->document); + spin_button = gtk_spin_button_new_with_range (0, n_pages - 1, 1); + g_signal_connect (G_OBJECT (spin_button), "value-changed", + G_CALLBACK (page_changed_callback), v); + hbox = gtk_hbox_new (FALSE, 5); + gtk_box_pack_end (GTK_BOX (hbox), spin_button, FALSE, TRUE, 0); + + gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, TRUE, 0); + + gtk_widget_show_all (window); + gtk_widget_realize (window); + + v->window = window; + v->drawing_area = drawing_area; + v->sw = sw; + v->window_count = window_count; + v->spin_button = spin_button; + + g_signal_connect (drawing_area, + "expose_event", + G_CALLBACK (drawing_area_expose), + (void*) v); + + g_signal_connect (window, + "destroy", + G_CALLBACK (destroy_window_callback), + (void*) v); + + return v; +} + +static int option_page = 0; +static GOptionEntry demo_options[] = { + { "page", 0, 0, G_OPTION_ARG_INT, &option_page, "Page number", "PAGE" }, + { NULL } +}; + +int +main (int argc, char *argv []) +{ + View *v; + int i, window_count; + GOptionContext *ctx; + + ctx = g_option_context_new("FILENAME ..."); + g_option_context_add_main_entries(ctx, demo_options, "main"); + g_option_context_parse(ctx, &argc, &argv, NULL); + g_option_context_free(ctx); + + gtk_init (&argc, &argv); + + if (argc == 1) + { + fprintf (stderr, "usage: %s PDF-FILES...\n", g_basename (argv[0])); + return -1; + } + + window_count = 0; + for (i = 1; i < argc; i++) { + v = view_new (argv[i], &window_count); + if (v == NULL) { + g_printerr ("Error loading %s\n", argv[i]); + continue; + } + + view_set_page (v, option_page); + window_count++; + } + + if (window_count > 0) + gtk_main (); + + return 0; +} diff --git a/rosapps/smartpdf/poppler/test/gtk-splash-test.cc b/rosapps/smartpdf/poppler/test/gtk-splash-test.cc new file mode 100644 index 00000000000..d809f5364d4 --- /dev/null +++ b/rosapps/smartpdf/poppler/test/gtk-splash-test.cc @@ -0,0 +1,309 @@ +//======================================================================== +// +// GDKSplashOutputDev.cc +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, Inc. (GDK port) +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include "Object.h" +#include "SplashOutputDev.h" +#include "GfxState.h" + +#include + +#include "PDFDoc.h" +#include "GlobalParams.h" +#include "ErrorCodes.h" +#include + +//------------------------------------------------------------------------ + +#define xOutMaxRGBCube 6 // max size of RGB color cube + +//------------------------------------------------------------------------ +// GDKSplashOutputDev +//------------------------------------------------------------------------ + +class GDKSplashOutputDev: public SplashOutputDev { +public: + + GDKSplashOutputDev(GdkScreen *screen, + void (*redrawCbkA)(void *data), + void *redrawCbkDataA, SplashColor sc); + + virtual ~GDKSplashOutputDev(); + + //----- initialization and control + + // End a page. + virtual void endPage(); + + // Dump page contents to display. + virtual void dump(); + + //----- update text state + virtual void updateFont(GfxState *state); + + //----- special access + + // Clear out the document (used when displaying an empty window). + void clear(); + + // Copy the rectangle (srcX, srcY, width, height) to (destX, destY) + // in destDC. + void redraw(int srcX, int srcY, + GdkDrawable *drawable, + int destX, int destY, + int width, int height); + +private: + + int incrementalUpdate; + void (*redrawCbk)(void *data); + void *redrawCbkData; +}; + +//------------------------------------------------------------------------ +// Constants and macros +//------------------------------------------------------------------------ + +#define xoutRound(x) ((int)(x + 0.5)) + +//------------------------------------------------------------------------ +// GDKSplashOutputDev +//------------------------------------------------------------------------ + +GDKSplashOutputDev::GDKSplashOutputDev(GdkScreen *screen, + void (*redrawCbkA)(void *data), + void *redrawCbkDataA, SplashColor sc): + SplashOutputDev(splashModeRGB8, 4, gFalse, sc), + incrementalUpdate (1) +{ + redrawCbk = redrawCbkA; + redrawCbkData = redrawCbkDataA; +} + +GDKSplashOutputDev::~GDKSplashOutputDev() { +} + +void GDKSplashOutputDev::clear() { + startDoc(NULL); + startPage(0, NULL); +} + +void GDKSplashOutputDev::endPage() { + SplashOutputDev::endPage(); + if (!incrementalUpdate) { + (*redrawCbk)(redrawCbkData); + } +} + +void GDKSplashOutputDev::dump() { + if (incrementalUpdate && redrawCbk) { + (*redrawCbk)(redrawCbkData); + } +} + +void GDKSplashOutputDev::updateFont(GfxState *state) { + SplashOutputDev::updateFont(state); +} + +void GDKSplashOutputDev::redraw(int srcX, int srcY, + GdkDrawable *drawable, + int destX, int destY, + int width, int height) { + GdkGC *gc; + int gdk_rowstride; + + gdk_rowstride = getBitmap()->getRowSize(); + gc = gdk_gc_new (drawable); + + gdk_draw_rgb_image (drawable, gc, + destX, destY, + width, height, + GDK_RGB_DITHER_NORMAL, + getBitmap()->getDataPtr() + srcY * gdk_rowstride + srcX * 3, + gdk_rowstride); + + g_object_unref (gc); +} + + +typedef struct +{ + GtkWidget *window; + GtkWidget *sw; + GtkWidget *drawing_area; + GDKSplashOutputDev *out; + PDFDoc *doc; +} View; + +static void +drawing_area_expose (GtkWidget *drawing_area, + GdkEventExpose *event, + void *data) +{ + View *v = (View*) data; + GdkRectangle document; + GdkRectangle draw; + + gdk_window_clear (drawing_area->window); + + document.x = 0; + document.y = 0; + document.width = v->out->getBitmapWidth(); + document.height = v->out->getBitmapHeight(); + + if (gdk_rectangle_intersect (&document, &event->area, &draw)) + { + v->out->redraw (draw.x, draw.y, + drawing_area->window, + draw.x, draw.y, + draw.width, draw.height); + } +} + +static int +view_load (View *v, + const char *filename) +{ + PDFDoc *newDoc; + int err; + GooString *filename_g; + int w, h; + + filename_g = new GooString (filename); + + // open the PDF file + newDoc = new PDFDoc(filename_g, 0, 0); + + delete filename_g; + + if (!newDoc->isOk()) + { + err = newDoc->getErrorCode(); + delete newDoc; + return err; + } + + if (v->doc) + delete v->doc; + v->doc = newDoc; + + v->out->startDoc(v->doc->getXRef()); + + v->doc->displayPage (v->out, 1, 72, 72, 0, gFalse, gTrue, gTrue); + + w = v->out->getBitmapWidth(); + h = v->out->getBitmapHeight(); + + gtk_widget_set_size_request (v->drawing_area, w, h); + + return errNone; +} + +static void +view_show (View *v) +{ + gtk_widget_show (v->window); +} + +static void +redraw_callback (void *data) +{ + View *v = (View*) data; + + gtk_widget_queue_draw (v->drawing_area); +} + +static View* +view_new (void) +{ + View *v; + GtkWidget *window; + GtkWidget *drawing_area; + GtkWidget *sw; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + drawing_area = gtk_drawing_area_new (); + + sw = gtk_scrolled_window_new (NULL, NULL); + + gtk_container_add (GTK_CONTAINER (window), sw); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), drawing_area); + + gtk_widget_show_all (sw); + + v = g_new0 (View, 1); + + v->window = window; + v->drawing_area = drawing_area; + v->sw = sw; + SplashColor sc; + sc[0] = 255; + sc[1] = 255; + sc[2] = 255; + v->out = new GDKSplashOutputDev (gtk_widget_get_screen (window), + redraw_callback, (void*) v, sc); + v->doc = 0; + + g_signal_connect (drawing_area, + "expose_event", + G_CALLBACK (drawing_area_expose), + (void*) v); + + return v; +} + +int +main (int argc, char *argv []) +{ + View *v; + int i; + + gtk_init (&argc, &argv); + + globalParams = new GlobalParams("/etc/xpdfrc"); + + if (argc == 1) + { + fprintf (stderr, "usage: %s PDF-FILES...\n", argv[0]); + return -1; + } + + + i = 1; + while (i < argc) + { + int err; + + v = view_new (); + + err = view_load (v, argv[i]); + + if (err != errNone) + g_printerr ("Error loading document!\n"); + + view_show (v); + + ++i; + } + + gtk_main (); + + delete globalParams; + + return 0; +} diff --git a/rosapps/smartpdf/poppler/test/pdf-inspector.cc b/rosapps/smartpdf/poppler/test/pdf-inspector.cc new file mode 100644 index 00000000000..6e205500b59 --- /dev/null +++ b/rosapps/smartpdf/poppler/test/pdf-inspector.cc @@ -0,0 +1,358 @@ +//======================================================================== +// +// GDKSplashOutputDev.cc +// +// Copyright 2003 Glyph & Cog, LLC +// Copyright 2004 Red Hat, Inc. (GDK port) +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "Object.h" +#include "ProfileData.h" +#include "GfxState.h" + +#include +#include +#include "CairoOutputDev.h" +#include +#include + +#include "PDFDoc.h" +#include "GlobalParams.h" +#include "ErrorCodes.h" +#include +#include + + +// Mapping +#include "pdf-operators.c" + +enum { + OP_STRING, + OP_COUNT, + OP_TOTAL, + OP_MIN, + OP_MAX, + N_COLUMNS, +}; + +class PdfInspector { +public: + + PdfInspector(void); + + void set_file_name (const char *file_name); + void load (const char *file_name); + void run (void); + void error_dialog (const char *error_message); + void analyze_page (int page); + +private: + static void on_file_activated (GtkWidget *widget, PdfInspector *inspector); + static void on_selection_changed (GtkTreeSelection *selection, PdfInspector *inspector); + static void on_analyze_clicked (GtkWidget *widget, PdfInspector *inspector); + + GladeXML *xml; + GtkTreeModel *model; + PDFDoc *doc; + CairoOutputDev *output; +}; + + + +PdfInspector::PdfInspector(void) +{ + GtkWidget *widget; + + xml = glade_xml_new ("./pdf-inspector.glade", NULL, NULL); + + widget = glade_xml_get_widget (xml, "pdf_file_chooser_button"); + g_signal_connect (widget, "selection-changed", G_CALLBACK (on_file_activated), this); + + widget = glade_xml_get_widget (xml, "analyze_button"); + g_signal_connect (widget, "clicked", G_CALLBACK (on_analyze_clicked), this); + + // setup the TreeView + widget = glade_xml_get_widget (xml, "pdf_tree_view"); + g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)), + "changed", G_CALLBACK (on_selection_changed), this); + model = (GtkTreeModel *)gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_INT, + G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE); + gtk_tree_view_set_model (GTK_TREE_VIEW (widget), model); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), + 0, "Operation", + gtk_cell_renderer_text_new (), + "text", OP_STRING, + NULL); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), + 1, "Count", + gtk_cell_renderer_text_new (), + "text", OP_COUNT, + NULL); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), + 2, "Elapsed", + gtk_cell_renderer_text_new (), + "text", OP_TOTAL, + NULL); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), + 3, "Min", + gtk_cell_renderer_text_new (), + "text", OP_MIN, + NULL); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), + 4, "Max", + gtk_cell_renderer_text_new (), + "text", OP_MAX, + NULL); + + for (int i = 0; i < N_COLUMNS; i++) + { + GtkTreeViewColumn *column; + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), i); + gtk_tree_view_column_set_sort_column_id (column, i); + } + doc = NULL; + output = new CairoOutputDev(); + + // set up initial widgets + load (NULL); +} + +void +PdfInspector::set_file_name(const char *file_name) +{ + GtkWidget *widget; + + widget = glade_xml_get_widget (xml, "pdf_file_chooser_button"); + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), file_name); +} + +void +PdfInspector::on_file_activated (GtkWidget *widget, PdfInspector *inspector) +{ + gchar *file_name; + + file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + if (file_name) + inspector->load (file_name); + + g_free (file_name); +} + +void +PdfInspector::on_selection_changed (GtkTreeSelection *selection, PdfInspector *inspector) +{ + GtkWidget *label; + int i; + GtkTreeModel *model; + GtkTreeIter iter; + gchar *op = NULL; + + label = glade_xml_get_widget (inspector->xml, "description_label"); + gtk_label_set_markup (GTK_LABEL (label), "No Description"); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gtk_tree_model_get (model, &iter, + OP_STRING, &op, + -1); + + } + + if (op == NULL) + return; + + for (i = 0; i < G_N_ELEMENTS (op_mapping); i++) + { + + if (!strcmp (op, op_mapping[i].op)) + { + gchar *text; + text = g_strdup_printf ("%s", op_mapping[i].description); + gtk_label_set_markup (GTK_LABEL (label), text); + g_free (text); + break; + } + } + + g_free (op); +} + +void +PdfInspector::on_analyze_clicked (GtkWidget *widget, PdfInspector *inspector) +{ + GtkWidget *spin; + int page; + + spin = glade_xml_get_widget (inspector->xml, "pdf_spin"); + + page = (int) gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin)); + + inspector->analyze_page (page); + +} + +void +PdfInspector::analyze_page (int page) +{ + GooHashIter *iter; + GooHash *hash; + GooString *key; + ProfileData *data_p; + GtkWidget *label; + char *text; + + label = glade_xml_get_widget (xml, "pdf_total_label"); + + output->startProfile (); + gtk_list_store_clear (GTK_LIST_STORE (model)); + + GooTimer timer; + doc->displayPage (output, page + 1, 72, 72, 0, gFalse, gTrue, gTrue); + + // Total time; + text = g_strdup_printf ("%g", timer.getElapsed ()); + gtk_label_set_text (GTK_LABEL (label), text); + g_free (text); + + // Individual times; + hash = output->endProfile (); + hash->startIter(&iter); + while (hash->getNext(&iter, &key, (void**) &data_p)) + { + GtkTreeIter tree_iter; + + gtk_list_store_append (GTK_LIST_STORE (model), &tree_iter); + gtk_list_store_set (GTK_LIST_STORE (model), &tree_iter, + OP_STRING, key->getCString(), + OP_COUNT, data_p->getCount (), + OP_TOTAL, data_p->getTotal (), + OP_MIN, data_p->getMin (), + OP_MAX, data_p->getMax (), + -1); + } + hash->killIter(&iter); + deleteGooHash (hash, ProfileData); +} + +void +PdfInspector::load(const char *file_name) +{ + GtkWidget *spin; + GtkWidget *button; + GtkWidget *label; + + // kill the old PDF file + if (doc != NULL) + { + delete doc; + doc = NULL; + } + + // load the new file + if (file_name) + { + GooString *filename_g; + + filename_g = new GooString (file_name); + doc = new PDFDoc(filename_g, 0, 0); + delete filename_g; + } + + if (doc && !doc->isOk()) + { + this->error_dialog ("Failed to load file."); + delete doc; + doc = NULL; + } + + spin = glade_xml_get_widget (xml, "pdf_spin"); + button = glade_xml_get_widget (xml, "analyze_button"); + label = glade_xml_get_widget (xml, "pdf_total_label"); + gtk_label_set_text (GTK_LABEL (label), ""); + + if (doc) + { + gtk_widget_set_sensitive (spin, TRUE); + gtk_widget_set_sensitive (button, TRUE); + gtk_widget_set_sensitive (label, TRUE); + gtk_spin_button_set_range (GTK_SPIN_BUTTON (spin), 0, doc->getNumPages()-1); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0); + + output->startDoc (doc->getXRef()); + } + else + { + gtk_widget_set_sensitive (spin, FALSE); + gtk_widget_set_sensitive (button, FALSE); + gtk_widget_set_sensitive (label, FALSE); + } +} + +void +PdfInspector::error_dialog (const char *error_message) +{ + g_warning (error_message); +} + +void +PdfInspector::run() +{ + GtkWidget *dialog; + + dialog = glade_xml_get_widget (xml, "pdf_dialog"); + + gtk_dialog_run (GTK_DIALOG (dialog)); +} + + + +int +main (int argc, char *argv []) +{ + const char *file_name = NULL; + PdfInspector *inspector; + + gtk_init (&argc, &argv); + + globalParams = new GlobalParams("/etc/xpdfrc"); + globalParams->setProfileCommands (true); + + if (argc == 2) + file_name = argv[1]; + else if (argc > 2) + { + fprintf (stderr, "usage: %s [PDF-FILE]\n", argv[0]); + return -1; + } + + inspector = new PdfInspector (); + + if (file_name) + inspector->set_file_name (file_name); + + inspector->run (); + + delete inspector; + delete globalParams; + + return 0; +} + + diff --git a/rosapps/smartpdf/poppler/test/pdf-inspector.glade b/rosapps/smartpdf/poppler/test/pdf-inspector.glade new file mode 100644 index 00000000000..6a756b01df2 --- /dev/null +++ b/rosapps/smartpdf/poppler/test/pdf-inspector.glade @@ -0,0 +1,434 @@ + + + + + + + 6 + True + PDF Inspector + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 600 + 400 + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + False + + + + True + False + 12 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + -7 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 6 + True + False + 12 + + + + True + 2 + 2 + False + 6 + 12 + + + + True + _File: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + Page Number + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + Select A File + GTK_FILE_CHOOSER_ACTION_OPEN + True + False + -1 + + + 1 + 2 + 0 + 1 + fill + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 100 1 10 10 + + + 1 + 2 + 1 + 2 + + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 6 + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + False + True + False + False + False + + + + + 0 + True + True + + + + + + True + 2 + 3 + False + 6 + 12 + + + + True + Total time elapsed: + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 1 + 3 + 1 + 2 + fill + + + + + + + True + Description: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + fill + fill + + + + + + True + <i>No Description</i> + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 1 + 2 + 0 + 1 + fill + + + + + + True + 0.5 + 0 + 0.0 + 0.0 + 0 + 0 + 0 + 0 + + + + True + True + _Analyze + True + GTK_RELIEF_NORMAL + True + + + + + 2 + 3 + 0 + 1 + fill + fill + + + + + 0 + False + True + + + + + + + + + + True + <b>PDF Instructions</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + + diff --git a/rosapps/smartpdf/poppler/test/pdf-operators.c b/rosapps/smartpdf/poppler/test/pdf-operators.c new file mode 100644 index 00000000000..3e838a2c641 --- /dev/null +++ b/rosapps/smartpdf/poppler/test/pdf-operators.c @@ -0,0 +1,81 @@ +typedef struct +{ + char *op; + char *description; +} OperatorMapping; + +OperatorMapping op_mapping[] = { + { "b", "Close, fill, and stroke path using nonzero winding number rule" }, + { "B", "Fill and stroke path using nonzero winding number rule" }, + { "b*", "Close, fill, and stroke path using even-odd rule" }, + { "B*", "Fill and stroke path using even-odd rule" }, + { "BDC", "(PDF 1.2) Begin marked-content sequence with property list" }, + { "BI", "Begin inline image object" }, + { "BMC", "(PDF 1.2) Begin marked-content sequence" }, + { "BT", "Begin text object" }, + { "BX", "(PDF 1.1) Begin compatibility section" }, + { "c", "Append curved segment to path (three control points)" }, + { "cm", "Concatenate matrix to current transformation matrix" }, + { "CS", "(PDF 1.1) Set color space for stroking operations" }, + { "cs", "(PDF 1.1) Set color space for nonstroking operations" }, + { "d", "Set line dash pattern" }, + { "d0", "Set glyph width in Type 3 font" }, + { "d1", "Set glyph width and bounding box in Type 3 font" }, + { "Do", "Invoke named XObject" }, + { "DP", "(PDF 1.2) Define marked-content point with property list" }, + { "EI", "End inline image object" }, + { "EMC", "(PDF 1.2) End marked-content sequence" }, + { "ET", "End text object" }, + { "EX", "(PDF 1.1) End compatibility section" }, + { "f", "Fill path using nonzero winding number rule" }, + { "F", "Fill path using nonzero winding number rule (obsolete)" }, + { "f*", "Fill path using even-odd rule" }, + { "G", "Set gray level for stroking operations" }, + { "g", "Set gray level for nonstroking operations" }, + { "gs", "(PDF 1.2) Set parameters from graphics state parameter dictionary" }, + { "h", "Close subpath" }, + { "i", "Set flatness tolerance" }, + { "ID", "Begin inline image data" }, + { "j", "Set line join style" }, + { "J", "Set line cap style" }, + { "K", "Set CMYK color for stroking operations" }, + { "k", "Set CMYK color for nonstroking operations" }, + { "l", "Append straight line segment to path" }, + { "m", "Begin new subpath" }, + { "M", "Set miter limit" }, + { "MP", "(PDF 1.2) Define marked-content point" }, + { "n", "End path without filling or stroking" }, + { "q", "Save graphics state" }, + { "Q", "Restore graphics state" }, + { "re", "Append rectangle to path" }, + { "RG", "Set RGB color for stroking operations" }, + { "rg", "Set RGB color for nonstroking operations" }, + { "ri", "Set color rendering intent" }, + { "s", "Close and stroke path" }, + { "S", "Stroke path" }, + { "SC", "(PDF 1.1) Set color for stroking operations" }, + { "sc", "(PDF 1.1) Set color for nonstroking operations" }, + { "SCN", "(PDF 1.2) Set color for stroking operations (ICCBased and special color spaces)" }, + { "scn", "(PDF 1.2) Set color for nonstroking operations (ICCBased and special color spaces)" }, + { "sh", "(PDF 1.3) Paint area defined by shading pattern" }, + { "T*", "Move to start of next text line" }, + { "Tc", "Set character spacing" }, + { "Td", "Move text position" }, + { "TD", "Move text position and set leading" }, + { "Tf", "Set text font and size" }, + { "Tj", "Show text" }, + { "TJ", "Show text, allowing individual glyph positioning" }, + { "TL", "Set text leading" }, + { "Tm", "Set text matrix and text line matrix" }, + { "Tr", "Set text rendering mode" }, + { "Ts", "Set text rise" }, + { "Tw", "Set word spacing" }, + { "Tz", "Set horizontal text scaling" }, + { "v", "Append curved segment to path (initial point replicated)" }, + { "w", "Set line width" }, + { "W", "Set clipping path using nonzero winding number rule" }, + { "W*", "Set clipping path using even-odd rule" }, + { "y", "Append curved segment to path (final point replicated)" }, + { "'", "Move to next line and show text" }, + { "\"", "Set word and character spacing, move to next line, and show text" }, +}; diff --git a/rosapps/smartpdf/poppler/test/pdfbench.cc b/rosapps/smartpdf/poppler/test/pdfbench.cc new file mode 100644 index 00000000000..dd1f03ece1f --- /dev/null +++ b/rosapps/smartpdf/poppler/test/pdfbench.cc @@ -0,0 +1,1244 @@ +/* + A tool to stress-test poppler rendering and measure rendering times for + very simplistic performance measuring. + + TODO: + * print more info about document like e.g. enumarate images, + streams, compression, encryption, password-protection. Each should have + a command-line arguments to turn it on/off + * never over-write file given as -out argument (optionally, provide -force + option to force writing the -out file). It's way too easy too lose results + of a previous run. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_DIRENT_H +#include +#endif + +#ifdef WIN32 +#include +#else +#define stricmp strcasecmp +#endif + +#include "ErrorCodes.h" +#include "GooString.h" +#include "GooList.h" +#include "GlobalParams.h" +#include "SplashBitmap.h" +#include "Object.h" /* must be included before SplashOutputDev.h because of sloppiness in SplashOutputDev.h */ +#include "SplashOutputDev.h" +#include "TextOutputDev.h" +#include "PDFDoc.h" +#include "SecurityHandler.h" +#include "Link.h" + +#include "BaseUtils.h" + +extern void PreviewBitmap_Init(void); +extern void PreviewBitmap(SplashBitmap *); +extern void PreviewBitmap_Destroy(void); + +#define PDF_FILE_DPI 72 + +#define MAX_FILENAME_SIZE 1024 + +struct FindFileState { + char path[MAX_FILENAME_SIZE]; + char dirpath[MAX_FILENAME_SIZE]; /* current dir path */ + char pattern[MAX_FILENAME_SIZE]; /* search pattern */ + const char *bufptr; +#ifdef WIN32 + WIN32_FIND_DATA fileinfo; + HANDLE dir; +#else + DIR *dir; +#endif +}; + +#ifdef WIN32 +#include +#include +#include + +__inline char *getcwd(char *buffer, int maxlen) +{ + return _getcwd(buffer, maxlen); +} + +int fnmatch(const char *pattern, const char *string, int flags) +{ + int prefix_len; + const char *star_pos = strchr(pattern, '*'); + if (!star_pos) + return strcmp(pattern, string) != 0; + + prefix_len = (int)(star_pos-pattern); + if (0 == prefix_len) + return 0; + + if (0 == _strnicmp(pattern, string, prefix_len)) + return 0; + + return 1; +} + +#else +#include +#endif + +#ifdef WIN32 +/* on windows to query dirs we need foo\* to get files in this directory. + foo\ always fails and foo will return just info about foo directory, + not files in this directory */ +static void win_correct_path_for_FindFirstFile(char *path, int path_max_len) +{ + int path_len = strlen(path); + if (path_len >= path_max_len-4) + return; + if (DIR_SEP_CHAR != path[path_len]) + path[path_len++] = DIR_SEP_CHAR; + path[path_len++] = '*'; + path[path_len] = 0; +} +#endif + +FindFileState *find_file_open(const char *path, const char *pattern) +{ + FindFileState *s; + + s = (FindFileState*)malloc(sizeof(FindFileState)); + if (!s) + return NULL; + strcpy_s(s->path, sizeof(s->path), path); + strcpy_s(s->dirpath, sizeof(s->path), path); +#ifdef WIN32 + win_correct_path_for_FindFirstFile(s->path, sizeof(s->path)); +#endif + strcpy_s(s->pattern, sizeof(s->pattern), pattern); + s->bufptr = s->path; +#ifdef WIN32 + s->dir = INVALID_HANDLE_VALUE; +#else + s->dir = NULL; +#endif + return s; +} + +#if 0 /* re-enable if we #define USE_OWN_GET_AUTH_DATA */ +void *StandardSecurityHandler::getAuthData() +{ + return NULL; +} +#endif + +/* strcat and truncate. */ +char *pstrcat(char *buf, int buf_size, const char *s) +{ + int len; + len = strlen(buf); + if (len < buf_size) + strcpy_s(buf + len, buf_size - len, s); + return buf; +} + +char *makepath(char *buf, int buf_size, const char *path, + const char *filename) +{ + int len; + + strcpy_s(buf, buf_size, path); + len = strlen(path); + if (len > 0 && path[len - 1] != DIR_SEP_CHAR && len + 1 < buf_size) { + buf[len++] = DIR_SEP_CHAR; + buf[len] = '\0'; + } + return pstrcat(buf, buf_size, filename); +} + +#ifdef WIN32 +static int skip_matching_file(const char *filename) +{ + if (0 == strcmp(".", filename)) + return 1; + if (0 == strcmp("..", filename)) + return 1; + return 0; +} +#endif + +int find_file_next(FindFileState *s, char *filename, int filename_size_max) +{ +#ifdef WIN32 + int fFound; + if (INVALID_HANDLE_VALUE == s->dir) { + s->dir = FindFirstFile(s->path, &(s->fileinfo)); + if (INVALID_HANDLE_VALUE == s->dir) + return -1; + goto CheckFile; + } + + while (1) { + fFound = FindNextFile(s->dir, &(s->fileinfo)); + if (!fFound) + return -1; +CheckFile: + if (skip_matching_file(s->fileinfo.cFileName)) + continue; + if (0 == fnmatch(s->pattern, s->fileinfo.cFileName, 0) ) { + makepath(filename, filename_size_max, s->dirpath, s->fileinfo.cFileName); + return 0; + } + } +#else + struct dirent *dirent; + const char *p; + char *q; + + if (s->dir == NULL) + goto redo; + + for (;;) { + dirent = readdir(s->dir); + if (dirent == NULL) { + redo: + if (s->dir) { + closedir(s->dir); + s->dir = NULL; + } + p = s->bufptr; + if (*p == '\0') + return -1; + /* CG: get_str(&p, s->dirpath, sizeof(s->dirpath), ":") */ + q = s->dirpath; + while (*p != ':' && *p != '\0') { + if ((q - s->dirpath) < (int)sizeof(s->dirpath) - 1) + *q++ = *p; + p++; + } + *q = '\0'; + if (*p == ':') + p++; + s->bufptr = p; + s->dir = opendir(s->dirpath); + if (!s->dir) + goto redo; + } else { + if (fnmatch(s->pattern, dirent->d_name, 0) == 0) { + makepath(filename, filename_size_max, + s->dirpath, dirent->d_name); + return 0; + } + } + } +#endif +} + +void find_file_close(FindFileState *s) +{ +#ifdef WIN32 + if (INVALID_HANDLE_VALUE != s->dir) + FindClose(s->dir); +#else + if (s->dir) + closedir(s->dir); +#endif + free(s); +} + +typedef struct StrList { + struct StrList *next; + char * str; +} StrList; + +/* List of all command-line arguments that are not switches. + We assume those are: + - names of PDF files + - names of a file with a list of PDF files + - names of directories with PDF files +*/ +static StrList *gArgsListRoot = NULL; + +/* Names of all command-line switches we recognize */ +#define TIMINGS_ARG "-timings" +#define RESOLUTION_ARG "-resolution" +#define RECURSIVE_ARG "-recursive" +#define OUT_ARG "-out" +#define PREVIEW_ARG "-preview" +#define SLOW_PREVIEW_ARG "-slowpreview" +#define LOAD_ONLY_ARG "-loadonly" +#define PAGE_ARG "-page" +#define DUMP_LINKS_ARG "-dump-links" +#define TEXT_ARG "-text" + +/* Should we record timings? True if -timings command-line argument was given. */ +static BOOL gfTimings = FALSE; + +/* If true, we use render each page at resolution 'gResolutionX'/'gResolutionY'. + If false, we render each page at its native resolution. + True if -resolution NxM command-line argument was given. */ +static BOOL gfForceResolution = FALSE; +static int gResolutionX = 0; +static int gResolutionY = 0; +/* If NULL, we output the log info to stdout. If not NULL, should be a name + of the file to which we output log info. + Controled by -out command-line argument. */ +static char * gOutFileName = NULL; +/* FILE * correspondig to gOutFileName or stdout if gOutFileName is NULL or + was invalid name */ +static FILE * gOutFile = NULL; +/* FILE * correspondig to gOutFileName or stderr if gOutFileName is NULL or + was invalid name */ +static FILE * gErrFile = NULL; + +/* If True and a directory is given as a command-line argument, we'll process + pdf files in sub-directories as well. + Controlled by -recursive command-line argument */ +static BOOL gfRecursive = FALSE; + +/* If true, preview rendered image. To make sure that they're being rendered correctly. */ +static BOOL gfPreview = FALSE; + +/* 1 second (1000 milliseconds) */ +#define SLOW_PREVIEW_TIME 1000 + +/* If true, preview rendered image in a slow mode i.e. delay displaying for + SLOW_PREVIEW_TIME. This is so that a human has enough time to see if the + PDF renders ok. In release mode on fast processor pages take only ~100-200 ms + to render and they go away too quickly to be inspected by a human. */ +static int gfSlowPreview = FALSE; + +/* If true, we only dump the text, not render */ +static int gfTextOnly = FALSE; + +#define PAGE_NO_NOT_GIVEN -1 + +/* If equals PAGE_NO_NOT_GIVEN, we're in default mode where we render all pages. + If different, will only render this page */ +static int gPageNo = PAGE_NO_NOT_GIVEN; +/* If true, will only load the file, not render any pages. Mostly for + profiling load time */ +static BOOL gfLoadOnly = FALSE; + +/* if TRUE, will dump information about links */ +static BOOL gfDumpLinks = FALSE; + +static SplashColor splashColRed; +static SplashColor splashColGreen; +static SplashColor splashColBlue; +static SplashColor splashColWhite; +static SplashColor splashColBlack; + +#define SPLASH_COL_RED_PTR (SplashColorPtr)&(splashColRed[0]) +#define SPLASH_COL_GREEN_PTR (SplashColorPtr)&(splashColGreen[0]) +#define SPLASH_COL_BLUE_PTR (SplashColorPtr)&(splashColBlue[0]) +#define SPLASH_COL_WHITE_PTR (SplashColorPtr)&(splashColWhite[0]) +#define SPLASH_COL_BLACK_PTR (SplashColorPtr)&(splashColBlack[0]) + +static SplashColorPtr gBgColor = SPLASH_COL_WHITE_PTR; +static SplashColorMode gSplashColorMode = splashModeBGR8; + +int StrList_Len(StrList **root) +{ + int len = 0; + StrList * cur; + assert(root); + if (!root) + return 0; + cur = *root; + while (cur) { + ++len; + cur = cur->next; + } + return len; +} + +int StrList_InsertAndOwn(StrList **root, char *txt) +{ + StrList * el; + assert(root && txt); + if (!root || !txt) + return FALSE; + + el = (StrList*)malloc(sizeof(StrList)); + if (!el) + return FALSE; + el->str = txt; + el->next = *root; + *root = el; + return TRUE; +} + +int StrList_Insert(StrList **root, char *txt) +{ + char *txtDup; + + assert(root && txt); + if (!root || !txt) + return FALSE; + txtDup = Str_Dup(txt); + if (!txtDup) + return FALSE; + + if (!StrList_InsertAndOwn(root, txtDup)) { + free((void*)txtDup); + return FALSE; + } + return TRUE; +} + +StrList* StrList_RemoveHead(StrList **root) +{ + StrList *tmp; + assert(root); + if (!root) + return NULL; + + if (!*root) + return NULL; + tmp = *root; + *root = tmp->next; + tmp->next = NULL; + return tmp; +} + +void StrList_FreeElement(StrList *el) +{ + if (!el) + return; + free((void*)el->str); + free((void*)el); +} + +void StrList_Destroy(StrList **root) +{ + StrList * cur; + StrList * next; + + if (!root) + return; + cur = *root; + while (cur) { + next = cur->next; + StrList_FreeElement(cur); + cur = next; + } + *root = NULL; +} + +static void SplashColorSet(SplashColorPtr col, Guchar red, Guchar green, Guchar blue, Guchar alpha) +{ + switch (gSplashColorMode) + { + case splashModeBGR8: + col[0] = blue; + col[1] = green; + col[2] = red; + break; + case splashModeRGB8: + col[0] = red; + col[1] = green; + col[2] = blue; + break; + default: + assert(0); + break; + } +} + +static void ColorsInit(void) +{ + /* splash colors */ + SplashColorSet(SPLASH_COL_RED_PTR, 0xff, 0, 0, 0); + SplashColorSet(SPLASH_COL_GREEN_PTR, 0, 0xff, 0, 0); + SplashColorSet(SPLASH_COL_BLUE_PTR, 0, 0, 0xff, 0); + SplashColorSet(SPLASH_COL_BLACK_PTR, 0, 0, 0, 0); + SplashColorSet(SPLASH_COL_WHITE_PTR, 0xff, 0xff, 0xff, 0); +} + +#ifndef WIN32 +void OutputDebugString(const char *txt) +{ + /* do nothing */ +} +#define _snprintf snprintf +#define _vsnprintf vsnprintf +#endif + +void CDECL error(int pos, char *msg, ...) { + va_list args; + char buf[4096], *p = buf; + + // NB: this can be called before the globalParams object is created + if (globalParams && globalParams->getErrQuiet()) { + return; + } + + if (pos >= 0) { + p += _snprintf(p, sizeof(buf)-1, "Error (%d): ", pos); + *p = '\0'; + OutputDebugString(p); + } else { + OutputDebugString("Error: "); + } + + p = buf; + va_start(args, msg); + p += _vsnprintf(p, sizeof(buf) - 1, msg, args); + while ( p > buf && isspace(p[-1]) ) + *--p = '\0'; + *p++ = '\r'; + *p++ = '\n'; + *p = '\0'; + OutputDebugString(buf); + va_end(args); + + if (pos >= 0) { + p += _snprintf(p, sizeof(buf)-1, "Error (%d): ", pos); + *p = '\0'; + OutputDebugString(buf); + if (gErrFile) + fprintf(gErrFile, buf); + } else { + OutputDebugString("Error: "); + if (gErrFile) + fprintf(gErrFile, "Error: "); + } + + p = buf; + va_start(args, msg); + p += _vsnprintf(p, sizeof(buf) - 3, msg, args); + while ( p > buf && isspace(p[-1]) ) + *--p = '\0'; + *p++ = '\r'; + *p++ = '\n'; + *p = '\0'; + OutputDebugString(buf); + if (gErrFile) + fprintf(gErrFile, buf); + va_end(args); +} + +void LogInfo(char *fmt, ...) +{ + va_list args; + char buf[4096], *p = buf; + + p = buf; + va_start(args, fmt); + p += _vsnprintf(p, sizeof(buf) - 1, fmt, args); + *p = '\0'; + fprintf(gOutFile, buf); + va_end(args); + fflush(gOutFile); +} + +static void PrintUsageAndExit(int argc, char **argv) +{ + printf("Usage: pdftest [-preview] [-slowpreview] [-timings] [-text] [-resolution NxM] [-recursive] [-page N] [-out out.txt] pdf-files-to-process\n"); + for (int i=0; i < argc; i++) { + printf("i=%d, '%s'\n", i, argv[i]); + } + exit(0); +} + +/* milli-second timer */ +#ifdef WIN32 +typedef struct MsTimer { + LARGE_INTEGER start; + LARGE_INTEGER end; +} MsTimer; + +void MsTimer_Start(MsTimer *timer) +{ + assert(timer); + if (!timer) + return; + QueryPerformanceCounter(&timer->start); +} +void MsTimer_End(MsTimer *timer) +{ + assert(timer); + if (!timer) + return; + QueryPerformanceCounter(&timer->end); +} + +double MsTimer_GetTimeInMs(MsTimer *timer) +{ + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + double durationInSecs = (double)(timer->end.QuadPart-timer->start.QuadPart)/(double)freq.QuadPart; + return durationInSecs * 1000.0; +} + +#else +#include + +typedef struct MsTimer { + struct timeval start; + struct timeval end; +} MsTimer; + +void MsTimer_Start(MsTimer *timer) +{ + assert(timer); + if (!timer) + return; + gettimeofday(&timer->start, NULL); +} + +void MsTimer_End(MsTimer *timer) +{ + assert(timer); + if (!timer) + return; + gettimeofday(&timer->end, NULL); +} + +double MsTimer_GetTimeInMs(MsTimer *timer) +{ + double timeInMs; + time_t seconds; + int usecs; + + assert(timer); + if (!timer) + return 0.0; + /* TODO: this logic needs to be verified */ + seconds = timer->end.tv_sec - timer->start.tv_sec; + usecs = timer->end.tv_usec - timer->start.tv_usec; + if (usecs < 0) { + --seconds; + usecs += 1000000; + } + timeInMs = (double)seconds*(double)1000.0 + (double)usecs/(double)1000.0; + return timeInMs; +} +#endif + +void *StandardSecurityHandler::getAuthData() +{ + return NULL; +} + +int ShowPreview(void) +{ + if (gfPreview || gfSlowPreview) + return TRUE; + return FALSE; +} + +static Links *GetLinksForPage(PDFDoc *doc, int pageNo) +{ + Object obj; + Catalog *catalog = doc->getCatalog(); + Page *page = catalog->getPage(pageNo); + Links *links = new Links(page->getAnnots(&obj), catalog->getBaseURI()); + obj.free(); + return links; +} + +static const char * GetLinkActionKindName(LinkActionKind kind) { + switch (kind) { + case (actionGoTo): + return "actionGoTo"; + case actionGoToR: + return "actionGoToR"; + case actionLaunch: + return "actionLaunch"; + case actionURI: + return "actionURI"; + case actionNamed: + return "actionNamed"; + case actionMovie: + return "actionMovie"; + case actionUnknown: + return "actionUnknown"; + default: + assert(0); + return "unknown action"; + } +} + +static void DumpLinks(PDFDoc *doc) +{ + Links * links = NULL; + int pagesCount, linkCount; + Link * link; + + if (!doc) + return; + + pagesCount = doc->getNumPages(); + for (int pageNo = 1; pageNo < pagesCount; ++pageNo) { + delete links; + links = GetLinksForPage(doc, pageNo); + if (!links) + continue; + linkCount = links->getNumLinks(); + for (int i=0; igetLink(i); + LinkAction * action = link->getAction(); + LinkActionKind actionKind = action->getKind(); + LogInfo("Link: page %d, type=%d (%s)\n", pageNo, actionKind, GetLinkActionKindName(actionKind)); +#if 0 /* TODO: maybe print the uri (and more) ? */ + if (actionURI == actionKind) { + LinkURI * linkUri; + linkUri = (LinkURI*)action; + DBG_OUT(" uri=%s\n", linkUri->getURI()->getCString()); + } +#endif + } + } + delete links; +} + +static void RenderPdfFileAsText(const char *fileName) +{ + MsTimer msTimer; + double timeInMs; + int pageCount; + int rotate; + GBool useMediaBox; + GBool crop; + GBool doLinks; + GooString * fileNameStr = NULL; + PDFDoc * pdfDoc = NULL; + TextOutputDev * textOut = NULL; + GooString * txt = NULL; + + assert(fileName); + if (!fileName) + return; + + LogInfo("started: %s\n", fileName); + + textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); + if (!textOut->isOk()) { + goto Exit; + } + + MsTimer_Start(&msTimer); + /* note: don't delete fileNameStr since PDFDoc takes ownership and deletes them itself */ + fileNameStr = new GooString(fileName); + if (!fileNameStr) + goto Exit; + + pdfDoc = new PDFDoc(fileNameStr, NULL, NULL, NULL); + if (!pdfDoc->isOk()) { + error(-1, "renderPdfFile(): failed to open PDF file %s\n", fileName); + goto Exit; + } + + MsTimer_End(&msTimer); + timeInMs = MsTimer_GetTimeInMs(&msTimer); + LogInfo("load: %.2f ms\n", timeInMs); + + pageCount = pdfDoc->getNumPages(); + LogInfo("page count: %d\n", pageCount); + + for (int curPage = 1; curPage <= pageCount; curPage++) { + if ((gPageNo != PAGE_NO_NOT_GIVEN) && (gPageNo != curPage)) + continue; + + MsTimer_Start(&msTimer); + rotate = 0; + useMediaBox = gFalse; + crop = gTrue; + doLinks = gFalse; + pdfDoc->displayPage(textOut, curPage, 72, 72, rotate, useMediaBox, crop, doLinks); + txt = textOut->getText(0.0, 0.0, 10000.0, 10000.0); + MsTimer_End(&msTimer); + timeInMs = MsTimer_GetTimeInMs(&msTimer); + if (gfTimings) + LogInfo("page %d: %.2f ms\n", curPage, timeInMs); + printf("%s\n", txt->getCString()); + delete txt; + txt = NULL; + } + +Exit: + LogInfo("finished: %s\n", fileName); + delete textOut; + delete pdfDoc; +} + +/* Render one pdf file with a given 'fileName'. Log apropriate info. */ +static void RenderPdfFileAsGfx(const char *fileName) +{ + MsTimer msTimer; + double timeInMs; + int pageCount; + int pageDx, pageDy; + int renderDx, renderDy; + double scaleX, scaleY; + double hDPI, vDPI; + int rotate; + GBool useMediaBox; + GBool crop; + GBool doLinks; + GooString * fileNameStr = NULL; + PDFDoc * pdfDoc = NULL; + SplashOutputDev * outputDevice = NULL; + SplashBitmap * bitmap = NULL; + + assert(fileName); + if (!fileName) + return; + + LogInfo("started: %s\n", fileName); + + outputDevice = new SplashOutputDev(gSplashColorMode, 4, gFalse, gBgColor); + if (!outputDevice) { + error(-1, "renderPdfFile(): failed to create outputDev\n"); + goto Error; + } + + MsTimer_Start(&msTimer); + /* note: don't delete fileNameStr since PDFDoc takes ownership and deletes them itself */ + fileNameStr = new GooString(fileName); + if (!fileNameStr) + goto Error; + + pdfDoc = new PDFDoc(fileNameStr, NULL, NULL, NULL); + if (!pdfDoc->isOk()) { + error(-1, "renderPdfFile(): failed to open PDF file %s\n", fileName); + goto Error; + } + outputDevice->startDoc(pdfDoc->getXRef()); + + MsTimer_End(&msTimer); + timeInMs = MsTimer_GetTimeInMs(&msTimer); + LogInfo("load: %.2f ms\n", timeInMs); + + pageCount = pdfDoc->getNumPages(); + LogInfo("page count: %d\n", pageCount); + + if (gfLoadOnly) + goto DumpLinks; + + for (int curPage = 1; curPage <= pageCount; curPage++) { + if ((gPageNo != PAGE_NO_NOT_GIVEN) && (gPageNo != curPage)) + continue; + + pageDx = (int)pdfDoc->getPageCropWidth(curPage); + pageDy = (int)pdfDoc->getPageCropHeight(curPage); + + renderDx = pageDx; + renderDy = pageDy; + if (gfForceResolution) { + renderDx = gResolutionX; + renderDy = gResolutionY; + } + MsTimer_Start(&msTimer); + rotate = 0; + useMediaBox = gFalse; + crop = gTrue; + doLinks = gTrue; + scaleX = 1.0; + scaleY = 1.0; + if (pageDx != renderDx) + scaleX = (double)renderDx / (double)pageDx; + if (pageDy != renderDy) + scaleY = (double)renderDy / (double)pageDy; + hDPI = (double)PDF_FILE_DPI * scaleX; + vDPI = (double)PDF_FILE_DPI * scaleY; + pdfDoc->displayPage(outputDevice, curPage, hDPI, vDPI, rotate, useMediaBox, crop, doLinks); + MsTimer_End(&msTimer); + timeInMs = MsTimer_GetTimeInMs(&msTimer); + if (gfTimings) + LogInfo("page %d: %.2f ms\n", curPage, timeInMs); + if (ShowPreview()) { + delete bitmap; + bitmap = outputDevice->takeBitmap(); + PreviewBitmap(bitmap); + if (gfSlowPreview && (int)timeInMs < SLOW_PREVIEW_TIME) + SleepMilliseconds(SLOW_PREVIEW_TIME - (int)timeInMs); + } + } +DumpLinks: + if (gfDumpLinks) + DumpLinks(pdfDoc); +Error: + LogInfo("finished: %s\n", fileName); + delete bitmap; + delete outputDevice; + delete pdfDoc; +} + +static void RenderPdfFile(const char *fileName) +{ + if (gfTextOnly) + RenderPdfFileAsText(fileName); + else + RenderPdfFileAsGfx(fileName); +} + +int ParseInteger(const char *start, const char *end, int *intOut) +{ + char numBuf[16]; + int digitsCount; + const char * tmp; + + assert(start && end && intOut); + assert(end >= start); + if (!start || !end || !intOut || (start > end)) + return FALSE; + + digitsCount = 0; + tmp = start; + while (tmp <= end) { + if (isspace(*tmp)) { + /* do nothing, we allow whitespace */ + } else if (!isdigit(*tmp)) + return FALSE; + numBuf[digitsCount] = *tmp; + ++digitsCount; + if (digitsCount == dimof(numBuf)-3) /* -3 to be safe */ + return FALSE; + ++tmp; + } + if (0 == digitsCount) + return FALSE; + numBuf[digitsCount] = 0; + *intOut = atoi(numBuf); + return TRUE; +} + +/* Given 'resolutionString' in format NxM (e.g. "100x200"), parse the string and put N + into 'resolutionXOut' and M into 'resolutionYOut'. + Return FALSE if there was an error (e.g. string is not in the right format */ +int ParseResolutionString(const char *resolutionString, int *resolutionXOut, int *resolutionYOut) +{ + const char * posOfX; + + assert(resolutionString); + assert(resolutionXOut); + assert(resolutionYOut); + if (!resolutionString || !resolutionXOut || !resolutionYOut) + return FALSE; + *resolutionXOut = 0; + *resolutionYOut = 0; + posOfX = strchr(resolutionString, 'X'); + if (!posOfX) + posOfX = strchr(resolutionString, 'x'); + if (!posOfX) + return FALSE; + if (posOfX == resolutionString) + return FALSE; + if (!ParseInteger(resolutionString, posOfX-1, resolutionXOut)) + return FALSE; + if (!ParseInteger(posOfX+1, resolutionString+strlen(resolutionString)-1, resolutionYOut)) + return FALSE; + return TRUE; +} + +#ifdef DEBUG +void u_ParseResolutionString(void) +{ + int i; + int result, resX, resY; + const char *str; + struct TestData { + const char * str; + int result; + int resX; + int resY; + } testData[] = { + { "", FALSE, 0, 0 }, + { "abc", FALSE, 0, 0}, + { "34", FALSE, 0, 0}, + { "0x0", TRUE, 0, 0}, + { "0x1", TRUE, 0, 1}, + { "0xab", FALSE, 0, 0}, + { "1x0", TRUE, 1, 0}, + { "100x200", TRUE, 100, 200}, + { "58x58", TRUE, 58, 58}, + { " 58x58", TRUE, 58, 58}, + { "58x 58", TRUE, 58, 58}, + { "58x58 ", TRUE, 58, 58}, + { " 58 x 58 ", TRUE, 58, 58}, + { "34x1234a", FALSE, 0, 0}, + { NULL, FALSE, 0, 0} + }; + for (i=0; NULL != testData[i].str; i++) { + str = testData[i].str; + result = ParseResolutionString(str, &resX, &resY); + assert(result == testData[i].result); + if (result) { + assert(resX == testData[i].resX); + assert(resY == testData[i].resY); + } + } +} +#endif + +void RunAllUnitTests(void) +{ +#ifdef DEBUG + u_ParseResolutionString(); +#endif +} + +void ParseCommandLine(int argc, char **argv) +{ + char * arg; + + if (argc < 2) + PrintUsageAndExit(argc, argv); + + for (int i=1; i < argc; i++) { + arg = argv[i]; + assert(arg); + if ('-' == arg[0]) { + if (Str_EqNoCase(arg, TIMINGS_ARG)) { + gfTimings = TRUE; + } else if (Str_EqNoCase(arg, RESOLUTION_ARG)) { + ++i; + if (i == argc) + PrintUsageAndExit(argc, argv); /* expect a file name after that */ + if (!ParseResolutionString(argv[i], &gResolutionX, &gResolutionY)) + PrintUsageAndExit(argc, argv); + gfForceResolution = TRUE; + } else if (Str_EqNoCase(arg, RECURSIVE_ARG)) { + gfRecursive = TRUE; + } else if (Str_EqNoCase(arg, OUT_ARG)) { + /* expect a file name after that */ + ++i; + if (i == argc) + PrintUsageAndExit(argc, argv); + gOutFileName = Str_Dup(argv[i]); + } else if (Str_EqNoCase(arg, PREVIEW_ARG)) { + gfPreview = TRUE; + } else if (Str_EqNoCase(arg, TEXT_ARG)) { + gfTextOnly = TRUE; + } else if (Str_EqNoCase(arg, SLOW_PREVIEW_ARG)) { + gfSlowPreview = TRUE; + } else if (Str_EqNoCase(arg, LOAD_ONLY_ARG)) { + gfLoadOnly = TRUE; + } else if (Str_EqNoCase(arg, PAGE_ARG)) { + /* expect an integer after that */ + ++i; + if (i == argc) + PrintUsageAndExit(argc, argv); + gPageNo = atoi(argv[i]); + if (gPageNo < 1) + PrintUsageAndExit(argc, argv); + } else if (Str_EqNoCase(arg, DUMP_LINKS_ARG)) { + gfDumpLinks = TRUE; + } else { + /* unknown option */ + PrintUsageAndExit(argc, argv); + } + } else { + /* we assume that this is not an option hence it must be + a name of PDF/directory/file with PDF names */ + StrList_Insert(&gArgsListRoot, arg); + } + } +} + +#define UNIX_NEWLINE "\x0a" +#define UNIX_NEWLINE_C 0xa + +void RenderPdfFileList(char *pdfFileList) +{ + char *data = NULL; + char *dataNormalized = NULL; + char *pdfFileName; + unsigned long fileSize; + + assert(pdfFileList); + if (!pdfFileList) + return; + data = File_Slurp(pdfFileList, &fileSize); + if (!data) { + error(-1, "couldn't load file '%s'", pdfFileList); + return; + } + dataNormalized = Str_NormalizeNewline(data, UNIX_NEWLINE); + if (!dataNormalized) { + error(-1, "couldn't normalize data of file '%s'", pdfFileList); + goto Exit; + } + for (;;) { + pdfFileName = Str_SplitIter(&dataNormalized, UNIX_NEWLINE_C); + if (!pdfFileName) + break; + Str_StripWsBoth(pdfFileName); + if (Str_Empty(pdfFileName)) { + free((void*)pdfFileName); + continue; + } + RenderPdfFile(pdfFileName); + free((void*)pdfFileName); + } +Exit: + free((void*)dataNormalized); + free((void*)data); +} + +#ifdef WIN32 +#include +#include + +int IsDirectoryName(char *path) +{ + struct _stat buf; + int result; + + result = _stat(path, &buf ); + if (0 != result) + return FALSE; + + if (buf.st_mode & _S_IFDIR) + return TRUE; + + return FALSE; +} + +int IsFileName(char *path) +{ + struct _stat buf; + int result; + + result = _stat(path, &buf ); + if (0 != result) + return FALSE; + + if (buf.st_mode & _S_IFREG) + return TRUE; + + return FALSE; +} +#else +int IsDirectoryName(char *path) +{ + /* TODO: implement me */ + return FALSE; +} + +int IsFileName(char *path) +{ + /* TODO: implement me */ + return TRUE; +} +#endif + +int IsPdfFileName(char *path) +{ + if (Str_EndsWithNoCase(path, ".pdf")) + return TRUE; + return FALSE; +} + +void RenderDirectory(char *path) +{ + FindFileState * ffs; + char filename[MAX_FILENAME_SIZE]; + StrList * dirList = NULL; + StrList * el; + + StrList_Insert(&dirList, path); + + while (0 != StrList_Len(&dirList)) { + el = StrList_RemoveHead(&dirList); + ffs = find_file_open(el->str, "*"); + while (!find_file_next(ffs, filename, sizeof(filename))) { + if (IsDirectoryName(filename)) { + if (gfRecursive) { + StrList_Insert(&dirList, filename); + } + } else if (IsFileName(filename)) { + if (IsPdfFileName(filename)) { + RenderPdfFile(filename); + } + } + } + find_file_close(ffs); + StrList_FreeElement(el); + } + StrList_Destroy(&dirList); +} + +/* Render 'cmdLineArg', which can be: + - directory name + - name of PDF file + - name of text file with names of PDF files +*/ +void RenderCmdLineArg(char *cmdLineArg) +{ + assert(cmdLineArg); + if (!cmdLineArg) + return; + if (IsDirectoryName(cmdLineArg)) { + RenderDirectory(cmdLineArg); + } else if (IsFileName(cmdLineArg)) { + if (IsPdfFileName(cmdLineArg)) + RenderPdfFile(cmdLineArg); + else + RenderPdfFileList(cmdLineArg); + } else { + error(-1, "unexpected argument '%s'", cmdLineArg); + } +} + +int main(int argc, char **argv) +{ + StrList * curr; + FILE * outFile = NULL; + + RunAllUnitTests(); + + ParseCommandLine(argc, argv); + if (0 == StrList_Len(&gArgsListRoot)) + PrintUsageAndExit(argc, argv); + assert(gArgsListRoot); + + ColorsInit(); + globalParams = new GlobalParams(""); + if (!globalParams) + return 1; + globalParams->setErrQuiet(gFalse); + + if (gOutFileName) { + outFile = fopen(gOutFileName, "wb"); + if (!outFile) { + printf("failed to open -out file %s\n", gOutFileName); + return 1; + } + gOutFile = outFile; + } + else + gOutFile = stdout; + + if (gOutFileName) + gErrFile = outFile; + else + gErrFile = stderr; + + PreviewBitmap_Init(); + + curr = gArgsListRoot; + while (curr) { + RenderCmdLineArg(curr->str); + curr = curr->next; + } + if (outFile) + fclose(outFile); + PreviewBitmap_Destroy(); + StrList_Destroy(&gArgsListRoot); + delete globalParams; + return 0; +} diff --git a/rosapps/smartpdf/poppler/utils/HtmlFonts.cc b/rosapps/smartpdf/poppler/utils/HtmlFonts.cc new file mode 100644 index 00000000000..c77683b0e7a --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/HtmlFonts.cc @@ -0,0 +1,326 @@ +#include "HtmlFonts.h" +#include "GlobalParams.h" +#include "UnicodeMap.h" +#include + + struct Fonts{ + char *Fontname; + char *name; + }; + +const int font_num=13; + +static Fonts fonts[font_num+1]={ + {"Courier", "Courier" }, + {"Courier-Bold", "Courier"}, + {"Courier-BoldOblique", "Courier"}, + {"Courier-Oblique", "Courier"}, + {"Helvetica", "Helvetica"}, + {"Helvetica-Bold", "Helvetica"}, + {"Helvetica-BoldOblique", "Helvetica"}, + {"Helvetica-Oblique", "Helvetica"}, + {"Symbol", "Symbol" }, + {"Times-Bold", "Times" }, + {"Times-BoldItalic", "Times" }, + {"Times-Italic", "Times" }, + {"Times-Roman", "Times" }, + {" " , "Times" }, +}; + +#define xoutRound(x) ((int)(x + 0.5)) +extern GBool xml; + +GooString* HtmlFont::DefaultFont=new GooString("Times"); // Arial,Helvetica,sans-serif + +HtmlFontColor::HtmlFontColor(GfxRGB rgb){ + r=static_cast(255*rgb.r); + g=static_cast(255*rgb.g); + b=static_cast(255*rgb.b); + if (!(Ok(r)&&Ok(b)&&Ok(g))) {printf("Error : Bad color \n");r=0;g=0;b=0;} +} + +GooString *HtmlFontColor::convtoX(unsigned int xcol) const{ + GooString *xret=new GooString(); + char tmp; + unsigned int k; + k = (xcol/16); + if ((k>=0)&&(k<10)) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10); + xret->append(tmp); + k = (xcol%16); + if ((k>=0)&&(k<10)) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10); + xret->append(tmp); + return xret; +} + +GooString *HtmlFontColor::toString() const{ + GooString *tmp=new GooString("#"); + GooString *tmpr=convtoX(r); + GooString *tmpg=convtoX(g); + GooString *tmpb=convtoX(b); + tmp->append(tmpr); + tmp->append(tmpg); + tmp->append(tmpb); + delete tmpr; + delete tmpg; + delete tmpb; + return tmp; +} + +HtmlFont::HtmlFont(GooString* ftname,int _size, GfxRGB rgb){ + //if (col) color=HtmlFontColor(col); + //else color=HtmlFontColor(); + color=HtmlFontColor(rgb); + + GooString *fontname = NULL; + + if( ftname ){ + fontname = new GooString(ftname); + FontName=new GooString(ftname); + } + else { + fontname = NULL; + FontName = NULL; + } + + lineSize = -1; + + size=(_size-1); + italic = gFalse; + bold = gFalse; + + if (fontname){ + if (strstr(fontname->lowerCase()->getCString(),"bold")) bold=gTrue; + + if (strstr(fontname->lowerCase()->getCString(),"italic")|| + strstr(fontname->lowerCase()->getCString(),"oblique")) italic=gTrue; + + int i=0; + while (strcmp(ftname->getCString(),fonts[i].Fontname)&&(igetTextEncoding())) { + return tmp; + } + + for (int i = 0; i < uLen; ++i) { + switch (u[i]) + { + case '"': tmp->append("""); break; + case '&': tmp->append("&"); break; + case '<': tmp->append("<"); break; + case '>': tmp->append(">"); break; + default: + { + // convert unicode to string + if ((n = uMap->mapUnicode(u[i], buf, sizeof(buf))) > 0) { + tmp->append(buf, n); + } + } + } + } + + uMap->decRefCnt(); + return tmp; +} + +GooString* HtmlFont::simple(HtmlFont* font, Unicode* content, int uLen){ + GooString *cont=HtmlFilter (content, uLen); + + /*if (font.isBold()) { + cont->insert(0,"",3); + cont->append("",4); + } + if (font.isItalic()) { + cont->insert(0,"",3); + cont->append("",4); + } */ + + return cont; +} + +HtmlFontAccu::HtmlFontAccu(){ + accu=new GooVector(); +} + +HtmlFontAccu::~HtmlFontAccu(){ + if (accu) delete accu; +} + +int HtmlFontAccu::AddFont(const HtmlFont& font){ + GooVector::iterator i; + for (i=accu->begin();i!=accu->end();i++) + { + if (font.isEqual(*i)) + { + return (int)(i-(accu->begin())); + } + } + + accu->push_back(font); + return (accu->size()-1); +} + +// get CSS font name for font #i +GooString* HtmlFontAccu::getCSStyle(int i, GooString* content){ + GooString *tmp; + GooString *iStr=GooString::fromInt(i); + + if (!xml) { + tmp = new GooString("append(iStr); + tmp->append("\">"); + tmp->append(content); + tmp->append(""); + } else { + tmp = new GooString(""); + tmp->append(content); + } + + delete iStr; + return tmp; +} + +// get CSS font definition for font #i +GooString* HtmlFontAccu::CSStyle(int i){ + GooString *tmp=new GooString(); + GooString *iStr=GooString::fromInt(i); + + GooVector::iterator g=accu->begin(); + g+=i; + HtmlFont font=*g; + GooString *Size=GooString::fromInt(font.getSize()); + GooString *colorStr=font.getColor().toString(); + GooString *fontName=font.getFontName(); + GooString *lSize; + + if(!xml){ + tmp->append(".ft"); + tmp->append(iStr); + tmp->append("{font-size:"); + tmp->append(Size); + if( font.getLineSize() != -1 ) + { + lSize = GooString::fromInt(font.getLineSize()); + tmp->append("px;line-height:"); + tmp->append(lSize); + delete lSize; + } + tmp->append("px;font-family:"); + tmp->append(fontName); //font.getFontName()); + tmp->append(";color:"); + tmp->append(colorStr); + tmp->append(";}"); + } + if (xml) { + tmp->append("append(iStr); + tmp->append("\" size=\""); + tmp->append(Size); + tmp->append("\" family=\""); + tmp->append(fontName); //font.getFontName()); + tmp->append("\" color=\""); + tmp->append(colorStr); + tmp->append("\"/>"); + } + + delete fontName; + delete colorStr; + delete iStr; + delete Size; + return tmp; +} + + diff --git a/rosapps/smartpdf/poppler/utils/HtmlFonts.h b/rosapps/smartpdf/poppler/utils/HtmlFonts.h new file mode 100644 index 00000000000..3ff5b81a924 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/HtmlFonts.h @@ -0,0 +1,85 @@ +#ifndef _HTML_FONTS_H +#define _HTML_FONTS_H +#include "goo/GooVector.h" +#include "goo/GooString.h" +#include "GfxState.h" +#include "CharTypes.h" + + +class HtmlFontColor{ + private: + unsigned int r; + unsigned int g; + unsigned int b; + GBool Ok(unsigned int xcol){ return ((xcol<=255)&&(xcol>=0));} + GooString *convtoX(unsigned int xcol) const; + public: + HtmlFontColor():r(0),g(0),b(0){} + HtmlFontColor(GfxRGB rgb); + HtmlFontColor(const HtmlFontColor& x){r=x.r;g=x.g;b=x.b;} + HtmlFontColor& operator=(const HtmlFontColor &x){ + r=x.r;g=x.g;b=x.b; + return *this; + } + ~HtmlFontColor(){}; + GooString* toString() const; + GBool isEqual(const HtmlFontColor& col) const{ + return ((r==col.r)&&(g==col.g)&&(b==col.b)); + } +} ; + + +class HtmlFont{ + private: + unsigned int size; + int lineSize; + GBool italic; + GBool bold; + int pos; // position of the font name in the fonts array + static GooString *DefaultFont; + GooString *FontName; + HtmlFontColor color; + static GooString* HtmlFilter(Unicode* u, int uLen); //char* s); +public: + + HtmlFont(){FontName=NULL;}; + HtmlFont(GooString* fontname,int _size, GfxRGB rgb); + HtmlFont(const HtmlFont& x); + HtmlFont& operator=(const HtmlFont& x); + HtmlFontColor getColor() const {return color;} + ~HtmlFont(); + static void clear(); + GooString* getFullName(); + GBool isItalic() const {return italic;} + GBool isBold() const {return bold;} + unsigned int getSize() const {return size;} + int getLineSize() const {return lineSize;} + void setLineSize(int _lineSize) { lineSize = _lineSize; } + GooString* getFontName(); + static GooString* getDefaultFont(); + static void setDefaultFont(GooString* defaultFont); + GBool isEqual(const HtmlFont& x) const; + GBool isEqualIgnoreBold(const HtmlFont& x) const; + static GooString* simple(HtmlFont *font, Unicode *content, int uLen); + void print() const {printf("font: %s %d %s%spos: %d\n", FontName->getCString(), size, bold ? "bold " : "", italic ? "italic " : "", pos);}; +}; + +class HtmlFontAccu{ +private: + GooVector *accu; + +public: + HtmlFontAccu(); + ~HtmlFontAccu(); + int AddFont(const HtmlFont& font); + HtmlFont* Get(int i){ + GooVector::iterator g=accu->begin(); + g+=i; + return g; + } + GooString* getCSStyle (int i, GooString* content); + GooString* CSStyle(int i); + int size() const {return accu->size();} + +}; +#endif diff --git a/rosapps/smartpdf/poppler/utils/HtmlLinks.cc b/rosapps/smartpdf/poppler/utils/HtmlLinks.cc new file mode 100644 index 00000000000..3010be5e3e2 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/HtmlLinks.cc @@ -0,0 +1,101 @@ +#include "HtmlLinks.h" + +HtmlLink::HtmlLink(const HtmlLink& x){ + Xmin=x.Xmin; + Ymin=x.Ymin; + Xmax=x.Xmax; + Ymax=x.Ymax; + dest=new GooString(x.dest); +} + +HtmlLink::HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString * _dest) +{ + if (xmin < xmax) { + Xmin=xmin; + Xmax=xmax; + } else { + Xmin=xmax; + Xmax=xmin; + } + if (ymin < ymax) { + Ymin=ymin; + Ymax=ymax; + } else { + Ymin=ymax; + Ymax=ymin; + } + dest=new GooString(_dest); +} + +HtmlLink::~HtmlLink(){ + if (dest) delete dest; +} + +GBool HtmlLink::isEqualDest(const HtmlLink& x) const{ + return (!strcmp(dest->getCString(), x.dest->getCString())); +} + +GBool HtmlLink::inLink(double xmin,double ymin,double xmax,double ymax) const { + double y=(ymin+ymax)/2; + if (y>Ymax) return gFalse; + return (y>Ymin)&&(xminXmin); + } + + +HtmlLink& HtmlLink::operator=(const HtmlLink& x){ + if (this==&x) return *this; + if (dest) {delete dest;dest=NULL;} + Xmin=x.Xmin; + Ymin=x.Ymin; + Xmax=x.Xmax; + Ymax=x.Ymax; + dest=new GooString(x.dest); + return *this; +} + +GooString* HtmlLink::getLinkStart() { + GooString *res = new GooString("append(dest); + res->append("\">"); + return res; +} + +/*GooString* HtmlLink::Link(GooString* content){ + //GooString* _dest=new GooString(dest); + GooString *tmp=new GooString("append(dest); + tmp->append("\">"); + tmp->append(content); + tmp->append(""); + //delete _dest; + return tmp; + }*/ + + + +HtmlLinks::HtmlLinks(){ + accu=new GooVector(); +} + +HtmlLinks::~HtmlLinks(){ + delete accu; + accu=NULL; +} + +GBool HtmlLinks::inLink(double xmin,double ymin,double xmax,double ymax,int& p)const { + + for(GooVector::iterator i=accu->begin();i!=accu->end();i++){ + if (i->inLink(xmin,ymin,xmax,ymax)) { + p=(i - accu->begin()); + return 1; + } + } + return 0; +} + +HtmlLink* HtmlLinks::getLink(int i) const{ + GooVector::iterator g=accu->begin(); + g+=i; + return g; +} + diff --git a/rosapps/smartpdf/poppler/utils/HtmlLinks.h b/rosapps/smartpdf/poppler/utils/HtmlLinks.h new file mode 100644 index 00000000000..71f8065ee90 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/HtmlLinks.h @@ -0,0 +1,49 @@ +#ifndef _HTML_LINKS +#define _HTML_LINKS + +#include +#include +#include "goo/GooVector.h" +#include "goo/GooString.h" + +class HtmlLink{ + +private: + double Xmin; + double Ymin; + double Xmax; + double Ymax; + GooString* dest; + +public: + HtmlLink(){dest=NULL;} + HtmlLink(const HtmlLink& x); + HtmlLink& operator=(const HtmlLink& x); + HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString *_dest); + ~HtmlLink(); + GBool isEqualDest(const HtmlLink& x) const; + GooString *getDest(){return new GooString(dest);} + double getX1() const {return Xmin;} + double getX2() const {return Xmax;} + double getY1() const {return Ymin;} + double getY2() const {return Ymax;} + GBool inLink(double xmin,double ymin,double xmax,double ymax) const ; + //GooString *Link(GooString *content); + GooString* getLinkStart(); + +}; + +class HtmlLinks{ +private: + GooVector *accu; +public: + HtmlLinks(); + ~HtmlLinks(); + void AddLink(const HtmlLink& x) {accu->push_back(x);} + GBool inLink(double xmin,double ymin,double xmax,double ymax,int& p) const; + HtmlLink* getLink(int i) const; + +}; + +#endif + diff --git a/rosapps/smartpdf/poppler/utils/HtmlOutputDev.cc b/rosapps/smartpdf/poppler/utils/HtmlOutputDev.cc new file mode 100644 index 00000000000..7cdc8b70f48 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/HtmlOutputDev.cc @@ -0,0 +1,1572 @@ +//======================================================================== +// +// HtmlOutputDev.cc +// +// Copyright 1997-2002 Glyph & Cog, LLC +// +// Changed 1999-2000 by G.Ovtcharov +// +// Changed 2002 by Mikhail Kruk +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "UnicodeMap.h" +#include "goo/gmem.h" +#include "Error.h" +#include "GfxState.h" +#ifdef ENABLE_LIBJPEG +#include "DCTStream.h" +#endif +#include "GlobalParams.h" +#include "HtmlOutputDev.h" +#include "HtmlFonts.h" +#include "UGooString.h" + +int HtmlPage::pgNum=0; +int HtmlOutputDev::imgNum=1; + +extern double scale; +extern GBool complexMode; +extern GBool ignore; +extern GBool printCommands; +extern GBool printHtml; +extern GBool noframes; +extern GBool stout; +extern GBool xml; +extern GBool showHidden; +extern GBool noMerge; + +static GooString* basename(GooString* str){ + + char *p=str->getCString(); + int len=str->getLength(); + for (int i=len-1;i>=0;i--) + if (*(p+i)==SLASH) + return new GooString((p+i+1),len-i-1); + return new GooString(str); +} + +static GooString* Dirname(GooString* str){ + + char *p=str->getCString(); + int len=str->getLength(); + for (int i=len-1;i>=0;i--) + if (*(p+i)==SLASH) + return new GooString(p,i+1); + return new GooString(); +} + +//------------------------------------------------------------------------ +// HtmlString +//------------------------------------------------------------------------ + +HtmlString::HtmlString(GfxState *state, double fontSize, HtmlFontAccu* fonts) { + GfxFont *font; + double x, y; + + state->transform(state->getCurX(), state->getCurY(), &x, &y); + if ((font = state->getFont())) { + yMin = y - font->getAscent() * fontSize; + yMax = y - font->getDescent() * fontSize; + GfxRGB rgb; + state->getFillRGB(&rgb); + GooString *name = state->getFont()->getName(); + if (!name) name = HtmlFont::getDefaultFont(); //new GooString("default"); + HtmlFont hfont=HtmlFont(name, static_cast(fontSize-1), rgb); + fontpos = fonts->AddFont(hfont); + } else { + // this means that the PDF file draws text without a current font, + // which should never happen + yMin = y - 0.95 * fontSize; + yMax = y + 0.35 * fontSize; + fontpos=0; + } + if (yMin == yMax) { + // this is a sanity check for a case that shouldn't happen -- but + // if it does happen, we want to avoid dividing by zero later + yMin = y; + yMax = y + 1; + } + col = 0; + text = NULL; + xRight = NULL; + link = NULL; + len = size = 0; + yxNext = NULL; + xyNext = NULL; + htext=new GooString(); + dir = textDirUnknown; +} + + +HtmlString::~HtmlString() { + delete text; + delete htext; + gfree(xRight); +} + +void HtmlString::addChar(GfxState *state, double x, double y, + double dx, double dy, Unicode u) { + if (dir == textDirUnknown) { + //dir = UnicodeMap::getDirection(u); + dir = textDirLeftRight; + } + + if (len == size) { + size += 16; + text = (Unicode *)grealloc(text, size * sizeof(Unicode)); + xRight = (double *)grealloc(xRight, size * sizeof(double)); + } + text[len] = u; + if (len == 0) { + xMin = x; + } + xMax = xRight[len] = x + dx; +//printf("added char: %f %f xright = %f\n", x, dx, x+dx); + ++len; +} + +void HtmlString::endString() +{ + if( dir == textDirRightLeft && len > 1 ) + { + //printf("will reverse!\n"); + for (int i = 0; i < len / 2; i++) + { + Unicode ch = text[i]; + text[i] = text[len - i - 1]; + text[len - i - 1] = ch; + } + } +} + +//------------------------------------------------------------------------ +// HtmlPage +//------------------------------------------------------------------------ + +HtmlPage::HtmlPage(GBool rawOrder, char *imgExtVal) { + this->rawOrder = rawOrder; + curStr = NULL; + yxStrings = NULL; + xyStrings = NULL; + yxCur1 = yxCur2 = NULL; + fonts=new HtmlFontAccu(); + links=new HtmlLinks(); + pageWidth=0; + pageHeight=0; + fontsPageMarker = 0; + DocName=NULL; + firstPage = -1; + imgExt = new GooString(imgExtVal); +} + +HtmlPage::~HtmlPage() { + clear(); + if (DocName) delete DocName; + if (fonts) delete fonts; + if (links) delete links; + if (imgExt) delete imgExt; +} + +void HtmlPage::updateFont(GfxState *state) { + GfxFont *font; + double *fm; + char *name; + int code; + double w; + + // adjust the font size + fontSize = state->getTransformedFontSize(); + if ((font = state->getFont()) && font->getType() == fontType3) { + // This is a hack which makes it possible to deal with some Type 3 + // fonts. The problem is that it's impossible to know what the + // base coordinate system used in the font is without actually + // rendering the font. This code tries to guess by looking at the + // width of the character 'm' (which breaks if the font is a + // subset that doesn't contain 'm'). + for (code = 0; code < 256; ++code) { + if ((name = ((Gfx8BitFont *)font)->getCharName(code)) && + name[0] == 'm' && name[1] == '\0') { + break; + } + } + if (code < 256) { + w = ((Gfx8BitFont *)font)->getWidth(code); + if (w != 0) { + // 600 is a generic average 'm' width -- yes, this is a hack + fontSize *= w / 0.6; + } + } + fm = font->getFontMatrix(); + if (fm[0] != 0) { + fontSize *= fabs(fm[3] / fm[0]); + } + } +} + +void HtmlPage::beginString(GfxState *state, GooString *s) { + curStr = new HtmlString(state, fontSize, fonts); +} + + +void HtmlPage::conv(){ + HtmlString *tmp; + + int linkIndex = 0; + HtmlFont* h; + for(tmp=yxStrings;tmp;tmp=tmp->yxNext){ + int pos=tmp->fontpos; + // printf("%d\n",pos); + h=fonts->Get(pos); + + if (tmp->htext) delete tmp->htext; + tmp->htext=HtmlFont::simple(h,tmp->text,tmp->len); + + if (links->inLink(tmp->xMin,tmp->yMin,tmp->xMax,tmp->yMax, linkIndex)){ + tmp->link = links->getLink(linkIndex); + /*GooString *t=tmp->htext; + tmp->htext=links->getLink(k)->Link(tmp->htext); + delete t;*/ + } + } + +} + + +void HtmlPage::addChar(GfxState *state, double x, double y, + double dx, double dy, + double ox, double oy, Unicode *u, int uLen) { + double x1, y1, w1, h1, dx2, dy2; + int n, i; + state->transform(x, y, &x1, &y1); + n = curStr->len; + + // check that new character is in the same direction as current string + // and is not too far away from it before adding + //if ((UnicodeMap::getDirection(u[0]) != curStr->dir) || + // XXX + if ( + (n > 0 && + fabs(x1 - curStr->xRight[n-1]) > 0.1 * (curStr->yMax - curStr->yMin))) { + endString(); + beginString(state, NULL); + } + state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(), + 0, &dx2, &dy2); + dx -= dx2; + dy -= dy2; + state->transformDelta(dx, dy, &w1, &h1); + if (uLen != 0) { + w1 /= uLen; + h1 /= uLen; + } + for (i = 0; i < uLen; ++i) { + curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]); + } +} + +void HtmlPage::endString() { + HtmlString *p1, *p2; + double h, y1, y2; + + // throw away zero-length strings -- they don't have valid xMin/xMax + // values, and they're useless anyway + if (curStr->len == 0) { + delete curStr; + curStr = NULL; + return; + } + + curStr->endString(); + +#if 0 //~tmp + if (curStr->yMax - curStr->yMin > 20) { + delete curStr; + curStr = NULL; + return; + } +#endif + + // insert string in y-major list + h = curStr->yMax - curStr->yMin; + y1 = curStr->yMin + 0.5 * h; + y2 = curStr->yMin + 0.8 * h; + if (rawOrder) { + p1 = yxCur1; + p2 = NULL; + } else if ((!yxCur1 || + (y1 >= yxCur1->yMin && + (y2 >= yxCur1->yMax || curStr->xMax >= yxCur1->xMin))) && + (!yxCur2 || + (y1 < yxCur2->yMin || + (y2 < yxCur2->yMax && curStr->xMax < yxCur2->xMin)))) { + p1 = yxCur1; + p2 = yxCur2; + } else { + for (p1 = NULL, p2 = yxStrings; p2; p1 = p2, p2 = p2->yxNext) { + if (y1 < p2->yMin || (y2 < p2->yMax && curStr->xMax < p2->xMin)) + break; + } + yxCur2 = p2; + } + yxCur1 = curStr; + if (p1) + p1->yxNext = curStr; + else + yxStrings = curStr; + curStr->yxNext = p2; + curStr = NULL; +} + +void HtmlPage::coalesce() { + HtmlString *str1, *str2; + HtmlFont *hfont1, *hfont2; + double space, horSpace, vertSpace, vertOverlap; + GBool addSpace, addLineBreak; + int n, i; + double curX, curY; + +#if 0 //~ for debugging + for (str1 = yxStrings; str1; str1 = str1->yxNext) { + printf("x=%f..%f y=%f..%f size=%2d '", + str1->xMin, str1->xMax, str1->yMin, str1->yMax, + (int)(str1->yMax - str1->yMin)); + for (i = 0; i < str1->len; ++i) { + fputc(str1->text[i] & 0xff, stdout); + } + printf("'\n"); + } + printf("\n------------------------------------------------------------\n\n"); +#endif + str1 = yxStrings; + + if( !str1 ) return; + + //----- discard duplicated text (fake boldface, drop shadows) + if( !complexMode ) + { /* if not in complex mode get rid of duplicate strings */ + HtmlString *str3; + GBool found; + while (str1) + { + double size = str1->yMax - str1->yMin; + double xLimit = str1->xMin + size * 0.2; + found = gFalse; + for (str2 = str1, str3 = str1->yxNext; + str3 && str3->xMin < xLimit; + str2 = str3, str3 = str2->yxNext) + { + if (str3->len == str1->len && + !memcmp(str3->text, str1->text, str1->len * sizeof(Unicode)) && + fabs(str3->yMin - str1->yMin) < size * 0.2 && + fabs(str3->yMax - str1->yMax) < size * 0.2 && + fabs(str3->xMax - str1->xMax) < size * 0.2) + { + found = gTrue; + //printf("found duplicate!\n"); + break; + } + } + if (found) + { + str2->xyNext = str3->xyNext; + str2->yxNext = str3->yxNext; + delete str3; + } + else + { + str1 = str1->yxNext; + } + } + } /*- !complexMode */ + + str1 = yxStrings; + + hfont1 = getFont(str1); + if( hfont1->isBold() ) + str1->htext->insert(0,"",3); + if( hfont1->isItalic() ) + str1->htext->insert(0,"",3); + if( str1->getLink() != NULL ) { + GooString *ls = str1->getLink()->getLinkStart(); + str1->htext->insert(0, ls); + delete ls; + } + curX = str1->xMin; curY = str1->yMin; + + while (str1 && (str2 = str1->yxNext)) { + hfont2 = getFont(str2); + space = str1->yMax - str1->yMin; + horSpace = str2->xMin - str1->xMax; + addLineBreak = !noMerge && (fabs(str1->xMin - str2->xMin) < 0.4); + vertSpace = str2->yMin - str1->yMax; + +//printf("coalesce %d %d %f? ", str1->dir, str2->dir, d); + + if (str2->yMin >= str1->yMin && str2->yMin <= str1->yMax) + { + vertOverlap = str1->yMax - str2->yMin; + } else + if (str2->yMax >= str1->yMin && str2->yMax <= str1->yMax) + { + vertOverlap = str2->yMax - str1->yMin; + } else + { + vertOverlap = 0; + } + + if ( + ( + ( + ( + (rawOrder && vertOverlap > 0.5 * space) + || + (!rawOrder && str2->yMin < str1->yMax) + ) && + (horSpace > -0.5 * space && horSpace < space) + ) || + (vertSpace >= 0 && vertSpace < 0.5 * space && addLineBreak) + ) && + (!complexMode || (hfont1->isEqualIgnoreBold(*hfont2))) && // in complex mode fonts must be the same, in other modes fonts do not metter + str1->dir == str2->dir // text direction the same + ) + { +// printf("yes\n"); + n = str1->len + str2->len; + if ((addSpace = horSpace > 0.1 * space)) { + ++n; + } + if (addLineBreak) { + ++n; + } + + str1->size = (n + 15) & ~15; + str1->text = (Unicode *)grealloc(str1->text, + str1->size * sizeof(Unicode)); + str1->xRight = (double *)grealloc(str1->xRight, + str1->size * sizeof(double)); + if (addSpace) { + str1->text[str1->len] = 0x20; + str1->htext->append(" "); + str1->xRight[str1->len] = str2->xMin; + ++str1->len; + } + if (addLineBreak) { + str1->text[str1->len] = '\n'; + str1->htext->append("
"); + str1->xRight[str1->len] = str2->xMin; + ++str1->len; + str1->yMin = str2->yMin; + str1->yMax = str2->yMax; + str1->xMax = str2->xMax; + int fontLineSize = hfont1->getLineSize(); + int curLineSize = (int)(vertSpace + space); + if( curLineSize != fontLineSize ) + { + HtmlFont *newfnt = new HtmlFont(*hfont1); + newfnt->setLineSize(curLineSize); + str1->fontpos = fonts->AddFont(*newfnt); + delete newfnt; + hfont1 = getFont(str1); + // we have to reget hfont2 because it's location could have + // changed on resize + hfont2 = getFont(str2); + } + } + for (i = 0; i < str2->len; ++i) { + str1->text[str1->len] = str2->text[i]; + str1->xRight[str1->len] = str2->xRight[i]; + ++str1->len; + } + + /* fix and if str1 and str2 differ */ + if( hfont1->isBold() && !hfont2->isBold() ) + str1->htext->append("", 4); + if( hfont1->isItalic() && !hfont2->isItalic() ) + str1->htext->append("", 4); + if( !hfont1->isBold() && hfont2->isBold() ) + str1->htext->append("", 3); + if( !hfont1->isItalic() && hfont2->isItalic() ) + str1->htext->append("", 3); + + /* now handle switch of links */ + HtmlLink *hlink1 = str1->getLink(); + HtmlLink *hlink2 = str2->getLink(); + if( !hlink1 || !hlink2 || !hlink1->isEqualDest(*hlink2) ) { + if(hlink1 != NULL ) + str1->htext->append(""); + if(hlink2 != NULL ) { + GooString *ls = hlink2->getLinkStart(); + str1->htext->append(ls); + delete ls; + } + } + + str1->htext->append(str2->htext); + // str1 now contains href for link of str2 (if it is defined) + str1->link = str2->link; + hfont1 = hfont2; + if (str2->xMax > str1->xMax) { + str1->xMax = str2->xMax; + } + if (str2->yMax > str1->yMax) { + str1->yMax = str2->yMax; + } + str1->yxNext = str2->yxNext; + delete str2; + } else { // keep strings separate +// printf("no\n"); + if( hfont1->isBold() ) + str1->htext->append("",4); + if( hfont1->isItalic() ) + str1->htext->append("",4); + if(str1->getLink() != NULL ) + str1->htext->append(""); + + str1->xMin = curX; str1->yMin = curY; + str1 = str2; + curX = str1->xMin; curY = str1->yMin; + hfont1 = hfont2; + if( hfont1->isBold() ) + str1->htext->insert(0,"",3); + if( hfont1->isItalic() ) + str1->htext->insert(0,"",3); + if( str1->getLink() != NULL ) { + GooString *ls = str1->getLink()->getLinkStart(); + str1->htext->insert(0, ls); + delete ls; + } + } + } + str1->xMin = curX; str1->yMin = curY; + if( hfont1->isBold() ) + str1->htext->append("",4); + if( hfont1->isItalic() ) + str1->htext->append("",4); + if(str1->getLink() != NULL ) + str1->htext->append(""); + +#if 0 //~ for debugging + for (str1 = yxStrings; str1; str1 = str1->yxNext) { + printf("x=%3d..%3d y=%3d..%3d size=%2d ", + (int)str1->xMin, (int)str1->xMax, (int)str1->yMin, (int)str1->yMax, + (int)(str1->yMax - str1->yMin)); + printf("'%s'\n", str1->htext->getCString()); + } + printf("\n------------------------------------------------------------\n\n"); +#endif + +} + +void HtmlPage::dumpAsXML(FILE* f,int page){ + fprintf(f, "\n", pageHeight,pageWidth); + + for(int i=fontsPageMarker;i < fonts->size();i++) { + GooString *fontCSStyle = fonts->CSStyle(i); + fprintf(f,"\t%s\n",fontCSStyle->getCString()); + delete fontCSStyle; + } + + GooString *str, *str1; + for(HtmlString *tmp=yxStrings;tmp;tmp=tmp->yxNext){ + if (tmp->htext){ + str=new GooString(tmp->htext); + fprintf(f,"yMin),xoutRound(tmp->xMin)); + fprintf(f,"width=\"%d\" height=\"%d\" ",xoutRound(tmp->xMax-tmp->xMin),xoutRound(tmp->yMax-tmp->yMin)); + fprintf(f,"font=\"%d\">", tmp->fontpos); + if (tmp->fontpos!=-1){ + str1=fonts->getCSStyle(tmp->fontpos, str); + } + fputs(str1->getCString(),f); + delete str; + delete str1; + fputs("\n",f); + } + } + fputs("\n",f); +} + + +void HtmlPage::dumpComplex(FILE *file, int page){ + FILE* pageFile; + GooString* tmp; + char* htmlEncoding; + + if( firstPage == -1 ) firstPage = page; + + if( !noframes ) + { + GooString* pgNum=GooString::fromInt(page); + tmp = new GooString(DocName); + tmp->append('-')->append(pgNum)->append(".html"); + delete pgNum; + + if (!(pageFile = fopen(getFileNameFromPath(tmp->getCString(),tmp->getLength()), "w"))) { + error(-1, "Couldn't open html file '%s'", tmp->getCString()); + delete tmp; + return; + } + delete tmp; + + fprintf(pageFile,"%s\n\n\nPage %d\n\n", + DOCTYPE, page); + + htmlEncoding = HtmlOutputDev::mapEncodingToHtml + (globalParams->getTextEncodingName()); + fprintf(pageFile, "\n", htmlEncoding); + } + else + { + pageFile = file; + fprintf(pageFile,"\n", page); + fprintf(pageFile,"\n", page); + } + + fprintf(pageFile,"
\n", + pageWidth, pageHeight); + + tmp=basename(DocName); + + fputs("\n",pageFile); + + if( !noframes ) + { + fputs("\n\n",pageFile); + } + + if( !ignore ) + { + fprintf(pageFile, + "\"background\n", + pageWidth, pageHeight, tmp->getCString(), + (page-firstPage+1), imgExt->getCString()); + } + + delete tmp; + + GooString *str, *str1; + for(HtmlString *tmp1=yxStrings;tmp1;tmp1=tmp1->yxNext){ + if (tmp1->htext){ + str=new GooString(tmp1->htext); + fprintf(pageFile, + "
", + xoutRound(tmp1->yMin), + xoutRound(tmp1->xMin)); + fputs("",pageFile); + if (tmp1->fontpos!=-1){ + str1=fonts->getCSStyle(tmp1->fontpos, str); + } + //printf("%s\n", str1->getCString()); + fputs(str1->getCString(),pageFile); + + delete str; + delete str1; + fputs("
\n",pageFile); + } + } + + fputs("
\n", pageFile); + + if( !noframes ) + { + fputs("\n\n",pageFile); + fclose(pageFile); + } +} + + +void HtmlPage::dump(FILE *f, int pageNum) +{ + if (complexMode) + { + if (xml) dumpAsXML(f, pageNum); + if (!xml) dumpComplex(f, pageNum); + } + else + { + fprintf(f,"",pageNum); + GooString* fName=basename(DocName); + for (int i=1;i
\n",fName->getCString(),pageNum,i); + HtmlOutputDev::imgNum=1; + delete fName; + + GooString* str; + for(HtmlString *tmp=yxStrings;tmp;tmp=tmp->yxNext){ + if (tmp->htext){ + str=new GooString(tmp->htext); + fputs(str->getCString(),f); + delete str; + fputs("
\n",f); + } + } + fputs("
\n",f); + } +} + + + +void HtmlPage::clear() { + HtmlString *p1, *p2; + + if (curStr) { + delete curStr; + curStr = NULL; + } + for (p1 = yxStrings; p1; p1 = p2) { + p2 = p1->yxNext; + delete p1; + } + yxStrings = NULL; + xyStrings = NULL; + yxCur1 = yxCur2 = NULL; + + if( !noframes ) + { + delete fonts; + fonts=new HtmlFontAccu(); + fontsPageMarker = 0; + } + else + { + fontsPageMarker = fonts->size(); + } + + delete links; + links=new HtmlLinks(); + + +} + +void HtmlPage::setDocName(char *fname){ + DocName=new GooString(fname); +} + +//------------------------------------------------------------------------ +// HtmlMetaVar +//------------------------------------------------------------------------ + +HtmlMetaVar::HtmlMetaVar(char *_name, char *_content) +{ + name = new GooString(_name); + content = new GooString(_content); +} + +HtmlMetaVar::~HtmlMetaVar() +{ + delete name; + delete content; +} + +GooString* HtmlMetaVar::toString() +{ + GooString *result = new GooString("append(name); + result->append("\" content=\""); + result->append(content); + result->append("\">"); + return result; +} + +//------------------------------------------------------------------------ +// HtmlOutputDev +//------------------------------------------------------------------------ + +static char* HtmlEncodings[][2] = { + {"Latin1", "ISO-8859-1"}, + {NULL, NULL} +}; + + +char* HtmlOutputDev::mapEncodingToHtml(GooString* encoding) +{ + char* enc = encoding->getCString(); + for(int i = 0; HtmlEncodings[i][0] != NULL; i++) + { + if( strcmp(enc, HtmlEncodings[i][0]) == 0 ) + { + return HtmlEncodings[i][1]; + } + } + return enc; +} + +void HtmlOutputDev::doFrame(int firstPage){ + GooString* fName=new GooString(Docname); + char* htmlEncoding; + fName->append(".html"); + + if (!(fContentsFrame = fopen(getFileNameFromPath(fName->getCString(),fName->getLength()), "w"))){ + delete fName; + error(-1, "Couldn't open html file '%s'", fName->getCString()); + return; + } + + delete fName; + + fName=basename(Docname); + fputs(DOCTYPE_FRAMES, fContentsFrame); + fputs("\n",fContentsFrame); + fputs("\n",fContentsFrame); + fprintf(fContentsFrame,"\n%s",docTitle->getCString()); + htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName()); + fprintf(fContentsFrame, "\n\n", htmlEncoding); + dumpMetaVars(fContentsFrame); + fprintf(fContentsFrame, "\n"); + fputs("\n",fContentsFrame); + fprintf(fContentsFrame,"\n",fName->getCString()); + fputs("getCString(), firstPage); + else + fprintf(fContentsFrame,"\"%ss.html\"",fName->getCString()); + + fputs(">\n\n\n",fContentsFrame); + + delete fName; + fclose(fContentsFrame); +} + +HtmlOutputDev::HtmlOutputDev(char *fileName, char *title, + char *author, char *keywords, char *subject, char *date, + char *extension, + GBool rawOrder, int firstPage, GBool outline) +{ + char *htmlEncoding; + + fContentsFrame = NULL; + docTitle = new GooString(title); + pages = NULL; + dumpJPEG=gTrue; + //write = gTrue; + this->rawOrder = rawOrder; + this->doOutline = outline; + ok = gFalse; + imgNum=1; + //this->firstPage = firstPage; + //pageNum=firstPage; + // open file + needClose = gFalse; + pages = new HtmlPage(rawOrder, extension); + + glMetaVars = new GooList(); + glMetaVars->append(new HtmlMetaVar("generator", "pdftohtml 0.36")); + if( author ) glMetaVars->append(new HtmlMetaVar("author", author)); + if( keywords ) glMetaVars->append(new HtmlMetaVar("keywords", keywords)); + if( date ) glMetaVars->append(new HtmlMetaVar("date", date)); + if( subject ) glMetaVars->append(new HtmlMetaVar("subject", subject)); + + maxPageWidth = 0; + maxPageHeight = 0; + + pages->setDocName(fileName); + Docname=new GooString (fileName); + + // for non-xml output (complex or simple) with frames generate the left frame + if(!xml && !noframes) + { + GooString* left=new GooString(fileName); + left->append("_ind.html"); + + doFrame(firstPage); + + if (!(fContentsFrame = fopen(getFileNameFromPath(left->getCString(),left->getLength()), "w"))) + { + error(-1, "Couldn't open html file '%s'", left->getCString()); + delete left; + return; + } + delete left; + fputs(DOCTYPE, fContentsFrame); + fputs("\n\n\n\n\n",fContentsFrame); + + if (doOutline) + { + GooString *str = basename(Docname); + fprintf(fContentsFrame, "Outline
", str->getCString(), complexMode ? "-outline.html" : "s.html#outline"); + delete str; + } + + if (!complexMode) + { /* not in complex mode */ + + GooString* right=new GooString(fileName); + right->append("s.html"); + + if (!(page=fopen(getFileNameFromPath(right->getCString(),right->getLength()),"w"))){ + error(-1, "Couldn't open html file '%s'", right->getCString()); + delete right; + return; + } + delete right; + fputs(DOCTYPE, page); + fputs("\n\n\n\n\n",page); + } + } + + if (noframes) { + if (stout) page=stdout; + else { + GooString* right=new GooString(fileName); + if (!xml) right->append(".html"); + if (xml) right->append(".xml"); + if (!(page=fopen(getFileNameFromPath(right->getCString(),right->getLength()),"w"))){ + delete right; + error(-1, "Couldn't open html file '%s'", right->getCString()); + return; + } + delete right; + } + + htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName()); + if (xml) + { + fprintf(page, "\n", htmlEncoding); + fputs("\n\n", page); + fputs("\n",page); + } + else + { + fprintf(page,"%s\n\n\n%s\n", + DOCTYPE, docTitle->getCString()); + + fprintf(page, "\n", htmlEncoding); + + dumpMetaVars(page); + fprintf(page,"\n"); + fprintf(page,"\n"); + } + } + ok = gTrue; +} + +HtmlOutputDev::~HtmlOutputDev() { + /*if (mode&&!xml){ + int h=xoutRound(pages->pageHeight/scale); + int w=xoutRound(pages->pageWidth/scale); + fprintf(tin,"%s=%03d\n","PAPER_WIDTH",w); + fprintf(tin,"%s=%03d\n","PAPER_HEIGHT",h); + fclose(tin); + }*/ + + HtmlFont::clear(); + + delete Docname; + delete docTitle; + + deleteGooList(glMetaVars, HtmlMetaVar); + + if (fContentsFrame){ + fputs("\n\n",fContentsFrame); + fclose(fContentsFrame); + } + if (xml) { + fputs("\n",page); + fclose(page); + } else + if ( !complexMode || xml || noframes ) + { + fputs("\n\n",page); + fclose(page); + } + if (pages) + delete pages; +} + + + +void HtmlOutputDev::startPage(int pageNum, GfxState *state) { + /*if (mode&&!xml){ + if (write){ + write=gFalse; + GooString* fname=Dirname(Docname); + fname->append("image.log"); + if((tin=fopen(getFileNameFromPath(fname->getCString(),fname->getLength()),"w"))==NULL){ + printf("Error : can not open %s",fname); + exit(1); + } + delete fname; + // if(state->getRotation()!=0) + // fprintf(tin,"ROTATE=%d rotate %d neg %d neg translate\n",state->getRotation(),state->getX1(),-state->getY1()); + // else + fprintf(tin,"ROTATE=%d neg %d neg translate\n",state->getX1(),state->getY1()); + } + }*/ + + this->pageNum = pageNum; + GooString *str=basename(Docname); + pages->clear(); + if(!noframes) + { + if (fContentsFrame) + { + if (complexMode) + fprintf(fContentsFrame,"getCString(),pageNum); + else + fprintf(fContentsFrame,"getCString(),pageNum); + fprintf(fContentsFrame," target=\"contents\" >Page %d
\n",pageNum); + } + } + + pages->pageWidth=static_cast(state->getPageWidth()); + pages->pageHeight=static_cast(state->getPageHeight()); + + delete str; +} + + +void HtmlOutputDev::endPage() { + pages->conv(); + pages->coalesce(); + pages->dump(page, pageNum); + + // I don't yet know what to do in the case when there are pages of different + // sizes and we want complex output: running ghostscript many times + // seems very inefficient. So for now I'll just use last page's size + maxPageWidth = pages->pageWidth; + maxPageHeight = pages->pageHeight; + + //if(!noframes&&!xml) fputs("
\n", fContentsFrame); + if(!stout && !globalParams->getErrQuiet()) printf("Page-%d\n",(pageNum)); +} + +void HtmlOutputDev::updateFont(GfxState *state) { + pages->updateFont(state); +} + +void HtmlOutputDev::beginString(GfxState *state, GooString *s) { + pages->beginString(state, s); +} + +void HtmlOutputDev::endString(GfxState *state) { + pages->endString(); +} + +void HtmlOutputDev::drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int /*nBytes*/, Unicode *u, int uLen) +{ + if ( !showHidden && (state->getRender() & 3) == 3) { + return; + } + pages->addChar(state, x, y, dx, dy, originX, originY, u, uLen); +} + +void HtmlOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + + int i, j; + + if (ignore||complexMode) { + OutputDev::drawImageMask(state, ref, str, width, height, invert, inlineImg); + return; + } + + FILE *f1; + int c; + + int x0, y0; // top left corner of image + int w0, h0, w1, h1; // size of image + double xt, yt, wt, ht; + GBool rotate, xFlip, yFlip; + GBool dither; + int x, y; + int ix, iy; + int px1, px2, qx, dx; + int py1, py2, qy, dy; + Gulong pixel; + int nComps, nVals, nBits; + double r1, g1, b1; + + // get image position and size + state->transform(0, 0, &xt, &yt); + state->transformDelta(1, 1, &wt, &ht); + if (wt > 0) { + x0 = xoutRound(xt); + w0 = xoutRound(wt); + } else { + x0 = xoutRound(xt + wt); + w0 = xoutRound(-wt); + } + if (ht > 0) { + y0 = xoutRound(yt); + h0 = xoutRound(ht); + } else { + y0 = xoutRound(yt + ht); + h0 = xoutRound(-ht); + } + state->transformDelta(1, 0, &xt, &yt); + rotate = fabs(xt) < fabs(yt); + if (rotate) { + w1 = h0; + h1 = w0; + xFlip = ht < 0; + yFlip = wt > 0; + } else { + w1 = w0; + h1 = h0; + xFlip = wt < 0; + yFlip = ht > 0; + } + + // dump JPEG file + if (dumpJPEG && str->getKind() == strDCT) { + GooString *fName=new GooString(Docname); + fName->append("-"); + GooString *pgNum=GooString::fromInt(pageNum); + GooString *imgnum=GooString::fromInt(imgNum); + // open the image file + fName->append(pgNum)->append("_")->append(imgnum)->append(".jpg"); + ++imgNum; + if (!(f1 = fopen(getFileNameFromPath(fName->getCString(),fName->getLength()), "wb"))) { + error(-1, "Couldn't open image file '%s'", fName->getCString()); + return; + } + + // initialize stream + str = ((DCTStream *)str)->getRawStream(); + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f1); + + fclose(f1); + + if (pgNum) delete pgNum; + if (imgnum) delete imgnum; + if (fName) delete fName; + } + else { + OutputDev::drawImageMask(state, ref, str, width, height, invert, inlineImg); + } +} + +void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) { + + int i, j; + + if (ignore||complexMode) { + OutputDev::drawImage(state, ref, str, width, height, colorMap, + maskColors, inlineImg); + return; + } + + FILE *f1; + ImageStream *imgStr; + Guchar pixBuf[4]; + GfxColor color; + int c; + + int x0, y0; // top left corner of image + int w0, h0, w1, h1; // size of image + double xt, yt, wt, ht; + GBool rotate, xFlip, yFlip; + GBool dither; + int x, y; + int ix, iy; + int px1, px2, qx, dx; + int py1, py2, qy, dy; + Gulong pixel; + int nComps, nVals, nBits; + double r1, g1, b1; + + // get image position and size + state->transform(0, 0, &xt, &yt); + state->transformDelta(1, 1, &wt, &ht); + if (wt > 0) { + x0 = xoutRound(xt); + w0 = xoutRound(wt); + } else { + x0 = xoutRound(xt + wt); + w0 = xoutRound(-wt); + } + if (ht > 0) { + y0 = xoutRound(yt); + h0 = xoutRound(ht); + } else { + y0 = xoutRound(yt + ht); + h0 = xoutRound(-ht); + } + state->transformDelta(1, 0, &xt, &yt); + rotate = fabs(xt) < fabs(yt); + if (rotate) { + w1 = h0; + h1 = w0; + xFlip = ht < 0; + yFlip = wt > 0; + } else { + w1 = w0; + h1 = h0; + xFlip = wt < 0; + yFlip = ht > 0; + } + + + /*if( !globalParams->getErrQuiet() ) + printf("image stream of kind %d\n", str->getKind());*/ + // dump JPEG file + if (dumpJPEG && str->getKind() == strDCT) { + GooString *fName=new GooString(Docname); + fName->append("-"); + GooString *pgNum= GooString::fromInt(pageNum); + GooString *imgnum= GooString::fromInt(imgNum); + + // open the image file + fName->append(pgNum)->append("_")->append(imgnum)->append(".jpg"); + ++imgNum; + + if (!(f1 = fopen(getFileNameFromPath(fName->getCString(),fName->getLength()), "wb"))) { + error(-1, "Couldn't open image file '%s'", fName->getCString()); + return; + } + + // initialize stream + str = ((DCTStream *)str)->getRawStream(); + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f1); + + fclose(f1); + + delete fName; + delete pgNum; + delete imgnum; + } + else { + OutputDev::drawImage(state, ref, str, width, height, colorMap, + maskColors, inlineImg); + } +} + + + +void HtmlOutputDev::drawLink(Link* link,Catalog *cat){ + double _x1,_y1,_x2,_y2,w; + int x1,y1,x2,y2; + + link->getRect(&_x1,&_y1,&_x2,&_y2); + w = link->getBorderStyle()->getWidth(); + cvtUserToDev(_x1,_y1,&x1,&y1); + + cvtUserToDev(_x2,_y2,&x2,&y2); + + + GooString* _dest=getLinkDest(link,cat); + HtmlLink t((double) x1,(double) y2,(double) x2,(double) y1,_dest); + pages->AddLink(t); + delete _dest; +} + +GooString* HtmlOutputDev::getLinkDest(Link *link,Catalog* catalog){ + char *p; + switch(link->getAction()->getKind()) + { + case actionGoTo: + { + GooString* file=basename(Docname); + int page=1; + LinkGoTo *ha=(LinkGoTo *)link->getAction(); + LinkDest *dest=NULL; + if (ha->getDest()==NULL) + dest=catalog->findDest(ha->getNamedDest()); + else + dest=ha->getDest()->copy(); + if (dest){ + if (dest->isPageRef()){ + Ref pageref=dest->getPageRef(); + page=catalog->findPage(pageref.num,pageref.gen); + } + else { + page=dest->getPageNum(); + } + + delete dest; + + GooString *str=GooString::fromInt(page); + /* complex simple + frames file-4.html files.html#4 + noframes file.html#4 file.html#4 + */ + if (noframes) + { + file->append(".html#"); + file->append(str); + } + else + { + if( complexMode ) + { + file->append("-"); + file->append(str); + file->append(".html"); + } + else + { + file->append("s.html#"); + file->append(str); + } + } + + if (printCommands) printf(" link to page %d ",page); + delete str; + return file; + } + else + { + return new GooString(); + } + } + case actionGoToR: + { + LinkGoToR *ha=(LinkGoToR *) link->getAction(); + LinkDest *dest=NULL; + int page=1; + GooString *file=new GooString(); + if (ha->getFileName()){ + delete file; + file=new GooString(ha->getFileName()->getCString()); + } + if (ha->getDest()!=NULL) dest=ha->getDest()->copy(); + if (dest&&file){ + if (!(dest->isPageRef())) page=dest->getPageNum(); + delete dest; + + if (printCommands) printf(" link to page %d ",page); + if (printHtml){ + p=file->getCString()+file->getLength()-4; + if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")){ + file->del(file->getLength()-4,4); + file->append(".html"); + } + file->append('#'); + file->append(GooString::fromInt(page)); + } + } + if (printCommands) printf("filename %s\n",file->getCString()); + return file; + } + case actionURI: + { + LinkURI *ha=(LinkURI *) link->getAction(); + GooString* file=new GooString(ha->getURI()->getCString()); + // printf("uri : %s\n",file->getCString()); + return file; + } + case actionLaunch: + { + LinkLaunch *ha=(LinkLaunch *) link->getAction(); + GooString* file=new GooString(ha->getFileName()->getCString()); + if (printHtml) { + p=file->getCString()+file->getLength()-4; + if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")){ + file->del(file->getLength()-4,4); + file->append(".html"); + } + if (printCommands) printf("filename %s",file->getCString()); + + return file; + + } + } + default: + return new GooString(); + } +} + +void HtmlOutputDev::dumpMetaVars(FILE *file) +{ + GooString *var; + + for(int i = 0; i < glMetaVars->getLength(); i++) + { + HtmlMetaVar *t = (HtmlMetaVar*)glMetaVars->get(i); + var = t->toString(); + fprintf(file, "%s\n", var->getCString()); + delete var; + } +} + +GBool HtmlOutputDev::dumpDocOutline(Catalog* catalog) +{ + FILE * output; + GBool bClose = gFalse; + + if (!ok || xml) + return gFalse; + + Object *outlines = catalog->getOutline(); + if (!outlines->isDict()) + return gFalse; + + if (!complexMode && !xml) + { + output = page; + } + else if (complexMode && !xml) + { + if (noframes) + { + output = page; + fputs("
\n", output); + } + else + { + GooString *str = basename(Docname); + str->append("-outline.html"); + output = fopen(getFileNameFromPath(str->getCString(),str->getLength()), "w"); + if (output == NULL) + return gFalse; + delete str; + bClose = gTrue; + fputs("\n\nDocument Outline\n\n\n", output); + } + } + + GBool done = newOutlineLevel(output, outlines, catalog); + if (done && !complexMode) + fputs("
\n", output); + + if (bClose) + { + fputs("\n\n", output); + fclose(output); + } + return done; +} + +GBool HtmlOutputDev::newOutlineLevel(FILE *output, Object *node, Catalog* catalog, int level) +{ + Object curr, next; + GBool atLeastOne = gFalse; + + if (node->dictLookup("First", &curr)->isDict()) { + if (level == 1) + { + fputs("", output); + fputs("

Document Outline

\n", output); + } + fputs("
    ",output); + do { + // get title, give up if not found + Object title; + if (curr.dictLookup("Title", &title)->isNull()) { + title.free(); + break; + } + GooString *titleStr = new GooString(title.getString()); + title.free(); + + // get corresponding link + // Note: some code duplicated from HtmlOutputDev::getLinkDest(). + GooString *linkName = NULL;; + Object dest; + if (!curr.dictLookup("Dest", &dest)->isNull()) { + LinkGoTo *link = new LinkGoTo(&dest); + LinkDest *linkdest=NULL; + if (link->getDest()==NULL) + linkdest=catalog->findDest(link->getNamedDest()); + else + linkdest=link->getDest()->copy(); + delete link; + if (linkdest) { + int page; + if (linkdest->isPageRef()) { + Ref pageref=linkdest->getPageRef(); + page=catalog->findPage(pageref.num,pageref.gen); + } else { + page=linkdest->getPageNum(); + } + delete linkdest; + + /* complex simple + frames file-4.html files.html#4 + noframes file.html#4 file.html#4 + */ + linkName=basename(Docname); + GooString *str=GooString::fromInt(page); + if (noframes) { + linkName->append(".html#"); + linkName->append(str); + } else { + if( complexMode ) { + linkName->append("-"); + linkName->append(str); + linkName->append(".html"); + } else { + linkName->append("s.html#"); + linkName->append(str); + } + } + delete str; + } + } + dest.free(); + + fputs("
  • ",output); + if (linkName) + fprintf(output,"", linkName->getCString()); + fputs(titleStr->getCString(),output); + if (linkName) { + fputs("",output); + delete linkName; + } + fputs("\n",output); + delete titleStr; + atLeastOne = gTrue; + + newOutlineLevel(output, &curr, catalog, level+1); + curr.dictLookup("Next", &next); + curr.free(); + curr = next; + } while(curr.isDict()); + fputs("
",output); + } + curr.free(); + + return atLeastOne; +} + +char* getFileNameFromPath(char* c, int strlen) { + int last_slash_index = 0; + int i = 0; + char* res; + + for (i=0;i +#include "goo/gtypes.h" +#include "goo/GooList.h" +#include "GfxFont.h" +#include "OutputDev.h" +#include "HtmlLinks.h" +#include "HtmlFonts.h" +#include "Link.h" +#include "Catalog.h" +#include "UnicodeMap.h" + + +#ifdef WIN32 +# define SLASH '\\' +#else +# define SLASH '/' +#endif + +#define xoutRound(x) ((int)(x + 0.5)) + +#define DOCTYPE "" +#define DOCTYPE_FRAMES "" + +class GfxState; +class GooString; +//------------------------------------------------------------------------ +// HtmlString +//------------------------------------------------------------------------ + +enum UnicodeTextDirection { + textDirUnknown, + textDirLeftRight, + textDirRightLeft, + textDirTopBottom +}; + + +class HtmlString { +public: + + // Constructor. + HtmlString(GfxState *state, double fontSize, HtmlFontAccu* fonts); + + // Destructor. + ~HtmlString(); + + // Add a character to the string. + void addChar(GfxState *state, double x, double y, + double dx, double dy, + Unicode u); + HtmlLink* getLink() { return link; } + void endString(); // postprocessing + +private: +// aender die text variable + HtmlLink *link; + double xMin, xMax; // bounding box x coordinates + double yMin, yMax; // bounding box y coordinates + int col; // starting column + Unicode *text; // the text + double *xRight; // right-hand x coord of each char + HtmlString *yxNext; // next string in y-major order + HtmlString *xyNext; // next string in x-major order + int fontpos; + GooString* htext; + int len; // length of text and xRight + int size; // size of text and xRight arrays + UnicodeTextDirection dir; // direction (left to right/right to left) + + friend class HtmlPage; + +}; + + +//------------------------------------------------------------------------ +// HtmlPage +//------------------------------------------------------------------------ + + + +class HtmlPage { +public: + + // Constructor. + HtmlPage(GBool rawOrder, char *imgExtVal); + + // Destructor. + ~HtmlPage(); + + // Begin a new string. + void beginString(GfxState *state, GooString *s); + + // Add a character to the current string. + void addChar(GfxState *state, double x, double y, + double dx, double dy, + double ox, double oy, + Unicode *u, int uLen); //Guchar c); + + void updateFont(GfxState *state); + + // End the current string, sorting it into the list of strings. + void endString(); + + // Coalesce strings that look like parts of the same line. + void coalesce(); + + // Find a string. If is true, starts looking at top of page; + // otherwise starts looking at ,. If is true, + // stops looking at bottom of page; otherwise stops looking at + // ,. If found, sets the text bounding rectange and + // returns true; otherwise returns false. + + + // new functions + void AddLink(const HtmlLink& x){ + links->AddLink(x); + } + + void dump(FILE *f, int pageNum); + + // Clear the page. + void clear(); + + void conv(); +private: + HtmlFont* getFont(HtmlString *hStr) { return fonts->Get(hStr->fontpos); } + + double fontSize; // current font size + GBool rawOrder; // keep strings in content stream order + + HtmlString *curStr; // currently active string + + HtmlString *yxStrings; // strings in y-major order + HtmlString *xyStrings; // strings in x-major order + HtmlString *yxCur1, *yxCur2; // cursors for yxStrings list + + void setDocName(char* fname); + void dumpAsXML(FILE* f,int page); + void dumpComplex(FILE* f, int page); + + // marks the position of the fonts that belong to current page (for noframes) + int fontsPageMarker; + HtmlFontAccu *fonts; + HtmlLinks *links; + + GooString *DocName; + GooString *imgExt; + int pageWidth; + int pageHeight; + static int pgNum; + int firstPage; // used to begin the numeration of pages + + friend class HtmlOutputDev; +}; + +//------------------------------------------------------------------------ +// HtmlMetaVar +//------------------------------------------------------------------------ +class HtmlMetaVar { +public: + HtmlMetaVar(char *_name, char *_content); + ~HtmlMetaVar(); + + GooString* toString(); + +private: + + GooString *name; + GooString *content; +}; + +//------------------------------------------------------------------------ +// HtmlOutputDev +//------------------------------------------------------------------------ + +class HtmlOutputDev: public OutputDev { +public: + + // Open a text output file. If is NULL, no file is written + // (this is useful, e.g., for searching text). If is true, + // text is converted to 7-bit ASCII; otherwise, text is converted to + // 8-bit ISO Latin-1. should also be set for Japanese + // (EUC-JP) text. If is true, the text is kept in content + // stream order. + HtmlOutputDev(char *fileName, char *title, + char *author, + char *keywords, + char *subject, + char *date, + char *extension, + GBool rawOrder, + int firstPage = 1, + GBool outline = 0); + + // Destructor. + virtual ~HtmlOutputDev(); + + // Check if file was successfully created. + virtual GBool isOk() { return ok; } + + //---- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gTrue; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gTrue; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() { return gFalse; } + + // Does this device need non-text content? + virtual GBool needNonText() { return gFalse; } + + //----- initialization and control + + // Start a page. + virtual void startPage(int pageNum, GfxState *state); + + // End a page. + virtual void endPage(); + + //----- update text state + virtual void updateFont(GfxState *state); + + //----- text drawing + virtual void beginString(GfxState *state, GooString *s); + virtual void endString(GfxState *state); + virtual void drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, Unicode *u, int uLen); + + virtual void drawImageMask(GfxState *state, Object *ref, + Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg); + + //new feature + virtual int DevType() {return 1234;} + virtual void drawLink(Link *link,Catalog *cat); + + int getPageWidth() { return maxPageWidth; } + int getPageHeight() { return maxPageHeight; } + + GBool dumpDocOutline(Catalog* catalog); + + /* char* getFileNameFromPath(char* c, int strlen); */ + +private: + // convert encoding into a HTML standard, or encoding->getCString if not + // recognized + static char* mapEncodingToHtml(GooString* encoding); + GooString* getLinkDest(Link *link,Catalog *catalog); + void dumpMetaVars(FILE *); + void doFrame(int firstPage); + GBool newOutlineLevel(FILE *output, Object *node, Catalog* catalog, int level = 1); + + FILE *fContentsFrame; + FILE *page; // html file + //FILE *tin; // image log file + //GBool write; + GBool needClose; // need to close the file? + HtmlPage *pages; // text for the current page + GBool rawOrder; // keep text in content stream order + GBool doOutline; // output document outline + GBool ok; // set up ok? + GBool dumpJPEG; + int pageNum; + int maxPageWidth; + int maxPageHeight; + static int imgNum; + GooString *Docname; + GooString *docTitle; + GooList *glMetaVars; + friend class HtmlPage; +}; + +char* getFileNameFromPath(char* c, int strlen); + +#endif diff --git a/rosapps/smartpdf/poppler/utils/ImageOutputDev.cc b/rosapps/smartpdf/poppler/utils/ImageOutputDev.cc new file mode 100644 index 00000000000..6c2b428edf7 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/ImageOutputDev.cc @@ -0,0 +1,197 @@ +//======================================================================== +// +// ImageOutputDev.cc +// +// Copyright 1998-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include "config.h" +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include +#include "goo/gmem.h" +#include "Error.h" +#include "GfxState.h" +#include "Object.h" +#include "Stream.h" +#ifdef ENABLE_LIBJPEG +#include "DCTStream.h" +#endif +#include "ImageOutputDev.h" + +ImageOutputDev::ImageOutputDev(char *fileRootA, GBool dumpJPEGA) { + fileRoot = copyString(fileRootA); + fileName = (char *)gmalloc(strlen(fileRoot) + 20); + dumpJPEG = dumpJPEGA; + imgNum = 0; + ok = gTrue; +} + +ImageOutputDev::~ImageOutputDev() { + gfree(fileName); + gfree(fileRoot); +} + +void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + FILE *f; + int c; + int size, i; + + // dump JPEG file + if (dumpJPEG && str->getKind() == strDCT && !inlineImg) { + + // open the image file + sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + + // initialize stream + str = ((DCTStream *)str)->getRawStream(); + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f); + + str->close(); + fclose(f); + + // dump PBM file + } else { + + // open the image file and write the PBM header + sprintf(fileName, "%s-%03d.pbm", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + fprintf(f, "P4\n"); + fprintf(f, "%d %d\n", width, height); + + // initialize stream + str->reset(); + + // copy the stream + size = height * ((width + 7) / 8); + for (i = 0; i < size; ++i) { + fputc(str->getChar(), f); + } + + str->close(); + fclose(f); + } +} + +void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) { + FILE *f; + ImageStream *imgStr; + Guchar *p; + GfxRGB rgb; + int x, y; + int c; + int size, i; + + // dump JPEG file + if (dumpJPEG && str->getKind() == strDCT && + colorMap->getNumPixelComps() == 3 && + !inlineImg) { + + // open the image file + sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + + // initialize stream + str = ((DCTStream *)str)->getRawStream(); + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f); + + str->close(); + fclose(f); + + // dump PBM file + } else if (colorMap->getNumPixelComps() == 1 && + colorMap->getBits() == 1) { + + // open the image file and write the PBM header + sprintf(fileName, "%s-%03d.pbm", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + fprintf(f, "P4\n"); + fprintf(f, "%d %d\n", width, height); + + // initialize stream + str->reset(); + + // copy the stream + size = height * ((width + 7) / 8); + for (i = 0; i < size; ++i) { + fputc(str->getChar() ^ 0xff, f); + } + + str->close(); + fclose(f); + + // dump PPM file + } else { + + // open the image file and write the PPM header + sprintf(fileName, "%s-%03d.ppm", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + fprintf(f, "P6\n"); + fprintf(f, "%d %d\n", width, height); + fprintf(f, "255\n"); + + // initialize stream + imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + // for each line... + for (y = 0; y < height; ++y) { + + // write the line + p = imgStr->getLine(); + for (x = 0; x < width; ++x) { + colorMap->getRGB(p, &rgb); + fputc(colToByte(rgb.r), f); + fputc(colToByte(rgb.g), f); + fputc(colToByte(rgb.b), f); + p += colorMap->getNumPixelComps(); + } + } + delete imgStr; + + fclose(f); + } +} diff --git a/rosapps/smartpdf/poppler/utils/ImageOutputDev.h b/rosapps/smartpdf/poppler/utils/ImageOutputDev.h new file mode 100644 index 00000000000..90c2e6f8b16 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/ImageOutputDev.h @@ -0,0 +1,76 @@ +//======================================================================== +// +// ImageOutputDev.h +// +// Copyright 1998-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef IMAGEOUTPUTDEV_H +#define IMAGEOUTPUTDEV_H + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include "goo/gtypes.h" +#include "OutputDev.h" + +class GfxState; + +//------------------------------------------------------------------------ +// ImageOutputDev +//------------------------------------------------------------------------ + +class ImageOutputDev: public OutputDev { +public: + + // Create an OutputDev which will write images to files named + // -NNN.. Normally, all images are written as PBM + // (.pbm) or PPM (.ppm) files. If is set, JPEG images are + // written as JPEG (.jpg) files. + ImageOutputDev(char *fileRootA, GBool dumpJPEGA); + + // Destructor. + virtual ~ImageOutputDev(); + + // Check if file was successfully created. + virtual GBool isOk() { return ok; } + + // Does this device use beginType3Char/endType3Char? Otherwise, + // text in Type 3 fonts will be drawn with drawChar/drawString. + virtual GBool interpretType3Chars() { return gFalse; } + + // Does this device need non-text content? + virtual GBool needNonText() { return gTrue; } + + //---- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gTrue; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gFalse; } + + //----- image drawing + virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg); + +private: + + char *fileRoot; // root of output file names + char *fileName; // buffer for output file names + GBool dumpJPEG; // set to dump native JPEG files + int imgNum; // current image number + GBool ok; // set up ok? +}; + +#endif diff --git a/rosapps/smartpdf/poppler/utils/Makefile.am b/rosapps/smartpdf/poppler/utils/Makefile.am new file mode 100644 index 00000000000..e6e2055cb3a --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/Makefile.am @@ -0,0 +1,80 @@ +if BUILD_SPLASH_OUTPUT + +pdftoppm_SOURCES = \ + pdftoppm.cc \ + $(common) + +pdftoppm_binary = pdftoppm + +pdftoppm_manpage = pdftoppm.1 + +endif + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/utils \ + -I$(top_srcdir)/poppler \ + $(UTILS_CFLAGS) \ + $(FONTCONFIG_CFLAGS) + +LDADD = \ + $(top_builddir)/poppler/libpoppler.la \ + $(UTILS_LIBS) \ + $(FONTCONFIG_LIBS) + +bin_PROGRAMS = \ + pdffonts \ + pdfimages \ + pdfinfo \ + pdftops \ + pdftotext \ + pdftohtml \ + $(pdftoppm_binary) + +dist_man1_MANS = \ + pdffonts.1 \ + pdfimages.1 \ + pdfinfo.1 \ + pdftops.1 \ + pdftotext.1 \ + pdftohtml.1 \ + $(pdftoppm_manpage) + +common = parseargs.c parseargs.h + +pdffonts_SOURCES = \ + pdffonts.cc \ + $(common) + +pdfimages_SOURCES = \ + pdfimages.cc \ + ImageOutputDev.cc \ + ImageOutputDev.h \ + $(common) + +pdfinfo_SOURCES = \ + pdfinfo.cc \ + $(common) + +pdftops_SOURCES = \ + pdftops.cc \ + $(common) + +pdftotext_SOURCES = \ + pdftotext.cc \ + $(common) + +pdftohtml_SOURCES = \ + pdftohtml.cc \ + HtmlFonts.cc \ + HtmlFonts.h \ + HtmlLinks.cc \ + HtmlLinks.h \ + HtmlOutputDev.cc \ + HtmlOutputDev.h \ + $(common) + +# Yay, automake! It should be able to figure out that it has to dist +# pdftoppm.1, but nooo. So we just add it here. + +EXTRA_DIST = pdf2xml.dtd pdftoppm.1 diff --git a/rosapps/smartpdf/poppler/utils/parseargs.c b/rosapps/smartpdf/poppler/utils/parseargs.c new file mode 100644 index 00000000000..9f579436ad0 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/parseargs.c @@ -0,0 +1,190 @@ +/* + * parseargs.h + * + * Command line argument parser. + * + * Copyright 1996-2003 Glyph & Cog, LLC + */ + +#include +#include +#include +#include +#include +#include "parseargs.h" + +static ArgDesc *findArg(ArgDesc *args, char *arg); +static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]); + +GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) { + ArgDesc *arg; + int i, j; + GBool ok; + + ok = gTrue; + i = 1; + while (i < *argc) { + if (!strcmp(argv[i], "--")) { + --*argc; + for (j = i; j < *argc; ++j) + argv[j] = argv[j+1]; + break; + } else if ((arg = findArg(args, argv[i]))) { + if (!grabArg(arg, i, argc, argv)) + ok = gFalse; + } else { + ++i; + } + } + return ok; +} + +void printUsage(char *program, char *otherArgs, ArgDesc *args) { + ArgDesc *arg; + char *typ; + int w, w1; + + w = 0; + for (arg = args; arg->arg; ++arg) { + if ((w1 = strlen(arg->arg)) > w) + w = w1; + } + + fprintf(stderr, "Usage: %s [options]", program); + if (otherArgs) + fprintf(stderr, " %s", otherArgs); + fprintf(stderr, "\n"); + + for (arg = args; arg->arg; ++arg) { + fprintf(stderr, " %s", arg->arg); + w1 = 9 + w - strlen(arg->arg); + switch (arg->kind) { + case argInt: + case argIntDummy: + typ = " "; + break; + case argFP: + case argFPDummy: + typ = " "; + break; + case argString: + case argStringDummy: + typ = " "; + break; + case argFlag: + case argFlagDummy: + default: + typ = ""; + break; + } + fprintf(stderr, "%-*s", w1, typ); + if (arg->usage) + fprintf(stderr, ": %s", arg->usage); + fprintf(stderr, "\n"); + } +} + +static ArgDesc *findArg(ArgDesc *args, char *arg) { + ArgDesc *p; + + for (p = args; p->arg; ++p) { + if (p->kind < argFlagDummy && !strcmp(p->arg, arg)) + return p; + } + return NULL; +} + +static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]) { + int n; + int j; + GBool ok; + + ok = gTrue; + n = 0; + switch (arg->kind) { + case argFlag: + *(GBool *)arg->val = gTrue; + n = 1; + break; + case argInt: + if (i + 1 < *argc && isInt(argv[i+1])) { + *(int *)arg->val = atoi(argv[i+1]); + n = 2; + } else { + ok = gFalse; + n = 1; + } + break; + case argFP: + if (i + 1 < *argc && isFP(argv[i+1])) { + *(double *)arg->val = atof(argv[i+1]); + n = 2; + } else { + ok = gFalse; + n = 1; + } + break; + case argString: + if (i + 1 < *argc) { + strncpy((char *)arg->val, argv[i+1], arg->size - 1); + ((char *)arg->val)[arg->size - 1] = '\0'; + n = 2; + } else { + ok = gFalse; + n = 1; + } + break; + default: + fprintf(stderr, "Internal error in arg table\n"); + n = 1; + break; + } + if (n > 0) { + *argc -= n; + for (j = i; j < *argc; ++j) + argv[j] = argv[j+n]; + } + return ok; +} + +GBool isInt(char *s) { + if (*s == '-' || *s == '+') + ++s; + while (isdigit(*s)) + ++s; + if (*s) + return gFalse; + return gTrue; +} + +GBool isFP(char *s) { + int n; + + if (*s == '-' || *s == '+') + ++s; + n = 0; + while (isdigit(*s)) { + ++s; + ++n; + } + if (*s == '.') + ++s; + while (isdigit(*s)) { + ++s; + ++n; + } + if (n > 0 && (*s == 'e' || *s == 'E')) { + ++s; + if (*s == '-' || *s == '+') + ++s; + n = 0; + if (!isdigit(*s)) + return gFalse; + do { + ++s; + } while (isdigit(*s)); + } + if (*s) + return gFalse; + return gTrue; +} diff --git a/rosapps/smartpdf/poppler/utils/parseargs.h b/rosapps/smartpdf/poppler/utils/parseargs.h new file mode 100644 index 00000000000..1b1c570e8b1 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/parseargs.h @@ -0,0 +1,71 @@ +/* + * parseargs.h + * + * Command line argument parser. + * + * Copyright 1996-2003 Glyph & Cog, LLC + */ + +#ifndef PARSEARGS_H +#define PARSEARGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "goo/gtypes.h" + +/* + * Argument kinds. + */ +typedef enum { + argFlag, /* flag (present / not-present) */ + /* [val: GBool *] */ + argInt, /* integer arg */ + /* [val: int *] */ + argFP, /* floating point arg */ + /* [val: double *] */ + argString, /* string arg */ + /* [val: char *] */ + /* dummy entries -- these show up in the usage listing only; */ + /* useful for X args, for example */ + argFlagDummy, + argIntDummy, + argFPDummy, + argStringDummy +} ArgKind; + +/* + * Argument descriptor. + */ +typedef struct { + char *arg; /* the command line switch */ + ArgKind kind; /* kind of arg */ + void *val; /* place to store value */ + int size; /* for argString: size of string */ + char *usage; /* usage string */ +} ArgDesc; + +/* + * Parse command line. Removes all args which are found in the arg + * descriptor list . Stops parsing if "--" is found (and removes + * it). Returns gFalse if there was an error. + */ +extern GBool parseArgs(ArgDesc *args, int *argc, char *argv[]); + +/* + * Print usage message, based on arg descriptor list. + */ +extern void printUsage(char *program, char *otherArgs, ArgDesc *args); + +/* + * Check if a string is a valid integer or floating point number. + */ +extern GBool isInt(char *s); +extern GBool isFP(char *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rosapps/smartpdf/poppler/utils/pdf2xml.dtd b/rosapps/smartpdf/poppler/utils/pdf2xml.dtd new file mode 100644 index 00000000000..1afa4fe9aa0 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdf2xml.dtd @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/rosapps/smartpdf/poppler/utils/pdffonts.1 b/rosapps/smartpdf/poppler/utils/pdffonts.1 new file mode 100644 index 00000000000..73246903083 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdffonts.1 @@ -0,0 +1,128 @@ +.\" Copyright 1999-2004 Glyph & Cog, LLC +.TH pdffonts 1 "22 January 2004" +.SH NAME +pdffonts \- Portable Document Format (PDF) font analyzer (version +3.00) +.SH SYNOPSIS +.B pdffonts +[options] +.RI [ PDF-file ] +.SH DESCRIPTION +.B Pdffonts +lists the fonts used in a Portable Document Format (PDF) file along +with various information for each font. +.PP +The following information is listed for each font: +.TP +.B name +the font name, exactly as given in the PDF file (potentially including +a subset prefix) +.TP +.B type +the font type -- see below for details +.TP +.B emb +"yes" if the font is embedded in the PDF file +.TP +.B sub +"yes" if the font is a subset +.TP +.B uni +"yes" if there is an explicit "ToUnicode" map in the PDF file (the +absence of a ToUnicode map doesn't necessarily mean that the text +can't be converted to Unicode) +.TP +.B object ID +the font dictionary object ID (number and generation) +.PP +PDF files can contain the following types of fonts: +.PP +.RS +Type 1 +.RE +.RS +Type 1C -- aka Compact Font Format (CFF) +.RE +.RS +Type 3 +.RE +.RS +TrueType +.RE +.RS +CID Type 0 -- 16-bit font with no specified type +.RE +.RS +CID Type 0C -- 16-bit PostScript CFF font +.RE +.RS +CID TrueType -- 16-bit TrueType font +.RE +.SH CONFIGURATION FILE +Pdffonts reads a configuration file at startup. It first tries to +find the user's private config file, ~/.xpdfrc. If that doesn't +exist, it looks for a system-wide config file, /etc/xpdf/xpdfrc. See the +.BR xpdfrc (5) +man page for details. +.SH OPTIONS +Many of the following options can be set with configuration file +commands. These are listed in square brackets with the description of +the corresponding command line option. +.TP +.BI \-f " number" +Specifies the first page to analyze. +.TP +.BI \-l " number" +Specifies the last page to analyze. +.TP +.BI \-opw " password" +Specify the owner password for the PDF file. Providing this will +bypass all security restrictions. +.TP +.BI \-upw " password" +Specify the user password for the PDF file. +.TP +.BI \-cfg " config-file" +Read +.I config-file +in place of ~/.xpdfrc or the system-wide config file. +.TP +.B \-v +Print copyright and version information. +.TP +.B \-h +Print usage information. +.RB ( \-help +and +.B \-\-help +are equivalent.) +.SH EXIT CODES +The Xpdf tools use the following exit codes: +.TP +0 +No error. +.TP +1 +Error opening a PDF file. +.TP +2 +Error opening an output file. +.TP +3 +Error related to PDF permissions. +.TP +99 +Other error. +.SH AUTHOR +The pdffonts software and documentation are copyright 1996-2004 Glyph +& Cog, LLC. +.SH "SEE ALSO" +.BR xpdf (1), +.BR pdftops (1), +.BR pdftotext (1), +.BR pdfinfo (1), +.BR pdftoppm (1), +.BR pdfimages (1), +.BR xpdfrc (5) +.br +.B http://www.foolabs.com/xpdf/ diff --git a/rosapps/smartpdf/poppler/utils/pdffonts.cc b/rosapps/smartpdf/poppler/utils/pdffonts.cc new file mode 100644 index 00000000000..1c5e3244ac6 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdffonts.cc @@ -0,0 +1,304 @@ +//======================================================================== +// +// pdffonts.cc +// +// Copyright 2001-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include "parseargs.h" +#include "goo/GooString.h" +#include "goo/gmem.h" +#include "GlobalParams.h" +#include "Error.h" +#include "Object.h" +#include "Dict.h" +#include "GfxFont.h" +#include "Annot.h" +#include "PDFDoc.h" +#include "UGooString.h" + +static char *fontTypeNames[] = { + "unknown", + "Type 1", + "Type 1C", + "Type 3", + "TrueType", + "CID Type 0", + "CID Type 0C", + "CID TrueType" +}; + +static void scanFonts(Dict *resDict, PDFDoc *doc); +static void scanFont(GfxFont *font, PDFDoc *doc); + +static int firstPage = 1; +static int lastPage = 0; +static char ownerPassword[33] = "\001"; +static char userPassword[33] = "\001"; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; + +static ArgDesc argDesc[] = { + {"-f", argInt, &firstPage, 0, + "first page to examine"}, + {"-l", argInt, &lastPage, 0, + "last page to examine"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, + {"-h", argFlag, &printHelp, 0, + "print usage information"}, + {"-help", argFlag, &printHelp, 0, + "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, + {NULL} +}; + +static Ref *fonts; +static int fontsLen; +static int fontsSize; + +int main(int argc, char *argv[]) { + PDFDoc *doc; + GooString *fileName; + GooString *ownerPW, *userPW; + GBool ok; + Page *page; + Dict *resDict; + Annots *annots; + Object obj1, obj2; + int pg, i; + int exitCode; + + exitCode = 99; + + // parse args + ok = parseArgs(argDesc, &argc, argv); + if (!ok || argc != 2 || printVersion || printHelp) { + fprintf(stderr, "pdffonts version %s\n", xpdfVersion); + fprintf(stderr, "%s\n", xpdfCopyright); + if (!printVersion) { + printUsage("pdffonts", "", argDesc); + } + goto err0; + } + fileName = new GooString(argv[1]); + + // read config file + globalParams = new GlobalParams(cfgFileName); + + // open PDF file + if (ownerPassword[0] != '\001') { + ownerPW = new GooString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0] != '\001') { + userPW = new GooString(userPassword); + } else { + userPW = NULL; + } + + if(fileName->cmp("-") != 0) { + doc = new PDFDoc(fileName, ownerPW, userPW); + } else { + Object obj; + + obj.initNull(); + doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + } + + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + exitCode = 1; + goto err1; + } + + // get page range + if (firstPage < 1) { + firstPage = 1; + } + if (lastPage < 1 || lastPage > doc->getNumPages()) { + lastPage = doc->getNumPages(); + } + + // scan the fonts + printf("name type emb sub uni object ID\n"); + printf("------------------------------------ ------------ --- --- --- ---------\n"); + fonts = NULL; + fontsLen = fontsSize = 0; + for (pg = firstPage; pg <= lastPage; ++pg) { + page = doc->getCatalog()->getPage(pg); + if ((resDict = page->getResourceDict())) { + scanFonts(resDict, doc); + } + annots = new Annots(doc->getXRef(), + doc->getCatalog(), + page->getAnnots(&obj1)); + obj1.free(); + for (i = 0; i < annots->getNumAnnots(); ++i) { + if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) { + obj1.streamGetDict()->lookup("Resources", &obj2); + if (obj2.isDict()) { + scanFonts(obj2.getDict(), doc); + } + obj2.free(); + } + obj1.free(); + } + delete annots; + } + + exitCode = 0; + + // clean up + gfree(fonts); + err1: + delete doc; + delete globalParams; + err0: + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + return exitCode; +} + +static void scanFonts(Dict *resDict, PDFDoc *doc) { + Object obj1, obj2, xObjDict, xObj, resObj; + Ref r; + GfxFontDict *gfxFontDict; + GfxFont *font; + int i; + + // scan the fonts in this resource dictionary + gfxFontDict = NULL; + resDict->lookupNF("Font", &obj1); + if (obj1.isRef()) { + obj1.fetch(doc->getXRef(), &obj2); + if (obj2.isDict()) { + r = obj1.getRef(); + gfxFontDict = new GfxFontDict(doc->getXRef(), &r, obj2.getDict()); + } + obj2.free(); + } else if (obj1.isDict()) { + gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict()); + } + if (gfxFontDict) { + for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { + if ((font = gfxFontDict->getFont(i))) { + scanFont(font, doc); + } + } + delete gfxFontDict; + } + obj1.free(); + + // recursively scan any resource dictionaries in objects in this + // resource dictionary + resDict->lookup("XObject", &xObjDict); + if (xObjDict.isDict()) { + for (i = 0; i < xObjDict.dictGetLength(); ++i) { + xObjDict.dictGetVal(i, &xObj); + if (xObj.isStream()) { + xObj.streamGetDict()->lookup("Resources", &resObj); + if (resObj.isDict()) { + scanFonts(resObj.getDict(), doc); + } + resObj.free(); + } + xObj.free(); + } + } + xObjDict.free(); +} + +static void scanFont(GfxFont *font, PDFDoc *doc) { + Ref fontRef, embRef; + Object fontObj, toUnicodeObj; + GooString *name; + GBool emb, subset, hasToUnicode; + int i; + + fontRef = *font->getID(); + + // check for an already-seen font + for (i = 0; i < fontsLen; ++i) { + if (fontRef.num == fonts[i].num && fontRef.gen == fonts[i].gen) { + return; + } + } + + // font name + name = font->getOrigName(); + + // check for an embedded font + if (font->getType() == fontType3) { + emb = gTrue; + } else { + emb = font->getEmbeddedFontID(&embRef); + } + + // look for a ToUnicode map + hasToUnicode = gFalse; + if (doc->getXRef()->fetch(fontRef.num, fontRef.gen, &fontObj)->isDict()) { + hasToUnicode = fontObj.dictLookup("ToUnicode", &toUnicodeObj)->isStream(); + toUnicodeObj.free(); + } + fontObj.free(); + + // check for a font subset name: capital letters followed by a '+' + // sign + subset = gFalse; + if (name) { + for (i = 0; i < name->getLength(); ++i) { + if (name->getChar(i) < 'A' || name->getChar(i) > 'Z') { + break; + } + } + subset = i > 0 && i < name->getLength() && name->getChar(i) == '+'; + } + + // print the font info + printf("%-36s %-12s %-3s %-3s %-3s", + name ? name->getCString() : "[none]", + fontTypeNames[font->getType()], + emb ? "yes" : "no", + subset ? "yes" : "no", + hasToUnicode ? "yes" : "no"); + if (fontRef.gen >= 100000) { + printf(" [none]\n"); + } else { + printf(" %6d %2d\n", fontRef.num, fontRef.gen); + } + + // add this font to the list + if (fontsLen == fontsSize) { + fontsSize += 32; + fonts = (Ref *)grealloc(fonts, fontsSize * sizeof(Ref)); + } + fonts[fontsLen++] = *font->getID(); +} diff --git a/rosapps/smartpdf/poppler/utils/pdfimages.1 b/rosapps/smartpdf/poppler/utils/pdfimages.1 new file mode 100644 index 00000000000..c580625ec3b --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdfimages.1 @@ -0,0 +1,96 @@ +.\" Copyright 1998-2004 Glyph & Cog, LLC +.TH pdfimages 1 "22 January 2004" +.SH NAME +pdfimages \- Portable Document Format (PDF) image extractor +(version 3.00) +.SH SYNOPSIS +.B pdfimages +[options] +.I PDF-file image-root +.SH DESCRIPTION +.B Pdfimages +saves images from a Portable Document Format (PDF) file as Portable +Pixmap (PPM), Portable Bitmap (PBM), or JPEG files. +.PP +Pdfimages reads the PDF file +.IR PDF-file , +scans one or more pages, and writes one PPM, PBM, or JPEG file for each image, +.IR image-root - nnn . xxx , +where +.I nnn +is the image number and +.I xxx +is the image type (.ppm, .pbm, .jpg). +.SH CONFIGURATION FILE +Pdfimages reads a configuration file at startup. It first tries to +find the user's private config file, ~/.xpdfrc. If that doesn't +exist, it looks for a system-wide config file, /etc/xpdf/xpdfrc. See the +.BR xpdfrc (5) +man page for details. +.SH OPTIONS +Many of the following options can be set with configuration file +commands. These are listed in square brackets with the description of +the corresponding command line option. +.TP +.BI \-f " number" +Specifies the first page to scan. +.TP +.BI \-l " number" +Specifies the last page to scan. +.TP +.B \-j +Normally, all images are written as PBM (for monochrome images) or PPM +(for non-monochrome images) files. With this option, images in DCT +format are saved as JPEG files. All non-DCT images are saved in +PBM/PPM format as usual. +.TP +.BI \-opw " password" +Specify the owner password for the PDF file. Providing this will +bypass all security restrictions. +.TP +.BI \-upw " password" +Specify the user password for the PDF file. +.TP +.B \-q +Don't print any messages or errors. +.RB "[config file: " errQuiet ] +.TP +.B \-v +Print copyright and version information. +.TP +.B \-h +Print usage information. +.RB ( \-help +and +.B \-\-help +are equivalent.) +.SH EXIT CODES +The Xpdf tools use the following exit codes: +.TP +0 +No error. +.TP +1 +Error opening a PDF file. +.TP +2 +Error opening an output file. +.TP +3 +Error related to PDF permissions. +.TP +99 +Other error. +.SH AUTHOR +The pdfimages software and documentation are copyright 1998-2004 Glyph +& Cog, LLC. +.SH "SEE ALSO" +.BR xpdf (1), +.BR pdftops (1), +.BR pdftotext (1), +.BR pdfinfo (1), +.BR pdffonts (1), +.BR pdftoppm (1), +.BR xpdfrc (5) +.br +.B http://www.foolabs.com/xpdf/ diff --git a/rosapps/smartpdf/poppler/utils/pdfimages.cc b/rosapps/smartpdf/poppler/utils/pdfimages.cc new file mode 100644 index 00000000000..0d4804ae06e --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdfimages.cc @@ -0,0 +1,159 @@ +//======================================================================== +// +// pdfimages.cc +// +// Copyright 1998-2003 Glyph & Cog, LLC +// +// Modified for Debian by Hamish Moffatt, 22 May 2002. +// +//======================================================================== + +#include "config.h" +#include +#include +#include +#include +#include +#include "parseargs.h" +#include "goo/GooString.h" +#include "goo/gmem.h" +#include "GlobalParams.h" +#include "Object.h" +#include "Stream.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "Catalog.h" +#include "Page.h" +#include "PDFDoc.h" +#include "ImageOutputDev.h" +#include "Error.h" + +static int firstPage = 1; +static int lastPage = 0; +static GBool dumpJPEG = gFalse; +static char ownerPassword[33] = "\001"; +static char userPassword[33] = "\001"; +static GBool quiet = gFalse; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; + +static ArgDesc argDesc[] = { + {"-f", argInt, &firstPage, 0, + "first page to convert"}, + {"-l", argInt, &lastPage, 0, + "last page to convert"}, + {"-j", argFlag, &dumpJPEG, 0, + "write JPEG images as JPEG files"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-q", argFlag, &quiet, 0, + "don't print any messages or errors"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, + {"-h", argFlag, &printHelp, 0, + "print usage information"}, + {"-help", argFlag, &printHelp, 0, + "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, + {NULL} +}; + +int main(int argc, char *argv[]) { + PDFDoc *doc; + GooString *fileName; + char *imgRoot; + GooString *ownerPW, *userPW; + ImageOutputDev *imgOut; + GBool ok; + int exitCode; + + exitCode = 99; + + // parse args + ok = parseArgs(argDesc, &argc, argv); + if (!ok || argc != 3 || printVersion || printHelp) { + fprintf(stderr, "pdfimages version %s\n", xpdfVersion); + fprintf(stderr, "%s\n", xpdfCopyright); + if (!printVersion) { + printUsage("pdfimages", " ", argDesc); + } + goto err0; + } + fileName = new GooString(argv[1]); + imgRoot = argv[2]; + + // read config file + globalParams = new GlobalParams(cfgFileName); + if (quiet) { + globalParams->setErrQuiet(quiet); + } + + // open PDF file + if (ownerPassword[0] != '\001') { + ownerPW = new GooString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0] != '\001') { + userPW = new GooString(userPassword); + } else { + userPW = NULL; + } + doc = new PDFDoc(fileName, ownerPW, userPW); + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + exitCode = 1; + goto err1; + } + + // check for copy permission +#ifdef ENFORCE_PERMISSIONS + if (!doc->okToCopy()) { + error(-1, "Copying of images from this document is not allowed."); + exitCode = 3; + goto err1; + } +#endif + + // get page range + if (firstPage < 1) + firstPage = 1; + if (lastPage < 1 || lastPage > doc->getNumPages()) + lastPage = doc->getNumPages(); + + // write image files + imgOut = new ImageOutputDev(imgRoot, dumpJPEG); + if (imgOut->isOk()) { + doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0, + gTrue, gFalse, gFalse); + } + delete imgOut; + + exitCode = 0; + + // clean up + err1: + delete doc; + delete globalParams; + err0: + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + return exitCode; +} diff --git a/rosapps/smartpdf/poppler/utils/pdfinfo.1 b/rosapps/smartpdf/poppler/utils/pdfinfo.1 new file mode 100644 index 00000000000..334520c80f8 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdfinfo.1 @@ -0,0 +1,157 @@ +.\" Copyright 1999-2004 Glyph & Cog, LLC +.TH pdfinfo 1 "22 January 2004" +.SH NAME +pdfinfo \- Portable Document Format (PDF) document information +extractor (version 3.00) +.SH SYNOPSIS +.B pdfinfo +[options] +.RI [ PDF-file ] +.SH DESCRIPTION +.B Pdfinfo +prints the contents of the \'Info' dictionary (plus some other useful +information) from a Portable Document Format (PDF) file. +.PP +The \'Info' dictionary contains the following values: +.PP +.RS +title +.RE +.RS +subject +.RE +.RS +keywords +.RE +.RS +author +.RE +.RS +creator +.RE +.RS +producer +.RE +.RS +creation date +.RE +.RS +modification date +.RE +.PP +In addition, the following information is printed: +.PP +.RS +tagged (yes/no) +.RE +.RS +page count +.RE +.RS +encrypted flag (yes/no) +.RE +.RS +print and copy permissions (if encrypted) +.RE +.RS +page size +.RE +.RS +file size +.RE +.RS +linearized (yes/no) +.RE +.RS +PDF version +.RE +.RS +metadata (only if requested) +.RE +.SH CONFIGURATION FILE +Pdfinfo reads a configuration file at startup. It first tries to find +the user's private config file, ~/.xpdfrc. If that doesn't exist, it +looks for a system-wide config file, /etc/xpdf/xpdfrc. See the +.BR xpdfrc (5) +man page for details. +.SH OPTIONS +Many of the following options can be set with configuration file +commands. These are listed in square brackets with the description of +the corresponding command line option. +.TP +.BI \-f " number" +Specifies the first page to examine. If multiple pages are requested +using the "-f" and "-l" options, the size of each requested page (and, +optionally, the bounding boxes for each requested page) are printed. +Otherwise, only page one is examined. +.TP +.BI \-l " number" +Specifies the last page to examine. +.TP +.B \-box +Prints the page box bounding boxes: MediaBox, CropBox, BleedBox, +TrimBox, and ArtBox. +.TP +.B \-meta +Prints document-level metadata. (This is the "Metadata" stream from +the PDF file's Catalog object.) +.TP +.BI \-enc " encoding-name" +Sets the encoding to use for text output. The +.I encoding\-name +must be defined with the unicodeMap command (see +.BR xpdfrc (5)). +This defaults to "Latin1" (which is a built-in encoding). +.RB "[config file: " textEncoding ] +.TP +.BI \-opw " password" +Specify the owner password for the PDF file. Providing this will +bypass all security restrictions. +.TP +.BI \-upw " password" +Specify the user password for the PDF file. +.TP +.BI \-cfg " config-file" +Read +.I config-file +in place of ~/.xpdfrc or the system-wide config file. +.TP +.B \-v +Print copyright and version information. +.TP +.B \-h +Print usage information. +.RB ( \-help +and +.B \-\-help +are equivalent.) +.SH EXIT CODES +The Xpdf tools use the following exit codes: +.TP +0 +No error. +.TP +1 +Error opening a PDF file. +.TP +2 +Error opening an output file. +.TP +3 +Error related to PDF permissions. +.TP +99 +Other error. +.SH AUTHOR +The pdfinfo software and documentation are copyright 1996-2004 Glyph & +Cog, LLC. +.SH "SEE ALSO" +.BR xpdf (1), +.BR pdftops (1), +.BR pdftotext (1), +.BR pdffonts (1), +.BR pdftoppm (1), +.BR pdfimages (1), +.BR xpdfrc (5) +.br +.B http://www.foolabs.com/xpdf/ diff --git a/rosapps/smartpdf/poppler/utils/pdfinfo.cc b/rosapps/smartpdf/poppler/utils/pdfinfo.cc new file mode 100644 index 00000000000..07f08cee212 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdfinfo.cc @@ -0,0 +1,386 @@ +//======================================================================== +// +// pdfinfo.cc +// +// Copyright 1998-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include "parseargs.h" +#include "goo/GooString.h" +#include "goo/gmem.h" +#include "GlobalParams.h" +#include "Object.h" +#include "Stream.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "Catalog.h" +#include "Page.h" +#include "PDFDoc.h" +#include "CharTypes.h" +#include "UnicodeMap.h" +#include "Error.h" +#include "UGooString.h" + +static void printInfoString(Dict *infoDict, char *key, char *text, + UnicodeMap *uMap); +static void printInfoDate(Dict *infoDict, char *key, char *text); +static void printBox(char *text, PDFRectangle *box); + +static int firstPage = 1; +static int lastPage = 0; +static GBool printBoxes = gFalse; +static GBool printMetadata = gFalse; +static char textEncName[128] = ""; +static char ownerPassword[33] = "\001"; +static char userPassword[33] = "\001"; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; + +static ArgDesc argDesc[] = { + {"-f", argInt, &firstPage, 0, + "first page to convert"}, + {"-l", argInt, &lastPage, 0, + "last page to convert"}, + {"-box", argFlag, &printBoxes, 0, + "print the page bounding boxes"}, + {"-meta", argFlag, &printMetadata, 0, + "print the document metadata (XML)"}, + {"-enc", argString, textEncName, sizeof(textEncName), + "output text encoding name"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, + {"-h", argFlag, &printHelp, 0, + "print usage information"}, + {"-help", argFlag, &printHelp, 0, + "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, + {NULL} +}; + +int main(int argc, char *argv[]) { + PDFDoc *doc; + GooString *fileName; + GooString *ownerPW, *userPW; + UnicodeMap *uMap; + Page *page; + Object info; + char buf[256]; + double w, h, wISO, hISO; + FILE *f; + GooString *metadata; + GBool ok; + int exitCode; + int pg, i; + GBool multiPage; + + exitCode = 99; + + // parse args + ok = parseArgs(argDesc, &argc, argv); + if (!ok || argc != 2 || printVersion || printHelp) { + fprintf(stderr, "pdfinfo version %s\n", xpdfVersion); + fprintf(stderr, "%s\n", xpdfCopyright); + if (!printVersion) { + printUsage("pdfinfo", "", argDesc); + } + goto err0; + } + fileName = new GooString(argv[1]); + + // read config file + globalParams = new GlobalParams(cfgFileName); + if (textEncName[0]) { + globalParams->setTextEncoding(textEncName); + } + + // get mapping to output encoding + if (!(uMap = globalParams->getTextEncoding())) { + error(-1, "Couldn't get text encoding"); + delete fileName; + goto err1; + } + + // open PDF file + if (ownerPassword[0] != '\001') { + ownerPW = new GooString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0] != '\001') { + userPW = new GooString(userPassword); + } else { + userPW = NULL; + } + + if(fileName->cmp("-") != 0) { + doc = new PDFDoc(fileName, ownerPW, userPW); + } else { + Object obj; + + obj.initNull(); + doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + } + + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + exitCode = 1; + goto err2; + } + + // get page range + if (firstPage < 1) { + firstPage = 1; + } + if (lastPage == 0) { + multiPage = gFalse; + lastPage = 1; + } else { + multiPage = gTrue; + } + if (lastPage < 1 || lastPage > doc->getNumPages()) { + lastPage = doc->getNumPages(); + } + + // print doc info + doc->getDocInfo(&info); + if (info.isDict()) { + printInfoString(info.getDict(), "Title", "Title: ", uMap); + printInfoString(info.getDict(), "Subject", "Subject: ", uMap); + printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap); + printInfoString(info.getDict(), "Author", "Author: ", uMap); + printInfoString(info.getDict(), "Creator", "Creator: ", uMap); + printInfoString(info.getDict(), "Producer", "Producer: ", uMap); + printInfoDate(info.getDict(), "CreationDate", "CreationDate: "); + printInfoDate(info.getDict(), "ModDate", "ModDate: "); + } + info.free(); + + // print tagging info + printf("Tagged: %s\n", + doc->getStructTreeRoot()->isDict() ? "yes" : "no"); + + // print page count + printf("Pages: %d\n", doc->getNumPages()); + + // print encryption info + printf("Encrypted: "); + if (doc->isEncrypted()) { + printf("yes (print:%s copy:%s change:%s addNotes:%s)\n", + doc->okToPrint(gTrue) ? "yes" : "no", + doc->okToCopy(gTrue) ? "yes" : "no", + doc->okToChange(gTrue) ? "yes" : "no", + doc->okToAddNotes(gTrue) ? "yes" : "no"); + } else { + printf("no\n"); + } + + // print page size + for (pg = firstPage; pg <= lastPage; ++pg) { + w = doc->getPageMediaWidth(pg); + h = doc->getPageMediaHeight(pg); + if (multiPage) { + printf("Page %4d size: %g x %g pts", pg, w, h); + } else { + printf("Page size: %g x %g pts", w, h); + } + if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) || + (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) { + printf(" (letter)"); + } else { + hISO = sqrt(sqrt(2.0)) * 7200 / 2.54; + wISO = hISO / sqrt(2.0); + for (i = 0; i <= 6; ++i) { + if ((fabs(w - wISO) < 1 && fabs(h - hISO) < 1) || + (fabs(w - hISO) < 1 && fabs(h - wISO) < 1)) { + printf(" (A%d)", i); + break; + } + hISO = wISO; + wISO /= sqrt(2.0); + } + } + printf("\n"); + } + + // print the boxes + if (printBoxes) { + if (multiPage) { + for (pg = firstPage; pg <= lastPage; ++pg) { + page = doc->getCatalog()->getPage(pg); + sprintf(buf, "Page %4d MediaBox: ", pg); + printBox(buf, page->getMediaBox()); + sprintf(buf, "Page %4d CropBox: ", pg); + printBox(buf, page->getCropBox()); + sprintf(buf, "Page %4d BleedBox: ", pg); + printBox(buf, page->getBleedBox()); + sprintf(buf, "Page %4d TrimBox: ", pg); + printBox(buf, page->getTrimBox()); + sprintf(buf, "Page %4d ArtBox: ", pg); + printBox(buf, page->getArtBox()); + } + } else { + page = doc->getCatalog()->getPage(firstPage); + printBox("MediaBox: ", page->getMediaBox()); + printBox("CropBox: ", page->getCropBox()); + printBox("BleedBox: ", page->getBleedBox()); + printBox("TrimBox: ", page->getTrimBox()); + printBox("ArtBox: ", page->getArtBox()); + } + } + + // print file size +#ifdef VMS + f = fopen(fileName->getCString(), "rb", "ctx=stm"); +#else + f = fopen(fileName->getCString(), "rb"); +#endif + if (f) { +#if HAVE_FSEEKO + fseeko(f, 0, SEEK_END); + printf("File size: %u bytes\n", (Guint)ftello(f)); +#elif HAVE_FSEEK64 + fseek64(f, 0, SEEK_END); + printf("File size: %u bytes\n", (Guint)ftell64(f)); +#else + fseek(f, 0, SEEK_END); + printf("File size: %d bytes\n", (int)ftell(f)); +#endif + fclose(f); + } + + // print linearization info + printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no"); + + // print PDF version + printf("PDF version: %.1f\n", doc->getPDFVersion()); + + // print the metadata + if (printMetadata && (metadata = doc->readMetadata())) { + fputs("Metadata:\n", stdout); + fputs(metadata->getCString(), stdout); + fputc('\n', stdout); + delete metadata; + } + + exitCode = 0; + + // clean up + err2: + uMap->decRefCnt(); + delete doc; + err1: + delete globalParams; + err0: + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + return exitCode; +} + +static void printInfoString(Dict *infoDict, char *key, char *text, + UnicodeMap *uMap) { + Object obj; + GooString *s1; + GBool isUnicode; + Unicode u; + char buf[8]; + int i, n; + + if (infoDict->lookup(key, &obj)->isString()) { + fputs(text, stdout); + s1 = obj.getString(); + if ((s1->getChar(0) & 0xff) == 0xfe && + (s1->getChar(1) & 0xff) == 0xff) { + isUnicode = gTrue; + i = 2; + } else { + isUnicode = gFalse; + i = 0; + } + while (i < obj.getString()->getLength()) { + if (isUnicode) { + u = ((s1->getChar(i) & 0xff) << 8) | + (s1->getChar(i+1) & 0xff); + i += 2; + } else { + u = s1->getChar(i) & 0xff; + ++i; + } + n = uMap->mapUnicode(u, buf, sizeof(buf)); + fwrite(buf, 1, n, stdout); + } + fputc('\n', stdout); + } + obj.free(); +} + +static void printInfoDate(Dict *infoDict, char *key, char *text) { + Object obj; + char *s; + int year, mon, day, hour, min, sec; + struct tm tmStruct; + char buf[256]; + + if (infoDict->lookup(key, &obj)->isString()) { + fputs(text, stdout); + s = obj.getString()->getCString(); + if (s[0] == 'D' && s[1] == ':') { + s += 2; + } + if (sscanf(s, "%4d%2d%2d%2d%2d%2d", + &year, &mon, &day, &hour, &min, &sec) == 6) { + tmStruct.tm_year = year - 1900; + tmStruct.tm_mon = mon - 1; + tmStruct.tm_mday = day; + tmStruct.tm_hour = hour; + tmStruct.tm_min = min; + tmStruct.tm_sec = sec; + tmStruct.tm_wday = -1; + tmStruct.tm_yday = -1; + tmStruct.tm_isdst = -1; + // compute the tm_wday and tm_yday fields + if (mktime(&tmStruct) != (time_t)-1 && + strftime(buf, sizeof(buf), "%c", &tmStruct)) { + fputs(buf, stdout); + } else { + fputs(s, stdout); + } + } else { + fputs(s, stdout); + } + fputc('\n', stdout); + } + obj.free(); +} + +static void printBox(char *text, PDFRectangle *box) { + printf("%s%8.2f %8.2f %8.2f %8.2f\n", + text, box->x1, box->y1, box->x2, box->y2); +} diff --git a/rosapps/smartpdf/poppler/utils/pdftohtml.1 b/rosapps/smartpdf/poppler/utils/pdftohtml.1 new file mode 100644 index 00000000000..850aa840cae --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftohtml.1 @@ -0,0 +1,85 @@ +.TH PDFTOHTML 1 +.\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection +.\" other parms are allowed: see man(7), man(1) +.SH NAME +pdftohtml \- program to convert pdf files into html, xml and png images +.SH SYNOPSIS +.B pdftohtml +.I "[options] [ ]" +.SH "DESCRIPTION" +This manual page documents briefly the +.BR pdftohtml +command. +This manual page was written for the Debian GNU/Linux distribution +because the original program does not have a manual page. +.PP +.B pdftohtml +is a program that converts pdf documents into html. It generates its output in +the current working directory. +.SH OPTIONS +A summary of options are included below. +.TP +.B \-h, \-help +Show summary of options. +.TP +.B \-f +first page to print +.TP +.B \-l +last page to print +.TP +.B \-q +dont print any messages or errors +.TP +.B \-v +print copyright and version info +.TP +.B \-p +exchange .pdf links with .html +.TP +.B \-c +generate complex output +.TP +.B \-i +ignore images +.TP +.B \-noframes +generate no frames. Not supported in complex output mode. +.TP +.B \-stdout +use standard output +.TP +.B \-zoom +zoom the pdf document (default 1.5) +.TP +.B \-xml +output for XML post-processing +.TP +.B \-enc +output text encoding name +.TP +.B \-opw +owner password (for encrypted files) +.TP +.B \-upw +user password (for encrypted files) +.TP +.B \-hidden +force hidden text extraction +.TP +.B \-dev +output device name for Ghostscript (png16m, jpeg etc) +.TP +.B \-nomerge +do not merge paragraphs +.TP +.B \-nodrm +override document DRM settings + +.SH AUTHOR + +Pdftohtml was developed by Gueorgui Ovtcharov and Rainer Dorsch. It is +based and benefits a lot from Derek Noonburg's xpdf package. + +This manual page was written by Søren Boll Overgaard , +for the Debian GNU/Linux system (but may be used by others). diff --git a/rosapps/smartpdf/poppler/utils/pdftohtml.cc b/rosapps/smartpdf/poppler/utils/pdftohtml.cc new file mode 100644 index 00000000000..42040fde4b9 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftohtml.cc @@ -0,0 +1,428 @@ +//======================================================================== +// +// pdftohtml.cc +// +// +// Copyright 1999-2000 G. Ovtcharov +//======================================================================== + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include "parseargs.h" +#include "goo/GooString.h" +#include "goo/gmem.h" +#include "Object.h" +#include "Stream.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "Catalog.h" +#include "Page.h" +#include "PDFDoc.h" +#include "HtmlOutputDev.h" +#include "PSOutputDev.h" +#include "GlobalParams.h" +#include "Error.h" +#include "UGooString.h" +#include "goo/gfile.h" + +#ifndef GHOSTSCRIPT +# define GHOSTSCRIPT "gs" +#endif + +static int firstPage = 1; +static int lastPage = 0; +static GBool rawOrder = gTrue; +GBool printCommands = gTrue; +static GBool printHelp = gFalse; +GBool printHtml = gFalse; +GBool complexMode=gFalse; +GBool ignore=gFalse; +//char extension[5]=".png"; +double scale=1.5; +GBool noframes=gFalse; +GBool stout=gFalse; +GBool xml=gFalse; +GBool errQuiet=gFalse; +GBool noDrm=gFalse; + +GBool showHidden = gFalse; +GBool noMerge = gFalse; +static char ownerPassword[33] = ""; +static char userPassword[33] = ""; +static char gsDevice[33] = "png16m"; +static GBool printVersion = gFalse; + +static GooString* getInfoString(Dict *infoDict, char *key); +static GooString* getInfoDate(Dict *infoDict, char *key); + +static char textEncName[128] = ""; + +static ArgDesc argDesc[] = { + {"-f", argInt, &firstPage, 0, + "first page to convert"}, + {"-l", argInt, &lastPage, 0, + "last page to convert"}, + /*{"-raw", argFlag, &rawOrder, 0, + "keep strings in content stream order"},*/ + {"-q", argFlag, &errQuiet, 0, + "don't print any messages or errors"}, + {"-h", argFlag, &printHelp, 0, + "print usage information"}, + {"-help", argFlag, &printHelp, 0, + "print usage information"}, + {"-p", argFlag, &printHtml, 0, + "exchange .pdf links by .html"}, + {"-c", argFlag, &complexMode, 0, + "generate complex document"}, + {"-i", argFlag, &ignore, 0, + "ignore images"}, + {"-noframes", argFlag, &noframes, 0, + "generate no frames"}, + {"-stdout" ,argFlag, &stout, 0, + "use standard output"}, + {"-zoom", argFP, &scale, 0, + "zoom the pdf document (default 1.5)"}, + {"-xml", argFlag, &xml, 0, + "output for XML post-processing"}, + {"-hidden", argFlag, &showHidden, 0, + "output hidden text"}, + {"-nomerge", argFlag, &noMerge, 0, + "do not merge paragraphs"}, + {"-enc", argString, textEncName, sizeof(textEncName), + "output text encoding name"}, + {"-dev", argString, gsDevice, sizeof(gsDevice), + "output device name for Ghostscript (png16m, jpeg etc)"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-nodrm", argFlag, &noDrm, 0, + "override document DRM settings"}, + {NULL} +}; + +int main(int argc, char *argv[]) { + PDFDoc *doc = NULL; + GooString *fileName = NULL; + GooString *docTitle = NULL; + GooString *author = NULL, *keywords = NULL, *subject = NULL, *date = NULL; + GooString *htmlFileName = NULL; + GooString *psFileName = NULL; + HtmlOutputDev *htmlOut = NULL; + PSOutputDev *psOut = NULL; + GBool ok; + char *p; + char extension[16] = "png"; + GooString *ownerPW, *userPW; + Object info; + char * extsList[] = {"png", "jpeg", "bmp", "pcx", "tiff", "pbm", NULL}; + + // parse args + ok = parseArgs(argDesc, &argc, argv); + if (!ok || argc < 2 || argc > 3 || printHelp || printVersion) { + fprintf(stderr, "pdftohtml version %s http://pdftohtml.sourceforge.net/, based on Xpdf version %s\n", "0.36", xpdfVersion); + fprintf(stderr, "%s\n", "Copyright 1999-2003 Gueorgui Ovtcharov and Rainer Dorsch"); + fprintf(stderr, "%s\n\n", xpdfCopyright); + if (!printVersion) { + printUsage("pdftohtml", " [ ]", argDesc); + } + exit(1); + } + + // init error file + //errorInit(); + + // read config file + globalParams = new GlobalParams(""); + + if (errQuiet) { + globalParams->setErrQuiet(errQuiet); + printCommands = gFalse; // I'm not 100% what is the differecne between them + } + + if (textEncName[0]) { + globalParams->setTextEncoding(textEncName); + if( !globalParams->getTextEncoding() ) { + goto error; + } + } + + // open PDF file + if (ownerPassword[0]) { + ownerPW = new GooString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0]) { + userPW = new GooString(userPassword); + } else { + userPW = NULL; + } + + fileName = new GooString(argv[1]); + + doc = new PDFDoc(fileName, ownerPW, userPW); + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + goto error; + } + + // check for copy permission + if (!doc->okToCopy()) { + if (!noDrm) { + error(-1, "Copying of text from this document is not allowed."); + goto error; + } + fprintf(stderr, "Document has copy-protection bit set.\n"); + } + + // construct text file name + if (argc == 3) { + GooString* tmp = new GooString(argv[2]); + p=tmp->getCString()+tmp->getLength()-5; + if (!xml) + if (!strcmp(p, ".html") || !strcmp(p, ".HTML")) + htmlFileName = new GooString(tmp->getCString(), + tmp->getLength() - 5); + else htmlFileName =new GooString(tmp); + else + if (!strcmp(p, ".xml") || !strcmp(p, ".XML")) + htmlFileName = new GooString(tmp->getCString(), + tmp->getLength() - 5); + else htmlFileName =new GooString(tmp); + + delete tmp; + } else { + p = fileName->getCString() + fileName->getLength() - 4; + if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) + htmlFileName = new GooString(fileName->getCString(), + fileName->getLength() - 4); + else + htmlFileName = fileName->copy(); + // htmlFileName->append(".html"); + } + + if (scale>3.0) scale=3.0; + if (scale<0.5) scale=0.5; + + if (complexMode) { + //noframes=gFalse; + stout=gFalse; + } + + if (stout) { + noframes=gTrue; + complexMode=gFalse; + } + + if (xml) + { + complexMode = gTrue; + noframes = gTrue; + noMerge = gTrue; + } + + // get page range + if (firstPage < 1) + firstPage = 1; + if (lastPage < 1 || lastPage > doc->getNumPages()) + lastPage = doc->getNumPages(); + + doc->getDocInfo(&info); + if (info.isDict()) { + docTitle = getInfoString(info.getDict(), "Title"); + author = getInfoString(info.getDict(), "Author"); + keywords = getInfoString(info.getDict(), "Keywords"); + subject = getInfoString(info.getDict(), "Subject"); + date = getInfoDate(info.getDict(), "ModDate"); + if( !date ) + date = getInfoDate(info.getDict(), "CreationDate"); + } + info.free(); + if( !docTitle ) docTitle = new GooString(htmlFileName); + + /* determine extensions of output backgroun images */ + {int i; + for(i = 0; extsList[i]; i++) + { + if( strstr(gsDevice, extsList[i]) != (char *) NULL ) + { + strncpy(extension, extsList[i], sizeof(extension)); + break; + } + }} + + rawOrder = complexMode; // todo: figure out what exactly rawOrder do :) + + // write text file + htmlOut = new HtmlOutputDev(htmlFileName->getCString(), + docTitle->getCString(), + author ? author->getCString() : NULL, + keywords ? keywords->getCString() : NULL, + subject ? subject->getCString() : NULL, + date ? date->getCString() : NULL, + extension, + rawOrder, + firstPage, + doc->getCatalog()->getOutline()->isDict()); + delete docTitle; + if( author ) + { + delete author; + } + if( keywords ) + { + delete keywords; + } + if( subject ) + { + delete subject; + } + if( date ) + { + delete date; + } + + if (htmlOut->isOk()) + { + doc->displayPages(htmlOut, firstPage, lastPage, 72, 72, 0, + gTrue, gFalse, gFalse); + if (!xml) + { + htmlOut->dumpDocOutline(doc->getCatalog()); + } + } + + if( complexMode && !xml && !ignore ) { + int h=xoutRound(htmlOut->getPageHeight()/scale); + int w=xoutRound(htmlOut->getPageWidth()/scale); + //int h=xoutRound(doc->getPageHeight(1)/scale); + //int w=xoutRound(doc->getPageWidth(1)/scale); + + psFileName = new GooString(htmlFileName->getCString()); + psFileName->append(".ps"); + + // XXX + // globalParams->setPSNoText(gTrue); + psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(), + doc->getCatalog(), firstPage, lastPage, psModePS, w, h); + doc->displayPages(psOut, firstPage, lastPage, 72, 72, 0, + gTrue, gFalse, gFalse); + delete psOut; + + /*sprintf(buf, "%s -sDEVICE=png16m -dBATCH -dNOPROMPT -dNOPAUSE -r72 -sOutputFile=%s%%03d.png -g%dx%d -q %s", GHOSTSCRIPT, htmlFileName->getCString(), w, h, + psFileName->getCString());*/ + + GooString *gsCmd = new GooString(GHOSTSCRIPT); + GooString *tw, *th, *sc; + gsCmd->append(" -sDEVICE="); + gsCmd->append(gsDevice); + gsCmd->append(" -dBATCH -dNOPROMPT -dNOPAUSE -r"); + sc = GooString::fromInt(static_cast(72*scale)); + gsCmd->append(sc); + gsCmd->append(" -sOutputFile="); + gsCmd->append("\""); + gsCmd->append(htmlFileName); + gsCmd->append("%03d."); + gsCmd->append(extension); + gsCmd->append("\" -g"); + tw = GooString::fromInt(static_cast(scale*w)); + gsCmd->append(tw); + gsCmd->append("x"); + th = GooString::fromInt(static_cast(scale*h)); + gsCmd->append(th); + gsCmd->append(" -q \""); + gsCmd->append(psFileName); + gsCmd->append("\""); +// printf("running: %s\n", gsCmd->getCString()); + if( !executeCommand(gsCmd->getCString()) && !errQuiet) { + error(-1, "Failed to launch Ghostscript!\n"); + } + unlink(psFileName->getCString()); + delete tw; + delete th; + delete sc; + delete gsCmd; + delete psFileName; + } + + delete htmlOut; + + // clean up + error: + if(doc) delete doc; + if(globalParams) delete globalParams; + + if(htmlFileName) delete htmlFileName; + HtmlFont::clear(); + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + return 0; +} + +static GooString* getInfoString(Dict *infoDict, char *key) { + Object obj; + GooString *s1 = NULL; + + if (infoDict->lookup(key, &obj)->isString()) { + s1 = new GooString(obj.getString()); + } + obj.free(); + return s1; +} + +static GooString* getInfoDate(Dict *infoDict, char *key) { + Object obj; + char *s; + int year, mon, day, hour, min, sec; + struct tm tmStruct; + GooString *result = NULL; + char buf[256]; + + if (infoDict->lookup(key, &obj)->isString()) { + s = obj.getString()->getCString(); + if (s[0] == 'D' && s[1] == ':') { + s += 2; + } + if (sscanf(s, "%4d%2d%2d%2d%2d%2d", + &year, &mon, &day, &hour, &min, &sec) == 6) { + tmStruct.tm_year = year - 1900; + tmStruct.tm_mon = mon - 1; + tmStruct.tm_mday = day; + tmStruct.tm_hour = hour; + tmStruct.tm_min = min; + tmStruct.tm_sec = sec; + tmStruct.tm_wday = -1; + tmStruct.tm_yday = -1; + tmStruct.tm_isdst = -1; + mktime(&tmStruct); // compute the tm_wday and tm_yday fields + if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S+00:00", &tmStruct)) { + result = new GooString(buf); + } else { + result = new GooString(s); + } + } else { + result = new GooString(s); + } + } + obj.free(); + return result; +} + diff --git a/rosapps/smartpdf/poppler/utils/pdftoppm.1 b/rosapps/smartpdf/poppler/utils/pdftoppm.1 new file mode 100644 index 00000000000..f4d93e3a9f2 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftoppm.1 @@ -0,0 +1,113 @@ +.\" Copyright 2004 Glyph & Cog, LLC +.TH pdftoppm 1 "22 January 2004" +.SH NAME +pdftoppm \- Portable Document Format (PDF) to Portable Pixmap (PPM) +converter (version 3.00) +.SH SYNOPSIS +.B pdftoppm +[options] +.I PDF-file PPM-root +.SH DESCRIPTION +.B Pdftoppm +converts Portable Document Format (PDF) files to color image files in +Portable Pixmap (PPM) format, grayscale image files in Portable +Graymap (PGM) format, or monochrome image files in Portable Bitmap +(PBM) format. +.PP +Pdftoppm reads the PDF file, +.IR PDF-file , +and writes one PPM file for each page, +.IR PPM-root - nnnnnn .ppm, +where +.I nnnnnn +is the page number. +.SH CONFIGURATION FILE +Pdftoppm reads a configuration file at startup. It first tries to +find the user's private config file, ~/.xpdfrc. If that doesn't +exist, it looks for a system-wide config file, /etc/xpdf/xpdfrc. See the +.BR xpdfrc (5) +man page for details. +.SH OPTIONS +Many of the following options can be set with configuration file +commands. These are listed in square brackets with the description of +the corresponding command line option. +.TP +.BI \-f " number" +Specifies the first page to convert. +.TP +.BI \-l " number" +Specifies the last page to convert. +.TP +.BI \-r " number" +Specifies the resolution, in DPI. The default is 150 DPI. +.TP +.B \-mono +Generate a monochrome PBM file (instead of a color PPM file). +.TP +.B \-gray +Generate a grayscale PGM file (instead of a color PPM file). +.TP +.BI \-t1lib " yes | no" +Enable or disable t1lib (a Type 1 font rasterizer). This defaults to +"yes". +.RB "[config file: " enableT1lib ] +.TP +.BI \-freetype " yes | no" +Enable or disable FreeType (a TrueType / Type 1 font rasterizer). +This defaults to "yes". +.RB "[config file: " enableFreeType ] +.TP +.BI \-aa " yes | no" +Enable or disable font anti-aliasing. This defaults to "yes". +.RB "[config file: " antialias ] +.TP +.BI \-opw " password" +Specify the owner password for the PDF file. Providing this will +bypass all security restrictions. +.TP +.BI \-upw " password" +Specify the user password for the PDF file. +.TP +.B \-q +Don't print any messages or errors. +.RB "[config file: " errQuiet ] +.TP +.B \-v +Print copyright and version information. +.TP +.B \-h +Print usage information. +.RB ( \-help +and +.B \-\-help +are equivalent.) +.SH EXIT CODES +The Xpdf tools use the following exit codes: +.TP +0 +No error. +.TP +1 +Error opening a PDF file. +.TP +2 +Error opening an output file. +.TP +3 +Error related to PDF permissions. +.TP +99 +Other error. +.SH AUTHOR +The pdftoppm software and documentation are copyright 1996-2004 Glyph +& Cog, LLC. +.SH "SEE ALSO" +.BR xpdf (1), +.BR pdftops (1), +.BR pdftotext (1), +.BR pdfinfo (1), +.BR pdffonts (1), +.BR pdfimages (1), +.BR xpdfrc (5) +.br +.B http://www.foolabs.com/xpdf/ diff --git a/rosapps/smartpdf/poppler/utils/pdftoppm.cc b/rosapps/smartpdf/poppler/utils/pdftoppm.cc new file mode 100644 index 00000000000..df94cecd821 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftoppm.cc @@ -0,0 +1,190 @@ +//======================================================================== +// +// pdftoppm.cc +// +// Copyright 2003 Glyph & Cog, LLC +// +//======================================================================== + +#include "config.h" +#include +#include +#include "parseargs.h" +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "GlobalParams.h" +#include "Object.h" +#include "PDFDoc.h" +#include "splash/SplashBitmap.h" +#include "splash/Splash.h" +#include "SplashOutputDev.h" + +static int firstPage = 1; +static int lastPage = 0; +static int resolution = 150; +static GBool mono = gFalse; +static GBool gray = gFalse; +static char enableT1libStr[16] = ""; +static char enableFreeTypeStr[16] = ""; +static char antialiasStr[16] = ""; +static char ownerPassword[33] = ""; +static char userPassword[33] = ""; +static GBool quiet = gFalse; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; + +static ArgDesc argDesc[] = { + {"-f", argInt, &firstPage, 0, + "first page to print"}, + {"-l", argInt, &lastPage, 0, + "last page to print"}, + {"-r", argInt, &resolution, 0, + "resolution, in DPI (default is 150)"}, + {"-mono", argFlag, &mono, 0, + "generate a monochrome PBM file"}, + {"-gray", argFlag, &gray, 0, + "generate a grayscale PGM file"}, +#if HAVE_T1LIB_H + {"-t1lib", argString, enableT1libStr, sizeof(enableT1libStr), + "enable t1lib font rasterizer: yes, no"}, +#endif +#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H + {"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr), + "enable FreeType font rasterizer: yes, no"}, +#endif + {"-aa", argString, antialiasStr, sizeof(antialiasStr), + "enable font anti-aliasing: yes, no"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-q", argFlag, &quiet, 0, + "don't print any messages or errors"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, + {"-h", argFlag, &printHelp, 0, + "print usage information"}, + {"-help", argFlag, &printHelp, 0, + "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, + {NULL} +}; + +int main(int argc, char *argv[]) { + PDFDoc *doc; + GooString *fileName; + char *ppmRoot; + char ppmFile[512]; + GooString *ownerPW, *userPW; + SplashColor paperColor; + SplashOutputDev *splashOut; + GBool ok; + int exitCode; + int pg; + + exitCode = 99; + + // parse args + ok = parseArgs(argDesc, &argc, argv); + if (mono && gray) { + ok = gFalse; + } + if (!ok || argc != 3 || printVersion || printHelp) { + fprintf(stderr, "pdftoppm version %s\n", xpdfVersion); + fprintf(stderr, "%s\n", xpdfCopyright); + if (!printVersion) { + printUsage("pdftoppm", " ", argDesc); + } + goto err0; + } + fileName = new GooString(argv[1]); + ppmRoot = argv[2]; + + // read config file + globalParams = new GlobalParams(cfgFileName); + if (enableT1libStr[0]) { + if (!globalParams->setEnableT1lib(enableT1libStr)) { + fprintf(stderr, "Bad '-t1lib' value on command line\n"); + } + } + if (enableFreeTypeStr[0]) { + if (!globalParams->setEnableFreeType(enableFreeTypeStr)) { + fprintf(stderr, "Bad '-freetype' value on command line\n"); + } + } + if (antialiasStr[0]) { + if (!globalParams->setAntialias(antialiasStr)) { + fprintf(stderr, "Bad '-aa' value on command line\n"); + } + } + if (quiet) { + globalParams->setErrQuiet(quiet); + } + + // open PDF file + if (ownerPassword[0]) { + ownerPW = new GooString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0]) { + userPW = new GooString(userPassword); + } else { + userPW = NULL; + } + doc = new PDFDoc(fileName, ownerPW, userPW); + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + exitCode = 1; + goto err1; + } + + // get page range + if (firstPage < 1) + firstPage = 1; + if (lastPage < 1 || lastPage > doc->getNumPages()) + lastPage = doc->getNumPages(); + + // write PPM files + paperColor[0] = 255; + paperColor[1] = 255; + paperColor[2] = 255; + splashOut = new SplashOutputDev(mono ? splashModeMono1 : + gray ? splashModeMono8 : + splashModeRGB8, 4, + gFalse, paperColor); + splashOut->startDoc(doc->getXRef()); + for (pg = firstPage; pg <= lastPage; ++pg) { + doc->displayPage(splashOut, pg, resolution, resolution, 0, gTrue, gFalse, gFalse); + sprintf(ppmFile, "%.*s-%06d.%s", + (int)sizeof(ppmFile) - 32, ppmRoot, pg, + mono ? "pbm" : gray ? "pgm" : "ppm"); + splashOut->getBitmap()->writePNMFile(ppmFile); + } + delete splashOut; + + exitCode = 0; + + // clean up + err1: + delete doc; + delete globalParams; + err0: + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + return exitCode; +} diff --git a/rosapps/smartpdf/poppler/utils/pdftops.1 b/rosapps/smartpdf/poppler/utils/pdftops.1 new file mode 100644 index 00000000000..04c5c7e1653 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftops.1 @@ -0,0 +1,224 @@ +.\" Copyright 1996-2004 Glyph & Cog, LLC +.TH pdftops 1 "22 January 2004" +.SH NAME +pdftops \- Portable Document Format (PDF) to PostScript converter +(version 3.00) +.SH SYNOPSIS +.B pdftops +[options] +.RI [ PDF-file +.RI [ PS-file ]] +.SH DESCRIPTION +.B Pdftops +converts Portable Document Format (PDF) files to PostScript so they +can be printed. +.PP +Pdftops reads the PDF file, +.IR PDF-file , +and writes a PostScript file, +.IR PS-file . +If +.I PS-file +is not specified, pdftops converts +.I file.pdf +to +.I file.ps +(or +.I file.eps +with the -eps option). If +.I PS-file +is \'-', the PostScript is sent to stdout. +.SH CONFIGURATION FILE +Pdftops reads a configuration file at startup. It first tries to find +the user's private config file, ~/.xpdfrc. If that doesn't exist, it +looks for a system-wide config file, /etc/xpdf/xpdfrc. See the +.BR xpdfrc (5) +man page for details. +.SH OPTIONS +Many of the following options can be set with configuration file +commands. These are listed in square brackets with the description of +the corresponding command line option. +.TP +.BI \-f " number" +Specifies the first page to print. +.TP +.BI \-l " number" +Specifies the last page to print. +.TP +.B \-level1 +Generate Level 1 PostScript. The resulting PostScript files will be +significantly larger (if they contain images), but will print on Level +1 printers. This also converts all images to black and white. No +more than one of the PostScript level options (-level1, -level1sep, +-level2, -level2sep, -level3, -level3Sep) may be given. +.RB "[config file: " psLevel ] +.TP +.B \-level1sep +Generate Level 1 separable PostScript. All colors are converted to +CMYK. Images are written with separate stream data for the four +components. +.RB "[config file: " psLevel ] +.TP +.B \-level2 +Generate Level 2 PostScript. Level 2 supports color images and image +compression. This is the default setting. +.RB "[config file: " psLevel ] +.TP +.B \-level2sep +Generate Level 2 separable PostScript. All colors are converted to +CMYK. The PostScript separation convention operators are used to +handle custom (spot) colors. +.RB "[config file: " psLevel ] +.TP +.B \-level3 +Generate Level 3 PostScript. This enables all Level 2 features plus +CID font embedding. +.RB "[config file: " psLevel ] +.TP +.B \-level3Sep +Generate Level 3 separable PostScript. The separation handling is the +same as for -level2Sep. +.RB "[config file: " psLevel ] +.TP +.B \-eps +Generate an Encapsulated PostScript (EPS) file. An EPS file contains +a single image, so if you use this option with a multi-page PDF file, +you must use -f and -l to specify a single page. No more than one of +the mode options (-eps, -form) may be given. +.TP +.B \-form +Generate a PostScript form which can be imported by software that +understands forms. A form contains a single page, so if you use this +option with a multi-page PDF file, you must use -f and -l to specify a +single page. The -level1 option cannot be used with -form. +.TP +.B \-opi +Generate OPI comments for all images and forms which have OPI +information. (This option is only available if pdftops was compiled +with OPI support.) +.RB "[config file: " psOPI ] +.TP +.B \-noembt1 +By default, any Type 1 fonts which are embedded in the PDF file are +copied into the PostScript file. This option causes pdftops to +substitute base fonts instead. Embedded fonts make PostScript files +larger, but may be necessary for readable output. +.RB "[config file: " psEmbedType1Fonts ] +.TP +.B \-noembtt +By default, any TrueType fonts which are embedded in the PDF file are +copied into the PostScript file. This option causes pdftops to +substitute base fonts instead. Embedded fonts make PostScript files +larger, but may be necessary for readable output. Also, some +PostScript interpreters do not have TrueType rasterizers. +.RB "[config file: " psEmbedTrueTypeFonts ] +.TP +.B \-noembcidps +By default, any CID PostScript fonts which are embedded in the PDF +file are copied into the PostScript file. This option disables that +embedding. No attempt is made to substitute for non-embedded CID +PostScript fonts. +.RB "[config file: " psEmbedCIDPostScriptFonts ] +.TP +.B \-noembcidtt +By default, any CID TrueType fonts which are embedded in the PDF file +are copied into the PostScript file. This option disables that +embedding. No attempt is made to substitute for non-embedded CID +TrueType fonts. +.RB "[config file: " psEmbedCIDTrueTypeFonts ] +.TP +.BI \-paper " size" +Set the paper size to one of "letter", "legal", "A4", or "A3". This +can also be set to "match", which will set the paper size to match the +size specified in the PDF file. +.RB "[config file: " psPaperSize ] +.TP +.BI \-paperw " size" +Set the paper width, in points. +.RB "[config file: " psPaperSize ] +.TP +.BI \-paperh " size" +Set the paper height, in points. +.RB "[config file: " psPaperSize ] +.TP +.B \-nocrop +By default, output is cropped to the CropBox specified in the PDF +file. This option disables cropping. +.RB "[config file: " psCrop ] +.TP +.B \-expand +Expand PDF pages smaller than the paper to fill the paper. By +default, these pages are not scaled. +.RB "[config file: " psExpandSmaller ] +.TP +.B \-noshrink +Don't scale PDF pages which are larger than the paper. By default, +pages larger than the paper are shrunk to fit. +.RB "[config file: " psShrinkLarger ] +.TP +.B \-nocenter +By default, PDF pages smaller than the paper (after any scaling) are +centered on the paper. This option causes them to be aligned to the +lower-left corner of the paper instead. +.RB "[config file: " psCenter ] +.TP +.B \-duplex +Set the Duplex pagedevice entry in the PostScript file. This tells +duplex-capable printers to enable duplexing. +.RB "[config file: " psDuplex ] +.TP +.BI \-opw " password" +Specify the owner password for the PDF file. Providing this will +bypass all security restrictions. +.TP +.BI \-upw " password" +Specify the user password for the PDF file. +.TP +.B \-q +Don't print any messages or errors. +.RB "[config file: " errQuiet ] +.TP +.BI \-cfg " config-file" +Read +.I config-file +in place of ~/.xpdfrc or the system-wide config file. +.TP +.B \-v +Print copyright and version information. +.TP +.B \-h +Print usage information. +.RB ( \-help +and +.B \-\-help +are equivalent.) +.SH EXIT CODES +The Xpdf tools use the following exit codes: +.TP +0 +No error. +.TP +1 +Error opening a PDF file. +.TP +2 +Error opening an output file. +.TP +3 +Error related to PDF permissions. +.TP +99 +Other error. +.SH AUTHOR +The pdftops software and documentation are copyright 1996-2004 Glyph & +Cog, LLC. +.SH "SEE ALSO" +.BR xpdf (1), +.BR pdftotext (1), +.BR pdfinfo (1), +.BR pdffonts (1), +.BR pdftoppm (1), +.BR pdfimages (1), +.BR xpdfrc (5) +.br +.B http://www.foolabs.com/xpdf/ diff --git a/rosapps/smartpdf/poppler/utils/pdftops.cc b/rosapps/smartpdf/poppler/utils/pdftops.cc new file mode 100644 index 00000000000..3718cc3ef99 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftops.cc @@ -0,0 +1,339 @@ +//======================================================================== +// +// pdftops.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +// Modified for Debian by Hamish Moffatt, 22 May 2002. +// +//======================================================================== + +#include "config.h" +#include +#include +#include +#include +#include +#include "parseargs.h" +#include "goo/GooString.h" +#include "goo/gmem.h" +#include "GlobalParams.h" +#include "Object.h" +#include "Stream.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "Catalog.h" +#include "Page.h" +#include "PDFDoc.h" +#include "PSOutputDev.h" +#include "Error.h" + +static int firstPage = 1; +static int lastPage = 0; +static GBool level1 = gFalse; +static GBool level1Sep = gFalse; +static GBool level2 = gFalse; +static GBool level2Sep = gFalse; +static GBool level3 = gFalse; +static GBool level3Sep = gFalse; +static GBool doEPS = gFalse; +static GBool doForm = gFalse; +#if OPI_SUPPORT +static GBool doOPI = gFalse; +#endif +static GBool noEmbedT1Fonts = gFalse; +static GBool noEmbedTTFonts = gFalse; +static GBool noEmbedCIDPSFonts = gFalse; +static GBool noEmbedCIDTTFonts = gFalse; +static char paperSize[15] = ""; +static int paperWidth = 0; +static int paperHeight = 0; +static GBool noCrop = gFalse; +static GBool expand = gFalse; +static GBool noShrink = gFalse; +static GBool noCenter = gFalse; +static GBool duplex = gFalse; +static char ownerPassword[33] = "\001"; +static char userPassword[33] = "\001"; +static GBool quiet = gFalse; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; + +static ArgDesc argDesc[] = { + {"-f", argInt, &firstPage, 0, + "first page to print"}, + {"-l", argInt, &lastPage, 0, + "last page to print"}, + {"-level1", argFlag, &level1, 0, + "generate Level 1 PostScript"}, + {"-level1sep", argFlag, &level1Sep, 0, + "generate Level 1 separable PostScript"}, + {"-level2", argFlag, &level2, 0, + "generate Level 2 PostScript"}, + {"-level2sep", argFlag, &level2Sep, 0, + "generate Level 2 separable PostScript"}, + {"-level3", argFlag, &level3, 0, + "generate Level 3 PostScript"}, + {"-level3sep", argFlag, &level3Sep, 0, + "generate Level 3 separable PostScript"}, + {"-eps", argFlag, &doEPS, 0, + "generate Encapsulated PostScript (EPS)"}, + {"-form", argFlag, &doForm, 0, + "generate a PostScript form"}, +#if OPI_SUPPORT + {"-opi", argFlag, &doOPI, 0, + "generate OPI comments"}, +#endif + {"-noembt1", argFlag, &noEmbedT1Fonts, 0, + "don't embed Type 1 fonts"}, + {"-noembtt", argFlag, &noEmbedTTFonts, 0, + "don't embed TrueType fonts"}, + {"-noembcidps", argFlag, &noEmbedCIDPSFonts, 0, + "don't embed CID PostScript fonts"}, + {"-noembcidtt", argFlag, &noEmbedCIDTTFonts, 0, + "don't embed CID TrueType fonts"}, + {"-paper", argString, paperSize, sizeof(paperSize), + "paper size (letter, legal, A4, A3, match)"}, + {"-paperw", argInt, &paperWidth, 0, + "paper width, in points"}, + {"-paperh", argInt, &paperHeight, 0, + "paper height, in points"}, + {"-nocrop", argFlag, &noCrop, 0, + "don't crop pages to CropBox"}, + {"-expand", argFlag, &expand, 0, + "expand pages smaller than the paper size"}, + {"-noshrink", argFlag, &noShrink, 0, + "don't shrink pages larger than the paper size"}, + {"-nocenter", argFlag, &noCenter, 0, + "don't center pages smaller than the paper size"}, + {"-duplex", argFlag, &duplex, 0, + "enable duplex printing"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-q", argFlag, &quiet, 0, + "don't print any messages or errors"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, + {"-h", argFlag, &printHelp, 0, + "print usage information"}, + {"-help", argFlag, &printHelp, 0, + "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, + {NULL} +}; + +int main(int argc, char *argv[]) { + PDFDoc *doc; + GooString *fileName; + GooString *psFileName; + PSLevel level; + PSOutMode mode; + GooString *ownerPW, *userPW; + PSOutputDev *psOut; + GBool ok; + char *p; + int exitCode; + + exitCode = 99; + + // parse args + ok = parseArgs(argDesc, &argc, argv); + if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) { + fprintf(stderr, "pdftops version %s\n", xpdfVersion); + fprintf(stderr, "%s\n", xpdfCopyright); + if (!printVersion) { + printUsage("pdftops", " []", argDesc); + } + exit(1); + } + if ((level1 ? 1 : 0) + + (level1Sep ? 1 : 0) + + (level2 ? 1 : 0) + + (level2Sep ? 1 : 0) + + (level3 ? 1 : 0) + + (level3Sep ? 1 : 0) > 1) { + fprintf(stderr, "Error: use only one of the 'level' options.\n"); + exit(1); + } + if (doEPS && doForm) { + fprintf(stderr, "Error: use only one of -eps and -form\n"); + exit(1); + } + if (level1) { + level = psLevel1; + } else if (level1Sep) { + level = psLevel1Sep; + } else if (level2Sep) { + level = psLevel2Sep; + } else if (level3) { + level = psLevel3; + } else if (level3Sep) { + level = psLevel3Sep; + } else { + level = psLevel2; + } + if (doForm && level < psLevel2) { + fprintf(stderr, "Error: forms are only available with Level 2 output.\n"); + exit(1); + } + mode = doEPS ? psModeEPS + : doForm ? psModeForm + : psModePS; + fileName = new GooString(argv[1]); + + // read config file + globalParams = new GlobalParams(cfgFileName); + if (paperSize[0]) { + if (!globalParams->setPSPaperSize(paperSize)) { + fprintf(stderr, "Invalid paper size\n"); + delete fileName; + goto err0; + } + } else { + if (paperWidth) { + globalParams->setPSPaperWidth(paperWidth); + } + if (paperHeight) { + globalParams->setPSPaperHeight(paperHeight); + } + } + if (noCrop) { + globalParams->setPSCrop(gFalse); + } + if (expand) { + globalParams->setPSExpandSmaller(gTrue); + } + if (noShrink) { + globalParams->setPSShrinkLarger(gFalse); + } + if (noCenter) { + globalParams->setPSCenter(gFalse); + } + if (duplex) { + globalParams->setPSDuplex(duplex); + } + if (level1 || level1Sep || level2 || level2Sep || level3 || level3Sep) { + globalParams->setPSLevel(level); + } + if (noEmbedT1Fonts) { + globalParams->setPSEmbedType1(!noEmbedT1Fonts); + } + if (noEmbedTTFonts) { + globalParams->setPSEmbedTrueType(!noEmbedTTFonts); + } + if (noEmbedCIDPSFonts) { + globalParams->setPSEmbedCIDPostScript(!noEmbedCIDPSFonts); + } + if (noEmbedCIDTTFonts) { + globalParams->setPSEmbedCIDTrueType(!noEmbedCIDTTFonts); + } +#if OPI_SUPPORT + if (doOPI) { + globalParams->setPSOPI(doOPI); + } +#endif + if (quiet) { + globalParams->setErrQuiet(quiet); + } + + // open PDF file + if (ownerPassword[0] != '\001') { + ownerPW = new GooString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0] != '\001') { + userPW = new GooString(userPassword); + } else { + userPW = NULL; + } + doc = new PDFDoc(fileName, ownerPW, userPW); + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + exitCode = 1; + goto err1; + } + +#ifdef ENFORCE_PERMISSIONS + // check for print permission + if (!doc->okToPrint()) { + error(-1, "Printing this document is not allowed."); + exitCode = 3; + goto err1; + } +#endif + + // construct PostScript file name + if (argc == 3) { + psFileName = new GooString(argv[2]); + } else { + p = fileName->getCString() + fileName->getLength() - 4; + if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) { + psFileName = new GooString(fileName->getCString(), + fileName->getLength() - 4); + } else { + psFileName = fileName->copy(); + } + psFileName->append(doEPS ? ".eps" : ".ps"); + } + + // get page range + if (firstPage < 1) { + firstPage = 1; + } + if (lastPage < 1 || lastPage > doc->getNumPages()) { + lastPage = doc->getNumPages(); + } + + // check for multi-page EPS or form + if ((doEPS || doForm) && firstPage != lastPage) { + error(-1, "EPS and form files can only contain one page."); + goto err2; + } + + // write PostScript file + psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(), + doc->getCatalog(), firstPage, lastPage, mode, + globalParams->getPSPaperWidth(), + globalParams->getPSPaperHeight(), + globalParams->getPSDuplex()); + if (psOut->isOk()) { + doc->displayPages(psOut, firstPage, lastPage, 72, 72, + 0, globalParams->getPSCrop(), gFalse, gFalse); + } else { + delete psOut; + exitCode = 2; + goto err2; + } + delete psOut; + + exitCode = 0; + + // clean up + err2: + delete psFileName; + err1: + delete doc; + err0: + delete globalParams; + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + return exitCode; +} diff --git a/rosapps/smartpdf/poppler/utils/pdftotext.1 b/rosapps/smartpdf/poppler/utils/pdftotext.1 new file mode 100644 index 00000000000..11a67694a98 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftotext.1 @@ -0,0 +1,135 @@ +.\" Copyright 1997-2004 Glyph & Cog, LLC +.TH pdftotext 1 "22 January 2004" +.SH NAME +pdftotext \- Portable Document Format (PDF) to text converter +(version 3.00) +.SH SYNOPSIS +.B pdftotext +[options] +.RI [ PDF-file +.RI [ text-file ]] +.SH DESCRIPTION +.B Pdftotext +converts Portable Document Format (PDF) files to plain text. +.PP +Pdftotext reads the PDF file, +.IR PDF-file , +and writes a text file, +.IR text-file . +If +.I text-file +is not specified, pdftotext converts +.I file.pdf +to +.IR file.txt . +If +.I text-file +is \'-', the text is sent to stdout. +.SH CONFIGURATION FILE +Pdftotext reads a configuration file at startup. It first tries to +find the user's private config file, ~/.xpdfrc. If that doesn't +exist, it looks for a system-wide config file, /etc/xpdf/xpdfrc. See the +.BR xpdfrc (5) +man page for details. +.SH OPTIONS +Many of the following options can be set with configuration file +commands. These are listed in square brackets with the description of +the corresponding command line option. +.TP +.BI \-f " number" +Specifies the first page to convert. +.TP +.BI \-l " number" +Specifies the last page to convert. +.TP +.B \-layout +Maintain (as best as possible) the original physical layout of the +text. The default is to \'undo' physical layout (columns, +hyphenation, etc.) and output the text in reading order. +.TP +.B \-raw +Keep the text in content stream order. This is a hack which often +"undoes" column formatting, etc. Use of raw mode is no longer +recommended. +.TP +.B \-htmlmeta +Generate a simple HTML file, including the meta information. This +simply wraps the text in
 and 
and prepends the meta +headers. +.TP +.BI \-enc " encoding-name" +Sets the encoding to use for text output. The +.I encoding\-name +must be defined with the unicodeMap command (see +.BR xpdfrc (5)). +The encoding name is case-sensitive. This defaults to "Latin1" (which +is a built-in encoding). +.RB "[config file: " textEncoding ] +.TP +.BI \-eol " unix | dos | mac" +Sets the end-of-line convention to use for text output. +.RB "[config file: " textEOL ] +.TP +.B \-nopgbrk +Don't insert page breaks (form feed characters) between pages. +.RB "[config file: " textPageBreaks ] +.TP +.BI \-opw " password" +Specify the owner password for the PDF file. Providing this will +bypass all security restrictions. +.TP +.BI \-upw " password" +Specify the user password for the PDF file. +.TP +.B \-q +Don't print any messages or errors. +.RB "[config file: " errQuiet ] +.TP +.BI \-cfg " config-file" +Read +.I config-file +in place of ~/.xpdfrc or the system-wide config file. +.TP +.B \-v +Print copyright and version information. +.TP +.B \-h +Print usage information. +.RB ( \-help +and +.B \-\-help +are equivalent.) +.SH BUGS +Some PDF files contain fonts whose encodings have been mangled beyond +recognition. There is no way (short of OCR) to extract text from +these files. +.SH EXIT CODES +The Xpdf tools use the following exit codes: +.TP +0 +No error. +.TP +1 +Error opening a PDF file. +.TP +2 +Error opening an output file. +.TP +3 +Error related to PDF permissions. +.TP +99 +Other error. +.SH AUTHOR +The pdftotext software and documentation are copyright 1996-2004 Glyph +& Cog, LLC. +.SH "SEE ALSO" +.BR xpdf (1), +.BR pdftops (1), +.BR pdfinfo (1), +.BR pdffonts (1), +.BR pdftoppm (1), +.BR pdfimages (1), +.BR xpdfrc (5) +.br +.B http://www.foolabs.com/xpdf/ diff --git a/rosapps/smartpdf/poppler/utils/pdftotext.cc b/rosapps/smartpdf/poppler/utils/pdftotext.cc new file mode 100644 index 00000000000..dc1977db0f2 --- /dev/null +++ b/rosapps/smartpdf/poppler/utils/pdftotext.cc @@ -0,0 +1,347 @@ +//======================================================================== +// +// pdftotext.cc +// +// Copyright 1997-2003 Glyph & Cog, LLC +// +// Modified for Debian by Hamish Moffatt, 22 May 2002. +// +//======================================================================== + +#include "config.h" +#include +#include +#include +#include +#include +#include "parseargs.h" +#include "goo/GooString.h" +#include "goo/gmem.h" +#include "GlobalParams.h" +#include "Object.h" +#include "Stream.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "Catalog.h" +#include "Page.h" +#include "PDFDoc.h" +#include "TextOutputDev.h" +#include "CharTypes.h" +#include "UnicodeMap.h" +#include "Error.h" +#include "UGooString.h" + +static void printInfoString(FILE *f, Dict *infoDict, char *key, + char *text1, char *text2, UnicodeMap *uMap); +static void printInfoDate(FILE *f, Dict *infoDict, char *key, char *fmt); + +static int firstPage = 1; +static int lastPage = 0; +static GBool physLayout = gFalse; +static GBool rawOrder = gFalse; +static GBool htmlMeta = gFalse; +static char textEncName[128] = ""; +static char textEOL[16] = ""; +static GBool noPageBreaks = gFalse; +static char ownerPassword[33] = "\001"; +static char userPassword[33] = "\001"; +static GBool quiet = gFalse; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; + +static ArgDesc argDesc[] = { + {"-f", argInt, &firstPage, 0, + "first page to convert"}, + {"-l", argInt, &lastPage, 0, + "last page to convert"}, + {"-layout", argFlag, &physLayout, 0, + "maintain original physical layout"}, + {"-raw", argFlag, &rawOrder, 0, + "keep strings in content stream order"}, + {"-htmlmeta", argFlag, &htmlMeta, 0, + "generate a simple HTML file, including the meta information"}, + {"-enc", argString, textEncName, sizeof(textEncName), + "output text encoding name"}, + {"-eol", argString, textEOL, sizeof(textEOL), + "output end-of-line convention (unix, dos, or mac)"}, + {"-nopgbrk", argFlag, &noPageBreaks, 0, + "don't insert page breaks between pages"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-q", argFlag, &quiet, 0, + "don't print any messages or errors"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, + {"-h", argFlag, &printHelp, 0, + "print usage information"}, + {"-help", argFlag, &printHelp, 0, + "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, + {NULL} +}; + +int main(int argc, char *argv[]) { + PDFDoc *doc; + GooString *fileName; + GooString *textFileName; + GooString *ownerPW, *userPW; + TextOutputDev *textOut; + FILE *f; + UnicodeMap *uMap; + Object info; + GBool ok; + char *p; + int exitCode; + + exitCode = 99; + + // parse args + ok = parseArgs(argDesc, &argc, argv); + if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) { + fprintf(stderr, "pdftotext version %s\n", xpdfVersion); + fprintf(stderr, "%s\n", xpdfCopyright); + if (!printVersion) { + printUsage("pdftotext", " []", argDesc); + } + goto err0; + } + fileName = new GooString(argv[1]); + + // read config file + globalParams = new GlobalParams(cfgFileName); + if (textEncName[0]) { + globalParams->setTextEncoding(textEncName); + } + if (textEOL[0]) { + if (!globalParams->setTextEOL(textEOL)) { + fprintf(stderr, "Bad '-eol' value on command line\n"); + } + } + if (noPageBreaks) { + globalParams->setTextPageBreaks(gFalse); + } + if (quiet) { + globalParams->setErrQuiet(quiet); + } + + // get mapping to output encoding + if (!(uMap = globalParams->getTextEncoding())) { + error(-1, "Couldn't get text encoding"); + delete fileName; + goto err1; + } + + // open PDF file + if (ownerPassword[0] != '\001') { + ownerPW = new GooString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0] != '\001') { + userPW = new GooString(userPassword); + } else { + userPW = NULL; + } + + if(fileName->cmp("-") != 0) { + doc = new PDFDoc(fileName, ownerPW, userPW); + } else { + Object obj; + + obj.initNull(); + doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + } + + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + exitCode = 1; + goto err2; + } + +#ifdef ENFORCE_PERMISSIONS + // check for copy permission + if (!doc->okToCopy()) { + error(-1, "Copying of text from this document is not allowed."); + exitCode = 3; + goto err2; + } +#endif + + // construct text file name + if (argc == 3) { + textFileName = new GooString(argv[2]); + } else { + p = fileName->getCString() + fileName->getLength() - 4; + if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) { + textFileName = new GooString(fileName->getCString(), + fileName->getLength() - 4); + } else { + textFileName = fileName->copy(); + } + textFileName->append(htmlMeta ? ".html" : ".txt"); + } + + // get page range + if (firstPage < 1) { + firstPage = 1; + } + if (lastPage < 1 || lastPage > doc->getNumPages()) { + lastPage = doc->getNumPages(); + } + + // write HTML header + if (htmlMeta) { + if (!textFileName->cmp("-")) { + f = stdout; + } else { + if (!(f = fopen(textFileName->getCString(), "wb"))) { + error(-1, "Couldn't open text file '%s'", textFileName->getCString()); + exitCode = 2; + goto err3; + } + } + fputs("\n", f); + fputs("\n", f); + doc->getDocInfo(&info); + if (info.isDict()) { + printInfoString(f, info.getDict(), "Title", "", "\n", + uMap); + printInfoString(f, info.getDict(), "Subject", + "\n", uMap); + printInfoString(f, info.getDict(), "Keywords", + "\n", uMap); + printInfoString(f, info.getDict(), "Author", + "\n", uMap); + printInfoString(f, info.getDict(), "Creator", + "\n", uMap); + printInfoString(f, info.getDict(), "Producer", + "\n", uMap); + printInfoDate(f, info.getDict(), "CreationDate", + "\n"); + printInfoDate(f, info.getDict(), "LastModifiedDate", + "\n"); + } + info.free(); + fputs("\n", f); + fputs("\n", f); + fputs("
\n", f);
+    if (f != stdout) {
+      fclose(f);
+    }
+  }
+
+  // write text file
+  textOut = new TextOutputDev(textFileName->getCString(),
+			      physLayout, rawOrder, htmlMeta);
+  if (textOut->isOk()) {
+      doc->displayPages(textOut, firstPage, lastPage, 72, 72, 0,
+			gTrue, gFalse, gFalse);
+  } else {
+    delete textOut;
+    exitCode = 2;
+    goto err3;
+  }
+  delete textOut;
+
+  // write end of HTML file
+  if (htmlMeta) {
+    if (!textFileName->cmp("-")) {
+      f = stdout;
+    } else {
+      if (!(f = fopen(textFileName->getCString(), "ab"))) {
+	error(-1, "Couldn't open text file '%s'", textFileName->getCString());
+	exitCode = 2;
+	goto err3;
+      }
+    }
+    fputs("
\n", f); + fputs("\n", f); + fputs("\n", f); + if (f != stdout) { + fclose(f); + } + } + + exitCode = 0; + + // clean up + err3: + delete textFileName; + err2: + delete doc; + uMap->decRefCnt(); + err1: + delete globalParams; + err0: + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + return exitCode; +} + +static void printInfoString(FILE *f, Dict *infoDict, char *key, + char *text1, char *text2, UnicodeMap *uMap) { + Object obj; + GooString *s1; + GBool isUnicode; + Unicode u; + char buf[8]; + int i, n; + + if (infoDict->lookup(key, &obj)->isString()) { + fputs(text1, f); + s1 = obj.getString(); + if ((s1->getChar(0) & 0xff) == 0xfe && + (s1->getChar(1) & 0xff) == 0xff) { + isUnicode = gTrue; + i = 2; + } else { + isUnicode = gFalse; + i = 0; + } + while (i < obj.getString()->getLength()) { + if (isUnicode) { + u = ((s1->getChar(i) & 0xff) << 8) | + (s1->getChar(i+1) & 0xff); + i += 2; + } else { + u = s1->getChar(i) & 0xff; + ++i; + } + n = uMap->mapUnicode(u, buf, sizeof(buf)); + fwrite(buf, 1, n, f); + } + fputs(text2, f); + } + obj.free(); +} + +static void printInfoDate(FILE *f, Dict *infoDict, char *key, char *fmt) { + Object obj; + char *s; + + if (infoDict->lookup(key, &obj)->isString()) { + s = obj.getString()->getCString(); + if (s[0] == 'D' && s[1] == ':') { + s += 2; + } + fprintf(f, fmt, s); + } + obj.free(); +} diff --git a/rosapps/smartpdf/popplerlib.cbp b/rosapps/smartpdf/popplerlib.cbp new file mode 100644 index 00000000000..a72b838b23d --- /dev/null +++ b/rosapps/smartpdf/popplerlib.cbp @@ -0,0 +1,414 @@ + + + + + + diff --git a/rosapps/smartpdf/popplerlib.vcproj b/rosapps/smartpdf/popplerlib.vcproj new file mode 100644 index 00000000000..215063d2a56 --- /dev/null +++ b/rosapps/smartpdf/popplerlib.vcproj @@ -0,0 +1,855 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/smartpdf/smartpdf.def b/rosapps/smartpdf/smartpdf.def new file mode 100644 index 00000000000..e6594ef1cb6 --- /dev/null +++ b/rosapps/smartpdf/smartpdf.def @@ -0,0 +1,2 @@ +LIBRARY smartpdf.dll +EXPORTS \ No newline at end of file diff --git a/rosapps/smartpdf/smartpdf.rbuild b/rosapps/smartpdf/smartpdf.rbuild new file mode 100644 index 00000000000..d37dc2df478 --- /dev/null +++ b/rosapps/smartpdf/smartpdf.rbuild @@ -0,0 +1,134 @@ + + ntdll + kernel32 + advapi32 + comctl32 + comdlg32 + gdi32 + msimg32 + shell32 + user32 + winspool + libjpeg + zlib + freetype + fitz + poppler + + + + + + + + + + + 1 + 1 + + 0x0500 + . + . + include + include/freetype + . + . + . + src + baseutils + fitz/include + poppler + poppler/goo + poppler/fofi + poppler/splash + poppler/poppler + + base_util.c + dstring.c + file_util.c + geom_util.c + str_util.c + win_util.c + + + diff --git a/rosapps/smartpdf/src/AppPrefs.cc b/rosapps/smartpdf/src/AppPrefs.cc new file mode 100644 index 00000000000..19ab2380fe2 --- /dev/null +++ b/rosapps/smartpdf/src/AppPrefs.cc @@ -0,0 +1,359 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "AppPrefs.h" +#include "str_util.h" +#include "DisplayModel.h" +#include "DisplayState.h" +#include "dstring.h" +#include "FileHistory.h" +#include +#include +#include +#include +#include + +extern BOOL gShowToolbar; +extern BOOL gUseFitz; +extern BOOL gPdfAssociateDontAskAgain; +extern BOOL gPdfAssociateShouldAssociate; +extern bool CurrLangNameSet(const char* langName); +extern const char* CurrLangNameGet(); + +#define DEFAULT_WINDOW_X 40 +#define DEFAULT_WINDOW_Y 20 +#define DEFAULT_WINDOW_DX 640 +#define DEFAULT_WINDOW_DY 480 + +static BOOL FileExists(const char *fileName) +{ + struct stat buf; + int res; + + res = stat(fileName, &buf); + if (0 != res) + return FALSE; + return TRUE; +} + +bool Prefs_Serialize(FileHistoryList **root, DString *strOut) +{ + assert(0 == strOut->length); + DStringSprintf(strOut, " %s: %d\n", SHOW_TOOLBAR_STR, gShowToolbar); + DStringSprintf(strOut, " %s: %d\n", USE_FITZ_STR, gUseFitz); + DStringSprintf(strOut, " %s: %d\n", PDF_ASSOCIATE_DONT_ASK_STR, gPdfAssociateDontAskAgain); + DStringSprintf(strOut, " %s: %d\n", PDF_ASSOCIATE_ASSOCIATE_STR, gPdfAssociateShouldAssociate); + DStringSprintf(strOut, " %s: %s\n", UI_LANGUAGE_STR, CurrLangNameGet()); + return FileHistoryList_Serialize(root, strOut); +} + +static BOOL ParseDisplayMode(const char *txt, DisplayMode *resOut) +{ + assert(txt); + if (!txt) return FALSE; + return DisplayModeEnumFromName(txt, resOut); +} + +static BOOL ParseDouble(const char *txt, double *resOut) +{ + int res; + + assert(txt); + if (!txt) return FALSE; + + res = sscanf(txt, "%lf", resOut); + if (1 != res) + return FALSE; + return TRUE; +} + +static BOOL ParseInt(const char *txt, int *resOut) +{ + assert(txt); + if (!txt) return FALSE; + *resOut = atoi(txt); + return TRUE; +} + +static BOOL ParseBool(const char *txt, BOOL *resOut) +{ + assert(txt); + if (!txt) return FALSE; + int val = atoi(txt); + if (val) + *resOut = TRUE; + else + *resOut = FALSE; + return TRUE; +} + +enum PrefsParsingState { PPS_START, PPS_IN_FILE_HISTORY }; + +/* Return TRUE if 'str' is a comment line in preferences file. + Comment lines start with '#'. */ +static int Prefs_LineIsComment(const char *str) +{ + if (!str) + return FALSE; + if ('#' == *str) + return TRUE; + return FALSE; +} + +static int Prefs_LineIsStructKey(const char *str) +{ + if (strlen(str) <= 3) + return FALSE; + if ((' ' == str[0]) && (' ' == str[1])) + return TRUE; + return FALSE; +} + +static void ParseKeyValue(char *key, char *value, DisplayState *dsOut) +{ + BOOL fOk; + + assert(key); + assert(value); + assert(dsOut); + if (!key || !value || !dsOut) + return; + + if (str_eq(FILE_STR, key)) { + assert(value); + if (!value) return; + assert(!dsOut->filePath); + free((void*)dsOut->filePath); + dsOut->filePath = str_dup(value); + return; + } + + if (str_eq(DISPLAY_MODE_STR, key)) { + dsOut->displayMode = DM_SINGLE_PAGE; + fOk = ParseDisplayMode(value, &dsOut->displayMode); + assert(fOk); + return; + } + + if (str_eq(PAGE_NO_STR, key)) { + fOk = ParseInt(value, &dsOut->pageNo); + assert(fOk); + if (!fOk || (dsOut->pageNo < 1)) + dsOut->pageNo = 1; + return; + } + + if (str_eq(ZOOM_VIRTUAL_STR, key)) { + fOk = ParseDouble(value, &dsOut->zoomVirtual); + assert(fOk); + if (!fOk || !ValidZoomVirtual(dsOut->zoomVirtual)) + dsOut->zoomVirtual = 100.0; + return; + } + + if (str_eq(ROTATION_STR, key)) { + fOk = ParseInt(value, &dsOut->rotation); + assert(fOk); + if (!fOk || !validRotation(dsOut->rotation)) + dsOut->rotation = 0; + return; + } + + if (str_eq(VISIBLE_STR, key)) { + dsOut->visible= FALSE; + fOk = ParseBool(value, &dsOut->visible); + assert(fOk); + return; + } + + if (str_eq(FULLSCREEN_STR, key)) { + dsOut->fullScreen = FALSE; + fOk = ParseBool(value, &dsOut->fullScreen); + assert(fOk); + return; + } + + if (str_eq(SCROLL_X_STR, key)) { + dsOut->scrollX = 0; + fOk = ParseInt(value, &dsOut->scrollX); + assert(fOk); + return; + } + + if (str_eq(SCROLL_Y_STR, key)) { + dsOut->scrollY = 0; + fOk = ParseInt(value, &dsOut->scrollY); + assert(fOk); + return; + } + + if (str_eq(WINDOW_X_STR, key)) { + dsOut->windowX = DEFAULT_WINDOW_X; + fOk = ParseInt(value, &dsOut->windowX); + assert(fOk); + return; + } + + if (str_eq(WINDOW_Y_STR, key)) { + dsOut->windowY = DEFAULT_WINDOW_Y; + fOk = ParseInt(value, &dsOut->windowY); + assert(fOk); + return; + } + + if (str_eq(WINDOW_DX_STR, key)) { + dsOut->windowDx = DEFAULT_WINDOW_DX; + fOk = ParseInt(value, &dsOut->windowDx); + assert(fOk); + return; + } + + if (str_eq(WINDOW_DY_STR, key)) { + dsOut->windowDy = DEFAULT_WINDOW_DY; + fOk = ParseInt(value, &dsOut->windowDy); + assert(fOk); + return; + } + + assert(0); +} + +void FileHistory_Add(FileHistoryList **fileHistoryRoot, DisplayState *state) +{ + FileHistoryList * fileHistoryNode = NULL; + if (!FileExists(state->filePath)) { + DBG_OUT("FileHistory_Add() file '%s' doesn't exist anymore\n", state->filePath); + return; + } + + fileHistoryNode = FileHistoryList_Node_Create(); + fileHistoryNode->state = *state; + FileHistoryList_Node_Append(fileHistoryRoot, fileHistoryNode); + fileHistoryNode = NULL; +} + +/* Deserialize preferences from text. Put state into 'dsOut' and add all history + items to file history list 'root'. + Return FALSE if there was an error. + An ode to a state machine. */ +bool Prefs_Deserialize(const char *prefsTxt, FileHistoryList **fileHistoryRoot) +{ + PrefsParsingState state = PPS_START; + char * prefsTxtNormalized = NULL; + char * strTmp = NULL; + char * line; + char * key, *value, *keyToFree = NULL; + int isStructVal; + DisplayState currState; + + DisplayState_Init(&currState); + + prefsTxtNormalized = str_normalize_newline(prefsTxt, UNIX_NEWLINE); + if (!prefsTxtNormalized) + goto Exit; + + strTmp = prefsTxtNormalized; + for (;;) { + line = str_split_iter(&strTmp, UNIX_NEWLINE_C); + if (!line) + break; + str_strip_ws_right(line); + + /* skip empty and comment lines*/ + if (str_empty(line)) + goto Next; + if (Prefs_LineIsComment(line)) + goto Next; + + /* each line is key/value pair formatted as: "key: value" + value is optional. If value exists, there must + be a space after ':' */ + value = line; + keyToFree = str_split_iter(&value, ':'); + key = keyToFree; + assert(key); + if (!key) + goto Next; + if (str_empty(value)) { + value = NULL; /* there was no value */ + } else { + assert(' ' == *value); + if (' ' != *value) + goto Next; + value += 1; + } + isStructVal = Prefs_LineIsStructKey(key); + if (isStructVal) + key += 2; + +StartOver: + switch (state) { + case PPS_START: + if (str_eq(SHOW_TOOLBAR_STR, key)) { + gShowToolbar = TRUE; + ParseBool(value, &gShowToolbar); + break; + } + if (str_eq(USE_FITZ_STR, key)) { + gUseFitz = TRUE; + ParseBool(value, &gUseFitz); + break; + } + if (str_eq(PDF_ASSOCIATE_DONT_ASK_STR, key)) { + gPdfAssociateDontAskAgain = FALSE; + ParseBool(value, &gPdfAssociateDontAskAgain); + break; + } + if (str_eq(PDF_ASSOCIATE_ASSOCIATE_STR, key)) { + gPdfAssociateShouldAssociate = TRUE; + ParseBool(value, &gPdfAssociateShouldAssociate); + break; + } + if (str_eq(UI_LANGUAGE_STR, key)) { + CurrLangNameSet(value); + break; + } + if (str_eq(FILE_HISTORY_STR, key)) { + assert(!isStructVal); + state = PPS_IN_FILE_HISTORY; + assert(!value); + } else { + if (line) + DBG_OUT(" in state PPS_START, line='%s' \n\n", line); + else + DBG_OUT(" in state PPS_START, line is NULL\n\n"); + assert(0); + } + break; + + case PPS_IN_FILE_HISTORY: + if (isStructVal) { + ParseKeyValue(key, value, &currState); + } else { + if (currState.filePath) { + FileHistory_Add(fileHistoryRoot, &currState); + DisplayState_Init(&currState); + } + state = PPS_START; + goto StartOver; + } + break; + + } +Next: + free((void*)keyToFree); + keyToFree = NULL; + free((void*)line); + line = NULL; + } + + if (PPS_IN_FILE_HISTORY == state) { + if (currState.filePath) { + if (FileExists(currState.filePath)) + FileHistory_Add(fileHistoryRoot, &currState); + } + } +Exit: + free((void*)prefsTxtNormalized); + return TRUE; +} + diff --git a/rosapps/smartpdf/src/AppPrefs.h b/rosapps/smartpdf/src/AppPrefs.h new file mode 100644 index 00000000000..e652ef0dc52 --- /dev/null +++ b/rosapps/smartpdf/src/AppPrefs.h @@ -0,0 +1,13 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef APP_PREFS_H_ +#define APP_PREFS_H_ + +#include "DisplayState.h" +#include "FileHistory.h" + +bool Prefs_Serialize(FileHistoryList **root, DString *strOut); +bool Prefs_Deserialize(const char *prefsTxt, FileHistoryList **fileHistoryRoot); + +#endif + diff --git a/rosapps/smartpdf/src/DisplayModel.cc b/rosapps/smartpdf/src/DisplayModel.cc new file mode 100644 index 00000000000..57e534dcf76 --- /dev/null +++ b/rosapps/smartpdf/src/DisplayModel.cc @@ -0,0 +1,1316 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "DisplayModel.h" + +#include "str_util.h" + +// TODO: get rid of the need for GooString and UGooString in common code +#include "GooString.h" +#include "UGooString.h" +// TODO: get rid of the need for GooMutex.h ? +#include "GooMutex.h" + +#include +#include + +#ifdef _WIN32 +#define PREDICTIVE_RENDER 1 +#endif + +#define MAX_BITMAPS_CACHED 256 +static GooMutex cacheMutex; +static BitmapCacheEntry * gBitmapCache[MAX_BITMAPS_CACHED] = {0}; +static int gBitmapCacheCount = 0; + +static MutexAutoInitDestroy gAutoCacheMutex(&cacheMutex); + +DisplaySettings gDisplaySettings = { + PADDING_PAGE_BORDER_TOP_DEF, + PADDING_PAGE_BORDER_BOTTOM_DEF, + PADDING_PAGE_BORDER_LEFT_DEF, + PADDING_PAGE_BORDER_RIGHT_DEF, + PADDING_BETWEEN_PAGES_X_DEF, + PADDING_BETWEEN_PAGES_Y_DEF +}; + +bool validZoomReal(double zoomReal) +{ + if ((zoomReal < ZOOM_MIN) || (zoomReal > ZOOM_MAX)) { + DBG_OUT("validZoomReal() invalid zoom: %.4f\n", zoomReal); + return false; + } + return true; +} + +bool displayModeFacing(DisplayMode displayMode) +{ + if ((DM_SINGLE_PAGE == displayMode) || (DM_CONTINUOUS == displayMode)) + return false; + else if ((DM_FACING == displayMode) || (DM_CONTINUOUS_FACING == displayMode)) + return true; + assert(0); + return false; +} + +bool displayModeContinuous(DisplayMode displayMode) +{ + if ((DM_SINGLE_PAGE == displayMode) || (DM_FACING == displayMode)) + return false; + else if ((DM_CONTINUOUS == displayMode) || (DM_CONTINUOUS_FACING == displayMode)) + return true; + assert(0); + return false; +} + +int columnsFromDisplayMode(DisplayMode displayMode) +{ + if (DM_SINGLE_PAGE == displayMode) { + return 1; + } else if (DM_FACING == displayMode) { + return 2; + } else if (DM_CONTINUOUS == displayMode) { + return 1; + } else if (DM_CONTINUOUS_FACING == displayMode) { + return 2; + } else + assert(0); + return 1; +} + +DisplaySettings *globalDisplaySettings(void) +{ + return &gDisplaySettings; +} + +bool rotationFlipped(int rotation) +{ + assert(validRotation(rotation)); + normalizeRotation(&rotation); + if ((90 == rotation) || (270 == rotation)) + return true; + return false; +} + +bool displayStateFromDisplayModel(DisplayState *ds, DisplayModel *dm) +{ + ds->filePath = str_escape(dm->fileName()); + if (!ds->filePath) + return FALSE; + ds->displayMode = dm->displayMode(); + ds->fullScreen = dm->fullScreen(); + ds->pageNo = dm->currentPageNo(); + ds->rotation = dm->rotation(); + ds->zoomVirtual = dm->zoomVirtual(); + ds->scrollX = (int)dm->areaOffset.x; + if (displayModeContinuous(dm->displayMode())) { + /* TODO: should be offset of top page */ + ds->scrollY = 0; + } else { + ds->scrollY = (int)dm->areaOffset.y; + } + ds->windowDx = dm->drawAreaSize.dxI(); + ds->windowDy = dm->drawAreaSize.dyI(); + ds->windowX = 0; + ds->windowY = 0; + return TRUE; +} + +/* Given 'pageInfo', which should contain correct information about + pageDx, pageDy and rotation, return a page size after applying a global + rotation */ +void pageSizeAfterRotation(PdfPageInfo *pageInfo, int rotation, + double *pageDxOut, double *pageDyOut) +{ + assert(pageInfo && pageDxOut && pageDyOut); + if (!pageInfo || !pageDxOut || !pageDyOut) + return; + + *pageDxOut = pageInfo->pageDx; + *pageDyOut = pageInfo->pageDy; + + rotation = rotation + pageInfo->rotation; + normalizeRotation(&rotation); + if (rotationFlipped(rotation)) + swap_double(pageDxOut, pageDyOut); +} + +DisplayModel::DisplayModel(DisplayMode displayMode) +{ + _displayMode = displayMode; + _rotation = INVALID_ROTATION; + _zoomVirtual = INVALID_ZOOM; + _fullScreen = false; + _startPage = INVALID_PAGE_NO; + _appData = NULL; + _pdfEngine = NULL; + pagesInfo = NULL; + + _linkCount = 0; + _links = NULL; + + searchHitPageNo = INVALID_PAGE_NO; + searchState.searchState = eSsNone; + searchState.str = new GooString(); + searchState.strU = new UGooString(); +} + +DisplayModel::~DisplayModel() +{ + delete _pdfEngine; +} + +PdfPageInfo *DisplayModel::getPageInfo(int pageNo) const +{ + assert(validPageNo(pageNo)); + assert(pagesInfo); + if (!pagesInfo) return NULL; + return &(pagesInfo[pageNo-1]); +} + +bool DisplayModel::load(const char *fileName, int startPage, WindowInfo *win) +{ + assert(fileName); + if (!_pdfEngine->load(fileName, win)) + return false; + + if (validPageNo(startPage)) + _startPage = startPage; + else + _startPage = 1; + + if (!buildPagesInfo()) + return false; + return true; +} + +bool DisplayModel::buildPagesInfo(void) +{ + assert(!pagesInfo); + int _pageCount = pageCount(); + + pagesInfo = (PdfPageInfo*)calloc(1, _pageCount * sizeof(PdfPageInfo)); + if (!pagesInfo) + return false; + + for (int pageNo = 1; pageNo <= _pageCount; pageNo++) { + PdfPageInfo *pageInfo = getPageInfo(pageNo); + SizeD pageSize = pdfEngine()->pageSize(pageNo); + pageInfo->pageDx = pageSize.dx(); + pageInfo->pageDy = pageSize.dy(); + pageInfo->rotation = pdfEngine()->pageRotation(pageNo); + + pageInfo->links = NULL; + pageInfo->textPage = NULL; + + pageInfo->visible = false; + pageInfo->shown = false; + if (displayModeContinuous(_displayMode)) { + pageInfo->shown = true; + } else { + if ((pageNo >= _startPage) && (pageNo < _startPage + columnsFromDisplayMode(_displayMode))) { + DBG_OUT("DisplayModelSplash::CreateFromPdfDoc() set page %d as shown\n", pageNo); + pageInfo->shown = true; + } + } + } + return true; +} + +bool DisplayModel::pageShown(int pageNo) +{ + PdfPageInfo *pageInfo = getPageInfo(pageNo); + if (!pageInfo) + return false; + return pageInfo->shown; +} + +bool DisplayModel::pageVisible(int pageNo) +{ + PdfPageInfo *pageInfo = getPageInfo(pageNo); + if (!pageInfo) + return false; + return pageInfo->visible; +} + +/* Return true if a page is visible or a page below or above is visible */ +bool DisplayModel::pageVisibleNearby(int pageNo) +{ + /* TODO: should it check 2 pages above and below in facing mode? */ + if (pageVisible(pageNo)) + return true; + if (validPageNo(pageNo-1) && pageVisible(pageNo-1)) + return true; + if (validPageNo(pageNo+1) && pageVisible(pageNo+1)) + return true; + return false; +} + +/* Given a zoom level that can include a "virtual" zoom levels like ZOOM_FIT_WIDTH + and ZOOM_FIT_PAGE, calculate an absolute zoom level */ +double DisplayModel::zoomRealFromFirtualForPage(double zoomVirtual, int pageNo) +{ + double _zoomReal, zoomX, zoomY, pageDx, pageDy; + double areaForPageDx, areaForPageDy; + int areaForPageDxInt; + int columns; + + assert(0 != drawAreaSize.dxI()); + assert(0 != drawAreaSize.dy()); + + pageSizeAfterRotation(getPageInfo(pageNo), rotation(), &pageDx, &pageDy); + + assert(0 != (int)pageDx); + assert(0 != (int)pageDy); + + columns = columnsFromDisplayMode(displayMode()); + areaForPageDx = (drawAreaSize.dx() - PADDING_PAGE_BORDER_LEFT - PADDING_PAGE_BORDER_RIGHT); + areaForPageDx -= (PADDING_BETWEEN_PAGES_X * (columns - 1)); + areaForPageDxInt = (int)(areaForPageDx / columns); + areaForPageDx = (double)areaForPageDxInt; + areaForPageDy = drawAreaSize.dy() - PADDING_PAGE_BORDER_TOP - PADDING_PAGE_BORDER_BOTTOM; + if (ZOOM_FIT_WIDTH == zoomVirtual) { + /* TODO: should use gWinDx if we don't show scrollbarY */ + _zoomReal = (areaForPageDx * 100.0) / (double)pageDx; + } else if (ZOOM_FIT_PAGE == zoomVirtual) { + zoomX = (areaForPageDx * 100.0) / (double)pageDx; + zoomY = (areaForPageDy * 100.0) / (double)pageDy; + if (zoomX < zoomY) + _zoomReal = zoomX; + else + _zoomReal= zoomY; + } else + _zoomReal = zoomVirtual; + + return _zoomReal; +} + +int DisplayModel::firstVisiblePageNo(void) const +{ + assert(pagesInfo); + if (!pagesInfo) return INVALID_PAGE_NO; + + for (int pageNo = 1; pageNo <= pageCount(); ++pageNo) { + PdfPageInfo *pageInfo = getPageInfo(pageNo); + if (pageInfo->visible) + return pageNo; + } + assert(0); + return INVALID_PAGE_NO; +} + +int DisplayModel::currentPageNo(void) const +{ + if (displayModeContinuous(displayMode())) + return firstVisiblePageNo(); + else + return _startPage; +} + +void DisplayModel::setZoomVirtual(double zoomVirtual) +{ + int pageNo; + double minZoom = INVALID_BIG_ZOOM; + double thisPageZoom; + + assert(ValidZoomVirtual(zoomVirtual)); + _zoomVirtual = zoomVirtual; + + if ((ZOOM_FIT_WIDTH == zoomVirtual) || (ZOOM_FIT_PAGE == zoomVirtual)) { + /* we want the same zoom for all pages, so use the smallest zoom + across the pages so that the largest page fits. In most PDFs all + pages are the same size anyway */ + for (pageNo = 1; pageNo <= pageCount(); pageNo++) { + if (pageShown(pageNo)) { + thisPageZoom = zoomRealFromFirtualForPage(this->zoomVirtual(), pageNo); + assert(0 != thisPageZoom); + if (minZoom > thisPageZoom) + minZoom = thisPageZoom; + } + } + assert(minZoom != INVALID_BIG_ZOOM); + this->_zoomReal = minZoom; + } else + this->_zoomReal = zoomVirtual; +} + +/* Given pdf info and zoom/rotation, calculate the position of each page on a + large sheet that is continous view. Needs to be recalculated when: + * zoom changes + * rotation changes + * switching between display modes + * navigating to another page in non-continuous mode */ +void DisplayModel::relayout(double zoomVirtual, int rotation) +{ + int pageNo; + PdfPageInfo*pageInfo = NULL; + double currPosX; + double pageDx=0, pageDy=0; + int currDxInt, currDyInt; + double totalAreaDx, totalAreaDy; + double areaPerPageDx; + int areaPerPageDxInt; + double thisRowDx; + double rowMaxPageDy; + double offX, offY; + double pageOffX; + int columnsLeft; + int pageInARow; + int columns; + double newAreaOffsetX; + + assert(pagesInfo); + if (!pagesInfo) + return; + + normalizeRotation(&rotation); + assert(validRotation(rotation)); + + _rotation = rotation; + + double currPosY = PADDING_PAGE_BORDER_TOP; + double currZoomReal = _zoomReal; + setZoomVirtual(zoomVirtual); + +// DBG_OUT("DisplayModel::relayout(), pageCount=%d, zoomReal=%.6f, zoomVirtual=%.2f\n", pageCount, dm->zoomReal, dm->zoomVirtual); + totalAreaDx = 0; + + if (0 == currZoomReal) + newAreaOffsetX = 0.0; + else + newAreaOffsetX = areaOffset.x * _zoomReal / currZoomReal; + areaOffset.x = newAreaOffsetX; + /* calculate the position of each page on the canvas, given current zoom, + rotation, columns parameters. You can think of it as a simple + table layout i.e. rows with a fixed number of columns. */ + columns = columnsFromDisplayMode(displayMode()); + columnsLeft = columns; + currPosX = PADDING_PAGE_BORDER_LEFT; + rowMaxPageDy = 0; + for (pageNo = 1; pageNo <= pageCount(); ++pageNo) { + pageInfo = getPageInfo(pageNo); + if (!pageInfo->shown) { + assert(!pageInfo->visible); + continue; + } + pageSizeAfterRotation(pageInfo, rotation, &pageDx, &pageDy); + currDxInt = (int)(pageDx * _zoomReal * 0.01 + 0.5); + currDyInt = (int)(pageDy * _zoomReal * 0.01 + 0.5); + pageInfo->currDx = (double)currDxInt; + pageInfo->currDy = (double)currDyInt; + + if (rowMaxPageDy < pageInfo->currDy) + rowMaxPageDy = pageInfo->currDy; + + pageInfo->currPosX = currPosX; + pageInfo->currPosY = currPosY; + /* set position of the next page to be after this page with padding. + Note: for the last page we don't want padding so we'll have to + substract it when we create new page */ + currPosX += (pageInfo->currDx + PADDING_BETWEEN_PAGES_X); + + --columnsLeft; + assert(columnsLeft >= 0); + if (0 == columnsLeft) { + /* starting next row */ + currPosY += rowMaxPageDy + PADDING_BETWEEN_PAGES_Y; + rowMaxPageDy = 0; + thisRowDx = currPosX - PADDING_BETWEEN_PAGES_X + PADDING_PAGE_BORDER_RIGHT; + if (totalAreaDx < thisRowDx) + totalAreaDx = thisRowDx; + columnsLeft = columns; + currPosX = PADDING_PAGE_BORDER_LEFT; + } +/* DBG_OUT(" page = %3d, (x=%3d, y=%5d, dx=%4d, dy=%4d) orig=(dx=%d,dy=%d)\n", + pageNo, (int)pageInfo->currPosX, (int)pageInfo->currPosY, + (int)pageInfo->currDx, (int)pageInfo->currDy, + (int)pageDx, (int)pageDy); */ + } + + if (columnsLeft < columns) { + /* this is a partial row */ + currPosY += rowMaxPageDy + PADDING_BETWEEN_PAGES_Y; + thisRowDx = currPosX + (pageInfo->currDx + PADDING_BETWEEN_PAGES_X) - PADDING_BETWEEN_PAGES_X + PADDING_PAGE_BORDER_RIGHT; + if (totalAreaDx < thisRowDx) + totalAreaDx = thisRowDx; + } + + /* since pages can be smaller than the drawing area, center them in x axis */ + if (totalAreaDx < drawAreaSize.dx()) { + areaOffset.x = 0.0; + offX = (drawAreaSize.dx() - totalAreaDx) / 2.0 + PADDING_PAGE_BORDER_LEFT; + assert(offX >= 0.0); + areaPerPageDx = totalAreaDx - PADDING_PAGE_BORDER_LEFT - PADDING_PAGE_BORDER_RIGHT; + areaPerPageDx = areaPerPageDx - (PADDING_BETWEEN_PAGES_X * (columns - 1)); + areaPerPageDxInt = (int)(areaPerPageDx / (double)columns); + areaPerPageDx = (double)areaPerPageDxInt; + totalAreaDx = drawAreaSize.dx(); + pageInARow = 0; + for (pageNo = 1; pageNo <= pageCount(); ++pageNo) { + pageInfo = getPageInfo(pageNo); + if (!pageInfo->shown) { + assert(!pageInfo->visible); + continue; + } + pageOffX = (pageInARow * (PADDING_BETWEEN_PAGES_X + areaPerPageDx)); + pageOffX += (areaPerPageDx - pageInfo->currDx) / 2; + assert(pageOffX >= 0.0); + pageInfo->currPosX = pageOffX + offX; + ++pageInARow; + if (pageInARow == columns) + pageInARow = 0; + } + } + + /* if after resizing we would have blank space on the right due to x offset + being too much, make x offset smaller so that there's no blank space */ + if (drawAreaSize.dx() - (totalAreaDx - newAreaOffsetX) > 0) { + newAreaOffsetX = totalAreaDx - drawAreaSize.dx(); + areaOffset.x = newAreaOffsetX; + } + + /* if a page is smaller than drawing area in y axis, y-center the page */ + totalAreaDy = currPosY + PADDING_PAGE_BORDER_BOTTOM - PADDING_BETWEEN_PAGES_Y; + if (totalAreaDy < drawAreaSize.dy()) { + offY = PADDING_PAGE_BORDER_TOP + (drawAreaSize.dy() - totalAreaDy) / 2; + DBG_OUT(" offY = %.2f\n", offY); + assert(offY >= 0.0); + totalAreaDy = drawAreaSize.dy(); + for (pageNo = 1; pageNo <= pageCount(); ++pageNo) { + pageInfo = getPageInfo(pageNo); + if (!pageInfo->shown) { + assert(!pageInfo->visible); + continue; + } + pageInfo->currPosY += offY; + DBG_OUT(" page = %3d, (x=%3d, y=%5d, dx=%4d, dy=%4d) orig=(dx=%d,dy=%d)\n", + pageNo, (int)pageInfo->currPosX, (int)pageInfo->currPosY, + (int)pageInfo->currDx, (int)pageInfo->currDy, + (int)pageDx, (int)pageDy); + } + } + + _canvasSize = SizeD(totalAreaDx, totalAreaDy); +} + +void DisplayModel::changeStartPage(int startPage) +{ + assert(validPageNo(startPage)); + assert(!displayModeContinuous(displayMode())); + + int columns = columnsFromDisplayMode(displayMode()); + _startPage = startPage; + for (int pageNo = 1; pageNo <= pageCount(); pageNo++) { + PdfPageInfo *pageInfo = getPageInfo(pageNo); + if (displayModeContinuous(displayMode())) + pageInfo->shown = true; + else + pageInfo->shown = false; + if ((pageNo >= startPage) && (pageNo < startPage + columns)) { + //DBG_OUT("DisplayModel::changeStartPage() set page %d as shown\n", pageNo); + pageInfo->shown = true; + } + pageInfo->visible = false; + } + relayout(zoomVirtual(), rotation()); +} + +/* Given positions of each page in a large sheet that is continous view and + coordinates of a current view into that large sheet, calculate which + parts of each page is visible on the screen. + Needs to be recalucated after scrolling the view. */ +void DisplayModel::recalcVisibleParts(void) +{ + int pageNo; + RectI drawAreaRect; + RectI pageRect; + RectI intersect; + PdfPageInfo* pageInfo; + int visibleCount; + + assert(pagesInfo); + if (!pagesInfo) + return; + + drawAreaRect.x = (int)areaOffset.x; + drawAreaRect.y = (int)areaOffset.y; + drawAreaRect.dx = drawAreaSize.dxI(); + drawAreaRect.dy = drawAreaSize.dyI(); + +// DBG_OUT("DisplayModel::recalcVisibleParts() draw area (x=%3d,y=%3d,dx=%4d,dy=%4d)\n", +// drawAreaRect.x, drawAreaRect.y, drawAreaRect.dx, drawAreaRect.dy); + visibleCount = 0; + for (pageNo = 1; pageNo <= pageCount(); ++pageNo) { + pageInfo = getPageInfo(pageNo); + if (!pageInfo->shown) { + assert(!pageInfo->visible); + continue; + } + pageRect.x = (int)pageInfo->currPosX; + pageRect.y = (int)pageInfo->currPosY; + pageRect.dx = (int)pageInfo->currDx; + pageRect.dy = (int)pageInfo->currDy; + pageInfo->visible = false; + if (RectI_Intersect(&pageRect, &drawAreaRect, &intersect)) { + pageInfo->visible = true; + visibleCount += 1; + pageInfo->bitmapX = (int) ((double)intersect.x - pageInfo->currPosX); + assert(pageInfo->bitmapX >= 0); + pageInfo->bitmapY = (int) ((double)intersect.y - pageInfo->currPosY); + assert(pageInfo->bitmapY >= 0); + pageInfo->bitmapDx = intersect.dx; + pageInfo->bitmapDy = intersect.dy; + pageInfo->screenX = (int) ((double)intersect.x - areaOffset.x); + assert(pageInfo->screenX >= 0); + assert(pageInfo->screenX <= drawAreaSize.dx()); + pageInfo->screenY = (int) ((double)intersect.y - areaOffset.y); + assert(pageInfo->screenX >= 0); + assert(pageInfo->screenY <= drawAreaSize.dy()); +/* DBG_OUT(" visible page = %d, (x=%3d,y=%3d,dx=%4d,dy=%4d) at (x=%d,y=%d)\n", + pageNo, pageInfo->bitmapX, pageInfo->bitmapY, + pageInfo->bitmapDx, pageInfo->bitmapDy, + pageInfo->screenX, pageInfo->screenY); */ + } + } + + assert(visibleCount > 0); +} + +/* Map rectangle on the page to point on the screen. */ +void DisplayModel::rectCvtUserToScreen(int pageNo, RectD *r) +{ + double sx, sy, ex, ey; + + sx = r->x; + sy = r->y; + ex = r->x + r->dx; + ey = r->y + r->dy; + + cvtUserToScreen(pageNo, &sx, &sy); + cvtUserToScreen(pageNo, &ex, &ey); + RectD_FromXY(r, sx, ex, sy, ey); +} + +/* Map rectangle on the page to point on the screen. */ +void DisplayModel::rectCvtScreenToUser(int *pageNo, RectD *r) +{ + double sx, sy, ex, ey; + + sx = r->x; + sy = r->y; + ex = r->x + r->dx; + ey = r->y + r->dy; + + cvtScreenToUser(pageNo, &sx, &sy); + cvtScreenToUser(pageNo, &ex, &ey); + RectD_FromXY(r, sx, ex, sy, ey); +} + +int DisplayModel::getPageNoByPoint (double x, double y) +{ + for (int pageNo = 1; pageNo <= pageCount(); ++pageNo) { + PdfPageInfo *pageInfo = getPageInfo(pageNo); + if (!pageInfo->visible) + continue; + assert(pageInfo->shown); + if (!pageInfo->shown) + continue; + + RectI pageOnScreen; + pageOnScreen.x = pageInfo->screenX; + pageOnScreen.y = pageInfo->screenY; + pageOnScreen.dx = pageInfo->bitmapDx; + pageOnScreen.dy = pageInfo->bitmapDy; + + if (RectI_Inside (&pageOnScreen, (int)x, (int)y)) /* @note: int casts */ + return pageNo; + } + return POINT_OUT_OF_PAGE; +} + +void DisplayModel::recalcSearchHitCanvasPos(void) +{ + int pageNo; + RectD rect; + + pageNo = searchHitPageNo; + if (INVALID_PAGE_NO == pageNo) return; + rect = searchHitRectPage; + rectCvtUserToScreen(pageNo, &rect); + searchHitRectCanvas.x = (int)rect.x; + searchHitRectCanvas.y = (int)rect.y; + searchHitRectCanvas.dx = (int)rect.dx; + searchHitRectCanvas.dy = (int)rect.dy; +} + +/* Recalculates the position of each link on the canvas i.e. applies current + rotation and zoom level and offsets it by the offset of each page in + the canvas. + TODO: applying rotation and zoom level could be split into a separate + function for speedup, since it only has to change after rotation/zoomLevel + changes while this function has to be called after each scrolling. + But I'm not sure if this would be a significant speedup */ +void DisplayModel::recalcLinksCanvasPos(void) +{ + PdfLink * pdfLink; + PdfPageInfo * pageInfo; + int linkNo; + RectD rect; + + // TODO: calling it here is a bit of a hack + recalcSearchHitCanvasPos(); + + DBG_OUT("DisplayModel::recalcLinksCanvasPos() linkCount=%d\n", _linkCount); + + if (0 == _linkCount) + return; + assert(_links); + if (!_links) + return; + + for (linkNo = 0; linkNo < _linkCount; linkNo++) { + pdfLink = link(linkNo); + pageInfo = getPageInfo(pdfLink->pageNo); + if (!pageInfo->visible) { + /* hack: make the links on pages that are not shown invisible by + moving it off canvas. A better solution would probably be + not adding those links in the first place */ + pdfLink->rectCanvas.x = -100; + pdfLink->rectCanvas.y = -100; + pdfLink->rectCanvas.dx = 0; + pdfLink->rectCanvas.dy = 0; + continue; + } + + rect = pdfLink->rectPage; + rectCvtUserToScreen(pdfLink->pageNo, &rect); + +#if 0 // this version is correct but needs to be made generic, not specific to poppler + /* hack: in PDFs that have a crop-box (like treo700psprint_UG.pdf) + we need to shift links by the offset of crop-box. Since we do it + after conversion involving ctm, we need to apply current zoom and + rotation. This is probably not the best place to be doing this + but it's the only one we managed to make work */ + double offX = dm->pdfDoc->getCatalog()->getPage(pdfLink->pageNo)->getCropBox()->x1; + double offY = dm->pdfDoc->getCatalog()->getPage(pdfLink->pageNo)->getCropBox()->y1; + if (flippedRotation(dm->rotation)) { + double tmp = offX; + offX = offY; + offY = tmp; + } + offX = offX * dm->zoomReal * 0.01; + offY = offY * dm->zoomReal * 0.01; +#else + pdfLink->rectCanvas.x = (int)rect.x; + pdfLink->rectCanvas.y = (int)rect.y; + pdfLink->rectCanvas.dx = (int)rect.dx; + pdfLink->rectCanvas.dy = (int)rect.dy; +#endif +#if 0 + DBG_OUT(" link on page (x=%d, y=%d, dx=%d, dy=%d),\n", + (int)pdfLink->rectPage.x, (int)pdfLink->rectPage.y, + (int)pdfLink->rectPage.dx, (int)pdfLink->rectPage.dy); + DBG_OUT(" screen (x=%d, y=%d, dx=%d, dy=%d)\n", + (int)rect.x, (int)rect.y, + (int)rect.dx, (int)rect.dy); +#endif + } +} + +void DisplayModel::clearSearchHit(void) +{ + DBG_OUT("DisplayModel::clearSearchHit()\n"); + searchHitPageNo = INVALID_PAGE_NO; +} + +void DisplayModel::setSearchHit(int pageNo, RectD *hitRect) +{ + //DBG_OUT("DisplayModel::setSearchHit() page=%d at pos (%.2f, %.2f)-(%.2f,%.2f)\n", pageNo, xs, ys, xe, ye); + searchHitPageNo = pageNo; + searchHitRectPage = *hitRect; + recalcSearchHitCanvasPos(); +} + +/* Given position 'x'/'y' in the draw area, returns a structure describing + a link or NULL if there is no link at this position. + Note: DisplayModelSplash owns this memory so it should not be changed by the + caller and caller should not reference it after it has changed (i.e. process + it immediately since it will become invalid after each _relayout()). + TODO: this function is called frequently from UI code so make sure that + it's fast enough for a decent number of link. + Possible speed improvement: remember which links are visible after + scrolling and skip the _Inside test for those invisible. + Another way: build another list with only those visible, so we don't + even have to travers those that are invisible. + */ +PdfLink *DisplayModel::linkAtPosition(int x, int y) +{ + if (0 == _linkCount) return NULL; + assert(_links); + if (!_links) return NULL; + + int canvasPosX = x + (int)areaOffset.x; + int canvasPosY = y + (int)areaOffset.y; + for (int i = 0; i < _linkCount; i++) { + PdfLink *currLink = link(i); + + if (RectI_Inside(&(currLink->rectCanvas), canvasPosX, canvasPosY)) + return currLink; + } + return NULL; +} + +/* Send the request to render a given page to a rendering thread */ +void DisplayModel::startRenderingPage(int pageNo) +{ + RenderQueue_Add(this, pageNo); +} + +void DisplayModel::renderVisibleParts(void) +{ + int pageNo; + PdfPageInfo* pageInfo; + int lastVisible = 0; + +// DBG_OUT("DisplayModel::renderVisibleParts()\n"); + for (pageNo = 1; pageNo <= pageCount(); ++pageNo) { + pageInfo = getPageInfo(pageNo); + if (pageInfo->visible) { + assert(pageInfo->shown); + startRenderingPage(pageNo); + lastVisible = pageNo; + } + } + assert(0 != lastVisible); +#ifdef PREDICTIVE_RENDER + if (lastVisible != pageCount()) + startRenderingPage(lastVisible+1); +#endif +} + +void DisplayModel::changeTotalDrawAreaSize(SizeD totalDrawAreaSize) +{ + int newPageNo; + int currPageNo; + + currPageNo = currentPageNo(); + + setTotalDrawAreaSize(totalDrawAreaSize); + + relayout(zoomVirtual(), rotation()); + recalcVisibleParts(); + recalcLinksCanvasPos(); + renderVisibleParts(); + setScrollbarsState(); + newPageNo = currentPageNo(); + if (newPageNo != currPageNo) + pageChanged(); + repaintDisplay(true); +} + +void DisplayModel::goToPage(int pageNo, int scrollY, int scrollX) +{ + assert(validPageNo(pageNo)); + if (!validPageNo(pageNo)) + return; + + /* in facing mode only start at odd pages (odd because page + numbering starts with 1, so odd is really an even page) */ + if (displayModeFacing(displayMode())) + pageNo = ((pageNo-1) & ~1) + 1; + + if (!displayModeContinuous(displayMode())) { + /* in single page mode going to another page involves recalculating + the size of canvas */ + changeStartPage(pageNo); + } + //DBG_OUT("DisplayModel::goToPage(pageNo=%d, scrollY=%d)\n", pageNo, scrollY); + if (-1 != scrollX) + areaOffset.x = (double)scrollX; + PdfPageInfo * pageInfo = getPageInfo(pageNo); + + /* Hack: if an image is smaller in Y axis than the draw area, then we center + the image by setting pageInfo->currPosY in RecalcPagesInfo. So we shouldn't + scroll (adjust areaOffset.y) there because it defeats the purpose. + TODO: is there a better way of y-centering? + TODO: it probably doesn't work in continuous mode (but that's a corner + case, I hope) */ + if (!displayModeContinuous(displayMode())) + areaOffset.y = (double)scrollY; + else + areaOffset.y = pageInfo->currPosY - PADDING_PAGE_BORDER_TOP + (double)scrollY; + /* TODO: prevent scrolling too far */ + + recalcVisibleParts(); + recalcLinksCanvasPos(); + renderVisibleParts(); + setScrollbarsState(); + pageChanged(); + repaintDisplay(true); +} + + +void DisplayModel::changeDisplayMode(DisplayMode displayMode) +{ + if (_displayMode == displayMode) + return; + + _displayMode = displayMode; + int currPageNo = currentPageNo(); + if (displayModeContinuous(displayMode)) { + /* mark all pages as shown but not yet visible. The equivalent code + for non-continuous mode is in DisplayModel::changeStartPage() called + from DisplayModel::goToPage() */ + for (int pageNo = 1; pageNo <= pageCount(); pageNo++) { + PdfPageInfo *pageInfo = &(pagesInfo[pageNo-1]); + pageInfo->shown = true; + pageInfo->visible = false; + } + relayout(zoomVirtual(), rotation()); + } + goToPage(currPageNo, 0); +} + +/* given 'columns' and an absolute 'pageNo', return the number of the first + page in a row to which a 'pageNo' belongs e.g. if 'columns' is 2 and we + have 5 pages in 3 rows: + (1,2) + (3,4) + (5) + then, we return 1 for pages (1,2), 3 for (3,4) and 5 for (5). + This is 1-based index, not 0-based. */ +static int FirstPageInARowNo(int pageNo, int columns) +{ + int row = ((pageNo - 1) / columns); /* 0-based row number */ + int firstPageNo = row * columns + 1; /* 1-based page in a row */ + return firstPageNo; +} + +/* In continuous mode just scrolls to the next page. In single page mode + rebuilds the display model for the next page. + Returns true if advanced to the next page or false if couldn't advance + (e.g. because already was at the last page) */ +bool DisplayModel::goToNextPage(int scrollY) +{ + int columns = columnsFromDisplayMode(displayMode()); + int currPageNo = currentPageNo(); + int firstPageInCurrRow = FirstPageInARowNo(currPageNo, columns); + int newPageNo = currPageNo + columns; + int firstPageInNewRow = FirstPageInARowNo(newPageNo, columns); + +// DBG_OUT("DisplayModel::goToNextPage(scrollY=%d), currPageNo=%d, firstPageInNewRow=%d\n", scrollY, currPageNo, firstPageInNewRow); + if ((firstPageInNewRow > pageCount()) || (firstPageInCurrRow == firstPageInNewRow)) { + /* we're on a last row or after it, can't go any further */ + return FALSE; + } + goToPage(firstPageInNewRow, scrollY); + return TRUE; +} + +bool DisplayModel::goToPrevPage(int scrollY) +{ + int columns = columnsFromDisplayMode(displayMode()); + int currPageNo = currentPageNo(); + DBG_OUT("DisplayModel::goToPrevPage(scrollY=%d), currPageNo=%d\n", scrollY, currPageNo); + if (currPageNo <= columns) { + /* we're on a first page, can't go back */ + return FALSE; + } + goToPage(currPageNo - columns, scrollY); + return TRUE; +} + +bool DisplayModel::goToLastPage(void) +{ + DBG_OUT("DisplayModel::goToLastPage()\n"); + + int columns = columnsFromDisplayMode(displayMode()); + int currPageNo = currentPageNo(); + int firstPageInLastRow = FirstPageInARowNo(pageCount(), columns); + + if (currPageNo != firstPageInLastRow) { /* are we on the last page already ? */ + goToPage(firstPageInLastRow, 0); + return TRUE; + } + return FALSE; +} + +bool DisplayModel::goToFirstPage(void) +{ + DBG_OUT("DisplayModel::goToFirstPage()\n"); + + if (displayModeContinuous(displayMode())) { + if (0 == areaOffset.y) { + return FALSE; + } + } else { + assert(pageShown(_startPage)); + if (1 == _startPage) { + /* we're on a first page already */ + return FALSE; + } + } + goToPage(1, 0); + return TRUE; +} + +void DisplayModel::scrollXTo(int xOff) +{ + DBG_OUT("DisplayModel::scrollXTo(xOff=%d)\n", xOff); + areaOffset.x = (double)xOff; + recalcVisibleParts(); + recalcLinksCanvasPos(); + setScrollbarsState(); + repaintDisplay(false); +} + +void DisplayModel::scrollXBy(int dx) +{ + DBG_OUT("DisplayModel::scrollXBy(dx=%d)\n", dx); + + double maxX = _canvasSize.dx() - drawAreaSize.dx(); + assert(maxX >= 0.0); + double prevX = areaOffset.x; + double newX = prevX + (double)dx; + if (newX < 0.0) + newX = 0.0; + else + if (newX > maxX) + newX = maxX; + + if (newX == prevX) + return; + + scrollXTo((int)newX); +} + +void DisplayModel::scrollYTo(int yOff) +{ + DBG_OUT("DisplayModel::scrollYTo(yOff=%d)\n", yOff); + + int currPageNo = currentPageNo(); + areaOffset.y = (double)yOff; + recalcVisibleParts(); + recalcLinksCanvasPos(); + renderVisibleParts(); + + int newPageNo = currentPageNo(); + if (newPageNo != currPageNo) + pageChanged(); + repaintDisplay(false); +} + +/* Scroll the doc in y-axis by 'dy'. If 'changePage' is TRUE, automatically + switch to prev/next page in non-continuous mode if we scroll past the edges + of current page */ +void DisplayModel::scrollYBy(int dy, bool changePage) +{ + PdfPageInfo * pageInfo; + int currYOff = (int)areaOffset.y; + int newPageNo; + int currPageNo; + + DBG_OUT("DisplayModel::scrollYBy(dy=%d, changePage=%d)\n", dy, (int)changePage); + assert(0 != dy); + if (0 == dy) return; + + int newYOff = currYOff; + + if (!displayModeContinuous(displayMode()) && changePage) { + if ((dy < 0) && (0 == currYOff)) { + if (_startPage > 1) { + newPageNo = _startPage-1; + assert(validPageNo(newPageNo)); + pageInfo = getPageInfo(newPageNo); + newYOff = (int)pageInfo->currDy - drawAreaSize.dyI(); + if (newYOff < 0) + newYOff = 0; /* TODO: center instead? */ + goToPrevPage(newYOff); + return; + } + } + + /* see if we have to change page when scrolling forward */ + if ((dy > 0) && (_startPage < pageCount())) { + if ((int)areaOffset.y + drawAreaSize.dyI() >= _canvasSize.dyI()) { + goToNextPage(0); + return; + } + } + } + + newYOff += dy; + if (newYOff < 0) { + newYOff = 0; + } else if (newYOff + drawAreaSize.dyI() > _canvasSize.dyI()) { + newYOff = _canvasSize.dyI() - drawAreaSize.dyI(); + } + + if (newYOff == currYOff) + return; + + currPageNo = currentPageNo(); + areaOffset.y = (double)newYOff; + recalcVisibleParts(); + recalcLinksCanvasPos(); + renderVisibleParts(); + setScrollbarsState(); + newPageNo = currentPageNo(); + if (newPageNo != currPageNo) + pageChanged(); + repaintDisplay(false); +} + +void DisplayModel::scrollYByAreaDy(bool forward, bool changePage) +{ + int toScroll = drawAreaSize.dyI(); + if (forward) + scrollYBy(toScroll, changePage); + else + scrollYBy(-toScroll, changePage); +} + +void DisplayModel::zoomTo(double zoomVirtual) +{ + //DBG_OUT("DisplayModel::zoomTo() zoomVirtual=%.6f\n", _zoomVirtual); + int currPageNo = currentPageNo(); + relayout(zoomVirtual, rotation()); + goToPage(currPageNo, 0); +} + +void DisplayModel::zoomBy(double zoomFactor) +{ + double newZoom = _zoomReal * zoomFactor; + //DBG_OUT("DisplayModel::zoomBy() zoomReal=%.6f, zoomFactor=%.2f, newZoom=%.2f\n", dm->zoomReal, zoomFactor, newZoom); + if (newZoom > ZOOM_MAX) + return; + zoomTo(newZoom); +} + +void DisplayModel::rotateBy(int newRotation) +{ + normalizeRotation(&newRotation); + assert(0 != newRotation); + if (0 == newRotation) + return; + assert(validRotation(newRotation)); + if (!validRotation(newRotation)) + return; + + newRotation += rotation(); + normalizeRotation(&newRotation); + assert(validRotation(newRotation)); + if (!validRotation(newRotation)) + return; + + int currPageNo = currentPageNo(); + relayout(zoomVirtual(), newRotation); + goToPage(currPageNo, 0); +} + +void DisplayModel::showNormalCursor(void) +{ + SetCursor(LoadCursor(NULL, IDC_ARROW)); +} + +void DisplayModel::showBusyCursor(void) +{ + // TODO: what is the right cursor? + // can I set it per-window only? + SetCursor(LoadCursor(NULL, IDC_ARROW)); +} + +void LockCache(void) { + gLockMutex(&cacheMutex); +} + +void UnlockCache(void) { + gUnlockMutex(&cacheMutex); +} + +static void BitmapCacheEntry_Free(BitmapCacheEntry *entry) { + assert(entry); + if (!entry) return; + delete entry->bitmap; + free((void*)entry); +} + +void BitmapCache_FreeAll(void) { + LockCache(); + for (int i=0; i < gBitmapCacheCount; i++) { + BitmapCacheEntry_Free(gBitmapCache[i]); + gBitmapCache[i] = NULL; + } + gBitmapCacheCount = 0; + UnlockCache(); +} + +/* Free all bitmaps in the cache that are not visible. Returns true if freed + at least one item. */ +bool BitmapCache_FreeNotVisible(void) { + LockCache(); + bool freedSomething = false; + int cacheCount = gBitmapCacheCount; + int curPos = 0; + for (int i = 0; i < cacheCount; i++) { + BitmapCacheEntry* entry = gBitmapCache[i]; + bool shouldFree = !entry->dm->pageVisibleNearby(entry->pageNo); + if (shouldFree) { + if (!freedSomething) + DBG_OUT("BitmapCache_FreeNotVisible() "); + DBG_OUT("freed %d ", entry->pageNo); + freedSomething = true; + BitmapCacheEntry_Free(gBitmapCache[i]); + gBitmapCache[i] = NULL; + --gBitmapCacheCount; + } + + if (curPos != i) + gBitmapCache[curPos] = gBitmapCache[i]; + + if (!shouldFree) + ++curPos; + } + UnlockCache(); + if (freedSomething) + DBG_OUT("\n"); + return freedSomething; +} + +static bool BitmapCache_FreePage(DisplayModel *dm, int pageNo) { + LockCache(); + int cacheCount = gBitmapCacheCount; + bool freedSomething = false; + int curPos = 0; + for (int i = 0; i < cacheCount; i++) { + bool shouldFree = (gBitmapCache[i]->dm == dm) && (gBitmapCache[i]->pageNo == pageNo); + if (shouldFree) { + if (!freedSomething) + DBG_OUT("BitmapCache_FreePage() "); + DBG_OUT("freed %d ", gBitmapCache[i]->pageNo); + freedSomething = true; + BitmapCacheEntry_Free(gBitmapCache[i]); + gBitmapCache[i] = NULL; + --gBitmapCacheCount; + } + + if (curPos != i) + gBitmapCache[curPos] = gBitmapCache[i]; + + if (!shouldFree) + ++curPos; + } + UnlockCache(); + if (freedSomething) + DBG_OUT("\n"); + return freedSomething; +} + +/* Free all bitmaps cached for a given . Returns TRUE if freed + at least one item. */ +bool BitmapCache_FreeForDisplayModel(DisplayModel *dm) { + LockCache(); + int cacheCount = gBitmapCacheCount; + bool freedSomething = false; + int curPos = 0; + for (int i = 0; i < cacheCount; i++) { + bool shouldFree = (gBitmapCache[i]->dm == dm); + if (shouldFree) { + if (!freedSomething) + DBG_OUT("BitmapCache_FreeForDisplayModel() "); + DBG_OUT("freed %d ", gBitmapCache[i]->pageNo); + freedSomething = true; + BitmapCacheEntry_Free(gBitmapCache[i]); + gBitmapCache[i] = NULL; + --gBitmapCacheCount; + } + + if (curPos != i) + gBitmapCache[curPos] = gBitmapCache[i]; + + if (!shouldFree) + ++curPos; + } + UnlockCache(); + if (freedSomething) + DBG_OUT("\n"); + return freedSomething; +} + +void BitmapCache_Add(DisplayModel *dm, int pageNo, double zoomLevel, int rotation, + RenderedBitmap *bitmap, double renderTime) { + assert(gBitmapCacheCount <= MAX_BITMAPS_CACHED); + assert(dm); + assert(validRotation(rotation)); + + normalizeRotation(&rotation); + DBG_OUT("BitmapCache_Add(pageNo=%d, zoomLevel=%.2f%%, rotation=%d)\n", pageNo, zoomLevel, rotation); + LockCache(); + + /* It's possible there still is a cached bitmap with different zoomLevel/rotation */ + BitmapCache_FreePage(dm, pageNo); + + if (gBitmapCacheCount >= MAX_BITMAPS_CACHED - 1) { + /* TODO: find entry that is not visible and remove it from cache to + make room for new entry */ + delete bitmap; + /* @note: crossing initialization of "BitmapCacheEntry* entry" not allowed in mingw */ + //goto UnlockAndExit; + UnlockCache(); + return; + } + BitmapCacheEntry* entry = (BitmapCacheEntry*)malloc(sizeof(BitmapCacheEntry)); + if (!entry) { + delete bitmap; + goto UnlockAndExit; + } + entry->dm = dm; + entry->pageNo = pageNo; + entry->zoomLevel = zoomLevel; + entry->rotation = rotation; + entry->bitmap = bitmap; + entry->renderTime = renderTime; + gBitmapCache[gBitmapCacheCount++] = entry; +UnlockAndExit: + UnlockCache(); +} + +BitmapCacheEntry *BitmapCache_Find(DisplayModel *dm, int pageNo) { + BitmapCacheEntry* entry; + LockCache(); + for (int i = 0; i < gBitmapCacheCount; i++) { + entry = gBitmapCache[i]; + if ( (dm == entry->dm) && (pageNo == entry->pageNo) ) { + goto Exit; + } + } + entry = NULL; +Exit: + UnlockCache(); + return entry; +} + +BitmapCacheEntry *BitmapCache_Find(DisplayModel *dm, int pageNo, double zoomLevel, int rotation) { + BitmapCacheEntry *entry; + normalizeRotation(&rotation); + LockCache(); + for (int i = 0; i < gBitmapCacheCount; i++) { + entry = gBitmapCache[i]; + if ( (dm == entry->dm) && (pageNo == entry->pageNo) && + (zoomLevel == entry->zoomLevel) && (rotation == entry->rotation)) { + goto Exit; + } + } + entry = NULL; +Exit: + UnlockCache(); + return entry; +} + +/* Return true if a bitmap for a page defined by , , + and exists in the cache */ +bool BitmapCache_Exists(DisplayModel *dm, int pageNo, double zoomLevel, int rotation) { + if (BitmapCache_Find(dm, pageNo, zoomLevel, rotation)) + return true; + return false; +} + diff --git a/rosapps/smartpdf/src/DisplayModel.h b/rosapps/smartpdf/src/DisplayModel.h new file mode 100644 index 00000000000..634ce589473 --- /dev/null +++ b/rosapps/smartpdf/src/DisplayModel.h @@ -0,0 +1,372 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef _DISPLAY_MODEL_H_ +#define _DISPLAY_MODEL_H_ + +#include "base_util.h" +#include "geom_util.h" +#include "DisplayState.h" +#include "PdfEngine.h" + +class GooString; +class Link; +class Links; +class TextPage; +class UGooString; +class SplashBitmap; + +#define INVALID_ZOOM -99 +#define INVALID_BIG_ZOOM 999999.0 /* arbitrary but big */ + +typedef struct DisplaySettings { + int paddingPageBorderTop; + int paddingPageBorderBottom; + int paddingPageBorderLeft; + int paddingPageBorderRight; + int paddingBetweenPagesX; + int paddingBetweenPagesY; +} DisplaySettings; + +/* the default distance between a page and window border edges, in pixels */ +#ifdef _WIN32 + #define PADDING_PAGE_BORDER_TOP_DEF 6 +#else + #define PADDING_PAGE_BORDER_TOP_DEF 4 +#endif +#define PADDING_PAGE_BORDER_BOTTOM_DEF PADDING_PAGE_BORDER_TOP_DEF +#define PADDING_PAGE_BORDER_LEFT_DEF 2 +#define PADDING_PAGE_BORDER_RIGHT_DEF 2 +/* the distance between pages in x axis, in pixels. Only applicable if + columns > 1 */ +#define PADDING_BETWEEN_PAGES_X_DEF 4 +/* the distance between pages in y axis, in pixels. Only applicable if + more than one page in y axis (continuous mode) */ +#define PADDING_BETWEEN_PAGES_Y_DEF PADDING_PAGE_BORDER_TOP_DEF * 2 + +#define PADDING_PAGE_BORDER_TOP gDisplaySettings.paddingPageBorderTop +#define PADDING_PAGE_BORDER_BOTTOM gDisplaySettings.paddingPageBorderBottom +#define PADDING_PAGE_BORDER_LEFT gDisplaySettings.paddingPageBorderLeft +#define PADDING_PAGE_BORDER_RIGHT gDisplaySettings.paddingPageBorderRight +#define PADDING_BETWEEN_PAGES_X gDisplaySettings.paddingBetweenPagesX +#define PADDING_BETWEEN_PAGES_Y gDisplaySettings.paddingBetweenPagesY + +#define POINT_OUT_OF_PAGE 0 + +/* Describes a link on PDF page. */ +typedef struct PdfLink { + int pageNo; /* on which Pdf page the link exists. 1..pageCount */ + // TODO: remove it from common code, only splash needs it + Link * link; /* a reference to a link; we don't own it */ + RectD rectPage; /* position of the link on the page */ + RectI rectCanvas; /* position of the link on canvas */ +} PdfLink; + +/* Describes many attributes of one page in one, convenient place */ +typedef struct PdfPageInfo { + /* data that is constant for a given page. page size and rotation + recorded in PDF file */ + double pageDx; // TODO: consider SizeD instead of pageDx/pageDy + double pageDy; + int rotation; + + /* data that needs to be set before DisplayModel_relayout(). + Determines whether a given page should be shown on the screen. */ + bool shown; + + /* data that changes when zoom and rotation changes */ + /* position and size within total area after applying zoom and rotation. + Represents display rectangle for a given page. + Calculated in DisplayModel_relayout() */ + + /* TODO: change it to RectD ?*/ + double currDx; + double currDy; + double currPosX; + double currPosY; + + /* data that changes due to scrolling. Calculated in DisplayModel_RecalcVisibleParts() */ + bool visible; /* is currently visible on the page ? */ + /* part of the image that should be shown */ + int bitmapX, bitmapY, bitmapDx, bitmapDy; + /* where it should be blitted on the screen */ + int screenX, screenY; + + // TODO: remove it from common code, only splash needs it + Links * links; + TextPage * textPage; +} PdfPageInfo; + +/* When searching, we can be in one of those states. The state determines what + will happen after searching for next or previous term. + */ +enum SearchState { + /* Search hasn't started yet. 'Next' will start searching from the top + of current page, searching forward. 'Previous' will start searching from + the top of current page, searching backward. */ + eSsNone, + /* We searched the whole document and didn't find the search term at all. 'Next' + and 'prev' do nothing. */ + eSsNotFound, + /* Previous 'next' search found the term, without wrapping. 'Next' will + continue searching forward from the current position. 'Previous' will + search backward from the current position.*/ + eSsFoundNext, + /* Like eSsFoundNext but we wrapped past last page. In that case we show + a message about being wrapped and continuing from top. */ + eSsFoundNextWrapped, + /* Previous 'prev' search found the term, without wrapping. 'Next' will + search forward from the current position. 'Prev' will continue searching + backward */ + eSsFoundPrev, + /* Like eSsFoundPrev, but wrapped around first page. */ + eSsFoundPrevWrapped, +/* TODO: add eSsFoundOnlyOne as optimization i.e. if the hit is the same + as previous hit, 'next' and 'previous' will do nothing, to avoid (possibly + long) no-op search. + eSsFoundOnlyOne */ +}; + +/* The current state of searching */ +typedef struct SearchStateData { + /* String we search for, both regular and unicode versions */ + GooString * str; + UGooString * strU; + /* The page on which we started the search */ + int startPage; + /* did we wrap (crossed last page when searching forward or first page + when searching backwards) */ + BOOL wrapped; + SearchState searchState; + BOOL caseSensitive; + int currPage; /* page for the last hit */ +} SearchStateData; + +class DisplayModel +{ +public: + DisplayModel(DisplayMode displayMode); + virtual ~DisplayModel(); + + RenderedBitmap *renderBitmap(int pageNo, double zoomReal, int rotation, + BOOL (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA) { + if (!_pdfEngine) return NULL; + return _pdfEngine->renderBitmap(pageNo, zoomReal, rotation, abortCheckCbkA, abortCheckCbkDataA); + } + + PdfEngine *pdfEngine() { return _pdfEngine; } + + /* number of pages in PDF document */ + int pageCount() const { return _pdfEngine->pageCount(); } + bool load(const char *fileName, int startPage, WindowInfo *win); + bool validPageNo(int pageNo) const { return _pdfEngine->validPageNo(pageNo); } + + /* current rotation selected by user */ + int rotation(void) const { return _rotation; } + void setRotation(int rotation) { _rotation = rotation; } + DisplayMode displayMode() const { return _displayMode; } + + void changeDisplayMode(DisplayMode displayMode); + const char *fileName(void) const { return _pdfEngine->fileName(); } + + bool fullScreen(void) const { return _fullScreen; } + void setFullScreen(bool fullScreen) { _fullScreen = fullScreen; } + + /* a "virtual" zoom level. Can be either a real zoom level in percent + (i.e. 100.0 is original size) or one of virtual values ZOOM_FIT_PAGE + or ZOOM_FIT_WIDTH, whose real value depends on draw area size */ + double zoomVirtual(void) const { return _zoomVirtual; } + void setZoomVirtual(double zoomVirtual); + + double zoomReal(void) const { return _zoomReal; } + + int startPage(void) const { return _startPage; } + + /* TODO: should become non-virtual */ + int currentPageNo(void) const; + + /* an arbitrary pointer that can be used by an app e.g. a multi-window GUI + could link this to a data describing window displaying this document */ + void * appData() const { return _appData; } + + void setAppData(void *appData) { _appData = appData; } + + /* TODO: rename to pageInfo() */ + PdfPageInfo * getPageInfo(int pageNo) const; + + /* an array of PdfPageInfo, len of array is pageCount */ + PdfPageInfo * pagesInfo; + + /* areaOffset is "polymorphic". If drawAreaSize.dx > totalAreSize.dx then + areaOffset.x is offset of total area rect inside draw area, otherwise + an offset of draw area inside total area. + The same for areaOff.y, except it's for dy */ + PointD areaOffset; + + /* size of draw area i.e. _totalDrawAreaSize minus scrollbarsSize (if + they're shown) */ + SizeD drawAreaSize; + + SearchStateData searchState; + + int searchHitPageNo; + RectD searchHitRectPage; + RectI searchHitRectCanvas; + + void setScrollbarsSize(int scrollbarXDy, int scrollbarYDx) { + _scrollbarXDy = scrollbarXDy; + _scrollbarYDx = scrollbarYDx; + } + + void setTotalDrawAreaSize(SizeD size) { + _totalDrawAreaSize = size; + drawAreaSize = SizeD(size.dx() - _scrollbarYDx, size.dy() - _scrollbarXDy); + } + + void changeTotalDrawAreaSize(SizeD totalDrawAreaSize); + + bool pageShown(int pageNo); + bool pageVisible(int pageNo); + bool pageVisibleNearby(int pageNo); + void relayout(double zoomVirtual, int rotation); + + void goToPage(int pageNo, int scrollY, int scrollX=-1); + bool goToPrevPage(int scrollY); + bool goToNextPage(int scrollY); + bool goToFirstPage(void); + bool goToLastPage(void); + + void scrollXTo(int xOff); + void scrollXBy(int dx); + + void scrollYTo(int yOff); + void scrollYBy(int dy, bool changePage); + void scrollYByAreaDy(bool forward, bool changePage); + + void zoomTo(double zoomVirtual); + void zoomBy(double zoomFactor); + void rotateBy(int rotation); + + virtual int getTextInRegion(int pageNo, RectD *region, unsigned short *buf, int buflen) = 0; + + void clearSearchHit(void); + void setSearchHit(int pageNo, RectD *hitRect); + void recalcLinksCanvasPos(void); + + int linkCount(void) const { return _linkCount; } + PdfLink * link(int linkNo) const { return &(_links[linkNo]); } + PdfLink * linkAtPosition(int x, int y); + + virtual void handleLink(PdfLink *pdfLink) = 0; + + virtual void cvtUserToScreen(int pageNo, double *x, double *y) = 0; + virtual void cvtScreenToUser(int *pageNo, double *x, double *y) = 0; + void rectCvtUserToScreen(int pageNo, RectD *r); + void rectCvtScreenToUser(int *pageNo, RectD *r); + +protected: + int getPageNoByPoint (double x, double y); + + void startRenderingPage(int pageNo); + + bool buildPagesInfo(void); + double zoomRealFromFirtualForPage(double zoomVirtual, int pageNo); + int firstVisiblePageNo(void) const; + void changeStartPage(int startPage); + void recalcVisibleParts(void); + void recalcSearchHitCanvasPos(void); + void renderVisibleParts(void); + /* Those need to be implemented somewhere else by the GUI */ + void setScrollbarsState(void); + /* called when a page number changes */ + void pageChanged(void); + /* called when we decide that the display needs to be redrawn */ + void repaintDisplay(bool delayed); + + void showBusyCursor(); + void showNormalCursor(); + + PdfEngine * _pdfEngine; + DisplayMode _displayMode; /* TODO: not used yet */ + bool _fullScreen; + /* In non-continuous mode is the first page from a PDF file that we're + displaying. + No meaning in continous mode. */ + int _startPage; + void * _appData; + + /* size of scrollbars */ + int _scrollbarXDy; + int _scrollbarYDx; + + /* size of total draw area (i.e. window size) */ + SizeD _totalDrawAreaSize; + + /* size of virtual canvas containing all rendered pages. + TODO: re-consider, 32 signed number should be large enough for everything. */ + SizeD _canvasSize; + + /* real zoom value calculated from zoomVirtual. Same as zoomVirtual except + for ZOOM_FIT_PAGE and ZOOM_FIT_WIDTH */ + double _zoomReal; + double _zoomVirtual; + int _rotation; + + /* total number of links */ + int _linkCount; + /* an array of 'totalLinksCount' size, each entry describing a link */ + PdfLink * _links; +}; + +bool validZoomReal(double zoomReal); +bool displayModeContinuous(DisplayMode displayMode); +bool displayModeFacing(DisplayMode displayMode); +DisplaySettings * globalDisplaySettings(void); +int columnsFromDisplayMode(DisplayMode displayMode); +void pageSizeAfterRotation(PdfPageInfo *pageInfo, int rotation, double *pageDxOut, double *pageDyOut); +bool displayStateFromDisplayModel(DisplayState *ds, DisplayModel *dm); + +extern DisplaySettings gDisplaySettings; + +/* must be implemented somewhere else */ +extern void LaunchBrowser(const char *uri); + +/* We keep a cache of rendered bitmaps. BitmapCacheEntry keeps data + that uniquely identifies rendered page (dm, pageNo, rotation, zoomReal) + and corresponding rendered bitmap. +*/ +typedef struct { + DisplayModel * dm; + int pageNo; + int rotation; + double zoomLevel; + RenderedBitmap *bitmap; + double renderTime; +} BitmapCacheEntry; + +typedef struct { + DisplayModel * dm; + int pageNo; + double zoomLevel; + int rotation; + int abort; +} PageRenderRequest; + +/* Lock protecting both bitmap cache and page render queue */ +void LockCache(); +void UnlockCache(); + +void RenderQueue_Add(DisplayModel *dm, int pageNo); +extern void RenderQueue_RemoveForDisplayModel(DisplayModel *dm); +extern void cancelRenderingForDisplayModel(DisplayModel *dm); + +BitmapCacheEntry *BitmapCache_Find(DisplayModel *dm, int pageNo, double zoomLevel, int rotation); +BitmapCacheEntry *BitmapCache_Find(DisplayModel *dm, int pageNo); +bool BitmapCache_Exists(DisplayModel *dm, int pageNo, double zoomLevel, int rotation); +void BitmapCache_Add(DisplayModel *dm, int pageNo, double zoomLevel, int rotation, + RenderedBitmap *bitmap, double renderTime); +void BitmapCache_FreeAll(void); +bool BitmapCache_FreeForDisplayModel(DisplayModel *dm); +bool BitmapCache_FreeNotVisible(void); + +#endif diff --git a/rosapps/smartpdf/src/DisplayModelFitz.cc b/rosapps/smartpdf/src/DisplayModelFitz.cc new file mode 100644 index 00000000000..397d0cfdc3f --- /dev/null +++ b/rosapps/smartpdf/src/DisplayModelFitz.cc @@ -0,0 +1,170 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "DisplayModelFitz.h" + +#include "str_util.h" + +DisplayModelFitz::DisplayModelFitz(DisplayMode displayMode) : + DisplayModel(displayMode) +{ + _pdfEngine = new PdfEngineFitz(); +} + +DisplayModelFitz::~DisplayModelFitz() +{ + RenderQueue_RemoveForDisplayModel(this); + BitmapCache_FreeForDisplayModel(this); + cancelRenderingForDisplayModel(this); +} + +DisplayModelFitz *DisplayModelFitz_CreateFromFileName( + const char *fileName, + SizeD totalDrawAreaSize, + int scrollbarXDy, int scrollbarYDx, + DisplayMode displayMode, int startPage, + WindowInfo *win) +{ + DisplayModelFitz * dm = NULL; + + dm = new DisplayModelFitz(displayMode); + if (!dm) + goto Error; + + if (!dm->load(fileName, startPage, win)) + goto Error; + + dm->setScrollbarsSize(scrollbarXDy, scrollbarYDx); + dm->setTotalDrawAreaSize(totalDrawAreaSize); + +// DBG_OUT("DisplayModelFitz_CreateFromPageTree() pageCount = %d, startPage=%d, displayMode=%d\n", +// dm->pageCount(), (int)dm->startPage, (int)displayMode); + return dm; +Error: + delete dm; + return NULL; +} + +void DisplayModelFitz::cvtUserToScreen(int pageNo, double *x, double *y) +{ + pdf_page *page = pdfEngineFitz()->getPdfPage(pageNo); + double zoom = zoomReal(); + int rot = rotation(); + fz_point p; + + normalizeRotation (&rot); + zoom *= 0.01; + + p.x = *x; + p.y = *y; + + fz_matrix ctm = pdfEngineFitz()->viewctm(page, zoom, rot); + + fz_point tp = fz_transformpoint (ctm, p); + + PdfPageInfo *pageInfo = getPageInfo(pageNo); + + double vx = 0, vy = 0; + if (rot == 90 || rot == 180) + vx += pageInfo->currDx; + if (rot == 180 || rot == 270) + vy += pageInfo->currDy; + + *x = tp.x + 0.5 + pageInfo->screenX - pageInfo->bitmapX + vx; + *y = tp.y + 0.5 + pageInfo->screenY - pageInfo->bitmapY + vy; + +} + +void DisplayModelFitz::cvtScreenToUser(int *pageNo, double *x, double *y) +{ + double zoom = zoomReal(); + int rot = rotation(); + fz_point p; + + normalizeRotation (&rot); + zoom *= 0.01; + + *pageNo = getPageNoByPoint (*x, *y); + if (*pageNo == POINT_OUT_OF_PAGE) return; + + pdf_page *page = pdfEngineFitz()->getPdfPage(*pageNo); + + PdfPageInfo *pageInfo = getPageInfo(*pageNo); + + p.x = *x - 0.5 - pageInfo->screenX + pageInfo->bitmapX; + p.y = *y - 0.5 - pageInfo->screenY + pageInfo->bitmapY; + + fz_matrix ctm = pdfEngineFitz()->viewctm(page, zoom, rot); + fz_matrix invCtm = fz_invertmatrix(ctm); + + fz_point tp = fz_transformpoint (invCtm, p); + + double vx = 0, vy = 0; + if (rot == 90 || rot == 180) + vy -= pageInfo->pageDy; + if (rot == 180 || rot == 270) + vx += pageInfo->pageDx; + + *x = tp.x + vx; + *y = tp.y + vy; +} + +void DisplayModelFitz::handleLink(PdfLink *pdfLink) +{ + // TODO: implement me +} + +/* Given (in user coordinates ) on page , copies text in that region + * to . Returnes number of copied characters */ +int DisplayModelFitz::getTextInRegion(int pageNo, RectD *region, unsigned short *buf, int buflen) +{ + int bxMin, bxMax, byMin, byMax; + int xMin, xMax, yMin, yMax; + pdf_textline * line, *ln; + fz_error * error; + pdf_page * page = pdfEngineFitz()->getPdfPage(pageNo); + fz_tree * tree = page->tree; + double rot = 0; + double zoom = 1; + + error = pdf_loadtextfromtree(&line, tree, fz_identity()); + if (error) + return NULL; + + xMin = region->x; + xMax = xMin + region->dx; + yMin = region->y; + yMax = yMin + region->dy; + + int p = 0; + for (ln = line; ln; ln = ln->next) { + int oldP = p; + for (int i = 0; i < ln->len; i++) { + bxMin = ln->text[i].bbox.x0; + bxMax = ln->text[i].bbox.x1; + byMin = ln->text[i].bbox.y0; + byMax = ln->text[i].bbox.y1; + int c = ln->text[i].c; + if (c < 32) + c = '?'; + if (bxMax >= xMin && bxMin <= xMax && byMax >= yMin && byMin <= yMax + && p < buflen) { + buf[p++] = c; + //DBG_OUT("Char: %c : %d; ushort: %hu\n", (char)c, (int)c, (unsigned short)c); + //DBG_OUT("Found char: %c : %hu; real %c : %hu\n", c, (unsigned short)(unsigned char) c, ln->text[i].c, ln->text[i].c); + } + } + + if (p > oldP && p < buflen - 1) { +#ifdef WIN32 + buf[p++] = '\r'; buf[p++] = 10; + //DBG_OUT("Char: %c : %d; ushort: %hu\n", (char)buf[p], (int)(unsigned char)buf[p], buf[p]); +#else + buf[p++] = '\n'; +#endif + } + } + + pdf_droptextline(line); + + return p; +} diff --git a/rosapps/smartpdf/src/DisplayModelFitz.h b/rosapps/smartpdf/src/DisplayModelFitz.h new file mode 100644 index 00000000000..deb4e0b6e9c --- /dev/null +++ b/rosapps/smartpdf/src/DisplayModelFitz.h @@ -0,0 +1,30 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef _DISPLAY_MODEL_FITZ_H_ +#define _DISPLAY_MODEL_FITZ_H_ + +#include "DisplayModel.h" + +class DisplayModelFitz : public DisplayModel +{ +public: + DisplayModelFitz(DisplayMode displayMode); + virtual ~DisplayModelFitz(); + + PdfEngineFitz * pdfEngineFitz(void) { return (PdfEngineFitz*)_pdfEngine; } + virtual void handleLink(PdfLink *pdfLink); + + virtual int getTextInRegion(int pageNo, RectD *region, unsigned short *buf, int buflen); + + virtual void cvtUserToScreen(int pageNo, double *x, double *y); + virtual void cvtScreenToUser(int *pageNo ,double *x, double *y); +}; + +DisplayModelFitz *DisplayModelFitz_CreateFromFileName( + const char *fileName, + SizeD totalDrawAreaSize, + int scrollbarXDy, int scrollbarYDx, + DisplayMode displayMode, int startPage, + WindowInfo *win); + +#endif diff --git a/rosapps/smartpdf/src/DisplayModelSplash.cc b/rosapps/smartpdf/src/DisplayModelSplash.cc new file mode 100644 index 00000000000..865c6373319 --- /dev/null +++ b/rosapps/smartpdf/src/DisplayModelSplash.cc @@ -0,0 +1,869 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "DisplayModelSplash.h" +#include "str_util.h" + +#include "GlobalParams.h" +#include "GooMutex.h" +#include "GooString.h" +#include "Link.h" +#include "Object.h" /* must be included before SplashOutputDev.h because of sloppiness in SplashOutputDev.h */ +#include "PDFDoc.h" +#include "SplashBitmap.h" +#include "SplashOutputDev.h" +#include "TextOutputDev.h" + +#ifdef __GNUC__ +#include +#endif + +#include +#include /* malloc etc. */ + +#define ACTION_NEXT_PAGE "NextPage" +#define ACTION_PREV_PAGE "PrevPage" +#define ACTION_FIRST_PAGE "FirstPage" +#define ACTION_LAST_PAGE "LastPage" + +void CDECL error(int pos, char *msg, ...) { + va_list args; + char buf[4096], *p = buf; + + // NB: this can be called before the globalParams object is created + if (globalParams && globalParams->getErrQuiet()) { + return; + } + + if (pos >= 0) { + p += _snprintf(p, sizeof(buf)-1, "Error (%d): ", pos); + *p = '\0'; + OutputDebugString((TCHAR*)p); /* @note: TCHAR* cast */ + } else { + OutputDebugString(TEXT("Error: ")); /* @note: TEXT() cast */ + } + + p = buf; + va_start(args, msg); + p += _vsnprintf(p, sizeof(buf) - 1, msg, args); + while ( p > buf && isspace(p[-1]) ) + *--p = '\0'; + *p++ = '\r'; + *p++ = '\n'; + *p = '\0'; + OutputDebugString((TCHAR*)buf); /* @note: TCHAR* cast */ + va_end(args); +} + +#if 0 +static Links *GetLinksForPage(PDFDoc *doc, int pageNo) +{ + Object obj; + Catalog *catalog = doc->getCatalog(); + Page *page = catalog->getPage(pageNo); + Links *links = new Links(page->getAnnots(&obj), catalog->getBaseURI()); + obj.free(); + return links; +} + +static int GetPageRotation(PDFDoc *doc, int pageNo) +{ + Catalog *catalog = doc->getCatalog(); + Page *page = catalog->getPage(pageNo); + int rotation = page->getRotate(); + return rotation; +} + +static const char * GetLinkActionKindName(LinkActionKind kind) { + switch (kind) { + case (actionGoTo): + return "actionGoTo"; + case actionGoToR: + return "actionGoToR"; + case actionLaunch: + return "actionLaunch"; + case actionURI: + return "actionURI"; + case actionNamed: + return "actionNamed"; + case actionMovie: + return "actionMovie"; + case actionUnknown: + return "actionUnknown"; + default: + assert(0); + return "unknown action"; + } +} + +static void DumpLinks(DisplayModelSplash *dm, PDFDoc *doc) +{ + Links * links = NULL; + int pagesCount, linkCount; + int pageRotation; + Link * link; + LinkURI * linkUri; + GBool upsideDown; + + DBG_OUT("DumpLinks() started\n"); + if (!doc) + return; + + upsideDown = dm->outputDevice->upsideDown(); + pagesCount = doc->getNumPages(); + for (int pageNo = 1; pageNo < pagesCount; ++pageNo) { + delete links; + links = GetLinksForPage(doc, pageNo); + if (!links) + goto Exit; + linkCount = links->getNumLinks(); + if (linkCount > 0) + DBG_OUT(" :page %d linkCount = %d\n", pageNo, linkCount); + pageRotation = GetPageRotation(doc, pageNo); + for (int i=0; igetLink(i); + LinkAction *action = link->getAction(); + LinkActionKind actionKind = action->getKind(); + double xs, ys, xe, ye; + link->getRect(&xs, &ys, &xe, &ye); + DBG_OUT( " link %d: pageRotation=%d upsideDown=%d, action=%d (%s), (xs=%d,ys=%d - xe=%d,ye=%d)\n", i, + pageRotation, (int)upsideDown, + (int)actionKind, + GetLinkActionKindName(actionKind), + (int)xs, (int)ys, (int)xe, (int)ye); + if (actionURI == actionKind) { + linkUri = (LinkURI*)action; + DBG_OUT(" uri=%s\n", linkUri->getURI()->getCString()); + } + } + } +Exit: + delete links; + DBG_OUT("DumpLinks() finished\n"); +} +#endif + +static void TransfromUpsideDown(DisplayModelSplash *dm, int pageNo, double *y1, double *y2) +{ + assert(dm); + if (!dm) return; + + PdfPageInfo *pageInfo = dm->getPageInfo(pageNo); + double dy = pageInfo->pageDy; + assert(*y1 <= dy); + *y1 = dy - *y1; + assert(*y2 <= dy); + *y2 = dy - *y2; +} + +DisplayModelSplash::DisplayModelSplash(DisplayMode displayMode) : + DisplayModel(displayMode) +{ + _pdfEngine = new PdfEnginePoppler(); +} + +TextPage *DisplayModelSplash::GetTextPage(int pageNo) +{ + assert(pdfDoc); + if (!pdfDoc) return NULL; + assert(validPageNo(pageNo)); + assert(pagesInfo); + if (!pagesInfo) return NULL; + + PdfPageInfo * pdfPageInfo = &(pagesInfo[pageNo-1]); + if (!pdfPageInfo->textPage) { + TextOutputDev *textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); + if (!textOut) + return NULL; + if (!textOut->isOk()) { + delete textOut; + return NULL; + } + pdfDoc->displayPage(textOut, pageNo, 72, 72, 0, gFalse, gTrue, gFalse); + pdfPageInfo->textPage = textOut->takeText(); + delete textOut; + } + return pdfPageInfo->textPage; +} + +void DisplayModelSplash::FreeLinks(void) +{ + for (int pageNo = 1; pageNo <= pageCount(); ++pageNo) { + delete pagesInfo[pageNo-1].links; + pagesInfo[pageNo-1].links = NULL; + } +} + +void DisplayModelSplash::FreeTextPages() +{ + for (int pageNo = 1; pageNo <= pageCount(); ++pageNo) { + delete pagesInfo[pageNo-1].textPage; + pagesInfo[pageNo-1].textPage = NULL; + } +} + +DisplayModelSplash::~DisplayModelSplash() +{ + RenderQueue_RemoveForDisplayModel(this); + BitmapCache_FreeForDisplayModel(this); + cancelRenderingForDisplayModel(this); + FreeLinks(); + FreeTextPages(); + + delete searchState.str; + delete searchState.strU; + free((void*)_links); + free((void*)pagesInfo); +} + +/* Map point / on the page to point on the screen. */ +void DisplayModelSplash::cvtUserToScreen(int pageNo, double *x, double *y) +{ + double xTmp = *x; + double yTmp = *y; + double ctm[6]; + double dpi; + int rotationTmp; + + assert(pdfDoc); + if (!pdfDoc) return; + + dpi = (double)PDF_FILE_DPI * _zoomReal * 0.01; + rotationTmp = rotation(); + normalizeRotation(&rotationTmp); + SplashOutputDev *outputDev = pdfEnginePoppler()->outputDevice(); + pdfDoc->getCatalog()->getPage(pageNo)->getDefaultCTM(ctm, dpi, dpi, rotationTmp, outputDev->upsideDown()); + + PdfPageInfo *pageInfo = getPageInfo(pageNo); + *x = ctm[0] * xTmp + ctm[2] * yTmp + ctm[4] + 0.5 + pageInfo->screenX - pageInfo->bitmapX; + *y = ctm[1] * xTmp + ctm[3] * yTmp + ctm[5] + 0.5 + pageInfo->screenY - pageInfo->bitmapY; +} + +/* Map point / on screen to user coordinates , , . + * If it's not possible (i.e. given point is out of any page), + * returns CONVERSION_IMPOSSIBLE as a */ +void DisplayModelSplash::cvtScreenToUser(int *pageNo, double *x, double *y) +{ + double xTmp = *x; + double yTmp = *y; + double ctm[6], invCtm[6]; + double dpi, invDpi; + int rotationTmp, invRotationTmp; + + assert(pdfDoc); + if (!pdfDoc) return; + + /* find page number of point / */ + *pageNo = getPageNoByPoint (*x, *y); + + if (*pageNo == POINT_OUT_OF_PAGE) return; + + dpi = (double)PDF_FILE_DPI * _zoomReal * 0.01; + invDpi = (double)PDF_FILE_DPI * 1/(_zoomReal * 0.01); + rotationTmp = rotation(); + normalizeRotation(&rotationTmp); + invRotationTmp = rotationTmp == 0 ? 0 : 360 - rotationTmp; + SplashOutputDev *outputDev = pdfEnginePoppler()->outputDevice(); + pdfDoc->getCatalog()->getPage(*pageNo)->getDefaultCTM(ctm, dpi, dpi, rotationTmp, outputDev->upsideDown()); + pdfDoc->getCatalog()->getPage(*pageNo)->getDefaultCTM(invCtm, invDpi, invDpi, invRotationTmp, outputDev->upsideDown()); + + //DBG_OUT("Rotation = %d\n", rotationTmp); + + int sign; + if (rotationTmp == 0 || rotationTmp == 180) + sign = 1; + else //rotationTmp == 90 || rotationTmp == 270 + sign = -1; + + PdfPageInfo *pageInfo = getPageInfo(*pageNo); + *x = invCtm[0] * sign*(xTmp - ctm[4] - 0.5 - pageInfo->screenX + pageInfo->bitmapX) + + invCtm[2] * sign*(yTmp - ctm[5] - 0.5 - pageInfo->screenY + pageInfo->bitmapY); + *y = invCtm[1] * sign*(xTmp - ctm[4] - 0.5 - pageInfo->screenX + pageInfo->bitmapX) + + invCtm[3] * sign*(yTmp - ctm[5] - 0.5 - pageInfo->screenY + pageInfo->bitmapY); +} + +/* Given (in user coordinates ) on page , return a text in that + region or NULL if no text */ +int DisplayModelSplash::getTextInRegion(int pageNo, RectD *region, unsigned short *buf, int buflen) +{ + GooString * txt = NULL; + double xMin, yMin, xMax, yMax; + GBool useMediaBox = gFalse; + GBool crop = gTrue; + GBool doLinks = gFalse; + PDFRectangle selection; + PdfPageInfo * pageInfo; + + assert(pdfDoc); + if (!pdfDoc) return NULL; + + double dpi = (double)PDF_FILE_DPI; + + /* TODO: cache textOut? */ + TextOutputDev *textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); + if (!textOut->isOk()) { + delete textOut; + return 0; + } + /* TODO: make sure we're not doing background threading */ + pageInfo = getPageInfo(pageNo); + xMin = region->x; + yMin = pageInfo->pageDy - (region->y + region->dy);//since coordinates are upside-dwon + xMax = xMin + region->dx; + yMax = yMin + region->dy; + pdfDoc->displayPage(textOut, pageNo, dpi, dpi, 0, useMediaBox, crop, doLinks); + + txt = textOut->getText(xMin, yMin, xMax, yMax); + + int length = 0; + if (txt && (txt->getLength() > 0)) { + //DBG_OUT("DisplayModelSplash::getTextInRegion() found text '%s' on pageNo=%d, (x=%d, y=%d), (dx=%d, dy=%d)\n", + //txt->getCString(), pageNo, (int)region->x, (int)region->y, (int)region->dx, (int)region->dy); + length = min (txt->getLength(), buflen); + for (int i = 0; i < length; i++) { + buf[i] = (unsigned short)(unsigned char)txt->getChar(i); + //DBG_OUT("Char: %c : %d; ushort: %hu\n", txt->getChar(i), (int)(unsigned char)txt->getChar(i), (unsigned short)(unsigned char)txt->getChar(i)); + } + } else { + DBG_OUT("DisplayModelSplash::getTextInRegion() didn't find text on pageNo=%d, (x=%d, y=%d), (dx=%d, dy=%d)\n", + pageNo, (int)region->x, (int)region->y, (int)region->dx, (int)region->dy); + if (txt) { + delete txt; + txt = NULL; + } + } + delete textOut; + return length; +} + +/* Create display info from a 'fileName' etc. 'pdfDoc' will be owned by DisplayInfo + from now on, so the caller should not delete it itself. Not very good but + alternative is worse. + */ +DisplayModelSplash *DisplayModelSplash_CreateFromFileName( + const char *fileName, + SizeD totalDrawAreaSize, + int scrollbarXDy, int scrollbarYDx, + DisplayMode displayMode, int startPage, + WindowInfo *win) +{ + DisplayModelSplash * dm = new DisplayModelSplash(displayMode); + if (!dm) + goto Error; + + if (!dm->load(fileName, startPage, win)) + goto Error; + + dm->setScrollbarsSize(scrollbarXDy, scrollbarYDx); + dm->setTotalDrawAreaSize(totalDrawAreaSize); + + dm->pdfDoc = dm->pdfEnginePoppler()->pdfDoc(); + + DBG_OUT("DisplayModelSplash::CreateFromPdfDoc() pageCount = %d, startPage=%d, displayMode=%d\n", + dm->pageCount(), (int)dm->startPage(), (int)displayMode); + return dm; +Error: + delete dm; + return NULL; +} + +/* Make sure that search hit is visible on the screen */ +void DisplayModelSplash::EnsureSearchHitVisible() +{ + int pageNo; + int yStart, yEnd; + int xStart, xEnd; + int xNewPos, yNewPos; + BOOL needScroll = FALSE; + + pageNo = searchHitPageNo; + yStart = searchHitRectCanvas.y; + yEnd = yStart + searchHitRectCanvas.dy + 24; /* TODO: 24 to account for the find ui bar */ + + xStart = searchHitRectCanvas.x; + xEnd = xStart + searchHitRectCanvas.dx; + + //DBG_OUT("DisplayModelSplash::EnsureSearchHitVisible(), (yStart=%d, yEnd=%d)\n", yStart, yEnd); + + // TODO: this logic is flawed + yNewPos = (int)areaOffset.y; + + if (yStart < (int)areaOffset.y) { + yNewPos -= ((int)areaOffset.y - yStart); + needScroll = TRUE; + } + if (yEnd > (int)(areaOffset.y + drawAreaSize.dy())) { + yNewPos -= ((int)(areaOffset.y + drawAreaSize.dy()) - yEnd); + needScroll = TRUE; + } + + xNewPos = (int)areaOffset.x; + if (xStart < (int)areaOffset.x) { + xNewPos -= ((int)areaOffset.x - xStart); + needScroll = TRUE; + } + if (xEnd > (int)(areaOffset.x + drawAreaSize.dx())) { + xNewPos -= ((int)(areaOffset.x + drawAreaSize.dx()) - xEnd); + needScroll = TRUE; + } + + PdfPageInfo *pageInfo = getPageInfo(pageNo); + bool pageRendered = BitmapCache_Exists(this, pageNo, _zoomReal, _rotation); + if (!pageInfo->visible || needScroll || !pageRendered) + goToPage(pageNo, yNewPos, xNewPos); +} + +/* Recalcualte 'linkCount' and 'links' out of 'pagesInfo' data. + Should only be called if link data has chagned in 'pagesInfo'. */ +void DisplayModelSplash::RecalcLinks(void) +{ + int pageNo; + int i; + PdfPageInfo * pageInfo; + Link * popplerLink; + PdfLink * currPdfLink; + int currPdfLinkNo; + double xs, ys, xe, ye; + + DBG_OUT("DisplayModelSplash::RecalcLinks()\n"); + + free((void*)_links); + _links = NULL; + _linkCount = 0; + + /* calculate number of links */ + for (pageNo = 1; pageNo <= pageCount(); ++pageNo) { + pageInfo = getPageInfo(pageNo); + if (!pageInfo->links) + continue; + _linkCount += pageInfo->links->getNumLinks(); + } + + assert(_linkCount > 0); + _links = (PdfLink*)malloc(_linkCount * sizeof(PdfLink)); + if (!_links) + return; + + /* build links info */ + currPdfLinkNo = 0; + for (pageNo = 1; pageNo <= pageCount(); ++pageNo) { + pageInfo = getPageInfo(pageNo); + if (!pageInfo->links) + continue; + for (i = 0; i < pageInfo->links->getNumLinks(); i++) { + currPdfLink = link(currPdfLinkNo); + popplerLink = pageInfo->links->getLink(i); + popplerLink->getRect(&xs, &ys, &xe, &ye); + /* note: different param order than getRect() is intentional */ + RectD_FromXY(&currPdfLink->rectPage, xs, xe, ys, ye); + assert(currPdfLink->rectPage.dx >= 0); + assert(currPdfLink->rectPage.dy >= 0); + currPdfLink->pageNo = pageNo; + currPdfLink->link = popplerLink; + ++currPdfLinkNo; + } + } + assert(_linkCount == currPdfLinkNo); + recalcLinksCanvasPos(); + DBG_OUT("DisplayModelSplash::RecalcLinks() new link count: %d\n", _linkCount); +} + +void DisplayModelSplash::GoToDest(LinkDest *linkDest) +{ + Ref pageRef; + int newPage = INVALID_PAGE_NO; + int left, top; + int scrollY = 0; + + assert(linkDest); + if (!linkDest) return; + + if (linkDest->isPageRef()) { + pageRef = linkDest->getPageRef(); + newPage = pdfDoc->findPage(pageRef.num, pageRef.gen); + } else { + newPage = linkDest->getPageNum(); + } + + if (newPage <= 0 || newPage > pdfDoc->getNumPages()) { + newPage = 1; + } + + left = (int)linkDest->getLeft(); + top = (int)linkDest->getTop(); + /* TODO: convert left/top coordinates to window space */ + + /* TODO: this logic needs to be implemented */ + switch (linkDest->getKind()) { + case destXYZ: + break; + case destFitR: + break; + default: + break; + } + goToPage( newPage, scrollY); +} + +void DisplayModelSplash::GoToNamedDest(UGooString *dest) +{ + LinkDest *d; + + assert(dest); + if (!dest) return; + + d = pdfDoc->findDest(dest); + assert(d); + if (!d) return; + GoToDest(d); + delete d; +} + +void DisplayModelSplash::handleLinkGoTo(LinkGoTo *linkGoTo) +{ + LinkDest * linkDest; + UGooString * linkNamedDest; + + assert(linkGoTo); + if (!linkGoTo) return; + + linkDest = linkGoTo->getDest(); + linkNamedDest = linkGoTo->getNamedDest(); + if (linkDest) { + assert(!linkNamedDest); + GoToDest(linkDest); + } else { + assert(linkNamedDest); + GoToNamedDest(linkNamedDest); + } +} + +void DisplayModelSplash::handleLinkGoToR(LinkGoToR *linkGoToR) +{ + LinkDest * linkDest; + UGooString * linkNamedDest; + GooString * fileName; + + assert(linkGoToR); + if (!linkGoToR) return; + + linkDest = linkGoToR->getDest(); + linkNamedDest = linkGoToR->getNamedDest(); + + fileName = linkGoToR->getFileName(); + /* TODO: see if a file exists, if not show a dialog box. If exists, + load it and go to a destination in this file. + Should also search currently opened files. */ + /* Test file: C:\kjk\test_pdfs\pda\palm\dev tools\sdk\user_interface.pdf, page 633 */ +} + +void DisplayModelSplash::handleLinkURI(LinkURI *linkURI) +{ + const char *uri; + + uri = linkURI->getURI()->getCString(); + if (str_empty(uri)) + return; + LaunchBrowser(uri); +} + +void DisplayModelSplash::handleLinkLaunch(LinkLaunch* linkLaunch) +{ + assert(linkLaunch); + if (!linkLaunch) return; + + /* Launching means executing another application. It's not supported + due to security and portability reasons */ +} + +void DisplayModelSplash::handleLinkNamed(LinkNamed *linkNamed) +{ + GooString * name; + char * nameTxt; + + assert(linkNamed); + if (!linkNamed) return; + + name = linkNamed->getName(); + if (!name) + return; + nameTxt = name->getCString(); + if (str_eq(ACTION_NEXT_PAGE, nameTxt)) { + goToNextPage(0); + } else if (str_eq(ACTION_PREV_PAGE, nameTxt)) { + goToPrevPage(0); + } else if (str_eq(ACTION_LAST_PAGE, nameTxt)) { + goToLastPage(); + } else if (str_eq(ACTION_FIRST_PAGE, nameTxt)) { + goToFirstPage(); + } else { + /* not supporting: "GoBack", "GoForward", "Quit" */ + } +} + +/* Return TRUE if can go to previous page (i.e. is not on the first page) */ +BOOL DisplayModelSplash::CanGoToPrevPage(void) +{ + if (1 == currentPageNo()) + return FALSE; + return TRUE; +} + +/* Return TRUE if can go to next page (i.e. doesn't already show last page) */ +BOOL DisplayModelSplash::CanGoToNextPage(void) +{ + if (displayModeFacing(displayMode())) { + if (currentPageNo()+1 >= pageCount()) + return FALSE; + } else { + if (pageCount() == currentPageNo()) + return FALSE; + } + return TRUE; +} + +void DisplayModelSplash::FindInit(int startPageNo) +{ + assert(validPageNo(startPageNo)); + searchState.searchState = eSsNone; + searchState.wrapped = FALSE; + searchState.startPage = startPageNo; +} + +BOOL DisplayModelSplash::FindNextBackward(void) +{ + GBool startAtTop, stopAtBottom; + GBool startAtLast, stopAtLast; + GBool caseSensitive, backward; + GBool found; + double xs, ys, xe, ye; + UGooString * strU; + TextPage * textPage; + int pageNo; + RectD hitRect; + + DBG_OUT("DisplayModelSplash::FindNextBackward()\n"); + + // previous search didn't find it, so there's no point looking again + if (eSsNotFound == searchState.searchState) + return FALSE; + + // search string was not entered + if (0 == searchState.str->getLength()) + return FALSE; + + // searching uses the same code as rendering and that code is not + // thread safe, so we have to cancel all background rendering + cancelRenderingForDisplayModel(this); + + showBusyCursor(); + + backward = gTrue; + caseSensitive = searchState.caseSensitive; + strU = searchState.strU; + + if (eSsNone == searchState.searchState) { + // starting a new search backward + searchState.currPage = searchState.startPage; + assert(FALSE == searchState.wrapped); + startAtLast = gFalse; + startAtTop = gFalse; + } else { + // continuing previous search backward or forward + startAtLast = gTrue; + startAtTop = gFalse; + } + stopAtBottom = gTrue; + stopAtLast = gFalse; + + if ((eSsFoundNext == searchState.searchState) + || (eSsFoundNextWrapped == searchState.searchState)) { + searchState.wrapped = FALSE; + } + + for (;;) { + pageNo = searchState.currPage; + textPage = GetTextPage(pageNo); + + DBG_OUT(" search backward for %s, case sensitive=%d, page=%d\n", searchState.str->getCString(), caseSensitive, pageNo); + found = textPage->findText(strU->unicode(), strU->getLength(), startAtTop, stopAtBottom, + startAtLast, stopAtLast, caseSensitive, backward, + &xs, &ys, &xe, &ye); + + if (found) { + DBG_OUT(" found '%s' on page %d at pos (%.2f, %.2f)-(%.2f,%.2f)\n", + searchState.str->getCString(), pageNo, xs, ys, xe, ye); + + TransfromUpsideDown(this, pageNo, &ys, &ye); + RectD_FromXY(&hitRect, xs, xe, ys, ye); + if (searchState.wrapped) { + searchState.wrapped = FALSE; + searchState.searchState = eSsFoundPrevWrapped; + } else { + searchState.searchState = eSsFoundPrev; + } + setSearchHit(pageNo, &hitRect); + EnsureSearchHitVisible(); + goto Exit; + } + + if (1 == pageNo) { + DBG_OUT(" wrapped\n"); + searchState.wrapped = TRUE; + searchState.currPage = pageCount(); + } else + searchState.currPage = pageNo - 1; + + // moved to another page, so starting from the top + startAtTop = gTrue; + startAtLast = gFalse; + + if (searchState.wrapped && + (searchState.currPage == searchState.startPage) && + (eSsNone == searchState.searchState) ) { + searchState.searchState = eSsNotFound; + clearSearchHit(); + goto Exit; + } + } +Exit: + showNormalCursor(); + return found; +} + +BOOL DisplayModelSplash::FindNextForward(void) +{ + GBool startAtTop, stopAtBottom; + GBool startAtLast, stopAtLast; + GBool caseSensitive, backward; + GBool found; + double xs, ys, xe, ye; + UGooString * strU; + TextPage * textPage; + int pageNo; + RectD hitRect; + + DBG_OUT("DisplayModelSplash::FindNextForward()\n"); + + // previous search didn't find it, so there's no point looking again + if (eSsNotFound == searchState.searchState) + return FALSE; + + // search string was not entered + if (0 == searchState.str->getLength()) + return FALSE; + + // searching uses the same code as rendering and that code is not + // thread safe, so we have to cancel all background rendering + cancelRenderingForDisplayModel(this); + + backward = gFalse; + caseSensitive =searchState.caseSensitive; + strU = searchState.strU; + if (eSsNone == searchState.searchState) { + // starting a new search forward + DBG_OUT(" new search\n"); + searchState.currPage = searchState.startPage; + assert(FALSE == searchState.wrapped); + startAtLast = gFalse; + startAtTop = gTrue; + } else { + // continuing previous search forward or backward + DBG_OUT(" continue search\n"); + startAtLast = gTrue; + startAtTop = gFalse; + } + stopAtBottom = gTrue; + stopAtLast = gFalse; + + if ((eSsFoundPrev == searchState.searchState) + || (eSsFoundPrevWrapped == searchState.searchState)) { + searchState.wrapped = FALSE; + } + + for (;;) { + pageNo = searchState.currPage; + textPage = GetTextPage(pageNo); + DBG_OUT(" search forward for '%s', case sensitive=%d, page=%d\n", searchState.str->getCString(), caseSensitive, pageNo); + found = textPage->findText(strU->unicode(), strU->getLength(), startAtTop, stopAtBottom, + startAtLast, stopAtLast, caseSensitive, backward, + &xs, &ys, &xe, &ye); + + if (found) { + DBG_OUT(" found '%s' on page %d at pos (%.2f, %.2f)-(%.2f,%.2f)\n", + searchState.str->getCString(), pageNo, xs, ys, xe, ye); + + TransfromUpsideDown(this, pageNo, &ys, &ye); + RectD_FromXY(&hitRect, xs, xe, ys, ye); + if (searchState.wrapped) { + searchState.wrapped = FALSE; + searchState.searchState = eSsFoundNextWrapped; + } else { + searchState.searchState = eSsFoundNext; + } + setSearchHit(pageNo, &hitRect); + EnsureSearchHitVisible(); + goto Exit; + } + + if (pageCount() == pageNo) { + DBG_OUT(" wrapped\n"); + searchState.wrapped = TRUE; + searchState.currPage = 1; + } else + searchState.currPage = pageNo + 1; + + startAtTop = gTrue; + startAtLast = gFalse; + + if (searchState.wrapped && + (searchState.currPage == searchState.startPage) && + (eSsNone == searchState.searchState) ) { + searchState.searchState = eSsNotFound; + clearSearchHit(); + goto Exit; + } + } +Exit: + showNormalCursor(); + return found; +} + +void DisplayModelSplash::handleLink(PdfLink *pdfLink) +{ + Link * link; + LinkAction * action; + LinkActionKind actionKind; + + assert(pdfLink); + if (!pdfLink) return; + + link = pdfLink->link; + assert(link); + if (!link) return; + + action = link->getAction(); + actionKind = action->getKind(); + + switch (actionKind) { + case actionGoTo: + handleLinkGoTo((LinkGoTo*)action); + break; + case actionGoToR: + handleLinkGoToR((LinkGoToR*)action); + break; + case actionLaunch: + handleLinkLaunch((LinkLaunch*)action); + break; + case actionURI: + handleLinkURI((LinkURI*)action); + break; + case actionNamed: + handleLinkNamed((LinkNamed *)action); + break; + default: + /* other kinds are not supported */ + break; + } +} + + diff --git a/rosapps/smartpdf/src/DisplayModelSplash.h b/rosapps/smartpdf/src/DisplayModelSplash.h new file mode 100644 index 00000000000..93986ea9f7b --- /dev/null +++ b/rosapps/smartpdf/src/DisplayModelSplash.h @@ -0,0 +1,115 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef _DISPLAY_MODEL_SPLASH_H_ +#define _DISPLAY_MODEL_SPLASH_H_ +/* How to think of display logic: physical screen of size + drawAreaSize is a window into (possibly much larger) + total area (canvas) of size canvasSize. + + In DM_SINGLE_PAGE mode total area is the size of currently displayed page + given current zoomLovel and rotation. + In DM_CONTINUOUS mode total area consist of all pages rendered sequentially + with a given zoomLevel and rotation. totalAreaDy is the sum of heights + of all pages plus spaces between them and totalAreaDx is the size of + the widest page. + + A possible configuration could look like this: + + ----------------------------------- + | | + | ------------- | + | | screen | | + | | i.e. | | + | | drawArea | | + | ------------- | + | | + | | + | canvas | + | | + | | + | | + | | + ----------------------------------- + + We calculate the total area size and position of each page we display on the + canvas. Canvas has to be >= draw area. + + Changing zoomLevel or rotation requires recalculation of total area and + position of pdf pages in it. + + We keep the offset of draw area relative to total area. The offset changes + due to scrolling (with keys or using scrollbars). + + To draw we calculate which part of each page overlaps draw area, we render + those pages to a bitmap and display those bitmaps. +*/ + +#include "DisplayState.h" +#include "DisplayModel.h" + +class GooString; +class Link; +class LinkDest; +class LinkGoTo; +class LinkGoToR; +class LinkLaunch; +class LinkNamed; +class LinkURI; +class Links; +class PDFDoc; +class SplashBitmap; +class TextOutputDev; +class TextPage; +class UGooString; + +/* Information needed to drive the display of a given PDF document on a screen. + You can think of it as a model in the MVC pardigm. + All the display changes should be done through changing this model via + API and re-displaying things based on new display information */ +class DisplayModelSplash : public DisplayModel +{ +public: + DisplayModelSplash(DisplayMode displayMode); + virtual ~DisplayModelSplash(); + + PdfEnginePoppler * pdfEnginePoppler() { return (PdfEnginePoppler*)pdfEngine(); } + + virtual void handleLink(PdfLink *pdfLink); + + TextPage * GetTextPage(int pageNo); + + void EnsureSearchHitVisible(); + + void handleLinkGoTo(LinkGoTo *linkGoTo); + void handleLinkGoToR(LinkGoToR *linkGoToR); + void handleLinkURI(LinkURI *linkURI); + void handleLinkLaunch(LinkLaunch* linkLaunch); + void handleLinkNamed(LinkNamed *linkNamed); + BOOL CanGoToNextPage(); + BOOL CanGoToPrevPage(); + + void FindInit(int startPageNo); + BOOL FindNextForward(); + BOOL FindNextBackward(); + + + void FreeTextPages(void); + void RecalcLinks(void); + void GoToDest(LinkDest *linkDest); + void GoToNamedDest(UGooString *dest); + void FreeLinks(void); + + virtual int getTextInRegion(int pageNo, RectD *region, unsigned short *buf, int buflen); + virtual void cvtUserToScreen(int pageNo, double *x, double *y); + virtual void cvtScreenToUser(int *pageNo, double *x, double *y); + +public: + PDFDoc * pdfDoc; +}; + +DisplayModelSplash *DisplayModelSplash_CreateFromFileName(const char *fileName, + SizeD totalDrawAreaSize, + int scrollbarXDy, int scrollbarYDx, + DisplayMode displayMode, int startPage, + WindowInfo *win); +#endif diff --git a/rosapps/smartpdf/src/DisplayState.cc b/rosapps/smartpdf/src/DisplayState.cc new file mode 100644 index 00000000000..0983a3ccf2b --- /dev/null +++ b/rosapps/smartpdf/src/DisplayState.cc @@ -0,0 +1,114 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "DisplayState.h" +#include "str_util.h" +#include "dstring.h" + +#include +#include +#include + +void normalizeRotation(int *rotation) +{ + assert(rotation); + if (!rotation) return; + while (*rotation < 0) + *rotation += 360; + while (*rotation >= 360) + *rotation -= 360; +} + +BOOL validRotation(int rotation) +{ + normalizeRotation(&rotation); + if ((0 == rotation) || (90 == rotation) || + (180 == rotation) || (270 == rotation)) + return TRUE; + return FALSE; +} + +BOOL ValidZoomVirtual(double zoomVirtual) +{ + if ((ZOOM_FIT_PAGE == zoomVirtual) || (ZOOM_FIT_WIDTH == zoomVirtual)) + return TRUE; + if ((zoomVirtual < ZOOM_MIN) || (zoomVirtual > ZOOM_MAX)) { + DBG_OUT("ValidZoomVirtual() invalid zoom: %.4f\n", zoomVirtual); + return FALSE; + } + return TRUE; +} + +#define STR_FROM_ENUM(val) \ + if (val == var) \ + return val##_STR; + +const char *DisplayModeNameFromEnum(DisplayMode var) +{ + STR_FROM_ENUM(DM_SINGLE_PAGE) + STR_FROM_ENUM(DM_FACING) + STR_FROM_ENUM(DM_CONTINUOUS) + STR_FROM_ENUM(DM_CONTINUOUS_FACING) + return NULL; +} + +#define IS_STR_ENUM(enumName) \ + if (str_eq(txt, enumName##_STR)) { \ + *resOut = enumName; \ + return TRUE; \ + } + +BOOL DisplayModeEnumFromName(const char *txt, DisplayMode *resOut) +{ + IS_STR_ENUM(DM_SINGLE_PAGE) + IS_STR_ENUM(DM_FACING) + IS_STR_ENUM(DM_CONTINUOUS) + IS_STR_ENUM(DM_CONTINUOUS_FACING) + assert(0); + return FALSE; +} + +void DisplayState_Init(DisplayState *ds) +{ + memzero(ds, sizeof(DisplayState)); + ds->displayMode = DM_SINGLE_PAGE; + ds->visible = FALSE; + ds->fullScreen = FALSE; + ds->pageNo = 1; + ds->zoomVirtual = 100.0; + ds->rotation = 0; +} + +void DisplayState_Free(DisplayState *ds) +{ + free((void*)ds->filePath); + DisplayState_Init(ds); +} + +BOOL DisplayState_Serialize(DisplayState *ds, DString *strOut) +{ + const char * displayModeName = NULL; + + DStringSprintf(strOut, " %s: %s\n", FILE_STR, ds->filePath); + + displayModeName = DisplayModeNameFromEnum(ds->displayMode); + if (displayModeName) + DStringSprintf(strOut, " %s: %s\n", DISPLAY_MODE_STR, displayModeName); + else + DStringSprintf(strOut, " %s: %s\n", DISPLAY_MODE_STR, DisplayModeNameFromEnum(DM_SINGLE_PAGE)); + + DStringSprintf(strOut, " %s: %d\n", VISIBLE_STR, ds->visible); + DStringSprintf(strOut, " %s: %d\n", PAGE_NO_STR, ds->pageNo); + DStringSprintf(strOut, " %s: %.4f\n", ZOOM_VIRTUAL_STR, ds->zoomVirtual); + DStringSprintf(strOut, " %s: %d\n", ROTATION_STR, ds->rotation); + DStringSprintf(strOut, " %s: %d\n", FULLSCREEN_STR, (int)ds->fullScreen); + + DStringSprintf(strOut, " %s: %d\n", SCROLL_X_STR, ds->scrollX); + DStringSprintf(strOut, " %s: %d\n", SCROLL_Y_STR, ds->scrollY); + + DStringSprintf(strOut, " %s: %d\n", WINDOW_X_STR, ds->windowX); + DStringSprintf(strOut, " %s: %d\n", WINDOW_Y_STR, ds->windowY); + DStringSprintf(strOut, " %s: %d\n", WINDOW_DX_STR, ds->windowDx); + DStringSprintf(strOut, " %s: %d\n", WINDOW_DY_STR, ds->windowDy); + return TRUE; +} + diff --git a/rosapps/smartpdf/src/DisplayState.h b/rosapps/smartpdf/src/DisplayState.h new file mode 100644 index 00000000000..62568a0c789 --- /dev/null +++ b/rosapps/smartpdf/src/DisplayState.h @@ -0,0 +1,77 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef DISPLAY_STATE_H_ +#define DISPLAY_STATE_H_ + +#include "base_util.h" +#include "dstring.h" + +enum DisplayMode { + DM_FIRST = 1, + DM_SINGLE_PAGE = DM_FIRST, + DM_FACING, + DM_CONTINUOUS, + DM_CONTINUOUS_FACING, + DM_LAST = DM_CONTINUOUS_FACING +}; + +#define ZOOM_FIT_PAGE -1 +#define ZOOM_FIT_WIDTH -2 +#define ZOOM_MAX 6401.0 /* max zoom in % */ +#define ZOOM_MIN 8.0 /* min zoom in % */ + +#define DM_SINGLE_PAGE_STR "single page" +#define DM_FACING_STR "facing" +#define DM_CONTINUOUS_STR "continuous" +#define DM_CONTINUOUS_FACING_STR "continuous facing" + +#define FILE_HISTORY_STR "File History" + +#define FILE_STR "File" +#define DISPLAY_MODE_STR "Display Mode" +#define VISIBLE_STR "Visible" +#define PAGE_NO_STR "Page" +#define ZOOM_VIRTUAL_STR "ZoomVirtual" +#define ROTATION_STR "Rotation" +#define FULLSCREEN_STR "Fullscreen" +#define SCROLL_X_STR "Scroll X" +#define SCROLL_Y_STR "Scroll Y" +#define WINDOW_X_STR "Window X" +#define WINDOW_Y_STR "Window Y" +#define WINDOW_DX_STR "Window DX" +#define WINDOW_DY_STR "Window DY" +#define SHOW_TOOLBAR_STR "ShowToolbar" +#define USE_FITZ_STR "UseFitz" +#define PDF_ASSOCIATE_DONT_ASK_STR "PdfAssociateDontAskAgain" +#define PDF_ASSOCIATE_ASSOCIATE_STR "PdfAssociateShouldAssociate" +#define UI_LANGUAGE_STR "UILanguage" + +typedef struct DisplayState { + const char * filePath; + enum DisplayMode displayMode; + BOOL visible; /* if TRUE, currently shown on the screen */ + int scrollX; + int scrollY; + int pageNo; + double zoomVirtual; + int rotation; + BOOL fullScreen; + int windowX; + int windowY; + int windowDx; + int windowDy; +} DisplayState; + +void normalizeRotation(int *rotation); +BOOL validRotation(int rotation); +BOOL ValidZoomVirtual(double zoomVirtual); + +const char * DisplayModeNameFromEnum(DisplayMode var); +BOOL DisplayModeEnumFromName(const char *txt, DisplayMode *resOut); + +void DisplayState_Init(DisplayState *ds); +void DisplayState_Free(DisplayState *ds); +BOOL DisplayState_Serialize(DisplayState *ds, DString *strOut); + +#endif + diff --git a/rosapps/smartpdf/src/FileHistory.cc b/rosapps/smartpdf/src/FileHistory.cc new file mode 100644 index 00000000000..3703ee21df5 --- /dev/null +++ b/rosapps/smartpdf/src/FileHistory.cc @@ -0,0 +1,210 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "FileHistory.h" +#include "str_util.h" + +#include +#include +#include +#include + +/* Handling of file history list. + + We keep an infinite list of all (still existing in the file system) PDF + files that a user has ever opened. For each file we also keep a bunch of + attributes describing the display state at the time the file was closed. + + We persist this list as serialized text inside preferences file. + Serialized history list looks like this: + +File History: + DisplayMode: single page + File: /home/test.pdf + PageNo: 5 + ZoomLevel: 123.3434 + FullScreen: 1 + LastAccessTimeInSecsSinceEpoch: 12341234124314 + +File History: + +etc... + + We deserialize this info at startup and serialize when the application + quits. +*/ + +FileHistoryList *FileHistoryList_Node_Create(void) +{ + FileHistoryList *node; + node = (FileHistoryList*)malloc(sizeof(FileHistoryList)); + if (!node) + return NULL; + + memzero(node, sizeof(node)); + DisplayState_Init(&(node->state)); + node->menuId = INVALID_MENU_ID; + return node; +} + +FileHistoryList *FileHistoryList_Node_CreateFromFilePath(const char *filePath) +{ + FileHistoryList *node; + + DBG_OUT("FileHistoryList_Node_CreateFromFilePath() file='%s'\n", filePath); + node = FileHistoryList_Node_Create(); + if (!node) + return NULL; + + node->state.filePath = (const char*)str_dup(filePath); + if (!node->state.filePath) + goto Error; + return node; + +Error: + FileHistoryList_Node_Free(node); + return NULL; +} + +void FileHistoryList_Node_Free(FileHistoryList *node) +{ + assert(node); + if (!node) return; + DisplayState_Free(&(node->state)); + free((void*)node); +} + +void FileHistoryList_Free(FileHistoryList **root) +{ + FileHistoryList *curr, *next; + assert(root); + if (!root) return; + + curr = *root; + while (curr) { + next = curr->next; + FileHistoryList_Node_Free(curr); + curr = next; + } + + *root = NULL; +} + +static BOOL FileHistoryList_Node_Serialize(FileHistoryList *node, DString *strOut) +{ + assert(node); + if (!node) return FALSE; + assert(strOut); + if (!strOut) return FALSE; + + DStringSprintf(strOut, "%s:\n", FILE_HISTORY_STR); + DisplayState_Serialize(&(node->state), strOut); + + return TRUE; +} + +bool FileHistoryList_Serialize(FileHistoryList **root, DString *strOut) +{ + assert(root); + if (!root) return false; + + FileHistoryList *curr = *root; + while (curr) { + int fOk = FileHistoryList_Node_Serialize(curr, strOut); + if (!fOk) + return false; + curr = curr->next; + } + return true; +} + +void FileHistoryList_Node_InsertHead(FileHistoryList **root, FileHistoryList *node) +{ + assert(root); + if (!root) return; + node->next = *root; + *root = node; +} + +void FileHistoryList_Node_Append(FileHistoryList **root, FileHistoryList *node) +{ + FileHistoryList *curr; + assert(root); + if (!root) return; + assert(node); + if (!node) return; + assert(!node->next); + curr = *root; + if (!curr) { + *root = node; + return; + } + while (curr->next) + curr = curr->next; + curr->next = node; +} + +FileHistoryList *FileHistoryList_Node_FindByFilePath(FileHistoryList **root, const char *filePath) +{ + FileHistoryList *curr; + + assert(root); + if (!root) return NULL; + assert(filePath); + if (!filePath) return NULL; + + curr = *root; + while (curr) { + assert(curr->state.filePath); + if (str_eq(filePath, curr->state.filePath)) + return curr; + curr = curr->next; + } + + return NULL; +} + +BOOL FileHistoryList_Node_RemoveByFilePath(FileHistoryList **root, const char *filePath) +{ + FileHistoryList *node; + + assert(root); + if (!root) return FALSE; + assert(filePath); + if (!filePath) return FALSE; + + /* TODO: traversing the list twice, but it's small so we don't care */ + node = FileHistoryList_Node_FindByFilePath(root, filePath); + if (!node) + return FALSE; + + return FileHistoryList_Node_RemoveAndFree(root, node); +} + +BOOL FileHistoryList_Node_RemoveAndFree(FileHistoryList **root, FileHistoryList *node) +{ + FileHistoryList **prev; + + assert(root); + if (!root) return FALSE; + + if (node == *root) { + *root = node->next; + goto Free; + } + + prev = root; + while (*prev) { + if ((*prev)->next == node) { + (*prev)->next = node->next; + goto Free; + } + prev = &((*prev)->next); + } + + /* TODO: should I free it anyway? */ + return FALSE; +Free: + FileHistoryList_Node_Free(node); + return TRUE; +} + diff --git a/rosapps/smartpdf/src/FileHistory.h b/rosapps/smartpdf/src/FileHistory.h new file mode 100644 index 00000000000..4c398bacb34 --- /dev/null +++ b/rosapps/smartpdf/src/FileHistory.h @@ -0,0 +1,33 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef FILE_HISTORY_H_ +#define FILE_HISTORY_H_ + +#include "DisplayState.h" +#include "dstring.h" + +#define INVALID_MENU_ID (unsigned int)-1 + +typedef struct FileHistoryList { + struct FileHistoryList *next; + unsigned int menuId; + DisplayState state; +} FileHistoryList; + +FileHistoryList * FileHistoryList_Node_Create(void); +FileHistoryList * FileHistoryList_Node_CreateFromFilePath(const char *filePath); + +void FileHistoryList_Node_Free(FileHistoryList *node); +void FileHistoryList_Free(FileHistoryList **root); + +void FileHistoryList_Node_InsertHead(FileHistoryList **root, FileHistoryList *node); +void FileHistoryList_Node_Append(FileHistoryList **root, FileHistoryList *node); + +FileHistoryList * FileHistoryList_Node_FindByFilePath(FileHistoryList **root, const char *filePath); +BOOL FileHistoryList_Node_RemoveAndFree(FileHistoryList **root, FileHistoryList *node); + +BOOL FileHistoryList_Node_RemoveByFilePath(FileHistoryList **root, const char *filePath); + +bool FileHistoryList_Serialize(FileHistoryList **root, DString *strOut); + +#endif diff --git a/rosapps/smartpdf/src/Kopie von SumatraPDF.cpp b/rosapps/smartpdf/src/Kopie von SumatraPDF.cpp new file mode 100644 index 00000000000..67e1f2d9764 --- /dev/null +++ b/rosapps/smartpdf/src/Kopie von SumatraPDF.cpp @@ -0,0 +1,5103 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ + +// have to undef _WIN32_IE here to use TB_* constants +// (_WIN32_IE was defined in *.cbp - codeblocks project file) +// ==> we have to use a stable API instead of MinGW 5.1.3 :-\ + +#ifdef __GNUC__ +#undef _WIN32_IE +#endif + +#include "SumatraPDF.h" + +#include "str_util.h" +#include "file_util.h" +#include "geom_util.h" +#include "win_util.h" +#include "translations.h" + +#include "SumatraDialogs.h" +#include "FileHistory.h" +#include "AppPrefs.h" +#include "DisplayModelSplash.h" + +/* TODO: this and StandardSecurityHandler::getAuthData() and new GlobalParams + should be moved to another file (PopplerInit(), PopplerDeinit() */ +#include "PDFDoc.h" +#include "SecurityHandler.h" +#include "GlobalParams.h" + +#include +#include +#include +#include +#include /* for _mkdir() */ + +#include +#include + +#include "str_strsafe.h" + +#include + +// some stupid things are in headers of MinGW 5.1.3 :-\ +// why we have to define these constants & prototypes again (?!) +#ifdef __GNUC__ +#ifndef VK_OEM_PLUS +#define VK_OEM_PLUS 0xBB +#endif +#ifndef VK_OEM_MINUS +#define VK_OEM_MINUS 0xBD +#endif + +extern "C" { +extern BOOL WINAPI GetDefaultPrinterA(LPSTR,LPDWORD); +extern BOOL WINAPI GetDefaultPrinterW(LPWSTR,LPDWORD); +} +#endif + +// this sucks but I don't know any other way +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") + +//#define FANCY_UI 1 + +/* Define if you want to conserve memory by always freeing cached bitmaps + for pages not visible. Only enable for stress-testing the logic. On + desktop machine we usually have plenty memory */ +//#define CONSERVE_MEMORY 1 + +/* Next action for the benchmark mode */ +#define MSG_BENCH_NEXT_ACTION WM_USER + 1 + +#define ZOOM_IN_FACTOR 1.2 +#define ZOOM_OUT_FACTOR 1.0 / ZOOM_IN_FACTOR + +/* if TRUE, we're in debug mode where we show links as blue rectangle on + the screen. Makes debugging code related to links easier. + TODO: make a menu item in DEBUG build to turn it on/off. */ +#ifdef DEBUG +static BOOL gDebugShowLinks = TRUE; +#else +static BOOL gDebugShowLinks = FALSE; +#endif + +/* default UI settings */ +#define DEFAULT_DISPLAY_MODE DM_CONTINUOUS + +//#define DEFAULT_ZOOM ZOOM_FIT_WIDTH +#define DEFAULT_ZOOM ZOOM_FIT_PAGE +#define DEFAULT_ROTATION 0 + +//#define START_WITH_ABOUT 1 + +/* define if want to use double-buffering for rendering the PDF. Takes more memory!. */ +#define DOUBLE_BUFFER 1 + +#define DRAGQUERY_NUMFILES 0xFFFFFFFF + +#define MAX_LOADSTRING 100 + +#define WM_CREATE_FAILED -1 +#define WM_CREATE_OK 0 +#define WM_NCPAINT_HANDLED 0 +#define WM_VSCROLL_HANDLED 0 +#define WM_HSCROLL_HANDLED 0 + +#define ABOUT_WIN_DX 440 +#define ABOUT_WIN_DY 300 + +#define WM_APP_REPAINT_DELAYED (WM_APP + 10) +#define WM_APP_REPAINT_NOW (WM_APP + 11) + +/* A caption is 4 white/blue 2 pixel line and a 3 pixel white line */ +#define CAPTION_DY 2*(2*4)+3 + +#define COL_CAPTION_BLUE RGB(0,0x50,0xa0) +#define COL_WHITE RGB(0xff,0xff,0xff) +#define COL_BLACK RGB(0,0,0) +#define COL_WINDOW_BG RGB(0xcc, 0xcc, 0xcc) +#define COL_WINDOW_SHADOW RGB(0x40, 0x40, 0x40) + +#define FRAME_CLASS_NAME _T("SUMATRA_PDF_FRAME") +#define CANVAS_CLASS_NAME _T("SUMATRA_PDF_CANVAS") +#define ABOUT_CLASS_NAME _T("SUMATRA_PDF_ABOUT") +#define APP_NAME _T("SumatraPDF") +#define PDF_DOC_NAME _T("Adobe PDF Document") +#define ABOUT_WIN_TITLE _TR("About SumatraPDF") +#define PREFS_FILE_NAME _T("sumatrapdfprefs.txt") +#define APP_SUB_DIR _T("SumatraPDF") + +#define BENCH_ARG_TXT "-bench" +#define PRINT_TO_ARG_TXT "-print-to" +#define NO_REGISTER_EXT_ARG_TXT "-no-register-ext" +#define PRINT_TO_DEFAULT_ARG_TXT "-print-to-default" +#define EXIT_ON_PRINT_ARG_TXT "-exit-on-print" +#define ENUM_PRINTERS_ARG_TXT "-enum-printers" + +/* Default size for the window, happens to be american A4 size (I think) */ +#define DEF_WIN_DX 612 +#define DEF_WIN_DY 792 + +#define REPAINT_TIMER_ID 1 +#define REPAINT_DELAY_IN_MS 400 + +/* A special "pointer" vlaue indicating that we tried to render this bitmap + but couldn't (e.g. due to lack of memory) */ +#define BITMAP_CANNOT_RENDER (RenderedBitmap*)NULL + +#define WS_REBAR (WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | RBS_VARHEIGHT | \ + RBS_BANDBORDERS | CCS_NODIVIDER | CCS_NOPARENTALIGN) + +#define MAX_RECENT_FILES_IN_MENU 15 + +typedef struct StrList { + struct StrList * next; + char * str; +} StrList; + +static FileHistoryList * gFileHistoryRoot = NULL; + +static HINSTANCE ghinst = NULL; +TCHAR windowTitle[MAX_LOADSTRING]; + +static WindowInfo* gWindowList; + +static HCURSOR gCursorArrow; +static HCURSOR gCursorHand; +static HCURSOR gCursorDrag; +static HBRUSH gBrushBg; +static HBRUSH gBrushWhite; +static HBRUSH gBrushShadow; +static HBRUSH gBrushLinkDebug; + +static HPEN ghpenWhite; +static HPEN ghpenBlue; + +#ifdef _WINDLL +static bool gRunningDLL = true; +#else +static bool gRunningDLL = false; +#endif +//static AppVisualStyle gVisualStyle = VS_WINDOWS; + +static char * gBenchFileName; +static int gBenchPageNum = INVALID_PAGE_NO; +BOOL gShowToolbar = TRUE; +BOOL gUseFitz = TRUE; +/* If false, we won't ask the user if he wants Sumatra to handle PDF files */ +BOOL gPdfAssociateDontAskAgain = FALSE; +/* If gPdfAssociateDontAskAgain is TRUE, says whether we should silently associate + or not */ +BOOL gPdfAssociateShouldAssociate = TRUE; +#ifdef DOUBLE_BUFFER +static bool gUseDoubleBuffer = true; +#else +static bool gUseDoubleBuffer = false; +#endif + +#define MAX_PAGE_REQUESTS 8 +static PageRenderRequest gPageRenderRequests[MAX_PAGE_REQUESTS]; +static int gPageRenderRequestsCount = 0; + +static HANDLE gPageRenderThreadHandle; +static HANDLE gPageRenderSem; +static PageRenderRequest * gCurPageRenderReq; + +static int gReBarDy; +static int gReBarDyFrame; +static HWND gHwndAbout; + +typedef struct ToolbarButtonInfo { + /* information provided at compile time */ + int bitmapResourceId; + int cmdId; + TCHAR * toolTip; + + /* information calculated at runtime */ + int index; +} ToolbarButtonInfo; + +#define IDB_SEPARATOR -1 + +ToolbarButtonInfo gToolbarButtons[] = { + { IDB_SILK_OPEN, IDM_OPEN, _TRN(TEXT("Open")), 0 }, + { IDB_SEPARATOR, IDB_SEPARATOR, 0, 0 }, + { IDB_SILK_PREV, IDM_GOTO_PREV_PAGE, _TRN(TEXT("Previous Page")), 0 }, + { IDB_SILK_NEXT, IDM_GOTO_NEXT_PAGE, _TRN(TEXT("Next Page")), 0 }, + { IDB_SEPARATOR, IDB_SEPARATOR, 0, 0 }, + { IDB_SILK_ZOOM_IN, IDT_VIEW_ZOOMIN, _TRN(TEXT("Zoom In")), 0 }, + { IDB_SILK_ZOOM_OUT, IDT_VIEW_ZOOMOUT, _TRN(TEXT("Zoom Out")), 0 } +}; /* @author: Klemens Friedl; TEXT() casts */ + +#define DEFAULT_LANGUAGE "en" + +#define TOOLBAR_BUTTONS_COUNT dimof(gToolbarButtons) + +static const char *g_currLangName; + +struct LangDef { + const char* _langName; + int _langId; +} g_langs[] = { + {"en", IDM_LANG_EN}, + {"pl", IDM_LANG_PL}, + {"fr", IDM_LANG_FR}, + {"de", IDM_LANG_DE}, +}; + +#define LANGS_COUNT dimof(g_langs) + +static void WindowInfo_ResizeToPage(WindowInfo *win, int pageNo); +static void CreateToolbar(WindowInfo *win, HINSTANCE hInst); +static void RebuildProgramMenus(void); + +const char* CurrLangNameGet() { + if (!g_currLangName) + return DEFAULT_LANGUAGE; + return g_currLangName; +} + +bool CurrLangNameSet(const char* langName) { + bool validLang = false; + for (int i=0; i < LANGS_COUNT; i++) { + if (str_eq(langName, g_langs[i]._langName)) { + validLang = true; + break; + } + } + assert(validLang); + if (!validLang) return false; + free((void*)g_currLangName); + g_currLangName = str_dup(langName); + + bool ok = Translations_SetCurrentLanguage(langName); + assert(ok); + + return true; +} + +void CurrLangNameFree() { + free((void*)g_currLangName); + g_currLangName = NULL; +} + +void LaunchBrowser(const TCHAR *url) +{ + launch_url(url); +} + +static BOOL pageRenderAbortCb(void *data) +{ + PageRenderRequest *req = (PageRenderRequest*)data; + if (req->abort) { + DBG_OUT("Rendering of page %d aborted\n", req->pageNo); + return TRUE; + } + else + return FALSE; +} + +void RenderQueue_RemoveForDisplayModel(DisplayModel *dm) { + LockCache(); + int reqCount = gPageRenderRequestsCount; + int curPos = 0; + for(int i = 0; i < reqCount; i++) { + PageRenderRequest *req = &(gPageRenderRequests[i]); + bool shouldRemove = (req->dm == dm); + if (i != curPos) + gPageRenderRequests[curPos] = gPageRenderRequests[i]; + if (shouldRemove) + --gPageRenderRequestsCount; + else + ++curPos; + } + UnlockCache(); +} + +/* Wait until rendering of a page beloging to has finished. */ +/* TODO: this might take some time, would be good to show a dialog to let the + user know he has to wait until we finish */ +void cancelRenderingForDisplayModel(DisplayModel *dm) { + + DBG_OUT("cancelRenderingForDisplayModel()\n"); + bool renderingFinished = false;; + for (;;) { + LockCache(); + if (!gCurPageRenderReq || (gCurPageRenderReq->dm != dm)) + renderingFinished = true; + else + gCurPageRenderReq->abort = TRUE; + UnlockCache(); + if (renderingFinished) + break; + /* TODO: busy loop is not good, but I don't have a better idea */ + sleep_milliseconds(500); + } +} + +/* Render a bitmap for page in . */ +void RenderQueue_Add(DisplayModel *dm, int pageNo) { + DBG_OUT("RenderQueue_Add(pageNo=%d)\n", pageNo); + assert(dm); + if (!dm) return; //goto Exit; /* @author: Klemens Friedl; because of crosses initialization of [...] */ + + LockCache(); + PdfPageInfo *pageInfo = dm->getPageInfo(pageNo); + int rotation = dm->rotation(); + normalizeRotation(&rotation); + double zoomLevel = dm->zoomReal(); + + if (BitmapCache_Exists(dm, pageNo, zoomLevel, rotation)) { + goto LeaveCsAndExit; + } + + if (gCurPageRenderReq && + (gCurPageRenderReq->pageNo == pageNo) && (gCurPageRenderReq->dm == dm)) { + if ((gCurPageRenderReq->zoomLevel != zoomLevel) || (gCurPageRenderReq->rotation != rotation)) { + /* Currently rendered page is for the same page but with different zoom + or rotation, so abort it */ + DBG_OUT(" aborting rendering\n"); + gCurPageRenderReq->abort = TRUE; + } else { + /* we're already rendering exactly the same page */ + DBG_OUT(" already rendering this page\n"); + goto LeaveCsAndExit; + } + } + + for (int i=0; i < gPageRenderRequestsCount; i++) { + PageRenderRequest* req = &(gPageRenderRequests[i]); + if ((req->pageNo == pageNo) && (req->dm == dm)) { + if ((req->zoomLevel == zoomLevel) && (req->rotation == rotation)) { + /* Request with exactly the same parameters already queued for + rendering. Move it to the top of the queue so that it'll + be rendered faster. */ + PageRenderRequest tmp; + tmp = gPageRenderRequests[gPageRenderRequestsCount-1]; + gPageRenderRequests[gPageRenderRequestsCount-1] = *req; + *req = tmp; + DBG_OUT(" already queued\n"); + goto LeaveCsAndExit; + } else { + /* There was a request queued for the same page but with different + zoom or rotation, so only replace this request */ + DBG_OUT("Replacing request for page %d with new request\n", req->pageNo); + req->zoomLevel = zoomLevel; + req->rotation = rotation; + goto LeaveCsAndExit; + + } + } + } + + PageRenderRequest* newRequest; + /* add request to the queue */ + if (gPageRenderRequestsCount == MAX_PAGE_REQUESTS) { + /* queue is full -> remove the oldest items on the queue */ + memmove(&(gPageRenderRequests[0]), &(gPageRenderRequests[1]), sizeof(PageRenderRequest)*(MAX_PAGE_REQUESTS-1)); + newRequest = &(gPageRenderRequests[MAX_PAGE_REQUESTS-1]); + } else { + newRequest = &(gPageRenderRequests[gPageRenderRequestsCount]); + gPageRenderRequestsCount++; + } + assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); + newRequest->dm = dm; + newRequest->pageNo = pageNo; + newRequest->zoomLevel = zoomLevel; + newRequest->rotation = rotation; + newRequest->abort = FALSE; + + UnlockCache(); + /* tell rendering thread there's a new request to render */ + LONG prevCount; + ReleaseSemaphore(gPageRenderSem, 1, &prevCount); +Exit: + return; +LeaveCsAndExit: + UnlockCache(); + return; +} + +void RenderQueue_Pop(PageRenderRequest *req) +{ + LockCache(); + assert(gPageRenderRequestsCount > 0); + assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); + --gPageRenderRequestsCount; + *req = gPageRenderRequests[gPageRenderRequestsCount]; + assert(gPageRenderRequestsCount >= 0); + UnlockCache(); +} + +static HMENU FindMenuItem(WindowInfo *win, UINT id) +{ + HMENU menuMain = GetMenu(win->hwndFrame); + + /* TODO: to be fully valid, it would have to be recursive */ + for (int i = 0; i < GetMenuItemCount(menuMain); i++) { + UINT thisId = GetMenuItemID(menuMain, i); + HMENU subMenu = GetSubMenu(menuMain, i); + if (id == thisId) + return subMenu; + for (int j = 0; j < GetMenuItemCount(subMenu); j++) { + thisId = GetMenuItemID(menuMain, j); + if (id == thisId) + return GetSubMenu(subMenu, j); + } + } + return NULL; +} + +static HMENU GetFileMenu(HWND hwnd) +{ + return GetSubMenu(GetMenu(hwnd), 0); +} + +static void SwitchToDisplayMode(WindowInfo *win, DisplayMode displayMode) +{ + HMENU menuMain; + UINT id; + + menuMain = GetMenu(win->hwndFrame); + CheckMenuItem(menuMain, IDM_VIEW_SINGLE_PAGE, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VIEW_FACING, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS_FACING, MF_BYCOMMAND | MF_UNCHECKED); + + win->dm->changeDisplayMode(displayMode); + if (DM_SINGLE_PAGE == displayMode) { + id = IDM_VIEW_SINGLE_PAGE; + } else if (DM_FACING == displayMode) { + id = IDM_VIEW_FACING; + } else if (DM_CONTINUOUS == displayMode) { + id = IDM_VIEW_CONTINUOUS; + } else if (DM_CONTINUOUS_FACING == displayMode) { + id = IDM_VIEW_CONTINUOUS_FACING; + } else + assert(0); + + CheckMenuItem(menuMain, id, MF_BYCOMMAND | MF_CHECKED); +} + +static UINT AllocNewMenuId(void) +{ + static UINT firstId = 1000; + ++firstId; + return firstId; +} + +#define SEP_ITEM "-----" + +typedef struct MenuDef { + const char *m_title; + int m_id; +} MenuDef; + +MenuDef menuDefFile[] = { + { _TRN("&Open\tCtrl-O"), IDM_OPEN }, + { _TRN("&Close\tCtrl-W"), IDM_CLOSE }, + { _TRN("&Save as"), IDM_SAVEAS }, + { _TRN("&Print"), IDM_PRINT }, + { SEP_ITEM, 0 }, + { _TRN("Make SumatraPDF a default PDF reader"), IDM_MAKE_DEFAULT_READER }, + { SEP_ITEM , 0 }, + { _TRN("E&xit\tCtrl-Q"), IDM_EXIT } +}; + +MenuDef menuDefView[] = { + { _TRN("Single page"), IDM_VIEW_SINGLE_PAGE }, + { _TRN("Facing"), IDM_VIEW_FACING }, + { _TRN("Continuous"), IDM_VIEW_CONTINUOUS }, + { _TRN("Continuous facing"), IDM_VIEW_CONTINUOUS_FACING }, + { SEP_ITEM, 0 }, + { _TRN("Rotate left"), IDM_VIEW_ROTATE_LEFT }, + { _TRN("Rotate right"), IDM_VIEW_ROTATE_RIGHT }, + { SEP_ITEM, 0 }, + { _TRN("Show toolbar"), IDM_VIEW_SHOW_HIDE_TOOLBAR }, + { SEP_ITEM, 0 }, + { _TRN("Use MuPDF rendering engine"), IDM_VIEW_USE_FITZ }, +}; + +MenuDef menuDefGoTo[] = { + { _TRN("Next Page"), IDM_GOTO_NEXT_PAGE }, + { _TRN("Previous Page"), IDM_GOTO_PREV_PAGE }, + { _TRN("First Page\tHome"), IDM_GOTO_FIRST_PAGE }, + { _TRN("Last Page\tEnd"), IDM_GOTO_LAST_PAGE }, + { _TRN("Page...\tCtrl-G"), IDM_GOTO_PAGE }, +}; + +MenuDef menuDefZoom[] = { + { _TRN("Fit &Page\tCtrl-0"), IDM_ZOOM_FIT_PAGE }, + { _TRN("Act&ual Size\tCtrl-1"), IDM_ZOOM_ACTUAL_SIZE }, + { _TRN("Fit Widt&h\tCtrl-2"), IDM_ZOOM_FIT_WIDTH }, + { SEP_ITEM }, + { _TRN("6400%"), IDM_ZOOM_6400 }, + { _TRN("3200%"), IDM_ZOOM_3200 }, + { _TRN("1600%"), IDM_ZOOM_1600 }, + { _TRN("800%"), IDM_ZOOM_800 }, + { _TRN("400%"), IDM_ZOOM_400 }, + { _TRN("200%"), IDM_ZOOM_200 }, + { _TRN("150%"), IDM_ZOOM_150 }, + { _TRN("125%"), IDM_ZOOM_125 }, + { _TRN("100%"), IDM_ZOOM_100 }, + { _TRN("50%"), IDM_ZOOM_50 }, + { _TRN("25%"), IDM_ZOOM_25 }, + { _TRN("12.5%"), IDM_ZOOM_12_5 }, + { _TRN("8.33%"), IDM_ZOOM_8_33 }, +}; + +MenuDef menuDefLang[] = { + { _TRN("&English"), IDM_LANG_EN }, + { _TRN("&French"), IDM_LANG_FR }, + { _TRN("&German"), IDM_LANG_DE }, + { _TRN("&Polish"), IDM_LANG_PL }, +}; + +MenuDef menuDefHelp[] = { + { _TRN("&Visit website"), IDM_VISIT_WEBSITE }, + { _TRN("&About"), IDM_ABOUT } +}; + +static void AddFileMenuItem(HMENU menuFile, FileHistoryList *node) +{ + assert(node); + if (!node) return; + assert(menuFile); + if (!menuFile) return; + + UINT newId = node->menuId; + if (INVALID_MENU_ID == node->menuId) + newId = AllocNewMenuId(); + const char* txt = FilePath_GetBaseName(node->state.filePath); + AppendMenu(menuFile, MF_ENABLED | MF_STRING, newId, (TCHAR*)txt); /* @author: Klemens Friedl; TCHAR* cast */ + node->menuId = newId; +} + +static HMENU BuildMenuFromMenuDef(MenuDef menuDefs[], int menuItems) +{ + HMENU m = CreateMenu(); + if (NULL == m) return NULL; + for (int i=0; i < menuItems; i++) { + MenuDef md = menuDefs[i]; + const char *title = md.m_title; + int id = md.m_id; + if (str_eq(title, SEP_ITEM)) + AppendMenu(m, MF_SEPARATOR, 0, NULL); + else { + const WCHAR* wtitle = Translatations_GetTranslationW(title); + if (wtitle) + AppendMenuW(m, MF_STRING, (UINT_PTR)id, wtitle); + } + } + return m; +} + +static HMENU g_currMenu = NULL; + +static void DestroyCurrentMenu() +{ + DestroyMenu(g_currMenu); + g_currMenu = NULL; +} + +static void AddRecentFilesToMenu(HMENU m) +{ + if (!gFileHistoryRoot) return; + + AppendMenu(m, MF_SEPARATOR, 0, NULL); + + int itemsAdded = 0; + FileHistoryList *curr = gFileHistoryRoot; + while (curr) { + assert(curr->state.filePath); + if (curr->state.filePath) { + AddFileMenuItem(m, curr); + assert(curr->menuId != INVALID_MENU_ID); + ++itemsAdded; + if (itemsAdded >= MAX_RECENT_FILES_IN_MENU) { + DBG_OUT(" not adding, reached max %d items\n", MAX_RECENT_FILES_IN_MENU); + return; + } + } + curr = curr->next; + } +} + +static HMENU ForceRebuildMenu() +{ + HMENU tmp; + DestroyCurrentMenu(); + g_currMenu = CreateMenu(); + tmp = BuildMenuFromMenuDef(menuDefFile, dimof(menuDefFile)); + AddRecentFilesToMenu(tmp); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&File")); + tmp = BuildMenuFromMenuDef(menuDefView, dimof(menuDefView)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&View")); + tmp = BuildMenuFromMenuDef(menuDefGoTo, dimof(menuDefGoTo)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Go To")); + tmp = BuildMenuFromMenuDef(menuDefZoom, dimof(menuDefZoom)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Zoom")); + tmp = BuildMenuFromMenuDef(menuDefLang, dimof(menuDefLang)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Language")); + tmp = BuildMenuFromMenuDef(menuDefHelp, dimof(menuDefHelp)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Help")); + return g_currMenu; +} + +static HMENU GetProgramMenu() +{ + if (NULL == g_currMenu) + ForceRebuildMenu(); + assert(g_currMenu); + return g_currMenu; +} + +/* Return the full exe path of my own executable. + Caller needs to free() the result. */ +static char *ExePathGet(void) +{ + char *cmdline = GetCommandLineA(); + return str_parse_possibly_quoted(&cmdline); +} + +/* Set the client area size of the window 'hwnd' to 'dx'/'dy'. */ +static void WinResizeClientArea(HWND hwnd, int dx, int dy) +{ + RECT rc; + GetClientRect(hwnd, &rc); + if ((rect_dx(&rc) == dx) && (rect_dy(&rc) == dy)) + return; + RECT rw; + GetWindowRect(hwnd, &rw); + int win_dx = rect_dx(&rw) + (dx - rect_dx(&rc)); + int win_dy = rect_dy(&rw) + (dy - rect_dy(&rc)); + SetWindowPos(hwnd, NULL, 0, 0, win_dx, win_dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); +} + +static void SetCanvasSizeToDxDy(WindowInfo *win, int w, int h) +{ + RECT canvasRect; + GetWindowRect(win->hwndCanvas, &canvasRect); + RECT frameRect; + GetWindowRect(win->hwndFrame, &frameRect); + int dx = rect_dx(&frameRect) - rect_dx(&canvasRect); + assert(dx >= 0); + int dy = rect_dy(&frameRect) - rect_dy(&canvasRect); + assert(dy >= 0); + SetWindowPos(win->hwndFrame, NULL, 0, 0, w+dx, h+dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); + //SetWindowPos(win->hwndCanvas, NULL, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); +} + +static void CaptionPens_Create(void) +{ + LOGPEN pen; + + assert(!ghpenWhite); + pen.lopnStyle = PS_SOLID; + pen.lopnWidth.x = 1; + pen.lopnWidth.y = 1; + pen.lopnColor = COL_WHITE; + ghpenWhite = CreatePenIndirect(&pen); + pen.lopnColor = COL_CAPTION_BLUE; + ghpenBlue = CreatePenIndirect(&pen); +} + +static void CaptionPens_Destroy(void) +{ + if (ghpenWhite) { + DeleteObject(ghpenWhite); + ghpenWhite = NULL; + } + + if (ghpenBlue) { + DeleteObject(ghpenBlue); + ghpenBlue = NULL; + } +} + +static void AddFileToHistory(const char *filePath) +{ + FileHistoryList * node; + uint32_t oldMenuId = INVALID_MENU_ID; + + assert(filePath); + if (!filePath) return; + + /* if a history entry with the same name already exists, then delete it. + That way we don't have duplicates and the file moves to the front of the list */ + node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, filePath); + if (node) { + oldMenuId = node->menuId; + FileHistoryList_Node_RemoveAndFree(&gFileHistoryRoot, node); + } + node = FileHistoryList_Node_CreateFromFilePath(filePath); + if (!node) + return; + node->menuId = oldMenuId; + FileHistoryList_Node_InsertHead(&gFileHistoryRoot, node); +} + +extern "C" char *GetPasswordForFile(WindowInfo *win, const char *fileName); + +/* Get password for a given 'fileName', can be NULL if user cancelled the + dialog box. + Caller needs to free() the result. */ +char *GetPasswordForFile(WindowInfo *win, const char *fileName) +{ + fileName = FilePath_GetBaseName(fileName); + return Dialog_GetPassword(win, fileName); +} + +void *StandardSecurityHandler::getAuthData() +{ + WindowInfo * win; + const char * pwd; + StandardAuthData * authData; + + win = (WindowInfo*)doc->getGUIData(); + assert(win); + if (!win) + return NULL; + + pwd = GetPasswordForFile(win, doc->getFileName()->getCString()); + if (!pwd) + return NULL; + + authData = new StandardAuthData(new GooString(pwd), new GooString(pwd)); + free((void*)pwd); + return (void*)authData; +} + +/* Return true if this program has been started from "Program Files" directory + (which is an indicator that it has been installed */ +static bool runningFromProgramFiles(void) +{ + char programFilesDir[MAX_PATH]; + BOOL fOk = SHGetSpecialFolderPath(NULL, (TCHAR*)programFilesDir, CSIDL_PROGRAM_FILES, FALSE); /* @author: Klemens Friedl; TCHAR* cast */ + char *exePath = ExePathGet(); + if (!exePath) return true; // again, assume it is + bool fromProgramFiles = false; + if (fOk) { + if (str_startswithi(exePath, programFilesDir)) + fromProgramFiles = true; + } else { + // SHGetSpecialFolderPath() might fail on win95/98 so need a different check + if (strstr(exePath, "Program Files")) + fromProgramFiles = true; + } + free(exePath); + return fromProgramFiles; +} + +static bool IsRunningInPortableMode(void) +{ + return !runningFromProgramFiles(); +} + +static void AppGetAppDir(DString* pDs) +{ + char dir[MAX_PATH]; + + SHGetSpecialFolderPath(NULL, (TCHAR*)dir, CSIDL_APPDATA, TRUE); /* @author: Klemens Friedl; TCHAR* cast */ + DStringSprintf(pDs, "%s/%s", dir, APP_SUB_DIR); + _mkdir(pDs->pString); +} + +/* Generate the full path for a filename used by the app in the userdata path. */ +static void AppGenDataFilename(char* pFilename, DString* pDs) +{ + assert(0 == pDs->length); + assert(pFilename); + if (!pFilename) return; + assert(pDs); + if (!pDs) return; + + bool portable = IsRunningInPortableMode(); + if (portable) { + /* Use the same path as the binary */ + char *exePath = ExePathGet(); + if (!exePath) return; + char *dir = FilePath_GetDir(exePath); + if (dir) + DStringSprintf(pDs, "%s", dir); + free((void*)exePath); + free((void*)dir); + } else { + AppGetAppDir(pDs); + } + if (!str_endswithi(pDs->pString, DIR_SEP_STR) && !(DIR_SEP_CHAR == pFilename[0])) { + DStringAppend(pDs, DIR_SEP_STR, -1); + } + DStringAppend(pDs, pFilename, -1); +} + +static void Prefs_GetFileName(DString* pDs) +{ + assert(0 == pDs->length); + AppGenDataFilename((char*)PREFS_FILE_NAME, pDs); /* @author: Klemens Friedl; char* cast */ +} + +/* Load preferences from the preferences file. */ +static void Prefs_Load(void) +{ + DString path; + static bool loaded = false; + char * prefsTxt = NULL; + + assert(!loaded); + loaded = true; + + DBG_OUT("Prefs_Load()\n"); + + DStringInit(&path); + Prefs_GetFileName(&path); + + size_t prefsFileLen; + prefsTxt = file_read_all(path.pString, &prefsFileLen); + if (str_empty(prefsTxt)) { + DBG_OUT(" no prefs file or is empty\n"); + return; + } + DBG_OUT("Prefs file %s:\n%s\n", path.pString, prefsTxt); + + bool fOk = Prefs_Deserialize(prefsTxt, &gFileHistoryRoot); + assert(fOk); + + DStringFree(&path); + free((void*)prefsTxt); +} + +static struct idToZoomMap { + UINT id; + double zoom; +} gZoomMenuItemsId[] = { + { IDM_ZOOM_6400, 6400.0 }, + { IDM_ZOOM_3200, 3200.0 }, + { IDM_ZOOM_1600, 1600.0 }, + { IDM_ZOOM_800, 800.0 }, + { IDM_ZOOM_400, 400.0 }, + { IDM_ZOOM_200, 200.0 }, + { IDM_ZOOM_150, 150.0 }, + { IDM_ZOOM_125, 125.0 }, + { IDM_ZOOM_100, 100.0 }, + { IDM_ZOOM_50, 50.0 }, + { IDM_ZOOM_25, 25.0 }, + { IDM_ZOOM_12_5, 12.5 }, + { IDM_ZOOM_8_33, 8.33 }, + { IDM_ZOOM_FIT_PAGE, ZOOM_FIT_PAGE }, + { IDM_ZOOM_FIT_WIDTH, ZOOM_FIT_WIDTH }, + { IDM_ZOOM_ACTUAL_SIZE, 100.0 } +}; + +static UINT MenuIdFromVirtualZoom(double virtualZoom) +{ + for (int i=0; i < dimof(gZoomMenuItemsId); i++) { + if (virtualZoom == gZoomMenuItemsId[i].zoom) + return gZoomMenuItemsId[i].id; + } + return IDM_ZOOM_ACTUAL_SIZE; +} + +static void ZoomMenuItemCheck(HMENU hmenu, UINT menuItemId) +{ + BOOL found = FALSE; + + for (int i=0; ihwndCanvas, &posX, &posY); + + ds->windowX = posX; + ds->windowY = posY; +} + +static void UpdateCurrentFileDisplayStateForWin(WindowInfo *win) +{ + DisplayState ds; + const char * fileName = NULL; + FileHistoryList*node = NULL; + + if (!win) + return; + if (WS_SHOWING_PDF != win->state) + return; + if (!win->dm) + return; + + fileName = win->dm->fileName(); + assert(fileName); + if (!fileName) + return; + + if (!gRunningDLL) + { + node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, fileName); + assert(node); + if (!node) + return; + } + + DisplayState_Init(&ds); + if (!displayStateFromDisplayModel(&ds, win->dm)) + return; + + UpdateDisplayStateWindowPos(win, &ds); + DisplayState_Free(&(node->state)); + node->state = ds; + node->state.visible = TRUE; +} + +static void UpdateCurrentFileDisplayState(void) +{ + WindowInfo * currWin; + FileHistoryList * currFile; + + currFile = gFileHistoryRoot; + while (currFile) { + currFile->state.visible = FALSE; + currFile = currFile->next; + } + + currWin = gWindowList; + while (currWin) { + UpdateCurrentFileDisplayStateForWin(currWin); + currWin = currWin->next; + } +} + +static void Prefs_Save(void) +{ + DString path; + DString prefsStr; + +#if 0 + if (gPrefsSaved) + return; + gPrefsSaved = TRUE; +#endif + + DStringInit(&prefsStr); + + /* mark currently shown files as visible */ + UpdateCurrentFileDisplayState(); + + bool fOk = Prefs_Serialize(&gFileHistoryRoot, &prefsStr); + if (!fOk) + goto Exit; + + DStringInit(&path); + Prefs_GetFileName(&path); + DBG_OUT("prefs file=%s\nprefs:\n%s\n", path.pString, prefsStr.pString); + /* TODO: consider 2-step process: + * write to a temp file + * rename temp file to final file */ + write_to_file((TCHAR*)path.pString, (void*)prefsStr.pString, prefsStr.length); /* @author: Klemens Friedl; TCHAR* cast */ + +Exit: + DStringFree(&prefsStr); + DStringFree(&path); +} + +static bool WindowInfo_Dib_Init(WindowInfo *win) { + assert(NULL == win->dibInfo); + win->dibInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + 12); + if (!win->dibInfo) + return false; + win->dibInfo->bmiHeader.biSize = sizeof(win->dibInfo->bmiHeader); + win->dibInfo->bmiHeader.biPlanes = 1; + win->dibInfo->bmiHeader.biBitCount = 24; + win->dibInfo->bmiHeader.biCompression = BI_RGB; + win->dibInfo->bmiHeader.biXPelsPerMeter = 2834; + win->dibInfo->bmiHeader.biYPelsPerMeter = 2834; + win->dibInfo->bmiHeader.biClrUsed = 0; + win->dibInfo->bmiHeader.biClrImportant = 0; + return true; +} + +static void WindowInfo_Dib_Deinit(WindowInfo *win) { + free((void*)win->dibInfo); + win->dibInfo = NULL; +} + +static void WindowInfo_DoubleBuffer_Delete(WindowInfo *win) { + if (win->bmpDoubleBuffer) { + DeleteObject(win->bmpDoubleBuffer); + win->bmpDoubleBuffer = NULL; + } + + if (win->hdcDoubleBuffer) { + DeleteDC(win->hdcDoubleBuffer); + win->hdcDoubleBuffer = NULL; + } + win->hdcToDraw = NULL; +} + +static bool WindowInfo_DoubleBuffer_New(WindowInfo *win) +{ + WindowInfo_DoubleBuffer_Delete(win); + + win->hdc = GetDC(win->hwndCanvas); + win->hdcToDraw = win->hdc; + win->GetCanvasSize(); + if (!gUseDoubleBuffer || (0 == win->winDx()) || (0 == win->winDy())) + return true; + + win->hdcDoubleBuffer = CreateCompatibleDC(win->hdc); + if (!win->hdcDoubleBuffer) + return false; + + win->bmpDoubleBuffer = CreateCompatibleBitmap(win->hdc, win->winDx(), win->winDy()); + if (!win->bmpDoubleBuffer) { + WindowInfo_DoubleBuffer_Delete(win); + return false; + } + /* TODO: do I need this ? */ + SelectObject(win->hdcDoubleBuffer, win->bmpDoubleBuffer); + /* fill out everything with background color */ + RECT r = {0}; + r.bottom = win->winDy(); + r.right = win->winDx(); + FillRect(win->hdcDoubleBuffer, &r, gBrushBg); + win->hdcToDraw = win->hdcDoubleBuffer; + return TRUE; +} + +static void WindowInfo_DoubleBuffer_Show(WindowInfo *win, HDC hdc) +{ + if (win->hdc != win->hdcToDraw) { + assert(win->hdcToDraw == win->hdcDoubleBuffer); + BitBlt(hdc, 0, 0, win->winDx(), win->winDy(), win->hdcDoubleBuffer, 0, 0, SRCCOPY); + } +} + +static void WindowInfo_Delete(WindowInfo *win) +{ + if (win->dm) { + RenderQueue_RemoveForDisplayModel(win->dm); + cancelRenderingForDisplayModel(win->dm); + } + delete win->dm; + win->dm = NULL; + WindowInfo_Dib_Deinit(win); + WindowInfo_DoubleBuffer_Delete(win); + delete win; +} + +static WindowInfo* WindowInfo_FindByHwnd(HWND hwnd) +{ + WindowInfo *win = gWindowList; + while (win) { + if (hwnd == win->hwndFrame) + return win; + if (hwnd == win->hwndCanvas) + return win; + if (hwnd == win->hwndReBar) + return win; + win = win->next; + } + return NULL; +} + +static WindowInfo *WindowInfo_New(HWND hwndFrame) { + WindowInfo * win = WindowInfo_FindByHwnd(hwndFrame); + assert(!win); + + win = new WindowInfo();; + if (!win) + return NULL; + + if (!WindowInfo_Dib_Init(win)) + goto Error; + + win->state = WS_ABOUT; + win->hwndFrame = hwndFrame; + win->mouseAction = MA_IDLE; + return win; +Error: + WindowInfo_Delete(win); + return NULL; +} + +static void WindowInfoList_Add(WindowInfo *win) { + win->next = gWindowList; + gWindowList = win; +} + +static bool WindowInfoList_ExistsWithError(void) { + WindowInfo *cur = gWindowList; + while (cur) { + if (WS_ERROR_LOADING_PDF == cur->state) + return true; + cur = cur->next; + } + return false; +} + +static void WindowInfoList_Remove(WindowInfo *to_remove) { + assert(to_remove); + if (!to_remove) + return; + if (gWindowList == to_remove) { + gWindowList = to_remove->next; + return; + } + WindowInfo* curr = gWindowList; + while (curr) { + if (to_remove == curr->next) { + curr->next = to_remove->next; + return; + } + curr = curr->next; + } +} + +static void WindowInfoList_DeleteAll(void) { + WindowInfo* curr = gWindowList; + while (curr) { + WindowInfo* next = curr->next; + WindowInfo_Delete(curr); + curr = next; + } + gWindowList = NULL; +} + +static int WindowInfoList_Len(void) { + int len = 0; + WindowInfo* curr = gWindowList; + while (curr) { + ++len; + curr = curr->next; + } + return len; +} + +static void WindowInfo_RedrawAll(WindowInfo *win, bool update=false) { + InvalidateRect(win->hwndCanvas, NULL, false); + if (update) + UpdateWindow(win->hwndCanvas); +} + +static bool FileCloseMenuEnabled(void) { + WindowInfo* win = gWindowList; + while (win) { + if (win->state == WS_SHOWING_PDF) + return true; + win = win->next; + } + return false; +} + +static void ToolbarUpdateStateForWindow(WindowInfo *win) { + LPARAM enable = (LPARAM)MAKELONG(1,0); + LPARAM disable = (LPARAM)MAKELONG(0,0); + + for (int i=0; i < TOOLBAR_BUTTONS_COUNT; i++) { + int cmdId = gToolbarButtons[i].cmdId; + if (IDB_SEPARATOR == cmdId) + continue; + LPARAM buttonState = enable; + if (IDM_OPEN != cmdId) { + if (WS_SHOWING_PDF != win->state) + buttonState = disable; + } + SendMessage(win->hwndToolbar, TB_ENABLEBUTTON, cmdId, buttonState); + } +} + +static void MenuUpdateShowToolbarStateForWindow(WindowInfo *win) { + HMENU hmenu = GetMenu(win->hwndFrame); + if (gShowToolbar) + CheckMenuItem(hmenu, IDM_VIEW_SHOW_HIDE_TOOLBAR, MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem(hmenu, IDM_VIEW_SHOW_HIDE_TOOLBAR, MF_BYCOMMAND | MF_UNCHECKED); +} + +static void MenuUpdateUseFitzStateForWindow(WindowInfo *win) { + HMENU hmenu = GetMenu(win->hwndFrame); + if (gUseFitz) + CheckMenuItem(hmenu, IDM_VIEW_USE_FITZ, MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem(hmenu, IDM_VIEW_USE_FITZ, MF_BYCOMMAND | MF_UNCHECKED); +} + +// show which language is being used via check in Language/* menu +static void MenuUpdateLanguage(WindowInfo *win) { + HMENU hmenu = GetMenu(win->hwndFrame); + for (int i = 0; i < LANGS_COUNT; i++) { + const char *langName = g_langs[i]._langName; + int langMenuId = g_langs[i]._langId; + if (str_eq(CurrLangNameGet(), langName)) + CheckMenuItem(hmenu, langMenuId, MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem(hmenu, langMenuId, MF_BYCOMMAND | MF_UNCHECKED); + } +} + +static void MenuUpdateStateForWindow(WindowInfo *win) { + static UINT menusToDisableIfNoPdf[] = { + IDM_VIEW_SINGLE_PAGE, IDM_VIEW_FACING, IDM_VIEW_CONTINUOUS, IDM_VIEW_CONTINUOUS_FACING, + IDM_VIEW_ROTATE_LEFT, IDM_VIEW_ROTATE_RIGHT, IDM_GOTO_NEXT_PAGE, IDM_GOTO_PREV_PAGE, + IDM_GOTO_FIRST_PAGE, IDM_GOTO_LAST_PAGE, IDM_GOTO_PAGE, IDM_ZOOM_FIT_PAGE, + IDM_ZOOM_ACTUAL_SIZE, IDM_ZOOM_FIT_WIDTH, IDM_ZOOM_6400, IDM_ZOOM_3200, + IDM_ZOOM_1600, IDM_ZOOM_800, IDM_ZOOM_400, IDM_ZOOM_200, IDM_ZOOM_150, + IDM_ZOOM_125, IDM_ZOOM_100, IDM_ZOOM_50, IDM_ZOOM_25, IDM_ZOOM_12_5, + IDM_ZOOM_8_33, IDM_SAVEAS }; + + bool fileCloseEnabled = FileCloseMenuEnabled(); + HMENU hmenu = GetMenu(win->hwndFrame); + if (fileCloseEnabled) + EnableMenuItem(hmenu, IDM_CLOSE, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(hmenu, IDM_CLOSE, MF_BYCOMMAND | MF_GRAYED); + + bool filePrintEnabled = false; + if (win->dm && win->dm->pdfEngine() && win->dm->pdfEngine()->printingAllowed()) + filePrintEnabled = true; + if (filePrintEnabled) + EnableMenuItem(hmenu, IDM_PRINT, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(hmenu, IDM_PRINT, MF_BYCOMMAND | MF_GRAYED); + + MenuUpdateShowToolbarStateForWindow(win); + MenuUpdateUseFitzStateForWindow(win); + MenuUpdateLanguage(win); + + for (int i = 0; i < dimof(menusToDisableIfNoPdf); i++) { + UINT menuId = menusToDisableIfNoPdf[i]; + if (WS_SHOWING_PDF == win->state) + EnableMenuItem(hmenu, menuId, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(hmenu, menuId, MF_BYCOMMAND | MF_GRAYED); + } + /* Hide scrollbars if not showing a PDF */ + /* TODO: doesn't really fit the name of the function */ + if (WS_SHOWING_PDF == win->state) + ShowScrollBar(win->hwndCanvas, SB_BOTH, TRUE); + else { + ShowScrollBar(win->hwndCanvas, SB_BOTH, FALSE); + win_set_text(win->hwndFrame, APP_NAME); + } +} + +/* Disable/enable menu items and toolbar buttons depending on wheter a + given window shows a PDF file or not. */ +static void MenuToolbarUpdateStateForAllWindows(void) { + WindowInfo* win = gWindowList; + while (win) { + MenuUpdateStateForWindow(win); + ToolbarUpdateStateForWindow(win); + win = win->next; + } +} + +static WindowInfo* WindowInfo_CreateEmpty(void) { + HWND hwndFrame, hwndCanvas; + WindowInfo* win; + +#if FANCY_UI + hwndFrame = CreateWindowEx( +// WS_EX_TOOLWINDOW, + 0, +// WS_OVERLAPPEDWINDOW, +// WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, + //WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_HSCROLL | WS_VSCROLL, + FRAME_CLASS_NAME, windowTitle, + WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + NULL, NULL, + ghinst, NULL); +#else + hwndFrame = CreateWindow( + FRAME_CLASS_NAME, windowTitle, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + NULL, NULL, + ghinst, NULL); + HMENU m = GetProgramMenu(); + SetMenu(hwndFrame, m); +#endif + + if (!hwndFrame) + return NULL; + + win = WindowInfo_New(hwndFrame); + hwndCanvas = CreateWindow( + CANVAS_CLASS_NAME, NULL, + WS_CHILD | WS_HSCROLL | WS_VSCROLL, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + hwndFrame, NULL, + ghinst, NULL); + if (!hwndCanvas) + return NULL; + win->hwndCanvas = hwndCanvas; + CreateToolbar(win, ghinst); + return win; +} + +BOOL GetDesktopWindowClientRect(RECT *r) +{ + HWND hwnd = GetDesktopWindow(); + if (!hwnd) return FALSE; + return GetClientRect(hwnd, r); +} + +void GetCanvasDxDyDiff(WindowInfo *win, int *dxOut, int *dyOut) +{ + RECT canvasRect; + GetWindowRect(win->hwndCanvas, &canvasRect); + RECT totalRect; + GetWindowRect(win->hwndFrame, &totalRect); + *dxOut = rect_dx(&totalRect) - rect_dx(&canvasRect); + // TODO: should figure out why it fires in DLL + assert(gRunningDLL || *dxOut >= 0); + *dyOut = rect_dy(&totalRect) - rect_dy(&canvasRect); + // TODO: should figure out why it fires in DLL + assert(gRunningDLL || *dyOut >= 0); +} + +SizeI GetMaxCanvasSize(WindowInfo *win) +{ + AppBarData abd; + RECT r; + GetDesktopWindowClientRect(&r); + // substract the area of the window not used for canvas + int dx, dy; + GetCanvasDxDyDiff(win, &dx, &dy); // TODO: lame name + int maxCanvasDx = rect_dx(&r) - dx; + int maxCanvasDy = rect_dy(&r) - dy; + if (abd.isHorizontal()) { + assert(maxCanvasDx >= abd.dx()); + maxCanvasDx -= abd.dx(); + } else { + assert(abd.isVertical()); + assert(maxCanvasDy >= abd.dy()); + maxCanvasDy -= abd.dy(); + } + return SizeI(maxCanvasDx, maxCanvasDy); +} + + +static void RecalcSelectionPosition (WindowInfo *win) { + SelectionOnPage * selOnPage = win->selectionOnPage; + RectD selD; + PdfPageInfo* pageInfo; + + while (selOnPage != NULL) { + pageInfo = win->dm->getPageInfo(selOnPage->pageNo); + /* if page is not visible, we hide seletion by simply moving it off + * the canvas */ + if (!pageInfo->visible) { + selOnPage->selectionCanvas.x = -100; + selOnPage->selectionCanvas.y = -100; + selOnPage->selectionCanvas.dx = 0; + selOnPage->selectionCanvas.dy = 0; + } else {//page is visible + RectD_Copy (&selD, &selOnPage->selectionPage); + win->dm->rectCvtUserToScreen (selOnPage->pageNo, &selD); + RectI_FromRectD (&selOnPage->selectionCanvas, &selD); + } + selOnPage = selOnPage->next; + } +} + +static WindowInfo* LoadPdf(const char *fileName, bool ignoreHistorySizePos = true, bool ignoreHistory = false) +{ + assert(fileName); + if (!fileName) return NULL; + + FileHistoryList * fileFromHistory = NULL; + if (!ignoreHistory) + fileFromHistory = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, fileName); + + WindowInfo * win; + bool reuseExistingWindow = false; + if ((1 == WindowInfoList_Len()) && (WS_SHOWING_PDF != gWindowList->state)) { + win = gWindowList; + reuseExistingWindow = true; + } else { + win = WindowInfo_CreateEmpty(); + if (!win) + return NULL; + } + + win->GetCanvasSize(); + SizeI maxCanvasSize = GetMaxCanvasSize(win); + SizeD totalDrawAreaSize(win->winSize()); + if (fileFromHistory && !ignoreHistorySizePos) { + WinResizeClientArea(win->hwndCanvas, fileFromHistory->state.windowDx, fileFromHistory->state.windowDy); + totalDrawAreaSize = SizeD(fileFromHistory->state.windowDx, fileFromHistory->state.windowDy); + Win32_Win_SetPos(win->hwndFrame, fileFromHistory->state.windowX, fileFromHistory->state.windowY); + } +#if 0 // not ready yet + else { + IntelligentWindowResize(win); + } +#endif + + /* TODO: make sure it doesn't have a stupid position like + outside of the screen etc. */ +#if 0 + if (totalDrawAreaSize.dxI() > maxCanvasSize.dx) + totalDrawAreaSize.setDx(maxCanvasSize.dx); + if (totalDrawAreaSize.dyI() > maxCanvasSize.dy) + totalDrawAreaSize.setDy(maxCanvasSize.dy); + + WinResizeClientArea(win->hwndCanvas, totalDrawAreaSize.dxI(), totalDrawAreaSize.dyI()); +#endif + + /* In theory I should get scrollbars sizes using Win32_GetScrollbarSize(&scrollbarYDx, &scrollbarXDy); + but scrollbars are not part of the client area on windows so it's better + not to have them taken into account by DisplayModelSplash code. + TODO: I think it's broken anyway and DisplayModelSplash needs to know if + scrollbars are part of client area in order to accomodate windows + UI properly */ + DisplayMode displayMode = DEFAULT_DISPLAY_MODE; + int offsetX = 0; + int offsetY = 0; + int startPage = 1; + int scrollbarYDx = 0; + int scrollbarXDy = 0; + if (fileFromHistory) { + startPage = fileFromHistory->state.pageNo; + displayMode = fileFromHistory->state.displayMode; + offsetX = fileFromHistory->state.scrollX; + offsetY = fileFromHistory->state.scrollY; + } + + if (gUseFitz) { + win->dm = DisplayModelFitz_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, win); + } else { + win->dm = DisplayModelSplash_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, win); + } + + double zoomVirtual = DEFAULT_ZOOM; + int rotation = DEFAULT_ROTATION; + if (!win->dm) { + if (!reuseExistingWindow && WindowInfoList_ExistsWithError()) { + /* don't create more than one window with errors */ + WindowInfo_Delete(win); + return NULL; + } + win->state = WS_ERROR_LOADING_PDF; + DBG_OUT("failed to load file %s\n", fileName); + //goto Exit; /* @author: Klemens Friedl; because of "crosses initialization of [...]" */ + if (!reuseExistingWindow) + WindowInfoList_Add(win); + MenuToolbarUpdateStateForAllWindows(); + assert(win); + DragAcceptFiles(win->hwndFrame, TRUE); + DragAcceptFiles(win->hwndCanvas, TRUE); + ShowWindow(win->hwndFrame, SW_SHOW); + ShowWindow(win->hwndCanvas, SW_SHOW); + UpdateWindow(win->hwndFrame); + UpdateWindow(win->hwndCanvas); + return win; + } + + win->dm->setAppData((void*)win); + + if (!fileFromHistory) { + AddFileToHistory(fileName); + RebuildProgramMenus(); + } + + /* TODO: if fileFromHistory, set the state based on gFileHistoryList node for + this entry */ + win->state = WS_SHOWING_PDF; + if (fileFromHistory) { + zoomVirtual = fileFromHistory->state.zoomVirtual; + rotation = fileFromHistory->state.rotation; + } + + UINT menuId = MenuIdFromVirtualZoom(zoomVirtual); + ZoomMenuItemCheck(GetMenu(win->hwndFrame), menuId); + + win->dm->relayout(zoomVirtual, rotation); + if (!win->dm->validPageNo(startPage)) + startPage = 1; + /* TODO: need to calculate proper offsetY, currently giving large offsetY + remembered for continuous mode breaks things (makes all pages invisible) */ + offsetY = 0; + /* TODO: make sure offsetX isn't bogus */ + win->dm->goToPage(startPage, offsetY, offsetX); + + /* only resize the window if it's a newly opened window */ + if (!reuseExistingWindow && !fileFromHistory) + WindowInfo_ResizeToPage(win, startPage); + + if (reuseExistingWindow) + WindowInfo_RedrawAll(win); + +Exit: + if (!reuseExistingWindow) + WindowInfoList_Add(win); + MenuToolbarUpdateStateForAllWindows(); + assert(win); + DragAcceptFiles(win->hwndFrame, TRUE); + DragAcceptFiles(win->hwndCanvas, TRUE); + ShowWindow(win->hwndFrame, SW_SHOW); + ShowWindow(win->hwndCanvas, SW_SHOW); + UpdateWindow(win->hwndFrame); + UpdateWindow(win->hwndCanvas); + return win; +} + +static HFONT Win32_Font_GetSimple(HDC hdc, char *fontName, int fontSize) +{ + HFONT font_dc; + HFONT font; + LOGFONT lf = {0}; + + font_dc = (HFONT)GetStockObject(SYSTEM_FONT); + if (!GetObject(font_dc, sizeof(LOGFONT), &lf)) + return NULL; + + lf.lfHeight = (LONG)-fontSize; + lf.lfWidth = 0; + //lf.lfHeight = -MulDiv(fontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfOutPrecision = OUT_TT_PRECIS; + lf.lfQuality = DEFAULT_QUALITY; + //lf.lfQuality = CLEARTYPE_QUALITY; + lf.lfPitchAndFamily = DEFAULT_PITCH; + strcpy_s((char*)lf.lfFaceName, LF_FACESIZE, fontName); /* @author: Klemens Friedl; char* cast */ + lf.lfWeight = FW_DONTCARE; + font = CreateFontIndirect(&lf); + return font; +} + +static void Win32_Font_Delete(HFONT font) +{ + DeleteObject(font); +} + +void DisplayModel::pageChanged(void) +{ + WindowInfo *win = (WindowInfo*)appData(); + assert(win); + if (!win) return; + +#if 0 + if (!win->dmSplash->pdfDoc) + return; +#endif + + int currPageNo = currentPageNo(); + int pageCount = win->dm->pageCount(); + const char *baseName = FilePath_GetBaseName(win->dm->fileName()); + if (pageCount <= 0) + win_set_text(win->hwndFrame, (TCHAR*)baseName); /* @author: Klemens Friedl; TCHAR* cast */ + else { + char titleBuf[256]; + HRESULT hr = StringCchPrintfA(titleBuf, dimof(titleBuf), "%s page %d of %d", baseName, currPageNo, pageCount); + win_set_text(win->hwndFrame, (TCHAR*)titleBuf); /* @author: Klemens Friedl; TCHAR* cast */ + /* @author: Klemens Friedl; FIXME: hr is unused ATM */ + } +} + +/* Call from non-UI thread to cause repainting of the display */ +static void triggerRepaintDisplayPotentiallyDelayed(WindowInfo *win, bool delayed) +{ + assert(win); + if (!win) return; + if (delayed) + PostMessage(win->hwndCanvas, WM_APP_REPAINT_DELAYED, 0, 0); + else + PostMessage(win->hwndCanvas, WM_APP_REPAINT_NOW, 0, 0); +} + +static void triggerRepaintDisplayNow(WindowInfo* win) +{ + triggerRepaintDisplayPotentiallyDelayed(win, false); +} + +void DisplayModel::repaintDisplay(bool delayed) +{ + WindowInfo* win = (WindowInfo*)appData(); + triggerRepaintDisplayPotentiallyDelayed(win, delayed); +} + +void DisplayModel::setScrollbarsState(void) +{ + WindowInfo *win = (WindowInfo*)this->appData(); + assert(win); + if (!win) return; + + SCROLLINFO si = {0}; + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + + int canvasDx = _canvasSize.dxI(); + int canvasDy = _canvasSize.dyI(); + int drawAreaDx = drawAreaSize.dxI(); + int drawAreaDy = drawAreaSize.dyI(); + + if (drawAreaDx >= canvasDx) { + si.nPos = 0; + si.nMin = 0; + si.nMax = 99; + si.nPage = 100; + } else { + si.nPos = (int)areaOffset.x; + si.nMin = 0; + si.nMax = canvasDx-1; + si.nPage = drawAreaDx; + } + SetScrollInfo(win->hwndCanvas, SB_HORZ, &si, TRUE); + + if (drawAreaDy >= canvasDy) { + si.nPos = 0; + si.nMin = 0; + si.nMax = 99; + si.nPage = 100; + } else { + si.nPos = (int)areaOffset.y; + si.nMin = 0; + si.nMax = canvasDy-1; + si.nPage = drawAreaDy; + } + SetScrollInfo(win->hwndCanvas, SB_VERT, &si, TRUE); +} + +static void WindowInfo_ResizeToWindow(WindowInfo *win) +{ + assert(win); + if (!win) return; + assert(win->dm); + if (!win->dm) return; + + win->dm->changeTotalDrawAreaSize(win->winSize()); +} + +void WindowInfo_ResizeToPage(WindowInfo *win, int pageNo) +{ + bool fullScreen = false; + + assert(win); + if (!win) return; + assert(win->dm); + if (!win->dm) + return; + + /* TODO: should take current monitor into account? */ + HDC hdc = GetDC(win->hwndCanvas); + int displayDx = GetDeviceCaps(hdc, HORZRES); + int displayDy = GetDeviceCaps(hdc, VERTRES); + + int dx, dy; + if (fullScreen) { + /* TODO: fullscreen not yet supported */ + assert(0); + dx = displayDx; + dy = displayDy; + } else { + assert(win->dm->validPageNo(pageNo)); + if (!win->dm->validPageNo(pageNo)) + return; + PdfPageInfo *pageInfo = win->dm->getPageInfo(pageNo); + assert(pageInfo); + if (!pageInfo) + return; + DisplaySettings *displaySettings = globalDisplaySettings(); + dx = pageInfo->currDx + displaySettings->paddingPageBorderLeft + displaySettings->paddingPageBorderRight; + dy = pageInfo->currDy + displaySettings->paddingPageBorderTop + displaySettings->paddingPageBorderBottom; + if (dx > displayDx - 10) + dx = displayDx - 10; + if (dy > displayDy - 10) + dy = displayDy - 10; + } + + WinResizeClientArea(win->hwndCanvas, dx, dy); +} + +static void WindowInfo_ToggleZoom(WindowInfo *win) +{ + DisplayModel * dm; + + assert(win); + if (!win) return; + + dm = win->dm; + assert(dm); + if (!dm) return; + + if (ZOOM_FIT_PAGE == dm->zoomVirtual()) + dm->setZoomVirtual(ZOOM_FIT_WIDTH); + else if (ZOOM_FIT_WIDTH == dm->zoomVirtual()) + dm->setZoomVirtual(ZOOM_FIT_PAGE); +} + +static BOOL WindowInfo_PdfLoaded(WindowInfo *win) +{ + assert(win); + if (!win) return FALSE; + if (!win->dm) return FALSE; +#if 0 + assert(win->dmSplash->pdfDoc); + assert(win->dmSplash->pdfDoc->isOk()); +#endif + return TRUE; +} + +int WindowsVerMajor() +{ + DWORD version = GetVersion(); + return (int)(version & 0xFF); +} + +int WindowsVerMinor() +{ + DWORD version = GetVersion(); + return (int)((version & 0xFF00) >> 8); +} + +bool WindowsVer2000OrGreater() +{ + if (WindowsVerMajor() >= 5) + return true; + return false; +} + +static bool AlreadyRegisteredForPdfExtentions(void) +{ + bool registered = false; + HKEY key = NULL; + char nameBuf[sizeof(APP_NAME)+8]; + DWORD cbNameBuf = sizeof(nameBuf); + DWORD keyType; + + /* HKEY_CLASSES_ROOT\.pdf */ + if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT(".pdf"), 0, KEY_QUERY_VALUE, &key)) /* @author: Klemens Friedl; TEXT() cast */ + return false; + + if (ERROR_SUCCESS != RegQueryValueEx(key, NULL, NULL, &keyType, (LPBYTE)nameBuf, &cbNameBuf)) + goto Exit; + + if (REG_SZ != keyType) + goto Exit; + + if (cbNameBuf != sizeof(APP_NAME)) + goto Exit; + + if (0 == memcmp(APP_NAME, nameBuf, sizeof(APP_NAME))) + registered = true; + +Exit: + RegCloseKey(key); + return registered; +} + +static void AssociateExeWithPdfExtensions() +{ + char tmp[256]; + HKEY key = NULL, kicon = NULL, kshell = NULL, kopen = NULL, kcmd = NULL; + DWORD disp; + HRESULT hr; + + char * exePath = ExePathGet(); + assert(exePath); + if (!exePath) return; + + HKEY hkeyToUse = HKEY_CURRENT_USER; + if (WindowsVer2000OrGreater()) + hkeyToUse = HKEY_LOCAL_MACHINE; + + /* key\.pdf */ /* @author: Klemens Friedl; TEXT() && TCHAR* casts */ + if (RegCreateKeyEx(hkeyToUse, + TEXT(".pdf"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &key, &disp)) + goto Exit; + + if (RegSetValueEx(key, TEXT(""), 0, REG_SZ, (const BYTE*)APP_NAME, sizeof(APP_NAME))) + goto Exit; + + RegCloseKey(key); + key = NULL; + + /* key\APP_NAME */ + if (RegCreateKeyEx(hkeyToUse, + APP_NAME, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &key, &disp)) + goto Exit; + + if (RegSetValueEx(key, TEXT(""), 0, REG_SZ, (const BYTE*)PDF_DOC_NAME, sizeof(PDF_DOC_NAME))) + goto Exit; + + /* key\APP_NAME\DefaultIcon */ + if (RegCreateKeyEx(key, + TEXT("DefaultIcon"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kicon, &disp)) + goto Exit; + + /* Note: I don't understand why icon index has to be 0, but it just has to */ + hr = StringCchPrintfA(tmp, dimof(tmp), "%s,0", exePath); + if (RegSetValueEx(kicon, TEXT(""), 0, REG_SZ, (const BYTE*)tmp, strlen(tmp)+1)) + goto Exit; + + RegCloseKey(kicon); + kicon = NULL; + + /* HKEY_CLASSES_ROOT\APP_NAME\Shell\Open\Command */ + if (RegCreateKeyEx(key, + TEXT("shell"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kshell, &disp)) + goto Exit; + + if (RegCreateKeyEx(kshell, + TEXT("open"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kopen, &disp)) + goto Exit; + + if (RegCreateKeyEx(kopen, + TEXT("command"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kcmd, &disp)) + goto Exit; + + hr = StringCchPrintfA(tmp, dimof(tmp), "\"%s\" \"%%1\"", exePath); + if (RegSetValueEx(kcmd, TEXT(""), 0, REG_SZ, (const BYTE*)tmp, strlen(tmp)+1)) + goto Exit; + + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, 0, 0); + +Exit: + if (kcmd) + RegCloseKey(kcmd); + if (kopen) + RegCloseKey(kopen); + if (kshell) + RegCloseKey(kshell); + if (key) + RegCloseKey(key); + free(exePath); +} + +static void RegisterForPdfExtentions(HWND hwnd) +{ + if (AlreadyRegisteredForPdfExtentions()) + return; + + if (IsRunningInPortableMode()) + return; + + /* Ask user for permission, unless he previously said he doesn't want to + see this dialog */ + if (!gPdfAssociateDontAskAgain) { + int result = Dialog_PdfAssociate(hwnd, &gPdfAssociateDontAskAgain); + if (DIALOG_NO_PRESSED == result) { + gPdfAssociateShouldAssociate = FALSE; + } else { + assert(DIALOG_OK_PRESSED == result); + gPdfAssociateShouldAssociate = TRUE; + } + } + + if (gPdfAssociateShouldAssociate) + AssociateExeWithPdfExtensions(); +} + +static void OnDropFiles(WindowInfo *win, HDROP hDrop) +{ + int i; + char filename[MAX_PATH]; + const int files_count = DragQueryFile(hDrop, DRAGQUERY_NUMFILES, 0, 0); + + for (i = 0; i < files_count; i++) + { + DragQueryFile(hDrop, i, (TCHAR*)filename, MAX_PATH); /* @author: Klemens Friedl; TCHAR* cast */ + LoadPdf(filename); + } + DragFinish(hDrop); + + if (files_count > 0) + WindowInfo_RedrawAll(win); +} + +static void DrawLineSimple(HDC hdc, int sx, int sy, int ex, int ey) +{ + MoveToEx(hdc, sx, sy, NULL); + LineTo(hdc, ex, ey); +} + +#if 0 +/* Draw caption area for a given window 'win' in the classic AmigaOS style */ +static void AmigaCaptionDraw(WindowInfo *win) +{ + HGDIOBJ prevPen; + HDC hdc = win->hdc; + + assert(VS_AMIGA == gVisualStyle); + + prevPen = SelectObject(hdc, ghpenWhite); + + /* white */ + DrawLineSimple(hdc, 0, 0, win->winDx, 0); + DrawLineSimple(hdc, 0, 1, win->winDx, 1); + + /* white */ + DrawLineSimple(hdc, 0, 4, win->winDx, 4); + DrawLineSimple(hdc, 0, 5, win->winDx, 5); + + /* white */ + DrawLineSimple(hdc, 0, 8, win->winDx, 8); + DrawLineSimple(hdc, 0, 9, win->winDx, 9); + + /* white */ + DrawLineSimple(hdc, 0, 12, win->winDx, 12); + DrawLineSimple(hdc, 0, 13, win->winDx, 13); + + /* white */ + DrawLineSimple(hdc, 0, 16, win->winDx, 16); + DrawLineSimple(hdc, 0, 17, win->winDx, 17); + DrawLineSimple(hdc, 0, 18, win->winDx, 18); + + SelectObject(hdc, ghpenBlue); + + /* blue */ + DrawLineSimple(hdc, 0, 2, win->winDx, 2); + DrawLineSimple(hdc, 0, 3, win->winDx, 3); + + /* blue */ + DrawLineSimple(hdc, 0, 6, win->winDx, 6); + DrawLineSimple(hdc, 0, 7, win->winDx, 7); + + /* blue */ + DrawLineSimple(hdc, 0, 10, win->winDx, 10); + DrawLineSimple(hdc, 0, 11, win->winDx, 11); + + /* blue */ + DrawLineSimple(hdc, 0, 14, win->winDx, 14); + DrawLineSimple(hdc, 0, 15, win->winDx, 15); + + SelectObject(hdc, prevPen); +} +#endif + +static void WinResizeIfNeeded(WindowInfo *win, bool resizeWindow=true) +{ + RECT rc; + GetClientRect(win->hwndCanvas, &rc); + int win_dx = rect_dx(&rc); + int win_dy = rect_dy(&rc); + + if (win->hdcToDraw && + (win_dx == win->winDx()) && + (win_dy == win->winDy())) + { + return; + } + + WindowInfo_DoubleBuffer_New(win); + if (resizeWindow) + WindowInfo_ResizeToWindow(win); +} + +static void PostBenchNextAction(HWND hwnd) +{ + PostMessage(hwnd, MSG_BENCH_NEXT_ACTION, 0, 0); +} + +static void OnBenchNextAction(WindowInfo *win) +{ + if (!win->dm) + return; + + if (win->dm->goToNextPage(0)) + PostBenchNextAction(win->hwndFrame); +} + +static void DrawCenteredText(HDC hdc, RECT *r, char *txt) +{ + SetBkMode(hdc, TRANSPARENT); + DrawText(hdc, (TCHAR*)txt, strlen(txt), r, DT_CENTER | DT_VCENTER | DT_SINGLELINE); /* @author: Klemens Friedl; TCHAR* cast */ +} + +static void SeeLastError(void) { + char *msgBuf = NULL; + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &msgBuf, 0, NULL); + if (!msgBuf) return; + printf("SeeLastError(): %s\n", msgBuf); + OutputDebugStringA(msgBuf); + LocalFree(msgBuf); +} + +static void PaintTransparentRectangle(WindowInfo *win, HDC hdc, RectI *rect) { + HBITMAP hbitmap; // bitmap handle + BITMAPINFO bmi; // bitmap header + VOID *pvBits; // pointer to DIB section + BLENDFUNCTION bf; // structure for alpha blending + HDC rectDC = CreateCompatibleDC(hdc); + const DWORD selectionColorYellow = 0xfff5fc0c; + const DWORD selectionColorBlack = 0xff000000; + const int margin = 1; + + ZeroMemory(&bmi, sizeof(BITMAPINFO)); + + bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = rect->dx; + bmi.bmiHeader.biHeight = rect->dy; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = rect->dx * rect->dy * 4; + + hbitmap = CreateDIBSection (rectDC, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0); + SelectObject(rectDC, hbitmap); + + for (int y = 0; y < rect->dy; y++) { + for (int x = 0; x < rect->dx; x++) { + if (x < margin || x > rect->dx - margin - 1 + || y < margin || y > rect->dy - margin - 1) + ((UINT32 *)pvBits)[x + y * rect->dx] = selectionColorBlack; + else + ((UINT32 *)pvBits)[x + y * rect->dx] = selectionColorYellow; + } + } + bf.BlendOp = AC_SRC_OVER; + bf.BlendFlags = 0; + bf.SourceConstantAlpha = 0x5f; + bf.AlphaFormat = AC_SRC_ALPHA; + + /*if (!AlphaBlend(hdc, rect->x, rect->y, rect->dx, rect->dy, + rectDC, 0, 0, rect->dx, rect->dy, bf)) + DBG_OUT("AlphaBlending error\n");*/ + /* @author: Klemens Friedl; error: 'AlphaBlend' was not declared in this scope; even with WINVER: 0x0500 set in rbuild file, weird; @FIXME */ + DeleteObject (hbitmap); + DeleteDC (rectDC); +} + +static void PaintSelection (WindowInfo *win, HDC hdc) { + if (win->mouseAction == MA_SELECTING) { + // during selecting + RectI selRect; + + selRect.x = min (win->selectionRect.x, + win->selectionRect.x + win->selectionRect.dx); + selRect.y = min (win->selectionRect.y, + win->selectionRect.y + win->selectionRect.dy); + selRect.dx = abs (win->selectionRect.dx); + selRect.dy = abs (win->selectionRect.dy); + + if (selRect.dx != 0 && selRect.dy != 0) + PaintTransparentRectangle (win, hdc, &selRect); + } else { + // after selection is done + SelectionOnPage *selOnPage = win->selectionOnPage; + // TODO: Move recalcing to better place + RecalcSelectionPosition(win); + while (selOnPage != NULL) { + if (selOnPage->selectionCanvas.dx != 0 && selOnPage->selectionCanvas.dy != 0) + PaintTransparentRectangle(win, hdc, &selOnPage->selectionCanvas); + selOnPage = selOnPage->next; + } + } +} + +static void WindowInfo_Paint(WindowInfo *win, HDC hdc, PAINTSTRUCT *ps) +{ + RECT bounds; + RenderedBitmap * renderedBmp = NULL; + + assert(win); + if (!win) return; + DisplayModel* dm = win->dm; + assert(dm); + if (!dm) return; +#if 0 // TODO: write the equivalent dm->isOk() ? + assert(dm->pdfDoc); + if (!dm->pdfDoc) return; +#endif + + assert(win->hdcToDraw); + hdc = win->hdcToDraw; + + FillRect(hdc, &(ps->rcPaint), gBrushBg); + + DBG_OUT("WindowInfo_Paint() "); + for (int pageNo = 1; pageNo <= dm->pageCount(); ++pageNo) { + PdfPageInfo *pageInfo = dm->getPageInfo(pageNo); + if (!pageInfo->visible) + continue; + assert(pageInfo->shown); + if (!pageInfo->shown) + continue; + + //BitmapCacheEntry *entry = BitmapCache_Find(dm, pageNo, dm->zoomReal(), dm->rotation()); + BitmapCacheEntry *entry = BitmapCache_Find(dm, pageNo); + if (entry) { + if ((dm->rotation() != entry->rotation) || (dm->zoomReal() != entry->zoomLevel)) + entry = NULL; + else + renderedBmp = entry->bitmap; + } + + if (!renderedBmp) + DBG_OUT(" missing bitmap on visible page %d\n", pageNo); + + int xSrc = (int)pageInfo->bitmapX; + int ySrc = (int)pageInfo->bitmapY; + int bmpDx = (int)pageInfo->bitmapDx; + int bmpDy = (int)pageInfo->bitmapDy; + int xDest = (int)pageInfo->screenX; + int yDest = (int)pageInfo->screenY; + + if (!entry) { + /* TODO: assert is queued for rendering ? */ + HFONT fontRightTxt = Win32_Font_GetSimple(hdc, "Tahoma", 14); + HFONT origFont = (HFONT)SelectObject(hdc, fontRightTxt); /* Just to remember the orig font */ + bounds.left = xDest; + bounds.top = yDest; + bounds.right = xDest + bmpDx; + bounds.bottom = yDest + bmpDy; + FillRect(hdc, &bounds, gBrushWhite); + DrawCenteredText(hdc, &bounds, "Please wait - rendering..."); + DBG_OUT("drawing empty %d ", pageNo); + if (origFont) + SelectObject(hdc, origFont); + Win32_Font_Delete(fontRightTxt); + continue; + } + + if (BITMAP_CANNOT_RENDER == renderedBmp) { + bounds.left = xDest; + bounds.top = yDest; + bounds.right = xDest + bmpDx; + bounds.bottom = yDest + bmpDy; + FillRect(hdc, &bounds, gBrushWhite); + DrawCenteredText(hdc, &bounds, "Couldn't render the page"); + continue; + } + + DBG_OUT("page %d ", pageNo); + + int renderedBmpDx = renderedBmp->dx(); + int renderedBmpDy = renderedBmp->dy(); + int currPageDx = pageInfo->currDx; + int currPageDy = pageInfo->currDy; + HBITMAP hbmp = renderedBmp->createDIBitmap(hdc); + if (!hbmp) + continue; + + HDC bmpDC = CreateCompatibleDC(hdc); + if (bmpDC) { + SelectObject(bmpDC, hbmp); +#if 0 + if ((currPageDx != renderedBmpDx) || (currPageDy != renderedBmpDy)) + StretchBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, renderedBmpDx, renderedBmpDy, SRCCOPY); + else +#endif + BitBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, SRCCOPY); + DeleteDC(bmpDC); + } + DeleteObject(hbmp); + } + + if (win->showSelection) + PaintSelection(win, hdc); + + DBG_OUT("\n"); + if (!gDebugShowLinks) + return; + + RectI drawAreaRect; + /* debug code to visualize links */ + drawAreaRect.x = (int)dm->areaOffset.x; + drawAreaRect.y = (int)dm->areaOffset.y; + drawAreaRect.dx = dm->drawAreaSize.dxI(); + drawAreaRect.dy = dm->drawAreaSize.dyI(); + + for (int linkNo = 0; linkNo < dm->linkCount(); ++linkNo) { + PdfLink *pdfLink = dm->link(linkNo); + + RectI rectLink, intersect; + rectLink.x = pdfLink->rectCanvas.x; + rectLink.y = pdfLink->rectCanvas.y; + rectLink.dx = pdfLink->rectCanvas.dx; + rectLink.dy = pdfLink->rectCanvas.dy; + + if (RectI_Intersect(&rectLink, &drawAreaRect, &intersect)) { + RECT rectScreen; + rectScreen.left = (LONG) ((double)intersect.x - dm->areaOffset.x); + rectScreen.top = (LONG) ((double)intersect.y - dm->areaOffset.y); + rectScreen.right = rectScreen.left + rectLink.dx; + rectScreen.bottom = rectScreen.top + rectLink.dy; + FillRect(hdc, &rectScreen, gBrushLinkDebug); + DBG_OUT(" link on screen rotate=%d, (x=%d, y=%d, dx=%d, dy=%d)\n", + dm->rotation() + dm->pagesInfo[pdfLink->pageNo-1].rotation, + rectScreen.left, rectScreen.top, rect_dx(&rectScreen), rect_dy(&rectScreen)); + } + } +} + +/* TODO: change the name to DrawAbout. + Draws the about screen a remember some state for hyperlinking. + It transcribes the design I did in graphics software - hopeless + to understand without seeing the design. */ +#define ABOUT_RECT_PADDING 8 +#define ABOUT_RECT_BORDER_DX_DY 4 +#define ABOUT_LINE_OUTER_SIZE 2 +#define ABOUT_LINE_RECT_SIZE 5 +#define ABOUT_LINE_SEP_SIZE 1 +#define ABOUT_LEFT_RIGHT_SPACE_DX 8 +#define ABOUT_MARGIN_DX 10 +#define ABOUT_BOX_MARGIN_DY 6 + +#define ABOUT_BORDER_COL COL_BLACK + +#define SUMATRA_TXT "Sumatra PDF" +#define SUMATRA_TXT_FONT "Arial Black" +#define SUMATRA_TXT_FONT_SIZE 24 +#define BETA_TXT "Beta v0.7" +#define BETA_TXT_FONT "Arial Black" +#define BETA_TXT_FONT_SIZE 12 +#define LEFT_TXT_FONT "Arial" +#define LEFT_TXT_FONT_SIZE 12 +#define RIGHT_TXT_FONT "Arial Black" +#define RIGHT_TXT_FONT_SIZE 12 + +#define ABOUT_BG_COLOR RGB(255,242,0) +#define ABOUT_RECT_BG_COLOR RGB(247,148,29) + +#define ABOUT_TXT_DY 6 + +typedef struct AboutLayoutInfoEl { + /* static data, must be provided */ + const char * leftTxt; + const char * rightTxt; + const char * url; + + /* data calculated by the layout */ + int leftTxtPosX; + int leftTxtPosY; + int leftTxtDx; + int leftTxtDy; + + int rightTxtPosX; + int rightTxtPosY; + int rightTxtDx; + int rightTxtDy; +} AboutLayoutInfoEl; + +AboutLayoutInfoEl gAboutLayoutInfo[] = { + { "design", "Krzysztof Kowalczyk", "http://blog.kowalczyk.info", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "programming", "Krzysztof Kowalczyk", "http://blog.kowalczyk.info", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "pdf rendering 1", "poppler + xpdf", "http://poppler.freedesktop.org/", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "pdf rendering 2", "MuPDF", "http://ccxvii.net/apparition/", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "license", "GPL v2", "http://www.gnu.org/copyleft/gpl.html", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "website", "http://blog.kowalczyk.info/software/sumatra", "http://blog.kowalczyk.info/software/sumatrapdf", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "forums", "http://blog.kowalczyk.info/forum_sumatra", "http://blog.kowalczyk.info/forum_sumatra", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "program icon", "Goce Mitevski", "http://monsteer.deviantart.com", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "toolbar icons", "Mark James", "http://www.famfamfam.com/lab/icons/silk/", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { NULL, NULL, NULL, + 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +static const char *AboutGetLink(WindowInfo *win, int x, int y) +{ + for (int i = 0; gAboutLayoutInfo[i].leftTxt; i++) { + if ((x < gAboutLayoutInfo[i].rightTxtPosX) || + (x > gAboutLayoutInfo[i].rightTxtPosX + gAboutLayoutInfo[i].rightTxtDx)) + continue; + if ((y < gAboutLayoutInfo[i].rightTxtPosY) || + (y > gAboutLayoutInfo[i].rightTxtPosY + gAboutLayoutInfo[i].rightTxtDy)) + continue; + return gAboutLayoutInfo[i].url; + } + return NULL; +} + +static void DrawAbout(HWND hwnd, HDC hdc, PAINTSTRUCT *ps) +{ + RECT rcTmp; + SIZE txtSize; + int totalDx, totalDy; + int leftDy, rightDy; + int leftLargestDx, rightLargestDx; + int sumatraPdfTxtDx, sumatraPdfTxtDy; + int betaTxtDx, betaTxtDy; + int linePosX, linePosY, lineDy; + int currY; + int fontDyDiff; + int offX, offY; + int x, y; + int boxDy; + + DString str; + DStringInit(&str); + + HBRUSH brushBg = CreateSolidBrush(ABOUT_BG_COLOR); + HBRUSH brushRectBg = CreateSolidBrush(ABOUT_RECT_BG_COLOR); + + HPEN penRectBorder = CreatePen(PS_SOLID, ABOUT_RECT_BORDER_DX_DY, COL_BLACK); + HPEN penBorder = CreatePen(PS_SOLID, ABOUT_LINE_OUTER_SIZE, COL_BLACK); + HPEN penDivideLine = CreatePen(PS_SOLID, ABOUT_LINE_SEP_SIZE, COL_BLACK); + + RECT rc; + GetClientRect(hwnd, &rc); + + int areaDx = rect_dx(&rc); + int areaDy = rect_dy(&rc); + + HFONT fontSumatraTxt = Win32_Font_GetSimple(hdc, SUMATRA_TXT_FONT, SUMATRA_TXT_FONT_SIZE); + HFONT fontBetaTxt = Win32_Font_GetSimple(hdc, BETA_TXT_FONT, BETA_TXT_FONT_SIZE); + HFONT fontLeftTxt = Win32_Font_GetSimple(hdc, LEFT_TXT_FONT, LEFT_TXT_FONT_SIZE); + HFONT fontRightTxt = Win32_Font_GetSimple(hdc, RIGHT_TXT_FONT, RIGHT_TXT_FONT_SIZE); + + HFONT origFont = (HFONT)SelectObject(hdc, fontSumatraTxt); /* Just to remember the orig font */ + + SetBkMode(hdc, TRANSPARENT); + + /* Layout stuff */ + const char *txt = SUMATRA_TXT; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ + sumatraPdfTxtDx = txtSize.cx; + sumatraPdfTxtDy = txtSize.cy; + + boxDy = sumatraPdfTxtDy + ABOUT_BOX_MARGIN_DY * 2; + txt = BETA_TXT; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ + betaTxtDx = txtSize.cx; + betaTxtDy = txtSize.cy; + + (HFONT)SelectObject(hdc, fontLeftTxt); + leftLargestDx = 0; + leftDy = 0; + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].leftTxt; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ + gAboutLayoutInfo[i].leftTxtDx = (int)txtSize.cx; + gAboutLayoutInfo[i].leftTxtDy = (int)txtSize.cy; + if (0 == i) + leftDy = gAboutLayoutInfo[i].leftTxtDy; + else + assert(leftDy == gAboutLayoutInfo[i].leftTxtDy); + if (leftLargestDx < gAboutLayoutInfo[i].leftTxtDx) + leftLargestDx = gAboutLayoutInfo[i].leftTxtDx; + } + + (HFONT)SelectObject(hdc, fontRightTxt); + rightLargestDx = 0; + rightDy = 0; + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].rightTxt; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ + gAboutLayoutInfo[i].rightTxtDx = (int)txtSize.cx; + gAboutLayoutInfo[i].rightTxtDy = (int)txtSize.cy; + if (0 == i) + rightDy = gAboutLayoutInfo[i].rightTxtDy; + else + assert(rightDy == gAboutLayoutInfo[i].rightTxtDy); + if (rightLargestDx < gAboutLayoutInfo[i].rightTxtDx) + rightLargestDx = gAboutLayoutInfo[i].rightTxtDx; + } + + fontDyDiff = (rightDy - leftDy) / 2; + + /* in the x order */ + totalDx = ABOUT_LINE_OUTER_SIZE + ABOUT_MARGIN_DX + leftLargestDx; + totalDx += ABOUT_LEFT_RIGHT_SPACE_DX + ABOUT_LINE_SEP_SIZE + ABOUT_LEFT_RIGHT_SPACE_DX; + totalDx += rightLargestDx + ABOUT_MARGIN_DX + ABOUT_LINE_OUTER_SIZE; + + totalDy = 0; + totalDy += boxDy; + totalDy += ABOUT_LINE_OUTER_SIZE; + totalDy += (dimof(gAboutLayoutInfo)-1) * (rightDy + ABOUT_TXT_DY); + totalDy += ABOUT_LINE_OUTER_SIZE + 4; + + offX = (areaDx - totalDx) / 2; + offY = (areaDy - totalDy) / 2; + + rcTmp.left = offX; + rcTmp.top = offY; + rcTmp.right = totalDx + offX; + rcTmp.bottom = totalDy + offY; + + FillRect(hdc, &rc, brushBg); + + SelectObject(hdc, brushBg); + SelectObject(hdc, penBorder); + + Rectangle(hdc, offX, offY + ABOUT_LINE_OUTER_SIZE, offX + totalDx, offY + boxDy + ABOUT_LINE_OUTER_SIZE); + + SetTextColor(hdc, ABOUT_BORDER_COL); + (HFONT)SelectObject(hdc, fontSumatraTxt); + x = offX + (totalDx - sumatraPdfTxtDx) / 2; + y = offY + (boxDy - sumatraPdfTxtDy) / 2; + txt = SUMATRA_TXT; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ + + //SetTextColor(hdc, ABOUT_RECT_BG_COLOR); + (HFONT)SelectObject(hdc, fontBetaTxt); + //SelectObject(hdc, brushRectBg); + x = offX + (totalDx - sumatraPdfTxtDx) / 2 + sumatraPdfTxtDx + 6; + y = offY + (boxDy - sumatraPdfTxtDy) / 2; + txt = BETA_TXT; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ + SetTextColor(hdc, ABOUT_BORDER_COL); + + offY += boxDy; + Rectangle(hdc, offX, offY, offX + totalDx, offY + totalDy - boxDy); + + linePosX = ABOUT_LINE_OUTER_SIZE + ABOUT_MARGIN_DX + leftLargestDx + ABOUT_LEFT_RIGHT_SPACE_DX; + linePosY = 4; + lineDy = (dimof(gAboutLayoutInfo)-1) * (rightDy + ABOUT_TXT_DY); + + /* render text on the left*/ + currY = linePosY; + (HFONT)SelectObject(hdc, fontLeftTxt); + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].leftTxt; + x = linePosX + offX - ABOUT_LEFT_RIGHT_SPACE_DX - gAboutLayoutInfo[i].leftTxtDx; + y = currY + fontDyDiff + offY; + gAboutLayoutInfo[i].leftTxtPosX = x; + gAboutLayoutInfo[i].leftTxtPosY = y; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ + currY += rightDy + ABOUT_TXT_DY; + } + + /* render text on the rigth */ + currY = linePosY; + (HFONT)SelectObject(hdc, fontRightTxt); + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].rightTxt; + x = linePosX + offX + ABOUT_LEFT_RIGHT_SPACE_DX; + y = currY + offY; + gAboutLayoutInfo[i].rightTxtPosX = x; + gAboutLayoutInfo[i].rightTxtPosY = y; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ + currY += rightDy + ABOUT_TXT_DY; + } + + SelectObject(hdc, penDivideLine); + MoveToEx(hdc, linePosX + offX, linePosY + offY, NULL); + LineTo(hdc, linePosX + offX, linePosY + lineDy + offY); + + if (origFont) + SelectObject(hdc, origFont); + + Win32_Font_Delete(fontSumatraTxt); + Win32_Font_Delete(fontBetaTxt); + Win32_Font_Delete(fontLeftTxt); + Win32_Font_Delete(fontRightTxt); + + DeleteObject(brushBg); + DeleteObject(brushRectBg); + DeleteObject(penBorder); + DeleteObject(penDivideLine); + DeleteObject(penRectBorder); +} + +static void WinMoveDocBy(WindowInfo *win, int dx, int dy) +{ + assert(win); + if (!win) return; + assert (WS_SHOWING_PDF == win->state); + if (WS_SHOWING_PDF != win->state) return; + assert(win->dm); + if (!win->dm) return; + assert(!win->linkOnLastButtonDown); + if (win->linkOnLastButtonDown) return; + if (0 != dx) + win->dm->scrollXBy(dx); + if (0 != dy) + win->dm->scrollYBy(dy, FALSE); +} + +static void CopySelectionTextToClipboard(WindowInfo *win) +{ + SelectionOnPage * selOnPage; + + assert(win); + if (!win) return; + + if (!win->selectionOnPage) return; + + HGLOBAL handle; + unsigned short *ucsbuf; + int ucsbuflen = 4096; + + if (!OpenClipboard(NULL)) return; + + EmptyClipboard(); + + handle = GlobalAlloc(GMEM_MOVEABLE, ucsbuflen * sizeof(unsigned short)); + if (!handle) { + CloseClipboard(); + return; + } + ucsbuf = (unsigned short *) GlobalLock(handle); + + selOnPage = win->selectionOnPage; + + int copied = 0; + while (selOnPage != NULL) { + int charCopied = win->dm->getTextInRegion(selOnPage->pageNo, + &selOnPage->selectionPage, ucsbuf + copied, ucsbuflen - copied - 1); + copied += charCopied; + if (ucsbuflen - copied == 1) + break; + selOnPage = selOnPage->next; + } + ucsbuf[copied] = 0; + + GlobalUnlock(handle); + + SetClipboardData(CF_UNICODETEXT, handle); + CloseClipboard(); +} + +static void DeleteOldSelectionInfo (WindowInfo *win) { + SelectionOnPage *selOnPage = win->selectionOnPage; + while (selOnPage != NULL) { + SelectionOnPage *tmp = selOnPage->next; + free(selOnPage); + selOnPage = tmp; + } + win->selectionOnPage = NULL; +} + +static void ConvertSelectionRectToSelectionOnPage (WindowInfo *win) { + RectI pageOnScreen, intersect; + + for (int pageNo = win->dm->pageCount(); pageNo >= 1; --pageNo) { + PdfPageInfo *pageInfo = win->dm->getPageInfo(pageNo); + if (!pageInfo->visible) + continue; + assert(pageInfo->shown); + if (!pageInfo->shown) + continue; + + pageOnScreen.x = pageInfo->screenX; + pageOnScreen.y = pageInfo->screenY; + pageOnScreen.dx = pageInfo->bitmapDx; + pageOnScreen.dy = pageInfo->bitmapDy; + + if (!RectI_Intersect(&win->selectionRect, &pageOnScreen, &intersect)) + continue; + + /* selection intersects with a page on the screen */ + SelectionOnPage *selOnPage = (SelectionOnPage*)malloc(sizeof(SelectionOnPage)); + RectD_FromRectI(&selOnPage->selectionPage, &intersect); + + win->dm->rectCvtScreenToUser (&selOnPage->pageNo, &selOnPage->selectionPage); + + assert (pageNo == selOnPage->pageNo); + + selOnPage->next = win->selectionOnPage; + win->selectionOnPage = selOnPage; + } +} + +static void OnMouseLeftButtonDown(WindowInfo *win, int x, int y) +{ + assert(win); + if (!win) return; + if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_IDLE) { + assert(win->dm); + if (!win->dm) return; + win->linkOnLastButtonDown = win->dm->linkAtPosition(x, y); + /* dragging mode only starts when we're not on a link */ + if (!win->linkOnLastButtonDown) { + SetCapture(win->hwndCanvas); + win->mouseAction = MA_DRAGGING; + win->dragPrevPosX = x; + win->dragPrevPosY = y; + SetCursor(gCursorDrag); + DBG_OUT(" dragging start, x=%d, y=%d\n", x, y); + } + } else if (WS_ABOUT == win->state) { + win->url = AboutGetLink(win, x, y); + } +} + +static void OnMouseLeftButtonUp(WindowInfo *win, int x, int y) +{ + PdfLink * link; + const char * url; + int dragDx, dragDy; + + assert(win); + if (!win) return; + + if (WS_ABOUT == win->state) { + url = AboutGetLink(win, x, y); + if (url == win->url) + LaunchBrowser(url); + win->url = NULL; + return; + } + + if (WS_SHOWING_PDF != win->state) + return; + + assert(win->dm); + if (!win->dm) return; + + if (win->mouseAction == MA_DRAGGING && (GetCapture() == win->hwndCanvas)) { + dragDx = 0; dragDy = 0; + dragDx = x - win->dragPrevPosX; + dragDy = y - win->dragPrevPosY; + DBG_OUT(" dragging ends, x=%d, y=%d, dx=%d, dy=%d\n", x, y, dragDx, dragDy); + assert(!win->linkOnLastButtonDown); + WinMoveDocBy(win, dragDx, -dragDy*2); + win->dragPrevPosX = x; + win->dragPrevPosY = y; + win->mouseAction = MA_IDLE; + SetCursor(gCursorArrow); + ReleaseCapture(); + return; + } + + if (!win->linkOnLastButtonDown) + return; + + link = win->dm->linkAtPosition(x, y); + if (link && (link == win->linkOnLastButtonDown)) + win->dm->handleLink(link); + win->linkOnLastButtonDown = NULL; +} + +static void OnMouseMove(WindowInfo *win, int x, int y, WPARAM flags) +{ + PdfLink * link; + const char * url; + int dragDx, dragDy; + + assert(win); + if (!win) return; + + if (WS_SHOWING_PDF == win->state) { + assert(win->dm); + if (!win->dm) return; + if (win->mouseAction == MA_SELECTING) { + SetCursor(gCursorArrow); + win->selectionRect.dx = x - win->selectionRect.x; + win->selectionRect.dy = y - win->selectionRect.y; + triggerRepaintDisplayNow(win); + } else { + if (win->mouseAction == MA_DRAGGING) { + dragDx = 0; dragDy = 0; + dragDx = -(x - win->dragPrevPosX); + dragDy = -(y - win->dragPrevPosY); + DBG_OUT(" drag move, x=%d, y=%d, dx=%d, dy=%d\n", x, y, dragDx, dragDy); + WinMoveDocBy(win, dragDx, dragDy*2); + win->dragPrevPosX = x; + win->dragPrevPosY = y; + return; + } + link = win->dm->linkAtPosition(x, y); + if (link) + SetCursor(gCursorHand); + else + SetCursor(gCursorArrow); + } + } else if (WS_ABOUT == win->state) { + url = AboutGetLink(win, x, y); + if (url) { + SetCursor(gCursorHand); + } else { + SetCursor(gCursorArrow); + } + } else { + // TODO: be more efficient, this only needs to be set once (I think) + SetCursor(gCursorArrow); + } +} + +static void OnMouseRightButtonDown(WindowInfo *win, int x, int y) +{ + //DBG_OUT("Right button clicked on %d %d\n", x, y); + assert (win); + if (!win) return; + + if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_IDLE) { + win->documentBlocked = true; + DeleteOldSelectionInfo (win); + + win->selectionRect.x = x; + win->selectionRect.y = y; + win->selectionRect.dx = 0; + win->selectionRect.dy = 0; + win->showSelection = true; + win->mouseAction = MA_SELECTING; + + triggerRepaintDisplayNow(win); + } +} + +static void OnMouseRightButtonUp(WindowInfo *win, int x, int y) +{ + assert (win); + if (!win) return; + + if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_SELECTING) { + assert (win->dm); + if (!win->dm) return; + win->documentBlocked = false; + + win->selectionRect.dx = abs (x - win->selectionRect.x); + win->selectionRect.dy = abs (y - win->selectionRect.y); + win->selectionRect.x = min (win->selectionRect.x, x); + win->selectionRect.y = min (win->selectionRect.y, y); + + win->mouseAction = MA_IDLE; + if (win->selectionRect.dx == 0 || win->selectionRect.dy == 0) { + win->showSelection = false; + } else { + ConvertSelectionRectToSelectionOnPage (win); + CopySelectionTextToClipboard (win); + } + triggerRepaintDisplayNow(win); + } +} + +#define ABOUT_ANIM_TIMER_ID 15 + +static void AnimState_AnimStop(AnimState *state) +{ + KillTimer(state->hwnd, ABOUT_ANIM_TIMER_ID); +} + +static void AnimState_NextFrame(AnimState *state) +{ + state->frame += 1; + InvalidateRect(state->hwnd, NULL, FALSE); + UpdateWindow(state->hwnd); +} + +static void AnimState_AnimStart(AnimState *state, HWND hwnd, UINT freqInMs) +{ + assert(IsWindow(hwnd)); + AnimState_AnimStop(state); + state->frame = 0; + state->hwnd = hwnd; + SetTimer(state->hwnd, ABOUT_ANIM_TIMER_ID, freqInMs, NULL); + AnimState_NextFrame(state); +} + +#define ANIM_FONT_NAME "Georgia" +#define ANIM_FONT_SIZE_START 20 +#define SCROLL_SPEED 3 + +static void DrawAnim2(WindowInfo *win, HDC hdc, PAINTSTRUCT *ps) +{ + AnimState * state = &(win->animState); + DString txt; + RECT rc; + HFONT fontArial24 = NULL; + HFONT origFont = NULL; + int curFontSize; + static int curTxtPosX = -1; + static int curTxtPosY = -1; + static int curDir = SCROLL_SPEED; + + GetClientRect(win->hwndCanvas, &rc); + + DStringInit(&txt); + + if (-1 == curTxtPosX) + curTxtPosX = 40; + if (-1 == curTxtPosY) + curTxtPosY = 25; + + int areaDx = rect_dx(&rc); + int areaDy = rect_dy(&rc); + +#if 0 + if (state->frame % 24 <= 12) { + curFontSize = ANIM_FONT_SIZE_START + (state->frame % 24); + } else { + curFontSize = ANIM_FONT_SIZE_START + 12 - (24 - (state->frame % 24)); + } +#else + curFontSize = ANIM_FONT_SIZE_START; +#endif + + curTxtPosY += curDir; + if (curTxtPosY < 20) + curDir = SCROLL_SPEED; + else if (curTxtPosY > areaDy - 40) + curDir = -SCROLL_SPEED; + + fontArial24 = Win32_Font_GetSimple(hdc, ANIM_FONT_NAME, curFontSize); + assert(fontArial24); + + origFont = (HFONT)SelectObject(hdc, fontArial24); + + SetBkMode(hdc, TRANSPARENT); + FillRect(hdc, &rc, gBrushBg); + //DStringSprintf(&txt, "Welcome to animation %d", state->frame); + DStringSprintf(&txt, "Welcome to animation"); + //DrawText (hdc, txt.pString, -1, &rc, DT_SINGLELINE); + TextOut(hdc, curTxtPosX, curTxtPosY, (TCHAR*)txt.pString, txt.length); /* @author: Klemens Friedl; TCHAR* cast */ + WindowInfo_DoubleBuffer_Show(win, hdc); + if (state->frame > 99) + state->frame = 0; + + if (origFont) + SelectObject(hdc, origFont); + Win32_Font_Delete(fontArial24); +} + +static void WindowInfo_DoubleBuffer_Resize_IfNeeded(WindowInfo *win) +{ + WinResizeIfNeeded(win, false); +} + +static void OnPaintAbout(HWND hwnd) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + SetBkMode(hdc, TRANSPARENT); + DrawAbout(hwnd, hdc, &ps); + EndPaint(hwnd, &ps); +} + +static void OnPaint(WindowInfo *win) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(win->hwndCanvas, &ps); + + SetBkMode(hdc, TRANSPARENT); + RECT rc; + GetClientRect(win->hwndCanvas, &rc); + + if (WS_ABOUT == win->state) { + WindowInfo_DoubleBuffer_Resize_IfNeeded(win); + DrawAbout(win->hwndCanvas, win->hdcToDraw, &ps); + WindowInfo_DoubleBuffer_Show(win, hdc); + } else if (WS_ERROR_LOADING_PDF == win->state) { + HFONT fontRightTxt = Win32_Font_GetSimple(hdc, "Tahoma", 14); + HFONT origFont = (HFONT)SelectObject(hdc, fontRightTxt); /* Just to remember the orig font */ + FillRect(hdc, &ps.rcPaint, gBrushBg); + /* @author: Klemens Friedl; translation function and it's related macros need some care */ + //DrawText(hdc, _TR("Error loading PDF file."), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; + DrawText(hdc, TEXT("Error loading PDF file."), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; + if (origFont) + SelectObject(hdc, origFont); + Win32_Font_Delete(fontRightTxt); + } else if (WS_SHOWING_PDF == win->state) { + //TODO: it might cause infinite loop due to showing/hiding scrollbars + WinResizeIfNeeded(win); + WindowInfo_Paint(win, hdc, &ps); +#if 0 + if (VS_AMIGA == gVisualStyle) + AmigaCaptionDraw(win); +#endif + WindowInfo_DoubleBuffer_Show(win, hdc); + } else + assert(0); + + EndPaint(win->hwndCanvas, &ps); +} + +static void OnMenuExit(void) +{ + Prefs_Save(); + PostQuitMessage(0); +} + +/* Close the document associated with window 'hwnd'. + Closes the window unless this is the last window in which + case it switches to empty window and disables the "File\Close" + menu item. */ +static void CloseWindow(WindowInfo *win, bool quitIfLast) +{ + assert(win); + if (!win) return; + + bool lastWindow = false; + if (gRunningDLL) { + lastWindow = true; + } else { + if (1 == WindowInfoList_Len()) + lastWindow = true; + + if (lastWindow) + Prefs_Save(); + else + UpdateCurrentFileDisplayStateForWin(win); + } + + win->state = WS_ABOUT; + + if (lastWindow && !quitIfLast) { + /* last window - don't delete it */ + delete win->dm; + win->dm = NULL; + WindowInfo_RedrawAll(win); + } else { + HWND hwndToDestroy = win->hwndFrame; + WindowInfoList_Remove(win); + WindowInfo_Delete(win); + DragAcceptFiles(hwndToDestroy, FALSE); + DestroyWindow(hwndToDestroy); + } + + if (lastWindow && quitIfLast) { + assert(0 == WindowInfoList_Len()); + PostQuitMessage(0); + } else { + if (!gRunningDLL) + MenuToolbarUpdateStateForAllWindows(); + } +} + +/* Zoom document in window 'hwnd' to zoom level 'zoom'. + 'zoom' is given as a floating-point number, 1.0 is 100%, 2.0 is 200% etc. +*/ +static void OnMenuZoom(WindowInfo *win, UINT menuId) +{ + if (!win->dm) + return; + + double zoom = ZoomMenuItemToZoom(menuId); + win->dm->zoomTo(zoom); + ZoomMenuItemCheck(GetMenu(win->hwndFrame), menuId); +} + +static bool CheckPrinterStretchDibSupport(HWND hwndForMsgBox, HDC hdc) +{ + // most printers can support stretchdibits, + // whereas a lot of printers do not support bitblt + // quit if printer doesn't support StretchDIBits + int rasterCaps = GetDeviceCaps(hdc, RASTERCAPS); + int supportsStretchDib = rasterCaps & RC_STRETCHDIB; + if (supportsStretchDib) + return true; + + MessageBox(hwndForMsgBox, TEXT("This printer doesn't support StretchDIBits function"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + return false; +} + +// TODO: make it run in a background thread by constructing new PdfEngine() +// from a file name - this should be thread safe +static void PrintToDevice(DisplayModel *dm, HDC hdc, LPDEVMODE devMode, int fromPage, int toPage) { + + assert(toPage >= fromPage); + assert(dm); + if (!dm) return; + + PdfEngine *pdfEngine = dm->pdfEngine(); + DOCINFO di = {0}; + di.cbSize = sizeof (DOCINFO); + di.lpszDocName = (LPCTSTR)pdfEngine->fileName(); + + if (StartDoc(hdc, &di) <= 0) + return; + + // rendering for the same DisplayModel is not thread-safe + // TODO: in fitz, propably rendering anything might not be thread-safe + RenderQueue_RemoveForDisplayModel(dm); + cancelRenderingForDisplayModel(dm); + + // print all the pages the user requested unless + // bContinue flags there is a problem. + for (int pageNo = fromPage; pageNo <= toPage; pageNo++) { + int rotation = pdfEngine->pageRotation(pageNo); + + DBG_OUT(" printing: drawing bitmap for page %d\n", pageNo); + + // render at a big zoom, 250% should be good enough. It's a compromise + // between quality and memory usage. TODO: ideally we would use zoom + // that matches the size of the page in the printer + // TODO: consider using a greater zoom level e.g. 750.0 + RenderedBitmap *bmp = pdfEngine->renderBitmap(pageNo, 250.0, rotation, NULL, NULL); + if (!bmp) + goto Error; /* most likely ran out of memory */ + + StartPage(hdc); + // MM_TEXT: Each logical unit is mapped to one device pixel. + // Positive x is to the right; positive y is down. + SetMapMode(hdc, MM_TEXT); + + int pageHeight = GetDeviceCaps(hdc, PHYSICALHEIGHT); + int pageWidth = GetDeviceCaps(hdc, PHYSICALWIDTH); + + int topMargin = GetDeviceCaps(hdc, PHYSICALOFFSETY); + int leftMargin = GetDeviceCaps(hdc, PHYSICALOFFSETX); + if (DMORIENT_LANDSCAPE == devMode->dmOrientation) + swap_int(&topMargin, &leftMargin); + + bmp->stretchDIBits(hdc, -leftMargin, -topMargin, pageWidth, pageHeight); + delete bmp; + if (EndPage(hdc) <= 0) { + AbortDoc(hdc); + return; + } + } + +Error: + EndDoc(hdc); +} + +/* Show Print Dialog box to allow user to select the printer +and the pages to print. + +Creates a new dummy page for each page with a large zoom factor, +and then uses StretchDIBits to copy this to the printer's dc. + +So far have tested printing from XP to + - Acrobat Professional 6 (note that acrobat is usually set to + downgrade the resolution of its bitmaps to 150dpi) + - HP Laserjet 2300d + - HP Deskjet D4160 + - Lexmark Z515 inkjet, which should cover most bases. +*/ +static void OnMenuPrint(WindowInfo *win) +{ + PRINTDLG pd; + + assert(win); + if (!win) return; + + DisplayModel *dm = win->dm; + assert(dm); + if (!dm) return; + + /* printing uses the WindowInfo win that is created for the + screen, it may be possible to create a new WindowInfo + for printing to so we don't mess with the screen one, + but the user is not inconvenienced too much, and this + way we only need to concern ourselves with one dm. + TODO: don't re-use WindowInfo, use a different, synchronious + way of creating a bitmap */ + ZeroMemory(&pd, sizeof(pd)); + pd.lStructSize = sizeof(pd); + pd.hwndOwner = win->hwndFrame; + pd.hDevMode = NULL; + pd.hDevNames = NULL; + pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; + pd.nCopies = 1; + /* by default print all pages */ + pd.nFromPage = 1; + pd.nToPage = dm->pageCount(); + pd.nMinPage = 1; + pd.nMaxPage = dm->pageCount(); + + BOOL pressedOk = PrintDlg(&pd); + if (!pressedOk) { + if (CommDlgExtendedError()) { + /* if PrintDlg was cancelled then + CommDlgExtendedError is zero, otherwise it returns the + error code, which we could look at here if we wanted. + for now just warn the user that printing has stopped + becasue of an error */ + MessageBox(win->hwndFrame, TEXT("Cannot initialise printer"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + } /* @author: Klemens Friedl; TEXT() casts */ + return; + } + + if (CheckPrinterStretchDibSupport(win->hwndFrame, pd.hDC)) + PrintToDevice(dm, pd.hDC, (LPDEVMODE)pd.hDevMode, pd.nFromPage, pd.nToPage); + + DeleteDC(pd.hDC); + if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); + if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); +} + +static void OnMenuSaveAs(WindowInfo *win) +{ + OPENFILENAME ofn = {0}; + char dstFileName[MAX_PATH] = {0}; + const char* srcFileName = NULL; + + assert(win); + if (!win) return; + assert(win->dm); + if (!win->dm) return; + + srcFileName = win->dm->fileName(); + assert(srcFileName); + if (!srcFileName) return; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = win->hwndFrame; + ofn.lpstrFile = (TCHAR*)dstFileName; + + // Set lpstrFile[0] to '\0' so that GetOpenFileName does not + // use the contents of szFile to initialize itself. + ofn.lpstrFile[0] = '\0'; + ofn.nMaxFile = dimof(dstFileName); + ofn.lpstrFilter = TEXT("PDF\0*.pdf\0All\0*.*\0"); /* @author: Klemens Friedl; TEXT() casts */ + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT; + + if (FALSE == GetSaveFileName(&ofn)) + return; + + char* realDstFileName = dstFileName; + if (!str_endswithi(dstFileName, ".pdf")) { + realDstFileName = str_cat(dstFileName, ".pdf"); + } + BOOL cancelled = FALSE; + BOOL ok = CopyFileEx((TCHAR*)srcFileName, (TCHAR*)realDstFileName, NULL, NULL, &cancelled, COPY_FILE_FAIL_IF_EXISTS); /* @author: Klemens Friedl; TCHAR* cast */ + if (!ok) { + SeeLastError(); + /* @author: Klemens Friedl; translation needs some care */ + //MessageBox(win->hwndFrame, _TR("Failed to save a file"), TEXT("Information"), MB_OK); + MessageBox(win->hwndFrame, TEXT("Failed to save a file"), TEXT("Information"), MB_OK); + } + if (realDstFileName != dstFileName) + free(realDstFileName); +} + +static void OnMenuOpen(WindowInfo *win) +{ + OPENFILENAME ofn = {0}; + char fileName[PATH_MAX]; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = win->hwndFrame; + ofn.lpstrFile = (TCHAR*)fileName; /* @author: Klemens Friedl; TCHAR* cast */ + + // Set lpstrFile[0] to '\0' so that GetOpenFileName does not + // use the contents of szFile to initialize itself. + ofn.lpstrFile[0] = '\0'; + ofn.nMaxFile = sizeof(fileName); + ofn.lpstrFilter = TEXT("PDF\0*.pdf\0All\0*.*\0"); + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if (FALSE == GetOpenFileName(&ofn)) + return; + + win = LoadPdf(fileName); + if (!win) + return; +} + +static void RotateLeft(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->rotateBy(-90); +} + +static void RotateRight(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->rotateBy(90); +} + +static void OnVScroll(WindowInfo *win, WPARAM wParam) +{ + if (win->documentBlocked) return; + SCROLLINFO si = {0}; + int iVertPos; + + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo(win->hwndCanvas, SB_VERT, &si); + + iVertPos = si.nPos; + + switch (LOWORD(wParam)) + { + case SB_TOP: + si.nPos = si.nMin; + break; + + case SB_BOTTOM: + si.nPos = si.nMax; + break; + + case SB_LINEUP: + si.nPos -= 16; + break; + + case SB_LINEDOWN: + si.nPos += 16; + break; + + case SB_PAGEUP: + si.nPos -= si.nPage; + break; + + case SB_PAGEDOWN: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + // Set the position and then retrieve it. Due to adjustments + // by Windows it may not be the same as the value set. + si.fMask = SIF_POS; + SetScrollInfo(win->hwndCanvas, SB_VERT, &si, TRUE); + GetScrollInfo(win->hwndCanvas, SB_VERT, &si); + + // If the position has changed, scroll the window and update it + if (win->dm && (si.nPos != iVertPos)) + win->dm->scrollYTo(si.nPos); +} + +static void OnHScroll(WindowInfo *win, WPARAM wParam) +{ + if (win->documentBlocked) return; + SCROLLINFO si = {0}; + int iVertPos; + + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo(win->hwndCanvas, SB_HORZ, &si); + + iVertPos = si.nPos; + + switch (LOWORD(wParam)) + { + case SB_TOP: + si.nPos = si.nMin; + break; + + case SB_BOTTOM: + si.nPos = si.nMax; + break; + + case SB_LINEUP: + si.nPos -= 16; + break; + + case SB_LINEDOWN: + si.nPos += 16; + break; + + case SB_PAGEUP: + si.nPos -= si.nPage; + break; + + case SB_PAGEDOWN: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + // Set the position and then retrieve it. Due to adjustments + // by Windows it may not be the same as the value set. + si.fMask = SIF_POS; + SetScrollInfo(win->hwndCanvas, SB_HORZ, &si, TRUE); + GetScrollInfo(win->hwndCanvas, SB_HORZ, &si); + + // If the position has changed, scroll the window and update it + if (win->dm && (si.nPos != iVertPos)) + win->dm->scrollXTo(si.nPos); +} + +static void ViewWithAcrobat(WindowInfo *win) +{ + // TODO: write me +} + +static void OnMenuViewSinglePage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_SINGLE_PAGE); +} + +static void OnMenuViewFacing(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_FACING); +} + +static void OneMenuMakeDefaultReader(void) +{ + AssociateExeWithPdfExtensions(); + /* @author: Klemens Friedl; translation need some care */ + //MessageBox(NULL, _TR("SumatraPDF is now a default reader for PDF files."), "Information", MB_OK); + MessageBox(NULL, TEXT("SumatraPDF is now a default reader for PDF files."), TEXT("Information"), MB_OK); +} + +static void OnSize(WindowInfo *win, int dx, int dy) +{ + int rebBarDy = 0; + if (gShowToolbar) { + SetWindowPos(win->hwndReBar, NULL, 0, 0, dx, rebBarDy, SWP_NOZORDER); + rebBarDy = gReBarDy + gReBarDyFrame; + } + SetWindowPos(win->hwndCanvas, NULL, 0, rebBarDy, dx, dy-rebBarDy, SWP_NOZORDER); +} + +static void ReloadPdfDocument(WindowInfo *win) +{ + if (WS_SHOWING_PDF != win->state) + return; + const char *fileName = NULL; + if (win->dm) + fileName = (const char*)str_dup(win->dm->fileName()); + CloseWindow(win, false); + if (fileName) { + LoadPdf(fileName); + free((void*)fileName); + } +} + +static void RebuildProgramMenus(void) +{ + HMENU m = ForceRebuildMenu(); + WindowInfo *win = gWindowList; + while (win) { + SetMenu(win->hwndFrame, m); + MenuUpdateStateForWindow(win); + win = win->next; + } +} + +static void LanguageChanged(const char *langName) +{ + assert(!str_eq(langName, CurrLangNameGet())); + + CurrLangNameSet(langName); + + RebuildProgramMenus(); + // TODO: recreate tooltips +} + +static void OnMenuLanguage(int langId) +{ + const char *langName = NULL; + for (int i=0; i < LANGS_COUNT; i++) { + if (g_langs[i]._langId == langId) { + langName = g_langs[i]._langName; + break; + } + } + + assert(langName); + if (!langName) return; + if (str_eq(langName, CurrLangNameGet())) + return; + LanguageChanged(langName); +} + +static void OnMenuViewUseFitz(WindowInfo *win) +{ + assert(win); + DBG_OUT("OnMenuViewUseFitz()\n"); + if (gUseFitz) + gUseFitz = FALSE; + else + gUseFitz = TRUE; + + ReloadPdfDocument(win); + win = gWindowList; + while (win) { + MenuUpdateUseFitzStateForWindow(win); + win = win->next; + } +} + +static void OnMenuViewShowHideToolbar() +{ + if (gShowToolbar) + gShowToolbar = FALSE; + else + gShowToolbar = TRUE; + + WindowInfo* win = gWindowList; + while (win) { + if (gShowToolbar) + ShowWindow(win->hwndReBar, SW_SHOW); + else + ShowWindow(win->hwndReBar, SW_HIDE); + int dx, dy, x, y; + Win32_Win_GetPos(win->hwndFrame, &x, &y); + Win32_Win_GetSize(win->hwndFrame, &dx, &dy); + // TODO: a hack. I add 1 to dy to cause sending WM_SIZE msg to hwndFrame + // but I shouldn't really change the size. But I don't know how to + // cause sending WM_SIZE otherwise. I tried calling OnSize() directly, + // but it left scrollbar partially hidden + MoveWindow(win->hwndFrame, x, y, dx, dy+1, TRUE); + MenuUpdateShowToolbarStateForWindow(win); + win = win->next; + } +} + +static void OnMenuViewContinuous(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_CONTINUOUS); +} + +static void OnMenuViewContinuousFacing(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_CONTINUOUS_FACING); +} + +static void OnMenuGoToNextPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToNextPage(0); +} + +static void OnMenuGoToPrevPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToPrevPage(0); +} + +static void OnMenuGoToLastPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToLastPage(); +} + +static void OnMenuGoToFirstPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToFirstPage(); +} + +static void OnMenuGoToPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + + int newPageNo = Dialog_GoToPage(win); + if (win->dm->validPageNo(newPageNo)) + win->dm->goToPage(newPageNo, 0); +} + +static void OnMenuViewRotateLeft(WindowInfo *win) +{ + RotateLeft(win); +} + +static void OnMenuViewRotateRight(WindowInfo *win) +{ + RotateRight(win); +} + +#define KEY_PRESSED_MASK 0x8000 +static bool WasKeyDown(int virtKey) +{ + SHORT state = GetKeyState(virtKey); + if (KEY_PRESSED_MASK & state) + return true; + return false; +} + +static bool WasShiftPressed() +{ + return WasKeyDown(VK_LSHIFT) || WasKeyDown(VK_RSHIFT); +} + +static bool WasCtrlPressed() +{ + return WasKeyDown(VK_LCONTROL) || WasKeyDown(VK_RCONTROL); +} + +static void OnKeydown(WindowInfo *win, int key, LPARAM lparam) +{ + if (!win->dm) + return; + if (win->documentBlocked) + return; + + bool shiftPressed = WasShiftPressed(); + bool ctrlPressed = WasCtrlPressed(); + //DBG_OUT("key=%d,%c,shift=%d,ctrl=%d\n", key, (char)key, (int)shiftPressed, (int)ctrlPressed); + + if (VK_PRIOR == key) { + /* TODO: more intelligence (see VK_NEXT comment). Also, probably + it's exactly the same as 'n' so the code should be factored out */ + win->dm->goToPrevPage(0); + /* SendMessage (win->hwnd, WM_VSCROLL, SB_PAGEUP, 0); */ + } else if (VK_NEXT == key) { + /* TODO: this probably should be more intelligent (scroll if not yet at the bottom, + go to next page if at the bottom, and something entirely different in continuous mode */ + win->dm->goToNextPage(0); + /* SendMessage (win->hwnd, WM_VSCROLL, SB_PAGEDOWN, 0); */ + } else if (VK_UP == key) { + SendMessage (win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); + } else if (VK_DOWN == key) { + SendMessage (win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); + } else if (VK_LEFT == key) { + SendMessage (win->hwndCanvas, WM_HSCROLL, SB_PAGEUP, 0); + } else if (VK_RIGHT == key) { + SendMessage (win->hwndCanvas, WM_HSCROLL, SB_PAGEDOWN, 0); + } else if (VK_HOME == key) { + win->dm->goToFirstPage(); + } else if (VK_END == key) { + win->dm->goToLastPage(); +#if 0 // we do it via accelerators + } else if ('G' == key) { + if (ctrlPressed) + OnMenuGoToPage(win); +#endif + } else if (VK_OEM_PLUS == key) { + // Emulate acrobat: "Shift Ctrl +" is rotate clockwise + if (shiftPressed & ctrlPressed) + RotateRight(win); + } else if (VK_OEM_MINUS == key) { + // Emulate acrobat: "Shift Ctrl -" is rotate counter-clockwise + if (shiftPressed & ctrlPressed) + RotateLeft(win); + } +} + +static void OnChar(WindowInfo *win, int key) +{ + if (!win->dm) + return; + if (win->documentBlocked) + return; + +// DBG_OUT("char=%d,%c\n", key, (char)key); + + if (VK_SPACE == key) { + win->dm->scrollYByAreaDy(true, true); + } else if (VK_BACK == key) { + win->dm->scrollYByAreaDy(false, true); + } else if ('g' == key) { + OnMenuGoToPage(win); + } else if ('k' == key) { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); + } else if ('j' == key) { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); + } else if ('n' == key) { + win->dm->goToNextPage(0); + } else if ('c' == key) { + // TODO: probably should preserve facing vs. non-facing + win->dm->changeDisplayMode(DM_CONTINUOUS); + } else if ('p' == key) { + win->dm->goToPrevPage(0); + } else if ('z' == key) { + WindowInfo_ToggleZoom(win); + } else if ('q' == key) { + DestroyWindow(win->hwndFrame); + } else if ('+' == key) { + win->dm->zoomBy(ZOOM_IN_FACTOR); + } else if ('-' == key) { + win->dm->zoomBy(ZOOM_OUT_FACTOR); + } else if ('r' == key) { + ReloadPdfDocument(win); + } +} + +static inline bool IsEnumPrintersArg(const char *txt) +{ + if (str_ieq(txt, ENUM_PRINTERS_ARG_TXT)) + return true; + return false; +} + +static inline bool IsDontRegisterExtArg(const char *txt) +{ + if (str_ieq(txt, NO_REGISTER_EXT_ARG_TXT)) + return true; + return false; +} + +static inline bool IsPrintToArg(const char *txt) +{ + if (str_ieq(txt, PRINT_TO_ARG_TXT)) + return true; + return false; +} + +static inline bool IsPrintToDefaultArg(const char *txt) +{ + if (str_ieq(txt, PRINT_TO_ARG_TXT)) + return true; + return false; +} + +static inline bool IsExitOnPrintArg(const char *txt) +{ + if (str_ieq(txt, EXIT_ON_PRINT_ARG_TXT)) + return true; + return false; +} + +static inline bool IsBenchArg(const char *txt) +{ + if (str_ieq(txt, BENCH_ARG_TXT)) + return true; + return false; +} + +static bool IsBenchMode(void) +{ + if (NULL != gBenchFileName) + return true; + return false; +} + +/* Find a file in a file history list that has a given 'menuId'. + Return a copy of filename or NULL if couldn't be found. + It's used to figure out if a menu item selected by the user + is one of the "recent files" menu items in File menu. + Caller needs to free() the memory. + */ +static const char *RecentFileNameFromMenuItemId(UINT menuId) { + FileHistoryList* curr = gFileHistoryRoot; + while (curr) { + if (curr->menuId == menuId) + return str_dup(curr->state.filePath); + curr = curr->next; + } + return NULL; +} + +#define FRAMES_PER_SECS 60 +#define ANIM_FREQ_IN_MS 1000 / FRAMES_PER_SECS + +static void OnMenuAbout() { + if (gHwndAbout) { + SetActiveWindow(gHwndAbout); + return; + } + gHwndAbout = CreateWindow( + ABOUT_CLASS_NAME, (TCHAR*)ABOUT_WIN_TITLE, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + ABOUT_WIN_DX, ABOUT_WIN_DY, + NULL, NULL, + ghinst, NULL); /* @author: Klemens Friedl; TCHAR* cast */ + if (!gHwndAbout) + return; + ShowWindow(gHwndAbout, SW_SHOW); +} + +BOOL PrivateIsAppThemed() { + BOOL isThemed = FALSE; + HMODULE hDll = LoadLibrary(TEXT("uxtheme.dll")); /* @author: Klemens Friedl; TEXT() cast */ + if (!hDll) return FALSE; + + FARPROC fp = GetProcAddress(hDll, TEXT("IsAppThemed")); /* @author: Klemens Friedl; TEXT() cast */ + if (fp) + isThemed = fp(); + + FreeLibrary(hDll); + return isThemed; +} + +static TBBUTTON TbButtonFromButtonInfo(int i) { + TBBUTTON tbButton = {0}; + if (IDB_SEPARATOR == gToolbarButtons[i].cmdId) { + tbButton.fsStyle = TBSTYLE_SEP; + } else { + tbButton.iBitmap = gToolbarButtons[i].index; + tbButton.idCommand = gToolbarButtons[i].cmdId; + tbButton.fsState = TBSTATE_ENABLED; + tbButton.fsStyle = TBSTYLE_BUTTON; + tbButton.iString = (INT_PTR)gToolbarButtons[i].toolTip; + } + return tbButton; +} + +#define WS_TOOLBAR (WS_CHILD | WS_CLIPSIBLINGS | \ + TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | \ + TBSTYLE_LIST | CCS_NODIVIDER | CCS_NOPARENTALIGN ) + +static void CreateToolbar(WindowInfo *win, HINSTANCE hInst) { + BOOL bIsAppThemed = PrivateIsAppThemed(); + + HWND hwndOwner = win->hwndFrame; + HWND hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_TOOLBAR, + 0,0,0,0, hwndOwner,(HMENU)IDC_TOOLBAR, hInst,NULL); + win->hwndToolbar = hwndToolbar; + LRESULT lres = SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + + ShowWindow(hwndToolbar, SW_SHOW); + HIMAGELIST himl = 0; + TBBUTTON tbButtons[TOOLBAR_BUTTONS_COUNT]; + for (int i=0; i < TOOLBAR_BUTTONS_COUNT; i++) { + if (IDB_SEPARATOR != gToolbarButtons[i].bitmapResourceId) { + HBITMAP hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(gToolbarButtons[i].bitmapResourceId)); + if (!himl) { + BITMAP bmp; + GetObject(hbmp, sizeof(BITMAP), &bmp); + int dx = bmp.bmWidth; + int dy = bmp.bmHeight; + himl = ImageList_Create(dx, dy, ILC_COLORDDB | ILC_MASK, 0, 0); + } + int index = ImageList_AddMasked(himl, hbmp, RGB(255,0,255)); + DeleteObject(hbmp); + gToolbarButtons[i].index = index; + } + tbButtons[i] = TbButtonFromButtonInfo(i); + } + lres = SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl); + + // TODO: construct disabled image list as well? + //SendMessage(hwndToolbar, TB_SETDISABLEDIMAGELIST, 0, (LPARAM)himl); + + LRESULT exstyle = SendMessage(hwndToolbar, TB_GETEXTENDEDSTYLE, 0, 0); + exstyle |= TBSTYLE_EX_MIXEDBUTTONS; + lres = SendMessage(hwndToolbar, TB_SETEXTENDEDSTYLE, 0, exstyle); + + lres = SendMessage(hwndToolbar, TB_ADDBUTTONS, TOOLBAR_BUTTONS_COUNT, (LPARAM)tbButtons); + RECT rc; + lres = SendMessage(hwndToolbar, TB_GETITEMRECT, 0, (LPARAM)&rc); + + DWORD reBarStyle = WS_REBAR | WS_VISIBLE; + win->hwndReBar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, reBarStyle, + 0,0,0,0, hwndOwner, (HMENU)IDC_REBAR, hInst, NULL); + if (!win->hwndReBar) + SeeLastError(); + + REBARINFO rbi; + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + lres = SendMessage(win->hwndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi); + + REBARBANDINFO rbBand; + rbBand.cbSize = sizeof(REBARBANDINFO); + rbBand.fMask = /*RBBIM_COLORS | RBBIM_TEXT | RBBIM_BACKGROUND | */ + RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE /*| RBBIM_SIZE*/; + rbBand.fStyle = /*RBBS_CHILDEDGE |*//* RBBS_BREAK |*/ RBBS_FIXEDSIZE /*| RBBS_GRIPPERALWAYS*/; + if (bIsAppThemed) + rbBand.fStyle |= RBBS_CHILDEDGE; + rbBand.hbmBack = NULL; + rbBand.lpText = "Toolbar"; + rbBand.hwndChild = hwndToolbar; + rbBand.cxMinChild = (rc.right - rc.left) * TOOLBAR_BUTTONS_COUNT; + rbBand.cyMinChild = (rc.bottom - rc.top) + 2 * rc.top; + rbBand.cx = 0; + lres = SendMessage(win->hwndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); + + SetWindowPos(win->hwndReBar, NULL, 0, 0, 0, 0, SWP_NOZORDER); + GetWindowRect(win->hwndReBar, &rc); + gReBarDy = rc.bottom - rc.top; + //TODO: this was inherited but doesn't seem to be right (makes toolbar + // partially unpainted if using classic scheme on xp or vista + //gReBarDyFrame = bIsAppThemed ? 0 : 2; + gReBarDyFrame = 0; +} + +static LRESULT CALLBACK WndProcAbout(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + assert(!gHwndAbout); + break; + + case WM_ERASEBKGND: + // do nothing, helps to avoid flicker + return TRUE; + + case WM_PAINT: + OnPaintAbout(hwnd); + break; + + case WM_DESTROY: + assert(gHwndAbout); + gHwndAbout = NULL; + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +/* TODO: gAccumDelta must be per WindowInfo */ +static int gDeltaPerLine, gAccumDelta; // for mouse wheel logic + +static LRESULT CALLBACK WndProcCanvas(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WindowInfo * win; + win = WindowInfo_FindByHwnd(hwnd); + switch (message) + { + case WM_APP_REPAINT_DELAYED: + if (win) + SetTimer(win->hwndCanvas, REPAINT_TIMER_ID, REPAINT_DELAY_IN_MS, NULL); + break; + + case WM_APP_REPAINT_NOW: + if (win) + WindowInfo_RedrawAll(win); + break; + + case WM_VSCROLL: + OnVScroll(win, wParam); + return WM_VSCROLL_HANDLED; + + case WM_HSCROLL: + OnHScroll(win, wParam); + return WM_HSCROLL_HANDLED; + + case WM_MOUSEMOVE: + if (win) + OnMouseMove(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), wParam); + break; + + case WM_LBUTTONDOWN: + if (win) + OnMouseLeftButtonDown(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_LBUTTONUP: + if (win) + OnMouseLeftButtonUp(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_RBUTTONDOWN: + if (win) + OnMouseRightButtonDown(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_RBUTTONUP: + if (win) + OnMouseRightButtonUp(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_SETCURSOR: + if (win && win->mouseAction == MA_DRAGGING) { + SetCursor(gCursorDrag); + return TRUE; + } + break; + + case WM_TIMER: + assert(win); + if (win) { + if (REPAINT_TIMER_ID == wParam) + WindowInfo_RedrawAll(win); + else + AnimState_NextFrame(&win->animState); + } + break; + + case WM_DROPFILES: + if (win) + OnDropFiles(win, (HDROP)wParam); + break; + + case WM_ERASEBKGND: + // do nothing, helps to avoid flicker + return TRUE; + + case WM_PAINT: + /* it might happen that we get WM_PAINT after destroying a window */ + if (win) { + /* blindly kill the timer, just in case it's there */ + KillTimer(win->hwndCanvas, REPAINT_TIMER_ID); + OnPaint(win); + } + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +static LRESULT CALLBACK WndProcFrame(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + WindowInfo * win; + ULONG ulScrollLines; // for mouse wheel logic + const char * fileName; + + win = WindowInfo_FindByHwnd(hwnd); + + switch (message) + { + case WM_CREATE: + // do nothing + goto InitMouseWheelInfo; + + case WM_SIZE: + if (win) { + int dx = LOWORD(lParam); + int dy = HIWORD(lParam); + OnSize(win, dx, dy); + } + break; + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + fileName = RecentFileNameFromMenuItemId(wmId); + if (fileName) { + LoadPdf(fileName); + free((void*)fileName); + break; + } + + switch (wmId) + { + case IDM_OPEN: + case IDT_FILE_OPEN: + OnMenuOpen(win); + break; + case IDM_SAVEAS: + OnMenuSaveAs(win); + break; + + case IDT_FILE_PRINT: + case IDM_PRINT: + OnMenuPrint(win); + break; + + case IDM_MAKE_DEFAULT_READER: + OneMenuMakeDefaultReader(); + break; + + case IDT_FILE_EXIT: + case IDM_CLOSE: + CloseWindow(win, FALSE); + break; + + case IDM_EXIT: + OnMenuExit(); + break; + + case IDT_VIEW_ZOOMIN: + if (win->dm) + win->dm->zoomBy(ZOOM_IN_FACTOR); + break; + + case IDT_VIEW_ZOOMOUT: + if (win->dm) + win->dm->zoomBy(ZOOM_OUT_FACTOR); + break; + + case IDM_ZOOM_6400: + case IDM_ZOOM_3200: + case IDM_ZOOM_1600: + case IDM_ZOOM_800: + case IDM_ZOOM_400: + case IDM_ZOOM_200: + case IDM_ZOOM_150: + case IDM_ZOOM_125: + case IDM_ZOOM_100: + case IDM_ZOOM_50: + case IDM_ZOOM_25: + case IDM_ZOOM_12_5: + case IDM_ZOOM_8_33: + case IDM_ZOOM_FIT_PAGE: + case IDM_ZOOM_FIT_WIDTH: + case IDM_ZOOM_ACTUAL_SIZE: + OnMenuZoom(win, (UINT)wmId); + break; + + case IDM_ZOOM_FIT_VISIBLE: + /* TODO: implement me */ + break; + + case IDM_VIEW_SINGLE_PAGE: + OnMenuViewSinglePage(win); + break; + + case IDM_VIEW_FACING: + OnMenuViewFacing(win); + break; + + case IDM_VIEW_CONTINUOUS: + OnMenuViewContinuous(win); + break; + + case IDM_VIEW_SHOW_HIDE_TOOLBAR: + OnMenuViewShowHideToolbar(); + break; + + case IDM_VIEW_USE_FITZ: + OnMenuViewUseFitz(win); + break; + + case IDM_GOTO_NEXT_PAGE: + OnMenuGoToNextPage(win); + break; + + case IDM_GOTO_PREV_PAGE: + OnMenuGoToPrevPage(win); + break; + + case IDM_GOTO_FIRST_PAGE: + OnMenuGoToFirstPage(win); + break; + + case IDM_GOTO_LAST_PAGE: + OnMenuGoToLastPage(win); + break; + + case IDM_GOTO_PAGE: + OnMenuGoToPage(win); + break; + + case IDM_VIEW_CONTINUOUS_FACING: + OnMenuViewContinuousFacing(win); + break; + + case IDM_VIEW_ROTATE_LEFT: + OnMenuViewRotateLeft(win); + break; + + case IDM_VIEW_ROTATE_RIGHT: + OnMenuViewRotateRight(win); + break; + + case IDM_VISIT_WEBSITE: + LaunchBrowser(_T("http://blog.kowalczyk.info/software/sumatrapdf/")); + break; + + case IDM_LANG_EN: + case IDM_LANG_PL: + case IDM_LANG_FR: + case IDM_LANG_DE: + OnMenuLanguage((int)wmId); + break; + + case IDM_ABOUT: + OnMenuAbout(); + break; + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + break; + + case WM_CHAR: + if (win) + OnChar(win, wParam); + break; + + case WM_KEYDOWN: + if (win) + OnKeydown(win, wParam, lParam); + break; + + case WM_SETTINGCHANGE: +InitMouseWheelInfo: + SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &ulScrollLines, 0); + // ulScrollLines usually equals 3 or 0 (for no scrolling) + // WHEEL_DELTA equals 120, so iDeltaPerLine will be 40 + if (ulScrollLines) + gDeltaPerLine = WHEEL_DELTA / ulScrollLines; + else + gDeltaPerLine = 0; + return 0; + + // TODO: I don't understand why WndProcCanvas() doesn't receive this message + case WM_MOUSEWHEEL: + if (!win || !win->dm) /* TODO: check for pdfDoc as well ? */ + break; + + if (gDeltaPerLine == 0) + break; + + gAccumDelta += (short) HIWORD (wParam); // 120 or -120 + + while (gAccumDelta >= gDeltaPerLine) + { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); + gAccumDelta -= gDeltaPerLine; + } + + while (gAccumDelta <= -gDeltaPerLine) + { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); + gAccumDelta += gDeltaPerLine; + } + return 0; + + case WM_DROPFILES: + if (win) + OnDropFiles(win, (HDROP)wParam); + break; + + case WM_DESTROY: + /* WM_DESTROY might be sent as a result of File\Close, in which case CloseWindow() has already been called */ + if (win) + CloseWindow(win, TRUE); + break; + + case IDM_VIEW_WITH_ACROBAT: + if (win) + ViewWithAcrobat(win); + break; + + case MSG_BENCH_NEXT_ACTION: + if (win) + OnBenchNextAction(win); + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +static BOOL RegisterWinClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + ATOM atom; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProcFrame; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SUMATRAPDF)); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = FRAME_CLASS_NAME; + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); + atom = RegisterClassEx(&wcex); + if (!atom) + return FALSE; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProcCanvas; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = 0; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = CANVAS_CLASS_NAME; + wcex.hIconSm = 0; + atom = RegisterClassEx(&wcex); + if (!atom) + return FALSE; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProcAbout; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = 0; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = ABOUT_CLASS_NAME; + wcex.hIconSm = 0; + atom = RegisterClassEx(&wcex); + if (!atom) + return FALSE; + + return TRUE; +} + +#define IDC_HAND MAKEINTRESOURCE(32649) +static BOOL InstanceInit(HINSTANCE hInstance, int nCmdShow) +{ + ghinst = hInstance; + + globalParams = new GlobalParams(""); + if (!globalParams) + return FALSE; + + SplashColorsInit(); + gCursorArrow = LoadCursor(NULL, IDC_ARROW); + gCursorHand = LoadCursor(NULL, IDC_HAND); // apparently only available if WINVER >= 0x0500 + if (!gCursorHand) + gCursorHand = LoadCursor(ghinst, MAKEINTRESOURCE(IDC_CURSORDRAG)); + gCursorDrag = LoadCursor(ghinst, MAKEINTRESOURCE(IDC_CURSORDRAG)); + gBrushBg = CreateSolidBrush(COL_WINDOW_BG); + gBrushWhite = CreateSolidBrush(COL_WHITE); + gBrushShadow = CreateSolidBrush(COL_WINDOW_SHADOW); + gBrushLinkDebug = CreateSolidBrush(RGB(0x00,0x00,0xff)); + return TRUE; +} + +static void StrList_Reverse(StrList **strListRoot) +{ + StrList *newRoot = NULL; + StrList *cur, *next; + if (!strListRoot) + return; + cur = *strListRoot; + while (cur) { + next = cur->next; + cur->next = newRoot; + newRoot = cur; + cur = next; + } + *strListRoot = newRoot; +} + +static BOOL StrList_InsertAndOwn(StrList **root, char *txt) +{ + StrList * el; + assert(root && txt); + if (!root || !txt) + return FALSE; + + el = (StrList*)malloc(sizeof(StrList)); + if (!el) + return FALSE; + el->str = txt; + el->next = *root; + *root = el; + return TRUE; +} + +static void StrList_Destroy(StrList **root) +{ + StrList * cur; + StrList * next; + + if (!root) + return; + cur = *root; + while (cur) { + next = cur->next; + free((void*)cur->str); + free((void*)cur); + cur = next; + } + *root = NULL; +} + +static StrList *StrList_FromCmdLine(char *cmdLine) +{ + char * exePath; + StrList * strList = NULL; + char * txt; + + assert(cmdLine); + + if (!cmdLine) + return NULL; + + exePath = ExePathGet(); + if (!exePath) + return NULL; + if (!StrList_InsertAndOwn(&strList, exePath)) { + free((void*)exePath); + return NULL; + } + + for (;;) { + txt = str_parse_possibly_quoted(&cmdLine); + if (!txt) + break; + if (!StrList_InsertAndOwn(&strList, txt)) { + free((void*)txt); + break; + } + } + StrList_Reverse(&strList); + return strList; +} + +static void u_DoAllTests(void) +{ +#ifdef DEBUG + printf("Running tests\n"); + u_RectI_Intersect(); +#else + printf("Not running tests\n"); +#endif +} + +#define CONSERVE_MEMORY 1 + +static DWORD WINAPI PageRenderThread(PVOID data) +{ + PageRenderRequest req; + RenderedBitmap * bmp; + + DBG_OUT("PageRenderThread() started\n"); + while (1) { + //DBG_OUT("Worker: wait\n"); + LockCache(); + gCurPageRenderReq = NULL; + int count = gPageRenderRequestsCount; + UnlockCache(); + if (0 == count) { + DWORD waitResult = WaitForSingleObject(gPageRenderSem, INFINITE); + if (WAIT_OBJECT_0 != waitResult) { + DBG_OUT(" WaitForSingleObject() failed\n"); + continue; + } + } + if (0 == gPageRenderRequestsCount) { + continue; + } + LockCache(); + RenderQueue_Pop(&req); + gCurPageRenderReq = &req; + UnlockCache(); + DBG_OUT("PageRenderThread(): dequeued %d\n", req.pageNo); + if (!req.dm->pageVisibleNearby(req.pageNo)) { + DBG_OUT("PageRenderThread(): not rendering because not visible\n"); + continue; + } + assert(!req.abort); + MsTimer renderTimer; + bmp = req.dm->renderBitmap(req.pageNo, req.zoomLevel, req.rotation, pageRenderAbortCb, (void*)&req); + renderTimer.stop(); + LockCache(); + gCurPageRenderReq = NULL; + UnlockCache(); + if (req.abort) { + delete bmp; + continue; + } + if (bmp) + DBG_OUT("PageRenderThread(): finished rendering %d\n", req.pageNo); + else + DBG_OUT("PageRenderThread(): failed to render a bitmap of page %d\n", req.pageNo); + double renderTime = renderTimer.timeInMs(); + BitmapCache_Add(req.dm, req.pageNo, req.zoomLevel, req.rotation, bmp, renderTime); +#ifdef CONSERVE_MEMORY + BitmapCache_FreeNotVisible(); +#endif + WindowInfo* win = (WindowInfo*)req.dm->appData(); + triggerRepaintDisplayNow(win); + } + DBG_OUT("PageRenderThread() finished\n"); + return 0; +} + +static void CreatePageRenderThread(void) +{ + LONG semMaxCount = 1000; /* don't really know what the limit should be */ + DWORD dwThread1ID = 0; + assert(NULL == gPageRenderThreadHandle); + + gPageRenderSem = CreateSemaphore(NULL, 0, semMaxCount, NULL); + gPageRenderThreadHandle = CreateThread(NULL, 0, PageRenderThread, (void*)NULL, 0, &dwThread1ID); + assert(NULL != gPageRenderThreadHandle); +} + +static void PrintFile(WindowInfo *win, const char *fileName, const char *printerName) +{ + char devstring[256]; // array for WIN.INI data + HANDLE printer; + LPDEVMODE devMode = NULL; + DWORD structSize, returnCode; + + if (!win->dm->pdfEngine()->printingAllowed()) { + MessageBox(win->hwndFrame, "Cannot print this file", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); + return; + } + + // Retrieve the printer, printer driver, and + // output-port names from WIN.INI. + GetProfileString("Devices", printerName, "", devstring, sizeof(devstring)); + + // Parse the string of names, setting ptrs as required + // If the string contains the required names, use them to + // create a device context. + char *driver = strtok (devstring, (const char *) ","); + char *port = strtok((char *) NULL, (const char *) ","); + + if (!driver || !port) { + MessageBox(win->hwndFrame, "Printer with given name doesn't exist", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); + return; + } + + BOOL fOk = OpenPrinter((LPSTR)printerName, &printer, NULL); + if (!fOk) { + MessageBox(win->hwndFrame, _TR("Could not open Printer"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + return; + } + + HDC hdcPrint = NULL; + structSize = DocumentProperties(NULL, + printer, /* Handle to our printer. */ + (LPSTR) printerName, /* Name of the printer. */ + NULL, /* Asking for size, so */ + NULL, /* these are not used. */ + 0); /* Zero returns buffer size. */ + devMode = (LPDEVMODE)malloc(structSize); + if (!devMode) goto Exit; + + // Get the default DevMode for the printer and modify it for your needs. + returnCode = DocumentProperties(NULL, + printer, + (LPSTR) printerName, + devMode, /* The address of the buffer to fill. */ + NULL, /* Not using the input buffer. */ + DM_OUT_BUFFER); /* Have the output buffer filled. */ + + if (IDOK != returnCode) { + // If failure, inform the user, cleanup and return failure. + MessageBox(win->hwndFrame, "Could not obtain Printer properties", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); + goto Exit; + } + + PdfPageInfo * pageInfo = pageInfo = win->dm->getPageInfo(1); + + if (pageInfo->bitmapDx > pageInfo->bitmapDy) { + devMode->dmOrientation = DMORIENT_LANDSCAPE; + } else { + devMode->dmOrientation = DMORIENT_PORTRAIT; + } + + /* + * Merge the new settings with the old. + * This gives the driver an opportunity to update any private + * portions of the DevMode structure. + */ + DocumentProperties(NULL, + printer, + (LPSTR) printerName, + devMode, /* Reuse our buffer for output. */ + devMode, /* Pass the driver our changes. */ + DM_IN_BUFFER | /* Commands to Merge our changes and */ + DM_OUT_BUFFER); /* write the result. */ + + ClosePrinter(printer); + + hdcPrint = CreateDC(driver, printerName, port, devMode); + if (!hdcPrint) { + MessageBox(win->hwndFrame, "Couldn't initialize printer", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); + goto Exit; + } + + if (CheckPrinterStretchDibSupport(win->hwndFrame, hdcPrint)) + PrintToDevice(win->dm, hdcPrint, devMode, 1, win->dm->pageCount()); +Exit: + free(devMode); + DeleteDC(hdcPrint); +} + +static void EnumeratePrinters() +{ + PRINTER_INFO_5 *info5Arr = NULL; + DWORD bufSize = 0, printersCount; + BOOL fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, + 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); + if (!fOk) { + info5Arr = (PRINTER_INFO_5*)malloc(bufSize); + fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, + 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); + } + if (!info5Arr) + return; + assert(fOk); + if (!fOk) return; + printf("Printers: %d\n", printersCount); + for (DWORD i=0; i < printersCount; i++) { + const char *printerName = info5Arr[i].pPrinterName; + const char *printerPort = info5Arr[i].pPortName; + bool fDefault = false; + if (info5Arr[i].Attributes & PRINTER_ATTRIBUTE_DEFAULT) + fDefault = true; + printf("Name: %s, port: %s, default: %d\n", printerName, printerPort, (int)fDefault); + } + TCHAR buf[512]; + bufSize = sizeof(buf); + fOk = GetDefaultPrinter(buf, &bufSize); + if (!fOk) { + if (ERROR_FILE_NOT_FOUND == GetLastError()) + printf("No default printer\n"); + } + free(info5Arr); +} + +/* Get the name of default printer or NULL if not exists. + The caller needs to free() the result */ +char *GetDefaultPrinterName() +{ + char buf[512]; + DWORD bufSize = sizeof(buf); + if (GetDefaultPrinterA(buf, &bufSize)) + return str_dup(buf); + return NULL; +} + +int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) +{ + StrList * argListRoot; + StrList * currArg; + char * benchPageNumStr = NULL; + MSG msg = {0}; + HACCEL hAccelTable; + WindowInfo* win; + int pdfOpened = 0; + bool exitOnPrint = false; + bool printToDefaultPrinter = false; + + UNREFERENCED_PARAMETER(hPrevInstance); + + u_DoAllTests(); + + INITCOMMONCONTROLSEX cex; + cex.dwSize = sizeof(INITCOMMONCONTROLSEX); + cex.dwICC = ICC_WIN95_CLASSES | ICC_DATE_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES; + InitCommonControlsEx(&cex); + + argListRoot = StrList_FromCmdLine(lpCmdLine); + assert(argListRoot); + if (!argListRoot) + return 0; + + Prefs_Load(); + /* parse argument list. If BENCH_ARG_TXT was given, then we're in benchmarking mode. Otherwise + we assume that all arguments are PDF file names. + BENCH_ARG_TXT can be followed by file or directory name. If file, it can additionally be followed by + a number which we interpret as page number */ + bool registerForPdfExtentions = true; + currArg = argListRoot->next; + char *printerName = NULL; + while (currArg) { + if (IsEnumPrintersArg(currArg->str)) { + EnumeratePrinters(); + /* this is for testing only, exit immediately */ + goto Exit; + } + + if (IsDontRegisterExtArg(currArg->str)) { + registerForPdfExtentions = false; + currArg = currArg->next; + continue; + } + + if (IsBenchArg(currArg->str)) { + currArg = currArg->next; + if (currArg) { + gBenchFileName = currArg->str; + if (currArg->next) + benchPageNumStr = currArg->next->str; + } + break; + } + + if (IsExitOnPrintArg(currArg->str)) { + currArg = currArg->next; + exitOnPrint = true; + continue; + } + + if (IsPrintToDefaultArg(currArg->str)) { + printToDefaultPrinter = true; + continue; + } + + if (IsPrintToArg(currArg->str)) { + currArg = currArg->next; + if (currArg) { + printerName = currArg->str; + currArg = currArg->next; + } + continue; + } + + // we assume that switches come first and file names to open later + // TODO: it would probably be better to collect all non-switches + // in a separate list so that file names can be interspersed with + // switches + break; + } + + if (benchPageNumStr) { + gBenchPageNum = atoi(benchPageNumStr); + if (gBenchPageNum < 1) + gBenchPageNum = INVALID_PAGE_NO; + } + + LoadString(hInstance, IDS_APP_TITLE, windowTitle, MAX_LOADSTRING); + if (!RegisterWinClass(hInstance)) + goto Exit; + + CaptionPens_Create(); + if (!InstanceInit(hInstance, nCmdShow)) + goto Exit; + + hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SUMATRAPDF)); + + CreatePageRenderThread(); + /* remaining arguments are names of PDF files */ + if (NULL != gBenchFileName) { + win = LoadPdf(gBenchFileName); + if (win) + ++pdfOpened; + } else { + while (currArg) { + win = LoadPdf(currArg->str); + if (!win) + goto Exit; + + if (exitOnPrint) + ShowWindow(win->hwndFrame, SW_HIDE); + + if (printToDefaultPrinter) { + printerName = GetDefaultPrinterName(); + if (printerName) + PrintFile(win, currArg->str, printerName); + free(printerName); + } else if (printerName) { + // note: this prints all of PDF files. Another option would be to + // print only the first one + PrintFile(win, currArg->str, printerName); + } + ++pdfOpened; + currArg = currArg->next; + } + } + + if (printerName && exitOnPrint) + goto Exit; + + if (0 == pdfOpened) { + /* disable benchmark mode if we couldn't open file to benchmark */ + gBenchFileName = 0; +#ifdef REOPEN_FILES_AT_STARTUP + FileHistoryList * currFile = gFileHistoryRoot; + while (currFile) { + if (currFile->state.visible) { + win = LoadPdf(currFile->state.filePath, false); + if (win) + ++pdfOpened; + } + currFile = currFile->next; + } +#endif + if (0 == pdfOpened) { + win = WindowInfo_CreateEmpty(); + if (!win) + goto Exit; + WindowInfoList_Add(win); + + /* TODO: should this be part of WindowInfo_CreateEmpty() ? */ + DragAcceptFiles(win->hwndFrame, TRUE); + ShowWindow(win->hwndCanvas, SW_SHOW); + UpdateWindow(win->hwndCanvas); + ShowWindow(win->hwndFrame, SW_SHOW); + UpdateWindow(win->hwndFrame); + } + } + + if (IsBenchMode()) { + assert(win); + assert(pdfOpened > 0); + if (win) + PostBenchNextAction(win->hwndFrame); + } + + if (0 == pdfOpened) + MenuToolbarUpdateStateForAllWindows(); + + if (registerForPdfExtentions) + RegisterForPdfExtentions(win ? win->hwndFrame : NULL); + + while (GetMessage(&msg, NULL, 0, 0)) { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + +Exit: + WindowInfoList_DeleteAll(); + FileHistoryList_Free(&gFileHistoryRoot); + CaptionPens_Destroy(); + DeleteObject(gBrushBg); + DeleteObject(gBrushWhite); + DeleteObject(gBrushShadow); + DeleteObject(gBrushLinkDebug); + + delete globalParams; + StrList_Destroy(&argListRoot); + Translations_FreeData(); + CurrLangNameFree(); + //histDump(); + return (int) msg.wParam; +} + +// Code for DLL interace +static WindowInfo* CreateEmpty(HWND parentHandle) { + WindowInfo* pdfWin; + HWND hwndCanvas; + pdfWin = WindowInfo_New(parentHandle); + hwndCanvas = CreateWindow( + CANVAS_CLASS_NAME, NULL, + WS_CHILD | WS_HSCROLL | WS_VSCROLL, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + parentHandle, NULL, + ghinst, NULL); + if (hwndCanvas) + pdfWin->hwndCanvas = hwndCanvas; + return pdfWin; +} + +static void OpenPdf(WindowInfo* pdfWin,const char *fileName, HWND parentHandle) +{ + assert(fileName); + if (!fileName) return; + assert(pdfWin); + if (!pdfWin) return; + + pdfWin->GetCanvasSize(); + SizeI maxCanvasSize = GetMaxCanvasSize(pdfWin); + SizeD totalDrawAreaSize(pdfWin->winSize()); + DisplayMode displayMode = DEFAULT_DISPLAY_MODE; + int offsetX = 0; + int offsetY = 0; + int startPage = 1; + int scrollbarYDx = 0; + int scrollbarXDy = 0; + + if (gUseFitz) { + pdfWin->dm = DisplayModelFitz_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, pdfWin); + } + else { + pdfWin->dm = DisplayModelSplash_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, pdfWin); + } + + pdfWin->dm->setAppData((void*)pdfWin); + pdfWin->state = WS_SHOWING_PDF; + double zoomVirtual = DEFAULT_ZOOM; + int rotation = DEFAULT_ROTATION; + + UINT menuId = MenuIdFromVirtualZoom(zoomVirtual); + ZoomMenuItemCheck(GetMenu(pdfWin->hwndFrame), menuId); + + pdfWin->dm->relayout(zoomVirtual, rotation); + if (!pdfWin->dm->validPageNo(startPage)) + startPage = 1; + offsetY = 0; + pdfWin->dm->goToPage(startPage, offsetY, offsetX); + WindowInfo_ResizeToPage(pdfWin, startPage); + WindowInfoList_Add(pdfWin); + + RECT rect; + if (GetWindowRect(pdfWin->hwndFrame , &rect) != 0) + { + int nWidth = rect_dx(&rect); + int nHeight = rect_dy(&rect); + WinResizeClientArea(pdfWin->hwndCanvas, nWidth, nHeight); + } + + ShowWindow(pdfWin->hwndFrame, SW_SHOW); + ShowWindow(pdfWin->hwndCanvas, SW_SHOW); + UpdateWindow(pdfWin->hwndFrame); + UpdateWindow(pdfWin->hwndCanvas); +} + +void Sumatra_LoadPDF(WindowInfo* pdfWin, const char *pdfFile) +{ + int pdfOpened = 0; + OpenPdf(pdfWin, pdfFile, pdfWin->hwndFrame); + ++pdfOpened; + if (pdfWin) + ShowWindow(pdfWin->hwndFrame, SW_SHOWNORMAL); +} + +void Sumatra_PrintPDF(WindowInfo* pdfWin, const char *pdfFile, long showOptionWindow) +{ +} + +void Sumatra_Print(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + OnMenuPrint(pdfWin); +} + +void Sumatra_ShowPrintDialog(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + OnMenuPrint(pdfWin); +} + +void Sumatra_SetDisplayMode(WindowInfo* pdfWin,long displayMode) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + SwitchToDisplayMode(pdfWin, (DisplayMode)displayMode); +} + +long Sumatra_GoToNextPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToNextPage(0); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToPreviousPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToPrevPage(0); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToFirstPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToFirstPage(); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToLastPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToLastPage(); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GetNumberOfPages(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + return pdfWin->dm->pageCount(); +} + +long Sumatra_GetCurrentPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToThisPage(WindowInfo* pdfWin,long pageNumber) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + if (pdfWin->dm->validPageNo(pageNumber)) + pdfWin->dm->goToPage(pageNumber, 0); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_ZoomIn(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + { + long currentZoom = Sumatra_GetCurrentZoom(pdfWin); + if (currentZoom < 500) + Sumatra_SetZoom(pdfWin,currentZoom+10); + } + return Sumatra_GetCurrentZoom(pdfWin); +} + +long Sumatra_ZoomOut(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + { + long currentZoom = Sumatra_GetCurrentZoom(pdfWin); + if (currentZoom > 10) + Sumatra_SetZoom(pdfWin,currentZoom-10); + } + return Sumatra_GetCurrentZoom(pdfWin); +} + +long Sumatra_SetZoom(WindowInfo* pdfWin,long zoomValue) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + pdfWin->dm->zoomTo((double)zoomValue); + return Sumatra_GetCurrentZoom(pdfWin); +} + +long Sumatra_GetCurrentZoom(WindowInfo* pdfWin) +{ + double zoomLevel = 0; + if (WindowInfo_PdfLoaded(pdfWin)) + zoomLevel = pdfWin->dm->zoomReal(); + return (long)zoomLevel; +} + +void Sumatra_Resize(WindowInfo* pdfWin) +{ + RECT rect; + if (GetWindowRect(pdfWin->hwndFrame , &rect) != 0) + { + int nWidth = rect_dx(&rect); + int nHeight = rect_dy(&rect); + WinResizeClientArea(pdfWin->hwndCanvas, nWidth, nHeight); + } +} + +void Sumatra_ClosePdf(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + CloseWindow(pdfWin, FALSE); +} + +WindowInfo* Sumatra_Init(HWND pHandle) +{ + WindowInfo* pdfWin; + gRunningDLL = true; + HINSTANCE hInstance = NULL; + HINSTANCE hPrevInstance = NULL; + int nCmdShow = 0; + + StrList * argListRoot = NULL; + StrList * currArg = NULL; + MSG msg = {0}; + bool exitOnPrint = false; + bool printToDefaultPrinter = false; + gUseFitz = TRUE; + + UNREFERENCED_PARAMETER(hPrevInstance); + + u_DoAllTests(); + + INITCOMMONCONTROLSEX cex; + cex.dwSize = sizeof(INITCOMMONCONTROLSEX); + cex.dwICC = ICC_WIN95_CLASSES | ICC_DATE_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES; + InitCommonControlsEx(&cex); + argListRoot = NULL; + + LoadString(hInstance, IDS_APP_TITLE, windowTitle, MAX_LOADSTRING); + + if (!RegisterWinClass(hInstance)) + Sumatra_Exit(); + + CaptionPens_Create(); + + if (!InstanceInit(hInstance, nCmdShow)) + Sumatra_Exit(); + + CreatePageRenderThread(); + + bool reuseExistingWindow = false; + + if (pHandle == 0 ) + pHandle = NULL; + + pdfWin = CreateEmpty(pHandle); + + return pdfWin; +} + +void Sumatra_Exit() +{ + CaptionPens_Destroy(); + DeleteObject(gBrushBg); + DeleteObject(gBrushWhite); + DeleteObject(gBrushShadow); + DeleteObject(gBrushLinkDebug); + delete globalParams; +} diff --git a/rosapps/smartpdf/src/PdfEngine.cc b/rosapps/smartpdf/src/PdfEngine.cc new file mode 100644 index 00000000000..93e434a7167 --- /dev/null +++ b/rosapps/smartpdf/src/PdfEngine.cc @@ -0,0 +1,714 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "base_util.h" +#include "PdfEngine.h" + +#include "ErrorCodes.h" +#include "GooString.h" +#include "GooList.h" +#include "GlobalParams.h" +#include "SplashBitmap.h" +#include "Object.h" /* must be included before SplashOutputDev.h because of sloppiness in SplashOutputDev.h */ +#include "SplashOutputDev.h" +#include "TextOutputDev.h" +#include "PDFDoc.h" +#include "SecurityHandler.h" +#include "Link.h" +#include "str_util.h" + +// in SumatraPDF.cpp +extern "C" char *GetPasswordForFile(WindowInfo *win, const char *fileName); + +const char* const LINK_ACTION_GOTO = "linkActionGoTo"; +const char* const LINK_ACTION_GOTOR = "linkActionGoToR"; +const char* const LINK_ACTION_LAUNCH = "linkActionLaunch"; +const char* const LINK_ACTION_URI = "linkActionUri"; +const char* const LINK_ACTION_NAMED = "linkActionNamed"; +const char* const LINK_ACTION_MOVIE = "linkActionMovie"; +const char* const LINK_ACTION_UNKNOWN = "linkActionUnknown"; + +static SplashColorMode gSplashColorMode = splashModeBGR8; + +static SplashColor splashColRed; +static SplashColor splashColGreen; +static SplashColor splashColBlue; +static SplashColor splashColWhite; +static SplashColor splashColBlack; + +#define SPLASH_COL_RED_PTR (SplashColorPtr)&(splashColRed[0]) +#define SPLASH_COL_GREEN_PTR (SplashColorPtr)&(splashColGreen[0]) +#define SPLASH_COL_BLUE_PTR (SplashColorPtr)&(splashColBlue[0]) +#define SPLASH_COL_WHITE_PTR (SplashColorPtr)&(splashColWhite[0]) +#define SPLASH_COL_BLACK_PTR (SplashColorPtr)&(splashColBlack[0]) + +static SplashColorPtr gBgColor = SPLASH_COL_WHITE_PTR; + +static void splashColorSet(SplashColorPtr col, Guchar red, Guchar green, Guchar blue, Guchar alpha) +{ + switch (gSplashColorMode) + { + case splashModeBGR8: + col[0] = blue; + col[1] = green; + col[2] = red; + break; + case splashModeRGB8: + col[0] = red; + col[1] = green; + col[2] = blue; + break; + default: + assert(0); + break; + } +} + +void SplashColorsInit(void) +{ + splashColorSet(SPLASH_COL_RED_PTR, 0xff, 0, 0, 0); + splashColorSet(SPLASH_COL_GREEN_PTR, 0, 0xff, 0, 0); + splashColorSet(SPLASH_COL_BLUE_PTR, 0, 0, 0xff, 0); + splashColorSet(SPLASH_COL_BLACK_PTR, 0, 0, 0, 0); + splashColorSet(SPLASH_COL_WHITE_PTR, 0xff, 0xff, 0xff, 0); +} + +static HBITMAP createDIBitmapCommon(RenderedBitmap *bmp, HDC hdc) +{ + int bmpDx = bmp->dx(); + int bmpDy = bmp->dy(); + int bmpRowSize = bmp->rowSize(); + + BITMAPINFOHEADER bmih; + bmih.biSize = sizeof(bmih); + bmih.biHeight = -bmpDy; + bmih.biWidth = bmpDx; + bmih.biPlanes = 1; + bmih.biBitCount = 24; + bmih.biCompression = BI_RGB; + bmih.biSizeImage = bmpDy * bmpRowSize;; + bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0; + bmih.biClrUsed = bmih.biClrImportant = 0; + + unsigned char* bmpData = bmp->data(); + HBITMAP hbmp = ::CreateDIBitmap(hdc, &bmih, CBM_INIT, bmpData, (BITMAPINFO *)&bmih , DIB_RGB_COLORS); + return hbmp; +} + +static void stretchDIBitsCommon(RenderedBitmap *bmp, HDC hdc, int leftMargin, int topMargin, int pageDx, int pageDy) +{ + int bmpDx = bmp->dx(); + int bmpDy = bmp->dy(); + int bmpRowSize = bmp->rowSize(); + + BITMAPINFOHEADER bmih; + bmih.biSize = sizeof(bmih); + bmih.biHeight = -bmpDy; + bmih.biWidth = bmpDx; + bmih.biPlanes = 1; + // we could create this dibsection in monochrome + // if the printer is monochrome, to reduce memory consumption + // but splash is currently setup to return a full colour bitmap + bmih.biBitCount = 24; + bmih.biCompression = BI_RGB; + bmih.biSizeImage = bmpDy * bmpRowSize;; + bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0; + bmih.biClrUsed = bmih.biClrImportant = 0; + SplashColorPtr bmpData = bmp->data(); + + ::StretchDIBits(hdc, + // destination rectangle + -leftMargin, -topMargin, pageDx, pageDy, + // source rectangle + 0, 0, bmpDx, bmpDy, + bmpData, + (BITMAPINFO *)&bmih , + DIB_RGB_COLORS, + SRCCOPY); +} + +RenderedBitmapFitz::RenderedBitmapFitz(fz_pixmap *bitmap) +{ + _bitmap = bitmap; +} + +RenderedBitmapFitz::~RenderedBitmapFitz() +{ + if (_bitmap) + fz_droppixmap(_bitmap); +} + +int RenderedBitmapFitz::rowSize() +{ + int rowSize = ((_bitmap->w * 3 + 3) / 4) * 4; + return rowSize; +} + +unsigned char *RenderedBitmapFitz::data() +{ +#ifdef FITZ_HEAD + unsigned char* bmpData = _bitmap->p; +#else + unsigned char* bmpData = _bitmap->samples; +#endif + return bmpData; +} + +HBITMAP RenderedBitmapFitz::createDIBitmap(HDC hdc) +{ + return createDIBitmapCommon(this, hdc); +} + +void RenderedBitmapFitz::stretchDIBits(HDC hdc, int leftMargin, int topMargin, int pageDx, int pageDy) +{ + stretchDIBitsCommon(this, hdc, leftMargin, topMargin, pageDx, pageDy); +} + +RenderedBitmapSplash::RenderedBitmapSplash(SplashBitmap *bitmap) +{ + _bitmap = bitmap; +} + +RenderedBitmapSplash::~RenderedBitmapSplash() { + delete _bitmap; +} + +int RenderedBitmapSplash::dx() +{ + return _bitmap->getWidth(); +} + +int RenderedBitmapSplash::dy() +{ + return _bitmap->getHeight(); +} + +int RenderedBitmapSplash::rowSize() +{ + return _bitmap->getRowSize(); +} + +unsigned char *RenderedBitmapSplash::data() +{ + return _bitmap->getDataPtr(); +} + +HBITMAP RenderedBitmapSplash::createDIBitmap(HDC hdc) +{ + return createDIBitmapCommon(this, hdc); +} + +void RenderedBitmapSplash::stretchDIBits(HDC hdc, int leftMargin, int topMargin, int pageDx, int pageDy) +{ + stretchDIBitsCommon(this, hdc, leftMargin, topMargin, pageDx, pageDy); +} + +PdfEnginePoppler::PdfEnginePoppler() : + PdfEngine() + , _pdfDoc(NULL) + , _outputDev(NULL) + , _linksForPage(NULL) +{ +} + +PdfEnginePoppler::~PdfEnginePoppler() +{ + delete _outputDev; + delete _pdfDoc; + for (int i = 0; (i < _pageCount) && _linksForPage; i++) + delete _linksForPage[i]; + free(_linksForPage); +} + +bool PdfEnginePoppler::load(const char *fileName, WindowInfo *win) +{ + setFileName(fileName); + _windowInfo = win; + /* note: don't delete fileNameStr since PDFDoc takes ownership and deletes them itself */ + GooString *fileNameStr = new GooString(fileName); + if (!fileNameStr) return false; + + _pdfDoc = new PDFDoc(fileNameStr, NULL, NULL, (void*)win); + if (!_pdfDoc->isOk()) { + return false; + } + _pageCount = _pdfDoc->getNumPages(); + _linksForPage = (Links**)malloc(_pageCount * sizeof(Links*)); + if (!_linksForPage) return false; + for (int i=0; i < _pageCount; i++) + _linksForPage[i] = NULL; + return true; +} + +int PdfEnginePoppler::pageRotation(int pageNo) +{ + assert(validPageNo(pageNo)); + return pdfDoc()->getPageRotate(pageNo); +} + +SizeD PdfEnginePoppler::pageSize(int pageNo) +{ + double dx = pdfDoc()->getPageCropWidth(pageNo); + double dy = pdfDoc()->getPageCropHeight(pageNo); + return SizeD(dx, dy); +} + +SplashOutputDev * PdfEnginePoppler::outputDevice() { + if (!_outputDev) { + GBool bitmapTopDown = gTrue; + _outputDev = new SplashOutputDev(gSplashColorMode, 4, gFalse, gBgColor, bitmapTopDown); + if (_outputDev) + _outputDev->startDoc(_pdfDoc->getXRef()); + } + return _outputDev; +} + +RenderedBitmap *PdfEnginePoppler::renderBitmap( + int pageNo, double zoomReal, int rotation, + BOOL (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA) +{ + assert(outputDevice()); + if (!outputDevice()) return NULL; + + //DBG_OUT("PdfEnginePoppler::RenderBitmap(pageNo=%d) rotate=%d, zoomReal=%.2f%%\n", pageNo, rotation, zoomReal); + + double hDPI = (double)PDF_FILE_DPI * zoomReal * 0.01; + double vDPI = (double)PDF_FILE_DPI * zoomReal * 0.01; + GBool useMediaBox = gFalse; + GBool crop = gTrue; + GBool doLinks = gTrue; + _pdfDoc->displayPage(_outputDev, pageNo, hDPI, vDPI, rotation, useMediaBox, crop, doLinks, + abortCheckCbkA, abortCheckCbkDataA); + +#if 0 + PdfPageInfo *pageInfo = getPageInfo(pageNo); + if (!pageInfo->links) { + /* displayPage calculates links for this page (if doLinks is true) + and puts inside pdfDoc */ + pageInfo->links = pdfDoc->takeLinks(); + if (pageInfo->links->getNumLinks() > 0) + RecalcLinks(); + } +#endif + SplashBitmap* bmp = _outputDev->takeBitmap(); + if (bmp) + return new RenderedBitmapSplash(bmp); + + return NULL; +} + +bool PdfEnginePoppler::printingAllowed() +{ + if (_pdfDoc->okToPrint()) + return true; + return false; +} + +Links* PdfEnginePoppler::getLinksForPage(int pageNo) +{ + if (!_linksForPage) + return NULL; + if (_linksForPage[pageNo-1]) + return NULL; + + Object obj; + Catalog *catalog = _pdfDoc->getCatalog(); + Page *page = catalog->getPage(pageNo); + Links *links = new Links(page->getAnnots(&obj), catalog->getBaseURI()); + obj.free(); + _linksForPage[pageNo-1] = links; + return _linksForPage[pageNo-1]; +} + +int PdfEnginePoppler::linkCount(int pageNo) { + Links *links = getLinksForPage(pageNo); + if (!links) return 0; + return links->getNumLinks(); +} + +const char* linkActionKindToLinkType(LinkActionKind kind) { + switch (kind) { + case (actionGoTo): + return LINK_ACTION_GOTO; + case actionGoToR: + return LINK_ACTION_GOTOR; + case actionLaunch: + return LINK_ACTION_LAUNCH; + case actionURI: + return LINK_ACTION_URI; + case actionNamed: + return LINK_ACTION_NAMED; + case actionMovie: + return LINK_ACTION_MOVIE; + case actionUnknown: + return LINK_ACTION_UNKNOWN; + default: + assert(0); + return LINK_ACTION_UNKNOWN; + } +} + +const char* PdfEnginePoppler::linkType(int pageNo, int linkNo) { + Links *links = getLinksForPage(pageNo); + if (!links) return 0; + int linkCount = links->getNumLinks(); + assert(linkNo < linkCount); + Link *link = links->getLink(linkNo-1); + LinkAction * action = link->getAction(); + LinkActionKind actionKind = action->getKind(); + return linkActionKindToLinkType(actionKind); +} + +fz_matrix PdfEngineFitz::viewctm (pdf_page *page, float zoom, int rotate) +{ + fz_matrix ctm; + ctm = fz_identity(); + ctm = fz_concat(ctm, fz_translate(0, -page->mediabox.y1)); + ctm = fz_concat(ctm, fz_scale(zoom, -zoom)); + ctm = fz_concat(ctm, fz_rotate(rotate + page->rotate)); + return ctm; +} + +PdfEngineFitz::PdfEngineFitz() : + PdfEngine() + , _popplerEngine(NULL) + , _xref(NULL) + , _outline(NULL) + , _pageTree(NULL) + , _pages(NULL) + , _rast(NULL) +{ + _getPageSem = CreateSemaphore(NULL, 1, 1, NULL); +} + +PdfEngineFitz::~PdfEngineFitz() +{ + if (_pages) { + for (int i=0; i < _pageCount; i++) { + if (_pages[i]) + pdf_droppage(_pages[i]); + } + free(_pages); + } + + if (_pageTree) + pdf_droppagetree(_pageTree); + + if (_outline) + pdf_dropoutline(_outline); + + if (_xref) { + if (_xref->store) + pdf_dropstore(_xref->store); + _xref->store = 0; + pdf_closexref(_xref); + } + + if (_rast) { +#ifdef FITZ_HEAD + fz_dropgraphics(_rast); +#else + fz_droprenderer(_rast); +#endif + } + + CloseHandle(_getPageSem); + + delete _popplerEngine; +} + +bool PdfEngineFitz::load(const char *fileName, WindowInfo *win) +{ + assert(!_popplerEngine); + _windowInfo = win; + setFileName(fileName); + fz_error *error = pdf_newxref(&_xref); + if (error) + goto Error; + + error = pdf_loadxref(_xref, (char*)fileName); + if (error) { + if (!strncmp(error->msg, "ioerror", 7)) + goto Error; + error = pdf_repairxref(_xref, (char*)fileName); + if (error) + goto TryPoppler; + } + + error = pdf_decryptxref(_xref); + if (error) + goto Error; + + if (_xref->crypt) { +#ifdef FITZ_HEAD + int okay = pdf_setpassword(_xref->crypt, ""); + if (!okay) + goto Error; + if (!win) { + // win might not be given if called from pdfbench.cc + goto Error; + } + for (int i=0; i<3; i++) { + char *pwd = GetPasswordForFile(win, fileName); + okay = pdf_setpassword(_xref->crypt, pwd); + free(pwd); + if (okay) + goto DecryptedOk; + } + goto Error; +#else + error = pdf_setpassword(_xref->crypt, ""); + if (!error) + goto DecryptedOk; + if (!win) { + // win might not be given if called from pdfbench.cc + goto Error; + } + for (int i=0; i<3; i++) { + char *pwd = GetPasswordForFile(win, fileName); + // dialog box was cancelled + if (!pwd) + goto Error; + error = pdf_setpassword(_xref->crypt, pwd); + free(pwd); + if (!error) + goto DecryptedOk; + } + goto Error; +#endif + } + +DecryptedOk: + error = pdf_loadpagetree(&_pageTree, _xref); + if (error) + goto Error; + + error = pdf_loadoutline(&_outline, _xref); + // TODO: can I ignore this error? + if (error) + goto Error; + + _pageCount = _pageTree->count; + _pages = (pdf_page**)malloc(sizeof(pdf_page*) * _pageCount); + for (int i = 0; i < _pageCount; i++) + _pages[i] = NULL; + return true; +Error: + return false; +TryPoppler: + _popplerEngine = new PdfEnginePoppler(); + if (!_popplerEngine) + return false; + bool fok = _popplerEngine->load(fileName, win); + if (!fok) + goto ErrorPoppler; + return true; + +ErrorPoppler: + delete _popplerEngine; + return false; +} + +pdf_page *PdfEngineFitz::getPdfPage(int pageNo) +{ + if (!_pages) + return NULL; + + WaitForSingleObject(_getPageSem, INFINITE); + pdf_page* page = _pages[pageNo-1]; + if (page) { + if (!ReleaseSemaphore(_getPageSem, 1, NULL)) + DBG_OUT("Fitz: ReleaseSemaphore error!\n"); + return page; + } + // TODO: should check for error from pdf_getpageobject? + fz_obj * obj = pdf_getpageobject(_pageTree, pageNo - 1); + fz_error * error = pdf_loadpage(&page, _xref, obj); + assert (!error); + if (error) { + if (!ReleaseSemaphore(_getPageSem, 1, NULL)) + DBG_OUT("Fitz: ReleaseSemaphore error!\n"); + fz_droperror(error); + return NULL; + } + _pages[pageNo-1] = page; + if (!ReleaseSemaphore(_getPageSem, 1, NULL)) + DBG_OUT("Fitz: ReleaseSemaphore error!\n"); + return page; +} + +void PdfEngineFitz::dropPdfPage(int pageNo) +{ + assert(_pages); + if (!_pages) return; + pdf_page* page = _pages[pageNo-1]; + assert(page); + if (!page) return; + pdf_droppage(page); + _pages[pageNo-1] = NULL; +} + +int PdfEngineFitz::pageRotation(int pageNo) +{ + if (_popplerEngine) + return _popplerEngine->pageRotation(pageNo); + + assert(validPageNo(pageNo)); + fz_obj *dict = pdf_getpageobject(pages(), pageNo - 1); + int rotation; + fz_error *error = pdf_getpageinfo(_xref, dict, NULL, &rotation); + if (error) + return INVALID_ROTATION; + return rotation; +} + +SizeD PdfEngineFitz::pageSize(int pageNo) +{ + if (_popplerEngine) + return _popplerEngine->pageSize(pageNo); + + assert(validPageNo(pageNo)); + fz_obj *dict = pdf_getpageobject(pages(), pageNo - 1); + fz_rect bbox; + fz_error *error = pdf_getpageinfo(_xref, dict, &bbox, NULL); + if (error) + return SizeD(0,0); + return SizeD(fabs(bbox.x1 - bbox.x0), fabs(bbox.y1 - bbox.y0)); +} + +bool PdfEngineFitz::printingAllowed() +{ + assert(_xref); + int permissionFlags = PDF_DEFAULT_PERM_FLAGS; + if (_xref && _xref->crypt) + permissionFlags = _xref->crypt->p; + if (permissionFlags & PDF_PERM_PRINT) + return true; + return false; +} + +static void ConvertPixmapForWindows(fz_pixmap *image) +{ + int bmpstride = ((image->w * 3 + 3) / 4) * 4; + unsigned char *bmpdata = (unsigned char*)fz_malloc(image->h * bmpstride); + if (!bmpdata) + return; + + for (int y = 0; y < image->h; y++) + { + unsigned char *p = bmpdata + y * bmpstride; +#ifdef FITZ_HEAD + unsigned char *s = image->p + y * image->w * 4; +#else + unsigned char *s = image->samples + y * image->w * 4; +#endif + for (int x = 0; x < image->w; x++) + { + p[x * 3 + 0] = s[x * 4 + 3]; + p[x * 3 + 1] = s[x * 4 + 2]; + p[x * 3 + 2] = s[x * 4 + 1]; + } + } +#ifdef FITZ_HEAD + fz_free(image->p); + image->p = bmpdata; +#else + fz_free(image->samples); + image->samples = bmpdata; +#endif +} + +RenderedBitmap *PdfEngineFitz::renderBitmap( + int pageNo, double zoomReal, int rotation, + BOOL (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA) +{ + fz_error* error; + fz_matrix ctm; + fz_rect bbox; + + if (_popplerEngine) + return _popplerEngine->renderBitmap(pageNo, zoomReal, rotation, abortCheckCbkA, abortCheckCbkDataA); + + if (!_rast) { +#ifdef FITZ_HEAD + error = fz_newgraphics(&_rast, 1024 * 512); +#else + error = fz_newrenderer(&_rast, pdf_devicergb, 0, 1024 * 512); +#endif + } + + fz_pixmap* image = NULL; + pdf_page* page = getPdfPage(pageNo); + if (!page) + goto TryPoppler; + zoomReal = zoomReal / 100.0; + ctm = viewctm(page, zoomReal, rotation); + bbox = fz_transformaabb(ctm, page->mediabox); +#ifdef FITZ_HEAD + error = fz_drawtree(&image, _rast, page->tree, ctm, pdf_devicergb, fz_roundrect(bbox), 1); +#else + error = fz_rendertree(&image, _rast, page->tree, ctm, fz_roundrect(bbox), 1); +#endif +#if CONSERVE_MEMORY + dropPdfPage(pageNo); +#endif + if (error) + goto TryPoppler; + ConvertPixmapForWindows(image); + return new RenderedBitmapFitz(image); +TryPoppler: + _popplerEngine = new PdfEnginePoppler(); + if (!_popplerEngine) + return false; + bool fok = _popplerEngine->load(fileName(), _windowInfo); + if (!fok) + goto ErrorPoppler; + return _popplerEngine->renderBitmap(pageNo, zoomReal, rotation, abortCheckCbkA, abortCheckCbkDataA); +ErrorPoppler: + return NULL; +} + +static int getLinkCount(pdf_link *currLink) { + if (!currLink) + return 0; + int count = 1; + while (currLink->next) { + ++count; + currLink = currLink->next; + } + return count; +} + +int PdfEngineFitz::linkCount(int pageNo) { + pdf_page* page = getPdfPage(pageNo); + if (!page) + return 0; + return getLinkCount(page->links); +} + +static const char *linkToLinkType(pdf_link *link) { + switch (link->kind) { + case PDF_LGOTO: + return LINK_ACTION_GOTO; + case PDF_LURI: + return LINK_ACTION_URI; + case PDF_LUNKNOWN: /* @note: add unhandled value */ + OutputDebugString(L"Link unknown"); + break; + } + return LINK_ACTION_UNKNOWN; +} + +const char* PdfEngineFitz::linkType(int pageNo, int linkNo) { + pdf_page* page = getPdfPage(pageNo); + pdf_link* currLink = page->links; + for (int i = 0; i < linkNo; i++) { + assert(currLink); + if (!currLink) + return NULL; + currLink = currLink->next; + } + return linkToLinkType(currLink); +} + diff --git a/rosapps/smartpdf/src/PdfEngine.h b/rosapps/smartpdf/src/PdfEngine.h new file mode 100644 index 00000000000..2e68e76a157 --- /dev/null +++ b/rosapps/smartpdf/src/PdfEngine.h @@ -0,0 +1,191 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef _PDF_ENGINE_H_ +#define _PDF_ENGINE_H_ + +#include "geom_util.h" + +#ifndef _FITZ_H_ +#include +#include +#endif + +class WindowInfo; + +class SplashBitmap; +class SplashOutputDev; +class PDFDoc; +class Links; + +extern const char* const LINK_ACTION_GOTO; +extern const char* const LINK_ACTION_GOTOR; +extern const char* const LINK_ACTION_LAUNCH; +extern const char* const LINK_ACTION_URI; +extern const char* const LINK_ACTION_NAMED; +extern const char* const LINK_ACTION_MOVIE; + +/* For simplicity, all in one file. Would be cleaner if they were + in separate files PdfEngineFitz.h and PdfEnginePoppler.h */ + +#define INVALID_PAGE_NO -1 +#define INVALID_ROTATION -1 +/* It seems that PDF documents are encoded assuming DPI of 72.0 */ +#define PDF_FILE_DPI 72 + +void SplashColorsInit(void); + +/* Abstract class representing cached bitmap. Allows different implementations + on different platforms. */ +class RenderedBitmap { +public: + virtual ~RenderedBitmap() {}; + virtual int dx() = 0; + virtual int dy() = 0; + virtual int rowSize() = 0; + virtual unsigned char *data() = 0; + + // TODO: this is for WINDOWS only + virtual HBITMAP createDIBitmap(HDC) = 0; + virtual void stretchDIBits(HDC, int, int, int, int) = 0; +}; + +class RenderedBitmapFitz : public RenderedBitmap { +public: + RenderedBitmapFitz(fz_pixmap *); + virtual ~RenderedBitmapFitz(); + + virtual int dx() { return _bitmap->w; } + virtual int dy() { return _bitmap->h; } + virtual int rowSize(); + virtual unsigned char *data(); + + virtual HBITMAP createDIBitmap(HDC); + virtual void stretchDIBits(HDC, int, int, int, int); +protected: + fz_pixmap *_bitmap; +}; + +class RenderedBitmapSplash : public RenderedBitmap { +public: + RenderedBitmapSplash(SplashBitmap *); + virtual ~RenderedBitmapSplash(); + + virtual int dx(); + virtual int dy(); + virtual int rowSize(); + virtual unsigned char *data(); + + virtual HBITMAP createDIBitmap(HDC); + virtual void stretchDIBits(HDC, int, int, int, int); + +protected: + SplashBitmap *_bitmap; +}; + +class PdfEngine { +public: + PdfEngine() : + _fileName(0) + , _pageCount(INVALID_PAGE_NO) + { } + + virtual ~PdfEngine() { free((void*)_fileName); } + + const char *fileName(void) const { return _fileName; }; + + void setFileName(const char *fileName) { + assert(!_fileName); + _fileName = (const char*)strdup(fileName); + } + + bool validPageNo(int pageNo) const { + if ((pageNo >= 1) && (pageNo <= pageCount())) + return true; + return false; + } + + int pageCount(void) const { return _pageCount; } + + virtual bool load(const char *fileName, WindowInfo *windowInfo) = 0; + virtual int pageRotation(int pageNo) = 0; + virtual SizeD pageSize(int pageNo) = 0; + virtual RenderedBitmap *renderBitmap(int pageNo, double zoomReal, int rotation, + BOOL (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA) = 0; + + virtual bool printingAllowed() = 0; + virtual int linkCount(int pageNo) = 0; + virtual const char* linkType(int pageNo, int linkNo) = 0; + +protected: + const char *_fileName; + int _pageCount; + WindowInfo *_windowInfo; +}; + +class PdfEnginePoppler : public PdfEngine { +public: + PdfEnginePoppler(); + virtual ~PdfEnginePoppler(); + virtual bool load(const char *fileName, WindowInfo* windowInfo); + virtual int pageRotation(int pageNo); + virtual SizeD pageSize(int pageNo); + virtual RenderedBitmap *renderBitmap(int pageNo, double zoomReal, int rotation, + BOOL (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA); + + virtual bool printingAllowed(); + virtual int linkCount(int pageNo); + virtual const char* linkType(int pageNo, int linkNo); + + PDFDoc* pdfDoc() { return _pdfDoc; } + SplashOutputDev * outputDevice(); +private: + Links* getLinksForPage(int pageNo); + + PDFDoc * _pdfDoc; + SplashOutputDev * _outputDev; + Links ** _linksForPage; +}; + +class PdfEngineFitz : public PdfEngine { +public: + PdfEngineFitz(); + virtual ~PdfEngineFitz(); + virtual bool load(const char *fileName, WindowInfo* windowInfo); + virtual int pageRotation(int pageNo); + virtual SizeD pageSize(int pageNo); + virtual RenderedBitmap *renderBitmap(int pageNo, double zoomReal, int rotation, + BOOL (*abortCheckCbkA)(void *data), + void *abortCheckCbkDataA); + + virtual bool printingAllowed(); + virtual int linkCount(int pageNo); + virtual const char* linkType(int pageNo, int linkNo); + + fz_matrix viewctm (pdf_page *page, float zoom, int rotate); + + pdf_page * getPdfPage(int pageNo); + +private: + PdfEnginePoppler* _popplerEngine; + + HANDLE _getPageSem; + + pdf_xref * xref() { return _xref; } + pdf_pagetree * pages() { return _pageTree; } + + void dropPdfPage(int pageNo); + + pdf_xref * _xref; + pdf_outline * _outline; + pdf_pagetree * _pageTree; + pdf_page ** _pages; +#ifdef FITZ_HEAD + fz_graphics * _rast; +#else + fz_renderer * _rast; +#endif +}; + +#endif diff --git a/rosapps/smartpdf/src/PdftestWinPreview.cc b/rosapps/smartpdf/src/PdftestWinPreview.cc new file mode 100644 index 00000000000..879b87b3194 --- /dev/null +++ b/rosapps/smartpdf/src/PdftestWinPreview.cc @@ -0,0 +1,234 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "win_util.h" +#include "PdfEngine.h" + +#include + +#define WIN_CLASS_NAME "PDFTEST_PDF_WIN" +#define COL_WINDOW_BG RGB(0xff, 0xff, 0xff) + +static HWND gHwndSplash; +static HWND gHwndFitz; +static HBRUSH gBrushBg; + +static RenderedBitmap *gBmpSplash, *gBmpFitz; + +/* Set the client area size of the window 'hwnd' to 'dx'/'dy'. */ +static void resizeClientArea(HWND hwnd, int x, int dx, int dy, int *dx_out) +{ + RECT rc; + GetClientRect(hwnd, &rc); + if ((rect_dx(&rc) == dx) && (rect_dy(&rc) == dy)) + return; + + RECT rw; + GetWindowRect(hwnd, &rw); + int win_dx = rect_dx(&rw) + (dx - rect_dx(&rc)); + int win_dy = rect_dy(&rw) + (dy - rect_dy(&rc)); + SetWindowPos(hwnd, NULL, x, 0, win_dx, win_dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + if (dx_out) + *dx_out = win_dx; +} + +static void resizeClientAreaToRenderedBitmap(HWND hwnd, RenderedBitmap *bmp, int x, int *dxOut) +{ + int dx = bmp->dx(); + int dy = bmp->dy(); + resizeClientArea(hwnd, x, dx, dy, dxOut); +} + +static void drawBitmap(HWND hwnd, RenderedBitmap *bmp) +{ + PAINTSTRUCT ps; + + HDC hdc = BeginPaint(hwnd, &ps); + SetBkMode(hdc, TRANSPARENT); + FillRect(hdc, &ps.rcPaint, gBrushBg); + + HBITMAP hbmp = bmp->createDIBitmap(hdc); + if (hbmp) { + HDC bmpDC = CreateCompatibleDC(hdc); + if (bmpDC) { + SelectObject(bmpDC, hbmp); + int xSrc = 0, ySrc = 0; + int xDest = 0, yDest = 0; + int bmpDx = bmp->dx(); + int bmpDy = bmp->dy(); + BitBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, SRCCOPY); + DeleteDC(bmpDC); + bmpDC = NULL; + } + DeleteObject(hbmp); + hbmp = NULL; + } + EndPaint(hwnd, &ps); +} + +static void onPaint(HWND hwnd) +{ + if (hwnd == gHwndSplash) + if (gBmpSplash) + drawBitmap(hwnd, gBmpSplash); + if (hwnd == gHwndFitz) + if (gBmpFitz) + drawBitmap(hwnd, gBmpFitz); +} + +static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + // do nothing + break; + + case WM_ERASEBKGND: + return TRUE; + + case WM_PAINT: + /* it might happen that we get WM_PAINT after destroying a window */ + onPaint(hwnd); + break; + + case WM_DESTROY: + /* WM_DESTROY might be sent as a result of File\Close, in which case CloseWindow() has already been called */ + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +static BOOL registerWinClass(void) +{ + WNDCLASSEX wcex; + ATOM atom; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = NULL; + wcex.hIcon = NULL; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = WIN_CLASS_NAME; + wcex.hIconSm = NULL; + + atom = RegisterClassEx(&wcex); + if (atom) + return TRUE; + return FALSE; +} + +static bool initWinIfNecessary(void) +{ + if (gHwndSplash) + return true; + + if (!registerWinClass()) + return false; + + gBrushBg = CreateSolidBrush(COL_WINDOW_BG); + + gHwndSplash = CreateWindow( + WIN_CLASS_NAME, "Splash", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, + CW_USEDEFAULT, 0, + NULL, NULL, + NULL, NULL); + + if (!gHwndSplash) + return false; + + gHwndFitz = CreateWindow( + WIN_CLASS_NAME, "Fitz", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, + CW_USEDEFAULT, 0, + NULL, NULL, + NULL, NULL); + + if (!gHwndFitz) + return false; + + ShowWindow(gHwndSplash, SW_HIDE); + ShowWindow(gHwndFitz, SW_HIDE); + return true; +} + +static void pumpMessages(void) +{ + BOOL isMessage; + MSG msg; + + for (;;) { + isMessage = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + if (!isMessage) + return; + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +void PreviewBitmapInit(void) +{ + /* no need to do anything */ +} + +static void deleteRenderedBitmaps() +{ + delete gBmpSplash; + delete gBmpFitz; +} + +void PreviewBitmapDestroy(void) +{ + PostQuitMessage(0); + pumpMessages(); + deleteRenderedBitmaps(); + DeleteObject(gBrushBg); +} + +static void UpdateWindows(void) +{ + int fitzDx = 0; + + if (gBmpFitz) { + resizeClientAreaToRenderedBitmap(gHwndFitz, gBmpFitz, 0, &fitzDx); + ShowWindow(gHwndFitz, SW_SHOW); + InvalidateRect(gHwndFitz, NULL, FALSE); + UpdateWindow(gHwndFitz); + } else { + ShowWindow(gHwndFitz, SW_HIDE); + } + + if (gBmpSplash) { + resizeClientAreaToRenderedBitmap(gHwndSplash, gBmpSplash, fitzDx, NULL); + ShowWindow(gHwndSplash, SW_SHOW); + InvalidateRect(gHwndSplash, NULL, FALSE); + UpdateWindow(gHwndSplash); + } else { + ShowWindow(gHwndSplash, SW_HIDE); + } + + pumpMessages(); +} + +void PreviewBitmapSplashFitz(RenderedBitmap *bmpSplash, RenderedBitmap *bmpFitz) +{ + if (!initWinIfNecessary()) + return; + + deleteRenderedBitmaps(); + gBmpSplash = bmpSplash; + gBmpFitz = bmpFitz; + UpdateWindows(); +} + diff --git a/rosapps/smartpdf/src/Resource.h b/rosapps/smartpdf/src/Resource.h new file mode 100644 index 00000000000..9fe032366f0 --- /dev/null +++ b/rosapps/smartpdf/src/Resource.h @@ -0,0 +1,117 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by SumatraPDF.rc +// +#define IDI_SUMATRAPDF 1 +#define IDS_APP_TITLE 100 +#define IDD_DIALOG1 129 +#define IDD_DIALOG_GOTO_PAGE 129 +#define IDD_DIALOG_GET_PASSWORD 130 +#define IDD_DIALOG_PDF_ASSOCIATE 131 +#define IDC_CURSORDRAG 132 +#define IDR_MAINFRAME 200 +#define IDD_XPDFWIN_DIALOG 300 +#define IDD_ABOUTBOX 301 +#define IDM_ABOUT 400 +#define IDM_EXIT 401 +#define IDM_OPEN 402 +#define IDM_CLOSE 403 +#define IDM_ZOOM_FIT_PAGE 404 +#define IDM_ZOOM_ACTUAL_SIZE 405 +#define IDM_ZOOM_FIT_WIDTH 406 +#define IDM_ZOOM_FIT_VISIBLE 407 +#define IDM_ZOOM_6400 408 +#define IDM_ZOOM_3200 409 +#define IDM_ZOOM_1600 410 +#define IDM_ZOOM_800 411 +#define IDM_ZOOM_400 412 +#define IDM_ZOOM_200 413 +#define IDM_ZOOM_150 414 +#define IDM_ZOOM_125 415 +#define IDM_ZOOM_100 416 +#define IDM_ZOOM_50 417 +#define IDM_ZOOM_25 418 +#define IDM_ZOOM_12_5 419 +#define IDM_ZOOM_8_33 420 +#define IDM_VIEW_WITH_ACROBAT 421 +#define IDM_VIEW_CONTINUOUS 422 +#define IDM_VIEW_SINGLE_PAGE 423 +#define IDM_VIEW_FACING 424 +#define IDM_VIEW_CONTINUOUS_FACING 425 +#define IDM_VIEW_ROTATE_LEFT 426 +#define IDM_VIEW_ROTATE_RIGHT 427 +#define IDM_GOTO_NEXT_PAGE 428 +#define IDM_GOTO_PREV_PAGE 429 +#define IDM_GOTO_FIRST_PAGE 430 +#define IDM_GOTO_LAST_PAGE 431 +#define IDM_GOTO_PAGE 432 +#define IDM_PRINT 433 +#define IDM_VIEW_SHOW_HIDE_TOOLBAR 434 +#define IDM_MAKE_DEFAULT_READER 435 +#define IDM_VISIT_WEBSITE 436 +#define IDM_VIEW_USE_FITZ 437 +#define IDM_SAVEAS 438 +#define IDM_LANG_EN 450 +#define IDM_LANG_FR 451 +#define IDM_LANG_PL 452 +#define IDM_LANG_DE 453 +#define IDC_SUMATRAPDF 600 +#define IDI_SMALL 601 +#define IDC_GOTO_PAGE_EDIT 1000 +#define IDC_GOTO_PAGE_GO 1001 +#define IDC_BUTTON2 1002 +#define IDC_GOTOPAGE_CANCEL 1002 +#define IDC_GOTO_PAGE_CANCEL 1002 +#define IDC_GOTO_PAGE_LABEL_OF 1003 +#define IDC_DIALOG_GET_PASSWORD_EDIT 1004 +#define IDC_GET_PASSWORD_EDIT 1004 +#define IDC_GET_PASSWORD_LABEL 1005 +#define IDC_TOOLBAR 1006 +#define IDC_REBAR 1007 +#define IDC_DONT_ASK_ME_AGAIN 1008 +#define IDB_TOOLBAR 2000 +#define IDB_TOOLBAR_DISABLED 2001 +#define IDB_SILK_OPEN 2002 +#define IDB_SILK_NEXT 2003 +#define IDB_SILK_PREV 2004 +#define IDB_SILK_ZOOM_IN 2005 +#define IDB_SILK_ZOOM_OUT 2006 +#define IDT_FILE_NEW 3000 +#define IDT_FILE_OPEN 3001 +#define IDT_FILE_METAPATH 3002 +#define IDT_FILE_SAVE 3003 +#define IDT_EDIT_UNDO 3004 +#define IDT_EDIT_REDO 3005 +#define IDT_EDIT_CUT 3006 +#define IDT_EDIT_COPY 3007 +#define IDT_EDIT_PASTE 3008 +#define IDT_EDIT_FIND 3009 +#define IDT_EDIT_REPLACE 3010 +#define IDT_VIEW_WORDWRAP 3011 +#define IDT_VIEW_ZOOMIN 3012 +#define IDT_VIEW_ZOOMOUT 3013 +#define IDT_VIEW_SCHEME 3014 +#define IDT_VIEW_SCHEMECONFIG 3015 +#define IDT_FILE_EXIT 3016 +#define IDT_FILE_SAVEAS 3017 +#define IDT_FILE_SAVECOPY 3018 +#define IDT_EDIT_COPYALL 3019 +#define IDT_EDIT_CLEAR 3020 +#define IDT_EDIT_FINDNEXT 3021 +#define IDT_EDIT_FINDPREV 3022 +#define IDT_FILE_PRINT 3023 +#define IDT_FILE_OPENFAV 3024 +#define IDT_FILE_ADDTOFAV 3025 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 134 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1006 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/rosapps/smartpdf/src/SumatraDialogs.cc b/rosapps/smartpdf/src/SumatraDialogs.cc new file mode 100644 index 00000000000..3d40b353b8e --- /dev/null +++ b/rosapps/smartpdf/src/SumatraDialogs.cc @@ -0,0 +1,227 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#include "SumatraDialogs.h" + +#include "DisplayModel.h" +#include "dstring.h" +#include "Resource.h" +#include "win_util.h" +#include + +static BOOL CALLBACK Dialog_GetPassword_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND edit; + HWND label; + DString ds; + Dialog_GetPassword_Data * data; + + switch (message) + { + case WM_INITDIALOG: + /* TODO: intelligently center the dialog within the parent window? */ + data = (Dialog_GetPassword_Data*)lParam; + assert(data); + if (!data) + return FALSE; + assert(data->fileName); + assert(!data->pwdOut); + SetWindowLongPtr(hDlg, GWL_USERDATA, (LONG_PTR)data); + DStringInit(&ds); + DStringSprintf(&ds, "Enter password for %s", data->fileName); + label = GetDlgItem(hDlg, IDC_GET_PASSWORD_LABEL); + win_set_text(label, (TCHAR*)ds.pString); /* @note: TCHAR* cast */ + DStringFree(&ds); + edit = GetDlgItem(hDlg, IDC_GET_PASSWORD_EDIT); + win_set_text(edit, TEXT("")); /* @note: TEXT() cast */ + SetFocus(edit); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + data = (Dialog_GetPassword_Data*)GetWindowLongPtr(hDlg, GWL_USERDATA); + assert(data); + if (!data) + return TRUE; + edit = GetDlgItem(hDlg, IDC_GET_PASSWORD_EDIT); + data->pwdOut = (char*)win_get_text(edit); /* @note: char* cast */ + EndDialog(hDlg, DIALOG_OK_PRESSED); + return TRUE; + + case IDCANCEL: + EndDialog(hDlg, DIALOG_CANCEL_PRESSED); + return TRUE; + } + break; + } + return FALSE; +} + +/* Shows a 'get password' dialog for a given file. + Returns a password entered by user as a newly allocated string or + NULL if user cancelled the dialog or there was an error. + Caller needs to free() the result. +*/ +char *Dialog_GetPassword(WindowInfo *win, const char *fileName) +{ + int dialogResult; + Dialog_GetPassword_Data data; + + assert(fileName); + if (!fileName) return NULL; + + data.fileName = fileName; + data.pwdOut = NULL; + dialogResult = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DIALOG_GET_PASSWORD), win->hwndFrame, Dialog_GetPassword_Proc, (LPARAM)&data); + if (DIALOG_OK_PRESSED == dialogResult) { + return data.pwdOut; + } + free((void*)data.pwdOut); + return NULL; +} + +static BOOL CALLBACK Dialog_GoToPage_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND editPageNo; + HWND labelOfPages; + DString ds; + TCHAR * newPageNoTxt; + Dialog_GoToPage_Data * data; + + switch (message) + { + case WM_INITDIALOG: + /* TODO: intelligently center the dialog within the parent window? */ + data = (Dialog_GoToPage_Data*)lParam; + assert(NULL != data); + if (!data) + return FALSE; + SetWindowLongPtr(hDlg, GWL_USERDATA, (LONG_PTR)data); + assert(INVALID_PAGE_NO != data->currPageNo); + assert(data->pageCount >= 1); + DStringInit(&ds); + DStringSprintf(&ds, "%d", data->currPageNo); + editPageNo = GetDlgItem(hDlg, IDC_GOTO_PAGE_EDIT); + win_set_text(editPageNo, (TCHAR*)ds.pString); /* @note: TCHAR* cast */ + DStringFree(&ds); + DStringSprintf(&ds, "(of %d)", data->pageCount); + labelOfPages = GetDlgItem(hDlg, IDC_GOTO_PAGE_LABEL_OF); + win_set_text(labelOfPages, (TCHAR*)ds.pString); /* @note: TCHAR* cast */ + DStringFree(&ds); + win_edit_select_all(editPageNo); + SetFocus(editPageNo); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + data = (Dialog_GoToPage_Data*)GetWindowLongPtr(hDlg, GWL_USERDATA); + assert(data); + if (!data) + return TRUE; + data->pageEnteredOut = INVALID_PAGE_NO; + editPageNo = GetDlgItem(hDlg, IDC_GOTO_PAGE_EDIT); + newPageNoTxt = win_get_text(editPageNo); + if (newPageNoTxt) { + data->pageEnteredOut = atoi((char*)newPageNoTxt); /* @note: char* cast */ + free((void*)newPageNoTxt); + } + EndDialog(hDlg, DIALOG_OK_PRESSED); + return TRUE; + + case IDCANCEL: + EndDialog(hDlg, DIALOG_CANCEL_PRESSED); + return TRUE; + } + break; + } + return FALSE; +} + +/* Shows a 'go to page' dialog and returns a page number entered by the user + or INVALID_PAGE_NO if user clicked "cancel" button, entered invalid + page number or there was an error. */ +int Dialog_GoToPage(WindowInfo *win) +{ + int dialogResult; + Dialog_GoToPage_Data data; + + assert(win); + if (!win) return INVALID_PAGE_NO; + + data.currPageNo = win->dm->startPage(); + data.pageCount = win->dm->pageCount(); + dialogResult = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DIALOG_GOTO_PAGE), win->hwndFrame, Dialog_GoToPage_Proc, (LPARAM)&data); + if (DIALOG_OK_PRESSED == dialogResult) { + if (win->dm->validPageNo(data.pageEnteredOut)) { + return data.pageEnteredOut; + } + } + return INVALID_PAGE_NO; +} + +static BOOL CALLBACK Dialog_PdfAssociate_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + Dialog_PdfAssociate_Data * data; + + switch (message) + { + case WM_INITDIALOG: + /* TODO: intelligently center the dialog within the parent window? */ + data = (Dialog_PdfAssociate_Data*)lParam; + assert(NULL != data); + SetWindowLongPtr(hDlg, GWL_USERDATA, (LONG_PTR)data); + CheckDlgButton(hDlg, IDC_DONT_ASK_ME_AGAIN, BST_UNCHECKED); + SetFocus(GetDlgItem(hDlg, IDOK)); + return FALSE; + + case WM_COMMAND: + data = (Dialog_PdfAssociate_Data*)GetWindowLongPtr(hDlg, GWL_USERDATA); + assert(data); + if (!data) + return TRUE; + data->dontAskAgain = FALSE; + switch (LOWORD(wParam)) + { + case IDOK: + data = (Dialog_PdfAssociate_Data*)GetWindowLongPtr(hDlg, GWL_USERDATA); + assert(data); + if (!data) + return TRUE; + if (BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_DONT_ASK_ME_AGAIN)) + data->dontAskAgain = TRUE; + EndDialog(hDlg, DIALOG_OK_PRESSED); + return TRUE; + + case IDCANCEL: + if (BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_DONT_ASK_ME_AGAIN)) + data->dontAskAgain = TRUE; + EndDialog(hDlg, DIALOG_NO_PRESSED); + return TRUE; + + case IDC_DONT_ASK_ME_AGAIN: + data = NULL; + return TRUE; + } + break; + } + return FALSE; +} + +/* Show "associate this application with PDF files" dialog. + Returns DIALOG_YES_PRESSED if "Yes" button was pressed or + DIALOG_NO_PRESSED if "No" button was pressed. + Returns the state of "don't ask me again" checkbox" in */ +int Dialog_PdfAssociate(HWND hwnd, BOOL *dontAskAgainOut) +{ + assert(dontAskAgainOut); + + Dialog_PdfAssociate_Data data; + int dialogResult = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DIALOG_PDF_ASSOCIATE), hwnd, Dialog_PdfAssociate_Proc, (LPARAM)&data); + if (dontAskAgainOut) + *dontAskAgainOut = data.dontAskAgain; + return dialogResult; +} + diff --git a/rosapps/smartpdf/src/SumatraDialogs.h b/rosapps/smartpdf/src/SumatraDialogs.h new file mode 100644 index 00000000000..6c2e4744691 --- /dev/null +++ b/rosapps/smartpdf/src/SumatraDialogs.h @@ -0,0 +1,35 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef SUMATRA_PDF_DIALOGS_H_ +#define SUMATRA_PDF_DIALOGS_H_ + +#include "SumatraPDF.h" + +#define DIALOG_OK_PRESSED 1 +#define DIALOG_YES_PRESSED 1 +#define DIALOG_CANCEL_PRESSED 2 +#define DIALOG_NO_PRESSED 3 + +/* For passing data to/from GetPassword dialog */ +typedef struct { + const char * fileName; /* name of the file for which we need the password */ + char * pwdOut; /* password entered by the user */ +} Dialog_GetPassword_Data; + +/* For passing data to/from GoToPage dialog */ +typedef struct { + int currPageNo; /* currently shown page number */ + int pageCount; /* total number of pages */ + int pageEnteredOut; /* page number entered by user */ +} Dialog_GoToPage_Data; + +/* For passing data to/from AssociateWithPdf dialog */ +typedef struct { + BOOL dontAskAgain; +} Dialog_PdfAssociate_Data; + +int Dialog_GoToPage(WindowInfo *win); +char * Dialog_GetPassword(WindowInfo *win, const char *fileName); +int Dialog_PdfAssociate(HWND hwnd, BOOL *dontAskAgainOut); + +#endif diff --git a/rosapps/smartpdf/src/SumatraPDF.aps b/rosapps/smartpdf/src/SumatraPDF.aps new file mode 100644 index 0000000000000000000000000000000000000000..e2fadb86f195a163b14f3b9ff84a2f1c95531d4a GIT binary patch literal 49724 zcmeI52Vhmjw)a;E7!;**FQ8xq@gf2y0Ro6f5)vSgMnVY^2?!`iNuhf=-q3A8LbHGn zsvyOHC?Xa>R1lS3L`vu+w9pZd^ZjPeIXgQih2V$pd+&XY?tP}LnOU>Sf7Z-7fQX1E zkKL{xvN=*~N{{ojl8zF~?abFR{* z?=R|{t0oyQo~}G@Qk=I)(gVgvuGg4B2j%Vm?2|Wb`(@0a!}9u&WAfIkC*T5o_a^L<8I$(NtZ94r+$ZyAZj(9h?~!>Q?3TIH_sW7nu5%l$GT>9C}XN|)rM6EbD&ahdvhx=b2*PEwLC$dpkRW$NgQd|u}Bs!UG0AyY@* zkZGfDkiR8Ucs~31sC@oOx~yKAE?=!aEbG2LDBrF-ARE>nk{>tyDnD)hO@99AfPD9D zx_rMOT{eDyST=rlTsCh!DnD;NE?a&+AwPb9hR+Pyx+PtFJl`$l)t;?C3Q)c1%6jWkQ zV#nLdh<&fO*blT7`>_PEXQqffYq{93Zp-dpp8nP7kHIBBNB>azGgek_`VT83_BXx7 z{y|%@f1Dupbt#OwT-S)daD> zlOp!dmWzGow(R~=QX=G^5-*QQvOFbe;wxLkPqHLf>}8%8yLY_U+m01`!VIyetPuP1 zjbh(+$kN}F{=W1Nq5q5YA4>lT^q)unPw4+O{ePf8bEfR4|8e?fnf+_a)6#|!dNaZ} zMwrhC8yMj*BV?7a%SCUyTyATZs|j|wmSUIRm)qs$HoMvXVfxphe>3_=(!V?X2h;y` z`oCAkE(^Tvva+pR)+g9yONw3gFSpC-ZQ1>c(_cxT0{tJR|6}xjg8sGX|6CcnM0?vM zp{-rsPGGDQyL_|UF8j7+_s<0g_qJl-ol`gKjCUrF>uv3DXZk)b4YYK)GyO~b23k7Y znZ8FHH0BIA`TV0vlP1r;JaC{@K1zt8f$aul(+~JpSXgj7_z4SD zsa|gSu(0N_7WyX`zcc*kRCnM&t9;736@4HqETm3?$$vssR?-W8!opRmHy{T;_x0%C zzF1h;{8L+w< z-{YC*pRMZ$<9;t2`ub;w4jrCHc2@bcY1ul20ln0E+XS_2t(IA)VWP61u$H7&^>fnG zO!9n1(K}KpFK{+b`DmIp4^``G=nMMr^7lXXoPuQ~A0t`hGcf8YQr!k!6oJlrKl`!) z;sal-quNL>Wb*@6p^{Tyg(8N?DWAWJ{=X+b*4W^l=ZS$yxBhT`rZa;ZW%Vh}&;K~e z%^aVPIzCG|K0O?t?tgz8aw|X%PB}Y27jiW9RHC-4b8HcEBCh9HPwM=5%yX=H%B9kh zCJetQ$^YSb?JDQc-{rmW`(@VDL!1i_aYj2NlgA$AjCYjJV|<>F_s1XS+;>VQjW{b) z$DEVt6Efu8H_prZZ=aVBCZ3U*laI)(DMw^R@(GzaDMLO;J_D^f7hZrqOC}{~vW?=a{Tmd{jPJd|Xy8JuaUuKO&!{9f$8DvS!s``J6Mynom#4SF29S`mavN zx-T>2yY(mJhYiO#Po9(?Hy)So)@8`1?=y_^%JZ_5v(5hBF37=y7v<2w%bYVW%i;9P zInJ2xa*q6zbL39TIkNoIBGrgFz2ZfhCX0lmiFD!|`f`@YP|l%mat@urIdmE4(6#j6 zPXA+;{!h@~FGA$`c#(n0^7lFR?{n-uJjZsh&yxZGHL^}xbZjWr+ zxw9t7yS;78$WD5MyxTi>j0kSkwmv-M({5C&`@R4E?a|TE29tb7M|V=$PL5B5|4zk9 z*6gS%i>%hQSz}cMW@?Kcs|iVwLjpgQq_uKovV936>4p->u7)Q>FQFVfO~r4NerH4J;eWR;;K3uU* zoo0^q`(lV4Nu%oQV^`F!O*?wAkAjETo&^5_hiGA2VNk2)vQ#-5RP-pG)5UOz+p za$06h&M;z=$s=w$;*t}@A1d}ZCG+1uMQoBGOXnYzMXAT-;{_*W$(&Qf97kluM<=<@ zJ}#@4pODonP8#vXm!A=He11Y!rJa(`dDeY(TsEvbA{*A8B=$IN#2%YBo}_%rh&_JU zoGHI-Chqtpljn@=*_~m;8oPI%BhJX+{`xd=26x!R8QZsJ$-cc8jJxcE#2H79T+I<< zNPIOegllsl?8}9)9~Z){rHs9^coRRgwU3ho`v;O@Um?rwo4DuBzRxW}98r`w;y&Vt z;=~aTq=}Ru4k?+1j_hTnDRD?=;*epC^LHG>efr<`@&5zv;{#k$GcOGqF4X}|n>H~T zTzmeZSRaQG*Lqd<{x7Kad;GCx0ReuGKk-EM+RXx<{a0PbynYY3H>JKr z`SRt2>Ywq4zG%|`-=YsbX`#QbM47rqyd? zm)`^Tx!qUROVRt4C{~&eWWlC!diyQ_so#_c$}ZdsaT0d7g9h1(`GD zqRgIrS>{f?BJ-wQmJi>*B#Tqeu&146Z#yfWEjua8KRhjIg%@P)nzOS0%Ph{%nX+xm8TPMpoR!ZR=i`mvX36#~ z7iHJ>i?Vy?Mfr8lCBB!vz9N*b~kIUwIR3;Yys-IpYJ<3yx$AgC>LlQVym`C;HXBGy=+U+H|H`M^^W%>P& zLf@j|MU0?OSp8baO*}mvC604Nq$0qh+SJL#owJHADSTI`-pCyPe#VbBPAXoK{rjT( zC0r&k?fv}TX|nOzR#J>lFPUO|ddpPf(?_Q9`G&NVG(Kxq6@d-ouGeng%F5N5D0|$R zlvANodx&%Ykjf&jm(vfGMzUYmzhAIl2T!y3odwVBtaQ14EM2lrrOVM{Mz2z8>%Wn`o4=GD z>pzk0;}^@7PtxSlf_ZY{i@9=U@dUZLB3Ukdm?ZXhQzf0}a&oey^BfyBO7_lMF56af zr~3IE*_xIr-+sPAHhsEK){_76Zu#@*@hn_`Gj4P`JGTw`fVA-S!~R=TV>(KWs>&gI(c)& zTKQt>LVg#OCZDcaB@0)sktK^4%Dg#~WzGEQl9rk*%b6o}O0vvL87;}Fsgk@fO;Tp3 zN%ES>GHv>7NlH$YB-ZoRsAPHPooVv++i%Orkt5~Myw@ZvHC|56PL!;7%8zgLk*!G)^3j{GNZRWOk~X57%o&p?Uyba--F&=^8ex-PdykNx2aOgq zE+6zAA?btSC4Fdf+1jJ4Y#k6U-}i}^wdB_gX(wA>jgU>3T!U3IzB0B9lYr4DXD&5@?mgI zNp9yQ$$p-a+{#l%hWN;cpvUB$MvT?4xg>c-$kaL&BzGrgZx*OTxarA`x3J$_wwNOUqBsOW>!cBxwA6=`m%IbRV58@#B)kYi*WzPXA53 z7M_q=A7x6l$s0xH9h1^4vZQqCRw*^%dxEX4QgieYDV>xieHQhR;iFz-zS2_V?MgTt z(e2Q+64WnCLgGhD{LmzMc~Fvg4o#J6ecw=wiFD=v_;?vIbg1<1!!Mn>Mo6Eo?Ij-B zz7!Q8;V-@<5nbaYqF21MYS%;jf+D0-=T6e1MWFa0j{yNSrH6k*=^Db*%1h!K28jPN z0n(?Amn8UG8Qp`Unq`AKO{PkG{BwWVHzdSH~Nlq_8qenf2l zBT|RVjLciT+ic(dVgc-Symq~#wb`|7ZOfTIk+Yb)TOYzHOl*+wu3Vs$%rCciw^5*>gYs zIP0QGQKMNUGjFris9`DCo}GENv$afq-2C|q7A#);(NbNX`nxl^&`~U2Jhf7Xj1C=c zwcWqv#qBl=yNd5@`i|GW`T1&_{L9%bZ&;G5J&{8{IoGGB8x` z;-{Z}+PwLfUw++p&743#3h`r~aZF*W)IYw0 zGp{}qQx=`GJ$v@NMM-0dG-}kSNmKui+N?W%^6Kx?OE`G=-4-)(=A1c8=rwryq&bT& z*(#=zidXG*=t5h(=V4ptA|*?fuTY~#?M7T=1Z3-{&x&g(4uo7R_8ohG5} z#2Tx9T-Mjwkj|)j0Y?ug{G%`Z3EkTW2>SIFAw!R_Lr2+dHCb z*ymq-@%8uLf4_NO1{Le~9Lm6*Zuh?S!X>mNBi%)?{Yhwpy)F$6l5YZyP) znI9Y9u$(imJ`*ZGy96bjzmi><=oUAC)O7LsO_;+^(>;)RO<&*6=tn9v8>-xDut$Yv z$xCe?bgA?~rHauH_rBF;yWu}>MT)q4czBdpS-NzEW`=&EdmYZ$x(D@yt~LB8N4aV3 z>7~%7P7ZZ8SeAxmy`Gjfq005^CpN7)aotD;doJtK(i!euPnrDDX-@w!`KM3x?VG)g zu2pUsAI?{Wgrw)H*s462lwh&e_MM9rDORlHV~-N7A3Z+<`38OV^>^QG_~D12f5s(l zpr77$H@jIj^y5~fC;~F{(<8iV#H!D=hBjZTLjTsQzW)B@Lx(bUfBm^y{zxyM`bTb` zE?Hv6yYHIjq*xjn-%x$nYz^aw>WuT9P`>h_N@FWOe@0bkz({m+b1zZ4dXvTLS8v+1 z@uwk0n>1?VeSR<0~ry1b#E7hY&mqlW*m ztr0<5JvqxwYfMC=#fm*ps`O*E9s037IQ0qeXX>&pVB3%A$C1=bF6%=-NN4y{-t_{8 zj{^E!`KL$mLpL+4@>wbKpc=qT32}~WT!L9=iz%n@%iW{YwoiA=Ito88wFn7Y_1WrA zzWV;V4V!!5U8}a= z;kCScj*t$|cxze?{rDz1_=!vM&E`ktUP(wOY2l8mms=f`X2R!S~K?uaZ1gs#LlW3w$}+ko{v_4z4r2 z$EDn)!bG>Gelf*%?b=nk2IM+DIkk$-wrm*%LqFC1O^9<@pVE(;d%#m8N4)j!!iA&J zPfq^TaFsG|W>m6OI(R`9?vP?U)PQb9JhpAyF+ClAdbHs8d$T`V@x>=7=$Gq`{l_fZ zZ2ks4@-g(&Gc>eol+w@VYXG?uRct+4wT^CFtXQeXX1v_-7bdS?3kB7$Uw`DN(Qi$g zO-0hUaVhf=eYtV*MpRHEetty)fN_BDV$E#1{s~iNjvG5JP!&5DsnfS_VjY9W(v24M z2>${F#kk==B~mLNwb=sQJSse=@y*bW9wPg#*p(vgMOUsYv9crrZyb$tq^6dB?6G0p z6_rs|&f+LHDL+KblVehft z9<5rTpt&nneDT%y8-6*}+emh^Y_m0meWg$jhkjb)Ksv2j^<@v${{;`0SF+Ke@0EV) zm8mu2t+(Eszi{F5(QhgJB#e*m7gv_dxP;n@o7(X+dEZ~RU;KE(VJMWXlkm#evCq|1 z&Hf5ZOVoC&TeoB!L0r$!&)0mrsf)1(rl!*FH)!&rB};`S+7mocdYg(9dF}AD8tt75~)K8Qx{;D-pdlb*d}>YD%S`Teq%g_nBDI?Xk(W znYGJ5m#rU5onH|{+!#zzk1p@C;GX|%+4{BFAIpjr7r**$^T}LgTN9%L0AuKr2VSRui3M8*s3*~I(LcbGGzL6`q?TE zax33#($Z%Jl`Bbj@J!W=4$-$NMpw0Ua0HXuoRkN7tSnLfysdXpw;^=JgK8XB{awoq zD-Kd~p~PYjJgD%k&QOeLOiF`)Ke^1|KMwsY9^VHIxvZ~=q!yiC#Jh|SV-y)NcPjRg zgMT$8sl%-cnL0PPwA*8oY?Eu03oy1@qta6MNasdP8~McynVy}~+ zYV>m){p2j$8Y%Xb$PN8;LqDy<6uy1_IlB+~{YR^+RYOCI6zkmG(2sYSkp?viS~%hz z2>SNx(?2Dpk*(|$r+yZdwKbZuFs@I(6oWfnm4?kY?ASap2XXhPrlx%Q?FzQ;ty+h! z`jJEwcikXwUbIN5!T66`ks8dPOP3+Trl*#w zaY*%dEi3(e`Q@%%MRx5fR?gUe`lZa7GG&hK$$wAHp`XQz$D<&d%laC*rHY%Ix3_md z!0_RtMvYeHY~|lz*;Xav%7qJtdDsF64VpOd(&WI2AAF$Ocw6fpX;Oi!LH7Hmsa=|& zpIG$K^3{;pVG~w=@zoD|bCqokm8eLB;|$d;xD^Uo)gABYW$35-KU%eFT-C!P`q1hx zet_VqGXGK3%7Ye;RQh?k+T(TO#*G`AJSDywMO(G_Mae@`QsVlQt~O4URq}lydYES4 z=Id65XBzlwi*b8w=B1fMsxL8`^vhaTv5A{U<;uP_ z%f6S|g%e@7f0A0YdMU&RLiC}GLlvVtRMAI2qIZY?Xa$|OJrT`#UAh2Y zFBlp$$_AY2a-BMLo+egINJt{RZOl-;f1MQc^Wbnt{C1*5iP9>5Gxi^s_4&FP5u7>| zXzpD22OFv$%rsPUP%9|V?Xkg2XS!9h>L*9tzf=e(?j?Lv+c9J}BgNtnDn;fh+l&d7 z$j+-{)Wcm>((18QR{AkgcikU?S_Tv|Ly@9yUYw?RMnQN(_3FA*y?Wicb)PQnXfi&! zG`4xnAUGz~psQPxiB*h(P3b3iZSbCm-TPK=a_Hxo7$O9lzww5uN{8agf1JtbKQK_l z-5sGtS5+fQk;X4;5|?tFM<0Du@$+<_KK=0qpT-%b8Bj-$2p+QHl6*vOXcZGfUPXuv-x)`qQV(xs$RWXNoT%fwd!WxsH^xw zaROf*Ak?T)v!-vON={m34{KYu4nMxW_j;{Bn{7}L6<-fA-nxID`cZ08Mjahpu4vJR zqaEsTE#p5pP`|!$ams@n)Ami6;>dA8Mbi%bs5(GbU? z1`mGanl}$DI@39U@tLEpTv@}SJbY6TLk@?4*0s!pBt&MpgfNEe(j`Vo)S!3xld4z0 zA9;%7biI1@hmRa-P~P!XMIlc`#|DxIbyQS0r*2eh(?M!+&l+!ox=M6*b0hu?n~|C} z_4oJdtlFQ5?$x`KQ$~4|jWKe(%4UZy*1H2mOonW6ZqjauDQKs2L{W$@f6&&kWh^+wSl^ zvijvMi9W7LeT)3}|NlQp;Iq#@8asCEh7B9qw{QQ_OD}!&(MR{( z7&uOGYtp!JV={#q{BG$BGiKpwdiCm6c;Y`txq9{L?na7tF8CTovSi5;Xn2#ShI(4_>}9R|?z`_m z28c;`v9^5u&46h-e8*|+QusW-8PmTcG2bBE9lI-swcB~;nc&JC0ek~D)~;PU)tM$4 zX_S%v{qKMG>C=a`ELyb4>{37mg+h$+^EUT)4B-9u-{-d=oUna-d{!BW?E~5J_gn-z zQ=Z^p&IK{X!;bUGC!d&=E*VT~!h{Ks6-I0HW$j$bplJU342r-VSch;Bn#;&8MSc-* z_3BmVb;4l4bHoV5;qvSkdZ%D0U@bmAe*gacc`AZdM#ei>7bb@^NI<4J-SFYV>E5qj zKkDI=`xlxH9z1AubFl8)Z@=aDg*a)`rcJ>&U=461e$y@hzQOHYBmMmI&j{xmBYpbm zryqa(F_iP?&xbvJZDchJlLs@S!42gSvA_d^V=`uI?o5942#SdclX8z)_!_{0#TEwN z?#e!uZRGSUy5rp_QDX>*goO1bo*%vyU_a&pF=Ijt^v){GN;5+%+nHI^84#6>euG8W zHbBZ;SQmL6SV91w|0o-uU zLx&FW(*Oua81M>b0_}h}ywB{S`Nx~6G=n{2Jca_+rcIm1555?|G%Y}K-n@A!DJei4 zdgoFIw>^CLFkF!V-jFA60y%Sv+!?S7f6)+^yH(eqF9;xmI6oR|{cEqi#$v%J4JjJ# z5Dp-0CCiWsPW=gkV{z32scv(p=)VLee8Bwm8JXPp5RSt+zavw+l0RElZa! z#m3l%OerNKBv2#~R}k~yO(bj&EogkxHP*L_Lhs5xb9)vZI(znPAP(HHCPE!6P*^7| zzXERsiAK&9@&>M+aAn>S2wYC#(|5C@)U7jwZkJO$Ul^n)OGQ+_q*SGzW5 ziAI1&Rt*&M2bZi}w8YS$nY4W(+Y1*iu!>)P`330_#X&$5gTM@F!GZHP0rq65nS==Ze)Q zHjhD~DeMXfgL0f!zz0)btPU7FcI+4-)6Shc0lFW4_yMd268Whfh=;5g7O@kjAuc^Q zutp-!y8wF4m{kj!CAMt1f>kYTlYguNeA5u8LpTS<8L=E-MFQmr;gnL0dwUQVgTxx4 zM?`Ei*gR|lR(KhfPr|y)DOdtOLIO8{IPlF(I3rzD~x;U$vCd!_L zTCq|q<^Vga1<&FD?h?7(6+M^Y49=ySa4xIL zfHEt-p$ov7%G~4Vn!B>k+@1x`xUCLIFlIJu?qNuv6N+YvyRsiElh_*;0>tTUizaH2 zKerH8vcELXg%8$(rmP8IrxLp&v1E>-sKeA3kb*WL&=7}qfH(~FdOLpb;c-w5Gw z0enqwzTi2n;1#BhYs0)Lc8;aS&nz7frw^+52qvL-It_7F69uVWdF2&u2GA_gui1ot zsl-nSD$Mc8P^1z{7NYCT?${gMtxGmLG8*aw;<$WZBDw%^j6Y?{6qAMw5<`IO(V!U# zoM+*tc(tx^NsVuMzd&dv#9{vstLV*$--!2EF9hbI)O2<`+MyE1G*4bkt-|8J1ug zCq9CYvr=%q0~bQ#%XhiZt{#=j-dsPDj0Iz)XR)Fb!98k?}SKmjF zST!8791`b8yC06QpcfYx zhcUxye)vWcg366=EK{#k4|rGh3AadwMQO1Bakwhx&91Gr%t8<;t(@9OOmSECqgk@P zHN>H75;w!SgExeOh?pH?z>4ULBOq8d5sVq2vySGHzhhtgf)(kdS>IH$C25ZU@z4lZ zrw2!#{K`8cBLg`QZL$qvu?S5=9IF80umO&!9XocU%iYq`1+cX;L*8^Q7kpzc2HbSg zw{2*Ugw{w*O~OM-oV@fAm6~(s&SCi&HcMc?){Dik*=+$U;ysu*B?&zS0Jv$EAl70* zDf+mlAr9v?yMP!t5pUupRA2=h@QvtBA&limZWO6hQ#dQ>LPxsmp{#?OG-d`X#U!vv zmti#l(tvZ8hEjACN8T!4P?Yl;_{O9x7GZ*}8sZ3L^{$8Wa=62(nTupjO$N`!sTmMy z;0vq*eB+o*T!AkmB`Woo3siz*ARB-NCzuMtCqpF{Zo1MsvXy@;!`3KH;~P;NXrR3w zMWZ0-^~S0h*6yrNj@EsIDejgYnZUMQvdNVRry3p+g%yH`CkflkZBFAG-!*86V=n;W z%!Pw#1)NVA76J@|42fQMWuJH!tRf9Wgk&&g+ywLH?!{aSl_-(8OXJ&J*^jvjYX;4t zYmiM}Xjq%b6F#9AW(VK23xIN*XfPhE&gC-sZu@c-h5=*wtb#Xir;j|uZvYwrD*g@u z@r(<;SwlFC6OFV9Z(2UcA3Q8PJxhQSQ`%-m1B(m3;X6)vQ=i%~b--r6&6_tZ z9Qe`rhFg)aRT6`Pcnl8cx!{{N08XPWoZwj+;t1r>i@vPTQ(%6825*GPPEArPGQusy zm><3YV%h~DhKyk~LNb(#OX^wl8#BN{uvKXCytXwr3k;h*3%1qmlO+*;#Ky+z0E7Jk zIUq@7f&g(eGwGX2-dsCa86eMgfWII^!X%g>T4OEX8B5;Dw~bzxT+JhPbi zhAzmvj7$+6U>q}eBctOtMmF!?_&OC`Xn$vLjc)+5#$+uYoEr9U9Pq(9%iYpzeABDr zP(Z>BN${gHKpaZZ%$O6QM9cteN3$d{G+}Q*99~vPd{c;K;F}3?402cYsXYr(U<}#> z=&qAyUT+HMi-e9C|E}!ET(6ly-B_lM+|YP#OGYy2l>LGYokW-fzEQ~yC&2*UMwvt9 z&J?CEzkg#1%Djy*NqfQR)2BHM0($5I1Au^x9v=)e@ro!8-nfVZ-@q0EHt>z@0Epx3 zRJf(f-O|$q6Vk$Wd1DVGRBWyke1iw=k{amnN}LoBBN4X2ybHe3s_~6p1U$GEE>B{U zMWM)n#4VgT1y09`^aX{<55|lW(F?Z%h(JFpzJVBE2!h3&U;s6d*uk+G#E8VK5gijz zq!LVk05Ti_GoT{~2{Y z-^^KbhK}qY^krRED`ghEgUt?6!y7hW2ISxgXj3r0p(#|LdDi%5jo;wE@b;-aOMynt zr2HzUXPF|pEBi5f=?u{VS|(|k^Cpj}yO05`u%nR>e8YHn85ywr$&nU{MEH!SeOsxB&QOCLNf8A)p)yJ(^#tYJ9s}dS=lg&8Y#k*`ZvW z%w>YW7z`Fg()h-7Dn4-@^mInyi;*Zo0KS2?;sCKL`oLnIrIx2?EJ&&!|8{ z949-_!0PoXq&FCV6HFSz=JH>KaoxJ<;LU|Yiu#DEX*j>o1sgVDhwdgnE*Uz4Z*UIJ z7zW2Q7Xs|WDoK_PCGlQvN;<;17A7mABg1lk0zD|f0)cVxO^4+!vw&|P11DcBf%uJ9 zT|>M?1gL9t7yJ>U0t0z7K1C1@+ve>urY@>qMCTR1QHcsj8sZ4yunoHK(+kkvT(XMc z#*c@Lbpdh6iW#jFxzN+m3URsV5s^;pVkFdr<*@ycP_CH>iLJAcN1mt^-q5m%Z>SiE zVCS#|wm{ zmkTk)g6ZkvB2vv29dR_2%iCl|f34uOIQ8iQ9h#CZR(x||iHHt}%fY(k&ubt7@XdNb zVM+Sy!HtdxP~#g>F;K=EVtB)C3EmJRewQb{fkN!0I)2k;iI81tOvW^t5d~>{ z!xzk^+?o91H?0K)a90(?ku<(B0tlwYv?L8#2+A6nn{(Y2Jt9J+Iyu#~%z!$DbtF6v z#LJCuOb0y>$Nr_yr!gVJ0n`Ma`DWqY|&o}Oj$!%D3^ z3br5J3k(OxIFo{Jc$PVo&ajcOeCu5b(nDx~8y6h}{Dl1!iH`7Dm%h1+h3rf4gP>Rl z4yyt>m?FK6#>w?sB*E^l}lY7BAztfSbuuo*A57 zJ3g)K;P@srx_)9{6qIM14uE*Y92fU*D@moD%R zz5x`vp7okbHYv3yY6jT8aWQmiwz_1j`vv%>Lt-kiGy*fu7rb*rs2&8fL>ksmjmX5M z#$~$ydwjFHp4IDtEWC`BV$URarkE$VX_g94kNucQ!y3*Atf>Ql5y+V#oXcW$5lSLG zVun0hsRYUtniH;x{6kJd-v*9gXWC+&Vr7Pm~4b0Lw%X z`T3gJy87 z8382%JiG~|blw``x)8e*3*Q$A?z!}zofn7gxR|*8Lf@?ydT+U~KJ&Vj{``&G zvon5AIevY_;cJNpuXf*erQM#(Eq7dMy!B$;pD#SIIqS!ZH?8y+Z~XDe*&FjRexG{c z`j{iv1|PiI^S3J<_goI%d8x^^i(bE6_$ep-)myhWUc9yX{LLk2Zp=9K`&&n^4Nt$? zcmLHFe!UXD`*PrpOIt79vX0MUum54c`iK3>E&HWgxA$JXHHC?eUK@PqYOmj}#O%Gi z=W-7EQ&(?J*?Io;U(O9!m$511>cv~P>BT$i*6s5*Z=d7e9%9e7goPJw{4wR=mC5@r zkJxqbl^@Uc-JCgQ$N8k~=U?4=e(;uaiCfNPT+6ZEYqxGsICeed;FVeFSC$;U%9xk` zP*YrRj(_8i9OM7NKX!!5ZrlI3trTaS`hQtIryuPov>$EYUnW$KGyPYJWo_6$?rORX zohts6(4_EPHoaK+(A+^=20mNJEfp_vfFPQX4Qv09#Vd2^JbC1p|)ZeOi;=^I*H!eMuR@j|7 zb8*tCg~QG1?wC0>cg!7W{%V4pezddDe)RulKgv%UE9;fbuPJx^hFI@ajmzb(&$DJz zpN9LUzPQ@2e4ec?mH5$tS^f7<@BLNF3NB5#i@V3P!jFD?_oaig6V^ulGdF>?X8+XK z{ewQIKA(yo;jKrPj@s1o;oLMXHR-7d_|fr?$DUX* zeoJC4m)1Os_z_)Bt)9Ab_%nGD)cKG)f|4O`+?+6`L*U*fArn# zuY2+&xaXBQ{b<);=SQvjEo+suI&xT!KVOjFa@vmm()Q_||9rZ;L&~==_xUD2GF=}% zVco><4yEomIr)e5Zqqk)X*b`6{^e2MhmHLvboAF=!x}u5;PphGT61@un!hI_Y0Wbo_>c;iJB^5)Vk;GIztl+c$r| zb^TJCnNdO0Lc4s}bIcEKMNNOc?%;Y)#;L!P&HVqZ)q4kjwC#_Zzu&xa{>J4qkqcwq z**`OG6_GREberl|D~DQf_tm3}#tKKQg=z`g4E#kyW;Z$@}q-6M1sTvD=IB zj4+Nn)_7aWK166 zA&-k6?QT@^qr5!Fb<*okw}@~@pCXPv%~?@@>2C0!leS1iA1MQMaXD?wKT>MK_e-p? zvH9PVMwi!Nz|$B{$#;}dSCD**N)P_qD9;&`{xX37;^3h-ybOdBPZ>gfAX4>|2qfBq z&zGp_OWOcxMz6w4Uqs3O0r}h_|4`=XW6TpJgQTA^Ya(ywTs>%eiSi(39LU_=B%c5J z!a;X~wm01NH+YJZ#C&-)7H7QN(N%G&Xz-9_$TEplsWJZL7=Hl#c*2QVyRxuu%+)`8 z0CHO2HEGY*cPB$0Imi@cL@Jt6bWR-`aSEg(}FlvmZY_& z)-r$<)nzq3sC7+6@UMrZn#FD+TvnZz&w8QfVeoy%;AMm{DA$!zpQjx%jOHE8KZem< zLZm%b5JWxyc&b6?CHEIKGQ1Ld4u~6+*u7`nUg(W-!Tpt{(WRw-^&UN6>fOJmr+-9L zyY_*>;jyiP0|SG?Vxu~R284%1J@i2J-u=7x9n_a5U z@#4|AKGIlyjH6D;)d-mQY{@f`N2Ox)yH97ugS?L;?@GVOQLpHo<0yKCJ}T8WeM#*e z+EYrG&eorzsmbHX-{r8`$Ej{59VLKI zyM3cUmLyj+b+0WNRW7Y zc_|yjA!7rB{X@cAdW*MDV`XO9Rk1C@+l9wQ__u_dw&FS4g4)p(71c33GElth;UhVk znKqWz@aDn(?dV?5oBfZWo5wb99~niLNdK19`XCc(BV$ATgTq=x`iBOI4~#vihl*y9 zj=^CL2BjV?59t>FfbjP10>Y!I^9JY`A~e>hlll;q(iK6`!R;t}tM6_UL3l(^7-b(K z3ZvXSBs?mJih5F3S3Dmc9va&sSgngC*Y~O~U&D*v24~dNmeqOaT5G+NFYIf=v z9N4ZEExuC0rKLk~RB!+?ukY1R{$XkJRm|4+Y9#-(RMt}hsPEMn49_0l+gDY3dr2ir zWh0}`TPj=Xj1j$k*fg>`8v}aRlSeFd-VM}v^`(ln&Zhx&4Wz2I&X~hj9<|gNT^r&9 zmMK)vMuIV#BJuW#Rh5m|y|ODC#n!7Q^?kggx~}XH9MmzkV{p4xvHr~?!vp-$myfry zc{PmD*gQO}U2s_Y@b*zO`A7{*Q&ezR%a9<4vV7{v6PC6X{>^EnOMT*-yhe*PDHFgh6J@xy!Z;yrE6PcaLZPzv7yw`jfR_q1w}gz$ET4zWoe0s4C>(Iva#AQ z)PP2x7QvBG&Q5qx9ZOS)e|C#E@j-ScZJfBy)4DPuGB^x&5UiK3Fyt21D!ilGZ-Zjn zg@=a(_(wufA0RNs3H5Ii6dM@S!oPh;yV%Ge|G*&C+(2zada+SBLC2r~KCs$)zEaQG zfV$d81t}+ao`!~M8&*A{{5u5sqoI0@q=Bvp@egYmtNaaX0Us5SQPqN(8hA@XOI1V& zRX)AB6KFd^1MKZfY5> z8oZ^cZU|`Ku3dPTkE-)gX8|>xB343t8-I55B*1Jv+h=dsoS#8LhLS)c-GZ-OMFF)BEujmB1L zeWbOeR{4aYt*3%(HMl{m{6W>$C;ZH=HEP!4+sSJI3TiRscL{vFgD_0?sG+29`- z*e=}B(tzVXEg%q^LU41bMfE{>rKnt?eA0f}GvGF^d7BHeC{L z{>*?*tqBfu#*Led25a2t42V4*>;s_2;4FzO^7}`}|-ACQEILE51giLH(lE;nnQ_dJ!--pyS?mZAS zH0s}b-0E?EQFR*@$BoE~aGA&s`64_aYzM`*ToiRMnBH*F4N7&3(<4`(?etOiE9zEc z0K4%3==*Xj5@Vd#`_e<*Jh;xZBi~;Ap&x3T?sM|CGv6NZhC~N5uaeJzTyyQpx96*d zH2UF?>ej}U$K8eKr)E?)5!t-z6VUxdd%%^t5$bN}OzBQZL6?+a730*9)82km)x;y& z=M?aT9V6$lq|Y-k5s7iH^z1%xKul!MZrullN5w=LHx4oVdd4KGnz#WfJ77@1ZUYm$ z#rJqAW=Hcc zJeNI(uge@NCb&0~G&3e?U|baBd4q6orfIG-{f z(I=ZM#2K8Qc2{l&&)iN}c+Posac}sJ%*}W1Fgz;{)}0(G9B^LMO-F5DP*iZsFfNC} zrDc1LvmwD@L4@RvR>E9$iKO_k+$-H1l`SxM^;Jhzmz47+jWG01NiAAE&~0^h-75*! zNY=fQBa}MPS?>MZ6bZ?Ln=zdha_f~w)^2y_(e2i|--X3RhL&=+>p86L8@c@R5 zeGZ39ssCX?eYBle^~5q|ZGn9hg|gr5?;YNzTzsLj;XnU9i@I4~$r#GE^ZIT>-P0HU zNVVsEPp|IepEcU^zLQsX>+jN@`))mZ9qJslb)}WYd5+4aQL(SzDl5&8%$!pm{|96{ Bwb%dv literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/SumatraPDF.cpp b/rosapps/smartpdf/src/SumatraPDF.cpp new file mode 100644 index 00000000000..25993e7e0a6 --- /dev/null +++ b/rosapps/smartpdf/src/SumatraPDF.cpp @@ -0,0 +1,5116 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ + +// have to undef _WIN32_IE here to use TB_* constants +// (_WIN32_IE was defined in *.cbp - codeblocks project file) +// ==> we have to use a stable API instead of MinGW 5.1.3 :-\ + +#ifdef __GNUC__ +#undef _WIN32_IE +#endif + +#include "SumatraPDF.h" + +#include "str_util.h" +#include "file_util.h" +#include "geom_util.h" +#include "win_util.h" +#include "translations.h" + +#include "SumatraDialogs.h" +#include "FileHistory.h" +#include "AppPrefs.h" +#include "DisplayModelSplash.h" + +/* TODO: this and StandardSecurityHandler::getAuthData() and new GlobalParams + should be moved to another file (PopplerInit(), PopplerDeinit() */ +#include "PDFDoc.h" +#include "SecurityHandler.h" +#include "GlobalParams.h" + +#include +#include +#include +#include +#include /* for _mkdir() */ + +#include +#include + +#include "str_strsafe.h" + +#include + +// some stupid things are in headers of MinGW 5.1.3 :-\ +// why we have to define these constants & prototypes again (?!) +#ifdef __GNUC__ +#ifndef VK_OEM_PLUS +#define VK_OEM_PLUS 0xBB +#endif +#ifndef VK_OEM_MINUS +#define VK_OEM_MINUS 0xBD +#endif + +extern "C" { +extern BOOL WINAPI GetDefaultPrinterA(LPSTR,LPDWORD); +extern BOOL WINAPI GetDefaultPrinterW(LPWSTR,LPDWORD); +} +#endif + +// this sucks but I don't know any other way +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") + +//#define FANCY_UI 1 + +/* Define if you want to conserve memory by always freeing cached bitmaps + for pages not visible. Only enable for stress-testing the logic. On + desktop machine we usually have plenty memory */ +//#define CONSERVE_MEMORY 1 + +/* Next action for the benchmark mode */ +#define MSG_BENCH_NEXT_ACTION WM_USER + 1 + +#define ZOOM_IN_FACTOR 1.2 +#define ZOOM_OUT_FACTOR 1.0 / ZOOM_IN_FACTOR + +/* if TRUE, we're in debug mode where we show links as blue rectangle on + the screen. Makes debugging code related to links easier. + TODO: make a menu item in DEBUG build to turn it on/off. */ +#ifdef DEBUG +static BOOL gDebugShowLinks = TRUE; +#else +static BOOL gDebugShowLinks = FALSE; +#endif + +/* default UI settings */ +#define DEFAULT_DISPLAY_MODE DM_CONTINUOUS + +//#define DEFAULT_ZOOM ZOOM_FIT_WIDTH +#define DEFAULT_ZOOM ZOOM_FIT_PAGE +#define DEFAULT_ROTATION 0 + +//#define START_WITH_ABOUT 1 + +/* define if want to use double-buffering for rendering the PDF. Takes more memory!. */ +#define DOUBLE_BUFFER 1 + +#define DRAGQUERY_NUMFILES 0xFFFFFFFF + +#define MAX_LOADSTRING 100 + +#define WM_CREATE_FAILED -1 +#define WM_CREATE_OK 0 +#define WM_NCPAINT_HANDLED 0 +#define WM_VSCROLL_HANDLED 0 +#define WM_HSCROLL_HANDLED 0 + +#define ABOUT_WIN_DX 440 +#define ABOUT_WIN_DY 300 + +#define WM_APP_REPAINT_DELAYED (WM_APP + 10) +#define WM_APP_REPAINT_NOW (WM_APP + 11) + +/* A caption is 4 white/blue 2 pixel line and a 3 pixel white line */ +#define CAPTION_DY 2*(2*4)+3 + +#define COL_CAPTION_BLUE RGB(0,0x50,0xa0) +#define COL_WHITE RGB(0xff,0xff,0xff) +#define COL_BLACK RGB(0,0,0) +#define COL_WINDOW_BG RGB(0xcc, 0xcc, 0xcc) +#define COL_WINDOW_SHADOW RGB(0x40, 0x40, 0x40) + +#define FRAME_CLASS_NAME _T("SUMATRA_PDF_FRAME") +#define CANVAS_CLASS_NAME _T("SUMATRA_PDF_CANVAS") +#define ABOUT_CLASS_NAME _T("SUMATRA_PDF_ABOUT") +#define APP_NAME _T("SumatraPDF") +#define PDF_DOC_NAME _T("Adobe PDF Document") +#define ABOUT_WIN_TITLE _TR("About SumatraPDF") +#define PREFS_FILE_NAME _T("sumatrapdfprefs.txt") +#define APP_SUB_DIR _T("SumatraPDF") + +#define BENCH_ARG_TXT "-bench" +#define PRINT_TO_ARG_TXT "-print-to" +#define NO_REGISTER_EXT_ARG_TXT "-no-register-ext" +#define PRINT_TO_DEFAULT_ARG_TXT "-print-to-default" +#define EXIT_ON_PRINT_ARG_TXT "-exit-on-print" +#define ENUM_PRINTERS_ARG_TXT "-enum-printers" + +/* Default size for the window, happens to be american A4 size (I think) */ +#define DEF_WIN_DX 612 +#define DEF_WIN_DY 792 + +#define REPAINT_TIMER_ID 1 +#define REPAINT_DELAY_IN_MS 400 + +/* A special "pointer" vlaue indicating that we tried to render this bitmap + but couldn't (e.g. due to lack of memory) */ +#define BITMAP_CANNOT_RENDER (RenderedBitmap*)NULL + +#define WS_REBAR (WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | RBS_VARHEIGHT | \ + RBS_BANDBORDERS | CCS_NODIVIDER | CCS_NOPARENTALIGN) + +#define MAX_RECENT_FILES_IN_MENU 15 + +typedef struct StrList { + struct StrList * next; + char * str; +} StrList; + +static FileHistoryList * gFileHistoryRoot = NULL; + +static HINSTANCE ghinst = NULL; +TCHAR windowTitle[MAX_LOADSTRING]; + +static WindowInfo* gWindowList; + +static HCURSOR gCursorArrow; +static HCURSOR gCursorHand; +static HCURSOR gCursorDrag; +static HBRUSH gBrushBg; +static HBRUSH gBrushWhite; +static HBRUSH gBrushShadow; +static HBRUSH gBrushLinkDebug; + +static HPEN ghpenWhite; +static HPEN ghpenBlue; + +#ifdef _WINDLL +static bool gRunningDLL = true; +#else +static bool gRunningDLL = false; +#endif +//static AppVisualStyle gVisualStyle = VS_WINDOWS; + +static char * gBenchFileName; +static int gBenchPageNum = INVALID_PAGE_NO; +BOOL gShowToolbar = TRUE; +BOOL gUseFitz = TRUE; +/* If false, we won't ask the user if he wants Sumatra to handle PDF files */ +BOOL gPdfAssociateDontAskAgain = FALSE; +/* If gPdfAssociateDontAskAgain is TRUE, says whether we should silently associate + or not */ +BOOL gPdfAssociateShouldAssociate = TRUE; +#ifdef DOUBLE_BUFFER +static bool gUseDoubleBuffer = true; +#else +static bool gUseDoubleBuffer = false; +#endif + +#define MAX_PAGE_REQUESTS 8 +static PageRenderRequest gPageRenderRequests[MAX_PAGE_REQUESTS]; +static int gPageRenderRequestsCount = 0; + +static HANDLE gPageRenderThreadHandle; +static HANDLE gPageRenderSem; +static PageRenderRequest * gCurPageRenderReq; + +static int gReBarDy; +static int gReBarDyFrame; +static HWND gHwndAbout; + +typedef struct ToolbarButtonInfo { + /* information provided at compile time */ + int bitmapResourceId; + int cmdId; + TCHAR * toolTip; + + /* information calculated at runtime */ + int index; +} ToolbarButtonInfo; + +#define IDB_SEPARATOR -1 + +ToolbarButtonInfo gToolbarButtons[] = { + { IDB_SILK_OPEN, IDM_OPEN, _TRN(TEXT("Open")), 0 }, + { IDB_SEPARATOR, IDB_SEPARATOR, 0, 0 }, + { IDB_SILK_PREV, IDM_GOTO_PREV_PAGE, _TRN(TEXT("Previous Page")), 0 }, + { IDB_SILK_NEXT, IDM_GOTO_NEXT_PAGE, _TRN(TEXT("Next Page")), 0 }, + { IDB_SEPARATOR, IDB_SEPARATOR, 0, 0 }, + { IDB_SILK_ZOOM_IN, IDT_VIEW_ZOOMIN, _TRN(TEXT("Zoom In")), 0 }, + { IDB_SILK_ZOOM_OUT, IDT_VIEW_ZOOMOUT, _TRN(TEXT("Zoom Out")), 0 } +}; /* @note: TEXT() casts */ + +#define DEFAULT_LANGUAGE "en" + +#define TOOLBAR_BUTTONS_COUNT dimof(gToolbarButtons) + +static const char *g_currLangName; + +struct LangDef { + const char* _langName; + int _langId; +} g_langs[] = { + {"en", IDM_LANG_EN}, + {"pl", IDM_LANG_PL}, + {"fr", IDM_LANG_FR}, + {"de", IDM_LANG_DE}, +}; + +#define LANGS_COUNT dimof(g_langs) + +static void WindowInfo_ResizeToPage(WindowInfo *win, int pageNo); +static void CreateToolbar(WindowInfo *win, HINSTANCE hInst); +static void RebuildProgramMenus(void); + +const char* CurrLangNameGet() { + if (!g_currLangName) + return DEFAULT_LANGUAGE; + return g_currLangName; +} + +bool CurrLangNameSet(const char* langName) { + bool validLang = false; + for (int i=0; i < LANGS_COUNT; i++) { + if (str_eq(langName, g_langs[i]._langName)) { + validLang = true; + break; + } + } + assert(validLang); + if (!validLang) return false; + free((void*)g_currLangName); + g_currLangName = str_dup(langName); + + bool ok = Translations_SetCurrentLanguage(langName); + assert(ok); + + return true; +} + +void CurrLangNameFree() { + free((void*)g_currLangName); + g_currLangName = NULL; +} + +void LaunchBrowser(const TCHAR *url) +{ + launch_url(url); +} + +static BOOL pageRenderAbortCb(void *data) +{ + PageRenderRequest *req = (PageRenderRequest*)data; + if (req->abort) { + DBG_OUT("Rendering of page %d aborted\n", req->pageNo); + return TRUE; + } + else + return FALSE; +} + +void RenderQueue_RemoveForDisplayModel(DisplayModel *dm) { + LockCache(); + int reqCount = gPageRenderRequestsCount; + int curPos = 0; + for(int i = 0; i < reqCount; i++) { + PageRenderRequest *req = &(gPageRenderRequests[i]); + bool shouldRemove = (req->dm == dm); + if (i != curPos) + gPageRenderRequests[curPos] = gPageRenderRequests[i]; + if (shouldRemove) + --gPageRenderRequestsCount; + else + ++curPos; + } + UnlockCache(); +} + +/* Wait until rendering of a page beloging to has finished. */ +/* TODO: this might take some time, would be good to show a dialog to let the + user know he has to wait until we finish */ +void cancelRenderingForDisplayModel(DisplayModel *dm) { + + DBG_OUT("cancelRenderingForDisplayModel()\n"); + bool renderingFinished = false;; + for (;;) { + LockCache(); + if (!gCurPageRenderReq || (gCurPageRenderReq->dm != dm)) + renderingFinished = true; + else + gCurPageRenderReq->abort = TRUE; + UnlockCache(); + if (renderingFinished) + break; + /* TODO: busy loop is not good, but I don't have a better idea */ + sleep_milliseconds(500); + } +} + +/* Render a bitmap for page in . */ +void RenderQueue_Add(DisplayModel *dm, int pageNo) { + DBG_OUT("RenderQueue_Add(pageNo=%d)\n", pageNo); + assert(dm); + if (!dm) return; //goto Exit; /* @note: because of crosses initialization of [...] */ + + LockCache(); + PdfPageInfo *pageInfo = dm->getPageInfo(pageNo); + int rotation = dm->rotation(); + normalizeRotation(&rotation); + double zoomLevel = dm->zoomReal(); + + if (BitmapCache_Exists(dm, pageNo, zoomLevel, rotation)) { + goto LeaveCsAndExit; + } + + if (gCurPageRenderReq && + (gCurPageRenderReq->pageNo == pageNo) && (gCurPageRenderReq->dm == dm)) { + if ((gCurPageRenderReq->zoomLevel != zoomLevel) || (gCurPageRenderReq->rotation != rotation)) { + /* Currently rendered page is for the same page but with different zoom + or rotation, so abort it */ + DBG_OUT(" aborting rendering\n"); + gCurPageRenderReq->abort = TRUE; + } else { + /* we're already rendering exactly the same page */ + DBG_OUT(" already rendering this page\n"); + goto LeaveCsAndExit; + } + } + + for (int i=0; i < gPageRenderRequestsCount; i++) { + PageRenderRequest* req = &(gPageRenderRequests[i]); + if ((req->pageNo == pageNo) && (req->dm == dm)) { + if ((req->zoomLevel == zoomLevel) && (req->rotation == rotation)) { + /* Request with exactly the same parameters already queued for + rendering. Move it to the top of the queue so that it'll + be rendered faster. */ + PageRenderRequest tmp; + tmp = gPageRenderRequests[gPageRenderRequestsCount-1]; + gPageRenderRequests[gPageRenderRequestsCount-1] = *req; + *req = tmp; + DBG_OUT(" already queued\n"); + goto LeaveCsAndExit; + } else { + /* There was a request queued for the same page but with different + zoom or rotation, so only replace this request */ + DBG_OUT("Replacing request for page %d with new request\n", req->pageNo); + req->zoomLevel = zoomLevel; + req->rotation = rotation; + goto LeaveCsAndExit; + + } + } + } + + PageRenderRequest* newRequest; + /* add request to the queue */ + if (gPageRenderRequestsCount == MAX_PAGE_REQUESTS) { + /* queue is full -> remove the oldest items on the queue */ + memmove(&(gPageRenderRequests[0]), &(gPageRenderRequests[1]), sizeof(PageRenderRequest)*(MAX_PAGE_REQUESTS-1)); + newRequest = &(gPageRenderRequests[MAX_PAGE_REQUESTS-1]); + } else { + newRequest = &(gPageRenderRequests[gPageRenderRequestsCount]); + gPageRenderRequestsCount++; + } + assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); + newRequest->dm = dm; + newRequest->pageNo = pageNo; + newRequest->zoomLevel = zoomLevel; + newRequest->rotation = rotation; + newRequest->abort = FALSE; + + UnlockCache(); + /* tell rendering thread there's a new request to render */ + LONG prevCount; + ReleaseSemaphore(gPageRenderSem, 1, &prevCount); +Exit: + return; +LeaveCsAndExit: + UnlockCache(); + return; +} + +void RenderQueue_Pop(PageRenderRequest *req) +{ + LockCache(); + assert(gPageRenderRequestsCount > 0); + assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); + --gPageRenderRequestsCount; + *req = gPageRenderRequests[gPageRenderRequestsCount]; + assert(gPageRenderRequestsCount >= 0); + UnlockCache(); +} + +static HMENU FindMenuItem(WindowInfo *win, UINT id) +{ + HMENU menuMain = GetMenu(win->hwndFrame); + + /* TODO: to be fully valid, it would have to be recursive */ + for (int i = 0; i < GetMenuItemCount(menuMain); i++) { + UINT thisId = GetMenuItemID(menuMain, i); + HMENU subMenu = GetSubMenu(menuMain, i); + if (id == thisId) + return subMenu; + for (int j = 0; j < GetMenuItemCount(subMenu); j++) { + thisId = GetMenuItemID(menuMain, j); + if (id == thisId) + return GetSubMenu(subMenu, j); + } + } + return NULL; +} + +static HMENU GetFileMenu(HWND hwnd) +{ + return GetSubMenu(GetMenu(hwnd), 0); +} + +static void SwitchToDisplayMode(WindowInfo *win, DisplayMode displayMode) +{ + HMENU menuMain; + UINT id; + + menuMain = GetMenu(win->hwndFrame); + CheckMenuItem(menuMain, IDM_VIEW_SINGLE_PAGE, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VIEW_FACING, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS_FACING, MF_BYCOMMAND | MF_UNCHECKED); + + win->dm->changeDisplayMode(displayMode); + if (DM_SINGLE_PAGE == displayMode) { + id = IDM_VIEW_SINGLE_PAGE; + } else if (DM_FACING == displayMode) { + id = IDM_VIEW_FACING; + } else if (DM_CONTINUOUS == displayMode) { + id = IDM_VIEW_CONTINUOUS; + } else if (DM_CONTINUOUS_FACING == displayMode) { + id = IDM_VIEW_CONTINUOUS_FACING; + } else + assert(0); + + CheckMenuItem(menuMain, id, MF_BYCOMMAND | MF_CHECKED); +} + +static UINT AllocNewMenuId(void) +{ + static UINT firstId = 1000; + ++firstId; + return firstId; +} + +#define SEP_ITEM "-----" + +typedef struct MenuDef { + const char *m_title; + int m_id; +} MenuDef; + +MenuDef menuDefFile[] = { + { _TRN("&Open\tCtrl-O"), IDM_OPEN }, + { _TRN("&Close\tCtrl-W"), IDM_CLOSE }, + { _TRN("&Save as"), IDM_SAVEAS }, + { _TRN("&Print"), IDM_PRINT }, + { SEP_ITEM, 0 }, + { _TRN("Make SumatraPDF a default PDF reader"), IDM_MAKE_DEFAULT_READER }, + { SEP_ITEM , 0 }, + { _TRN("E&xit\tCtrl-Q"), IDM_EXIT } +}; + +MenuDef menuDefView[] = { + { _TRN("Single page"), IDM_VIEW_SINGLE_PAGE }, + { _TRN("Facing"), IDM_VIEW_FACING }, + { _TRN("Continuous"), IDM_VIEW_CONTINUOUS }, + { _TRN("Continuous facing"), IDM_VIEW_CONTINUOUS_FACING }, + { SEP_ITEM, 0 }, + { _TRN("Rotate left"), IDM_VIEW_ROTATE_LEFT }, + { _TRN("Rotate right"), IDM_VIEW_ROTATE_RIGHT }, + { SEP_ITEM, 0 }, + { _TRN("Show toolbar"), IDM_VIEW_SHOW_HIDE_TOOLBAR }, + { SEP_ITEM, 0 }, + { _TRN("Use MuPDF rendering engine"), IDM_VIEW_USE_FITZ }, +}; + +MenuDef menuDefGoTo[] = { + { _TRN("Next Page"), IDM_GOTO_NEXT_PAGE }, + { _TRN("Previous Page"), IDM_GOTO_PREV_PAGE }, + { _TRN("First Page\tHome"), IDM_GOTO_FIRST_PAGE }, + { _TRN("Last Page\tEnd"), IDM_GOTO_LAST_PAGE }, + { _TRN("Page...\tCtrl-G"), IDM_GOTO_PAGE }, +}; + +MenuDef menuDefZoom[] = { + { _TRN("Fit &Page\tCtrl-0"), IDM_ZOOM_FIT_PAGE }, + { _TRN("Act&ual Size\tCtrl-1"), IDM_ZOOM_ACTUAL_SIZE }, + { _TRN("Fit Widt&h\tCtrl-2"), IDM_ZOOM_FIT_WIDTH }, + { SEP_ITEM }, + { _TRN("6400%"), IDM_ZOOM_6400 }, + { _TRN("3200%"), IDM_ZOOM_3200 }, + { _TRN("1600%"), IDM_ZOOM_1600 }, + { _TRN("800%"), IDM_ZOOM_800 }, + { _TRN("400%"), IDM_ZOOM_400 }, + { _TRN("200%"), IDM_ZOOM_200 }, + { _TRN("150%"), IDM_ZOOM_150 }, + { _TRN("125%"), IDM_ZOOM_125 }, + { _TRN("100%"), IDM_ZOOM_100 }, + { _TRN("50%"), IDM_ZOOM_50 }, + { _TRN("25%"), IDM_ZOOM_25 }, + { _TRN("12.5%"), IDM_ZOOM_12_5 }, + { _TRN("8.33%"), IDM_ZOOM_8_33 }, +}; + +MenuDef menuDefLang[] = { + { _TRN("&English"), IDM_LANG_EN }, + { _TRN("&French"), IDM_LANG_FR }, + { _TRN("&German"), IDM_LANG_DE }, + { _TRN("&Polish"), IDM_LANG_PL }, +}; + +MenuDef menuDefHelp[] = { + { _TRN("&Visit website"), IDM_VISIT_WEBSITE }, + { _TRN("&About"), IDM_ABOUT } +}; + +static void AddFileMenuItem(HMENU menuFile, FileHistoryList *node) +{ + assert(node); + if (!node) return; + assert(menuFile); + if (!menuFile) return; + + UINT newId = node->menuId; + if (INVALID_MENU_ID == node->menuId) + newId = AllocNewMenuId(); + const char* txt = FilePath_GetBaseName(node->state.filePath); + AppendMenu(menuFile, MF_ENABLED | MF_STRING, newId, (TCHAR*)txt); /* @note: TCHAR* cast */ + node->menuId = newId; +} + +static HMENU BuildMenuFromMenuDef(MenuDef menuDefs[], int menuItems) +{ + HMENU m = CreateMenu(); + if (NULL == m) return NULL; + for (int i=0; i < menuItems; i++) { + MenuDef md = menuDefs[i]; + const char *title = md.m_title; + int id = md.m_id; + if (str_eq(title, SEP_ITEM)) + AppendMenu(m, MF_SEPARATOR, 0, NULL); + else { + const WCHAR* wtitle = Translatations_GetTranslationW(title); + if (wtitle) + AppendMenuW(m, MF_STRING, (UINT_PTR)id, wtitle); + } + } + return m; +} + +static HMENU g_currMenu = NULL; + +static void DestroyCurrentMenu() +{ + DestroyMenu(g_currMenu); + g_currMenu = NULL; +} + +static void AddRecentFilesToMenu(HMENU m) +{ + if (!gFileHistoryRoot) return; + + AppendMenu(m, MF_SEPARATOR, 0, NULL); + + int itemsAdded = 0; + FileHistoryList *curr = gFileHistoryRoot; + while (curr) { + assert(curr->state.filePath); + if (curr->state.filePath) { + AddFileMenuItem(m, curr); + assert(curr->menuId != INVALID_MENU_ID); + ++itemsAdded; + if (itemsAdded >= MAX_RECENT_FILES_IN_MENU) { + DBG_OUT(" not adding, reached max %d items\n", MAX_RECENT_FILES_IN_MENU); + return; + } + } + curr = curr->next; + } +} + +static HMENU ForceRebuildMenu() +{ + HMENU tmp; + DestroyCurrentMenu(); + g_currMenu = CreateMenu(); + tmp = BuildMenuFromMenuDef(menuDefFile, dimof(menuDefFile)); + AddRecentFilesToMenu(tmp); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&File")); + tmp = BuildMenuFromMenuDef(menuDefView, dimof(menuDefView)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&View")); + tmp = BuildMenuFromMenuDef(menuDefGoTo, dimof(menuDefGoTo)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Go To")); + tmp = BuildMenuFromMenuDef(menuDefZoom, dimof(menuDefZoom)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Zoom")); + tmp = BuildMenuFromMenuDef(menuDefLang, dimof(menuDefLang)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Language")); + tmp = BuildMenuFromMenuDef(menuDefHelp, dimof(menuDefHelp)); + AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Help")); + return g_currMenu; +} + +static HMENU GetProgramMenu() +{ + if (NULL == g_currMenu) + ForceRebuildMenu(); + assert(g_currMenu); + return g_currMenu; +} + +/* Return the full exe path of my own executable. + Caller needs to free() the result. */ +static char *ExePathGet(void) +{ + char *cmdline = GetCommandLineA(); + return str_parse_possibly_quoted(&cmdline); +} + +/* Set the client area size of the window 'hwnd' to 'dx'/'dy'. */ +static void WinResizeClientArea(HWND hwnd, int dx, int dy) +{ + RECT rc; + GetClientRect(hwnd, &rc); + if ((rect_dx(&rc) == dx) && (rect_dy(&rc) == dy)) + return; + RECT rw; + GetWindowRect(hwnd, &rw); + int win_dx = rect_dx(&rw) + (dx - rect_dx(&rc)); + int win_dy = rect_dy(&rw) + (dy - rect_dy(&rc)); + SetWindowPos(hwnd, NULL, 0, 0, win_dx, win_dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); +} + +static void SetCanvasSizeToDxDy(WindowInfo *win, int w, int h) +{ + RECT canvasRect; + GetWindowRect(win->hwndCanvas, &canvasRect); + RECT frameRect; + GetWindowRect(win->hwndFrame, &frameRect); + int dx = rect_dx(&frameRect) - rect_dx(&canvasRect); + assert(dx >= 0); + int dy = rect_dy(&frameRect) - rect_dy(&canvasRect); + assert(dy >= 0); + SetWindowPos(win->hwndFrame, NULL, 0, 0, w+dx, h+dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); + //SetWindowPos(win->hwndCanvas, NULL, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); +} + +static void CaptionPens_Create(void) +{ + LOGPEN pen; + + assert(!ghpenWhite); + pen.lopnStyle = PS_SOLID; + pen.lopnWidth.x = 1; + pen.lopnWidth.y = 1; + pen.lopnColor = COL_WHITE; + ghpenWhite = CreatePenIndirect(&pen); + pen.lopnColor = COL_CAPTION_BLUE; + ghpenBlue = CreatePenIndirect(&pen); +} + +static void CaptionPens_Destroy(void) +{ + if (ghpenWhite) { + DeleteObject(ghpenWhite); + ghpenWhite = NULL; + } + + if (ghpenBlue) { + DeleteObject(ghpenBlue); + ghpenBlue = NULL; + } +} + +static void AddFileToHistory(const char *filePath) +{ + FileHistoryList * node; + uint32_t oldMenuId = INVALID_MENU_ID; + + assert(filePath); + if (!filePath) return; + + /* if a history entry with the same name already exists, then delete it. + That way we don't have duplicates and the file moves to the front of the list */ + node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, filePath); + if (node) { + oldMenuId = node->menuId; + FileHistoryList_Node_RemoveAndFree(&gFileHistoryRoot, node); + } + node = FileHistoryList_Node_CreateFromFilePath(filePath); + if (!node) + return; + node->menuId = oldMenuId; + FileHistoryList_Node_InsertHead(&gFileHistoryRoot, node); +} + +extern "C" char *GetPasswordForFile(WindowInfo *win, const char *fileName); + +/* Get password for a given 'fileName', can be NULL if user cancelled the + dialog box. + Caller needs to free() the result. */ +char *GetPasswordForFile(WindowInfo *win, const char *fileName) +{ + fileName = FilePath_GetBaseName(fileName); + return Dialog_GetPassword(win, fileName); +} + +void *StandardSecurityHandler::getAuthData() +{ + WindowInfo * win; + const char * pwd; + StandardAuthData * authData; + + win = (WindowInfo*)doc->getGUIData(); + assert(win); + if (!win) + return NULL; + + pwd = GetPasswordForFile(win, doc->getFileName()->getCString()); + if (!pwd) + return NULL; + + authData = new StandardAuthData(new GooString(pwd), new GooString(pwd)); + free((void*)pwd); + return (void*)authData; +} + +/* Return true if this program has been started from "Program Files" directory + (which is an indicator that it has been installed */ +static bool runningFromProgramFiles(void) +{ + char programFilesDir[MAX_PATH]; + BOOL fOk = SHGetSpecialFolderPath(NULL, (TCHAR*)programFilesDir, CSIDL_PROGRAM_FILES, FALSE); /* @note: TCHAR* cast */ + char *exePath = ExePathGet(); + if (!exePath) return true; // again, assume it is + bool fromProgramFiles = false; + if (fOk) { + if (str_startswithi(exePath, programFilesDir)) + fromProgramFiles = true; + } else { + // SHGetSpecialFolderPath() might fail on win95/98 so need a different check + if (strstr(exePath, "Program Files")) + fromProgramFiles = true; + } + free(exePath); + return fromProgramFiles; +} + +static bool IsRunningInPortableMode(void) +{ + return !runningFromProgramFiles(); +} + +static void AppGetAppDir(DString* pDs) +{ + char dir[MAX_PATH]; + + SHGetSpecialFolderPath(NULL, (TCHAR*)dir, CSIDL_APPDATA, TRUE); /* @note: TCHAR* cast */ + DStringSprintf(pDs, "%s/%s", dir, APP_SUB_DIR); + _mkdir(pDs->pString); +} + +/* Generate the full path for a filename used by the app in the userdata path. */ +static void AppGenDataFilename(char* pFilename, DString* pDs) +{ + assert(0 == pDs->length); + assert(pFilename); + if (!pFilename) return; + assert(pDs); + if (!pDs) return; + + bool portable = IsRunningInPortableMode(); + if (portable) { + /* Use the same path as the binary */ + char *exePath = ExePathGet(); + if (!exePath) return; + char *dir = FilePath_GetDir(exePath); + if (dir) + DStringSprintf(pDs, "%s", dir); + free((void*)exePath); + free((void*)dir); + } else { + AppGetAppDir(pDs); + } + if (!str_endswithi(pDs->pString, DIR_SEP_STR) && !(DIR_SEP_CHAR == pFilename[0])) { + DStringAppend(pDs, DIR_SEP_STR, -1); + } + DStringAppend(pDs, pFilename, -1); +} + +static void Prefs_GetFileName(DString* pDs) +{ + assert(0 == pDs->length); + AppGenDataFilename((char*)PREFS_FILE_NAME, pDs); /* @note: char* cast */ +} + +/* Load preferences from the preferences file. */ +static void Prefs_Load(void) +{ + DString path; + static bool loaded = false; + char * prefsTxt = NULL; + + assert(!loaded); + loaded = true; + + DBG_OUT("Prefs_Load()\n"); + + DStringInit(&path); + Prefs_GetFileName(&path); + + size_t prefsFileLen; + prefsTxt = file_read_all(path.pString, &prefsFileLen); + if (str_empty(prefsTxt)) { + DBG_OUT(" no prefs file or is empty\n"); + return; + } + DBG_OUT("Prefs file %s:\n%s\n", path.pString, prefsTxt); + + bool fOk = Prefs_Deserialize(prefsTxt, &gFileHistoryRoot); + assert(fOk); + + DStringFree(&path); + free((void*)prefsTxt); +} + +static struct idToZoomMap { + UINT id; + double zoom; +} gZoomMenuItemsId[] = { + { IDM_ZOOM_6400, 6400.0 }, + { IDM_ZOOM_3200, 3200.0 }, + { IDM_ZOOM_1600, 1600.0 }, + { IDM_ZOOM_800, 800.0 }, + { IDM_ZOOM_400, 400.0 }, + { IDM_ZOOM_200, 200.0 }, + { IDM_ZOOM_150, 150.0 }, + { IDM_ZOOM_125, 125.0 }, + { IDM_ZOOM_100, 100.0 }, + { IDM_ZOOM_50, 50.0 }, + { IDM_ZOOM_25, 25.0 }, + { IDM_ZOOM_12_5, 12.5 }, + { IDM_ZOOM_8_33, 8.33 }, + { IDM_ZOOM_FIT_PAGE, ZOOM_FIT_PAGE }, + { IDM_ZOOM_FIT_WIDTH, ZOOM_FIT_WIDTH }, + { IDM_ZOOM_ACTUAL_SIZE, 100.0 } +}; + +static UINT MenuIdFromVirtualZoom(double virtualZoom) +{ + for (int i=0; i < dimof(gZoomMenuItemsId); i++) { + if (virtualZoom == gZoomMenuItemsId[i].zoom) + return gZoomMenuItemsId[i].id; + } + return IDM_ZOOM_ACTUAL_SIZE; +} + +static void ZoomMenuItemCheck(HMENU hmenu, UINT menuItemId) +{ + BOOL found = FALSE; + + for (int i=0; ihwndCanvas, &posX, &posY); + + ds->windowX = posX; + ds->windowY = posY; +} + +static void UpdateCurrentFileDisplayStateForWin(WindowInfo *win) +{ + DisplayState ds; + const char * fileName = NULL; + FileHistoryList*node = NULL; + + if (!win) + return; + if (WS_SHOWING_PDF != win->state) + return; + if (!win->dm) + return; + + fileName = win->dm->fileName(); + assert(fileName); + if (!fileName) + return; + + if (!gRunningDLL) + { + node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, fileName); + assert(node); + if (!node) + return; + } + + DisplayState_Init(&ds); + if (!displayStateFromDisplayModel(&ds, win->dm)) + return; + + UpdateDisplayStateWindowPos(win, &ds); + DisplayState_Free(&(node->state)); + node->state = ds; + node->state.visible = TRUE; +} + +static void UpdateCurrentFileDisplayState(void) +{ + WindowInfo * currWin; + FileHistoryList * currFile; + + currFile = gFileHistoryRoot; + while (currFile) { + currFile->state.visible = FALSE; + currFile = currFile->next; + } + + currWin = gWindowList; + while (currWin) { + UpdateCurrentFileDisplayStateForWin(currWin); + currWin = currWin->next; + } +} + +static void Prefs_Save(void) +{ + DString path; + DString prefsStr; + +#if 0 + if (gPrefsSaved) + return; + gPrefsSaved = TRUE; +#endif + + DStringInit(&prefsStr); + + /* mark currently shown files as visible */ + UpdateCurrentFileDisplayState(); + + bool fOk = Prefs_Serialize(&gFileHistoryRoot, &prefsStr); + if (!fOk) + goto Exit; + + DStringInit(&path); + Prefs_GetFileName(&path); + DBG_OUT("prefs file=%s\nprefs:\n%s\n", path.pString, prefsStr.pString); + /* TODO: consider 2-step process: + * write to a temp file + * rename temp file to final file */ + write_to_file((TCHAR*)path.pString, (void*)prefsStr.pString, prefsStr.length); /* @note: TCHAR* cast */ + +Exit: + DStringFree(&prefsStr); + DStringFree(&path); +} + +static bool WindowInfo_Dib_Init(WindowInfo *win) { + assert(NULL == win->dibInfo); + win->dibInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + 12); + if (!win->dibInfo) + return false; + win->dibInfo->bmiHeader.biSize = sizeof(win->dibInfo->bmiHeader); + win->dibInfo->bmiHeader.biPlanes = 1; + win->dibInfo->bmiHeader.biBitCount = 24; + win->dibInfo->bmiHeader.biCompression = BI_RGB; + win->dibInfo->bmiHeader.biXPelsPerMeter = 2834; + win->dibInfo->bmiHeader.biYPelsPerMeter = 2834; + win->dibInfo->bmiHeader.biClrUsed = 0; + win->dibInfo->bmiHeader.biClrImportant = 0; + return true; +} + +static void WindowInfo_Dib_Deinit(WindowInfo *win) { + free((void*)win->dibInfo); + win->dibInfo = NULL; +} + +static void WindowInfo_DoubleBuffer_Delete(WindowInfo *win) { + if (win->bmpDoubleBuffer) { + DeleteObject(win->bmpDoubleBuffer); + win->bmpDoubleBuffer = NULL; + } + + if (win->hdcDoubleBuffer) { + DeleteDC(win->hdcDoubleBuffer); + win->hdcDoubleBuffer = NULL; + } + win->hdcToDraw = NULL; +} + +static bool WindowInfo_DoubleBuffer_New(WindowInfo *win) +{ + WindowInfo_DoubleBuffer_Delete(win); + + win->hdc = GetDC(win->hwndCanvas); + win->hdcToDraw = win->hdc; + win->GetCanvasSize(); + if (!gUseDoubleBuffer || (0 == win->winDx()) || (0 == win->winDy())) + return true; + + win->hdcDoubleBuffer = CreateCompatibleDC(win->hdc); + if (!win->hdcDoubleBuffer) + return false; + + win->bmpDoubleBuffer = CreateCompatibleBitmap(win->hdc, win->winDx(), win->winDy()); + if (!win->bmpDoubleBuffer) { + WindowInfo_DoubleBuffer_Delete(win); + return false; + } + /* TODO: do I need this ? */ + SelectObject(win->hdcDoubleBuffer, win->bmpDoubleBuffer); + /* fill out everything with background color */ + RECT r = {0}; + r.bottom = win->winDy(); + r.right = win->winDx(); + FillRect(win->hdcDoubleBuffer, &r, gBrushBg); + win->hdcToDraw = win->hdcDoubleBuffer; + return TRUE; +} + +static void WindowInfo_DoubleBuffer_Show(WindowInfo *win, HDC hdc) +{ + if (win->hdc != win->hdcToDraw) { + assert(win->hdcToDraw == win->hdcDoubleBuffer); + BitBlt(hdc, 0, 0, win->winDx(), win->winDy(), win->hdcDoubleBuffer, 0, 0, SRCCOPY); + } +} + +static void WindowInfo_Delete(WindowInfo *win) +{ + if (win->dm) { + RenderQueue_RemoveForDisplayModel(win->dm); + cancelRenderingForDisplayModel(win->dm); + } + delete win->dm; + win->dm = NULL; + WindowInfo_Dib_Deinit(win); + WindowInfo_DoubleBuffer_Delete(win); + delete win; +} + +static WindowInfo* WindowInfo_FindByHwnd(HWND hwnd) +{ + WindowInfo *win = gWindowList; + while (win) { + if (hwnd == win->hwndFrame) + return win; + if (hwnd == win->hwndCanvas) + return win; + if (hwnd == win->hwndReBar) + return win; + win = win->next; + } + return NULL; +} + +static WindowInfo *WindowInfo_New(HWND hwndFrame) { + WindowInfo * win = WindowInfo_FindByHwnd(hwndFrame); + assert(!win); + + win = new WindowInfo();; + if (!win) + return NULL; + + if (!WindowInfo_Dib_Init(win)) + goto Error; + + win->state = WS_ABOUT; + win->hwndFrame = hwndFrame; + win->mouseAction = MA_IDLE; + return win; +Error: + WindowInfo_Delete(win); + return NULL; +} + +static void WindowInfoList_Add(WindowInfo *win) { + win->next = gWindowList; + gWindowList = win; +} + +static bool WindowInfoList_ExistsWithError(void) { + WindowInfo *cur = gWindowList; + while (cur) { + if (WS_ERROR_LOADING_PDF == cur->state) + return true; + cur = cur->next; + } + return false; +} + +static void WindowInfoList_Remove(WindowInfo *to_remove) { + assert(to_remove); + if (!to_remove) + return; + if (gWindowList == to_remove) { + gWindowList = to_remove->next; + return; + } + WindowInfo* curr = gWindowList; + while (curr) { + if (to_remove == curr->next) { + curr->next = to_remove->next; + return; + } + curr = curr->next; + } +} + +static void WindowInfoList_DeleteAll(void) { + WindowInfo* curr = gWindowList; + while (curr) { + WindowInfo* next = curr->next; + WindowInfo_Delete(curr); + curr = next; + } + gWindowList = NULL; +} + +static int WindowInfoList_Len(void) { + int len = 0; + WindowInfo* curr = gWindowList; + while (curr) { + ++len; + curr = curr->next; + } + return len; +} + +static void WindowInfo_RedrawAll(WindowInfo *win, bool update=false) { + InvalidateRect(win->hwndCanvas, NULL, false); + if (update) + UpdateWindow(win->hwndCanvas); +} + +static bool FileCloseMenuEnabled(void) { + WindowInfo* win = gWindowList; + while (win) { + if (win->state == WS_SHOWING_PDF) + return true; + win = win->next; + } + return false; +} + +static void ToolbarUpdateStateForWindow(WindowInfo *win) { + LPARAM enable = (LPARAM)MAKELONG(1,0); + LPARAM disable = (LPARAM)MAKELONG(0,0); + + for (int i=0; i < TOOLBAR_BUTTONS_COUNT; i++) { + int cmdId = gToolbarButtons[i].cmdId; + if (IDB_SEPARATOR == cmdId) + continue; + LPARAM buttonState = enable; + if (IDM_OPEN != cmdId) { + if (WS_SHOWING_PDF != win->state) + buttonState = disable; + } + SendMessage(win->hwndToolbar, TB_ENABLEBUTTON, cmdId, buttonState); + } +} + +static void MenuUpdateShowToolbarStateForWindow(WindowInfo *win) { + HMENU hmenu = GetMenu(win->hwndFrame); + if (gShowToolbar) + CheckMenuItem(hmenu, IDM_VIEW_SHOW_HIDE_TOOLBAR, MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem(hmenu, IDM_VIEW_SHOW_HIDE_TOOLBAR, MF_BYCOMMAND | MF_UNCHECKED); +} + +static void MenuUpdateUseFitzStateForWindow(WindowInfo *win) { + HMENU hmenu = GetMenu(win->hwndFrame); + if (gUseFitz) + CheckMenuItem(hmenu, IDM_VIEW_USE_FITZ, MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem(hmenu, IDM_VIEW_USE_FITZ, MF_BYCOMMAND | MF_UNCHECKED); +} + +// show which language is being used via check in Language/* menu +static void MenuUpdateLanguage(WindowInfo *win) { + HMENU hmenu = GetMenu(win->hwndFrame); + for (int i = 0; i < LANGS_COUNT; i++) { + const char *langName = g_langs[i]._langName; + int langMenuId = g_langs[i]._langId; + if (str_eq(CurrLangNameGet(), langName)) + CheckMenuItem(hmenu, langMenuId, MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem(hmenu, langMenuId, MF_BYCOMMAND | MF_UNCHECKED); + } +} + +static void MenuUpdateStateForWindow(WindowInfo *win) { + static UINT menusToDisableIfNoPdf[] = { + IDM_VIEW_SINGLE_PAGE, IDM_VIEW_FACING, IDM_VIEW_CONTINUOUS, IDM_VIEW_CONTINUOUS_FACING, + IDM_VIEW_ROTATE_LEFT, IDM_VIEW_ROTATE_RIGHT, IDM_GOTO_NEXT_PAGE, IDM_GOTO_PREV_PAGE, + IDM_GOTO_FIRST_PAGE, IDM_GOTO_LAST_PAGE, IDM_GOTO_PAGE, IDM_ZOOM_FIT_PAGE, + IDM_ZOOM_ACTUAL_SIZE, IDM_ZOOM_FIT_WIDTH, IDM_ZOOM_6400, IDM_ZOOM_3200, + IDM_ZOOM_1600, IDM_ZOOM_800, IDM_ZOOM_400, IDM_ZOOM_200, IDM_ZOOM_150, + IDM_ZOOM_125, IDM_ZOOM_100, IDM_ZOOM_50, IDM_ZOOM_25, IDM_ZOOM_12_5, + IDM_ZOOM_8_33, IDM_SAVEAS }; + + bool fileCloseEnabled = FileCloseMenuEnabled(); + HMENU hmenu = GetMenu(win->hwndFrame); + if (fileCloseEnabled) + EnableMenuItem(hmenu, IDM_CLOSE, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(hmenu, IDM_CLOSE, MF_BYCOMMAND | MF_GRAYED); + + bool filePrintEnabled = false; + if (win->dm && win->dm->pdfEngine() && win->dm->pdfEngine()->printingAllowed()) + filePrintEnabled = true; + if (filePrintEnabled) + EnableMenuItem(hmenu, IDM_PRINT, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(hmenu, IDM_PRINT, MF_BYCOMMAND | MF_GRAYED); + + MenuUpdateShowToolbarStateForWindow(win); + MenuUpdateUseFitzStateForWindow(win); + MenuUpdateLanguage(win); + + for (int i = 0; i < dimof(menusToDisableIfNoPdf); i++) { + UINT menuId = menusToDisableIfNoPdf[i]; + if (WS_SHOWING_PDF == win->state) + EnableMenuItem(hmenu, menuId, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(hmenu, menuId, MF_BYCOMMAND | MF_GRAYED); + } + /* Hide scrollbars if not showing a PDF */ + /* TODO: doesn't really fit the name of the function */ + if (WS_SHOWING_PDF == win->state) + ShowScrollBar(win->hwndCanvas, SB_BOTH, TRUE); + else { + ShowScrollBar(win->hwndCanvas, SB_BOTH, FALSE); + win_set_text(win->hwndFrame, APP_NAME); + } +} + +/* Disable/enable menu items and toolbar buttons depending on wheter a + given window shows a PDF file or not. */ +static void MenuToolbarUpdateStateForAllWindows(void) { + WindowInfo* win = gWindowList; + while (win) { + MenuUpdateStateForWindow(win); + ToolbarUpdateStateForWindow(win); + win = win->next; + } +} + +static WindowInfo* WindowInfo_CreateEmpty(void) { + HWND hwndFrame, hwndCanvas; + WindowInfo* win; + +#if FANCY_UI + hwndFrame = CreateWindowEx( +// WS_EX_TOOLWINDOW, + 0, +// WS_OVERLAPPEDWINDOW, +// WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, + //WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_HSCROLL | WS_VSCROLL, + FRAME_CLASS_NAME, windowTitle, + WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + NULL, NULL, + ghinst, NULL); +#else + hwndFrame = CreateWindow( + FRAME_CLASS_NAME, windowTitle, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + NULL, NULL, + ghinst, NULL); + HMENU m = GetProgramMenu(); + SetMenu(hwndFrame, m); +#endif + + if (!hwndFrame) + return NULL; + + win = WindowInfo_New(hwndFrame); + hwndCanvas = CreateWindow( + CANVAS_CLASS_NAME, NULL, + WS_CHILD | WS_HSCROLL | WS_VSCROLL, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + hwndFrame, NULL, + ghinst, NULL); + if (!hwndCanvas) + return NULL; + win->hwndCanvas = hwndCanvas; + CreateToolbar(win, ghinst); + return win; +} + +BOOL GetDesktopWindowClientRect(RECT *r) +{ + HWND hwnd = GetDesktopWindow(); + if (!hwnd) return FALSE; + return GetClientRect(hwnd, r); +} + +void GetCanvasDxDyDiff(WindowInfo *win, int *dxOut, int *dyOut) +{ + RECT canvasRect; + GetWindowRect(win->hwndCanvas, &canvasRect); + RECT totalRect; + GetWindowRect(win->hwndFrame, &totalRect); + *dxOut = rect_dx(&totalRect) - rect_dx(&canvasRect); + // TODO: should figure out why it fires in DLL + assert(gRunningDLL || *dxOut >= 0); + *dyOut = rect_dy(&totalRect) - rect_dy(&canvasRect); + // TODO: should figure out why it fires in DLL + assert(gRunningDLL || *dyOut >= 0); +} + +SizeI GetMaxCanvasSize(WindowInfo *win) +{ + AppBarData abd; + RECT r; + GetDesktopWindowClientRect(&r); + // substract the area of the window not used for canvas + int dx, dy; + GetCanvasDxDyDiff(win, &dx, &dy); // TODO: lame name + int maxCanvasDx = rect_dx(&r) - dx; + int maxCanvasDy = rect_dy(&r) - dy; + if (abd.isHorizontal()) { + assert(maxCanvasDx >= abd.dx()); + maxCanvasDx -= abd.dx(); + } else { + assert(abd.isVertical()); + assert(maxCanvasDy >= abd.dy()); + maxCanvasDy -= abd.dy(); + } + return SizeI(maxCanvasDx, maxCanvasDy); +} + + +static void RecalcSelectionPosition (WindowInfo *win) { + SelectionOnPage * selOnPage = win->selectionOnPage; + RectD selD; + PdfPageInfo* pageInfo; + + while (selOnPage != NULL) { + pageInfo = win->dm->getPageInfo(selOnPage->pageNo); + /* if page is not visible, we hide seletion by simply moving it off + * the canvas */ + if (!pageInfo->visible) { + selOnPage->selectionCanvas.x = -100; + selOnPage->selectionCanvas.y = -100; + selOnPage->selectionCanvas.dx = 0; + selOnPage->selectionCanvas.dy = 0; + } else {//page is visible + RectD_Copy (&selD, &selOnPage->selectionPage); + win->dm->rectCvtUserToScreen (selOnPage->pageNo, &selD); + RectI_FromRectD (&selOnPage->selectionCanvas, &selD); + } + selOnPage = selOnPage->next; + } +} + +static WindowInfo* LoadPdf(const char *fileName, bool ignoreHistorySizePos = true, bool ignoreHistory = false) +{ + assert(fileName); + if (!fileName) return NULL; + + FileHistoryList * fileFromHistory = NULL; + if (!ignoreHistory) + fileFromHistory = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, fileName); + + WindowInfo * win; + bool reuseExistingWindow = false; + if ((1 == WindowInfoList_Len()) && (WS_SHOWING_PDF != gWindowList->state)) { + win = gWindowList; + reuseExistingWindow = true; + } else { + win = WindowInfo_CreateEmpty(); + if (!win) + return NULL; + } + + win->GetCanvasSize(); + SizeI maxCanvasSize = GetMaxCanvasSize(win); + SizeD totalDrawAreaSize(win->winSize()); + if (fileFromHistory && !ignoreHistorySizePos) { + WinResizeClientArea(win->hwndCanvas, fileFromHistory->state.windowDx, fileFromHistory->state.windowDy); + totalDrawAreaSize = SizeD(fileFromHistory->state.windowDx, fileFromHistory->state.windowDy); + Win32_Win_SetPos(win->hwndFrame, fileFromHistory->state.windowX, fileFromHistory->state.windowY); + } +#if 0 // not ready yet + else { + IntelligentWindowResize(win); + } +#endif + + /* TODO: make sure it doesn't have a stupid position like + outside of the screen etc. */ +#if 0 + if (totalDrawAreaSize.dxI() > maxCanvasSize.dx) + totalDrawAreaSize.setDx(maxCanvasSize.dx); + if (totalDrawAreaSize.dyI() > maxCanvasSize.dy) + totalDrawAreaSize.setDy(maxCanvasSize.dy); + + WinResizeClientArea(win->hwndCanvas, totalDrawAreaSize.dxI(), totalDrawAreaSize.dyI()); +#endif + + /* In theory I should get scrollbars sizes using Win32_GetScrollbarSize(&scrollbarYDx, &scrollbarXDy); + but scrollbars are not part of the client area on windows so it's better + not to have them taken into account by DisplayModelSplash code. + TODO: I think it's broken anyway and DisplayModelSplash needs to know if + scrollbars are part of client area in order to accomodate windows + UI properly */ + DisplayMode displayMode = DEFAULT_DISPLAY_MODE; + int offsetX = 0; + int offsetY = 0; + int startPage = 1; + int scrollbarYDx = 0; + int scrollbarXDy = 0; + if (fileFromHistory) { + startPage = fileFromHistory->state.pageNo; + displayMode = fileFromHistory->state.displayMode; + offsetX = fileFromHistory->state.scrollX; + offsetY = fileFromHistory->state.scrollY; + } + + if (gUseFitz) { + win->dm = DisplayModelFitz_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, win); + } else { + win->dm = DisplayModelSplash_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, win); + } + + double zoomVirtual = DEFAULT_ZOOM; + int rotation = DEFAULT_ROTATION; + if (!win->dm) { + if (!reuseExistingWindow && WindowInfoList_ExistsWithError()) { + /* don't create more than one window with errors */ + WindowInfo_Delete(win); + return NULL; + } + win->state = WS_ERROR_LOADING_PDF; + DBG_OUT("failed to load file %s\n", fileName); + //goto Exit; /* @note: because of "crosses initialization of [...]" */ + if (!reuseExistingWindow) + WindowInfoList_Add(win); + MenuToolbarUpdateStateForAllWindows(); + assert(win); + DragAcceptFiles(win->hwndFrame, TRUE); + DragAcceptFiles(win->hwndCanvas, TRUE); + ShowWindow(win->hwndFrame, SW_SHOW); + ShowWindow(win->hwndCanvas, SW_SHOW); + UpdateWindow(win->hwndFrame); + UpdateWindow(win->hwndCanvas); + return win; + } + + win->dm->setAppData((void*)win); + + if (!fileFromHistory) { + AddFileToHistory(fileName); + RebuildProgramMenus(); + } + + /* TODO: if fileFromHistory, set the state based on gFileHistoryList node for + this entry */ + win->state = WS_SHOWING_PDF; + if (fileFromHistory) { + zoomVirtual = fileFromHistory->state.zoomVirtual; + rotation = fileFromHistory->state.rotation; + } + + UINT menuId = MenuIdFromVirtualZoom(zoomVirtual); + ZoomMenuItemCheck(GetMenu(win->hwndFrame), menuId); + + win->dm->relayout(zoomVirtual, rotation); + if (!win->dm->validPageNo(startPage)) + startPage = 1; + /* TODO: need to calculate proper offsetY, currently giving large offsetY + remembered for continuous mode breaks things (makes all pages invisible) */ + offsetY = 0; + /* TODO: make sure offsetX isn't bogus */ + win->dm->goToPage(startPage, offsetY, offsetX); + + /* only resize the window if it's a newly opened window */ + if (!reuseExistingWindow && !fileFromHistory) + WindowInfo_ResizeToPage(win, startPage); + + if (reuseExistingWindow) + WindowInfo_RedrawAll(win); + +Exit: + if (!reuseExistingWindow) + WindowInfoList_Add(win); + MenuToolbarUpdateStateForAllWindows(); + assert(win); + DragAcceptFiles(win->hwndFrame, TRUE); + DragAcceptFiles(win->hwndCanvas, TRUE); + ShowWindow(win->hwndFrame, SW_SHOW); + ShowWindow(win->hwndCanvas, SW_SHOW); + UpdateWindow(win->hwndFrame); + UpdateWindow(win->hwndCanvas); + return win; +} + +static HFONT Win32_Font_GetSimple(HDC hdc, char *fontName, int fontSize) +{ + HFONT font_dc; + HFONT font; + LOGFONT lf = {0}; + + font_dc = (HFONT)GetStockObject(SYSTEM_FONT); + if (!GetObject(font_dc, sizeof(LOGFONT), &lf)) + return NULL; + + lf.lfHeight = (LONG)-fontSize; + lf.lfWidth = 0; + //lf.lfHeight = -MulDiv(fontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfOutPrecision = OUT_TT_PRECIS; + lf.lfQuality = DEFAULT_QUALITY; + //lf.lfQuality = CLEARTYPE_QUALITY; + lf.lfPitchAndFamily = DEFAULT_PITCH; + strcpy_s((char*)lf.lfFaceName, LF_FACESIZE, fontName); /* @note: char* cast */ + lf.lfWeight = FW_DONTCARE; + font = CreateFontIndirect(&lf); + return font; +} + +static void Win32_Font_Delete(HFONT font) +{ + DeleteObject(font); +} + +void DisplayModel::pageChanged(void) +{ + WindowInfo *win = (WindowInfo*)appData(); + assert(win); + if (!win) return; + +#if 0 + if (!win->dmSplash->pdfDoc) + return; +#endif + + int currPageNo = currentPageNo(); + int pageCount = win->dm->pageCount(); + const char *baseName = FilePath_GetBaseName(win->dm->fileName()); + if (pageCount <= 0) + win_set_text(win->hwndFrame, (TCHAR*)baseName); /* @note: TCHAR* cast */ + else { + char titleBuf[256]; + HRESULT hr = StringCchPrintfA(titleBuf, dimof(titleBuf), "%s page %d of %d", baseName, currPageNo, pageCount); + win_set_text(win->hwndFrame, (TCHAR*)titleBuf); /* @note: TCHAR* cast */ + /* @note: FIXME: hr is unused ATM */ + } +} + +/* Call from non-UI thread to cause repainting of the display */ +static void triggerRepaintDisplayPotentiallyDelayed(WindowInfo *win, bool delayed) +{ + assert(win); + if (!win) return; + if (delayed) + PostMessage(win->hwndCanvas, WM_APP_REPAINT_DELAYED, 0, 0); + else + PostMessage(win->hwndCanvas, WM_APP_REPAINT_NOW, 0, 0); +} + +static void triggerRepaintDisplayNow(WindowInfo* win) +{ + triggerRepaintDisplayPotentiallyDelayed(win, false); +} + +void DisplayModel::repaintDisplay(bool delayed) +{ + WindowInfo* win = (WindowInfo*)appData(); + triggerRepaintDisplayPotentiallyDelayed(win, delayed); +} + +void DisplayModel::setScrollbarsState(void) +{ + WindowInfo *win = (WindowInfo*)this->appData(); + assert(win); + if (!win) return; + + SCROLLINFO si = {0}; + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + + int canvasDx = _canvasSize.dxI(); + int canvasDy = _canvasSize.dyI(); + int drawAreaDx = drawAreaSize.dxI(); + int drawAreaDy = drawAreaSize.dyI(); + + if (drawAreaDx >= canvasDx) { + si.nPos = 0; + si.nMin = 0; + si.nMax = 99; + si.nPage = 100; + } else { + si.nPos = (int)areaOffset.x; + si.nMin = 0; + si.nMax = canvasDx-1; + si.nPage = drawAreaDx; + } + SetScrollInfo(win->hwndCanvas, SB_HORZ, &si, TRUE); + + if (drawAreaDy >= canvasDy) { + si.nPos = 0; + si.nMin = 0; + si.nMax = 99; + si.nPage = 100; + } else { + si.nPos = (int)areaOffset.y; + si.nMin = 0; + si.nMax = canvasDy-1; + si.nPage = drawAreaDy; + } + SetScrollInfo(win->hwndCanvas, SB_VERT, &si, TRUE); +} + +static void WindowInfo_ResizeToWindow(WindowInfo *win) +{ + assert(win); + if (!win) return; + assert(win->dm); + if (!win->dm) return; + + win->dm->changeTotalDrawAreaSize(win->winSize()); +} + +void WindowInfo_ResizeToPage(WindowInfo *win, int pageNo) +{ + bool fullScreen = false; + + assert(win); + if (!win) return; + assert(win->dm); + if (!win->dm) + return; + + /* TODO: should take current monitor into account? */ + HDC hdc = GetDC(win->hwndCanvas); + int displayDx = GetDeviceCaps(hdc, HORZRES); + int displayDy = GetDeviceCaps(hdc, VERTRES); + + int dx, dy; + if (fullScreen) { + /* TODO: fullscreen not yet supported */ + assert(0); + dx = displayDx; + dy = displayDy; + } else { + assert(win->dm->validPageNo(pageNo)); + if (!win->dm->validPageNo(pageNo)) + return; + PdfPageInfo *pageInfo = win->dm->getPageInfo(pageNo); + assert(pageInfo); + if (!pageInfo) + return; + DisplaySettings *displaySettings = globalDisplaySettings(); + dx = pageInfo->currDx + displaySettings->paddingPageBorderLeft + displaySettings->paddingPageBorderRight; + dy = pageInfo->currDy + displaySettings->paddingPageBorderTop + displaySettings->paddingPageBorderBottom; + if (dx > displayDx - 10) + dx = displayDx - 10; + if (dy > displayDy - 10) + dy = displayDy - 10; + } + + WinResizeClientArea(win->hwndCanvas, dx, dy); +} + +static void WindowInfo_ToggleZoom(WindowInfo *win) +{ + DisplayModel * dm; + + assert(win); + if (!win) return; + + dm = win->dm; + assert(dm); + if (!dm) return; + + if (ZOOM_FIT_PAGE == dm->zoomVirtual()) + dm->setZoomVirtual(ZOOM_FIT_WIDTH); + else if (ZOOM_FIT_WIDTH == dm->zoomVirtual()) + dm->setZoomVirtual(ZOOM_FIT_PAGE); +} + +static BOOL WindowInfo_PdfLoaded(WindowInfo *win) +{ + assert(win); + if (!win) return FALSE; + if (!win->dm) return FALSE; +#if 0 + assert(win->dmSplash->pdfDoc); + assert(win->dmSplash->pdfDoc->isOk()); +#endif + return TRUE; +} + +int WindowsVerMajor() +{ + DWORD version = GetVersion(); + return (int)(version & 0xFF); +} + +int WindowsVerMinor() +{ + DWORD version = GetVersion(); + return (int)((version & 0xFF00) >> 8); +} + +bool WindowsVer2000OrGreater() +{ + if (WindowsVerMajor() >= 5) + return true; + return false; +} + +static bool AlreadyRegisteredForPdfExtentions(void) +{ + bool registered = false; + HKEY key = NULL; + char nameBuf[sizeof(APP_NAME)+8]; + DWORD cbNameBuf = sizeof(nameBuf); + DWORD keyType; + + /* HKEY_CLASSES_ROOT\.pdf */ + if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT(".pdf"), 0, KEY_QUERY_VALUE, &key)) /* @note: TEXT() cast */ + return false; + + if (ERROR_SUCCESS != RegQueryValueEx(key, NULL, NULL, &keyType, (LPBYTE)nameBuf, &cbNameBuf)) + goto Exit; + + if (REG_SZ != keyType) + goto Exit; + + if (cbNameBuf != sizeof(APP_NAME)) + goto Exit; + + if (0 == memcmp(APP_NAME, nameBuf, sizeof(APP_NAME))) + registered = true; + +Exit: + RegCloseKey(key); + return registered; +} + +static void AssociateExeWithPdfExtensions() +{ + char tmp[256]; + HKEY key = NULL, kicon = NULL, kshell = NULL, kopen = NULL, kcmd = NULL; + DWORD disp; + HRESULT hr; + + char * exePath = ExePathGet(); + assert(exePath); + if (!exePath) return; + + HKEY hkeyToUse = HKEY_CURRENT_USER; + if (WindowsVer2000OrGreater()) + hkeyToUse = HKEY_LOCAL_MACHINE; + + /* key\.pdf */ /* @note: TEXT() && TCHAR* casts */ + if (RegCreateKeyEx(hkeyToUse, + TEXT(".pdf"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &key, &disp)) + goto Exit; + + if (RegSetValueEx(key, TEXT(""), 0, REG_SZ, (const BYTE*)APP_NAME, sizeof(APP_NAME))) + goto Exit; + + RegCloseKey(key); + key = NULL; + + /* key\APP_NAME */ + if (RegCreateKeyEx(hkeyToUse, + APP_NAME, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &key, &disp)) + goto Exit; + + if (RegSetValueEx(key, TEXT(""), 0, REG_SZ, (const BYTE*)PDF_DOC_NAME, sizeof(PDF_DOC_NAME))) + goto Exit; + + /* key\APP_NAME\DefaultIcon */ + if (RegCreateKeyEx(key, + TEXT("DefaultIcon"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kicon, &disp)) + goto Exit; + + /* Note: I don't understand why icon index has to be 0, but it just has to */ + hr = StringCchPrintfA(tmp, dimof(tmp), "%s,0", exePath); + if (RegSetValueEx(kicon, TEXT(""), 0, REG_SZ, (const BYTE*)tmp, strlen(tmp)+1)) + goto Exit; + + RegCloseKey(kicon); + kicon = NULL; + + /* HKEY_CLASSES_ROOT\APP_NAME\Shell\Open\Command */ + if (RegCreateKeyEx(key, + TEXT("shell"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kshell, &disp)) + goto Exit; + + if (RegCreateKeyEx(kshell, + TEXT("open"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kopen, &disp)) + goto Exit; + + if (RegCreateKeyEx(kopen, + TEXT("command"), 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &kcmd, &disp)) + goto Exit; + + hr = StringCchPrintfA(tmp, dimof(tmp), "\"%s\" \"%%1\"", exePath); + if (RegSetValueEx(kcmd, TEXT(""), 0, REG_SZ, (const BYTE*)tmp, strlen(tmp)+1)) + goto Exit; + + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, 0, 0); + +Exit: + if (kcmd) + RegCloseKey(kcmd); + if (kopen) + RegCloseKey(kopen); + if (kshell) + RegCloseKey(kshell); + if (key) + RegCloseKey(key); + free(exePath); +} + +static void RegisterForPdfExtentions(HWND hwnd) +{ + if (AlreadyRegisteredForPdfExtentions()) + return; + + if (IsRunningInPortableMode()) + return; + + /* Ask user for permission, unless he previously said he doesn't want to + see this dialog */ + if (!gPdfAssociateDontAskAgain) { + int result = Dialog_PdfAssociate(hwnd, &gPdfAssociateDontAskAgain); + if (DIALOG_NO_PRESSED == result) { + gPdfAssociateShouldAssociate = FALSE; + } else { + assert(DIALOG_OK_PRESSED == result); + gPdfAssociateShouldAssociate = TRUE; + } + } + + if (gPdfAssociateShouldAssociate) + AssociateExeWithPdfExtensions(); +} + +static void OnDropFiles(WindowInfo *win, HDROP hDrop) +{ + int i; + char filename[MAX_PATH]; + const int files_count = DragQueryFile(hDrop, DRAGQUERY_NUMFILES, 0, 0); + + for (i = 0; i < files_count; i++) + { + DragQueryFile(hDrop, i, (TCHAR*)filename, MAX_PATH); /* @note: TCHAR* cast */ + LoadPdf(filename); + } + DragFinish(hDrop); + + if (files_count > 0) + WindowInfo_RedrawAll(win); +} + +static void DrawLineSimple(HDC hdc, int sx, int sy, int ex, int ey) +{ + MoveToEx(hdc, sx, sy, NULL); + LineTo(hdc, ex, ey); +} + +#if 0 +/* Draw caption area for a given window 'win' in the classic AmigaOS style */ +static void AmigaCaptionDraw(WindowInfo *win) +{ + HGDIOBJ prevPen; + HDC hdc = win->hdc; + + assert(VS_AMIGA == gVisualStyle); + + prevPen = SelectObject(hdc, ghpenWhite); + + /* white */ + DrawLineSimple(hdc, 0, 0, win->winDx, 0); + DrawLineSimple(hdc, 0, 1, win->winDx, 1); + + /* white */ + DrawLineSimple(hdc, 0, 4, win->winDx, 4); + DrawLineSimple(hdc, 0, 5, win->winDx, 5); + + /* white */ + DrawLineSimple(hdc, 0, 8, win->winDx, 8); + DrawLineSimple(hdc, 0, 9, win->winDx, 9); + + /* white */ + DrawLineSimple(hdc, 0, 12, win->winDx, 12); + DrawLineSimple(hdc, 0, 13, win->winDx, 13); + + /* white */ + DrawLineSimple(hdc, 0, 16, win->winDx, 16); + DrawLineSimple(hdc, 0, 17, win->winDx, 17); + DrawLineSimple(hdc, 0, 18, win->winDx, 18); + + SelectObject(hdc, ghpenBlue); + + /* blue */ + DrawLineSimple(hdc, 0, 2, win->winDx, 2); + DrawLineSimple(hdc, 0, 3, win->winDx, 3); + + /* blue */ + DrawLineSimple(hdc, 0, 6, win->winDx, 6); + DrawLineSimple(hdc, 0, 7, win->winDx, 7); + + /* blue */ + DrawLineSimple(hdc, 0, 10, win->winDx, 10); + DrawLineSimple(hdc, 0, 11, win->winDx, 11); + + /* blue */ + DrawLineSimple(hdc, 0, 14, win->winDx, 14); + DrawLineSimple(hdc, 0, 15, win->winDx, 15); + + SelectObject(hdc, prevPen); +} +#endif + +static void WinResizeIfNeeded(WindowInfo *win, bool resizeWindow=true) +{ + RECT rc; + GetClientRect(win->hwndCanvas, &rc); + int win_dx = rect_dx(&rc); + int win_dy = rect_dy(&rc); + + if (win->hdcToDraw && + (win_dx == win->winDx()) && + (win_dy == win->winDy())) + { + return; + } + + WindowInfo_DoubleBuffer_New(win); + if (resizeWindow) + WindowInfo_ResizeToWindow(win); +} + +static void PostBenchNextAction(HWND hwnd) +{ + PostMessage(hwnd, MSG_BENCH_NEXT_ACTION, 0, 0); +} + +static void OnBenchNextAction(WindowInfo *win) +{ + if (!win->dm) + return; + + if (win->dm->goToNextPage(0)) + PostBenchNextAction(win->hwndFrame); +} + +static void DrawCenteredText(HDC hdc, RECT *r, char *txt) +{ + SetBkMode(hdc, TRANSPARENT); + DrawText(hdc, (TCHAR*)txt, strlen(txt), r, DT_CENTER | DT_VCENTER | DT_SINGLELINE); /* @note: TCHAR* cast */ +} + +static void SeeLastError(void) { + char *msgBuf = NULL; + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &msgBuf, 0, NULL); + if (!msgBuf) return; + printf("SeeLastError(): %s\n", msgBuf); + OutputDebugStringA(msgBuf); + LocalFree(msgBuf); +} + +static void PaintTransparentRectangle(WindowInfo *win, HDC hdc, RectI *rect) { + HBITMAP hbitmap; // bitmap handle + BITMAPINFO bmi; // bitmap header + VOID *pvBits; // pointer to DIB section + BLENDFUNCTION bf; // structure for alpha blending + HDC rectDC = CreateCompatibleDC(hdc); + const DWORD selectionColorYellow = 0xfff5fc0c; + const DWORD selectionColorBlack = 0xff000000; + const int margin = 1; + + ZeroMemory(&bmi, sizeof(BITMAPINFO)); + + bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = rect->dx; + bmi.bmiHeader.biHeight = rect->dy; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = rect->dx * rect->dy * 4; + + hbitmap = CreateDIBSection (rectDC, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0); + SelectObject(rectDC, hbitmap); + + for (int y = 0; y < rect->dy; y++) { + for (int x = 0; x < rect->dx; x++) { + if (x < margin || x > rect->dx - margin - 1 + || y < margin || y > rect->dy - margin - 1) + ((UINT32 *)pvBits)[x + y * rect->dx] = selectionColorBlack; + else + ((UINT32 *)pvBits)[x + y * rect->dx] = selectionColorYellow; + } + } + bf.BlendOp = AC_SRC_OVER; + bf.BlendFlags = 0; + bf.SourceConstantAlpha = 0x5f; + bf.AlphaFormat = AC_SRC_ALPHA; + + /*if (!AlphaBlend(hdc, rect->x, rect->y, rect->dx, rect->dy, + rectDC, 0, 0, rect->dx, rect->dy, bf)) + DBG_OUT("AlphaBlending error\n");*/ + /* @note: error: 'AlphaBlend' was not declared in this scope; even with WINVER: 0x0500 set in rbuild file, weird; @FIXME */ + DeleteObject (hbitmap); + DeleteDC (rectDC); +} + +static void PaintSelection (WindowInfo *win, HDC hdc) { + if (win->mouseAction == MA_SELECTING) { + // during selecting + RectI selRect; + + selRect.x = min (win->selectionRect.x, + win->selectionRect.x + win->selectionRect.dx); + selRect.y = min (win->selectionRect.y, + win->selectionRect.y + win->selectionRect.dy); + selRect.dx = abs (win->selectionRect.dx); + selRect.dy = abs (win->selectionRect.dy); + + if (selRect.dx != 0 && selRect.dy != 0) + PaintTransparentRectangle (win, hdc, &selRect); + } else { + // after selection is done + SelectionOnPage *selOnPage = win->selectionOnPage; + // TODO: Move recalcing to better place + RecalcSelectionPosition(win); + while (selOnPage != NULL) { + if (selOnPage->selectionCanvas.dx != 0 && selOnPage->selectionCanvas.dy != 0) + PaintTransparentRectangle(win, hdc, &selOnPage->selectionCanvas); + selOnPage = selOnPage->next; + } + } +} + +static void WindowInfo_Paint(WindowInfo *win, HDC hdc, PAINTSTRUCT *ps) +{ + RECT bounds; + RenderedBitmap * renderedBmp = NULL; + + assert(win); + if (!win) return; + DisplayModel* dm = win->dm; + assert(dm); + if (!dm) return; +#if 0 // TODO: write the equivalent dm->isOk() ? + assert(dm->pdfDoc); + if (!dm->pdfDoc) return; +#endif + + assert(win->hdcToDraw); + hdc = win->hdcToDraw; + + FillRect(hdc, &(ps->rcPaint), gBrushBg); + + DBG_OUT("WindowInfo_Paint() "); + for (int pageNo = 1; pageNo <= dm->pageCount(); ++pageNo) { + PdfPageInfo *pageInfo = dm->getPageInfo(pageNo); + if (!pageInfo->visible) + continue; + assert(pageInfo->shown); + if (!pageInfo->shown) + continue; + + //BitmapCacheEntry *entry = BitmapCache_Find(dm, pageNo, dm->zoomReal(), dm->rotation()); + BitmapCacheEntry *entry = BitmapCache_Find(dm, pageNo); + if (entry) { + if ((dm->rotation() != entry->rotation) || (dm->zoomReal() != entry->zoomLevel)) + entry = NULL; + else + renderedBmp = entry->bitmap; + } + + if (!renderedBmp) + DBG_OUT(" missing bitmap on visible page %d\n", pageNo); + + int xSrc = (int)pageInfo->bitmapX; + int ySrc = (int)pageInfo->bitmapY; + int bmpDx = (int)pageInfo->bitmapDx; + int bmpDy = (int)pageInfo->bitmapDy; + int xDest = (int)pageInfo->screenX; + int yDest = (int)pageInfo->screenY; + + if (!entry) { + /* TODO: assert is queued for rendering ? */ + HFONT fontRightTxt = Win32_Font_GetSimple(hdc, "Tahoma", 14); + HFONT origFont = (HFONT)SelectObject(hdc, fontRightTxt); /* Just to remember the orig font */ + bounds.left = xDest; + bounds.top = yDest; + bounds.right = xDest + bmpDx; + bounds.bottom = yDest + bmpDy; + FillRect(hdc, &bounds, gBrushWhite); + DrawCenteredText(hdc, &bounds, "Please wait - rendering..."); + DBG_OUT("drawing empty %d ", pageNo); + if (origFont) + SelectObject(hdc, origFont); + Win32_Font_Delete(fontRightTxt); + continue; + } + + if (BITMAP_CANNOT_RENDER == renderedBmp) { + bounds.left = xDest; + bounds.top = yDest; + bounds.right = xDest + bmpDx; + bounds.bottom = yDest + bmpDy; + FillRect(hdc, &bounds, gBrushWhite); + DrawCenteredText(hdc, &bounds, "Couldn't render the page"); + continue; + } + + DBG_OUT("page %d ", pageNo); + + int renderedBmpDx = renderedBmp->dx(); + int renderedBmpDy = renderedBmp->dy(); + int currPageDx = pageInfo->currDx; + int currPageDy = pageInfo->currDy; + HBITMAP hbmp = renderedBmp->createDIBitmap(hdc); + if (!hbmp) + continue; + + HDC bmpDC = CreateCompatibleDC(hdc); + if (bmpDC) { + SelectObject(bmpDC, hbmp); +#if 0 + if ((currPageDx != renderedBmpDx) || (currPageDy != renderedBmpDy)) + StretchBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, renderedBmpDx, renderedBmpDy, SRCCOPY); + else +#endif + BitBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, SRCCOPY); + DeleteDC(bmpDC); + } + DeleteObject(hbmp); + } + + if (win->showSelection) + PaintSelection(win, hdc); + + DBG_OUT("\n"); + if (!gDebugShowLinks) + return; + + RectI drawAreaRect; + /* debug code to visualize links */ + drawAreaRect.x = (int)dm->areaOffset.x; + drawAreaRect.y = (int)dm->areaOffset.y; + drawAreaRect.dx = dm->drawAreaSize.dxI(); + drawAreaRect.dy = dm->drawAreaSize.dyI(); + + for (int linkNo = 0; linkNo < dm->linkCount(); ++linkNo) { + PdfLink *pdfLink = dm->link(linkNo); + + RectI rectLink, intersect; + rectLink.x = pdfLink->rectCanvas.x; + rectLink.y = pdfLink->rectCanvas.y; + rectLink.dx = pdfLink->rectCanvas.dx; + rectLink.dy = pdfLink->rectCanvas.dy; + + if (RectI_Intersect(&rectLink, &drawAreaRect, &intersect)) { + RECT rectScreen; + rectScreen.left = (LONG) ((double)intersect.x - dm->areaOffset.x); + rectScreen.top = (LONG) ((double)intersect.y - dm->areaOffset.y); + rectScreen.right = rectScreen.left + rectLink.dx; + rectScreen.bottom = rectScreen.top + rectLink.dy; + FillRect(hdc, &rectScreen, gBrushLinkDebug); + DBG_OUT(" link on screen rotate=%d, (x=%d, y=%d, dx=%d, dy=%d)\n", + dm->rotation() + dm->pagesInfo[pdfLink->pageNo-1].rotation, + rectScreen.left, rectScreen.top, rect_dx(&rectScreen), rect_dy(&rectScreen)); + } + } +} + +/* TODO: change the name to DrawAbout. + Draws the about screen a remember some state for hyperlinking. + It transcribes the design I did in graphics software - hopeless + to understand without seeing the design. */ +#define ABOUT_RECT_PADDING 8 +#define ABOUT_RECT_BORDER_DX_DY 4 +#define ABOUT_LINE_OUTER_SIZE 2 +#define ABOUT_LINE_RECT_SIZE 5 +#define ABOUT_LINE_SEP_SIZE 1 +#define ABOUT_LEFT_RIGHT_SPACE_DX 8 +#define ABOUT_MARGIN_DX 10 +#define ABOUT_BOX_MARGIN_DY 6 + +#define ABOUT_BORDER_COL COL_BLACK + +#define SUMATRA_TXT "Sumatra PDF" +#define SUMATRA_TXT_FONT "Arial Black" +#define SUMATRA_TXT_FONT_SIZE 24 +#define BETA_TXT "Beta v0.7" +#define BETA_TXT_FONT "Arial Black" +#define BETA_TXT_FONT_SIZE 12 +#define LEFT_TXT_FONT "Arial" +#define LEFT_TXT_FONT_SIZE 12 +#define RIGHT_TXT_FONT "Arial Black" +#define RIGHT_TXT_FONT_SIZE 12 + +#define ABOUT_BG_COLOR RGB(255,242,0) +#define ABOUT_RECT_BG_COLOR RGB(247,148,29) + +#define ABOUT_TXT_DY 6 + +typedef struct AboutLayoutInfoEl { + /* static data, must be provided */ + const char * leftTxt; + const char * rightTxt; + const char * url; + + /* data calculated by the layout */ + int leftTxtPosX; + int leftTxtPosY; + int leftTxtDx; + int leftTxtDy; + + int rightTxtPosX; + int rightTxtPosY; + int rightTxtDx; + int rightTxtDy; +} AboutLayoutInfoEl; + +AboutLayoutInfoEl gAboutLayoutInfo[] = { + { "design", "Krzysztof Kowalczyk", "http://blog.kowalczyk.info", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "programming", "Krzysztof Kowalczyk", "http://blog.kowalczyk.info", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "pdf rendering 1", "poppler + xpdf", "http://poppler.freedesktop.org/", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "pdf rendering 2", "MuPDF", "http://ccxvii.net/apparition/", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "license", "GPL v2", "http://www.gnu.org/copyleft/gpl.html", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "website", "http://blog.kowalczyk.info/software/sumatra", "http://blog.kowalczyk.info/software/sumatrapdf", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "forums", "http://blog.kowalczyk.info/forum_sumatra", "http://blog.kowalczyk.info/forum_sumatra", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "program icon", "Goce Mitevski", "http://monsteer.deviantart.com", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { "toolbar icons", "Mark James", "http://www.famfamfam.com/lab/icons/silk/", + 0, 0, 0, 0, 0, 0, 0, 0 }, + + { NULL, NULL, NULL, + 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +static const char *AboutGetLink(WindowInfo *win, int x, int y) +{ + for (int i = 0; gAboutLayoutInfo[i].leftTxt; i++) { + if ((x < gAboutLayoutInfo[i].rightTxtPosX) || + (x > gAboutLayoutInfo[i].rightTxtPosX + gAboutLayoutInfo[i].rightTxtDx)) + continue; + if ((y < gAboutLayoutInfo[i].rightTxtPosY) || + (y > gAboutLayoutInfo[i].rightTxtPosY + gAboutLayoutInfo[i].rightTxtDy)) + continue; + return gAboutLayoutInfo[i].url; + } + return NULL; +} + +static void DrawAbout(HWND hwnd, HDC hdc, PAINTSTRUCT *ps) +{ + RECT rcTmp; + SIZE txtSize; + int totalDx, totalDy; + int leftDy, rightDy; + int leftLargestDx, rightLargestDx; + int sumatraPdfTxtDx, sumatraPdfTxtDy; + int betaTxtDx, betaTxtDy; + int linePosX, linePosY, lineDy; + int currY; + int fontDyDiff; + int offX, offY; + int x, y; + int boxDy; + + DString str; + DStringInit(&str); + + HBRUSH brushBg = CreateSolidBrush(ABOUT_BG_COLOR); + HBRUSH brushRectBg = CreateSolidBrush(ABOUT_RECT_BG_COLOR); + + HPEN penRectBorder = CreatePen(PS_SOLID, ABOUT_RECT_BORDER_DX_DY, COL_BLACK); + HPEN penBorder = CreatePen(PS_SOLID, ABOUT_LINE_OUTER_SIZE, COL_BLACK); + HPEN penDivideLine = CreatePen(PS_SOLID, ABOUT_LINE_SEP_SIZE, COL_BLACK); + + RECT rc; + GetClientRect(hwnd, &rc); + + int areaDx = rect_dx(&rc); + int areaDy = rect_dy(&rc); + + HFONT fontSumatraTxt = Win32_Font_GetSimple(hdc, SUMATRA_TXT_FONT, SUMATRA_TXT_FONT_SIZE); + HFONT fontBetaTxt = Win32_Font_GetSimple(hdc, BETA_TXT_FONT, BETA_TXT_FONT_SIZE); + HFONT fontLeftTxt = Win32_Font_GetSimple(hdc, LEFT_TXT_FONT, LEFT_TXT_FONT_SIZE); + HFONT fontRightTxt = Win32_Font_GetSimple(hdc, RIGHT_TXT_FONT, RIGHT_TXT_FONT_SIZE); + + HFONT origFont = (HFONT)SelectObject(hdc, fontSumatraTxt); /* Just to remember the orig font */ + + SetBkMode(hdc, TRANSPARENT); + + /* Layout stuff */ + const char *txt = SUMATRA_TXT; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @note: TCHAR* cast */ + sumatraPdfTxtDx = txtSize.cx; + sumatraPdfTxtDy = txtSize.cy; + + boxDy = sumatraPdfTxtDy + ABOUT_BOX_MARGIN_DY * 2; + txt = BETA_TXT; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @note: TCHAR* cast */ + betaTxtDx = txtSize.cx; + betaTxtDy = txtSize.cy; + + (HFONT)SelectObject(hdc, fontLeftTxt); + leftLargestDx = 0; + leftDy = 0; + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].leftTxt; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @note: TCHAR* cast */ + gAboutLayoutInfo[i].leftTxtDx = (int)txtSize.cx; + gAboutLayoutInfo[i].leftTxtDy = (int)txtSize.cy; + if (0 == i) + leftDy = gAboutLayoutInfo[i].leftTxtDy; + else + assert(leftDy == gAboutLayoutInfo[i].leftTxtDy); + if (leftLargestDx < gAboutLayoutInfo[i].leftTxtDx) + leftLargestDx = gAboutLayoutInfo[i].leftTxtDx; + } + + (HFONT)SelectObject(hdc, fontRightTxt); + rightLargestDx = 0; + rightDy = 0; + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].rightTxt; + GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @note: TCHAR* cast */ + gAboutLayoutInfo[i].rightTxtDx = (int)txtSize.cx; + gAboutLayoutInfo[i].rightTxtDy = (int)txtSize.cy; + if (0 == i) + rightDy = gAboutLayoutInfo[i].rightTxtDy; + else + assert(rightDy == gAboutLayoutInfo[i].rightTxtDy); + if (rightLargestDx < gAboutLayoutInfo[i].rightTxtDx) + rightLargestDx = gAboutLayoutInfo[i].rightTxtDx; + } + + fontDyDiff = (rightDy - leftDy) / 2; + + /* in the x order */ + totalDx = ABOUT_LINE_OUTER_SIZE + ABOUT_MARGIN_DX + leftLargestDx; + totalDx += ABOUT_LEFT_RIGHT_SPACE_DX + ABOUT_LINE_SEP_SIZE + ABOUT_LEFT_RIGHT_SPACE_DX; + totalDx += rightLargestDx + ABOUT_MARGIN_DX + ABOUT_LINE_OUTER_SIZE; + + totalDy = 0; + totalDy += boxDy; + totalDy += ABOUT_LINE_OUTER_SIZE; + totalDy += (dimof(gAboutLayoutInfo)-1) * (rightDy + ABOUT_TXT_DY); + totalDy += ABOUT_LINE_OUTER_SIZE + 4; + + offX = (areaDx - totalDx) / 2; + offY = (areaDy - totalDy) / 2; + + rcTmp.left = offX; + rcTmp.top = offY; + rcTmp.right = totalDx + offX; + rcTmp.bottom = totalDy + offY; + + FillRect(hdc, &rc, brushBg); + + SelectObject(hdc, brushBg); + SelectObject(hdc, penBorder); + + Rectangle(hdc, offX, offY + ABOUT_LINE_OUTER_SIZE, offX + totalDx, offY + boxDy + ABOUT_LINE_OUTER_SIZE); + + SetTextColor(hdc, ABOUT_BORDER_COL); + (HFONT)SelectObject(hdc, fontSumatraTxt); + x = offX + (totalDx - sumatraPdfTxtDx) / 2; + y = offY + (boxDy - sumatraPdfTxtDy) / 2; + txt = SUMATRA_TXT; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @note: TCHAR* cast */ + + //SetTextColor(hdc, ABOUT_RECT_BG_COLOR); + (HFONT)SelectObject(hdc, fontBetaTxt); + //SelectObject(hdc, brushRectBg); + x = offX + (totalDx - sumatraPdfTxtDx) / 2 + sumatraPdfTxtDx + 6; + y = offY + (boxDy - sumatraPdfTxtDy) / 2; + txt = BETA_TXT; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @note: TCHAR* cast */ + SetTextColor(hdc, ABOUT_BORDER_COL); + + offY += boxDy; + Rectangle(hdc, offX, offY, offX + totalDx, offY + totalDy - boxDy); + + linePosX = ABOUT_LINE_OUTER_SIZE + ABOUT_MARGIN_DX + leftLargestDx + ABOUT_LEFT_RIGHT_SPACE_DX; + linePosY = 4; + lineDy = (dimof(gAboutLayoutInfo)-1) * (rightDy + ABOUT_TXT_DY); + + /* render text on the left*/ + currY = linePosY; + (HFONT)SelectObject(hdc, fontLeftTxt); + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].leftTxt; + x = linePosX + offX - ABOUT_LEFT_RIGHT_SPACE_DX - gAboutLayoutInfo[i].leftTxtDx; + y = currY + fontDyDiff + offY; + gAboutLayoutInfo[i].leftTxtPosX = x; + gAboutLayoutInfo[i].leftTxtPosY = y; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @note: TCHAR* cast */ + currY += rightDy + ABOUT_TXT_DY; + } + + /* render text on the rigth */ + currY = linePosY; + (HFONT)SelectObject(hdc, fontRightTxt); + for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { + txt = gAboutLayoutInfo[i].rightTxt; + x = linePosX + offX + ABOUT_LEFT_RIGHT_SPACE_DX; + y = currY + offY; + gAboutLayoutInfo[i].rightTxtPosX = x; + gAboutLayoutInfo[i].rightTxtPosY = y; + TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @note: TCHAR* cast */ + currY += rightDy + ABOUT_TXT_DY; + } + + SelectObject(hdc, penDivideLine); + MoveToEx(hdc, linePosX + offX, linePosY + offY, NULL); + LineTo(hdc, linePosX + offX, linePosY + lineDy + offY); + + if (origFont) + SelectObject(hdc, origFont); + + Win32_Font_Delete(fontSumatraTxt); + Win32_Font_Delete(fontBetaTxt); + Win32_Font_Delete(fontLeftTxt); + Win32_Font_Delete(fontRightTxt); + + DeleteObject(brushBg); + DeleteObject(brushRectBg); + DeleteObject(penBorder); + DeleteObject(penDivideLine); + DeleteObject(penRectBorder); +} + +static void WinMoveDocBy(WindowInfo *win, int dx, int dy) +{ + assert(win); + if (!win) return; + assert (WS_SHOWING_PDF == win->state); + if (WS_SHOWING_PDF != win->state) return; + assert(win->dm); + if (!win->dm) return; + assert(!win->linkOnLastButtonDown); + if (win->linkOnLastButtonDown) return; + if (0 != dx) + win->dm->scrollXBy(dx); + if (0 != dy) + win->dm->scrollYBy(dy, FALSE); +} + +static void CopySelectionTextToClipboard(WindowInfo *win) +{ + SelectionOnPage * selOnPage; + + assert(win); + if (!win) return; + + if (!win->selectionOnPage) return; + + HGLOBAL handle; + unsigned short *ucsbuf; + int ucsbuflen = 4096; + + if (!OpenClipboard(NULL)) return; + + EmptyClipboard(); + + handle = GlobalAlloc(GMEM_MOVEABLE, ucsbuflen * sizeof(unsigned short)); + if (!handle) { + CloseClipboard(); + return; + } + ucsbuf = (unsigned short *) GlobalLock(handle); + + selOnPage = win->selectionOnPage; + + int copied = 0; + while (selOnPage != NULL) { + int charCopied = win->dm->getTextInRegion(selOnPage->pageNo, + &selOnPage->selectionPage, ucsbuf + copied, ucsbuflen - copied - 1); + copied += charCopied; + if (ucsbuflen - copied == 1) + break; + selOnPage = selOnPage->next; + } + ucsbuf[copied] = 0; + + GlobalUnlock(handle); + + SetClipboardData(CF_UNICODETEXT, handle); + CloseClipboard(); +} + +static void DeleteOldSelectionInfo (WindowInfo *win) { + SelectionOnPage *selOnPage = win->selectionOnPage; + while (selOnPage != NULL) { + SelectionOnPage *tmp = selOnPage->next; + free(selOnPage); + selOnPage = tmp; + } + win->selectionOnPage = NULL; +} + +static void ConvertSelectionRectToSelectionOnPage (WindowInfo *win) { + RectI pageOnScreen, intersect; + + for (int pageNo = win->dm->pageCount(); pageNo >= 1; --pageNo) { + PdfPageInfo *pageInfo = win->dm->getPageInfo(pageNo); + if (!pageInfo->visible) + continue; + assert(pageInfo->shown); + if (!pageInfo->shown) + continue; + + pageOnScreen.x = pageInfo->screenX; + pageOnScreen.y = pageInfo->screenY; + pageOnScreen.dx = pageInfo->bitmapDx; + pageOnScreen.dy = pageInfo->bitmapDy; + + if (!RectI_Intersect(&win->selectionRect, &pageOnScreen, &intersect)) + continue; + + /* selection intersects with a page on the screen */ + SelectionOnPage *selOnPage = (SelectionOnPage*)malloc(sizeof(SelectionOnPage)); + RectD_FromRectI(&selOnPage->selectionPage, &intersect); + + win->dm->rectCvtScreenToUser (&selOnPage->pageNo, &selOnPage->selectionPage); + + assert (pageNo == selOnPage->pageNo); + + selOnPage->next = win->selectionOnPage; + win->selectionOnPage = selOnPage; + } +} + +static void OnMouseLeftButtonDown(WindowInfo *win, int x, int y) +{ + assert(win); + if (!win) return; + if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_IDLE) { + assert(win->dm); + if (!win->dm) return; + win->linkOnLastButtonDown = win->dm->linkAtPosition(x, y); + /* dragging mode only starts when we're not on a link */ + if (!win->linkOnLastButtonDown) { + SetCapture(win->hwndCanvas); + win->mouseAction = MA_DRAGGING; + win->dragPrevPosX = x; + win->dragPrevPosY = y; + SetCursor(gCursorDrag); + DBG_OUT(" dragging start, x=%d, y=%d\n", x, y); + } + } else if (WS_ABOUT == win->state) { + win->url = AboutGetLink(win, x, y); + } +} + +static void OnMouseLeftButtonUp(WindowInfo *win, int x, int y) +{ + PdfLink * link; + const char * url; + int dragDx, dragDy; + + assert(win); + if (!win) return; + + if (WS_ABOUT == win->state) { + url = AboutGetLink(win, x, y); + if (url == win->url) + LaunchBrowser(url); + win->url = NULL; + return; + } + + if (WS_SHOWING_PDF != win->state) + return; + + assert(win->dm); + if (!win->dm) return; + + if (win->mouseAction == MA_DRAGGING && (GetCapture() == win->hwndCanvas)) { + dragDx = 0; dragDy = 0; + dragDx = x - win->dragPrevPosX; + dragDy = y - win->dragPrevPosY; + DBG_OUT(" dragging ends, x=%d, y=%d, dx=%d, dy=%d\n", x, y, dragDx, dragDy); + assert(!win->linkOnLastButtonDown); + WinMoveDocBy(win, dragDx, -dragDy*2); + win->dragPrevPosX = x; + win->dragPrevPosY = y; + win->mouseAction = MA_IDLE; + SetCursor(gCursorArrow); + ReleaseCapture(); + return; + } + + if (!win->linkOnLastButtonDown) + return; + + link = win->dm->linkAtPosition(x, y); + if (link && (link == win->linkOnLastButtonDown)) + win->dm->handleLink(link); + win->linkOnLastButtonDown = NULL; +} + +static void OnMouseMove(WindowInfo *win, int x, int y, WPARAM flags) +{ + PdfLink * link; + const char * url; + int dragDx, dragDy; + + assert(win); + if (!win) return; + + if (WS_SHOWING_PDF == win->state) { + assert(win->dm); + if (!win->dm) return; + if (win->mouseAction == MA_SELECTING) { + SetCursor(gCursorArrow); + win->selectionRect.dx = x - win->selectionRect.x; + win->selectionRect.dy = y - win->selectionRect.y; + triggerRepaintDisplayNow(win); + } else { + if (win->mouseAction == MA_DRAGGING) { + dragDx = 0; dragDy = 0; + dragDx = -(x - win->dragPrevPosX); + dragDy = -(y - win->dragPrevPosY); + DBG_OUT(" drag move, x=%d, y=%d, dx=%d, dy=%d\n", x, y, dragDx, dragDy); + WinMoveDocBy(win, dragDx, dragDy*2); + win->dragPrevPosX = x; + win->dragPrevPosY = y; + return; + } + link = win->dm->linkAtPosition(x, y); + if (link) + SetCursor(gCursorHand); + else + SetCursor(gCursorArrow); + } + } else if (WS_ABOUT == win->state) { + url = AboutGetLink(win, x, y); + if (url) { + SetCursor(gCursorHand); + } else { + SetCursor(gCursorArrow); + } + } else { + // TODO: be more efficient, this only needs to be set once (I think) + SetCursor(gCursorArrow); + } +} + +static void OnMouseRightButtonDown(WindowInfo *win, int x, int y) +{ + //DBG_OUT("Right button clicked on %d %d\n", x, y); + assert (win); + if (!win) return; + + if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_IDLE) { + win->documentBlocked = true; + DeleteOldSelectionInfo (win); + + win->selectionRect.x = x; + win->selectionRect.y = y; + win->selectionRect.dx = 0; + win->selectionRect.dy = 0; + win->showSelection = true; + win->mouseAction = MA_SELECTING; + + triggerRepaintDisplayNow(win); + } +} + +static void OnMouseRightButtonUp(WindowInfo *win, int x, int y) +{ + assert (win); + if (!win) return; + + if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_SELECTING) { + assert (win->dm); + if (!win->dm) return; + win->documentBlocked = false; + + win->selectionRect.dx = abs (x - win->selectionRect.x); + win->selectionRect.dy = abs (y - win->selectionRect.y); + win->selectionRect.x = min (win->selectionRect.x, x); + win->selectionRect.y = min (win->selectionRect.y, y); + + win->mouseAction = MA_IDLE; + if (win->selectionRect.dx == 0 || win->selectionRect.dy == 0) { + win->showSelection = false; + } else { + ConvertSelectionRectToSelectionOnPage (win); + CopySelectionTextToClipboard (win); + } + triggerRepaintDisplayNow(win); + } +} + +#define ABOUT_ANIM_TIMER_ID 15 + +static void AnimState_AnimStop(AnimState *state) +{ + KillTimer(state->hwnd, ABOUT_ANIM_TIMER_ID); +} + +static void AnimState_NextFrame(AnimState *state) +{ + state->frame += 1; + InvalidateRect(state->hwnd, NULL, FALSE); + UpdateWindow(state->hwnd); +} + +static void AnimState_AnimStart(AnimState *state, HWND hwnd, UINT freqInMs) +{ + assert(IsWindow(hwnd)); + AnimState_AnimStop(state); + state->frame = 0; + state->hwnd = hwnd; + SetTimer(state->hwnd, ABOUT_ANIM_TIMER_ID, freqInMs, NULL); + AnimState_NextFrame(state); +} + +#define ANIM_FONT_NAME "Georgia" +#define ANIM_FONT_SIZE_START 20 +#define SCROLL_SPEED 3 + +static void DrawAnim2(WindowInfo *win, HDC hdc, PAINTSTRUCT *ps) +{ + AnimState * state = &(win->animState); + DString txt; + RECT rc; + HFONT fontArial24 = NULL; + HFONT origFont = NULL; + int curFontSize; + static int curTxtPosX = -1; + static int curTxtPosY = -1; + static int curDir = SCROLL_SPEED; + + GetClientRect(win->hwndCanvas, &rc); + + DStringInit(&txt); + + if (-1 == curTxtPosX) + curTxtPosX = 40; + if (-1 == curTxtPosY) + curTxtPosY = 25; + + int areaDx = rect_dx(&rc); + int areaDy = rect_dy(&rc); + +#if 0 + if (state->frame % 24 <= 12) { + curFontSize = ANIM_FONT_SIZE_START + (state->frame % 24); + } else { + curFontSize = ANIM_FONT_SIZE_START + 12 - (24 - (state->frame % 24)); + } +#else + curFontSize = ANIM_FONT_SIZE_START; +#endif + + curTxtPosY += curDir; + if (curTxtPosY < 20) + curDir = SCROLL_SPEED; + else if (curTxtPosY > areaDy - 40) + curDir = -SCROLL_SPEED; + + fontArial24 = Win32_Font_GetSimple(hdc, ANIM_FONT_NAME, curFontSize); + assert(fontArial24); + + origFont = (HFONT)SelectObject(hdc, fontArial24); + + SetBkMode(hdc, TRANSPARENT); + FillRect(hdc, &rc, gBrushBg); + //DStringSprintf(&txt, "Welcome to animation %d", state->frame); + DStringSprintf(&txt, "Welcome to animation"); + //DrawText (hdc, txt.pString, -1, &rc, DT_SINGLELINE); + TextOut(hdc, curTxtPosX, curTxtPosY, (TCHAR*)txt.pString, txt.length); /* @note: TCHAR* cast */ + WindowInfo_DoubleBuffer_Show(win, hdc); + if (state->frame > 99) + state->frame = 0; + + if (origFont) + SelectObject(hdc, origFont); + Win32_Font_Delete(fontArial24); +} + +static void WindowInfo_DoubleBuffer_Resize_IfNeeded(WindowInfo *win) +{ + WinResizeIfNeeded(win, false); +} + +static void OnPaintAbout(HWND hwnd) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + SetBkMode(hdc, TRANSPARENT); + DrawAbout(hwnd, hdc, &ps); + EndPaint(hwnd, &ps); +} + +static void OnPaint(WindowInfo *win) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(win->hwndCanvas, &ps); + + SetBkMode(hdc, TRANSPARENT); + RECT rc; + GetClientRect(win->hwndCanvas, &rc); + + if (WS_ABOUT == win->state) { + WindowInfo_DoubleBuffer_Resize_IfNeeded(win); + DrawAbout(win->hwndCanvas, win->hdcToDraw, &ps); + WindowInfo_DoubleBuffer_Show(win, hdc); + } else if (WS_ERROR_LOADING_PDF == win->state) { + HFONT fontRightTxt = Win32_Font_GetSimple(hdc, "Tahoma", 14); + HFONT origFont = (HFONT)SelectObject(hdc, fontRightTxt); /* Just to remember the orig font */ + FillRect(hdc, &ps.rcPaint, gBrushBg); + /* @note: translation function and it's related macros need some care */ + //DrawText(hdc, _TR("Error loading PDF file."), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; + DrawText(hdc, TEXT("Error loading PDF file."), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; + if (origFont) + SelectObject(hdc, origFont); + Win32_Font_Delete(fontRightTxt); + } else if (WS_SHOWING_PDF == win->state) { + //TODO: it might cause infinite loop due to showing/hiding scrollbars + WinResizeIfNeeded(win); + WindowInfo_Paint(win, hdc, &ps); +#if 0 + if (VS_AMIGA == gVisualStyle) + AmigaCaptionDraw(win); +#endif + WindowInfo_DoubleBuffer_Show(win, hdc); + } else + assert(0); + + EndPaint(win->hwndCanvas, &ps); +} + +static void OnMenuExit(void) +{ + Prefs_Save(); + PostQuitMessage(0); +} + +/* Close the document associated with window 'hwnd'. + Closes the window unless this is the last window in which + case it switches to empty window and disables the "File\Close" + menu item. */ +static void CloseWindow(WindowInfo *win, bool quitIfLast) +{ + assert(win); + if (!win) return; + + bool lastWindow = false; + if (gRunningDLL) { + lastWindow = true; + } else { + if (1 == WindowInfoList_Len()) + lastWindow = true; + + if (lastWindow) + Prefs_Save(); + else + UpdateCurrentFileDisplayStateForWin(win); + } + + win->state = WS_ABOUT; + + if (lastWindow && !quitIfLast) { + /* last window - don't delete it */ + delete win->dm; + win->dm = NULL; + WindowInfo_RedrawAll(win); + } else { + HWND hwndToDestroy = win->hwndFrame; + WindowInfoList_Remove(win); + WindowInfo_Delete(win); + DragAcceptFiles(hwndToDestroy, FALSE); + DestroyWindow(hwndToDestroy); + } + + if (lastWindow && quitIfLast) { + assert(0 == WindowInfoList_Len()); + PostQuitMessage(0); + } else { + if (!gRunningDLL) + MenuToolbarUpdateStateForAllWindows(); + } +} + +/* Zoom document in window 'hwnd' to zoom level 'zoom'. + 'zoom' is given as a floating-point number, 1.0 is 100%, 2.0 is 200% etc. +*/ +static void OnMenuZoom(WindowInfo *win, UINT menuId) +{ + if (!win->dm) + return; + + double zoom = ZoomMenuItemToZoom(menuId); + win->dm->zoomTo(zoom); + ZoomMenuItemCheck(GetMenu(win->hwndFrame), menuId); +} + +static bool CheckPrinterStretchDibSupport(HWND hwndForMsgBox, HDC hdc) +{ + // most printers can support stretchdibits, + // whereas a lot of printers do not support bitblt + // quit if printer doesn't support StretchDIBits + int rasterCaps = GetDeviceCaps(hdc, RASTERCAPS); + int supportsStretchDib = rasterCaps & RC_STRETCHDIB; + if (supportsStretchDib) + return true; + + MessageBox(hwndForMsgBox, TEXT("This printer doesn't support StretchDIBits function"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + return false; +} + +// TODO: make it run in a background thread by constructing new PdfEngine() +// from a file name - this should be thread safe +static void PrintToDevice(DisplayModel *dm, HDC hdc, LPDEVMODE devMode, int fromPage, int toPage) { + + assert(toPage >= fromPage); + assert(dm); + if (!dm) return; + + PdfEngine *pdfEngine = dm->pdfEngine(); + DOCINFO di = {0}; + di.cbSize = sizeof (DOCINFO); + di.lpszDocName = (LPCTSTR)pdfEngine->fileName(); + + if (StartDoc(hdc, &di) <= 0) + return; + + // rendering for the same DisplayModel is not thread-safe + // TODO: in fitz, propably rendering anything might not be thread-safe + RenderQueue_RemoveForDisplayModel(dm); + cancelRenderingForDisplayModel(dm); + + // print all the pages the user requested unless + // bContinue flags there is a problem. + for (int pageNo = fromPage; pageNo <= toPage; pageNo++) { + int rotation = pdfEngine->pageRotation(pageNo); + + DBG_OUT(" printing: drawing bitmap for page %d\n", pageNo); + + // render at a big zoom, 250% should be good enough. It's a compromise + // between quality and memory usage. TODO: ideally we would use zoom + // that matches the size of the page in the printer + // TODO: consider using a greater zoom level e.g. 750.0 + RenderedBitmap *bmp = pdfEngine->renderBitmap(pageNo, 250.0, rotation, NULL, NULL); + if (!bmp) + goto Error; /* most likely ran out of memory */ + + StartPage(hdc); + // MM_TEXT: Each logical unit is mapped to one device pixel. + // Positive x is to the right; positive y is down. + SetMapMode(hdc, MM_TEXT); + + int pageHeight = GetDeviceCaps(hdc, PHYSICALHEIGHT); + int pageWidth = GetDeviceCaps(hdc, PHYSICALWIDTH); + + int topMargin = GetDeviceCaps(hdc, PHYSICALOFFSETY); + int leftMargin = GetDeviceCaps(hdc, PHYSICALOFFSETX); + if (DMORIENT_LANDSCAPE == devMode->dmOrientation) + swap_int(&topMargin, &leftMargin); + + bmp->stretchDIBits(hdc, -leftMargin, -topMargin, pageWidth, pageHeight); + delete bmp; + if (EndPage(hdc) <= 0) { + AbortDoc(hdc); + return; + } + } + +Error: + EndDoc(hdc); +} + +/* Show Print Dialog box to allow user to select the printer +and the pages to print. + +Creates a new dummy page for each page with a large zoom factor, +and then uses StretchDIBits to copy this to the printer's dc. + +So far have tested printing from XP to + - Acrobat Professional 6 (note that acrobat is usually set to + downgrade the resolution of its bitmaps to 150dpi) + - HP Laserjet 2300d + - HP Deskjet D4160 + - Lexmark Z515 inkjet, which should cover most bases. +*/ +static void OnMenuPrint(WindowInfo *win) +{ + PRINTDLG pd; + + assert(win); + if (!win) return; + + DisplayModel *dm = win->dm; + assert(dm); + if (!dm) return; + + /* printing uses the WindowInfo win that is created for the + screen, it may be possible to create a new WindowInfo + for printing to so we don't mess with the screen one, + but the user is not inconvenienced too much, and this + way we only need to concern ourselves with one dm. + TODO: don't re-use WindowInfo, use a different, synchronious + way of creating a bitmap */ + ZeroMemory(&pd, sizeof(pd)); + pd.lStructSize = sizeof(pd); + pd.hwndOwner = win->hwndFrame; + pd.hDevMode = NULL; + pd.hDevNames = NULL; + pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; + pd.nCopies = 1; + /* by default print all pages */ + pd.nFromPage = 1; + pd.nToPage = dm->pageCount(); + pd.nMinPage = 1; + pd.nMaxPage = dm->pageCount(); + + BOOL pressedOk = PrintDlg(&pd); + if (!pressedOk) { + if (CommDlgExtendedError()) { + /* if PrintDlg was cancelled then + CommDlgExtendedError is zero, otherwise it returns the + error code, which we could look at here if we wanted. + for now just warn the user that printing has stopped + becasue of an error */ + MessageBox(win->hwndFrame, TEXT("Cannot initialise printer"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + } /* @note: TEXT() casts */ + return; + } + + if (CheckPrinterStretchDibSupport(win->hwndFrame, pd.hDC)) + PrintToDevice(dm, pd.hDC, (LPDEVMODE)pd.hDevMode, pd.nFromPage, pd.nToPage); + + DeleteDC(pd.hDC); + if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); + if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); +} + +static void OnMenuSaveAs(WindowInfo *win) +{ + OPENFILENAME ofn = {0}; + char dstFileName[MAX_PATH] = {0}; + const char* srcFileName = NULL; + + assert(win); + if (!win) return; + assert(win->dm); + if (!win->dm) return; + + srcFileName = win->dm->fileName(); + assert(srcFileName); + if (!srcFileName) return; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = win->hwndFrame; + ofn.lpstrFile = (TCHAR*)dstFileName; + + // Set lpstrFile[0] to '\0' so that GetOpenFileName does not + // use the contents of szFile to initialize itself. + ofn.lpstrFile[0] = '\0'; + ofn.nMaxFile = dimof(dstFileName); + ofn.lpstrFilter = TEXT("PDF\0*.pdf\0All\0*.*\0"); /* @note: TEXT() casts */ + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT; + + if (FALSE == GetSaveFileName(&ofn)) + return; + + char* realDstFileName = dstFileName; + if (!str_endswithi(dstFileName, ".pdf")) { + realDstFileName = str_cat(dstFileName, ".pdf"); + } + BOOL cancelled = FALSE; + BOOL ok = CopyFileEx((TCHAR*)srcFileName, (TCHAR*)realDstFileName, NULL, NULL, &cancelled, COPY_FILE_FAIL_IF_EXISTS); /* @note: TCHAR* cast */ + if (!ok) { + SeeLastError(); + /* @note: translation needs some care */ + //MessageBox(win->hwndFrame, _TR("Failed to save a file"), TEXT("Information"), MB_OK); + MessageBox(win->hwndFrame, TEXT("Failed to save a file"), TEXT("Information"), MB_OK); + } + if (realDstFileName != dstFileName) + free(realDstFileName); +} + +static void OnMenuOpen(WindowInfo *win) +{ + OPENFILENAME ofn = {0}; + char fileName[PATH_MAX]; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = win->hwndFrame; + ofn.lpstrFile = (TCHAR*)fileName; /* @note: TCHAR* cast */ + + // Set lpstrFile[0] to '\0' so that GetOpenFileName does not + // use the contents of szFile to initialize itself. + ofn.lpstrFile[0] = '\0'; + ofn.nMaxFile = sizeof(fileName); + ofn.lpstrFilter = TEXT("PDF\0*.pdf\0All\0*.*\0"); + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if (FALSE == GetOpenFileName(&ofn)) + return; + + win = LoadPdf(fileName); + if (!win) + return; +} + +static void RotateLeft(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->rotateBy(-90); +} + +static void RotateRight(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->rotateBy(90); +} + +static void OnVScroll(WindowInfo *win, WPARAM wParam) +{ + if (win->documentBlocked) return; + SCROLLINFO si = {0}; + int iVertPos; + + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo(win->hwndCanvas, SB_VERT, &si); + + iVertPos = si.nPos; + + switch (LOWORD(wParam)) + { + case SB_TOP: + si.nPos = si.nMin; + break; + + case SB_BOTTOM: + si.nPos = si.nMax; + break; + + case SB_LINEUP: + si.nPos -= 16; + break; + + case SB_LINEDOWN: + si.nPos += 16; + break; + + case SB_PAGEUP: + si.nPos -= si.nPage; + break; + + case SB_PAGEDOWN: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + // Set the position and then retrieve it. Due to adjustments + // by Windows it may not be the same as the value set. + si.fMask = SIF_POS; + SetScrollInfo(win->hwndCanvas, SB_VERT, &si, TRUE); + GetScrollInfo(win->hwndCanvas, SB_VERT, &si); + + // If the position has changed, scroll the window and update it + if (win->dm && (si.nPos != iVertPos)) + win->dm->scrollYTo(si.nPos); +} + +static void OnHScroll(WindowInfo *win, WPARAM wParam) +{ + if (win->documentBlocked) return; + SCROLLINFO si = {0}; + int iVertPos; + + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo(win->hwndCanvas, SB_HORZ, &si); + + iVertPos = si.nPos; + + switch (LOWORD(wParam)) + { + case SB_TOP: + si.nPos = si.nMin; + break; + + case SB_BOTTOM: + si.nPos = si.nMax; + break; + + case SB_LINEUP: + si.nPos -= 16; + break; + + case SB_LINEDOWN: + si.nPos += 16; + break; + + case SB_PAGEUP: + si.nPos -= si.nPage; + break; + + case SB_PAGEDOWN: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + // Set the position and then retrieve it. Due to adjustments + // by Windows it may not be the same as the value set. + si.fMask = SIF_POS; + SetScrollInfo(win->hwndCanvas, SB_HORZ, &si, TRUE); + GetScrollInfo(win->hwndCanvas, SB_HORZ, &si); + + // If the position has changed, scroll the window and update it + if (win->dm && (si.nPos != iVertPos)) + win->dm->scrollXTo(si.nPos); +} + +static void ViewWithAcrobat(WindowInfo *win) +{ + // TODO: write me +} + +static void OnMenuViewSinglePage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_SINGLE_PAGE); +} + +static void OnMenuViewFacing(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_FACING); +} + +static void OneMenuMakeDefaultReader(void) +{ + AssociateExeWithPdfExtensions(); + /* @note: translation need some care */ + //MessageBox(NULL, _TR("SumatraPDF is now a default reader for PDF files."), "Information", MB_OK); + MessageBox(NULL, TEXT("SumatraPDF is now a default reader for PDF files."), TEXT("Information"), MB_OK); +} + +static void OnSize(WindowInfo *win, int dx, int dy) +{ + int rebBarDy = 0; + if (gShowToolbar) { + SetWindowPos(win->hwndReBar, NULL, 0, 0, dx, rebBarDy, SWP_NOZORDER); + rebBarDy = gReBarDy + gReBarDyFrame; + } + SetWindowPos(win->hwndCanvas, NULL, 0, rebBarDy, dx, dy-rebBarDy, SWP_NOZORDER); +} + +static void ReloadPdfDocument(WindowInfo *win) +{ + if (WS_SHOWING_PDF != win->state) + return; + const char *fileName = NULL; + if (win->dm) + fileName = (const char*)str_dup(win->dm->fileName()); + CloseWindow(win, false); + if (fileName) { + LoadPdf(fileName); + free((void*)fileName); + } +} + +static void RebuildProgramMenus(void) +{ + HMENU m = ForceRebuildMenu(); + WindowInfo *win = gWindowList; + while (win) { + SetMenu(win->hwndFrame, m); + MenuUpdateStateForWindow(win); + win = win->next; + } +} + +static void LanguageChanged(const char *langName) +{ + assert(!str_eq(langName, CurrLangNameGet())); + + CurrLangNameSet(langName); + + RebuildProgramMenus(); + // TODO: recreate tooltips +} + +static void OnMenuLanguage(int langId) +{ + const char *langName = NULL; + for (int i=0; i < LANGS_COUNT; i++) { + if (g_langs[i]._langId == langId) { + langName = g_langs[i]._langName; + break; + } + } + + assert(langName); + if (!langName) return; + if (str_eq(langName, CurrLangNameGet())) + return; + LanguageChanged(langName); +} + +static void OnMenuViewUseFitz(WindowInfo *win) +{ + assert(win); + DBG_OUT("OnMenuViewUseFitz()\n"); + if (gUseFitz) + gUseFitz = FALSE; + else + gUseFitz = TRUE; + + ReloadPdfDocument(win); + win = gWindowList; + while (win) { + MenuUpdateUseFitzStateForWindow(win); + win = win->next; + } +} + +static void OnMenuViewShowHideToolbar() +{ + if (gShowToolbar) + gShowToolbar = FALSE; + else + gShowToolbar = TRUE; + + WindowInfo* win = gWindowList; + while (win) { + if (gShowToolbar) + ShowWindow(win->hwndReBar, SW_SHOW); + else + ShowWindow(win->hwndReBar, SW_HIDE); + int dx, dy, x, y; + Win32_Win_GetPos(win->hwndFrame, &x, &y); + Win32_Win_GetSize(win->hwndFrame, &dx, &dy); + // TODO: a hack. I add 1 to dy to cause sending WM_SIZE msg to hwndFrame + // but I shouldn't really change the size. But I don't know how to + // cause sending WM_SIZE otherwise. I tried calling OnSize() directly, + // but it left scrollbar partially hidden + MoveWindow(win->hwndFrame, x, y, dx, dy+1, TRUE); + MenuUpdateShowToolbarStateForWindow(win); + win = win->next; + } +} + +static void OnMenuViewContinuous(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_CONTINUOUS); +} + +static void OnMenuViewContinuousFacing(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + SwitchToDisplayMode(win, DM_CONTINUOUS_FACING); +} + +static void OnMenuGoToNextPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToNextPage(0); +} + +static void OnMenuGoToPrevPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToPrevPage(0); +} + +static void OnMenuGoToLastPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToLastPage(); +} + +static void OnMenuGoToFirstPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + win->dm->goToFirstPage(); +} + +static void OnMenuGoToPage(WindowInfo *win) +{ + assert(win); + if (!win) return; + if (!WindowInfo_PdfLoaded(win)) + return; + + int newPageNo = Dialog_GoToPage(win); + if (win->dm->validPageNo(newPageNo)) + win->dm->goToPage(newPageNo, 0); +} + +static void OnMenuViewRotateLeft(WindowInfo *win) +{ + RotateLeft(win); +} + +static void OnMenuViewRotateRight(WindowInfo *win) +{ + RotateRight(win); +} + +#define KEY_PRESSED_MASK 0x8000 +static bool WasKeyDown(int virtKey) +{ + SHORT state = GetKeyState(virtKey); + if (KEY_PRESSED_MASK & state) + return true; + return false; +} + +static bool WasShiftPressed() +{ + return WasKeyDown(VK_LSHIFT) || WasKeyDown(VK_RSHIFT); +} + +static bool WasCtrlPressed() +{ + return WasKeyDown(VK_LCONTROL) || WasKeyDown(VK_RCONTROL); +} + +static void OnKeydown(WindowInfo *win, int key, LPARAM lparam) +{ + if (!win->dm) + return; + if (win->documentBlocked) + return; + + bool shiftPressed = WasShiftPressed(); + bool ctrlPressed = WasCtrlPressed(); + //DBG_OUT("key=%d,%c,shift=%d,ctrl=%d\n", key, (char)key, (int)shiftPressed, (int)ctrlPressed); + + if (VK_PRIOR == key) { + /* TODO: more intelligence (see VK_NEXT comment). Also, probably + it's exactly the same as 'n' so the code should be factored out */ + win->dm->goToPrevPage(0); + /* SendMessage (win->hwnd, WM_VSCROLL, SB_PAGEUP, 0); */ + } else if (VK_NEXT == key) { + /* TODO: this probably should be more intelligent (scroll if not yet at the bottom, + go to next page if at the bottom, and something entirely different in continuous mode */ + win->dm->goToNextPage(0); + /* SendMessage (win->hwnd, WM_VSCROLL, SB_PAGEDOWN, 0); */ + } else if (VK_UP == key) { + SendMessage (win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); + } else if (VK_DOWN == key) { + SendMessage (win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); + } else if (VK_LEFT == key) { + SendMessage (win->hwndCanvas, WM_HSCROLL, SB_PAGEUP, 0); + } else if (VK_RIGHT == key) { + SendMessage (win->hwndCanvas, WM_HSCROLL, SB_PAGEDOWN, 0); + } else if (VK_HOME == key) { + win->dm->goToFirstPage(); + } else if (VK_END == key) { + win->dm->goToLastPage(); +#if 0 // we do it via accelerators + } else if ('G' == key) { + if (ctrlPressed) + OnMenuGoToPage(win); +#endif + } else if (VK_OEM_PLUS == key) { + // Emulate acrobat: "Shift Ctrl +" is rotate clockwise + if (shiftPressed & ctrlPressed) + RotateRight(win); + } else if (VK_OEM_MINUS == key) { + // Emulate acrobat: "Shift Ctrl -" is rotate counter-clockwise + if (shiftPressed & ctrlPressed) + RotateLeft(win); + } +} + +static void OnChar(WindowInfo *win, int key) +{ + if (!win->dm) + return; + if (win->documentBlocked) + return; + +// DBG_OUT("char=%d,%c\n", key, (char)key); + + if (VK_SPACE == key) { + win->dm->scrollYByAreaDy(true, true); + } else if (VK_BACK == key) { + win->dm->scrollYByAreaDy(false, true); + } else if ('g' == key) { + OnMenuGoToPage(win); + } else if ('k' == key) { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); + } else if ('j' == key) { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); + } else if ('n' == key) { + win->dm->goToNextPage(0); + } else if ('c' == key) { + // TODO: probably should preserve facing vs. non-facing + win->dm->changeDisplayMode(DM_CONTINUOUS); + } else if ('p' == key) { + win->dm->goToPrevPage(0); + } else if ('z' == key) { + WindowInfo_ToggleZoom(win); + } else if ('q' == key) { + DestroyWindow(win->hwndFrame); + } else if ('+' == key) { + win->dm->zoomBy(ZOOM_IN_FACTOR); + } else if ('-' == key) { + win->dm->zoomBy(ZOOM_OUT_FACTOR); + } else if ('r' == key) { + ReloadPdfDocument(win); + } +} + +static inline bool IsEnumPrintersArg(const char *txt) +{ + if (str_ieq(txt, ENUM_PRINTERS_ARG_TXT)) + return true; + return false; +} + +static inline bool IsDontRegisterExtArg(const char *txt) +{ + if (str_ieq(txt, NO_REGISTER_EXT_ARG_TXT)) + return true; + return false; +} + +static inline bool IsPrintToArg(const char *txt) +{ + if (str_ieq(txt, PRINT_TO_ARG_TXT)) + return true; + return false; +} + +static inline bool IsPrintToDefaultArg(const char *txt) +{ + if (str_ieq(txt, PRINT_TO_ARG_TXT)) + return true; + return false; +} + +static inline bool IsExitOnPrintArg(const char *txt) +{ + if (str_ieq(txt, EXIT_ON_PRINT_ARG_TXT)) + return true; + return false; +} + +static inline bool IsBenchArg(const char *txt) +{ + if (str_ieq(txt, BENCH_ARG_TXT)) + return true; + return false; +} + +static bool IsBenchMode(void) +{ + if (NULL != gBenchFileName) + return true; + return false; +} + +/* Find a file in a file history list that has a given 'menuId'. + Return a copy of filename or NULL if couldn't be found. + It's used to figure out if a menu item selected by the user + is one of the "recent files" menu items in File menu. + Caller needs to free() the memory. + */ +static const char *RecentFileNameFromMenuItemId(UINT menuId) { + FileHistoryList* curr = gFileHistoryRoot; + while (curr) { + if (curr->menuId == menuId) + return str_dup(curr->state.filePath); + curr = curr->next; + } + return NULL; +} + +#define FRAMES_PER_SECS 60 +#define ANIM_FREQ_IN_MS 1000 / FRAMES_PER_SECS + +static void OnMenuAbout() { + if (gHwndAbout) { + SetActiveWindow(gHwndAbout); + return; + } + gHwndAbout = CreateWindow( + ABOUT_CLASS_NAME, (TCHAR*)ABOUT_WIN_TITLE, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + ABOUT_WIN_DX, ABOUT_WIN_DY, + NULL, NULL, + ghinst, NULL); /* @note: TCHAR* cast */ + if (!gHwndAbout) + return; + ShowWindow(gHwndAbout, SW_SHOW); +} + +BOOL PrivateIsAppThemed() { + BOOL isThemed = FALSE; + HMODULE hDll = LoadLibrary(TEXT("uxtheme.dll")); /* @note: TEXT() cast */ + if (!hDll) return FALSE; + + FARPROC fp = GetProcAddress(hDll, "IsAppThemed"); + if (fp) + isThemed = fp(); + + FreeLibrary(hDll); + return isThemed; +} + +static TBBUTTON TbButtonFromButtonInfo(int i) { + TBBUTTON tbButton = {0}; + if (IDB_SEPARATOR == gToolbarButtons[i].cmdId) { + tbButton.fsStyle = TBSTYLE_SEP; + } else { + tbButton.iBitmap = gToolbarButtons[i].index; + tbButton.idCommand = gToolbarButtons[i].cmdId; + tbButton.fsState = TBSTATE_ENABLED; + tbButton.fsStyle = TBSTYLE_BUTTON; + tbButton.iString = (INT_PTR)gToolbarButtons[i].toolTip; + } + return tbButton; +} + +#define WS_TOOLBAR (WS_CHILD | WS_CLIPSIBLINGS | \ + TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | \ + TBSTYLE_LIST | CCS_NODIVIDER | CCS_NOPARENTALIGN ) + +static void CreateToolbar(WindowInfo *win, HINSTANCE hInst) { + BOOL bIsAppThemed = PrivateIsAppThemed(); + + HWND hwndOwner = win->hwndFrame; + HWND hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_TOOLBAR, + 0,0,0,0, hwndOwner,(HMENU)IDC_TOOLBAR, hInst,NULL); + win->hwndToolbar = hwndToolbar; + LRESULT lres = SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + + ShowWindow(hwndToolbar, SW_SHOW); + HIMAGELIST himl = 0; + TBBUTTON tbButtons[TOOLBAR_BUTTONS_COUNT]; + for (int i=0; i < TOOLBAR_BUTTONS_COUNT; i++) { + if (IDB_SEPARATOR != gToolbarButtons[i].bitmapResourceId) { + HBITMAP hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(gToolbarButtons[i].bitmapResourceId)); + if (!himl) { + BITMAP bmp; + GetObject(hbmp, sizeof(BITMAP), &bmp); + int dx = bmp.bmWidth; + int dy = bmp.bmHeight; + himl = ImageList_Create(dx, dy, ILC_COLORDDB | ILC_MASK, 0, 0); + } + int index = ImageList_AddMasked(himl, hbmp, RGB(255,0,255)); + DeleteObject(hbmp); + gToolbarButtons[i].index = index; + } + tbButtons[i] = TbButtonFromButtonInfo(i); + } + lres = SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl); + + // TODO: construct disabled image list as well? + //SendMessage(hwndToolbar, TB_SETDISABLEDIMAGELIST, 0, (LPARAM)himl); + + LRESULT exstyle = SendMessage(hwndToolbar, TB_GETEXTENDEDSTYLE, 0, 0); + exstyle |= TBSTYLE_EX_MIXEDBUTTONS; + lres = SendMessage(hwndToolbar, TB_SETEXTENDEDSTYLE, 0, exstyle); + + lres = SendMessage(hwndToolbar, TB_ADDBUTTONS, TOOLBAR_BUTTONS_COUNT, (LPARAM)tbButtons); + RECT rc; + lres = SendMessage(hwndToolbar, TB_GETITEMRECT, 0, (LPARAM)&rc); + + DWORD reBarStyle = WS_REBAR | WS_VISIBLE; + win->hwndReBar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, reBarStyle, + 0,0,0,0, hwndOwner, (HMENU)IDC_REBAR, hInst, NULL); + if (!win->hwndReBar) + SeeLastError(); + + REBARINFO rbi; + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + lres = SendMessage(win->hwndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi); + + REBARBANDINFO rbBand; + rbBand.cbSize = sizeof(REBARBANDINFO); + rbBand.fMask = /*RBBIM_COLORS | RBBIM_TEXT | RBBIM_BACKGROUND | */ + RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE /*| RBBIM_SIZE*/; + rbBand.fStyle = /*RBBS_CHILDEDGE |*//* RBBS_BREAK |*/ RBBS_FIXEDSIZE /*| RBBS_GRIPPERALWAYS*/; + if (bIsAppThemed) + rbBand.fStyle |= RBBS_CHILDEDGE; + rbBand.hbmBack = NULL; + rbBand.lpText = TEXT("Toolbar"); + rbBand.hwndChild = hwndToolbar; + rbBand.cxMinChild = (rc.right - rc.left) * TOOLBAR_BUTTONS_COUNT; + rbBand.cyMinChild = (rc.bottom - rc.top) + 2 * rc.top; + rbBand.cx = 0; + lres = SendMessage(win->hwndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); + + SetWindowPos(win->hwndReBar, NULL, 0, 0, 0, 0, SWP_NOZORDER); + GetWindowRect(win->hwndReBar, &rc); + gReBarDy = rc.bottom - rc.top; + //TODO: this was inherited but doesn't seem to be right (makes toolbar + // partially unpainted if using classic scheme on xp or vista + //gReBarDyFrame = bIsAppThemed ? 0 : 2; + gReBarDyFrame = 0; +} + +static LRESULT CALLBACK WndProcAbout(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + assert(!gHwndAbout); + break; + + case WM_ERASEBKGND: + // do nothing, helps to avoid flicker + return TRUE; + + case WM_PAINT: + OnPaintAbout(hwnd); + break; + + case WM_DESTROY: + assert(gHwndAbout); + gHwndAbout = NULL; + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +/* TODO: gAccumDelta must be per WindowInfo */ +static int gDeltaPerLine, gAccumDelta; // for mouse wheel logic + +static LRESULT CALLBACK WndProcCanvas(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WindowInfo * win; + win = WindowInfo_FindByHwnd(hwnd); + switch (message) + { + case WM_APP_REPAINT_DELAYED: + if (win) + SetTimer(win->hwndCanvas, REPAINT_TIMER_ID, REPAINT_DELAY_IN_MS, NULL); + break; + + case WM_APP_REPAINT_NOW: + if (win) + WindowInfo_RedrawAll(win); + break; + + case WM_VSCROLL: + OnVScroll(win, wParam); + return WM_VSCROLL_HANDLED; + + case WM_HSCROLL: + OnHScroll(win, wParam); + return WM_HSCROLL_HANDLED; + + case WM_MOUSEMOVE: + if (win) + OnMouseMove(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), wParam); + break; + + case WM_LBUTTONDOWN: + if (win) + OnMouseLeftButtonDown(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_LBUTTONUP: + if (win) + OnMouseLeftButtonUp(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_RBUTTONDOWN: + if (win) + OnMouseRightButtonDown(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_RBUTTONUP: + if (win) + OnMouseRightButtonUp(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_SETCURSOR: + if (win && win->mouseAction == MA_DRAGGING) { + SetCursor(gCursorDrag); + return TRUE; + } + break; + + case WM_TIMER: + assert(win); + if (win) { + if (REPAINT_TIMER_ID == wParam) + WindowInfo_RedrawAll(win); + else + AnimState_NextFrame(&win->animState); + } + break; + + case WM_DROPFILES: + if (win) + OnDropFiles(win, (HDROP)wParam); + break; + + case WM_ERASEBKGND: + // do nothing, helps to avoid flicker + return TRUE; + + case WM_PAINT: + /* it might happen that we get WM_PAINT after destroying a window */ + if (win) { + /* blindly kill the timer, just in case it's there */ + KillTimer(win->hwndCanvas, REPAINT_TIMER_ID); + OnPaint(win); + } + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +static LRESULT CALLBACK WndProcFrame(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + WindowInfo * win; + ULONG ulScrollLines; // for mouse wheel logic + const char * fileName; + + win = WindowInfo_FindByHwnd(hwnd); + + switch (message) + { + case WM_CREATE: + // do nothing + goto InitMouseWheelInfo; + + case WM_SIZE: + if (win) { + int dx = LOWORD(lParam); + int dy = HIWORD(lParam); + OnSize(win, dx, dy); + } + break; + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + fileName = RecentFileNameFromMenuItemId(wmId); + if (fileName) { + LoadPdf(fileName); + free((void*)fileName); + break; + } + + switch (wmId) + { + case IDM_OPEN: + case IDT_FILE_OPEN: + OnMenuOpen(win); + break; + case IDM_SAVEAS: + OnMenuSaveAs(win); + break; + + case IDT_FILE_PRINT: + case IDM_PRINT: + OnMenuPrint(win); + break; + + case IDM_MAKE_DEFAULT_READER: + OneMenuMakeDefaultReader(); + break; + + case IDT_FILE_EXIT: + case IDM_CLOSE: + CloseWindow(win, FALSE); + break; + + case IDM_EXIT: + OnMenuExit(); + break; + + case IDT_VIEW_ZOOMIN: + if (win->dm) + win->dm->zoomBy(ZOOM_IN_FACTOR); + break; + + case IDT_VIEW_ZOOMOUT: + if (win->dm) + win->dm->zoomBy(ZOOM_OUT_FACTOR); + break; + + case IDM_ZOOM_6400: + case IDM_ZOOM_3200: + case IDM_ZOOM_1600: + case IDM_ZOOM_800: + case IDM_ZOOM_400: + case IDM_ZOOM_200: + case IDM_ZOOM_150: + case IDM_ZOOM_125: + case IDM_ZOOM_100: + case IDM_ZOOM_50: + case IDM_ZOOM_25: + case IDM_ZOOM_12_5: + case IDM_ZOOM_8_33: + case IDM_ZOOM_FIT_PAGE: + case IDM_ZOOM_FIT_WIDTH: + case IDM_ZOOM_ACTUAL_SIZE: + OnMenuZoom(win, (UINT)wmId); + break; + + case IDM_ZOOM_FIT_VISIBLE: + /* TODO: implement me */ + break; + + case IDM_VIEW_SINGLE_PAGE: + OnMenuViewSinglePage(win); + break; + + case IDM_VIEW_FACING: + OnMenuViewFacing(win); + break; + + case IDM_VIEW_CONTINUOUS: + OnMenuViewContinuous(win); + break; + + case IDM_VIEW_SHOW_HIDE_TOOLBAR: + OnMenuViewShowHideToolbar(); + break; + + case IDM_VIEW_USE_FITZ: + OnMenuViewUseFitz(win); + break; + + case IDM_GOTO_NEXT_PAGE: + OnMenuGoToNextPage(win); + break; + + case IDM_GOTO_PREV_PAGE: + OnMenuGoToPrevPage(win); + break; + + case IDM_GOTO_FIRST_PAGE: + OnMenuGoToFirstPage(win); + break; + + case IDM_GOTO_LAST_PAGE: + OnMenuGoToLastPage(win); + break; + + case IDM_GOTO_PAGE: + OnMenuGoToPage(win); + break; + + case IDM_VIEW_CONTINUOUS_FACING: + OnMenuViewContinuousFacing(win); + break; + + case IDM_VIEW_ROTATE_LEFT: + OnMenuViewRotateLeft(win); + break; + + case IDM_VIEW_ROTATE_RIGHT: + OnMenuViewRotateRight(win); + break; + + case IDM_VISIT_WEBSITE: + LaunchBrowser(_T("http://blog.kowalczyk.info/software/sumatrapdf/")); + break; + + case IDM_LANG_EN: + case IDM_LANG_PL: + case IDM_LANG_FR: + case IDM_LANG_DE: + OnMenuLanguage((int)wmId); + break; + + case IDM_ABOUT: + OnMenuAbout(); + break; + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + break; + + case WM_CHAR: + if (win) + OnChar(win, wParam); + break; + + case WM_KEYDOWN: + if (win) + OnKeydown(win, wParam, lParam); + break; + + case WM_SETTINGCHANGE: +InitMouseWheelInfo: + SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &ulScrollLines, 0); + // ulScrollLines usually equals 3 or 0 (for no scrolling) + // WHEEL_DELTA equals 120, so iDeltaPerLine will be 40 + if (ulScrollLines) + gDeltaPerLine = WHEEL_DELTA / ulScrollLines; + else + gDeltaPerLine = 0; + return 0; + + // TODO: I don't understand why WndProcCanvas() doesn't receive this message + case WM_MOUSEWHEEL: + if (!win || !win->dm) /* TODO: check for pdfDoc as well ? */ + break; + + if (gDeltaPerLine == 0) + break; + + gAccumDelta += (short) HIWORD (wParam); // 120 or -120 + + while (gAccumDelta >= gDeltaPerLine) + { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); + gAccumDelta -= gDeltaPerLine; + } + + while (gAccumDelta <= -gDeltaPerLine) + { + SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); + gAccumDelta += gDeltaPerLine; + } + return 0; + + case WM_DROPFILES: + if (win) + OnDropFiles(win, (HDROP)wParam); + break; + + case WM_DESTROY: + /* WM_DESTROY might be sent as a result of File\Close, in which case CloseWindow() has already been called */ + if (win) + CloseWindow(win, TRUE); + break; + + case IDM_VIEW_WITH_ACROBAT: + if (win) + ViewWithAcrobat(win); + break; + + case MSG_BENCH_NEXT_ACTION: + if (win) + OnBenchNextAction(win); + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +static BOOL RegisterWinClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + ATOM atom; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProcFrame; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SUMATRAPDF)); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = FRAME_CLASS_NAME; + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); + atom = RegisterClassEx(&wcex); + if (!atom) + return FALSE; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProcCanvas; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = 0; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = CANVAS_CLASS_NAME; + wcex.hIconSm = 0; + atom = RegisterClassEx(&wcex); + if (!atom) + return FALSE; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProcAbout; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = 0; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = ABOUT_CLASS_NAME; + wcex.hIconSm = 0; + atom = RegisterClassEx(&wcex); + if (!atom) + return FALSE; + + return TRUE; +} + +#define IDC_HAND MAKEINTRESOURCE(32649) +static BOOL InstanceInit(HINSTANCE hInstance, int nCmdShow) +{ + ghinst = hInstance; + + globalParams = new GlobalParams(""); + if (!globalParams) + return FALSE; + + SplashColorsInit(); + gCursorArrow = LoadCursor(NULL, IDC_ARROW); + gCursorHand = LoadCursor(NULL, IDC_HAND); // apparently only available if WINVER >= 0x0500 + if (!gCursorHand) + gCursorHand = LoadCursor(ghinst, MAKEINTRESOURCE(IDC_CURSORDRAG)); + gCursorDrag = LoadCursor(ghinst, MAKEINTRESOURCE(IDC_CURSORDRAG)); + gBrushBg = CreateSolidBrush(COL_WINDOW_BG); + gBrushWhite = CreateSolidBrush(COL_WHITE); + gBrushShadow = CreateSolidBrush(COL_WINDOW_SHADOW); + gBrushLinkDebug = CreateSolidBrush(RGB(0x00,0x00,0xff)); + return TRUE; +} + +static void StrList_Reverse(StrList **strListRoot) +{ + StrList *newRoot = NULL; + StrList *cur, *next; + if (!strListRoot) + return; + cur = *strListRoot; + while (cur) { + next = cur->next; + cur->next = newRoot; + newRoot = cur; + cur = next; + } + *strListRoot = newRoot; +} + +static BOOL StrList_InsertAndOwn(StrList **root, char *txt) +{ + StrList * el; + assert(root && txt); + if (!root || !txt) + return FALSE; + + el = (StrList*)malloc(sizeof(StrList)); + if (!el) + return FALSE; + el->str = txt; + el->next = *root; + *root = el; + return TRUE; +} + +static void StrList_Destroy(StrList **root) +{ + StrList * cur; + StrList * next; + + if (!root) + return; + cur = *root; + while (cur) { + next = cur->next; + free((void*)cur->str); + free((void*)cur); + cur = next; + } + *root = NULL; +} + +static StrList *StrList_FromCmdLine(char *cmdLine) +{ + char * exePath; + StrList * strList = NULL; + char * txt; + + assert(cmdLine); + + if (!cmdLine) + return NULL; + + exePath = ExePathGet(); + if (!exePath) + return NULL; + if (!StrList_InsertAndOwn(&strList, exePath)) { + free((void*)exePath); + return NULL; + } + + for (;;) { + txt = str_parse_possibly_quoted(&cmdLine); + if (!txt) + break; + if (!StrList_InsertAndOwn(&strList, txt)) { + free((void*)txt); + break; + } + } + StrList_Reverse(&strList); + return strList; +} + +static void u_DoAllTests(void) +{ +#ifdef DEBUG + printf("Running tests\n"); + u_RectI_Intersect(); +#else + printf("Not running tests\n"); +#endif +} + +#define CONSERVE_MEMORY 1 + +static DWORD WINAPI PageRenderThread(PVOID data) +{ + PageRenderRequest req; + RenderedBitmap * bmp; + + DBG_OUT("PageRenderThread() started\n"); + while (1) { + //DBG_OUT("Worker: wait\n"); + LockCache(); + gCurPageRenderReq = NULL; + int count = gPageRenderRequestsCount; + UnlockCache(); + if (0 == count) { + DWORD waitResult = WaitForSingleObject(gPageRenderSem, INFINITE); + if (WAIT_OBJECT_0 != waitResult) { + DBG_OUT(" WaitForSingleObject() failed\n"); + continue; + } + } + if (0 == gPageRenderRequestsCount) { + continue; + } + LockCache(); + RenderQueue_Pop(&req); + gCurPageRenderReq = &req; + UnlockCache(); + DBG_OUT("PageRenderThread(): dequeued %d\n", req.pageNo); + if (!req.dm->pageVisibleNearby(req.pageNo)) { + DBG_OUT("PageRenderThread(): not rendering because not visible\n"); + continue; + } + assert(!req.abort); + MsTimer renderTimer; + bmp = req.dm->renderBitmap(req.pageNo, req.zoomLevel, req.rotation, pageRenderAbortCb, (void*)&req); + renderTimer.stop(); + LockCache(); + gCurPageRenderReq = NULL; + UnlockCache(); + if (req.abort) { + delete bmp; + continue; + } + if (bmp) + DBG_OUT("PageRenderThread(): finished rendering %d\n", req.pageNo); + else + DBG_OUT("PageRenderThread(): failed to render a bitmap of page %d\n", req.pageNo); + double renderTime = renderTimer.timeInMs(); + BitmapCache_Add(req.dm, req.pageNo, req.zoomLevel, req.rotation, bmp, renderTime); +#ifdef CONSERVE_MEMORY + BitmapCache_FreeNotVisible(); +#endif + WindowInfo* win = (WindowInfo*)req.dm->appData(); + triggerRepaintDisplayNow(win); + } + DBG_OUT("PageRenderThread() finished\n"); + return 0; +} + +static void CreatePageRenderThread(void) +{ + LONG semMaxCount = 1000; /* don't really know what the limit should be */ + DWORD dwThread1ID = 0; + assert(NULL == gPageRenderThreadHandle); + + gPageRenderSem = CreateSemaphore(NULL, 0, semMaxCount, NULL); + gPageRenderThreadHandle = CreateThread(NULL, 0, PageRenderThread, (void*)NULL, 0, &dwThread1ID); + assert(NULL != gPageRenderThreadHandle); +} + +static void PrintFile(WindowInfo *win, const char *fileName, const char *printerName) +{ + char devstring[256]; // array for WIN.INI data + HANDLE printer; + LPDEVMODE devMode = NULL; + DWORD structSize, returnCode; + + if (!win->dm->pdfEngine()->printingAllowed()) { /* @note: TCHAR* and TEXT() casts */ + MessageBox(win->hwndFrame, TEXT("Cannot print this file"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + return; + } + + // Retrieve the printer, printer driver, and + // output-port names from WIN.INI. + GetProfileString(TEXT("Devices"), (TCHAR*)printerName, TEXT(""), (TCHAR*)devstring, sizeof(devstring)); + + // Parse the string of names, setting ptrs as required + // If the string contains the required names, use them to + // create a device context. + char *driver = strtok (devstring, (const char *) ","); + char *port = strtok((char *) NULL, (const char *) ","); + + if (!driver || !port) { + MessageBox(win->hwndFrame, TEXT("Printer with given name doesn't exist"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + return; + } + + BOOL fOk = OpenPrinter((TCHAR*)printerName, &printer, NULL); /* @note: neither LPCTSTR nor LPCTSTR work => TCHAR* cast */ + if (!fOk) { + /* @note: translation need some care */ + //MessageBox(win->hwndFrame, _TR("Could not open Printer"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + MessageBox(win->hwndFrame, TEXT("Could not open Printer"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + return; + } + + HDC hdcPrint = NULL; + structSize = DocumentProperties(NULL, + printer, /* Handle to our printer. */ + (TCHAR*) printerName, /* Name of the printer. */ /* @note: neither LPCTSTR nor LPCTSTR work => TCHAR* cast */ + NULL, /* Asking for size, so */ + NULL, /* these are not used. */ + 0); /* Zero returns buffer size. */ + devMode = (LPDEVMODE)malloc(structSize); + if (!devMode) { + /* @note: "crosses initialization of [...]" issues */ + //goto Exit; + free(devMode); + DeleteDC(hdcPrint); + } + + // Get the default DevMode for the printer and modify it for your needs. + returnCode = DocumentProperties(NULL, + printer, + (TCHAR*) printerName, /* Name of the printer. */ /* @note: neither LPCTSTR nor LPCTSTR work => TCHAR* cast */ + devMode, /* The address of the buffer to fill. */ + NULL, /* Not using the input buffer. */ + DM_OUT_BUFFER); /* Have the output buffer filled. */ + + if (IDOK != returnCode) { + // If failure, inform the user, cleanup and return failure. + MessageBox(win->hwndFrame, TEXT("Could not obtain Printer properties"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + /* @note: "crosses initialization of [...]" issues */ + //goto Exit; + free(devMode); + DeleteDC(hdcPrint); + } + + PdfPageInfo * pageInfo = pageInfo = win->dm->getPageInfo(1); + + if (pageInfo->bitmapDx > pageInfo->bitmapDy) { + devMode->dmOrientation = DMORIENT_LANDSCAPE; + } else { + devMode->dmOrientation = DMORIENT_PORTRAIT; + } + + /* + * Merge the new settings with the old. + * This gives the driver an opportunity to update any private + * portions of the DevMode structure. + */ + DocumentProperties(NULL, + printer, + (TCHAR*) printerName, /* Name of the printer. */ /* @note: neither LPCTSTR nor LPCTSTR work => TCHAR* cast */ + devMode, /* Reuse our buffer for output. */ + devMode, /* Pass the driver our changes. */ + DM_IN_BUFFER | /* Commands to Merge our changes and */ + DM_OUT_BUFFER); /* write the result. */ + + ClosePrinter(printer); + + hdcPrint = CreateDC((TCHAR*)driver, (TCHAR*)printerName, (TCHAR*)port, devMode); + if (!hdcPrint) { + MessageBox(win->hwndFrame, TEXT("Couldn't initialize printer"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); + /* @note: "crosses initialization of [...]" issues */ + //goto Exit; + free(devMode); + DeleteDC(hdcPrint); + } + + if (CheckPrinterStretchDibSupport(win->hwndFrame, hdcPrint)) + PrintToDevice(win->dm, hdcPrint, devMode, 1, win->dm->pageCount()); +Exit: + free(devMode); + DeleteDC(hdcPrint); +} + +static void EnumeratePrinters() +{ + PRINTER_INFO_5 *info5Arr = NULL; + DWORD bufSize = 0, printersCount; + BOOL fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, + 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); + if (!fOk) { + info5Arr = (PRINTER_INFO_5*)malloc(bufSize); + fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, + 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); + } + if (!info5Arr) + return; + assert(fOk); + if (!fOk) return; + printf("Printers: %d\n", printersCount); + for (DWORD i=0; i < printersCount; i++) { + const char *printerName = (char*)info5Arr[i].pPrinterName; /* @note: char* cast */ + const char *printerPort = (char*)info5Arr[i].pPortName; /* @note: char* cast */ + bool fDefault = false; + if (info5Arr[i].Attributes & PRINTER_ATTRIBUTE_DEFAULT) + fDefault = true; + printf("Name: %s, port: %s, default: %d\n", printerName, printerPort, (int)fDefault); + } + TCHAR buf[512]; + bufSize = sizeof(buf); + fOk = GetDefaultPrinter(buf, &bufSize); + if (!fOk) { + if (ERROR_FILE_NOT_FOUND == GetLastError()) + printf("No default printer\n"); + } + free(info5Arr); +} + +/* Get the name of default printer or NULL if not exists. + The caller needs to free() the result */ +char *GetDefaultPrinterName() +{ + char buf[512]; + DWORD bufSize = sizeof(buf); + if (GetDefaultPrinterA(buf, &bufSize)) + return str_dup(buf); + return NULL; +} + +int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) +{ + StrList * argListRoot; + StrList * currArg; + char * benchPageNumStr = NULL; + MSG msg = {0}; + HACCEL hAccelTable; + WindowInfo* win; + int pdfOpened = 0; + bool exitOnPrint = false; + bool printToDefaultPrinter = false; + + UNREFERENCED_PARAMETER(hPrevInstance); + + u_DoAllTests(); + + INITCOMMONCONTROLSEX cex; + cex.dwSize = sizeof(INITCOMMONCONTROLSEX); + cex.dwICC = ICC_WIN95_CLASSES | ICC_DATE_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES; + InitCommonControlsEx(&cex); + + argListRoot = StrList_FromCmdLine((char*)lpCmdLine); /* @note: char* cast */ + assert(argListRoot); + if (!argListRoot) + return 0; + + Prefs_Load(); + /* parse argument list. If BENCH_ARG_TXT was given, then we're in benchmarking mode. Otherwise + we assume that all arguments are PDF file names. + BENCH_ARG_TXT can be followed by file or directory name. If file, it can additionally be followed by + a number which we interpret as page number */ + bool registerForPdfExtentions = true; + currArg = argListRoot->next; + char *printerName = NULL; + while (currArg) { + if (IsEnumPrintersArg(currArg->str)) { + EnumeratePrinters(); + /* this is for testing only, exit immediately */ + goto Exit; + } + + if (IsDontRegisterExtArg(currArg->str)) { + registerForPdfExtentions = false; + currArg = currArg->next; + continue; + } + + if (IsBenchArg(currArg->str)) { + currArg = currArg->next; + if (currArg) { + gBenchFileName = currArg->str; + if (currArg->next) + benchPageNumStr = currArg->next->str; + } + break; + } + + if (IsExitOnPrintArg(currArg->str)) { + currArg = currArg->next; + exitOnPrint = true; + continue; + } + + if (IsPrintToDefaultArg(currArg->str)) { + printToDefaultPrinter = true; + continue; + } + + if (IsPrintToArg(currArg->str)) { + currArg = currArg->next; + if (currArg) { + printerName = currArg->str; + currArg = currArg->next; + } + continue; + } + + // we assume that switches come first and file names to open later + // TODO: it would probably be better to collect all non-switches + // in a separate list so that file names can be interspersed with + // switches + break; + } + + if (benchPageNumStr) { + gBenchPageNum = atoi(benchPageNumStr); + if (gBenchPageNum < 1) + gBenchPageNum = INVALID_PAGE_NO; + } + + LoadString(hInstance, IDS_APP_TITLE, windowTitle, MAX_LOADSTRING); + if (!RegisterWinClass(hInstance)) + goto Exit; + + CaptionPens_Create(); + if (!InstanceInit(hInstance, nCmdShow)) + goto Exit; + + hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SUMATRAPDF)); + + CreatePageRenderThread(); + /* remaining arguments are names of PDF files */ + if (NULL != gBenchFileName) { + win = LoadPdf(gBenchFileName); + if (win) + ++pdfOpened; + } else { + while (currArg) { + win = LoadPdf(currArg->str); + if (!win) + goto Exit; + + if (exitOnPrint) + ShowWindow(win->hwndFrame, SW_HIDE); + + if (printToDefaultPrinter) { + printerName = GetDefaultPrinterName(); + if (printerName) + PrintFile(win, currArg->str, printerName); + free(printerName); + } else if (printerName) { + // note: this prints all of PDF files. Another option would be to + // print only the first one + PrintFile(win, currArg->str, printerName); + } + ++pdfOpened; + currArg = currArg->next; + } + } + + if (printerName && exitOnPrint) + goto Exit; + + if (0 == pdfOpened) { + /* disable benchmark mode if we couldn't open file to benchmark */ + gBenchFileName = 0; +#ifdef REOPEN_FILES_AT_STARTUP + FileHistoryList * currFile = gFileHistoryRoot; + while (currFile) { + if (currFile->state.visible) { + win = LoadPdf(currFile->state.filePath, false); + if (win) + ++pdfOpened; + } + currFile = currFile->next; + } +#endif + if (0 == pdfOpened) { + win = WindowInfo_CreateEmpty(); + if (!win) + goto Exit; + WindowInfoList_Add(win); + + /* TODO: should this be part of WindowInfo_CreateEmpty() ? */ + DragAcceptFiles(win->hwndFrame, TRUE); + ShowWindow(win->hwndCanvas, SW_SHOW); + UpdateWindow(win->hwndCanvas); + ShowWindow(win->hwndFrame, SW_SHOW); + UpdateWindow(win->hwndFrame); + } + } + + if (IsBenchMode()) { + assert(win); + assert(pdfOpened > 0); + if (win) + PostBenchNextAction(win->hwndFrame); + } + + if (0 == pdfOpened) + MenuToolbarUpdateStateForAllWindows(); + + if (registerForPdfExtentions) + RegisterForPdfExtentions(win ? win->hwndFrame : NULL); + + while (GetMessage(&msg, NULL, 0, 0)) { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + +Exit: + WindowInfoList_DeleteAll(); + FileHistoryList_Free(&gFileHistoryRoot); + CaptionPens_Destroy(); + DeleteObject(gBrushBg); + DeleteObject(gBrushWhite); + DeleteObject(gBrushShadow); + DeleteObject(gBrushLinkDebug); + + delete globalParams; + StrList_Destroy(&argListRoot); + Translations_FreeData(); + CurrLangNameFree(); + //histDump(); + return (int) msg.wParam; +} + +// Code for DLL interace +static WindowInfo* CreateEmpty(HWND parentHandle) { + WindowInfo* pdfWin; + HWND hwndCanvas; + pdfWin = WindowInfo_New(parentHandle); + hwndCanvas = CreateWindow( + CANVAS_CLASS_NAME, NULL, + WS_CHILD | WS_HSCROLL | WS_VSCROLL, + CW_USEDEFAULT, CW_USEDEFAULT, + DEF_WIN_DX, DEF_WIN_DY, + parentHandle, NULL, + ghinst, NULL); + if (hwndCanvas) + pdfWin->hwndCanvas = hwndCanvas; + return pdfWin; +} + +static void OpenPdf(WindowInfo* pdfWin,const char *fileName, HWND parentHandle) +{ + assert(fileName); + if (!fileName) return; + assert(pdfWin); + if (!pdfWin) return; + + pdfWin->GetCanvasSize(); + SizeI maxCanvasSize = GetMaxCanvasSize(pdfWin); + SizeD totalDrawAreaSize(pdfWin->winSize()); + DisplayMode displayMode = DEFAULT_DISPLAY_MODE; + int offsetX = 0; + int offsetY = 0; + int startPage = 1; + int scrollbarYDx = 0; + int scrollbarXDy = 0; + + if (gUseFitz) { + pdfWin->dm = DisplayModelFitz_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, pdfWin); + } + else { + pdfWin->dm = DisplayModelSplash_CreateFromFileName(fileName, + totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, pdfWin); + } + + pdfWin->dm->setAppData((void*)pdfWin); + pdfWin->state = WS_SHOWING_PDF; + double zoomVirtual = DEFAULT_ZOOM; + int rotation = DEFAULT_ROTATION; + + UINT menuId = MenuIdFromVirtualZoom(zoomVirtual); + ZoomMenuItemCheck(GetMenu(pdfWin->hwndFrame), menuId); + + pdfWin->dm->relayout(zoomVirtual, rotation); + if (!pdfWin->dm->validPageNo(startPage)) + startPage = 1; + offsetY = 0; + pdfWin->dm->goToPage(startPage, offsetY, offsetX); + WindowInfo_ResizeToPage(pdfWin, startPage); + WindowInfoList_Add(pdfWin); + + RECT rect; + if (GetWindowRect(pdfWin->hwndFrame , &rect) != 0) + { + int nWidth = rect_dx(&rect); + int nHeight = rect_dy(&rect); + WinResizeClientArea(pdfWin->hwndCanvas, nWidth, nHeight); + } + + ShowWindow(pdfWin->hwndFrame, SW_SHOW); + ShowWindow(pdfWin->hwndCanvas, SW_SHOW); + UpdateWindow(pdfWin->hwndFrame); + UpdateWindow(pdfWin->hwndCanvas); +} + +void Sumatra_LoadPDF(WindowInfo* pdfWin, const char *pdfFile) +{ + int pdfOpened = 0; + OpenPdf(pdfWin, pdfFile, pdfWin->hwndFrame); + ++pdfOpened; + if (pdfWin) + ShowWindow(pdfWin->hwndFrame, SW_SHOWNORMAL); +} + +void Sumatra_PrintPDF(WindowInfo* pdfWin, const char *pdfFile, long showOptionWindow) +{ +} + +void Sumatra_Print(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + OnMenuPrint(pdfWin); +} + +void Sumatra_ShowPrintDialog(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + OnMenuPrint(pdfWin); +} + +void Sumatra_SetDisplayMode(WindowInfo* pdfWin,long displayMode) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + SwitchToDisplayMode(pdfWin, (DisplayMode)displayMode); +} + +long Sumatra_GoToNextPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToNextPage(0); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToPreviousPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToPrevPage(0); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToFirstPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToFirstPage(); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToLastPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + pdfWin->dm->goToLastPage(); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GetNumberOfPages(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + return pdfWin->dm->pageCount(); +} + +long Sumatra_GetCurrentPage(WindowInfo* pdfWin) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_GoToThisPage(WindowInfo* pdfWin,long pageNumber) +{ + if (!WindowInfo_PdfLoaded(pdfWin)) + return 0; + if (pdfWin->dm->validPageNo(pageNumber)) + pdfWin->dm->goToPage(pageNumber, 0); + return pdfWin->dm->currentPageNo(); +} + +long Sumatra_ZoomIn(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + { + long currentZoom = Sumatra_GetCurrentZoom(pdfWin); + if (currentZoom < 500) + Sumatra_SetZoom(pdfWin,currentZoom+10); + } + return Sumatra_GetCurrentZoom(pdfWin); +} + +long Sumatra_ZoomOut(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + { + long currentZoom = Sumatra_GetCurrentZoom(pdfWin); + if (currentZoom > 10) + Sumatra_SetZoom(pdfWin,currentZoom-10); + } + return Sumatra_GetCurrentZoom(pdfWin); +} + +long Sumatra_SetZoom(WindowInfo* pdfWin,long zoomValue) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + pdfWin->dm->zoomTo((double)zoomValue); + return Sumatra_GetCurrentZoom(pdfWin); +} + +long Sumatra_GetCurrentZoom(WindowInfo* pdfWin) +{ + double zoomLevel = 0; + if (WindowInfo_PdfLoaded(pdfWin)) + zoomLevel = pdfWin->dm->zoomReal(); + return (long)zoomLevel; +} + +void Sumatra_Resize(WindowInfo* pdfWin) +{ + RECT rect; + if (GetWindowRect(pdfWin->hwndFrame , &rect) != 0) + { + int nWidth = rect_dx(&rect); + int nHeight = rect_dy(&rect); + WinResizeClientArea(pdfWin->hwndCanvas, nWidth, nHeight); + } +} + +void Sumatra_ClosePdf(WindowInfo* pdfWin) +{ + if (WindowInfo_PdfLoaded(pdfWin)) + CloseWindow(pdfWin, FALSE); +} + +WindowInfo* Sumatra_Init(HWND pHandle) +{ + WindowInfo* pdfWin; + gRunningDLL = true; + HINSTANCE hInstance = NULL; + HINSTANCE hPrevInstance = NULL; + int nCmdShow = 0; + + StrList * argListRoot = NULL; + StrList * currArg = NULL; + MSG msg = {0}; + bool exitOnPrint = false; + bool printToDefaultPrinter = false; + gUseFitz = TRUE; + + UNREFERENCED_PARAMETER(hPrevInstance); + + u_DoAllTests(); + + INITCOMMONCONTROLSEX cex; + cex.dwSize = sizeof(INITCOMMONCONTROLSEX); + cex.dwICC = ICC_WIN95_CLASSES | ICC_DATE_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES; + InitCommonControlsEx(&cex); + argListRoot = NULL; + + LoadString(hInstance, IDS_APP_TITLE, windowTitle, MAX_LOADSTRING); + + if (!RegisterWinClass(hInstance)) + Sumatra_Exit(); + + CaptionPens_Create(); + + if (!InstanceInit(hInstance, nCmdShow)) + Sumatra_Exit(); + + CreatePageRenderThread(); + + bool reuseExistingWindow = false; + + if (pHandle == 0 ) + pHandle = NULL; + + pdfWin = CreateEmpty(pHandle); + + return pdfWin; +} + +void Sumatra_Exit() +{ + CaptionPens_Destroy(); + DeleteObject(gBrushBg); + DeleteObject(gBrushWhite); + DeleteObject(gBrushShadow); + DeleteObject(gBrushLinkDebug); + delete globalParams; +} diff --git a/rosapps/smartpdf/src/SumatraPDF.h b/rosapps/smartpdf/src/SumatraPDF.h new file mode 100644 index 00000000000..533642a8472 --- /dev/null +++ b/rosapps/smartpdf/src/SumatraPDF.h @@ -0,0 +1,165 @@ +/* Copyright Krzysztof Kowalczyk 2006-2007 + License: GPLv2 */ +#ifndef SUMATRAPDF_H_ +#define SUMATRAPDF_H_ + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER +#define WINVER 0x0410 +#endif + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include + +#include +#include +#include +#include +#include "resource.h" + +#include "win_util.h" +#include "DisplayModelSplash.h" +#include "DisplayModelFitz.h" + +/* TODO: Currently not used. The idea is to be able to switch between different + visual styles. Because I can. */ +enum AppVisualStyle { + VS_WINDOWS = 1, + VS_AMIGA +}; + +/* Current state of a window: + - WS_ERROR_LOADING_PDF - showing an error message after failing to open a PDF + - WS_SHOWING_PDF - showing a PDF file + - WS_ABOUT - showing "about" screen */ +enum WinState { + WS_ERROR_LOADING_PDF = 1, + WS_SHOWING_PDF, + WS_ABOUT +}; + +/* When doing "about" animation, remembers the current animation state */ +typedef struct { + HWND hwnd; + int frame; + UINT_PTR timerId; +} AnimState; + +/* Describes actions which can be performed by mouse */ +enum MouseAction { + MA_IDLE = 0, + MA_DRAGGING, + MA_SELECTING +}; + +/* Represents selected area on given page */ +typedef struct SelectionOnPage { + int pageNo; + RectD selectionPage; /* position of selection rectangle on page */ + RectI selectionCanvas; /* position of selection rectangle on canvas */ + SelectionOnPage *next; /* pointer to next page with selected area + * or NULL if such page not exists */ +} SelectionOnPage; + +/* Describes information related to one window with (optional) pdf document + on the screen */ +class WindowInfo { +public: + WindowInfo() { + memzero(this, sizeof(*this)); // TODO: this might not be valid + } + void GetCanvasSize() { + GetClientRect(hwndCanvas, &m_canvasRc); + } + int winDx() { return rect_dx(&m_canvasRc); } + int winDy() { return rect_dy(&m_canvasRc); } + SizeI winSize() { return SizeI(rect_dx(&m_canvasRc), rect_dy(&m_canvasRc)); } + + /* points to the next element in the list or the first element if + this is the first element */ + WindowInfo * next; + WinState state; + WinState prevState; + + DisplayModel * dm; + HWND hwndFrame; + HWND hwndCanvas; + HWND hwndToolbar; + HWND hwndReBar; + + HDC hdc; + BITMAPINFO * dibInfo; + + /* bitmap and hdc for (optional) double-buffering */ + HDC hdcToDraw; + HDC hdcDoubleBuffer; + HBITMAP bmpDoubleBuffer; + + PdfLink * linkOnLastButtonDown; + const char * url; + + /*if set to TRUE, page rotating, zooming, and scrolling is impossible */ + bool documentBlocked; + + MouseAction mouseAction; + + /* when dragging the document around, this is previous position of the + cursor. A delta between previous and current is by how much we + moved */ + int dragPrevPosX, dragPrevPosY; + AnimState animState; + + bool showSelection; + + /* selection rectangle in screen coordinates + * while selecting, it represents area which is being selected */ + RectI selectionRect; + + /* after selection is done, the selected area is converted + * to user coordinates for each page which has not empty intersection with it */ + SelectionOnPage *selectionOnPage; + + +private: + RECT m_canvasRc; +}; + +#endif + +#define SUMATRAPDF_API __declspec(dllexport) +extern "C" { + SUMATRAPDF_API void Sumatra_LoadPDF(WindowInfo* pdfWin, const char *pdfFile); + SUMATRAPDF_API void Sumatra_Print(WindowInfo* pdfWin); + SUMATRAPDF_API void Sumatra_PrintPDF(WindowInfo* pdfWin, const char *pdfFile, long showOptionWindow); + SUMATRAPDF_API void Sumatra_SetDisplayMode(WindowInfo* pdfWin, long displayMode); + SUMATRAPDF_API long Sumatra_GoToNextPage(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_GoToPreviousPage(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_GoToFirstPage(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_GoToLastPage(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_GoToThisPage(WindowInfo* pdfWin, long pageNumber); + SUMATRAPDF_API long Sumatra_GetNumberOfPages(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_GetCurrentPage(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_ZoomIn(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_ZoomOut(WindowInfo* pdfWin); + SUMATRAPDF_API long Sumatra_SetZoom(WindowInfo* pdfWin, long zoomValue); + SUMATRAPDF_API long Sumatra_GetCurrentZoom(WindowInfo* pdfWin); + SUMATRAPDF_API void Sumatra_Resize(WindowInfo* pdfWin); + SUMATRAPDF_API void Sumatra_ClosePdf(WindowInfo* pdfWin); + SUMATRAPDF_API void Sumatra_ShowPrintDialog(WindowInfo* pdfWin); + SUMATRAPDF_API WindowInfo* Sumatra_Init(HWND parentHandle); + SUMATRAPDF_API void Sumatra_Exit(); +} diff --git a/rosapps/smartpdf/src/SumatraPDF.ico b/rosapps/smartpdf/src/SumatraPDF.ico new file mode 100644 index 0000000000000000000000000000000000000000..59e730ca9a4121fb67b6ddb561006e0d02b58f1b GIT binary patch literal 9158 zcmeHN30PBC7XC3TipplJidz)57EwXP+A0uf)m9}MYZau^>2$NU9VM7{TD#${3}V8j zSQYoBwhFk{rS3(oMGyfIkS&3*gn(#U+xhOC`?3%b2WLK=>CAY(@8rIF&i|ix-p%8^ zb8Y}^U<+?=(AXL~oPeS&fl>EUhM(&Ck}2Zf0GA`g+DO(7Ezy+BkEHvmVQ`)pWaH~?+4yD$pXXxN)?6g-%E8_}IY`}|i+#yCID8-r zN59R+!M(XSwEr589xTN1BL(>GXg;DNilJUu1XY9>JYcE9`TFn zX>6eJHew_0Ab!CeBrLi^$G;(t^uV4{9NJri!~2SG>~Jwo9xue{lLa_)>IN>HzlI+! zUdN>$3UKyx5zd_{LfW}vq@C5^Vp=IKUDP1`k`@=vRnw@$<@6$CTrNgth89<^YH6%M zR;CWwS9QqEuEw?8N?f~EgZ%3?D9AUU=tez?if*E$_!i1ae?nOq*Pjuc4D3t?P8om< z=89bAgF+@pDN{hl)Tm`CxXm)a7!&S=!To^Aqk*tcK&1qdqk;6DfZ;U2GF`!PeZUIj zU}XxhN;Q}v1?+Z4BVSDX-o&RHPUTPhAmURj!z|)|>az%&_+ zd=c?&iBI>kstxh!K22{&e7et>#0|{f2kaF&*gOT;DmB=F6tJv}Mn0S{8J!S@UQl5G zk}(|Vkivi$!CYs6`GkSVmw+kOf~ix%QqsUOZdmap#2-%liNt@M_#Y8Jn)q9YznA#O ziT^$E>743(;%kU+u<*Sw7!xSMEQ+v{B5b7yXDC83MKHKB)cY_r$Qf=c7=BVS{F1`( zYX-CMyAppO@dJoIh4^m}|3l(0BYvVQ!!{p=eR76V3WjtwLw*WFRYoJfHSzfhbR>RP z;`btcKjM24-`|xX*oQ$OXNXczEH%S-DGYfTjr@Ba2oKkwY+3$fea4pIb7ol+TE@Tk zw$h5wGXCv9E3F7E%Pk3*c%wd)Z-%VzcAdgqbG(;u~8ezg);uF60yG`-3NzW0%XHxTc z2P?cw=N=;44s;ri*~%eS`1|G4?kz>w`$O7NCc_^npLYCO=K8wHWPKI)&F5|73Wn45 z3V7ulkxUji>wfvTcI)po{C%ae5g*=NCL8+-U!NyNjvP5^rc!CWK70{_o}W6m5kL1y zne4@>l#eWk%g}rAGTC!~w8HnJ_@R`KQ3ffM*6ZVDW9ulBO&qAO38Q=_cJv+M>-+lM`Ox|8M%@iKu%GU>SAITpY^C8p&iTV3_ATWW<>+`7azt4QEYlDY=Of@jcZ+|n7 zMRW!mn)4Cn@e9*Dz%=$Wjn1ag!8D2kvw7rws)STZYUxv{7idnRKdp!A z3)0VTQ=j<@5?ACSDgFlaeK)8FyMfpxrPRZf(pW~L7Hd{$sIRL)%={X}FV^GBXdPBB zuf>|ETC7`HjrFl5NQx`LT9p>-V{}-jswOP&`|1d9Kup9f#4X@`-!DSHw=tm<8{;+D zl30RmYfG?sH9yv3`?_-MSYM2tNm^`5&|yQ29vkEIP#@WV;-ZGTddSt(C+?>{G0Un?6b}Y^Q%&g|2KcFfiOE0+ z^_epbz(>?)MpB=-mio-y)MuU`ekSqDtoZ$iFP#j`2m_QVJnmB;_o)xDPYrEeUNS#P zns*0J8fyYH?|*r6unEw-e~LUb)Cg$aFCRB0#2BG@f9UkdFTNljMmgNaFPQoM-S6KY z92_hpNn>zu2tN!ljY9q*c251LbEBP;lT*9)LnnrYIym)`ah%cLR?=@8_d80s^yn-L z^^gn*vi1)$`P&Wla1}|On$py7<_~%~Sk}qbZA?>tr+~3jd3+vcw0rkwJS1ZOpb670 z=kMOF!;|Ap{xL2+hj>VObn)`?v-m|eB8jKW$bYV@$k#*2^ywMq{M$dT_PN+!E@QL;Lb*kGKG9SC%1mkq&W-b%Q#$ zJ#q8^)f9)cIG9|4L!>8jIb3C^4-r`kdz)D{=h%4uF9)D}Npti+EOsjm33lC&B* z**c+?$j;JJ9igNB=PIfrXb+m|h|J3d~n7;Orxyl6vrIBn=k zX+w8BTv;f5s6LRhrBJYSP_tB|u=BJ}-MAmyis}SgsuS#~PH0Vaf@3n!mg)>A1J#Pm z4SrN-gi@XHF~xaYr_g@*`P}EBz_#v*R`qqD|QOijL@qFC*Vx#Kq?}&d1%UG^Y@qwsf5)0 z9+TS8q#04quY!7hHP%GdA}OX4tCrqG!s1&rZ@_w$0ZFP`*brMqJu&sXvDMfVugBIz z>Ume!;H&ku)CbpLQ(QeZ#x`Jc{4H!rXu$S0H?eC&HNCTH=-pL=1G~$Svb_q)bez1S z0{g$Np>Hucr5to_bxq z(BGz=HXt*-9#=E#k)2hKYdJURchfrRck5ADP)}n63JQ47dke+IcfYSvn1){9YJpK5;Mnv=^btZKnrTJA5CzZ=6jX-JR!U1pa06FzBu8)*M}JZelH=0st^UPxQyLNZ8*2>(P?1svCiU{%r3V-e>$LWcf3T-U5mo34BByffsq|g% I@69~(1C#cGI{*Lx literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/Thumbs.db b/rosapps/smartpdf/src/icons-silk/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..5548668a6b6ff1267e167e11ddadcb7b95bb968d GIT binary patch literal 15872 zcmeI22|U%=`^UeyvSi$3h)4I06V||Z~1x4*UwN1W=jZ zAYTn=0Gfanum;cubO2poEuaUi15laukQ)Gozy@F=U<7Oei~$qC6xa-y0jP`xQ0=NQhfIHv;cmiI4H-Oaa1MCHS zfqej~&mZ#r0P^V+z#=M`zYizdFcuw6ZB2{;*WTl{DrI@Tj^N4~PdW$+dohT@wk8@~f>FDQz zK^_Yzl!}THM}>L~*8AXd497~%Hh<~LIqU{jGz(lfmIa(lq!n3}eVx;=VMtWg+BJ}l zo{O7@mrrb=_@ZAVh6OH{61jEIIdHL}?aEbyB~ z_Q$|Jj*EaXP*K2_N5u*P9DCVeSJkhzuGwr={iDRfkn_j2tq$rc-)>uWgYUBBJ5y~@ z!P3im+kBS{x4QXvCJlL(x`+2}7)hs%avH&+6SULcuEW%mka3pLU_8)QSRpHMpF?ZdoI0) z3su5IM5!9G?;3}e+xm09R~|Z^+##hoiRs4HUemN)LtTGjFj9oy_a>*lwEEGMT@U@{ z`1%id9aLi+_F8%0*GMojjUaU`zBSY7%!OSs7JfTAY!x?cxURZOq*JR#XwGnSd+Omg z{j$}bqbZ4dIOrHNJiQE}B;DqQ7q5xbN6~YUMSl03OYxryZKmjET$A+2Ox7P+ ze?L}#X9$WM$WT3~d0QA=Toeu`Lia(u{M58mS9Q~HiBPHA;wRbevB5(&kfDjs*Nd*TI& zt4B+V3hM{@+ZDJ58t*-75f7Q;|&LzcJaqJ4v6eXITEa-U?h^3 z{zQ-{_59GKfo*xeu6=ul>+Oq>QrZ=R^4Q*|~+?xF0)l=UlcV zr_r5>{+8&{zAR^%=5Bu%TYVMZm8UXvCNb-Gs&Nz2&UQ>r`U95l%3Fp#y47dtGCz?k zNk0-~{g9tOe(>`L!*C{%>GieEHT&y%p5?_W$4E;hVSBDK2xCtxv`+2z@fq`oXC}s< z>@4N=P!;TV+WOc!Qb`+kma^eysZosDi+;4P|FBJm{}DCGp>2G^!7Xcp`CsG- z=-3%bQRSu2XALjbTmXA;Ho{KA9&euFyhXH!_qM-~bL6Aq%-weNmWWf-9_A-eniJv< zu73NsVl-KsR~Q8*-5Y;d+D{ntS8H|bvcadkEYVv%!6@}ks^sbjnVc%yV3ktDCV7LA@HIa1oHU*`51BV#?G)f^sVwg7$$z~swU1aMdWON-bN#bU z6^123D@_SbsUGKBlkc3lgR86Q8c+^Y4z*ct*{h&bmX-G8aaA^Nl3swB@Wo2LXI}Fz zv`v)m8dK9{BcAjce~>Ui{rpu6@rD2Hj!CRQy~#mFd@NLS&~c%^M;p$syQuduV}eANl96o z8q-Mdp7W2qW_4U^)xKbtiV}t{|0fpCFYk4gZ#ntAu4R0u`Yq?)=bsf9Nk1z8rTRfJ zvhPW-{+v25fX)ZZcKvG(wrk*iqx2g@z}x``h-jgh*WXPL-I;0^wT;qj%I^fD)o9ZK zlH!N#oBw{x`g=FDrZ+wQB~ua1Z*Cs$JtYN-&oTnD9lsygnoqY+j(^P}u=mfbf5(ig z1(yv49Vv0SsGU(3o4?e=H1oi&bIj8IPg+O9u3ce&m2iR!W6$*@==n4Ft{b`$sAA+0 zYf*jG+i!s2mR5Pbjw8QGI@Bq~w2U#5CH zf0^U9kt?D)fwpU|2e>tAjwl7z?&iPuHm@{VGU%$avSWGgo{78Bx!v7O6Bd(LlK*F2 z>#Qa<3+$Ysxw~~56r-Pth%-m|~jEX%(%aOmZ!FIt}fZg!k z2hV}_6{lo9U3NRzI6ze079!-*5M_4+Ta=L9)b#(X-N*Vw!44wE7&dL^1T}d>PiEGI zY|#GS|F-#9&tmu(ov9+(?1ui>LX_Sf`sV?W`W!sPSqH_^w-*u*~{nQ=$ zFyfDvs8+femOjw3Gu)3Yf5b0W!VMwE|H<+H&mL^}XZ+tNzTK{`pe;_lLf);n*t;n! zYd)K5HU3v7ok;T&sWhpo0e5A$$oe&^(=RS#8zwrq=ll0vE#&HG729|Bd?IdKs}sLY z(o26l)vjzvBP+;PE2Xq8C;U#q)tsf0QI*G(wD}VaN`|zej~%_yzjJ8>;a$z!J92KXeJr6})8u;a^e~@2LCvx^|KiPWa)PAi&-Fh^e*xeX z0)Yd-LEt~YAs`4i3>*Q1fujIAHxvT-aUc{p0h|QFfN&rJhy(5_}X0;FYHMhwy4AXh&`Q6@mMK!Uw@Mk&6BM=-Z5!ca+NL5!DZzC;IFp3iz4E$++i9 zu!%l-VtFsy^t8Rj?MIK@4(zA)J001KANE&2uktd^aLN}OL?k7MWu7x{>S}OJPuH*z zsvlWgm?hG2s!qu@iZ9*8^=gEf{VP)`u6%7%Q-!?PSw?e6{#WrQ`QM+dzoq{N>(7}U z23+q~(=o8nfcuTovhQzy>KT>^>O%dPs`M*=V&U@@)9uTCfBRGC&(YKMY}>yGwyM+Z zf2FIl`uOkO|CyDN*Z)6l{Xb64?R?>d;c%$Q1DSrQ_|}2<>ADx@A15$y;b@0U1CNEd z-Kvq8#45_U{VP@z;*z`?d-FG)Q*@NM#FB*Pm&=Yg!NT+`jE-BBp^dLgZN4u*k?CrC zcZ1x~IC))u``AIfU5_@42U=WWQ&e|b6ehe)m9l_}VTmNZj6pl?{leh@spDC6g+%Vd zmm2YgjhU1Mj~cc`v^-wj!f`WTUW`C-NEK_2)zH55#7(hh92-hK9QQSqzsZ-M#CD`x zZfxi1d6YY5Hkw!FHA_c3bJESYCi&mR|E2zytiPY8zp>^H=jx-S3RS6|VG1}K7mH5~TQjb5>PSXEUvi`~O%O4!SWV~lxOw^0mocT5}ZIv_o zonS&^f7@}|mWY}P1^LHpW-9TKS#5EeqpD^m^@C2LWo8_K9fSdEmF7bhZIYcAHXW(i zd(2p%llh=ecY3n)5i8Y$qblsnt5XT0uTu7(Xwz&-j1gT~(ka2b&O2+x@T$}{e3fkS zTJh2*j~>T952@wChZKVBPgJ|HRrAptc0Q3K)OPEx4Z&C4;qvQb-s>rETnG9me6s3C jd8`&SRT`zGTkdKPlF_|XaIdvo@6GG)`@f5%iPHZ7)T6#w literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/folder.bmp b/rosapps/smartpdf/src/icons-silk/folder.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f814309646b0ae8ad6f7bee4817080a6816a9969 GIT binary patch literal 822 zcmdr}F-yZh7_B(Eh?BoSoW!XhZX$?-xCkyfiJ;P{LO~I2aVoU-KlI3}7UI!jQJv-BWKJ2q z2g7Ok)~iRDTmyU|nTb#1u-4kGY8zz~D53c$b@~yGvkIeNw?AE0w`^qDDz+6&@(9Oi zP*n@PprxWZmxmnm=xfM~=cJvqxOyqv2nb+8rzkfukxU|*gc`d2Wy6Z|>Rt(kAHYho z5lGb|thAMt))^_35rY{~&^-HUm_*<77_T0e)kFnRPiQ$2a>w7WJpLAO5-BX=e4IP_ HpWVLz=Qluq literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/folder.png b/rosapps/smartpdf/src/icons-silk/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..784e8fa48234f4f64b6922a6758f254ee0ca08ec GIT binary patch literal 537 zcmV+!0_OdRP)x(K@^6+>g^d@v4;gkbWsEoXE%32*i1tcpTNXd5CcIl)ECgqz|2rE6EW}s7R?kl za1q`0GCkMruC6-2LANtwVlsgzsp4?{@7$`KBv!G66>Vie3h?3OmEEkjwdLG0PgLVi z`!N((f$A@n17Ldj#`};0I3@iHJ5M{#IZz|UIYRm4(!uV7eYIYIwQf&}_2J~}>pQ^n z6o8--^T(=hkBNQ_k{-_GWE;FMW7!p}f{NG3nHZ{D5<3d8&tLh%a4AqqnjMkr3m&fkMdECD3N5}Unig5wy40;>lo4j~k+e}v)` zR6)J8Mk*u=SpB`p6o)7j?S0T@9?bz#m@l>gc*zk__|*!FMcHwP!gwLJvS~9c0px8E zW$5-D+}(3*HHCzGV^ zFD^Y_Vnd{svw6x7SJXXNR(YY^mKZIU%1xiFZ@<5==;6wm3sv?6wOng)e!g|WgT*Be zmXtqQ-FUg)8NZg>eZjAG&wRY9;qmImCmXx2b$H`f|8RQJn}Z8qY@hUU_sqM~6Y(ns z%060<_wM+Lw}%!#UQ$X>F;Ky?<(2PGtbMVeofySHHLq4TyjW2~q++157mHhoS4<<7 E0J%Q=@Bjb+ literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/next.png b/rosapps/smartpdf/src/icons-silk/next.png new file mode 100644 index 0000000000000000000000000000000000000000..e252606d3e68c6da135a9b165996d9da968ef7fc GIT binary patch literal 395 zcmV;60d)R}P)IO8de(|Ml<%@O-40!dwX61{2C5s-llVw2V@@N0oo_PPieZ!0Y2~+R( zk!(QTf=B;X9DnzJ@u9c>OP4(U@7{849!UlyO@H`*;lVfmCvAW6f9CF&{}ZR*{jXDW zb_vl21ozzrYJBy-Vb$aRjjJF3@7nm}zjw#A|58cE9uZ}LbIY~=6ShA8U$XeY|MDdd zfQCH!?_7WRzhvaG%|sbsT7Kz&`}!yUix%Do#>T_{_Ei`DO9UTSBkH=Hg(w4*^UnUS zTk-IJ<+2C=ZObqG7Z2FGlB7VCN;>(!bn*TFHYMl(i+Sx`L~=ArL>~EXU3lidsO!!J pWF;gqzXSh89JkLNxXeT<1_12n>%V}Y6R`jQ002ovPDHLkV1iLCz99er literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/previous.bmp b/rosapps/smartpdf/src/icons-silk/previous.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4b8a70397eaa0ba589492546c1e9aa6b35e3ccd7 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C76%bR+z<>C_|Ncv0MQm>A>wU65^uQOQkY2fC$r6O zO-hDaAf4aH*!IJVj zv(g_ft2!1ViC_JLx!EsvOntn%@&3Z1$7`EUrb^>i50rhdpz!7HnNQcZJ=@fKzDSFp zdZ2>GOG<%SUhJHDrN)XF^*}XGmsP#mJL_h<7m@0L${tQnzB?h3c=bS)k7pE;q@Hrc E09;u1X8-^I literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/previous.png b/rosapps/smartpdf/src/icons-silk/previous.png new file mode 100644 index 0000000000000000000000000000000000000000..18f9cc10948f025fde708328fa704b520161e5f6 GIT binary patch literal 389 zcmV;00eb$4P)K{b{Xc8(tN&i@ zH%T)fYQpV#rAr?FpSkE_eXe+_wJd|K3f{{%aMTC(eL? z&YO?2=RWv9b;pbUjjJF3FIss2fAiYM|D{t;5@!?n%vQ}6um-u(1``H~0!(`ViJ zU$yMvf616*#2KJfaGFIu@9Y|n)@%Q3RzCcnHskjH!iD$#iw7MbEf6JRj;ypTzwkeA z{@wqXv+w*Db>B;RG>UocU1Xkp@_*9QTmMBIcK#^msfbTI z9jQ^EwMRD5xNEm*sJPjH^k)@gXT@kl5ii6#6jNXX`Yb0kVgq(zut?ZfbRr+DS= z>q{33dTpWN$tl6c7nxE)4Qur1GCxuUnp5Y z5HK(>u&W4&EXz<>UtfnPivJ`O3Zb4K8yl-}7K;Uh5XR!-B2uXo6E#Dr&Ck!D<$0b5 zXEK?PNF*3;w;Rc15`MqGDN4rSaGd2kJ3GNmOiaM%^D*ppJL2&;mX?;95{t!PwOY^e z?d|R0=pOKTy$qMj1$rk8qtS@b(NQ*LUtb@(y1JlNtJzsS-`3U!Ze(Pn>hXBkfzr6} z{3Vv(2AlG1;RQN6I#_mYZVs)jt>6p>!_3go(6&ye1Mdo>SRyz&A^1T#%t=UROW6Bf zz^9CeqErU&3`3<-Da~6HQ^UW&yCT)$Cu literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/rotate_anticlock.png b/rosapps/smartpdf/src/icons-silk/rotate_anticlock.png new file mode 100644 index 0000000000000000000000000000000000000000..46c75aa859671e2d1366f2aed7f5792b371091f1 GIT binary patch literal 608 zcmV-m0-ybfP)*nn(6-Ko08>y5Bipj zFuyiPrdN8pDqvvkw%oSbD|$YUB3aMBizpn!0@bH?0kAfUJ+m=Vt{!e1UD z_AQ7AnZ&Yq3oU^QbQ$1o#v~>3AqYSCl3VwJuGp2*ve%Mr?A16`oZg&5Nc6*_Q~a<`f+n=r+3NUh>M=H*cV_-chG}N7Vspn9Y`Se z0C&>eX!bRrM=;=eq7!GFC$R4w=n|A@e`7&l%LDhi6W$FLp7k-fKe@oJG0^dCs2ftC zB0v*S$*EwIXr4EM`7n&hl5iB`A4lL?b)cQ2aNKqjRZp2DO_QVx^`6pHR5;7E zlj%-cQ51!F4&J~xM61?D4NeiKN{NVy6X-Qqxk8=MfEX_jL}^8BK|~N7FhJC_i5-lo zIHJodz)CX1Y{)@S~!d8q1l+bMV!}{YL?7wC( z%edaW=F&F+ z($9?`K8YY%uR)_%0MQCxd3ndPa;Y~P?U+0ni$XZM7r6Hug|3%ZMP*Zkl*~_HJgCLk zA%$#B#@zrWY4GPt5fc}9icOq|ZdVP>t`f>G-FQBfO2-8VoE7L?C-B-QL8&<(Elc$< z9F9VNpaHd~Mzw{9XMM@!tpI_e9I`cn>D7RVpdQ8}3WkFbsCW7qu?h_iA<}x2LUHGS zH_L_8E5^i;Hs-n?bM4!dqv}ItRGh3xVBa~)+_!mXcGsfbDMZdlCbCp%NFPW!OYKP{ oAG`}3ZPvAC_|NbkKk~?3=h3h;sB$}gWf0lGmOZsw zuh(zA7B=y4diH+&S|a)m_8+~!;PUgy#~&olJ{cFX6it14^D)1+{k|>x3@S~v3k}q= zwH9A}vGn@OhTXRuQ`RCYF6cg+zu?re!}lJ&{sKhi&33hinsiExW}bQ6d*q&f^B!cy z#S_jiK63Bh@1K8ueD^jXiZh30!@$TT+QF>*@n)!Ojio18-C|h;$@9&?#zrO$V z+@?MirkbOvN|qzd)d^B z^ODzO+jhGE-G;0_Y1!E)@4x-}{N~rES0Dt|6}C2h?$u>Lw*mbE3;|^I$t%u3eg7S# z?9)rQmY8kn;TsZxZUd?h>^gv~K4m%7v+TE=2L@ zAc44q=tejYU5HLZGooZ=NXsV%)bU*sTokj@jZSo^9&w{ke7#VNQ*1zG!rIRk_@ zCqOr;g6B6CM1oPv1(~U4k@Gd+5tN0(j@GA*K*busv3Lb0UyXuowiRkTRZ#85JN!eC z_8ZVW>+upx5C#N|BTv2dK_EW@%(@F6yu1sZv>T3gm&*mIkvej1R4=RyYw#mS zx}c)#2z<)=VQ1|=ux>5PwjVE+J!Q84EQyG-j9SFYV*6AQj$Gb(7!KJE!k5iQ@O3K$ z@0NQZ)>b7&TaFd~Ciolk*Q(7cL+9cB`Y;G@rr`tk5Hdjv+))zSdlF#gI!>6`zB<@i zaKYP!9!Pl&5VMjydlq1x&}37{RQY+SSBXX-w?kCLKK%bXFYU6{?d+nH00000NkvXX Hu0mjfTSP*+ literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/zoom_out.bmp b/rosapps/smartpdf/src/icons-silk/zoom_out.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a40e8e294a1675a04433a61626d0b60a5ae392a7 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C76%bR+z<>C_|NbkKQfM4>d~;%yLdBxWf0lGmOZsw zuh(zA7B=y4P}Vm5S|a)m_8+~!;PUgy#~&olJ{cFX6it14^D)1+{k|>xqU-kiH12NS ze|z!O7fY|dY}kFvF=g#v(SLCD1>I-!7o1vl_}-(}Uw~-IzB|Fa2P?N+n|bDO?~!}{ z&3lj)7f(39_{hC~zkmMu@i{5^S6Ik*57#eNrXTgx-YHAHkr8|aHx|g~-g%>J)y2QR zfBydZ{@0f`x%q$gpZKx;!1s0AzAah(W%h#4KrP7XGnSuSbLPpP?;n4Cehow=75{)* z&}>0gpS0}kllR|#eSY)n(<=}H>jH7VyaCz>^b0Tqkku!zIREthcaXAAFVVF8{`wB6 zKCtTmvih90m)2c;_WRq1pC4cR1Ze^50^9QE`={kc?q{@}KvqBT(B0Z?*Z=+kS%Itt zXgDws3YVNkRt#a+F1WGs{8OM7P!NH=@cY|GpyI_x?-%u+!&DCx0cxq;etrGLXHP$T m2YP?axhLgoFO^QZh*dFMuyVoGv=!%5mYpk|eHkuDAp-z^-Xj_S literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/icons-silk/zoom_out.png b/rosapps/smartpdf/src/icons-silk/zoom_out.png new file mode 100644 index 0000000000000000000000000000000000000000..07bf98a79cfea526e250703356dbefdb6b80d166 GIT binary patch literal 708 zcmV;#0z3VQP)TNkCP1&*^7LC~A?iZQEu_hKZoQoXI zA7tfTv}|~Fb8b^XuP>qvDk=)P)vYKtT12;}bKn-mwHWl`1Bb)&{XXC4IY$Nnvj5@N zfekg1Y}gcI!)Cq|u?lR+A{2&=d~S$}&0ei1|7pO6jkZ$6%&{R8TNpk>=dV#j&aWqO zgE~4pNU_-giktFkY-J5_XDlv`7+j?n3mXtxgadILp+c<9cr~t!x1LM6m69Z~V#pLL z22Cs~BoIdtZHTjo7Q|_U0a2OmSF=gCGFB$RVZIP(pixmBqE!^15yd!#9Z{Wh)zB%o zikBFa!WJPvMB(noe(U;k1e~Y|r$}@wh*Ymykd6>E3t69z5DT&Jq-fSG-dPdU{SG;i zbSb3<`RfKgJD|lQC`6(Cdut1PbDV&$M=Y?U)x)A(0iQN+gAeOBg2Z6fr$_Is!%M70 z=n*z7{*s%3rO7yazIO)}qa&~o@WZ=R>!b#mOSR zlCR8M*iRy2j7!PmWiiegA>Og~W1?FLk0*NI^}`$RW +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_DIRENT_H +#include +#endif + +extern void PreviewBitmapInit(void); +extern void PreviewBitmapDestroy(void); +extern void PreviewBitmapSplashFitz(RenderedBitmap *bmpSplash, RenderedBitmap *bmpFitz); +extern "C" char *GetPasswordForFile(WindowInfo *win, const char *fileName); + +char *GetPasswordForFile(WindowInfo *win, const char *fileName) +{ + return strdup(""); +} + +static void PreviewBitmapFitz(RenderedBitmap *bmpFitz) +{ + PreviewBitmapSplashFitz(NULL, bmpFitz); +} + +static void PreviewBitmapSplash(RenderedBitmap *bmpSplash) +{ + PreviewBitmapSplashFitz(bmpSplash, NULL); +} + +class RGBAImageFitz : public RGBAImage +{ +public: + RGBAImageFitz(fz_pixmap *bmp) { + m_bmp = bmp; +#ifdef FITZ_HEAD + samples = bmp->p; +#else + samples = bmp->samples; +#endif + w = bmp->w; + h = bmp->h; + } + virtual ~RGBAImageFitz() {} + virtual int Get_Width(void) const { return m_bmp->w; } + virtual int Get_Height(void) const { return m_bmp->h; } + virtual unsigned char Get_Red(unsigned int i) { return samples[i*4]; } + virtual unsigned char Get_Green(unsigned int i) { return samples[i*4+1]; } + virtual unsigned char Get_Blue(unsigned int i) { return samples[i*4+2]; } +// virtual unsigned char Get_Alpha(unsigned int i) { return samples[i*4+3]; } + virtual unsigned char Get_Alpha(unsigned int i) { return 0; } + virtual void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i) { /* no-op */ } + virtual unsigned int Get(int i) const { + unsigned int *data = (unsigned int *)samples; + return samples[i]; + } +private: + fz_pixmap * m_bmp; + fz_sample * samples; + int w; + int h; +}; + +class RGBAImageSplash : public RGBAImage +{ +public: + RGBAImageSplash(SplashBitmap *bmp) { + m_bmp = bmp; + assert(splashModeBGR8 == m_bmp->getMode()); + rowSize = m_bmp->getRowSize(); + assert(rowSize > 0); + } + virtual ~RGBAImageSplash() {} + virtual int Get_Width(void) const { return m_bmp->getWidth(); } + virtual int Get_Height(void) const { return m_bmp->getHeight(); } + virtual unsigned char Get_Red(unsigned int i) { + SplashColor p; + int x = i % rowSize; + int y = i / rowSize; + m_bmp->getPixel(x, y, p); + return splashBGR8R(p); + } + virtual unsigned char Get_Green(unsigned int i) { + SplashColor p; + int x = i % rowSize; + int y = i / rowSize; + m_bmp->getPixel(x, y, p); + return splashBGR8G(p); + } + virtual unsigned char Get_Blue(unsigned int i) { + SplashColor p; + int x = i % rowSize; + int y = i / rowSize; + m_bmp->getPixel(x, y, p); + return splashBGR8B(p); + } + virtual unsigned char Get_Alpha(unsigned int i) { return 0; } + virtual void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i) { /* no-op */ } + virtual unsigned int Get(int i) const { + SplashColor p; + int x = i % rowSize; + int y = i / rowSize; + m_bmp->getPixel(x, y, p); + return p[0] + ((unsigned int)p[1] >> 8) + ((unsigned int)p[2] >> 16); + } +private: + SplashBitmap * m_bmp; + int rowSize; +}; + +#define PDF_FILE_DPI 72 + +#define MAX_FILENAME_SIZE 1024 + +struct FindFileState { + char path[MAX_FILENAME_SIZE]; + char dirpath[MAX_FILENAME_SIZE]; /* current dir path */ + char pattern[MAX_FILENAME_SIZE]; /* search pattern */ + const char *bufptr; +#ifdef WIN32 + WIN32_FIND_DATA fileinfo; + HANDLE dir; +#else + DIR *dir; +#endif +}; + +#ifdef WIN32 +#include +#include +#include + +__inline char *getcwd(char *buffer, int maxlen) +{ + return _getcwd(buffer, maxlen); +} + +int fnmatch(const char *pattern, const char *string, int flags) +{ + int prefix_len; + const char *star_pos = strchr(pattern, '*'); + if (!star_pos) + return strcmp(pattern, string) != 0; + + prefix_len = (int)(star_pos-pattern); + if (0 == prefix_len) + return 0; + + if (0 == _strnicmp(pattern, string, prefix_len)) + return 0; + + return 1; +} + +#else +#include +#endif + +#ifdef WIN32 +/* on windows to query dirs we need foo\* to get files in this directory. + foo\ always fails and foo will return just info about foo directory, + not files in this directory */ +static void win_correct_path_for_FindFirstFile(char *path, int path_max_len) +{ + int path_len = strlen(path); + if (path_len >= path_max_len-4) + return; + if (DIR_SEP_CHAR != path[path_len]) + path[path_len++] = DIR_SEP_CHAR; + path[path_len++] = '*'; + path[path_len] = 0; +} +#endif + +FindFileState *find_file_open(const char *path, const char *pattern) +{ + FindFileState *s; + + s = (FindFileState*)malloc(sizeof(FindFileState)); + if (!s) + return NULL; + strcpy_s(s->path, sizeof(s->path), path); + strcpy_s(s->dirpath, sizeof(s->path), path); +#ifdef WIN32 + win_correct_path_for_FindFirstFile(s->path, sizeof(s->path)); +#endif + strcpy_s(s->pattern, sizeof(s->pattern), pattern); + s->bufptr = s->path; +#ifdef WIN32 + s->dir = INVALID_HANDLE_VALUE; +#else + s->dir = NULL; +#endif + return s; +} + +#if 0 /* re-enable if we #define USE_OWN_GET_AUTH_DATA */ +void *StandardSecurityHandler::getAuthData() +{ + return NULL; +} +#endif + +char *makepath(char *buf, int buf_size, const char *path, + const char *filename) +{ + strcpy_s(buf, buf_size, path); + int len = strlen(path); + if (len > 0 && path[len - 1] != DIR_SEP_CHAR && len + 1 < buf_size) { + buf[len++] = DIR_SEP_CHAR; + buf[len] = '\0'; + } + strcat_s(buf, buf_size, filename); + return buf; +} + +#ifdef WIN32 +static int skip_matching_file(const char *filename) +{ + if (0 == strcmp(".", filename)) + return 1; + if (0 == strcmp("..", filename)) + return 1; + return 0; +} +#endif + +int find_file_next(FindFileState *s, char *filename, int filename_size_max) +{ +#ifdef WIN32 + int fFound; + if (INVALID_HANDLE_VALUE == s->dir) { + s->dir = FindFirstFile(s->path, &(s->fileinfo)); + if (INVALID_HANDLE_VALUE == s->dir) + return -1; + goto CheckFile; + } + + while (1) { + fFound = FindNextFile(s->dir, &(s->fileinfo)); + if (!fFound) + return -1; +CheckFile: + if (skip_matching_file(s->fileinfo.cFileName)) + continue; + if (0 == fnmatch(s->pattern, s->fileinfo.cFileName, 0) ) { + makepath(filename, filename_size_max, s->dirpath, s->fileinfo.cFileName); + return 0; + } + } +#else + struct dirent *dirent; + const char *p; + char *q; + + if (s->dir == NULL) + goto redo; + + for (;;) { + dirent = readdir(s->dir); + if (dirent == NULL) { + redo: + if (s->dir) { + closedir(s->dir); + s->dir = NULL; + } + p = s->bufptr; + if (*p == '\0') + return -1; + /* CG: get_str(&p, s->dirpath, sizeof(s->dirpath), ":") */ + q = s->dirpath; + while (*p != ':' && *p != '\0') { + if ((q - s->dirpath) < (int)sizeof(s->dirpath) - 1) + *q++ = *p; + p++; + } + *q = '\0'; + if (*p == ':') + p++; + s->bufptr = p; + s->dir = opendir(s->dirpath); + if (!s->dir) + goto redo; + } else { + if (fnmatch(s->pattern, dirent->d_name, 0) == 0) { + makepath(filename, filename_size_max, + s->dirpath, dirent->d_name); + return 0; + } + } + } +#endif +} + +void find_file_close(FindFileState *s) +{ +#ifdef WIN32 + if (INVALID_HANDLE_VALUE != s->dir) + FindClose(s->dir); +#else + if (s->dir) + closedir(s->dir); +#endif + free(s); +} + +typedef struct StrList { + struct StrList *next; + char * str; +} StrList; + +/* List of all command-line arguments that are not switches. + We assume those are: + - names of PDF files + - names of a file with a list of PDF files + - names of directories with PDF files +*/ +static StrList *gArgsListRoot = NULL; + +/* Names of all command-line switches we recognize */ +#define TIMINGS_ARG "-timings" +#define RESOLUTION_ARG "-resolution" +#define RECURSIVE_ARG "-recursive" +#define OUT_ARG "-out" +#define PREVIEW_ARG "-preview" +#define SLOW_PREVIEW_ARG "-slowpreview" +#define LOAD_ONLY_ARG "-loadonly" +#define PAGE_ARG "-page" +#define DUMP_LINKS_ARG "-links" +#define TEXT_ARG "-text" +#define FITZ_ARG "-fitz" +#define BOTH_ARG "-both" +#define PDIFF_ARG "-pdiff" + +/* Should we record timings? True if -timings command-line argument was given. */ +static BOOL gfTimings = FALSE; + +/* If true, we use render each page at resolution 'gResolutionX'/'gResolutionY'. + If false, we render each page at its native resolution. + True if -resolution NxM command-line argument was given. */ +static BOOL gfForceResolution = FALSE; +static int gResolutionX = 0; +static int gResolutionY = 0; +/* If NULL, we output the log info to stdout. If not NULL, should be a name + of the file to which we output log info. + Controled by -out command-line argument. */ +static char * gOutFileName = NULL; +/* FILE * correspondig to gOutFileName or stdout if gOutFileName is NULL or + was invalid name */ +static FILE * gOutFile = NULL; +/* FILE * correspondig to gOutFileName or stderr if gOutFileName is NULL or + was invalid name */ +static FILE * gErrFile = NULL; + +/* If True and a directory is given as a command-line argument, we'll process + pdf files in sub-directories as well. + Controlled by -recursive command-line argument */ +static BOOL gfRecursive = FALSE; + +/* If true, preview rendered image. To make sure that they're being rendered correctly. */ +static BOOL gfPreview = FALSE; + +/* If true and rendering both, checks images for visual differences */ +static BOOL gfPDiff = FALSE; + +/* 1 second (1000 milliseconds) */ +#define SLOW_PREVIEW_TIME 1000 + +/* If true, preview rendered image in a slow mode i.e. delay displaying for + SLOW_PREVIEW_TIME. This is so that a human has enough time to see if the + PDF renders ok. In release mode on fast processor pages take only ~100-200 ms + to render and they go away too quickly to be inspected by a human. */ +static int gfSlowPreview = FALSE; + +/* If true, we only dump the text, not render */ +static int gfTextOnly = FALSE; + +/* If true, using fitz (instead of poppler) for rendering */ +static int gfFitzRendering = FALSE; + +#define PAGE_NO_NOT_GIVEN -1 + +/* If equals PAGE_NO_NOT_GIVEN, we're in default mode where we render all pages. + If different, will only render this page */ +static int gPageNo = PAGE_NO_NOT_GIVEN; +/* If true, will only load the file, not render any pages. Mostly for + profiling load time */ +static BOOL gfLoadOnly = FALSE; + +/* if TRUE, will dump information about links */ +static BOOL gfLinks = FALSE; + +/* if TRUE, will timer, render and preview both fitz and poppler backends */ +static BOOL gfBoth = FALSE; + +int StrList_Len(StrList **root) +{ + int len = 0; + StrList * cur; + assert(root); + if (!root) + return 0; + cur = *root; + while (cur) { + ++len; + cur = cur->next; + } + return len; +} + +int StrList_InsertAndOwn(StrList **root, char *txt) +{ + StrList * el; + assert(root && txt); + if (!root || !txt) + return FALSE; + + el = (StrList*)malloc(sizeof(StrList)); + if (!el) + return FALSE; + el->str = txt; + el->next = *root; + *root = el; + return TRUE; +} + +int StrList_Insert(StrList **root, char *txt) +{ + char *txtDup; + + assert(root && txt); + if (!root || !txt) + return FALSE; + txtDup = str_dup(txt); + if (!txtDup) + return FALSE; + + if (!StrList_InsertAndOwn(root, txtDup)) { + free((void*)txtDup); + return FALSE; + } + return TRUE; +} + +StrList* StrList_RemoveHead(StrList **root) +{ + StrList *tmp; + assert(root); + if (!root) + return NULL; + + if (!*root) + return NULL; + tmp = *root; + *root = tmp->next; + tmp->next = NULL; + return tmp; +} + +void StrList_FreeElement(StrList *el) +{ + if (!el) + return; + free((void*)el->str); + free((void*)el); +} + +void StrList_Destroy(StrList **root) +{ + StrList * cur; + StrList * next; + + if (!root) + return; + cur = *root; + while (cur) { + next = cur->next; + StrList_FreeElement(cur); + cur = next; + } + *root = NULL; +} + +#ifndef WIN32 +void OutputDebugString(const char *txt) +{ + /* do nothing */ +} +#define _snprintf snprintf +#define _vsnprintf vsnprintf +#endif + +void CDECL error(int pos, char *msg, ...) { + va_list args; + char buf[4096], *p = buf; + + // NB: this can be called before the globalParams object is created + if (globalParams && globalParams->getErrQuiet()) { + return; + } + + if (pos >= 0) { + p += _snprintf(p, sizeof(buf)-1, "Error (%d): ", pos); + *p = '\0'; + OutputDebugString(p); + } else { + OutputDebugString("Error: "); + } + + p = buf; + va_start(args, msg); + p += _vsnprintf(p, sizeof(buf) - 1, msg, args); + while ( p > buf && isspace(p[-1]) ) + *--p = '\0'; + *p++ = '\r'; + *p++ = '\n'; + *p = '\0'; + OutputDebugString(buf); + va_end(args); + + if (pos >= 0) { + p += _snprintf(p, sizeof(buf)-1, "Error (%d): ", pos); + *p = '\0'; + OutputDebugString(buf); + if (gErrFile) + fprintf(gErrFile, buf); + } else { + OutputDebugString("Error: "); + if (gErrFile) + fprintf(gErrFile, "Error: "); + } + + p = buf; + va_start(args, msg); + p += _vsnprintf(p, sizeof(buf) - 3, msg, args); + while ( p > buf && isspace(p[-1]) ) + *--p = '\0'; + *p++ = '\r'; + *p++ = '\n'; + *p = '\0'; + OutputDebugString(buf); + if (gErrFile) + fprintf(gErrFile, buf); + va_end(args); +} + +void LogInfo(char *fmt, ...) +{ + va_list args; + char buf[4096], *p = buf; + + p = buf; + va_start(args, fmt); + p += _vsnprintf(p, sizeof(buf) - 1, fmt, args); + *p = '\0'; + fprintf(gOutFile, buf); + va_end(args); + fflush(gOutFile); +} + +static void printUsageAndExit(int argc, char **argv) +{ + printf("Usage: pdftest [-preview] [-slowpreview] [-timings] [-text] [-resolution NxM] [-recursive] [-page N] [-out out.txt] pdf-files-to-process\n"); + for (int i=0; i < argc; i++) { + printf("i=%d, '%s'\n", i, argv[i]); + } + exit(0); +} + +void *StandardSecurityHandler::getAuthData() +{ + return NULL; +} + +static int ShowPreview(void) +{ + if (gfPreview || gfSlowPreview) + return TRUE; + return FALSE; +} + +static int DoPDiff(void) +{ + return gfPDiff; +} + +static void DumpLinks(int pageNo, PdfEngine *engine) +{ + assert(engine); + if (!engine) return; + int linkCount = engine->linkCount(pageNo); + for (int linkNo = 0; linkNo < linkCount; ++linkNo) { + const char *linkType = engine->linkType(pageNo, linkNo); + LogInfo("Link: page %d, type=%s\n", pageNo, linkType); + } +} + +static void renderPdfAsText(const char *fileName) +{ + GooString * fileNameStr = NULL; + PDFDoc * pdfDoc = NULL; + GooString * txt = NULL; + + assert(fileName); + if (!fileName) + return; + + LogInfo("started: %s\n", fileName); + + TextOutputDev * textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); + if (!textOut->isOk()) { + delete textOut; + return; + } + + MsTimer msTimer; + /* note: don't delete fileNameStr since PDFDoc takes ownership and deletes them itself */ + fileNameStr = new GooString(fileName); + if (!fileNameStr) + goto Exit; + + pdfDoc = new PDFDoc(fileNameStr, NULL, NULL, NULL); + if (!pdfDoc->isOk()) { + error(-1, "renderPdfFile(): failed to open PDF file %s\n", fileName); + goto Exit; + } + + msTimer.stop(); + double timeInMs = msTimer.timeInMs(); + LogInfo("load: %.2f ms\n", timeInMs); + + int pageCount = pdfDoc->getNumPages(); + LogInfo("page count: %d\n", pageCount); + + for (int curPage = 1; curPage <= pageCount; curPage++) { + if ((gPageNo != PAGE_NO_NOT_GIVEN) && (gPageNo != curPage)) + continue; + + msTimer.start(); + int rotate = 0; + GBool useMediaBox = gFalse; + GBool crop = gTrue; + GBool doLinks = gFalse; + pdfDoc->displayPage(textOut, curPage, 72, 72, rotate, useMediaBox, crop, doLinks); + txt = textOut->getText(0.0, 0.0, 10000.0, 10000.0); + msTimer.stop(); + timeInMs = msTimer.timeInMs(); + if (gfTimings) + LogInfo("page %d: %.2f ms\n", curPage, timeInMs); + printf("%s\n", txt->getCString()); + delete txt; + txt = NULL; + } + +Exit: + LogInfo("finished: %s\n", fileName); + delete textOut; + delete pdfDoc; +} + +extern "C" fz_error *initfontlibs_ms(void); + +#define FITZ_TMP_NAME "c:\\fitz_tmp.pdf" +#define POPPLER_TMP_NAME "c:\\poppler_tmp.pdf" + +#if 0 +void SplashRender::RenderPage(int pageNo) +{ + pageDx = (int)pdfEngine->pdfDoc()->getPageCropWidth(pageNo); + pageDy = (int)pdfEngine->pdfDoc()->getPageCropHeight(pageNo); + + renderDx = pageDx; + renderDy = pageDy; + if (gfForceResolution) { + renderDx = gResolutionX; + renderDy = gResolutionY; + } + rotate = 0; + useMediaBox = gFalse; + crop = gTrue; + doLinks = gTrue; + scaleX = 1.0; + scaleY = 1.0; + if (pageDx != renderDx) + scaleX = (double)renderDx / (double)pageDx; + if (pageDy != renderDy) + scaleY = (double)renderDy / (double)pageDy; + hDPI = (double)PDF_FILE_DPI * scaleX; + vDPI = (double)PDF_FILE_DPI * scaleY; + pdfEngine->pdfDoc()->displayPage(outputDevice, pageNo, hDPI, vDPI, rotate, useMediaBox, crop, doLinks); + FreePage(); +} +#endif + +enum RenderType { + renderFitz, + renderSplash, + renderBoth +}; + +static void renderPdf(const char *fileName, RenderType renderType) +{ + const char *fileNameFitz = NULL; + PdfEngine * engineFitz = NULL; + int pageCountFitz; + + const char *fileNameSplash = NULL; + PdfEngine * engineSplash = NULL; + int pageCountSplash; + + switch (renderType) { + case renderBoth: + // TODO: fails if file already exists and has read-only attribute + CopyFile(fileName, FITZ_TMP_NAME, FALSE); + CopyFile(fileName, POPPLER_TMP_NAME, FALSE); + fileNameSplash = POPPLER_TMP_NAME; + fileNameFitz = FITZ_TMP_NAME; + break; + case renderFitz: + fileNameFitz = fileName; + break; + case renderSplash: + fileNameSplash = fileName; + break; + } + + LogInfo("started: %s\n", fileName); + initfontlibs_ms(); + + if (fileNameFitz) { + engineFitz = new PdfEngineFitz(); + + MsTimer msTimer; + if (!engineFitz->load(fileNameFitz, NULL)) { + LogInfo("failed to load fitz\n"); + goto Error; + } + msTimer.stop(); + double timeInMs = msTimer.timeInMs(); + LogInfo("load fitz : %.2f ms\n", timeInMs); + pageCountFitz = engineFitz->pageCount(); + } + + if (fileNameSplash) { + engineSplash = new PdfEnginePoppler(); + + MsTimer msTimer; + if (!engineSplash->load(fileNameSplash, NULL)) { + LogInfo("failed to load splash\n"); + goto Error; + } + msTimer.stop(); + double timeInMs = msTimer.timeInMs(); + LogInfo("load splash: %.2f ms\n", timeInMs); + pageCountSplash = engineSplash->pageCount(); + } + + int pageCount; + switch (renderType) { + case renderBoth: + pageCount = pageCountFitz; + if (pageCountSplash < pageCount) + pageCount = pageCountSplash; + break; + case renderFitz: + pageCount = pageCountFitz; + break; + case renderSplash: + pageCount = pageCountSplash; + break; + } + LogInfo("page count: %d\n", pageCount); + + for (int curPage = 1; curPage <= pageCount; curPage++) { + if ((gPageNo != PAGE_NO_NOT_GIVEN) && (gPageNo != curPage)) + continue; + + RenderedBitmap *bmpFitz = NULL; + RenderedBitmap *bmpSplash = NULL; + + if (fileNameFitz) { + MsTimer msTimer; + bmpFitz = engineFitz->renderBitmap(curPage, 100.0, 0, NULL, NULL); + msTimer.stop(); + double timeInMs = msTimer.timeInMs(); + + if (gfTimings) + if (!bmpFitz) + LogInfo("page fitz %d: failed to render\n", curPage); + else + LogInfo("page fitz %d (%dx%d): %.2f ms\n", curPage, bmpFitz->dx(), bmpFitz->dy(), timeInMs); + if (gfLinks) + DumpLinks(curPage, engineFitz); + } + + if (fileNameSplash) { + MsTimer msTimer; + bmpSplash = engineSplash->renderBitmap(curPage, 100.0, 0, NULL, NULL); + msTimer.stop(); + double timeInMs = msTimer.timeInMs(); + if (gfTimings) + if (!bmpSplash) + LogInfo("page splash %d: failed to render\n", curPage); + else + LogInfo("page splash %d (%dx%d): %.2f ms\n", curPage, bmpSplash->dx(), bmpSplash->dy(), timeInMs); + if (gfLinks) + DumpLinks(curPage, engineSplash); + } + + if (ShowPreview()) { + PreviewBitmapSplashFitz(bmpSplash, bmpFitz); + if (gfSlowPreview) + sleep_milliseconds(SLOW_PREVIEW_TIME); + } + +#if 0 + if (DoPDiff()) { + CompareArgs compareArgs; + compareArgs.ImgA = new RGBAImageFitz(renderFitz->image); + compareArgs.ImgB = new RGBAImageSplash(splashBmp); + compareArgs.ImgDiff = NULL; + unsigned long pixelDiffCount = Yee_Compare(compareArgs); + LogInfo("pixels different: %d\n", (int)pixelDiffCount); + } +#endif + } + +Error: + delete engineFitz; + delete engineSplash; + LogInfo("finished: %s\n", fileName); +} + +static void renderFile(const char *fileName) +{ + if (gfTextOnly) { + /* TODO: right not rendering as text is only supported with poppler, not fitz */ + renderPdfAsText(fileName); + return; + } + + RenderType renderType; + if (gfBoth) + renderType = renderBoth; + else { + renderType = renderSplash; + if (gfFitzRendering) + renderType = renderFitz; + } + renderPdf(fileName, renderType); +} + +static int ParseInteger(const char *start, const char *end, int *intOut) +{ + char numBuf[16]; + int digitsCount; + const char * tmp; + + assert(start && end && intOut); + assert(end >= start); + if (!start || !end || !intOut || (start > end)) + return FALSE; + + digitsCount = 0; + tmp = start; + while (tmp <= end) { + if (isspace(*tmp)) { + /* do nothing, we allow whitespace */ + } else if (!isdigit(*tmp)) + return FALSE; + numBuf[digitsCount] = *tmp; + ++digitsCount; + if (digitsCount == dimof(numBuf)-3) /* -3 to be safe */ + return FALSE; + ++tmp; + } + if (0 == digitsCount) + return FALSE; + numBuf[digitsCount] = 0; + *intOut = atoi(numBuf); + return TRUE; +} + +/* Given 'resolutionString' in format NxM (e.g. "100x200"), parse the string and put N + into 'resolutionXOut' and M into 'resolutionYOut'. + Return FALSE if there was an error (e.g. string is not in the right format */ +static int ParseResolutionString(const char *resolutionString, int *resolutionXOut, int *resolutionYOut) +{ + const char * posOfX; + + assert(resolutionString); + assert(resolutionXOut); + assert(resolutionYOut); + if (!resolutionString || !resolutionXOut || !resolutionYOut) + return FALSE; + *resolutionXOut = 0; + *resolutionYOut = 0; + posOfX = strchr(resolutionString, 'X'); + if (!posOfX) + posOfX = strchr(resolutionString, 'x'); + if (!posOfX) + return FALSE; + if (posOfX == resolutionString) + return FALSE; + if (!ParseInteger(resolutionString, posOfX-1, resolutionXOut)) + return FALSE; + if (!ParseInteger(posOfX+1, resolutionString+strlen(resolutionString)-1, resolutionYOut)) + return FALSE; + return TRUE; +} + +#ifdef DEBUG +static void u_ParseResolutionString(void) +{ + int i; + int result, resX, resY; + const char *str; + struct TestData { + const char * str; + int result; + int resX; + int resY; + } testData[] = { + { "", FALSE, 0, 0 }, + { "abc", FALSE, 0, 0}, + { "34", FALSE, 0, 0}, + { "0x0", TRUE, 0, 0}, + { "0x1", TRUE, 0, 1}, + { "0xab", FALSE, 0, 0}, + { "1x0", TRUE, 1, 0}, + { "100x200", TRUE, 100, 200}, + { "58x58", TRUE, 58, 58}, + { " 58x58", TRUE, 58, 58}, + { "58x 58", TRUE, 58, 58}, + { "58x58 ", TRUE, 58, 58}, + { " 58 x 58 ", TRUE, 58, 58}, + { "34x1234a", FALSE, 0, 0}, + { NULL, FALSE, 0, 0} + }; + for (i=0; NULL != testData[i].str; i++) { + str = testData[i].str; + result = ParseResolutionString(str, &resX, &resY); + assert(result == testData[i].result); + if (result) { + assert(resX == testData[i].resX); + assert(resY == testData[i].resY); + } + } +} +#endif + +static void runAllUnitTests(void) +{ +#ifdef DEBUG + u_ParseResolutionString(); +#endif +} + +static void parseCommandLine(int argc, char **argv) +{ + char * arg; + + if (argc < 2) + printUsageAndExit(argc, argv); + + for (int i=1; i < argc; i++) { + arg = argv[i]; + assert(arg); + if ('-' == arg[0]) { + if (str_ieq(arg, TIMINGS_ARG)) { + gfTimings = TRUE; + } else if (str_ieq(arg, RESOLUTION_ARG)) { + ++i; + if (i == argc) + printUsageAndExit(argc, argv); /* expect a file name after that */ + if (!ParseResolutionString(argv[i], &gResolutionX, &gResolutionY)) + printUsageAndExit(argc, argv); + gfForceResolution = TRUE; + } else if (str_ieq(arg, RECURSIVE_ARG)) { + gfRecursive = TRUE; + } else if (str_ieq(arg, OUT_ARG)) { + /* expect a file name after that */ + ++i; + if (i == argc) + printUsageAndExit(argc, argv); + gOutFileName = str_dup(argv[i]); + } else if (str_ieq(arg, PREVIEW_ARG)) { + gfPreview = TRUE; + } else if (str_ieq(arg, TEXT_ARG)) { + gfTextOnly = TRUE; + } else if (str_ieq(arg, SLOW_PREVIEW_ARG)) { + gfSlowPreview = TRUE; + } else if (str_ieq(arg, LOAD_ONLY_ARG)) { + gfLoadOnly = TRUE; + } else if (str_ieq(arg, FITZ_ARG)) { + gfFitzRendering = TRUE; + } else if (str_ieq(arg, BOTH_ARG)) { + gfBoth = TRUE; + } else if (str_ieq(arg, PDIFF_ARG)) { + gfPDiff = TRUE; + } else if (str_ieq(arg, PAGE_ARG)) { + /* expect an integer after that */ + ++i; + if (i == argc) + printUsageAndExit(argc, argv); + gPageNo = atoi(argv[i]); + if (gPageNo < 1) + printUsageAndExit(argc, argv); + } else if (str_ieq(arg, DUMP_LINKS_ARG)) { + gfLinks = TRUE; + } else { + /* unknown option */ + printUsageAndExit(argc, argv); + } + } else { + /* we assume that this is not an option hence it must be + a name of PDF/directory/file with PDF names */ + StrList_Insert(&gArgsListRoot, arg); + } + } +} + +void renderFileList(char *pdfFileList) +{ + char *data = NULL; + char *dataNormalized = NULL; + char *pdfFileName; + size_t fileSize; + + assert(pdfFileList); + if (!pdfFileList) + return; + data = file_read_all(pdfFileList, &fileSize); + if (!data) { + error(-1, "couldn't load file '%s'", pdfFileList); + return; + } + dataNormalized = str_normalize_newline(data, UNIX_NEWLINE); + if (!dataNormalized) { + error(-1, "couldn't normalize data of file '%s'", pdfFileList); + goto Exit; + } + for (;;) { + pdfFileName = str_split_iter(&dataNormalized, UNIX_NEWLINE_C); + if (!pdfFileName) + break; + str_strip_ws_both(pdfFileName); + if (str_empty(pdfFileName)) { + free((void*)pdfFileName); + continue; + } + renderFile(pdfFileName); + free((void*)pdfFileName); + } +Exit: + free((void*)dataNormalized); + free((void*)data); +} + +#ifdef WIN32 +#include +#include + +int IsDirectoryName(char *path) +{ + struct _stat buf; + int result; + + result = _stat(path, &buf ); + if (0 != result) + return FALSE; + + if (buf.st_mode & _S_IFDIR) + return TRUE; + + return FALSE; +} + +int IsFileName(char *path) +{ + struct _stat buf; + int result; + + result = _stat(path, &buf ); + if (0 != result) + return FALSE; + + if (buf.st_mode & _S_IFREG) + return TRUE; + + return FALSE; +} +#else +int IsDirectoryName(char *path) +{ + /* TODO: implement me */ + return FALSE; +} + +int IsFileName(char *path) +{ + /* TODO: implement me */ + return TRUE; +} +#endif + +int IsPdfFileName(char *path) +{ + if (str_endswith(path, ".pdf")) + return TRUE; + return FALSE; +} + +void renderDirectory(char *path) +{ + FindFileState * ffs; + char filename[MAX_FILENAME_SIZE]; + StrList * dirList = NULL; + StrList * el; + + StrList_Insert(&dirList, path); + + while (0 != StrList_Len(&dirList)) { + el = StrList_RemoveHead(&dirList); + ffs = find_file_open(el->str, "*"); + while (!find_file_next(ffs, filename, sizeof(filename))) { + if (IsDirectoryName(filename)) { + if (gfRecursive) { + StrList_Insert(&dirList, filename); + } + } else if (IsFileName(filename)) { + if (IsPdfFileName(filename)) { + renderFile(filename); + } + } + } + find_file_close(ffs); + StrList_FreeElement(el); + } + StrList_Destroy(&dirList); +} + +/* Render 'cmdLineArg', which can be: + - directory name + - name of PDF file + - name of text file with names of PDF files +*/ +static void renderCmdLineArg(char *cmdLineArg) +{ + assert(cmdLineArg); + if (!cmdLineArg) + return; + if (IsDirectoryName(cmdLineArg)) { + renderDirectory(cmdLineArg); + } else if (IsFileName(cmdLineArg)) { + if (IsPdfFileName(cmdLineArg)) + renderFile(cmdLineArg); + else + renderFileList(cmdLineArg); + } else { + error(-1, "unexpected argument '%s'", cmdLineArg); + } +} + +extern "C" void deinitfontlibs_ms(void); + +extern "C" void dump_type_stats(void); + +int main(int argc, char **argv) +{ + runAllUnitTests(); + + parseCommandLine(argc, argv); + if (0 == StrList_Len(&gArgsListRoot)) + printUsageAndExit(argc, argv); + assert(gArgsListRoot); + + void *leak = malloc(20); + + SplashColorsInit(); + globalParams = new GlobalParams(""); + if (!globalParams) + return 1; + globalParams->setErrQuiet(gFalse); + + FILE * outFile = NULL; + if (gOutFileName) { + outFile = fopen(gOutFileName, "wb"); + if (!outFile) { + printf("failed to open -out file %s\n", gOutFileName); + return 1; + } + gOutFile = outFile; + } + else + gOutFile = stdout; + + if (gOutFileName) + gErrFile = outFile; + else + gErrFile = stderr; + + PreviewBitmapInit(); + + StrList * curr = gArgsListRoot; + while (curr) { + renderCmdLineArg(curr->str); + curr = curr->next; + } + if (outFile) + fclose(outFile); + PreviewBitmapDestroy(); + deinitfontlibs_ms(); + StrList_Destroy(&gArgsListRoot); + dump_type_stats(); + delete globalParams; + return 0; +} diff --git a/rosapps/smartpdf/src/poppler-config.h b/rosapps/smartpdf/src/poppler-config.h new file mode 100644 index 00000000000..bd0dd5cd293 --- /dev/null +++ b/rosapps/smartpdf/src/poppler-config.h @@ -0,0 +1,150 @@ +//================================================= -*- mode: c++ -*- ==== +// +// poppler-config.h +// +// Copyright 1996-2004 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef POPPLER_CONFIG_H +#define POPPLER_CONFIG_H + +// We duplicate some of the config.h #define's here since they are +// used in some of the header files we install. The #ifndef/#endif +// around #undef look odd, but it's to silence warnings about +// redefining those symbols. + +/* Enable multithreading support. */ +#ifndef MULTITHREADING +#undef MULTITHREADED +#endif + +/* Full path for the system-wide xpdfrc file. */ +#ifndef SYSTEM_XPDFRC +#undef SYSTEM_XPDFRC +#endif + +/* Include support for OPI comments. */ +#ifndef OPI_SUPPORT +#undef OPI_SUPPORT +#endif + +/* Enable word list support. */ +#ifndef TEXTOUT_WORD_LIST +#undef TEXTOUT_WORD_LIST +#endif + +// Also, there's a couple of preprocessor symbols in the header files +// that are used but never defined: DISABLE_OUTLINE, DEBUG_MEM and + +//------------------------------------------------------------------------ +// version +//------------------------------------------------------------------------ + +// xpdf version +#define xpdfVersion "3.00" +#define xpdfVersionNum 3.00 +#define xpdfMajorVersion 3 +#define xpdfMinorVersion 0 +#define xpdfMajorVersionStr "3" +#define xpdfMinorVersionStr "0" + +// supported PDF version +#define supportedPDFVersionStr "1.5" +#define supportedPDFVersionNum 1.5 + +// copyright notice +#define xpdfCopyright "Copyright 1996-2004 Glyph & Cog, LLC" + +// Windows resource file stuff +#define winxpdfVersion "WinXpdf 3.00" +#define xpdfCopyrightAmp "Copyright 1996-2004 Glyph && Cog, LLC" + +//------------------------------------------------------------------------ +// paper size +//------------------------------------------------------------------------ + +// default paper size (in points) for PostScript output +#ifdef A4_PAPER +#define defPaperWidth 595 // ISO A4 (210x297 mm) +#define defPaperHeight 842 +#else +#define defPaperWidth 612 // American letter (8.5x11") +#define defPaperHeight 792 +#endif + +//------------------------------------------------------------------------ +// config file (xpdfrc) path +//------------------------------------------------------------------------ + +// user config file name, relative to the user's home directory +#if defined(VMS) || (defined(WIN32) && !defined(__CYGWIN32__)) +#define xpdfUserConfigFile "xpdfrc" +#else +#define xpdfUserConfigFile ".xpdfrc" +#endif + +// system config file name (set via the configure script) +#ifdef SYSTEM_XPDFRC +#define xpdfSysConfigFile SYSTEM_XPDFRC +#else +// under Windows, we get the directory with the executable and then +// append this file name +#define xpdfSysConfigFile "xpdfrc" +#endif + +//------------------------------------------------------------------------ +// X-related constants +//------------------------------------------------------------------------ + +// default maximum size of color cube to allocate +#define defaultRGBCube 5 + +// number of fonts (combined t1lib, FreeType, X server) to cache +#define xOutFontCacheSize 64 + +// number of Type 3 fonts to cache +#define xOutT3FontCacheSize 8 + +//------------------------------------------------------------------------ +// popen +//------------------------------------------------------------------------ + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define popen _popen +#define pclose _pclose +#endif + +#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(WIN32) || defined(__DJGPP__) || defined(MACOS) +#define POPEN_READ_MODE "rb" +#else +#define POPEN_READ_MODE "r" +#endif + +//------------------------------------------------------------------------ +// Win32 stuff +//------------------------------------------------------------------------ + +#ifdef CDECL +#undef CDECL +#endif + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define CDECL __cdecl +#else +#define CDECL +#endif + +//------------------------------------------------------------------------ +// Compiler +//------------------------------------------------------------------------ + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define GCC_PRINTF_FORMAT(fmt_index, va_index) \ + __attribute__((__format__(__printf__, fmt_index, va_index))) +#else +#define GCC_PRINTF_FORMAT(fmt_index, va_index) +#endif + + +#endif /* POPPLER_CONFIG_H */ diff --git a/rosapps/smartpdf/src/strings.txt b/rosapps/smartpdf/src/strings.txt new file mode 100644 index 00000000000..b9e46822aad --- /dev/null +++ b/rosapps/smartpdf/src/strings.txt @@ -0,0 +1,210 @@ +# This is a file with translations for Sumatra +# Lines at the beginning starting with # are comments +# It must be in utf-8 encoding so when editing make sure +# you use a proper text editor (notepad++ or notepad2 will work) +# What follows below is a line listing all languages supported +# in this file followed by translations themselves +Languages: en pl fr de +- +&File +pl:Plik +de:&Datei +fr:&Fichier +- +&Open\tCtrl-O +pl:Otwórz\tCtrl-O +de:&Öffnen\tCtrl-O +fr:Ouvrir\tCtrl-O +- +&Close\tCtrl-W +pl:&Zamknij\tCtrl-W +de:&Schließen\tCtrl-W +fr:&Fermer\tCtrl-W +- +&Save as +pl:Zapisz jako +- +&Print +pl:Drukuj +de:&Drucken +- +Make SumatraPDF a default PDF reader +pl:Zrób domyślnym programem dla PDF +de:Standardmäßig PDFs öffnen +- +E&xit\tCtrl-Q +pl:Wyjdź\tCtrl-Q +de:E&nde\tCtrl-Q +fr:Quitter\tCtrl-Q +- +&View +pl:&Widok +de:&Ansicht +fr:&Afffichage +- +Single page +pl:Jedna strona +de:Einzelnde Seite +fr:Une seule page +- +Facing +pl:Na przeciwko +de:Doppelseite +fr:Page double +- +Continuous +pl:Ciągły +de:Fortlaufend +fr:Continue +- +Continuous facing +pl:Ciągły na przeciwko +de:Fortlaufende Doppelseite +fr:Continue - Page double +- +Rotate left +pl:Obróć w lewo +de:Drehung links +fr:Rotation horaire +- +Rotate right +pl:Obróć w prawo +de:Drehung rechts +fr:Rotation antihoraire +- +Show toolbar +pl:Pokaż toolbar +de:Werkzeugleiste zeigen +- +Use MuPDF rendering engine +pl:Użyj MuPDF do renderowania +de:MuPDF Renderingengine benutzen +- +&Go To +pl:Idź do +de:&Gehe zu +fr:Atteindre +- +Next Page +pl:Następna strona +de:Nächste Seite +fr:Page suivante +- +Previous Page +pl:Poprzednia strona +de:Vorherige Seite +fr:Page précédente +- +First Page\tHome +pl:Pierwsza strona\tHome +de:Erste Seite\tHome +fr:Première page\tHome +- +Last Page\tEnd +pl:Ostatnia strona\tEnd +de:Letzte Seite\tEnd +fr:Dernière page\tEnd +- +Page...\tCtrl-G +pl:Strona...\tCtrl-G +de:Seite... +- +&Zoom +pl:Powiększenie +de:&Zoom +- +Fit &Page\tCtrl-0 +pl:Dopasuj do strony\tCtrl-0 +de:An Seite anpassen\tCtrl-0 +fr:Page entière\tCtrl-0 +- +Act&ual Size\tCtrl-1 +pl:Prawdziwy rozmiar\tCtrl-1 +de:Tat&sächliche Größe\tCtrl-1 +fr:Taille réelle\tCtrl-1 +- +Fit Widt&h\tCtrl-2 +pl:Dopasuj do szerokości\tCtrl-2 +de:An Breite Anpassen\tCtrl-2 +fr:Pleine largeur +- +6400% +- +3200% +- +1600% +- +800% +- +400% +- +200% +- +150% +- +125% +- +100% +- +50% +- +25% +- +12.5% +- +8.33% +- +&Language +pl:Język +- +&English +pl:&Angielski +- +&German +pl:&Niemiecki +- +&Polish +pl:&Polski +- +&French +pl:&Francuski +- +&Help +pl:&Pomoc +de:&Hilfe +- +&Visit website +pl:Strona www +de:&Website +- +&About +pl:O programie +de:&Über +- +Zoom In +pl:Powiększ +- +Zoom Out +pl:Pomniejsz +- +About SumatraPDF +pl:O programie +- +Open +pl:Otwórz +de:&Öffnen\tCtrl-O +- +SumatraPDF is now a default reader for PDF files. +pl:SumatraPDF jest teraz domyślnym programem do obsługi plików PDF +- +Failed to save a file +pl:Problem przy zapisywaniu pliku. +- +Error loading PDF file. +pl:Problem przy otwarzaniu pliku. +- +Could not open Printer +pl:Drukarka niedostępna. +- +Printing problem. +pl:Problem z drukowaniem. diff --git a/rosapps/smartpdf/src/todo.txt b/rosapps/smartpdf/src/todo.txt new file mode 100644 index 00000000000..8d955e6044c --- /dev/null +++ b/rosapps/smartpdf/src/todo.txt @@ -0,0 +1,21 @@ +Short term todo (before next 0.7 release): +* change toolbar tooltips after changing a language +* use MultiByteToWideChar() + (http://msdn2.microsoft.com/en-us/library/ms776413.aspx) with CP_UTF8 + for utf8->utf16 conversion +* make selection use left mouse button, not right +* when starting for the first time, detect language from windows settings + see http://msdn2.microsoft.com/en-us/library/bb507201.aspx, GetLocaleInfo(), + LOCALE_ICOUNTRY +* write a web page about how to translate the files + +Long term todo: +* find +* show table of contents +* check for new version on-line +* crash reporting with breakpad +* show keybindings in help +* better, animated about screen +* a nicer way to show selected text +* convert WindowInfo_* to a class + diff --git a/rosapps/smartpdf/src/toolbar-disabled.bmp b/rosapps/smartpdf/src/toolbar-disabled.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f39d3976dada98041e0c471745229d5c7695f170 GIT binary patch literal 20022 zcmeI(N33ndat7f0W{i*r9x#HT88HBK1ww$q7GMMnum}?I$_NlS2oNF&VWPxEU@$r7 z9855X@W?rcY(x^6AOt227{K8ATl;^f+_(2W`|N!m&jXthZ{1$Ks=KSJ{`$Mt+UIS( zY|F1mo;DZltz4g|6?X}l7 z+ibJ(#v7k;#u?8%^UN;0?6Uv<``>okZNIrI?!W*3op#!3(@i(km}T;L^=FxLcAWzc zJaBg9HPd|f;fMceBzx|;=kB}jzVpsI@36xTV)3^lS+hBR!%@c^bIh^F9{c2zPj++a z(eG*3|G#|Oa#yvNwBd>?uK2sDQZt-+=9#CRcG~gBAAi(QM~RXE?YQHP(EB$dS!bPf z)>>;V*V13I0nZz4w9zfM+|p_ua>yZxzWGTo5E#f!0t=gLvPnCnYd`+@k<2`rXbr)LLYOAfdYy9byp8fXQ?;l6<4OCyg5T`ImEgC>9(zpq&O7fs6&==XhqJ2;OEGPCMn4QxXwvAa`x;srD@RdGW;;8Grljx7Vny z@#dRvc0ChsUwGk#z4zW*t^vs%cich8Ra=jKPbZFQJD+{_S_ zefL#o*8r_^&pnsgEKxJo-dC(xA<)}yyRBPvhwC_p)4G|v+oO*@`sbg2rXK+qe9nz1 zPRctka#ENItsQa15g&f|;lx0AYG&DCUm(XD1ZCE8C!Tns;fEf2sD5^Cu)zi%ef;sq zZJMLHr=NcMoO8~Rq?>QPIetTH$W8s06u@t+{g08n`s%Bk^T&}q@W2Ci-+edD8*jXk zc^6-NaSM#Hp&B7K!Bw%a!Q>!QPsbaJ>2s8YW|8qZXYWA{HaiQy&4tea8>?rQ;j&v0 z!yy=nhjWN8#&1*bQyTcLMRiugQ^#4|rh!p4a>YfkjYzEpUD_!sD6msokA6?- zXw$E;nIUrqTCcqF%0vKHr)a+P(n}d4t<+109d?*$WtP)+{q@&hcinaWdXj|S22NWL z?J4?MB2h5nmtTJQ;fEi-{PIgF_WJ9u^SnoliJGg|8RRBCKl$X7ciwr20s-KETM%rA z;$&Y9iT$!kXBB&DJX4{yi!Qq8=9_OeLqQ8k-f+VW=bwK*iWB$EHrq_ve){RBtkOVl z{OPKSt0l%8xJ$l-;>Mq*N4zLdqr8|-+kf)OC)+HJ3Z;bZI0p&0YU6F1e2Y@Vv4jte z^@srrXT|U@g0fTW694ly=MaG?eiJ5^Nc@vdI;rJ({xLR>yzbf=lfB$|=bbR-7%DFvdE}99iMm3~Bbx~9 zi9+}-J?*s%=v??5&ny{w?X}mUIK0t{Ql}+~cF`&LDK*ZNQ{JM4wK~(VO@Zz@7rO-> zIQMoYzM)E2Z9T#NVgu9f5WM{I%fI^SE8zL|+ix`>nE{VH@<<)BJTF+NGDGYREMI>4 zWgt%hz&}n;VlPDL#OF?Jq*wf=5tehEqMs!y3IR5X!zW3xj^AX8)BrhohutD2zW^tVev4+F&Un=+UlG@s?X|*$#=vM6e|I&c)KgZ+y~vjH8E=U;z8NyRJ|~!vw~KX?I5-pIaVDhU zy4IMoN<+v{M}1J@ZMP!G08ax&`OE*|xAb(^cEY*vDQe7)@TbU%uk$4o=U8#;B&ru) z3mH<#Nn;9r$}k}|34U|#E265O^9B023Z@ zDRCMf;yP~R0c*KNP#gj*W5zctA}}Ml@x3&}%U(r=qvC~9 zM3X`&PIOS5Pb<$o_Z*fhic`fYs*B%he*88?KbsZM($~mAV@3JJ+hqx5bu|nVNW)`A zZfSrJD2C!7BqbdC@tYD(3dpq_zWCfzdioiuGE{WTok3~#qw1I;FUD9*7YdJwer~G4h@tcMN$hleWQlg8OFiD)endVw16~AeaiTu{$VJ>{ena(3Yfp!oQ zU)UZBp;4lVqfV%UZCTH%x$slFNW(eh97J(8;s}FMZ>HV(?nMuKMAlnxJp)}^>E>*2 zmmCYvk3RaS4T_qLxb=+!25=ga1OkV<)s}skna+QWq$qCt?YED4C@xi;5)MW9ItK=w z;I}FISpr#A0;Z8P6qJelhODZDQq&Ve4=3s1x`64$L$nPw)}=d?Td>z zGsyz3ypdyW`SRsXI{gJ;OF)ZxP?p>m&G+7WFZ*%@Y)`uy#w}&hFEv|WjN$rC)lObI z8fNAz6Dr9@72L5HMn<$cfwXPn1pAeM!|JPs-y?`!v(R>k_s5(UJmzQ!#SKmyNmX%i zLM@?yIsNq04>;feMw$V?`6*dDo#AJl5TXs_&U8ECLr_N`!|$dKKG@Z7HMvH>zz-!} za0r$|adzZt7uYpf?@(quYi(JSV{K6uZGU}oxK{N@oyjq{srW~Z5OE_||oIRw8h$Lj;%+T{~OXUUICwu%m3P zz3Ox%B_lANh~TIi{ctzc9x7`exSKkn1+Zv-? z$<^_jvlzKW^0iF_iKr1v6B$apdF2&V&v)N_2l;?)3(o6o7OU|BrS=44Z6T61ul(ISXB(Ik{No_4sOKZqnNo_*jkPCK! z-@GQPE95dS>CBG{I`J50Luf1k70%bt>4RH3+nHPYTZ7vwF8rp7!v@KEffgY8Iap(G z(m8LA?KxtJdG+~(+1YYgRdgD9fTLMPQYf9OIcB>2>@T0C*eiERk8E zIE9?JNa#RKN4;!Pv*L?z|KbX-L?U28t7u7*h)gA{gLyktG@)!5fN`Wi#^Iz-S|WD~dD8T=-08 zaRo300)|Iod=3TiB4T9zx$sl_t%h(zW-2!kA4f9Jh^h0!flic3_)VuToQeUzM%7f~ zjakO}`!`z{;5{mnk_F#<^Np85q$d^tKtUt(f@({ceF4^XH{C^ZQxNX)gVF*lFJK8$XjWyBdBtD7Uu_At3Evj06}a zF@I@>;%q9F6(lRzYI2QEAO1}{MISirBK%gXq+y^F#8~@kQEC<0;jrUsw!uIZJ zOy@U|5`x$qerxMD_Ro&bWY$0$tILpAt7lfZXfFKJs5DdyqD{G_CI^^s$5uqH+9|vb%kRY9?(70$+F|BsNkVbXNZl~)T(z!HN87R>N z*R_nv&k75O8~*L6BbtV^{MMPIqC;`3ncn>WHFyBOwI3+TOR@&VNmXB*@?%pORt8BZyIKxMY1)oo8NI;WQ5I(HMA)RvfwM{4$W)sQHKn@JQsftmVD`mDx zTg4kU%DajDhJ~D@sow%iPVRcju&|jbDEuZD>d|;(vHC4h7zpm?f#OK`%?uc9n6r^k z7Du&}d95{`8o2o#1j)kG6S|!mdjiPk#!27zTviFQoj$tS`etU%cdfwmQ3p zM-*sI(dmY;AHN}r^xJQ3xipiBF~IRH#l*Cpc8&JDz;7vubwZlL%=?AwIE7{su;h)l zR8yIBJ>7DDKEJi8*JeG+l4W)Z&xFlxCz4xCnq41$Ng`0HZ>#O1N&bxuvPn zQ!`9_suPtBY&MdjxS?l}!)`8ou0dwag`XJ7)tJp^(#2|W$7>f0o)j$nM)*_6hAM86 zEqDDhj`dzPK(`U6o~nQYh2w({KFG9mD!yqO6D9CVHJ&28o!^V6VBs9JtcqAH*J{YT`ZaK_hM$n+ zuUFK?Mvdrg!euf20;k53_^g~N)>^a7TFjXA3#jsJdRgAhAc%;^RVkHrTjF-g-Rbn2{ literal 0 HcmV?d00001 diff --git a/rosapps/smartpdf/src/toolbar.bmp b/rosapps/smartpdf/src/toolbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b45926ce6eb021025e97172458a7afb1a9ae238f GIT binary patch literal 7734 zcmeHLeN6c`+;fT$FrlnRI~rJ`wVF-|ZO1e6q&pbJ6k?Sv1Z zEm{)Aj}Ay9ibC-tS}cAy; zXYaGmIs5G2+57AepB(82lp_07Up@z@6*x1^7VBJt(9!&^G`B1Nih=V8CJl z3qDURozVAPCs^)xLf3a)(9?Mn25z^3rLzq>FI64%K&_Ps}rtY{~FrQpM;C;SE2RnNoZ}o2rVa1!K0IPFwkbiIq*4$ zkI4x4&ox2kiG6UkcLuQGaBIJ!ToUlKs}hSePM4MnCcDCzP$|E>U3~& z+dAZR(6)9pw5%@#(`GFgu6+-U-#-E)`od`Ghwa!l-2WB6ICTMZ-2q|gqFo3S!2>Pu?&>dM18>_a0R%ZY$?x(z12b(r+gf(l{Kv7WBEMT^4k&O9xA-4DOV?1sBS*p-n4;&pvt=j34BJu`ms4S1*NQMM}_VHBem0!Z+$d zxRh4{h&F6lR0y4U8t5#T25lKCXj`U%Guaw2Vf#e>+t9Z1Eof24gGq+6M0{kiV3Nz= z+=6iE)PzIv3>DO_m=6b5&H-aa92l0q1qQVYwyUPYp4k~-d`AWbnGAL$$AUIf1-b$i z=$EOWcv&WtXU>52^W&i?Yc^=pW$@wauYq132gM1~;L|xTf-xl=$BqU=Y&h(EJs5Ov zhl4J5H0TmXL(zt~pe3hzzzCXi7SOc+0;;P| zAnmjTW}bWmvbG;#-sVnt?LaRi9JmkD*VaKsWdo#_=s;7ZgK(1tMpu0c;q~1x_A@gC ztUm{^{W}otw}8md217qS1E6n%;F4V+(i$PVAsbc|zmMyQK(fXM0}ddzzy#A5TVRH! z1T+O&SeU1U(FFzwSo9$=3_yi{8V%$Z6o5Kg4H}gUvQ_VZ27S9=c0A0QzW`(^4al-I zkoa~6#7>vNT*X{?_0!d z&f~s0_TA3BeV=2y+mU^ii`=kbtEl!XYPCQPF3`p*NSsf4F#ON8xDg>UMUfw}LAyVno`1nD5 z<~+W1Jb9MMwyu?rvzGw?P-sMn{8zZ z{Wh=-Y^AR)SE0ucZw1+`TBe$L@bKZ|XU?2yz1f3;mg^lo7*0>skIx=GjvFZokBGSQ{R*LQ z#m>z;_o4zv;wVk2wOy)-5?kBko9p}XE(EFf(V%cCld}vdrm^Kb9*2unLiBlXWTXP| z0q>~=B&?PTy{GDSvs;utTYN^yN2>eZxI*KH5eQs_LZL^KNaQ`0;v>(x-P3j*;Yl{p z_;KK4LaK%$njGF@ncC}U-$VV-F=j(c~1M|yt8V;By!}tHd^DyW z62Bro>H%iJ##4M4fh#(Q;*&8;C2Ky&A=LUQ1<_YGv z0mR3~bNJu@p_s>KmTD#fbnx);<7aNRU_d1%&&-ksORIZKCUX6*8XG?G4$|%F@{JDo zL~40^akyLL+s`KE;D`+Mv!!ey7}b!bLW&8!Jb}sy3A(# z_@VerCWA09kkl~}^Sgpsi6m?yB$DC=7s{#c{gt;)(CBgEqrEGbnAlXeYuB!cf>52K z7dJ>)cF!JUC_aI4wiM^IKY|bA5Bao7+(T>V@{L52H(V7 z5V*KDHF-37qQfW4F*pnck-z_nbfQIh5-dC)?Uhf~a&ddkV<@Tz>1)x}g31r}7?DsP z@#*g7@gep)?Jtf2VU;+3?BCF(;?2byo$V(}vLnq;I{bS2vq*d0!-o%lVt*n;SW0%X z)ZoZyMXGW|)hC8KD?Y*fW+WyeK->23KYZ-Wsmu4(lm=`(%f_Jj1W+N5PZ9_@RE*1z|n#EQ=m9-l^nkJJ8QAkJW@o-izexTt)?250-pk_4ds{zqK+RCqG} z>)DzRuU7`~v6ICLsJrpNxC)hj#|>xx@wKG)x9)}g`+q!ky7k^OJR401V1l9eq$edM z&7Q4NrKM$NW@M;a*v#h>=L(Y%prDT9t!T=mVTEWaNk`uMO2~DYqshsxAg(Xda`bl)i z^2DB49!&A;Ns;%Dko&PId@;!#ClW!zCJ(P(R_)5<<4}yCpxb1;Gaoe~kF13tx;;09 zYqgBSKF5iw1*hm0-fKi8zO#aN7nv9}f1DC6QA4ADFq; zauMUdj$I!lj;Gfx723&OP)K8>v8nl0hR$k5KE;Ow&?j5B9Xf>g+(mpGc~(lyCoZS> zq#-^@Gf93sco1(N#P|6`KfmN;ftwI*la!lK35OZ0jvJG|10Ps4Cl zT3Mfyy;x7J!f8L~iN^t4gaKs9@oT)<^u(m(<_kzz#r0A3X|95y%Q1c!fe6bt zR|!_u1Rp;hpJ+aQ1bF`lJ$u44J0I^Q{lQITim|cx~m3tusG9bokiW8_)1;6mb<2mg6{8 z+Uto3P;)v)PZq@|{rSYi$$mniyyMW}v#2m`*x!gYiJ|Rz*3L<4bMn|-ojHf(}7LJc{r}2Xp;}t~l z`NI;axDrEq)rW)l1Y&)_#gEheqL?jYyS#VERvhi8Ca0UtYF2Hg`ISv&{A(W82m*J} zF79P78xhS2eSIT?hks&F;xEFqKO!Y2E|@{fxEsûZ$_hVc&9m6Xr?F~Bb7CZxK z&m;NG&B{ui*?b74<47t-LV)Tb2tJ_*N!XGyysK$yM(5k`nLKZV?`;X4 zGnfpH^R41IR+X4|LY6%1(3khVxpfbT@g^GC|(a(=kGxBH@1eVfD_(4+l^$ zJ4TN4DV3PM=1~MGPtzI4hlYlZ$67HrSBtcUt`N8+RFC)!S;g0H-5wqyQoqsr$7z3& z46WeEuL90GC;Krs_}wy7Xl`);B{2TWch@ih_V_r+{!B_ZaPf#Vyp2<)QTi(e1fjQ{ z;aR#Maak|<88uQxh=YgqCHPQE=fD^%x^@SCkL5(B;$$!^p3dtQ|wl~iuo;> z4~XC3xdj;}hQec=kY%gzK3Doy5eFvP4Ii|h5s-4mN`Zj^p4PT!K%lKnWh3UfW8upc z2th%?!I4rQt1dYYrlh1lYk4|YqVd5VdNi;Go|{xR|_^<1lu zeuJlTIJ|}rmM-@HJ0Lnv`?Gq-3Xj7ylo@$zFu18;Dl?Ux%8&pZBuAMzn5RL7|8F^X azthe_index = 0; + utf8->the_input = p; + utf8->the_length = length; + utf8->the_char = 0; + utf8->the_byte = 0; +} + +static int +get(json_utf8_decode *utf8) +{ + int c; + if (utf8->the_index >= utf8->the_length) { + return UTF8_END; + } + c = utf8->the_input[utf8->the_index] & 0xFF; + utf8->the_index += 1; + return c; +} + +static int +cont(json_utf8_decode *utf8) +{ + int c = get(utf8); + return ((c & 0xC0) == 0x80) ? (c & 0x3F) : UTF8_ERROR; +} + +int +utf8_decode_next(json_utf8_decode *utf8) +{ + int c; /* the first byte of the character */ + int r; /* the result */ + + if (utf8->the_index >= utf8->the_length) { + return utf8->the_index == utf8->the_length ? UTF8_END : UTF8_ERROR; + } + utf8->the_byte = utf8->the_index; + utf8->the_char += 1; + c = get(utf8); +/* + Zero continuation (0 to 127) +*/ + if ((c & 0x80) == 0) { + return c; + } +/* + One contination (128 to 2047) +*/ + if ((c & 0xE0) == 0xC0) { + int c1 = cont(utf8); + if (c1 < 0) { + return UTF8_ERROR; + } + r = ((c & 0x1F) << 6) | c1; + return r >= 128 ? r : UTF8_ERROR; + } +/* + Two continuation (2048 to 55295 and 57344 to 65535) +*/ + if ((c & 0xF0) == 0xE0) { + int c1 = cont(utf8); + int c2 = cont(utf8); + if (c1 < 0 || c2 < 0) { + return UTF8_ERROR; + } + r = ((c & 0x0F) << 12) | (c1 << 6) | c2; + return r >= 2048 && (r < 55296 || r > 57343) ? r : UTF8_ERROR; + } +/* + Three continuation (65536 to 1114111) +*/ + if ((c & 0xF1) == 0xF0) { + int c1 = cont(utf8); + int c2 = cont(utf8); + int c3 = cont(utf8); + if (c1 < 0 || c2 < 0 || c3 < 0) { + return UTF8_ERROR; + } + r = ((c & 0x0F) << 18) | (c1 << 12) | (c2 << 6) | c3; + return r >= 65536 && r <= 1114111 ? r : UTF8_ERROR; + } + return UTF8_ERROR; +} + +static int json_utf8_to_utf16(unsigned short *w, const char *p, int length) +{ + int c; + int the_index = 0; + json_utf8_decode utf8; + + utf8_decode_init(&utf8, p, length); + for (;;) { + c = utf8_decode_next(&utf8); + if (c < 0) { + return UTF8_END ? the_index : UTF8_ERROR; + } + if (c < 0x10000) { + w[the_index] = (unsigned short)c; + the_index += 1; + } else { + c &= 0xFFFF; + w[the_index] = (unsigned short)(0xD800 | (c >> 10)); + the_index += 1; + w[the_index] = (unsigned short)(0xDC00 | (c & 0x3FF)); + the_index += 1; + } + } +} + +WCHAR* utf8_to_utf16(const char *txt) +{ + // TODO: this is not correct, need real conversion + size_t len = strlen(txt); + WCHAR* wstr = (WCHAR*)zmalloc((len+1) * sizeof(WCHAR)); + if (!wstr) return NULL; + int res = json_utf8_to_utf16((unsigned short*)wstr, txt, len); + assert(UTF8_ERROR != res); + return wstr; +} + +// TODO: this is not thread-safe. lastTxtCached should be per-thread +const WCHAR* Translatations_GetTranslationW(const char* txt) +{ + txt = Translatations_GetTranslation(txt); + if (!txt) return NULL; + if (lastTxtCached) + free(lastTxtCached); + lastTxtCached = utf8_to_utf16(txt); + return (const WCHAR*)lastTxtCached; +} + +void Translations_FreeData() +{ + // TODO: will be more when we implement Translations_FromData + free(lastTxtCached); + lastTxtCached = NULL; +} + diff --git a/rosapps/smartpdf/src/translations.h b/rosapps/smartpdf/src/translations.h new file mode 100644 index 00000000000..22fabdf5585 --- /dev/null +++ b/rosapps/smartpdf/src/translations.h @@ -0,0 +1,15 @@ +#ifndef TRANSLATIONS_H__ +#define TRANSLATIONS_H__ + +//bool Translations_FromData(const char* langs, const char* data, size_t data_len); +bool Translations_SetCurrentLanguage(const char* lang); +const char* Translatations_GetTranslation(const char* txt); +const WCHAR* Translatations_GetTranslationW(const char* txt); +void Translations_FreeData(); + +#define _TR(x) Translatations_GetTranslation(x) +#define _TRN(x) x +#define _TRW(x) Translatations_GetTranslationW(x) +#define _TRWN(x) x + +#endif diff --git a/rosapps/smartpdf/src/translations_txt.c b/rosapps/smartpdf/src/translations_txt.c new file mode 100644 index 00000000000..c3c60366af1 --- /dev/null +++ b/rosapps/smartpdf/src/translations_txt.c @@ -0,0 +1,257 @@ +/* Generated by script gen_c_from_strings_file.py + DO NOT EDIT MANUALLY */ +#ifndef NULL +#define NULL 0 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +int g_transLangsCount = 4; + +const char *g_transLangs[] = { + "en", "pl", "de", "fr" +}; + +int g_transTranslationsCount = 56; + +const char *g_transTranslations[] = { + + /* Translations for language en */ + "&About", + "&Close\tCtrl-W", + "&English", + "&File", + "&French", + "&German", + "&Go To", + "&Help", + "&Language", + "&Open\tCtrl-O", + "&Polish", + "&Print", + "&Save as", + "&View", + "&Visit website", + "&Zoom", + "100%", + "12.5%", + "125%", + "150%", + "1600%", + "200%", + "25%", + "3200%", + "400%", + "50%", + "6400%", + "8.33%", + "800%", + "About SumatraPDF", + "Act&ual Size\tCtrl-1", + "Continuous", + "Continuous facing", + "Could not open Printer", + "E&xit\tCtrl-Q", + "Error loading PDF file.", + "Facing", + "Failed to save a file", + "First Page\tHome", + "Fit &Page\tCtrl-0", + "Fit Widt&h\tCtrl-2", + "Last Page\tEnd", + "Make SumatraPDF a default PDF reader", + "Next Page", + "Open", + "Page...\tCtrl-G", + "Previous Page", + "Printing problem.", + "Rotate left", + "Rotate right", + "Show toolbar", + "Single page", + "SumatraPDF is now a default reader for PDF files.", + "Use MuPDF rendering engine", + "Zoom In", + "Zoom Out", + + /* Translations for language pl */ + "O programie", + "&Zamknij\tCtrl-W", + "&Angielski", + "Plik", + "&Francuski", + "&Niemiecki", + "Id\305\272 do", + "&Pomoc", + "J\304\231zyk", + "Otw\303\263rz\tCtrl-O", + "&Polski", + "Drukuj", + "Zapisz jako", + "&Widok", + "Strona www", + "Powi\304\231kszenie", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "O programie", + "Prawdziwy rozmiar\tCtrl-1", + "Ci\304\205g\305\202y", + "Ci\304\205g\305\202y na przeciwko", + "Drukarka niedost\304\231pna.", + "Wyjd\305\272\tCtrl-Q", + "Problem przy otwarzaniu pliku.", + "Na przeciwko", + "Problem przy zapisywaniu pliku.", + "Pierwsza strona\tHome", + "Dopasuj do strony\tCtrl-0", + "Dopasuj do szeroko\305\233ci\tCtrl-2", + "Ostatnia strona\tEnd", + "Zr\303\263b domy\305\233lnym programem dla PDF", + "Nast\304\231pna strona", + "Otw\303\263rz", + "Strona...\tCtrl-G", + "Poprzednia strona", + "Problem z drukowaniem.", + "Obr\303\263\304\207 w lewo", + "Obr\303\263\304\207 w prawo", + "Poka\305\274 toolbar", + "Jedna strona", + "SumatraPDF jest teraz domy\305\233lnym programem do obs\305\202ugi plik\303\263w PDF", + "U\305\274yj MuPDF do renderowania", + "Powi\304\231ksz", + "Pomniejsz", + + /* Translations for language de */ + "&\303\234ber", + "&Schlie\303\237en\tCtrl-W", + NULL, + "&Datei", + NULL, + NULL, + "&Gehe zu", + "&Hilfe", + NULL, + "&\303\226ffnen\tCtrl-O", + NULL, + "&Drucken", + NULL, + "&Ansicht", + "&Website", + "&Zoom", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Tat&s\303\244chliche Gr\303\266\303\237e\tCtrl-1", + "Fortlaufend", + "Fortlaufende Doppelseite", + NULL, + "E&nde\tCtrl-Q", + NULL, + "Doppelseite", + NULL, + "Erste Seite\tHome", + "An Seite anpassen\tCtrl-0", + "An Breite Anpassen\tCtrl-2", + "Letzte Seite\tEnd", + "Standardm\303\244\303\237ig PDFs \303\266ffnen", + "N\303\244chste Seite", + "&\303\226ffnen\tCtrl-O", + "Seite...", + "Vorherige Seite", + NULL, + "Drehung links", + "Drehung rechts", + "Werkzeugleiste zeigen", + "Einzelnde Seite", + NULL, + "MuPDF Renderingengine benutzen", + NULL, + NULL, + + /* Translations for language fr */ + NULL, + "&Fermer\tCtrl-W", + NULL, + "&Fichier", + NULL, + NULL, + "Atteindre", + NULL, + NULL, + "Ouvrir\tCtrl-O", + NULL, + NULL, + NULL, + "&Afffichage", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Taille r\303\251elle\tCtrl-1", + "Continue", + "Continue - Page double", + NULL, + "Quitter\tCtrl-Q", + NULL, + "Page double", + NULL, + "Premi\303\250re page\tHome", + "Page enti\303\250re\tCtrl-0", + "Pleine largeur", + "Derni\303\250re page\tEnd", + NULL, + "Page suivante", + NULL, + NULL, + "Page pr\303\251c\303\251dente", + NULL, + "Rotation horaire", + "Rotation antihoraire", + NULL, + "Une seule page", + NULL, + NULL, + NULL, + NULL, +}; + +#ifdef __cplusplus +} +#endif diff --git a/rosapps/smartpdf/src/translations_txt.h b/rosapps/smartpdf/src/translations_txt.h new file mode 100644 index 00000000000..40e82a8ab0e --- /dev/null +++ b/rosapps/smartpdf/src/translations_txt.h @@ -0,0 +1,18 @@ +#ifndef TRANSLATIONS_TXT_H__ +#define TRANSLATIONS_TXT_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern int g_transLangsCount; +extern const char *g_transLangs[]; +extern int g_transTranslationsCount; +extern const char *g_transTranslations[]; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/rosapps/smartpdf/sumatrapdf.cbp b/rosapps/smartpdf/sumatrapdf.cbp new file mode 100644 index 00000000000..6eaa1529619 --- /dev/null +++ b/rosapps/smartpdf/sumatrapdf.cbp @@ -0,0 +1,187 @@ + + + + + + diff --git a/rosapps/smartpdf/sumatrapdf.sln b/rosapps/smartpdf/sumatrapdf.sln new file mode 100644 index 00000000000..f654f10798d --- /dev/null +++ b/rosapps/smartpdf/sumatrapdf.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SumatraPDF", "sumatrapdf.vcproj", "{836D470A-7050-4423-B938-0ADB24BFA581}" + ProjectSection(ProjectDependencies) = postProject + {07E5FC14-E74E-4734-9E73-4BB282C2B473} = {07E5FC14-E74E-4734-9E73-4BB282C2B473} + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6} = {F78B1C7E-135A-4178-BED4-A4CCCA9389D6} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "popplerlib", "popplerlib.vcproj", "{F78B1C7E-135A-4178-BED4-A4CCCA9389D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fitzlib", "fitzlib.vcproj", "{07E5FC14-E74E-4734-9E73-4BB282C2B473}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {836D470A-7050-4423-B938-0ADB24BFA581}.Debug|Win32.ActiveCfg = Debug|Win32 + {836D470A-7050-4423-B938-0ADB24BFA581}.Debug|Win32.Build.0 = Debug|Win32 + {836D470A-7050-4423-B938-0ADB24BFA581}.Release|Win32.ActiveCfg = Release|Win32 + {836D470A-7050-4423-B938-0ADB24BFA581}.Release|Win32.Build.0 = Release|Win32 + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Debug|Win32.Build.0 = Debug|Win32 + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Release|Win32.ActiveCfg = Release|Win32 + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Release|Win32.Build.0 = Release|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Debug|Win32.ActiveCfg = Debug|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Debug|Win32.Build.0 = Debug|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Release|Win32.ActiveCfg = Release|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/rosapps/smartpdf/sumatrapdf.vcproj b/rosapps/smartpdf/sumatrapdf.vcproj new file mode 100644 index 00000000000..7f0ca7120f1 --- /dev/null +++ b/rosapps/smartpdf/sumatrapdf.vcproj @@ -0,0 +1,416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/smartpdf/sumatrapdfdll.sln b/rosapps/smartpdf/sumatrapdfdll.sln new file mode 100644 index 00000000000..c24a8f0ac21 --- /dev/null +++ b/rosapps/smartpdf/sumatrapdfdll.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "popplerlib", "popplerlib.vcproj", "{F78B1C7E-135A-4178-BED4-A4CCCA9389D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fitzlib", "fitzlib.vcproj", "{07E5FC14-E74E-4734-9E73-4BB282C2B473}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SumatraPDF", "sumatrapdfdll.vcproj", "{680D376C-9239-4229-8806-23E5AE8B5114}" + ProjectSection(ProjectDependencies) = postProject + {07E5FC14-E74E-4734-9E73-4BB282C2B473} = {07E5FC14-E74E-4734-9E73-4BB282C2B473} + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6} = {F78B1C7E-135A-4178-BED4-A4CCCA9389D6} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Debug|Win32.Build.0 = Debug|Win32 + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Release|Win32.ActiveCfg = Release|Win32 + {F78B1C7E-135A-4178-BED4-A4CCCA9389D6}.Release|Win32.Build.0 = Release|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Debug|Win32.ActiveCfg = Debug|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Debug|Win32.Build.0 = Debug|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Release|Win32.ActiveCfg = Release|Win32 + {07E5FC14-E74E-4734-9E73-4BB282C2B473}.Release|Win32.Build.0 = Release|Win32 + {680D376C-9239-4229-8806-23E5AE8B5114}.Debug|Win32.ActiveCfg = Debug|Win32 + {680D376C-9239-4229-8806-23E5AE8B5114}.Debug|Win32.Build.0 = Debug|Win32 + {680D376C-9239-4229-8806-23E5AE8B5114}.Release|Win32.ActiveCfg = Release|Win32 + {680D376C-9239-4229-8806-23E5AE8B5114}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/rosapps/smartpdf/sumatrapdfdll.vcproj b/rosapps/smartpdf/sumatrapdfdll.vcproj new file mode 100644 index 00000000000..f86b4bf692a --- /dev/null +++ b/rosapps/smartpdf/sumatrapdfdll.vcproj @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.17.1